@reforma/project-tokens 0.0.1 → 0.0.2
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 +49 -13
- package/dist/cli.js +3 -3
- package/dist/compilation/compiler.d.ts +2 -0
- package/dist/compilation/compiler.d.ts.map +1 -1
- package/dist/generation.d.ts.map +1 -1
- package/dist/generation.js +6 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,12 +1,52 @@
|
|
|
1
1
|
# @reforma/project-tokens
|
|
2
2
|
|
|
3
3
|
Compile project DTCG JSON into CSS, Tailwind theme bindings, and mode metadata.
|
|
4
|
-
The compiler runs locally on Node 24 or newer.
|
|
4
|
+
The compiler runs locally on Node 24 or newer.
|
|
5
|
+
|
|
6
|
+
## Files
|
|
7
|
+
|
|
8
|
+
The compiler reads a DTCG resolver and the documents that resolver references.
|
|
9
|
+
It writes `tokens.css`, `tailwind.css`, and `modes.json` into the directory
|
|
10
|
+
from `--out`. Without that flag, the directory is `.generated` beside the resolver.
|
|
11
|
+
The JSON stays the source. Ignore the output directory.
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
tokens/tokens.resolver.json sets, modes, default
|
|
15
|
+
tokens/base.json every value for the default context
|
|
16
|
+
tokens/dark.json sparse overrides for one other context
|
|
17
|
+
tokens/.generated/tokens.css custom properties
|
|
18
|
+
tokens/.generated/tailwind.css Tailwind @theme bindings
|
|
19
|
+
tokens/.generated/modes.json context names, selectors, revision
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The directory and the JSON filenames are yours. `$ref` inside the resolver
|
|
23
|
+
decides which documents are read. `base.json` and `dark.json` above are only
|
|
24
|
+
an example: one complete document, then a document that overrides existing
|
|
25
|
+
paths for another context. A mode file does not declare types and does not
|
|
26
|
+
add tokens that exist only in that mode.
|
|
27
|
+
|
|
28
|
+
Pass `--entry` to point at the resolver and `--out` to choose the output
|
|
29
|
+
directory. If you omit `--entry`, the CLI uses
|
|
30
|
+
`.reforma/tokens/tokens.resolver.json`. If you omit `--out`, it writes
|
|
31
|
+
`.generated` beside the resolver.
|
|
32
|
+
|
|
33
|
+
`tokens.css` puts the default context on `:root` and each other context on a
|
|
34
|
+
selector such as `html[data-theme="dark"]`. `tailwind.css` is an
|
|
35
|
+
`@theme inline` block. It includes only names Tailwind already treats as theme
|
|
36
|
+
keys, including `color`, `spacing`, `font`, `text`, `radius`, and `shadow`.
|
|
37
|
+
Any other group stays a plain variable in `tokens.css`. `modes.json` records
|
|
38
|
+
the default, each modifier's contexts, the selector for every permutation,
|
|
39
|
+
the input revision, and hashes of the source files.
|
|
40
|
+
|
|
41
|
+
This generated `tailwind.css` is not the project's Tailwind entry. The app
|
|
42
|
+
imports its own Tailwind CSS, then these generated files. `check` writes
|
|
43
|
+
nothing. `build`, `watch`, and `dev` replace the three files when the output
|
|
44
|
+
changes, and leave the last good output in place when the JSON is invalid.
|
|
5
45
|
|
|
6
46
|
## CLI
|
|
7
47
|
|
|
8
|
-
Install the package, then call the `reforma-tokens` binary from a script.
|
|
9
|
-
entry is `.reforma/tokens/tokens.resolver.json`.
|
|
48
|
+
Install the package, then call the `reforma-tokens` binary from a script.
|
|
49
|
+
`--entry` selects the resolver. The default is `.reforma/tokens/tokens.resolver.json`.
|
|
10
50
|
|
|
11
51
|
```json
|
|
12
52
|
{
|
|
@@ -29,20 +69,16 @@ command.
|
|
|
29
69
|
| `dev -- command ...` | Build before starting the command. Watch sources. Forward signals and the exit status. |
|
|
30
70
|
|
|
31
71
|
`--cwd directory` selects the workspace. `--entry path` selects its resolver.
|
|
72
|
+
`--out directory` selects the output directory.
|
|
32
73
|
Repeat `--context axis=value` to supply contexts, including axes without defaults.
|
|
33
74
|
Every permutation is validated. The selected or default input supplies `:root`.
|
|
34
75
|
Names are case-sensitive. Compilation stops at 1000 permutations.
|
|
35
76
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
`
|
|
40
|
-
|
|
41
|
-
A failed rebuild leaves the last successful output unchanged. Watch and dev print
|
|
42
|
-
one JSON diagnostic per line on stderr and `{ "status": "stale", "revision" }`
|
|
43
|
-
when input is invalid. A successful rebuild prints `{ "status": "ready", "revision" }`
|
|
44
|
-
on stdout. The app keeps running after a bad edit. An invalid first build does
|
|
45
|
-
not start the dev command.
|
|
77
|
+
A build may also leave staging and lock files in the output directory while it runs.
|
|
78
|
+
Watch and dev print one JSON diagnostic per line on stderr and
|
|
79
|
+
`{ "status": "stale", "revision" }` when input is invalid. A successful rebuild
|
|
80
|
+
prints `{ "status": "ready", "revision" }` on stdout. The app keeps running after
|
|
81
|
+
a bad edit. An invalid first build does not start the dev command.
|
|
46
82
|
|
|
47
83
|
## API
|
|
48
84
|
|
package/dist/cli.js
CHANGED
|
@@ -111,11 +111,11 @@ async function main() {
|
|
|
111
111
|
const separator = args.indexOf('--');
|
|
112
112
|
const childCommand = separator < 0 ? [] : args.slice(separator + 1);
|
|
113
113
|
const { values, positionals } = parseArgs({ args: separator < 0 ? args : args.slice(0, separator), allowPositionals: true, options: {
|
|
114
|
-
cwd: { type: 'string' }, entry: { type: 'string' }, context: { type: 'string', multiple: true }, help: { type: 'boolean' },
|
|
114
|
+
cwd: { type: 'string' }, entry: { type: 'string' }, out: { type: 'string' }, context: { type: 'string', multiple: true }, help: { type: 'boolean' },
|
|
115
115
|
} });
|
|
116
116
|
const [command] = positionals;
|
|
117
117
|
if (values.help) {
|
|
118
|
-
process.stdout.write('reforma-tokens <build|check|watch|dev -- command...> [--cwd directory] [--entry resolver.json] [--context axis=value]\n');
|
|
118
|
+
process.stdout.write('reforma-tokens <build|check|watch|dev -- command...> [--cwd directory] [--entry resolver.json] [--out directory] [--context axis=value]\n');
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
121
|
if (!['build', 'check', 'watch', 'dev'].includes(command ?? '') || positionals.length !== 1)
|
|
@@ -129,7 +129,7 @@ async function main() {
|
|
|
129
129
|
throw new Error('Expected --context axis=value.');
|
|
130
130
|
input[context.slice(0, separator)] = context.slice(separator + 1);
|
|
131
131
|
}
|
|
132
|
-
const options = { workspaceRoot: await realpath(resolve(values.cwd ?? process.cwd())), entry: values.entry, input };
|
|
132
|
+
const options = { workspaceRoot: await realpath(resolve(values.cwd ?? process.cwd())), entry: values.entry, out: values.out, input };
|
|
133
133
|
if (command === 'watch' || command === 'dev')
|
|
134
134
|
return watch(options, childCommand);
|
|
135
135
|
const result = await (command === 'check' ? compileProjectTokens(options) : buildProjectTokens(options));
|
|
@@ -38,6 +38,8 @@ export interface TokenPermutation {
|
|
|
38
38
|
export interface TokenCompilationOptions {
|
|
39
39
|
workspaceRoot: string;
|
|
40
40
|
entry?: string;
|
|
41
|
+
/** Directory for generated CSS and mode metadata. Defaults to `.generated` beside the resolver. */
|
|
42
|
+
out?: string;
|
|
41
43
|
/** Required values for modifiers without a default. */
|
|
42
44
|
input?: Record<string, string>;
|
|
43
45
|
/** In-memory candidate files, keyed by workspace-relative path. Never persisted by compilation. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/compilation/compiler.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEtG,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,eAAe;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,mGAAmG;IACnG,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,MAAM,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1E;AAUD,mFAAmF;AACnF,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiStG"}
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/compilation/compiler.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEtG,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,eAAe;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mGAAmG;IACnG,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,mGAAmG;IACnG,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,MAAM,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1E;AAUD,mFAAmF;AACnF,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiStG"}
|
package/dist/generation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../src/generation.ts"],"names":[],"mappings":"AAKA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAYtH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,0BAYnE;
|
|
1
|
+
{"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../src/generation.ts"],"names":[],"mappings":"AAKA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAYtH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,0BAYnE;AAOD,wBAAsB,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,gBAAgB,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoIxL;AAED,0FAA0F;AAC1F,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAEpG"}
|
package/dist/generation.js
CHANGED
|
@@ -28,9 +28,14 @@ export async function readTokenDependency(root, path) {
|
|
|
28
28
|
throw error;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
+
function generatedDirectory(root, options) {
|
|
32
|
+
if (options.out)
|
|
33
|
+
return resolve(root, options.out);
|
|
34
|
+
return resolve(root, dirname(options.entry ?? '.reforma/tokens/tokens.resolver.json'), '.generated');
|
|
35
|
+
}
|
|
31
36
|
export async function withTokenCompilationLock(options, work) {
|
|
32
37
|
const root = await realpath(options.workspaceRoot);
|
|
33
|
-
const directory =
|
|
38
|
+
const directory = generatedDirectory(root, options);
|
|
34
39
|
// Check every existing ancestor before creating output or following a symlink.
|
|
35
40
|
for (let path = directory; path !== root; path = dirname(path)) {
|
|
36
41
|
const rel = relative(root, path);
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reforma/project-tokens",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Portable DTCG 2025.10 compiler for project design tokens.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"author": "Reforma, Inc. <dev@reforma.ai>",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/reforma-
|
|
10
|
+
"url": "https://github.com/reforma-ai/reforma",
|
|
11
11
|
"directory": "packages/project-tokens"
|
|
12
12
|
},
|
|
13
13
|
"exports": {
|