@kanso-labs/unplugin-style-dictionary 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +441 -32
- package/dist/index.d.ts +2 -5
- package/dist/index.js +146 -17
- package/dist/index.js.map +1 -1
- package/dist/rolldown.d.ts +2 -2
- package/dist/rollup.d.ts +2 -2
- package/dist/types.d.ts +136 -2
- package/dist/vite.d.ts +2 -2
- package/dist/watch-filter.js +13 -0
- package/dist/watch-filter.js.map +1 -0
- package/dist/webpack.d.ts +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
+
import { matchesWatchedFile } from "./watch-filter.js";
|
|
1
2
|
import JSON5 from "json5";
|
|
2
3
|
import fs from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { pathToFileURL } from "node:url";
|
|
5
6
|
import zlib from "node:zlib";
|
|
6
|
-
import picomatch from "picomatch";
|
|
7
7
|
import StyleDictionary from "style-dictionary";
|
|
8
8
|
import { glob } from "tinyglobby";
|
|
9
9
|
import { createUnplugin } from "unplugin";
|
|
10
10
|
//#region src/index.ts
|
|
11
|
-
function matchesWatchedFile(file, patterns) {
|
|
12
|
-
const normalizedFile = file.replace(/\\/g, "/");
|
|
13
|
-
return patterns.some((pattern) => {
|
|
14
|
-
const normalizedPattern = pattern.replace(/\\/g, "/");
|
|
15
|
-
return normalizedPattern === normalizedFile || picomatch.isMatch(normalizedFile, normalizedPattern);
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
11
|
function asError(error) {
|
|
19
12
|
return error instanceof Error ? error : new Error(errorMessage(error));
|
|
20
13
|
}
|
|
14
|
+
function colourAllowed(stream) {
|
|
15
|
+
if (process.env.NO_COLOR) return false;
|
|
16
|
+
const forced = process.env.FORCE_COLOR;
|
|
17
|
+
if (forced === "0") return false;
|
|
18
|
+
if (forced !== void 0 && forced !== "") return true;
|
|
19
|
+
if (process.env.TERM === "dumb") return false;
|
|
20
|
+
return stream.isTTY === true;
|
|
21
|
+
}
|
|
21
22
|
function discardTemporaryFile(temporary) {
|
|
22
23
|
try {
|
|
23
24
|
fs.rmSync(temporary, { force: true });
|
|
@@ -29,6 +30,15 @@ function errorMessage(error) {
|
|
|
29
30
|
function isConfig(value) {
|
|
30
31
|
return typeof value === "object" && value !== null;
|
|
31
32
|
}
|
|
33
|
+
function isMessageChannel(value) {
|
|
34
|
+
return typeof value === "function";
|
|
35
|
+
}
|
|
36
|
+
function isThenable(value) {
|
|
37
|
+
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
38
|
+
}
|
|
39
|
+
function paint(code, value, allowed) {
|
|
40
|
+
return allowed ? `\u001B[${code}m${value}\u001B[0m` : value;
|
|
41
|
+
}
|
|
32
42
|
function unwrapDefault(value) {
|
|
33
43
|
return typeof value === "object" && value !== null && "default" in value ? value.default ?? value : value;
|
|
34
44
|
}
|
|
@@ -130,11 +140,25 @@ function statOrNull(file) {
|
|
|
130
140
|
}
|
|
131
141
|
const unpluginFactory = (options = {}, meta) => {
|
|
132
142
|
const isWebpack = meta.framework === "webpack";
|
|
133
|
-
const { cache = true, failOnError = "build", logLevel, report = true, root: rootOption, silent = false } = options;
|
|
143
|
+
const { cache = true, errorOverlay = true, failOnError = "build", logLevel, onBuildEnd, onBuildError, onBuildStart, report = true, root: rootOption, silent = false } = options;
|
|
134
144
|
const level = logLevel ?? (silent ? "silent" : void 0);
|
|
135
145
|
const quiet = level === "silent" || level === "warn";
|
|
136
146
|
const verbosity = level === void 0 ? void 0 : level === "verbose" ? "verbose" : level === "silent" ? "silent" : "default";
|
|
137
147
|
const failsTheBuild = (context) => failOnError === true || (context === void 0 ? failOnError === "build" : failOnError === "serve");
|
|
148
|
+
let hostCommand = "build";
|
|
149
|
+
let hostMode;
|
|
150
|
+
let isWatching = false;
|
|
151
|
+
const configContext = () => ({
|
|
152
|
+
command: hostCommand,
|
|
153
|
+
mode: hostMode ?? (hostCommand === "serve" ? "development" : "production"),
|
|
154
|
+
watch: isWatching
|
|
155
|
+
});
|
|
156
|
+
const adoptWatchMode = (context) => {
|
|
157
|
+
const hookMeta = "meta" in context ? context.meta : void 0;
|
|
158
|
+
if (typeof hookMeta !== "object" || hookMeta === null) return;
|
|
159
|
+
const watching = "watchMode" in hookMeta ? hookMeta.watchMode : void 0;
|
|
160
|
+
if (typeof watching === "boolean") isWatching = watching;
|
|
161
|
+
};
|
|
138
162
|
let root = rootOption ? path.resolve(process.cwd(), rootOption) : process.cwd();
|
|
139
163
|
const generatedDestinations = /* @__PURE__ */ new Set();
|
|
140
164
|
let cachedPatterns;
|
|
@@ -156,15 +180,52 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
156
180
|
return Array.from(paths);
|
|
157
181
|
};
|
|
158
182
|
const isWatchedSource = (file, patterns) => !generatedDestinations.has(file.replace(/\\/g, "/")) && matchesWatchedFile(file, patterns);
|
|
183
|
+
const stdoutColour = colourAllowed(process.stdout);
|
|
184
|
+
const stderrColour = colourAllowed(process.stderr);
|
|
185
|
+
let host;
|
|
186
|
+
const adoptHost = (context) => {
|
|
187
|
+
if (host) return;
|
|
188
|
+
const warn = "warn" in context ? context.warn : void 0;
|
|
189
|
+
if (!isMessageChannel(warn)) return;
|
|
190
|
+
const info = "info" in context ? context.info : void 0;
|
|
191
|
+
host = {
|
|
192
|
+
error: (message) => {
|
|
193
|
+
warn.call(context, message);
|
|
194
|
+
},
|
|
195
|
+
info: isMessageChannel(info) ? (message) => {
|
|
196
|
+
info.call(context, message);
|
|
197
|
+
} : void 0
|
|
198
|
+
};
|
|
199
|
+
};
|
|
159
200
|
const log = (message, type = "info") => {
|
|
160
201
|
const prefix = "[unplugin-style-dictionary]";
|
|
161
202
|
if (type === "error") {
|
|
162
|
-
|
|
203
|
+
if (host) {
|
|
204
|
+
host.error(`${prefix} ${message}`);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
console.error(paint("31", `${prefix} ${message}`, stderrColour));
|
|
163
208
|
return;
|
|
164
209
|
}
|
|
165
210
|
if (quiet) return;
|
|
166
|
-
if (
|
|
167
|
-
|
|
211
|
+
if (host?.info) {
|
|
212
|
+
host.info(`${prefix} ${message}`);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
console.log(paint(type === "success" ? "32" : "36", `${prefix} ${message}`, stdoutColour));
|
|
216
|
+
};
|
|
217
|
+
const callHook = (name, hook, ...args) => {
|
|
218
|
+
let result;
|
|
219
|
+
try {
|
|
220
|
+
result = hook(...args);
|
|
221
|
+
} catch (err) {
|
|
222
|
+
log(`The ${name} hook threw: ${errorMessage(err)}`, "error");
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (!isThenable(result)) return;
|
|
226
|
+
Promise.resolve(result).catch((err) => {
|
|
227
|
+
log(`The ${name} hook rejected: ${errorMessage(err)}`, "error");
|
|
228
|
+
});
|
|
168
229
|
};
|
|
169
230
|
const resolveConfigs = async () => {
|
|
170
231
|
let rawConfig = options.config;
|
|
@@ -184,7 +245,7 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
184
245
|
log("No configuration specified and no default config file found. Style Dictionary will not compile.", "error");
|
|
185
246
|
return [];
|
|
186
247
|
}
|
|
187
|
-
if (typeof rawConfig === "function") rawConfig = await rawConfig();
|
|
248
|
+
if (typeof rawConfig === "function") rawConfig = await rawConfig(configContext());
|
|
188
249
|
return (Array.isArray(rawConfig) ? rawConfig : [rawConfig]).map((conf) => {
|
|
189
250
|
if (typeof conf === "string") {
|
|
190
251
|
const fullPath = path.resolve(root, conf);
|
|
@@ -314,7 +375,7 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
314
375
|
const displayPath = path.relative(root, filePath).replace(/\\/g, "/");
|
|
315
376
|
const dir = path.dirname(displayPath);
|
|
316
377
|
const base = path.basename(displayPath);
|
|
317
|
-
const coloredPath = dir === "." ?
|
|
378
|
+
const coloredPath = dir === "." ? paint("32", base, stdoutColour) : paint("90", `${dir}/`, stdoutColour) + paint("32", base, stdoutColour);
|
|
318
379
|
try {
|
|
319
380
|
const sizeStr = `${(fs.statSync(filePath).size / 1024).toFixed(2)} kB`;
|
|
320
381
|
const content = fs.readFileSync(filePath);
|
|
@@ -333,7 +394,7 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
333
394
|
for (const info of fileInfos) {
|
|
334
395
|
const pathPadding = " ".repeat(Math.max(2, longestPathLength - info.relativeDisplayPath.length + 2));
|
|
335
396
|
const sizePadded = info.sizeStr.padStart(longestSizeLength);
|
|
336
|
-
console.log(
|
|
397
|
+
console.log(info.coloredPath + pathPadding + paint("90", `${sizePadded} │ gzip: ${info.gzipSizeStr}`, stdoutColour));
|
|
337
398
|
}
|
|
338
399
|
}
|
|
339
400
|
};
|
|
@@ -343,6 +404,7 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
343
404
|
let skipped = 0;
|
|
344
405
|
try {
|
|
345
406
|
if (!context) log("Compiling design tokens...", "info");
|
|
407
|
+
if (onBuildStart) callHook("onBuildStart", onBuildStart);
|
|
346
408
|
for (const item of resolvedConfigs) {
|
|
347
409
|
const declared = cache ? await readConfigObject(item, false) : null;
|
|
348
410
|
if (declared && await isUpToDate(item, declared)) {
|
|
@@ -373,10 +435,17 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
373
435
|
} catch (err) {
|
|
374
436
|
const duration = Date.now() - startTime;
|
|
375
437
|
log(`Compilation failed after ${duration}ms: ${errorMessage(err)}`, "error");
|
|
438
|
+
notifyBuildOutcome?.(asError(err));
|
|
439
|
+
if (onBuildError) callHook("onBuildError", onBuildError, err);
|
|
376
440
|
if (failsTheBuild(context)) throw err;
|
|
377
441
|
return;
|
|
378
442
|
}
|
|
443
|
+
notifyBuildOutcome?.(null);
|
|
379
444
|
const duration = Date.now() - startTime;
|
|
445
|
+
if (onBuildEnd) {
|
|
446
|
+
const files = Array.from(generatedFiles).sort((left, right) => left.localeCompare(right));
|
|
447
|
+
callHook("onBuildEnd", onBuildEnd, files, duration);
|
|
448
|
+
}
|
|
380
449
|
const everythingSkipped = skipped === resolvedConfigs.length;
|
|
381
450
|
if (context) {
|
|
382
451
|
log(everythingSkipped ? `Design tokens already up to date after change in ${context} (${duration}ms)` : `Rebuilt design tokens due to change in ${context} (${duration}ms)`, "success");
|
|
@@ -418,6 +487,7 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
418
487
|
let inFlight;
|
|
419
488
|
let waiting = [];
|
|
420
489
|
let refreshServerWatchList;
|
|
490
|
+
let notifyBuildOutcome;
|
|
421
491
|
const drain = async () => {
|
|
422
492
|
while (pendingReason !== void 0) {
|
|
423
493
|
const reason = pendingReason;
|
|
@@ -437,7 +507,10 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
437
507
|
}
|
|
438
508
|
} catch (err) {
|
|
439
509
|
failure = { error: err };
|
|
440
|
-
if (!compiling)
|
|
510
|
+
if (!compiling) {
|
|
511
|
+
log(`Rebuild failed: ${errorMessage(err)}`, "error");
|
|
512
|
+
notifyBuildOutcome?.(asError(err));
|
|
513
|
+
}
|
|
441
514
|
}
|
|
442
515
|
for (const settle of resolvers) settle(failure);
|
|
443
516
|
}
|
|
@@ -460,6 +533,8 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
460
533
|
};
|
|
461
534
|
return {
|
|
462
535
|
async buildStart() {
|
|
536
|
+
adoptHost(this);
|
|
537
|
+
adoptWatchMode(this);
|
|
463
538
|
const resolved = await resolveConfigs();
|
|
464
539
|
if (resolved.length === 0) return;
|
|
465
540
|
const { paths } = await getWatchTargets(resolved);
|
|
@@ -476,8 +551,19 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
476
551
|
vite: {
|
|
477
552
|
configResolved(config) {
|
|
478
553
|
if (rootOption === void 0) root = config.root || process.cwd();
|
|
554
|
+
hostCommand = config.command;
|
|
555
|
+
hostMode = config.mode;
|
|
556
|
+
host = {
|
|
557
|
+
error: (message) => {
|
|
558
|
+
config.logger.error(message);
|
|
559
|
+
},
|
|
560
|
+
info: (message) => {
|
|
561
|
+
config.logger.info(message);
|
|
562
|
+
}
|
|
563
|
+
};
|
|
479
564
|
},
|
|
480
565
|
async configureServer(server) {
|
|
566
|
+
isWatching = true;
|
|
481
567
|
const resolved = await resolveConfigs();
|
|
482
568
|
if (resolved.length === 0) return;
|
|
483
569
|
let targets = await getWatchTargets(resolved);
|
|
@@ -486,6 +572,29 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
486
572
|
targets = await getWatchTargets(rebuilt);
|
|
487
573
|
server.watcher.add(targets.paths);
|
|
488
574
|
};
|
|
575
|
+
if (errorOverlay) {
|
|
576
|
+
let overlayShowing = false;
|
|
577
|
+
notifyBuildOutcome = (error) => {
|
|
578
|
+
if (error) {
|
|
579
|
+
overlayShowing = true;
|
|
580
|
+
server.hot.send({
|
|
581
|
+
err: {
|
|
582
|
+
message: error.message,
|
|
583
|
+
plugin: "unplugin-style-dictionary",
|
|
584
|
+
stack: error.stack ?? ""
|
|
585
|
+
},
|
|
586
|
+
type: "error"
|
|
587
|
+
});
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
if (!overlayShowing) return;
|
|
591
|
+
overlayShowing = false;
|
|
592
|
+
server.hot.send({
|
|
593
|
+
type: "update",
|
|
594
|
+
updates: []
|
|
595
|
+
});
|
|
596
|
+
};
|
|
597
|
+
}
|
|
489
598
|
server.watcher.on("all", (_event, file) => {
|
|
490
599
|
if (!isWatchedSource(file, targets.patterns)) return;
|
|
491
600
|
schedule(path.basename(file)).catch(() => {});
|
|
@@ -493,6 +602,8 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
493
602
|
}
|
|
494
603
|
},
|
|
495
604
|
async watchChange(id) {
|
|
605
|
+
adoptHost(this);
|
|
606
|
+
adoptWatchMode(this);
|
|
496
607
|
watchRebuild = true;
|
|
497
608
|
if (cachedPatterns && !isWatchedSource(id, cachedPatterns)) return;
|
|
498
609
|
const resolved = await resolveConfigs();
|
|
@@ -504,7 +615,25 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
504
615
|
},
|
|
505
616
|
webpack(compiler) {
|
|
506
617
|
if (rootOption === void 0) root = compiler.options.context ?? process.cwd();
|
|
618
|
+
hostMode = compiler.options.mode;
|
|
619
|
+
const pending = [];
|
|
620
|
+
host = { error: (message) => {
|
|
621
|
+
pending.push(message);
|
|
622
|
+
} };
|
|
623
|
+
compiler.hooks.compilation.tap("unplugin-style-dictionary", (compilation) => {
|
|
624
|
+
for (const message of pending.splice(0)) {
|
|
625
|
+
const reported = new Error(message);
|
|
626
|
+
reported.name = "UnpluginStyleDictionaryWarning";
|
|
627
|
+
compilation.warnings.push(reported);
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
const drainToConsole = () => {
|
|
631
|
+
for (const message of pending.splice(0)) console.error(paint("31", message, stderrColour));
|
|
632
|
+
};
|
|
633
|
+
compiler.hooks.failed.tap("unplugin-style-dictionary", drainToConsole);
|
|
634
|
+
compiler.hooks.done.tap("unplugin-style-dictionary", drainToConsole);
|
|
507
635
|
compiler.hooks.beforeCompile.tapPromise("unplugin-style-dictionary", async () => {
|
|
636
|
+
isWatching = compiler.watchMode;
|
|
508
637
|
const resolved = await resolveConfigs();
|
|
509
638
|
if (resolved.length === 0) return;
|
|
510
639
|
await compileOnceAcrossInstances(resolved);
|
|
@@ -515,6 +644,6 @@ const unpluginFactory = (options = {}, meta) => {
|
|
|
515
644
|
};
|
|
516
645
|
const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory);
|
|
517
646
|
//#endregion
|
|
518
|
-
export { unplugin as default, unplugin
|
|
647
|
+
export { unplugin as default, unplugin };
|
|
519
648
|
|
|
520
649
|
//# sourceMappingURL=index.js.map
|