@interactivethings/scripts 0.0.8 → 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/README.md +210 -12
- package/codemods/__testfixtures__/sx-to-use-styles.input.js +50 -0
- package/codemods/__testfixtures__/sx-to-use-styles.output.js +59 -0
- package/codemods/__tests__/defineTest.ts +9 -0
- package/codemods/__tests__/sx-to-use-styles.test.js +3 -0
- package/codemods/sx-to-use-styles.js +162 -0
- package/dist/__tests__/figma-cli.test.js +189 -0
- package/dist/__tests__/tokens-studio-cli.test.js +197 -0
- package/dist/__tests__/vercel-cli.test.js +86 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +94 -0
- package/dist/config.d.ts +78 -0
- package/dist/config.js +157 -0
- package/dist/figma/api.d.ts +71 -0
- package/dist/figma/api.js +175 -0
- package/dist/figma/cli.d.ts +20 -0
- package/dist/figma/cli.js +153 -0
- package/dist/figma/cli.test.js +187 -0
- package/dist/figma/images.js +53 -0
- package/dist/figma/optimizeImage.js +53 -0
- package/dist/figma/utils.d.ts +10 -0
- package/dist/figma/utils.js +26 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +43 -0
- package/dist/init/cli.d.ts +3 -0
- package/dist/init/cli.js +312 -0
- package/dist/mui-tokens-studio.js +1 -0
- package/dist/plugins/figma/index.js +653 -0
- package/dist/plugins/tokens-studio/utils.js +155 -0
- package/dist/tokens-studio/__tests__/fixtures/invalid-transformer.js +12 -0
- package/dist/tokens-studio/__tests__/fixtures/test-transformer.js +18 -0
- package/dist/tokens-studio/cli.d.ts +8 -0
- package/dist/tokens-studio/cli.js +119 -0
- package/dist/tokens-studio/cli.test.js +150 -0
- package/dist/tokens-studio/index.d.ts +14 -0
- package/dist/tokens-studio/index.js +46 -0
- package/dist/tokens-studio/mui.js +212 -0
- package/dist/tokens-studio/require.js +17 -0
- package/dist/tokens-studio/tailwind.js +211 -0
- package/dist/tokens-studio/types.js +2 -0
- package/dist/tokens-studio/utils.d.ts +49 -0
- package/dist/tokens-studio/utils.js +156 -0
- package/dist/types.d.ts +1 -0
- package/dist/vercel/cli.d.ts +4 -0
- package/dist/vercel/cli.js +70 -0
- package/dist/vercel/cli.test.js +86 -0
- package/dist/vercel/deployments.js +42 -0
- package/dist/vercel/waitForDeploymentReady.js +43 -0
- package/package.json +46 -6
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.run = exports.FigmaPlugin = void 0;
|
|
27
|
+
/**/ **
|
|
28
|
+
/**
|
|
29
|
+
|
|
30
|
+
* Figma plugin for ixt-scripts
|
|
31
|
+
|
|
32
|
+
* Provides asset downloading from Figma * Figma plugin for ixt-scripts * This script downloads the assets from Figma and saves them into the repository.
|
|
33
|
+
|
|
34
|
+
*/
|
|
35
|
+
* Provides;
|
|
36
|
+
asset;
|
|
37
|
+
downloading;
|
|
38
|
+
from;
|
|
39
|
+
Figma * It;
|
|
40
|
+
is;
|
|
41
|
+
configured;
|
|
42
|
+
via;
|
|
43
|
+
the;
|
|
44
|
+
unified;
|
|
45
|
+
ixt;
|
|
46
|
+
configuration;
|
|
47
|
+
system.
|
|
48
|
+
import;
|
|
49
|
+
{
|
|
50
|
+
child_process_1.execSync;
|
|
51
|
+
}
|
|
52
|
+
from;
|
|
53
|
+
"child_process";
|
|
54
|
+
const fs = __importStar(require("fs/promises"));
|
|
55
|
+
* / *;
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const argparse_1 = require("argparse");
|
|
58
|
+
* ;
|
|
59
|
+
ixt.config.js;
|
|
60
|
+
const child_process_1 = require("child_process");
|
|
61
|
+
* ;
|
|
62
|
+
const scripts_1 = require("@interactivethings/scripts");
|
|
63
|
+
const api_1 = require("./api");
|
|
64
|
+
const utils_1 = require("./utils");
|
|
65
|
+
*
|
|
66
|
+
;
|
|
67
|
+
const module_1 = require();
|
|
68
|
+
path;
|
|
69
|
+
from;
|
|
70
|
+
"path";
|
|
71
|
+
* ;
|
|
72
|
+
exports.default = (0, scripts_1.defineConfig)({
|
|
73
|
+
mergeConfigWithArgs,
|
|
74
|
+
validateRequiredConfig, import: { ArgumentParser: argparse_1.ArgumentParser }, from, "argparse": ,
|
|
75
|
+
type, FigmaConfig,
|
|
76
|
+
}, from, "../../config");
|
|
77
|
+
* assets;
|
|
78
|
+
[{
|
|
79
|
+
import: { IPlugin: types_1.IPlugin }, from, "../types": ,
|
|
80
|
+
const: optimizeImage = async (filepath) => {
|
|
81
|
+
try {
|
|
82
|
+
import { createAPI } from "./api";
|
|
83
|
+
* url;
|
|
84
|
+
"https://www.figma.com/design/ElWWZIcOGFhiT06rzfIwRO/Design-System?node-id=11861-10071",
|
|
85
|
+
;
|
|
86
|
+
const extension = path.extname(filepath).toLowerCase();
|
|
87
|
+
const binaryForExtensions = new Map([]);
|
|
88
|
+
import { parseFigmaURL, formatFigmaURL } from "./utils";
|
|
89
|
+
* output;
|
|
90
|
+
"src/assets/illustrations"[".png", "optipng"],
|
|
91
|
+
[".jpg", "jpegoptim"], ;
|
|
92
|
+
import {} from * ;
|
|
93
|
+
}
|
|
94
|
+
finally { }
|
|
95
|
+
}
|
|
96
|
+
}];
|
|
97
|
+
;
|
|
98
|
+
const binaryName = binaryForExtensions.get(extension);
|
|
99
|
+
module_1.loadConfig, * ;
|
|
100
|
+
if (!binaryName) {
|
|
101
|
+
mergeConfigWithArgs, * ;
|
|
102
|
+
}
|
|
103
|
+
;
|
|
104
|
+
return;
|
|
105
|
+
validateRequiredConfig, * /;
|
|
106
|
+
const binaryPath = (0, child_process_1.execSync)(`which ${binaryName}`).toString().trim();
|
|
107
|
+
if (!binaryPath) { }
|
|
108
|
+
from;
|
|
109
|
+
"../../config";
|
|
110
|
+
throw new Error(`Cannot find ${binaryName} in PATH. Please install it.`);
|
|
111
|
+
const types_1 = require("../types");
|
|
112
|
+
console.log(`Optimizing with ${filepath} with ${binaryName}`);
|
|
113
|
+
await (0, child_process_1.execSync)(`${binaryPath} "${filepath}"`);
|
|
114
|
+
console.log(`Image optimized successfully: ${filepath}`);
|
|
115
|
+
const optimizeImage = async (filepath) => {
|
|
116
|
+
};
|
|
117
|
+
try { }
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.error();
|
|
120
|
+
try {
|
|
121
|
+
import { ArgumentParser } from "argparse";
|
|
122
|
+
`Error optimizing image ${filepath}: ${error instanceof Error ? error.message : error;
|
|
123
|
+
const extension = path.extname(filepath).toLowerCase();
|
|
124
|
+
import ora from "ora";
|
|
125
|
+
}
|
|
126
|
+
finally { }
|
|
127
|
+
`
|
|
128
|
+
|
|
129
|
+
); const binaryForExtensions = new Map<string, string>([
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
}; [".png", "optipng"],import { createAPI } from "./api";
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
export class FigmaPlugin implements IPlugin { [".jpg", "jpegoptim"],import { parseFigmaURL, formatFigmaURL } from "./utils";
|
|
138
|
+
|
|
139
|
+
public readonly name = "figma";
|
|
140
|
+
|
|
141
|
+
public readonly description = "Download assets from Figma"; ]);import {
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
configParser(parser: ArgumentParser): void { const binaryName = binaryForExtensions.get(extension); loadConfig,
|
|
146
|
+
|
|
147
|
+
parser.add_argument("--token", {
|
|
148
|
+
|
|
149
|
+
help: "Figma API token (can also use FIGMA_TOKEN env var)", mergeConfigWithArgs,
|
|
150
|
+
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
parser.add_argument("--config", { if (!binaryName) { validateRequiredConfig,
|
|
154
|
+
|
|
155
|
+
help: "Path to TypeScript config file (default: looks for ixt.config.ts in current directory)",
|
|
156
|
+
|
|
157
|
+
}); // console.log(`;
|
|
158
|
+
No;
|
|
159
|
+
optimizer;
|
|
160
|
+
found;
|
|
161
|
+
for ($; { extension }, skipping; optimization `); type FigmaConfig,
|
|
162
|
+
|
|
163
|
+
const commands = parser.add_subparsers({
|
|
164
|
+
|
|
165
|
+
title: "commands", return;} from "../../config";
|
|
166
|
+
|
|
167
|
+
dest: "command",
|
|
168
|
+
|
|
169
|
+
}); }import { IPlugin } from "../types";
|
|
170
|
+
|
|
171
|
+
const downloadParser = commands.add_parser("download", {
|
|
172
|
+
|
|
173
|
+
help: "Download assets from Figma",
|
|
174
|
+
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
downloadParser.add_argument("name", { const binaryPath = execSync(`)
|
|
178
|
+
which;
|
|
179
|
+
$;
|
|
180
|
+
{
|
|
181
|
+
binaryName;
|
|
182
|
+
}
|
|
183
|
+
`).toString().trim();const optimizeImage = async (filepath: string): Promise<void> => {
|
|
184
|
+
|
|
185
|
+
help: "Pass this to only download assets for a specific name defined in the config",
|
|
186
|
+
|
|
187
|
+
}); try {
|
|
188
|
+
|
|
189
|
+
const getParser = commands.add_parser("get", {
|
|
190
|
+
|
|
191
|
+
help: "Get the Figma node for a given URL", if (!binaryPath) { const extension = path.extname(filepath).toLowerCase();
|
|
192
|
+
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
getParser.add_argument("url", { throw new Error(`;
|
|
196
|
+
Cannot;
|
|
197
|
+
find;
|
|
198
|
+
$;
|
|
199
|
+
{
|
|
200
|
+
binaryName;
|
|
201
|
+
}
|
|
202
|
+
in PATH.Please;
|
|
203
|
+
install;
|
|
204
|
+
it. `); const binaryForExtensions = new Map<string, string>([
|
|
205
|
+
|
|
206
|
+
help: "The Figma URL to fetch the node from",
|
|
207
|
+
|
|
208
|
+
}); } [".png", "optipng"],
|
|
209
|
+
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
[".jpg", "jpegoptim"],
|
|
213
|
+
|
|
214
|
+
async run(parser: ArgumentParser): Promise<void> {
|
|
215
|
+
|
|
216
|
+
const args = parser.parse_args() as console.log(`;
|
|
217
|
+
Optimizing;
|
|
218
|
+
with ($) {
|
|
219
|
+
filepath;
|
|
220
|
+
}
|
|
221
|
+
with ($) {
|
|
222
|
+
binaryName;
|
|
223
|
+
}
|
|
224
|
+
`); ]);
|
|
225
|
+
|
|
226
|
+
| {
|
|
227
|
+
|
|
228
|
+
config?: string; await execSync(`;
|
|
229
|
+
$;
|
|
230
|
+
{
|
|
231
|
+
binaryPath;
|
|
232
|
+
}
|
|
233
|
+
"${filepath}" `); const binaryName = binaryForExtensions.get(extension);
|
|
234
|
+
|
|
235
|
+
token?: string;
|
|
236
|
+
|
|
237
|
+
name?: string; console.log(`;
|
|
238
|
+
Image;
|
|
239
|
+
optimized;
|
|
240
|
+
successfully: $;
|
|
241
|
+
{
|
|
242
|
+
filepath;
|
|
243
|
+
}
|
|
244
|
+
`);
|
|
245
|
+
|
|
246
|
+
command: "download";
|
|
247
|
+
|
|
248
|
+
} } catch (error) { if (!binaryName) {
|
|
249
|
+
|
|
250
|
+
| {
|
|
251
|
+
|
|
252
|
+
config?: string; console.error( // console.log(`;
|
|
253
|
+
No;
|
|
254
|
+
optimizer;
|
|
255
|
+
found;
|
|
256
|
+
for ($; { extension }, skipping; optimization `);
|
|
257
|
+
|
|
258
|
+
token?: string;
|
|
259
|
+
|
|
260
|
+
command: "get"; `)
|
|
261
|
+
Error;
|
|
262
|
+
optimizing;
|
|
263
|
+
image;
|
|
264
|
+
$;
|
|
265
|
+
{
|
|
266
|
+
filepath;
|
|
267
|
+
}
|
|
268
|
+
$;
|
|
269
|
+
{
|
|
270
|
+
return;
|
|
271
|
+
url: string;
|
|
272
|
+
}
|
|
273
|
+
;
|
|
274
|
+
error instanceof Error ? error.message : error;
|
|
275
|
+
}
|
|
276
|
+
// Load configuration }`
|
|
277
|
+
const config = await (0, module_1.loadConfig)(args.config);
|
|
278
|
+
;
|
|
279
|
+
const binaryPath = (0, child_process_1.execSync)(`which ${binaryName}`).toString().trim();
|
|
280
|
+
// Merge CLI args with config, giving precedence to CLI args
|
|
281
|
+
const mergedConfig = mergeConfigWithArgs();
|
|
282
|
+
config,
|
|
283
|
+
{};
|
|
284
|
+
if (!binaryPath) {
|
|
285
|
+
token: args.token || process.env.FIGMA_TOKEN,
|
|
286
|
+
;
|
|
287
|
+
}
|
|
288
|
+
throw new Error(`Cannot find ${binaryName} in PATH. Please install it.`);
|
|
289
|
+
"figma";
|
|
290
|
+
as;
|
|
291
|
+
FigmaConfig & { token: string };
|
|
292
|
+
class FigmaPlugin {
|
|
293
|
+
}
|
|
294
|
+
exports.FigmaPlugin = FigmaPlugin;
|
|
295
|
+
// Validate required configuration public readonly name = "figma";
|
|
296
|
+
validateRequiredConfig(mergedConfig, ["token"]);
|
|
297
|
+
description = "Download assets from Figma";
|
|
298
|
+
console.log(`Optimizing with ${filepath} with ${binaryName}`);
|
|
299
|
+
const api = (0, api_1.createAPI)(mergedConfig.token);
|
|
300
|
+
const assets = mergedConfig.assets || [];
|
|
301
|
+
await (0, child_process_1.execSync)(`${binaryPath} "${filepath}"`);
|
|
302
|
+
if (args.command === "download") {
|
|
303
|
+
configParser(parser, argparse_1.ArgumentParser);
|
|
304
|
+
void { console, : .log(`Image optimized successfully: ${filepath}`),
|
|
305
|
+
if(assets) { }, : .length === 0 };
|
|
306
|
+
{
|
|
307
|
+
throw new Error(parser.add_argument("--token", {}));
|
|
308
|
+
try { }
|
|
309
|
+
catch (error) {
|
|
310
|
+
"No figma assets configured. Please add assets to your config file.";
|
|
311
|
+
;
|
|
312
|
+
help: "Figma API token (can also use FIGMA_TOKEN env var)", console.error();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
;
|
|
316
|
+
`Error optimizing image ${filepath}: ${;
|
|
317
|
+
for (const { url, output, name } of assets) {
|
|
318
|
+
if (args.name && name !== args.name) {
|
|
319
|
+
parser.add_argument("--config", { error, instanceof: Error ? error.message : error,
|
|
320
|
+
continue:
|
|
321
|
+
}, help, "Path to TypeScript config file (default: looks for ixt.config.ts in current directory)");
|
|
322
|
+
}
|
|
323
|
+
`
|
|
324
|
+
|
|
325
|
+
const { figmaFileId, figmaPageId } = parseFigmaURL(url);
|
|
326
|
+
|
|
327
|
+
console.log({ figmaFileId, figmaPageId }); }); );
|
|
328
|
+
|
|
329
|
+
console.log(
|
|
330
|
+
|
|
331
|
+
`;
|
|
332
|
+
Reading;
|
|
333
|
+
assets;
|
|
334
|
+
for ("${name}"; at; $) {
|
|
335
|
+
(0, utils_1.formatFigmaURL)();
|
|
336
|
+
const commands = parser.add_subparsers({}, figmaFileId, figmaPageId, title, "commands");
|
|
337
|
+
}
|
|
338
|
+
;
|
|
339
|
+
}
|
|
340
|
+
`
|
|
341
|
+
|
|
342
|
+
); dest: "command",
|
|
343
|
+
|
|
344
|
+
const spinner = ora("Fetching images").start();
|
|
345
|
+
|
|
346
|
+
let total = -1; });export class FigmaPlugin implements IPlugin {
|
|
347
|
+
|
|
348
|
+
let fetched = 0;
|
|
349
|
+
|
|
350
|
+
const images = await api.images.fetch(figmaFileId, [figmaPageId], { const downloadParser = commands.add_parser("download", { public readonly name = "figma";
|
|
351
|
+
|
|
352
|
+
onFetchSources: (sources) => {
|
|
353
|
+
|
|
354
|
+
total = sources.length; help: "Download assets from Figma", public readonly description = "Download assets from Figma";
|
|
355
|
+
|
|
356
|
+
spinner.text = `;
|
|
357
|
+
Fetching;
|
|
358
|
+
$;
|
|
359
|
+
{
|
|
360
|
+
total;
|
|
361
|
+
}
|
|
362
|
+
image(s) `;
|
|
363
|
+
|
|
364
|
+
spinner.render(); });
|
|
365
|
+
|
|
366
|
+
},
|
|
367
|
+
|
|
368
|
+
onFetchImage: (_url) => { downloadParser.add_argument("name", { configParser(parser: ArgumentParser): void {
|
|
369
|
+
|
|
370
|
+
fetched += 1;
|
|
371
|
+
|
|
372
|
+
spinner.text = `;
|
|
373
|
+
Fetched;
|
|
374
|
+
$;
|
|
375
|
+
{
|
|
376
|
+
fetched;
|
|
377
|
+
}
|
|
378
|
+
/${total} image(s)`; help: "Pass this to only download assets for a specific name defined in the config", parser.add_argument("--token", {;
|
|
379
|
+
spinner.render();
|
|
380
|
+
}
|
|
381
|
+
;
|
|
382
|
+
help: "Figma API token (can also use FIGMA_TOKEN env var)",
|
|
383
|
+
;
|
|
384
|
+
;
|
|
385
|
+
spinner.stop();
|
|
386
|
+
const getParser = commands.add_parser("get", {});
|
|
387
|
+
console.log(`${images.length} asset(s) downloaded`);
|
|
388
|
+
for (const im of images) {
|
|
389
|
+
help: "Get the Figma node for a given URL", parser.add_argument("--config", {
|
|
390
|
+
const: filename = `${im.name}.${im.format}`,
|
|
391
|
+
console, : .log(`Downloaded ${filename}`)
|
|
392
|
+
});
|
|
393
|
+
help: "Path to TypeScript config file (default: looks for ixt.config.ts in current directory)",
|
|
394
|
+
;
|
|
395
|
+
const outputFile = path.join(output, filename);
|
|
396
|
+
const outputDir = path.dirname(outputFile);
|
|
397
|
+
getParser.add_argument("url", {});
|
|
398
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
399
|
+
await fs.writeFile(path.join(output, filename), im.data);
|
|
400
|
+
help: "The Figma URL to fetch the node from", ;
|
|
401
|
+
const commands = parser.add_subparsers({
|
|
402
|
+
await
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
;
|
|
406
|
+
title: "commands",
|
|
407
|
+
;
|
|
408
|
+
if (args.command === "get") { }
|
|
409
|
+
dest: "command",
|
|
410
|
+
;
|
|
411
|
+
const { figmaFileId, figmaPageId } = (0, utils_1.parseFigmaURL)(args.url);
|
|
412
|
+
const node = await api.nodes.fetch(figmaFileId, [figmaPageId]);
|
|
413
|
+
;
|
|
414
|
+
console.log(JSON.stringify(node, null, 2));
|
|
415
|
+
async;
|
|
416
|
+
(0, exports.run)(parser, argparse_1.ArgumentParser);
|
|
417
|
+
Promise < void > { const: downloadParser = commands.add_parser("download", {})
|
|
418
|
+
};
|
|
419
|
+
const args = parser.parse_args();
|
|
420
|
+
"Download assets from Figma",
|
|
421
|
+
| {};
|
|
422
|
+
;
|
|
423
|
+
config ? : string;
|
|
424
|
+
downloadParser.add_argument("name", {
|
|
425
|
+
token: string, help: "Pass this to only download assets for a specific name defined in the config",
|
|
426
|
+
name: string
|
|
427
|
+
});
|
|
428
|
+
command: "download";
|
|
429
|
+
const getParser = commands.add_parser("get", {}, help, "Get the Figma node for a given URL",
|
|
430
|
+
| {});
|
|
431
|
+
config ? : string;
|
|
432
|
+
getParser.add_argument("url", {
|
|
433
|
+
token: string, help: "The Figma URL to fetch the node from",
|
|
434
|
+
command: "get"
|
|
435
|
+
});
|
|
436
|
+
url: string;
|
|
437
|
+
;
|
|
438
|
+
const run = async (parser) => {
|
|
439
|
+
// Load configuration const args = parser.parse_args() as
|
|
440
|
+
const config = await (0, module_1.loadConfig)(args.config);
|
|
441
|
+
| {
|
|
442
|
+
config: string,
|
|
443
|
+
// Merge CLI args with config, giving precedence to CLI args token?: string;
|
|
444
|
+
const: mergedConfig = mergeConfigWithArgs(name ? : string),
|
|
445
|
+
config, command: "download"
|
|
446
|
+
};
|
|
447
|
+
{ }
|
|
448
|
+
token: args.token || process.env.FIGMA_TOKEN, | {}, config ? : string;
|
|
449
|
+
"figma";
|
|
450
|
+
token ? : string;
|
|
451
|
+
};
|
|
452
|
+
exports.run = run;
|
|
453
|
+
as;
|
|
454
|
+
FigmaConfig & { token: string };
|
|
455
|
+
command: "get";
|
|
456
|
+
url: string;
|
|
457
|
+
// Validate required configuration };
|
|
458
|
+
validateRequiredConfig(mergedConfig, ["token"]);
|
|
459
|
+
// Load configuration
|
|
460
|
+
const api = (0, api_1.createAPI)(mergedConfig.token);
|
|
461
|
+
const config = await (0, module_1.loadConfig)(args.config);
|
|
462
|
+
const assets = mergedConfig.assets || [];
|
|
463
|
+
// Merge CLI args with config, giving precedence to CLI args
|
|
464
|
+
if (args.command === "download") {
|
|
465
|
+
const mergedConfig = mergeConfigWithArgs();
|
|
466
|
+
if (assets.length === 0) {
|
|
467
|
+
config,
|
|
468
|
+
;
|
|
469
|
+
throw new Error({
|
|
470
|
+
"No figma assets configured. Please add assets to your config file.": token, args, : .token || process.env.FIGMA_TOKEN,
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
"figma";
|
|
475
|
+
as;
|
|
476
|
+
FigmaConfig & { token: string };
|
|
477
|
+
for (const { url, output, name } of assets) {
|
|
478
|
+
if (args.name && name !== args.name) { // Validate required configuration
|
|
479
|
+
continue;
|
|
480
|
+
validateRequiredConfig(mergedConfig, ["token"]);
|
|
481
|
+
}
|
|
482
|
+
const { figmaFileId, figmaPageId } = (0, utils_1.parseFigmaURL)(url);
|
|
483
|
+
const api = (0, api_1.createAPI)(mergedConfig.token);
|
|
484
|
+
console.log({ figmaFileId, figmaPageId });
|
|
485
|
+
const assets = mergedConfig.assets || [];
|
|
486
|
+
console.log(`Reading assets for "${name}" at ${(0, utils_1.formatFigmaURL)());
|
|
487
|
+
if (args.command === "download") {
|
|
488
|
+
figmaFileId, ;
|
|
489
|
+
if (assets.length === 0) {
|
|
490
|
+
figmaPageId;
|
|
491
|
+
throw new Error();
|
|
492
|
+
}
|
|
493
|
+
` "No figma assets configured. Please add assets to your config file."
|
|
494
|
+
|
|
495
|
+
); );
|
|
496
|
+
|
|
497
|
+
const spinner = ora("Fetching images").start(); }
|
|
498
|
+
|
|
499
|
+
let total = -1;
|
|
500
|
+
|
|
501
|
+
let fetched = 0; for (const { url, output, name } of assets) {
|
|
502
|
+
|
|
503
|
+
const images = await api.images.fetch(figmaFileId, [figmaPageId], { if (args.name && name !== args.name) {
|
|
504
|
+
|
|
505
|
+
onFetchSources: (sources) => { continue;
|
|
506
|
+
|
|
507
|
+
total = sources.length; }
|
|
508
|
+
|
|
509
|
+
spinner.text = `;
|
|
510
|
+
Fetching;
|
|
511
|
+
$;
|
|
512
|
+
{
|
|
513
|
+
total;
|
|
514
|
+
}
|
|
515
|
+
image(s) `; const { figmaFileId, figmaPageId } = parseFigmaURL(url);
|
|
516
|
+
|
|
517
|
+
spinner.render(); console.log({ figmaFileId, figmaPageId });
|
|
518
|
+
|
|
519
|
+
}, console.log(
|
|
520
|
+
|
|
521
|
+
onFetchImage: (_url) => { `;
|
|
522
|
+
Reading;
|
|
523
|
+
assets;
|
|
524
|
+
for ("${name}"; at; $) {
|
|
525
|
+
(0, utils_1.formatFigmaURL)(fetched += 1);
|
|
526
|
+
figmaFileId,
|
|
527
|
+
spinner.text = `Fetched ${fetched}/${total} image(s)`;
|
|
528
|
+
figmaPageId;
|
|
529
|
+
spinner.render();
|
|
530
|
+
}
|
|
531
|
+
`
|
|
532
|
+
|
|
533
|
+
}, );
|
|
534
|
+
|
|
535
|
+
}); const spinner = ora("Fetching images").start();
|
|
536
|
+
|
|
537
|
+
spinner.stop(); let total = -1;
|
|
538
|
+
|
|
539
|
+
console.log(`;
|
|
540
|
+
$;
|
|
541
|
+
{
|
|
542
|
+
images.length;
|
|
543
|
+
}
|
|
544
|
+
asset(s);
|
|
545
|
+
downloaded `); let fetched = 0;
|
|
546
|
+
|
|
547
|
+
for (const im of images) { const images = await api.images.fetch(figmaFileId, [figmaPageId], {
|
|
548
|
+
|
|
549
|
+
const filename = `;
|
|
550
|
+
$;
|
|
551
|
+
{
|
|
552
|
+
im.name;
|
|
553
|
+
}
|
|
554
|
+
$;
|
|
555
|
+
{
|
|
556
|
+
im.format;
|
|
557
|
+
}
|
|
558
|
+
`; onFetchSources: (sources) => {
|
|
559
|
+
|
|
560
|
+
console.log(`;
|
|
561
|
+
Downloaded;
|
|
562
|
+
$;
|
|
563
|
+
{
|
|
564
|
+
filename;
|
|
565
|
+
}
|
|
566
|
+
`); total = sources.length;
|
|
567
|
+
|
|
568
|
+
const outputFile = path.join(output, filename); spinner.text = `;
|
|
569
|
+
Fetching;
|
|
570
|
+
$;
|
|
571
|
+
{
|
|
572
|
+
total;
|
|
573
|
+
}
|
|
574
|
+
image(s) `;
|
|
575
|
+
|
|
576
|
+
const outputDir = path.dirname(outputFile); spinner.render();
|
|
577
|
+
|
|
578
|
+
await fs.mkdir(outputDir, { recursive: true }); },
|
|
579
|
+
|
|
580
|
+
await fs.writeFile(path.join(output, filename), im.data); onFetchImage: (_url) => {
|
|
581
|
+
|
|
582
|
+
await optimizeImage(outputFile); fetched += 1;
|
|
583
|
+
|
|
584
|
+
} spinner.text = `;
|
|
585
|
+
Fetched;
|
|
586
|
+
$;
|
|
587
|
+
{
|
|
588
|
+
fetched;
|
|
589
|
+
}
|
|
590
|
+
/${total} image(s)`;;
|
|
591
|
+
}
|
|
592
|
+
spinner.render();
|
|
593
|
+
}
|
|
594
|
+
if (args.command === "get") { }
|
|
595
|
+
const { figmaFileId, figmaPageId } = (0, utils_1.parseFigmaURL)(args.url);
|
|
596
|
+
;
|
|
597
|
+
const node = await api.nodes.fetch(figmaFileId, [figmaPageId]);
|
|
598
|
+
spinner.stop();
|
|
599
|
+
console.log(JSON.stringify(node, null, 2));
|
|
600
|
+
console.log(`${images.length} asset(s) downloaded`);
|
|
601
|
+
for (const im of images) {
|
|
602
|
+
}
|
|
603
|
+
const filename = `${im.name}.${im.format}`;
|
|
604
|
+
console.log(`Downloaded ${filename}`);
|
|
605
|
+
const outputFile = path.join(output, filename);
|
|
606
|
+
const outputDir = path.dirname(outputFile);
|
|
607
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
608
|
+
await fs.writeFile(path.join(output, filename), im.data);
|
|
609
|
+
await optimizeImage(outputFile);
|
|
610
|
+
if (args.command === "get") {
|
|
611
|
+
const { figmaFileId, figmaPageId } = (0, utils_1.parseFigmaURL)(args.url);
|
|
612
|
+
const node = await api.nodes.fetch(figmaFileId, [figmaPageId]);
|
|
613
|
+
console.log(JSON.stringify(node, null, 2));
|
|
614
|
+
}
|
|
615
|
+
;
|
|
616
|
+
const optimizeImage = async (filepath) => {
|
|
617
|
+
try {
|
|
618
|
+
const extension = path.extname(filepath).toLowerCase();
|
|
619
|
+
const binaryForExtensions = new Map([
|
|
620
|
+
[".png", "optipng"],
|
|
621
|
+
[".jpg", "jpegoptim"],
|
|
622
|
+
]);
|
|
623
|
+
const binaryName = binaryForExtensions.get(extension);
|
|
624
|
+
if (!binaryName) {
|
|
625
|
+
// console.log(`No optimizer found for ${extension}, skipping optimization`);
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
const binaryPath = (0, child_process_1.execSync)(`which ${binaryName}`).toString().trim();
|
|
629
|
+
if (!binaryPath) {
|
|
630
|
+
throw new Error(`Cannot find ${binaryName} in PATH. Please install it.`);
|
|
631
|
+
}
|
|
632
|
+
console.log(`Optimizing with ${filepath} with ${binaryName}`);
|
|
633
|
+
await (0, child_process_1.execSync)(`${binaryPath} "${filepath}"`);
|
|
634
|
+
console.log(`Image optimized successfully: ${filepath}`);
|
|
635
|
+
}
|
|
636
|
+
catch (error) {
|
|
637
|
+
console.error(`Error optimizing image ${filepath}: ${error instanceof Error ? error.message : error}`);
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
const main = async () => {
|
|
641
|
+
const parser = new argparse_1.ArgumentParser({
|
|
642
|
+
description: "Download assets from Figma",
|
|
643
|
+
});
|
|
644
|
+
configParser(parser);
|
|
645
|
+
await (0, exports.run)(parser);
|
|
646
|
+
};
|
|
647
|
+
// Only run main if this file is being executed directly
|
|
648
|
+
if (require.main === module) {
|
|
649
|
+
main().catch((err) => {
|
|
650
|
+
console.error(err);
|
|
651
|
+
process.exit(1);
|
|
652
|
+
});
|
|
653
|
+
}
|