praxis-kit 1.1.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.
@@ -0,0 +1,1329 @@
1
+ // ../vite-plugin/src/ast.ts
2
+ import ts from "typescript";
3
+ function getProperty(obj, key) {
4
+ for (const prop of obj.properties) {
5
+ if (!ts.isPropertyAssignment(prop)) continue;
6
+ const name = prop.name;
7
+ if ((ts.isIdentifier(name) || ts.isStringLiteral(name)) && name.text === key)
8
+ return prop.initializer;
9
+ }
10
+ return void 0;
11
+ }
12
+ function asObject(node) {
13
+ if (!node) return void 0;
14
+ return ts.isObjectLiteralExpression(node) ? node : void 0;
15
+ }
16
+ function asArray(node) {
17
+ if (!node) return void 0;
18
+ return ts.isArrayLiteralExpression(node) ? node : void 0;
19
+ }
20
+ function asPositiveInt(node) {
21
+ if (!node) return void 0;
22
+ if (ts.isNumericLiteral(node)) {
23
+ const n = Number(node.text);
24
+ return Number.isFinite(n) && n >= 0 ? n : void 0;
25
+ }
26
+ return void 0;
27
+ }
28
+ function isFactoryCall(call, names) {
29
+ const { expression } = call;
30
+ if (ts.isIdentifier(expression)) return names.has(expression.text);
31
+ if (ts.isPropertyAccessExpression(expression)) return names.has(expression.name.text);
32
+ return false;
33
+ }
34
+ function firstObjectArg(call) {
35
+ const [first] = call.arguments;
36
+ return first && ts.isObjectLiteralExpression(first) ? first : void 0;
37
+ }
38
+ function walk(node, visitor) {
39
+ visitor(node);
40
+ ts.forEachChild(node, (child) => walk(child, visitor));
41
+ }
42
+ function parseSource(filename, code) {
43
+ return ts.createSourceFile(filename, code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
44
+ }
45
+
46
+ // ../vite-plugin/src/class-extract.ts
47
+ import ts2 from "typescript";
48
+ var MAX_COMBINATIONS = 512;
49
+ function asString(node) {
50
+ return node && ts2.isStringLiteral(node) ? node.text : void 0;
51
+ }
52
+ function asStringOrStringArray(node) {
53
+ if (!node) return void 0;
54
+ if (ts2.isStringLiteral(node)) return node.text;
55
+ if (ts2.isArrayLiteralExpression(node)) {
56
+ const items = [];
57
+ for (const elem of node.elements) {
58
+ if (!ts2.isStringLiteral(elem)) return void 0;
59
+ items.push(elem.text);
60
+ }
61
+ return items;
62
+ }
63
+ return void 0;
64
+ }
65
+ function propKey(prop) {
66
+ if (!ts2.isPropertyAssignment(prop)) return void 0;
67
+ const n = prop.name;
68
+ return ts2.isIdentifier(n) || ts2.isStringLiteral(n) ? n.text : void 0;
69
+ }
70
+ function extractVariantMap(stylingObj) {
71
+ const variantsObj = asObject(getProperty(stylingObj, "variants"));
72
+ if (!variantsObj) return null;
73
+ const result = {};
74
+ for (const prop of variantsObj.properties) {
75
+ const key = propKey(prop);
76
+ if (!key || !ts2.isPropertyAssignment(prop)) return null;
77
+ const valuesObj = asObject(prop.initializer);
78
+ if (!valuesObj) return null;
79
+ const values = {};
80
+ for (const vp of valuesObj.properties) {
81
+ const vk = propKey(vp);
82
+ if (!vk || !ts2.isPropertyAssignment(vp)) return null;
83
+ const v = asStringOrStringArray(vp.initializer);
84
+ if (v === void 0) return null;
85
+ values[vk] = v;
86
+ }
87
+ result[key] = values;
88
+ }
89
+ return result;
90
+ }
91
+ function extractDefaults(stylingObj) {
92
+ const defaultsObj = asObject(getProperty(stylingObj, "defaults"));
93
+ if (!defaultsObj) return {};
94
+ const result = {};
95
+ for (const prop of defaultsObj.properties) {
96
+ const key = propKey(prop);
97
+ if (!key || !ts2.isPropertyAssignment(prop)) return {};
98
+ const v = asString(prop.initializer);
99
+ if (v === void 0) return {};
100
+ result[key] = v;
101
+ }
102
+ return result;
103
+ }
104
+ function extractCompounds(stylingObj) {
105
+ const compoundsArr = asArray(getProperty(stylingObj, "compounds"));
106
+ if (!compoundsArr) return [];
107
+ const result = [];
108
+ for (const elem of compoundsArr.elements) {
109
+ const obj = asObject(elem);
110
+ if (!obj) return null;
111
+ const cls = asStringOrStringArray(getProperty(obj, "class"));
112
+ if (cls === void 0) return null;
113
+ const conditions = {};
114
+ for (const cp of obj.properties) {
115
+ const key = propKey(cp);
116
+ if (!key || !ts2.isPropertyAssignment(cp)) return null;
117
+ if (key === "class") continue;
118
+ const v = asStringOrStringArray(cp.initializer);
119
+ if (v === void 0) return null;
120
+ conditions[key] = v;
121
+ }
122
+ result.push({ conditions, cls });
123
+ }
124
+ return result;
125
+ }
126
+ function enumerateCombinations(variantMap) {
127
+ const keys = Object.keys(variantMap);
128
+ if (keys.length === 0) return [{}];
129
+ let total = 1;
130
+ for (const key of keys) {
131
+ total *= Object.keys(variantMap[key]).length + 1;
132
+ if (total > MAX_COMBINATIONS) return null;
133
+ }
134
+ function rec(remaining) {
135
+ if (remaining.length === 0) return [{}];
136
+ const first = remaining[0];
137
+ const rest = remaining.slice(1);
138
+ const restCombos = rec(rest);
139
+ const valueKeys = Object.keys(variantMap[first]);
140
+ const out = [];
141
+ for (const combo of restCombos) {
142
+ out.push(combo);
143
+ for (const v of valueKeys) {
144
+ out.push({ [first]: v, ...combo });
145
+ }
146
+ }
147
+ return out;
148
+ }
149
+ return rec(keys);
150
+ }
151
+ function buildCacheKey(props) {
152
+ const parts = Object.keys(props).sort().map((k) => `${k}:s:${props[k]}`);
153
+ return `__none__:${parts.join("|")}`;
154
+ }
155
+ function computeClasses(config, props) {
156
+ const { variantMap, defaults, compounds } = config;
157
+ const effective = { ...defaults, ...props };
158
+ const classes = [];
159
+ for (const [key, values] of Object.entries(variantMap)) {
160
+ const v = effective[key];
161
+ if (v === void 0) continue;
162
+ const cls = values[v];
163
+ if (cls === void 0) continue;
164
+ if (Array.isArray(cls)) classes.push(...cls);
165
+ else classes.push(cls);
166
+ }
167
+ for (const { conditions, cls } of compounds) {
168
+ let ok = true;
169
+ for (const [key, cond] of Object.entries(conditions)) {
170
+ const v = effective[key];
171
+ if (Array.isArray(cond)) {
172
+ if (v === void 0 || !cond.includes(v)) {
173
+ ok = false;
174
+ break;
175
+ }
176
+ } else {
177
+ if (v !== cond) {
178
+ ok = false;
179
+ break;
180
+ }
181
+ }
182
+ }
183
+ if (ok) {
184
+ if (Array.isArray(cls)) classes.push(...cls);
185
+ else classes.push(cls);
186
+ }
187
+ }
188
+ return classes.filter(Boolean).join(" ");
189
+ }
190
+ function buildPrecomputedClasses(stylingObj) {
191
+ if (getProperty(stylingObj, "precomputedClasses") !== void 0) return null;
192
+ const variantMap = extractVariantMap(stylingObj);
193
+ if (!variantMap || Object.keys(variantMap).length === 0) return null;
194
+ const defaults = extractDefaults(stylingObj);
195
+ const compounds = extractCompounds(stylingObj);
196
+ if (!compounds) return null;
197
+ const combos = enumerateCombinations(variantMap);
198
+ if (!combos) return null;
199
+ const config = { variantMap, defaults, compounds };
200
+ const map = {};
201
+ for (const combo of combos) {
202
+ map[buildCacheKey(combo)] = computeClasses(config, combo);
203
+ }
204
+ return map;
205
+ }
206
+ function createClassExtractTransformer(factory, calleeNames, onInjected) {
207
+ return (context) => {
208
+ function visit(node) {
209
+ if (!ts2.isCallExpression(node)) return ts2.visitEachChild(node, visit, context);
210
+ if (!isFactoryCall(node, calleeNames)) return ts2.visitEachChild(node, visit, context);
211
+ const arg = firstObjectArg(node);
212
+ if (!arg) return node;
213
+ const stylingNode = getProperty(arg, "styling");
214
+ const stylingObj = asObject(stylingNode);
215
+ if (!stylingObj) return ts2.visitEachChild(node, visit, context);
216
+ const map = buildPrecomputedClasses(stylingObj);
217
+ if (!map) return ts2.visitEachChild(node, visit, context);
218
+ onInjected();
219
+ const mapProps = Object.entries(map).map(
220
+ ([k, v]) => factory.createPropertyAssignment(
221
+ factory.createStringLiteral(k),
222
+ factory.createStringLiteral(v)
223
+ )
224
+ );
225
+ const mapLiteral = factory.createObjectLiteralExpression(mapProps, true);
226
+ const precomputedProp = factory.createPropertyAssignment(
227
+ factory.createIdentifier("precomputedClasses"),
228
+ mapLiteral
229
+ );
230
+ const newStylingObj = factory.createObjectLiteralExpression(
231
+ [...stylingObj.properties, precomputedProp],
232
+ true
233
+ );
234
+ const newArgProps = arg.properties.map((p) => {
235
+ if (ts2.isPropertyAssignment(p) && (ts2.isIdentifier(p.name) || ts2.isStringLiteral(p.name)) && p.name.text === "styling") {
236
+ return factory.createPropertyAssignment(p.name, newStylingObj);
237
+ }
238
+ return p;
239
+ });
240
+ const newArg = factory.createObjectLiteralExpression(newArgProps, true);
241
+ return factory.createCallExpression(node.expression, node.typeArguments, [
242
+ newArg,
243
+ ...node.arguments.slice(1)
244
+ ]);
245
+ }
246
+ return (sourceFile) => ts2.visitEachChild(sourceFile, visit, context);
247
+ };
248
+ }
249
+ function injectPrecomputedClasses(source, calleeNames) {
250
+ let hasVariants = false;
251
+ walk(source, (n) => {
252
+ if (hasVariants) return;
253
+ if (ts2.isPropertyAssignment(n) && (ts2.isIdentifier(n.name) || ts2.isStringLiteral(n.name)) && n.name.text === "variants")
254
+ hasVariants = true;
255
+ });
256
+ if (!hasVariants) return null;
257
+ let didInject = false;
258
+ const result = ts2.transform(
259
+ source,
260
+ [
261
+ createClassExtractTransformer(ts2.factory, calleeNames, () => {
262
+ didInject = true;
263
+ })
264
+ ],
265
+ { target: ts2.ScriptTarget.Latest }
266
+ );
267
+ if (!didInject) {
268
+ result.dispose();
269
+ return null;
270
+ }
271
+ const printer = ts2.createPrinter({ newLine: ts2.NewLineKind.LineFeed, removeComments: false });
272
+ const output = printer.printFile(result.transformed[0]);
273
+ result.dispose();
274
+ return output;
275
+ }
276
+
277
+ // ../vite-plugin/src/collect.ts
278
+ import ts3 from "typescript";
279
+ function extractBound(element) {
280
+ const obj = asObject(element);
281
+ if (!obj) return void 0;
282
+ const cardinalityNode = getProperty(obj, "cardinality");
283
+ const cardObj = asObject(cardinalityNode);
284
+ let cardinality;
285
+ if (cardObj) {
286
+ const minNode = getProperty(cardObj, "min");
287
+ const maxNode = getProperty(cardObj, "max");
288
+ const min = asPositiveInt(minNode) ?? 0;
289
+ const max = asPositiveInt(maxNode);
290
+ if (min === 0 && max === void 0) {
291
+ cardinality = { kind: "unbounded" };
292
+ } else {
293
+ cardinality = { kind: "bounded", min, max: max ?? Infinity };
294
+ }
295
+ } else {
296
+ cardinality = { kind: "unbounded" };
297
+ }
298
+ const positionNode = getProperty(obj, "position");
299
+ let position = "any";
300
+ if (positionNode && ts3.isStringLiteral(positionNode)) {
301
+ const p = positionNode.text;
302
+ if (p === "first" || p === "last" || p === "any") position = p;
303
+ }
304
+ return { cardinality, position };
305
+ }
306
+ function cardinalityMin(c) {
307
+ return c.kind === "bounded" ? c.min : 0;
308
+ }
309
+ function cardinalityMax(c) {
310
+ return c.kind === "bounded" ? c.max : Infinity;
311
+ }
312
+ function processVariableStatement(node, calleeNames, out) {
313
+ for (const decl of node.declarationList.declarations) {
314
+ if (!decl.initializer || !ts3.isCallExpression(decl.initializer)) continue;
315
+ if (!isFactoryCall(decl.initializer, calleeNames)) continue;
316
+ const arg = firstObjectArg(decl.initializer);
317
+ if (!arg) continue;
318
+ const tagNode = getProperty(arg, "tag");
319
+ const defaultTag = tagNode && ts3.isStringLiteral(tagNode) ? tagNode.text : void 0;
320
+ const enforcementProp = getProperty(arg, "enforcement");
321
+ const enfObj = asObject(enforcementProp);
322
+ const ariaNode = enfObj ? getProperty(enfObj, "aria") : void 0;
323
+ const ariaArr = asArray(ariaNode);
324
+ const hasAriaRules = ariaArr !== void 0 && ariaArr.elements.length > 0;
325
+ const childrenProp = enfObj ? getProperty(enfObj, "children") : void 0;
326
+ const childrenArr = asArray(childrenProp);
327
+ const rules = [];
328
+ if (childrenArr) {
329
+ for (const element of childrenArr.elements) {
330
+ const bound = extractBound(element);
331
+ if (bound) rules.push(bound);
332
+ }
333
+ }
334
+ if (rules.length === 0 && !hasAriaRules && !defaultTag) continue;
335
+ const totalMin = rules.reduce((s, r) => s + cardinalityMin(r.cardinality), 0);
336
+ const totalMax = rules.reduce(
337
+ (s, r) => s === Infinity ? Infinity : s + cardinalityMax(r.cardinality),
338
+ 0
339
+ );
340
+ const componentName = ts3.isIdentifier(decl.name) ? decl.name.text : void 0;
341
+ if (!componentName) continue;
342
+ out.push({
343
+ name: componentName,
344
+ rules,
345
+ totalMin,
346
+ totalMax,
347
+ ...defaultTag !== void 0 && { defaultTag },
348
+ hasAriaRules
349
+ });
350
+ }
351
+ }
352
+ function collectConstraints(source, calleeNames) {
353
+ const constraints = [];
354
+ walk(source, (node) => {
355
+ if (ts3.isVariableStatement(node)) processVariableStatement(node, calleeNames, constraints);
356
+ });
357
+ return constraints;
358
+ }
359
+ function collectFileDeclarations(source, calleeNames) {
360
+ const constraints = [];
361
+ const importSpecifiers = /* @__PURE__ */ new Map();
362
+ walk(source, (node) => {
363
+ if (ts3.isVariableStatement(node)) {
364
+ processVariableStatement(node, calleeNames, constraints);
365
+ } else if (ts3.isImportDeclaration(node)) {
366
+ const spec = node.moduleSpecifier;
367
+ if (!ts3.isStringLiteral(spec)) return;
368
+ const namedBindings = node.importClause?.namedBindings;
369
+ if (!namedBindings || !ts3.isNamedImports(namedBindings)) return;
370
+ for (const el of namedBindings.elements) importSpecifiers.set(el.name.text, spec.text);
371
+ }
372
+ });
373
+ return { constraints, importSpecifiers };
374
+ }
375
+
376
+ // ../vite-plugin/src/compound-prune.ts
377
+ import ts4 from "typescript";
378
+ function extractVariantMap2(stylingObj) {
379
+ const result = /* @__PURE__ */ new Map();
380
+ const variantsObj = asObject(getProperty(stylingObj, "variants"));
381
+ if (!variantsObj) return result;
382
+ for (const prop of variantsObj.properties) {
383
+ if (!ts4.isPropertyAssignment(prop)) continue;
384
+ const key = ts4.isIdentifier(prop.name) || ts4.isStringLiteral(prop.name) ? prop.name.text : void 0;
385
+ if (!key) continue;
386
+ const valuesObj = asObject(prop.initializer);
387
+ if (!valuesObj) continue;
388
+ const valid = /* @__PURE__ */ new Set();
389
+ for (const vp of valuesObj.properties) {
390
+ if (!ts4.isPropertyAssignment(vp)) continue;
391
+ const vk = ts4.isIdentifier(vp.name) || ts4.isStringLiteral(vp.name) ? vp.name.text : void 0;
392
+ if (vk) valid.add(vk);
393
+ }
394
+ result.set(key, valid);
395
+ }
396
+ return result;
397
+ }
398
+ function isDeadCompound(entry, variantMap) {
399
+ for (const prop of entry.properties) {
400
+ if (!ts4.isPropertyAssignment(prop)) continue;
401
+ const key = ts4.isIdentifier(prop.name) || ts4.isStringLiteral(prop.name) ? prop.name.text : void 0;
402
+ if (!key || key === "class") continue;
403
+ const validValues = variantMap.get(key);
404
+ if (!validValues) return true;
405
+ const val = prop.initializer;
406
+ if (ts4.isStringLiteral(val)) {
407
+ if (!validValues.has(val.text)) return true;
408
+ } else if (ts4.isArrayLiteralExpression(val)) {
409
+ const allLiterals = val.elements.every(ts4.isStringLiteral);
410
+ if (!allLiterals) continue;
411
+ const hasAnyValid = val.elements.some((e) => ts4.isStringLiteral(e) && validValues.has(e.text));
412
+ if (!hasAnyValid) return true;
413
+ }
414
+ }
415
+ return false;
416
+ }
417
+ function createCompoundPruner(factory, calleeNames, onPruned) {
418
+ return (context) => {
419
+ function visit(node) {
420
+ if (!ts4.isCallExpression(node)) return ts4.visitEachChild(node, visit, context);
421
+ if (!isFactoryCall(node, calleeNames)) return ts4.visitEachChild(node, visit, context);
422
+ const arg = firstObjectArg(node);
423
+ if (!arg) return node;
424
+ const stylingNode = getProperty(arg, "styling");
425
+ const stylingObj = asObject(stylingNode);
426
+ if (!stylingObj) return ts4.visitEachChild(node, visit, context);
427
+ const compoundsNode = getProperty(stylingObj, "compounds");
428
+ const compoundsArr = asArray(compoundsNode);
429
+ if (!compoundsArr || compoundsArr.elements.length === 0)
430
+ return ts4.visitEachChild(node, visit, context);
431
+ const variantMap = extractVariantMap2(stylingObj);
432
+ if (variantMap.size === 0) return ts4.visitEachChild(node, visit, context);
433
+ const liveEntries = compoundsArr.elements.filter((elem) => {
434
+ const obj = asObject(elem);
435
+ return !obj || !isDeadCompound(obj, variantMap);
436
+ });
437
+ if (liveEntries.length === compoundsArr.elements.length)
438
+ return ts4.visitEachChild(node, visit, context);
439
+ onPruned();
440
+ const newCompoundsArr = factory.createArrayLiteralExpression(liveEntries, true);
441
+ const newStylingProps = stylingObj.properties.map((p) => {
442
+ if (ts4.isPropertyAssignment(p) && (ts4.isIdentifier(p.name) || ts4.isStringLiteral(p.name)) && p.name.text === "compounds") {
443
+ return factory.createPropertyAssignment(p.name, newCompoundsArr);
444
+ }
445
+ return p;
446
+ });
447
+ const newStylingObj = factory.createObjectLiteralExpression(newStylingProps, true);
448
+ const newArgProps = arg.properties.map((p) => {
449
+ if (ts4.isPropertyAssignment(p) && (ts4.isIdentifier(p.name) || ts4.isStringLiteral(p.name)) && p.name.text === "styling") {
450
+ return factory.createPropertyAssignment(p.name, newStylingObj);
451
+ }
452
+ return p;
453
+ });
454
+ const newArg = factory.createObjectLiteralExpression(newArgProps, true);
455
+ return factory.createCallExpression(node.expression, node.typeArguments, [
456
+ newArg,
457
+ ...node.arguments.slice(1)
458
+ ]);
459
+ }
460
+ return (sourceFile) => ts4.visitEachChild(sourceFile, visit, context);
461
+ };
462
+ }
463
+ function pruneDeadCompounds(source, calleeNames) {
464
+ let hasCompounds = false;
465
+ walk(source, (n) => {
466
+ if (hasCompounds) return;
467
+ if (ts4.isPropertyAssignment(n)) {
468
+ const key = ts4.isIdentifier(n.name) || ts4.isStringLiteral(n.name) ? n.name.text : void 0;
469
+ if (key === "compounds") hasCompounds = true;
470
+ }
471
+ });
472
+ if (!hasCompounds) return null;
473
+ let didPrune = false;
474
+ const result = ts4.transform(
475
+ source,
476
+ [
477
+ createCompoundPruner(ts4.factory, calleeNames, () => {
478
+ didPrune = true;
479
+ })
480
+ ],
481
+ { target: ts4.ScriptTarget.Latest }
482
+ );
483
+ if (!didPrune) {
484
+ result.dispose();
485
+ return null;
486
+ }
487
+ const printer = ts4.createPrinter({ newLine: ts4.NewLineKind.LineFeed, removeComments: false });
488
+ const output = printer.printFile(result.transformed[0]);
489
+ result.dispose();
490
+ return output;
491
+ }
492
+
493
+ // ../vite-plugin/src/constants.ts
494
+ var DEFAULT_CALLEE_NAMES = ["createPolymorphicComponent", "createContractComponent"];
495
+ var JSX_EXTS = /* @__PURE__ */ new Set(["tsx", "jsx"]);
496
+ var ALL_EXTS = /* @__PURE__ */ new Set(["ts", "tsx", "js", "jsx"]);
497
+
498
+ // ../vite-plugin/src/diagnose.ts
499
+ import ts5 from "typescript";
500
+ function analyzeJsxSites(source, constraints, severity) {
501
+ const byName = new Map(constraints.filter((c) => c.rules.length > 0).map((c) => [c.name, c]));
502
+ const byNameAria = new Map(
503
+ constraints.filter((c) => c.hasAriaRules && c.defaultTag !== void 0).map((c) => [c.name, c])
504
+ );
505
+ const diagnostics = [];
506
+ const usages = [];
507
+ walk(source, (node) => {
508
+ let tagName;
509
+ let attributes;
510
+ let count;
511
+ if (ts5.isJsxElement(node)) {
512
+ const opening = node.openingElement;
513
+ tagName = ts5.isIdentifier(opening.tagName) ? opening.tagName.text : void 0;
514
+ attributes = opening.attributes;
515
+ count = countStaticChildren(node);
516
+ } else if (ts5.isJsxSelfClosingElement(node)) {
517
+ tagName = ts5.isIdentifier(node.tagName) ? node.tagName.text : void 0;
518
+ attributes = node.attributes;
519
+ count = 0;
520
+ }
521
+ if (!tagName) return;
522
+ let pos;
523
+ const getPos = () => pos ??= source.getLineAndCharacterOfPosition(node.getStart(source));
524
+ if (count !== void 0) {
525
+ const c = byName.get(tagName);
526
+ if (c && (count < c.totalMin || count > c.totalMax)) {
527
+ const { line, character } = getPos();
528
+ const { totalMin, totalMax, name } = c;
529
+ const rangeText = totalMax === Infinity ? `at least ${totalMin}` : totalMin === totalMax ? `exactly ${totalMin}` : `${totalMin}\u2013${totalMax}`;
530
+ diagnostics.push({
531
+ message: `<${name}> expects ${rangeText} ${totalMax === 1 && totalMin === 1 ? "child" : "children"} but received ${count}.`,
532
+ line: line + 1,
533
+ col: character + 1,
534
+ severity
535
+ });
536
+ }
537
+ }
538
+ if (attributes) {
539
+ const c = byNameAria.get(tagName);
540
+ if (c) {
541
+ for (const attr of attributes.properties) {
542
+ if (!ts5.isJsxAttribute(attr)) continue;
543
+ const attrName = ts5.isIdentifier(attr.name) ? attr.name.text : void 0;
544
+ if (attrName !== "as" || !attr.initializer) continue;
545
+ let asValue;
546
+ if (ts5.isStringLiteral(attr.initializer)) {
547
+ asValue = attr.initializer.text;
548
+ } else if (ts5.isJsxExpression(attr.initializer) && attr.initializer.expression !== void 0 && ts5.isStringLiteral(attr.initializer.expression)) {
549
+ asValue = attr.initializer.expression.text;
550
+ }
551
+ if (asValue !== void 0 && asValue !== c.defaultTag) {
552
+ const { line, character } = getPos();
553
+ diagnostics.push({
554
+ message: `<${tagName} as="${asValue}"> changes the element type from '${c.defaultTag}' \u2014 ARIA enforcement rules may not apply as expected.`,
555
+ line: line + 1,
556
+ col: character + 1,
557
+ severity
558
+ });
559
+ }
560
+ }
561
+ }
562
+ }
563
+ if (/^[A-Z]/.test(tagName)) {
564
+ const { line, character } = getPos();
565
+ usages.push({ tagName, count, line: line + 1, col: character + 1 });
566
+ }
567
+ });
568
+ return { diagnostics, usages };
569
+ }
570
+ function countStaticChildren(node) {
571
+ let count = 0;
572
+ for (const child of node.children) {
573
+ if (ts5.isJsxExpression(child)) return void 0;
574
+ if (ts5.isJsxText(child)) {
575
+ if (child.text.trim().length > 0) count++;
576
+ } else {
577
+ count++;
578
+ }
579
+ }
580
+ return count;
581
+ }
582
+ function diagnoseUsages(source, constraints, severity) {
583
+ if (constraints.length === 0) return [];
584
+ const byName = new Map(constraints.filter((c) => c.rules.length > 0).map((c) => [c.name, c]));
585
+ const diagnostics = [];
586
+ walk(source, (node) => {
587
+ let tagName;
588
+ let count;
589
+ if (ts5.isJsxElement(node)) {
590
+ const openTag = node.openingElement;
591
+ tagName = ts5.isIdentifier(openTag.tagName) ? openTag.tagName.text : void 0;
592
+ count = countStaticChildren(node);
593
+ } else if (ts5.isJsxSelfClosingElement(node)) {
594
+ tagName = ts5.isIdentifier(node.tagName) ? node.tagName.text : void 0;
595
+ count = 0;
596
+ }
597
+ if (!tagName) return;
598
+ const constraint = byName.get(tagName);
599
+ if (!constraint) return;
600
+ if (count === void 0) return;
601
+ const { totalMin, totalMax, name } = constraint;
602
+ if (count < totalMin || count > totalMax) {
603
+ const { line, character } = source.getLineAndCharacterOfPosition(node.getStart(source));
604
+ const rangeText = totalMax === Infinity ? `at least ${totalMin}` : totalMin === totalMax ? `exactly ${totalMin}` : `${totalMin}\u2013${totalMax}`;
605
+ diagnostics.push({
606
+ message: `<${name}> expects ${rangeText} ${totalMax === 1 && totalMin === 1 ? "child" : "children"} but received ${count}.`,
607
+ line: line + 1,
608
+ col: character + 1,
609
+ severity
610
+ });
611
+ }
612
+ });
613
+ return diagnostics;
614
+ }
615
+
616
+ // ../vite-plugin/src/registry.ts
617
+ var ConstraintRegistry = class {
618
+ constraints = /* @__PURE__ */ new Map();
619
+ importMap = /* @__PURE__ */ new Map();
620
+ pending = /* @__PURE__ */ new Map();
621
+ registerConstraints(fileId, cs) {
622
+ this.constraints.set(fileId, new Map(cs.map((c) => [c.name, c])));
623
+ }
624
+ /** resolvedImports: local name → absolute file ID of the exporting module. */
625
+ registerImports(fileId, resolvedImports) {
626
+ this.importMap.set(fileId, resolvedImports);
627
+ }
628
+ addPendingUsage(fileId, usage) {
629
+ let list = this.pending.get(fileId);
630
+ if (!list) {
631
+ list = [];
632
+ this.pending.set(fileId, list);
633
+ }
634
+ list.push(usage);
635
+ }
636
+ /** Resolves a component name used in `fileId` to its constraint definition. */
637
+ resolveConstraint(fileId, name) {
638
+ const imports = this.importMap.get(fileId);
639
+ if (!imports) return void 0;
640
+ const sourceId = imports.get(name);
641
+ if (!sourceId) return void 0;
642
+ return this.constraints.get(sourceId)?.get(name);
643
+ }
644
+ /** Returns cardinality violations across all pending cross-file usages. */
645
+ diagnostics(severity) {
646
+ const result = [];
647
+ for (const [fileId, usages] of this.pending) {
648
+ for (const usage of usages) {
649
+ if (usage.count === void 0) continue;
650
+ const constraint = this.resolveConstraint(fileId, usage.tagName);
651
+ if (!constraint) continue;
652
+ const { totalMin, totalMax, name } = constraint;
653
+ if (usage.count >= totalMin && usage.count <= totalMax) continue;
654
+ const rangeText = totalMax === Infinity ? `at least ${totalMin}` : totalMin === totalMax ? `exactly ${totalMin}` : `${totalMin}\u2013${totalMax}`;
655
+ const childWord = totalMax === 1 && totalMin === 1 ? "child" : "children";
656
+ result.push({
657
+ fileId,
658
+ message: `<${name}> expects ${rangeText} ${childWord} but received ${usage.count}.`,
659
+ line: usage.line,
660
+ col: usage.col,
661
+ severity
662
+ });
663
+ }
664
+ }
665
+ return result;
666
+ }
667
+ };
668
+
669
+ // ../vite-plugin/src/slot-transform.ts
670
+ import ts6 from "typescript";
671
+ function isUpperCase(s) {
672
+ return s.charCodeAt(0) >= 65 && s.charCodeAt(0) <= 90;
673
+ }
674
+ function jsxAttrName(attr) {
675
+ return ts6.isIdentifier(attr.name) ? attr.name.text : "";
676
+ }
677
+ function getStaticClassName(child) {
678
+ const attrs = ts6.isJsxElement(child) ? child.openingElement.attributes.properties : child.attributes.properties;
679
+ for (const attr of attrs) {
680
+ if (!ts6.isJsxAttribute(attr) || jsxAttrName(attr) !== "className") continue;
681
+ const init = attr.initializer;
682
+ if (!init) return { absent: false, value: "" };
683
+ if (ts6.isStringLiteral(init)) return { absent: false, value: init.text };
684
+ if (ts6.isJsxExpression(init) && init.expression !== void 0 && ts6.isStringLiteral(init.expression))
685
+ return { absent: false, value: init.expression.text };
686
+ return null;
687
+ }
688
+ return { absent: true };
689
+ }
690
+ function getStyleInfo(child) {
691
+ const attrs = ts6.isJsxElement(child) ? child.openingElement.attributes.properties : child.attributes.properties;
692
+ for (const attr of attrs) {
693
+ if (!ts6.isJsxAttribute(attr) || jsxAttrName(attr) !== "style") continue;
694
+ const init = attr.initializer;
695
+ if (!init || ts6.isStringLiteral(init)) return null;
696
+ if (ts6.isJsxExpression(init) && init.expression !== void 0)
697
+ return { absent: false, expr: init.expression };
698
+ return null;
699
+ }
700
+ return { absent: true };
701
+ }
702
+ function getEventHandlers(child) {
703
+ const attrs = ts6.isJsxElement(child) ? child.openingElement.attributes.properties : child.attributes.properties;
704
+ const handlers = [];
705
+ for (const attr of attrs) {
706
+ if (!ts6.isJsxAttribute(attr)) continue;
707
+ const name = jsxAttrName(attr);
708
+ if (!/^on[A-Z]/.test(name)) continue;
709
+ const init = attr.initializer;
710
+ if (!init) return null;
711
+ if (ts6.isJsxExpression(init) && init.expression !== void 0) {
712
+ handlers.push({ name, expr: init.expression });
713
+ continue;
714
+ }
715
+ return null;
716
+ }
717
+ return handlers;
718
+ }
719
+ function hasAsChild(opening) {
720
+ for (const attr of opening.attributes.properties) {
721
+ if (!ts6.isJsxAttribute(attr)) continue;
722
+ if (jsxAttrName(attr) !== "asChild") continue;
723
+ if (attr.initializer === void 0) return true;
724
+ if (ts6.isJsxExpression(attr.initializer) && attr.initializer.expression !== void 0 && attr.initializer.expression.kind === ts6.SyntaxKind.TrueKeyword)
725
+ return true;
726
+ }
727
+ return false;
728
+ }
729
+ function getSingleElementChild(node) {
730
+ const meaningful = [];
731
+ for (const child of node.children) {
732
+ if (ts6.isJsxText(child)) {
733
+ if (child.text.trim().length > 0) return void 0;
734
+ continue;
735
+ }
736
+ if (ts6.isJsxExpression(child)) return void 0;
737
+ if (ts6.isJsxElement(child) || ts6.isJsxSelfClosingElement(child)) {
738
+ meaningful.push(child);
739
+ continue;
740
+ }
741
+ return void 0;
742
+ }
743
+ return meaningful.length === 1 ? meaningful[0] : void 0;
744
+ }
745
+ function getTagName(child) {
746
+ const tag = ts6.isJsxElement(child) ? child.openingElement.tagName : child.tagName;
747
+ return ts6.isIdentifier(tag) ? tag.text : void 0;
748
+ }
749
+ function buildTransformedAttributes(factory, original, child, tagName, clsResult, styleInfo, handlers) {
750
+ const parentAttrs = original.attributes.properties.filter(
751
+ (attr) => !(ts6.isJsxAttribute(attr) && jsxAttrName(attr) === "asChild")
752
+ );
753
+ const hasStaticCls = !clsResult.absent;
754
+ const hasStyle = !styleInfo.absent;
755
+ const handlerNames = new Set(handlers.map((h) => h.name));
756
+ const childOpeningAttrs = (ts6.isJsxElement(child) ? child.openingElement.attributes.properties : child.attributes.properties).filter(
757
+ (attr) => !(ts6.isJsxAttribute(attr) && (jsxAttrName(attr) === "ref" || hasStaticCls && jsxAttrName(attr) === "className" || hasStyle && jsxAttrName(attr) === "style" || handlerNames.has(jsxAttrName(attr))))
758
+ );
759
+ const childContent = ts6.isJsxElement(child) ? child.children : void 0;
760
+ const spreadProp = factory.createJsxSpreadAttribute(factory.createIdentifier("_p"));
761
+ const extraAttrs = [];
762
+ if (hasStaticCls && clsResult.value !== "") {
763
+ const mergedExpr = factory.createBinaryExpression(
764
+ factory.createPropertyAccessExpression(factory.createIdentifier("_p"), "className"),
765
+ ts6.SyntaxKind.PlusToken,
766
+ factory.createStringLiteral(` ${clsResult.value}`)
767
+ );
768
+ extraAttrs.push(
769
+ factory.createJsxAttribute(
770
+ factory.createIdentifier("className"),
771
+ factory.createJsxExpression(void 0, mergedExpr)
772
+ )
773
+ );
774
+ }
775
+ if (hasStyle) {
776
+ const styleExpr = styleInfo.expr;
777
+ const pStyleSpread = factory.createSpreadAssignment(
778
+ factory.createPropertyAccessExpression(factory.createIdentifier("_p"), "style")
779
+ );
780
+ let mergedStyleObj;
781
+ if (ts6.isObjectLiteralExpression(styleExpr)) {
782
+ mergedStyleObj = factory.createObjectLiteralExpression(
783
+ [pStyleSpread, ...styleExpr.properties],
784
+ false
785
+ );
786
+ } else {
787
+ mergedStyleObj = factory.createObjectLiteralExpression(
788
+ [pStyleSpread, factory.createSpreadAssignment(styleExpr)],
789
+ false
790
+ );
791
+ }
792
+ extraAttrs.push(
793
+ factory.createJsxAttribute(
794
+ factory.createIdentifier("style"),
795
+ factory.createJsxExpression(void 0, mergedStyleObj)
796
+ )
797
+ );
798
+ }
799
+ for (const { name, expr } of handlers) {
800
+ const eParam = factory.createParameterDeclaration(void 0, void 0, "_e");
801
+ const callChild = factory.createExpressionStatement(
802
+ factory.createCallExpression(factory.createParenthesizedExpression(expr), void 0, [
803
+ factory.createIdentifier("_e")
804
+ ])
805
+ );
806
+ const callParent = factory.createExpressionStatement(
807
+ factory.createCallChain(
808
+ factory.createPropertyAccessExpression(factory.createIdentifier("_p"), name),
809
+ factory.createToken(ts6.SyntaxKind.QuestionDotToken),
810
+ void 0,
811
+ [factory.createIdentifier("_e")]
812
+ )
813
+ );
814
+ const composedFn = factory.createArrowFunction(
815
+ void 0,
816
+ void 0,
817
+ [eParam],
818
+ void 0,
819
+ factory.createToken(ts6.SyntaxKind.EqualsGreaterThanToken),
820
+ factory.createBlock([callChild, callParent], true)
821
+ );
822
+ extraAttrs.push(
823
+ factory.createJsxAttribute(
824
+ factory.createIdentifier(name),
825
+ factory.createJsxExpression(void 0, composedFn)
826
+ )
827
+ );
828
+ }
829
+ const childAttrsWithSpread = factory.createJsxAttributes([
830
+ ...childOpeningAttrs,
831
+ spreadProp,
832
+ ...extraAttrs
833
+ ]);
834
+ const childElement = ts6.isJsxElement(child) ? factory.createJsxElement(
835
+ factory.createJsxOpeningElement(
836
+ factory.createIdentifier(tagName),
837
+ void 0,
838
+ childAttrsWithSpread
839
+ ),
840
+ childContent ?? [],
841
+ factory.createJsxClosingElement(factory.createIdentifier(tagName))
842
+ ) : factory.createJsxSelfClosingElement(
843
+ factory.createIdentifier(tagName),
844
+ void 0,
845
+ childAttrsWithSpread
846
+ );
847
+ const renderArrow = factory.createArrowFunction(
848
+ void 0,
849
+ void 0,
850
+ [factory.createParameterDeclaration(void 0, void 0, "_p")],
851
+ void 0,
852
+ factory.createToken(ts6.SyntaxKind.EqualsGreaterThanToken),
853
+ factory.createParenthesizedExpression(childElement)
854
+ );
855
+ const renderAttr = factory.createJsxAttribute(
856
+ factory.createIdentifier("render"),
857
+ factory.createJsxExpression(void 0, renderArrow)
858
+ );
859
+ return factory.createJsxAttributes([renderAttr, ...parentAttrs]);
860
+ }
861
+ function createAsChildTransformer(factory) {
862
+ return (context) => {
863
+ function visit(node) {
864
+ if (!ts6.isJsxElement(node)) return ts6.visitEachChild(node, visit, context);
865
+ const opening = node.openingElement;
866
+ const tagName = ts6.isIdentifier(opening.tagName) ? opening.tagName.text : void 0;
867
+ if (!tagName || !isUpperCase(tagName)) {
868
+ return ts6.visitEachChild(node, visit, context);
869
+ }
870
+ if (!hasAsChild(opening)) return ts6.visitEachChild(node, visit, context);
871
+ const child = getSingleElementChild(node);
872
+ if (!child) return ts6.visitEachChild(node, visit, context);
873
+ const clsResult = getStaticClassName(child);
874
+ if (clsResult === null) return ts6.visitEachChild(node, visit, context);
875
+ const styleInfo = getStyleInfo(child);
876
+ if (styleInfo === null) return ts6.visitEachChild(node, visit, context);
877
+ const handlers = getEventHandlers(child);
878
+ if (handlers === null) return ts6.visitEachChild(node, visit, context);
879
+ const childTag = getTagName(child);
880
+ if (!childTag) return ts6.visitEachChild(node, visit, context);
881
+ const newAttrs = buildTransformedAttributes(
882
+ factory,
883
+ opening,
884
+ child,
885
+ childTag,
886
+ clsResult,
887
+ styleInfo,
888
+ handlers
889
+ );
890
+ return factory.createJsxSelfClosingElement(opening.tagName, opening.typeArguments, newAttrs);
891
+ }
892
+ return (sourceFile) => ts6.visitEachChild(sourceFile, visit, context);
893
+ };
894
+ }
895
+ function transformAsChild(source) {
896
+ let hasAny = false;
897
+ walk(source, (n) => {
898
+ if (hasAny) return;
899
+ if (ts6.isJsxAttribute(n) && jsxAttrName(n) === "asChild") hasAny = true;
900
+ });
901
+ if (!hasAny) return null;
902
+ const result = ts6.transform(source, [createAsChildTransformer(ts6.factory)], {
903
+ jsx: ts6.JsxEmit.Preserve,
904
+ target: ts6.ScriptTarget.Latest
905
+ });
906
+ const printer = ts6.createPrinter({ newLine: ts6.NewLineKind.LineFeed, removeComments: false });
907
+ const output = printer.printFile(result.transformed[0]);
908
+ result.dispose();
909
+ return output;
910
+ }
911
+
912
+ // ../vite-plugin/src/static-compose.ts
913
+ import ts7 from "typescript";
914
+ function asStringLiteral(node) {
915
+ return node !== void 0 && ts7.isStringLiteral(node) ? node.text : void 0;
916
+ }
917
+ function extractStaticComponents(source, calleeNames) {
918
+ const result = /* @__PURE__ */ new Map();
919
+ walk(source, (node) => {
920
+ if (!ts7.isVariableDeclaration(node)) return;
921
+ if (!ts7.isIdentifier(node.name)) return;
922
+ const varName = node.name.text;
923
+ const init = node.initializer;
924
+ if (!init) return;
925
+ let call;
926
+ if (ts7.isCallExpression(init) && isFactoryCall(init, calleeNames)) {
927
+ call = init;
928
+ } else if (ts7.isAsExpression(init) && ts7.isCallExpression(init.expression) && isFactoryCall(init.expression, calleeNames)) {
929
+ call = init.expression;
930
+ }
931
+ if (!call) return;
932
+ const arg = firstObjectArg(call);
933
+ if (!arg) return;
934
+ const defaultTag = asStringLiteral(getProperty(arg, "tag"));
935
+ if (!defaultTag) return;
936
+ const stylingObj = asObject(getProperty(arg, "styling"));
937
+ if (!stylingObj) return;
938
+ const precomputedNode = asObject(getProperty(stylingObj, "precomputedClasses"));
939
+ if (!precomputedNode) return;
940
+ const precomputedClasses = {};
941
+ for (const prop of precomputedNode.properties) {
942
+ if (!ts7.isPropertyAssignment(prop)) return;
943
+ const key = ts7.isStringLiteral(prop.name) ? prop.name.text : void 0;
944
+ const val = asStringLiteral(prop.initializer);
945
+ if (key === void 0 || val === void 0) return;
946
+ precomputedClasses[key] = val;
947
+ }
948
+ if (getProperty(arg, "defaults") !== void 0) return;
949
+ if (getProperty(arg, "enforcement") !== void 0) return;
950
+ const variantKeys = /* @__PURE__ */ new Set();
951
+ const variantsObj = asObject(getProperty(stylingObj, "variants"));
952
+ if (variantsObj) {
953
+ for (const prop of variantsObj.properties) {
954
+ if (ts7.isPropertyAssignment(prop) && (ts7.isIdentifier(prop.name) || ts7.isStringLiteral(prop.name))) {
955
+ variantKeys.add(prop.name.text);
956
+ }
957
+ }
958
+ }
959
+ result.set(varName, { defaultTag, variantKeys, precomputedClasses });
960
+ });
961
+ return result;
962
+ }
963
+ function readAttrValue(attrs, name) {
964
+ for (const attr of attrs) {
965
+ if (!ts7.isJsxAttribute(attr)) continue;
966
+ if (!(ts7.isIdentifier(attr.name) && attr.name.text === name)) continue;
967
+ const init = attr.initializer;
968
+ if (!init) return { kind: "string", value: "" };
969
+ if (ts7.isStringLiteral(init)) return { kind: "string", value: init.text };
970
+ if (ts7.isJsxExpression(init) && init.expression !== void 0) {
971
+ if (ts7.isStringLiteral(init.expression))
972
+ return { kind: "string", value: init.expression.text };
973
+ return { kind: "dynamic" };
974
+ }
975
+ return { kind: "dynamic" };
976
+ }
977
+ return { kind: "absent" };
978
+ }
979
+ function createStaticCompositionTransformer(factory, components, onInlined) {
980
+ return (context) => {
981
+ function visit(node) {
982
+ const isSelfClose = ts7.isJsxSelfClosingElement(node);
983
+ const isOpen = ts7.isJsxElement(node);
984
+ if (!isSelfClose && !isOpen) return ts7.visitEachChild(node, visit, context);
985
+ const tagNode = isOpen ? node.openingElement.tagName : node.tagName;
986
+ if (!ts7.isIdentifier(tagNode)) return ts7.visitEachChild(node, visit, context);
987
+ const info = components.get(tagNode.text);
988
+ if (!info) return ts7.visitEachChild(node, visit, context);
989
+ const attrList = isOpen ? node.openingElement.attributes.properties : node.attributes.properties;
990
+ if (attrList.some(ts7.isJsxSpreadAttribute)) return ts7.visitEachChild(node, visit, context);
991
+ if (readAttrValue(attrList, "asChild").kind !== "absent")
992
+ return ts7.visitEachChild(node, visit, context);
993
+ if (readAttrValue(attrList, "render").kind !== "absent")
994
+ return ts7.visitEachChild(node, visit, context);
995
+ const asVal = readAttrValue(attrList, "as");
996
+ if (asVal.kind === "dynamic") return ts7.visitEachChild(node, visit, context);
997
+ const outputTag = asVal.kind === "string" ? asVal.value : info.defaultTag;
998
+ const variantProps = {};
999
+ for (const propName of info.variantKeys) {
1000
+ const val = readAttrValue(attrList, propName);
1001
+ if (val.kind === "absent") continue;
1002
+ if (val.kind === "string") {
1003
+ variantProps[propName] = val.value;
1004
+ continue;
1005
+ }
1006
+ return ts7.visitEachChild(node, visit, context);
1007
+ }
1008
+ const cacheKey = buildCacheKey(variantProps);
1009
+ const baseClass = info.precomputedClasses[cacheKey];
1010
+ if (baseClass === void 0) return ts7.visitEachChild(node, visit, context);
1011
+ const clsVal = readAttrValue(attrList, "className");
1012
+ if (clsVal.kind === "dynamic") return ts7.visitEachChild(node, visit, context);
1013
+ const finalClass = clsVal.kind === "string" && clsVal.value ? `${baseClass} ${clsVal.value}` : baseClass;
1014
+ const strip = /* @__PURE__ */ new Set([...info.variantKeys, "as", "asChild", "render", "className"]);
1015
+ const outputAttrs = [
1016
+ factory.createJsxAttribute(
1017
+ factory.createIdentifier("className"),
1018
+ factory.createStringLiteral(finalClass)
1019
+ )
1020
+ ];
1021
+ for (const attr of attrList) {
1022
+ if (ts7.isJsxSpreadAttribute(attr)) continue;
1023
+ if (!ts7.isJsxAttribute(attr)) continue;
1024
+ const name = ts7.isIdentifier(attr.name) ? attr.name.text : "";
1025
+ if (strip.has(name)) continue;
1026
+ outputAttrs.push(attr);
1027
+ }
1028
+ const newAttrs = factory.createJsxAttributes(outputAttrs);
1029
+ const outputTagIdent = factory.createIdentifier(outputTag);
1030
+ onInlined();
1031
+ if (isSelfClose) {
1032
+ return factory.createJsxSelfClosingElement(outputTagIdent, void 0, newAttrs);
1033
+ }
1034
+ const openNode = node;
1035
+ const visitedChildren = openNode.children.map((c) => ts7.visitNode(c, visit));
1036
+ return factory.createJsxElement(
1037
+ factory.createJsxOpeningElement(outputTagIdent, void 0, newAttrs),
1038
+ visitedChildren,
1039
+ factory.createJsxClosingElement(outputTagIdent)
1040
+ );
1041
+ }
1042
+ return (sourceFile) => ts7.visitEachChild(sourceFile, visit, context);
1043
+ };
1044
+ }
1045
+ function composeStatically(source, calleeNames) {
1046
+ const components = extractStaticComponents(source, calleeNames);
1047
+ if (components.size === 0) return null;
1048
+ const componentNames = new Set(components.keys());
1049
+ let hasEligibleTag = false;
1050
+ walk(source, (n) => {
1051
+ if (hasEligibleTag) return;
1052
+ const tagNode = ts7.isJsxElement(n) ? n.openingElement.tagName : ts7.isJsxSelfClosingElement(n) ? n.tagName : void 0;
1053
+ if (tagNode && ts7.isIdentifier(tagNode) && componentNames.has(tagNode.text))
1054
+ hasEligibleTag = true;
1055
+ });
1056
+ if (!hasEligibleTag) return null;
1057
+ let didInline = false;
1058
+ const transformResult = ts7.transform(
1059
+ source,
1060
+ [
1061
+ createStaticCompositionTransformer(ts7.factory, components, () => {
1062
+ didInline = true;
1063
+ })
1064
+ ],
1065
+ { jsx: ts7.JsxEmit.Preserve, target: ts7.ScriptTarget.Latest }
1066
+ );
1067
+ if (!didInline) {
1068
+ transformResult.dispose();
1069
+ return null;
1070
+ }
1071
+ const printer = ts7.createPrinter({ newLine: ts7.NewLineKind.LineFeed, removeComments: false });
1072
+ const output = printer.printFile(transformResult.transformed[0]);
1073
+ transformResult.dispose();
1074
+ return output;
1075
+ }
1076
+
1077
+ // ../vite-plugin/src/analyze.ts
1078
+ function analyze(code, filename, options) {
1079
+ const ext = filename.split(".").pop() ?? "";
1080
+ if (!JSX_EXTS.has(ext)) return [];
1081
+ const calleeNames = new Set(options?.calleeNames ?? DEFAULT_CALLEE_NAMES);
1082
+ const severity = options?.severity ?? "warning";
1083
+ const source = parseSource(filename, code);
1084
+ const constraints = collectConstraints(source, calleeNames);
1085
+ return diagnoseUsages(source, constraints, severity);
1086
+ }
1087
+
1088
+ // ../vite-plugin/src/design-tokens.ts
1089
+ import { writeFileSync } from "fs";
1090
+ import { resolve } from "path";
1091
+ import ts8 from "typescript";
1092
+ function collectStringValues(node, out) {
1093
+ if (!node) return;
1094
+ if (ts8.isStringLiteral(node)) {
1095
+ if (node.text.trim()) out.push(node.text);
1096
+ return;
1097
+ }
1098
+ if (ts8.isArrayLiteralExpression(node)) {
1099
+ for (const elem of node.elements) collectStringValues(elem, out);
1100
+ }
1101
+ }
1102
+ function extractStylingTokens(stylingObj) {
1103
+ const base = [];
1104
+ const variantClasses = [];
1105
+ const compoundClasses = [];
1106
+ const tagClasses = [];
1107
+ collectStringValues(getProperty(stylingObj, "base"), base);
1108
+ const variantsObj = asObject(getProperty(stylingObj, "variants"));
1109
+ if (variantsObj) {
1110
+ for (const dimProp of variantsObj.properties) {
1111
+ if (!ts8.isPropertyAssignment(dimProp)) continue;
1112
+ const valuesObj = asObject(dimProp.initializer);
1113
+ if (!valuesObj) continue;
1114
+ for (const vp of valuesObj.properties) {
1115
+ if (!ts8.isPropertyAssignment(vp)) continue;
1116
+ collectStringValues(vp.initializer, variantClasses);
1117
+ }
1118
+ }
1119
+ }
1120
+ const compoundsArr = asArray(getProperty(stylingObj, "compounds"));
1121
+ if (compoundsArr) {
1122
+ for (const elem of compoundsArr.elements) {
1123
+ const obj = asObject(elem);
1124
+ if (!obj) continue;
1125
+ collectStringValues(getProperty(obj, "class"), compoundClasses);
1126
+ }
1127
+ }
1128
+ const tagsObj = asObject(getProperty(stylingObj, "tags"));
1129
+ if (tagsObj) {
1130
+ for (const tp of tagsObj.properties) {
1131
+ if (!ts8.isPropertyAssignment(tp)) continue;
1132
+ collectStringValues(tp.initializer, tagClasses);
1133
+ }
1134
+ }
1135
+ return { base, variantClasses, compoundClasses, tagClasses };
1136
+ }
1137
+ function collectFileTokens(source, calleeNames) {
1138
+ const result = /* @__PURE__ */ new Map();
1139
+ ts8.forEachChild(source, (stmt) => {
1140
+ if (!ts8.isVariableStatement(stmt)) return;
1141
+ for (const decl of stmt.declarationList.declarations) {
1142
+ if (!decl.initializer || !ts8.isCallExpression(decl.initializer)) continue;
1143
+ if (!isFactoryCall(decl.initializer, calleeNames)) continue;
1144
+ const arg = firstObjectArg(decl.initializer);
1145
+ if (!arg) continue;
1146
+ const stylingNode = getProperty(arg, "styling");
1147
+ const stylingObj = asObject(stylingNode);
1148
+ if (!stylingObj) continue;
1149
+ const name = ts8.isIdentifier(decl.name) ? decl.name.text : void 0;
1150
+ if (!name) continue;
1151
+ result.set(name, extractStylingTokens(stylingObj));
1152
+ }
1153
+ });
1154
+ return result;
1155
+ }
1156
+ function mergeTokens(existing, incoming) {
1157
+ if (!existing) return incoming;
1158
+ return {
1159
+ base: [.../* @__PURE__ */ new Set([...existing.base, ...incoming.base])],
1160
+ variantClasses: [.../* @__PURE__ */ new Set([...existing.variantClasses, ...incoming.variantClasses])],
1161
+ compoundClasses: [.../* @__PURE__ */ new Set([...existing.compoundClasses, ...incoming.compoundClasses])],
1162
+ tagClasses: [.../* @__PURE__ */ new Set([...existing.tagClasses, ...incoming.tagClasses])]
1163
+ };
1164
+ }
1165
+ function buildManifest(allTokens) {
1166
+ const components = {};
1167
+ const seen = /* @__PURE__ */ new Set();
1168
+ for (const [name, tokens] of allTokens) {
1169
+ components[name] = tokens;
1170
+ for (const cls of [
1171
+ ...tokens.base,
1172
+ ...tokens.variantClasses,
1173
+ ...tokens.compoundClasses,
1174
+ ...tokens.tagClasses
1175
+ ]) {
1176
+ for (const part of cls.split(/\s+/)) {
1177
+ if (part) seen.add(part);
1178
+ }
1179
+ }
1180
+ }
1181
+ return {
1182
+ components,
1183
+ allClasses: [...seen].sort()
1184
+ };
1185
+ }
1186
+ function designTokensPlugin(options) {
1187
+ const calleeNames = new Set(options?.calleeNames ?? DEFAULT_CALLEE_NAMES);
1188
+ const outFile = options?.outFile ?? "praxis-tokens.json";
1189
+ const accumulated = /* @__PURE__ */ new Map();
1190
+ return {
1191
+ name: "praxis-kit:design-tokens",
1192
+ transform(code, id) {
1193
+ const ext = id.split(".").pop() ?? "";
1194
+ if (!ALL_EXTS.has(ext)) return null;
1195
+ const source = parseSource(id, code);
1196
+ for (const [name, tokens] of collectFileTokens(source, calleeNames)) {
1197
+ accumulated.set(name, mergeTokens(accumulated.get(name), tokens));
1198
+ }
1199
+ return null;
1200
+ },
1201
+ writeBundle() {
1202
+ if (accumulated.size === 0) return;
1203
+ const manifest = buildManifest(accumulated);
1204
+ const root = this.config?.root ?? process.cwd();
1205
+ writeFileSync(resolve(root, outFile), JSON.stringify(manifest, null, 2));
1206
+ }
1207
+ };
1208
+ }
1209
+
1210
+ // ../vite-plugin/src/index.ts
1211
+ function contractPlugin(options) {
1212
+ const registry = new ConstraintRegistry();
1213
+ const calleeNames = new Set(options?.calleeNames ?? DEFAULT_CALLEE_NAMES);
1214
+ const severity = options?.severity ?? "warning";
1215
+ return {
1216
+ name: "praxis-kit:contract",
1217
+ async transform(code, id) {
1218
+ const ext = id.split(".").pop() ?? "";
1219
+ if (!JSX_EXTS.has(ext)) return null;
1220
+ const source = parseSource(id, code);
1221
+ const { constraints, importSpecifiers } = collectFileDeclarations(source, calleeNames);
1222
+ registry.registerConstraints(id, constraints);
1223
+ const { diagnostics, usages: allUsages } = analyzeJsxSites(source, constraints, severity);
1224
+ for (const d of diagnostics) {
1225
+ const loc = { file: id, line: d.line, column: d.col };
1226
+ if (d.severity === "error") {
1227
+ this.error({ message: d.message, loc });
1228
+ } else {
1229
+ this.warn({ message: d.message, loc });
1230
+ }
1231
+ }
1232
+ const localNames = new Set(constraints.map((c) => c.name));
1233
+ const importedTagsInUse = new Set(
1234
+ allUsages.filter((u) => !localNames.has(u.tagName) && importSpecifiers.has(u.tagName)).map((u) => u.tagName)
1235
+ );
1236
+ if (importedTagsInUse.size > 0) {
1237
+ const resolvedImports = /* @__PURE__ */ new Map();
1238
+ for (const [name, specifier] of importSpecifiers) {
1239
+ if (!importedTagsInUse.has(name)) continue;
1240
+ const resolved = await this.resolve(specifier, id);
1241
+ if (resolved) resolvedImports.set(name, resolved.id);
1242
+ }
1243
+ registry.registerImports(id, resolvedImports);
1244
+ for (const usage of allUsages) {
1245
+ if (importedTagsInUse.has(usage.tagName)) {
1246
+ registry.addPendingUsage(id, usage);
1247
+ }
1248
+ }
1249
+ }
1250
+ },
1251
+ buildEnd() {
1252
+ for (const d of registry.diagnostics(severity)) {
1253
+ const loc = { file: d.fileId, line: d.line, column: d.col };
1254
+ if (d.severity === "error") {
1255
+ this.error({ message: d.message, loc });
1256
+ } else {
1257
+ this.warn({ message: d.message, loc });
1258
+ }
1259
+ }
1260
+ }
1261
+ };
1262
+ }
1263
+ function compoundPrunePlugin(options) {
1264
+ const calleeNames = new Set(options?.calleeNames ?? DEFAULT_CALLEE_NAMES);
1265
+ return {
1266
+ name: "praxis-kit:compound-prune",
1267
+ transform(code, id) {
1268
+ const ext = id.split(".").pop() ?? "";
1269
+ if (!ALL_EXTS.has(ext)) return null;
1270
+ const result = pruneDeadCompounds(parseSource(id, code), calleeNames);
1271
+ return result !== null ? { code: result } : null;
1272
+ }
1273
+ };
1274
+ }
1275
+ function classExtractPlugin(options) {
1276
+ const calleeNames = new Set(options?.calleeNames ?? DEFAULT_CALLEE_NAMES);
1277
+ return {
1278
+ name: "praxis-kit:class-extract",
1279
+ transform(code, id) {
1280
+ const ext = id.split(".").pop() ?? "";
1281
+ if (!ALL_EXTS.has(ext)) return null;
1282
+ const result = injectPrecomputedClasses(parseSource(id, code), calleeNames);
1283
+ return result !== null ? { code: result } : null;
1284
+ }
1285
+ };
1286
+ }
1287
+ function slotTransformPlugin() {
1288
+ return {
1289
+ name: "praxis-kit:slot-transform",
1290
+ transform(code, id) {
1291
+ const ext = id.split(".").pop() ?? "";
1292
+ if (!JSX_EXTS.has(ext)) return null;
1293
+ const result = transformAsChild(parseSource(id, code));
1294
+ return result !== null ? { code: result } : null;
1295
+ }
1296
+ };
1297
+ }
1298
+ function staticCompositionPlugin(options) {
1299
+ const calleeNames = new Set(options?.calleeNames ?? DEFAULT_CALLEE_NAMES);
1300
+ return {
1301
+ name: "praxis-kit:static-compose",
1302
+ transform(code, id) {
1303
+ const ext = id.split(".").pop() ?? "";
1304
+ if (!JSX_EXTS.has(ext)) return null;
1305
+ const result = composeStatically(parseSource(id, code), calleeNames);
1306
+ return result !== null ? { code: result } : null;
1307
+ }
1308
+ };
1309
+ }
1310
+ function ssrOptimizePlugin(options) {
1311
+ return [slotTransformPlugin(), classExtractPlugin(options), staticCompositionPlugin(options)];
1312
+ }
1313
+ export {
1314
+ analyze,
1315
+ buildManifest,
1316
+ buildPrecomputedClasses,
1317
+ classExtractPlugin,
1318
+ collectFileTokens,
1319
+ composeStatically,
1320
+ compoundPrunePlugin,
1321
+ contractPlugin,
1322
+ designTokensPlugin,
1323
+ injectPrecomputedClasses,
1324
+ pruneDeadCompounds,
1325
+ slotTransformPlugin,
1326
+ ssrOptimizePlugin,
1327
+ staticCompositionPlugin,
1328
+ transformAsChild
1329
+ };