@wildo-ai/saas-website 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/astro/blog-post-bridge.d.ts +14 -20
- package/dist/esm/astro/blog-post-bridge.d.ts.map +1 -1
- package/dist/esm/astro/blog-post-bridge.js +4 -2
- package/dist/esm/astro/blog-post-bridge.js.map +1 -1
- package/dist/esm/astro/bridge-runtime.d.ts +30 -20
- package/dist/esm/astro/bridge-runtime.d.ts.map +1 -1
- package/dist/esm/astro/bridge-runtime.js +13 -3
- package/dist/esm/astro/bridge-runtime.js.map +1 -1
- package/dist/esm/astro/label-pack-loader.d.ts.map +1 -1
- package/dist/esm/astro/label-pack-loader.js +5 -0
- package/dist/esm/astro/label-pack-loader.js.map +1 -1
- package/dist/esm/config/load-website-config.d.ts.map +1 -1
- package/dist/esm/config/load-website-config.js +2 -1
- package/dist/esm/config/load-website-config.js.map +1 -1
- package/dist/esm/config/wildo-website-config.schemas.d.ts +10 -5
- package/dist/esm/config/wildo-website-config.schemas.d.ts.map +1 -1
- package/dist/esm/config/wildo-website-config.schemas.js +10 -5
- package/dist/esm/config/wildo-website-config.schemas.js.map +1 -1
- package/dist/esm/core/anonymous-session/inbound-contact-form.schema.d.ts +3 -3
- package/dist/esm/core/anonymous-session/inbound-contact-form.schema.d.ts.map +1 -1
- package/dist/esm/core/anonymous-session/inbound-contact-form.schema.js +13 -9
- package/dist/esm/core/anonymous-session/inbound-contact-form.schema.js.map +1 -1
- package/dist/esm/core/anonymous-session/website-anonymous-session-client.d.ts +11 -0
- package/dist/esm/core/anonymous-session/website-anonymous-session-client.d.ts.map +1 -1
- package/dist/esm/core/anonymous-session/website-anonymous-session-client.js +14 -1
- package/dist/esm/core/anonymous-session/website-anonymous-session-client.js.map +1 -1
- package/dist/esm/core/consent/WebsiteConsentBanner.d.ts +6 -0
- package/dist/esm/core/consent/WebsiteConsentBanner.d.ts.map +1 -0
- package/dist/esm/core/consent/WebsiteConsentBanner.js +128 -0
- package/dist/esm/core/consent/WebsiteConsentBanner.js.map +1 -0
- package/dist/esm/core/consent/WebsiteConsentContext.d.ts +85 -0
- package/dist/esm/core/consent/WebsiteConsentContext.d.ts.map +1 -0
- package/dist/esm/core/consent/WebsiteConsentContext.js +89 -0
- package/dist/esm/core/consent/WebsiteConsentContext.js.map +1 -0
- package/dist/esm/core/consent/WebsiteConsentGate.d.ts +27 -0
- package/dist/esm/core/consent/WebsiteConsentGate.d.ts.map +1 -0
- package/dist/esm/core/consent/WebsiteConsentGate.js +9 -0
- package/dist/esm/core/consent/WebsiteConsentGate.js.map +1 -0
- package/dist/esm/core/consent/useWebsiteConsent.d.ts +10 -0
- package/dist/esm/core/consent/useWebsiteConsent.d.ts.map +1 -0
- package/dist/esm/core/consent/useWebsiteConsent.js +17 -0
- package/dist/esm/core/consent/useWebsiteConsent.js.map +1 -0
- package/dist/esm/core/consent/website-consent-storage.d.ts +22 -0
- package/dist/esm/core/consent/website-consent-storage.d.ts.map +1 -0
- package/dist/esm/core/consent/website-consent-storage.js +102 -0
- package/dist/esm/core/consent/website-consent-storage.js.map +1 -0
- package/dist/esm/core/contexts/WebsiteRuntimeContext.d.ts +8 -1
- package/dist/esm/core/contexts/WebsiteRuntimeContext.d.ts.map +1 -1
- package/dist/esm/core/contexts/WebsiteRuntimeContext.js.map +1 -1
- package/dist/esm/core/external-providers/frontend-provider-registry.website.d.ts +1 -2
- package/dist/esm/core/external-providers/frontend-provider-registry.website.d.ts.map +1 -1
- package/dist/esm/core/external-providers/frontend-provider-registry.website.js.map +1 -1
- package/dist/esm/core/external-providers/useWebsiteProviderScripts.d.ts +33 -10
- package/dist/esm/core/external-providers/useWebsiteProviderScripts.d.ts.map +1 -1
- package/dist/esm/core/external-providers/useWebsiteProviderScripts.js +64 -16
- package/dist/esm/core/external-providers/useWebsiteProviderScripts.js.map +1 -1
- package/dist/esm/core/layouts/WebsitePageLayout.d.ts +21 -1
- package/dist/esm/core/layouts/WebsitePageLayout.d.ts.map +1 -1
- package/dist/esm/core/layouts/WebsitePageLayout.js +32 -4
- package/dist/esm/core/layouts/WebsitePageLayout.js.map +1 -1
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/schemas/label-keys/website-consent-label-keys.schemas.d.ts +61 -0
- package/dist/esm/schemas/label-keys/website-consent-label-keys.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/label-keys/website-consent-label-keys.schemas.js +73 -0
- package/dist/esm/schemas/label-keys/website-consent-label-keys.schemas.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -29
- package/src/astro/__tests__/blog-post-bridge.test.tsx +41 -0
- package/src/astro/__tests__/bridge-runtime.test.tsx +25 -0
- package/src/astro/__tests__/label-pack-loader.test.ts +26 -1
- package/src/astro/blog-post-bridge.tsx +18 -22
- package/src/astro/bridge-runtime.tsx +45 -23
- package/src/astro/label-pack-loader.ts +4 -0
- package/src/config/load-website-config.ts +2 -1
- package/src/config/wildo-website-config.schemas.ts +10 -5
- package/src/core/__tests__/WebsitePageLayout.test.tsx +1 -1
- package/src/core/__tests__/website-consent.test.tsx +311 -0
- package/src/core/anonymous-session/__tests__/inbound-contact-form.schema.test.ts +11 -4
- package/src/core/anonymous-session/inbound-contact-form.schema.ts +14 -9
- package/src/core/anonymous-session/website-anonymous-session-client.ts +15 -1
- package/src/core/consent/WebsiteConsentBanner.tsx +222 -0
- package/src/core/consent/WebsiteConsentContext.tsx +164 -0
- package/src/core/consent/WebsiteConsentGate.tsx +34 -0
- package/src/core/consent/useWebsiteConsent.ts +18 -0
- package/src/core/consent/website-consent-storage.ts +116 -0
- package/src/core/contexts/WebsiteRuntimeContext.tsx +8 -1
- package/src/core/external-providers/frontend-provider-registry.website.ts +1 -2
- package/src/core/external-providers/useWebsiteProviderScripts.ts +72 -17
- package/src/core/layouts/WebsitePageLayout.tsx +66 -3
- package/src/index.ts +7 -0
- package/src/schemas/label-keys/__tests__/scaffolded-consent-label-pack.parity.test.ts +71 -0
- package/src/schemas/label-keys/website-consent-label-keys.schemas.ts +78 -0
- package/dist/esm/core/external-providers/provider-scripts.website.d.ts +0 -68
- package/dist/esm/core/external-providers/provider-scripts.website.d.ts.map +0 -1
- package/dist/esm/core/external-providers/provider-scripts.website.js +0 -99
- package/dist/esm/core/external-providers/provider-scripts.website.js.map +0 -1
- package/src/core/external-providers/__tests__/provider-scripts.website.test.ts +0 -146
- package/src/core/external-providers/provider-scripts.website.ts +0 -126
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ConsentPurpose } from '@wildo-ai/saas-models/public-runtime';
|
|
2
|
+
import { type WebsiteLabelKey } from './website-label-key.schemas';
|
|
3
|
+
/**
|
|
4
|
+
* The label keys the framework's visitor consent surface reads (#534).
|
|
5
|
+
*
|
|
6
|
+
* FRAMEWORK-OWNED, like the skip link's key: the consent banner is rendered by `WebsitePageLayout`, not by
|
|
7
|
+
* the site's chrome, so the site does not list these in `chromeLabelKeys`.
|
|
8
|
+
* `composeEffectiveChromeLabelKeys` unions them into the label-pack validator's expected set, so a locale
|
|
9
|
+
* pack missing one fails the build rather than showing a visitor a raw key.
|
|
10
|
+
*
|
|
11
|
+
* They are required of every site, including one that runs no consent-based provider today: the words are
|
|
12
|
+
* cheap, and a site that adds analytics tomorrow must not ship it with an unlabelled — or absent — way to
|
|
13
|
+
* refuse.
|
|
14
|
+
*
|
|
15
|
+
* Purpose names are keyed by the `ConsentPurpose` VALUE and derived from the vocabulary, so a purpose added
|
|
16
|
+
* to it is a missing label in every site's pack at the next build, not a purpose the banner cannot name.
|
|
17
|
+
*/
|
|
18
|
+
export declare enum WebsiteConsentLabelSlot {
|
|
19
|
+
/** Heading of the consent panel. */
|
|
20
|
+
TITLE = "title",
|
|
21
|
+
/** What the panel is for: optional purposes are off until agreed, each chosen separately, changeable later. */
|
|
22
|
+
DESCRIPTION = "description",
|
|
23
|
+
/** Agree to every purpose listed. */
|
|
24
|
+
ACCEPT_ALL = "accept-all",
|
|
25
|
+
/** Agree to none of them — recorded as a choice, so the panel does not return. */
|
|
26
|
+
DECLINE_ALL = "decline-all",
|
|
27
|
+
/** Save exactly the purposes ticked. */
|
|
28
|
+
SAVE = "save",
|
|
29
|
+
/** Re-open the panel to change a choice already made. */
|
|
30
|
+
MANAGE = "manage",
|
|
31
|
+
/**
|
|
32
|
+
* Name of the row covering what runs whatever the visitor chooses.
|
|
33
|
+
*
|
|
34
|
+
* NOT a `ConsentPurpose`, and it must never become one: that vocabulary is what a visitor DECIDES,
|
|
35
|
+
* and this is the thing they are not being asked about. It is shown because a panel listing only
|
|
36
|
+
* the optional purposes cannot answer the question a visitor opened it to answer — what is
|
|
37
|
+
* happening on this site — which is why every specialized consent platform states it.
|
|
38
|
+
*/
|
|
39
|
+
ESSENTIAL_TITLE = "essential-title",
|
|
40
|
+
/** What the always-active row covers, and why its control is checked and cannot be changed. */
|
|
41
|
+
ESSENTIAL_DESCRIPTION = "essential-description"
|
|
42
|
+
}
|
|
43
|
+
/** The fully-composed key for one panel slot. */
|
|
44
|
+
export declare function websiteConsentLabelKey(slot: WebsiteConsentLabelSlot): WebsiteLabelKey;
|
|
45
|
+
/** The fully-composed key naming one consent purpose. */
|
|
46
|
+
export declare function websiteConsentPurposeLabelKey(purpose: ConsentPurpose): WebsiteLabelKey;
|
|
47
|
+
/**
|
|
48
|
+
* The key EXPLAINING one consent purpose — what agreeing to it means for this visitor.
|
|
49
|
+
*
|
|
50
|
+
* The name above answers *what is it called*; this answers *what will happen to me*, and a choice
|
|
51
|
+
* made without the second is not an informed one. "Analytics" beside a tick box is a category, not
|
|
52
|
+
* something a visitor can weigh.
|
|
53
|
+
*
|
|
54
|
+
* Derived from the vocabulary exactly as the name is, so a purpose added to `ConsentPurpose` is a
|
|
55
|
+
* missing label in every site's pack at the next build rather than a row that renders a name with no
|
|
56
|
+
* explanation beneath it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function websiteConsentPurposeDescriptionLabelKey(purpose: ConsentPurpose): WebsiteLabelKey;
|
|
59
|
+
/** Every framework-owned consent key — what a locale pack must carry. Total over both vocabularies. */
|
|
60
|
+
export declare const WEBSITE_CONSENT_LABEL_KEYS: readonly WebsiteLabelKey[];
|
|
61
|
+
//# sourceMappingURL=website-consent-label-keys.schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"website-consent-label-keys.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/schemas/label-keys/website-consent-label-keys.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAoB,MAAM,sCAAsC,CAAC;AAExF,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE1F;;;;;;;;;;;;;;GAcG;AACH,oBAAY,uBAAuB;IACjC,oCAAoC;IACpC,KAAK,UAAU;IACf,+GAA+G;IAC/G,WAAW,gBAAgB;IAC3B,qCAAqC;IACrC,UAAU,eAAe;IACzB,kFAAkF;IAClF,WAAW,gBAAgB;IAC3B,wCAAwC;IACxC,IAAI,SAAS;IACb,yDAAyD;IACzD,MAAM,WAAW;IACjB;;;;;;;OAOG;IACH,eAAe,oBAAoB;IACnC,+FAA+F;IAC/F,qBAAqB,0BAA0B;CAChD;AAID,iDAAiD;AACjD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,uBAAuB,GAAG,eAAe,CAErF;AAED,yDAAyD;AACzD,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,CAEtF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wCAAwC,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,CAEjG;AAED,uGAAuG;AACvG,eAAO,MAAM,0BAA0B,EAAE,SAAS,eAAe,EAI/D,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { CONSENT_PURPOSES } from '@wildo-ai/saas-models/public-runtime';
|
|
2
|
+
import { WebsiteLabelKeySchema } from './website-label-key.schemas.js';
|
|
3
|
+
/**
|
|
4
|
+
* The label keys the framework's visitor consent surface reads (#534).
|
|
5
|
+
*
|
|
6
|
+
* FRAMEWORK-OWNED, like the skip link's key: the consent banner is rendered by `WebsitePageLayout`, not by
|
|
7
|
+
* the site's chrome, so the site does not list these in `chromeLabelKeys`.
|
|
8
|
+
* `composeEffectiveChromeLabelKeys` unions them into the label-pack validator's expected set, so a locale
|
|
9
|
+
* pack missing one fails the build rather than showing a visitor a raw key.
|
|
10
|
+
*
|
|
11
|
+
* They are required of every site, including one that runs no consent-based provider today: the words are
|
|
12
|
+
* cheap, and a site that adds analytics tomorrow must not ship it with an unlabelled — or absent — way to
|
|
13
|
+
* refuse.
|
|
14
|
+
*
|
|
15
|
+
* Purpose names are keyed by the `ConsentPurpose` VALUE and derived from the vocabulary, so a purpose added
|
|
16
|
+
* to it is a missing label in every site's pack at the next build, not a purpose the banner cannot name.
|
|
17
|
+
*/
|
|
18
|
+
export var WebsiteConsentLabelSlot;
|
|
19
|
+
(function (WebsiteConsentLabelSlot) {
|
|
20
|
+
/** Heading of the consent panel. */
|
|
21
|
+
WebsiteConsentLabelSlot["TITLE"] = "title";
|
|
22
|
+
/** What the panel is for: optional purposes are off until agreed, each chosen separately, changeable later. */
|
|
23
|
+
WebsiteConsentLabelSlot["DESCRIPTION"] = "description";
|
|
24
|
+
/** Agree to every purpose listed. */
|
|
25
|
+
WebsiteConsentLabelSlot["ACCEPT_ALL"] = "accept-all";
|
|
26
|
+
/** Agree to none of them — recorded as a choice, so the panel does not return. */
|
|
27
|
+
WebsiteConsentLabelSlot["DECLINE_ALL"] = "decline-all";
|
|
28
|
+
/** Save exactly the purposes ticked. */
|
|
29
|
+
WebsiteConsentLabelSlot["SAVE"] = "save";
|
|
30
|
+
/** Re-open the panel to change a choice already made. */
|
|
31
|
+
WebsiteConsentLabelSlot["MANAGE"] = "manage";
|
|
32
|
+
/**
|
|
33
|
+
* Name of the row covering what runs whatever the visitor chooses.
|
|
34
|
+
*
|
|
35
|
+
* NOT a `ConsentPurpose`, and it must never become one: that vocabulary is what a visitor DECIDES,
|
|
36
|
+
* and this is the thing they are not being asked about. It is shown because a panel listing only
|
|
37
|
+
* the optional purposes cannot answer the question a visitor opened it to answer — what is
|
|
38
|
+
* happening on this site — which is why every specialized consent platform states it.
|
|
39
|
+
*/
|
|
40
|
+
WebsiteConsentLabelSlot["ESSENTIAL_TITLE"] = "essential-title";
|
|
41
|
+
/** What the always-active row covers, and why its control is checked and cannot be changed. */
|
|
42
|
+
WebsiteConsentLabelSlot["ESSENTIAL_DESCRIPTION"] = "essential-description";
|
|
43
|
+
})(WebsiteConsentLabelSlot || (WebsiteConsentLabelSlot = {}));
|
|
44
|
+
const CONSENT_LABEL_KEY_PREFIX = 'website.chrome.consent';
|
|
45
|
+
/** The fully-composed key for one panel slot. */
|
|
46
|
+
export function websiteConsentLabelKey(slot) {
|
|
47
|
+
return WebsiteLabelKeySchema.parse(`${CONSENT_LABEL_KEY_PREFIX}.${slot}`);
|
|
48
|
+
}
|
|
49
|
+
/** The fully-composed key naming one consent purpose. */
|
|
50
|
+
export function websiteConsentPurposeLabelKey(purpose) {
|
|
51
|
+
return WebsiteLabelKeySchema.parse(`${CONSENT_LABEL_KEY_PREFIX}.purpose-${purpose}`);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The key EXPLAINING one consent purpose — what agreeing to it means for this visitor.
|
|
55
|
+
*
|
|
56
|
+
* The name above answers *what is it called*; this answers *what will happen to me*, and a choice
|
|
57
|
+
* made without the second is not an informed one. "Analytics" beside a tick box is a category, not
|
|
58
|
+
* something a visitor can weigh.
|
|
59
|
+
*
|
|
60
|
+
* Derived from the vocabulary exactly as the name is, so a purpose added to `ConsentPurpose` is a
|
|
61
|
+
* missing label in every site's pack at the next build rather than a row that renders a name with no
|
|
62
|
+
* explanation beneath it.
|
|
63
|
+
*/
|
|
64
|
+
export function websiteConsentPurposeDescriptionLabelKey(purpose) {
|
|
65
|
+
return WebsiteLabelKeySchema.parse(`${CONSENT_LABEL_KEY_PREFIX}.purpose-${purpose}-description`);
|
|
66
|
+
}
|
|
67
|
+
/** Every framework-owned consent key — what a locale pack must carry. Total over both vocabularies. */
|
|
68
|
+
export const WEBSITE_CONSENT_LABEL_KEYS = Object.freeze([
|
|
69
|
+
...Object.values(WebsiteConsentLabelSlot).map(websiteConsentLabelKey),
|
|
70
|
+
...CONSENT_PURPOSES.map(websiteConsentPurposeLabelKey),
|
|
71
|
+
...CONSENT_PURPOSES.map(websiteConsentPurposeDescriptionLabelKey),
|
|
72
|
+
]);
|
|
73
|
+
//# sourceMappingURL=website-consent-label-keys.schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"website-consent-label-keys.schemas.js","sourceRoot":"","sources":["../../../../../src/schemas/label-keys/website-consent-label-keys.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExF,OAAO,EAAE,qBAAqB,EAAwB,MAAM,6BAA6B,CAAC;AAE1F;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAN,IAAY,uBAwBX;AAxBD,WAAY,uBAAuB;IACjC,oCAAoC;IACpC,0CAAe,CAAA;IACf,+GAA+G;IAC/G,sDAA2B,CAAA;IAC3B,qCAAqC;IACrC,oDAAyB,CAAA;IACzB,kFAAkF;IAClF,sDAA2B,CAAA;IAC3B,wCAAwC;IACxC,wCAAa,CAAA;IACb,yDAAyD;IACzD,4CAAiB,CAAA;IACjB;;;;;;;OAOG;IACH,8DAAmC,CAAA;IACnC,+FAA+F;IAC/F,0EAA+C,CAAA;AACjD,CAAC,EAxBW,uBAAuB,KAAvB,uBAAuB,QAwBlC;AAED,MAAM,wBAAwB,GAAG,wBAAwB,CAAC;AAE1D,iDAAiD;AACjD,MAAM,UAAU,sBAAsB,CAAC,IAA6B;IAClE,OAAO,qBAAqB,CAAC,KAAK,CAAC,GAAG,wBAAwB,IAAI,IAAI,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,6BAA6B,CAAC,OAAuB;IACnE,OAAO,qBAAqB,CAAC,KAAK,CAAC,GAAG,wBAAwB,YAAY,OAAO,EAAE,CAAC,CAAC;AACvF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wCAAwC,CAAC,OAAuB;IAC9E,OAAO,qBAAqB,CAAC,KAAK,CAAC,GAAG,wBAAwB,YAAY,OAAO,cAAc,CAAC,CAAC;AACnG,CAAC;AAED,uGAAuG;AACvG,MAAM,CAAC,MAAM,0BAA0B,GAA+B,MAAM,CAAC,MAAM,CAAC;IAClF,GAAG,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,GAAG,CAAC,sBAAsB,CAAC;IACrE,GAAG,gBAAgB,CAAC,GAAG,CAAC,6BAA6B,CAAC;IACtD,GAAG,gBAAgB,CAAC,GAAG,CAAC,wCAAwC,CAAC;CAClE,CAAC,CAAC","sourcesContent":["import { ConsentPurpose, CONSENT_PURPOSES } from '@wildo-ai/saas-models/public-runtime';\n\nimport { WebsiteLabelKeySchema, type WebsiteLabelKey } from './website-label-key.schemas';\n\n/**\n * The label keys the framework's visitor consent surface reads (#534).\n *\n * FRAMEWORK-OWNED, like the skip link's key: the consent banner is rendered by `WebsitePageLayout`, not by\n * the site's chrome, so the site does not list these in `chromeLabelKeys`.\n * `composeEffectiveChromeLabelKeys` unions them into the label-pack validator's expected set, so a locale\n * pack missing one fails the build rather than showing a visitor a raw key.\n *\n * They are required of every site, including one that runs no consent-based provider today: the words are\n * cheap, and a site that adds analytics tomorrow must not ship it with an unlabelled — or absent — way to\n * refuse.\n *\n * Purpose names are keyed by the `ConsentPurpose` VALUE and derived from the vocabulary, so a purpose added\n * to it is a missing label in every site's pack at the next build, not a purpose the banner cannot name.\n */\nexport enum WebsiteConsentLabelSlot {\n /** Heading of the consent panel. */\n TITLE = 'title',\n /** What the panel is for: optional purposes are off until agreed, each chosen separately, changeable later. */\n DESCRIPTION = 'description',\n /** Agree to every purpose listed. */\n ACCEPT_ALL = 'accept-all',\n /** Agree to none of them — recorded as a choice, so the panel does not return. */\n DECLINE_ALL = 'decline-all',\n /** Save exactly the purposes ticked. */\n SAVE = 'save',\n /** Re-open the panel to change a choice already made. */\n MANAGE = 'manage',\n /**\n * Name of the row covering what runs whatever the visitor chooses.\n *\n * NOT a `ConsentPurpose`, and it must never become one: that vocabulary is what a visitor DECIDES,\n * and this is the thing they are not being asked about. It is shown because a panel listing only\n * the optional purposes cannot answer the question a visitor opened it to answer — what is\n * happening on this site — which is why every specialized consent platform states it.\n */\n ESSENTIAL_TITLE = 'essential-title',\n /** What the always-active row covers, and why its control is checked and cannot be changed. */\n ESSENTIAL_DESCRIPTION = 'essential-description',\n}\n\nconst CONSENT_LABEL_KEY_PREFIX = 'website.chrome.consent';\n\n/** The fully-composed key for one panel slot. */\nexport function websiteConsentLabelKey(slot: WebsiteConsentLabelSlot): WebsiteLabelKey {\n return WebsiteLabelKeySchema.parse(`${CONSENT_LABEL_KEY_PREFIX}.${slot}`);\n}\n\n/** The fully-composed key naming one consent purpose. */\nexport function websiteConsentPurposeLabelKey(purpose: ConsentPurpose): WebsiteLabelKey {\n return WebsiteLabelKeySchema.parse(`${CONSENT_LABEL_KEY_PREFIX}.purpose-${purpose}`);\n}\n\n/**\n * The key EXPLAINING one consent purpose — what agreeing to it means for this visitor.\n *\n * The name above answers *what is it called*; this answers *what will happen to me*, and a choice\n * made without the second is not an informed one. \"Analytics\" beside a tick box is a category, not\n * something a visitor can weigh.\n *\n * Derived from the vocabulary exactly as the name is, so a purpose added to `ConsentPurpose` is a\n * missing label in every site's pack at the next build rather than a row that renders a name with no\n * explanation beneath it.\n */\nexport function websiteConsentPurposeDescriptionLabelKey(purpose: ConsentPurpose): WebsiteLabelKey {\n return WebsiteLabelKeySchema.parse(`${CONSENT_LABEL_KEY_PREFIX}.purpose-${purpose}-description`);\n}\n\n/** Every framework-owned consent key — what a locale pack must carry. Total over both vocabularies. */\nexport const WEBSITE_CONSENT_LABEL_KEYS: readonly WebsiteLabelKey[] = Object.freeze([\n ...Object.values(WebsiteConsentLabelSlot).map(websiteConsentLabelKey),\n ...CONSENT_PURPOSES.map(websiteConsentPurposeLabelKey),\n ...CONSENT_PURPOSES.map(websiteConsentPurposeDescriptionLabelKey),\n]);\n"]}
|