@wix/web5-core 1.63.47 → 1.63.49

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 (67) hide show
  1. package/dist/cjs/client/loaderAuthFetch.js +25 -0
  2. package/dist/cjs/client/loaderAuthFetch.js.map +1 -0
  3. package/dist/cjs/index.js +6 -28
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/esm/client/loaderAuthFetch.js +21 -0
  6. package/dist/esm/client/loaderAuthFetch.js.map +1 -0
  7. package/dist/esm/index.js +1 -4
  8. package/dist/esm/index.js.map +1 -1
  9. package/dist/types/client/loaderAuthFetch.d.ts +26 -0
  10. package/dist/types/client/loaderAuthFetch.d.ts.map +1 -0
  11. package/dist/types/index.d.ts +1 -2
  12. package/dist/types/index.d.ts.map +1 -1
  13. package/package.json +2 -2
  14. package/dist/cjs/client/wixAuthFetch.js +0 -73
  15. package/dist/cjs/client/wixAuthFetch.js.map +0 -1
  16. package/dist/cjs/privacy/consentGate.js +0 -129
  17. package/dist/cjs/privacy/consentGate.js.map +0 -1
  18. package/dist/cjs/privacy/consentOverride.js +0 -94
  19. package/dist/cjs/privacy/consentOverride.js.map +0 -1
  20. package/dist/cjs/privacy/detectProvider.js +0 -71
  21. package/dist/cjs/privacy/detectProvider.js.map +0 -1
  22. package/dist/cjs/privacy/index.js +0 -33
  23. package/dist/cjs/privacy/index.js.map +0 -1
  24. package/dist/cjs/privacy/providers/hostSuppliedProvider.js +0 -93
  25. package/dist/cjs/privacy/providers/hostSuppliedProvider.js.map +0 -1
  26. package/dist/cjs/privacy/providers/oneTrustProvider.js +0 -72
  27. package/dist/cjs/privacy/providers/oneTrustProvider.js.map +0 -1
  28. package/dist/cjs/privacy/providers/shopifyProvider.js +0 -181
  29. package/dist/cjs/privacy/providers/shopifyProvider.js.map +0 -1
  30. package/dist/cjs/privacy/types.js +0 -34
  31. package/dist/cjs/privacy/types.js.map +0 -1
  32. package/dist/esm/client/wixAuthFetch.js +0 -68
  33. package/dist/esm/client/wixAuthFetch.js.map +0 -1
  34. package/dist/esm/privacy/consentGate.js +0 -122
  35. package/dist/esm/privacy/consentGate.js.map +0 -1
  36. package/dist/esm/privacy/consentOverride.js +0 -87
  37. package/dist/esm/privacy/consentOverride.js.map +0 -1
  38. package/dist/esm/privacy/detectProvider.js +0 -65
  39. package/dist/esm/privacy/detectProvider.js.map +0 -1
  40. package/dist/esm/privacy/index.js +0 -8
  41. package/dist/esm/privacy/index.js.map +0 -1
  42. package/dist/esm/privacy/providers/hostSuppliedProvider.js +0 -85
  43. package/dist/esm/privacy/providers/hostSuppliedProvider.js.map +0 -1
  44. package/dist/esm/privacy/providers/oneTrustProvider.js +0 -66
  45. package/dist/esm/privacy/providers/oneTrustProvider.js.map +0 -1
  46. package/dist/esm/privacy/providers/shopifyProvider.js +0 -178
  47. package/dist/esm/privacy/providers/shopifyProvider.js.map +0 -1
  48. package/dist/esm/privacy/types.js +0 -30
  49. package/dist/esm/privacy/types.js.map +0 -1
  50. package/dist/types/client/wixAuthFetch.d.ts +0 -12
  51. package/dist/types/client/wixAuthFetch.d.ts.map +0 -1
  52. package/dist/types/privacy/consentGate.d.ts +0 -52
  53. package/dist/types/privacy/consentGate.d.ts.map +0 -1
  54. package/dist/types/privacy/consentOverride.d.ts +0 -33
  55. package/dist/types/privacy/consentOverride.d.ts.map +0 -1
  56. package/dist/types/privacy/detectProvider.d.ts +0 -25
  57. package/dist/types/privacy/detectProvider.d.ts.map +0 -1
  58. package/dist/types/privacy/index.d.ts +0 -8
  59. package/dist/types/privacy/index.d.ts.map +0 -1
  60. package/dist/types/privacy/providers/hostSuppliedProvider.d.ts +0 -29
  61. package/dist/types/privacy/providers/hostSuppliedProvider.d.ts.map +0 -1
  62. package/dist/types/privacy/providers/oneTrustProvider.d.ts +0 -15
  63. package/dist/types/privacy/providers/oneTrustProvider.d.ts.map +0 -1
  64. package/dist/types/privacy/providers/shopifyProvider.d.ts +0 -26
  65. package/dist/types/privacy/providers/shopifyProvider.d.ts.map +0 -1
  66. package/dist/types/privacy/types.d.ts +0 -32
  67. package/dist/types/privacy/types.d.ts.map +0 -1
@@ -1,94 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.setConsentOverride = exports.overrideSnapshot = exports.getConsentOverride = exports.CONSENT_OVERRIDE_QUERY_PARAM = exports.CONSENT_OVERRIDE_KEY = void 0;
5
- /**
6
- * Consent override (debug-only) — DL #218.
7
- *
8
- * Shopify only serves its cookie banner where consent is legally required, so
9
- * from most of the world `shouldShowBanner()` is `false` and there is no way to
10
- * reach the `unknown` or `denied` branches by hand. Development stores often
11
- * have no privacy configuration at all, which pins the gate at `unknown`
12
- * forever. Neither is a bug, and both make the interesting states unreachable
13
- * from a browser.
14
- *
15
- * This forces the gate's answer so all four rows of the truth table can be
16
- * walked on any store, in any region, published or not.
17
- *
18
- * ?w5consent=granted | denied | unknown (one-shot)
19
- * localStorage["w5_consent_override"] (sticky)
20
- *
21
- * **The two are not equally trusted, on purpose.** A link is something one
22
- * person can send another, so a query param may only ever *reduce* what is
23
- * collected: `denied` is honoured anywhere, while `granted` and `unknown` are
24
- * honoured only on a local origin. Turning tracking *on* for someone else by
25
- * sending them a URL is exactly the thing this whole feature exists to
26
- * prevent. On a real storefront, set the localStorage key in devtools — which
27
- * is a deliberate act by the person whose browser it is.
28
- */
29
-
30
- const CONSENT_OVERRIDE_KEY = exports.CONSENT_OVERRIDE_KEY = 'w5_consent_override';
31
- const CONSENT_OVERRIDE_QUERY_PARAM = exports.CONSENT_OVERRIDE_QUERY_PARAM = 'w5consent';
32
- const VALID = ['granted', 'denied', 'unknown'];
33
- const isConsentState = value => typeof value === 'string' && VALID.includes(value);
34
-
35
- /** Only a local origin may force a *more* permissive state from a URL. */
36
- const isLocalOrigin = () => {
37
- try {
38
- const {
39
- hostname
40
- } = window.location;
41
- return hostname === 'localhost' || hostname === '127.0.0.1' || hostname.endsWith('.local');
42
- } catch {
43
- return false;
44
- }
45
- };
46
- const readQueryParam = () => {
47
- try {
48
- const raw = new URLSearchParams(window.location.search).get(CONSENT_OVERRIDE_QUERY_PARAM);
49
- if (!isConsentState(raw)) {
50
- return null;
51
- }
52
- // `denied` can only ever collect less, so a link may set it anywhere.
53
- if (raw === 'denied' || isLocalOrigin()) {
54
- return raw;
55
- }
56
- console.warn(`[w5-consent] ignoring ?${CONSENT_OVERRIDE_QUERY_PARAM}=${raw} — only "denied" is accepted from a URL off a local origin. ` + `Set localStorage["${CONSENT_OVERRIDE_KEY}"] = "${raw}" instead.`);
57
- return null;
58
- } catch {
59
- return null;
60
- }
61
- };
62
- const readStorage = () => {
63
- try {
64
- const raw = localStorage.getItem(CONSENT_OVERRIDE_KEY);
65
- return isConsentState(raw) ? raw : null;
66
- } catch {
67
- return null;
68
- }
69
- };
70
-
71
- /** The forced consent state, or `null` when no override is active. */
72
- const getConsentOverride = () => readQueryParam() ?? readStorage();
73
- exports.getConsentOverride = getConsentOverride;
74
- const overrideSnapshot = state => ({
75
- analytics: state,
76
- marketing: state,
77
- performance: state
78
- });
79
-
80
- /** Persist the override and apply it on the next load. `null` clears it. */
81
- exports.overrideSnapshot = overrideSnapshot;
82
- const setConsentOverride = state => {
83
- try {
84
- if (state) {
85
- localStorage.setItem(CONSENT_OVERRIDE_KEY, state);
86
- } else {
87
- localStorage.removeItem(CONSENT_OVERRIDE_KEY);
88
- }
89
- } catch {
90
- // Ignore — the override simply won't persist.
91
- }
92
- };
93
- exports.setConsentOverride = setConsentOverride;
94
- //# sourceMappingURL=consentOverride.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["CONSENT_OVERRIDE_KEY","exports","CONSENT_OVERRIDE_QUERY_PARAM","VALID","isConsentState","value","includes","isLocalOrigin","hostname","window","location","endsWith","readQueryParam","raw","URLSearchParams","search","get","console","warn","readStorage","localStorage","getItem","getConsentOverride","overrideSnapshot","state","analytics","marketing","performance","setConsentOverride","setItem","removeItem"],"sources":["../../../src/privacy/consentOverride.ts"],"sourcesContent":["/**\n * Consent override (debug-only) — DL #218.\n *\n * Shopify only serves its cookie banner where consent is legally required, so\n * from most of the world `shouldShowBanner()` is `false` and there is no way to\n * reach the `unknown` or `denied` branches by hand. Development stores often\n * have no privacy configuration at all, which pins the gate at `unknown`\n * forever. Neither is a bug, and both make the interesting states unreachable\n * from a browser.\n *\n * This forces the gate's answer so all four rows of the truth table can be\n * walked on any store, in any region, published or not.\n *\n * ?w5consent=granted | denied | unknown (one-shot)\n * localStorage[\"w5_consent_override\"] (sticky)\n *\n * **The two are not equally trusted, on purpose.** A link is something one\n * person can send another, so a query param may only ever *reduce* what is\n * collected: `denied` is honoured anywhere, while `granted` and `unknown` are\n * honoured only on a local origin. Turning tracking *on* for someone else by\n * sending them a URL is exactly the thing this whole feature exists to\n * prevent. On a real storefront, set the localStorage key in devtools — which\n * is a deliberate act by the person whose browser it is.\n */\n\nimport type { ConsentSnapshot, ConsentState } from './types';\n\nexport const CONSENT_OVERRIDE_KEY = 'w5_consent_override';\nexport const CONSENT_OVERRIDE_QUERY_PARAM = 'w5consent';\n\nconst VALID: readonly ConsentState[] = ['granted', 'denied', 'unknown'];\n\nconst isConsentState = (value: unknown): value is ConsentState =>\n typeof value === 'string' && (VALID as readonly string[]).includes(value);\n\n/** Only a local origin may force a *more* permissive state from a URL. */\nconst isLocalOrigin = (): boolean => {\n try {\n const { hostname } = window.location;\n return (\n hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname.endsWith('.local')\n );\n } catch {\n return false;\n }\n};\n\nconst readQueryParam = (): ConsentState | null => {\n try {\n const raw = new URLSearchParams(window.location.search).get(\n CONSENT_OVERRIDE_QUERY_PARAM,\n );\n if (!isConsentState(raw)) {\n return null;\n }\n // `denied` can only ever collect less, so a link may set it anywhere.\n if (raw === 'denied' || isLocalOrigin()) {\n return raw;\n }\n console.warn(\n `[w5-consent] ignoring ?${CONSENT_OVERRIDE_QUERY_PARAM}=${raw} — only \"denied\" is accepted from a URL off a local origin. ` +\n `Set localStorage[\"${CONSENT_OVERRIDE_KEY}\"] = \"${raw}\" instead.`,\n );\n return null;\n } catch {\n return null;\n }\n};\n\nconst readStorage = (): ConsentState | null => {\n try {\n const raw = localStorage.getItem(CONSENT_OVERRIDE_KEY);\n return isConsentState(raw) ? raw : null;\n } catch {\n return null;\n }\n};\n\n/** The forced consent state, or `null` when no override is active. */\nexport const getConsentOverride = (): ConsentState | null =>\n readQueryParam() ?? readStorage();\n\nexport const overrideSnapshot = (state: ConsentState): ConsentSnapshot => ({\n analytics: state,\n marketing: state,\n performance: state,\n});\n\n/** Persist the override and apply it on the next load. `null` clears it. */\nexport const setConsentOverride = (state: ConsentState | null): void => {\n try {\n if (state) {\n localStorage.setItem(CONSENT_OVERRIDE_KEY, state);\n } else {\n localStorage.removeItem(CONSENT_OVERRIDE_KEY);\n }\n } catch {\n // Ignore — the override simply won't persist.\n }\n};\n"],"mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIO,MAAMA,oBAAoB,GAAAC,OAAA,CAAAD,oBAAA,GAAG,qBAAqB;AAClD,MAAME,4BAA4B,GAAAD,OAAA,CAAAC,4BAAA,GAAG,WAAW;AAEvD,MAAMC,KAA8B,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;AAEvE,MAAMC,cAAc,GAAIC,KAAc,IACpC,OAAOA,KAAK,KAAK,QAAQ,IAAKF,KAAK,CAAuBG,QAAQ,CAACD,KAAK,CAAC;;AAE3E;AACA,MAAME,aAAa,GAAGA,CAAA,KAAe;EACnC,IAAI;IACF,MAAM;MAAEC;IAAS,CAAC,GAAGC,MAAM,CAACC,QAAQ;IACpC,OACEF,QAAQ,KAAK,WAAW,IACxBA,QAAQ,KAAK,WAAW,IACxBA,QAAQ,CAACG,QAAQ,CAAC,QAAQ,CAAC;EAE/B,CAAC,CAAC,MAAM;IACN,OAAO,KAAK;EACd;AACF,CAAC;AAED,MAAMC,cAAc,GAAGA,CAAA,KAA2B;EAChD,IAAI;IACF,MAAMC,GAAG,GAAG,IAAIC,eAAe,CAACL,MAAM,CAACC,QAAQ,CAACK,MAAM,CAAC,CAACC,GAAG,CACzDd,4BACF,CAAC;IACD,IAAI,CAACE,cAAc,CAACS,GAAG,CAAC,EAAE;MACxB,OAAO,IAAI;IACb;IACA;IACA,IAAIA,GAAG,KAAK,QAAQ,IAAIN,aAAa,CAAC,CAAC,EAAE;MACvC,OAAOM,GAAG;IACZ;IACAI,OAAO,CAACC,IAAI,CACV,0BAA0BhB,4BAA4B,IAAIW,GAAG,8DAA8D,GACzH,qBAAqBb,oBAAoB,SAASa,GAAG,YACzD,CAAC;IACD,OAAO,IAAI;EACb,CAAC,CAAC,MAAM;IACN,OAAO,IAAI;EACb;AACF,CAAC;AAED,MAAMM,WAAW,GAAGA,CAAA,KAA2B;EAC7C,IAAI;IACF,MAAMN,GAAG,GAAGO,YAAY,CAACC,OAAO,CAACrB,oBAAoB,CAAC;IACtD,OAAOI,cAAc,CAACS,GAAG,CAAC,GAAGA,GAAG,GAAG,IAAI;EACzC,CAAC,CAAC,MAAM;IACN,OAAO,IAAI;EACb;AACF,CAAC;;AAED;AACO,MAAMS,kBAAkB,GAAGA,CAAA,KAChCV,cAAc,CAAC,CAAC,IAAIO,WAAW,CAAC,CAAC;AAAClB,OAAA,CAAAqB,kBAAA,GAAAA,kBAAA;AAE7B,MAAMC,gBAAgB,GAAIC,KAAmB,KAAuB;EACzEC,SAAS,EAAED,KAAK;EAChBE,SAAS,EAAEF,KAAK;EAChBG,WAAW,EAAEH;AACf,CAAC,CAAC;;AAEF;AAAAvB,OAAA,CAAAsB,gBAAA,GAAAA,gBAAA;AACO,MAAMK,kBAAkB,GAAIJ,KAA0B,IAAW;EACtE,IAAI;IACF,IAAIA,KAAK,EAAE;MACTJ,YAAY,CAACS,OAAO,CAAC7B,oBAAoB,EAAEwB,KAAK,CAAC;IACnD,CAAC,MAAM;MACLJ,YAAY,CAACU,UAAU,CAAC9B,oBAAoB,CAAC;IAC/C;EACF,CAAC,CAAC,MAAM;IACN;EAAA;AAEJ,CAAC;AAACC,OAAA,CAAA2B,kBAAA,GAAAA,kBAAA","ignoreList":[]}
@@ -1,71 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.initConsentGate = exports.detectConsentProvider = void 0;
5
- var _consentGate = require("./consentGate");
6
- var _consentOverride = require("./consentOverride");
7
- var _hostSuppliedProvider = require("./providers/hostSuppliedProvider");
8
- var _shopifyProvider = require("./providers/shopifyProvider");
9
- var _oneTrustProvider = require("./providers/oneTrustProvider");
10
- /**
11
- * Provider selection — DL #218.
12
- *
13
- * Detected at boot, not configured per client, because a merchant can install
14
- * a CMP long after we deploy and the bundle is not the source of truth for a
15
- * store's behaviour (DL #214).
16
- *
17
- * Order is host-supplied → Shopify → OneTrust → none. A host that publishes an
18
- * answer outranks anything we could sniff, because it knows things we cannot:
19
- * a server-side consent record, a CMP behind its own abstraction, or a legal
20
- * position we have no business guessing at.
21
- *
22
- * When nothing is detected the gate keeps its default — everything `unknown`,
23
- * held until the visitor acts. That is the case on every Shopify store with no
24
- * privacy configuration, which today is most of them.
25
- */
26
-
27
- const detectConsentProvider = () => {
28
- // Debug override outranks every real signal, so the states a region or an
29
- // unconfigured store makes unreachable can still be walked by hand.
30
- const forced = (0, _consentOverride.getConsentOverride)();
31
- if (forced) {
32
- console.warn(`[w5-consent] OVERRIDE ACTIVE — consent forced to "${forced}". This is a debug switch, not a real answer.`);
33
- return {
34
- name: `override:${forced}`,
35
- read: () => (0, _consentOverride.overrideSnapshot)(forced),
36
- subscribe: () => () => {}
37
- };
38
- }
39
- if ((0, _hostSuppliedProvider.hasHostSuppliedConsent)()) {
40
- return (0, _hostSuppliedProvider.createHostSuppliedConsentProvider)();
41
- }
42
- if ((0, _shopifyProvider.isShopifyHost)()) {
43
- return (0, _shopifyProvider.createShopifyConsentProvider)();
44
- }
45
- if ((0, _oneTrustProvider.isOneTrustHost)()) {
46
- return (0, _oneTrustProvider.createOneTrustConsentProvider)();
47
- }
48
- return null;
49
- };
50
-
51
- /**
52
- * Install the detected provider, if any. Call once at boot, before the first
53
- * emitter runs — anything raised earlier is held rather than lost, but the
54
- * sooner this runs the less the buffer has to carry.
55
- */
56
- exports.detectConsentProvider = detectConsentProvider;
57
- const initConsentGate = () => {
58
- const provider = detectConsentProvider();
59
- if (provider) {
60
- (0, _consentGate.installConsentProvider)(provider);
61
- } else {
62
- try {
63
- console.debug('[w5-consent] no CMP detected (no host-supplied consent, no Shopify customerPrivacy, no OneTrust) — everything held until the visitor submits a prompt');
64
- } catch {
65
- /* never break on a console */
66
- }
67
- }
68
- return provider;
69
- };
70
- exports.initConsentGate = initConsentGate;
71
- //# sourceMappingURL=detectProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_consentGate","require","_consentOverride","_hostSuppliedProvider","_shopifyProvider","_oneTrustProvider","detectConsentProvider","forced","getConsentOverride","console","warn","name","read","overrideSnapshot","subscribe","hasHostSuppliedConsent","createHostSuppliedConsentProvider","isShopifyHost","createShopifyConsentProvider","isOneTrustHost","createOneTrustConsentProvider","exports","initConsentGate","provider","installConsentProvider","debug"],"sources":["../../../src/privacy/detectProvider.ts"],"sourcesContent":["/**\n * Provider selection — DL #218.\n *\n * Detected at boot, not configured per client, because a merchant can install\n * a CMP long after we deploy and the bundle is not the source of truth for a\n * store's behaviour (DL #214).\n *\n * Order is host-supplied → Shopify → OneTrust → none. A host that publishes an\n * answer outranks anything we could sniff, because it knows things we cannot:\n * a server-side consent record, a CMP behind its own abstraction, or a legal\n * position we have no business guessing at.\n *\n * When nothing is detected the gate keeps its default — everything `unknown`,\n * held until the visitor acts. That is the case on every Shopify store with no\n * privacy configuration, which today is most of them.\n */\n\nimport { installConsentProvider } from './consentGate';\nimport { getConsentOverride, overrideSnapshot } from './consentOverride';\nimport type { ConsentProvider } from './types';\nimport {\n createHostSuppliedConsentProvider,\n hasHostSuppliedConsent,\n} from './providers/hostSuppliedProvider';\nimport {\n createShopifyConsentProvider,\n isShopifyHost,\n} from './providers/shopifyProvider';\nimport {\n createOneTrustConsentProvider,\n isOneTrustHost,\n} from './providers/oneTrustProvider';\n\nexport const detectConsentProvider = (): ConsentProvider | null => {\n // Debug override outranks every real signal, so the states a region or an\n // unconfigured store makes unreachable can still be walked by hand.\n const forced = getConsentOverride();\n if (forced) {\n console.warn(\n `[w5-consent] OVERRIDE ACTIVE — consent forced to \"${forced}\". This is a debug switch, not a real answer.`,\n );\n return {\n name: `override:${forced}`,\n read: () => overrideSnapshot(forced),\n subscribe: () => () => {},\n };\n }\n if (hasHostSuppliedConsent()) {\n return createHostSuppliedConsentProvider();\n }\n if (isShopifyHost()) {\n return createShopifyConsentProvider();\n }\n if (isOneTrustHost()) {\n return createOneTrustConsentProvider();\n }\n return null;\n};\n\n/**\n * Install the detected provider, if any. Call once at boot, before the first\n * emitter runs — anything raised earlier is held rather than lost, but the\n * sooner this runs the less the buffer has to carry.\n */\nexport const initConsentGate = (): ConsentProvider | null => {\n const provider = detectConsentProvider();\n if (provider) {\n installConsentProvider(provider);\n } else {\n try {\n console.debug(\n '[w5-consent] no CMP detected (no host-supplied consent, no Shopify customerPrivacy, no OneTrust) — everything held until the visitor submits a prompt',\n );\n } catch {\n /* never break on a console */\n }\n }\n return provider;\n};\n"],"mappings":";;;;AAiBA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,gBAAA,GAAAD,OAAA;AAEA,IAAAE,qBAAA,GAAAF,OAAA;AAIA,IAAAG,gBAAA,GAAAH,OAAA;AAIA,IAAAI,iBAAA,GAAAJ,OAAA;AA5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAkBO,MAAMK,qBAAqB,GAAGA,CAAA,KAA8B;EACjE;EACA;EACA,MAAMC,MAAM,GAAG,IAAAC,mCAAkB,EAAC,CAAC;EACnC,IAAID,MAAM,EAAE;IACVE,OAAO,CAACC,IAAI,CACV,qDAAqDH,MAAM,+CAC7D,CAAC;IACD,OAAO;MACLI,IAAI,EAAE,YAAYJ,MAAM,EAAE;MAC1BK,IAAI,EAAEA,CAAA,KAAM,IAAAC,iCAAgB,EAACN,MAAM,CAAC;MACpCO,SAAS,EAAEA,CAAA,KAAM,MAAM,CAAC;IAC1B,CAAC;EACH;EACA,IAAI,IAAAC,4CAAsB,EAAC,CAAC,EAAE;IAC5B,OAAO,IAAAC,uDAAiC,EAAC,CAAC;EAC5C;EACA,IAAI,IAAAC,8BAAa,EAAC,CAAC,EAAE;IACnB,OAAO,IAAAC,6CAA4B,EAAC,CAAC;EACvC;EACA,IAAI,IAAAC,gCAAc,EAAC,CAAC,EAAE;IACpB,OAAO,IAAAC,+CAA6B,EAAC,CAAC;EACxC;EACA,OAAO,IAAI;AACb,CAAC;;AAED;AACA;AACA;AACA;AACA;AAJAC,OAAA,CAAAf,qBAAA,GAAAA,qBAAA;AAKO,MAAMgB,eAAe,GAAGA,CAAA,KAA8B;EAC3D,MAAMC,QAAQ,GAAGjB,qBAAqB,CAAC,CAAC;EACxC,IAAIiB,QAAQ,EAAE;IACZ,IAAAC,mCAAsB,EAACD,QAAQ,CAAC;EAClC,CAAC,MAAM;IACL,IAAI;MACFd,OAAO,CAACgB,KAAK,CACX,uJACF,CAAC;IACH,CAAC,CAAC,MAAM;MACN;IAAA;EAEJ;EACA,OAAOF,QAAQ;AACjB,CAAC;AAACF,OAAA,CAAAC,eAAA,GAAAA,eAAA","ignoreList":[]}
@@ -1,33 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.unlockOnUserAction = exports.subscribeToConsent = exports.setConsentOverride = exports.resetConsentGateForTests = exports.publishHostConsent = exports.mayPersistToken = exports.isShopifyHost = exports.isOneTrustHost = exports.installConsentProvider = exports.initConsentGate = exports.hasHostSuppliedConsent = exports.getConsentSnapshot = exports.getConsentOverride = exports.detectConsentProvider = exports.createShopifyConsentProvider = exports.createOneTrustConsentProvider = exports.createHostSuppliedConsentProvider = exports.UNKNOWN_CONSENT = exports.HOST_CONSENT_GLOBAL = exports.CONSENT_OVERRIDE_QUERY_PARAM = exports.CONSENT_OVERRIDE_KEY = void 0;
5
- var _types = require("./types");
6
- exports.UNKNOWN_CONSENT = _types.UNKNOWN_CONSENT;
7
- var _consentGate = require("./consentGate");
8
- exports.unlockOnUserAction = _consentGate.unlockOnUserAction;
9
- exports.mayPersistToken = _consentGate.mayPersistToken;
10
- exports.getConsentSnapshot = _consentGate.getConsentSnapshot;
11
- exports.subscribeToConsent = _consentGate.subscribeToConsent;
12
- exports.installConsentProvider = _consentGate.installConsentProvider;
13
- exports.resetConsentGateForTests = _consentGate.resetConsentGateForTests;
14
- var _detectProvider = require("./detectProvider");
15
- exports.detectConsentProvider = _detectProvider.detectConsentProvider;
16
- exports.initConsentGate = _detectProvider.initConsentGate;
17
- var _consentOverride = require("./consentOverride");
18
- exports.CONSENT_OVERRIDE_KEY = _consentOverride.CONSENT_OVERRIDE_KEY;
19
- exports.CONSENT_OVERRIDE_QUERY_PARAM = _consentOverride.CONSENT_OVERRIDE_QUERY_PARAM;
20
- exports.getConsentOverride = _consentOverride.getConsentOverride;
21
- exports.setConsentOverride = _consentOverride.setConsentOverride;
22
- var _shopifyProvider = require("./providers/shopifyProvider");
23
- exports.createShopifyConsentProvider = _shopifyProvider.createShopifyConsentProvider;
24
- exports.isShopifyHost = _shopifyProvider.isShopifyHost;
25
- var _oneTrustProvider = require("./providers/oneTrustProvider");
26
- exports.createOneTrustConsentProvider = _oneTrustProvider.createOneTrustConsentProvider;
27
- exports.isOneTrustHost = _oneTrustProvider.isOneTrustHost;
28
- var _hostSuppliedProvider = require("./providers/hostSuppliedProvider");
29
- exports.HOST_CONSENT_GLOBAL = _hostSuppliedProvider.HOST_CONSENT_GLOBAL;
30
- exports.createHostSuppliedConsentProvider = _hostSuppliedProvider.createHostSuppliedConsentProvider;
31
- exports.hasHostSuppliedConsent = _hostSuppliedProvider.hasHostSuppliedConsent;
32
- exports.publishHostConsent = _hostSuppliedProvider.publishHostConsent;
33
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_types","require","exports","UNKNOWN_CONSENT","_consentGate","unlockOnUserAction","mayPersistToken","getConsentSnapshot","subscribeToConsent","installConsentProvider","resetConsentGateForTests","_detectProvider","detectConsentProvider","initConsentGate","_consentOverride","CONSENT_OVERRIDE_KEY","CONSENT_OVERRIDE_QUERY_PARAM","getConsentOverride","setConsentOverride","_shopifyProvider","createShopifyConsentProvider","isShopifyHost","_oneTrustProvider","createOneTrustConsentProvider","isOneTrustHost","_hostSuppliedProvider","HOST_CONSENT_GLOBAL","createHostSuppliedConsentProvider","hasHostSuppliedConsent","publishHostConsent"],"sources":["../../../src/privacy/index.ts"],"sourcesContent":["export {\n type ConsentState,\n type ConsentPurpose,\n type GatedPurpose,\n type ConsentSnapshot,\n type ConsentProvider,\n UNKNOWN_CONSENT,\n} from './types';\n\nexport {\n unlockOnUserAction,\n mayPersistToken,\n getConsentSnapshot,\n subscribeToConsent,\n installConsentProvider,\n resetConsentGateForTests,\n} from './consentGate';\n\nexport { detectConsentProvider, initConsentGate } from './detectProvider';\n\nexport {\n CONSENT_OVERRIDE_KEY,\n CONSENT_OVERRIDE_QUERY_PARAM,\n getConsentOverride,\n setConsentOverride,\n} from './consentOverride';\n\nexport {\n createShopifyConsentProvider,\n isShopifyHost,\n} from './providers/shopifyProvider';\nexport {\n createOneTrustConsentProvider,\n isOneTrustHost,\n} from './providers/oneTrustProvider';\nexport {\n type HostConsentInput,\n HOST_CONSENT_GLOBAL,\n createHostSuppliedConsentProvider,\n hasHostSuppliedConsent,\n publishHostConsent,\n} from './providers/hostSuppliedProvider';\n"],"mappings":";;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAOiBC,OAAA,CAAAC,eAAA,GAAAH,MAAA,CAAAG,eAAA;AAEjB,IAAAC,YAAA,GAAAH,OAAA;AAOuBC,OAAA,CAAAG,kBAAA,GAAAD,YAAA,CAAAC,kBAAA;AAAAH,OAAA,CAAAI,eAAA,GAAAF,YAAA,CAAAE,eAAA;AAAAJ,OAAA,CAAAK,kBAAA,GAAAH,YAAA,CAAAG,kBAAA;AAAAL,OAAA,CAAAM,kBAAA,GAAAJ,YAAA,CAAAI,kBAAA;AAAAN,OAAA,CAAAO,sBAAA,GAAAL,YAAA,CAAAK,sBAAA;AAAAP,OAAA,CAAAQ,wBAAA,GAAAN,YAAA,CAAAM,wBAAA;AAEvB,IAAAC,eAAA,GAAAV,OAAA;AAA0EC,OAAA,CAAAU,qBAAA,GAAAD,eAAA,CAAAC,qBAAA;AAAAV,OAAA,CAAAW,eAAA,GAAAF,eAAA,CAAAE,eAAA;AAE1E,IAAAC,gBAAA,GAAAb,OAAA;AAK2BC,OAAA,CAAAa,oBAAA,GAAAD,gBAAA,CAAAC,oBAAA;AAAAb,OAAA,CAAAc,4BAAA,GAAAF,gBAAA,CAAAE,4BAAA;AAAAd,OAAA,CAAAe,kBAAA,GAAAH,gBAAA,CAAAG,kBAAA;AAAAf,OAAA,CAAAgB,kBAAA,GAAAJ,gBAAA,CAAAI,kBAAA;AAE3B,IAAAC,gBAAA,GAAAlB,OAAA;AAGqCC,OAAA,CAAAkB,4BAAA,GAAAD,gBAAA,CAAAC,4BAAA;AAAAlB,OAAA,CAAAmB,aAAA,GAAAF,gBAAA,CAAAE,aAAA;AACrC,IAAAC,iBAAA,GAAArB,OAAA;AAGsCC,OAAA,CAAAqB,6BAAA,GAAAD,iBAAA,CAAAC,6BAAA;AAAArB,OAAA,CAAAsB,cAAA,GAAAF,iBAAA,CAAAE,cAAA;AACtC,IAAAC,qBAAA,GAAAxB,OAAA;AAM0CC,OAAA,CAAAwB,mBAAA,GAAAD,qBAAA,CAAAC,mBAAA;AAAAxB,OAAA,CAAAyB,iCAAA,GAAAF,qBAAA,CAAAE,iCAAA;AAAAzB,OAAA,CAAA0B,sBAAA,GAAAH,qBAAA,CAAAG,sBAAA;AAAA1B,OAAA,CAAA2B,kBAAA,GAAAJ,qBAAA,CAAAI,kBAAA","ignoreList":[]}
@@ -1,93 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.publishHostConsent = exports.hasHostSuppliedConsent = exports.createHostSuppliedConsentProvider = exports.__resetHostConsentForTests = exports.HOST_CONSENT_GLOBAL = void 0;
5
- var _types = require("../types");
6
- /**
7
- * Host-supplied provider — DL #218.
8
- *
9
- * The escape hatch for every CMP we cannot detect: a host page that already
10
- * knows its visitor's answer publishes it, and the gate believes it. This is
11
- * how Circana, feature.com and any merchant on Cookiebot/Osano/Klaviyo reach
12
- * the gate without web5 learning each vendor's API.
13
- *
14
- * Two ways in, because hosts differ in when they know:
15
- * - `window.__web5_consent__` set before the bundle loads, read at install
16
- * - `publishHostConsent()` called at any time afterwards
17
- */
18
-
19
- const HOST_CONSENT_GLOBAL = exports.HOST_CONSENT_GLOBAL = '__web5_consent__';
20
-
21
- /** What a host may publish. Anything missing stays `unknown`. */
22
-
23
- const coerce = value => {
24
- if (value === true) {
25
- return 'granted';
26
- }
27
- if (value === false) {
28
- return 'denied';
29
- }
30
- if (value === 'granted' || value === 'denied' || value === 'unknown') {
31
- return value;
32
- }
33
- return 'unknown';
34
- };
35
- const normalize = input => {
36
- if (!input || typeof input !== 'object') {
37
- return _types.UNKNOWN_CONSENT;
38
- }
39
- const analytics = coerce(input.analytics);
40
- return {
41
- analytics,
42
- marketing: coerce(input.marketing),
43
- // A host that speaks only about analytics is taken to mean the same for
44
- // load telemetry, which is the same wire and the same recipient.
45
- performance: input.performance === undefined ? analytics : coerce(input.performance)
46
- };
47
- };
48
- const readGlobal = () => {
49
- if (typeof window === 'undefined') {
50
- return _types.UNKNOWN_CONSENT;
51
- }
52
- const raw = window[HOST_CONSENT_GLOBAL];
53
- return normalize(raw);
54
- };
55
- const hasHostSuppliedConsent = () => {
56
- if (typeof window === 'undefined') {
57
- return false;
58
- }
59
- const raw = window[HOST_CONSENT_GLOBAL];
60
- return !!raw && typeof raw === 'object';
61
- };
62
- exports.hasHostSuppliedConsent = hasHostSuppliedConsent;
63
- const subscribers = new Set();
64
- let published = null;
65
-
66
- /**
67
- * Called by the host — directly, or by the loader when it is handed consent in
68
- * its boot options — whenever the visitor's answer is known or changes.
69
- */
70
- const publishHostConsent = input => {
71
- published = normalize(input);
72
- for (const subscriber of subscribers) {
73
- subscriber(published);
74
- }
75
- };
76
- exports.publishHostConsent = publishHostConsent;
77
- const createHostSuppliedConsentProvider = () => ({
78
- name: 'host-supplied',
79
- read: () => published ?? readGlobal(),
80
- subscribe(onChange) {
81
- subscribers.add(onChange);
82
- return () => {
83
- subscribers.delete(onChange);
84
- };
85
- }
86
- });
87
- exports.createHostSuppliedConsentProvider = createHostSuppliedConsentProvider;
88
- const __resetHostConsentForTests = () => {
89
- published = null;
90
- subscribers.clear();
91
- };
92
- exports.__resetHostConsentForTests = __resetHostConsentForTests;
93
- //# sourceMappingURL=hostSuppliedProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_types","require","HOST_CONSENT_GLOBAL","exports","coerce","value","normalize","input","UNKNOWN_CONSENT","analytics","marketing","performance","undefined","readGlobal","window","raw","hasHostSuppliedConsent","subscribers","Set","published","publishHostConsent","subscriber","createHostSuppliedConsentProvider","name","read","subscribe","onChange","add","delete","__resetHostConsentForTests","clear"],"sources":["../../../../src/privacy/providers/hostSuppliedProvider.ts"],"sourcesContent":["/**\n * Host-supplied provider — DL #218.\n *\n * The escape hatch for every CMP we cannot detect: a host page that already\n * knows its visitor's answer publishes it, and the gate believes it. This is\n * how Circana, feature.com and any merchant on Cookiebot/Osano/Klaviyo reach\n * the gate without web5 learning each vendor's API.\n *\n * Two ways in, because hosts differ in when they know:\n * - `window.__web5_consent__` set before the bundle loads, read at install\n * - `publishHostConsent()` called at any time afterwards\n */\n\nimport {\n UNKNOWN_CONSENT,\n type ConsentProvider,\n type ConsentSnapshot,\n type ConsentState,\n} from '../types';\n\nexport const HOST_CONSENT_GLOBAL = '__web5_consent__';\n\n/** What a host may publish. Anything missing stays `unknown`. */\nexport interface HostConsentInput {\n analytics?: ConsentState | boolean;\n marketing?: ConsentState | boolean;\n performance?: ConsentState | boolean;\n}\n\nconst coerce = (value: ConsentState | boolean | undefined): ConsentState => {\n if (value === true) {\n return 'granted';\n }\n if (value === false) {\n return 'denied';\n }\n if (value === 'granted' || value === 'denied' || value === 'unknown') {\n return value;\n }\n return 'unknown';\n};\n\nconst normalize = (\n input: HostConsentInput | null | undefined,\n): ConsentSnapshot => {\n if (!input || typeof input !== 'object') {\n return UNKNOWN_CONSENT;\n }\n const analytics = coerce(input.analytics);\n return {\n analytics,\n marketing: coerce(input.marketing),\n // A host that speaks only about analytics is taken to mean the same for\n // load telemetry, which is the same wire and the same recipient.\n performance:\n input.performance === undefined ? analytics : coerce(input.performance),\n };\n};\n\nconst readGlobal = (): ConsentSnapshot => {\n if (typeof window === 'undefined') {\n return UNKNOWN_CONSENT;\n }\n const raw = (window as unknown as Record<string, unknown>)[\n HOST_CONSENT_GLOBAL\n ];\n return normalize(raw as HostConsentInput | undefined);\n};\n\nexport const hasHostSuppliedConsent = (): boolean => {\n if (typeof window === 'undefined') {\n return false;\n }\n const raw = (window as unknown as Record<string, unknown>)[\n HOST_CONSENT_GLOBAL\n ];\n return !!raw && typeof raw === 'object';\n};\n\nconst subscribers = new Set<(snapshot: ConsentSnapshot) => void>();\nlet published: ConsentSnapshot | null = null;\n\n/**\n * Called by the host — directly, or by the loader when it is handed consent in\n * its boot options — whenever the visitor's answer is known or changes.\n */\nexport const publishHostConsent = (input: HostConsentInput): void => {\n published = normalize(input);\n for (const subscriber of subscribers) {\n subscriber(published);\n }\n};\n\nexport const createHostSuppliedConsentProvider = (): ConsentProvider => ({\n name: 'host-supplied',\n\n read: () => published ?? readGlobal(),\n\n subscribe(onChange) {\n subscribers.add(onChange);\n return () => {\n subscribers.delete(onChange);\n };\n },\n});\n\nexport const __resetHostConsentForTests = (): void => {\n published = null;\n subscribers.clear();\n};\n"],"mappings":";;;;AAaA,IAAAA,MAAA,GAAAC,OAAA;AAbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AASO,MAAMC,mBAAmB,GAAAC,OAAA,CAAAD,mBAAA,GAAG,kBAAkB;;AAErD;;AAOA,MAAME,MAAM,GAAIC,KAAyC,IAAmB;EAC1E,IAAIA,KAAK,KAAK,IAAI,EAAE;IAClB,OAAO,SAAS;EAClB;EACA,IAAIA,KAAK,KAAK,KAAK,EAAE;IACnB,OAAO,QAAQ;EACjB;EACA,IAAIA,KAAK,KAAK,SAAS,IAAIA,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAK,SAAS,EAAE;IACpE,OAAOA,KAAK;EACd;EACA,OAAO,SAAS;AAClB,CAAC;AAED,MAAMC,SAAS,GACbC,KAA0C,IACtB;EACpB,IAAI,CAACA,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE;IACvC,OAAOC,sBAAe;EACxB;EACA,MAAMC,SAAS,GAAGL,MAAM,CAACG,KAAK,CAACE,SAAS,CAAC;EACzC,OAAO;IACLA,SAAS;IACTC,SAAS,EAAEN,MAAM,CAACG,KAAK,CAACG,SAAS,CAAC;IAClC;IACA;IACAC,WAAW,EACTJ,KAAK,CAACI,WAAW,KAAKC,SAAS,GAAGH,SAAS,GAAGL,MAAM,CAACG,KAAK,CAACI,WAAW;EAC1E,CAAC;AACH,CAAC;AAED,MAAME,UAAU,GAAGA,CAAA,KAAuB;EACxC,IAAI,OAAOC,MAAM,KAAK,WAAW,EAAE;IACjC,OAAON,sBAAe;EACxB;EACA,MAAMO,GAAG,GAAID,MAAM,CACjBZ,mBAAmB,CACpB;EACD,OAAOI,SAAS,CAACS,GAAmC,CAAC;AACvD,CAAC;AAEM,MAAMC,sBAAsB,GAAGA,CAAA,KAAe;EACnD,IAAI,OAAOF,MAAM,KAAK,WAAW,EAAE;IACjC,OAAO,KAAK;EACd;EACA,MAAMC,GAAG,GAAID,MAAM,CACjBZ,mBAAmB,CACpB;EACD,OAAO,CAAC,CAACa,GAAG,IAAI,OAAOA,GAAG,KAAK,QAAQ;AACzC,CAAC;AAACZ,OAAA,CAAAa,sBAAA,GAAAA,sBAAA;AAEF,MAAMC,WAAW,GAAG,IAAIC,GAAG,CAAsC,CAAC;AAClE,IAAIC,SAAiC,GAAG,IAAI;;AAE5C;AACA;AACA;AACA;AACO,MAAMC,kBAAkB,GAAIb,KAAuB,IAAW;EACnEY,SAAS,GAAGb,SAAS,CAACC,KAAK,CAAC;EAC5B,KAAK,MAAMc,UAAU,IAAIJ,WAAW,EAAE;IACpCI,UAAU,CAACF,SAAS,CAAC;EACvB;AACF,CAAC;AAAChB,OAAA,CAAAiB,kBAAA,GAAAA,kBAAA;AAEK,MAAME,iCAAiC,GAAGA,CAAA,MAAwB;EACvEC,IAAI,EAAE,eAAe;EAErBC,IAAI,EAAEA,CAAA,KAAML,SAAS,IAAIN,UAAU,CAAC,CAAC;EAErCY,SAASA,CAACC,QAAQ,EAAE;IAClBT,WAAW,CAACU,GAAG,CAACD,QAAQ,CAAC;IACzB,OAAO,MAAM;MACXT,WAAW,CAACW,MAAM,CAACF,QAAQ,CAAC;IAC9B,CAAC;EACH;AACF,CAAC,CAAC;AAACvB,OAAA,CAAAmB,iCAAA,GAAAA,iCAAA;AAEI,MAAMO,0BAA0B,GAAGA,CAAA,KAAY;EACpDV,SAAS,GAAG,IAAI;EAChBF,WAAW,CAACa,KAAK,CAAC,CAAC;AACrB,CAAC;AAAC3B,OAAA,CAAA0B,0BAAA,GAAAA,0BAAA","ignoreList":[]}
@@ -1,72 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.isOneTrustHost = exports.createOneTrustConsentProvider = void 0;
5
- /**
6
- * OneTrust provider — DL #218.
7
- *
8
- * Lifted from the consent check that used to live inside
9
- * `utils/analyticsEvents.ts`, with one deliberate behaviour change: that
10
- * function returned `true` when OneTrust was absent ("host is responsible for
11
- * loading OneTrust"), which on a Shopify storefront meant unconditional
12
- * default-allow. Absence is no longer this provider's problem — it is only
13
- * selected when OneTrust is actually on the page, and absence is handled by
14
- * the gate's own default.
15
- */
16
-
17
- /** OneTrust's default taxonomy: C0002 is the performance/analytics category. */
18
- const ANALYTICS_CATEGORY = 'C0002';
19
- /** C0004 is targeting/advertising. */
20
- const MARKETING_CATEGORY = 'C0004';
21
- const readGroups = () => {
22
- if (typeof window === 'undefined') {
23
- return null;
24
- }
25
- const groups = window.OnetrustActiveGroups;
26
- return typeof groups === 'string' ? groups : null;
27
- };
28
- const isOneTrustHost = () => readGroups() !== null;
29
- exports.isOneTrustHost = isOneTrustHost;
30
- const readSnapshot = () => {
31
- const groups = readGroups();
32
- if (groups !== null) {
33
- try {
34
- console.debug(`[w5-consent] onetrust: active groups "${groups}"`);
35
- } catch {
36
- /* never break on a console */
37
- }
38
- }
39
- if (groups === null) {
40
- return {
41
- analytics: 'unknown',
42
- marketing: 'unknown',
43
- performance: 'unknown'
44
- };
45
- }
46
- // OneTrust publishes the *active* groups, so a category that is absent from
47
- // a string OneTrust has written is a refusal, not silence.
48
- const analytics = groups.includes(ANALYTICS_CATEGORY) ? 'granted' : 'denied';
49
- const marketing = groups.includes(MARKETING_CATEGORY) ? 'granted' : 'denied';
50
- return {
51
- analytics,
52
- marketing,
53
- performance: analytics
54
- };
55
- };
56
- const createOneTrustConsentProvider = () => ({
57
- name: 'onetrust',
58
- read: readSnapshot,
59
- subscribe(onChange) {
60
- const publish = () => onChange(readSnapshot());
61
- if (typeof window === 'undefined') {
62
- return () => {};
63
- }
64
- // OneTrust fires this on every banner interaction.
65
- window.addEventListener('OneTrustGroupsUpdated', publish);
66
- return () => {
67
- window.removeEventListener('OneTrustGroupsUpdated', publish);
68
- };
69
- }
70
- });
71
- exports.createOneTrustConsentProvider = createOneTrustConsentProvider;
72
- //# sourceMappingURL=oneTrustProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["ANALYTICS_CATEGORY","MARKETING_CATEGORY","readGroups","window","groups","OnetrustActiveGroups","isOneTrustHost","exports","readSnapshot","console","debug","analytics","marketing","performance","includes","createOneTrustConsentProvider","name","read","subscribe","onChange","publish","addEventListener","removeEventListener"],"sources":["../../../../src/privacy/providers/oneTrustProvider.ts"],"sourcesContent":["/**\n * OneTrust provider — DL #218.\n *\n * Lifted from the consent check that used to live inside\n * `utils/analyticsEvents.ts`, with one deliberate behaviour change: that\n * function returned `true` when OneTrust was absent (\"host is responsible for\n * loading OneTrust\"), which on a Shopify storefront meant unconditional\n * default-allow. Absence is no longer this provider's problem — it is only\n * selected when OneTrust is actually on the page, and absence is handled by\n * the gate's own default.\n */\n\nimport type { ConsentProvider, ConsentSnapshot } from '../types';\n\n/** OneTrust's default taxonomy: C0002 is the performance/analytics category. */\nconst ANALYTICS_CATEGORY = 'C0002';\n/** C0004 is targeting/advertising. */\nconst MARKETING_CATEGORY = 'C0004';\n\nconst readGroups = (): string | null => {\n if (typeof window === 'undefined') {\n return null;\n }\n const groups = (window as unknown as { OnetrustActiveGroups?: unknown })\n .OnetrustActiveGroups;\n return typeof groups === 'string' ? groups : null;\n};\n\nexport const isOneTrustHost = (): boolean => readGroups() !== null;\n\nconst readSnapshot = (): ConsentSnapshot => {\n const groups = readGroups();\n if (groups !== null) {\n try {\n console.debug(`[w5-consent] onetrust: active groups \"${groups}\"`);\n } catch {\n /* never break on a console */\n }\n }\n if (groups === null) {\n return {\n analytics: 'unknown',\n marketing: 'unknown',\n performance: 'unknown',\n };\n }\n // OneTrust publishes the *active* groups, so a category that is absent from\n // a string OneTrust has written is a refusal, not silence.\n const analytics = groups.includes(ANALYTICS_CATEGORY) ? 'granted' : 'denied';\n const marketing = groups.includes(MARKETING_CATEGORY) ? 'granted' : 'denied';\n return { analytics, marketing, performance: analytics };\n};\n\nexport const createOneTrustConsentProvider = (): ConsentProvider => ({\n name: 'onetrust',\n\n read: readSnapshot,\n\n subscribe(onChange) {\n const publish = () => onChange(readSnapshot());\n if (typeof window === 'undefined') {\n return () => {};\n }\n // OneTrust fires this on every banner interaction.\n window.addEventListener('OneTrustGroupsUpdated', publish);\n return () => {\n window.removeEventListener('OneTrustGroupsUpdated', publish);\n };\n },\n});\n"],"mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA,MAAMA,kBAAkB,GAAG,OAAO;AAClC;AACA,MAAMC,kBAAkB,GAAG,OAAO;AAElC,MAAMC,UAAU,GAAGA,CAAA,KAAqB;EACtC,IAAI,OAAOC,MAAM,KAAK,WAAW,EAAE;IACjC,OAAO,IAAI;EACb;EACA,MAAMC,MAAM,GAAID,MAAM,CACnBE,oBAAoB;EACvB,OAAO,OAAOD,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAG,IAAI;AACnD,CAAC;AAEM,MAAME,cAAc,GAAGA,CAAA,KAAeJ,UAAU,CAAC,CAAC,KAAK,IAAI;AAACK,OAAA,CAAAD,cAAA,GAAAA,cAAA;AAEnE,MAAME,YAAY,GAAGA,CAAA,KAAuB;EAC1C,MAAMJ,MAAM,GAAGF,UAAU,CAAC,CAAC;EAC3B,IAAIE,MAAM,KAAK,IAAI,EAAE;IACnB,IAAI;MACFK,OAAO,CAACC,KAAK,CAAC,yCAAyCN,MAAM,GAAG,CAAC;IACnE,CAAC,CAAC,MAAM;MACN;IAAA;EAEJ;EACA,IAAIA,MAAM,KAAK,IAAI,EAAE;IACnB,OAAO;MACLO,SAAS,EAAE,SAAS;MACpBC,SAAS,EAAE,SAAS;MACpBC,WAAW,EAAE;IACf,CAAC;EACH;EACA;EACA;EACA,MAAMF,SAAS,GAAGP,MAAM,CAACU,QAAQ,CAACd,kBAAkB,CAAC,GAAG,SAAS,GAAG,QAAQ;EAC5E,MAAMY,SAAS,GAAGR,MAAM,CAACU,QAAQ,CAACb,kBAAkB,CAAC,GAAG,SAAS,GAAG,QAAQ;EAC5E,OAAO;IAAEU,SAAS;IAAEC,SAAS;IAAEC,WAAW,EAAEF;EAAU,CAAC;AACzD,CAAC;AAEM,MAAMI,6BAA6B,GAAGA,CAAA,MAAwB;EACnEC,IAAI,EAAE,UAAU;EAEhBC,IAAI,EAAET,YAAY;EAElBU,SAASA,CAACC,QAAQ,EAAE;IAClB,MAAMC,OAAO,GAAGA,CAAA,KAAMD,QAAQ,CAACX,YAAY,CAAC,CAAC,CAAC;IAC9C,IAAI,OAAOL,MAAM,KAAK,WAAW,EAAE;MACjC,OAAO,MAAM,CAAC,CAAC;IACjB;IACA;IACAA,MAAM,CAACkB,gBAAgB,CAAC,uBAAuB,EAAED,OAAO,CAAC;IACzD,OAAO,MAAM;MACXjB,MAAM,CAACmB,mBAAmB,CAAC,uBAAuB,EAAEF,OAAO,CAAC;IAC9D,CAAC;EACH;AACF,CAAC,CAAC;AAACb,OAAA,CAAAQ,6BAAA,GAAAA,6BAAA","ignoreList":[]}
@@ -1,181 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.isShopifyHost = exports.createShopifyConsentProvider = void 0;
5
- var _types = require("../types");
6
- /**
7
- * Shopify Customer Privacy API provider — DL #218.
8
- *
9
- * Two things about this API shape the provider:
10
- *
11
- * 1. **It is not on the page by default.** `window.Shopify.customerPrivacy` is
12
- * `undefined` until somebody asks for it with `Shopify.loadFeatures`. The
13
- * theme app extension warms it so it is ready before the bundle mounts;
14
- * this provider still requests it, because the extension may not be
15
- * installed and the request is idempotent.
16
- *
17
- * 2. **`visitorConsentCollected` may have already fired.** The bundle executes
18
- * into an already-rendered storefront page (DL #217), so `read()` answers
19
- * from current state and the event is only ever an update.
20
- *
21
- * The region rule is the one judgement encoded here, and it keys off
22
- * `isRegulationEnforced()` rather than `shouldShowBanner()`. The two are not
23
- * interchangeable: the banner reflects what the *merchant* configured, while
24
- * enforcement reflects what the *visitor's jurisdiction* requires. A store with
25
- * an empty consent configuration reports "no banner needed" everywhere,
26
- * including inside the EU.
27
- */
28
-
29
- const CONSENT_FEATURE = {
30
- name: 'consent-tracking-api',
31
- version: '0.1'
32
- };
33
- const log = (...args) => {
34
- try {
35
- console.debug('[w5-consent] shopify:', ...args);
36
- } catch {
37
- /* never break on a console */
38
- }
39
- };
40
- const getShopify = () => {
41
- if (typeof window === 'undefined') {
42
- return null;
43
- }
44
- return window.Shopify ?? null;
45
- };
46
- const isShopifyHost = () => getShopify() !== null;
47
- exports.isShopifyHost = isShopifyHost;
48
- const toState = value => {
49
- if (value === 'yes') {
50
- return 'granted';
51
- }
52
- if (value === 'no') {
53
- return 'denied';
54
- }
55
- return null;
56
- };
57
- const readSnapshot = () => {
58
- var _getShopify;
59
- const privacy = (_getShopify = getShopify()) == null ? void 0 : _getShopify.customerPrivacy;
60
- if (!privacy) {
61
- log('customerPrivacy API not on the page — no answer available (store has no privacy configuration, or loadFeatures has not resolved yet)');
62
- // The API has not loaded (or the store has no privacy configuration at
63
- // all). Not an answer — the gate holds, and the visitor's own action is
64
- // what unlocks the session.
65
- return _types.UNKNOWN_CONSENT;
66
- }
67
- let consent = {};
68
- try {
69
- consent = (privacy.currentVisitorConsent == null ? void 0 : privacy.currentVisitorConsent()) ?? {};
70
- } catch {
71
- // Present but not ready — treat as no answer yet.
72
- }
73
- const explicitAnalytics = toState(consent.analytics);
74
- const explicitMarketing = toState(consent.marketing);
75
- let allowed = false;
76
- try {
77
- allowed = (privacy.analyticsProcessingAllowed == null ? void 0 : privacy.analyticsProcessingAllowed()) === true;
78
- } catch {
79
- allowed = false;
80
- }
81
-
82
- // Is a privacy regulation in force for *this visitor's* region? This is the
83
- // question that matters, and it is not the same question as "is a banner
84
- // being shown" — see the comment on `enforced` below.
85
- let enforced = null;
86
- let regulation = '';
87
- let region = '';
88
- try {
89
- if (typeof privacy.isRegulationEnforced === 'function') {
90
- enforced = privacy.isRegulationEnforced() === true;
91
- }
92
- regulation = (privacy.getRegulation == null ? void 0 : privacy.getRegulation()) ?? '';
93
- region = (privacy.getRegion == null ? void 0 : privacy.getRegion()) ?? '';
94
- } catch {
95
- enforced = null;
96
- }
97
- let bannerRequired = true;
98
- try {
99
- bannerRequired = (privacy.shouldShowBanner == null ? void 0 : privacy.shouldShowBanner()) !== false;
100
- } catch {
101
- bannerRequired = true;
102
- }
103
-
104
- /*
105
- * Measured on a live store from a Frankfurt IP, with no consent recorded:
106
- *
107
- * region 'DEBE' · regulation 'GDPR' · isRegulationEnforced() true
108
- * shouldShowBanner() false · analyticsProcessingAllowed() TRUE
109
- * getShopPrefs() { limit: [] }
110
- *
111
- * Shopify said tracking was allowed for a GDPR-protected visitor who had
112
- * never been asked, because the *merchant* had configured no consent
113
- * preferences. `shouldShowBanner()` and `analyticsProcessingAllowed()` both
114
- * describe the merchant's setup; neither is a statement about a legal basis.
115
- * A merchant's misconfiguration must not become our tracking decision, so
116
- * under an enforced regulation an absent answer stays `unknown` and the gate
117
- * holds — the visitor's own prompt is then the only thing that unlocks them.
118
- */
119
- const permissiveDefault = allowed || !bannerRequired;
120
- const fallbackWhenUnenforceable = permissiveDefault ? 'granted' : 'unknown';
121
- const analytics = explicitAnalytics ?? (enforced === true ? 'unknown' : fallbackWhenUnenforceable);
122
- const marketing = explicitMarketing ?? (enforced === true ? 'unknown' : !bannerRequired ? 'granted' : 'unknown');
123
- log(`read — visitorConsent.analytics=${consent.analytics ?? '(unset)'} ` + `analyticsProcessingAllowed=${allowed} bannerRequired=${bannerRequired} ` + `region=${region || '?'} regulation=${regulation || '?'} enforced=${enforced === null ? 'unavailable' : enforced}` + (enforced === true && explicitAnalytics === null ? ' → regulated and unanswered, holding' : '') + ` ⇒ ${analytics}`);
124
- return {
125
- analytics,
126
- marketing,
127
- // Shopify has no separate performance bucket. Load telemetry carries an
128
- // app name and a session id to a Wix endpoint, so it answers to the same
129
- // answer analytics does rather than riding for free.
130
- performance: analytics
131
- };
132
- };
133
-
134
- /**
135
- * Ask Shopify to load the consent API if it is not already there. Safe to call
136
- * more than once; the callback re-reads whatever state arrives.
137
- */
138
- const requestConsentApi = onReady => {
139
- const shopify = getShopify();
140
- if (!shopify || shopify.customerPrivacy || !shopify.loadFeatures) {
141
- return;
142
- }
143
- try {
144
- log('requesting consent-tracking-api via Shopify.loadFeatures…');
145
- shopify.loadFeatures([CONSENT_FEATURE], error => {
146
- if (error) {
147
- log('loadFeatures failed — gate stays held', error);
148
- return;
149
- }
150
- log('loadFeatures resolved — re-reading consent');
151
- onReady();
152
- });
153
- } catch {
154
- // Storefronts without the feature simply never resolve; the gate stays
155
- // held and engagement remains the only unlock.
156
- }
157
- };
158
- const createShopifyConsentProvider = () => ({
159
- name: 'shopify-customer-privacy',
160
- read: readSnapshot,
161
- subscribe(onChange) {
162
- const publish = () => {
163
- log('visitorConsentCollected — the visitor answered the banner');
164
- onChange(readSnapshot());
165
- };
166
-
167
- // The visitor may have answered the banner before this bundle existed, so
168
- // the event is an update — never the first read.
169
- if (typeof document !== 'undefined') {
170
- document.addEventListener('visitorConsentCollected', publish);
171
- }
172
- requestConsentApi(() => onChange(readSnapshot()));
173
- return () => {
174
- if (typeof document !== 'undefined') {
175
- document.removeEventListener('visitorConsentCollected', publish);
176
- }
177
- };
178
- }
179
- });
180
- exports.createShopifyConsentProvider = createShopifyConsentProvider;
181
- //# sourceMappingURL=shopifyProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_types","require","CONSENT_FEATURE","name","version","log","args","console","debug","getShopify","window","Shopify","isShopifyHost","exports","toState","value","readSnapshot","_getShopify","privacy","customerPrivacy","UNKNOWN_CONSENT","consent","currentVisitorConsent","explicitAnalytics","analytics","explicitMarketing","marketing","allowed","analyticsProcessingAllowed","enforced","regulation","region","isRegulationEnforced","getRegulation","getRegion","bannerRequired","shouldShowBanner","permissiveDefault","fallbackWhenUnenforceable","performance","requestConsentApi","onReady","shopify","loadFeatures","error","createShopifyConsentProvider","read","subscribe","onChange","publish","document","addEventListener","removeEventListener"],"sources":["../../../../src/privacy/providers/shopifyProvider.ts"],"sourcesContent":["/**\n * Shopify Customer Privacy API provider — DL #218.\n *\n * Two things about this API shape the provider:\n *\n * 1. **It is not on the page by default.** `window.Shopify.customerPrivacy` is\n * `undefined` until somebody asks for it with `Shopify.loadFeatures`. The\n * theme app extension warms it so it is ready before the bundle mounts;\n * this provider still requests it, because the extension may not be\n * installed and the request is idempotent.\n *\n * 2. **`visitorConsentCollected` may have already fired.** The bundle executes\n * into an already-rendered storefront page (DL #217), so `read()` answers\n * from current state and the event is only ever an update.\n *\n * The region rule is the one judgement encoded here, and it keys off\n * `isRegulationEnforced()` rather than `shouldShowBanner()`. The two are not\n * interchangeable: the banner reflects what the *merchant* configured, while\n * enforcement reflects what the *visitor's jurisdiction* requires. A store with\n * an empty consent configuration reports \"no banner needed\" everywhere,\n * including inside the EU.\n */\n\nimport {\n UNKNOWN_CONSENT,\n type ConsentProvider,\n type ConsentSnapshot,\n type ConsentState,\n} from '../types';\n\ntype ShopifyConsentValue = 'yes' | 'no' | '' | undefined;\n\ninterface ShopifyVisitorConsent {\n analytics?: ShopifyConsentValue;\n marketing?: ShopifyConsentValue;\n preferences?: ShopifyConsentValue;\n sale_of_data?: ShopifyConsentValue;\n}\n\ninterface ShopifyCustomerPrivacy {\n analyticsProcessingAllowed?: () => boolean;\n marketingAllowed?: () => boolean;\n currentVisitorConsent?: () => ShopifyVisitorConsent;\n shouldShowBanner?: () => boolean;\n /** Whether a privacy regulation applies to this visitor's region. */\n isRegulationEnforced?: () => boolean;\n /** e.g. 'GDPR', 'CCPA'. */\n getRegulation?: () => string;\n /** e.g. 'DEBE' — country + subdivision. */\n getRegion?: () => string;\n}\n\ninterface ShopifyGlobal {\n customerPrivacy?: ShopifyCustomerPrivacy;\n loadFeatures?: (\n features: { name: string; version: string }[],\n callback: (error?: unknown) => void,\n ) => void;\n}\n\nconst CONSENT_FEATURE = { name: 'consent-tracking-api', version: '0.1' };\n\nconst log = (...args: unknown[]): void => {\n try {\n console.debug('[w5-consent] shopify:', ...args);\n } catch {\n /* never break on a console */\n }\n};\n\nconst getShopify = (): ShopifyGlobal | null => {\n if (typeof window === 'undefined') {\n return null;\n }\n return (window as unknown as { Shopify?: ShopifyGlobal }).Shopify ?? null;\n};\n\nexport const isShopifyHost = (): boolean => getShopify() !== null;\n\nconst toState = (value: ShopifyConsentValue): ConsentState | null => {\n if (value === 'yes') {\n return 'granted';\n }\n if (value === 'no') {\n return 'denied';\n }\n return null;\n};\n\nconst readSnapshot = (): ConsentSnapshot => {\n const privacy = getShopify()?.customerPrivacy;\n if (!privacy) {\n log(\n 'customerPrivacy API not on the page — no answer available (store has no privacy configuration, or loadFeatures has not resolved yet)',\n );\n // The API has not loaded (or the store has no privacy configuration at\n // all). Not an answer — the gate holds, and the visitor's own action is\n // what unlocks the session.\n return UNKNOWN_CONSENT;\n }\n\n let consent: ShopifyVisitorConsent = {};\n try {\n consent = privacy.currentVisitorConsent?.() ?? {};\n } catch {\n // Present but not ready — treat as no answer yet.\n }\n\n const explicitAnalytics = toState(consent.analytics);\n const explicitMarketing = toState(consent.marketing);\n\n let allowed = false;\n try {\n allowed = privacy.analyticsProcessingAllowed?.() === true;\n } catch {\n allowed = false;\n }\n\n // Is a privacy regulation in force for *this visitor's* region? This is the\n // question that matters, and it is not the same question as \"is a banner\n // being shown\" — see the comment on `enforced` below.\n let enforced: boolean | null = null;\n let regulation = '';\n let region = '';\n try {\n if (typeof privacy.isRegulationEnforced === 'function') {\n enforced = privacy.isRegulationEnforced() === true;\n }\n regulation = privacy.getRegulation?.() ?? '';\n region = privacy.getRegion?.() ?? '';\n } catch {\n enforced = null;\n }\n\n let bannerRequired = true;\n try {\n bannerRequired = privacy.shouldShowBanner?.() !== false;\n } catch {\n bannerRequired = true;\n }\n\n /*\n * Measured on a live store from a Frankfurt IP, with no consent recorded:\n *\n * region 'DEBE' · regulation 'GDPR' · isRegulationEnforced() true\n * shouldShowBanner() false · analyticsProcessingAllowed() TRUE\n * getShopPrefs() { limit: [] }\n *\n * Shopify said tracking was allowed for a GDPR-protected visitor who had\n * never been asked, because the *merchant* had configured no consent\n * preferences. `shouldShowBanner()` and `analyticsProcessingAllowed()` both\n * describe the merchant's setup; neither is a statement about a legal basis.\n * A merchant's misconfiguration must not become our tracking decision, so\n * under an enforced regulation an absent answer stays `unknown` and the gate\n * holds — the visitor's own prompt is then the only thing that unlocks them.\n */\n const permissiveDefault = allowed || !bannerRequired;\n const fallbackWhenUnenforceable = permissiveDefault ? 'granted' : 'unknown';\n\n const analytics: ConsentState =\n explicitAnalytics ??\n (enforced === true ? 'unknown' : fallbackWhenUnenforceable);\n\n const marketing: ConsentState =\n explicitMarketing ??\n (enforced === true ? 'unknown' : !bannerRequired ? 'granted' : 'unknown');\n\n log(\n `read — visitorConsent.analytics=${consent.analytics ?? '(unset)'} ` +\n `analyticsProcessingAllowed=${allowed} bannerRequired=${bannerRequired} ` +\n `region=${region || '?'} regulation=${regulation || '?'} enforced=${\n enforced === null ? 'unavailable' : enforced\n }` +\n (enforced === true && explicitAnalytics === null\n ? ' → regulated and unanswered, holding'\n : '') +\n ` ⇒ ${analytics}`,\n );\n\n return {\n analytics,\n marketing,\n // Shopify has no separate performance bucket. Load telemetry carries an\n // app name and a session id to a Wix endpoint, so it answers to the same\n // answer analytics does rather than riding for free.\n performance: analytics,\n };\n};\n\n/**\n * Ask Shopify to load the consent API if it is not already there. Safe to call\n * more than once; the callback re-reads whatever state arrives.\n */\nconst requestConsentApi = (onReady: () => void): void => {\n const shopify = getShopify();\n if (!shopify || shopify.customerPrivacy || !shopify.loadFeatures) {\n return;\n }\n try {\n log('requesting consent-tracking-api via Shopify.loadFeatures…');\n shopify.loadFeatures([CONSENT_FEATURE], (error) => {\n if (error) {\n log('loadFeatures failed — gate stays held', error);\n return;\n }\n log('loadFeatures resolved — re-reading consent');\n onReady();\n });\n } catch {\n // Storefronts without the feature simply never resolve; the gate stays\n // held and engagement remains the only unlock.\n }\n};\n\nexport const createShopifyConsentProvider = (): ConsentProvider => ({\n name: 'shopify-customer-privacy',\n\n read: readSnapshot,\n\n subscribe(onChange) {\n const publish = () => {\n log('visitorConsentCollected — the visitor answered the banner');\n onChange(readSnapshot());\n };\n\n // The visitor may have answered the banner before this bundle existed, so\n // the event is an update — never the first read.\n if (typeof document !== 'undefined') {\n document.addEventListener('visitorConsentCollected', publish);\n }\n requestConsentApi(() => onChange(readSnapshot()));\n\n return () => {\n if (typeof document !== 'undefined') {\n document.removeEventListener('visitorConsentCollected', publish);\n }\n };\n },\n});\n"],"mappings":"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","ignoreList":[]}