diff --git a/.coderabbit/config.yml b/.coderabbit/config.yml new file mode 100644 index 0000000000..0639013445 --- /dev/null +++ b/.coderabbit/config.yml @@ -0,0 +1,7 @@ +# .coderabbit/config.yml +reviews: + instructions: + - pattern: '**/*' + instruction: | + # Ignore code coverage issues + Do not mention code coverage warnings or code coverage reports in the review. diff --git a/.eslintignore b/.eslintignore index 7271f521b1..d67659fc27 100644 --- a/.eslintignore +++ b/.eslintignore @@ -16,3 +16,4 @@ tsconfig.build.tsbuildinfo nativeSdkLoader.js nativeSdkLoader.ts assets/ +package.json diff --git a/.github/workflows/deploy-beta.yml b/.github/workflows/deploy-beta.yml index 29835d344c..19977b836a 100644 --- a/.github/workflows/deploy-beta.yml +++ b/.github/workflows/deploy-beta.yml @@ -8,7 +8,7 @@ permissions: contents: read # This is required for actions/checkout env: - NODE_OPTIONS: "--no-warnings" + NODE_OPTIONS: '--no-warnings' jobs: get-deploy-inputs: diff --git a/.github/workflows/deploy-sanity-suite.yml b/.github/workflows/deploy-sanity-suite.yml index 0c73ebfab6..68a2e03cc8 100644 --- a/.github/workflows/deploy-sanity-suite.yml +++ b/.github/workflows/deploy-sanity-suite.yml @@ -50,7 +50,7 @@ permissions: env: NODE_OPTIONS: '--no-warnings' - CACHE_CONTROL: "\"max-age=3600\"" + CACHE_CONTROL: '"max-age=3600"' jobs: deploy: @@ -69,7 +69,7 @@ jobs: current_version=$(jq -r .version packages/sanity-suite/package.json) echo "CURRENT_VERSION_VALUE=$current_version" >> $GITHUB_ENV echo "DATE=$(date)" >> $GITHUB_ENV - + if [ "${{ inputs.environment }}" == "staging" ]; then echo "AWS_ACCOUNT_ID=${{ secrets.AWS_STAGING_ACCOUNT_ID }}" >> $GITHUB_ENV echo "AWS_S3_SYNC_ROLE=${{ secrets.AWS_STAGING_S3_SYNC_ROLE }}" >> $GITHUB_ENV @@ -102,7 +102,7 @@ jobs: - name: Install AWS CLI uses: unfor19/install-aws-cli-action@master - + - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b71bd210d2..9fe4ecf9fc 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -49,7 +49,8 @@ permissions: env: NODE_OPTIONS: "--no-warnings" - CACHE_CONTROL: "\"no-store\"" # "\"max-age=3600\"" + CACHE_CONTROL_NO_STORE: "\"no-store\"" + CACHE_CONTROL_MAX_AGE: "\"max-age=3600\"" jobs: deploy: @@ -77,12 +78,12 @@ jobs: echo "Checkout SHA: $sha" echo "SHA=$sha" >> $GITHUB_OUTPUT - - name: Checkout + - name: Checkout source code uses: actions/checkout@v4 with: ref: ${{ steps.getSHA.outputs.SHA }} - - name: Get new version number + - name: Get new versions run: | current_version_v1=$(jq -r .version packages/analytics-v1.1/package.json) current_version=$(jq -r .version packages/analytics-js/package.json) @@ -96,7 +97,7 @@ jobs: node-version-file: '.nvmrc' cache: 'npm' - - name: Install dependencies + - name: Setup workspace env: HUSKY: 0 REMOTE_MODULES_BASE_PATH: 'https://cdn.rudderlabs.com/${{ inputs.s3_dir_path }}/modern/plugins' @@ -105,7 +106,7 @@ jobs: run: | npm run setup:ci - - name: Build release artifacts + - name: Build artifacts env: BUGSNAG_API_KEY: ${{ secrets.BUGSNAG_API_KEY }} BUGSNAG_RELEASE_STAGE: ${{ inputs.bugsnag_release_stage }} @@ -113,23 +114,36 @@ jobs: npm run build:browser npm run build:browser:modern - - name: Sync Adobe Analytics assets to S3 + - name: Copy assets to S3 if: ${{ inputs.environment == 'production' }} run: | - aws s3 cp assets/integrations/AdobeAnalytics/ s3://${{ secrets.AWS_S3_BUCKET_NAME }}/adobe-analytics-js --recursive --cache-control ${{ env.CACHE_CONTROL }} + aws s3 cp assets/integrations/AdobeAnalytics/ s3://${{ secrets.AWS_S3_BUCKET_NAME }}/adobe-analytics-js --recursive --cache-control ${{ env.CACHE_CONTROL_NO_STORE }} - - name: Create Cloudfront invalidation + - name: Invalidate CloudFront cache for assets if: ${{ inputs.environment == 'production' }} run: | - aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/adobe-analytics-js*" + invalidation_id=$(AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/adobe-analytics-js*" --query "Invalidation.Id" --output text) - - name: Sync files to S3 + aws cloudfront wait invalidation-completed --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --id "$invalidation_id" + + - name: Determine cache policy based on environment + id: cache_policy + run: | + if [ "${{ inputs.environment }}" == "production" ]; then + echo "CACHE_CONTROL=${{ env.CACHE_CONTROL_NO_STORE }}" >> $GITHUB_ENV + else + echo "CACHE_CONTROL=${{ env.CACHE_CONTROL_MAX_AGE }}" >> $GITHUB_ENV + fi + + - name: Copy SDK artifacts to S3 run: | core_sdk_path_prefix="packages/analytics-js/dist/cdn" integration_sdks_path_prefix="packages/analytics-js-integrations/dist/cdn" plugins_path_prefix="packages/analytics-js-plugins/dist/cdn" - s3_path_prefix="s3://${{ secrets.AWS_S3_BUCKET_NAME }}/${{ inputs.s3_dir_path }}" - copy_args="--recursive --cache-control ${{ env.CACHE_CONTROL }}" + s3_relative_path_prefix="${{ inputs.s3_dir_path }}" + s3_path_prefix="s3://${{ secrets.AWS_S3_BUCKET_NAME }}/$s3_relative_path_prefix" + copy_recursive_args="--recursive --cache-control ${{ env.CACHE_CONTROL }}" + copy_args="--cache-control ${{ env.CACHE_CONTROL }}" integration_sdks_zip_file="all_integration_sdks.tar.gz" plugins_zip_file="all_plugins.tar.gz" @@ -152,72 +166,76 @@ jobs: mv "$tmp_file" "$plugins_path_prefix/modern/plugins/$plugins_zip_file" # Upload all the files to S3 - aws s3 cp $core_sdk_path_prefix/legacy/iife/ $s3_path_prefix/legacy/ $copy_args - aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/ $s3_path_prefix/legacy/js-integrations/ $copy_args + aws s3 cp $core_sdk_path_prefix/legacy/iife/ $s3_path_prefix/legacy/ $copy_recursive_args + aws s3 cp $core_sdk_path_prefix/modern/iife/ $s3_path_prefix/modern/ $copy_recursive_args - aws s3 cp $core_sdk_path_prefix/modern/iife/ $s3_path_prefix/modern/ $copy_args - aws s3 cp $plugins_path_prefix/modern/plugins/ $s3_path_prefix/modern/plugins/ $copy_args - aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/ $s3_path_prefix/modern/js-integrations/ $copy_args + aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/ $s3_path_prefix/legacy/js-integrations/ $copy_recursive_args + aws s3 cp $plugins_path_prefix/modern/plugins/ $s3_path_prefix/modern/plugins/ $copy_recursive_args + aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/ $s3_path_prefix/modern/js-integrations/ $copy_recursive_args # Generate the HTML file to list all the integrations - ./scripts/list-sdk-components.sh ${{ secrets.AWS_S3_BUCKET_NAME }} ${{ inputs.s3_dir_path }}/legacy/js-integrations $integration_sdks_html_file $integration_sdks_path_prefix/legacy/js-integrations "Device Mode Integrations" $integration_sdks_zip_file + ./scripts/list-sdk-components.sh ${{ secrets.AWS_S3_BUCKET_NAME }} $s3_relative_path_prefix/legacy/js-integrations $integration_sdks_html_file $integration_sdks_path_prefix/legacy/js-integrations "Device Mode Integrations (Legacy)" $integration_sdks_zip_file - ./scripts/list-sdk-components.sh ${{ secrets.AWS_S3_BUCKET_NAME }} ${{ inputs.s3_dir_path }}/modern/js-integrations $integration_sdks_html_file $integration_sdks_path_prefix/modern/js-integrations "Device Mode Integrations" $integration_sdks_zip_file + ./scripts/list-sdk-components.sh ${{ secrets.AWS_S3_BUCKET_NAME }} $s3_relative_path_prefix/modern/js-integrations $integration_sdks_html_file $integration_sdks_path_prefix/modern/js-integrations "Device Mode Integrations (Modern)" $integration_sdks_zip_file # Generate the HTML file to list all the plugins - ./scripts/list-sdk-components.sh ${{ secrets.AWS_S3_BUCKET_NAME }} ${{ inputs.s3_dir_path }}/modern/plugins $plugins_html_file $plugins_path_prefix/modern/plugins "Plugins" $plugins_zip_file + ./scripts/list-sdk-components.sh ${{ secrets.AWS_S3_BUCKET_NAME }} $s3_relative_path_prefix/modern/plugins $plugins_html_file $plugins_path_prefix/modern/plugins "Plugins" $plugins_zip_file # Copy the HTML files to S3 - aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/$integration_sdks_html_file $s3_path_prefix/legacy/js-integrations/$integration_sdks_html_file --cache-control ${{ env.CACHE_CONTROL }} - aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/$integration_sdks_html_file $s3_path_prefix/modern/js-integrations/$integration_sdks_html_file --cache-control ${{ env.CACHE_CONTROL }} - aws s3 cp $plugins_path_prefix/modern/plugins/$plugins_html_file $s3_path_prefix/modern/plugins/$plugins_html_file --cache-control ${{ env.CACHE_CONTROL }} + aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/$integration_sdks_html_file $s3_path_prefix/legacy/js-integrations/$integration_sdks_html_file $copy_args + aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/$integration_sdks_html_file $s3_path_prefix/modern/js-integrations/$integration_sdks_html_file $copy_args + aws s3 cp $plugins_path_prefix/modern/plugins/$plugins_html_file $s3_path_prefix/modern/plugins/$plugins_html_file $copy_args - - name: Create Cloudfront invalidation + - name: Invalidate CloudFront cache for all the SDK artifacts run: | - AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/${{ inputs.s3_dir_path }}/*" + invalidation_id=$(AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/${{ inputs.s3_dir_path }}/*" --query "Invalidation.Id" --output text) - - name: Sync files to S3 versioned directory + aws cloudfront wait invalidation-completed --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --id "$invalidation_id" + + - name: Copy SDK artifacts to S3 (versioned directory) if: ${{ inputs.environment == 'production' }} run: | core_sdk_path_prefix="packages/analytics-js/dist/cdn" integration_sdks_path_prefix="packages/analytics-js-integrations/dist/cdn" plugins_path_prefix="packages/analytics-js-plugins/dist/cdn" - s3_path_prefix="s3://${{ secrets.AWS_S3_BUCKET_NAME }}/${{ env.CURRENT_VERSION_VALUE }}" - copy_args="--recursive --cache-control ${{ env.CACHE_CONTROL }}" + s3_relative_path_prefix="${{ env.CURRENT_VERSION_VALUE }}" + s3_path_prefix="s3://${{ secrets.AWS_S3_BUCKET_NAME }}/$s3_relative_path_prefix" + copy_recursive_args="--recursive --cache-control ${{ env.CACHE_CONTROL_MAX_AGE }}" + copy_args="--cache-control ${{ env.CACHE_CONTROL_MAX_AGE }}" - aws s3 cp $core_sdk_path_prefix/legacy/iife/ $s3_path_prefix/legacy/ $copy_args - aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/ $s3_path_prefix/legacy/js-integrations/ $copy_args + integration_sdks_zip_file="all_integration_sdks.tar.gz" + plugins_zip_file="all_plugins.tar.gz" - aws s3 cp $core_sdk_path_prefix/modern/iife/ $s3_path_prefix/modern/ $copy_args - aws s3 cp $plugins_path_prefix/modern/plugins/ $s3_path_prefix/modern/plugins/ $copy_args - aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/ $s3_path_prefix/modern/js-integrations/ $copy_args + integration_sdks_html_file="list.html" + plugins_html_file="list.html" - - name: Create Cloudfront invalidation - if: ${{ inputs.environment == 'production' }} - run: | - AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/${{ env.CURRENT_VERSION_VALUE }}/*" + # Copy all the files to S3 + aws s3 cp $core_sdk_path_prefix/legacy/iife/ $s3_path_prefix/legacy/ $copy_recursive_args + aws s3 cp $core_sdk_path_prefix/modern/iife/ $s3_path_prefix/modern/ $copy_recursive_args - # TODO: The '/latest' directory is unused. Might be removed in future. - - name: Sync files to S3 latest - if: ${{ inputs.environment == 'production' }} - run: | - core_sdk_path_prefix="packages/analytics-js/dist/cdn" - integration_sdks_path_prefix="packages/analytics-js-integrations/dist/cdn" - plugins_path_prefix="packages/analytics-js-plugins/dist/cdn" - s3_path_prefix="s3://${{ secrets.AWS_S3_BUCKET_NAME }}/latest" - copy_args="--recursive --cache-control ${{ env.CACHE_CONTROL }}" + aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/ $s3_path_prefix/legacy/js-integrations/ $copy_recursive_args + aws s3 cp $plugins_path_prefix/modern/plugins/ $s3_path_prefix/modern/plugins/ $copy_recursive_args + aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/ $s3_path_prefix/modern/js-integrations/ $copy_recursive_args - aws s3 cp $core_sdk_path_prefix/legacy/iife/ $s3_path_prefix/legacy/ $copy_args - aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/ $s3_path_prefix/legacy/js-integrations/ $copy_args + # Generate the HTML file to list all the integrations + ./scripts/list-sdk-components.sh ${{ secrets.AWS_S3_BUCKET_NAME }} $s3_relative_path_prefix/legacy/js-integrations $integration_sdks_html_file $integration_sdks_path_prefix/legacy/js-integrations "Device Mode Integrations (Legacy)" $integration_sdks_zip_file - aws s3 cp $core_sdk_path_prefix/modern/iife/ $s3_path_prefix/modern/ $copy_args - aws s3 cp $plugins_path_prefix/modern/plugins/ $s3_path_prefix/modern/plugins/ $copy_args - aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/ $s3_path_prefix/modern/js-integrations/ $copy_args + ./scripts/list-sdk-components.sh ${{ secrets.AWS_S3_BUCKET_NAME }} $s3_relative_path_prefix/modern/js-integrations $integration_sdks_html_file $integration_sdks_path_prefix/modern/js-integrations "Device Mode Integrations (Modern)" $integration_sdks_zip_file + + # Generate the HTML file to list all the plugins + ./scripts/list-sdk-components.sh ${{ secrets.AWS_S3_BUCKET_NAME }} $s3_relative_path_prefix/modern/plugins $plugins_html_file $plugins_path_prefix/modern/plugins "Plugins" $plugins_zip_file + + # Copy all the HTML files to S3 + aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/$integration_sdks_html_file $s3_path_prefix/legacy/js-integrations/$integration_sdks_html_file $copy_args + aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/$integration_sdks_html_file $s3_path_prefix/modern/js-integrations/$integration_sdks_html_file $copy_args + aws s3 cp $plugins_path_prefix/modern/plugins/$plugins_html_file $s3_path_prefix/modern/plugins/$plugins_html_file $copy_args - - name: Create Cloudfront invalidation + - name: Invalidate CloudFront cache for all the SDK artifacts (versioned directory) if: ${{ inputs.environment == 'production' }} run: | - AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/latest*" + invalidation_id=$(AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/${{ env.CURRENT_VERSION_VALUE }}/*" --query "Invalidation.Id" --output text) + + aws cloudfront wait invalidation-completed --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --id "$invalidation_id" - name: Send message to Slack channel id: slack @@ -263,7 +281,7 @@ jobs: # Below steps are for v1.1 SDK (legacy) - - name: Sync files to S3 v1.1 directory + - name: Copy legacy SDK artifacts to S3 run: | core_sdk_path_prefix="packages/analytics-v1.1/dist/cdn" integration_sdks_path_prefix="packages/analytics-js-integrations/dist/cdn" @@ -271,49 +289,34 @@ jobs: copy_args="--recursive --cache-control ${{ env.CACHE_CONTROL }}" aws s3 cp $core_sdk_path_prefix/legacy/ $s3_path_prefix/ $copy_args - aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/ $s3_path_prefix/js-integrations/ $copy_args - aws s3 cp $core_sdk_path_prefix/modern/ $s3_path_prefix/modern/ $copy_args + + aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/ $s3_path_prefix/js-integrations/ $copy_args aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/ $s3_path_prefix/modern/js-integrations/ $copy_args - - name: Create Cloudfront invalidation + - name: Invalidate CloudFront cache for all the legacy SDK artifacts run: | - AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/${{ inputs.s3_dir_path_legacy }}*" + invalidation_id=$(AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/${{ inputs.s3_dir_path_legacy }}/*" --query "Invalidation.Id" --output text) + + aws cloudfront wait invalidation-completed --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --id "$invalidation_id" - - name: Sync files to S3 v1.1 versioned directory + - name: Copy legacy SDK artifacts to S3 (versioned directory) if: ${{ inputs.environment == 'production' }} run: | core_sdk_path_prefix="packages/analytics-v1.1/dist/cdn" integration_sdks_path_prefix="packages/analytics-js-integrations/dist/cdn" s3_path_prefix="s3://${{ secrets.AWS_S3_BUCKET_NAME }}/${{ env.CURRENT_VERSION_V1_VALUE }}" - copy_args="--recursive --cache-control ${{ env.CACHE_CONTROL }}" + copy_args="--recursive --cache-control ${{ env.CACHE_CONTROL_MAX_AGE }}" aws s3 cp $core_sdk_path_prefix/legacy/ $s3_path_prefix/ $copy_args - aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/ $s3_path_prefix/js-integrations/ $copy_args - aws s3 cp $core_sdk_path_prefix/modern/ $s3_path_prefix/modern/ $copy_args - aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/ $s3_path_prefix/modern/js-integrations/ $copy_args - - - name: Create Cloudfront invalidation - if: ${{ inputs.environment == 'production' }} - run: | - AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/${{ env.CURRENT_VERSION_V1_VALUE }}*" - - - name: Sync files to S3 latest (v1.1) - if: ${{ inputs.environment == 'production' }} - run: | - core_sdk_path_prefix="packages/analytics-v1.1/dist/cdn" - integration_sdks_path_prefix="packages/analytics-js-integrations/dist/cdn" - s3_path_prefix="s3://${{ secrets.AWS_S3_BUCKET_NAME }}/latest" - copy_args="--recursive --cache-control ${{ env.CACHE_CONTROL }}" - - aws s3 cp $core_sdk_path_prefix/legacy/ $s3_path_prefix/ $copy_args + aws s3 cp $integration_sdks_path_prefix/legacy/js-integrations/ $s3_path_prefix/js-integrations/ $copy_args - - aws s3 cp $core_sdk_path_prefix/modern/ $s3_path_prefix/modern/ $copy_args aws s3 cp $integration_sdks_path_prefix/modern/js-integrations/ $s3_path_prefix/modern/js-integrations/ $copy_args - - name: Create Cloudfront invalidation + - name: Invalidate CloudFront cache for all the legacy SDK artifacts (versioned directory) if: ${{ inputs.environment == 'production' }} run: | - AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/latest*" + invalidation_id=$(AWS_MAX_ATTEMPTS=10 aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --paths "/${{ env.CURRENT_VERSION_V1_VALUE }}/*" --query "Invalidation.Id" --output text) + + aws cloudfront wait invalidation-completed --distribution-id ${{ secrets.AWS_CF_DISTRIBUTION_ID }} --id "$invalidation_id" diff --git a/.github/workflows/draft-new-release.yml b/.github/workflows/draft-new-release.yml index 0d63cd39a8..85cc31db83 100644 --- a/.github/workflows/draft-new-release.yml +++ b/.github/workflows/draft-new-release.yml @@ -11,10 +11,17 @@ env: NODE_OPTIONS: '--no-warnings' jobs: + validate-actor: + # Only allow to draft a new release from develop and hotfix branches + if: github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/') + uses: ./.github/workflows/validate-actor.yml + secrets: + PAT: ${{ secrets.PAT }} + draft-new-release: + needs: validate-actor name: Draft a new release runs-on: [self-hosted, Linux, X64] - if: github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/') steps: - name: Checkout uses: actions/checkout@v4 @@ -106,9 +113,9 @@ jobs: pr_title: 'chore(release): pull ${{ steps.create-release.outputs.branch_name }} into main' pr_body: | :crown: *An automated PR* - + This PR is created automatically by the GitHub Actions workflow to merge the release branch into the main branch. - + Linear Ticket: https://linear.app/rudderstack/issue/${{ github.event.inputs.release_ticket_id }} @@ -134,4 +141,3 @@ jobs: console.error(`Error deleting branch ${branchToDelete}:`, error); process.exit(1); // Fail the workflow if branch deletion fails } - diff --git a/.github/workflows/rollback.yml b/.github/workflows/rollback.yml index 6bc29c88c1..f1d3589e26 100644 --- a/.github/workflows/rollback.yml +++ b/.github/workflows/rollback.yml @@ -4,9 +4,16 @@ on: workflow_dispatch: jobs: + validate-actor: + # Only allow to be deployed from tags and main branch + if: startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' + uses: ./.github/workflows/validate-actor.yml + secrets: + PAT: ${{ secrets.PAT }} + deploy: + needs: validate-actor name: Rollback production deployment - if: startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' uses: ./.github/workflows/deploy.yml with: environment: 'production' diff --git a/.github/workflows/security-code-quality-and-bundle-size-checks.yml b/.github/workflows/security-code-quality-and-bundle-size-checks.yml index e285abe49f..44e0f2b8b8 100644 --- a/.github/workflows/security-code-quality-and-bundle-size-checks.yml +++ b/.github/workflows/security-code-quality-and-bundle-size-checks.yml @@ -6,7 +6,7 @@ on: types: ['opened', 'reopened', 'synchronize'] env: - NODE_OPTIONS: "--no-warnings" + NODE_OPTIONS: '--no-warnings' BASE_REF: ${{ github.event.pull_request.base.sha || 'HEAD' }} jobs: diff --git a/.github/workflows/unit-tests-and-lint.yml b/.github/workflows/unit-tests-and-lint.yml index b95731b7b6..525d807fd2 100644 --- a/.github/workflows/unit-tests-and-lint.yml +++ b/.github/workflows/unit-tests-and-lint.yml @@ -9,7 +9,7 @@ on: types: ['opened', 'reopened', 'synchronize'] env: - NODE_OPTIONS: "--no-warnings" + NODE_OPTIONS: '--no-warnings' BASE_REF: ${{ github.event.pull_request.base.sha || 'HEAD' }} jobs: diff --git a/.github/workflows/update-cache-policy.yml b/.github/workflows/update-cache-policy.yml new file mode 100644 index 0000000000..26a1856ed3 --- /dev/null +++ b/.github/workflows/update-cache-policy.yml @@ -0,0 +1,68 @@ +name: Update cache control policy + +on: + workflow_dispatch: + inputs: + policy_type: + type: choice + description: Select the cache control policy type + required: true + options: + - no-store + - max-age=3600 + +permissions: + id-token: write # allows the JWT to be requested from GitHub's OIDC provider + contents: read # This is required for actions/checkout + +jobs: + validate-actor: + # Only allow to be deployed from tags and main branch + if: startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' + uses: ./.github/workflows/validate-actor.yml + secrets: + PAT: ${{ secrets.PAT }} + + update-cache-policy: + needs: validate-actor + name: Update cache control policy for SDK artifacts + runs-on: [self-hosted, Linux, X64] + + steps: + - name: Install AWS CLI + uses: unfor19/install-aws-cli-action@master + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ secrets.AWS_PROD_ACCOUNT_ID }}:role/${{ secrets.AWS_PROD_S3_SYNC_ROLE }} + aws-region: us-east-1 + + - name: Determine the cache control policy + id: determine_policy + run: | + echo "cache_control_policy=${{ github.event.inputs.policy_type || inputs.policy_type }}" >> $GITHUB_ENV + + - name: Update cache control policy + run: | + # Get the number of CPU cores in the runner and leave one core free + num_cores=$(nproc --ignore=1 || echo 1) # Default to 1 if nproc is unavailable + # Use a factor to set the parallel jobs (e.g., number of cores or slightly lower) + parallel_jobs=$((num_cores * 2)) + echo "Detected $num_cores cores. Using $parallel_jobs parallel jobs." + + prefixes=("adobe-analytics-js" "v3" "v1.1") + + for prefix in "${prefixes[@]}"; do + echo "Processing prefix: $prefix" + + aws s3api list-objects --bucket ${{ secrets.AWS_PROD_S3_BUCKET_NAME }} --prefix "$prefix" --query "Contents[].Key" --output text | tr '\t' '\n' | \ + parallel --retries 10 -j "$parallel_jobs" "aws s3api copy-object \ + --bucket ${{ secrets.AWS_PROD_S3_BUCKET_NAME }} \ + --copy-source ${{ secrets.AWS_PROD_S3_BUCKET_NAME }}/{} \ + --key {} \ + --metadata-directive REPLACE \ + --cache-control '${{ env.cache_control_policy }}'" + done + + diff --git a/.github/workflows/validate-actor.yml b/.github/workflows/validate-actor.yml new file mode 100644 index 0000000000..15981efc51 --- /dev/null +++ b/.github/workflows/validate-actor.yml @@ -0,0 +1,30 @@ +name: Validate Actor + +on: + workflow_call: + secrets: + PAT: + required: true + +jobs: + validate-actor: + runs-on: [self-hosted, Linux, X64] + steps: + - name: Validate if actor is allowed to trigger the workflow + env: + ORG_NAME: rudderlabs + TEAM_NAME: js-sdk + run: | + actor=${{ github.actor || github.triggering_actor }} + response=$(curl -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.PAT }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/orgs/${{ env.ORG_NAME }}/teams/${{ env.TEAM_NAME }}/memberships/$actor) + + if echo "$response" | grep -q '"state": "active"'; then + echo "$actor is a member of $TEAM_NAME team" + else + echo "$actor is NOT a member of $TEAM_NAME team" + exit 1 + fi diff --git a/.gitignore b/.gitignore index b58ba7f42e..8241a0cb92 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,7 @@ tsconfig.build.tsbuildinfo .nx/cache .nx/workspace-data + +.angular/ +build/ +vendor/ diff --git a/.prettierignore b/.prettierignore index 2d30234d31..743fb3f2fb 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,18 +1,15 @@ -dist/ -node_modules/ -reports/ -stats/ +# Include patterns from .gitignore +# .gitignore + +# Additional Prettier-specific ignore patterns assets/ -cdnSDK.js -cdnSDKv3.js CHANGELOG.md CHANGELOG_LATEST.md CONTRIBUTING.md - examples/chrome-extension/**/rudderAnalytics.js examples/chrome-extension/**/foreground.js examples/**/index.html -**/public/index.html - -/.nx/cache -/.nx/workspace-data \ No newline at end of file +examples/gatsby/sample-gatsby-site/public/ +examples/gatsby/sample-gatsby-plugin-usage/public/ +**/nativeSdkLoader.js +composer.lock diff --git a/LICENSE.md b/LICENSE.md index 554bb72539..37517857b4 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -40,14 +40,14 @@ As far as the law allows, the software comes as is, without any warranty or cond ## Definitions -The *licensor* is the entity offering these terms, and the *software* is the software the licensor makes available under these terms, including any portion of it. +The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it. -*you* refers to the individual or entity agreeing to these terms. +_you_ refers to the individual or entity agreeing to these terms. -*your company* is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. *control* means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. +_your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. -*your licenses* are all the licenses granted to you for the software under these terms. +_your licenses_ are all the licenses granted to you for the software under these terms. -*use* means anything you do with the software requiring one of your licenses. +_use_ means anything you do with the software requiring one of your licenses. -*trademark* means trademarks, service marks, and similar rights. +_trademark_ means trademarks, service marks, and similar rights. diff --git a/examples/angular/sample-app/package-lock.json b/examples/angular/sample-app/package-lock.json index d615a7ff96..fde4ea26c9 100644 --- a/examples/angular/sample-app/package-lock.json +++ b/examples/angular/sample-app/package-lock.json @@ -18,15 +18,15 @@ "@angular/router": "18.2.6", "@rudderstack/analytics-js": "*", "rxjs": "7.8.1", - "tslib": "2.7.0", + "tslib": "2.8.1", "zone.js": "0.14.10" }, "devDependencies": { "@angular-devkit/build-angular": "18.2.6", "@angular/cli": "18.2.6", "@angular/compiler-cli": "18.2.6", - "@types/jasmine": "5.1.4", - "jasmine-core": "5.3.0", + "@types/jasmine": "5.1.5", + "jasmine-core": "5.5.0", "karma": "6.4.4", "karma-chrome-launcher": "3.2.0", "karma-coverage": "2.2.1", @@ -191,6 +191,375 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular/build": { + "version": "18.2.6", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.6.tgz", + "integrity": "sha512-TQzX6Mi7uXFvmz7+OVl4Za7WawYPcx+B5Ewm6IY/DdMyB9P/Z4tbKb1LO+ynWUXYwm7avXo6XQQ4m5ArDY5F/A==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1802.6", + "@babel/core": "7.25.2", + "@babel/helper-annotate-as-pure": "7.24.7", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.24.7", + "@inquirer/confirm": "3.1.22", + "@vitejs/plugin-basic-ssl": "1.1.0", + "browserslist": "^4.23.0", + "critters": "0.0.24", + "esbuild": "0.23.0", + "fast-glob": "3.3.2", + "https-proxy-agent": "7.0.5", + "listr2": "8.2.4", + "lmdb": "3.0.13", + "magic-string": "0.30.11", + "mrmime": "2.0.0", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.6.1", + "rollup": "4.22.4", + "sass": "1.77.6", + "semver": "7.6.3", + "vite": "5.4.6", + "watchpack": "2.4.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^18.0.0", + "@angular/localize": "^18.0.0", + "@angular/platform-server": "^18.0.0", + "@angular/service-worker": "^18.0.0", + "less": "^4.2.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.4 <5.6" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@inquirer/confirm": { + "version": "3.1.22", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.22.tgz", + "integrity": "sha512-gsAKIOWBm2Q87CDfs9fEo7wJT3fwWIJfnDGMn9Qy74gBnNFOACDNfhUzovubbJjWnKLGBln7/NcSmZwj5DuEXg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.10", + "@inquirer/type": "^1.5.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-android-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular-devkit/build-angular/node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/rollup": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", + "fsevents": "~2.3.2" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", @@ -269,78 +638,10 @@ "tslib": "^2.3.0" }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "@angular/core": "18.2.6" - } - }, - "node_modules/@angular/build": { - "version": "18.2.6", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.6.tgz", - "integrity": "sha512-TQzX6Mi7uXFvmz7+OVl4Za7WawYPcx+B5Ewm6IY/DdMyB9P/Z4tbKb1LO+ynWUXYwm7avXo6XQQ4m5ArDY5F/A==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1802.6", - "@babel/core": "7.25.2", - "@babel/helper-annotate-as-pure": "7.24.7", - "@babel/helper-split-export-declaration": "7.24.7", - "@babel/plugin-syntax-import-attributes": "7.24.7", - "@inquirer/confirm": "3.1.22", - "@vitejs/plugin-basic-ssl": "1.1.0", - "browserslist": "^4.23.0", - "critters": "0.0.24", - "esbuild": "0.23.0", - "fast-glob": "3.3.2", - "https-proxy-agent": "7.0.5", - "listr2": "8.2.4", - "lmdb": "3.0.13", - "magic-string": "0.30.11", - "mrmime": "2.0.0", - "parse5-html-rewriting-stream": "7.0.0", - "picomatch": "4.0.2", - "piscina": "4.6.1", - "rollup": "4.22.4", - "sass": "1.77.6", - "semver": "7.6.3", - "vite": "5.4.6", - "watchpack": "2.4.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "@angular/compiler-cli": "^18.0.0", - "@angular/localize": "^18.0.0", - "@angular/platform-server": "^18.0.0", - "@angular/service-worker": "^18.0.0", - "less": "^4.2.0", - "postcss": "^8.4.0", - "tailwindcss": "^2.0.0 || ^3.0.0", - "typescript": ">=5.4 <5.6" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, - "peerDependenciesMeta": { - "@angular/localize": { - "optional": true - }, - "@angular/platform-server": { - "optional": true - }, - "@angular/service-worker": { - "optional": true - }, - "less": { - "optional": true - }, - "postcss": { - "optional": true - }, - "tailwindcss": { - "optional": true - } + "peerDependencies": { + "@angular/core": "18.2.6" } }, "node_modules/@angular/cli": { @@ -526,12 +827,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -539,9 +841,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", - "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", "dev": true, "engines": { "node": ">=6.9.0" @@ -619,28 +921,15 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", - "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -658,17 +947,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", - "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.4", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", "semver": "^6.3.1" }, "engines": { @@ -678,6 +967,18 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -688,13 +989,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", - "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "regexpu-core": "^5.3.1", + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -704,6 +1005,18 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -714,9 +1027,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -730,41 +1043,40 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", - "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dev": true, "dependencies": { - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -774,35 +1086,35 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dev": true, "dependencies": { - "@babel/types": "^7.24.7" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", - "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-wrap-function": "^7.25.0", - "@babel/traverse": "^7.25.0" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -811,44 +1123,43 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", - "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/traverse": "^7.25.0" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", "dev": true, "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dev": true, "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -867,81 +1178,66 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", - "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "dev": true, "dependencies": { - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", - "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", - "dev": true, - "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", "dev": true, "dependencies": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.26.3" }, "bin": { "parser": "bin/babel-parser.js" @@ -951,13 +1247,13 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", - "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/traverse": "^7.25.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -967,12 +1263,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", - "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -982,12 +1278,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", - "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -997,14 +1293,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", - "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1014,13 +1310,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", - "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/traverse": "^7.25.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1105,12 +1401,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", - "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1120,12 +1416,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1277,12 +1573,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", - "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1327,12 +1623,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", - "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1342,12 +1638,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", - "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1357,13 +1653,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", - "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.4", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1373,14 +1669,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", - "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1390,16 +1685,16 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", - "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/traverse": "^7.25.4", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", "globals": "^11.1.0" }, "engines": { @@ -1409,14 +1704,26 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", - "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/template": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1426,12 +1733,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", - "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1441,13 +1748,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", - "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1457,12 +1764,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", - "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1472,13 +1779,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", - "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1488,13 +1795,12 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", - "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1504,13 +1810,12 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", - "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1520,13 +1825,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", - "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1536,13 +1840,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", - "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1552,14 +1856,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.25.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", - "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/traverse": "^7.25.1" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1569,13 +1873,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", - "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1585,12 +1888,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", - "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1600,13 +1903,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", - "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1616,12 +1918,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", - "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1631,13 +1933,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", - "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1647,14 +1949,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", - "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.8", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-simple-access": "^7.24.7" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1664,15 +1965,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", - "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.0" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1682,13 +1983,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", - "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1698,13 +1999,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", - "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1714,12 +2015,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", - "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1729,13 +2030,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", - "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1745,13 +2045,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", - "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1761,15 +2060,14 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", - "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.7" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1779,13 +2077,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", - "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-replace-supers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1795,13 +2093,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", - "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1811,14 +2108,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", - "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1828,12 +2124,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", - "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1843,13 +2139,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", - "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.4", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1859,15 +2155,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", - "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1876,13 +2171,25 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-private-property-in-object/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", - "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1892,12 +2199,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", - "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1908,12 +2215,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", - "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1952,12 +2259,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", - "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1967,13 +2274,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", - "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1983,12 +2290,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", - "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1998,12 +2305,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", - "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2013,12 +2320,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", - "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2028,12 +2335,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", - "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2043,13 +2350,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", - "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2059,13 +2366,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", - "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.7", - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2075,13 +2382,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", - "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.2", - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2210,12 +2517,6 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, "node_modules/@babel/runtime": { "version": "7.25.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", @@ -2229,30 +2530,30 @@ } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2261,29 +2562,41 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", "dev": true, "dependencies": { - "@babel/types": "^7.25.6", + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2708,13 +3021,13 @@ } }, "node_modules/@inquirer/confirm": { - "version": "3.1.22", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.22.tgz", - "integrity": "sha512-gsAKIOWBm2Q87CDfs9fEo7wJT3fwWIJfnDGMn9Qy74gBnNFOACDNfhUzovubbJjWnKLGBln7/NcSmZwj5DuEXg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.2.0.tgz", + "integrity": "sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw==", "dev": true, "dependencies": { - "@inquirer/core": "^9.0.10", - "@inquirer/type": "^1.5.2" + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3" }, "engines": { "node": ">=18" @@ -2784,9 +3097,9 @@ } }, "node_modules/@inquirer/figures": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.6.tgz", - "integrity": "sha512-yfZzps3Cso2UbM7WlxKwZQh2Hs6plrbjs1QnzQDZhK2DgyCo6D8AaHps9olkNcUFlcYERMqU3uJSp1gmy3s/qQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", + "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==", "dev": true, "engines": { "node": ">=18" @@ -3090,9 +3403,9 @@ } }, "node_modules/@jsonjoy.com/json-pack": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz", - "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", + "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", "dev": true, "dependencies": { "@jsonjoy.com/base64": "^1.1.1", @@ -3112,9 +3425,9 @@ } }, "node_modules/@jsonjoy.com/util": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz", - "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", "dev": true, "engines": { "node": ">=10.0" @@ -3623,9 +3936,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", + "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==", "cpu": [ "arm" ], @@ -3636,9 +3949,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz", + "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==", "cpu": [ "arm64" ], @@ -3649,9 +3962,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz", + "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==", "cpu": [ "arm64" ], @@ -3662,9 +3975,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz", + "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==", "cpu": [ "x64" ], @@ -3674,10 +3987,36 @@ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz", + "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz", + "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz", + "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==", "cpu": [ "arm" ], @@ -3688,9 +4027,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz", + "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==", "cpu": [ "arm" ], @@ -3701,9 +4040,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz", + "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==", "cpu": [ "arm64" ], @@ -3714,9 +4053,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz", + "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==", "cpu": [ "arm64" ], @@ -3726,10 +4065,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz", + "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz", + "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==", "cpu": [ "ppc64" ], @@ -3740,9 +4092,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz", + "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==", "cpu": [ "riscv64" ], @@ -3753,9 +4105,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz", + "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==", "cpu": [ "s390x" ], @@ -3766,9 +4118,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz", + "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==", "cpu": [ "x64" ], @@ -3779,9 +4131,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz", + "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==", "cpu": [ "x64" ], @@ -3792,9 +4144,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz", + "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==", "cpu": [ "arm64" ], @@ -3805,9 +4157,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz", + "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==", "cpu": [ "ia32" ], @@ -3818,9 +4170,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz", + "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==", "cpu": [ "x64" ], @@ -3831,9 +4183,9 @@ ] }, "node_modules/@rudderstack/analytics-js": { - "version": "3.7.13", - "resolved": "https://registry.npmjs.org/@rudderstack/analytics-js/-/analytics-js-3.7.13.tgz", - "integrity": "sha512-8nIWn2gv3x2Vj1m7xa8fwXz8aqKo+HdOfYitsNaSTPDM2he0W8jsE8ydx1Q010hf77WT75v9C9VqYNlZe7mHDQ==" + "version": "3.11.15", + "resolved": "https://registry.npmjs.org/@rudderstack/analytics-js/-/analytics-js-3.11.15.tgz", + "integrity": "sha512-AMy9i+nLXtIKix8o6ME6Q+WA+CBhHwtTzxegJ15Yq6FjHRwhvlUSIUwt0bacr/kPMYJ5KdttrXRHuNMOAo2N1A==" }, "node_modules/@schematics/angular": { "version": "18.2.6", @@ -4043,9 +4395,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/express": { @@ -4061,9 +4413,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz", - "integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz", + "integrity": "sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg==", "dev": true, "dependencies": { "@types/node": "*", @@ -4100,9 +4452,9 @@ } }, "node_modules/@types/jasmine": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.4.tgz", - "integrity": "sha512-px7OMFO/ncXxixDe1zR13V1iycqWae0MxTaw62RpFlksUi5QuNWgQJFkTQjIOvrmutJbI7Fp2Y2N1F6D2R4G6w==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.5.tgz", + "integrity": "sha512-SaCZ3kM5NjOiJqMRYwHpLbTfUC2Dyk1KS3QanNFsUYPGTk70CWVK/J9ueun6zNhw/UkgV7xl8V4ZLQZNRbfnNw==", "dev": true }, "node_modules/@types/json-schema": { @@ -4127,12 +4479,12 @@ } }, "node_modules/@types/node": { - "version": "22.7.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.3.tgz", - "integrity": "sha512-qXKfhXXqGTyBskvWEzJZPUxSslAiLaB6JGP1ic/XTH9ctGgzdgYguuLP1C601aRTSDNlLb0jbKqXjZ48GNraSA==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "dev": true, "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.20.0" } }, "node_modules/@types/node-forge": { @@ -4145,9 +4497,9 @@ } }, "node_modules/@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", "dev": true }, "node_modules/@types/range-parser": { @@ -4208,9 +4560,9 @@ "dev": true }, "node_modules/@types/ws": { - "version": "8.5.12", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", - "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "dev": true, "dependencies": { "@types/node": "*" @@ -4229,148 +4581,148 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -4414,10 +4766,19 @@ "node": ">= 0.6" } }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -4463,13 +4824,10 @@ } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, "engines": { "node": ">= 14" } @@ -4578,15 +4936,18 @@ } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { @@ -4681,13 +5042,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { @@ -4717,12 +5078,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -4841,9 +5202,9 @@ "dev": true }, "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", @@ -4879,9 +5240,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -4898,10 +5259,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -5038,16 +5399,15 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -5056,6 +5416,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5066,9 +5439,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001664", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz", - "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==", + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", "dev": true, "funding": [ { @@ -5086,17 +5459,19 @@ ] }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chardet": { @@ -5222,39 +5597,6 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/cliui/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -5325,18 +5667,21 @@ } }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/colorette": { @@ -5370,32 +5715,23 @@ } }, "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", "dev": true, "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", + "negotiator": "~0.6.4", "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.1", "vary": "~1.1.2" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5411,12 +5747,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5490,9 +5820,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" @@ -5553,12 +5883,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.38.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", - "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", "dev": true, "dependencies": { - "browserslist": "^4.23.3" + "browserslist": "^4.24.2" }, "funding": { "type": "opencollective", @@ -5581,124 +5911,55 @@ "vary": "^1" }, "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "dev": true, - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/critters": { - "version": "0.0.24", - "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.24.tgz", - "integrity": "sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "css-select": "^5.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.2", - "htmlparser2": "^8.0.2", - "postcss": "^8.4.23", - "postcss-media-query-parser": "^0.2.3" - } - }, - "node_modules/critters/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/critters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/critters/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/critters/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/critters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">= 0.10" } }, - "node_modules/critters/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" }, "engines": { - "node": ">=8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/critters": { + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.24.tgz", + "integrity": "sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==", + "deprecated": "Ownership of Critters has moved to the Nuxt team, who will be maintaining the project going forward. If you'd like to keep using Critters, please switch to the actively-maintained fork at https://github.com/danielroe/beasties", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "css-select": "^5.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.2", + "htmlparser2": "^8.0.2", + "postcss": "^8.4.23", + "postcss-media-query-parser": "^0.2.3" } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -5815,9 +6076,9 @@ } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "dependencies": { "ms": "^2.1.3" @@ -6031,6 +6292,20 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -6044,9 +6319,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.5.29", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.29.tgz", - "integrity": "sha512-PF8n2AlIhCKXQ+gTpiJi0VhcHDb69kYX4MtCiivctc2QD3XuNZ/XIOlbGzt7WAjjEev0TtaH6Cu3arZExm5DOw==", + "version": "1.5.72", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.72.tgz", + "integrity": "sha512-ZpSAUOZ2Izby7qnZluSrAlGgGQzucmFbN0n64dYzocYxnxV5ufurpj3VgEe4cUp7ir9LmeLxNYo8bVnlM8bQHw==", "dev": true }, "node_modules/emoji-regex": { @@ -6097,9 +6372,9 @@ } }, "node_modules/engine.io": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.1.tgz", - "integrity": "sha512-NEpDCw9hrvBW+hVEOK4T7v0jFJ++KgtPl4jKFwsZVfG1XhS0dCrSb3VMb9gPAd7VAdW52VT1EnaNiU2vM8C0og==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -6107,7 +6382,7 @@ "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", @@ -6126,6 +6401,23 @@ "node": ">=10.0.0" } }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/enhanced-resolve": { "version": "5.17.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", @@ -6213,13 +6505,10 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -6305,15 +6594,6 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -6441,9 +6721,9 @@ "dev": true }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "dev": true, "dependencies": { "accepts": "~1.3.8", @@ -6451,7 +6731,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -6465,7 +6745,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -6480,12 +6760,16 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "engines": { "node": ">= 0.6" @@ -6591,9 +6875,9 @@ "dev": true }, "node_modules/fast-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", - "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", "dev": true }, "node_modules/fastq": { @@ -6716,9 +7000,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "dev": true }, "node_modules/follow-redirects": { @@ -6862,9 +7146,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", "dev": true, "engines": { "node": ">=18" @@ -6874,16 +7158,19 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.5.tgz", + "integrity": "sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==", "dev": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -6973,12 +7260,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6997,12 +7284,12 @@ "dev": true }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { @@ -7017,22 +7304,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "engines": { "node": ">= 0.4" @@ -7224,23 +7499,6 @@ "node": ">= 14" } }, - "node_modules/http-proxy-middleware": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.0.tgz", - "integrity": "sha512-36AV1fIaI2cWRzHo+rbcxhe3M3jUDCNzc4D5zRl57sEWRAxdXYtw7FSQKYY6PDKssiAKjLYypbssHk+xs/kMXw==", - "dev": true, - "dependencies": { - "@types/http-proxy": "^1.17.10", - "debug": "^4.3.4", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.5" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/https-proxy-agent": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", @@ -7738,27 +7996,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", @@ -7811,9 +8048,9 @@ } }, "node_modules/jasmine-core": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.3.0.tgz", - "integrity": "sha512-zsOmeBKESky4toybvWEikRiZ0jHoBEu79wNArLfMdSnlLMZx3Xcp6CSm2sUcYyoJC+Uyj8LBJap/MUbVSfJ27g==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.5.0.tgz", + "integrity": "sha512-NHOvoPO6o9gVR6pwqEACTEpbgcH+JJ6QDypyymGbSUIFIFsMMbBJ/xsFNud8MSClfnWclXd7RQlAZBz7yVo5TQ==", "dev": true }, "node_modules/jest-worker": { @@ -7830,15 +8067,6 @@ "node": ">= 10.13.0" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -8080,21 +8308,6 @@ "source-map-support": "^0.5.5" } }, - "node_modules/karma/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/karma/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -8106,24 +8319,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/karma/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/karma/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/karma/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -8460,6 +8655,12 @@ "@lmdb/lmdb-win32-x64": "3.0.13" } }, + "node_modules/lmdb/node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -8508,87 +8709,17 @@ "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update": { @@ -8794,9 +8925,9 @@ } }, "node_modules/memfs": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz", - "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.0.tgz", + "integrity": "sha512-q9MmZXd2rRWHS6GU3WEm3HyiXZyyoA1DqdOhEq0lxPBmKb5S7IAOwX0RgUCwJfqjelDCySa5h8ujOy24LqsWcw==", "dev": true, "dependencies": { "@jsonjoy.com/json-pack": "^1.0.3", @@ -9158,9 +9289,9 @@ "dev": true }, "node_modules/msgpackr": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.0.tgz", - "integrity": "sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", "dev": true, "optionalDependencies": { "msgpackr-extract": "^3.0.2" @@ -9211,9 +9342,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { @@ -9259,9 +9390,9 @@ } }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "dev": true, "engines": { "node": ">= 0.6" @@ -9288,19 +9419,13 @@ "node-gyp-build": "^4.2.2" } }, - "node_modules/nice-napi/node_modules/node-addon-api": { + "node_modules/node-addon-api": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", "dev": true, "optional": true }, - "node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", - "dev": true - }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -9311,9 +9436,9 @@ } }, "node_modules/node-gyp": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", - "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz", + "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==", "dev": true, "dependencies": { "env-paths": "^2.2.0", @@ -9335,9 +9460,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", - "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "dev": true, "optional": true, "bin": { @@ -9429,9 +9554,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "node_modules/nopt": { @@ -9609,9 +9734,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, "engines": { "node": ">= 0.4" @@ -9712,37 +9837,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/ora/node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -9755,33 +9849,6 @@ "node": ">=8" } }, - "node_modules/ora/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ora/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/ora/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/ora/node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -9816,22 +9883,10 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "node_modules/ora/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ordered-binary": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.2.tgz", - "integrity": "sha512-JTo+4+4Fw7FreyAvlSLjb1BBVaxEQAacmjD3jjuyPZclpbEghTvQZbXBb2qPd2LeIMxiHwXBZUcpmG2Gl/mDEA==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", "dev": true }, "node_modules/os-tmpdir": { @@ -9889,9 +9944,9 @@ } }, "node_modules/p-retry": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", - "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", "dev": true, "dependencies": { "@types/retry": "0.12.2", @@ -9997,12 +10052,12 @@ } }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dev": true, "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -10099,9 +10154,9 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "dev": true }, "node_modules/path-type": { @@ -10117,9 +10172,9 @@ } }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "node_modules/picomatch": { @@ -10246,13 +10301,13 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.1.0.tgz", + "integrity": "sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==", "dev": true, "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -10263,12 +10318,12 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -10293,9 +10348,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -10541,15 +10596,15 @@ "dev": true }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -10557,25 +10612,34 @@ "node": ">=4" } }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true + }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dev": true, "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, "bin": { "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" } }, "node_modules/require-directory": { @@ -10725,12 +10789,12 @@ } }, "node_modules/rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz", + "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", "dev": true, "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -10740,22 +10804,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", + "@rollup/rollup-android-arm-eabi": "4.28.1", + "@rollup/rollup-android-arm64": "4.28.1", + "@rollup/rollup-darwin-arm64": "4.28.1", + "@rollup/rollup-darwin-x64": "4.28.1", + "@rollup/rollup-freebsd-arm64": "4.28.1", + "@rollup/rollup-freebsd-x64": "4.28.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.28.1", + "@rollup/rollup-linux-arm-musleabihf": "4.28.1", + "@rollup/rollup-linux-arm64-gnu": "4.28.1", + "@rollup/rollup-linux-arm64-musl": "4.28.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.28.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1", + "@rollup/rollup-linux-riscv64-gnu": "4.28.1", + "@rollup/rollup-linux-s390x-gnu": "4.28.1", + "@rollup/rollup-linux-x64-gnu": "4.28.1", + "@rollup/rollup-linux-x64-musl": "4.28.1", + "@rollup/rollup-win32-arm64-msvc": "4.28.1", + "@rollup/rollup-win32-ia32-msvc": "4.28.1", + "@rollup/rollup-win32-x64-msvc": "4.28.1", "fsevents": "~2.3.2" } }, @@ -11178,10 +11245,13 @@ } }, "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11284,9 +11354,9 @@ } }, "node_modules/socket.io": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", - "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "dev": true, "dependencies": { "accepts": "~1.3.4", @@ -11311,6 +11381,23 @@ "ws": "~8.17.1" } }, + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/socket.io-parser": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", @@ -11324,6 +11411,40 @@ "node": ">=10.0.0" } }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -11350,12 +11471,12 @@ } }, "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "dev": true, "dependencies": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -11653,15 +11774,15 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -11893,15 +12014,6 @@ "node": ">=0.6.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -11949,9 +12061,9 @@ } }, "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/tuf-js": { "version": "2.2.1", @@ -12038,9 +12150,9 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -12138,9 +12250,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -12157,8 +12269,8 @@ } ], "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -12703,9 +12815,9 @@ } }, "node_modules/vite/node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -12723,7 +12835,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -12940,9 +13052,9 @@ } }, "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dev": true, "dependencies": { "@types/http-proxy": "^1.17.8", @@ -13165,39 +13277,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -13227,39 +13306,6 @@ "node": ">=8" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", diff --git a/examples/angular/sample-app/package.json b/examples/angular/sample-app/package.json index debc41ffc3..0aa0537041 100644 --- a/examples/angular/sample-app/package.json +++ b/examples/angular/sample-app/package.json @@ -20,20 +20,23 @@ "@angular/router": "18.2.6", "@rudderstack/analytics-js": "*", "rxjs": "7.8.1", - "tslib": "2.7.0", + "tslib": "2.8.1", "zone.js": "0.14.10" }, "devDependencies": { "@angular-devkit/build-angular": "18.2.6", "@angular/cli": "18.2.6", "@angular/compiler-cli": "18.2.6", - "@types/jasmine": "5.1.4", - "jasmine-core": "5.3.0", + "@types/jasmine": "5.1.5", + "jasmine-core": "5.5.0", "karma": "6.4.4", "karma-chrome-launcher": "3.2.0", "karma-coverage": "2.2.1", "karma-jasmine": "5.1.0", "karma-jasmine-html-reporter": "2.1.0", "typescript": "5.5.4" + }, + "overrides": { + "http-proxy-middleware": "2.0.7" } } diff --git a/examples/angular/sample-app/src/index.html b/examples/angular/sample-app/src/index.html index 73157c23ed..a98f255267 100644 --- a/examples/angular/sample-app/src/index.html +++ b/examples/angular/sample-app/src/index.html @@ -9,7 +9,7 @@ - - - - - diff --git a/packages/analytics-js-integrations/rollup.config.mjs b/packages/analytics-js-integrations/rollup.config.mjs index ceea3df47e..5a2255a076 100644 --- a/packages/analytics-js-integrations/rollup.config.mjs +++ b/packages/analytics-js-integrations/rollup.config.mjs @@ -1,5 +1,5 @@ /* eslint-disable import/no-extraneous-dependencies */ -import path from "path"; +import path from 'path'; import babel from '@rollup/plugin-babel'; import commonjs from '@rollup/plugin-commonjs'; import resolve from '@rollup/plugin-node-resolve'; @@ -69,8 +69,8 @@ export function getDefaultConfig(distName, moduleType = 'cdn') { { find: '@rudderstack/analytics-js-common', replacement: path.resolve('../analytics-js-common/src'), - } - ] + }, + ], }), nodePolyfills(), resolve({ @@ -114,7 +114,7 @@ export function getDefaultConfig(distName, moduleType = 'cdn') { open: true, gzipSize: true, brotliSize: true, - }) + }), ], }; } diff --git a/packages/analytics-js-integrations/src/integrations/AdobeAnalytics/browser.js b/packages/analytics-js-integrations/src/integrations/AdobeAnalytics/browser.js index a064e74ebf..c831b2b5a7 100644 --- a/packages/analytics-js-integrations/src/integrations/AdobeAnalytics/browser.js +++ b/packages/analytics-js-integrations/src/integrations/AdobeAnalytics/browser.js @@ -98,7 +98,7 @@ class AdobeAnalytics { // The referrer variable overrides the automatically collected referrer in reports. let referrer; let url; - if (rudderElement.message.context && rudderElement.message.context.page) { + if (rudderElement.message.context?.page) { referrer = rudderElement.message.context.page.referrer; url = rudderElement.message.context.page.url; } else if (rudderElement.message.properties) { diff --git a/packages/analytics-js-integrations/src/integrations/AdobeAnalytics/util.js b/packages/analytics-js-integrations/src/integrations/AdobeAnalytics/util.js index 414d82b668..daa1dc4393 100644 --- a/packages/analytics-js-integrations/src/integrations/AdobeAnalytics/util.js +++ b/packages/analytics-js-integrations/src/integrations/AdobeAnalytics/util.js @@ -129,7 +129,7 @@ const updateWindowSKeys = (value, key) => { const updateCommonWindowSKeys = (rudderElement, pageName) => { const { properties, type, context } = rudderElement.message; let campaign; - if (context && context.campaign) { + if (context?.campaign) { campaign = context.campaign.name; } else { campaign = properties.campaign; diff --git a/packages/analytics-js-integrations/src/integrations/Amplitude/browser.js b/packages/analytics-js-integrations/src/integrations/Amplitude/browser.js index 6f725c6435..e1626f0e04 100644 --- a/packages/analytics-js-integrations/src/integrations/Amplitude/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Amplitude/browser.js @@ -89,7 +89,7 @@ class Amplitude { } isLoaded() { - return Boolean(window.amplitude && window.amplitude.getDeviceId()); + return Boolean(window.amplitude?.getDeviceId()); } isReady() { diff --git a/packages/analytics-js-integrations/src/integrations/DCMFloodlight/browser.js b/packages/analytics-js-integrations/src/integrations/DCMFloodlight/browser.js index 5c40bbcdbc..a736c86069 100644 --- a/packages/analytics-js-integrations/src/integrations/DCMFloodlight/browser.js +++ b/packages/analytics-js-integrations/src/integrations/DCMFloodlight/browser.js @@ -83,8 +83,9 @@ class DCMFloodlight { loadCookieMatching() { if (this.doubleclickId && this.googleNetworkId) { const image = document.createElement('img'); - image.src = `https://cm.g.doubleclick.net/pixel?google_nid=${this.googleNetworkId - }&google_hm=${btoa(this.analytics.getAnonymousId())}`; + image.src = `https://cm.g.doubleclick.net/pixel?google_nid=${ + this.googleNetworkId + }&google_hm=${btoa(this.analytics.getAnonymousId())}`; document.getElementsByTagName('head')[0].appendChild(image); } } diff --git a/packages/analytics-js-integrations/src/integrations/FacebookPixel/browser.js b/packages/analytics-js-integrations/src/integrations/FacebookPixel/browser.js index 17489680e3..4d8ca8807d 100644 --- a/packages/analytics-js-integrations/src/integrations/FacebookPixel/browser.js +++ b/packages/analytics-js-integrations/src/integrations/FacebookPixel/browser.js @@ -106,7 +106,7 @@ class FacebookPixel { } isLoaded() { - return !!(window.fbq && window.fbq.callMethod); + return !!window.fbq?.callMethod; } isReady() { @@ -266,7 +266,7 @@ class FacebookPixel { } else if (event === 'Checkout Started') { let contentCategory = category; const { contents, contentIds } = getProductsContentsAndContentIds(products, quantity, price); - if (Array.isArray(products) && !contentCategory && products[0] && products[0].category) { + if (Array.isArray(products) && !contentCategory && products[0]?.category) { contentCategory = products[0].category; } diff --git a/packages/analytics-js-integrations/src/integrations/FacebookPixel/utils.js b/packages/analytics-js-integrations/src/integrations/FacebookPixel/utils.js index c06d8d773d..7a54f29501 100644 --- a/packages/analytics-js-integrations/src/integrations/FacebookPixel/utils.js +++ b/packages/analytics-js-integrations/src/integrations/FacebookPixel/utils.js @@ -228,17 +228,26 @@ const getProductsContentsAndContentIds = (products, quantity, price, deliveryCat const contents = products ? products .filter(product => product) - .map(({ product_id: prodId, sku, id, quantity: productQuantity, price: productPrice, delivery_category: prodDeliveryCategory }) => { - const productId = prodId || sku || id; - return isDefined(productId) - ? { - id: productId, - quantity: productQuantity || quantity || 1, - item_price: productPrice || price, - delivery_category: prodDeliveryCategory || deliveryCategory, - } - : null; - }) + .map( + ({ + product_id: prodId, + sku, + id, + quantity: productQuantity, + price: productPrice, + delivery_category: prodDeliveryCategory, + }) => { + const productId = prodId || sku || id; + return isDefined(productId) + ? { + id: productId, + quantity: productQuantity || quantity || 1, + item_price: productPrice || price, + delivery_category: prodDeliveryCategory || deliveryCategory, + } + : null; + }, + ) .filter(content => content !== null) : []; diff --git a/packages/analytics-js-integrations/src/integrations/Fullstory/browser.js b/packages/analytics-js-integrations/src/integrations/Fullstory/browser.js index 8006292274..b1b1d4b760 100644 --- a/packages/analytics-js-integrations/src/integrations/Fullstory/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Fullstory/browser.js @@ -142,7 +142,6 @@ class Fullstory { } page(rudderElement) { - const rudderMessage = rudderElement.message; const pageName = rudderMessage.name; const props = { diff --git a/packages/analytics-js-integrations/src/integrations/GA4/config.js b/packages/analytics-js-integrations/src/integrations/GA4/config.js index 1856222e4b..dd5494dae5 100644 --- a/packages/analytics-js-integrations/src/integrations/GA4/config.js +++ b/packages/analytics-js-integrations/src/integrations/GA4/config.js @@ -121,7 +121,10 @@ const eventParams = { destKey: 'item_id', }, url: { sourceKeys: ['properties.url', 'context.page.url'], destKey: 'page_location' }, - referrer: { sourceKeys: ['properties.referrer', 'context.page.referrer'], destKey: 'page_referrer' }, + referrer: { + sourceKeys: ['properties.referrer', 'context.page.referrer'], + destKey: 'page_referrer', + }, title: { sourceKeys: ['properties.title', 'context.page.title'], destKey: 'page_title' }, }; diff --git a/packages/analytics-js-integrations/src/integrations/GA4_V2/browser.js b/packages/analytics-js-integrations/src/integrations/GA4_V2/browser.js index 079608d0fc..01082f20a2 100644 --- a/packages/analytics-js-integrations/src/integrations/GA4_V2/browser.js +++ b/packages/analytics-js-integrations/src/integrations/GA4_V2/browser.js @@ -34,7 +34,7 @@ export default class GA4_V2 extends GA4 { if (!isDefinedAndNotNull(newConfig.measurementId)) { logger.error('Measurement ID is required for GA4'); } - + newConfig.isExtendedGa4_V2 = true; super(newConfig, analytics, destinationInfo); this.analytics = analytics; diff --git a/packages/analytics-js-integrations/src/integrations/Gainsight_PX/browser.js b/packages/analytics-js-integrations/src/integrations/Gainsight_PX/browser.js index b73f0eee4a..7e96a5eb31 100644 --- a/packages/analytics-js-integrations/src/integrations/Gainsight_PX/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Gainsight_PX/browser.js @@ -49,7 +49,7 @@ class Gainsight_PX { } isLoaded() { - return !!(window.aptrinsic && window.aptrinsic.init); + return !!window.aptrinsic?.init; } isReady() { @@ -101,7 +101,7 @@ class Gainsight_PX { }; } - window.aptrinsic('identify',visitorObj, accountObj); + window.aptrinsic('identify', visitorObj, accountObj); } // Custom Events diff --git a/packages/analytics-js-integrations/src/integrations/GoogleAds/browser.test.js b/packages/analytics-js-integrations/src/integrations/GoogleAds/browser.test.js index e79fe7bc1a..6b685f4135 100644 --- a/packages/analytics-js-integrations/src/integrations/GoogleAds/browser.test.js +++ b/packages/analytics-js-integrations/src/integrations/GoogleAds/browser.test.js @@ -1,16 +1,16 @@ -import { GoogleAds } from "."; +import { GoogleAds } from '.'; -describe("Google Ads", () => { - describe("isLoaded", () => { - it("should return false if when init is not called", () => { - const googleAds = new GoogleAds({}, {}, {}); - expect(googleAds.isLoaded()).toBe(false); - }); +describe('Google Ads', () => { + describe('isLoaded', () => { + it('should return false if when init is not called', () => { + const googleAds = new GoogleAds({}, {}, {}); + expect(googleAds.isLoaded()).toBe(false); }); - describe("isReady", () => { - it("should return false if when init is not called", () => { - const googleAds = new GoogleAds({}, {}, {}); - expect(googleAds.isReady()).toBe(false); - }); + }); + describe('isReady', () => { + it('should return false if when init is not called', () => { + const googleAds = new GoogleAds({}, {}, {}); + expect(googleAds.isReady()).toBe(false); }); -}); \ No newline at end of file + }); +}); diff --git a/packages/analytics-js-integrations/src/integrations/GoogleAds/utils.js b/packages/analytics-js-integrations/src/integrations/GoogleAds/utils.js index 0320368d63..06abff7d64 100644 --- a/packages/analytics-js-integrations/src/integrations/GoogleAds/utils.js +++ b/packages/analytics-js-integrations/src/integrations/GoogleAds/utils.js @@ -120,7 +120,7 @@ function getConversionData(eventTypeConversions, eventName, defaultPageConversio function newCustomerAcquisitionReporting(properties) { const updatedProperties = { ...properties }; // create a copy of properties object - if (updatedProperties && updatedProperties.newCustomer) { + if (updatedProperties?.newCustomer) { updatedProperties.new_customer = updatedProperties.newCustomer; delete updatedProperties.newCustomer; } diff --git a/packages/analytics-js-integrations/src/integrations/Heap/browser.js b/packages/analytics-js-integrations/src/integrations/Heap/browser.js index 0f1d2938f7..47b0ccb177 100644 --- a/packages/analytics-js-integrations/src/integrations/Heap/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Heap/browser.js @@ -34,7 +34,7 @@ class Heap { } isLoaded() { - return !!(window.heap && window.heap.appid); + return !!window.heap?.appid; } isReady() { diff --git a/packages/analytics-js-integrations/src/integrations/Klaviyo/browser.js b/packages/analytics-js-integrations/src/integrations/Klaviyo/browser.js index 259dd26fe9..13debb1efb 100644 --- a/packages/analytics-js-integrations/src/integrations/Klaviyo/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Klaviyo/browser.js @@ -102,7 +102,7 @@ class Klaviyo { identify(rudderElement) { const { message } = rudderElement; - if (!(message.context && message.context.traits)) { + if (!message.context?.traits) { logger.error('user traits not present'); return; } diff --git a/packages/analytics-js-integrations/src/integrations/Lotame/browser.js b/packages/analytics-js-integrations/src/integrations/Lotame/browser.js index 595ae2f245..e9ff3fd805 100644 --- a/packages/analytics-js-integrations/src/integrations/Lotame/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Lotame/browser.js @@ -34,7 +34,7 @@ class Lotame { } init() { - window.LOTAME_SYNCH_CALLBACK = () => { }; + window.LOTAME_SYNCH_CALLBACK = () => {}; } isLoaded() { diff --git a/packages/analytics-js-integrations/src/integrations/Mixpanel/util.js b/packages/analytics-js-integrations/src/integrations/Mixpanel/util.js index 5bc2309ff2..3e1eb02ac2 100644 --- a/packages/analytics-js-integrations/src/integrations/Mixpanel/util.js +++ b/packages/analytics-js-integrations/src/integrations/Mixpanel/util.js @@ -2,7 +2,10 @@ /* eslint-disable no-restricted-syntax */ /* eslint-disable no-prototype-builtins */ import get from 'get-value'; -import { DISPLAY_NAME, NAME } from '@rudderstack/analytics-js-common/constants/integrations/Mixpanel/constants'; +import { + DISPLAY_NAME, + NAME, +} from '@rudderstack/analytics-js-common/constants/integrations/Mixpanel/constants'; import Logger from '../../utils/logger'; import { getDefinedTraits, extractCustomFields, isDefinedAndNotNull } from '../../utils/utils'; @@ -284,7 +287,6 @@ const generatePageCustomEventName = (message, userDefinedEventTemplate) => { const getDestinationOptions = integrationsOptions => integrationsOptions && (integrationsOptions[DISPLAY_NAME] || integrationsOptions[NAME]); - export { mapTraits, unionArrays, @@ -297,5 +299,5 @@ export { filterSetOnceTraits, unset, generatePageCustomEventName, - getDestinationOptions + getDestinationOptions, }; diff --git a/packages/analytics-js-integrations/src/integrations/Optimizely/browser.js b/packages/analytics-js-integrations/src/integrations/Optimizely/browser.js index 32e5ceed8e..07acc2bb4f 100644 --- a/packages/analytics-js-integrations/src/integrations/Optimizely/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Optimizely/browser.js @@ -126,7 +126,7 @@ class Optimizely { sendCampaignData(campaignState); } } catch (e) { - logger.error('Page loaded without Optimizely.') + logger.error('Page loaded without Optimizely.'); } }; @@ -140,7 +140,7 @@ class Optimizely { if (!state) { return undefined; } - const referrer = state.getRedirectInfo() && state.getRedirectInfo().referrer; + const referrer = state.getRedirectInfo()?.referrer; if (!referrer) { return undefined; } @@ -168,7 +168,7 @@ class Optimizely { try { state = window?.optimizely?.get('state'); } catch (e) { - state = undefined + state = undefined; } if (state) { const referrer = checkReferrer(); @@ -194,7 +194,6 @@ class Optimizely { }, }); } - }; registerCurrentlyActiveCampaigns(); registerFutureActiveCampaigns(); diff --git a/packages/analytics-js-integrations/src/integrations/Podsights/browser.js b/packages/analytics-js-integrations/src/integrations/Podsights/browser.js index 9aa7b1ba36..d97b99a8e0 100644 --- a/packages/analytics-js-integrations/src/integrations/Podsights/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Podsights/browser.js @@ -16,7 +16,7 @@ import { ADD_TO_CART_EVENT, CHECK_OUT_EVENT, LEAD_EVENT, -} from '@rudderstack/analytics-js-common/constants/integrations/CommonIntegrationsConstant/constants' +} from '@rudderstack/analytics-js-common/constants/integrations/CommonIntegrationsConstant/constants'; import { ScriptLoader } from '@rudderstack/analytics-js-common/v1.1/utils/ScriptLoader'; import Logger from '../../utils/logger'; import { diff --git a/packages/analytics-js-integrations/src/integrations/Posthog/browser.js b/packages/analytics-js-integrations/src/integrations/Posthog/browser.js index 3ea0f35205..ef5ecb22b7 100644 --- a/packages/analytics-js-integrations/src/integrations/Posthog/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Posthog/browser.js @@ -29,7 +29,7 @@ class Posthog { this.propertyBlackList = getPropertyBlackList(config); this.xhrHeaders = getXhrHeaders(config); this.enableLocalStoragePersistence = config.enableLocalStoragePersistence; - if(isDefinedAndNotNull(config.personProfiles)) { + if (isDefinedAndNotNull(config.personProfiles)) { this.personProfiles = config.personProfiles; } ({ @@ -55,7 +55,7 @@ class Posthog { disable_cookie: this.disableCookie, }; - if(this.personProfiles) { + if (this.personProfiles) { configObject.person_profiles = this.personProfiles; } diff --git a/packages/analytics-js-integrations/src/integrations/Qualaroo/browser.js b/packages/analytics-js-integrations/src/integrations/Qualaroo/browser.js index c746555bfe..3dabdf26d3 100644 --- a/packages/analytics-js-integrations/src/integrations/Qualaroo/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Qualaroo/browser.js @@ -48,7 +48,6 @@ class Qualaroo { } isReady() { - if (this.recordQualarooEvents) { recordQualarooEvents( this.updateEventNames, diff --git a/packages/analytics-js-integrations/src/integrations/Qualtrics/browser.js b/packages/analytics-js-integrations/src/integrations/Qualtrics/browser.js index c848f43ba1..60f102d434 100644 --- a/packages/analytics-js-integrations/src/integrations/Qualtrics/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Qualtrics/browser.js @@ -44,7 +44,7 @@ class Qualtrics { } isLoaded() { - return !!(window._qsie && window.QSI && window.QSI.API); + return !!(window._qsie && window.QSI?.API); } isReady() { diff --git a/packages/analytics-js-integrations/src/integrations/Rockerbox/browser.js b/packages/analytics-js-integrations/src/integrations/Rockerbox/browser.js index b31a5d6b57..925f1457a7 100644 --- a/packages/analytics-js-integrations/src/integrations/Rockerbox/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Rockerbox/browser.js @@ -64,7 +64,6 @@ class Rockerbox { return; } - const { message } = rudderElement; const { event, anonymousId, properties } = message; if (!event) { diff --git a/packages/analytics-js-integrations/src/integrations/Sendinblue/browser.js b/packages/analytics-js-integrations/src/integrations/Sendinblue/browser.js index cd1a9cc56e..b087aa7829 100644 --- a/packages/analytics-js-integrations/src/integrations/Sendinblue/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Sendinblue/browser.js @@ -43,7 +43,6 @@ class Sendinblue { } isReady() { - return this.isLoaded(); } diff --git a/packages/analytics-js-integrations/src/integrations/Sprig/browser.js b/packages/analytics-js-integrations/src/integrations/Sprig/browser.js index 4ea8abfad9..1885283d8b 100644 --- a/packages/analytics-js-integrations/src/integrations/Sprig/browser.js +++ b/packages/analytics-js-integrations/src/integrations/Sprig/browser.js @@ -7,83 +7,83 @@ import { loadNativeSdk } from './nativeSdkLoader'; const logger = new Logger(NAME); class Sprig { - constructor(config, analytics, destinationInfo) { - if (analytics.logLevel) { - logger.setLogLevel(analytics.logLevel); - } - this.analytics = analytics; - this.environmentId = config.environmentId; - this.name = NAME; - ({ - shouldApplyDeviceModeTransformation: this.shouldApplyDeviceModeTransformation, - propagateEventsUntransformedOnError: this.propagateEventsUntransformedOnError, - destinationId: this.destinationId, - } = destinationInfo ?? {}); + constructor(config, analytics, destinationInfo) { + if (analytics.logLevel) { + logger.setLogLevel(analytics.logLevel); } + this.analytics = analytics; + this.environmentId = config.environmentId; + this.name = NAME; + ({ + shouldApplyDeviceModeTransformation: this.shouldApplyDeviceModeTransformation, + propagateEventsUntransformedOnError: this.propagateEventsUntransformedOnError, + destinationId: this.destinationId, + } = destinationInfo ?? {}); + } - loadScript() { - loadNativeSdk(this.environmentId); - } + loadScript() { + loadNativeSdk(this.environmentId); + } - init() { - this.loadScript(); - } + init() { + this.loadScript(); + } - isLoaded() { - return !!window.Sprig; - } + isLoaded() { + return !!window.Sprig; + } - isReady() { - return !!window.Sprig; - } + isReady() { + return !!window.Sprig; + } - identify(rudderElement) { - const { message } = rudderElement; - const { userId, context } = message; - if (userId) { - window.Sprig('setUserId', userId); - } + identify(rudderElement) { + const { message } = rudderElement; + const { userId, context } = message; + if (userId) { + window.Sprig('setUserId', userId); + } - const email = get(message, 'context.traits.email'); - if (email) { - window.Sprig('setEmail', email); - } + const email = get(message, 'context.traits.email'); + if (email) { + window.Sprig('setEmail', email); + } - const { traits } = context; - if (traits.email) { - delete traits.email; - } - if (Object.keys(traits).length > 0) { - window.Sprig('setAttributes', traits); - } + const { traits } = context; + if (traits.email) { + delete traits.email; + } + if (Object.keys(traits).length > 0) { + window.Sprig('setAttributes', traits); } + } - track(rudderElement) { - const { message } = rudderElement; - const { event, properties, userId } = message; - if (!event) { - logger.error('Event name is required for track call'); - return; - } + track(rudderElement) { + const { message } = rudderElement; + const { event, properties, userId } = message; + if (!event) { + logger.error('Event name is required for track call'); + return; + } - if(typeof event !== 'string'){ - logger.error('Event name should be string'); - return; - } + if (typeof event !== 'string') { + logger.error('Event name should be string'); + return; + } - if (event.toLowerCase() === 'signed out') { - window.Sprig('logoutUser'); - } else { - const payload = { eventName: event }; - if (userId) { - payload.userId = userId; - } - if (typeof properties === 'object' && Object.keys(properties).length > 0) { - payload.properties = properties; - } - window.Sprig('identifyAndTrack', payload); - } + if (event.toLowerCase() === 'signed out') { + window.Sprig('logoutUser'); + } else { + const payload = { eventName: event }; + if (userId) { + payload.userId = userId; + } + if (typeof properties === 'object' && Object.keys(properties).length > 0) { + payload.properties = properties; + } + window.Sprig('identifyAndTrack', payload); } + } } -export default Sprig; \ No newline at end of file +export default Sprig; diff --git a/packages/analytics-js-integrations/src/integrations/Sprig/index.js b/packages/analytics-js-integrations/src/integrations/Sprig/index.js index 5b1301ec64..f9a58567d1 100644 --- a/packages/analytics-js-integrations/src/integrations/Sprig/index.js +++ b/packages/analytics-js-integrations/src/integrations/Sprig/index.js @@ -1 +1 @@ -export { default as Sprig } from './browser'; \ No newline at end of file +export { default as Sprig } from './browser'; diff --git a/packages/analytics-js-integrations/src/integrations/VWO/browser.js b/packages/analytics-js-integrations/src/integrations/VWO/browser.js index 44ee23e8d4..761cabfd4d 100644 --- a/packages/analytics-js-integrations/src/integrations/VWO/browser.js +++ b/packages/analytics-js-integrations/src/integrations/VWO/browser.js @@ -130,14 +130,13 @@ class VWO { } track(rudderElement) { - const eventName = rudderElement.message.event; // throw error if event name is not present if (!eventName) { logger.error('[VWO] track:: event name is required'); return; } - const properties = (rudderElement.message && rudderElement.message.properties) || {}; + const properties = rudderElement.message?.properties || {}; window.VWO = window.VWO || []; if (eventName === 'Order Completed') { const total = rudderElement.message.properties diff --git a/packages/analytics-js-integrations/src/utils/commonUtils.js b/packages/analytics-js-integrations/src/utils/commonUtils.js index 09f64a20aa..519356def3 100644 --- a/packages/analytics-js-integrations/src/utils/commonUtils.js +++ b/packages/analytics-js-integrations/src/utils/commonUtils.js @@ -157,7 +157,7 @@ function getEventMappingFromConfig(event, eventsHashmap) { function getDestinationExternalID(message, type) { let externalIdArray = null; let destinationExternalId = null; - if (message.context && message.context.externalId) { + if (message.context?.externalId) { externalIdArray = message.context.externalId; } if (externalIdArray && Array.isArray(externalIdArray)) { diff --git a/packages/analytics-js-integrations/src/utils/utils.js b/packages/analytics-js-integrations/src/utils/utils.js index c287833699..824d9d5f00 100644 --- a/packages/analytics-js-integrations/src/utils/utils.js +++ b/packages/analytics-js-integrations/src/utils/utils.js @@ -9,7 +9,7 @@ import { logger } from '@rudderstack/analytics-js-common/v1.1/utils/logUtil'; * @param {*} inURL */ function removeTrailingSlashes(inURL) { - return inURL && inURL.endsWith('/') ? inURL.replace(/\/+$/, '') : inURL; + return inURL?.endsWith('/') ? inURL.replace(/\/+$/, '') : inURL; } /** @@ -51,7 +51,7 @@ function getRevenue(properties, eventName) { const orderCompletedRegExp = /^[ _]?completed[ _]?order[ _]?|^[ _]?order[ _]?completed[ _]?$/i; // it's always revenue, unless it's called during an order completion. - if (!revenue && eventName && eventName.match(orderCompletedRegExp)) { + if (!revenue && eventName?.match(orderCompletedRegExp)) { revenue = total; } diff --git a/packages/analytics-js-plugins/CHANGELOG.md b/packages/analytics-js-plugins/CHANGELOG.md index 2dd234d70a..9a4a17473c 100644 --- a/packages/analytics-js-plugins/CHANGELOG.md +++ b/packages/analytics-js-plugins/CHANGELOG.md @@ -2,6 +2,24 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [3.6.20](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-plugins@3.6.19...@rudderstack/analytics-js-plugins@3.6.20) (2024-12-17) + +### Dependency Updates + +* `@rudderstack/analytics-js-common` updated to version `3.14.14` +* `@rudderstack/analytics-js-cookies` updated to version `0.4.17` + +### Bug Fixes + +* remove circular dependency in packages ([#1973](https://github.com/rudderlabs/rudder-sdk-js/issues/1973)) ([e525496](https://github.com/rudderlabs/rudder-sdk-js/commit/e5254964310c2c73baaf4d0655c3e4025c5e7d2b)) +* separator and make changes in bugsnag plugin ([b69347c](https://github.com/rudderlabs/rudder-sdk-js/commit/b69347cd9bbf3a395b2f557f8219287900ceca5a)) + +## [3.6.19](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-plugins@3.6.18...@rudderstack/analytics-js-plugins@3.6.19) (2024-12-13) + +### Dependency Updates + +* `@rudderstack/analytics-js` updated to version `3.11.15` +* `@rudderstack/analytics-js-cookies` updated to version `0.4.16` ## [3.6.18](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-plugins@3.6.17...@rudderstack/analytics-js-plugins@3.6.18) (2024-12-06) ### Dependency Updates diff --git a/packages/analytics-js-plugins/CHANGELOG_LATEST.md b/packages/analytics-js-plugins/CHANGELOG_LATEST.md index 21a9836db6..6abd863f11 100644 --- a/packages/analytics-js-plugins/CHANGELOG_LATEST.md +++ b/packages/analytics-js-plugins/CHANGELOG_LATEST.md @@ -1,6 +1,12 @@ -## [3.6.18](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-plugins@3.6.17...@rudderstack/analytics-js-plugins@3.6.18) (2024-12-06) +## [3.6.20](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-plugins@3.6.19...@rudderstack/analytics-js-plugins@3.6.20) (2024-12-17) ### Dependency Updates -* `@rudderstack/analytics-js-common` updated to version `3.14.13` -* `@rudderstack/analytics-js` updated to version `3.11.14` +* `@rudderstack/analytics-js-common` updated to version `3.14.14` +* `@rudderstack/analytics-js-cookies` updated to version `0.4.17` + +### Bug Fixes + +* remove circular dependency in packages ([#1973](https://github.com/rudderlabs/rudder-sdk-js/issues/1973)) ([e525496](https://github.com/rudderlabs/rudder-sdk-js/commit/e5254964310c2c73baaf4d0655c3e4025c5e7d2b)) +* separator and make changes in bugsnag plugin ([b69347c](https://github.com/rudderlabs/rudder-sdk-js/commit/b69347cd9bbf3a395b2f557f8219287900ceca5a)) + diff --git a/packages/analytics-js-plugins/LICENSE.md b/packages/analytics-js-plugins/LICENSE.md index 554bb72539..37517857b4 100644 --- a/packages/analytics-js-plugins/LICENSE.md +++ b/packages/analytics-js-plugins/LICENSE.md @@ -40,14 +40,14 @@ As far as the law allows, the software comes as is, without any warranty or cond ## Definitions -The *licensor* is the entity offering these terms, and the *software* is the software the licensor makes available under these terms, including any portion of it. +The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it. -*you* refers to the individual or entity agreeing to these terms. +_you_ refers to the individual or entity agreeing to these terms. -*your company* is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. *control* means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. +_your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. -*your licenses* are all the licenses granted to you for the software under these terms. +_your licenses_ are all the licenses granted to you for the software under these terms. -*use* means anything you do with the software requiring one of your licenses. +_use_ means anything you do with the software requiring one of your licenses. -*trademark* means trademarks, service marks, and similar rights. +_trademark_ means trademarks, service marks, and similar rights. diff --git a/packages/analytics-js-plugins/__fixtures__/fixtures.ts b/packages/analytics-js-plugins/__fixtures__/fixtures.ts index cf149a7c1e..4f1a256543 100644 --- a/packages/analytics-js-plugins/__fixtures__/fixtures.ts +++ b/packages/analytics-js-plugins/__fixtures__/fixtures.ts @@ -1,3 +1,5 @@ +import type { RudderEvent } from '@rudderstack/analytics-js-common/types/Event'; + const sdkName = 'RudderLabs JavaScript SDK'; const rudderEventPage = { properties: { @@ -77,7 +79,7 @@ const rudderEventPage = { userId: 'customUserID', anonymousId: '1901c08d-d505-41cd-81a6-060457fad648', event: null, -}; +} as unknown as RudderEvent; const errorMessage = 'Invalid request payload'; diff --git a/packages/analytics-js-plugins/__fixtures__/msw.handlers.js b/packages/analytics-js-plugins/__fixtures__/msw.handlers.js index 292c3e773c..130000bd57 100644 --- a/packages/analytics-js-plugins/__fixtures__/msw.handlers.js +++ b/packages/analytics-js-plugins/__fixtures__/msw.handlers.js @@ -40,7 +40,7 @@ const handlers = [ status: 500, }); }), - http.get(`https://asdf.com/bugsnag.min.js`, () => { + http.get(`__RS_BUGSNAG_SDK_URL__`, () => { return new HttpResponse(errorMessage, { status: 404, }); diff --git a/packages/analytics-js-plugins/__mocks__/.gitkeep b/packages/analytics-js-plugins/__mocks__/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/analytics-js-plugins/__mocks__/HttpClient.ts b/packages/analytics-js-plugins/__mocks__/HttpClient.ts new file mode 100644 index 0000000000..46a62d81f8 --- /dev/null +++ b/packages/analytics-js-plugins/__mocks__/HttpClient.ts @@ -0,0 +1,17 @@ +import type { IErrorHandler } from '@rudderstack/analytics-js-common/types/ErrorHandler'; +import type { IHttpClient } from '@rudderstack/analytics-js-common/types/HttpClient'; +import type { ILogger } from '@rudderstack/analytics-js-common/types/Logger'; + +class HttpClient implements IHttpClient { + errorHandler?: IErrorHandler; + logger?: ILogger; + hasErrorHandler = false; + getData = jest.fn(); + getAsyncData = jest.fn(); + setAuthHeader = jest.fn(); + resetAuthHeader = jest.fn(); +} + +const defaultHttpClient = new HttpClient(); + +export { HttpClient, defaultHttpClient }; diff --git a/packages/analytics-js-plugins/__mocks__/PluginEngine.ts b/packages/analytics-js-plugins/__mocks__/PluginEngine.ts new file mode 100644 index 0000000000..7132eedcdb --- /dev/null +++ b/packages/analytics-js-plugins/__mocks__/PluginEngine.ts @@ -0,0 +1,20 @@ +import type { IPluginEngine } from '@rudderstack/analytics-js-common/types/PluginEngine'; + +class PluginEngine implements IPluginEngine { + // mock all the properties and methods of the PluginEngine class + plugins: any[] = []; + byName: any = {}; + cache: any = {}; + config: any = { throws: true }; + register = jest.fn(); + unregister = jest.fn(); + getPlugin = jest.fn(); + getPlugins = jest.fn(); + invoke = jest.fn(); + invokeSingle = jest.fn(); + invokeMultiple = jest.fn(); +} + +const defaultPluginEngine = new PluginEngine(); + +export { PluginEngine, defaultPluginEngine }; diff --git a/packages/analytics-js-plugins/__mocks__/PluginsManager.ts b/packages/analytics-js-plugins/__mocks__/PluginsManager.ts new file mode 100644 index 0000000000..9229ae2170 --- /dev/null +++ b/packages/analytics-js-plugins/__mocks__/PluginsManager.ts @@ -0,0 +1,18 @@ +import type { IPluginEngine } from '@rudderstack/analytics-js-common/types/PluginEngine'; +import type { IPluginsManager } from '@rudderstack/analytics-js-common/types/PluginsManager'; +import { defaultPluginEngine } from './PluginEngine'; + +class PluginsManager implements IPluginsManager { + // mock all the properties and methods of the PluginsManager class + engine: IPluginEngine = defaultPluginEngine; + init = jest.fn(); + attachEffects = jest.fn(); + setActivePlugins = jest.fn(); + invokeMultiple = jest.fn(); + invokeSingle = jest.fn(); + register = jest.fn(); +} + +const defaultPluginsManager = new PluginsManager(); + +export { PluginsManager, defaultPluginsManager }; diff --git a/packages/analytics-js-plugins/__mocks__/state.ts b/packages/analytics-js-plugins/__mocks__/state.ts new file mode 100644 index 0000000000..a53a58ebbe --- /dev/null +++ b/packages/analytics-js-plugins/__mocks__/state.ts @@ -0,0 +1,208 @@ +import { signal } from '@preact/signals-core'; +import type { ApplicationState } from '@rudderstack/analytics-js-common/types/ApplicationState'; +import type { PluginName } from '@rudderstack/analytics-js-common/types/PluginsManager'; +import { clone } from 'ramda'; + +const defaultStateValues: ApplicationState = { + capabilities: { + isOnline: signal(true), + storage: { + isLocalStorageAvailable: signal(false), + isCookieStorageAvailable: signal(false), + isSessionStorageAvailable: signal(false), + }, + isBeaconAvailable: signal(false), + isLegacyDOM: signal(false), + isUaCHAvailable: signal(false), + isCryptoAvailable: signal(false), + isIE11: signal(false), + isAdBlocked: signal(false), + }, + consents: { + enabled: signal(false), + initialized: signal(false), + data: signal({}), + activeConsentManagerPluginName: signal(undefined), + preConsent: signal({ enabled: false }), + postConsent: signal({}), + resolutionStrategy: signal('and'), + provider: signal(undefined), + metadata: signal(undefined), + }, + context: { + app: signal({ + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: 'dev-snapshot', + installType: 'cdn', + }), + traits: signal(null), + library: signal({ + name: 'RudderLabs JavaScript SDK', + version: 'dev-snapshot', + snippetVersion: (globalThis as typeof window).RudderSnippetVersion, + }), + userAgent: signal(''), + device: signal(null), + network: signal(null), + os: signal({ + name: '', + version: '', + }), + locale: signal(null), + screen: signal({ + density: 0, + width: 0, + height: 0, + innerWidth: 0, + innerHeight: 0, + }), + 'ua-ch': signal(undefined), + timezone: signal(undefined), + }, + eventBuffer: { + toBeProcessedArray: signal([]), + readyCallbacksArray: signal([]), + }, + lifecycle: { + activeDataplaneUrl: signal(undefined), + integrationsCDNPath: signal(undefined), + pluginsCDNPath: signal(undefined), + sourceConfigUrl: signal(undefined), + status: signal(undefined), + initialized: signal(false), + logLevel: signal('ERROR'), + loaded: signal(false), + readyCallbacks: signal([]), + writeKey: signal(undefined), + dataPlaneUrl: signal(undefined), + }, + loadOptions: signal({ + logLevel: 'ERROR', + configUrl: 'https://api.rudderstack.com', + loadIntegration: true, + sessions: { + autoTrack: true, + timeout: 30 * 60 * 1000, + }, + sameSiteCookie: 'Lax', + polyfillIfRequired: true, + integrations: { All: true }, + useBeacon: false, + beaconQueueOptions: {}, + destinationsQueueOptions: {}, + queueOptions: {}, + lockIntegrationsVersion: false, + lockPluginsVersion: false, + uaChTrackLevel: 'none', + plugins: [], + useGlobalIntegrationsConfigInEvents: false, + bufferDataPlaneEventsUntilReady: false, + dataPlaneEventsBufferTimeout: 1000, + storage: { + encryption: { + version: 'v3', + }, + migrate: true, + cookie: {}, + }, + sendAdblockPageOptions: {}, + useServerSideCookies: false, + }), + metrics: { + retries: signal(0), + dropped: signal(0), + sent: signal(0), + queued: signal(0), + triggered: signal(0), + metricsServiceUrl: signal(undefined), + }, + nativeDestinations: { + configuredDestinations: signal([]), + activeDestinations: signal([]), + loadOnlyIntegrations: signal({}), + failedDestinations: signal([]), + loadIntegration: signal(true), + initializedDestinations: signal([]), + clientDestinationsReady: signal(false), + integrationsConfig: signal({}), + }, + plugins: { + ready: signal(false), + loadedPlugins: signal([]), + failedPlugins: signal([]), + pluginsToLoadFromConfig: signal([]), + activePlugins: signal([]), + totalPluginsToLoad: signal(0), + }, + reporting: { + isErrorReportingEnabled: signal(false), + isMetricsReportingEnabled: signal(false), + isErrorReportingPluginLoaded: signal(false), + breadcrumbs: signal([]), + }, + session: { + userId: signal(''), + userTraits: signal({}), + anonymousId: signal(''), + groupId: signal(''), + groupTraits: signal({}), + initialReferrer: signal(''), + initialReferringDomain: signal(''), + sessionInfo: signal({}), + authToken: signal(''), + }, + source: signal({ + id: 'dummy-source-id', + workspaceId: 'dummy-workspace-id', + }), + storage: { + encryptionPluginName: signal(undefined), + migrate: signal(false), + type: signal(undefined), + cookie: signal(undefined), + entries: signal({}), + trulyAnonymousTracking: signal(false), + }, + serverCookies: { + isEnabledServerSideCookies: signal(false), + dataServiceUrl: signal(undefined), + }, + dataPlaneEvents: { + eventsQueuePluginName: signal(undefined), + deliveryEnabled: signal(true), // Delivery should always happen + }, + autoTrack: { + enabled: signal(false), + pageLifecycle: { + enabled: signal(false), + visitId: signal(undefined), + pageLoadedTimestamp: signal(undefined), + }, + }, +}; + +const state: ApplicationState = { + ...clone(defaultStateValues), +}; + +const resetState = () => { + state.capabilities = clone(defaultStateValues.capabilities); + state.consents = clone(defaultStateValues.consents); + state.context = clone(defaultStateValues.context); + state.eventBuffer = clone(defaultStateValues.eventBuffer); + state.lifecycle = clone(defaultStateValues.lifecycle); + state.loadOptions = clone(defaultStateValues.loadOptions); + state.metrics = clone(defaultStateValues.metrics); + state.nativeDestinations = clone(defaultStateValues.nativeDestinations); + state.plugins = clone(defaultStateValues.plugins); + state.reporting = clone(defaultStateValues.reporting); + state.session = clone(defaultStateValues.session); + state.source = clone(defaultStateValues.source); + state.storage = clone(defaultStateValues.storage); + state.serverCookies = clone(defaultStateValues.serverCookies); + state.dataPlaneEvents = clone(defaultStateValues.dataPlaneEvents); + state.autoTrack = clone(defaultStateValues.autoTrack); +}; + +export { state, resetState }; diff --git a/packages/analytics-js-plugins/__tests__/bugsnag/index.test.ts b/packages/analytics-js-plugins/__tests__/bugsnag/index.test.ts index 4c6674bc45..1064d9ea29 100644 --- a/packages/analytics-js-plugins/__tests__/bugsnag/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/bugsnag/index.test.ts @@ -1,33 +1,10 @@ -import { signal } from '@preact/signals-core'; -import { clone } from 'ramda'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; import { Bugsnag } from '../../src/bugsnag'; import * as bugsnagConstants from '../../src/bugsnag/constants'; +import { resetState, state } from '../../__mocks__/state'; describe('Plugin - Bugsnag', () => { - const originalState = { - plugins: { - loadedPlugins: signal([]), - }, - lifecycle: { - writeKey: signal('dummy-write-key'), - }, - source: signal({ - id: 'test-source-id', - }), - context: { - app: signal({ - name: 'test-app', - namespace: 'test-namespace', - version: '1.0.0', - installType: 'npm', - }), - }, - }; - - let state: any; - const origApiKey = bugsnagConstants.API_KEY; - const origMaxSDKWait = bugsnagConstants.MAX_WAIT_FOR_SDK_LOAD_MS; const mountBugsnagSDK = () => { (window as any).bugsnag = jest.fn(() => ({ @@ -39,21 +16,28 @@ describe('Plugin - Bugsnag', () => { }; beforeEach(() => { - state = clone(originalState); + resetState(); delete (window as any).bugsnag; - bugsnagConstants.API_KEY = origApiKey; - bugsnagConstants.MAX_WAIT_FOR_SDK_LOAD_MS = origMaxSDKWait; + + Object.defineProperty(bugsnagConstants, 'API_KEY', { + value: origApiKey, + writable: true, + }); }); it('should add Bugsnag plugin in the loaded plugin list', () => { - Bugsnag().initialize(state); + Bugsnag().initialize?.(state); expect(state.plugins.loadedPlugins.value.includes('Bugsnag')).toBe(true); }); it('should reject the promise if the Api Key is not valid', async () => { - bugsnagConstants.API_KEY = '{{ dummy api key }}'; + Object.defineProperty(bugsnagConstants, 'API_KEY', { + value: '{{ dummy api key }}', + writable: true, + }); - const pluginInitPromise = Bugsnag().errorReportingProvider.init(); + // eslint-disable-next-line @typescript-eslint/dot-notation + const pluginInitPromise = (Bugsnag().errorReportingProvider as ExtensionPoint)?.init?.(); await expect(pluginInitPromise).rejects.toThrow( 'The Bugsnag API key ({{ dummy api key }}) is invalid or not provided.', @@ -61,29 +45,45 @@ describe('Plugin - Bugsnag', () => { }); it('should reject the promise if the Bugsnag client could not be initialized', async () => { - bugsnagConstants.MAX_WAIT_FOR_SDK_LOAD_MS = 1000; + jest.useFakeTimers(); + jest.setSystemTime(0); const mockExtSrcLoader = { loadJSFile: jest.fn(() => Promise.resolve()), }; - const pluginInitPromise = Bugsnag().errorReportingProvider.init(state, mockExtSrcLoader); + const pluginInitPromise = (Bugsnag().errorReportingProvider as ExtensionPoint)?.init?.( + state, + mockExtSrcLoader, + ); + + // Advance timers to trigger the timeout + jest.advanceTimersByTime(10000); await expect(pluginInitPromise).rejects.toThrow( - 'A timeout 1000 ms occurred while trying to load the Bugsnag SDK.', + 'A timeout 10000 ms occurred while trying to load the Bugsnag SDK.', ); + + jest.useRealTimers(); }); it('should initialize the Bugsnag SDK and return the client instance', async () => { - setTimeout(() => { - mountBugsnagSDK(); - }, 500); + jest.useFakeTimers(); + jest.setSystemTime(0); const mockExtSrcLoader = { loadJSFile: jest.fn(() => Promise.resolve()), }; - const pluginInitPromise = Bugsnag().errorReportingProvider.init(state, mockExtSrcLoader); + const pluginInitPromise = (Bugsnag().errorReportingProvider as ExtensionPoint)?.init?.( + state, + mockExtSrcLoader, + ); + + jest.advanceTimersByTime(1); + mountBugsnagSDK(); + + jest.runAllTimers(); await expect(pluginInitPromise).resolves.toBeDefined(); }); @@ -93,7 +93,7 @@ describe('Plugin - Bugsnag', () => { const mockError = new Error('Test Error'); - Bugsnag().errorReportingProvider.notify(bsClient, mockError); + (Bugsnag().errorReportingProvider as ExtensionPoint)?.notify?.(bsClient, mockError); expect(bsClient.notify).toHaveBeenCalledWith(mockError); }); @@ -103,7 +103,7 @@ describe('Plugin - Bugsnag', () => { const mockMessage = 'Test Breadcrumb'; - Bugsnag().errorReportingProvider.breadcrumb(bsClient, mockMessage); + (Bugsnag().errorReportingProvider as ExtensionPoint)?.breadcrumb?.(bsClient, mockMessage); expect(bsClient.leaveBreadcrumb).toHaveBeenCalledWith(mockMessage); }); diff --git a/packages/analytics-js-plugins/__tests__/bugsnag/utils.test.ts b/packages/analytics-js-plugins/__tests__/bugsnag/utils.test.ts index 6d58890430..855073690f 100644 --- a/packages/analytics-js-plugins/__tests__/bugsnag/utils.test.ts +++ b/packages/analytics-js-plugins/__tests__/bugsnag/utils.test.ts @@ -1,10 +1,7 @@ -/* eslint-disable max-classes-per-file */ import { signal } from '@preact/signals-core'; import { ExternalSrcLoader } from '@rudderstack/analytics-js-common/services/ExternalSrcLoader'; -import type { ILogger } from '@rudderstack/analytics-js-common/types/Logger'; -import type { IErrorHandler } from '@rudderstack/analytics-js-common/types/ErrorHandler'; -import * as timeouts from '@rudderstack/analytics-js-common/src/constants/timeouts'; -import type { ApplicationState } from '@rudderstack/analytics-js-common/types/ApplicationState'; +import { defaultErrorHandler } from '@rudderstack/analytics-js-common/__mocks__/ErrorHandler'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; import * as bugsnagConstants from '../../src/bugsnag/constants'; import { isApiKeyValid, @@ -20,54 +17,171 @@ import { } from '../../src/bugsnag/utils'; import { server } from '../../__fixtures__/msw.server'; import type { BugsnagLib } from '../../src/types/plugins'; - -let state: ApplicationState; +import { resetState, state } from '../../__mocks__/state'; beforeEach(() => { window.RudderSnippetVersion = '3.0.0'; - state = { - context: { - app: signal({ - name: 'test-app', - namespace: 'test-namespace', - version: '1.0.0', - installType: 'npm', - }), - }, - source: signal({ - id: 'dummy-source-id', - }), - lifecycle: { - writeKey: signal('dummy-write-key'), - }, - }; + resetState(); + state.lifecycle.writeKey.value = 'dummy-write-key'; }); afterEach(() => { window.RudderSnippetVersion = undefined; }); -describe('Bugsnag utilities', () => { - class MockLogger implements ILogger { - warn = jest.fn(); - log = jest.fn(); - error = jest.fn(); - info = jest.fn(); - debug = jest.fn(); - minLogLevel = 0; - scope = 'test scope'; - setMinLogLevel = jest.fn(); - setScope = jest.fn(); - logProvider = console; - } - - class MockErrorHandler implements IErrorHandler { - init = jest.fn(); - onError = jest.fn(); - leaveBreadcrumb = jest.fn(); - notifyError = jest.fn(); - } +const DEFAULT_STATE_DATA = { + autoTrack: { + enabled: false, + pageLifecycle: { + enabled: false, + }, + }, + capabilities: { + isAdBlocked: false, + isBeaconAvailable: false, + isCryptoAvailable: false, + isIE11: false, + isLegacyDOM: false, + isOnline: true, + isUaCHAvailable: false, + storage: { + isCookieStorageAvailable: false, + isLocalStorageAvailable: false, + isSessionStorageAvailable: false, + }, + }, + consents: { + data: {}, + enabled: false, + initialized: false, + postConsent: {}, + preConsent: { + enabled: false, + }, + resolutionStrategy: 'and', + }, + context: { + app: { + installType: 'cdn', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: 'dev-snapshot', + }, + device: null, + library: { + name: 'RudderLabs JavaScript SDK', + version: 'dev-snapshot', + }, + locale: null, + network: null, + os: { + name: '', + version: '', + }, + screen: { + density: 0, + height: 0, + innerHeight: 0, + innerWidth: 0, + width: 0, + }, + userAgent: '', + }, + dataPlaneEvents: { + deliveryEnabled: true, + }, + lifecycle: { + initialized: false, + loaded: false, + logLevel: 'ERROR', + readyCallbacks: [], + writeKey: 'dummy-write-key', + }, + loadOptions: { + beaconQueueOptions: {}, + bufferDataPlaneEventsUntilReady: false, + configUrl: 'https://api.rudderstack.com', + dataPlaneEventsBufferTimeout: 1000, + destinationsQueueOptions: {}, + integrations: { + All: true, + }, + loadIntegration: true, + lockIntegrationsVersion: false, + lockPluginsVersion: false, + logLevel: 'ERROR', + plugins: [], + polyfillIfRequired: true, + queueOptions: {}, + sameSiteCookie: 'Lax', + sendAdblockPageOptions: {}, + sessions: { + autoTrack: true, + timeout: 1800000, + }, + storage: { + cookie: {}, + encryption: { + version: 'v3', + }, + migrate: true, + }, + uaChTrackLevel: 'none', + useBeacon: false, + useGlobalIntegrationsConfigInEvents: false, + useServerSideCookies: false, + }, + metrics: { + dropped: 0, + queued: 0, + retries: 0, + sent: 0, + triggered: 0, + }, + nativeDestinations: { + activeDestinations: [], + clientDestinationsReady: false, + configuredDestinations: [], + failedDestinations: [], + initializedDestinations: [], + integrationsConfig: {}, + loadIntegration: true, + loadOnlyIntegrations: {}, + }, + plugins: { + activePlugins: [], + failedPlugins: [], + loadedPlugins: [], + pluginsToLoadFromConfig: [], + ready: false, + totalPluginsToLoad: 0, + }, + reporting: { + breadcrumbs: [], + isErrorReportingEnabled: false, + isErrorReportingPluginLoaded: false, + isMetricsReportingEnabled: false, + }, + serverCookies: { + isEnabledServerSideCookies: false, + }, + session: { + initialReferrer: '', + initialReferringDomain: '', + sessionInfo: {}, + }, + source: { + id: 'dummy-source-id', + workspaceId: 'dummy-workspace-id', + }, + storage: { + entries: {}, + migrate: false, + trulyAnonymousTracking: false, + }, +}; +describe('Bugsnag utilities', () => { describe('isApiKeyValid', () => { it('should return true for a valid API key', () => { const apiKey = '1234567890abcdef'; @@ -104,8 +218,6 @@ describe('Bugsnag utilities', () => { describe('getReleaseStage', () => { let windowSpy: any; - let documentSpy: any; - let navigatorSpy: any; let locationSpy: any; beforeEach(() => { @@ -166,7 +278,7 @@ describe('Bugsnag utilities', () => { }); describe('isRudderSDKError', () => { - const testCaseData = [ + const testCaseData: any[][] = [ ['https://invalid-domain.com/rsa.min.js', true], ['https://invalid-domain.com/rss.min.js', false], ['https://invalid-domain.com/rsa-plugins-Beacon.min.js', true], @@ -184,7 +296,7 @@ describe('Bugsnag utilities', () => { it.each(testCaseData)( 'if script src is "%s" then it should return the value as "%s" ', - (scriptSrc, expectedValue) => { + (scriptSrc: any, expectedValue: boolean) => { // Bugsnag error event object structure const event = { stacktrace: [ @@ -192,7 +304,7 @@ describe('Bugsnag utilities', () => { file: scriptSrc, }, ], - }; + } as unknown as BugsnagLib.Report; expect(isRudderSDKError(event)).toBe(expectedValue); }, @@ -202,40 +314,26 @@ describe('Bugsnag utilities', () => { describe('enhanceErrorEventMutator', () => { it('should return the enhanced error event object', () => { const event = { - metadata: {}, + metaData: {}, stacktrace: [ { file: 'https://invalid-domain.com/rsa.min.js', }, ], - updateMetaData(key, value) { - this.metadata[key] = value; + updateMetaData(key: string, value: any) { + // @ts-expect-error ignore for testing + this.metaData[key] = value; }, errorMessage: 'test error message', - }; + } as unknown as BugsnagLib.Report; enhanceErrorEventMutator(state, event); - expect(event.metadata).toEqual({ + expect(event.metaData).toEqual({ source: { snippetVersion: '3.0.0', }, - state: { - source: { - id: 'dummy-source-id', - }, - lifecycle: { - writeKey: 'dummy-write-key', - }, - context: { - app: { - name: 'test-app', - namespace: 'test-namespace', - version: '1.0.0', - installType: 'npm', - }, - }, - }, + state: DEFAULT_STATE_DATA, }); expect(event.context).toBe('test error message'); @@ -244,40 +342,26 @@ describe('Bugsnag utilities', () => { it('should return the enhanced error event object if the error is for script loads', () => { const event = { - metadata: {}, + metaData: {}, stacktrace: [ { file: 'https://invalid-domain.com/rsa.min.js', }, ], - updateMetaData(key, value) { - this.metadata[key] = value; + updateMetaData(key: string, value: any) { + // @ts-expect-error ignore for testing + this.metaData[key] = value; }, errorMessage: 'error in script loading "https://invalid-domain.com/rsa.min.js"', - }; + } as unknown as BugsnagLib.Report; - enhanceErrorEventMutator(state, event, 'dummyMetadataVal'); + enhanceErrorEventMutator(state, event); - expect(event.metadata).toEqual({ + expect(event.metaData).toEqual({ source: { snippetVersion: '3.0.0', }, - state: { - source: { - id: 'dummy-source-id', - }, - lifecycle: { - writeKey: 'dummy-write-key', - }, - context: { - app: { - name: 'test-app', - namespace: 'test-namespace', - version: '1.0.0', - installType: 'npm', - }, - }, - }, + state: DEFAULT_STATE_DATA, }); expect(event.context).toBe('Script load failures'); @@ -286,16 +370,20 @@ describe('Bugsnag utilities', () => { }); describe('initBugsnagClient', () => { - const origSdkMaxWait = bugsnagConstants.MAX_WAIT_FOR_SDK_LOAD_MS; - const mountBugsnagSDK = () => { (window as any).bugsnag = jest.fn(() => ({ notifier: { version: '6.0.0' } })); }; + beforeEach(() => { + jest.useFakeTimers(); + jest.setSystemTime(0); + }); + afterEach(() => { delete (window as any).bugsnag; - bugsnagConstants.MAX_WAIT_FOR_SDK_LOAD_MS = origSdkMaxWait; - state = undefined; + resetState(); + + jest.useRealTimers(); }); it('should resolve the promise immediately if the bugsnag SDK is already loaded', async () => { @@ -309,14 +397,20 @@ describe('Bugsnag utilities', () => { }); it('should resolve the promise after some time when the bugsnag SDK is loaded', async () => { - setTimeout(() => { - mountBugsnagSDK(); - }, 1000); - const bsClientPromise: Promise = new Promise((resolve, reject) => { initBugsnagClient(state, resolve, reject); }); + state.session.sessionInfo.value = { id: 123 }; + state.autoTrack.pageLifecycle.visitId.value = 'test-visit-id'; + + // Advance time and mount the Bugsnag SDK + jest.advanceTimersByTime(1); + mountBugsnagSDK(); + + // Run all timers to trigger the promise resolution + jest.runAllTimers(); + const bsClient: BugsnagLib.Client = await bsClientPromise; expect(bsClient).toBeDefined(); // returns a mocked Bugsnag client @@ -325,11 +419,11 @@ describe('Bugsnag utilities', () => { expect((window as any).bugsnag).toHaveBeenCalledTimes(2); expect((window as any).bugsnag).toHaveBeenNthCalledWith(2, { apiKey: '__RS_BUGSNAG_API_KEY__', - appVersion: '1.0.0', + appVersion: 'dev-snapshot', metaData: { SDK: { name: 'JS', - installType: 'npm', + installType: 'cdn', }, }, autoCaptureSessions: false, @@ -338,7 +432,7 @@ describe('Bugsnag utilities', () => { maxBreadcrumbs: 40, releaseStage: 'development', user: { - id: 'dummy-source-id', + id: 'dummy-source-id..123..test-visit-id', }, networkBreadcrumbsEnabled: false, beforeSend: expect.any(Function), @@ -347,28 +441,34 @@ describe('Bugsnag utilities', () => { }); it('should return bugsnag client with write key as user id if source id is not available', async () => { + // @ts-expect-error source id is not defined for the test case state.source.value = { id: undefined }; state.lifecycle.writeKey = signal('dummy-write-key'); - - setTimeout(() => { - mountBugsnagSDK(); - }, 1000); + state.session.sessionInfo.value = { id: 123 }; + state.autoTrack.pageLifecycle.visitId.value = 'test-visit-id'; const bsClientPromise: Promise = new Promise((resolve, reject) => { initBugsnagClient(state, resolve, reject); }); + // Advance time and mount the Bugsnag SDK + jest.advanceTimersByTime(1); + mountBugsnagSDK(); + + // Run all timers to trigger the promise resolution + jest.runAllTimers(); + await bsClientPromise; // First call is the version check expect((window as any).bugsnag).toHaveBeenCalledTimes(2); expect((window as any).bugsnag).toHaveBeenNthCalledWith(2, { apiKey: '__RS_BUGSNAG_API_KEY__', - appVersion: '1.0.0', + appVersion: 'dev-snapshot', metaData: { SDK: { name: 'JS', - installType: 'npm', + installType: 'cdn', }, }, autoCaptureSessions: false, @@ -377,7 +477,7 @@ describe('Bugsnag utilities', () => { maxBreadcrumbs: 40, releaseStage: 'development', user: { - id: 'dummy-write-key', + id: 'dummy-write-key..123..test-visit-id', }, networkBreadcrumbsEnabled: false, beforeSend: expect.any(Function), @@ -386,19 +486,24 @@ describe('Bugsnag utilities', () => { }); it('should reject the promise if the Bugsnag SDK is not loaded', async () => { - bugsnagConstants.MAX_WAIT_FOR_SDK_LOAD_MS = 1000; - const bsClientPromise = new Promise((resolve, reject) => { initBugsnagClient(state, resolve, reject); }); + // Advance time to trigger timeout + jest.advanceTimersByTime(10000); // 10 seconds + await expect(bsClientPromise).rejects.toThrow( - 'A timeout 1000 ms occurred while trying to load the Bugsnag SDK.', + 'A timeout 10000 ms occurred while trying to load the Bugsnag SDK.', ); }); }); describe('loadBugsnagSDK', () => { + let insertBeforeSpy: any; + + const extSrcLoader = new ExternalSrcLoader(defaultErrorHandler, defaultLogger); + beforeAll(() => { server.listen(); }); @@ -406,17 +511,12 @@ describe('Bugsnag utilities', () => { afterAll(() => { server.close(); }); - let insertBeforeSpy: any; - - const mockLogger = new MockLogger(); - const mockErrorHandler = new MockErrorHandler(); - const extSrcLoader = new ExternalSrcLoader(mockErrorHandler, mockLogger); - - const origBugsnagUrl = bugsnagConstants.BUGSNAG_CDN_URL; - const origExtSrcLoadTimeout = timeouts.DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS; beforeEach(() => { insertBeforeSpy = jest.spyOn(document.head, 'insertBefore'); + + jest.useFakeTimers(); + jest.setSystemTime(0); }); afterEach(() => { @@ -426,14 +526,14 @@ describe('Bugsnag utilities', () => { } delete (window as any).Bugsnag; delete (window as any).bugsnag; - bugsnagConstants.BUGSNAG_CDN_URL = origBugsnagUrl; - timeouts.DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS = origExtSrcLoadTimeout; + + jest.useRealTimers(); }); it('should not load Bugsnag SDK if it (<=v6) is already loaded', () => { (window as any).bugsnag = jest.fn(() => ({ notifier: { version: '6.0.0' } })); - loadBugsnagSDK(); + loadBugsnagSDK(extSrcLoader, defaultLogger); expect(insertBeforeSpy).not.toHaveBeenCalled(); }); @@ -441,37 +541,36 @@ describe('Bugsnag utilities', () => { it('should not load Bugsnag SDK if it (>v6) is already loaded', () => { (window as any).Bugsnag = { _client: { _notifier: { version: '7.0.0' } } }; - loadBugsnagSDK(); + loadBugsnagSDK(extSrcLoader, defaultLogger); expect(insertBeforeSpy).not.toHaveBeenCalled(); }); - it('should attempt to load Bugsnag SDK if not already loaded', done => { - loadBugsnagSDK(extSrcLoader, undefined); + it('should attempt to load Bugsnag SDK if not already loaded', () => { + loadBugsnagSDK(extSrcLoader); - setTimeout(() => { - expect(insertBeforeSpy).toHaveBeenCalled(); - done(); - }, 500); + // Run all timers to trigger the script load + jest.runAllTimers(); + + expect(insertBeforeSpy).toHaveBeenCalled(); }); it('should invoke error handler and log error if Bugsnag SDK could not be loaded', done => { - timeouts.DEFAULT_EXT_SRC_LOAD_TIMEOUT_MS = 1000; // 1 second - bugsnagConstants.BUGSNAG_CDN_URL = 'https://asdf.com/bugsnag.min.js'; - loadBugsnagSDK(extSrcLoader, mockLogger); + loadBugsnagSDK(extSrcLoader, defaultLogger); - setTimeout(() => { - expect(mockErrorHandler.onError).toHaveBeenCalledWith( + // Advance the timer to trigger the script load and result in error + jest.advanceTimersByTimeAsync(1).then(() => { + expect(defaultErrorHandler.onError).toHaveBeenCalledWith( new Error( - `Failed to load the script with the id "rs-bugsnag" from URL "https://asdf.com/bugsnag.min.js".`, + `Failed to load the script with the id "rs-bugsnag" from URL "__RS_BUGSNAG_SDK_URL__".`, ), 'ExternalSrcLoader', ); - expect(mockLogger.error).toHaveBeenCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( `BugsnagPlugin:: Failed to load the Bugsnag SDK.`, ); done(); - }, 2000); + }); }); }); @@ -487,7 +586,7 @@ describe('Bugsnag utilities', () => { file: 'https://invalid-domain.com/not-rsa.min.js', }, ], - }; + } as unknown as BugsnagLib.Report; const onErrorFn = onError(state); @@ -512,22 +611,7 @@ describe('Bugsnag utilities', () => { expect(error.updateMetaData).toHaveBeenNthCalledWith(1, 'source', { snippetVersion: '3.0.0', }); - expect(error.updateMetaData).toHaveBeenNthCalledWith(2, 'state', { - source: { - id: 'dummy-source-id', - }, - lifecycle: { - writeKey: 'dummy-write-key', - }, - context: { - app: { - name: 'test-app', - namespace: 'test-namespace', - version: '1.0.0', - installType: 'npm', - }, - }, - }); + expect(error.updateMetaData).toHaveBeenNthCalledWith(2, 'state', DEFAULT_STATE_DATA); expect(error.severity).toBe('error'); expect(error.context).toBe('Script load failures'); }); @@ -549,8 +633,6 @@ describe('Bugsnag utilities', () => { }); it('should log error and return false if the error could not be filtered', () => { - const mockLogger = new MockLogger(); - const error = { stacktrace: [ { @@ -565,10 +647,12 @@ describe('Bugsnag utilities', () => { }), } as any; - const onErrorFn = onError(state, mockLogger); + const onErrorFn = onError(state, defaultLogger); expect(onErrorFn(error)).toBe(false); - expect(mockLogger.error).toHaveBeenCalledWith('BugsnagPlugin:: Failed to filter the error.'); + expect(defaultLogger.error).toHaveBeenCalledWith( + 'BugsnagPlugin:: Failed to filter the error.', + ); }); }); @@ -576,12 +660,15 @@ describe('Bugsnag utilities', () => { const origAppStateExcludes = bugsnagConstants.APP_STATE_EXCLUDE_KEYS; beforeEach(() => { - bugsnagConstants.APP_STATE_EXCLUDE_KEYS = origAppStateExcludes; + Object.defineProperty(bugsnagConstants, 'APP_STATE_EXCLUDE_KEYS', { + value: origAppStateExcludes, + writable: true, + }); }); // Here we are just exploring different combinations of data where // the signals could be buried inside objects, arrays, nested objects, etc. - const tcData = [ + const tcData: any[][] = [ [ { name: 'test', @@ -697,6 +784,9 @@ describe('Bugsnag utilities', () => { ], [ { + // We're intentionally adding BigInt values + // here to test if they are converted to strings + // eslint-disable-next-line compat/compat someKey: BigInt(123), }, undefined, @@ -705,7 +795,11 @@ describe('Bugsnag utilities', () => { ]; it.each(tcData)('should convert signals to JSON %#', (input, expected, excludes) => { - bugsnagConstants.APP_STATE_EXCLUDE_KEYS = excludes; + Object.defineProperty(bugsnagConstants, 'APP_STATE_EXCLUDE_KEYS', { + value: excludes, + writable: true, + }); + expect(getAppStateForMetadata(input)).toEqual(expected); }); }); diff --git a/packages/analytics-js-plugins/__tests__/customConsentManager/index.test.ts b/packages/analytics-js-plugins/__tests__/customConsentManager/index.test.ts index 340e9b2d81..8856df7154 100644 --- a/packages/analytics-js-plugins/__tests__/customConsentManager/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/customConsentManager/index.test.ts @@ -1,4 +1,7 @@ -import { state, resetState } from '@rudderstack/analytics-js/state'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import { defaultErrorHandler } from '@rudderstack/analytics-js-common/__mocks__/ErrorHandler'; +import { resetState, state } from '../../__mocks__/state'; import { CustomConsentManager } from '../../src/customConsentManager'; describe('Plugin - CustomConsentManager', () => { @@ -6,33 +9,25 @@ describe('Plugin - CustomConsentManager', () => { resetState(); }); - const mockLogger = { - error: jest.fn(), - warn: jest.fn(), - log: jest.fn(), - }; - - const mockErrorHandler = { - onError: jest.fn(), - }; - it('should add CustomConsentManager plugin in the loaded plugin list', () => { - CustomConsentManager().initialize(state); + CustomConsentManager().initialize?.(state); expect(state.plugins.loadedPlugins.value.includes('CustomConsentManager')).toBe(true); }); it('ensure default extension points are defined', () => { - expect(CustomConsentManager().consentManager.init()).toBeUndefined(); - expect(CustomConsentManager().consentManager.updateConsentsInfo()).toBeUndefined(); + expect((CustomConsentManager().consentManager as ExtensionPoint)?.init?.()).toBeUndefined(); + expect( + (CustomConsentManager().consentManager as ExtensionPoint)?.updateConsentsInfo?.(), + ).toBeUndefined(); }); it('should return true if the consent manager is not initialized', () => { expect( - CustomConsentManager().consentManager.isDestinationConsented( + (CustomConsentManager().consentManager as ExtensionPoint)?.isDestinationConsented?.( state, undefined, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -42,11 +37,11 @@ describe('Plugin - CustomConsentManager', () => { state.consents.provider.value = 'custom'; const destConfig = {}; expect( - CustomConsentManager().consentManager.isDestinationConsented( + (CustomConsentManager().consentManager as ExtensionPoint)?.isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -75,11 +70,11 @@ describe('Plugin - CustomConsentManager', () => { }; expect( - CustomConsentManager().consentManager.isDestinationConsented( + (CustomConsentManager().consentManager as ExtensionPoint)?.isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -93,11 +88,11 @@ describe('Plugin - CustomConsentManager', () => { }; expect( - CustomConsentManager().consentManager.isDestinationConsented( + (CustomConsentManager().consentManager as ExtensionPoint)?.isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -111,11 +106,11 @@ describe('Plugin - CustomConsentManager', () => { }; expect( - CustomConsentManager().consentManager.isDestinationConsented( + (CustomConsentManager().consentManager as ExtensionPoint)?.isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -145,11 +140,11 @@ describe('Plugin - CustomConsentManager', () => { }; expect( - CustomConsentManager().consentManager.isDestinationConsented( + (CustomConsentManager().consentManager as ExtensionPoint)?.isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -179,11 +174,11 @@ describe('Plugin - CustomConsentManager', () => { }; expect( - CustomConsentManager().consentManager.isDestinationConsented( + (CustomConsentManager().consentManager as ExtensionPoint)?.isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -213,11 +208,11 @@ describe('Plugin - CustomConsentManager', () => { }; expect( - CustomConsentManager().consentManager.isDestinationConsented( + (CustomConsentManager().consentManager as ExtensionPoint)?.isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(false); }); @@ -226,7 +221,8 @@ describe('Plugin - CustomConsentManager', () => { state.consents.initialized.value = true; state.consents.provider.value = 'custom'; state.consents.data.value = { - allowedConsentIds: null, // This will throw an exception + // @ts-expect-error Intentionally setting to null to throw an exception + allowedConsentIds: null, }; const destConfig = { @@ -247,15 +243,15 @@ describe('Plugin - CustomConsentManager', () => { }; expect( - CustomConsentManager().consentManager.isDestinationConsented( + (CustomConsentManager().consentManager as ExtensionPoint)?.isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); - expect(mockErrorHandler.onError).toBeCalledWith( + expect(defaultErrorHandler.onError).toHaveBeenCalledWith( new TypeError("Cannot read properties of null (reading 'includes')"), 'CustomConsentManagerPlugin', 'Failed to determine the consent status for the destination. Please check the destination configuration and try again.', diff --git a/packages/analytics-js-plugins/__tests__/deviceModeDestinations/utils.test.ts b/packages/analytics-js-plugins/__tests__/deviceModeDestinations/utils.test.ts index 0e2c0a9315..1b356a10d4 100644 --- a/packages/analytics-js-plugins/__tests__/deviceModeDestinations/utils.test.ts +++ b/packages/analytics-js-plugins/__tests__/deviceModeDestinations/utils.test.ts @@ -1,5 +1,5 @@ +/* eslint-disable class-methods-use-this */ // eslint-disable-next-line max-classes-per-file -import { signal } from '@preact/signals-core'; import type { Destination } from '@rudderstack/analytics-js-common/types/Destination'; import { wait, @@ -7,15 +7,31 @@ import { createDestinationInstance, isDestinationSDKMounted, } from '../../src/deviceModeDestinations/utils'; -import * as dmdConstants from '../../src/deviceModeDestinations/constants'; +import type { DeviceModeDestinationsAnalyticsInstance } from '../../src/deviceModeDestinations/types'; +import type { LogLevel } from '../../src/types/plugins'; +import { resetState, state } from '../../__mocks__/state'; describe('deviceModeDestinations utils', () => { describe('wait', () => { + beforeEach(() => { + jest.useFakeTimers(); + jest.setSystemTime(0); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + it('should return a promise that resolves after the specified time', async () => { const time = 1000; const startTime = Date.now(); - await wait(time); + const waitPromise = wait(time); + + // Advance the timers by the specified time + jest.runAllTimers(); + + await waitPromise; const endTime = Date.now(); @@ -26,7 +42,12 @@ describe('deviceModeDestinations utils', () => { const time = 0; const startTime = Date.now(); - await wait(time); + const waitPromise = wait(time); + + // Advance the timers by the specified time + jest.runAllTimers(); + + await waitPromise; const endTime = Date.now(); @@ -37,7 +58,12 @@ describe('deviceModeDestinations utils', () => { const time = -1000; const startTime = Date.now(); - await wait(time); + const waitPromise = wait(time); + + // Advance the timers by the next tick + jest.runAllTimers(); + + await waitPromise; const endTime = Date.now(); @@ -48,7 +74,13 @@ describe('deviceModeDestinations utils', () => { const time = '2 seconds'; const startTime = Date.now(); - await wait(time); + // @ts-expect-error intentionally passing a string + const waitPromise = wait(time); + + // Advance the timers by the next tick + jest.runAllTimers(); + + await waitPromise; const endTime = Date.now(); @@ -57,40 +89,44 @@ describe('deviceModeDestinations utils', () => { }); describe('isDestinationReady', () => { - const originalInitializedCheckTimeout = dmdConstants.READY_CHECK_TIMEOUT_MS; - const originalInitializedPollInterval = dmdConstants.LOAD_CHECK_POLL_INTERVAL; + let isLoadedResponse = false; const destination = { instance: { - isLoaded: () => false, + isLoaded: () => isLoadedResponse, }, userFriendlyId: 'GA4___1234567890', }; beforeEach(() => { - // temporarily manipulate the timeout and interval constants to speed up the test - dmdConstants.READY_CHECK_TIMEOUT_MS = 200; - dmdConstants.LOAD_CHECK_POLL_INTERVAL = 100; + jest.useFakeTimers(); + jest.setSystemTime(0); }); afterEach(() => { - dmdConstants.READY_CHECK_TIMEOUT_MS = originalInitializedCheckTimeout; - dmdConstants.LOAD_CHECK_POLL_INTERVAL = originalInitializedPollInterval; - destination.instance.isLoaded = () => false; + jest.useRealTimers(); + isLoadedResponse = false; }); it('should return a promise that gets resolved when the destination is ready immediately', async () => { - destination.instance.isLoaded = () => true; + isLoadedResponse = true; const isReadyPromise = isDestinationReady(destination as Destination); + + // Fast-forward the timers + jest.runAllTimers(); + await expect(isReadyPromise).resolves.toEqual(true); }); it('should return a promise that gets resolved when the destination is ready after some time', async () => { - const isReadyPromise = isDestinationReady(destination as Destination); + setTimeout(() => { + isLoadedResponse = true; + }, 1000); - await wait(100); + const isReadyPromise = isDestinationReady(destination as Destination); - destination.instance.isLoaded = () => true; + // Fast-forward the timers + jest.advanceTimersByTime(1000); await expect(isReadyPromise).resolves.toEqual(true); }); @@ -98,16 +134,19 @@ describe('deviceModeDestinations utils', () => { it('should return a promise that gets rejected when the destination is not ready after the timeout', async () => { const isReadyPromise = isDestinationReady(destination as Destination); + // Fast-forward the timers to cause a timeout + jest.advanceTimersByTime(11000); + await expect(isReadyPromise).rejects.toThrow( new Error( - `A timeout of 200 ms occurred while trying to check the ready status for "${destination.userFriendlyId}" destination.`, + `A timeout of 11000 ms occurred while trying to check the ready status for "${destination.userFriendlyId}" destination.`, ), ); }); }); describe('createDestinationInstance', () => { - class mockAnalytics { + class MockAnalytics implements DeviceModeDestinationsAnalyticsInstance { page = () => {}; track = () => {}; identify = () => {}; @@ -118,24 +157,27 @@ describe('deviceModeDestinations utils', () => { getUserTraits = () => ({ trait1: 'value1' }); getGroupId = () => 'groupId'; getGroupTraits = () => ({ trait2: 'value2' }); - getSessionId = () => 'sessionId'; + getSessionId = () => 123; + loadIntegration = true; + logLevel = 'DEBUG' as LogLevel; + loadOnlyIntegrations = { All: true }; } // create two mock instances to later choose based on the write key - const mockAnalyticsInstance_writeKey1 = new mockAnalytics(); - const mockAnalyticsInstance_writeKey2 = new mockAnalytics(); - - class mockRudderAnalytics { - getAnalyticsInstance = writeKey => { - const instancesMap = { - '1234567890': mockAnalyticsInstance_writeKey1, - '12345678910': mockAnalyticsInstance_writeKey2, + const mockAnalyticsInstanceWriteKey1 = new MockAnalytics(); + const mockAnalyticsInstanceWriteKey2 = new MockAnalytics(); + + class MockRudderAnalytics { + getAnalyticsInstance = (writeKey: string) => { + const instancesMap: Record = { + '1234567890': mockAnalyticsInstanceWriteKey1, + '12345678910': mockAnalyticsInstanceWriteKey2, }; return instancesMap[writeKey]; }; } - const mockRudderAnalyticsInstance = new mockRudderAnalytics(); + const mockRudderAnalyticsInstance = new MockRudderAnalytics(); // put destination SDK code on the window object const destSDKIdentifier = 'GA4_RS'; @@ -148,7 +190,7 @@ describe('deviceModeDestinations utils', () => { [sdkTypeName]: class { config: any; analytics: any; - constructor(config, analytics) { + constructor(config: any, analytics: any) { this.config = config; this.analytics = analytics; } @@ -162,19 +204,7 @@ describe('deviceModeDestinations utils', () => { }); it('should return an instance of the destination', () => { - const state = { - nativeDestinations: { - loadIntegration: signal(true), - loadOnlyIntegrations: signal({ All: true }), - }, - lifecycle: { - logLevel: signal('DEBUG'), - writeKey: signal('12345678910'), // mockAnalyticsInstance_writeKey2 - }, - consents: { - postConsent: signal({}), - }, - }; + state.lifecycle.writeKey.value = '12345678910'; // write key 2 const destination = { config: { @@ -182,7 +212,7 @@ describe('deviceModeDestinations utils', () => { }, areTransformationsConnected: false, id: 'GA4___5678', - }; + } as unknown as Destination; const destinationInstance = createDestinationInstance( destSDKIdentifier, @@ -195,8 +225,8 @@ describe('deviceModeDestinations utils', () => { expect(destinationInstance.config).toEqual(destination.config); expect(destinationInstance.analytics).toEqual({ loadIntegration: true, - loadOnlyIntegrations: { All: true }, - logLevel: 'DEBUG', + loadOnlyIntegrations: {}, + logLevel: 'ERROR', alias: expect.any(Function), group: expect.any(Function), identify: expect.any(Function), @@ -215,13 +245,15 @@ describe('deviceModeDestinations utils', () => { expect(destinationInstance.analytics.getUserTraits()).toEqual({ trait1: 'value1' }); expect(destinationInstance.analytics.getGroupId()).toEqual('groupId'); expect(destinationInstance.analytics.getGroupTraits()).toEqual({ trait2: 'value2' }); - expect(destinationInstance.analytics.getSessionId()).toEqual('sessionId'); + expect(destinationInstance.analytics.getSessionId()).toEqual(123); // Making sure that the call gets forwarded to the correct instance - const pageCallSpy = jest.spyOn(mockAnalyticsInstance_writeKey2, 'page'); + const pageCallSpy = jest.spyOn(mockAnalyticsInstanceWriteKey2, 'page'); destinationInstance.analytics.page(); - expect(mockAnalyticsInstance_writeKey2.page).toHaveBeenCalled(); + expect(mockAnalyticsInstanceWriteKey2.page).toHaveBeenCalled(); pageCallSpy.mockRestore(); + + resetState(); }); }); @@ -235,21 +267,6 @@ describe('deviceModeDestinations utils', () => { delete (window as any)[destSDKIdentifier]; }); - class MockLogger implements ILogger { - warn = jest.fn(); - log = jest.fn(); - error = jest.fn(); - info = jest.fn(); - debug = jest.fn(); - minLogLevel = 0; - scope = 'test scope'; - setMinLogLevel = jest.fn(); - setScope = jest.fn(); - logProvider = console; - } - - const mockLogger = new MockLogger(); - it('should return false if the destination SDK is not evaluated', () => { expect(isDestinationSDKMounted(destSDKIdentifier, sdkTypeName)).toEqual(false); }); @@ -265,6 +282,7 @@ describe('deviceModeDestinations utils', () => { it('should return true if the destination SDK is a constructable type', () => { (window as any)[destSDKIdentifier] = { [sdkTypeName]: class { + // eslint-disable-next-line @typescript-eslint/no-useless-constructor, sonarjs/no-useless-constructor, sonarjs/no-empty-function, @typescript-eslint/no-empty-function constructor() {} }, }; diff --git a/packages/analytics-js-plugins/__tests__/deviceModeTransformation/.gitkeep b/packages/analytics-js-plugins/__tests__/deviceModeTransformation/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts b/packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts index 544957d15f..80b8c43a21 100644 --- a/packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts @@ -1,14 +1,12 @@ /* eslint-disable no-plusplus */ import { batch } from '@preact/signals-core'; -import { HttpClient } from '@rudderstack/analytics-js/services/HttpClient'; -import { state } from '@rudderstack/analytics-js/state'; -import { PluginsManager } from '@rudderstack/analytics-js/components/pluginsManager'; -import { defaultPluginEngine } from '@rudderstack/analytics-js/services/PluginEngine'; -import { defaultErrorHandler } from '@rudderstack/analytics-js/services/ErrorHandler'; -import { defaultLogger } from '@rudderstack/analytics-js/services/Logger'; -import { StoreManager } from '@rudderstack/analytics-js/services/StoreManager'; import type { RudderEvent } from '@rudderstack/analytics-js-common/types/Event'; -import type { IHttpClient } from '@rudderstack/analytics-js-common/types/HttpClient'; +import { defaultErrorHandler } from '@rudderstack/analytics-js-common/__mocks__/ErrorHandler'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import { defaultStoreManager } from '@rudderstack/analytics-js-common/__mocks__/StoreManager'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; +import * as utils from '../../src/deviceModeTransformation/utilities'; +import { DeviceModeTransformation } from '../../src/deviceModeTransformation'; import { dummyDataplaneHost, dummyWriteKey, @@ -16,8 +14,11 @@ import { dmtSuccessResponse, } from '../../__fixtures__/fixtures'; import { server } from '../../__fixtures__/msw.server'; -import * as utils from '@rudderstack/analytics-js-plugins/deviceModeTransformation/utilities'; -import { DeviceModeTransformation } from '@rudderstack/analytics-js-plugins/deviceModeTransformation'; +import { resetState, state } from '../../__mocks__/state'; +import { defaultHttpClient } from '../../__mocks__/HttpClient'; +import { defaultPluginsManager } from '../../__mocks__/PluginsManager'; +import type { RetryQueue } from '../../src/utilities/retryQueue/RetryQueue'; +import type { QueueItem, QueueItemData } from '../../src/types/plugins'; jest.mock('@rudderstack/analytics-js-common/utilities/uuId', () => ({ ...jest.requireActual('@rudderstack/analytics-js-common/utilities/uuId'), @@ -25,16 +26,9 @@ jest.mock('@rudderstack/analytics-js-common/utilities/uuId', () => ({ })); describe('Device mode transformation plugin', () => { - const defaultPluginsManager = new PluginsManager( - defaultPluginEngine, - defaultErrorHandler, - defaultLogger, - ); - - const defaultStoreManager = new StoreManager(defaultPluginsManager); - beforeAll(() => { server.listen(); + resetState(); batch(() => { state.lifecycle.writeKey.value = dummyWriteKey; state.lifecycle.activeDataplaneUrl.value = dummyDataplaneHost; @@ -42,8 +36,6 @@ describe('Device mode transformation plugin', () => { }); }); - const httpClient = new HttpClient(); - afterAll(() => { server.close(); }); @@ -82,32 +74,32 @@ describe('Device mode transformation plugin', () => { }); it('should return a queue object on init', () => { - const queue = DeviceModeTransformation().transformEvent?.init( + const queue = (DeviceModeTransformation()?.transformEvent as ExtensionPoint)?.init?.( state, defaultPluginsManager, - httpClient, + defaultHttpClient, defaultStoreManager, defaultErrorHandler, defaultLogger, - ); + ) as RetryQueue; expect(queue).toBeDefined(); expect(queue.name).toBe('rudder_dummy-write-key'); }); it('should add item in queue on enqueue', () => { - const queue = DeviceModeTransformation().transformEvent?.init( + const queue = (DeviceModeTransformation()?.transformEvent as ExtensionPoint)?.init?.( state, defaultPluginsManager, - httpClient, + defaultHttpClient, defaultStoreManager, defaultErrorHandler, defaultLogger, - ); + ) as RetryQueue; const addItemSpy = jest.spyOn(queue, 'addItem'); - const event: RudderEvent = { + const event = { type: 'track', event: 'test', userId: 'test', @@ -117,11 +109,16 @@ describe('Device mode transformation plugin', () => { anonymousId: 'sampleAnonId', messageId: 'test', originalTimestamp: 'test', - }; + } as unknown as RudderEvent; - DeviceModeTransformation().transformEvent?.enqueue(state, queue, event, destinations); + (DeviceModeTransformation()?.transformEvent as ExtensionPoint)?.enqueue?.( + state, + queue, + event, + destinations, + ); - expect(addItemSpy).toBeCalledWith({ + expect(addItemSpy).toHaveBeenCalledWith({ token: authToken, destinationIds, event, @@ -131,20 +128,19 @@ describe('Device mode transformation plugin', () => { }); it('should process queue item on start', () => { - const mockHttpClient = { - getAsyncData: ({ callback }) => { - callback(true); - }, - setAuthHeader: jest.fn(), - }; - const queue = DeviceModeTransformation().transformEvent?.init( + // Mock the implementation of getAsyncData to return a successful response + defaultHttpClient.getAsyncData.mockImplementation(({ callback }) => { + callback(true); + }); + + const queue = (DeviceModeTransformation()?.transformEvent as ExtensionPoint)?.init?.( state, defaultPluginsManager, - mockHttpClient, + defaultHttpClient, defaultStoreManager, - ); + ) as RetryQueue; - const event: RudderEvent = { + const event = { type: 'track', event: 'test', userId: 'test', @@ -154,17 +150,22 @@ describe('Device mode transformation plugin', () => { anonymousId: 'sampleAnonId', messageId: 'test', originalTimestamp: 'test', - }; + } as unknown as RudderEvent; const queueProcessCbSpy = jest.spyOn(queue, 'processQueueCb'); - DeviceModeTransformation().transformEvent?.enqueue(state, queue, event, destinations); + (DeviceModeTransformation()?.transformEvent as ExtensionPoint)?.enqueue?.( + state, + queue, + event, + destinations, + ); // Explicitly start the queue to process the item // In actual implementation, this is done based on the state signals queue.start(); - expect(queueProcessCbSpy).toBeCalledWith( + expect(queueProcessCbSpy).toHaveBeenCalledWith( { token: authToken, destinationIds, @@ -177,33 +178,33 @@ describe('Device mode transformation plugin', () => { ); // Item is successfully processed and removed from queue - expect(queue.getStorageEntry('queue').length).toBe(0); + expect((queue.getStorageEntry('queue') as QueueItem[]).length).toBe(0); queueProcessCbSpy.mockRestore(); + defaultHttpClient.getAsyncData.mockRestore(); }); - it('SendTransformedEventToDestinations function is called in case of successful transformation', () => { - const mockHttpClient: IHttpClient = { - getAsyncData: ({ callback }) => { - callback?.(JSON.stringify(dmtSuccessResponse), { xhr: { status: 200 } }); - }, - setAuthHeader: jest.fn(), - }; + it('should process transformed events in case of successful transformation', () => { + // Mock the implementation of getAsyncData to return a successful response + defaultHttpClient.getAsyncData.mockImplementation(({ callback }) => { + callback(JSON.stringify(dmtSuccessResponse), { xhr: { status: 200 } }); + }); + const mockSendTransformedEventToDestinations = jest.spyOn( utils, 'sendTransformedEventToDestinations', ); - const queue = DeviceModeTransformation().transformEvent?.init( + const queue = (DeviceModeTransformation()?.transformEvent as ExtensionPoint)?.init?.( state, defaultPluginsManager, - mockHttpClient, + defaultHttpClient, defaultStoreManager, defaultErrorHandler, defaultLogger, - ); + ) as RetryQueue; - const event: RudderEvent = { + const event = { type: 'track', event: 'test', userId: 'test', @@ -213,12 +214,17 @@ describe('Device mode transformation plugin', () => { anonymousId: 'sampleAnonId', messageId: 'test', originalTimestamp: 'test', - }; + } as unknown as RudderEvent; queue.start(); - DeviceModeTransformation().transformEvent?.enqueue(state, queue, event, destinations); + (DeviceModeTransformation()?.transformEvent as ExtensionPoint)?.enqueue?.( + state, + queue, + event, + destinations, + ); - expect(mockSendTransformedEventToDestinations).toBeCalledTimes(1); + expect(mockSendTransformedEventToDestinations).toHaveBeenCalledTimes(1); expect(mockSendTransformedEventToDestinations).toHaveBeenCalledWith( state, defaultPluginsManager, @@ -229,30 +235,31 @@ describe('Device mode transformation plugin', () => { defaultErrorHandler, defaultLogger, ); + mockSendTransformedEventToDestinations.mockRestore(); + defaultHttpClient.getAsyncData.mockRestore(); }); - it('SendTransformedEventToDestinations function should not be called in case of unsuccessful transformation', () => { - const mockHttpClient: IHttpClient = { - getAsyncData: ({ callback }) => { - callback?.(false, { error: 'some error', xhr: { status: 502 } }); - }, - setAuthHeader: jest.fn(), - }; + it('should not process transformed events in case of unsuccessful transformation', () => { + // Mock the implementation of getAsyncData to return a retryable error response + defaultHttpClient.getAsyncData.mockImplementation(({ callback }) => { + callback(false, { error: 'some error', xhr: { status: 502 } }); + }); + const mockSendTransformedEventToDestinations = jest.spyOn( utils, 'sendTransformedEventToDestinations', ); - const queue = DeviceModeTransformation().transformEvent?.init( + const queue = (DeviceModeTransformation()?.transformEvent as ExtensionPoint)?.init?.( state, defaultPluginsManager, - mockHttpClient, + defaultHttpClient, defaultStoreManager, defaultErrorHandler, defaultLogger, - ); + ) as RetryQueue; - const event: RudderEvent = { + const event = { type: 'track', event: 'test', userId: 'test', @@ -262,12 +269,17 @@ describe('Device mode transformation plugin', () => { anonymousId: 'sampleAnonId', messageId: 'test', originalTimestamp: 'test', - }; + } as unknown as RudderEvent; queue.start(); - DeviceModeTransformation().transformEvent?.enqueue(state, queue, event, destinations); + (DeviceModeTransformation()?.transformEvent as ExtensionPoint)?.enqueue?.( + state, + queue, + event, + destinations, + ); - expect(mockSendTransformedEventToDestinations).not.toBeCalled(); + expect(mockSendTransformedEventToDestinations).not.toHaveBeenCalled(); // The element is requeued expect(queue.getStorageEntry('queue')).toStrictEqual([ { diff --git a/packages/analytics-js-plugins/__tests__/errorReporting/index.test.ts b/packages/analytics-js-plugins/__tests__/errorReporting/index.test.ts index f1cab14dca..f0bed5e533 100644 --- a/packages/analytics-js-plugins/__tests__/errorReporting/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/errorReporting/index.test.ts @@ -1,6 +1,8 @@ import { signal } from '@preact/signals-core'; import { clone } from 'ramda'; import type { IHttpClient } from '@rudderstack/analytics-js-common/types/HttpClient'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; import { ErrorReporting } from '../../src/errorReporting'; describe('Plugin - ErrorReporting', () => { @@ -24,6 +26,14 @@ describe('Plugin - ErrorReporting', () => { id: 'test-source-id', config: {}, }), + session: { + sessionInfo: signal({ id: 'test-session-id' }), + }, + autoTrack: { + pageLifecycle: { + visitId: signal('test-visit-id'), + }, + }, }; let state: any; @@ -35,9 +45,6 @@ describe('Plugin - ErrorReporting', () => { const mockExtSrcLoader = { loadJSFile: jest.fn(() => Promise.resolve()), }; - const mockLogger = { - error: jest.fn(), - }; const mockErrReportingProviderClient = { notify: jest.fn(), leaveBreadcrumb: jest.fn(), @@ -49,47 +56,58 @@ describe('Plugin - ErrorReporting', () => { }); it('should add ErrorReporting plugin in the loaded plugin list', () => { - ErrorReporting().initialize(state); + ErrorReporting()?.initialize?.(state); expect(state.plugins.loadedPlugins.value.includes('ErrorReporting')).toBe(true); expect(state.reporting.isErrorReportingPluginLoaded.value).toBe(true); expect(state.reporting.breadcrumbs.value[0].name).toBe('Error Reporting Plugin Loaded'); }); it('should not invoke error reporting provider plugin on init if request is coming from latest core SDK', () => { - ErrorReporting().errorReporting.init({}, mockPluginEngine, mockExtSrcLoader, mockLogger, true); + (ErrorReporting()?.errorReporting as ExtensionPoint)?.init?.( + {}, + mockPluginEngine, + mockExtSrcLoader, + defaultLogger, + true, + ); expect(mockPluginEngine.invokeSingle).not.toHaveBeenCalled(); }); it('should not invoke error reporting provider plugin on init if sourceConfig do not have required parameters', () => { - ErrorReporting().errorReporting.init( + (ErrorReporting()?.errorReporting as ExtensionPoint)?.init?.( state, mockPluginEngine, mockExtSrcLoader, - mockLogger, + defaultLogger, true, ); expect(mockPluginEngine.invokeSingle).not.toHaveBeenCalled(); }); it('should not invoke error reporting provider plugin on init if request is coming from old core SDK', () => { - ErrorReporting().errorReporting.init(state, mockPluginEngine, mockExtSrcLoader, mockLogger); + (ErrorReporting()?.errorReporting as ExtensionPoint)?.init?.( + state, + mockPluginEngine, + mockExtSrcLoader, + defaultLogger, + ); expect(mockPluginEngine.invokeSingle).toHaveBeenCalledTimes(1); expect(mockPluginEngine.invokeSingle).toHaveBeenCalledWith( 'errorReportingProvider.init', state, mockExtSrcLoader, - mockLogger, + defaultLogger, ); }); it('should invoke the error reporting provider plugin on notify if httpClient is not provided', () => { const dummyError = new Error('dummy error'); - ErrorReporting().errorReporting.notify( + (ErrorReporting()?.errorReporting as ExtensionPoint)?.notify?.( mockPluginEngine, mockErrReportingProviderClient, dummyError, state, - mockLogger, + defaultLogger, ); expect(mockPluginEngine.invokeSingle).toHaveBeenCalledTimes(1); expect(mockPluginEngine.invokeSingle).toHaveBeenCalledWith( @@ -97,7 +115,7 @@ describe('Plugin - ErrorReporting', () => { mockErrReportingProviderClient, dummyError, state, - mockLogger, + defaultLogger, ); }); @@ -119,7 +137,7 @@ describe('Plugin - ErrorReporting', () => { value: `The request failed due to timeout at Analytics.page (http://localhost:3001/cdn/modern/iife/rsa.js:1610:3) at RudderAnalytics.page (http://localhost:3001/cdn/modern/iife/rsa.js:1666:84)`, }, }); - ErrorReporting().errorReporting.notify( + (ErrorReporting()?.errorReporting as ExtensionPoint)?.notify?.( {}, undefined, normalizedError, @@ -154,7 +172,7 @@ describe('Plugin - ErrorReporting', () => { value: `ReferenceError: testUndefinedFn is not defined at Analytics.page (http://localhost:3001/cdn/modern/iife/rsa.js:1610:3) at RudderAnalytics.page (http://localhost:3001/cdn/modern/iife/rsa.js:1666:84)`, }, }); - ErrorReporting().errorReporting.notify( + (ErrorReporting()?.errorReporting as ExtensionPoint)?.notify?.( {}, undefined, normalizedError, @@ -183,7 +201,7 @@ describe('Plugin - ErrorReporting', () => { value: `ReferenceError: testUndefinedFn is not defined at Abcd.page (http://localhost:3001/cdn/modern/iife/abc.js:1610:3) at xyz.page (http://localhost:3001/cdn/modern/iife/abc.js:1666:84)`, }, }); - ErrorReporting().errorReporting.notify( + (ErrorReporting()?.errorReporting as ExtensionPoint)?.notify?.( {}, undefined, normalizedError, @@ -202,18 +220,24 @@ describe('Plugin - ErrorReporting', () => { it('should add a new breadcrumb', () => { const breadcrumbLength = state.reporting.breadcrumbs.value.length; - ErrorReporting().errorReporting.breadcrumb({}, undefined, 'dummy breadcrumb', undefined, state); + (ErrorReporting()?.errorReporting as ExtensionPoint)?.breadcrumb?.( + {}, + undefined, + 'dummy breadcrumb', + undefined, + state, + ); expect(state.reporting.breadcrumbs.value.length).toBe(breadcrumbLength + 1); expect(mockPluginEngine.invokeSingle).not.toHaveBeenCalled(); }); it('should invoke the error reporting provider plugin on new breadcrumb if state is not provided', () => { - ErrorReporting().errorReporting.breadcrumb( + (ErrorReporting()?.errorReporting as ExtensionPoint)?.breadcrumb?.( mockPluginEngine, mockErrReportingProviderClient, 'dummy breadcrumb', - mockLogger, + defaultLogger, ); expect(mockPluginEngine.invokeSingle).toHaveBeenCalledTimes(1); @@ -221,7 +245,7 @@ describe('Plugin - ErrorReporting', () => { 'errorReportingProvider.breadcrumb', mockErrReportingProviderClient, 'dummy breadcrumb', - mockLogger, + defaultLogger, ); }); }); diff --git a/packages/analytics-js-plugins/__tests__/errorReporting/utils.test.ts b/packages/analytics-js-plugins/__tests__/errorReporting/utils.test.ts index 1853279900..59c883c6fa 100644 --- a/packages/analytics-js-plugins/__tests__/errorReporting/utils.test.ts +++ b/packages/analytics-js-plugins/__tests__/errorReporting/utils.test.ts @@ -1,5 +1,7 @@ /* eslint-disable max-classes-per-file */ import { signal } from '@preact/signals-core'; +import type { ErrorEventPayload } from '@rudderstack/analytics-js-common/types/Metrics'; +import { mergeDeepRight } from '@rudderstack/analytics-js-common/utilities/object'; import { ErrorFormat } from '../../src/errorReporting/event/event'; import * as errorReportingConstants from '../../src/errorReporting/constants'; import { @@ -14,11 +16,162 @@ import { getConfigForPayloadCreation, isAllowedToBeNotified, } from '../../src/errorReporting/utils'; +import { state } from '../../__mocks__/state'; jest.mock('@rudderstack/analytics-js-common/utilities/uuId', () => ({ generateUUID: jest.fn().mockReturnValue('test_uuid'), })); +const DEFAULT_STATE_DATA = { + autoTrack: { + enabled: false, + pageLifecycle: { + enabled: false, + }, + }, + capabilities: { + isAdBlocked: false, + isBeaconAvailable: false, + isCryptoAvailable: false, + isIE11: false, + isLegacyDOM: false, + isOnline: true, + isUaCHAvailable: false, + storage: { + isCookieStorageAvailable: false, + isLocalStorageAvailable: false, + isSessionStorageAvailable: false, + }, + }, + consents: { + data: {}, + enabled: false, + initialized: false, + postConsent: {}, + preConsent: { + enabled: false, + }, + resolutionStrategy: 'and', + }, + context: { + app: { + installType: 'cdn', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: 'dev-snapshot', + }, + device: null, + library: { + name: 'RudderLabs JavaScript SDK', + version: 'dev-snapshot', + }, + locale: null, + network: null, + os: { + name: '', + version: '', + }, + screen: { + density: 0, + height: 0, + innerHeight: 0, + innerWidth: 0, + width: 0, + }, + userAgent: '', + }, + dataPlaneEvents: { + deliveryEnabled: true, + }, + lifecycle: { + initialized: false, + loaded: false, + logLevel: 'ERROR', + readyCallbacks: [], + }, + loadOptions: { + beaconQueueOptions: {}, + bufferDataPlaneEventsUntilReady: false, + configUrl: 'https://api.rudderstack.com', + dataPlaneEventsBufferTimeout: 1000, + destinationsQueueOptions: {}, + integrations: { + All: true, + }, + loadIntegration: true, + lockIntegrationsVersion: false, + lockPluginsVersion: false, + logLevel: 'ERROR', + plugins: [], + polyfillIfRequired: true, + queueOptions: {}, + sameSiteCookie: 'Lax', + sendAdblockPageOptions: {}, + sessions: { + autoTrack: true, + timeout: 1800000, + }, + storage: { + cookie: {}, + encryption: { + version: 'v3', + }, + migrate: true, + }, + uaChTrackLevel: 'none', + useBeacon: false, + useGlobalIntegrationsConfigInEvents: false, + useServerSideCookies: false, + }, + metrics: { + dropped: 0, + queued: 0, + retries: 0, + sent: 0, + triggered: 0, + }, + nativeDestinations: { + activeDestinations: [], + clientDestinationsReady: false, + configuredDestinations: [], + failedDestinations: [], + initializedDestinations: [], + integrationsConfig: {}, + loadIntegration: true, + loadOnlyIntegrations: {}, + }, + plugins: { + activePlugins: [], + failedPlugins: [], + loadedPlugins: [], + pluginsToLoadFromConfig: [], + ready: false, + totalPluginsToLoad: 0, + }, + reporting: { + breadcrumbs: [], + isErrorReportingEnabled: false, + isErrorReportingPluginLoaded: false, + isMetricsReportingEnabled: false, + }, + serverCookies: { + isEnabledServerSideCookies: false, + }, + session: { + initialReferrer: '', + initialReferringDomain: '', + }, + source: { + id: 'dummy-source-id', + workspaceId: 'dummy-workspace-id', + }, + storage: { + entries: {}, + migrate: false, + trulyAnonymousTracking: false, + }, +}; + describe('Error Reporting utilities', () => { describe('createNewBreadcrumb', () => { it('should create and return a breadcrumb', () => { @@ -84,7 +237,7 @@ describe('Error Reporting utilities', () => { }); describe('isRudderSDKError', () => { - const testCaseData = [ + const testCaseData: any[] = [ ['https://invalid-domain.com/rsa.min.js', true], ['https://invalid-domain.com/rss.min.js', false], ['https://invalid-domain.com/rsa-plugins-Beacon.min.js', true], @@ -103,7 +256,7 @@ describe('Error Reporting utilities', () => { it.each(testCaseData)( 'if script src is "%s" then it should return the value as "%s" ', - (scriptSrc, expectedValue) => { + (scriptSrc: string, expectedValue: boolean) => { // Bugsnag error event object structure const event = { stacktrace: [ @@ -155,13 +308,16 @@ describe('Error Reporting utilities', () => { describe('getAppStateForMetadata', () => { const origAppStateExcludes = errorReportingConstants.APP_STATE_EXCLUDE_KEYS; - beforeEach(() => { - errorReportingConstants.APP_STATE_EXCLUDE_KEYS = origAppStateExcludes; + afterEach(() => { + Object.defineProperty(errorReportingConstants, 'APP_STATE_EXCLUDE_KEYS', { + value: origAppStateExcludes, + writable: true, + }); }); // Here we are just exploring different combinations of data where // the signals could be buried inside objects, arrays, nested objects, etc. - const tcData = [ + const tcData: any[][] = [ [ { name: 'test', @@ -277,6 +433,7 @@ describe('Error Reporting utilities', () => { ], [ { + // eslint-disable-next-line compat/compat someKey: BigInt(123), }, {}, @@ -285,13 +442,20 @@ describe('Error Reporting utilities', () => { ]; it.each(tcData)('should convert signals to JSON %#', (input, expected, excludes) => { - errorReportingConstants.APP_STATE_EXCLUDE_KEYS = excludes; + Object.defineProperty(errorReportingConstants, 'APP_STATE_EXCLUDE_KEYS', { + value: excludes, + writable: true, + }); + expect(getAppStateForMetadata(input)).toEqual(expected); }); }); describe('getBugsnagErrorEvent', () => { it('should return enhanced error event payload', () => { + state.session.sessionInfo.value = { id: 123 }; + state.autoTrack.pageLifecycle.visitId.value = 'test-visit-id'; + const newError = new Error(); const normalizedError = Object.create(newError, { message: { value: 'ReferenceError: testUndefinedFn is not defined' }, @@ -304,29 +468,15 @@ describe('Error Reporting utilities', () => { unhandled: false, severityReason: { type: 'handledException' }, }; - const errorPayload = ErrorFormat.create(normalizedError, 'notify()'); + const errorPayload = ErrorFormat.create(normalizedError, 'notify()') as ErrorFormat; - const appState = { - context: { - locale: signal('en-GB'), - userAgent: signal('sample user agent'), - app: signal({ version: 'sample_version', installType: 'sample_installType' }), - }, - lifecycle: { - writeKey: signal('sample-write-key'), - }, - reporting: { - breadcrumbs: signal([]), - }, - source: signal({ id: 'sample_source_id' }), - }; (window as any).RudderSnippetVersion = 'sample_snippet_version'; - const enhancedError = getBugsnagErrorEvent(errorPayload, errorState, appState); + const enhancedError = getBugsnagErrorEvent(errorPayload, errorState, state); console.log(JSON.stringify(enhancedError)); const expectedOutcome = { notifier: { name: 'RudderStack JavaScript SDK Error Notifier', - version: 'sample_version', + version: 'dev-snapshot', url: 'https://github.com/rudderlabs/rudder-sdk-js', }, events: [ @@ -355,12 +505,11 @@ describe('Error Reporting utilities', () => { type: 'handledException', }, app: { - version: 'sample_version', + version: 'dev-snapshot', releaseStage: 'development', }, device: { - locale: 'en-GB', - userAgent: 'sample user agent', + userAgent: '', time: expect.any(Date), }, request: { @@ -372,33 +521,24 @@ describe('Error Reporting utilities', () => { metaData: { sdk: { name: 'JS', - installType: 'sample_installType', + installType: 'cdn', }, - state: { - context: { - userAgent: 'sample user agent', - locale: 'en-GB', - app: { - version: 'sample_version', - installType: 'sample_installType', + state: mergeDeepRight(DEFAULT_STATE_DATA, { + autoTrack: { + pageLifecycle: { + visitId: 'test-visit-id', }, }, - lifecycle: { - writeKey: 'sample-write-key', - }, - reporting: { - breadcrumbs: [], + session: { + sessionInfo: { id: 123 }, }, - source: { - id: 'sample_source_id', - }, - }, + }), source: { snippetVersion: 'sample_snippet_version', }, }, user: { - id: 'sample_source_id', + id: 'dummy-source-id..123..test-visit-id', }, }, ], @@ -409,14 +549,6 @@ describe('Error Reporting utilities', () => { describe('getErrorDeliveryPayload', () => { it('should return error delivery payload', () => { - const appState = { - lifecycle: { - writeKey: signal('sample-write-key'), - }, - context: { - app: signal({ version: 'sample_version', installType: 'sample_installType' }), - }, - }; const enhancedErrorPayload = { notifier: { name: 'Rudderstack JavaScript SDK Error Notifier', @@ -449,12 +581,11 @@ describe('Error Reporting utilities', () => { type: 'handledException', }, app: { - version: 'sample_version', + version: 'dev-snapshot', releaseStage: 'development', }, device: { - locale: 'en-GB', - userAgent: 'sample user agent', + userAgent: '', time: expect.any(Date), }, request: { @@ -466,18 +597,11 @@ describe('Error Reporting utilities', () => { metaData: { sdk: { name: 'JS', - installType: 'sample_installType', + installType: 'cdn', }, - state: { - context: { - userAgent: 'sample user agent', - locale: 'en-GB', - app: 'sample_version', - }, - lifecycle: { - writeKey: 'sample-write-key', - }, - breadcrumbs: [], + state: DEFAULT_STATE_DATA, + source: { + snippetVersion: 'sample_snippet_version', }, }, user: { @@ -485,18 +609,17 @@ describe('Error Reporting utilities', () => { }, }, ], - }; + } as unknown as ErrorEventPayload; - const deliveryPayload = getErrorDeliveryPayload(enhancedErrorPayload, appState); + const deliveryPayload = getErrorDeliveryPayload(enhancedErrorPayload, state); expect(deliveryPayload).toEqual( JSON.stringify({ version: '1', message_id: 'test_uuid', source: { name: 'js', - sdk_version: 'sample_version', - write_key: 'sample-write-key', - install_type: 'sample_installType', + sdk_version: 'dev-snapshot', + install_type: 'cdn', }, errors: enhancedErrorPayload, }), @@ -515,7 +638,11 @@ describe('Error Reporting utilities', () => { }); it('should return the config for payload creation in case of unhandledPromiseRejection', () => { - const error = new PromiseRejectionEvent('test error'); + // eslint-disable-next-line compat/compat + const error = new PromiseRejectionEvent('test error', { + promise: Promise.resolve(), + reason: 'test error', + }); const config = getConfigForPayloadCreation(error, 'unhandledPromiseRejection'); expect(config).toEqual({ component: 'unhandledrejection handler', diff --git a/packages/analytics-js-plugins/__tests__/iubendaConsentManager/index.test.ts b/packages/analytics-js-plugins/__tests__/iubendaConsentManager/index.test.ts index 536cdf9430..7c90642a0a 100644 --- a/packages/analytics-js-plugins/__tests__/iubendaConsentManager/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/iubendaConsentManager/index.test.ts @@ -1,13 +1,15 @@ -import { state, resetState } from '@rudderstack/analytics-js/state'; -import { defaultPluginEngine } from '@rudderstack/analytics-js/services/PluginEngine'; -import { PluginsManager } from '@rudderstack/analytics-js/components/pluginsManager'; -import { StoreManager } from '@rudderstack/analytics-js/services/StoreManager/StoreManager'; +import { defaultStoreManager } from '@rudderstack/analytics-js-common/__mocks__/StoreManager'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import { defaultErrorHandler } from '@rudderstack/analytics-js-common/__mocks__/ErrorHandler'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; +import { resetState, state } from '../../__mocks__/state'; import { IubendaConsentManager } from '../../src/iubendaConsentManager'; import { IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME } from '../../src/iubendaConsentManager/constants'; describe('Plugin - IubendaConsentManager', () => { beforeEach(() => { resetState(); + // eslint-disable-next-line no-underscore-dangle (window as any)._iub = { cs: { consent: {} } }; (window as any).getIubendaUserConsentedPurposes = undefined; (window as any).getIubendaUserDeniedPurposes = undefined; @@ -19,24 +21,14 @@ describe('Plugin - IubendaConsentManager', () => { }); }); - const mockLogger = { - error: jest.fn(), - warn: jest.fn(), - log: jest.fn(), - }; - - const mockErrorHandler = { - onError: jest.fn(), - }; - it('should add IubendaConsentManager plugin in the loaded plugin list', () => { - IubendaConsentManager().initialize(state); + IubendaConsentManager()?.initialize?.(state); expect(state.plugins.loadedPlugins.value.includes('IubendaConsentManager')).toBe(true); }); it('should initialize the plugin if iubenda consent data is already available on the window object', () => { // Initialize the plugin - IubendaConsentManager().consentManager.init(state, mockLogger); + (IubendaConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); expect((window as any).getIubendaUserConsentedPurposes).toEqual(expect.any(Function)); expect((window as any).getIubendaUserDeniedPurposes).toEqual(expect.any(Function)); @@ -45,27 +37,32 @@ describe('Plugin - IubendaConsentManager', () => { it('should update state with consents data from iubenda window resources', () => { // Mock the iubenda data on the window object + // eslint-disable-next-line no-underscore-dangle (window as any)._iub.cs.consent = { - timestamp: "2024-10-1T01:57:25.825Z", - version: "1.67.1", + timestamp: '2024-10-1T01:57:25.825Z', + version: '1.67.1', purposes: { '1': true, '2': false, '3': false, '4': true, - '5': true + '5': true, }, id: 252372, cons: { - rand: "92f72a" - } + rand: '92f72a', + }, }; // Initialize the plugin - IubendaConsentManager().consentManager.init(state, mockLogger); + (IubendaConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); // Update the state with the consent data - IubendaConsentManager().consentManager.updateConsentsInfo(state, undefined, mockLogger); + (IubendaConsentManager()?.consentManager as ExtensionPoint).updateConsentsInfo?.( + state, + undefined, + defaultLogger, + ); expect(state.consents.initialized.value).toBe(true); expect(state.consents.data.value).toStrictEqual({ @@ -73,17 +70,13 @@ describe('Plugin - IubendaConsentManager', () => { deniedConsentIds: ['2', '3'], }); - expect((window as any).getIubendaUserConsentedPurposes()).toStrictEqual([ - '1', - '4', - '5', - ]); + expect((window as any).getIubendaUserConsentedPurposes()).toStrictEqual(['1', '4', '5']); expect((window as any).getIubendaUserDeniedPurposes()).toStrictEqual(['2', '3']); }); it('should return undefined values when the window callbacks are invoked and there is no data in the state', () => { // Initialize the plugin - IubendaConsentManager().consentManager.init(state, mockLogger); + (IubendaConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); expect((window as any).getIubendaUserConsentedPurposes()).toStrictEqual(undefined); expect((window as any).getIubendaUserDeniedPurposes()).toStrictEqual(undefined); @@ -91,24 +84,25 @@ describe('Plugin - IubendaConsentManager', () => { it('should define a callback function on window to update consent data', () => { // Mock the iubenda data on the window object + // eslint-disable-next-line no-underscore-dangle (window as any)._iub.cs.consent = { - timestamp: "2024-10-1T01:57:25.825Z", - version: "1.67.1", + timestamp: '2024-10-1T01:57:25.825Z', + version: '1.67.1', purposes: { '1': true, '2': false, '3': false, '4': true, - '5': true + '5': true, }, id: 252372, cons: { - rand: "92f72a" - } + rand: '92f72a', + }, }; // Initialize the plugin - IubendaConsentManager().consentManager.init(state, mockLogger); + (IubendaConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); // Call the callback function (window as any).updateIubendaConsent({ @@ -116,7 +110,7 @@ describe('Plugin - IubendaConsentManager', () => { '2': true, '3': false, '4': true, - '5': false + '5': false, }); expect(state.consents.data.value).toStrictEqual({ @@ -130,33 +124,34 @@ describe('Plugin - IubendaConsentManager', () => { it('should get consent data from iubenda cookies if iubenda consent data is not available on the window object', () => { const iubendaRawConsentData = { - timestamp: "2024-10-1T01:57:25.825Z", - version: "1.67.1", + timestamp: '2024-10-1T01:57:25.825Z', + version: '1.67.1', purposes: { '1': true, '2': false, '3': false, '4': true, - '5': true + '5': true, }, id: 252372, cons: { - rand: "92f72a" - } + rand: '92f72a', + }, }; const iubendaConsentString = JSON.stringify(iubendaRawConsentData); // Mock the iubenda cookies document.cookie = `${IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME}=${encodeURIComponent(iubendaConsentString)};`; - const pluginsManager = new PluginsManager(defaultPluginEngine, undefined, mockLogger); - const storeManager = new StoreManager(pluginsManager, undefined, mockLogger); - // Initialize the plugin - IubendaConsentManager().consentManager.init(state, mockLogger); + (IubendaConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); // Update the state with the consent data - IubendaConsentManager().consentManager.updateConsentsInfo(state, storeManager, mockLogger); + (IubendaConsentManager()?.consentManager as ExtensionPoint).updateConsentsInfo?.( + state, + defaultStoreManager, + defaultLogger, + ); expect(state.consents.initialized.value).toBe(true); expect(state.consents.data.value).toStrictEqual({ @@ -164,21 +159,17 @@ describe('Plugin - IubendaConsentManager', () => { deniedConsentIds: ['2', '3'], }); - expect((window as any).getIubendaUserConsentedPurposes()).toStrictEqual([ - '1', - '4', - '5', - ]); + expect((window as any).getIubendaUserConsentedPurposes()).toStrictEqual(['1', '4', '5']); expect((window as any).getIubendaUserDeniedPurposes()).toStrictEqual(['2', '3']); }); it('should return true if the consent manager is not initialized', () => { expect( - IubendaConsentManager().consentManager.isDestinationConsented( + (IubendaConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, undefined, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -197,11 +188,11 @@ describe('Plugin - IubendaConsentManager', () => { }; expect( - IubendaConsentManager().consentManager.isDestinationConsented( + (IubendaConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -218,18 +209,19 @@ describe('Plugin - IubendaConsentManager', () => { blacklistedEvents: [], whitelistedEvents: [], eventFilteringOption: 'disable', - consentManagement: [{ - provider: 'iubenda', - }], - + consentManagement: [ + { + provider: 'iubenda', + }, + ], }; expect( - IubendaConsentManager().consentManager.isDestinationConsented( + (IubendaConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -246,21 +238,21 @@ describe('Plugin - IubendaConsentManager', () => { blacklistedEvents: [], whitelistedEvents: [], eventFilteringOption: 'disable', - consentManagement:[ + consentManagement: [ { provider: 'iubenda', consents: [{ consent: '1' }, { consent: '2' }], - resolutionStrategy: 'or' - } + resolutionStrategy: 'or', + }, ], }; expect( - IubendaConsentManager().consentManager.isDestinationConsented( + (IubendaConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -277,21 +269,21 @@ describe('Plugin - IubendaConsentManager', () => { blacklistedEvents: [], whitelistedEvents: [], eventFilteringOption: 'disable', - consentManagement:[ + consentManagement: [ { provider: 'iubenda', consents: [{ consent: '2' }, { consent: '4' }], - resolutionStrategy: 'and' - } + resolutionStrategy: 'and', + }, ], }; expect( - IubendaConsentManager().consentManager.isDestinationConsented( + (IubendaConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(false); }); @@ -299,6 +291,7 @@ describe('Plugin - IubendaConsentManager', () => { it('should return true and log an error if any exception is thrown while checking if the destination is consented', () => { state.consents.initialized.value = true; state.consents.data.value = { + // @ts-expect-error Intentionally setting null to test the error handling allowedConsentIds: null, // This will throw an exception deniedConsentIds: ['2', '4'], }; @@ -308,24 +301,23 @@ describe('Plugin - IubendaConsentManager', () => { blacklistedEvents: [], whitelistedEvents: [], eventFilteringOption: 'disable', - consentManagement:[ + consentManagement: [ { provider: 'iubenda', consents: [{ consent: '2' }, { consent: '4' }], - resolutionStrategy: 'and' - } + resolutionStrategy: 'and', + }, ], }; expect( - IubendaConsentManager().consentManager.isDestinationConsented( + (IubendaConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, - + defaultErrorHandler, + defaultLogger, ), ).toBe(true); - expect(mockErrorHandler.onError).toHaveBeenCalledWith( + expect(defaultErrorHandler.onError).toHaveBeenCalledWith( new TypeError("Cannot read properties of null (reading 'includes')"), 'IubendaConsentManagerPlugin', 'Failed to determine the consent status for the destination. Please check the destination configuration and try again.', @@ -365,12 +357,9 @@ describe('Plugin - IubendaConsentManager', () => { }, ], }; - const isDestinationConsented = IubendaConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + IubendaConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(false); }); @@ -396,12 +385,9 @@ describe('Plugin - IubendaConsentManager', () => { }, ], }; - const isDestinationConsented = IubendaConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + IubendaConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -438,12 +424,9 @@ describe('Plugin - IubendaConsentManager', () => { }, ], }; - const isDestinationConsented = IubendaConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + IubendaConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -470,11 +453,11 @@ describe('Plugin - IubendaConsentManager', () => { ], }; expect( - IubendaConsentManager().consentManager.isDestinationConsented( + (IubendaConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -482,7 +465,7 @@ describe('Plugin - IubendaConsentManager', () => { it('should return appropriate value when the resolution strategy not set', () => { state.consents.initialized.value = true; state.consents.provider.value = 'iubenda'; - state.consents.resolutionStrategy.value = null; + state.consents.resolutionStrategy.value = undefined; state.consents.data.value = { allowedConsentIds: ['C0001', 'C0002', 'C0003'], }; @@ -502,11 +485,11 @@ describe('Plugin - IubendaConsentManager', () => { ], }; expect( - IubendaConsentManager().consentManager.isDestinationConsented( + (IubendaConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); diff --git a/packages/analytics-js-plugins/__tests__/iubendaConsentManager/utils.test.ts b/packages/analytics-js-plugins/__tests__/iubendaConsentManager/utils.test.ts index 69318eb680..5f221c7958 100644 --- a/packages/analytics-js-plugins/__tests__/iubendaConsentManager/utils.test.ts +++ b/packages/analytics-js-plugins/__tests__/iubendaConsentManager/utils.test.ts @@ -1,21 +1,15 @@ -import { state, resetState } from '@rudderstack/analytics-js/state'; -import { defaultPluginEngine } from '@rudderstack/analytics-js/services/PluginEngine'; -import { PluginsManager } from '@rudderstack/analytics-js/components/pluginsManager'; -import { StoreManager } from '@rudderstack/analytics-js/services/StoreManager/StoreManager'; +import { defaultStoreManager } from '@rudderstack/analytics-js-common/__mocks__/StoreManager'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import type { IStoreManager } from '@rudderstack/analytics-js-common/types/Store'; +import { resetState, state } from '../../__mocks__/state'; import { updateConsentStateFromData, getConsentData, getIubendaConsentData, } from '../../src/iubendaConsentManager/utils'; -import { IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME} from '../../src/iubendaConsentManager/constants'; +import { IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME } from '../../src/iubendaConsentManager/constants'; describe('IubendaConsentManager - Utils', () => { - const mockLogger = { - error: jest.fn(), - warn: jest.fn(), - log: jest.fn(), - }; - beforeEach(() => { resetState(); @@ -76,32 +70,29 @@ describe('IubendaConsentManager - Utils', () => { }); describe('getIubendaConsentData', () => { - const pluginsManager = new PluginsManager(defaultPluginEngine, undefined, mockLogger); - const storeManager = new StoreManager(pluginsManager, undefined, mockLogger); - it('should get the iubenda consent data from cookies', () => { // Mock the iubenda data in the cookies const iubendaRawConsentData = { - timestamp: "2024-10-1T01:57:25.825Z", - version: "1.67.1", + timestamp: '2024-10-1T01:57:25.825Z', + version: '1.67.1', purposes: { '1': true, '2': false, '3': true, '4': false, - '5': true + '5': true, }, id: 252372, cons: { - rand: "92f72a" - } + rand: '92f72a', + }, }; const iubendaConsentString = JSON.stringify(iubendaRawConsentData); // Mock the iubenda cookies document.cookie = `${IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME}=${window.encodeURIComponent(iubendaConsentString)};`; - const iubendaConsentData = getIubendaConsentData(storeManager, mockLogger); + const iubendaConsentData = getIubendaConsentData(defaultStoreManager, defaultLogger); expect(iubendaConsentData).toStrictEqual({ '1': true, @@ -118,26 +109,25 @@ describe('IubendaConsentManager - Utils', () => { setStore: () => ({ engine: null, }), - }; + } as unknown as IStoreManager; - const iubendaConsentData = getIubendaConsentData(mockStoreManager, mockLogger); + const iubendaConsentData = getIubendaConsentData(mockStoreManager, defaultLogger); expect(iubendaConsentData).toBeUndefined(); }); it('should return undefined if iubenda consent cookie is not present', () => { - const iubendaConsentData = getIubendaConsentData(storeManager, mockLogger); + const iubendaConsentData = getIubendaConsentData(defaultStoreManager, defaultLogger); expect(iubendaConsentData).toBeUndefined(); }); - it('should return undefined if iubenda consent data inside the cookie is null', () => { // Mock the iubenda cookie // The value is inside is null document.cookie = `${IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME}=null;`; - const iubendaConsentData = getIubendaConsentData(storeManager, mockLogger); + const iubendaConsentData = getIubendaConsentData(defaultStoreManager, defaultLogger); expect(iubendaConsentData).toBeUndefined(); }); @@ -147,7 +137,7 @@ describe('IubendaConsentManager - Utils', () => { // The value is inside is empty string document.cookie = `${IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME}=%22%22;`; - const iubendaConsentData = getIubendaConsentData(storeManager, mockLogger); + const iubendaConsentData = getIubendaConsentData(defaultStoreManager, defaultLogger); expect(iubendaConsentData).toBeUndefined(); }); diff --git a/packages/analytics-js-plugins/__tests__/ketchConsentManager/index.test.ts b/packages/analytics-js-plugins/__tests__/ketchConsentManager/index.test.ts index 3404beb04f..b02cd1e16d 100644 --- a/packages/analytics-js-plugins/__tests__/ketchConsentManager/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/ketchConsentManager/index.test.ts @@ -1,7 +1,8 @@ -import { state, resetState } from '@rudderstack/analytics-js/state'; -import { defaultPluginEngine } from '@rudderstack/analytics-js/services/PluginEngine'; -import { PluginsManager } from '@rudderstack/analytics-js/components/pluginsManager'; -import { StoreManager } from '@rudderstack/analytics-js/services/StoreManager/StoreManager'; +import { defaultStoreManager } from '@rudderstack/analytics-js-common/__mocks__/StoreManager'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import { defaultErrorHandler } from '@rudderstack/analytics-js-common/__mocks__/ErrorHandler'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; +import { resetState, state } from '../../__mocks__/state'; import { KetchConsentManager } from '../../src/ketchConsentManager'; describe('Plugin - KetchConsentManager', () => { @@ -18,24 +19,14 @@ describe('Plugin - KetchConsentManager', () => { }); }); - const mockLogger = { - error: jest.fn(), - warn: jest.fn(), - log: jest.fn(), - }; - - const mockErrorHandler = { - onError: jest.fn(), - }; - it('should add KetchConsentManager plugin in the loaded plugin list', () => { - KetchConsentManager().initialize(state); + KetchConsentManager()?.initialize?.(state); expect(state.plugins.loadedPlugins.value.includes('KetchConsentManager')).toBe(true); }); it('should initialize the plugin if ketch consent data is already available on the window object', () => { // Initialize the plugin - KetchConsentManager().consentManager.init(state, mockLogger); + (KetchConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); expect((window as any).getKetchUserConsentedPurposes).toEqual(expect.any(Function)); expect((window as any).getKetchUserDeniedPurposes).toEqual(expect.any(Function)); @@ -53,10 +44,14 @@ describe('Plugin - KetchConsentManager', () => { }; // Initialize the plugin - KetchConsentManager().consentManager.init(state, mockLogger); + (KetchConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); // Update the state with the consent data - KetchConsentManager().consentManager.updateConsentsInfo(state, undefined, mockLogger); + (KetchConsentManager()?.consentManager as ExtensionPoint).updateConsentsInfo?.( + state, + undefined, + defaultLogger, + ); expect(state.consents.initialized.value).toBe(true); expect(state.consents.data.value).toStrictEqual({ @@ -74,7 +69,7 @@ describe('Plugin - KetchConsentManager', () => { it('should return undefined values when the window callbacks are invoked and there is no data in the state', () => { // Initialize the plugin - KetchConsentManager().consentManager.init(state, mockLogger); + (KetchConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); expect((window as any).getKetchUserConsentedPurposes()).toStrictEqual(undefined); expect((window as any).getKetchUserDeniedPurposes()).toStrictEqual(undefined); @@ -91,7 +86,7 @@ describe('Plugin - KetchConsentManager', () => { }; // Initialize the plugin - KetchConsentManager().consentManager.init(state, mockLogger); + (KetchConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); // Call the callback function (window as any).updateKetchConsent({ @@ -138,14 +133,15 @@ describe('Plugin - KetchConsentManager', () => { // Mock the ketch cookies document.cookie = `_ketch_consent_v1_=${window.btoa(ketchConsentString)};`; - const pluginsManager = new PluginsManager(defaultPluginEngine, undefined, mockLogger); - const storeManager = new StoreManager(pluginsManager, undefined, mockLogger); - // Initialize the plugin - KetchConsentManager().consentManager.init(state, mockLogger); + (KetchConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); // Update the state with the consent data - KetchConsentManager().consentManager.updateConsentsInfo(state, storeManager, mockLogger); + (KetchConsentManager()?.consentManager as ExtensionPoint).updateConsentsInfo?.( + state, + defaultStoreManager, + defaultLogger, + ); expect(state.consents.initialized.value).toBe(true); expect(state.consents.data.value).toStrictEqual({ @@ -163,11 +159,11 @@ describe('Plugin - KetchConsentManager', () => { it('should return true if the consent manager is not initialized', () => { expect( - KetchConsentManager().consentManager.isDestinationConsented( + (KetchConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, undefined, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -186,11 +182,11 @@ describe('Plugin - KetchConsentManager', () => { }; expect( - KetchConsentManager().consentManager.isDestinationConsented( + (KetchConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -210,11 +206,11 @@ describe('Plugin - KetchConsentManager', () => { }; expect( - KetchConsentManager().consentManager.isDestinationConsented( + (KetchConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -241,11 +237,11 @@ describe('Plugin - KetchConsentManager', () => { }; expect( - KetchConsentManager().consentManager.isDestinationConsented( + (KetchConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -272,11 +268,11 @@ describe('Plugin - KetchConsentManager', () => { }; expect( - KetchConsentManager().consentManager.isDestinationConsented( + (KetchConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(false); }); @@ -284,6 +280,7 @@ describe('Plugin - KetchConsentManager', () => { it('should return true and log an error if any exception is thrown while checking if the destination is consented', () => { state.consents.initialized.value = true; state.consents.data.value = { + // @ts-expect-error Intentionally set to null to throw an exception allowedConsentIds: null, // This will throw an exception deniedConsentIds: ['purpose2', 'purpose4'], }; @@ -303,14 +300,14 @@ describe('Plugin - KetchConsentManager', () => { }; expect( - KetchConsentManager().consentManager.isDestinationConsented( + (KetchConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); - expect(mockErrorHandler.onError).toHaveBeenCalledWith( + expect(defaultErrorHandler.onError).toHaveBeenCalledWith( new TypeError("Cannot read properties of null (reading 'includes')"), 'KetchConsentManagerPlugin', 'Failed to determine the consent status for the destination. Please check the destination configuration and try again.', @@ -350,12 +347,9 @@ describe('Plugin - KetchConsentManager', () => { }, ], }; - const isDestinationConsented = KetchConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + KetchConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(false); }); @@ -381,12 +375,9 @@ describe('Plugin - KetchConsentManager', () => { }, ], }; - const isDestinationConsented = KetchConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + KetchConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -423,12 +414,9 @@ describe('Plugin - KetchConsentManager', () => { }, ], }; - const isDestinationConsented = KetchConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + KetchConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -455,11 +443,11 @@ describe('Plugin - KetchConsentManager', () => { ], }; expect( - KetchConsentManager().consentManager.isDestinationConsented( + (KetchConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); @@ -467,7 +455,7 @@ describe('Plugin - KetchConsentManager', () => { it('should return appropriate value when the resolution strategy not set', () => { state.consents.initialized.value = true; state.consents.provider.value = 'ketch'; - state.consents.resolutionStrategy.value = null; + state.consents.resolutionStrategy.value = undefined; state.consents.data.value = { allowedConsentIds: ['C0001', 'C0002', 'C0003'], }; @@ -487,11 +475,11 @@ describe('Plugin - KetchConsentManager', () => { ], }; expect( - KetchConsentManager().consentManager.isDestinationConsented( + (KetchConsentManager()?.consentManager as ExtensionPoint).isDestinationConsented?.( state, destConfig, - mockErrorHandler, - mockLogger, + defaultErrorHandler, + defaultLogger, ), ).toBe(true); }); diff --git a/packages/analytics-js-plugins/__tests__/ketchConsentManager/utils.test.ts b/packages/analytics-js-plugins/__tests__/ketchConsentManager/utils.test.ts index 6843d29753..af3eb2a7c9 100644 --- a/packages/analytics-js-plugins/__tests__/ketchConsentManager/utils.test.ts +++ b/packages/analytics-js-plugins/__tests__/ketchConsentManager/utils.test.ts @@ -1,20 +1,14 @@ -import { state, resetState } from '@rudderstack/analytics-js/state'; -import { defaultPluginEngine } from '@rudderstack/analytics-js/services/PluginEngine'; -import { PluginsManager } from '@rudderstack/analytics-js/components/pluginsManager'; -import { StoreManager } from '@rudderstack/analytics-js/services/StoreManager/StoreManager'; +import { defaultStoreManager } from '@rudderstack/analytics-js-common/__mocks__/StoreManager'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import { resetState, state } from '../../__mocks__/state'; import { updateConsentStateFromData, getConsentData, getKetchConsentData, } from '../../src/ketchConsentManager/utils'; +import { defaultPluginsManager } from '../../__mocks__/PluginsManager'; describe('KetchConsentManager - Utils', () => { - const mockLogger = { - error: jest.fn(), - warn: jest.fn(), - log: jest.fn(), - }; - beforeEach(() => { resetState(); @@ -75,9 +69,6 @@ describe('KetchConsentManager - Utils', () => { }); describe('getKetchConsentData', () => { - const pluginsManager = new PluginsManager(defaultPluginEngine, undefined, mockLogger); - const storeManager = new StoreManager(pluginsManager, undefined, mockLogger); - it('should get the ketch consent data from cookies', () => { // Mock the ketch data in the cookies const ketchRawConsentData = { @@ -102,7 +93,7 @@ describe('KetchConsentManager - Utils', () => { // Mock the ketch cookies document.cookie = `_ketch_consent_v1_=${window.btoa(ketchConsentString)};`; - const ketchConsentData = getKetchConsentData(storeManager, mockLogger); + const ketchConsentData = getKetchConsentData(defaultStoreManager, defaultLogger); expect(ketchConsentData).toStrictEqual({ purpose1: true, @@ -121,17 +112,17 @@ describe('KetchConsentManager - Utils', () => { }), }; - const ketchConsentData = getKetchConsentData(mockStoreManager, mockLogger); + const ketchConsentData = getKetchConsentData(mockStoreManager, defaultLogger); expect(ketchConsentData).toBeUndefined(); - expect(mockLogger.error).toHaveBeenCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'KetchConsentManagerPlugin:: Failed to read the consent cookie.', new TypeError("Cannot read properties of null (reading 'getItem')"), ); }); it('should return undefined if ketch consent cookie is not present', () => { - const ketchConsentData = getKetchConsentData(storeManager, mockLogger); + const ketchConsentData = getKetchConsentData(defaultStoreManager, defaultLogger); expect(ketchConsentData).toBeUndefined(); }); @@ -141,10 +132,10 @@ describe('KetchConsentManager - Utils', () => { // The value is not Base64 encoded document.cookie = `_ketch_consent_v1_=abc;`; - const ketchConsentData = getKetchConsentData(storeManager, mockLogger); + const ketchConsentData = getKetchConsentData(defaultStoreManager, defaultLogger); expect(ketchConsentData).toBeUndefined(); - expect(mockLogger.error).toHaveBeenCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'KetchConsentManagerPlugin:: Failed to parse the consent cookie.', new SyntaxError('Unexpected token \'i\', "i�" is not valid JSON'), ); @@ -155,10 +146,10 @@ describe('KetchConsentManager - Utils', () => { // The value is not JSON stringified document.cookie = `_ketch_consent_v1_=YWJjZGU=;`; - const ketchConsentData = getKetchConsentData(storeManager, mockLogger); + const ketchConsentData = getKetchConsentData(defaultStoreManager, defaultLogger); expect(ketchConsentData).toBeUndefined(); - expect(mockLogger.error).toHaveBeenCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'KetchConsentManagerPlugin:: Failed to parse the consent cookie.', new SyntaxError('Unexpected token \'a\', "abcde" is not valid JSON'), ); @@ -169,7 +160,7 @@ describe('KetchConsentManager - Utils', () => { // The value is inside is null document.cookie = `_ketch_consent_v1_=bnVsbA==;`; - const ketchConsentData = getKetchConsentData(storeManager, mockLogger); + const ketchConsentData = getKetchConsentData(defaultStoreManager, defaultLogger); expect(ketchConsentData).toBeUndefined(); }); @@ -179,7 +170,7 @@ describe('KetchConsentManager - Utils', () => { // The value is inside is empty string document.cookie = `_ketch_consent_v1_=IiI=;`; - const ketchConsentData = getKetchConsentData(storeManager, mockLogger); + const ketchConsentData = getKetchConsentData(defaultStoreManager, defaultLogger); expect(ketchConsentData).toBeUndefined(); }); diff --git a/packages/analytics-js-plugins/__tests__/nativeDestinationQueue/utilities.test.ts b/packages/analytics-js-plugins/__tests__/nativeDestinationQueue/utilities.test.ts index 3710e18f69..10f64648c7 100644 --- a/packages/analytics-js-plugins/__tests__/nativeDestinationQueue/utilities.test.ts +++ b/packages/analytics-js-plugins/__tests__/nativeDestinationQueue/utilities.test.ts @@ -1,9 +1,10 @@ import { clone } from 'ramda'; +import type { Destination } from '@rudderstack/analytics-js-common/types/Destination'; import { isEventDenyListed } from '../../src/nativeDestinationQueue/utilities'; describe('nativeDestinationQueue Plugin - utilities', () => { describe('isEventDenyListed', () => { - const mockDestination = { + const destination = { id: 'sample-destination-id', displayName: 'Destination Display Name', userFriendlyId: 'ID_sample-destination-id', @@ -21,13 +22,13 @@ describe('nativeDestinationQueue Plugin - utilities', () => { analytics: {}, isLoaded: () => true, }, - }; + } as unknown as Destination; it('should return false if the event type is not track', () => { - const outcome1 = isEventDenyListed('identify', undefined, mockDestination); - const outcome2 = isEventDenyListed('page', undefined, mockDestination); - const outcome3 = isEventDenyListed('group', undefined, mockDestination); - const outcome4 = isEventDenyListed('alias', undefined, mockDestination); + const outcome1 = isEventDenyListed('identify', null, destination); + const outcome2 = isEventDenyListed('page', null, destination); + const outcome3 = isEventDenyListed('group', null, destination); + const outcome4 = isEventDenyListed('alias', null, destination); expect(outcome1).toBeFalsy(); expect(outcome2).toBeFalsy(); @@ -36,62 +37,66 @@ describe('nativeDestinationQueue Plugin - utilities', () => { }); it('should return false if deny list is selected and track event does not have event name property', () => { - const mockDest = clone(mockDestination); + const mockDest = clone(destination); mockDest.config.eventFilteringOption = 'blacklistedEvents'; - const outcome1 = isEventDenyListed('track', undefined, mockDest); + const outcome1 = isEventDenyListed('track', null, mockDest); expect(outcome1).toBeFalsy(); }); it('should return false if deny list is selected and track event name is not string', () => { - const mockDest = clone(mockDestination); + const mockDest = clone(destination); mockDest.config.eventFilteringOption = 'blacklistedEvents'; + // @ts-expect-error eventName is not a string const outcome1 = isEventDenyListed('track', true, mockDest); + // @ts-expect-error eventName is not a string const outcome2 = isEventDenyListed('track', 12345, mockDest); expect(outcome1).toBeFalsy(); expect(outcome2).toBeFalsy(); }); it('should return true if deny list is selected and track event name matches with denylist event name', () => { - const mockDest = clone(mockDestination); + const mockDest = clone(destination); mockDest.config.eventFilteringOption = 'blacklistedEvents'; const outcome1 = isEventDenyListed('track', 'sample track event 2', mockDest); expect(outcome1).toBeTruthy(); }); it('should return false if deny list is selected and track event name does not matches with denylist event name', () => { - const mockDest = clone(mockDestination); + const mockDest = clone(destination); mockDest.config.eventFilteringOption = 'blacklistedEvents'; const outcome1 = isEventDenyListed('track', 'sample track event 1234', mockDest); expect(outcome1).toBeFalsy(); }); it('should return false if deny list is selected and track event name is in different case than with denylist event name', () => { - const mockDest = clone(mockDestination); + const mockDest = clone(destination); mockDest.config.eventFilteringOption = 'blacklistedEvents'; const outcome1 = isEventDenyListed('track', 'Sample track event 2', mockDest); expect(outcome1).toBeFalsy(); }); it('should return true if allow list is selected and track event does not have event name property', () => { - const outcome1 = isEventDenyListed('track', undefined, mockDestination); + const outcome1 = isEventDenyListed('track', null, destination); expect(outcome1).toBeTruthy(); }); it('should return true if allow list is selected and track event name is not string', () => { - const outcome1 = isEventDenyListed('track', true, mockDestination); - const outcome2 = isEventDenyListed('track', 12345, mockDestination); + // @ts-expect-error eventName is not a string + const outcome1 = isEventDenyListed('track', true, destination); + // @ts-expect-error eventName is not a string + const outcome2 = isEventDenyListed('track', 12345, destination); expect(outcome1).toBeTruthy(); expect(outcome2).toBeTruthy(); }); it('should return false if allow list is selected and track event name matches with allowlist event name', () => { - const outcome1 = isEventDenyListed('track', 'sample track event 1', mockDestination); + const outcome1 = isEventDenyListed('track', 'sample track event 1', destination); expect(outcome1).toBeFalsy(); }); it('should return true if allow list is selected and track event name does not matches with allowlist event name', () => { - const outcome1 = isEventDenyListed('track', 'sample track event 1234', mockDestination); + const outcome1 = isEventDenyListed('track', 'sample track event 1234', destination); expect(outcome1).toBeTruthy(); }); it('should return true if allow list is selected and track event name is in different case than with with allowlist event name', () => { - const outcome1 = isEventDenyListed('track', 'Sample track event 1', mockDestination); + const outcome1 = isEventDenyListed('track', 'Sample track event 1', destination); expect(outcome1).toBeTruthy(); }); }); diff --git a/packages/analytics-js-plugins/__tests__/oneTrustConsentManager/index.test.ts b/packages/analytics-js-plugins/__tests__/oneTrustConsentManager/index.test.ts index 45efa9c923..30cab22e91 100644 --- a/packages/analytics-js-plugins/__tests__/oneTrustConsentManager/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/oneTrustConsentManager/index.test.ts @@ -1,4 +1,7 @@ -import { state, resetState } from '@rudderstack/analytics-js/state'; +import { defaultErrorHandler } from '@rudderstack/analytics-js-common/__mocks__/ErrorHandler'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; +import { resetState, state } from '../../__mocks__/state'; import { OneTrustConsentManager } from '../../src/oneTrustConsentManager'; describe('Plugin - OneTrustConsentManager', () => { @@ -8,18 +11,8 @@ describe('Plugin - OneTrustConsentManager', () => { delete (window as any).OnetrustActiveGroups; }); - const mockLogger = { - error: jest.fn(), - warn: jest.fn(), - log: jest.fn(), - }; - - const mockErrorHandler = { - onError: jest.fn(), - }; - it('should add OneTrustConsentManager plugin in the loaded plugin list', () => { - OneTrustConsentManager().initialize(state); + OneTrustConsentManager()?.initialize?.(state); expect(state.plugins.loadedPlugins.value.includes('OneTrustConsentManager')).toBe(true); }); @@ -40,10 +33,14 @@ describe('Plugin - OneTrustConsentManager', () => { (window as any).OnetrustActiveGroups = ',C0001,C0003,'; // Initialize the plugin - OneTrustConsentManager().consentManager.init(state, mockLogger); + (OneTrustConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); // Update the consent info from state - OneTrustConsentManager().consentManager.updateConsentsInfo(state, undefined, mockLogger); + (OneTrustConsentManager()?.consentManager as ExtensionPoint).updateConsentsInfo?.( + state, + undefined, + defaultLogger, + ); expect(state.consents.initialized.value).toBe(true); expect(state.consents.data.value).toStrictEqual({ @@ -54,13 +51,17 @@ describe('Plugin - OneTrustConsentManager', () => { it('should not successfully update consents data the plugin if OneTrust SDK is not loaded', () => { // Initialize the plugin - OneTrustConsentManager().consentManager.init(state, mockLogger); + (OneTrustConsentManager()?.consentManager as ExtensionPoint).init?.(state, defaultLogger); // Update the consent info from state - OneTrustConsentManager().consentManager.updateConsentsInfo(state, undefined, mockLogger); + (OneTrustConsentManager()?.consentManager as ExtensionPoint).updateConsentsInfo?.( + state, + undefined, + defaultLogger, + ); expect(state.consents.initialized.value).toStrictEqual(false); - expect(mockLogger.error).toHaveBeenCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( `OneTrustConsentManagerPlugin:: Failed to access OneTrust SDK resources. Please ensure that the OneTrust SDK is loaded successfully before RudderStack SDK.`, ); }); @@ -89,12 +90,9 @@ describe('Plugin - OneTrustConsentManager', () => { key: 'value', }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -116,12 +114,9 @@ describe('Plugin - OneTrustConsentManager', () => { key: 'value', }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -137,12 +132,9 @@ describe('Plugin - OneTrustConsentManager', () => { key: 'value', }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -165,12 +157,9 @@ describe('Plugin - OneTrustConsentManager', () => { ], key: 'value', }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(false); }); @@ -187,14 +176,11 @@ describe('Plugin - OneTrustConsentManager', () => { key: 'value', }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); - expect(mockErrorHandler.onError).toHaveBeenCalledWith( + expect(defaultErrorHandler.onError).toHaveBeenCalledWith( new TypeError('oneTrustCookieCategories.map is not a function'), 'OneTrustConsentManagerPlugin', 'Failed to determine the consent status for the destination. Please check the destination configuration and try again.', @@ -234,12 +220,9 @@ describe('Plugin - OneTrustConsentManager', () => { }, ], }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(false); }); @@ -265,12 +248,9 @@ describe('Plugin - OneTrustConsentManager', () => { }, ], }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -307,12 +287,9 @@ describe('Plugin - OneTrustConsentManager', () => { }, ], }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -349,12 +326,9 @@ describe('Plugin - OneTrustConsentManager', () => { }, ], }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); @@ -384,12 +358,9 @@ describe('Plugin - OneTrustConsentManager', () => { }, ], }; - const isDestinationConsented = OneTrustConsentManager().consentManager.isDestinationConsented( - state, - destConfig, - mockErrorHandler, - mockLogger, - ); + const isDestinationConsented = ( + OneTrustConsentManager()?.consentManager as ExtensionPoint + ).isDestinationConsented?.(state, destConfig, defaultErrorHandler, defaultLogger); expect(isDestinationConsented).toBe(true); }); }); diff --git a/packages/analytics-js-plugins/__tests__/storageEncryption/index.test.ts b/packages/analytics-js-plugins/__tests__/storageEncryption/index.test.ts index 877dc058a2..8f8f5ec515 100644 --- a/packages/analytics-js-plugins/__tests__/storageEncryption/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/storageEncryption/index.test.ts @@ -1,37 +1,32 @@ -import { signal } from '@preact/signals-core'; -import { clone } from 'ramda'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; import { StorageEncryption } from '../../src/storageEncryption'; +import { resetState, state } from '../../__mocks__/state'; describe('Plugin - Storage Encryption', () => { - const originalState = { - plugins: { - loadedPlugins: signal([]), - }, - }; const storageEncryption = StorageEncryption(); - let state: any; - beforeEach(() => { - state = clone(originalState); + resetState(); }); it('should add plugin in the loaded plugin list', () => { - storageEncryption.initialize(state); + storageEncryption?.initialize?.(state); expect(state.plugins.loadedPlugins.value.includes('StorageEncryption')).toBe(true); }); it('should encrypt the data', () => { - const encryptedData = storageEncryption.storage?.encrypt('test-data'); + const encryptedData = (storageEncryption.storage as ExtensionPoint).encrypt?.('test-data'); expect(encryptedData).toBe('RS_ENC_v3_dGVzdC1kYXRh'); }); it('should decrypt encrypted data', () => { - const decryptedData = storageEncryption.storage?.decrypt('RS_ENC_v3_dGVzdC1kYXRh'); + const decryptedData = (storageEncryption.storage as ExtensionPoint).decrypt?.( + 'RS_ENC_v3_dGVzdC1kYXRh', + ); expect(decryptedData).toBe('test-data'); }); it('should return same data if it is not a supported encryption format', () => { - const decryptedData = storageEncryption.storage?.decrypt('test-data'); + const decryptedData = (storageEncryption.storage as ExtensionPoint).decrypt?.('test-data'); expect(decryptedData).toBe('test-data'); }); }); diff --git a/packages/analytics-js-plugins/__tests__/storageEncryptionLegacy/index.test.ts b/packages/analytics-js-plugins/__tests__/storageEncryptionLegacy/index.test.ts index bef4d7e5f2..82d2e07dad 100644 --- a/packages/analytics-js-plugins/__tests__/storageEncryptionLegacy/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/storageEncryptionLegacy/index.test.ts @@ -1,41 +1,41 @@ -import { signal } from '@preact/signals-core'; -import { clone } from 'ramda'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; import { StorageEncryptionLegacy } from '../../src/storageEncryptionLegacy'; +import { resetState, state } from '../../__mocks__/state'; describe('Plugin - Storage Encryption Legacy', () => { - const originalState = { - plugins: { - loadedPlugins: signal([]), - }, - }; const storageEncryptionLegacy = StorageEncryptionLegacy(); - let state: any; beforeEach(() => { - state = clone(originalState); + resetState(); }); it('should add plugin in the loaded plugin list', () => { - storageEncryptionLegacy.initialize(state); + storageEncryptionLegacy?.initialize?.(state); expect(state.plugins.loadedPlugins.value.includes('StorageEncryptionLegacy')).toBe(true); }); it('should encrypt the data', () => { const srcData = '"1wefk7M3Y1D6EDX4ZpIE00LpKAE"'; - const encryptedData = storageEncryptionLegacy.storage?.encrypt(srcData); + const encryptedData = (storageEncryptionLegacy.storage as ExtensionPoint).encrypt?.( + srcData, + ) as string; expect(encryptedData.startsWith('RudderEncrypt:')).toBe(true); - expect(storageEncryptionLegacy.storage?.decrypt(encryptedData)).toBe(srcData); + expect((storageEncryptionLegacy.storage as ExtensionPoint).decrypt?.(encryptedData)).toBe( + srcData, + ); }); it('should decrypt encrypted data', () => { - const decryptedData = storageEncryptionLegacy.storage?.decrypt( + const decryptedData = (storageEncryptionLegacy.storage as ExtensionPoint).decrypt?.( 'RudderEncrypt:U2FsdGVkX1+5q5jikppUASe8AdIH6O2iORyF41sYXgxzIGiX9whSeVxxww0OK5h/', ); expect(decryptedData).toBe('"1wefk7M3Y1D6EDX4ZpIE00LpKAE"'); }); it('should return same data if it is not a supported encryption format', () => { - const decryptedData = storageEncryptionLegacy.storage?.decrypt('test-data'); + const decryptedData = (storageEncryptionLegacy.storage as ExtensionPoint).decrypt?.( + 'test-data', + ); expect(decryptedData).toBe('test-data'); }); }); diff --git a/packages/analytics-js-plugins/__tests__/storageMigrator/.gitkeep b/packages/analytics-js-plugins/__tests__/storageMigrator/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/analytics-js-plugins/__tests__/storageMigrator/index.test.ts b/packages/analytics-js-plugins/__tests__/storageMigrator/index.test.ts index 55a7a016df..899adbf465 100644 --- a/packages/analytics-js-plugins/__tests__/storageMigrator/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/storageMigrator/index.test.ts @@ -1,144 +1,144 @@ -import { signal } from '@preact/signals-core'; -import { clone } from 'ramda'; +import { defaultErrorHandler } from '@rudderstack/analytics-js-common/__mocks__/ErrorHandler'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; +import { defaultLocalStorage } from '@rudderstack/analytics-js-common/__mocks__/Storage'; import { StorageMigrator } from '../../src/storageMigrator'; +import { resetState, state } from '../../__mocks__/state'; describe('Plugin - Storage Migrator', () => { - const originalState = { - plugins: { - loadedPlugins: signal([]), - }, - }; const storageMigrator = StorageMigrator(); - let state: any; beforeEach(() => { - state = clone(originalState); - }); - - let storedVal; - - const storageEngine = { - getItem: (key: string) => storedVal, - }; - - const mockLogger = { - error: jest.fn(), - }; - - const mockErrorHandler = { - onError: jest.fn(), - }; - - beforeEach(() => { - storedVal = undefined; + resetState(); }); it('should add plugin in the loaded plugin list', () => { - storageMigrator.initialize(state); + storageMigrator?.initialize?.(state); expect(state.plugins.loadedPlugins.value.includes('StorageMigrator')).toBe(true); }); it('should migrate legacy encrypted data', () => { - storedVal = 'RudderEncrypt:U2FsdGVkX1+5q5jikppUASe8AdIH6O2iORyF41sYXgxzIGiX9whSeVxxww0OK5h/'; - const migratedVal = storageMigrator.storage?.migrate( - null, - storageEngine, - mockErrorHandler, - mockLogger, + defaultLocalStorage.setItem( + 'key', + 'RudderEncrypt:U2FsdGVkX1+5q5jikppUASe8AdIH6O2iORyF41sYXgxzIGiX9whSeVxxww0OK5h/', + ); + + const migratedVal = (storageMigrator.storage as ExtensionPoint).migrate?.( + 'key', + defaultLocalStorage, + defaultErrorHandler, + defaultLogger, ); expect(migratedVal).toBe('1wefk7M3Y1D6EDX4ZpIE00LpKAE'); }); it('should migrate v3 encrypted data', () => { - storedVal = 'RS_ENC_v3_InRlc3QtZGF0YSI='; - const migratedVal = storageMigrator.storage?.migrate( - null, - storageEngine, - mockErrorHandler, - mockLogger, + defaultLocalStorage.setItem('key', 'RS_ENC_v3_InRlc3QtZGF0YSI='); + + const migratedVal = (storageMigrator.storage as ExtensionPoint).migrate?.( + 'key', + defaultLocalStorage, + defaultErrorHandler, + defaultLogger, ); expect(migratedVal).toBe('test-data'); }); it('should return null if the stored value is undefined', () => { - storedVal = undefined; - const migratedVal = storageMigrator.storage?.migrate( - null, - storageEngine, - mockErrorHandler, - mockLogger, + defaultLocalStorage.setItem('key', undefined); + + const migratedVal = (storageMigrator.storage as ExtensionPoint).migrate?.( + 'key', + defaultLocalStorage, + defaultErrorHandler, + defaultLogger, ); expect(migratedVal).toBe(null); }); it('should return null if the stored value is null', () => { - storedVal = null; - const migratedVal = storageMigrator.storage?.migrate( - null, - storageEngine, - mockErrorHandler, - mockLogger, + defaultLocalStorage.setItem('key', null); + + const migratedVal = (storageMigrator.storage as ExtensionPoint).migrate?.( + 'key', + defaultLocalStorage, + defaultErrorHandler, + defaultLogger, ); expect(migratedVal).toBe(null); }); it('should return null if the legacy decrypted value is undefined', () => { - storedVal = 'RudderEncrypt:U2FsdGVkX195kUN9L968e0E/eu8CtnDHWt6ALf6bm8E='; - const migratedVal = storageMigrator.storage?.migrate( - null, - storageEngine, - mockErrorHandler, - mockLogger, + defaultLocalStorage.setItem( + 'key', + 'RudderEncrypt:U2FsdGVkX195kUN9L968e0E/eu8CtnDHWt6ALf6bm8E=', + ); + + const migratedVal = (storageMigrator.storage as ExtensionPoint).migrate?.( + 'key', + defaultLocalStorage, + defaultErrorHandler, + defaultLogger, ); expect(migratedVal).toBe(null); }); it('should return null if the legacy decrypted value is null', () => { - storedVal = 'RudderEncrypt:U2FsdGVkX1+SMQ+LKcuk7w/nQ9DEjgU9EUmmBgb/Pfo='; - const migratedVal = storageMigrator.storage?.migrate( + defaultLocalStorage.setItem( + 'key', + 'RudderEncrypt:U2FsdGVkX1+SMQ+LKcuk7w/nQ9DEjgU9EUmmBgb/Pfo=', + ); + + const migratedVal = (storageMigrator.storage as ExtensionPoint).migrate?.( null, - storageEngine, - mockErrorHandler, - mockLogger, + defaultLocalStorage, + defaultErrorHandler, + defaultLogger, ); expect(migratedVal).toBe(null); }); it('should return null if the v3 decrypted value is undefined', () => { - storedVal = 'RS_ENC_v3_dW5kZWZpbmVk'; - const migratedVal = storageMigrator.storage?.migrate( - null, - storageEngine, - mockErrorHandler, - mockLogger, + defaultLocalStorage.setItem('key', 'RS_ENC_v3_dW5kZWZpbmVk'); + + const migratedVal = (storageMigrator.storage as ExtensionPoint).migrate?.( + 'key', + defaultLocalStorage, + defaultErrorHandler, + defaultLogger, ); expect(migratedVal).toBe(null); }); it('should return null if the v3 decrypted value is null', () => { - storedVal = 'RS_ENC_v3_bnVsbA=='; - const migratedVal = storageMigrator.storage?.migrate( + defaultLocalStorage.setItem('key', 'RS_ENC_v3_bnVsbA=='); + + const migratedVal = (storageMigrator.storage as ExtensionPoint).migrate?.( null, - storageEngine, - mockErrorHandler, - mockLogger, + defaultLocalStorage, + defaultErrorHandler, + defaultLogger, ); expect(migratedVal).toBe(null); }); it('should return null and log error if the stored actual value is not JSON parsable', () => { - storedVal = 'RudderEncrypt:U2FsdGVkX1+leaJ/SuyfirUYffyQelWPnCTB93FBo4Y='; - const migratedVal = storageMigrator.storage?.migrate( - 'someKey', - storageEngine, - mockErrorHandler, - mockLogger, + defaultLocalStorage.setItem( + 'key', + 'RudderEncrypt:U2FsdGVkX1+leaJ/SuyfirUYffyQelWPnCTB93FBo4Y=', + ); + + const migratedVal = (storageMigrator.storage as ExtensionPoint).migrate?.( + 'key', + defaultLocalStorage, + defaultErrorHandler, + defaultLogger, ); expect(migratedVal).toBe(null); - expect(mockErrorHandler.onError).toHaveBeenCalledWith( + expect(defaultErrorHandler.onError).toHaveBeenCalledWith( new SyntaxError('Unexpected token \'h\', "hello" is not valid JSON'), 'StorageMigratorPlugin', - 'Failed to retrieve or parse data for someKey from storage.', + 'Failed to retrieve or parse data for key from storage.', ); }); }); diff --git a/packages/analytics-js-plugins/__tests__/utilities/destination.test.ts b/packages/analytics-js-plugins/__tests__/utilities/destination.test.ts index 57d7e40f19..3feee0c3b7 100644 --- a/packages/analytics-js-plugins/__tests__/utilities/destination.test.ts +++ b/packages/analytics-js-plugins/__tests__/utilities/destination.test.ts @@ -1,16 +1,18 @@ +import type { Destination } from '@rudderstack/analytics-js-common/types/Destination'; +import type { IntegrationOpts } from '@rudderstack/analytics-js-common/types/Integration'; import { filterDestinations } from '../../src/utilities/destination'; describe('Destination Utilities', () => { describe('filterDestinations', () => { - const destinations = [ + const destinations: Destination[] = [ { name: 'GA4', displayName: 'Google Analytics 4 (GA4)', - }, + } as unknown as Destination, { name: 'BRAZE', displayName: 'Braze', - }, + } as unknown as Destination, ]; it('return value should not contain destinations that are specified as false in the load options', () => { @@ -71,8 +73,9 @@ describe('Destination Utilities', () => { 'Google Analytics 4 (GA4)': { customKey: 'customValue', }, + // Intentionally, set a truthy value for Braze Braze: [1, 2, 3], - }; + } as unknown as IntegrationOpts; const filteredDestinations = filterDestinations(loadOptions, destinations); @@ -80,26 +83,27 @@ describe('Destination Utilities', () => { }); it('should not return destinations whose values are specified as falsy in the load options', () => { - const configDestinations = [ + const configDestinations: Destination[] = [ { name: 'GA4', displayName: 'Google Analytics 4 (GA4)', - }, + } as unknown as Destination, { name: 'BRAZE', displayName: 'Braze', - }, + } as unknown as Destination, { name: 'AM', displayName: 'Amplitude', - }, + } as unknown as Destination, ]; const loadOptions = { All: true, 'Google Analytics 4 (GA4)': '', + // Intentionally, set a falsy value for Braze Braze: 0, - }; + } as unknown as IntegrationOpts; const filteredDestinations = filterDestinations(loadOptions, configDestinations); diff --git a/packages/analytics-js-plugins/__tests__/utilities/queue.test.ts b/packages/analytics-js-plugins/__tests__/utilities/queue.test.ts index 0f60b8eac1..44dca615f7 100644 --- a/packages/analytics-js-plugins/__tests__/utilities/queue.test.ts +++ b/packages/analytics-js-plugins/__tests__/utilities/queue.test.ts @@ -1,25 +1,8 @@ -import type { RudderEvent } from '@rudderstack/analytics-js-common/types/Event'; -import type { ILogger } from '@rudderstack/analytics-js-common/types/Logger'; -import { - getDeliveryPayload, - validateEventPayloadSize, -} from '@rudderstack/analytics-js-plugins/utilities/eventsDelivery'; -import * as utilConstants from '@rudderstack/analytics-js-plugins/utilities/constants'; - -class MockLogger implements ILogger { - warn = jest.fn(); - log = jest.fn(); - error = jest.fn(); - info = jest.fn(); - debug = jest.fn(); - minLogLevel = 0; - scope = 'test scope'; - setMinLogLevel = jest.fn(); - setScope = jest.fn(); - logProvider = console; -} - -const mockLogger = new MockLogger(); +import type { RudderContext, RudderEvent } from '@rudderstack/analytics-js-common/types/Event'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import type { ApiObject } from '@rudderstack/analytics-js-common/types/ApiObject'; +import { getDeliveryPayload, validateEventPayloadSize } from '../../src/utilities/eventsDelivery'; +import * as utilConstants from '../../src/utilities/constants'; describe('Queue Plugins Utilities', () => { describe('getDeliveryPayload', () => { @@ -89,7 +72,7 @@ describe('Queue Plugins Utilities', () => { properties: { test: 'test', }, - }; + } as unknown as RudderEvent; expect(getDeliveryPayload(event)).toEqual( '{"channel":"test","type":"track","anonymousId":"test","context":{"traits":{"trait_1":"trait_1","trait_2":"trait_2"},"sessionId":1,"sessionStart":true,"consentManagement":{"deniedConsentIds":["1","2","3"]},"ua-ch":{"test":"test"},"app":{"name":"test","version":"test","namespace":"test"},"library":{"name":"test","version":"test"},"userAgent":"test","os":{"name":"test","version":"test"},"locale":"test","screen":{"width":1,"height":1,"density":1,"innerWidth":1,"innerHeight":1},"campaign":{"source":"test","medium":"test","name":"test","term":"test","content":"test"}},"originalTimestamp":"test","integrations":{"All":true},"messageId":"test","previousId":"test","sentAt":"test","category":"test","traits":{"trait_1":"trait_11","trait_2":"trait_12"},"groupId":"test","event":"test","userId":"test","properties":{"test":"test"}}', @@ -152,7 +135,7 @@ describe('Queue Plugins Utilities', () => { test: 'test', test2: null, }, - }; + } as unknown as RudderEvent; expect(getDeliveryPayload(event)).toEqual( '{"channel":"test","type":"track","anonymousId":"test","context":{"traits":{"trait_1":"trait_1","trait_2":"trait_2"},"sessionId":1,"sessionStart":true,"ua-ch":{"test":"test"},"app":{"name":"test","version":"test","namespace":"test"},"library":{"name":"test","version":"test"},"userAgent":"test","os":{"name":"test","version":"test"},"locale":"test","screen":{"width":1,"height":1,"density":1,"innerWidth":1,"innerHeight":1}},"originalTimestamp":"test","integrations":{"All":true},"messageId":"test","previousId":"test","sentAt":"test","category":"test","groupId":"test","event":"test","userId":"test","properties":{"test":"test"}}', @@ -225,12 +208,12 @@ describe('Queue Plugins Utilities', () => { properties: { test: 'test', }, - } as RudderEvent; + } as unknown as RudderEvent; event.traits = event.context.traits; - event.context.traits.newTraits = event.traits; + ((event.context as RudderContext).traits as ApiObject).newTraits = event.traits; - expect(getDeliveryPayload(event, mockLogger)).toContain('[Circular Reference]'); + expect(getDeliveryPayload(event, defaultLogger)).toContain('[Circular Reference]'); }); it('should return null if the payload cannot be stringified', () => { @@ -238,11 +221,12 @@ describe('Queue Plugins Utilities', () => { channel: 'test', type: 'track', properties: { + // eslint-disable-next-line compat/compat someBigInt: BigInt(9007199254740991), }, } as unknown as RudderEvent; - expect(getDeliveryPayload(event, mockLogger)).toBeNull(); + expect(getDeliveryPayload(event, defaultLogger)).toBeNull(); }); }); @@ -250,11 +234,17 @@ describe('Queue Plugins Utilities', () => { const originalMaxEventPayloadSize = utilConstants.EVENT_PAYLOAD_SIZE_BYTES_LIMIT; beforeEach(() => { - utilConstants.EVENT_PAYLOAD_SIZE_BYTES_LIMIT = 50; + Object.defineProperty(utilConstants, 'EVENT_PAYLOAD_SIZE_BYTES_LIMIT', { + value: 50, + writable: true, + }); }); afterEach(() => { - utilConstants.EVENT_PAYLOAD_SIZE_BYTES_LIMIT = originalMaxEventPayloadSize; + Object.defineProperty(utilConstants, 'EVENT_PAYLOAD_SIZE_BYTES_LIMIT', { + value: originalMaxEventPayloadSize, + writable: false, + }); }); it('should log a warning if the payload size is greater than the max limit', () => { @@ -269,10 +259,10 @@ describe('Queue Plugins Utilities', () => { properties: { test: 'test', }, - }; - validateEventPayloadSize(event, mockLogger); + } as unknown as RudderEvent; + validateEventPayloadSize(event, defaultLogger); - expect(mockLogger.warn).toHaveBeenCalledWith( + expect(defaultLogger.warn).toHaveBeenCalledWith( 'QueueUtilities:: The size of the event payload (129 bytes) exceeds the maximum limit of 50 bytes. Events with large payloads may be dropped in the future. Please review your instrumentation to ensure that event payloads are within the size limit.', ); }); @@ -281,11 +271,11 @@ describe('Queue Plugins Utilities', () => { const event = { channel: 'test', type: 'track', - }; + } as unknown as RudderEvent; - validateEventPayloadSize(event, mockLogger); + validateEventPayloadSize(event, defaultLogger); - expect(mockLogger.warn).not.toHaveBeenCalled(); + expect(defaultLogger.warn).not.toHaveBeenCalled(); }); it('should not log a warning if the payload size is equal to the max limit', () => { @@ -295,11 +285,11 @@ describe('Queue Plugins Utilities', () => { type: 'track', ab: 'd', g: 'j', - }; + } as unknown as RudderEvent; - validateEventPayloadSize(event, mockLogger); + validateEventPayloadSize(event, defaultLogger); - expect(mockLogger.warn).not.toHaveBeenCalled(); + expect(defaultLogger.warn).not.toHaveBeenCalled(); }); it('should log a warning if the payload size could not be calculated', () => { @@ -313,13 +303,14 @@ describe('Queue Plugins Utilities', () => { userId: 'test', properties: { test: 'test', + // eslint-disable-next-line compat/compat test1: BigInt(9007199254740991), }, } as unknown as RudderEvent; - validateEventPayloadSize(event, mockLogger); + validateEventPayloadSize(event, defaultLogger); - expect(mockLogger.warn).toHaveBeenCalledWith( + expect(defaultLogger.warn).toHaveBeenCalledWith( 'QueueUtilities:: Failed to validate event payload size. Please make sure that the event payload is within the size limit and is a valid JSON object.', ); }); diff --git a/packages/analytics-js-plugins/__tests__/utilities/retryQueue/RetryQueue.test.ts b/packages/analytics-js-plugins/__tests__/utilities/retryQueue/RetryQueue.test.ts index fba64dc8e4..8787c17838 100644 --- a/packages/analytics-js-plugins/__tests__/utilities/retryQueue/RetryQueue.test.ts +++ b/packages/analytics-js-plugins/__tests__/utilities/retryQueue/RetryQueue.test.ts @@ -1,13 +1,11 @@ /* eslint-disable import/no-extraneous-dependencies */ import { QueueStatuses } from '@rudderstack/analytics-js-common/constants/QueueStatuses'; -import { getStorageEngine } from '@rudderstack/analytics-js/services/StoreManager/storages'; -import { Store, StoreManager } from '@rudderstack/analytics-js/services/StoreManager'; -import { PluginsManager } from '@rudderstack/analytics-js/components/pluginsManager'; -import { defaultPluginEngine } from '@rudderstack/analytics-js/services/PluginEngine'; -import { defaultErrorHandler } from '@rudderstack/analytics-js/services/ErrorHandler'; -import { defaultLogger } from '@rudderstack/analytics-js/services/Logger'; +import { defaultStoreManager } from '@rudderstack/analytics-js-common/__mocks__/StoreManager'; +import { defaultLocalStorage } from '@rudderstack/analytics-js-common/__mocks__/Storage'; +import { Store } from '@rudderstack/analytics-js-common/__mocks__/Store'; import { Schedule } from '../../../src/utilities/retryQueue/Schedule'; import { RetryQueue } from '../../../src/utilities/retryQueue/RetryQueue'; +import type { QueueItem, QueueItemData } from '../../../src/types/plugins'; const size = (queue: RetryQueue): { queue: number; inProgress: number } => ({ queue: queue.store.get(QueueStatuses.QUEUE).length, @@ -16,23 +14,14 @@ const size = (queue: RetryQueue): { queue: number; inProgress: number } => ({ describe('Queue', () => { let queue: RetryQueue; - // let clock: InstalledClock; let schedule: Schedule; - const engine = getStorageEngine('localStorage'); - const defaultPluginsManager = new PluginsManager( - defaultPluginEngine, - defaultErrorHandler, - defaultLogger, - ); - - const defaultStoreManager = new StoreManager(defaultPluginsManager); beforeAll(() => { jest.useFakeTimers(); }); beforeEach(() => { - engine.clear(); + defaultLocalStorage.clear(); schedule = new Schedule(); schedule.now = () => +new window.Date(); @@ -241,7 +230,11 @@ describe('Queue', () => { queue.processQueueCb = mockProcessItemCb; queue.start(); - queue.requeue({ item: 'b', attemptNumber: 0, type: 'Single' }); + queue.requeue({ + item: 'b', + attemptNumber: 0, + type: 'Single', + } as unknown as QueueItem); queue.addItem('a'); expect(queue.processQueueCb).toHaveBeenCalledTimes(1); @@ -257,7 +250,7 @@ describe('Queue', () => { }); it('should respect shouldRetry', () => { - queue.shouldRetry = (_, attemptNumber) => !(attemptNumber > 2); + queue.shouldRetry = (_, attemptNumber) => attemptNumber <= 2; const mockProcessItemCb = jest.fn((_, cb) => cb(new Error('no'))); @@ -266,17 +259,29 @@ describe('Queue', () => { queue.start(); // over maxattempts - queue.requeue({ item: 'b', attemptNumber: 2, type: 'Single' }); + queue.requeue({ + item: 'b', + attemptNumber: 2, + type: 'Single', + } as unknown as QueueItem); jest.advanceTimersByTime(queue.getDelay(3)); expect(queue.processQueueCb).toHaveBeenCalledTimes(0); mockProcessItemCb.mockReset(); - queue.requeue({ item: ['a', 'b'], attemptNumber: 1, type: 'Batch' }); + queue.requeue({ + item: ['a', 'b'], + attemptNumber: 1, + type: 'Batch', + } as unknown as QueueItem); jest.advanceTimersByTime(queue.getDelay(2)); expect(queue.processQueueCb).toHaveBeenCalledTimes(1); mockProcessItemCb.mockReset(); - queue.requeue({ item: 'b', attemptNumber: 2, type: 'Single' }); + queue.requeue({ + item: 'b', + attemptNumber: 2, + type: 'Single', + } as unknown as QueueItem); jest.advanceTimersByTime(queue.getDelay(1)); expect(queue.processQueueCb).toHaveBeenCalledTimes(0); }); @@ -305,10 +310,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, 0); // fake timers starts at time 0 - foundQueue.set(foundQueue.validKeys.QUEUE, [ + foundQueue.set(foundQueue.validKeys.ACK as string, 0); // fake timers starts at time 0 + foundQueue.set(foundQueue.validKeys.QUEUE as string, [ { item: 'a', time: 0, @@ -384,10 +389,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, -15000); - foundQueue.set(foundQueue.validKeys.IN_PROGRESS, { + foundQueue.set(foundQueue.validKeys.ACK as string, -15000); + foundQueue.set(foundQueue.validKeys.IN_PROGRESS as string, { 'task-id-1': { item: 'a', time: 0, @@ -470,10 +475,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, 0); // fake timers starts at time 0 - foundQueue.set(foundQueue.validKeys.BATCH_QUEUE, [ + foundQueue.set(foundQueue.validKeys.ACK as string, 0); // fake timers starts at time 0 + foundQueue.set(foundQueue.validKeys.BATCH_QUEUE as string, [ { item: 'a', time: 0, @@ -514,10 +519,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, 0); // fake timers starts at time 0 - foundQueue.set(foundQueue.validKeys.BATCH_QUEUE, [ + foundQueue.set(foundQueue.validKeys.ACK as string, 0); // fake timers starts at time 0 + foundQueue.set(foundQueue.validKeys.BATCH_QUEUE as string, [ { item: 'a', time: 0, @@ -565,10 +570,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, -15000); - foundQueue.set(foundQueue.validKeys.QUEUE, [ + foundQueue.set(foundQueue.validKeys.ACK as string, -15000); + foundQueue.set(foundQueue.validKeys.QUEUE as string, [ { item: 'a', time: 0, @@ -603,10 +608,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, -15000); - foundQueue.set(foundQueue.validKeys.IN_PROGRESS, { + foundQueue.set(foundQueue.validKeys.ACK as string, -15000); + foundQueue.set(foundQueue.validKeys.IN_PROGRESS as string, { 'task-id-0': { item: 'a', time: 0, @@ -641,10 +646,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, -15000); - foundQueue.set(foundQueue.validKeys.BATCH_QUEUE, [ + foundQueue.set(foundQueue.validKeys.ACK as string, -15000); + foundQueue.set(foundQueue.validKeys.BATCH_QUEUE as string, [ { item: 'a', time: 0, @@ -679,10 +684,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, -15000); - foundQueue.set(foundQueue.validKeys.IN_PROGRESS, { + foundQueue.set(foundQueue.validKeys.ACK as string, -15000); + foundQueue.set(foundQueue.validKeys.IN_PROGRESS as string, { 'task-id-0': { item: 'a', time: 0, @@ -697,7 +702,7 @@ describe('Queue', () => { }, }); - foundQueue.set(foundQueue.validKeys.QUEUE, [ + foundQueue.set(foundQueue.validKeys.QUEUE as string, [ { item: 'a', time: 0, @@ -712,7 +717,7 @@ describe('Queue', () => { }, ]); - foundQueue.set(foundQueue.validKeys.BATCH_QUEUE, [ + foundQueue.set(foundQueue.validKeys.BATCH_QUEUE as string, [ { item: 'c', time: 0, @@ -749,10 +754,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, -15000); - foundQueue.set(foundQueue.validKeys.IN_PROGRESS, { + foundQueue.set(foundQueue.validKeys.ACK as string, -15000); + foundQueue.set(foundQueue.validKeys.IN_PROGRESS as string, { 'task-id-0': { item: 'a', time: 0, @@ -765,7 +770,7 @@ describe('Queue', () => { }, }); - foundQueue.set(foundQueue.validKeys.QUEUE, [ + foundQueue.set(foundQueue.validKeys.QUEUE as string, [ { item: 'a', time: 0, @@ -798,24 +803,24 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, -15000); - foundQueue.set(foundQueue.validKeys.QUEUE, [ + foundQueue.set(foundQueue.validKeys.ACK as string, -15000); + foundQueue.set(foundQueue.validKeys.QUEUE as string, [ { item: 'a', time: 0, attemptNumber: 0, }, ]); - foundQueue.set(foundQueue.validKeys.IN_PROGRESS, { + foundQueue.set(foundQueue.validKeys.IN_PROGRESS as string, { 'task-id': { item: 'b', time: 1, attemptNumber: 0, }, }); - foundQueue.set(foundQueue.validKeys.BATCH_QUEUE, { + foundQueue.set(foundQueue.validKeys.BATCH_QUEUE as string, { 'task-id2': { item: 'c', time: 1, @@ -850,10 +855,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, 0); // fake timers starts at time 0 - foundQueue.set(foundQueue.validKeys.QUEUE, [ + foundQueue.set(foundQueue.validKeys.ACK as string, 0); // fake timers starts at time 0 + foundQueue.set(foundQueue.validKeys.QUEUE as string, [ { item: 'a', time: 0, @@ -887,10 +892,10 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, -15000); - foundQueue.set(foundQueue.validKeys.IN_PROGRESS, { + foundQueue.set(foundQueue.validKeys.ACK as string, -15000); + foundQueue.set(foundQueue.validKeys.IN_PROGRESS as string, { 'task-id': { item: 'a', time: 0, @@ -924,17 +929,17 @@ describe('Queue', () => { id: 'fake-id', validKeys: QueueStatuses, }, - getStorageEngine('localStorage'), + defaultLocalStorage, ); - foundQueue.set(foundQueue.validKeys.ACK, -15000); - foundQueue.set(foundQueue.validKeys.QUEUE, [ + foundQueue.set(foundQueue.validKeys.ACK as string, -15000); + foundQueue.set(foundQueue.validKeys.QUEUE as string, [ { item: 'a', time: 0, attemptNumber: 0, }, ]); - foundQueue.set(foundQueue.validKeys.IN_PROGRESS, { + foundQueue.set(foundQueue.validKeys.IN_PROGRESS as string, { 'task-id': { item: 'b', time: 1, @@ -975,10 +980,10 @@ describe('Queue', () => { queue.maxAttempts = 2; queue.processQueueCb = (item, done) => { - if (!calls[item.index]) { - calls[item.index] = 1; + if (!calls[(item as Record).index]) { + calls[(item as Record).index] = 1; } else { - calls[item.index]++; + calls[(item as Record).index]++; } done(new Error()); @@ -997,7 +1002,7 @@ describe('Queue', () => { }); it('should limit inProgress using maxItems', () => { - const waiting: Function[] = []; + const waiting: (() => void)[] = []; let i; queue.maxItems = 100; @@ -1031,7 +1036,7 @@ describe('Queue', () => { // resolved all waiting items while (waiting.length > 0) { - waiting.pop()(); + waiting.pop()?.(); } // inProgress should now be empty @@ -1050,6 +1055,7 @@ describe('Queue', () => { let batchQueue = new RetryQueue( 'batchQueue', { + // @ts-expect-error testing invalid options batch: {}, }, () => {}, @@ -1064,6 +1070,7 @@ describe('Queue', () => { batch: { enabled: true, maxSize: 1024, + // @ts-expect-error testing invalid options maxItems: '1', }, }, @@ -1083,6 +1090,7 @@ describe('Queue', () => { { batch: { enabled: true, + // @ts-expect-error testing invalid options maxSize: '3', maxItems: 20, }, @@ -1205,14 +1213,6 @@ describe('Queue', () => { describe('end-to-end', () => { let queue: RetryQueue; - const defaultPluginsManager = new PluginsManager( - defaultPluginEngine, - defaultErrorHandler, - defaultLogger, - ); - - const defaultStoreManager = new StoreManager(defaultPluginsManager); - beforeEach(() => { queue = new RetryQueue( 'e2e_test', diff --git a/packages/analytics-js-plugins/__tests__/xhrQueue/index.test.ts b/packages/analytics-js-plugins/__tests__/xhrQueue/index.test.ts index 360f5ff5e2..2bfdf81e5e 100644 --- a/packages/analytics-js-plugins/__tests__/xhrQueue/index.test.ts +++ b/packages/analytics-js-plugins/__tests__/xhrQueue/index.test.ts @@ -1,18 +1,17 @@ /* eslint-disable import/no-extraneous-dependencies */ import { batch } from '@preact/signals-core'; -import { HttpClient } from '@rudderstack/analytics-js/services/HttpClient'; -import { state } from '@rudderstack/analytics-js/state'; import { mergeDeepRight } from '@rudderstack/analytics-js-common/utilities/object'; -import { PluginsManager } from '@rudderstack/analytics-js/components/pluginsManager'; -import { defaultPluginEngine } from '@rudderstack/analytics-js/services/PluginEngine'; -import { defaultErrorHandler } from '@rudderstack/analytics-js/services/ErrorHandler'; -import { defaultLogger } from '@rudderstack/analytics-js/services/Logger'; -import { StoreManager } from '@rudderstack/analytics-js/services/StoreManager'; +import { defaultStoreManager } from '@rudderstack/analytics-js-common/__mocks__/StoreManager'; import type { RudderEvent } from '@rudderstack/analytics-js-common/types/Event'; -import type { ILogger } from '@rudderstack/analytics-js-common/types/Logger'; -import type { IHttpClient } from '@rudderstack/analytics-js-common/types/HttpClient'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import { defaultErrorHandler } from '@rudderstack/analytics-js-common/__mocks__/ErrorHandler'; +import type { ExtensionPoint } from '@rudderstack/analytics-js-common/types/PluginEngine'; +import type { RetryQueue } from '../../src/utilities/retryQueue/RetryQueue'; +import type { QueueItem, QueueItemData } from '../../src/types/plugins'; +import { resetState, state } from '../../__mocks__/state'; import { XhrQueue } from '../../src/xhrQueue'; import { Schedule } from '../../src/utilities/retryQueue/Schedule'; +import { defaultHttpClient } from '../../__mocks__/HttpClient'; jest.mock('@rudderstack/analytics-js-common/utilities/timestamp', () => ({ ...jest.requireActual('@rudderstack/analytics-js-common/utilities/timestamp'), @@ -25,19 +24,8 @@ jest.mock('@rudderstack/analytics-js-common/utilities/uuId', () => ({ })); describe('XhrQueue', () => { - const defaultPluginsManager = new PluginsManager( - defaultPluginEngine, - defaultErrorHandler, - defaultLogger, - ); - - const defaultStoreManager = new StoreManager(defaultPluginsManager); - - const mockLogger = { - error: jest.fn(), - } as unknown as ILogger; - beforeAll(() => { + resetState(); batch(() => { state.lifecycle.writeKey.value = 'sampleWriteKey'; state.lifecycle.activeDataplaneUrl.value = 'https://sampleurl.com'; @@ -51,33 +39,35 @@ describe('XhrQueue', () => { }); }); - const httpClient = new HttpClient(); - it('should add itself to the loaded plugins list on initialized', () => { - XhrQueue().initialize(state); + XhrQueue()?.initialize?.(state); expect(state.plugins.loadedPlugins.value).toContain('XhrQueue'); }); it('should return a queue object on init', () => { - const queue = XhrQueue().dataplaneEventsQueue?.init( + const queue = (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).init?.( state, - httpClient, + defaultHttpClient, defaultStoreManager, defaultErrorHandler, defaultLogger, - ); + ) as RetryQueue; expect(queue).toBeDefined(); expect(queue.name).toBe('rudder_sampleWriteKey'); }); it('should add item in queue on enqueue', () => { - const queue = XhrQueue().dataplaneEventsQueue?.init(state, httpClient, defaultStoreManager); + const queue = (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).init?.( + state, + defaultHttpClient, + defaultStoreManager, + ) as RetryQueue; const addItemSpy = jest.spyOn(queue, 'addItem'); - const event: RudderEvent = { + const event = { type: 'track', event: 'test', userId: 'test', @@ -87,11 +77,11 @@ describe('XhrQueue', () => { anonymousId: 'sampleAnonId', messageId: 'test', originalTimestamp: 'test', - }; + } as unknown as RudderEvent; - XhrQueue().dataplaneEventsQueue?.enqueue(state, queue, event); + (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).enqueue?.(state, queue, event); - expect(addItemSpy).toBeCalledWith({ + expect(addItemSpy).toHaveBeenCalledWith({ url: 'https://sampleurl.com/v1/track', headers: { AnonymousId: 'c2FtcGxlQW5vbklk', // Base64 encoded anonymousId @@ -103,15 +93,18 @@ describe('XhrQueue', () => { }); it('should process queue item on start', () => { - const mockHttpClient = { - getAsyncData: ({ callback }) => { - callback(true); - }, - setAuthHeader: jest.fn(), - }; - const queue = XhrQueue().dataplaneEventsQueue?.init(state, mockHttpClient, defaultStoreManager); + // Mock getAsyncData to return a successful response - const event: RudderEvent = { + defaultHttpClient.getAsyncData.mockImplementation(({ callback }) => { + callback?.(true); + }); + const queue = (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).init?.( + state, + defaultHttpClient, + defaultStoreManager, + ) as RetryQueue; + + const event = { type: 'track', event: 'test', userId: 'test', @@ -121,17 +114,17 @@ describe('XhrQueue', () => { anonymousId: 'sampleAnonId', messageId: 'test', originalTimestamp: 'test', - }; + } as unknown as RudderEvent; const queueProcessCbSpy = jest.spyOn(queue, 'processQueueCb'); - XhrQueue().dataplaneEventsQueue?.enqueue(state, queue, event); + (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).enqueue?.(state, queue, event); // Explicitly start the queue to process the item // In actual implementation, this is done based on the state signals queue.start(); - expect(queueProcessCbSpy).toBeCalledWith( + expect(queueProcessCbSpy).toHaveBeenCalledWith( { url: 'https://sampleurl.com/v1/track', headers: { @@ -146,26 +139,24 @@ describe('XhrQueue', () => { ); // Item is successfully processed and removed from queue - expect(queue.getStorageEntry('queue').length).toBe(0); + expect((queue.getStorageEntry('queue') as QueueItem[]).length).toBe(0); queueProcessCbSpy.mockRestore(); }); it('should log error on retryable failure and requeue the item', () => { - const mockHttpClient = { - getAsyncData: ({ callback }) => { - callback(false, { error: 'some error', xhr: { status: 429 } }); - }, - setAuthHeader: jest.fn(), - } as unknown as IHttpClient; + // Mock getAsyncData to return a retryable failure - const queue = XhrQueue().dataplaneEventsQueue?.init( + defaultHttpClient.getAsyncData.mockImplementation(({ callback }) => { + callback?.(false, { error: 'some error', xhr: { status: 429 } }); + }); + const queue = (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).init?.( state, - mockHttpClient, + defaultHttpClient, defaultStoreManager, undefined, - mockLogger, - ); + defaultLogger, + ) as RetryQueue; const schedule = new Schedule(); // Override the timestamp generation function to return a fixed value @@ -173,7 +164,7 @@ describe('XhrQueue', () => { queue.schedule = schedule; - const event: RudderEvent = { + const event = { type: 'track', event: 'test', userId: 'test', @@ -183,15 +174,15 @@ describe('XhrQueue', () => { anonymousId: 'sampleAnonId', messageId: 'test', originalTimestamp: 'test', - }; + } as unknown as RudderEvent; - XhrQueue().dataplaneEventsQueue?.enqueue(state, queue, event); + (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).enqueue?.(state, queue, event); // Explicitly start the queue to process the item // In actual implementation, this is done based on the state signals queue.start(); - expect(mockLogger.error).toBeCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'XhrQueuePlugin:: Failed to deliver event(s) to https://sampleurl.com/v1/track. It/they will be retried.', ); @@ -229,18 +220,13 @@ describe('XhrQueue', () => { }; }); - const mockHttpClient = { - getAsyncData: jest.fn(), - setAuthHeader: jest.fn(), - } as unknown as IHttpClient; - - const queue = XhrQueue().dataplaneEventsQueue?.init( + const queue = (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).init?.( state, - mockHttpClient, + defaultHttpClient, defaultStoreManager, undefined, - mockLogger, - ); + defaultLogger, + ) as RetryQueue; const queueProcessCbSpy = jest.spyOn(queue, 'processQueueCb'); const schedule = new Schedule(); @@ -249,7 +235,7 @@ describe('XhrQueue', () => { queue.schedule = schedule; - const event: RudderEvent = { + const event = { type: 'track', event: 'test', userId: 'test', @@ -259,9 +245,9 @@ describe('XhrQueue', () => { anonymousId: 'sampleAnonId', messageId: 'test', originalTimestamp: 'test', - }; + } as unknown as RudderEvent; - const event2: RudderEvent = { + const event2 = { type: 'track', event: 'test2', userId: 'test2', @@ -271,16 +257,16 @@ describe('XhrQueue', () => { anonymousId: 'sampleAnonId', messageId: 'test2', originalTimestamp: 'test2', - }; + } as unknown as RudderEvent; - XhrQueue().dataplaneEventsQueue?.enqueue(state, queue, event); - XhrQueue().dataplaneEventsQueue?.enqueue(state, queue, event2); + (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).enqueue?.(state, queue, event); + (XhrQueue()?.dataplaneEventsQueue as ExtensionPoint).enqueue?.(state, queue, event2); // Explicitly start the queue to process the item // In actual implementation, this is done based on the state signals queue.start(); - expect(queueProcessCbSpy).toBeCalledWith( + expect(queueProcessCbSpy).toHaveBeenCalledWith( [ { url: 'https://sampleurl.com/v1/track', @@ -303,7 +289,7 @@ describe('XhrQueue', () => { true, ); - expect(mockHttpClient.getAsyncData).toBeCalledWith({ + expect(defaultHttpClient.getAsyncData).toHaveBeenCalledWith({ url: 'https://sampleurl.com/v1/batch', options: { method: 'POST', diff --git a/packages/analytics-js-plugins/__tests__/xhrQueue/utilities.test.ts b/packages/analytics-js-plugins/__tests__/xhrQueue/utilities.test.ts index 9b1a15bdf4..c8a4957f3f 100644 --- a/packages/analytics-js-plugins/__tests__/xhrQueue/utilities.test.ts +++ b/packages/analytics-js-plugins/__tests__/xhrQueue/utilities.test.ts @@ -1,8 +1,8 @@ import type { RudderEvent } from '@rudderstack/analytics-js-common/types/Event'; import type { ResponseDetails } from '@rudderstack/analytics-js-common/types/HttpClient'; -import type { ILogger } from '@rudderstack/analytics-js-common/types/Logger'; -import { state, resetState } from '@rudderstack/analytics-js/state'; import { getCurrentTimeFormatted } from '@rudderstack/analytics-js-common/utilities/timestamp'; +import { defaultLogger } from '@rudderstack/analytics-js-common/__mocks__/Logger'; +import type { ApiObject } from '@rudderstack/analytics-js-common/types/ApiObject'; import { getNormalizedQueueOptions, getDeliveryUrl, @@ -10,18 +10,14 @@ import { logErrorOnFailure, getRequestInfo, getBatchDeliveryPayload, -} from '@rudderstack/analytics-js-plugins/xhrQueue/utilities'; +} from '../../src/xhrQueue/utilities'; +import { resetState, state } from '../../__mocks__/state'; jest.mock('@rudderstack/analytics-js-common/utilities/timestamp', () => ({ getCurrentTimeFormatted: () => '2021-01-01T00:00:00.000Z', })); describe('xhrQueue Plugin Utilities', () => { - const mockLogger = { - error: jest.fn(), - warn: jest.fn(), - } as unknown as ILogger; - describe('getNormalizedQueueOptions', () => { it('should return default queue options if input queue options is empty object', () => { const queueOptions = getNormalizedQueueOptions({}); @@ -36,6 +32,7 @@ describe('xhrQueue Plugin Utilities', () => { }); it('should return default queue options if input queue options is null', () => { + // @ts-expect-error Testing for null const queueOptions = getNormalizedQueueOptions(null); expect(queueOptions).toEqual({ @@ -48,6 +45,7 @@ describe('xhrQueue Plugin Utilities', () => { }); it('should return default queue options if input queue options is undefined', () => { + // @ts-expect-error Testing for undefined const queueOptions = getNormalizedQueueOptions(undefined); expect(queueOptions).toEqual({ @@ -122,9 +120,9 @@ describe('xhrQueue Plugin Utilities', () => { response: {}, } as ResponseDetails; - logErrorOnFailure(details, 'https://test.com/v1/page', false, 1, 10, mockLogger); + logErrorOnFailure(details, 'https://test.com/v1/page', false, 1, 10, defaultLogger); - expect(mockLogger.error).not.toBeCalled(); + expect(defaultLogger.error).not.toHaveBeenCalled(); }); it('should log an error for delivery failure', () => { @@ -132,9 +130,9 @@ describe('xhrQueue Plugin Utilities', () => { error: {}, } as ResponseDetails; - logErrorOnFailure(details, 'https://test.com/v1/page', false, 1, 10, mockLogger); + logErrorOnFailure(details, 'https://test.com/v1/page', false, 1, 10, defaultLogger); - expect(mockLogger.error).toBeCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'XhrQueuePlugin:: Failed to deliver event(s) to https://test.com/v1/page. The event(s) will be dropped.', ); }); @@ -147,54 +145,59 @@ describe('xhrQueue Plugin Utilities', () => { }, } as ResponseDetails; - logErrorOnFailure(details, 'https://test.com/v1/page', true, 1, 10, mockLogger); + logErrorOnFailure(details, 'https://test.com/v1/page', true, 1, 10, defaultLogger); - expect(mockLogger.error).toBeCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'XhrQueuePlugin:: Failed to deliver event(s) to https://test.com/v1/page. It/they will be retried. Retry attempt 1 of 10.', ); // Retryable error but it's the first attempt - details.xhr.status = 429; + // @ts-expect-error Needed to set the status for testing + (details.xhr as XMLHttpRequest).status = 429; - logErrorOnFailure(details, 'https://test.com/v1/page', true, 0, 10, mockLogger); + logErrorOnFailure(details, 'https://test.com/v1/page', true, 0, 10, defaultLogger); - expect(mockLogger.error).toBeCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'XhrQueuePlugin:: Failed to deliver event(s) to https://test.com/v1/page. It/they will be retried.', ); // 500 error - details.xhr.status = 500; + // @ts-expect-error Needed to set the status for testing + (details.xhr as XMLHttpRequest).status = 500; - logErrorOnFailure(details, 'https://test.com/v1/page', true, 1, 10, mockLogger); + logErrorOnFailure(details, 'https://test.com/v1/page', true, 1, 10, defaultLogger); - expect(mockLogger.error).toBeCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'XhrQueuePlugin:: Failed to deliver event(s) to https://test.com/v1/page. It/they will be retried. Retry attempt 1 of 10.', ); // 5xx error - details.xhr.status = 501; + // @ts-expect-error Needed to set the status for testing + (details.xhr as XMLHttpRequest).status = 501; - logErrorOnFailure(details, 'https://test.com/v1/page', true, 1, 10, mockLogger); + logErrorOnFailure(details, 'https://test.com/v1/page', true, 1, 10, defaultLogger); - expect(mockLogger.error).toBeCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'XhrQueuePlugin:: Failed to deliver event(s) to https://test.com/v1/page. It/they will be retried. Retry attempt 1 of 10.', ); // 600 error - details.xhr.status = 600; + // @ts-expect-error Needed to set the status for testing + (details.xhr as XMLHttpRequest).status = 600; - logErrorOnFailure(details, 'https://test.com/v1/page', true, 1, 10, mockLogger); + logErrorOnFailure(details, 'https://test.com/v1/page', true, 1, 10, defaultLogger); - expect(mockLogger.error).toBeCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'XhrQueuePlugin:: Failed to deliver event(s) to https://test.com/v1/page. The event(s) will be dropped.', ); // Retryable error but exhausted all tries - details.xhr.status = 520; + // @ts-expect-error Needed to set the status for testing + (details.xhr as XMLHttpRequest).status = 520; - logErrorOnFailure(details, 'https://test.com/v1/page', false, 10, 10, mockLogger); + logErrorOnFailure(details, 'https://test.com/v1/page', false, 10, 10, defaultLogger); - expect(mockLogger.error).toBeCalledWith( + expect(defaultLogger.error).toHaveBeenCalledWith( 'XhrQueuePlugin:: Failed to deliver event(s) to https://test.com/v1/page. Retries exhausted (10). The event(s) will be dropped.', ); }); @@ -219,7 +222,7 @@ describe('xhrQueue Plugin Utilities', () => { }, }; - const requestInfo = getRequestInfo(queueItemData, state, mockLogger); + const requestInfo = getRequestInfo(queueItemData, state, defaultLogger); expect(requestInfo).toEqual({ url: 'https://test.com/v1/track', @@ -260,7 +263,7 @@ describe('xhrQueue Plugin Utilities', () => { state.lifecycle.activeDataplaneUrl.value = 'https://test.dataplaneurl.com/'; - const requestInfo = getRequestInfo(queueItemData, state, mockLogger); + const requestInfo = getRequestInfo(queueItemData, state, defaultLogger); expect(requestInfo).toEqual({ url: 'https://test.dataplaneurl.com/v1/batch', @@ -294,7 +297,7 @@ describe('xhrQueue Plugin Utilities', () => { } as unknown as RudderEvent, ]; - expect(getBatchDeliveryPayload(events, currentTime, mockLogger)).toBe( + expect(getBatchDeliveryPayload(events, currentTime, defaultLogger)).toBe( '{"batch":[{"channel":"test","type":"track","anonymousId":"test","properties":{"test":"test"}},{"channel":"test","type":"track","anonymousId":"test","properties":{"test1":"test1"}}],"sentAt":"2021-01-01T00:00:00.000Z"}', ); }); @@ -324,13 +327,13 @@ describe('xhrQueue Plugin Utilities', () => { }, } as unknown as RudderEvent, ]; - expect(getBatchDeliveryPayload(events, currentTime, mockLogger)).toBe( + expect(getBatchDeliveryPayload(events, currentTime, defaultLogger)).toBe( '{"batch":[{"channel":"test","type":"track","anonymousId":"test","properties":{"test":"test"}},{"channel":"test","type":"track","anonymousId":"test","properties":{"test1":"test1","test3":{}}}],"sentAt":"2021-01-01T00:00:00.000Z"}', ); }); it('should return string with circular dependencies replaced with static string', () => { - const events = [ + const events: RudderEvent[] = [ { channel: 'test', type: 'track', @@ -354,10 +357,13 @@ describe('xhrQueue Plugin Utilities', () => { }, } as unknown as RudderEvent, ]; + const event2 = events[1] as RudderEvent; - events[1].properties.test5 = events[1]; + // Create a circular reference + // @ts-expect-error Testing for circular reference + (event2.properties as ApiObject).test5 = event2; - expect(getBatchDeliveryPayload(events, currentTime, mockLogger)).toContain( + expect(getBatchDeliveryPayload(events, currentTime, defaultLogger)).toContain( '[Circular Reference]', ); }); @@ -382,7 +388,7 @@ describe('xhrQueue Plugin Utilities', () => { } as unknown as RudderEvent, ]; - expect(getBatchDeliveryPayload(events, currentTime, mockLogger)).toBeNull(); + expect(getBatchDeliveryPayload(events, currentTime, defaultLogger)).toBeNull(); }); }); }); diff --git a/packages/analytics-js-plugins/package.json b/packages/analytics-js-plugins/package.json index c9aa047025..d40b626bfa 100644 --- a/packages/analytics-js-plugins/package.json +++ b/packages/analytics-js-plugins/package.json @@ -1,6 +1,6 @@ { "name": "@rudderstack/analytics-js-plugins", - "version": "3.6.18", + "version": "3.6.20", "private": true, "description": "RudderStack JavaScript SDK plugins", "main": "dist/npm/modern/cjs/index.cjs", diff --git a/packages/analytics-js-plugins/project.json b/packages/analytics-js-plugins/project.json index 806a31ff27..5d1c6afbc6 100644 --- a/packages/analytics-js-plugins/project.json +++ b/packages/analytics-js-plugins/project.json @@ -51,9 +51,9 @@ "github": { "executor": "@jscutlery/semver:github", "options": { - "tag": "@rudderstack/analytics-js-plugins@3.6.18", - "title": "@rudderstack/analytics-js-plugins@3.6.18", - "discussion-category": "@rudderstack/analytics-js-plugins@3.6.18", + "tag": "@rudderstack/analytics-js-plugins@3.6.20", + "title": "@rudderstack/analytics-js-plugins@3.6.20", + "discussion-category": "@rudderstack/analytics-js-plugins@3.6.20", "notesFile": "./packages/analytics-js-plugins/CHANGELOG_LATEST.md" } } diff --git a/packages/analytics-js-plugins/src/bugsnag/constants.ts b/packages/analytics-js-plugins/src/bugsnag/constants.ts index 3140ca74eb..5b45e385e7 100644 --- a/packages/analytics-js-plugins/src/bugsnag/constants.ts +++ b/packages/analytics-js-plugins/src/bugsnag/constants.ts @@ -31,7 +31,7 @@ const APP_STATE_EXCLUDE_KEYS = [ 'instance', // destination instance objects 'eventBuffer', // pre-load event buffer (may contain PII) 'traits', - 'authToken' + 'authToken', ]; const BUGSNAG_PLUGIN = 'BugsnagPlugin'; diff --git a/packages/analytics-js-plugins/src/bugsnag/utils.ts b/packages/analytics-js-plugins/src/bugsnag/utils.ts index 135054ef83..e1c159dcae 100644 --- a/packages/analytics-js-plugins/src/bugsnag/utils.ts +++ b/packages/analytics-js-plugins/src/bugsnag/utils.ts @@ -136,7 +136,8 @@ const getNewClient = (state: ApplicationState, logger?: ILogger): BugsnagLib.Cli maxBreadcrumbs: 40, releaseStage: getReleaseStage(), user: { - id: state.source.value?.id || state.lifecycle.writeKey.value, + // Combination of source, session and visit ids + id: `${state.source.value?.id ?? (state.lifecycle.writeKey.value as string)}..${state.session.sessionInfo.value?.id ?? 'NA'}..${state.autoTrack?.pageLifecycle?.visitId?.value ?? 'NA'}`, }, logger, networkBreadcrumbsEnabled: false, diff --git a/packages/analytics-js-plugins/src/deviceModeDestinations/utils.ts b/packages/analytics-js-plugins/src/deviceModeDestinations/utils.ts index 4855302afb..2e615ce2b9 100644 --- a/packages/analytics-js-plugins/src/deviceModeDestinations/utils.ts +++ b/packages/analytics-js-plugins/src/deviceModeDestinations/utils.ts @@ -50,9 +50,7 @@ const isDestinationSDKMounted = ( logger?: ILogger, ): boolean => Boolean( - (globalThis as any)[destSDKIdentifier] && - (globalThis as any)[destSDKIdentifier][sdkTypeName] && - (globalThis as any)[destSDKIdentifier][sdkTypeName].prototype && + (globalThis as any)[destSDKIdentifier]?.[sdkTypeName]?.prototype && typeof (globalThis as any)[destSDKIdentifier][sdkTypeName].prototype.constructor !== 'undefined', ); diff --git a/packages/analytics-js-plugins/src/errorReporting/constants.ts b/packages/analytics-js-plugins/src/errorReporting/constants.ts index c01a6d056a..6fa61398c0 100644 --- a/packages/analytics-js-plugins/src/errorReporting/constants.ts +++ b/packages/analytics-js-plugins/src/errorReporting/constants.ts @@ -17,7 +17,7 @@ const APP_STATE_EXCLUDE_KEYS = [ 'instance', // destination instance objects 'eventBuffer', // pre-load event buffer (may contain PII) 'traits', - 'authToken' + 'authToken', ]; const REQUEST_TIMEOUT_MS = 10 * 1000; // 10 seconds const NOTIFIER_NAME = 'RudderStack JavaScript SDK Error Notifier'; diff --git a/packages/analytics-js-plugins/src/errorReporting/utils.ts b/packages/analytics-js-plugins/src/errorReporting/utils.ts index ced6d752b6..ef8fadc3bc 100644 --- a/packages/analytics-js-plugins/src/errorReporting/utils.ts +++ b/packages/analytics-js-plugins/src/errorReporting/utils.ts @@ -132,7 +132,8 @@ const getBugsnagErrorEvent = ( }, }, user: { - id: state.source.value?.id ?? (state.lifecycle.writeKey.value as string), + // Combination of source, session and visit ids + id: `${state.source.value?.id ?? (state.lifecycle.writeKey.value as string)}..${state.session.sessionInfo.value?.id ?? 'NA'}..${state.autoTrack?.pageLifecycle?.visitId?.value ?? 'NA'}`, }, }, ], diff --git a/packages/analytics-js-plugins/src/iubendaConsentManager/constants.ts b/packages/analytics-js-plugins/src/iubendaConsentManager/constants.ts index b54a9bd668..0d7ea84cf4 100644 --- a/packages/analytics-js-plugins/src/iubendaConsentManager/constants.ts +++ b/packages/analytics-js-plugins/src/iubendaConsentManager/constants.ts @@ -1,4 +1,8 @@ const IUBENDA_CONSENT_MANAGER_PLUGIN = 'IubendaConsentManagerPlugin'; const IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME = '_iub_cs-252372'; const IUBENDA_CONSENT_COOKIE_NAME_PATTERN = /^_iub_cs-\d+$/; -export { IUBENDA_CONSENT_MANAGER_PLUGIN, IUBENDA_CONSENT_COOKIE_NAME_PATTERN, IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME }; +export { + IUBENDA_CONSENT_MANAGER_PLUGIN, + IUBENDA_CONSENT_COOKIE_NAME_PATTERN, + IUBENDA_CONSENT_EXAMPLE_COOKIE_NAME, +}; diff --git a/packages/analytics-js-plugins/src/iubendaConsentManager/types.ts b/packages/analytics-js-plugins/src/iubendaConsentManager/types.ts index 86454b83b5..efc27b37b7 100644 --- a/packages/analytics-js-plugins/src/iubendaConsentManager/types.ts +++ b/packages/analytics-js-plugins/src/iubendaConsentManager/types.ts @@ -1,16 +1,15 @@ - export type IubendaConsentCookieData = { - timestamp: string; // ISO 8601 format date string - version: string; // Version number in string format - purposes: IubendaConsentData; // Object holding purpose consent data - id: number; // Unique ID number - cons: Consent; // Additional consent details + timestamp: string; // ISO 8601 format date string + version: string; // Version number in string format + purposes: IubendaConsentData; // Object holding purpose consent data + id: number; // Unique ID number + cons: Consent; // Additional consent details }; export type IubendaConsentData = { - [purposeId: string]: boolean; + [purposeId: string]: boolean; }; export type Consent = { - rand: string; // A random string associated with consent -}; \ No newline at end of file + rand: string; // A random string associated with consent +}; diff --git a/packages/analytics-js-service-worker/CHANGELOG.md b/packages/analytics-js-service-worker/CHANGELOG.md index 6896172252..09f57055b5 100644 --- a/packages/analytics-js-service-worker/CHANGELOG.md +++ b/packages/analytics-js-service-worker/CHANGELOG.md @@ -2,6 +2,11 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [3.2.17](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-service-worker@3.2.16...@rudderstack/analytics-js-service-worker@3.2.17) (2024-12-17) + +### Dependency Updates + +* `@rudderstack/analytics-js-common` updated to version `3.14.14` ## [3.2.16](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-service-worker@3.2.15...@rudderstack/analytics-js-service-worker@3.2.16) (2024-12-06) ### Dependency Updates diff --git a/packages/analytics-js-service-worker/CHANGELOG_LATEST.md b/packages/analytics-js-service-worker/CHANGELOG_LATEST.md index b944464104..5d53b24f3b 100644 --- a/packages/analytics-js-service-worker/CHANGELOG_LATEST.md +++ b/packages/analytics-js-service-worker/CHANGELOG_LATEST.md @@ -1,5 +1,5 @@ -## [3.2.16](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-service-worker@3.2.15...@rudderstack/analytics-js-service-worker@3.2.16) (2024-12-06) +## [3.2.17](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-service-worker@3.2.16...@rudderstack/analytics-js-service-worker@3.2.17) (2024-12-17) ### Dependency Updates -* `@rudderstack/analytics-js-common` updated to version `3.14.13` +* `@rudderstack/analytics-js-common` updated to version `3.14.14` diff --git a/packages/analytics-js-service-worker/LICENSE.md b/packages/analytics-js-service-worker/LICENSE.md index 554bb72539..37517857b4 100644 --- a/packages/analytics-js-service-worker/LICENSE.md +++ b/packages/analytics-js-service-worker/LICENSE.md @@ -40,14 +40,14 @@ As far as the law allows, the software comes as is, without any warranty or cond ## Definitions -The *licensor* is the entity offering these terms, and the *software* is the software the licensor makes available under these terms, including any portion of it. +The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it. -*you* refers to the individual or entity agreeing to these terms. +_you_ refers to the individual or entity agreeing to these terms. -*your company* is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. *control* means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. +_your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. -*your licenses* are all the licenses granted to you for the software under these terms. +_your licenses_ are all the licenses granted to you for the software under these terms. -*use* means anything you do with the software requiring one of your licenses. +_use_ means anything you do with the software requiring one of your licenses. -*trademark* means trademarks, service marks, and similar rights. +_trademark_ means trademarks, service marks, and similar rights. diff --git a/packages/analytics-js-service-worker/__tests__/Analytics.test.ts b/packages/analytics-js-service-worker/__tests__/Analytics.test.ts index 8b00a76318..905460d185 100644 --- a/packages/analytics-js-service-worker/__tests__/Analytics.test.ts +++ b/packages/analytics-js-service-worker/__tests__/Analytics.test.ts @@ -67,7 +67,7 @@ describe('JS SDK Service Worker', () => { }).toThrow('The provided data plane URL "dummy" is invalid.'); }); - it('Should initialise with correct values', () => { + it('should initialise with correct values', () => { expect(rudderAnalyticsClient.writeKey).toBe(dummyWriteKey); expect(rudderAnalyticsClient.host).toBe('https://dummy.dataplane.host.com/v1/batch'); expect(rudderAnalyticsClient.timeout).toBe(undefined); @@ -78,7 +78,7 @@ describe('JS SDK Service Worker', () => { expect(rudderAnalyticsClient.enable).toBe(dummyInitOptions.enable); }); - it('Should record identify', done => { + it('should record identify', done => { rudderAnalyticsClient.identify(identifyRequestPayload); rudderAnalyticsClient.flush(); setTimeout(() => { @@ -87,7 +87,7 @@ describe('JS SDK Service Worker', () => { }, 10); }); - it('Should record track', done => { + it('should record track', done => { rudderAnalyticsClient.track(trackRequestPayload); rudderAnalyticsClient.flush(); setTimeout(() => { @@ -96,7 +96,7 @@ describe('JS SDK Service Worker', () => { }, 10); }); - it('Should record page', done => { + it('should record page', done => { rudderAnalyticsClient.page(pageRequestPayload); rudderAnalyticsClient.flush(); @@ -106,7 +106,7 @@ describe('JS SDK Service Worker', () => { }, 10); }); - it('Should record screen', done => { + it('should record screen', done => { rudderAnalyticsClient.screen(screenRequestPayload); rudderAnalyticsClient.flush(); @@ -116,7 +116,7 @@ describe('JS SDK Service Worker', () => { }, 10); }); - it('Should record group', done => { + it('should record group', done => { rudderAnalyticsClient.group(groupRequestPayload); rudderAnalyticsClient.flush(); @@ -126,7 +126,7 @@ describe('JS SDK Service Worker', () => { }, 10); }); - it('Should record alias', done => { + it('should record alias', done => { rudderAnalyticsClient.alias(aliasRequestPayload); rudderAnalyticsClient.flush(); diff --git a/packages/analytics-js-service-worker/package.json b/packages/analytics-js-service-worker/package.json index 78f6ec934c..382dc8efde 100644 --- a/packages/analytics-js-service-worker/package.json +++ b/packages/analytics-js-service-worker/package.json @@ -1,6 +1,6 @@ { "name": "@rudderstack/analytics-js-service-worker", - "version": "3.2.16", + "version": "3.2.17", "description": "RudderStack JavaScript Service Worker SDK", "main": "dist/npm/modern/cjs/index.cjs", "module": "dist/npm/modern/esm/index.mjs", @@ -93,7 +93,7 @@ "@rudderstack/analytics-js-common": "*", "@vespaiach/axios-fetch-adapter": "0.3.1", "assert": "2.1.0", - "axios": "1.7.7", + "axios": "1.7.9", "axios-retry": "4.5.0", "component-type": "2.0.0", "join-component": "1.1.0", diff --git a/packages/analytics-js-service-worker/project.json b/packages/analytics-js-service-worker/project.json index 0c006c91c7..d191528748 100644 --- a/packages/analytics-js-service-worker/project.json +++ b/packages/analytics-js-service-worker/project.json @@ -51,9 +51,9 @@ "github": { "executor": "@jscutlery/semver:github", "options": { - "tag": "@rudderstack/analytics-js-service-worker@3.2.16", - "title": "rudderstack/analytics-js-service-worker@3.2.16", - "discussion-category": "rudderstack/analytics-js-service-worker@3.2.16", + "tag": "@rudderstack/analytics-js-service-worker@3.2.17", + "title": "rudderstack/analytics-js-service-worker@3.2.17", + "discussion-category": "rudderstack/analytics-js-service-worker@3.2.17", "notesFile": "./packages/analytics-js-service-worker/CHANGELOG_LATEST.md" } } diff --git a/packages/analytics-js-service-worker/rollup.config.mjs b/packages/analytics-js-service-worker/rollup.config.mjs index f8f906e5c8..7fb815d4fc 100644 --- a/packages/analytics-js-service-worker/rollup.config.mjs +++ b/packages/analytics-js-service-worker/rollup.config.mjs @@ -48,7 +48,7 @@ export function getDefaultConfig(distName) { plugins: [ replace({ preventAssignment: true, - __PACKAGE_VERSION__: version + __PACKAGE_VERSION__: version, }), resolve({ jsnext: true, @@ -74,20 +74,18 @@ export function getDefaultConfig(distName) { sourcemap: sourceMapType, }), nodePolyfills({ - include: null + include: null, }), process.env.UGLIFY === 'true' && - terser({ - safari10: isLegacyBuild, - ecma: isLegacyBuild ? 2015 : 2017, - format: { - comments: false, - }, - }), + terser({ + safari10: isLegacyBuild, + ecma: isLegacyBuild ? 2015 : 2017, + format: { + comments: false, + }, + }), copy({ - targets: [ - { src: 'types/index.d.ts', dest: outDir } - ], + targets: [{ src: 'types/index.d.ts', dest: outDir }], }), filesize({ showBrotliSize: true, @@ -100,7 +98,7 @@ export function getDefaultConfig(distName) { open: true, gzipSize: true, brotliSize: true, - }) + }), ], }; } @@ -114,7 +112,7 @@ const outputFilesNpm = [ sourcemap: sourceMapType, generatedCode: { preset: isLegacyBuild ? 'es5' : 'es2015', - } + }, }, { entryFileNames: `index.cjs`, @@ -124,7 +122,7 @@ const outputFilesNpm = [ sourcemap: sourceMapType, generatedCode: { preset: isLegacyBuild ? 'es5' : 'es2015', - } + }, }, { entryFileNames: `index.js`, @@ -134,7 +132,7 @@ const outputFilesNpm = [ sourcemap: sourceMapType, generatedCode: { preset: isLegacyBuild ? 'es5' : 'es2015', - } + }, }, ]; @@ -156,11 +154,11 @@ const buildEntries = [ { find: '@rudderstack/analytics-js-common', replacement: path.resolve('./dist/dts/packages/analytics-js-common/src'), - } - ] + }, + ], }), dts(), - del({ hook: "buildEnd", targets: "./dist/dts" }), + del({ hook: 'buildEnd', targets: './dist/dts' }), ], output: [ { @@ -170,8 +168,8 @@ const buildEntries = [ { file: `${outDirNpmRoot}/index.d.cts`, format: 'es', - } - ] + }, + ], }, ]; diff --git a/packages/analytics-js/.size-limit.mjs b/packages/analytics-js/.size-limit.mjs index 82b89e09dc..9dc1495ea0 100644 --- a/packages/analytics-js/.size-limit.mjs +++ b/packages/analytics-js/.size-limit.mjs @@ -59,7 +59,7 @@ export default [ name: 'Core (Bundled) - Legacy - NPM (CJS)', path: 'dist/npm/legacy/bundled/cjs/index.cjs', import: '*', - limit: '49 KiB', + limit: '49.1 KiB', }, { name: 'Core (Bundled) - Legacy - NPM (UMD)', diff --git a/packages/analytics-js/CHANGELOG.md b/packages/analytics-js/CHANGELOG.md index bb8c1a10ac..83940fd8f1 100644 --- a/packages/analytics-js/CHANGELOG.md +++ b/packages/analytics-js/CHANGELOG.md @@ -2,6 +2,19 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [3.11.16](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js@3.11.15...@rudderstack/analytics-js@3.11.16) (2024-12-17) + +### Dependency Updates + +* `@rudderstack/analytics-js-cookies` updated to version `0.4.17` +* `@rudderstack/analytics-js-common` updated to version `3.14.14` +* `@rudderstack/analytics-js-plugins` updated to version `3.6.20` + +### Bug Fixes + +* remove circular dependency in packages ([#1973](https://github.com/rudderlabs/rudder-sdk-js/issues/1973)) ([e525496](https://github.com/rudderlabs/rudder-sdk-js/commit/e5254964310c2c73baaf4d0655c3e4025c5e7d2b)) +* separator and make changes in bugsnag plugin ([b69347c](https://github.com/rudderlabs/rudder-sdk-js/commit/b69347cd9bbf3a395b2f557f8219287900ceca5a)) + ## [3.11.15](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js@3.11.14...@rudderstack/analytics-js@3.11.15) (2024-12-06) ### Dependency Updates diff --git a/packages/analytics-js/CHANGELOG_LATEST.md b/packages/analytics-js/CHANGELOG_LATEST.md index 20097a8545..25932bb992 100644 --- a/packages/analytics-js/CHANGELOG_LATEST.md +++ b/packages/analytics-js/CHANGELOG_LATEST.md @@ -1,7 +1,13 @@ -## [3.11.15](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js@3.11.14...@rudderstack/analytics-js@3.11.15) (2024-12-06) +## [3.11.16](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js@3.11.15...@rudderstack/analytics-js@3.11.16) (2024-12-17) ### Dependency Updates -* `@rudderstack/analytics-js-cookies` updated to version `0.4.16` -* `@rudderstack/analytics-js-common` updated to version `3.14.13` -* `@rudderstack/analytics-js-plugins` updated to version `3.6.18` +* `@rudderstack/analytics-js-cookies` updated to version `0.4.17` +* `@rudderstack/analytics-js-common` updated to version `3.14.14` +* `@rudderstack/analytics-js-plugins` updated to version `3.6.20` + +### Bug Fixes + +* remove circular dependency in packages ([#1973](https://github.com/rudderlabs/rudder-sdk-js/issues/1973)) ([e525496](https://github.com/rudderlabs/rudder-sdk-js/commit/e5254964310c2c73baaf4d0655c3e4025c5e7d2b)) +* separator and make changes in bugsnag plugin ([b69347c](https://github.com/rudderlabs/rudder-sdk-js/commit/b69347cd9bbf3a395b2f557f8219287900ceca5a)) + diff --git a/packages/analytics-js/LICENSE.md b/packages/analytics-js/LICENSE.md index 554bb72539..37517857b4 100644 --- a/packages/analytics-js/LICENSE.md +++ b/packages/analytics-js/LICENSE.md @@ -40,14 +40,14 @@ As far as the law allows, the software comes as is, without any warranty or cond ## Definitions -The *licensor* is the entity offering these terms, and the *software* is the software the licensor makes available under these terms, including any portion of it. +The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it. -*you* refers to the individual or entity agreeing to these terms. +_you_ refers to the individual or entity agreeing to these terms. -*your company* is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. *control* means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. +_your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. -*your licenses* are all the licenses granted to you for the software under these terms. +_your licenses_ are all the licenses granted to you for the software under these terms. -*use* means anything you do with the software requiring one of your licenses. +_use_ means anything you do with the software requiring one of your licenses. -*trademark* means trademarks, service marks, and similar rights. +_trademark_ means trademarks, service marks, and similar rights. diff --git a/packages/analytics-js/__tests__/app/RudderAnalytics.test.ts b/packages/analytics-js/__tests__/app/RudderAnalytics.test.ts index a603989866..09c3c74802 100644 --- a/packages/analytics-js/__tests__/app/RudderAnalytics.test.ts +++ b/packages/analytics-js/__tests__/app/RudderAnalytics.test.ts @@ -829,16 +829,19 @@ describe('Core - Rudder Analytics Facade', () => { enabled: true, }, }); - expect(rudderAnalyticsInstance.trackPageLifecycleEvents).toHaveBeenCalledWith([ - ['consent', { sendPageEvent: true }], - ['consent', { sendPageEvent: false }], - ['track'], - ['track'], - ], { - autoTrack: { - enabled: true, + expect(rudderAnalyticsInstance.trackPageLifecycleEvents).toHaveBeenCalledWith( + [ + ['consent', { sendPageEvent: true }], + ['consent', { sendPageEvent: false }], + ['track'], + ['track'], + ], + { + autoTrack: { + enabled: true, + }, }, - }); + ); }); }); }); diff --git a/packages/analytics-js/__tests__/components/capabilitiesManager/detection/clientHint.test.ts b/packages/analytics-js/__tests__/components/capabilitiesManager/detection/clientHint.test.ts index ff1e812f05..6b3fa2d16a 100644 --- a/packages/analytics-js/__tests__/components/capabilitiesManager/detection/clientHint.test.ts +++ b/packages/analytics-js/__tests__/components/capabilitiesManager/detection/clientHint.test.ts @@ -56,26 +56,26 @@ describe('User Agent Client Hint Utilities', () => { global.navigator.userAgentData = undefined; }); - it('Should return undefined when none is passed as the level', () => { + it('should return undefined when none is passed as the level', () => { const callback = jest.fn(userAgentClientHint => { expect(userAgentClientHint).toBe(undefined); }); getUserAgentClientHint(callback, 'none'); }); - it('Should return undefined if no argument is passed as the level', () => { + it('should return undefined if no argument is passed as the level', () => { const callback = jest.fn(userAgentClientHint => { expect(userAgentClientHint).toBe(undefined); }); getUserAgentClientHint(callback); }); - it('Should return default client-hint object if default is passed as the level', () => { + it('should return default client-hint object if default is passed as the level', () => { global.navigator.userAgentData = chromeDefaultUACH; const callback = jest.fn(userAgentClientHint => { expect(userAgentClientHint).toBe(chromeDefaultUACH); }); getUserAgentClientHint(callback, 'default'); }); - it('Should return default client-hint object if full is passed as the level', () => { + it('should return default client-hint object if full is passed as the level', () => { navigator.userAgentData = { getHighEntropyValues: jest.fn().mockResolvedValue(chromeFullUACH), }; diff --git a/packages/analytics-js/__tests__/services/StoreManager/top-domain/index.test.ts b/packages/analytics-js/__tests__/services/StoreManager/top-domain/index.test.ts index dc1e77410b..b1bf676a02 100644 --- a/packages/analytics-js/__tests__/services/StoreManager/top-domain/index.test.ts +++ b/packages/analytics-js/__tests__/services/StoreManager/top-domain/index.test.ts @@ -1,12 +1,12 @@ import type { Nullable } from '@rudderstack/analytics-js-common/types/Nullable'; import type { CookieOptions } from '@rudderstack/analytics-js-common/types/Storage'; -import { cookie } from '@rudderstack/analytics-js-cookies/component-cookie'; +import { cookie } from '@rudderstack/analytics-js-common/component-cookie'; import { domain } from '../../../../src/services/StoreManager/top-domain'; let cookies: Record = {}; -jest.mock('@rudderstack/analytics-js-cookies/component-cookie', () => { - const originalModule = jest.requireActual('@rudderstack/analytics-js-cookies/component-cookie'); +jest.mock('@rudderstack/analytics-js-common/component-cookie', () => { + const originalModule = jest.requireActual('@rudderstack/analytics-js-common/component-cookie'); return { __esModule: true, diff --git a/packages/analytics-js/package.json b/packages/analytics-js/package.json index d7f145c3ed..f4017fb3a0 100644 --- a/packages/analytics-js/package.json +++ b/packages/analytics-js/package.json @@ -1,6 +1,6 @@ { "name": "@rudderstack/analytics-js", - "version": "3.11.15", + "version": "3.11.16", "description": "RudderStack JavaScript SDK", "main": "dist/npm/modern/cjs/index.cjs", "module": "dist/npm/modern/esm/index.mjs", diff --git a/packages/analytics-js/project.json b/packages/analytics-js/project.json index 9c96d13261..4adfc485a3 100644 --- a/packages/analytics-js/project.json +++ b/packages/analytics-js/project.json @@ -59,9 +59,9 @@ "github": { "executor": "@jscutlery/semver:github", "options": { - "tag": "@rudderstack/analytics-js@3.11.15", - "title": "@rudderstack/analytics-js@3.11.15", - "discussion-category": "@rudderstack/analytics-js@3.11.15", + "tag": "@rudderstack/analytics-js@3.11.16", + "title": "@rudderstack/analytics-js@3.11.16", + "discussion-category": "@rudderstack/analytics-js@3.11.16", "notesFile": "./packages/analytics-js/CHANGELOG_LATEST.md" } } diff --git a/packages/analytics-js/public/index.html b/packages/analytics-js/public/index.html index fb35e033a2..029e693b8c 100644 --- a/packages/analytics-js/public/index.html +++ b/packages/analytics-js/public/index.html @@ -1,11 +1,16 @@ - + - + - \ No newline at end of file + diff --git a/packages/analytics-js/public/list_integration_sdks.html b/packages/analytics-js/public/list_integration_sdks.html deleted file mode 100644 index c346ee3b8d..0000000000 --- a/packages/analytics-js/public/list_integration_sdks.html +++ /dev/null @@ -1,409 +0,0 @@ - - - - - RudderStack JavaScript SDK v3 - Integration SDKs - - -
- - - - - - - diff --git a/packages/analytics-js/src/services/StoreManager/Store.ts b/packages/analytics-js/src/services/StoreManager/Store.ts index da079a8a64..744ab3e6af 100644 --- a/packages/analytics-js/src/services/StoreManager/Store.ts +++ b/packages/analytics-js/src/services/StoreManager/Store.ts @@ -208,7 +208,7 @@ class Store implements IStore { ? this.pluginsManager.invokeSingle(extensionPointName, value) : value; - return typeof formattedValue === 'undefined' ? value : formattedValue ?? ''; + return typeof formattedValue === 'undefined' ? value : (formattedValue ?? ''); } /** diff --git a/packages/analytics-js/src/services/StoreManager/storages/CookieStorage.ts b/packages/analytics-js/src/services/StoreManager/storages/CookieStorage.ts index b857e618fd..b67eebd38a 100644 --- a/packages/analytics-js/src/services/StoreManager/storages/CookieStorage.ts +++ b/packages/analytics-js/src/services/StoreManager/storages/CookieStorage.ts @@ -4,7 +4,7 @@ import type { Nullable } from '@rudderstack/analytics-js-common/types/Nullable'; import type { ILogger } from '@rudderstack/analytics-js-common/types/Logger'; import { COOKIE_STORAGE } from '@rudderstack/analytics-js-common/constants/storages'; import { mergeDeepRight } from '@rudderstack/analytics-js-common/utilities/object'; -import { cookie } from '@rudderstack/analytics-js-cookies/component-cookie'; +import { cookie } from '@rudderstack/analytics-js-common/component-cookie'; import { isStorageAvailable } from '../../../components/capabilitiesManager/detection'; import { getDefaultCookieOptions } from './defaultOptions'; diff --git a/packages/analytics-js/src/services/StoreManager/top-domain/index.ts b/packages/analytics-js/src/services/StoreManager/top-domain/index.ts index cf5d2af383..c1b9e46ab8 100644 --- a/packages/analytics-js/src/services/StoreManager/top-domain/index.ts +++ b/packages/analytics-js/src/services/StoreManager/top-domain/index.ts @@ -1,4 +1,4 @@ -import { cookie } from '@rudderstack/analytics-js-cookies/component-cookie'; +import { cookie } from '@rudderstack/analytics-js-common/component-cookie'; import { STORAGE_TEST_TOP_LEVEL_DOMAIN } from '../../../constants/storage'; const legacyGetHostname = (href: string): string => { diff --git a/packages/analytics-v1.1/CHANGELOG.md b/packages/analytics-v1.1/CHANGELOG.md index 072b9c4995..29e52dbe08 100644 --- a/packages/analytics-v1.1/CHANGELOG.md +++ b/packages/analytics-v1.1/CHANGELOG.md @@ -2,6 +2,11 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [2.48.42](https://github.com/rudderlabs/rudder-sdk-js/compare/rudder-sdk-js@2.48.41...rudder-sdk-js@2.48.42) (2024-12-17) + +### Dependency Updates + +* `@rudderstack/analytics-js-common` updated to version `3.14.14` ## [2.48.41](https://github.com/rudderlabs/rudder-sdk-js/compare/rudder-sdk-js@2.48.40...rudder-sdk-js@2.48.41) (2024-12-06) ### Dependency Updates diff --git a/packages/analytics-v1.1/CHANGELOG_LATEST.md b/packages/analytics-v1.1/CHANGELOG_LATEST.md index c03bb99cad..aa3a573d29 100644 --- a/packages/analytics-v1.1/CHANGELOG_LATEST.md +++ b/packages/analytics-v1.1/CHANGELOG_LATEST.md @@ -1,5 +1,5 @@ -## [2.48.41](https://github.com/rudderlabs/rudder-sdk-js/compare/rudder-sdk-js@2.48.40...rudder-sdk-js@2.48.41) (2024-12-06) +## [2.48.42](https://github.com/rudderlabs/rudder-sdk-js/compare/rudder-sdk-js@2.48.41...rudder-sdk-js@2.48.42) (2024-12-17) ### Dependency Updates -* `@rudderstack/analytics-js-common` updated to version `3.14.13` +* `@rudderstack/analytics-js-common` updated to version `3.14.14` diff --git a/packages/analytics-v1.1/LICENSE.md b/packages/analytics-v1.1/LICENSE.md index 554bb72539..37517857b4 100644 --- a/packages/analytics-v1.1/LICENSE.md +++ b/packages/analytics-v1.1/LICENSE.md @@ -40,14 +40,14 @@ As far as the law allows, the software comes as is, without any warranty or cond ## Definitions -The *licensor* is the entity offering these terms, and the *software* is the software the licensor makes available under these terms, including any portion of it. +The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it. -*you* refers to the individual or entity agreeing to these terms. +_you_ refers to the individual or entity agreeing to these terms. -*your company* is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. *control* means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. +_your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. -*your licenses* are all the licenses granted to you for the software under these terms. +_your licenses_ are all the licenses granted to you for the software under these terms. -*use* means anything you do with the software requiring one of your licenses. +_use_ means anything you do with the software requiring one of your licenses. -*trademark* means trademarks, service marks, and similar rights. +_trademark_ means trademarks, service marks, and similar rights. diff --git a/packages/analytics-v1.1/README.md b/packages/analytics-v1.1/README.md index 1cbfee8c21..54c77c6951 100644 --- a/packages/analytics-v1.1/README.md +++ b/packages/analytics-v1.1/README.md @@ -20,7 +20,7 @@ --- | :warning: This package is deprecated. Please switch to the latest [@rudderstack/analytics-js](https://www.npmjs.com/package/@rudderstack/analytics-js) package for improved features and support.
For more details, visit [link](https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/). | -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | # RudderStack JavaScript SDK @@ -40,7 +40,7 @@ The JavaScript SDK lets you track customer event data from your website and send - [**Usage in Serverless Runtimes**](#usage-in-serverless-runtimes) | **IMPORTANT**: We have deprecated the service worker export from RudderStack JavaScript SDK NPM package and moved it to a separate package.
If you still wish to use it for your project, refer to [**@rudderstack/analytics-js-service-worker package**](https://www.npmjs.com/package/@rudderstack/analytics-js-service-worker). | -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ## [](https://github.com/rudderlabs/rudder-sdk-js/blob/main/packages/analytics-v1.1/README.md#installing-the-javascript-sdk)Installing the JavaScript SDK diff --git a/packages/analytics-v1.1/__tests__/features/core/metrics/errorReporting/ErrorReportingService.test.js b/packages/analytics-v1.1/__tests__/features/core/metrics/errorReporting/ErrorReportingService.test.js index ede024331a..c73cfc1662 100644 --- a/packages/analytics-v1.1/__tests__/features/core/metrics/errorReporting/ErrorReportingService.test.js +++ b/packages/analytics-v1.1/__tests__/features/core/metrics/errorReporting/ErrorReportingService.test.js @@ -6,19 +6,19 @@ const DEFAULT_ERROR_REPORT_PROVIDER = 'rs-bugsnag'; const sourceId = 'random-source-id'; describe('Error reporting service Test suite', () => { - test('Should print error message and return if source config or sourceId is not provided in init call', () => { + test('should print error message and return if source config or sourceId is not provided in init call', () => { const outcome = errorReportingService.init(); expect(outcome).toBe(undefined); }); - test('Should not initialize provider if not enabled from source config in init call', () => { + test('should not initialize provider if not enabled from source config in init call', () => { errorReportingService.init({ statsCollection: { errors: { enabled: false } } }, sourceId); expect(errorReportingService.isEnabled).toEqual(false); }); - test('Should initialize provider if enabled from source config in init call', async () => { + test('should initialize provider if enabled from source config in init call', async () => { errorReportingService.init({ statsCollection: { errors: { enabled: true } } }, sourceId); expect(errorReportingService.isEnabled).toEqual(true); }); - test('Should initialize default provider if enabled from source config but provider name is not there', async () => { + test('should initialize default provider if enabled from source config but provider name is not there', async () => { window.bugsnag = jest.fn(() => ({ notifier: { version: '6.0.0' } })); errorReportingService.exposeToGlobal = jest.fn(); errorReportingService.onClientReady = jest.fn(() => errorReportingService.exposeToGlobal()); @@ -27,7 +27,7 @@ describe('Error reporting service Test suite', () => { expect(errorReportingService.onClientReady).toHaveBeenCalledTimes(1); expect(errorReportingService.exposeToGlobal).toHaveBeenCalledTimes(1); }); - test('Should not initialize provider if provider from source config does not match with SDK supported list', async () => { + test('should not initialize provider if provider from source config does not match with SDK supported list', async () => { window.bugsnag = undefined; errorReportingService.init( { statsCollection: { errors: { enabled: true, provider: 'test' } } }, @@ -36,13 +36,13 @@ describe('Error reporting service Test suite', () => { expect(errorReportingService.provider.client).toEqual(undefined); expect(errorReportingService.onClientReady).toHaveBeenCalledTimes(0); }); - test('Should not initialize provider if the enabled flag is missing from the source config (default state is to not load)', async () => { + test('should not initialize provider if the enabled flag is missing from the source config (default state is to not load)', async () => { window.bugsnag = undefined; errorReportingService.init({ statsCollection: { errors: { provider: 'test' } } }, sourceId); expect(errorReportingService.provider.client).toEqual(undefined); expect(errorReportingService.onClientReady).toHaveBeenCalledTimes(0); }); - test('Should not initialize provider if the error collection enabled flag is not a boolean', async () => { + test('should not initialize provider if the error collection enabled flag is not a boolean', async () => { window.bugsnag = undefined; errorReportingService.init( { statsCollection: { errors: { enabled: 'true', provider: 'test' } } }, @@ -54,22 +54,22 @@ describe('Error reporting service Test suite', () => { }); describe('Bugsnag Test suite', () => { - test('Should not initialize bugsnag if version > 6 of bugsnag is present in window scope', async () => { + test('should not initialize bugsnag if version > 6 of bugsnag is present in window scope', async () => { window.bugsnag = { _client: { _notifier: { version: '7.0.0' } } }; errorReportingService.init({ statsCollection: { errors: { enabled: true } } }, sourceId); expect(errorReportingService.provider.client).toEqual(undefined); }); - test('Should not initialize bugsnag if version <6 of bugsnag is present in window scope', async () => { + test('should not initialize bugsnag if version <6 of bugsnag is present in window scope', async () => { window.bugsnag = jest.fn(() => ({ notifier: { version: '4.0.0' } })); errorReportingService.init({ statsCollection: { errors: { enabled: true } } }, sourceId); expect(errorReportingService.provider.client).toEqual(undefined); }); - test('Should initialize bugsnag if version 6 of bugsnag is present in window scope', async () => { + test('should initialize bugsnag if version 6 of bugsnag is present in window scope', async () => { window.bugsnag = jest.fn(() => ({ notifier: { version: '6.0.0' } })); errorReportingService.init({ statsCollection: { errors: { enabled: true } } }, sourceId); expect(errorReportingService.provider.client).not.toBe(undefined); }); - test('Should initialize Bugsnag if provider from source config matches with SDK supported list', async () => { + test('should initialize Bugsnag if provider from source config matches with SDK supported list', async () => { window.bugsnag = jest.fn(() => ({ notifier: { version: '6.0.0' } })); errorReportingService.init( { statsCollection: { errors: { enabled: true, provider: 'rs-bugsnag' } } }, diff --git a/packages/analytics-v1.1/__tests__/ketchConsent.test.js b/packages/analytics-v1.1/__tests__/ketchConsent.test.js index 58b92c1a61..55eb89121f 100644 --- a/packages/analytics-v1.1/__tests__/ketchConsent.test.js +++ b/packages/analytics-v1.1/__tests__/ketchConsent.test.js @@ -11,19 +11,19 @@ const expectedDeniedPurposes = ['email_mktg', 'behavioral_advertising']; const ketch = new Ketch(); describe('Test suit for Ketch consent manager', () => { - it('Should allow events when no category is set in destination config', () => { + it('should allow events when no category is set in destination config', () => { const destConfig = {}; const allowEvent = ketch.isEnabled(destConfig); expect(allowEvent).toBe(true); }); - it('Should allow events when purpose in destination config is present in consented categories', () => { + it('should allow events when purpose in destination config is present in consented categories', () => { const destConfig = { ketchConsentPurposes: [{ purpose: 'analytics' }], }; const allowEvent = ketch.isEnabled(destConfig); expect(allowEvent).toBe(true); }); - it('Should not allow events when consented category name is not present in destination config', () => { + it('should not allow events when consented category name is not present in destination config', () => { const destConfig = { ketchConsentPurposes: [{ purpose: 'performance' }], }; @@ -31,18 +31,18 @@ describe('Test suit for Ketch consent manager', () => { expect(allowEvent).toBe(false); }); - it('Should not allow events when all the category IDs in destination config present in consented category IDs', () => { + it('should not allow events when all the category IDs in destination config present in consented category IDs', () => { const destConfig = { ketchConsentPurposes: [{ purpose: 'analytics' }, { purpose: 'email_mktg' }], }; const allowEvent = ketch.isEnabled(destConfig); expect(allowEvent).toBe(true); }); - it('Should return the category IDs that the user has not consented for', () => { + it('should return the category IDs that the user has not consented for', () => { const actualDeniedPurposes = ketch.getDeniedList(); expect(actualDeniedPurposes).toEqual(expectedDeniedPurposes); }); - it('Should return the category IDs that the user has not consented for', () => { + it('should return the category IDs that the user has not consented for', () => { const actualDeniedPurposes = ketch.getDeniedList(); expect(actualDeniedPurposes).toEqual(expectedDeniedPurposes); }); diff --git a/packages/analytics-v1.1/__tests__/oneTrustCookieConsent.test.js b/packages/analytics-v1.1/__tests__/oneTrustCookieConsent.test.js index 4cc473da1f..304b0e9f9b 100644 --- a/packages/analytics-v1.1/__tests__/oneTrustCookieConsent.test.js +++ b/packages/analytics-v1.1/__tests__/oneTrustCookieConsent.test.js @@ -19,26 +19,26 @@ const expectedDeniedConsentIds = ['C0002', 'C0004', 'C0005', 'C0006']; const oneTrust = new OneTrust(); describe('Test suit for OneTrust cookie consent manager', () => { - it('Should allow events when no category is set in destination config', () => { + it('should allow events when no category is set in destination config', () => { const destConfig = {}; const allowEvent = oneTrust.isEnabled(destConfig); expect(allowEvent).toBe(true); }); - it('Should allow events when oneTrustCookieCategory in destination config is present in consented categories', () => { + it('should allow events when oneTrustCookieCategory in destination config is present in consented categories', () => { const destConfig = { oneTrustCookieCategories: [{ oneTrustCookieCategory: 'analytical cookies' }], }; const allowEvent = oneTrust.isEnabled(destConfig); expect(allowEvent).toBe(true); }); - it('Should allow events when category ID in destination config is present in consented category IDs', () => { + it('should allow events when category ID in destination config is present in consented category IDs', () => { const destConfig = { oneTrustCookieCategories: [{ oneTrustCookieCategory: 'c0003' }], }; const allowEvent = oneTrust.isEnabled(destConfig); expect(allowEvent).toBe(true); }); - it('Should allow events when category ID and name both is present in destination config and present in consented categories', () => { + it('should allow events when category ID and name both is present in destination config and present in consented categories', () => { const destConfig = { oneTrustCookieCategories: [ { oneTrustCookieCategory: 'c0001' }, @@ -48,21 +48,21 @@ describe('Test suit for OneTrust cookie consent manager', () => { const allowEvent = oneTrust.isEnabled(destConfig); expect(allowEvent).toBe(true); }); - it('Should not allow events when consented category name is not present in destination config', () => { + it('should not allow events when consented category name is not present in destination config', () => { const destConfig = { oneTrustCookieCategories: [{ oneTrustCookieCategory: 'Performance Cookies' }], }; const allowEvent = oneTrust.isEnabled(destConfig); expect(allowEvent).toBe(false); }); - it('Should not allow events when consented category ID is not present in destination config', () => { + it('should not allow events when consented category ID is not present in destination config', () => { const destConfig = { oneTrustCookieCategories: [{ oneTrustCookieCategory: 'c0005' }], }; const allowEvent = oneTrust.isEnabled(destConfig); expect(allowEvent).toBe(false); }); - it('Should not allow events when all the category IDs in destination config present in consented category IDs', () => { + it('should not allow events when all the category IDs in destination config present in consented category IDs', () => { const destConfig = { oneTrustCookieCategories: [ { oneTrustCookieCategory: 'c0001' }, @@ -72,7 +72,7 @@ describe('Test suit for OneTrust cookie consent manager', () => { const allowEvent = oneTrust.isEnabled(destConfig); expect(allowEvent).toBe(false); }); - it('Should not allow events when all the category IDs/names in destination config present in consented category IDs/names', () => { + it('should not allow events when all the category IDs/names in destination config present in consented category IDs/names', () => { const destConfig = { oneTrustCookieCategories: [ { oneTrustCookieCategory: 'analytical cookies' }, @@ -82,7 +82,7 @@ describe('Test suit for OneTrust cookie consent manager', () => { const allowEvent = oneTrust.isEnabled(destConfig); expect(allowEvent).toBe(false); }); - it('Should return the category IDs that the user has not consented for', () => { + it('should return the category IDs that the user has not consented for', () => { const actualDeniedConsentIds = oneTrust.getDeniedList(); expect(actualDeniedConsentIds).toEqual(expectedDeniedConsentIds); }); diff --git a/packages/analytics-v1.1/__tests__/transformationHandler.test.js b/packages/analytics-v1.1/__tests__/transformationHandler.test.js index 20a6584247..b1a1cd02e4 100644 --- a/packages/analytics-v1.1/__tests__/transformationHandler.test.js +++ b/packages/analytics-v1.1/__tests__/transformationHandler.test.js @@ -105,7 +105,7 @@ describe('Test suite for device mode transformation feature', () => { }); }); - it('Should not filter transformed events that are not 200', async () => { + it('should not filter transformed events that are not 200', async () => { DeviceModeTransformations.init(dummyWriteKey, `${dummyDataplaneHost}/partialSuccess`); await DeviceModeTransformations.sendEventForTransformation(payload, retryCount) diff --git a/packages/analytics-v1.1/__tests__/utils/clientHint.test.js b/packages/analytics-v1.1/__tests__/utils/clientHint.test.js index c093430310..b2c8dcf2dd 100644 --- a/packages/analytics-v1.1/__tests__/utils/clientHint.test.js +++ b/packages/analytics-v1.1/__tests__/utils/clientHint.test.js @@ -56,26 +56,26 @@ describe('User Agent Client Hint Utilities', () => { global.navigator.userAgentData = undefined; }); - it('Should return undefined when none is passed as the level', () => { + it('should return undefined when none is passed as the level', () => { const callback = jest.fn(userAgentClientHint => { expect(userAgentClientHint).toBe(undefined); }); getUserAgentClientHint(callback, 'none'); }); - it('Should return undefined if no argument is passed as the level', () => { + it('should return undefined if no argument is passed as the level', () => { const callback = jest.fn(userAgentClientHint => { expect(userAgentClientHint).toBe(undefined); }); getUserAgentClientHint(callback); }); - it('Should return default client-hint object if default is passed as the level', () => { + it('should return default client-hint object if default is passed as the level', () => { global.navigator.userAgentData = chromeDefaultUACH; const callback = jest.fn(userAgentClientHint => { expect(userAgentClientHint).toBe(chromeDefaultUACH); }); getUserAgentClientHint(callback, 'default'); }); - it('Should return default client-hint object if full is passed as the level', () => { + it('should return default client-hint object if full is passed as the level', () => { navigator.userAgentData = { getHighEntropyValues: jest.fn().mockResolvedValue(chromeFullUACH), }; diff --git a/packages/analytics-v1.1/__tests__/utils/eventProcessorUtils.test.js b/packages/analytics-v1.1/__tests__/utils/eventProcessorUtils.test.js index 8fd22350f2..a80e9b4f87 100644 --- a/packages/analytics-v1.1/__tests__/utils/eventProcessorUtils.test.js +++ b/packages/analytics-v1.1/__tests__/utils/eventProcessorUtils.test.js @@ -210,54 +210,54 @@ describe('Event processor Utilities', () => { }, }; - it('Should merge the context provided in options with the previous context', () => { + it('should merge the context provided in options with the previous context', () => { const mergedRudderMessageContext = mergeContext(rudderElement.message, options); expect(mergedRudderMessageContext).toStrictEqual(expectedRudderElement.message.context); }); - it('Should context object remain intact if no options provided', () => { + it('should context object remain intact if no options provided', () => { const mergedRudderMessageContext = mergeContext(rudderElement.message, undefined); expect(mergedRudderMessageContext).toStrictEqual(rudderElement.message.context); }); - it('Should context object remain intact if null options provided', () => { + it('should context object remain intact if null options provided', () => { const mergedRudderMessageContext = mergeContext(rudderElement.message, null); expect(mergedRudderMessageContext).toStrictEqual(rudderElement.message.context); }); - it('Should context object remain intact if non object type options provided', () => { + it('should context object remain intact if non object type options provided', () => { const mergedRudderMessageContext = mergeContext(rudderElement.message, 'options'); expect(mergedRudderMessageContext).toStrictEqual(rudderElement.message.context); }); - it('Should mutate the top level context in rudder element if provided in options', () => { + it('should mutate the top level context in rudder element if provided in options', () => { mergeTopLevelElementsMutator(rudderElement.message, optionsWithTopLevelContext); expect(rudderElement.message).toStrictEqual(expectedRudderElementWithTopLevelElement.message); }); - it('Should top level context object remain intact if no options provided', () => { + it('should top level context object remain intact if no options provided', () => { mergeTopLevelElementsMutator(rudderElement.message, undefined); expect(rudderElement.message).toStrictEqual(rudderElement.message); }); - it('Should top level context object remain intact if null options provided', () => { + it('should top level context object remain intact if null options provided', () => { mergeTopLevelElementsMutator(rudderElement.message, null); expect(rudderElement.message).toStrictEqual(rudderElement.message); }); - it('Should top level context object remain intact if non object type options provided', () => { + it('should top level context object remain intact if non object type options provided', () => { mergeTopLevelElementsMutator(rudderElement.message, 'options'); expect(rudderElement.message).toStrictEqual(rudderElement.message); }); - it('Should not override library info in context if provided in options', () => { + it('should not override library info in context if provided in options', () => { const mergedRudderMessageContext = mergeContext(rudderElement.message, optionsWithLibraryInfo); expect(mergedRudderMessageContext).toStrictEqual( expectedRudderElementWithLibraryInfo.message.context, ); }); - it('Should not merge null context if provided in options', () => { + it('should not merge null context if provided in options', () => { const mergedRudderMessageContext = mergeContext(rudderElement.message, optionsWithNullContext); expect(mergedRudderMessageContext).toStrictEqual(expectedRudderElement.message.context); }); diff --git a/packages/analytics-v1.1/__tests__/utils/navigator.test.js b/packages/analytics-v1.1/__tests__/utils/navigator.test.js index 339ce8cab0..a33bf0885b 100644 --- a/packages/analytics-v1.1/__tests__/utils/navigator.test.js +++ b/packages/analytics-v1.1/__tests__/utils/navigator.test.js @@ -14,14 +14,14 @@ describe('Navigator Utilities', () => { global.navigator.language = undefined; }); - it('Should get User Agent when navigator is defined', () => { + it('should get User Agent when navigator is defined', () => { global.navigator.userAgent = chromeUserAgentString; const userAgent = getUserAgent(); expect(userAgent).toBe(chromeUserAgentString); }); - it('Should get User Agent with Braze info for braze browsers', () => { + it('should get User Agent with Braze info for braze browsers', () => { global.navigator.userAgent = chromeUserAgentString; global.navigator.brave = new BraveBrowser(); const userAgent = getUserAgent(); @@ -29,7 +29,7 @@ describe('Navigator Utilities', () => { expect(userAgent).toBe(`${chromeUserAgentString} Brave/${chromeVersion}`); }); - it('Should get language when navigator is defined', () => { + it('should get language when navigator is defined', () => { global.navigator.language = mockLanguage; const language = getLanguage(); diff --git a/packages/analytics-v1.1/__tests__/utils/screenDetails.test.js b/packages/analytics-v1.1/__tests__/utils/screenDetails.test.js index d85e25f5c1..fdcaeafa13 100644 --- a/packages/analytics-v1.1/__tests__/utils/screenDetails.test.js +++ b/packages/analytics-v1.1/__tests__/utils/screenDetails.test.js @@ -9,7 +9,7 @@ describe('Screen Details Utilities', () => { expectedScreenInfo.innerWidth = 1680; expectedScreenInfo.innerHeight = 1024; - it('Should get Screen Details when window is defined', () => { + it('should get Screen Details when window is defined', () => { jest.spyOn(window.screen, 'width', 'get').mockReturnValue(1680); jest.spyOn(window.screen, 'height', 'get').mockReturnValue(1024); const screen = getScreenDetails(); diff --git a/packages/analytics-v1.1/package.json b/packages/analytics-v1.1/package.json index 49f483c7c2..a86129ebd7 100644 --- a/packages/analytics-v1.1/package.json +++ b/packages/analytics-v1.1/package.json @@ -1,6 +1,6 @@ { "name": "rudder-sdk-js", - "version": "2.48.41", + "version": "2.48.42", "description": "RudderStack JavaScript SDK", "main": "dist/npm/index.js", "module": "dist/npm/index.es.js", diff --git a/packages/analytics-v1.1/project.json b/packages/analytics-v1.1/project.json index 577aa82984..f6d34b5aaa 100644 --- a/packages/analytics-v1.1/project.json +++ b/packages/analytics-v1.1/project.json @@ -59,9 +59,9 @@ "github": { "executor": "@jscutlery/semver:github", "options": { - "tag": "rudder-sdk-js@2.48.41", - "title": "rudder-sdk-js@2.48.41", - "discussion-category": "rudder-sdk-js@2.48.41", + "tag": "rudder-sdk-js@2.48.42", + "title": "rudder-sdk-js@2.48.42", + "discussion-category": "rudder-sdk-js@2.48.42", "notesFile": "./packages/analytics-v1.1/CHANGELOG_LATEST.md" } } diff --git a/packages/analytics-v1.1/public/index.html b/packages/analytics-v1.1/public/index.html index 24eca28583..50da509cb2 100644 --- a/packages/analytics-v1.1/public/index.html +++ b/packages/analytics-v1.1/public/index.html @@ -1,41 +1,45 @@ - + - - - - - Smoke test + + + + + + Smoke test - - + rudderanalytics.page(); + + - -

Test HTML file

-
+ +

Test HTML file

+
- - - - - + + + + + -

-

+

+

- - + // prettier-ignore + function group() { + rudderanalytics.group( + 'sample_group_id', + { + name: 'Apple Inc.', + location: 'USA', + }, + function (rudderElement) { + console.log('group call'); + document.getElementById('action').innerHTML = 'Group called'; + document.getElementById('rudderElement').innerHTML = JSON.stringify(rudderElement); + } + ); + } + + diff --git a/packages/analytics-v1.1/rollup-configs/rollup.sdk.npm.mjs b/packages/analytics-v1.1/rollup-configs/rollup.sdk.npm.mjs index 6867976849..1f311f1841 100644 --- a/packages/analytics-v1.1/rollup-configs/rollup.sdk.npm.mjs +++ b/packages/analytics-v1.1/rollup-configs/rollup.sdk.npm.mjs @@ -8,8 +8,8 @@ const distName = 'rudder-analytics'; const modName = 'rudderanalytics'; const isContentScriptBuild = process.env.NO_EXTERNAL_HOST; -if(isContentScriptBuild) { - npmPackageOutDir = `${npmPackageOutDir}/content-script` +if (isContentScriptBuild) { + npmPackageOutDir = `${npmPackageOutDir}/content-script`; } const outputFiles = [ @@ -36,9 +36,7 @@ const buildConfig = { buildConfig.plugins.push( copy({ - targets: [ - { src: 'types/index.d.ts', dest: npmPackageOutDir } - ], + targets: [{ src: 'types/index.d.ts', dest: npmPackageOutDir }], }), ); diff --git a/packages/analytics-v1.1/rollup-configs/rollup.utilities.mjs b/packages/analytics-v1.1/rollup-configs/rollup.utilities.mjs index a7ff0dd28b..3b73693326 100644 --- a/packages/analytics-v1.1/rollup-configs/rollup.utilities.mjs +++ b/packages/analytics-v1.1/rollup-configs/rollup.utilities.mjs @@ -1,5 +1,5 @@ /* eslint-disable import/no-extraneous-dependencies */ -import path from "path"; +import path from 'path'; import babel from '@rollup/plugin-babel'; import commonjs from '@rollup/plugin-commonjs'; import resolve from '@rollup/plugin-node-resolve'; @@ -13,7 +13,7 @@ import serve from 'rollup-plugin-serve'; import htmlTemplate from 'rollup-plugin-generate-html-template'; import typescript from 'rollup-plugin-typescript2'; import nodePolyfills from 'rollup-plugin-polyfill-node'; -import alias from "@rollup/plugin-alias"; +import alias from '@rollup/plugin-alias'; import * as dotenv from 'dotenv'; import { DEFAULT_EXTENSIONS } from '@babel/core'; @@ -26,7 +26,7 @@ let googleAdsSDKUrl = '//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js' // For Chrome extension as content script any references in code to third party URLs // throw violations at approval phase even if relevant code is not used -if(isContentScriptBuild) { +if (isContentScriptBuild) { bugsnagSDKUrl = ''; polyfillIoUrl = ''; googleAdsSDKUrl = ''; @@ -75,15 +75,15 @@ export function getDefaultConfig(distName) { __RS_BUGSNAG_RELEASE_STAGE__: process.env.BUGSNAG_RELEASE_STAGE || 'production', __RS_POLYFILLIO_SDK_URL__: polyfillIoUrl, __RS_BUGSNAG_SDK_URL__: bugsnagSDKUrl, - __RS_GOOGLE_ADS_SDK_URL__: googleAdsSDKUrl + __RS_GOOGLE_ADS_SDK_URL__: googleAdsSDKUrl, }), alias({ entries: [ { find: '@rudderstack/analytics-js-common', replacement: path.resolve('../analytics-js-common/src'), - } - ] + }, + ], }), nodePolyfills(), resolve({ @@ -135,8 +135,7 @@ export function getDefaultConfig(distName) { replaceVars: { __WRITE_KEY__: process.env.WRITE_KEY, __DATAPLANE_URL__: process.env.DATAPLANE_URL, - __CONFIG_SERVER_HOST__: - process.env.CONFIG_SERVER_HOST || '', + __CONFIG_SERVER_HOST__: process.env.CONFIG_SERVER_HOST || '', __DEST_SDK_BASE_URL__: process.env.DEST_SDK_BASE_URL, }, }), diff --git a/packages/analytics-v1.1/src/core/analytics.js b/packages/analytics-v1.1/src/core/analytics.js index 2d6ea53f94..29aff3b035 100644 --- a/packages/analytics-v1.1/src/core/analytics.js +++ b/packages/analytics-v1.1/src/core/analytics.js @@ -210,9 +210,7 @@ class Analytics { */ integrationSDKLoaded(pluginName, modName) { return ( - window[pluginName] && - window[pluginName][modName] && - window[pluginName][modName].prototype && + window[pluginName]?.[modName]?.prototype && typeof window[pluginName][modName].prototype.constructor !== 'undefined' ); } @@ -295,7 +293,7 @@ class Analytics { try { const cookieConsent = CookieConsentFactory.initialize(this.cookieConsentOptions); // Fetch denied consent group Ids and pass it to cloud mode - this.deniedConsentIds = cookieConsent && cookieConsent.getDeniedList(); + this.deniedConsentIds = cookieConsent?.getDeniedList(); // If cookie consent object is return we filter according to consents given by user // else we do not consider any filtering for cookie consent. this.clientIntegrations = this.clientIntegrations.filter( @@ -1114,7 +1112,7 @@ class Analytics { getPageProperties(properties, options) { const defaultPageProperties = getDefaultPageProperties(); - const optionPageProperties = (options && options.page) || {}; + const optionPageProperties = options?.page || {}; for (const key in defaultPageProperties) { if (properties[key] === undefined) { properties[key] = optionPageProperties[key] || defaultPageProperties[key]; @@ -1128,8 +1126,7 @@ class Analytics { const defaultPageProperties = getDefaultPageProperties(); const contextPageProperties = {}; for (const key in defaultPageProperties) { - contextPageProperties[key] = - properties && properties[key] ? properties[key] : defaultPageProperties[key]; + contextPageProperties[key] = properties?.[key] ? properties[key] : defaultPageProperties[key]; } return contextPageProperties; } @@ -1229,7 +1226,7 @@ class Analytics { options = serverUrl; serverUrl = null; } - if (options && options.logLevel) { + if (options?.logLevel) { this.logLevel = options.logLevel; logger.setLogLevel(options.logLevel); } @@ -1239,8 +1236,7 @@ class Analytics { if (!this.storage || Object.keys(this.storage).length === 0) { throw Error('Cannot proceed as no storage is available'); } - if (options && options.cookieConsentManager) - this.cookieConsentOptions = options.cookieConsentManager; + if (options?.cookieConsentManager) this.cookieConsentOptions = options.cookieConsentManager; this.writeKey = writeKey; this.serverUrl = serverUrl; @@ -1248,7 +1244,7 @@ class Analytics { let storageOptions = {}; - if (options && options.setCookieDomain) { + if (options?.setCookieDomain) { storageOptions = { ...storageOptions, domain: options.setCookieDomain }; } @@ -1280,7 +1276,7 @@ class Analytics { }, this.uaChTrackLevel); } - if (options && options.integrations) { + if (options?.integrations) { Object.assign(this.loadOnlyIntegrations, options.integrations); transformToRudderNames(this.loadOnlyIntegrations); } @@ -1288,20 +1284,16 @@ class Analytics { this.useGlobalIntegrationsConfigInEvents = options && options.useGlobalIntegrationsConfigInEvents === true; - if (options && options.sendAdblockPage) { + if (options?.sendAdblockPage) { this.sendAdblockPage = true; } - if ( - options && - options.sendAdblockPageOptions && - typeof options.sendAdblockPageOptions === 'object' - ) { + if (options?.sendAdblockPageOptions && typeof options.sendAdblockPageOptions === 'object') { this.sendAdblockPageOptions = options.sendAdblockPageOptions; } // Session initialization this.uSession.initialize(options); - if (options && options.clientSuppliedCallbacks) { + if (options?.clientSuppliedCallbacks) { // convert to rudder recognized method names const transformedCallbackMapping = {}; Object.keys(this.methodToCallbackMapping).forEach(methodName => { @@ -1317,7 +1309,7 @@ class Analytics { this.registerCallbacks(true); } - if (options && options.loadIntegration != undefined) { + if (options?.loadIntegration != undefined) { this.loadIntegration = !!options.loadIntegration; } @@ -1342,10 +1334,10 @@ class Analytics { this.destSDKBaseURL = getIntegrationsCDNPath( this.version, this.lockIntegrationsVersion, - options && options.destSDKBaseURL, + options?.destSDKBaseURL, ); - if (options && options.getSourceConfig) { + if (options?.getSourceConfig) { if (typeof options.getSourceConfig !== 'function') { handleError(new Error('option "getSourceConfig" must be a function')); } else { @@ -1361,7 +1353,7 @@ class Analytics { } let configUrl = getConfigUrl(writeKey, this.lockIntegrationsVersion); - if (options && options.configUrl) { + if (options?.configUrl) { configUrl = getUserProvidedConfigUrl(options.configUrl, configUrl); } diff --git a/packages/analytics-v1.1/src/features/core/cookieConsent/ketch/browser.js b/packages/analytics-v1.1/src/features/core/cookieConsent/ketch/browser.js index 853c315bf4..6d6649521b 100644 --- a/packages/analytics-v1.1/src/features/core/cookieConsent/ketch/browser.js +++ b/packages/analytics-v1.1/src/features/core/cookieConsent/ketch/browser.js @@ -103,7 +103,7 @@ class Ketch { Object.entries(consentObj).forEach(e => { const purposeCode = e[0]; const purposeValue = e[1]; - if (purposeValue && purposeValue.status) { + if (purposeValue?.status) { consent[purposeCode] = purposeValue.status === 'granted'; } }); diff --git a/packages/analytics-v1.1/src/features/core/metrics/errorReporting/providers/Bugsnag.js b/packages/analytics-v1.1/src/features/core/metrics/errorReporting/providers/Bugsnag.js index bae0116bbc..39e45e90e9 100644 --- a/packages/analytics-v1.1/src/features/core/metrics/errorReporting/providers/Bugsnag.js +++ b/packages/analytics-v1.1/src/features/core/metrics/errorReporting/providers/Bugsnag.js @@ -39,11 +39,7 @@ const getReleaseStage = () => { const isValidVersion = globalLibInstance => { // For version 7 - let version = - globalLibInstance && - globalLibInstance._client && - globalLibInstance._client._notifier && - globalLibInstance._client._notifier.version; + let version = globalLibInstance?._client?._notifier?.version; // For versions older than 7 if (!version) { @@ -55,7 +51,7 @@ const isValidVersion = globalLibInstance => { return false; }, }); - version = tempInstance.notifier && tempInstance.notifier.version; + version = tempInstance.notifier?.version; tempInstance = undefined; } @@ -123,10 +119,7 @@ class BugsnagProvider { */ init() { // Return if RS Bugsnag instance is already initialized or should not init - if ( - window.RudderStackGlobals && - window.RudderStackGlobals[ERROR_REPORTING_SERVICE_GLOBAL_KEY_NAME] - ) { + if (window.RudderStackGlobals?.[ERROR_REPORTING_SERVICE_GLOBAL_KEY_NAME]) { return; } diff --git a/packages/analytics-v1.1/src/utils/EventRepository.js b/packages/analytics-v1.1/src/utils/EventRepository.js index 65e090c547..acdf6607c0 100644 --- a/packages/analytics-v1.1/src/utils/EventRepository.js +++ b/packages/analytics-v1.1/src/utils/EventRepository.js @@ -26,7 +26,7 @@ class EventRepository { initialize(writeKey, url, options) { let queueOptions = {}; let targetUrl = removeTrailingSlashes(url); - if (options && options.useBeacon && navigator.sendBeacon) { + if (options?.useBeacon && navigator.sendBeacon) { if ( options.beaconQueueOptions && options.beaconQueueOptions != null && @@ -37,14 +37,13 @@ class EventRepository { targetUrl = `${targetUrl}/beacon/v1/batch`; this.queue = new BeaconQueue(); } else { - if (options && options.useBeacon) { + if (options?.useBeacon) { logger.info( '[EventRepository] sendBeacon feature not available in this browser :: fallback to XHR', ); } if ( - options && - options.queueOptions && + options?.queueOptions && options.queueOptions != null && typeof options.queueOptions === 'object' ) { diff --git a/packages/analytics-v1.1/src/utils/linker/index.js b/packages/analytics-v1.1/src/utils/linker/index.js index 4520e05677..2795cd9f9b 100644 --- a/packages/analytics-v1.1/src/utils/linker/index.js +++ b/packages/analytics-v1.1/src/utils/linker/index.js @@ -8,7 +8,7 @@ import crc32 from './crc32'; import USER_INTERFACE from './userLib'; import decode from './base64decoder'; -const KEY_VALIDATOR = /^[a-zA-Z0-9\-_.]+$/; +const KEY_VALIDATOR = /^[\w.-]+$/; const CHECKSUM_OFFSET_MAX_MIN = 1; const VALID_VERSION = 1; const DELIMITER = '*'; diff --git a/packages/analytics-v1.1/src/utils/utils.js b/packages/analytics-v1.1/src/utils/utils.js index 41b71c0931..3c372d98ba 100644 --- a/packages/analytics-v1.1/src/utils/utils.js +++ b/packages/analytics-v1.1/src/utils/utils.js @@ -19,7 +19,7 @@ import { * @param {*} inURL */ function removeTrailingSlashes(inURL) { - return inURL && inURL.endsWith('/') ? inURL.replace(/\/+$/, '') : inURL; + return inURL?.endsWith('/') ? inURL.replace(/\/+$/, '') : inURL; } /** diff --git a/packages/analytics-v1.1/types/service-worker/index.d.ts b/packages/analytics-v1.1/types/service-worker/index.d.ts index 0020e4faf5..d15a5d3b75 100644 --- a/packages/analytics-v1.1/types/service-worker/index.d.ts +++ b/packages/analytics-v1.1/types/service-worker/index.d.ts @@ -36,7 +36,7 @@ export type FlushOverrideMessage = { host: string; writeKey: string; data: { - batch: Object[], + batch: Object[]; sentAt: string; }; headers: Record; @@ -44,7 +44,7 @@ export type FlushOverrideMessage = { flush: (callback?: apiCallback) => void; done: (error?: Error) => void; isErrorRetryable: (error: Error) => boolean; -} +}; /** * Represents the constructor options object diff --git a/packages/loading-scripts/CHANGELOG.md b/packages/loading-scripts/CHANGELOG.md index fe89c65e67..c9fa4256b4 100644 --- a/packages/loading-scripts/CHANGELOG.md +++ b/packages/loading-scripts/CHANGELOG.md @@ -2,6 +2,11 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [3.0.59](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-loading-scripts@3.0.58...@rudderstack/analytics-js-loading-scripts@3.0.59) (2024-12-17) + +### Dependency Updates + +* `@rudderstack/analytics-js` updated to version `3.11.16` ## [3.0.58](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-loading-scripts@3.0.57...@rudderstack/analytics-js-loading-scripts@3.0.58) (2024-12-06) ### Dependency Updates diff --git a/packages/loading-scripts/CHANGELOG_LATEST.md b/packages/loading-scripts/CHANGELOG_LATEST.md index 232e50114b..10d6bcfd48 100644 --- a/packages/loading-scripts/CHANGELOG_LATEST.md +++ b/packages/loading-scripts/CHANGELOG_LATEST.md @@ -1,5 +1,5 @@ -## [3.0.58](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-loading-scripts@3.0.57...@rudderstack/analytics-js-loading-scripts@3.0.58) (2024-12-06) +## [3.0.59](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-loading-scripts@3.0.58...@rudderstack/analytics-js-loading-scripts@3.0.59) (2024-12-17) ### Dependency Updates -* `@rudderstack/analytics-js` updated to version `3.11.15` +* `@rudderstack/analytics-js` updated to version `3.11.16` diff --git a/packages/loading-scripts/LICENSE.md b/packages/loading-scripts/LICENSE.md index 554bb72539..37517857b4 100644 --- a/packages/loading-scripts/LICENSE.md +++ b/packages/loading-scripts/LICENSE.md @@ -40,14 +40,14 @@ As far as the law allows, the software comes as is, without any warranty or cond ## Definitions -The *licensor* is the entity offering these terms, and the *software* is the software the licensor makes available under these terms, including any portion of it. +The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it. -*you* refers to the individual or entity agreeing to these terms. +_you_ refers to the individual or entity agreeing to these terms. -*your company* is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. *control* means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. +_your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. -*your licenses* are all the licenses granted to you for the software under these terms. +_your licenses_ are all the licenses granted to you for the software under these terms. -*use* means anything you do with the software requiring one of your licenses. +_use_ means anything you do with the software requiring one of your licenses. -*trademark* means trademarks, service marks, and similar rights. +_trademark_ means trademarks, service marks, and similar rights. diff --git a/packages/loading-scripts/package.json b/packages/loading-scripts/package.json index a74234a413..cb41db9f0e 100644 --- a/packages/loading-scripts/package.json +++ b/packages/loading-scripts/package.json @@ -1,9 +1,9 @@ { "name": "@rudderstack/analytics-js-loading-scripts", - "version": "3.0.58", + "version": "3.0.59", "private": true, "description": "Loading script for RudderStack JavaScript SDK", - "main": "./src/index.js", + "main": "./src/index.ts", "keywords": [ "analytics", "rudder" diff --git a/packages/loading-scripts/project.json b/packages/loading-scripts/project.json index dff8ca8fcb..f096d7c512 100644 --- a/packages/loading-scripts/project.json +++ b/packages/loading-scripts/project.json @@ -44,16 +44,15 @@ "executor": "@jscutlery/semver:version", "options": { "preset": "conventionalcommits", - "tagPrefix": "{projectName}@", - "trackDeps": true + "tagPrefix": "{projectName}@" } }, "github": { "executor": "@jscutlery/semver:github", "options": { - "tag": "@rudderstack/analytics-js-loading-scripts@3.0.58", - "title": "@rudderstack/analytics-js-loading-scripts@3.0.58", - "discussion-category": "@rudderstack/analytics-js-loading-scripts@3.0.58", + "tag": "@rudderstack/analytics-js-loading-scripts@3.0.59", + "title": "@rudderstack/analytics-js-loading-scripts@3.0.59", + "discussion-category": "@rudderstack/analytics-js-loading-scripts@3.0.59", "notesFile": "./packages/loading-scripts/CHANGELOG_LATEST.md" } } diff --git a/packages/loading-scripts/public/index.html b/packages/loading-scripts/public/index.html index 69d1090a9a..62c4372ff9 100644 --- a/packages/loading-scripts/public/index.html +++ b/packages/loading-scripts/public/index.html @@ -1,8 +1,13 @@ - + - + diff --git a/packages/loading-scripts/rollup.config.mjs b/packages/loading-scripts/rollup.config.mjs index 012288e8a3..618e004961 100644 --- a/packages/loading-scripts/rollup.config.mjs +++ b/packages/loading-scripts/rollup.config.mjs @@ -69,53 +69,57 @@ export function getDefaultConfig(distName) { safari10: true, webkit: true, }, - compress: shouldUglify ? { - evaluate: false, - join_vars: false, - toplevel: true, - dead_code: false, - unused: false, - top_retain: [ - 'sdkBaseUrl', - 'sdkName', - 'loadOptions', - 'scriptLoadingMode', - 'rudderanalytics' - ], - booleans: false - } : false, - mangle: shouldUglify ? { - eval: false, - keep_fnames: true, - reserved: [ - 'sdkBaseUrl', - 'sdkName', - 'loadOptions', - 'scriptLoadingMode', - 'rudderanalytics' - ], - toplevel: true, - safari10: true, - } : false, + compress: shouldUglify + ? { + evaluate: false, + join_vars: false, + toplevel: true, + dead_code: false, + unused: false, + top_retain: [ + 'sdkBaseUrl', + 'sdkName', + 'loadOptions', + 'scriptLoadingMode', + 'rudderanalytics', + ], + booleans: false, + } + : false, + mangle: shouldUglify + ? { + eval: false, + keep_fnames: true, + reserved: [ + 'sdkBaseUrl', + 'sdkName', + 'loadOptions', + 'scriptLoadingMode', + 'rudderanalytics', + ], + toplevel: true, + safari10: true, + } + : false, }), isLocalServerEnabled && - htmlTemplate({ - template: process.env.TEST_FILE_PATH || 'public/index.html', - target: 'index.html', - addToHead: true - }), - isLocalServerEnabled && - serve({ - open: true, - openPage: `/index.html`, - contentBase: ['dist'], - host: 'localhost', - port: 3001, - headers: { - 'Access-Control-Allow-Origin': '*', - }, - }), - isLocalServerEnabled && livereload(), + htmlTemplate({ + template: process.env.TEST_FILE_PATH || 'public/index.html', + target: 'index.html', + addToHead: true, + }), + isLocalServerEnabled && + serve({ + open: true, + openPage: `/index.html`, + contentBase: ['dist'], + host: 'localhost', + port: 3001, + headers: { + 'Access-Control-Allow-Origin': '*', + }, + }), + isLocalServerEnabled && livereload(), ], }; } diff --git a/packages/loading-scripts/src/types/rudderanalytics.d.ts b/packages/loading-scripts/src/types/rudderanalytics.d.ts index 841e99d66a..e310406501 100644 --- a/packages/loading-scripts/src/types/rudderanalytics.d.ts +++ b/packages/loading-scripts/src/types/rudderanalytics.d.ts @@ -9,7 +9,7 @@ declare global { rudderanalytics: RudderAnalytics | RudderAnalyticsPreloader | undefined; rudderAnalyticsMount: () => void; rudderAnalyticsBuildType: 'legacy' | 'modern'; - RudderSnippetVersion?: string; + RudderSnippetVersion: string; rudderAnalyticsAddScript: ( url: string, extraAttributeKey?: string, diff --git a/packages/sanity-suite/CHANGELOG.md b/packages/sanity-suite/CHANGELOG.md index 244f3bfa83..1314dbba2f 100644 --- a/packages/sanity-suite/CHANGELOG.md +++ b/packages/sanity-suite/CHANGELOG.md @@ -2,6 +2,11 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +## [3.1.50](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-sanity-suite@3.1.49...@rudderstack/analytics-js-sanity-suite@3.1.50) (2024-12-17) + +### Dependency Updates + +* `@rudderstack/analytics-js` updated to version `3.11.16` ## [3.1.49](https://github.com/rudderlabs/rudder-sdk-js/compare/@rudderstack/analytics-js-sanity-suite@3.1.48...@rudderstack/analytics-js-sanity-suite@3.1.49) (2024-12-06) ### Dependency Updates diff --git a/packages/sanity-suite/LICENSE.md b/packages/sanity-suite/LICENSE.md index 554bb72539..37517857b4 100644 --- a/packages/sanity-suite/LICENSE.md +++ b/packages/sanity-suite/LICENSE.md @@ -40,14 +40,14 @@ As far as the law allows, the software comes as is, without any warranty or cond ## Definitions -The *licensor* is the entity offering these terms, and the *software* is the software the licensor makes available under these terms, including any portion of it. +The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it. -*you* refers to the individual or entity agreeing to these terms. +_you_ refers to the individual or entity agreeing to these terms. -*your company* is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. *control* means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. +_your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. -*your licenses* are all the licenses granted to you for the software under these terms. +_your licenses_ are all the licenses granted to you for the software under these terms. -*use* means anything you do with the software requiring one of your licenses. +_use_ means anything you do with the software requiring one of your licenses. -*trademark* means trademarks, service marks, and similar rights. +_trademark_ means trademarks, service marks, and similar rights. diff --git a/packages/sanity-suite/package.json b/packages/sanity-suite/package.json index f520de48e6..e2829a33ef 100644 --- a/packages/sanity-suite/package.json +++ b/packages/sanity-suite/package.json @@ -1,6 +1,6 @@ { "name": "@rudderstack/analytics-js-sanity-suite", - "version": "3.1.49", + "version": "3.1.50", "private": true, "description": "Sanity suite for testing JS SDK package", "main": "./dist/v3/cdn/testBook.js", diff --git a/packages/sanity-suite/public/v1.1/index-cdn.html b/packages/sanity-suite/public/v1.1/index-cdn.html index 0c58202060..7e66d1d29c 100644 --- a/packages/sanity-suite/public/v1.1/index-cdn.html +++ b/packages/sanity-suite/public/v1.1/index-cdn.html @@ -1,12 +1,17 @@ - + - + RudderStack JS SDK Sanity Suite + crossorigin="anonymous"> - + crossorigin="anonymous"> + + src="https://cdn.rudderlabs.com/__CDN_VERSION_PATH__/rudder-analytics.min.js">
diff --git a/packages/sanity-suite/public/v1.1/index-local.html b/packages/sanity-suite/public/v1.1/index-local.html index a7f13349f0..a41ffd2d36 100644 --- a/packages/sanity-suite/public/v1.1/index-local.html +++ b/packages/sanity-suite/public/v1.1/index-local.html @@ -1,121 +1,114 @@ - - - - + + + + RudderStack JS SDK Sanity Suite + crossorigin="anonymous" /> + href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" /> + crossorigin="anonymous"> - + crossorigin="anonymous"> + - - - -
-
-
-
+ + +
+
+
+
-
- + diff --git a/packages/sanity-suite/public/v1.1/index-npm.html b/packages/sanity-suite/public/v1.1/index-npm.html index e4601f4122..c7d0698e9f 100644 --- a/packages/sanity-suite/public/v1.1/index-npm.html +++ b/packages/sanity-suite/public/v1.1/index-npm.html @@ -1,12 +1,17 @@ - + - + RudderStack JS SDK Sanity Suite + crossorigin="anonymous" /> + href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" /> + crossorigin="anonymous"> - + crossorigin="anonymous"> + + src="https://cdn.rudderlabs.com/__CDN_VERSION_PATH__/rudder-analytics.min.js"> + crossorigin="anonymous" /> + href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" /> + crossorigin="anonymous"> - + crossorigin="anonymous"> + + crossorigin="anonymous"> - + crossorigin="anonymous"> + @@ -80,25 +81,19 @@ rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" - crossorigin="anonymous" - /> + crossorigin="anonymous" /> + href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" /> + crossorigin="anonymous"> - + crossorigin="anonymous"> + + src="https://cdn.rudderlabs.com/__CDN_VERSION_PATH__/rudder-analytics.min.js"> + crossorigin="anonymous" /> + href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" /> + crossorigin="anonymous"> - + crossorigin="anonymous"> + + crossorigin="anonymous"> - + crossorigin="anonymous"> + - + - + + crossorigin="anonymous" /> + href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" /> + crossorigin="anonymous"> - + crossorigin="anonymous"> + - + + crossorigin="anonymous" /> + href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" /> + crossorigin="anonymous"> - + crossorigin="anonymous"> + - + - + + crossorigin="anonymous"> - + crossorigin="anonymous"> + - + + crossorigin="anonymous"> - + crossorigin="anonymous"> + - + - + + crossorigin="anonymous"> - + crossorigin="anonymous"> + - + + crossorigin="anonymous"> - + crossorigin="anonymous"> +