@weatherboard/cms 0.9.0 → 0.11.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.
package/README.md CHANGED
@@ -244,9 +244,11 @@ from a later caller read. The returned objects share no caller-owned data.
244
244
  CMS has no runtime dependency on the unpublished menu or schema packages.
245
245
  Compatibility is exercised with a copied, neutral café saved-shape fixture;
246
246
  there is no schema devDependency or menu test-fixture import. Publication tests
247
- resolve imports in source, all eight entry bundles and their build input paths,
247
+ resolve imports in source, all ten entry bundles and their build input paths,
248
248
  including relative imports into either forbidden package root and type specifiers.
249
249
  Type-only test imports are refused too because the copied-fixture option was used.
250
+ When adding a public entry, run the package's whole suite (`pnpm --filter @weatherboard/cms test`)
251
+ and release smoke (`pnpm --filter @weatherboard/cms smoke`) before publication (A-553).
250
252
 
251
253
  ```ts
252
254
  import { menuQuery, menuTags } from '@weatherboard/cms';
@@ -306,3 +308,63 @@ that this source change alone cannot supply.
306
308
 
307
309
  0.4.0 raises the tagline safety cap to 40, refuses all-caps taglines and preserves
308
310
  valid siblings in published lists. It is one minor above the npm 0.3.0 release.
311
+
312
+ ## Site content manifest (0.11.0)
313
+
314
+ `@weatherboard/cms/content-manifest` exports the protocol types, finite
315
+ `CONTENT_CONTROLS` / `CONTENT_RULES` registries, `contentManifestDigest` and
316
+ `parseContentManifest`. Both functions are asynchronous and use Web Crypto.
317
+ The digest covers only `content`, including revision, dataset, coverage, rules,
318
+ field bindings and defaults; repository/build identity is checked separately by
319
+ the future target resolver. Object keys sort lexically; array order matters.
320
+ Pass JSON-decoded data, not JSON text. The allow-list contract fixes every
321
+ object's properties and every value's type: unknown properties return
322
+ `UNEXPECTED_PROPERTY`; wrong text/default types return `INVALID_VALUE_TYPE`.
323
+ Text/paragraph defaults are strings, enum defaults are declared options, and a
324
+ keyed text list's `fallback` is a map with exactly its declared keys and string
325
+ values. Key declarations carry labels and optional conditions, not defaults.
326
+ Unsupported controls permit only absent or null defaults; operator objects are
327
+ therefore refused by type, regardless of their spelling. Input is copied
328
+ without invoking accessors; functions, exotic objects, accessors and the names
329
+ `__proto__`, `constructor`, `prototype` remain refused as `UNSAFE_CONTENT`.
330
+
331
+ Identifiers return `INVALID_IDENTIFIER` unless they match these full grammars:
332
+
333
+ | Identifier | Grammar |
334
+ | --- | --- |
335
+ | Group/field/keyed-list keys, condition field/context keys, rule/control names, slot/component names | `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$` |
336
+ | Document types and field path segments | `^[a-zA-Z][a-zA-Z0-9_]{0,63}$` |
337
+ | Singleton/eligible/reference IDs, enum options, revision, repository owner/name, deployment ID | `^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$` |
338
+ | Dataset | `^[a-z0-9][a-z0-9_-]{0,63}$` |
339
+ | Project ID | `^[a-z0-9]{8}$` |
340
+ | API version | `YYYY-MM-DD`, four digits, month 01–12, day 01–31 |
341
+ | Perspective | Key grammar plus the sole allowed value `published` |
342
+ | Route | `/` or slash-separated nonempty segments containing only ASCII letters, digits, `_`, `-`, `[` and `]`; one optional trailing slash; no empty interior segments |
343
+
344
+ Controls, rules and contexts must also belong to their finite registries;
345
+ unknown names return `UNKNOWN_CONTROL`, `UNKNOWN_RULE` or `UNKNOWN_CONTEXT`.
346
+ Commit and digest are respectively 40 and 64 lowercase hexadecimal characters.
347
+ All strings are limited to 4096 characters; C0/DEL control characters are
348
+ refused. Arrays are limited to 128 entries, nesting to 16, nodes to 10000 and
349
+ UTF-8 JSON to 262144 bytes. Limits apply before structural validation.
350
+
351
+ Labels, warnings and default copy are inert plain text, returned verbatim,
352
+ including text resembling queries, URLs or code. They must be rendered as text,
353
+ never HTML, queries, imports or operations: **the dashboard never evaluates
354
+ manifest strings**. This is a consumer contract; this package adds no UI.
355
+ There is no query-syntax blocklist for prose.
356
+
357
+ Conditions retain stored-field string equality (`fieldKey`, `equals`,
358
+ `destinations`). Alternatively a condition can name a finite runtime `context`
359
+ instead of `fieldKey`. `CONTENT_CONTEXTS` starts with `season`; its values must
360
+ be keys declared on the enclosing keyed text list (`INVALID_CONTEXT_VALUE`
361
+ otherwise). Each key can declare `conditions`, for example
362
+ `{ context: "season", equals: "summer", destinations: [...] }`. The site supplies
363
+ this render state; no stored season field is required. Extend the registry and
364
+ its value policy together when introducing another runtime context.
365
+
366
+ Complex controls remain present with `unsupported` status and diagnostics. All
367
+ registered validation rules are pending implementation and make their fields
368
+ unsupported. Partial or unobserved coverage and producer warnings also return
369
+ diagnostics automatically. Structural acceptance grants no write permission and
370
+ proves no rendered output.
@@ -0,0 +1,7 @@
1
+ import type { ContentManifestData, ParsedContentManifest } from './types.cjs';
2
+ export * from './registry.cjs';
3
+ export type * from './types.cjs';
4
+ /** SHA-256 over content data only; object keys sorted, array order preserved. */
5
+ export declare function contentManifestDigest(content: ContentManifestData): Promise<string>;
6
+ /** Structural acceptance is not permission to publish or proof of rendering. */
7
+ export declare function parseContentManifest(input: unknown): Promise<ParsedContentManifest>;
@@ -0,0 +1,7 @@
1
+ import type { ContentManifestData, ParsedContentManifest } from './types.mjs';
2
+ export * from './registry.mjs';
3
+ export type * from './types.mjs';
4
+ /** SHA-256 over content data only; object keys sorted, array order preserved. */
5
+ export declare function contentManifestDigest(content: ContentManifestData): Promise<string>;
6
+ /** Structural acceptance is not permission to publish or proof of rendering. */
7
+ export declare function parseContentManifest(input: unknown): Promise<ParsedContentManifest>;
@@ -0,0 +1,7 @@
1
+ import type { ContentManifestData, ParsedContentManifest } from './types.js';
2
+ export * from './registry.js';
3
+ export type * from './types.js';
4
+ /** SHA-256 over content data only; object keys sorted, array order preserved. */
5
+ export declare function contentManifestDigest(content: ContentManifestData): Promise<string>;
6
+ /** Structural acceptance is not permission to publish or proof of rendering. */
7
+ export declare function parseContentManifest(input: unknown): Promise<ParsedContentManifest>;
@@ -0,0 +1,32 @@
1
+ /** Protocol vocabulary only; rule execution is introduced separately. */
2
+ export declare const CONTENT_MANIFEST_VERSION = 1;
3
+ export declare const CONTENT_CONTROLS: Readonly<{
4
+ 'plain-text': true;
5
+ paragraph: true;
6
+ 'keyed-text-list': true;
7
+ enum: true;
8
+ 'portable-text': false;
9
+ 'ordered-list': false;
10
+ image: false;
11
+ reference: false;
12
+ }>;
13
+ export declare const CONTENT_RULES: Readonly<{
14
+ trimmed: false;
15
+ 'single-line': false;
16
+ 'no-em-dash': false;
17
+ 'no-trailing-full-stop': false;
18
+ 'sentence-case': false;
19
+ 'no-money': false;
20
+ 'no-season-prefix': false;
21
+ }>;
22
+ export declare const CONTENT_MANIFEST_LIMITS: Readonly<{
23
+ depth: 16;
24
+ list: 128;
25
+ string: 4096;
26
+ nodes: 10000;
27
+ bytes: 262144;
28
+ }>;
29
+ /** Site-supplied render state; allowed values come from the enclosing keyed list. */
30
+ export declare const CONTENT_CONTEXTS: Readonly<{
31
+ season: "keyed-list-keys";
32
+ }>;
@@ -0,0 +1,32 @@
1
+ /** Protocol vocabulary only; rule execution is introduced separately. */
2
+ export declare const CONTENT_MANIFEST_VERSION = 1;
3
+ export declare const CONTENT_CONTROLS: Readonly<{
4
+ 'plain-text': true;
5
+ paragraph: true;
6
+ 'keyed-text-list': true;
7
+ enum: true;
8
+ 'portable-text': false;
9
+ 'ordered-list': false;
10
+ image: false;
11
+ reference: false;
12
+ }>;
13
+ export declare const CONTENT_RULES: Readonly<{
14
+ trimmed: false;
15
+ 'single-line': false;
16
+ 'no-em-dash': false;
17
+ 'no-trailing-full-stop': false;
18
+ 'sentence-case': false;
19
+ 'no-money': false;
20
+ 'no-season-prefix': false;
21
+ }>;
22
+ export declare const CONTENT_MANIFEST_LIMITS: Readonly<{
23
+ depth: 16;
24
+ list: 128;
25
+ string: 4096;
26
+ nodes: 10000;
27
+ bytes: 262144;
28
+ }>;
29
+ /** Site-supplied render state; allowed values come from the enclosing keyed list. */
30
+ export declare const CONTENT_CONTEXTS: Readonly<{
31
+ season: "keyed-list-keys";
32
+ }>;
@@ -0,0 +1,32 @@
1
+ /** Protocol vocabulary only; rule execution is introduced separately. */
2
+ export declare const CONTENT_MANIFEST_VERSION = 1;
3
+ export declare const CONTENT_CONTROLS: Readonly<{
4
+ 'plain-text': true;
5
+ paragraph: true;
6
+ 'keyed-text-list': true;
7
+ enum: true;
8
+ 'portable-text': false;
9
+ 'ordered-list': false;
10
+ image: false;
11
+ reference: false;
12
+ }>;
13
+ export declare const CONTENT_RULES: Readonly<{
14
+ trimmed: false;
15
+ 'single-line': false;
16
+ 'no-em-dash': false;
17
+ 'no-trailing-full-stop': false;
18
+ 'sentence-case': false;
19
+ 'no-money': false;
20
+ 'no-season-prefix': false;
21
+ }>;
22
+ export declare const CONTENT_MANIFEST_LIMITS: Readonly<{
23
+ depth: 16;
24
+ list: 128;
25
+ string: 4096;
26
+ nodes: 10000;
27
+ bytes: 262144;
28
+ }>;
29
+ /** Site-supplied render state; allowed values come from the enclosing keyed list. */
30
+ export declare const CONTENT_CONTEXTS: Readonly<{
31
+ season: "keyed-list-keys";
32
+ }>;
@@ -0,0 +1,123 @@
1
+ import type { CONTENT_CONTEXTS, CONTENT_CONTROLS, CONTENT_RULES } from './registry.cjs';
2
+ export type ContentControlKind = keyof typeof CONTENT_CONTROLS;
3
+ export type ContentRuleId = keyof typeof CONTENT_RULES;
4
+ export type ContentClassification = 'visible' | 'metadata' | 'accessibility' | 'control' | 'unsupported';
5
+ export type ContentSelector = {
6
+ kind: 'singleton';
7
+ id: string;
8
+ } | {
9
+ kind: 'collection';
10
+ eligibleIds: string[];
11
+ maxDocuments: number;
12
+ };
13
+ export type ContentDestination = {
14
+ route: string;
15
+ slot: string;
16
+ component: string;
17
+ };
18
+ export type ContentContextKey = keyof typeof CONTENT_CONTEXTS;
19
+ export type ContentCondition = ({
20
+ fieldKey: string;
21
+ } | {
22
+ context: ContentContextKey;
23
+ }) & {
24
+ equals: string;
25
+ destinations: ContentDestination[];
26
+ };
27
+ export type ContentField = {
28
+ key: string;
29
+ path: string[];
30
+ label: string;
31
+ required: boolean;
32
+ classification: ContentClassification;
33
+ rules: ContentRuleId[];
34
+ limits: {
35
+ min: number;
36
+ max: number;
37
+ };
38
+ blank: 'reset' | 'empty' | 'refuse';
39
+ reset: 'fallback' | 'remove' | 'refuse';
40
+ destinations: ContentDestination[];
41
+ conditions: ContentCondition[];
42
+ } & ({
43
+ kind: 'plain-text' | 'paragraph';
44
+ fallback: string;
45
+ } | {
46
+ kind: 'enum';
47
+ options: string[];
48
+ fallback: string;
49
+ } | {
50
+ kind: 'keyed-text-list';
51
+ keys: {
52
+ key: string;
53
+ label: string;
54
+ conditions?: ContentCondition[];
55
+ }[];
56
+ fallback: Record<string, string>;
57
+ } | {
58
+ kind: 'reference';
59
+ eligibleIds: string[];
60
+ documentType: string;
61
+ fallback?: null;
62
+ } | {
63
+ kind: 'portable-text' | 'ordered-list' | 'image';
64
+ fallback?: null;
65
+ });
66
+ export type ContentGroup = {
67
+ key: string;
68
+ label: string;
69
+ documentType: string;
70
+ selector: ContentSelector;
71
+ create: boolean;
72
+ delete: boolean;
73
+ fields: ContentField[];
74
+ };
75
+ export type ContentManifestData = {
76
+ revision: string;
77
+ sanity: {
78
+ projectId: string;
79
+ dataset: string;
80
+ apiVersion: string;
81
+ perspective: 'published';
82
+ };
83
+ controlVersion: 1;
84
+ validatorVersion: 1;
85
+ coverage: {
86
+ state: 'complete' | 'partial' | 'unobserved';
87
+ excluded: string[];
88
+ };
89
+ warnings: string[];
90
+ groups: ContentGroup[];
91
+ };
92
+ export type ContentManifest = {
93
+ protocolVersion: 1;
94
+ digest: string;
95
+ repository: {
96
+ owner: string;
97
+ name: string;
98
+ };
99
+ build: {
100
+ commit: string;
101
+ deploymentId: string;
102
+ environment: 'production' | 'preview';
103
+ };
104
+ content: ContentManifestData;
105
+ };
106
+ export type ContentManifestDiagnosticCode = 'INVALID_SHAPE' | 'UNEXPECTED_PROPERTY' | 'INVALID_VALUE_TYPE' | 'INVALID_IDENTIFIER' | 'UNKNOWN_CONTEXT' | 'INVALID_CONTEXT_VALUE' | 'UNKNOWN_PROTOCOL' | 'UNKNOWN_CONTROL' | 'UNKNOWN_RULE' | 'UNKNOWN_VERSION' | 'DUPLICATE_KEY' | 'STRING_LIMIT' | 'LIST_LIMIT' | 'DEPTH_LIMIT' | 'NODE_LIMIT' | 'BYTE_LIMIT' | 'UNSAFE_CONTENT' | 'INVALID_BINDING' | 'INVALID_LIMITS' | 'INVALID_COVERAGE' | 'DIGEST_MISMATCH' | 'UNSUPPORTED_CONTROL' | 'UNSUPPORTED_FIELD' | 'UNIMPLEMENTED_RULE' | 'INCOMPLETE_COVERAGE' | 'PRODUCER_WARNING';
107
+ export type ContentManifestDiagnostic = {
108
+ code: ContentManifestDiagnosticCode;
109
+ path: string;
110
+ };
111
+ export type ParsedContentManifest = {
112
+ ok: false;
113
+ diagnostics: ContentManifestDiagnostic[];
114
+ } | {
115
+ ok: true;
116
+ manifest: ContentManifest;
117
+ diagnostics: ContentManifestDiagnostic[];
118
+ fields: {
119
+ groupKey: string;
120
+ fieldKey: string;
121
+ status: 'supported' | 'unsupported';
122
+ }[];
123
+ };
@@ -0,0 +1,123 @@
1
+ import type { CONTENT_CONTEXTS, CONTENT_CONTROLS, CONTENT_RULES } from './registry.mjs';
2
+ export type ContentControlKind = keyof typeof CONTENT_CONTROLS;
3
+ export type ContentRuleId = keyof typeof CONTENT_RULES;
4
+ export type ContentClassification = 'visible' | 'metadata' | 'accessibility' | 'control' | 'unsupported';
5
+ export type ContentSelector = {
6
+ kind: 'singleton';
7
+ id: string;
8
+ } | {
9
+ kind: 'collection';
10
+ eligibleIds: string[];
11
+ maxDocuments: number;
12
+ };
13
+ export type ContentDestination = {
14
+ route: string;
15
+ slot: string;
16
+ component: string;
17
+ };
18
+ export type ContentContextKey = keyof typeof CONTENT_CONTEXTS;
19
+ export type ContentCondition = ({
20
+ fieldKey: string;
21
+ } | {
22
+ context: ContentContextKey;
23
+ }) & {
24
+ equals: string;
25
+ destinations: ContentDestination[];
26
+ };
27
+ export type ContentField = {
28
+ key: string;
29
+ path: string[];
30
+ label: string;
31
+ required: boolean;
32
+ classification: ContentClassification;
33
+ rules: ContentRuleId[];
34
+ limits: {
35
+ min: number;
36
+ max: number;
37
+ };
38
+ blank: 'reset' | 'empty' | 'refuse';
39
+ reset: 'fallback' | 'remove' | 'refuse';
40
+ destinations: ContentDestination[];
41
+ conditions: ContentCondition[];
42
+ } & ({
43
+ kind: 'plain-text' | 'paragraph';
44
+ fallback: string;
45
+ } | {
46
+ kind: 'enum';
47
+ options: string[];
48
+ fallback: string;
49
+ } | {
50
+ kind: 'keyed-text-list';
51
+ keys: {
52
+ key: string;
53
+ label: string;
54
+ conditions?: ContentCondition[];
55
+ }[];
56
+ fallback: Record<string, string>;
57
+ } | {
58
+ kind: 'reference';
59
+ eligibleIds: string[];
60
+ documentType: string;
61
+ fallback?: null;
62
+ } | {
63
+ kind: 'portable-text' | 'ordered-list' | 'image';
64
+ fallback?: null;
65
+ });
66
+ export type ContentGroup = {
67
+ key: string;
68
+ label: string;
69
+ documentType: string;
70
+ selector: ContentSelector;
71
+ create: boolean;
72
+ delete: boolean;
73
+ fields: ContentField[];
74
+ };
75
+ export type ContentManifestData = {
76
+ revision: string;
77
+ sanity: {
78
+ projectId: string;
79
+ dataset: string;
80
+ apiVersion: string;
81
+ perspective: 'published';
82
+ };
83
+ controlVersion: 1;
84
+ validatorVersion: 1;
85
+ coverage: {
86
+ state: 'complete' | 'partial' | 'unobserved';
87
+ excluded: string[];
88
+ };
89
+ warnings: string[];
90
+ groups: ContentGroup[];
91
+ };
92
+ export type ContentManifest = {
93
+ protocolVersion: 1;
94
+ digest: string;
95
+ repository: {
96
+ owner: string;
97
+ name: string;
98
+ };
99
+ build: {
100
+ commit: string;
101
+ deploymentId: string;
102
+ environment: 'production' | 'preview';
103
+ };
104
+ content: ContentManifestData;
105
+ };
106
+ export type ContentManifestDiagnosticCode = 'INVALID_SHAPE' | 'UNEXPECTED_PROPERTY' | 'INVALID_VALUE_TYPE' | 'INVALID_IDENTIFIER' | 'UNKNOWN_CONTEXT' | 'INVALID_CONTEXT_VALUE' | 'UNKNOWN_PROTOCOL' | 'UNKNOWN_CONTROL' | 'UNKNOWN_RULE' | 'UNKNOWN_VERSION' | 'DUPLICATE_KEY' | 'STRING_LIMIT' | 'LIST_LIMIT' | 'DEPTH_LIMIT' | 'NODE_LIMIT' | 'BYTE_LIMIT' | 'UNSAFE_CONTENT' | 'INVALID_BINDING' | 'INVALID_LIMITS' | 'INVALID_COVERAGE' | 'DIGEST_MISMATCH' | 'UNSUPPORTED_CONTROL' | 'UNSUPPORTED_FIELD' | 'UNIMPLEMENTED_RULE' | 'INCOMPLETE_COVERAGE' | 'PRODUCER_WARNING';
107
+ export type ContentManifestDiagnostic = {
108
+ code: ContentManifestDiagnosticCode;
109
+ path: string;
110
+ };
111
+ export type ParsedContentManifest = {
112
+ ok: false;
113
+ diagnostics: ContentManifestDiagnostic[];
114
+ } | {
115
+ ok: true;
116
+ manifest: ContentManifest;
117
+ diagnostics: ContentManifestDiagnostic[];
118
+ fields: {
119
+ groupKey: string;
120
+ fieldKey: string;
121
+ status: 'supported' | 'unsupported';
122
+ }[];
123
+ };
@@ -0,0 +1,123 @@
1
+ import type { CONTENT_CONTEXTS, CONTENT_CONTROLS, CONTENT_RULES } from './registry.js';
2
+ export type ContentControlKind = keyof typeof CONTENT_CONTROLS;
3
+ export type ContentRuleId = keyof typeof CONTENT_RULES;
4
+ export type ContentClassification = 'visible' | 'metadata' | 'accessibility' | 'control' | 'unsupported';
5
+ export type ContentSelector = {
6
+ kind: 'singleton';
7
+ id: string;
8
+ } | {
9
+ kind: 'collection';
10
+ eligibleIds: string[];
11
+ maxDocuments: number;
12
+ };
13
+ export type ContentDestination = {
14
+ route: string;
15
+ slot: string;
16
+ component: string;
17
+ };
18
+ export type ContentContextKey = keyof typeof CONTENT_CONTEXTS;
19
+ export type ContentCondition = ({
20
+ fieldKey: string;
21
+ } | {
22
+ context: ContentContextKey;
23
+ }) & {
24
+ equals: string;
25
+ destinations: ContentDestination[];
26
+ };
27
+ export type ContentField = {
28
+ key: string;
29
+ path: string[];
30
+ label: string;
31
+ required: boolean;
32
+ classification: ContentClassification;
33
+ rules: ContentRuleId[];
34
+ limits: {
35
+ min: number;
36
+ max: number;
37
+ };
38
+ blank: 'reset' | 'empty' | 'refuse';
39
+ reset: 'fallback' | 'remove' | 'refuse';
40
+ destinations: ContentDestination[];
41
+ conditions: ContentCondition[];
42
+ } & ({
43
+ kind: 'plain-text' | 'paragraph';
44
+ fallback: string;
45
+ } | {
46
+ kind: 'enum';
47
+ options: string[];
48
+ fallback: string;
49
+ } | {
50
+ kind: 'keyed-text-list';
51
+ keys: {
52
+ key: string;
53
+ label: string;
54
+ conditions?: ContentCondition[];
55
+ }[];
56
+ fallback: Record<string, string>;
57
+ } | {
58
+ kind: 'reference';
59
+ eligibleIds: string[];
60
+ documentType: string;
61
+ fallback?: null;
62
+ } | {
63
+ kind: 'portable-text' | 'ordered-list' | 'image';
64
+ fallback?: null;
65
+ });
66
+ export type ContentGroup = {
67
+ key: string;
68
+ label: string;
69
+ documentType: string;
70
+ selector: ContentSelector;
71
+ create: boolean;
72
+ delete: boolean;
73
+ fields: ContentField[];
74
+ };
75
+ export type ContentManifestData = {
76
+ revision: string;
77
+ sanity: {
78
+ projectId: string;
79
+ dataset: string;
80
+ apiVersion: string;
81
+ perspective: 'published';
82
+ };
83
+ controlVersion: 1;
84
+ validatorVersion: 1;
85
+ coverage: {
86
+ state: 'complete' | 'partial' | 'unobserved';
87
+ excluded: string[];
88
+ };
89
+ warnings: string[];
90
+ groups: ContentGroup[];
91
+ };
92
+ export type ContentManifest = {
93
+ protocolVersion: 1;
94
+ digest: string;
95
+ repository: {
96
+ owner: string;
97
+ name: string;
98
+ };
99
+ build: {
100
+ commit: string;
101
+ deploymentId: string;
102
+ environment: 'production' | 'preview';
103
+ };
104
+ content: ContentManifestData;
105
+ };
106
+ export type ContentManifestDiagnosticCode = 'INVALID_SHAPE' | 'UNEXPECTED_PROPERTY' | 'INVALID_VALUE_TYPE' | 'INVALID_IDENTIFIER' | 'UNKNOWN_CONTEXT' | 'INVALID_CONTEXT_VALUE' | 'UNKNOWN_PROTOCOL' | 'UNKNOWN_CONTROL' | 'UNKNOWN_RULE' | 'UNKNOWN_VERSION' | 'DUPLICATE_KEY' | 'STRING_LIMIT' | 'LIST_LIMIT' | 'DEPTH_LIMIT' | 'NODE_LIMIT' | 'BYTE_LIMIT' | 'UNSAFE_CONTENT' | 'INVALID_BINDING' | 'INVALID_LIMITS' | 'INVALID_COVERAGE' | 'DIGEST_MISMATCH' | 'UNSUPPORTED_CONTROL' | 'UNSUPPORTED_FIELD' | 'UNIMPLEMENTED_RULE' | 'INCOMPLETE_COVERAGE' | 'PRODUCER_WARNING';
107
+ export type ContentManifestDiagnostic = {
108
+ code: ContentManifestDiagnosticCode;
109
+ path: string;
110
+ };
111
+ export type ParsedContentManifest = {
112
+ ok: false;
113
+ diagnostics: ContentManifestDiagnostic[];
114
+ } | {
115
+ ok: true;
116
+ manifest: ContentManifest;
117
+ diagnostics: ContentManifestDiagnostic[];
118
+ fields: {
119
+ groupKey: string;
120
+ fieldKey: string;
121
+ status: 'supported' | 'unsupported';
122
+ }[];
123
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";var A=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var H=Object.prototype.hasOwnProperty;var W=(e,t)=>{for(var n in t)A(e,n,{get:t[n],enumerable:!0})},Z=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of G(t))!H.call(e,o)&&o!==n&&A(e,o,{get:()=>t[o],enumerable:!(s=K(t,o))||s.enumerable});return e};var B=e=>Z(A({},"__esModule",{value:!0}),e);var se={};W(se,{CONTENT_CONTEXTS:()=>L,CONTENT_CONTROLS:()=>p,CONTENT_MANIFEST_LIMITS:()=>u,CONTENT_MANIFEST_VERSION:()=>h,CONTENT_RULES:()=>D,contentManifestDigest:()=>z,parseContentManifest:()=>ne});module.exports=B(se);var h=1,p=Object.freeze({"plain-text":!0,paragraph:!0,"keyed-text-list":!0,enum:!0,"portable-text":!1,"ordered-list":!1,image:!1,reference:!1}),D=Object.freeze({trimmed:!1,"single-line":!1,"no-em-dash":!1,"no-trailing-full-stop":!1,"sentence-case":!1,"no-money":!1,"no-season-prefix":!1}),u=Object.freeze({depth:16,list:128,string:4096,nodes:1e4,bytes:262144}),L=Object.freeze({season:"keyed-list-keys"});var T=class extends Error{constructor(n,s){super(n);this.code=n;this.path=s}code;path};function r(e,t){throw new T(e,t)}var $=e=>["__proto__","prototype","constructor"].includes(e.toLowerCase());function P(e){let t=0,n=(o,i,c)=>{if(++t>u.nodes&&r("NODE_LIMIT",i),c>u.depth&&r("DEPTH_LIMIT",i),typeof o=="string")return o.length>u.string&&r("STRING_LIMIT",i),($(o)||[...o].some(f=>f.charCodeAt(0)<32||f.charCodeAt(0)===127))&&r("UNSAFE_CONTENT",i),o;if(o===null||typeof o=="boolean"||typeof o=="number"&&Number.isFinite(o))return o;typeof o!="object"&&r("UNSAFE_CONTENT",i);let d=Array.isArray(o);!d&&Object.getPrototypeOf(o)!==Object.prototype&&Object.getPrototypeOf(o)!==null&&r("UNSAFE_CONTENT",i);let _=Object.getOwnPropertyDescriptors(o);Reflect.ownKeys(o).some(f=>typeof f!="string")&&r("UNSAFE_CONTENT",i),d&&o.length>u.list&&r("LIST_LIMIT",i);let C=Object.create(null);for(let[f,b]of Object.entries(_))d&&f==="length"||((!b.enumerable||!("value"in b)||$(f))&&r("UNSAFE_CONTENT",i),f.length>u.string&&r("STRING_LIMIT",i),d&&(String(Number(f))!==f||!Number.isInteger(Number(f))||Number(f)<0)&&r("UNSAFE_CONTENT",i),C[f]=n(b.value,`${i}/${f}`,c+1));return d?(Object.keys(C).length!==o.length&&r("UNSAFE_CONTENT",i),Object.values(C)):C},s=n(e,"",0);return new TextEncoder().encode(JSON.stringify(s)).length>u.bytes&&r("BYTE_LIMIT",""),s}var m=(e,t)=>{typeof e!="string"&&r("INVALID_VALUE_TYPE",t)},I=(e,t)=>{m(e,t),e.trim()||r("INVALID_SHAPE",t)},S=(e,t)=>{typeof e!="boolean"&&r("INVALID_SHAPE",t)},x=(e,t)=>{(!Number.isSafeInteger(e)||e<0)&&r("INVALID_SHAPE",t)},N=(e,t="INVALID_SHAPE")=>(n,s)=>{e.includes(n)||r(t,s)},j=e=>(t,n)=>{I(t,n),e.test(t)||r("INVALID_BINDING",n)},y=e=>(t,n)=>{(typeof t!="string"||!e.test(t))&&r("INVALID_IDENTIFIER",n)},k=y(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/),g=y(/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/),V=y(/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/),X=(e,t)=>{if((typeof e!="string"||!e.startsWith("/"))&&r("INVALID_IDENTIFIER",t),e==="/")return;let n=e.slice(1).split("/");n.at(-1)===""&&n.pop();for(let s of n)y(/^[a-zA-Z0-9_[\]-]{1,4096}$/)(s,t)},Y=(e,t)=>{(typeof e!="string"||e.length!==10||e[4]!=="-"||e[7]!=="-")&&r("INVALID_IDENTIFIER",t),y(/^[0-9]{8}$/)(e.slice(0,4)+e.slice(5,7)+e.slice(8),t);let n=Number(e.slice(5,7)),s=Number(e.slice(8));(n<1||n>12||s<1||s>31)&&r("INVALID_IDENTIFIER",t)},O=(e,t)=>(n,s)=>{g(n,s),N(e,t)(n,s)},l=(e,t=0)=>(n,s)=>{(!Array.isArray(n)||n.length<t)&&r("INVALID_SHAPE",s),n.forEach((o,i)=>e(o,`${s}/${i}`))},E=(e,t)=>{new Set(e).size!==e.length&&r("DUPLICATE_KEY",t)},M=(e,t)=>{l(k,1)(e,t),E(e,t)},a=e=>(t,n)=>{(!t||typeof t!="object"||Array.isArray(t))&&r("INVALID_SHAPE",n);let s=t;for(let o of Object.keys(s))Object.hasOwn(e,o)||r("UNEXPECTED_PROPERTY",`${n}/${o}`);for(let[o,i]of Object.entries(e))i(s[o],`${n}/${o}`)},w=a({route:X,slot:g,component:g}),U=(e,t)=>{let n=e&&typeof e=="object"&&Object.hasOwn(e,"context");a({...n?{context:O(Object.keys(L),"UNKNOWN_CONTEXT")}:{fieldKey:g},equals:m,destinations:l(w,1)})(e,t)},q=e=>(t,n)=>{t!==void 0&&e(t,n)},J=(e,t)=>{a({min:x,max:x})(e,t);let{min:n,max:s}=e;(n>s||s>u.string)&&r("INVALID_LIMITS",t)},Q=(e,t)=>{if(e?.kind==="singleton")a({kind:N(["singleton"]),id:k})(e,t);else{a({kind:N(["collection"]),eligibleIds:M,maxDocuments:x})(e,t);let s=e;(s.maxDocuments<1||s.maxDocuments>s.eligibleIds.length)&&r("INVALID_LIMITS",t)}},v=(e,t)=>{let n=e?.kind;O(Object.keys(p),"UNKNOWN_CONTROL")(n,`${t}/kind`);let s=n==="enum"?{options:M}:n==="keyed-text-list"?{keys:l(a({key:g,label:I,conditions:q(l(U))}),1)}:n==="reference"?{eligibleIds:M,documentType:V}:{};a({key:g,path:l(V,1),label:I,kind:I,required:S,classification:N(["visible","metadata","accessibility","control","unsupported"]),rules:l(O(Object.keys(D),"UNKNOWN_RULE")),limits:J,blank:N(["reset","empty","refuse"]),reset:N(["fallback","remove","refuse"]),...s,fallback:(i,c)=>{if(n==="keyed-text-list"){let d=e.keys;a(Object.fromEntries(d.map(_=>[_.key,m])))(i,c)}else["plain-text","paragraph","enum"].includes(n)?m(i,c):i!=null&&r("INVALID_VALUE_TYPE",c)},destinations:l(w,1),conditions:l(U)})(e,t);let o=e;E(o.rules,`${t}/rules`),o.kind==="keyed-text-list"&&E(o.keys.map(i=>i.key),`${t}/keys`),o.kind==="enum"&&!o.options.includes(o.fallback)&&r("INVALID_BINDING",`${t}/fallback`)},ee=(e,t)=>{a({key:g,label:I,documentType:V,selector:Q,create:S,delete:S,fields:l(v,1)})(e,t);let n=e;E(n.fields.map(s=>s.key),`${t}/fields`),E(n.fields.map(s=>JSON.stringify(s.path)),`${t}/paths`);for(let s of n.fields){let o=[...s.conditions,...s.kind==="keyed-text-list"?s.keys.flatMap(i=>i.conditions??[]):[]];for(let i of o)"context"in i?(s.kind!=="keyed-text-list"||!s.keys.some(c=>c.key===i.equals))&&r("INVALID_CONTEXT_VALUE",`${t}/conditions`):n.fields.some(c=>c.key===i.fieldKey)||r("INVALID_BINDING",`${t}/conditions`)}},te=(e,t)=>{a({state:N(["complete","partial","unobserved"],"INVALID_COVERAGE"),excluded:l(I)})(e,t);let n=e;n.state==="complete"!=(n.excluded.length===0)&&r("INVALID_COVERAGE",t)},F=a({revision:k,sanity:a({projectId:y(/^[a-z0-9]{8}$/),dataset:y(/^[a-z0-9][a-z0-9_-]{0,63}$/),apiVersion:Y,perspective:O(["published"],"INVALID_BINDING")}),controlVersion:N([1],"UNKNOWN_VERSION"),validatorVersion:N([1],"UNKNOWN_VERSION"),coverage:te,warnings:l(I),groups:l(ee)});function R(e){return Array.isArray(e)?`[${e.map(R).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${R(e[t])}`).join(",")}}`:JSON.stringify(e)}async function z(e){let t=P(e);F(t,"/content");let n=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(R(t)));return Array.from(new Uint8Array(n),s=>s.toString(16).padStart(2,"0")).join("")}async function ne(e){try{let t=P(e);a({protocolVersion:N([1],"UNKNOWN_PROTOCOL"),digest:j(/^[a-f0-9]{64}$/),repository:a({owner:k,name:k}),build:a({commit:j(/^[a-f0-9]{40}$/),deploymentId:k,environment:N(["production","preview"])}),content:F})(t,"");let n=t;E(n.content.groups.map(i=>i.key),"/content/groups"),n.digest!==await z(n.content)&&r("DIGEST_MISMATCH","/digest");let s=[],o=n.content.groups.flatMap(i=>i.fields.map(c=>{let d=`/content/groups/${i.key}/fields/${c.key}`;return p[c.kind]||s.push({code:"UNSUPPORTED_CONTROL",path:d}),c.classification==="unsupported"&&s.push({code:"UNSUPPORTED_FIELD",path:d}),c.rules.length&&s.push({code:"UNIMPLEMENTED_RULE",path:d}),{groupKey:i.key,fieldKey:c.key,status:!p[c.kind]||c.classification==="unsupported"||c.rules.length?"unsupported":"supported"}}));return n.content.coverage.state!=="complete"&&s.push({code:"INCOMPLETE_COVERAGE",path:"/content/coverage"}),n.content.warnings.forEach((i,c)=>s.push({code:"PRODUCER_WARNING",path:`/content/warnings/${c}`})),{ok:!0,manifest:n,fields:o,diagnostics:s}}catch(t){return{ok:!1,diagnostics:[{code:t instanceof T?t.code:"UNSAFE_CONTENT",path:t instanceof T?t.path:""}]}}}0&&(module.exports={CONTENT_CONTEXTS,CONTENT_CONTROLS,CONTENT_MANIFEST_LIMITS,CONTENT_MANIFEST_VERSION,CONTENT_RULES,contentManifestDigest,parseContentManifest});
2
+ //# sourceMappingURL=content-manifest.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/content-manifest.ts", "../src/content-manifest/registry.ts", "../src/content-manifest/index.ts"],
4
+ "sourcesContent": ["export * from './content-manifest/index';\n", "/** Protocol vocabulary only; rule execution is introduced separately. */\nexport const CONTENT_MANIFEST_VERSION = 1;\nexport const CONTENT_CONTROLS = Object.freeze({\n 'plain-text': true, paragraph: true, 'keyed-text-list': true, enum: true,\n 'portable-text': false, 'ordered-list': false, image: false, reference: false,\n});\nexport const CONTENT_RULES = Object.freeze({\n 'trimmed': false, 'single-line': false, 'no-em-dash': false,\n 'no-trailing-full-stop': false, 'sentence-case': false, 'no-money': false,\n 'no-season-prefix': false,\n});\nexport const CONTENT_MANIFEST_LIMITS = Object.freeze({\n depth: 16, list: 128, string: 4096, nodes: 10000, bytes: 262144,\n});\n\n/** Site-supplied render state; allowed values come from the enclosing keyed list. */\nexport const CONTENT_CONTEXTS = Object.freeze({ season: 'keyed-list-keys' as const });\n", "import { CONTENT_CONTEXTS, CONTENT_CONTROLS, CONTENT_MANIFEST_LIMITS as caps, CONTENT_MANIFEST_VERSION, CONTENT_RULES } from './registry';\nimport type { ContentManifest, ContentManifestData, ContentManifestDiagnostic, ContentManifestDiagnosticCode, ParsedContentManifest } from './types';\nexport * from './registry';\nexport type * from './types';\n\ntype RecordValue = Record<string, unknown>;\nclass Refusal extends Error {\n constructor(readonly code: ContentManifestDiagnosticCode, readonly path: string) { super(code); }\n}\nfunction refuse(code: ContentManifestDiagnosticCode, path: string): never { throw new Refusal(code, path); }\nconst reserved = (value: string) => ['__proto__', 'prototype', 'constructor'].includes(value.toLowerCase());\n// Only JSON data properties are inspected; accessors are never invoked.\nfunction bounded(input: unknown): unknown {\n let nodes = 0;\n const visit = (value: unknown, path: string, depth: number): unknown => {\n if (++nodes > caps.nodes) refuse('NODE_LIMIT', path);\n if (depth > caps.depth) refuse('DEPTH_LIMIT', path);\n if (typeof value === 'string') {\n if (value.length > caps.string) refuse('STRING_LIMIT', path);\n if (reserved(value) || [...value].some(c => c.charCodeAt(0) < 32 || c.charCodeAt(0) === 127)) refuse('UNSAFE_CONTENT', path);\n return value;\n }\n if (value === null || typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value))) return value;\n if (typeof value !== 'object') refuse('UNSAFE_CONTENT', path);\n const array = Array.isArray(value);\n if (!array && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) refuse('UNSAFE_CONTENT', path);\n const descriptors = Object.getOwnPropertyDescriptors(value);\n if (Reflect.ownKeys(value).some(key => typeof key !== 'string')) refuse('UNSAFE_CONTENT', path);\n if (array && value.length > caps.list) refuse('LIST_LIMIT', path);\n const output: RecordValue = Object.create(null);\n for (const [key, descriptor] of Object.entries(descriptors)) {\n if (array && key === 'length') continue;\n if (!descriptor.enumerable || !('value' in descriptor) || reserved(key)) refuse('UNSAFE_CONTENT', path);\n if (key.length > caps.string) refuse('STRING_LIMIT', path);\n if (array && (String(Number(key)) !== key || !Number.isInteger(Number(key)) || Number(key) < 0)) refuse('UNSAFE_CONTENT', path);\n output[key] = visit(descriptor.value, `${path}/${key}`, depth + 1);\n }\n if (array) {\n if (Object.keys(output).length !== value.length) refuse('UNSAFE_CONTENT', path);\n return Object.values(output);\n }\n return output;\n };\n const result = visit(input, '', 0);\n if (new TextEncoder().encode(JSON.stringify(result)).length > caps.bytes) refuse('BYTE_LIMIT', '');\n return result;\n}\ntype Check = (value: unknown, path: string) => void;\nconst string: Check = (v, p) => { if (typeof v !== 'string') refuse('INVALID_VALUE_TYPE', p); };\nconst text: Check = (v, p) => { string(v, p); if (!(v as string).trim()) refuse('INVALID_SHAPE', p); };\nconst bool: Check = (v, p) => { if (typeof v !== 'boolean') refuse('INVALID_SHAPE', p); };\nconst number: Check = (v, p) => { if (!Number.isSafeInteger(v) || (v as number) < 0) refuse('INVALID_SHAPE', p); };\nconst literal = (values: readonly unknown[], code: ContentManifestDiagnosticCode = 'INVALID_SHAPE'): Check =>\n (v, p) => { if (!values.includes(v)) refuse(code, p); };\nconst pattern = (re: RegExp): Check => (v, p) => { text(v, p); if (!re.test(v as string)) refuse('INVALID_BINDING', p); };\nconst identifier = (re: RegExp): Check => (v, p) => {\n if (typeof v !== 'string' || !re.test(v)) refuse('INVALID_IDENTIFIER', p);\n};\nconst id = identifier(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/);\nconst key = identifier(/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/);\nconst segment = identifier(/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/);\n// Root or nonempty slash-separated segments; one trailing slash is allowed.\n// Split first so segment repetition cannot overlap with route repetition.\nconst route: Check = (v, p) => {\n if (typeof v !== 'string' || !v.startsWith('/')) refuse('INVALID_IDENTIFIER', p);\n if (v === '/') return;\n const segments = v.slice(1).split('/');\n if (segments.at(-1) === '') segments.pop();\n for (const part of segments) identifier(/^[a-zA-Z0-9_[\\]-]{1,4096}$/)(part, p);\n};\nconst apiVersion: Check = (v, p) => {\n if (typeof v !== 'string' || v.length !== 10 || v[4] !== '-' || v[7] !== '-') refuse('INVALID_IDENTIFIER', p);\n identifier(/^[0-9]{8}$/)(v.slice(0, 4) + v.slice(5, 7) + v.slice(8), p);\n const month = Number(v.slice(5, 7)); const day = Number(v.slice(8));\n if (month < 1 || month > 12 || day < 1 || day > 31) refuse('INVALID_IDENTIFIER', p);\n};\nconst vocabulary = (values: readonly string[], code: ContentManifestDiagnosticCode): Check => (v, p) => {\n key(v, p); literal(values, code)(v, p);\n};\nconst list = (check: Check, minimum = 0): Check => (v, p) => {\n if (!Array.isArray(v) || v.length < minimum) refuse('INVALID_SHAPE', p);\n v.forEach((item, i) => check(item, `${p}/${i}`));\n};\nconst unique = (values: unknown[], p: string) => {\n if (new Set(values).size !== values.length) refuse('DUPLICATE_KEY', p);\n};\nconst ids: Check = (v, p) => { list(id, 1)(v, p); unique(v as string[], p); };\nconst object = (shape: Record<string, Check>): Check => (v, p) => {\n if (!v || typeof v !== 'object' || Array.isArray(v)) refuse('INVALID_SHAPE', p);\n const record = v as RecordValue;\n for (const key of Object.keys(record)) if (!Object.hasOwn(shape, key)) refuse('UNEXPECTED_PROPERTY', `${p}/${key}`);\n for (const [key, check] of Object.entries(shape)) check(record[key], `${p}/${key}`);\n};\nconst destination = object({ route, slot: key, component: key });\nconst condition: Check = (v, p) => {\n const context = v && typeof v === 'object' && Object.hasOwn(v, 'context');\n object({ ...(context ? { context: vocabulary(Object.keys(CONTENT_CONTEXTS), 'UNKNOWN_CONTEXT') } : { fieldKey: key }),\n equals: string, destinations: list(destination, 1) })(v, p);\n};\nconst optional = (check: Check): Check => (v, p) => { if (v !== undefined) check(v, p); };\nconst limits: Check = (v, p) => {\n object({ min: number, max: number })(v, p);\n const { min, max } = v as { min: number; max: number };\n if (min > max || max > caps.string) refuse('INVALID_LIMITS', p);\n};\nconst selector: Check = (v, p) => {\n const kind = (v as RecordValue | null)?.kind;\n if (kind === 'singleton') object({ kind: literal(['singleton']), id })(v, p);\n else {\n object({ kind: literal(['collection']), eligibleIds: ids, maxDocuments: number })(v, p);\n const record = v as { eligibleIds: string[]; maxDocuments: number };\n if (record.maxDocuments < 1 || record.maxDocuments > record.eligibleIds.length) refuse('INVALID_LIMITS', p);\n }\n};\nconst field: Check = (v, p) => {\n const kind = (v as RecordValue | null)?.kind;\n vocabulary(Object.keys(CONTENT_CONTROLS), 'UNKNOWN_CONTROL')(kind, `${p}/kind`);\n const extra: Record<string, Check> = kind === 'enum' ? { options: ids } : kind === 'keyed-text-list' ?\n { keys: list(object({ key, label: text, conditions: optional(list(condition)) }), 1) } : kind === 'reference' ? { eligibleIds: ids, documentType: segment } : {};\n object({ key, path: list(segment, 1), label: text, kind: text, required: bool,\n classification: literal(['visible', 'metadata', 'accessibility', 'control', 'unsupported']),\n rules: list(vocabulary(Object.keys(CONTENT_RULES), 'UNKNOWN_RULE')), limits,\n blank: literal(['reset', 'empty', 'refuse']), reset: literal(['fallback', 'remove', 'refuse']),\n ...extra,\n fallback: (value, path) => {\n if (kind === 'keyed-text-list') {\n const keys = (v as { keys: { key: string }[] }).keys;\n object(Object.fromEntries(keys.map(k => [k.key, string])))(value, path);\n } else if (['plain-text', 'paragraph', 'enum'].includes(kind as string)) string(value, path);\n else if (value !== undefined && value !== null) refuse('INVALID_VALUE_TYPE', path);\n },\n destinations: list(destination, 1), conditions: list(condition),\n })(v, p);\n const f = v as ContentManifestData['groups'][number]['fields'][number];\n unique(f.rules, `${p}/rules`);\n if (f.kind === 'keyed-text-list') unique(f.keys.map(k => k.key), `${p}/keys`);\n if (f.kind === 'enum' && !f.options.includes(f.fallback)) refuse('INVALID_BINDING', `${p}/fallback`);\n};\nconst group: Check = (v, p) => {\n object({ key, label: text, documentType: segment, selector, create: bool, delete: bool, fields: list(field, 1) })(v, p);\n const g = v as ContentManifestData['groups'][number];\n unique(g.fields.map(f => f.key), `${p}/fields`);\n unique(g.fields.map(f => JSON.stringify(f.path)), `${p}/paths`);\n for (const f of g.fields) {\n const conditions = [...f.conditions, ...(f.kind === 'keyed-text-list' ? f.keys.flatMap(k => k.conditions ?? []) : [])];\n for (const c of conditions) {\n if ('context' in c) {\n if (f.kind !== 'keyed-text-list' || !f.keys.some(k => k.key === c.equals)) refuse('INVALID_CONTEXT_VALUE', `${p}/conditions`);\n } else if (!g.fields.some(other => other.key === c.fieldKey)) refuse('INVALID_BINDING', `${p}/conditions`);\n }\n }\n};\nconst coverage: Check = (v, p) => {\n object({ state: literal(['complete', 'partial', 'unobserved'], 'INVALID_COVERAGE'), excluded: list(text) })(v, p);\n const c = v as ContentManifestData['coverage'];\n if ((c.state === 'complete') !== (c.excluded.length === 0)) refuse('INVALID_COVERAGE', p);\n};\nconst data: Check = object({ revision: id,\n sanity: object({ projectId: identifier(/^[a-z0-9]{8}$/), dataset: identifier(/^[a-z0-9][a-z0-9_-]{0,63}$/),\n apiVersion, perspective: vocabulary(['published'], 'INVALID_BINDING') }),\n controlVersion: literal([1], 'UNKNOWN_VERSION'), validatorVersion: literal([1], 'UNKNOWN_VERSION'),\n coverage, warnings: list(text), groups: list(group),\n});\nfunction canonical(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonical).join(',')}]`;\n if (value && typeof value === 'object') return `{${Object.keys(value).sort().map(k => `${JSON.stringify(k)}:${canonical((value as RecordValue)[k])}`).join(',')}}`;\n return JSON.stringify(value);\n}\n/** SHA-256 over content data only; object keys sorted, array order preserved. */\nexport async function contentManifestDigest(content: ContentManifestData): Promise<string> {\n const safe = bounded(content);\n data(safe, '/content');\n const bytes = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(canonical(safe)));\n return Array.from(new Uint8Array(bytes), b => b.toString(16).padStart(2, '0')).join('');\n}\n/** Structural acceptance is not permission to publish or proof of rendering. */\nexport async function parseContentManifest(input: unknown): Promise<ParsedContentManifest> {\n try {\n const safe = bounded(input);\n object({ protocolVersion: literal([CONTENT_MANIFEST_VERSION], 'UNKNOWN_PROTOCOL'),\n digest: pattern(/^[a-f0-9]{64}$/), repository: object({ owner: id, name: id }),\n build: object({ commit: pattern(/^[a-f0-9]{40}$/), deploymentId: id, environment: literal(['production', 'preview']) }),\n content: data,\n })(safe, '');\n const manifest = safe as ContentManifest;\n unique(manifest.content.groups.map(g => g.key), '/content/groups');\n if (manifest.digest !== await contentManifestDigest(manifest.content)) refuse('DIGEST_MISMATCH', '/digest');\n const diagnostics: ContentManifestDiagnostic[] = [];\n const fields: Extract<ParsedContentManifest, { ok: true }>['fields'] = manifest.content.groups.flatMap(g => g.fields.map(f => {\n const path = `/content/groups/${g.key}/fields/${f.key}`;\n if (!CONTENT_CONTROLS[f.kind]) diagnostics.push({ code: 'UNSUPPORTED_CONTROL', path });\n if (f.classification === 'unsupported') diagnostics.push({ code: 'UNSUPPORTED_FIELD', path });\n if (f.rules.length) diagnostics.push({ code: 'UNIMPLEMENTED_RULE', path });\n return { groupKey: g.key, fieldKey: f.key, status: (!CONTENT_CONTROLS[f.kind] || f.classification === 'unsupported' || f.rules.length ? 'unsupported' : 'supported') };\n }));\n if (manifest.content.coverage.state !== 'complete') diagnostics.push({ code: 'INCOMPLETE_COVERAGE', path: '/content/coverage' });\n manifest.content.warnings.forEach((_, i) => diagnostics.push({ code: 'PRODUCER_WARNING', path: `/content/warnings/${i}` }));\n return { ok: true, manifest, fields, diagnostics };\n } catch (error) {\n return { ok: false, diagnostics: [{ code: error instanceof Refusal ? error.code : 'UNSAFE_CONTENT', path: error instanceof Refusal ? error.path : '' }] };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["content_manifest_exports", "__export", "CONTENT_CONTEXTS", "CONTENT_CONTROLS", "CONTENT_MANIFEST_LIMITS", "CONTENT_MANIFEST_VERSION", "CONTENT_RULES", "contentManifestDigest", "parseContentManifest", "__toCommonJS", "CONTENT_MANIFEST_VERSION", "CONTENT_CONTROLS", "CONTENT_RULES", "CONTENT_MANIFEST_LIMITS", "CONTENT_CONTEXTS", "Refusal", "code", "path", "refuse", "reserved", "value", "bounded", "input", "nodes", "visit", "depth", "CONTENT_MANIFEST_LIMITS", "c", "array", "descriptors", "key", "output", "descriptor", "result", "string", "v", "p", "text", "bool", "number", "literal", "values", "pattern", "re", "identifier", "id", "segment", "route", "segments", "part", "apiVersion", "month", "day", "vocabulary", "list", "check", "minimum", "item", "unique", "ids", "object", "shape", "record", "destination", "condition", "context", "CONTENT_CONTEXTS", "optional", "limits", "min", "max", "selector", "field", "kind", "CONTENT_CONTROLS", "extra", "CONTENT_RULES", "keys", "k", "f", "group", "g", "conditions", "other", "coverage", "data", "canonical", "contentManifestDigest", "content", "safe", "bytes", "b", "parseContentManifest", "manifest", "diagnostics", "fields", "_", "i", "error"]
7
+ }