@adobe/design-data-spec 3.1.0 → 3.2.1
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/conformance/diff/cross-format/expected.json +2 -2
- package/conformance/diff/deprecated-new-token/new/tokens.tokens.json +1 -1
- package/conformance/diff/matched-gaining-deprecated/expected.json +1 -1
- package/conformance/diff/matched-gaining-deprecated/new/tokens.tokens.json +1 -1
- package/conformance/diff/replaced-by-pairing/expected.json +8 -8
- package/conformance/diff/replaced-by-pairing/old/tokens.tokens.json +5 -3
- package/conformance/diff/reverted-token/old/tokens.tokens.json +1 -1
- package/conformance/generation/ctr-legacy-key/expected/button.json +8 -0
- package/conformance/generation/ctr-legacy-key/expected/tokens.json +7 -0
- package/conformance/generation/ctr-legacy-key/input/tokens.tokens.json +8 -0
- package/conformance/generation/ctr-legacy-key/relationships/button.json +14 -0
- package/conformance/generation/deprecated-token/input/tokens.tokens.json +5 -3
- package/conformance/generation/mode-set-edit/input/tokens.tokens.json +8 -4
- package/conformance/generation/renamed-token/input/tokens.tokens.json +4 -2
- package/conformance/invalid/SPEC-010/dataset.json +4 -2
- package/conformance/invalid/SPEC-010/expected-errors.json +1 -1
- package/conformance/invalid/SPEC-010/tokens.tokens.json +4 -2
- package/conformance/invalid/SPEC-011/dataset.json +7 -5
- package/conformance/invalid/SPEC-011/expected-errors.json +1 -1
- package/conformance/invalid/SPEC-011/tokens.tokens.json +7 -5
- package/conformance/invalid/SPEC-012/dataset.json +1 -1
- package/conformance/invalid/SPEC-012/expected-errors.json +1 -1
- package/conformance/invalid/SPEC-012/tokens.tokens.json +1 -1
- package/conformance/invalid/SPEC-013/dataset.json +1 -1
- package/conformance/invalid/SPEC-013/tokens.tokens.json +1 -1
- package/conformance/invalid/SPEC-014/dataset.json +1 -1
- package/conformance/invalid/SPEC-014/tokens.tokens.json +1 -1
- package/conformance/invalid/SPEC-036/dataset.json +1 -1
- package/conformance/invalid/SPEC-037/dataset.json +3 -3
- package/conformance/invalid/SPEC-051/dataset.json +16 -0
- package/conformance/invalid/SPEC-051/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-052/dataset.json +24 -0
- package/conformance/invalid/SPEC-052/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-053/dataset.json +26 -0
- package/conformance/invalid/SPEC-053/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-054/dataset.json +24 -0
- package/conformance/invalid/SPEC-054/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-055/dataset.json +16 -0
- package/conformance/invalid/SPEC-055/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-056/dataset.json +22 -0
- package/conformance/invalid/SPEC-056/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-057/dataset.json +21 -0
- package/conformance/invalid/SPEC-057/expected-errors.json +10 -0
- package/conformance/valid/SPEC-014/dataset.json +1 -1
- package/conformance/valid/SPEC-036/dataset.json +2 -2
- package/conformance/valid/SPEC-037/dataset.json +6 -6
- package/conformance/valid/SPEC-051/dataset.json +42 -0
- package/conformance/valid/lifecycle-with-last-modified.json +1 -1
- package/package.json +1 -1
- package/rules/rules.yaml +98 -2
- package/schemas/component.schema.json +4 -4
- package/schemas/relationship.schema.json +228 -0
- package/schemas/token.schema.json +38 -48
- package/spec/agent-surface.md +13 -13
- package/spec/authoring-workflow.md +39 -39
- package/spec/dataset-layout.md +1 -1
- package/spec/evolution.md +20 -20
- package/spec/index.md +2 -0
- package/spec/relationship-format.md +103 -0
- package/spec/token-format.md +39 -27
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"property": "color"
|
|
14
14
|
},
|
|
15
15
|
"value": "#000000",
|
|
16
|
-
"
|
|
16
|
+
"lifecycle": { "deprecatedIn": "1.0.0-draft" }
|
|
17
17
|
}
|
|
18
18
|
],
|
|
19
19
|
"components": [
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"documentationUrl": "https://spectrum.adobe.com/page/old-widget/"
|
|
36
36
|
},
|
|
37
37
|
"lifecycle": {
|
|
38
|
-
"
|
|
38
|
+
"deprecatedIn": "1.0.0-draft",
|
|
39
39
|
"deprecatedComment": "Superseded by new-widget."
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"property": "background-color"
|
|
16
16
|
},
|
|
17
17
|
"value": "#0265dc",
|
|
18
|
-
"
|
|
18
|
+
"lifecycle": { "deprecatedIn": "1.0.0-draft" }
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"name": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"property": "background-color"
|
|
33
33
|
},
|
|
34
34
|
"value": "#cccccc",
|
|
35
|
-
"
|
|
35
|
+
"lifecycle": { "deprecatedIn": "1.0.0-draft" }
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
"name": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"property": "background-color"
|
|
50
50
|
},
|
|
51
51
|
"value": "#0265dc",
|
|
52
|
-
"
|
|
52
|
+
"lifecycle": { "deprecatedIn": "1.0.0-draft" }
|
|
53
53
|
}
|
|
54
54
|
],
|
|
55
55
|
"components": [
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
{
|
|
69
69
|
"name": "handle",
|
|
70
70
|
"lifecycle": {
|
|
71
|
-
"
|
|
71
|
+
"deprecatedIn": "1.0.0-draft",
|
|
72
72
|
"deprecatedComment": "Renamed to thumb."
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
{
|
|
90
90
|
"name": "pressed",
|
|
91
91
|
"lifecycle": {
|
|
92
|
-
"
|
|
92
|
+
"deprecatedIn": "1.0.0-draft",
|
|
93
93
|
"deprecatedComment": "Use active instead."
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
{
|
|
108
108
|
"value": "cta",
|
|
109
109
|
"lifecycle": {
|
|
110
|
-
"
|
|
110
|
+
"deprecatedIn": "1.0.0-draft",
|
|
111
111
|
"deprecatedComment": "Use primary instead."
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"relationships": [
|
|
3
|
+
{
|
|
4
|
+
"scope": {
|
|
5
|
+
"component": "button",
|
|
6
|
+
"part": "label",
|
|
7
|
+
"property": "background-color",
|
|
8
|
+
"options": { "style": "fill", "state": ["hover"] }
|
|
9
|
+
},
|
|
10
|
+
"value": "#ff0000",
|
|
11
|
+
"uuid": "33333333-3333-3333-3333-333333333333",
|
|
12
|
+
"legacyKey": "button-label-background-color-fill-hover"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"scope": { "component": "button", "property": "border-color" },
|
|
16
|
+
"context": "informative border color",
|
|
17
|
+
"$ref": "33333333-3333-3333-3333-333333333333"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"components": [
|
|
21
|
+
{
|
|
22
|
+
"$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/components/button.json",
|
|
23
|
+
"name": "button",
|
|
24
|
+
"displayName": "Button",
|
|
25
|
+
"meta": { "category": "actions" },
|
|
26
|
+
"anatomy": [
|
|
27
|
+
{ "name": "icon", "description": "Leading icon." },
|
|
28
|
+
{ "name": "label", "description": "Button text.", "required": true }
|
|
29
|
+
],
|
|
30
|
+
"options": {
|
|
31
|
+
"style": {
|
|
32
|
+
"type": "enum",
|
|
33
|
+
"values": [{ "value": "fill" }, { "value": "outline" }]
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"states": [
|
|
37
|
+
{ "name": "hover", "trigger": "interaction", "precedence": 50 },
|
|
38
|
+
{ "name": "disabled", "trigger": "prop", "precedence": 100 }
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
package/package.json
CHANGED
package/rules/rules.yaml
CHANGED
|
@@ -96,7 +96,7 @@ rules:
|
|
|
96
96
|
name: replaced-by-array-requires-comment
|
|
97
97
|
severity: error
|
|
98
98
|
category: completeness
|
|
99
|
-
assert: When replaced_by is an array, deprecated_comment MUST be present to explain which replacement applies in which
|
|
99
|
+
assert: When replaced_by is an array, deprecated_comment MUST be present to explain which replacement applies in which scope.
|
|
100
100
|
message: "replaced_by is an array but deprecated_comment is missing on token {token}"
|
|
101
101
|
spec_ref: spec/token-format.md#lifecycle-and-metadata
|
|
102
102
|
introduced_in: "1.0.0-draft"
|
|
@@ -322,7 +322,7 @@ rules:
|
|
|
322
322
|
assert: >
|
|
323
323
|
A validator MUST NOT flag a registry ID as invalid solely because that same ID appears in
|
|
324
324
|
a different registry. Registry IDs are scoped to their registry; cross-registry overlap is
|
|
325
|
-
intentional when the same word is a valid term in each registry's distinct validation
|
|
325
|
+
intentional when the same word is a valid term in each registry's distinct validation scope.
|
|
326
326
|
message: "Registry ID '{id}' appears in multiple registries — this is permitted; do not reject on cross-registry overlap alone"
|
|
327
327
|
spec_ref: spec/registry.md#id-scoping
|
|
328
328
|
introduced_in: "1.0.0-draft"
|
|
@@ -594,3 +594,99 @@ rules:
|
|
|
594
594
|
message: "Token '{token}' fuses '{field}' concept '{value}' into name.property; decompose into the structured field"
|
|
595
595
|
spec_ref: spec/token-format.md#name-object
|
|
596
596
|
introduced_in: "1.0.0-draft"
|
|
597
|
+
|
|
598
|
+
- id: SPEC-051
|
|
599
|
+
name: ctr-component-exists
|
|
600
|
+
severity: error
|
|
601
|
+
layer: 2
|
|
602
|
+
category: reference-integrity
|
|
603
|
+
assert: >
|
|
604
|
+
A Component/Token Relationship (CTR)'s `scope.component` value MUST match the
|
|
605
|
+
`name` of a declared component in the dataset. Mirrors SPEC-018
|
|
606
|
+
(component-name-exists) for the CTR scope object.
|
|
607
|
+
message: "Relationship '{relationship}' references undeclared component '{component}'"
|
|
608
|
+
spec_ref: spec/relationship-format.md#scope-fields
|
|
609
|
+
introduced_in: "1.0.0-draft"
|
|
610
|
+
|
|
611
|
+
- id: SPEC-052
|
|
612
|
+
name: ctr-part-valid
|
|
613
|
+
severity: error
|
|
614
|
+
layer: 2
|
|
615
|
+
category: reference-integrity
|
|
616
|
+
assert: >
|
|
617
|
+
A CTR's `scope.part` value, when present, MUST match the `name` of a declared
|
|
618
|
+
anatomy part on the referenced component. Mirrors SPEC-020
|
|
619
|
+
(component-anatomy-valid) for the CTR scope object.
|
|
620
|
+
message: "Relationship '{relationship}' references undeclared anatomy part '{part}' on component '{component}'"
|
|
621
|
+
spec_ref: spec/relationship-format.md#scope-fields
|
|
622
|
+
introduced_in: "1.0.0-draft"
|
|
623
|
+
|
|
624
|
+
- id: SPEC-053
|
|
625
|
+
name: ctr-option-valid
|
|
626
|
+
severity: error
|
|
627
|
+
layer: 2
|
|
628
|
+
category: reference-integrity
|
|
629
|
+
assert: >
|
|
630
|
+
A CTR's `scope.options.<key>` value MUST match a value in the declared
|
|
631
|
+
`options.<key>.values` list for the referenced component, when that list exists.
|
|
632
|
+
Combines the intent of SPEC-019 (component-variant-valid, error) and SPEC-040
|
|
633
|
+
(component-option-field-valid, warning) into a single error-severity rule for
|
|
634
|
+
CTRs, since a CTR's options are the whole of its scope rather than one field
|
|
635
|
+
among many name-object keys.
|
|
636
|
+
message: "Relationship '{relationship}' has {key} '{value}' which is not declared on component '{component}'"
|
|
637
|
+
spec_ref: spec/relationship-format.md#scope-fields
|
|
638
|
+
introduced_in: "1.0.0-draft"
|
|
639
|
+
|
|
640
|
+
- id: SPEC-054
|
|
641
|
+
name: ctr-state-valid
|
|
642
|
+
severity: error
|
|
643
|
+
layer: 2
|
|
644
|
+
category: reference-integrity
|
|
645
|
+
assert: >
|
|
646
|
+
Each element of a CTR's `scope.options.state` array MUST match the `name` of a
|
|
647
|
+
declared state on the referenced component, when state declarations are present.
|
|
648
|
+
Mirrors SPEC-022 (component-state-valid) for the CTR scope object.
|
|
649
|
+
message: "Relationship '{relationship}' references undeclared state '{state}' on component '{component}'"
|
|
650
|
+
spec_ref: spec/relationship-format.md#scope-fields
|
|
651
|
+
introduced_in: "1.0.0-draft"
|
|
652
|
+
|
|
653
|
+
- id: SPEC-055
|
|
654
|
+
name: ctr-ref-resolves
|
|
655
|
+
severity: error
|
|
656
|
+
layer: 2
|
|
657
|
+
category: reference-integrity
|
|
658
|
+
assert: >
|
|
659
|
+
A CTR's `$ref` value MUST resolve to a declared token or relationship `uuid` in
|
|
660
|
+
the dataset. Mirrors SPEC-001 (alias-target-exists) and SPEC-027
|
|
661
|
+
(token-binding-token-exists) for the CTR alias direction.
|
|
662
|
+
message: "Relationship alias target not found for $ref: {target}"
|
|
663
|
+
spec_ref: spec/relationship-format.md#value-owning-vs-relationship-only
|
|
664
|
+
introduced_in: "1.0.0-draft"
|
|
665
|
+
|
|
666
|
+
- id: SPEC-056
|
|
667
|
+
name: ctr-uuid-unique
|
|
668
|
+
severity: error
|
|
669
|
+
layer: 2
|
|
670
|
+
category: reference-integrity
|
|
671
|
+
assert: >
|
|
672
|
+
CTR `uuid` values MUST be unique across all relationship entries within the same
|
|
673
|
+
cascade layer. Mirrors SPEC-004 (uuid-global-uniqueness) for relationships.
|
|
674
|
+
message: "Duplicate relationship uuid {uuid}"
|
|
675
|
+
spec_ref: spec/relationship-format.md#identity
|
|
676
|
+
introduced_in: "1.0.0-draft"
|
|
677
|
+
|
|
678
|
+
- id: SPEC-057
|
|
679
|
+
name: ctr-legacykey-present-if-legacy
|
|
680
|
+
severity: warning
|
|
681
|
+
layer: 2
|
|
682
|
+
category: naming-consistency
|
|
683
|
+
note: >
|
|
684
|
+
Advisory placeholder. Detecting "this CTR should have a legacy counterpart" is a
|
|
685
|
+
generator-side determination deferred to the legacy-migration phase; this rule
|
|
686
|
+
documents intent rather than enforcing it structurally.
|
|
687
|
+
assert: >
|
|
688
|
+
A CTR that round-trips through the legacy generator (packages/tokens/src) SHOULD
|
|
689
|
+
carry `legacyKey`. Not structurally enforced in this foundation.
|
|
690
|
+
message: "Relationship '{relationship}' may need a legacyKey to round-trip through the legacy generator"
|
|
691
|
+
spec_ref: spec/relationship-format.md#legacy-fields-interim
|
|
692
|
+
introduced_in: "1.0.0-draft"
|
|
@@ -179,7 +179,7 @@
|
|
|
179
179
|
},
|
|
180
180
|
"lifecycle": {
|
|
181
181
|
"$ref": "#/$defs/lifecycle",
|
|
182
|
-
"description": "Version lifecycle metadata for this value. Set lifecycle.
|
|
182
|
+
"description": "Version lifecycle metadata for this value. Set lifecycle.deprecatedIn to signal that tokens referencing this value should migrate (SPEC-037)."
|
|
183
183
|
}
|
|
184
184
|
},
|
|
185
185
|
"additionalProperties": false
|
|
@@ -234,7 +234,7 @@
|
|
|
234
234
|
},
|
|
235
235
|
"lifecycle": {
|
|
236
236
|
"$ref": "#/$defs/lifecycle",
|
|
237
|
-
"description": "Version lifecycle metadata for this anatomy part. Set lifecycle.
|
|
237
|
+
"description": "Version lifecycle metadata for this anatomy part. Set lifecycle.deprecatedIn to signal that tokens referencing this part should migrate."
|
|
238
238
|
}
|
|
239
239
|
},
|
|
240
240
|
"additionalProperties": false
|
|
@@ -284,7 +284,7 @@
|
|
|
284
284
|
},
|
|
285
285
|
"lifecycle": {
|
|
286
286
|
"$ref": "#/$defs/lifecycle",
|
|
287
|
-
"description": "Version lifecycle metadata for this state. Set lifecycle.
|
|
287
|
+
"description": "Version lifecycle metadata for this state. Set lifecycle.deprecatedIn to signal that tokens referencing this state should migrate."
|
|
288
288
|
}
|
|
289
289
|
},
|
|
290
290
|
"additionalProperties": false
|
|
@@ -314,7 +314,7 @@
|
|
|
314
314
|
"type": "string",
|
|
315
315
|
"description": "Spec version when this component declaration was added (e.g. '1.0.0-draft')."
|
|
316
316
|
},
|
|
317
|
-
"
|
|
317
|
+
"deprecatedIn": {
|
|
318
318
|
"type": "string",
|
|
319
319
|
"description": "Spec version when this component was deprecated. Truthy = deprecated."
|
|
320
320
|
},
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/relationship.schema.json",
|
|
4
|
+
"title": "Component/Token Relationship (CTR) file",
|
|
5
|
+
"description": "Layer 1 — structural shape of a relationships/*.json file: a JSON array of Component/Token Relationship (CTR) entries. Graph rules (option-value validity, component/part/state existence, $ref resolution) are Layer 2. See spec/relationship-format.md.",
|
|
6
|
+
"type": "array",
|
|
7
|
+
"items": {
|
|
8
|
+
"$ref": "#/$defs/relationship"
|
|
9
|
+
},
|
|
10
|
+
"$defs": {
|
|
11
|
+
"lifecycle": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"description": "Version lifecycle metadata, mirroring the token/component lifecycle pattern (see token.schema.json).",
|
|
14
|
+
"properties": {
|
|
15
|
+
"introduced": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "Spec version when this relationship was added (e.g. \"1.0.0-draft\")."
|
|
18
|
+
},
|
|
19
|
+
"deprecatedIn": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Spec version when the relationship was deprecated (e.g. \"3.2.0\"). Truthy = deprecated."
|
|
22
|
+
},
|
|
23
|
+
"deprecatedComment": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Human-readable deprecation explanation and migration guidance."
|
|
26
|
+
},
|
|
27
|
+
"replacedBy": {
|
|
28
|
+
"oneOf": [
|
|
29
|
+
{ "type": "string", "format": "uuid" },
|
|
30
|
+
{
|
|
31
|
+
"type": "array",
|
|
32
|
+
"items": { "type": "string", "format": "uuid" },
|
|
33
|
+
"minItems": 1
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"description": "UUID(s) of the replacement relationship(s). Array form requires deprecatedComment."
|
|
37
|
+
},
|
|
38
|
+
"plannedRemoval": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"description": "Spec version when the relationship will be removed."
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"additionalProperties": false
|
|
44
|
+
},
|
|
45
|
+
"scope": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"description": "Explicit relationship context: which component, part, and property this CTR describes, plus any option-scoped narrowing. Layer 1 only enforces shape here — that `component.<part>` exists, that `options.<key>` values validate against the referenced component's declared option values, and that `property` matches a registered property term are Layer 2 rules (see spec/relationship-format.md).",
|
|
48
|
+
"required": ["component", "property"],
|
|
49
|
+
"properties": {
|
|
50
|
+
"component": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"minLength": 1,
|
|
53
|
+
"description": "Component name (kebab-case). MUST match a declared component name (SPEC-051)."
|
|
54
|
+
},
|
|
55
|
+
"part": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"minLength": 1,
|
|
58
|
+
"description": "Anatomy part name within the component. MUST match a declared anatomy part when present (SPEC-052)."
|
|
59
|
+
},
|
|
60
|
+
"property": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"minLength": 1,
|
|
63
|
+
"description": "The stylistic attribute this relationship describes (e.g. color, width, padding)."
|
|
64
|
+
},
|
|
65
|
+
"options": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"description": "Option-scoped narrowing (e.g. variant, size, style, arbitrary component option keys). Each key's value MUST validate against the referenced component's options.<key>.values (SPEC-053), except `state`, which is an ordered array of atomic state ids validated against the component's declared states (SPEC-054).",
|
|
68
|
+
"properties": {
|
|
69
|
+
"state": {
|
|
70
|
+
"type": "array",
|
|
71
|
+
"items": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"pattern": "^[a-z][a-z0-9-]*$"
|
|
74
|
+
},
|
|
75
|
+
"minItems": 1,
|
|
76
|
+
"description": "Ordered array of atomic state ids (e.g. [\"hover\"], [\"selected\", \"hover\"])."
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"additionalProperties": {
|
|
80
|
+
"type": "string"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"additionalProperties": false
|
|
85
|
+
},
|
|
86
|
+
"ctrWithValue": {
|
|
87
|
+
"type": "object",
|
|
88
|
+
"required": ["scope", "value"],
|
|
89
|
+
"not": {
|
|
90
|
+
"required": ["$ref"]
|
|
91
|
+
},
|
|
92
|
+
"dependentRequired": {
|
|
93
|
+
"setUuid": ["legacyKey"],
|
|
94
|
+
"setSchema": ["legacyKey"]
|
|
95
|
+
},
|
|
96
|
+
"properties": {
|
|
97
|
+
"specVersion": {
|
|
98
|
+
"const": "1.0.0-draft"
|
|
99
|
+
},
|
|
100
|
+
"scope": {
|
|
101
|
+
"$ref": "#/$defs/scope"
|
|
102
|
+
},
|
|
103
|
+
"context": {
|
|
104
|
+
"type": "string",
|
|
105
|
+
"description": "Human-readable label for how this CTR is used (mirrors tokenBindings[].context; maps to a Figma Token Group label). Purely descriptive — not validated."
|
|
106
|
+
},
|
|
107
|
+
"$valueType": {
|
|
108
|
+
"type": "string",
|
|
109
|
+
"format": "uri-reference",
|
|
110
|
+
"description": "URI reference to a value-type schema under schemas/value-types/. When present, value MUST validate against the referenced schema."
|
|
111
|
+
},
|
|
112
|
+
"value": {
|
|
113
|
+
"description": "Literal value owned by this CTR; type narrowed by value-type schemas where applicable.",
|
|
114
|
+
"anyOf": [
|
|
115
|
+
{ "$ref": "value-types/color.schema.json" },
|
|
116
|
+
{ "type": "string" },
|
|
117
|
+
{ "type": "number" },
|
|
118
|
+
{ "type": "boolean" },
|
|
119
|
+
{ "type": "object" },
|
|
120
|
+
{ "type": "array" }
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
"uuid": {
|
|
124
|
+
"type": "string",
|
|
125
|
+
"format": "uuid",
|
|
126
|
+
"description": "MUST be globally unique across all relationship entries in the same layer (SPEC-056)."
|
|
127
|
+
},
|
|
128
|
+
"lifecycle": {
|
|
129
|
+
"$ref": "#/$defs/lifecycle"
|
|
130
|
+
},
|
|
131
|
+
"private": {
|
|
132
|
+
"type": "boolean"
|
|
133
|
+
},
|
|
134
|
+
"description": {
|
|
135
|
+
"type": "string",
|
|
136
|
+
"description": "Plain text describing the relationship's purpose."
|
|
137
|
+
},
|
|
138
|
+
"legacyKey": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"minLength": 1,
|
|
141
|
+
"description": "Interim/transitional: pins the exact flat key written to legacy output (packages/tokens/src) for CTRs that must round-trip through the legacy generator. Not required for CTRs with no legacy counterpart. See spec/relationship-format.md#legacy-fields."
|
|
142
|
+
},
|
|
143
|
+
"setUuid": {
|
|
144
|
+
"type": "string",
|
|
145
|
+
"format": "uuid",
|
|
146
|
+
"description": "Interim/transitional: identifies the legacy color-set entry this CTR belongs to, for color-set legacy output reconstruction. Only present alongside legacyKey."
|
|
147
|
+
},
|
|
148
|
+
"setSchema": {
|
|
149
|
+
"type": "string",
|
|
150
|
+
"minLength": 1,
|
|
151
|
+
"description": "Interim/transitional: names the legacy color-set schema this CTR's set entry conforms to. Only present alongside setUuid."
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"additionalProperties": false
|
|
155
|
+
},
|
|
156
|
+
"ctrWithRef": {
|
|
157
|
+
"type": "object",
|
|
158
|
+
"required": ["scope", "$ref"],
|
|
159
|
+
"not": {
|
|
160
|
+
"required": ["value"]
|
|
161
|
+
},
|
|
162
|
+
"dependentRequired": {
|
|
163
|
+
"setUuid": ["legacyKey"],
|
|
164
|
+
"setSchema": ["legacyKey"]
|
|
165
|
+
},
|
|
166
|
+
"properties": {
|
|
167
|
+
"specVersion": {
|
|
168
|
+
"const": "1.0.0-draft"
|
|
169
|
+
},
|
|
170
|
+
"scope": {
|
|
171
|
+
"$ref": "#/$defs/scope"
|
|
172
|
+
},
|
|
173
|
+
"context": {
|
|
174
|
+
"type": "string",
|
|
175
|
+
"description": "Human-readable label for how this CTR is used (mirrors tokenBindings[].context; maps to a Figma Token Group label). Purely descriptive — not validated."
|
|
176
|
+
},
|
|
177
|
+
"$valueType": {
|
|
178
|
+
"type": "string",
|
|
179
|
+
"format": "uri-reference",
|
|
180
|
+
"description": "URI reference to a value-type schema under schemas/value-types/. When present, the alias resolution chain MUST terminate at a value validating against this schema."
|
|
181
|
+
},
|
|
182
|
+
"$ref": {
|
|
183
|
+
"type": "string",
|
|
184
|
+
"minLength": 1,
|
|
185
|
+
"description": "Alias target. MUST resolve to a token or relationship UUID in the dataset (SPEC-055)."
|
|
186
|
+
},
|
|
187
|
+
"uuid": {
|
|
188
|
+
"type": "string",
|
|
189
|
+
"format": "uuid",
|
|
190
|
+
"description": "MUST be globally unique across all relationship entries in the same layer (SPEC-056)."
|
|
191
|
+
},
|
|
192
|
+
"lifecycle": {
|
|
193
|
+
"$ref": "#/$defs/lifecycle"
|
|
194
|
+
},
|
|
195
|
+
"private": {
|
|
196
|
+
"type": "boolean"
|
|
197
|
+
},
|
|
198
|
+
"description": {
|
|
199
|
+
"type": "string",
|
|
200
|
+
"description": "Plain text describing the relationship's purpose."
|
|
201
|
+
},
|
|
202
|
+
"legacyKey": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"minLength": 1,
|
|
205
|
+
"description": "Interim/transitional: pins the exact flat key written to legacy output (packages/tokens/src) for CTRs that must round-trip through the legacy generator. Not required for CTRs with no legacy counterpart. See spec/relationship-format.md#legacy-fields."
|
|
206
|
+
},
|
|
207
|
+
"setUuid": {
|
|
208
|
+
"type": "string",
|
|
209
|
+
"format": "uuid",
|
|
210
|
+
"description": "Interim/transitional: identifies the legacy color-set entry this CTR belongs to, for color-set legacy output reconstruction. Only present alongside legacyKey."
|
|
211
|
+
},
|
|
212
|
+
"setSchema": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"minLength": 1,
|
|
215
|
+
"description": "Interim/transitional: names the legacy color-set schema this CTR's set entry conforms to. Only present alongside setUuid."
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"additionalProperties": false
|
|
219
|
+
},
|
|
220
|
+
"relationship": {
|
|
221
|
+
"type": "object",
|
|
222
|
+
"oneOf": [
|
|
223
|
+
{ "$ref": "#/$defs/ctrWithValue" },
|
|
224
|
+
{ "$ref": "#/$defs/ctrWithRef" }
|
|
225
|
+
]
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -114,6 +114,40 @@
|
|
|
114
114
|
"type": "string"
|
|
115
115
|
}
|
|
116
116
|
},
|
|
117
|
+
"lifecycle": {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"description": "Version lifecycle metadata, mirroring the component lifecycle pattern (see component.schema.json).",
|
|
120
|
+
"properties": {
|
|
121
|
+
"introduced": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"description": "Spec version when this token was added (e.g. \"1.0.0-draft\")."
|
|
124
|
+
},
|
|
125
|
+
"deprecatedIn": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"description": "Spec version when the token was deprecated (e.g. \"3.2.0\"). Truthy = deprecated."
|
|
128
|
+
},
|
|
129
|
+
"deprecatedComment": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"description": "Human-readable deprecation explanation and migration guidance."
|
|
132
|
+
},
|
|
133
|
+
"replacedBy": {
|
|
134
|
+
"oneOf": [
|
|
135
|
+
{ "type": "string", "format": "uuid" },
|
|
136
|
+
{
|
|
137
|
+
"type": "array",
|
|
138
|
+
"items": { "type": "string", "format": "uuid" },
|
|
139
|
+
"minItems": 1
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"description": "UUID(s) of the replacement token(s). Array form requires deprecatedComment."
|
|
143
|
+
},
|
|
144
|
+
"plannedRemoval": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"description": "Spec version when token will be removed."
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"additionalProperties": false
|
|
150
|
+
},
|
|
117
151
|
"tokenWithValue": {
|
|
118
152
|
"type": "object",
|
|
119
153
|
"required": ["name", "value"],
|
|
@@ -166,30 +200,8 @@
|
|
|
166
200
|
"type": "string",
|
|
167
201
|
"format": "uuid"
|
|
168
202
|
},
|
|
169
|
-
"
|
|
170
|
-
"
|
|
171
|
-
},
|
|
172
|
-
"deprecated": {
|
|
173
|
-
"type": "string",
|
|
174
|
-
"description": "Spec version when token was deprecated (e.g. \"3.2.0\"). Truthy = deprecated."
|
|
175
|
-
},
|
|
176
|
-
"deprecated_comment": {
|
|
177
|
-
"type": "string"
|
|
178
|
-
},
|
|
179
|
-
"replaced_by": {
|
|
180
|
-
"oneOf": [
|
|
181
|
-
{ "type": "string", "format": "uuid" },
|
|
182
|
-
{
|
|
183
|
-
"type": "array",
|
|
184
|
-
"items": { "type": "string", "format": "uuid" },
|
|
185
|
-
"minItems": 1
|
|
186
|
-
}
|
|
187
|
-
],
|
|
188
|
-
"description": "UUID(s) of the replacement token(s). Array form requires deprecated_comment."
|
|
189
|
-
},
|
|
190
|
-
"plannedRemoval": {
|
|
191
|
-
"type": "string",
|
|
192
|
-
"description": "Spec version when token will be removed."
|
|
203
|
+
"lifecycle": {
|
|
204
|
+
"$ref": "#/$defs/lifecycle"
|
|
193
205
|
},
|
|
194
206
|
"private": {
|
|
195
207
|
"type": "boolean"
|
|
@@ -250,30 +262,8 @@
|
|
|
250
262
|
"type": "string",
|
|
251
263
|
"format": "uuid"
|
|
252
264
|
},
|
|
253
|
-
"
|
|
254
|
-
"
|
|
255
|
-
},
|
|
256
|
-
"deprecated": {
|
|
257
|
-
"type": "string",
|
|
258
|
-
"description": "Spec version when token was deprecated (e.g. \"3.2.0\"). Truthy = deprecated."
|
|
259
|
-
},
|
|
260
|
-
"deprecated_comment": {
|
|
261
|
-
"type": "string"
|
|
262
|
-
},
|
|
263
|
-
"replaced_by": {
|
|
264
|
-
"oneOf": [
|
|
265
|
-
{ "type": "string", "format": "uuid" },
|
|
266
|
-
{
|
|
267
|
-
"type": "array",
|
|
268
|
-
"items": { "type": "string", "format": "uuid" },
|
|
269
|
-
"minItems": 1
|
|
270
|
-
}
|
|
271
|
-
],
|
|
272
|
-
"description": "UUID(s) of the replacement token(s). Array form requires deprecated_comment."
|
|
273
|
-
},
|
|
274
|
-
"plannedRemoval": {
|
|
275
|
-
"type": "string",
|
|
276
|
-
"description": "Spec version when token will be removed."
|
|
265
|
+
"lifecycle": {
|
|
266
|
+
"$ref": "#/$defs/lifecycle"
|
|
277
267
|
},
|
|
278
268
|
"private": {
|
|
279
269
|
"type": "boolean"
|