@contentful/experience-design-system-types 2.34.5-dev-build-d08439d.0 → 2.34.5-dev-build-75bf00ac.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 +3 -9
- package/dist/package.json +1 -1
- package/dist/src/cdf/build.d.ts +43 -0
- package/dist/src/cdf/build.js +98 -0
- package/dist/src/cdf/index.d.ts +3 -2
- package/dist/src/cdf/index.js +3 -2
- package/dist/src/cdf/schema.d.ts +32 -8
- package/dist/src/cdf/schema.js +27 -9
- package/dist/src/cdf/types.d.ts +26 -0
- package/dist/src/cdf/types.js +8 -0
- package/dist/src/cdf/validate.d.ts +17 -5
- package/dist/src/cdf/validate.js +32 -14
- package/dist/src/index.d.ts +1 -3
- package/dist/src/index.js +3 -3
- package/package.json +1 -1
- package/dist/src/sources-api/manifest/index.d.ts +0 -5
- package/dist/src/sources-api/manifest/index.js +0 -1
- package/dist/src/sources-api/manifest/utils.d.ts +0 -11
- package/dist/src/sources-api/manifest/utils.js +0 -64
package/README.md
CHANGED
|
@@ -8,22 +8,16 @@ This package is a bundled dependency of `@contentful/experience-design-system-cl
|
|
|
8
8
|
|
|
9
9
|
### CDF — Component Definition Format
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
One typed, validated document for a design system's components and design tokens together — the request body sent to both the preview and apply endpoints. A leaf's `$type` decides what it is (`'component'` vs. a `DESIGN_TOKEN_TYPES` member), so groups can nest either kind side by side. There is no separate manifest envelope.
|
|
12
12
|
|
|
13
|
-
**Exports:** `validateCDF`, `
|
|
13
|
+
**Exports:** `validateCDF`, `parseCDFComponents`, `buildCDF`, `buildFilteredCDF`, `validateSlotReferences`, `CDF_SCHEMA_URL`, `CDF_PROPERTY_TYPES`, `CDFComponentEntry`, `CDFTokenEntry`, `CDFPropertyDefinition`, `CDFValidationError`, `CDFValidationResult`, `CDFDocument`
|
|
14
14
|
|
|
15
15
|
### DTCG — Design Token Community Group
|
|
16
16
|
|
|
17
|
-
Types for `.tokens.json` files following the [W3C DTCG format](https://tr.designtokens.org/format/)
|
|
17
|
+
Types for standalone `.tokens.json` files following the [W3C DTCG format](https://tr.designtokens.org/format/) — used when generating or ingesting raw design tokens ahead of merging them into a CDF document.
|
|
18
18
|
|
|
19
19
|
**Exports:** `DESIGN_TOKEN_TYPES`, `DesignTokenType`, `DTCGTokenEntry`, `DTCGTokenGroup`, `DTCGTokenNode`, `DTCGTokenGroupNode`
|
|
20
20
|
|
|
21
|
-
### Sources API — Manifest
|
|
22
|
-
|
|
23
|
-
Request body sent to both the preview and apply endpoints.
|
|
24
|
-
|
|
25
|
-
**Exports:** `ManifestPayload`
|
|
26
|
-
|
|
27
21
|
### Sources API — Preview
|
|
28
22
|
|
|
29
23
|
Response types for the Sources API preview endpoint, which returns a diff of what will change before committing.
|
package/dist/package.json
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { CDF_SCHEMA_URL } from './schema.js';
|
|
2
|
+
import type { CDFComponentEntry, CDFTokenEntry, CDFValidationError } from './types.js';
|
|
3
|
+
/** Drops `$required` from slot definitions — the server never reads it and
|
|
4
|
+
* older CDF consumers reject unknown slot fields. */
|
|
5
|
+
export declare function stripUnsupportedSlotFields(entry: CDFComponentEntry): CDFComponentEntry;
|
|
6
|
+
/** A CDF document — the single file/wire payload for both components and
|
|
7
|
+
* design tokens. There is no separate manifest envelope. */
|
|
8
|
+
export interface CDFDocument {
|
|
9
|
+
$schema: typeof CDF_SCHEMA_URL;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
export declare function buildCDF(components: Array<{
|
|
13
|
+
key: string;
|
|
14
|
+
entry: CDFComponentEntry;
|
|
15
|
+
}>, tokens: Array<{
|
|
16
|
+
path: string;
|
|
17
|
+
entry: CDFTokenEntry;
|
|
18
|
+
}>, opts?: {
|
|
19
|
+
deleteAll?: boolean;
|
|
20
|
+
}): CDFDocument | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Filters a CDF document down to a selected subset of component keys and
|
|
23
|
+
* token paths, preserving the group nesting each dotted path implies.
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildFilteredCDF(fullDocument: CDFDocument, selectedComponentKeys: Set<string>, selectedTokenPaths: Set<string>): CDFDocument | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Document-local pre-flight for `$allowedComponents` references: every entry
|
|
28
|
+
* must resolve to another component in the same document, or be left for the
|
|
29
|
+
* server to resolve against the target environment (this function has no
|
|
30
|
+
* network access, so it cannot tell "doesn't exist anywhere" from "exists
|
|
31
|
+
* only in the target env" — it only flags names absent from `components`).
|
|
32
|
+
*
|
|
33
|
+
* Mirrors the error shape `previewImport`/`applyImport` return for the
|
|
34
|
+
* equivalent server-side check, so callers can route both through the same
|
|
35
|
+
* `path`/`message` handling — just without a round-trip when the typo is
|
|
36
|
+
* local to the document itself. The `manifest:` path prefix below is a wire
|
|
37
|
+
* contract with the server's own error shape — keep it as-is even though the
|
|
38
|
+
* rest of this module no longer says "manifest".
|
|
39
|
+
*/
|
|
40
|
+
export declare function validateSlotReferences(components: Array<{
|
|
41
|
+
key: string;
|
|
42
|
+
entry: CDFComponentEntry;
|
|
43
|
+
}>): CDFValidationError[];
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { CDF_SCHEMA_URL } from './schema.js';
|
|
2
|
+
/** Drops `$required` from slot definitions — the server never reads it and
|
|
3
|
+
* older CDF consumers reject unknown slot fields. */
|
|
4
|
+
export function stripUnsupportedSlotFields(entry) {
|
|
5
|
+
if (!entry.$slots)
|
|
6
|
+
return entry;
|
|
7
|
+
const cleaned = {};
|
|
8
|
+
for (const [name, slot] of Object.entries(entry.$slots)) {
|
|
9
|
+
const { $required: _required, ...rest } = slot;
|
|
10
|
+
cleaned[name] = rest;
|
|
11
|
+
}
|
|
12
|
+
return { ...entry, $slots: cleaned };
|
|
13
|
+
}
|
|
14
|
+
export function buildCDF(components, tokens, opts = {}) {
|
|
15
|
+
if (components.length === 0 && tokens.length === 0 && !opts.deleteAll)
|
|
16
|
+
return undefined;
|
|
17
|
+
const doc = { $schema: CDF_SCHEMA_URL };
|
|
18
|
+
for (const { key, entry } of components) {
|
|
19
|
+
setAtPath(doc, key, stripUnsupportedSlotFields(entry));
|
|
20
|
+
}
|
|
21
|
+
for (const { path, entry } of tokens) {
|
|
22
|
+
setAtPath(doc, path, entry);
|
|
23
|
+
}
|
|
24
|
+
return doc;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Filters a CDF document down to a selected subset of component keys and
|
|
28
|
+
* token paths, preserving the group nesting each dotted path implies.
|
|
29
|
+
*/
|
|
30
|
+
export function buildFilteredCDF(fullDocument, selectedComponentKeys, selectedTokenPaths) {
|
|
31
|
+
const selected = new Set([...selectedComponentKeys, ...selectedTokenPaths]);
|
|
32
|
+
if (selected.size === 0)
|
|
33
|
+
return undefined;
|
|
34
|
+
const filtered = { $schema: CDF_SCHEMA_URL };
|
|
35
|
+
for (const dottedPath of selected) {
|
|
36
|
+
const value = getAtPath(fullDocument, dottedPath);
|
|
37
|
+
if (value !== undefined)
|
|
38
|
+
setAtPath(filtered, dottedPath, value);
|
|
39
|
+
}
|
|
40
|
+
return filtered;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Document-local pre-flight for `$allowedComponents` references: every entry
|
|
44
|
+
* must resolve to another component in the same document, or be left for the
|
|
45
|
+
* server to resolve against the target environment (this function has no
|
|
46
|
+
* network access, so it cannot tell "doesn't exist anywhere" from "exists
|
|
47
|
+
* only in the target env" — it only flags names absent from `components`).
|
|
48
|
+
*
|
|
49
|
+
* Mirrors the error shape `previewImport`/`applyImport` return for the
|
|
50
|
+
* equivalent server-side check, so callers can route both through the same
|
|
51
|
+
* `path`/`message` handling — just without a round-trip when the typo is
|
|
52
|
+
* local to the document itself. The `manifest:` path prefix below is a wire
|
|
53
|
+
* contract with the server's own error shape — keep it as-is even though the
|
|
54
|
+
* rest of this module no longer says "manifest".
|
|
55
|
+
*/
|
|
56
|
+
export function validateSlotReferences(components) {
|
|
57
|
+
const componentKeys = new Set(components.map((c) => c.key));
|
|
58
|
+
const errors = [];
|
|
59
|
+
for (const { key, entry } of components) {
|
|
60
|
+
const slots = entry.$slots ?? {};
|
|
61
|
+
for (const [slotKey, slot] of Object.entries(slots)) {
|
|
62
|
+
const allowed = slot?.$allowedComponents ?? [];
|
|
63
|
+
const unresolved = allowed.filter((name) => !componentKeys.has(name));
|
|
64
|
+
if (unresolved.length === 0)
|
|
65
|
+
continue;
|
|
66
|
+
errors.push({
|
|
67
|
+
path: `manifest:components/${key}/$slots/${slotKey}/$allowedComponents`,
|
|
68
|
+
message: `Unresolved $allowedComponents reference(s): ${unresolved.join(', ')}. ` +
|
|
69
|
+
`Not found in this document — if not an existing Component in the target ` +
|
|
70
|
+
`environment either, the server will reject this on preview/apply.`,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return errors;
|
|
75
|
+
}
|
|
76
|
+
function setAtPath(root, dottedPath, value) {
|
|
77
|
+
const segments = dottedPath.split('.');
|
|
78
|
+
let cursor = root;
|
|
79
|
+
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
80
|
+
const segment = segments[i];
|
|
81
|
+
const next = cursor[segment];
|
|
82
|
+
if (typeof next !== 'object' || next === null) {
|
|
83
|
+
cursor[segment] = {};
|
|
84
|
+
}
|
|
85
|
+
cursor = cursor[segment];
|
|
86
|
+
}
|
|
87
|
+
cursor[segments[segments.length - 1]] = value;
|
|
88
|
+
}
|
|
89
|
+
function getAtPath(root, dottedPath) {
|
|
90
|
+
const segments = dottedPath.split('.');
|
|
91
|
+
let cursor = root;
|
|
92
|
+
for (const segment of segments) {
|
|
93
|
+
if (typeof cursor !== 'object' || cursor === null)
|
|
94
|
+
return undefined;
|
|
95
|
+
cursor = cursor[segment];
|
|
96
|
+
}
|
|
97
|
+
return cursor;
|
|
98
|
+
}
|
package/dist/src/cdf/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { validateCDF, parseCDFComponents } from './validate.js';
|
|
2
|
-
export {
|
|
2
|
+
export { CDF_SCHEMA_URL, cdfJsonSchema } from './schema.js';
|
|
3
3
|
export { CDF_PROPERTY_TYPES, CDF_PROPERTY_CATEGORIES } from './vocabularies.js';
|
|
4
|
-
export { CDFComponentSchema, CDFPropertySchema, CDFSlotSchema, type CDFComponentEntry, type CDFPropertyDefinition, type CDFSlotDefinition, type CDFValidationError, } from './types.js';
|
|
4
|
+
export { CDFComponentSchema, CDFPropertySchema, CDFSlotSchema, CDFTokenSchema, type CDFComponentEntry, type CDFPropertyDefinition, type CDFSlotDefinition, type CDFTokenEntry, type CDFValidationError, type CDFValidationResult, } from './types.js';
|
|
5
|
+
export { buildCDF, buildFilteredCDF, stripUnsupportedSlotFields, validateSlotReferences, type CDFDocument, } from './build.js';
|
package/dist/src/cdf/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { validateCDF, parseCDFComponents } from './validate.js';
|
|
2
|
-
export {
|
|
2
|
+
export { CDF_SCHEMA_URL, cdfJsonSchema } from './schema.js';
|
|
3
3
|
export { CDF_PROPERTY_TYPES, CDF_PROPERTY_CATEGORIES } from './vocabularies.js';
|
|
4
|
-
export { CDFComponentSchema, CDFPropertySchema, CDFSlotSchema, } from './types.js';
|
|
4
|
+
export { CDFComponentSchema, CDFPropertySchema, CDFSlotSchema, CDFTokenSchema, } from './types.js';
|
|
5
|
+
export { buildCDF, buildFilteredCDF, stripUnsupportedSlotFields, validateSlotReferences, } from './build.js';
|
package/dist/src/cdf/schema.d.ts
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
|
|
1
|
+
export declare const CDF_SCHEMA_URL = "https://contentful.com/schemas/cdf";
|
|
2
|
+
/**
|
|
3
|
+
* Components and design tokens live in one recursive tree. A leaf's `$type`
|
|
4
|
+
* decides what it is ('component' vs. a DESIGN_TOKEN_TYPES member), so the
|
|
5
|
+
* same `group` container can hold either kind side by side. There is no
|
|
6
|
+
* separate manifest envelope — this document is the single file/wire
|
|
7
|
+
* payload sent to preview/apply.
|
|
8
|
+
*/
|
|
9
|
+
export declare const cdfJsonSchema: {
|
|
3
10
|
readonly $schema: "http://json-schema.org/draft-07/schema#";
|
|
4
|
-
readonly $id: "https://contentful.com/schemas/cdf
|
|
5
|
-
readonly title: "CDF Component Definition Format
|
|
11
|
+
readonly $id: "https://contentful.com/schemas/cdf";
|
|
12
|
+
readonly title: "CDF Component + Design Token Definition Format";
|
|
6
13
|
readonly type: "object";
|
|
7
14
|
readonly required: readonly ["$schema"];
|
|
8
15
|
readonly properties: {
|
|
9
16
|
readonly $schema: {
|
|
10
17
|
readonly type: "string";
|
|
11
|
-
readonly const: "https://contentful.com/schemas/cdf
|
|
18
|
+
readonly const: "https://contentful.com/schemas/cdf";
|
|
12
19
|
};
|
|
13
20
|
};
|
|
14
21
|
readonly additionalProperties: {
|
|
15
|
-
readonly $ref: "#/definitions/
|
|
22
|
+
readonly $ref: "#/definitions/groupOrEntry";
|
|
16
23
|
};
|
|
17
24
|
readonly definitions: {
|
|
18
|
-
readonly
|
|
25
|
+
readonly groupOrEntry: {
|
|
19
26
|
readonly oneOf: readonly [{
|
|
20
27
|
readonly $ref: "#/definitions/component";
|
|
28
|
+
}, {
|
|
29
|
+
readonly $ref: "#/definitions/token";
|
|
21
30
|
}, {
|
|
22
31
|
readonly $ref: "#/definitions/group";
|
|
23
32
|
}];
|
|
@@ -103,6 +112,21 @@ export declare const cdfV1JsonSchema: {
|
|
|
103
112
|
};
|
|
104
113
|
readonly additionalProperties: false;
|
|
105
114
|
};
|
|
115
|
+
readonly token: {
|
|
116
|
+
readonly type: "object";
|
|
117
|
+
readonly required: readonly ["$type", "$value"];
|
|
118
|
+
readonly properties: {
|
|
119
|
+
readonly $type: {
|
|
120
|
+
readonly type: "string";
|
|
121
|
+
readonly enum: readonly ["color", "dimension", "fontFamily", "fontWeight", "duration", "cubicBezier", "number", "strokeStyle", "border", "transition", "shadow", "gradient", "typography"];
|
|
122
|
+
};
|
|
123
|
+
readonly $value: {};
|
|
124
|
+
readonly $description: {
|
|
125
|
+
readonly type: "string";
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
readonly additionalProperties: false;
|
|
129
|
+
};
|
|
106
130
|
readonly group: {
|
|
107
131
|
readonly type: "object";
|
|
108
132
|
readonly properties: {
|
|
@@ -111,7 +135,7 @@ export declare const cdfV1JsonSchema: {
|
|
|
111
135
|
};
|
|
112
136
|
};
|
|
113
137
|
readonly additionalProperties: {
|
|
114
|
-
readonly $ref: "#/definitions/
|
|
138
|
+
readonly $ref: "#/definitions/groupOrEntry";
|
|
115
139
|
};
|
|
116
140
|
};
|
|
117
141
|
};
|
package/dist/src/cdf/schema.js
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import { CDF_PROPERTY_TYPES, CDF_PROPERTY_CATEGORIES } from './vocabularies.js';
|
|
2
|
-
|
|
3
|
-
export const
|
|
2
|
+
import { DESIGN_TOKEN_TYPES } from '../dtcg/token-types.js';
|
|
3
|
+
export const CDF_SCHEMA_URL = 'https://contentful.com/schemas/cdf';
|
|
4
|
+
/**
|
|
5
|
+
* Components and design tokens live in one recursive tree. A leaf's `$type`
|
|
6
|
+
* decides what it is ('component' vs. a DESIGN_TOKEN_TYPES member), so the
|
|
7
|
+
* same `group` container can hold either kind side by side. There is no
|
|
8
|
+
* separate manifest envelope — this document is the single file/wire
|
|
9
|
+
* payload sent to preview/apply.
|
|
10
|
+
*/
|
|
11
|
+
export const cdfJsonSchema = {
|
|
4
12
|
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
5
|
-
$id:
|
|
6
|
-
title: 'CDF Component Definition Format
|
|
13
|
+
$id: CDF_SCHEMA_URL,
|
|
14
|
+
title: 'CDF Component + Design Token Definition Format',
|
|
7
15
|
type: 'object',
|
|
8
16
|
required: ['$schema'],
|
|
9
17
|
properties: {
|
|
10
|
-
$schema: { type: 'string', const:
|
|
18
|
+
$schema: { type: 'string', const: CDF_SCHEMA_URL },
|
|
11
19
|
},
|
|
12
|
-
additionalProperties: { $ref: '#/definitions/
|
|
20
|
+
additionalProperties: { $ref: '#/definitions/groupOrEntry' },
|
|
13
21
|
definitions: {
|
|
14
|
-
|
|
15
|
-
oneOf: [{ $ref: '#/definitions/component' }, { $ref: '#/definitions/group' }],
|
|
22
|
+
groupOrEntry: {
|
|
23
|
+
oneOf: [{ $ref: '#/definitions/component' }, { $ref: '#/definitions/token' }, { $ref: '#/definitions/group' }],
|
|
16
24
|
},
|
|
17
25
|
component: {
|
|
18
26
|
type: 'object',
|
|
@@ -55,10 +63,20 @@ export const cdfV1JsonSchema = {
|
|
|
55
63
|
},
|
|
56
64
|
additionalProperties: false,
|
|
57
65
|
},
|
|
66
|
+
token: {
|
|
67
|
+
type: 'object',
|
|
68
|
+
required: ['$type', '$value'],
|
|
69
|
+
properties: {
|
|
70
|
+
$type: { type: 'string', enum: [...DESIGN_TOKEN_TYPES] },
|
|
71
|
+
$value: {},
|
|
72
|
+
$description: { type: 'string' },
|
|
73
|
+
},
|
|
74
|
+
additionalProperties: false,
|
|
75
|
+
},
|
|
58
76
|
group: {
|
|
59
77
|
type: 'object',
|
|
60
78
|
properties: { $description: { type: 'string' } },
|
|
61
|
-
additionalProperties: { $ref: '#/definitions/
|
|
79
|
+
additionalProperties: { $ref: '#/definitions/groupOrEntry' },
|
|
62
80
|
},
|
|
63
81
|
},
|
|
64
82
|
};
|
package/dist/src/cdf/types.d.ts
CHANGED
|
@@ -74,6 +74,28 @@ export interface CDFValidationError {
|
|
|
74
74
|
expected?: string;
|
|
75
75
|
actual?: string;
|
|
76
76
|
}
|
|
77
|
+
/** A token leaf — same shape as a DTCG token entry, but discovered inside
|
|
78
|
+
* the CDF tree rather than a standalone DTCG document. */
|
|
79
|
+
export declare const CDFTokenSchema: z.ZodMiniObject<{
|
|
80
|
+
$type: z.ZodMiniEnum<{
|
|
81
|
+
number: "number";
|
|
82
|
+
color: "color";
|
|
83
|
+
dimension: "dimension";
|
|
84
|
+
fontFamily: "fontFamily";
|
|
85
|
+
fontWeight: "fontWeight";
|
|
86
|
+
duration: "duration";
|
|
87
|
+
cubicBezier: "cubicBezier";
|
|
88
|
+
strokeStyle: "strokeStyle";
|
|
89
|
+
border: "border";
|
|
90
|
+
transition: "transition";
|
|
91
|
+
shadow: "shadow";
|
|
92
|
+
gradient: "gradient";
|
|
93
|
+
typography: "typography";
|
|
94
|
+
}>;
|
|
95
|
+
$value: z.ZodMiniUnknown;
|
|
96
|
+
$description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
97
|
+
}, z.core.$strict>;
|
|
98
|
+
export type CDFTokenEntry = z.infer<typeof CDFTokenSchema>;
|
|
77
99
|
export interface CDFValidationResult {
|
|
78
100
|
valid: boolean;
|
|
79
101
|
errors: CDFValidationError[];
|
|
@@ -81,4 +103,8 @@ export interface CDFValidationResult {
|
|
|
81
103
|
key: string;
|
|
82
104
|
entry: CDFComponentEntry;
|
|
83
105
|
}>;
|
|
106
|
+
tokens: Array<{
|
|
107
|
+
path: string;
|
|
108
|
+
entry: CDFTokenEntry;
|
|
109
|
+
}>;
|
|
84
110
|
}
|
package/dist/src/cdf/types.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as z from 'zod/mini';
|
|
2
2
|
import { CDF_PROPERTY_TYPES, CDF_PROPERTY_CATEGORIES } from './vocabularies.js';
|
|
3
|
+
import { DESIGN_TOKEN_TYPES } from '../dtcg/token-types.js';
|
|
3
4
|
export const CDFPropertySchema = z.strictObject({
|
|
4
5
|
$type: z.enum(CDF_PROPERTY_TYPES),
|
|
5
6
|
$category: z.enum(CDF_PROPERTY_CATEGORIES),
|
|
@@ -21,3 +22,10 @@ export const CDFComponentSchema = z.strictObject({
|
|
|
21
22
|
$properties: z.record(z.string(), CDFPropertySchema),
|
|
22
23
|
$slots: z.optional(z.record(z.string(), CDFSlotSchema)),
|
|
23
24
|
});
|
|
25
|
+
/** A token leaf — same shape as a DTCG token entry, but discovered inside
|
|
26
|
+
* the CDF tree rather than a standalone DTCG document. */
|
|
27
|
+
export const CDFTokenSchema = z.strictObject({
|
|
28
|
+
$type: z.enum(DESIGN_TOKEN_TYPES),
|
|
29
|
+
$value: z.unknown(),
|
|
30
|
+
$description: z.optional(z.string()),
|
|
31
|
+
});
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
import type { CDFComponentEntry, CDFValidationResult } from './types.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import type { CDFComponentEntry, CDFTokenEntry, CDFValidationResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Walks the CDF tree once, splitting every leaf into a component or a
|
|
4
|
+
* token by its `$type` (the two vocabularies — 'component' vs.
|
|
5
|
+
* DESIGN_TOKEN_TYPES — are disjoint by construction). Groups (plain nested
|
|
6
|
+
* objects that are neither) recurse.
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseCDFComponents(obj: Record<string, unknown>, prefix?: string): {
|
|
9
|
+
components: Array<{
|
|
10
|
+
key: string;
|
|
11
|
+
entry: CDFComponentEntry;
|
|
12
|
+
}>;
|
|
13
|
+
tokens: Array<{
|
|
14
|
+
path: string;
|
|
15
|
+
entry: CDFTokenEntry;
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
6
18
|
export declare function validateCDF(input: unknown): CDFValidationResult;
|
package/dist/src/cdf/validate.js
CHANGED
|
@@ -1,26 +1,43 @@
|
|
|
1
1
|
import { Ajv } from 'ajv';
|
|
2
|
-
import {
|
|
2
|
+
import { cdfJsonSchema, CDF_SCHEMA_URL } from './schema.js';
|
|
3
|
+
import { DESIGN_TOKEN_TYPES } from '../dtcg/token-types.js';
|
|
3
4
|
const ajv = new Ajv({ allErrors: true });
|
|
4
|
-
const validate = ajv.compile(
|
|
5
|
+
const validate = ajv.compile(cdfJsonSchema);
|
|
6
|
+
const TOKEN_TYPE_SET = new Set(DESIGN_TOKEN_TYPES);
|
|
5
7
|
function isComponentEntry(value) {
|
|
8
|
+
return typeof value === 'object' && value !== null && value['$type'] === 'component';
|
|
9
|
+
}
|
|
10
|
+
function isTokenEntry(value) {
|
|
6
11
|
return (typeof value === 'object' &&
|
|
7
12
|
value !== null &&
|
|
8
|
-
'$type'
|
|
9
|
-
value['$type'] === 'component');
|
|
13
|
+
TOKEN_TYPE_SET.has(value['$type']));
|
|
10
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Walks the CDF tree once, splitting every leaf into a component or a
|
|
17
|
+
* token by its `$type` (the two vocabularies — 'component' vs.
|
|
18
|
+
* DESIGN_TOKEN_TYPES — are disjoint by construction). Groups (plain nested
|
|
19
|
+
* objects that are neither) recurse.
|
|
20
|
+
*/
|
|
11
21
|
export function parseCDFComponents(obj, prefix = '') {
|
|
12
|
-
const
|
|
22
|
+
const components = [];
|
|
23
|
+
const tokens = [];
|
|
13
24
|
for (const [key, value] of Object.entries(obj)) {
|
|
14
25
|
if (key.startsWith('$'))
|
|
15
26
|
continue;
|
|
27
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
16
28
|
if (isComponentEntry(value)) {
|
|
17
|
-
|
|
29
|
+
components.push({ key: path, entry: value });
|
|
30
|
+
}
|
|
31
|
+
else if (isTokenEntry(value)) {
|
|
32
|
+
tokens.push({ path, entry: value });
|
|
18
33
|
}
|
|
19
34
|
else if (typeof value === 'object' && value !== null) {
|
|
20
|
-
|
|
35
|
+
const nested = parseCDFComponents(value, path);
|
|
36
|
+
components.push(...nested.components);
|
|
37
|
+
tokens.push(...nested.tokens);
|
|
21
38
|
}
|
|
22
39
|
}
|
|
23
|
-
return
|
|
40
|
+
return { components, tokens };
|
|
24
41
|
}
|
|
25
42
|
export function validateCDF(input) {
|
|
26
43
|
const valid = validate(input);
|
|
@@ -30,23 +47,24 @@ export function validateCDF(input) {
|
|
|
30
47
|
message: err.message ?? 'Unknown validation error',
|
|
31
48
|
expected: err.params ? JSON.stringify(err.params) : undefined,
|
|
32
49
|
}));
|
|
33
|
-
return { valid: false, errors, components: [] };
|
|
50
|
+
return { valid: false, errors, components: [], tokens: [] };
|
|
34
51
|
}
|
|
35
52
|
const file = input;
|
|
36
|
-
if (file.$schema !==
|
|
53
|
+
if (file.$schema !== CDF_SCHEMA_URL) {
|
|
37
54
|
return {
|
|
38
55
|
valid: false,
|
|
39
56
|
errors: [
|
|
40
57
|
{
|
|
41
58
|
path: '/$schema',
|
|
42
|
-
message: `Expected schema "${
|
|
43
|
-
expected:
|
|
59
|
+
message: `Expected schema "${CDF_SCHEMA_URL}"`,
|
|
60
|
+
expected: CDF_SCHEMA_URL,
|
|
44
61
|
actual: file.$schema,
|
|
45
62
|
},
|
|
46
63
|
],
|
|
47
64
|
components: [],
|
|
65
|
+
tokens: [],
|
|
48
66
|
};
|
|
49
67
|
}
|
|
50
|
-
const components = parseCDFComponents(file);
|
|
51
|
-
return { valid: true, errors: [], components };
|
|
68
|
+
const { components, tokens } = parseCDFComponents(file);
|
|
69
|
+
return { valid: true, errors: [], components, tokens };
|
|
52
70
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export { validateCDF, parseCDFComponents,
|
|
1
|
+
export { validateCDF, parseCDFComponents, CDF_SCHEMA_URL, cdfJsonSchema, CDF_PROPERTY_TYPES, CDF_PROPERTY_CATEGORIES, CDFComponentSchema, CDFPropertySchema, CDFSlotSchema, CDFTokenSchema, buildCDF, buildFilteredCDF, stripUnsupportedSlotFields, validateSlotReferences, type CDFComponentEntry, type CDFPropertyDefinition, type CDFSlotDefinition, type CDFTokenEntry, type CDFValidationError, type CDFValidationResult, type CDFDocument, } from './cdf/index.js';
|
|
2
2
|
export { DESIGN_TOKEN_TYPES, flattenDTCG, validateDTCG, DTCGTokenSchema, type DesignTokenType, type DTCGTokenEntry, type DTCGTokenGroup, type DTCGTokenNode, type DTCGTokenGroupNode, type DTCGValidationError, type DTCGValidationResult, } from './dtcg/index.js';
|
|
3
3
|
export type { BreakingChange, ChangeClassification, DownstreamImpact, PropertySummary, ComponentTypeSummary, DesignTokenSummary, TaxonomySummary, ChangedEntity, EntityDiffGroup, ServerPreviewResponse, } from './sources-api/preview/index.js';
|
|
4
4
|
export type { ApplyOperationStatus, ApplyOperationItemError, ApplyOperationItem, ApplyOperationResponse, ApplyGateError, } from './sources-api/apply/index.js';
|
|
5
|
-
export type { ManifestPayload } from './sources-api/manifest/index.js';
|
|
6
|
-
export { buildManifest, buildFilteredManifest, stripUnsupportedSlotFields } from './sources-api/manifest/index.js';
|
package/dist/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// CDF (Component Definition Format) exports
|
|
2
|
-
|
|
1
|
+
// CDF (Component Definition Format) exports — one schema/file for both
|
|
2
|
+
// components and design tokens, no separate manifest envelope.
|
|
3
|
+
export { validateCDF, parseCDFComponents, CDF_SCHEMA_URL, cdfJsonSchema, CDF_PROPERTY_TYPES, CDF_PROPERTY_CATEGORIES, CDFComponentSchema, CDFPropertySchema, CDFSlotSchema, CDFTokenSchema, buildCDF, buildFilteredCDF, stripUnsupportedSlotFields, validateSlotReferences, } from './cdf/index.js';
|
|
3
4
|
// DTCG (W3C Design Token Community Group)
|
|
4
5
|
export { DESIGN_TOKEN_TYPES, flattenDTCG, validateDTCG, DTCGTokenSchema, } from './dtcg/index.js';
|
|
5
|
-
export { buildManifest, buildFilteredManifest, stripUnsupportedSlotFields } from './sources-api/manifest/index.js';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { buildManifest, buildFilteredManifest, stripUnsupportedSlotFields } from './utils.js';
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { CDFComponentEntry } from '../../cdf/index.js';
|
|
2
|
-
import type { DTCGTokenEntry } from '../../dtcg/types.js';
|
|
3
|
-
import type { ManifestPayload } from './index.js';
|
|
4
|
-
export declare function stripUnsupportedSlotFields(entry: CDFComponentEntry): CDFComponentEntry;
|
|
5
|
-
export declare function buildManifest(components: Array<{
|
|
6
|
-
key: string;
|
|
7
|
-
entry: CDFComponentEntry;
|
|
8
|
-
}>, tokens: DTCGTokenEntry[], opts?: {
|
|
9
|
-
deleteAllComponents?: boolean;
|
|
10
|
-
}): ManifestPayload;
|
|
11
|
-
export declare function buildFilteredManifest(fullManifest: ManifestPayload, selectedComponentKeys: Set<string>, selectedTokenPaths: Set<string>): ManifestPayload;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { CDF_V1_SCHEMA_URL } from '../../cdf/index.js';
|
|
2
|
-
export function stripUnsupportedSlotFields(entry) {
|
|
3
|
-
if (!entry.$slots)
|
|
4
|
-
return entry;
|
|
5
|
-
const cleaned = {};
|
|
6
|
-
for (const [name, slot] of Object.entries(entry.$slots)) {
|
|
7
|
-
const { $required: _required, ...rest } = slot;
|
|
8
|
-
cleaned[name] = rest;
|
|
9
|
-
}
|
|
10
|
-
return { ...entry, $slots: cleaned };
|
|
11
|
-
}
|
|
12
|
-
export function buildManifest(components, tokens, opts = {}) {
|
|
13
|
-
const manifest = {};
|
|
14
|
-
// With components, emit them. With none, normally omit the key entirely — but
|
|
15
|
-
// when `deleteAllComponents` is set, emit an empty-but-present manifest so the
|
|
16
|
-
// server diffs it as "remove every existing component" (delete-all). An
|
|
17
|
-
// omitted key is a no-op; a present-empty one is an explicit clear.
|
|
18
|
-
if (components.length > 0 || opts.deleteAllComponents) {
|
|
19
|
-
const componentsObj = { $schema: CDF_V1_SCHEMA_URL };
|
|
20
|
-
for (const { key, entry } of components) {
|
|
21
|
-
componentsObj[key] = stripUnsupportedSlotFields(entry);
|
|
22
|
-
}
|
|
23
|
-
manifest.componentsManifest = componentsObj;
|
|
24
|
-
}
|
|
25
|
-
if (tokens.length > 0) {
|
|
26
|
-
const tokensObj = {};
|
|
27
|
-
for (const token of tokens) {
|
|
28
|
-
tokensObj[token.path] = {
|
|
29
|
-
$type: token.$type,
|
|
30
|
-
$value: token.$value,
|
|
31
|
-
...(token.$description ? { $description: token.$description } : {}),
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
manifest.tokensManifest = tokensObj;
|
|
35
|
-
}
|
|
36
|
-
return manifest;
|
|
37
|
-
}
|
|
38
|
-
export function buildFilteredManifest(fullManifest, selectedComponentKeys, selectedTokenPaths) {
|
|
39
|
-
const filtered = {};
|
|
40
|
-
if (fullManifest.componentsManifest) {
|
|
41
|
-
const obj = {};
|
|
42
|
-
if (fullManifest.componentsManifest['$schema']) {
|
|
43
|
-
obj['$schema'] = fullManifest.componentsManifest['$schema'];
|
|
44
|
-
}
|
|
45
|
-
for (const [key, value] of Object.entries(fullManifest.componentsManifest)) {
|
|
46
|
-
if (key === '$schema')
|
|
47
|
-
continue;
|
|
48
|
-
if (selectedComponentKeys.has(key))
|
|
49
|
-
obj[key] = value;
|
|
50
|
-
}
|
|
51
|
-
if (Object.keys(obj).length > 1)
|
|
52
|
-
filtered.componentsManifest = obj;
|
|
53
|
-
}
|
|
54
|
-
if (fullManifest.tokensManifest) {
|
|
55
|
-
const obj = {};
|
|
56
|
-
for (const [path, value] of Object.entries(fullManifest.tokensManifest)) {
|
|
57
|
-
if (selectedTokenPaths.has(path))
|
|
58
|
-
obj[path] = value;
|
|
59
|
-
}
|
|
60
|
-
if (Object.keys(obj).length > 0)
|
|
61
|
-
filtered.tokensManifest = obj;
|
|
62
|
-
}
|
|
63
|
-
return filtered;
|
|
64
|
-
}
|