@breadstone-infrastructure/token-linter 0.0.231

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 (196) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/LICENSE +21 -0
  3. package/README.md +72 -0
  4. package/cli/Cli.d.ts +10 -0
  5. package/cli/Cli.d.ts.map +1 -0
  6. package/cli/Cli.js +32 -0
  7. package/cli/Cli.js.map +1 -0
  8. package/cli/CliArgs.d.ts +2 -0
  9. package/cli/CliArgs.d.ts.map +1 -0
  10. package/cli/CliArgs.js +88 -0
  11. package/cli/CliArgs.js.map +1 -0
  12. package/cli/CliArgsConfig.d.ts +2 -0
  13. package/cli/CliArgsConfig.d.ts.map +1 -0
  14. package/cli/CliArgsConfig.js +12 -0
  15. package/cli/CliArgsConfig.js.map +1 -0
  16. package/cli/CliRun.d.ts +2 -0
  17. package/cli/CliRun.d.ts.map +1 -0
  18. package/cli/CliRun.js +34 -0
  19. package/cli/CliRun.js.map +1 -0
  20. package/cli/commands/LintCommand.d.ts +2 -0
  21. package/cli/commands/LintCommand.d.ts.map +1 -0
  22. package/cli/commands/LintCommand.js +66 -0
  23. package/cli/commands/LintCommand.js.map +1 -0
  24. package/cli/commands/LintCommandArgsConfig.d.ts +2 -0
  25. package/cli/commands/LintCommandArgsConfig.d.ts.map +1 -0
  26. package/cli/commands/LintCommandArgsConfig.js +46 -0
  27. package/cli/commands/LintCommandArgsConfig.js.map +1 -0
  28. package/cli/lint.d.ts +3 -0
  29. package/cli/lint.d.ts.map +1 -0
  30. package/cli/lint.js +55 -0
  31. package/cli/lint.js.map +1 -0
  32. package/config/TokenLinterConfigDiscovery.d.ts +16 -0
  33. package/config/TokenLinterConfigDiscovery.d.ts.map +1 -0
  34. package/config/TokenLinterConfigDiscovery.js +44 -0
  35. package/config/TokenLinterConfigDiscovery.js.map +1 -0
  36. package/config/defineConfig.d.ts +41 -0
  37. package/config/defineConfig.d.ts.map +1 -0
  38. package/config/defineConfig.js +37 -0
  39. package/config/defineConfig.js.map +1 -0
  40. package/core/interaction.d.ts +25 -0
  41. package/core/interaction.d.ts.map +1 -0
  42. package/core/interaction.js +45 -0
  43. package/core/interaction.js.map +1 -0
  44. package/core/loader.d.ts +21 -0
  45. package/core/loader.d.ts.map +1 -0
  46. package/core/loader.js +84 -0
  47. package/core/loader.js.map +1 -0
  48. package/core/rule-registry.d.ts +46 -0
  49. package/core/rule-registry.d.ts.map +1 -0
  50. package/core/rule-registry.js +73 -0
  51. package/core/rule-registry.js.map +1 -0
  52. package/core/rule.d.ts +46 -0
  53. package/core/rule.d.ts.map +1 -0
  54. package/core/rule.js +3 -0
  55. package/core/rule.js.map +1 -0
  56. package/core/runner.d.ts +23 -0
  57. package/core/runner.d.ts.map +1 -0
  58. package/core/runner.js +103 -0
  59. package/core/runner.js.map +1 -0
  60. package/index.d.ts +46 -0
  61. package/index.d.ts.map +1 -0
  62. package/index.js +47 -0
  63. package/index.js.map +1 -0
  64. package/models/lint-result.d.ts +14 -0
  65. package/models/lint-result.d.ts.map +1 -0
  66. package/models/lint-result.js +3 -0
  67. package/models/lint-result.js.map +1 -0
  68. package/models/rule-context.d.ts +18 -0
  69. package/models/rule-context.d.ts.map +1 -0
  70. package/models/rule-context.js +3 -0
  71. package/models/rule-context.js.map +1 -0
  72. package/models/rule-finding.d.ts +15 -0
  73. package/models/rule-finding.d.ts.map +1 -0
  74. package/models/rule-finding.js +3 -0
  75. package/models/rule-finding.js.map +1 -0
  76. package/models/rule-result.d.ts +11 -0
  77. package/models/rule-result.d.ts.map +1 -0
  78. package/models/rule-result.js +3 -0
  79. package/models/rule-result.js.map +1 -0
  80. package/models/rule-severity.d.ts +14 -0
  81. package/models/rule-severity.d.ts.map +1 -0
  82. package/models/rule-severity.js +10 -0
  83. package/models/rule-severity.js.map +1 -0
  84. package/models/token-entry.d.ts +11 -0
  85. package/models/token-entry.d.ts.map +1 -0
  86. package/models/token-entry.js +2 -0
  87. package/models/token-entry.js.map +1 -0
  88. package/models/token-linter-config.d.ts +30 -0
  89. package/models/token-linter-config.d.ts.map +1 -0
  90. package/models/token-linter-config.js +3 -0
  91. package/models/token-linter-config.js.map +1 -0
  92. package/orchestration/TokenLinterOrchestrator.d.ts +29 -0
  93. package/orchestration/TokenLinterOrchestrator.d.ts.map +1 -0
  94. package/orchestration/TokenLinterOrchestrator.js +98 -0
  95. package/orchestration/TokenLinterOrchestrator.js.map +1 -0
  96. package/package.json +20 -0
  97. package/presets/index.d.ts +2 -0
  98. package/presets/index.d.ts.map +1 -0
  99. package/presets/index.js +2 -0
  100. package/presets/index.js.map +1 -0
  101. package/presets/recommended.d.ts +23 -0
  102. package/presets/recommended.d.ts.map +1 -0
  103. package/presets/recommended.js +41 -0
  104. package/presets/recommended.js.map +1 -0
  105. package/reporters/console.reporter.d.ts +15 -0
  106. package/reporters/console.reporter.d.ts.map +1 -0
  107. package/reporters/console.reporter.js +75 -0
  108. package/reporters/console.reporter.js.map +1 -0
  109. package/reporters/json.reporter.d.ts +11 -0
  110. package/reporters/json.reporter.d.ts.map +1 -0
  111. package/reporters/json.reporter.js +37 -0
  112. package/reporters/json.reporter.js.map +1 -0
  113. package/reporters/reporter.d.ts +16 -0
  114. package/reporters/reporter.d.ts.map +1 -0
  115. package/reporters/reporter.js +3 -0
  116. package/reporters/reporter.js.map +1 -0
  117. package/reporters/summary.reporter.d.ts +12 -0
  118. package/reporters/summary.reporter.d.ts.map +1 -0
  119. package/reporters/summary.reporter.js +48 -0
  120. package/reporters/summary.reporter.js.map +1 -0
  121. package/rules/alphabetical-sort.rule.d.ts +19 -0
  122. package/rules/alphabetical-sort.rule.d.ts.map +1 -0
  123. package/rules/alphabetical-sort.rule.js +72 -0
  124. package/rules/alphabetical-sort.rule.js.map +1 -0
  125. package/rules/component-presence.rule.d.ts +29 -0
  126. package/rules/component-presence.rule.d.ts.map +1 -0
  127. package/rules/component-presence.rule.js +102 -0
  128. package/rules/component-presence.rule.js.map +1 -0
  129. package/rules/duplicate-value.rule.d.ts +17 -0
  130. package/rules/duplicate-value.rule.d.ts.map +1 -0
  131. package/rules/duplicate-value.rule.js +49 -0
  132. package/rules/duplicate-value.rule.js.map +1 -0
  133. package/rules/empty-json.rule.d.ts +52 -0
  134. package/rules/empty-json.rule.d.ts.map +1 -0
  135. package/rules/empty-json.rule.js +100 -0
  136. package/rules/empty-json.rule.js.map +1 -0
  137. package/rules/forbidden-key.rule.d.ts +57 -0
  138. package/rules/forbidden-key.rule.d.ts.map +1 -0
  139. package/rules/forbidden-key.rule.js +118 -0
  140. package/rules/forbidden-key.rule.js.map +1 -0
  141. package/rules/forbidden-value.rule.d.ts +53 -0
  142. package/rules/forbidden-value.rule.d.ts.map +1 -0
  143. package/rules/forbidden-value.rule.js +130 -0
  144. package/rules/forbidden-value.rule.js.map +1 -0
  145. package/rules/includes-consistency.rule.d.ts +30 -0
  146. package/rules/includes-consistency.rule.d.ts.map +1 -0
  147. package/rules/includes-consistency.rule.js +153 -0
  148. package/rules/includes-consistency.rule.js.map +1 -0
  149. package/rules/index.d.ts +7 -0
  150. package/rules/index.d.ts.map +1 -0
  151. package/rules/index.js +47 -0
  152. package/rules/index.js.map +1 -0
  153. package/rules/key-consistency.rule.d.ts +38 -0
  154. package/rules/key-consistency.rule.d.ts.map +1 -0
  155. package/rules/key-consistency.rule.js +161 -0
  156. package/rules/key-consistency.rule.js.map +1 -0
  157. package/rules/missing-includes.rule.d.ts +19 -0
  158. package/rules/missing-includes.rule.d.ts.map +1 -0
  159. package/rules/missing-includes.rule.js +51 -0
  160. package/rules/missing-includes.rule.js.map +1 -0
  161. package/rules/mixin-reference.rule.d.ts +28 -0
  162. package/rules/mixin-reference.rule.d.ts.map +1 -0
  163. package/rules/mixin-reference.rule.js +104 -0
  164. package/rules/mixin-reference.rule.js.map +1 -0
  165. package/rules/naming-convention.rule.d.ts +29 -0
  166. package/rules/naming-convention.rule.d.ts.map +1 -0
  167. package/rules/naming-convention.rule.js +112 -0
  168. package/rules/naming-convention.rule.js.map +1 -0
  169. package/rules/nested-depth.rule.d.ts +42 -0
  170. package/rules/nested-depth.rule.d.ts.map +1 -0
  171. package/rules/nested-depth.rule.js +72 -0
  172. package/rules/nested-depth.rule.js.map +1 -0
  173. package/rules/required-includes.rule.d.ts +60 -0
  174. package/rules/required-includes.rule.d.ts.map +1 -0
  175. package/rules/required-includes.rule.js +118 -0
  176. package/rules/required-includes.rule.js.map +1 -0
  177. package/rules/rule-options.d.ts +158 -0
  178. package/rules/rule-options.d.ts.map +1 -0
  179. package/rules/rule-options.js +89 -0
  180. package/rules/rule-options.js.map +1 -0
  181. package/rules/value-consistency.rule.d.ts +17 -0
  182. package/rules/value-consistency.rule.d.ts.map +1 -0
  183. package/rules/value-consistency.rule.js +69 -0
  184. package/rules/value-consistency.rule.js.map +1 -0
  185. package/rules/value-schema.rule.d.ts +18 -0
  186. package/rules/value-schema.rule.d.ts.map +1 -0
  187. package/rules/value-schema.rule.js +108 -0
  188. package/rules/value-schema.rule.js.map +1 -0
  189. package/rules/value-type.rule.d.ts +71 -0
  190. package/rules/value-type.rule.d.ts.map +1 -0
  191. package/rules/value-type.rule.js +176 -0
  192. package/rules/value-type.rule.js.map +1 -0
  193. package/utils.d.ts +55 -0
  194. package/utils.d.ts.map +1 -0
  195. package/utils.js +125 -0
  196. package/utils.js.map +1 -0
@@ -0,0 +1,176 @@
1
+ // #region Imports
2
+ import * as fs from 'fs';
3
+ import { RuleSeverity } from '../models/rule-severity.js';
4
+ import { METADATA_KEYS, isTokenValue } from '../utils.js';
5
+ // #endregion
6
+ // #region Constants
7
+ /**
8
+ * @description Default key-to-type constraints.
9
+ * Keys listed here must have values of the specified type in every component where they appear.
10
+ * @public
11
+ */
12
+ const DEFAULT_TYPE_CONSTRAINTS = {
13
+ transitionProperty: 'array',
14
+ tooltipTransitionProperty: 'array',
15
+ };
16
+ // #endregion
17
+ // #region Functions
18
+ /**
19
+ * @description Creates typed rule options for the `value-type` rule.
20
+ * @public
21
+ *
22
+ * @example
23
+ * ```js
24
+ * ruleOptions: {
25
+ * ...valueTypeRuleOptions({ types: { transitionProperty: 'array' } }),
26
+ * }
27
+ * ```
28
+ */
29
+ export function valueTypeRuleOptions(options) {
30
+ return { 'value-type': options };
31
+ }
32
+ // #endregion
33
+ /**
34
+ * @description Enforces that specific token keys have values of a required type (string, array, or number).
35
+ * When auto-fix is enabled, values are coerced to the expected type where possible
36
+ * (e.g. a string is wrapped into a single-element array).
37
+ *
38
+ * The type constraints default to `{ transitionProperty: 'array', tooltipTransitionProperty: 'array' }`
39
+ * and can be overridden via `ruleOptions`:
40
+ *
41
+ * @example Configuration
42
+ * ```js
43
+ * export default defineConfig({
44
+ * rules: { 'value-type': 'error' },
45
+ * ruleOptions: {
46
+ * 'value-type': {
47
+ * types: {
48
+ * transitionProperty: 'array',
49
+ * tooltipTransitionProperty: 'array',
50
+ * },
51
+ * },
52
+ * },
53
+ * });
54
+ * ```
55
+ *
56
+ * @public
57
+ */
58
+ export class ValueTypeRule {
59
+ // #region Fields
60
+ name = 'value-type';
61
+ description = 'Enforces that specific token keys have values of a required type (string, array, number).';
62
+ defaultSeverity = RuleSeverity.Error;
63
+ fixable = true;
64
+ interactive = false;
65
+ // #endregion
66
+ // #region Methods
67
+ run(context) {
68
+ const findings = [];
69
+ const options = context.config.ruleOptions[this.name];
70
+ const typeConstraints = options?.types ?? DEFAULT_TYPE_CONSTRAINTS;
71
+ for (const entry of context.entries) {
72
+ for (const [key, val] of Object.entries(entry.content)) {
73
+ if (METADATA_KEYS.includes(key)) {
74
+ continue;
75
+ }
76
+ if (!(key in typeConstraints)) {
77
+ continue;
78
+ }
79
+ if (!isTokenValue(val)) {
80
+ continue;
81
+ }
82
+ const expectedType = typeConstraints[key];
83
+ const actualType = this._getValueType(val.value);
84
+ if (actualType !== expectedType) {
85
+ findings.push({
86
+ component: entry.component,
87
+ theme: entry.theme,
88
+ key,
89
+ message: `Value of '${key}' in '${entry.component}' (${entry.theme}) must be ${expectedType}, but is ${actualType}.`,
90
+ severity: this.defaultSeverity,
91
+ filePath: entry.filePath,
92
+ fixed: false,
93
+ });
94
+ }
95
+ }
96
+ }
97
+ return { ruleName: this.name, findings, duration: 0 };
98
+ }
99
+ fix(context, findings) {
100
+ const options = context.config.ruleOptions[this.name];
101
+ const typeConstraints = options?.types ?? DEFAULT_TYPE_CONSTRAINTS;
102
+ const entryMap = new Map(context.entries.map(e => [e.filePath, e]));
103
+ const pendingWrites = new Map();
104
+ const result = [];
105
+ for (const finding of findings) {
106
+ const entry = finding.filePath ? entryMap.get(finding.filePath) : undefined;
107
+ if (!entry || !finding.key) {
108
+ result.push(finding);
109
+ continue;
110
+ }
111
+ const expectedType = typeConstraints[finding.key];
112
+ if (!expectedType) {
113
+ result.push(finding);
114
+ continue;
115
+ }
116
+ const content = pendingWrites.get(entry.filePath) ?? entry.content;
117
+ const tokenObj = content[finding.key];
118
+ if (!isTokenValue(tokenObj)) {
119
+ result.push(finding);
120
+ continue;
121
+ }
122
+ const coerced = this._coerceValue(tokenObj.value, expectedType);
123
+ if (coerced !== undefined) {
124
+ tokenObj['value'] = coerced;
125
+ pendingWrites.set(entry.filePath, content);
126
+ result.push({ ...finding, fixed: true });
127
+ }
128
+ else {
129
+ result.push(finding);
130
+ }
131
+ }
132
+ for (const [filePath, content] of pendingWrites.entries()) {
133
+ fs.writeFileSync(filePath, JSON.stringify(content, null, 2) + '\n', 'utf-8');
134
+ }
135
+ return result;
136
+ }
137
+ _getValueType(value) {
138
+ if (Array.isArray(value)) {
139
+ return 'array';
140
+ }
141
+ if (typeof value === 'string') {
142
+ return 'string';
143
+ }
144
+ if (typeof value === 'number') {
145
+ return 'number';
146
+ }
147
+ return 'unknown';
148
+ }
149
+ _coerceValue(value, target) {
150
+ const currentType = this._getValueType(value);
151
+ if (currentType === target) {
152
+ return value;
153
+ }
154
+ // string → array: wrap in single-element array
155
+ if (currentType === 'string' && target === 'array') {
156
+ return [value];
157
+ }
158
+ // array → string: unwrap if single element
159
+ if (currentType === 'array' && target === 'string' && Array.isArray(value) && value.length === 1) {
160
+ return value[0];
161
+ }
162
+ // string → number: parse if numeric
163
+ if (currentType === 'string' && target === 'number') {
164
+ const num = Number(value);
165
+ if (!isNaN(num)) {
166
+ return num;
167
+ }
168
+ }
169
+ // number → string
170
+ if (currentType === 'number' && target === 'string') {
171
+ return String(value);
172
+ }
173
+ return undefined;
174
+ }
175
+ }
176
+ //# sourceMappingURL=value-type.rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-type.rule.js","sourceRoot":"","sources":["../../src/rules/value-type.rule.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAElB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAKzB,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAY1D,aAAa;AAEb,oBAAoB;AAEpB;;;;GAIG;AACH,MAAM,wBAAwB,GAA6C;IACvE,kBAAkB,EAAE,OAAO;IAC3B,yBAAyB,EAAE,OAAO;CACrC,CAAC;AAmBF,aAAa;AAEb,oBAAoB;AAEpB;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA8B;IAC/D,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC;AAED,aAAa;AAEb;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,OAAO,aAAa;IAEtB,iBAAiB;IAED,IAAI,GAAG,YAAY,CAAC;IACpB,WAAW,GAAG,2FAA2F,CAAC;IAC1G,eAAe,GAAiB,YAAY,CAAC,KAAK,CAAC;IACnD,OAAO,GAAG,IAAI,CAAC;IACf,WAAW,GAAG,KAAK,CAAC;IAEpC,aAAa;IAEb,kBAAkB;IAEX,GAAG,CAAC,OAAqB;QAC5B,MAAM,QAAQ,GAAmB,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAsC,CAAC;QAC3F,MAAM,eAAe,GAAG,OAAO,EAAE,KAAK,IAAI,wBAAwB,CAAC;QAEnE,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAClC,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrD,IAAI,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9B,SAAS;gBACb,CAAC;gBAED,IAAI,CAAC,CAAC,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC;oBAC5B,SAAS;gBACb,CAAC;gBAED,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;oBACrB,SAAS;gBACb,CAAC;gBAED,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;gBAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAEjD,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;oBAC9B,QAAQ,CAAC,IAAI,CAAC;wBACV,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,GAAG;wBACH,OAAO,EAAE,aAAa,GAAG,SAAS,KAAK,CAAC,SAAS,MAAM,KAAK,CAAC,KAAK,aAAa,YAAY,YAAY,UAAU,GAAG;wBACpH,QAAQ,EAAE,IAAI,CAAC,eAAe;wBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,KAAK,EAAE,KAAK;qBACf,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAC1D,CAAC;IAEM,GAAG,CAAC,OAAqB,EAAE,QAAqC;QACnE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAsC,CAAC;QAC3F,MAAM,eAAe,GAAG,OAAO,EAAE,KAAK,IAAI,wBAAwB,CAAC;QACnE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAmC,CAAC;QACjE,MAAM,MAAM,GAAmB,EAAE,CAAC;QAElC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAE5E,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBACzB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAErB,SAAS;YACb,CAAC;YAED,MAAM,YAAY,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAElD,IAAI,CAAC,YAAY,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAErB,SAAS;YACb,CAAC;YAED,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC;YACnE,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAEtC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAErB,SAAS;YACb,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;YAEhE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBACvB,QAAoC,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;gBACzD,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAC3C,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;QAED,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YACxD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QACjF,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,aAAa,CAAC,KAAc;QAChC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,OAAO,CAAC;QACnB,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,YAAY,CAAC,KAAc,EAAE,MAAsB;QACvD,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE9C,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,+CAA+C;QAC/C,IAAI,WAAW,KAAK,QAAQ,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACjD,OAAO,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;QAED,2CAA2C;QAC3C,IAAI,WAAW,KAAK,OAAO,IAAI,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/F,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,oCAAoC;QACpC,IAAI,WAAW,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAE1B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBACd,OAAO,GAAG,CAAC;YACf,CAAC;QACL,CAAC;QAED,kBAAkB;QAClB,IAAI,WAAW,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YAClD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;CAGJ"}
package/utils.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @description Metadata keys in token JSON files that are not token definitions.
3
+ * @public
4
+ */
5
+ export declare const METADATA_KEYS: ReadonlyArray<string>;
6
+ /**
7
+ * @description Checks if an object is a token value object with a `value` property.
8
+ * @public
9
+ */
10
+ export declare function isTokenValue(obj: unknown): obj is {
11
+ value: unknown;
12
+ };
13
+ /**
14
+ * @description Checks if an object is a nested token group containing sub-objects with `value`.
15
+ * @public
16
+ */
17
+ export declare function isNestedTokenGroup(obj: unknown): obj is Record<string, unknown>;
18
+ /**
19
+ * @description Extracts the string value from a token value object.
20
+ * @public
21
+ */
22
+ export declare function getTokenStringValue(obj: unknown): string | undefined;
23
+ /**
24
+ * @description Retrieves all token keys from a content object, excluding metadata keys.
25
+ * @public
26
+ */
27
+ export declare function getTokenKeys(content: Record<string, unknown>): string[];
28
+ /**
29
+ * @description Collects all flat token entries including nested ones using dot notation for keys.
30
+ * @public
31
+ */
32
+ export declare function flattenTokenEntries(content: Record<string, unknown>, prefix?: string): Array<{
33
+ key: string;
34
+ value: unknown;
35
+ }>;
36
+ /**
37
+ * @description Groups token entries by component name.
38
+ * @public
39
+ */
40
+ export declare function groupByComponent<T extends {
41
+ component: string;
42
+ }>(entries: ReadonlyArray<T>): Map<string, T[]>;
43
+ /**
44
+ * @description Resolves the `$includes` array of a component entry to the set of token keys
45
+ * those mixins provide. Handles modifier syntax (e.g. `"color:background"` → `backgroundColor`).
46
+ * @public
47
+ */
48
+ export declare function resolveMixinKeys(includes: ReadonlyArray<string>, mixinKeys: ReadonlyMap<string, ReadonlyArray<string>>): Set<string>;
49
+ /**
50
+ * @description Deep-clones a value and replaces occurrences of the source theme prefix with the target theme prefix
51
+ * in all CSS variable references (e.g. `--memphis-` → `--joy-`).
52
+ * @public
53
+ */
54
+ export declare function replaceThemePrefix(value: unknown, sourceTheme: string, targetTheme: string): unknown;
55
+ //# sourceMappingURL=utils.d.ts.map
package/utils.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,MAAM,CAAiB,CAAC;AAMlE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,CAEpE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAM/E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAMpE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAEvE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,SAAK,GAAG,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAkBzH;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAY7G;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC5B,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,EAC/B,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,GACtD,GAAG,CAAC,MAAM,CAAC,CAuBb;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAoBpG"}
package/utils.js ADDED
@@ -0,0 +1,125 @@
1
+ // #region Constants
2
+ /**
3
+ * @description Metadata keys in token JSON files that are not token definitions.
4
+ * @public
5
+ */
6
+ export const METADATA_KEYS = ['$includes'];
7
+ // #endregion
8
+ // #region Functions
9
+ /**
10
+ * @description Checks if an object is a token value object with a `value` property.
11
+ * @public
12
+ */
13
+ export function isTokenValue(obj) {
14
+ return typeof obj === 'object' && obj !== null && 'value' in obj;
15
+ }
16
+ /**
17
+ * @description Checks if an object is a nested token group containing sub-objects with `value`.
18
+ * @public
19
+ */
20
+ export function isNestedTokenGroup(obj) {
21
+ if (typeof obj !== 'object' || obj === null || 'value' in obj) {
22
+ return false;
23
+ }
24
+ return Object.values(obj).some(v => isTokenValue(v));
25
+ }
26
+ /**
27
+ * @description Extracts the string value from a token value object.
28
+ * @public
29
+ */
30
+ export function getTokenStringValue(obj) {
31
+ if (isTokenValue(obj) && typeof obj.value === 'string') {
32
+ return obj.value;
33
+ }
34
+ return undefined;
35
+ }
36
+ /**
37
+ * @description Retrieves all token keys from a content object, excluding metadata keys.
38
+ * @public
39
+ */
40
+ export function getTokenKeys(content) {
41
+ return Object.keys(content).filter(key => !METADATA_KEYS.includes(key));
42
+ }
43
+ /**
44
+ * @description Collects all flat token entries including nested ones using dot notation for keys.
45
+ * @public
46
+ */
47
+ export function flattenTokenEntries(content, prefix = '') {
48
+ const result = [];
49
+ for (const [key, val] of Object.entries(content)) {
50
+ if (METADATA_KEYS.includes(key)) {
51
+ continue;
52
+ }
53
+ const fullKey = prefix ? `${prefix}.${key}` : key;
54
+ if (isTokenValue(val)) {
55
+ result.push({ key: fullKey, value: val.value });
56
+ }
57
+ else if (isNestedTokenGroup(val)) {
58
+ result.push(...flattenTokenEntries(val, fullKey));
59
+ }
60
+ }
61
+ return result;
62
+ }
63
+ /**
64
+ * @description Groups token entries by component name.
65
+ * @public
66
+ */
67
+ export function groupByComponent(entries) {
68
+ const grouped = new Map();
69
+ for (const entry of entries) {
70
+ if (!grouped.has(entry.component)) {
71
+ grouped.set(entry.component, []);
72
+ }
73
+ grouped.get(entry.component).push(entry);
74
+ }
75
+ return grouped;
76
+ }
77
+ /**
78
+ * @description Resolves the `$includes` array of a component entry to the set of token keys
79
+ * those mixins provide. Handles modifier syntax (e.g. `"color:background"` → `backgroundColor`).
80
+ * @public
81
+ */
82
+ export function resolveMixinKeys(includes, mixinKeys) {
83
+ const resolved = new Set();
84
+ for (const include of includes) {
85
+ const colonIndex = include.indexOf(':');
86
+ const baseName = colonIndex >= 0 ? include.substring(0, colonIndex) : include;
87
+ const modifier = colonIndex >= 0 ? include.substring(colonIndex + 1) : undefined;
88
+ const keys = mixinKeys.get(baseName);
89
+ if (!keys) {
90
+ continue;
91
+ }
92
+ for (const key of keys) {
93
+ if (modifier) {
94
+ resolved.add(modifier + key);
95
+ }
96
+ else {
97
+ resolved.add(key);
98
+ }
99
+ }
100
+ }
101
+ return resolved;
102
+ }
103
+ /**
104
+ * @description Deep-clones a value and replaces occurrences of the source theme prefix with the target theme prefix
105
+ * in all CSS variable references (e.g. `--memphis-` → `--joy-`).
106
+ * @public
107
+ */
108
+ export function replaceThemePrefix(value, sourceTheme, targetTheme) {
109
+ if (typeof value === 'string') {
110
+ return value.replaceAll(`--${sourceTheme}-`, `--${targetTheme}-`);
111
+ }
112
+ if (Array.isArray(value)) {
113
+ return value.map(item => replaceThemePrefix(item, sourceTheme, targetTheme));
114
+ }
115
+ if (value !== null && typeof value === 'object') {
116
+ const result = {};
117
+ for (const [objKey, objVal] of Object.entries(value)) {
118
+ result[objKey] = replaceThemePrefix(objVal, sourceTheme, targetTheme);
119
+ }
120
+ return result;
121
+ }
122
+ return value;
123
+ }
124
+ // #endregion
125
+ //# sourceMappingURL=utils.js.map
package/utils.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}