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.
Files changed (431) hide show
  1. package/.editorconfig +10 -0
  2. package/.eslintrc.isomorphic.js +26 -0
  3. package/.eslintrc.js +86 -0
  4. package/.gitattributes +1 -0
  5. package/.github/workflows/ci.yml +33 -0
  6. package/.github/workflows/deploy-browser-cdn-candidate.yml +51 -0
  7. package/.github/workflows/deploy-releases.yml +178 -0
  8. package/.nvmrc +1 -0
  9. package/.prettierrc +7 -0
  10. package/.vscode/extensions.json +3 -0
  11. package/.vscode/launch.json +81 -0
  12. package/.vscode/settings.json +41 -0
  13. package/.yarn/plugins/@yarnpkg/plugin-constraints.cjs +52 -0
  14. package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +546 -0
  15. package/.yarn/plugins/@yarnpkg/plugin-typescript.cjs +9 -0
  16. package/.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs +28 -0
  17. package/.yarn/releases/yarn-3.4.1.cjs +873 -0
  18. package/.yarnrc.yml +15 -0
  19. package/jest.config.js +18 -0
  20. package/package.json +59 -0
  21. package/packages/browser/.eslintrc.js +9 -0
  22. package/packages/browser/.lintstagedrc.js +1 -0
  23. package/packages/browser/ARCHITECTURE.md +48 -0
  24. package/packages/browser/LICENSE.MD +45 -0
  25. package/packages/browser/Makefile +64 -0
  26. package/packages/browser/README.md +227 -0
  27. package/packages/browser/e2e-tests/local-server.ts +28 -0
  28. package/packages/browser/e2e-tests/performance/ajs-perf-browser.test.ts +75 -0
  29. package/packages/browser/jest.config.js +15 -0
  30. package/packages/browser/jest.setup.js +10 -0
  31. package/packages/browser/package.json +106 -0
  32. package/packages/browser/qa/README.md +41 -0
  33. package/packages/browser/qa/__fixtures__/snippets.ts +148 -0
  34. package/packages/browser/qa/__tests__/backwards-compatibility.test.ts +180 -0
  35. package/packages/browser/qa/__tests__/destinations.test.ts +101 -0
  36. package/packages/browser/qa/__tests__/smoke.test.ts +170 -0
  37. package/packages/browser/qa/lib/benchmark.ts +36 -0
  38. package/packages/browser/qa/lib/browser.ts +28 -0
  39. package/packages/browser/qa/lib/jest-reporter.js +57 -0
  40. package/packages/browser/qa/lib/runner.ts +142 -0
  41. package/packages/browser/qa/lib/schema.ts +59 -0
  42. package/packages/browser/qa/lib/server.ts +54 -0
  43. package/packages/browser/qa/lib/stats.ts +52 -0
  44. package/packages/browser/scripts/build-prep.sh +7 -0
  45. package/packages/browser/scripts/ci.sh +15 -0
  46. package/packages/browser/scripts/release.js +121 -0
  47. package/packages/browser/scripts/release.sh +9 -0
  48. package/packages/browser/scripts/run.sh +8 -0
  49. package/packages/browser/src/browser/__tests__/analytics-lazy-init.integration.test.ts +51 -0
  50. package/packages/browser/src/browser/__tests__/analytics-pre-init.integration.test.ts +440 -0
  51. package/packages/browser/src/browser/__tests__/anon-id-and-reset.integration.test.ts +73 -0
  52. package/packages/browser/src/browser/__tests__/cdn.test.ts +53 -0
  53. package/packages/browser/src/browser/__tests__/csp-detection.test.ts +140 -0
  54. package/packages/browser/src/browser/__tests__/inspector.integration.test.ts +121 -0
  55. package/packages/browser/src/browser/__tests__/integration.test.ts +1213 -0
  56. package/packages/browser/src/browser/__tests__/integrations.integration.test.ts +260 -0
  57. package/packages/browser/src/browser/__tests__/page-enrichment.integration.test.ts +216 -0
  58. package/packages/browser/src/browser/__tests__/query-string.integration.test.ts +116 -0
  59. package/packages/browser/src/browser/__tests__/standalone-analytics.test.ts +303 -0
  60. package/packages/browser/src/browser/__tests__/standalone-errors.test.ts +136 -0
  61. package/packages/browser/src/browser/__tests__/standalone.test.ts +97 -0
  62. package/packages/browser/src/browser/__tests__/typedef-tests/analytics-browser.ts +150 -0
  63. package/packages/browser/src/browser/__tests__/update-cdn-settings.test.ts +71 -0
  64. package/packages/browser/src/browser/browser-umd.ts +19 -0
  65. package/packages/browser/src/browser/index.ts +486 -0
  66. package/packages/browser/src/browser/standalone-analytics.ts +62 -0
  67. package/packages/browser/src/browser/standalone-interface.ts +11 -0
  68. package/packages/browser/src/browser/standalone.ts +92 -0
  69. package/packages/browser/src/core/__tests__/track-form.test.ts +193 -0
  70. package/packages/browser/src/core/__tests__/track-link.test.ts +252 -0
  71. package/packages/browser/src/core/analytics/__tests__/integration.test.ts +334 -0
  72. package/packages/browser/src/core/analytics/__tests__/test-plugins.ts +94 -0
  73. package/packages/browser/src/core/analytics/index.ts +672 -0
  74. package/packages/browser/src/core/analytics/interfaces.ts +100 -0
  75. package/packages/browser/src/core/arguments-resolver/__tests__/index.test.ts +524 -0
  76. package/packages/browser/src/core/arguments-resolver/index.ts +200 -0
  77. package/packages/browser/src/core/auto-track.ts +152 -0
  78. package/packages/browser/src/core/buffer/__tests__/index.test.ts +455 -0
  79. package/packages/browser/src/core/buffer/index.ts +371 -0
  80. package/packages/browser/src/core/callback/index.ts +1 -0
  81. package/packages/browser/src/core/connection/__tests__/index.test.ts +25 -0
  82. package/packages/browser/src/core/connection/index.ts +13 -0
  83. package/packages/browser/src/core/constants/index.ts +1 -0
  84. package/packages/browser/src/core/context/__tests__/index.test.ts +201 -0
  85. package/packages/browser/src/core/context/index.ts +21 -0
  86. package/packages/browser/src/core/environment/index.ts +7 -0
  87. package/packages/browser/src/core/events/__tests__/index.test.ts +450 -0
  88. package/packages/browser/src/core/events/index.ts +280 -0
  89. package/packages/browser/src/core/events/interfaces.ts +36 -0
  90. package/packages/browser/src/core/inspector/index.ts +14 -0
  91. package/packages/browser/src/core/page/__tests__/index.test.ts +130 -0
  92. package/packages/browser/src/core/page/add-page-context.ts +33 -0
  93. package/packages/browser/src/core/page/get-page-context.ts +140 -0
  94. package/packages/browser/src/core/page/index.ts +2 -0
  95. package/packages/browser/src/core/plugin/index.ts +12 -0
  96. package/packages/browser/src/core/query-string/__tests__/gracefulDecodeURIComponent.test.ts +17 -0
  97. package/packages/browser/src/core/query-string/__tests__/index.test.ts +149 -0
  98. package/packages/browser/src/core/query-string/__tests__/pickPrefix.test.ts +31 -0
  99. package/packages/browser/src/core/query-string/__tests__/useQueryString.test.ts +60 -0
  100. package/packages/browser/src/core/query-string/gracefulDecodeURIComponent.ts +16 -0
  101. package/packages/browser/src/core/query-string/index.ts +64 -0
  102. package/packages/browser/src/core/query-string/pickPrefix.ts +20 -0
  103. package/packages/browser/src/core/queue/__tests__/event-queue.test.ts +82 -0
  104. package/packages/browser/src/core/queue/event-queue.ts +22 -0
  105. package/packages/browser/src/core/session/__tests__/index.test.ts +41 -0
  106. package/packages/browser/src/core/session/index.ts +107 -0
  107. package/packages/browser/src/core/stats/__tests__/index.test.ts +15 -0
  108. package/packages/browser/src/core/stats/__tests__/remote-metrics.test.ts +189 -0
  109. package/packages/browser/src/core/stats/index.ts +15 -0
  110. package/packages/browser/src/core/stats/remote-metrics.ts +144 -0
  111. package/packages/browser/src/core/storage/__tests__/cookieStorage.test.ts +58 -0
  112. package/packages/browser/src/core/storage/__tests__/localStorage.test.ts +70 -0
  113. package/packages/browser/src/core/storage/__tests__/test-helpers.ts +26 -0
  114. package/packages/browser/src/core/storage/__tests__/universalStorage.test.ts +167 -0
  115. package/packages/browser/src/core/storage/cookieStorage.ts +80 -0
  116. package/packages/browser/src/core/storage/index.ts +64 -0
  117. package/packages/browser/src/core/storage/localStorage.ts +45 -0
  118. package/packages/browser/src/core/storage/memoryStorage.ts +22 -0
  119. package/packages/browser/src/core/storage/settings.ts +23 -0
  120. package/packages/browser/src/core/storage/types.ts +49 -0
  121. package/packages/browser/src/core/storage/universalStorage.ts +78 -0
  122. package/packages/browser/src/core/user/__tests__/index.test.ts +922 -0
  123. package/packages/browser/src/core/user/__tests__/migrate.test.ts +101 -0
  124. package/packages/browser/src/core/user/__tests__/session.test.ts +136 -0
  125. package/packages/browser/src/core/user/__tests__/tld.test.ts +36 -0
  126. package/packages/browser/src/core/user/index.ts +399 -0
  127. package/packages/browser/src/core/user/migrate.ts +126 -0
  128. package/packages/browser/src/core/user/tld.ts +65 -0
  129. package/packages/browser/src/core/user/vendor/crypto-es/LICENSE +53 -0
  130. package/packages/browser/src/core/user/vendor/crypto-es/lib/aes.ts +302 -0
  131. package/packages/browser/src/core/user/vendor/crypto-es/lib/cipher-core.ts +922 -0
  132. package/packages/browser/src/core/user/vendor/crypto-es/lib/core.ts +806 -0
  133. package/packages/browser/src/core/user/vendor/crypto-es/lib/enc-base64.ts +110 -0
  134. package/packages/browser/src/core/user/vendor/crypto-es/lib/evpkdf.ts +110 -0
  135. package/packages/browser/src/core/user/vendor/crypto-es/lib/md5.ts +238 -0
  136. package/packages/browser/src/core/user/vendor/readme.md +7 -0
  137. package/packages/browser/src/generated/__tests__/version.test.ts +18 -0
  138. package/packages/browser/src/generated/version.ts +2 -0
  139. package/packages/browser/src/index.ts +13 -0
  140. package/packages/browser/src/lib/__tests__/embedded-write-key.test.ts +15 -0
  141. package/packages/browser/src/lib/__tests__/fetch.test.ts +35 -0
  142. package/packages/browser/src/lib/__tests__/get-process-env.test.ts +5 -0
  143. package/packages/browser/src/lib/__tests__/group-by.test.ts +96 -0
  144. package/packages/browser/src/lib/__tests__/is-plan-event-enabled.test.ts +36 -0
  145. package/packages/browser/src/lib/__tests__/is-thenable.test.ts +39 -0
  146. package/packages/browser/src/lib/__tests__/merged-options.test.ts +123 -0
  147. package/packages/browser/src/lib/__tests__/on-page-change.test.ts +74 -0
  148. package/packages/browser/src/lib/__tests__/parse-cdn.test.ts +88 -0
  149. package/packages/browser/src/lib/__tests__/pick.test.ts +34 -0
  150. package/packages/browser/src/lib/__tests__/pick.typedef.ts +39 -0
  151. package/packages/browser/src/lib/bind-all.ts +19 -0
  152. package/packages/browser/src/lib/browser-polyfill.ts +23 -0
  153. package/packages/browser/src/lib/client-hints/__tests__/index.test.ts +66 -0
  154. package/packages/browser/src/lib/client-hints/index.ts +16 -0
  155. package/packages/browser/src/lib/client-hints/interfaces.ts +42 -0
  156. package/packages/browser/src/lib/create-deferred.ts +16 -0
  157. package/packages/browser/src/lib/csp-detection.ts +8 -0
  158. package/packages/browser/src/lib/embedded-write-key.ts +24 -0
  159. package/packages/browser/src/lib/fetch.ts +10 -0
  160. package/packages/browser/src/lib/get-global.ts +16 -0
  161. package/packages/browser/src/lib/get-process-env.ts +11 -0
  162. package/packages/browser/src/lib/global-analytics-helper.ts +31 -0
  163. package/packages/browser/src/lib/group-by.ts +30 -0
  164. package/packages/browser/src/lib/is-plan-event-enabled.ts +20 -0
  165. package/packages/browser/src/lib/is-thenable.ts +9 -0
  166. package/packages/browser/src/lib/load-script.ts +66 -0
  167. package/packages/browser/src/lib/merged-options.ts +46 -0
  168. package/packages/browser/src/lib/on-page-change.ts +29 -0
  169. package/packages/browser/src/lib/p-while.ts +12 -0
  170. package/packages/browser/src/lib/parse-cdn.ts +56 -0
  171. package/packages/browser/src/lib/pick.ts +28 -0
  172. package/packages/browser/src/lib/priority-queue/__tests__/backoff.test.ts +23 -0
  173. package/packages/browser/src/lib/priority-queue/__tests__/index.test.ts +158 -0
  174. package/packages/browser/src/lib/priority-queue/__tests__/persisted.test.ts +228 -0
  175. package/packages/browser/src/lib/priority-queue/backoff.ts +24 -0
  176. package/packages/browser/src/lib/priority-queue/index.ts +6 -0
  177. package/packages/browser/src/lib/priority-queue/persisted.ts +127 -0
  178. package/packages/browser/src/lib/sleep.ts +4 -0
  179. package/packages/browser/src/lib/to-facade.ts +53 -0
  180. package/packages/browser/src/lib/version-type.ts +10 -0
  181. package/packages/browser/src/node/__tests__/node-integration.test.ts +19 -0
  182. package/packages/browser/src/node/index.ts +36 -0
  183. package/packages/browser/src/node/node.browser.ts +7 -0
  184. package/packages/browser/src/plugins/ajs-destination/__tests__/index.test.ts +834 -0
  185. package/packages/browser/src/plugins/ajs-destination/index.ts +392 -0
  186. package/packages/browser/src/plugins/ajs-destination/loader.ts +129 -0
  187. package/packages/browser/src/plugins/ajs-destination/types.ts +44 -0
  188. package/packages/browser/src/plugins/ajs-destination/utils.ts +32 -0
  189. package/packages/browser/src/plugins/analytics-node/__tests__/index.test.ts +69 -0
  190. package/packages/browser/src/plugins/analytics-node/index.ts +67 -0
  191. package/packages/browser/src/plugins/env-enrichment/__tests__/index.test.ts +421 -0
  192. package/packages/browser/src/plugins/env-enrichment/index.ts +208 -0
  193. package/packages/browser/src/plugins/hightouchio/__tests__/batched-dispatcher.test.ts +299 -0
  194. package/packages/browser/src/plugins/hightouchio/__tests__/index.test.ts +317 -0
  195. package/packages/browser/src/plugins/hightouchio/__tests__/normalize.test.ts +181 -0
  196. package/packages/browser/src/plugins/hightouchio/__tests__/retries.test.ts +82 -0
  197. package/packages/browser/src/plugins/hightouchio/batched-dispatcher.ts +127 -0
  198. package/packages/browser/src/plugins/hightouchio/fetch-dispatcher.ts +27 -0
  199. package/packages/browser/src/plugins/hightouchio/index.ts +147 -0
  200. package/packages/browser/src/plugins/hightouchio/normalize.ts +71 -0
  201. package/packages/browser/src/plugins/hightouchio/schedule-flush.ts +58 -0
  202. package/packages/browser/src/plugins/legacy-video-plugins/__tests__/index.test.ts +48 -0
  203. package/packages/browser/src/plugins/legacy-video-plugins/index.ts +16 -0
  204. package/packages/browser/src/plugins/middleware/__tests__/index.test.ts +268 -0
  205. package/packages/browser/src/plugins/middleware/index.ts +131 -0
  206. package/packages/browser/src/plugins/remote-loader/__tests__/index.test.ts +943 -0
  207. package/packages/browser/src/plugins/remote-loader/index.ts +256 -0
  208. package/packages/browser/src/plugins/remote-middleware/__tests__/index.test.ts +116 -0
  209. package/packages/browser/src/plugins/remote-middleware/index.ts +44 -0
  210. package/packages/browser/src/plugins/routing-middleware/__tests__/index.test.ts +64 -0
  211. package/packages/browser/src/plugins/routing-middleware/index.ts +37 -0
  212. package/packages/browser/src/plugins/schema-filter/__tests__/index.test.ts +520 -0
  213. package/packages/browser/src/plugins/schema-filter/index.ts +90 -0
  214. package/packages/browser/src/plugins/validation/__tests__/index.test.ts +78 -0
  215. package/packages/browser/src/plugins/validation/index.ts +44 -0
  216. package/packages/browser/src/test-helpers/browser-storage.ts +75 -0
  217. package/packages/browser/src/test-helpers/factories.ts +18 -0
  218. package/packages/browser/src/test-helpers/fetch-parse.ts +8 -0
  219. package/packages/browser/src/test-helpers/fixtures/cdn-settings.ts +301 -0
  220. package/packages/browser/src/test-helpers/fixtures/classic-destination.ts +25 -0
  221. package/packages/browser/src/test-helpers/fixtures/client-hints.ts +28 -0
  222. package/packages/browser/src/test-helpers/fixtures/create-fetch-method.ts +30 -0
  223. package/packages/browser/src/test-helpers/fixtures/index.ts +4 -0
  224. package/packages/browser/src/test-helpers/fixtures/page-context.ts +11 -0
  225. package/packages/browser/src/test-helpers/test-writekeys.ts +5 -0
  226. package/packages/browser/src/test-helpers/type-assertions.ts +11 -0
  227. package/packages/browser/src/tester/__fixtures__/hightouch-snippet.ts +64 -0
  228. package/packages/browser/src/tester/__fixtures__/index.html +8 -0
  229. package/packages/browser/src/tester/ajs-perf.ts +30 -0
  230. package/packages/browser/src/tester/ajs-tester.ts +119 -0
  231. package/packages/browser/src/tester/server.js +16 -0
  232. package/packages/browser/tsconfig.build.json +9 -0
  233. package/packages/browser/tsconfig.json +13 -0
  234. package/packages/browser/webpack.config.js +106 -0
  235. package/packages/config/package.json +10 -0
  236. package/packages/config/src/index.js +4 -0
  237. package/packages/config/src/jest/config.js +50 -0
  238. package/packages/config/src/jest/get-module-map.js +34 -0
  239. package/packages/config/src/lint-staged/config.js +4 -0
  240. package/packages/config-webpack/package.json +20 -0
  241. package/packages/config-webpack/webpack.config.common.js +75 -0
  242. package/packages/consent/consent-tools/.eslintrc.js +7 -0
  243. package/packages/consent/consent-tools/.lintstagedrc.js +1 -0
  244. package/packages/consent/consent-tools/LICENSE +45 -0
  245. package/packages/consent/consent-tools/README.md +104 -0
  246. package/packages/consent/consent-tools/jest.config.js +6 -0
  247. package/packages/consent/consent-tools/jest.setup.js +4 -0
  248. package/packages/consent/consent-tools/package.json +48 -0
  249. package/packages/consent/consent-tools/src/domain/__tests__/assertions/integrations-assertions.ts +37 -0
  250. package/packages/consent/consent-tools/src/domain/__tests__/consent-stamping.test.ts +45 -0
  251. package/packages/consent/consent-tools/src/domain/__tests__/create-wrapper.test.ts +816 -0
  252. package/packages/consent/consent-tools/src/domain/__tests__/typedef-tests.ts +21 -0
  253. package/packages/consent/consent-tools/src/domain/consent-changed.ts +51 -0
  254. package/packages/consent/consent-tools/src/domain/consent-stamping.ts +19 -0
  255. package/packages/consent/consent-tools/src/domain/create-wrapper.ts +238 -0
  256. package/packages/consent/consent-tools/src/domain/get-initialized-analytics.ts +25 -0
  257. package/packages/consent/consent-tools/src/domain/load-cancellation.ts +31 -0
  258. package/packages/consent/consent-tools/src/domain/validation/__tests__/options-validators.test.ts +77 -0
  259. package/packages/consent/consent-tools/src/domain/validation/__tests__/validation-error.test.ts +15 -0
  260. package/packages/consent/consent-tools/src/domain/validation/common-validators.ts +19 -0
  261. package/packages/consent/consent-tools/src/domain/validation/index.ts +1 -0
  262. package/packages/consent/consent-tools/src/domain/validation/options-validators.ts +74 -0
  263. package/packages/consent/consent-tools/src/domain/validation/validation-error.ts +11 -0
  264. package/packages/consent/consent-tools/src/index.ts +16 -0
  265. package/packages/consent/consent-tools/src/types/errors.ts +14 -0
  266. package/packages/consent/consent-tools/src/types/index.ts +3 -0
  267. package/packages/consent/consent-tools/src/types/settings.ts +121 -0
  268. package/packages/consent/consent-tools/src/types/wrapper.ts +107 -0
  269. package/packages/consent/consent-tools/src/utils/index.ts +4 -0
  270. package/packages/consent/consent-tools/src/utils/pick.ts +18 -0
  271. package/packages/consent/consent-tools/src/utils/pipe.ts +14 -0
  272. package/packages/consent/consent-tools/src/utils/resolve-when.ts +32 -0
  273. package/packages/consent/consent-tools/src/utils/uniq.ts +4 -0
  274. package/packages/consent/consent-tools/tsconfig.build.json +9 -0
  275. package/packages/consent/consent-tools/tsconfig.json +12 -0
  276. package/packages/consent/consent-wrapper-onetrust/.eslintrc.js +7 -0
  277. package/packages/consent/consent-wrapper-onetrust/.lintstagedrc.js +1 -0
  278. package/packages/consent/consent-wrapper-onetrust/LICENSE +45 -0
  279. package/packages/consent/consent-wrapper-onetrust/README.md +125 -0
  280. package/packages/consent/consent-wrapper-onetrust/img/onetrust-cat-id.jpg +0 -0
  281. package/packages/consent/consent-wrapper-onetrust/img/onetrust-popup.jpg +0 -0
  282. package/packages/consent/consent-wrapper-onetrust/jest.config.js +6 -0
  283. package/packages/consent/consent-wrapper-onetrust/jest.setup.js +4 -0
  284. package/packages/consent/consent-wrapper-onetrust/package.json +60 -0
  285. package/packages/consent/consent-wrapper-onetrust/src/domain/__tests__/wrapper.test.ts +151 -0
  286. package/packages/consent/consent-wrapper-onetrust/src/domain/wrapper.ts +61 -0
  287. package/packages/consent/consent-wrapper-onetrust/src/index.ts +6 -0
  288. package/packages/consent/consent-wrapper-onetrust/src/index.umd.ts +11 -0
  289. package/packages/consent/consent-wrapper-onetrust/src/lib/__tests__/onetrust-api.test.ts +181 -0
  290. package/packages/consent/consent-wrapper-onetrust/src/lib/onetrust-api.ts +155 -0
  291. package/packages/consent/consent-wrapper-onetrust/src/lib/validation/index.ts +1 -0
  292. package/packages/consent/consent-wrapper-onetrust/src/lib/validation/onetrust-api-error.ts +11 -0
  293. package/packages/consent/consent-wrapper-onetrust/src/test-helpers/mocks.ts +23 -0
  294. package/packages/consent/consent-wrapper-onetrust/src/test-helpers/onetrust-globals.d.ts +11 -0
  295. package/packages/consent/consent-wrapper-onetrust/src/test-helpers/utils.ts +3 -0
  296. package/packages/consent/consent-wrapper-onetrust/tsconfig.build.json +9 -0
  297. package/packages/consent/consent-wrapper-onetrust/tsconfig.json +11 -0
  298. package/packages/consent/consent-wrapper-onetrust/webpack.config.js +25 -0
  299. package/packages/core/.eslintrc.js +4 -0
  300. package/packages/core/.lintstagedrc.js +1 -0
  301. package/packages/core/LICENSE.MD +45 -0
  302. package/packages/core/README.md +3 -0
  303. package/packages/core/jest.config.js +5 -0
  304. package/packages/core/jest.setup.js +10 -0
  305. package/packages/core/package.json +40 -0
  306. package/packages/core/src/analytics/__tests__/dispatch.test.ts +95 -0
  307. package/packages/core/src/analytics/dispatch.ts +58 -0
  308. package/packages/core/src/analytics/index.ts +11 -0
  309. package/packages/core/src/callback/__tests__/index.test.ts +85 -0
  310. package/packages/core/src/callback/index.ts +51 -0
  311. package/packages/core/src/context/index.ts +123 -0
  312. package/packages/core/src/emitter/__tests__/emitter.test.ts +74 -0
  313. package/packages/core/src/emitter/index.ts +65 -0
  314. package/packages/core/src/emitter/interface.ts +31 -0
  315. package/packages/core/src/events/__tests__/index.test.ts +394 -0
  316. package/packages/core/src/events/index.ts +280 -0
  317. package/packages/core/src/events/interfaces.ts +475 -0
  318. package/packages/core/src/index.ts +19 -0
  319. package/packages/core/src/logger/__tests__/index.test.ts +66 -0
  320. package/packages/core/src/logger/index.ts +74 -0
  321. package/packages/core/src/plugins/index.ts +43 -0
  322. package/packages/core/src/priority-queue/__tests__/backoff.test.ts +23 -0
  323. package/packages/core/src/priority-queue/__tests__/index.test.ts +158 -0
  324. package/packages/core/src/priority-queue/backoff.ts +24 -0
  325. package/packages/core/src/priority-queue/index.ts +103 -0
  326. package/packages/core/src/queue/__tests__/event-queue.test.ts +678 -0
  327. package/packages/core/src/queue/__tests__/extension-flushing.test.ts +416 -0
  328. package/packages/core/src/queue/delivery.ts +73 -0
  329. package/packages/core/src/queue/event-queue.ts +318 -0
  330. package/packages/core/src/stats/__tests__/index.test.ts +103 -0
  331. package/packages/core/src/stats/index.ts +88 -0
  332. package/packages/core/src/task/__tests__/task-group.test.ts +26 -0
  333. package/packages/core/src/task/task-group.ts +31 -0
  334. package/packages/core/src/user/index.ts +7 -0
  335. package/packages/core/src/utils/__tests__/group-by.test.ts +96 -0
  336. package/packages/core/src/utils/__tests__/is-plain-object.test.ts +27 -0
  337. package/packages/core/src/utils/__tests__/is-thenable.test.ts +39 -0
  338. package/packages/core/src/utils/bind-all.ts +19 -0
  339. package/packages/core/src/utils/get-global.ts +17 -0
  340. package/packages/core/src/utils/group-by.ts +30 -0
  341. package/packages/core/src/utils/has-properties.ts +7 -0
  342. package/packages/core/src/utils/is-plain-object.ts +26 -0
  343. package/packages/core/src/utils/is-thenable.ts +9 -0
  344. package/packages/core/src/utils/p-while.ts +12 -0
  345. package/packages/core/src/utils/pick.ts +8 -0
  346. package/packages/core/src/utils/ts-helpers.ts +13 -0
  347. package/packages/core/src/validation/__tests__/assertions.test.ts +155 -0
  348. package/packages/core/src/validation/assertions.ts +72 -0
  349. package/packages/core/src/validation/errors.ts +8 -0
  350. package/packages/core/src/validation/helpers.ts +23 -0
  351. package/packages/core/test-helpers/index.ts +2 -0
  352. package/packages/core/test-helpers/test-ctx.ts +7 -0
  353. package/packages/core/test-helpers/test-event-queue.ts +7 -0
  354. package/packages/core/tsconfig.build.json +9 -0
  355. package/packages/core/tsconfig.json +11 -0
  356. package/packages/node/.eslintrc.js +7 -0
  357. package/packages/node/.lintstagedrc.js +1 -0
  358. package/packages/node/LICENSE +45 -0
  359. package/packages/node/README.md +138 -0
  360. package/packages/node/jest.config.js +5 -0
  361. package/packages/node/jest.setup.js +4 -0
  362. package/packages/node/package.json +50 -0
  363. package/packages/node/scripts/version.sh +11 -0
  364. package/packages/node/src/__tests__/callback.test.ts +47 -0
  365. package/packages/node/src/__tests__/disable.integration.test.ts +42 -0
  366. package/packages/node/src/__tests__/emitter.integration.test.ts +45 -0
  367. package/packages/node/src/__tests__/graceful-shutdown-integration.test.ts +244 -0
  368. package/packages/node/src/__tests__/http-client.integration.test.ts +69 -0
  369. package/packages/node/src/__tests__/http-integration.test.ts +362 -0
  370. package/packages/node/src/__tests__/integration.test.ts +357 -0
  371. package/packages/node/src/__tests__/plugins.test.ts +16 -0
  372. package/packages/node/src/__tests__/settings.test.ts +9 -0
  373. package/packages/node/src/__tests__/test-helpers/assert-shape/http-request-event.ts +13 -0
  374. package/packages/node/src/__tests__/test-helpers/assert-shape/index.ts +2 -0
  375. package/packages/node/src/__tests__/test-helpers/assert-shape/segment-http-api.ts +43 -0
  376. package/packages/node/src/__tests__/test-helpers/create-test-analytics.ts +42 -0
  377. package/packages/node/src/__tests__/test-helpers/factories.ts +17 -0
  378. package/packages/node/src/__tests__/test-helpers/is-valid-date.ts +6 -0
  379. package/packages/node/src/__tests__/test-helpers/resolve-ctx.ts +19 -0
  380. package/packages/node/src/__tests__/test-helpers/resolve-emitter.ts +11 -0
  381. package/packages/node/src/__tests__/test-helpers/sleep.ts +3 -0
  382. package/packages/node/src/__tests__/test-helpers/test-plugin.ts +16 -0
  383. package/packages/node/src/__tests__/typedef-tests.ts +120 -0
  384. package/packages/node/src/app/analytics-node.ts +299 -0
  385. package/packages/node/src/app/context.ts +11 -0
  386. package/packages/node/src/app/dispatch-emit.ts +42 -0
  387. package/packages/node/src/app/emitter.ts +23 -0
  388. package/packages/node/src/app/event-factory.ts +20 -0
  389. package/packages/node/src/app/event-queue.ts +23 -0
  390. package/packages/node/src/app/settings.ts +49 -0
  391. package/packages/node/src/app/types/index.ts +3 -0
  392. package/packages/node/src/app/types/params.ts +76 -0
  393. package/packages/node/src/app/types/plugin.ts +5 -0
  394. package/packages/node/src/app/types/segment-event.ts +7 -0
  395. package/packages/node/src/generated/version.ts +2 -0
  396. package/packages/node/src/index.ts +26 -0
  397. package/packages/node/src/lib/__tests__/abort.test.ts +54 -0
  398. package/packages/node/src/lib/__tests__/create-url.test.ts +35 -0
  399. package/packages/node/src/lib/__tests__/env.test.ts +52 -0
  400. package/packages/node/src/lib/__tests__/get-message-id.test.ts +21 -0
  401. package/packages/node/src/lib/abort.ts +77 -0
  402. package/packages/node/src/lib/base-64-encode.ts +8 -0
  403. package/packages/node/src/lib/create-url.ts +11 -0
  404. package/packages/node/src/lib/env.ts +45 -0
  405. package/packages/node/src/lib/extract-promise-parts.ts +21 -0
  406. package/packages/node/src/lib/fetch.ts +16 -0
  407. package/packages/node/src/lib/get-message-id.ts +10 -0
  408. package/packages/node/src/lib/http-client.ts +95 -0
  409. package/packages/node/src/lib/uuid.ts +1 -0
  410. package/packages/node/src/plugins/segmentio/__tests__/methods.test.ts +223 -0
  411. package/packages/node/src/plugins/segmentio/__tests__/publisher.test.ts +411 -0
  412. package/packages/node/src/plugins/segmentio/context-batch.ts +71 -0
  413. package/packages/node/src/plugins/segmentio/index.ts +66 -0
  414. package/packages/node/src/plugins/segmentio/publisher.ts +265 -0
  415. package/packages/node/tsconfig.build.json +9 -0
  416. package/packages/node/tsconfig.json +10 -0
  417. package/packages/test-helpers/.eslintrc.js +7 -0
  418. package/packages/test-helpers/.lintstagedrc.js +1 -0
  419. package/packages/test-helpers/jest.config.js +3 -0
  420. package/packages/test-helpers/package.json +26 -0
  421. package/packages/test-helpers/src/analytics/cdn-settings-builder.ts +79 -0
  422. package/packages/test-helpers/src/analytics/index.ts +1 -0
  423. package/packages/test-helpers/src/index.ts +2 -0
  424. package/packages/test-helpers/src/utils/index.ts +1 -0
  425. package/packages/test-helpers/src/utils/sleep.ts +4 -0
  426. package/packages/test-helpers/tsconfig.build.json +9 -0
  427. package/packages/test-helpers/tsconfig.json +11 -0
  428. package/tsconfig.json +21 -0
  429. package/turbo.json +39 -0
  430. package/typings/get-monorepo-packages.d.ts +9 -0
  431. package/typings/spawn.d.ts +10 -0
@@ -0,0 +1,303 @@
1
+ import jsdom, { JSDOM } from 'jsdom'
2
+ import { InitOptions, getGlobalAnalytics } from '../../'
3
+ import { HtEventsBrowser, loadLegacySettings } from '../../browser'
4
+ import { snippet } from '../../tester/__fixtures__/hightouch-snippet'
5
+ import { install } from '../standalone-analytics'
6
+ import unfetch from 'unfetch'
7
+ import { PersistedPriorityQueue } from '../../lib/priority-queue/persisted'
8
+ import { sleep } from '../../lib/sleep'
9
+ import * as Factory from '../../test-helpers/factories'
10
+ import { EventQueue } from '../../core/queue/event-queue'
11
+ import { AnalyticsStandalone } from '../standalone-interface'
12
+ import { getBufferedPageCtxFixture } from '../../test-helpers/fixtures'
13
+
14
+ const track = jest.fn()
15
+ const identify = jest.fn()
16
+ const page = jest.fn()
17
+ const setAnonymousId = jest.fn()
18
+ const register = jest.fn()
19
+ const addSourceMiddleware = jest.fn()
20
+ const on = jest.fn()
21
+
22
+ jest.mock('../../core/analytics', () => ({
23
+ Analytics: (_: unknown, options?: InitOptions): unknown => ({
24
+ track,
25
+ identify,
26
+ page,
27
+ setAnonymousId,
28
+ addSourceMiddleware,
29
+ register,
30
+ emit: jest.fn(),
31
+ on,
32
+ queue: new EventQueue(new PersistedPriorityQueue(1, 'event-queue') as any),
33
+ options,
34
+ }),
35
+ }))
36
+
37
+ const fetchSettings = Factory.createSuccess({ integrations: {} })
38
+
39
+ jest.mock('unfetch', () => {
40
+ return jest.fn()
41
+ })
42
+
43
+ describe('standalone bundle', () => {
44
+ const hightouchDotCom = `foo`
45
+
46
+ beforeEach(async () => {
47
+ ;(window as any).htevents = undefined
48
+ const html = `
49
+ <!DOCTYPE html>
50
+ <head>
51
+ <script>
52
+ ${snippet(
53
+ hightouchDotCom,
54
+ true,
55
+ `
56
+ window.htevents.track('fruit basket', { fruits: ['🍌', '🍇'] })
57
+ window.htevents.identify('netto', { employer: 'hightouch' })
58
+ window.htevents.setAnonymousId('anonNetto')
59
+ window.htevents.on('initialize', () => ({ user: 'ariel' }))
60
+ `
61
+ )}
62
+ </script>
63
+ </head>
64
+ <body>
65
+ </body>
66
+ </html>
67
+ `.trim()
68
+
69
+ const virtualConsole = new jsdom.VirtualConsole()
70
+
71
+ const jsd = new JSDOM(html, {
72
+ runScripts: 'dangerously',
73
+ resources: 'usable',
74
+ url: 'https://hightouch.com',
75
+ virtualConsole,
76
+ })
77
+
78
+ const windowSpy = jest.spyOn(global, 'window', 'get')
79
+ const documentSpy = jest.spyOn(global, 'document', 'get')
80
+
81
+ jest.spyOn(console, 'warn').mockImplementationOnce(() => {})
82
+ jest.spyOn(console, 'error').mockImplementationOnce(() => {})
83
+
84
+ windowSpy.mockImplementation(() => {
85
+ return jsd.window as unknown as Window & typeof globalThis
86
+ })
87
+
88
+ documentSpy.mockImplementation(
89
+ () => jsd.window.document as unknown as Document
90
+ )
91
+ })
92
+
93
+ it('detects embedded write keys', async () => {
94
+ window.analyticsWriteKey = 'write_key_abc_123'
95
+
96
+ const fakeAjs = {
97
+ ready: async (cb: Function): Promise<void> => {
98
+ cb()
99
+ },
100
+ }
101
+
102
+ const spy = jest
103
+ .spyOn(HtEventsBrowser, 'standalone')
104
+ .mockResolvedValueOnce(fakeAjs as AnalyticsStandalone)
105
+
106
+ await install()
107
+
108
+ expect(spy).toHaveBeenCalledWith('write_key_abc_123', {})
109
+ })
110
+
111
+ it('derives the write key from scripts on the page', async () => {
112
+ const fakeAjs = {
113
+ ready: async (cb: Function): Promise<void> => {
114
+ cb()
115
+ },
116
+ }
117
+ const spy = jest
118
+ .spyOn(HtEventsBrowser, 'standalone')
119
+ .mockResolvedValueOnce(fakeAjs as AnalyticsStandalone)
120
+
121
+ await install()
122
+
123
+ expect(spy).toHaveBeenCalledWith(hightouchDotCom, {})
124
+ })
125
+
126
+ it('derives the CDN from scripts on the page', async () => {
127
+ jest
128
+ .mocked(unfetch)
129
+ // @ts-ignore ignore Response required fields
130
+ .mockImplementation((): Promise<Response> => fetchSettings)
131
+
132
+ await loadLegacySettings(hightouchDotCom)
133
+
134
+ expect(unfetch).toHaveBeenCalledWith(
135
+ 'https://cdn.foo.com/v1/projects/foo/settings'
136
+ )
137
+ })
138
+
139
+ it('is capable of having the CDN overridden', async () => {
140
+ jest
141
+ .mocked(unfetch)
142
+ // @ts-ignore ignore Response required fields
143
+ .mockImplementation((): Promise<Response> => fetchSettings)
144
+ const mockCdn = 'http://my-overridden-cdn.com'
145
+
146
+ getGlobalAnalytics()!._cdn = mockCdn
147
+ await loadLegacySettings(hightouchDotCom)
148
+
149
+ expect(unfetch).toHaveBeenCalledWith(expect.stringContaining(mockCdn))
150
+ })
151
+
152
+ it('runs any buffered operations after load', async () => {
153
+ jest
154
+ .mocked(unfetch)
155
+ // @ts-ignore ignore Response required fields
156
+ .mockImplementation((): Promise<Response> => fetchSettings)
157
+
158
+ await install()
159
+
160
+ await sleep(0)
161
+
162
+ expect(track).toHaveBeenCalledWith(
163
+ 'fruit basket',
164
+ {
165
+ fruits: ['🍌', '🍇'],
166
+ },
167
+ getBufferedPageCtxFixture()
168
+ )
169
+ expect(identify).toHaveBeenCalledWith(
170
+ 'netto',
171
+ {
172
+ employer: 'hightouch',
173
+ },
174
+ getBufferedPageCtxFixture()
175
+ )
176
+
177
+ expect(page).toHaveBeenCalled()
178
+ })
179
+
180
+ it('adds buffered source middleware before other buffered operations', async () => {
181
+ jest
182
+ .mocked(unfetch)
183
+ // @ts-ignore ignore Response required fields
184
+ .mockImplementation((): Promise<Response> => fetchSettings)
185
+
186
+ const operations: string[] = []
187
+
188
+ addSourceMiddleware.mockImplementationOnce(() =>
189
+ operations.push('addSourceMiddleware')
190
+ )
191
+ page.mockImplementationOnce(() => operations.push('page'))
192
+
193
+ await install()
194
+
195
+ await sleep(0)
196
+
197
+ expect(addSourceMiddleware).toHaveBeenCalled()
198
+
199
+ expect(operations).toEqual([
200
+ // should run before page call in the snippet
201
+ 'addSourceMiddleware',
202
+ 'page',
203
+ ])
204
+ })
205
+
206
+ it('sets buffered anonymousId before loading destinations', async () => {
207
+ jest
208
+ .mocked(unfetch)
209
+ // @ts-ignore ignore Response required fields
210
+ .mockImplementation((): Promise<Response> => fetchSettings)
211
+
212
+ const operations: string[] = []
213
+
214
+ track.mockImplementationOnce(() => operations.push('track'))
215
+ setAnonymousId.mockImplementationOnce(() =>
216
+ operations.push('setAnonymousId')
217
+ )
218
+ register.mockImplementationOnce(() => operations.push('register'))
219
+
220
+ await install()
221
+
222
+ await sleep(0)
223
+
224
+ expect(setAnonymousId).toHaveBeenCalledWith('anonNetto')
225
+
226
+ expect(operations).toEqual([
227
+ // should run before any plugin is registered
228
+ 'setAnonymousId',
229
+ // should run before any events are sent downstream
230
+ 'register',
231
+ // should run after all plugins have been registered
232
+ 'track',
233
+ ])
234
+ })
235
+ it('sets buffered event emitters before loading destinations', async () => {
236
+ jest
237
+ .mocked(unfetch)
238
+ .mockImplementation(() => fetchSettings as Promise<Response>)
239
+
240
+ const operations: string[] = []
241
+
242
+ track.mockImplementationOnce(() => operations.push('track'))
243
+ on.mockImplementationOnce(() => operations.push('on'))
244
+ register.mockImplementationOnce(() => operations.push('register'))
245
+
246
+ await install()
247
+
248
+ await sleep(0)
249
+
250
+ const initializeCalls = on.mock.calls.filter(
251
+ ([arg1]) => arg1 === 'initialize'
252
+ )
253
+
254
+ expect(initializeCalls.length).toBe(1)
255
+
256
+ expect(operations).toEqual([
257
+ // should run before any plugin is registered
258
+ 'on',
259
+ // should run before any events are sent downstream
260
+ 'register',
261
+ // should run after all plugins have been registered
262
+ 'track',
263
+ ])
264
+ })
265
+
266
+ it('runs any buffered operations created after preFlush after load', async () => {
267
+ jest
268
+ .mocked(unfetch)
269
+ // @ts-ignore ignore Response required fields
270
+ .mockImplementation((): Promise<Response> => fetchSettings)
271
+
272
+ // register is called after flushPreBuffer in `loadAnalytics`
273
+ register.mockImplementationOnce(() =>
274
+ getGlobalAnalytics()?.track('race conditions', { foo: 'bar' })
275
+ )
276
+
277
+ await install()
278
+
279
+ await sleep(0)
280
+
281
+ expect(track).toHaveBeenCalledWith(
282
+ 'fruit basket',
283
+ {
284
+ fruits: ['🍌', '🍇'],
285
+ },
286
+ getBufferedPageCtxFixture()
287
+ )
288
+ expect(track).toHaveBeenCalledWith(
289
+ 'race conditions',
290
+ { foo: 'bar' },
291
+ getBufferedPageCtxFixture()
292
+ )
293
+ expect(identify).toHaveBeenCalledWith(
294
+ 'netto',
295
+ {
296
+ employer: 'hightouch',
297
+ },
298
+ getBufferedPageCtxFixture()
299
+ )
300
+
301
+ expect(page).toHaveBeenCalled()
302
+ })
303
+ })
@@ -0,0 +1,136 @@
1
+ import jsdom, { JSDOM } from 'jsdom'
2
+ import { HtEventsBrowser, LegacySettings } from '..'
3
+ import { snippet } from '../../tester/__fixtures__/hightouch-snippet'
4
+ import { pWhile } from '../../lib/p-while'
5
+ import unfetch from 'unfetch'
6
+ import { RemoteMetrics } from '../../core/stats/remote-metrics'
7
+ import * as Factory from '../../test-helpers/factories'
8
+
9
+ const cdnResponse: LegacySettings = {
10
+ integrations: {
11
+ Zapier: {
12
+ type: 'server',
13
+ },
14
+ 'Amazon S3': {},
15
+ Amplitude: {
16
+ type: 'browser',
17
+ },
18
+ Hightouchio: {
19
+ type: 'browser',
20
+ },
21
+ Iterable: {
22
+ type: 'browser',
23
+ name: 'Iterable',
24
+ },
25
+ },
26
+ }
27
+
28
+ const fetchSettings = Factory.createSuccess(cdnResponse)
29
+
30
+ jest.mock('unfetch', () => {
31
+ return jest.fn()
32
+ })
33
+
34
+ describe('standalone bundle', () => {
35
+ const hightouchDotCom = `foo`
36
+
37
+ let jsd: JSDOM
38
+
39
+ beforeEach(() => {
40
+ jest.restoreAllMocks()
41
+ jest.resetAllMocks()
42
+
43
+ jest.spyOn(console, 'warn').mockImplementationOnce(() => {})
44
+
45
+ jest
46
+ .mocked(unfetch)
47
+ // @ts-ignore ignore Response required fields
48
+ .mockImplementation((): Promise<Response> => fetchSettings)
49
+
50
+ const html = `
51
+ <!DOCTYPE html>
52
+ <head>
53
+ <script>
54
+ ${snippet(hightouchDotCom, true)}
55
+ </script>
56
+ </head>
57
+ <body>
58
+ </body>
59
+ </html>
60
+ `.trim()
61
+
62
+ const virtualConsole = new jsdom.VirtualConsole()
63
+ jsd = new JSDOM(html, {
64
+ runScripts: 'dangerously',
65
+ resources: 'usable',
66
+ url: 'https://hightouch.com',
67
+ virtualConsole,
68
+ })
69
+
70
+ const windowSpy = jest.spyOn(global, 'window', 'get')
71
+ const documentSpy = jest.spyOn(global, 'document', 'get')
72
+
73
+ jest.spyOn(console, 'warn').mockImplementationOnce(() => {})
74
+
75
+ windowSpy.mockImplementation(() => {
76
+ return jsd.window as unknown as Window & typeof globalThis
77
+ })
78
+
79
+ documentSpy.mockImplementation(
80
+ () => jsd.window.document as unknown as Document
81
+ )
82
+ })
83
+
84
+ it('catches initialization errors and reports them', async () => {
85
+ window.analyticsWriteKey = 'write_key_abc_123'
86
+ const errorMessages: string[] = []
87
+ const metrics: { metric: string; tags: string[] }[] = []
88
+
89
+ jest.spyOn(console, 'error').mockImplementationOnce((...args) => {
90
+ errorMessages.push(args.join(','))
91
+ })
92
+
93
+ jest
94
+ .spyOn(RemoteMetrics.prototype, 'increment')
95
+ .mockImplementationOnce((metric, tags) => {
96
+ metrics.push({
97
+ metric,
98
+ tags,
99
+ })
100
+ })
101
+
102
+ jest
103
+ .spyOn(HtEventsBrowser, 'standalone')
104
+ .mockRejectedValueOnce(new Error('Ohhh nooo'))
105
+
106
+ await import('../standalone')
107
+
108
+ await pWhile(
109
+ () => errorMessages.length === 0,
110
+ () => {}
111
+ )
112
+
113
+ expect(metrics).toMatchInlineSnapshot(`Array []`)
114
+
115
+ // Uncomment when re-enabling RemoteMetrics -- see standalone.ts and loadAnalytics usage of RemoteMetrics
116
+ // expect(metrics).toMatchInlineSnapshot(`
117
+ // Array [
118
+ // Object {
119
+ // "metric": "analytics_js.invoke.error",
120
+ // "tags": Array [
121
+ // "type:initialization",
122
+ // "message:Ohhh nooo",
123
+ // "name:Error",
124
+ // "wk:write_key_abc_123",
125
+ // ],
126
+ // },
127
+ // ]
128
+ // `)
129
+
130
+ expect(errorMessages).toMatchInlineSnapshot(`
131
+ Array [
132
+ "[analytics.js],Failed to load Analytics.js,Error: Ohhh nooo",
133
+ ]
134
+ `)
135
+ })
136
+ })
@@ -0,0 +1,97 @@
1
+ import jsdom, { JSDOM } from 'jsdom'
2
+ import unfetch from 'unfetch'
3
+ import { LegacySettings } from '..'
4
+ import { pWhile } from '../../lib/p-while'
5
+ import { snippet } from '../../tester/__fixtures__/hightouch-snippet'
6
+ import * as Factory from '../../test-helpers/factories'
7
+ import { getGlobalAnalytics } from '../..'
8
+
9
+ const cdnResponse: LegacySettings = {
10
+ integrations: {
11
+ Zapier: {
12
+ type: 'server',
13
+ },
14
+ 'Amazon S3': {},
15
+ Amplitude: {
16
+ type: 'browser',
17
+ },
18
+ Hightouchio: {
19
+ type: 'browser',
20
+ },
21
+ Iterable: {
22
+ type: 'browser',
23
+ name: 'Iterable',
24
+ },
25
+ },
26
+ }
27
+
28
+ const fetchSettings = Factory.createSuccess(cdnResponse)
29
+
30
+ jest.mock('unfetch', () => {
31
+ return jest.fn()
32
+ })
33
+
34
+ describe('standalone bundle', () => {
35
+ const hightouchDotCom = `foo`
36
+
37
+ let jsd: JSDOM
38
+ let windowSpy: jest.SpyInstance
39
+ let documentSpy: jest.SpyInstance
40
+
41
+ beforeEach(() => {
42
+ jest.restoreAllMocks()
43
+ jest.resetAllMocks()
44
+
45
+ jest.spyOn(console, 'warn').mockImplementationOnce(() => {})
46
+
47
+ jest
48
+ .mocked(unfetch)
49
+ // @ts-ignore ignore Response required fields
50
+ .mockImplementation((): Promise<Response> => fetchSettings)
51
+
52
+ const html = `
53
+ <!DOCTYPE html>
54
+ <head>
55
+ <script>
56
+ ${snippet(hightouchDotCom, true)}
57
+ </script>
58
+ </head>
59
+ <body>
60
+ </body>
61
+ </html>
62
+ `.trim()
63
+
64
+ const virtualConsole = new jsdom.VirtualConsole()
65
+ jsd = new JSDOM(html, {
66
+ runScripts: 'dangerously',
67
+ resources: 'usable',
68
+ url: 'https://hightouch.com',
69
+ virtualConsole,
70
+ })
71
+
72
+ windowSpy = jest.spyOn(global, 'window', 'get')
73
+ documentSpy = jest.spyOn(global, 'document', 'get')
74
+
75
+ jest.spyOn(console, 'warn').mockImplementationOnce(() => {})
76
+
77
+ windowSpy.mockImplementation(() => {
78
+ return jsd.window as unknown as Window & typeof globalThis
79
+ })
80
+
81
+ documentSpy.mockImplementation(
82
+ () => jsd.window.document as unknown as Document
83
+ )
84
+ })
85
+
86
+ it('loads AJS on execution', async () => {
87
+ await import('../standalone')
88
+
89
+ await pWhile(
90
+ () => getGlobalAnalytics()?.initialized !== true,
91
+ () => {}
92
+ )
93
+
94
+ expect(getGlobalAnalytics()).not.toBeUndefined()
95
+ expect(getGlobalAnalytics()?.initialized).toBe(true)
96
+ })
97
+ })
@@ -0,0 +1,150 @@
1
+ import { HtEventsBrowser, Analytics, Context, User, Group } from '../../..'
2
+ import { assertNotAny, assertIs } from '../../../test-helpers/type-assertions'
3
+
4
+ /**
5
+ * These are general typescript definition tests;
6
+ * They aren't meant to be run by anything but the typescript compiler.
7
+ */
8
+ export default {
9
+ 'HtEventsBrowser should return the correct type': () => {
10
+ const result = HtEventsBrowser.load({ writeKey: 'abc' })
11
+ assertNotAny(result)
12
+ assertIs<HtEventsBrowser>(result)
13
+ },
14
+ 'HtEventsBrowser should return the correct type if awaited on.': async () => {
15
+ const [analytics, context] = await HtEventsBrowser.load({
16
+ writeKey: 'foo',
17
+ })
18
+
19
+ assertNotAny(analytics)
20
+ assertIs<Analytics>(analytics)
21
+
22
+ assertNotAny(context)
23
+ assertIs<Context>(context)
24
+ },
25
+ 'Promise API should work': () => {
26
+ void HtEventsBrowser.load({ writeKey: 'foo' })
27
+ .then(([analytics, context]) => {
28
+ assertNotAny(analytics)
29
+ assertIs<Analytics>(analytics)
30
+
31
+ assertNotAny(context)
32
+ assertIs<Context>(context)
33
+ })
34
+ .then(() => {
35
+ return 'a String!' as const
36
+ })
37
+ .then((str) => {
38
+ assertNotAny(str)
39
+ assertIs<'a String!'>(str)
40
+ })
41
+ },
42
+ 'If catch is before "then" in the middleware chain, .then should take into account the catch clause':
43
+ () => {
44
+ void HtEventsBrowser.load({ writeKey: 'foo' })
45
+ .catch((err: string) => {
46
+ assertIs<string>(err)
47
+ return 123
48
+ })
49
+ .then((response) => {
50
+ assertNotAny(response)
51
+ assertIs<number | [Analytics, Context]>(response)
52
+ })
53
+ },
54
+
55
+ 'Group should have the correct type': () => {
56
+ const ajs = HtEventsBrowser.load({ writeKey: 'foo' })
57
+ {
58
+ const grpResult = ajs.group()
59
+ assertIs<Promise<Group>>(grpResult)
60
+ }
61
+ {
62
+ const grpResult = ajs.group('foo')
63
+ assertIs<Promise<Context>>(grpResult)
64
+ }
65
+ },
66
+ 'User should have the correct type': () => {
67
+ const ajs = HtEventsBrowser.load({ writeKey: 'foo' })
68
+ {
69
+ const grpResult = ajs.user()
70
+ assertIs<Promise<User>>(grpResult)
71
+ }
72
+ },
73
+ 'Identify should work with spread objects ': () => {
74
+ const user = {
75
+ name: 'john',
76
+ id: 'abc123',
77
+ }
78
+ const { id, ...traits } = user
79
+ void HtEventsBrowser.load({ writeKey: 'foo' }).identify('foo', traits)
80
+ },
81
+ 'Track should work with spread objects': () => {
82
+ const user = {
83
+ name: 'john',
84
+ id: 'abc123',
85
+ }
86
+ const { id, ...traits } = user
87
+ void HtEventsBrowser.load({ writeKey: 'foo' }).track('foo', traits)
88
+ },
89
+ 'Identify should work with generic objects ': () => {
90
+ const user = {
91
+ name: 'john',
92
+ id: 'abc123',
93
+ }
94
+ void HtEventsBrowser.load({ writeKey: 'foo' }).identify('foo', user)
95
+ },
96
+ 'Context should have a key allowing arbitrary properties': async () => {
97
+ const [_, ctx] = await HtEventsBrowser.load({ writeKey: 'foo' })
98
+ const properties = ctx.event.properties!
99
+
100
+ properties.category.baz = 'hello'
101
+ },
102
+ 'Track should allow undefined properties': () => {
103
+ type User = {
104
+ name?: string
105
+ thing: 123
106
+ }
107
+ void HtEventsBrowser.load({ writeKey: 'foo' }).track('foo', {} as User)
108
+ },
109
+ 'Lazy instantiation should be supported': () => {
110
+ const analytics = new HtEventsBrowser()
111
+ assertNotAny(analytics)
112
+ assertIs<HtEventsBrowser>(analytics)
113
+ analytics.load({ writeKey: 'foo' })
114
+ void analytics.track('foo')
115
+ },
116
+ '.load should return this': () => {
117
+ const analytics = new HtEventsBrowser().load({ writeKey: 'foo' })
118
+ assertNotAny(analytics)
119
+ assertIs<HtEventsBrowser>(analytics)
120
+ },
121
+
122
+ 'Should accept traits': () => {
123
+ const analytics = {} as HtEventsBrowser
124
+
125
+ class Foo {
126
+ name = 'hello'
127
+ toJSON() {
128
+ return this.name
129
+ }
130
+ }
131
+ void analytics.identify('foo', new Foo())
132
+ void analytics.identify('foo', { address: null })
133
+ // @ts-expect-error - Type 'string' has no properties in common with type
134
+ void analytics.identify('foo', { address: 'hello' })
135
+ // @ts-expect-error - Type 'never[]' is not assignable to type
136
+ void analytics.identify('foo', { id: [] })
137
+ },
138
+
139
+ 'Should accept optional ExtraContext': () => {
140
+ const analytics = {} as HtEventsBrowser
141
+ void analytics.track('foo', undefined, { context: {} })
142
+ void analytics.track('foo', undefined, { context: { active: true } })
143
+ void analytics.track('foo', undefined, {
144
+ context: {
145
+ // @ts-expect-error Type 'string' is not assignable to type 'boolean | null | undefined'.ts(2322)
146
+ active: 'hello',
147
+ },
148
+ })
149
+ },
150
+ }