@terrazzo/cli 2.0.3 → 2.1.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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # @terrazzo/cli
2
2
 
3
+ ## 2.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#740](https://github.com/terrazzoapp/terrazzo/pull/740) [`2845b02`](https://github.com/terrazzoapp/terrazzo/commit/2845b02718db1ddbf5e17efdc53ff16109b63d28) Thanks [@badams](https://github.com/badams)! - Add OAuth bearer token support for Figma import. Set `FIGMA_OAUTH_TOKEN` to use an OAuth access token instead of a Personal Access Token (`FIGMA_ACCESS_TOKEN`). OAuth takes precedence if both are set.
8
+
9
+ ### Patch Changes
10
+
11
+ - [#742](https://github.com/terrazzoapp/terrazzo/pull/742) [`de25711`](https://github.com/terrazzoapp/terrazzo/commit/de25711f65c10c58776f7b71c5621f6228387f79) Thanks [@mrginglymus](https://github.com/mrginglymus)! - Respect --no-lint options in build command
12
+
13
+ - [#715](https://github.com/terrazzoapp/terrazzo/pull/715) [`6261145`](https://github.com/terrazzoapp/terrazzo/commit/62611450071c4c1e09a1ffd78998cbfdc36605ba) Thanks [@heddendorp](https://github.com/heddendorp)! - Fix Figma alias resolution for hidden local variables
14
+
15
+ - Updated dependencies [[`fefd4b1`](https://github.com/terrazzoapp/terrazzo/commit/fefd4b149d03ca2199eaddc7b197e4e081169e7f)]:
16
+ - @terrazzo/token-tools@2.1.0
17
+
3
18
  ## 2.0.3
4
19
 
5
20
  ### Patch Changes
package/bin/cli.js CHANGED
@@ -65,6 +65,7 @@ const { values: flags, positionals } = parseArgs({
65
65
  watch: { type: 'boolean', short: 'w' },
66
66
  version: { type: 'boolean' },
67
67
  unpublished: { type: 'boolean' },
68
+ 'no-lint': { type: 'boolean' },
68
69
  'skip-styles': { type: 'boolean' },
69
70
  'skip-variables': { type: 'boolean' },
70
71
  'font-family-names': { type: 'string' },
package/dist/index.d.ts CHANGED
@@ -13,6 +13,8 @@ interface Flags {
13
13
  out?: string;
14
14
  /** --help */
15
15
  help?: boolean;
16
+ /** --no-lint */
17
+ 'no-lint'?: boolean;
16
18
  /** --watch, -w */
17
19
  watch?: boolean;
18
20
  /** --version */
@@ -1 +1 @@
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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"}
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":";;;cAUa,GAAA,EAAG,GAAA;AAAA,cACH,mBAAA,EAAmB,GAAA;AAAA,cACnB,mBAAA,EAAmB,GAAA;AAAA,KAEpB,OAAA;AAAA,cAEC,WAAA;AAAA,UAEI,KAAA;EAR6C;EAU5D,MAAA;EATqE;EAWrE,GAAA;EAX8B;EAa9B,IAAA;EAZW;EAcX,SAAA;;EAEA,KAAA;EAhB8D;EAkB9D,OAAA;AAAA;AAAA,UAGe,iBAAA;EACf,GAAA,EAAK,OAAA;EACL,KAAA,EAAO,KAAA;EACP,MAAA,EAAQ,MAAA;AAAA;;iBAIY,UAAA,CAAA;EAAa,GAAA;EAAK,KAAA;EAAO;AAAA,GAAU,iBAAA,GAAiB,OAAA;;;;;iBA0FpD,UAAA,CAAW,UAAA,EAAY,GAAA;EAAS;AAAA;EAAY,MAAA,EAAQ,MAAA;AAAA,IAAQ,OAAA;;;;;iBA6FlE,UAAA,CAAW,OAAA;;iBAMX,YAAA,CAAa,OAAA,UAAiB,SAAA;;iBAM9B,aAAA,CAAc,QAAA;;iBAgBd,gBAAA,CAAiB,QAAA;EAAoB;AAAA;EAAY,MAAA,EAAQ,MAAA;AAAA,IAAQ,GAAA;;iBAWjE,IAAA,CAAK,KAAA;;;UCpPJ,YAAA;EACf,KAAA,EAAO,KAAA;EACP,MAAA,EAAQ,UAAA;EACR,UAAA;EACA,MAAA,EAAQ,MAAA;AAAA;ADXV;AAAA,iBCesB,QAAA,CAAA;EAAW,MAAA;EAAQ,UAAA;EAAY,KAAA;EAAO;AAAA,GAAU,YAAA,GAAY,OAAA;;iBAsFlE,UAAA,CAAW,MAAA,EAAQ,iBAAA;EAAqB,MAAA;EAAQ;AAAA;EAAY,MAAA,EAAQ,UAAA;EAAY,MAAA,EAAQ,MAAA;AAAA;;;UC5GvF,YAAA;;EAEf,WAAA;EACA,MAAA,EAAQ,UAAA;EACR,MAAA,EAAQ,MAAA;AAAA;;iBAIY,QAAA,CAAA;EAAW,MAAA;EAAQ,MAAA;EAAQ;AAAA,GAAe,YAAA,GAAY,OAAA;;;UCF3D,gBAAA;EACf,MAAA,EAAQ,MAAA;EACR,MAAA,EAAQ,GAAA;AAAA;AAAA,iBASY,SAAA,CAAU,QAAA;EAAoB,MAAA;EAAQ;AAAA,GAAU,gBAAA,GAAgB,OAAA;;;;iBCpBtE,OAAA,CAAA;;;UCMC,sBAAA;EACf,GAAA;EACA,MAAA,EAAQ,MAAA;ELCoD;EKC5D,WAAA;EACA,UAAA;EACA,aAAA;ELFW;EKIX,eAAA;;EAEA,eAAA;ELNqE;EKQrE,WAAA;AAAA;AAAA,UAGe,WAAA;EACf,aAAA;EACA,UAAA;ELVU;EKYV,IAAA,EAAM,MAAA;AAAA;AAAA,iBAGc,eAAA,CAAA;EACpB,GAAA;EACA,MAAA;EACA,WAAA;EACA,UAAA;EACA,aAAA;EACA,eAAA;EACA,eAAA;EACA;AAAA,GACC,sBAAA,GAAyB,OAAA,CAAQ,WAAA;;iBA8DpB,WAAA,CAAY,GAAA;;;UC3FX,gBAAA;EACf,KAAA;INA4D,sCME1D,MAAA;EAAA,IACE,MAAA;EACJ,WAAA;EACA,MAAA,EAAQ,MAAA;AAAA;AAAA,iBAGY,SAAA,CAAA;EAAY,KAAA;EAAO,WAAA;EAAa;AAAA,GAAU,gBAAA,GAAgB,OAAA;;;UCmE/D,WAAA;EACf,MAAA,EAAQ,MAAA;AAAA;AAAA,iBAGY,OAAA,CAAA;EAAU;AAAA,GAAU,WAAA,GAAW,OAAA;;;UChFpC,eAAA;EACf,KAAA,EAAO,KAAA;EACP,MAAA,EAAQ,UAAA;EACR,UAAA;EACA,MAAA,EAAQ,MAAA;AAAA;AAAA,iBAGY,MAAA,CAAA;EAAS,MAAA;EAAQ;AAAA,GAAU,eAAA,GAAe,OAAA;;;iBCdhD,UAAA,CAAA;;;iBCiBA,YAAA,CAAa,MAAA,EAAQ,MAAA,GAAS,UAAA"}
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import pc from "picocolors";
7
7
  import { createServer } from "vite";
8
8
  import { ViteNodeRunner } from "vite-node/client";
9
9
  import { ViteNodeServer } from "vite-node/server";
10
+ import { camelCase } from "scule";
10
11
  import chokidar from "chokidar";
11
12
  import yamlToMomoa from "yaml-to-momoa";
12
13
  import * as momoa from "@humanwhocodes/momoa";
@@ -15,7 +16,6 @@ import { isAlias, pluralize } from "@terrazzo/token-tools";
15
16
  import yaml from "yaml";
16
17
  import fs from "node:fs/promises";
17
18
  import { merge } from "merge-anything";
18
- import { camelCase } from "scule";
19
19
  import { spawn } from "node:child_process";
20
20
  import { confirm, intro, multiselect, outro, select, spinner } from "@clack/prompts";
21
21
  import { detect } from "detect-package-manager";
@@ -24,7 +24,107 @@ import { parseModule } from "meriyah";
24
24
  import { Readable, Writable } from "node:stream";
25
25
  import { serve } from "@hono/node-server";
26
26
  import mime from "mime";
27
-
27
+ //#region src/import/figma/lib.ts
28
+ const KEY = ":key";
29
+ const FILE_KEY = ":file_key";
30
+ const API = {
31
+ file: `https://api.figma.com/v1/files/${FILE_KEY}`,
32
+ fileNodes: `https://api.figma.com/v1/files/${FILE_KEY}/nodes`,
33
+ fileStyles: `https://api.figma.com/v1/files/${FILE_KEY}/styles`,
34
+ localVariables: `https://api.figma.com/v1/files/${FILE_KEY}/variables/local`,
35
+ publishedVariables: `https://api.figma.com/v1/files/${FILE_KEY}/variables/published`,
36
+ styles: `https://api.figma.com/v1/styles/${KEY}`
37
+ };
38
+ /** Wrapper around camelCase to handle more cases */
39
+ function formatName(name) {
40
+ return camelCase(name.replace(/\s+/g, "-"));
41
+ }
42
+ const nf = new Intl.NumberFormat("en-us");
43
+ /** Wrapper around camelCase to handle more cases */
44
+ function formatNumber(number) {
45
+ return nf.format(number);
46
+ }
47
+ /** Get File ID from design URL */
48
+ function getFileID(url) {
49
+ return url.match(/^https:\/\/(www\.)?figma\.com\/design\/([^/]+)/)?.[2];
50
+ }
51
+ /**
52
+ * Returns Figma API auth headers based on environment variables.
53
+ * Prefers OAuth (FIGMA_OAUTH_TOKEN) over PAT (FIGMA_ACCESS_TOKEN) if both are set.
54
+ * Warns via logger and returns empty headers if neither is set.
55
+ */
56
+ function getFigmaAuthHeaders(logger) {
57
+ if (process.env.FIGMA_OAUTH_TOKEN) return { Authorization: `Bearer ${process.env.FIGMA_OAUTH_TOKEN}` };
58
+ if (process.env.FIGMA_ACCESS_TOKEN) return { "X-Figma-Token": process.env.FIGMA_ACCESS_TOKEN };
59
+ logger.warn({
60
+ group: "config",
61
+ message: "Figma auth not configured! Set FIGMA_OAUTH_TOKEN or FIGMA_ACCESS_TOKEN"
62
+ });
63
+ return {};
64
+ }
65
+ /** /v1/files/:file_key */
66
+ async function getFile(fileKey, { logger }) {
67
+ const res = await fetch(API.file.replace(FILE_KEY, fileKey), {
68
+ method: "GET",
69
+ headers: getFigmaAuthHeaders(logger)
70
+ });
71
+ if (!res.ok) logger.error({
72
+ group: "import",
73
+ message: `${res.status} ${await res.text()}`
74
+ });
75
+ return await res.json();
76
+ }
77
+ /** /v1/files/:file_key/nodes */
78
+ async function getFileNodes(fileKey, { ids, logger }) {
79
+ let url = API.fileNodes.replace(FILE_KEY, fileKey);
80
+ if (ids?.length) url += `?ids=${ids.join(",")}`;
81
+ const res = await fetch(url, {
82
+ method: "GET",
83
+ headers: getFigmaAuthHeaders(logger)
84
+ });
85
+ if (!res.ok) logger.error({
86
+ group: "import",
87
+ message: `${res.status} ${await res.text()}`
88
+ });
89
+ return await res.json();
90
+ }
91
+ /** /v1/files/:file_key/styles */
92
+ async function getFileStyles(fileKey, { logger }) {
93
+ const res = await fetch(API.fileStyles.replace(FILE_KEY, fileKey), {
94
+ method: "GET",
95
+ headers: getFigmaAuthHeaders(logger)
96
+ });
97
+ if (!res.ok) logger.error({
98
+ group: "import",
99
+ message: `${res.status} ${await res.text()}`
100
+ });
101
+ return await res.json();
102
+ }
103
+ /** /v1/files/:file_key/variables/local */
104
+ async function getFileLocalVariables(fileKey, { logger }) {
105
+ const res = await fetch(API.localVariables.replace(FILE_KEY, fileKey), {
106
+ method: "GET",
107
+ headers: getFigmaAuthHeaders(logger)
108
+ });
109
+ if (!res.ok) logger.error({
110
+ group: "import",
111
+ message: `${res.status} ${await res.text}`
112
+ });
113
+ return await res.json();
114
+ }
115
+ /** /v1/files/:file_key/variables/published */
116
+ async function getFilePublishedVariables(fileKey, { logger }) {
117
+ const res = await fetch(API.publishedVariables.replace(FILE_KEY, fileKey), {
118
+ method: "GET",
119
+ headers: getFigmaAuthHeaders(logger)
120
+ });
121
+ if (!res.ok) logger.error({
122
+ group: "import",
123
+ message: `${res.status} ${await res.text}`
124
+ });
125
+ return await res.json();
126
+ }
127
+ //#endregion
28
128
  //#region src/shared.ts
29
129
  const cwd = new URL(`${pathToFileURL(process.cwd())}/`);
30
130
  const DEFAULT_CONFIG_PATH = new URL("./terrazzo.config.ts", cwd);
@@ -86,6 +186,7 @@ async function loadConfig({ cmd, flags, logger }) {
86
186
  cwd,
87
187
  logger
88
188
  });
189
+ if (flags["no-lint"]) config.lint.build.enabled = false;
89
190
  } catch (err) {
90
191
  logger.error({
91
192
  group: "config",
@@ -146,12 +247,8 @@ async function loadTokens(tokenPaths, { logger }) {
146
247
  });
147
248
  const headers = new Headers({
148
249
  Accept: "*/*",
149
- "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:123.0) Gecko/20100101 Firefox/123.0"
150
- });
151
- if (process.env.FIGMA_ACCESS_TOKEN) headers.set("X-FIGMA-TOKEN", process.env.FIGMA_ACCESS_TOKEN);
152
- else logger.warn({
153
- group: "config",
154
- message: "FIGMA_ACCESS_TOKEN not set"
250
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:123.0) Gecko/20100101 Firefox/123.0",
251
+ ...getFigmaAuthHeaders(logger)
155
252
  });
156
253
  const res = await fetch(`https://api.figma.com/v1/files/${fileKey}/variables/local`, {
157
254
  method: "GET",
@@ -245,7 +342,6 @@ function time(start) {
245
342
  const diff = performance.now() - start;
246
343
  return pc.dim(diff < 750 ? `${Math.round(diff)}ms` : `${(diff / 1e3).toFixed(1)}s`);
247
344
  }
248
-
249
345
  //#endregion
250
346
  //#region src/build.ts
251
347
  /** tz build */
@@ -264,9 +360,11 @@ async function buildCmd({ config, configPath, flags, logger }) {
264
360
  });
265
361
  return;
266
362
  }
363
+ const skipLint = !config.lint.build.enabled;
267
364
  let { tokens, resolver, sources } = await parse(rawSchemas, {
268
365
  config,
269
366
  logger,
367
+ skipLint,
270
368
  yamlToMomoa
271
369
  });
272
370
  let result = await build(tokens, {
@@ -296,6 +394,7 @@ async function buildCmd({ config, configPath, flags, logger }) {
296
394
  const parseResult = await parse(rawSchemas, {
297
395
  config,
298
396
  logger,
397
+ skipLint,
299
398
  yamlToMomoa
300
399
  });
301
400
  tokens = parseResult.tokens;
@@ -346,7 +445,6 @@ function writeFiles(result, { config, logger }) {
346
445
  });
347
446
  }
348
447
  }
349
-
350
448
  //#endregion
351
449
  //#region src/check.ts
352
450
  /** tz check */
@@ -373,7 +471,6 @@ async function checkCmd({ config, logger, positionals }) {
373
471
  process.exit(1);
374
472
  }
375
473
  }
376
-
377
474
  //#endregion
378
475
  //#region src/format.ts
379
476
  function findMember(name) {
@@ -492,7 +589,6 @@ function formatTypography(node) {
492
589
  if (!lineHeight) node.members.push(momoa.parse("{\"lineHeight\":1}").body.members[0]);
493
590
  return node;
494
591
  }
495
-
496
592
  //#endregion
497
593
  //#region src/help.ts
498
594
  /** Show help */
@@ -522,95 +618,6 @@ function helpCmd() {
522
618
  --quiet Suppress warnings
523
619
  `);
524
620
  }
525
-
526
- //#endregion
527
- //#region src/import/figma/lib.ts
528
- const KEY = ":key";
529
- const FILE_KEY = ":file_key";
530
- const API = {
531
- file: `https://api.figma.com/v1/files/${FILE_KEY}`,
532
- fileNodes: `https://api.figma.com/v1/files/${FILE_KEY}/nodes`,
533
- fileStyles: `https://api.figma.com/v1/files/${FILE_KEY}/styles`,
534
- localVariables: `https://api.figma.com/v1/files/${FILE_KEY}/variables/local`,
535
- publishedVariables: `https://api.figma.com/v1/files/${FILE_KEY}/variables/published`,
536
- styles: `https://api.figma.com/v1/styles/${KEY}`
537
- };
538
- /** Wrapper around camelCase to handle more cases */
539
- function formatName(name) {
540
- return camelCase(name.replace(/\s+/g, "-"));
541
- }
542
- const nf = new Intl.NumberFormat("en-us");
543
- /** Wrapper around camelCase to handle more cases */
544
- function formatNumber(number) {
545
- return nf.format(number);
546
- }
547
- /** Get File ID from design URL */
548
- function getFileID(url) {
549
- return url.match(/^https:\/\/(www\.)?figma\.com\/design\/([^/]+)/)?.[2];
550
- }
551
- /** /v1/files/:file_key */
552
- async function getFile(fileKey, { logger }) {
553
- const res = await fetch(API.file.replace(FILE_KEY, fileKey), {
554
- method: "GET",
555
- headers: { "X-Figma-Token": process.env.FIGMA_ACCESS_TOKEN }
556
- });
557
- if (!res.ok) logger.error({
558
- group: "import",
559
- message: `${res.status} ${await res.text()}`
560
- });
561
- return await res.json();
562
- }
563
- /** /v1/files/:file_key/nodes */
564
- async function getFileNodes(fileKey, { ids, logger }) {
565
- let url = API.fileNodes.replace(FILE_KEY, fileKey);
566
- if (ids?.length) url += `?ids=${ids.join(",")}`;
567
- const res = await fetch(url, {
568
- method: "GET",
569
- headers: { "X-Figma-Token": process.env.FIGMA_ACCESS_TOKEN }
570
- });
571
- if (!res.ok) logger.error({
572
- group: "import",
573
- message: `${res.status} ${await res.text()}`
574
- });
575
- return await res.json();
576
- }
577
- /** /v1/files/:file_key/styles */
578
- async function getFileStyles(fileKey, { logger }) {
579
- const res = await fetch(API.fileStyles.replace(FILE_KEY, fileKey), {
580
- method: "GET",
581
- headers: { "X-Figma-Token": process.env.FIGMA_ACCESS_TOKEN }
582
- });
583
- if (!res.ok) logger.error({
584
- group: "import",
585
- message: `${res.status} ${await res.text()}`
586
- });
587
- return await res.json();
588
- }
589
- /** /v1/files/:file_key/variables/local */
590
- async function getFileLocalVariables(fileKey, { logger }) {
591
- const res = await fetch(API.localVariables.replace(FILE_KEY, fileKey), {
592
- method: "GET",
593
- headers: { "X-Figma-Token": process.env.FIGMA_ACCESS_TOKEN }
594
- });
595
- if (!res.ok) logger.error({
596
- group: "import",
597
- message: `${res.status} ${await res.text}`
598
- });
599
- return await res.json();
600
- }
601
- /** /v1/files/:file_key/variables/published */
602
- async function getFilePublishedVariables(fileKey, { logger }) {
603
- const res = await fetch(API.publishedVariables.replace(FILE_KEY, fileKey), {
604
- method: "GET",
605
- headers: { "X-Figma-Token": process.env.FIGMA_ACCESS_TOKEN }
606
- });
607
- if (!res.ok) logger.error({
608
- group: "import",
609
- message: `${res.status} ${await res.text}`
610
- });
611
- return await res.json();
612
- }
613
-
614
621
  //#endregion
615
622
  //#region src/import/figma/styles.ts
616
623
  /** /v1/files/:file_key/styles */
@@ -843,9 +850,11 @@ function textStyle(node) {
843
850
  } : 1
844
851
  };
845
852
  }
846
-
847
853
  //#endregion
848
854
  //#region src/import/figma/variables.ts
855
+ function getAliasID(value) {
856
+ if (typeof value === "object" && value && "type" in value && value.type === "VARIABLE_ALIAS" && "id" in value && typeof value.id === "string") return value.id;
857
+ }
849
858
  /** /v1/files/:file_key/variables/published | /v1/files/:file_key/variables/local */
850
859
  async function getVariables(fileKey, { logger, unpublished, matchers }) {
851
860
  const result = {
@@ -861,19 +870,27 @@ async function getVariables(fileKey, { logger, unpublished, matchers }) {
861
870
  let finalVariables = {};
862
871
  const modeIDToName = {};
863
872
  const local = await getFileLocalVariables(fileKey, { logger });
864
- for (const id of Object.keys(local.meta.variables)) {
865
- if (local.meta.variables[id].hiddenFromPublishing) continue;
866
- allVariables[id] = local.meta.variables[id];
867
- }
873
+ for (const id of Object.keys(local.meta.variables)) allVariables[id] = local.meta.variables[id];
868
874
  for (const id of Object.keys(local.meta.variableCollections)) {
869
875
  variableCollections[id] = local.meta.variableCollections[id];
870
876
  for (const mode of local.meta.variableCollections[id].modes) modeIDToName[mode.modeId] = formatName(mode.name);
871
877
  }
872
- if (unpublished) finalVariables = allVariables;
878
+ if (unpublished) finalVariables = Object.fromEntries(Object.entries(allVariables).filter(([, variable]) => !variable.hiddenFromPublishing));
873
879
  else {
874
880
  const published = await getFilePublishedVariables(fileKey, { logger });
875
881
  for (const id of Object.keys(published.meta.variables)) finalVariables[id] = allVariables[id];
876
882
  }
883
+ const pendingIDs = Object.keys(finalVariables);
884
+ for (let i = 0; i < pendingIDs.length; i++) {
885
+ const variable = finalVariables[pendingIDs[i]];
886
+ if (!variable) continue;
887
+ for (const value of Object.values(variable.valuesByMode)) {
888
+ const aliasID = getAliasID(value);
889
+ if (!aliasID || !allVariables[aliasID] || aliasID in finalVariables) continue;
890
+ finalVariables[aliasID] = allVariables[aliasID];
891
+ pendingIDs.push(aliasID);
892
+ }
893
+ }
877
894
  const remoteIDs = /* @__PURE__ */ new Set();
878
895
  for (const id of Object.keys(finalVariables)) {
879
896
  const variable = finalVariables[id];
@@ -905,7 +922,7 @@ async function getVariables(fileKey, { logger, unpublished, matchers }) {
905
922
  codeSyntax: Object.keys(variable.codeSyntax).length ? variable.codeSyntax : void 0
906
923
  } }
907
924
  };
908
- const isAliasOfID = typeof value === "object" && "type" in value && value.type === "VARIABLE_ALIAS" && value.id || void 0;
925
+ const isAliasOfID = getAliasID(value);
909
926
  if (isAliasOfID) if (allVariables[isAliasOfID]) {
910
927
  tokenBase.$type = matches || {
911
928
  COLOR: "color",
@@ -971,7 +988,6 @@ async function getVariables(fileKey, { logger, unpublished, matchers }) {
971
988
  result.remoteCount = remoteIDs.size;
972
989
  return result;
973
990
  }
974
-
975
991
  //#endregion
976
992
  //#region src/import/figma/index.ts
977
993
  async function importFromFigma({ url, logger, unpublished, skipStyles, skipVariables, fontFamilyNames = "/fontFamily$", fontWeightNames = "/fontWeight$", numberNames }) {
@@ -1031,7 +1047,6 @@ function isFigmaPath(url) {
1031
1047
  return false;
1032
1048
  }
1033
1049
  }
1034
-
1035
1050
  //#endregion
1036
1051
  //#region src/import/index.ts
1037
1052
  async function importCmd({ flags, positionals, logger }) {
@@ -1041,10 +1056,10 @@ async function importCmd({ flags, positionals, logger }) {
1041
1056
  message: "Missing import path. Expected `tz import [file]`."
1042
1057
  });
1043
1058
  if (isFigmaPath(url)) {
1044
- const { FIGMA_ACCESS_TOKEN } = process.env;
1045
- if (!FIGMA_ACCESS_TOKEN) logger.error({
1059
+ const { FIGMA_ACCESS_TOKEN, FIGMA_OAUTH_TOKEN } = process.env;
1060
+ if (!FIGMA_ACCESS_TOKEN && !FIGMA_OAUTH_TOKEN) logger.error({
1046
1061
  group: "import",
1047
- message: `FIGMA_ACCESS_TOKEN not set! See https://terrazzo.app/docs/guides/import-from-figma`
1062
+ message: `Figma auth not configured! Set FIGMA_OAUTH_TOKEN (OAuth access token) or FIGMA_ACCESS_TOKEN (Personal Access Token). See https://terrazzo.app/docs/guides/import-from-figma`
1048
1063
  });
1049
1064
  const start = performance.now();
1050
1065
  const result = await importFromFigma({
@@ -1079,7 +1094,6 @@ async function importCmd({ flags, positionals, logger }) {
1079
1094
  return;
1080
1095
  }
1081
1096
  }
1082
-
1083
1097
  //#endregion
1084
1098
  //#region src/init.ts
1085
1099
  const INSTALL_COMMAND = {
@@ -1534,7 +1548,6 @@ const EXAMPLE_TOKENS = {
1534
1548
  }
1535
1549
  }
1536
1550
  };
1537
-
1538
1551
  //#endregion
1539
1552
  //#region src/lab.ts
1540
1553
  async function labCmd({ config, logger }) {
@@ -1583,14 +1596,12 @@ async function labCmd({ config, logger }) {
1583
1596
  server.on("error", reject);
1584
1597
  });
1585
1598
  }
1586
-
1587
1599
  //#endregion
1588
1600
  //#region src/version.ts
1589
1601
  function versionCmd() {
1590
1602
  const { version } = JSON.parse(fsSync.readFileSync(new URL("../package.json", import.meta.url), "utf8"));
1591
1603
  console.log(version);
1592
1604
  }
1593
-
1594
1605
  //#endregion
1595
1606
  //#region src/index.ts
1596
1607
  const require = createRequire(cwd);
@@ -1608,7 +1619,7 @@ function defineConfig(config) {
1608
1619
  });
1609
1620
  return defineConfig$1(normalizedConfig, { cwd });
1610
1621
  }
1611
-
1612
1622
  //#endregion
1613
1623
  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 };
1624
+
1614
1625
  //# sourceMappingURL=index.js.map