@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/types.d.ts
CHANGED
|
@@ -11,12 +11,69 @@ import { Config } from "style-dictionary";
|
|
|
11
11
|
* build (e.g. `tsdown`/`rolldown build` without `--watch`) only builds once, in
|
|
12
12
|
* `buildStart`.
|
|
13
13
|
*
|
|
14
|
+
* Everything the plugin says goes through the host rather than to the console:
|
|
15
|
+
* Vite's `config.logger`, the plugin context under rollup and rolldown, and
|
|
16
|
+
* `compilation.warnings` under webpack, which is what puts a failed compile in
|
|
17
|
+
* `stats.toJson()`. A failure is reported on the warning channel and never the
|
|
18
|
+
* error one — rollup's `this.error` aborts the bundle, and that decision is
|
|
19
|
+
* `failOnError`'s alone. Where no host offers a channel the console is used,
|
|
20
|
+
* with colour gated on `NO_COLOR`, `FORCE_COLOR` and whether the stream is a
|
|
21
|
+
* terminal.
|
|
22
|
+
*
|
|
23
|
+
* The three `onBuild*` hooks are called synchronously and their return value
|
|
24
|
+
* is not awaited, so a build never waits for one. A hook may still be written
|
|
25
|
+
* `async`: a promise it returns is left to run on its own, and a rejection is
|
|
26
|
+
* caught and reported rather than reaching the host as an unhandled one. A
|
|
27
|
+
* hook that throws is reported and does not fail the build that called it.
|
|
28
|
+
*
|
|
29
|
+
* They return `Promise<void> | void` rather than `void` for that reason. Both
|
|
30
|
+
* accept an `async` hook as far as the compiler is concerned, but `void` alone
|
|
31
|
+
* makes one a `no-misused-promises` error under the type-aware lint rules a
|
|
32
|
+
* consumer is likely to be running — for a hook this documents as supported.
|
|
33
|
+
*
|
|
14
34
|
* Rolldown's watch mode is the exception, and it is not about glob patterns.
|
|
15
35
|
* `addWatchFile` is accepted either way, but what happens next differs by
|
|
16
36
|
* platform — on macOS a file registered through it is watched by nothing, while
|
|
17
37
|
* on a Linux runner the same edit reaches a rebuild. Do not rely on a token
|
|
18
38
|
* edit triggering a rebuild there.
|
|
19
39
|
*/
|
|
40
|
+
/**
|
|
41
|
+
* What the host is doing, handed to the function form of `config` so it can
|
|
42
|
+
* decide what to build.
|
|
43
|
+
*
|
|
44
|
+
* Only Vite reports all three. Where a host does not say, the value is
|
|
45
|
+
* derived rather than guessed at, and each field below says how.
|
|
46
|
+
*/
|
|
47
|
+
export interface StyleDictionaryConfigContext {
|
|
48
|
+
/**
|
|
49
|
+
* Whether the host is serving or building.
|
|
50
|
+
*
|
|
51
|
+
* `'serve'` comes from Vite's own `config.command` and is the dev server.
|
|
52
|
+
* Every other target builds, so it is `'build'` there — rollup, rolldown and
|
|
53
|
+
* webpack have no serving mode of their own to report.
|
|
54
|
+
*/
|
|
55
|
+
command: 'build' | 'serve';
|
|
56
|
+
/**
|
|
57
|
+
* The host's mode, as it names it.
|
|
58
|
+
*
|
|
59
|
+
* Vite reports its `config.mode` — `'development'` serving,
|
|
60
|
+
* `'production'` building, or whatever `--mode` named. webpack reports its
|
|
61
|
+
* `mode` option. rollup and rolldown have no such concept, so the value
|
|
62
|
+
* follows `command`: `'development'` when serving, `'production'` when
|
|
63
|
+
* building.
|
|
64
|
+
*/
|
|
65
|
+
mode: string;
|
|
66
|
+
/**
|
|
67
|
+
* Whether the host will keep rebuilding.
|
|
68
|
+
*
|
|
69
|
+
* `true` under Vite's dev server, `rollup --watch`, `rolldown.watch()` and
|
|
70
|
+
* `webpack --watch`; `false` for a one-shot build. It is read from the
|
|
71
|
+
* host — the plugin context's `meta.watchMode` on the three rollup-shaped
|
|
72
|
+
* targets, and `compiler.watchMode` on webpack — rather than inferred from
|
|
73
|
+
* `command`, because `rollup --watch` both watches and builds.
|
|
74
|
+
*/
|
|
75
|
+
watch: boolean;
|
|
76
|
+
}
|
|
20
77
|
export interface UnpluginStyleDictionaryOptions {
|
|
21
78
|
/**
|
|
22
79
|
* Whether a configuration whose output is already up to date may skip its
|
|
@@ -57,10 +114,42 @@ export interface UnpluginStyleDictionaryOptions {
|
|
|
57
114
|
* - A function that returns a config or array of configs (or resolves to them).
|
|
58
115
|
* Useful for calling `StyleDictionary.registerFormat()` (or other `register*`
|
|
59
116
|
* methods) before returning a config that references the custom format by name.
|
|
117
|
+
* It is handed a `StyleDictionaryConfigContext` describing what the host is
|
|
118
|
+
* doing, so an expensive platform can be built only when it is wanted —
|
|
119
|
+
* skipped under the dev server, built by `vite build`. A function taking no
|
|
120
|
+
* arguments stays valid: TypeScript accepts one of fewer parameters, and
|
|
121
|
+
* JavaScript ignores the extra argument.
|
|
60
122
|
*
|
|
61
|
-
* If not provided,
|
|
123
|
+
* If not provided, the root directory is searched for 'sd.config.json',
|
|
124
|
+
* 'config.json', 'sd.config.js' and 'sd.config.mjs', in that order. The
|
|
125
|
+
* first one that exists wins, and the rest are not looked at.
|
|
62
126
|
*/
|
|
63
|
-
config?: (() => Config | Config[] | Promise<Config | Config[]>) | Config | Config[] | string | string[];
|
|
127
|
+
config?: ((context: StyleDictionaryConfigContext) => Config | Config[] | Promise<Config | Config[]>) | Config | Config[] | string | string[];
|
|
128
|
+
/**
|
|
129
|
+
* Whether a failed rebuild is pushed to Vite's error overlay.
|
|
130
|
+
*
|
|
131
|
+
* A rebuild that fails under the dev server used to reach the browser
|
|
132
|
+
* nowhere: the page went on rendering the last good generated file, and the
|
|
133
|
+
* only trace was one red terminal line the developer may not have been
|
|
134
|
+
* looking at. With this on, the failure is sent to the page as an error
|
|
135
|
+
* frame naming this plugin, and the overlay is dismissed on the next
|
|
136
|
+
* rebuild that succeeds.
|
|
137
|
+
*
|
|
138
|
+
* This is Vite's overlay, so it does nothing on the other three targets,
|
|
139
|
+
* and nothing under `vite build` — there is no page to draw on.
|
|
140
|
+
*
|
|
141
|
+
* It is not `failOnError`'s job, and the two are independent. `failOnError`
|
|
142
|
+
* decides whether the host stops; this decides whether the browser is told.
|
|
143
|
+
* A dev server deliberately keeps serving through a failed rebuild, which is
|
|
144
|
+
* precisely the case where the overlay is the only thing that can say so.
|
|
145
|
+
*
|
|
146
|
+
* A failure Style Dictionary raises before this plugin can catch it — a
|
|
147
|
+
* token file that is not valid JSON, which rejects out of band — reaches
|
|
148
|
+
* neither the overlay nor this option.
|
|
149
|
+
*
|
|
150
|
+
* @default true
|
|
151
|
+
*/
|
|
152
|
+
errorOverlay?: boolean;
|
|
64
153
|
/**
|
|
65
154
|
* Whether a compile that fails should throw rather than only be reported.
|
|
66
155
|
*
|
|
@@ -99,10 +188,55 @@ export interface UnpluginStyleDictionaryOptions {
|
|
|
99
188
|
* A compile that fails is reported at every level, so there is no
|
|
100
189
|
* `'error'`: `'silent'` is the quietest and still reports a failure.
|
|
101
190
|
*
|
|
191
|
+
* This option governs what the plugin says, not where it goes. The messages
|
|
192
|
+
* are handed to the host — Vite's `config.logger`, the rollup and rolldown
|
|
193
|
+
* plugin context, webpack's `compilation` — so a host silenced by its own
|
|
194
|
+
* log level suppresses them after this option has let them through. A
|
|
195
|
+
* failure still stops the build whenever `failOnError` says it should,
|
|
196
|
+
* printed or not.
|
|
197
|
+
*
|
|
102
198
|
* @default undefined, which prints the plugin's own lines and leaves the
|
|
103
199
|
* configuration's `log.verbosity` alone
|
|
104
200
|
*/
|
|
105
201
|
logLevel?: 'info' | 'silent' | 'verbose' | 'warn';
|
|
202
|
+
/**
|
|
203
|
+
* Called once a build has finished, with every file it declares and how long
|
|
204
|
+
* it took in milliseconds.
|
|
205
|
+
*
|
|
206
|
+
* The paths are absolute and platform-native, sorted so two runs of the same
|
|
207
|
+
* configuration hand back the same order. They are what the build declares
|
|
208
|
+
* rather than what it wrote this time: a configuration skipped by `cache`
|
|
209
|
+
* contributes its destinations too, because they are on disk and current,
|
|
210
|
+
* and a post-processing step that ignored them would leave half the output
|
|
211
|
+
* untouched on a rebuild that changed one file.
|
|
212
|
+
*
|
|
213
|
+
* This is where formatting the generated files, type-checking them, or
|
|
214
|
+
* telling something else they have landed belongs.
|
|
215
|
+
*
|
|
216
|
+
* @default undefined
|
|
217
|
+
*/
|
|
218
|
+
onBuildEnd?: (files: string[], durationMs: number) => Promise<void> | void;
|
|
219
|
+
/**
|
|
220
|
+
* Called when a build fails, with whatever was thrown.
|
|
221
|
+
*
|
|
222
|
+
* It fires whatever `failOnError` is set to, and before that option decides
|
|
223
|
+
* whether to rethrow — the two answer different questions, and under a dev
|
|
224
|
+
* server the default is not to throw at all.
|
|
225
|
+
*
|
|
226
|
+
* The failure is reported to the console either way, so this is for reacting
|
|
227
|
+
* to one rather than for noticing it.
|
|
228
|
+
*
|
|
229
|
+
* @default undefined
|
|
230
|
+
*/
|
|
231
|
+
onBuildError?: (error: unknown) => Promise<void> | void;
|
|
232
|
+
/**
|
|
233
|
+
* Called before a build begins, once per build.
|
|
234
|
+
*
|
|
235
|
+
* A watch-triggered rebuild is a build, so this fires again for each one.
|
|
236
|
+
*
|
|
237
|
+
* @default undefined
|
|
238
|
+
*/
|
|
239
|
+
onBuildStart?: () => Promise<void> | void;
|
|
106
240
|
/**
|
|
107
241
|
* Whether the table of generated files and their sizes is produced.
|
|
108
242
|
*
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { UnpluginStyleDictionaryOptions } from "./types.js";
|
|
1
|
+
import { StyleDictionaryConfigContext, UnpluginStyleDictionaryOptions } from "./types.js";
|
|
2
2
|
//#region src/vite.d.ts
|
|
3
3
|
declare const _default: (options?: UnpluginStyleDictionaryOptions | undefined) => import("vite").Plugin<any>;
|
|
4
4
|
//#endregion
|
|
5
|
-
export { type UnpluginStyleDictionaryOptions, _default as default };
|
|
5
|
+
export { type StyleDictionaryConfigContext, type UnpluginStyleDictionaryOptions, _default as default };
|
|
6
6
|
//# sourceMappingURL=vite.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import picomatch from "picomatch";
|
|
2
|
+
//#region src/watch-filter.ts
|
|
3
|
+
function matchesWatchedFile(file, patterns) {
|
|
4
|
+
const normalizedFile = file.replace(/\\/g, "/");
|
|
5
|
+
return patterns.some((pattern) => {
|
|
6
|
+
const normalizedPattern = pattern.replace(/\\/g, "/");
|
|
7
|
+
return normalizedPattern === normalizedFile || picomatch.isMatch(normalizedFile, normalizedPattern);
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { matchesWatchedFile };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=watch-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-filter.js","names":[],"sources":["../src/watch-filter.ts"],"sourcesContent":["import picomatch from 'picomatch'\n\n// Whether `file` matches one of the resolved config/token watch patterns.\n// Shared by the Vite-specific `configureServer` watcher and the universal\n// `watchChange` hook — both need it, and both must skip files that don't\n// match: without this filter, `watchChange` reacts to *any* changed\n// module-graph file, including this plugin's own generated output (since\n// consuming code imports it). Every regenerate is itself a \"change\", which\n// without filtering re-triggers a rebuild forever.\n//\n// Matching a pattern is only half of that, and this function is only the half\n// it can answer. A `buildPath` inside a `source` directory is a supported\n// layout, and under any correct matcher its output matches the very glob that\n// produced it — so the caller also subtracts what the last build wrote. See\n// `generatedDestinations` and `isWatchedSource` in the factory below.\n//\n// The patterns are Style Dictionary's own `source` and `include` globs, so the\n// filter has to admit exactly what the build reads — which is why the matching\n// is a real globber's rather than hand-rolled. The version this replaces was\n// wrong in both directions at once: it stripped `/**` out of a pattern and\n// prefix-matched the remainder, so `tokens/**/*.json` matched nothing sitting\n// directly in `tokens/` and `tokens/**` matched a `tokens-backup/` sibling,\n// while its regex branch mapped every `*` to `.*` — crossing `/` — and tested\n// it unanchored, so generated output under a watched directory matched its own\n// source glob and rebuilt forever.\n//\n// picomatch rather than `path.matchesGlob`, which would need no dependency at\n// all: that function is documented experimental, and on Node 20 — the floor\n// `engines` declares — it prints `ExperimentalWarning: glob is an experimental\n// feature and might change at any time` into the consumer's build output. The\n// dependency is free in practice, since `unplugin` depends on the same\n// picomatch and is already installed wherever this plugin is. Its `dot: false`\n// default is deliberate: it is what glob, and so Style Dictionary, reads\n// sources with, so a dotfile is invisible to the filter and to the build alike.\nexport function matchesWatchedFile(file: string, patterns: string[]): boolean {\n const normalizedFile = file.replace(/\\\\/g, '/')\n\n return patterns.some((pattern) => {\n const normalizedPattern = pattern.replace(/\\\\/g, '/')\n\n // A config file reaches this function as its own literal path, which is\n // both the common case and the one shape that is not a glob at all.\n return (\n normalizedPattern === normalizedFile ||\n picomatch.isMatch(normalizedFile, normalizedPattern)\n )\n })\n}\n"],"mappings":";;AAkCA,SAAgB,mBAAmB,MAAc,UAA6B;CAC5E,MAAM,iBAAiB,KAAK,QAAQ,OAAO,GAAG;CAE9C,OAAO,SAAS,MAAM,YAAY;EAChC,MAAM,oBAAoB,QAAQ,QAAQ,OAAO,GAAG;EAIpD,OACE,sBAAsB,kBACtB,UAAU,QAAQ,gBAAgB,iBAAiB;CAEvD,CAAC;AACH"}
|
package/dist/webpack.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { UnpluginStyleDictionaryOptions } from "./types.js";
|
|
1
|
+
import { StyleDictionaryConfigContext, UnpluginStyleDictionaryOptions } from "./types.js";
|
|
2
2
|
//#region src/webpack.d.ts
|
|
3
3
|
declare const _default: (options?: UnpluginStyleDictionaryOptions | undefined) => import("webpack").WebpackPluginInstance;
|
|
4
4
|
//#endregion
|
|
5
|
-
export { type UnpluginStyleDictionaryOptions, _default as default };
|
|
5
|
+
export { type StyleDictionaryConfigContext, type UnpluginStyleDictionaryOptions, _default as default };
|
|
6
6
|
//# sourceMappingURL=webpack.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanso-labs/unplugin-style-dictionary",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Compile Style Dictionary design tokens ahead of your bundler (Vite, Rolldown, Rollup, or Webpack) from a single unplugin-based plugin, with automatic watching and rebuilding under Vite",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"unplugin",
|