@design-token-kit/cli 0.2.1 → 0.3.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.
Files changed (2) hide show
  1. package/bin/index.mjs +74 -59
  2. package/package.json +5 -4
package/bin/index.mjs CHANGED
@@ -11,9 +11,26 @@ import { Command } from "commander";
11
11
  import {
12
12
  DtcgTokenValidator
13
13
  } from "@design-token-kit/core";
14
+ var EXIT_VALIDATION_ERROR = 2;
15
+ var EXIT_FAILURE = 1;
16
+ var validateCommand = new Command("validate").description("Validate DTCG JSON or HRDT YAML token files.").argument("[files...]", "Paths to DTCG JSON or HRDT YAML token files (reads from stdin when omitted)").addHelpText("after", "\nExit status:\n 0 success\n 1 unexpected error\n 2 validation errors found").action(async (sources) => {
17
+ try {
18
+ const validator = new DtcgTokenValidator();
19
+ const issues = await validator.validate(sources.length > 0 ? sources : ["-"]);
20
+ printIssues(issues);
21
+ if (hasErrors(issues)) {
22
+ process.exit(EXIT_VALIDATION_ERROR);
23
+ }
24
+ console.log("Validation passed.");
25
+ } catch (error) {
26
+ console.error("Validation error:", error.message);
27
+ process.exit(EXIT_FAILURE);
28
+ }
29
+ });
14
30
  function formatIssue(issue) {
31
+ const source = issue.sourcePath === "-" ? "stdin" : issue.sourcePath;
15
32
  const location = issue.line === void 0 ? "" : issue.column === void 0 ? `:${issue.line}` : `:${issue.line}:${issue.column}`;
16
- return `[${issue.name}] ${issue.severity}: ${issue.sourcePath}${location} - ${issue.message}`;
33
+ return `[${issue.name}] ${issue.severity}: ${source}${location} - ${issue.message}`;
17
34
  }
18
35
  function printIssues(issues) {
19
36
  for (const issue of issues) {
@@ -24,24 +41,10 @@ function printIssues(issues) {
24
41
  function hasErrors(issues) {
25
42
  return issues.some((i) => i.severity === "error");
26
43
  }
27
- var validateCommand = new Command("validate").description("Validate DTCG JSON or HRDT YAML token files.").argument("<files...>", "Paths to DTCG JSON or HRDT YAML token files").action(async (sources) => {
28
- try {
29
- const validator = new DtcgTokenValidator();
30
- const issues = await validator.validate(sources);
31
- printIssues(issues);
32
- if (hasErrors(issues)) {
33
- process.exit(2);
34
- }
35
- console.log("Validation passed.");
36
- } catch (error) {
37
- console.error("Validation error:", error.message);
38
- process.exit(1);
39
- }
40
- });
41
44
 
42
45
  // src/commands/convert.ts
43
46
  import { Command as Command2 } from "commander";
44
- import { Source } from "@design-token-kit/core";
47
+ import { DtcgListLoader, DtcgTokenCssConverter as DtcgTokenCssConverter2 } from "@design-token-kit/core";
45
48
  import { writeFile } from "fs/promises";
46
49
 
47
50
  // src/commands/formats.ts
@@ -52,20 +55,9 @@ import {
52
55
  HrdtTokenReader,
53
56
  HrdtTokenWriter
54
57
  } from "@design-token-kit/core";
55
- function getReader(format) {
56
- return readers[toDocumentFormat(format)];
57
- }
58
58
  function getWriter(format) {
59
59
  return writers[toOutputFormat(format)];
60
60
  }
61
- var readers = {
62
- ["dtcg" /* DTCG */]: {
63
- read: (content) => new DtcgJsonReader().parse(content)
64
- },
65
- ["hrdt" /* HRDT */]: {
66
- read: (content) => new HrdtTokenReader().parse(content)
67
- }
68
- };
69
61
  var writers = {
70
62
  ["dtcg" /* DTCG */]: {
71
63
  write: (doc) => new DtcgJsonWriter().write(doc)
@@ -89,23 +81,39 @@ function toOutputFormat(format, fallback = "css" /* CSS */) {
89
81
  }
90
82
 
91
83
  // src/commands/convert.ts
92
- var convertCommand = new Command2("convert").description("Convert a token file to DTCG JSON, HRDT YAML, or CSS.").argument("<file>", "Path to a token file").option("-i, --inform [format]", "Input format: dtcg, hrdt (default: auto-detect)").option("-f, --outform [format]", "Output format: dtcg, hrdt, css (default: css)").option("-o, --out [file]", "Output file (default: stdout)").action(async (file, options) => {
84
+ var EXIT_FAILURE2 = 1;
85
+ var convertCommand = new Command2("convert").description("Convert a token file to DTCG JSON, HRDT YAML, or CSS.").argument("[files...]", "Paths to token files (reads from stdin when omitted or '-')").option("-i, --inform [format]", "Input format: dtcg, hrdt (force all files to this format)").option("-f, --outform [format]", "Output format: dtcg, hrdt, css (default: css)").option("-o, --out [file]", "Output file (default: stdout)").addHelpText("after", "\nExit status:\n 0 success\n 1 conversion failed").action(async (files, options) => {
93
86
  try {
94
- const reader = getReader(options.inform);
95
- const content = await new Source(file).getContent();
96
- const doc = reader.read(content);
97
- const writer = getWriter(options.outform);
98
- const output = writer.write(doc);
99
- if (options.out) {
100
- await writeFile(options.out, output);
101
- } else {
102
- process.stdout.write(output);
103
- }
87
+ const outform = options.outform ?? "css" /* CSS */;
88
+ const forcedFormat = options.inform !== void 0 ? toDocumentFormat(options.inform) : void 0;
89
+ const list = await loadSources(files, forcedFormat);
90
+ const output = convertList(list, outform);
91
+ await writeOutput(output, options.out);
104
92
  } catch (error) {
105
93
  console.error("Conversion failed:", error.message);
106
- process.exit(1);
94
+ process.exit(EXIT_FAILURE2);
107
95
  }
108
96
  });
97
+ async function loadSources(files, forcedFormat) {
98
+ const sources = files.length > 0 ? files : ["-"];
99
+ return new DtcgListLoader().load(sources, forcedFormat);
100
+ }
101
+ function convertList(list, outform) {
102
+ if (outform === "css" /* CSS */) {
103
+ return new DtcgTokenCssConverter2().convertList(list);
104
+ }
105
+ if (list.themes.size > 0) {
106
+ throw new Error(`Multiple files are only supported with --outform css, got ${outform}`);
107
+ }
108
+ return getWriter(outform).write(list.base);
109
+ }
110
+ async function writeOutput(output, out) {
111
+ if (out) {
112
+ await writeFile(out, output);
113
+ } else {
114
+ process.stdout.write(output);
115
+ }
116
+ }
109
117
 
110
118
  // src/commands/showcase.ts
111
119
  import { Command as Command3 } from "commander";
@@ -113,7 +121,29 @@ import { writeFile as writeFile2 } from "fs/promises";
113
121
  import { spawn } from "child_process";
114
122
  import path from "path";
115
123
  import { tmpdir } from "os";
116
- import { Source as Source2, createTokenHtmlShowcase } from "@design-token-kit/core";
124
+ import { Source, createTokenHtmlShowcase } from "@design-token-kit/core";
125
+ var EXIT_FAILURE3 = 1;
126
+ var showcaseCommand = new Command3("showcase").description("Create HTML showcase from DTCG JSON, HRDT YAML, or CSS.").argument("[files...]", "Paths to token JSON, HRDT, or CSS files (reads from stdin when omitted)").option("-o, --out <file>", "Output HTML file name or path").option("--open", "Open the generated HTML in browser (only with --out)").addHelpText("after", "\nExit status:\n 0 success\n 1 showcase failed").action(async (files, options) => {
127
+ try {
128
+ const showcase = createTokenHtmlShowcase();
129
+ const sources = (files.length > 0 ? files : ["-"]).map((f) => new Source(f));
130
+ const filePaths = await Promise.all(sources.map((s) => s.getFile()));
131
+ const html = await showcase.showcase(filePaths);
132
+ if (options.out) {
133
+ const targetFile = resolveOutputPath(options.out);
134
+ await writeFile2(targetFile, html);
135
+ console.log(`Saved HTML to: ${targetFile}`);
136
+ if (options.open) {
137
+ openFile(targetFile);
138
+ }
139
+ } else {
140
+ process.stdout.write(html);
141
+ }
142
+ } catch (error) {
143
+ console.error("Showcase failed:", error.message);
144
+ process.exit(EXIT_FAILURE3);
145
+ }
146
+ });
117
147
  function resolveOutputPath(output) {
118
148
  if (path.isAbsolute(output)) {
119
149
  return output;
@@ -135,25 +165,6 @@ function openFile(filePath) {
135
165
  }
136
166
  spawn("xdg-open", [filePath], { stdio: "ignore", detached: true });
137
167
  }
138
- var showcaseCommand = new Command3("showcase").description("Create HTML showcase from DTCG JSON, HRDT YAML, or CSS.").argument("<files...>", "Paths to token JSON, HRDT, or CSS files").option("-o, --out <file>", "Output HTML file name or path").action(async (files, options) => {
139
- try {
140
- const showcase = createTokenHtmlShowcase();
141
- const sources = files.map((f) => new Source2(f));
142
- const filePaths = await Promise.all(sources.map((s) => s.getFile()));
143
- const html = await showcase.showcase(filePaths);
144
- if (options.out) {
145
- const targetFile = resolveOutputPath(options.out);
146
- await writeFile2(targetFile, html);
147
- console.log(`Saved HTML to: ${targetFile}`);
148
- openFile(targetFile);
149
- } else {
150
- process.stdout.write(html);
151
- }
152
- } catch (error) {
153
- console.error("Showcase failed:", error.message);
154
- process.exit(1);
155
- }
156
- });
157
168
 
158
169
  // src/index.ts
159
170
  var packageJsonPath = path2.resolve(path2.dirname(fileURLToPath(import.meta.url)), "../package.json");
@@ -164,9 +175,13 @@ var program = new Command4().name("dtokens").description("CLI for DTCG JSON and
164
175
  Examples:
165
176
  $ dtokens validate tokens.json
166
177
  $ dtokens validate tokens.yaml
178
+ $ dtokens validate tokens.yaml tokens.dark.yaml
179
+ $ dtokens validate - tokens.dark.yaml < tokens.yaml
167
180
  $ dtokens convert tokens.yaml --inform hrdt --outform css --out ./dist/tokens.css
168
181
  $ dtokens convert tokens.json --outform hrdt
182
+ $ dtokens convert --outform css < tokens.yaml
169
183
  $ dtokens showcase tokens.yaml --out ./dist/showcase.html
184
+ $ dtokens showcase - < tokens.yaml
170
185
  ` : "");
171
186
  program.parseAsync(process.argv).catch((error) => {
172
187
  console.error(error instanceof Error ? error.message : error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design-token-kit/cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "CLI for Design Token Kit: validate, convert, showcase.",
5
5
  "keywords": [
6
6
  "design-tokens",
@@ -39,15 +39,16 @@
39
39
  "scripts": {
40
40
  "build": "tsc --noEmit && tsup",
41
41
  "dist": "node ../scripts/stage-package.mjs cli",
42
- "test": "exit 0"
42
+ "test": "vitest run"
43
43
  },
44
44
  "dependencies": {
45
- "@design-token-kit/core": "0.2.1",
45
+ "@design-token-kit/core": "0.3.0",
46
46
  "commander": "14.0.1"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/node": "24.10.1",
50
50
  "tsup": "8.5.1",
51
- "typescript": "5.9.3"
51
+ "typescript": "5.9.3",
52
+ "vitest": "^4.1.7"
52
53
  }
53
54
  }