Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: limit dynamic config for all destinations #1801

Draft
wants to merge 16 commits into
base: chore.limit-dynamic-config-zendesk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
33 changes: 33 additions & 0 deletions scripts/destinations/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export const DYNAMIC_CONFIG_FIELDS: Record<string, string[]> = {
ZENDESK: ['email', 'sourceName', 'domain'],
ZAPIER: ['trackEventsToZap', 'pageScreenEventsToZap'],
WEBHOOK: ['headers', 'webhookUrl'],
SENDGRID: ['listId'],
SEGMENT: ['writeKey'],
SALESFORCE: ['userName'],
REDDIT: ['accountId'],
MP: ['serviceAccountSecret', 'apiSecret', 'projectId', 'serviceAccountUserName'],
MOVABLE_INK: ['endpoint'],
MAILCHIMP: ['apiKey', 'datacenterId', 'audienceId'],
KLAVIYO: ['listId', 'publicApiKey'],
INTERCOM: ['apiKey', 'appId'],
IMPACT: ['campaignId', 'accountSID', 'eventTypeId'],
HS: ['hubID', 'hubspotEvents', 'accessToken'],
GTM: ['containerID'],
GA: ['metrics', 'trackingID'],
BRAZE: ['appKey'],
BQSTREAM: ['tableId'],
AM: ['groupTypeTrait', 'groupValueTrait'],
AF: ['appleAppId', 'androidAppId'],
ADOBE_ANALYTICS: ['trackingServerUrl', 'reportSuiteIds', 'trackingServerSecureUrl'],
FACEBOOK_PIXEL: ['legacyConversionPixelId', 'pixelId', 'accessToken'],
FACEBOOK_CONVERSIONS: ['datasetId'],
FACEBOOK_OFFLINE_CONVERSIONS: ['eventsToIds'],
FB_CUSTOM_AUDIENCE: ['audienceId'],
GA4: ['measurementId'],
GOOGLE_ADWORDS_ENHANCED_CONVERSIONS: ['loginCustomerId', 'customerId'],
GOOGLE_ADWORDS_OFFLINE_CONVERSIONS: ['loginCustomerId', 'customerId'],
GOOGLEADS: ['conversionID'],
SNAPCHAT_CONVERSION: ['pixelId'],
PINTEREST_TAG: ['advertiserId'],
};
123 changes: 123 additions & 0 deletions scripts/destinations/process-ui-config-template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* eslint-disable no-lonely-if */
/* eslint-disable no-param-reassign */
import { BaseField, NewStyleUIConfig } from './types';
import { removeDefaultSubRegex } from './utils';

// Extend BaseField to include all possible nested fields
interface TemplateField extends BaseField {
fields?: TemplateField[];
customFields?: TemplateField[];
rowFields?: TemplateField[];
columns?: TemplateField[];
from?: TemplateField;
to?: TemplateField;
regex?: string;
dynamicConfigSupported?: boolean;
}

const processTemplateField = (
field: TemplateField,
dynamicFields: string[],
_parentKey?: string,
): void => {
// Get the relevant key for dynamic field check
const fieldKey = field.configKey || field.value || '';
const isFieldDynamic = dynamicFields.includes(fieldKey);

// If field is dynamic, add dynamicConfigSupported flag
if (isFieldDynamic) {
field.dynamicConfigSupported = true;
} else {
// Process regex if not a dynamic field
if (field.regex) {
field.regex = removeDefaultSubRegex(field.regex);
}
}

// Process from/to fields for mapping components
if (field.from) {
processTemplateField(field.from, dynamicFields, fieldKey);
}
if (field.to) {
processTemplateField(field.to, dynamicFields, fieldKey);
}

// Process nested fields
if (field.fields) {
field.fields.forEach((nestedField) => {
processTemplateField(nestedField, dynamicFields, fieldKey);
});
}

// Process custom fields
if (field.customFields) {
field.customFields.forEach((customField) => {
processTemplateField(customField, dynamicFields, fieldKey);
});
}

// Process row fields
if (field.rowFields) {
field.rowFields.forEach((rowField) => {
processTemplateField(rowField, dynamicFields, fieldKey);
});
}

// Process columns
if (field.columns) {
field.columns.forEach((column) => {
processTemplateField(column, dynamicFields, fieldKey);
});
}
};

const processUIConfigTemplate = (template: NewStyleUIConfig, dynamicFields: string[]): void => {
// Process base template
if (template.baseTemplate) {
template.baseTemplate.forEach((base: { sections: any[] }) => {
base.sections?.forEach((section: { groups: any[] }) => {
section.groups?.forEach((group: { fields: any[] }) => {
group.fields?.forEach((field: TemplateField) => {
processTemplateField(field as TemplateField, dynamicFields);
});
});
});
});
}

// Process SDK template
if (template.sdkTemplate?.sections) {
template.sdkTemplate.sections.forEach((section: any) => {
section.groups?.forEach((group: { fields: any[] }) => {
group.fields?.forEach((field: TemplateField) => {
processTemplateField(field as TemplateField, dynamicFields);
});
});
});
}

// Process consent settings template
if (template.consentSettingsTemplate?.sections) {
template.consentSettingsTemplate.sections.forEach((section: any) => {
section.groups?.forEach((group: { fields: any[] }) => {
group.fields?.forEach((field: TemplateField) => {
processTemplateField(field as TemplateField, dynamicFields);
});
});
});
}

// Process redirect groups
if (template.redirectGroups) {
Object.values(template.redirectGroups).forEach((group: unknown) => {
const typedGroup = group as { tabs?: { fields?: TemplateField[] }[] };
typedGroup.tabs?.forEach((tab) => {
tab.fields?.forEach((field: TemplateField) => {
processTemplateField(field as TemplateField, dynamicFields);
});
});
});
}
};

export { processUIConfigTemplate };
117 changes: 117 additions & 0 deletions scripts/destinations/schema.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
interface SchemaDefinition {
name: string;
description?: string;
platform?: string;
categories?: string[];
website?: string;
presets?: Array<{
name: string;
description?: string;
subscribe?: string[];
}>;
authentication?: {
scheme: string;
fields: Record<
string,
{
type: string;
required?: boolean;
description?: string;
default?: any;
sensitive?: boolean;
}
>;
};
settings?: {
fields: Record<
string,
{
type: string;
required?: boolean;
description?: string;
default?: any;
allowNull?: boolean;
properties?: Record<
string,
{
type: string;
description?: string;
}
>;
items?: {
type: string;
properties?: Record<
string,
{
type: string;
description?: string;
}
>;
};
}
>;
};
actions?: Array<{
name: string;
description?: string;
platform?: string;
defaultSubscription: string;
fields: Record<
string,
{
type: string;
required?: boolean;
description?: string;
default?: any;
properties?: Record<
string,
{
type: string;
description?: string;
}
>;
}
>;
}>;
idResolution?: {
type: string;
scheme: string;
fields: Record<
string,
{
type: string;
required?: boolean;
description?: string;
}
>;
};
}

// Helper type for field definitions
interface SchemaField {
type: string;
required?: boolean;
description?: string;
default?: any;
sensitive?: boolean;
allowNull?: boolean;
properties?: Record<
string,
{
type: string;
description?: string;
}
>;
items?: {
type: string;
properties?: Record<
string,
{
type: string;
description?: string;
}
>;
};
}

export type { SchemaDefinition, SchemaField };
Loading
Loading