@owlmeans/marketing-consent 0.1.18-rc.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 (65) hide show
  1. package/README.md +15 -0
  2. package/agent-meta/manifest.json +16 -0
  3. package/agent-meta/skills/marketing-consent/SKILL.md +169 -0
  4. package/build/consts.d.ts +32 -0
  5. package/build/consts.d.ts.map +1 -0
  6. package/build/consts.js +125 -0
  7. package/build/consts.js.map +1 -0
  8. package/build/entrypoints.d.ts +13 -0
  9. package/build/entrypoints.d.ts.map +1 -0
  10. package/build/entrypoints.js +36 -0
  11. package/build/entrypoints.js.map +1 -0
  12. package/build/errors.d.ts +14 -0
  13. package/build/errors.d.ts.map +1 -0
  14. package/build/errors.js +21 -0
  15. package/build/errors.js.map +1 -0
  16. package/build/i18n/be.json +62 -0
  17. package/build/i18n/de.json +62 -0
  18. package/build/i18n/en.json +62 -0
  19. package/build/i18n/es.json +62 -0
  20. package/build/i18n/fr.json +62 -0
  21. package/build/i18n/pl.json +62 -0
  22. package/build/i18n/ru.json +62 -0
  23. package/build/i18n/uk.json +62 -0
  24. package/build/i18n.d.ts +2 -0
  25. package/build/i18n.d.ts.map +1 -0
  26. package/build/i18n.js +21 -0
  27. package/build/i18n.js.map +1 -0
  28. package/build/index.d.ts +8 -0
  29. package/build/index.d.ts.map +1 -0
  30. package/build/index.js +7 -0
  31. package/build/index.js.map +1 -0
  32. package/build/resolve.d.ts +21 -0
  33. package/build/resolve.d.ts.map +1 -0
  34. package/build/resolve.js +96 -0
  35. package/build/resolve.js.map +1 -0
  36. package/build/schemas.d.ts +5 -0
  37. package/build/schemas.d.ts.map +1 -0
  38. package/build/schemas.js +46 -0
  39. package/build/schemas.js.map +1 -0
  40. package/build/types.d.ts +147 -0
  41. package/build/types.d.ts.map +1 -0
  42. package/build/types.js +2 -0
  43. package/build/types.js.map +1 -0
  44. package/package.json +49 -0
  45. package/src/consts.ts +136 -0
  46. package/src/entrypoints.ts +65 -0
  47. package/src/errors.ts +25 -0
  48. package/src/i18n/be.json +62 -0
  49. package/src/i18n/de.json +62 -0
  50. package/src/i18n/en.json +62 -0
  51. package/src/i18n/es.json +62 -0
  52. package/src/i18n/fr.json +62 -0
  53. package/src/i18n/pl.json +62 -0
  54. package/src/i18n/ru.json +62 -0
  55. package/src/i18n/uk.json +62 -0
  56. package/src/i18n.ts +23 -0
  57. package/src/index.ts +7 -0
  58. package/src/resolve.ts +117 -0
  59. package/src/schemas.ts +50 -0
  60. package/src/types.ts +144 -0
  61. package/tests/entrypoints.spec.ts +56 -0
  62. package/tests/i18n.spec.ts +37 -0
  63. package/tests/resolve.spec.ts +62 -0
  64. package/tests/status.spec.ts +118 -0
  65. package/tsconfig.json +8 -0
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ <!-- owlmeans:agent-guidance:start -->
2
+ ## Agent guidance
3
+
4
+ This package ships embedded agent skills under `agent-meta/`. After installing your
5
+ `@owlmeans/*` packages, run the OwlMeans agent-skills installer to place them into
6
+ your project's skill store (`.agents/skills/`):
7
+
8
+ ```sh
9
+ npx @owlmeans/agent-skills@^0.1.18-rc.33
10
+ ```
11
+
12
+ The embedded files are version-matched to this package release. Do not edit them
13
+ directly — they are regenerated on each publish. To contribute guidance edits,
14
+ open a PR against the source monorepo.
15
+ <!-- owlmeans:agent-guidance:end -->
@@ -0,0 +1,16 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "package": "@owlmeans/marketing-consent",
4
+ "version": "0.1.18-rc.0",
5
+ "generatedAt": "2026-09-22T17:37:10.924Z",
6
+ "canonicalRepo": "https://github.com/owlmeans/common",
7
+ "entries": [
8
+ {
9
+ "kind": "skill",
10
+ "name": "marketing-consent",
11
+ "category": "package-specific",
12
+ "file": "skills/marketing-consent/SKILL.md",
13
+ "canonicalPath": ".agents/skills/marketing-consent/SKILL.md"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,169 @@
1
+ ---
2
+ name: marketing-consent
3
+ description: How to use @owlmeans/marketing-consent — the standard 8-key marketing/data/tracker consent catalogue, revision-aware status resolution (new/revised/current, GPC honoring), terms acceptance, and the guarded consent-surface protocol tree (makeMarketingConsentProtocols). Auto-invoked when importing marketing-consent constants/types/schemas, resolving or displaying a person's consent status, saving consent decisions, or reasoning about which legal basis a marketing/tracking consent needs.
4
+ user-invocable: false
5
+ ---
6
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
7
+
8
+ # @owlmeans/marketing-consent
9
+
10
+ **Layer:** Domain (beside `consent`, `payment`, `planning`)
11
+ **Install:** `"@owlmeans/marketing-consent": "^0.1.18-rc.0"` in `dependencies`
12
+ **Sibling:** `@owlmeans/consent` — the cookie-consent widget. This package's two `trackers.*` keys
13
+ carry a `cookieCategory` pointing at that package's `CONSENT_ANALYTICS`/`CONSENT_MARKETING` keys,
14
+ so the two surfaces describe the SAME cookies from two angles: a banner (broad, cookie-law-shaped)
15
+ and a per-purpose settings screen (granular, marketing-shaped). A runtime wiring both must keep a
16
+ `trackers.*` decision and the matching cookie-consent category in sync — this package supplies the
17
+ seam (`MarketingConsentBridge`) but not the wiring itself, which is server- or client-specific.
18
+
19
+ Pure contracts, like `@owlmeans/oauth`: constants, types, AJV schemas, an immutable protocol-tree
20
+ factory, pure resolution functions and an error family. No server, no storage, no React — a
21
+ `@owlmeans/server-marketing-consent` (decision log, handlers) and a
22
+ `@owlmeans/web-marketing-consent` (settings screen, sign-in step) are separate, unbuilt packages
23
+ that would depend on this one.
24
+
25
+ ## The 8 standard keys
26
+
27
+ `STANDARD_MARKETING_CONSENTS` — every key `opt-in`, ordered 10..80, grouped under
28
+ `MC_GROUP_COMMUNICATIONS` / `MC_GROUP_DATA` / `MC_GROUP_TRACKERS`:
29
+
30
+ | Constant | Key | Group | `cookieCategory` | `honorGpc` |
31
+ |---|---|---|---|---|
32
+ | `MC_EMAIL` | `marketing.email` | communications | — | — |
33
+ | `MC_SMS` | `marketing.sms` | communications | — | — |
34
+ | `MC_PHONE` | `marketing.phone` | communications | — | — |
35
+ | `MC_PUSH` | `marketing.push` | communications | — | — |
36
+ | `MC_PROFILING` | `data.profiling` | data | — | — |
37
+ | `MC_PARTNERS` | `data.partners` | data | — | yes |
38
+ | `MC_ANALYTICS` | `trackers.analytics` | trackers | `CONSENT_ANALYTICS` | — |
39
+ | `MC_ADVERTISING` | `trackers.advertising` | trackers | `CONSENT_MARKETING` | yes |
40
+
41
+ `STANDARD_REVISION` is the wording revision every standard definition is stamped with. Bump it (an
42
+ ISO date) whenever the standard wording changes — a saved decision under the old revision becomes
43
+ `'revised'` and is re-asked. Each `labelKey`/`descriptionKey` is `consent.<key>.label` /
44
+ `consent.<key>.description` — the key's own dots, e.g. `consent.trackers.advertising.label` — and
45
+ resolves through `MARKETING_CONSENT_I18N` (`'marketing-consent'`).
46
+
47
+ ## Resolving an application's catalogue — `resolveMarketingConsents(cfg?)`
48
+
49
+ ```ts
50
+ import { resolveMarketingConsents } from '@owlmeans/marketing-consent'
51
+
52
+ const defs = resolveMarketingConsents({
53
+ standard: {
54
+ 'marketing.sms': false, // drop a standard key entirely
55
+ 'marketing.email': { labelKey: 'app.email.label' }, // reword one; key/group never change
56
+ },
57
+ custom: [{ key: 'app.newsletter', group: 'communications', mode: 'opt-in' }],
58
+ links: { 'data.partners': [{ href: 'https://example.com/partners' }] },
59
+ })
60
+ ```
61
+
62
+ Order: start from `STANDARD_MARKETING_CONSENTS`, apply `cfg.standard[key]` (a `false` drops it, an
63
+ object partially overrides it — never `key`/`group`), append `cfg.custom` (defaulted `mode:
64
+ 'opt-in'`, `enabled: true`, `revisedAt: cfg.revisedAt ?? STANDARD_REVISION`), merge `cfg.links[key]`
65
+ into that definition's `links` (concatenated, de-duplicated by `href`), then drop anything with
66
+ `enabled === false` and sort by `order ?? 1000` (ties keep first-seen order — standard before
67
+ custom, declaration order within each).
68
+
69
+ ## Status and the decision table — `consentStatus(defs, decisions, opts?)`
70
+
71
+ For each resolved definition, find the LATEST decision by `key` (max `decidedAt` — `decisions` may
72
+ hold history) and classify:
73
+
74
+ | Saved? | `revisedAt`/`mode` match? | Status |
75
+ |---|---|---|
76
+ | no | — | `new` |
77
+ | yes | no | `revised` |
78
+ | yes | yes | `current` |
79
+
80
+ Initial `granted`:
81
+
82
+ | Status | `opt-in` | `opt-out` |
83
+ |---|---|---|
84
+ | `current` | `saved.granted` | `saved.granted` |
85
+ | `new` | `false` | `true`, unless `honorGpc && opts.gpc` → `false` |
86
+ | `revised` | `false` | `saved.granted` (their last answer persists), unless `honorGpc && opts.gpc` → forced `false` |
87
+
88
+ `updated` is `true` on `revised`, and on `new` when `decisions.length > 0` — i.e. this person has
89
+ answered other consents before, just never this one, so the UI can say "Updated" instead of
90
+ treating a first-ever visitor specially. `view.pending` is `true` iff any item is not `current`.
91
+ `view.terms` is attached only when `opts.termsAcceptedAt` is given.
92
+
93
+ **GPC (`honorGpc`)** only ever suppresses a grant — it never grants something the definition itself
94
+ would deny, and it never overrides an opt-in default (which starts denied anyway). Only
95
+ `data.partners` and `trackers.advertising` carry it in the standard set: those are the two rows
96
+ with a real US "sale/share"/cross-context-advertising opt-out analogue.
97
+
98
+ ## Protocol tree — `makeMarketingConsentProtocols(opts?)`
99
+
100
+ Same shape as `@owlmeans/oauth`'s `makeOAuthProtocols` / `@owlmeans/planning`'s
101
+ `makePlanningProtocols`: one base carrying the guard (and optional gate), four leaves hanging under
102
+ it, plus a parentless sticky screen.
103
+
104
+ ```ts
105
+ const tree = makeMarketingConsentProtocols({
106
+ parent: 'app:account', // OR: guards: 'guard:default', gate: { alias, params? }
107
+ path: '/marketing-consent', // default MARKETING_CONSENT_API_PATH
108
+ screen: { path: '/consent/marketing' }, // default MARKETING_CONSENT_SCREEN_PATH
109
+ })
110
+ // tree.base, tree.status (GET), tree.save (POST), tree.terms (POST), tree.screen (frontend, sticky)
111
+ ```
112
+
113
+ `parent` and `guards`/`gate` are exclusive, the same rule as every other guarded base in this repo:
114
+ a `parent` inherits that route's guards/gate; no `parent` means the base MUST carry `guards` itself
115
+ — status/save/terms always act on the caller's own saved decisions, so there is no ungated shape.
116
+ Passing neither throws `SyntaxError` at declaration time (a wiring mistake, not a runtime one).
117
+ `save`'s request body is schema-checked (`SaveMarketingConsentSchema` — 1..64 decisions, `source`
118
+ one of `'sign-in' | 'settings' | 'cookie'`, never `'api'`); `terms`'s is `TermsAcceptanceSchema`.
119
+
120
+ ## Errors
121
+
122
+ `MarketingConsentError` (family `marketing-consent:*`, base `ResilientError`) and
123
+ `UnknownMarketingConsentError` — raise the latter when a `SaveMarketingConsentRequest` decision
124
+ names a key that `resolveMarketingConsents` did not produce for this application; do not silently
125
+ drop it, because a dropped decision is a decision the person believes they made and did not.
126
+
127
+ ## Legal matrix
128
+
129
+ Rows named `Key` and jurisdiction citations for what each consent gates. **This is not legal
130
+ advice** — article numbers are believed correct as of September 2026 and must be reverified before
131
+ being relied on. `honorGpc` in the standard set is what wires the Global Privacy Control column
132
+ below into `consentStatus`'s decision table.
133
+
134
+ | Key | EU / PL / DE / FR | US |
135
+ |---|---|---|
136
+ | `marketing.email` | ePrivacy Art.13(1); PL Prawo komunikacji elektronicznej art.398 (per-channel consent, in force since 10 Nov 2024); DE UWG §7(2) Nr.2; FR CPCE L.34-5 | CAN-SPAM (opt-out baseline; this package defaults to the stricter opt-in) |
137
+ | `marketing.sms` | same as email | TCPA prior express written consent; revocation by any reasonable means (FCC rule effective 11 Apr 2025); must not condition purchase on consent |
138
+ | `marketing.phone` | PKE art.398; DE UWG §7(2) Nr.1 + §7a (written proof kept 5 years after each use) | TCPA + Telemarketing Sales Rule / Do-Not-Call |
139
+ | `marketing.push` | ePrivacy Art.5(3)/13; PKE art.398/399; DE TDDDG §25 | OS-level permission is separate; this consent gates the SEND, not the OS permission |
140
+ | `data.profiling` | GDPR Art.6(1)(a) taken as the lawful basis (worst case vs. legitimate interest), Art.21(2)-(3) right to object, Art.22 no solely-automated decisions | state privacy laws' opt-out of profiling/targeted advertising |
141
+ | `data.partners` | GDPR Art.6(1)(a) + Art.13(1)(e) recipients disclosure; CNIL 2022 guidance on partner lists for e-prospecting | CCPA/CPRA "sale/share" opt-out; honor Global Privacy Control (`honorGpc`) |
142
+ | `trackers.analytics` | ePrivacy Art.5(3); PL PKE art.399; DE TDDDG §25; CNIL cookie guidance; Planet49 (CJEU C-673/17) bars pre-ticked boxes | CCPA "sharing" definition can include analytics cookies |
143
+ | `trackers.advertising` | same as analytics, plus Google's EU User Consent Policy / Consent Mode v2 (`ad_user_data`, `ad_personalization`) | CCPA cross-context behavioral-advertising opt-out; GPC |
144
+
145
+ Consent must be freely given (GDPR Art.7(4) — nothing here may be a condition of using the
146
+ product), granular per purpose (EDPB Guidelines 05/2020), an active opt-in with no pre-ticked boxes
147
+ (Recital 32, Planet49), withdrawable as easily as it was given (Art.7(3)), and demonstrable
148
+ (Art.7(1) — this is why a future `@owlmeans/server-marketing-consent` keeps an append-only decision
149
+ log rather than overwriting `MarketingConsentDecision` rows in place).
150
+
151
+ ## Key exports
152
+
153
+ | Export | Description |
154
+ |---|---|
155
+ | `MC_EMAIL` … `MC_ADVERTISING` | The 8 standard consent keys |
156
+ | `MC_GROUP_COMMUNICATIONS` · `MC_GROUP_DATA` · `MC_GROUP_TRACKERS` | The 3 groups |
157
+ | `STANDARD_REVISION` · `STANDARD_MARKETING_CONSENTS` | The wording revision and the standard catalogue |
158
+ | `MARKETING_CONSENT_SERVICE` · `MARKETING_CONSENT_I18N` · `MARKETING_CONSENT_API_PATH` · `MARKETING_CONSENT_SCREEN_PATH` | Service/i18n/wire identifiers |
159
+ | `MARKETING_CONSENT_BASE` · `MARKETING_CONSENT_STATUS` · `MARKETING_CONSENT_SAVE` · `MARKETING_CONSENT_TERMS` · `MARKETING_CONSENT_SCREEN` | Protocol-tree aliases |
160
+ | `resolveMarketingConsents(cfg?)` · `consentStatus(defs, decisions, opts?)` | Pure resolution |
161
+ | `makeMarketingConsentProtocols(opts?)` | The protocol tree |
162
+ | `SaveMarketingConsentSchema` · `TermsAcceptanceSchema` | AJV request schemas |
163
+ | `MarketingConsentError` · `UnknownMarketingConsentError` | Errors |
164
+ | Types | `MarketingConsentDefinition`, `MarketingConsentConfig`, `MarketingConsentDecision`, `MarketingConsentStatusView`/`Item`, `TermsAcceptance`, `SaveMarketingConsentRequest`, `MarketingConsentBridge`, `MarketingConsentEntrypointOptions`/`Entrypoints` |
165
+
166
+ Importing `@owlmeans/marketing-consent` also registers its 8-language i18n bundle
167
+ (`en`/`pl`/`ru`/`be`/`uk`/`es`/`de`/`fr` — `CONSENT_LOCALES`, one more than `@owlmeans/i18n`'s own
168
+ `SUPPORTED_LNGS` because it shares `fr` with `@owlmeans/consent`) as a side effect, the same as
169
+ `@owlmeans/payment` and `@owlmeans/planning` do.
@@ -0,0 +1,32 @@
1
+ import type { MarketingConsentDefinition } from './types.js';
2
+ export declare const MC_EMAIL = "marketing.email";
3
+ export declare const MC_SMS = "marketing.sms";
4
+ export declare const MC_PHONE = "marketing.phone";
5
+ export declare const MC_PUSH = "marketing.push";
6
+ export declare const MC_PROFILING = "data.profiling";
7
+ export declare const MC_PARTNERS = "data.partners";
8
+ export declare const MC_ANALYTICS = "trackers.analytics";
9
+ export declare const MC_ADVERTISING = "trackers.advertising";
10
+ export declare const MC_GROUP_COMMUNICATIONS = "communications";
11
+ export declare const MC_GROUP_DATA = "data";
12
+ export declare const MC_GROUP_TRACKERS = "trackers";
13
+ /**
14
+ * The wording revision the standard catalogue was last updated at.
15
+ *
16
+ * Bump this (and any `revisedAt` it seeds) whenever the standard wording changes — a person who
17
+ * already answered under an earlier revision is then asked again (`consentStatus`'s `'revised'`
18
+ * status), never silently carried over onto new language.
19
+ */
20
+ export declare const STANDARD_REVISION = "2026-09-22";
21
+ /** The 8 standard marketing/data/tracker consents, in their default order. */
22
+ export declare const STANDARD_MARKETING_CONSENTS: MarketingConsentDefinition[];
23
+ export declare const MARKETING_CONSENT_SERVICE = "marketing-consent";
24
+ export declare const MARKETING_CONSENT_I18N = "marketing-consent";
25
+ export declare const MARKETING_CONSENT_API_PATH = "/marketing-consent";
26
+ export declare const MARKETING_CONSENT_SCREEN_PATH = "/consent/marketing";
27
+ export declare const MARKETING_CONSENT_BASE = "marketing-consent";
28
+ export declare const MARKETING_CONSENT_STATUS = "marketing-consent:status";
29
+ export declare const MARKETING_CONSENT_SAVE = "marketing-consent:save";
30
+ export declare const MARKETING_CONSENT_TERMS = "marketing-consent:terms";
31
+ export declare const MARKETING_CONSENT_SCREEN = "marketing-consent:screen";
32
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAI5D,eAAO,MAAM,QAAQ,oBAAoB,CAAA;AACzC,eAAO,MAAM,MAAM,kBAAkB,CAAA;AACrC,eAAO,MAAM,QAAQ,oBAAoB,CAAA;AACzC,eAAO,MAAM,OAAO,mBAAmB,CAAA;AACvC,eAAO,MAAM,YAAY,mBAAmB,CAAA;AAC5C,eAAO,MAAM,WAAW,kBAAkB,CAAA;AAC1C,eAAO,MAAM,YAAY,uBAAuB,CAAA;AAChD,eAAO,MAAM,cAAc,yBAAyB,CAAA;AAIpD,eAAO,MAAM,uBAAuB,mBAAmB,CAAA;AACvD,eAAO,MAAM,aAAa,SAAS,CAAA;AACnC,eAAO,MAAM,iBAAiB,aAAa,CAAA;AAE3C;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,eAAe,CAAA;AAO7C,8EAA8E;AAC9E,eAAO,MAAM,2BAA2B,EAAE,0BAA0B,EAqFnE,CAAA;AAID,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAC5D,eAAO,MAAM,sBAAsB,sBAAsB,CAAA;AACzD,eAAO,MAAM,0BAA0B,uBAAuB,CAAA;AAC9D,eAAO,MAAM,6BAA6B,uBAAuB,CAAA;AAIjE,eAAO,MAAM,sBAAsB,sBAAsB,CAAA;AACzD,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAClE,eAAO,MAAM,sBAAsB,2BAA2B,CAAA;AAC9D,eAAO,MAAM,uBAAuB,4BAA4B,CAAA;AAChE,eAAO,MAAM,wBAAwB,6BAA6B,CAAA"}
@@ -0,0 +1,125 @@
1
+ import { CONSENT_ANALYTICS, CONSENT_MARKETING } from '@owlmeans/consent';
2
+ // --- Consent keys ------------------------------------------------------------------------------
3
+ export const MC_EMAIL = 'marketing.email';
4
+ export const MC_SMS = 'marketing.sms';
5
+ export const MC_PHONE = 'marketing.phone';
6
+ export const MC_PUSH = 'marketing.push';
7
+ export const MC_PROFILING = 'data.profiling';
8
+ export const MC_PARTNERS = 'data.partners';
9
+ export const MC_ANALYTICS = 'trackers.analytics';
10
+ export const MC_ADVERTISING = 'trackers.advertising';
11
+ // --- Consent groups ------------------------------------------------------------------------------
12
+ export const MC_GROUP_COMMUNICATIONS = 'communications';
13
+ export const MC_GROUP_DATA = 'data';
14
+ export const MC_GROUP_TRACKERS = 'trackers';
15
+ /**
16
+ * The wording revision the standard catalogue was last updated at.
17
+ *
18
+ * Bump this (and any `revisedAt` it seeds) whenever the standard wording changes — a person who
19
+ * already answered under an earlier revision is then asked again (`consentStatus`'s `'revised'`
20
+ * status), never silently carried over onto new language.
21
+ */
22
+ export const STANDARD_REVISION = '2026-09-22';
23
+ /** `'marketing.email'` -> `'consent.marketing.email.label'` — the key's own dots become the i18n
24
+ * path's dots, so the bundle nests exactly as the key reads (`src/i18n/en.json`'s `consent.*`). */
25
+ const labelOf = (key) => `consent.${key}.label`;
26
+ const descriptionOf = (key) => `consent.${key}.description`;
27
+ /** The 8 standard marketing/data/tracker consents, in their default order. */
28
+ export const STANDARD_MARKETING_CONSENTS = [
29
+ {
30
+ key: MC_EMAIL,
31
+ group: MC_GROUP_COMMUNICATIONS,
32
+ mode: 'opt-in',
33
+ enabled: true,
34
+ revisedAt: STANDARD_REVISION,
35
+ labelKey: labelOf(MC_EMAIL),
36
+ descriptionKey: descriptionOf(MC_EMAIL),
37
+ order: 10,
38
+ },
39
+ {
40
+ key: MC_SMS,
41
+ group: MC_GROUP_COMMUNICATIONS,
42
+ mode: 'opt-in',
43
+ enabled: true,
44
+ revisedAt: STANDARD_REVISION,
45
+ labelKey: labelOf(MC_SMS),
46
+ descriptionKey: descriptionOf(MC_SMS),
47
+ order: 20,
48
+ },
49
+ {
50
+ key: MC_PHONE,
51
+ group: MC_GROUP_COMMUNICATIONS,
52
+ mode: 'opt-in',
53
+ enabled: true,
54
+ revisedAt: STANDARD_REVISION,
55
+ labelKey: labelOf(MC_PHONE),
56
+ descriptionKey: descriptionOf(MC_PHONE),
57
+ order: 30,
58
+ },
59
+ {
60
+ key: MC_PUSH,
61
+ group: MC_GROUP_COMMUNICATIONS,
62
+ mode: 'opt-in',
63
+ enabled: true,
64
+ revisedAt: STANDARD_REVISION,
65
+ labelKey: labelOf(MC_PUSH),
66
+ descriptionKey: descriptionOf(MC_PUSH),
67
+ order: 40,
68
+ },
69
+ {
70
+ key: MC_PROFILING,
71
+ group: MC_GROUP_DATA,
72
+ mode: 'opt-in',
73
+ enabled: true,
74
+ revisedAt: STANDARD_REVISION,
75
+ labelKey: labelOf(MC_PROFILING),
76
+ descriptionKey: descriptionOf(MC_PROFILING),
77
+ order: 50,
78
+ },
79
+ {
80
+ key: MC_PARTNERS,
81
+ group: MC_GROUP_DATA,
82
+ mode: 'opt-in',
83
+ enabled: true,
84
+ revisedAt: STANDARD_REVISION,
85
+ labelKey: labelOf(MC_PARTNERS),
86
+ descriptionKey: descriptionOf(MC_PARTNERS),
87
+ honorGpc: true,
88
+ order: 60,
89
+ },
90
+ {
91
+ key: MC_ANALYTICS,
92
+ group: MC_GROUP_TRACKERS,
93
+ mode: 'opt-in',
94
+ enabled: true,
95
+ revisedAt: STANDARD_REVISION,
96
+ labelKey: labelOf(MC_ANALYTICS),
97
+ descriptionKey: descriptionOf(MC_ANALYTICS),
98
+ cookieCategory: CONSENT_ANALYTICS,
99
+ order: 70,
100
+ },
101
+ {
102
+ key: MC_ADVERTISING,
103
+ group: MC_GROUP_TRACKERS,
104
+ mode: 'opt-in',
105
+ enabled: true,
106
+ revisedAt: STANDARD_REVISION,
107
+ labelKey: labelOf(MC_ADVERTISING),
108
+ descriptionKey: descriptionOf(MC_ADVERTISING),
109
+ cookieCategory: CONSENT_MARKETING,
110
+ honorGpc: true,
111
+ order: 80,
112
+ },
113
+ ];
114
+ // --- Service / i18n / wire identifiers -----------------------------------------------------
115
+ export const MARKETING_CONSENT_SERVICE = 'marketing-consent';
116
+ export const MARKETING_CONSENT_I18N = 'marketing-consent';
117
+ export const MARKETING_CONSENT_API_PATH = '/marketing-consent';
118
+ export const MARKETING_CONSENT_SCREEN_PATH = '/consent/marketing';
119
+ // --- Protocol tree aliases -----------------------------------------------------------------
120
+ export const MARKETING_CONSENT_BASE = 'marketing-consent';
121
+ export const MARKETING_CONSENT_STATUS = 'marketing-consent:status';
122
+ export const MARKETING_CONSENT_SAVE = 'marketing-consent:save';
123
+ export const MARKETING_CONSENT_TERMS = 'marketing-consent:terms';
124
+ export const MARKETING_CONSENT_SCREEN = 'marketing-consent:screen';
125
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { MarketingConsentEntrypointOptions, MarketingConsentEntrypoints } from './types.js';
2
+ /**
3
+ * The guarded marketing-consent surface: read the current status, save decisions, record a
4
+ * terms acceptance — plus the top-level screen that hosts them.
5
+ *
6
+ * A base with a `parent` inherits that parent's guards and gate, the same as every other nested
7
+ * route. A base with no `parent` MUST carry `opts.guards` itself — status/save/terms always act
8
+ * on the caller's own saved decisions, so there is no ungated shape; neither given is a
9
+ * declaration error, not a runtime one, because it means the application forgot to mount this
10
+ * tree at all.
11
+ */
12
+ export declare const makeMarketingConsentProtocols: (opts?: MarketingConsentEntrypointOptions) => MarketingConsentEntrypoints;
13
+ //# sourceMappingURL=entrypoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,iCAAiC,EAAE,2BAA2B,EAE/D,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,UAAU,iCAAiC,KAAQ,2BAyC5F,CAAA"}
@@ -0,0 +1,36 @@
1
+ import { contract, openProtocol, protocol, typed } from '@owlmeans/entrypoint';
2
+ import { frontend, route, RouteMethod } from '@owlmeans/route';
3
+ import { MARKETING_CONSENT_API_PATH, MARKETING_CONSENT_BASE, MARKETING_CONSENT_SAVE, MARKETING_CONSENT_SCREEN, MARKETING_CONSENT_SCREEN_PATH, MARKETING_CONSENT_STATUS, MARKETING_CONSENT_TERMS, } from './consts.js';
4
+ import { SaveMarketingConsentSchema, TermsAcceptanceSchema } from './schemas.js';
5
+ /**
6
+ * The guarded marketing-consent surface: read the current status, save decisions, record a
7
+ * terms acceptance — plus the top-level screen that hosts them.
8
+ *
9
+ * A base with a `parent` inherits that parent's guards and gate, the same as every other nested
10
+ * route. A base with no `parent` MUST carry `opts.guards` itself — status/save/terms always act
11
+ * on the caller's own saved decisions, so there is no ungated shape; neither given is a
12
+ * declaration error, not a runtime one, because it means the application forgot to mount this
13
+ * tree at all.
14
+ */
15
+ export const makeMarketingConsentProtocols = (opts = {}) => {
16
+ const path = opts.path ?? MARKETING_CONSENT_API_PATH;
17
+ if (opts.parent == null && opts.guards == null) {
18
+ throw new SyntaxError('marketing-consent: guarded routes need either a parent or explicit guards');
19
+ }
20
+ const base = opts.parent != null
21
+ ? openProtocol(route(MARKETING_CONSENT_BASE, path, { parent: opts.parent }))
22
+ : openProtocol(route(MARKETING_CONSENT_BASE, path), {
23
+ guards: opts.guards,
24
+ ...(opts.gate != null ? { gate: opts.gate } : {}),
25
+ });
26
+ return {
27
+ base,
28
+ status: protocol(route(MARKETING_CONSENT_STATUS, '/status', { parent: MARKETING_CONSENT_BASE, method: RouteMethod.GET }), contract(typed())),
29
+ save: protocol(route(MARKETING_CONSENT_SAVE, '/save', { parent: MARKETING_CONSENT_BASE, method: RouteMethod.POST }), contract.request({ body: typed(SaveMarketingConsentSchema) }, typed())),
30
+ terms: protocol(route(MARKETING_CONSENT_TERMS, '/terms', { parent: MARKETING_CONSENT_BASE, method: RouteMethod.POST }), contract.request({ body: typed(TermsAcceptanceSchema) }, typed())),
31
+ // A top-level frontend screen, no parent, `sticky` so the router keeps it regardless of
32
+ // `cfg.service` filtering — the same shape as `@owlmeans/oauth`'s three consent screens.
33
+ screen: openProtocol(route(MARKETING_CONSENT_SCREEN, opts.screen?.path ?? MARKETING_CONSENT_SCREEN_PATH, frontend({ parent: opts.screen?.parent })), { sticky: true }),
34
+ };
35
+ };
36
+ //# sourceMappingURL=entrypoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoints.js","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EACL,0BAA0B,EAAE,sBAAsB,EAAE,sBAAsB,EAC1E,wBAAwB,EAAE,6BAA6B,EAAE,wBAAwB,EACjF,uBAAuB,GACxB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAMhF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,IAAI,GAAsC,EAAE,EAA+B,EAAE;IACzH,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAA;IAEpD,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC/C,MAAM,IAAI,WAAW,CAAC,2EAA2E,CAAC,CAAA;IACpG,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI;QAC9B,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,sBAAsB,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,sBAAsB,EAAE,IAAI,CAAC,EAAE;YAChD,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAC,CAAA;IAEN,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,QAAQ,CACd,KAAK,CAAC,wBAAwB,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC,EACvG,QAAQ,CAAC,KAAK,EAA8B,CAAC,CAC9C;QACD,IAAI,EAAE,QAAQ,CACZ,KAAK,CAAC,sBAAsB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,EACpG,QAAQ,CAAC,OAAO,CACd,EAAE,IAAI,EAAE,KAAK,CAA8B,0BAA0B,CAAC,EAAE,EACxE,KAAK,EAAuD,CAC7D,CACF;QACD,KAAK,EAAE,QAAQ,CACb,KAAK,CAAC,uBAAuB,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,EACtG,QAAQ,CAAC,OAAO,CACd,EAAE,IAAI,EAAE,KAAK,CAAkB,qBAAqB,CAAC,EAAE,EACvD,KAAK,EAAmB,CACzB,CACF;QACD,wFAAwF;QACxF,yFAAyF;QACzF,MAAM,EAAE,YAAY,CAClB,KAAK,CAAC,wBAAwB,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,6BAA6B,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAC9H,EAAE,MAAM,EAAE,IAAI,EAAE,CACjB;KACF,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { ResilientError } from '@owlmeans/error';
2
+ /** The marketing-consent error family — refusals a status/save/terms handler raises. */
3
+ export declare class MarketingConsentError extends ResilientError {
4
+ static typeName: string;
5
+ constructor(message?: string);
6
+ }
7
+ /** A `SaveMarketingConsentRequest` decision named a key that no resolved definition carries. */
8
+ export declare class UnknownMarketingConsentError extends MarketingConsentError {
9
+ static typeName: string;
10
+ /** A bad request, not a server fault — the caller named a key this deployment does not have. */
11
+ static httpStatus: number;
12
+ constructor(message?: string);
13
+ }
14
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,wFAAwF;AACxF,qBAAa,qBAAsB,SAAQ,cAAc;IACvD,OAAuB,QAAQ,EAAE,MAAM,CAA0B;IAEjE,YAAY,OAAO,GAAE,MAAgB,EAEpC;CACF;AAED,gGAAgG;AAChG,qBAAa,4BAA6B,SAAQ,qBAAqB;IACrE,OAAuB,QAAQ,EAAE,MAAM,CAA6C;IACpF,gGAAgG;IAChG,OAAc,UAAU,SAAM;IAE9B,YAAY,OAAO,GAAE,MAAgB,EAGpC;CACF"}
@@ -0,0 +1,21 @@
1
+ import { ResilientError } from '@owlmeans/error';
2
+ /** The marketing-consent error family — refusals a status/save/terms handler raises. */
3
+ export class MarketingConsentError extends ResilientError {
4
+ static typeName = 'MarketingConsentError';
5
+ constructor(message = 'error') {
6
+ super(MarketingConsentError.typeName, `marketing-consent:${message}`);
7
+ }
8
+ }
9
+ /** A `SaveMarketingConsentRequest` decision named a key that no resolved definition carries. */
10
+ export class UnknownMarketingConsentError extends MarketingConsentError {
11
+ static typeName = `${MarketingConsentError.typeName}Unknown`;
12
+ /** A bad request, not a server fault — the caller named a key this deployment does not have. */
13
+ static httpStatus = 400;
14
+ constructor(message = 'error') {
15
+ super(`unknown:${message}`);
16
+ this.type = UnknownMarketingConsentError.typeName;
17
+ }
18
+ }
19
+ ResilientError.registerErrorClass(MarketingConsentError);
20
+ ResilientError.registerErrorClass(UnknownMarketingConsentError);
21
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,wFAAwF;AACxF,MAAM,OAAO,qBAAsB,SAAQ,cAAc;IAChD,MAAM,CAAU,QAAQ,GAAW,uBAAuB,CAAA;IAEjE,YAAY,OAAO,GAAW,OAAO;QACnC,KAAK,CAAC,qBAAqB,CAAC,QAAQ,EAAE,qBAAqB,OAAO,EAAE,CAAC,CAAA;IACvE,CAAC;CACF;AAED,gGAAgG;AAChG,MAAM,OAAO,4BAA6B,SAAQ,qBAAqB;IAC9D,MAAM,CAAU,QAAQ,GAAW,GAAG,qBAAqB,CAAC,QAAQ,SAAS,CAAA;IACpF,gGAAgG;IACzF,MAAM,CAAC,UAAU,GAAG,GAAG,CAAA;IAE9B,YAAY,OAAO,GAAW,OAAO;QACnC,KAAK,CAAC,WAAW,OAAO,EAAE,CAAC,CAAA;QAC3B,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC,QAAQ,CAAA;IACnD,CAAC;CACF;AAED,cAAc,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;AACxD,cAAc,CAAC,kBAAkB,CAAC,4BAA4B,CAAC,CAAA"}
@@ -0,0 +1,62 @@
1
+ {
2
+ "group": {
3
+ "communications": {
4
+ "title": "Камунікацыі",
5
+ "description": "Як мы з вамі звязваемся."
6
+ },
7
+ "data": {
8
+ "title": "Выкарыстанне дадзеных",
9
+ "description": "Як выкарыстоўваюцца і перадаюцца вашы дадзеныя."
10
+ },
11
+ "trackers": {
12
+ "title": "Трэкеры",
13
+ "description": "Аналітычныя і рэкламныя тэхналогіі."
14
+ }
15
+ },
16
+ "consent": {
17
+ "marketing": {
18
+ "email": {
19
+ "label": "Прапановы і навіны на email",
20
+ "description": "Навіны пра прадукт, прапановы і абнаўленні па электроннай пошце."
21
+ },
22
+ "sms": {
23
+ "label": "SMS-паведамленні",
24
+ "description": "Прапановы і абнаўленні ў выглядзе тэкставых паведамленняў."
25
+ },
26
+ "phone": {
27
+ "label": "Тэлефонныя званкі",
28
+ "description": "Прапановы і абнаўленні па тэлефоне."
29
+ },
30
+ "push": {
31
+ "label": "Push-паведамленні",
32
+ "description": "Прапановы і абнаўленні ў выглядзе push-паведамленняў."
33
+ }
34
+ },
35
+ "data": {
36
+ "profiling": {
37
+ "label": "Персаналізацыя",
38
+ "description": "Выкарыстанне вашай актыўнасці для персаналізацыі таго, што вы бачыце."
39
+ },
40
+ "partners": {
41
+ "label": "Перадача партнёрам",
42
+ "description": "Перадача вашых дадзеных абраным партнёрам для іх уласнага маркетынгу."
43
+ }
44
+ },
45
+ "trackers": {
46
+ "analytics": {
47
+ "label": "Аналітычныя cookie",
48
+ "description": "Cookie, якія дапамагаюць зразумець, як выкарыстоўваецца прадукт."
49
+ },
50
+ "advertising": {
51
+ "label": "Рэкламныя cookie",
52
+ "description": "Cookie, якія выкарыстоўваюцца для вымярэння і персаналізацыі рэкламы."
53
+ }
54
+ }
55
+ },
56
+ "link": {
57
+ "default": "Даведацца больш"
58
+ },
59
+ "errors": {
60
+ "unknown": "Невядомая згода: {{key}}"
61
+ }
62
+ }
@@ -0,0 +1,62 @@
1
+ {
2
+ "group": {
3
+ "communications": {
4
+ "title": "Kommunikation",
5
+ "description": "Wie wir Sie kontaktieren."
6
+ },
7
+ "data": {
8
+ "title": "Datennutzung",
9
+ "description": "Wie Ihre Daten verwendet und weitergegeben werden."
10
+ },
11
+ "trackers": {
12
+ "title": "Tracker",
13
+ "description": "Analyse- und Werbetechnologien."
14
+ }
15
+ },
16
+ "consent": {
17
+ "marketing": {
18
+ "email": {
19
+ "label": "Angebote und Neuigkeiten per E-Mail",
20
+ "description": "Produktneuigkeiten, Angebote und Updates per E-Mail."
21
+ },
22
+ "sms": {
23
+ "label": "SMS-Nachrichten",
24
+ "description": "Angebote und Updates per Textnachricht."
25
+ },
26
+ "phone": {
27
+ "label": "Telefonanrufe",
28
+ "description": "Angebote und Updates per Telefonanruf."
29
+ },
30
+ "push": {
31
+ "label": "Push-Benachrichtigungen",
32
+ "description": "Angebote und Updates als Push-Benachrichtigungen."
33
+ }
34
+ },
35
+ "data": {
36
+ "profiling": {
37
+ "label": "Personalisierung",
38
+ "description": "Nutzung Ihrer Aktivität, um Inhalte für Sie zu personalisieren."
39
+ },
40
+ "partners": {
41
+ "label": "Weitergabe an Partner",
42
+ "description": "Weitergabe Ihrer Daten an ausgewählte Partner für deren eigenes Marketing."
43
+ }
44
+ },
45
+ "trackers": {
46
+ "analytics": {
47
+ "label": "Analyse-Cookies",
48
+ "description": "Cookies, die uns helfen zu verstehen, wie das Produkt genutzt wird."
49
+ },
50
+ "advertising": {
51
+ "label": "Werbe-Cookies",
52
+ "description": "Cookies zur Messung und Personalisierung von Werbung."
53
+ }
54
+ }
55
+ },
56
+ "link": {
57
+ "default": "Mehr erfahren"
58
+ },
59
+ "errors": {
60
+ "unknown": "Unbekannte Einwilligung: {{key}}"
61
+ }
62
+ }