utneque 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +10 -0
- package/.eslintrc.isomorphic.js +26 -0
- package/.eslintrc.js +86 -0
- package/.gitattributes +1 -0
- package/.github/workflows/ci.yml +33 -0
- package/.github/workflows/deploy-browser-cdn-candidate.yml +51 -0
- package/.github/workflows/deploy-releases.yml +178 -0
- package/.nvmrc +1 -0
- package/.prettierrc +7 -0
- package/.vscode/extensions.json +3 -0
- package/.vscode/launch.json +81 -0
- package/.vscode/settings.json +41 -0
- package/.yarn/plugins/@yarnpkg/plugin-constraints.cjs +52 -0
- package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +546 -0
- package/.yarn/plugins/@yarnpkg/plugin-typescript.cjs +9 -0
- package/.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs +28 -0
- package/.yarn/releases/yarn-3.4.1.cjs +873 -0
- package/.yarnrc.yml +15 -0
- package/jest.config.js +18 -0
- package/package.json +59 -0
- package/packages/browser/.eslintrc.js +9 -0
- package/packages/browser/.lintstagedrc.js +1 -0
- package/packages/browser/ARCHITECTURE.md +48 -0
- package/packages/browser/LICENSE.MD +45 -0
- package/packages/browser/Makefile +64 -0
- package/packages/browser/README.md +227 -0
- package/packages/browser/e2e-tests/local-server.ts +28 -0
- package/packages/browser/e2e-tests/performance/ajs-perf-browser.test.ts +75 -0
- package/packages/browser/jest.config.js +15 -0
- package/packages/browser/jest.setup.js +10 -0
- package/packages/browser/package.json +106 -0
- package/packages/browser/qa/README.md +41 -0
- package/packages/browser/qa/__fixtures__/snippets.ts +148 -0
- package/packages/browser/qa/__tests__/backwards-compatibility.test.ts +180 -0
- package/packages/browser/qa/__tests__/destinations.test.ts +101 -0
- package/packages/browser/qa/__tests__/smoke.test.ts +170 -0
- package/packages/browser/qa/lib/benchmark.ts +36 -0
- package/packages/browser/qa/lib/browser.ts +28 -0
- package/packages/browser/qa/lib/jest-reporter.js +57 -0
- package/packages/browser/qa/lib/runner.ts +142 -0
- package/packages/browser/qa/lib/schema.ts +59 -0
- package/packages/browser/qa/lib/server.ts +54 -0
- package/packages/browser/qa/lib/stats.ts +52 -0
- package/packages/browser/scripts/build-prep.sh +7 -0
- package/packages/browser/scripts/ci.sh +15 -0
- package/packages/browser/scripts/release.js +121 -0
- package/packages/browser/scripts/release.sh +9 -0
- package/packages/browser/scripts/run.sh +8 -0
- package/packages/browser/src/browser/__tests__/analytics-lazy-init.integration.test.ts +51 -0
- package/packages/browser/src/browser/__tests__/analytics-pre-init.integration.test.ts +440 -0
- package/packages/browser/src/browser/__tests__/anon-id-and-reset.integration.test.ts +73 -0
- package/packages/browser/src/browser/__tests__/cdn.test.ts +53 -0
- package/packages/browser/src/browser/__tests__/csp-detection.test.ts +140 -0
- package/packages/browser/src/browser/__tests__/inspector.integration.test.ts +121 -0
- package/packages/browser/src/browser/__tests__/integration.test.ts +1213 -0
- package/packages/browser/src/browser/__tests__/integrations.integration.test.ts +260 -0
- package/packages/browser/src/browser/__tests__/page-enrichment.integration.test.ts +216 -0
- package/packages/browser/src/browser/__tests__/query-string.integration.test.ts +116 -0
- package/packages/browser/src/browser/__tests__/standalone-analytics.test.ts +303 -0
- package/packages/browser/src/browser/__tests__/standalone-errors.test.ts +136 -0
- package/packages/browser/src/browser/__tests__/standalone.test.ts +97 -0
- package/packages/browser/src/browser/__tests__/typedef-tests/analytics-browser.ts +150 -0
- package/packages/browser/src/browser/__tests__/update-cdn-settings.test.ts +71 -0
- package/packages/browser/src/browser/browser-umd.ts +19 -0
- package/packages/browser/src/browser/index.ts +486 -0
- package/packages/browser/src/browser/standalone-analytics.ts +62 -0
- package/packages/browser/src/browser/standalone-interface.ts +11 -0
- package/packages/browser/src/browser/standalone.ts +92 -0
- package/packages/browser/src/core/__tests__/track-form.test.ts +193 -0
- package/packages/browser/src/core/__tests__/track-link.test.ts +252 -0
- package/packages/browser/src/core/analytics/__tests__/integration.test.ts +334 -0
- package/packages/browser/src/core/analytics/__tests__/test-plugins.ts +94 -0
- package/packages/browser/src/core/analytics/index.ts +672 -0
- package/packages/browser/src/core/analytics/interfaces.ts +100 -0
- package/packages/browser/src/core/arguments-resolver/__tests__/index.test.ts +524 -0
- package/packages/browser/src/core/arguments-resolver/index.ts +200 -0
- package/packages/browser/src/core/auto-track.ts +152 -0
- package/packages/browser/src/core/buffer/__tests__/index.test.ts +455 -0
- package/packages/browser/src/core/buffer/index.ts +371 -0
- package/packages/browser/src/core/callback/index.ts +1 -0
- package/packages/browser/src/core/connection/__tests__/index.test.ts +25 -0
- package/packages/browser/src/core/connection/index.ts +13 -0
- package/packages/browser/src/core/constants/index.ts +1 -0
- package/packages/browser/src/core/context/__tests__/index.test.ts +201 -0
- package/packages/browser/src/core/context/index.ts +21 -0
- package/packages/browser/src/core/environment/index.ts +7 -0
- package/packages/browser/src/core/events/__tests__/index.test.ts +450 -0
- package/packages/browser/src/core/events/index.ts +280 -0
- package/packages/browser/src/core/events/interfaces.ts +36 -0
- package/packages/browser/src/core/inspector/index.ts +14 -0
- package/packages/browser/src/core/page/__tests__/index.test.ts +130 -0
- package/packages/browser/src/core/page/add-page-context.ts +33 -0
- package/packages/browser/src/core/page/get-page-context.ts +140 -0
- package/packages/browser/src/core/page/index.ts +2 -0
- package/packages/browser/src/core/plugin/index.ts +12 -0
- package/packages/browser/src/core/query-string/__tests__/gracefulDecodeURIComponent.test.ts +17 -0
- package/packages/browser/src/core/query-string/__tests__/index.test.ts +149 -0
- package/packages/browser/src/core/query-string/__tests__/pickPrefix.test.ts +31 -0
- package/packages/browser/src/core/query-string/__tests__/useQueryString.test.ts +60 -0
- package/packages/browser/src/core/query-string/gracefulDecodeURIComponent.ts +16 -0
- package/packages/browser/src/core/query-string/index.ts +64 -0
- package/packages/browser/src/core/query-string/pickPrefix.ts +20 -0
- package/packages/browser/src/core/queue/__tests__/event-queue.test.ts +82 -0
- package/packages/browser/src/core/queue/event-queue.ts +22 -0
- package/packages/browser/src/core/session/__tests__/index.test.ts +41 -0
- package/packages/browser/src/core/session/index.ts +107 -0
- package/packages/browser/src/core/stats/__tests__/index.test.ts +15 -0
- package/packages/browser/src/core/stats/__tests__/remote-metrics.test.ts +189 -0
- package/packages/browser/src/core/stats/index.ts +15 -0
- package/packages/browser/src/core/stats/remote-metrics.ts +144 -0
- package/packages/browser/src/core/storage/__tests__/cookieStorage.test.ts +58 -0
- package/packages/browser/src/core/storage/__tests__/localStorage.test.ts +70 -0
- package/packages/browser/src/core/storage/__tests__/test-helpers.ts +26 -0
- package/packages/browser/src/core/storage/__tests__/universalStorage.test.ts +167 -0
- package/packages/browser/src/core/storage/cookieStorage.ts +80 -0
- package/packages/browser/src/core/storage/index.ts +64 -0
- package/packages/browser/src/core/storage/localStorage.ts +45 -0
- package/packages/browser/src/core/storage/memoryStorage.ts +22 -0
- package/packages/browser/src/core/storage/settings.ts +23 -0
- package/packages/browser/src/core/storage/types.ts +49 -0
- package/packages/browser/src/core/storage/universalStorage.ts +78 -0
- package/packages/browser/src/core/user/__tests__/index.test.ts +922 -0
- package/packages/browser/src/core/user/__tests__/migrate.test.ts +101 -0
- package/packages/browser/src/core/user/__tests__/session.test.ts +136 -0
- package/packages/browser/src/core/user/__tests__/tld.test.ts +36 -0
- package/packages/browser/src/core/user/index.ts +399 -0
- package/packages/browser/src/core/user/migrate.ts +126 -0
- package/packages/browser/src/core/user/tld.ts +65 -0
- package/packages/browser/src/core/user/vendor/crypto-es/LICENSE +53 -0
- package/packages/browser/src/core/user/vendor/crypto-es/lib/aes.ts +302 -0
- package/packages/browser/src/core/user/vendor/crypto-es/lib/cipher-core.ts +922 -0
- package/packages/browser/src/core/user/vendor/crypto-es/lib/core.ts +806 -0
- package/packages/browser/src/core/user/vendor/crypto-es/lib/enc-base64.ts +110 -0
- package/packages/browser/src/core/user/vendor/crypto-es/lib/evpkdf.ts +110 -0
- package/packages/browser/src/core/user/vendor/crypto-es/lib/md5.ts +238 -0
- package/packages/browser/src/core/user/vendor/readme.md +7 -0
- package/packages/browser/src/generated/__tests__/version.test.ts +18 -0
- package/packages/browser/src/generated/version.ts +2 -0
- package/packages/browser/src/index.ts +13 -0
- package/packages/browser/src/lib/__tests__/embedded-write-key.test.ts +15 -0
- package/packages/browser/src/lib/__tests__/fetch.test.ts +35 -0
- package/packages/browser/src/lib/__tests__/get-process-env.test.ts +5 -0
- package/packages/browser/src/lib/__tests__/group-by.test.ts +96 -0
- package/packages/browser/src/lib/__tests__/is-plan-event-enabled.test.ts +36 -0
- package/packages/browser/src/lib/__tests__/is-thenable.test.ts +39 -0
- package/packages/browser/src/lib/__tests__/merged-options.test.ts +123 -0
- package/packages/browser/src/lib/__tests__/on-page-change.test.ts +74 -0
- package/packages/browser/src/lib/__tests__/parse-cdn.test.ts +88 -0
- package/packages/browser/src/lib/__tests__/pick.test.ts +34 -0
- package/packages/browser/src/lib/__tests__/pick.typedef.ts +39 -0
- package/packages/browser/src/lib/bind-all.ts +19 -0
- package/packages/browser/src/lib/browser-polyfill.ts +23 -0
- package/packages/browser/src/lib/client-hints/__tests__/index.test.ts +66 -0
- package/packages/browser/src/lib/client-hints/index.ts +16 -0
- package/packages/browser/src/lib/client-hints/interfaces.ts +42 -0
- package/packages/browser/src/lib/create-deferred.ts +16 -0
- package/packages/browser/src/lib/csp-detection.ts +8 -0
- package/packages/browser/src/lib/embedded-write-key.ts +24 -0
- package/packages/browser/src/lib/fetch.ts +10 -0
- package/packages/browser/src/lib/get-global.ts +16 -0
- package/packages/browser/src/lib/get-process-env.ts +11 -0
- package/packages/browser/src/lib/global-analytics-helper.ts +31 -0
- package/packages/browser/src/lib/group-by.ts +30 -0
- package/packages/browser/src/lib/is-plan-event-enabled.ts +20 -0
- package/packages/browser/src/lib/is-thenable.ts +9 -0
- package/packages/browser/src/lib/load-script.ts +66 -0
- package/packages/browser/src/lib/merged-options.ts +46 -0
- package/packages/browser/src/lib/on-page-change.ts +29 -0
- package/packages/browser/src/lib/p-while.ts +12 -0
- package/packages/browser/src/lib/parse-cdn.ts +56 -0
- package/packages/browser/src/lib/pick.ts +28 -0
- package/packages/browser/src/lib/priority-queue/__tests__/backoff.test.ts +23 -0
- package/packages/browser/src/lib/priority-queue/__tests__/index.test.ts +158 -0
- package/packages/browser/src/lib/priority-queue/__tests__/persisted.test.ts +228 -0
- package/packages/browser/src/lib/priority-queue/backoff.ts +24 -0
- package/packages/browser/src/lib/priority-queue/index.ts +6 -0
- package/packages/browser/src/lib/priority-queue/persisted.ts +127 -0
- package/packages/browser/src/lib/sleep.ts +4 -0
- package/packages/browser/src/lib/to-facade.ts +53 -0
- package/packages/browser/src/lib/version-type.ts +10 -0
- package/packages/browser/src/node/__tests__/node-integration.test.ts +19 -0
- package/packages/browser/src/node/index.ts +36 -0
- package/packages/browser/src/node/node.browser.ts +7 -0
- package/packages/browser/src/plugins/ajs-destination/__tests__/index.test.ts +834 -0
- package/packages/browser/src/plugins/ajs-destination/index.ts +392 -0
- package/packages/browser/src/plugins/ajs-destination/loader.ts +129 -0
- package/packages/browser/src/plugins/ajs-destination/types.ts +44 -0
- package/packages/browser/src/plugins/ajs-destination/utils.ts +32 -0
- package/packages/browser/src/plugins/analytics-node/__tests__/index.test.ts +69 -0
- package/packages/browser/src/plugins/analytics-node/index.ts +67 -0
- package/packages/browser/src/plugins/env-enrichment/__tests__/index.test.ts +421 -0
- package/packages/browser/src/plugins/env-enrichment/index.ts +208 -0
- package/packages/browser/src/plugins/hightouchio/__tests__/batched-dispatcher.test.ts +299 -0
- package/packages/browser/src/plugins/hightouchio/__tests__/index.test.ts +317 -0
- package/packages/browser/src/plugins/hightouchio/__tests__/normalize.test.ts +181 -0
- package/packages/browser/src/plugins/hightouchio/__tests__/retries.test.ts +82 -0
- package/packages/browser/src/plugins/hightouchio/batched-dispatcher.ts +127 -0
- package/packages/browser/src/plugins/hightouchio/fetch-dispatcher.ts +27 -0
- package/packages/browser/src/plugins/hightouchio/index.ts +147 -0
- package/packages/browser/src/plugins/hightouchio/normalize.ts +71 -0
- package/packages/browser/src/plugins/hightouchio/schedule-flush.ts +58 -0
- package/packages/browser/src/plugins/legacy-video-plugins/__tests__/index.test.ts +48 -0
- package/packages/browser/src/plugins/legacy-video-plugins/index.ts +16 -0
- package/packages/browser/src/plugins/middleware/__tests__/index.test.ts +268 -0
- package/packages/browser/src/plugins/middleware/index.ts +131 -0
- package/packages/browser/src/plugins/remote-loader/__tests__/index.test.ts +943 -0
- package/packages/browser/src/plugins/remote-loader/index.ts +256 -0
- package/packages/browser/src/plugins/remote-middleware/__tests__/index.test.ts +116 -0
- package/packages/browser/src/plugins/remote-middleware/index.ts +44 -0
- package/packages/browser/src/plugins/routing-middleware/__tests__/index.test.ts +64 -0
- package/packages/browser/src/plugins/routing-middleware/index.ts +37 -0
- package/packages/browser/src/plugins/schema-filter/__tests__/index.test.ts +520 -0
- package/packages/browser/src/plugins/schema-filter/index.ts +90 -0
- package/packages/browser/src/plugins/validation/__tests__/index.test.ts +78 -0
- package/packages/browser/src/plugins/validation/index.ts +44 -0
- package/packages/browser/src/test-helpers/browser-storage.ts +75 -0
- package/packages/browser/src/test-helpers/factories.ts +18 -0
- package/packages/browser/src/test-helpers/fetch-parse.ts +8 -0
- package/packages/browser/src/test-helpers/fixtures/cdn-settings.ts +301 -0
- package/packages/browser/src/test-helpers/fixtures/classic-destination.ts +25 -0
- package/packages/browser/src/test-helpers/fixtures/client-hints.ts +28 -0
- package/packages/browser/src/test-helpers/fixtures/create-fetch-method.ts +30 -0
- package/packages/browser/src/test-helpers/fixtures/index.ts +4 -0
- package/packages/browser/src/test-helpers/fixtures/page-context.ts +11 -0
- package/packages/browser/src/test-helpers/test-writekeys.ts +5 -0
- package/packages/browser/src/test-helpers/type-assertions.ts +11 -0
- package/packages/browser/src/tester/__fixtures__/hightouch-snippet.ts +64 -0
- package/packages/browser/src/tester/__fixtures__/index.html +8 -0
- package/packages/browser/src/tester/ajs-perf.ts +30 -0
- package/packages/browser/src/tester/ajs-tester.ts +119 -0
- package/packages/browser/src/tester/server.js +16 -0
- package/packages/browser/tsconfig.build.json +9 -0
- package/packages/browser/tsconfig.json +13 -0
- package/packages/browser/webpack.config.js +106 -0
- package/packages/config/package.json +10 -0
- package/packages/config/src/index.js +4 -0
- package/packages/config/src/jest/config.js +50 -0
- package/packages/config/src/jest/get-module-map.js +34 -0
- package/packages/config/src/lint-staged/config.js +4 -0
- package/packages/config-webpack/package.json +20 -0
- package/packages/config-webpack/webpack.config.common.js +75 -0
- package/packages/consent/consent-tools/.eslintrc.js +7 -0
- package/packages/consent/consent-tools/.lintstagedrc.js +1 -0
- package/packages/consent/consent-tools/LICENSE +45 -0
- package/packages/consent/consent-tools/README.md +104 -0
- package/packages/consent/consent-tools/jest.config.js +6 -0
- package/packages/consent/consent-tools/jest.setup.js +4 -0
- package/packages/consent/consent-tools/package.json +48 -0
- package/packages/consent/consent-tools/src/domain/__tests__/assertions/integrations-assertions.ts +37 -0
- package/packages/consent/consent-tools/src/domain/__tests__/consent-stamping.test.ts +45 -0
- package/packages/consent/consent-tools/src/domain/__tests__/create-wrapper.test.ts +816 -0
- package/packages/consent/consent-tools/src/domain/__tests__/typedef-tests.ts +21 -0
- package/packages/consent/consent-tools/src/domain/consent-changed.ts +51 -0
- package/packages/consent/consent-tools/src/domain/consent-stamping.ts +19 -0
- package/packages/consent/consent-tools/src/domain/create-wrapper.ts +238 -0
- package/packages/consent/consent-tools/src/domain/get-initialized-analytics.ts +25 -0
- package/packages/consent/consent-tools/src/domain/load-cancellation.ts +31 -0
- package/packages/consent/consent-tools/src/domain/validation/__tests__/options-validators.test.ts +77 -0
- package/packages/consent/consent-tools/src/domain/validation/__tests__/validation-error.test.ts +15 -0
- package/packages/consent/consent-tools/src/domain/validation/common-validators.ts +19 -0
- package/packages/consent/consent-tools/src/domain/validation/index.ts +1 -0
- package/packages/consent/consent-tools/src/domain/validation/options-validators.ts +74 -0
- package/packages/consent/consent-tools/src/domain/validation/validation-error.ts +11 -0
- package/packages/consent/consent-tools/src/index.ts +16 -0
- package/packages/consent/consent-tools/src/types/errors.ts +14 -0
- package/packages/consent/consent-tools/src/types/index.ts +3 -0
- package/packages/consent/consent-tools/src/types/settings.ts +121 -0
- package/packages/consent/consent-tools/src/types/wrapper.ts +107 -0
- package/packages/consent/consent-tools/src/utils/index.ts +4 -0
- package/packages/consent/consent-tools/src/utils/pick.ts +18 -0
- package/packages/consent/consent-tools/src/utils/pipe.ts +14 -0
- package/packages/consent/consent-tools/src/utils/resolve-when.ts +32 -0
- package/packages/consent/consent-tools/src/utils/uniq.ts +4 -0
- package/packages/consent/consent-tools/tsconfig.build.json +9 -0
- package/packages/consent/consent-tools/tsconfig.json +12 -0
- package/packages/consent/consent-wrapper-onetrust/.eslintrc.js +7 -0
- package/packages/consent/consent-wrapper-onetrust/.lintstagedrc.js +1 -0
- package/packages/consent/consent-wrapper-onetrust/LICENSE +45 -0
- package/packages/consent/consent-wrapper-onetrust/README.md +125 -0
- package/packages/consent/consent-wrapper-onetrust/img/onetrust-cat-id.jpg +0 -0
- package/packages/consent/consent-wrapper-onetrust/img/onetrust-popup.jpg +0 -0
- package/packages/consent/consent-wrapper-onetrust/jest.config.js +6 -0
- package/packages/consent/consent-wrapper-onetrust/jest.setup.js +4 -0
- package/packages/consent/consent-wrapper-onetrust/package.json +60 -0
- package/packages/consent/consent-wrapper-onetrust/src/domain/__tests__/wrapper.test.ts +151 -0
- package/packages/consent/consent-wrapper-onetrust/src/domain/wrapper.ts +61 -0
- package/packages/consent/consent-wrapper-onetrust/src/index.ts +6 -0
- package/packages/consent/consent-wrapper-onetrust/src/index.umd.ts +11 -0
- package/packages/consent/consent-wrapper-onetrust/src/lib/__tests__/onetrust-api.test.ts +181 -0
- package/packages/consent/consent-wrapper-onetrust/src/lib/onetrust-api.ts +155 -0
- package/packages/consent/consent-wrapper-onetrust/src/lib/validation/index.ts +1 -0
- package/packages/consent/consent-wrapper-onetrust/src/lib/validation/onetrust-api-error.ts +11 -0
- package/packages/consent/consent-wrapper-onetrust/src/test-helpers/mocks.ts +23 -0
- package/packages/consent/consent-wrapper-onetrust/src/test-helpers/onetrust-globals.d.ts +11 -0
- package/packages/consent/consent-wrapper-onetrust/src/test-helpers/utils.ts +3 -0
- package/packages/consent/consent-wrapper-onetrust/tsconfig.build.json +9 -0
- package/packages/consent/consent-wrapper-onetrust/tsconfig.json +11 -0
- package/packages/consent/consent-wrapper-onetrust/webpack.config.js +25 -0
- package/packages/core/.eslintrc.js +4 -0
- package/packages/core/.lintstagedrc.js +1 -0
- package/packages/core/LICENSE.MD +45 -0
- package/packages/core/README.md +3 -0
- package/packages/core/jest.config.js +5 -0
- package/packages/core/jest.setup.js +10 -0
- package/packages/core/package.json +40 -0
- package/packages/core/src/analytics/__tests__/dispatch.test.ts +95 -0
- package/packages/core/src/analytics/dispatch.ts +58 -0
- package/packages/core/src/analytics/index.ts +11 -0
- package/packages/core/src/callback/__tests__/index.test.ts +85 -0
- package/packages/core/src/callback/index.ts +51 -0
- package/packages/core/src/context/index.ts +123 -0
- package/packages/core/src/emitter/__tests__/emitter.test.ts +74 -0
- package/packages/core/src/emitter/index.ts +65 -0
- package/packages/core/src/emitter/interface.ts +31 -0
- package/packages/core/src/events/__tests__/index.test.ts +394 -0
- package/packages/core/src/events/index.ts +280 -0
- package/packages/core/src/events/interfaces.ts +475 -0
- package/packages/core/src/index.ts +19 -0
- package/packages/core/src/logger/__tests__/index.test.ts +66 -0
- package/packages/core/src/logger/index.ts +74 -0
- package/packages/core/src/plugins/index.ts +43 -0
- package/packages/core/src/priority-queue/__tests__/backoff.test.ts +23 -0
- package/packages/core/src/priority-queue/__tests__/index.test.ts +158 -0
- package/packages/core/src/priority-queue/backoff.ts +24 -0
- package/packages/core/src/priority-queue/index.ts +103 -0
- package/packages/core/src/queue/__tests__/event-queue.test.ts +678 -0
- package/packages/core/src/queue/__tests__/extension-flushing.test.ts +416 -0
- package/packages/core/src/queue/delivery.ts +73 -0
- package/packages/core/src/queue/event-queue.ts +318 -0
- package/packages/core/src/stats/__tests__/index.test.ts +103 -0
- package/packages/core/src/stats/index.ts +88 -0
- package/packages/core/src/task/__tests__/task-group.test.ts +26 -0
- package/packages/core/src/task/task-group.ts +31 -0
- package/packages/core/src/user/index.ts +7 -0
- package/packages/core/src/utils/__tests__/group-by.test.ts +96 -0
- package/packages/core/src/utils/__tests__/is-plain-object.test.ts +27 -0
- package/packages/core/src/utils/__tests__/is-thenable.test.ts +39 -0
- package/packages/core/src/utils/bind-all.ts +19 -0
- package/packages/core/src/utils/get-global.ts +17 -0
- package/packages/core/src/utils/group-by.ts +30 -0
- package/packages/core/src/utils/has-properties.ts +7 -0
- package/packages/core/src/utils/is-plain-object.ts +26 -0
- package/packages/core/src/utils/is-thenable.ts +9 -0
- package/packages/core/src/utils/p-while.ts +12 -0
- package/packages/core/src/utils/pick.ts +8 -0
- package/packages/core/src/utils/ts-helpers.ts +13 -0
- package/packages/core/src/validation/__tests__/assertions.test.ts +155 -0
- package/packages/core/src/validation/assertions.ts +72 -0
- package/packages/core/src/validation/errors.ts +8 -0
- package/packages/core/src/validation/helpers.ts +23 -0
- package/packages/core/test-helpers/index.ts +2 -0
- package/packages/core/test-helpers/test-ctx.ts +7 -0
- package/packages/core/test-helpers/test-event-queue.ts +7 -0
- package/packages/core/tsconfig.build.json +9 -0
- package/packages/core/tsconfig.json +11 -0
- package/packages/node/.eslintrc.js +7 -0
- package/packages/node/.lintstagedrc.js +1 -0
- package/packages/node/LICENSE +45 -0
- package/packages/node/README.md +138 -0
- package/packages/node/jest.config.js +5 -0
- package/packages/node/jest.setup.js +4 -0
- package/packages/node/package.json +50 -0
- package/packages/node/scripts/version.sh +11 -0
- package/packages/node/src/__tests__/callback.test.ts +47 -0
- package/packages/node/src/__tests__/disable.integration.test.ts +42 -0
- package/packages/node/src/__tests__/emitter.integration.test.ts +45 -0
- package/packages/node/src/__tests__/graceful-shutdown-integration.test.ts +244 -0
- package/packages/node/src/__tests__/http-client.integration.test.ts +69 -0
- package/packages/node/src/__tests__/http-integration.test.ts +362 -0
- package/packages/node/src/__tests__/integration.test.ts +357 -0
- package/packages/node/src/__tests__/plugins.test.ts +16 -0
- package/packages/node/src/__tests__/settings.test.ts +9 -0
- package/packages/node/src/__tests__/test-helpers/assert-shape/http-request-event.ts +13 -0
- package/packages/node/src/__tests__/test-helpers/assert-shape/index.ts +2 -0
- package/packages/node/src/__tests__/test-helpers/assert-shape/segment-http-api.ts +43 -0
- package/packages/node/src/__tests__/test-helpers/create-test-analytics.ts +42 -0
- package/packages/node/src/__tests__/test-helpers/factories.ts +17 -0
- package/packages/node/src/__tests__/test-helpers/is-valid-date.ts +6 -0
- package/packages/node/src/__tests__/test-helpers/resolve-ctx.ts +19 -0
- package/packages/node/src/__tests__/test-helpers/resolve-emitter.ts +11 -0
- package/packages/node/src/__tests__/test-helpers/sleep.ts +3 -0
- package/packages/node/src/__tests__/test-helpers/test-plugin.ts +16 -0
- package/packages/node/src/__tests__/typedef-tests.ts +120 -0
- package/packages/node/src/app/analytics-node.ts +299 -0
- package/packages/node/src/app/context.ts +11 -0
- package/packages/node/src/app/dispatch-emit.ts +42 -0
- package/packages/node/src/app/emitter.ts +23 -0
- package/packages/node/src/app/event-factory.ts +20 -0
- package/packages/node/src/app/event-queue.ts +23 -0
- package/packages/node/src/app/settings.ts +49 -0
- package/packages/node/src/app/types/index.ts +3 -0
- package/packages/node/src/app/types/params.ts +76 -0
- package/packages/node/src/app/types/plugin.ts +5 -0
- package/packages/node/src/app/types/segment-event.ts +7 -0
- package/packages/node/src/generated/version.ts +2 -0
- package/packages/node/src/index.ts +26 -0
- package/packages/node/src/lib/__tests__/abort.test.ts +54 -0
- package/packages/node/src/lib/__tests__/create-url.test.ts +35 -0
- package/packages/node/src/lib/__tests__/env.test.ts +52 -0
- package/packages/node/src/lib/__tests__/get-message-id.test.ts +21 -0
- package/packages/node/src/lib/abort.ts +77 -0
- package/packages/node/src/lib/base-64-encode.ts +8 -0
- package/packages/node/src/lib/create-url.ts +11 -0
- package/packages/node/src/lib/env.ts +45 -0
- package/packages/node/src/lib/extract-promise-parts.ts +21 -0
- package/packages/node/src/lib/fetch.ts +16 -0
- package/packages/node/src/lib/get-message-id.ts +10 -0
- package/packages/node/src/lib/http-client.ts +95 -0
- package/packages/node/src/lib/uuid.ts +1 -0
- package/packages/node/src/plugins/segmentio/__tests__/methods.test.ts +223 -0
- package/packages/node/src/plugins/segmentio/__tests__/publisher.test.ts +411 -0
- package/packages/node/src/plugins/segmentio/context-batch.ts +71 -0
- package/packages/node/src/plugins/segmentio/index.ts +66 -0
- package/packages/node/src/plugins/segmentio/publisher.ts +265 -0
- package/packages/node/tsconfig.build.json +9 -0
- package/packages/node/tsconfig.json +10 -0
- package/packages/test-helpers/.eslintrc.js +7 -0
- package/packages/test-helpers/.lintstagedrc.js +1 -0
- package/packages/test-helpers/jest.config.js +3 -0
- package/packages/test-helpers/package.json +26 -0
- package/packages/test-helpers/src/analytics/cdn-settings-builder.ts +79 -0
- package/packages/test-helpers/src/analytics/index.ts +1 -0
- package/packages/test-helpers/src/index.ts +2 -0
- package/packages/test-helpers/src/utils/index.ts +1 -0
- package/packages/test-helpers/src/utils/sleep.ts +4 -0
- package/packages/test-helpers/tsconfig.build.json +9 -0
- package/packages/test-helpers/tsconfig.json +11 -0
- package/tsconfig.json +21 -0
- package/turbo.json +39 -0
- package/typings/get-monorepo-packages.d.ts +9 -0
- package/typings/spawn.d.ts +10 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { queryString } from '..'
|
|
2
|
+
import { Analytics } from '../../analytics'
|
|
3
|
+
|
|
4
|
+
let analytics: Analytics
|
|
5
|
+
|
|
6
|
+
describe('queryString', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
analytics = new Analytics({
|
|
9
|
+
writeKey: 'abc',
|
|
10
|
+
})
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
describe('calls', () => {
|
|
14
|
+
describe('identify', () => {
|
|
15
|
+
it('if `ajs_uid` is present', async () => {
|
|
16
|
+
const spy = jest.spyOn(analytics, 'identify')
|
|
17
|
+
await queryString(analytics, '?ajs_uid=1234')
|
|
18
|
+
expect(spy).toHaveBeenCalledWith('1234', {})
|
|
19
|
+
spy.mockRestore()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('accepts encoded emails as `ajs_uid` params', async () => {
|
|
23
|
+
const spy = jest.spyOn(analytics, 'identify')
|
|
24
|
+
await queryString(analytics, '?ajs_uid=user%40example.org')
|
|
25
|
+
expect(spy).toHaveBeenCalledWith('user@example.org', {})
|
|
26
|
+
spy.mockRestore()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('applies traits if `ajs_trait_` is present', async () => {
|
|
30
|
+
const spy = jest.spyOn(analytics, 'identify')
|
|
31
|
+
await queryString(analytics, '?ajs_uid=1234&ajs_trait_address=123 St')
|
|
32
|
+
expect(spy).toHaveBeenCalledWith('1234', { address: '123 St' })
|
|
33
|
+
spy.mockRestore()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('applies multiple traits if `ajs_trait_` is declared more than once', async () => {
|
|
37
|
+
const spy = jest.spyOn(analytics, 'identify')
|
|
38
|
+
await queryString(
|
|
39
|
+
analytics,
|
|
40
|
+
'?ajs_uid=1234&ajs_trait_address=123 St&ajs_trait_city=Vancouver'
|
|
41
|
+
)
|
|
42
|
+
expect(spy).toHaveBeenCalledWith('1234', {
|
|
43
|
+
address: '123 St',
|
|
44
|
+
city: 'Vancouver',
|
|
45
|
+
})
|
|
46
|
+
spy.mockRestore()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('only considers one `ajs_uid` received as parameter', async () => {
|
|
50
|
+
const spy = jest.spyOn(analytics, 'identify')
|
|
51
|
+
await queryString(
|
|
52
|
+
analytics,
|
|
53
|
+
'?ajs_uid=1234&ajs_trait_address=123 St&ajs_trait_address=908 St'
|
|
54
|
+
)
|
|
55
|
+
expect(spy).toHaveBeenCalledWith('1234', { address: '908 St' })
|
|
56
|
+
spy.mockRestore()
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
describe('track', () => {
|
|
61
|
+
it('calls track if `ajs_event` is present', async () => {
|
|
62
|
+
const spy = jest.spyOn(analytics, 'track')
|
|
63
|
+
await queryString(analytics, '?ajs_event=Button Clicked')
|
|
64
|
+
expect(spy).toHaveBeenCalledWith('Button Clicked', {})
|
|
65
|
+
spy.mockRestore()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('applies props if `ajs_prop_` is present', async () => {
|
|
69
|
+
const spy = jest.spyOn(analytics, 'track')
|
|
70
|
+
await queryString(
|
|
71
|
+
analytics,
|
|
72
|
+
'?ajs_event=Button Clicked&ajs_prop_location=Home Page'
|
|
73
|
+
)
|
|
74
|
+
expect(spy).toHaveBeenCalledWith('Button Clicked', {
|
|
75
|
+
location: 'Home Page',
|
|
76
|
+
})
|
|
77
|
+
spy.mockRestore()
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('applies multiple props if `ajs_prop_` is declared more than once', async () => {
|
|
81
|
+
const spy = jest.spyOn(analytics, 'track')
|
|
82
|
+
await queryString(
|
|
83
|
+
analytics,
|
|
84
|
+
'?ajs_event=Button Clicked&ajs_prop_location=Home Page&ajs_prop_team=Instrumentation'
|
|
85
|
+
)
|
|
86
|
+
expect(spy).toHaveBeenCalledWith('Button Clicked', {
|
|
87
|
+
location: 'Home Page',
|
|
88
|
+
team: 'Instrumentation',
|
|
89
|
+
})
|
|
90
|
+
spy.mockRestore()
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
it('only considers the first `ajs_event` received as parameter', async () => {
|
|
94
|
+
const spy = jest.spyOn(analytics, 'track')
|
|
95
|
+
await queryString(
|
|
96
|
+
analytics,
|
|
97
|
+
'?ajs_event=Button Clicked&ajs_prop_location=Home Page&ajs_prop_location=Teams Page'
|
|
98
|
+
)
|
|
99
|
+
expect(spy).toHaveBeenCalledWith('Button Clicked', {
|
|
100
|
+
location: 'Teams Page',
|
|
101
|
+
})
|
|
102
|
+
spy.mockRestore()
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
describe('setAnonymousId', () => {
|
|
107
|
+
it('if `ajs_aid` is present', async () => {
|
|
108
|
+
const spy = jest.spyOn(analytics, 'setAnonymousId')
|
|
109
|
+
await queryString(analytics, '?ajs_aid=immaghost')
|
|
110
|
+
expect(spy).toHaveBeenCalledWith('immaghost')
|
|
111
|
+
spy.mockRestore()
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('only considers the first aid received as parameter', async () => {
|
|
115
|
+
const spy = jest.spyOn(analytics, 'setAnonymousId')
|
|
116
|
+
await queryString(analytics, '?ajs_aid=imbatman&ajs_aid=bruce')
|
|
117
|
+
expect(spy).toHaveBeenCalledWith('bruce')
|
|
118
|
+
spy.mockRestore()
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
describe('setting anonymous id when making track and identify calls', () => {
|
|
123
|
+
it('updates the anonymous ids before track calls are made', async () => {
|
|
124
|
+
const dispatchSpy = jest.spyOn(analytics as any, '_dispatch')
|
|
125
|
+
await queryString(analytics, '?ajs_event=event&ajs_aid=ariel')
|
|
126
|
+
expect(dispatchSpy).toHaveBeenCalledWith(
|
|
127
|
+
expect.objectContaining({
|
|
128
|
+
anonymousId: 'ariel',
|
|
129
|
+
event: 'event',
|
|
130
|
+
}),
|
|
131
|
+
undefined
|
|
132
|
+
)
|
|
133
|
+
dispatchSpy.mockRestore()
|
|
134
|
+
})
|
|
135
|
+
it('updates the anonymous ids before identify calls are made', async () => {
|
|
136
|
+
const dispatchSpy = jest.spyOn(analytics as any, '_dispatch')
|
|
137
|
+
await queryString(analytics, '?ajs_uid=1234&ajs_aid=ariel')
|
|
138
|
+
expect(dispatchSpy).toHaveBeenCalledWith(
|
|
139
|
+
expect.objectContaining({
|
|
140
|
+
anonymousId: 'ariel',
|
|
141
|
+
userId: '1234',
|
|
142
|
+
}),
|
|
143
|
+
undefined
|
|
144
|
+
)
|
|
145
|
+
dispatchSpy.mockRestore()
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
})
|
|
149
|
+
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { pickPrefix } from '../pickPrefix'
|
|
2
|
+
|
|
3
|
+
describe('pickPrefix', () => {
|
|
4
|
+
it('strips a single prefix to creates an object', () => {
|
|
5
|
+
const traits = pickPrefix('ajs_traits_', {
|
|
6
|
+
ajs_traits_address: '12-123 St.',
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
const output = {
|
|
10
|
+
address: '12-123 St.',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
expect(traits).toEqual(output)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('stripts multiple prefixes to create an object', () => {
|
|
17
|
+
const traits = pickPrefix('ajs_traits_', {
|
|
18
|
+
ajs_traits_address: '12-123 St.',
|
|
19
|
+
ajs_traits_city: 'Vancouver',
|
|
20
|
+
ajs_traits_province: 'BC',
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const output = {
|
|
24
|
+
address: '12-123 St.',
|
|
25
|
+
city: 'Vancouver',
|
|
26
|
+
province: 'BC',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
expect(traits).toEqual(output)
|
|
30
|
+
})
|
|
31
|
+
})
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import unfetch from 'unfetch'
|
|
2
|
+
import { HtEventsBrowser } from '../../..'
|
|
3
|
+
import { createSuccess } from '../../../test-helpers/factories'
|
|
4
|
+
|
|
5
|
+
jest.mock('unfetch')
|
|
6
|
+
jest
|
|
7
|
+
.mocked(unfetch)
|
|
8
|
+
.mockImplementation(() => createSuccess({ integrations: {} }))
|
|
9
|
+
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
delete window.location
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
window.location = new URL(
|
|
14
|
+
'https://www.example.com?ajs_aid=873832VB&ajs_uid=xcvn7568'
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
describe('useQueryString configuration option', () => {
|
|
18
|
+
it('ignores aid and uid from query string when disabled', async () => {
|
|
19
|
+
const [analyticsAlt] = await HtEventsBrowser.load(
|
|
20
|
+
{ writeKey: 'abc' },
|
|
21
|
+
{
|
|
22
|
+
useQueryString: false,
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
// not acknowledge the aid provided in the query params, let ajs generate one
|
|
27
|
+
expect(analyticsAlt.user().anonymousId()).not.toBe('873832VB')
|
|
28
|
+
expect(analyticsAlt.user().id()).toBe(null)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('ignores uid when it doesnt match the required pattern', async () => {
|
|
32
|
+
const [analyticsAlt] = await HtEventsBrowser.load(
|
|
33
|
+
{ writeKey: 'abc' },
|
|
34
|
+
{
|
|
35
|
+
useQueryString: {
|
|
36
|
+
uid: /[A-Z]{6}/,
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
// no constraint was set for aid therefore accepted
|
|
42
|
+
expect(analyticsAlt.user().anonymousId()).toBe('873832VB')
|
|
43
|
+
expect(analyticsAlt.user().id()).toBe(null)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('accepts both aid and uid from query string when they match the required pattern', async () => {
|
|
47
|
+
const [analyticsAlt] = await HtEventsBrowser.load(
|
|
48
|
+
{ writeKey: 'abc' },
|
|
49
|
+
{
|
|
50
|
+
useQueryString: {
|
|
51
|
+
aid: /\d{6}[A-Z]{2}/,
|
|
52
|
+
uid: /[a-z]{4}\d{4}/,
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
expect(analyticsAlt.user().anonymousId()).toBe('873832VB')
|
|
58
|
+
expect(analyticsAlt.user().id()).toBe('xcvn7568')
|
|
59
|
+
})
|
|
60
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tries to gets the unencoded version of an encoded component of a
|
|
3
|
+
* Uniform Resource Identifier (URI). If input string is malformed,
|
|
4
|
+
* returns it back as-is.
|
|
5
|
+
*
|
|
6
|
+
* Note: All occurences of the `+` character become ` ` (spaces).
|
|
7
|
+
**/
|
|
8
|
+
export function gracefulDecodeURIComponent(
|
|
9
|
+
encodedURIComponent: string
|
|
10
|
+
): string {
|
|
11
|
+
try {
|
|
12
|
+
return decodeURIComponent(encodedURIComponent.replace(/\+/g, ' '))
|
|
13
|
+
} catch {
|
|
14
|
+
return encodedURIComponent
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { pickPrefix } from './pickPrefix'
|
|
2
|
+
import { gracefulDecodeURIComponent } from './gracefulDecodeURIComponent'
|
|
3
|
+
import { Analytics } from '../analytics'
|
|
4
|
+
import { Context } from '../context'
|
|
5
|
+
import { isPlainObject } from '@ht-sdks/events-sdk-js-core'
|
|
6
|
+
|
|
7
|
+
export interface QueryStringParams {
|
|
8
|
+
[key: string]: string | null
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function queryString(
|
|
12
|
+
analytics: Analytics,
|
|
13
|
+
query: string
|
|
14
|
+
): Promise<Context[]> {
|
|
15
|
+
const a = document.createElement('a')
|
|
16
|
+
a.href = query
|
|
17
|
+
const parsed = a.search.slice(1)
|
|
18
|
+
const params = parsed.split('&').reduce((acc: QueryStringParams, str) => {
|
|
19
|
+
const [k, v] = str.split('=')
|
|
20
|
+
acc[k] = gracefulDecodeURIComponent(v)
|
|
21
|
+
return acc
|
|
22
|
+
}, {})
|
|
23
|
+
|
|
24
|
+
const calls = []
|
|
25
|
+
|
|
26
|
+
const { ajs_uid, ajs_event, ajs_aid } = params
|
|
27
|
+
const { aid: aidPattern = /.+/, uid: uidPattern = /.+/ } = isPlainObject(
|
|
28
|
+
analytics.options.useQueryString
|
|
29
|
+
)
|
|
30
|
+
? analytics.options.useQueryString
|
|
31
|
+
: {}
|
|
32
|
+
|
|
33
|
+
if (ajs_aid) {
|
|
34
|
+
const anonId = Array.isArray(params.ajs_aid)
|
|
35
|
+
? params.ajs_aid[0]
|
|
36
|
+
: params.ajs_aid
|
|
37
|
+
|
|
38
|
+
if (aidPattern.test(anonId)) {
|
|
39
|
+
analytics.setAnonymousId(anonId)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (ajs_uid) {
|
|
44
|
+
const uid = Array.isArray(params.ajs_uid)
|
|
45
|
+
? params.ajs_uid[0]
|
|
46
|
+
: params.ajs_uid
|
|
47
|
+
|
|
48
|
+
if (uidPattern.test(uid)) {
|
|
49
|
+
const traits = pickPrefix('ajs_trait_', params)
|
|
50
|
+
|
|
51
|
+
calls.push(analytics.identify(uid, traits))
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (ajs_event) {
|
|
56
|
+
const event = Array.isArray(params.ajs_event)
|
|
57
|
+
? params.ajs_event[0]
|
|
58
|
+
: params.ajs_event
|
|
59
|
+
const props = pickPrefix('ajs_prop_', params)
|
|
60
|
+
calls.push(analytics.track(event, props))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return Promise.all(calls)
|
|
64
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { QueryStringParams } from '.'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns an object containing only the properties prefixed by the input
|
|
5
|
+
* string.
|
|
6
|
+
* Ex: prefix('ajs_traits_', { ajs_traits_address: '123 St' })
|
|
7
|
+
* will return { address: '123 St' }
|
|
8
|
+
**/
|
|
9
|
+
export function pickPrefix(
|
|
10
|
+
prefix: string,
|
|
11
|
+
object: QueryStringParams
|
|
12
|
+
): QueryStringParams {
|
|
13
|
+
return Object.keys(object).reduce((acc: QueryStringParams, key: string) => {
|
|
14
|
+
if (key.startsWith(prefix)) {
|
|
15
|
+
const field = key.substr(prefix.length)
|
|
16
|
+
acc[field] = object[key]!
|
|
17
|
+
}
|
|
18
|
+
return acc
|
|
19
|
+
}, {})
|
|
20
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Analytics } from '../../analytics'
|
|
2
|
+
import { pWhile } from '../../../lib/p-while'
|
|
3
|
+
import { Context } from '../../context'
|
|
4
|
+
import { Plugin } from '../../plugin'
|
|
5
|
+
import { EventQueue } from '../event-queue'
|
|
6
|
+
import { ActionDestination } from '../../../plugins/remote-loader'
|
|
7
|
+
|
|
8
|
+
async function flushAll(eq: EventQueue): Promise<Context[]> {
|
|
9
|
+
const flushSpy = jest.spyOn(eq, 'flush')
|
|
10
|
+
await pWhile(
|
|
11
|
+
() => eq.queue.length > 0,
|
|
12
|
+
async () => {
|
|
13
|
+
return new Promise((r) => setTimeout(r, 0))
|
|
14
|
+
}
|
|
15
|
+
)
|
|
16
|
+
const results = flushSpy.mock.results.map((r) => r.value)
|
|
17
|
+
flushSpy.mockClear()
|
|
18
|
+
|
|
19
|
+
const flushed = await Promise.all(results)
|
|
20
|
+
return flushed.reduce((prev, cur) => {
|
|
21
|
+
return prev.concat(cur)
|
|
22
|
+
}, [])
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const testPlugin: Plugin = {
|
|
26
|
+
name: 'test',
|
|
27
|
+
type: 'before',
|
|
28
|
+
version: '0.1.0',
|
|
29
|
+
load: () => Promise.resolve(),
|
|
30
|
+
isLoaded: () => true,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const ajs = {} as Analytics
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* This test file only contains event-queue tests that _are_ specific to this package.
|
|
37
|
+
* You should prefer to write tests in packages/core
|
|
38
|
+
*/
|
|
39
|
+
const hightouchio = {
|
|
40
|
+
...testPlugin,
|
|
41
|
+
name: 'Hightouch.io',
|
|
42
|
+
type: 'after' as const,
|
|
43
|
+
track: (ctx: Context): Promise<Context> | Context => {
|
|
44
|
+
return Promise.resolve(ctx)
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
describe('alternative names', () => {
|
|
49
|
+
test('delivers to action destinations using alternative names', async () => {
|
|
50
|
+
const eq = new EventQueue(`writeKey:event-queue`)
|
|
51
|
+
const fullstory = new ActionDestination('fullstory', testPlugin) // TODO: This should be re-written as higher level integration test.
|
|
52
|
+
fullstory.alternativeNames.push('fullstory trackEvent')
|
|
53
|
+
fullstory.type = 'destination'
|
|
54
|
+
|
|
55
|
+
jest.spyOn(fullstory, 'track')
|
|
56
|
+
jest.spyOn(hightouchio, 'track')
|
|
57
|
+
|
|
58
|
+
const evt = {
|
|
59
|
+
type: 'track' as const,
|
|
60
|
+
integrations: {
|
|
61
|
+
All: false,
|
|
62
|
+
'fullstory trackEvent': true,
|
|
63
|
+
'Hightouch.io': {},
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const ctx = new Context(evt)
|
|
68
|
+
|
|
69
|
+
await eq.register(Context.system(), fullstory, ajs)
|
|
70
|
+
await eq.register(Context.system(), hightouchio, ajs)
|
|
71
|
+
|
|
72
|
+
void eq.dispatch(ctx)
|
|
73
|
+
|
|
74
|
+
expect(eq.queue.length).toBe(1)
|
|
75
|
+
const flushed = await flushAll(eq)
|
|
76
|
+
|
|
77
|
+
expect(flushed).toEqual([ctx])
|
|
78
|
+
|
|
79
|
+
expect(fullstory.track).toHaveBeenCalled()
|
|
80
|
+
expect(hightouchio.track).toHaveBeenCalled()
|
|
81
|
+
})
|
|
82
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PriorityQueue } from '../../lib/priority-queue'
|
|
2
|
+
import { PersistedPriorityQueue } from '../../lib/priority-queue/persisted'
|
|
3
|
+
import { Context } from '../context'
|
|
4
|
+
import { AnyBrowserPlugin } from '../plugin'
|
|
5
|
+
import { CoreEventQueue } from '@ht-sdks/events-sdk-js-core'
|
|
6
|
+
import { isOffline } from '../connection'
|
|
7
|
+
|
|
8
|
+
export class EventQueue extends CoreEventQueue<Context, AnyBrowserPlugin> {
|
|
9
|
+
constructor(name: string)
|
|
10
|
+
constructor(priorityQueue: PriorityQueue<Context>)
|
|
11
|
+
constructor(nameOrQueue: string | PriorityQueue<Context>) {
|
|
12
|
+
super(
|
|
13
|
+
typeof nameOrQueue === 'string'
|
|
14
|
+
? new PersistedPriorityQueue(4, nameOrQueue)
|
|
15
|
+
: nameOrQueue
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
async flush(): Promise<Context[]> {
|
|
19
|
+
if (isOffline()) return []
|
|
20
|
+
return super.flush()
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hasSessionExpired,
|
|
3
|
+
isManualSessionIdValid,
|
|
4
|
+
updateSessionExpiration,
|
|
5
|
+
} from '..'
|
|
6
|
+
|
|
7
|
+
describe('()', () => {
|
|
8
|
+
it('hasSessionExpired', () => {
|
|
9
|
+
const past = Date.now() - 10000
|
|
10
|
+
expect(hasSessionExpired(past)).toEqual(true)
|
|
11
|
+
const future = Date.now() + 10000
|
|
12
|
+
expect(hasSessionExpired(future)).toEqual(false)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('isManualSessionIdValid', () => {
|
|
16
|
+
expect(isManualSessionIdValid(-100)).toBe(false)
|
|
17
|
+
expect(isManualSessionIdValid(100)).toBe(false)
|
|
18
|
+
expect(isManualSessionIdValid()).toBe(false)
|
|
19
|
+
expect(isManualSessionIdValid(Date.now())).toBe(true)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('updateSessionExpiration', () => {
|
|
23
|
+
expect(updateSessionExpiration({})).toEqual({ sessionStart: false })
|
|
24
|
+
expect(updateSessionExpiration({ sessionStart: true })).toEqual({
|
|
25
|
+
sessionStart: false,
|
|
26
|
+
})
|
|
27
|
+
expect(
|
|
28
|
+
updateSessionExpiration({
|
|
29
|
+
autoTrack: true,
|
|
30
|
+
expiresAt: 10,
|
|
31
|
+
timeout: 15,
|
|
32
|
+
sessionStart: false,
|
|
33
|
+
})
|
|
34
|
+
).toEqual({
|
|
35
|
+
autoTrack: true,
|
|
36
|
+
expiresAt: 25,
|
|
37
|
+
timeout: 15,
|
|
38
|
+
sessionStart: false,
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
})
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// https://github.com/rudderlabs/rudder-sdk-js/blob/3a818accd24e6b3667c75a6b60fb12aba36bdf7e/packages/analytics-js/LICENSE
|
|
2
|
+
// MIT License
|
|
3
|
+
|
|
4
|
+
// Copyright (c) 2021 RudderStack
|
|
5
|
+
|
|
6
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
// in the Software without restriction, including without limitation the rights
|
|
9
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
// furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
// copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
// SOFTWARE.
|
|
23
|
+
|
|
24
|
+
export type SessionInfo = {
|
|
25
|
+
autoTrack?: boolean
|
|
26
|
+
manualTrack?: boolean
|
|
27
|
+
timeout?: number
|
|
28
|
+
expiresAt?: number
|
|
29
|
+
id?: number
|
|
30
|
+
sessionStart?: boolean
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type SessionContext = {
|
|
34
|
+
sessionId?: number
|
|
35
|
+
sessionStart?: boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A function to validate current session and return true/false depending on that
|
|
40
|
+
* @returns boolean
|
|
41
|
+
*/
|
|
42
|
+
export const hasSessionExpired = (expiresAt: number): boolean => {
|
|
43
|
+
const timestamp = Date.now()
|
|
44
|
+
return Boolean(timestamp > expiresAt)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const generateSessionId = (): number => Date.now()
|
|
48
|
+
|
|
49
|
+
export const isManualSessionIdValid = (sessionId?: number): boolean => {
|
|
50
|
+
if (
|
|
51
|
+
!sessionId ||
|
|
52
|
+
sessionId.toString().startsWith('-') ||
|
|
53
|
+
sessionId.toString().length < 10
|
|
54
|
+
) {
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
57
|
+
return true
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const MIN_SESSION_TIMEOUT_MS = 10 * 1000 // 10 seconds
|
|
61
|
+
const DEFAULT_SESSION_TIMEOUT_MS = 30 * 60 * 1000 // 30 minutes
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A function to generate new auto tracking session
|
|
65
|
+
* @param sessionTimeout current timestamp
|
|
66
|
+
* @returns SessionInfo
|
|
67
|
+
*/
|
|
68
|
+
export const generateAutoTrackingSession = (
|
|
69
|
+
sessionTimeout?: number
|
|
70
|
+
): SessionInfo => {
|
|
71
|
+
const timestamp = Date.now()
|
|
72
|
+
const timeout: number = sessionTimeout || DEFAULT_SESSION_TIMEOUT_MS
|
|
73
|
+
if (timeout < MIN_SESSION_TIMEOUT_MS) {
|
|
74
|
+
console.warn('Session timeouts of less than 10 seconds are not recommended')
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
id: timestamp, // set the current timestamp
|
|
78
|
+
expiresAt: timestamp + timeout, // set the expiry time of the session
|
|
79
|
+
timeout,
|
|
80
|
+
sessionStart: true,
|
|
81
|
+
autoTrack: true,
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A function to generate new manual tracking session
|
|
87
|
+
* @param id Provided sessionId
|
|
88
|
+
* @returns SessionInfo
|
|
89
|
+
*/
|
|
90
|
+
export const generateManualTrackingSession = (id?: number): SessionInfo => {
|
|
91
|
+
const sessionId: number = isManualSessionIdValid(id)
|
|
92
|
+
? (id as number)
|
|
93
|
+
: generateSessionId()
|
|
94
|
+
return {
|
|
95
|
+
id: sessionId,
|
|
96
|
+
sessionStart: true,
|
|
97
|
+
manualTrack: true,
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const updateSessionExpiration = (session: SessionInfo): SessionInfo => {
|
|
102
|
+
session.sessionStart = false
|
|
103
|
+
if (session.autoTrack) {
|
|
104
|
+
session.expiresAt = session.expiresAt! + session.timeout!
|
|
105
|
+
}
|
|
106
|
+
return session
|
|
107
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RemoteMetrics } from '../remote-metrics'
|
|
2
|
+
import { Stats } from '..'
|
|
3
|
+
|
|
4
|
+
const spy = jest.spyOn(RemoteMetrics.prototype, 'increment')
|
|
5
|
+
|
|
6
|
+
describe(Stats, () => {
|
|
7
|
+
test('forwards increments to remote metrics endpoint', () => {
|
|
8
|
+
Stats.initRemoteMetrics()
|
|
9
|
+
|
|
10
|
+
const stats = new Stats()
|
|
11
|
+
stats.increment('banana', 1, ['phone:1'])
|
|
12
|
+
|
|
13
|
+
expect(spy).toHaveBeenCalledWith('banana', ['phone:1'])
|
|
14
|
+
})
|
|
15
|
+
})
|