@terrazzo/cli 0.0.11 → 0.0.12

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 (3) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/bin/cli.js +44 -35
  3. package/package.json +4 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # @terrazzo/cli
2
+
3
+ ## 0.0.12
4
+
5
+ ### Patch Changes
6
+
7
+ - [#285](https://github.com/terrazzoapp/terrazzo/pull/285) [`e8a0df1`](https://github.com/terrazzoapp/terrazzo/commit/e8a0df1f3b50cf7cb292bcc475aae271feae4569) Thanks [@drwpow](https://github.com/drwpow)! - Add support for multiple token files
8
+
9
+ - Updated dependencies [[`e8a0df1`](https://github.com/terrazzoapp/terrazzo/commit/e8a0df1f3b50cf7cb292bcc475aae271feae4569)]:
10
+ - @terrazzo/token-tools@0.0.6
11
+ - @terrazzo/parser@0.0.12
package/bin/cli.js CHANGED
@@ -109,11 +109,11 @@ export default async function main() {
109
109
  process.exit(1);
110
110
  }
111
111
 
112
- let rawSchema = await loadTokens(config.tokens);
112
+ let rawSchemas = await loadTokens(config.tokens);
113
113
 
114
114
  const watch = args.includes('-w') || args.includes('--watch');
115
115
 
116
- let { tokens, ast } = await parse(rawSchema, { config });
116
+ let { tokens, ast } = await parse(rawSchemas, { config });
117
117
  let result = await build(tokens, { ast, config });
118
118
  writeFiles(result, config);
119
119
 
@@ -125,28 +125,28 @@ export default async function main() {
125
125
  hour: '2-digit',
126
126
  minute: '2-digit',
127
127
  });
128
- const tokenWatcher = chokidar.watch(config.tokens.map((filepath) => fileURLToPath(filepath)));
129
- tokenWatcher.on('change', async (filePath) => {
128
+ const tokenWatcher = chokidar.watch(config.tokens.map((filename) => fileURLToPath(filename)));
129
+ tokenWatcher.on('change', async (filename) => {
130
130
  try {
131
- rawSchema = await loadTokens(config.tokens);
132
- const parseResult = await parse(tokens, { config });
131
+ rawSchemas = await loadTokens(config.tokens);
132
+ const parseResult = await parse(rawSchemas, { config });
133
133
  tokens = parseResult.tokens;
134
134
  ast = parseResult.ast;
135
135
  result = await build(tokens, { ast, config });
136
136
  console.log(
137
- `${pc.dim(dt.format(new Date()))} ${pc.green('Tz')}} ${pc.yellow(filePath)} updated ${GREEN_CHECK}`,
137
+ `${pc.dim(dt.format(new Date()))} ${pc.green('Tz')}} ${pc.yellow(filename)} updated ${GREEN_CHECK}`,
138
138
  );
139
139
  } catch (err) {
140
140
  printErrors([err.message || err]);
141
141
  }
142
142
  });
143
143
  const configWatcher = chokidar.watch(resolveConfig(configPath));
144
- configWatcher.on('change', async (filePath) => {
144
+ configWatcher.on('change', async (filename) => {
145
145
  try {
146
146
  console.log(
147
147
  `${pc.dim(dt.format(new Date()))} ${pc.green('Tz')} ${pc.yellow('Config updated. Reloading…')}`,
148
148
  );
149
- config = (await import(filePath)).default;
149
+ config = (await import(filename)).default;
150
150
  rawSchema = await loadTokens(config.tokens);
151
151
  const parseResult = await parse(tokens, { config });
152
152
  tokens = parseResult.tokens;
@@ -168,10 +168,10 @@ export default async function main() {
168
168
  break;
169
169
  }
170
170
  case 'check': {
171
- const rawSchema = await loadTokens(flags._[0] ? [resolveTokenPath(flags._[0])] : config.tokens);
172
- const filepath = flags._[0] || config.tokens[0];
173
- console.log(pc.underline(filepath.protocol === 'file:' ? fileURLToPath(filepath) : filepath));
174
- await parse(rawSchema, { config, continueOnError: true }); // will throw if errors
171
+ const rawSchemas = await loadTokens(flags._[0] ? [resolveTokenPath(flags._[0])] : config.tokens);
172
+ const filename = flags._[0] || config.tokens[0];
173
+ console.log(pc.underline(filename.protocol === 'file:' ? fileURLToPath(filename) : filename));
174
+ await parse(rawSchemas, { config, continueOnError: true }); // will throw if errors
175
175
  printSuccess(`No errors ${time(start)}`);
176
176
  break;
177
177
  }
@@ -238,21 +238,30 @@ function showHelp() {
238
238
 
239
239
  /** load tokens */
240
240
  async function loadTokens(tokenPaths) {
241
- // TODO: merge tokens
242
-
243
241
  const allTokens = [];
244
242
 
243
+ if (!Array.isArray(tokenPaths)) {
244
+ printErrors(`loadTokens: Expected array, received ${typeof tokenPaths}`);
245
+ process.exit(1);
246
+ }
247
+
245
248
  // download/read
246
249
  for (let i = 0; i < tokenPaths.length; i++) {
247
- const filepath = tokenPaths[i];
248
- if (filepath.protocol === 'http:' || filepath.protocol === 'https:') {
250
+ const filename = tokenPaths[i];
251
+
252
+ if (!(filename instanceof URL)) {
253
+ printErrors(`loadTokens[${i}]: Expected URL, received ${filename}`);
254
+ process.exit(1);
255
+ }
256
+
257
+ if (filename.protocol === 'http:' || filename.protocol === 'https:') {
249
258
  try {
250
259
  // if Figma URL
251
- if (filepath.host === 'figma.com' || filepath.host === 'www.figma.com') {
252
- const [_, fileKeyword, fileKey] = filepath.pathname.split('/');
260
+ if (filename.host === 'figma.com' || filename.host === 'www.figma.com') {
261
+ const [_, fileKeyword, fileKey] = filename.pathname.split('/');
253
262
  if (fileKeyword !== 'file' || !fileKey) {
254
263
  printErrors(
255
- `Unexpected Figma URL. Expected "https://www.figma.com/file/:file_key/:file_name?…", received "${filepath.href}"`,
264
+ `Unexpected Figma URL. Expected "https://www.figma.com/file/:file_key/:file_name?…", received "${filename.href}"`,
256
265
  );
257
266
  process.exit(1);
258
267
  }
@@ -270,7 +279,7 @@ async function loadTokens(tokenPaths) {
270
279
  headers,
271
280
  });
272
281
  if (res.ok) {
273
- allTokens.push(await res.text());
282
+ allTokens.push({ filename, src: await res.text() });
274
283
  }
275
284
  const message = res.status !== 404 ? JSON.stringify(await res.json(), undefined, 2) : '';
276
285
  printErrors(`Figma responded with ${res.status}${message ? `:\n${message}` : ''}`);
@@ -279,27 +288,27 @@ async function loadTokens(tokenPaths) {
279
288
  }
280
289
 
281
290
  // otherwise, expect YAML/JSON
282
- const res = await fetch(filepath, {
291
+ const res = await fetch(filename, {
283
292
  method: 'GET',
284
293
  headers: { Accept: '*/*', 'User-Agent': 'Mozilla/5.0 Gecko/20100101 Firefox/123.0' },
285
294
  });
286
- allTokens.push(await res.text());
295
+ allTokens.push({ filename, src: await res.text() });
287
296
  } catch (err) {
288
- printErrors(`${filepath.href}: ${err}`);
297
+ printErrors(`${filename.href}: ${err}`);
289
298
  }
290
299
  } else {
291
- if (fs.existsSync(filepath)) {
292
- allTokens.push(fs.readFileSync(filepath, 'utf8'));
300
+ if (fs.existsSync(filename)) {
301
+ allTokens.push({ filename, src: fs.readFileSync(filename, 'utf8') });
293
302
  } else {
294
303
  printErrors(
295
- `Could not locate ${path.relative(fileURLToPath(cwd), fileURLToPath(filepath))}. To create one, run \`npx tz init\`.`,
304
+ `Could not locate ${path.relative(fileURLToPath(cwd), fileURLToPath(filename))}. To create one, run \`npx tz init\`.`,
296
305
  );
297
306
  process.exit(1);
298
307
  }
299
308
  }
300
309
  }
301
310
 
302
- return allTokens[0];
311
+ return allTokens;
303
312
  }
304
313
 
305
314
  /**
@@ -326,14 +335,14 @@ function resolveConfig(filename) {
326
335
  }
327
336
 
328
337
  /** Resolve tokens.json path (for lint command) */
329
- function resolveTokenPath(filepath) {
330
- const tokensPath = new URL(filepath, cwd);
338
+ function resolveTokenPath(filename) {
339
+ const tokensPath = new URL(filename, cwd);
331
340
  if (!fs.existsSync(tokensPath)) {
332
- printErrors(`Could not locate ${filepath}. Does the file exist?`);
341
+ printErrors(`Could not locate ${filename}. Does the file exist?`);
333
342
  process.exit(1);
334
343
  }
335
344
  if (!fs.statSync(tokensPath).isFile()) {
336
- printErrors(`Expected JSON or YAML file, received ${filepath}.`);
345
+ printErrors(`Expected JSON or YAML file, received ${filename}.`);
337
346
  process.exit(1);
338
347
  }
339
348
  return tokensPath;
@@ -373,8 +382,8 @@ export function printWarnings(warnings) {
373
382
  /** Write files */
374
383
  export function writeFiles(result, config) {
375
384
  for (const { filename, contents } of result.outputFiles) {
376
- const filepath = new URL(filename, config.outDir);
377
- fs.mkdirSync(new URL('.', filepath), { recursive: true });
378
- fs.writeFileSync(filepath, contents);
385
+ const output = new URL(filename, config.outDir);
386
+ fs.mkdirSync(new URL('.', output), { recursive: true });
387
+ fs.writeFileSync(output, contents);
379
388
  }
380
389
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terrazzo/cli",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "CLI for managing design tokens using the Design Tokens Community Group (DTCG) standard and generating code for any platform via plugins.",
5
5
  "type": "module",
6
6
  "author": {
@@ -37,15 +37,15 @@
37
37
  "merge-anything": "^5.1.7",
38
38
  "picocolors": "^1.0.1",
39
39
  "yargs-parser": "^21.1.1",
40
- "@terrazzo/parser": "^0.0.11",
41
- "@terrazzo/token-tools": "^0.0.4"
40
+ "@terrazzo/parser": "^0.0.12",
41
+ "@terrazzo/token-tools": "^0.0.6"
42
42
  },
43
43
  "devDependencies": {
44
44
  "typescript": "^5.5.3"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "pnpm run build:clean && pnpm run build:ts",
48
- "build:clean": "del dist",
48
+ "build:clean": "del-cli dist",
49
49
  "build:ts": "tsc -p tsconfig.build.json",
50
50
  "dev": "tsc -p tsconfig.build.json -w",
51
51
  "lint": "biome check .",