@owlmeans/server-marketing-consent 0.1.18-rc.8 → 0.1.18

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/README.md +182 -1
  2. package/agent-meta/manifest.json +3 -3
  3. package/agent-meta/skills/server-marketing-consent/SKILL.md +13 -13
  4. package/build/handlers/index.d.ts +4 -0
  5. package/build/handlers/index.d.ts.map +1 -0
  6. package/build/handlers/index.js +4 -0
  7. package/build/handlers/index.js.map +1 -0
  8. package/build/handlers/save.d.ts +9 -0
  9. package/build/handlers/save.d.ts.map +1 -0
  10. package/build/handlers/save.js +11 -0
  11. package/build/handlers/save.js.map +1 -0
  12. package/build/handlers/status.d.ts +4 -0
  13. package/build/handlers/status.d.ts.map +1 -0
  14. package/build/handlers/status.js +12 -0
  15. package/build/handlers/status.js.map +1 -0
  16. package/build/handlers/terms.d.ts +8 -0
  17. package/build/handlers/terms.d.ts.map +1 -0
  18. package/build/handlers/terms.js +11 -0
  19. package/build/handlers/terms.js.map +1 -0
  20. package/build/helper.d.ts +1 -4
  21. package/build/helper.d.ts.map +1 -1
  22. package/build/helper.js +1 -1
  23. package/build/helper.js.map +1 -1
  24. package/build/index.d.ts +3 -1
  25. package/build/index.d.ts.map +1 -1
  26. package/build/index.js +1 -1
  27. package/build/index.js.map +1 -1
  28. package/build/model.d.ts +1 -56
  29. package/build/model.d.ts.map +1 -1
  30. package/build/model.js.map +1 -1
  31. package/build/service.d.ts +1 -47
  32. package/build/service.d.ts.map +1 -1
  33. package/build/service.js +13 -11
  34. package/build/service.js.map +1 -1
  35. package/build/subject/types.d.ts +19 -0
  36. package/build/subject/types.d.ts.map +1 -0
  37. package/build/subject/types.js +2 -0
  38. package/build/subject/types.js.map +1 -0
  39. package/build/subject.d.ts +3 -20
  40. package/build/subject.d.ts.map +1 -1
  41. package/build/subject.js +11 -18
  42. package/build/subject.js.map +1 -1
  43. package/build/types.d.ts +119 -0
  44. package/build/types.d.ts.map +1 -0
  45. package/build/types.js +2 -0
  46. package/build/types.js.map +1 -0
  47. package/package.json +20 -19
  48. package/src/handlers/index.ts +3 -0
  49. package/src/handlers/save.ts +16 -0
  50. package/src/handlers/status.ts +19 -0
  51. package/src/handlers/terms.ts +16 -0
  52. package/src/helper.ts +2 -6
  53. package/src/index.ts +3 -1
  54. package/src/model.ts +2 -60
  55. package/src/service.ts +15 -57
  56. package/src/subject/types.ts +19 -0
  57. package/src/subject.ts +14 -24
  58. package/src/types.ts +114 -0
  59. package/tests/context.ts +2 -4
  60. package/tests/handlers.spec.ts +1 -1
  61. package/tests/service.spec.ts +2 -6
  62. package/tests/subject.spec.ts +6 -6
  63. package/build/handlers.d.ts +0 -20
  64. package/build/handlers.d.ts.map +0 -1
  65. package/build/handlers.js +0 -23
  66. package/build/handlers.js.map +0 -1
  67. package/src/handlers.ts +0 -44
package/README.md CHANGED
@@ -1,3 +1,184 @@
1
+ # @owlmeans/server-marketing-consent
2
+
3
+ The server half of `@owlmeans/marketing-consent`: a database-agnostic `MarketingConsentService`
4
+ (status, save, terms acceptance, the `isGranted` send gate, purge, observers) over two resources it
5
+ resolves by alias, plus the `status` / `save` / `terms` handlers for the protocol tree from
6
+ `makeMarketingConsentProtocols`. A backend uses it when people record marketing or data-use consent
7
+ and terms acceptance through the API, or when server code must check a consent before sending or
8
+ sharing. It stores nothing by itself: register the resources with
9
+ `@owlmeans/marketing-consent-mongo` or `@owlmeans/marketing-consent-postgres`. Pure catalogue and
10
+ status logic without a server lives in `@owlmeans/marketing-consent`; the screens are
11
+ `@owlmeans/web-marketing-consent`.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ bun add @owlmeans/server-marketing-consent@^0.1.18
17
+ ```
18
+
19
+ ## Concepts
20
+
21
+ - **Subject** — `MarketingConsentSubject` `{ userId, profileId?, entityId? }`, read from an
22
+ authenticated request. `entityId` comes only from `req.entity?.id`; an app without organization
23
+ entities simply has none.
24
+ - **Subject key** — `` `${entityId ?? ''}|${userId}|${profileId ?? ''}` ``, stored in the state
25
+ record's `subject` field. Records are addressed by `subject`, never by `id` (the backend mints
26
+ `id`).
27
+ - **State record** — `MarketingConsentStateRecord` at `RES_MARKETING_CONSENT_STATE`: one row per
28
+ subject holding the latest decision per key (`decisions` is an array) and the last terms
29
+ acceptance.
30
+ - **Log record** — `MarketingConsentLogRecord` at `RES_MARKETING_CONSENT_LOG`: append-only evidence
31
+ of every decision (`kind: 'consent'`) and terms acceptance (`kind: 'terms'`). Never updated or
32
+ deleted.
33
+ - **Send gate** — `isGranted(subject, key)` trusts only a saved, unrevised (`current`) answer; the
34
+ display `granted` from `status()` defaults unanswered opt-out items to `true` and must not gate a
35
+ send.
36
+
37
+ ## Usage
38
+
39
+ ### Register storage, the service and the handlers
40
+
41
+ ```typescript
42
+ import { makeMarketingConsentProtocols } from '@owlmeans/marketing-consent'
43
+ import { appendMarketingConsentPostgres } from '@owlmeans/marketing-consent-postgres'
44
+ import { appendMarketingConsentService, serveMarketingConsentEntrypoints } from '@owlmeans/server-marketing-consent'
45
+
46
+ // shared package
47
+ export const marketingConsentProtocols = makeMarketingConsentProtocols({ parent: appProtocols.account.base })
48
+
49
+ // backend context
50
+ appendMarketingConsentPostgres(context) // the two resources
51
+ appendMarketingConsentService(context, { // no-op when the alias is already registered
52
+ config: { standard: { 'marketing.phone': false } },
53
+ })
54
+
55
+ // API process
56
+ context.registerEntrypoints(serveMarketingConsentEntrypoints(marketingConsentProtocols))
57
+ ```
58
+
59
+ `serveMarketingConsentEntrypoints` binds `status`, `save` and `terms` only. A `base` declared without
60
+ a `parent` must still be bound by the app, or boot fails with `Entrypoint marketing-consent not found`.
61
+
62
+ ### Gate a send on a consent
63
+
64
+ ```typescript
65
+ import { MC_EMAIL, MARKETING_CONSENT_SERVICE } from '@owlmeans/marketing-consent'
66
+ import type { MarketingConsentService } from '@owlmeans/server-marketing-consent'
67
+
68
+ const consents = context.service<MarketingConsentService>(MARKETING_CONSENT_SERVICE)
69
+
70
+ if (await consents.isGranted({ userId, profileId, entityId }, MC_EMAIL)) {
71
+ await sendNewsletter(userId)
72
+ }
73
+ ```
74
+
75
+ ### Record a decision from server code
76
+
77
+ ```typescript
78
+ import { marketingConsentSubjectHelper } from '@owlmeans/server-marketing-consent'
79
+
80
+ const subject = marketingConsentSubjectHelper.subjectOf(req) // AuthForbidden without a user
81
+ await consents.save(subject, { decisions: [{ key: MC_EMAIL, granted: false }], source: 'api' })
82
+ ```
83
+
84
+ `source: 'api'` is accepted only by the service, never by the HTTP `save` schema. It is meant for a
85
+ server withdrawing a consent on a caller's behalf.
86
+
87
+ ### React to decisions
88
+
89
+ ```typescript
90
+ consents.observe(async ({ subject, decisions }) => {
91
+ await mailingList.sync(subject.userId, decisions)
92
+ })
93
+ ```
94
+
95
+ Listeners run in registration order after each `save`; a throwing listener is logged and never fails
96
+ the write.
97
+
98
+ ### Custom handler options
99
+
100
+ ```typescript
101
+ import { saveMarketingConsent } from '@owlmeans/server-marketing-consent'
102
+ import { bind } from '@owlmeans/server-entrypoint'
103
+
104
+ bind(protocols.save, saveMarketingConsent(protocols.save, { allowAccessTokens: true, serviceAlias: 'my-consents' }))
105
+ ```
106
+
107
+ ## API
108
+
109
+ ### Functions
110
+
111
+ | Symbol | Purpose |
112
+ |---|---|
113
+ | `makeMarketingConsentService(opts?)` | Builds the lazy `MarketingConsentService` |
114
+ | `appendMarketingConsentService(ctx, opts?)` | Registers it unless the alias already exists |
115
+ | `serveMarketingConsentEntrypoints(protocols, opts?)` | `[bind(status), bind(save), bind(terms)]` |
116
+ | `marketingConsentStatus(protocol, opts?)` | `status` handler; reads `Sec-GPC: 1` as `gpc` |
117
+ | `saveMarketingConsent(protocol, opts?)` | `save` handler; refuses access-token auth unless `allowAccessTokens` |
118
+ | `recordTermsAcceptance(protocol, opts?)` | `terms` handler; refuses access-token auth unless `allowAccessTokens` |
119
+ | `marketingConsentSubjectHelper.subjectOf(req)` | `MarketingConsentSubject`; throws `AuthForbidden` without `req.auth.userId` |
120
+ | `marketingConsentSubjectHelper.subjectKey(subject)` | The `subject` string a state record is addressed by |
121
+ | `createMarketingConsentSubjectHelper()` | Builds a `MarketingConsentSubjectHelper` |
122
+
123
+ ### `MarketingConsentService`
124
+
125
+ | Method | Purpose |
126
+ |---|---|
127
+ | `definitions()` | Effective catalogue from `opts.config`, memoized |
128
+ | `status(subject, { gpc? }?)` | `MarketingConsentStatusView` for a screen |
129
+ | `save(subject, request)` | Validates every key (`UnknownMarketingConsentError` on any unknown), appends one log row per decision, replaces those keys in the state record, notifies observers |
130
+ | `recordTerms(subject, acceptance, { source? }?)` | Appends a `terms` log row and sets the state record's `terms`; `source` defaults to `sign-in` |
131
+ | `isGranted(subject, key, { gpc? }?)` | `true` only for a `current` item whose saved answer is granted |
132
+ | `purge(subject)` | Deletes the state record; log rows stay |
133
+ | `observe(listener)` | Adds a `MarketingConsentObserver` |
134
+
135
+ ### Constants, schemas and types
136
+
137
+ | Symbol | Kind | Purpose |
138
+ |---|---|---|
139
+ | `RES_MARKETING_CONSENT_STATE` | const | `'marketing-consent-state'` |
140
+ | `RES_MARKETING_CONSENT_LOG` | const | `'marketing-consent-log'` |
141
+ | `MarketingConsentStateSchema`, `MarketingConsentLogSchema` | AJV schema | Shared with the storage packages |
142
+ | `MakeMarketingConsentServiceOptions` | type | `{ alias?, state?, log?, config? }` |
143
+ | `MarketingConsentHandlerOptions` | type | `{ serviceAlias?, allowAccessTokens? }` |
144
+ | `MarketingConsentServedProtocols` | type | `status`, `save`, `terms` of the protocol tree |
145
+ | `MarketingConsentStateRecord`, `MarketingConsentLogRecord` | type | Stored records |
146
+ | `MarketingConsentSubject`, `MarketingConsentSubjectHelper` | type | Who a decision is recorded for |
147
+ | `MarketingConsentService`, `MarketingConsentObserver`, `MarketingConsentContext` | type | Service, listener, `ServerContext<ServerConfig>` |
148
+
149
+ ## Testing
150
+
151
+ `bun test ./tests` runs against `@owlmeans/static-resource` stores for both aliases; no database is
152
+ needed. The suites cover the in-place upsert, `isGranted` versus display `granted`, `purge` leaving
153
+ the log intact, a throwing observer, the access-token refusal on `save` / `terms`, and a request
154
+ without an organization entity.
155
+
156
+ ## Common pitfalls
157
+
158
+ - Gating a send on `status(...).items[n].granted` instead of `isGranted` — that sends to people who
159
+ opened the settings screen and changed nothing.
160
+ - Storing `decisions` as an object keyed by consent key — dotted keys (`marketing.email`) become
161
+ paths in Mongo and Postgres jsonb queries.
162
+ - Creating a state record with a caller-supplied `id` — Mongo and Postgres refuse it; the service
163
+ addresses rows by `subject`.
164
+ - Expecting `purge` to remove the log — the log is GDPR Art. 7(1) evidence and is never deleted
165
+ here.
166
+ - Reading `entityId` from a slug or `requireEntityKey` — the subject takes `req.entity?.id` only.
167
+ - Forgetting a storage package — the service resolves its resources by alias on first call and fails
168
+ there.
169
+
170
+ The `server-marketing-consent` skill covers these rules in depth; the `marketing-consent` skill
171
+ covers the catalogue and status table.
172
+
173
+ ## Related packages
174
+
175
+ - [`@owlmeans/marketing-consent`](../marketing-consent) — catalogue, status resolution, protocol tree, errors
176
+ - [`@owlmeans/marketing-consent-mongo`](../marketing-consent-mongo) — MongoDB resources for the two aliases
177
+ - [`@owlmeans/marketing-consent-postgres`](../marketing-consent-postgres) — PostgreSQL resources for the two aliases
178
+ - [`@owlmeans/web-marketing-consent`](../web-marketing-consent) — the screens that call these handlers
179
+ - [`@owlmeans/server-auth-token`](../server-auth-token) — `refuseTokenAuth`, used by `save` and `terms`
180
+ - [`@owlmeans/server-api`](../server-api) — the `handlers()` builder the handlers use
181
+
1
182
  <!-- owlmeans:agent-guidance:start -->
2
183
  ## Agent guidance
3
184
 
@@ -6,7 +187,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
6
187
  your project's skill store (`.agents/skills/`):
7
188
 
8
189
  ```sh
9
- npx @owlmeans/agent-skills@^0.1.18-rc.41
190
+ npx @owlmeans/agent-skills@^0.1.18
10
191
  ```
11
192
 
12
193
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
- "schemaVersion": 2,
2
+ "schemaVersion": 3,
3
3
  "package": "@owlmeans/server-marketing-consent",
4
- "version": "0.1.18-rc.8",
5
- "generatedAt": "2026-09-28T02:06:37.893Z",
4
+ "version": "0.1.18",
5
+ "generatedAt": "2026-10-28T00:31:34.768Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,8 +8,8 @@ user-invocable: false
8
8
  # @owlmeans/server-marketing-consent
9
9
 
10
10
  **Layer:** Server
11
- **Install:** `"@owlmeans/server-marketing-consent": "^0.1.18-rc.8"` in `dependencies`
12
- **Contracts:** `@owlmeans/marketing-consent` — the catalogue, `consentStatus`, the protocol tree, the error family
11
+ **Install:** `"@owlmeans/server-marketing-consent": "^0.1.18"` in `dependencies`
12
+ **Contracts:** `@owlmeans/marketing-consent` — the catalogue, `marketingConsentHelper.consentStatus`, the protocol tree, the error family
13
13
 
14
14
  ## Key Exports
15
15
 
@@ -17,7 +17,7 @@ user-invocable: false
17
17
  |--------|-------------|
18
18
  | `RES_MARKETING_CONSENT_STATE` (`marketing-consent-state`) · `RES_MARKETING_CONSENT_LOG` (`marketing-consent-log`) | Resource aliases — never rename, a later Mongo/Postgres extension's generated resource file names derive from these exact strings |
19
19
  | `MarketingConsentStateRecord` · `MarketingConsentLogRecord` · `MarketingConsentStateSchema` · `MarketingConsentLogSchema` | The two record shapes and their AJV `JSONSchemaType` schemas — shared with the `@owlmeans/marketing-consent-mongo` / `@owlmeans/marketing-consent-postgres` extensions, which import them rather than redeclaring |
20
- | `subjectOf(req)` · `subjectKey(subject)` · `MarketingConsentSubject` | Who a decision is recorded for, and the `subject` key its one state record is addressed by |
20
+ | `marketingConsentSubjectHelper.subjectOf(req)` · `.subjectKey(subject)` · `MarketingConsentSubject` | Who a decision is recorded for, and the `subject` key its one state record is addressed by |
21
21
  | `makeMarketingConsentService(opts?)` · `appendMarketingConsentService(ctx, opts?)` | Build/register the `MarketingConsentService` |
22
22
  | `MarketingConsentService` | `definitions`, `status`, `save`, `recordTerms`, `isGranted`, `purge`, `observe` |
23
23
  | `marketingConsentStatus` · `saveMarketingConsent` · `recordTermsAcceptance` | Handler makers for `makeMarketingConsentProtocols().status/save/terms` |
@@ -54,43 +54,43 @@ exists under this alias before the first `status`/`save`/`terms` call" does).
54
54
 
55
55
  This is the single most important gotcha in this package. `MarketingConsentStateRecord.decisions`
56
56
  holds `MarketingConsentDecision[]`, one entry per key, folded down to the latest per key on read
57
- (`consentStatus`). It is never stored as `{ [key]: MarketingConsentDecision }`, because every
57
+ (`marketingConsentHelper.consentStatus`). It is never stored as `{ [key]: MarketingConsentDecision }`, because every
58
58
  standard consent key is DOTTED (`marketing.email`, `data.profiling`) and a dotted key inside
59
59
  an object field is read as a PATH by both Mongo's dot-notation queries (`{'decisions.marketing.email':
60
60
  ...}` reaches into a nested `email` field under a nested `marketing` field, not a literal key) and
61
61
  Postgres jsonb path operators (`->` chains on segments). An object-keyed shape works in a quick
62
62
  manual test with one key and breaks the moment a second dotted key is added — the two fields
63
63
  silently merge into one nested tree instead of staying two siblings. Keep it an array in every
64
- storage backend; fold by key only in memory, in `consentStatus` or in a resource's own read path.
64
+ storage backend; fold by key only in memory, in `.consentStatus` or in a resource's own read path.
65
65
 
66
- ## `subjectOf` never uses the slug
66
+ ## `marketingConsentSubjectHelper.subjectOf` never uses the slug
67
67
 
68
68
  ```ts
69
- export const subjectOf = (req: AbstractRequest): MarketingConsentSubject => {
69
+ const subjectOf = (req: AbstractRequest): MarketingConsentSubject => {
70
70
  if (req.auth?.userId == null || req.auth.userId === '') throw new AuthForbidden(...)
71
71
  return { userId: req.auth.userId, profileId: req.auth.profileId, entityId: req.entity?.id }
72
72
  }
73
73
  ```
74
74
 
75
- `entityId` reads `req.entity?.id` ONLY — never `requireEntityKey(req)`, never a slug off the token.
75
+ `entityId` reads `req.entity?.id` ONLY — never `makeEntityScope(req).requireEntityKey()`, never a slug off the token.
76
76
  A deployment with no organization concept at all (a generated target app serving its own end users,
77
77
  say) registers no entity resolver, so `req.entity` stays `undefined` and `entityId` is simply
78
- absent — a valid, expected shape this package must never throw on. `subjectKey(subject)` —
78
+ absent — a valid, expected shape this package must never throw on. `marketingConsentSubjectHelper.subjectKey(subject)` —
79
79
  `` `${entityId ?? ''}|${userId}|${profileId ?? ''}` `` — is the state record's `subject` field, and
80
80
  every read and write addresses the record by it (`load({ subject })`, `purge({ subject })`), never
81
81
  by `id`. The record's `id` is whatever the backend mints on `create()`: Mongo and Postgres refuse a
82
82
  caller-supplied id outright (`RecordExists('id-present')`, whether or not such a row exists), so a
83
83
  natural key can only ever live in a field. Each storage extension makes `subject` unique.
84
84
 
85
- ## `isGranted` is not `consentStatus`'s display `granted`
85
+ ## `isGranted` is not `marketingConsentHelper.consentStatus`'s display `granted`
86
86
 
87
- `status(subject)` returns what `consentStatus` computes for a settings screen: an unanswered
87
+ `status(subject)` returns what `marketingConsentHelper.consentStatus` computes for a settings screen: an unanswered
88
88
  `opt-out` item (e.g. `data.partners`) reads `granted: true` there — the "on until you turn it off"
89
89
  copy an unauthenticated-feeling first visit shows. `isGranted(subject, key)` is a DIFFERENT
90
90
  question — the SERVER-SIDE gate a send/share actually checks before doing something — and it must
91
91
  never honor that display default: an item whose `status` is `'new'` or `'revised'` has never been
92
92
  affirmatively answered by this person, so `isGranted` answers `false` for it regardless of what
93
- `consentStatus.granted` says, and `false` too for a key `definitions()` does not carry at all
93
+ `marketingConsentHelper.consentStatus`'s `granted` says, and `false` too for a key `definitions()` does not carry at all
94
94
  (unknown or disabled). Only a `'current'` (i.e. actually saved, unrevised) item's `granted` is
95
95
  trusted. Getting this backwards — wiring a send to `status(...).items.find(...).granted` instead of
96
96
  `isGranted(...)` — sends to people who opened the settings screen and changed nothing.
@@ -151,7 +151,7 @@ directly — the app never calls `context.init()`/`configure()` in this style of
151
151
 
152
152
  ## Related
153
153
 
154
- - `@owlmeans/marketing-consent` — the catalogue, `consentStatus`, the protocol tree (read its skill
154
+ - `@owlmeans/marketing-consent` — the catalogue, `marketingConsentHelper.consentStatus`, the protocol tree (read its skill
155
155
  first; this package builds on it and repeats nothing it already documents)
156
156
  - `@owlmeans/server-oauth`, `@owlmeans/server-auth-token` — `refuseTokenAuth`, the session-guarded
157
157
  handler shape this package's `save`/`terms` copy
@@ -0,0 +1,4 @@
1
+ export * from './status.js';
2
+ export * from './save.js';
3
+ export * from './terms.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './status.js';
2
+ export * from './save.js';
3
+ export * from './terms.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { type MarketingConsentEntrypoints } from '@owlmeans/marketing-consent';
2
+ import type { MarketingConsentHandlerOptions } from '../types.js';
3
+ export declare const saveMarketingConsent: (protocol: MarketingConsentEntrypoints['save'], opts?: MarketingConsentHandlerOptions) => import("@owlmeans/server-entrypoint").BoundEntrypointHandler<import("@owlmeans/entrypoint").EntrypointProtocol<{
4
+ body: import("@owlmeans/marketing-consent").SaveMarketingConsentRequest;
5
+ }, {
6
+ ok: boolean;
7
+ status: import("@owlmeans/marketing-consent").MarketingConsentStatusView;
8
+ }>>;
9
+ //# sourceMappingURL=save.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/handlers/save.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,2BAA2B,EAAE,MAAM,6BAA6B,CAAA;AAGzG,OAAO,KAAK,EAA2B,8BAA8B,EAA2B,MAAM,aAAa,CAAA;AAMnH,eAAO,MAAM,oBAAoB,aACrB,2BAA2B,CAAC,MAAM,CAAC,SAAQ,8BAA8B;;;;;GAKnF,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { MARKETING_CONSENT_SERVICE } from '@owlmeans/marketing-consent';
2
+ import { handlers } from '@owlmeans/server-api';
3
+ import { refuseTokenAuth } from '@owlmeans/server-auth-token';
4
+ import { marketingConsentSubjectHelper } from '../subject.js';
5
+ const serviceOf = (context, opts) => context.service(opts?.serviceAlias ?? MARKETING_CONSENT_SERVICE);
6
+ export const saveMarketingConsent = (protocol, opts = {}) => handlers().body(protocol, async (payload, context, req) => {
7
+ if (opts.allowAccessTokens !== true)
8
+ refuseTokenAuth(req, 'marketing-consent-save');
9
+ return serviceOf(context, opts).save(marketingConsentSubjectHelper.subjectOf(req), payload);
10
+ });
11
+ //# sourceMappingURL=save.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.js","sourceRoot":"","sources":["../../src/handlers/save.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAoC,MAAM,6BAA6B,CAAA;AACzG,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAE7D,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAA;AAE7D,MAAM,SAAS,GAAG,CAAC,OAAgC,EAAE,IAAqC,EAA2B,EAAE,CACrH,OAAO,CAAC,OAAO,CAA0B,IAAI,EAAE,YAAY,IAAI,yBAAyB,CAAC,CAAA;AAE3F,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,QAA6C,EAAE,IAAI,GAAmC,EAAE,EACxF,EAAE,CAAC,QAAQ,EAA2B,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;IACtF,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI;QAAE,eAAe,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAA;IAEnF,OAAO,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;AAC7F,CAAC,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { type MarketingConsentEntrypoints } from '@owlmeans/marketing-consent';
2
+ import type { MarketingConsentHandlerOptions } from '../types.js';
3
+ export declare const marketingConsentStatus: (protocol: MarketingConsentEntrypoints['status'], opts?: MarketingConsentHandlerOptions) => import("@owlmeans/server-entrypoint").BoundEntrypointHandler<import("@owlmeans/entrypoint").EntrypointProtocol<{}, import("@owlmeans/marketing-consent").MarketingConsentStatusView>>;
4
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/handlers/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,2BAA2B,EAAE,MAAM,6BAA6B,CAAA;AAEzG,OAAO,KAAK,EAA2B,8BAA8B,EAA2B,MAAM,aAAa,CAAA;AAanH,eAAO,MAAM,sBAAsB,aACvB,2BAA2B,CAAC,QAAQ,CAAC,SAAQ,8BAA8B,0LAE4B,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { MARKETING_CONSENT_SERVICE } from '@owlmeans/marketing-consent';
2
+ import { handlers } from '@owlmeans/server-api';
3
+ import { marketingConsentSubjectHelper } from '../subject.js';
4
+ const serviceOf = (context, opts) => context.service(opts?.serviceAlias ?? MARKETING_CONSENT_SERVICE);
5
+ /** GPC ("Sec-GPC: 1") read as a plain header — Fastify normalizes header names to lower case, and
6
+ * a repeated header arrives as an array, so only its first value is read. */
7
+ const gpcOf = (headers) => {
8
+ const raw = headers['sec-gpc'];
9
+ return (Array.isArray(raw) ? raw[0] : raw) === '1';
10
+ };
11
+ export const marketingConsentStatus = (protocol, opts = {}) => handlers().request(protocol, async (req, context) => serviceOf(context, opts).status(marketingConsentSubjectHelper.subjectOf(req), { gpc: gpcOf(req.headers ?? {}) }));
12
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/handlers/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAoC,MAAM,6BAA6B,CAAA;AACzG,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAA;AAE7D,MAAM,SAAS,GAAG,CAAC,OAAgC,EAAE,IAAqC,EAA2B,EAAE,CACrH,OAAO,CAAC,OAAO,CAA0B,IAAI,EAAE,YAAY,IAAI,yBAAyB,CAAC,CAAA;AAE3F;6EAC6E;AAC7E,MAAM,KAAK,GAAG,CAAC,OAAsD,EAAW,EAAE;IAChF,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IAC9B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,CAAA;AACpD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,QAA+C,EAAE,IAAI,GAAmC,EAAE,EAC1F,EAAE,CAAC,QAAQ,EAA2B,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAChF,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,6BAA6B,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { type MarketingConsentEntrypoints } from '@owlmeans/marketing-consent';
2
+ import type { MarketingConsentHandlerOptions } from '../types.js';
3
+ export declare const recordTermsAcceptance: (protocol: MarketingConsentEntrypoints['terms'], opts?: MarketingConsentHandlerOptions) => import("@owlmeans/server-entrypoint").BoundEntrypointHandler<import("@owlmeans/entrypoint").EntrypointProtocol<{
4
+ body: import("@owlmeans/marketing-consent").TermsAcceptance;
5
+ }, {
6
+ ok: boolean;
7
+ }>>;
8
+ //# sourceMappingURL=terms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terms.d.ts","sourceRoot":"","sources":["../../src/handlers/terms.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,2BAA2B,EAAE,MAAM,6BAA6B,CAAA;AAGzG,OAAO,KAAK,EAA2B,8BAA8B,EAA2B,MAAM,aAAa,CAAA;AAMnH,eAAO,MAAM,qBAAqB,aACtB,2BAA2B,CAAC,OAAO,CAAC,SAAQ,8BAA8B;;;;GAKpF,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { MARKETING_CONSENT_SERVICE } from '@owlmeans/marketing-consent';
2
+ import { handlers } from '@owlmeans/server-api';
3
+ import { refuseTokenAuth } from '@owlmeans/server-auth-token';
4
+ import { marketingConsentSubjectHelper } from '../subject.js';
5
+ const serviceOf = (context, opts) => context.service(opts?.serviceAlias ?? MARKETING_CONSENT_SERVICE);
6
+ export const recordTermsAcceptance = (protocol, opts = {}) => handlers().body(protocol, async (payload, context, req) => {
7
+ if (opts.allowAccessTokens !== true)
8
+ refuseTokenAuth(req, 'marketing-consent-terms');
9
+ return serviceOf(context, opts).recordTerms(marketingConsentSubjectHelper.subjectOf(req), payload);
10
+ });
11
+ //# sourceMappingURL=terms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terms.js","sourceRoot":"","sources":["../../src/handlers/terms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAoC,MAAM,6BAA6B,CAAA;AACzG,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAE7D,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAA;AAE7D,MAAM,SAAS,GAAG,CAAC,OAAgC,EAAE,IAAqC,EAA2B,EAAE,CACrH,OAAO,CAAC,OAAO,CAA0B,IAAI,EAAE,YAAY,IAAI,yBAAyB,CAAC,CAAA;AAE3F,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,QAA8C,EAAE,IAAI,GAAmC,EAAE,EACzF,EAAE,CAAC,QAAQ,EAA2B,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;IACtF,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI;QAAE,eAAe,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAA;IAEpF,OAAO,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,6BAA6B,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;AACpG,CAAC,CAAC,CAAA"}
package/build/helper.d.ts CHANGED
@@ -1,7 +1,4 @@
1
- import type { MarketingConsentEntrypoints } from '@owlmeans/marketing-consent';
2
- import type { MarketingConsentHandlerOptions } from './handlers.js';
3
- /** The part of a `makeMarketingConsentProtocols` tree that carries a server implementation. */
4
- export type MarketingConsentServedProtocols = Pick<MarketingConsentEntrypoints, 'status' | 'save' | 'terms'>;
1
+ import type { MarketingConsentHandlerOptions, MarketingConsentServedProtocols } from './types.js';
5
2
  /**
6
3
  * Bind this package's handlers to a tree declared by `makeMarketingConsentProtocols` — one binding
7
4
  * per protocol that needs a server implementation. `base` and `screen` carry no handler of their
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAA;AAE9E,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAA;AAEnE,+FAA+F;AAC/F,MAAM,MAAM,+BAA+B,GAAG,IAAI,CAAC,2BAA2B,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,CAAA;AAE5G;;;;;;;GAOG;AACH,eAAO,MAAM,gCAAgC,cAChC,+BAA+B,SAAQ,8BAA8B;;;;;;;;;gMAKjF,CAAA"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,8BAA8B,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAA;AAEjG;;;;;;;GAOG;AACH,eAAO,MAAM,gCAAgC,cAChC,+BAA+B,SAAQ,8BAA8B;;;;;;;;;gMAKjF,CAAA"}
package/build/helper.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { bind } from '@owlmeans/server-entrypoint';
2
- import { marketingConsentStatus, recordTermsAcceptance, saveMarketingConsent } from './handlers.js';
2
+ import { marketingConsentStatus, recordTermsAcceptance, saveMarketingConsent } from './handlers/index.js';
3
3
  /**
4
4
  * Bind this package's handlers to a tree declared by `makeMarketingConsentProtocols` — one binding
5
5
  * per protocol that needs a server implementation. `base` and `screen` carry no handler of their
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAElD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAMnG;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC9C,SAA0C,EAAE,IAAI,GAAmC,EAAE,EACrF,EAAE,CAAC;IACH,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,sBAAsB,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACtE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,oBAAoB,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,qBAAqB,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;CACpE,CAAA"}
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAClD,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAGzG;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC9C,SAA0C,EAAE,IAAI,GAAmC,EAAE,EACrF,EAAE,CAAC;IACH,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,sBAAsB,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACtE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,oBAAoB,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,qBAAqB,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;CACpE,CAAA"}
package/build/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  export * from './consts.js';
2
2
  export * from './model.js';
3
+ export type * from './types.js';
4
+ export type * from './subject/types.js';
3
5
  export * from './subject.js';
4
6
  export * from './service.js';
5
- export * from './handlers.js';
7
+ export * from './handlers/index.js';
6
8
  export * from './helper.js';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,mBAAmB,YAAY,CAAA;AAC/B,mBAAmB,oBAAoB,CAAA;AACvC,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA"}
package/build/index.js CHANGED
@@ -2,6 +2,6 @@ export * from './consts.js';
2
2
  export * from './model.js';
3
3
  export * from './subject.js';
4
4
  export * from './service.js';
5
- export * from './handlers.js';
5
+ export * from './handlers/index.js';
6
6
  export * from './helper.js';
7
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAG1B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA"}
package/build/model.d.ts CHANGED
@@ -1,60 +1,5 @@
1
1
  import type { JSONSchemaType } from 'ajv';
2
- import type { ResourceRecord } from '@owlmeans/resource';
3
- import type { MarketingConsentDecision, MarketingConsentMode, MarketingConsentSource, TermsDocumentRef } from '@owlmeans/marketing-consent';
4
- /**
5
- * One subject's saved decisions, one record per subject (`id` = `subjectKey(subject)`).
6
- *
7
- * `decisions` is an ARRAY, never an object keyed by consent key. A dotted key such as
8
- * `"marketing.email"` is read as a PATH by both Mongo dot-notation queries and Postgres jsonb path
9
- * operators — an object-keyed shape breaks the moment a second consent key is added. This is the
10
- * single most important shape decision in this package; the Mongo/Postgres extensions that will
11
- * store this record must not "flatten" it into an object for convenience.
12
- */
13
- export interface MarketingConsentStateRecord extends ResourceRecord {
14
- id: string;
15
- /** `subjectKey(subjectOf(req))` — see `./subject.js`. Also this record's own `id`. */
16
- subject: string;
17
- userId: string;
18
- profileId?: string;
19
- entityId?: string;
20
- decisions: MarketingConsentDecision[];
21
- terms?: {
22
- documents: TermsDocumentRef[];
23
- notices?: TermsDocumentRef[];
24
- version: string;
25
- locale?: string;
26
- acceptedAt: string;
27
- };
28
- gpc?: boolean;
29
- createdAt: string;
30
- updatedAt: string;
31
- }
32
- /**
33
- * Append-only evidence of every decision and terms acceptance ever recorded — GDPR Art. 7(1)
34
- * "demonstrate consent" material. Never updated or deleted, including on `purge()`: only the
35
- * current-state record is cleared there.
36
- */
37
- export interface MarketingConsentLogRecord extends ResourceRecord {
38
- id: string;
39
- subject: string;
40
- userId: string;
41
- profileId?: string;
42
- entityId?: string;
43
- kind: 'consent' | 'terms';
44
- /** Present when `kind === 'consent'`. */
45
- key?: string;
46
- granted?: boolean;
47
- revisedAt?: string;
48
- mode?: MarketingConsentMode;
49
- /** Present when `kind === 'terms'`. */
50
- documents?: TermsDocumentRef[];
51
- notices?: TermsDocumentRef[];
52
- version?: string;
53
- decidedAt: string;
54
- source: MarketingConsentSource;
55
- locale?: string;
56
- gpc?: boolean;
57
- }
2
+ import type { MarketingConsentLogRecord, MarketingConsentStateRecord } from './types.js';
58
3
  /**
59
4
  * Shared with the Mongo/Postgres extension packages this schema is built for — imported by them,
60
5
  * never duplicated.
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EACV,wBAAwB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,gBAAgB,EACzF,MAAM,6BAA6B,CAAA;AAEpC;;;;;;;;GAQG;AACH,MAAM,WAAW,2BAA4B,SAAQ,cAAc;IACjE,EAAE,EAAE,MAAM,CAAA;IACV,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,wBAAwB,EAAE,CAAA;IACrC,KAAK,CAAC,EAAE;QACN,SAAS,EAAE,gBAAgB,EAAE,CAAA;QAC7B,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;QAC5B,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,UAAU,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAA0B,SAAQ,cAAc;IAC/D,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;IACzB,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,oBAAoB,CAAA;IAC3B,uCAAuC;IACvC,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC9B,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,sBAAsB,CAAA;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AA8BD;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,cAAc,CAAC,2BAA2B,CA4BnF,CAAA;AAED,eAAO,MAAM,yBAAyB,EAAE,cAAc,CAAC,yBAAyB,CAuB/E,CAAA"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AAEzC,OAAO,KAAK,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AA8BxF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,cAAc,CAAC,2BAA2B,CA4BnF,CAAA;AAED,eAAO,MAAM,yBAAyB,EAAE,cAAc,CAAC,yBAAyB,CAuB/E,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
@@ -1,50 +1,4 @@
1
- import type { LazyService } from '@owlmeans/context';
2
- import type { MarketingConsentConfig, MarketingConsentDecision, MarketingConsentDefinition, MarketingConsentSource, MarketingConsentStatusView, SaveMarketingConsentRequest, TermsAcceptance } from '@owlmeans/marketing-consent';
3
- import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
4
- import type { MarketingConsentSubject } from './subject.js';
5
- export type MarketingConsentContext = ServerContext<ServerConfig>;
6
- export type MarketingConsentObserver = (event: {
7
- subject: MarketingConsentSubject;
8
- decisions: MarketingConsentDecision[];
9
- }) => void | Promise<void>;
10
- export interface MarketingConsentService extends LazyService {
11
- /** The effective catalogue (`resolveMarketingConsents`), computed once and memoized. */
12
- definitions(): MarketingConsentDefinition[];
13
- status(subject: MarketingConsentSubject, opts?: {
14
- gpc?: boolean;
15
- }): Promise<MarketingConsentStatusView>;
16
- save(subject: MarketingConsentSubject, request: SaveMarketingConsentRequest | (Omit<SaveMarketingConsentRequest, 'source'> & {
17
- source: 'api';
18
- })): Promise<{
19
- ok: true;
20
- status: MarketingConsentStatusView;
21
- }>;
22
- recordTerms(subject: MarketingConsentSubject, acceptance: TermsAcceptance, opts?: {
23
- source?: MarketingConsentSource;
24
- }): Promise<{
25
- ok: true;
26
- }>;
27
- /**
28
- * The SERVER-SIDE gate a send/share checks — the SAVED, CONFIRMED answer only. An item still
29
- * `'new'` or `'revised'` has never been affirmatively answered by this person, so it reads as
30
- * NOT granted here even where `consentStatus`'s own `granted` defaults an opt-out item to `true`
31
- * for DISPLAY purposes.
32
- */
33
- isGranted(subject: MarketingConsentSubject, key: string, opts?: {
34
- gpc?: boolean;
35
- }): Promise<boolean>;
36
- /** Clears the current-state record. Log rows stay — they are the append-only compliance evidence. */
37
- purge(subject: MarketingConsentSubject): Promise<void>;
38
- observe(listener: MarketingConsentObserver): void;
39
- }
40
- export interface MakeMarketingConsentServiceOptions {
41
- alias?: string;
42
- /** Resource alias holding one current-state record per subject. Defaults to `RES_MARKETING_CONSENT_STATE`. */
43
- state?: string;
44
- /** Resource alias holding the append-only log. Defaults to `RES_MARKETING_CONSENT_LOG`. */
45
- log?: string;
46
- config?: MarketingConsentConfig;
47
- }
1
+ import type { MakeMarketingConsentServiceOptions, MarketingConsentContext, MarketingConsentService } from './types.js';
48
2
  /**
49
3
  * Build the `MarketingConsentService`. Database-agnostic: both resources are resolved BY ALIAS
50
4
  * from the context lazily, inside each method call — never imported or constructed here. A
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAIpD,OAAO,KAAK,EACV,sBAAsB,EAAE,wBAAwB,EAAE,0BAA0B,EAC5E,sBAAsB,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,eAAe,EACjG,MAAM,6BAA6B,CAAA;AAEpC,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAI3E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAE3D,MAAM,MAAM,uBAAuB,GAAG,aAAa,CAAC,YAAY,CAAC,CAAA;AAEjE,MAAM,MAAM,wBAAwB,GAClC,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,uBAAuB,CAAC;IAAC,SAAS,EAAE,wBAAwB,EAAE,CAAA;CAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAE9G,MAAM,WAAW,uBAAwB,SAAQ,WAAW;IAC1D,wFAAwF;IACxF,WAAW,IAAI,0BAA0B,EAAE,CAAA;IAC3C,MAAM,CAAC,OAAO,EAAE,uBAAuB,EAAE,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAA;IACvG,IAAI,CACF,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE,2BAA2B,GAAG,CAAC,IAAI,CAAC,2BAA2B,EAAE,QAAQ,CAAC,GAAG;QAAE,MAAM,EAAE,KAAK,CAAA;KAAE,CAAC,GACvG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,0BAA0B,CAAA;KAAE,CAAC,CAAA;IAC5D,WAAW,CACT,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,sBAAsB,CAAA;KAAE,GACxG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC,CAAA;IACxB;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACpG,qGAAqG;IACrG,KAAK,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtD,OAAO,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAAA;CAClD;AAED,MAAM,WAAW,kCAAkC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8GAA8G;IAC9G,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2FAA2F;IAC3F,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,sBAAsB,CAAA;CAChC;AAID;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,UAChC,kCAAkC,KACvC,uBA+JF,CAAA;AAED,gGAAgG;AAChG,eAAO,MAAM,6BAA6B,YAC/B,uBAAuB,SAAQ,kCAAkC,KACzE,IAKF,CAAA"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAmF,kCAAkC,EAAE,uBAAuB,EAA4B,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAQjO;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,UAChC,kCAAkC,KACvC,uBA+JF,CAAA;AAED,gGAAgG;AAChG,eAAO,MAAM,6BAA6B,YAC/B,uBAAuB,SAAQ,kCAAkC,KACzE,IAKF,CAAA"}