@sugarcube-org/core 0.0.1-alpha.2 → 0.0.1-alpha.4

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 (3) hide show
  1. package/dist/index.d.ts +714 -215
  2. package/dist/index.js +19 -9
  3. package/package.json +17 -5
package/dist/index.d.ts CHANGED
@@ -1,79 +1,193 @@
1
- type Files = Record<string, string>;
2
- type CollectionMode = {
3
- name: string;
4
- files: string[];
1
+ import { z } from 'zod';
2
+
3
+ type ColorFormat = "hex" | "rgb" | "rgba" | "hsl" | "hsla" | "oklch" | "p3";
4
+ type ColorConfig = {
5
+ format?: ColorFormat;
5
6
  };
6
- type Collection = {
7
- name: string;
8
- modes?: CollectionMode[];
9
- files?: string[];
7
+ type FluidConfig = {
8
+ min: number;
9
+ max: number;
10
10
  };
11
- type ColorFormat = StandardColorFormat | FeatureDependentColorFormat;
12
- type StandardColorFormat = {
13
- name: "hex" | "rgb" | "hsl";
11
+ type TokenCollection = {
12
+ source: string[];
13
+ type: "starter-kit" | "custom";
14
+ themes?: Record<string, string[]>;
14
15
  };
15
- type FeatureDependentColorFormat = {
16
- name: "p3";
17
- featureQuery: string;
16
+ type TokenCollections = Record<string, TokenCollection>;
17
+ type OptionsConfig = {
18
+ fluid?: FluidConfig;
19
+ prefix?: string;
20
+ color?: ColorFormat;
21
+ };
22
+ type DirectoriesConfig = {
23
+ tokens: string;
24
+ components?: string;
25
+ css: string;
26
+ };
27
+ type CSSOutputConfig = {
28
+ /**
29
+ * Controls how CSS variables are organized in output files:
30
+ * - When false: Generates one file per collection, combining all tokens within each collection
31
+ * (e.g., base/tokens.variables.css, ui/tokens.variables.css)
32
+ * - When true: Generates separate files by token type within each collection
33
+ * (e.g., base/colors.variables.css, base/space.variables.css)
34
+ * @default false
35
+ */
36
+ separate: boolean;
37
+ manageIndex?: boolean;
38
+ format?: "css" | "scss" | "less";
18
39
  };
19
- type ColorFormatConverter = {
20
- type: "standard" | "conditional";
21
- convert: (r: number, g: number, b: number, a: number) => string;
22
- featureQuery?: string;
40
+ type OutputConfig = {
41
+ directories: DirectoriesConfig;
42
+ css: CSSOutputConfig;
43
+ };
44
+ interface SugarcubeConfig {
45
+ tokens: TokenCollection | TokenCollections;
46
+ options?: OptionsConfig;
47
+ output: OutputConfig;
48
+ }
49
+
50
+ /**
51
+ * Represents a single CSS file output with its name and content
52
+ */
53
+ type CSSFile = {
54
+ path: string;
55
+ css: string;
23
56
  };
24
- type ColorConfig = {
25
- format: ColorFormat;
26
- converter?: ColorFormatConverter;
57
+ /**
58
+ * Represents the output from generateCSS which always returns exactly one file
59
+ */
60
+ type SingleFileOutput = [CSSFile];
61
+ /**
62
+ * Represents multiple CSS file outputs from generateSeparateFiles or generateSingleFile
63
+ */
64
+ type CSSFileOutput = CSSFile[];
65
+ /**
66
+ * Result of the CSS generation process
67
+ * For generateCSS: Contains exactly one file
68
+ * For generate: Contains one or more files
69
+ */
70
+ type CSSGenerationResult = {
71
+ output: SingleFileOutput | CSSFileOutput;
27
72
  };
28
- type ViewportDimension = {
29
- value: number;
30
- unit: "px" | "rem";
73
+
74
+ /**
75
+ * A token value that can either be a raw value or a reference
76
+ */
77
+ type TokenValue<T extends TokenType> = RawTokenValue<T> | Reference<T>;
78
+ /**
79
+ * The actual value of a token without references
80
+ */
81
+ type RawTokenValue<T extends TokenType> = T extends SimpleTokenType ? SimpleTokenValue<T> : T extends CompositeTokenType ? CompositeTokenValue<T> : never;
82
+ /**
83
+ * A reference to another token, with optional type checking
84
+ */
85
+ type Reference<T extends TokenType = TokenType> = string & {
86
+ __tokenType?: T;
31
87
  };
32
- type FluidConfig = {
33
- viewports: {
34
- min: ViewportDimension;
35
- max: ViewportDimension;
88
+ /**
89
+ * Metadata that can be attached to any node in the token tree
90
+ */
91
+ type NodeMetadata = {
92
+ $description?: string;
93
+ $extensions?: {
94
+ [key: string]: unknown;
36
95
  };
37
96
  };
38
- type OutputConfig = {
39
- directory?: string;
40
- separate?: boolean;
97
+ /**
98
+ * A single token with its value and metadata
99
+ */
100
+ type Token = NodeMetadata & {
101
+ $value: TokenValue<TokenType>;
102
+ $type?: TokenType;
41
103
  };
42
- type SugarcubeConfig = {
43
- files: Files;
44
- collections?: Collection[];
45
- fluid?: FluidConfig;
46
- color?: ColorConfig;
47
- output?: OutputConfig;
104
+ /**
105
+ * A group of tokens that can be nested. The type allows for:
106
+ * - Regular token properties (non-$ prefixed) which must be Token | TokenGroup
107
+ * - Metadata properties from NodeMetadata (like $description, $extensions)
108
+ * - $type property for type inheritance as specified in the W3C spec
109
+ * - undefined to support optional metadata properties
110
+ */
111
+ type TokenGroup = NodeMetadata & {
112
+ $type?: TokenType;
113
+ [key: string]: Token | TokenGroup | TokenType | undefined;
48
114
  };
49
-
115
+ /**
116
+ * All possible token types, either simple or composite
117
+ */
118
+ type TokenType = SimpleTokenType | CompositeTokenType;
119
+ /**
120
+ * Token types that contain a single value
121
+ */
122
+ type SimpleTokenType = "color" | "dimension" | "fluidDimension" | "duration" | "cubicBezier" | "fontFamily" | "fontWeight" | "number";
123
+ /**
124
+ * Values for simple token types
125
+ */
126
+ type SimpleTokenValue<T extends SimpleTokenType = SimpleTokenType> = T extends "color" ? Color : T extends "dimension" ? Dimension : T extends "fluidDimension" ? FluidDimension : T extends "duration" ? Duration : T extends "cubicBezier" ? CubicBezier : T extends "fontFamily" ? FontFamily : T extends "fontWeight" ? FontWeight : T extends "number" ? number : never;
127
+ /**
128
+ * Token types that contain multiple values or are structurally complex
129
+ */
130
+ type CompositeTokenType = AlwaysDecomposedType | "border" | "shadow" | "gradient" | "transition" | StructuralCompositeType;
131
+ /**
132
+ * Token types that must always be broken down into their constituent parts
133
+ */
134
+ type AlwaysDecomposedType = "typography";
135
+ /**
136
+ * Token types that define structural patterns
137
+ */
138
+ type StructuralCompositeType = "strokeStyle";
139
+ /**
140
+ * Values for composite token types
141
+ */
142
+ type CompositeTokenValue<T extends CompositeTokenType = CompositeTokenType> = T extends "typography" ? Typography : T extends "border" ? Border : T extends "shadow" ? Shadow : T extends "gradient" ? Gradient : T extends "transition" ? Transition : T extends "strokeStyle" ? StrokeStyle : never;
143
+ /**
144
+ * A color value in any valid CSS color format
145
+ */
50
146
  type Color = string;
147
+ /**
148
+ * A dimensional value with a numeric value and unit
149
+ */
51
150
  type Dimension = {
52
151
  value: number;
53
152
  unit: "px" | "rem";
54
153
  };
154
+ /**
155
+ * A fluid dimension that scales between min and max values
156
+ */
55
157
  type FluidDimension = {
56
158
  min: Dimension;
57
159
  max: Dimension;
58
160
  };
59
- type Duration = string;
161
+ /**
162
+ * A duration value with a numeric value and time unit
163
+ */
164
+ type Duration = {
165
+ value: number;
166
+ unit: "ms" | "s";
167
+ };
168
+ /**
169
+ * A cubic bezier curve defined by four control points
170
+ */
60
171
  type CubicBezier = [number, number, number, number];
172
+ /**
173
+ * A font family name or list of fallback fonts
174
+ */
61
175
  type FontFamily = string | string[];
176
+ /**
177
+ * A font weight value as either a number or semantic string
178
+ */
62
179
  type FontWeight = number | FontWeightString;
180
+ /**
181
+ * Semantic font weight names
182
+ */
63
183
  type FontWeightString = "thin" | "hairline" | "extra-light" | "ultra-light" | "light" | "normal" | "regular" | "book" | "medium" | "semi-bold" | "demi-bold" | "bold" | "extra-bold" | "ultra-bold" | "black" | "heavy" | "extra-black" | "ultra-black";
184
+ /**
185
+ * Line cap style for strokes
186
+ */
64
187
  type LineCap = "round" | "butt" | "square";
65
- type TokenType = SimpleTokenType | CompositeTokenType;
66
- type SimpleTokenType = "color" | "dimension" | "fluidDimension" | "duration" | "cubicBezier" | "fontFamily" | "fontWeight" | "number";
67
- type CompositeTokenType = AlwaysDecomposedType | "border" | "shadow" | "gradient" | "transition" | StructuralCompositeType;
68
- type AlwaysDecomposedType = "typography";
69
- type StructuralCompositeType = "strokeStyle";
70
- type Reference<T extends TokenType = TokenType> = string & {
71
- __tokenType?: T;
72
- };
73
- type TokenValue<T extends TokenType> = RawTokenValue<T> | Reference<T>;
74
- type RawTokenValue<T extends TokenType> = T extends SimpleTokenType ? SimpleTokenValue<T> : T extends CompositeTokenType ? CompositeTokenValue<T> : never;
75
- type SimpleTokenValue<T extends SimpleTokenType = SimpleTokenType> = T extends "color" ? Color : T extends "dimension" ? Dimension : T extends "fluidDimension" ? FluidDimension : T extends "duration" ? Duration : T extends "cubicBezier" ? CubicBezier : T extends "fontFamily" ? FontFamily : T extends "fontWeight" ? FontWeight : T extends "number" ? number : never;
76
- type CompositeTokenValue<T extends CompositeTokenType = CompositeTokenType> = T extends "typography" ? Typography : T extends "border" ? Border : T extends "shadow" ? Shadow : T extends "gradient" ? Gradient : T extends "transition" ? Transition : T extends "strokeStyle" ? StrokeStyle : never;
188
+ /**
189
+ * Typography token combining font properties
190
+ */
77
191
  type Typography = {
78
192
  fontFamily: TokenValue<"fontFamily">;
79
193
  fontSize: TokenValue<"dimension">;
@@ -81,22 +195,40 @@ type Typography = {
81
195
  letterSpacing?: TokenValue<"dimension">;
82
196
  lineHeight?: TokenValue<"number">;
83
197
  };
198
+ /**
199
+ * Transition token defining animation properties
200
+ */
84
201
  type Transition = {
85
202
  duration: TokenValue<"duration">;
86
203
  delay?: TokenValue<"duration">;
87
204
  timingFunction: TokenValue<"cubicBezier">;
88
205
  };
206
+ /**
207
+ * Predefined stroke style keywords
208
+ */
89
209
  type StrokeStyleKeyword = "solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "outset" | "inset";
210
+ /**
211
+ * Custom stroke style definition
212
+ */
90
213
  type StrokeStyleCustom = {
91
214
  dashArray: Array<TokenValue<"dimension">>;
92
215
  lineCap: LineCap;
93
216
  };
217
+ /**
218
+ * A stroke style that can be either a keyword or custom definition
219
+ */
94
220
  type StrokeStyle = StrokeStyleKeyword | StrokeStyleCustom;
221
+ /**
222
+ * Border token combining color, width, and style
223
+ */
95
224
  type Border = {
96
225
  color: TokenValue<"color">;
97
226
  width: TokenValue<"dimension">;
98
227
  style: StrokeStyle | Reference<"strokeStyle">;
99
228
  };
229
+ /**
230
+ * Individual shadow definition
231
+ */
100
232
  type ShadowObject = {
101
233
  color: TokenValue<"color">;
102
234
  offsetX: TokenValue<"dimension">;
@@ -105,43 +237,51 @@ type ShadowObject = {
105
237
  spread: TokenValue<"dimension">;
106
238
  inset?: boolean;
107
239
  };
240
+ /**
241
+ * Shadow token that can be single or multiple shadows
242
+ */
108
243
  type Shadow = ShadowObject | ShadowObject[];
244
+ /**
245
+ * Color stop in a gradient
246
+ */
109
247
  type GradientStop = {
110
248
  color: TokenValue<"color">;
111
- position: number;
249
+ position: number | Reference<"number">;
112
250
  };
251
+ /**
252
+ * Gradient defined as a list of color stops
253
+ */
113
254
  type Gradient = GradientStop[];
114
- type CSSProperties<T extends TokenType> = T extends SimpleTokenType ? SimpleCSSProperties : T extends AlwaysDecomposedType ? AlwaysDecomposedProperties : T extends StructuralCompositeType ? SimpleCSSProperties : never;
115
- type SimpleCSSProperties = {
116
- value: string;
117
- featureValues?: Array<{
118
- query: string;
119
- value: string;
120
- }>;
121
- };
122
- type AlwaysDecomposedProperties = CSSTypographyProperties;
123
- type CSSTypographyProperties = {
124
- "font-family": string;
125
- "font-size": string;
126
- "font-weight"?: number | string;
127
- "letter-spacing"?: string;
128
- "line-height"?: number | string;
129
- };
130
- type NodeMetadata = {
131
- $description?: string;
132
- $extensions?: {
133
- [key: string]: unknown;
134
- };
255
+
256
+ /**
257
+ * Source information for a token, tracking its collection and theme
258
+ */
259
+ type TokenSource = {
260
+ collection: string;
261
+ theme?: string;
262
+ sourcePath: string;
135
263
  };
136
- type Token = NodeMetadata & {
137
- $value: TokenValue<TokenType>;
138
- $type?: TokenType;
264
+ /**
265
+ * A complete token tree with collection and theme information
266
+ */
267
+ type TokenTree = {
268
+ collection: string;
269
+ theme?: string;
270
+ tokens: TokenGroup;
271
+ sourcePath: string;
139
272
  };
140
- type TokenGroup = {
141
- [key: string]: Token | TokenGroup;
142
- } & NodeMetadata & {
143
- $type?: TokenType;
273
+
274
+ /**
275
+ * Base error type that all other error types extend from.
276
+ * Used as the foundation for all error types in the system.
277
+ */
278
+ type BaseError = {
279
+ message: string;
144
280
  };
281
+
282
+ /**
283
+ * A flattened token with its source information and path
284
+ */
145
285
  type FlattenedToken<T extends TokenType = TokenType> = NodeMetadata & {
146
286
  $type: T;
147
287
  $value: TokenValue<T>;
@@ -149,189 +289,548 @@ type FlattenedToken<T extends TokenType = TokenType> = NodeMetadata & {
149
289
  $source: TokenSource;
150
290
  $originalPath: string;
151
291
  };
292
+ /**
293
+ * A map of flattened tokens and metadata by their lookup path, with an index for quick reference lookups
294
+ */
152
295
  type FlattenedTokens = {
153
- [lookupKey: TokenLookupKey]: FlattenedToken | NodeMetadata;
154
- };
155
- type ValidatedToken<T extends TokenType = TokenType> = FlattenedToken<T>;
156
- type ResolvedToken<T extends TokenType = TokenType> = ValidatedToken<T> & {
157
- $resolvedValue: RawTokenValue<T>;
158
- };
159
- type ResolvedTokens = {
160
- [lookupKey: TokenLookupKey]: ResolvedToken | NodeMetadata;
161
- };
162
- type ConvertedToken<T extends TokenType = TokenType> = ResolvedToken<T> & {
163
- $cssProperties: CSSProperties<T>;
164
- };
165
- type ConvertedTokens = {
166
- [lookupKey: TokenLookupKey]: ConvertedToken | NodeMetadata;
167
- };
168
- type TokenSource = {
169
- file: string;
170
- };
171
- type DesignTokens = TokenGroup;
172
- type TokenTree = {
173
- name: string;
174
- tokens: TokenGroup;
175
- };
176
- type BaseError = {
177
- message: string;
178
- };
179
- type LoadError = BaseError & {
180
- file: string;
296
+ tokens: {
297
+ [lookupKey: string]: FlattenedToken | NodeMetadata;
298
+ };
299
+ pathIndex: Map<string, string>;
181
300
  };
301
+ /**
302
+ * An error that occurred during token flattening
303
+ */
182
304
  type FlattenError = BaseError & {
183
305
  path: string;
184
306
  source: TokenSource;
185
307
  };
308
+
309
+ /**
310
+ * An error that occurred during token validation
311
+ */
186
312
  type ValidationError = BaseError & {
187
313
  path: string;
188
314
  source: TokenSource;
189
315
  };
190
- type ResolutionError = BaseError & {
191
- type: "circular" | "missing" | "type-mismatch";
192
- path: string;
193
- source: TokenSource;
194
- };
195
- type NormalizedConvertedTokens = {
196
- [collection: string]: {
197
- [mode: string]: ConvertedTokens;
198
- };
199
- };
200
316
 
201
- type LoadResult = {
202
- trees: TokenTree[];
203
- errors: LoadError[];
204
- };
205
- declare function loadTreesFromConfig(files: SugarcubeConfig["files"]): Promise<LoadResult>;
206
-
207
- declare function flatten(trees: Array<{
208
- name: string;
209
- tokens: TokenGroup;
210
- }>): {
211
- tokens: FlattenedTokens;
212
- errors: FlattenError[];
317
+ /**
318
+ * A resolved token with its final value
319
+ */
320
+ type ResolvedToken<T extends TokenType = TokenType> = NodeMetadata & {
321
+ $type: T;
322
+ $value: RawTokenValue<T>;
323
+ $path: string;
324
+ $source: TokenSource;
325
+ $originalPath: string;
326
+ $resolvedValue: RawTokenValue<T>;
213
327
  };
214
-
215
- declare function resolve(tokens: FlattenedTokens): {
216
- resolved: ResolvedTokens;
217
- errors: ResolutionError[];
328
+ /**
329
+ * A map of resolved tokens by their lookup path
330
+ */
331
+ type ResolvedTokens = {
332
+ [lookupKey: string]: ResolvedToken | NodeMetadata;
218
333
  };
219
-
220
- declare function convert(tokens: {
221
- [collection: string]: {
222
- [mode: string]: ResolvedTokens;
223
- };
224
- }, config: SugarcubeConfig): NormalizedConvertedTokens;
225
-
226
334
  /**
227
- * This function takes a JSON string representation of a token tree and converts it
228
- * into a DesignTokens object.
229
- *
230
- * @param {string} json - A JSON string representing a token tree structure.
231
- * @returns {DesignTokens} A DesignTokens object representing the parsed token structure.
232
- * @throws {SyntaxError} If the provided JSON string is not valid JSON.
233
- * @throws {TypeError} If the JSON structure doesn't match the expected DesignTokens format.
335
+ * Type of resolution error that occurred
234
336
  */
235
- declare function parseJson(json: string): DesignTokens;
236
-
237
- declare function validate(tokens: FlattenedTokens, config: SugarcubeConfig): ValidationError[];
238
-
239
- type ProcessedTree = {
240
- name: string;
241
- tokens: ResolvedTokens;
337
+ type ResolutionErrorType = "circular" | "missing" | "type-mismatch";
338
+ /**
339
+ * An error that occurred during token resolution
340
+ */
341
+ type ResolutionError = BaseError & {
342
+ type: ResolutionErrorType;
343
+ path: string;
344
+ source: TokenSource;
242
345
  };
243
- declare function processTrees(trees: Pick<TokenTree, "name">[], resolved: ResolvedTokens): ProcessedTree[];
244
346
 
245
- type CollectionModes = {
246
- [mode: string]: ResolvedTokens;
247
- };
248
- type NormalizedTokens = {
249
- default: CollectionModes;
250
- [collection: string]: CollectionModes;
251
- };
252
- type NormalizationError = ValidationError & {
253
- collection: string;
254
- mode: string;
255
- };
347
+ /**
348
+ * A warning that occurred during token normalization
349
+ */
256
350
  type NormalizationWarning = {
257
351
  type: "warning";
258
352
  message: string;
259
353
  file: string;
260
354
  collection: string;
261
- mode?: string;
355
+ theme?: string;
262
356
  };
357
+ /**
358
+ * An error that occurred during token normalization
359
+ */
360
+ type NormalizationError = ValidationError & {
361
+ collection: string;
362
+ theme: string;
363
+ };
364
+ /**
365
+ * A set of tokens for a theme, including metadata nodes
366
+ */
367
+ type ThemeTokenSet = {
368
+ default: ResolvedTokens;
369
+ [theme: string]: ResolvedTokens;
370
+ };
371
+ /**
372
+ * Normalized tokens organized by collection and theme
373
+ */
374
+ type NormalizedTokens = {
375
+ [collection: string]: ThemeTokenSet;
376
+ };
377
+ /**
378
+ * Result of the normalization process
379
+ */
263
380
  type NormalizeResult = {
264
381
  tokens: NormalizedTokens;
265
382
  errors: NormalizationError[];
266
383
  warnings: NormalizationWarning[];
267
384
  };
268
- declare function normalizeTokens(trees: ProcessedTree[], collections?: SugarcubeConfig["collections"]): NormalizeResult;
269
385
 
270
- type GenerationError = {
271
- path: string;
272
- message: string;
386
+ /**
387
+ * Result of loading token trees from files or memory
388
+ */
389
+ type LoadResult = {
390
+ trees: TokenTree[];
391
+ errors: LoadError[];
273
392
  };
274
- type GeneratedOutput = Array<{
275
- name: string;
393
+ /**
394
+ * Data structure for loading tokens from memory
395
+ */
396
+ type TokenMemoryData = Record<string, {
397
+ collection: string;
398
+ theme?: string;
276
399
  content: string;
277
400
  }>;
278
- type GenerationResult = {
279
- output: GeneratedOutput;
280
- errors: GenerationError[];
401
+ /**
402
+ * An error that occurred during token loading
403
+ */
404
+ type LoadError = BaseError & {
405
+ file: string;
281
406
  };
282
- declare function generate(tokens: NormalizedConvertedTokens, config?: OutputConfig): Promise<GenerationResult>;
283
407
 
408
+ /**
409
+ * Result of running the tokens-to-CSS pipeline
410
+ */
284
411
  type TokensToCSSPipelineResult = {
285
- output: GeneratedOutput;
412
+ output: CSSFileOutput;
286
413
  trees: TokenTree[];
287
- errors: {
288
- load: LoadError[];
289
- flatten: FlattenError[];
290
- validation: ValidationError[];
291
- resolution: ResolutionError[];
292
- generation: GenerationError[];
293
- };
294
- warnings: {
295
- normalization: Array<{
296
- type: "warning";
297
- message: string;
298
- file: string;
299
- collection: string;
300
- mode?: string;
301
- }>;
302
- };
414
+ errors: PipelineErrors;
415
+ warnings: PipelineWarnings;
303
416
  };
304
- declare function tokensToCSSPipeline(config: SugarcubeConfig): Promise<TokensToCSSPipelineResult>;
305
-
306
- type ValidationPipelineErrors = {
417
+ /**
418
+ * Common error types that can occur during pipeline execution
419
+ */
420
+ type PipelineErrors = {
307
421
  load: LoadError[];
308
422
  flatten: FlattenError[];
309
423
  validation: ValidationError[];
310
424
  resolution: ResolutionError[];
311
425
  };
426
+ /**
427
+ * Common warning types that can occur during pipeline execution
428
+ */
429
+ type PipelineWarnings = {
430
+ normalization: NormalizationWarning[];
431
+ };
432
+ /**
433
+ * Result of running the validation pipeline
434
+ */
312
435
  type ValidationPipelineResult = {
313
436
  trees: TokenTree[];
314
437
  flattenedTokens: FlattenedTokens;
315
438
  resolved: ResolvedTokens;
316
- errors: ValidationPipelineErrors;
439
+ errors: PipelineErrors;
317
440
  };
318
- declare function validationPipeline(config: SugarcubeConfig): Promise<ValidationPipelineResult>;
319
-
441
+ /**
442
+ * Options for loading tokens in the validation pipeline
443
+ */
444
+ type TokenLoader = {
445
+ type: "files";
446
+ paths: SugarcubeConfig;
447
+ } | {
448
+ type: "memory";
449
+ data: TokenMemoryData;
450
+ };
451
+ /**
452
+ * Options for configuring the validation pipeline
453
+ */
454
+ type ValidationPipelineOptions = {
455
+ loader: TokenLoader;
456
+ };
457
+ /**
458
+ * Result of running the generation pipeline
459
+ */
320
460
  type GenerationPipelineResult = {
321
- output: GeneratedOutput;
322
- errors: {
323
- generation: GenerationError[];
324
- };
325
- warnings: {
326
- normalization: Array<{
327
- type: "warning";
328
- message: string;
329
- file: string;
330
- collection: string;
331
- mode?: string;
461
+ output: CSSFileOutput;
462
+ warnings: PipelineWarnings;
463
+ };
464
+
465
+ declare function tokensToCSSPipeline(config: SugarcubeConfig, options?: {
466
+ loader?: TokenLoader;
467
+ }): Promise<TokensToCSSPipelineResult>;
468
+
469
+ declare function validationPipeline(config: SugarcubeConfig, options: ValidationPipelineOptions): Promise<ValidationPipelineResult>;
470
+
471
+ declare function generationPipeline(trees: TokenTree[], resolved: ResolvedTokens, configState: SugarcubeConfig): Promise<GenerationPipelineResult>;
472
+
473
+ declare function loadTreesFromConfig(config: SugarcubeConfig): Promise<LoadResult>;
474
+ declare function loadTreesFromMemory(data: TokenMemoryData): Promise<LoadResult>;
475
+
476
+ declare function validate(tokens: FlattenedTokens): ValidationError[];
477
+
478
+ declare function flatten(trees: TokenTree[]): {
479
+ tokens: FlattenedTokens;
480
+ errors: FlattenError[];
481
+ };
482
+
483
+ declare function resolve(tokens: FlattenedTokens): {
484
+ resolved: ResolvedTokens;
485
+ errors: ResolutionError[];
486
+ };
487
+
488
+ /**
489
+ * A processed token tree that has been filtered to only include tokens
490
+ * from its specific collection and theme, with resolved values
491
+ */
492
+ type ProcessedTree = {
493
+ collection: string;
494
+ theme?: string;
495
+ tokens: ResolvedTokens;
496
+ };
497
+
498
+ /**
499
+ * Process token trees by filtering resolved tokens based on collection and theme.
500
+ * Uses a two-level index (collection -> theme) for O(1) lookups.
501
+ */
502
+ declare function processTrees(trees: TokenTree[], resolved: ResolvedTokens): ProcessedTree[];
503
+
504
+ /**
505
+ * A token that has been converted to CSS properties
506
+ */
507
+ type ConvertedToken<T extends TokenType = TokenType> = ResolvedToken<T> & {
508
+ $cssProperties: CSSProperties<T>;
509
+ };
510
+ /**
511
+ * A collection of converted tokens
512
+ */
513
+ type ConvertedTokens = {
514
+ [lookupKey: string]: ConvertedToken | NodeMetadata;
515
+ };
516
+ /**
517
+ * A collection of converted tokens organized by theme
518
+ */
519
+ type ConvertedThemeTokenSet = {
520
+ default: ConvertedTokens;
521
+ [theme: string]: ConvertedTokens;
522
+ };
523
+ /**
524
+ * A collection of converted tokens organized by collection and theme
525
+ */
526
+ type NormalizedConvertedTokens = {
527
+ [collection: string]: ConvertedThemeTokenSet;
528
+ };
529
+ /**
530
+ * CSS property types for different token types
531
+ */
532
+ type CSSProperties<T extends TokenType> = T extends SimpleTokenType ? SimpleCSSProperties : T extends AlwaysDecomposedType ? AlwaysDecomposedProperties : T extends "border" ? CSSBorderProperties : T extends "shadow" ? CSSShadowProperties : T extends "gradient" ? CSSGradientProperties : T extends "transition" ? CSSTransitionProperties : T extends StructuralCompositeType ? SimpleCSSProperties : never;
533
+ /**
534
+ * Simple CSS properties with a single value
535
+ */
536
+ type SimpleCSSProperties = {
537
+ value: string | number;
538
+ featureValues?: Array<{
539
+ query: string;
540
+ value: string;
541
+ }>;
542
+ };
543
+ /**
544
+ * CSS properties that are always broken down into multiple properties
545
+ */
546
+ type AlwaysDecomposedProperties = CSSTypographyProperties;
547
+ /**
548
+ * CSS properties specific to typography tokens
549
+ */
550
+ type CSSTypographyProperties = {
551
+ "font-family": string;
552
+ "font-size": string;
553
+ "font-weight"?: number | string;
554
+ "letter-spacing"?: string;
555
+ "line-height"?: number | string;
556
+ };
557
+ /**
558
+ * CSS properties for specific token types
559
+ */
560
+ type CSSBorderProperties = {
561
+ value: string;
562
+ };
563
+ type CSSShadowProperties = {
564
+ value: string;
565
+ };
566
+ type CSSGradientProperties = {
567
+ value: string;
568
+ };
569
+ type CSSTransitionProperties = {
570
+ value: string;
571
+ };
572
+
573
+ declare function convert(tokens: NormalizedTokens, config: SugarcubeConfig): NormalizedConvertedTokens;
574
+
575
+ /**
576
+ * Normalizes processed token trees into a collection-theme-token structure.
577
+ *
578
+ * This stage:
579
+ * 1. Organizes tokens by collection and theme
580
+ * 2. Removes collection prefixes from token keys (e.g., "default.color.primary" -> "color.primary")
581
+ * 3. Preserves metadata nodes
582
+ * 4. Maintains theme isolation (tokens only appear in their specified theme)
583
+ *
584
+ * The output structure is:
585
+ * {
586
+ * [collection]: {
587
+ * [theme]: {
588
+ * [tokenKey]: Token
589
+ * }
590
+ * }
591
+ * }
592
+ *
593
+ * For example:
594
+ * {
595
+ * default: {
596
+ * default: { "color.primary": { $value: "#FF0000" } },
597
+ * dark: { "color.primary": { $value: "#000000" } }
598
+ * },
599
+ * components: {
600
+ * default: { "button.primary": { $value: "#00FF00" } }
601
+ * }
602
+ * }
603
+ */
604
+ declare function normalizeTokens(trees: ProcessedTree[]): NormalizeResult;
605
+
606
+ /**
607
+ * Generates CSS variable files from normalized and converted design tokens.
608
+ * Output organization is controlled by config.output.css.separate:
609
+ *
610
+ * When separate=false (default):
611
+ * - Generates one file per collection
612
+ * - Each collection's tokens are combined into a single file named 'tokens.variables.css'
613
+ * - Example for collections 'base' and 'ui':
614
+ * - base/tokens.variables.css
615
+ * - ui/tokens.variables.css
616
+ *
617
+ * When separate=true:
618
+ * - Generates multiple files per collection, based on source filenames
619
+ * - Files are organized in directories by collection name
620
+ * - Example for collection 'base' with source 'base.json' and collection 'ui' with source 'ui.json':
621
+ * - base/base.variables.css
622
+ * - ui/ui.variables.css
623
+ *
624
+ * Note: Each collection gets its own directory regardless of the 'separate' setting.
625
+ * This maintains a clear separation between different token collections.
626
+ */
627
+ declare function generate(tokens: NormalizedConvertedTokens, config: SugarcubeConfig): Promise<CSSGenerationResult>;
628
+
629
+ /**
630
+ * Adds a warning banner to generated CSS content
631
+ */
632
+ declare function addWarningBanner(cssContent: string): string;
633
+ /**
634
+ * Gets the token file paths from config for use in warning banners
635
+ */
636
+ declare function getTokenPathsFromConfig(config: SugarcubeConfig): string[];
637
+ /**
638
+ * Writes CSS files to disk with directory creation
639
+ */
640
+ declare function writeCSSFilesToDisk(output: CSSFileOutput, addBanner?: boolean, tokenPaths?: string[]): Promise<CSSFileOutput>;
641
+
642
+ /**
643
+ * Validates the configuration object against the schema
644
+ */
645
+ declare function validateConfig(config: Partial<SugarcubeConfig>): SugarcubeConfig;
646
+ /**
647
+ * Parses and validates a JSON configuration string
648
+ */
649
+ declare function parseAndValidateConfig(configString: string): SugarcubeConfig;
650
+
651
+ /**
652
+ * Loads and validates the config file from disk
653
+ */
654
+ declare function loadConfig(configPath?: string): Promise<SugarcubeConfig>;
655
+
656
+ /**
657
+ * Manages the CSS index file that imports all CSS files.
658
+ * @param options.cssOutputDirectory - Directory where the index.css will be created/updated
659
+ * @param options.files - CSS files to include in the index
660
+ * @returns Path to the generated index file
661
+ */
662
+ declare function manageCSSIndex({ cssOutputDirectory, files, }: {
663
+ cssOutputDirectory: string;
664
+ files: string[];
665
+ }): Promise<string>;
666
+
667
+ /**
668
+ * Schema for configuration
669
+ */
670
+ declare const configSchema: z.ZodObject<{
671
+ tokens: z.ZodUnion<[z.ZodObject<{
672
+ source: z.ZodArray<z.ZodString, "many">;
673
+ type: z.ZodEnum<["starter-kit", "custom"]>;
674
+ themes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
675
+ }, "strip", z.ZodTypeAny, {
676
+ source: string[];
677
+ type: "starter-kit" | "custom";
678
+ themes?: Record<string, string[]> | undefined;
679
+ }, {
680
+ source: string[];
681
+ type: "starter-kit" | "custom";
682
+ themes?: Record<string, string[]> | undefined;
683
+ }>, z.ZodRecord<z.ZodString, z.ZodObject<{
684
+ source: z.ZodArray<z.ZodString, "many">;
685
+ type: z.ZodEnum<["starter-kit", "custom"]>;
686
+ themes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
687
+ }, "strip", z.ZodTypeAny, {
688
+ source: string[];
689
+ type: "starter-kit" | "custom";
690
+ themes?: Record<string, string[]> | undefined;
691
+ }, {
692
+ source: string[];
693
+ type: "starter-kit" | "custom";
694
+ themes?: Record<string, string[]> | undefined;
695
+ }>>]>;
696
+ options: z.ZodOptional<z.ZodObject<{
697
+ fluid: z.ZodOptional<z.ZodObject<{
698
+ min: z.ZodNumber;
699
+ max: z.ZodNumber;
700
+ }, "strict", z.ZodTypeAny, {
701
+ min: number;
702
+ max: number;
703
+ }, {
704
+ min: number;
705
+ max: number;
706
+ }>>;
707
+ prefix: z.ZodOptional<z.ZodString>;
708
+ color: z.ZodOptional<z.ZodEnum<["hex", "rgb", "rgba", "hsl", "hsla", "oklch", "p3"]>>;
709
+ }, "strip", z.ZodTypeAny, {
710
+ color?: "hex" | "rgb" | "rgba" | "hsl" | "hsla" | "oklch" | "p3" | undefined;
711
+ fluid?: {
712
+ min: number;
713
+ max: number;
714
+ } | undefined;
715
+ prefix?: string | undefined;
716
+ }, {
717
+ color?: "hex" | "rgb" | "rgba" | "hsl" | "hsla" | "oklch" | "p3" | undefined;
718
+ fluid?: {
719
+ min: number;
720
+ max: number;
721
+ } | undefined;
722
+ prefix?: string | undefined;
723
+ }>>;
724
+ output: z.ZodObject<{
725
+ directories: z.ZodObject<{
726
+ tokens: z.ZodString;
727
+ components: z.ZodOptional<z.ZodString>;
728
+ css: z.ZodString;
729
+ }, "strip", z.ZodTypeAny, {
730
+ css: string;
731
+ tokens: string;
732
+ components?: string | undefined;
733
+ }, {
734
+ css: string;
735
+ tokens: string;
736
+ components?: string | undefined;
737
+ }>;
738
+ css: z.ZodObject<{
739
+ separate: z.ZodBoolean;
740
+ manageIndex: z.ZodOptional<z.ZodBoolean>;
741
+ format: z.ZodOptional<z.ZodEnum<["css", "scss", "less"]>>;
742
+ }, "strip", z.ZodTypeAny, {
743
+ separate: boolean;
744
+ manageIndex?: boolean | undefined;
745
+ format?: "css" | "scss" | "less" | undefined;
746
+ }, {
747
+ separate: boolean;
748
+ manageIndex?: boolean | undefined;
749
+ format?: "css" | "scss" | "less" | undefined;
332
750
  }>;
751
+ }, "strip", z.ZodTypeAny, {
752
+ css: {
753
+ separate: boolean;
754
+ manageIndex?: boolean | undefined;
755
+ format?: "css" | "scss" | "less" | undefined;
756
+ };
757
+ directories: {
758
+ css: string;
759
+ tokens: string;
760
+ components?: string | undefined;
761
+ };
762
+ }, {
763
+ css: {
764
+ separate: boolean;
765
+ manageIndex?: boolean | undefined;
766
+ format?: "css" | "scss" | "less" | undefined;
767
+ };
768
+ directories: {
769
+ css: string;
770
+ tokens: string;
771
+ components?: string | undefined;
772
+ };
773
+ }>;
774
+ }, "strip", z.ZodTypeAny, {
775
+ tokens: {
776
+ source: string[];
777
+ type: "starter-kit" | "custom";
778
+ themes?: Record<string, string[]> | undefined;
779
+ } | Record<string, {
780
+ source: string[];
781
+ type: "starter-kit" | "custom";
782
+ themes?: Record<string, string[]> | undefined;
783
+ }>;
784
+ output: {
785
+ css: {
786
+ separate: boolean;
787
+ manageIndex?: boolean | undefined;
788
+ format?: "css" | "scss" | "less" | undefined;
789
+ };
790
+ directories: {
791
+ css: string;
792
+ tokens: string;
793
+ components?: string | undefined;
794
+ };
333
795
  };
334
- };
335
- declare function generationPipeline(trees: TokenTree[], resolved: ResolvedTokens, configState: any): Promise<GenerationPipelineResult>;
796
+ options?: {
797
+ color?: "hex" | "rgb" | "rgba" | "hsl" | "hsla" | "oklch" | "p3" | undefined;
798
+ fluid?: {
799
+ min: number;
800
+ max: number;
801
+ } | undefined;
802
+ prefix?: string | undefined;
803
+ } | undefined;
804
+ }, {
805
+ tokens: {
806
+ source: string[];
807
+ type: "starter-kit" | "custom";
808
+ themes?: Record<string, string[]> | undefined;
809
+ } | Record<string, {
810
+ source: string[];
811
+ type: "starter-kit" | "custom";
812
+ themes?: Record<string, string[]> | undefined;
813
+ }>;
814
+ output: {
815
+ css: {
816
+ separate: boolean;
817
+ manageIndex?: boolean | undefined;
818
+ format?: "css" | "scss" | "less" | undefined;
819
+ };
820
+ directories: {
821
+ css: string;
822
+ tokens: string;
823
+ components?: string | undefined;
824
+ };
825
+ };
826
+ options?: {
827
+ color?: "hex" | "rgb" | "rgba" | "hsl" | "hsla" | "oklch" | "p3" | undefined;
828
+ fluid?: {
829
+ min: number;
830
+ max: number;
831
+ } | undefined;
832
+ prefix?: string | undefined;
833
+ } | undefined;
834
+ }>;
336
835
 
337
- export { type GeneratedOutput, type GenerationResult, type ResolutionError, type ResolvedTokens, type TokenTree, type ValidationError, convert, flatten, generate, generationPipeline, loadTreesFromConfig, normalizeTokens, parseJson, processTrees, resolve, tokensToCSSPipeline, validate, validationPipeline };
836
+ export { type CSSFileOutput, type CSSGenerationResult, type CSSOutputConfig, type ColorConfig, type ColorFormat, type DirectoriesConfig, type FluidConfig, type LoadError, type LoadResult, type OptionsConfig, type OutputConfig, type ResolutionError, type ResolvedToken, type ResolvedTokens, type SugarcubeConfig, type TokenCollection, type TokenCollections, type TokenLoader, type TokenMemoryData, type TokenSource, type TokenTree, type ValidationError, addWarningBanner, configSchema, convert, flatten, generate, generationPipeline, getTokenPathsFromConfig, loadConfig, loadTreesFromConfig, loadTreesFromMemory, manageCSSIndex, normalizeTokens, parseAndValidateConfig, processTrees, resolve, tokensToCSSPipeline, validate, validateConfig, validationPipeline, writeCSSFilesToDisk };
package/dist/index.js CHANGED
@@ -1,13 +1,23 @@
1
- var Q=Object.defineProperty;var n=(e,t)=>Q(e,"name",{value:t,configurable:!0});import{readFile as ee}from"fs/promises";import te from"fast-glob";import re from"node:path";const u={LOAD:{FILE_NOT_FOUND:n(e=>`File not found: ${e}`,"FILE_NOT_FOUND"),INVALID_JSON:n((e,t)=>`Invalid JSON in file ${e}: ${t}`,"INVALID_JSON"),READ_ERROR:n((e,t)=>`Error reading file ${e}: ${t}`,"READ_ERROR"),INVALID_SOURCE:n(e=>`Invalid source: expected string or array of file descriptors, got ${typeof e}`,"INVALID_SOURCE"),NO_FILES_FOUND:n(e=>`No files found matching pattern: ${e}.`,"NO_FILES_FOUND"),GLOB_ERROR:n((e,t)=>`Error resolving glob pattern ${e}: ${t}`,"GLOB_ERROR"),EMPTY_CONFIG:n(()=>"No token files specified in sugarcube.config.json","EMPTY_CONFIG")},PARSE:{INVALID_INPUT_TYPE:n(e=>`Invalid input: expected string, got ${e}`,"INVALID_INPUT_TYPE"),JSON_PARSE_ERROR:n(e=>`JSON parsing error: ${e}`,"JSON_PARSE_ERROR"),UNEXPECTED_ERROR:n(e=>`Unexpected error during parsing: ${e}`,"UNEXPECTED_ERROR")},FLATTEN:{INVALID_TOKEN_NAME:n(e=>`Invalid token name '${e}': cannot contain '.', '{', or '}'`,"INVALID_TOKEN_NAME"),INVALID_NODE_STRUCTURE:n(e=>`Invalid node structure at '${e}': expected object`,"INVALID_NODE_STRUCTURE"),MISSING_INHERITED_TYPE:n(e=>`Token at '${e}' has no type (neither explicit nor inherited)`,"MISSING_INHERITED_TYPE")},METADATA:{COLLECTION_ERROR:n(e=>`Error collecting metadata: ${e}`,"COLLECTION_ERROR"),INVALID_EXTENSIONS:n(e=>`Invalid extensions at '${e}': expected object, got ${typeof e}`,"INVALID_EXTENSIONS"),INVALID_DESCRIPTION:n(e=>`Invalid description at '${e}': expected string, got ${typeof e}`,"INVALID_DESCRIPTION")},VALIDATE:{MISSING_TYPE:n(e=>`Token at '${e}' is missing the "$type" property`,"MISSING_TYPE"),MISSING_VALUE:n(e=>`Token at '${e}' is missing the "$value" property`,"MISSING_VALUE"),UNKNOWN_TOKEN_TYPE:n((e,t)=>`Unknown token type '${e}' at '${t}'. Valid types are: color, dimension, fontFamily, fontWeight, duration, cubicBezier, strokeStyle, border, transition, shadow, gradient, typography`,"UNKNOWN_TOKEN_TYPE"),INVALID_COLOR:n((e,t)=>`Invalid color at '${t}': '${e}'. Color should be a valid hex value`,"INVALID_COLOR"),INVALID_DIMENSION:n((e,t)=>`Invalid dimension at '${t}': ${e}. Dimensions should have a numeric value and unit, like { "value": 16, "unit": "px" }`,"INVALID_DIMENSION"),INVALID_DIMENSION_UNIT:n((e,t)=>`Invalid unit at '${t}': ${e}. Unit must be either "px" or "rem"`,"INVALID_DIMENSION_UNIT"),INVALID_FONT_FAMILY:n((e,t)=>`Invalid font family at '${t}': ${e}. Should be a string or array of strings, like "Arial" or ["Arial", "sans-serif"]`,"INVALID_FONT_FAMILY"),INVALID_FONT_WEIGHT:n((e,t)=>`Invalid font weight at '${t}': ${e}. Should be a number between 1-1000 or a keyword like "thin", "light", "normal", "bold"`,"INVALID_FONT_WEIGHT"),INVALID_DURATION:n((e,t)=>`Invalid duration at '${t}': ${e}. Should be like { "value": 300, "unit": "ms" }`,"INVALID_DURATION"),INVALID_DURATION_UNIT:n((e,t)=>`Invalid unit at '${t}': ${e}. Unit must be "ms" or "s"`,"INVALID_DURATION_UNIT"),INVALID_CUBIC_BEZIER:n((e,t)=>`Invalid cubic bezier at '${t}': ${e}. Should be an array of 4 numbers between 0 and 1`,"INVALID_CUBIC_BEZIER"),INVALID_CUBIC_BEZIER_RANGE:n((e,t)=>`Invalid cubic bezier control points at '${t}': ${e}. X values must be between 0 and 1`,"INVALID_CUBIC_BEZIER_RANGE"),INVALID_STROKE_STYLE:n((e,t)=>`Invalid stroke style at '${t}': ${e}. Should be "solid", "dashed", "dotted", etc.`,"INVALID_STROKE_STYLE"),INVALID_STROKE_LINE_CAP:n((e,t)=>`Invalid line cap at '${t}': ${e}. Should be one of: round, butt, square`,"INVALID_STROKE_LINE_CAP"),INVALID_BORDER:n((e,t)=>`Invalid border at '${t}': ${e}. Should have color, width, and style properties`,"INVALID_BORDER"),INVALID_SHADOW:n((e,t)=>`Invalid shadow at '${t}': ${e}. Should have color, offsetX, offsetY properties (blur and spread are optional)`,"INVALID_SHADOW"),INVALID_SHADOW_INSET:n((e,t)=>`Invalid inset value at '${t}': ${e}. Should be true or false`,"INVALID_SHADOW_INSET"),INVALID_TRANSITION:n((e,t)=>`Invalid transition at '${t}': ${e}. Should have duration, delay, and timingFunction properties`,"INVALID_TRANSITION"),INVALID_GRADIENT:n((e,t)=>`Invalid gradient at '${t}': ${e}. Should be an array of color stops with position values between 0 and 1`,"INVALID_GRADIENT"),INVALID_GRADIENT_STOP_POSITION:n((e,t)=>`Invalid gradient stop position at '${t}': ${e}. Position must be between 0 and 1`,"INVALID_GRADIENT_STOP_POSITION"),INVALID_TYPOGRAPHY:n((e,t)=>`Invalid typography at '${t}': ${e}. Should have fontFamily and fontSize (fontWeight, letterSpacing, and lineHeight are optional)`,"INVALID_TYPOGRAPHY"),MISSING_REQUIRED_PROPERTY:n((e,t)=>`Missing required property '${e}' at '${t}'`,"MISSING_REQUIRED_PROPERTY"),INVALID_NUMBER:n((e,t)=>`Invalid number at '${t}': ${e}. Expected a number value`,"INVALID_NUMBER"),INVALID_ARRAY:n((e,t)=>`Invalid array at '${t}': ${e}. Expected an array value`,"INVALID_ARRAY"),MISSING_FLUID_CONFIG:n(e=>`Missing fluid configuration at root level. Token at '${e}' requires fluid viewport settings`,"MISSING_FLUID_CONFIG"),INVALID_FLUID_DIMENSION:n((e,t)=>`Invalid fluid dimension at '${t}': ${e}. Fluid dimensions should have min and max values, like { "min": { "value": 16, "unit": "px" }, "max": { "value": 24, "unit": "px" } }`,"INVALID_FLUID_DIMENSION"),INVALID_VIEWPORT_CONFIG:n((e,t)=>`Invalid viewport configuration at '${t}': ${e}. Viewport config should have min and max dimension values`,"INVALID_VIEWPORT_CONFIG"),MISMATCHED_UNITS:n((e,t,r)=>`Mismatched units at '${r}': min uses '${e}', max uses '${t}'. Both values must use the same unit`,"MISMATCHED_UNITS"),INVALID_FLUID_VALUE_RANGE:n(e=>`Invalid fluid value range at '${e}': min value must be less than max value`,"INVALID_FLUID_VALUE_RANGE"),INVALID_TOKEN_TYPE:n((e,t,r)=>`Invalid token type at '${r}': expected ${e}, got ${t}`,"INVALID_TOKEN_TYPE"),INVALID_TYPE:n((e,t,r)=>`Expected ${e}, received ${typeof t} at '${r}'`,"INVALID_TYPE"),INVALID_ENUM_VALUE:n((e,t,r)=>`Expected value to be one of [${e.join(", ")}], but got ${String(t)} at ${r}`,"INVALID_ENUM_VALUE")},RESOLVE:{CIRCULAR_REFERENCE:n((e,t)=>`Circular reference detected: ${e} -> ${t}`,"CIRCULAR_REFERENCE"),REFERENCE_NOT_FOUND:n((e,t)=>`Reference not found: ${t} in ${e}`,"REFERENCE_NOT_FOUND"),TYPE_MISMATCH:n(e=>`Type mismatch in reference resolution at ${e}`,"TYPE_MISMATCH")},NORMALIZE:{DUPLICATE_FILE_WARNING:n((e,t)=>`Warning: File '${e}' is assigned to multiple collections without modes (in '${t}'). This will create duplicate CSS variables in :root since collections without modes default to root scope.`,"DUPLICATE_FILE_WARNING"),DUPLICATE_MODE_WARNING:n((e,t,r)=>`Warning: File '${e}' is assigned to multiple modes in collection '${t}' (in '${r}'). This means the same token values will be duplicated across different theme selectors.`,"DUPLICATE_MODE_WARNING")},GENERATE:{INVALID_CSS_VALUE:n((e,t)=>`Invalid CSS value for property '${e}': ${t}`,"INVALID_CSS_VALUE"),INVALID_VARIABLE_NAME:n((e,t)=>`Invalid CSS variable name at '${e}': ${t}`,"INVALID_VARIABLE_NAME")}};async function ne(e){const t={files:{},errors:[]};for(const[r,i]of Object.entries(e))try{const o=!i.includes("*")&&!i.endsWith(".json")?re.join(i,"**/*.json"):i,s=await te(o,{absolute:!0,onlyFiles:!0});if(s.length===0){t.errors.push({pattern:i,error:u.LOAD.NO_FILES_FOUND(i)});continue}t.files[r]=s}catch(o){t.errors.push({pattern:i,error:u.LOAD.GLOB_ERROR(i,o instanceof Error?o.message:"Unknown error")})}return t}n(ne,"resolveFiles");async function oe(e){try{const t=await ee(e,"utf-8");return JSON.parse(t)}catch(t){throw t instanceof Error?t instanceof SyntaxError?new Error(u.LOAD.INVALID_JSON(e,t.message)):"code"in t&&t.code==="ENOENT"?new Error(u.LOAD.FILE_NOT_FOUND(e)):new Error(u.LOAD.READ_ERROR(e,t.message)):new Error(u.LOAD.READ_ERROR(e,"Unknown error"))}}n(oe,"loadTree");async function L(e){const t=[],r=[];if(Object.keys(e).length===0)return{trees:[],errors:[{file:"",message:u.LOAD.EMPTY_CONFIG()}]};const{files:i,errors:o}=await ne(e);t.push(...o.map(s=>({file:s.pattern,message:s.error})));for(const[s,a]of Object.entries(i))for(const c of a)try{const f=await oe(c);r.push({name:s,tokens:f})}catch(f){t.push({file:c,message:f instanceof Error?f.message:"Unknown error"})}return{trees:r,errors:t}}n(L,"loadTreesFromConfig");function ie(e,t){const r={},i=[];(e.$description||e.$extensions)&&(r[t.file]={$description:e.$description,$extensions:e.$extensions});function o(s,a=[],c){if(a.length>0&&(s.$description||s.$extensions)&&(r[`${t.file}.${a.join(".")}`]={$description:s.$description,$extensions:s.$extensions}),"$value"in s)return;const f=s.$type||c,d=Object.keys(s).filter(l=>!l.startsWith("$"));for(const l of d){const I=s[l];if(l.includes(".")||l.includes("{")||l.includes("}")){i.push({path:[...a,l].join("."),source:t,message:u.FLATTEN.INVALID_TOKEN_NAME(l)});continue}const m=[...a,l];if("$value"in I){if(!f&&!I.$type){i.push({path:m.join("."),source:t,message:u.FLATTEN.MISSING_INHERITED_TYPE(m.join("."))});continue}r[`${t.file}.${m.join(".")}`]={...I,$type:I.$type||f,$path:m.join("."),$source:t,$originalPath:m.join(".")}}else o(I,m,f)}}return n(o,"processNode"),o(e),{tokens:r,errors:i}}n(ie,"flattenTree");function b(e){return e.reduce((t,{name:r,tokens:i})=>{const{tokens:o,errors:s}=ie(i,{file:r});return{tokens:{...t.tokens,...o},errors:[...t.errors,...s]}},{tokens:{},errors:[]})}n(b,"flatten");function p(e){return typeof e=="string"&&e.startsWith("{")&&e.endsWith("}")}n(p,"isReference");function g(e,t,r,i){return typeof t=="string"&&p(t)?se(e,t,r,i):Array.isArray(t)?t.map(o=>g(e,o,r,i)):typeof t=="object"&&t!==null?Object.entries(t).reduce((s,[a,c])=>({...s,[a]:g(`${e}.${a}`,c,r,i)}),{}):t}n(g,"resolveValue");function V(e){const t={},r=new Set,i=[];for(const[o,s]of Object.entries(e))try{if(!("$value"in s)){t[o]=s;continue}const a=s;t[o]={...a,$resolvedValue:g(a.$path,a.$value,e,r)}}catch(a){const c=a instanceof Error?a.message:String(a),f=s,d=f.$path,l=f.$source;let I,m;c.includes("Circular reference detected")?(I="circular",m=c):c.includes("Reference not found")?(I="missing",m=c):(I="type-mismatch",m=u.RESOLVE.TYPE_MISMATCH(d)),i.push({type:I,path:d,source:l,message:m})}return{resolved:t,errors:i}}n(V,"resolve");function se(e,t,r,i){const o=t.slice(1,-1),s=Object.keys(r).find(f=>{const d=r[f];return d?"$originalPath"in d&&d.$originalPath===o:!1});if(!s)throw new Error(`Reference not found: ${o} in ${e}`);if(i.has(s))throw new Error(`Circular reference detected: ${e} -> ${s}`);const a=r[s];if(!a||!("$value"in a))throw new Error(`Reference not found: ${o} in ${e}`);i.add(s);const c=g(s,a.$value,r,i);return i.delete(s),c}n(se,"resolveReferenceChain");function E(e){return["serif","sans-serif","monospace","cursive","fantasy","system-ui","ui-serif","ui-sans-serif","ui-monospace","ui-rounded","emoji","math","fangsong"].includes(e.toLowerCase())?e:/[\s'"!@#$%^&*()=+[\]{};:|\\/,.<>?~]/.test(e)?`"${e}"`:e}n(E,"quoteFont");const ae={thin:100,hairline:100,"extra-light":200,"ultra-light":200,light:300,normal:400,regular:400,book:400,medium:500,"semi-bold":600,"demi-bold":600,bold:700,"extra-bold":800,"ultra-bold":800,black:900,heavy:900,"extra-black":950,"ultra-black":950};function x(e){return p(e)?{value:e}:typeof e=="number"?{value:e}:{value:ae[e.toLowerCase()]??e}}n(x,"convertFontWeightToken");function ce(e){if(p(e))return{"font-family":e,"font-size":e};const t={"font-family":p(e.fontFamily)?e.fontFamily:Array.isArray(e.fontFamily)?e.fontFamily.map(r=>E(r)).join(", "):E(e.fontFamily),"font-size":p(e.fontSize)?e.fontSize:`${e.fontSize.value}${e.fontSize.unit}`};return e.fontWeight&&(t["font-weight"]=p(e.fontWeight)?e.fontWeight:x(e.fontWeight).value),e.letterSpacing&&(t["letter-spacing"]=p(e.letterSpacing)?e.letterSpacing:`${e.letterSpacing.value}${e.letterSpacing.unit}`),e.lineHeight&&(t["line-height"]=(p(e.lineHeight),e.lineHeight)),t}n(ce,"convertTypographyToken");function ue(e){if(p(e))return{value:e};const t=(p(e.duration),e.duration),r=p(e.timingFunction)?e.timingFunction:`cubic-bezier(${e.timingFunction.join(", ")})`,i=e.delay&&(p(e.delay),e.delay);return{value:[t,r,i].filter(Boolean).join(" ")}}n(ue,"convertTransitionToken");function fe(e){return p(e)?{value:e}:{value:`cubic-bezier(${e.join(", ")})`}}n(fe,"convertCubicBezierToken");function le(e){return p(e)?{value:e}:{value:e}}n(le,"convertNumberToken");function de(e){return p(e)?{value:e}:{value:e.toString()}}n(de,"convertDurationToken");function P(e){return p(e)?{value:e}:typeof e=="string"?{value:e}:{value:`${e.dashArray.map(r=>p(r)?r:`${r.value}${r.unit}`).join(" ")} ${e.lineCap}`}}n(P,"convertStrokeStyleToken");function pe(e){if(p(e))return{value:e};const t=p(e.width)?e.width:`${e.width.value}${e.width.unit}`,r=(p(e.color),e.color),i=typeof e.style=="string"?e.style:P(e.style).value;return{value:`${t} ${i} ${r}`}}n(pe,"convertBorderToken");function U(e){const t=p(e.offsetX)?e.offsetX:`${e.offsetX.value}${e.offsetX.unit}`,r=p(e.offsetY)?e.offsetY:`${e.offsetY.value}${e.offsetY.unit}`,i=p(e.blur)?e.blur:`${e.blur.value}${e.blur.unit}`,o=p(e.spread)?e.spread:`${e.spread.value}${e.spread.unit}`,s=(p(e.color),e.color);return`${e.inset?"inset ":""}${t} ${r} ${i} ${o} ${s}`}n(U,"convertSingleShadow");function Ie(e){return p(e)?{value:e}:Array.isArray(e)?{value:e.map(U).join(", ")}:{value:U(e)}}n(Ie,"convertShadowToken");function me(e){return p(e)?{value:e}:{value:`linear-gradient(${e.map(r=>`${p(r.color),r.color} ${r.position}%`).join(", ")})`}}n(me,"convertGradientToken");function $e(e){return p(e)?{value:e}:{value:Array.isArray(e)?e.map(r=>E(r)).join(", "):E(e)}}n($e,"convertFontFamilyToken");function he(e){return p(e)?{value:e}:{value:`${e.value}${e.unit}`}}n(he,"convertDimensionToken");function T(e,t=16){return e.unit==="px"?e.value:e.value*t}n(T,"normalizeToPixels");function Ae(e,t){const{min:r,max:i}=e,{viewports:o}=t.fluidConfig,s=16,a=T(r,s),c=T(i,s),f=T(o.min,s),d=T(o.max,s);if(a===c)return{value:`${a/s}rem`};const l=a/s,I=c/s,m=f/s,A=d/s,y=(I-l)/(A-m),_=-1*m*y+l;return{value:`clamp(${l}rem, ${_.toFixed(2)}rem + ${(y*100).toFixed(2)}vw, ${I}rem)`}}n(Ae,"convertFluidDimension");function ye(e,t){return p(e)?{value:e}:Ae(e,t)}n(ye,"convertFluidDimensionToken");function ge(e,t,r){const i=Math.max(e,t,r),o=Math.min(e,t,r);let s=0,a=0;const c=(i+o)/2;if(i!==o){const f=i-o;switch(a=c>.5?f/(2-i-o):f/(i+o),i){case e:s=(t-r)/f+(t<r?6:0);break;case t:s=(r-e)/f+2;break;case r:s=(e-t)/f+4;break}s*=60}return[Math.round(s),Math.round(a*100),Math.round(c*100)]}n(ge,"rgbToHsl");const N=n(e=>Number.isInteger(e)?e.toString():Number(e.toFixed(3)).toString(),"formatNumber"),Ee={hex:{type:"standard",convert:n((e,t,r,i)=>{const o=n(s=>Math.round(s*255).toString(16).padStart(2,"0"),"toHex");return`#${o(e)}${o(t)}${o(r)}${i<1?o(i):""}`},"convert")},rgb:{type:"standard",convert:n((e,t,r,i)=>{const o=[e,t,r].map(s=>Math.round(s*255));return i===1?`rgb(${o.join(", ")})`:`rgba(${o.join(", ")}, ${N(i)})`},"convert")},hsl:{type:"standard",convert:n((e,t,r,i)=>{const[o,s,a]=ge(e,t,r);return i===1?`hsl(${o}, ${s}%, ${a}%)`:`hsla(${o}, ${s}%, ${a}%, ${N(i)})`},"convert")},p3:{type:"conditional",featureQuery:"@supports (color: color(display-p3 1 1 1))",convert:n((e,t,r,i)=>{const o=[e,t,r].map(N).join(" ");return i===1?`color(display-p3 ${o})`:`color(display-p3 ${o} / ${N(i)})`},"convert")}};function Te(e,t){if(p(e))return{value:e};const r=t.colorFormat||"hex";if(r==="hex")return{value:e};const i=Ee[r.name];if(!i)return{value:e};const o=e.substring(1),s=parseInt(o.substring(0,2),16)/255,a=parseInt(o.substring(2,4),16)/255,c=parseInt(o.substring(4,6),16)/255,f=o.length===8?parseInt(o.substring(6,8),16)/255:1;return i.type==="conditional"?{value:e,featureValues:[{query:i.featureQuery,value:i.convert(s,a,c,f)}]}:{value:i.convert(s,a,c,f)}}n(Te,"convertColorToken");const G={duration:de,number:le,cubicBezier:fe,color:Te,dimension:he,fluidDimension:ye,typography:ce,border:pe,shadow:Ie,gradient:me,transition:ue,strokeStyle:P,fontFamily:$e,fontWeight:x};function Ne(e,t){const r=G[e.$type];return{...e.$description?{$description:e.$description}:{},...e.$extensions?{$extensions:e.$extensions}:{},$type:e.$type,$value:e.$value,$path:e.$path,$source:e.$source,$originalPath:e.$originalPath,$resolvedValue:e.$resolvedValue,$cssProperties:r(e.$value,t)}}n(Ne,"convertSingleToken");function Se(e,t){const r={};for(const[i,o]of Object.entries(e)){if(!o||typeof o!="object")continue;if(!("$type"in o)){r[i]={...o.$description?{$description:o.$description}:{},...o.$extensions?{$extensions:o.$extensions}:{}};continue}if(!G[o.$type])continue;const s={fluidConfig:t.fluid,colorFormat:t.color?.format,path:o.$path};r[i]=Ne(o,s)}return r}n(Se,"convertTokens");function O(e,t){const r={};for(const[i,o]of Object.entries(e)){r[i]={};for(const[s,a]of Object.entries(o))r[i][s]=Se(a,t)}return r}n(O,"convert");function De(e){return JSON.parse(e)}n(De,"parseJson");const _e={isObject:n(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObject")};function $(e,t,r,i){if(p(t))return[];switch(e.type){case"object":return be(e,t,r,i);case"union":return Ve(e,t,r,i);case"array":return Oe(e,t,r,i);default:return Le(e,t,r,i)}}n($,"validateSchema");function Le(e,t,r,i){return typeof t!==e.type?[{path:r,message:e.errorMessage?.(t,r)||u.VALIDATE.INVALID_TYPE(e.type,t,r),source:i}]:e.validate?.(t,r,i)??[]}n(Le,"validateSimpleValue");function be(e,t,r,i){if(!_e.isObject(t))return[{path:r,message:e.errorMessage?.(t,r)||u.VALIDATE.INVALID_TYPE("object",t,r),source:i}];const o=[],s=t;if(e.required)for(const a of e.required)a in s||o.push({path:`${r}.${a}`,message:u.VALIDATE.MISSING_REQUIRED_PROPERTY(a,r),source:i});for(const[a,c]of Object.entries(e.properties))a in s&&o.push(...$(c,s[a],`${r}.${a}`,i));return o}n(be,"validateObject");function Ve(e,t,r,i){let o=[],s=1/0;for(const a of e.oneOf){if(a.type==="string"&&typeof t!="string"||a.type==="object"&&typeof t!="object")continue;const c=$(a,t,r,i);if(c.length===0)return e.validate?.(t,r,i)??[];c.length<s&&(o=c,s=c.length)}return s===1/0?[{path:r,message:u.VALIDATE.INVALID_TYPE(e.oneOf.map(a=>a.type).join(" or "),t,r),source:i}]:o}n(Ve,"validateUnion");function Oe(e,t,r,i){return Array.isArray(t)?e.validate?.(t,r,i)??[]:[{path:r,message:e.errorMessage?.(t,r)||u.VALIDATE.INVALID_TYPE("array",t,r),source:i}]}n(Oe,"validateArray");const S={tokenType:"color",schema:{type:"string",errorMessage:n((e,t)=>u.VALIDATE.INVALID_COLOR(e,t),"errorMessage"),validate:n((e,t,r)=>/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/.test(e)?[]:[{path:t,message:u.VALIDATE.INVALID_COLOR(e,t),source:r}],"validate")}};function Re(e,t,r){return $(S.schema,e,t,r)}n(Re,"validateColor");const D={tokenType:"number",schema:{type:"number",errorMessage:n((e,t)=>u.VALIDATE.INVALID_NUMBER(e,t),"errorMessage"),validate:n((e,t,r)=>typeof e!="number"||isNaN(e)?[{path:t,message:u.VALIDATE.INVALID_NUMBER(e,t),source:r}]:[],"validate")}};function ve(e,t,r){return $(D.schema,e,t,r)}n(ve,"validateNumber");const h={tokenType:"dimension",schema:{type:"object",errorMessage:n((e,t)=>u.VALIDATE.INVALID_DIMENSION(e,t),"errorMessage"),properties:{value:D.schema,unit:{type:"string",validate:n((e,t,r)=>typeof e!="string"||!["px","rem"].includes(e)?[{path:t,message:u.VALIDATE.INVALID_DIMENSION_UNIT(e,t),source:r}]:[],"validate")}},required:["value","unit"]}};function Fe(e,t,r){return $(h.schema,e,t,r)}n(Fe,"validateDimension");const W={tokenType:"fontFamily",schema:{type:"union",oneOf:[{type:"string",errorMessage:n((e,t)=>u.VALIDATE.INVALID_FONT_FAMILY(e,t),"errorMessage")},{type:"array",errorMessage:n((e,t)=>u.VALIDATE.INVALID_FONT_FAMILY(e,t),"errorMessage"),validate:n((e,t,r)=>e.every(o=>typeof o=="string")?[]:[{path:t,message:u.VALIDATE.INVALID_FONT_FAMILY(e,t),source:r}],"validate")}],errorMessage:n((e,t)=>u.VALIDATE.INVALID_FONT_FAMILY(e,t),"errorMessage")}};function ke(e,t,r){return $(W.schema,e,t,r)}n(ke,"validateFontFamily");const Me=["thin","hairline","extra-light","ultra-light","light","normal","regular","book","medium","semi-bold","demi-bold","bold","extra-bold","ultra-bold","black","heavy","extra-black","ultra-black"],Y={tokenType:"fontWeight",schema:{type:"union",errorMessage:n((e,t)=>u.VALIDATE.INVALID_FONT_WEIGHT(e,t),"errorMessage"),oneOf:[{type:"number",errorMessage:n((e,t)=>u.VALIDATE.INVALID_FONT_WEIGHT(e,t),"errorMessage"),validate:n((e,t,r)=>e<1||e>1e3?[{path:t,message:u.VALIDATE.INVALID_FONT_WEIGHT(e,t),source:r}]:[],"validate")},{type:"string",errorMessage:n((e,t)=>u.VALIDATE.INVALID_FONT_WEIGHT(e,t),"errorMessage"),validate:n((e,t,r)=>Me.includes(e.toLowerCase())?[]:[{path:t,message:u.VALIDATE.INVALID_FONT_WEIGHT(e,t),source:r}],"validate")}]}};function Ce(e,t,r){return $(Y.schema,e,t,r)}n(Ce,"validateFontWeight");const je=["ms","s"],R={tokenType:"duration",schema:{type:"object",errorMessage:n((e,t)=>u.VALIDATE.INVALID_DURATION(e,t),"errorMessage"),properties:{value:D.schema,unit:{type:"string",validate:n((e,t,r)=>je.includes(e)?[]:[{path:t,message:u.VALIDATE.INVALID_DURATION_UNIT(e,t),source:r}],"validate")}},required:["value","unit"]}};function we(e,t,r){return $(R.schema,e,t,r)}n(we,"validateDuration");const z={tokenType:"cubicBezier",schema:{type:"array",errorMessage:n((e,t)=>u.VALIDATE.INVALID_CUBIC_BEZIER(e,t),"errorMessage"),validate:n((e,t,r)=>{const i=e;if(i.length!==4||!i.every(a=>typeof a=="number"))return[{path:t,message:u.VALIDATE.INVALID_CUBIC_BEZIER(e,t),source:r}];const[o,,s]=i;return o<0||o>1||s<0||s>1?[{path:t,message:u.VALIDATE.INVALID_CUBIC_BEZIER_RANGE(e,t),source:r}]:[]},"validate")}};function xe(e,t,r){return $(z.schema,e,t,r)}n(xe,"validateCubicBezier");const Pe={tokenType:"typography",schema:{type:"object",properties:{fontFamily:W.schema,fontSize:h.schema,letterSpacing:h.schema,lineHeight:D.schema,fontWeight:Y.schema},required:["fontFamily","fontSize"],errorMessage:n((e,t)=>u.VALIDATE.INVALID_TYPOGRAPHY(e,t),"errorMessage")}};function Ue(e,t,r){return $(Pe.schema,e,t,r)}n(Ue,"validateTypography");const Ge=["solid","dashed","dotted","double","groove","ridge","outset","inset"],We=["round","butt","square"],Ye={type:"object",errorMessage:n((e,t)=>u.VALIDATE.INVALID_STROKE_STYLE(e,t),"errorMessage"),properties:{dashArray:{type:"array",validate:n((e,t,r)=>{const i=e,o=[];return i.forEach((s,a)=>{typeof s!="string"&&o.push(...$(h.schema,s,`${t}.${a}`,r))}),o},"validate")},lineCap:{type:"string",validate:n((e,t,r)=>We.includes(e)?[]:[{path:t,message:u.VALIDATE.INVALID_STROKE_LINE_CAP(e,t),source:r}],"validate")}},required:["dashArray","lineCap"]},B={tokenType:"strokeStyle",schema:{type:"union",oneOf:[{type:"string",validate:n((e,t,r)=>!Ge.includes(e)&&typeof e=="string"?[{path:t,message:u.VALIDATE.INVALID_STROKE_STYLE(e,t),source:r}]:[],"validate")},Ye]}};function ze(e,t,r){return $(B.schema,e,t,r)}n(ze,"validateStrokeStyle");const Be={tokenType:"border",schema:{type:"object",properties:{color:S.schema,width:h.schema,style:B.schema},required:["color","width","style"],errorMessage:n((e,t)=>u.VALIDATE.INVALID_BORDER(e,t),"errorMessage")}};function He(e,t,r){return $(Be.schema,e,t,r)}n(He,"validateBorder");const qe={tokenType:"transition",schema:{type:"object",properties:{duration:R.schema,delay:R.schema,timingFunction:z.schema},required:["duration","delay","timingFunction"],errorMessage:n((e,t)=>u.VALIDATE.INVALID_TRANSITION(e,t),"errorMessage")}};function Ke(e,t,r){return $(qe.schema,e,t,r)}n(Ke,"validateTransition");const H={tokenType:"shadow",schema:{type:"object",properties:{color:S.schema,offsetX:h.schema,offsetY:h.schema,blur:h.schema,spread:h.schema,inset:{type:"boolean",errorMessage:n((e,t)=>u.VALIDATE.INVALID_SHADOW_INSET(e,t),"errorMessage")}},required:["color","offsetX","offsetY","blur","spread"],errorMessage:n((e,t)=>u.VALIDATE.INVALID_SHADOW(e,t),"errorMessage")}};function Ze(e,t,r){const i=[];return Array.isArray(e)?(e.forEach((o,s)=>{i.push(...$(H.schema,o,`${t}[${s}]`,r))}),i):$(H.schema,e,t,r)}n(Ze,"validateShadow");const Xe={type:"object",errorMessage:n((e,t)=>u.VALIDATE.INVALID_GRADIENT(e,t),"errorMessage"),properties:{color:{type:"string",validate:S.schema.validate},position:{type:"number",validate:n((e,t,r)=>e<0||e>1?[{path:t,message:u.VALIDATE.INVALID_GRADIENT_STOP_POSITION(e,t),source:r}]:[],"validate")}},required:["color","position"]},Je={tokenType:"gradient",schema:{type:"array",errorMessage:n((e,t)=>u.VALIDATE.INVALID_ARRAY(e,t),"errorMessage"),validate:n((e,t,r)=>{const i=e,o=[];return i.forEach((s,a)=>{o.push(...$(Xe,s,`${t}[${a}]`,r))}),o},"validate")}};function Qe(e,t,r){return $(Je.schema,e,t,r)}n(Qe,"validateGradient");const et={tokenType:"fluidDimension",schema:{type:"object",errorMessage:n((e,t)=>u.VALIDATE.INVALID_FLUID_DIMENSION(e,t),"errorMessage"),properties:{min:h.schema,max:h.schema},required:["min","max"]}};function tt(e,t,r,i){const o=[];return i?.fluid?.viewports||o.push({path:t,message:u.VALIDATE.MISSING_FLUID_CONFIG(t),source:r}),o.push(...$(et.schema,e,t,r)),o}n(tt,"validateFluidDimension");const rt={color:Re,dimension:Fe,fluidDimension:tt,duration:we,cubicBezier:xe,fontFamily:ke,fontWeight:Ce,number:ve,strokeStyle:ze,typography:Ue,border:He,shadow:Ze,gradient:Qe,transition:Ke};function v(e,t){const r=[];for(const[i,o]of Object.entries(e)){if(typeof o!="object"||o===null||!("$type"in o)||!("$path"in o)||o.$path.startsWith("$"))continue;const s=rt[o.$type];if(!s){r.push({path:o.$path,message:u.VALIDATE.UNKNOWN_TOKEN_TYPE(o.$type,o.$path),source:o.$source});continue}r.push(...s(o.$value,o.$path,o.$source,t))}return r}n(v,"validate");function F(e,t){return e.map(r=>({name:r.name,tokens:Object.entries(t).reduce((i,[o,s])=>("$source"in s&&s.$source.file!==r.name||("$type"in s?s.$source.file===r.name&&(i[o]=s):i[o]=s),i),{})}))}n(F,"processTrees");function k(e,t){const r=[],i=[],o=new Map;return t?.length?{...e.reduce((a,{name:c,tokens:f})=>{let d=!1;return t.forEach(l=>{l.modes?.length&&l.modes.forEach(I=>{if(!I.files.includes(c))return;const m=o.get(c);m&&m.collection===l.name&&r.push({type:"warning",message:u.NORMALIZE.DUPLICATE_MODE_WARNING(c,l.name,I.name),file:c,collection:l.name,mode:I.name}),o.set(c,{collection:l.name,mode:I.name}),d=!0;const A=a.tokens[l.name]||{},y=A[I.name]||{};a.tokens[l.name]={...A,[I.name]:{...y,...f}}})}),d||t.forEach(l=>{if(!l.modes&&l.files?.includes(c)){const I=o.get(c);I&&!t.find(m=>m.name===I.collection)?.modes?.length&&r.push({type:"warning",message:u.NORMALIZE.DUPLICATE_FILE_WARNING(c,l.name),file:c,collection:l.name}),o.set(c,{collection:l.name}),d=!0,a.tokens[l.name]={default:{...a.tokens[l.name]?.default,...f}}}}),d||(a.tokens.default={default:{...a.tokens.default?.default,...f}}),a},{tokens:{default:{default:{}}},errors:[],warnings:[],processedFiles:new Map}),errors:i,warnings:r}:{tokens:{default:{default:e.reduce((c,{tokens:f})=>({...c,...f}),{})}},errors:[],warnings:[]}}n(k,"normalizeTokens");const q=new Map;function nt(e){const t=q.get(e);if(t)return t;const r=e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([A-Z])([A-Z])(?=[a-z])/g,"$1-$2").toLowerCase();return q.set(e,r),r}n(nt,"toKebabCase");function ot(e){return typeof e=="object"&&e!==null&&typeof e.query=="string"&&typeof e.value=="string"}n(ot,"isFeatureValue");function it(e){return typeof e!="object"||e===null||!("value"in e)||typeof e.value!="string"&&typeof e.value!="number"?!1:"featureValues"in e?Array.isArray(e.featureValues)?e.featureValues.every(ot):!1:!0}n(it,"isSimpleCSSProperties");function M(e){return!!(typeof e=="string"||typeof e=="number"||it(e))}n(M,"isValidCSSValue");function st(e){return/^--[a-zA-Z][a-zA-Z0-9-]*$/.test(e)}n(st,"isValidCSSVariableName");const K="@supports (color: color(display-p3 1 1 1))";function at(e){return e.$type==="typography"}n(at,"isTypographyToken");function C(e){return e.split(".").join("-")}n(C,"formatCSSVarPath");function Z(e){return typeof e=="number"?e:typeof e!="string"?(console.warn("Unexpected value type in convertReferenceToCSSVar, got:",e),String(e)):e.replace(/\{([^}]+)\}/g,(t,r)=>`var(--${r.split(".").map(nt).join("-")})`)}n(Z,"convertReferenceToCSSVar");function ct(e,t){const r=`--${C(e.$path)}`,i=e.$cssProperties;if(!("value"in i))return;const o=i.value;if(!M(o)){t.push({path:e.$path,message:u.GENERATE.INVALID_CSS_VALUE(e.$path,String(o))});return}if(!st(r)){t.push({path:e.$path,message:u.GENERATE.INVALID_VARIABLE_NAME(e.$path,r)});return}return{name:r,value:Z(o)}}n(ct,"generateSingleVariable");function ut(e,t){const r=[];return Object.entries(e.$cssProperties).forEach(([i,o])=>{if(o!==void 0){if(!M(o)){t.push({path:`${e.$path}-${i}`,message:u.GENERATE.INVALID_CSS_VALUE(e.$path,String(o))});return}r.push({name:`--${C(e.$path)}-${i}`,value:Z(o)})}}),r}n(ut,"generateTypographyVariables");function X(e,t){if(e.$type!=="color")return[];const r=e.$cssProperties;if(!("featureValues"in r))return[];const i=[];return r.featureValues?.forEach(o=>{if(o.query===K){if(!M(o.value)){t.push({path:e.$path,message:u.GENERATE.INVALID_CSS_VALUE(e.$path,String(o.value))});return}i.push({name:`--${C(e.$path)}`,value:o.value})}}),i}n(X,"generateFeatureVariables");function J(e){const t=[`${e.selector} {`];if(e.comment&&t.push(` /* ${e.comment} */`),e.vars.length>0){const r=e.vars.map(i=>` ${i.name}: ${i.value};`).join(`
2
- `);t.push(r)}return t.push("}"),t.join(`
3
- `)}n(J,"generateCSSBlock");function ft(e){const t=[];return e.root.vars.length>0&&t.push(J({selector:e.root.selector,vars:e.root.vars})),e.features.forEach(r=>{const o=J({selector:e.root.selector,vars:r.vars}).split(`
4
- `).map(s=>` ${s}`).join(`
5
- `);t.push(`${r.query} {
6
- ${o}
1
+ var $e=Object.defineProperty;var o=(e,t)=>$e(e,"name",{value:t,configurable:!0});import{readFile as ye}from"node:fs/promises";import Ae from"fast-glob";import Ee,{relative as L}from"node:path";import{converter as _,formatHex8 as Te,formatHex as z}from"culori";import T from"path";import Ne,{mkdir as be,readFile as Y,writeFile as B}from"fs/promises";import{existsSync as H}from"fs";import{z as m}from"zod";const u={LOAD:{NO_FILES_FOUND:o(e=>`No files found matching pattern: ${e}.`,"NO_FILES_FOUND"),INVALID_JSON:o((e,t)=>`Invalid JSON in file ${e}: ${t}`,"INVALID_JSON"),GLOB_ERROR:o((e,t)=>`Error resolving glob pattern ${e}: ${t}`,"GLOB_ERROR")},FLATTEN:{INVALID_TOKEN_NAME:o(e=>`Invalid token name "${e}": Token names cannot contain dots (.), curly braces ({,}), or other special characters`,"INVALID_TOKEN_NAME"),MISSING_DOLLAR_PREFIX:o(e=>`Token at ${e} is using 'value' or 'type' without the required '$' prefix. Use '$value' and '$type' instead.`,"MISSING_DOLLAR_PREFIX")},METADATA:{COLLECTION_ERROR:o(e=>`Error collecting metadata: ${e}`,"COLLECTION_ERROR"),INVALID_EXTENSIONS:o(e=>`Invalid extensions at ${e}: expected object, got ${typeof e}`,"INVALID_EXTENSIONS"),INVALID_DESCRIPTION:o(e=>`Invalid description at ${e}: expected string, got ${typeof e}`,"INVALID_DESCRIPTION")},VALIDATE:{MISSING_TYPE:o(e=>`Token at '${e}' is missing the "$type" property`,"MISSING_TYPE"),UNKNOWN_TOKEN_TYPE:o((e,t)=>`Unknown token type '${e}' at ${t}. Valid types are: color, dimension, fontFamily, fontWeight, duration, cubicBezier, strokeStyle, border, transition, shadow, gradient, typography`,"UNKNOWN_TOKEN_TYPE"),INVALID_COLOR:o((e,t)=>`Invalid color at ${t}: '${e}'. Color should be a valid hex value`,"INVALID_COLOR"),INVALID_DIMENSION:o((e,t)=>`Invalid dimension at '${t}': ${e}. Dimensions should have a numeric value and unit, like { "value": 16, "unit": "px" }`,"INVALID_DIMENSION"),INVALID_DIMENSION_UNIT:o((e,t)=>`Invalid unit at ${t}': '${e}'. Unit must be either "px" or "rem"`,"INVALID_DIMENSION_UNIT"),INVALID_FONT_FAMILY:o((e,t)=>`Invalid font family at '${t}': ${e}. Should be a string or array of strings, like "Arial" or ["Arial", "sans-serif"]`,"INVALID_FONT_FAMILY"),INVALID_FONT_WEIGHT:o((e,t)=>`Invalid font weight at '${t}': ${e}. Should be a number between 1-1000 or a keyword like "thin", "light", "normal", "bold"`,"INVALID_FONT_WEIGHT"),INVALID_DURATION:o((e,t)=>`Invalid duration at '${t}': ${e}. Should be like { "value": 300, "unit": "ms" }`,"INVALID_DURATION"),INVALID_DURATION_UNIT:o((e,t)=>`Invalid unit at ${t}: "${e}". Unit must be "ms" or "s"`,"INVALID_DURATION_UNIT"),INVALID_CUBIC_BEZIER:o((e,t)=>`Invalid cubic bezier at ${t}: "${e}". Should be an array of 4 numbers between 0 and 1`,"INVALID_CUBIC_BEZIER"),INVALID_STROKE_STYLE:o((e,t)=>`Invalid stroke style at ${t}: "${e}". Should be "solid", "dashed", "dotted", etc.`,"INVALID_STROKE_STYLE"),INVALID_STROKE_LINE_CAP:o((e,t)=>`Invalid line cap at ${t}: "${e}". Should be one of: round, butt, square`,"INVALID_STROKE_LINE_CAP"),INVALID_BORDER:o((e,t)=>`Invalid border at ${t}: "${e}". Should have color, width, and style properties`,"INVALID_BORDER"),INVALID_SHADOW:o((e,t)=>`Invalid shadow at ${t}: "${e}". Should have color, offsetX, offsetY properties (blur and spread are optional)`,"INVALID_SHADOW"),INVALID_SHADOW_INSET:o((e,t)=>`Invalid inset value at ${t}: "${e}". Should be true or false`,"INVALID_SHADOW_INSET"),INVALID_TRANSITION:o((e,t)=>`Invalid transition at ${t}: "${e}". Should have duration, delay, and timingFunction properties`,"INVALID_TRANSITION"),INVALID_GRADIENT:o((e,t)=>`Invalid gradient at ${t}: "${e}". Should be an array of color stops with position values between 0 and 1`,"INVALID_GRADIENT"),INVALID_GRADIENT_STOP_POSITION:o((e,t)=>`Invalid gradient stop position at ${t}: "${e}". Position must be between 0 and 1`,"INVALID_GRADIENT_STOP_POSITION"),INVALID_TYPOGRAPHY:o((e,t)=>`Invalid typography at ${t}: "${e}". Should have fontFamily and fontSize (fontWeight, letterSpacing, and lineHeight are optional)`,"INVALID_TYPOGRAPHY"),MISSING_REQUIRED_PROPERTY:o((e,t)=>`Missing required property '${e}' at ${t}`,"MISSING_REQUIRED_PROPERTY"),INVALID_NUMBER:o((e,t)=>`Invalid number at ${t}: "${e}". Expected a number value`,"INVALID_NUMBER"),INVALID_ARRAY:o((e,t)=>`Invalid array at ${t}: "${e}". Expected an array value`,"INVALID_ARRAY"),MISSING_FLUID_CONFIG:o(e=>`Missing fluid configuration. Token at ${e} requires fluid viewport settings.`,"MISSING_FLUID_CONFIG"),INVALID_FLUID_DIMENSION:o((e,t)=>`Invalid fluid dimension at ${t}: "${e}". Fluid dimensions should have min and max values, like { "min": { "value": 16, "unit": "px" }, "max": { "value": 24, "unit": "px" } }`,"INVALID_FLUID_DIMENSION"),INVALID_VIEWPORT_CONFIG:o((e,t)=>`Invalid viewport configuration at ${t}: "${e}". Viewport config should have min and max dimension values`,"INVALID_VIEWPORT_CONFIG"),MISMATCHED_UNITS:o((e,t,n)=>`Mismatched units at ${n}: min uses '${e}', max uses '${t}'. Both values must use the same unit`,"MISMATCHED_UNITS"),INVALID_FLUID_VALUE_RANGE:o(e=>`Invalid fluid value range at ${e}: min value must be less than max value`,"INVALID_FLUID_VALUE_RANGE"),INVALID_TOKEN_TYPE:o((e,t,n)=>`Invalid token type at ${n}: expected ${e}, got ${t}`,"INVALID_TOKEN_TYPE"),INVALID_TYPE:o((e,t,n)=>`Expected ${e}, received ${typeof t} at ${n}`,"INVALID_TYPE"),INVALID_ENUM_VALUE:o((e,t,n)=>`Expected value to be one of [${e.join(", ")}], but got ${String(t)} at ${n}`,"INVALID_ENUM_VALUE")},RESOLVE:{CIRCULAR_REFERENCE:o((e,t)=>`Circular reference detected: ${e} -> ${t}`,"CIRCULAR_REFERENCE"),REFERENCE_NOT_FOUND:o((e,t)=>`Reference not found: ${e} in ${t}`,"REFERENCE_NOT_FOUND"),TYPE_MISMATCH:o(e=>`Type mismatch in ${e}`,"TYPE_MISMATCH")},GENERATE:{INVALID_CSS_VALUE:o((e,t)=>`Invalid CSS value for property '${e}': ${t}`,"INVALID_CSS_VALUE"),INVALID_VARIABLE_NAME:o((e,t)=>`Invalid CSS variable name at '${e}': ${t}`,"INVALID_VARIABLE_NAME")},CONFIG:{INVALID_JSON:o(e=>`Invalid JSON in config file: ${e}`,"INVALID_JSON"),INVALID_CONFIG:o((e,t)=>`Invalid configuration at ${e}: ${t}`,"INVALID_CONFIG"),DUPLICATE_FILENAMES:o((e,t,n)=>`Duplicate filename "${t}" found in collection "${e}":
2
+ ${n.map(r=>` - ${r}`).join(`
3
+ `)}`,"DUPLICATE_FILENAMES"),FILE_NOT_FOUND:o(e=>`Cannot read config file at ${e} - check file permissions and path`,"FILE_NOT_FOUND")}};async function q(e){const t={files:[],errors:[]};for(const n of e)try{const r=!n.includes("*")&&!n.endsWith(".json")?Ee.join(n,"**/*.json"):n,s=await Ae(r,{absolute:!0,onlyFiles:!0});if(s.length===0){t.errors.push({pattern:n,error:u.LOAD.NO_FILES_FOUND(n)});continue}t.files.push(...s)}catch(r){t.errors.push({pattern:n,error:u.LOAD.GLOB_ERROR(n,r instanceof Error?r.message:"Unknown error")})}return t}o(q,"resolveFiles");async function K(e){try{const t=await ye(e,"utf-8");return JSON.parse(t)}catch(t){throw t instanceof Error&&t instanceof SyntaxError?new Error(u.LOAD.INVALID_JSON(e,t.message)):t}}o(K,"loadTree");function Se(e){const t=new Set;return e.themes&&Object.values(e.themes).forEach(n=>{n.forEach(r=>t.add(r))}),t}o(Se,"collectThemePaths");async function O(e){const t=[],n=[],r=Array.isArray(e.tokens)?{default:{source:e.tokens,type:"custom"}}:"source"in e.tokens?{default:e.tokens}:e.tokens;for(const[s,i]of Object.entries(r)){const a=Se(i),{files:c,errors:l}=await q(Array.isArray(i.source)?i.source:[i.source]);if(l.length>0){t.push(...l.map(f=>({file:f.pattern,message:f.error})));continue}for(const f of c){const p=L(process.cwd(),f);if(!a.has(p))try{const d=await K(f),I={collection:s,tokens:d,sourcePath:p};n.push(I)}catch(d){t.push({file:f,message:d instanceof Error?d.message:"Unknown error"})}}if(i.themes)for(const[f,p]of Object.entries(i.themes))try{const{files:d,errors:I}=await q(p);if(I.length>0){t.push(...I.map(g=>({file:g.pattern,message:g.error})));continue}for(const g of d)try{const y=await K(g),A={collection:s,theme:f,tokens:y,sourcePath:L(process.cwd(),g)};n.push(A)}catch(y){t.push({file:g,message:y instanceof Error?y.message:"Unknown error"})}}catch(d){t.push({file:p.join(", "),message:d instanceof Error?d.message:"Unknown error"})}}return{trees:n,errors:t}}o(O,"loadTreesFromConfig");async function V(e){const t=[],n=[],r=new Map;for(const[s,{collection:i,theme:a,content:c}]of Object.entries(e)){r.has(i)||r.set(i,new Map);const l=r.get(i);l.has(a)||l.set(a,[]),l.get(a).push({content:c,path:s})}for(const[s,i]of r)for(const[a,c]of i)for(const{content:l,path:f}of c)try{const p=JSON.parse(l);t.push({collection:s,theme:a,tokens:p,sourcePath:L(process.cwd(),f)})}catch(p){p instanceof Error?p instanceof SyntaxError?n.push({file:f,message:u.LOAD.INVALID_JSON(f,p.message)}):n.push({file:f,message:p.message}):n.push({file:f,message:"Unknown error"})}return{trees:t,errors:n}}o(V,"loadTreesFromMemory");function De(e){if(typeof e!="object"||e===null||"$value"in e)return!1;const t="value"in e,n="type"in e;if(t&&n)return!0;if(t){const r=e.value;return typeof r=="string"||typeof r=="number"||Array.isArray(r)}return!1}o(De,"looksLikeUnprefixedToken");function Le(e,t){const n={tokens:{},pathIndex:new Map},r=[];function s(a=[]){const c=[t.collection];return t.theme&&c.push(t.theme),a.length>0&&c.push(a.join(".")),c.join(".")}o(s,"createLookupKey"),(e.$description||e.$extensions)&&(n.tokens[s()]={$description:e.$description,$extensions:e.$extensions});function i(a,c=[],l){if(c.length>0){const d=s(c);n.tokens[d]={$description:a.$description,$extensions:a.$extensions,$path:c.join("."),$source:{collection:t.collection,theme:t.theme,sourcePath:t.sourcePath}}}if("$value"in a)return;const f=a.$type||l,p=Object.keys(a).filter(d=>!d.startsWith("$"));for(const d of p){const I=a[d],g=[...c,d];if(De(I)){r.push({path:g.join("."),source:t,message:u.FLATTEN.MISSING_DOLLAR_PREFIX(g.join("."))});continue}if(d.includes(".")||d.includes("{")||d.includes("}")){r.push({path:g.join("."),source:t,message:u.FLATTEN.INVALID_TOKEN_NAME(d)});continue}if("$value"in I){const y=s(g),A=g.join(".");n.tokens[y]={...I,$type:I.$type||f,$path:A,$source:{collection:t.collection,theme:t.theme,sourcePath:t.sourcePath},$originalPath:A},n.pathIndex.set(A,y)}else i(I,g,f)}}return o(i,"processNode"),i(e),{tokens:n,errors:r}}o(Le,"flattenTree");function F(e){const t={tokens:{},pathIndex:new Map},n=[];for(const r of e){const{tokens:s,errors:i}=Le(r.tokens,{collection:r.collection,theme:r.theme,sourcePath:r.sourcePath});Object.assign(t.tokens,s.tokens);for(const[a,c]of s.pathIndex)t.pathIndex.set(a,c);n.push(...i)}return{tokens:t,errors:n}}o(F,"flatten");const _e={isObject:o(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObject")};function h(e){return typeof e=="string"&&e.startsWith("{")&&e.endsWith("}")}o(h,"isReference");function $(e,t,n,r){if(h(t))return[];switch(e.type){case"object":return Ve(e,t,n,r);case"union":return Fe(e,t,n,r);case"array":return ke(e,t,n,r);default:return Oe(e,t,n,r)}}o($,"validateSchema");function Oe(e,t,n,r){return typeof t!==e.type?[{path:n,message:e.errorMessage?.(t,n)||u.VALIDATE.INVALID_TYPE(e.type,t,n),source:r}]:e.validate?.(t,n,r)??[]}o(Oe,"validateSimpleValue");function Ve(e,t,n,r){if(!_e.isObject(t))return[{path:n,message:e.errorMessage?.(t,n)||u.VALIDATE.INVALID_TYPE("object",t,n),source:r}];const s=[],i=t;if(e.required)for(const a of e.required)a in i||s.push({path:`${n}.${a}`,message:u.VALIDATE.MISSING_REQUIRED_PROPERTY(a,n),source:r});for(const[a,c]of Object.entries(e.properties))a in i&&s.push(...$(c,i[a],`${n}.${a}`,r));return s}o(Ve,"validateObject");function Fe(e,t,n,r){let s=[],i=1/0;for(const a of e.oneOf){if(a.type==="string"&&typeof t!="string"||a.type==="object"&&typeof t!="object")continue;const c=$(a,t,n,r);if(c.length===0)return e.validate?.(t,n,r)??[];c.length<i&&(s=c,i=c.length)}return i===1/0?[{path:n,message:u.VALIDATE.INVALID_TYPE(e.oneOf.map(a=>a.type).join(" or "),t,n),source:r}]:s}o(Fe,"validateUnion");function ke(e,t,n,r){return Array.isArray(t)?e.validate?.(t,n,r)??[]:[{path:n,message:e.errorMessage?.(t,n)||u.VALIDATE.INVALID_TYPE("array",t,n),source:r}]}o(ke,"validateArray");const N={tokenType:"color",schema:{type:"string",errorMessage:o((e,t)=>u.VALIDATE.INVALID_COLOR(e,t),"errorMessage"),validate:o((e,t,n)=>/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/.test(e)?[]:[{path:t,message:u.VALIDATE.INVALID_COLOR(e,t),source:n}],"validate")}};function ve(e,t,n){return $(N.schema,e,t,n)}o(ve,"validateColor");const b={tokenType:"number",schema:{type:"number",errorMessage:o((e,t)=>u.VALIDATE.INVALID_NUMBER(e,t),"errorMessage"),validate:o((e,t,n)=>typeof e!="number"||isNaN(e)?[{path:t,message:u.VALIDATE.INVALID_NUMBER(e,t),source:n}]:[],"validate")}};function we(e,t,n){return $(b.schema,e,t,n)}o(we,"validateNumber");const E={tokenType:"dimension",schema:{type:"object",errorMessage:o((e,t)=>u.VALIDATE.INVALID_DIMENSION(e,t),"errorMessage"),properties:{value:b.schema,unit:{type:"string",validate:o((e,t,n)=>typeof e!="string"||!["px","rem"].includes(e)?[{path:t,message:u.VALIDATE.INVALID_DIMENSION_UNIT(e,t),source:n}]:[],"validate")}},required:["value","unit"]}};function xe(e,t,n){return $(E.schema,e,t,n)}o(xe,"validateDimension");const X={tokenType:"fontFamily",schema:{type:"union",oneOf:[{type:"string",errorMessage:o((e,t)=>u.VALIDATE.INVALID_FONT_FAMILY(e,t),"errorMessage")},{type:"array",errorMessage:o((e,t)=>u.VALIDATE.INVALID_FONT_FAMILY(e,t),"errorMessage"),validate:o((e,t,n)=>e.every(s=>typeof s=="string")?[]:[{path:t,message:u.VALIDATE.INVALID_FONT_FAMILY(e,t),source:n}],"validate")}],errorMessage:o((e,t)=>u.VALIDATE.INVALID_FONT_FAMILY(e,t),"errorMessage")}};function Ce(e,t,n){return $(X.schema,e,t,n)}o(Ce,"validateFontFamily");const Re=["thin","hairline","extra-light","ultra-light","light","normal","regular","book","medium","semi-bold","demi-bold","bold","extra-bold","ultra-bold","black","heavy","extra-black","ultra-black"],J={tokenType:"fontWeight",schema:{type:"union",errorMessage:o((e,t)=>u.VALIDATE.INVALID_FONT_WEIGHT(e,t),"errorMessage"),oneOf:[{type:"number",errorMessage:o((e,t)=>u.VALIDATE.INVALID_FONT_WEIGHT(e,t),"errorMessage"),validate:o((e,t,n)=>e<1||e>1e3?[{path:t,message:u.VALIDATE.INVALID_FONT_WEIGHT(e,t),source:n}]:[],"validate")},{type:"string",errorMessage:o((e,t)=>u.VALIDATE.INVALID_FONT_WEIGHT(e,t),"errorMessage"),validate:o((e,t,n)=>Re.includes(e.toLowerCase())?[]:[{path:t,message:u.VALIDATE.INVALID_FONT_WEIGHT(e,t),source:n}],"validate")}]}};function je(e,t,n){return $(J.schema,e,t,n)}o(je,"validateFontWeight");const Me=["ms","s"],k={tokenType:"duration",schema:{type:"object",errorMessage:o((e,t)=>u.VALIDATE.INVALID_DURATION(e,t),"errorMessage"),properties:{value:b.schema,unit:{type:"string",validate:o((e,t,n)=>Me.includes(e)?[]:[{path:t,message:u.VALIDATE.INVALID_DURATION_UNIT(e,t),source:n}],"validate")}},required:["value","unit"]}};function Pe(e,t,n){return $(k.schema,e,t,n)}o(Pe,"validateDuration");const Z={tokenType:"cubicBezier",schema:{type:"array",errorMessage:o((e,t)=>u.VALIDATE.INVALID_CUBIC_BEZIER(e,t),"errorMessage"),validate:o((e,t,n)=>{const r=e;if(r.length!==4||!r.every(a=>typeof a=="number"))return[{path:t,message:u.VALIDATE.INVALID_CUBIC_BEZIER(e,t),source:n}];const[s,,i]=r;return s<0||s>1||i<0||i>1?[{path:t,message:u.VALIDATE.INVALID_CUBIC_BEZIER(e,t),source:n}]:[]},"validate")}};function Ue(e,t,n){return $(Z.schema,e,t,n)}o(Ue,"validateCubicBezier");const Ge={tokenType:"typography",schema:{type:"object",properties:{fontFamily:X.schema,fontSize:E.schema,letterSpacing:E.schema,lineHeight:b.schema,fontWeight:J.schema},required:["fontFamily","fontSize"],errorMessage:o((e,t)=>u.VALIDATE.INVALID_TYPOGRAPHY(e,t),"errorMessage")}};function We(e,t,n){return $(Ge.schema,e,t,n)}o(We,"validateTypography");const ze=["solid","dashed","dotted","double","groove","ridge","outset","inset"],Ye=["round","butt","square"],Be={type:"object",errorMessage:o((e,t)=>u.VALIDATE.INVALID_STROKE_STYLE(e,t),"errorMessage"),properties:{dashArray:{type:"array",validate:o((e,t,n)=>{const r=e,s=[];return r.forEach((i,a)=>{typeof i!="string"&&s.push(...$(E.schema,i,`${t}.${a}`,n))}),s},"validate")},lineCap:{type:"string",validate:o((e,t,n)=>Ye.includes(e)?[]:[{path:t,message:u.VALIDATE.INVALID_STROKE_LINE_CAP(e,t),source:n}],"validate")}},required:["dashArray","lineCap"]},Q={tokenType:"strokeStyle",schema:{type:"union",oneOf:[{type:"string",validate:o((e,t,n)=>!ze.includes(e)&&typeof e=="string"?[{path:t,message:u.VALIDATE.INVALID_STROKE_STYLE(e,t),source:n}]:[],"validate")},Be]}};function He(e,t,n){return $(Q.schema,e,t,n)}o(He,"validateStrokeStyle");const qe={tokenType:"border",schema:{type:"object",properties:{color:N.schema,width:E.schema,style:Q.schema},required:["color","width","style"],errorMessage:o((e,t)=>u.VALIDATE.INVALID_BORDER(e,t),"errorMessage")}};function Ke(e,t,n){return $(qe.schema,e,t,n)}o(Ke,"validateBorder");const Xe={tokenType:"transition",schema:{type:"object",properties:{duration:k.schema,delay:k.schema,timingFunction:Z.schema},required:["duration","delay","timingFunction"],errorMessage:o((e,t)=>u.VALIDATE.INVALID_TRANSITION(e,t),"errorMessage")}};function Je(e,t,n){return $(Xe.schema,e,t,n)}o(Je,"validateTransition");const ee={tokenType:"shadow",schema:{type:"object",properties:{color:N.schema,offsetX:E.schema,offsetY:E.schema,blur:E.schema,spread:E.schema,inset:{type:"boolean",errorMessage:o((e,t)=>u.VALIDATE.INVALID_SHADOW_INSET(e,t),"errorMessage")}},required:["color","offsetX","offsetY","blur","spread"],errorMessage:o((e,t)=>u.VALIDATE.INVALID_SHADOW(e,t),"errorMessage")}};function Ze(e,t,n){const r=[];return Array.isArray(e)?(e.forEach((s,i)=>{r.push(...$(ee.schema,s,`${t}[${i}]`,n))}),r):$(ee.schema,e,t,n)}o(Ze,"validateShadow");const Qe={type:"object",errorMessage:o((e,t)=>u.VALIDATE.INVALID_GRADIENT(e,t),"errorMessage"),properties:{color:{type:"string",validate:N.schema.validate},position:{type:"number",validate:o((e,t,n)=>e<0||e>1?[{path:t,message:u.VALIDATE.INVALID_GRADIENT_STOP_POSITION(e,t),source:n}]:[],"validate")}},required:["color","position"]},et={tokenType:"gradient",schema:{type:"array",errorMessage:o((e,t)=>u.VALIDATE.INVALID_ARRAY(e,t),"errorMessage"),validate:o((e,t,n)=>{const r=e,s=[];return r.forEach((i,a)=>{s.push(...$(Qe,i,`${t}[${a}]`,n))}),s},"validate")}};function tt(e,t,n){return $(et.schema,e,t,n)}o(tt,"validateGradient");const nt={tokenType:"fluidDimension",schema:{type:"object",errorMessage:o((e,t)=>u.VALIDATE.INVALID_FLUID_DIMENSION(e,t),"errorMessage"),properties:{min:E.schema,max:E.schema},required:["min","max"]}};function rt(e,t,n){return $(nt.schema,e,t,n)}o(rt,"validateFluidDimension");const ot={color:ve,dimension:xe,fluidDimension:rt,duration:Pe,cubicBezier:Ue,fontFamily:Ce,fontWeight:je,number:we,strokeStyle:He,typography:We,border:Ke,shadow:Ze,gradient:tt,transition:Je};function v(e){const t=[];for(const[n,r]of Object.entries(e.tokens)){if(typeof r!="object"||r===null||!("$type"in r)||!("$path"in r)||r.$path.startsWith("$"))continue;if(!("$value"in r)){t.push({path:r.$path,message:u.VALIDATE.MISSING_REQUIRED_PROPERTY("$value",r.$path),source:r.$source});continue}const s=ot[r.$type];if(!s){t.push({path:r.$path,message:u.VALIDATE.UNKNOWN_TOKEN_TYPE(r.$type,r.$path),source:r.$source});continue}const i=r;t.push(...s(i.$value,i.$path,i.$source))}return t}o(v,"validate");function S(e,t,n,r){return typeof t=="string"&&h(t)?st(e,t,n,r):Array.isArray(t)?t.map(s=>S(e,s,n,r)):typeof t=="object"&&t!==null?Object.entries(t).reduce((i,[a,c])=>({...i,[a]:S(`${e}.${a}`,c,n,r)}),{}):t}o(S,"resolveValue");function w(e){const t={},n=new Set,r=[];for(const[s,i]of Object.entries(e.tokens))try{if(!("$value"in i)){t[s]=i;continue}const a=i;t[s]={...a,$resolvedValue:S(a.$path,a.$value,e,n)}}catch(a){const c=a instanceof Error?a.message:String(a),l=i,f=l.$path,p=l.$source;let d,I;c.includes("Circular reference detected")?(d="circular",I=c):c.includes("Reference not found")?(d="missing",I=c):(d="type-mismatch",I=u.RESOLVE.TYPE_MISMATCH(f)),r.push({type:d,path:f,source:p,message:I})}return{resolved:t,errors:r}}o(w,"resolve");function st(e,t,n,r){const s=t.slice(1,-1),i=n.pathIndex.get(s);if(!i)throw new Error(u.RESOLVE.REFERENCE_NOT_FOUND(s,e));if(r.has(i)){const l=n.tokens[i];throw!l||!("$path"in l)?new Error(u.RESOLVE.REFERENCE_NOT_FOUND(s,e)):new Error(u.RESOLVE.CIRCULAR_REFERENCE(e,l.$path))}const a=n.tokens[i];if(!a||!("$value"in a))throw new Error(u.RESOLVE.REFERENCE_NOT_FOUND(s,e));r.add(i);const c=S(i,a.$value,n,r);return r.delete(i),c}o(st,"resolveReferenceChain");function x(e,t){const n=new Map;for(const[r,s]of Object.entries(t)){if(!("$source"in s)){for(const l of e){const f=l.collection;n.has(f)||n.set(f,new Map);const p=n.get(f),d=l.theme;p.has(d)||p.set(d,{}),p.get(d)[r]=s}continue}const i=s.$source.collection,a=s.$source.theme;n.has(i)||n.set(i,new Map);const c=n.get(i);c.has(void 0)||c.set(void 0,{}),a||(c.get(void 0)[r]=s),a&&(c.has(a)||c.set(a,{}),c.get(a)[r]=s)}return e.map(r=>{const s=n.get(r.collection);if(!s)return{collection:r.collection,theme:r.theme,tokens:{}};if(r.theme){const i=s.get(r.theme)||{};return{collection:r.collection,theme:r.theme,tokens:i}}else{const i=s.get(void 0)||{};return{collection:r.collection,theme:r.theme,tokens:i}}})}o(x,"processTrees");function D(e){return["serif","sans-serif","monospace","cursive","fantasy","system-ui","ui-serif","ui-sans-serif","ui-monospace","ui-rounded","emoji","math","fangsong"].includes(e.toLowerCase())?e:/[\s'"!@#$%^&*()=+[\]{};:|\\/,.<>?~]/.test(e)?`"${e}"`:e}o(D,"quoteFont");const it={thin:100,hairline:100,"extra-light":200,"ultra-light":200,light:300,normal:400,regular:400,book:400,medium:500,"semi-bold":600,"demi-bold":600,bold:700,"extra-bold":800,"ultra-bold":800,black:900,heavy:900,"extra-black":950,"ultra-black":950};function te(e){return h(e)?{value:e}:typeof e=="number"?{value:e}:{value:it[e.toLowerCase()]??e}}o(te,"convertFontWeightToken");function at(e){if(h(e))return{"font-family":e,"font-size":e};const t={"font-family":h(e.fontFamily)?e.fontFamily:Array.isArray(e.fontFamily)?e.fontFamily.map(n=>D(n)).join(", "):D(e.fontFamily),"font-size":h(e.fontSize)?e.fontSize:`${e.fontSize.value}${e.fontSize.unit}`};return e.fontWeight&&(t["font-weight"]=h(e.fontWeight)?e.fontWeight:te(e.fontWeight).value),e.letterSpacing&&(t["letter-spacing"]=h(e.letterSpacing)?e.letterSpacing:`${e.letterSpacing.value}${e.letterSpacing.unit}`),e.lineHeight&&(t["line-height"]=(h(e.lineHeight),e.lineHeight)),t}o(at,"convertTypographyToken");function ne(e){return e?`${e.value}${e.unit}`:"0ms"}o(ne,"formatDuration");function ct(e){if(h(e))return{value:e};const t=h(e.duration)?e.duration:ne(e.duration),n=h(e.timingFunction)?e.timingFunction:`cubic-bezier(${e.timingFunction.join(", ")})`,r=e.delay&&(h(e.delay)?e.delay:ne(e.delay));return{value:[t,n,r].filter(Boolean).join(" ")}}o(ct,"convertTransitionToken");function lt(e){return h(e)?{value:e}:{value:`cubic-bezier(${e.join(", ")})`}}o(lt,"convertCubicBezierToken");function ut(e){return h(e)?{value:e}:{value:e}}o(ut,"convertNumberToken");function ft(e){return h(e)?{value:e}:{value:`${e.value}${e.unit}`}}o(ft,"convertDurationToken");function re(e){return h(e)?{value:e}:typeof e=="string"?{value:e}:{value:`${e.dashArray.map(n=>h(n)?n:`${n.value}${n.unit}`).join(" ")} ${e.lineCap}`}}o(re,"convertStrokeStyleToken");function dt(e){if(h(e))return{value:e};const t=h(e.width)?e.width:`${e.width.value}${e.width.unit}`,n=(h(e.color),e.color),r=typeof e.style=="string"?e.style:re(e.style).value;return{value:`${t} ${r} ${n}`}}o(dt,"convertBorderToken");function oe(e){const t=h(e.offsetX)?e.offsetX:`${e.offsetX.value}${e.offsetX.unit}`,n=h(e.offsetY)?e.offsetY:`${e.offsetY.value}${e.offsetY.unit}`,r=h(e.blur)?e.blur:`${e.blur.value}${e.blur.unit}`,s=h(e.spread)?e.spread:`${e.spread.value}${e.spread.unit}`,i=(h(e.color),e.color);return`${e.inset?"inset ":""}${t} ${n} ${r} ${s} ${i}`}o(oe,"convertSingleShadow");function pt(e){return h(e)?{value:e}:Array.isArray(e)?{value:e.map(oe).join(", ")}:{value:oe(e)}}o(pt,"convertShadowToken");function ht(e){return h(e)?{value:e}:{value:`linear-gradient(${e.map(n=>{const r=(h(n.color),n.color),s=h(n.position)?n.position:`${n.position*100}`;return`${r} ${s}%`}).join(", ")})`}}o(ht,"convertGradientToken");function mt(e){return h(e)?{value:e}:{value:Array.isArray(e)?e.map(n=>D(n)).join(", "):D(e)}}o(mt,"convertFontFamilyToken");function It(e){return h(e)?{value:e}:{value:`${e.value}${e.unit}`}}o(It,"convertDimensionToken");function se(e,t=16){return e.unit==="px"?e.value:e.value*t}o(se,"normalizeToPixels");function gt(e,t){const{min:n,max:r}=e,s=t.fluidConfig;if(!s)throw new Error(u.VALIDATE.MISSING_FLUID_CONFIG(t.path??""));const i=16,a=se(n,i),c=se(r,i),l=s.min,f=s.max;if(a===c)return{value:`${a/i}rem`};const p=a/i,d=c/i,I=l/i,g=f/i,y=(d-p)/(g-I),A=-1*I*y+p;return{value:`clamp(${p}rem, ${A.toFixed(2)}rem + ${(y*100).toFixed(2)}vw, ${d}rem)`}}o(gt,"convertFluidDimension");function $t(e,t){if(h(e))return{value:e};if(!t.fluidConfig)throw new Error(u.VALIDATE.MISSING_FLUID_CONFIG(t.path??""));return gt(e,t)}o($t,"convertFluidDimensionToken");function C(e){return e===1?"1":e===0?"0":e.toFixed(2)}o(C,"formatAlpha");function R(e,t){try{const n=t==="rgba"?"rgb":t==="hsla"?"hsl":t,r=_(n==="hex"?"rgb":n)(e);if(!r)throw new Error(`Failed to convert color ${e} to ${t}`);switch(n){case"hsl":{if(r.mode!=="hsl")throw new Error("Unexpected color mode");const s=Math.round(r.h??0),i=Math.round((r.s??0)*100),a=Math.round((r.l??0)*100),c=r.alpha;return c!==void 0?`hsl(${s} ${i}% ${a}% / ${C(c)})`:`hsl(${s} ${i}% ${a}%)`}case"oklch":{if(r.mode!=="oklch")throw new Error("Unexpected color mode");const s=r.l??0,i=r.c??0,a=r.h??0,c=r.alpha;return c!==void 0?`oklch(${s.toFixed(3)} ${i.toFixed(3)} ${a.toFixed(1)} / ${c.toFixed(2)})`:`oklch(${s.toFixed(3)} ${i.toFixed(3)} ${a.toFixed(1)})`}case"rgb":{if(r.mode!=="rgb")throw new Error("Unexpected color mode");const s=Math.round((r.r??0)*255),i=Math.round((r.g??0)*255),a=Math.round((r.b??0)*255),c=r.alpha;return c!==void 0?`rgb(${s} ${i} ${a} / ${C(c)})`:`rgb(${s} ${i} ${a})`}case"p3":{if(r.mode!=="p3")throw new Error("Unexpected color mode");const s=r.r??0,i=r.g??0,a=r.b??0,c=r.alpha;return c!==void 0?`color(display-p3 ${s.toFixed(6)} ${i.toFixed(6)} ${a.toFixed(6)} / ${C(c)})`:`color(display-p3 ${s.toFixed(6)} ${i.toFixed(6)} ${a.toFixed(6)})`}default:{const s=_("rgb")(r);return s?s.alpha!==void 0?Te(s):z(s):e}}}catch{const r=_("rgb")(e);return console.warn(`Failed to convert color ${e} to ${t}, falling back to hex`),r?z(r):e}}o(R,"convertHexToColorString");function yt(e,t){if(h(e))return{value:e};const n=t.colorFormat||"hex";try{const r=R(e,n);return n==="p3"?{value:R(e,"hex")||e,featureValues:[{query:"@supports (color: color(display-p3 1 1 1))",value:r||e}]}:{value:r||e}}catch{return console.warn(`Failed to convert color ${e} to ${n}, falling back to hex`),{value:R(e,"hex")}}}o(yt,"convertColorToken");const ie={duration:ft,number:ut,cubicBezier:lt,color:yt,dimension:It,fluidDimension:$t,typography:at,border:dt,shadow:pt,gradient:ht,transition:ct,strokeStyle:re,fontFamily:mt,fontWeight:te};function At(e,t){const n=ie[e.$type];return{...e.$description?{$description:e.$description}:{},...e.$extensions?{$extensions:e.$extensions}:{},$type:e.$type,$value:e.$value,$path:e.$path,$source:e.$source,$originalPath:e.$originalPath,$resolvedValue:e.$resolvedValue,$cssProperties:n(e.$value,t)}}o(At,"convertSingleToken");function ae(e,t){const n={};for(const[r,s]of Object.entries(e)){if(!s||typeof s!="object")continue;if(!("$type"in s)){n[r]={...s.$description?{$description:s.$description}:{},...s.$extensions?{$extensions:s.$extensions}:{}};continue}if(!ie[s.$type])continue;const i={fluidConfig:t.options?.fluid,colorFormat:t.options?.color,path:s.$path};n[r]=At(s,i)}return n}o(ae,"convertTokens");function j(e,t){const n={};for(const[r,s]of Object.entries(e)){const i={default:ae(s.default,t)};for(const[a,c]of Object.entries(s))a!=="default"&&(i[a]=ae(c,t));n[r]=i}return n}o(j,"convert");const ce=new Map;function Et(e){const t=ce.get(e);if(t)return t;const n=e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([A-Z])([A-Z])(?=[a-z])/g,"$1-$2").toLowerCase();return ce.set(e,n),n}o(Et,"toKebabCase");function M({collection:e,filename:t,separate:n,baseDir:r}){const s=`${t}.variables.css`;return e==="default"?`${r}/${s}`:`${r}/${e}/${s}`}o(M,"getOutputPath");const le="@supports (color: color(display-p3 1 1 1))";function Tt(e){return e.$type==="typography"}o(Tt,"isTypographyToken");function P(e){return e.split(".").join("-")}o(P,"formatCSSVarPath");function ue(e){return typeof e=="number"?e:typeof e!="string"?(console.warn("Unexpected value type in convertReferenceToCSSVar, got:",e),String(e)):e.replace(/\{([^}]+)\}/g,(t,n)=>`var(--${n.split(".").map(Et).join("-")})`)}o(ue,"convertReferenceToCSSVar");function Nt(e){const t=e.$cssProperties;if("value"in t)return{name:`--${P(e.$path)}`,value:ue(t.value)}}o(Nt,"generateSingleVariable");function bt(e){return Object.entries(e.$cssProperties).filter(([t,n])=>n!==void 0).map(([t,n])=>({name:`--${P(e.$path)}-${t}`,value:ue(n)}))}o(bt,"generateTypographyVariables");function fe(e){if(e.$type!=="color")return[];const t=e.$cssProperties;return"featureValues"in t?t.featureValues?.filter(n=>n.query===le).map(n=>({name:`--${P(e.$path)}`,value:n.value}))??[]:[]}o(fe,"generateFeatureVariables");function de(e){const t=[`${e.selector} {`];if(e.comment&&t.push(` /* ${e.comment} */`),e.vars.length>0){const n=e.vars.map(r=>` ${r.name}: ${r.value};`).join(`
4
+ `);t.push(n)}return t.push("}"),t.join(`
5
+ `)}o(de,"generateCSSBlock");function St(e){const t=[];return e.root.vars.length>0&&t.push(de({selector:e.root.selector,vars:e.root.vars})),e.features.forEach(n=>{const s=de({selector:e.root.selector,vars:n.vars}).split(`
6
+ `).map(i=>` ${i}`).join(`
7
+ `);t.push(`${n.query} {
8
+ ${s}
7
9
  }`)}),t.filter(Boolean).join(`
8
10
 
9
- `)}n(ft,"convertCSSVarsToString");function lt(e,t){if(at(e))return{vars:ut(e,t),features:X(e,t)};const r=ct(e,t);return{vars:r?[r]:[],features:X(e,t)}}n(lt,"generateVariablesForToken");async function j(e,t={}){const r=[],i=Object.entries(e).filter(([f,d])=>f!=="$extensions"&&"$type"in d).map(([f,d])=>lt(d,r));let o=":root";t.collection&&t.mode&&t.mode!=="default"&&(o+=`[data-theme="${t.mode}"]`);const s=i.flatMap(f=>f.vars),a=i.flatMap(f=>f.features||[]),c=ft({root:{selector:o,vars:s},features:a.length?[{query:K,vars:a}]:[]});return{output:[{name:"variables.css",content:dt(c)}],errors:r}}n(j,"generateCSS");function dt(e){return e.endsWith(`
11
+ `)}o(St,"convertCSSVarsToString");function Dt(e){if(Tt(e))return{vars:bt(e),features:fe(e)};const t=Nt(e);return{vars:t?[t]:[],features:fe(e)}}o(Dt,"generateVariablesForToken");async function U(e,t={}){const n=Object.entries(e).filter(([c,l])=>c!=="$extensions"&&"$type"in l).map(([c,l])=>Dt(l));let r=":root";t.theme&&t.theme!=="default"&&(r=`[data-theme="${t.theme}"]`);const s=n.flatMap(c=>c.vars),i=n.flatMap(c=>c.features||[]),a=St({root:{selector:r,vars:s},features:i.length?[{query:le,vars:i}]:[]});return a.trim()?{output:[{path:"tokens.variables.css",css:Lt(a)}]}:{output:[{path:"tokens.variables.css",css:""}]}}o(U,"generateCSS");function Lt(e){return e.endsWith(`
10
12
  `)?e:e+`
11
- `}n(dt,"formatCSSVars");async function w(e,t){const r=[];return{output:t?.separate?await It(e,r,t):await pt(e,r,t),errors:r}}n(w,"generate");async function pt(e,t,r){const i=[];for(const[o,s]of Object.entries(e))for(const[a,c]of Object.entries(s)){const f=await j(c,{mode:a!=="default"?a:void 0,collection:o!=="default"?o:void 0});t.push(...f.errors.map(d=>({...d,path:`${o}.${a}.${d.path}`}))),f.output[0]?.content&&i.push(f.output[0].content)}return[{name:r?.directory?`${r.directory}/variables.css`:"variables.css",content:i.filter(Boolean).join(`
13
+ `}o(Lt,"formatCSSVars");async function G(e,t){const n={};for(const[r,s]of Object.entries(e)){n[r]={default:{}},s.default&&(n[r].default=s.default);for(const[i,a]of Object.entries(s))i!=="default"&&a&&(n[r][i]=a);Object.keys(n[r].default).length===0&&Object.keys(n[r]).length===1&&delete n[r]}return t.output.css.separate?{output:await Ot(n,t)}:{output:await _t(n,t)}}o(G,"generate");async function _t(e,t){const n=`${t.output.directories.css}/global/variables`,r=[];for(const[s,i]of Object.entries(e)){const a=[];for(const[c,l]of Object.entries(i)){const f=await U(l,{theme:c!=="default"?c:void 0,collection:s!=="default"?s:void 0});f.output[0].css.trim()&&a.push(f.output[0].css)}a.length>0&&r.push({path:M({collection:s,filename:"tokens",separate:!1,baseDir:n}),css:a.filter(Boolean).join(`
12
14
  `).trim()+`
13
- `}]}n(pt,"generateSingleFile");async function It(e,t,r){const i=r?.directory||"",o=[],s=e.default?.default;if(s&&Object.keys(e).length===1){const a=new Map;for(const[c,f]of Object.entries(s)){const d=c.split(".")[0]||"default";a.has(d)||a.set(d,{});const l=a.get(d);l[c]=f}for(const[c,f]of a){const d=await j(f,{});d.output[0]?.content&&o.push({name:`${i}/${c}.css`,content:d.output[0].content}),t.push(...d.errors.map(l=>({...l,path:`${c}.${l.path}`})))}return o}for(const[a,c]of Object.entries(e))if(Object.keys(c).length!==0)for(const[f,d]of Object.entries(c)){if(Object.keys(d).length===0)continue;const l=await j(d,{mode:f!=="default"?f:void 0,collection:a!=="default"?a:void 0});if(t.push(...l.errors.map(I=>({...I,path:`${a}.${f}.${I.path}`}))),l.output[0]?.content){const I=a==="default"?Object.keys(d)[0].split(".")[0]:a;o.push({name:`${i}/${I}.css`,content:l.output[0].content})}}return o}n(It,"generateSeparateFiles");async function mt(e){const t={load:[],flatten:[],validation:[],resolution:[],generation:[]},r={normalization:[]},{trees:i,errors:o}=await L(e.files);t.load.push(...o);const{tokens:s,errors:a}=b(i);t.flatten.push(...a);const c=v(s,e);if(t.validation.push(...c),c.length>0)return{output:[],trees:i,errors:t,warnings:r};const{resolved:f,errors:d}=V(s);t.resolution.push(...d);const l=F(i,f),{tokens:I,warnings:m}=k(l,e.collections);r.normalization.push(...m);const A=O(I,e),{output:y,errors:_}=await w(A,e.output);return t.generation.push(..._),{output:y,trees:i,errors:t,warnings:r}}n(mt,"tokensToCSSPipeline");async function $t(e){const{trees:t,errors:r}=await L(e.files),{tokens:i,errors:o}=b(t),s=v(i,e),{resolved:a,errors:c}=V(i);return{trees:t,flattenedTokens:i,resolved:a,errors:{load:r,flatten:o,validation:s,resolution:c}}}n($t,"validationPipeline");async function ht(e,t,r){const i={generation:[]},o={normalization:[]},s=F(e,t),{tokens:a,warnings:c}=k(s,r.collections);o.normalization.push(...c);const f=O(a,r),{output:d,errors:l}=await w(f,r.output);return i.generation.push(...l),{output:d,errors:i,warnings:o}}n(ht,"generationPipeline");export{O as convert,b as flatten,w as generate,ht as generationPipeline,L as loadTreesFromConfig,k as normalizeTokens,De as parseJson,F as processTrees,V as resolve,mt as tokensToCSSPipeline,v as validate,$t as validationPipeline};
15
+ `})}return r}o(_t,"generateSingleFile");async function Ot(e,t){const n=`${t.output.directories.css}/global/variables`,r=[];for(const[s,i]of Object.entries(e))if(Object.keys(i).length!==0){for(const[a,c]of Object.entries(i))if(Object.keys(c).length!==0)if(a==="default"){const l=new Map;for(const[f,p]of Object.entries(c)){if(!("$type"in p))continue;const I=p.$source.sourcePath;l.has(I)||l.set(I,{}),l.get(I)[f]=p}for(const[f,p]of l){if(Object.keys(p).length===0)continue;const d=f.split("/").pop()?.replace(/\.json$/,"")??"tokens",g=(await U(p,{collection:s==="default"?void 0:s})).output[0].css;g.trim()&&r.push({path:M({collection:s,filename:d,separate:!0,baseDir:n}),css:g})}}else{const f=(await U(c,{theme:a,collection:s==="default"?void 0:s})).output[0].css;f.trim()&&r.push({path:M({collection:s,filename:a,separate:!0,baseDir:n}),css:f})}}return r}o(Ot,"generateSeparateFiles");function W(e){const t=[],n=[],r=new Set,s=new Map;e.forEach(c=>{const{collection:l,theme:f="default"}=c;r.add(l),s.has(l)||s.set(l,new Set),s.get(l).add(f)});const i={};function a(c){const l={default:{}};i[c]=l;const f=s.get(c);return f&&f.forEach(p=>{l[p]={}}),l}return o(a,"addCollection"),r.forEach(c=>{a(c)}),e.forEach(c=>{const{collection:l,theme:f="default",tokens:p}=c,d=i[l]||a(l),I=d[f]||(d[f]={});Object.entries(p).forEach(([g,y])=>{const A=g.replace(`${l}.`,"");I[A]=y})}),{tokens:i,errors:n,warnings:t}}o(W,"normalizeTokens");async function Vt(e,t){const n={load:[],flatten:[],validation:[],resolution:[]},r={normalization:[]},{trees:s,errors:i}=await(t?.loader?.type==="memory"?V(t.loader.data):O(e));n.load.push(...i);const{tokens:a,errors:c}=F(s);n.flatten.push(...c);const l=v(a);if(n.validation.push(...l),l.length>0)return{output:[],trees:s,errors:n,warnings:r};const{resolved:f,errors:p}=w(a);n.resolution.push(...p);const d=x(s,f),{tokens:I,warnings:g}=W(d);r.normalization.push(...g);const y=j(I,e),{output:A}=await G(y,e);return{output:A,trees:s,errors:n,warnings:r}}o(Vt,"tokensToCSSPipeline");async function Ft(e,t){const{trees:n,errors:r}=await(t.loader.type==="memory"?V(t.loader.data):O(t.loader.paths)),{tokens:s,errors:i}=F(n),a=v(s),{resolved:c,errors:l}=w(s);return{trees:n,flattenedTokens:s,resolved:c,errors:{load:r,flatten:i,validation:a,resolution:l}}}o(Ft,"validationPipeline");async function kt(e,t,n){const r={normalization:[]},s=x(e,t),{tokens:i,warnings:a}=W(s);r.normalization.push(...a);const c=j(i,n),{output:l}=await G(c,n);return{output:l,warnings:r}}o(kt,"generationPipeline");function vt(e){return"source"in e&&Array.isArray(e.source)}o(vt,"isSingleCollection");function pe(e){return`/**
16
+ * \u26A0\uFE0F AUTOMATICALLY GENERATED FILE - DO NOT EDIT DIRECTLY \u26A0\uFE0F
17
+ */
18
+
19
+ ${e}`}o(pe,"addWarningBanner");function wt(e){return vt(e.tokens)?e.tokens.source:Object.values(e.tokens).flatMap(t=>"source"in t?t.source:[])}o(wt,"getTokenPathsFromConfig");async function xt(e,t=!0,n){for(const r of e){const s=t&&n?pe(r.css):r.css;try{await be(T.dirname(r.path),{recursive:!0});let i=!0;if(H(r.path))try{await Y(r.path,"utf-8")===s&&(i=!1)}catch{}i&&await B(r.path,s,"utf-8")}catch(i){throw new Error(`Failed to write CSS file ${r.path}: ${i instanceof Error?i.message:"Unknown error"}`)}}return e}o(xt,"writeCSSFilesToDisk");const he=m.object({tokens:m.union([m.object({source:m.array(m.string()),type:m.enum(["starter-kit","custom"]),themes:m.record(m.array(m.string())).optional()}),m.record(m.string(),m.object({source:m.array(m.string()),type:m.enum(["starter-kit","custom"]),themes:m.record(m.array(m.string())).optional()}))]),options:m.object({fluid:m.object({min:m.number(),max:m.number()}).strict().optional(),prefix:m.string().optional(),color:m.enum(["hex","rgb","rgba","hsl","hsla","oklch","p3"]).optional()}).optional(),output:m.object({directories:m.object({tokens:m.string(),components:m.string().optional(),css:m.string()}),css:m.object({separate:m.boolean(),manageIndex:m.boolean().optional(),format:m.enum(["css","scss","less"]).optional()})})});function me(e){const t=he.safeParse(e);if(!t.success){const n=t.error.errors.map(r=>{const s=r.path.join(".");return u.CONFIG.INVALID_CONFIG(s||"root",r.message)});throw new Error(n.join(`
20
+ `))}return Ct(t.data),t.data}o(me,"validateConfig");function Ie(e){try{const t=JSON.parse(e);return me(t)}catch(t){throw t instanceof SyntaxError?new Error(u.CONFIG.INVALID_JSON(t.message)):t}}o(Ie,"parseAndValidateConfig");function Ct(e){if(typeof e.tokens=="object")for(const[t,n]of Object.entries(e.tokens)){if(!n.source?.length)continue;const r=new Map;n.source.forEach(s=>{const i=T.basename(s),a=r.get(i)||[];r.set(i,[...a,s])});for(const[s,i]of r)if(i.length>1)throw new Error(u.CONFIG.DUPLICATE_FILENAMES(t,s,i))}}o(Ct,"validateFileNames");async function Rt(e="sugarcube.config.json"){try{const t=await Ne.readFile(e,"utf-8");return Ie(t)}catch(t){throw t instanceof Error&&"code"in t&&t.code==="ENOENT"?new Error(u.CONFIG.FILE_NOT_FOUND(e)):t}}o(Rt,"loadConfig");function jt(e){const t=e.split("/"),n=t.findIndex(s=>s==="variables");if(n===-1||n===t.length-1)return"default";const r=t[n+1];return!r||r.endsWith(".css")?"default":r}o(jt,"getCollectionFromPath");function ge(e,t){if(e.includes("/variables/")){const n=jt(e),r=t.variables.get(n)??[];r.push(e),t.variables.set(n,r)}else e.startsWith("global/")?t.global.push(e):e.startsWith("compositions/")?t.compositions.push(e):e.startsWith("utilities/")&&t.utilities.push(e)}o(ge,"groupFile");async function Mt(e,t){const n={variables:new Map,global:[],compositions:[],utilities:[]},r=T.join(t,"index.css");let s="";H(r)&&(s=await Y(r,"utf-8"),s.split(`
21
+ `).filter(l=>l.trim().startsWith("@import")).map(l=>l.match(/'([^']+)'/)?.[1]).filter(l=>l!==void 0).forEach(l=>ge(l,n))),e.filter(c=>c.endsWith(".css")).forEach(c=>{const l=T.relative(t,c).replace(/\\/g,"/");ge(l,n)});const i=["reset.css","fonts.css","global-styles.css"];n.global.sort((c,l)=>{const f=i.findIndex(d=>c.endsWith(d)),p=i.findIndex(d=>l.endsWith(d));return f-p});const a=[];for(const[,c]of Array.from(n.variables.entries()).sort())c.length>0&&a.push(...c.sort().map(l=>`@import '${l}';`));return n.global.length>0&&(a.length&&a.push(""),a.push(...n.global.map(c=>`@import '${c}';`))),n.compositions.length>0&&(a.length&&a.push(""),a.push(...n.compositions.sort().map(c=>`@import '${c}';`))),n.utilities.length>0&&(a.length&&a.push(""),a.push(...n.utilities.sort().map(c=>`@import '${c}';`))),a.filter(Boolean).join(`
22
+ `)+`
23
+ `}o(Mt,"generateCSSIndex");async function Pt({cssOutputDirectory:e,files:t}){const n=t.filter(s=>s.endsWith(".css"));if(n.length===0)throw new Error("No CSS files to manage");const r=T.join(e,"index.css");try{const s=await Mt(n,e);return await B(r,s),r}catch(s){throw new Error(`Failed to manage CSS index file: ${s instanceof Error?s.message:String(s)}`)}}o(Pt,"manageCSSIndex");export{pe as addWarningBanner,he as configSchema,j as convert,F as flatten,G as generate,kt as generationPipeline,wt as getTokenPathsFromConfig,Rt as loadConfig,O as loadTreesFromConfig,V as loadTreesFromMemory,Pt as manageCSSIndex,W as normalizeTokens,Ie as parseAndValidateConfig,x as processTrees,w as resolve,Vt as tokensToCSSPipeline,v as validate,me as validateConfig,Ft as validationPipeline,xt as writeCSSFilesToDisk};
package/package.json CHANGED
@@ -1,22 +1,30 @@
1
1
  {
2
2
  "name": "@sugarcube-org/core",
3
- "version": "0.0.1-alpha.2",
3
+ "version": "0.0.1-alpha.4",
4
4
  "publishConfig": {
5
- "access": "restricted"
5
+ "access": "public"
6
6
  },
7
+ "description": "Core functionality for sugarcube",
8
+ "license": "AGPL-3.0",
7
9
  "main": "./dist/index.js",
8
10
  "types": "./dist/index.d.ts",
9
11
  "type": "module",
12
+ "exports": {
13
+ ".": "./dist/index.js"
14
+ },
10
15
  "files": [
11
16
  "dist",
12
17
  "README.md"
13
18
  ],
14
19
  "devDependencies": {
15
- "@types/picomatch": "^3.0.1",
20
+ "@vitest/coverage-istanbul": "2.1.2",
16
21
  "pkgroll": "^2.5.1",
17
22
  "tsx": "^4.19.2"
18
23
  },
19
24
  "dependencies": {
25
+ "@types/culori": "^2.1.1",
26
+ "@types/picomatch": "^3.0.1",
27
+ "culori": "^4.0.1",
20
28
  "fast-glob": "^3.3.2",
21
29
  "globby": "^14.0.2",
22
30
  "picomatch": "^4.0.2",
@@ -25,7 +33,11 @@
25
33
  "scripts": {
26
34
  "build": "pkgroll --minify",
27
35
  "dev": "pkgroll --watch",
28
- "test": "vitest",
29
- "type-check": "tsc --noEmit"
36
+ "test": "vitest --no-watch",
37
+ "test:watch": "vitest",
38
+ "test:coverage": "vitest run --coverage",
39
+ "test:bench": "vitest bench --no-watch",
40
+ "type-check": "tsc --noEmit",
41
+ "ci": "pnpm type-check && pnpm test"
30
42
  }
31
43
  }