dispersa 0.4.3 → 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.
Files changed (58) hide show
  1. package/README.md +65 -30
  2. package/dist/android-CRDfSB3_.d.cts +126 -0
  3. package/dist/android-DANJjjPO.d.ts +126 -0
  4. package/dist/builders.cjs +206 -62
  5. package/dist/builders.cjs.map +1 -1
  6. package/dist/builders.d.cts +12 -11
  7. package/dist/builders.d.ts +12 -11
  8. package/dist/builders.js +206 -62
  9. package/dist/builders.js.map +1 -1
  10. package/dist/cli/cli.js +120 -7
  11. package/dist/cli/cli.js.map +1 -1
  12. package/dist/cli/config.d.ts +321 -0
  13. package/dist/cli/config.js.map +1 -1
  14. package/dist/cli/index.js +119 -7
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/dispersa-BC1kDF5u.d.ts +118 -0
  17. package/dist/dispersa-DL3J_Pmz.d.cts +118 -0
  18. package/dist/errors-qT4sJgSA.d.cts +104 -0
  19. package/dist/errors-qT4sJgSA.d.ts +104 -0
  20. package/dist/errors.cjs.map +1 -1
  21. package/dist/errors.d.cts +1 -83
  22. package/dist/errors.d.ts +1 -83
  23. package/dist/errors.js.map +1 -1
  24. package/dist/filters.cjs.map +1 -1
  25. package/dist/filters.d.cts +2 -2
  26. package/dist/filters.d.ts +2 -2
  27. package/dist/filters.js.map +1 -1
  28. package/dist/{index-CNT2Meyf.d.cts → index-Dajm5rvM.d.ts} +311 -132
  29. package/dist/{index-CqdaN3X0.d.ts → index-De6SjZYH.d.cts} +311 -132
  30. package/dist/index.cjs +799 -353
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +8 -329
  33. package/dist/index.d.ts +8 -329
  34. package/dist/index.js +793 -353
  35. package/dist/index.js.map +1 -1
  36. package/dist/lint.cjs +1029 -0
  37. package/dist/lint.cjs.map +1 -0
  38. package/dist/lint.d.cts +463 -0
  39. package/dist/lint.d.ts +463 -0
  40. package/dist/lint.js +1009 -0
  41. package/dist/lint.js.map +1 -0
  42. package/dist/preprocessors.d.cts +2 -2
  43. package/dist/preprocessors.d.ts +2 -2
  44. package/dist/renderers.cjs.map +1 -1
  45. package/dist/renderers.d.cts +7 -6
  46. package/dist/renderers.d.ts +7 -6
  47. package/dist/renderers.js.map +1 -1
  48. package/dist/transforms.d.cts +2 -2
  49. package/dist/transforms.d.ts +2 -2
  50. package/dist/{types-CZb19kiq.d.ts → types-8MLtztK3.d.ts} +56 -1
  51. package/dist/{types-CussyWwe.d.cts → types-BHBHRm0a.d.cts} +56 -1
  52. package/dist/{types-BAv39mum.d.cts → types-BltzwVYK.d.cts} +1 -1
  53. package/dist/{types-DWKq-eJj.d.cts → types-CAdUV-fa.d.cts} +1 -1
  54. package/dist/{types-CzHa7YkW.d.ts → types-DztXKlka.d.ts} +1 -1
  55. package/dist/{types-Bc0kA7De.d.ts → types-TQHV1MrY.d.cts} +19 -1
  56. package/dist/{types-Bc0kA7De.d.cts → types-TQHV1MrY.d.ts} +19 -1
  57. package/dist/{types-BzNcG-rI.d.ts → types-ebxDimRz.d.ts} +1 -1
  58. package/package.json +19 -9
@@ -1,8 +1,9 @@
1
- import { F as FileFunction, L as LifecycleHooks, C as CssRendererOptions, O as OutputConfig, T as TailwindRendererOptions, I as IosRendererOptions, A as AndroidRendererOptions } from './index-CNT2Meyf.cjs';
2
- import { F as Filter } from './types-DWKq-eJj.cjs';
3
- import { T as Transform } from './types-BAv39mum.cjs';
4
- import { a as JsonRendererOptions, J as JsModuleRendererOptions } from './types-CussyWwe.cjs';
5
- import './types-Bc0kA7De.cjs';
1
+ import { F as FileFunction, L as LifecycleHooks, C as CssRendererOptions, O as OutputConfig } from './index-De6SjZYH.cjs';
2
+ import { F as Filter } from './types-CAdUV-fa.cjs';
3
+ import { T as Transform } from './types-BltzwVYK.cjs';
4
+ import { a as JsonRendererOptions, J as JsModuleRendererOptions } from './types-BHBHRm0a.cjs';
5
+ import { T as TailwindRendererOptions, I as IosRendererOptions, A as AndroidRendererOptions } from './android-CRDfSB3_.cjs';
6
+ import './types-TQHV1MrY.cjs';
6
7
  import 'json-schema-to-ts';
7
8
 
8
9
  /**
@@ -52,7 +53,7 @@ type CssBuilderConfig = BuilderConfigBase & CssRendererOptions;
52
53
  *
53
54
  * The `file` property is optional. When omitted, content is returned in-memory instead
54
55
  * of being written to disk. The `file` property is required when `buildPath` is provided
55
- * to `dispersa.build()`.
56
+ * to `build()`.
56
57
  *
57
58
  * @example Basic CSS bundle with transforms
58
59
  * ```typescript
@@ -93,7 +94,7 @@ type CssBuilderConfig = BuilderConfigBase & CssRendererOptions;
93
94
  * selector: ':root'
94
95
  * })
95
96
  * // Use without buildPath to get content in-memory
96
- * const result = await dispersa.build({ outputs: [config] })
97
+ * const result = await build({ outputs: [config] })
97
98
  * console.log(result.outputs[0].content)
98
99
  * ```
99
100
  */
@@ -118,7 +119,7 @@ type JsonBuilderConfig = BuilderConfigBase & JsonRendererOptions;
118
119
  *
119
120
  * The `file` property is optional. When omitted, content is returned in-memory instead
120
121
  * of being written to disk. The `file` property is required when `buildPath` is provided
121
- * to `dispersa.build()`.
122
+ * to `build()`.
122
123
  *
123
124
  * @example Standalone JSON with flat structure
124
125
  * ```typescript
@@ -155,7 +156,7 @@ type JsonBuilderConfig = BuilderConfigBase & JsonRendererOptions;
155
156
  * structure: 'flat'
156
157
  * })
157
158
  * // Use without buildPath to get content in-memory
158
- * const result = await dispersa.build({ outputs: [config] })
159
+ * const result = await build({ outputs: [config] })
159
160
  * console.log(result.outputs[0].content)
160
161
  * ```
161
162
  */
@@ -181,7 +182,7 @@ type JsBuilderConfig = BuilderConfigBase & JsModuleRendererOptions;
181
182
  *
182
183
  * The `file` property is optional. When omitted, content is returned in-memory instead
183
184
  * of being written to disk. The `file` property is required when `buildPath` is provided
184
- * to `dispersa.build()`.
185
+ * to `build()`.
185
186
  *
186
187
  * @example Bundle JS with helper function
187
188
  * ```typescript
@@ -220,7 +221,7 @@ type JsBuilderConfig = BuilderConfigBase & JsModuleRendererOptions;
220
221
  * structure: 'flat'
221
222
  * })
222
223
  * // Use without buildPath to get content in-memory
223
- * const result = await dispersa.build({ outputs: [config] })
224
+ * const result = await build({ outputs: [config] })
224
225
  * console.log(result.outputs[0].content)
225
226
  * ```
226
227
  */
@@ -1,8 +1,9 @@
1
- import { F as FileFunction, L as LifecycleHooks, C as CssRendererOptions, O as OutputConfig, T as TailwindRendererOptions, I as IosRendererOptions, A as AndroidRendererOptions } from './index-CqdaN3X0.js';
2
- import { F as Filter } from './types-BzNcG-rI.js';
3
- import { T as Transform } from './types-CzHa7YkW.js';
4
- import { a as JsonRendererOptions, J as JsModuleRendererOptions } from './types-CZb19kiq.js';
5
- import './types-Bc0kA7De.js';
1
+ import { F as FileFunction, L as LifecycleHooks, C as CssRendererOptions, O as OutputConfig } from './index-Dajm5rvM.js';
2
+ import { F as Filter } from './types-ebxDimRz.js';
3
+ import { T as Transform } from './types-DztXKlka.js';
4
+ import { a as JsonRendererOptions, J as JsModuleRendererOptions } from './types-8MLtztK3.js';
5
+ import { T as TailwindRendererOptions, I as IosRendererOptions, A as AndroidRendererOptions } from './android-DANJjjPO.js';
6
+ import './types-TQHV1MrY.js';
6
7
  import 'json-schema-to-ts';
7
8
 
8
9
  /**
@@ -52,7 +53,7 @@ type CssBuilderConfig = BuilderConfigBase & CssRendererOptions;
52
53
  *
53
54
  * The `file` property is optional. When omitted, content is returned in-memory instead
54
55
  * of being written to disk. The `file` property is required when `buildPath` is provided
55
- * to `dispersa.build()`.
56
+ * to `build()`.
56
57
  *
57
58
  * @example Basic CSS bundle with transforms
58
59
  * ```typescript
@@ -93,7 +94,7 @@ type CssBuilderConfig = BuilderConfigBase & CssRendererOptions;
93
94
  * selector: ':root'
94
95
  * })
95
96
  * // Use without buildPath to get content in-memory
96
- * const result = await dispersa.build({ outputs: [config] })
97
+ * const result = await build({ outputs: [config] })
97
98
  * console.log(result.outputs[0].content)
98
99
  * ```
99
100
  */
@@ -118,7 +119,7 @@ type JsonBuilderConfig = BuilderConfigBase & JsonRendererOptions;
118
119
  *
119
120
  * The `file` property is optional. When omitted, content is returned in-memory instead
120
121
  * of being written to disk. The `file` property is required when `buildPath` is provided
121
- * to `dispersa.build()`.
122
+ * to `build()`.
122
123
  *
123
124
  * @example Standalone JSON with flat structure
124
125
  * ```typescript
@@ -155,7 +156,7 @@ type JsonBuilderConfig = BuilderConfigBase & JsonRendererOptions;
155
156
  * structure: 'flat'
156
157
  * })
157
158
  * // Use without buildPath to get content in-memory
158
- * const result = await dispersa.build({ outputs: [config] })
159
+ * const result = await build({ outputs: [config] })
159
160
  * console.log(result.outputs[0].content)
160
161
  * ```
161
162
  */
@@ -181,7 +182,7 @@ type JsBuilderConfig = BuilderConfigBase & JsModuleRendererOptions;
181
182
  *
182
183
  * The `file` property is optional. When omitted, content is returned in-memory instead
183
184
  * of being written to disk. The `file` property is required when `buildPath` is provided
184
- * to `dispersa.build()`.
185
+ * to `build()`.
185
186
  *
186
187
  * @example Bundle JS with helper function
187
188
  * ```typescript
@@ -220,7 +221,7 @@ type JsBuilderConfig = BuilderConfigBase & JsModuleRendererOptions;
220
221
  * structure: 'flat'
221
222
  * })
222
223
  * // Use without buildPath to get content in-memory
223
- * const result = await dispersa.build({ outputs: [config] })
224
+ * const result = await build({ outputs: [config] })
224
225
  * console.log(result.outputs[0].content)
225
226
  * ```
226
227
  */
package/dist/builders.js CHANGED
@@ -41,19 +41,6 @@ var init_errors = __esm({
41
41
  });
42
42
 
43
43
  // src/shared/utils/token-utils.ts
44
- function formatDeprecationMessage(token, description = "", format = "bracket") {
45
- if (token.$deprecated == null || token.$deprecated === false) {
46
- return description;
47
- }
48
- const deprecationMsg = typeof token.$deprecated === "string" ? token.$deprecated : "";
49
- if (format === "comment") {
50
- const msg2 = deprecationMsg ? ` ${deprecationMsg}` : "";
51
- return `DEPRECATED${msg2}`;
52
- }
53
- const msg = deprecationMsg ? `: ${deprecationMsg}` : "";
54
- const prefix = `[DEPRECATED${msg}]`;
55
- return description ? `${prefix} ${description}` : prefix;
56
- }
57
44
  function stripInternalTokenMetadata(tokens) {
58
45
  const cleaned = {};
59
46
  for (const [name, token] of Object.entries(tokens)) {
@@ -331,6 +318,94 @@ var init_utils = __esm({
331
318
  }
332
319
  });
333
320
 
321
+ // src/renderers/metadata.ts
322
+ function sanitizeText(text, format) {
323
+ switch (format) {
324
+ case "css":
325
+ case "tailwind":
326
+ return text.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ").trim();
327
+ case "kotlin":
328
+ return text.replace(/\*\//g, "* /").replace(/\r?\n/g, " ").trim();
329
+ case "js":
330
+ case "swift":
331
+ return text.replace(/\r?\n/g, " ").trim();
332
+ default:
333
+ return text.trim();
334
+ }
335
+ }
336
+ function buildDeprecationText(token) {
337
+ if (token.$deprecated == null || token.$deprecated === false) {
338
+ return "";
339
+ }
340
+ const msg = typeof token.$deprecated === "string" ? token.$deprecated : "";
341
+ return msg ? `DEPRECATED: ${msg}` : "DEPRECATED";
342
+ }
343
+ function buildTokenDescriptionComment(token, format) {
344
+ if (!token.$description || token.$description === "") {
345
+ return void 0;
346
+ }
347
+ const text = sanitizeText(token.$description, format);
348
+ switch (format) {
349
+ case "css":
350
+ case "tailwind":
351
+ return `/* ${text} */`;
352
+ case "js":
353
+ return `// ${text}`;
354
+ case "swift":
355
+ return `/// ${text}`;
356
+ case "kotlin":
357
+ return `/** ${text} */`;
358
+ default:
359
+ return void 0;
360
+ }
361
+ }
362
+ function buildTokenDeprecationComment(token, format) {
363
+ const text = buildDeprecationText(token);
364
+ if (!text) {
365
+ return void 0;
366
+ }
367
+ switch (format) {
368
+ case "css":
369
+ case "tailwind":
370
+ return `/* ${text} */`;
371
+ case "js":
372
+ return `// ${text}`;
373
+ case "swift":
374
+ return `/// ${text}`;
375
+ case "kotlin":
376
+ return `/** ${text} */`;
377
+ default:
378
+ return void 0;
379
+ }
380
+ }
381
+ function buildModifierComment(modifier, context) {
382
+ return `/* Modifier: ${modifier}=${context} */`;
383
+ }
384
+ function buildSwiftDeprecationAttribute(token) {
385
+ if (token.$deprecated == null || token.$deprecated === false) {
386
+ return void 0;
387
+ }
388
+ const msg = typeof token.$deprecated === "string" ? token.$deprecated : "";
389
+ if (msg) {
390
+ return `@available(*, deprecated, message: "${sanitizeText(msg, "swift")}")`;
391
+ }
392
+ return "@available(*, deprecated)";
393
+ }
394
+ function buildKotlinDeprecationAnnotation(token) {
395
+ if (token.$deprecated == null || token.$deprecated === false) {
396
+ return void 0;
397
+ }
398
+ const msg = typeof token.$deprecated === "string" ? token.$deprecated : "";
399
+ if (msg) {
400
+ return `@Deprecated(message = "${sanitizeText(msg, "kotlin")}")`;
401
+ }
402
+ return "@Deprecated";
403
+ }
404
+ var init_metadata = __esm({
405
+ "src/renderers/metadata.ts"() {
406
+ }
407
+ });
408
+
334
409
  // src/renderers/bundlers/js.ts
335
410
  var js_exports = {};
336
411
  __export(js_exports, {
@@ -435,7 +510,7 @@ async function bundleAsJsModule(bundleData, resolver, options, formatTokens) {
435
510
  }
436
511
  const metadata = buildMetadata(resolver);
437
512
  const jsBlocks = [];
438
- for (const { tokens, modifierInputs } of bundleData) {
513
+ for (const { tokens, modifierInputs, isBase } of bundleData) {
439
514
  const cleanTokens = stripInternalMetadata(tokens);
440
515
  const key = buildStableDashKey({
441
516
  modifierInputs,
@@ -443,10 +518,30 @@ async function bundleAsJsModule(bundleData, resolver, options, formatTokens) {
443
518
  defaults: metadata.defaults
444
519
  });
445
520
  const camelKey = toCamelKey(key);
521
+ const normalizedInputs = normalizeModifierInputs(modifierInputs);
522
+ const modifierParts = [];
523
+ for (const dim of metadata.dimensions) {
524
+ const value = normalizedInputs[dim.toLowerCase()];
525
+ if (value) {
526
+ modifierParts.push(`${dim}=${value}`);
527
+ }
528
+ }
446
529
  const formattedJs = await formatTokens(cleanTokens);
447
530
  const tokenObject = extractObjectFromJsModule(formattedJs);
448
531
  const indentedObject = tokenObject.replace(/\n/g, "\n ");
449
- jsBlocks.push(` // ${key}
532
+ let comment;
533
+ if (modifierParts.length > 0) {
534
+ const modifierPart = modifierParts[0];
535
+ const eqIndex = modifierPart.indexOf("=");
536
+ const modifier = modifierPart.slice(0, eqIndex);
537
+ const context = modifierPart.slice(eqIndex + 1);
538
+ comment = buildModifierComment(modifier, context);
539
+ } else if (isBase) {
540
+ comment = "// Base permutation";
541
+ } else {
542
+ comment = `// ${key}`;
543
+ }
544
+ jsBlocks.push(` ${comment}
450
545
  ${JSON.stringify(camelKey)}: ${indentedObject}`);
451
546
  }
452
547
  return assembleJsBundle(metadata, jsBlocks, options?.generateHelper ?? false);
@@ -454,6 +549,7 @@ async function bundleAsJsModule(bundleData, resolver, options, formatTokens) {
454
549
  var init_js = __esm({
455
550
  "src/renderers/bundlers/js.ts"() {
456
551
  init_errors();
552
+ init_metadata();
457
553
  init_utils();
458
554
  }
459
555
  });
@@ -573,6 +669,7 @@ function durationObjectToString(duration) {
573
669
  init_errors();
574
670
  init_token_utils();
575
671
  init_utils();
672
+ init_metadata();
576
673
 
577
674
  // src/renderers/output-tree.ts
578
675
  var outputTree = (files) => {
@@ -633,9 +730,6 @@ function resolveColorFormat(format) {
633
730
  function escapeKotlinString(str) {
634
731
  return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\$/g, "\\$");
635
732
  }
636
- function escapeKDoc(str) {
637
- return str.replace(/\*\//g, "* /").replace(/\r?\n/g, " ").trim();
638
- }
639
733
  function formatKotlinNumber(value) {
640
734
  return Number.isInteger(value) ? `${value}.0` : String(value);
641
735
  }
@@ -767,8 +861,13 @@ var AndroidRenderer = class {
767
861
  const kotlinName = this.buildFlatKotlinName(token);
768
862
  const kotlinValue = this.formatKotlinValue(token, options, baseDepth + 1);
769
863
  const annotation = this.typeAnnotationSuffix(token);
770
- if (token.$description) {
771
- lines.push(`${valIndent}/** ${escapeKDoc(token.$description)} */`);
864
+ const descriptionComment = buildTokenDescriptionComment(token, "kotlin");
865
+ if (descriptionComment) {
866
+ lines.push(`${valIndent}${descriptionComment}`);
867
+ }
868
+ const deprecation = buildKotlinDeprecationAnnotation(token);
869
+ if (deprecation) {
870
+ lines.push(`${valIndent}${deprecation}`);
772
871
  }
773
872
  lines.push(
774
873
  `${valIndent}${options.visPrefix}val ${kotlinName}${annotation} = ${kotlinValue}`
@@ -804,8 +903,13 @@ var AndroidRenderer = class {
804
903
  const kotlinName = toSafeIdentifier(key, KOTLIN_KEYWORDS, false);
805
904
  const kotlinValue = this.formatKotlinValue(token, options, depth);
806
905
  const annotation = this.typeAnnotationSuffix(token);
807
- if (token.$description) {
808
- lines.push(`${pad}/** ${escapeKDoc(token.$description)} */`);
906
+ const descriptionComment = buildTokenDescriptionComment(token, "kotlin");
907
+ if (descriptionComment) {
908
+ lines.push(`${pad}${descriptionComment}`);
909
+ }
910
+ const deprecation = buildKotlinDeprecationAnnotation(token);
911
+ if (deprecation) {
912
+ lines.push(`${pad}${deprecation}`);
809
913
  }
810
914
  lines.push(`${pad}${options.visPrefix}val ${kotlinName}${annotation} = ${kotlinValue}`);
811
915
  }
@@ -1582,10 +1686,8 @@ function stableInputsKey(modifierInputs) {
1582
1686
 
1583
1687
  // src/renderers/css.ts
1584
1688
  init_utils();
1689
+ init_metadata();
1585
1690
  var CssRenderer = class _CssRenderer {
1586
- sanitizeCssCommentText(text) {
1587
- return text.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ").trim();
1588
- }
1589
1691
  async format(context, options) {
1590
1692
  const opts = {
1591
1693
  preset: options?.preset ?? "bundle",
@@ -1665,12 +1767,13 @@ var CssRenderer = class _CssRenderer {
1665
1767
  }
1666
1768
  pushTokenLines(lines, token, tokens, referenceTokens, preserveReferences, indent, newline, space) {
1667
1769
  const entries = this.buildCssEntries(token, tokens, referenceTokens, preserveReferences);
1668
- if (token.$deprecated != null && token.$deprecated !== false) {
1669
- const deprecationMsg = formatDeprecationMessage(token, "", "comment");
1670
- lines.push(`${indent}/* ${this.sanitizeCssCommentText(deprecationMsg)} */${newline}`);
1770
+ const deprecationComment = buildTokenDeprecationComment(token, "css");
1771
+ if (deprecationComment) {
1772
+ lines.push(`${indent}${deprecationComment}${newline}`);
1671
1773
  }
1672
- if (token.$description && token.$description !== "") {
1673
- lines.push(`${indent}/* ${this.sanitizeCssCommentText(token.$description)} */${newline}`);
1774
+ const descriptionComment = buildTokenDescriptionComment(token, "css");
1775
+ if (descriptionComment) {
1776
+ lines.push(`${indent}${descriptionComment}${newline}`);
1674
1777
  }
1675
1778
  for (const entry of entries) {
1676
1779
  lines.push(`${indent}--${entry.name}:${space}${entry.value};${newline}`);
@@ -2321,6 +2424,7 @@ function isBorderToken(token) {
2321
2424
 
2322
2425
  // src/renderers/ios.ts
2323
2426
  init_utils();
2427
+ init_metadata();
2324
2428
  var toSRGB2 = converter("rgb");
2325
2429
  var toP32 = converter("p3");
2326
2430
  var SWIFT_TYPE_GROUP_MAP = {
@@ -2464,9 +2568,13 @@ var IosRenderer = class {
2464
2568
  const swiftValue = this.formatSwiftValue(token, options);
2465
2569
  const typeAnnotation = this.getTypeAnnotation(token);
2466
2570
  const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
2467
- const docComment = this.buildDocComment(token, indent);
2571
+ const docComment = buildTokenDescriptionComment(token, "swift");
2468
2572
  if (docComment) {
2469
- lines.push(docComment);
2573
+ lines.push(`${indent}${docComment}`);
2574
+ }
2575
+ const deprecationAttr = buildSwiftDeprecationAttribute(token);
2576
+ if (deprecationAttr) {
2577
+ lines.push(`${indent}${deprecationAttr}`);
2470
2578
  }
2471
2579
  lines.push(`${indent}${access} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
2472
2580
  }
@@ -2481,15 +2589,6 @@ var IosRenderer = class {
2481
2589
  }
2482
2590
  return Array.from(imports).sort();
2483
2591
  }
2484
- /**
2485
- * Builds a `///` doc comment from a token's `$description`, if present.
2486
- */
2487
- buildDocComment(token, indent) {
2488
- if (!token.$description) {
2489
- return void 0;
2490
- }
2491
- return `${indent}/// ${token.$description}`;
2492
- }
2493
2592
  /**
2494
2593
  * Builds a qualified Swift name from a token's path, preserving parent
2495
2594
  * hierarchy segments to avoid duplicate identifiers.
@@ -2880,6 +2979,7 @@ function iosRenderer() {
2880
2979
  // src/renderers/js-module.ts
2881
2980
  init_utils();
2882
2981
  init_token_utils();
2982
+ init_metadata();
2883
2983
  var JsModuleRenderer = class {
2884
2984
  async format(context, options) {
2885
2985
  const opts = {
@@ -2917,17 +3017,10 @@ var JsModuleRenderer = class {
2917
3017
  return outputTree(files);
2918
3018
  }
2919
3019
  async formatTokens(tokens, options) {
2920
- const opts = {
2921
- preset: options.preset ?? "standalone",
2922
- structure: options.structure ?? "nested",
2923
- minify: options.minify ?? false,
2924
- moduleName: options.moduleName ?? "tokens",
2925
- generateHelper: options.generateHelper ?? false
2926
- };
2927
3020
  const lines = [];
2928
- lines.push(...this.formatAsObject(tokens, opts));
3021
+ lines.push(...this.formatAsObject(tokens, options));
2929
3022
  const code = lines.join("\n");
2930
- if (opts.minify) {
3023
+ if (options.minify) {
2931
3024
  return code;
2932
3025
  }
2933
3026
  return await prettier.format(code, {
@@ -2940,20 +3033,53 @@ var JsModuleRenderer = class {
2940
3033
  trailingComma: "es5"
2941
3034
  });
2942
3035
  }
2943
- /**
2944
- * Format as default export object
2945
- */
2946
3036
  formatAsObject(tokens, options) {
2947
3037
  const lines = [];
2948
- const tokenObj = this.tokensToPlainObject(tokens, options.structure);
3038
+ const tokenMap = this.buildTokenMap(tokens);
2949
3039
  const varName = options.moduleName !== "" ? options.moduleName : "tokens";
2950
- lines.push(`const ${varName} = {`);
2951
- this.addObjectProperties(lines, tokenObj, 1);
2952
- lines.push("}");
3040
+ if (options.structure === "flat") {
3041
+ lines.push(`const ${varName} = {`);
3042
+ this.addFlatProperties(lines, tokens, 1);
3043
+ lines.push("}");
3044
+ } else {
3045
+ lines.push(`const ${varName} = {`);
3046
+ const tokenObj = this.tokensToPlainObject(tokens, "nested");
3047
+ this.addNestedProperties(lines, tokenObj, tokenMap, 1);
3048
+ lines.push("}");
3049
+ }
2953
3050
  lines.push("");
2954
3051
  lines.push(`export default ${varName}`);
2955
3052
  return lines;
2956
3053
  }
3054
+ buildTokenMap(tokens) {
3055
+ const map = /* @__PURE__ */ new Map();
3056
+ for (const [name, token] of Object.entries(tokens)) {
3057
+ map.set(name, token);
3058
+ }
3059
+ return map;
3060
+ }
3061
+ addFlatProperties(lines, tokens, indent) {
3062
+ const indentStr2 = " ".repeat(indent);
3063
+ const sortedEntries = getSortedTokenEntries(tokens);
3064
+ for (let i = 0; i < sortedEntries.length; i++) {
3065
+ const [name, token] = sortedEntries[i];
3066
+ const isLast = i === sortedEntries.length - 1;
3067
+ this.pushTokenComments(lines, token, indentStr2);
3068
+ lines.push(
3069
+ `${indentStr2}${this.quoteKey(name)}: ${JSON.stringify(token.$value)}${isLast ? "" : ","}`
3070
+ );
3071
+ }
3072
+ }
3073
+ pushTokenComments(lines, token, indent) {
3074
+ const deprecationComment = buildTokenDeprecationComment(token, "js");
3075
+ if (deprecationComment) {
3076
+ lines.push(`${indent}${deprecationComment}`);
3077
+ }
3078
+ const descriptionComment = buildTokenDescriptionComment(token, "js");
3079
+ if (descriptionComment) {
3080
+ lines.push(`${indent}${descriptionComment}`);
3081
+ }
3082
+ }
2957
3083
  tokensToPlainObject(tokens, structure) {
2958
3084
  if (structure === "nested") {
2959
3085
  return buildNestedTokenObject(tokens, (token) => token.$value);
@@ -2964,7 +3090,7 @@ var JsModuleRenderer = class {
2964
3090
  }
2965
3091
  return result;
2966
3092
  }
2967
- addObjectProperties(lines, obj, indent) {
3093
+ addNestedProperties(lines, obj, tokenMap, indent) {
2968
3094
  const indentStr2 = " ".repeat(indent);
2969
3095
  const entries = Object.entries(obj).sort(([keyA], [keyB]) => keyA.localeCompare(keyB));
2970
3096
  for (let i = 0; i < entries.length; i++) {
@@ -2976,19 +3102,20 @@ var JsModuleRenderer = class {
2976
3102
  const isLast = i === entries.length - 1;
2977
3103
  const isNestedObject = typeof value === "object" && value !== null && !Array.isArray(value);
2978
3104
  if (!isNestedObject) {
3105
+ const token = tokenMap.get(key);
3106
+ if (token) {
3107
+ this.pushTokenComments(lines, token, indentStr2);
3108
+ }
2979
3109
  lines.push(
2980
3110
  `${indentStr2}${this.quoteKey(key)}: ${JSON.stringify(value)}${isLast ? "" : ","}`
2981
3111
  );
2982
3112
  continue;
2983
3113
  }
2984
3114
  lines.push(`${indentStr2}${this.quoteKey(key)}: {`);
2985
- this.addObjectProperties(lines, value, indent + 1);
3115
+ this.addNestedProperties(lines, value, tokenMap, indent + 1);
2986
3116
  lines.push(`${indentStr2}}${isLast ? "" : ","}`);
2987
3117
  }
2988
3118
  }
2989
- /**
2990
- * Quote key if necessary
2991
- */
2992
3119
  quoteKey(key) {
2993
3120
  if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) {
2994
3121
  return key;
@@ -3224,6 +3351,7 @@ function resolveOptions(options) {
3224
3351
 
3225
3352
  // src/renderers/tailwind.ts
3226
3353
  init_utils();
3354
+ init_metadata();
3227
3355
  var TAILWIND_NAMESPACE_MAP = {
3228
3356
  color: "color",
3229
3357
  dimension: "spacing",
@@ -3277,6 +3405,14 @@ var TailwindRenderer = class {
3277
3405
  for (const [, token] of getSortedTokenEntries(tokens)) {
3278
3406
  const varName = this.buildVariableName(token);
3279
3407
  const varValue = this.formatValue(token);
3408
+ const deprecationComment = buildTokenDeprecationComment(token, "tailwind");
3409
+ if (deprecationComment) {
3410
+ lines.push(`${indent}${deprecationComment}${newline}`);
3411
+ }
3412
+ const descriptionComment = buildTokenDescriptionComment(token, "tailwind");
3413
+ if (descriptionComment) {
3414
+ lines.push(`${indent}${descriptionComment}${newline}`);
3415
+ }
3280
3416
  lines.push(`${indent}--${varName}:${space}${varValue};${newline}`);
3281
3417
  }
3282
3418
  lines.push(`}${newline}`);
@@ -3303,6 +3439,14 @@ var TailwindRenderer = class {
3303
3439
  for (const [, token] of getSortedTokenEntries(tokens)) {
3304
3440
  const varName = this.buildVariableName(token);
3305
3441
  const varValue = this.formatValue(token);
3442
+ const deprecationComment = buildTokenDeprecationComment(token, "tailwind");
3443
+ if (deprecationComment) {
3444
+ lines.push(`${tokenIndent}${deprecationComment}${newline}`);
3445
+ }
3446
+ const descriptionComment = buildTokenDescriptionComment(token, "tailwind");
3447
+ if (descriptionComment) {
3448
+ lines.push(`${tokenIndent}${descriptionComment}${newline}`);
3449
+ }
3306
3450
  lines.push(`${tokenIndent}--${varName}:${space}${varValue};${newline}`);
3307
3451
  }
3308
3452
  if (hasMediaQuery) {