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,151 @@
1
+ import * as ConsentTools from '@ht-sdks/events-sdk-js-consent-tools'
2
+ import * as OneTrustAPI from '../../lib/onetrust-api'
3
+ import { sleep } from '@internal/test-helpers'
4
+ import { withOneTrust } from '../wrapper'
5
+ import { OneTrustMockGlobal, analyticsMock } from '../../test-helpers/mocks'
6
+
7
+ const throwNotImplemented = (): never => {
8
+ throw new Error('not implemented')
9
+ }
10
+
11
+ const grpFixture = {
12
+ StrictlyNeccessary: {
13
+ CustomGroupId: 'C0001',
14
+ },
15
+ Targeting: {
16
+ CustomGroupId: 'C0004',
17
+ },
18
+ Performance: {
19
+ CustomGroupId: 'C0005',
20
+ },
21
+ }
22
+
23
+ const getConsentedGroupIdsSpy = jest
24
+ .spyOn(OneTrustAPI, 'getConsentedGroupIds')
25
+ .mockImplementationOnce(throwNotImplemented)
26
+
27
+ const createWrapperSpyHelper = {
28
+ _spy: jest.spyOn(ConsentTools, 'createWrapper'),
29
+ get shouldLoad() {
30
+ return createWrapperSpyHelper._spy.mock.lastCall[0].shouldLoad!
31
+ },
32
+ get getCategories() {
33
+ return createWrapperSpyHelper._spy.mock.lastCall[0].getCategories!
34
+ },
35
+ get registerOnConsentChanged() {
36
+ return createWrapperSpyHelper._spy.mock.lastCall[0]
37
+ .registerOnConsentChanged!
38
+ },
39
+ }
40
+
41
+ /**
42
+ * These tests are not meant to be comprehensive, but they should cover the most important cases.
43
+ * We should prefer unit tests for most functionality (see lib/__tests__)
44
+ */
45
+ describe('High level "integration" tests', () => {
46
+ let resolveResolveWhen = () => {}
47
+ beforeEach(() => {
48
+ jest
49
+ .spyOn(OneTrustAPI, 'getOneTrustGlobal')
50
+ .mockImplementation(() => OneTrustMockGlobal)
51
+ getConsentedGroupIdsSpy.mockReset()
52
+ Object.values(OneTrustMockGlobal).forEach((fn) => fn.mockReset())
53
+ /**
54
+ * Typically, resolveWhen triggers when a predicate is true. We can manually 'check' so we don't have to use timeouts.
55
+ */
56
+ jest.spyOn(ConsentTools, 'resolveWhen').mockImplementation(async (fn) => {
57
+ return new Promise((_resolve) => {
58
+ resolveResolveWhen = () => {
59
+ if (fn()) {
60
+ _resolve()
61
+ } else {
62
+ throw new Error('Refuse to resolve, resolveWhen condition is false')
63
+ }
64
+ }
65
+ })
66
+ })
67
+ })
68
+
69
+ describe('shouldLoad', () => {
70
+ it('should be resolved successfully', async () => {
71
+ withOneTrust(analyticsMock)
72
+ OneTrustMockGlobal.GetDomainData.mockReturnValueOnce({
73
+ Groups: [grpFixture.StrictlyNeccessary, grpFixture.Performance],
74
+ })
75
+ getConsentedGroupIdsSpy.mockImplementation(() => [
76
+ grpFixture.StrictlyNeccessary.CustomGroupId,
77
+ ])
78
+ const shouldLoadP = Promise.resolve(
79
+ createWrapperSpyHelper.shouldLoad({} as any)
80
+ )
81
+ let shouldLoadResolved = false
82
+ void shouldLoadP.then(() => (shouldLoadResolved = true))
83
+ await sleep(0)
84
+ expect(shouldLoadResolved).toBe(false)
85
+ OneTrustMockGlobal.IsAlertBoxClosed.mockReturnValueOnce(true)
86
+ resolveResolveWhen()
87
+ const result = await shouldLoadP
88
+ expect(result).toBe(undefined)
89
+ })
90
+ })
91
+
92
+ describe('getCategories', () => {
93
+ it('should get categories successfully', async () => {
94
+ withOneTrust(analyticsMock)
95
+ OneTrustMockGlobal.GetDomainData.mockReturnValue({
96
+ Groups: [
97
+ grpFixture.StrictlyNeccessary,
98
+ grpFixture.Performance,
99
+ grpFixture.Targeting,
100
+ ],
101
+ })
102
+ getConsentedGroupIdsSpy.mockImplementation(() => [
103
+ grpFixture.StrictlyNeccessary.CustomGroupId,
104
+ ])
105
+ const categories = createWrapperSpyHelper.getCategories()
106
+ // contain both consented and denied category
107
+ expect(categories).toEqual({
108
+ C0001: true,
109
+ C0004: false,
110
+ C0005: false,
111
+ })
112
+ })
113
+ })
114
+
115
+ describe('Consent changed', () => {
116
+ it('should enable consent changed by default', async () => {
117
+ withOneTrust(analyticsMock)
118
+ OneTrustMockGlobal.GetDomainData.mockReturnValue({
119
+ Groups: [
120
+ grpFixture.StrictlyNeccessary,
121
+ grpFixture.Performance,
122
+ grpFixture.Targeting,
123
+ ],
124
+ })
125
+ const onCategoriesChangedCb = jest.fn()
126
+
127
+ createWrapperSpyHelper.registerOnConsentChanged(onCategoriesChangedCb)
128
+ onCategoriesChangedCb()
129
+
130
+ resolveResolveWhen() // wait for OneTrust global to be available
131
+ await sleep(0)
132
+
133
+ const onConsentChangedArg =
134
+ OneTrustMockGlobal.OnConsentChanged.mock.lastCall[0]
135
+ onConsentChangedArg(
136
+ new CustomEvent('', {
137
+ detail: [
138
+ grpFixture.StrictlyNeccessary.CustomGroupId,
139
+ grpFixture.Performance.CustomGroupId,
140
+ ],
141
+ })
142
+ )
143
+ // expect to be normalized!
144
+ expect(onCategoriesChangedCb.mock.lastCall[0]).toEqual({
145
+ [grpFixture.StrictlyNeccessary.CustomGroupId]: true,
146
+ [grpFixture.Performance.CustomGroupId]: true,
147
+ [grpFixture.Targeting.CustomGroupId]: false,
148
+ })
149
+ })
150
+ })
151
+ })
@@ -0,0 +1,61 @@
1
+ import {
2
+ AnyAnalytics,
3
+ createWrapper,
4
+ CreateWrapperSettings,
5
+ RegisterOnConsentChangedFunction,
6
+ resolveWhen,
7
+ } from '@ht-sdks/events-sdk-js-consent-tools'
8
+
9
+ import {
10
+ getNormalizedCategoriesFromGroupData,
11
+ getNormalizedCategoriesFromGroupIds,
12
+ getConsentedGroupIds,
13
+ getOneTrustGlobal,
14
+ } from '../lib/onetrust-api'
15
+
16
+ export interface OneTrustSettings {
17
+ integrationCategoryMappings?: CreateWrapperSettings['integrationCategoryMappings']
18
+ disableConsentChangedEvent?: boolean
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @param analyticsInstance - An analytics instance. Either `window.htevents`, or the instance returned by `new HtEventsBrowser()` or `HtEventsBrowser.load({...})`
24
+ * @param settings - Optional settings for configuring your OneTrust wrapper
25
+ */
26
+ export const withOneTrust = <Analytics extends AnyAnalytics>(
27
+ analyticsInstance: Analytics,
28
+ settings: OneTrustSettings = {}
29
+ ): Analytics => {
30
+ const registerOnConsentChanged: RegisterOnConsentChangedFunction = async (
31
+ onCategoriesChangedCb
32
+ ) => {
33
+ await resolveWhen(() => getOneTrustGlobal() !== undefined, 500)
34
+ getOneTrustGlobal()!.OnConsentChanged((event) => {
35
+ const normalizedCategories = getNormalizedCategoriesFromGroupIds(
36
+ event.detail
37
+ )
38
+ onCategoriesChangedCb(normalizedCategories)
39
+ })
40
+ }
41
+ return createWrapper<Analytics>({
42
+ shouldLoad: async () => {
43
+ await resolveWhen(() => {
44
+ const oneTrustGlobal = getOneTrustGlobal()
45
+ return (
46
+ oneTrustGlobal !== undefined &&
47
+ Boolean(getConsentedGroupIds().length) &&
48
+ oneTrustGlobal.IsAlertBoxClosed()
49
+ )
50
+ }, 500)
51
+ },
52
+ getCategories: () => {
53
+ const results = getNormalizedCategoriesFromGroupData()
54
+ return results
55
+ },
56
+ registerOnConsentChanged: settings.disableConsentChangedEvent
57
+ ? undefined
58
+ : registerOnConsentChanged,
59
+ integrationCategoryMappings: settings.integrationCategoryMappings,
60
+ })(analyticsInstance)
61
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * This is the public API for this package.
3
+ * We avoid using splat (*) exports so that we can control what is exposed.
4
+ */
5
+ export { withOneTrust } from './domain/wrapper'
6
+ export type { OneTrustSettings } from './domain/wrapper'
@@ -0,0 +1,11 @@
1
+ /**
2
+ * This file is meant to be used to create a webpack bundle.
3
+ */
4
+ import { withOneTrust } from './index'
5
+ export { withOneTrust }
6
+
7
+ // this will almost certainly be executed in the browser, but since this is UMD,
8
+ // we are checking just for the sake of being thorough
9
+ if (typeof window !== 'undefined') {
10
+ ;(window as any).withOneTrust = withOneTrust
11
+ }
@@ -0,0 +1,181 @@
1
+ import '../../test-helpers/onetrust-globals.d.ts'
2
+
3
+ import {
4
+ getConsentedGroupIds,
5
+ getGroupDataFromGroupIds,
6
+ getNormalizedCategoriesFromGroupData,
7
+ getOneTrustActiveGroups,
8
+ getNormalizedCategoriesFromGroupIds,
9
+ getOneTrustGlobal,
10
+ getAllGroups,
11
+ } from '../onetrust-api'
12
+ import { OneTrustMockGlobal } from '../../test-helpers/mocks'
13
+ import { OneTrustApiValidationError } from '../validation'
14
+
15
+ beforeEach(() => {
16
+ // @ts-ignore
17
+ delete window.OneTrustActiveGroups
18
+ // @ts-ignore
19
+ delete window.OneTrust
20
+ })
21
+
22
+ describe(getOneTrustGlobal, () => {
23
+ it('should get the global', () => {
24
+ ;(window as any).OneTrust = OneTrustMockGlobal
25
+ expect(getOneTrustGlobal()).toEqual(OneTrustMockGlobal)
26
+ })
27
+
28
+ it('should throw an error if the global is missing fields', () => {
29
+ ;(window as any).OneTrust = {}
30
+ expect(() => getOneTrustGlobal()).toThrow(OneTrustApiValidationError)
31
+ })
32
+ })
33
+
34
+ describe(getAllGroups, () => {
35
+ it('works if OneTrust global is not available', () => {
36
+ ;(window as any).OneTrust = undefined
37
+ expect(getAllGroups()).toEqual([])
38
+ })
39
+ it('get the normalized groups', () => {
40
+ ;(window as any).OneTrust = OneTrustMockGlobal
41
+ window.OneTrust = {
42
+ ...OneTrustMockGlobal,
43
+ GetDomainData: () => ({
44
+ Groups: [
45
+ {
46
+ CustomGroupId: 'C0001',
47
+ },
48
+ {
49
+ CustomGroupId: 'C0004',
50
+ },
51
+ {
52
+ CustomGroupId: ' C0005',
53
+ },
54
+ {
55
+ CustomGroupId: 'C0006 ',
56
+ },
57
+ ],
58
+ }),
59
+ }
60
+ expect(getAllGroups()).toEqual([
61
+ { groupId: 'C0001' },
62
+ { groupId: 'C0004' },
63
+ { groupId: 'C0005' },
64
+ { groupId: 'C0006' },
65
+ ])
66
+ })
67
+ })
68
+
69
+ describe(getNormalizedCategoriesFromGroupData, () => {
70
+ it('should return a set of groups', () => {
71
+ expect(
72
+ getNormalizedCategoriesFromGroupData({
73
+ userSetConsentGroups: [{ groupId: 'C0003' }],
74
+ userDeniedConsentGroups: [{ groupId: 'C0001' }, { groupId: 'C0002' }],
75
+ })
76
+ ).toEqual({ C0003: true, C0001: false, C0002: false })
77
+ })
78
+ })
79
+
80
+ describe(getOneTrustActiveGroups, () => {
81
+ it('should return the global string', () => {
82
+ window.OnetrustActiveGroups = 'hello'
83
+ expect(getOneTrustActiveGroups()).toBe('hello')
84
+ })
85
+ it('should return undefined if no groups are defined', () => {
86
+ // @ts-ignore
87
+ window.OnetrustActiveGroups = undefined
88
+ expect(getOneTrustActiveGroups()).toBe(undefined)
89
+
90
+ // @ts-ignore
91
+ window.OnetrustActiveGroups = null
92
+ expect(getOneTrustActiveGroups()).toBe(undefined)
93
+
94
+ window.OnetrustActiveGroups = ''
95
+ expect(getOneTrustActiveGroups()).toBe(undefined)
96
+ })
97
+
98
+ it('should throw an error if OneTrustActiveGroups is invalid', () => {
99
+ // @ts-ignore
100
+ window.OnetrustActiveGroups = []
101
+ expect(() => getOneTrustActiveGroups()).toThrow(OneTrustApiValidationError)
102
+ })
103
+ })
104
+
105
+ describe(getConsentedGroupIds, () => {
106
+ it('should normalize groupIds', () => {
107
+ expect(getConsentedGroupIds(',C0001,')).toEqual(['C0001'])
108
+ expect(getConsentedGroupIds('C0001,C0004')).toEqual(['C0001', 'C0004'])
109
+ expect(getConsentedGroupIds(',C0001,C0004')).toEqual(['C0001', 'C0004'])
110
+ expect(getConsentedGroupIds(',')).toEqual([])
111
+ expect(getConsentedGroupIds('')).toEqual([])
112
+ expect(getConsentedGroupIds(',,')).toEqual([])
113
+ })
114
+
115
+ it('should return an empty array if no groups are defined', () => {
116
+ // @ts-ignore
117
+ window.OnetrustActiveGroups = undefined
118
+ expect(getConsentedGroupIds()).toEqual([])
119
+ })
120
+ })
121
+
122
+ describe(getGroupDataFromGroupIds, () => {
123
+ it('should partition groups into consent/deny', () => {
124
+ window.OnetrustActiveGroups = ',C0001,C0004'
125
+ window.OneTrust = {
126
+ ...OneTrustMockGlobal,
127
+ GetDomainData: () => ({
128
+ Groups: [
129
+ {
130
+ CustomGroupId: 'C0001',
131
+ },
132
+ {
133
+ CustomGroupId: 'C0004',
134
+ },
135
+ {
136
+ CustomGroupId: 'SOME_OTHER_GROUP',
137
+ },
138
+ ],
139
+ }),
140
+ }
141
+ const data = getGroupDataFromGroupIds()
142
+
143
+ expect(data.userSetConsentGroups).toEqual([
144
+ {
145
+ groupId: 'C0001',
146
+ },
147
+ {
148
+ groupId: 'C0004',
149
+ },
150
+ ])
151
+
152
+ expect(data.userDeniedConsentGroups).toEqual([
153
+ {
154
+ groupId: 'SOME_OTHER_GROUP',
155
+ },
156
+ ])
157
+ })
158
+ })
159
+
160
+ describe(getNormalizedCategoriesFromGroupIds, () => {
161
+ it('should get normalized categories', () => {
162
+ window.OneTrust = {
163
+ ...OneTrustMockGlobal,
164
+ GetDomainData: () => ({
165
+ Groups: [
166
+ {
167
+ CustomGroupId: 'C0001',
168
+ },
169
+ {
170
+ CustomGroupId: 'C0004',
171
+ },
172
+ {
173
+ CustomGroupId: 'SOME_OTHER_GROUP',
174
+ },
175
+ ],
176
+ }),
177
+ }
178
+ const ids = getNormalizedCategoriesFromGroupIds(['C0001'])
179
+ expect(ids).toEqual({ C0001: true, C0004: false, SOME_OTHER_GROUP: false })
180
+ })
181
+ })
@@ -0,0 +1,155 @@
1
+ import { Categories } from '@ht-sdks/events-sdk-js-consent-tools'
2
+ import { OneTrustApiValidationError } from './validation'
3
+ /**
4
+ * @example ["C0001", "C0002"]
5
+ */
6
+ type ConsentGroupIds = string[]
7
+
8
+ /**
9
+ * @example
10
+ * ",C0001,C0002" => ["C0001", "C0002"]
11
+ */
12
+ const normalizeActiveGroupIds = (
13
+ oneTrustActiveGroups: string
14
+ ): ConsentGroupIds => {
15
+ return oneTrustActiveGroups.trim().split(',').filter(Boolean)
16
+ }
17
+
18
+ type GroupInfoDto = {
19
+ CustomGroupId: string
20
+ }
21
+
22
+ type OtConsentChangedEvent = CustomEvent<ConsentGroupIds>
23
+
24
+ /**
25
+ * The data model used by the OneTrust lib
26
+ */
27
+ export interface OneTrustGlobal {
28
+ GetDomainData: () => {
29
+ Groups: GroupInfoDto[]
30
+ }
31
+ /**
32
+ * This callback appears to fire whenever the alert box is closed, no matter what.
33
+ * E.g:
34
+ * - if a user continues without accepting
35
+ * - if a user makes a selection
36
+ * - if a user rejects all
37
+ */
38
+ OnConsentChanged: (cb: (event: OtConsentChangedEvent) => void) => void
39
+ IsAlertBoxClosed: () => boolean
40
+ }
41
+
42
+ export const getOneTrustGlobal = (): OneTrustGlobal | undefined => {
43
+ const oneTrust = (window as any).OneTrust
44
+ if (!oneTrust) return undefined
45
+ if (
46
+ typeof oneTrust === 'object' &&
47
+ 'OnConsentChanged' in oneTrust &&
48
+ 'IsAlertBoxClosed' in oneTrust &&
49
+ 'GetDomainData' in oneTrust
50
+ ) {
51
+ return oneTrust
52
+ }
53
+
54
+ throw new OneTrustApiValidationError(
55
+ 'window.OneTrust is not in expected format',
56
+ oneTrust
57
+ )
58
+ }
59
+
60
+ export const getOneTrustActiveGroups = (): string | undefined => {
61
+ const groups = (window as any).OnetrustActiveGroups
62
+ if (!groups) return undefined
63
+ if (typeof groups !== 'string') {
64
+ throw new OneTrustApiValidationError(
65
+ `window.OnetrustActiveGroups is not a string`,
66
+ groups
67
+ )
68
+ }
69
+ return groups
70
+ }
71
+
72
+ export const getConsentedGroupIds = (
73
+ groups = getOneTrustActiveGroups()
74
+ ): ConsentGroupIds => {
75
+ if (!groups) {
76
+ return []
77
+ }
78
+ return normalizeActiveGroupIds(groups || '')
79
+ }
80
+
81
+ export type GroupInfo = {
82
+ groupId: string
83
+ }
84
+
85
+ const normalizeGroupInfo = (groupInfo: GroupInfoDto): GroupInfo => ({
86
+ groupId: groupInfo.CustomGroupId.trim(),
87
+ })
88
+
89
+ /**
90
+ * get *all* groups / categories, not just active ones
91
+ */
92
+ export const getAllGroups = (): GroupInfo[] => {
93
+ const oneTrustGlobal = getOneTrustGlobal()
94
+ if (!oneTrustGlobal) return []
95
+ return oneTrustGlobal.GetDomainData().Groups.map(normalizeGroupInfo)
96
+ }
97
+
98
+ type UserConsentGroupData = {
99
+ userSetConsentGroups: GroupInfo[]
100
+ userDeniedConsentGroups: GroupInfo[]
101
+ }
102
+
103
+ // derive the groupIds from the active groups
104
+ export const getGroupDataFromGroupIds = (
105
+ userSetConsentGroupIds = getConsentedGroupIds()
106
+ ): UserConsentGroupData => {
107
+ // partition all groups into "consent" or "deny"
108
+ const userConsentGroupData = getAllGroups().reduce<UserConsentGroupData>(
109
+ (acc, group) => {
110
+ if (userSetConsentGroupIds.includes(group.groupId)) {
111
+ acc.userSetConsentGroups.push(group)
112
+ } else {
113
+ acc.userDeniedConsentGroups.push(group)
114
+ }
115
+ return acc
116
+ },
117
+ { userSetConsentGroups: [], userDeniedConsentGroups: [] }
118
+ )
119
+
120
+ return userConsentGroupData
121
+ }
122
+
123
+ export const getNormalizedCategoriesFromGroupData = (
124
+ groupData = getGroupDataFromGroupIds()
125
+ ): Categories => {
126
+ const { userSetConsentGroups, userDeniedConsentGroups } = groupData
127
+ const consentedCategories = userSetConsentGroups.reduce<Categories>(
128
+ (acc, c) => {
129
+ return {
130
+ ...acc,
131
+ [c.groupId]: true,
132
+ }
133
+ },
134
+ {}
135
+ )
136
+
137
+ const deniedCategories = userDeniedConsentGroups.reduce<Categories>(
138
+ (acc, c) => {
139
+ return {
140
+ ...acc,
141
+ [c.groupId]: false,
142
+ }
143
+ },
144
+ {}
145
+ )
146
+ return { ...consentedCategories, ...deniedCategories }
147
+ }
148
+
149
+ export const getNormalizedCategoriesFromGroupIds = (
150
+ groupIds: ConsentGroupIds
151
+ ): Categories => {
152
+ return getNormalizedCategoriesFromGroupData(
153
+ getGroupDataFromGroupIds(groupIds)
154
+ )
155
+ }
@@ -0,0 +1 @@
1
+ export * from './onetrust-api-error'
@@ -0,0 +1,11 @@
1
+ /**
2
+ * An Errot that represents that the OneTrust API is not in the expected format.
3
+ * This is not something that could happen unless our API types are wrong and something is very wonky.
4
+ * Not a recoverable error.
5
+ */
6
+ export class OneTrustApiValidationError extends Error {
7
+ name = 'OtConsentWrapperValidationError'
8
+ constructor(message: string, received: any) {
9
+ super(`Invariant: ${message} (Received: ${JSON.stringify(received)})`)
10
+ }
11
+ }
@@ -0,0 +1,23 @@
1
+ import { OneTrustGlobal } from '../lib/onetrust-api'
2
+ import { throwNotImplemented } from './utils'
3
+ import type { AnyAnalytics } from '@ht-sdks/events-sdk-js-consent-tools'
4
+ /**
5
+ * This can be used to mock the OneTrust global object in individual tests
6
+ * @example
7
+ * ```ts
8
+ * import * as OneTrustAPI from '../onetrust-api'
9
+ * jest.spyOn(OneTrustAPI, 'getOneTrustGlobal').mockImplementation(() => OneTrustMockGlobal)
10
+ * ````
11
+ */
12
+ export const OneTrustMockGlobal: jest.Mocked<OneTrustGlobal> = {
13
+ GetDomainData: jest.fn().mockImplementation(throwNotImplemented),
14
+ IsAlertBoxClosed: jest.fn().mockImplementation(throwNotImplemented),
15
+ OnConsentChanged: jest.fn().mockImplementation(throwNotImplemented), // not implemented atm
16
+ }
17
+
18
+ export const analyticsMock: jest.Mocked<AnyAnalytics> = {
19
+ addSourceMiddleware: jest.fn().mockImplementation(throwNotImplemented),
20
+ load: jest.fn().mockImplementation(throwNotImplemented),
21
+ on: jest.fn().mockImplementation(throwNotImplemented),
22
+ track: jest.fn().mockImplementation(throwNotImplemented),
23
+ }
@@ -0,0 +1,11 @@
1
+ import { OneTrustGlobal } from '../lib/onetrust-api'
2
+ /**
3
+ * ALERT: It's OK to declare ambient globals in test code, but __not__ in library code
4
+ * This file should not be included in the final package
5
+ */
6
+ export declare global {
7
+ interface Window {
8
+ OneTrust: OneTrustGlobal
9
+ OnetrustActiveGroups: string
10
+ }
11
+ }
@@ -0,0 +1,3 @@
1
+ export const throwNotImplemented = (): never => {
2
+ throw new Error('not implemented')
3
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["src"],
4
+ "exclude": ["**/__tests__/**", "**/test-helpers/**"],
5
+ "compilerOptions": {
6
+ "outDir": "./dist/esm",
7
+ "declarationDir": "./dist/types"
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../../tsconfig.json",
3
+ "exclude": ["node_modules", "dist"],
4
+ "compilerOptions": {
5
+ "module": "ESNext", // es6 modules
6
+ "target": "ES2020", // don't down-compile *too much* -- if users are using webpack, they can always transpile this library themselves
7
+ "lib": ["ES2020", "DOM", "DOM.Iterable"], // assume that consumers will be polyfilling at least down to es2020
8
+ "moduleResolution": "node",
9
+ "isolatedModules": true // ensure we are friendly to build systems
10
+ }
11
+ }
@@ -0,0 +1,25 @@
1
+ const common = require('@internal/config-webpack/webpack.config.common')
2
+ const path = require('path')
3
+ const { merge } = require('webpack-merge')
4
+ const isProd = process.env.NODE_ENV === 'production'
5
+ /**
6
+ * @type { import('webpack').Configuration }
7
+ */
8
+ module.exports = merge(common, {
9
+ entry: {
10
+ 'analytics-onetrust.umd': {
11
+ import: path.resolve(__dirname, 'src/index.umd.ts'),
12
+ library: {
13
+ name: 'AnalyticsOneTrust',
14
+ type: 'umd',
15
+ },
16
+ },
17
+ },
18
+ output: {
19
+ filename: isProd ? '[name].js' : '[name].development.js',
20
+ path: path.resolve(__dirname, 'dist/umd'),
21
+ chunkFilename: isProd
22
+ ? '[name].[contenthash].js'
23
+ : '[name].chunk.development.js',
24
+ },
25
+ })
@@ -0,0 +1,4 @@
1
+ /** @type { import('eslint').Linter.Config } */
2
+ module.exports = {
3
+ extends: ['../../.eslintrc.isomorphic'],
4
+ }
@@ -0,0 +1 @@
1
+ module.exports = require("@internal/config").lintStagedConfig