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,922 @@
1
+ import assert from 'assert'
2
+ import jar from 'js-cookie'
3
+ import { Group, User } from '..'
4
+ import { LocalStorage, StoreType } from '../../storage'
5
+ import {
6
+ disableCookies,
7
+ disableLocalStorage,
8
+ } from '../../storage/__tests__/test-helpers'
9
+
10
+ function clear(): void {
11
+ document.cookie.split(';').forEach(function (c) {
12
+ document.cookie = c
13
+ .replace(/^ +/, '')
14
+ .replace(/=.*/, '=;expires=' + new Date().toUTCString() + ';path=/')
15
+ })
16
+ localStorage.clear()
17
+ }
18
+
19
+ /**
20
+ * Filters out the calls made for probing cookie availability
21
+ */
22
+ const ignoreProbeCookieWrites = (
23
+ fn: jest.SpyInstance<
24
+ string | undefined,
25
+ [
26
+ name: string,
27
+ value: string | object,
28
+ options?: jar.CookieAttributes | undefined
29
+ ]
30
+ >
31
+ ) => fn.mock.calls.filter((c) => c[0] !== 'ajs_cookies_check')
32
+
33
+ let store: LocalStorage
34
+ beforeEach(function () {
35
+ store = new LocalStorage()
36
+ clear()
37
+ // Restore any cookie, localstorage disable
38
+ jest.restoreAllMocks()
39
+ jest.spyOn(console, 'warn').mockImplementation(() => {}) // silence console spam.
40
+ })
41
+
42
+ describe('user', () => {
43
+ const cookieKey = User.defaults.cookie.key
44
+ const localStorageKey = User.defaults.localStorage.key
45
+
46
+ describe('()', () => {
47
+ it('should pick the old "_sio" anonymousId', () => {
48
+ jar.set('_sio', 'anonymous-id----user-id')
49
+ const user = new User()
50
+ expect(user.anonymousId()).toEqual('anonymous-id')
51
+ })
52
+
53
+ it('should not pick the old "_sio" if anonymous id is present', () => {
54
+ jar.set('_sio', 'old-anonymous-id----user-id')
55
+ jar.set('htjs_anonymous_id', 'new-anonymous-id')
56
+ assert(new User().anonymousId() === 'new-anonymous-id')
57
+ })
58
+
59
+ it('should create anonymous id if missing (persist: default (true))', () => {
60
+ const user = new User()
61
+ assert(user.anonymousId()?.length === 36)
62
+ expect(jar.get('htjs_anonymous_id')?.length).toBe(36)
63
+ expect(localStorage.getItem('htjs_anonymous_id')?.length).toBe(38)
64
+ })
65
+
66
+ it('should create anonymous id if missing (persist: false)', () => {
67
+ const setCookieSpy = jest.spyOn(jar, 'set')
68
+
69
+ const user = new User({ persist: false })
70
+ assert(user.anonymousId()?.length === 36)
71
+ expect(jar.get('htjs_anonymous_id')).toBeUndefined()
72
+ expect(localStorage.getItem('htjs_anonymous_id')).toBeNull()
73
+ expect(ignoreProbeCookieWrites(setCookieSpy).length).toBe(0)
74
+ })
75
+
76
+ it('should not overwrite anonymous id', () => {
77
+ jar.set('htjs_anonymous_id', 'anonymous')
78
+ expect(new User().anonymousId()).toEqual('anonymous')
79
+ })
80
+ })
81
+
82
+ describe('#id', () => {
83
+ let user: User
84
+
85
+ beforeEach(() => {
86
+ user = new User()
87
+ })
88
+
89
+ describe('when cookies are disabled', () => {
90
+ beforeEach(() => {
91
+ disableCookies()
92
+
93
+ user = new User()
94
+ clear()
95
+ })
96
+
97
+ it('should not reset id with new user', () => {
98
+ store.set(cookieKey, 'id')
99
+ user = new User()
100
+ assert(user.id() === 'id')
101
+ })
102
+
103
+ it('should get an id from the store', () => {
104
+ store.set(cookieKey, 'id')
105
+ assert(user.id() === 'id')
106
+ })
107
+
108
+ it('should set an id to the store', () => {
109
+ user.id('id')
110
+ assert(store.get(cookieKey) === 'id')
111
+ })
112
+
113
+ it('should set the id when not persisting', () => {
114
+ user = new User({ persist: false })
115
+ user.id('id')
116
+ assert(user.id() === 'id')
117
+ })
118
+
119
+ it('should be null by default', () => {
120
+ assert(user.id() === null)
121
+ })
122
+
123
+ it('should not reset anonymousId if the user didnt have previous id', () => {
124
+ const prev = user.anonymousId()
125
+
126
+ user.id('foo')
127
+ user.id('foo')
128
+ user.id('foo')
129
+
130
+ assert(user.anonymousId() === prev)
131
+ })
132
+
133
+ it('should reset anonymousId if the user id changed', () => {
134
+ user.anonymousId('bla')
135
+
136
+ const prev = user.anonymousId()
137
+ user.id('foo')
138
+ user.id('baz')
139
+
140
+ expect(user.anonymousId()).not.toEqual(prev)
141
+ expect(user.anonymousId()?.length).toBe(36)
142
+ })
143
+
144
+ it('should not reset anonymousId if the user id changed to null', () => {
145
+ const prev = user.anonymousId()
146
+ user.id('foo')
147
+ user.id(null)
148
+ assert(user.anonymousId() === prev)
149
+ assert(user.anonymousId()?.length === 36)
150
+ })
151
+ })
152
+
153
+ describe('when cookies and localStorage are disabled', () => {
154
+ beforeEach(() => {
155
+ disableCookies()
156
+ disableLocalStorage()
157
+
158
+ user = new User()
159
+ clear()
160
+ })
161
+
162
+ it('should get an id from memory', () => {
163
+ user.id('id')
164
+ assert(user.id() === 'id')
165
+ })
166
+
167
+ it('should get an id when not persisting', () => {
168
+ user = new User({ persist: false })
169
+ user.id('id')
170
+ assert(user.id() === 'id')
171
+ })
172
+
173
+ it('should not reset anonymousId if the user didnt have previous id', () => {
174
+ const prev = user.anonymousId()
175
+ user.id('foo')
176
+ user.id('foo')
177
+ user.id('foo')
178
+
179
+ assert(user.anonymousId() === prev)
180
+ })
181
+
182
+ it('should reset anonymousId if the user id changed', () => {
183
+ const prev = user.anonymousId()
184
+ user.id('foo')
185
+ user.id('baz')
186
+ assert(user.anonymousId() !== prev)
187
+ assert(user.anonymousId()?.length === 36)
188
+ })
189
+
190
+ it('should not reset anonymousId if the user id changed to null', () => {
191
+ const prev = user.anonymousId()
192
+ user.id('foo')
193
+ user.id(null)
194
+ assert(user.anonymousId() === prev)
195
+ assert(user.anonymousId()?.length === 36)
196
+ })
197
+ })
198
+
199
+ describe('when persist is disabled', () => {
200
+ let setCookieSpy: jest.SpyInstance
201
+ beforeEach(() => {
202
+ setCookieSpy = jest.spyOn(jar, 'set')
203
+ user = new User({ persist: false })
204
+ clear()
205
+ })
206
+
207
+ it('should get an id from memory', () => {
208
+ user.id('id')
209
+ assert(user.id() === 'id')
210
+ })
211
+
212
+ it('should be null by default', () => {
213
+ assert(user.id() === null)
214
+ })
215
+
216
+ it('should not reset anonymousId if the user didnt have previous id', () => {
217
+ const prev = user.anonymousId()
218
+ user.id('foo')
219
+ user.id('foo')
220
+ user.id('foo')
221
+
222
+ assert(user.anonymousId() === prev)
223
+ expect(ignoreProbeCookieWrites(setCookieSpy).length).toBe(0)
224
+ })
225
+
226
+ it('should reset anonymousId if the user id changed', () => {
227
+ const prev = user.anonymousId()
228
+ user.id('foo')
229
+ user.id('baz')
230
+ assert(user.anonymousId() !== prev)
231
+ assert(user.anonymousId()?.length === 36)
232
+ expect(ignoreProbeCookieWrites(setCookieSpy).length).toBe(0)
233
+ })
234
+
235
+ it('should not reset anonymousId if the user id changed to null', () => {
236
+ const prev = user.anonymousId()
237
+ user.id('foo')
238
+ user.id(null)
239
+ assert(user.anonymousId() === prev)
240
+ assert(user.anonymousId()?.length === 36)
241
+ expect(ignoreProbeCookieWrites(setCookieSpy).length).toBe(0)
242
+ })
243
+ })
244
+
245
+ describe('when disabled', () => {
246
+ beforeEach(() => {
247
+ user = new User({ disable: true })
248
+ })
249
+
250
+ it('should always be null', () => {
251
+ expect(user.id()).toBeNull()
252
+ expect(user.id('foo')).toBeNull()
253
+ expect(user.id()).toBeNull()
254
+ })
255
+ })
256
+
257
+ describe('when cookies are enabled', () => {
258
+ it('should get an id from the cookie', () => {
259
+ jar.set(cookieKey, 'id')
260
+ assert(user.id() === 'id')
261
+ })
262
+
263
+ it('should set an id to the cookie', () => {
264
+ user.id('id')
265
+ assert(jar.get(cookieKey) === 'id')
266
+ })
267
+
268
+ it('should get an id when not persisting', function () {
269
+ user = new User({ persist: false })
270
+ user.id('id')
271
+ assert(user.id() === 'id')
272
+ })
273
+
274
+ it('should be null by default', () => {
275
+ assert(user.id() === null)
276
+ })
277
+
278
+ it('should parse integer values', () => {
279
+ // @ts-expect-error the library only accepts strings or objects,
280
+ // but AJS Classic allows setting numbers on cookie values, so we have
281
+ // to parse them back to string.
282
+ jar.set(cookieKey, 1234)
283
+ assert(user.id() === '1234')
284
+ })
285
+
286
+ it('should not reset anonymousId if the user didnt have previous id', () => {
287
+ const prev = user.anonymousId()
288
+ user.id('foo')
289
+ user.id('foo')
290
+ user.id('foo')
291
+ assert(user.anonymousId() === prev)
292
+ })
293
+
294
+ it('should reset anonymousId if the user id changed', () => {
295
+ const prev = user.anonymousId()
296
+ user.id('foo')
297
+ user.id('baz')
298
+ assert(user.anonymousId() !== prev)
299
+ assert(user.anonymousId()?.length === 36)
300
+ })
301
+ })
302
+ })
303
+
304
+ describe('#anonymousId', () => {
305
+ let user: User
306
+
307
+ beforeEach(() => {
308
+ user = new User()
309
+ })
310
+
311
+ describe('when cookies are disabled', () => {
312
+ beforeEach(() => {
313
+ disableCookies()
314
+
315
+ user = new User()
316
+ })
317
+
318
+ it('should get an id from the store', () => {
319
+ store.set('htjs_anonymous_id', 'anon-id')
320
+ expect(user.anonymousId()).toEqual('anon-id')
321
+ })
322
+
323
+ it('should set an id to the store', () => {
324
+ user.anonymousId('anon-id')
325
+ assert(store.get('htjs_anonymous_id') === 'anon-id')
326
+ })
327
+
328
+ it('should return anonymousId using the store', () => {
329
+ user.anonymousId('anon-id')
330
+ assert(user.anonymousId() === 'anon-id')
331
+ })
332
+
333
+ it('should get an id without quotes from the store', () => {
334
+ window.localStorage.setItem('htjs_anonymous_id', 'abc-def')
335
+ assert(user.anonymousId() === 'abc-def')
336
+ })
337
+ })
338
+
339
+ describe('when cookies and localStorage are disabled', () => {
340
+ beforeEach(() => {
341
+ disableCookies()
342
+ disableLocalStorage()
343
+
344
+ user = new User()
345
+ })
346
+
347
+ it('should get an id from memory', () => {
348
+ user.anonymousId('anon-id')
349
+ assert(user.anonymousId() === 'anon-id')
350
+ })
351
+ })
352
+
353
+ describe('when cookies are enabled', () => {
354
+ it('should get an id from the cookie', () => {
355
+ jar.set('htjs_anonymous_id', 'anon-id')
356
+ assert(user.anonymousId() === 'anon-id')
357
+ })
358
+
359
+ it('should set an id to the cookie', () => {
360
+ user.anonymousId('anon-id')
361
+ assert(jar.get('htjs_anonymous_id') === 'anon-id')
362
+ })
363
+
364
+ it('should set anonymousId in both cookie and localStorage', () => {
365
+ user.anonymousId('anon0')
366
+ assert.equal(jar.get('htjs_anonymous_id'), 'anon0')
367
+ assert.equal(store.get('htjs_anonymous_id'), 'anon0')
368
+ })
369
+
370
+ it('should not set anonymousId in localStorage when localStorage fallback is disabled', () => {
371
+ user = new User({
372
+ localStorageFallbackDisabled: true,
373
+ })
374
+
375
+ user.anonymousId('anon0')
376
+ assert.equal(jar.get('htjs_anonymous_id'), 'anon0')
377
+ assert.equal(store.get('htjs_anonymous_id'), null)
378
+ })
379
+
380
+ it('should copy value from cookie to localStorage', () => {
381
+ user = new User()
382
+ jar.set('htjs_anonymous_id', 'anon1')
383
+
384
+ assert.equal(user.anonymousId(), 'anon1')
385
+ assert.equal(store.get('htjs_anonymous_id'), 'anon1')
386
+ })
387
+
388
+ it('should not copy value from cookie to localStorage when localStorage fallback is disabled', () => {
389
+ user = new User({
390
+ localStorageFallbackDisabled: true,
391
+ })
392
+ jar.set('htjs_anonymous_id', 'anon1')
393
+ assert.equal(user.anonymousId(), 'anon1')
394
+ assert.equal(store.get('htjs_anonymous_id'), null)
395
+ })
396
+
397
+ it('should fall back to localStorage when cookie is not set', () => {
398
+ user = new User()
399
+ user.anonymousId('anon12')
400
+ assert.equal(jar.get('htjs_anonymous_id'), 'anon12')
401
+
402
+ // delete the cookie
403
+ jar.remove('htjs_anonymous_id')
404
+ assert.equal(jar.get('htjs_anonymous_id'), null)
405
+
406
+ // verify anonymousId() returns the correct id even when there's no cookie
407
+ assert.equal(user.anonymousId(), 'anon12')
408
+
409
+ // verify cookie value is restored from localStorage
410
+ assert.equal(jar.get('htjs_anonymous_id'), 'anon12')
411
+ })
412
+
413
+ it('should write to both cookie and localStorage when generating a new anonymousId', () => {
414
+ user = new User()
415
+ user.anonymousId('bla')
416
+ const anonId = user.anonymousId()
417
+
418
+ assert.notEqual(anonId, null)
419
+ assert.equal(jar.get('htjs_anonymous_id'), anonId)
420
+ assert.equal(store.get('htjs_anonymous_id'), anonId)
421
+ })
422
+
423
+ it('should not write to both cookie and localStorage when generating a new anonymousId and localStorage fallback is disabled', () => {
424
+ user = new User({
425
+ localStorageFallbackDisabled: true,
426
+ })
427
+
428
+ user.anonymousId('bla')
429
+ const anonId = user.anonymousId()
430
+
431
+ assert.notEqual(anonId, null)
432
+ assert.equal(jar.get('htjs_anonymous_id'), anonId)
433
+ assert.equal(store.get('htjs_anonymous_id'), null)
434
+ })
435
+ })
436
+
437
+ describe('when disabled', () => {
438
+ beforeEach(() => {
439
+ user = new User({ disable: true })
440
+ })
441
+
442
+ it('should always be null', () => {
443
+ expect(user.anonymousId()).toBeNull()
444
+ expect(user.anonymousId('foo')).toBeNull()
445
+ expect(user.anonymousId()).toBeNull()
446
+ })
447
+ })
448
+ })
449
+
450
+ describe('#traits', () => {
451
+ let user: User
452
+
453
+ beforeEach(() => {
454
+ user = new User()
455
+ })
456
+
457
+ it('should get traits', () => {
458
+ store.set(localStorageKey, { trait: true })
459
+ expect(user.traits()).toEqual({ trait: true })
460
+ })
461
+
462
+ it('should get traits when not persisting', () => {
463
+ user = new User({ persist: false })
464
+ user.traits({ trait: true })
465
+ expect(user.traits()).toEqual({ trait: true })
466
+ expect(store.get(localStorageKey)).toBeNull()
467
+ })
468
+
469
+ it('should set traits', () => {
470
+ user.traits({ trait: true })
471
+ expect(store.get(localStorageKey)).toEqual({ trait: true })
472
+ })
473
+
474
+ it('should default traits to an empty object', () => {
475
+ user.traits(null)
476
+ expect(store.get(localStorageKey)).toEqual({})
477
+ })
478
+
479
+ it('should default traits to an empty object when not persisting', () => {
480
+ user = new User({ persist: false })
481
+ user.traits(null)
482
+ expect(user.traits()).toEqual({})
483
+ })
484
+
485
+ it('should be an empty object by default', () => {
486
+ expect(user.traits()).toEqual({})
487
+ })
488
+
489
+ it('should not reset traits on new user', () => {
490
+ user.traits({ trait: true })
491
+ user = new User()
492
+ expect(user.traits()).toEqual({ trait: true })
493
+ })
494
+
495
+ describe('when disabled', () => {
496
+ beforeEach(() => {
497
+ user = new User({ disable: true })
498
+ })
499
+
500
+ it('should always be undefined', () => {
501
+ expect(user.traits()).toBeUndefined()
502
+ expect(user.traits({})).toBeUndefined()
503
+ expect(user.traits()).toBeUndefined()
504
+ })
505
+ })
506
+ })
507
+
508
+ describe('#save', () => {
509
+ let user: User
510
+
511
+ beforeEach(() => {
512
+ user = new User()
513
+ })
514
+
515
+ it('should save an id to a cookie', () => {
516
+ user.id('id')
517
+ user.save()
518
+ expect(jar.get(cookieKey)).toEqual('id')
519
+ })
520
+
521
+ it('should save an id to localStorage', () => {
522
+ user.id('id')
523
+ user.save()
524
+ expect(store.get(cookieKey)).toEqual('id')
525
+ })
526
+
527
+ it('should not save an id to localStorage when localStorage fallback is disabled', () => {
528
+ user = new User({
529
+ localStorageFallbackDisabled: true,
530
+ })
531
+
532
+ user.id('id')
533
+ user.save()
534
+ expect(store.get(cookieKey)).toBeNull()
535
+ })
536
+
537
+ it('should not get id from localStorage when fallback is disabled and id() is called', () => {
538
+ user = new User({
539
+ localStorageFallbackDisabled: false,
540
+ })
541
+
542
+ user.id('id')
543
+ user.save()
544
+ jar.remove(cookieKey)
545
+
546
+ user = new User({
547
+ localStorageFallbackDisabled: true,
548
+ })
549
+
550
+ user.id('foo')
551
+ user.save()
552
+
553
+ expect(user.id()).toEqual('foo')
554
+ expect(store.get(cookieKey)).toEqual('id')
555
+ })
556
+
557
+ it('should save traits to local storage', () => {
558
+ user.traits({ trait: true })
559
+ user.save()
560
+ expect(store.get(localStorageKey)).toEqual({ trait: true })
561
+ })
562
+
563
+ it('shouldnt save if persist is false', () => {
564
+ user = new User({
565
+ persist: false,
566
+ })
567
+
568
+ user.id('id')
569
+ user.save()
570
+ expect(jar.get(cookieKey)).toBeUndefined()
571
+ })
572
+ })
573
+
574
+ describe('#logout', () => {
575
+ let user: User
576
+
577
+ beforeEach(() => {
578
+ user = new User()
579
+ })
580
+
581
+ it('should reset an id and traits', () => {
582
+ user.id('id')
583
+ user.anonymousId('anon-id')
584
+ user.traits({ trait: true })
585
+ user.logout()
586
+
587
+ expect(jar.get('htjs_anonymous_id')).toBeUndefined()
588
+ expect(user.id()).toBeNull()
589
+ expect(user.traits()).toEqual({})
590
+ })
591
+
592
+ it('should clear id in cookie', () => {
593
+ user.id('id')
594
+ user.save()
595
+ user.logout()
596
+
597
+ expect(jar.get(cookieKey)).toBeFalsy()
598
+ })
599
+
600
+ it('should clear id in local storage', () => {
601
+ user.id('id')
602
+ user.save()
603
+ user.logout()
604
+ expect(store.get(cookieKey)).toBeNull()
605
+ })
606
+
607
+ it('should clear traits in local storage', () => {
608
+ user.traits({ trait: true })
609
+ user.save()
610
+ user.logout()
611
+
612
+ expect(store.get(localStorageKey)).toEqual({})
613
+ })
614
+ })
615
+
616
+ describe('#identify', () => {
617
+ let user: User
618
+
619
+ beforeEach(() => {
620
+ user = new User()
621
+ })
622
+
623
+ it('should save an id', () => {
624
+ user.identify('id')
625
+ expect(user.id()).toEqual('id')
626
+ })
627
+
628
+ it('should save traits', () => {
629
+ user.identify(null, { trait: true })
630
+
631
+ expect(user.traits()).toEqual({ trait: true })
632
+ expect(store.get(localStorageKey)).toEqual({ trait: true })
633
+ })
634
+
635
+ it('should save an id and traits', () => {
636
+ user.identify('id', { trait: true })
637
+
638
+ expect(user.id()).toEqual('id')
639
+ expect(user.traits()).toEqual({ trait: true })
640
+
641
+ expect(jar.get(cookieKey)).toEqual('id')
642
+ expect(store.get(localStorageKey)).toEqual({ trait: true })
643
+ })
644
+
645
+ it('should extend existing traits', () => {
646
+ user.traits({ one: 1 })
647
+ user.identify('id', { two: 2 })
648
+
649
+ expect(user.traits()).toEqual({ one: 1, two: 2 })
650
+ expect(store.get(localStorageKey)).toEqual({ one: 1, two: 2 })
651
+ })
652
+
653
+ it('shouldnt extend existing traits for a new id', () => {
654
+ user.id('id')
655
+ user.traits({ one: 1 })
656
+ user.identify('new', { two: 2 })
657
+
658
+ expect(user.traits()).toEqual({ two: 2 })
659
+ expect(store.get(localStorageKey)).toEqual({ two: 2 })
660
+ })
661
+
662
+ it('should reset traits for a new id', () => {
663
+ user.id('id')
664
+ user.traits({ one: 1 })
665
+ user.identify('new')
666
+
667
+ expect(user.traits()).toEqual({})
668
+ expect(store.get(localStorageKey)).toEqual({})
669
+ })
670
+ })
671
+
672
+ describe('#load', () => {
673
+ let user: User
674
+
675
+ beforeEach(() => {
676
+ user = new User()
677
+ })
678
+
679
+ it('should load an empty user', () => {
680
+ user.load()
681
+
682
+ expect(user.id()).toBe(null)
683
+ expect(user.traits()).toEqual({})
684
+ })
685
+
686
+ it('should load an id from a cookie', () => {
687
+ jar.set(cookieKey, 'le id')
688
+ user.load()
689
+ expect(user.id()).toEqual('le id')
690
+ })
691
+
692
+ it('should load traits from local storage', () => {
693
+ store.set(localStorageKey, { trait: true })
694
+ user.load()
695
+ expect(user.traits()).toEqual({ trait: true })
696
+ })
697
+
698
+ it('should load from an old cookie', () => {
699
+ jar.set(
700
+ User.defaults.cookie.oldKey,
701
+ JSON.stringify({
702
+ id: 'old',
703
+ traits: { trait: true },
704
+ })
705
+ )
706
+
707
+ user.load()
708
+ expect(user.id()).toEqual('old')
709
+ expect(user.traits()).toEqual({ trait: true })
710
+ })
711
+
712
+ it('load should preserve the original User cookie options', () => {
713
+ user = new User(undefined, {
714
+ domain: 'foo.com',
715
+ })
716
+ const setCookieSpy = jest.spyOn(jar, 'set')
717
+ user.load().anonymousId('anon-id')
718
+
719
+ expect(setCookieSpy).toHaveBeenLastCalledWith(
720
+ 'htjs_anonymous_id',
721
+ 'anon-id',
722
+ {
723
+ domain: 'foo.com',
724
+ expires: 365,
725
+ path: '/',
726
+ sameSite: 'Lax',
727
+ secure: undefined,
728
+ }
729
+ )
730
+ })
731
+ })
732
+
733
+ describe('storage', () => {
734
+ it('allows custom storage priority', () => {
735
+ const expected = 'CookieValue'
736
+ // Set a cookie first
737
+ jar.set('htjs_anonymous_id', expected)
738
+ store.set('htjs_anonymous_id', 'localStorageValue')
739
+ const user = new User({
740
+ storage: {
741
+ stores: [StoreType.Cookie, StoreType.LocalStorage, StoreType.Memory],
742
+ },
743
+ })
744
+ expect(user.anonymousId()).toEqual(expected)
745
+ })
746
+
747
+ it('custom storage priority respects availability', () => {
748
+ const expected = 'localStorageValue'
749
+ // Set a cookie first
750
+ jar.set('htjs_anonymous_id', 'CookieValue')
751
+ disableCookies()
752
+ store.set('htjs_anonymous_id', expected)
753
+ const user = new User({
754
+ storage: {
755
+ stores: [StoreType.Cookie, StoreType.LocalStorage, StoreType.Memory],
756
+ },
757
+ })
758
+ expect(user.anonymousId()).toEqual(expected)
759
+ })
760
+
761
+ it('persist option overrides any custom storage', () => {
762
+ const setCookieSpy = jest.spyOn(jar, 'set')
763
+ const user = new User({
764
+ storage: {
765
+ stores: [StoreType.Cookie, StoreType.LocalStorage, StoreType.Memory],
766
+ },
767
+ persist: false,
768
+ })
769
+ user.id('id')
770
+
771
+ expect(user.id()).toBe('id')
772
+ expect(jar.get('htjs_user_id')).toBeFalsy()
773
+ expect(store.get('htjs_user_id')).toBeFalsy()
774
+ expect(setCookieSpy.mock.calls.length).toBe(0)
775
+ })
776
+
777
+ it('disable option overrides any custom storage', () => {
778
+ const setCookieSpy = jest.spyOn(jar, 'set')
779
+ const user = new User({
780
+ storage: {
781
+ stores: [StoreType.Cookie, StoreType.LocalStorage, StoreType.Memory],
782
+ },
783
+ disable: true,
784
+ })
785
+ user.id('id')
786
+
787
+ expect(user.id()).toBe(null)
788
+ expect(jar.get('htjs_user_id')).toBeFalsy()
789
+ expect(store.get('htjs_user_id')).toBeFalsy()
790
+ expect(setCookieSpy.mock.calls.length).toBe(0)
791
+ })
792
+ })
793
+ })
794
+
795
+ describe('group', () => {
796
+ it('should not reset id and traits', () => {
797
+ let group = new Group()
798
+ group.id('gid')
799
+ group.traits({ trait: true })
800
+ group = new Group()
801
+ expect(group.id()).toBe('gid')
802
+ expect(group.traits()!.trait).toBe(true)
803
+ })
804
+
805
+ it('id() should fallback to localStorage', function () {
806
+ const group = new Group()
807
+
808
+ group.id('gid')
809
+
810
+ jar.remove('htjs_group_id')
811
+
812
+ assert.equal(jar.get('htjs_group_id'), null)
813
+ assert.equal(group.id(), 'gid')
814
+ assert.equal(store.get('htjs_group_id'), 'gid')
815
+ })
816
+
817
+ it('id() should not persist when persist disabled', () => {
818
+ const setCookieSpy = jest.spyOn(jar, 'set')
819
+
820
+ const group = new Group({ persist: false })
821
+ group.id('gid')
822
+
823
+ expect(group.id()).toBe('gid')
824
+ expect(jar.get('htjs_group_id')).toBeFalsy()
825
+ expect(store.get('htjs_group_id')).toBeFalsy()
826
+ expect(ignoreProbeCookieWrites(setCookieSpy).length).toBe(0)
827
+ })
828
+
829
+ it('behaves the same as user', () => {
830
+ const user = new User()
831
+ const group = new Group()
832
+
833
+ user.id('uid')
834
+ group.id('gid')
835
+
836
+ expect(user.id()).toEqual('uid')
837
+ expect(group.id()).toEqual('gid')
838
+ })
839
+
840
+ it('always ignores anonymous ids', () => {
841
+ const group = new Group()
842
+ expect(group.anonymousId()).toBeUndefined()
843
+
844
+ group.anonymousId('bla')
845
+ expect(group.anonymousId()).toBeUndefined()
846
+ })
847
+
848
+ it('uses a different cookie from user', () => {
849
+ const group = new Group()
850
+ group.id('gid')
851
+
852
+ expect(jar.get(group.options.cookie?.key ?? '')).toEqual('gid')
853
+ expect(jar.get(User.defaults.cookie.key)).not.toEqual('gid')
854
+ })
855
+
856
+ it('uses a different local storage key', () => {
857
+ const group = new Group()
858
+ group.identify('gid', { coolkids: true })
859
+
860
+ expect(store.get(group.options.localStorage?.key ?? '')).toEqual({
861
+ coolkids: true,
862
+ })
863
+ expect(store.get(User.defaults.localStorage.key)).not.toEqual({
864
+ coolkids: true,
865
+ })
866
+ })
867
+
868
+ describe('when disabled', () => {
869
+ let group: Group
870
+ beforeEach(() => {
871
+ group = new Group({ disable: true })
872
+ })
873
+
874
+ it('id should always be null', () => {
875
+ expect(group.id()).toBeNull()
876
+ expect(group.id('foo')).toBeNull()
877
+ expect(group.id()).toBeNull()
878
+ })
879
+
880
+ it('traits should always be undefined', () => {
881
+ expect(group.traits()).toBeUndefined()
882
+ expect(group.traits({})).toBeUndefined()
883
+ expect(group.traits()).toBeUndefined()
884
+ })
885
+ })
886
+
887
+ describe('#options', () => {
888
+ it('should set options with defaults', function () {
889
+ const group = new Group()
890
+ expect(group.options).toEqual({
891
+ persist: true,
892
+ cookie: {
893
+ key: 'htjs_group_id',
894
+ },
895
+ localStorage: {
896
+ key: 'htjs_group_properties',
897
+ },
898
+ sessions: {
899
+ autoTrack: true,
900
+ },
901
+ })
902
+ })
903
+ })
904
+ })
905
+
906
+ describe('Custom cookie params', () => {
907
+ it('allows for overriding keys', () => {
908
+ const customUser = new User(
909
+ {},
910
+ {
911
+ maxage: 200,
912
+ path: '/',
913
+ sameSite: 'Lax',
914
+ }
915
+ )
916
+ customUser.identify('some_id', { trait: true })
917
+
918
+ expect(document.cookie).toMatchInlineSnapshot(`"; htjs_user_id=some_id"`)
919
+ expect(customUser.id()).toBe('some_id')
920
+ expect(customUser.traits()).toEqual({ trait: true })
921
+ })
922
+ })