diff --git a/.eslintignore b/.eslintignore index 60934a8e91..6f33878172 100644 --- a/.eslintignore +++ b/.eslintignore @@ -15,3 +15,4 @@ src/logger.js src/util/eventValidations.js **/trackingPlan* src/v0/destinations/personalize/scripts/ +test/integrations/destinations/testTypes.d.ts diff --git a/.github/workflows/master-bulids.yml b/.github/workflows/master-bulids.yml index aa7eeafdb5..478632a508 100644 --- a/.github/workflows/master-bulids.yml +++ b/.github/workflows/master-bulids.yml @@ -4,9 +4,63 @@ on: branches: - 'master' env: + REPO_NAME_OLD: dockeronce.azurecr.io/kubernetes/rudder-transformer REPO_NAME: dockeronce.azurecr.io/kubernetes/rudder-transformer + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} jobs: + transformer-build: + name: Build transformer master image + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Get image version + id: get_version + run: | + VERSION="master" + echo $VERSION + echo "::set-output name=version::$VERSION" + + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ env.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PROD_TOKEN }} + + - name: Build image + uses: docker/build-push-action@v3 + with: + context: . + file: Dockerfile + load: true + tags: | + ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} + + - name: Run Tests + run: | + docker run ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} npm run test + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push multi-platform images + uses: docker/build-push-action@v3 + with: + context: . + file: Dockerfile + push: true + tags: | + ${{ env.REPO_NAME_OLD }}:${{ steps.get_version.outputs.version }} + ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} + platforms: | + linux/amd64 + linux/arm64 + build-args: | + VERSION=${{ steps.get_version.outputs.version }} + COMMIT_HASH=${{ github.sha }} + user-transformer-build: name: Build user transformer master image runs-on: ubuntu-latest @@ -27,26 +81,34 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and export to Docker + - name: Build image uses: docker/build-push-action@v3 with: context: . file: Dockerfile-ut-func load: true - tags: ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} + tags: | + ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} - name: Run Tests run: | docker run ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} npm run test - - name: Build and push + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push multi-platform images uses: docker/build-push-action@v3 with: context: . file: Dockerfile-ut-func push: true - tags: ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} + tags: | + ${{ env.REPO_NAME_OLD }}:${{ steps.get_version.outputs.version }} + ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} + platforms: | + linux/amd64 + linux/arm64 build-args: | VERSION=${{ steps.get_version.outputs.version }} COMMIT_HASH=${{ github.sha }} - # TODO: Add Dest transformer build job after codebuild is removed diff --git a/.github/workflows/pr-builds.yml b/.github/workflows/pr-builds.yml index ec72377856..bb672af440 100644 --- a/.github/workflows/pr-builds.yml +++ b/.github/workflows/pr-builds.yml @@ -9,9 +9,63 @@ on: - ready_for_review - synchronize env: + REPO_NAME_OLD: dockeronce.azurecr.io/kubernetes/rudder-transformer REPO_NAME: dockeronce.azurecr.io/kubernetes/rudder-transformer + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} jobs: + transformer-build: + name: Build transformer image + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Extract branch name + shell: bash + run: | + echo "##[set-output name=branch;]$(echo ${{ github.head_ref }} | tr "/" .)" + id: extract_branch + + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + registry: dockeronce.azurecr.io + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build image + uses: docker/build-push-action@v3 + with: + context: . + file: Dockerfile + load: true + tags: | + ${{ env.REPO_NAME }}:${{ steps.extract_branch.outputs.branch }} + + - name: Run Tests + run: | + docker run ${{ env.REPO_NAME }}:${{ steps.extract_branch.outputs.branch }} npm run test + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push multi-platform images + uses: docker/build-push-action@v3 + with: + context: . + file: Dockerfile + push: true + tags: | + ${{ env.REPO_NAME_OLD }}:${{ steps.extract_branch.outputs.branch }} + ${{ env.REPO_NAME }}:${{ steps.extract_branch.outputs.branch }} + platforms: | + linux/amd64 + linux/arm64 + build-args: | + VERSION=${{ steps.extract_branch.outputs.branch }} + COMMIT_HASH=${{ github.sha }} + user-transformer-build: name: Build user transformer image runs-on: ubuntu-latest @@ -32,26 +86,34 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and export to Docker + - name: Build image uses: docker/build-push-action@v3 with: context: . file: Dockerfile-ut-func load: true - tags: ${{ env.REPO_NAME }}:${{ steps.extract_branch.outputs.branch }} + tags: | + ${{ env.REPO_NAME }}:${{ steps.extract_branch.outputs.branch }} - name: Run Tests run: | docker run ${{ env.REPO_NAME }}:${{ steps.extract_branch.outputs.branch }} npm run test - - name: Build and push + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push multi-platform images uses: docker/build-push-action@v3 with: context: . file: Dockerfile-ut-func push: true - tags: ${{ env.REPO_NAME }}:${{ steps.extract_branch.outputs.branch }} + tags: | + ${{ env.REPO_NAME_OLD }}:${{ steps.extract_branch.outputs.branch }} + ${{ env.REPO_NAME }}:${{ steps.extract_branch.outputs.branch }} + platforms: | + linux/amd64 + linux/arm64 build-args: | VERSION=${{ steps.extract_branch.outputs.branch }} COMMIT_HASH=${{ github.sha }} - # TODO: Add Dest transformer build job after codebuild is removed diff --git a/.github/workflows/saas-builds.yml b/.github/workflows/saas-builds.yml index af8b3d9378..c8c41ae865 100644 --- a/.github/workflows/saas-builds.yml +++ b/.github/workflows/saas-builds.yml @@ -4,9 +4,63 @@ on: branches: - 'rudder-saas' env: - REPO_NAME: rudderlabs/rudder-transformer + REPO_NAME_OLD: rudderlabs/rudder-transformer + REPO_NAME: rudderstack/rudder-transformer + DOCKERHUB_USERNAME: rudderlabs jobs: + transformer-build: + name: Build transformer image + environment: production + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Get image version + id: get_version + run: | + VERSION="$(date '+%d%m%Y.%H%M%S')" + echo $VERSION + echo "::set-output name=version::$VERSION" + + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ env.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PROD_TOKEN }} + + - name: Build image + uses: docker/build-push-action@v3 + with: + context: . + file: Dockerfile + load: true + tags: ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} + + - name: Run Tests + run: | + docker run ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} npm run test + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push multi-platform images + uses: docker/build-push-action@v3 + with: + context: . + file: Dockerfile + push: true + tags: | + ${{ env.REPO_NAME_OLD }}:${{ steps.get_version.outputs.version }} + ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} + platforms: | + linux/amd64 + linux/arm64 + build-args: | + VERSION=${{ steps.get_version.outputs.version }} + COMMIT_HASH=${{ github.sha }} + user-transformer-build: name: Build user transformer image environment: production @@ -19,16 +73,16 @@ jobs: id: get_version run: | VERSION="ut-$(date '+%d%m%Y.%H%M%S')" - echo $VERSION + echo $VERSION echo "::set-output name=version::$VERSION" - name: Login to Docker Hub uses: docker/login-action@v2 with: - username: rudderlabs + username: ${{ env.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PROD_TOKEN }} - - name: Build and export to Docker + - name: Build image uses: docker/build-push-action@v3 with: context: . @@ -40,14 +94,21 @@ jobs: run: | docker run ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} npm run test - - name: Build and push + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push multi-platform images uses: docker/build-push-action@v3 with: context: . file: Dockerfile-ut-func push: true - tags: ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} + tags: | + ${{ env.REPO_NAME_OLD }}:${{ steps.get_version.outputs.version }} + ${{ env.REPO_NAME }}:${{ steps.get_version.outputs.version }} + platforms: | + linux/amd64 + linux/arm64 build-args: | VERSION=${{ steps.get_version.outputs.version }} COMMIT_HASH=${{ github.sha }} - # TODO: Add Dest transformer build job after codebuild is removed diff --git a/CHANGELOG.md b/CHANGELOG.md index 182b768516..02c9208c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,87 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.13.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.12.0...v1.13.0) (2023-02-15) + + +### Features + +* **destination:** onboard criteo audience ([#1792](https://github.com/rudderlabs/rudder-transformer/issues/1792)) ([5904c75](https://github.com/rudderlabs/rudder-transformer/commit/5904c75042c7cb34320fc43bcd3b54bfe5ce97fc)) +* **integration:** rockerbox - add support for custom properties mapping ([#1815](https://github.com/rudderlabs/rudder-transformer/issues/1815)) ([8ba50d2](https://github.com/rudderlabs/rudder-transformer/commit/8ba50d2249d5bd5db84ff9c37323e618b5942ec5)) +* **integration:** rockerbox - allow all properties to be passed over to rockerbox ([#1838](https://github.com/rudderlabs/rudder-transformer/issues/1838)) ([fb64039](https://github.com/rudderlabs/rudder-transformer/commit/fb6403992c76077398a9f8b5ac4cbe9fb28fd073)) +* **integrations:** onboarding webhook to CDK v2 ([#1783](https://github.com/rudderlabs/rudder-transformer/issues/1783)) ([22d583a](https://github.com/rudderlabs/rudder-transformer/commit/22d583ae2c239f532629a0d0db055658e2eda65d)) +* **mailchimp:** add support for track call ([#1814](https://github.com/rudderlabs/rudder-transformer/issues/1814)) ([94c10ba](https://github.com/rudderlabs/rudder-transformer/commit/94c10ba971a54f5f9894c0107a96a121068994cf)) +* moengage source ([#1846](https://github.com/rudderlabs/rudder-transformer/issues/1846)) ([123a2d9](https://github.com/rudderlabs/rudder-transformer/commit/123a2d9f57fd4f0c76f939b8d56edbbbc995ab00)) +* **new integration:** onboard optimizely fullstack cloud mode ([#1805](https://github.com/rudderlabs/rudder-transformer/issues/1805)) ([5373185](https://github.com/rudderlabs/rudder-transformer/commit/537318589110672ad6f453510a19e7fde3bfd2bb)) +* shopify - add cart token, order token and checkout token in the Context object ([#1847](https://github.com/rudderlabs/rudder-transformer/issues/1847)) ([88e8fe0](https://github.com/rudderlabs/rudder-transformer/commit/88e8fe0a14766532739aaf800cebb61b0ef6175d)) +* **source:** initial commit for identity stitching in shopify ([#1810](https://github.com/rudderlabs/rudder-transformer/issues/1810)) ([7b662df](https://github.com/rudderlabs/rudder-transformer/commit/7b662dfbf192f08f7bd2baf8dbd9dc5f12a8f23e)) +* **transformation:** libraries import extractor ([#1851](https://github.com/rudderlabs/rudder-transformer/issues/1851)) ([462bba9](https://github.com/rudderlabs/rudder-transformer/commit/462bba9e9ed49f0a76a8bb0e4d0b444e324f208c)) +* userId to be converted to string for Router ([#1822](https://github.com/rudderlabs/rudder-transformer/issues/1822)) ([7ec03c6](https://github.com/rudderlabs/rudder-transformer/commit/7ec03c66632513da4a311c3e19abcb3accf3437e)) + + +### Bug Fixes + +* **active_campaign:** handle bad url string while formatting with domainUrlV2 ([#1816](https://github.com/rudderlabs/rudder-transformer/issues/1816)) ([7fd15be](https://github.com/rudderlabs/rudder-transformer/commit/7fd15be8633c9cc6fcb4448f73042d641f81356c)) +* amplitude check for actionKey before accessing it ([#1833](https://github.com/rudderlabs/rudder-transformer/issues/1833)) ([5071582](https://github.com/rudderlabs/rudder-transformer/commit/50715827981e70e814c427cfa0359de16fb3c554)) +* bugsnag errors ([#1863](https://github.com/rudderlabs/rudder-transformer/issues/1863)) ([ae627d3](https://github.com/rudderlabs/rudder-transformer/commit/ae627d3adc48aa5ab390461693005d8957757430)) +* **CDK v2:** editing CDK v2 for pinterest tag for num_items field ([#1840](https://github.com/rudderlabs/rudder-transformer/issues/1840)) ([b1265c0](https://github.com/rudderlabs/rudder-transformer/commit/b1265c0949f8352881dfb13d5d31ba712e26363b)) +* codebuild issue ([16eab14](https://github.com/rudderlabs/rudder-transformer/commit/16eab14e627184d04b1a7dbb1fdd3388ff065c85)) +* criteo_audience: stringification of destination error ([#1839](https://github.com/rudderlabs/rudder-transformer/issues/1839)) ([fe17453](https://github.com/rudderlabs/rudder-transformer/commit/fe17453db7bef03916feb271bae1c25b613829da)) +* ga4 userId issue ([#1857](https://github.com/rudderlabs/rudder-transformer/issues/1857)) ([cd30c47](https://github.com/rudderlabs/rudder-transformer/commit/cd30c47f292db71a8961bef6b38a3478316e00b9)) +* **integration:** Pinterest conversion in CDK v2 returns correct num_items for single product array ([#1861](https://github.com/rudderlabs/rudder-transformer/issues/1861)) ([8c8c316](https://github.com/rudderlabs/rudder-transformer/commit/8c8c316b9ba795111f716c314cedb189e968260e)) +* **integrations:** salesforce update error message and error response handler ([#1799](https://github.com/rudderlabs/rudder-transformer/issues/1799)) ([b473c23](https://github.com/rudderlabs/rudder-transformer/commit/b473c2389909e1f06d8d79b279e66b86b414c908)) +* **klaviyo:** skip profile lookup call for rETL events ([#1856](https://github.com/rudderlabs/rudder-transformer/issues/1856)) ([9e6b5e4](https://github.com/rudderlabs/rudder-transformer/commit/9e6b5e4c145d64341e043014baed4e344fecc74c)) +* order_token updated in shopify ([#1865](https://github.com/rudderlabs/rudder-transformer/issues/1865)) ([7fc608e](https://github.com/rudderlabs/rudder-transformer/commit/7fc608e0f1c264c4494b987e0102ff48aa51e4fe)) +* package.json & package-lock.json to reduce vulnerabilities ([#1824](https://github.com/rudderlabs/rudder-transformer/issues/1824)) ([779edb2](https://github.com/rudderlabs/rudder-transformer/commit/779edb290b04694b126739708a30be024a53fe33)) +* refactor subscribe user flow to stop subscribing user without consent ([#1841](https://github.com/rudderlabs/rudder-transformer/issues/1841)) ([fe231c2](https://github.com/rudderlabs/rudder-transformer/commit/fe231c280a1250413f4b665820e4da303e05259a)) +* set context as metadata in bugsnag error notification ([#1778](https://github.com/rudderlabs/rudder-transformer/issues/1778)) ([55c3097](https://github.com/rudderlabs/rudder-transformer/commit/55c309716877b303943c18537352347b83d72c2f)) +* **singular:** undefined properties object for track ([#1808](https://github.com/rudderlabs/rudder-transformer/issues/1808)) ([f53bec1](https://github.com/rudderlabs/rudder-transformer/commit/f53bec192825aedfcf320197c386a449f9677816)) +* **transformation:** release isolate in case of error while creating ([#1850](https://github.com/rudderlabs/rudder-transformer/issues/1850)) ([ea51e24](https://github.com/rudderlabs/rudder-transformer/commit/ea51e24a893daa18e9b30463e9300ce029230a00)) +* typecast userId, anonymousId to string ([2150033](https://github.com/rudderlabs/rudder-transformer/commit/215003381557c583bd8889cef121ebbba56785c2)) +* undefined check added for isHybridModeEnabled function ([#1812](https://github.com/rudderlabs/rudder-transformer/issues/1812)) ([a49be9e](https://github.com/rudderlabs/rudder-transformer/commit/a49be9e77b6ba6bc1ef5087208ddc1a135e4301e)) +* update check for props value ([343e946](https://github.com/rudderlabs/rudder-transformer/commit/343e946ed4adc89ad8c17d945b69c2f3f3be7506)) + + +### Miscellaneous + +* add instanceName tag to statsd metrics ([#1860](https://github.com/rudderlabs/rudder-transformer/issues/1860)) ([e1984b1](https://github.com/rudderlabs/rudder-transformer/commit/e1984b171cfcb4501922b141b903ca64c4d6bdfc)) +* add logging for cdk v2 for debugging comparison failures ([#1820](https://github.com/rudderlabs/rudder-transformer/issues/1820)) ([bac5ca4](https://github.com/rudderlabs/rudder-transformer/commit/bac5ca4292f85ac7f05510590fbc7eb8c4c73949)) +* add support for multi platform docker images ([#1235](https://github.com/rudderlabs/rudder-transformer/issues/1235)) ([7d29cb1](https://github.com/rudderlabs/rudder-transformer/commit/7d29cb1ac4d1695311044cb00181dc00e91d9962)) +* add type declaration file to eslint ignore ([f8de632](https://github.com/rudderlabs/rudder-transformer/commit/f8de632887e82db2372d1d639cd99191bb63db34)) +* add unit tests for extractCustomFields function ([#1848](https://github.com/rudderlabs/rudder-transformer/issues/1848)) ([6fd1278](https://github.com/rudderlabs/rudder-transformer/commit/6fd1278dd25e78c24c1cb4da90c92c9977be25ed)) +* email made unmandatory ([#1819](https://github.com/rudderlabs/rudder-transformer/issues/1819)) ([65f42ae](https://github.com/rudderlabs/rudder-transformer/commit/65f42ae4bd8809a9eb60a7d38886de6356c04648)) +* refactor utility function test scripts ([#1832](https://github.com/rudderlabs/rudder-transformer/issues/1832)) ([7ce889a](https://github.com/rudderlabs/rudder-transformer/commit/7ce889aba987dba14fea4bef8d8e59648eaaa212)) +* **trackingplan:** added ajv format definitions support ([#1806](https://github.com/rudderlabs/rudder-transformer/issues/1806)) ([c0f46fc](https://github.com/rudderlabs/rudder-transformer/commit/c0f46fc5855f9793089aa3a9a92e630e5227e8e4)) +* unit test suite for integrations ([#1835](https://github.com/rudderlabs/rudder-transformer/issues/1835)) ([8bb0927](https://github.com/rudderlabs/rudder-transformer/commit/8bb09276813a463f8b16fc66ac5b7aaf18b8017c)) + +## [1.12.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.11.1...v1.12.0) (2023-01-19) + + +### Features + +* **BQStream:** add batch support ([#1377](https://github.com/rudderlabs/rudder-transformer/issues/1377)) ([14c7531](https://github.com/rudderlabs/rudder-transformer/commit/14c7531635b5348ef518dcad483f25d4adeddddd)) +* **destination:** onboard lemnisk integration ([#1787](https://github.com/rudderlabs/rudder-transformer/issues/1787)) ([3c6b9e1](https://github.com/rudderlabs/rudder-transformer/commit/3c6b9e148dff559357fb61de49602f9d1689d699)) +* ga4 page calls are discarded if hybrid mode is enabled ([#1794](https://github.com/rudderlabs/rudder-transformer/issues/1794)) ([ca12d07](https://github.com/rudderlabs/rudder-transformer/commit/ca12d078e3f936c4c0fd4449259d1a55ba0a4424)) +* sessionId consistency across destinations ([#1789](https://github.com/rudderlabs/rudder-transformer/issues/1789)) ([ff68a44](https://github.com/rudderlabs/rudder-transformer/commit/ff68a4488e50f4a44c950395d0f9e5dc514db1df)) + + +### Bug Fixes + +* add sources as valid channel to cdkv1 ([bd74ef7](https://github.com/rudderlabs/rudder-transformer/commit/bd74ef7eff712d4db75856a205ddaa473d80ddd9)) +* add sources as valid channel to cdkv1 ([#1803](https://github.com/rudderlabs/rudder-transformer/issues/1803)) ([e3057db](https://github.com/rudderlabs/rudder-transformer/commit/e3057dbff9d8daa1f64b5cd6de6b57ab97c016ee)) +* array type check for externalIdArray ([#1785](https://github.com/rudderlabs/rudder-transformer/issues/1785)) ([dec3bb6](https://github.com/rudderlabs/rudder-transformer/commit/dec3bb6661b6737203964b2c4b5e3d2bd7421433)) +* change destination configuration errors to abortable ([#1790](https://github.com/rudderlabs/rudder-transformer/issues/1790)) ([fb1281d](https://github.com/rudderlabs/rudder-transformer/commit/fb1281d2bc090bda34c7420c10946504e83756ef)) +* **integration:** GAOC - fix timestamp format, allow calls without custom variables ([#1796](https://github.com/rudderlabs/rudder-transformer/issues/1796)) ([7c450ee](https://github.com/rudderlabs/rudder-transformer/commit/7c450ee78db2052bbb70866cbc6bd98cfd9c32b4)) +* iterable alias call is separated from identify batching ([#1777](https://github.com/rudderlabs/rudder-transformer/issues/1777)) ([3676c45](https://github.com/rudderlabs/rudder-transformer/commit/3676c4591e8b241ad6a7873954bc8f07e7a69584)) +* products array mapping and rename impact_radius to impact ([#1797](https://github.com/rudderlabs/rudder-transformer/issues/1797)) ([f812f0d](https://github.com/rudderlabs/rudder-transformer/commit/f812f0d3fbff6d6bfdd3670c59cf8ea01744f80f)) +* remove regex validation for phone_number ([#1771](https://github.com/rudderlabs/rudder-transformer/issues/1771)) ([6c01642](https://github.com/rudderlabs/rudder-transformer/commit/6c016428b496cea7e3771d3cf5ab4dfbbd7e382b)) + + +### Miscellaneous + +* fix formatting and linting issues ([#1772](https://github.com/rudderlabs/rudder-transformer/issues/1772)) ([fb8b818](https://github.com/rudderlabs/rudder-transformer/commit/fb8b818b2cbd05f784117b9f3040856dab1a7346)) +* **owner:** added a code owner ([#1793](https://github.com/rudderlabs/rudder-transformer/issues/1793)) ([1c6f92a](https://github.com/rudderlabs/rudder-transformer/commit/1c6f92a90363489bfc3e9430ec50fb30b2a65557)) + ## [1.11.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.11.0...v1.11.1) (2023-01-13) diff --git a/buildspec.dev.yml b/buildspec.dev.yml index 85b7cfba8c..07e7f413eb 100644 --- a/buildspec.dev.yml +++ b/buildspec.dev.yml @@ -4,6 +4,13 @@ phases: install: runtime-versions: nodejs: 14 + commands: + - 'echo "${DOCKERHUB_PASSWORD}" | docker login --username rudderlabs --password-stdin' + - wget https://github.com/docker/buildx/releases/download/v0.10.2/buildx-v0.10.2.linux-amd64 + - mkdir -p ~/.docker/cli-plugins + - mv buildx-v0.10.2.linux-amd64 ~/.docker/cli-plugins/docker-buildx + - chmod a+rx ~/.docker/cli-plugins/docker-buildx + - docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 pre_build: commands: - docker login --username rudderlabs --password $DOCKERHUB_PASSWORD @@ -17,14 +24,28 @@ phases: --build-arg version=${VERSION} --build-arg GIT_COMMIT_SHA=$CODEBUILD_RESOLVED_SOURCE_VERSION -t rudderlabs/develop-rudder-transformer:$VERSION + -t rudderstack/develop-rudder-transformer:$VERSION -f Dockerfile . - - docker run rudderlabs/develop-rudder-transformer:$VERSION npm run test + - docker run rudderstack/develop-rudder-transformer:$VERSION npm run test - echo $? post_build: commands: - echo build Docker image complete `date` - echo push latest Docker images to docker hub... - - docker push rudderlabs/develop-rudder-transformer:$VERSION + + # creates a docker builder instance to build multi-platform docker images + - docker buildx create --use + + # builds and pushes multi-platform docker images to docker registry + - > + docker buildx build + --build-arg version=${VERSION} + --build-arg GIT_COMMIT_SHA=$CODEBUILD_RESOLVED_SOURCE_VERSION + --platform=linux/amd64,linux/arm64 + -t rudderlabs/develop-rudder-transformer:$VERSION + -t rudderstack/develop-rudder-transformer:$VERSION + -f Dockerfile + --push . artifacts: files: - '**/*' diff --git a/buildspec.master.yml b/buildspec.master.yml index cad4e15ac6..91eb201935 100644 --- a/buildspec.master.yml +++ b/buildspec.master.yml @@ -4,6 +4,13 @@ phases: install: runtime-versions: nodejs: 14 + commands: + - 'echo "${DOCKERHUB_PASSWORD}" | docker login --username rudderlabs --password-stdin' + - wget https://github.com/docker/buildx/releases/download/v0.10.2/buildx-v0.10.2.linux-amd64 + - mkdir -p ~/.docker/cli-plugins + - mv buildx-v0.10.2.linux-amd64 ~/.docker/cli-plugins/docker-buildx + - chmod a+rx ~/.docker/cli-plugins/docker-buildx + - docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 pre_build: commands: - docker login --username rudderlabs --password $DOCKERHUB_PASSWORD @@ -17,14 +24,28 @@ phases: --build-arg version=${VERSION} --build-arg GIT_COMMIT_SHA=$CODEBUILD_RESOLVED_SOURCE_VERSION -t rudderlabs/develop-rudder-transformer:$VERSION + -t rudderstack/develop-rudder-transformer:$VERSION -f Dockerfile . - - docker run rudderlabs/develop-rudder-transformer:$VERSION npm run test + - docker run rudderstack/develop-rudder-transformer:$VERSION npm run test - echo $? post_build: commands: - echo build Docker image complete `date` - echo push latest Docker images to docker hub... - - docker push rudderlabs/develop-rudder-transformer:$VERSION + + # creates a docker builder instance to build multi-platform docker images + - docker buildx create --use + + # builds and pushes multi-platform docker images to docker registry + - > + docker buildx build + --build-arg version=${VERSION} + --build-arg GIT_COMMIT_SHA=$CODEBUILD_RESOLVED_SOURCE_VERSION + --platform=linux/amd64,linux/arm64 + -t rudderlabs/develop-rudder-transformer:$VERSION + -t rudderstack/develop-rudder-transformer:$VERSION + -f Dockerfile + --push . artifacts: files: - '**/*' diff --git a/buildspec.saas.yml b/buildspec.saas.yml index 1f724bd372..f598719fec 100644 --- a/buildspec.saas.yml +++ b/buildspec.saas.yml @@ -13,8 +13,15 @@ phases: commands: - wget https://github.com/mikefarah/yq/releases/download/v4.9.6/yq_linux_amd64 -O /usr/bin/yq - chmod +x /usr/bin/yq + - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - - apt-get update - apt install -y hub + - 'echo "${DOCKERHUB_PASSWORD}" | docker login --username rudderlabs --password-stdin' + - wget https://github.com/docker/buildx/releases/download/v0.10.2/buildx-v0.10.2.linux-amd64 + - mkdir -p ~/.docker/cli-plugins + - mv buildx-v0.10.2.linux-amd64 ~/.docker/cli-plugins/docker-buildx + - chmod a+rx ~/.docker/cli-plugins/docker-buildx + - docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 pre_build: commands: - docker login --username rudderlabs --password $dockerhub_passwd @@ -27,14 +34,31 @@ phases: --build-arg version=${VERSION} --build-arg GIT_COMMIT_SHA=$CODEBUILD_RESOLVED_SOURCE_VERSION -t rudderlabs/rudder-transformer:$VERSION + -t rudderstack/rudder-transformer:$VERSION -f Dockerfile . - - docker run rudderlabs/rudder-transformer:$VERSION npm run test + - docker run rudderstack/rudder-transformer:$VERSION npm run test - echo $? - - docker tag rudderlabs/rudder-transformer:$VERSION rudderlabs/rudder-transformer:latest post_build: commands: - - docker push rudderlabs/rudder-transformer:$VERSION - - docker push rudderlabs/rudder-transformer:latest + - VERSION="$(date '+%d%m%Y.%H%M%S')" + + # creates a docker builder instance to build multi-platform docker images + - docker buildx create --use + + # builds and pushes multi-platform docker images to docker registry + - > + docker buildx build + --build-arg version=${VERSION} + --build-arg GIT_COMMIT_SHA=$CODEBUILD_RESOLVED_SOURCE_VERSION + --platform=linux/amd64,linux/arm64 + -t rudderlabs/rudder-transformer:latest + -t rudderlabs/rudder-transformer:$VERSION + -t rudderstack/rudder-transformer:latest + -t rudderstack/rudder-transformer:$VERSION + -f Dockerfile + --push . + + # raise a pull request to update default transformer version - git clone https://$GITHUB_TOKEN@github.com/rudderlabs/rudder-devops.git - git config --global user.email \"$MAIL\" - git config --global user.name \"$USER_NAME\" diff --git a/buildspec.saasdev.yml b/buildspec.saasdev.yml index 204e4fdbe4..4bd110fbab 100644 --- a/buildspec.saasdev.yml +++ b/buildspec.saasdev.yml @@ -4,6 +4,13 @@ phases: install: runtime-versions: nodejs: 14 + commands: + - 'echo "${DOCKERHUB_PASSWORD}" | docker login --username rudderlabs --password-stdin' + - wget https://github.com/docker/buildx/releases/download/v0.10.2/buildx-v0.10.2.linux-amd64 + - mkdir -p ~/.docker/cli-plugins + - mv buildx-v0.10.2.linux-amd64 ~/.docker/cli-plugins/docker-buildx + - chmod a+rx ~/.docker/cli-plugins/docker-buildx + - docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 pre_build: commands: - docker login --username rudderlabs --password $DOCKERHUB_PASSWORD @@ -17,14 +24,28 @@ phases: --build-arg version=${VERSION} --build-arg GIT_COMMIT_SHA=$CODEBUILD_RESOLVED_SOURCE_VERSION -t rudderlabs/develop-rudder-transformer:$VERSION + -t rudderstack/develop-rudder-transformer:$VERSION -f Dockerfile . - - docker run rudderlabs/develop-rudder-transformer:$VERSION npm run test + - docker run rudderstack/develop-rudder-transformer:$VERSION npm run test - echo $? post_build: commands: - echo build Docker image complete `date` - echo push latest Docker images to docker hub... - - docker push rudderlabs/develop-rudder-transformer:$VERSION + + # creates a docker builder instance to build multi-platform docker images + - docker buildx create --use + + # builds and pushes multi-platform docker images to docker registry + - > + docker buildx build + --build-arg version=${VERSION} + --build-arg GIT_COMMIT_SHA=$CODEBUILD_RESOLVED_SOURCE_VERSION + --platform=linux/amd64,linux/arm64 + -t rudderlabs/develop-rudder-transformer:$VERSION + -t rudderstack/develop-rudder-transformer:$VERSION + -f Dockerfile + --push . artifacts: files: - '**/*' diff --git a/buildspec.yml b/buildspec.yml index 915d93ee02..a146df0726 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -6,7 +6,7 @@ phases: nodejs: 14 pre_build: commands: - - docker login --username rudderlabs --password $DOCKERHUB_PASSWORD + - docker login --username rudderlabs --password ${{ secrets.DOCKERHUB_PROD_TOKEN }} build: commands: - VERSION=$(head -1 .version) diff --git a/features.json b/features.json index 4fdfba81b7..4662836e6d 100644 --- a/features.json +++ b/features.json @@ -51,6 +51,7 @@ "SENDINBLUE": true, "ZENDESK": true, "MP": true, - "TIKTOK_ADS_OFFLINE_EVENTS": true + "TIKTOK_ADS_OFFLINE_EVENTS": true, + "CRITEO_AUDIENCE": true } } diff --git a/package-lock.json b/package-lock.json index c5fdad5a30..f7f5a368ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,22 +1,23 @@ { "name": "rudder-transformer", - "version": "1.11.1", + "version": "1.14.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.11.1", + "version": "1.14.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "0.7.24", "@aws-sdk/client-lambda": "^3.245.0", - "@aws-sdk/client-s3": "^3.245.0", + "@aws-sdk/client-s3": "^3.276.0", "@aws-sdk/lib-storage": "^3.245.0", "@bugsnag/js": "^7.18.0", "@ndhoule/extend": "^2.0.0", "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", + "ajv-formats": "^2.1.1", "aws-sdk": "^2.1292.0", "axios": "^0.27.2", "btoa": "^1.2.1", @@ -51,16 +52,14 @@ "object-hash": "^2.2.0", "parse-static-imports": "^1.1.0", "pprof": "^3.2.0", - "prom-client": "^14.0.1", - "qs": "^6.11.0", - "readline-sync": "^1.4.10", - "rudder-transformer-cdk": "^1.4.3", + "prom-client": "^14.1.1", + "rudder-transformer-cdk": "^1.4.5", "rudder-workflow-engine": "0.4.0", "set-value": "^4.1.0", "sha256": "^0.2.0", "statsd-client": "^0.4.7", "truncate-utf8-bytes": "^1.0.2", - "ua-parser-js": "^0.8.1", + "ua-parser-js": "^1.0.33", "unset-value": "^2.0.1", "uuid": "^8.3.2", "valid-url": "^1.0.9" @@ -91,7 +90,8 @@ "node-notifier": "^10.0.1", "pre-commit": "^1.2.2", "prettier": "^2.8.2", - "standard-version": "^9.5.0" + "standard-version": "^9.5.0", + "supertest": "^6.3.3" } }, "node_modules/@amplitude/ua-parser-js": { @@ -115,12 +115,22 @@ } }, "node_modules/@aws-crypto/crc32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-2.0.0.tgz", - "integrity": "sha512-TvE1r2CUueyXOuHdEigYjIZVesInd9KN+K/TFFNfkkxRThiNxO6i4ZqqAVMoEjAamZZ1AA8WXJkjCz7YShHPQA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", "dependencies": { - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32/node_modules/@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } }, @@ -130,12 +140,22 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-crypto/crc32c": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-2.0.0.tgz", - "integrity": "sha512-vF0eMdMHx3O3MoOXUfBZry8Y4ZDtcuskjjKgJz8YfIDjLStxTZrYXk+kZqtl6A0uCmmiN/Eb/JbC/CndTV1MHg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz", + "integrity": "sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==", "dependencies": { - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32c/node_modules/@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } }, @@ -158,227 +178,1073 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-crypto/sha1-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz", + "integrity": "sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@aws-crypto/ie11-detection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-browser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-2.0.0.tgz", - "integrity": "sha512-3fIVRjPFY8EG5HWXR+ZJZMdWNRpwbxGzJ9IH9q93FpbgCH8u8GHRi46mZXp3cYD7gealmyqpm3ThZwLKJjWJhA==", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-2.0.0.tgz", + "integrity": "sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==", "dependencies": { "@aws-crypto/ie11-detection": "^2.0.0", + "@aws-crypto/sha256-js": "^2.0.0", "@aws-crypto/supports-web-crypto": "^2.0.0", + "@aws-crypto/util": "^2.0.0", "@aws-sdk/types": "^3.1.0", "@aws-sdk/util-locate-window": "^3.0.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } }, - "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-2.0.0.tgz", - "integrity": "sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==", + "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-2.0.0.tgz", + "integrity": "sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==", + "dependencies": { + "@aws-crypto/util": "^2.0.0", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.2.tgz", + "integrity": "sha512-6mbSsLHwZ99CTOOswvCRP3C+VCWnzBf+1SnbWxzzJ9lR0mA0JnY2JEAhp8rqmTE0GPFy88rrM27ffgp62oErMQ==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.2.tgz", + "integrity": "sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA==", + "dependencies": { + "@aws-sdk/types": "^3.110.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/abort-controller": { + "version": "3.226.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.226.0.tgz", + "integrity": "sha512-cJVzr1xxPBd08voknXvR0RLgtZKGKt6WyDpH/BaPCu3rfSqWCDZKzwqe940eqosjmKrxC6pUZNKASIqHOQ8xxQ==", + "dependencies": { + "@aws-sdk/types": "3.226.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/chunked-blob-reader": { + "version": "3.188.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.188.0.tgz", + "integrity": "sha512-zkPRFZZPL3eH+kH86LDYYXImiClA1/sW60zYOjse9Pgka+eDJlvBN6hcYxwDEKjcwATYiSRR1aVQHcfCinlGXg==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/chunked-blob-reader-native": { + "version": "3.208.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader-native/-/chunked-blob-reader-native-3.208.0.tgz", + "integrity": "sha512-JeOZ95PW+fJ6bbuqPySYqLqHk1n4+4ueEEraJsiUrPBV0S1ZtyvOGHcnGztKUjr2PYNaiexmpWuvUve9K12HRA==", + "dependencies": { + "@aws-sdk/util-base64": "3.208.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/client-lambda": { + "version": "3.245.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.245.0.tgz", + "integrity": "sha512-vhC9MPWclA3/qMUzOMu6Xc3sQ1iJJFQ+h7kbnYMbQFDQWIN24O/HqmdLJ3iGcIYLd8vw3jpz6dQB/OCKSPIPVg==", + "dependencies": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/client-sts": "3.245.0", + "@aws-sdk/config-resolver": "3.234.0", + "@aws-sdk/credential-provider-node": "3.245.0", + "@aws-sdk/fetch-http-handler": "3.226.0", + "@aws-sdk/hash-node": "3.226.0", + "@aws-sdk/invalid-dependency": "3.226.0", + "@aws-sdk/middleware-content-length": "3.226.0", + "@aws-sdk/middleware-endpoint": "3.226.0", + "@aws-sdk/middleware-host-header": "3.226.0", + "@aws-sdk/middleware-logger": "3.226.0", + "@aws-sdk/middleware-recursion-detection": "3.226.0", + "@aws-sdk/middleware-retry": "3.235.0", + "@aws-sdk/middleware-serde": "3.226.0", + "@aws-sdk/middleware-signing": "3.226.0", + "@aws-sdk/middleware-stack": "3.226.0", + "@aws-sdk/middleware-user-agent": "3.226.0", + "@aws-sdk/node-config-provider": "3.226.0", + "@aws-sdk/node-http-handler": "3.226.0", + "@aws-sdk/protocol-http": "3.226.0", + "@aws-sdk/smithy-client": "3.234.0", + "@aws-sdk/types": "3.226.0", + "@aws-sdk/url-parser": "3.226.0", + "@aws-sdk/util-base64": "3.208.0", + "@aws-sdk/util-body-length-browser": "3.188.0", + "@aws-sdk/util-body-length-node": "3.208.0", + "@aws-sdk/util-defaults-mode-browser": "3.234.0", + "@aws-sdk/util-defaults-mode-node": "3.234.0", + "@aws-sdk/util-endpoints": "3.245.0", + "@aws-sdk/util-retry": "3.229.0", + "@aws-sdk/util-user-agent-browser": "3.226.0", + "@aws-sdk/util-user-agent-node": "3.226.0", + "@aws-sdk/util-utf8-browser": "3.188.0", + "@aws-sdk/util-utf8-node": "3.208.0", + "@aws-sdk/util-waiter": "3.226.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.276.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.276.0.tgz", + "integrity": "sha512-9cwrYeMTx9a9MUWSxBr2i87NACEw3Vc8ALnDYZSvhps8UivdgZ1v3zN8c0v/g/3RrJJNco2HCs9je+lOPRvq3w==", + "dependencies": { + "@aws-crypto/sha1-browser": "3.0.0", + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.276.0", + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/credential-provider-node": "3.272.0", + "@aws-sdk/eventstream-serde-browser": "3.272.0", + "@aws-sdk/eventstream-serde-config-resolver": "3.272.0", + "@aws-sdk/eventstream-serde-node": "3.272.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/hash-blob-browser": "3.272.0", + "@aws-sdk/hash-node": "3.272.0", + "@aws-sdk/hash-stream-node": "3.272.0", + "@aws-sdk/invalid-dependency": "3.272.0", + "@aws-sdk/md5-js": "3.272.0", + "@aws-sdk/middleware-bucket-endpoint": "3.272.0", + "@aws-sdk/middleware-content-length": "3.272.0", + "@aws-sdk/middleware-endpoint": "3.272.0", + "@aws-sdk/middleware-expect-continue": "3.272.0", + "@aws-sdk/middleware-flexible-checksums": "3.272.0", + "@aws-sdk/middleware-host-header": "3.272.0", + "@aws-sdk/middleware-location-constraint": "3.272.0", + "@aws-sdk/middleware-logger": "3.272.0", + "@aws-sdk/middleware-recursion-detection": "3.272.0", + "@aws-sdk/middleware-retry": "3.272.0", + "@aws-sdk/middleware-sdk-s3": "3.272.0", + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/middleware-signing": "3.272.0", + "@aws-sdk/middleware-ssec": "3.272.0", + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/middleware-user-agent": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4-multi-region": "3.272.0", + "@aws-sdk/smithy-client": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "@aws-sdk/util-body-length-browser": "3.188.0", + "@aws-sdk/util-body-length-node": "3.208.0", + "@aws-sdk/util-defaults-mode-browser": "3.272.0", + "@aws-sdk/util-defaults-mode-node": "3.272.0", + "@aws-sdk/util-endpoints": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "@aws-sdk/util-stream-browser": "3.272.0", + "@aws-sdk/util-stream-node": "3.272.0", + "@aws-sdk/util-user-agent-browser": "3.272.0", + "@aws-sdk/util-user-agent-node": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "@aws-sdk/util-waiter": "3.272.0", + "@aws-sdk/xml-builder": "3.201.0", + "fast-xml-parser": "4.1.2", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/ie11-detection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/sha256-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", + "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/sha256-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", + "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/abort-controller": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.272.0.tgz", + "integrity": "sha512-s2TV3phapcTwZNr4qLxbfuQuE9ZMP4RoJdkvRRCkKdm6jslsWLJf2Zlcxti/23hOlINUMYv2iXE2pftIgWGdpg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/client-sso": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.272.0.tgz", + "integrity": "sha512-xn9a0IGONwQIARmngThoRhF1lLGjHAD67sUaShgIMaIMc6ipVYN6alWG1VuUpoUQ6iiwMEt0CHdfCyLyUV/fTA==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/hash-node": "3.272.0", + "@aws-sdk/invalid-dependency": "3.272.0", + "@aws-sdk/middleware-content-length": "3.272.0", + "@aws-sdk/middleware-endpoint": "3.272.0", + "@aws-sdk/middleware-host-header": "3.272.0", + "@aws-sdk/middleware-logger": "3.272.0", + "@aws-sdk/middleware-recursion-detection": "3.272.0", + "@aws-sdk/middleware-retry": "3.272.0", + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/middleware-user-agent": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/smithy-client": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "@aws-sdk/util-body-length-browser": "3.188.0", + "@aws-sdk/util-body-length-node": "3.208.0", + "@aws-sdk/util-defaults-mode-browser": "3.272.0", + "@aws-sdk/util-defaults-mode-node": "3.272.0", + "@aws-sdk/util-endpoints": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "@aws-sdk/util-user-agent-browser": "3.272.0", + "@aws-sdk/util-user-agent-node": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.272.0.tgz", + "integrity": "sha512-ECcXu3xoa1yggnGKMTh29eWNHiF/wC6r5Uqbla22eOOosyh0+Z6lkJ3JUSLOUKCkBXA4Cs/tJL9UDFBrKbSlvA==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/hash-node": "3.272.0", + "@aws-sdk/invalid-dependency": "3.272.0", + "@aws-sdk/middleware-content-length": "3.272.0", + "@aws-sdk/middleware-endpoint": "3.272.0", + "@aws-sdk/middleware-host-header": "3.272.0", + "@aws-sdk/middleware-logger": "3.272.0", + "@aws-sdk/middleware-recursion-detection": "3.272.0", + "@aws-sdk/middleware-retry": "3.272.0", + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/middleware-user-agent": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/smithy-client": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "@aws-sdk/util-body-length-browser": "3.188.0", + "@aws-sdk/util-body-length-node": "3.208.0", + "@aws-sdk/util-defaults-mode-browser": "3.272.0", + "@aws-sdk/util-defaults-mode-node": "3.272.0", + "@aws-sdk/util-endpoints": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "@aws-sdk/util-user-agent-browser": "3.272.0", + "@aws-sdk/util-user-agent-node": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/client-sts": { + "version": "3.276.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.276.0.tgz", + "integrity": "sha512-J6FR4tYa/WdDdwWAKhw/mXQXKWUaZZQpMiyFEbFPQyURSWu3u17nv97NUdvVOgCth48H6Wb6a4ksssYy4K9tFQ==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/credential-provider-node": "3.272.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/hash-node": "3.272.0", + "@aws-sdk/invalid-dependency": "3.272.0", + "@aws-sdk/middleware-content-length": "3.272.0", + "@aws-sdk/middleware-endpoint": "3.272.0", + "@aws-sdk/middleware-host-header": "3.272.0", + "@aws-sdk/middleware-logger": "3.272.0", + "@aws-sdk/middleware-recursion-detection": "3.272.0", + "@aws-sdk/middleware-retry": "3.272.0", + "@aws-sdk/middleware-sdk-sts": "3.272.0", + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/middleware-signing": "3.272.0", + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/middleware-user-agent": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/smithy-client": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "@aws-sdk/util-body-length-browser": "3.188.0", + "@aws-sdk/util-body-length-node": "3.208.0", + "@aws-sdk/util-defaults-mode-browser": "3.272.0", + "@aws-sdk/util-defaults-mode-node": "3.272.0", + "@aws-sdk/util-endpoints": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "@aws-sdk/util-user-agent-browser": "3.272.0", + "@aws-sdk/util-user-agent-node": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "fast-xml-parser": "4.1.2", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/config-resolver": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.272.0.tgz", + "integrity": "sha512-Dr4CffRVNsOp3LRNdpvcH6XuSgXOSLblWliCy/5I86cNl567KVMxujVx6uPrdTXYs2h1rt3MNl6jQGnAiJeTbw==", + "dependencies": { + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-config-provider": "3.208.0", + "@aws-sdk/util-middleware": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.272.0.tgz", + "integrity": "sha512-QI65NbLnKLYHyTYhXaaUrq6eVsCCrMUb05WDA7+TJkWkjXesovpjc8vUKgFiLSxmgKmb2uOhHNcDyObKMrYQFw==", + "dependencies": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/credential-provider-imds": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.272.0.tgz", + "integrity": "sha512-wwAfVY1jTFQEfxVfdYD5r5ieYGl+0g4nhekVxNMqE8E1JeRDd18OqiwAflzpgBIqxfqvCUkf+vl5JYyacMkNAQ==", + "dependencies": { + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.272.0.tgz", + "integrity": "sha512-iE3CDzK5NcupHYjfYjBdY1JCy8NLEoRUsboEjG0i0gy3S3jVpDeVHX1dLVcL/slBFj6GiM7SoNV/UfKnJf3Gaw==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.272.0", + "@aws-sdk/credential-provider-imds": "3.272.0", + "@aws-sdk/credential-provider-process": "3.272.0", + "@aws-sdk/credential-provider-sso": "3.272.0", + "@aws-sdk/credential-provider-web-identity": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.272.0.tgz", + "integrity": "sha512-FI8uvwM1IxiRSvbkdKv8DZG5vxU3ezaseTaB1fHWTxEUFb0pWIoHX9oeOKer9Fj31SOZTCNAaYFURbSRuZlm/w==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.272.0", + "@aws-sdk/credential-provider-imds": "3.272.0", + "@aws-sdk/credential-provider-ini": "3.272.0", + "@aws-sdk/credential-provider-process": "3.272.0", + "@aws-sdk/credential-provider-sso": "3.272.0", + "@aws-sdk/credential-provider-web-identity": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.272.0.tgz", + "integrity": "sha512-hiCAjWWm2PeBFp5cjkxqyam/XADjiS+e7GzwC34TbZn3LisS0uoweLojj9tD11NnnUhyhbLteUvu5+rotOLwrg==", + "dependencies": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.272.0.tgz", + "integrity": "sha512-hwYaulyiU/7chKKFecxCeo0ls6Dxs7h+5EtoYcJJGvfpvCncyOZF35t00OAsCd3Wo7HkhhgfpGdb6dmvCNQAZQ==", + "dependencies": { + "@aws-sdk/client-sso": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/token-providers": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.272.0.tgz", + "integrity": "sha512-ImrHMkcgneGa/HadHAQXPwOrX26sAKuB8qlMxZF/ZCM2B55u8deY+ZVkVuraeKb7YsahMGehPFOfRAF6mvFI5Q==", + "dependencies": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/fetch-http-handler": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.272.0.tgz", + "integrity": "sha512-1Qhm9e0RbS1Xf4CZqUbQyUMkDLd7GrsRXWIvm9b86/vgeV8/WnjO3CMue9D51nYgcyQORhYXv6uVjAYCWbUExA==", + "dependencies": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/querystring-builder": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/hash-node": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.272.0.tgz", + "integrity": "sha512-40dwND+iAm3VtPHPZu7/+CIdVJFk2s0cWZt1lOiMPMSXycSYJ45wMk7Lly3uoqRx0uWfFK5iT2OCv+fJi5jTng==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-buffer-from": "3.208.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/invalid-dependency": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.272.0.tgz", + "integrity": "sha512-ysW6wbjl1Y78txHUQ/Tldj2Rg1BI7rpMO9B9xAF6yAX3mQ7t6SUPQG/ewOGvH2208NBIl3qP5e/hDf0Q6r/1iw==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-content-length": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.272.0.tgz", + "integrity": "sha512-sAbDZSTNmLX+UTGwlUHJBWy0QGQkiClpHwVFXACon+aG0ySLNeRKEVYs6NCPYldw4cj6hveLUn50cX44ukHErw==", + "dependencies": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-endpoint": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.272.0.tgz", + "integrity": "sha512-Dk3JVjj7SxxoUKv3xGiOeBksvPtFhTDrVW75XJ98Ymv8gJH5L1sq4hIeJAHRKogGiRFq2J73mnZSlM9FVXEylg==", + "dependencies": { + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "@aws-sdk/util-config-provider": "3.208.0", + "@aws-sdk/util-middleware": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-host-header": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.272.0.tgz", + "integrity": "sha512-Q8K7bMMFZnioUXpxn57HIt4p+I63XaNAawMLIZ5B4F2piyukbQeM9q2XVKMGwqLvijHR8CyP5nHrtKqVuINogQ==", + "dependencies": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-logger": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.272.0.tgz", + "integrity": "sha512-u2SQ0hWrFwxbxxYMG5uMEgf01pQY5jauK/LYWgGIvuCmFgiyRQQP3oN7kkmsxnS9MWmNmhbyQguX2NY02s5e9w==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.272.0.tgz", + "integrity": "sha512-Gp/eKWeUWVNiiBdmUM2qLkBv+VLSJKoWAO+aKmyxxwjjmWhE0FrfA1NQ1a3g+NGMhRbAfQdaYswRAKsul70ISg==", + "dependencies": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-retry": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.272.0.tgz", + "integrity": "sha512-pCGvHM7C76VbO/dFerH+Vwf7tGv7j+e+eGrvhQ35mRghCtfIou/WMfTZlD1TNee93crrAQQVZKjtW3dMB3WCzg==", + "dependencies": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/service-error-classification": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-middleware": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "tslib": "^2.3.1", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-sdk-sts": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.272.0.tgz", + "integrity": "sha512-VvYPg7LrDIjUOWueSzo2wBzcNG7dw+cmzV6zAKaLxf0RC5jeAP4hE0OzDiiZfDrjNghEzgq/V+0NO+LewqYL9Q==", + "dependencies": { + "@aws-sdk/middleware-signing": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-serde": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.272.0.tgz", + "integrity": "sha512-kW1uOxgPSwtXPB5rm3QLdWomu42lkYpQL94tM1BjyFOWmBLO2lQhk5a7Dw6HkTozT9a+vxtscLChRa6KZe61Hw==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-signing": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.272.0.tgz", + "integrity": "sha512-4LChFK4VAR91X+dupqM8fQqYhFGE0G4Bf9rQlVTgGSbi2KUOmpqXzH0/WKE228nKuEhmH8+Qd2VPSAE2JcyAUA==", + "dependencies": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-middleware": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-stack": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.272.0.tgz", + "integrity": "sha512-jhwhknnPBGhfXAGV5GXUWfEhDFoP/DN8MPCO2yC5OAxyp6oVJ8lTPLkZYMTW5VL0c0eG44dXpF4Ib01V+PlDrQ==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.272.0.tgz", + "integrity": "sha512-Qy7/0fsDJxY5l0bEk7WKDfqb4Os/sCAgFR2zEvrhDtbkhYPf72ysvg/nRUTncmCbo8tOok4SJii2myk8KMfjjw==", + "dependencies": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/node-config-provider": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.272.0.tgz", + "integrity": "sha512-YYCIBh9g1EQo7hm2l22HX5Yr9RoPQ2RCvhzKvF1n1e8t1QH4iObQrYUtqHG4khcm64Cft8C5MwZmgzHbya5Z6Q==", + "dependencies": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/node-http-handler": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.272.0.tgz", + "integrity": "sha512-VrW9PjhhngeyYp4yGYPe5S0vgZH6NwU3Po9xAgayUeE37Inr7LS1YteFMHdpgsUUeNXnh7d06CXqHo1XjtqOKA==", + "dependencies": { + "@aws-sdk/abort-controller": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/querystring-builder": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/property-provider": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.272.0.tgz", + "integrity": "sha512-V1pZTaH5eqpAt8O8CzbItHhOtzIfFuWymvwZFkAtwKuaHpnl7jjrTouV482zoq8AD/fF+VVSshwBKYA7bhidIw==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/querystring-builder": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.272.0.tgz", + "integrity": "sha512-ndo++7GkdCj5tBXE6rGcITpSpZS4PfyV38wntGYAlj9liL1omk3bLZRY6uzqqkJpVHqbg2fD7O2qHNItzZgqhw==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/querystring-parser": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.272.0.tgz", + "integrity": "sha512-5oS4/9n6N1LZW9tI3qq/0GnCuWoOXRgcHVB+AJLRBvDbEe+GI+C/xK1tKLsfpDNgsQJHc4IPQoIt4megyZ/1+A==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/service-error-classification": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.272.0.tgz", + "integrity": "sha512-REoltM1LK9byyIufLqx9znhSolPcHQgVHIA2S0zu5sdt5qER4OubkLAXuo4MBbisUTmh8VOOvIyUb5ijZCXq1w==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/shared-ini-file-loader": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.272.0.tgz", + "integrity": "sha512-lzFPohp5sy2XvwFjZIzLVCRpC0i5cwBiaXmFzXYQZJm6FSCszHO4ax+m9yrtlyVFF/2YPWl+/bzNthy4aJtseA==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/signature-v4": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.272.0.tgz", + "integrity": "sha512-pWxnHG1NqJWMwlhJ6NHNiUikOL00DHROmxah6krJPMPq4I3am2KY2Rs/8ouWhnEXKaHAv4EQhSALJ+7Mq5S4/A==", "dependencies": { - "@aws-crypto/ie11-detection": "^2.0.0", - "@aws-crypto/sha256-js": "^2.0.0", - "@aws-crypto/supports-web-crypto": "^2.0.0", - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@aws-sdk/is-array-buffer": "3.201.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-hex-encoding": "3.201.0", + "@aws-sdk/util-middleware": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/smithy-client": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.272.0.tgz", + "integrity": "sha512-pvdleJ3kaRvyRw2pIZnqL85ZlWBOZrPKmR9I69GCvlyrfdjRBhbSjIEZ+sdhZudw0vdHxq25AGoLUXhofVLf5Q==", + "dependencies": { + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } }, - "node_modules/@aws-crypto/sha256-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-2.0.0.tgz", - "integrity": "sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==", + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/token-providers": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.272.0.tgz", + "integrity": "sha512-0GISJ4IKN2rXvbSddB775VjBGSKhYIGQnAdMqbvxi9LB6pSvVxcH9aIL28G0spiuL+dy3yGQZ8RlJPAyP9JW9A==", "dependencies": { - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", - "tslib": "^1.11.1" + "@aws-sdk/client-sso-oidc": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.2.tgz", - "integrity": "sha512-6mbSsLHwZ99CTOOswvCRP3C+VCWnzBf+1SnbWxzzJ9lR0mA0JnY2JEAhp8rqmTE0GPFy88rrM27ffgp62oErMQ==", + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/url-parser": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.272.0.tgz", + "integrity": "sha512-vX/Tx02PlnQ/Kgtf5TnrNDHPNbY+amLZjW0Z1d9vzAvSZhQ4i9Y18yxoRDIaDTCNVRDjdhV8iuctW+05PB5JtQ==", "dependencies": { - "tslib": "^1.11.1" + "@aws-sdk/querystring-parser": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" } }, - "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-defaults-mode-browser": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.272.0.tgz", + "integrity": "sha512-W8ZVJSZRuUBg8l0JEZzUc+9fKlthVp/cdE+pFeF8ArhZelOLCiaeCrMaZAeJusaFzIpa6cmOYQAjtSMVyrwRtg==", + "dependencies": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "bowser": "^2.11.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 10.0.0" + } }, - "node_modules/@aws-crypto/util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.2.tgz", - "integrity": "sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA==", + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-defaults-mode-node": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.272.0.tgz", + "integrity": "sha512-U0NTcbMw6KFk7uz/avBmfxQSTREEiX6JDMH68oN/3ux4AICd2I4jHyxnloSWGuiER1FxZf1dEJ8ZTwy8Ibl21Q==", "dependencies": { - "@aws-sdk/types": "^3.110.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/credential-provider-imds": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 10.0.0" } }, - "node_modules/@aws-crypto/util/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-endpoints": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.272.0.tgz", + "integrity": "sha512-c4MPUaJt2G6gGpoiwIOqDfUa98c1J63RpYvf/spQEKOtC/tF5Gfqlxuq8FnAl5lHnrqj1B9ZXLLxFhHtDR0IiQ==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } }, - "node_modules/@aws-sdk/abort-controller": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.226.0.tgz", - "integrity": "sha512-cJVzr1xxPBd08voknXvR0RLgtZKGKt6WyDpH/BaPCu3rfSqWCDZKzwqe940eqosjmKrxC6pUZNKASIqHOQ8xxQ==", + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-middleware": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.272.0.tgz", + "integrity": "sha512-Abw8m30arbwxqmeMMha5J11ESpHUNmCeSqSzE8/C4B8jZQtHY4kq7f+upzcNIQ11lsd+uzBEzNG3+dDRi0XOJQ==", "dependencies": { - "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/chunked-blob-reader": { - "version": "3.188.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.188.0.tgz", - "integrity": "sha512-zkPRFZZPL3eH+kH86LDYYXImiClA1/sW60zYOjse9Pgka+eDJlvBN6hcYxwDEKjcwATYiSRR1aVQHcfCinlGXg==", + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-retry": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.272.0.tgz", + "integrity": "sha512-Ngha5414LR4gRHURVKC9ZYXsEJhMkm+SJ+44wlzOhavglfdcKKPUsibz5cKY1jpUV7oKECwaxHWpBB8r6h+hOg==", "dependencies": { + "@aws-sdk/service-error-classification": "3.272.0", "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@aws-sdk/chunked-blob-reader-native": { - "version": "3.208.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader-native/-/chunked-blob-reader-native-3.208.0.tgz", - "integrity": "sha512-JeOZ95PW+fJ6bbuqPySYqLqHk1n4+4ueEEraJsiUrPBV0S1ZtyvOGHcnGztKUjr2PYNaiexmpWuvUve9K12HRA==", + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.272.0.tgz", + "integrity": "sha512-Lp5QX5bH6uuwBlIdr7w7OAcAI50ttyskb++yUr9i+SPvj6RI2dsfIBaK4mDg1qUdM5LeUdvIyqwj3XHjFKAAvA==", "dependencies": { - "@aws-sdk/util-base64": "3.208.0", + "@aws-sdk/types": "3.272.0", + "bowser": "^2.11.0", "tslib": "^2.3.1" } }, - "node_modules/@aws-sdk/client-lambda": { - "version": "3.245.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.245.0.tgz", - "integrity": "sha512-vhC9MPWclA3/qMUzOMu6Xc3sQ1iJJFQ+h7kbnYMbQFDQWIN24O/HqmdLJ3iGcIYLd8vw3jpz6dQB/OCKSPIPVg==", + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.272.0.tgz", + "integrity": "sha512-ljK+R3l+Q1LIHrcR+Knhk0rmcSkfFadZ8V+crEGpABf/QUQRg7NkZMsoe814tfBO5F7tMxo8wwwSdaVNNHtoRA==", "dependencies": { - "@aws-crypto/sha256-browser": "2.0.0", - "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/client-sts": "3.245.0", - "@aws-sdk/config-resolver": "3.234.0", - "@aws-sdk/credential-provider-node": "3.245.0", - "@aws-sdk/fetch-http-handler": "3.226.0", - "@aws-sdk/hash-node": "3.226.0", - "@aws-sdk/invalid-dependency": "3.226.0", - "@aws-sdk/middleware-content-length": "3.226.0", - "@aws-sdk/middleware-endpoint": "3.226.0", - "@aws-sdk/middleware-host-header": "3.226.0", - "@aws-sdk/middleware-logger": "3.226.0", - "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.235.0", - "@aws-sdk/middleware-serde": "3.226.0", - "@aws-sdk/middleware-signing": "3.226.0", - "@aws-sdk/middleware-stack": "3.226.0", - "@aws-sdk/middleware-user-agent": "3.226.0", - "@aws-sdk/node-config-provider": "3.226.0", - "@aws-sdk/node-http-handler": "3.226.0", - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/smithy-client": "3.234.0", - "@aws-sdk/types": "3.226.0", - "@aws-sdk/url-parser": "3.226.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.234.0", - "@aws-sdk/util-defaults-mode-node": "3.234.0", - "@aws-sdk/util-endpoints": "3.245.0", - "@aws-sdk/util-retry": "3.229.0", - "@aws-sdk/util-user-agent-browser": "3.226.0", - "@aws-sdk/util-user-agent-node": "3.226.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.208.0", - "@aws-sdk/util-waiter": "3.226.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" }, "engines": { "node": ">=14.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } } }, - "node_modules/@aws-sdk/client-s3": { - "version": "3.245.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.245.0.tgz", - "integrity": "sha512-wdCrEiqIfwtWebrK7A1giRggwO64S6I2iPXTwRmat4AR6sFlMO02jVFaIDyA8TTiVnBMz7ekT1QFmIjFAKc4uQ==", + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-waiter": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-waiter/-/util-waiter-3.272.0.tgz", + "integrity": "sha512-N25/XsJ2wkPh1EgkFyb/GRgfHDityScfD49Hk1AwJWpfetzgkcEtWdeW4IuPymXlSKhrm5L+SBw49USxo9kBag==", "dependencies": { - "@aws-crypto/sha1-browser": "2.0.0", - "@aws-crypto/sha256-browser": "2.0.0", - "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/client-sts": "3.245.0", - "@aws-sdk/config-resolver": "3.234.0", - "@aws-sdk/credential-provider-node": "3.245.0", - "@aws-sdk/eventstream-serde-browser": "3.226.0", - "@aws-sdk/eventstream-serde-config-resolver": "3.226.0", - "@aws-sdk/eventstream-serde-node": "3.226.0", - "@aws-sdk/fetch-http-handler": "3.226.0", - "@aws-sdk/hash-blob-browser": "3.226.0", - "@aws-sdk/hash-node": "3.226.0", - "@aws-sdk/hash-stream-node": "3.226.0", - "@aws-sdk/invalid-dependency": "3.226.0", - "@aws-sdk/md5-js": "3.226.0", - "@aws-sdk/middleware-bucket-endpoint": "3.226.0", - "@aws-sdk/middleware-content-length": "3.226.0", - "@aws-sdk/middleware-endpoint": "3.226.0", - "@aws-sdk/middleware-expect-continue": "3.226.0", - "@aws-sdk/middleware-flexible-checksums": "3.226.0", - "@aws-sdk/middleware-host-header": "3.226.0", - "@aws-sdk/middleware-location-constraint": "3.226.0", - "@aws-sdk/middleware-logger": "3.226.0", - "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.235.0", - "@aws-sdk/middleware-sdk-s3": "3.231.0", - "@aws-sdk/middleware-serde": "3.226.0", - "@aws-sdk/middleware-signing": "3.226.0", - "@aws-sdk/middleware-ssec": "3.226.0", - "@aws-sdk/middleware-stack": "3.226.0", - "@aws-sdk/middleware-user-agent": "3.226.0", - "@aws-sdk/node-config-provider": "3.226.0", - "@aws-sdk/node-http-handler": "3.226.0", - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/signature-v4-multi-region": "3.226.0", - "@aws-sdk/smithy-client": "3.234.0", - "@aws-sdk/types": "3.226.0", - "@aws-sdk/url-parser": "3.226.0", - "@aws-sdk/util-base64": "3.208.0", - "@aws-sdk/util-body-length-browser": "3.188.0", - "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.234.0", - "@aws-sdk/util-defaults-mode-node": "3.234.0", - "@aws-sdk/util-endpoints": "3.245.0", - "@aws-sdk/util-retry": "3.229.0", - "@aws-sdk/util-stream-browser": "3.226.0", - "@aws-sdk/util-stream-node": "3.226.0", - "@aws-sdk/util-user-agent-browser": "3.226.0", - "@aws-sdk/util-user-agent-node": "3.226.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.208.0", - "@aws-sdk/util-waiter": "3.226.0", - "@aws-sdk/xml-builder": "3.201.0", - "fast-xml-parser": "4.0.11", + "@aws-sdk/abort-controller": "3.272.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" }, "engines": { "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/client-s3/node_modules/fast-xml-parser": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.1.2.tgz", + "integrity": "sha512-CDYeykkle1LiA/uqQyNwYpFbyF6Axec6YapmpUP+/RHWIoR1zKjocdvNaTsxCxZzQ6v9MLXaSYm9Qq0thv0DHg==", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + }, "node_modules/@aws-sdk/client-sso": { "version": "3.245.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.245.0.tgz", @@ -638,23 +1504,45 @@ } }, "node_modules/@aws-sdk/eventstream-codec": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.226.0.tgz", - "integrity": "sha512-6uPtR8vSwz3fqoZk9hrb6qBYdp3PJ22+JxV5Wimdesvow4kJXSgDQXIxEkxbv6SxB9tNRB4uJHD84RetHEi15Q==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.272.0.tgz", + "integrity": "sha512-HYMzglDnqUhvx3u9MdzZ/OjLuavaaH9zF9XMXRuv7bdsN9AAi3/0he0FEx84ZXNXSAZCebLwXJYf0ZrN6g37QA==", "dependencies": { - "@aws-crypto/crc32": "2.0.0", - "@aws-sdk/types": "3.226.0", + "@aws-crypto/crc32": "3.0.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-hex-encoding": "3.201.0", "tslib": "^2.3.1" } }, + "node_modules/@aws-sdk/eventstream-codec/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/eventstream-serde-browser": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.226.0.tgz", - "integrity": "sha512-otYC5aZE9eJUqAlKpy8w0rPDQ1eKGvZPtgxWXmFYSO2lDVGfI1nBBNmdZ4MdHqNuQ7ucsKMQYF8BFJ65K2tYPA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.272.0.tgz", + "integrity": "sha512-mE1+mevS+KVKpnTLi5FytsBwAK1kWZ92ERtAiElp58SKE1OpfSg8lEY8VI6JKGlueN540Qq3LeIgA2/HJOcK/w==", + "dependencies": { + "@aws-sdk/eventstream-serde-universal": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-serde-browser/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", "dependencies": { - "@aws-sdk/eventstream-serde-universal": "3.226.0", - "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, "engines": { @@ -662,11 +1550,22 @@ } }, "node_modules/@aws-sdk/eventstream-serde-config-resolver": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.226.0.tgz", - "integrity": "sha512-A56Gypg+lyEfA5cna+EUH9XTrj0SvRG1gwNW7lrUzviN36SeA/LFTUIOEjxVML3Lowy+EPAcrSZ67h6aepoAig==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.272.0.tgz", + "integrity": "sha512-e47BhGBvx+me53cvYx+47ml5KNDj7XoTth80krHlyLrimFELE1ij4tHSKR/XzilKKH1uIWmJQdlAi29129ZX5w==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-serde-config-resolver/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", "dependencies": { - "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, "engines": { @@ -674,12 +1573,23 @@ } }, "node_modules/@aws-sdk/eventstream-serde-node": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.226.0.tgz", - "integrity": "sha512-KWLnKkKDzI9RNkiK6OiSYpG/XjZfue6Bsp/vRG+H5z3fbXdHv4X2+iW+Efu2Kvn7jsUyUv82TCl57DyJ/HKYhQ==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.272.0.tgz", + "integrity": "sha512-uto8y4FoZugWnczM1TKwv6oV2Po2Jgrp+W1Ws3baRQ4Lan+QpFx3Tps1N5rNzQ+7Uz0xT1BhbSNPAkKs22/jtg==", + "dependencies": { + "@aws-sdk/eventstream-serde-universal": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-serde-node/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", "dependencies": { - "@aws-sdk/eventstream-serde-universal": "3.226.0", - "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, "engines": { @@ -687,12 +1597,23 @@ } }, "node_modules/@aws-sdk/eventstream-serde-universal": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.226.0.tgz", - "integrity": "sha512-Q8viYM1Sv90/yIUqyWNeG1GEvyVlAI3GIrInQcCMC+xT59jS+IKGy2y7ojCvSWXnhf5/HMXKcmG092QsqeKy0Q==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.272.0.tgz", + "integrity": "sha512-E9jlt8tzDcEMoNlgv3+01jGPJPHmbmw2NsajZhB4axVMpEy247JV6qvCZe+5R+EGy96t0pfsO2naViEB4Va47g==", + "dependencies": { + "@aws-sdk/eventstream-codec": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-serde-universal/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", "dependencies": { - "@aws-sdk/eventstream-codec": "3.226.0", - "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, "engines": { @@ -712,14 +1633,25 @@ } }, "node_modules/@aws-sdk/hash-blob-browser": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.226.0.tgz", - "integrity": "sha512-5DCvWE6L4xGoViEHyjcPFuUe1G2EtNx8TqswWaoaKgyasP/yuRm4H99Ra7rqIrjCcSTAGD9NVsUQvVVw1bGt9w==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.272.0.tgz", + "integrity": "sha512-IRCIMG42fXcdD92C8Sb0CQI8D/msxDwHGAIqP94iGhVEnKX2egyx5J8lmPY4gEky5UzyMMaH7cayBv89ZMEBmQ==", "dependencies": { "@aws-sdk/chunked-blob-reader": "3.188.0", "@aws-sdk/chunked-blob-reader-native": "3.208.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/hash-blob-browser/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "dependencies": { "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/hash-node": { @@ -736,11 +1668,23 @@ } }, "node_modules/@aws-sdk/hash-stream-node": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-stream-node/-/hash-stream-node-3.226.0.tgz", - "integrity": "sha512-cgNTGlF8SdHaQXtjEmuLXz2U8SLM2JDKtIVPku/lHTMsUsEn+fuv2C+h1f/hvd4aNw5t1zggym7sO1/h/rv56Q==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-stream-node/-/hash-stream-node-3.272.0.tgz", + "integrity": "sha512-mWwQWdfVYoR6PXRLkHP6pC1cghZMg0ULuOAm70EtTO2YXiyLlMIDb+VD4RRbjh3hNkzh+y/W47wSUJthGBM1kg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/hash-stream-node/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", "dependencies": { - "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, "engines": { @@ -788,23 +1732,33 @@ } }, "node_modules/@aws-sdk/md5-js": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/md5-js/-/md5-js-3.226.0.tgz", - "integrity": "sha512-ENigJRNudqyh6xsch166SZ4gggHd3XzZJ8gkCU4CWPne04HcR3BkWSO774IuWooCHt8zkaEHKecPurRz6qR+Vw==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/md5-js/-/md5-js-3.272.0.tgz", + "integrity": "sha512-/GK32mgAarhn/F0xCeBKbYfLRof3tOCNrg8mAGNz9Di8E1/qMOnX/OXUGag0lsvNZ6DTjdjln29t4e8iKmOVqA==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/md5-js/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", "dependencies": { - "@aws-sdk/types": "3.226.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.208.0", "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.226.0.tgz", - "integrity": "sha512-A1Vq5W2X7jgTfjqcKPmjoHohF0poP+9fxwL97fQMvzcwmjhtoCV3bLEpo6CGYx0pKPiSlRJXZkRwRPj2hDHDmA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.272.0.tgz", + "integrity": "sha512-523T6JXfjsY9uSgMusa6myCccRv2TWyUSjzMx/0aUHfHRacJSunfPtSNX1kfYxXWn/ByWhaieHFBPehVI6wg1A==", "dependencies": { - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-arn-parser": "3.208.0", "@aws-sdk/util-config-provider": "3.208.0", "tslib": "^2.3.1" @@ -813,6 +1767,29 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-bucket-endpoint/node_modules/@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-content-length": { "version": "3.226.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.226.0.tgz", @@ -845,12 +1822,35 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.226.0.tgz", - "integrity": "sha512-YxvQKTV/eA9P8AgW0hXOgj5Qa+TSnNFfyOkfeP089aP3f6p92b1cESf33TEOKsddive2mHT5LRCN6MuPcgWWrA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.272.0.tgz", + "integrity": "sha512-TNx61LCZUKp/yZqcb38qb4tU3lbhKaI9zn2FQ+fpKzUSTI3H6E5aw42wHaq2LEacYlyK3b5Wg1R0sKR+vsUutw==", + "dependencies": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue/node_modules/@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", "dependencies": { - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, "engines": { @@ -858,15 +1858,39 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.226.0.tgz", - "integrity": "sha512-8A9Ot9A7794UP5tMGl2MnfTW/UM/jYy1wRWF9YkR/hPIcPb7OmE0hmlwIQGzb/7grxpYw66ETKf0WeH/41YfeQ==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.272.0.tgz", + "integrity": "sha512-dc/tMiYM4wTZpjXf2PSQCFD4SQI5wyVwY5SoBgcB3W2XLq1SzXahiDnnUSn2EzDTKPIrmQmYyDFRpFEPo0sP/g==", "dependencies": { - "@aws-crypto/crc32": "2.0.0", - "@aws-crypto/crc32c": "2.0.0", + "@aws-crypto/crc32": "3.0.0", + "@aws-crypto/crc32c": "3.0.0", "@aws-sdk/is-array-buffer": "3.201.0", - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums/node_modules/@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "dependencies": { "tslib": "^2.3.1" }, "engines": { @@ -887,11 +1911,22 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.226.0.tgz", - "integrity": "sha512-qHiYaBYPc2R37KxG2uqsUUwh4usrQMHfGkrpTUnx5d4rGzM3mC+muPsTpSHnAL63K2/yJOHQJFjss3GGwV4SSA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.272.0.tgz", + "integrity": "sha512-tROQ1DM9djxfXmXPTT0XietrUt6y6QEHShPI9rQMstjXYiaHBVXRveuRLcLAKwl4nXIrgmnIU7ygyj2ZyD8gcA==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-location-constraint/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", "dependencies": { - "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, "engines": { @@ -941,12 +1976,12 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.231.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.231.0.tgz", - "integrity": "sha512-UGaSvevd2TanfKgStF46dDSHkh4bxOr1gdUkyHm9i+1pF5lx4KdbnBZv/5SKnn7XifhHRXrs1M3lTzemXREhTA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.272.0.tgz", + "integrity": "sha512-uMvoLePkyP54b9BckMELlDnFh0SGPAfTkBwiH/FC79K7noGLA5A4KgqKObtB9LPYHkPfm1WLqIgdaE6gS1BlFQ==", "dependencies": { - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-arn-parser": "3.208.0", "tslib": "^2.3.1" }, @@ -954,6 +1989,29 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/middleware-sdk-s3/node_modules/@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/middleware-sdk-sts": { "version": "3.226.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.226.0.tgz", @@ -999,11 +2057,22 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.226.0.tgz", - "integrity": "sha512-DR97oWoLHiMdaUP/wu99HtzG7/ijvCrjZGDH37WBO1rxFtEti6L7T09wgHzwxMN8gtL8FJA7dU8IrffGSC9VmA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.272.0.tgz", + "integrity": "sha512-WDPcNPkscTmJUzdAvfx8p+YuUn2YR9ocmZA7yYUJ5kA94MyGH6Rbjp8tleWwQvah/HweeCQrYUzJk9wsH64LPA==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", "dependencies": { - "@aws-sdk/types": "3.226.0", "tslib": "^2.3.1" }, "engines": { @@ -1149,13 +2218,13 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.226.0.tgz", - "integrity": "sha512-QHxNuf9ynK208v7Y3imdsa3Cz8ynYV7ZOf3sBJdItuEtHN6uy/KxaOrtvpF8I5Hyn48Hc8z5miTSMujFKT7GEw==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.272.0.tgz", + "integrity": "sha512-nir/ICA3saE303tS+DuJ803Uocn/d3hOpOl5DqI9RDjaZxbTXwv9uHP+by8sdyyfwCE8TFaYWoiSW5rLI+Qt0g==", "dependencies": { - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/signature-v4": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-arn-parser": "3.208.0", "tslib": "^2.3.1" }, @@ -1171,6 +2240,57 @@ } } }, + "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/signature-v4": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.272.0.tgz", + "integrity": "sha512-pWxnHG1NqJWMwlhJ6NHNiUikOL00DHROmxah6krJPMPq4I3am2KY2Rs/8ouWhnEXKaHAv4EQhSALJ+7Mq5S4/A==", + "dependencies": { + "@aws-sdk/is-array-buffer": "3.201.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-hex-encoding": "3.201.0", + "@aws-sdk/util-middleware": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/util-middleware": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.272.0.tgz", + "integrity": "sha512-Abw8m30arbwxqmeMMha5J11ESpHUNmCeSqSzE8/C4B8jZQtHY4kq7f+upzcNIQ11lsd+uzBEzNG3+dDRi0XOJQ==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/smithy-client": { "version": "3.234.0", "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.234.0.tgz", @@ -1373,25 +2493,73 @@ } }, "node_modules/@aws-sdk/util-stream-browser": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-browser/-/util-stream-browser-3.226.0.tgz", - "integrity": "sha512-ZvjlA1ySaLd0DqUWTKmL7LsxfPhroAONpzsinaHmw9aZVL40s2cADU9eWgBdHTuAOeFklL7NP0cc6UiTFHKe8g==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-browser/-/util-stream-browser-3.272.0.tgz", + "integrity": "sha512-vD514YffKxBjV/erjUNgkXcb/mzXAz3uk/KUFMXsodo3cA4Z8WxL4P0p1O09FVuJlNa0gZ8mhFPNzNOekh31GA==", "dependencies": { - "@aws-sdk/fetch-http-handler": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-base64": "3.208.0", "@aws-sdk/util-hex-encoding": "3.201.0", - "@aws-sdk/util-utf8-browser": "3.188.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-stream-browser/node_modules/@aws-sdk/fetch-http-handler": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.272.0.tgz", + "integrity": "sha512-1Qhm9e0RbS1Xf4CZqUbQyUMkDLd7GrsRXWIvm9b86/vgeV8/WnjO3CMue9D51nYgcyQORhYXv6uVjAYCWbUExA==", + "dependencies": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/querystring-builder": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-stream-browser/node_modules/@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-stream-browser/node_modules/@aws-sdk/querystring-builder": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.272.0.tgz", + "integrity": "sha512-ndo++7GkdCj5tBXE6rGcITpSpZS4PfyV38wntGYAlj9liL1omk3bLZRY6uzqqkJpVHqbg2fD7O2qHNItzZgqhw==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-stream-browser/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "dependencies": { "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@aws-sdk/util-stream-node": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-node/-/util-stream-node-3.226.0.tgz", - "integrity": "sha512-HADXiIgDGoXcCLSKuPnjCLENf0iC0lzqqnymZu9H2FoACZhJB7DvJ9LnP51Pvw9lfCu+yvLzbMqSPdbXtMbRWg==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-node/-/util-stream-node-3.272.0.tgz", + "integrity": "sha512-s7dGeM1ImzihqBKgrpaeZokLnPUk3H4Et5oiM+t+TpRxotXTecJPyuD0p76HRgO8KSXfVT5Nxw/FoHXqj1fiMg==", "dependencies": { - "@aws-sdk/node-http-handler": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-buffer-from": "3.208.0", "tslib": "^2.3.1" }, @@ -1399,6 +2567,69 @@ "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/util-stream-node/node_modules/@aws-sdk/abort-controller": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.272.0.tgz", + "integrity": "sha512-s2TV3phapcTwZNr4qLxbfuQuE9ZMP4RoJdkvRRCkKdm6jslsWLJf2Zlcxti/23hOlINUMYv2iXE2pftIgWGdpg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-stream-node/node_modules/@aws-sdk/node-http-handler": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.272.0.tgz", + "integrity": "sha512-VrW9PjhhngeyYp4yGYPe5S0vgZH6NwU3Po9xAgayUeE37Inr7LS1YteFMHdpgsUUeNXnh7d06CXqHo1XjtqOKA==", + "dependencies": { + "@aws-sdk/abort-controller": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/querystring-builder": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-stream-node/node_modules/@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-stream-node/node_modules/@aws-sdk/querystring-builder": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.272.0.tgz", + "integrity": "sha512-ndo++7GkdCj5tBXE6rGcITpSpZS4PfyV38wntGYAlj9liL1omk3bLZRY6uzqqkJpVHqbg2fD7O2qHNItzZgqhw==", + "dependencies": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-stream-node/node_modules/@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/util-uri-escape": { "version": "3.201.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.201.0.tgz", @@ -1441,6 +2672,18 @@ } } }, + "node_modules/@aws-sdk/util-utf8": { + "version": "3.254.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.254.0.tgz", + "integrity": "sha512-14Kso/eIt5/qfIBmhEL9L1IfyUqswjSTqO2mY7KOzUZ9SZbwn3rpxmtkhmATkRjD7XIlLKaxBkI7tU9Zjzj8Kw==", + "dependencies": { + "@aws-sdk/util-buffer-from": "3.208.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-sdk/util-utf8-browser": { "version": "3.188.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.188.0.tgz", @@ -3530,6 +4773,22 @@ } } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -3754,6 +5013,12 @@ "node": ">=0.10.0" } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, "node_modules/ast-module-types": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-3.0.0.tgz", @@ -4736,6 +6001,12 @@ "to-function": "2.0.6" } }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, "node_modules/component-props": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/component-props/-/component-props-1.1.1.tgz", @@ -5249,6 +6520,12 @@ "resolved": "https://registry.npmjs.org/convert-string/-/convert-string-0.1.0.tgz", "integrity": "sha512-1KX9ESmtl8xpT2LN2tFnKSbV4NiarbVi8DVb39ZriijvtTklyrT+4dT1wsGMHKD3CJUjXgvJzstm9qL9ICojGA==" }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true + }, "node_modules/cookies": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz", @@ -5887,6 +7164,16 @@ "node": ">=4.2.0" } }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -7134,6 +8421,12 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, "node_modules/fast-xml-parser": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz", @@ -7394,6 +8687,21 @@ "node": ">= 6" } }, + "node_modules/formidable": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", + "dev": true, + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0", + "qs": "^6.11.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -8080,6 +9388,15 @@ "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" }, + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -11320,6 +12637,18 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -12942,14 +14271,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "node_modules/readline-sync": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", - "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -13215,9 +14536,9 @@ } }, "node_modules/rudder-transformer-cdk": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/rudder-transformer-cdk/-/rudder-transformer-cdk-1.4.3.tgz", - "integrity": "sha512-nekX3JHhRiWrY/VLCwQZSLqQB9QrB0/lo4su3Nd4B95qDSMEp4x6K1DFU7fBR5ZQ8o8PVa+2qcckyop838nSdQ==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/rudder-transformer-cdk/-/rudder-transformer-cdk-1.4.5.tgz", + "integrity": "sha512-681KUMOavx2++1hxs9ABXNI+ndNJRPEBYaHkQmNbo+kgvro3XSspiVNBfMGnqwKofLi3ysfpREQ8NFZHm3gwTA==", "dependencies": { "get-value": "^3.0.1", "handlebars": "^4.7.7", @@ -15008,6 +16329,40 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/superagent": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz", + "integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==", + "dev": true, + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.4", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.1.2", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=6.4.0 <13 || >=14" + } + }, + "node_modules/supertest": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz", + "integrity": "sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==", + "dev": true, + "dependencies": { + "methods": "^1.1.2", + "superagent": "^8.0.5" + }, + "engines": { + "node": ">=6.4.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -15504,9 +16859,9 @@ } }, "node_modules/ua-parser-js": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.8.1.tgz", - "integrity": "sha512-top37bpoaHp+wJBAqjm5KNz7qNfSZ/tmHEisuMMK5uzjdIo/L6uWovDFuYboO+q8EMz1f67exTnd+OPYESuu8Q==", + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz", + "integrity": "sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==", "funding": [ { "type": "opencollective", @@ -16190,15 +17545,25 @@ } }, "@aws-crypto/crc32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-2.0.0.tgz", - "integrity": "sha512-TvE1r2CUueyXOuHdEigYjIZVesInd9KN+K/TFFNfkkxRThiNxO6i4ZqqAVMoEjAamZZ1AA8WXJkjCz7YShHPQA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", "requires": { - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", "tslib": "^1.11.1" }, "dependencies": { + "@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -16207,15 +17572,25 @@ } }, "@aws-crypto/crc32c": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-2.0.0.tgz", - "integrity": "sha512-vF0eMdMHx3O3MoOXUfBZry8Y4ZDtcuskjjKgJz8YfIDjLStxTZrYXk+kZqtl6A0uCmmiN/Eb/JbC/CndTV1MHg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz", + "integrity": "sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==", "requires": { - "@aws-crypto/util": "^2.0.0", - "@aws-sdk/types": "^3.1.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", "tslib": "^1.11.1" }, "dependencies": { + "@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -16239,18 +17614,45 @@ } }, "@aws-crypto/sha1-browser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-2.0.0.tgz", - "integrity": "sha512-3fIVRjPFY8EG5HWXR+ZJZMdWNRpwbxGzJ9IH9q93FpbgCH8u8GHRi46mZXp3cYD7gealmyqpm3ThZwLKJjWJhA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz", + "integrity": "sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==", "requires": { - "@aws-crypto/ie11-detection": "^2.0.0", - "@aws-crypto/supports-web-crypto": "^2.0.0", - "@aws-sdk/types": "^3.1.0", + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" }, "dependencies": { + "@aws-crypto/ie11-detection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "requires": { + "tslib": "^1.11.1" + } + }, + "@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", + "requires": { + "tslib": "^1.11.1" + } + }, + "@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -16400,65 +17802,752 @@ } }, "@aws-sdk/client-s3": { - "version": "3.245.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.245.0.tgz", - "integrity": "sha512-wdCrEiqIfwtWebrK7A1giRggwO64S6I2iPXTwRmat4AR6sFlMO02jVFaIDyA8TTiVnBMz7ekT1QFmIjFAKc4uQ==", - "requires": { - "@aws-crypto/sha1-browser": "2.0.0", - "@aws-crypto/sha256-browser": "2.0.0", - "@aws-crypto/sha256-js": "2.0.0", - "@aws-sdk/client-sts": "3.245.0", - "@aws-sdk/config-resolver": "3.234.0", - "@aws-sdk/credential-provider-node": "3.245.0", - "@aws-sdk/eventstream-serde-browser": "3.226.0", - "@aws-sdk/eventstream-serde-config-resolver": "3.226.0", - "@aws-sdk/eventstream-serde-node": "3.226.0", - "@aws-sdk/fetch-http-handler": "3.226.0", - "@aws-sdk/hash-blob-browser": "3.226.0", - "@aws-sdk/hash-node": "3.226.0", - "@aws-sdk/hash-stream-node": "3.226.0", - "@aws-sdk/invalid-dependency": "3.226.0", - "@aws-sdk/md5-js": "3.226.0", - "@aws-sdk/middleware-bucket-endpoint": "3.226.0", - "@aws-sdk/middleware-content-length": "3.226.0", - "@aws-sdk/middleware-endpoint": "3.226.0", - "@aws-sdk/middleware-expect-continue": "3.226.0", - "@aws-sdk/middleware-flexible-checksums": "3.226.0", - "@aws-sdk/middleware-host-header": "3.226.0", - "@aws-sdk/middleware-location-constraint": "3.226.0", - "@aws-sdk/middleware-logger": "3.226.0", - "@aws-sdk/middleware-recursion-detection": "3.226.0", - "@aws-sdk/middleware-retry": "3.235.0", - "@aws-sdk/middleware-sdk-s3": "3.231.0", - "@aws-sdk/middleware-serde": "3.226.0", - "@aws-sdk/middleware-signing": "3.226.0", - "@aws-sdk/middleware-ssec": "3.226.0", - "@aws-sdk/middleware-stack": "3.226.0", - "@aws-sdk/middleware-user-agent": "3.226.0", - "@aws-sdk/node-config-provider": "3.226.0", - "@aws-sdk/node-http-handler": "3.226.0", - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/signature-v4-multi-region": "3.226.0", - "@aws-sdk/smithy-client": "3.234.0", - "@aws-sdk/types": "3.226.0", - "@aws-sdk/url-parser": "3.226.0", + "version": "3.276.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.276.0.tgz", + "integrity": "sha512-9cwrYeMTx9a9MUWSxBr2i87NACEw3Vc8ALnDYZSvhps8UivdgZ1v3zN8c0v/g/3RrJJNco2HCs9je+lOPRvq3w==", + "requires": { + "@aws-crypto/sha1-browser": "3.0.0", + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.276.0", + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/credential-provider-node": "3.272.0", + "@aws-sdk/eventstream-serde-browser": "3.272.0", + "@aws-sdk/eventstream-serde-config-resolver": "3.272.0", + "@aws-sdk/eventstream-serde-node": "3.272.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/hash-blob-browser": "3.272.0", + "@aws-sdk/hash-node": "3.272.0", + "@aws-sdk/hash-stream-node": "3.272.0", + "@aws-sdk/invalid-dependency": "3.272.0", + "@aws-sdk/md5-js": "3.272.0", + "@aws-sdk/middleware-bucket-endpoint": "3.272.0", + "@aws-sdk/middleware-content-length": "3.272.0", + "@aws-sdk/middleware-endpoint": "3.272.0", + "@aws-sdk/middleware-expect-continue": "3.272.0", + "@aws-sdk/middleware-flexible-checksums": "3.272.0", + "@aws-sdk/middleware-host-header": "3.272.0", + "@aws-sdk/middleware-location-constraint": "3.272.0", + "@aws-sdk/middleware-logger": "3.272.0", + "@aws-sdk/middleware-recursion-detection": "3.272.0", + "@aws-sdk/middleware-retry": "3.272.0", + "@aws-sdk/middleware-sdk-s3": "3.272.0", + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/middleware-signing": "3.272.0", + "@aws-sdk/middleware-ssec": "3.272.0", + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/middleware-user-agent": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4-multi-region": "3.272.0", + "@aws-sdk/smithy-client": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", "@aws-sdk/util-base64": "3.208.0", "@aws-sdk/util-body-length-browser": "3.188.0", "@aws-sdk/util-body-length-node": "3.208.0", - "@aws-sdk/util-defaults-mode-browser": "3.234.0", - "@aws-sdk/util-defaults-mode-node": "3.234.0", - "@aws-sdk/util-endpoints": "3.245.0", - "@aws-sdk/util-retry": "3.229.0", - "@aws-sdk/util-stream-browser": "3.226.0", - "@aws-sdk/util-stream-node": "3.226.0", - "@aws-sdk/util-user-agent-browser": "3.226.0", - "@aws-sdk/util-user-agent-node": "3.226.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.208.0", - "@aws-sdk/util-waiter": "3.226.0", + "@aws-sdk/util-defaults-mode-browser": "3.272.0", + "@aws-sdk/util-defaults-mode-node": "3.272.0", + "@aws-sdk/util-endpoints": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "@aws-sdk/util-stream-browser": "3.272.0", + "@aws-sdk/util-stream-node": "3.272.0", + "@aws-sdk/util-user-agent-browser": "3.272.0", + "@aws-sdk/util-user-agent-node": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "@aws-sdk/util-waiter": "3.272.0", "@aws-sdk/xml-builder": "3.201.0", - "fast-xml-parser": "4.0.11", + "fast-xml-parser": "4.1.2", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-crypto/ie11-detection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "requires": { + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/sha256-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", + "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", + "requires": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/sha256-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", + "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", + "requires": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", + "requires": { + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "requires": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-sdk/abort-controller": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.272.0.tgz", + "integrity": "sha512-s2TV3phapcTwZNr4qLxbfuQuE9ZMP4RoJdkvRRCkKdm6jslsWLJf2Zlcxti/23hOlINUMYv2iXE2pftIgWGdpg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/client-sso": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.272.0.tgz", + "integrity": "sha512-xn9a0IGONwQIARmngThoRhF1lLGjHAD67sUaShgIMaIMc6ipVYN6alWG1VuUpoUQ6iiwMEt0CHdfCyLyUV/fTA==", + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/hash-node": "3.272.0", + "@aws-sdk/invalid-dependency": "3.272.0", + "@aws-sdk/middleware-content-length": "3.272.0", + "@aws-sdk/middleware-endpoint": "3.272.0", + "@aws-sdk/middleware-host-header": "3.272.0", + "@aws-sdk/middleware-logger": "3.272.0", + "@aws-sdk/middleware-recursion-detection": "3.272.0", + "@aws-sdk/middleware-retry": "3.272.0", + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/middleware-user-agent": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/smithy-client": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "@aws-sdk/util-body-length-browser": "3.188.0", + "@aws-sdk/util-body-length-node": "3.208.0", + "@aws-sdk/util-defaults-mode-browser": "3.272.0", + "@aws-sdk/util-defaults-mode-node": "3.272.0", + "@aws-sdk/util-endpoints": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "@aws-sdk/util-user-agent-browser": "3.272.0", + "@aws-sdk/util-user-agent-node": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/client-sso-oidc": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.272.0.tgz", + "integrity": "sha512-ECcXu3xoa1yggnGKMTh29eWNHiF/wC6r5Uqbla22eOOosyh0+Z6lkJ3JUSLOUKCkBXA4Cs/tJL9UDFBrKbSlvA==", + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/hash-node": "3.272.0", + "@aws-sdk/invalid-dependency": "3.272.0", + "@aws-sdk/middleware-content-length": "3.272.0", + "@aws-sdk/middleware-endpoint": "3.272.0", + "@aws-sdk/middleware-host-header": "3.272.0", + "@aws-sdk/middleware-logger": "3.272.0", + "@aws-sdk/middleware-recursion-detection": "3.272.0", + "@aws-sdk/middleware-retry": "3.272.0", + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/middleware-user-agent": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/smithy-client": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "@aws-sdk/util-body-length-browser": "3.188.0", + "@aws-sdk/util-body-length-node": "3.208.0", + "@aws-sdk/util-defaults-mode-browser": "3.272.0", + "@aws-sdk/util-defaults-mode-node": "3.272.0", + "@aws-sdk/util-endpoints": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "@aws-sdk/util-user-agent-browser": "3.272.0", + "@aws-sdk/util-user-agent-node": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/client-sts": { + "version": "3.276.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.276.0.tgz", + "integrity": "sha512-J6FR4tYa/WdDdwWAKhw/mXQXKWUaZZQpMiyFEbFPQyURSWu3u17nv97NUdvVOgCth48H6Wb6a4ksssYy4K9tFQ==", + "requires": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/credential-provider-node": "3.272.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/hash-node": "3.272.0", + "@aws-sdk/invalid-dependency": "3.272.0", + "@aws-sdk/middleware-content-length": "3.272.0", + "@aws-sdk/middleware-endpoint": "3.272.0", + "@aws-sdk/middleware-host-header": "3.272.0", + "@aws-sdk/middleware-logger": "3.272.0", + "@aws-sdk/middleware-recursion-detection": "3.272.0", + "@aws-sdk/middleware-retry": "3.272.0", + "@aws-sdk/middleware-sdk-sts": "3.272.0", + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/middleware-signing": "3.272.0", + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/middleware-user-agent": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/smithy-client": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "@aws-sdk/util-body-length-browser": "3.188.0", + "@aws-sdk/util-body-length-node": "3.208.0", + "@aws-sdk/util-defaults-mode-browser": "3.272.0", + "@aws-sdk/util-defaults-mode-node": "3.272.0", + "@aws-sdk/util-endpoints": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "@aws-sdk/util-user-agent-browser": "3.272.0", + "@aws-sdk/util-user-agent-node": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", + "fast-xml-parser": "4.1.2", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/config-resolver": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.272.0.tgz", + "integrity": "sha512-Dr4CffRVNsOp3LRNdpvcH6XuSgXOSLblWliCy/5I86cNl567KVMxujVx6uPrdTXYs2h1rt3MNl6jQGnAiJeTbw==", + "requires": { + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-config-provider": "3.208.0", + "@aws-sdk/util-middleware": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-env": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.272.0.tgz", + "integrity": "sha512-QI65NbLnKLYHyTYhXaaUrq6eVsCCrMUb05WDA7+TJkWkjXesovpjc8vUKgFiLSxmgKmb2uOhHNcDyObKMrYQFw==", + "requires": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-imds": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.272.0.tgz", + "integrity": "sha512-wwAfVY1jTFQEfxVfdYD5r5ieYGl+0g4nhekVxNMqE8E1JeRDd18OqiwAflzpgBIqxfqvCUkf+vl5JYyacMkNAQ==", + "requires": { + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-ini": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.272.0.tgz", + "integrity": "sha512-iE3CDzK5NcupHYjfYjBdY1JCy8NLEoRUsboEjG0i0gy3S3jVpDeVHX1dLVcL/slBFj6GiM7SoNV/UfKnJf3Gaw==", + "requires": { + "@aws-sdk/credential-provider-env": "3.272.0", + "@aws-sdk/credential-provider-imds": "3.272.0", + "@aws-sdk/credential-provider-process": "3.272.0", + "@aws-sdk/credential-provider-sso": "3.272.0", + "@aws-sdk/credential-provider-web-identity": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-node": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.272.0.tgz", + "integrity": "sha512-FI8uvwM1IxiRSvbkdKv8DZG5vxU3ezaseTaB1fHWTxEUFb0pWIoHX9oeOKer9Fj31SOZTCNAaYFURbSRuZlm/w==", + "requires": { + "@aws-sdk/credential-provider-env": "3.272.0", + "@aws-sdk/credential-provider-imds": "3.272.0", + "@aws-sdk/credential-provider-ini": "3.272.0", + "@aws-sdk/credential-provider-process": "3.272.0", + "@aws-sdk/credential-provider-sso": "3.272.0", + "@aws-sdk/credential-provider-web-identity": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-process": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.272.0.tgz", + "integrity": "sha512-hiCAjWWm2PeBFp5cjkxqyam/XADjiS+e7GzwC34TbZn3LisS0uoweLojj9tD11NnnUhyhbLteUvu5+rotOLwrg==", + "requires": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-sso": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.272.0.tgz", + "integrity": "sha512-hwYaulyiU/7chKKFecxCeo0ls6Dxs7h+5EtoYcJJGvfpvCncyOZF35t00OAsCd3Wo7HkhhgfpGdb6dmvCNQAZQ==", + "requires": { + "@aws-sdk/client-sso": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/token-providers": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/credential-provider-web-identity": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.272.0.tgz", + "integrity": "sha512-ImrHMkcgneGa/HadHAQXPwOrX26sAKuB8qlMxZF/ZCM2B55u8deY+ZVkVuraeKb7YsahMGehPFOfRAF6mvFI5Q==", + "requires": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/fetch-http-handler": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.272.0.tgz", + "integrity": "sha512-1Qhm9e0RbS1Xf4CZqUbQyUMkDLd7GrsRXWIvm9b86/vgeV8/WnjO3CMue9D51nYgcyQORhYXv6uVjAYCWbUExA==", + "requires": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/querystring-builder": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/hash-node": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.272.0.tgz", + "integrity": "sha512-40dwND+iAm3VtPHPZu7/+CIdVJFk2s0cWZt1lOiMPMSXycSYJ45wMk7Lly3uoqRx0uWfFK5iT2OCv+fJi5jTng==", + "requires": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-buffer-from": "3.208.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/invalid-dependency": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.272.0.tgz", + "integrity": "sha512-ysW6wbjl1Y78txHUQ/Tldj2Rg1BI7rpMO9B9xAF6yAX3mQ7t6SUPQG/ewOGvH2208NBIl3qP5e/hDf0Q6r/1iw==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-content-length": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.272.0.tgz", + "integrity": "sha512-sAbDZSTNmLX+UTGwlUHJBWy0QGQkiClpHwVFXACon+aG0ySLNeRKEVYs6NCPYldw4cj6hveLUn50cX44ukHErw==", + "requires": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-endpoint": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.272.0.tgz", + "integrity": "sha512-Dk3JVjj7SxxoUKv3xGiOeBksvPtFhTDrVW75XJ98Ymv8gJH5L1sq4hIeJAHRKogGiRFq2J73mnZSlM9FVXEylg==", + "requires": { + "@aws-sdk/middleware-serde": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/url-parser": "3.272.0", + "@aws-sdk/util-config-provider": "3.208.0", + "@aws-sdk/util-middleware": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-host-header": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.272.0.tgz", + "integrity": "sha512-Q8K7bMMFZnioUXpxn57HIt4p+I63XaNAawMLIZ5B4F2piyukbQeM9q2XVKMGwqLvijHR8CyP5nHrtKqVuINogQ==", + "requires": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-logger": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.272.0.tgz", + "integrity": "sha512-u2SQ0hWrFwxbxxYMG5uMEgf01pQY5jauK/LYWgGIvuCmFgiyRQQP3oN7kkmsxnS9MWmNmhbyQguX2NY02s5e9w==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-recursion-detection": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.272.0.tgz", + "integrity": "sha512-Gp/eKWeUWVNiiBdmUM2qLkBv+VLSJKoWAO+aKmyxxwjjmWhE0FrfA1NQ1a3g+NGMhRbAfQdaYswRAKsul70ISg==", + "requires": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-retry": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.272.0.tgz", + "integrity": "sha512-pCGvHM7C76VbO/dFerH+Vwf7tGv7j+e+eGrvhQ35mRghCtfIou/WMfTZlD1TNee93crrAQQVZKjtW3dMB3WCzg==", + "requires": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/service-error-classification": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-middleware": "3.272.0", + "@aws-sdk/util-retry": "3.272.0", + "tslib": "^2.3.1", + "uuid": "^8.3.2" + } + }, + "@aws-sdk/middleware-sdk-sts": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.272.0.tgz", + "integrity": "sha512-VvYPg7LrDIjUOWueSzo2wBzcNG7dw+cmzV6zAKaLxf0RC5jeAP4hE0OzDiiZfDrjNghEzgq/V+0NO+LewqYL9Q==", + "requires": { + "@aws-sdk/middleware-signing": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-serde": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.272.0.tgz", + "integrity": "sha512-kW1uOxgPSwtXPB5rm3QLdWomu42lkYpQL94tM1BjyFOWmBLO2lQhk5a7Dw6HkTozT9a+vxtscLChRa6KZe61Hw==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-signing": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.272.0.tgz", + "integrity": "sha512-4LChFK4VAR91X+dupqM8fQqYhFGE0G4Bf9rQlVTgGSbi2KUOmpqXzH0/WKE228nKuEhmH8+Qd2VPSAE2JcyAUA==", + "requires": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-middleware": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-stack": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.272.0.tgz", + "integrity": "sha512-jhwhknnPBGhfXAGV5GXUWfEhDFoP/DN8MPCO2yC5OAxyp6oVJ8lTPLkZYMTW5VL0c0eG44dXpF4Ib01V+PlDrQ==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/middleware-user-agent": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.272.0.tgz", + "integrity": "sha512-Qy7/0fsDJxY5l0bEk7WKDfqb4Os/sCAgFR2zEvrhDtbkhYPf72ysvg/nRUTncmCbo8tOok4SJii2myk8KMfjjw==", + "requires": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/node-config-provider": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.272.0.tgz", + "integrity": "sha512-YYCIBh9g1EQo7hm2l22HX5Yr9RoPQ2RCvhzKvF1n1e8t1QH4iObQrYUtqHG4khcm64Cft8C5MwZmgzHbya5Z6Q==", + "requires": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/node-http-handler": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.272.0.tgz", + "integrity": "sha512-VrW9PjhhngeyYp4yGYPe5S0vgZH6NwU3Po9xAgayUeE37Inr7LS1YteFMHdpgsUUeNXnh7d06CXqHo1XjtqOKA==", + "requires": { + "@aws-sdk/abort-controller": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/querystring-builder": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/property-provider": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.272.0.tgz", + "integrity": "sha512-V1pZTaH5eqpAt8O8CzbItHhOtzIfFuWymvwZFkAtwKuaHpnl7jjrTouV482zoq8AD/fF+VVSshwBKYA7bhidIw==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/querystring-builder": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.272.0.tgz", + "integrity": "sha512-ndo++7GkdCj5tBXE6rGcITpSpZS4PfyV38wntGYAlj9liL1omk3bLZRY6uzqqkJpVHqbg2fD7O2qHNItzZgqhw==", + "requires": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/querystring-parser": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.272.0.tgz", + "integrity": "sha512-5oS4/9n6N1LZW9tI3qq/0GnCuWoOXRgcHVB+AJLRBvDbEe+GI+C/xK1tKLsfpDNgsQJHc4IPQoIt4megyZ/1+A==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/service-error-classification": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.272.0.tgz", + "integrity": "sha512-REoltM1LK9byyIufLqx9znhSolPcHQgVHIA2S0zu5sdt5qER4OubkLAXuo4MBbisUTmh8VOOvIyUb5ijZCXq1w==" + }, + "@aws-sdk/shared-ini-file-loader": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.272.0.tgz", + "integrity": "sha512-lzFPohp5sy2XvwFjZIzLVCRpC0i5cwBiaXmFzXYQZJm6FSCszHO4ax+m9yrtlyVFF/2YPWl+/bzNthy4aJtseA==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/signature-v4": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.272.0.tgz", + "integrity": "sha512-pWxnHG1NqJWMwlhJ6NHNiUikOL00DHROmxah6krJPMPq4I3am2KY2Rs/8ouWhnEXKaHAv4EQhSALJ+7Mq5S4/A==", + "requires": { + "@aws-sdk/is-array-buffer": "3.201.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-hex-encoding": "3.201.0", + "@aws-sdk/util-middleware": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/smithy-client": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.272.0.tgz", + "integrity": "sha512-pvdleJ3kaRvyRw2pIZnqL85ZlWBOZrPKmR9I69GCvlyrfdjRBhbSjIEZ+sdhZudw0vdHxq25AGoLUXhofVLf5Q==", + "requires": { + "@aws-sdk/middleware-stack": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/token-providers": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.272.0.tgz", + "integrity": "sha512-0GISJ4IKN2rXvbSddB775VjBGSKhYIGQnAdMqbvxi9LB6pSvVxcH9aIL28G0spiuL+dy3yGQZ8RlJPAyP9JW9A==", + "requires": { + "@aws-sdk/client-sso-oidc": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/shared-ini-file-loader": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/url-parser": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.272.0.tgz", + "integrity": "sha512-vX/Tx02PlnQ/Kgtf5TnrNDHPNbY+amLZjW0Z1d9vzAvSZhQ4i9Y18yxoRDIaDTCNVRDjdhV8iuctW+05PB5JtQ==", + "requires": { + "@aws-sdk/querystring-parser": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-defaults-mode-browser": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.272.0.tgz", + "integrity": "sha512-W8ZVJSZRuUBg8l0JEZzUc+9fKlthVp/cdE+pFeF8ArhZelOLCiaeCrMaZAeJusaFzIpa6cmOYQAjtSMVyrwRtg==", + "requires": { + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "bowser": "^2.11.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-defaults-mode-node": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.272.0.tgz", + "integrity": "sha512-U0NTcbMw6KFk7uz/avBmfxQSTREEiX6JDMH68oN/3ux4AICd2I4jHyxnloSWGuiER1FxZf1dEJ8ZTwy8Ibl21Q==", + "requires": { + "@aws-sdk/config-resolver": "3.272.0", + "@aws-sdk/credential-provider-imds": "3.272.0", + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/property-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-endpoints": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.272.0.tgz", + "integrity": "sha512-c4MPUaJt2G6gGpoiwIOqDfUa98c1J63RpYvf/spQEKOtC/tF5Gfqlxuq8FnAl5lHnrqj1B9ZXLLxFhHtDR0IiQ==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-middleware": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.272.0.tgz", + "integrity": "sha512-Abw8m30arbwxqmeMMha5J11ESpHUNmCeSqSzE8/C4B8jZQtHY4kq7f+upzcNIQ11lsd+uzBEzNG3+dDRi0XOJQ==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-retry": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.272.0.tgz", + "integrity": "sha512-Ngha5414LR4gRHURVKC9ZYXsEJhMkm+SJ+44wlzOhavglfdcKKPUsibz5cKY1jpUV7oKECwaxHWpBB8r6h+hOg==", + "requires": { + "@aws-sdk/service-error-classification": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-user-agent-browser": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.272.0.tgz", + "integrity": "sha512-Lp5QX5bH6uuwBlIdr7w7OAcAI50ttyskb++yUr9i+SPvj6RI2dsfIBaK4mDg1qUdM5LeUdvIyqwj3XHjFKAAvA==", + "requires": { + "@aws-sdk/types": "3.272.0", + "bowser": "^2.11.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-user-agent-node": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.272.0.tgz", + "integrity": "sha512-ljK+R3l+Q1LIHrcR+Knhk0rmcSkfFadZ8V+crEGpABf/QUQRg7NkZMsoe814tfBO5F7tMxo8wwwSdaVNNHtoRA==", + "requires": { + "@aws-sdk/node-config-provider": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-waiter": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-waiter/-/util-waiter-3.272.0.tgz", + "integrity": "sha512-N25/XsJ2wkPh1EgkFyb/GRgfHDityScfD49Hk1AwJWpfetzgkcEtWdeW4IuPymXlSKhrm5L+SBw49USxo9kBag==", + "requires": { + "@aws-sdk/abort-controller": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "fast-xml-parser": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.1.2.tgz", + "integrity": "sha512-CDYeykkle1LiA/uqQyNwYpFbyF6Axec6YapmpUP+/RHWIoR1zKjocdvNaTsxCxZzQ6v9MLXaSYm9Qq0thv0DHg==", + "requires": { + "strnum": "^1.0.5" + } + } } }, "@aws-sdk/client-sso": { @@ -16687,53 +18776,103 @@ } }, "@aws-sdk/eventstream-codec": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.226.0.tgz", - "integrity": "sha512-6uPtR8vSwz3fqoZk9hrb6qBYdp3PJ22+JxV5Wimdesvow4kJXSgDQXIxEkxbv6SxB9tNRB4uJHD84RetHEi15Q==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.272.0.tgz", + "integrity": "sha512-HYMzglDnqUhvx3u9MdzZ/OjLuavaaH9zF9XMXRuv7bdsN9AAi3/0he0FEx84ZXNXSAZCebLwXJYf0ZrN6g37QA==", "requires": { - "@aws-crypto/crc32": "2.0.0", - "@aws-sdk/types": "3.226.0", + "@aws-crypto/crc32": "3.0.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-hex-encoding": "3.201.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/eventstream-serde-browser": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.226.0.tgz", - "integrity": "sha512-otYC5aZE9eJUqAlKpy8w0rPDQ1eKGvZPtgxWXmFYSO2lDVGfI1nBBNmdZ4MdHqNuQ7ucsKMQYF8BFJ65K2tYPA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.272.0.tgz", + "integrity": "sha512-mE1+mevS+KVKpnTLi5FytsBwAK1kWZ92ERtAiElp58SKE1OpfSg8lEY8VI6JKGlueN540Qq3LeIgA2/HJOcK/w==", "requires": { - "@aws-sdk/eventstream-serde-universal": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/eventstream-serde-universal": "3.272.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/eventstream-serde-config-resolver": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.226.0.tgz", - "integrity": "sha512-A56Gypg+lyEfA5cna+EUH9XTrj0SvRG1gwNW7lrUzviN36SeA/LFTUIOEjxVML3Lowy+EPAcrSZ67h6aepoAig==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.272.0.tgz", + "integrity": "sha512-e47BhGBvx+me53cvYx+47ml5KNDj7XoTth80krHlyLrimFELE1ij4tHSKR/XzilKKH1uIWmJQdlAi29129ZX5w==", "requires": { - "@aws-sdk/types": "3.226.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/eventstream-serde-node": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.226.0.tgz", - "integrity": "sha512-KWLnKkKDzI9RNkiK6OiSYpG/XjZfue6Bsp/vRG+H5z3fbXdHv4X2+iW+Efu2Kvn7jsUyUv82TCl57DyJ/HKYhQ==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.272.0.tgz", + "integrity": "sha512-uto8y4FoZugWnczM1TKwv6oV2Po2Jgrp+W1Ws3baRQ4Lan+QpFx3Tps1N5rNzQ+7Uz0xT1BhbSNPAkKs22/jtg==", "requires": { - "@aws-sdk/eventstream-serde-universal": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/eventstream-serde-universal": "3.272.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/eventstream-serde-universal": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.226.0.tgz", - "integrity": "sha512-Q8viYM1Sv90/yIUqyWNeG1GEvyVlAI3GIrInQcCMC+xT59jS+IKGy2y7ojCvSWXnhf5/HMXKcmG092QsqeKy0Q==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.272.0.tgz", + "integrity": "sha512-E9jlt8tzDcEMoNlgv3+01jGPJPHmbmw2NsajZhB4axVMpEy247JV6qvCZe+5R+EGy96t0pfsO2naViEB4Va47g==", "requires": { - "@aws-sdk/eventstream-codec": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/eventstream-codec": "3.272.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/fetch-http-handler": { @@ -16749,14 +18888,24 @@ } }, "@aws-sdk/hash-blob-browser": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.226.0.tgz", - "integrity": "sha512-5DCvWE6L4xGoViEHyjcPFuUe1G2EtNx8TqswWaoaKgyasP/yuRm4H99Ra7rqIrjCcSTAGD9NVsUQvVVw1bGt9w==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.272.0.tgz", + "integrity": "sha512-IRCIMG42fXcdD92C8Sb0CQI8D/msxDwHGAIqP94iGhVEnKX2egyx5J8lmPY4gEky5UzyMMaH7cayBv89ZMEBmQ==", "requires": { "@aws-sdk/chunked-blob-reader": "3.188.0", "@aws-sdk/chunked-blob-reader-native": "3.208.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/hash-node": { @@ -16770,12 +18919,23 @@ } }, "@aws-sdk/hash-stream-node": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/hash-stream-node/-/hash-stream-node-3.226.0.tgz", - "integrity": "sha512-cgNTGlF8SdHaQXtjEmuLXz2U8SLM2JDKtIVPku/lHTMsUsEn+fuv2C+h1f/hvd4aNw5t1zggym7sO1/h/rv56Q==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-stream-node/-/hash-stream-node-3.272.0.tgz", + "integrity": "sha512-mWwQWdfVYoR6PXRLkHP6pC1cghZMg0ULuOAm70EtTO2YXiyLlMIDb+VD4RRbjh3hNkzh+y/W47wSUJthGBM1kg==", "requires": { - "@aws-sdk/types": "3.226.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/invalid-dependency": { @@ -16809,26 +18969,54 @@ } }, "@aws-sdk/md5-js": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/md5-js/-/md5-js-3.226.0.tgz", - "integrity": "sha512-ENigJRNudqyh6xsch166SZ4gggHd3XzZJ8gkCU4CWPne04HcR3BkWSO774IuWooCHt8zkaEHKecPurRz6qR+Vw==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/md5-js/-/md5-js-3.272.0.tgz", + "integrity": "sha512-/GK32mgAarhn/F0xCeBKbYfLRof3tOCNrg8mAGNz9Di8E1/qMOnX/OXUGag0lsvNZ6DTjdjln29t4e8iKmOVqA==", "requires": { - "@aws-sdk/types": "3.226.0", - "@aws-sdk/util-utf8-browser": "3.188.0", - "@aws-sdk/util-utf8-node": "3.208.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/middleware-bucket-endpoint": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.226.0.tgz", - "integrity": "sha512-A1Vq5W2X7jgTfjqcKPmjoHohF0poP+9fxwL97fQMvzcwmjhtoCV3bLEpo6CGYx0pKPiSlRJXZkRwRPj2hDHDmA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.272.0.tgz", + "integrity": "sha512-523T6JXfjsY9uSgMusa6myCccRv2TWyUSjzMx/0aUHfHRacJSunfPtSNX1kfYxXWn/ByWhaieHFBPehVI6wg1A==", "requires": { - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-arn-parser": "3.208.0", "@aws-sdk/util-config-provider": "3.208.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/middleware-content-length": { @@ -16857,26 +19045,65 @@ } }, "@aws-sdk/middleware-expect-continue": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.226.0.tgz", - "integrity": "sha512-YxvQKTV/eA9P8AgW0hXOgj5Qa+TSnNFfyOkfeP089aP3f6p92b1cESf33TEOKsddive2mHT5LRCN6MuPcgWWrA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.272.0.tgz", + "integrity": "sha512-TNx61LCZUKp/yZqcb38qb4tU3lbhKaI9zn2FQ+fpKzUSTI3H6E5aw42wHaq2LEacYlyK3b5Wg1R0sKR+vsUutw==", "requires": { - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/middleware-flexible-checksums": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.226.0.tgz", - "integrity": "sha512-8A9Ot9A7794UP5tMGl2MnfTW/UM/jYy1wRWF9YkR/hPIcPb7OmE0hmlwIQGzb/7grxpYw66ETKf0WeH/41YfeQ==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.272.0.tgz", + "integrity": "sha512-dc/tMiYM4wTZpjXf2PSQCFD4SQI5wyVwY5SoBgcB3W2XLq1SzXahiDnnUSn2EzDTKPIrmQmYyDFRpFEPo0sP/g==", "requires": { - "@aws-crypto/crc32": "2.0.0", - "@aws-crypto/crc32c": "2.0.0", + "@aws-crypto/crc32": "3.0.0", + "@aws-crypto/crc32c": "3.0.0", "@aws-sdk/is-array-buffer": "3.201.0", - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-utf8": "3.254.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/middleware-host-header": { @@ -16890,12 +19117,22 @@ } }, "@aws-sdk/middleware-location-constraint": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.226.0.tgz", - "integrity": "sha512-qHiYaBYPc2R37KxG2uqsUUwh4usrQMHfGkrpTUnx5d4rGzM3mC+muPsTpSHnAL63K2/yJOHQJFjss3GGwV4SSA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.272.0.tgz", + "integrity": "sha512-tROQ1DM9djxfXmXPTT0XietrUt6y6QEHShPI9rQMstjXYiaHBVXRveuRLcLAKwl4nXIrgmnIU7ygyj2ZyD8gcA==", "requires": { - "@aws-sdk/types": "3.226.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/middleware-logger": { @@ -16932,14 +19169,33 @@ } }, "@aws-sdk/middleware-sdk-s3": { - "version": "3.231.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.231.0.tgz", - "integrity": "sha512-UGaSvevd2TanfKgStF46dDSHkh4bxOr1gdUkyHm9i+1pF5lx4KdbnBZv/5SKnn7XifhHRXrs1M3lTzemXREhTA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.272.0.tgz", + "integrity": "sha512-uMvoLePkyP54b9BckMELlDnFh0SGPAfTkBwiH/FC79K7noGLA5A4KgqKObtB9LPYHkPfm1WLqIgdaE6gS1BlFQ==", "requires": { - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-arn-parser": "3.208.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/middleware-sdk-sts": { @@ -16978,12 +19234,22 @@ } }, "@aws-sdk/middleware-ssec": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.226.0.tgz", - "integrity": "sha512-DR97oWoLHiMdaUP/wu99HtzG7/ijvCrjZGDH37WBO1rxFtEti6L7T09wgHzwxMN8gtL8FJA7dU8IrffGSC9VmA==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.272.0.tgz", + "integrity": "sha512-WDPcNPkscTmJUzdAvfx8p+YuUn2YR9ocmZA7yYUJ5kA94MyGH6Rbjp8tleWwQvah/HweeCQrYUzJk9wsH64LPA==", "requires": { - "@aws-sdk/types": "3.226.0", + "@aws-sdk/types": "3.272.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/middleware-stack": { @@ -17092,15 +19358,56 @@ } }, "@aws-sdk/signature-v4-multi-region": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.226.0.tgz", - "integrity": "sha512-QHxNuf9ynK208v7Y3imdsa3Cz8ynYV7ZOf3sBJdItuEtHN6uy/KxaOrtvpF8I5Hyn48Hc8z5miTSMujFKT7GEw==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.272.0.tgz", + "integrity": "sha512-nir/ICA3saE303tS+DuJ803Uocn/d3hOpOl5DqI9RDjaZxbTXwv9uHP+by8sdyyfwCE8TFaYWoiSW5rLI+Qt0g==", "requires": { - "@aws-sdk/protocol-http": "3.226.0", - "@aws-sdk/signature-v4": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/signature-v4": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-arn-parser": "3.208.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/signature-v4": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.272.0.tgz", + "integrity": "sha512-pWxnHG1NqJWMwlhJ6NHNiUikOL00DHROmxah6krJPMPq4I3am2KY2Rs/8ouWhnEXKaHAv4EQhSALJ+7Mq5S4/A==", + "requires": { + "@aws-sdk/is-array-buffer": "3.201.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-hex-encoding": "3.201.0", + "@aws-sdk/util-middleware": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "@aws-sdk/util-utf8": "3.254.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + }, + "@aws-sdk/util-middleware": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.272.0.tgz", + "integrity": "sha512-Abw8m30arbwxqmeMMha5J11ESpHUNmCeSqSzE8/C4B8jZQtHY4kq7f+upzcNIQ11lsd+uzBEzNG3+dDRi0XOJQ==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/smithy-client": { @@ -17260,27 +19567,118 @@ } }, "@aws-sdk/util-stream-browser": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-browser/-/util-stream-browser-3.226.0.tgz", - "integrity": "sha512-ZvjlA1ySaLd0DqUWTKmL7LsxfPhroAONpzsinaHmw9aZVL40s2cADU9eWgBdHTuAOeFklL7NP0cc6UiTFHKe8g==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-browser/-/util-stream-browser-3.272.0.tgz", + "integrity": "sha512-vD514YffKxBjV/erjUNgkXcb/mzXAz3uk/KUFMXsodo3cA4Z8WxL4P0p1O09FVuJlNa0gZ8mhFPNzNOekh31GA==", "requires": { - "@aws-sdk/fetch-http-handler": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/fetch-http-handler": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-base64": "3.208.0", "@aws-sdk/util-hex-encoding": "3.201.0", - "@aws-sdk/util-utf8-browser": "3.188.0", + "@aws-sdk/util-utf8": "3.254.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/fetch-http-handler": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.272.0.tgz", + "integrity": "sha512-1Qhm9e0RbS1Xf4CZqUbQyUMkDLd7GrsRXWIvm9b86/vgeV8/WnjO3CMue9D51nYgcyQORhYXv6uVjAYCWbUExA==", + "requires": { + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/querystring-builder": "3.272.0", + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-base64": "3.208.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/querystring-builder": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.272.0.tgz", + "integrity": "sha512-ndo++7GkdCj5tBXE6rGcITpSpZS4PfyV38wntGYAlj9liL1omk3bLZRY6uzqqkJpVHqbg2fD7O2qHNItzZgqhw==", + "requires": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/util-stream-node": { - "version": "3.226.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-node/-/util-stream-node-3.226.0.tgz", - "integrity": "sha512-HADXiIgDGoXcCLSKuPnjCLENf0iC0lzqqnymZu9H2FoACZhJB7DvJ9LnP51Pvw9lfCu+yvLzbMqSPdbXtMbRWg==", + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-node/-/util-stream-node-3.272.0.tgz", + "integrity": "sha512-s7dGeM1ImzihqBKgrpaeZokLnPUk3H4Et5oiM+t+TpRxotXTecJPyuD0p76HRgO8KSXfVT5Nxw/FoHXqj1fiMg==", "requires": { - "@aws-sdk/node-http-handler": "3.226.0", - "@aws-sdk/types": "3.226.0", + "@aws-sdk/node-http-handler": "3.272.0", + "@aws-sdk/types": "3.272.0", "@aws-sdk/util-buffer-from": "3.208.0", "tslib": "^2.3.1" + }, + "dependencies": { + "@aws-sdk/abort-controller": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.272.0.tgz", + "integrity": "sha512-s2TV3phapcTwZNr4qLxbfuQuE9ZMP4RoJdkvRRCkKdm6jslsWLJf2Zlcxti/23hOlINUMYv2iXE2pftIgWGdpg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/node-http-handler": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.272.0.tgz", + "integrity": "sha512-VrW9PjhhngeyYp4yGYPe5S0vgZH6NwU3Po9xAgayUeE37Inr7LS1YteFMHdpgsUUeNXnh7d06CXqHo1XjtqOKA==", + "requires": { + "@aws-sdk/abort-controller": "3.272.0", + "@aws-sdk/protocol-http": "3.272.0", + "@aws-sdk/querystring-builder": "3.272.0", + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/protocol-http": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.272.0.tgz", + "integrity": "sha512-4JQ54v5Yn08jspNDeHo45CaSn1CvTJqS1Ywgr79eU6jBExtguOWv6LNtwVSBD9X37v88iqaxt8iu1Z3pZZAJeg==", + "requires": { + "@aws-sdk/types": "3.272.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/querystring-builder": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.272.0.tgz", + "integrity": "sha512-ndo++7GkdCj5tBXE6rGcITpSpZS4PfyV38wntGYAlj9liL1omk3bLZRY6uzqqkJpVHqbg2fD7O2qHNItzZgqhw==", + "requires": { + "@aws-sdk/types": "3.272.0", + "@aws-sdk/util-uri-escape": "3.201.0", + "tslib": "^2.3.1" + } + }, + "@aws-sdk/types": { + "version": "3.272.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.272.0.tgz", + "integrity": "sha512-MmmL6vxMGP5Bsi+4wRx4mxYlU/LX6M0noOXrDh/x5FfG7/4ZOar/nDxqDadhJtNM88cuWVHZWY59P54JzkGWmA==", + "requires": { + "tslib": "^2.3.1" + } + } } }, "@aws-sdk/util-uri-escape": { @@ -17311,6 +19709,15 @@ "tslib": "^2.3.1" } }, + "@aws-sdk/util-utf8": { + "version": "3.254.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.254.0.tgz", + "integrity": "sha512-14Kso/eIt5/qfIBmhEL9L1IfyUqswjSTqO2mY7KOzUZ9SZbwn3rpxmtkhmATkRjD7XIlLKaxBkI7tU9Zjzj8Kw==", + "requires": { + "@aws-sdk/util-buffer-from": "3.208.0", + "tslib": "^2.3.1" + } + }, "@aws-sdk/util-utf8-browser": { "version": "3.188.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.188.0.tgz", @@ -18978,6 +21385,14 @@ "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", "requires": {} }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "requires": { + "ajv": "^8.0.0" + } + }, "ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -19152,6 +21567,12 @@ "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, "ast-module-types": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-3.0.0.tgz", @@ -19873,6 +22294,12 @@ "to-function": "2.0.6" } }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, "component-props": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/component-props/-/component-props-1.1.1.tgz", @@ -20286,6 +22713,12 @@ "resolved": "https://registry.npmjs.org/convert-string/-/convert-string-0.1.0.tgz", "integrity": "sha512-1KX9ESmtl8xpT2LN2tFnKSbV4NiarbVi8DVb39ZriijvtTklyrT+4dT1wsGMHKD3CJUjXgvJzstm9qL9ICojGA==" }, + "cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true + }, "cookies": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz", @@ -20771,6 +23204,16 @@ } } }, + "dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -21736,6 +24179,12 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, + "fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, "fast-xml-parser": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz", @@ -21930,6 +24379,18 @@ "mime-types": "^2.1.12" } }, + "formidable": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", + "dev": true, + "requires": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0", + "qs": "^6.11.0" + } + }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -22433,6 +24894,12 @@ "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" }, + "hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "dev": true + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -24887,6 +27354,12 @@ "picomatch": "^2.3.1" } }, + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -26110,11 +28583,6 @@ } } }, - "readline-sync": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", - "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==" - }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -26298,9 +28766,9 @@ "integrity": "sha512-tXxQZ/bdwOCG1ONIRuP+fbR5g0YAZJZ7J9GhPVlF1al2h+FqAfYlct+ZiNFPmRMYHNosgADFsZ0SfEHrXUuWhw==" }, "rudder-transformer-cdk": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/rudder-transformer-cdk/-/rudder-transformer-cdk-1.4.3.tgz", - "integrity": "sha512-nekX3JHhRiWrY/VLCwQZSLqQB9QrB0/lo4su3Nd4B95qDSMEp4x6K1DFU7fBR5ZQ8o8PVa+2qcckyop838nSdQ==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/rudder-transformer-cdk/-/rudder-transformer-cdk-1.4.5.tgz", + "integrity": "sha512-681KUMOavx2++1hxs9ABXNI+ndNJRPEBYaHkQmNbo+kgvro3XSspiVNBfMGnqwKofLi3ysfpREQ8NFZHm3gwTA==", "requires": { "get-value": "^3.0.1", "handlebars": "^4.7.7", @@ -27704,6 +30172,34 @@ } } }, + "superagent": { + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz", + "integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==", + "dev": true, + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.4", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.1.2", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0", + "semver": "^7.3.8" + } + }, + "supertest": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz", + "integrity": "sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==", + "dev": true, + "requires": { + "methods": "^1.1.2", + "superagent": "^8.0.5" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -28084,9 +30580,9 @@ "devOptional": true }, "ua-parser-js": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.8.1.tgz", - "integrity": "sha512-top37bpoaHp+wJBAqjm5KNz7qNfSZ/tmHEisuMMK5uzjdIo/L6uWovDFuYboO+q8EMz1f67exTnd+OPYESuu8Q==" + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz", + "integrity": "sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==" }, "uglify-js": { "version": "3.17.4", @@ -28603,4 +31099,4 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index eefbf37f24..73340d7725 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.11.1", + "version": "1.13.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { @@ -43,6 +43,7 @@ "@ndhoule/extend": "^2.0.0", "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", + "ajv-formats": "^2.1.1", "aws-sdk": "^2.1292.0", "axios": "^0.27.2", "btoa": "^1.2.1", @@ -77,16 +78,14 @@ "object-hash": "^2.2.0", "parse-static-imports": "^1.1.0", "pprof": "^3.2.0", - "prom-client": "^14.0.1", - "qs": "^6.11.0", - "readline-sync": "^1.4.10", - "rudder-transformer-cdk": "^1.4.3", + "prom-client": "^14.1.1", + "rudder-transformer-cdk": "^1.4.5", "rudder-workflow-engine": "0.4.0", "set-value": "^4.1.0", "sha256": "^0.2.0", "statsd-client": "^0.4.7", "truncate-utf8-bytes": "^1.0.2", - "ua-parser-js": "^0.8.1", + "ua-parser-js": "^1.0.33", "unset-value": "^2.0.1", "uuid": "^8.3.2", "valid-url": "^1.0.9" @@ -117,7 +116,8 @@ "node-notifier": "^10.0.1", "pre-commit": "^1.2.2", "prettier": "^2.8.2", - "standard-version": "^9.5.0" + "standard-version": "^9.5.0", + "supertest": "^6.3.3" }, "lint-staged": { "*.{js,ts}": "eslint --fix", @@ -132,4 +132,4 @@ "defaultType": "feat" } } -} \ No newline at end of file +} diff --git a/src/cdk/v2/destinations/algolia/procWorkflow.yaml b/src/cdk/v2/destinations/algolia/procWorkflow.yaml index bbef23c603..765431d396 100644 --- a/src/cdk/v2/destinations/algolia/procWorkflow.yaml +++ b/src/cdk/v2/destinations/algolia/procWorkflow.yaml @@ -16,6 +16,7 @@ steps: $.assert(.message.type === {{$.EventType.TRACK}}, "message type " + .message.type + " not supported") $.assert(.message.event, "event is required for track call") + $.assert(typeof .message.event === "string", "event name should be a string") - name: preparePayload template: | diff --git a/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml b/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml index 4dd6ec7b99..99b4cb0393 100644 --- a/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml +++ b/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml @@ -8,6 +8,8 @@ bindings: path: ../../../../v0/destinations/pinterest_tag/config - name: removeUndefinedValues path: ../../../../v0/util + - name: removeUndefinedAndNullAndEmptyValues + path: ../../../../v0/util steps: - name: checkIfProcessed condition: .message.statusCode @@ -92,7 +94,7 @@ steps: "client_ip_address": .context.ip ?? .request_ip, "client_user_agent": .context.userAgent }); - userFields = $.removeUndefinedValues(userFields); + userFields = $.removeUndefinedAndNullAndEmptyValues(userFields); .destination.Config.sendingUnHashedData ? $.processUserPayload(userFields) : $.processHashedUserPayload(userFields, .message) @@ -125,7 +127,7 @@ steps: template: | let products = .message.properties.products; { - "num_items": $.sum(products.quantity.(Number(.))), + "num_items": $.sum(products.quantity.(Number(.))[]) || 0, "content_ids": products.(.product_id ?? .sku ?? .id)[], "contents": .message.properties@prop.products.({ "quantity": Number(.quantity ?? prop.quantity ?? 1), @@ -137,7 +139,7 @@ steps: template: | const props = .message.properties; const output = { - "num_items": Number(props.quantity), + "num_items": Number(props.quantity) || 0, "content_ids": (props.product_id ?? props.sku ?? props.id)[], "contents": { "quantity": Number(props.quantity) || 1, diff --git a/src/cdk/v2/destinations/webhook/procWorkflow.yaml b/src/cdk/v2/destinations/webhook/procWorkflow.yaml new file mode 100644 index 0000000000..862ae2bed9 --- /dev/null +++ b/src/cdk/v2/destinations/webhook/procWorkflow.yaml @@ -0,0 +1,82 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + exportAll: true + - path: ../../../../v0/destinations/webhook/utils + - name: getHashFromArray + path: ../../../../v0/util + - name: getIntegrationsObj + path: ../../../../v0/util + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + +steps: + - name: checkIfProcessed + condition: .message.statusCode + template: | + $.batchMode ? .message.body.JSON : .message + onComplete: return + - name: validateInput + template: | + $.assertConfig(.destination.Config.webhookUrl, "Invalid URL in destination config"); + $.assert(.message.type.toLowerCase(), "Message type is not present. Aborting message."); + - name: deduceMethod + template: | + $.context.method = .destination.Config.webhookMethod ?? 'POST'; + - name: buildHeaderBlock + template: | + let defaultHeaders = $.context.method in ['POST', 'PUT', 'PATCH'] ? {"content-type": "application/json"} : {} + let configHeaders = $.getHashFromArray(.destination.Config.headers) + let messageHeader = typeof .message.header === "object" ? Object.assign(...Object.entries(.message.header).{typeof .[1] === 'string'}[].({[.[0]]: .[1]})[]) : {} + $.context.finalHeaders = { + ...defaultHeaders, + ...configHeaders, + ...messageHeader + } + + - name: deduceEndPoint + template: | + let integrationsObjects = $.getIntegrationsObj(.message, "webhook"); + let defaultEndpoint = .destination.Config.webhookUrl; + let messageAppendPath = .message.appendPath ?? integrationsObjects.appendPath ?? ""; + + $.context.finalEndpoint = .message.fullPath ?? integrationsObjects.fullPath ?? defaultEndpoint; + $.context.finalEndpoint = $.context.finalEndpoint + messageAppendPath; + - name: prepareContext + template: | + $.context.params = {} + $.context.payload = {} + - name: prepareParams + condition: $.context.method in ['GET', 'DELETE'] + template: | + $.context.params = $.getPropertyParams(.message) ?? {} + - name: prepareBody + condition: $.context.method in ['POST', 'PUT', 'PATCH'] + template: | + let ip = .message.context.ip ?? .message.request_ip; + let payload = .message{~["fullPath", "appendPath", "header"]} + ip && ( + payload.context = payload.context || {}; + payload.context.ip = ip; + ) + $.context.payload = $.removeUndefinedAndNullValues(payload) + - name: buildResponseForProcessTransformation + template: | + $.context.payload.({ + "body": { + "JSON": ., + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": ^.message.anonymousId, + "type": "REST", + "method": $.context.method, + "endpoint": $.context.finalEndpoint, + "headers": $.context.finalHeaders, + "params": $.context.params, + "files": {} + }) + \ No newline at end of file diff --git a/src/cdk/v2/destinations/webhook/rtWorkflow.yaml b/src/cdk/v2/destinations/webhook/rtWorkflow.yaml new file mode 100644 index 0000000000..122dbe4d51 --- /dev/null +++ b/src/cdk/v2/destinations/webhook/rtWorkflow.yaml @@ -0,0 +1,32 @@ +bindings: +- name: handleRtTfSingleEventError + path: ../../../../v0/util/index + +steps: + - name: validateInput + template: | + $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") + + - name: transform + externalWorkflow: + path: ./procWorkflow.yaml + loopOverInput: true + + - name: successfulEvents + template: | + $.outputs.transform#idx.output.({ + "batchedRequest": ., + "batched": false, + "destination": ^[idx].destination, + "metadata": ^[idx].metadata[], + "statusCode": 200 + })[] + - name: failedEvents + template: | + $.outputs.transform#idx.error.( + $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) + )[] + - name: finalPayload + template: | + [...$.outputs.failedEvents, ...$.outputs.successfulEvents] + diff --git a/src/constants/destinationCanonicalNames.js b/src/constants/destinationCanonicalNames.js index c694702f79..ead81b2a1e 100644 --- a/src/constants/destinationCanonicalNames.js +++ b/src/constants/destinationCanonicalNames.js @@ -87,6 +87,23 @@ const DestCanonicalNames = { ga4: ['GA4', 'ga4', 'Ga4', 'Google Analytics 4', 'googleAnalytics4'], pipedream: ['Pipedream', 'PipeDream', 'pipedream', 'PIPEDREAM'], pagerduty: ['pagerduty', 'PAGERDUTY', 'PagerDuty', 'Pagerduty', 'pagerDuty'], + criteo_audience: [ + "criteo audience", + "criteoAudience", + "Criteo Audience", + "criteoaudience", + "CRITEO AUDIENCE", + "CRITEO_AUDIENCE", + "CRITEOAUDIENCE" + ], + optimizely_fullstack: [ + 'Optimizely Fullstack', + 'OPTIMIZELY FULLSTACK', + 'optimizely fullstack', + 'OptimizelyFullstack', + 'Optimizely_Fullstack', + 'optimizely_fullstack', + ], }; module.exports = { DestHandlerMap, DestCanonicalNames }; diff --git a/src/util/customTransformer.js b/src/util/customTransformer.js index ef683fcfcb..dc88e42989 100644 --- a/src/util/customTransformer.js +++ b/src/util/customTransformer.js @@ -3,6 +3,7 @@ const fetch = require('node-fetch'); const { getTransformationCode } = require('./customTransforrmationsStore'); const stats = require('./stats'); const { UserTransformHandlerFactory } = require('./customTransformerFactory'); +const { parserForImport } = require('./parser'); async function runUserTransform(events, code, eventsMetadata, versionId, testMode = false) { const tags = { @@ -265,7 +266,14 @@ async function setupUserTransformHandler( const resp = await UserTransformHandlerFactory(trRevCode).setUserTransform(testWithPublish); return resp; } + +// param 'validateImports' supported for python/pythonfaas. +async function extractLibraries(code, validateImports, language = "javascript") { + return parserForImport(code, validateImports, language); +} + module.exports = { userTransformHandler, setupUserTransformHandler, + extractLibraries }; diff --git a/src/util/customTransforrmationsStore-v1.js b/src/util/customTransforrmationsStore-v1.js index 40a7b006c9..894981d889 100644 --- a/src/util/customTransforrmationsStore-v1.js +++ b/src/util/customTransforrmationsStore-v1.js @@ -5,11 +5,13 @@ const { responseStatusHandler } = require('./utils'); const transformationCache = {}; const libraryCache = {}; +const rudderLibraryCache = {}; -// const CONFIG_BACKEND_URL = "http://localhost:5000"; +// const CONFIG_BACKEND_URL = 'http://localhost:5000'; const CONFIG_BACKEND_URL = process.env.CONFIG_BACKEND_URL || 'https://api.rudderlabs.com'; const getTransformationURL = `${CONFIG_BACKEND_URL}/transformation/getByVersionId`; const getLibrariesUrl = `${CONFIG_BACKEND_URL}/transformationLibrary/getByVersionId`; +const getRudderLibrariesUrl = `${CONFIG_BACKEND_URL}/rudderstackTransformationLibraries`; // Gets the transformation from config backend. // Stores the transformation object in memory with time to live after which it expires. @@ -64,4 +66,31 @@ async function getLibraryCodeV1(versionId) { } } -module.exports = { getTransformationCodeV1, getLibraryCodeV1 }; +async function getRudderLibByImportName(importName) { + const rudderLibrary = rudderLibraryCache[importName]; + if (rudderLibrary) return rudderLibrary; + const tags = { + libraryVersionId: importName, + version: 1, + type: 'rudderlibrary', + }; + try { + const [name, version] = importName.split('/').slice(-2); + const url = `${getRudderLibrariesUrl}/${name}?version=${version}`; + const startTime = new Date(); + const response = await fetchWithProxy(url); + + responseStatusHandler(response.status, 'Rudder Library', importName, url); + stats.increment('get_libraries_code.success', tags); + stats.timing('get_libraries_code', startTime, tags); + const myJson = await response.json(); + rudderLibraryCache[importName] = myJson; + return myJson; + } catch (error) { + logger.error(error); + stats.increment('get_libraries_code.error', tags); + throw error; + } +} + +module.exports = { getTransformationCodeV1, getLibraryCodeV1, getRudderLibByImportName }; diff --git a/src/util/dynamicConfig.js b/src/util/dynamicConfig.js index bfff1b63fa..6c527aa990 100644 --- a/src/util/dynamicConfig.js +++ b/src/util/dynamicConfig.js @@ -54,16 +54,16 @@ function getDynamicConfig(event) { return event; } -function processDynamicConfig(event, type) { +function processDynamicConfig(events, type) { if (type === 'router' || type === 'batch') { const eventRetArr = []; - event.forEach((e) => { + events.forEach((e) => { const newEvent = getDynamicConfig(e); eventRetArr.push(newEvent); }); return eventRetArr; } - return getDynamicConfig(event); + return getDynamicConfig(events); } exports.processDynamicConfig = processDynamicConfig; diff --git a/src/util/errorNotifier/bugsnag.js b/src/util/errorNotifier/bugsnag.js index 8ad6b530fd..94c9760c7d 100644 --- a/src/util/errorNotifier/bugsnag.js +++ b/src/util/errorNotifier/bugsnag.js @@ -72,8 +72,7 @@ function notify(err, context, metadata) { if (isDeniedErrType) return; bugsnagClient.notify(err, (event) => { - event.context = context; - event.addMetadata('metadata', metadata); + event.addMetadata('metadata', { ...metadata, opContext: context }); }); } } diff --git a/src/util/eventValidation.js b/src/util/eventValidation.js index fec8c92814..f933aa01ba 100644 --- a/src/util/eventValidation.js +++ b/src/util/eventValidation.js @@ -3,6 +3,7 @@ const Ajv2019 = require('ajv/dist/2019'); const Ajv = require('ajv-draft-04'); const draft7MetaSchema = require('ajv/dist/refs/json-schema-draft-07.json'); const draft6MetaSchema = require('ajv/dist/refs/json-schema-draft-06.json'); +const addFormats = require("ajv-formats"); const NodeCache = require('node-cache'); const hash = require('object-hash'); @@ -41,8 +42,10 @@ const supportedEventTypes = { // When no ajv options are provided, ajv constructed from defaultOptions will be used const ajv4 = new Ajv(defaultOptions); +addFormats(ajv4); const ajv19 = new Ajv2019(defaultOptions); +addFormats(ajv19); ajv19.addMetaSchema(draft6MetaSchema); ajv19.addMetaSchema(draft7MetaSchema); @@ -55,11 +58,14 @@ ajv19.addMetaSchema(draft7MetaSchema); */ function getAjv(ajvOptions, isDraft4 = false) { if (isDraft4) { - return new Ajv(ajvOptions); + const ajv = new Ajv(ajvOptions); + addFormats(ajv); + return ajv; } const ajv = new Ajv2019(ajvOptions); ajv.addMetaSchema(draft6MetaSchema); ajv.addMetaSchema(draft7MetaSchema); + addFormats(ajv); return ajv; } diff --git a/src/util/ivmFactory.js b/src/util/ivmFactory.js index 0eae6ac0b1..a987806db6 100644 --- a/src/util/ivmFactory.js +++ b/src/util/ivmFactory.js @@ -3,10 +3,12 @@ const fetch = require('node-fetch'); const _ = require('lodash'); const stats = require('./stats'); -const { getLibraryCodeV1 } = require('./customTransforrmationsStore-v1'); +const { getLibraryCodeV1, getRudderLibByImportName } = require('./customTransforrmationsStore-v1'); const { parserForImport } = require('./parser'); const logger = require('../logger'); +const RUDDER_LIBRARY_REGEX = /^@rs\/[A-Za-z]+\/v[0-9]{1,3}$/; + const isolateVmMem = 128; async function evaluateModule(isolate, context, moduleCode) { const module = await isolate.compileModule(moduleCode); @@ -25,18 +27,29 @@ async function createIvm(code, libraryVersionIds, versionId, testMode) { const createIvmStartTime = new Date(); const logs = []; const libraries = await Promise.all( - libraryVersionIds.map(async (libraryVersionId) => getLibraryCodeV1(libraryVersionId)), + libraryVersionIds.map(async (libraryVersionId) => await getLibraryCodeV1(libraryVersionId)), ); const librariesMap = {}; if (code && libraries) { - const extractedLibraries = Object.keys(parserForImport(code)); - // TODO: Check if this should this be && + const extractedLibImportNames = Object.keys(await parserForImport(code)); + libraries.forEach((library) => { const libHandleName = _.camelCase(library.name); - if (extractedLibraries.includes(libHandleName)) { + if (extractedLibImportNames.includes(libHandleName)) { librariesMap[libHandleName] = library.code; } }); + + // Extract ruddder libraries from import names + const rudderLibImportNames = extractedLibImportNames.filter((name) => + RUDDER_LIBRARY_REGEX.test(name), + ); + const rudderLibraries = await Promise.all( + rudderLibImportNames.map(async (importName) => await getRudderLibByImportName(importName)), + ); + rudderLibraries.forEach((library) => { + librariesMap[library.importName] = library.code; + }); } const codeWithWrapper = @@ -259,10 +272,12 @@ async function createIvm(code, libraryVersionIds, versionId, testMode) { const bootstrapScriptResult = await bootstrap.run(context); // const customScript = await isolate.compileScript(`${library} ;\n; ${code}`); const customScriptModule = await isolate.compileModule(`${codeWithWrapper}`); - await customScriptModule.instantiate(context, (spec) => { + await customScriptModule.instantiate(context, async (spec) => { if (librariesMap[spec]) { return compiledModules[spec].module; } + // Release the isolate context before throwing an error + await context.release(); console.log(`import from ${spec} failed. Module not found.`); throw new Error(`import from ${spec} failed. Module not found.`); }); diff --git a/src/util/libExtractor.js b/src/util/libExtractor.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/util/openfaas/faasApi.js b/src/util/openfaas/faasApi.js index 06f53a688f..3922b35ba3 100644 --- a/src/util/openfaas/faasApi.js +++ b/src/util/openfaas/faasApi.js @@ -61,10 +61,22 @@ const deployFunction = async (payload) => .catch((err) => reject(parseAxiosError(err))); }); +const checkFunctionHealth = async (functionName) => + new Promise((resolve, reject) => { + const url = `${OPENFAAS_GATEWAY_URL}/function/${functionName}`; + axios + .get(url, { + headers: { "X-REQUEST-TYPE": "HEALTH-CHECK"} + }) + .then((resp) => resolve(resp)) + .catch((err) => reject(parseAxiosError(err))); + }); + module.exports = { deleteFunction, deployFunction, getFunction, getFunctionList, invokeFunction, + checkFunctionHealth }; diff --git a/src/util/openfaas/index.js b/src/util/openfaas/index.js index 3cfe6808b3..474e945cc3 100644 --- a/src/util/openfaas/index.js +++ b/src/util/openfaas/index.js @@ -1,5 +1,5 @@ const NodeCache = require('node-cache'); -const { getFunction, deleteFunction, deployFunction, invokeFunction } = require('./faasApi'); +const { getFunction, deleteFunction, deployFunction, invokeFunction, checkFunctionHealth } = require('./faasApi'); const logger = require('../../logger'); const { RetryRequestError, RespStatusError } = require('../utils'); @@ -13,26 +13,60 @@ const FAAS_MAX_INFLIGHT = process.env.FAAS_MAX_INFLIGHT || '4'; const FAAS_EXEC_TIMEOUT = process.env.FAAS_EXEC_TIMEOUT || '4s'; const FAAS_ENABLE_WATCHDOG_ENV_VARS = process.env.FAAS_ENABLE_WATCHDOG_ENV_VARS || 'true'; const CONFIG_BACKEND_URL = process.env.CONFIG_BACKEND_URL || 'https://api.rudderlabs.com'; +const FAAS_AST_VID = "ast"; +const FAAS_AST_FN_NAME = "fn-ast"; // Initialise node cache const functionListCache = new NodeCache(); const FUNC_LIST_KEY = 'fn-list'; functionListCache.set(FUNC_LIST_KEY, []); +const DEFAULT_RETRY_DELAY_MS = 2000; +const DEFAULT_RETRY_THRESHOLD = 2; + const delayInMs = async (ms = 2000) => new Promise((resolve) => setTimeout(resolve, ms)); -const callWithRetry = async (fn, count = 0, ...args) => { +const callWithRetry = async (fn, count = 0, delay = DEFAULT_RETRY_DELAY_MS, retryThreshold = DEFAULT_RETRY_THRESHOLD, ...args) => { try { return await fn(...args); } catch (err) { - if (count > 2) { + if (count > retryThreshold) { throw err; } - await delayInMs(); - return callWithRetry(fn, count + 1); + await delayInMs(delay); + return callWithRetry(fn, count + 1, delay, retryThreshold, args); } }; +const awaitFunctionReadiness = async (functionName, maxWaitInMs = 22000, waitBetweenIntervalsInMs = 250) => { + const executionPromise = new Promise(async (resolve) => { + try { + await callWithRetry( + checkFunctionHealth, + 0, + waitBetweenIntervalsInMs, + Math.floor(maxWaitInMs/waitBetweenIntervalsInMs), + functionName + ); + + resolve(true); + } catch (error) { + logger.error(`Error while waiting for function ${functionName} to be ready: ${error}`); + resolve(error.message); + } + }); + + let setTimeoutHandle; + const timeoutPromise = new Promise((resolve) => { + setTimeoutHandle = setTimeout(() => { + resolve('Timedout'); + }, maxWaitInMs); + }); + + return Promise.race([executionPromise, timeoutPromise]) + .finally(() => clearTimeout(setTimeoutHandle)); +} + const isFunctionDeployed = (functionName) => { const funcList = functionListCache.get(FUNC_LIST_KEY) || []; return funcList.includes(functionName); @@ -114,7 +148,7 @@ async function setupFaasFunction(functionName, code, versionId, testMode) { // This api call is only used to check if function is spinned eventually // TODO: call health endpoint instead of get function to get correct status - await callWithRetry(getFunction, 0, functionName); + await callWithRetry(getFunction, 0, 2000, 2, functionName); setFunctionInCache(functionName); logger.debug(`[Faas] Finished deploying faas function ${functionName}`); @@ -127,6 +161,9 @@ async function setupFaasFunction(functionName, code, versionId, testMode) { const executeFaasFunction = async (functionName, events, versionId, testMode) => { try { logger.debug('[Faas] Invoking faas function'); + + if (testMode) await awaitFunctionReadiness(functionName); + const res = await invokeFunction(functionName, events); logger.debug('[Faas] Invoked faas function'); return res; @@ -163,7 +200,10 @@ const executeFaasFunction = async (functionName, events, versionId, testMode) => }; module.exports = { + awaitFunctionReadiness, executeFaasFunction, setupFaasFunction, invalidateFnCache, + FAAS_AST_VID, + FAAS_AST_FN_NAME }; diff --git a/src/util/parser.js b/src/util/parser.js index 8cc8f3b1aa..d7a5e11419 100644 --- a/src/util/parser.js +++ b/src/util/parser.js @@ -1,6 +1,22 @@ +const axios = require('axios'); const parseStaticImports = require('parse-static-imports'); +const { executeFaasFunction, FAAS_AST_VID, FAAS_AST_FN_NAME } = require('./openfaas'); -function parserForImport(code) { +async function parserForImport(code, validateImports=true, language="javascript") { + if (!code || code.trim().length === 0) throw Error('No code for parsing'); + + switch(language) { + case "javascript": + return parserForJSImports(code); + case "python": + case "pythonfaas": + return parserForPythonImports(code, validateImports); + default: + throw Error(`Unsupported language ${language}`); + } +} + +function parserForJSImports(code) { const obj = {}; const modules = parseStaticImports(code); @@ -21,4 +37,33 @@ function parserForImport(code) { return obj; } -exports.parserForImport = parserForImport; +async function parserForPythonImports(code, validateImports=true, additionalLibs=[]) { + const obj = {}; + + const payload = [{ + message: { + messageId: "1", + code, + validateImports, + additionalLibraries: additionalLibs + } + }]; + + const result = await executeFaasFunction( + FAAS_AST_FN_NAME, + payload, + FAAS_AST_VID, + false + ); + + const err = result.transformedEvents[0].error; + + if (err) { + throw Error(err); + } + + result.transformedEvents[0].transformedEvent.modules.forEach((mod) => obj[mod.name] = []); + return obj; +} + +exports.parserForImport = parserForImport; \ No newline at end of file diff --git a/src/util/stats.js b/src/util/stats.js index def21ac4b7..bb0a984f8d 100644 --- a/src/util/stats.js +++ b/src/util/stats.js @@ -3,12 +3,15 @@ const SDC = require('statsd-client'); const enableStats = process.env.ENABLE_STATS !== 'false'; const statsServerHost = process.env.STATSD_SERVER_HOST || 'localhost'; const statsServerPort = parseInt(process.env.STATSD_SERVER_PORT || '8125', 10); +const instanceID = process.env.INSTANCE_ID || 'localhost'; const statsdClient = new SDC({ host: statsServerHost, port: statsServerPort, prefix: 'transformer', - tags: {}, + tags: { + instanceName: instanceID, + }, }); // Sends the diff between current time and start as the stat diff --git a/src/v0/destinations/am/transform.js b/src/v0/destinations/am/transform.js index 1ab0f38fd9..a302c9fe9c 100644 --- a/src/v0/destinations/am/transform.js +++ b/src/v0/destinations/am/transform.js @@ -97,8 +97,8 @@ function getSessionId(message) { return get(message, 'session_id') ? handleSessionIdUnderRoot(message) : get(message, 'context.sessionId') - ? handleSessionIdUnderContext(message) - : -1; + ? handleSessionIdUnderContext(message) + : -1; } function addMinIdlength() { @@ -131,8 +131,10 @@ function createRevenuePayload(message, rawPayload) { function updateTraitsObject(property, traitsObject, actionKey) { const propertyToUpdate = getValueFromMessage(traitsObject, property); - traitsObject[actionKey][property] = propertyToUpdate; - deleteObjectProperty(traitsObject, property); + if (traitsObject[actionKey] && property && typeof property === 'string') { + traitsObject[actionKey][property] = propertyToUpdate; + deleteObjectProperty(traitsObject, property); + } return traitsObject; } @@ -142,6 +144,9 @@ function prepareTraitsConfig(configPropertyTrait, actionKey, traitsObject) { const property = traitsElement.traits; traitsObject = updateTraitsObject(property, traitsObject, actionKey); }); + if (Object.keys(traitsObject[actionKey]).length === 0) { + delete traitsObject[actionKey]; + } return traitsObject; } @@ -520,9 +525,8 @@ function processSingleMessage(message, destination) { category = ConfigCategory.PAGE; break; case EventType.SCREEN: - evType = `Viewed ${ - message.name || message.event || get(message, 'properties.category') || '' - } Screen`; + evType = `Viewed ${message.name || message.event || get(message, 'properties.category') || '' + } Screen`; message.properties = { ...message.properties, name: message.name || message.event || get(message, 'properties.category'), @@ -756,7 +760,7 @@ function getBatchEvents(message, destination, metadata, batchEventResponse) { if ( batchEventArray.length < AMBatchEventLimit && JSON.stringify(batchPayloadJSON).length + JSON.stringify(incomingMessageEvent).length < - AMBatchSizeLimit + AMBatchSizeLimit ) { batchEventArray.push(incomingMessageEvent); // set value batchEventJobs.push(metadata); @@ -790,14 +794,14 @@ function batch(destEvents) { messageEvent && Array.isArray(messageEvent) ? messageEvent[0].user_id : messageEvent - ? messageEvent.user_id - : undefined; + ? messageEvent.user_id + : undefined; deviceId = messageEvent && Array.isArray(messageEvent) ? messageEvent[0].device_id : messageEvent - ? messageEvent.device_id - : undefined; + ? messageEvent.device_id + : undefined; // this case shold not happen and should be filtered already // by the first pass of single event transformation if (messageEvent && !userId && !deviceId) { diff --git a/src/v0/destinations/criteo_audience/config.js b/src/v0/destinations/criteo_audience/config.js new file mode 100644 index 0000000000..1779aa3f56 --- /dev/null +++ b/src/v0/destinations/criteo_audience/config.js @@ -0,0 +1,10 @@ +const version = "2022-10"; +const BASE_ENDPOINT = `https://api.criteo.com/${version}/`; +const operation = ["add", "remove"]; +// https://developers.criteo.com/marketing-solutions/v2021.04/docs/managing-users-in-an-audience +const MAX_IDENTIFIERS = 50000; +module.exports = { + BASE_ENDPOINT, + operation, + MAX_IDENTIFIERS +}; diff --git a/src/v0/destinations/criteo_audience/networkHandler.js b/src/v0/destinations/criteo_audience/networkHandler.js new file mode 100644 index 0000000000..b9424810af --- /dev/null +++ b/src/v0/destinations/criteo_audience/networkHandler.js @@ -0,0 +1,93 @@ +const { + prepareProxyRequest, + proxyRequest +} = require("../../../adapters/network"); +const { isHttpStatusSuccess } = require("../../util/index"); +const { + REFRESH_TOKEN +} = require("../../../adapters/networkhandler/authConstants"); +const tags = require("../../util/tags"); +const { + getDynamicErrorType, + processAxiosResponse +} = require("../../../adapters/utils/networkUtils"); +const { NetworkError, ThrottledError, NetworkInstrumentationError, AbortedError, RetryableError } = require("../../util/errorTypes"); + +// https://developers.criteo.com/marketing-solutions/v2021.01/docs/how-to-handle-api-errors#:~:text=the%20response%20body.-,401,-Authentication%20error +// Following fucntion tells us if there is a particular error code in the response. +const matchErrorCode = (errorCode, response) => + response && Array.isArray(response?.errors) && response.errors.some((resp) => resp?.code === errorCode); + +const criteoAudienceRespHandler = (destResponse, stageMsg) => { + const { status, response } = destResponse; + + // https://developers.criteo.com/marketing-solutions/docs/api-error-types#error-category-types + // to handle the case when authorization-token is invalid + if (status === 401 && matchErrorCode('authorization-token-invalid', response)) { + throw new NetworkError( + `${response?.errors[0]?.title} ${stageMsg}`, + status, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status) + }, + response, + REFRESH_TOKEN + ); + } else if (status === 404 && matchErrorCode('audience-invalid', response)) { + // to handle the case when audience-id is invalid + throw new NetworkInstrumentationError( + `AudienceId is Invalid. Please Provide Valid AudienceId`, + destResponse, + ); + } else if (status === 429) { + // https://developers.criteo.com/marketing-solutions/docs/api-error-types#429 + throw new ThrottledError( + `Request Failed: ${stageMsg} - due to Request Limit exceeded, (Throttled)`, + destResponse, + ); + } else if (status === 503 || status === 500) { + // see if its 500 internal error or 503 service unavailable + throw new RetryableError( + `Request Failed: ${stageMsg} (Retryable)`, + 500, + destResponse, + ); + } + // else throw the error + const errorMessage = response?.errors; + throw new AbortedError( + `Request Failed: ${stageMsg} with status "${status}" due to "${errorMessage? JSON.stringify(errorMessage[0]) : JSON.stringify(response) + }", (Aborted) `, + 400, + destResponse, + ); +}; + +const responseHandler = destinationResponse => { + const message = `Request Processed Successfully`; + const { status } = destinationResponse; + if (!isHttpStatusSuccess(status)) { + // if error, successfully return status, message and original destination response + criteoAudienceRespHandler( + destinationResponse, + "during criteo_audience response transformation" + ); + } + // Mostly any error will not have a status of 2xx + return { + status, + message, + destinationResponse + }; +}; + +class networkHandler { + constructor() { + this.responseHandler = responseHandler; + this.proxy = proxyRequest; + this.prepareProxy = prepareProxyRequest; + this.processAxiosResponse = processAxiosResponse; + } +} + +module.exports = { networkHandler }; diff --git a/src/v0/destinations/criteo_audience/transform.js b/src/v0/destinations/criteo_audience/transform.js new file mode 100644 index 0000000000..3e97668d10 --- /dev/null +++ b/src/v0/destinations/criteo_audience/transform.js @@ -0,0 +1,97 @@ +const { + BASE_ENDPOINT, + operation +} = require("./config"); +const { + defaultRequestConfig, + removeUndefinedAndNullValues, + simpleProcessRouterDest, + defaultPatchRequestConfig, + getAccessToken, + getEventType +} = require("../../util"); +const { InstrumentationError } = require("../../util/errorTypes"); + +const { preparePayload } = require("./util"); + +const prepareResponse = (payload, audienceId, accessToken) => { + const response = defaultRequestConfig(); + response.endpoint = `${BASE_ENDPOINT}audiences/${audienceId}/contactlist`; + response.body.JSON = removeUndefinedAndNullValues(payload); + response.method = defaultPatchRequestConfig.requestMethod; + response.headers = { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + Accept: "application/json" + }; + return response; +}; +/** + * This function is used for building the final response to be returned. + * @param {*} message + * @param {*} destination + * @returns + */ +const responseBuilder = (message, destination, accessToken) => { + const responseArray = []; + const { Config } = destination; + const { audienceId } = Config; + const { listData } = message.properties; + operation.forEach(op => { + if (listData[op]) { + const criteoPayloadArray = preparePayload( + listData[op], + op, + Config + ); + criteoPayloadArray.forEach(criteoPayload => { + responseArray.push( + prepareResponse(criteoPayload, audienceId, accessToken) + ); + }); + + } + }); + + if (responseArray.length === 0) { + throw new InstrumentationError(`Payload could not be populated`); + } + return responseArray; +}; + +const processEvent = async (metadata, message, destination) => { + const accessToken = getAccessToken(metadata, 'accessToken'); + let response; + if (!message.type) { + throw new InstrumentationError( + "Message Type is not present. Aborting message." + ); + } + if (!message.properties) { + throw new InstrumentationError( + "Message properties is not present. Aborting message." + ); + } + if (!message.properties.listData) { + throw new InstrumentationError( + "listData is not present inside properties. Aborting message." + ); + } + if (getEventType(message) === "audiencelist") { + response = responseBuilder(message, destination, accessToken); + } else { + throw new InstrumentationError( + `Event type ${message.type} is not supported` + ); + } + return response; +}; + +const process = async event => processEvent(event.metadata, event.message, event.destination); + +const processRouterDest = async (inputs, reqMetadata) => { + const respList = await simpleProcessRouterDest(inputs, process, reqMetadata); + return respList; +}; + +module.exports = { process, processRouterDest }; diff --git a/src/v0/destinations/criteo_audience/util.js b/src/v0/destinations/criteo_audience/util.js new file mode 100644 index 0000000000..6bd58816c4 --- /dev/null +++ b/src/v0/destinations/criteo_audience/util.js @@ -0,0 +1,72 @@ +const _ = require('lodash'); +const { isDefinedAndNotNullAndNotEmpty } = require("../../util"); +const { + ConfigurationError, + InstrumentationError +} = require("../../util/errorTypes"); +const { MAX_IDENTIFIERS } = require("./config"); + +const populateIdentifiers = (audienceList, audienceType) => { + const identifiers = []; + audienceList.forEach(userTraits => { + const traits = Object.keys(userTraits); + if (!traits.includes(audienceType)) { + throw new InstrumentationError( + `Required property for ${audienceType} type audience is not available in an object` + ); + } + identifiers.push(userTraits[audienceType]); + }); + const identifierChunks = _.chunk(identifiers, MAX_IDENTIFIERS); + return identifierChunks; +}; + +const populateAttributes = (audienceList, operationType, Config) => { + const { audienceType, gumCallerId } = Config; + + const attributesArray = []; + const identifiers = populateIdentifiers(audienceList, audienceType); + identifiers.forEach(identifier => { + const attributes = {}; + attributes.operation = operationType; + attributes.identifierType = audienceType; + attributes.internalIdentifiers = false; + if (audienceType === "gum") { + if (!isDefinedAndNotNullAndNotEmpty(gumCallerId)) { + throw new ConfigurationError( + `gumCallerId is required for audience type ${audienceType}` + ); + } else { + attributes.gumCallerId = gumCallerId; + } + } + attributes.identifiers = identifier; + attributesArray.push(attributes); + }); + return attributesArray; +}; + +const populateData = (audienceList, operationType, Config) => { + const arrayData = []; + const populatedAttributesArray = populateAttributes(audienceList, operationType, Config); + populatedAttributesArray.forEach(populatedAttribute => { + const data = {}; + data.type = "ContactlistAmendment"; + data.attributes = populatedAttribute; + arrayData.push(data); + }); + return arrayData; +}; + +const preparePayload = (audienceList, operationType, Config) => { + const responsePayload = []; + const populatedData = populateData(audienceList, operationType, Config); + populatedData.forEach(data => { + responsePayload.push({ data }); + }); + return responsePayload; +}; + +module.exports = { + preparePayload +}; diff --git a/src/v0/destinations/ga4/data/GA4CommonConfig.json b/src/v0/destinations/ga4/data/GA4CommonConfig.json index 3047679056..b6e29044c6 100644 --- a/src/v0/destinations/ga4/data/GA4CommonConfig.json +++ b/src/v0/destinations/ga4/data/GA4CommonConfig.json @@ -3,7 +3,10 @@ "destKey": "user_id", "sourceKeys": "userIdOnly", "sourceFromGenericMap": true, - "required": false + "required": false, + "metadata": { + "type": "toString" + } }, { "destKey": "timestamp_micros", diff --git a/src/v0/destinations/ga4/transform.js b/src/v0/destinations/ga4/transform.js index 43ba645678..eb9c53a6eb 100644 --- a/src/v0/destinations/ga4/transform.js +++ b/src/v0/destinations/ga4/transform.js @@ -13,7 +13,11 @@ const { getIntegrationsObj, isHybridModeEnabled, } = require('../../util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); +const { + InstrumentationError, + ConfigurationError, + UnsupportedEventError, +} = require('../../util/errorTypes'); const { ENDPOINT, DEBUG_ENDPOINT, @@ -428,8 +432,14 @@ const process = (event) => { break; case EventType.PAGE: // GA4 custom event 'page_view' is fired for page - message.event = 'page_view'; - response = responseBuilder(message, destination); + if (!isHybridModeEnabled(Config)) { + message.event = 'page_view'; + response = responseBuilder(message, destination); + } else { + throw new UnsupportedEventError( + 'GA4 Hybrid mode is enabled, page calls will be sent through device mode', + ); + } break; case EventType.GROUP: // GA4 standard event 'join_group' is fired for group diff --git a/src/v0/destinations/impact_radius/config.js b/src/v0/destinations/impact/config.js similarity index 100% rename from src/v0/destinations/impact_radius/config.js rename to src/v0/destinations/impact/config.js diff --git a/src/v0/destinations/impact_radius/data/ImpactConversionConfig.json b/src/v0/destinations/impact/data/ImpactConversionConfig.json similarity index 99% rename from src/v0/destinations/impact_radius/data/ImpactConversionConfig.json rename to src/v0/destinations/impact/data/ImpactConversionConfig.json index 167cf0483e..7ae0cc72eb 100644 --- a/src/v0/destinations/impact_radius/data/ImpactConversionConfig.json +++ b/src/v0/destinations/impact/data/ImpactConversionConfig.json @@ -9,7 +9,7 @@ "destKey": "EventDate", "sourceKeys": "timestamp", "sourceFromGenericMap": true, - "required": false + "required": true }, { "destKey": "CurrencyCode", diff --git a/src/v0/destinations/impact_radius/data/ImpactPageLoadConfig.json b/src/v0/destinations/impact/data/ImpactPageLoadConfig.json similarity index 100% rename from src/v0/destinations/impact_radius/data/ImpactPageLoadConfig.json rename to src/v0/destinations/impact/data/ImpactPageLoadConfig.json diff --git a/src/v0/destinations/impact_radius/transform.js b/src/v0/destinations/impact/transform.js similarity index 100% rename from src/v0/destinations/impact_radius/transform.js rename to src/v0/destinations/impact/transform.js diff --git a/src/v0/destinations/impact_radius/util.js b/src/v0/destinations/impact/util.js similarity index 99% rename from src/v0/destinations/impact_radius/util.js rename to src/v0/destinations/impact/util.js index 27cee1639c..b8c6e92e76 100644 --- a/src/v0/destinations/impact_radius/util.js +++ b/src/v0/destinations/impact/util.js @@ -60,6 +60,8 @@ const getProductsMapping = (productsMapping, itemName) => { productsMapping.forEach((mapping) => { prop = mapping.to === itemName ? mapping.from : itemMapping[itemName]; }); + } else { + prop = itemMapping[itemName]; } return prop; }; diff --git a/src/v0/destinations/klaviyo/config.js b/src/v0/destinations/klaviyo/config.js index 8e79aeb9c0..70f3ddf877 100644 --- a/src/v0/destinations/klaviyo/config.js +++ b/src/v0/destinations/klaviyo/config.js @@ -49,8 +49,8 @@ const jsonNameMapping = { 'Started Checkout': 'STARTED_CHECKOUT', }; const LIST_CONF = { - SUBSCRIBE: 'Subscribe', - MEMBERSHIP: 'Membership', + SUBSCRIBE: 'subscribe_with_consentInfo', + ADD_TO_LIST: 'subscribe_without_consentInfo', }; const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); diff --git a/src/v0/destinations/klaviyo/transform.js b/src/v0/destinations/klaviyo/transform.js index 210a45756d..04296d709e 100644 --- a/src/v0/destinations/klaviyo/transform.js +++ b/src/v0/destinations/klaviyo/transform.js @@ -12,7 +12,7 @@ const { eventNameMapping, jsonNameMapping, } = require('./config'); -const { isProfileExist, checkForMembersAndSubscribe, createCustomerProperties } = require('./util'); +const { isProfileExist, createCustomerProperties, checkForSubscribe } = require('./util'); const { defaultRequestConfig, constructPayload, @@ -56,7 +56,10 @@ const identifyRequestHandler = async (message, category, destination) => { } const traitsInfo = getFieldValueFromMessage(message, 'traits'); const response = defaultRequestConfig(); - const personId = await isProfileExist(message, destination); + let personId; + if (message.channel !== 'sources') { + personId = await isProfileExist(message, destination); + } let propertyPayload = constructPayload(message, MAPPING_CONFIG[category.name]); // Extract other K-V property from traits about user custom properties propertyPayload = extractCustomFields( @@ -92,7 +95,7 @@ const identifyRequestHandler = async (message, category, destination) => { response.params.api_key = destination.Config.privateApiKey; } const responseArray = [response]; - responseArray.push(...checkForMembersAndSubscribe(message, traitsInfo, destination)); + responseArray.push(...checkForSubscribe(message, traitsInfo, destination)); return responseArray; }; @@ -201,6 +204,9 @@ const groupRequestHandler = (message, category, destination) => { if (!destination.Config.privateApiKey) { throw new ConfigurationError('Private API Key is a required field for group events'); } + if (!message.groupId) { + throw new InstrumentationError('groupId is a required field for group events'); + } let profile = constructPayload(message, MAPPING_CONFIG[category.name]); // Extract other K-V property from traits about user custom properties const groupWhitelistedTraits = [...WhiteListedTraits, 'consent', 'smsConsent', 'subscribe']; @@ -215,45 +221,23 @@ const groupRequestHandler = (message, category, destination) => { delete profile.$id; profile._id = getFieldValueFromMessage(message, 'userId'); } - const responseArray = []; + if (message.traits.subscribe === true) { + profile.sms_consent = message.context?.traits.smsConsent || destination.Config.smsConsent; + profile.$consent = message.context?.traits.consent || destination.Config.consent; + } - const payload = { + const subscribePayload = { profiles: [profile], }; - const membersResponse = defaultRequestConfig(); - membersResponse.endpoint = `${BASE_ENDPOINT}/api/v2/list/${get(message, 'groupId')}/members`; - membersResponse.headers = { + const subscribeResponse = defaultRequestConfig(); + subscribeResponse.endpoint = `${BASE_ENDPOINT}/api/v2/list/${message.groupId}/subscribe`; + subscribeResponse.headers = { 'Content-Type': 'application/json', }; - membersResponse.body.JSON = payload; - membersResponse.method = defaultPostRequestConfig.requestMethod; - membersResponse.params = { api_key: destination.Config.privateApiKey }; - responseArray.push(membersResponse); - - if (get(message.traits, 'subscribe') === true) { - // Adding Consent Info to Profiles - const subscribeProfile = JSON.parse(JSON.stringify(profile)); - subscribeProfile.sms_consent = - message.context?.traits.smsConsent || destination.Config.smsConsent; - subscribeProfile.$consent = message.context?.traits.consent || destination.Config.consent; - - const subscribePayload = { - profiles: [subscribeProfile], - }; - const subscribeResponse = defaultRequestConfig(); - subscribeResponse.endpoint = `${BASE_ENDPOINT}/api/v2/list/${get( - message, - 'groupId', - )}/subscribe`; - subscribeResponse.headers = { - 'Content-Type': 'application/json', - }; - subscribeResponse.body.JSON = subscribePayload; - subscribeResponse.method = defaultPostRequestConfig.requestMethod; - subscribeResponse.params = { api_key: destination.Config.privateApiKey }; - responseArray.push(subscribeResponse); - } - return responseArray; + subscribeResponse.body.JSON = subscribePayload; + subscribeResponse.method = defaultPostRequestConfig.requestMethod; + subscribeResponse.params = { api_key: destination.Config.privateApiKey }; + return subscribeResponse; }; // Main event processor using specific handler funcs diff --git a/src/v0/destinations/klaviyo/util.js b/src/v0/destinations/klaviyo/util.js index 2c40f5d71c..417f98aa1f 100644 --- a/src/v0/destinations/klaviyo/util.js +++ b/src/v0/destinations/klaviyo/util.js @@ -1,4 +1,3 @@ -const get = require('get-value'); const { httpGET } = require('../../../adapters/network'); const { WhiteListedTraits } = require('../../../constants'); @@ -78,15 +77,14 @@ const isProfileExist = async (message, { Config }) => { }; /** - * This function is used for creating response for adding members to a specific list - * and subscribing members to a particular list depending on the condition passed. + * This function is used for creating response for subscribing users to a particular list. * DOCS: https://www.klaviyo.com/docs/api/v2/lists */ -const addUserToList = (message, traitsInfo, conf, destination) => { +const subscribeUserToList = (message, traitsInfo, conf, destination) => { // listId from message properties are preferred over Config listId - let targetUrl = `${BASE_ENDPOINT}/api/v2/list/${ - traitsInfo.properties?.listId || destination.Config.listId - }`; + const targetUrl = `${BASE_ENDPOINT}/api/v2/list/${ + traitsInfo.properties?.listId || destination.Config?.listId + }/subscribe`; let profile = { id: getFieldValueFromMessage(message, 'userId'), email: getFieldValueFromMessage(message, 'email'), @@ -97,12 +95,8 @@ const addUserToList = (message, traitsInfo, conf, destination) => { // eslint-disable-next-line no-underscore-dangle profile._id = getFieldValueFromMessage(message, 'userId'); } - // If func is called as membership func else subscribe func - if (conf === LIST_CONF.MEMBERSHIP) { - targetUrl = `${targetUrl}/members`; - } else { + if (conf === LIST_CONF.SUBSCRIBE) { // get consent statuses from message if availabe else from dest config - targetUrl = `${targetUrl}/subscribe`; profile.sms_consent = traitsInfo.properties?.smsConsent || destination.Config.smsConsent; profile.$consent = traitsInfo.properties?.consent || destination.Config.consent; } @@ -123,33 +117,35 @@ const addUserToList = (message, traitsInfo, conf, destination) => { }; /** - * This function is used to check if the user needs to be added to list or needs to be subscribed or not. - * Building and returning response array for both the members(for adding to the list) and subscribe - * endpoints (for subscribing) + * This function is used to check if the user needs to be subscribed or not. + * Building and returning response array for subscribe endpoint (for subscribing) * @param {*} message * @param {*} traitsInfo * @param {*} destination * @returns */ -const checkForMembersAndSubscribe = (message, traitsInfo, destination) => { +const checkForSubscribe = (message, traitsInfo, destination) => { const responseArray = []; if ( - (!!destination.Config.listId || !!get(traitsInfo.properties, 'listId')) && - destination.Config.privateApiKey + (traitsInfo.properties?.listId || destination.Config?.listId) && + traitsInfo.properties?.subscribe === true ) { - const membersResponse = addUserToList(message, traitsInfo, LIST_CONF.MEMBERSHIP, destination); - responseArray.push(membersResponse); - if (get(traitsInfo.properties, 'subscribe') === true) { - const subscribeResponse = addUserToList( - message, - traitsInfo, - LIST_CONF.SUBSCRIBE, - destination, - ); - responseArray.push(subscribeResponse); - } + const subscribeResponse = subscribeUserToList( + message, + traitsInfo, + LIST_CONF.SUBSCRIBE, + destination, + ); + responseArray.push(subscribeResponse); + } else if (traitsInfo.properties?.listId || destination.Config?.listId) { + const subscribeResponse = subscribeUserToList( + message, + traitsInfo, + LIST_CONF.ADD_TO_LIST, + destination, + ); + responseArray.push(subscribeResponse); } - return responseArray; }; @@ -172,7 +168,7 @@ const createCustomerProperties = (message) => { module.exports = { isProfileExist, - addUserToList, - checkForMembersAndSubscribe, + subscribeUserToList, + checkForSubscribe, createCustomerProperties, }; diff --git a/src/v0/destinations/lemnisk/config.js b/src/v0/destinations/lemnisk/config.js new file mode 100644 index 0000000000..692bc774ad --- /dev/null +++ b/src/v0/destinations/lemnisk/config.js @@ -0,0 +1,22 @@ +const { getMappingConfig } = require("../../util"); + +const CONFIG_CATEGORIES = { + IDENTIFY: { type: "identify", name: "LEMNISKIdentifyConfig" }, + TRACK: { type: "track", name: "LEMNISKTrackConfig" }, + PAGE: { type: "page", name: "LEMNISKPageConfig" } +}; + +const DIAPI_CONFIG_CATEGORIES = { + TRACK: { type: "track", name: "LEMNISKDIAPITrackConfig" } +}; +const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); +const DIAPI_MAPPING_CONFIG = getMappingConfig( + DIAPI_CONFIG_CATEGORIES, + __dirname +); +module.exports = { + CONFIG_CATEGORIES, + MAPPING_CONFIG, + DIAPI_MAPPING_CONFIG, + DIAPI_CONFIG_CATEGORIES +}; diff --git a/src/v0/destinations/lemnisk/data/LEMNISKDIAPITrackConfig.json b/src/v0/destinations/lemnisk/data/LEMNISKDIAPITrackConfig.json new file mode 100644 index 0000000000..e58a430642 --- /dev/null +++ b/src/v0/destinations/lemnisk/data/LEMNISKDIAPITrackConfig.json @@ -0,0 +1,26 @@ +[ + { + "destKey": "properties", + "sourceKeys": "properties", + "required": true + }, + { + "destKey": "userId", + "sourceKeys": [ + "userId", + "anonymousId" + ], + "required": true + }, + { + "destKey": "eventname", + "sourceKeys": "event", + "required": false + }, + { + "destKey": "email", + "sourceKeys": "emailOnly", + "sourceFromGenericMap": true, + "required": false + } +] \ No newline at end of file diff --git a/src/v0/destinations/lemnisk/data/LEMNISKIdentifyConfig.json b/src/v0/destinations/lemnisk/data/LEMNISKIdentifyConfig.json new file mode 100644 index 0000000000..5ff700ba6c --- /dev/null +++ b/src/v0/destinations/lemnisk/data/LEMNISKIdentifyConfig.json @@ -0,0 +1,41 @@ +[ + { + "destKey": "type", + "sourceKeys": "type", + "required": true + }, + { + "destKey": "context", + "sourceKeys": "context", + "required": true + }, + { + "destKey": "customerProperties", + "sourceKeys": "traits", + "sourceFromGenericMap": true, + "required": true + }, + { + "destKey": "id", + "sourceKeys": "userId", + "sourceFromGenericMap": true, + "required": true + }, + { + "destKey": "userId", + "sourceKeys": "userId", + "sourceFromGenericMap": true, + "required": true + }, + { + "destKey": "messageId", + "sourceKeys": "messageId", + "required": true + }, + { + "destKey": "originalTimestamp", + "sourceKeys": "timestamp", + "sourceFromGenericMap": true, + "required": true + } +] diff --git a/src/v0/destinations/lemnisk/data/LEMNISKPageConfig.json b/src/v0/destinations/lemnisk/data/LEMNISKPageConfig.json new file mode 100644 index 0000000000..181873be0d --- /dev/null +++ b/src/v0/destinations/lemnisk/data/LEMNISKPageConfig.json @@ -0,0 +1,44 @@ +[ + { + "destKey": "type", + "sourceKeys": "type", + "required": true + }, + { + "destKey": "context", + "sourceKeys": "context", + "required": true + }, + { + "destKey": "messageId", + "sourceKeys": "messageId", + "required": true + }, + { + "destKey": "properties", + "sourceKeys": "properties", + "required": true + }, + { + "destKey": "id", + "sourceKeys": ["userId","anonymousId"], + "required": true + }, + { + "destKey": "userId", + "sourceKeys": "userId", + "sourceFromGenericMap": true, + "required": true + }, + { + "destKey": "originalTimestamp", + "sourceKeys": "timestamp", + "sourceFromGenericMap": true, + "required": true + }, + { + "destKey": "name", + "sourceKeys": "name", + "required": true + } +] \ No newline at end of file diff --git a/src/v0/destinations/lemnisk/data/LEMNISKTrackConfig.json b/src/v0/destinations/lemnisk/data/LEMNISKTrackConfig.json new file mode 100644 index 0000000000..c0b15c2833 --- /dev/null +++ b/src/v0/destinations/lemnisk/data/LEMNISKTrackConfig.json @@ -0,0 +1,47 @@ +[ + { + "destKey": "type", + "sourceKeys": "type", + "required": true + }, + { + "destKey": "context", + "sourceKeys": "context", + "required": true, + "metadata": { + "defaultValue": {} + } + }, + { + "destKey": "properties", + "sourceKeys": "properties", + "required": true + }, + { + "destKey": "event", + "sourceKeys": "event", + "required": true + }, + { + "destKey": "id", + "sourceKeys": ["userId","anonymousId"], + "required": true + }, + { + "destKey": "userId", + "sourceKeys": "userId", + "sourceFromGenericMap": true, + "required": true + }, + { + "destKey": "messageId", + "sourceKeys": "messageId", + "required": true + }, + { + "destKey": "originalTimestamp", + "sourceKeys": "timestamp", + "sourceFromGenericMap": true, + "required": true + } +] diff --git a/src/v0/destinations/lemnisk/transform.js b/src/v0/destinations/lemnisk/transform.js new file mode 100644 index 0000000000..eb0ae1e788 --- /dev/null +++ b/src/v0/destinations/lemnisk/transform.js @@ -0,0 +1,131 @@ +const { EventType } = require("../../../constants"); +const { + CONFIG_CATEGORIES, + MAPPING_CONFIG, + DIAPI_CONFIG_CATEGORIES, + DIAPI_MAPPING_CONFIG +} = require("./config"); +const { + constructPayload, + defaultPostRequestConfig, + removeUndefinedAndNullValues, + defaultRequestConfig, + simpleProcessRouterDest, + isDefinedAndNotNullAndNotEmpty +} = require("../../util"); +const { fetchPlatform } = require("./utils"); +const { + ConfigurationError, + TransformationError, + InstrumentationError +} = require("../../util/errorTypes"); + +const responseBuilder = (message, category, destination, platform) => { + let payload; + const { Config } = destination; + const response = defaultRequestConfig(); + response.method = defaultPostRequestConfig.requestMethod; + if (platform === "pl") { + const { plWriteKey, pl } = Config; + if (!isDefinedAndNotNullAndNotEmpty(plWriteKey) || !isDefinedAndNotNullAndNotEmpty(pl)) { + throw new ConfigurationError( + "Configuration for Web Mode requires write key and region url" + ); + } + payload = constructPayload(message, MAPPING_CONFIG[category.name]); + payload.writeKey = plWriteKey; + payload.context.userAgent = { + ua: payload.context.userAgent + }; + response.endpoint = pl; + response.headers = { + "Content-Type": "application/json" + }; + } else { + // diapi + const { diapi, apiKey, passKey, diapiWriteKey, srcId } = Config; + if ( + !isDefinedAndNotNullAndNotEmpty(diapi) || + !isDefinedAndNotNullAndNotEmpty(apiKey) || + !isDefinedAndNotNullAndNotEmpty(passKey) + ) { + throw new ConfigurationError( + "Configuration for Server Mode requires Api key, Pass Key and region url" + ); + } + payload = constructPayload(message, DIAPI_MAPPING_CONFIG[category.name]); + if (diapiWriteKey !== "") { + payload.WriteKey = diapiWriteKey; + } + if (srcId !== "") { + payload.srcid = srcId; + } + response.endpoint = diapi; + response.headers = { + "Content-Type": "application/json", + "x-api-passKey": passKey, + "x-api-key": apiKey + }; + } + response.userId = message.anonymousId || message.userId; + if (payload) { + payload.type = category.type; + response.body.JSON = removeUndefinedAndNullValues(payload); + } else { + // fail-safety for developer error + throw new TransformationError("Payload could not be constructed"); + } + return response; +}; + +const process = event => { + const { message, destination } = event; + if (!message.type) { + throw new InstrumentationError("Event type is required"); + } + + const messageType = message.type.toLowerCase(); + let response; + let category; + const platform = fetchPlatform(destination); + if (platform === "pl") { + switch (messageType) { + case EventType.PAGE: + category = CONFIG_CATEGORIES.PAGE; + response = responseBuilder(message, category, destination, platform); + break; + case EventType.IDENTIFY: + category = CONFIG_CATEGORIES.IDENTIFY; + response = responseBuilder(message, category, destination, platform); + break; + case EventType.TRACK: + category = CONFIG_CATEGORIES.TRACK; + response = responseBuilder(message, category, destination, platform); + break; + default: + throw new InstrumentationError( + `Event type ${messageType} is not supported in Web Cloud Mode` + ); + } + } + if (platform === "diapi") { + switch (messageType) { + case EventType.TRACK: + category = DIAPI_CONFIG_CATEGORIES.TRACK; + response = responseBuilder(message, category, destination, platform); + break; + default: + throw new InstrumentationError( + `Event type ${messageType} is not supported in Server Cloud Mode` + ); + } + } + return response; +}; + +const processRouterDest = async (inputs, reqMetadata) => { + const respList = await simpleProcessRouterDest(inputs, process, reqMetadata); + return respList; +}; + +module.exports = { process, processRouterDest }; diff --git a/src/v0/destinations/lemnisk/utils.js b/src/v0/destinations/lemnisk/utils.js new file mode 100644 index 0000000000..bf7311b614 --- /dev/null +++ b/src/v0/destinations/lemnisk/utils.js @@ -0,0 +1,19 @@ +const { ConfigurationError } = require("../../util/errorTypes"); + +/** + * Fetches the platform type from the destination Config + * @param {*} destination + * @returns platform type used + */ +const fetchPlatform = destination => { + const { cloudMode } = destination.Config; + if (cloudMode === "web") { + return "pl"; + } + if (cloudMode === "server") { + return "diapi"; + } + throw new ConfigurationError("Payload contains invalid configuration"); +}; + +module.exports = { fetchPlatform }; diff --git a/src/v0/destinations/mailchimp/config.js b/src/v0/destinations/mailchimp/config.js index 37894d7364..fa521a42c7 100644 --- a/src/v0/destinations/mailchimp/config.js +++ b/src/v0/destinations/mailchimp/config.js @@ -13,6 +13,7 @@ const VALID_STATUSES = ['subscribed', 'unsubscribed', 'cleaned', 'pending', 'tra const CONFIG_CATEGORIES = { IDENTIFY: { name: 'mailchimpMergeFieldConfig' }, MERGE_ADDRESS: { name: 'mailchimpMergeAddressConfig' }, + TRACK: { name: 'mailchimpTrackEventConfig' }, }; const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); @@ -22,4 +23,5 @@ module.exports = { VALID_STATUSES, MERGE_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.IDENTIFY.name], MERGE_ADDRESS: MAPPING_CONFIG[CONFIG_CATEGORIES.MERGE_ADDRESS.name], + TRACK_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.TRACK.name], }; diff --git a/src/v0/destinations/mailchimp/data/mailchimpTrackEventConfig.json b/src/v0/destinations/mailchimp/data/mailchimpTrackEventConfig.json new file mode 100644 index 0000000000..c2747eccbd --- /dev/null +++ b/src/v0/destinations/mailchimp/data/mailchimpTrackEventConfig.json @@ -0,0 +1,24 @@ +[ + { + "destKey": "name", + "sourceKeys": "event", + "required": true + }, + { + "destKey": "properties", + "sourceKeys": "properties", + "required": false + }, + { + "destKey": "occurred_at", + "sourceKeys": "timestamp", + "sourceFromGenericMap": true, + "required": false + }, + { + "destKey": "is_syncing", + "sourceKeys": "properties.isSyncing", + "sourceFromGenericMap": false, + "required": false + } +] diff --git a/src/v0/destinations/mailchimp/transform.js b/src/v0/destinations/mailchimp/transform.js index 77bda5e647..b2b55aa0ff 100644 --- a/src/v0/destinations/mailchimp/transform.js +++ b/src/v0/destinations/mailchimp/transform.js @@ -3,6 +3,10 @@ const { defaultPutRequestConfig, handleRtTfSingleEventError, checkInvalidRtTfEvents, + constructPayload, + defaultPostRequestConfig, + isDefinedAndNotNull, + formatTimeStamp, } = require('../../util'); const { EventType } = require('../../../constants'); const { @@ -15,15 +19,19 @@ const { mailChimpSubscriptionEndpoint, getAudienceId, generateBatchedPaylaodForArray, + mailchimpEventsEndpoint, + stringifyPropertiesValues, } = require('./utils'); -const { MAX_BATCH_SIZE, VALID_STATUSES } = require('./config'); +const { MAX_BATCH_SIZE, VALID_STATUSES, TRACK_CONFIG } = require('./config'); const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); -const responseBuilderSimple = (finalPayload, email, Config, audienceId) => { - const { datacenterId, apiKey } = Config; +const responseBuilderSimple = (finalPayload, endpoint, Config, audienceId) => { + const { apiKey } = Config; const response = defaultRequestConfig(); - response.endpoint = mailChimpSubscriptionEndpoint(datacenterId, audienceId, email); - response.method = defaultPutRequestConfig.requestMethod; + response.endpoint = endpoint; + response.method = endpoint.includes('events') + ? defaultPostRequestConfig.requestMethod + : defaultPutRequestConfig.requestMethod; response.body.JSON = finalPayload; const basicAuth = Buffer.from(`apiKey:${apiKey}`).toString('base64'); if (finalPayload.status && !VALID_STATUSES.includes(finalPayload.status)) { @@ -41,14 +49,39 @@ const responseBuilderSimple = (finalPayload, email, Config, audienceId) => { }; }; +const trackResponseBuilder = (message, { Config }) => { + const { datacenterId } = Config; + const audienceId = getAudienceId(message, Config); + const email = getFieldValueFromMessage(message, 'email'); + if (!email) { + throw new InstrumentationError('Email is required for track'); + } + const endpoint = mailchimpEventsEndpoint(datacenterId, audienceId, email); + const processedPayload = constructPayload(message, TRACK_CONFIG); + if (processedPayload?.properties) { + processedPayload.properties = stringifyPropertiesValues(processedPayload.properties); + } + processedPayload.name = processedPayload.name.trim().replace(/\s+/g, '_'); + processedPayload.occurred_at = formatTimeStamp( + processedPayload.occurred_at, + 'YYYY-MM-DDTHH:mm:ssZ', + ); + if (isDefinedAndNotNull(processedPayload.properties?.isSyncing)) { + delete processedPayload.properties.isSyncing; + } + return responseBuilderSimple(processedPayload, endpoint, Config, audienceId); +}; + const identifyResponseBuilder = async (message, { Config }) => { + const { datacenterId } = Config; const email = getFieldValueFromMessage(message, 'email'); if (!email) { throw new InstrumentationError('Email is required for identify'); } const audienceId = getAudienceId(message, Config); + const endpoint = mailChimpSubscriptionEndpoint(datacenterId, audienceId, email); const processedPayload = await processPayload(message, Config, audienceId); - return responseBuilderSimple(processedPayload, email, Config, audienceId); + return responseBuilderSimple(processedPayload, endpoint, Config, audienceId); }; const process = async (event) => { @@ -77,6 +110,9 @@ const process = async (event) => { case EventType.IDENTIFY: response = await identifyResponseBuilder(message, destination); break; + case EventType.TRACK: + response = trackResponseBuilder(message, destination); + break; default: throw new InstrumentationError(`message type ${messageType} is not supported`); } @@ -109,6 +145,15 @@ const batchEvents = (successRespList) => { return batchedResponseList; }; +// This function separates identify and track call in chunks +const getEventChunks = (event, identifyRespList, trackRespList) => { + if (event.message.endpoint.includes('events')) { + trackRespList.push(event); + } else { + identifyRespList.push(event); + } +}; + const processRouterDest = async (inputs, reqMetadata) => { const errorRespEvents = checkInvalidRtTfEvents(inputs); if (errorRespEvents.length > 0) { @@ -116,26 +161,30 @@ const processRouterDest = async (inputs, reqMetadata) => { } let batchResponseList = []; const batchErrorRespList = []; - const successRespList = []; + const identifyRespList = []; + const trackRespList = []; const { destination } = inputs[0]; await Promise.all( inputs.map(async (event) => { try { if (event.message.statusCode) { // already transformed event - successRespList.push({ - message: event.message, - metadata: event.metadata, - destination, - }); + getEventChunks( + { message: event.message, metadata: event.metadata, destination }, + identifyRespList, + trackRespList, + ); } else { // if not transformed - const transformedPayload = { - message: await process(event), - metadata: event.metadata, - destination, - }; - successRespList.push(transformedPayload); + getEventChunks( + { + message: await process(event), + metadata: event.metadata, + destination, + }, + identifyRespList, + trackRespList, + ); } } catch (error) { const errRespEvent = handleRtTfSingleEventError(event, error, reqMetadata); @@ -143,9 +192,15 @@ const processRouterDest = async (inputs, reqMetadata) => { } }), ); - if (successRespList.length > 0) { - batchResponseList = batchEvents(successRespList); + let batchedIdentifyResponseList = []; + if (identifyRespList.length > 0) { + batchedIdentifyResponseList = batchEvents(identifyRespList); } + const trackResponseList = []; + trackRespList.forEach((resp) => { + trackResponseList.push(getSuccessRespEvents(resp.message, [resp.metadata], resp.destination)); + }); + batchResponseList = batchResponseList.concat(batchedIdentifyResponseList, trackResponseList); return [...batchResponseList, ...batchErrorRespList]; }; diff --git a/src/v0/destinations/mailchimp/utils.js b/src/v0/destinations/mailchimp/utils.js index 834c2da5c4..d5abb11023 100644 --- a/src/v0/destinations/mailchimp/utils.js +++ b/src/v0/destinations/mailchimp/utils.js @@ -61,6 +61,9 @@ const getMailChimpBaseEndpoint = (datacenterId, audienceId) => const mailChimpSubscriptionEndpoint = (datacenterId, audienceId, email) => `${getMailChimpBaseEndpoint(datacenterId, audienceId)}/members/${md5(email)}`; +const mailchimpEventsEndpoint = (datacenterId, audienceId, email) => + `${getMailChimpBaseEndpoint(datacenterId, audienceId)}/members/${md5(email)}/events`; + /** * Returns common endpoint for mailchimp * If enableMergeFields option is not present in config, we will set it to false @@ -84,6 +87,21 @@ const getBatchEndpoint = (destConfig, audienceId) => { return BATCH_ENDPOINT; }; +/** + * Returns the properties object with stringified values of properties[key] as mailchimp only supports string as the values for properties[key] + * @param {*} properties + * @returns + */ +const stringifyPropertiesValues = (properties) => { + const updatedProperties = properties; + const keys = Object.keys(updatedProperties); + keys.forEach((key) => { + if (typeof updatedProperties[key] !== 'string') + updatedProperties[key] = JSON.stringify(updatedProperties[key]); + }); + return updatedProperties; +}; + /** * Dynamically returns audienceId from message or Config * @param {*} message @@ -372,5 +390,7 @@ module.exports = { getAudienceId, generateBatchedPaylaodForArray, mailChimpSubscriptionEndpoint, + mailchimpEventsEndpoint, processPayload, + stringifyPropertiesValues, }; diff --git a/src/v0/destinations/mp/transform.js b/src/v0/destinations/mp/transform.js index bbf0b35b22..9364337eae 100644 --- a/src/v0/destinations/mp/transform.js +++ b/src/v0/destinations/mp/transform.js @@ -310,6 +310,12 @@ const processGroupEvents = (message, type, destination) => { }; const processSingleMessage = async (message, destination) => { + if (message.userId) { + message.userId = String(message.userId); + } + if (message.anonymousId) { + message.anonymousId = String(message.anonymousId); + } if (!message.type) { throw new InstrumentationError('Event type is required'); } diff --git a/src/v0/destinations/optimizely_fullstack/config.js b/src/v0/destinations/optimizely_fullstack/config.js new file mode 100644 index 0000000000..662db6ba9d --- /dev/null +++ b/src/v0/destinations/optimizely_fullstack/config.js @@ -0,0 +1,20 @@ +const { getMappingConfig } = require('../../util'); + +const getTrackEndPoint = (baseUrl, event) => + `${baseUrl}/v1/track?eventKey=${encodeURIComponent(event)}`; + +const CONFIG_CATEGORIES = { + TRACK: { + name: 'OptimizelyFullStackTrackConfig', + type: 'track', + endpoint: '/v1/track', + }, +}; + +const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); + +module.exports = { + CONFIG_CATEGORIES, + MAPPING_CONFIG, + getTrackEndPoint, +}; diff --git a/src/v0/destinations/optimizely_fullstack/data/OptimizelyFullStackTrackConfig.json b/src/v0/destinations/optimizely_fullstack/data/OptimizelyFullStackTrackConfig.json new file mode 100644 index 0000000000..d3ae45d7dc --- /dev/null +++ b/src/v0/destinations/optimizely_fullstack/data/OptimizelyFullStackTrackConfig.json @@ -0,0 +1,11 @@ +[ + { + "destKey": "userAttributes", + "sourceKeys": "traits", + "sourceFromGenericMap": true + }, + { + "destKey": "eventTags", + "sourceKeys": "properties" + } +] diff --git a/src/v0/destinations/optimizely_fullstack/transform.js b/src/v0/destinations/optimizely_fullstack/transform.js new file mode 100644 index 0000000000..20e1faae29 --- /dev/null +++ b/src/v0/destinations/optimizely_fullstack/transform.js @@ -0,0 +1,107 @@ +const { EventType } = require('../../../constants'); +const { + defaultRequestConfig, + simpleProcessRouterDest, + constructPayload, + removeUndefinedAndNullValues, + defaultPostRequestConfig, +} = require('../../util'); +const { validateConfig, validateEvent } = require('./util'); +const { CONFIG_CATEGORIES, MAPPING_CONFIG, getTrackEndPoint } = require('./config'); +const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); + +const responseBuilder = (payload, endpoint, destination) => { + if (payload) { + const response = defaultRequestConfig(); + const { sdkKey } = destination.Config; + response.endpoint = endpoint; + response.headers = { + 'Content-Type': 'application/json', + 'X-Optimizely-SDK-Key': sdkKey, + }; + response.method = defaultPostRequestConfig.requestMethod; + response.body.JSON = removeUndefinedAndNullValues(payload); + return response; + } + // fail-safety for developer error + throw new TransformationError('Something went wrong while constructing the payload'); +}; + +// ref:- https://docs.developers.optimizely.com/experimentation/v3.1.0-full-stack/reference/trackevent +const trackResponseBuilder = (message, destination) => { + const { event, userId, anonymousId } = message; + if (!event) { + throw new InstrumentationError('Event name is required'); + } + + validateEvent(message, destination); + const { baseUrl, trackKnownUsers } = destination.Config; + const endpoint = getTrackEndPoint(baseUrl, event); + const { name } = CONFIG_CATEGORIES.TRACK; + const payload = constructPayload(message, MAPPING_CONFIG[name]); + + payload.userId = anonymousId; + if (trackKnownUsers) { + payload.userId = userId; + } + return responseBuilder(payload, endpoint, destination); +}; + +const pageResponseBuilder = (message, destination) => { + const { trackCategorizedPages, trackNamedPages } = destination.Config; + const newMessage = { ...message }; + const returnValue = []; + + if (message.category && trackCategorizedPages) { + newMessage.event = `Viewed ${message.category} page`; + returnValue.push(trackResponseBuilder(newMessage, destination)); + } + if (message.name && trackNamedPages) { + newMessage.event = `Viewed ${message.name} page`; + returnValue.push(trackResponseBuilder(newMessage, destination)); + } + + return returnValue; +}; + +const screenResponseBuilder = (message, destination) => { + const newMessage = { ...message }; + newMessage.event = 'Viewed screen'; + if (message.name) { + newMessage.event = `Viewed ${message.name} screen`; + } + return trackResponseBuilder(newMessage, destination); +}; + +const processEvent = (message, destination) => { + validateConfig(destination); + if (!message.type) { + throw new InstrumentationError('Event type is required'); + } + + const messageType = message.type.toLowerCase(); + let response; + switch (messageType) { + case EventType.TRACK: + response = trackResponseBuilder(message, destination); + break; + case EventType.PAGE: + response = pageResponseBuilder(message, destination); + break; + case EventType.SCREEN: + response = screenResponseBuilder(message, destination); + break; + default: + throw new InstrumentationError(`Event type "${messageType}" is not supported`); + } + return response; +}; + +const process = (event) => processEvent(event.message, event.destination); + +const processRouterDest = async (inputs, reqMetadata) => { + const respList = await simpleProcessRouterDest(inputs, process, reqMetadata); + return respList; +}; + +module.exports = { process, processRouterDest }; diff --git a/src/v0/destinations/optimizely_fullstack/util.js b/src/v0/destinations/optimizely_fullstack/util.js new file mode 100644 index 0000000000..4fa8c3a905 --- /dev/null +++ b/src/v0/destinations/optimizely_fullstack/util.js @@ -0,0 +1,30 @@ +const { ConfigurationError } = require('../../util/errorTypes'); + +const validateConfig = (destination) => { + if (!destination.Config.sdkKey) { + throw new ConfigurationError('SDK key is required'); + } + + if (!destination.Config.baseUrl) { + throw new ConfigurationError('Base url is required'); + } +}; + +const validateEvent = (message, destination) => { + const { userId, anonymousId } = message; + const { trackKnownUsers } = destination.Config; + + if (trackKnownUsers && !userId) { + throw new ConfigurationError( + 'RudderStack will only track users associated with a userId when the trackKnownUsers setting is enabled', + ); + } + + if (!trackKnownUsers && !anonymousId) { + throw new ConfigurationError( + 'AnonymousId is required when trackKnownUsers setting is disabled', + ); + } +}; + +module.exports = { validateConfig, validateEvent }; diff --git a/src/v0/destinations/pinterest_tag/utils.js b/src/v0/destinations/pinterest_tag/utils.js index cc520283b6..28ad27183c 100644 --- a/src/v0/destinations/pinterest_tag/utils.js +++ b/src/v0/destinations/pinterest_tag/utils.js @@ -262,7 +262,7 @@ const processHashedUserPayload = (userPayload, message) => { }); // multiKeyMap will works on only specific values like m, male, MALE, f, F, Female // if hashed data is sent from the user, it is directly set over here - processedHashedUserPayload.ge = [message.traits?.gender || message.context?.traits?.gender]; + processedHashedUserPayload.ge = [message.traits?.gender || message.context?.traits?.gender || null]; return processedHashedUserPayload; }; diff --git a/src/v0/destinations/rockerbox/config.js b/src/v0/destinations/rockerbox/config.js index e3efb94751..2fa3933b97 100644 --- a/src/v0/destinations/rockerbox/config.js +++ b/src/v0/destinations/rockerbox/config.js @@ -13,8 +13,26 @@ const CONFIG_CATEGORIES = { const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); +const ROCKERBOX_DEFINED_PROPERTIES = [ + 'userId', + 'email', + 'phone', + 'timestamp', + 'revenue', + 'value', + 'price', + 'total', + 'orderId', + 'order_id', + 'in_store', + 'salesforce', + 'countryCode', + 'listingId', +]; + module.exports = { BASE_ENDPOINT, CONFIG_CATEGORIES, MAPPING_CONFIG, + ROCKERBOX_DEFINED_PROPERTIES, }; diff --git a/src/v0/destinations/rockerbox/transform.js b/src/v0/destinations/rockerbox/transform.js index 31f826095e..c02db32111 100644 --- a/src/v0/destinations/rockerbox/transform.js +++ b/src/v0/destinations/rockerbox/transform.js @@ -5,9 +5,10 @@ const { constructPayload, simpleProcessRouterDest, getHashFromArray, + extractCustomFields, } = require('../../util'); const { EventType } = require('../../../constants'); -const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); +const { CONFIG_CATEGORIES, MAPPING_CONFIG, ROCKERBOX_DEFINED_PROPERTIES } = require('./config'); const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const responseBuilderSimple = (message, category, destination) => { @@ -25,6 +26,7 @@ const responseBuilderSimple = (message, category, destination) => { } else { payload.action = eventsHashMap[message.event.toLowerCase()]; } + extractCustomFields(message, payload, ['properties'], ROCKERBOX_DEFINED_PROPERTIES); const response = defaultRequestConfig(); response.endpoint = category.endpoint; // the endpoint has advertiser = ADVERTISER_ID in the query params diff --git a/src/v0/destinations/rs/transform.js b/src/v0/destinations/rs/transform.js index 97d975afe1..f051ff49d5 100644 --- a/src/v0/destinations/rs/transform.js +++ b/src/v0/destinations/rs/transform.js @@ -13,7 +13,7 @@ function getDataTypeOverride(key, val, options, jsonKey = false) { return 'json'; } - if (options.rsAlterStringToText === 'true' && val) { + if (val) { const stringifiedVal = Array.isArray(val) ? JSON.stringify(val) : val; if (stringifiedVal.length > RSStringLimit) { return 'text'; @@ -26,7 +26,6 @@ function process(event) { const whSchemaVersion = event.request.query.whSchemaVersion || 'v1'; const whStoreEvent = event.destination.Config.storeFullEvent === true; const destJsonPaths = event.destination?.Config?.jsonPaths || ''; - const rsAlterStringToText = event.request.query.rsAlterStringToText || 'false'; const provider = redshift; return processSingleMessage(event.message, { metadata: event.metadata, @@ -34,7 +33,6 @@ function process(event) { whStoreEvent, getDataTypeOverride, provider, - rsAlterStringToText, sourceCategory: event.metadata ? event.metadata.sourceCategory : null, destJsonPaths, }); diff --git a/src/v0/destinations/salesforce/transform.js b/src/v0/destinations/salesforce/transform.js index 74cef1facc..d40bc485f9 100644 --- a/src/v0/destinations/salesforce/transform.js +++ b/src/v0/destinations/salesforce/transform.js @@ -114,7 +114,7 @@ async function getSaleforceIdForRecord( if (processedsfSearchResponse.status !== 200) { salesforceResponseHandler( processedsfSearchResponse, - `SALESFORCE SEARCH BY ID: ${JSON.stringify(processedsfSearchResponse.response)}`, + `:- SALESFORCE SEARCH BY ID`, destination.ID, ); } @@ -212,7 +212,7 @@ async function getSalesforceIdFromPayload(message, authorizationData, destinatio if (processedLeadQueryResponse.status !== 200) { salesforceResponseHandler( processedLeadQueryResponse, - `During Lead Query: ${JSON.stringify(processedLeadQueryResponse.response)}`, + `:- during Lead Query`, destination.ID, ); } diff --git a/src/v0/destinations/salesforce/utils.js b/src/v0/destinations/salesforce/utils.js index 6c723b62a2..7eafe1376c 100644 --- a/src/v0/destinations/salesforce/utils.js +++ b/src/v0/destinations/salesforce/utils.js @@ -25,27 +25,31 @@ const salesforceResponseHandler = (destResponse, sourceMessage, authKey) => { // if the response from destination is not a success case build an explicit error if (!isHttpStatusSuccess(status) && status >= 400) { const matchErrorCode = (errorCode) => - response && Array.isArray(response) && response.some((resp) => resp.errorCode === errorCode); + response && Array.isArray(response) && response.some((resp) => resp?.errorCode === errorCode); if (status === 401 && authKey && matchErrorCode('INVALID_SESSION_ID')) { // checking for invalid/expired token errors and evicting cache in that case // rudderJobMetadata contains some destination info which is being used to evict the cache ACCESS_TOKEN_CACHE.del(authKey); throw new RetryableError( - `${DESTINATION} Request Failed - due to ${response[0].message}, (Retryable).${sourceMessage}`, + `${DESTINATION} Request Failed - due to "INVALID_SESSION_ID", (Retryable) ${sourceMessage}`, 500, destResponse, ); } else if (status === 403 && matchErrorCode('REQUEST_LIMIT_EXCEEDED')) { // If the error code is REQUEST_LIMIT_EXCEEDED, you’ve exceeded API request limits in your org. throw new ThrottledError( - `${DESTINATION} Request Failed - due to ${response[0].message}, (Throttled).${sourceMessage}`, + `${DESTINATION} Request Failed - due to "REQUEST_LIMIT_EXCEEDED", (Throttled) ${sourceMessage}`, destResponse, ); - } else if (status === 503) { + } else if (status === 503 || status === 500) { // The salesforce server is unavailable to handle the request. Typically this occurs if the server is down // for maintenance or is currently overloaded. throw new RetryableError( - `${DESTINATION} Request Failed - due to ${response[0].message}, (Retryable).${sourceMessage}`, + `${DESTINATION} Request Failed - due to "${ + response && Array.isArray(response) && response[0]?.message?.length > 0 + ? response[0].message + : JSON.stringify(response) + }", (Retryable) ${sourceMessage}`, 500, destResponse, ); @@ -55,9 +59,11 @@ const salesforceResponseHandler = (destResponse, sourceMessage, authKey) => { if (response && Array.isArray(response)) { errorMessage = response[0].message; } - + // aborting for all other error codes throw new AbortedError( - `${DESTINATION} Request Failed: ${status} due to ${errorMessage}, (Aborted). ${sourceMessage}`, + `${DESTINATION} Request Failed: "${status}" due to "${ + errorMessage || JSON.stringify(response) + }", (Aborted) ${sourceMessage}`, 400, destResponse, ); @@ -91,15 +97,17 @@ const getAccessToken = async (destination) => { const { httpResponse, processedResponse } = await handleHttpRequest('post', authUrl, {}); // If the request fails, throwing error. if (!httpResponse.success) { - const { error } = httpResponse.response.response.data; + salesforceResponseHandler(processedResponse, `:- authentication failed during fetching access token.`, accessTokenKey); + } + const token = httpResponse.response.data; + // If the httpResponse.success is true it will not come, It's an extra security for developer's. + if (!token.access_token || !token.instance_url) { salesforceResponseHandler( - processedResponse.response, - `access token could not be generated due to ${error}`, - undefined, + processedResponse, + `:- authentication failed could not retrieve authorization token.`, accessTokenKey, ); } - const token = httpResponse.response.data; return { token: `Bearer ${token.access_token}`, instanceUrl: token.instance_url, diff --git a/src/v0/destinations/sendgrid/util.js b/src/v0/destinations/sendgrid/util.js index 05079f6dda..0309e80e07 100644 --- a/src/v0/destinations/sendgrid/util.js +++ b/src/v0/destinations/sendgrid/util.js @@ -480,15 +480,17 @@ const getCustomFields = async (message, destination) => { return name; }); - fields.forEach((field) => { - if (payload[field]) { - const customFieldName = fieldsMapping[field]; - if (customFieldNamesArray.includes(customFieldName)) { - const customFieldId = customFieldNameToIdMapping[customFieldName]; - customFields[customFieldId] = payload[field]; + if (!isEmptyObject(payload)) { + fields.forEach((field) => { + if (payload[field]) { + const customFieldName = fieldsMapping[field]; + if (customFieldNamesArray.includes(customFieldName)) { + const customFieldId = customFieldNameToIdMapping[customFieldName]; + customFields[customFieldId] = payload[field]; + } } - } - }); + }); + } } return customFields; }; diff --git a/src/v0/destinations/singular/transform.js b/src/v0/destinations/singular/transform.js index c8af708d6e..749debb0b0 100644 --- a/src/v0/destinations/singular/transform.js +++ b/src/v0/destinations/singular/transform.js @@ -23,13 +23,15 @@ const responseBuilderSimple = (message, { Config }) => { const { eventAttributes, payload } = platformWisePayloadGenerator(message, sessionEvent); const endpoint = sessionEvent ? `${BASE_URL}/launch` : `${BASE_URL}/evt`; - if (!sessionEvent) { - const { products } = message.properties; - // If we have an event where we have an array of Products, example Order Completed - // We will convert the event to revenue events - if (products && Array.isArray(products)) { - return generateRevenuePayloadArray(products, payload, Config, eventAttributes); - } + // If we have an event where we have an array of Products, example Order Completed + // We will convert the event to revenue events + if (!sessionEvent && Array.isArray(message?.properties?.products)) { + return generateRevenuePayloadArray( + message.properties.products, + payload, + Config, + eventAttributes, + ); } const response = { diff --git a/src/v0/destinations/snapchat_conversion/util.js b/src/v0/destinations/snapchat_conversion/util.js index 467fb89ed6..875097493c 100644 --- a/src/v0/destinations/snapchat_conversion/util.js +++ b/src/v0/destinations/snapchat_conversion/util.js @@ -1,6 +1,6 @@ const get = require('get-value'); const sha256 = require('sha256'); -const { logger } = require('handlebars'); +const logger = require('../../../logger'); const { isDefinedAndNotNull, diff --git a/src/v0/destinations/webhook/utils.js b/src/v0/destinations/webhook/utils.js new file mode 100644 index 0000000000..0e3fdb3994 --- /dev/null +++ b/src/v0/destinations/webhook/utils.js @@ -0,0 +1,13 @@ +const { EventType } = require("../../../constants"); +const { getFieldValueFromMessage, flattenJson } = require("../../util"); + +const getPropertyParams = message => { + if (message.type === EventType.IDENTIFY) { + return flattenJson(getFieldValueFromMessage(message, "traits")); + } + return flattenJson(message.properties); +}; + +module.exports = { + getPropertyParams +}; diff --git a/src/v0/destinations/zendesk/transform.js b/src/v0/destinations/zendesk/transform.js index b84e991e7a..e394ee304b 100644 --- a/src/v0/destinations/zendesk/transform.js +++ b/src/v0/destinations/zendesk/transform.js @@ -363,7 +363,7 @@ async function createOrganization(message, category, headers, destinationConfig, const payload = constructPayload(message, mappingJson); const sourceKeys = defaultFields[ConfigCategory.GROUP.organizationFieldsJson]; - if (payload.organization.external_id) { + if (payload?.organization?.external_id) { set(payload, 'organization.organization_fields.id', payload.organization.external_id); } const traitKeys = Object.keys(message.traits); diff --git a/src/v0/sources/moengage/transform.js b/src/v0/sources/moengage/transform.js new file mode 100644 index 0000000000..280a745fd1 --- /dev/null +++ b/src/v0/sources/moengage/transform.js @@ -0,0 +1,8 @@ +function process(events) { + if (events.batch) { + return events.batch; + } + return events; +} + +exports.process = process; \ No newline at end of file diff --git a/src/v0/sources/shopify/transform.js b/src/v0/sources/shopify/transform.js index 593a618279..cdc47a6439 100644 --- a/src/v0/sources/shopify/transform.js +++ b/src/v0/sources/shopify/transform.js @@ -1,5 +1,6 @@ const _ = require('lodash'); const get = require('get-value'); +const stats = require('../../../util/stats'); const { getShopifyTopic, createPropertiesForEcomEvent, @@ -151,10 +152,42 @@ const processEvent = (inputEvent) => { version: '1.0.0', }); message.setProperty('context.topic', shopifyTopic); + + // attaching cart, checkout and order tokens in context object + message.setProperty(`context.cart_token`, event.cart_token); + message.setProperty(`context.checkout_token`, event.checkout_token); + if (shopifyTopic === 'orders_updated') { + message.setProperty(`context.order_token`, event.token); + } + message = removeUndefinedAndNullValues(message); + stats.increment('shopify_server_side_identifier_event', 1, { + writeKey: inputEvent.query_parameters?.writeKey?.[0], + timestamp: Date.now(), + }); return message; }; - -const process = (event) => processEvent(event); +const isIdentifierEvent = (event) => { + if (event?.event === 'rudderIdentifier') { + stats.increment('shopify_client_side_identifier_event', 1, { + writeKey: event.query_parameters?.writeKey?.[0], + timestamp: Date.now(), + }); + return true; + } + return false; +}; +const processIdentifierEvent = () => { + const result = { + outputToSource: { + body: Buffer.from('OK').toString('base64'), + contentType: 'text/plain', + }, + statusCode: 200, + }; + return result; +}; +const process = (event) => + isIdentifierEvent(event) ? processIdentifierEvent() : processEvent(event); exports.process = process; diff --git a/src/v0/util/errorTypes/index.js b/src/v0/util/errorTypes/index.js index fd93290c4e..70775a380d 100644 --- a/src/v0/util/errorTypes/index.js +++ b/src/v0/util/errorTypes/index.js @@ -12,6 +12,7 @@ const AbortedError = require('./abortedError'); const UnhandledStatusCodeError = require('./unhandledStatusCodeError'); const UnauthorizedError = require('./unauthorizedError'); const NetworkInstrumentationError = require('./networkInstrumentationError'); +const UnsupportedEventError = require('./unsupportedEventError'); module.exports = { BaseError, @@ -28,4 +29,5 @@ module.exports = { UnhandledStatusCodeError, UnauthorizedError, NetworkInstrumentationError, + UnsupportedEventError, }; diff --git a/src/v0/util/errorTypes/unsupportedEventError.js b/src/v0/util/errorTypes/unsupportedEventError.js new file mode 100644 index 0000000000..c2e965b620 --- /dev/null +++ b/src/v0/util/errorTypes/unsupportedEventError.js @@ -0,0 +1,14 @@ +const tags = require('../tags'); +const { BaseError } = require('./base'); + +class UnsupportedEventError extends BaseError { + constructor(message) { + const finalStatTags = { + [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.PLATFORM, + [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.UNSUPPORTED, + }; + super(message, 400, finalStatTags); + } +} + +module.exports = UnsupportedEventError; diff --git a/src/v0/util/index.js b/src/v0/util/index.js index ab813bfcdb..6069a07b44 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -23,6 +23,7 @@ const { BaseError, PlatformError, TransformationError, + OAuthSecretError, } = require('./errorTypes'); const { client: errNotificationClient } = require('../../util/errorNotifier'); // ======================================================================== @@ -742,7 +743,10 @@ const handleMetadataForValue = (value, metadata, destKey, integrationsObj = null formattedVal = formattedVal.replace('https://', '').replace('http://', ''); break; case 'domainUrlV2': { - const url = new URL(formattedVal); + const url = isValidUrl(formattedVal); + if (!url) { + throw new InstrumentationError(`Invalid URL: ${formattedVal}`); + } formattedVal = url.hostname.replace('www.', ''); break; } @@ -977,7 +981,7 @@ function getDestinationExternalID(message, type) { } if (Array.isArray(externalIdArray)) { - externalIdArray.forEach(extIdObj => { + externalIdArray.forEach((extIdObj) => { if (extIdObj.type === type) { destinationExternalId = extIdObj.id; } @@ -1666,8 +1670,10 @@ const validatePhoneWithCountryCode = (phone) => { * @returns */ const isHybridModeEnabled = (Config) => { - const { useNativeSDK, useNativeSDKToSend } = Config; - return useNativeSDK && !useNativeSDKToSend; + if (isDefinedAndNotNull(Config.useNativeSDK) && isDefinedAndNotNull(Config.useNativeSDKToSend)) { + return Config.useNativeSDK && !Config.useNativeSDKToSend; + } + return false; }; /** @@ -1677,6 +1683,48 @@ const isHybridModeEnabled = (Config) => { */ const getEventType = (message) => message?.type?.toLowerCase(); +// Set the user ID to an empty string for +// all the falsy values (including 0 and false) +// Otherwise, server panics while un-marshalling the response +// while expecting only strings. +const checkAndCorrectUserId = (statusCode, userId) => { + if (!userId) { + return ''; + } + if (statusCode !== 400 && userId) { + return `${userId}`; + } + return userId; +}; + +/** + * Get access token to be bound to the event req headers + * + * **Note**: + * - the schema that we'd get in `metadata.secret` can be different + * for different destinations + * - useful only for OAuth destinations + * + * @param {Object} metadata + * @param {string} accessTokenKey + * - represents the property name under which you have accessToken information in "metadata.secret" object + * - property paths like data.t.accessToken, some.prop.access_token, prop.accessToken are not supported + * @returns + * accesstoken information + * @example + * getAccessToken(metadata, "access_token") ✅ + * getAccessToken(metadata, "prop.token") ❌ + */ +const getAccessToken = (metadata, accessTokenKey) => { + // OAuth for this destination + const { secret } = metadata; + // we would need to verify if secret is present and also if the access token field is present in secret + if (!secret || !secret[accessTokenKey]) { + throw new OAuthSecretError("Empty/Invalid access token"); + } + return secret[accessTokenKey]; +}; + // ======================================================================== // EXPORTS // ======================================================================== @@ -1771,4 +1819,6 @@ module.exports = { getEventReqMetadata, isHybridModeEnabled, getEventType, + checkAndCorrectUserId, + getAccessToken }; diff --git a/src/v0/util/tags.js b/src/v0/util/tags.js index a08933b5b3..41373665fd 100644 --- a/src/v0/util/tags.js +++ b/src/v0/util/tags.js @@ -49,6 +49,7 @@ const ERROR_TYPES = { RETRYABLE: 'retryable', ABORTED: 'aborted', OAUTH_SECRET: 'oAuthSecret', + UNSUPPORTED: 'unsupported' }; const METADATA = { diff --git a/src/versionedRouter.js b/src/versionedRouter.js index a1d42a2751..a33d66df79 100644 --- a/src/versionedRouter.js +++ b/src/versionedRouter.js @@ -18,6 +18,7 @@ const { getErrorRespEvents, isCdkDestination, getErrorStatusCode, + checkAndCorrectUserId, } = require('./v0/util'); const { processDynamicConfig } = require('./util/dynamicConfig'); const { DestHandlerMap } = require('./constants/destinationCanonicalNames'); @@ -37,6 +38,7 @@ const { PlatformError } = require('./v0/util/errorTypes'); const { getCachedWorkflowEngine, processCdkV2Workflow } = require('./cdk/v2/handler'); const { processCdkV1 } = require('./cdk/v1/handler'); const {oncehubTransformer} = require("./util/oncehub-custom-transformer"); +const { extractLibraries } = require('./util/customTransformer'); const CDK_V1_DEST_PATH = 'cdk/v1'; @@ -139,6 +141,11 @@ async function compareWithCdkV2(destType, inputArr, feature, v0Result, v0Time) { const objectDiff = CommonUtils.objectDiff(v0Result, cdkResult); if (Object.keys(objectDiff).length > 0) { stats.counter('cdk_live_compare_test_failed', 1, { destType, feature }); + logger.error( + `[LIVE_COMPARE_TEST] failed for destType=${destType}, feature=${feature}, diff_keys=${JSON.stringify( + Object.keys(objectDiff) + )}` + ); // logger.error( // `[LIVE_COMPARE_TEST] failed for destType=${destType}, feature=${feature}, diff=${JSON.stringify( // objectDiff @@ -163,6 +170,17 @@ async function compareWithCdkV2(destType, inputArr, feature, v0Result, v0Time) { } } +/** + * Enriches the transformed event with more information + * - userId stringification + * + * @param {Object} transformedEvent - single transformed event + * @returns transformedEvent after enrichment + */ +const enrichTransformedEvent = (transformedEvent) => ( + { ...transformedEvent, userId: checkAndCorrectUserId(transformedEvent.statusCode, transformedEvent?.userId) } +); + async function handleV0Destination(destHandler, destType, inputArr, feature) { const v0Result = {}; let v0Time = 0; @@ -253,40 +271,24 @@ async function handleDest(ctx, version, destination) { if (!Array.isArray(respEvents)) { respEvents = [respEvents]; } - return respEvents.map((ev) => { - let { userId } = ev; - const { statusCode } = ev; - // Set the user ID to an empty string for - // all the falsy values (including 0 and false) - // Otherwise, server panics while un-marshalling the response - // while expecting only strings. - if (!userId) { - userId = ''; - } - - if (statusCode !== 400 && userId) { - userId = `${userId}`; - } - - return { - output: { ...ev, userId }, - metadata: destHandler?.processMetadata - ? destHandler.processMetadata({ - metadata: event.metadata, - inputEvent: parsedEvent, - outputEvent: ev, - }) - : event.metadata, - statusCode: 200, - }; - }); + return respEvents.map((ev) => ({ + output: enrichTransformedEvent(ev), + metadata: destHandler?.processMetadata + ? destHandler.processMetadata({ + metadata: event.metadata, + inputEvent: parsedEvent, + outputEvent: ev, + }) + : event.metadata, + statusCode: 200, + })); } return undefined; } catch (error) { logger.error(error); let implementation = tags.IMPLEMENTATIONS.NATIVE; - let errCtx = 'Destination Transformation'; + let errCtx = 'Processor Transformation'; if (isCdkV2Destination(event)) { errCtx = `CDK V2 - ${errCtx}`; implementation = tags.IMPLEMENTATIONS.CDK_V2; @@ -485,11 +487,23 @@ async function routerHandleDest(ctx) { tags.FEATURES.ROUTER, ); } - if (routerDestHandler.processMetadataForRouter) { - listOutput.forEach((output) => { - output.metadata = routerDestHandler.processMetadataForRouter(output); - }); - } + const hasProcMetadataForRouter = routerDestHandler.processMetadataForRouter; + // enriching transformed event + listOutput.forEach(listOut => { + const { batchedRequest } = listOut; + if (Array.isArray(batchedRequest)) { + // eslint-disable-next-line no-param-reassign + listOut.batchedRequest = batchedRequest.map(batReq => enrichTransformedEvent(batReq)); + } else if (batchedRequest && typeof batchedRequest === 'object') { + // eslint-disable-next-line no-param-reassign + listOut.batchedRequest = enrichTransformedEvent(batchedRequest); + } + + if (hasProcMetadataForRouter) { + // eslint-disable-next-line no-param-reassign + listOut.metadata = routerDestHandler.processMetadataForRouter(listOut); + } + }); respEvents.push(...listOutput); }), ); @@ -584,6 +598,22 @@ if (startDestTransformer) { }); if (functionsEnabled()) { + router.post('/extractLibs', async (ctx) => { + try { + const { code, validateImports = false, language = "javascript" } = ctx.request.body; + + if (!code) { + throw new Error('Invalid request. Code is missing'); + } + + const obj = await extractLibraries(code, validateImports, language); + ctx.body = obj; + } catch (err) { + ctx.status = 400; + ctx.body = { "error": err.error || err.message }; + } + }); + router.post('/customTransform', async (ctx) => { const startTime = new Date(); const events = ctx.request.body; diff --git a/test/__mocks__/axios.js b/test/__mocks__/axios.js index 7970101350..ec83b3c10e 100644 --- a/test/__mocks__/axios.js +++ b/test/__mocks__/axios.js @@ -49,7 +49,8 @@ const urlDirectoryMap = { "api.profitwell.com": "profitwell", "ruddertest2.mautic.net": "mautic", "api.sendgrid.com": "sendgrid", - "api.sendinblue.com": "sendinblue" + "api.sendinblue.com": "sendinblue", + "api.criteo.com": "criteo_audience" }; const fs = require("fs"); diff --git a/test/__mocks__/data/criteo_audience/proxy_response.json b/test/__mocks__/data/criteo_audience/proxy_response.json new file mode 100644 index 0000000000..fc87870c5c --- /dev/null +++ b/test/__mocks__/data/criteo_audience/proxy_response.json @@ -0,0 +1,69 @@ +{ + "https://api.criteo.com/2022-10/audiences/34894/contactlist": { + "status": 200 + }, + "https://api.criteo.com/2022-10/audiences/34895/contactlist": { + "code": "400", + "response": { + "data": { + "errors": [ + { + "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", + "type": "authorization", + "code": "authorization-token-invalid", + "instance": "/2022-10/audiences/123/contactlist", + "title": "The authorization header is invalid" + } + ] + }, + "status": 401 + } + }, + "https://api.criteo.com/2022-10/audiences/34896/contactlist": { + "code": "400", + "response": { + "data": { + "errors": [ + { + "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", + "type": "authorization", + "code": "audience-invalid" + } + ] + }, + "status": 404 + } + }, + "https://api.criteo.com/2022-10/audiences/34897/contactlist": { + "code": "500", + "response": { + "data": { + "errors": [ + { + "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", + "type": "authorization", + "code": "audience-invalid" + } + ] + }, + "status": 503 + } + }, + "https://api.criteo.com/2022-10/audiences/34898/contactlist": { + "code": "429", + "response": { + "data": { + }, + "status": 429 + } + }, + "https://api.criteo.com/2022-10/audiences/34899/contactlist": { + "code": "400", + "response": { + "data": { + "message": "unknown error" + }, + "status": 410 + } + } +} \ No newline at end of file diff --git a/test/__mocks__/data/criteo_audience/response.json b/test/__mocks__/data/criteo_audience/response.json new file mode 100644 index 0000000000..7830427147 --- /dev/null +++ b/test/__mocks__/data/criteo_audience/response.json @@ -0,0 +1,33 @@ +{ + "https://api.criteo.com/2022-10//audiences/34894/contactlist": { + "data": { + "request_status": "SUCCESS", + "request_id": "12345", + "users": [ + { + "sub_request_status": "SUCCESS", + "user": { + "number_uploaded_users": 1 + } + } + ] + }, + "status": 200, + "statusText": "OK" + }, + "https://api.criteo.com/2022-10/audiences/34895/contactlist": { + "data": "unauthorized", + "status": 401, + "response": { + "errors": [ + { + "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", + "type": "authorization", + "code": "authorization-token-invalid", + "instance": "/2022-10/audiences/123/contactlist", + "title": "The authorization header is invalid" + } + ] + } + } + } \ No newline at end of file diff --git a/test/__mocks__/data/salesforce/proxy_response.json b/test/__mocks__/data/salesforce/proxy_response.json index 7f444c6845..ddb515c5da 100644 --- a/test/__mocks__/data/salesforce/proxy_response.json +++ b/test/__mocks__/data/salesforce/proxy_response.json @@ -50,5 +50,23 @@ ], "status": 503 } + }, + "https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/6": { + "response": { + "data": { + "error": "invalid_grant", + "error_description": "authentication failure" + }, + "status": 400 + } + }, + "https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/7": { + "response": { + "data": { + "message": "Server Unavailable", + "errorCode": "SERVER_UNAVAILABLE" + }, + "status": 503 + } } -} +} \ No newline at end of file diff --git a/test/__mocks__/network.js b/test/__mocks__/network.js index 246843a910..b8bc753bb6 100644 --- a/test/__mocks__/network.js +++ b/test/__mocks__/network.js @@ -20,7 +20,8 @@ const urlDirectoryMap = { "api.mautic.com": "mautic", "adsapi.snapchat.com": "snapchat_custom_audience", "api.clevertap.com": "clevertap", - "marketo_acct_id_success.mktorest.com": "marketo_static_list" + "marketo_acct_id_success.mktorest.com": "marketo_static_list", + "api.criteo.com": "criteo_audience" }; function getData(url) { diff --git a/test/__tests__/__integration_util_test__/data/checkAndCorrectUserId.json b/test/__tests__/__integration_util_test__/data/checkAndCorrectUserId.json new file mode 100644 index 0000000000..a3f3f55ad3 --- /dev/null +++ b/test/__tests__/__integration_util_test__/data/checkAndCorrectUserId.json @@ -0,0 +1,25 @@ +[ + { + "description": "userId as an integer", + "input": { + "statusCode": 200, + "userId": 1234 + }, + "output": "1234" + }, + { + "description": "userId not given", + "input": { + "statusCode": 200 + }, + "output": "" + }, + { + "description": "userID as string", + "input": { + "statusCode": 200, + "userId": "abcd1234" + }, + "output": "abcd1234" + } +] \ No newline at end of file diff --git a/test/__tests__/__integration_util_test__/data/extractCustomFields.json b/test/__tests__/__integration_util_test__/data/extractCustomFields.json new file mode 100644 index 0000000000..6c4916e053 --- /dev/null +++ b/test/__tests__/__integration_util_test__/data/extractCustomFields.json @@ -0,0 +1,166 @@ +[ + { + "description": "Check for message fields absent from the exclusion list and adding them to payload object - 1", + "input": [ + { + "type": "track", + "event": "Product Added", + "sentAt": "2022-08-07T20:02:19.352Z", + "userId": "userSampleX138", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "locale": "en-IN", + "traits": { + "email": "userSampleX120@gmail.com", + "phone": "9878764736", + "last_name": "Stack", + "first_name": "Rudder" + }, + "externalId": [ + { + "type": "rockerboxExternalId", + "id": "rbUid" + } + ], + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" + }, + "rudderId": "4a47e99b-2afc-45c6-b902-ed69282ca805", + "messageId": "1659902539347900-c622426c-a1dd-44c0-ac6d-d4dbee3f4a93", + "properties": { + "checkout_id": "12345", + "product_url": "http://www.yourdomain.com/products/red-t-shirt", + "product_name": "Red T-shirt", + "externalId": "rbUid", + "countryCode": "IN", + "listingId": "10101" + }, + "anonymousId": "5f093403-1457-4a2c-b4e4-c61ec3bacf56", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-08-07T20:02:19.347Z" + }, + { + "customer_id": "userSampleX138", + "email": "userSampleX120@gmail.com", + "phone": "9878764736", + "timestamp": 1659902539, + "country_code": "IN", + "listing_id": "10101", + "conversion_source": "RudderStack", + "action": "conv.add_to_cart" + }, + ["properties"], + [ + "userId", + "email", + "phone", + "timestamp", + "revenue", + "value", + "price", + "total", + "orderId", + "order_id", + "in_store", + "salesforce", + "countryCode", + "listingId" + ] + ], + "output": { + "customer_id": "userSampleX138", + "email": "userSampleX120@gmail.com", + "phone": "9878764736", + "timestamp": 1659902539, + "country_code": "IN", + "listing_id": "10101", + "conversion_source": "RudderStack", + "action": "conv.add_to_cart", + "checkout_id": "12345", + "product_url": "http://www.yourdomain.com/products/red-t-shirt", + "product_name": "Red T-shirt", + "externalId": "rbUid" + } + }, + { + "description": "Check for message fields absent from the exclusion list and adding them to payload object - 2", + "input": [ + { + "type": "track", + "event": "Product Viewed", + "sentAt": "2022-08-07T20:02:19.352Z", + "userId": "userSampleX138", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "locale": "en-IN", + "traits": { + "email": "userSampleX120@gmail.com", + "phone": "9878764736", + "last_name": "Stack", + "first_name": "Rudder" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" + }, + "rudderId": "4a47e99b-2afc-45c6-b902-ed69282ca805", + "messageId": "1659902539347900-c622426c-a1dd-44c0-ac6d-d4dbee3f4a93", + "properties": { + "checkout_id": "12345", + "product_url": "http://www.yourdomain.com/products/red-t-shirt", + "product_name": "Red T-shirt" + }, + "anonymousId": "5f093403-1457-4a2c-b4e4-c61ec3bacf56", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-08-07T20:02:19.347Z" + }, + { + "customer_id": "userSampleX138", + "email": "userSampleX120@gmail.com", + "phone": "9878764736", + "timestamp": 1659902539, + "conversion_source": "RudderStack", + "action": "conv.add_to_cart" + }, + ["properties"], + [ + "userId", + "email", + "phone", + "timestamp", + "revenue", + "value", + "price", + "total", + "orderId", + "order_id", + "in_store", + "salesforce", + "countryCode", + "listingId" + ] + ], + "output": { + "customer_id": "userSampleX138", + "email": "userSampleX120@gmail.com", + "phone": "9878764736", + "timestamp": 1659902539, + "conversion_source": "RudderStack", + "action": "conv.add_to_cart", + "checkout_id": "12345", + "product_url": "http://www.yourdomain.com/products/red-t-shirt", + "product_name": "Red T-shirt" + } + } +] diff --git a/test/__tests__/__integration_util_test__/data/flattenJsonTestCases.json b/test/__tests__/__integration_util_test__/data/flattenJson.json similarity index 97% rename from test/__tests__/__integration_util_test__/data/flattenJsonTestCases.json rename to test/__tests__/__integration_util_test__/data/flattenJson.json index b48ce5f3ca..d992d4d787 100644 --- a/test/__tests__/__integration_util_test__/data/flattenJsonTestCases.json +++ b/test/__tests__/__integration_util_test__/data/flattenJson.json @@ -1,6 +1,6 @@ [ { - "description": "Invalid priority", + "description": "Should return flattened JSON if the input contains array of objects", "input": { "checkout_id": "what is checkout id here??", "coupon": "APPARELSALE", @@ -137,7 +137,7 @@ } }, { - "description": "Custom field: Invalid phone number", + "description": "Should return flattened JSON if the input contains array of objects containing arrays", "input": { "checkout_id": "what is checkout id here??", "coupon": "APPARELSALE", @@ -328,7 +328,7 @@ } }, { - "description": "Custom field: Invalid url", + "description": "Should return flattened JSON and preserve the arrays order if the input contains array of objects containing arrays", "input": { "checkout_id": "what is checkout id here??", "coupon": "APPARELSALE", @@ -465,7 +465,7 @@ } }, { - "description": "Custom field: Invalid location latitude", + "description": "Should return flattened JSON if the input contains objects and simple fields (of all data types)", "input": { "timezone": "Asia/Kolkata", "app": { @@ -481,7 +481,7 @@ "locale": "en-GB", "os": { "name": "", - "version": "" + "version": 2.3 }, "page": { "path": "/testing/script-test.html", @@ -513,7 +513,7 @@ "library.version": "1.1.6", "locale": "en-GB", "os.name": "", - "os.version": "", + "os.version": 2.3, "page.path": "/testing/script-test.html", "page.referrer": "", "page.search": "", diff --git a/test/__tests__/__integration_util_test__/data/getExternalIDTestCases.json b/test/__tests__/__integration_util_test__/data/getDestinationExternalID.json similarity index 54% rename from test/__tests__/__integration_util_test__/data/getExternalIDTestCases.json rename to test/__tests__/__integration_util_test__/data/getDestinationExternalID.json index 25aaddeaa3..af1f515ef8 100644 --- a/test/__tests__/__integration_util_test__/data/getExternalIDTestCases.json +++ b/test/__tests__/__integration_util_test__/data/getDestinationExternalID.json @@ -1,33 +1,36 @@ [ { - "description": "Passing externalIdArray as Array", - "input": { - "type": "track", - "event": "Product Reviewed", - "userId": "5136633649", - "properties": { - "review_id": "12345", - "product_id": "123", - "rating": 3.0, - "review_body": "Average product, expected much more.", - "groupId": "test-12345" + "description": "Should return the correct value if the external ID is an array", + "input": [ + { + "type": "track", + "event": "Product Reviewed", + "userId": "5136633649", + "properties": { + "review_id": "12345", + "product_id": "123", + "rating": 3.0, + "review_body": "Average product, expected much more.", + "groupId": "test-12345" + }, + "context": { + "externalId": [ + { + "type": "randomType", + "id": "91Yb32830" + } + ] + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "originalTimestamp": "2022-01-20T13:39:21.032Z" }, - "context": { - "externalId": [ - { - "type": "juneGroupId", - "id": "91Yb32830" - } - ] - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "originalTimestamp": "2022-01-20T13:39:21.032Z" - }, + "randomType" + ], "output": "91Yb32830" }, { - "description": "Not Passing externalIdArray at all", + "description": "Should return null if no external ID is defined", "input": { "type": "track", "event": "Product Reviewed", @@ -53,7 +56,7 @@ "output": null }, { - "description": "Passing externalIdArray as Object", + "description": "Should return null if the external ID is an object", "input": { "type": "track", "event": "Product Reviewed", @@ -66,11 +69,10 @@ "groupId": "test-12345" }, "context": { - "externalId": - { - "type": "juneGroupId", - "id": "91Yb32830" - } + "externalId": { + "type": "juneGroupId", + "id": "91Yb32830" + } }, "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", "anonymousId": "bf412108-0357-4330-b119-7305e767823c", diff --git a/test/__tests__/__integration_util_test__/data/getErrorStatusCode.json b/test/__tests__/__integration_util_test__/data/getErrorStatusCode.json new file mode 100644 index 0000000000..0a707d22ef --- /dev/null +++ b/test/__tests__/__integration_util_test__/data/getErrorStatusCode.json @@ -0,0 +1,60 @@ +[ + { + "description": "Should return status code from 'response.status' if it is a positive integer", + "input": { + "response": { "status": 403 } + }, + "output": 403 + }, + { + "description": "Should return status code from 'code' if it is a positive integer", + "input": { + "code": 403 + }, + "output": 403 + }, + { + "description": "Should return status code from 'status' if it is a positive integer", + "input": { + "status": 403 + }, + "output": 403 + }, + { + "description": "Should return 400 status code if 'response.status' is not a positive integer", + "input": { + "response": { "status": "403" } + }, + "output": 400 + }, + { + "description": "Should return the supplied default status code if 'response.status' is not a positive integer", + "input": [ + { + "response": { "status": "403" } + }, + 500 + ], + "output": 500 + }, + { + "description": "Should return the supplied default status code if no status code is present", + "input": [ + { + "message": "An error occurred" + }, + 502 + ], + "output": 502 + }, + { + "description": "Should return 400 status code if no status code is present and the the default status code is not a positive integer", + "input": [ + { + "message": "An error occurred" + }, + "502" + ], + "output": 400 + } +] diff --git a/test/__tests__/__integration_util_test__/data/getFormData.json b/test/__tests__/__integration_util_test__/data/getFormData.json new file mode 100644 index 0000000000..a6900e1786 --- /dev/null +++ b/test/__tests__/__integration_util_test__/data/getFormData.json @@ -0,0 +1,29 @@ +[ + { + "description": "Special characters should encode correctly", + "input": { "data": " ?&=#+%!<>#\"{}|\\^[]`☺\t:/@$'()*,;" }, + "output": "data=+%3F%26%3D%23%2B%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%E2%98%BA%09%3A%2F%40%24%27%28%29*%2C%3B" + }, + { + "description": "String containing and characters should encode correctly", + "input": { + "data": "Channel is *san_dev* which is being viewed by `Sank`, you don't have _control_ over\n```This code-snippet does the trick for us```" + }, + "output": "data=Channel+is+*san_dev*+which+is+being+viewed+by+%60Sank%60%2C+you+don%27t+have+_control_+over%0A%60%60%60This+code-snippet+does+the+trick+for+us%60%60%60" + }, + { + "description": "String[] containing should encode correctly", + "input": { "data": ["{\"user_id\": \"1lknduhkl3nr8skm3hkdkis\"}"] }, + "output": "data=%5B%7B%22user_id%22%3A+%221lknduhkl3nr8skm3hkdkis%22%7D%5D" + }, + { + "description": "\"~\" as a character in the data should be encoded", + "input": { "data": "~" }, + "output": "data=%7E" + }, + { + "description": "All \"~\" should be encoded as \"%7E\"", + "input": { "data": "ab~cd~ef~gh" }, + "output": "data=ab%7Ecd%7Eef%7Egh" + } +] diff --git a/test/__tests__/__integration_util_test__/data/isHybridModeEnabled.json b/test/__tests__/__integration_util_test__/data/isHybridModeEnabled.json new file mode 100644 index 0000000000..ce212c7ba5 --- /dev/null +++ b/test/__tests__/__integration_util_test__/data/isHybridModeEnabled.json @@ -0,0 +1,38 @@ +[ + { + "description": "Should return false if both flags (useNativeSDK and useNativeSDKToSend) are not present", + "input": {}, + "output": false + }, + { + "description": "Should return false if useNativeSDKToSend is not present", + "input": { + "useNativeSDK": false + }, + "output": false + }, + { + "description": "Should return true if both flags (useNativeSDK and useNativeSDKToSend) are present and device mode is enabled", + "input": { + "useNativeSDK": true, + "useNativeSDKToSend": false + }, + "output": true + }, + { + "description": "Should return false if both flags (useNativeSDK and useNativeSDKToSend) are present and set to true", + "input": { + "useNativeSDK": true, + "useNativeSDKToSend": true + }, + "output": false + }, + { + "description": "Should return false if both flags (useNativeSDK and useNativeSDKToSend) are present but set to true", + "input": { + "useNativeSDK": false, + "useNativeSDKToSend": false + }, + "output": false + } +] diff --git a/test/__tests__/__integration_util_test__/data/processDynamicConfig.json b/test/__tests__/__integration_util_test__/data/processDynamicConfig.json new file mode 100644 index 0000000000..eeb02d98b9 --- /dev/null +++ b/test/__tests__/__integration_util_test__/data/processDynamicConfig.json @@ -0,0 +1,519 @@ +[ + { + "description": "Should return parsed destination config if a single field has templated config", + "input": { + "destination": { + "Config": { + "appId": "{{ message.traits.appId || \"\" }}" + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath", + "email": "sampath@gmail.com", + "appId": "testAppId" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": "testAppId" + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath", + "email": "sampath@gmail.com" + } + } + } + }, + { + "description": "Should return parsed destination config if multiple fields have templated config", + "input": { + "destination": { + "Config": { + "appId": [ + { + "from": "{{ message.traits.appId || \"\" }}", + "to": "{{ message.traits.anonymousId || \"1234\" }}" + } + ] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath", + "email": "sampath@gmail.com", + "appId": "testAppId" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": [{ "from": "testAppId", "to": "sampath" }] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "email": "sampath@gmail.com" + } + } + } + }, + { + "description": "Should return parsed destination config if the templated config is defined inside object of an array", + "input": { + "destination": { + "Config": { + "appId": { + "key2": "hey", + "key3": "{{ message.traits.appId || \"email\" }}", + "key4": [ + { + "from": "{{ message.traits.email || \"email\" }}", + "to": "no" + } + ] + } + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath", + "email": "sampath@gmail.com", + "appId": "testAppId" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": { + "key2": "hey", + "key3": "testAppId", + "key4": [{ "from": "sampath@gmail.com", "to": "no" }] + } + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath" + } + } + } + }, + { + "description": "Should return parsed destination config if the templated config is defined inside object of an array inside an object", + "input": { + "destination": { + "Config": { + "appId": [ + { "key2": "hey" }, + { "key3": "{{ message.traits.appId || \"email\" }}" }, + { + "key4": [ + { + "from": "{{ message.traits.email || \"email\" }}", + "to": "no" + } + ] + } + ] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath", + "email": "sampath@gmail.com", + "appId": "testAppId" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": [ + { "key2": "hey" }, + { "key3": "testAppId" }, + { + "key4": [ + { + "from": "sampath@gmail.com", + "to": "no" + } + ] + } + ] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath" + } + } + } + }, + { + "description": "Should return parsed destination config if the templated config field is invalid but a default value is specified", + "input": { + "destination": { + "Config": { + "appId": [ + { "key2": "hey" }, + { "key3": "{{ message.traits.appId || \"email\" }}" }, + { + "key4": ["{{ message.traits.email || \"email\" }}", "no"] + } + ] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath", + "email": "sampath@gmail.com", + "appId": "testAppId" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": [ + { "key2": "hey" }, + { "key3": "testAppId" }, + { + "key4": ["sampath@gmail.com", "no"] + } + ] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath" + } + } + } + }, + { + "description": "Should return the same destination config if there are no fields with templated configuration", + "input": { + "destination": { + "Config": { + "appId": false + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath", + "email": "sampath@gmail.com", + "appId": "testAppId" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": false + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath", + "email": "sampath@gmail.com", + "appId": "testAppId" + } + } + } + }, + { + "description": "Should return parsed destination config if the templated config is defined inside an array", + "input": { + "destination": { + "Config": { + "appId": [ + { "abc": 1234, "def": "{{message.traits.email|| \"email\"}}" }, + "{{message.traits.appId|| \"testAppId\"}}" + ] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath", + "email": "sampath@gmail.com", + "appId": "testAppId" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": [{ "abc": 1234, "def": "sampath@gmail.com" }, "testAppId"] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath" + } + } + } + }, + { + "description": "Should return parsed destination config if the templated config is defined inside an object", + "input": { + "destination": { + "Config": { + "appId": [ + { "abc": 1234, "def": "{{message.traits.email|| 12345 }}" }, + "{{message.traits.appId|| false }}" + ] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": [{ "abc": 1234, "def": "12345" }, "false"] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath" + } + } + } + }, + { + "description": "Should return parsed destination config if the templated config is deeply nested", + "input": { + "destination": { + "Config": { + "appId": "{{ message.traits.appId || appId }} ", + "email": " {{ message.trait.email || \"test@gmail.com \" }}", + "key": "{{ message.key || \" default value \" }}", + "key1": "{{ message.key1 || \" default value }}", + "key2": "{{ message.key1 || default value \" }}", + "key3": "{{ message.traits.appId || 123.1234 }}", + "key4": ["{{ message.traits.key4 || defaultVal }}", "{{ message.key4 || defaultVal }}"], + "key5": [{ "key2": { "key3": "{{ message.key5 || defaultVal }}" } }], + "key6": [ + [ + { "key2": { "key3": "{{ message.key5 || defaultVal }}" } }, + { "key4": "{{ mesage.traits.key4 || defaultVal }}" } + ], + "defaultVal" + ] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "key": "val", + "key4": "val4", + "key5": "val5", + "context": {}, + "traits": { + "anonymousId": "sampath", + "appId": "testAppId" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": "testAppId", + "email": "test@gmail.com", + "key": "val", + "key1": "default value", + "key2": "default value", + "key3": "123.1234", + "key4": ["defaultVal", "val4"], + "key5": [{ "key2": { "key3": "val5" } }], + "key6": [[{ "key2": { "key3": "defaultVal" } }, { "key4": "defaultVal" }], "defaultVal"] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath" + } + } + } + }, + { + "description": "Should return parsed destination config with whitespace trimmed if the templated config has default values surrounded with whitespaces", + "input": { + "destination": { + "Config": { + "appId": "{{ event.traits.appId || appId }} ", + "email": " {{ event.trait.email || \"test@gmail.com \" }}", + "key": "{{ event.key || \" default value \" }}", + "key1": "{{ event.key1 || \" default value }}", + "key2": "{{ event.key1 || default value \" }}", + "key3": "{{ message.traits.appId || 123.1234 }}", + "key4": ["{{ event.traits.key4 || defaultVal }}", "{{ event.key4 || defaultVal }}"], + "key5": [{ "key2": { "key3": "{{ event.key5 || defaultVal }}" } }], + "key6": [ + [ + { "key2": { "key3": "{{ event.key5 || defaultVal }}" } }, + { "key4": "{{ evnt.traits.key4 || defaultVal }}" } + ], + "defaultVal" + ] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "key": "val", + "key4": "val4", + "key5": "val5", + "context": {}, + "traits": { + "anonymousId": "sampath", + "appId": "testAppId" + } + } + }, + "output": { + "destination": { + "Config": { + "appId": "testAppId", + "email": "test@gmail.com", + "key": "val", + "key1": "default value", + "key2": "default value", + "key3": "123.1234", + "key4": ["defaultVal", "val4"], + "key5": [{ "key2": { "key3": "val5" } }], + "key6": [[{ "key2": { "key3": "defaultVal" } }, { "key4": "defaultVal" }], "defaultVal"] + } + }, + "metadata": { + "jobId": 2 + }, + "message": { + "anonymousId": "sampath", + "channel": "web", + "context": {}, + "traits": { + "anonymousId": "sampath" + } + } + } + } +] diff --git a/test/__tests__/__integration_util_test__/flattenJSONUtil.test.js b/test/__tests__/__integration_util_test__/flattenJSONUtil.test.js deleted file mode 100644 index 7d754bcd1c..0000000000 --- a/test/__tests__/__integration_util_test__/flattenJSONUtil.test.js +++ /dev/null @@ -1,20 +0,0 @@ -const fs = require("fs"); -const path = require("path"); -const utilObj = require("../../../src/v0/util"); - -const fnName = "flattenJson"; - -// Test file -const testDataFile = fs.readFileSync( - path.resolve(__dirname, `./data/flattenJsonTestCases.json`) -); -const testData = JSON.parse(testDataFile); - -describe("flattenJSon util test", () => { - testData.forEach(async (dataPoint, index) => { - it(`Test Case ${index}.`, async () => { - const outputArray = utilObj[fnName](dataPoint.input); - expect(outputArray).toEqual(dataPoint.output); - }); - }); -}); diff --git a/test/__tests__/__integration_util_test__/getExternalIDUtil.test.js b/test/__tests__/__integration_util_test__/getExternalIDUtil.test.js deleted file mode 100644 index 011c4aa6fc..0000000000 --- a/test/__tests__/__integration_util_test__/getExternalIDUtil.test.js +++ /dev/null @@ -1,20 +0,0 @@ -const fs = require("fs"); -const path = require("path"); -const { getDestinationExternalID } = require("../../../src/v0/util"); - -const type = "juneGroupId"; - -// Test file -const testDataFile = fs.readFileSync( - path.resolve(__dirname, `./data/getExternalIDTestCases.json`) -); -const testData = JSON.parse(testDataFile); - -describe("getDestinationExternalID util test", () => { - testData.forEach(async (dataPoint, index) => { - it(`Test Case ${index}.`, async () => { - const outputArray = getDestinationExternalID(dataPoint.input, type); - expect(outputArray).toEqual(dataPoint.output); - }); - }); -}); diff --git a/test/__tests__/__integration_util_test__/getFormData.test.js b/test/__tests__/__integration_util_test__/getFormData.test.js new file mode 100644 index 0000000000..c74bc247ba --- /dev/null +++ b/test/__tests__/__integration_util_test__/getFormData.test.js @@ -0,0 +1,17 @@ +const { getFormData } = require('../../../src/adapters/network'); +const { getFuncTestData } = require('./testHelper'); + +const funcName = 'getFormData'; + +describe(`${funcName} Tests`, () => { + const funcTestData = getFuncTestData(funcName); + test.each(funcTestData)('$description', async ({ description, input, output }) => { + let result; + if (Array.isArray(input)) { + result = getFormData(...input); + } else { + result = getFormData(input); + } + expect(result.toString()).toEqual(output); + }); +}); diff --git a/test/__tests__/__integration_util_test__/processDynamicConfig.test.js b/test/__tests__/__integration_util_test__/processDynamicConfig.test.js new file mode 100644 index 0000000000..e28f47b15b --- /dev/null +++ b/test/__tests__/__integration_util_test__/processDynamicConfig.test.js @@ -0,0 +1,18 @@ +const { processDynamicConfig } = require('../../../src/util/dynamicConfig'); +const { getFuncTestData } = require('./testHelper'); + +const funcName = 'processDynamicConfig'; +const reqType = 'processor'; + +describe(`${funcName} Tests`, () => { + const funcTestData = getFuncTestData(funcName); + test.each(funcTestData)('$description', async ({ description, input, output }) => { + let result; + if (Array.isArray(input)) { + result = processDynamicConfig(...input); + } else { + result = processDynamicConfig(input, reqType); + } + expect(result).toEqual(output); + }); +}); diff --git a/test/__tests__/__integration_util_test__/testHelper.js b/test/__tests__/__integration_util_test__/testHelper.js new file mode 100644 index 0000000000..49816b3eaa --- /dev/null +++ b/test/__tests__/__integration_util_test__/testHelper.js @@ -0,0 +1,12 @@ +const fs = require('fs'); +const path = require('path'); + +const getFuncTestData = (funcName) => { + const fileData = fs.readFileSync(path.resolve(__dirname, `./data/${funcName}.json`)); + const testData = JSON.parse(fileData); + return testData; +}; + +module.exports = { + getFuncTestData, +}; diff --git a/test/__tests__/__integration_util_test__/v0_index.test.js b/test/__tests__/__integration_util_test__/v0_index.test.js deleted file mode 100644 index 855fbf1611..0000000000 --- a/test/__tests__/__integration_util_test__/v0_index.test.js +++ /dev/null @@ -1,118 +0,0 @@ -const fs = require("fs"); -const path = require("path"); -const { getFormData } = require("../../../src/adapters/network"); -const utilObj = require("../../../src/v0/util"); - -const functionsToTest = [ - "handleSourceKeysOperation", - "getValueFromPropertiesOrTraits" -]; - -const fnName = "all"; - -describe("Integration Util Tests", () => { - functionsToTest.forEach(fn => { - if (fnName === "all" || fn === fnName) { - describe(`Test - ${fn}`, () => { - const fnObj = utilObj[fn]; - - // common for all the methods - it(`${fn} is defined`, () => { - expect(fnObj).not.toBeNull(); - }); - - // get the data file for the function - const inputFile = fs.readFileSync( - path.resolve(__dirname, `./data/${fn}.json`) - ); - const inputData = JSON.parse(inputFile); - - inputData.forEach(dataPoint => { - const { input, output, description } = dataPoint; - it(description, () => { - const result = fnObj({ ...input }); - if (output === null) { - expect(result).toBeNull(); - } else { - expect(result).toEqual(output); - } - }); - }); - }); - } - }); -}); - -const formDataEscapeCases = [ - // This case is added because url.Values{}.Encode() encodes all the special characters - { - testCase: "Special characters should encode correctly", - input: { data: " ?&=#+%!<>#\"{}|\\^[]`☺\t:/@$'()*,;" }, - expected: - "data=+%3F%26%3D%23%2B%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%E2%98%BA%09%3A%2F%40%24%27%28%29*%2C%3B" - }, - { - testCase: "String containing and characters should encode correctly", - input: { - data: - "Channel is *san_dev* which is being viewed by `Sank`, you don't have _control_ over\n```This code-snippet does the trick for us```" - }, - expected: - "data=Channel+is+*san_dev*+which+is+being+viewed+by+%60Sank%60%2C+you+don%27t+have+_control_+over%0A%60%60%60This+code-snippet+does+the+trick+for+us%60%60%60" - }, - { - testCase: "String[] containing should encode correctly", - input: { data: ['{"user_id": "1lknduhkl3nr8skm3hkdkis"}'] }, - expected: "data=%5B%7B%22user_id%22%3A+%221lknduhkl3nr8skm3hkdkis%22%7D%5D" - }, - // This case is added because url.Values{}.Encode()(in golang) doesn't encode `~` - { - testCase: '"~" as a character in the data should be encoded', - input: { data: "~" }, - expected: "data=%7E" - }, - { - testCase: 'All "~" should be encoded as "%7E"', - input: { data: "ab~cd~ef~gh" }, - expected: "data=ab%7Ecd%7Eef%7Egh" - } -]; - -describe("`FORM` format escape test-cases", () => { - it.each(formDataEscapeCases)("$testCase", ({ input, expected }) => { - const output = getFormData(input); - expect(output.toString()).toEqual(expected); - }); -}); - -const { getErrorStatusCode } = utilObj; - -describe("error status code when error is thrown", () => { - it('should return status-code from "response.status"', () => { - expect(getErrorStatusCode({ response: { status: 403 } })).toEqual(403); - }); - it('should return status-code from "code"', () => { - expect(getErrorStatusCode({ code: 403 })).toEqual(403); - }); - it('should return status-code from "status"', () => { - expect(getErrorStatusCode({ status: 403 })).toEqual(403); - }); - it('should return default status-code when "response.status" is a stringified number', () => { - expect(getErrorStatusCode({ response: { status: "403" } })).toEqual(400); - }); - it('should return send default status-code when "response.status" is a stringified number', () => { - expect(getErrorStatusCode({ response: { status: "403" } }, 500)).toEqual( - 500 - ); - }); - it("should return send default status-code when no status code is sent", () => { - expect(getErrorStatusCode({ message: "An error occurred" }, 502)).toEqual( - 502 - ); - }); - it("should return 400 when no status code is sent & default status code is other than number", () => { - expect(getErrorStatusCode({ message: "An error occurred" }, "502")).toEqual( - 400 - ); - }); -}); diff --git a/test/__tests__/__integration_util_test__/v0_utilities.test.js b/test/__tests__/__integration_util_test__/v0_utilities.test.js new file mode 100644 index 0000000000..f1b169778d --- /dev/null +++ b/test/__tests__/__integration_util_test__/v0_utilities.test.js @@ -0,0 +1,66 @@ +const utilities = require('../../../src/v0/util'); +const { getFuncTestData } = require('./testHelper'); + +// Names of the utility functions to test +const functionNames = [ + 'flattenJson', + 'getDestinationExternalID', + 'isHybridModeEnabled', + 'handleSourceKeysOperation', + 'getValueFromPropertiesOrTraits', + 'getErrorStatusCode', + 'extractCustomFields' +]; + +// Names of the utility functions to test which expects multiple arguments as values and not objects +const functionNamesExpectingMultipleArguments = [ + 'checkAndCorrectUserId' +] + +describe('Utility Functions Tests', () => { + describe.each(functionNames)('%s Tests', (funcName) => { + const funcTestData = getFuncTestData(funcName); + test.each(funcTestData)('$description', async ({ description, input, output }) => { + try { + let result; + + // This is to allow sending multiple arguments to the function + if (Array.isArray(input)) { + result = utilities[funcName](...input); + } else { + result = utilities[funcName](input); + } + expect(result).toEqual(output); + } catch (e) { + // Explicitly fail the test case + expect(true).toEqual(false); + } + }); + }); + /* This is to allow sending multiple arguments to the function in case when input is not an array but object + * Like in case of checkAndCorrectUserId + * "input": { + "statusCode": 200, + "userId": 1234 + } + * checkAndCorrectUserId function expects two arguments statusCode and userId and not an object so we need to send them as multiple arguments + * in the same order that they are defined in the function. + * This order should be maintained in the input Object. + */ + describe.each(functionNamesExpectingMultipleArguments)('%s Tests', (funcName) => { + const funcTestData = getFuncTestData(funcName); + test.each(funcTestData)('$description', async ({ description, input, output }) => { + try { + let result; + console.log(Object.values(input)); + result = utilities[funcName](...Object.values(input)); + expect(result).toEqual(output); + } catch (e) { + // Explicitly fail the test case + expect(true).toEqual(false); + } + }); + }); +}); + + diff --git a/test/__tests__/criteo_audience.test.js b/test/__tests__/criteo_audience.test.js new file mode 100644 index 0000000000..bdc428cecb --- /dev/null +++ b/test/__tests__/criteo_audience.test.js @@ -0,0 +1,46 @@ +const fs = require("fs"); +const path = require("path"); + +const integration = "criteo_audience"; +const name = "Criteo_Audience"; +const version = "v0"; + +const transformer = require(`../../src/${version}/destinations/${integration}/transform`); + +// Processor Test Data +const testDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}.json`) +); +const testData = JSON.parse(testDataFile); + +// Router Test Data +const inputRouterDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}_router_input.json`) +); +const outputRouterDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}_router_output.json`) +); +const inputRouterData = JSON.parse(inputRouterDataFile); +const expectedRouterData = JSON.parse(outputRouterDataFile); + +describe(`${name} Tests`, () => { + describe("Processor", () => { + testData.forEach((dataPoint, index) => { + it(`${index}. ${integration} - ${dataPoint.description}`, async () => { + try { + const output = await transformer.process(dataPoint.input); + expect(output).toEqual(dataPoint.output); + } catch (error) { + expect(error.message).toEqual(dataPoint.output.error); + } + }); + }); + }); + + describe("Router Tests", () => { + it("Payload", async () => { + const routerOutput = await transformer.processRouterDest(inputRouterData); + expect(routerOutput).toEqual(expectedRouterData); + }); + }); +}); diff --git a/test/__tests__/data/active_campaign_router_input.json b/test/__tests__/data/active_campaign_router_input.json index 17c31f3518..89c710a53b 100644 --- a/test/__tests__/data/active_campaign_router_input.json +++ b/test/__tests__/data/active_campaign_router_input.json @@ -141,5 +141,86 @@ }, "sentAt": "2019-10-14T11:15:53.296Z" } + }, + { + "message": { + "name": "home", + "type": "page", + "sentAt": "2023-01-10T22:31:10.954Z", + "userId": "", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "2.20.0", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "url", + "path": "path", + "title": "title", + "search": "search", + "tab_url": "https://simple-tenet.github.io/rudderstack-sample-site/", + "referrer": "referrer", + "initial_referrer": "$direct", + "referring_domain": "", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1512, + "height": 982, + "density": 2, + "innerWidth": 846, + "innerHeight": 782 + }, + "traits": {}, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.20.0" + }, + "campaign": {}, + "sessionId": 1673389635049, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" + }, + "rudderId": "d37dd81f-5894-48ec-b312-09c590bab15c", + "messageId": "2774384870943800-0b15a357-c85d-4b22-916e-ed53286b742a", + "timestamp": "2023-01-10T22:31:11.601Z", + "properties": { + "url": "url", + "name": "home", + "path": "path", + "title": "title", + "search": "search", + "tab_url": "https://simple-tenet.github.io/rudderstack-sample-site/", + "referrer": "referrer", + "initial_referrer": "$direct", + "referring_domain": "", + "initial_referring_domain": "" + }, + "receivedAt": "2023-01-10T22:31:11.612Z", + "request_ip": "0.0.0.20", + "anonymousId": "878e8f5f-9b6c-4aef-b5d3-1b970a13f17a", + "integrations": { + "All": true + }, + "originalTimestamp": "2023-01-10T22:31:10.943Z" + }, + "destination": { + "Config": { + "apiKey": "fbee74a147828e2932c701d19dc1f2dcfa4ac0048be3aa3a88d427090a59dc1c0fa002f1", + "apiUrl": "https://active.campaigns.rudder.com", + "actid": "476550467", + "eventKey": "f8a866fddc721350fdc2fbbd2e5c43a6dddaaa03" + } + }, + "metadata": { + "jobId": 5 + } } ] diff --git a/test/__tests__/data/active_campaign_router_output.json b/test/__tests__/data/active_campaign_router_output.json index 7ac0e540c1..1be6412883 100644 --- a/test/__tests__/data/active_campaign_router_output.json +++ b/test/__tests__/data/active_campaign_router_output.json @@ -97,5 +97,27 @@ "eventKey": "f8a866fddc721350fdc2fbbd2e5c43a6dddaaa03" } } + }, + { + "batched": false, + "error": "Invalid URL: url", + "metadata": [ + { + "jobId": 5 + } + ], + "destination": { + "Config": { + "apiKey": "fbee74a147828e2932c701d19dc1f2dcfa4ac0048be3aa3a88d427090a59dc1c0fa002f1", + "apiUrl": "https://active.campaigns.rudder.com", + "actid": "476550467", + "eventKey": "f8a866fddc721350fdc2fbbd2e5c43a6dddaaa03" + } + }, + "statTags": { + "errorCategory": "dataValidation", + "errorType": "instrumentation" + }, + "statusCode": 400 } ] diff --git a/test/__tests__/data/algolia_input.json b/test/__tests__/data/algolia_input.json index ce4afa3657..67216fc871 100644 --- a/test/__tests__/data/algolia_input.json +++ b/test/__tests__/data/algolia_input.json @@ -732,5 +732,73 @@ ] } } + }, + { + "message": { + "channel": "web", + "context": { + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.0.0" + }, + "traits": { + "email": "testone@gmail.com", + "firstName": "test", + "lastName": "one" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.0.0" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", + "locale": "en-US", + "ip": "0.0.0.0", + "os": { + "name": "", + "version": "" + }, + "screen": { + "density": 2 + }, + "page": { + "path": "/destinations/ometria", + "referrer": "", + "search": "", + "title": "", + "url": "https://docs.rudderstack.com/destinations/ometria", + "category": "destination", + "initial_referrer": "https://docs.rudderstack.com", + "initial_referring_domain": "docs.rudderstack.com" + } + }, + "type": "track", + "messageId": "84e26acc-56a5-4835-8233-591137fca468", + "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "originalTimestamp": "2019-10-14T09:03:17.562Z", + "anonymousId": "123456", + "event": ["abc", "def"], + "userId": "testuserId1", + "properties": { + "filters": ["field1:hello", "val1:val2"] + }, + "integrations": { + "All": true + }, + "sentAt": "2019-10-14T09:03:22.563Z" + }, + "destination": { + "Config": { + "apiKey": "34d8efa09c5b048bbacc6af157f2e687", + "applicationId": "O2YARRI15I", + "eventTypeSettings": [ + { + "from": "product clicked", + "to": "cLick " + } + ] + } + } } ] diff --git a/test/__tests__/data/algolia_output.json b/test/__tests__/data/algolia_output.json index a4cb9b5640..ed02c274e1 100644 --- a/test/__tests__/data/algolia_output.json +++ b/test/__tests__/data/algolia_output.json @@ -113,5 +113,9 @@ { "statusCode": "400", "message": "Missing required value from \"properties.index\"" + }, + { + "statusCode": "400", + "message": "event name should be a string" } ] diff --git a/test/__tests__/data/am_input.json b/test/__tests__/data/am_input.json index 25b0f9871d..c9fdb2d8a5 100644 --- a/test/__tests__/data/am_input.json +++ b/test/__tests__/data/am_input.json @@ -1,4 +1,101 @@ [ + { + "message": { + "channel": "web", + "context": { + "externalId": [ + { + "id": "lynnanderson@smith.net", + "identifierType": "device_id", + "type": "AM-users" + } + ], + "mappedToDestination": "true", + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.0.0" + }, + "traits": { + "anonymousId": "123456", + "email": "sayan@gmail.com", + "address": { + "country": "India", + "postalCode": 712136, + "state": "WB", + "street": "", + "os_version": "test os" + }, + "ip": "0.0.0.0", + "age": 26 + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.0.0" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", + "locale": "en-US", + "ip": "0.0.0.0", + "os": { + "name": "", + "version": "" + }, + "screen": { + "density": 2 + }, + "page": { + "path": "/destinations/amplitude", + "referrer": "", + "search": "", + "title": "", + "url": "https://docs.rudderstack.com/destinations/amplitude", + "category": "destination", + "initial_referrer": "https://docs.rudderstack.com", + "initial_referring_domain": "docs.rudderstack.com" + } + }, + "traits": { + "anonymousId": "123456", + "email": "sayan@gmail.com", + "city": "kolkata", + "address": { + "country": "India", + "postalCode": 712136, + "state": "WB", + "street": "" + }, + "os_version": "test os", + "ip": "0.0.0.0", + "age": 26 + }, + "type": "identify", + "messageId": "84e26acc-56a5-4835-8233-591137fca468", + "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "originalTimestamp": "2019-10-14T09:03:17.562Z", + "anonymousId": "123456", + "userId": "123456", + "integrations": { + "All": true + }, + "sentAt": "2019-10-14T09:03:22.563Z" + }, + "metadata": { + "jobId": 2 + }, + "destination": { + "Config": { + "apiKey": "abcde", + "groupTypeTrait": "email", + "groupValueTrait": "age", + "traitsToIncrement": [ + { + "traits": "" + } + ] + } + } + }, { "message": { "channel": "web", diff --git a/test/__tests__/data/am_output.json b/test/__tests__/data/am_output.json index 911daee019..a620f5c903 100644 --- a/test/__tests__/data/am_output.json +++ b/test/__tests__/data/am_output.json @@ -55,6 +55,62 @@ "files": {}, "userId": "123456" }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/2/httpapi", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "api_key": "abcde", + "events": [ + { + "os_name": "Chrome", + "os_version": "test os", + "device_model": "Mac", + "platform": "Web", + "device_id": "lynnanderson@smith.net", + "app_name": "RudderLabs JavaScript SDK", + "app_version": "1.0.0", + "language": "en-US", + "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "insert_id": "84e26acc-56a5-4835-8233-591137fca468", + "ip": "0.0.0.0", + "user_properties": { + "initial_referrer": "https://docs.rudderstack.com", + "initial_referring_domain": "docs.rudderstack.com", + "anonymousId": "123456", + "email": "sayan@gmail.com", + "postalCode": 712136, + "state": "WB", + "street": "", + "ip": "0.0.0.0", + "age": 26, + "device_id": "lynnanderson@smith.net" + }, + "event_type": "$identify", + "time": 1571043797562, + "user_id": "123456", + "country": "India", + "city": "kolkata", + "library": "rudderstack" + } + ], + "options": { + "min_id_length": 1 + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "123456" + }, { "version": "1", "type": "REST", diff --git a/test/__tests__/data/criteo_audience.json b/test/__tests__/data/criteo_audience.json new file mode 100644 index 0000000000..5cce1bc3ac --- /dev/null +++ b/test/__tests__/data/criteo_audience.json @@ -0,0 +1,966 @@ +[ + { + "description": "Adding email audienceType", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_2", + "email": "van@email.com", + "identityLink": "abc.com", + "gum": "sdjfds" + } + ] + } + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34894", + "audienceType": "email" + }, + "ID": "sample_destinationId" + } + }, + "output": [ + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34894/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "email", + "identifiers": [ + "alex@email.com", + "amy@email.com", + "van@email.com" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ] + }, + { + "description": "Adding madid audienceType", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_2", + "email": "van@email.com", + "identityLink": "abc.com", + "gum": "sdjfds" + } + ] + } + }, + "context": { + "ip": "14.5.67.21" + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34895", + "audienceType": "madid" + }, + "ID": "sample_destinationId" + } + }, + "output": [ + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34895/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "madid", + "identifiers": [ + "sample_madid", + "sample_madid_1", + "sample_madid_2" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ] + }, + { + "description": "Adding and removing madid audienceType", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_2", + "email": "van@email.com", + "identityLink": "abc.com", + "gum": "sdjfds" + } + ], + "remove": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + } + ] + } + }, + "context": { + "ip": "14.5.67.21" + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "madid" + }, + "ID": "sample_destinationId" + } + }, + "output": [ + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34893/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "madid", + "identifiers": [ + "sample_madid", + "sample_madid_1", + "sample_madid_2" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + }, + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34893/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "remove", + "identifierType": "madid", + "identifiers": [ + "sample_madid" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ] + }, + { + "description": "Adding and removing identityLink audienceType", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_2", + "email": "van@email.com", + "identityLink": "abc.com", + "gum": "sdjfds" + } + ], + "remove": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + } + ] + } + }, + "context": { + "ip": "14.5.67.21" + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "identityLink" + }, + "ID": "sample_destinationId" + } + }, + "output": [ + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34893/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "identityLink", + "identifiers": [ + "text.com", + "yahoo.com", + "abc.com" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + }, + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34893/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "remove", + "identifierType": "identityLink", + "identifiers": [ + "text.com" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ] + }, + { + "description": "Adding and removing gum audienceType", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sample_gum1" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sample_gum2" + }, + { + "madid": "sample_madid_2", + "email": "van@email.com", + "identityLink": "abc.com", + "gum": "sample_gum3" + } + ], + "remove": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sample_gum3" + } + ] + } + }, + "context": { + "ip": "14.5.67.21" + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "gum", + "gumCallerId": "329739" + }, + "ID": "sample_destinationId" + } + }, + "output": [ + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34893/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "gum", + "identifiers": [ + "sample_gum1", + "sample_gum2", + "sample_gum3" + ], + "internalIdentifiers": false, + "gumCallerId": "329739" + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + }, + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34893/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "remove", + "identifierType": "gum", + "identifiers": [ + "sample_gum3" + ], + "internalIdentifiers": false, + "gumCallerId": "329739" + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ] + }, + { + "description": "Unsupported message type", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "message": { + "userId": "user 1", + "type": "identify", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_2", + "email": "van@email.com", + "identityLink": "abc.com", + "gum": "sdjfds" + } + ] + } + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "email" + }, + "ID": "sample_destinationId" + } + }, + "output": { + "error": "Event type identify is not supported" + } + }, + { + "description": "Properties is not present in the message", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "email" + }, + "ID": "sample_destinationId" + }, + "message": { + "type": "audiencelist", + "sentAt": "2021-01-03T17:02:53.195Z", + "userId": "ujjwal27", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "1.12.3" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.1.11", + "namespace": "com.rudderlabs.javascript" + }, + "traits": { + "brand": "John Players", + "price": "15000", + "firstName": "Ujjwal", + "email": "ujjwal@rudderstack.com", + "userId": "ujjwal27" + }, + "locale": "en-US", + "device": { + "token": "token", + "id": "id", + "type": "ios" + }, + "screen": { + "density": 2 + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.11" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0" + }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35", + "originalTimestamp": "2021-01-03T17:02:53.193Z" + } + }, + "output": { + "error": "Message properties is not present. Aborting message." + } + }, + { + "description": "Payload without listData", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "email" + }, + "ID": "sample_destinationId" + }, + "message": { + "event": "add_to_Cart", + "type": "track", + "sentAt": "2021-01-03T17:02:53.195Z", + "userId": "ujjwal27", + "channel": "web", + "properties": { + "brand": "Zara", + "price": "12000" + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.1.11", + "namespace": "com.rudderlabs.javascript" + }, + "locale": "en-US", + "screen": { + "density": 2 + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.11" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0" + }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35", + "originalTimestamp": "2021-01-03T17:02:53.193Z" + } + }, + "output": { + "error": "listData is not present inside properties. Aborting message." + } + }, + { + "description": "Response is empty", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": {} + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "email" + }, + "ID": "sample_destinationId" + } + }, + "output": { + "error": "Payload could not be populated" + } + }, + { + "description": "Message type not given", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "email" + }, + "ID": "sample_destinationId" + }, + "message": { + "event": "add_to_Cart", + "sentAt": "2021-01-03T17:02:53.195Z", + "userId": "ujjwal27", + "channel": "web", + "properties": { + "brand": "Zara", + "price": "12000" + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.1.11", + "namespace": "com.rudderlabs.javascript" + }, + "locale": "en-US", + "screen": { + "density": 2 + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.11" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0" + }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35", + "originalTimestamp": "2021-01-03T17:02:53.193Z" + } + }, + "output": { + "error": "Message Type is not present. Aborting message." + } + }, + { + "description": "Gum caller ID is not present", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "destination": { + "Config": { + "audienceId": "34893", + "audienceType": "gum" + }, + "ID": "sample_destinationId" + }, + "message": { + "event": "add_to_Cart", + "sentAt": "2021-01-03T17:02:53.195Z", + "userId": "ujjwal27", + "type": "audiencelist", + "channel": "web", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sample_gum1" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sample_gum2" + }, + { + "madid": "sample_madid_2", + "email": "van@email.com", + "identityLink": "abc.com", + "gum": "sample_gum3" + } + ] + }, + "brand": "Zara", + "price": "12000" + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.1.11", + "namespace": "com.rudderlabs.javascript" + }, + "locale": "en-US", + "screen": { + "density": 2 + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.11" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0" + }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35", + "originalTimestamp": "2021-01-03T17:02:53.193Z" + } + }, + "output": { + "error": "gumCallerId is required for audience type gum" + } + }, + { + "description": "reuqired properties in listData are not present", + "input": { + "metadata": { + "secret": { + "accessToken": "success_access_token" + } + }, + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_2", + "identityLink": "abc.com", + "gum": "sdjfds" + } + ] + } + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34894", + "audienceType": "email" + }, + "ID": "sample_destinationId" + } + }, + "output": { + "error": "Required property for email type audience is not available in an object" + } + } +] \ No newline at end of file diff --git a/test/__tests__/data/criteo_audience_proxy_input.json b/test/__tests__/data/criteo_audience_proxy_input.json new file mode 100644 index 0000000000..fb93fda18a --- /dev/null +++ b/test/__tests__/data/criteo_audience_proxy_input.json @@ -0,0 +1,223 @@ +[ + { + "request": { + "body": { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34894/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "remove", + "identifierType": "gum", + "identifiers": [ + "sample_gum3" + ], + "internalIdentifiers": false, + "gumCallerId": "329739" + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + } + }, + { + "request": { + "body": { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34895/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "madid", + "identifiers": [ + "sample_madid", + "sample_madid_1", + "sample_madid_2" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + } + }, + { + "request": { + "body": { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34896/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "madid", + "identifiers": [ + "sample_madid", + "sample_madid_1", + "sample_madid_2" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + } + }, + { + "request": { + "body": { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34897/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "madid", + "identifiers": [ + "sample_madid", + "sample_madid_1", + "sample_madid_2" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + } + }, + { + "request": { + "body": { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34898/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "madid", + "identifiers": [ + "sample_madid", + "sample_madid_1", + "sample_madid_2" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + } + }, + { + "request": { + "body": { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34899/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "madid", + "identifiers": [ + "sample_madid", + "sample_madid_1", + "sample_madid_2" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + } + } +] \ No newline at end of file diff --git a/test/__tests__/data/criteo_audience_proxy_output.json b/test/__tests__/data/criteo_audience_proxy_output.json new file mode 100644 index 0000000000..846a1d5cd4 --- /dev/null +++ b/test/__tests__/data/criteo_audience_proxy_output.json @@ -0,0 +1,129 @@ +[ + { + "output": { + "status": 200, + "message": "Request Processed Successfully", + "destinationResponse": { + "response": "", + "status": 200 + } + } + }, + { + "output": { + "status": 401, + "authErrorCategory": "REFRESH_TOKEN", + "destinationResponse": { + "errors": [ + { + "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", + "type": "authorization", + "code": "authorization-token-invalid", + "instance": "/2022-10/audiences/123/contactlist", + "title": "The authorization header is invalid" + } + ] + }, + "message": "The authorization header is invalid during criteo_audience response transformation", + "statTags": { + "destType": "CRITEO_AUDIENCE", + "errorCategory": "network", + "errorType": "aborted", + "feature": "dataDelivery", + "implementation": "native", + "module": "destination" + } + } + }, + { + "output": { + "message": "AudienceId is Invalid. Please Provide Valid AudienceId", + "destinationResponse": { + "response": { + "errors": [ + { + "code": "audience-invalid", + "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", + "type": "authorization" + } + ] + }, + "status": 404 + }, + "statTags": { + "destType": "CRITEO_AUDIENCE", + "errorCategory": "network", + "errorType": "aborted", + "feature": "dataDelivery", + "implementation": "native", + "meta": "instrumentation", + "module": "destination" + }, + "status": 400 + } + }, + { + "output": { + "destinationResponse": { + "response": { + "errors": [ + { + "code": "audience-invalid", + "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", + "type": "authorization" + } + ] + }, + "status": 503 + }, + "message": "Request Failed: during criteo_audience response transformation (Retryable)", + "statTags": { + "destType": "CRITEO_AUDIENCE", + "errorCategory": "network", + "feature": "dataDelivery", + "implementation": "native", + "errorType": "retryable", + "module": "destination" + }, + "status": 500 + } + }, + { + "output": { + "destinationResponse": { + "response": {}, + "status": 429 + }, + "message": "Request Failed: during criteo_audience response transformation - due to Request Limit exceeded, (Throttled)", + "statTags": { + "destType": "CRITEO_AUDIENCE", + "errorCategory": "network", + "errorType": "throttled", + "feature": "dataDelivery", + "implementation": "native", + "module": "destination" + }, + "status": 429 + } + }, + { + "output": { + "destinationResponse":{ + "response": { + "message": "unknown error" + }, + "status": 410 + }, + "message": "Request Failed: during criteo_audience response transformation with status \"410\" due to \"{\"message\":\"unknown error\"}\", (Aborted) ", + "statTags": { + "destType": "CRITEO_AUDIENCE", + "errorCategory": "network", + "errorType": "aborted", + "feature": "dataDelivery", + "implementation": "native", + "module": "destination" + }, + "status": 400 + } + } +] \ No newline at end of file diff --git a/test/__tests__/data/criteo_audience_router_input.json b/test/__tests__/data/criteo_audience_router_input.json new file mode 100644 index 0000000000..af3f4dbe8f --- /dev/null +++ b/test/__tests__/data/criteo_audience_router_input.json @@ -0,0 +1,111 @@ +[ + { + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "email" + }, + "ID": "iwehr83843" + }, + "metadata": { + "secret": { + "accessToken": "success_access_token" + }, + "jobId": 1 + }, + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_2", + "email": "van@email.com", + "identityLink": "abc.com", + "gum": "sdjfds" + } + ] + } + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "timestamp": "2020-02-02T00:23:09.544Z" + } + }, + { + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "madid" + }, + "ID": "iwehr83843" + }, + "metadata": { + "secret": { + "accessToken": "success_access_token" + }, + "jobId": 2 + }, + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_1", + "email": "amy@email.com", + "identityLink": "yahoo.com", + "gum": "sdjfds" + }, + { + "madid": "sample_madid_2", + "email": "van@email.com", + "identityLink": "abc.com", + "gum": "sdjfds" + } + ], + "remove": [ + { + "madid": "sample_madid", + "email": "alex@email.com", + "identityLink": "text.com", + "gum": "sdjfds" + } + ] + } + }, + "context": { + "ip": "14.5.67.21" + }, + "timestamp": "2020-02-02T00:23:09.544Z" + } + } +] \ No newline at end of file diff --git a/test/__tests__/data/criteo_audience_router_output.json b/test/__tests__/data/criteo_audience_router_output.json new file mode 100644 index 0000000000..776634ae4b --- /dev/null +++ b/test/__tests__/data/criteo_audience_router_output.json @@ -0,0 +1,145 @@ +[ + { + "batchedRequest": [ + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34893/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "email", + "identifiers": [ + "alex@email.com", + "amy@email.com", + "van@email.com" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ], + "metadata": [ + { + "jobId": 1, + "secret": { + "accessToken": "success_access_token" + } + } + ], + "batched": false, + "statusCode": 200, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "email" + }, + "ID": "iwehr83843" + } + }, + { + "batchedRequest": [ + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34893/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "add", + "identifierType": "madid", + "identifiers": [ + "sample_madid", + "sample_madid_1", + "sample_madid_2" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + }, + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://api.criteo.com/2022-10/audiences/34893/contactlist", + "headers": { + "Authorization": "Bearer success_access_token", + "Content-Type": "application/json", + "Accept": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "ContactlistAmendment", + "attributes": { + "operation": "remove", + "identifierType": "madid", + "identifiers": [ + "sample_madid" + ], + "internalIdentifiers": false + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ], + "metadata": [ + { + "jobId": 2, + "secret": { + "accessToken": "success_access_token" + } + } + ], + "batched": false, + "statusCode": 200, + "destination": { + "Config": { + "clientId": "abcdef8-f49-4cd6-b4c5-958b3d66d431", + "clientSecret": "sjhdkhfrz6yc9LrRRIPimE9h53jADLccXTykHCcA6eEoFR4rXQg", + "audienceId": "34893", + "audienceType": "madid" + }, + "ID": "iwehr83843" + } + } +] \ No newline at end of file diff --git a/test/__tests__/data/dynamicConfig_input.json b/test/__tests__/data/dynamicConfig_input.json deleted file mode 100644 index 4063c1bc10..0000000000 --- a/test/__tests__/data/dynamicConfig_input.json +++ /dev/null @@ -1,293 +0,0 @@ -{ - "request": { - "body": [ - { - "destination": { - "Config": { - "appId": "{{ message.traits.appId || \"\" }}" - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": [ - { - "from": "{{ message.traits.appId || \"\" }}", - "to": "{{ message.traits.anonymousId || \"1234\" }}" - } - ] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": { - "key2": "hey", - "key3": "{{ message.traits.appId || \"email\" }}", - "key4": [ - { - "from": "{{ message.traits.email || \"email\" }}", - "to": "no" - } - ] - } - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": [ - { "key2": "hey" }, - { "key3": "{{ message.traits.appId || \"email\" }}" }, - { - "key4": [ - { - "from": "{{ message.traits.email || \"email\" }}", - "to": "no" - } - ] - } - ] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": [ - { "key2": "hey" }, - { "key3": "{{ message.traits.appId || \"email\" }}" }, - { - "key4": ["{{ message.traits.email || \"email\" }}", "no"] - } - ] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": false - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": 12345 - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": [ - { "abc": 1234, "def": "{{message.traits.email|| \"email\"}}" }, - "{{message.traits.appId|| \"testAppId\"}}" - ] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": [ - { "abc": 1234, "def": "{{message.traits.email|| 12345 }}" }, - "{{message.traits.appId|| false }}" - ] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath" - } - } - }, - { - "destination": { - "Config": { - "appId": "{{ message.traits.appId || appId }} ", - "email": " {{ message.trait.email || \"test@gmail.com \" }}", - "key": "{{ message.key || \" default value \" }}", - "key1": "{{ message.key1 || \" default value }}", - "key2": "{{ message.key1 || default value \" }}", - "key3": "{{ message.traits.appId || 123.1234 }}", - "key4": ["{{ message.traits.key4 || defaultVal }}", "{{ message.key4 || defaultVal }}"], - "key5": [{ "key2": { "key3": "{{ message.key5 || defaultVal }}" } }], - "key6": [ - [ - { "key2": { "key3": "{{ message.key5 || defaultVal }}" } }, - { "key4": "{{ mesage.traits.key4 || defaultVal }}" } - ], - "defaultVal" - ] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "key": "val", - "key4": "val4", - "key5": "val5", - "context": {}, - "traits": { - "anonymousId": "sampath", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": "{{ event.traits.appId || appId }} ", - "email": " {{ event.trait.email || \"test@gmail.com \" }}", - "key": "{{ event.key || \" default value \" }}", - "key1": "{{ event.key1 || \" default value }}", - "key2": "{{ event.key1 || default value \" }}", - "key3": "{{ message.traits.appId || 123.1234 }}", - "key4": ["{{ event.traits.key4 || defaultVal }}", "{{ event.key4 || defaultVal }}"], - "key5": [{ "key2": { "key3": "{{ event.key5 || defaultVal }}" } }], - "key6": [ - [ - { "key2": { "key3": "{{ event.key5 || defaultVal }}" } }, - { "key4": "{{ evnt.traits.key4 || defaultVal }}" } - ], - "defaultVal" - ] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "key": "val", - "key4": "val4", - "key5": "val5", - "context": {}, - "traits": { - "anonymousId": "sampath", - "appId": "testAppId" - } - } - } - ] - } -} diff --git a/test/__tests__/data/dynamicConfig_output.json b/test/__tests__/data/dynamicConfig_output.json deleted file mode 100644 index 2bdecf0184..0000000000 --- a/test/__tests__/data/dynamicConfig_output.json +++ /dev/null @@ -1,242 +0,0 @@ -[ - { - "destination": { - "Config": { - "appId": "testAppId" - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com" - } - } - }, - { - "destination": { - "Config": { - "appId": [{ "from": "testAppId", "to": "sampath" }] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "email": "sampath@gmail.com" - } - } - }, - { - "destination": { - "Config": { - "appId": { - "key2": "hey", - "key3": "testAppId", - "key4": [{ "from": "sampath@gmail.com", "to": "no" }] - } - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath" - } - } - }, - { - "destination": { - "Config": { - "appId": [ - { "key2": "hey" }, - { "key3": "testAppId" }, - { - "key4": [ - { - "from": "sampath@gmail.com", - "to": "no" - } - ] - } - ] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath" - } - } - }, - { - "destination": { - "Config": { - "appId": [ - { "key2": "hey" }, - { "key3": "testAppId" }, - { - "key4": ["sampath@gmail.com", "no"] - } - ] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath" - } - } - }, - { - "destination": { - "Config": { - "appId": false - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": 12345 - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath", - "email": "sampath@gmail.com", - "appId": "testAppId" - } - } - }, - { - "destination": { - "Config": { - "appId": [{ "abc": 1234, "def": "sampath@gmail.com" }, "testAppId"] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath" - } - } - }, - { - "destination": { - "Config": { - "appId": [{ "abc": 1234, "def": "12345" }, "false"] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath" - } - } - }, - { - "destination": { - "Config": { - "appId": "testAppId", - "email": "test@gmail.com", - "key": "val", - "key1": "default value", - "key2": "default value", - "key3": "123.1234", - "key4": ["defaultVal", "val4"], - "key5": [{ "key2": { "key3": "val5" } }], - "key6": [[{ "key2": { "key3": "defaultVal" } }, { "key4": "defaultVal" }], "defaultVal"] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath" - } - } - }, - { - "destination": { - "Config": { - "appId": "testAppId", - "email": "test@gmail.com", - "key": "val", - "key1": "default value", - "key2": "default value", - "key3": "123.1234", - "key4": ["defaultVal", "val4"], - "key5": [{ "key2": { "key3": "val5" } }], - "key6": [[{ "key2": { "key3": "defaultVal" } }, { "key4": "defaultVal" }], "defaultVal"] - } - }, - "metadata": { - "jobId": 2 - }, - "message": { - "anonymousId": "sampath", - "channel": "web", - "context": {}, - "traits": { - "anonymousId": "sampath" - } - } - } -] diff --git a/test/__tests__/data/ga4.json b/test/__tests__/data/ga4.json index 4f27a0c7e9..c1beaa1b57 100644 --- a/test/__tests__/data/ga4.json +++ b/test/__tests__/data/ga4.json @@ -11509,7 +11509,11 @@ "city": "kolkata", "district": "24pgs" }, - "categoryLevels": ["Furniture", "Bedroom Furniture", "Dressers & Chests"], + "categoryLevels": [ + "Furniture", + "Bedroom Furniture", + "Dressers & Chests" + ], "products": [ { "product_id": "1234", @@ -11517,7 +11521,11 @@ "colour": "red", "shape": "rectangle" }, - "productLevels": ["test1", "test2", "test3"] + "productLevels": [ + "test1", + "test2", + "test3" + ] } ] }, @@ -11799,5 +11807,185 @@ "version": "1", "endpoint": "https://www.google-analytics.com/mp/collect" } - } -] + }, + { + "description": "(gtag) send integer userId", + "input": { + "message": { + "channel": "web", + "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", + "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", + "userId": 34567, + "context": { + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.0.0" + }, + "device": { + "adTrackingEnabled": "false", + "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", + "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", + "manufacturer": "Google", + "model": "AOSP on IA Emulator", + "name": "generic_x86_arm", + "type": "ios", + "attTrackingStatus": 3 + }, + "ip": "0.0.0.0", + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.0.0" + }, + "locale": "en-US", + "os": { + "name": "iOS", + "version": "14.4.1" + }, + "screen": { + "density": 2 + }, + "externalId": [ + { + "type": "ga4AppInstanceId", + "id": "f0dd99b6f979fb551ce583373900f937" + }, + { + "type": "ga4ClientId", + "id": "client_id" + } + ], + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36", + "sessionId": 16678456735 + }, + "type": "track", + "event": "product added", + "properties": { + "currency": "USD", + "price": 2.4, + "quantity": 2, + "client_id": "client@1234", + "products": [ + { + "product_id": "507f1f77bcf86cd799439011", + "name": "Monopoly: 3rd Edition", + "coupon": "SUMMER_FUN", + "category": "Apparel", + "brand": "Google", + "variant": "green", + "price": "19", + "quantity": "2", + "position": "1", + "affiliation": "Google Merchandise Store", + "currency": "USD", + "discount": 2.22, + "item_category2": "Adult", + "item_category3": "Shirts", + "item_category4": "Crew", + "item_category5": "Short sleeve", + "item_list_id": "related_products", + "item_list_name": "Related Products", + "location_id": "L_12345" + } + ] + }, + "integrations": { + "All": true + } + }, + "destination": { + "Config": { + "apiSecret": "QyWKGHj8QhG2L4ePAPiXCA", + "measurementId": "G-T40PE6BET4", + "firebaseAppId": "", + "blockPageViewEvent": false, + "typesOfClient": "gtag", + "extendPageViewParams": false, + "sendUserId": false, + "eventFilteringOption": "disable", + "blacklistedEvents": [ + { + "eventName": "" + } + ], + "whitelistedEvents": [ + { + "eventName": "" + } + ], + "enableServerSideIdentify": true, + "sendLoginSignup": true, + "newOrExistingUserTrait": "firstLogin", + "loginSignupMethod": "method", + "generateLead": true, + "generateLeadValueTrait": "value", + "generateLeadCurrencyTrait": "currency" + }, + "Enabled": true + } + }, + "output": { + "body": { + "XML": {}, + "FORM": {}, + "JSON": { + "events": [ + { + "name": "add_to_cart", + "params": { + "items": [ + { + "index": 1, + "price": 19, + "coupon": "SUMMER_FUN", + "item_id": "507f1f77bcf86cd799439011", + "currency": "USD", + "discount": 2.22, + "quantity": 2, + "item_name": "Monopoly: 3rd Edition", + "item_brand": "Google", + "affiliation": "Google Merchandise Store", + "location_id": "L_12345", + "item_list_id": "related_products", + "item_variant": "green", + "item_category": "Apparel", + "item_category2": "Adult", + "item_category3": "Shirts", + "item_category4": "Crew", + "item_category5": "Short sleeve", + "item_list_name": "Related Products" + } + ], + "price": 2.4, + "value": 4.8, + "currency": "USD", + "quantity": 2, + "session_id": 16678456735, + "engagement_time_msec": 1, + "client_id": "client@1234" + } + } + ], + "client_id": "client_id", + "user_id": "34567", + "non_personalized_ads": true + }, + "JSON_ARRAY": {} + }, + "type": "REST", + "files": {}, + "method": "POST", + "params": { + "api_secret": "QyWKGHj8QhG2L4ePAPiXCA", + "measurement_id": "G-T40PE6BET4" + }, + "headers": { + "HOST": "www.google-analytics.com", + "Content-Type": "application/json" + }, + "version": "1", + "endpoint": "https://www.google-analytics.com/mp/collect" + } + } +] \ No newline at end of file diff --git a/test/__tests__/data/impact_radius.json b/test/__tests__/data/impact.json similarity index 93% rename from test/__tests__/data/impact_radius.json rename to test/__tests__/data/impact.json index 29003eca58..729d1a36cf 100644 --- a/test/__tests__/data/impact_radius.json +++ b/test/__tests__/data/impact.json @@ -514,6 +514,124 @@ } ] }, + { + "description": "Track Call with products array without any custom products mapping", + "input": { + "message": { + "event": "Product Purchased", + "type": "track", + "sentAt": "2021-01-03T17:02:53.195Z", + "userId": "Ujjwalab", + "channel": "web", + "properties": { + "orderId": "9217374917471", + "coupon": "10OFF-ROCKET", + "clickId": "wEWU47yhtzBnU-CTug3:7Wv4UkAzMbzkZ2lTz80", + "products": [ + { + "brand": "zara", + "category": "wearables", + "name": "Monopoly", + "price": 332, + "quantity": 1, + "sku": "G-32" + } + ] + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.1.11", + "namespace": "com.rudderlabs.javascript" + }, + "locale": "en-US", + "screen": { + "density": 2 + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.11" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0" + }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35", + "originalTimestamp": "NOW" + }, + "destination": { + "Config": { + "accountSID": "dfsgertrtff3erfc34rfwf", + "apiKey": "fghsdfgegvcergfvfdfsag", + "campaignId": "23224", + "impactAppId": "2323", + "eventTypeId": "56446", + "enableEmailHashing": true, + "rudderToImpactProperty": [ + { + "from": "properties.profit", + "to": "Money1" + } + ], + "productsMapping": "", + "enableIdentifyEvents": false, + "enablePageEvents": false, + "enableScreenEvents": false, + "actionEventNames": [{ "eventName": "Product Purchased" }], + "installEventNames": [{ "eventName": "App Installed" }] + } + } + }, + "output": [ + { + "body": { + "XML": {}, + "FORM": { + "AppVer": "1.1.11", + "AppName": "RudderLabs JavaScript SDK", + "ClickId": "wEWU47yhtzBnU-CTug3:7Wv4UkAzMbzkZ2lTz80", + "OrderId": "9217374917471", + "ItemSku1": "G-32", + "EventDate": "NOW", + "ItemName1": "Monopoly", + "UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0", + "AppPackage": "1.0.0", + "CampaignId": "23224", + "CustomerId": "Ujjwalab", + "ItemBrand1": "zara", + "ItemPrice1": 332, + "EventTypeId": "56446", + "ImpactAppId": "2323", + "DeviceLocale": "en-US", + "EventTypeCode": "Product Purchased", + "ItemQuantity1": 1, + "ItemCategory1": "wearables", + + "OrderPromoCode": "10OFF-ROCKET", + "CustomProfileId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "JSON": {}, + "JSON_ARRAY": {} + }, + "type": "REST", + "files": {}, + "method": "POST", + "params": {}, + "headers": { + "Content-Type": "application/x-www-form-urlencoded", + "Authorization": "Basic ZGZzZ2VydHJ0ZmYzZXJmYzM0cmZ3ZjpmZ2hzZGZnZWd2Y2VyZ2Z2ZmRmc2Fn" + }, + "version": "1", + "endpoint": "https://api.impact.com/Advertisers/dfsgertrtff3erfc34rfwf/Conversions" + } + ] + }, { "description": "Track Call with products array to test conversion endpoint with a custom products mapping", "input": { diff --git a/test/__tests__/data/impact_radius_router.json b/test/__tests__/data/impact_router.json similarity index 100% rename from test/__tests__/data/impact_radius_router.json rename to test/__tests__/data/impact_router.json diff --git a/test/__tests__/data/klaviyo.json b/test/__tests__/data/klaviyo.json index a08bb2ed38..8abbfb03f7 100644 --- a/test/__tests__/data/klaviyo.json +++ b/test/__tests__/data/klaviyo.json @@ -1,6 +1,6 @@ [ { - "description": "Profile updation call and list and subcribe user", + "description": "Profile updation call and subcribe user", "input": { "destination": { "Config": { @@ -99,33 +99,6 @@ }, "files": {} }, - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://a.klaviyo.com/api/v2/list/XUepkK/members", - "headers": { - "Content-Type": "application/json" - }, - "params": { - "api_key": "pk_b68c7b5163d98807fcb57e6f921216629d" - }, - "body": { - "JSON": { - "profiles": [ - { - "id": "utsabc", - "email": "utsab@rudderstack.com", - "phone_number": "+12 345 578 900" - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - }, { "version": "1", "type": "REST", @@ -405,64 +378,70 @@ "timestamp": "2020-01-21T00:21:34.208Z" } }, - "output": [ - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://a.klaviyo.com/api/v2/list/XUepkK/members", - "headers": { - "Content-Type": "application/json" - }, - "params": { - "api_key": "pk_b68c7b5163d98807fcb57e6f921216629d" - }, - "body": { - "JSON": { - "profiles": [ - { - "email": "utsab@rudderstack.com", - "phone_number": "+12 345 678 900", - "$id": "user123" - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://a.klaviyo.com/api/v2/list/XUepkK/subscribe", + "headers": { + "Content-Type": "application/json" }, - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://a.klaviyo.com/api/v2/list/XUepkK/subscribe", - "headers": { - "Content-Type": "application/json" + "params": { + "api_key": "pk_b68c7b5163d98807fcb57e6f921216629d" + }, + "body": { + "JSON": { + "profiles": [ + { + "email": "utsab@rudderstack.com", + "phone_number": "+12 345 678 900", + "$id": "user123", + "sms_consent": true, + "$consent": "email" + } + ] }, - "params": { - "api_key": "pk_b68c7b5163d98807fcb57e6f921216629d" + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + }, + { + "description": "group call without groupId", + "input": { + "destination": { + "Config": { + "publicApiKey": "WJqij9", + "privateApiKey": "pk_b68c7b5163d98807fcb57e6f921216629d" + } + }, + "message": { + "userId": "user123", + "type": "group", + "groupId": "", + "traits": { + "subscribe": true }, - "body": { - "JSON": { - "profiles": [ - { - "email": "utsab@rudderstack.com", - "phone_number": "+12 345 678 900", - "$id": "user123", - "sms_consent": true, - "$consent": "email" - } - ] + "context": { + "traits": { + "email": "utsab@rudderstack.com", + "phone": "+12 345 678 900", + "consent": "email", + "smsConsent": true }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} + "ip": "14.5.67.21", + "library": { + "name": "http" + } }, - "files": {} + "timestamp": "2020-01-21T00:21:34.208Z" } - ] + }, + "output": { + "error": "groupId is a required field for group events" + } }, { "description": "[Error]: Check for unsupported message type", @@ -595,33 +574,6 @@ }, "files": {} }, - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://a.klaviyo.com/api/v2/list/XUepkK/members", - "headers": { - "Content-Type": "application/json" - }, - "params": { - "api_key": "pk_a68c7b5163d98807fcb57e6f921216629d" - }, - "body": { - "JSON": { - "profiles": [ - { - "id": "batsu", - "email": "batsu@rudderstack.com", - "phone_number": "+12 345 578 900" - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - }, { "version": "1", "type": "REST", @@ -1158,7 +1110,7 @@ } }, { - "description": "Throwing error if list Id is not in the payload", + "description": "Identify call for existing profile details when channel === 'sources'", "input": { "destination": { "Config": { @@ -1170,9 +1122,8 @@ "type": "identify", "sentAt": "2021-01-03T17:02:53.195Z", "userId": "utsabc", - "channel": "web", + "channel": "sources", "context": { - "mappedToDestination": true, "externalId": [ { "identifierType": "$email", @@ -1211,21 +1162,24 @@ { "version": "1", "type": "REST", - "method": "PUT", - "endpoint": "https://a.klaviyo.com/api/v1/person/01G79MV4XVPABNP8G5FSK40QES", + "method": "POST", + "endpoint": "https://a.klaviyo.com/api/identify", "headers": { - "Accept": "application/json" - }, - "params": { - "$id": "utsab@rudderstack.com", - "$email": "utsab@rudderstack.com", - "api_key": "pk_b68c7b5163d98807fcb57e6f921216629d", - "$first_name": "Utsab", - "$last_name": "Chowdhury", - "omega": "omegashenron" + "Content-Type": "application/json", + "Accept": "text/html" }, + "params": {}, "body": { - "JSON": {}, + "JSON": { + "token": "WJqij9", + "properties": { + "$email": "utsab@rudderstack.com", + "omega": "omegashenron", + "$last_name": "Chowdhury", + "$first_name": "Utsab", + "$id": "utsabc" + } + }, "JSON_ARRAY": {}, "XML": {}, "FORM": {} diff --git a/test/__tests__/data/klaviyo_router_output.json b/test/__tests__/data/klaviyo_router_output.json index 7aca672fd3..ea933584f3 100644 --- a/test/__tests__/data/klaviyo_router_output.json +++ b/test/__tests__/data/klaviyo_router_output.json @@ -33,33 +33,6 @@ }, "files": {} }, - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://a.klaviyo.com/api/v2/list/XUepkK/members", - "headers": { - "Content-Type": "application/json" - }, - "params": { - "api_key": "pk_b68c7b5163d98807fcb57e6f921216629d" - }, - "body": { - "JSON": { - "profiles": [ - { - "id": "utsabc", - "email": "utsab@rudderstack.com", - "phone_number": "+12 345 578 900" - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - }, { "version": "1", "type": "REST", diff --git a/test/__tests__/data/lemnisk.json b/test/__tests__/data/lemnisk.json new file mode 100644 index 0000000000..f445a89fd4 --- /dev/null +++ b/test/__tests__/data/lemnisk.json @@ -0,0 +1,1055 @@ +[ + { + "description": "Error: Event Type is required ", + "input": { + "message": { + "userId": "user123", + "event": "Product Reviewed", + "properties": { + "review_body": "Average product, expected much more." + }, + "context": { + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36" + }, + "timestamp": "2020-02-02T00:23:09.544Z", + "messageId": "1578564113557-af022c68-429e-4af4-b99b-2b9174056383" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "http://10.11.36.17:8080/analyze/analyze.php", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + } + }, + "output": { + "error": "Event type is required" + } + }, + { + "description": "Error: Pl Track: Invalid Configuration", + "input": { + "message": { + "type": "track", + "properties": { + "product_id": "ab1234", + "rating": 3, + "review_body": "Average product, expected much more.", + "review_id": "12345" + }, + "event": "Product Reviewed", + "context": { + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.9.1" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36" + }, + "timestamp": "2020-02-02T00:23:09.544Z", + "messageId": "1578564113557-af022c68-429e-4af4-b99b-2b9174056383" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + } + }, + "output": { + "error": "Configuration for Web Mode requires write key and region url" + } + }, + { + "description": "Error: Invalid Configs for Diapi", + "input": { + "message": { + "anonymousId": "anon-id-new", + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + }, + "traits": { + "firstName": "Anant", + "lastName": "jain", + "role": "Manager", + "address": "Flat No 58 ABC building XYZ Area near PQRS , 354408", + "hasPurchased": "yes", + "email": "abc@xyz.com", + "title": "Mr", + "phone": "9876543212", + "state": "Uttar Pradesh", + "zipcode": "243001", + "prospectOrCustomer": "Prospect", + "country": "India", + "website": "abc.com", + "subscriptionStatus": "New" + } + }, + "messageId": "25ea6605-c788-4cab-8fed-2cf0b831c4a8", + "originalTimestamp": "2020-02-02T00:23:09.544Z", + "receivedAt": "2022-08-17T10:40:21.162+05:30", + "request_ip": "[::1]", + "rudderId": "daf823fb-e8d3-413a-8313-d34cd756f968", + "sentAt": "2022-08-17T10:40:21.728+05:30", + "timestamp": "2020-02-02T05:53:08.977+05:30", + "type": "track", + "userId": "identified user id" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "", + "pl": "", + "passKey": "1234", + "apiKey": "", + "diapi": "https://crux.lemnisk.co/v3/data", + "cloudMode": "server", + "srcId": "1", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + } + }, + "output": { + "error": "Configuration for Server Mode requires Api key, Pass Key and region url" + } + }, + { + "description": "Diapi Platform: Track Call", + "input": { + "message": { + "type": "track", + "properties": { + "product_id": "ab1234", + "rating": 3, + "review_body": "Average product, expected much more.", + "review_id": "12345" + }, + "event": "Product Reviewed", + "context": { + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.9.1" + }, + "traits": { + "email": "a@example.com" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36" + }, + "timestamp": "2020-02-02T00:23:09.544Z", + "messageId": "1578564113557-af022c68-429e-4af4-b99b-2b9174056383", + "userId": "user123" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "", + "pl": "", + "passKey": "1234", + "apiKey": "abcd", + "diapi": "https://crux.lemnisk.co/v3/data", + "cloudMode": "server", + "srcId": "1", + "diapiWriteKey": "diapi_write_key" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + } + }, + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://crux.lemnisk.co/v3/data", + "headers": { + "Content-Type": "application/json", + "x-api-passKey": "1234", + "x-api-key": "abcd" + }, + "params": {}, + "body": { + "JSON": { + "type": "track", + "properties": { + "product_id": "ab1234", + "rating": 3, + "review_body": "Average product, expected much more.", + "review_id": "12345" + }, + "WriteKey":"diapi_write_key", + "eventname": "Product Reviewed", + "userId": "user123", + "email": "a@example.com", + "srcid": "1" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "user123" + } + }, + { + "description": "Error: Message type not supported", + "input": { + "message": { + "anonymousId": "anon-id-new", + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + }, + "traits": { + "state": "uttar pradesh" + } + }, + "messageId": "25ea6605-c788-4cab-8fed-2cf0b831c4a8", + "originalTimestamp": "2020-02-02T00:23:09.544Z", + "receivedAt": "2022-08-17T10:40:21.162+05:30", + "request_ip": "[::1]", + "rudderId": "daf823fb-e8d3-413a-8313-d34cd756f968", + "sentAt": "2022-08-17T10:40:21.728+05:30", + "timestamp": "2020-02-02T05:53:08.977+05:30", + "userId": "identified user id", + "type": "Alias" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "http://10.11.36.17:8080/analyze/analyze.php", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + } + }, + "output": { + "error": "Event type alias is not supported in Web Cloud Mode" + } + }, + { + "description": " Page Call -> pl Platform ", + "input": { + "message": { + "anonymousId": "anon-id-new", + "channel": "mobile", + "context": { + "app": { + "build": "4", + "name": "RuddCDN" + }, + "page": { + "referrer": "google.com" + }, + "device": { + "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", + "name": "generic_x86_arm" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.6" + }, + "os": { + "name": "Android", + "version": "9" + }, + "timezone": "Asia/Kolkata", + "traits": { + "customProp": "customValue" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + }, + "name": "Home", + "category": "Profile", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "properties": { + "title": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "receivedAt": "2020-09-29T14:50:43.005+05:30", + "sentAt": "2020-09-28T19:53:44.998Z", + "timestamp": "2020-09-29T14:50:29.907+05:30", + "type": "page" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "http://10.11.36.17:8080/analyze/analyze.php", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + } + }, + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "http://10.11.36.17:8080/analyze/analyze.php", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "type": "page", + "context": { + "app": { + "build": "4", + "name": "RuddCDN" + }, + "page": { + "referrer": "google.com" + }, + "device": { + "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", + "name": "generic_x86_arm" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.6" + }, + "os": { + "name": "Android", + "version": "9" + }, + "timezone": "Asia/Kolkata", + "traits": { + "customProp": "customValue" + }, + "userAgent": { + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + } + }, + "properties": { + "title": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "name": "Home", + "id": "anon-id-new", + "userId": "anon-id-new", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "writeKey": "pl_writeKey" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "anon-id-new" + } + }, + { + "description": " Identify Call -> pl Platform ", + "input": { + "message": { + "anonymousId": "anon-id-new", + "channel": "mobile", + "context": { + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + }, + "event": "Visited Home", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "traits": { + "name": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "receivedAt": "2020-09-29T14:50:43.005+05:30", + "sentAt": "2020-09-28T19:53:44.998Z", + "timestamp": "2020-09-29T14:50:29.907+05:30", + "type": "identify" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "http://10.11.36.17:8080/analyze/analyze.php", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + } + }, + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "http://10.11.36.17:8080/analyze/analyze.php", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "type": "identify", + "context": { + "userAgent": { + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + } + }, + "customerProperties": { + "name": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "id": "anon-id-new", + "userId": "anon-id-new", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "writeKey": "pl_writeKey" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "anon-id-new" + } + }, + { + "description": " Track Call -> pl Platform ", + "input": { + "message": { + "anonymousId": "anon-id-new", + "channel": "mobile", + "context": { + "app": { + "build": "4", + "name": "RuddCDN" + }, + "page": { + "referrer": "google.com" + }, + "device": { + "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", + "name": "generic_x86_arm" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.6" + }, + "os": { + "name": "Android", + "version": "9" + }, + "timezone": "Asia/Kolkata", + "traits": { + "customProp": "customValue" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + }, + "event": "Visited Home", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "properties": { + "title": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "receivedAt": "2020-09-29T14:50:43.005+05:30", + "sentAt": "2020-09-28T19:53:44.998Z", + "timestamp": "2020-09-29T14:50:29.907+05:30", + "type": "track" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "http://10.11.36.17:8080/analyze/analyze.php", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + } + }, + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "http://10.11.36.17:8080/analyze/analyze.php", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "type": "track", + "context": { + "app": { + "build": "4", + "name": "RuddCDN" + }, + "page": { + "referrer": "google.com" + }, + "device": { + "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", + "name": "generic_x86_arm" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.6" + }, + "os": { + "name": "Android", + "version": "9" + }, + "timezone": "Asia/Kolkata", + "traits": { + "customProp": "customValue" + }, + "userAgent": { + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + } + }, + "properties": { + "title": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "event": "Visited Home", + "id": "anon-id-new", + "userId": "anon-id-new", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "writeKey": "pl_writeKey" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "anon-id-new" + } + } +] \ No newline at end of file diff --git a/test/__tests__/data/lemnisk_router.json b/test/__tests__/data/lemnisk_router.json new file mode 100644 index 0000000000..7e1559baf6 --- /dev/null +++ b/test/__tests__/data/lemnisk_router.json @@ -0,0 +1,693 @@ +[ + { + "description": "Lemnisk batch events", + "input": [ + { + "message": { + "anonymousId": "anon-id-new", + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "type": "identify" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "", + "pl": "https://crux.lemnisk.co/v2/data", + "passKey": "", + "apiKey": "", + "diapi": " ", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + }, + "metadata": { + "jobId": 1 + } + }, + { + "message": { + "anonymousId": "anon-id-new", + "channel": "mobile", + "context": { + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + }, + "event": "Visited Home", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "traits": { + "name": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "receivedAt": "2020-09-29T14:50:43.005+05:30", + "sentAt": "2020-09-28T19:53:44.998Z", + "timestamp": "2020-09-29T14:50:29.907+05:30", + "type": "identify" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "http://10.11.36.17:8080/analyze/analyze.php", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + }, + "metadata": { + "anonymousId": "12345", + "destinationId": "1ZQVSU9SXNg6KYgZALaqjAO3PIL", + "destinationType": "DISCORD", + "jobId": 123, + "messageId": "4aaecff2-a513-4bbf-9824-c471f4ac9777", + "sourceId": "1YhwKyDcKstudlGxkeN5p2wgsrp" + } + }, + { + "message": { + "anonymousId": "anon-id-new", + "channel": "mobile", + "context": { + "app": { + "build": "4", + "name": "RuddCDN" + }, + "page": { + "referrer": "google.com" + }, + "device": { + "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", + "name": "generic_x86_arm" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.6" + }, + "os": { + "name": "Android", + "version": "9" + }, + "timezone": "Asia/Kolkata", + "traits": { + "customProp": "customValue" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + }, + "event": "Visited Home", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "properties": { + "title": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "receivedAt": "2020-09-29T14:50:43.005+05:30", + "sentAt": "2020-09-28T19:53:44.998Z", + "timestamp": "2020-09-29T14:50:29.907+05:30", + "type": "track" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "http://10.11.36.17:8080/analyze/analyze.php", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + }, + "metadata": { + "anonymousId": "00000000000000000000000000", + "destinationId": "1ZQVSU9SXNg6KYgZALaqjAO3PIL", + "destinationType": "DISCORD", + "jobId": 129, + "messageId": "8b8d5937-09bc-49dc-a35e-8cd6370575f8", + "sourceId": "1YhwKyDcKstudlGxkeN5p2wgsrp" + } + } + ], + "output": [ + { + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "", + "pl": "https://crux.lemnisk.co/v2/data", + "passKey": "", + "apiKey": "", + "diapi": " ", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + }, + "metadata": [ + { + "jobId": 1 + } + ], + "statTags": { + "errorCategory": "dataValidation", + "errorType": "configuration" + }, + "batched": false, + "statusCode": 400, + "error": "Configuration for Web Mode requires write key and region url" + }, + { + "batchedRequest": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "http://10.11.36.17:8080/analyze/analyze.php", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "type": "identify", + "context": { + "userAgent": { + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + } + }, + "customerProperties": { + "name": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "id": "anon-id-new", + "userId": "anon-id-new", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "writeKey": "pl_writeKey" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "anon-id-new" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "http://10.11.36.17:8080/analyze/analyze.php", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + }, + "metadata": [ + { + "anonymousId": "12345", + "destinationId": "1ZQVSU9SXNg6KYgZALaqjAO3PIL", + "destinationType": "DISCORD", + "jobId": 123, + "messageId": "4aaecff2-a513-4bbf-9824-c471f4ac9777", + "sourceId": "1YhwKyDcKstudlGxkeN5p2wgsrp" + } + ], + "batched": false, + "statusCode": 200 + }, + { + "batchedRequest": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "http://10.11.36.17:8080/analyze/analyze.php", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "type": "track", + "context": { + "app": { + "build": "4", + "name": "RuddCDN" + }, + "page": { + "referrer": "google.com" + }, + "device": { + "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", + "name": "generic_x86_arm" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.6" + }, + "os": { + "name": "Android", + "version": "9" + }, + "timezone": "Asia/Kolkata", + "traits": { + "customProp": "customValue" + }, + "userAgent": { + "ua": "Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)" + } + }, + "properties": { + "title": "Home | RudderStack", + "url": "http://www.rudderstack.com" + }, + "event": "Visited Home", + "id": "anon-id-new", + "userId": "anon-id-new", + "messageId": "1601322811899-d9c7dd00-50dc-4364-95c8-e89423eb3cfb", + "originalTimestamp": "2020-09-28T19:53:31.900Z", + "writeKey": "pl_writeKey" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "anon-id-new" + }, + "destination": { + "id": "2JAdls99p6UxoFNSKGwvh0aIt7E", + "name": "Lemnisk Marketing Automation", + "enabled": true, + "Config": { + "plWriteKey": "pl_writeKey", + "pl": "http://10.11.36.17:8080/analyze/analyze.php", + "passKey": "", + "apiKey": "", + "diapi": "", + "cloudMode": "web", + "srcId": "", + "diapiWriteKey": "" + }, + "destinationDefinition": { + "config": { + "transformAt": "processor", + "transformAtV1": "processor", + "saveDestinationResponse": true, + "includeKeys": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "srcId" + ], + "excludeKeys": [], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative", + "flutter", + "cordova", + "warehouse" + ], + "supportedMessageTypes": [ + "track", + "identify", + "page" + ], + "destConfig": { + "defaultConfig": [ + "apiKey", + "passKey", + "cloudMode", + "diapi", + "pl", + "diapiWriteKey", + "plWriteKey", + "deviceModeWriteKey", + "srcId" + ] + }, + "secretKeys": [ + "apiKey", + "passKey", + "plWriteKey", + "diapiWriteKey" + ] + }, + "responseRules": null, + "id": "1j9dYVEplxUC5swbXkpK9fYT7uk", + "name": "LEMNISK_MARKETING_AUTOMATION", + "displayName": "Lemnisk Marketing Automation", + "createdAt": "2022-12-12T21:58:08.637Z" + }, + "rootStore": null, + "isProcessorEnabled": true + }, + "metadata": [ + { + "anonymousId": "00000000000000000000000000", + "destinationId": "1ZQVSU9SXNg6KYgZALaqjAO3PIL", + "destinationType": "DISCORD", + "jobId": 129, + "messageId": "8b8d5937-09bc-49dc-a35e-8cd6370575f8", + "sourceId": "1YhwKyDcKstudlGxkeN5p2wgsrp" + } + ], + "batched": false, + "statusCode": 200 + } + ] + } +] \ No newline at end of file diff --git a/test/__tests__/data/mailchimp_input.json b/test/__tests__/data/mailchimp_input.json index 5f9ed8edc4..9c7f9daf71 100644 --- a/test/__tests__/data/mailchimp_input.json +++ b/test/__tests__/data/mailchimp_input.json @@ -883,7 +883,257 @@ "sentAt": "2019-11-15T10:22:37Z", "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", "timestamp": "2019-11-15T15:52:32+05:30", + "type": "group", + "userId": "userId12345" + } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "zesrxdthfcjg345yruikyhntbgrafvd", + "audienceId": "df42a82d07", + "datacenterId": "us20" + }, + "Enabled": true, + "Transformations": [] + }, + "message": { + "anonymousId": "userId12345", + "channel": "web", + "context": { + "traits": { + "anonymousId": "userId12345", + "email": "bob.dole@initech.com" + } + }, + "properties": { + "brand": "Aster", + "product": "Garments" + }, + "messageId": "6d1f3ca8-e2d0-4d34-9926-44596171af0c", + "originalTimestamp": "2019-11-15T10:26:53Z", + "receivedAt": "2019-11-15T15:56:58+05:30", + "sentAt": "2019-11-15T10:26:58Z", + "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", + "timestamp": "2019-11-15T15:56:53+05:30", + "type": "track", + "event": "local testing", + "userId": "userId12345" + } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "zesrxdthfcjg345yruikyhntbgrafvd", + "audienceId": "df42a82d07", + "datacenterId": "us20" + }, + "Enabled": true, + "Transformations": [] + }, + "message": { + "anonymousId": "userId12345", + "channel": "web", + "context": { + "traits": { + "anonymousId": "userId12345", + "email": "bob.dole@initech.com" + } + }, + "properties": { + "brand": "Aster", + "product": "Garments", + "isSyncing": false + }, + "messageId": "6d1f3ca8-e2d0-4d34-9926-44596171af0c", + "originalTimestamp": "2019-11-15T10:26:53Z", + "receivedAt": "2019-11-15T15:56:58+05:30", + "sentAt": "2019-11-15T10:26:58Z", + "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", + "timestamp": "2019-11-15T15:56:53+05:30", + "type": "track", + "event": "local testing", + "userId": "userId12345" + } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "zesrxdthfcjg345yruikyhntbgrafvd", + "audienceId": "df42a82d07", + "datacenterId": "us20" + }, + "Enabled": true, + "Transformations": [] + }, + "message": { + "anonymousId": "userId12345", + "channel": "web", + "context": { + "traits": { + "anonymousId": "userId12345" + } + }, + "messageId": "6d1f3ca8-e2d0-4d34-9926-44596171af0c", + "originalTimestamp": "2019-11-15T10:26:53Z", + "receivedAt": "2019-11-15T15:56:58+05:30", + "sentAt": "2019-11-15T10:26:58Z", + "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", + "timestamp": "2019-11-15T15:56:53+05:30", + "type": "track", + "event": "local testing", + "userId": "userId12345" + } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "zesrxdthfcjg345yruikyhntbgrafvd", + "audienceId": "df42a82d07", + "datacenterId": "us20" + }, + "Enabled": true, + "Transformations": [] + }, + "message": { + "anonymousId": "userId12345", + "channel": "web", + "context": { + "traits": { + "anonymousId": "userId12345", + "email": "bob.dole@initech.com" + } + }, + "properties": { + "brand": "Aster", + "product": "Garments", + "isSyncing": false + }, + "messageId": "6d1f3ca8-e2d0-4d34-9926-44596171af0c", + "originalTimestamp": "2019-11-15T10:26:53Z", + "receivedAt": "2019-11-15T15:56:58+05:30", + "sentAt": "2019-11-15T10:26:58Z", + "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", + "timestamp": "2019-11-15T15:56:53+05:30", + "type": "track", + "userId": "userId12345" + } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "zesrxdthfcjg345yruikyhntbgrafvd", + "audienceId": "df42a82d07", + "datacenterId": "us20" + }, + "Enabled": true, + "Transformations": [] + }, + "message": { + "anonymousId": "userId12345", + "channel": "web", + "context": { + "traits": { + "anonymousId": "userId12345", + "email": "bob.dole@initech.com" + } + }, + "messageId": "6d1f3ca8-e2d0-4d34-9926-44596171af0c", + "originalTimestamp": "2019-11-15T10:26:53Z", + "receivedAt": "2019-11-15T15:56:58+05:30", + "sentAt": "2019-11-15T10:26:58Z", + "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", + "timestamp": "2019-11-15T15:56:53+05:30", + "type": "track", + "event": "local testing", + "userId": "userId12345" + } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "zesrxdthfcjg345yruikyhntbgrafvd", + "audienceId": "df42a82d07", + "datacenterId": "us20" + }, + "Enabled": true, + "Transformations": [] + }, + "message": { + "anonymousId": "userId12345", + "channel": "web", + "context": { + "traits": { + "anonymousId": "userId12345", + "email": "bob.dole@initech.com" + } + }, + "properties": { + "brand": "Aster", + "product": "Garments", + "isSyncing": false, + "products": [ + { + "product_id": "123", + "price": "14" + }, + { + "product_id": "123", + "price": 14 + } + ], + "purchased": false + }, + "messageId": "6d1f3ca8-e2d0-4d34-9926-44596171af0c", + "originalTimestamp": "2019-11-15T10:26:53Z", + "receivedAt": "2019-11-15T15:56:58+05:30", + "sentAt": "2019-11-15T10:26:58Z", + "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", + "timestamp": "2019-11-15T15:56:53+05:30", "type": "track", + "event": "local testing", "userId": "userId12345" } } diff --git a/test/__tests__/data/mailchimp_output.json b/test/__tests__/data/mailchimp_output.json index 39a5eb6970..6221318154 100644 --- a/test/__tests__/data/mailchimp_output.json +++ b/test/__tests__/data/mailchimp_output.json @@ -304,6 +304,116 @@ "Enabled": true, "Transformations": [] }, - "error": "message type track is not supported" + "error": "message type group is not supported" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://us20.api.mailchimp.com/3.0/lists/df42a82d07/members/48cd6232dc124497369f59c33d3eb4ab/events", + "headers": { + "Content-Type": "application/json", + "Authorization": "Basic YXBpS2V5Onplc3J4ZHRoZmNqZzM0NXlydWlreWhudGJncmFmdmQ=" + }, + "params": {}, + "body": { + "JSON": { + "name": "local_testing", + "occurred_at": "2019-11-15T10:26:53+00:00", + "properties": { + "brand": "Aster", + "product": "Garments" + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "audienceId": "df42a82d07" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://us20.api.mailchimp.com/3.0/lists/df42a82d07/members/48cd6232dc124497369f59c33d3eb4ab/events", + "headers": { + "Content-Type": "application/json", + "Authorization": "Basic YXBpS2V5Onplc3J4ZHRoZmNqZzM0NXlydWlreWhudGJncmFmdmQ=" + }, + "params": {}, + "body": { + "JSON": { + "name": "local_testing", + "occurred_at": "2019-11-15T10:26:53+00:00", + "is_syncing": false, + "properties": { + "brand": "Aster", + "product": "Garments" + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "audienceId": "df42a82d07" + }, + { + "error": "Email is required for track" + }, + { + "error": "Missing required value from \"event\"" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://us20.api.mailchimp.com/3.0/lists/df42a82d07/members/48cd6232dc124497369f59c33d3eb4ab/events", + "headers": { + "Content-Type": "application/json", + "Authorization": "Basic YXBpS2V5Onplc3J4ZHRoZmNqZzM0NXlydWlreWhudGJncmFmdmQ=" + }, + "params": {}, + "body": { + "JSON": { + "name": "local_testing", + "occurred_at": "2019-11-15T10:26:53+00:00" + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "audienceId": "df42a82d07" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://us20.api.mailchimp.com/3.0/lists/df42a82d07/members/48cd6232dc124497369f59c33d3eb4ab/events", + "headers": { + "Content-Type": "application/json", + "Authorization": "Basic YXBpS2V5Onplc3J4ZHRoZmNqZzM0NXlydWlreWhudGJncmFmdmQ=" + }, + "params": {}, + "body": { + "JSON": { + "name": "local_testing", + "occurred_at": "2019-11-15T10:26:53+00:00", + "is_syncing": false, + "properties": { + "brand": "Aster", + "product": "Garments", + "products": "[{\"product_id\":\"123\",\"price\":\"14\"},{\"product_id\":\"123\",\"price\":14}]", + "purchased": "false" + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "audienceId": "df42a82d07" } ] diff --git a/test/__tests__/data/mailchimp_router_input.json b/test/__tests__/data/mailchimp_router_input.json index e5b0ab9f54..71b5e8b4fd 100644 --- a/test/__tests__/data/mailchimp_router_input.json +++ b/test/__tests__/data/mailchimp_router_input.json @@ -196,5 +196,152 @@ "type": "identify", "userId": "userId12345" } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "94f71917d8522770c97449b0c90caa4c-us20", + "audienceId": "df42a82d07", + "datacenterId": "us20", + "enableMergeFields": true + }, + "Enabled": true, + "Transformations": [] + }, + "metadata": { + "jobId": 5 + }, + "message": { + "anonymousId": "userId12345", + "channel": "web", + "context": { + "traits": { + "anonymousId": "userId12345", + "email": "bob.dole@initech.com" + } + }, + "properties": { + "brand": "Aster", + "product": "Garments" + }, + "messageId": "6d1f3ca8-e2d0-4d34-9926-44596171af0c", + "originalTimestamp": "2019-11-15T10:26:53Z", + "receivedAt": "2019-11-15T15:56:58+05:30", + "sentAt": "2019-11-15T10:26:58Z", + "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", + "timestamp": "2019-11-15T15:56:53+05:30", + "type": "track", + "event": "local testing", + "userId": "userId12345" + } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "94f71917d8522770c97449b0c90caa4c-us20", + "audienceId": "df42a82d07", + "datacenterId": "us20", + "enableMergeFields": true + }, + "Enabled": true, + "Transformations": [] + }, + "metadata": { + "jobId": 6 + }, + "message": { + "anonymousId": "userId12345", + "channel": "web", + "context": { + "traits": { + "anonymousId": "userId12345", + "email": "bob.dole@initech.com" + } + }, + "properties": { + "brand": "Aster", + "product": "Garments", + "is_syncing": false + }, + "messageId": "6d1f3ca8-e2d0-4d34-9926-44596171af0c", + "originalTimestamp": "2019-11-15T10:26:53Z", + "receivedAt": "2019-11-15T15:56:58+05:30", + "sentAt": "2019-11-15T10:26:58Z", + "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", + "timestamp": "2019-11-15T15:56:53+05:30", + "type": "track", + "userId": "userId12345" + } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "94f71917d8522770c97449b0c90caa4c-us20", + "audienceId": "df42a82d07", + "datacenterId": "us20", + "enableMergeFields": true + }, + "Enabled": true, + "Transformations": [] + }, + "metadata": { + "jobId": 7 + }, + "message": { + "anonymousId": "userId12345", + "channel": "web", + "context": { + "traits": { + "anonymousId": "userId12345", + "email": "bob.dole@initech.com" + } + }, + "properties": { + "brand": "Aster", + "product": "Garments", + "isSyncing": false, + "products": [ + { + "product_id": "123", + "price": "14" + }, + { + "product_id": "123", + "price": 14 + } + ], + "purchased": false + }, + "messageId": "6d1f3ca8-e2d0-4d34-9926-44596171af0c", + "originalTimestamp": "2019-11-15T10:26:53Z", + "receivedAt": "2019-11-15T15:56:58+05:30", + "sentAt": "2019-11-15T10:26:58Z", + "source_id": "1TdhTcwsUVOeEMWyPUpQIgF3pYr", + "timestamp": "2019-11-15T15:56:53+05:30", + "type": "track", + "event": "local testing", + "userId": "userId12345" + } } ] diff --git a/test/__tests__/data/mailchimp_router_output.json b/test/__tests__/data/mailchimp_router_output.json index 6574285ede..5aa4c9f8c7 100644 --- a/test/__tests__/data/mailchimp_router_output.json +++ b/test/__tests__/data/mailchimp_router_output.json @@ -66,6 +66,144 @@ "Transformations": [] } }, + { + "batchedRequest": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://us20.api.mailchimp.com/3.0/lists/df42a82d07/members/48cd6232dc124497369f59c33d3eb4ab/events", + "headers": { + "Content-Type": "application/json", + "Authorization": "Basic YXBpS2V5Ojk0ZjcxOTE3ZDg1MjI3NzBjOTc0NDliMGM5MGNhYTRjLXVzMjA=" + }, + "params": {}, + "body": { + "JSON": { + "name": "local_testing", + "occurred_at": "2019-11-15T10:26:53+00:00", + "properties": { + "brand": "Aster", + "product": "Garments" + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "audienceId": "df42a82d07" + }, + "metadata": [ + { + "jobId": 5 + } + ], + "batched": false, + "statusCode": 200, + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "94f71917d8522770c97449b0c90caa4c-us20", + "audienceId": "df42a82d07", + "datacenterId": "us20", + "enableMergeFields": true + }, + "Enabled": true, + "Transformations": [] + } + }, + { + "batchedRequest": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://us20.api.mailchimp.com/3.0/lists/df42a82d07/members/48cd6232dc124497369f59c33d3eb4ab/events", + "headers": { + "Content-Type": "application/json", + "Authorization": "Basic YXBpS2V5Ojk0ZjcxOTE3ZDg1MjI3NzBjOTc0NDliMGM5MGNhYTRjLXVzMjA=" + }, + "params": {}, + "body": { + "JSON": { + "name": "local_testing", + "occurred_at": "2019-11-15T10:26:53+00:00", + "is_syncing": false, + "properties": { + "brand": "Aster", + "product": "Garments", + "products": "[{\"product_id\":\"123\",\"price\":\"14\"},{\"product_id\":\"123\",\"price\":14}]", + "purchased": "false" + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "audienceId": "df42a82d07" + }, + "metadata": [ + { + "jobId": 7 + } + ], + "batched": false, + "statusCode": 200, + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "94f71917d8522770c97449b0c90caa4c-us20", + "audienceId": "df42a82d07", + "datacenterId": "us20", + "enableMergeFields": true + }, + "Enabled": true, + "Transformations": [] + } + }, + { + "destination": { + "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", + "Name": "test-mc", + "DestinationDefinition": { + "ID": "1SujZGrVEPqYmpUJcV4vSl9tfxn", + "Name": "MC", + "DisplayName": "MailChimp" + }, + "Config": { + "apiKey": "94f71917d8522770c97449b0c90caa4c-us20", + "audienceId": "df42a82d07", + "datacenterId": "us20", + "enableMergeFields": true + }, + "Enabled": true, + "Transformations": [] + }, + "metadata": [ + { + "jobId": 6 + } + ], + "batched": false, + "statusCode": 400, + "error": "Missing required value from \"event\"", + "statTags": { + "errorCategory": "dataValidation", + "errorType": "instrumentation" + } + }, { "destination": { "ID": "1Tdi0lpXwSVwXG1lcdP2pXHKrJ6", diff --git a/test/__tests__/data/optimizely_fullstack.json b/test/__tests__/data/optimizely_fullstack.json new file mode 100644 index 0000000000..3798523b1d --- /dev/null +++ b/test/__tests__/data/optimizely_fullstack.json @@ -0,0 +1,488 @@ +[ + { + "description": "Invalid Configuration (missing sdk key)", + "input": { + "message": { + "type": "track", + "channel": "web", + "event": "Product Added", + "properties": {}, + "context": {}, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "baseUrl": "https://example.com", + "trackKnownUsers": false, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + }, + "output": { + "error": "SDK key is required" + } + }, + { + "description": "Invalid Configuration (missing bsase url)", + "input": { + "message": { + "type": "track", + "channel": "web", + "event": "Product Added", + "properties": {}, + "context": {}, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "trackKnownUsers": false, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + }, + "output": { + "error": "Base url is required" + } + }, + { + "description": "Invalid Configuration (Track known users toggle is on and userId is missing in request)", + "input": { + "message": { + "type": "track", + "channel": "web", + "event": "Product Added", + "properties": { "price": 999, "quantity": 1 }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + }, + "output": { + "error": "RudderStack will only track users associated with a userId when the trackKnownUsers setting is enabled" + } + }, + { + "description": "Invalid Configuration (Track known users toggle is off and anonymousId is missing in request)", + "input": { + "message": { + "type": "track", + "channel": "web", + "event": "Product Added", + "properties": { "price": 999, "quantity": 1 }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": false, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + }, + "output": { + "error": "AnonymousId is required when trackKnownUsers setting is disabled" + } + }, + { + "description": "Track call without event", + "input": { + "message": { + "type": "track", + "channel": "web", + "properties": {}, + "context": {}, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": false, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + }, + "output": { + "error": "Event name is required" + } + }, + { + "description": "Track call with userId", + "input": { + "message": { + "type": "track", + "channel": "web", + "event": "Product Added", + "userId": "test123", + "properties": { "price": 999, "quantity": 1 }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + }, + "output": { + "body": { + "FORM": {}, + "JSON": { + "userId": "test123", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { "price": 999, "quantity": 1 } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Product%20Added", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + } + }, + { + "description": "Track call with anonymousId", + "input": { + "message": { + "type": "track", + "channel": "web", + "event": "Product Added", + "properties": { "price": 999, "quantity": 1 }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": false, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + }, + "output": { + "body": { + "FORM": {}, + "JSON": { + "userId": "97c46c81-3140-456d-b2a9-690d70aaca35", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { "price": 999, "quantity": 1 } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Product%20Added", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + } + }, + { + "description": "Page call with Track Categorized Pages is enabled", + "input": { + "message": { + "type": "page", + "channel": "web", + "userId": "test123", + "category": "food", + "properties": { + "url": "https://www.google.com/", + "title": "Google home" + }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + }, + "output": [ + { + "body": { + "FORM": {}, + "JSON": { + "userId": "test123", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { + "url": "https://www.google.com/", + "title": "Google home" + } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Viewed%20food%20page", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + } + ] + }, + { + "description": "Page call with Track Named Pages is enabled", + "input": { + "message": { + "type": "page", + "channel": "web", + "userId": "test123", + "name": "Thank You", + "properties": { + "url": "https://www.google.com/", + "title": "Google home" + }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": false, + "trackNamedPages": true + } + } + }, + "output": [ + { + "body": { + "FORM": {}, + "JSON": { + "userId": "test123", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { + "url": "https://www.google.com/", + "title": "Google home" + } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Viewed%20Thank%20You%20page", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + } + ] + }, + { + "description": "Page call with both Track Categorized Pages and Track Named Pages toggles are enabled", + "input": { + "message": { + "type": "page", + "channel": "web", + "userId": "test123", + "category": "Docs", + "name": "Index", + "properties": { + "url": "https://www.google.com/", + "title": "Google home" + }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + }, + "output": [ + { + "body": { + "FORM": {}, + "JSON": { + "userId": "test123", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { + "url": "https://www.google.com/", + "title": "Google home" + } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Viewed%20Docs%20page", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + }, + { + "body": { + "FORM": {}, + "JSON": { + "userId": "test123", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { + "url": "https://www.google.com/", + "title": "Google home" + } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Viewed%20Index%20page", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + } + ] + }, + { + "description": "Screen call", + "input": { + "message": { + "type": "screen", + "channel": "web", + "userId": "test123", + "name": "Main", + "properties": { + "url": "https://www.google.com/", + "title": "Google Main" + }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": false, + "trackNamedPages": true + } + } + }, + "output": { + "body": { + "FORM": {}, + "JSON": { + "userId": "test123", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { + "url": "https://www.google.com/", + "title": "Google Main" + } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Viewed%20Main%20screen", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + } + } +] diff --git a/test/__tests__/data/optimizely_fullstack_router.json b/test/__tests__/data/optimizely_fullstack_router.json new file mode 100644 index 0000000000..1d4edceb54 --- /dev/null +++ b/test/__tests__/data/optimizely_fullstack_router.json @@ -0,0 +1,228 @@ +[ + { + "input": [ + { + "message": { + "type": "track", + "channel": "web", + "event": "Product Added", + "userId": "test123", + "properties": { "price": 999, "quantity": 1 }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + }, + "metadata": { + "jobId": 1 + } + }, + { + "message": { + "type": "page", + "channel": "web", + "userId": "test123", + "category": "Docs", + "name": "Index", + "properties": { + "url": "https://www.google.com/", + "title": "Google home" + }, + "context": { "traits": { "firstName": "John", "age": 27 } }, + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + }, + "metadata": { + "jobId": 2 + } + }, + { + "message": { + "type": "track", + "channel": "web", + "event": "Product Added", + "properties": {}, + "context": {}, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "trackKnownUsers": false, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + }, + "metadata": { + "jobId": 3 + } + } + ], + "output": [ + { + "batched": false, + "batchedRequest": { + "body": { + "FORM": {}, + "JSON": { + "userId": "test123", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { "price": 999, "quantity": 1 } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Product%20Added", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + }, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + }, + "metadata": [ + { + "jobId": 1 + } + ], + "statusCode": 200 + }, + { + "batched": false, + "batchedRequest": [ + { + "body": { + "FORM": {}, + "JSON": { + "userId": "test123", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { + "url": "https://www.google.com/", + "title": "Google home" + } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Viewed%20Docs%20page", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + }, + { + "body": { + "FORM": {}, + "JSON": { + "userId": "test123", + "userAttributes": { "firstName": "John", "age": 27 }, + "eventTags": { + "url": "https://www.google.com/", + "title": "Google home" + } + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://example.com/v1/track?eventKey=Viewed%20Index%20page", + "files": {}, + "headers": { + "Content-Type": "application/json", + "X-Optimizely-SDK-Key": "test-sdk-key" + }, + "method": "POST", + "params": {}, + "type": "REST", + "version": "1" + } + ], + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "baseUrl": "https://example.com", + "trackKnownUsers": true, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + }, + "metadata": [ + { + "jobId": 2 + } + ], + "statusCode": 200 + }, + { + "batched": false, + "error": "Base url is required", + "metadata": [ + { + "jobId": 3 + } + ], + "statTags": { + "errorCategory": "dataValidation", + "errorType": "configuration" + }, + "statusCode": 400, + "destination": { + "Config": { + "sdkKey": "test-sdk-key", + "trackKnownUsers": false, + "nonInteraction": false, + "listen": false, + "trackCategorizedPages": true, + "trackNamedPages": true + } + } + } + ] + } +] diff --git a/test/__tests__/data/pinterest_tag_input.json b/test/__tests__/data/pinterest_tag_input.json index 8df3c95895..c6d88306b5 100644 --- a/test/__tests__/data/pinterest_tag_input.json +++ b/test/__tests__/data/pinterest_tag_input.json @@ -1410,5 +1410,323 @@ "Enabled": true, "Transformations": [] } + }, + { + "message": { + "name": "Test Tool", + "type": "page", + "sentAt": "2023-02-01T00:00:00.379Z", + "userId": "", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "version": "2.22.3", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "https://www.abc.com/s598907", + "path": "/test-path/s598907", + "title": "Test Tool + Reviews | Rudderstack", + "search": "", + "tab_url": "https://www.abc.com/s598907", + "referrer": "$direct", + "initial_referrer": "$direct", + "referring_domain": "", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1024, + "height": 1024, + "density": 1, + "innerWidth": 1024, + "innerHeight": 1024 + }, + "traits": {}, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.22.3" + }, + "campaign": {}, + "doNotSell": false, + "sessionId": 1675209600203, + "userAgent": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/109.0.5414.101 Safari/537.36", + "gaClientId": { + "integrations": { + "Google Ads": { + "gclid": "" + }, + "Google Analytics": { + "clientId": "1518934611.1234569600" + } + } + }, + "sessionStart": true + }, + "rudderId": "7291a10f-e7dd-49f9-94ce-0154f53897y6", + "messageId": "1c77a616-13a7-4a2e-a8e7-e1a0971897y6", + "timestamp": "2023-02-01T12:47:30.030Z", + "properties": { + "sku": "45790-32", + "url": "https://www.abc.com/23rty", + "name": "Test Tool", + "path": "/test-path/tool", + "email": "", + "title": "Test Tool + Reviews | Rudderstack", + "review": { + "reviewCount": 2, + "averageReview": 5, + "reviewContentID": [ + "238300132" + ] + }, + "search": "", + "tab_url": "https://www.abc/com", + "pageInfo": { + "pageId": "s592897", + "category": { + "pageType": "product", + "subCategory": "Dining & Kitchen Furniture", + "pageTemplate": "product detail grouper", + "primaryCategory": "Furniture" + }, + "brandType": "new brand" + }, + "referrer": "", + "subCategory": "Dining & Kitchen Furniture", + "primaryCategory": "Furniture", + "initial_referrer": "$direct", + "referring_domain": "", + "initial_referring_domain": "" + }, + "receivedAt": "2023-02-01T12:47:30.038Z", + "request_ip": "66.249.72.218", + "anonymousId": "a61c77a6-1613-474a-aee8-e7e1a0971047", + "integrations": { + "All": true + }, + "originalTimestamp": "2023-02-01T00:00:00.371Z" + }, + "destination": { + "ID": "1pYpzzvcn7AQ2W9GGIAZSsN6Mfq", + "Name": "PINTEREST_TAG", + "Config": { + "tagId": "123456789", + "advertiserId": "123478671210", + "sendingUnHashedData": false, + "enableDeduplication": false, + "eventsMapping": [ + { + "from": "Product Added", + "to": "AddToCart" + }, + { + "from": "Order Completed", + "to": "Checkout" + }, + { + "from": "Product Viewed", + "to": "PageVisit" + }, + { + "from": "Lead", + "to": "Lead" + }, + { + "from": "Signup", + "to": "Signup" + } + ], + "enhancedMatch": true + }, + "Enabled": true, + "Transformations": [] + } +}, +{ + "message": { + "type": "track", + "event": "custom event", + "channel": "web", + "sentAt": "2020-08-14T05:30:30.118Z", + "context": { + "source": "test", + "userAgent": "chrome", + "traits": { + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "email": "abc@gmail.com", + "phone": "+1234589947", + "ge": "male", + "db": "19950715", + "lastname": "Ganguly", + "firstName": "Shrouti", + "address": { + "city": "Kolkata", + "state": "WB", + "zip": "700114", + "country": "IN" + } + }, + "device": { + "advertisingId": "abc123" + }, + "library": { + "name": "rudder-sdk-ruby-sync", + "version": "1.0.6" + } + }, + "messageId": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "timestamp": "2020-08-14T05:30:30.118Z", + "properties": { + "sku": "1234", + "tax": 2, + "total": 27.5, + "coupon": "hasbros", + "revenue": 48, + "currency": "USD", + "discount": 2.5, + "order_id": "50314b8e9bcf000000000000", + "requestIP": "123.0.0.0", + "shipping": 3, + "subtotal": 22.5, + "affiliation": "Google Store", + "checkout_id": "fksdjfsdjfisjf9sdfjsd9f" + }, + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "integrations": { + "All": true + } + }, + "destination": { + "ID": "1pYpzzvcn7AQ2W9GGIAZSsN6Mfq", + "Name": "PINTEREST_TAG", + "Config": { + "tagId": "123456789", + "advertiserId": "123456", + "appId": "429047995", + "sendingUnHashedData": true, + "enableDeduplication": true, + "deduplicationKey": "messageId", + "enhancedMatch": true, + "customProperties": [ + { + "properties": "presentclass" + }, + { + "properties": "presentgrade" + } + ], + "eventsMapping": [ + { + "from": "ABC Searched", + "to": "Watch Video" + } + ] + }, + "Enabled": true, + "Transformations": [] } +}, +{ + "message": { + "type": "track", + "event": "custom event", + "channel": "web", + "sentAt": "2020-08-14T05:30:30.118Z", + "context": { + "source": "test", + "userAgent": "chrome", + "traits": { + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "email": "abc@gmail.com", + "phone": "+1234589947", + "ge": "male", + "db": "19950715", + "lastname": "Ganguly", + "firstName": "Shrouti", + "address": { + "city": "Kolkata", + "state": "WB", + "zip": "700114", + "country": "IN" + } + }, + "device": { + "advertisingId": "abc123" + }, + "library": { + "name": "rudder-sdk-ruby-sync", + "version": "1.0.6" + } + }, + "messageId": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "timestamp": "2020-08-14T05:30:30.118Z", + "properties": { + "sku": "1234", + "tax": 2, + "total": 27.5, + "coupon": "hasbros", + "revenue": 48, + "currency": "USD", + "discount": 2.5, + "order_id": "50314b8e9bcf000000000000", + "requestIP": "123.0.0.0", + "shipping": 3, + "subtotal": 22.5, + "affiliation": "Google Store", + "checkout_id": "fksdjfsdjfisjf9sdfjsd9f", + "products": [ + { + "sku": "45790-32", + "url": "https://www.example.com/product/path", + "name": "Monopoly: 3rd Edition", + "price": 19, + "category": "Games", + "quantity": 1, + "image_url": "https:///www.example.com/product/path.jpg", + "product_id": "507f1f77bcf86cd799439011" + } + ] + }, + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "integrations": { + "All": true + } + }, + "destination": { + "ID": "1pYpzzvcn7AQ2W9GGIAZSsN6Mfq", + "Name": "PINTEREST_TAG", + "Config": { + "tagId": "123456789", + "advertiserId": "123456", + "appId": "429047995", + "sendingUnHashedData": true, + "enableDeduplication": true, + "deduplicationKey": "messageId", + "enhancedMatch": true, + "customProperties": [ + { + "properties": "presentclass" + }, + { + "properties": "presentgrade" + } + ], + "eventsMapping": [ + { + "from": "ABC Searched", + "to": "Watch Video" + } + ] + }, + "Enabled": true, + "Transformations": [] + } +} ] + diff --git a/test/__tests__/data/pinterest_tag_output.json b/test/__tests__/data/pinterest_tag_output.json index e087c85e40..5ceaebba96 100644 --- a/test/__tests__/data/pinterest_tag_output.json +++ b/test/__tests__/data/pinterest_tag_output.json @@ -18,15 +18,33 @@ "app_id": "429047995", "advertiser_id": "429047995", "user_data": { - "em": ["48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"], - "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], - "ln": ["bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819"], - "fn": ["ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b"], - "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], - "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], - "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], - "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], - "hashed_maids": ["6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090"], + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], "client_user_agent": "chrome" }, "custom_data": { @@ -35,7 +53,10 @@ "order_id": "50314b8e9bcf000000000000", "opt_out_type": "LDP", "num_items": 3, - "content_ids": ["507f1f77bcf86cd799439011", "505bd76785ebb509fc183733"], + "content_ids": [ + "507f1f77bcf86cd799439011", + "505bd76785ebb509fc183733" + ], "contents": [ { "quantity": 1, @@ -74,15 +95,33 @@ "app_id": "429047995", "advertiser_id": "429047995", "user_data": { - "em": ["48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"], - "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], - "ln": ["bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819"], - "fn": ["ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b"], - "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], - "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], - "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], - "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], - "hashed_maids": ["6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090"], + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], "client_user_agent": "chrome" }, "custom_data": { @@ -90,7 +129,10 @@ "value": 27.5, "order_id": "50314b8e9bcf000000000000", "num_items": 3, - "content_ids": ["507f1f77bcf86cd799439011", "505bd76785ebb509fc183733"], + "content_ids": [ + "507f1f77bcf86cd799439011", + "505bd76785ebb509fc183733" + ], "contents": [ { "quantity": 1, @@ -129,15 +171,33 @@ "app_id": "429047995", "advertiser_id": "429047995", "user_data": { - "em": ["48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"], - "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], - "ln": ["bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819"], - "fn": ["ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b"], - "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], - "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], - "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], - "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], - "hashed_maids": ["6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090"], + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], "client_user_agent": "chrome" }, "custom_data": { @@ -145,7 +205,9 @@ "value": 27.5, "order_id": "50314b8e9bcf000000000000", "num_items": 2, - "content_ids": ["123"], + "content_ids": [ + "123" + ], "contents": [ { "quantity": 2, @@ -188,15 +250,33 @@ "app_id": "429047995", "advertiser_id": "429047995", "user_data": { - "em": ["48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"], - "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], - "ln": ["bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819"], - "fn": ["ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b"], - "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], - "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], - "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], - "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], - "hashed_maids": ["6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090"], + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], "client_user_agent": "chrome" }, "custom_data": { @@ -204,7 +284,10 @@ "value": 27.5, "num_items": 2, "order_id": "50314b8e9bcf000000000000", - "content_ids": ["507f1f77bcf86cd799439011", "505bd76785ebb509fc183733"], + "content_ids": [ + "507f1f77bcf86cd799439011", + "505bd76785ebb509fc183733" + ], "contents": [ { "quantity": 1, @@ -255,15 +338,33 @@ "action_source": "web", "advertiser_id": "123456", "user_data": { - "em": ["48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"], - "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], - "ln": ["bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819"], - "fn": ["ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b"], - "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], - "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], - "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], - "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], - "hashed_maids": ["6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090"], + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], "client_user_agent": "chrome" }, "custom_data": { @@ -271,7 +372,10 @@ "value": 27.5, "num_items": 2, "order_id": "50314b8e9bcf000000000000", - "content_ids": ["507f1f77bcf86cd799439011", "505bd76785ebb509fc183733"], + "content_ids": [ + "507f1f77bcf86cd799439011", + "505bd76785ebb509fc183733" + ], "contents": [ { "quantity": 1, @@ -310,15 +414,33 @@ "app_id": "429047995", "advertiser_id": "123456", "user_data": { - "em": ["48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"], - "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], - "ln": ["bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819"], - "fn": ["ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b"], - "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], - "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], - "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], - "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], - "hashed_maids": ["6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090"], + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], "client_user_agent": "chrome" } }, @@ -348,15 +470,33 @@ "app_id": "429047995", "advertiser_id": "123456", "user_data": { - "em": ["48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"], - "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], - "ln": ["bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819"], - "fn": ["ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b"], - "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], - "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], - "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], - "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], - "hashed_maids": ["6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090"], + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], "client_user_agent": "chrome" } }, @@ -387,15 +527,33 @@ "app_id": "429047995", "advertiser_id": "123456", "user_data": { - "em": ["48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"], - "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], - "ln": ["bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819"], - "fn": ["ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b"], - "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], - "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], - "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], - "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], - "hashed_maids": ["6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090"], + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], "client_user_agent": "chrome" } }, @@ -426,13 +584,27 @@ "app_id": "429047995", "advertiser_id": "123456", "user_data": { - "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], - "ln": ["bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819"], - "fn": ["ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b"], - "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], - "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], - "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], - "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], "client_ip_address": "127.0.0.0", "client_user_agent": "chrome" } @@ -464,16 +636,36 @@ "advertiser_id": "123456", "event_id": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", "user_data": { - "ph": ["Hashed phone"], - "db": ["Hashed DB"], - "ln": ["Hashed Lastname"], - "fn": ["Hashed FirstName"], - "ct": ["hashed city"], - "st": ["hashed state"], - "zp": ["Hashed Zip"], - "country": ["hashed country"], - "hashed_maids": ["Hashed maids"], - "ge": ["Hashed Gender"], + "ph": [ + "Hashed phone" + ], + "db": [ + "Hashed DB" + ], + "ln": [ + "Hashed Lastname" + ], + "fn": [ + "Hashed FirstName" + ], + "ct": [ + "hashed city" + ], + "st": [ + "hashed state" + ], + "zp": [ + "Hashed Zip" + ], + "country": [ + "hashed country" + ], + "hashed_maids": [ + "Hashed maids" + ], + "ge": [ + "Hashed Gender" + ], "client_user_agent": "chrome" } }, @@ -483,5 +675,183 @@ }, "files": {} } + ], + [ + { + "body": { + "JSON": { + "event_time": 1675209600, + "event_source_url": "https://www.abc.com/s598907", + "action_source": "web", + "app_name": "RudderLabs JavaScript SDK", + "app_version": "2.22.3", + "language": "en-US", + "event_id": "1c77a616-13a7-4a2e-a8e7-e1a0971897y6", + "advertiser_id": "123478671210", + "user_data": { + "client_ip_address": "66.249.72.218", + "client_user_agent": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/109.0.5414.101 Safari/537.36", + "ge": [ + null + ] + }, + "event_name": "PageVisit" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://ct.pinterest.com/events/v3", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "files": {} + } + ], + [ + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://ct.pinterest.com/events/v3", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "event_name": "custom event", + "event_time": 1597383030, + "action_source": "web", + "event_id": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "app_id": "429047995", + "advertiser_id": "123456", + "user_data": { + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], + "client_user_agent": "chrome" + }, + "custom_data": { + "currency": "USD", + "value": 27.5, + "order_id": "50314b8e9bcf000000000000", + "num_items": 0, + "content_ids": [ + "1234" + ], + "contents": [ + { + "quantity": 1, + "item_price": "undefined" + } + ] + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ], + [ + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://ct.pinterest.com/events/v3", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "event_name": "custom event", + "event_time": 1597383030, + "action_source": "web", + "event_id": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "app_id": "429047995", + "advertiser_id": "123456", + "user_data": { + "em": [ + "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08" + ], + "ph": [ + "d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b" + ], + "ln": [ + "bdfdee6414a89d72bfbf5ee90b1f85924467bae1e3980d83c2cd348dc31d5819" + ], + "fn": [ + "ee5db3fe0253b651aca3676692e0c59b25909304f5c51d223a02a215d104144b" + ], + "ct": [ + "6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85" + ], + "st": [ + "3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd" + ], + "zp": [ + "1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c" + ], + "country": [ + "582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf" + ], + "hashed_maids": [ + "6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090" + ], + "client_user_agent": "chrome" + }, + "custom_data": { + "currency": "USD", + "value": 27.5, + "order_id": "50314b8e9bcf000000000000", + "num_items": 1, + "content_ids": [ + "507f1f77bcf86cd799439011" + ], + "contents": [ + { + "quantity": 1, + "item_price": "19" + } + ] + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } ] ] diff --git a/test/__tests__/data/rockerbox.json b/test/__tests__/data/rockerbox.json index 426c995a93..5c76023f50 100644 --- a/test/__tests__/data/rockerbox.json +++ b/test/__tests__/data/rockerbox.json @@ -216,10 +216,13 @@ "FORM": {}, "JSON": { "action": "conv.add_to_cart", + "checkout_id": "12345", "email": "userSampleX120@gmail.com", "conversion_source": "RudderStack", "customer_id": "userSampleX138", "phone": "9878764736", + "product_name": "Red T-shirt", + "product_url": "http://www.yourdomain.com/products/red-t-shirt", "timestamp": 1659902539 }, "JSON_ARRAY": {}, @@ -340,12 +343,16 @@ "JSON": { "customer_id": "userSampleX138", "email": "userSampleX120@gmail.com", + "externalId": "rbUid", "phone": "9878764736", + "product_name": "Red T-shirt", + "product_url": "http://www.yourdomain.com/products/red-t-shirt", "timestamp": 1659902539, "country_code": "IN", "listing_id": "10101", "conversion_source": "RudderStack", - "action": "conv.add_to_cart" + "action": "conv.add_to_cart", + "checkout_id": "12345" }, "JSON_ARRAY": {}, "XML": {}, @@ -353,5 +360,159 @@ }, "files": {} } + }, + { + "description": "Track call with all properties along-with custom properties", + "input": { + "destination": { + "Config": { + "advertiserId": "hdowhfiqhfwaiwhrdafshbfacicolsa", + "eventFilteringOption": "disable", + "whitelistedEvents": [ + { + "eventName": "" + } + ], + "blacklistedEvents": [ + { + "eventName": "" + } + ], + "eventsMap": [ + { + "from": "Product Added", + "to": "conv.add_to_cart" + } + ], + "customPropsMapping": [ + { + "from": "unit_id", + "to": "unitID" + }, + { + "from": "merch_id", + "to": "merch_id" + }, + { + "from": "bounce_id", + "to": "bounceID" + } + ], + "useNativeSDK": { + "web": false + }, + "useNativeSDKToSend": { + "web": false + }, + "clientAuthId": { + "web": "" + }, + "oneTrustCookieCategories": { + "web": [ + { + "oneTrustCookieCategory": "" + } + ] + }, + "customDomain": { + "web": "" + }, + "enableCookieSync": { + "web": false + } + } + }, + "message": { + "channel": "web", + "context": { + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.0.0" + }, + "library": { "name": "RudderLabs JavaScript SDK", "version": "1.0.0" }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", + "locale": "en-US", + "ip": "0.0.0.0", + "os": { "name": "", "version": "" }, + "screen": { "density": 2 } + }, + "messageId": "84e26acc-56a5-4835-8233-591137fca468", + "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "originalTimestamp": "2019-10-14T09:03:17.562Z", + "anonymousId": "anon_id", + "type": "track", + "traits": { + "anonymousId": "anon_id", + "email": "jamesDoe@gmail.com", + "name": "James Doe", + "phone": "92374162212", + "gender": "M", + "employed": true, + "birthday": "1614775793", + "education": "Science", + "graduate": true, + "married": true, + "customerType": "Prime", + "msg_push": true, + "msgSms": true, + "msgemail": true, + "msgwhatsapp": false, + "custom_tags": ["Test_User", "Interested_User", "DIY_Hobby"], + "custom_mappings": { + "Office": "Trastkiv", + "Country": "Russia" + }, + "address": { + "city": "kolkata", + "country": "India", + "postalCode": 789223, + "state": "WB", + "street": "" + } + }, + "properties": { + "unit_id": 123, + "merch_id": false, + "bounceiD": "fakefake", + "counce_id": "" + }, + "event": "Product Added", + "integrations": { "All": true }, + "sentAt": "2019-10-14T09:03:22.563Z" + }, + "writeKey": "2D0yaayoBD7bp8uFomnBONdedcA", + "requestIP": "[::1]", + "receivedAt": "2022-08-08T01:32:19.369+05:30" + }, + "output": { + "body": { + "XML": {}, + "FORM": {}, + "JSON": { + "email": "jamesDoe@gmail.com", + "phone": "92374162212", + "action": "conv.add_to_cart", + "bounceiD": "fakefake", + "merch_id": false, + "timestamp": 1571043797, + "unit_id": 123, + "customer_id": "anon_id", + "conversion_source": "RudderStack", + "counce_id": "" + }, + "JSON_ARRAY": {} + }, + "type": "REST", + "files": {}, + "method": "POST", + "params": { + "advertiser": "hdowhfiqhfwaiwhrdafshbfacicolsa" + }, + "headers": {}, + "version": "1", + "endpoint": "https://webhooks.getrockerbox.com/rudderstack" + } } ] diff --git a/test/__tests__/data/rockerbox_router_output.json b/test/__tests__/data/rockerbox_router_output.json index 4d91390c8e..75f3bea086 100644 --- a/test/__tests__/data/rockerbox_router_output.json +++ b/test/__tests__/data/rockerbox_router_output.json @@ -13,10 +13,13 @@ "body": { "JSON": { "action": "conv.add_to_cart", + "checkout_id": "12345", "conversion_source": "RudderStack", "customer_id": "userSampleX138", "email": "userSampleX120@gmail.com", "phone": "9878764736", + "product_name": "Red T-shirt", + "product_url": "http://www.yourdomain.com/products/red-t-shirt", "timestamp": 1659902539 }, "JSON_ARRAY": {}, @@ -87,10 +90,13 @@ "body": { "JSON": { "action": "conv.add_to_cart", + "checkout_id": "12345", "conversion_source": "RudderStack", "customer_id": "userSampleX138", "email": "userSampleX120@gmail.com", "phone": "9878764736", + "product_name": "Red T-shirt", + "product_url": "http://www.yourdomain.com/products/red-t-shirt", "timestamp": 1659902539 }, "JSON_ARRAY": {}, diff --git a/test/__tests__/data/salesforce_proxy_input.json b/test/__tests__/data/salesforce_proxy_input.json index 1de81aa281..6be3d2cd25 100644 --- a/test/__tests__/data/salesforce_proxy_input.json +++ b/test/__tests__/data/salesforce_proxy_input.json @@ -163,5 +163,71 @@ } } } + }, + { + "request": { + "body": { + "type": "REST", + "files": {}, + "method": "POST", + "params": {}, + "userId": "", + "headers": { + "Content-Type": "application/json", + "Authorization": "Bearer token" + }, + "version": "1", + "endpoint": "https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/6", + "body": { + "XML": {}, + "FORM": {}, + "JSON": { + "Email": "denis.kornilov@sbermarket.ru", + "Company": "sbermarket.ru", + "LastName": "Корнилов", + "FirstName": "Денис", + "LeadSource": "App Signup", + "account_type__c": "free_trial" + }, + "JSON_ARRAY": {} + }, + "metadata": { + "destInfo": { "authKey": "2HezPl1w11opbFSxnLDEgZ7kWTf" } + } + } + } + }, + { + "request": { + "body": { + "type": "REST", + "files": {}, + "method": "POST", + "params": {}, + "userId": "", + "headers": { + "Content-Type": "application/json", + "Authorization": "Bearer token" + }, + "version": "1", + "endpoint": "https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/7", + "body": { + "XML": {}, + "FORM": {}, + "JSON": { + "Email": "denis.kornilov@sbermarket.ru", + "Company": "sbermarket.ru", + "LastName": "Корнилов", + "FirstName": "Денис", + "LeadSource": "App Signup", + "account_type__c": "free_trial" + }, + "JSON_ARRAY": {} + }, + "metadata": { + "destInfo": { "authKey": "2HezPl1w11opbFSxnLDEgZ7kWTf" } + } + } + } } ] diff --git a/test/__tests__/data/salesforce_proxy_output.json b/test/__tests__/data/salesforce_proxy_output.json index c72d26500a..690a3bdb22 100644 --- a/test/__tests__/data/salesforce_proxy_output.json +++ b/test/__tests__/data/salesforce_proxy_output.json @@ -19,7 +19,7 @@ { "output": { "status": 500, - "message": "Salesforce Request Failed - due to Session expired or invalid, (Retryable).during Salesforce Response Handling", + "message": "Salesforce Request Failed - due to \"INVALID_SESSION_ID\", (Retryable) during Salesforce Response Handling", "destinationResponse": { "response": [ { @@ -47,7 +47,7 @@ { "output": { "status": 400, - "message": "Salesforce Request Failed: 401 due to INVALID_HEADER_TYPE, (Aborted). during Salesforce Response Handling", + "message": "Salesforce Request Failed: \"401\" due to \"INVALID_HEADER_TYPE\", (Aborted) during Salesforce Response Handling", "destinationResponse": { "response": [ { @@ -75,7 +75,7 @@ { "output": { "status": 429, - "message": "Salesforce Request Failed - due to Request limit exceeded, (Throttled).during Salesforce Response Handling", + "message": "Salesforce Request Failed - due to \"REQUEST_LIMIT_EXCEEDED\", (Throttled) during Salesforce Response Handling", "destinationResponse": { "response": [ { @@ -103,7 +103,7 @@ { "output": { "status": 500, - "message": "Salesforce Request Failed - due to Server Unavailable, (Retryable).during Salesforce Response Handling", + "message": "Salesforce Request Failed - due to \"Server Unavailable\", (Retryable) during Salesforce Response Handling", "destinationResponse": { "response": [ { @@ -127,5 +127,57 @@ "module": "destination" } } + }, + { + "output": { + "status": 400, + "message": "Salesforce Request Failed: \"400\" due to \"{\"error\":\"invalid_grant\",\"error_description\":\"authentication failure\"}\", (Aborted) during Salesforce Response Handling", + "destinationResponse": { + "response": { + "error": "invalid_grant", + "error_description": "authentication failure" + }, + "status": 400, + "rudderJobMetadata": { + "destInfo": { + "authKey": "2HezPl1w11opbFSxnLDEgZ7kWTf" + } + } + }, + "statTags": { + "destType": "SALESFORCE", + "errorCategory": "network", + "errorType": "aborted", + "feature": "dataDelivery", + "implementation": "native", + "module": "destination" + } + } + }, + { + "output": { + "destinationResponse": { + "response": { + "errorCode": "SERVER_UNAVAILABLE", + "message": "Server Unavailable" + }, + "rudderJobMetadata": { + "destInfo": { + "authKey": "2HezPl1w11opbFSxnLDEgZ7kWTf" + } + }, + "status": 503 + }, + "message": "Salesforce Request Failed - due to \"{\"message\":\"Server Unavailable\",\"errorCode\":\"SERVER_UNAVAILABLE\"}\", (Retryable) during Salesforce Response Handling", + "statTags": { + "destType": "SALESFORCE", + "errorCategory": "network", + "errorType": "retryable", + "feature": "dataDelivery", + "implementation": "native", + "module": "destination" + }, + "status": 500 + } } -] +] \ No newline at end of file diff --git a/test/__tests__/data/shopify_source_output.json b/test/__tests__/data/shopify_source_output.json index b76bdec8c7..22676336dd 100644 --- a/test/__tests__/data/shopify_source_output.json +++ b/test/__tests__/data/shopify_source_output.json @@ -93,7 +93,10 @@ "integration": { "name": "SHOPIFY" }, - "topic": "orders_updated" + "topic": "orders_updated", + "cart_token": "7ed2aa8c6e74666534b023e197fffd41", + "checkout_token": "7ed2aa8c6e74666534b023e197fffd41", + "order_token": "4e72b2e04f9e9faa1ec4f8bdb5a36502" }, "integrations": { "SHOPIFY": true diff --git a/test/__tests__/data/singular_router_input.json b/test/__tests__/data/singular_router_input.json index c31e304bc8..7f50244276 100644 --- a/test/__tests__/data/singular_router_input.json +++ b/test/__tests__/data/singular_router_input.json @@ -340,5 +340,200 @@ }, "timestamp": "2021-09-01T15:46:51.000Z" } + }, + { + "message": { + "type": "track", + "event": "Application Backgrounded", + "sentAt": "2023-01-19T14:25:24.234Z", + "userId": "68e214f1-ac84-4241-b27d-78a18f59f21e", + "channel": "mobile", + "context": { + "os": { + "name": "iOS", + "version": "16.2" + }, + "app": { + "build": "5013", + "version": "0.5.13", + "namespace": "com.yabimoney" + }, + "device": { + "id": "cc06ff5e-838b-4e33-9d90-4ab5a6068bec", + "name": "iPhone", + "type": "iOS", + "model": "iPhone", + "manufacturer": "Apple", + "advertisingId": "1", + "adTrackingEnabled": true, + "attTrackingStatus": 0 + }, + "locale": "en-AE", + "screen": { + "width": 844, + "height": 390, + "density": 3 + }, + "traits": { + "phone": "", + "userId": "68e214f1-ac84-4241-b27d-78a18f59f21e", + "tenant_id": "tgTV2Bbv", + "anonymousId": "cc06ff5e-838b-4e33-9d90-4ab5a6068bec", + "yabi_user_id": "uCh5IS8p", + "subscription_type": "" + }, + "library": { + "name": "rudder-ios-library", + "version": "1.8.0" + }, + "network": { + "wifi": true, + "carrier": "etisalat", + "cellular": false + }, + "timezone": "Asia/Dubai", + "sessionId": 1674138119 + }, + "rudderId": "b7bbf406-aa7f-4d64-a388-925675e78f36", + "messageId": "b9e9534b-b3b7-4bdb-8d59-062e1fbf4e2b", + "timestamp": "2023-01-19T14:25:07.532Z", + "receivedAt": "2023-01-19T14:25:25.465Z", + "request_ip": "87.201.98.151", + "anonymousId": "cc06ff5e-838b-4e33-9d90-4ab5a6068bec", + "integrations": { + "All": true + }, + "originalTimestamp": "2023-01-19T14:25:06.301Z" + }, + "destination": { + "secretConfig": {}, + "Config": { + "apiKey": "apiKey", + "apiSecret": "apiSecreth9h3984bnsdfkh98kjiu4h", + "sessionEventList": [ + { + "sessionEventName": "test_event" + } + ], + "blacklistedEvents": [ + { + "eventName": "" + } + ], + "whitelistedEvents": [ + { + "eventName": "" + } + ], + "eventFilteringOption": "whitelistedEvents", + "eventDelivery": false, + "eventDeliveryTS": 1663919255086 + }, + "liveEventsConfig": { + "eventDelivery": false, + "eventDeliveryTS": 1663919255086 + }, + "ID": "2EhlBrBduwN2NX4pJ7nrVDHAz6C", + "workspaceId": "1sUXvPs0hYgjBxSfjG4gqnRFNoP", + "DestinationDefinition": { + "config": { + "destConfig": { + "ios": [ + "useNativeSDK" + ], + "android": [ + "useNativeSDK" + ], + "cordova": [ + "useNativeSDK" + ], + "reactnative": [ + "useNativeSDK" + ], + "defaultConfig": [ + "apiKey", + "apiSecret", + "sessionEventList", + "blacklistedEvents", + "whitelistedEvents", + "eventFilteringOption" + ] + }, + "excludeKeys": [], + "includeKeys": [ + "apiKey", + "apiSecret", + "sessionEventList", + "blacklistedEvents", + "whitelistedEvents", + "eventFilteringOption" + ], + "transformAt": "processor", + "transformAtV1": "processor", + "supportedSourceTypes": [ + "android", + "ios", + "flutter", + "reactnative", + "cordova", + "web", + "amp", + "cloud", + "warehouse" + ], + "saveDestinationResponse": true + }, + "configSchema": {}, + "responseRules": {}, + "options": null, + "id": "2642K92ztyRPghLlFL9GXfwjWDp", + "name": "SINGULAR", + "displayName": "Singular", + "category": null, + "createdAt": "2022-03-07T15:54:30.619Z", + "updatedAt": "2022-10-12T12:44:07.624Z" + }, + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true, + "name": "Singular", + "enabled": true, + "deleted": false, + "createdAt": "2022-09-13T07:52:44.981Z", + "updatedAt": "2022-09-23T07:47:35.092Z", + "revisionId": "2F9znalm2FSPmdj99jJbsoVLSVM", + "secretVersion": 1 + }, + "metadata": { + "sourceId": "1vPJD7KzElDJ0N7SRf1fZ32z1SW", + "workspaceId": "1sUXvPs0hYgjBxSfjG4gqnRFNoP", + "namespace": "mynamespace", + "instanceId": "mynamespace-v0-rudderstack-0", + "sourceType": "Javascript", + "sourceCategory": "", + "trackingPlanId": "", + "trackingPlanVersion": 0, + "sourceTpConfig": null, + "mergedTpConfig": null, + "destinationId": "2EhlBrBduwN2NX4pJ7nrVDHAz6C", + "jobRunId": "", + "jobId": 68205922, + "sourceBatchId": "", + "sourceJobId": "", + "sourceJobRunId": "", + "sourceTaskId": "", + "sourceTaskRunId": "", + "recordId": null, + "destinationType": "SINGULAR", + "messageId": "b9e9534b-b3b7-4bdb-8d59-062e1fbf4e2b", + "oauthAccessToken": "", + "messageIds": null, + "rudderId": "67895e15-d37f-49d6-9017-e8d29264e31f<<>>yolanda.rivera2@yahoo.com", + "receivedAt": "2022-05-02T07:20:13.809Z", + "eventName": "", + "eventType": "track", + "sourceDefinitionId": "1TW48i2bIzEl1HPf825cEznfIM8", + "destinationDefinitionId": "" + } } -] +] \ No newline at end of file diff --git a/test/__tests__/data/singular_router_output.json b/test/__tests__/data/singular_router_output.json index 5ccea4e08d..08a6e355e2 100644 --- a/test/__tests__/data/singular_router_output.json +++ b/test/__tests__/data/singular_router_output.json @@ -202,5 +202,170 @@ ] } } + }, + { + "batchedRequest": { + "version": "1", + "type": "REST", + "method": "GET", + "endpoint": "https://s2s.singular.net/api/v1/evt", + "headers": {}, + "params": { + "n": "Application Backgrounded", + "p": "iOS", + "i": "com.yabimoney", + "ip": "87.201.98.151", + "ve": "16.2", + "att_authorization_status": 0, + "custom_user_id": "68e214f1-ac84-4241-b27d-78a18f59f21e", + "utime": 1674138306, + "idfa": "1", + "idfv": "cc06ff5e-838b-4e33-9d90-4ab5a6068bec", + "c": "wifi", + "a": "apiKey", + "e": {} + }, + "body": { + "JSON": {}, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + }, + "metadata": [ + { + "sourceId": "1vPJD7KzElDJ0N7SRf1fZ32z1SW", + "workspaceId": "1sUXvPs0hYgjBxSfjG4gqnRFNoP", + "namespace": "mynamespace", + "instanceId": "mynamespace-v0-rudderstack-0", + "sourceType": "Javascript", + "sourceCategory": "", + "trackingPlanId": "", + "trackingPlanVersion": 0, + "sourceTpConfig": null, + "mergedTpConfig": null, + "destinationId": "2EhlBrBduwN2NX4pJ7nrVDHAz6C", + "jobRunId": "", + "jobId": 68205922, + "sourceBatchId": "", + "sourceJobId": "", + "sourceJobRunId": "", + "sourceTaskId": "", + "sourceTaskRunId": "", + "recordId": null, + "destinationType": "SINGULAR", + "messageId": "b9e9534b-b3b7-4bdb-8d59-062e1fbf4e2b", + "oauthAccessToken": "", + "messageIds": null, + "rudderId": "67895e15-d37f-49d6-9017-e8d29264e31f<<>>yolanda.rivera2@yahoo.com", + "receivedAt": "2022-05-02T07:20:13.809Z", + "eventName": "", + "eventType": "track", + "sourceDefinitionId": "1TW48i2bIzEl1HPf825cEznfIM8", + "destinationDefinitionId": "" + } + ], + "batched": false, + "statusCode": 200, + "destination": { + "secretConfig": {}, + "Config": { + "apiKey": "apiKey", + "apiSecret": "apiSecreth9h3984bnsdfkh98kjiu4h", + "sessionEventList": [ + { + "sessionEventName": "test_event" + } + ], + "blacklistedEvents": [ + { + "eventName": "" + } + ], + "whitelistedEvents": [ + { + "eventName": "" + } + ], + "eventFilteringOption": "whitelistedEvents", + "eventDelivery": false, + "eventDeliveryTS": 1663919255086 + }, + "liveEventsConfig": { + "eventDelivery": false, + "eventDeliveryTS": 1663919255086 + }, + "ID": "2EhlBrBduwN2NX4pJ7nrVDHAz6C", + "workspaceId": "1sUXvPs0hYgjBxSfjG4gqnRFNoP", + "DestinationDefinition": { + "config": { + "destConfig": { + "ios": [ + "useNativeSDK" + ], + "android": [ + "useNativeSDK" + ], + "cordova": [ + "useNativeSDK" + ], + "reactnative": [ + "useNativeSDK" + ], + "defaultConfig": [ + "apiKey", + "apiSecret", + "sessionEventList", + "blacklistedEvents", + "whitelistedEvents", + "eventFilteringOption" + ] + }, + "excludeKeys": [], + "includeKeys": [ + "apiKey", + "apiSecret", + "sessionEventList", + "blacklistedEvents", + "whitelistedEvents", + "eventFilteringOption" + ], + "transformAt": "processor", + "transformAtV1": "processor", + "supportedSourceTypes": [ + "android", + "ios", + "flutter", + "reactnative", + "cordova", + "web", + "amp", + "cloud", + "warehouse" + ], + "saveDestinationResponse": true + }, + "configSchema": {}, + "responseRules": {}, + "options": null, + "id": "2642K92ztyRPghLlFL9GXfwjWDp", + "name": "SINGULAR", + "displayName": "Singular", + "category": null, + "createdAt": "2022-03-07T15:54:30.619Z", + "updatedAt": "2022-10-12T12:44:07.624Z" + }, + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true, + "name": "Singular", + "enabled": true, + "deleted": false, + "createdAt": "2022-09-13T07:52:44.981Z", + "updatedAt": "2022-09-23T07:47:35.092Z", + "revisionId": "2F9znalm2FSPmdj99jJbsoVLSVM", + "secretVersion": 1 + } } -] +] \ No newline at end of file diff --git a/test/__tests__/data/webhook_router_input.json b/test/__tests__/data/webhook_router_input.json index f14f843016..197677d7a9 100644 --- a/test/__tests__/data/webhook_router_input.json +++ b/test/__tests__/data/webhook_router_input.json @@ -1,212 +1,215 @@ [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" + [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } }, - "network": { - "carrier": "Banglalink" + "event": "spin_result", + "integrations": { + "All": true }, - "os": { - "name": "android", - "version": "8.1.0" + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 } }, - "event": "spin_result", - "integrations": { - "All": true + "metadata": { + "jobId": 2 }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "headers": [ + { + "from": "", + "to": "" + }, + { + "from": "test2", + "to": "value2" + } + ] + } } }, - "metadata": { - "jobId": 2 - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "headers": [ - { - "from": "", - "to": "" + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" }, - { - "from": "test2", - "to": "value2" + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" } - ] - } - } - }, - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" }, - "network": { - "carrier": "Banglalink" + "event": "spin_result", + "integrations": { + "All": true }, - "os": { - "name": "android", - "version": "8.1.0" + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 } }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 + "metadata": { + "jobId": 2 }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "metadata": { - "jobId": 2 - }, - "destination": { - "Config": { - "webhookUrl": "https://6b0e6a60.ngrok.io/n" + "destination": { + "Config": { + "webhookUrl": "https://6b0e6a60.ngrok.io/n" + } } } - } + ] ] + diff --git a/test/__tests__/data/webhook_router_output.json b/test/__tests__/data/webhook_router_output.json index 95620e8487..a5f0aaf7b3 100644 --- a/test/__tests__/data/webhook_router_output.json +++ b/test/__tests__/data/webhook_router_output.json @@ -1,255 +1,257 @@ [ - { - "batchedRequest": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "JSON": { - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "user_properties": { - "total_payments": 0, - "internetReachability": "ReachableViaLocalAreaNetwork", - "level": 6, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "coin_balance": 9466052, - "player_total_shields": 0, - "isLowEndDevice": false, - "game_fps": 30, - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "graphicsQuality": "HD", - "current_module_name": "CasinoGameModule", - "player_total_battles": 0, - "lifetime_gem_balance": 0, - "gem_balance": 0, - "fb_profile": "0", - "start_date": "2019-08-01", - "versionSessionCount": 2, - "game_name": "FireEagleSlots" - }, - "integrations": { - "All": true - }, - "event": "spin_result", - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "model": "Redmi 6", - "manufacturer": "Xiaomi", - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "name": "xiaomi" + [ + { + "batchedRequest": { + "body": { + "XML": {}, + "JSON_ARRAY": {}, + "JSON": { + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "user_properties": { + "total_payments": 0, + "internetReachability": "ReachableViaLocalAreaNetwork", + "level": 6, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "coin_balance": 9466052, + "player_total_shields": 0, + "isLowEndDevice": false, + "game_fps": 30, + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "graphicsQuality": "HD", + "current_module_name": "CasinoGameModule", + "player_total_battles": 0, + "lifetime_gem_balance": 0, + "gem_balance": 0, + "fb_profile": "0", + "start_date": "2019-08-01", + "versionSessionCount": 2, + "game_name": "FireEagleSlots" }, - "traits": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "address": { - "city": "Dhaka", - "country": "Bangladesh" - } + "integrations": { + "All": true }, - "os": { - "version": "8.1.0", - "name": "android" + "event": "spin_result", + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "model": "Redmi 6", + "manufacturer": "Xiaomi", + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "name": "xiaomi" + }, + "traits": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "address": { + "city": "Dhaka", + "country": "Bangladesh" + } + }, + "os": { + "version": "8.1.0", + "name": "android" + }, + "network": { + "carrier": "Banglalink" + } }, - "network": { - "carrier": "Banglalink" + "type": "track", + "properties": { + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "jackpot_win_type": "Silver", + "coin_balance": 9466052, + "bet_level": 1, + "ishighroller": "False", + "tournament_id": "T1561970819", + "battle_id": "N/A", + "bet_amount": 9, + "fb_profile": "0", + "player_total_shields": 0, + "is_turbo": "False", + "player_total_battles": 0, + "bet_multiplier": 1, + "start_date": "2019-08-01", + "versionSessionCount": 2, + "graphicsQuality": "HD", + "is_auto_spin": "False", + "days_in_game": 0, + "additional_bet_index": 0, + "isLowEndDevice": "False", + "game_fps": 30, + "extra_param": "N/A", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "current_module_name": "CasinoGameModule", + "game_id": "fireEagleBase", + "featureGameType": "N/A", + "gem_balance": 0, + "internetReachability": "ReachableViaLocalAreaNetwork", + "total_payments": 0, + "level": 6, + "win_amount": 0, + "no_of_spin": 1, + "game_name": "FireEagleSlots", + "jackpot_win_amount": 90, + "lifetime_gem_balance": 0, + "isf": "False" } }, - "type": "track", - "properties": { - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "jackpot_win_type": "Silver", - "coin_balance": 9466052, - "bet_level": 1, - "ishighroller": "False", - "tournament_id": "T1561970819", - "battle_id": "N/A", - "bet_amount": 9, - "fb_profile": "0", - "player_total_shields": 0, - "is_turbo": "False", - "player_total_battles": 0, - "bet_multiplier": 1, - "start_date": "2019-08-01", - "versionSessionCount": 2, - "graphicsQuality": "HD", - "is_auto_spin": "False", - "days_in_game": 0, - "additional_bet_index": 0, - "isLowEndDevice": "False", - "game_fps": 30, - "extra_param": "N/A", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "current_module_name": "CasinoGameModule", - "game_id": "fireEagleBase", - "featureGameType": "N/A", - "gem_balance": 0, - "internetReachability": "ReachableViaLocalAreaNetwork", - "total_payments": 0, - "level": 6, - "win_amount": 0, - "no_of_spin": 1, - "game_name": "FireEagleSlots", - "jackpot_win_amount": 90, - "lifetime_gem_balance": 0, - "isf": "False" - } + "FORM": {} }, - "FORM": {} - }, - "files": {}, - "endpoint": "http://6b0e6a60.ngrok.io", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "headers": { - "content-type": "application/json", - "test2": "value2" + "files": {}, + "endpoint": "http://6b0e6a60.ngrok.io", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "headers": { + "content-type": "application/json", + "test2": "value2" + }, + "version": "1", + "params": {}, + "type": "REST", + "method": "POST" }, - "version": "1", - "params": {}, - "type": "REST", - "method": "POST" - }, - "metadata": [ - { - "jobId": 2 - } - ], - "batched": false, - "statusCode": 200, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "headers": [ - { - "from": "", - "to": "" - }, - { - "from": "test2", - "to": "value2" - } - ] + "metadata": [ + { + "jobId": 2 + } + ], + "batched": false, + "statusCode": 200, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "headers": [ + { + "from": "", + "to": "" + }, + { + "from": "test2", + "to": "value2" + } + ] + } } - } - }, - { - "batchedRequest": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "JSON": { - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "user_properties": { - "total_payments": 0, - "internetReachability": "ReachableViaLocalAreaNetwork", - "level": 6, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "coin_balance": 9466052, - "player_total_shields": 0, - "isLowEndDevice": false, - "game_fps": 30, - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "graphicsQuality": "HD", - "current_module_name": "CasinoGameModule", - "player_total_battles": 0, - "lifetime_gem_balance": 0, - "gem_balance": 0, - "fb_profile": "0", - "start_date": "2019-08-01", - "versionSessionCount": 2, - "game_name": "FireEagleSlots" - }, - "integrations": { - "All": true - }, - "event": "spin_result", - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "model": "Redmi 6", - "manufacturer": "Xiaomi", - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "name": "xiaomi" + }, + { + "batchedRequest": { + "body": { + "XML": {}, + "JSON_ARRAY": {}, + "JSON": { + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "user_properties": { + "total_payments": 0, + "internetReachability": "ReachableViaLocalAreaNetwork", + "level": 6, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "coin_balance": 9466052, + "player_total_shields": 0, + "isLowEndDevice": false, + "game_fps": 30, + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "graphicsQuality": "HD", + "current_module_name": "CasinoGameModule", + "player_total_battles": 0, + "lifetime_gem_balance": 0, + "gem_balance": 0, + "fb_profile": "0", + "start_date": "2019-08-01", + "versionSessionCount": 2, + "game_name": "FireEagleSlots" }, - "traits": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "address": { - "city": "Dhaka", - "country": "Bangladesh" - } + "integrations": { + "All": true }, - "os": { - "version": "8.1.0", - "name": "android" + "event": "spin_result", + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "model": "Redmi 6", + "manufacturer": "Xiaomi", + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "name": "xiaomi" + }, + "traits": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "address": { + "city": "Dhaka", + "country": "Bangladesh" + } + }, + "os": { + "version": "8.1.0", + "name": "android" + }, + "network": { + "carrier": "Banglalink" + } }, - "network": { - "carrier": "Banglalink" + "type": "track", + "properties": { + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "jackpot_win_type": "Silver", + "coin_balance": 9466052, + "bet_level": 1, + "ishighroller": "False", + "tournament_id": "T1561970819", + "battle_id": "N/A", + "bet_amount": 9, + "fb_profile": "0", + "player_total_shields": 0, + "is_turbo": "False", + "player_total_battles": 0, + "bet_multiplier": 1, + "start_date": "2019-08-01", + "versionSessionCount": 2, + "graphicsQuality": "HD", + "is_auto_spin": "False", + "days_in_game": 0, + "additional_bet_index": 0, + "isLowEndDevice": "False", + "game_fps": 30, + "extra_param": "N/A", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "current_module_name": "CasinoGameModule", + "game_id": "fireEagleBase", + "featureGameType": "N/A", + "gem_balance": 0, + "internetReachability": "ReachableViaLocalAreaNetwork", + "total_payments": 0, + "level": 6, + "win_amount": 0, + "no_of_spin": 1, + "game_name": "FireEagleSlots", + "jackpot_win_amount": 90, + "lifetime_gem_balance": 0, + "isf": "False" } }, - "type": "track", - "properties": { - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "jackpot_win_type": "Silver", - "coin_balance": 9466052, - "bet_level": 1, - "ishighroller": "False", - "tournament_id": "T1561970819", - "battle_id": "N/A", - "bet_amount": 9, - "fb_profile": "0", - "player_total_shields": 0, - "is_turbo": "False", - "player_total_battles": 0, - "bet_multiplier": 1, - "start_date": "2019-08-01", - "versionSessionCount": 2, - "graphicsQuality": "HD", - "is_auto_spin": "False", - "days_in_game": 0, - "additional_bet_index": 0, - "isLowEndDevice": "False", - "game_fps": 30, - "extra_param": "N/A", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "current_module_name": "CasinoGameModule", - "game_id": "fireEagleBase", - "featureGameType": "N/A", - "gem_balance": 0, - "internetReachability": "ReachableViaLocalAreaNetwork", - "total_payments": 0, - "level": 6, - "win_amount": 0, - "no_of_spin": 1, - "game_name": "FireEagleSlots", - "jackpot_win_amount": 90, - "lifetime_gem_balance": 0, - "isf": "False" - } + "FORM": {} }, - "FORM": {} - }, - "files": {}, - "endpoint": "https://6b0e6a60.ngrok.io/n", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "headers": { - "content-type": "application/json" + "files": {}, + "endpoint": "https://6b0e6a60.ngrok.io/n", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "headers": { + "content-type": "application/json" + }, + "version": "1", + "params": {}, + "type": "REST", + "method": "POST" }, - "version": "1", - "params": {}, - "type": "REST", - "method": "POST" - }, - "metadata": [ - { - "jobId": 2 - } - ], - "batched": false, - "statusCode": 200, - "destination": { - "Config": { - "webhookUrl": "https://6b0e6a60.ngrok.io/n" + "metadata": [ + { + "jobId": 2 + } + ], + "batched": false, + "statusCode": 200, + "destination": { + "Config": { + "webhookUrl": "https://6b0e6a60.ngrok.io/n" + } } } - } -] + ] +] \ No newline at end of file diff --git a/test/__tests__/dynamicConfig.test.js b/test/__tests__/dynamicConfig.test.js deleted file mode 100644 index c8b6dfb8cd..0000000000 --- a/test/__tests__/dynamicConfig.test.js +++ /dev/null @@ -1,22 +0,0 @@ -const integration = "dynamicConfig"; - -const fs = require("fs"); -const path = require("path"); -const { processDynamicConfig } = require("../../src/util/dynamicConfig"); - -const inputDataFile = fs.readFileSync( - path.resolve(__dirname, `./data/${integration}_input.json`) -); -const outputDataFile = fs.readFileSync( - path.resolve(__dirname, `./data/${integration}_output.json`) -); - -const inputData = JSON.parse(inputDataFile); -const expectedData = JSON.parse(outputDataFile); - -it(`Testing: handleDest`, async () => { - let output = processDynamicConfig(inputData.request.body, "router"); - // output = JSON.stringify(output); - // expectedData = JSON.stringify(expectedData); - expect(output).toEqual(expectedData); -}); diff --git a/test/__tests__/impact_radius.test.js b/test/__tests__/impact.test.js similarity index 94% rename from test/__tests__/impact_radius.test.js rename to test/__tests__/impact.test.js index ad2dfd6f8e..8a741840de 100644 --- a/test/__tests__/impact_radius.test.js +++ b/test/__tests__/impact.test.js @@ -1,8 +1,8 @@ const fs = require("fs"); const path = require("path"); -const integration = "impact_radius"; -const name = "IMPACT_RADIUS"; +const integration = "impact"; +const name = "IMPACT"; const version = "v0"; const transformer = require(`../../src/${version}/destinations/${integration}/transform`); diff --git a/test/__tests__/lemniskMarketingAutomation.test.js b/test/__tests__/lemniskMarketingAutomation.test.js new file mode 100644 index 0000000000..55c09ba63e --- /dev/null +++ b/test/__tests__/lemniskMarketingAutomation.test.js @@ -0,0 +1,44 @@ +const integration = "lemnisk"; +const name = "lemniskMarketingAutomation"; +const version = "v0"; + +const fs = require("fs"); +const path = require("path"); + +const transformer = require(`../../src/${version}/destinations/${integration}/transform`); + +// Processor Test Data +const testDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}.json`) +); +const testData = JSON.parse(testDataFile); + +// Router Test files +const routerTestDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}_router.json`) +); +const routerTestData = JSON.parse(routerTestDataFile); + +describe(`${name} Tests`, () => { + describe("Processor", () => { + testData.forEach((dataPoint, index) => { + it(`${index}. ${integration} - ${dataPoint.description}`, async () => { + try { + const output = await transformer.process(dataPoint.input); + expect(output).toEqual(dataPoint.output); + } catch (error) { + expect(error.message).toEqual(dataPoint.output.error); + } + }); + }); + }); + + describe("Router Tests", () => { + routerTestData.forEach(dataPoint => { + it("Payload", async () => { + const output = await transformer.processRouterDest(dataPoint.input); + expect(output).toEqual(dataPoint.output); + }); + }); + }); +}); diff --git a/test/__tests__/optimizely_fullstack.test.js b/test/__tests__/optimizely_fullstack.test.js new file mode 100644 index 0000000000..23e614c219 --- /dev/null +++ b/test/__tests__/optimizely_fullstack.test.js @@ -0,0 +1,46 @@ +const integration = "optimizely_fullstack"; +const name = "Optimizely Fullstack"; + +const fs = require("fs"); +const path = require("path"); + +const version = "v0"; + +const transformer = require(`../../src/${version}/destinations/${integration}/transform`); + +// Processor Test files +const testDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}.json`) +); +const testData = JSON.parse(testDataFile); + +// Router Test files +const routerTestDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}_router.json`) + ); +const routerTestData = JSON.parse(routerTestDataFile); + +describe(`${name} Tests`, () => { + describe("Processor", () => { + testData.forEach(async (dataPoint, index) => { + it(`${index}. ${integration} - ${dataPoint.description}`, async () => { + try { + const output = await transformer.process(dataPoint.input); + expect(output).toEqual(dataPoint.output); + } catch (error) { + expect(error.message).toEqual(dataPoint.output.error); + } + }); + }); + }); + + describe("Router Tests", () => { + routerTestData.forEach(dataPoint => { + it("Payload", async () => { + const output = await transformer.processRouterDest(dataPoint.input); + expect(output).toEqual(dataPoint.output); + }); + }); + }); + +}); diff --git a/test/__tests__/proxy.test.js b/test/__tests__/proxy.test.js index 21d4cad2c5..abdfbeb20f 100644 --- a/test/__tests__/proxy.test.js +++ b/test/__tests__/proxy.test.js @@ -13,7 +13,8 @@ const destinations = [ "snapchat_custom_audience", "clevertap", "salesforce", - "marketo_static_list" + "marketo_static_list", + "criteo_audience" ]; const service = require("../../src/versionedRouter").handleProxyRequest; diff --git a/test/__tests__/trackingPlan.test.js b/test/__tests__/trackingPlan.test.js index 78a9ac83aa..bf0241fe22 100644 --- a/test/__tests__/trackingPlan.test.js +++ b/test/__tests__/trackingPlan.test.js @@ -92,6 +92,10 @@ const trackingPlan = { }, revenue: { type: ["number"] + }, + dateString: { + type: ["string"], + format: "date-time" } }, type: "object", @@ -134,6 +138,10 @@ const trackingPlan = { }, revenue: { type: ["integer"] + }, + dateString: { + type: ["string"], + format: "date-time" } }, type: "object", @@ -183,6 +191,10 @@ const trackingPlan = { type: "number", maximum: 4.0 } + }, + dateString: { + type: ["string"], + format: "date-time" } }, type: "object", @@ -227,6 +239,10 @@ const trackingPlan = { }, revenue: { type: ["number"] + }, + dateString: { + type: ["string"], + format: "date-time" } }, type: "object", @@ -250,8 +266,8 @@ const trackingPlan = { update_time: "2021-12-15T13:29:59.272Z" }; -const constructEventToValidate = eventName => { - return { +const constructEventToValidate = (eventName, dateStr='2020-06-08T01:00:00') => { + const ev = { metadata: { trackingPlanId: "dummy_tracking_plan_id", trackingPlanVersion: "dummy_version", @@ -270,7 +286,8 @@ const constructEventToValidate = eventName => { prop_integer: 2, prop_float: 2.3, email: "demo@rudderstack.com", - props: ["string", 1, 2, 3] + props: ["string", 1, 2, 3], + dateString: dateStr }, context: { ip: "14.5.67.21" @@ -278,6 +295,7 @@ const constructEventToValidate = eventName => { timestamp: "2020-02-02T00:23:09.544Z" } }; + return ev; }; const eventValidationTestCases = [ @@ -347,6 +365,21 @@ const eventValidationTestCases = [ } } ] + }, + { + testCase: "draft 4 - wrong date-time", + event: constructEventToValidate("Product clicked draft 4", "2022-06-08"), + trackingPlan, + output: [ + { + message: "must match format \"date-time\"", + meta: { + instacePath: "/properties/dateString", + schemaPath: "#/properties/properties/properties/dateString/format", + }, + type: "Unknown-Violation", + } + ] } ]; diff --git a/test/__tests__/user_transformation.integration.test.js b/test/__tests__/user_transformation.integration.test.js index 183c07a2d5..cf184f12f4 100644 --- a/test/__tests__/user_transformation.integration.test.js +++ b/test/__tests__/user_transformation.integration.test.js @@ -7,17 +7,18 @@ const { setupUserTransformHandler } = require("../../src/util/customTransformer"); const { - generateFunctionName + generateFunctionName, setOpenFaasUserTransform } = require("../../src/util/customTransformer-faas"); const { deleteFunction, getFunctionList, getFunction } = require("../../src/util/openfaas/faasApi"); -const { invalidateFnCache } = require("../../src/util/openfaas/index"); +const { invalidateFnCache, awaitFunctionReadiness, FAAS_AST_FN_NAME, FAAS_AST_VID } = require("../../src/util/openfaas/index"); +const { extractLibraries } = require('../../src/util/customTransformer'); const { RetryRequestError } = require("../../src/util/utils"); -jest.setTimeout(15000); +jest.setTimeout(25000); jest.mock("axios", () => ({ ...jest.requireActual("axios") })); @@ -35,6 +36,24 @@ const contructTrRevCode = vid => { }; }; +const faasCodeParsedForLibs = [ + { + code: "import uuid\nimport requests\ndef transformEvent(event, metadata):\n return event\n", + language: "pythonfaas", + response: { + uuid: [], + requests: [] + }, + }, + { + code: "from time import sleep\ndef transformBatch(events, metadata):\n return events\n", + language: "pythonfaas", + response: { + time: [] + }, + } +] + describe("Function Creation Tests", () => { afterAll(async () => { (await getFunctionList()).forEach(fn => { @@ -127,3 +146,24 @@ describe("Function invocation & creation tests", () => { expect(deployedFn.name).toEqual(funcName); }); }); + +describe("Auxiliary tests", () => { + beforeAll(async () => { + (await setOpenFaasUserTransform( + { + language: "pythonfaas", + versionId: FAAS_AST_VID + }, + true, + FAAS_AST_FN_NAME + )); + + await awaitFunctionReadiness(FAAS_AST_FN_NAME); + }); + it("Should be able to extract libraries from code", async () => { + for(const testObj of faasCodeParsedForLibs) { + const response = await extractLibraries(testObj.code, testObj.validateImports || false, testObj.language); + expect(response).toEqual(testObj.response); + } + }); +}); \ No newline at end of file diff --git a/test/__tests__/user_transformation.test.js b/test/__tests__/user_transformation.test.js index 452bf15e7b..1237891d33 100644 --- a/test/__tests__/user_transformation.test.js +++ b/test/__tests__/user_transformation.test.js @@ -842,7 +842,7 @@ describe("User transformation", () => { expect(output).toEqual(expectedData); }); - it(`Simple ${name} Test for library parser`, () => { + it(`Simple ${name} Test for library parser`, async () => { const outputImport = { "@angular2/core": ["Component"], "module-name1": ["defaultMember"], @@ -864,11 +864,57 @@ describe("User transformation", () => { import { member1 , member2 as alias2 , member3 as alias3 } from "module-name6"; import defaultMember, { member, member } from "module-name7"; `; - const output = parserForImport(code); + const output = await parserForImport(code); expect(output).toEqual(outputImport); }); + it(`Simple ${name} Test for invalid library import error`, async () => { + const versionId = randomID(); + const libraryVersionId = randomID(); + const inputData = require(`./data/${integration}_input.json`); + + const respBody = { + code: ` + import { add } from 'addLib'; + import { sub } from 'somelib'; + export async function transformEvent(event, metadata) { + event.add = add(1, 2); + event.sub = sub(1, 2); + return event; + } + `, + name: "import from non existing library", + codeVersion: "1" + }; + respBody.versionId = versionId; + const transformerUrl = `https://api.rudderlabs.com/transformation/getByVersionId?versionId=${versionId}`; + when(fetch) + .calledWith(transformerUrl) + .mockResolvedValue({ + status: 200, + json: jest.fn().mockResolvedValue(respBody) + }); + + const addLibCode = ` + export function add(a, b) { + return a + b; + } + `; + + const libraryUrl = `https://api.rudderlabs.com/transformationLibrary/getByVersionId?versionId=${libraryVersionId}`; + when(fetch) + .calledWith(libraryUrl) + .mockResolvedValue({ + status: 200, + json: jest.fn().mockResolvedValue({ code: addLibCode, name: "addLib" }) + }); + + await expect(async () => { + await userTransformHandler(inputData, versionId, [libraryVersionId]); + }).rejects.toThrow("import from somelib failed. Module not found."); + }); + it(`Simple ${name} async test for V1 transformation code`, async () => { const libraryVersionId = randomID(); const inputData = require(`./data/${integration}_input.json`); @@ -1054,6 +1100,67 @@ describe("Timeout tests", () => { }); }); +describe("Rudder library tests", () => { + beforeEach(() => {}); + it(`Simple ${name} async test for V1 transformation - with rudder library urlParser `, async () => { + const versionId = randomID(); + const rudderLibraryImportName = '@rs/urlParser/v1'; + const [name, version] = rudderLibraryImportName.split('/').slice(-2); + const inputData = require(`./data/${integration}_input_large.json`); + const expectedData = require(`./data/${integration}_async_output_large.json`); + + const respBody = { + code: ` + import url from '@rs/urlParser/v1'; + async function foo() { + return 'resolved'; + } + export async function transformEvent(event, metadata) { + const pr = await foo(); + if(event.properties && event.properties.url){ + const x = new url.URLSearchParams(event.properties.url).get("client"); + } + event.promise = pr; + return event; + } + `, + name: "urlParser", + codeVersion: "1" + }; + respBody.versionId = versionId; + const transformerUrl = `https://api.rudderlabs.com/transformation/getByVersionId?versionId=${versionId}`; + when(fetch) + .calledWith(transformerUrl) + .mockResolvedValue({ + status: 200, + json: jest.fn().mockResolvedValue(respBody) + }); + + const urlCode = `${fs.readFileSync( + path.resolve(__dirname, "../../src/util/url-search-params.min.js"), + "utf8" + )}; + export default self; + `; + + const rudderLibraryUrl = `https://api.rudderlabs.com/rudderstackTransformationLibraries/${name}?version=${version}`; + when(fetch) + .calledWith(rudderLibraryUrl) + .mockResolvedValue({ + status: 200, + json: jest.fn().mockResolvedValue({ code: urlCode, name: "urlParser", importName: rudderLibraryImportName }) + }); + + const output = await userTransformHandler(inputData, versionId, []); + + expect(fetch).toHaveBeenCalledWith( + `https://api.rudderlabs.com/transformation/getByVersionId?versionId=${versionId}` + ); + + expect(output).toEqual(expectedData); + }); +}); + // Running tests for python transformations with openfaas mocks describe("Python transformations", () => { beforeEach(() => { @@ -1170,7 +1277,7 @@ describe("Python transformations", () => { expect(output).toEqual(outputData); expect(axios.post).toHaveBeenCalledTimes(2); - expect(axios.get).toHaveBeenCalledTimes(1); + expect(axios.get).toHaveBeenCalledTimes(2); expect(axios.delete).toHaveBeenCalledTimes(1); }); diff --git a/test/__tests__/webhook-cdk.test.js b/test/__tests__/webhook-cdk.test.js new file mode 100644 index 0000000000..e9e203e141 --- /dev/null +++ b/test/__tests__/webhook-cdk.test.js @@ -0,0 +1,64 @@ +const fs = require("fs"); +const path = require("path"); +const { processCdkV2Workflow } = require("../../src/cdk/v2/handler"); +const tags = require("../../src/v0/util/tags"); + +const integration = "webhook"; +const name = "Webhook"; + +const inputDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}_input.json`) +); +const outputDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}_output.json`) +); +const inputData = JSON.parse(inputDataFile); +const expectedData = JSON.parse(outputDataFile); + +describe(`${name} Tests`, () => { + describe("Processor Tests", () => { + inputData.forEach((input, index) => { + it(`${name} - payload: ${index}`, async () => { + const expected = expectedData[index]; + try { + const output = await processCdkV2Workflow( + integration, + input, + tags.FEATURES.PROCESSOR + ); + expect(output).toEqual(expected); + } catch (error) { + expect(error.message).toEqual(expected.message); + } + }); + }); + }); + + const inputRouterDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}_router_input.json`) + ); + const outputRouterDataFile = fs.readFileSync( + path.resolve(__dirname, `./data/${integration}_router_output.json`) + ); + const inputRouterData = JSON.parse(inputRouterDataFile); + const expectedRouterData = JSON.parse(outputRouterDataFile); + + describe("Router Tests", () => { + inputRouterData.forEach((input, index) => { + it(`${name} - payload: ${index}`, async () => { + const expected = expectedRouterData[index]; + try { + const output = await processCdkV2Workflow( + integration, + input, + tags.FEATURES.ROUTER + ); + expect(output).toEqual(expected); + } catch (error) { + // console.log(error); + expect(error.message).toEqual(expected.message); + } + }); + }); + }); +}); diff --git a/test/__tests__/webhook.test.js b/test/__tests__/webhook.test.js index 9af179b8aa..80da88d989 100644 --- a/test/__tests__/webhook.test.js +++ b/test/__tests__/webhook.test.js @@ -40,9 +40,19 @@ describe(`${name} Tests`, () => { }); describe("Router Tests", () => { - it("Payload", async () => { - const routerOutput = await transformer.processRouterDest(inputRouterData); - expect(routerOutput).toEqual(expectedRouterData); + inputRouterData.forEach((input, index) => { + it(`${name} Tests: payload - ${index}`, async () => { + let output, expected; + try { + output = await transformer.processRouterDest(input); + expected = expectedRouterData[index]; + } catch (error) { + output = error.message; + // console.log(output); + expected = expectedRouterData[index].message; + } + expect(output).toEqual(expected); + }); }); }); }); diff --git a/test/integrations/destinations/canny/data.js b/test/integrations/destinations/canny/data.js new file mode 100644 index 0000000000..2d984ae7a7 --- /dev/null +++ b/test/integrations/destinations/canny/data.js @@ -0,0 +1,1848 @@ +const data = [ + { + "name": "canny", + "description": "Identify call for creating or updating user", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "FXLkLUEhGJyvmY4" + } + }, + "message": { + "type": "identify", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "name": "First User", + "email": "firstUser@testmail.com", + "title": "VP", + "gender": "female", + "avatar": "https://i.pravatar.cc/300" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "output": { + "version": "1", + "userId": "", + "type": "REST", + "method": "POST", + "endpoint": "https://canny.io/api/v1/users/create_or_update", + "headers": { + "Authorization": "Basic FXLkLUEhGJyvmY4", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "customFields": { + "city": "Pune", + "title": "VP", + "gender": "female" + }, + "apiKey": "FXLkLUEhGJyvmY4", + "userID": "user123456001", + "email": "firstUser@testmail.com", + "name": "First User", + "created": "2022-01-20T13:39:21.032Z", + "avatarURL": "https://i.pravatar.cc/300" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + }, + "statusCode": 200 + }] + } + } + }, + { + "name": "canny", + "description": "Identify call without sending userId", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "FXLkLUEhGJyvmY4" + } + }, + "message": { + "type": "identify", + "sentAt": "2022-01-20T13:39:21.033Z", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "name": "First User", + "email": "firstUser@testmail.com", + "title": "VP", + "gender": "female" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "FXLkLUEhGJyvmY4" + } + }, + "error": "Missing required value from \"userIdOnly\"", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "Identify call without sending name", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "FXLkLUEhGJyvmY4" + } + }, + "message": { + "type": "identify", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "email": "firstUser@testmail.com", + "title": "VP", + "gender": "female" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "FXLkLUEhGJyvmY4" + } + }, + "error": "Missing required value from \"name\"", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "Sending page call", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "FXLkLUEhGJyvmY4" + } + }, + "message": { + "type": "page", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "email": "firstUser@testmail.com", + "title": "VP", + "gender": "female" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "FXLkLUEhGJyvmY4" + } + }, + "error": "Message type not supported", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "Sending without API Key", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "" + } + }, + "message": { + "type": "page", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "email": "firstUser@testmail.com", + "title": "VP", + "gender": "female" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "" + } + }, + "error": "API Key is not present. Aborting message.", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "configuration", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "Sending without message type", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "api123" + } + }, + "message": { + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "email": "firstUser@testmail.com", + "title": "VP", + "gender": "female" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "api123" + } + }, + "error": "Message Type is not present. Aborting message.", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "specifying multiple events for one event name and vice versa.", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc", + "to": "createVote" + }, + { + "from": "abc", + "to": "createPost" + }, + { + "from": "def", + "to": "createPost" + } + ] + } + }, + "message": { + "postID": "postid", + "event": "abc", + "type": "track", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "properties": { + "postID": "postid", + "boardID": "boardid", + "title": "title", + "details": "details" + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "name": "First User", + "email": "rohithkaza@rudderstack.com", + "title": "VP", + "gender": "male" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "version": "1", + "type": "REST", + "userId": "", + "method": "POST", + "endpoint": "https://canny.io/api/v1/votes/create", + "headers": { + "Authorization": "Basic apikey123", + "Content-Type": "application/x-www-form-urlencoded" + }, + "params": {}, + "body": { + "JSON": {}, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": { + "postID": "postid", + "apiKey": "apikey123", + "voterID": "52d14c90fff7c80abcd12345" + } + }, + "files": {} + }, + "statusCode": 200, + }, + { + "output": { + "version": "1", + "type": "REST", + "userId": "", + "method": "POST", + "endpoint": "https://canny.io/api/v1/posts/create", + "headers": { + "Authorization": "Basic apikey123", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "apiKey": "apikey123", + "boardID": "boardid", + "details": "details", + "title": "title", + "authorID": "52d14c90fff7c80abcd12345" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + }, + "statusCode": 200, + } + ] + } + } + }, + { + "name": "canny", + "description": "mapping event to createPost", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc def", + "to": "createPost" + } + ] + } + }, + "message": { + "boardID": "postid", + "event": " abc def ", + "type": "track", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "properties": { + "boardID": "boardid", + "title": "title", + "details": "details" + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "name": "First User", + "email": "rohithkaza@rudderstack.com", + "title": "VP", + "gender": "male" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "output": + { + "version": "1", + "type": "REST", + "method": "POST", + "userId": "", + "endpoint": "https://canny.io/api/v1/posts/create", + "headers": { + "Authorization": "Basic apikey123", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "FORM": {}, + "JSON_ARRAY": {}, + "XML": {}, + "JSON": { + "apiKey": "apikey123", + "authorID": "52d14c90fff7c80abcd12345", + "boardID": "boardid", + "details": "details", + "title": "title" + } + }, + "files": {} + }, + "statusCode": 200 + }] + } + } + }, + { + "name": "canny", + "description": "mapping single event to same event multiple times", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "sample", + "to": "createPost" + }, + { + "from": "sample", + "to": "createPost" + }, + { + "from": "sample", + "to": "createPost" + } + ] + } + }, + "message": { + "anonymousId": "d6a9d06e8a464324d448003ff0467d971a55ca2950e11fc51faaec4e2850ecc6", + "event": "sample", + "integrations": { "Canny": false }, + "context": { + "library": { + "name": "unknown", + "version": "unknown" + }, + "integration": { + "name": "Canny", + "version": "1.0.0" + }, + "traits": { + "created": "2022-07-15T11:16:32.648Z", + "email": "rohithkaza@abc.com", + "isAdmin": true, + "name": "Rohith Kumar Kaza", + "url": "https://rudder.canny.io/admin/users/rohith-kumar-kaza-1" + }, + "externalId": [ + { + "type": "cannyUserId", + "id": "62d1" + } + ] + }, + "timestamp": "2022-07-28T10:52:46.294Z", + "originalTimestamp": "2022-07-28T10:52:46.294Z", + "type": "track", + "properties": { + "board": { + "created": "2022-07-25T12:11:19.895Z", + "id": "62de8", + "name": "features", + "postCount": 13, + "url": "https://rudder.canny.io/admin/board/features" + }, + "by": null, + "category": null, + "commentCount": 0, + "created": "2022-07-28T10:52:46.172Z", + "customFields": [{ "id": "62e138", "name": "abc", "value": "123" }], + "details": "Array of images", + "eta": null, + "id": "62e26a", + "imageURLs": [ + "https://canny.io/images/6371453a825c79351c52a6063c3af476.jpg", + "https://canny.io/images/47db6ee5035bfb45ea87a74f2eb17928.jpg" + ], + "objectType": "post", + "owner": null, + "score": 1, + "status": "open", + "tags": [], + "title": "Custom Fields Testing", + "url": "https://rudder.canny.io/admin/board/features/p/custom-fields-testing" + } + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "output": + { + "version": "1", + "type": "REST", + "userId": "", + "method": "POST", + "endpoint": "https://canny.io/api/v1/posts/create", + "headers": { + "Authorization": "Basic apikey123", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "FORM": {}, + "JSON_ARRAY": {}, + "XML": {}, + "JSON": { + "apiKey": "apikey123", + "authorID": "62d1", + "boardID": "62de8", + "details": "Array of images", + "title": "Custom Fields Testing", + "imageURLs": [ + "https://canny.io/images/6371453a825c79351c52a6063c3af476.jpg", + "https://canny.io/images/47db6ee5035bfb45ea87a74f2eb17928.jpg" + ], + "customFields": [{ "id": "62e138", "name": "abc", "value": "123" }] + } + }, + "files": {} + }, + "statusCode": 200 + }] + } + } + }, + { + "name": "canny", + "description": "Event is not found in mapping", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "sample", + "to": "createPost" + }, + { + "from": "sample2", + "to": "createPost" + } + ] + } + }, + "message": { + "anonymousId": "d6a9d06e8a464324d448003ff0467d971a55ca2950e11fc51faaec4e2850ecc6", + "event": "sample3", + "integrations": { "Canny": false }, + "context": { + "library": { + "name": "unknown", + "version": "unknown" + }, + "integration": { + "name": "Canny", + "version": "1.0.0" + }, + "traits": { + "created": "2022-07-15T11:16:32.648Z", + "email": "rohithkaza@abc.com", + "isAdmin": true, + "name": "Rohith Kumar Kaza", + "url": "https://rudder.canny.io/admin/users/rohith-kumar-kaza-1" + }, + "externalId": [ + { + "type": "cannyUserId", + "value": "62d1" + } + ] + }, + "timestamp": "2022-07-28T10:52:46.294Z", + "originalTimestamp": "2022-07-28T10:52:46.294Z", + "type": "track", + "properties": { + "board": { + "created": "2022-07-25T12:11:19.895Z", + "id": "62de8", + "name": "features", + "postCount": 13, + "url": "https://rudder.canny.io/admin/board/features" + }, + "by": null, + "category": null, + "commentCount": 0, + "created": "2022-07-28T10:52:46.172Z", + "customFields": [{ "id": "62e138", "name": "abc", "value": "123" }], + "details": "Array of images", + "eta": null, + "id": "62e26a", + "imageURLs": [ + "https://canny.io/images/6371453a825c79351c52a6063c3af476.jpg", + "https://canny.io/images/47db6ee5035bfb45ea87a74f2eb17928.jpg" + ], + "objectType": "post", + "owner": null, + "score": 1, + "status": "open", + "tags": [], + "title": "Custom Fields Testing", + "url": "https://rudder.canny.io/admin/board/features/p/custom-fields-testing" + } + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "sample", + "to": "createPost" + }, + { + "from": "sample2", + "to": "createPost" + } + ] + } + }, + "error": "Event name (sample3) is not present in the mapping", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "Sending without Event Name", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "sample", + "to": "createPost" + }, + { + "from": "sample", + "to": "createPost" + }, + { + "from": "sample", + "to": "createPost" + } + ] + } + }, + "message": { + "anonymousId": "d6a9d06e8a464324d448003ff0467d971a55ca2950e11fc51faaec4e2850ecc6", + "integrations": { "Canny": false }, + "context": { + "library": { + "name": "unknown", + "version": "unknown" + }, + "integration": { + "name": "Canny", + "version": "1.0.0" + }, + "traits": { + "created": "2022-07-15T11:16:32.648Z", + "email": "rohithkaza@abc.com", + "isAdmin": true, + "name": "Rohith Kumar Kaza", + "url": "https://rudder.canny.io/admin/users/rohith-kumar-kaza-1" + }, + "externalId": [ + { + "type": "cannyUserId", + "value": "62d1" + } + ] + }, + "timestamp": "2022-07-28T10:52:46.294Z", + "originalTimestamp": "2022-07-28T10:52:46.294Z", + "type": "track", + "properties": { + "board": { + "created": "2022-07-25T12:11:19.895Z", + "id": "62de8", + "name": "features", + "postCount": 13, + "url": "https://rudder.canny.io/admin/board/features" + }, + "by": null, + "category": null, + "commentCount": 0, + "created": "2022-07-28T10:52:46.172Z", + "customFields": [{ "id": "62e138", "name": "abc", "value": "123" }], + "details": "Array of images", + "eta": null, + "id": "62e26a", + "imageURLs": [ + "https://canny.io/images/6371453a825c79351c52a6063c3af476.jpg", + "https://canny.io/images/47db6ee5035bfb45ea87a74f2eb17928.jpg" + ], + "objectType": "post", + "owner": null, + "score": 1, + "status": "open", + "tags": [], + "title": "Custom Fields Testing", + "url": "https://rudder.canny.io/admin/board/features/p/custom-fields-testing" + } + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "sample", + "to": "createPost" + }, + { + "from": "sample", + "to": "createPost" + }, + { + "from": "sample", + "to": "createPost" + } + ] + } + }, + "error": "Event name is required", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "Sending empty mapping", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [] + } + }, + "message": { + "anonymousId": "d6a9d06e8a464324d448003ff0467d971a55ca2950e11fc51faaec4e2850ecc6", + "event": "abc", + "integrations": { "Canny": false }, + "context": { + "library": { + "name": "unknown", + "version": "unknown" + }, + "integration": { + "name": "Canny", + "version": "1.0.0" + }, + "traits": { + "created": "2022-07-15T11:16:32.648Z", + "email": "rohithkaza@abc.com", + "isAdmin": true, + "name": "Rohith Kumar Kaza", + "url": "https://rudder.canny.io/admin/users/rohith-kumar-kaza-1" + }, + "externalId": [ + { + "type": "cannyUserId", + "value": "62d1" + } + ] + }, + "timestamp": "2022-07-28T10:52:46.294Z", + "originalTimestamp": "2022-07-28T10:52:46.294Z", + "type": "track", + "properties": { + "board": { + "created": "2022-07-25T12:11:19.895Z", + "id": "62de8", + "name": "features", + "postCount": 13, + "url": "https://rudder.canny.io/admin/board/features" + }, + "by": null, + "category": null, + "commentCount": 0, + "created": "2022-07-28T10:52:46.172Z", + "customFields": [{ "id": "62e138", "name": "abc", "value": "123" }], + "details": "Array of images", + "eta": null, + "id": "62e26a", + "imageURLs": [ + "https://canny.io/images/6371453a825c79351c52a6063c3af476.jpg", + "https://canny.io/images/47db6ee5035bfb45ea87a74f2eb17928.jpg" + ], + "objectType": "post", + "owner": null, + "score": 1, + "status": "open", + "tags": [], + "title": "Custom Fields Testing", + "url": "https://rudder.canny.io/admin/board/features/p/custom-fields-testing" + } + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [] + } + }, + "error": "Event name (abc) is not present in the mapping", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "create vote without postId", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc", + "to": "createVote" + } + ] + } + }, + "message": { + "event": "abc", + "type": "track", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "properties": { + "boardID": "boardid", + "title": "title", + "details": "details" + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "name": "First User", + "email": "rohithkaza@rudderstack.com", + "title": "VP", + "gender": "male" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc", + "to": "createVote" + } + ] + } + }, + "error": "Missing required value from [\"properties.postID\",\"properties.postId\",\"properties.post.id\"]", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "create post without boardId", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc def", + "to": "createPost" + } + ] + } + }, + "message": { + "boardID": "postid", + "event": " abc def ", + "type": "track", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "properties": { + "title": "title", + "details": "details" + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "name": "First User", + "email": "rohithkaza@rudderstack.com", + "title": "VP", + "gender": "male" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc def", + "to": "createPost" + } + ] + } + }, + "error": "Missing required value from [\"properties.boardID\",\"properties.boardId\",\"properties.board.id\"]", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "create post without title", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc def", + "to": "createPost" + } + ] + } + }, + "message": { + "boardID": "postid", + "event": " abc def ", + "type": "track", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "properties": { + "boardID": "boardid", + "details": "details" + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "name": "First User", + "email": "rohithkaza@rudderstack.com", + "title": "VP", + "gender": "male" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc def", + "to": "createPost" + } + ] + } + }, + "error": "Missing required value from \"properties.title\"", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + }, + { + "name": "canny", + "description": "create post without details", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc def", + "to": "createPost" + } + ] + } + }, + "message": { + "boardID": "postid", + "event": " abc def ", + "type": "track", + "sentAt": "2022-01-20T13:39:21.033Z", + "userId": "user123456001", + "channel": "web", + "properties": { + "boardID": "boardid", + "title": "title" + }, + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.2.20", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", + "title": "Document", + "search": "", + "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", + "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", + "initial_referrer": "$direct", + "referring_domain": "127.0.0.1:7307", + "initial_referring_domain": "" + }, + "locale": "en-US", + "screen": { + "width": 1440, + "height": 900, + "density": 2, + "innerWidth": 536, + "innerHeight": 689 + }, + "traits": { + "city": "Pune", + "name": "First User", + "email": "rohithkaza@rudderstack.com", + "title": "VP", + "gender": "male" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.2.20" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" + }, + "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", + "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", + "anonymousId": "bf412108-0357-4330-b119-7305e767823c", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-01-20T13:39:21.032Z" + } + }], + "method": "POST" + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [{ + "destination": { + "Config": { + "apiKey": "apikey123", + "eventsToEvents": [ + { + "from": "abc def", + "to": "createPost" + } + ] + } + }, + "error": "Missing required value from \"properties.details\"", + "statTags": { + "destType": "CANNY", + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "feature": "processor", + "implementation": "native", + "module": "destination", + }, + "statusCode": 400 + }] + } + } + } +]; + +module.exports = { + data +} diff --git a/test/integrations/destinations/testTypes.d.ts b/test/integrations/destinations/testTypes.d.ts new file mode 100644 index 0000000000..d0da7254af --- /dev/null +++ b/test/integrations/destinations/testTypes.d.ts @@ -0,0 +1,39 @@ +interface requestType { + method: string, + body?: any, + headers?: Record, + params?: Record +} + +interface responseType { + status: number, + body?: any, + headers?: Record +} + +interface inputType { + request: requestType, + pathSuffix?: string +} + +interface outputType { + response?: responseType +} + +interface mockType { + request: requestType, + response: responseType +} + +interface testCaseDataType { + name: string, + description: string, + feature: string, + module: string, + version?: string + input: inputType, + output: outputType, + mock?: mockType[] +}; + + diff --git a/test/integrations/integrations.test.js b/test/integrations/integrations.test.js new file mode 100644 index 0000000000..6ec093e6c8 --- /dev/null +++ b/test/integrations/integrations.test.js @@ -0,0 +1,110 @@ +const path = require("path"); +const Koa = require("koa"); +const bodyParser = require("koa-bodyparser"); + +const { router } = require("../../src/versionedRouter"); +const { getTestDataFilePaths, getTestData } = require("./testUtils"); +const tags = require("../../src/v0/util/tags"); +const supertest = require("supertest"); + +// Initialize application +const app = new Koa(); +app.use( + bodyParser({ + jsonLimit: "200mb" + }) +); +app.use(router.routes()).use(router.allowedMethods()); + +const rootDir = __dirname; +const allTestDataFilePaths = getTestDataFilePaths(rootDir); +const DEFAULT_VERSION = "v0"; + +const testRoute = async (route, tcData) => { + const inputReq = tcData.input.request; + let stHandler = supertest(app.callback()); + const { headers, params, body } = inputReq; + switch (inputReq.method) { + case "GET": + stHandler = stHandler.get(route); + break; + case "PUT": + stHandler = stHandler.put(route); + break; + case "DELETE": + stHandler = stHandler.delete(route); + break; + default: + stHandler = stHandler.post(route); + break; + } + + const response = await stHandler + .set(headers || {}) + .query(params || {}) + .send(body || ""); + + const outputResp = tcData.output.response; + expect(response.status).toEqual(outputResp.status); + + if (outputResp && outputResp.body) { + expect(response.body).toEqual(outputResp.body); + } + + if (outputResp.headers !== undefined) { + expect(response.headers).toEqual(outputResp.headers); + } +} + +const destinationTestHandler = async (tcData) => { + let route; + switch (tcData.feature) { + case tags.FEATURES.ROUTER: + route = `/routerTransform`; + break; + case tags.FEATURES.BATCH: + route = `/batch`; + break; + case tags.FEATURES.DATA_DELIVERY: + route = `/${path.join(tcData.version || DEFAULT_VERSION, "destinations", tcData.name, "proxy")}`; + break; + case tags.FEATURES.USER_DELETION: + route = 'deleteUsers'; + break; + case tags.FEATURES.PROCESSOR: + // Processor transformation + route = `/${path.join(tcData.version || DEFAULT_VERSION, "destinations", tcData.name)}`; + break; + default: + // Intentionally fail the test case + expect(true).toEqual(false); + break; + } + route = path.join(route, tcData.input.pathSuffix); + await testRoute(route, tcData); +}; + +const sourceTestHandler = async (tcData) => { + const route = `/${path.join(tcData.version || DEFAULT_VERSION, "sources", tcData.name, tcData.input.pathSuffix)}`; + await testRoute(route, tcData); +}; + +// Trigger the test suites +describe.each(allTestDataFilePaths)("%s Tests", (testDataPath) => { + const testData = getTestData(testDataPath); + test.each(testData)('$name - $module - $feature -> $description', async (tcData) => { + switch (tcData.module) { + case tags.MODULES.DESTINATION: + await destinationTestHandler(tcData); + break; + case tags.MODULES.SOURCE: + await sourceTestHandler(tcData); + break; + default: + console.log('Invalid module'); + // Intentionally fail the test case + expect(true).toEqual(false); + break; + } + }); +}); diff --git a/test/integrations/sources/moengage/data.js b/test/integrations/sources/moengage/data.js new file mode 100644 index 0000000000..4d785d0788 --- /dev/null +++ b/test/integrations/sources/moengage/data.js @@ -0,0 +1,736 @@ +const data = [ + { + "name": "moengage", + "description": "Simple track call", + "module": "source", + "version": "v0", + "input": { + "request": { + "body": [ + { + "anonymousId": "4eb021e9-a2af-4926-ae82-fe996d12f3c5", + "channel": "web", + "context": { + "timezone": "Wrong/Timezone", + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.1.6" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.6" + }, + "locale": "en-GB", + "os": { + "name": "", + "version": "" + }, + "page": { + "path": "/testing/script-test.html", + "referrer": "", + "search": "", + "title": "", + "url": "http://localhost:3243/testing/script-test.html" + }, + "screen": { + "density": 2 + }, + "traits": { + "company": { + "id": "abc123" + }, + "createdAt": "Thu Mar 24 2016 17:46:45 GMT+0000 (UTC)", + "email": "ruchira@gmail.com", + "name": "Ruchira Moitra", + "plan": "Enterprise" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36" + }, + "event": "Order Completed", + "integrations": { + "All": true + }, + "messageId": "a0adfab9-baf7-4e09-a2ce-bbe2844c324a", + "originalTimestamp": "2020-10-16T08:10:12.782Z", + "properties": { + "checkout_id": "what is checkout id here??", + "coupon": "APPARELSALE", + "currency": "GBP", + "order_id": "transactionId", + "products": [ + { + "brand": "", + "category": "Merch", + "currency": "GBP", + "image_url": "https://www.example.com/product/bacon-jam.jpg", + "name": "Food/Drink", + "position": 1, + "price": 3, + "product_id": "product-bacon-jam", + "quantity": 2, + "sku": "sku-1", + "typeOfProduct": "Food", + "url": "https://www.example.com/product/bacon-jam", + "value": 6, + "variant": "Extra topped" + }, + { + "brand": "Levis", + "category": "Merch", + "currency": "GBP", + "image_url": "https://www.example.com/product/t-shirt.jpg", + "name": "T-Shirt", + "position": 2, + "price": 12.99, + "product_id": "product-t-shirt", + "quantity": 1, + "sku": "sku-2", + "typeOfProduct": "Shirt", + "url": "https://www.example.com/product/t-shirt", + "value": 12.99, + "variant": "White" + }, + { + "brand": "Levis", + "category": "Merch", + "coupon": "APPARELSALE", + "currency": "GBP", + "image_url": "https://www.example.com/product/offer-t-shirt.jpg", + "name": "T-Shirt-on-offer", + "position": 1, + "price": 12.99, + "product_id": "offer-t-shirt", + "quantity": 1, + "sku": "sku-3", + "typeOfProduct": "Shirt", + "url": "https://www.example.com/product/offer-t-shirt", + "value": 12.99, + "variant": "Black" + } + ], + "revenue": 31.98, + "shipping": 4, + "value": 31.98 + }, + "receivedAt": "2020-10-16T13:40:12.792+05:30", + "request_ip": "[::1]", + "sentAt": "2020-10-16T08:10:12.783Z", + "timestamp": "2020-10-16T13:40:12.791+05:30", + "type": "track", + "userId": "ruchu123" + } + ], + "method": "POST", + "headers": { + "Content-Type": "application/json" + } + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "batch": [ + { + "anonymousId": "4eb021e9-a2af-4926-ae82-fe996d12f3c5", + "channel": "web", + "context": { + "timezone": "Wrong/Timezone", + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.1.6" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.6" + }, + "locale": "en-GB", + "os": { + "name": "", + "version": "" + }, + "page": { + "path": "/testing/script-test.html", + "referrer": "", + "search": "", + "title": "", + "url": "http://localhost:3243/testing/script-test.html" + }, + "screen": { + "density": 2 + }, + "traits": { + "company": { + "id": "abc123" + }, + "createdAt": "Thu Mar 24 2016 17:46:45 GMT+0000 (UTC)", + "email": "ruchira@gmail.com", + "name": "Ruchira Moitra", + "plan": "Enterprise" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36" + }, + "event": "Order Completed", + "integrations": { + "All": true + }, + "messageId": "a0adfab9-baf7-4e09-a2ce-bbe2844c324a", + "originalTimestamp": "2020-10-16T08:10:12.782Z", + "properties": { + "checkout_id": "what is checkout id here??", + "coupon": "APPARELSALE", + "currency": "GBP", + "order_id": "transactionId", + "products": [ + { + "brand": "", + "category": "Merch", + "currency": "GBP", + "image_url": "https://www.example.com/product/bacon-jam.jpg", + "name": "Food/Drink", + "position": 1, + "price": 3, + "product_id": "product-bacon-jam", + "quantity": 2, + "sku": "sku-1", + "typeOfProduct": "Food", + "url": "https://www.example.com/product/bacon-jam", + "value": 6, + "variant": "Extra topped" + }, + { + "brand": "Levis", + "category": "Merch", + "currency": "GBP", + "image_url": "https://www.example.com/product/t-shirt.jpg", + "name": "T-Shirt", + "position": 2, + "price": 12.99, + "product_id": "product-t-shirt", + "quantity": 1, + "sku": "sku-2", + "typeOfProduct": "Shirt", + "url": "https://www.example.com/product/t-shirt", + "value": 12.99, + "variant": "White" + }, + { + "brand": "Levis", + "category": "Merch", + "coupon": "APPARELSALE", + "currency": "GBP", + "image_url": "https://www.example.com/product/offer-t-shirt.jpg", + "name": "T-Shirt-on-offer", + "position": 1, + "price": 12.99, + "product_id": "offer-t-shirt", + "quantity": 1, + "sku": "sku-3", + "typeOfProduct": "Shirt", + "url": "https://www.example.com/product/offer-t-shirt", + "value": 12.99, + "variant": "Black" + } + ], + "revenue": 31.98, + "shipping": 4, + "value": 31.98 + }, + "receivedAt": "2020-10-16T13:40:12.792+05:30", + "request_ip": "[::1]", + "sentAt": "2020-10-16T08:10:12.783Z", + "timestamp": "2020-10-16T13:40:12.791+05:30", + "type": "track", + "userId": "ruchu123" + } + ] + } + } + ] + } + } + }, + { + "name": "moengage", + "description": "Batch of events", + "module": "source", + "version": "v0", + "input": { + "request": { + "body": [ + { + "batch": [ + { + "type": "page", + "event": "home", + "sentAt": "2020-11-12T21:12:54.117Z", + "userId": "sajal", + "channel": "mobile", + "context": { + "traits": { + + }, + "library": { + "name": "rudder-sdk-ruby-sync", + "version": "1.0.7" + }, + "page": { + "path": "/Rectified.html", + "referrer": "http://localhost:1112/", + "search": "", + "title": "", + "url": "http://localhost:1112/Rectified.html" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 10; Redmi K20 Pro MIUI/V12.0.3.0.QFKINXM)" + }, + "rudderId": "asdfasdfsadf", + "properties": { + "name": "asdfsadf" + }, + "timestamp": "2020-11-12T21:12:41.320Z", + "anonymousId": "123123123123" + }, + { + "anonymousId": "4eb021e9-a2af-4926-ae82-fe996d12f3c5", + "channel": "web", + "context": { + "timezone": "Asia/Tokyo", + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.1.6" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.6" + }, + "locale": "en-GB", + "os": { + "name": "", + "version": "" + }, + "page": { + "path": "/testing/script-test.html", + "referrer": "", + "search": "", + "title": "", + "url": "http://localhost:3243/testing/script-test.html" + }, + "screen": { + "density": 2 + }, + "traits": { + "company": { + "id": "abc123" + }, + "createdAt": "Thu Mar 24 2016 17:46:45 GMT+0000 (UTC)", + "email": "ruchira@gmail.com", + "name": "Ruchira Moitra", + "plan": "Enterprise" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36" + }, + "event": "Order Completed", + "integrations": { + "All": true + }, + "messageId": "a0adfab9-baf7-4e09-a2ce-bbe2844c324a", + "originalTimestamp": "2020-10-16T08:10:12.782Z", + "properties": { + "checkout_id": "what is checkout id here??", + "coupon": "APPARELSALE", + "currency": "GBP", + "order_id": "transactionId", + "category": "some category", + "originalArray": [ + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + } + ], + "products": [ + { + "brand": "", + "category": "Merch", + "currency": "GBP", + "image_url": "https://www.example.com/product/bacon-jam.jpg", + "name": "Food/Drink", + "position": 1, + "price": 3, + "product_id": "product-bacon-jam", + "quantity": 2, + "sku": "sku-1", + "typeOfProduct": "Food", + "url": "https://www.example.com/product/bacon-jam", + "value": 6, + "variant": "Extra topped" + }, + { + "brand": "Levis", + "category": "Merch", + "currency": "GBP", + "image_url": "https://www.example.com/product/t-shirt.jpg", + "name": "T-Shirt", + "position": 2, + "price": 12.99, + "product_id": "product-t-shirt", + "quantity": 1, + "sku": "sku-2", + "typeOfProduct": "Shirt", + "url": "https://www.example.com/product/t-shirt", + "value": 12.99, + "variant": "White" + }, + { + "brand": "Levis", + "category": "Merch", + "coupon": "APPARELSALE", + "currency": "GBP", + "image_url": "https://www.example.com/product/offer-t-shirt.jpg", + "name": "T-Shirt-on-offer", + "position": 1, + "price": 12.99, + "product_id": "offer-t-shirt", + "quantity": 1, + "sku": "sku-3", + "typeOfProduct": "Shirt", + "url": "https://www.example.com/product/offer-t-shirt", + "value": 12.99, + "variant": "Black" + } + ], + "revenue": 31.98, + "shipping": 4, + "value": 31.98 + }, + "receivedAt": "2020-10-16T13:40:12.792+05:30", + "request_ip": "[::1]", + "sentAt": "2020-10-16T08:10:12.783Z", + "timestamp": "2020-10-16T13:40:12.791+05:30", + "type": "track", + "userId": "ruchu123" + } + ] + } + ], + "method": "POST", + "headers": { + "Content-Type": "application/json" + } + }, + "pathSuffix": "" + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "batch": [ + { + "type": "page", + "event": "home", + "sentAt": "2020-11-12T21:12:54.117Z", + "userId": "sajal", + "channel": "mobile", + "context": { + "traits": { + + }, + "library": { + "name": "rudder-sdk-ruby-sync", + "version": "1.0.7" + }, + "page": { + "path": "/Rectified.html", + "referrer": "http://localhost:1112/", + "search": "", + "title": "", + "url": "http://localhost:1112/Rectified.html" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 10; Redmi K20 Pro MIUI/V12.0.3.0.QFKINXM)" + }, + "rudderId": "asdfasdfsadf", + "properties": { + "name": "asdfsadf" + }, + "timestamp": "2020-11-12T21:12:41.320Z", + "anonymousId": "123123123123" + }, + { + "anonymousId": "4eb021e9-a2af-4926-ae82-fe996d12f3c5", + "channel": "web", + "context": { + "timezone": "Asia/Tokyo", + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.1.6" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.6" + }, + "locale": "en-GB", + "os": { + "name": "", + "version": "" + }, + "page": { + "path": "/testing/script-test.html", + "referrer": "", + "search": "", + "title": "", + "url": "http://localhost:3243/testing/script-test.html" + }, + "screen": { + "density": 2 + }, + "traits": { + "company": { + "id": "abc123" + }, + "createdAt": "Thu Mar 24 2016 17:46:45 GMT+0000 (UTC)", + "email": "ruchira@gmail.com", + "name": "Ruchira Moitra", + "plan": "Enterprise" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.80 Safari/537.36" + }, + "event": "Order Completed", + "integrations": { + "All": true + }, + "messageId": "a0adfab9-baf7-4e09-a2ce-bbe2844c324a", + "originalTimestamp": "2020-10-16T08:10:12.782Z", + "properties": { + "checkout_id": "what is checkout id here??", + "coupon": "APPARELSALE", + "currency": "GBP", + "order_id": "transactionId", + "category": "some category", + "originalArray": [ + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + }, + { + "nested_field": "nested value", + "tags": [ + "tag_1", + "tag_2", + "tag_3" + ] + } + ], + "products": [ + { + "brand": "", + "category": "Merch", + "currency": "GBP", + "image_url": "https://www.example.com/product/bacon-jam.jpg", + "name": "Food/Drink", + "position": 1, + "price": 3, + "product_id": "product-bacon-jam", + "quantity": 2, + "sku": "sku-1", + "typeOfProduct": "Food", + "url": "https://www.example.com/product/bacon-jam", + "value": 6, + "variant": "Extra topped" + }, + { + "brand": "Levis", + "category": "Merch", + "currency": "GBP", + "image_url": "https://www.example.com/product/t-shirt.jpg", + "name": "T-Shirt", + "position": 2, + "price": 12.99, + "product_id": "product-t-shirt", + "quantity": 1, + "sku": "sku-2", + "typeOfProduct": "Shirt", + "url": "https://www.example.com/product/t-shirt", + "value": 12.99, + "variant": "White" + }, + { + "brand": "Levis", + "category": "Merch", + "coupon": "APPARELSALE", + "currency": "GBP", + "image_url": "https://www.example.com/product/offer-t-shirt.jpg", + "name": "T-Shirt-on-offer", + "position": 1, + "price": 12.99, + "product_id": "offer-t-shirt", + "quantity": 1, + "sku": "sku-3", + "typeOfProduct": "Shirt", + "url": "https://www.example.com/product/offer-t-shirt", + "value": 12.99, + "variant": "Black" + } + ], + "revenue": 31.98, + "shipping": 4, + "value": 31.98 + }, + "receivedAt": "2020-10-16T13:40:12.792+05:30", + "request_ip": "[::1]", + "sentAt": "2020-10-16T08:10:12.783Z", + "timestamp": "2020-10-16T13:40:12.791+05:30", + "type": "track", + "userId": "ruchu123" + } + ] + } + } + ] + } + } + } + ] + +module.exports = { + data +} \ No newline at end of file diff --git a/test/integrations/testUtils.js b/test/integrations/testUtils.js new file mode 100644 index 0000000000..df1ded03fc --- /dev/null +++ b/test/integrations/testUtils.js @@ -0,0 +1,26 @@ +const fs = require('fs'); +const path = require('path'); + +const getTestDataFilePaths = (dirPath) => { + const dirEntries = fs.readdirSync(dirPath); + const testDataFilePaths = []; + dirEntries.forEach(dEntry => { + const dEntryPath = path.join(dirPath, dEntry); + const stats = fs.statSync(dEntryPath); + if (stats.isFile() && dEntry.toLowerCase() === "data.js") { + testDataFilePaths.push(dEntryPath); + } else if (stats.isDirectory()) { + testDataFilePaths.push(...getTestDataFilePaths(dEntryPath)); + } + }); + return testDataFilePaths; +}; + +const getTestData = (filePath) => { + return require(filePath).data; +} + +module.exports = { + getTestDataFilePaths, + getTestData +}