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,121 @@
|
|
1
|
+
#!/usr/bin/env ./node_modules/.bin/ts-node --script-mode --transpile-only --files
|
2
|
+
/* eslint-disable no-undef */
|
3
|
+
|
4
|
+
const ex = require('execa')
|
5
|
+
const S3 = require('aws-sdk/clients/s3')
|
6
|
+
const fs = require('fs-extra')
|
7
|
+
const path = require('path')
|
8
|
+
const mime = require('mime')
|
9
|
+
const logUpdate = require('log-update')
|
10
|
+
|
11
|
+
const bucket =
|
12
|
+
process.env.NODE_ENV == 'production'
|
13
|
+
? process.env.PROD_BUCKET
|
14
|
+
: process.env.STAGE_BUCKET
|
15
|
+
if (!bucket) throw new Error('Missing one of PROD_BUCKET or STAGE_BUCKET')
|
16
|
+
|
17
|
+
const accessKeyId = process.env.AWS_ACCESS_KEY_ID
|
18
|
+
if (!accessKeyId) throw new Error('Missing AWS_ACCESS_KEY_ID')
|
19
|
+
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY
|
20
|
+
if (!secretAccessKey) throw new Error('Missing AWS_SECRET_ACCESS_KEY')
|
21
|
+
const sessionToken = process.env.AWS_SESSION_TOKEN
|
22
|
+
if (!sessionToken) throw new Error('Missing AWS_SESSION_TOKEN')
|
23
|
+
|
24
|
+
const pathPrefix = process.env.PATH_PREFIX ?? 'browser/candidate'
|
25
|
+
const pathVersion = process.env.PATH_VERSION
|
26
|
+
if (!pathVersion) throw new Error('Missing PATH_VERSION')
|
27
|
+
|
28
|
+
const getBranch = async () =>
|
29
|
+
(await ex('git', ['branch', '--show-current'])).stdout
|
30
|
+
|
31
|
+
const getSha = async () =>
|
32
|
+
(await ex('git', ['rev-parse', '--short', 'HEAD'])).stdout
|
33
|
+
|
34
|
+
async function getFiles(dir) {
|
35
|
+
const subdirs = await fs.readdir(dir)
|
36
|
+
const files = await Promise.all(
|
37
|
+
subdirs.map(async (subdir) => {
|
38
|
+
const res = path.resolve(dir, subdir)
|
39
|
+
return (await fs.stat(res)).isDirectory() ? getFiles(res) : [res]
|
40
|
+
})
|
41
|
+
)
|
42
|
+
return files.reduce((a, f) => a.concat(f, [])).map((f) => f.split(dir)[1])
|
43
|
+
}
|
44
|
+
|
45
|
+
async function upload() {
|
46
|
+
const s3 = new S3({
|
47
|
+
accessKeyId,
|
48
|
+
secretAccessKey,
|
49
|
+
sessionToken,
|
50
|
+
region: 'us-east-1',
|
51
|
+
})
|
52
|
+
|
53
|
+
const files = await getFiles(path.join(process.cwd(), './dist/umd'))
|
54
|
+
const total = files.length
|
55
|
+
let progress = 0
|
56
|
+
|
57
|
+
const uploads = files.map(async (f) => {
|
58
|
+
const filePath = path.join(process.cwd(), './dist/umd', f)
|
59
|
+
|
60
|
+
const options = {
|
61
|
+
Bucket: bucket,
|
62
|
+
Key: path.join(pathPrefix, pathVersion, f),
|
63
|
+
Body: await fs.readFile(filePath),
|
64
|
+
ContentType:
|
65
|
+
mime.getType(filePath.replace('.gz', '')) || 'application/javascript',
|
66
|
+
CacheControl: 'public,max-age=31536000,immutable',
|
67
|
+
}
|
68
|
+
|
69
|
+
if (filePath.includes('.gz')) {
|
70
|
+
options.ContentEncoding = 'gzip'
|
71
|
+
}
|
72
|
+
|
73
|
+
const output = await s3.putObject(options).promise()
|
74
|
+
|
75
|
+
if (pathPrefix === 'browser/release') {
|
76
|
+
// only build "v1-latest" when it's a "release" build
|
77
|
+
// put latest version with only 5 minutes caching
|
78
|
+
const majorVersion = pathVersion.split('.').reverse().pop()
|
79
|
+
await s3
|
80
|
+
.putObject({
|
81
|
+
...options,
|
82
|
+
CacheControl: 'public,max-age=300,immutable',
|
83
|
+
Key: path.join(pathPrefix, `v${majorVersion}-latest`, f),
|
84
|
+
})
|
85
|
+
.promise()
|
86
|
+
}
|
87
|
+
|
88
|
+
progress++
|
89
|
+
logUpdate(`Progress: ${progress}/${total}`)
|
90
|
+
|
91
|
+
return output
|
92
|
+
})
|
93
|
+
|
94
|
+
await Promise.all(uploads)
|
95
|
+
}
|
96
|
+
|
97
|
+
async function release() {
|
98
|
+
console.log('Compiling Bundles')
|
99
|
+
|
100
|
+
const sha = await getSha()
|
101
|
+
let branch = process.env.GITHUB_REF_NAME ?? (await getBranch())
|
102
|
+
|
103
|
+
const meta = {
|
104
|
+
sha,
|
105
|
+
branch: `${branch}`,
|
106
|
+
}
|
107
|
+
|
108
|
+
console.table(meta)
|
109
|
+
const envVars = {
|
110
|
+
PATH_VERSION: pathVersion,
|
111
|
+
PATH_PREFIX: pathPrefix,
|
112
|
+
}
|
113
|
+
console.table(envVars)
|
114
|
+
console.log('Uploading Assets')
|
115
|
+
await upload(meta)
|
116
|
+
}
|
117
|
+
|
118
|
+
release().catch((err) => {
|
119
|
+
console.error(err)
|
120
|
+
process.exit(1)
|
121
|
+
})
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import { sleep } from '@ht-sdks/events-sdk-js-core'
|
2
|
+
import { getBufferedPageCtxFixture } from '../../test-helpers/fixtures'
|
3
|
+
import unfetch from 'unfetch'
|
4
|
+
import { HtEventsBrowser } from '..'
|
5
|
+
import { Analytics } from '../../core/analytics'
|
6
|
+
import { createSuccess } from '../../test-helpers/factories'
|
7
|
+
|
8
|
+
jest.mock('unfetch')
|
9
|
+
|
10
|
+
const mockFetchSettingsSuccessResponse = () => {
|
11
|
+
return jest
|
12
|
+
.mocked(unfetch)
|
13
|
+
.mockImplementation(() => createSuccess({ integrations: {} }))
|
14
|
+
}
|
15
|
+
|
16
|
+
describe('Lazy initialization', () => {
|
17
|
+
let trackSpy: jest.SpiedFunction<Analytics['track']>
|
18
|
+
let fetched: jest.MockedFn<typeof unfetch>
|
19
|
+
beforeEach(() => {
|
20
|
+
fetched = mockFetchSettingsSuccessResponse()
|
21
|
+
trackSpy = jest.spyOn(Analytics.prototype, 'track')
|
22
|
+
})
|
23
|
+
|
24
|
+
it('Should be able to delay initialization ', async () => {
|
25
|
+
const analytics = new HtEventsBrowser()
|
26
|
+
const track = analytics.track('foo')
|
27
|
+
await sleep(100)
|
28
|
+
expect(trackSpy).not.toBeCalled()
|
29
|
+
analytics.load({ writeKey: 'abc' })
|
30
|
+
await track
|
31
|
+
expect(trackSpy).toBeCalledWith('foo', getBufferedPageCtxFixture())
|
32
|
+
})
|
33
|
+
|
34
|
+
it('.load method return an analytics instance', async () => {
|
35
|
+
const analytics = new HtEventsBrowser().load({ writeKey: 'foo' })
|
36
|
+
expect(analytics instanceof HtEventsBrowser).toBeTruthy()
|
37
|
+
})
|
38
|
+
|
39
|
+
// Load already defaults to NOT fetching external settings from CDN
|
40
|
+
it.skip('should ignore subsequent .load calls', async () => {
|
41
|
+
const analytics = new HtEventsBrowser()
|
42
|
+
await analytics.load({ writeKey: 'my-write-key' })
|
43
|
+
await analytics.load({ writeKey: 'def' })
|
44
|
+
expect(fetched).toBeCalledTimes(1)
|
45
|
+
expect(fetched).toBeCalledWith(
|
46
|
+
expect.stringContaining(
|
47
|
+
'https://cdn.hightouch-events.com/v1/projects/my-write-key/settings'
|
48
|
+
)
|
49
|
+
)
|
50
|
+
})
|
51
|
+
})
|
@@ -0,0 +1,440 @@
|
|
1
|
+
import { HtEventsBrowser } from '../..'
|
2
|
+
import unfetch from 'unfetch'
|
3
|
+
import { Analytics } from '../../core/analytics'
|
4
|
+
import { Context } from '../../core/context'
|
5
|
+
import * as Factory from '../../test-helpers/factories'
|
6
|
+
import { sleep } from '../../lib/sleep'
|
7
|
+
import { setGlobalCDNUrl } from '../../lib/parse-cdn'
|
8
|
+
import { User } from '../../core/user'
|
9
|
+
import { getBufferedPageCtxFixture } from '../../test-helpers/fixtures'
|
10
|
+
|
11
|
+
jest.mock('unfetch')
|
12
|
+
|
13
|
+
const mockFetchSettingsSuccessResponse = () => {
|
14
|
+
jest
|
15
|
+
.mocked(unfetch)
|
16
|
+
.mockImplementation(() => Factory.createSuccess({ integrations: {} }))
|
17
|
+
}
|
18
|
+
|
19
|
+
const mockFetchSettingsErrorResponse = (response?: Partial<Response>) => {
|
20
|
+
jest.mocked(unfetch).mockImplementation(() => Factory.createError(response))
|
21
|
+
}
|
22
|
+
|
23
|
+
const writeKey = 'foo'
|
24
|
+
|
25
|
+
const errMsg = 'errMsg'
|
26
|
+
|
27
|
+
jest.spyOn(console, 'error').mockImplementation(() => {}) // silence console spam
|
28
|
+
|
29
|
+
describe('Pre-initialization', () => {
|
30
|
+
const trackSpy = jest.spyOn(Analytics.prototype, 'track')
|
31
|
+
const identifySpy = jest.spyOn(Analytics.prototype, 'identify')
|
32
|
+
const onSpy = jest.spyOn(Analytics.prototype, 'on')
|
33
|
+
const getOnSpyCalls = (event: string) =>
|
34
|
+
onSpy.mock.calls.filter(([arg1]) => arg1 === event)
|
35
|
+
|
36
|
+
const readySpy = jest.spyOn(Analytics.prototype, 'ready')
|
37
|
+
const browserLoadSpy = jest.spyOn(HtEventsBrowser, 'load')
|
38
|
+
const consoleErrorSpy = jest.spyOn(console, 'error')
|
39
|
+
|
40
|
+
beforeEach(() => {
|
41
|
+
setGlobalCDNUrl(undefined as any)
|
42
|
+
mockFetchSettingsSuccessResponse()
|
43
|
+
;(window as any).htevents = undefined
|
44
|
+
})
|
45
|
+
|
46
|
+
describe('Smoke', () => {
|
47
|
+
test('load should instantiate an object that resolves into an Analytics object', async () => {
|
48
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
49
|
+
expect(ajsBrowser).toBeInstanceOf<typeof HtEventsBrowser>(HtEventsBrowser)
|
50
|
+
expect(ajsBrowser.instance).toBeUndefined()
|
51
|
+
const [ajs, ctx] = await ajsBrowser
|
52
|
+
expect(ajsBrowser.instance).toBeInstanceOf<typeof Analytics>(Analytics)
|
53
|
+
expect(ajsBrowser.ctx).toBeInstanceOf<typeof Context>(Context)
|
54
|
+
expect(ajs).toBeInstanceOf<typeof Analytics>(Analytics)
|
55
|
+
expect(ctx).toBeInstanceOf<typeof Context>(Context)
|
56
|
+
})
|
57
|
+
|
58
|
+
test('If a user sends a single pre-initialized track event, that event gets flushed', async () => {
|
59
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
60
|
+
const trackCtxPromise = ajsBrowser.track('foo', { name: 'john' })
|
61
|
+
const result = await trackCtxPromise
|
62
|
+
expect(result).toBeInstanceOf(Context)
|
63
|
+
expect(trackSpy).toBeCalledWith(
|
64
|
+
'foo',
|
65
|
+
{ name: 'john' },
|
66
|
+
getBufferedPageCtxFixture()
|
67
|
+
)
|
68
|
+
expect(trackSpy).toBeCalledTimes(1)
|
69
|
+
})
|
70
|
+
|
71
|
+
test('"return types should not change over the lifecycle for async methods', async () => {
|
72
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
73
|
+
|
74
|
+
const trackCtxPromise1 = ajsBrowser.track('foo', { name: 'john' })
|
75
|
+
expect(trackCtxPromise1).toBeInstanceOf(Promise)
|
76
|
+
await ajsBrowser
|
77
|
+
|
78
|
+
// loaded
|
79
|
+
const trackCtxPromise2 = ajsBrowser.track('foo', { name: 'john' })
|
80
|
+
expect(trackCtxPromise2).toBeInstanceOf(Promise)
|
81
|
+
|
82
|
+
expect(await trackCtxPromise1).toBeInstanceOf(Context)
|
83
|
+
expect(await trackCtxPromise2).toBeInstanceOf(Context)
|
84
|
+
})
|
85
|
+
|
86
|
+
test('return types should not change over lifecycle for sync methods', async () => {
|
87
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
88
|
+
const user = ajsBrowser.user()
|
89
|
+
expect(user).toBeInstanceOf(Promise)
|
90
|
+
await ajsBrowser
|
91
|
+
|
92
|
+
// loaded
|
93
|
+
const user2 = ajsBrowser.user()
|
94
|
+
expect(user2).toBeInstanceOf(Promise)
|
95
|
+
|
96
|
+
expect(await user).toBeInstanceOf(User)
|
97
|
+
expect(await user2).toBeInstanceOf(User)
|
98
|
+
})
|
99
|
+
|
100
|
+
test('version should return version', async () => {
|
101
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
102
|
+
expect(typeof ajsBrowser.VERSION).toBe('string')
|
103
|
+
})
|
104
|
+
|
105
|
+
test('If a user sends multiple events, all of those event gets flushed', async () => {
|
106
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
107
|
+
const trackCtxPromise = ajsBrowser.track('foo', { name: 'john' })
|
108
|
+
const trackCtxPromise2 = ajsBrowser.track('bar', { age: 123 })
|
109
|
+
const identifyCtxPromise = ajsBrowser.identify('hello')
|
110
|
+
|
111
|
+
await Promise.all([trackCtxPromise, trackCtxPromise2, identifyCtxPromise])
|
112
|
+
|
113
|
+
expect(trackSpy).toBeCalledWith(
|
114
|
+
'foo',
|
115
|
+
{ name: 'john' },
|
116
|
+
getBufferedPageCtxFixture()
|
117
|
+
)
|
118
|
+
expect(trackSpy).toBeCalledWith(
|
119
|
+
'bar',
|
120
|
+
{ age: 123 },
|
121
|
+
getBufferedPageCtxFixture()
|
122
|
+
)
|
123
|
+
expect(trackSpy).toBeCalledTimes(2)
|
124
|
+
|
125
|
+
expect(identifySpy).toBeCalledWith('hello', getBufferedPageCtxFixture())
|
126
|
+
expect(identifySpy).toBeCalledTimes(1)
|
127
|
+
})
|
128
|
+
|
129
|
+
// by default, we do not fetch settings from cdn
|
130
|
+
test.skip('should not throw on initialization failures', async () => {
|
131
|
+
mockFetchSettingsErrorResponse()
|
132
|
+
const ajs = HtEventsBrowser.load({ writeKey })
|
133
|
+
await sleep(100)
|
134
|
+
expect(ajs.instance).toBeUndefined()
|
135
|
+
void ajs.track('foo')
|
136
|
+
})
|
137
|
+
|
138
|
+
// by default, we do not fetch settings from cdn
|
139
|
+
test.skip('should log errors if network error', async () => {
|
140
|
+
const err = {
|
141
|
+
status: 403,
|
142
|
+
statusText: 'Forbidden',
|
143
|
+
json: undefined,
|
144
|
+
}
|
145
|
+
mockFetchSettingsErrorResponse(err)
|
146
|
+
const consoleSpy = jest
|
147
|
+
.spyOn(console, 'error')
|
148
|
+
.mockImplementationOnce(() => {})
|
149
|
+
HtEventsBrowser.load({ writeKey: 'abc' })
|
150
|
+
await sleep(500)
|
151
|
+
expect(consoleSpy).toBeCalled()
|
152
|
+
})
|
153
|
+
})
|
154
|
+
|
155
|
+
describe('Promise API', () => {
|
156
|
+
describe('.then', () => {
|
157
|
+
test('.then should be called on success', () => {
|
158
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey: 'abc' })
|
159
|
+
const newPromise = ajsBrowser.then(([analytics, context]) => {
|
160
|
+
expect(analytics).toBeInstanceOf<typeof Analytics>(Analytics)
|
161
|
+
expect(context).toBeInstanceOf<typeof Context>(Context)
|
162
|
+
})
|
163
|
+
expect(newPromise).toBeInstanceOf<typeof Promise>(Promise)
|
164
|
+
return newPromise
|
165
|
+
})
|
166
|
+
|
167
|
+
it('.then should pass to the next .then', async () => {
|
168
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey: 'abc' })
|
169
|
+
const obj = ajsBrowser.then(() => ({ foo: 123 } as const))
|
170
|
+
expect(obj).toBeInstanceOf(Promise)
|
171
|
+
await obj.then((el) => expect(el.foo).toBe(123))
|
172
|
+
})
|
173
|
+
})
|
174
|
+
|
175
|
+
describe('.catch', () => {
|
176
|
+
it('should be capable of handling errors if using promise syntax', async () => {
|
177
|
+
browserLoadSpy.mockImplementationOnce((): any => Promise.reject(errMsg))
|
178
|
+
|
179
|
+
await expect(() =>
|
180
|
+
HtEventsBrowser.load({ writeKey: 'abc' })
|
181
|
+
).rejects.toEqual(errMsg)
|
182
|
+
})
|
183
|
+
})
|
184
|
+
|
185
|
+
describe('.finally', () => {
|
186
|
+
test('success', async () => {
|
187
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey: 'abc' })
|
188
|
+
const thenCb = jest.fn()
|
189
|
+
const finallyCb = jest.fn()
|
190
|
+
const catchCb = jest.fn()
|
191
|
+
await ajsBrowser.then(thenCb).catch(catchCb).finally(finallyCb)
|
192
|
+
expect(catchCb).not.toBeCalled()
|
193
|
+
expect(finallyCb).toBeCalledTimes(1)
|
194
|
+
expect(thenCb).toBeCalledTimes(1)
|
195
|
+
})
|
196
|
+
test('rejection', async () => {
|
197
|
+
browserLoadSpy.mockImplementationOnce((): any => Promise.reject(errMsg))
|
198
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey: 'abc' })
|
199
|
+
const onFinallyCb = jest.fn()
|
200
|
+
await ajsBrowser
|
201
|
+
.catch((reason) => {
|
202
|
+
expect(reason).toBe(errMsg)
|
203
|
+
})
|
204
|
+
.finally(() => {
|
205
|
+
onFinallyCb()
|
206
|
+
})
|
207
|
+
expect(onFinallyCb).toBeCalledTimes(1)
|
208
|
+
expect.assertions(2)
|
209
|
+
})
|
210
|
+
})
|
211
|
+
})
|
212
|
+
|
213
|
+
describe('Load failures', () => {
|
214
|
+
test('rejected promise should work as expected for buffered analytics instances', async () => {
|
215
|
+
trackSpy.mockImplementationOnce(() => Promise.reject(errMsg))
|
216
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
217
|
+
try {
|
218
|
+
await ajsBrowser.track('foo', { name: 'john' })
|
219
|
+
} catch (err) {
|
220
|
+
expect(err).toBe(errMsg)
|
221
|
+
}
|
222
|
+
expect.assertions(1)
|
223
|
+
})
|
224
|
+
|
225
|
+
test('rejected promise should work as expected for initialized analytics instances', async () => {
|
226
|
+
trackSpy.mockImplementationOnce(() => Promise.reject(errMsg))
|
227
|
+
const [analytics] = await HtEventsBrowser.load({ writeKey })
|
228
|
+
try {
|
229
|
+
await analytics.track('foo', { name: 'john' })
|
230
|
+
} catch (err) {
|
231
|
+
expect(err).toBe(errMsg)
|
232
|
+
}
|
233
|
+
expect.assertions(1)
|
234
|
+
})
|
235
|
+
})
|
236
|
+
|
237
|
+
describe('Snippet / standalone', () => {
|
238
|
+
test('If a snippet user sends multiple events, all of those event gets flushed', async () => {
|
239
|
+
const onTrackCb = jest.fn()
|
240
|
+
const onTrack = ['on', 'track', onTrackCb]
|
241
|
+
const track = ['track', 'foo']
|
242
|
+
const track2 = ['track', 'bar']
|
243
|
+
const identify = ['identify']
|
244
|
+
|
245
|
+
;(window as any).htevents = [onTrack, track, track2, identify]
|
246
|
+
|
247
|
+
await HtEventsBrowser.standalone(writeKey)
|
248
|
+
|
249
|
+
await sleep(100) // the snippet does not return a promise (pre-initialization) ... it sometimes has a callback as the third argument.
|
250
|
+
expect(trackSpy).toBeCalledWith('foo', getBufferedPageCtxFixture())
|
251
|
+
expect(trackSpy).toBeCalledWith('bar', getBufferedPageCtxFixture())
|
252
|
+
expect(trackSpy).toBeCalledTimes(2)
|
253
|
+
|
254
|
+
expect(identifySpy).toBeCalledTimes(1)
|
255
|
+
|
256
|
+
expect(getOnSpyCalls('track').length).toBe(1)
|
257
|
+
expect(onTrackCb).toBeCalledTimes(2) // gets called once for each track event
|
258
|
+
expect(onTrackCb).toBeCalledWith('foo', {}, undefined)
|
259
|
+
expect(onTrackCb).toBeCalledWith('bar', {}, undefined)
|
260
|
+
})
|
261
|
+
test('If a snippet user has an event "fail", it will not create a promise rejection or effect other method calls', async () => {
|
262
|
+
identifySpy.mockImplementationOnce(() => {
|
263
|
+
return Promise.reject('identity rejection')
|
264
|
+
})
|
265
|
+
consoleErrorSpy.mockImplementationOnce(() => null)
|
266
|
+
|
267
|
+
const onTrackCb = jest.fn()
|
268
|
+
const onTrack = ['on', 'track', onTrackCb]
|
269
|
+
const track = ['track', 'foo']
|
270
|
+
const track2 = ['track', 'bar']
|
271
|
+
const identify = ['identify']
|
272
|
+
|
273
|
+
;(window as any).htevents = [identify, onTrack, track, track2]
|
274
|
+
|
275
|
+
await HtEventsBrowser.standalone(writeKey)
|
276
|
+
|
277
|
+
await sleep(100) // the snippet does not return a promise (pre-initialization) ... it sometimes has a callback as the third argument.
|
278
|
+
expect(trackSpy).toBeCalledWith('foo', getBufferedPageCtxFixture())
|
279
|
+
expect(trackSpy).toBeCalledWith('bar', getBufferedPageCtxFixture())
|
280
|
+
expect(trackSpy).toBeCalledTimes(2)
|
281
|
+
|
282
|
+
expect(identifySpy).toBeCalledWith(getBufferedPageCtxFixture())
|
283
|
+
expect(identifySpy).toBeCalledTimes(1)
|
284
|
+
expect(consoleErrorSpy).toBeCalledTimes(1)
|
285
|
+
|
286
|
+
expect(consoleErrorSpy).toBeCalledWith('identity rejection')
|
287
|
+
|
288
|
+
expect(getOnSpyCalls('track').length).toBe(1)
|
289
|
+
|
290
|
+
expect(onTrackCb).toBeCalledTimes(2) // gets called once for each track event
|
291
|
+
expect(onTrackCb).toBeCalledWith('foo', {}, undefined)
|
292
|
+
expect(onTrackCb).toBeCalledWith('bar', {}, undefined)
|
293
|
+
})
|
294
|
+
test('events can be buffered under a custom window key', async () => {
|
295
|
+
const onTrackCb = jest.fn()
|
296
|
+
const onTrack = ['on', 'track', onTrackCb]
|
297
|
+
const track = ['track', 'foo']
|
298
|
+
const track2 = ['track', 'bar']
|
299
|
+
const identify = ['identify']
|
300
|
+
|
301
|
+
;(window as any).hightouch = [onTrack, track, track2, identify]
|
302
|
+
|
303
|
+
await HtEventsBrowser.standalone(writeKey, {
|
304
|
+
globalAnalyticsKey: 'hightouch',
|
305
|
+
})
|
306
|
+
|
307
|
+
await sleep(100) // the snippet does not return a promise (pre-initialization) ... it sometimes has a callback as the third argument.
|
308
|
+
expect(trackSpy).toBeCalledWith('foo', getBufferedPageCtxFixture())
|
309
|
+
expect(trackSpy).toBeCalledWith('bar', getBufferedPageCtxFixture())
|
310
|
+
expect(trackSpy).toBeCalledTimes(2)
|
311
|
+
|
312
|
+
expect(identifySpy).toBeCalledTimes(1)
|
313
|
+
|
314
|
+
expect(getOnSpyCalls('track').length).toBe(1)
|
315
|
+
expect(onTrackCb).toBeCalledTimes(2) // gets called once for each track event
|
316
|
+
expect(onTrackCb).toBeCalledWith('foo', {}, undefined)
|
317
|
+
expect(onTrackCb).toBeCalledWith('bar', {}, undefined)
|
318
|
+
})
|
319
|
+
})
|
320
|
+
|
321
|
+
describe('Emitter methods', () => {
|
322
|
+
test('If, before initialization, .on("track") is called, the .on method should be called after analytics load', async () => {
|
323
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
324
|
+
const args = ['track', jest.fn()] as const
|
325
|
+
ajsBrowser.on(...args)
|
326
|
+
expect(onSpy).not.toHaveBeenCalledWith(...args)
|
327
|
+
|
328
|
+
await ajsBrowser
|
329
|
+
expect(onSpy).toBeCalledWith(...args)
|
330
|
+
expect(getOnSpyCalls('track').length).toBe(1)
|
331
|
+
})
|
332
|
+
|
333
|
+
test('If, before initialization .on("track") is called and then .track is called, the callback method should be called after analytics loads', async () => {
|
334
|
+
const onFnCb = jest.fn()
|
335
|
+
const analytics = HtEventsBrowser.load({ writeKey })
|
336
|
+
analytics.on('track', onFnCb)
|
337
|
+
const trackCtxPromise = analytics.track('foo', { name: 123 })
|
338
|
+
|
339
|
+
expect(onFnCb).not.toHaveBeenCalled()
|
340
|
+
|
341
|
+
await Promise.all([analytics, trackCtxPromise])
|
342
|
+
|
343
|
+
expect(onSpy).toBeCalledWith('track', onFnCb)
|
344
|
+
expect(getOnSpyCalls('track').length).toBe(1)
|
345
|
+
|
346
|
+
expect(onFnCb).toHaveBeenCalledWith('foo', { name: 123 }, undefined)
|
347
|
+
expect(onFnCb).toBeCalledTimes(1)
|
348
|
+
})
|
349
|
+
|
350
|
+
test('If, before initialization, .ready is called, the callback method should be called after analytics loads', async () => {
|
351
|
+
const onReadyCb = jest.fn()
|
352
|
+
const analytics = HtEventsBrowser.load({ writeKey })
|
353
|
+
const onReadyPromise = analytics.ready(onReadyCb)
|
354
|
+
expect(onReadyCb).not.toHaveBeenCalled()
|
355
|
+
await onReadyPromise
|
356
|
+
expect(readySpy).toHaveBeenCalledTimes(1)
|
357
|
+
expect(onReadyCb).toHaveBeenCalledTimes(1)
|
358
|
+
expect(readySpy).toHaveBeenCalledWith(expect.any(Function))
|
359
|
+
})
|
360
|
+
|
361
|
+
test('Should work with "on" events if a track event is called after load is complete', async () => {
|
362
|
+
const onTrackCb = jest.fn()
|
363
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
364
|
+
ajsBrowser.on('track', onTrackCb)
|
365
|
+
await ajsBrowser
|
366
|
+
await ajsBrowser.track('foo', { name: 123 })
|
367
|
+
|
368
|
+
expect(onTrackCb).toHaveBeenCalledTimes(1)
|
369
|
+
expect(onTrackCb).toHaveBeenCalledWith('foo', { name: 123 }, undefined)
|
370
|
+
})
|
371
|
+
test('"on, off, once" should return ajsBrowser', () => {
|
372
|
+
const analytics = HtEventsBrowser.load({ writeKey })
|
373
|
+
expect(
|
374
|
+
[
|
375
|
+
analytics.on('track', jest.fn),
|
376
|
+
analytics.off('track', jest.fn),
|
377
|
+
analytics.once('track', jest.fn),
|
378
|
+
].map((el) => el instanceof HtEventsBrowser)
|
379
|
+
).toEqual([true, true, true])
|
380
|
+
})
|
381
|
+
|
382
|
+
test('"emitted" events should be chainable', async () => {
|
383
|
+
const onTrackCb = jest.fn()
|
384
|
+
const onIdentifyCb = jest.fn()
|
385
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
386
|
+
const identifyResult = ajsBrowser.identify('bar')
|
387
|
+
const result = ajsBrowser
|
388
|
+
.on('track', onTrackCb)
|
389
|
+
.on('identify', onIdentifyCb)
|
390
|
+
.once('group', jest.fn)
|
391
|
+
.off('alias', jest.fn)
|
392
|
+
|
393
|
+
expect(result instanceof HtEventsBrowser).toBeTruthy()
|
394
|
+
await ajsBrowser.track('foo', { name: 123 })
|
395
|
+
expect(onTrackCb).toHaveBeenCalledTimes(1)
|
396
|
+
expect(onTrackCb).toHaveBeenCalledWith('foo', { name: 123 }, undefined)
|
397
|
+
|
398
|
+
await identifyResult
|
399
|
+
expect(onIdentifyCb).toHaveBeenCalledTimes(1)
|
400
|
+
expect(onIdentifyCb).toHaveBeenCalledWith('bar', {}, undefined)
|
401
|
+
})
|
402
|
+
|
403
|
+
test('the "this" value of "emitted" event callbacks should be Analytics', async () => {
|
404
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
405
|
+
ajsBrowser.on('track', function onTrackCb(this: any) {
|
406
|
+
expect(this).toBeInstanceOf(Analytics)
|
407
|
+
})
|
408
|
+
ajsBrowser.once('group', function trackOnceCb(this: any) {
|
409
|
+
expect(this).toBeInstanceOf(Analytics)
|
410
|
+
})
|
411
|
+
|
412
|
+
await Promise.all([
|
413
|
+
ajsBrowser.track('foo', { name: 123 }),
|
414
|
+
ajsBrowser.group('foo'),
|
415
|
+
])
|
416
|
+
})
|
417
|
+
|
418
|
+
test('"return types should not change over the lifecycle for chainable methods', async () => {
|
419
|
+
const ajsBrowser = HtEventsBrowser.load({ writeKey })
|
420
|
+
|
421
|
+
const result1 = ajsBrowser.on('track', jest.fn)
|
422
|
+
expect(result1).toBeInstanceOf(HtEventsBrowser)
|
423
|
+
await result1
|
424
|
+
// loaded
|
425
|
+
const result2 = ajsBrowser.on('track', jest.fn)
|
426
|
+
expect(result2).toBeInstanceOf(HtEventsBrowser)
|
427
|
+
})
|
428
|
+
})
|
429
|
+
|
430
|
+
describe('Multi-instance', () => {
|
431
|
+
it('should not throw an error', async () => {
|
432
|
+
const ajsBrowser1 = HtEventsBrowser.load({ writeKey: 'foo' })
|
433
|
+
const ajsBrowser2 = HtEventsBrowser.load({ writeKey: 'abc' })
|
434
|
+
expect(ajsBrowser1).toBeInstanceOf(HtEventsBrowser)
|
435
|
+
expect(ajsBrowser2).toBeInstanceOf(HtEventsBrowser)
|
436
|
+
await ajsBrowser1
|
437
|
+
await ajsBrowser2
|
438
|
+
})
|
439
|
+
})
|
440
|
+
})
|