@weatherboard/cms 0.10.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 +60 -0
- package/dist/content-manifest/index.d.cts +7 -0
- package/dist/content-manifest/index.d.mts +7 -0
- package/dist/content-manifest/index.d.ts +7 -0
- package/dist/content-manifest/registry.d.cts +32 -0
- package/dist/content-manifest/registry.d.mts +32 -0
- package/dist/content-manifest/registry.d.ts +32 -0
- package/dist/content-manifest/types.d.cts +123 -0
- package/dist/content-manifest/types.d.mts +123 -0
- package/dist/content-manifest/types.d.ts +123 -0
- package/dist/content-manifest.cjs +2 -0
- package/dist/content-manifest.cjs.map +7 -0
- package/dist/content-manifest.d.cts +1 -0
- package/dist/content-manifest.d.mts +1 -0
- package/dist/content-manifest.d.ts +1 -0
- package/dist/content-manifest.mjs +2 -0
- package/dist/content-manifest.mjs.map +7 -0
- package/package.json +13 -2
package/README.md
CHANGED
|
@@ -308,3 +308,63 @@ that this source change alone cannot supply.
|
|
|
308
308
|
|
|
309
309
|
0.4.0 raises the tagline safety cap to 40, refuses all-caps taglines and preserves
|
|
310
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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './content-manifest/index.cjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './content-manifest/index.mjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './content-manifest/index.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var x=1,C=Object.freeze({"plain-text":!0,paragraph:!0,"keyed-text-list":!0,enum:!0,"portable-text":!1,"ordered-list":!1,image:!1,reference:!1}),V=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}),M=Object.freeze({season:"keyed-list-keys"});var p=class extends Error{constructor(n,s){super(n);this.code=n;this.path=s}code;path};function r(e,t){throw new p(e,t)}var R=e=>["__proto__","prototype","constructor"].includes(e.toLowerCase());function U(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),(R(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 T=Object.create(null);for(let[f,b]of Object.entries(_))d&&f==="length"||((!b.enumerable||!("value"in b)||R(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),T[f]=n(b.value,`${i}/${f}`,c+1));return d?(Object.keys(T).length!==o.length&&r("UNSAFE_CONTENT",i),Object.values(T)):T},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)},A=(e,t)=>{typeof e!="boolean"&&r("INVALID_SHAPE",t)},h=(e,t)=>{(!Number.isSafeInteger(e)||e<0)&&r("INVALID_SHAPE",t)},N=(e,t="INVALID_SHAPE")=>(n,s)=>{e.includes(n)||r(t,s)},$=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}$/),D=y(/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/),F=(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)},z=(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)},L=(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}`)},P=a({route:F,slot:g,component:g}),j=(e,t)=>{let n=e&&typeof e=="object"&&Object.hasOwn(e,"context");a({...n?{context:O(Object.keys(M),"UNKNOWN_CONTEXT")}:{fieldKey:g},equals:m,destinations:l(P,1)})(e,t)},K=e=>(t,n)=>{t!==void 0&&e(t,n)},G=(e,t)=>{a({min:h,max:h})(e,t);let{min:n,max:s}=e;(n>s||s>u.string)&&r("INVALID_LIMITS",t)},H=(e,t)=>{if(e?.kind==="singleton")a({kind:N(["singleton"]),id:k})(e,t);else{a({kind:N(["collection"]),eligibleIds:L,maxDocuments:h})(e,t);let s=e;(s.maxDocuments<1||s.maxDocuments>s.eligibleIds.length)&&r("INVALID_LIMITS",t)}},W=(e,t)=>{let n=e?.kind;O(Object.keys(C),"UNKNOWN_CONTROL")(n,`${t}/kind`);let s=n==="enum"?{options:L}:n==="keyed-text-list"?{keys:l(a({key:g,label:I,conditions:K(l(j))}),1)}:n==="reference"?{eligibleIds:L,documentType:D}:{};a({key:g,path:l(D,1),label:I,kind:I,required:A,classification:N(["visible","metadata","accessibility","control","unsupported"]),rules:l(O(Object.keys(V),"UNKNOWN_RULE")),limits:G,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(P,1),conditions:l(j)})(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`)},Z=(e,t)=>{a({key:g,label:I,documentType:D,selector:H,create:A,delete:A,fields:l(W,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`)}},B=(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)},w=a({revision:k,sanity:a({projectId:y(/^[a-z0-9]{8}$/),dataset:y(/^[a-z0-9][a-z0-9_-]{0,63}$/),apiVersion:z,perspective:O(["published"],"INVALID_BINDING")}),controlVersion:N([1],"UNKNOWN_VERSION"),validatorVersion:N([1],"UNKNOWN_VERSION"),coverage:B,warnings:l(I),groups:l(Z)});function S(e){return Array.isArray(e)?`[${e.map(S).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${S(e[t])}`).join(",")}}`:JSON.stringify(e)}async function X(e){let t=U(e);w(t,"/content");let n=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(S(t)));return Array.from(new Uint8Array(n),s=>s.toString(16).padStart(2,"0")).join("")}async function J(e){try{let t=U(e);a({protocolVersion:N([1],"UNKNOWN_PROTOCOL"),digest:$(/^[a-f0-9]{64}$/),repository:a({owner:k,name:k}),build:a({commit:$(/^[a-f0-9]{40}$/),deploymentId:k,environment:N(["production","preview"])}),content:w})(t,"");let n=t;E(n.content.groups.map(i=>i.key),"/content/groups"),n.digest!==await X(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 C[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:!C[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 p?t.code:"UNSAFE_CONTENT",path:t instanceof p?t.path:""}]}}}export{M as CONTENT_CONTEXTS,C as CONTENT_CONTROLS,u as CONTENT_MANIFEST_LIMITS,x as CONTENT_MANIFEST_VERSION,V as CONTENT_RULES,X as contentManifestDigest,J as parseContentManifest};
|
|
2
|
+
//# sourceMappingURL=content-manifest.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/content-manifest/registry.ts", "../src/content-manifest/index.ts"],
|
|
4
|
+
"sourcesContent": ["/** 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_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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weatherboard/cms",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Published-content contracts, server readers, adapters and portable content tooling.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -113,6 +113,16 @@
|
|
|
113
113
|
"types": "./dist/fact-guard.d.cts",
|
|
114
114
|
"default": "./dist/fact-guard.cjs"
|
|
115
115
|
}
|
|
116
|
+
},
|
|
117
|
+
"./content-manifest": {
|
|
118
|
+
"import": {
|
|
119
|
+
"types": "./dist/content-manifest.d.mts",
|
|
120
|
+
"default": "./dist/content-manifest.mjs"
|
|
121
|
+
},
|
|
122
|
+
"require": {
|
|
123
|
+
"types": "./dist/content-manifest.d.cts",
|
|
124
|
+
"default": "./dist/content-manifest.cjs"
|
|
125
|
+
}
|
|
116
126
|
}
|
|
117
127
|
},
|
|
118
128
|
"main": "./dist/index.cjs",
|
|
@@ -131,7 +141,8 @@
|
|
|
131
141
|
"webhook": 16384,
|
|
132
142
|
"site-content": 32768,
|
|
133
143
|
"facts": 8192,
|
|
134
|
-
"fact-guard": 8192
|
|
144
|
+
"fact-guard": 8192,
|
|
145
|
+
"content-manifest": 8192
|
|
135
146
|
},
|
|
136
147
|
"dependencies": {
|
|
137
148
|
"server-only": "0.0.1"
|