@damarkuncoro/meta-architecture-style-engine 0.1.0 → 0.1.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/README.md +985 -14
- package/lib/cjs/cli/index.js +160 -112
- package/lib/cjs/cli/index.js.map +1 -1
- package/lib/cjs/index.d.ts +202 -111
- package/lib/cjs/index.js +720 -642
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/cli/index.js +160 -112
- package/lib/esm/cli/index.js.map +1 -1
- package/lib/esm/index.d.mts +202 -111
- package/lib/esm/index.js +716 -643
- package/lib/esm/index.js.map +1 -1
- package/package.json +6 -4
package/lib/esm/index.js
CHANGED
|
@@ -1,199 +1,276 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// src/data/tokens.ts
|
|
2
|
+
var TOKENS = {
|
|
3
|
+
// Colors - Intent based
|
|
4
|
+
"color.primary": { id: "color.primary", domain: "color", value: "bg-blue-600" },
|
|
5
|
+
"color.secondary": { id: "color.secondary", domain: "color", value: "bg-gray-600" },
|
|
6
|
+
"color.danger": { id: "color.danger", domain: "color", value: "bg-red-600" },
|
|
7
|
+
// Spacing - Scale based
|
|
8
|
+
"space.sm": { id: "space.sm", domain: "layout", value: "p-2" },
|
|
9
|
+
"space.md": { id: "space.md", domain: "layout", value: "p-4" },
|
|
10
|
+
"space.lg": { id: "space.lg", domain: "layout", value: "p-6" },
|
|
11
|
+
// Forbidden/Raw tokens (for demo)
|
|
12
|
+
"raw.hex": { id: "raw.hex", domain: "color", value: "bg-[#123456]" },
|
|
13
|
+
// Illegal
|
|
14
|
+
// Surface (Theme Aware!)
|
|
15
|
+
"surface.card": {
|
|
16
|
+
id: "surface.card",
|
|
17
|
+
domain: "color",
|
|
18
|
+
value: {
|
|
19
|
+
light: "bg-white",
|
|
20
|
+
dark: "bg-slate-800"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"surface.ground": {
|
|
24
|
+
id: "surface.ground",
|
|
25
|
+
domain: "color",
|
|
26
|
+
value: {
|
|
27
|
+
light: "bg-gray-50",
|
|
28
|
+
dark: "bg-slate-900"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"surface.paper": {
|
|
32
|
+
id: "surface.paper",
|
|
33
|
+
domain: "color",
|
|
34
|
+
value: {
|
|
35
|
+
light: "bg-white",
|
|
36
|
+
dark: "bg-slate-700"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
// Text (Theme Aware!)
|
|
40
|
+
"text.light": {
|
|
41
|
+
id: "text.light",
|
|
42
|
+
domain: "color",
|
|
43
|
+
value: {
|
|
44
|
+
light: "text-white",
|
|
45
|
+
dark: "text-gray-100"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"text.dark": {
|
|
49
|
+
id: "text.dark",
|
|
50
|
+
domain: "color",
|
|
51
|
+
value: {
|
|
52
|
+
light: "text-gray-900",
|
|
53
|
+
dark: "text-white"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"text.primary": {
|
|
57
|
+
id: "text.primary",
|
|
58
|
+
domain: "color",
|
|
59
|
+
value: {
|
|
60
|
+
light: "text-gray-900",
|
|
61
|
+
dark: "text-gray-50"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"text.secondary": {
|
|
65
|
+
id: "text.secondary",
|
|
66
|
+
domain: "color",
|
|
67
|
+
value: {
|
|
68
|
+
light: "text-gray-500",
|
|
69
|
+
dark: "text-gray-400"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"shadow.sm": { id: "shadow.sm", domain: "effect", value: "shadow-sm" },
|
|
73
|
+
"shadow.md": { id: "shadow.md", domain: "effect", value: "shadow-md" },
|
|
74
|
+
"shadow.lg": { id: "shadow.lg", domain: "effect", value: "shadow-lg" },
|
|
75
|
+
// Radius
|
|
76
|
+
"radius.md": { id: "radius.md", domain: "layout", value: "rounded-md" },
|
|
77
|
+
"radius.lg": { id: "radius.lg", domain: "layout", value: "rounded-lg" }
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// src/domain/registry/TokenRegistry.ts
|
|
81
|
+
var TokenRegistry = class {
|
|
82
|
+
constructor(tokens = TOKENS) {
|
|
83
|
+
this.tokens = Object.freeze({ ...tokens });
|
|
5
84
|
}
|
|
6
85
|
/**
|
|
7
|
-
*
|
|
86
|
+
* Get token by ID
|
|
87
|
+
* @throws Error if token not found
|
|
8
88
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
message: `Token '${tokenId}' does not exist in Registry.`,
|
|
14
|
-
severity: "error",
|
|
15
|
-
semantic: `${property}.${tokenId}`,
|
|
16
|
-
context: context ? { ...context } : void 0
|
|
17
|
-
};
|
|
89
|
+
getToken(id) {
|
|
90
|
+
const token = this.tokens[id];
|
|
91
|
+
if (!token) {
|
|
92
|
+
throw new Error(`Token '${id}' not found in registry`);
|
|
18
93
|
}
|
|
19
|
-
return
|
|
94
|
+
return token;
|
|
20
95
|
}
|
|
21
96
|
/**
|
|
22
|
-
*
|
|
97
|
+
* Check if token exists
|
|
23
98
|
*/
|
|
24
|
-
|
|
25
|
-
return
|
|
99
|
+
hasToken(id) {
|
|
100
|
+
return id in this.tokens;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get all tokens (immutable)
|
|
104
|
+
*/
|
|
105
|
+
getAllTokens() {
|
|
106
|
+
return this.tokens;
|
|
26
107
|
}
|
|
27
108
|
};
|
|
28
109
|
|
|
29
|
-
// src/domain/
|
|
30
|
-
var
|
|
31
|
-
constructor(tokenRegistry) {
|
|
32
|
-
this.tokenRegistry = tokenRegistry;
|
|
33
|
-
}
|
|
110
|
+
// src/domain/resolution/ThemeResolver.ts
|
|
111
|
+
var ThemeResolver = class {
|
|
34
112
|
/**
|
|
35
|
-
*
|
|
113
|
+
* Resolve theme value based on current theme
|
|
36
114
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
rule: "domain-violation",
|
|
42
|
-
message: `Property '${property}' expects domain '${rule.domain}', but got token from '${token.domain}'.`,
|
|
43
|
-
severity: "error",
|
|
44
|
-
semantic: `${property}.${tokenId}`,
|
|
45
|
-
context: context ? { ...context } : void 0
|
|
46
|
-
};
|
|
115
|
+
resolve(value, theme) {
|
|
116
|
+
if (typeof value === "string") {
|
|
117
|
+
return value;
|
|
47
118
|
}
|
|
48
|
-
|
|
119
|
+
if (theme in value) {
|
|
120
|
+
return value[theme];
|
|
121
|
+
}
|
|
122
|
+
throw new Error(`Theme '${theme}' not found in value. Available themes: ${Object.keys(value).join(", ")}`);
|
|
49
123
|
}
|
|
50
124
|
/**
|
|
51
|
-
* Get
|
|
125
|
+
* Get current theme from context
|
|
126
|
+
* Defaults to 'light' if not specified
|
|
52
127
|
*/
|
|
53
|
-
|
|
54
|
-
return "
|
|
128
|
+
getCurrentTheme(context) {
|
|
129
|
+
return context?.theme || "light";
|
|
55
130
|
}
|
|
56
131
|
};
|
|
57
132
|
|
|
58
|
-
// src/domain/
|
|
59
|
-
var
|
|
133
|
+
// src/domain/resolution/ContextBinder.ts
|
|
134
|
+
var ContextBinder = class {
|
|
135
|
+
constructor(graph, bindingRules = []) {
|
|
136
|
+
this.graph = graph;
|
|
137
|
+
this.bindingRules = bindingRules;
|
|
138
|
+
}
|
|
60
139
|
/**
|
|
61
|
-
*
|
|
140
|
+
* Bind graph to a specific context
|
|
141
|
+
* @param context - Style context to bind to
|
|
142
|
+
* @returns Bound context with active contracts and disabled variants
|
|
62
143
|
*/
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
144
|
+
bind(context) {
|
|
145
|
+
const activeContracts = /* @__PURE__ */ new Set();
|
|
146
|
+
const disabledVariants = /* @__PURE__ */ new Map();
|
|
147
|
+
for (const rule of this.bindingRules) {
|
|
148
|
+
const isActive = rule.condition(context);
|
|
149
|
+
if (isActive) {
|
|
150
|
+
activeContracts.add(rule.contract);
|
|
151
|
+
if (rule.disabledVariants && rule.disabledVariants.length > 0) {
|
|
152
|
+
disabledVariants.set(rule.contract, rule.disabledVariants);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
72
155
|
}
|
|
73
|
-
|
|
156
|
+
const graphView = this.createGraphView(activeContracts, disabledVariants);
|
|
157
|
+
return {
|
|
158
|
+
context,
|
|
159
|
+
activeContracts,
|
|
160
|
+
disabledVariants,
|
|
161
|
+
graphView
|
|
162
|
+
};
|
|
74
163
|
}
|
|
75
164
|
/**
|
|
76
|
-
*
|
|
165
|
+
* Bind graph to multiple contexts
|
|
166
|
+
* @param contexts - Array of style contexts
|
|
167
|
+
* @returns Array of bound contexts
|
|
77
168
|
*/
|
|
78
|
-
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// src/domain/StyleResolutionEngine.ts
|
|
84
|
-
var StyleResolutionEngine = class {
|
|
85
|
-
constructor(tokenRegistry, themeResolver, validators) {
|
|
86
|
-
this.tokenRegistry = tokenRegistry;
|
|
87
|
-
this.themeResolver = themeResolver;
|
|
88
|
-
this.validators = validators || [
|
|
89
|
-
new TokenExistenceValidator(tokenRegistry),
|
|
90
|
-
new DomainValidator(tokenRegistry),
|
|
91
|
-
new AllowedTokenValidator()
|
|
92
|
-
];
|
|
169
|
+
bindMultiple(contexts) {
|
|
170
|
+
return contexts.map((ctx) => this.bind(ctx));
|
|
93
171
|
}
|
|
94
172
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* @
|
|
99
|
-
* @param constitution - Component constitution
|
|
100
|
-
* @param context - Optional style context
|
|
101
|
-
* @returns Resolution result with nodes, violations, and className
|
|
173
|
+
* Create immutable view of the graph
|
|
174
|
+
* @param activeContracts - Set of active contract names
|
|
175
|
+
* @param disabledVariants - Map of disabled variants per contract
|
|
176
|
+
* @returns Immutable array of nodes
|
|
102
177
|
*/
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
const rule = constitution.rules.find((r) => r.property === property);
|
|
109
|
-
if (!rule) {
|
|
110
|
-
violations.push({
|
|
111
|
-
rule: "unknown-property",
|
|
112
|
-
message: `Property '${property}' is not defined in ${constitution.componentName} constitution.`,
|
|
113
|
-
severity: "warning",
|
|
114
|
-
semantic: `${property}`
|
|
115
|
-
});
|
|
178
|
+
createGraphView(activeContracts, disabledVariants) {
|
|
179
|
+
const allNodes = this.graph.getAllNodes();
|
|
180
|
+
const view = [];
|
|
181
|
+
for (const node of allNodes) {
|
|
182
|
+
if (!activeContracts.has(node.contractRef)) {
|
|
116
183
|
continue;
|
|
117
184
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
constitution,
|
|
124
|
-
violations,
|
|
125
|
-
nodes,
|
|
126
|
-
validClassNames,
|
|
127
|
-
void 0,
|
|
128
|
-
context
|
|
129
|
-
);
|
|
130
|
-
} else if (typeof rawValue === "object" && rawValue !== null) {
|
|
131
|
-
for (const [bp, tokenId] of Object.entries(rawValue)) {
|
|
132
|
-
this.validateAndResolve(
|
|
133
|
-
property,
|
|
134
|
-
tokenId,
|
|
135
|
-
rule,
|
|
136
|
-
constitution,
|
|
137
|
-
violations,
|
|
138
|
-
nodes,
|
|
139
|
-
validClassNames,
|
|
140
|
-
bp,
|
|
141
|
-
context
|
|
142
|
-
);
|
|
185
|
+
const disabledForContract = disabledVariants.get(node.contractRef);
|
|
186
|
+
if (disabledForContract && disabledForContract.length > 0) {
|
|
187
|
+
const variant = this.extractVariant(node.id);
|
|
188
|
+
if (variant && disabledForContract.includes(variant)) {
|
|
189
|
+
continue;
|
|
143
190
|
}
|
|
144
191
|
}
|
|
192
|
+
view.push(node);
|
|
145
193
|
}
|
|
146
|
-
return
|
|
147
|
-
valid: violations.length === 0,
|
|
148
|
-
nodes: Object.freeze(nodes),
|
|
149
|
-
violations: Object.freeze(violations),
|
|
150
|
-
className: validClassNames.join(" ")
|
|
151
|
-
};
|
|
194
|
+
return Object.freeze(view);
|
|
152
195
|
}
|
|
153
196
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
197
|
+
* Extract variant from node ID
|
|
198
|
+
* @param nodeId - Node ID (e.g., "Button.padding.md")
|
|
199
|
+
* @returns Variant (e.g., "md") or null
|
|
156
200
|
*/
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
violations.push({
|
|
162
|
-
...violation,
|
|
163
|
-
context: breakpoint ? { breakpoint } : void 0
|
|
164
|
-
});
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
201
|
+
extractVariant(nodeId) {
|
|
202
|
+
const parts = nodeId.split(".");
|
|
203
|
+
if (parts.length >= 3) {
|
|
204
|
+
return parts[2];
|
|
167
205
|
}
|
|
168
|
-
|
|
169
|
-
nodes.push({
|
|
170
|
-
domain: token.domain,
|
|
171
|
-
semantic: `${constitution.componentName}.${property}`,
|
|
172
|
-
tokenRef: token.id,
|
|
173
|
-
source: "SRE.v2",
|
|
174
|
-
breakpoint
|
|
175
|
-
});
|
|
176
|
-
const materializedValue = this.materializeToken(token, breakpoint, context);
|
|
177
|
-
validClassNames.push(materializedValue);
|
|
206
|
+
return null;
|
|
178
207
|
}
|
|
179
208
|
/**
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
209
|
+
* Add a binding rule
|
|
210
|
+
* @param rule - Context binding rule
|
|
211
|
+
*/
|
|
212
|
+
addBindingRule(rule) {
|
|
213
|
+
this.bindingRules.push(rule);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Remove a binding rule
|
|
217
|
+
* @param contract - Contract name
|
|
218
|
+
* @param property - Property name
|
|
185
219
|
*/
|
|
186
|
-
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
220
|
+
removeBindingRule(contract, property) {
|
|
221
|
+
const index = this.bindingRules.findIndex(
|
|
222
|
+
(r) => r.contract === contract && r.property === property
|
|
223
|
+
);
|
|
224
|
+
if (index !== -1) {
|
|
225
|
+
this.bindingRules.splice(index, 1);
|
|
191
226
|
}
|
|
192
|
-
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Get all binding rules
|
|
230
|
+
* @returns Immutable array of binding rules
|
|
231
|
+
*/
|
|
232
|
+
getBindingRules() {
|
|
233
|
+
return Object.freeze([...this.bindingRules]);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Create default binding rules for common scenarios
|
|
237
|
+
* @returns Array of default binding rules
|
|
238
|
+
*/
|
|
239
|
+
static createDefaultRules() {
|
|
240
|
+
return [
|
|
241
|
+
// Mobile: Disable large spacing
|
|
242
|
+
{
|
|
243
|
+
contract: "Card",
|
|
244
|
+
property: "padding",
|
|
245
|
+
condition: (ctx) => ctx.device === "mobile",
|
|
246
|
+
disabledVariants: ["lg", "xl", "2xl"]
|
|
247
|
+
},
|
|
248
|
+
// Mobile: Disable large shadows
|
|
249
|
+
{
|
|
250
|
+
contract: "Card",
|
|
251
|
+
property: "shadow",
|
|
252
|
+
condition: (ctx) => ctx.device === "mobile",
|
|
253
|
+
disabledVariants: ["lg", "xl"]
|
|
254
|
+
},
|
|
255
|
+
// Dark mode: Disable light surfaces
|
|
256
|
+
{
|
|
257
|
+
contract: "Card",
|
|
258
|
+
property: "background",
|
|
259
|
+
condition: (ctx) => ctx.theme === "dark",
|
|
260
|
+
disabledVariants: ["surface.white", "surface.gray"]
|
|
261
|
+
},
|
|
262
|
+
// Reduced motion: Disable animations
|
|
263
|
+
{
|
|
264
|
+
contract: "Button",
|
|
265
|
+
property: "effect",
|
|
266
|
+
condition: (ctx) => ctx.state === "disabled",
|
|
267
|
+
disabledVariants: ["animate", "transition"]
|
|
268
|
+
}
|
|
269
|
+
];
|
|
193
270
|
}
|
|
194
271
|
};
|
|
195
272
|
|
|
196
|
-
// src/domain/CanonicalStyleGraph.ts
|
|
273
|
+
// src/domain/resolution/CanonicalStyleGraph.ts
|
|
197
274
|
var CanonicalStyleGraph = class {
|
|
198
275
|
constructor(contracts, tokenRegistry) {
|
|
199
276
|
this.nodes = /* @__PURE__ */ new Map();
|
|
@@ -366,357 +443,242 @@ var CanonicalStyleGraph = class {
|
|
|
366
443
|
const nodeId = queue.shift();
|
|
367
444
|
result.push(nodeId);
|
|
368
445
|
visited.add(nodeId);
|
|
369
|
-
const node = this.nodes.get(nodeId);
|
|
370
|
-
if (node) {
|
|
371
|
-
for (const edge of node.dependencies) {
|
|
372
|
-
const neighborId = edge.to;
|
|
373
|
-
const current = inDegree.get(neighborId) || 0;
|
|
374
|
-
inDegree.set(neighborId, current - 1);
|
|
375
|
-
if (current - 1 === 0) {
|
|
376
|
-
queue.push(neighborId);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
if (visited.size !== this.nodes.size) {
|
|
382
|
-
throw new Error("Cannot resolve order: graph contains cycles");
|
|
383
|
-
}
|
|
384
|
-
return result;
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Get node by ID
|
|
388
|
-
*/
|
|
389
|
-
getNode(id) {
|
|
390
|
-
return this.nodes.get(id);
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Get all nodes
|
|
394
|
-
*/
|
|
395
|
-
getAllNodes() {
|
|
396
|
-
return Array.from(this.nodes.values());
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Get all edges
|
|
400
|
-
*/
|
|
401
|
-
getAllEdges() {
|
|
402
|
-
return this.edges;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Get constitution by component name
|
|
406
|
-
*/
|
|
407
|
-
getConstitution(componentName) {
|
|
408
|
-
return this.constitutionsMap.get(componentName);
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Get all constitutions
|
|
412
|
-
*/
|
|
413
|
-
getAllConstitutions() {
|
|
414
|
-
return Array.from(this.constitutionsMap.values());
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Check if graph is empty
|
|
418
|
-
*/
|
|
419
|
-
isEmpty() {
|
|
420
|
-
return this.nodes.size === 0;
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* Get graph size
|
|
424
|
-
*/
|
|
425
|
-
size() {
|
|
426
|
-
return this.nodes.size;
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
// src/domain/ContextBinder.ts
|
|
431
|
-
var ContextBinder = class {
|
|
432
|
-
constructor(graph, bindingRules = []) {
|
|
433
|
-
this.graph = graph;
|
|
434
|
-
this.bindingRules = bindingRules;
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* Bind graph to a specific context
|
|
438
|
-
* @param context - Style context to bind to
|
|
439
|
-
* @returns Bound context with active contracts and disabled variants
|
|
440
|
-
*/
|
|
441
|
-
bind(context) {
|
|
442
|
-
const activeContracts = /* @__PURE__ */ new Set();
|
|
443
|
-
const disabledVariants = /* @__PURE__ */ new Map();
|
|
444
|
-
for (const rule of this.bindingRules) {
|
|
445
|
-
const isActive = rule.condition(context);
|
|
446
|
-
if (isActive) {
|
|
447
|
-
activeContracts.add(rule.contract);
|
|
448
|
-
if (rule.disabledVariants && rule.disabledVariants.length > 0) {
|
|
449
|
-
disabledVariants.set(rule.contract, rule.disabledVariants);
|
|
446
|
+
const node = this.nodes.get(nodeId);
|
|
447
|
+
if (node) {
|
|
448
|
+
for (const edge of node.dependencies) {
|
|
449
|
+
const neighborId = edge.to;
|
|
450
|
+
const current = inDegree.get(neighborId) || 0;
|
|
451
|
+
inDegree.set(neighborId, current - 1);
|
|
452
|
+
if (current - 1 === 0) {
|
|
453
|
+
queue.push(neighborId);
|
|
454
|
+
}
|
|
450
455
|
}
|
|
451
456
|
}
|
|
452
457
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
disabledVariants,
|
|
458
|
-
graphView
|
|
459
|
-
};
|
|
458
|
+
if (visited.size !== this.nodes.size) {
|
|
459
|
+
throw new Error("Cannot resolve order: graph contains cycles");
|
|
460
|
+
}
|
|
461
|
+
return result;
|
|
460
462
|
}
|
|
461
463
|
/**
|
|
462
|
-
*
|
|
463
|
-
* @param contexts - Array of style contexts
|
|
464
|
-
* @returns Array of bound contexts
|
|
464
|
+
* Get node by ID
|
|
465
465
|
*/
|
|
466
|
-
|
|
467
|
-
return
|
|
466
|
+
getNode(id) {
|
|
467
|
+
return this.nodes.get(id);
|
|
468
468
|
}
|
|
469
469
|
/**
|
|
470
|
-
*
|
|
471
|
-
* @param activeContracts - Set of active contract names
|
|
472
|
-
* @param disabledVariants - Map of disabled variants per contract
|
|
473
|
-
* @returns Immutable array of nodes
|
|
470
|
+
* Get all nodes
|
|
474
471
|
*/
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
const view = [];
|
|
478
|
-
for (const node of allNodes) {
|
|
479
|
-
if (!activeContracts.has(node.contractRef)) {
|
|
480
|
-
continue;
|
|
481
|
-
}
|
|
482
|
-
const disabledForContract = disabledVariants.get(node.contractRef);
|
|
483
|
-
if (disabledForContract && disabledForContract.length > 0) {
|
|
484
|
-
const variant = this.extractVariant(node.id);
|
|
485
|
-
if (variant && disabledForContract.includes(variant)) {
|
|
486
|
-
continue;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
view.push(node);
|
|
490
|
-
}
|
|
491
|
-
return Object.freeze(view);
|
|
472
|
+
getAllNodes() {
|
|
473
|
+
return Array.from(this.nodes.values());
|
|
492
474
|
}
|
|
493
475
|
/**
|
|
494
|
-
*
|
|
495
|
-
* @param nodeId - Node ID (e.g., "Button.padding.md")
|
|
496
|
-
* @returns Variant (e.g., "md") or null
|
|
476
|
+
* Get all edges
|
|
497
477
|
*/
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
if (parts.length >= 3) {
|
|
501
|
-
return parts[2];
|
|
502
|
-
}
|
|
503
|
-
return null;
|
|
478
|
+
getAllEdges() {
|
|
479
|
+
return this.edges;
|
|
504
480
|
}
|
|
505
481
|
/**
|
|
506
|
-
*
|
|
507
|
-
* @param rule - Context binding rule
|
|
482
|
+
* Get constitution by component name
|
|
508
483
|
*/
|
|
509
|
-
|
|
510
|
-
this.
|
|
484
|
+
getConstitution(componentName) {
|
|
485
|
+
return this.constitutionsMap.get(componentName);
|
|
511
486
|
}
|
|
512
487
|
/**
|
|
513
|
-
*
|
|
514
|
-
* @param contract - Contract name
|
|
515
|
-
* @param property - Property name
|
|
488
|
+
* Get all constitutions
|
|
516
489
|
*/
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
(r) => r.contract === contract && r.property === property
|
|
520
|
-
);
|
|
521
|
-
if (index !== -1) {
|
|
522
|
-
this.bindingRules.splice(index, 1);
|
|
523
|
-
}
|
|
490
|
+
getAllConstitutions() {
|
|
491
|
+
return Array.from(this.constitutionsMap.values());
|
|
524
492
|
}
|
|
525
493
|
/**
|
|
526
|
-
*
|
|
527
|
-
* @returns Immutable array of binding rules
|
|
494
|
+
* Check if graph is empty
|
|
528
495
|
*/
|
|
529
|
-
|
|
530
|
-
return
|
|
496
|
+
isEmpty() {
|
|
497
|
+
return this.nodes.size === 0;
|
|
531
498
|
}
|
|
532
499
|
/**
|
|
533
|
-
*
|
|
534
|
-
* @returns Array of default binding rules
|
|
500
|
+
* Get graph size
|
|
535
501
|
*/
|
|
536
|
-
|
|
537
|
-
return
|
|
538
|
-
// Mobile: Disable large spacing
|
|
539
|
-
{
|
|
540
|
-
contract: "Card",
|
|
541
|
-
property: "padding",
|
|
542
|
-
condition: (ctx) => ctx.device === "mobile",
|
|
543
|
-
disabledVariants: ["lg", "xl", "2xl"]
|
|
544
|
-
},
|
|
545
|
-
// Mobile: Disable large shadows
|
|
546
|
-
{
|
|
547
|
-
contract: "Card",
|
|
548
|
-
property: "shadow",
|
|
549
|
-
condition: (ctx) => ctx.device === "mobile",
|
|
550
|
-
disabledVariants: ["lg", "xl"]
|
|
551
|
-
},
|
|
552
|
-
// Dark mode: Disable light surfaces
|
|
553
|
-
{
|
|
554
|
-
contract: "Card",
|
|
555
|
-
property: "background",
|
|
556
|
-
condition: (ctx) => ctx.theme === "dark",
|
|
557
|
-
disabledVariants: ["surface.white", "surface.gray"]
|
|
558
|
-
},
|
|
559
|
-
// Reduced motion: Disable animations
|
|
560
|
-
{
|
|
561
|
-
contract: "Button",
|
|
562
|
-
property: "effect",
|
|
563
|
-
condition: (ctx) => ctx.state === "disabled",
|
|
564
|
-
disabledVariants: ["animate", "transition"]
|
|
565
|
-
}
|
|
566
|
-
];
|
|
502
|
+
size() {
|
|
503
|
+
return this.nodes.size;
|
|
567
504
|
}
|
|
568
505
|
};
|
|
569
506
|
|
|
570
|
-
// src/domain/
|
|
571
|
-
var
|
|
572
|
-
constructor(
|
|
573
|
-
this.
|
|
574
|
-
this.handlers = /* @__PURE__ */ new Map();
|
|
575
|
-
if (handlers) {
|
|
576
|
-
for (const handler of handlers) {
|
|
577
|
-
this.handlers.set(handler.constructor.name, handler);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
507
|
+
// src/domain/governance/strategies/TokenExistenceValidator.ts
|
|
508
|
+
var TokenExistenceValidator = class {
|
|
509
|
+
constructor(tokenRegistry) {
|
|
510
|
+
this.tokenRegistry = tokenRegistry;
|
|
580
511
|
}
|
|
581
512
|
/**
|
|
582
|
-
*
|
|
583
|
-
* @param violation - The violation to handle
|
|
584
|
-
* @returns Outcome (decision, not execution)
|
|
513
|
+
* Validate that token exists
|
|
585
514
|
*/
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
515
|
+
validate(property, tokenId, rule, context) {
|
|
516
|
+
if (!this.tokenRegistry.hasToken(tokenId)) {
|
|
517
|
+
return {
|
|
518
|
+
rule: "invalid-token",
|
|
519
|
+
message: `Token '${tokenId}' does not exist in Registry.`,
|
|
520
|
+
severity: "error",
|
|
521
|
+
semantic: `${property}.${tokenId}`,
|
|
522
|
+
context: context ? { ...context } : void 0
|
|
523
|
+
};
|
|
590
524
|
}
|
|
591
|
-
return
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* Handle multiple violations
|
|
595
|
-
* @param violations - Array of violations
|
|
596
|
-
* @returns Array of outcomes
|
|
597
|
-
*/
|
|
598
|
-
handleMultiple(violations) {
|
|
599
|
-
return violations.map((v) => this.handle(v));
|
|
525
|
+
return null;
|
|
600
526
|
}
|
|
601
527
|
/**
|
|
602
|
-
* Get
|
|
603
|
-
* @returns Current default action
|
|
528
|
+
* Get strategy name
|
|
604
529
|
*/
|
|
605
|
-
|
|
606
|
-
return
|
|
530
|
+
getName() {
|
|
531
|
+
return "TokenExistenceValidator";
|
|
607
532
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
const currentAction = this.getCurrentDefaultAction();
|
|
615
|
-
switch (currentAction) {
|
|
616
|
-
case "reject":
|
|
617
|
-
return {
|
|
618
|
-
action: "reject",
|
|
619
|
-
metadata: {
|
|
620
|
-
contract: violation.semantic || "unknown",
|
|
621
|
-
reason: violation.message,
|
|
622
|
-
context: violation.context || {},
|
|
623
|
-
severity: violation.severity
|
|
624
|
-
}
|
|
625
|
-
};
|
|
626
|
-
case "fallback":
|
|
627
|
-
return {
|
|
628
|
-
action: "fallback",
|
|
629
|
-
replacement: this.determineFallbackValue(violation),
|
|
630
|
-
metadata: {
|
|
631
|
-
contract: violation.semantic || "unknown",
|
|
632
|
-
reason: violation.message,
|
|
633
|
-
context: violation.context || {},
|
|
634
|
-
severity: "warning"
|
|
635
|
-
}
|
|
636
|
-
};
|
|
637
|
-
case "override":
|
|
638
|
-
return {
|
|
639
|
-
action: "override",
|
|
640
|
-
metadata: {
|
|
641
|
-
contract: violation.semantic || "unknown",
|
|
642
|
-
reason: violation.message,
|
|
643
|
-
context: violation.context || {},
|
|
644
|
-
severity: "warning"
|
|
645
|
-
}
|
|
646
|
-
};
|
|
647
|
-
case "warn":
|
|
648
|
-
return {
|
|
649
|
-
action: "warn",
|
|
650
|
-
metadata: {
|
|
651
|
-
contract: violation.semantic || "unknown",
|
|
652
|
-
reason: violation.message,
|
|
653
|
-
context: violation.context || {},
|
|
654
|
-
severity: "warning"
|
|
655
|
-
}
|
|
656
|
-
};
|
|
657
|
-
default:
|
|
658
|
-
throw new Error(`Unknown action: ${currentAction}`);
|
|
659
|
-
}
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
// src/domain/governance/strategies/DomainValidator.ts
|
|
536
|
+
var DomainValidator = class {
|
|
537
|
+
constructor(tokenRegistry) {
|
|
538
|
+
this.tokenRegistry = tokenRegistry;
|
|
660
539
|
}
|
|
661
540
|
/**
|
|
662
|
-
*
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
const property = parts[parts.length - 1];
|
|
675
|
-
const fallbacks = {
|
|
676
|
-
"padding": "md",
|
|
677
|
-
"margin": "md",
|
|
678
|
-
"spacing": "md",
|
|
679
|
-
"radius": "md",
|
|
680
|
-
"shadow": "md",
|
|
681
|
-
"background": "surface.card",
|
|
682
|
-
"color": "color.primary"
|
|
683
|
-
};
|
|
684
|
-
if (property in fallbacks) {
|
|
685
|
-
return fallbacks[property];
|
|
686
|
-
}
|
|
687
|
-
}
|
|
541
|
+
* Validate that token domain matches rule domain
|
|
542
|
+
*/
|
|
543
|
+
validate(property, tokenId, rule, context) {
|
|
544
|
+
const token = this.tokenRegistry.getToken(tokenId);
|
|
545
|
+
if (token.domain !== rule.domain) {
|
|
546
|
+
return {
|
|
547
|
+
rule: "domain-violation",
|
|
548
|
+
message: `Property '${property}' expects domain '${rule.domain}', but got token from '${token.domain}'.`,
|
|
549
|
+
severity: "error",
|
|
550
|
+
semantic: `${property}.${tokenId}`,
|
|
551
|
+
context: context ? { ...context } : void 0
|
|
552
|
+
};
|
|
688
553
|
}
|
|
689
|
-
return
|
|
554
|
+
return null;
|
|
690
555
|
}
|
|
691
556
|
/**
|
|
692
|
-
*
|
|
693
|
-
* @param handler - The handler to register
|
|
557
|
+
* Get strategy name
|
|
694
558
|
*/
|
|
695
|
-
|
|
696
|
-
|
|
559
|
+
getName() {
|
|
560
|
+
return "DomainValidator";
|
|
697
561
|
}
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
// src/domain/governance/strategies/AllowedTokenValidator.ts
|
|
565
|
+
var AllowedTokenValidator = class {
|
|
698
566
|
/**
|
|
699
|
-
*
|
|
700
|
-
* @param handlerName - Name of handler to unregister
|
|
567
|
+
* Validate that token is allowed
|
|
701
568
|
*/
|
|
702
|
-
|
|
703
|
-
|
|
569
|
+
validate(property, tokenId, rule, context) {
|
|
570
|
+
if (!rule.allowedTokens.includes(tokenId)) {
|
|
571
|
+
return {
|
|
572
|
+
rule: "illegal-token-usage",
|
|
573
|
+
message: `Token '${tokenId}' is NOT allowed for property '${property}'. Allowed: ${rule.allowedTokens.join(", ")}`,
|
|
574
|
+
severity: "error",
|
|
575
|
+
semantic: `${property}.${tokenId}`,
|
|
576
|
+
context: context ? { ...context } : void 0
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
return null;
|
|
704
580
|
}
|
|
705
581
|
/**
|
|
706
|
-
* Get
|
|
707
|
-
* @returns Array of handler names
|
|
582
|
+
* Get strategy name
|
|
708
583
|
*/
|
|
709
|
-
|
|
710
|
-
return
|
|
584
|
+
getName() {
|
|
585
|
+
return "AllowedTokenValidator";
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
// src/domain/resolution/StyleResolutionEngine.ts
|
|
590
|
+
var StyleResolutionEngine = class {
|
|
591
|
+
constructor(tokenRegistry, themeResolver, validators) {
|
|
592
|
+
this.tokenRegistry = tokenRegistry;
|
|
593
|
+
this.themeResolver = themeResolver;
|
|
594
|
+
this.validators = validators || [
|
|
595
|
+
new TokenExistenceValidator(tokenRegistry),
|
|
596
|
+
new DomainValidator(tokenRegistry),
|
|
597
|
+
new AllowedTokenValidator()
|
|
598
|
+
];
|
|
711
599
|
}
|
|
712
600
|
/**
|
|
713
|
-
*
|
|
714
|
-
*
|
|
601
|
+
* resolve()
|
|
602
|
+
* Main function: Validates style contract against constitution
|
|
603
|
+
*
|
|
604
|
+
* @param contract - Style contract definition
|
|
605
|
+
* @param constitution - Component constitution
|
|
606
|
+
* @param context - Optional style context
|
|
607
|
+
* @returns Resolution result with nodes and violations
|
|
715
608
|
*/
|
|
716
|
-
|
|
717
|
-
|
|
609
|
+
resolve(contract, constitution, context) {
|
|
610
|
+
const violations = [];
|
|
611
|
+
const nodes = [];
|
|
612
|
+
for (const [property, rawValue] of Object.entries(contract)) {
|
|
613
|
+
const rule = constitution.rules.find((r) => r.property === property);
|
|
614
|
+
if (!rule) {
|
|
615
|
+
violations.push({
|
|
616
|
+
rule: "unknown-property",
|
|
617
|
+
message: `Property '${property}' is not defined in ${constitution.componentName} constitution.`,
|
|
618
|
+
severity: "warning",
|
|
619
|
+
semantic: `${property}`
|
|
620
|
+
});
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
if (typeof rawValue === "string") {
|
|
624
|
+
this.validateAndResolve(
|
|
625
|
+
property,
|
|
626
|
+
rawValue,
|
|
627
|
+
rule,
|
|
628
|
+
constitution,
|
|
629
|
+
violations,
|
|
630
|
+
nodes,
|
|
631
|
+
void 0,
|
|
632
|
+
context
|
|
633
|
+
);
|
|
634
|
+
} else if (typeof rawValue === "object" && rawValue !== null) {
|
|
635
|
+
for (const [bp, tokenId] of Object.entries(rawValue)) {
|
|
636
|
+
this.validateAndResolve(
|
|
637
|
+
property,
|
|
638
|
+
tokenId,
|
|
639
|
+
rule,
|
|
640
|
+
constitution,
|
|
641
|
+
violations,
|
|
642
|
+
nodes,
|
|
643
|
+
bp,
|
|
644
|
+
context
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
return {
|
|
650
|
+
valid: violations.length === 0,
|
|
651
|
+
nodes: Object.freeze(nodes),
|
|
652
|
+
violations: Object.freeze(violations)
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* validateAndResolve()
|
|
657
|
+
* Internal helper to validate and resolve a single token
|
|
658
|
+
*/
|
|
659
|
+
validateAndResolve(property, tokenId, rule, constitution, violations, nodes, breakpoint, context) {
|
|
660
|
+
for (const validator of this.validators) {
|
|
661
|
+
const violation = validator.validate(property, tokenId, rule, context);
|
|
662
|
+
if (violation) {
|
|
663
|
+
violations.push({
|
|
664
|
+
...violation,
|
|
665
|
+
context: breakpoint ? { breakpoint } : void 0
|
|
666
|
+
});
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
const token = this.tokenRegistry.getToken(tokenId);
|
|
671
|
+
nodes.push({
|
|
672
|
+
domain: token.domain,
|
|
673
|
+
semantic: `${constitution.componentName}.${property}`,
|
|
674
|
+
tokenRef: token.id,
|
|
675
|
+
source: "SRE.v2",
|
|
676
|
+
breakpoint
|
|
677
|
+
});
|
|
718
678
|
}
|
|
719
679
|
};
|
|
680
|
+
|
|
681
|
+
// src/domain/governance/DefaultViolationHandlers.ts
|
|
720
682
|
var DefaultViolationHandlers = class {
|
|
721
683
|
};
|
|
722
684
|
/**
|
|
@@ -792,139 +754,158 @@ DefaultViolationHandlers.ContextViolationHandler = {
|
|
|
792
754
|
}
|
|
793
755
|
};
|
|
794
756
|
|
|
795
|
-
// src/
|
|
796
|
-
var
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
"space.lg": { id: "space.lg", domain: "layout", value: "p-6" },
|
|
805
|
-
// Forbidden/Raw tokens (for demo)
|
|
806
|
-
"raw.hex": { id: "raw.hex", domain: "color", value: "bg-[#123456]" },
|
|
807
|
-
// Illegal
|
|
808
|
-
// Surface (Theme Aware!)
|
|
809
|
-
"surface.card": {
|
|
810
|
-
id: "surface.card",
|
|
811
|
-
domain: "color",
|
|
812
|
-
value: {
|
|
813
|
-
light: "bg-white",
|
|
814
|
-
dark: "bg-slate-800"
|
|
815
|
-
}
|
|
816
|
-
},
|
|
817
|
-
"surface.ground": {
|
|
818
|
-
id: "surface.ground",
|
|
819
|
-
domain: "color",
|
|
820
|
-
value: {
|
|
821
|
-
light: "bg-gray-50",
|
|
822
|
-
dark: "bg-slate-900"
|
|
823
|
-
}
|
|
824
|
-
},
|
|
825
|
-
"surface.paper": {
|
|
826
|
-
id: "surface.paper",
|
|
827
|
-
domain: "color",
|
|
828
|
-
value: {
|
|
829
|
-
light: "bg-white",
|
|
830
|
-
dark: "bg-slate-700"
|
|
831
|
-
}
|
|
832
|
-
},
|
|
833
|
-
// Text (Theme Aware!)
|
|
834
|
-
"text.light": {
|
|
835
|
-
id: "text.light",
|
|
836
|
-
domain: "color",
|
|
837
|
-
value: {
|
|
838
|
-
light: "text-white",
|
|
839
|
-
dark: "text-gray-100"
|
|
840
|
-
}
|
|
841
|
-
},
|
|
842
|
-
"text.dark": {
|
|
843
|
-
id: "text.dark",
|
|
844
|
-
domain: "color",
|
|
845
|
-
value: {
|
|
846
|
-
light: "text-gray-900",
|
|
847
|
-
dark: "text-white"
|
|
757
|
+
// src/domain/governance/ViolationEngine.ts
|
|
758
|
+
var ViolationEngine = class {
|
|
759
|
+
constructor(defaultAction = "reject", handlers) {
|
|
760
|
+
this.defaultAction = defaultAction;
|
|
761
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
762
|
+
if (handlers) {
|
|
763
|
+
for (const handler of handlers) {
|
|
764
|
+
this.handlers.set(handler.constructor.name, handler);
|
|
765
|
+
}
|
|
848
766
|
}
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Handle a violation
|
|
770
|
+
* @param violation - The violation to handle
|
|
771
|
+
* @returns Outcome (decision, not execution)
|
|
772
|
+
*/
|
|
773
|
+
handle(violation) {
|
|
774
|
+
const handler = this.handlers.get(violation.rule);
|
|
775
|
+
if (handler) {
|
|
776
|
+
return handler.handle(violation);
|
|
856
777
|
}
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
778
|
+
return this.createDefaultOutcome(violation);
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Handle multiple violations
|
|
782
|
+
* @param violations - Array of violations
|
|
783
|
+
* @returns Array of outcomes
|
|
784
|
+
*/
|
|
785
|
+
handleMultiple(violations) {
|
|
786
|
+
return violations.map((v) => this.handle(v));
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Get current default action
|
|
790
|
+
* @returns Current default action
|
|
791
|
+
*/
|
|
792
|
+
getCurrentDefaultAction() {
|
|
793
|
+
return this.defaultAction;
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Create default outcome based on default action
|
|
797
|
+
* @param violation - The violation
|
|
798
|
+
* @returns Default outcome
|
|
799
|
+
*/
|
|
800
|
+
createDefaultOutcome(violation) {
|
|
801
|
+
const currentAction = this.getCurrentDefaultAction();
|
|
802
|
+
switch (currentAction) {
|
|
803
|
+
case "reject":
|
|
804
|
+
return {
|
|
805
|
+
action: "reject",
|
|
806
|
+
metadata: {
|
|
807
|
+
contract: violation.semantic || "unknown",
|
|
808
|
+
reason: violation.message,
|
|
809
|
+
context: violation.context || {},
|
|
810
|
+
severity: violation.severity
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
case "fallback":
|
|
814
|
+
return {
|
|
815
|
+
action: "fallback",
|
|
816
|
+
replacement: this.determineFallbackValue(violation),
|
|
817
|
+
metadata: {
|
|
818
|
+
contract: violation.semantic || "unknown",
|
|
819
|
+
reason: violation.message,
|
|
820
|
+
context: violation.context || {},
|
|
821
|
+
severity: "warning"
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
case "override":
|
|
825
|
+
return {
|
|
826
|
+
action: "override",
|
|
827
|
+
metadata: {
|
|
828
|
+
contract: violation.semantic || "unknown",
|
|
829
|
+
reason: violation.message,
|
|
830
|
+
context: violation.context || {},
|
|
831
|
+
severity: "warning"
|
|
832
|
+
}
|
|
833
|
+
};
|
|
834
|
+
case "warn":
|
|
835
|
+
return {
|
|
836
|
+
action: "warn",
|
|
837
|
+
metadata: {
|
|
838
|
+
contract: violation.semantic || "unknown",
|
|
839
|
+
reason: violation.message,
|
|
840
|
+
context: violation.context || {},
|
|
841
|
+
severity: "warning"
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
default:
|
|
845
|
+
throw new Error(`Unknown action: ${currentAction}`);
|
|
864
846
|
}
|
|
865
|
-
},
|
|
866
|
-
"shadow.sm": { id: "shadow.sm", domain: "effect", value: "shadow-sm" },
|
|
867
|
-
"shadow.md": { id: "shadow.md", domain: "effect", value: "shadow-md" },
|
|
868
|
-
"shadow.lg": { id: "shadow.lg", domain: "effect", value: "shadow-lg" },
|
|
869
|
-
// Radius
|
|
870
|
-
"radius.md": { id: "radius.md", domain: "layout", value: "rounded-md" },
|
|
871
|
-
"radius.lg": { id: "radius.lg", domain: "layout", value: "rounded-lg" }
|
|
872
|
-
};
|
|
873
|
-
|
|
874
|
-
// src/domain/TokenRegistry.ts
|
|
875
|
-
var TokenRegistry = class {
|
|
876
|
-
constructor(tokens = TOKENS) {
|
|
877
|
-
this.tokens = Object.freeze({ ...tokens });
|
|
878
847
|
}
|
|
879
848
|
/**
|
|
880
|
-
*
|
|
881
|
-
* @
|
|
849
|
+
* Determine fallback value for a violation
|
|
850
|
+
* @param violation - The violation
|
|
851
|
+
* @returns Fallback value or undefined
|
|
882
852
|
*/
|
|
883
|
-
|
|
884
|
-
const
|
|
885
|
-
if (
|
|
886
|
-
|
|
853
|
+
determineFallbackValue(violation) {
|
|
854
|
+
const match = violation.message.match(/fallback to \[([^\]]+)\]/i);
|
|
855
|
+
if (match && match[1]) {
|
|
856
|
+
return match[1];
|
|
887
857
|
}
|
|
888
|
-
|
|
858
|
+
if (violation.semantic) {
|
|
859
|
+
const parts = violation.semantic.split(".");
|
|
860
|
+
if (parts.length >= 2) {
|
|
861
|
+
const property = parts[parts.length - 1];
|
|
862
|
+
const fallbacks = {
|
|
863
|
+
"padding": "md",
|
|
864
|
+
"margin": "md",
|
|
865
|
+
"spacing": "md",
|
|
866
|
+
"radius": "md",
|
|
867
|
+
"shadow": "md",
|
|
868
|
+
"background": "surface.card",
|
|
869
|
+
"color": "color.primary"
|
|
870
|
+
};
|
|
871
|
+
if (property in fallbacks) {
|
|
872
|
+
return fallbacks[property];
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
return void 0;
|
|
889
877
|
}
|
|
890
878
|
/**
|
|
891
|
-
*
|
|
879
|
+
* Register a handler
|
|
880
|
+
* @param handler - The handler to register
|
|
892
881
|
*/
|
|
893
|
-
|
|
894
|
-
|
|
882
|
+
registerHandler(handler) {
|
|
883
|
+
this.handlers.set(handler.constructor.name, handler);
|
|
895
884
|
}
|
|
896
885
|
/**
|
|
897
|
-
*
|
|
886
|
+
* Unregister a handler
|
|
887
|
+
* @param handlerName - Name of handler to unregister
|
|
898
888
|
*/
|
|
899
|
-
|
|
900
|
-
|
|
889
|
+
unregisterHandler(handlerName) {
|
|
890
|
+
this.handlers.delete(handlerName);
|
|
901
891
|
}
|
|
902
|
-
};
|
|
903
|
-
|
|
904
|
-
// src/domain/ThemeResolver.ts
|
|
905
|
-
var ThemeResolver = class {
|
|
906
892
|
/**
|
|
907
|
-
*
|
|
893
|
+
* Get all registered handlers
|
|
894
|
+
* @returns Array of handler names
|
|
908
895
|
*/
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
return value;
|
|
912
|
-
}
|
|
913
|
-
if (theme in value) {
|
|
914
|
-
return value[theme];
|
|
915
|
-
}
|
|
916
|
-
throw new Error(`Theme '${theme}' not found in value. Available themes: ${Object.keys(value).join(", ")}`);
|
|
896
|
+
getHandlers() {
|
|
897
|
+
return Array.from(this.handlers.keys());
|
|
917
898
|
}
|
|
918
899
|
/**
|
|
919
|
-
*
|
|
920
|
-
*
|
|
900
|
+
* Set default action
|
|
901
|
+
* @param action - The default action
|
|
921
902
|
*/
|
|
922
|
-
|
|
923
|
-
|
|
903
|
+
setDefaultAction(action) {
|
|
904
|
+
this.defaultAction = action;
|
|
924
905
|
}
|
|
925
906
|
};
|
|
926
907
|
|
|
927
|
-
// src/domain/ContextFactory.ts
|
|
908
|
+
// src/domain/factories/ContextFactory.ts
|
|
928
909
|
var ContextFactory = class {
|
|
929
910
|
/**
|
|
930
911
|
* Create a style context with all required fields
|
|
@@ -971,7 +952,7 @@ var ContextFactory = class {
|
|
|
971
952
|
}
|
|
972
953
|
};
|
|
973
954
|
|
|
974
|
-
// src/runtime/StyleContract.ts
|
|
955
|
+
// src/runtime/core/StyleContract.ts
|
|
975
956
|
var StyleContract = class {
|
|
976
957
|
constructor(contract, constitution, engine) {
|
|
977
958
|
this.contract = contract;
|
|
@@ -1068,8 +1049,51 @@ var StyleContract = class {
|
|
|
1068
1049
|
}
|
|
1069
1050
|
};
|
|
1070
1051
|
|
|
1071
|
-
// src/runtime/StyleProvider.tsx
|
|
1072
|
-
import { createContext, useContext, useEffect, useState } from "react";
|
|
1052
|
+
// src/runtime/react/StyleProvider.tsx
|
|
1053
|
+
import { createContext, useContext, useEffect, useState, useMemo } from "react";
|
|
1054
|
+
|
|
1055
|
+
// src/runtime/adapters/WebPlatformAdapter.ts
|
|
1056
|
+
var WebPlatformAdapter = class {
|
|
1057
|
+
constructor() {
|
|
1058
|
+
this.platform = "web";
|
|
1059
|
+
}
|
|
1060
|
+
getInitialDevice() {
|
|
1061
|
+
if (typeof window === "undefined") return "desktop";
|
|
1062
|
+
const width = window.innerWidth;
|
|
1063
|
+
if (width < 768) return "mobile";
|
|
1064
|
+
if (width < 1024) return "tablet";
|
|
1065
|
+
return "desktop";
|
|
1066
|
+
}
|
|
1067
|
+
subscribeToResize(callback) {
|
|
1068
|
+
if (typeof window === "undefined") {
|
|
1069
|
+
return () => {
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
const handleResize = () => {
|
|
1073
|
+
const width = window.innerWidth;
|
|
1074
|
+
let device = "desktop";
|
|
1075
|
+
if (width < 768) device = "mobile";
|
|
1076
|
+
else if (width < 1024) device = "tablet";
|
|
1077
|
+
callback(device);
|
|
1078
|
+
};
|
|
1079
|
+
window.addEventListener("resize", handleResize);
|
|
1080
|
+
handleResize();
|
|
1081
|
+
return () => {
|
|
1082
|
+
window.removeEventListener("resize", handleResize);
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
applyTheme(theme) {
|
|
1086
|
+
if (typeof document === "undefined") return;
|
|
1087
|
+
const root = document.documentElement;
|
|
1088
|
+
if (theme === "dark") {
|
|
1089
|
+
root.classList.add("dark");
|
|
1090
|
+
} else {
|
|
1091
|
+
root.classList.remove("dark");
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
};
|
|
1095
|
+
|
|
1096
|
+
// src/runtime/react/StyleProvider.tsx
|
|
1073
1097
|
import { jsx } from "react/jsx-runtime";
|
|
1074
1098
|
var defaultContext = {
|
|
1075
1099
|
platform: "web",
|
|
@@ -1081,27 +1105,29 @@ var defaultContext = {
|
|
|
1081
1105
|
}
|
|
1082
1106
|
};
|
|
1083
1107
|
var StyleEngineContext = createContext(defaultContext);
|
|
1084
|
-
var StyleProvider = ({
|
|
1108
|
+
var StyleProvider = ({
|
|
1109
|
+
children,
|
|
1110
|
+
initialTheme = "light",
|
|
1111
|
+
adapter
|
|
1112
|
+
}) => {
|
|
1113
|
+
const platformAdapter = useMemo(() => adapter || new WebPlatformAdapter(), [adapter]);
|
|
1085
1114
|
const [theme, setThemeState] = useState(initialTheme);
|
|
1086
|
-
const [device, setDevice] = useState(
|
|
1115
|
+
const [device, setDevice] = useState(() => {
|
|
1116
|
+
try {
|
|
1117
|
+
return platformAdapter.getInitialDevice();
|
|
1118
|
+
} catch {
|
|
1119
|
+
return "desktop";
|
|
1120
|
+
}
|
|
1121
|
+
});
|
|
1087
1122
|
useEffect(() => {
|
|
1088
|
-
const
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
};
|
|
1094
|
-
handleResize();
|
|
1095
|
-
window.addEventListener("resize", handleResize);
|
|
1096
|
-
return () => window.removeEventListener("resize", handleResize);
|
|
1097
|
-
}, []);
|
|
1123
|
+
const unsubscribe = platformAdapter.subscribeToResize((newDevice) => {
|
|
1124
|
+
setDevice(newDevice);
|
|
1125
|
+
});
|
|
1126
|
+
return unsubscribe;
|
|
1127
|
+
}, [platformAdapter]);
|
|
1098
1128
|
useEffect(() => {
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
} else {
|
|
1102
|
-
document.documentElement.classList.remove("dark");
|
|
1103
|
-
}
|
|
1104
|
-
}, [theme]);
|
|
1129
|
+
platformAdapter.applyTheme(theme);
|
|
1130
|
+
}, [theme, platformAdapter]);
|
|
1105
1131
|
const toggleTheme = () => {
|
|
1106
1132
|
setThemeState((prev) => prev === "light" ? "dark" : "light");
|
|
1107
1133
|
};
|
|
@@ -1109,7 +1135,7 @@ var StyleProvider = ({ children, initialTheme = "light" }) => {
|
|
|
1109
1135
|
setThemeState(newTheme);
|
|
1110
1136
|
};
|
|
1111
1137
|
const value = {
|
|
1112
|
-
platform:
|
|
1138
|
+
platform: platformAdapter.platform,
|
|
1113
1139
|
theme,
|
|
1114
1140
|
device,
|
|
1115
1141
|
toggleTheme,
|
|
@@ -1119,7 +1145,23 @@ var StyleProvider = ({ children, initialTheme = "light" }) => {
|
|
|
1119
1145
|
};
|
|
1120
1146
|
var useStyleContext = () => useContext(StyleEngineContext);
|
|
1121
1147
|
|
|
1122
|
-
// src/
|
|
1148
|
+
// src/runtime/adapters/NativePlatformAdapter.ts
|
|
1149
|
+
var NativePlatformAdapter = class {
|
|
1150
|
+
constructor() {
|
|
1151
|
+
this.platform = "native";
|
|
1152
|
+
}
|
|
1153
|
+
getInitialDevice() {
|
|
1154
|
+
return "mobile";
|
|
1155
|
+
}
|
|
1156
|
+
subscribeToResize(callback) {
|
|
1157
|
+
return () => {
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
applyTheme(theme) {
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
|
|
1164
|
+
// src/adapter/meta-architecture/rules/MaseValidationRule.ts
|
|
1123
1165
|
import {
|
|
1124
1166
|
ValidationError
|
|
1125
1167
|
} from "@damarkuncoro/meta-architecture";
|
|
@@ -1167,6 +1209,8 @@ var MaseValidationRule = class {
|
|
|
1167
1209
|
);
|
|
1168
1210
|
}
|
|
1169
1211
|
};
|
|
1212
|
+
|
|
1213
|
+
// src/adapter/meta-architecture/MasePlugin.ts
|
|
1170
1214
|
var MaseGraphValidationPlugin = class {
|
|
1171
1215
|
constructor() {
|
|
1172
1216
|
this.metadata = {
|
|
@@ -1188,7 +1232,46 @@ var MaseGraphValidationPlugin = class {
|
|
|
1188
1232
|
}
|
|
1189
1233
|
};
|
|
1190
1234
|
|
|
1191
|
-
// src/adapter/
|
|
1235
|
+
// src/adapter/meta-architecture/errors/MaseValidationError.ts
|
|
1236
|
+
var MaseValidationError = class extends Error {
|
|
1237
|
+
constructor(message, code, field) {
|
|
1238
|
+
super(message);
|
|
1239
|
+
this.name = "ValidationError";
|
|
1240
|
+
this.code = code;
|
|
1241
|
+
this.field = field;
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
|
|
1245
|
+
// src/adapter/meta-architecture/rules/MaseGovernanceRule.ts
|
|
1246
|
+
var MaseGovernanceRule = class {
|
|
1247
|
+
constructor() {
|
|
1248
|
+
this.name = "MASE-Constitutional-Compliance";
|
|
1249
|
+
this.description = "Enforces strict adherence to Component Constitution using MASE SRE.";
|
|
1250
|
+
this.category = "business";
|
|
1251
|
+
// It's a business rule (Design System Law)
|
|
1252
|
+
this.severity = "error";
|
|
1253
|
+
const tokenRegistry = new TokenRegistry();
|
|
1254
|
+
const themeResolver = new ThemeResolver();
|
|
1255
|
+
this.engine = new StyleResolutionEngine(tokenRegistry, themeResolver);
|
|
1256
|
+
}
|
|
1257
|
+
async validate(target, _context) {
|
|
1258
|
+
const result = this.engine.resolve(target.contract, target.constitution);
|
|
1259
|
+
if (result.valid) {
|
|
1260
|
+
return null;
|
|
1261
|
+
}
|
|
1262
|
+
const primaryViolation = result.violations[0];
|
|
1263
|
+
const messages = result.violations.map((v) => `[${v.rule}] ${v.message} (${v.semantic})`).join("; ");
|
|
1264
|
+
return new MaseValidationError(
|
|
1265
|
+
messages,
|
|
1266
|
+
primaryViolation.rule,
|
|
1267
|
+
// code
|
|
1268
|
+
target.constitution.componentName
|
|
1269
|
+
// field/target
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
};
|
|
1273
|
+
|
|
1274
|
+
// src/adapter/meta-architecture/factories/CompliancePipelineFactory.ts
|
|
1192
1275
|
import { ValidationPipeline } from "@damarkuncoro/meta-architecture";
|
|
1193
1276
|
|
|
1194
1277
|
// src/data/constitutions/CardConstitution.ts
|
|
@@ -1219,7 +1302,7 @@ var CardConstitution = {
|
|
|
1219
1302
|
]
|
|
1220
1303
|
};
|
|
1221
1304
|
|
|
1222
|
-
// src/adapter/
|
|
1305
|
+
// src/adapter/meta-architecture/factories/CompliancePipelineFactory.ts
|
|
1223
1306
|
var CompliancePipelineFactory = class {
|
|
1224
1307
|
static async createPipeline() {
|
|
1225
1308
|
const pipeline = new ValidationPipeline();
|
|
@@ -1278,43 +1361,6 @@ var CompliancePipelineFactory = class {
|
|
|
1278
1361
|
}
|
|
1279
1362
|
};
|
|
1280
1363
|
|
|
1281
|
-
// src/adapter/rules.ts
|
|
1282
|
-
var MaseValidationError = class extends Error {
|
|
1283
|
-
constructor(message, code, field) {
|
|
1284
|
-
super(message);
|
|
1285
|
-
this.name = "ValidationError";
|
|
1286
|
-
this.code = code;
|
|
1287
|
-
this.field = field;
|
|
1288
|
-
}
|
|
1289
|
-
};
|
|
1290
|
-
var MaseGovernanceRule = class {
|
|
1291
|
-
constructor() {
|
|
1292
|
-
this.name = "MASE-Constitutional-Compliance";
|
|
1293
|
-
this.description = "Enforces strict adherence to Component Constitution using MASE SRE.";
|
|
1294
|
-
this.category = "business";
|
|
1295
|
-
// It's a business rule (Design System Law)
|
|
1296
|
-
this.severity = "error";
|
|
1297
|
-
const tokenRegistry = new TokenRegistry();
|
|
1298
|
-
const themeResolver = new ThemeResolver();
|
|
1299
|
-
this.engine = new StyleResolutionEngine(tokenRegistry, themeResolver);
|
|
1300
|
-
}
|
|
1301
|
-
async validate(target, _context) {
|
|
1302
|
-
const result = this.engine.resolve(target.contract, target.constitution);
|
|
1303
|
-
if (result.valid) {
|
|
1304
|
-
return null;
|
|
1305
|
-
}
|
|
1306
|
-
const primaryViolation = result.violations[0];
|
|
1307
|
-
const messages = result.violations.map((v) => `[${v.rule}] ${v.message} (${v.semantic})`).join("; ");
|
|
1308
|
-
return new MaseValidationError(
|
|
1309
|
-
messages,
|
|
1310
|
-
primaryViolation.rule,
|
|
1311
|
-
// code
|
|
1312
|
-
target.constitution.componentName
|
|
1313
|
-
// field/target
|
|
1314
|
-
);
|
|
1315
|
-
}
|
|
1316
|
-
};
|
|
1317
|
-
|
|
1318
1364
|
// src/data/constitutions/ButtonConstitution.ts
|
|
1319
1365
|
var ButtonConstitution = {
|
|
1320
1366
|
componentName: "Button",
|
|
@@ -1340,7 +1386,17 @@ var ButtonConstitution = {
|
|
|
1340
1386
|
]
|
|
1341
1387
|
};
|
|
1342
1388
|
|
|
1343
|
-
// src/dsl/
|
|
1389
|
+
// src/dsl/lexer/TokenizerError.ts
|
|
1390
|
+
var TokenizerError = class extends Error {
|
|
1391
|
+
constructor(message, line, column) {
|
|
1392
|
+
super(message);
|
|
1393
|
+
this.name = "TokenizerError";
|
|
1394
|
+
this.line = line;
|
|
1395
|
+
this.column = column;
|
|
1396
|
+
}
|
|
1397
|
+
};
|
|
1398
|
+
|
|
1399
|
+
// src/dsl/lexer/Tokenizer.ts
|
|
1344
1400
|
var TokenType = {
|
|
1345
1401
|
// Keywords
|
|
1346
1402
|
CONTRACT: "CONTRACT",
|
|
@@ -1382,14 +1438,6 @@ var TokenType = {
|
|
|
1382
1438
|
EOF: "EOF",
|
|
1383
1439
|
UNKNOWN: "UNKNOWN"
|
|
1384
1440
|
};
|
|
1385
|
-
var TokenizerError = class extends Error {
|
|
1386
|
-
constructor(message, line, column) {
|
|
1387
|
-
super(message);
|
|
1388
|
-
this.name = "TokenizerError";
|
|
1389
|
-
this.line = line;
|
|
1390
|
-
this.column = column;
|
|
1391
|
-
}
|
|
1392
|
-
};
|
|
1393
1441
|
var ContractDSLTokenizer = class {
|
|
1394
1442
|
constructor() {
|
|
1395
1443
|
this.source = "";
|
|
@@ -1413,7 +1461,7 @@ var ContractDSLTokenizer = class {
|
|
|
1413
1461
|
["web", TokenType.WEB],
|
|
1414
1462
|
["native", TokenType.NATIVE],
|
|
1415
1463
|
["canvas", TokenType.CANVAS],
|
|
1416
|
-
[
|
|
1464
|
+
// ['default', TokenType.DEFAULT_CTX], // Removed duplicate mapping
|
|
1417
1465
|
["hover", TokenType.HOVER],
|
|
1418
1466
|
["active", TokenType.ACTIVE],
|
|
1419
1467
|
["disabled", TokenType.DISABLED],
|
|
@@ -1573,7 +1621,7 @@ var ContractDSLTokenizer = class {
|
|
|
1573
1621
|
}
|
|
1574
1622
|
};
|
|
1575
1623
|
|
|
1576
|
-
// src/dsl/
|
|
1624
|
+
// src/dsl/parser/ParserError.ts
|
|
1577
1625
|
var ParserError = class extends Error {
|
|
1578
1626
|
constructor(message, line, column) {
|
|
1579
1627
|
super(message);
|
|
@@ -1582,6 +1630,8 @@ var ParserError = class extends Error {
|
|
|
1582
1630
|
this.column = column;
|
|
1583
1631
|
}
|
|
1584
1632
|
};
|
|
1633
|
+
|
|
1634
|
+
// src/dsl/parser/Parser.ts
|
|
1585
1635
|
var ContractDSLParser = class {
|
|
1586
1636
|
constructor() {
|
|
1587
1637
|
this.tokens = [];
|
|
@@ -1626,7 +1676,7 @@ var ContractDSLParser = class {
|
|
|
1626
1676
|
parseDomain() {
|
|
1627
1677
|
this.expect(TokenType.DOMAIN);
|
|
1628
1678
|
this.expect(TokenType.COLON);
|
|
1629
|
-
const domain = this.
|
|
1679
|
+
const domain = this.expectDomain();
|
|
1630
1680
|
this.expect(TokenType.SEMICOLON);
|
|
1631
1681
|
return domain;
|
|
1632
1682
|
}
|
|
@@ -1763,13 +1813,29 @@ var ContractDSLParser = class {
|
|
|
1763
1813
|
this.advance();
|
|
1764
1814
|
return token.value;
|
|
1765
1815
|
}
|
|
1816
|
+
/**
|
|
1817
|
+
* Expect domain token
|
|
1818
|
+
* @returns Domain value
|
|
1819
|
+
*/
|
|
1820
|
+
expectDomain() {
|
|
1821
|
+
const token = this.peek();
|
|
1822
|
+
if (!token || token.type !== TokenType.LAYOUT && token.type !== TokenType.TYPOGRAPHY && token.type !== TokenType.COLOR && token.type !== TokenType.EFFECT && token.type !== TokenType.INTERACTION && token.type !== TokenType.IDENTIFIER) {
|
|
1823
|
+
throw new ParserError(
|
|
1824
|
+
`Expected domain, got ${token?.type || "EOF"}`,
|
|
1825
|
+
token?.line || 0,
|
|
1826
|
+
token?.column || 0
|
|
1827
|
+
);
|
|
1828
|
+
}
|
|
1829
|
+
this.advance();
|
|
1830
|
+
return token.value;
|
|
1831
|
+
}
|
|
1766
1832
|
/**
|
|
1767
1833
|
* Expect context token
|
|
1768
1834
|
* @returns Context value
|
|
1769
1835
|
*/
|
|
1770
1836
|
expectContext() {
|
|
1771
1837
|
const token = this.peek();
|
|
1772
|
-
if (!token || token.type !== TokenType.MOBILE && token.type !== TokenType.TABLET && token.type !== TokenType.DESKTOP && token.type !== TokenType.LIGHT && token.type !== TokenType.DARK && token.type !== TokenType.WEB && token.type !== TokenType.NATIVE && token.type !== TokenType.CANVAS && token.type !== TokenType.DEFAULT_CTX && token.type !== TokenType.HOVER && token.type !== TokenType.ACTIVE && token.type !== TokenType.DISABLED) {
|
|
1838
|
+
if (!token || token.type !== TokenType.MOBILE && token.type !== TokenType.TABLET && token.type !== TokenType.DESKTOP && token.type !== TokenType.LIGHT && token.type !== TokenType.DARK && token.type !== TokenType.WEB && token.type !== TokenType.NATIVE && token.type !== TokenType.CANVAS && token.type !== TokenType.DEFAULT_CTX && token.type !== TokenType.DEFAULT && token.type !== TokenType.HOVER && token.type !== TokenType.ACTIVE && token.type !== TokenType.DISABLED) {
|
|
1773
1839
|
throw new ParserError(
|
|
1774
1840
|
`Expected context, got ${token?.type || "EOF"}`,
|
|
1775
1841
|
token?.line || 0,
|
|
@@ -1809,7 +1875,7 @@ var ContractDSLParser = class {
|
|
|
1809
1875
|
}
|
|
1810
1876
|
};
|
|
1811
1877
|
|
|
1812
|
-
// src/dsl/
|
|
1878
|
+
// src/dsl/validator/ValidationError.ts
|
|
1813
1879
|
var ValidationError2 = class extends Error {
|
|
1814
1880
|
constructor(message, path) {
|
|
1815
1881
|
super(message);
|
|
@@ -1817,6 +1883,8 @@ var ValidationError2 = class extends Error {
|
|
|
1817
1883
|
this.path = path;
|
|
1818
1884
|
}
|
|
1819
1885
|
};
|
|
1886
|
+
|
|
1887
|
+
// src/dsl/validator/Validator.ts
|
|
1820
1888
|
var ContractDSLValidator = class {
|
|
1821
1889
|
constructor() {
|
|
1822
1890
|
this.validDomains = /* @__PURE__ */ new Set([
|
|
@@ -2099,7 +2167,7 @@ var ContractDSLValidator = class {
|
|
|
2099
2167
|
}
|
|
2100
2168
|
};
|
|
2101
2169
|
|
|
2102
|
-
// src/dsl/Compiler.ts
|
|
2170
|
+
// src/dsl/compiler/Compiler.ts
|
|
2103
2171
|
var ContractDSLCompiler = class {
|
|
2104
2172
|
/**
|
|
2105
2173
|
* Compile AST to ComponentConstitution and StyleContractDefinition
|
|
@@ -2254,7 +2322,7 @@ var ContractDSLCompiler = class {
|
|
|
2254
2322
|
}
|
|
2255
2323
|
};
|
|
2256
2324
|
|
|
2257
|
-
// src/materializer/
|
|
2325
|
+
// src/materializer/core/MaterializationError.ts
|
|
2258
2326
|
var MaterializationError = class extends Error {
|
|
2259
2327
|
constructor(message, platform, semantic) {
|
|
2260
2328
|
super(message);
|
|
@@ -2264,7 +2332,7 @@ var MaterializationError = class extends Error {
|
|
|
2264
2332
|
}
|
|
2265
2333
|
};
|
|
2266
2334
|
|
|
2267
|
-
// src/materializer/CSSMaterializer.ts
|
|
2335
|
+
// src/materializer/targets/CSSMaterializer.ts
|
|
2268
2336
|
var CSSMaterializer = class {
|
|
2269
2337
|
constructor() {
|
|
2270
2338
|
this.semanticToCSS = this.buildSemanticToCSSMapping();
|
|
@@ -2426,7 +2494,7 @@ var CSSMaterializer = class {
|
|
|
2426
2494
|
}
|
|
2427
2495
|
};
|
|
2428
2496
|
|
|
2429
|
-
// src/materializer/RNMaterializer.ts
|
|
2497
|
+
// src/materializer/targets/RNMaterializer.ts
|
|
2430
2498
|
var RNMaterializer = class {
|
|
2431
2499
|
constructor() {
|
|
2432
2500
|
this.semanticToRN = this.buildSemanticToRNMapping();
|
|
@@ -2541,7 +2609,7 @@ var RNMaterializer = class {
|
|
|
2541
2609
|
}
|
|
2542
2610
|
};
|
|
2543
2611
|
|
|
2544
|
-
// src/materializer/PDFMaterializer.ts
|
|
2612
|
+
// src/materializer/targets/PDFMaterializer.ts
|
|
2545
2613
|
var PDFMaterializer = class {
|
|
2546
2614
|
constructor() {
|
|
2547
2615
|
this.semanticToPDF = this.buildSemanticToPDFMapping();
|
|
@@ -2656,6 +2724,7 @@ var PDFMaterializer = class {
|
|
|
2656
2724
|
}
|
|
2657
2725
|
};
|
|
2658
2726
|
export {
|
|
2727
|
+
AllowedTokenValidator,
|
|
2659
2728
|
ButtonConstitution,
|
|
2660
2729
|
CSSMaterializer,
|
|
2661
2730
|
CanonicalStyleGraph,
|
|
@@ -2668,11 +2737,13 @@ export {
|
|
|
2668
2737
|
ContractDSLTokenizer,
|
|
2669
2738
|
ContractDSLValidator,
|
|
2670
2739
|
DefaultViolationHandlers,
|
|
2740
|
+
DomainValidator,
|
|
2671
2741
|
MaseGovernanceRule,
|
|
2672
2742
|
MaseGraphValidationPlugin,
|
|
2673
2743
|
MaseValidationError,
|
|
2674
2744
|
MaseValidationRule,
|
|
2675
2745
|
MaterializationError,
|
|
2746
|
+
NativePlatformAdapter,
|
|
2676
2747
|
PDFMaterializer,
|
|
2677
2748
|
RNMaterializer,
|
|
2678
2749
|
StyleContract,
|
|
@@ -2680,8 +2751,10 @@ export {
|
|
|
2680
2751
|
StyleResolutionEngine,
|
|
2681
2752
|
TOKENS,
|
|
2682
2753
|
ThemeResolver,
|
|
2754
|
+
TokenExistenceValidator,
|
|
2683
2755
|
TokenRegistry,
|
|
2684
2756
|
ViolationEngine,
|
|
2757
|
+
WebPlatformAdapter,
|
|
2685
2758
|
useStyleContext
|
|
2686
2759
|
};
|
|
2687
2760
|
//# sourceMappingURL=index.js.map
|