diff --git a/.github/workflows/raise-pr-for-constants.yml b/.github/workflows/raise-pr-for-constants.yml index 47691c630..b559d8d8c 100644 --- a/.github/workflows/raise-pr-for-constants.yml +++ b/.github/workflows/raise-pr-for-constants.yml @@ -33,10 +33,10 @@ jobs: id: compare_files run: | if cmp -s "${{ env.SRC_FILE }}" "dest-repo/${{ env.DEST_PATH }}"; then - echo "No changes detected." > "result.txt" + echo "No changes detected." echo "pr_required=false" >> $GITHUB_OUTPUT else - echo "Changes detected." > "result.txt" + echo "Changes detected." echo "pr_required=true" >> $GITHUB_OUTPUT fi @@ -58,20 +58,21 @@ jobs: GH_TOKEN: ${{ secrets.PAT }} run: | cd dest-repo - EXISTING_PR=$(gh pr list --head ${{ env.BRANCH_NAME }} --json number --jq ".[0].number") + EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --json number --jq ".[0].number") if [ -z "$EXISTING_PR" ]; then - gh pr create \ - --title "fix: update destination constants" \ - --body "$(cat < { + try { + const destinationsFilePath = path.join(destinationsDir, destination, 'db-config.json'); + if (!fs.existsSync(destinationsFilePath)) { + console.warn(`Skipping ${destination}: Missing configuration file`); + return null; + } + const destinationsContent = fs.readFileSync(destinationsFilePath, 'utf8'); + const destinationDefinition = JSON.parse(destinationsContent); + if (!destinationDefinition.name) { + console.warn(`Skipping ${destination}: Missing name`); + return null; + } + return { + name: destinationDefinition.name, + config: destinationDefinition.config, + }; + } catch (err) { + console.error(`Error processing ${destination}:`, err.message); + return null; + } + }) + .filter(Boolean) + .filter( + (destination) => + !destination.config?.disableJsonMapper && !destination.config?.supportsVisualMapper, + ) + .map((destination) => destination.name); + } catch (err) { + console.error('Failed to process destinations:', err.message); + return []; + } +} + +console.log(findJsonMapperDestinations().join('\n')); diff --git a/src/configurations/destinations/topsort/db-config.json b/src/configurations/destinations/topsort/db-config.json new file mode 100644 index 000000000..a332d44c6 --- /dev/null +++ b/src/configurations/destinations/topsort/db-config.json @@ -0,0 +1,109 @@ +{ + "name": "TOPSORT", + "displayName": "Topsort", + "config": { + "transformAtV1": "processor", + "saveDestinationResponse": true, + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "unity", + "amp", + "web", + "cloud", + "warehouse", + "reactnative", + "flutter", + "cordova", + "shopify" + ], + "supportedMessageTypes": { "cloud": ["track"] }, + "supportedConnectionModes": { + "android": ["cloud"], + "ios": ["cloud"], + "web": ["cloud"], + "unity": ["cloud"], + "amp": ["cloud"], + "reactnative": ["cloud"], + "flutter": ["cloud"], + "cordova": ["cloud"], + "shopify": ["cloud"], + "cloud": ["cloud"], + "warehouse": ["cloud"] + }, + "destConfig": { + "defaultConfig": ["apiKey", "topsortEvents"], + "android": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "ios": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "unity": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "amp": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "reactnative": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "flutter": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "cordova": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "web": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "cloud": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "shopify": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ], + "warehouse": [ + "connectionMode", + "consentManagement", + "oneTrustCookieCategories", + "ketchConsentPurposes" + ] + }, + "secretKeys": ["apiKey"] + }, + "options": { + "isBeta": true + } +} diff --git a/src/configurations/destinations/topsort/schema.json b/src/configurations/destinations/topsort/schema.json new file mode 100644 index 000000000..be1f7159f --- /dev/null +++ b/src/configurations/destinations/topsort/schema.json @@ -0,0 +1,876 @@ +{ + "configSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "required": ["apiKey"], + "type": "object", + "properties": { + "apiKey": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{1,100})$" + }, + "topsortEvents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "from": { + "type": "string", + "enum": [ + "Product Clicked", + "Product Viewed", + "Product Added", + "Product Removed", + "Cart Viewed", + "Checkout Started", + "Checkout Step Viewed", + "Payment Info Entered", + "Order Updated", + "Order Completed", + "Order Refunded", + "Order Cancelled" + ] + }, + "to": { + "type": "string", + "enum": ["clicks", "impressions", "purchases"] + } + } + } + }, + "oneTrustCookieCategories": { + "type": "object", + "properties": { + "android": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "ios": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "unity": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "amp": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "reactnative": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "flutter": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "cordova": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "web": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "cloud": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "shopify": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "warehouse": { + "type": "array", + "items": { + "type": "object", + "properties": { + "oneTrustCookieCategory": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + } + }, + "consentManagement": { + "type": "object", + "properties": { + "cloud": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "warehouse": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "android": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "ios": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "web": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "unity": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "amp": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "reactnative": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "flutter": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "cordova": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + }, + "shopify": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "enum": ["custom", "ketch", "oneTrust"], + "default": "oneTrust" + }, + "consents": { + "type": "array", + "items": { + "type": "object", + "properties": { + "consent": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + }, + "allOf": [ + { + "if": { + "properties": { + "provider": { + "const": "custom" + } + }, + "required": ["provider"] + }, + "then": { + "properties": { + "resolutionStrategy": { + "type": "string", + "enum": ["and", "or"] + } + }, + "required": ["resolutionStrategy"] + } + } + ] + } + } + } + }, + "ketchConsentPurposes": { + "type": "object", + "properties": { + "android": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "ios": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "unity": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "amp": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "reactnative": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "flutter": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "cordova": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "web": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "cloud": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "shopify": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + }, + "warehouse": { + "type": "array", + "items": { + "type": "object", + "properties": { + "purpose": { + "type": "string", + "pattern": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{0,100})$" + } + } + } + } + } + }, + "connectionMode": { + "type": "object", + "properties": { + "android": { + "type": "string", + "enum": ["cloud"] + }, + "ios": { + "type": "string", + "enum": ["cloud"] + }, + "web": { + "type": "string", + "enum": ["cloud"] + }, + "unity": { + "type": "string", + "enum": ["cloud"] + }, + "amp": { + "type": "string", + "enum": ["cloud"] + }, + "reactnative": { + "type": "string", + "enum": ["cloud"] + }, + "flutter": { + "type": "string", + "enum": ["cloud"] + }, + "cordova": { + "type": "string", + "enum": ["cloud"] + }, + "shopify": { + "type": "string", + "enum": ["cloud"] + }, + "cloud": { + "type": "string", + "enum": ["cloud"] + }, + "warehouse": { + "type": "string", + "enum": ["cloud"] + } + } + } + } + } +} diff --git a/src/configurations/destinations/topsort/ui-config.json b/src/configurations/destinations/topsort/ui-config.json new file mode 100644 index 000000000..6a6d4573c --- /dev/null +++ b/src/configurations/destinations/topsort/ui-config.json @@ -0,0 +1,260 @@ +{ + "uiConfig": { + "baseTemplate": [ + { + "title": "Initial setup", + "note": "Review how this destination is set up", + "sections": [ + { + "groups": [ + { + "title": "Connection Settings", + "note": "Update your connection settings here", + "icon": "settings", + "fields": [ + { + "type": "textInput", + "label": "API Key", + "configKey": "apiKey", + "regex": "(^\\{\\{.*\\|\\|(.*)\\}\\}$)|(^env[.].+)|^(.{1,100})$", + "regexErrorMessage": "Invalid API Key", + "placeholder": "e.g. 88a1b72e-a017-4803-9854-0c447045c29e" + } + ] + } + ] + }, + { + "groups": [ + { + "title": "Connection mode", + "note": [ + "Update how you want to route events from your source to destination. ", + { + "text": "Get help deciding", + "link": "https://www.rudderstack.com/docs/destinations/rudderstack-connection-modes/" + } + ], + "icon": "sliders", + "fields": [] + } + ] + } + ] + }, + { + "title": "Configuration settings", + "note": "Manage the settings for your destination", + "sections": [ + { + "id": "consentSettings", + "title": "Consent settings", + "note": "Configure consent settings for each provider here", + "icon": "settings", + "groups": [] + } + ] + }, + { + "title": "Event mapping", + "note": "Map RudderStack events to Topsort events", + "hideEditIcon": true, + "sections": [ + { + "groups": [ + { + "title": "RudderStack Event to Topsort Event Mapping", + "fields": [ + { + "type": "redirect", + "redirectGroupKey": "eventsMapping", + "label": "Event and property mappings", + "note": "Map RudderStack events/properties to Topsort events/properties" + } + ] + } + ] + } + ] + } + ], + "sdkTemplate": { + "title": "SDK settings", + "note": "not visible in the ui", + "fields": [] + }, + "redirectGroups": { + "eventsMapping": { + "fields": [ + { + "type": "mapping", + "label": "Map RudderStack event to Topsort event", + "configKey": "topsortEvents", + "default": [ + { + "from": "Product Clicked", + "to": "clicks" + }, + { + "from": "Product Viewed", + "to": "impressions" + }, + { + "from": "Order Completed", + "to": "purchases" + } + ], + "columns": [ + { + "type": "singleSelect", + "key": "from", + "label": "RudderStack Event", + "options": [ + { + "label": "Product Clicked", + "value": "Product Clicked" + }, + { + "label": "Product Viewed", + "value": "Product Viewed" + }, + { + "label": "Product Added", + "value": "Product Added" + }, + { + "label": "Product Removed", + "value": "Product Removed" + }, + { + "label": "Cart Viewed", + "value": "Cart Viewed" + }, + { + "label": "Checkout Started", + "value": "Checkout Started" + }, + { + "label": "Checkout Step Viewed", + "value": "Checkout Step Viewed" + }, + { + "label": "Payment Info Entered", + "value": "Payment Info Entered" + }, + { + "label": "Order Updated", + "value": "Order Updated" + }, + { + "label": "Order Completed", + "value": "Order Completed" + }, + { + "label": "Order Refunded", + "value": "Order Refunded" + }, + { + "label": "Order Cancelled", + "value": "Order Cancelled" + } + ] + }, + { + "type": "singleSelect", + "key": "to", + "label": "Topsort event", + "options": [ + { + "label": "clicks", + "value": "clicks" + }, + { + "label": "impressions", + "value": "impressions" + }, + { + "label": "purchases", + "value": "purchases" + } + ] + } + ] + } + ] + } + }, + "consentSettingsTemplate": { + "title": "Consent settings", + "note": "not visible in the ui", + "fields": [ + { + "type": "dynamicCustomForm", + "configKey": "consentManagement", + "default": [], + "rowFields": [ + { + "type": "singleSelect", + "label": "Consent management provider", + "configKey": "provider", + "options": [ + { + "label": "Custom", + "value": "custom" + }, + { + "label": "Ketch", + "value": "ketch" + }, + { + "label": "OneTrust", + "value": "oneTrust" + } + ], + "default": "oneTrust", + "required": true + }, + { + "type": "singleSelect", + "label": "the required consent logic", + "configKey": "resolutionStrategy", + "options": [ + { + "label": "AND", + "value": "and" + }, + { + "label": "OR", + "value": "or" + } + ], + "required": true, + "variant": "badge", + "preRequisites": { + "fields": [ + { + "configKey": "provider", + "value": "custom" + } + ] + } + }, + { + "type": "tagInput", + "label": "Enter consent category IDs", + "note": "Input your consent category IDs by pressing 'Enter' after each entry. We recommend using IDs instead of names as IDs are unique and less likely to change over time, making them a more reliable choice.", + "configKey": "consents", + "tagKey": "consent", + "placeholder": "e.g: Marketing", + "default": [ + { + "consent": "" + } + ] + } + ] + } + ] + } + } +} diff --git a/src/configurations/sources/amp/db-config.json b/src/configurations/sources/amp/db-config.json index f27a7d0cf..d98b0b85c 100644 --- a/src/configurations/sources/amp/db-config.json +++ b/src/configurations/sources/amp/db-config.json @@ -1,5 +1,8 @@ { "name": "AMP", "displayName": "AMP", - "type": "amp" + "type": "amp", + "options": { + "sdkExecutionEnvironment": "client" + } } diff --git a/src/configurations/sources/android/db-config.json b/src/configurations/sources/android/db-config.json index 95473faed..d9e1b8c21 100644 --- a/src/configurations/sources/android/db-config.json +++ b/src/configurations/sources/android/db-config.json @@ -1,5 +1,8 @@ { "name": "Android", "displayName": "Android", - "type": "android" + "type": "android", + "options": { + "sdkExecutionEnvironment": "client" + } } diff --git a/src/configurations/sources/cordova/db-config.json b/src/configurations/sources/cordova/db-config.json index 5ee84ca76..6cc47e2d2 100644 --- a/src/configurations/sources/cordova/db-config.json +++ b/src/configurations/sources/cordova/db-config.json @@ -1,5 +1,8 @@ { "name": "Cordova", "displayName": "Cordova", - "type": "cordova" + "type": "cordova", + "options": { + "sdkExecutionEnvironment": "client" + } } diff --git a/src/configurations/sources/dotnet/db-config.json b/src/configurations/sources/dotnet/db-config.json index dd5204182..f737ad33c 100644 --- a/src/configurations/sources/dotnet/db-config.json +++ b/src/configurations/sources/dotnet/db-config.json @@ -1,5 +1,8 @@ { "name": "DotNet", "displayName": ".Net", - "type": "cloud" + "type": "cloud", + "options": { + "sdkExecutionEnvironment": "server" + } } diff --git a/src/configurations/sources/flutter/db-config.json b/src/configurations/sources/flutter/db-config.json index d2b602e62..26856f086 100644 --- a/src/configurations/sources/flutter/db-config.json +++ b/src/configurations/sources/flutter/db-config.json @@ -1,5 +1,8 @@ { "name": "Flutter", "displayName": "Flutter", - "type": "flutter" + "type": "flutter", + "options": { + "sdkExecutionEnvironment": "client" + } } diff --git a/src/configurations/sources/go/db-config.json b/src/configurations/sources/go/db-config.json index ca4b23f3c..76e630e2d 100644 --- a/src/configurations/sources/go/db-config.json +++ b/src/configurations/sources/go/db-config.json @@ -1,5 +1,8 @@ { "name": "Go", "displayName": "Go", - "type": "cloud" + "type": "cloud", + "options": { + "sdkExecutionEnvironment": "server" + } } diff --git a/src/configurations/sources/ios/db-config.json b/src/configurations/sources/ios/db-config.json index a55f4d793..4d65dc374 100644 --- a/src/configurations/sources/ios/db-config.json +++ b/src/configurations/sources/ios/db-config.json @@ -1,5 +1,8 @@ { "name": "iOS", "displayName": "iOS", - "type": "ios" + "type": "ios", + "options": { + "sdkExecutionEnvironment": "client" + } } diff --git a/src/configurations/sources/java/db-config.json b/src/configurations/sources/java/db-config.json index 58f6b8686..506d5dc28 100644 --- a/src/configurations/sources/java/db-config.json +++ b/src/configurations/sources/java/db-config.json @@ -1,5 +1,8 @@ { "name": "Java", "displayName": "Java", - "type": "cloud" + "type": "cloud", + "options": { + "sdkExecutionEnvironment": "server" + } } diff --git a/src/configurations/sources/javascript/db-config.json b/src/configurations/sources/javascript/db-config.json index e823e2183..4f0773d72 100644 --- a/src/configurations/sources/javascript/db-config.json +++ b/src/configurations/sources/javascript/db-config.json @@ -1,5 +1,8 @@ { "name": "Javascript", "displayName": "Javascript", - "type": "web" + "type": "web", + "options": { + "sdkExecutionEnvironment": "client" + } } diff --git a/src/configurations/sources/node/db-config.json b/src/configurations/sources/node/db-config.json index c7ab6a7ff..8d897bee4 100644 --- a/src/configurations/sources/node/db-config.json +++ b/src/configurations/sources/node/db-config.json @@ -1,5 +1,8 @@ { "name": "Node", "displayName": "Node", - "type": "cloud" + "type": "cloud", + "options": { + "sdkExecutionEnvironment": "server" + } } diff --git a/src/configurations/sources/php/db-config.json b/src/configurations/sources/php/db-config.json index c34a3cdd5..149c70949 100644 --- a/src/configurations/sources/php/db-config.json +++ b/src/configurations/sources/php/db-config.json @@ -1,5 +1,8 @@ { "name": "PHP", "displayName": "PHP", - "type": "cloud" + "type": "cloud", + "options": { + "sdkExecutionEnvironment": "server" + } } diff --git a/src/configurations/sources/python/db-config.json b/src/configurations/sources/python/db-config.json index 76415d16d..e8ee2c15c 100644 --- a/src/configurations/sources/python/db-config.json +++ b/src/configurations/sources/python/db-config.json @@ -1,5 +1,8 @@ { "name": "Python", "displayName": "Python", - "type": "cloud" + "type": "cloud", + "options": { + "sdkExecutionEnvironment": "server" + } } diff --git a/src/configurations/sources/react_native/db-config.json b/src/configurations/sources/react_native/db-config.json index 37a80466e..f49efcbfa 100644 --- a/src/configurations/sources/react_native/db-config.json +++ b/src/configurations/sources/react_native/db-config.json @@ -1,5 +1,8 @@ { "name": "ReactNative", "displayName": "React Native", - "type": "reactnative" + "type": "reactnative", + "options": { + "sdkExecutionEnvironment": "client" + } } diff --git a/src/configurations/sources/ruby/db-config.json b/src/configurations/sources/ruby/db-config.json index 8b0e872f2..6da7a202d 100644 --- a/src/configurations/sources/ruby/db-config.json +++ b/src/configurations/sources/ruby/db-config.json @@ -1,5 +1,8 @@ { "name": "Ruby", "displayName": "Ruby", - "type": "cloud" + "type": "cloud", + "options": { + "sdkExecutionEnvironment": "server" + } } diff --git a/src/configurations/sources/rust/db-config.json b/src/configurations/sources/rust/db-config.json index 12e377523..aa4322a1f 100644 --- a/src/configurations/sources/rust/db-config.json +++ b/src/configurations/sources/rust/db-config.json @@ -1,5 +1,8 @@ { "name": "Rust", "displayName": "Rust", - "type": "cloud" + "type": "cloud", + "options": { + "sdkExecutionEnvironment": "server" + } } diff --git a/src/configurations/sources/unity/db-config.json b/src/configurations/sources/unity/db-config.json index ab4bf8d8e..1783a5160 100644 --- a/src/configurations/sources/unity/db-config.json +++ b/src/configurations/sources/unity/db-config.json @@ -1,5 +1,8 @@ { "name": "Unity", "displayName": "Unity", - "type": "unity" + "type": "unity", + "options": { + "sdkExecutionEnvironment": "client" + } } diff --git a/src/schemas/sources/db-config-schema.json b/src/schemas/sources/db-config-schema.json index dc1cfa381..1761b63d6 100644 --- a/src/schemas/sources/db-config-schema.json +++ b/src/schemas/sources/db-config-schema.json @@ -146,6 +146,12 @@ "type": "boolean", "title": "Supports Destination Sync Mode", "description": "TBD" + }, + "sdkExecutionEnvironment": { + "type": "string", + "title": "SDK Execution Environment", + "description": "It denotes the environment in which the SDK is executed. The presence of this field also indicates that the source is an SDK source.", + "enum": ["server", "client"] } } } diff --git a/test/data/validation/destinations/topsort.json b/test/data/validation/destinations/topsort.json new file mode 100644 index 000000000..a07f0132a --- /dev/null +++ b/test/data/validation/destinations/topsort.json @@ -0,0 +1,197 @@ +[ + { + "testTitle": "With all valid events and details", + "config": { + "apiKey": "test-api", + "topsortEvents": [ + { + "to": "clicks", + "from": "Product Clicked" + }, + { + "to": "impressions", + "from": "Product Viewed" + }, + { + "to": "purchases", + "from": "Order Completed" + } + ], + "connectionMode": { + "web": "cloud" + }, + "consentManagement": {}, + "oneTrustCookieCategories": {}, + "ketchConsentPurposes": {} + }, + "result": true + }, + { + "testTitle": "With invalid connectionMode value", + "config": { + "apiKey": "test-api", + "topsortEvents": [ + { + "to": "clicks", + "from": "Product Clicked" + }, + { + "to": "impressions", + "from": "Product Viewed" + }, + { + "to": "purchases", + "from": "Order Completed" + } + ], + "connectionMode": { + "web": "abc" + }, + "consentManagement": {}, + "oneTrustCookieCategories": {}, + "ketchConsentPurposes": {} + }, + "result": false, + "err": ["connectionMode.web must be equal to one of the allowed values"] + }, + { + "testTitle": "Device mode is not supported", + "config": { + "connectionMode": { + "web": "device" + }, + "consentManagement": {}, + "oneTrustCookieCategories": {}, + "ketchConsentPurposes": {}, + "apiKey": "test-api", + "topsortEvents": [ + { + "to": "clicks", + "from": "Product Clicked" + }, + { + "to": "impressions", + "from": "Product Viewed" + }, + { + "to": "purchases", + "from": "Order Completed" + } + ] + }, + "result": false, + "err": ["connectionMode.web must be equal to one of the allowed values"] + }, + { + "testTitle": "without api key", + "config": { + "connectionMode": { + "web": "cloud" + }, + "consentManagement": {}, + "oneTrustCookieCategories": {}, + "ketchConsentPurposes": {}, + "topsortEvents": [ + { + "to": "clicks", + "from": "Product Clicked" + }, + { + "to": "impressions", + "from": "Product Viewed" + }, + { + "to": "purchases", + "from": "Order Completed" + } + ] + }, + "result": false, + "err": [" must have required property 'apiKey'"] + }, + { + "testTitle": "Invalid Topsort event name", + "config": { + "connectionMode": { + "web": "cloud" + }, + "consentManagement": {}, + "oneTrustCookieCategories": {}, + "ketchConsentPurposes": {}, + "apiKey": "test-api", + "topsortEvents": [ + { + "to": "test", + "from": "Product Clicked" + }, + { + "to": "impressions", + "from": "Product Viewed" + } + ] + }, + "result": false, + "err": ["topsortEvents.0.to must be equal to one of the allowed values"] + }, + { + "testTitle": "Invalid Rudderstack event name", + "config": { + "connectionMode": { + "web": "cloud" + }, + "consentManagement": {}, + "oneTrustCookieCategories": {}, + "ketchConsentPurposes": {}, + "apiKey": "test-api", + "topsortEvents": [ + { + "to": "clicks", + "from": "test" + }, + { + "to": "impressions", + "from": "Product Viewed" + } + ] + }, + "result": false, + "err": ["topsortEvents.0.from must be equal to one of the allowed values"] + }, + { + "testTitle": "With consent management custom provider config and no resolutionStrategy value", + "config": { + "apiKey": "test-api", + "consentManagement": { + "android": [ + { + "provider": "custom" + } + ] + } + }, + "oneTrustCookieCategories": {}, + "ketchConsentPurposes": {}, + "result": false, + "err": [ + "consentManagement.android.0 must have required property 'resolutionStrategy'", + "consentManagement.android.0 must match \"then\" schema" + ] + }, + { + "testTitle": "With consent management custom provider config invalid provider value", + "config": { + "apiKey": "test-api", + "consentManagement": { + "android": [ + { + "provider": "dummyProvider" + } + ] + }, + "oneTrustCookieCategories": {}, + "ketchConsentPurposes": {} + }, + "result": false, + "err": ["consentManagement.android.0.provider must be equal to one of the allowed values"] + } +]