@terrazzo/cli 2.0.0-beta.6 → 2.0.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/CHANGELOG.md +2 -2
- package/bin/cli.js +4 -4
- package/dist/index.d.ts +11 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +156 -146
- package/dist/index.js.map +1 -1
- package/dist/lab/assets/index-B8CS4Pk9.js +10 -0
- package/dist/lab/assets/index-B8CS4Pk9.js.map +1 -0
- package/dist/lab/index.html +1 -1
- package/package.json +9 -19
- package/dist/lab/assets/index-Bnka3dzO.js +0 -10
- package/dist/lab/assets/index-Bnka3dzO.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -77,9 +77,9 @@ The 2.0.0 release is full of new features:
|
|
|
77
77
|
|
|
78
78
|
- [#568](https://github.com/terrazzoapp/terrazzo/pull/568) [`67c75be`](https://github.com/terrazzoapp/terrazzo/commit/67c75be78978cece52b61cf258ccc3a875e6af48) Thanks [@drwpow](https://github.com/drwpow)! - Fix border tokens not cascading correctly across modes
|
|
79
79
|
|
|
80
|
-
- An error is now thrown if `--config [path]` points to a bad location.
|
|
80
|
+
- Bugfix: An error is now thrown if `--config [path]` points to a bad location.
|
|
81
81
|
|
|
82
|
-
- TypeScript
|
|
82
|
+
- Config: TypeScript files and plugins are now fully supported! `terrazzo.config.ts` is now the default.
|
|
83
83
|
|
|
84
84
|
## 0.10.3
|
|
85
85
|
|
package/bin/cli.js
CHANGED
|
@@ -32,12 +32,12 @@ import { Logger } from '@terrazzo/parser';
|
|
|
32
32
|
import {
|
|
33
33
|
buildCmd,
|
|
34
34
|
checkCmd,
|
|
35
|
+
formatCmd,
|
|
35
36
|
helpCmd,
|
|
36
37
|
importCmd,
|
|
37
38
|
initCmd,
|
|
38
39
|
labCmd,
|
|
39
40
|
loadConfig,
|
|
40
|
-
normalizeCmd,
|
|
41
41
|
versionCmd,
|
|
42
42
|
} from '../dist/index.js';
|
|
43
43
|
|
|
@@ -113,9 +113,9 @@ export default async function main() {
|
|
|
113
113
|
process.exit(0);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
//
|
|
117
|
-
if (cmd === 'normalize') {
|
|
118
|
-
await
|
|
116
|
+
// format
|
|
117
|
+
if (cmd === 'format' || cmd === 'normalize') {
|
|
118
|
+
await formatCmd(positionals[1], { logger, output: flags.output });
|
|
119
119
|
process.exit(0);
|
|
120
120
|
}
|
|
121
121
|
// import
|
package/dist/index.d.ts
CHANGED
|
@@ -93,6 +93,16 @@ declare function checkCmd({
|
|
|
93
93
|
positionals
|
|
94
94
|
}: CheckOptions): Promise<void>;
|
|
95
95
|
//#endregion
|
|
96
|
+
//#region src/format.d.ts
|
|
97
|
+
interface NormalizeOptions {
|
|
98
|
+
logger: Logger;
|
|
99
|
+
output: URL;
|
|
100
|
+
}
|
|
101
|
+
declare function formatCmd(filename: string, {
|
|
102
|
+
logger,
|
|
103
|
+
output
|
|
104
|
+
}: NormalizeOptions): Promise<void>;
|
|
105
|
+
//#endregion
|
|
96
106
|
//#region src/help.d.ts
|
|
97
107
|
/** Show help */
|
|
98
108
|
declare function helpCmd(): void;
|
|
@@ -165,21 +175,11 @@ declare function labCmd({
|
|
|
165
175
|
logger
|
|
166
176
|
}: LabBuildOptions): Promise<void>;
|
|
167
177
|
//#endregion
|
|
168
|
-
//#region src/normalize.d.ts
|
|
169
|
-
interface NormalizeOptions {
|
|
170
|
-
logger: Logger;
|
|
171
|
-
output: URL;
|
|
172
|
-
}
|
|
173
|
-
declare function normalizeCmd(filename: string, {
|
|
174
|
-
logger,
|
|
175
|
-
output
|
|
176
|
-
}: NormalizeOptions): Promise<void>;
|
|
177
|
-
//#endregion
|
|
178
178
|
//#region src/version.d.ts
|
|
179
179
|
declare function versionCmd(): void;
|
|
180
180
|
//#endregion
|
|
181
181
|
//#region src/index.d.ts
|
|
182
182
|
declare function defineConfig(config: Config): ConfigInit;
|
|
183
183
|
//#endregion
|
|
184
|
-
export { BuildOptions, CheckOptions, Command, DEFAULT_CONFIG_PATH, DEFAULT_TOKENS_PATH, FigmaOutput, Flags, GREEN_CHECK, ImportCmdOptions, InitOptions, LabBuildOptions, LoadConfigOptions, NormalizeOptions, buildCmd, checkCmd, cwd, defineConfig, helpCmd, importCmd, importFromFigma, importFromFigmaOptions, initCmd, isFigmaPath, labCmd, loadConfig, loadTokens,
|
|
184
|
+
export { BuildOptions, CheckOptions, Command, DEFAULT_CONFIG_PATH, DEFAULT_TOKENS_PATH, FigmaOutput, Flags, GREEN_CHECK, ImportCmdOptions, InitOptions, LabBuildOptions, LoadConfigOptions, NormalizeOptions, buildCmd, checkCmd, cwd, defineConfig, formatCmd, helpCmd, importCmd, importFromFigma, importFromFigmaOptions, initCmd, isFigmaPath, labCmd, loadConfig, loadTokens, printError, printSuccess, resolveConfig, resolveTokenPath, time, versionCmd, writeFiles };
|
|
185
185
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/shared.ts","../src/build.ts","../src/check.ts","../src/help.ts","../src/import/figma/index.ts","../src/import/index.ts","../src/init.ts","../src/lab.ts","../src/
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/shared.ts","../src/build.ts","../src/check.ts","../src/format.ts","../src/help.ts","../src/import/figma/index.ts","../src/import/index.ts","../src/init.ts","../src/lab.ts","../src/version.ts","../src/index.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
import fsSync from "node:fs";
|
|
2
3
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
3
4
|
import { build, defineConfig as defineConfig$1, parse } from "@terrazzo/parser";
|
|
4
|
-
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import pc from "picocolors";
|
|
7
7
|
import { createServer } from "vite";
|
|
@@ -9,8 +9,11 @@ import { ViteNodeRunner } from "vite-node/client";
|
|
|
9
9
|
import { ViteNodeServer } from "vite-node/server";
|
|
10
10
|
import chokidar from "chokidar";
|
|
11
11
|
import yamlToMomoa from "yaml-to-momoa";
|
|
12
|
-
import
|
|
12
|
+
import * as momoa from "@humanwhocodes/momoa";
|
|
13
|
+
import { getObjMember, getObjMembers, traverse } from "@terrazzo/json-schema-tools";
|
|
13
14
|
import { isAlias, pluralize } from "@terrazzo/token-tools";
|
|
15
|
+
import yaml from "yaml";
|
|
16
|
+
import fs from "node:fs/promises";
|
|
14
17
|
import { merge } from "merge-anything";
|
|
15
18
|
import { camelCase } from "scule";
|
|
16
19
|
import { spawn } from "node:child_process";
|
|
@@ -21,8 +24,6 @@ import { parseModule } from "meriyah";
|
|
|
21
24
|
import { Readable, Writable } from "node:stream";
|
|
22
25
|
import { serve } from "@hono/node-server";
|
|
23
26
|
import mime from "mime";
|
|
24
|
-
import * as momoa from "@humanwhocodes/momoa";
|
|
25
|
-
import { getObjMember, getObjMembers, traverse } from "@terrazzo/json-schema-tools";
|
|
26
27
|
|
|
27
28
|
//#region src/shared.ts
|
|
28
29
|
const cwd = new URL(`${pathToFileURL(process.cwd())}/`);
|
|
@@ -115,9 +116,9 @@ async function loadTokens(tokenPaths, { logger }) {
|
|
|
115
116
|
message: `loadTokens: Expected array, received ${typeof tokenPaths}`
|
|
116
117
|
});
|
|
117
118
|
if (tokenPaths.length === 1 && tokenPaths[0].href === DEFAULT_TOKENS_PATH.href) {
|
|
118
|
-
if (!
|
|
119
|
+
if (!fsSync.existsSync(tokenPaths[0])) {
|
|
119
120
|
const yamlPath = new URL("./tokens.yaml", cwd);
|
|
120
|
-
if (
|
|
121
|
+
if (fsSync.existsSync(yamlPath)) tokenPaths[0] = yamlPath;
|
|
121
122
|
else {
|
|
122
123
|
logger.error({
|
|
123
124
|
group: "config",
|
|
@@ -185,9 +186,9 @@ async function loadTokens(tokenPaths, { logger }) {
|
|
|
185
186
|
});
|
|
186
187
|
return;
|
|
187
188
|
}
|
|
188
|
-
else if (
|
|
189
|
+
else if (fsSync.existsSync(filename)) allTokens.push({
|
|
189
190
|
filename,
|
|
190
|
-
src:
|
|
191
|
+
src: fsSync.readFileSync(filename, "utf8")
|
|
191
192
|
});
|
|
192
193
|
else {
|
|
193
194
|
logger.error({
|
|
@@ -213,7 +214,7 @@ function printSuccess(message, startTime) {
|
|
|
213
214
|
}
|
|
214
215
|
/** Resolve config */
|
|
215
216
|
function resolveConfig(filename) {
|
|
216
|
-
if (filename &&
|
|
217
|
+
if (filename && fsSync.existsSync(new URL(filename, cwd))) return filename;
|
|
217
218
|
for (const ext of [
|
|
218
219
|
".ts",
|
|
219
220
|
".js",
|
|
@@ -223,17 +224,17 @@ function resolveConfig(filename) {
|
|
|
223
224
|
".cjs"
|
|
224
225
|
]) {
|
|
225
226
|
const maybeFilename = `terrazzo.config${ext}`;
|
|
226
|
-
if (
|
|
227
|
+
if (fsSync.existsSync(new URL(maybeFilename, cwd))) return fileURLToPath(new URL(maybeFilename, cwd));
|
|
227
228
|
}
|
|
228
229
|
}
|
|
229
230
|
/** Resolve tokens.json path (for lint command) */
|
|
230
231
|
function resolveTokenPath(filename, { logger }) {
|
|
231
232
|
const tokensPath = new URL(filename, cwd);
|
|
232
|
-
if (!
|
|
233
|
+
if (!fsSync.existsSync(tokensPath)) logger.error({
|
|
233
234
|
group: "config",
|
|
234
235
|
message: `Could not locate ${filename}. Does the file exist?`
|
|
235
236
|
});
|
|
236
|
-
else if (!
|
|
237
|
+
else if (!fsSync.statSync(tokensPath).isFile()) logger.error({
|
|
237
238
|
group: "config",
|
|
238
239
|
message: `Expected JSON or YAML file, received ${filename}.`
|
|
239
240
|
});
|
|
@@ -336,8 +337,8 @@ async function buildCmd({ config, configPath, flags, logger }) {
|
|
|
336
337
|
function writeFiles(result, { config, logger }) {
|
|
337
338
|
for (const { filename, contents } of result.outputFiles) {
|
|
338
339
|
const output = new URL(filename, config.outDir);
|
|
339
|
-
|
|
340
|
-
|
|
340
|
+
fsSync.mkdirSync(new URL(".", output), { recursive: true });
|
|
341
|
+
fsSync.writeFileSync(output, contents);
|
|
341
342
|
logger.debug({
|
|
342
343
|
group: "parser",
|
|
343
344
|
label: "buildEnd",
|
|
@@ -373,6 +374,125 @@ async function checkCmd({ config, logger, positionals }) {
|
|
|
373
374
|
}
|
|
374
375
|
}
|
|
375
376
|
|
|
377
|
+
//#endregion
|
|
378
|
+
//#region src/format.ts
|
|
379
|
+
function findMember(name) {
|
|
380
|
+
return function(member) {
|
|
381
|
+
return member.name.type === "String" && member.name.value === name;
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
async function formatCmd(filename, { logger, output }) {
|
|
385
|
+
try {
|
|
386
|
+
if (!filename) {
|
|
387
|
+
logger.error({
|
|
388
|
+
group: "config",
|
|
389
|
+
message: "Expected input: `tz format <tokens.json> -o output.json`"
|
|
390
|
+
});
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const sourceLoc = new URL(filename, cwd);
|
|
394
|
+
if (!fsSync.existsSync(sourceLoc)) logger.error({
|
|
395
|
+
group: "config",
|
|
396
|
+
message: `Couldn’t find ${path.relative(cwd.href, sourceLoc.href)}. Does it exist?`
|
|
397
|
+
});
|
|
398
|
+
const sourceData = fsSync.readFileSync(sourceLoc, "utf8");
|
|
399
|
+
const isYaml = filename.endsWith(".yml") || filename.endsWith(".yaml") || !sourceData.startsWith("{");
|
|
400
|
+
const document = isYaml ? yamlToMomoa(sourceData) : momoa.parse(sourceData, { mode: "jsonc" });
|
|
401
|
+
const { tokens } = await parse([{
|
|
402
|
+
src: sourceData,
|
|
403
|
+
filename: sourceLoc
|
|
404
|
+
}], {
|
|
405
|
+
config: defineConfig$1({ lint: { rules: {
|
|
406
|
+
"core/consistent-naming": "off",
|
|
407
|
+
"core/valid-color": "off",
|
|
408
|
+
"core/valid-dimension": "off",
|
|
409
|
+
"core/valid-duration": "off",
|
|
410
|
+
"core/valid-typography": "off"
|
|
411
|
+
} } }, { cwd }),
|
|
412
|
+
logger,
|
|
413
|
+
resolveAliases: false,
|
|
414
|
+
yamlToMomoa
|
|
415
|
+
});
|
|
416
|
+
traverse(document, { enter(node, _parent, nodePath) {
|
|
417
|
+
const token = tokens[nodePath.join(".")];
|
|
418
|
+
if (!token || token.aliasOf || node.type !== "Member" || node.value.type !== "Object") return;
|
|
419
|
+
const $valueI = node.value.members.findIndex(findMember("$value"));
|
|
420
|
+
switch (token.$type) {
|
|
421
|
+
case "color":
|
|
422
|
+
if (node.value.members[$valueI].value.type === "String") {
|
|
423
|
+
if (isAlias(node.value.members[$valueI].value.value)) return;
|
|
424
|
+
const hex = node.value.members[$valueI].value.value;
|
|
425
|
+
node.value.members[$valueI].value = momoa.parse(JSON.stringify({
|
|
426
|
+
...token.$value,
|
|
427
|
+
hex: hex.startsWith("#") ? hex.slice(0, 7) : void 0
|
|
428
|
+
})).body;
|
|
429
|
+
const $extensions = getObjMember(node.value, "$extensions");
|
|
430
|
+
if ($extensions?.type === "Object") {
|
|
431
|
+
const mode = getObjMember($extensions, "mode");
|
|
432
|
+
if (mode?.type === "Object") for (let i = 0; i < mode.members.length; i++) {
|
|
433
|
+
const modeName = mode.members[i].name.value;
|
|
434
|
+
const hex = mode.members[i].value.value;
|
|
435
|
+
mode.members[i].value = momoa.parse(JSON.stringify({
|
|
436
|
+
...token.mode[modeName].$value,
|
|
437
|
+
hex: hex.startsWith("#") ? hex.slice(0, 7) : void 0
|
|
438
|
+
})).body;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
break;
|
|
443
|
+
case "dimension":
|
|
444
|
+
case "duration":
|
|
445
|
+
if (node.value.members[$valueI].value.type === "String") {
|
|
446
|
+
if (isAlias(node.value.members[$valueI].value.value)) return;
|
|
447
|
+
node.value.members[$valueI].value = formatDurationDimension(node.value.members[$valueI].value);
|
|
448
|
+
const $extensions = getObjMember(node.value, "$extensions");
|
|
449
|
+
if ($extensions?.type === "Object") {
|
|
450
|
+
const mode = getObjMember($extensions, "mode");
|
|
451
|
+
if (mode?.type === "Object") for (let i = 0; i < mode.members.length; i++) mode.members[i].value = formatDurationDimension(node.value.members[$valueI].value);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
break;
|
|
455
|
+
case "typography": {
|
|
456
|
+
if (node.value.members[$valueI]?.value.type !== "Object") return;
|
|
457
|
+
node.value.members[$valueI].value = formatTypography(node.value.members[$valueI].value);
|
|
458
|
+
const $extensions = getObjMember(node.value, "$extensions");
|
|
459
|
+
if ($extensions?.type === "Object") {
|
|
460
|
+
const mode = getObjMember($extensions, "mode");
|
|
461
|
+
if (mode?.type === "Object") for (let i = 0; i < mode.members.length; i++) mode.members[i].value = formatTypography(mode.members[i].value);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
} });
|
|
466
|
+
const outputLoc = new URL(output, cwd);
|
|
467
|
+
const contents = isYaml ? yaml.stringify(JSON.parse(momoa.print(document))) : momoa.print(document, { indent: 2 });
|
|
468
|
+
fsSync.mkdirSync(new URL(".", outputLoc), { recursive: true });
|
|
469
|
+
fsSync.writeFileSync(outputLoc, contents);
|
|
470
|
+
} catch (err) {
|
|
471
|
+
printError(err.message);
|
|
472
|
+
process.exit(1);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
function formatDurationDimension(node) {
|
|
476
|
+
const value = Number.parseFloat(node.value);
|
|
477
|
+
if (!Number.isFinite(value)) return node;
|
|
478
|
+
node.type = "Object";
|
|
479
|
+
node.members = momoa.parse(JSON.stringify({
|
|
480
|
+
value,
|
|
481
|
+
unit: node.value.replace(String(value), "")
|
|
482
|
+
})).body.members;
|
|
483
|
+
delete node.value;
|
|
484
|
+
return node;
|
|
485
|
+
}
|
|
486
|
+
function formatTypography(node) {
|
|
487
|
+
const { fontFamily, fontSize, fontWeight, letterSpacing, lineHeight } = getObjMembers(node);
|
|
488
|
+
if (!fontFamily) node.members.push(momoa.parse("{\"fontFamily\":[\"inherit\"]}").body.members[0]);
|
|
489
|
+
if (!fontSize) node.members.push(momoa.parse("{\"fontSize\":{\"value\":1,\"unit\":\"rem\"}}").body.members[0]);
|
|
490
|
+
if (!fontWeight) node.members.push(momoa.parse("{\"fontWeight\":400}").body.members[0]);
|
|
491
|
+
if (!letterSpacing) node.members.push(momoa.parse("{\"letterSpacing\":{\"value\":0,\"unit\":\"rem\"}}").body.members[0]);
|
|
492
|
+
if (!lineHeight) node.members.push(momoa.parse("{\"lineHeight\":1}").body.members[0]);
|
|
493
|
+
return node;
|
|
494
|
+
}
|
|
495
|
+
|
|
376
496
|
//#endregion
|
|
377
497
|
//#region src/help.ts
|
|
378
498
|
/** Show help */
|
|
@@ -384,6 +504,9 @@ function helpCmd() {
|
|
|
384
504
|
--no-lint Disable linters running on build
|
|
385
505
|
check [path] Check tokens.json for errors and run linters
|
|
386
506
|
lint [path] (alias of check)
|
|
507
|
+
format [path] Format your tokens
|
|
508
|
+
--o [file] Output file
|
|
509
|
+
normalize (alias of format)
|
|
387
510
|
init Create a starter tokens.json file
|
|
388
511
|
lab Manage your tokens with a web interface
|
|
389
512
|
import [path] Import from a Figma Design file
|
|
@@ -936,7 +1059,7 @@ async function importCmd({ flags, positionals, logger }) {
|
|
|
936
1059
|
});
|
|
937
1060
|
const end = performance.now() - start;
|
|
938
1061
|
if (flags.output) {
|
|
939
|
-
const oldFile =
|
|
1062
|
+
const oldFile = fsSync.existsSync(flags.output) ? JSON.parse(await fs.readFile(flags.output, "utf8")) : {};
|
|
940
1063
|
const code = {
|
|
941
1064
|
$schema: result.code.$schema,
|
|
942
1065
|
version: result.code.version,
|
|
@@ -946,7 +1069,7 @@ async function importCmd({ flags, positionals, logger }) {
|
|
|
946
1069
|
$defs: oldFile.$defs,
|
|
947
1070
|
$extensions: oldFile.$extensions
|
|
948
1071
|
};
|
|
949
|
-
await fs
|
|
1072
|
+
await fs.writeFile(flags.output, `${JSON.stringify(code, void 0, 2)}\n`);
|
|
950
1073
|
logger.info({
|
|
951
1074
|
group: "import",
|
|
952
1075
|
message: `Imported ${formatNumber(result.variableCount)} ${pluralize(result.variableCount, "Variable", "Variables")}, ${formatNumber(result.styleCount)} ${pluralize(result.styleCount, "Style", "Styles")} → ${flags.output}`,
|
|
@@ -1018,9 +1141,9 @@ async function initCmd({ logger }) {
|
|
|
1018
1141
|
logger
|
|
1019
1142
|
});
|
|
1020
1143
|
const tokensPath = config.tokens[0];
|
|
1021
|
-
const hasExistingConfig =
|
|
1022
|
-
let startFromDS = !(tokensPath &&
|
|
1023
|
-
if (tokensPath &&
|
|
1144
|
+
const hasExistingConfig = fsSync.existsSync(configPath);
|
|
1145
|
+
let startFromDS = !(tokensPath && fsSync.existsSync(tokensPath));
|
|
1146
|
+
if (tokensPath && fsSync.existsSync(tokensPath)) {
|
|
1024
1147
|
if (await confirm({ message: `Found tokens at ${path.relative(fileURLToPath(cwd), fileURLToPath(tokensPath))}. Overwrite with a new design system?` })) startFromDS = true;
|
|
1025
1148
|
}
|
|
1026
1149
|
if (startFromDS) {
|
|
@@ -1049,7 +1172,7 @@ async function initCmd({ logger }) {
|
|
|
1049
1172
|
}
|
|
1050
1173
|
if (!hasExistingConfig) {
|
|
1051
1174
|
await newConfigFile(configPath, [EXAMPLE_TOKENS_PATH]);
|
|
1052
|
-
await fs
|
|
1175
|
+
await fs.writeFile(EXAMPLE_TOKENS_PATH, JSON.stringify(EXAMPLE_TOKENS, void 0, 2));
|
|
1053
1176
|
}
|
|
1054
1177
|
const existingPlugins = config.plugins.map((p) => p.name);
|
|
1055
1178
|
const pluginSelection = await multiselect({
|
|
@@ -1103,7 +1226,7 @@ async function initCmd({ logger }) {
|
|
|
1103
1226
|
}
|
|
1104
1227
|
}
|
|
1105
1228
|
async function newConfigFile(configPath, tokens, imports = []) {
|
|
1106
|
-
await fs
|
|
1229
|
+
await fs.writeFile(configPath, `import { defineConfig } from '@terrazzo/cli';
|
|
1107
1230
|
${imports.map((p) => `import ${p.specifier} from '${p.path}';`).join("\n")}
|
|
1108
1231
|
|
|
1109
1232
|
export default defineConfig({
|
|
@@ -1150,7 +1273,7 @@ function getConfigObjFromAst(ast, configPath) {
|
|
|
1150
1273
|
return astConfig;
|
|
1151
1274
|
}
|
|
1152
1275
|
async function updateConfigTokens(configPath, tokens) {
|
|
1153
|
-
const ast = parseModule(await fs
|
|
1276
|
+
const ast = parseModule(await fs.readFile(configPath, "utf8"));
|
|
1154
1277
|
const astConfig = getConfigObjFromAst(ast, configPath);
|
|
1155
1278
|
let tokensKey = astConfig.properties.find((p) => p.type === "Property" && p.key.type === "Identifier" && p.key.name === "tokens");
|
|
1156
1279
|
if (!tokensKey) {
|
|
@@ -1174,7 +1297,7 @@ async function updateConfigTokens(configPath, tokens) {
|
|
|
1174
1297
|
};
|
|
1175
1298
|
astConfig.properties.unshift(tokensKey);
|
|
1176
1299
|
}
|
|
1177
|
-
await fs
|
|
1300
|
+
await fs.writeFile(configPath, generate(ast, SYNTAX_SETTINGS));
|
|
1178
1301
|
}
|
|
1179
1302
|
/**
|
|
1180
1303
|
* Add plugin imports
|
|
@@ -1185,7 +1308,7 @@ async function updateConfigTokens(configPath, tokens) {
|
|
|
1185
1308
|
* introduce bugs).
|
|
1186
1309
|
*/
|
|
1187
1310
|
async function updateConfigPlugins(configPath, plugins) {
|
|
1188
|
-
const ast = parseModule(await fs
|
|
1311
|
+
const ast = parseModule(await fs.readFile(configPath, "utf8"));
|
|
1189
1312
|
ast.body.push(...plugins.map((p) => ({
|
|
1190
1313
|
type: "ImportDeclaration",
|
|
1191
1314
|
source: {
|
|
@@ -1228,7 +1351,7 @@ async function updateConfigPlugins(configPath, plugins) {
|
|
|
1228
1351
|
method: false,
|
|
1229
1352
|
shorthand: false
|
|
1230
1353
|
});
|
|
1231
|
-
await fs
|
|
1354
|
+
await fs.writeFile(configPath, generate(ast, SYNTAX_SETTINGS));
|
|
1232
1355
|
}
|
|
1233
1356
|
const EXAMPLE_TOKENS = {
|
|
1234
1357
|
color: {
|
|
@@ -1418,7 +1541,7 @@ async function labCmd({ config, logger }) {
|
|
|
1418
1541
|
/** TODO: handle multiple files */
|
|
1419
1542
|
const [tokenFileUrl] = config.tokens;
|
|
1420
1543
|
const staticFiles = /* @__PURE__ */ new Set();
|
|
1421
|
-
const dirEntries = await fs
|
|
1544
|
+
const dirEntries = await fs.readdir(fileURLToPath(import.meta.resolve("./lab")), {
|
|
1422
1545
|
withFileTypes: true,
|
|
1423
1546
|
recursive: true
|
|
1424
1547
|
});
|
|
@@ -1432,18 +1555,18 @@ async function labCmd({ config, logger }) {
|
|
|
1432
1555
|
overrideGlobalObjects: false,
|
|
1433
1556
|
async fetch(request) {
|
|
1434
1557
|
const pathname = new URL(request.url).pathname;
|
|
1435
|
-
if (pathname === "/") return new Response(Readable.toWeb(
|
|
1558
|
+
if (pathname === "/") return new Response(Readable.toWeb(fsSync.createReadStream(fileURLToPath(import.meta.resolve("./lab/index.html")))), { headers: { "Content-Type": "text/html" } });
|
|
1436
1559
|
if (pathname === "/api/tokens") {
|
|
1437
|
-
if (request.method === "GET") return new Response(Readable.toWeb(
|
|
1560
|
+
if (request.method === "GET") return new Response(Readable.toWeb(fsSync.createReadStream(tokenFileUrl)), { headers: {
|
|
1438
1561
|
"Content-Type": "application/json",
|
|
1439
1562
|
"Cache-Control": "no-cache"
|
|
1440
1563
|
} });
|
|
1441
1564
|
else if (request.method === "POST" && request.body) {
|
|
1442
|
-
await request.body.pipeTo(Writable.toWeb(
|
|
1565
|
+
await request.body.pipeTo(Writable.toWeb(fsSync.createWriteStream(tokenFileUrl)));
|
|
1443
1566
|
return new Response(JSON.stringify({ success: true }), { headers: { "Content-Type": "application/json" } });
|
|
1444
1567
|
}
|
|
1445
1568
|
}
|
|
1446
|
-
if (staticFiles.has(pathname)) return new Response(Readable.toWeb(
|
|
1569
|
+
if (staticFiles.has(pathname)) return new Response(Readable.toWeb(fsSync.createReadStream(fileURLToPath(import.meta.resolve(`./lab${pathname}`)))), { headers: { "Content-Type": mime.getType(pathname) ?? "application/octet-stream" } });
|
|
1447
1570
|
return new Response("Not found", { status: 404 });
|
|
1448
1571
|
}
|
|
1449
1572
|
}, (info) => {
|
|
@@ -1461,124 +1584,10 @@ async function labCmd({ config, logger }) {
|
|
|
1461
1584
|
});
|
|
1462
1585
|
}
|
|
1463
1586
|
|
|
1464
|
-
//#endregion
|
|
1465
|
-
//#region src/normalize.ts
|
|
1466
|
-
function findMember(name) {
|
|
1467
|
-
return function(member) {
|
|
1468
|
-
return member.name.type === "String" && member.name.value === name;
|
|
1469
|
-
};
|
|
1470
|
-
}
|
|
1471
|
-
async function normalizeCmd(filename, { logger, output }) {
|
|
1472
|
-
try {
|
|
1473
|
-
if (!filename) {
|
|
1474
|
-
logger.error({
|
|
1475
|
-
group: "config",
|
|
1476
|
-
message: "Expected input: `tz normalize <tokens.json> -o output.json`"
|
|
1477
|
-
});
|
|
1478
|
-
return;
|
|
1479
|
-
}
|
|
1480
|
-
const sourceLoc = new URL(filename, cwd);
|
|
1481
|
-
if (!fs.existsSync(sourceLoc)) logger.error({
|
|
1482
|
-
group: "config",
|
|
1483
|
-
message: `Couldn’t find ${path.relative(cwd.href, sourceLoc.href)}. Does it exist?`
|
|
1484
|
-
});
|
|
1485
|
-
const sourceData = fs.readFileSync(sourceLoc, "utf8");
|
|
1486
|
-
const document = momoa.parse(sourceData, { mode: "jsonc" });
|
|
1487
|
-
const { tokens } = await parse([{
|
|
1488
|
-
src: sourceData,
|
|
1489
|
-
filename: sourceLoc
|
|
1490
|
-
}], {
|
|
1491
|
-
config: defineConfig$1({ lint: { rules: {
|
|
1492
|
-
"core/valid-color": "off",
|
|
1493
|
-
"core/valid-dimension": "off",
|
|
1494
|
-
"core/valid-duration": "off",
|
|
1495
|
-
"core/valid-typography": "off"
|
|
1496
|
-
} } }, { cwd }),
|
|
1497
|
-
logger
|
|
1498
|
-
});
|
|
1499
|
-
traverse(document, { enter(node, _parent, nodePath) {
|
|
1500
|
-
const token = tokens[nodePath.join(".")];
|
|
1501
|
-
if (!token || token.aliasOf || node.type !== "Member" || node.value.type !== "Object") return;
|
|
1502
|
-
const $valueI = node.value.members.findIndex(findMember("$value"));
|
|
1503
|
-
switch (token.$type) {
|
|
1504
|
-
case "color":
|
|
1505
|
-
if (node.value.members[$valueI].value.type === "String") {
|
|
1506
|
-
if (isAlias(node.value.members[$valueI].value.value)) return;
|
|
1507
|
-
const hex = node.value.members[$valueI].value.value;
|
|
1508
|
-
node.value.members[$valueI].value = momoa.parse(JSON.stringify({
|
|
1509
|
-
...token.$value,
|
|
1510
|
-
hex: hex.startsWith("#") ? hex.slice(0, 7) : void 0
|
|
1511
|
-
})).body;
|
|
1512
|
-
const $extensions = getObjMember(node.value, "$extensions");
|
|
1513
|
-
if ($extensions?.type === "Object") {
|
|
1514
|
-
const mode = getObjMember($extensions, "mode");
|
|
1515
|
-
if (mode?.type === "Object") for (let i = 0; i < mode.members.length; i++) {
|
|
1516
|
-
const modeName = mode.members[i].name.value;
|
|
1517
|
-
const hex = mode.members[i].value.value;
|
|
1518
|
-
mode.members[i].value = momoa.parse(JSON.stringify({
|
|
1519
|
-
...token.mode[modeName].$value,
|
|
1520
|
-
hex: hex.startsWith("#") ? hex.slice(0, 7) : void 0
|
|
1521
|
-
})).body;
|
|
1522
|
-
}
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
|
-
break;
|
|
1526
|
-
case "dimension":
|
|
1527
|
-
case "duration":
|
|
1528
|
-
if (node.value.members[$valueI].value.type === "String") {
|
|
1529
|
-
if (isAlias(node.value.members[$valueI].value.value)) return;
|
|
1530
|
-
node.value.members[$valueI].value = normalizeDurationDimension(node.value.members[$valueI].value);
|
|
1531
|
-
const $extensions = getObjMember(node.value, "$extensions");
|
|
1532
|
-
if ($extensions?.type === "Object") {
|
|
1533
|
-
const mode = getObjMember($extensions, "mode");
|
|
1534
|
-
if (mode?.type === "Object") for (let i = 0; i < mode.members.length; i++) mode.members[i].value = normalizeDurationDimension(node.value.members[$valueI].value);
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
break;
|
|
1538
|
-
case "typography": {
|
|
1539
|
-
if (node.value.members[$valueI]?.value.type !== "Object") return;
|
|
1540
|
-
node.value.members[$valueI].value = normalizeTypography(node.value.members[$valueI].value);
|
|
1541
|
-
const $extensions = getObjMember(node.value, "$extensions");
|
|
1542
|
-
if ($extensions?.type === "Object") {
|
|
1543
|
-
const mode = getObjMember($extensions, "mode");
|
|
1544
|
-
if (mode?.type === "Object") for (let i = 0; i < mode.members.length; i++) mode.members[i].value = normalizeTypography(mode.members[i].value);
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
} });
|
|
1549
|
-
const outputLoc = new URL(output, cwd);
|
|
1550
|
-
fs.mkdirSync(new URL(".", outputLoc), { recursive: true });
|
|
1551
|
-
fs.writeFileSync(outputLoc, momoa.print(document, { indent: 2 }));
|
|
1552
|
-
} catch (err) {
|
|
1553
|
-
printError(err.message);
|
|
1554
|
-
process.exit(1);
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
function normalizeDurationDimension(node) {
|
|
1558
|
-
const value = Number.parseFloat(node.value);
|
|
1559
|
-
if (!Number.isFinite(value)) return node;
|
|
1560
|
-
node.type = "Object";
|
|
1561
|
-
node.members = momoa.parse(JSON.stringify({
|
|
1562
|
-
value,
|
|
1563
|
-
unit: node.value.replace(String(value), "")
|
|
1564
|
-
})).body.members;
|
|
1565
|
-
delete node.value;
|
|
1566
|
-
return node;
|
|
1567
|
-
}
|
|
1568
|
-
function normalizeTypography(node) {
|
|
1569
|
-
const { fontFamily, fontSize, fontWeight, letterSpacing, lineHeight } = getObjMembers(node);
|
|
1570
|
-
if (!fontFamily) node.members.push(momoa.parse("{\"fontFamily\":[\"inherit\"]}").body.members[0]);
|
|
1571
|
-
if (!fontSize) node.members.push(momoa.parse("{\"fontSize\":{\"value\":1,\"unit\":\"rem\"}}").body.members[0]);
|
|
1572
|
-
if (!fontWeight) node.members.push(momoa.parse("{\"fontWeight\":400}").body.members[0]);
|
|
1573
|
-
if (!letterSpacing) node.members.push(momoa.parse("{\"letterSpacing\":{\"value\":0,\"unit\":\"rem\"}}").body.members[0]);
|
|
1574
|
-
if (!lineHeight) node.members.push(momoa.parse("{\"lineHeight\":1}").body.members[0]);
|
|
1575
|
-
return node;
|
|
1576
|
-
}
|
|
1577
|
-
|
|
1578
1587
|
//#endregion
|
|
1579
1588
|
//#region src/version.ts
|
|
1580
1589
|
function versionCmd() {
|
|
1581
|
-
const { version } = JSON.parse(
|
|
1590
|
+
const { version } = JSON.parse(fsSync.readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
1582
1591
|
console.log(version);
|
|
1583
1592
|
}
|
|
1584
1593
|
|
|
@@ -1589,6 +1598,7 @@ function defineConfig(config) {
|
|
|
1589
1598
|
const normalizedConfig = { ...config };
|
|
1590
1599
|
if (typeof normalizedConfig.tokens === "string" || Array.isArray(normalizedConfig.tokens)) normalizedConfig.tokens = (Array.isArray(normalizedConfig.tokens) ? normalizedConfig.tokens : [normalizedConfig.tokens]).map((tokenPath) => {
|
|
1591
1600
|
if (tokenPath.startsWith(".") || /^(https?|file):\/\//i.test(tokenPath)) return tokenPath;
|
|
1601
|
+
else if (fsSync.existsSync(new URL(tokenPath, cwd))) return new URL(tokenPath, cwd);
|
|
1592
1602
|
try {
|
|
1593
1603
|
return pathToFileURL(require.resolve(tokenPath));
|
|
1594
1604
|
} catch (err) {
|
|
@@ -1600,5 +1610,5 @@ function defineConfig(config) {
|
|
|
1600
1610
|
}
|
|
1601
1611
|
|
|
1602
1612
|
//#endregion
|
|
1603
|
-
export { DEFAULT_CONFIG_PATH, DEFAULT_TOKENS_PATH, GREEN_CHECK, buildCmd, checkCmd, cwd, defineConfig, helpCmd, importCmd, importFromFigma, initCmd, isFigmaPath, labCmd, loadConfig, loadTokens,
|
|
1613
|
+
export { DEFAULT_CONFIG_PATH, DEFAULT_TOKENS_PATH, GREEN_CHECK, buildCmd, checkCmd, cwd, defineConfig, formatCmd, helpCmd, importCmd, importFromFigma, initCmd, isFigmaPath, labCmd, loadConfig, loadTokens, printError, printSuccess, resolveConfig, resolveTokenPath, time, versionCmd, writeFiles };
|
|
1604
1614
|
//# sourceMappingURL=index.js.map
|