@nice2dev/design-tokens 1.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3018 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __esm = (fn, res) => function __init() {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ };
12
+ var __commonJS = (cb, mod) => function __require() {
13
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
14
+ };
15
+ var __export = (target, all) => {
16
+ for (var name in all)
17
+ __defProp(target, name, { get: all[name], enumerable: true });
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (let key of __getOwnPropNames(from))
22
+ if (!__hasOwnProp.call(to, key) && key !== except)
23
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
24
+ }
25
+ return to;
26
+ };
27
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
28
+ // If the importer is in node compatibility mode or this is not an ESM
29
+ // file that has been converted to a CommonJS file using a Babel-
30
+ // compatible transform (i.e. "__esModule" has not been set), then set
31
+ // "default" to the CommonJS "module.exports" for node compatibility.
32
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
33
+ mod
34
+ ));
35
+
36
+ // package.json
37
+ var require_package = __commonJS({
38
+ "package.json"(exports2, module2) {
39
+ module2.exports = {
40
+ name: "@nice2dev/design-tokens",
41
+ version: "1.0.28",
42
+ description: "W3C Design Tokens for Nice2Dev UI with CLI generator",
43
+ type: "module",
44
+ main: "./dist/index.cjs",
45
+ module: "./dist/index.js",
46
+ types: "./dist/index.d.ts",
47
+ sideEffects: false,
48
+ exports: {
49
+ ".": {
50
+ import: "./dist/index.js",
51
+ require: "./dist/index.cjs",
52
+ types: "./dist/index.d.ts"
53
+ },
54
+ "./tokens/*": "./tokens/*",
55
+ "./cli": "./dist/cli/index.js"
56
+ },
57
+ bin: {
58
+ "nice-tokens": "./dist/cli/index.js"
59
+ },
60
+ files: [
61
+ "dist",
62
+ "tokens"
63
+ ],
64
+ scripts: {
65
+ build: "tsup src/index.ts src/cli/index.ts --format esm,cjs --dts --clean",
66
+ dev: "tsup src/index.ts src/cli/index.ts --format esm,cjs --dts --watch",
67
+ generate: "node dist/cli/index.js generate",
68
+ test: "vitest run --passWithNoTests",
69
+ typecheck: "tsc --noEmit"
70
+ },
71
+ dependencies: {
72
+ "chroma-js": "^2.4.2",
73
+ commander: "^12.1.0",
74
+ "fast-glob": "^3.3.2"
75
+ },
76
+ devDependencies: {
77
+ "@types/chroma-js": "^2.4.4",
78
+ "@types/node": "^20.14.10",
79
+ tsup: "^8.3.5",
80
+ typescript: "^5.7.2",
81
+ vitest: "^2.1.8"
82
+ },
83
+ keywords: [
84
+ "design-tokens",
85
+ "w3c",
86
+ "css-variables",
87
+ "nice2dev",
88
+ "design-system"
89
+ ],
90
+ author: "Nice2Dev",
91
+ license: "MIT",
92
+ repository: {
93
+ type: "git",
94
+ url: "https://github.com/nicetogit/nice2dev-ui.git",
95
+ directory: "packages/design-tokens"
96
+ }
97
+ };
98
+ }
99
+ });
100
+
101
+ // ../../node_modules/readdirp/esm/index.js
102
+ function readdirp(root, options = {}) {
103
+ let type = options.entryType || options.type;
104
+ if (type === "both")
105
+ type = EntryTypes.FILE_DIR_TYPE;
106
+ if (type)
107
+ options.type = type;
108
+ if (!root) {
109
+ throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");
110
+ } else if (typeof root !== "string") {
111
+ throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");
112
+ } else if (type && !ALL_TYPES.includes(type)) {
113
+ throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(", ")}`);
114
+ }
115
+ options.root = root;
116
+ return new ReaddirpStream(options);
117
+ }
118
+ var import_promises, import_node_stream, import_node_path, EntryTypes, defaultOptions2, RECURSIVE_ERROR_CODE, NORMAL_FLOW_ERRORS, ALL_TYPES, DIR_TYPES, FILE_TYPES, isNormalFlowError, wantBigintFsStats, emptyFn, normalizeFilter, ReaddirpStream;
119
+ var init_esm = __esm({
120
+ "../../node_modules/readdirp/esm/index.js"() {
121
+ "use strict";
122
+ import_promises = require("fs/promises");
123
+ import_node_stream = require("stream");
124
+ import_node_path = require("path");
125
+ EntryTypes = {
126
+ FILE_TYPE: "files",
127
+ DIR_TYPE: "directories",
128
+ FILE_DIR_TYPE: "files_directories",
129
+ EVERYTHING_TYPE: "all"
130
+ };
131
+ defaultOptions2 = {
132
+ root: ".",
133
+ fileFilter: (_entryInfo) => true,
134
+ directoryFilter: (_entryInfo) => true,
135
+ type: EntryTypes.FILE_TYPE,
136
+ lstat: false,
137
+ depth: 2147483648,
138
+ alwaysStat: false,
139
+ highWaterMark: 4096
140
+ };
141
+ Object.freeze(defaultOptions2);
142
+ RECURSIVE_ERROR_CODE = "READDIRP_RECURSIVE_ERROR";
143
+ NORMAL_FLOW_ERRORS = /* @__PURE__ */ new Set(["ENOENT", "EPERM", "EACCES", "ELOOP", RECURSIVE_ERROR_CODE]);
144
+ ALL_TYPES = [
145
+ EntryTypes.DIR_TYPE,
146
+ EntryTypes.EVERYTHING_TYPE,
147
+ EntryTypes.FILE_DIR_TYPE,
148
+ EntryTypes.FILE_TYPE
149
+ ];
150
+ DIR_TYPES = /* @__PURE__ */ new Set([
151
+ EntryTypes.DIR_TYPE,
152
+ EntryTypes.EVERYTHING_TYPE,
153
+ EntryTypes.FILE_DIR_TYPE
154
+ ]);
155
+ FILE_TYPES = /* @__PURE__ */ new Set([
156
+ EntryTypes.EVERYTHING_TYPE,
157
+ EntryTypes.FILE_DIR_TYPE,
158
+ EntryTypes.FILE_TYPE
159
+ ]);
160
+ isNormalFlowError = (error) => NORMAL_FLOW_ERRORS.has(error.code);
161
+ wantBigintFsStats = process.platform === "win32";
162
+ emptyFn = (_entryInfo) => true;
163
+ normalizeFilter = (filter) => {
164
+ if (filter === void 0)
165
+ return emptyFn;
166
+ if (typeof filter === "function")
167
+ return filter;
168
+ if (typeof filter === "string") {
169
+ const fl = filter.trim();
170
+ return (entry) => entry.basename === fl;
171
+ }
172
+ if (Array.isArray(filter)) {
173
+ const trItems = filter.map((item) => item.trim());
174
+ return (entry) => trItems.some((f) => entry.basename === f);
175
+ }
176
+ return emptyFn;
177
+ };
178
+ ReaddirpStream = class extends import_node_stream.Readable {
179
+ constructor(options = {}) {
180
+ super({
181
+ objectMode: true,
182
+ autoDestroy: true,
183
+ highWaterMark: options.highWaterMark
184
+ });
185
+ const opts = { ...defaultOptions2, ...options };
186
+ const { root, type } = opts;
187
+ this._fileFilter = normalizeFilter(opts.fileFilter);
188
+ this._directoryFilter = normalizeFilter(opts.directoryFilter);
189
+ const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat;
190
+ if (wantBigintFsStats) {
191
+ this._stat = (path3) => statMethod(path3, { bigint: true });
192
+ } else {
193
+ this._stat = statMethod;
194
+ }
195
+ this._maxDepth = opts.depth ?? defaultOptions2.depth;
196
+ this._wantsDir = type ? DIR_TYPES.has(type) : false;
197
+ this._wantsFile = type ? FILE_TYPES.has(type) : false;
198
+ this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
199
+ this._root = (0, import_node_path.resolve)(root);
200
+ this._isDirent = !opts.alwaysStat;
201
+ this._statsProp = this._isDirent ? "dirent" : "stats";
202
+ this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
203
+ this.parents = [this._exploreDir(root, 1)];
204
+ this.reading = false;
205
+ this.parent = void 0;
206
+ }
207
+ async _read(batch) {
208
+ if (this.reading)
209
+ return;
210
+ this.reading = true;
211
+ try {
212
+ while (!this.destroyed && batch > 0) {
213
+ const par = this.parent;
214
+ const fil = par && par.files;
215
+ if (fil && fil.length > 0) {
216
+ const { path: path3, depth } = par;
217
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path3));
218
+ const awaited = await Promise.all(slice);
219
+ for (const entry of awaited) {
220
+ if (!entry)
221
+ continue;
222
+ if (this.destroyed)
223
+ return;
224
+ const entryType = await this._getEntryType(entry);
225
+ if (entryType === "directory" && this._directoryFilter(entry)) {
226
+ if (depth <= this._maxDepth) {
227
+ this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
228
+ }
229
+ if (this._wantsDir) {
230
+ this.push(entry);
231
+ batch--;
232
+ }
233
+ } else if ((entryType === "file" || this._includeAsFile(entry)) && this._fileFilter(entry)) {
234
+ if (this._wantsFile) {
235
+ this.push(entry);
236
+ batch--;
237
+ }
238
+ }
239
+ }
240
+ } else {
241
+ const parent = this.parents.pop();
242
+ if (!parent) {
243
+ this.push(null);
244
+ break;
245
+ }
246
+ this.parent = await parent;
247
+ if (this.destroyed)
248
+ return;
249
+ }
250
+ }
251
+ } catch (error) {
252
+ this.destroy(error);
253
+ } finally {
254
+ this.reading = false;
255
+ }
256
+ }
257
+ async _exploreDir(path3, depth) {
258
+ let files;
259
+ try {
260
+ files = await (0, import_promises.readdir)(path3, this._rdOptions);
261
+ } catch (error) {
262
+ this._onError(error);
263
+ }
264
+ return { files, depth, path: path3 };
265
+ }
266
+ async _formatEntry(dirent, path3) {
267
+ let entry;
268
+ const basename4 = this._isDirent ? dirent.name : dirent;
269
+ try {
270
+ const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path3, basename4));
271
+ entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename4 };
272
+ entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
273
+ } catch (err) {
274
+ this._onError(err);
275
+ return;
276
+ }
277
+ return entry;
278
+ }
279
+ _onError(err) {
280
+ if (isNormalFlowError(err) && !this.destroyed) {
281
+ this.emit("warn", err);
282
+ } else {
283
+ this.destroy(err);
284
+ }
285
+ }
286
+ async _getEntryType(entry) {
287
+ if (!entry && this._statsProp in entry) {
288
+ return "";
289
+ }
290
+ const stats = entry[this._statsProp];
291
+ if (stats.isFile())
292
+ return "file";
293
+ if (stats.isDirectory())
294
+ return "directory";
295
+ if (stats && stats.isSymbolicLink()) {
296
+ const full = entry.fullPath;
297
+ try {
298
+ const entryRealPath = await (0, import_promises.realpath)(full);
299
+ const entryRealPathStats = await (0, import_promises.lstat)(entryRealPath);
300
+ if (entryRealPathStats.isFile()) {
301
+ return "file";
302
+ }
303
+ if (entryRealPathStats.isDirectory()) {
304
+ const len = entryRealPath.length;
305
+ if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path.sep) {
306
+ const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
307
+ recursiveError.code = RECURSIVE_ERROR_CODE;
308
+ return this._onError(recursiveError);
309
+ }
310
+ return "directory";
311
+ }
312
+ } catch (error) {
313
+ this._onError(error);
314
+ return "";
315
+ }
316
+ }
317
+ }
318
+ _includeAsFile(entry) {
319
+ const stats = entry && entry[this._statsProp];
320
+ return stats && this._wantsEverything && !stats.isDirectory();
321
+ }
322
+ };
323
+ }
324
+ });
325
+
326
+ // ../../node_modules/chokidar/esm/handler.js
327
+ function createFsWatchInstance(path3, options, listener, errHandler, emitRaw) {
328
+ const handleEvent = (rawEvent, evPath) => {
329
+ listener(path3);
330
+ emitRaw(rawEvent, evPath, { watchedPath: path3 });
331
+ if (evPath && path3 !== evPath) {
332
+ fsWatchBroadcast(sysPath.resolve(path3, evPath), KEY_LISTENERS, sysPath.join(path3, evPath));
333
+ }
334
+ };
335
+ try {
336
+ return (0, import_fs.watch)(path3, {
337
+ persistent: options.persistent
338
+ }, handleEvent);
339
+ } catch (error) {
340
+ errHandler(error);
341
+ return void 0;
342
+ }
343
+ }
344
+ var import_fs, import_promises2, sysPath, import_os, STR_DATA, STR_END, STR_CLOSE, EMPTY_FN, pl, isWindows, isMacos, isLinux, isFreeBSD, isIBMi, EVENTS, EV, THROTTLE_MODE_WATCH, statMethods, KEY_LISTENERS, KEY_ERR, KEY_RAW, HANDLER_KEYS, binaryExtensions, isBinaryPath, foreach, addAndConvert, clearItem, delFromSet, isEmptySet, FsWatchInstances, fsWatchBroadcast, setFsWatchListener, FsWatchFileInstances, setFsWatchFileListener, NodeFsHandler;
345
+ var init_handler = __esm({
346
+ "../../node_modules/chokidar/esm/handler.js"() {
347
+ "use strict";
348
+ import_fs = require("fs");
349
+ import_promises2 = require("fs/promises");
350
+ sysPath = __toESM(require("path"), 1);
351
+ import_os = require("os");
352
+ STR_DATA = "data";
353
+ STR_END = "end";
354
+ STR_CLOSE = "close";
355
+ EMPTY_FN = () => {
356
+ };
357
+ pl = process.platform;
358
+ isWindows = pl === "win32";
359
+ isMacos = pl === "darwin";
360
+ isLinux = pl === "linux";
361
+ isFreeBSD = pl === "freebsd";
362
+ isIBMi = (0, import_os.type)() === "OS400";
363
+ EVENTS = {
364
+ ALL: "all",
365
+ READY: "ready",
366
+ ADD: "add",
367
+ CHANGE: "change",
368
+ ADD_DIR: "addDir",
369
+ UNLINK: "unlink",
370
+ UNLINK_DIR: "unlinkDir",
371
+ RAW: "raw",
372
+ ERROR: "error"
373
+ };
374
+ EV = EVENTS;
375
+ THROTTLE_MODE_WATCH = "watch";
376
+ statMethods = { lstat: import_promises2.lstat, stat: import_promises2.stat };
377
+ KEY_LISTENERS = "listeners";
378
+ KEY_ERR = "errHandlers";
379
+ KEY_RAW = "rawEmitters";
380
+ HANDLER_KEYS = [KEY_LISTENERS, KEY_ERR, KEY_RAW];
381
+ binaryExtensions = /* @__PURE__ */ new Set([
382
+ "3dm",
383
+ "3ds",
384
+ "3g2",
385
+ "3gp",
386
+ "7z",
387
+ "a",
388
+ "aac",
389
+ "adp",
390
+ "afdesign",
391
+ "afphoto",
392
+ "afpub",
393
+ "ai",
394
+ "aif",
395
+ "aiff",
396
+ "alz",
397
+ "ape",
398
+ "apk",
399
+ "appimage",
400
+ "ar",
401
+ "arj",
402
+ "asf",
403
+ "au",
404
+ "avi",
405
+ "bak",
406
+ "baml",
407
+ "bh",
408
+ "bin",
409
+ "bk",
410
+ "bmp",
411
+ "btif",
412
+ "bz2",
413
+ "bzip2",
414
+ "cab",
415
+ "caf",
416
+ "cgm",
417
+ "class",
418
+ "cmx",
419
+ "cpio",
420
+ "cr2",
421
+ "cur",
422
+ "dat",
423
+ "dcm",
424
+ "deb",
425
+ "dex",
426
+ "djvu",
427
+ "dll",
428
+ "dmg",
429
+ "dng",
430
+ "doc",
431
+ "docm",
432
+ "docx",
433
+ "dot",
434
+ "dotm",
435
+ "dra",
436
+ "DS_Store",
437
+ "dsk",
438
+ "dts",
439
+ "dtshd",
440
+ "dvb",
441
+ "dwg",
442
+ "dxf",
443
+ "ecelp4800",
444
+ "ecelp7470",
445
+ "ecelp9600",
446
+ "egg",
447
+ "eol",
448
+ "eot",
449
+ "epub",
450
+ "exe",
451
+ "f4v",
452
+ "fbs",
453
+ "fh",
454
+ "fla",
455
+ "flac",
456
+ "flatpak",
457
+ "fli",
458
+ "flv",
459
+ "fpx",
460
+ "fst",
461
+ "fvt",
462
+ "g3",
463
+ "gh",
464
+ "gif",
465
+ "graffle",
466
+ "gz",
467
+ "gzip",
468
+ "h261",
469
+ "h263",
470
+ "h264",
471
+ "icns",
472
+ "ico",
473
+ "ief",
474
+ "img",
475
+ "ipa",
476
+ "iso",
477
+ "jar",
478
+ "jpeg",
479
+ "jpg",
480
+ "jpgv",
481
+ "jpm",
482
+ "jxr",
483
+ "key",
484
+ "ktx",
485
+ "lha",
486
+ "lib",
487
+ "lvp",
488
+ "lz",
489
+ "lzh",
490
+ "lzma",
491
+ "lzo",
492
+ "m3u",
493
+ "m4a",
494
+ "m4v",
495
+ "mar",
496
+ "mdi",
497
+ "mht",
498
+ "mid",
499
+ "midi",
500
+ "mj2",
501
+ "mka",
502
+ "mkv",
503
+ "mmr",
504
+ "mng",
505
+ "mobi",
506
+ "mov",
507
+ "movie",
508
+ "mp3",
509
+ "mp4",
510
+ "mp4a",
511
+ "mpeg",
512
+ "mpg",
513
+ "mpga",
514
+ "mxu",
515
+ "nef",
516
+ "npx",
517
+ "numbers",
518
+ "nupkg",
519
+ "o",
520
+ "odp",
521
+ "ods",
522
+ "odt",
523
+ "oga",
524
+ "ogg",
525
+ "ogv",
526
+ "otf",
527
+ "ott",
528
+ "pages",
529
+ "pbm",
530
+ "pcx",
531
+ "pdb",
532
+ "pdf",
533
+ "pea",
534
+ "pgm",
535
+ "pic",
536
+ "png",
537
+ "pnm",
538
+ "pot",
539
+ "potm",
540
+ "potx",
541
+ "ppa",
542
+ "ppam",
543
+ "ppm",
544
+ "pps",
545
+ "ppsm",
546
+ "ppsx",
547
+ "ppt",
548
+ "pptm",
549
+ "pptx",
550
+ "psd",
551
+ "pya",
552
+ "pyc",
553
+ "pyo",
554
+ "pyv",
555
+ "qt",
556
+ "rar",
557
+ "ras",
558
+ "raw",
559
+ "resources",
560
+ "rgb",
561
+ "rip",
562
+ "rlc",
563
+ "rmf",
564
+ "rmvb",
565
+ "rpm",
566
+ "rtf",
567
+ "rz",
568
+ "s3m",
569
+ "s7z",
570
+ "scpt",
571
+ "sgi",
572
+ "shar",
573
+ "snap",
574
+ "sil",
575
+ "sketch",
576
+ "slk",
577
+ "smv",
578
+ "snk",
579
+ "so",
580
+ "stl",
581
+ "suo",
582
+ "sub",
583
+ "swf",
584
+ "tar",
585
+ "tbz",
586
+ "tbz2",
587
+ "tga",
588
+ "tgz",
589
+ "thmx",
590
+ "tif",
591
+ "tiff",
592
+ "tlz",
593
+ "ttc",
594
+ "ttf",
595
+ "txz",
596
+ "udf",
597
+ "uvh",
598
+ "uvi",
599
+ "uvm",
600
+ "uvp",
601
+ "uvs",
602
+ "uvu",
603
+ "viv",
604
+ "vob",
605
+ "war",
606
+ "wav",
607
+ "wax",
608
+ "wbmp",
609
+ "wdp",
610
+ "weba",
611
+ "webm",
612
+ "webp",
613
+ "whl",
614
+ "wim",
615
+ "wm",
616
+ "wma",
617
+ "wmv",
618
+ "wmx",
619
+ "woff",
620
+ "woff2",
621
+ "wrm",
622
+ "wvx",
623
+ "xbm",
624
+ "xif",
625
+ "xla",
626
+ "xlam",
627
+ "xls",
628
+ "xlsb",
629
+ "xlsm",
630
+ "xlsx",
631
+ "xlt",
632
+ "xltm",
633
+ "xltx",
634
+ "xm",
635
+ "xmind",
636
+ "xpi",
637
+ "xpm",
638
+ "xwd",
639
+ "xz",
640
+ "z",
641
+ "zip",
642
+ "zipx"
643
+ ]);
644
+ isBinaryPath = (filePath) => binaryExtensions.has(sysPath.extname(filePath).slice(1).toLowerCase());
645
+ foreach = (val, fn) => {
646
+ if (val instanceof Set) {
647
+ val.forEach(fn);
648
+ } else {
649
+ fn(val);
650
+ }
651
+ };
652
+ addAndConvert = (main, prop, item) => {
653
+ let container = main[prop];
654
+ if (!(container instanceof Set)) {
655
+ main[prop] = container = /* @__PURE__ */ new Set([container]);
656
+ }
657
+ container.add(item);
658
+ };
659
+ clearItem = (cont) => (key) => {
660
+ const set = cont[key];
661
+ if (set instanceof Set) {
662
+ set.clear();
663
+ } else {
664
+ delete cont[key];
665
+ }
666
+ };
667
+ delFromSet = (main, prop, item) => {
668
+ const container = main[prop];
669
+ if (container instanceof Set) {
670
+ container.delete(item);
671
+ } else if (container === item) {
672
+ delete main[prop];
673
+ }
674
+ };
675
+ isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
676
+ FsWatchInstances = /* @__PURE__ */ new Map();
677
+ fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
678
+ const cont = FsWatchInstances.get(fullPath);
679
+ if (!cont)
680
+ return;
681
+ foreach(cont[listenerType], (listener) => {
682
+ listener(val1, val2, val3);
683
+ });
684
+ };
685
+ setFsWatchListener = (path3, fullPath, options, handlers) => {
686
+ const { listener, errHandler, rawEmitter } = handlers;
687
+ let cont = FsWatchInstances.get(fullPath);
688
+ let watcher;
689
+ if (!options.persistent) {
690
+ watcher = createFsWatchInstance(path3, options, listener, errHandler, rawEmitter);
691
+ if (!watcher)
692
+ return;
693
+ return watcher.close.bind(watcher);
694
+ }
695
+ if (cont) {
696
+ addAndConvert(cont, KEY_LISTENERS, listener);
697
+ addAndConvert(cont, KEY_ERR, errHandler);
698
+ addAndConvert(cont, KEY_RAW, rawEmitter);
699
+ } else {
700
+ watcher = createFsWatchInstance(
701
+ path3,
702
+ options,
703
+ fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
704
+ errHandler,
705
+ // no need to use broadcast here
706
+ fsWatchBroadcast.bind(null, fullPath, KEY_RAW)
707
+ );
708
+ if (!watcher)
709
+ return;
710
+ watcher.on(EV.ERROR, async (error) => {
711
+ const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR);
712
+ if (cont)
713
+ cont.watcherUnusable = true;
714
+ if (isWindows && error.code === "EPERM") {
715
+ try {
716
+ const fd = await (0, import_promises2.open)(path3, "r");
717
+ await fd.close();
718
+ broadcastErr(error);
719
+ } catch (err) {
720
+ }
721
+ } else {
722
+ broadcastErr(error);
723
+ }
724
+ });
725
+ cont = {
726
+ listeners: listener,
727
+ errHandlers: errHandler,
728
+ rawEmitters: rawEmitter,
729
+ watcher
730
+ };
731
+ FsWatchInstances.set(fullPath, cont);
732
+ }
733
+ return () => {
734
+ delFromSet(cont, KEY_LISTENERS, listener);
735
+ delFromSet(cont, KEY_ERR, errHandler);
736
+ delFromSet(cont, KEY_RAW, rawEmitter);
737
+ if (isEmptySet(cont.listeners)) {
738
+ cont.watcher.close();
739
+ FsWatchInstances.delete(fullPath);
740
+ HANDLER_KEYS.forEach(clearItem(cont));
741
+ cont.watcher = void 0;
742
+ Object.freeze(cont);
743
+ }
744
+ };
745
+ };
746
+ FsWatchFileInstances = /* @__PURE__ */ new Map();
747
+ setFsWatchFileListener = (path3, fullPath, options, handlers) => {
748
+ const { listener, rawEmitter } = handlers;
749
+ let cont = FsWatchFileInstances.get(fullPath);
750
+ const copts = cont && cont.options;
751
+ if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
752
+ (0, import_fs.unwatchFile)(fullPath);
753
+ cont = void 0;
754
+ }
755
+ if (cont) {
756
+ addAndConvert(cont, KEY_LISTENERS, listener);
757
+ addAndConvert(cont, KEY_RAW, rawEmitter);
758
+ } else {
759
+ cont = {
760
+ listeners: listener,
761
+ rawEmitters: rawEmitter,
762
+ options,
763
+ watcher: (0, import_fs.watchFile)(fullPath, options, (curr, prev) => {
764
+ foreach(cont.rawEmitters, (rawEmitter2) => {
765
+ rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
766
+ });
767
+ const currmtime = curr.mtimeMs;
768
+ if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
769
+ foreach(cont.listeners, (listener2) => listener2(path3, curr));
770
+ }
771
+ })
772
+ };
773
+ FsWatchFileInstances.set(fullPath, cont);
774
+ }
775
+ return () => {
776
+ delFromSet(cont, KEY_LISTENERS, listener);
777
+ delFromSet(cont, KEY_RAW, rawEmitter);
778
+ if (isEmptySet(cont.listeners)) {
779
+ FsWatchFileInstances.delete(fullPath);
780
+ (0, import_fs.unwatchFile)(fullPath);
781
+ cont.options = cont.watcher = void 0;
782
+ Object.freeze(cont);
783
+ }
784
+ };
785
+ };
786
+ NodeFsHandler = class {
787
+ constructor(fsW) {
788
+ this.fsw = fsW;
789
+ this._boundHandleError = (error) => fsW._handleError(error);
790
+ }
791
+ /**
792
+ * Watch file for changes with fs_watchFile or fs_watch.
793
+ * @param path to file or dir
794
+ * @param listener on fs change
795
+ * @returns closer for the watcher instance
796
+ */
797
+ _watchWithNodeFs(path3, listener) {
798
+ const opts = this.fsw.options;
799
+ const directory = sysPath.dirname(path3);
800
+ const basename4 = sysPath.basename(path3);
801
+ const parent = this.fsw._getWatchedDir(directory);
802
+ parent.add(basename4);
803
+ const absolutePath = sysPath.resolve(path3);
804
+ const options = {
805
+ persistent: opts.persistent
806
+ };
807
+ if (!listener)
808
+ listener = EMPTY_FN;
809
+ let closer;
810
+ if (opts.usePolling) {
811
+ const enableBin = opts.interval !== opts.binaryInterval;
812
+ options.interval = enableBin && isBinaryPath(basename4) ? opts.binaryInterval : opts.interval;
813
+ closer = setFsWatchFileListener(path3, absolutePath, options, {
814
+ listener,
815
+ rawEmitter: this.fsw._emitRaw
816
+ });
817
+ } else {
818
+ closer = setFsWatchListener(path3, absolutePath, options, {
819
+ listener,
820
+ errHandler: this._boundHandleError,
821
+ rawEmitter: this.fsw._emitRaw
822
+ });
823
+ }
824
+ return closer;
825
+ }
826
+ /**
827
+ * Watch a file and emit add event if warranted.
828
+ * @returns closer for the watcher instance
829
+ */
830
+ _handleFile(file, stats, initialAdd) {
831
+ if (this.fsw.closed) {
832
+ return;
833
+ }
834
+ const dirname4 = sysPath.dirname(file);
835
+ const basename4 = sysPath.basename(file);
836
+ const parent = this.fsw._getWatchedDir(dirname4);
837
+ let prevStats = stats;
838
+ if (parent.has(basename4))
839
+ return;
840
+ const listener = async (path3, newStats) => {
841
+ if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
842
+ return;
843
+ if (!newStats || newStats.mtimeMs === 0) {
844
+ try {
845
+ const newStats2 = await (0, import_promises2.stat)(file);
846
+ if (this.fsw.closed)
847
+ return;
848
+ const at = newStats2.atimeMs;
849
+ const mt = newStats2.mtimeMs;
850
+ if (!at || at <= mt || mt !== prevStats.mtimeMs) {
851
+ this.fsw._emit(EV.CHANGE, file, newStats2);
852
+ }
853
+ if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
854
+ this.fsw._closeFile(path3);
855
+ prevStats = newStats2;
856
+ const closer2 = this._watchWithNodeFs(file, listener);
857
+ if (closer2)
858
+ this.fsw._addPathCloser(path3, closer2);
859
+ } else {
860
+ prevStats = newStats2;
861
+ }
862
+ } catch (error) {
863
+ this.fsw._remove(dirname4, basename4);
864
+ }
865
+ } else if (parent.has(basename4)) {
866
+ const at = newStats.atimeMs;
867
+ const mt = newStats.mtimeMs;
868
+ if (!at || at <= mt || mt !== prevStats.mtimeMs) {
869
+ this.fsw._emit(EV.CHANGE, file, newStats);
870
+ }
871
+ prevStats = newStats;
872
+ }
873
+ };
874
+ const closer = this._watchWithNodeFs(file, listener);
875
+ if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) {
876
+ if (!this.fsw._throttle(EV.ADD, file, 0))
877
+ return;
878
+ this.fsw._emit(EV.ADD, file, stats);
879
+ }
880
+ return closer;
881
+ }
882
+ /**
883
+ * Handle symlinks encountered while reading a dir.
884
+ * @param entry returned by readdirp
885
+ * @param directory path of dir being read
886
+ * @param path of this item
887
+ * @param item basename of this item
888
+ * @returns true if no more processing is needed for this entry.
889
+ */
890
+ async _handleSymlink(entry, directory, path3, item) {
891
+ if (this.fsw.closed) {
892
+ return;
893
+ }
894
+ const full = entry.fullPath;
895
+ const dir = this.fsw._getWatchedDir(directory);
896
+ if (!this.fsw.options.followSymlinks) {
897
+ this.fsw._incrReadyCount();
898
+ let linkPath;
899
+ try {
900
+ linkPath = await (0, import_promises2.realpath)(path3);
901
+ } catch (e) {
902
+ this.fsw._emitReady();
903
+ return true;
904
+ }
905
+ if (this.fsw.closed)
906
+ return;
907
+ if (dir.has(item)) {
908
+ if (this.fsw._symlinkPaths.get(full) !== linkPath) {
909
+ this.fsw._symlinkPaths.set(full, linkPath);
910
+ this.fsw._emit(EV.CHANGE, path3, entry.stats);
911
+ }
912
+ } else {
913
+ dir.add(item);
914
+ this.fsw._symlinkPaths.set(full, linkPath);
915
+ this.fsw._emit(EV.ADD, path3, entry.stats);
916
+ }
917
+ this.fsw._emitReady();
918
+ return true;
919
+ }
920
+ if (this.fsw._symlinkPaths.has(full)) {
921
+ return true;
922
+ }
923
+ this.fsw._symlinkPaths.set(full, true);
924
+ }
925
+ _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
926
+ directory = sysPath.join(directory, "");
927
+ throttler = this.fsw._throttle("readdir", directory, 1e3);
928
+ if (!throttler)
929
+ return;
930
+ const previous = this.fsw._getWatchedDir(wh.path);
931
+ const current = /* @__PURE__ */ new Set();
932
+ let stream = this.fsw._readdirp(directory, {
933
+ fileFilter: (entry) => wh.filterPath(entry),
934
+ directoryFilter: (entry) => wh.filterDir(entry)
935
+ });
936
+ if (!stream)
937
+ return;
938
+ stream.on(STR_DATA, async (entry) => {
939
+ if (this.fsw.closed) {
940
+ stream = void 0;
941
+ return;
942
+ }
943
+ const item = entry.path;
944
+ let path3 = sysPath.join(directory, item);
945
+ current.add(item);
946
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path3, item)) {
947
+ return;
948
+ }
949
+ if (this.fsw.closed) {
950
+ stream = void 0;
951
+ return;
952
+ }
953
+ if (item === target || !target && !previous.has(item)) {
954
+ this.fsw._incrReadyCount();
955
+ path3 = sysPath.join(dir, sysPath.relative(dir, path3));
956
+ this._addToNodeFs(path3, initialAdd, wh, depth + 1);
957
+ }
958
+ }).on(EV.ERROR, this._boundHandleError);
959
+ return new Promise((resolve4, reject) => {
960
+ if (!stream)
961
+ return reject();
962
+ stream.once(STR_END, () => {
963
+ if (this.fsw.closed) {
964
+ stream = void 0;
965
+ return;
966
+ }
967
+ const wasThrottled = throttler ? throttler.clear() : false;
968
+ resolve4(void 0);
969
+ previous.getChildren().filter((item) => {
970
+ return item !== directory && !current.has(item);
971
+ }).forEach((item) => {
972
+ this.fsw._remove(directory, item);
973
+ });
974
+ stream = void 0;
975
+ if (wasThrottled)
976
+ this._handleRead(directory, false, wh, target, dir, depth, throttler);
977
+ });
978
+ });
979
+ }
980
+ /**
981
+ * Read directory to add / remove files from `@watched` list and re-read it on change.
982
+ * @param dir fs path
983
+ * @param stats
984
+ * @param initialAdd
985
+ * @param depth relative to user-supplied path
986
+ * @param target child path targeted for watch
987
+ * @param wh Common watch helpers for this path
988
+ * @param realpath
989
+ * @returns closer for the watcher instance.
990
+ */
991
+ async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath2) {
992
+ const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir));
993
+ const tracked = parentDir.has(sysPath.basename(dir));
994
+ if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
995
+ this.fsw._emit(EV.ADD_DIR, dir, stats);
996
+ }
997
+ parentDir.add(sysPath.basename(dir));
998
+ this.fsw._getWatchedDir(dir);
999
+ let throttler;
1000
+ let closer;
1001
+ const oDepth = this.fsw.options.depth;
1002
+ if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath2)) {
1003
+ if (!target) {
1004
+ await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler);
1005
+ if (this.fsw.closed)
1006
+ return;
1007
+ }
1008
+ closer = this._watchWithNodeFs(dir, (dirPath, stats2) => {
1009
+ if (stats2 && stats2.mtimeMs === 0)
1010
+ return;
1011
+ this._handleRead(dirPath, false, wh, target, dir, depth, throttler);
1012
+ });
1013
+ }
1014
+ return closer;
1015
+ }
1016
+ /**
1017
+ * Handle added file, directory, or glob pattern.
1018
+ * Delegates call to _handleFile / _handleDir after checks.
1019
+ * @param path to file or ir
1020
+ * @param initialAdd was the file added at watch instantiation?
1021
+ * @param priorWh depth relative to user-supplied path
1022
+ * @param depth Child path actually targeted for watch
1023
+ * @param target Child path actually targeted for watch
1024
+ */
1025
+ async _addToNodeFs(path3, initialAdd, priorWh, depth, target) {
1026
+ const ready = this.fsw._emitReady;
1027
+ if (this.fsw._isIgnored(path3) || this.fsw.closed) {
1028
+ ready();
1029
+ return false;
1030
+ }
1031
+ const wh = this.fsw._getWatchHelpers(path3);
1032
+ if (priorWh) {
1033
+ wh.filterPath = (entry) => priorWh.filterPath(entry);
1034
+ wh.filterDir = (entry) => priorWh.filterDir(entry);
1035
+ }
1036
+ try {
1037
+ const stats = await statMethods[wh.statMethod](wh.watchPath);
1038
+ if (this.fsw.closed)
1039
+ return;
1040
+ if (this.fsw._isIgnored(wh.watchPath, stats)) {
1041
+ ready();
1042
+ return false;
1043
+ }
1044
+ const follow = this.fsw.options.followSymlinks;
1045
+ let closer;
1046
+ if (stats.isDirectory()) {
1047
+ const absPath = sysPath.resolve(path3);
1048
+ const targetPath = follow ? await (0, import_promises2.realpath)(path3) : path3;
1049
+ if (this.fsw.closed)
1050
+ return;
1051
+ closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
1052
+ if (this.fsw.closed)
1053
+ return;
1054
+ if (absPath !== targetPath && targetPath !== void 0) {
1055
+ this.fsw._symlinkPaths.set(absPath, targetPath);
1056
+ }
1057
+ } else if (stats.isSymbolicLink()) {
1058
+ const targetPath = follow ? await (0, import_promises2.realpath)(path3) : path3;
1059
+ if (this.fsw.closed)
1060
+ return;
1061
+ const parent = sysPath.dirname(wh.watchPath);
1062
+ this.fsw._getWatchedDir(parent).add(wh.watchPath);
1063
+ this.fsw._emit(EV.ADD, wh.watchPath, stats);
1064
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path3, wh, targetPath);
1065
+ if (this.fsw.closed)
1066
+ return;
1067
+ if (targetPath !== void 0) {
1068
+ this.fsw._symlinkPaths.set(sysPath.resolve(path3), targetPath);
1069
+ }
1070
+ } else {
1071
+ closer = this._handleFile(wh.watchPath, stats, initialAdd);
1072
+ }
1073
+ ready();
1074
+ if (closer)
1075
+ this.fsw._addPathCloser(path3, closer);
1076
+ return false;
1077
+ } catch (error) {
1078
+ if (this.fsw._handleError(error)) {
1079
+ ready();
1080
+ return path3;
1081
+ }
1082
+ }
1083
+ }
1084
+ };
1085
+ }
1086
+ });
1087
+
1088
+ // ../../node_modules/chokidar/esm/index.js
1089
+ var esm_exports = {};
1090
+ __export(esm_exports, {
1091
+ FSWatcher: () => FSWatcher,
1092
+ WatchHelper: () => WatchHelper,
1093
+ default: () => esm_default,
1094
+ watch: () => watch
1095
+ });
1096
+ function arrify(item) {
1097
+ return Array.isArray(item) ? item : [item];
1098
+ }
1099
+ function createPattern(matcher) {
1100
+ if (typeof matcher === "function")
1101
+ return matcher;
1102
+ if (typeof matcher === "string")
1103
+ return (string) => matcher === string;
1104
+ if (matcher instanceof RegExp)
1105
+ return (string) => matcher.test(string);
1106
+ if (typeof matcher === "object" && matcher !== null) {
1107
+ return (string) => {
1108
+ if (matcher.path === string)
1109
+ return true;
1110
+ if (matcher.recursive) {
1111
+ const relative3 = sysPath2.relative(matcher.path, string);
1112
+ if (!relative3) {
1113
+ return false;
1114
+ }
1115
+ return !relative3.startsWith("..") && !sysPath2.isAbsolute(relative3);
1116
+ }
1117
+ return false;
1118
+ };
1119
+ }
1120
+ return () => false;
1121
+ }
1122
+ function normalizePath(path3) {
1123
+ if (typeof path3 !== "string")
1124
+ throw new Error("string expected");
1125
+ path3 = sysPath2.normalize(path3);
1126
+ path3 = path3.replace(/\\/g, "/");
1127
+ let prepend = false;
1128
+ if (path3.startsWith("//"))
1129
+ prepend = true;
1130
+ const DOUBLE_SLASH_RE2 = /\/\//;
1131
+ while (path3.match(DOUBLE_SLASH_RE2))
1132
+ path3 = path3.replace(DOUBLE_SLASH_RE2, "/");
1133
+ if (prepend)
1134
+ path3 = "/" + path3;
1135
+ return path3;
1136
+ }
1137
+ function matchPatterns(patterns, testString, stats) {
1138
+ const path3 = normalizePath(testString);
1139
+ for (let index = 0; index < patterns.length; index++) {
1140
+ const pattern = patterns[index];
1141
+ if (pattern(path3, stats)) {
1142
+ return true;
1143
+ }
1144
+ }
1145
+ return false;
1146
+ }
1147
+ function anymatch(matchers, testString) {
1148
+ if (matchers == null) {
1149
+ throw new TypeError("anymatch: specify first argument");
1150
+ }
1151
+ const matchersArray = arrify(matchers);
1152
+ const patterns = matchersArray.map((matcher) => createPattern(matcher));
1153
+ if (testString == null) {
1154
+ return (testString2, stats) => {
1155
+ return matchPatterns(patterns, testString2, stats);
1156
+ };
1157
+ }
1158
+ return matchPatterns(patterns, testString);
1159
+ }
1160
+ function watch(paths, options = {}) {
1161
+ const watcher = new FSWatcher(options);
1162
+ watcher.add(paths);
1163
+ return watcher;
1164
+ }
1165
+ var import_fs2, import_promises3, import_events, sysPath2, SLASH, SLASH_SLASH, ONE_DOT, TWO_DOTS, STRING_TYPE, BACK_SLASH_RE, DOUBLE_SLASH_RE, DOT_RE, REPLACER_RE, isMatcherObject, unifyPaths, toUnix, normalizePathToUnix, normalizeIgnored, getAbsolutePath, EMPTY_SET, DirEntry, STAT_METHOD_F, STAT_METHOD_L, WatchHelper, FSWatcher, esm_default;
1166
+ var init_esm2 = __esm({
1167
+ "../../node_modules/chokidar/esm/index.js"() {
1168
+ "use strict";
1169
+ import_fs2 = require("fs");
1170
+ import_promises3 = require("fs/promises");
1171
+ import_events = require("events");
1172
+ sysPath2 = __toESM(require("path"), 1);
1173
+ init_esm();
1174
+ init_handler();
1175
+ SLASH = "/";
1176
+ SLASH_SLASH = "//";
1177
+ ONE_DOT = ".";
1178
+ TWO_DOTS = "..";
1179
+ STRING_TYPE = "string";
1180
+ BACK_SLASH_RE = /\\/g;
1181
+ DOUBLE_SLASH_RE = /\/\//;
1182
+ DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
1183
+ REPLACER_RE = /^\.[/\\]/;
1184
+ isMatcherObject = (matcher) => typeof matcher === "object" && matcher !== null && !(matcher instanceof RegExp);
1185
+ unifyPaths = (paths_) => {
1186
+ const paths = arrify(paths_).flat();
1187
+ if (!paths.every((p) => typeof p === STRING_TYPE)) {
1188
+ throw new TypeError(`Non-string provided as watch path: ${paths}`);
1189
+ }
1190
+ return paths.map(normalizePathToUnix);
1191
+ };
1192
+ toUnix = (string) => {
1193
+ let str = string.replace(BACK_SLASH_RE, SLASH);
1194
+ let prepend = false;
1195
+ if (str.startsWith(SLASH_SLASH)) {
1196
+ prepend = true;
1197
+ }
1198
+ while (str.match(DOUBLE_SLASH_RE)) {
1199
+ str = str.replace(DOUBLE_SLASH_RE, SLASH);
1200
+ }
1201
+ if (prepend) {
1202
+ str = SLASH + str;
1203
+ }
1204
+ return str;
1205
+ };
1206
+ normalizePathToUnix = (path3) => toUnix(sysPath2.normalize(toUnix(path3)));
1207
+ normalizeIgnored = (cwd = "") => (path3) => {
1208
+ if (typeof path3 === "string") {
1209
+ return normalizePathToUnix(sysPath2.isAbsolute(path3) ? path3 : sysPath2.join(cwd, path3));
1210
+ } else {
1211
+ return path3;
1212
+ }
1213
+ };
1214
+ getAbsolutePath = (path3, cwd) => {
1215
+ if (sysPath2.isAbsolute(path3)) {
1216
+ return path3;
1217
+ }
1218
+ return sysPath2.join(cwd, path3);
1219
+ };
1220
+ EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
1221
+ DirEntry = class {
1222
+ constructor(dir, removeWatcher) {
1223
+ this.path = dir;
1224
+ this._removeWatcher = removeWatcher;
1225
+ this.items = /* @__PURE__ */ new Set();
1226
+ }
1227
+ add(item) {
1228
+ const { items } = this;
1229
+ if (!items)
1230
+ return;
1231
+ if (item !== ONE_DOT && item !== TWO_DOTS)
1232
+ items.add(item);
1233
+ }
1234
+ async remove(item) {
1235
+ const { items } = this;
1236
+ if (!items)
1237
+ return;
1238
+ items.delete(item);
1239
+ if (items.size > 0)
1240
+ return;
1241
+ const dir = this.path;
1242
+ try {
1243
+ await (0, import_promises3.readdir)(dir);
1244
+ } catch (err) {
1245
+ if (this._removeWatcher) {
1246
+ this._removeWatcher(sysPath2.dirname(dir), sysPath2.basename(dir));
1247
+ }
1248
+ }
1249
+ }
1250
+ has(item) {
1251
+ const { items } = this;
1252
+ if (!items)
1253
+ return;
1254
+ return items.has(item);
1255
+ }
1256
+ getChildren() {
1257
+ const { items } = this;
1258
+ if (!items)
1259
+ return [];
1260
+ return [...items.values()];
1261
+ }
1262
+ dispose() {
1263
+ this.items.clear();
1264
+ this.path = "";
1265
+ this._removeWatcher = EMPTY_FN;
1266
+ this.items = EMPTY_SET;
1267
+ Object.freeze(this);
1268
+ }
1269
+ };
1270
+ STAT_METHOD_F = "stat";
1271
+ STAT_METHOD_L = "lstat";
1272
+ WatchHelper = class {
1273
+ constructor(path3, follow, fsw) {
1274
+ this.fsw = fsw;
1275
+ const watchPath = path3;
1276
+ this.path = path3 = path3.replace(REPLACER_RE, "");
1277
+ this.watchPath = watchPath;
1278
+ this.fullWatchPath = sysPath2.resolve(watchPath);
1279
+ this.dirParts = [];
1280
+ this.dirParts.forEach((parts) => {
1281
+ if (parts.length > 1)
1282
+ parts.pop();
1283
+ });
1284
+ this.followSymlinks = follow;
1285
+ this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
1286
+ }
1287
+ entryPath(entry) {
1288
+ return sysPath2.join(this.watchPath, sysPath2.relative(this.watchPath, entry.fullPath));
1289
+ }
1290
+ filterPath(entry) {
1291
+ const { stats } = entry;
1292
+ if (stats && stats.isSymbolicLink())
1293
+ return this.filterDir(entry);
1294
+ const resolvedPath = this.entryPath(entry);
1295
+ return this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats);
1296
+ }
1297
+ filterDir(entry) {
1298
+ return this.fsw._isntIgnored(this.entryPath(entry), entry.stats);
1299
+ }
1300
+ };
1301
+ FSWatcher = class extends import_events.EventEmitter {
1302
+ // Not indenting methods for history sake; for now.
1303
+ constructor(_opts = {}) {
1304
+ super();
1305
+ this.closed = false;
1306
+ this._closers = /* @__PURE__ */ new Map();
1307
+ this._ignoredPaths = /* @__PURE__ */ new Set();
1308
+ this._throttled = /* @__PURE__ */ new Map();
1309
+ this._streams = /* @__PURE__ */ new Set();
1310
+ this._symlinkPaths = /* @__PURE__ */ new Map();
1311
+ this._watched = /* @__PURE__ */ new Map();
1312
+ this._pendingWrites = /* @__PURE__ */ new Map();
1313
+ this._pendingUnlinks = /* @__PURE__ */ new Map();
1314
+ this._readyCount = 0;
1315
+ this._readyEmitted = false;
1316
+ const awf = _opts.awaitWriteFinish;
1317
+ const DEF_AWF = { stabilityThreshold: 2e3, pollInterval: 100 };
1318
+ const opts = {
1319
+ // Defaults
1320
+ persistent: true,
1321
+ ignoreInitial: false,
1322
+ ignorePermissionErrors: false,
1323
+ interval: 100,
1324
+ binaryInterval: 300,
1325
+ followSymlinks: true,
1326
+ usePolling: false,
1327
+ // useAsync: false,
1328
+ atomic: true,
1329
+ // NOTE: overwritten later (depends on usePolling)
1330
+ ..._opts,
1331
+ // Change format
1332
+ ignored: _opts.ignored ? arrify(_opts.ignored) : arrify([]),
1333
+ awaitWriteFinish: awf === true ? DEF_AWF : typeof awf === "object" ? { ...DEF_AWF, ...awf } : false
1334
+ };
1335
+ if (isIBMi)
1336
+ opts.usePolling = true;
1337
+ if (opts.atomic === void 0)
1338
+ opts.atomic = !opts.usePolling;
1339
+ const envPoll = process.env.CHOKIDAR_USEPOLLING;
1340
+ if (envPoll !== void 0) {
1341
+ const envLower = envPoll.toLowerCase();
1342
+ if (envLower === "false" || envLower === "0")
1343
+ opts.usePolling = false;
1344
+ else if (envLower === "true" || envLower === "1")
1345
+ opts.usePolling = true;
1346
+ else
1347
+ opts.usePolling = !!envLower;
1348
+ }
1349
+ const envInterval = process.env.CHOKIDAR_INTERVAL;
1350
+ if (envInterval)
1351
+ opts.interval = Number.parseInt(envInterval, 10);
1352
+ let readyCalls = 0;
1353
+ this._emitReady = () => {
1354
+ readyCalls++;
1355
+ if (readyCalls >= this._readyCount) {
1356
+ this._emitReady = EMPTY_FN;
1357
+ this._readyEmitted = true;
1358
+ process.nextTick(() => this.emit(EVENTS.READY));
1359
+ }
1360
+ };
1361
+ this._emitRaw = (...args) => this.emit(EVENTS.RAW, ...args);
1362
+ this._boundRemove = this._remove.bind(this);
1363
+ this.options = opts;
1364
+ this._nodeFsHandler = new NodeFsHandler(this);
1365
+ Object.freeze(opts);
1366
+ }
1367
+ _addIgnoredPath(matcher) {
1368
+ if (isMatcherObject(matcher)) {
1369
+ for (const ignored of this._ignoredPaths) {
1370
+ if (isMatcherObject(ignored) && ignored.path === matcher.path && ignored.recursive === matcher.recursive) {
1371
+ return;
1372
+ }
1373
+ }
1374
+ }
1375
+ this._ignoredPaths.add(matcher);
1376
+ }
1377
+ _removeIgnoredPath(matcher) {
1378
+ this._ignoredPaths.delete(matcher);
1379
+ if (typeof matcher === "string") {
1380
+ for (const ignored of this._ignoredPaths) {
1381
+ if (isMatcherObject(ignored) && ignored.path === matcher) {
1382
+ this._ignoredPaths.delete(ignored);
1383
+ }
1384
+ }
1385
+ }
1386
+ }
1387
+ // Public methods
1388
+ /**
1389
+ * Adds paths to be watched on an existing FSWatcher instance.
1390
+ * @param paths_ file or file list. Other arguments are unused
1391
+ */
1392
+ add(paths_, _origAdd, _internal) {
1393
+ const { cwd } = this.options;
1394
+ this.closed = false;
1395
+ this._closePromise = void 0;
1396
+ let paths = unifyPaths(paths_);
1397
+ if (cwd) {
1398
+ paths = paths.map((path3) => {
1399
+ const absPath = getAbsolutePath(path3, cwd);
1400
+ return absPath;
1401
+ });
1402
+ }
1403
+ paths.forEach((path3) => {
1404
+ this._removeIgnoredPath(path3);
1405
+ });
1406
+ this._userIgnored = void 0;
1407
+ if (!this._readyCount)
1408
+ this._readyCount = 0;
1409
+ this._readyCount += paths.length;
1410
+ Promise.all(paths.map(async (path3) => {
1411
+ const res = await this._nodeFsHandler._addToNodeFs(path3, !_internal, void 0, 0, _origAdd);
1412
+ if (res)
1413
+ this._emitReady();
1414
+ return res;
1415
+ })).then((results) => {
1416
+ if (this.closed)
1417
+ return;
1418
+ results.forEach((item) => {
1419
+ if (item)
1420
+ this.add(sysPath2.dirname(item), sysPath2.basename(_origAdd || item));
1421
+ });
1422
+ });
1423
+ return this;
1424
+ }
1425
+ /**
1426
+ * Close watchers or start ignoring events from specified paths.
1427
+ */
1428
+ unwatch(paths_) {
1429
+ if (this.closed)
1430
+ return this;
1431
+ const paths = unifyPaths(paths_);
1432
+ const { cwd } = this.options;
1433
+ paths.forEach((path3) => {
1434
+ if (!sysPath2.isAbsolute(path3) && !this._closers.has(path3)) {
1435
+ if (cwd)
1436
+ path3 = sysPath2.join(cwd, path3);
1437
+ path3 = sysPath2.resolve(path3);
1438
+ }
1439
+ this._closePath(path3);
1440
+ this._addIgnoredPath(path3);
1441
+ if (this._watched.has(path3)) {
1442
+ this._addIgnoredPath({
1443
+ path: path3,
1444
+ recursive: true
1445
+ });
1446
+ }
1447
+ this._userIgnored = void 0;
1448
+ });
1449
+ return this;
1450
+ }
1451
+ /**
1452
+ * Close watchers and remove all listeners from watched paths.
1453
+ */
1454
+ close() {
1455
+ if (this._closePromise) {
1456
+ return this._closePromise;
1457
+ }
1458
+ this.closed = true;
1459
+ this.removeAllListeners();
1460
+ const closers = [];
1461
+ this._closers.forEach((closerList) => closerList.forEach((closer) => {
1462
+ const promise = closer();
1463
+ if (promise instanceof Promise)
1464
+ closers.push(promise);
1465
+ }));
1466
+ this._streams.forEach((stream) => stream.destroy());
1467
+ this._userIgnored = void 0;
1468
+ this._readyCount = 0;
1469
+ this._readyEmitted = false;
1470
+ this._watched.forEach((dirent) => dirent.dispose());
1471
+ this._closers.clear();
1472
+ this._watched.clear();
1473
+ this._streams.clear();
1474
+ this._symlinkPaths.clear();
1475
+ this._throttled.clear();
1476
+ this._closePromise = closers.length ? Promise.all(closers).then(() => void 0) : Promise.resolve();
1477
+ return this._closePromise;
1478
+ }
1479
+ /**
1480
+ * Expose list of watched paths
1481
+ * @returns for chaining
1482
+ */
1483
+ getWatched() {
1484
+ const watchList = {};
1485
+ this._watched.forEach((entry, dir) => {
1486
+ const key = this.options.cwd ? sysPath2.relative(this.options.cwd, dir) : dir;
1487
+ const index = key || ONE_DOT;
1488
+ watchList[index] = entry.getChildren().sort();
1489
+ });
1490
+ return watchList;
1491
+ }
1492
+ emitWithAll(event, args) {
1493
+ this.emit(event, ...args);
1494
+ if (event !== EVENTS.ERROR)
1495
+ this.emit(EVENTS.ALL, event, ...args);
1496
+ }
1497
+ // Common helpers
1498
+ // --------------
1499
+ /**
1500
+ * Normalize and emit events.
1501
+ * Calling _emit DOES NOT MEAN emit() would be called!
1502
+ * @param event Type of event
1503
+ * @param path File or directory path
1504
+ * @param stats arguments to be passed with event
1505
+ * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
1506
+ */
1507
+ async _emit(event, path3, stats) {
1508
+ if (this.closed)
1509
+ return;
1510
+ const opts = this.options;
1511
+ if (isWindows)
1512
+ path3 = sysPath2.normalize(path3);
1513
+ if (opts.cwd)
1514
+ path3 = sysPath2.relative(opts.cwd, path3);
1515
+ const args = [path3];
1516
+ if (stats != null)
1517
+ args.push(stats);
1518
+ const awf = opts.awaitWriteFinish;
1519
+ let pw;
1520
+ if (awf && (pw = this._pendingWrites.get(path3))) {
1521
+ pw.lastChange = /* @__PURE__ */ new Date();
1522
+ return this;
1523
+ }
1524
+ if (opts.atomic) {
1525
+ if (event === EVENTS.UNLINK) {
1526
+ this._pendingUnlinks.set(path3, [event, ...args]);
1527
+ setTimeout(() => {
1528
+ this._pendingUnlinks.forEach((entry, path4) => {
1529
+ this.emit(...entry);
1530
+ this.emit(EVENTS.ALL, ...entry);
1531
+ this._pendingUnlinks.delete(path4);
1532
+ });
1533
+ }, typeof opts.atomic === "number" ? opts.atomic : 100);
1534
+ return this;
1535
+ }
1536
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path3)) {
1537
+ event = EVENTS.CHANGE;
1538
+ this._pendingUnlinks.delete(path3);
1539
+ }
1540
+ }
1541
+ if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
1542
+ const awfEmit = (err, stats2) => {
1543
+ if (err) {
1544
+ event = EVENTS.ERROR;
1545
+ args[0] = err;
1546
+ this.emitWithAll(event, args);
1547
+ } else if (stats2) {
1548
+ if (args.length > 1) {
1549
+ args[1] = stats2;
1550
+ } else {
1551
+ args.push(stats2);
1552
+ }
1553
+ this.emitWithAll(event, args);
1554
+ }
1555
+ };
1556
+ this._awaitWriteFinish(path3, awf.stabilityThreshold, event, awfEmit);
1557
+ return this;
1558
+ }
1559
+ if (event === EVENTS.CHANGE) {
1560
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path3, 50);
1561
+ if (isThrottled)
1562
+ return this;
1563
+ }
1564
+ if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
1565
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path3) : path3;
1566
+ let stats2;
1567
+ try {
1568
+ stats2 = await (0, import_promises3.stat)(fullPath);
1569
+ } catch (err) {
1570
+ }
1571
+ if (!stats2 || this.closed)
1572
+ return;
1573
+ args.push(stats2);
1574
+ }
1575
+ this.emitWithAll(event, args);
1576
+ return this;
1577
+ }
1578
+ /**
1579
+ * Common handler for errors
1580
+ * @returns The error if defined, otherwise the value of the FSWatcher instance's `closed` flag
1581
+ */
1582
+ _handleError(error) {
1583
+ const code = error && error.code;
1584
+ if (error && code !== "ENOENT" && code !== "ENOTDIR" && (!this.options.ignorePermissionErrors || code !== "EPERM" && code !== "EACCES")) {
1585
+ this.emit(EVENTS.ERROR, error);
1586
+ }
1587
+ return error || this.closed;
1588
+ }
1589
+ /**
1590
+ * Helper utility for throttling
1591
+ * @param actionType type being throttled
1592
+ * @param path being acted upon
1593
+ * @param timeout duration of time to suppress duplicate actions
1594
+ * @returns tracking object or false if action should be suppressed
1595
+ */
1596
+ _throttle(actionType, path3, timeout) {
1597
+ if (!this._throttled.has(actionType)) {
1598
+ this._throttled.set(actionType, /* @__PURE__ */ new Map());
1599
+ }
1600
+ const action = this._throttled.get(actionType);
1601
+ if (!action)
1602
+ throw new Error("invalid throttle");
1603
+ const actionPath = action.get(path3);
1604
+ if (actionPath) {
1605
+ actionPath.count++;
1606
+ return false;
1607
+ }
1608
+ let timeoutObject;
1609
+ const clear = () => {
1610
+ const item = action.get(path3);
1611
+ const count = item ? item.count : 0;
1612
+ action.delete(path3);
1613
+ clearTimeout(timeoutObject);
1614
+ if (item)
1615
+ clearTimeout(item.timeoutObject);
1616
+ return count;
1617
+ };
1618
+ timeoutObject = setTimeout(clear, timeout);
1619
+ const thr = { timeoutObject, clear, count: 0 };
1620
+ action.set(path3, thr);
1621
+ return thr;
1622
+ }
1623
+ _incrReadyCount() {
1624
+ return this._readyCount++;
1625
+ }
1626
+ /**
1627
+ * Awaits write operation to finish.
1628
+ * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback.
1629
+ * @param path being acted upon
1630
+ * @param threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished
1631
+ * @param event
1632
+ * @param awfEmit Callback to be called when ready for event to be emitted.
1633
+ */
1634
+ _awaitWriteFinish(path3, threshold, event, awfEmit) {
1635
+ const awf = this.options.awaitWriteFinish;
1636
+ if (typeof awf !== "object")
1637
+ return;
1638
+ const pollInterval = awf.pollInterval;
1639
+ let timeoutHandler;
1640
+ let fullPath = path3;
1641
+ if (this.options.cwd && !sysPath2.isAbsolute(path3)) {
1642
+ fullPath = sysPath2.join(this.options.cwd, path3);
1643
+ }
1644
+ const now = /* @__PURE__ */ new Date();
1645
+ const writes = this._pendingWrites;
1646
+ function awaitWriteFinishFn(prevStat) {
1647
+ (0, import_fs2.stat)(fullPath, (err, curStat) => {
1648
+ if (err || !writes.has(path3)) {
1649
+ if (err && err.code !== "ENOENT")
1650
+ awfEmit(err);
1651
+ return;
1652
+ }
1653
+ const now2 = Number(/* @__PURE__ */ new Date());
1654
+ if (prevStat && curStat.size !== prevStat.size) {
1655
+ writes.get(path3).lastChange = now2;
1656
+ }
1657
+ const pw = writes.get(path3);
1658
+ const df = now2 - pw.lastChange;
1659
+ if (df >= threshold) {
1660
+ writes.delete(path3);
1661
+ awfEmit(void 0, curStat);
1662
+ } else {
1663
+ timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
1664
+ }
1665
+ });
1666
+ }
1667
+ if (!writes.has(path3)) {
1668
+ writes.set(path3, {
1669
+ lastChange: now,
1670
+ cancelWait: () => {
1671
+ writes.delete(path3);
1672
+ clearTimeout(timeoutHandler);
1673
+ return event;
1674
+ }
1675
+ });
1676
+ timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
1677
+ }
1678
+ }
1679
+ /**
1680
+ * Determines whether user has asked to ignore this path.
1681
+ */
1682
+ _isIgnored(path3, stats) {
1683
+ if (this.options.atomic && DOT_RE.test(path3))
1684
+ return true;
1685
+ if (!this._userIgnored) {
1686
+ const { cwd } = this.options;
1687
+ const ign = this.options.ignored;
1688
+ const ignored = (ign || []).map(normalizeIgnored(cwd));
1689
+ const ignoredPaths = [...this._ignoredPaths];
1690
+ const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
1691
+ this._userIgnored = anymatch(list, void 0);
1692
+ }
1693
+ return this._userIgnored(path3, stats);
1694
+ }
1695
+ _isntIgnored(path3, stat4) {
1696
+ return !this._isIgnored(path3, stat4);
1697
+ }
1698
+ /**
1699
+ * Provides a set of common helpers and properties relating to symlink handling.
1700
+ * @param path file or directory pattern being watched
1701
+ */
1702
+ _getWatchHelpers(path3) {
1703
+ return new WatchHelper(path3, this.options.followSymlinks, this);
1704
+ }
1705
+ // Directory helpers
1706
+ // -----------------
1707
+ /**
1708
+ * Provides directory tracking objects
1709
+ * @param directory path of the directory
1710
+ */
1711
+ _getWatchedDir(directory) {
1712
+ const dir = sysPath2.resolve(directory);
1713
+ if (!this._watched.has(dir))
1714
+ this._watched.set(dir, new DirEntry(dir, this._boundRemove));
1715
+ return this._watched.get(dir);
1716
+ }
1717
+ // File helpers
1718
+ // ------------
1719
+ /**
1720
+ * Check for read permissions: https://stackoverflow.com/a/11781404/1358405
1721
+ */
1722
+ _hasReadPermissions(stats) {
1723
+ if (this.options.ignorePermissionErrors)
1724
+ return true;
1725
+ return Boolean(Number(stats.mode) & 256);
1726
+ }
1727
+ /**
1728
+ * Handles emitting unlink events for
1729
+ * files and directories, and via recursion, for
1730
+ * files and directories within directories that are unlinked
1731
+ * @param directory within which the following item is located
1732
+ * @param item base path of item/directory
1733
+ */
1734
+ _remove(directory, item, isDirectory) {
1735
+ const path3 = sysPath2.join(directory, item);
1736
+ const fullPath = sysPath2.resolve(path3);
1737
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path3) || this._watched.has(fullPath);
1738
+ if (!this._throttle("remove", path3, 100))
1739
+ return;
1740
+ if (!isDirectory && this._watched.size === 1) {
1741
+ this.add(directory, item, true);
1742
+ }
1743
+ const wp = this._getWatchedDir(path3);
1744
+ const nestedDirectoryChildren = wp.getChildren();
1745
+ nestedDirectoryChildren.forEach((nested) => this._remove(path3, nested));
1746
+ const parent = this._getWatchedDir(directory);
1747
+ const wasTracked = parent.has(item);
1748
+ parent.remove(item);
1749
+ if (this._symlinkPaths.has(fullPath)) {
1750
+ this._symlinkPaths.delete(fullPath);
1751
+ }
1752
+ let relPath = path3;
1753
+ if (this.options.cwd)
1754
+ relPath = sysPath2.relative(this.options.cwd, path3);
1755
+ if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
1756
+ const event = this._pendingWrites.get(relPath).cancelWait();
1757
+ if (event === EVENTS.ADD)
1758
+ return;
1759
+ }
1760
+ this._watched.delete(path3);
1761
+ this._watched.delete(fullPath);
1762
+ const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
1763
+ if (wasTracked && !this._isIgnored(path3))
1764
+ this._emit(eventName, path3);
1765
+ this._closePath(path3);
1766
+ }
1767
+ /**
1768
+ * Closes all watchers for a path
1769
+ */
1770
+ _closePath(path3) {
1771
+ this._closeFile(path3);
1772
+ const dir = sysPath2.dirname(path3);
1773
+ this._getWatchedDir(dir).remove(sysPath2.basename(path3));
1774
+ }
1775
+ /**
1776
+ * Closes only file-specific watchers
1777
+ */
1778
+ _closeFile(path3) {
1779
+ const closers = this._closers.get(path3);
1780
+ if (!closers)
1781
+ return;
1782
+ closers.forEach((closer) => closer());
1783
+ this._closers.delete(path3);
1784
+ }
1785
+ _addPathCloser(path3, closer) {
1786
+ if (!closer)
1787
+ return;
1788
+ let list = this._closers.get(path3);
1789
+ if (!list) {
1790
+ list = [];
1791
+ this._closers.set(path3, list);
1792
+ }
1793
+ list.push(closer);
1794
+ }
1795
+ _readdirp(root, opts) {
1796
+ if (this.closed)
1797
+ return;
1798
+ const options = { type: EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 };
1799
+ let stream = readdirp(root, options);
1800
+ this._streams.add(stream);
1801
+ stream.once(STR_CLOSE, () => {
1802
+ stream = void 0;
1803
+ });
1804
+ stream.once(STR_END, () => {
1805
+ if (stream) {
1806
+ this._streams.delete(stream);
1807
+ stream = void 0;
1808
+ }
1809
+ });
1810
+ return stream;
1811
+ }
1812
+ };
1813
+ esm_default = { watch, FSWatcher };
1814
+ }
1815
+ });
1816
+
1817
+ // src/cli/index.ts
1818
+ var fs3 = __toESM(require("fs"), 1);
1819
+ var path2 = __toESM(require("path"), 1);
1820
+ var import_commander = require("commander");
1821
+
1822
+ // src/generator.ts
1823
+ var fs2 = __toESM(require("fs"), 1);
1824
+ var path = __toESM(require("path"), 1);
1825
+
1826
+ // src/parser.ts
1827
+ var fs = __toESM(require("fs"), 1);
1828
+ function isDesignToken(obj) {
1829
+ return typeof obj === "object" && obj !== null && "$value" in obj && obj.$value !== void 0;
1830
+ }
1831
+ function isTokenGroup(obj) {
1832
+ if (typeof obj !== "object" || obj === null) {
1833
+ return false;
1834
+ }
1835
+ if (isDesignToken(obj)) {
1836
+ return false;
1837
+ }
1838
+ return Object.keys(obj).some((key) => !key.startsWith("$"));
1839
+ }
1840
+ function isReference(value) {
1841
+ if (typeof value !== "string") {
1842
+ return false;
1843
+ }
1844
+ return /^\{[\w.]+\}$/.test(value);
1845
+ }
1846
+ function extractReferencePath(ref) {
1847
+ const match = ref.match(/^\{([\w.]+)\}$/);
1848
+ if (!match) {
1849
+ throw new Error(`Invalid reference: ${ref}`);
1850
+ }
1851
+ return match[1].split(".");
1852
+ }
1853
+ function pathToCssVariable(path3, prefix = "nice") {
1854
+ return `--${prefix}-${path3.join("-")}`;
1855
+ }
1856
+ function pathToString(path3) {
1857
+ return path3.join(".");
1858
+ }
1859
+ function parseTokenFile(filePath) {
1860
+ const content = fs.readFileSync(filePath, "utf-8");
1861
+ const parsed = JSON.parse(content);
1862
+ return parsed;
1863
+ }
1864
+ function parseTokenFiles(filePaths) {
1865
+ const merged = {};
1866
+ for (const filePath of filePaths) {
1867
+ const tokens = parseTokenFile(filePath);
1868
+ mergeTokenFiles(merged, tokens);
1869
+ }
1870
+ return merged;
1871
+ }
1872
+ function mergeTokenFiles(target, source) {
1873
+ for (const [key, value] of Object.entries(source)) {
1874
+ if (key.startsWith("$")) {
1875
+ if (!(key in target)) {
1876
+ target[key] = value;
1877
+ }
1878
+ } else if (typeof value === "object" && value !== null) {
1879
+ if (!(key in target)) {
1880
+ target[key] = {};
1881
+ }
1882
+ const targetValue = target[key];
1883
+ if (typeof targetValue === "object" && targetValue !== null) {
1884
+ mergeTokenFiles(targetValue, value);
1885
+ }
1886
+ } else {
1887
+ target[key] = value;
1888
+ }
1889
+ }
1890
+ }
1891
+ function flattenTokens(tokenFile, prefix = [], inheritedType) {
1892
+ const tokens = [];
1893
+ const currentType = tokenFile.$type ?? inheritedType;
1894
+ for (const [key, value] of Object.entries(tokenFile)) {
1895
+ if (key.startsWith("$")) {
1896
+ continue;
1897
+ }
1898
+ const currentPath = [...prefix, key];
1899
+ if (isDesignToken(value)) {
1900
+ const token = value;
1901
+ const tokenType = token.$type ?? currentType;
1902
+ const references = [];
1903
+ findReferences(token.$value, references);
1904
+ tokens.push({
1905
+ path: currentPath,
1906
+ name: key,
1907
+ value: token.$value,
1908
+ resolvedValue: "",
1909
+ // Will be populated by resolver
1910
+ type: tokenType,
1911
+ description: token.$description,
1912
+ cssVariable: pathToCssVariable(currentPath),
1913
+ references: references.length > 0 ? references : void 0
1914
+ });
1915
+ } else if (isTokenGroup(value)) {
1916
+ const group = value;
1917
+ const groupType = group.$type ?? currentType;
1918
+ tokens.push(...flattenTokens(group, currentPath, groupType));
1919
+ }
1920
+ }
1921
+ return tokens;
1922
+ }
1923
+ function findReferences(value, refs) {
1924
+ if (typeof value === "string" && isReference(value)) {
1925
+ refs.push(extractReferencePath(value).join("."));
1926
+ } else if (typeof value === "object" && value !== null) {
1927
+ if (Array.isArray(value)) {
1928
+ for (const item of value) {
1929
+ findReferences(item, refs);
1930
+ }
1931
+ } else {
1932
+ for (const v of Object.values(value)) {
1933
+ findReferences(v, refs);
1934
+ }
1935
+ }
1936
+ }
1937
+ }
1938
+ function createTokenCollection(tokens) {
1939
+ const byPath = /* @__PURE__ */ new Map();
1940
+ const byName = /* @__PURE__ */ new Map();
1941
+ for (const token of tokens) {
1942
+ const pathStr = pathToString(token.path);
1943
+ byPath.set(pathStr, token);
1944
+ const existing = byName.get(token.name);
1945
+ if (!existing || token.path.length > existing.path.length) {
1946
+ byName.set(token.name, token);
1947
+ }
1948
+ }
1949
+ return { tokens, byPath, byName };
1950
+ }
1951
+ function getCategories(collection) {
1952
+ const categories = /* @__PURE__ */ new Set();
1953
+ for (const token of collection.tokens) {
1954
+ if (token.path.length > 0) {
1955
+ categories.add(token.path[0]);
1956
+ }
1957
+ }
1958
+ return Array.from(categories);
1959
+ }
1960
+
1961
+ // src/resolver.ts
1962
+ var MAX_RESOLUTION_DEPTH = 10;
1963
+ function resolveTokens(collection) {
1964
+ const resolvedTokens = collection.tokens.map((token) => {
1965
+ const resolved = { ...token };
1966
+ resolved.resolvedValue = resolveTokenValue(token.value, collection, 0);
1967
+ return resolved;
1968
+ });
1969
+ return {
1970
+ tokens: resolvedTokens,
1971
+ byPath: new Map(resolvedTokens.map((t) => [pathToString(t.path), t])),
1972
+ byName: new Map(resolvedTokens.map((t) => [t.name, t]))
1973
+ };
1974
+ }
1975
+ function resolveTokenValue(value, collection, depth) {
1976
+ if (depth > MAX_RESOLUTION_DEPTH) {
1977
+ throw new Error(`Maximum reference depth exceeded while resolving token`);
1978
+ }
1979
+ if (typeof value === "string") {
1980
+ if (isReference(value)) {
1981
+ const refPath = extractReferencePath(value);
1982
+ const refPathStr = pathToString(refPath);
1983
+ const refToken = collection.byPath.get(refPathStr);
1984
+ if (!refToken) {
1985
+ console.warn(`Reference not found: ${value}`);
1986
+ return value;
1987
+ }
1988
+ return resolveTokenValue(refToken.value, collection, depth + 1);
1989
+ }
1990
+ return value;
1991
+ }
1992
+ if (typeof value === "number") {
1993
+ return String(value);
1994
+ }
1995
+ if (Array.isArray(value)) {
1996
+ return value.map((v) => {
1997
+ if (typeof v === "string") {
1998
+ return v.includes(" ") ? `"${v}"` : v;
1999
+ }
2000
+ return String(v);
2001
+ }).join(", ");
2002
+ }
2003
+ if (isShadowValue(value)) {
2004
+ return resolveShadowValue(value, collection, depth);
2005
+ }
2006
+ if (Array.isArray(value) && value.length > 0 && isShadowValue(value[0])) {
2007
+ return value.map((s) => resolveShadowValue(s, collection, depth)).join(", ");
2008
+ }
2009
+ if (isTypographyValue(value)) {
2010
+ return resolveTypographyValue(value, collection, depth);
2011
+ }
2012
+ if (isBorderValue(value)) {
2013
+ return resolveBorderValue(value, collection, depth);
2014
+ }
2015
+ return JSON.stringify(value);
2016
+ }
2017
+ function isShadowValue(value) {
2018
+ if (typeof value !== "object" || value === null) {
2019
+ return false;
2020
+ }
2021
+ return "offsetX" in value && "offsetY" in value && "blur" in value;
2022
+ }
2023
+ function resolveShadowValue(shadow, collection, depth) {
2024
+ const offsetX = resolveTokenValue(shadow.offsetX, collection, depth);
2025
+ const offsetY = resolveTokenValue(shadow.offsetY, collection, depth);
2026
+ const blur = resolveTokenValue(shadow.blur, collection, depth);
2027
+ const spread = resolveTokenValue(shadow.spread, collection, depth);
2028
+ const color = resolveTokenValue(shadow.color, collection, depth);
2029
+ const inset = shadow.inset ? "inset " : "";
2030
+ return `${inset}${offsetX} ${offsetY} ${blur} ${spread} ${color}`;
2031
+ }
2032
+ function isTypographyValue(value) {
2033
+ if (typeof value !== "object" || value === null) {
2034
+ return false;
2035
+ }
2036
+ return "fontFamily" in value && "fontSize" in value;
2037
+ }
2038
+ function resolveTypographyValue(typography, collection, depth) {
2039
+ const fontFamily = resolveTokenValue(typography.fontFamily, collection, depth);
2040
+ const fontSize = resolveTokenValue(typography.fontSize, collection, depth);
2041
+ const fontWeight = resolveTokenValue(typography.fontWeight, collection, depth);
2042
+ const lineHeight = typography.lineHeight ? resolveTokenValue(typography.lineHeight, collection, depth) : "normal";
2043
+ const fontStyle = typography.fontStyle || "normal";
2044
+ return `${fontStyle} ${fontWeight} ${fontSize}/${lineHeight} ${fontFamily}`;
2045
+ }
2046
+ function isBorderValue(value) {
2047
+ if (typeof value !== "object" || value === null) {
2048
+ return false;
2049
+ }
2050
+ return "color" in value && "width" in value && "style" in value;
2051
+ }
2052
+ function resolveBorderValue(border, collection, depth) {
2053
+ const width = resolveTokenValue(border.width, collection, depth);
2054
+ const style = resolveTokenValue(border.style, collection, depth);
2055
+ const color = resolveTokenValue(border.color, collection, depth);
2056
+ return `${width} ${style} ${color}`;
2057
+ }
2058
+
2059
+ // src/transforms.ts
2060
+ function transformToCss(collection, prefix = "nice") {
2061
+ const lines = [];
2062
+ for (const token of collection.tokens) {
2063
+ const varName = `--${prefix}-${token.path.join("-")}`;
2064
+ lines.push(` ${varName}: ${token.resolvedValue};`);
2065
+ }
2066
+ return `:root {
2067
+ ${lines.join("\n")}
2068
+ }`;
2069
+ }
2070
+ function transformToScss(collection, prefix = "nice") {
2071
+ const lines = [];
2072
+ for (const token of collection.tokens) {
2073
+ const varName = `$${prefix}-${token.path.join("-")}`;
2074
+ lines.push(`${varName}: ${token.resolvedValue};`);
2075
+ }
2076
+ return lines.join("\n");
2077
+ }
2078
+ function transformToJs(collection, variableName = "tokens") {
2079
+ const obj = buildTokenObject(collection);
2080
+ return `export const ${variableName} = ${JSON.stringify(obj, null, 2)};`;
2081
+ }
2082
+ function transformToTs(collection, variableName = "tokens") {
2083
+ const obj = buildTokenObject(collection);
2084
+ const types = generateTokenTypes(collection);
2085
+ return `${types}
2086
+
2087
+ export const ${variableName}: Tokens = ${JSON.stringify(obj, null, 2)};`;
2088
+ }
2089
+ function buildTokenObject(collection) {
2090
+ const result = {};
2091
+ for (const token of collection.tokens) {
2092
+ let current = result;
2093
+ for (let i = 0; i < token.path.length - 1; i++) {
2094
+ const key = token.path[i];
2095
+ if (!(key in current)) {
2096
+ current[key] = {};
2097
+ }
2098
+ current = current[key];
2099
+ }
2100
+ const lastKey = token.path[token.path.length - 1];
2101
+ current[lastKey] = token.resolvedValue;
2102
+ }
2103
+ return result;
2104
+ }
2105
+ function generateTokenTypes(collection) {
2106
+ const typeObj = buildTypeStructure(collection);
2107
+ return `interface Tokens ${formatTypeStructure(typeObj)}`;
2108
+ }
2109
+ function buildTypeStructure(collection) {
2110
+ const result = {};
2111
+ for (const token of collection.tokens) {
2112
+ let current = result;
2113
+ for (let i = 0; i < token.path.length - 1; i++) {
2114
+ const key = token.path[i];
2115
+ if (!(key in current)) {
2116
+ current[key] = {};
2117
+ }
2118
+ current = current[key];
2119
+ }
2120
+ const lastKey = token.path[token.path.length - 1];
2121
+ current[lastKey] = "string";
2122
+ }
2123
+ return result;
2124
+ }
2125
+ function formatTypeStructure(obj, indent = 0) {
2126
+ const spaces = " ".repeat(indent);
2127
+ const lines = ["{"];
2128
+ for (const [key, value] of Object.entries(obj)) {
2129
+ const safeKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `'${key}'`;
2130
+ if (typeof value === "string") {
2131
+ lines.push(`${spaces} ${safeKey}: ${value};`);
2132
+ } else {
2133
+ lines.push(
2134
+ `${spaces} ${safeKey}: ${formatTypeStructure(value, indent + 1)};`
2135
+ );
2136
+ }
2137
+ }
2138
+ lines.push(`${spaces}}`);
2139
+ return lines.join("\n");
2140
+ }
2141
+ function transformToTailwind(collection) {
2142
+ const colors = {};
2143
+ const spacing = {};
2144
+ const fontSize = {};
2145
+ const fontFamily = {};
2146
+ const borderRadius = {};
2147
+ const boxShadow = {};
2148
+ for (const token of collection.tokens) {
2149
+ const path3 = token.path;
2150
+ const value = token.resolvedValue;
2151
+ if (path3[0] === "color" || path3[0] === "colors") {
2152
+ setNestedValue(colors, path3.slice(1), value);
2153
+ } else if (path3[0] === "spacing") {
2154
+ spacing[path3.slice(1).join("-")] = value;
2155
+ } else if (path3[0] === "typography" && path3[1] === "fontSize") {
2156
+ fontSize[path3[2]] = value;
2157
+ } else if (path3[0] === "typography" && path3[1] === "fontFamily") {
2158
+ fontFamily[path3[2]] = value.split(",").map((f) => f.trim());
2159
+ } else if (path3[0] === "effects" && path3[1] === "radius") {
2160
+ borderRadius[path3[2]] = value;
2161
+ } else if (path3[0] === "effects" && path3[1] === "shadow") {
2162
+ boxShadow[path3[2]] = value;
2163
+ }
2164
+ }
2165
+ const config = {
2166
+ theme: {
2167
+ extend: {
2168
+ colors,
2169
+ spacing,
2170
+ fontSize,
2171
+ fontFamily,
2172
+ borderRadius,
2173
+ boxShadow
2174
+ }
2175
+ }
2176
+ };
2177
+ return `module.exports = ${JSON.stringify(config, null, 2)};`;
2178
+ }
2179
+ function setNestedValue(obj, path3, value) {
2180
+ let current = obj;
2181
+ for (let i = 0; i < path3.length - 1; i++) {
2182
+ const key = path3[i];
2183
+ if (!(key in current)) {
2184
+ current[key] = {};
2185
+ }
2186
+ current = current[key];
2187
+ }
2188
+ current[path3[path3.length - 1]] = value;
2189
+ }
2190
+ function applyThemeOverrides(baseCollection, overrides) {
2191
+ const mergedTokens = [...baseCollection.tokens];
2192
+ for (const override of overrides.tokens) {
2193
+ const pathStr = pathToString(override.path);
2194
+ const existingIndex = mergedTokens.findIndex((t) => pathToString(t.path) === pathStr);
2195
+ if (existingIndex >= 0) {
2196
+ mergedTokens[existingIndex] = { ...mergedTokens[existingIndex], ...override };
2197
+ } else {
2198
+ mergedTokens.push(override);
2199
+ }
2200
+ }
2201
+ return {
2202
+ tokens: mergedTokens,
2203
+ byPath: new Map(mergedTokens.map((t) => [pathToString(t.path), t])),
2204
+ byName: new Map(mergedTokens.map((t) => [t.name, t]))
2205
+ };
2206
+ }
2207
+
2208
+ // src/themes.ts
2209
+ var defaultThemes = {
2210
+ light: {
2211
+ name: "light",
2212
+ displayName: "Light",
2213
+ mode: "light",
2214
+ selector: ':root, [data-theme="light"]'
2215
+ },
2216
+ dark: {
2217
+ name: "dark",
2218
+ displayName: "Dark",
2219
+ mode: "dark",
2220
+ selector: '[data-theme="dark"]',
2221
+ mediaQuery: "(prefers-color-scheme: dark)",
2222
+ extends: "light"
2223
+ },
2224
+ "high-contrast": {
2225
+ name: "high-contrast",
2226
+ displayName: "High Contrast",
2227
+ mode: "high-contrast",
2228
+ selector: '[data-theme="high-contrast"]',
2229
+ mediaQuery: "(prefers-contrast: more)",
2230
+ extends: "light"
2231
+ },
2232
+ "high-contrast-dark": {
2233
+ name: "high-contrast-dark",
2234
+ displayName: "High Contrast Dark",
2235
+ mode: "high-contrast-dark",
2236
+ selector: '[data-theme="high-contrast-dark"]',
2237
+ extends: "dark"
2238
+ },
2239
+ dim: {
2240
+ name: "dim",
2241
+ displayName: "Dim",
2242
+ mode: "dim",
2243
+ selector: '[data-theme="dim"]',
2244
+ extends: "dark"
2245
+ }
2246
+ };
2247
+ function createTheme(name, baseTokens, overrideTokens, config) {
2248
+ const tokens = overrideTokens ? applyThemeOverrides(baseTokens, overrideTokens) : baseTokens;
2249
+ const resolvedTokens = resolveTokens(tokens);
2250
+ const themeConfig = { ...defaultThemes.light, ...config, name };
2251
+ return {
2252
+ name,
2253
+ tokens: resolvedTokens,
2254
+ extends: themeConfig.extends,
2255
+ selector: themeConfig.selector,
2256
+ mediaQuery: themeConfig.mediaQuery
2257
+ };
2258
+ }
2259
+ function generateThemesCss(themes, prefix = "nice") {
2260
+ const sections = [];
2261
+ for (const theme of themes) {
2262
+ const vars = generateThemeVariables(theme, prefix);
2263
+ sections.push(`${theme.selector} {
2264
+ ${vars}
2265
+ }`);
2266
+ if (theme.mediaQuery) {
2267
+ sections.push(
2268
+ `@media ${theme.mediaQuery} {
2269
+ :root {
2270
+ ${vars.split("\n").map((l) => ` ${l}`).join("\n")}
2271
+ }
2272
+ }`
2273
+ );
2274
+ }
2275
+ }
2276
+ return sections.join("\n\n");
2277
+ }
2278
+ function generateThemeVariables(theme, prefix) {
2279
+ const lines = [];
2280
+ for (const token of theme.tokens.tokens) {
2281
+ const varName = `--${prefix}-${token.path.join("-")}`;
2282
+ lines.push(` ${varName}: ${token.resolvedValue};`);
2283
+ }
2284
+ return lines.join("\n");
2285
+ }
2286
+ function generateThemeSwitcher() {
2287
+ return `
2288
+ /**
2289
+ * Nice2Dev Theme Switcher
2290
+ * Auto-generated by @nice2dev/design-tokens
2291
+ */
2292
+
2293
+ const THEME_KEY = 'nice-theme';
2294
+ const THEMES = ['light', 'dark', 'high-contrast', 'high-contrast-dark', 'dim'];
2295
+
2296
+ /**
2297
+ * Get current theme
2298
+ */
2299
+ function getTheme() {
2300
+ return document.documentElement.getAttribute('data-theme') || 'light';
2301
+ }
2302
+
2303
+ /**
2304
+ * Set theme
2305
+ */
2306
+ function setTheme(theme) {
2307
+ if (!THEMES.includes(theme)) {
2308
+ console.warn(\`Invalid theme: \${theme}\`);
2309
+ return;
2310
+ }
2311
+
2312
+ document.documentElement.setAttribute('data-theme', theme);
2313
+ localStorage.setItem(THEME_KEY, theme);
2314
+
2315
+ // Dispatch event
2316
+ window.dispatchEvent(new CustomEvent('nice-theme-change', { detail: { theme } }));
2317
+ }
2318
+
2319
+ /**
2320
+ * Toggle between light and dark
2321
+ */
2322
+ function toggleTheme() {
2323
+ const current = getTheme();
2324
+ const next = current === 'dark' ? 'light' : 'dark';
2325
+ setTheme(next);
2326
+ return next;
2327
+ }
2328
+
2329
+ /**
2330
+ * Use system preference
2331
+ */
2332
+ function useSystemTheme() {
2333
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
2334
+ const prefersHighContrast = window.matchMedia('(prefers-contrast: more)').matches;
2335
+
2336
+ let theme = 'light';
2337
+ if (prefersDark && prefersHighContrast) {
2338
+ theme = 'high-contrast-dark';
2339
+ } else if (prefersDark) {
2340
+ theme = 'dark';
2341
+ } else if (prefersHighContrast) {
2342
+ theme = 'high-contrast';
2343
+ }
2344
+
2345
+ setTheme(theme);
2346
+ return theme;
2347
+ }
2348
+
2349
+ /**
2350
+ * Initialize theme on page load
2351
+ */
2352
+ function initTheme() {
2353
+ const saved = localStorage.getItem(THEME_KEY);
2354
+
2355
+ if (saved && THEMES.includes(saved)) {
2356
+ setTheme(saved);
2357
+ } else {
2358
+ useSystemTheme();
2359
+ }
2360
+
2361
+ // Listen for system changes
2362
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
2363
+ if (!localStorage.getItem(THEME_KEY)) {
2364
+ useSystemTheme();
2365
+ }
2366
+ });
2367
+ }
2368
+
2369
+ // Auto-init
2370
+ if (typeof document !== 'undefined') {
2371
+ if (document.readyState === 'loading') {
2372
+ document.addEventListener('DOMContentLoaded', initTheme);
2373
+ } else {
2374
+ initTheme();
2375
+ }
2376
+ }
2377
+
2378
+ export { getTheme, setTheme, toggleTheme, useSystemTheme, initTheme, THEMES };
2379
+ `.trim();
2380
+ }
2381
+ function generateReactThemeContext() {
2382
+ return `
2383
+ 'use client';
2384
+
2385
+ import React, { createContext, useContext, useEffect, useState, useCallback } from 'react';
2386
+
2387
+ type Theme = 'light' | 'dark' | 'high-contrast' | 'high-contrast-dark' | 'dim';
2388
+
2389
+ interface ThemeContextValue {
2390
+ theme: Theme;
2391
+ setTheme: (theme: Theme) => void;
2392
+ toggleTheme: () => void;
2393
+ useSystemTheme: () => void;
2394
+ }
2395
+
2396
+ const ThemeContext = createContext<ThemeContextValue | undefined>(undefined);
2397
+
2398
+ const THEME_KEY = 'nice-theme';
2399
+ const THEMES: Theme[] = ['light', 'dark', 'high-contrast', 'high-contrast-dark', 'dim'];
2400
+
2401
+ interface ThemeProviderProps {
2402
+ children: React.ReactNode;
2403
+ defaultTheme?: Theme;
2404
+ }
2405
+
2406
+ export function ThemeProvider({ children, defaultTheme = 'light' }: ThemeProviderProps) {
2407
+ const [theme, setThemeState] = useState<Theme>(defaultTheme);
2408
+
2409
+ useEffect(() => {
2410
+ const saved = localStorage.getItem(THEME_KEY) as Theme | null;
2411
+ if (saved && THEMES.includes(saved)) {
2412
+ setThemeState(saved);
2413
+ document.documentElement.setAttribute('data-theme', saved);
2414
+ } else {
2415
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
2416
+ const initial = prefersDark ? 'dark' : 'light';
2417
+ setThemeState(initial);
2418
+ document.documentElement.setAttribute('data-theme', initial);
2419
+ }
2420
+ }, []);
2421
+
2422
+ const setTheme = useCallback((newTheme: Theme) => {
2423
+ setThemeState(newTheme);
2424
+ document.documentElement.setAttribute('data-theme', newTheme);
2425
+ localStorage.setItem(THEME_KEY, newTheme);
2426
+ }, []);
2427
+
2428
+ const toggleTheme = useCallback(() => {
2429
+ setTheme(theme === 'dark' ? 'light' : 'dark');
2430
+ }, [theme, setTheme]);
2431
+
2432
+ const useSystemTheme = useCallback(() => {
2433
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
2434
+ const prefersHighContrast = window.matchMedia('(prefers-contrast: more)').matches;
2435
+
2436
+ let systemTheme: Theme = 'light';
2437
+ if (prefersDark && prefersHighContrast) {
2438
+ systemTheme = 'high-contrast-dark';
2439
+ } else if (prefersDark) {
2440
+ systemTheme = 'dark';
2441
+ } else if (prefersHighContrast) {
2442
+ systemTheme = 'high-contrast';
2443
+ }
2444
+
2445
+ setTheme(systemTheme);
2446
+ localStorage.removeItem(THEME_KEY);
2447
+ }, [setTheme]);
2448
+
2449
+ return (
2450
+ <ThemeContext.Provider value={{ theme, setTheme, toggleTheme, useSystemTheme }}>
2451
+ {children}
2452
+ </ThemeContext.Provider>
2453
+ );
2454
+ }
2455
+
2456
+ export function useTheme(): ThemeContextValue {
2457
+ const context = useContext(ThemeContext);
2458
+ if (!context) {
2459
+ throw new Error('useTheme must be used within a ThemeProvider');
2460
+ }
2461
+ return context;
2462
+ }
2463
+
2464
+ export { THEMES };
2465
+ export type { Theme };
2466
+ `.trim();
2467
+ }
2468
+
2469
+ // src/generator.ts
2470
+ var defaultOptions = {
2471
+ formats: ["css"],
2472
+ outputDir: "./dist",
2473
+ prefix: "nice",
2474
+ includePrimitives: true,
2475
+ separateFiles: false,
2476
+ includeDarkMode: true,
2477
+ includeComponents: true
2478
+ };
2479
+ var TokenGenerator = class {
2480
+ constructor(options = {}) {
2481
+ this.plugins = [];
2482
+ this.collection = null;
2483
+ this.themes = [];
2484
+ this.options = { ...defaultOptions, ...options };
2485
+ }
2486
+ /**
2487
+ * Add plugin
2488
+ */
2489
+ use(plugin) {
2490
+ this.plugins.push(plugin);
2491
+ return this;
2492
+ }
2493
+ /**
2494
+ * Load tokens from files
2495
+ */
2496
+ load(files) {
2497
+ const tokenFile = parseTokenFiles(files);
2498
+ let processedTokens = [tokenFile];
2499
+ for (const plugin of this.plugins) {
2500
+ if (plugin.beforeResolve) {
2501
+ processedTokens = plugin.beforeResolve(processedTokens);
2502
+ }
2503
+ }
2504
+ const flatTokens = flattenTokens(processedTokens[0]);
2505
+ let collection = createTokenCollection(flatTokens);
2506
+ collection = resolveTokens(collection);
2507
+ for (const plugin of this.plugins) {
2508
+ if (plugin.afterResolve) {
2509
+ collection = plugin.afterResolve(collection);
2510
+ }
2511
+ }
2512
+ this.collection = collection;
2513
+ return this;
2514
+ }
2515
+ /**
2516
+ * Load tokens from directory
2517
+ */
2518
+ loadDirectory(dir, pattern = "**/*.json") {
2519
+ const glob = require("fast-glob");
2520
+ const files = glob.sync(path.join(dir, pattern));
2521
+ return this.load(files);
2522
+ }
2523
+ /**
2524
+ * Add theme
2525
+ */
2526
+ addTheme(name, overrideTokens) {
2527
+ if (!this.collection) {
2528
+ throw new Error("Load tokens first before adding themes");
2529
+ }
2530
+ const theme = createTheme(name, this.collection, overrideTokens);
2531
+ this.themes.push(theme);
2532
+ return this;
2533
+ }
2534
+ /**
2535
+ * Generate output files
2536
+ */
2537
+ async generate() {
2538
+ if (!this.collection) {
2539
+ throw new Error("No tokens loaded");
2540
+ }
2541
+ fs2.mkdirSync(this.options.outputDir, { recursive: true });
2542
+ for (const format of this.options.formats) {
2543
+ await this.generateFormat(format);
2544
+ }
2545
+ if (this.themes.length > 0) {
2546
+ await this.generateThemeFiles();
2547
+ }
2548
+ }
2549
+ /**
2550
+ * Generate single format
2551
+ */
2552
+ async generateFormat(format) {
2553
+ if (!this.collection) {
2554
+ return;
2555
+ }
2556
+ for (const plugin of this.plugins) {
2557
+ if (plugin.customFormat) {
2558
+ const output = plugin.customFormat(this.collection, this.options);
2559
+ if (output) {
2560
+ const ext = this.getExtension(format);
2561
+ fs2.writeFileSync(
2562
+ path.join(this.options.outputDir, `tokens.${plugin.name}.${ext}`),
2563
+ output
2564
+ );
2565
+ }
2566
+ }
2567
+ }
2568
+ if (this.options.separateFiles) {
2569
+ await this.generateSeparateFiles(format);
2570
+ } else {
2571
+ await this.generateSingleFile(format);
2572
+ }
2573
+ }
2574
+ /**
2575
+ * Generate single output file
2576
+ */
2577
+ async generateSingleFile(format) {
2578
+ if (!this.collection) {
2579
+ return;
2580
+ }
2581
+ const content = this.transform(this.collection, format);
2582
+ const filename = `tokens.${this.getExtension(format)}`;
2583
+ const filepath = path.join(this.options.outputDir, filename);
2584
+ fs2.writeFileSync(filepath, content);
2585
+ console.log(`Generated: ${filepath}`);
2586
+ }
2587
+ /**
2588
+ * Generate separate files by category
2589
+ */
2590
+ async generateSeparateFiles(format) {
2591
+ if (!this.collection) {
2592
+ return;
2593
+ }
2594
+ const categories = getCategories(this.collection);
2595
+ const ext = this.getExtension(format);
2596
+ for (const category of categories) {
2597
+ const tokens = this.collection.tokens.filter((t) => t.path[0] === category);
2598
+ const catCollection = {
2599
+ tokens,
2600
+ byPath: new Map(tokens.map((t) => [t.path.join("."), t])),
2601
+ byName: new Map(tokens.map((t) => [t.name, t]))
2602
+ };
2603
+ const content = this.transform(catCollection, format);
2604
+ const filename = `${category}.${ext}`;
2605
+ const filepath = path.join(this.options.outputDir, filename);
2606
+ fs2.writeFileSync(filepath, content);
2607
+ console.log(`Generated: ${filepath}`);
2608
+ }
2609
+ this.generateIndexFile(categories, format);
2610
+ }
2611
+ /**
2612
+ * Generate index file for separated files
2613
+ */
2614
+ generateIndexFile(categories, format) {
2615
+ const ext = this.getExtension(format);
2616
+ let content = "";
2617
+ switch (format) {
2618
+ case "css":
2619
+ content = categories.map((c) => `@import './${c}.css';`).join("\n");
2620
+ break;
2621
+ case "scss":
2622
+ content = categories.map((c) => `@import './${c}';`).join("\n");
2623
+ break;
2624
+ case "js":
2625
+ case "ts":
2626
+ content = categories.map((c) => `export * from './${c}';`).join("\n");
2627
+ break;
2628
+ default:
2629
+ return;
2630
+ }
2631
+ const filepath = path.join(this.options.outputDir, `index.${ext}`);
2632
+ fs2.writeFileSync(filepath, content);
2633
+ console.log(`Generated: ${filepath}`);
2634
+ }
2635
+ /**
2636
+ * Transform collection to format
2637
+ */
2638
+ transform(collection, format) {
2639
+ const prefix = this.options.prefix ?? "nice";
2640
+ switch (format) {
2641
+ case "css":
2642
+ return transformToCss(collection, prefix);
2643
+ case "scss":
2644
+ return transformToScss(collection, prefix);
2645
+ case "js":
2646
+ return transformToJs(collection);
2647
+ case "ts":
2648
+ return transformToTs(collection);
2649
+ case "json":
2650
+ return JSON.stringify(this.buildNestedObject(collection), null, 2);
2651
+ case "tailwind":
2652
+ return transformToTailwind(collection);
2653
+ default:
2654
+ throw new Error(`Unsupported format: ${format}`);
2655
+ }
2656
+ }
2657
+ /**
2658
+ * Build nested object from flat tokens
2659
+ */
2660
+ buildNestedObject(collection) {
2661
+ const result = {};
2662
+ for (const token of collection.tokens) {
2663
+ let current = result;
2664
+ for (let i = 0; i < token.path.length - 1; i++) {
2665
+ const key = token.path[i];
2666
+ if (!(key in current)) {
2667
+ current[key] = {};
2668
+ }
2669
+ current = current[key];
2670
+ }
2671
+ current[token.path[token.path.length - 1]] = token.resolvedValue;
2672
+ }
2673
+ return result;
2674
+ }
2675
+ /**
2676
+ * Get file extension for format
2677
+ */
2678
+ getExtension(format) {
2679
+ switch (format) {
2680
+ case "css":
2681
+ return "css";
2682
+ case "scss":
2683
+ return "scss";
2684
+ case "js":
2685
+ return "js";
2686
+ case "ts":
2687
+ return "ts";
2688
+ case "json":
2689
+ return "json";
2690
+ case "tailwind":
2691
+ return "tailwind.js";
2692
+ default:
2693
+ return "txt";
2694
+ }
2695
+ }
2696
+ /**
2697
+ * Generate theme-related files
2698
+ */
2699
+ async generateThemeFiles() {
2700
+ const prefix = this.options.prefix ?? "nice";
2701
+ const themesCss = generateThemesCss(this.themes, prefix);
2702
+ fs2.writeFileSync(path.join(this.options.outputDir, "themes.css"), themesCss);
2703
+ console.log(`Generated: themes.css`);
2704
+ const switcherJs = generateThemeSwitcher();
2705
+ fs2.writeFileSync(path.join(this.options.outputDir, "theme-switcher.js"), switcherJs);
2706
+ console.log(`Generated: theme-switcher.js`);
2707
+ const reactContext = generateReactThemeContext();
2708
+ fs2.writeFileSync(path.join(this.options.outputDir, "ThemeContext.tsx"), reactContext);
2709
+ console.log(`Generated: ThemeContext.tsx`);
2710
+ }
2711
+ /**
2712
+ * Get generated token collection
2713
+ */
2714
+ getCollection() {
2715
+ return this.collection;
2716
+ }
2717
+ /**
2718
+ * Get generated themes
2719
+ */
2720
+ getThemes() {
2721
+ return this.themes;
2722
+ }
2723
+ };
2724
+ function createGenerator(options) {
2725
+ return new TokenGenerator(options);
2726
+ }
2727
+
2728
+ // src/cli/index.ts
2729
+ var pkg = require_package();
2730
+ var program = new import_commander.Command();
2731
+ program.name("nice-tokens").description("Generate design tokens in various formats").version(pkg.version);
2732
+ program.command("build").description("Build design tokens from JSON source files").option("-i, --input <dir>", "Input directory containing token JSON files", "./tokens").option("-o, --output <dir>", "Output directory for generated files", "./dist").option(
2733
+ "-f, --formats <formats>",
2734
+ "Output formats (comma-separated: css,scss,js,ts,json,tailwind)",
2735
+ "css"
2736
+ ).option("-p, --prefix <prefix>", "CSS variable prefix", "nice").option("--separate", "Generate separate files by category").option("--no-dark", "Exclude dark mode tokens").option("--no-components", "Exclude component tokens").option("--watch", "Watch for changes and rebuild").action(async (options) => {
2737
+ const formats = options.formats.split(",").map((f) => f.trim());
2738
+ console.log("\u{1F3A8} Nice2Dev Design Tokens Generator\n");
2739
+ console.log(`\u{1F4C1} Input: ${path2.resolve(options.input)}`);
2740
+ console.log(`\u{1F4C1} Output: ${path2.resolve(options.output)}`);
2741
+ console.log(`\u{1F4C4} Formats: ${formats.join(", ")}`);
2742
+ console.log("");
2743
+ try {
2744
+ const generator = createGenerator({
2745
+ outputDir: options.output,
2746
+ formats,
2747
+ prefix: options.prefix,
2748
+ separateFiles: options.separate,
2749
+ includeDarkMode: options.dark !== false,
2750
+ includeComponents: options.components !== false
2751
+ });
2752
+ generator.loadDirectory(options.input);
2753
+ await generator.generate();
2754
+ console.log("\n\u2705 Build complete!");
2755
+ if (options.watch) {
2756
+ console.log("\n\u{1F440} Watching for changes...");
2757
+ const chokidar = await Promise.resolve().then(() => (init_esm2(), esm_exports));
2758
+ const watcher = chokidar.watch(path2.join(options.input, "**/*.json"), {
2759
+ ignoreInitial: true
2760
+ });
2761
+ watcher.on("change", async (file) => {
2762
+ console.log(`
2763
+ \u{1F504} File changed: ${path2.basename(file)}`);
2764
+ try {
2765
+ const gen = createGenerator({
2766
+ outputDir: options.output,
2767
+ formats,
2768
+ prefix: options.prefix,
2769
+ separateFiles: options.separate,
2770
+ includeDarkMode: options.dark !== false,
2771
+ includeComponents: options.components !== false
2772
+ });
2773
+ gen.loadDirectory(options.input);
2774
+ await gen.generate();
2775
+ console.log("\u2705 Rebuild complete!");
2776
+ } catch (err) {
2777
+ console.error("\u274C Rebuild failed:", err.message);
2778
+ }
2779
+ });
2780
+ }
2781
+ } catch (err) {
2782
+ console.error("\u274C Build failed:", err.message);
2783
+ process.exit(1);
2784
+ }
2785
+ });
2786
+ program.command("init").description("Initialize a new design tokens project").option("-d, --dir <dir>", "Directory to initialize", ".").action(async (options) => {
2787
+ const dir = path2.resolve(options.dir);
2788
+ const tokensDir = path2.join(dir, "tokens");
2789
+ console.log("\u{1F3A8} Initializing Nice2Dev Design Tokens\n");
2790
+ fs3.mkdirSync(tokensDir, { recursive: true });
2791
+ fs3.mkdirSync(path2.join(dir, "dist"), { recursive: true });
2792
+ const colorsJson = {
2793
+ color: {
2794
+ $type: "color",
2795
+ primary: {
2796
+ "50": { $value: "#eff6ff" },
2797
+ "100": { $value: "#dbeafe" },
2798
+ "500": { $value: "#3b82f6" },
2799
+ "600": { $value: "#2563eb" },
2800
+ "700": { $value: "#1d4ed8" },
2801
+ "900": { $value: "#1e3a8a" }
2802
+ },
2803
+ gray: {
2804
+ "50": { $value: "#f9fafb" },
2805
+ "100": { $value: "#f3f4f6" },
2806
+ "500": { $value: "#6b7280" },
2807
+ "700": { $value: "#374151" },
2808
+ "900": { $value: "#111827" }
2809
+ }
2810
+ }
2811
+ };
2812
+ fs3.writeFileSync(path2.join(tokensDir, "colors.json"), JSON.stringify(colorsJson, null, 2));
2813
+ const typographyJson = {
2814
+ typography: {
2815
+ fontFamily: {
2816
+ $type: "fontFamily",
2817
+ sans: { $value: ["Inter", "system-ui", "sans-serif"] },
2818
+ mono: { $value: ["JetBrains Mono", "monospace"] }
2819
+ },
2820
+ fontSize: {
2821
+ $type: "dimension",
2822
+ xs: { $value: "0.75rem" },
2823
+ sm: { $value: "0.875rem" },
2824
+ base: { $value: "1rem" },
2825
+ lg: { $value: "1.125rem" },
2826
+ xl: { $value: "1.25rem" }
2827
+ }
2828
+ }
2829
+ };
2830
+ fs3.writeFileSync(
2831
+ path2.join(tokensDir, "typography.json"),
2832
+ JSON.stringify(typographyJson, null, 2)
2833
+ );
2834
+ const spacingJson = {
2835
+ spacing: {
2836
+ $type: "dimension",
2837
+ "0": { $value: "0" },
2838
+ "1": { $value: "0.25rem" },
2839
+ "2": { $value: "0.5rem" },
2840
+ "4": { $value: "1rem" },
2841
+ "6": { $value: "1.5rem" },
2842
+ "8": { $value: "2rem" }
2843
+ }
2844
+ };
2845
+ fs3.writeFileSync(path2.join(tokensDir, "spacing.json"), JSON.stringify(spacingJson, null, 2));
2846
+ console.log("\u2705 Created token files in ./tokens/");
2847
+ console.log("");
2848
+ console.log("Next steps:");
2849
+ console.log(" 1. Edit tokens in ./tokens/*.json");
2850
+ console.log(" 2. Run: nice-tokens build");
2851
+ console.log(" 3. Import generated CSS/JS from ./dist/");
2852
+ });
2853
+ program.command("validate").description("Validate design token files").argument("[files...]", "Token files to validate").option("-d, --dir <dir>", "Directory containing token files").action(async (files, options) => {
2854
+ const glob = require("fast-glob");
2855
+ let tokenFiles = files;
2856
+ if (options.dir) {
2857
+ tokenFiles = await glob(path2.join(options.dir, "**/*.json"));
2858
+ }
2859
+ if (tokenFiles.length === 0) {
2860
+ console.log("No token files specified");
2861
+ process.exit(1);
2862
+ }
2863
+ console.log("\u{1F50D} Validating design tokens\n");
2864
+ let hasErrors = false;
2865
+ for (const file of tokenFiles) {
2866
+ try {
2867
+ const content = fs3.readFileSync(file, "utf-8");
2868
+ JSON.parse(content);
2869
+ console.log(`\u2705 ${path2.basename(file)}`);
2870
+ } catch (err) {
2871
+ console.log(`\u274C ${path2.basename(file)}: ${err.message}`);
2872
+ hasErrors = true;
2873
+ }
2874
+ }
2875
+ if (hasErrors) {
2876
+ console.log("\n\u274C Validation failed");
2877
+ process.exit(1);
2878
+ } else {
2879
+ console.log("\n\u2705 All files valid");
2880
+ }
2881
+ });
2882
+ program.command("convert").description("Convert between token formats").argument("<input>", "Input file or directory").argument("<output>", "Output file").option("-f, --format <format>", "Output format", "css").action(async (input, output, options) => {
2883
+ const format = options.format;
2884
+ console.log(`\u{1F504} Converting to ${format}...
2885
+ `);
2886
+ try {
2887
+ const generator = createGenerator({
2888
+ formats: [format],
2889
+ outputDir: path2.dirname(output)
2890
+ });
2891
+ const inputStat = fs3.statSync(input);
2892
+ if (inputStat.isDirectory()) {
2893
+ generator.loadDirectory(input);
2894
+ } else {
2895
+ generator.load([input]);
2896
+ }
2897
+ await generator.generate();
2898
+ console.log(`\u2705 Converted to ${output}`);
2899
+ } catch (err) {
2900
+ console.error("\u274C Conversion failed:", err.message);
2901
+ process.exit(1);
2902
+ }
2903
+ });
2904
+ program.command("info").description("Show information about token files").argument("<dir>", "Directory containing token files").action(async (dir) => {
2905
+ const glob = require("fast-glob");
2906
+ const files = await glob(path2.join(dir, "**/*.json"));
2907
+ console.log("\u{1F4CA} Token Information\n");
2908
+ console.log(`Directory: ${path2.resolve(dir)}`);
2909
+ console.log(`Files: ${files.length}`);
2910
+ console.log("");
2911
+ const generator = createGenerator();
2912
+ generator.loadDirectory(dir);
2913
+ const collection = generator.getCollection();
2914
+ if (collection) {
2915
+ console.log(`Total tokens: ${collection.tokens.length}`);
2916
+ console.log("");
2917
+ const byType = /* @__PURE__ */ new Map();
2918
+ const byCategory = /* @__PURE__ */ new Map();
2919
+ for (const token of collection.tokens) {
2920
+ const type = token.type || "unknown";
2921
+ byType.set(type, (byType.get(type) || 0) + 1);
2922
+ const category = token.path[0] || "root";
2923
+ byCategory.set(category, (byCategory.get(category) || 0) + 1);
2924
+ }
2925
+ console.log("By type:");
2926
+ for (const [type, count] of byType.entries()) {
2927
+ console.log(` ${type}: ${count}`);
2928
+ }
2929
+ console.log("\nBy category:");
2930
+ for (const [category, count] of byCategory.entries()) {
2931
+ console.log(` ${category}: ${count}`);
2932
+ }
2933
+ }
2934
+ });
2935
+ program.command("diff").description("Compare two token files or directories").argument("<source>", "Source file or directory").argument("<target>", "Target file or directory").action(async (source, target) => {
2936
+ console.log("\u{1F50D} Comparing tokens\n");
2937
+ const generatorA = createGenerator();
2938
+ const generatorB = createGenerator();
2939
+ const statA = fs3.statSync(source);
2940
+ const statB = fs3.statSync(target);
2941
+ if (statA.isDirectory()) {
2942
+ generatorA.loadDirectory(source);
2943
+ } else {
2944
+ generatorA.load([source]);
2945
+ }
2946
+ if (statB.isDirectory()) {
2947
+ generatorB.loadDirectory(target);
2948
+ } else {
2949
+ generatorB.load([target]);
2950
+ }
2951
+ const collectionA = generatorA.getCollection();
2952
+ const collectionB = generatorB.getCollection();
2953
+ if (!collectionA || !collectionB) {
2954
+ console.error("Failed to load tokens");
2955
+ process.exit(1);
2956
+ }
2957
+ const pathsA = new Set(collectionA.tokens.map((t) => t.path.join(".")));
2958
+ const pathsB = new Set(collectionB.tokens.map((t) => t.path.join(".")));
2959
+ const added = [];
2960
+ const removed = [];
2961
+ const changed = [];
2962
+ for (const path3 of pathsB) {
2963
+ if (!pathsA.has(path3)) {
2964
+ added.push(path3);
2965
+ }
2966
+ }
2967
+ for (const path3 of pathsA) {
2968
+ if (!pathsB.has(path3)) {
2969
+ removed.push(path3);
2970
+ }
2971
+ }
2972
+ for (const tokenA of collectionA.tokens) {
2973
+ const path3 = tokenA.path.join(".");
2974
+ const tokenB = collectionB.byPath.get(path3);
2975
+ if (tokenB && tokenA.resolvedValue !== tokenB.resolvedValue) {
2976
+ changed.push(`${path3}: ${tokenA.resolvedValue} \u2192 ${tokenB.resolvedValue}`);
2977
+ }
2978
+ }
2979
+ if (added.length === 0 && removed.length === 0 && changed.length === 0) {
2980
+ console.log("No differences found");
2981
+ return;
2982
+ }
2983
+ if (added.length > 0) {
2984
+ console.log(`\u2795 Added (${added.length}):`);
2985
+ for (const p of added.slice(0, 10)) {
2986
+ console.log(` ${p}`);
2987
+ }
2988
+ if (added.length > 10) {
2989
+ console.log(` ... and ${added.length - 10} more`);
2990
+ }
2991
+ console.log("");
2992
+ }
2993
+ if (removed.length > 0) {
2994
+ console.log(`\u2796 Removed (${removed.length}):`);
2995
+ for (const p of removed.slice(0, 10)) {
2996
+ console.log(` ${p}`);
2997
+ }
2998
+ if (removed.length > 10) {
2999
+ console.log(` ... and ${removed.length - 10} more`);
3000
+ }
3001
+ console.log("");
3002
+ }
3003
+ if (changed.length > 0) {
3004
+ console.log(`\u{1F4DD} Changed (${changed.length}):`);
3005
+ for (const p of changed.slice(0, 10)) {
3006
+ console.log(` ${p}`);
3007
+ }
3008
+ if (changed.length > 10) {
3009
+ console.log(` ... and ${changed.length - 10} more`);
3010
+ }
3011
+ }
3012
+ });
3013
+ program.parse();
3014
+ /*! Bundled license information:
3015
+
3016
+ chokidar/esm/index.js:
3017
+ (*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) *)
3018
+ */