@charcoal-ui/icons-cli 5.0.0-beta.2 → 5.0.0-beta.4

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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
2
+ //#region rolldown:runtime
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -7,696 +7,568 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
9
  var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
16
18
  };
17
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
- // If the importer is in node compatibility mode or this is not an ESM
19
- // file that has been converted to a CommonJS file using a Babel-
20
- // compatible transform (i.e. "__esModule" has not been set), then set
21
- // "default" to the CommonJS "module.exports" for node compatibility.
22
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
- mod
24
- ));
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
25
23
 
26
- // src/index.ts
27
- var import_yargs = __toESM(require("yargs"));
24
+ //#endregion
25
+ let yargs = require("yargs");
26
+ yargs = __toESM(yargs);
27
+ let path = require("path");
28
+ path = __toESM(path);
29
+ let camelcase = require("camelcase");
30
+ camelcase = __toESM(camelcase);
31
+ let figma_js = require("figma-js");
32
+ figma_js = __toESM(figma_js);
33
+ let fs_extra = require("fs-extra");
34
+ fs_extra = __toESM(fs_extra);
35
+ let got = require("got");
36
+ got = __toESM(got);
37
+ let path_to_regexp = require("path-to-regexp");
38
+ path_to_regexp = __toESM(path_to_regexp);
39
+ let p_queue = require("p-queue");
40
+ p_queue = __toESM(p_queue);
41
+ let __octokit_rest = require("@octokit/rest");
42
+ __octokit_rest = __toESM(__octokit_rest);
43
+ let fs = require("fs");
44
+ fs = __toESM(fs);
45
+ let child_process = require("child_process");
46
+ child_process = __toESM(child_process);
47
+ let __gitbeaker_node = require("@gitbeaker/node");
48
+ __gitbeaker_node = __toESM(__gitbeaker_node);
49
+ let jsdom = require("jsdom");
50
+ jsdom = __toESM(jsdom);
51
+ let polished = require("polished");
52
+ polished = __toESM(polished);
53
+ let svgo = require("svgo");
54
+ svgo = __toESM(svgo);
55
+ let fast_glob = require("fast-glob");
56
+ fast_glob = __toESM(fast_glob);
28
57
 
29
- // src/figma/FigmaFileClient.ts
30
- var import_path = __toESM(require("path"));
31
- var import_camelcase = __toESM(require("camelcase"));
32
- var Figma = __toESM(require("figma-js"));
33
- var import_fs_extra = require("fs-extra");
34
- var import_got = __toESM(require("got"));
35
- var import_path_to_regexp = require("path-to-regexp");
36
-
37
- // src/concurrently.ts
38
- var import_p_queue = __toESM(require("p-queue"));
58
+ //#region src/concurrently.ts
39
59
  function concurrently(tasks) {
40
- const queue = new import_p_queue.default({ concurrency: 3 });
41
- for (const task of tasks) {
42
- void queue.add(task);
43
- }
44
- queue.start();
45
- return queue.onIdle();
60
+ const queue = new p_queue.default({ concurrency: 3 });
61
+ for (const task of tasks) queue.add(task);
62
+ queue.start();
63
+ return queue.onIdle();
46
64
  }
47
65
 
48
- // src/figma/FigmaFileClient.ts
49
- var DRY_RUN = Boolean(process.env.DRY_RUN);
50
- var matchPath = (0, import_path_to_regexp.match)("/file/:fileId/:name");
66
+ //#endregion
67
+ //#region src/figma/FigmaFileClient.ts
68
+ const DRY_RUN = Boolean(process.env.DRY_RUN);
69
+ const matchPath = (0, path_to_regexp.match)("/file/:fileId/:name");
51
70
  function extractParams(url) {
52
- const { pathname, searchParams } = new URL(url);
53
- const result = matchPath(pathname);
54
- if (result === false) {
55
- throw new Error("No fileId found in url");
56
- }
57
- return {
58
- fileId: result.params.fileId,
59
- nodeId: searchParams.get("node-id") ?? void 0
60
- };
71
+ const { pathname, searchParams } = new URL(url);
72
+ const result = matchPath(pathname);
73
+ if (result === false) throw new Error("No fileId found in url");
74
+ return {
75
+ fileId: result.params.fileId,
76
+ nodeId: searchParams.get("node-id") ?? void 0
77
+ };
61
78
  }
62
79
  function filenamify(name) {
63
- return (0, import_camelcase.default)(name, { pascalCase: true }).replace(" ", "");
80
+ return (0, camelcase.default)(name, { pascalCase: true }).replace(" ", "");
64
81
  }
65
- var iconName = /^(?:\d+|Inline)\s*\//u;
82
+ const iconName = /^(?:\d+|Inline)\s*\//u;
66
83
  function isIconNode(node) {
67
- return iconName.test(node.name);
84
+ return iconName.test(node.name);
68
85
  }
69
86
  function parseV2IconName(name) {
70
- return name.split(",").map((f) => f.split("=").map((s) => s.trim())[1]).join("/").toLowerCase();
87
+ return name.split(",").map((f) => f.split("=").map((s) => s.trim())[1]).join("/").toLowerCase();
71
88
  }
72
89
  var FigmaFileClient = class {
73
- fileId;
74
- nodeId;
75
- exportFormat;
76
- client;
77
- layoutVersion;
78
- components = {};
79
- static async runFromCli(url, token, outputRootDir, exportFormat, layoutVersion = "v1") {
80
- const client = new this(url, token, exportFormat, layoutVersion);
81
- const outputDir = import_path.default.join(process.cwd(), outputRootDir, exportFormat);
82
- console.log(
83
- `Exporting components from ${url} using layout ${layoutVersion}`
84
- );
85
- await client.loadSvg(outputDir);
86
- console.log("success!");
87
- }
88
- constructor(url, personalAccessToken, exportFormat, layoutVersion) {
89
- this.client = Figma.Client({
90
- personalAccessToken
91
- });
92
- const { fileId, nodeId } = extractParams(url);
93
- this.fileId = fileId;
94
- this.nodeId = nodeId;
95
- this.exportFormat = exportFormat;
96
- this.layoutVersion = layoutVersion;
97
- }
98
- async loadSvg(outputDir) {
99
- await (0, import_fs_extra.remove)(outputDir);
100
- await (0, import_fs_extra.ensureDir)(outputDir);
101
- await this.loadComponents();
102
- await this.loadImageUrls();
103
- await this.downloadImages(outputDir);
104
- }
105
- async loadComponents() {
106
- const { document } = await this.getFile();
107
- if (this.layoutVersion === "v2") {
108
- this.findComponentsV2(document);
109
- } else {
110
- const targets = this.nodeId !== void 0 ? document.children.filter((node) => node.id === this.nodeId) : document.children;
111
- targets.forEach((child) => this.findComponentsRecursively(child));
112
- }
113
- const len = Object.keys(this.components).length;
114
- if (len === 0) {
115
- throw new Error("No components found!");
116
- } else {
117
- console.log(`found ${len} icons`);
118
- }
119
- }
120
- async loadImageUrls() {
121
- console.log("Getting export urls");
122
- const { data } = await this.client.fileImages(this.fileId, {
123
- format: this.exportFormat,
124
- ids: Object.keys(this.components),
125
- scale: 1,
126
- ...this.exportFormat == "pdf" ? { use_absolute_bounds: true } : {}
127
- });
128
- for (const [id, image] of Object.entries(data.images)) {
129
- this.components[id].image = image;
130
- }
131
- }
132
- async downloadImages(outputDir) {
133
- return concurrently(
134
- Object.values(this.components).map((component) => async () => {
135
- if (component.image === void 0) {
136
- return;
137
- }
138
- const filename = component.variant ? `${parseV2IconName(component.variant)}/${component.name}.${this.exportFormat}` : `${filenamify(component.name)}.${this.exportFormat}`;
139
- const fullname = import_path.default.join(outputDir, filename);
140
- const dirname = import_path.default.dirname(fullname);
141
- if (DRY_RUN) {
142
- console.log(`[DRY_RUN] skip: ${filename} => \u2705 writing...`);
143
- return;
144
- }
145
- const response = await import_got.default.get(
146
- component.image,
147
- this.exportFormat == "pdf" ? { responseType: "buffer" } : {}
148
- );
149
- await (0, import_fs_extra.ensureDir)(dirname);
150
- console.log(`found: ${filename} => \u2705 writing...`);
151
- await (0, import_fs_extra.writeFile)(fullname, response.body, "utf8");
152
- })
153
- );
154
- }
155
- async getFile() {
156
- console.log("Processing response");
157
- const { data } = await this.client.file(this.fileId.toString());
158
- return data;
159
- }
160
- findComponentsRecursively(child) {
161
- if (child.type === "COMPONENT") {
162
- const { name, id } = child;
163
- if (isIconNode(child)) {
164
- this.components[id] = {
165
- name,
166
- id
167
- };
168
- }
169
- } else if ("children" in child) {
170
- child.children.forEach(
171
- (grandChild) => this.findComponentsRecursively(grandChild)
172
- );
173
- }
174
- }
175
- findComponentsV2(document) {
176
- const iconsPage = document.children.find(
177
- (child) => child.name === "Icons \u4E00\u89A7" && child.type === "CANVAS"
178
- );
179
- const iconComponentSets = iconsPage == null ? void 0 : iconsPage.children.flatMap((c) => {
180
- if (c.type !== "FRAME")
181
- return [];
182
- return c.children.filter(
183
- (c2) => c2.type === "COMPONENT_SET"
184
- );
185
- });
186
- iconComponentSets == null ? void 0 : iconComponentSets.forEach((set) => {
187
- set.children.forEach((i) => {
188
- if (i.type !== "COMPONENT")
189
- return null;
190
- this.components[i.id] = {
191
- name: set.name,
192
- variant: i.name,
193
- id: i.id
194
- };
195
- });
196
- });
197
- }
90
+ fileId;
91
+ nodeId;
92
+ exportFormat;
93
+ client;
94
+ layoutVersion;
95
+ components = {};
96
+ static async runFromCli(url, token, outputRootDir, exportFormat, layoutVersion = "v1") {
97
+ const client = new this(url, token, exportFormat, layoutVersion);
98
+ const outputDir = path.default.join(process.cwd(), outputRootDir, exportFormat);
99
+ console.log(`Exporting components from ${url} using layout ${layoutVersion}`);
100
+ await client.loadSvg(outputDir);
101
+ console.log("success!");
102
+ }
103
+ constructor(url, personalAccessToken, exportFormat, layoutVersion) {
104
+ this.client = figma_js.Client({ personalAccessToken });
105
+ const { fileId, nodeId } = extractParams(url);
106
+ this.fileId = fileId;
107
+ this.nodeId = nodeId;
108
+ this.exportFormat = exportFormat;
109
+ this.layoutVersion = layoutVersion;
110
+ }
111
+ async loadSvg(outputDir) {
112
+ await (0, fs_extra.remove)(outputDir);
113
+ await (0, fs_extra.ensureDir)(outputDir);
114
+ await this.loadComponents();
115
+ await this.loadImageUrls();
116
+ await this.downloadImages(outputDir);
117
+ }
118
+ async loadComponents() {
119
+ const { document } = await this.getFile();
120
+ if (this.layoutVersion === "v2") this.findComponentsV2(document);
121
+ else (this.nodeId !== void 0 ? document.children.filter((node) => node.id === this.nodeId) : document.children).forEach((child) => this.findComponentsRecursively(child));
122
+ const len = Object.keys(this.components).length;
123
+ if (len === 0) throw new Error("No components found!");
124
+ else console.log(`found ${len} icons`);
125
+ }
126
+ async loadImageUrls() {
127
+ console.log("Getting export urls");
128
+ const { data } = await this.client.fileImages(this.fileId, {
129
+ format: this.exportFormat,
130
+ ids: Object.keys(this.components),
131
+ scale: 1,
132
+ ...this.exportFormat == "pdf" ? { use_absolute_bounds: true } : {}
133
+ });
134
+ for (const [id, image] of Object.entries(data.images)) this.components[id].image = image;
135
+ }
136
+ async downloadImages(outputDir) {
137
+ return concurrently(Object.values(this.components).map((component) => async () => {
138
+ if (component.image === void 0) return;
139
+ const filename = component.variant ? `${parseV2IconName(component.variant)}/${component.name}.${this.exportFormat}` : `${filenamify(component.name)}.${this.exportFormat}`;
140
+ const fullname = path.default.join(outputDir, filename);
141
+ const dirname = path.default.dirname(fullname);
142
+ if (DRY_RUN) {
143
+ console.log(`[DRY_RUN] skip: ${filename} => writing...`);
144
+ return;
145
+ }
146
+ const response = await got.default.get(component.image, this.exportFormat == "pdf" ? { responseType: "buffer" } : {});
147
+ await (0, fs_extra.ensureDir)(dirname);
148
+ console.log(`found: ${filename} => ✅ writing...`);
149
+ await (0, fs_extra.writeFile)(fullname, response.body, "utf8");
150
+ }));
151
+ }
152
+ async getFile() {
153
+ console.log("Processing response");
154
+ const { data } = await this.client.file(this.fileId.toString());
155
+ return data;
156
+ }
157
+ findComponentsRecursively(child) {
158
+ if (child.type === "COMPONENT") {
159
+ const { name, id } = child;
160
+ if (isIconNode(child)) this.components[id] = {
161
+ name,
162
+ id
163
+ };
164
+ } else if ("children" in child) child.children.forEach((grandChild) => this.findComponentsRecursively(grandChild));
165
+ }
166
+ findComponentsV2(document) {
167
+ (document.children.find((child) => child.name === "Icons 一覧" && child.type === "CANVAS")?.children.flatMap((c) => {
168
+ if (c.type !== "FRAME") return [];
169
+ return c.children.filter((c$1) => c$1.type === "COMPONENT_SET");
170
+ }))?.forEach((set) => {
171
+ set.children.forEach((i) => {
172
+ if (i.type !== "COMPONENT") return null;
173
+ this.components[i.id] = {
174
+ name: set.name,
175
+ variant: i.name,
176
+ id: i.id
177
+ };
178
+ });
179
+ });
180
+ }
198
181
  };
199
182
 
200
- // src/GitHubClient.ts
201
- var import_rest = require("@octokit/rest");
202
- var import_path3 = __toESM(require("path"));
203
-
204
- // src/getChangedFiles.ts
205
- var import_fs = require("fs");
206
- var import_path2 = __toESM(require("path"));
207
-
208
- // src/utils.ts
209
- var import_child_process = require("child_process");
210
- var execp = (command) => new Promise((resolve, reject) => {
211
- (0, import_child_process.exec)(command, (err, stdout) => {
212
- if (err) {
213
- return reject(err);
214
- }
215
- return resolve(stdout);
216
- });
183
+ //#endregion
184
+ //#region src/utils.ts
185
+ /**
186
+ * FIXME: util.promisify を使うと node-libs-browser に入っている方が使われてしまい、壊れる
187
+ */
188
+ const execp = (command) => new Promise((resolve, reject) => {
189
+ (0, child_process.exec)(command, (err, stdout) => {
190
+ if (err) return reject(err);
191
+ return resolve(stdout);
192
+ });
217
193
  });
218
194
  function mustBeDefined(value, name) {
219
- if (typeof value === "undefined") {
220
- throw new TypeError(`${name} must be defined.`);
221
- }
195
+ if (typeof value === "undefined") throw new TypeError(`${name} must be defined.`);
222
196
  }
223
197
 
224
- // src/getChangedFiles.ts
198
+ //#endregion
199
+ //#region src/getChangedFiles.ts
200
+ /**
201
+ * dir 内で変更があったファイル情報を for await で回せるようにするやつ
202
+ */
225
203
  async function* getChangedFiles(dir) {
226
- if (!(0, import_fs.existsSync)(dir))
227
- throw new Error(`icons-cli: target directory not found (${dir})`);
228
- const gitStatus = await collectGitStatus();
229
- for (const [relativePath, status] of gitStatus) {
230
- const fullpath = import_path2.default.resolve(process.cwd(), "../../", relativePath);
231
- if (!fullpath.startsWith(`${dir}/`)) {
232
- continue;
233
- }
234
- if (!(0, import_fs.existsSync)(fullpath))
235
- throw new Error(`icons-cli: could not load svg (${fullpath})`);
236
- const content = await import_fs.promises.readFile(fullpath, { encoding: "utf-8" });
237
- yield { relativePath, content, status };
238
- }
204
+ if (!(0, fs.existsSync)(dir)) throw new Error(`icons-cli: target directory not found (${dir})`);
205
+ const gitStatus = await collectGitStatus();
206
+ for (const [relativePath, status] of gitStatus) {
207
+ const fullpath = path.default.resolve(process.cwd(), "../../", relativePath);
208
+ if (!fullpath.startsWith(`${dir}/`)) continue;
209
+ if (!(0, fs.existsSync)(fullpath)) throw new Error(`icons-cli: could not load svg (${fullpath})`);
210
+ yield {
211
+ relativePath,
212
+ content: await fs.promises.readFile(fullpath, { encoding: "utf-8" }),
213
+ status
214
+ };
215
+ }
239
216
  }
240
217
  async function collectGitStatus() {
241
- return new Map(
242
- /**
243
- * @see https://git-scm.com/docs/git-status#_porcelain_format_version_1
244
- */
245
- (await execp(`git status --porcelain`)).split("\n").map((s) => {
246
- return [
247
- s.slice(3),
248
- s.startsWith(" M") ? "modified" : s.startsWith("??") ? "untracked" : s.startsWith(" D") ? "deleted" : null
249
- ];
250
- })
251
- );
218
+ return new Map(
219
+ /**
220
+ * @see https://git-scm.com/docs/git-status#_porcelain_format_version_1
221
+ */
222
+ (await execp(`git status --porcelain`)).split("\n").map((s) => {
223
+ return [s.slice(3), s.startsWith(" M") ? "modified" : s.startsWith("??") ? "untracked" : s.startsWith(" D") ? "deleted" : null];
224
+ })
225
+ );
252
226
  }
253
227
 
254
- // src/GitHubClient.ts
228
+ //#endregion
229
+ //#region src/GitHubClient.ts
255
230
  var GithubClient = class {
256
- constructor(repoOwner, repoName, token, defaultBranch, now = /* @__PURE__ */ new Date()) {
257
- this.repoOwner = repoOwner;
258
- this.repoName = repoName;
259
- this.defaultBranch = defaultBranch;
260
- this.api = new import_rest.Octokit({
261
- auth: token
262
- });
263
- this.now = now;
264
- }
265
- api;
266
- now;
267
- static async runFromCli(repoOwner, repoName, token, defaultBranch, outputDir) {
268
- const client = new this(repoOwner, repoName, token, defaultBranch);
269
- const outputDirFullPath = import_path3.default.resolve(process.cwd(), outputDir);
270
- const diff = await client.createTreeFromDiff(outputDirFullPath);
271
- console.log(`${diff.length} files are changed`);
272
- if (diff.length === 0) {
273
- console.log("no changes. aborting");
274
- return;
275
- }
276
- const newBranch = await client.createBranch();
277
- await client.createCommit(diff, newBranch);
278
- return client.createPullRequest(newBranch);
279
- }
280
- get branch() {
281
- return `icons/update/${this.now.getTime()}`;
282
- }
283
- /**
284
- * both used for commit message or pull request title
285
- */
286
- get message() {
287
- return `[icons-cli] Update icons ${this.now.toDateString()}`;
288
- }
289
- async createTreeFromDiff(outputDir) {
290
- const tree = [];
291
- for await (const file of getChangedFiles(outputDir)) {
292
- const item = {
293
- path: file.relativePath,
294
- // 100 はファイル 644 は実行不可なファイルであるという意味
295
- // @see https://octokit.github.io/rest.js/v18#git-create-tree
296
- mode: "100644",
297
- content: file.content
298
- };
299
- if (file.status === "deleted") {
300
- tree.push({
301
- ...item,
302
- sha: null
303
- });
304
- } else {
305
- tree.push(item);
306
- }
307
- }
308
- return tree;
309
- }
310
- async createCommit(tree, targetBranch) {
311
- const parentCommit = await this.api.git.getCommit({
312
- owner: this.repoOwner,
313
- repo: this.repoName,
314
- commit_sha: targetBranch.data.object.sha
315
- });
316
- const newTree = await this.api.git.createTree({
317
- owner: this.repoOwner,
318
- repo: this.repoName,
319
- base_tree: parentCommit.data.tree.sha,
320
- tree
321
- });
322
- const commit = await this.api.git.createCommit({
323
- owner: this.repoOwner,
324
- repo: this.repoName,
325
- message: this.message,
326
- tree: newTree.data.sha,
327
- parents: [parentCommit.data.sha]
328
- });
329
- await this.api.git.updateRef({
330
- owner: this.repoOwner,
331
- repo: this.repoName,
332
- ref: `heads/${this.branch}`,
333
- sha: commit.data.sha
334
- });
335
- return commit;
336
- }
337
- async createPullRequest(targetBranch) {
338
- const defaultBranch = await this.getDefaultBranchRef();
339
- return this.api.pulls.create({
340
- owner: this.repoOwner,
341
- repo: this.repoName,
342
- head: targetBranch.data.ref,
343
- base: defaultBranch.data.ref,
344
- title: this.message,
345
- body: ""
346
- });
347
- }
348
- getDefaultBranchRef() {
349
- return this.api.git.getRef({
350
- owner: this.repoOwner,
351
- repo: this.repoName,
352
- ref: `heads/${this.defaultBranch}`
353
- });
354
- }
355
- async createBranch() {
356
- const defaultBranch = await this.getDefaultBranchRef();
357
- return this.api.git.createRef({
358
- owner: this.repoOwner,
359
- repo: this.repoName,
360
- ref: `refs/heads/${this.branch}`,
361
- sha: defaultBranch.data.object.sha
362
- });
363
- }
231
+ api;
232
+ now;
233
+ static async runFromCli(repoOwner, repoName, token, defaultBranch, outputDir) {
234
+ const client = new this(repoOwner, repoName, token, defaultBranch);
235
+ const outputDirFullPath = path.default.resolve(process.cwd(), outputDir);
236
+ const diff = await client.createTreeFromDiff(outputDirFullPath);
237
+ console.log(`${diff.length} files are changed`);
238
+ if (diff.length === 0) {
239
+ console.log("no changes. aborting");
240
+ return;
241
+ }
242
+ const newBranch = await client.createBranch();
243
+ await client.createCommit(diff, newBranch);
244
+ return client.createPullRequest(newBranch);
245
+ }
246
+ constructor(repoOwner, repoName, token, defaultBranch, now = /* @__PURE__ */ new Date()) {
247
+ this.repoOwner = repoOwner;
248
+ this.repoName = repoName;
249
+ this.defaultBranch = defaultBranch;
250
+ this.api = new __octokit_rest.Octokit({ auth: token });
251
+ this.now = now;
252
+ }
253
+ get branch() {
254
+ return `icons/update/${this.now.getTime()}`;
255
+ }
256
+ /**
257
+ * both used for commit message or pull request title
258
+ */
259
+ get message() {
260
+ return `[icons-cli] Update icons ${this.now.toDateString()}`;
261
+ }
262
+ async createTreeFromDiff(outputDir) {
263
+ const tree = [];
264
+ for await (const file of getChangedFiles(outputDir)) {
265
+ const item = {
266
+ path: file.relativePath,
267
+ mode: "100644",
268
+ content: file.content
269
+ };
270
+ if (file.status === "deleted") tree.push({
271
+ ...item,
272
+ sha: null
273
+ });
274
+ else tree.push(item);
275
+ }
276
+ return tree;
277
+ }
278
+ async createCommit(tree, targetBranch) {
279
+ const parentCommit = await this.api.git.getCommit({
280
+ owner: this.repoOwner,
281
+ repo: this.repoName,
282
+ commit_sha: targetBranch.data.object.sha
283
+ });
284
+ const newTree = await this.api.git.createTree({
285
+ owner: this.repoOwner,
286
+ repo: this.repoName,
287
+ base_tree: parentCommit.data.tree.sha,
288
+ tree
289
+ });
290
+ const commit = await this.api.git.createCommit({
291
+ owner: this.repoOwner,
292
+ repo: this.repoName,
293
+ message: this.message,
294
+ tree: newTree.data.sha,
295
+ parents: [parentCommit.data.sha]
296
+ });
297
+ await this.api.git.updateRef({
298
+ owner: this.repoOwner,
299
+ repo: this.repoName,
300
+ ref: `heads/${this.branch}`,
301
+ sha: commit.data.sha
302
+ });
303
+ return commit;
304
+ }
305
+ async createPullRequest(targetBranch) {
306
+ const defaultBranch = await this.getDefaultBranchRef();
307
+ return this.api.pulls.create({
308
+ owner: this.repoOwner,
309
+ repo: this.repoName,
310
+ head: targetBranch.data.ref,
311
+ base: defaultBranch.data.ref,
312
+ title: this.message,
313
+ body: ""
314
+ });
315
+ }
316
+ getDefaultBranchRef() {
317
+ return this.api.git.getRef({
318
+ owner: this.repoOwner,
319
+ repo: this.repoName,
320
+ ref: `heads/${this.defaultBranch}`
321
+ });
322
+ }
323
+ async createBranch() {
324
+ const defaultBranch = await this.getDefaultBranchRef();
325
+ return this.api.git.createRef({
326
+ owner: this.repoOwner,
327
+ repo: this.repoName,
328
+ ref: `refs/heads/${this.branch}`,
329
+ sha: defaultBranch.data.object.sha
330
+ });
331
+ }
364
332
  };
365
333
 
366
- // src/GitlabClient.ts
367
- var import_node = require("@gitbeaker/node");
368
- var import_path4 = __toESM(require("path"));
334
+ //#endregion
335
+ //#region src/GitlabClient.ts
369
336
  var GitlabClient = class {
370
- constructor(host, projectId, privateToken, defaultBranch, now = /* @__PURE__ */ new Date()) {
371
- this.host = host;
372
- this.projectId = projectId;
373
- this.defaultBranch = defaultBranch;
374
- this.api = new import_node.Gitlab({
375
- host: this.host,
376
- token: privateToken
377
- });
378
- this.now = now;
379
- }
380
- api;
381
- now;
382
- static async runFromCli(host, projectId, privateToken, defaultBranch, outputDir) {
383
- const client = new this(host, projectId, privateToken, defaultBranch);
384
- const outputDirFullPath = import_path4.default.resolve(process.cwd(), outputDir);
385
- const diff = await client.createActionsFromDiff(outputDirFullPath);
386
- console.log(`${diff.length} files are changed`);
387
- if (diff.length === 0) {
388
- console.log("no changes. aborting");
389
- return;
390
- }
391
- await client.createCommit(diff);
392
- return client.createMergeRequest();
393
- }
394
- get branch() {
395
- return `icons/update/${this.now.getTime()}`;
396
- }
397
- /**
398
- * both used for commit message or merge request title
399
- */
400
- get message() {
401
- return `[icons-cli] Update icons ${this.now.toDateString()}`;
402
- }
403
- async createActionsFromDiff(outputDir) {
404
- const actions = [];
405
- for await (const file of getChangedFiles(outputDir)) {
406
- actions.push({
407
- action: file.status === "untracked" ? "create" : file.status === "deleted" ? "delete" : "update",
408
- filePath: file.relativePath,
409
- content: file.content
410
- });
411
- }
412
- return actions;
413
- }
414
- async createCommit(diff) {
415
- return this.api.Commits.create(
416
- this.projectId,
417
- this.branch,
418
- this.message,
419
- diff,
420
- {
421
- start_branch: this.defaultBranch
422
- }
423
- );
424
- }
425
- createMergeRequest() {
426
- return this.api.MergeRequests.create(
427
- this.projectId,
428
- this.branch,
429
- this.defaultBranch,
430
- this.message
431
- );
432
- }
337
+ api;
338
+ now;
339
+ static async runFromCli(host, projectId, privateToken, defaultBranch, outputDir) {
340
+ const client = new this(host, projectId, privateToken, defaultBranch);
341
+ const outputDirFullPath = path.default.resolve(process.cwd(), outputDir);
342
+ const diff = await client.createActionsFromDiff(outputDirFullPath);
343
+ console.log(`${diff.length} files are changed`);
344
+ if (diff.length === 0) {
345
+ console.log("no changes. aborting");
346
+ return;
347
+ }
348
+ await client.createCommit(diff);
349
+ return client.createMergeRequest();
350
+ }
351
+ constructor(host, projectId, privateToken, defaultBranch, now = /* @__PURE__ */ new Date()) {
352
+ this.host = host;
353
+ this.projectId = projectId;
354
+ this.defaultBranch = defaultBranch;
355
+ this.api = new __gitbeaker_node.Gitlab({
356
+ host: this.host,
357
+ token: privateToken
358
+ });
359
+ this.now = now;
360
+ }
361
+ get branch() {
362
+ return `icons/update/${this.now.getTime()}`;
363
+ }
364
+ /**
365
+ * both used for commit message or merge request title
366
+ */
367
+ get message() {
368
+ return `[icons-cli] Update icons ${this.now.toDateString()}`;
369
+ }
370
+ async createActionsFromDiff(outputDir) {
371
+ const actions = [];
372
+ for await (const file of getChangedFiles(outputDir)) actions.push({
373
+ action: file.status === "untracked" ? "create" : file.status === "deleted" ? "delete" : "update",
374
+ filePath: file.relativePath,
375
+ content: file.content
376
+ });
377
+ return actions;
378
+ }
379
+ async createCommit(diff) {
380
+ return this.api.Commits.create(this.projectId, this.branch, this.message, diff, { start_branch: this.defaultBranch });
381
+ }
382
+ createMergeRequest() {
383
+ return this.api.MergeRequests.create(this.projectId, this.branch, this.defaultBranch, this.message);
384
+ }
433
385
  };
434
386
 
435
- // src/svg/optimizeSvg.ts
436
- var import_jsdom = require("jsdom");
437
- var import_polished = require("polished");
438
- var import_svgo = __toESM(require("svgo"));
439
- var DEFAULT_CURRENT_COLOR_TARGET = "#858585";
440
- var svgo = new import_svgo.default({
441
- plugins: [
442
- // NOTICE: SVGO は「svg 内のすべての fill を currentColor に変える」機能しかない
443
- // icons-cli に必要なのは「特定の黒っぽい色だけ currentColor に変える」機能
444
- // なので、convertColors plugin は使わない
445
- // { convertColors: { currentColor: true } },
446
- { removeViewBox: false },
447
- { removeAttrs: { attrs: ["stroke-opacity", "fill-opacity"] } }
448
- ]
449
- });
387
+ //#endregion
388
+ //#region src/svg/optimizeSvg.ts
389
+ const DEFAULT_CURRENT_COLOR_TARGET = "#858585";
390
+ const svgo$1 = new svgo.default({ plugins: [{ removeViewBox: false }, { removeAttrs: { attrs: ["stroke-opacity", "fill-opacity"] } }] });
450
391
  async function optimizeSvg(input, options) {
451
- const { document } = new import_jsdom.JSDOM(input).window;
452
- const svg = document.querySelector("svg");
453
- if (!svg) {
454
- throw new Error("optimizeSvg: input string seems not to have <svg>");
455
- }
456
- addViewboxToRootSvg(svg);
457
- convertToCurrentColor(svg, options.convertedColor);
458
- if (options.withoutOptimizeBySVGO === true) {
459
- return svg.outerHTML;
460
- } else {
461
- return (await svgo.optimize(svg.outerHTML)).data;
462
- }
392
+ const { document } = new jsdom.JSDOM(input).window;
393
+ const svg = document.querySelector("svg");
394
+ if (!svg) throw new Error("optimizeSvg: input string seems not to have <svg>");
395
+ addViewboxToRootSvg(svg);
396
+ convertToCurrentColor(svg, options.convertedColor);
397
+ if (options.withoutOptimizeBySVGO === true) return svg.outerHTML;
398
+ else return (await svgo$1.optimize(svg.outerHTML)).data;
463
399
  }
464
- var TARGET_ATTRS = ["fill", "stroke"];
400
+ const TARGET_ATTRS = ["fill", "stroke"];
465
401
  function convertToCurrentColor(svg, convertedColor) {
466
- const targetColor = parseColor(convertedColor);
467
- if (!targetColor) {
468
- throw new Error(`${convertedColor} is not a valid color`);
469
- }
470
- for (const attr of TARGET_ATTRS) {
471
- const targets = Array.from(svg.querySelectorAll(`[${attr}]`));
472
- for (const el of targets) {
473
- const value = parseColor(el.getAttribute(attr));
474
- if (!value) {
475
- continue;
476
- }
477
- if (!colorEquals(value, targetColor)) {
478
- continue;
479
- }
480
- el.setAttribute(attr, "currentColor");
481
- }
482
- }
402
+ const targetColor = parseColor(convertedColor);
403
+ if (!targetColor) throw new Error(`${convertedColor} is not a valid color`);
404
+ for (const attr of TARGET_ATTRS) {
405
+ const targets = Array.from(svg.querySelectorAll(`[${attr}]`));
406
+ for (const el of targets) {
407
+ const value = parseColor(el.getAttribute(attr));
408
+ if (!value) continue;
409
+ if (!colorEquals(value, targetColor)) continue;
410
+ el.setAttribute(attr, "currentColor");
411
+ }
412
+ }
483
413
  }
484
414
  function parseColor(value) {
485
- if (value == null) {
486
- return null;
487
- }
488
- try {
489
- return (0, import_polished.parseToRgb)(value);
490
- } catch {
491
- return null;
492
- }
415
+ if (value == null) return null;
416
+ try {
417
+ return (0, polished.parseToRgb)(value);
418
+ } catch {
419
+ return null;
420
+ }
493
421
  }
494
422
  function colorEquals(self, other) {
495
- if (self.red !== other.red) {
496
- return false;
497
- }
498
- if (self.blue !== other.blue) {
499
- return false;
500
- }
501
- if (self.green !== other.green) {
502
- return false;
503
- }
504
- if ("alpha" in self) {
505
- if ("alpha" in other) {
506
- if (self.alpha !== other.alpha) {
507
- return false;
508
- }
509
- }
510
- }
511
- return true;
423
+ if (self.red !== other.red) return false;
424
+ if (self.blue !== other.blue) return false;
425
+ if (self.green !== other.green) return false;
426
+ if ("alpha" in self) {
427
+ if ("alpha" in other) {
428
+ if (self.alpha !== other.alpha) return false;
429
+ }
430
+ }
431
+ return true;
512
432
  }
513
433
  function addViewboxToRootSvg(svg) {
514
- const width = svg.getAttribute("width");
515
- const height = svg.getAttribute("height");
516
- svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
434
+ const width = svg.getAttribute("width");
435
+ const height = svg.getAttribute("height");
436
+ svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
517
437
  }
518
438
 
519
- // src/svg/optimizeSvgInDirectory.ts
520
- var import_path5 = __toESM(require("path"));
521
- var import_fast_glob = __toESM(require("fast-glob"));
522
- var import_fs_extra2 = __toESM(require("fs-extra"));
523
- var optimizeSvgInDirectory = async (outputDir, replaceColor, ignoreFile) => {
524
- const rootDir = import_path5.default.join(outputDir, "svg");
525
- const ignorePatterns = ignoreFile !== void 0 ? (await import_fs_extra2.default.readFile(ignoreFile, "utf8")).trim().split(/\r?\n/u) : [];
526
- const files = await (0, import_fast_glob.default)("**/*.svg", {
527
- cwd: rootDir
528
- });
529
- await concurrently(
530
- files.map((file) => async () => {
531
- console.log(`Optimizing ${file}...`);
532
- const fullPath = import_path5.default.join(rootDir, file);
533
- const originalSvg = await import_fs_extra2.default.readFile(fullPath, "utf8");
534
- const optimizedSvg = await optimizeSvg(originalSvg, {
535
- convertedColor: replaceColor,
536
- withoutOptimizeBySVGO: ignorePatterns.includes(file)
537
- });
538
- await import_fs_extra2.default.writeFile(fullPath, optimizedSvg);
539
- })
540
- );
439
+ //#endregion
440
+ //#region src/svg/optimizeSvgInDirectory.ts
441
+ const optimizeSvgInDirectory = async (outputDir, replaceColor, ignoreFile) => {
442
+ const rootDir = path.default.join(outputDir, "svg");
443
+ const ignorePatterns = ignoreFile !== void 0 ? (await fs_extra.default.readFile(ignoreFile, "utf8")).trim().split(/\r?\n/u) : [];
444
+ await concurrently((await (0, fast_glob.default)("**/*.svg", { cwd: rootDir })).map((file) => async () => {
445
+ console.log(`Optimizing ${file}...`);
446
+ const fullPath = path.default.join(rootDir, file);
447
+ const optimizedSvg = await optimizeSvg(await fs_extra.default.readFile(fullPath, "utf8"), {
448
+ convertedColor: replaceColor,
449
+ withoutOptimizeBySVGO: ignorePatterns.includes(file)
450
+ });
451
+ await fs_extra.default.writeFile(fullPath, optimizedSvg);
452
+ }));
541
453
  };
542
454
 
543
- // src/generateSource.ts
544
- var import_path6 = __toESM(require("path"));
545
- var import_fast_glob2 = __toESM(require("fast-glob"));
546
- var import_fs_extra3 = __toESM(require("fs-extra"));
547
- var generateIconSvgEmbeddedSource = (svgString) => {
548
- const str = svgString.replace(/\r?\n/g, "");
549
- return `/** This file is auto generated. DO NOT EDIT BY HAND. */
550
- export default '${str}'
455
+ //#endregion
456
+ //#region src/generateSource.ts
457
+ const generateIconSvgEmbeddedSource = (svgString) => {
458
+ return `/** This file is auto generated. DO NOT EDIT BY HAND. */
459
+ export default '${svgString.replace(/\r?\n/g, "")}'
551
460
  `;
552
461
  };
553
- var generateMjsEntrypoint = (icons) => `/** This file is auto generated. DO NOT EDIT BY HAND. */
462
+ const generateMjsEntrypoint = (icons) => `/** This file is auto generated. DO NOT EDIT BY HAND. */
554
463
 
555
464
  export default {
556
465
  ${icons.map((it) => ` '${it}': () => import('./${it}.js').then(m => m.default)`).join(",\n")}
557
466
  }
558
467
  `;
559
- var generateCjsEntrypoint = (icons) => `/** This file is auto generated. DO NOT EDIT BY HAND. */
468
+ const generateCjsEntrypoint = (icons) => `/** This file is auto generated. DO NOT EDIT BY HAND. */
560
469
 
561
470
  module.exports = {
562
471
  ${icons.map((it) => ` '${it}': () => import('./${it}.js').then(m => m.default)`).join(",\n")}
563
472
  }
564
473
  `;
565
- var generateTypeDefinitionEntrypoint = (icons) => `/** This file is auto generated. DO NOt EDIT BY HAND. */
474
+ const generateTypeDefinitionEntrypoint = (icons) => `/** This file is auto generated. DO NOt EDIT BY HAND. */
566
475
 
567
476
  declare var _default: {
568
477
  ${icons.map((it) => ` '${it}': () => Promise<string>`).join(";\n")}
569
478
  };
570
479
  export default _default;
571
480
  `;
572
- var generateEntrypoint = async (outputDir, icons) => {
573
- const srcRoot = import_path6.default.join(outputDir, "src");
574
- const mjsPath = import_path6.default.join(srcRoot, "index.js");
575
- await import_fs_extra3.default.ensureFile(mjsPath);
576
- await import_fs_extra3.default.writeFile(mjsPath, generateMjsEntrypoint(icons));
577
- const cjsPath = import_path6.default.join(srcRoot, "index.cjs");
578
- await import_fs_extra3.default.ensureFile(cjsPath);
579
- await import_fs_extra3.default.writeFile(cjsPath, generateCjsEntrypoint(icons));
580
- const dtsPath = import_path6.default.join(srcRoot, "index.d.ts");
581
- await import_fs_extra3.default.ensureFile(dtsPath);
582
- await import_fs_extra3.default.writeFile(dtsPath, generateTypeDefinitionEntrypoint(icons));
481
+ const generateEntrypoint = async (outputDir, icons) => {
482
+ const srcRoot = path.default.join(outputDir, "src");
483
+ const mjsPath = path.default.join(srcRoot, "index.js");
484
+ await fs_extra.default.ensureFile(mjsPath);
485
+ await fs_extra.default.writeFile(mjsPath, generateMjsEntrypoint(icons));
486
+ const cjsPath = path.default.join(srcRoot, "index.cjs");
487
+ await fs_extra.default.ensureFile(cjsPath);
488
+ await fs_extra.default.writeFile(cjsPath, generateCjsEntrypoint(icons));
489
+ const dtsPath = path.default.join(srcRoot, "index.d.ts");
490
+ await fs_extra.default.ensureFile(dtsPath);
491
+ await fs_extra.default.writeFile(dtsPath, generateTypeDefinitionEntrypoint(icons));
583
492
  };
584
- var generateIconSource = async (outputDir) => {
585
- const svgRoot = import_path6.default.join(outputDir, "svg");
586
- const srcRoot = import_path6.default.join(outputDir, "src");
587
- const icons = (await (0, import_fast_glob2.default)("**/*.svg", { cwd: svgRoot })).map(
588
- (path7) => path7.slice(0, -4)
589
- // e.g. '16/Add.svg' -> '16/Add'
590
- ).sort();
591
- for (const it of icons) {
592
- const data = await import_fs_extra3.default.readFile(import_path6.default.join(svgRoot, `${it}.svg`));
593
- const outputPath = import_path6.default.join(srcRoot, `${it}.js`);
594
- await import_fs_extra3.default.ensureFile(outputPath);
595
- await import_fs_extra3.default.writeFile(
596
- outputPath,
597
- generateIconSvgEmbeddedSource(data.toString())
598
- );
599
- }
600
- await generateEntrypoint(outputDir, icons);
493
+ const generateIconSource = async (outputDir) => {
494
+ const svgRoot = path.default.join(outputDir, "svg");
495
+ const srcRoot = path.default.join(outputDir, "src");
496
+ const icons = (await (0, fast_glob.default)("**/*.svg", { cwd: svgRoot })).map((path$7) => path$7.slice(0, -4)).sort();
497
+ for (const it of icons) {
498
+ const data = await fs_extra.default.readFile(path.default.join(svgRoot, `${it}.svg`));
499
+ const outputPath = path.default.join(srcRoot, `${it}.js`);
500
+ await fs_extra.default.ensureFile(outputPath);
501
+ await fs_extra.default.writeFile(outputPath, generateIconSvgEmbeddedSource(data.toString()));
502
+ }
503
+ await generateEntrypoint(outputDir, icons);
601
504
  };
602
505
 
603
- // src/index.ts
604
- var FIGMA_TOKEN = process.env.FIGMA_TOKEN;
605
- var FIGMA_FILE_URL = process.env.FIGMA_FILE_URL;
606
- var OUTPUT_ROOT_DIR = process.env.OUTPUT_ROOT_DIR;
607
- var GITLAB_ACCESS_TOKEN = process.env.GITLAB_ACCESS_TOKEN;
608
- var GITLAB_DEFAULT_BRANCH = process.env.GITLAB_DEFAULT_BRANCH;
609
- var GITLAB_HOST = process.env.GITLAB_HOST;
610
- var GITLAB_PROJECT_ID = process.env.GITLAB_PROJECT_ID;
611
- var GITHUB_ACCESS_TOKEN = process.env.GITHUB_ACCESS_TOKEN;
612
- var GITHUB_REPO_OWNER = process.env.GITHUB_REPO_OWNER;
613
- var GITHUB_REPO_NAME = process.env.GITHUB_REPO_NAME;
614
- var GITHUB_DEFAULT_BRANCH = process.env.GITHUB_DEFAULT_BRANCH;
615
- void import_yargs.default.scriptName("icons-cli").command(
616
- "figma:export",
617
- "Load all icons from Figma and save to files",
618
- {
619
- format: {
620
- default: "svg",
621
- choices: ["svg", "pdf"],
622
- describe: "Output format"
623
- },
624
- layout: {
625
- default: "v1",
626
- describe: "Figma icon file layout version"
627
- }
628
- },
629
- async ({ format, layout }) => {
630
- mustBeDefined(FIGMA_FILE_URL, "FIGMA_FILE_URL");
631
- mustBeDefined(FIGMA_TOKEN, "FIGMA_TOKEN");
632
- mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
633
- await FigmaFileClient.runFromCli(
634
- FIGMA_FILE_URL,
635
- FIGMA_TOKEN,
636
- OUTPUT_ROOT_DIR,
637
- format,
638
- layout
639
- );
640
- }
641
- ).command(
642
- "svg:optimize",
643
- "Optimize svg files in output directory",
644
- {
645
- color: {
646
- default: DEFAULT_CURRENT_COLOR_TARGET,
647
- type: "string",
648
- describe: "Color code that should be converted into `currentColor`"
649
- },
650
- ignoreFile: {
651
- type: "string",
652
- describe: "A file that contains the list of path to SVG files that should not be optimized"
653
- }
654
- },
655
- async ({ color, ignoreFile }) => {
656
- mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
657
- await optimizeSvgInDirectory(OUTPUT_ROOT_DIR, color, ignoreFile);
658
- }
659
- ).command(
660
- "files:generate",
661
- "Enumerate svg files in output directory and generate icon files",
662
- {},
663
- () => {
664
- mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
665
- void generateIconSource(OUTPUT_ROOT_DIR).catch((e) => {
666
- console.error(e);
667
- process.exit(1);
668
- });
669
- }
670
- ).command(
671
- "gitlab:mr",
672
- "Create a merge request in the name of icons-cli",
673
- {},
674
- async () => {
675
- mustBeDefined(GITLAB_PROJECT_ID, "GITLAB_PROJECT_ID");
676
- mustBeDefined(GITLAB_ACCESS_TOKEN, "GITLAB_ACCESS_TOKEN");
677
- mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
678
- await GitlabClient.runFromCli(
679
- GITLAB_HOST ?? "https://gitlab.com",
680
- Number(GITLAB_PROJECT_ID),
681
- GITLAB_ACCESS_TOKEN,
682
- GITLAB_DEFAULT_BRANCH ?? "main",
683
- OUTPUT_ROOT_DIR
684
- );
685
- }
686
- ).command(
687
- "github:pr",
688
- "Create a pull request in the name of icons-cli",
689
- {},
690
- async () => {
691
- mustBeDefined(GITHUB_ACCESS_TOKEN, "GITHUB_ACCESS_TOKEN");
692
- mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
693
- await GithubClient.runFromCli(
694
- GITHUB_REPO_OWNER ?? "pixiv",
695
- GITHUB_REPO_NAME ?? "charcoal",
696
- GITHUB_ACCESS_TOKEN,
697
- GITHUB_DEFAULT_BRANCH ?? "main",
698
- OUTPUT_ROOT_DIR
699
- );
700
- }
701
- ).demandCommand().strict().help().parse();
506
+ //#endregion
507
+ //#region src/index.ts
508
+ /**
509
+ * Figma
510
+ */
511
+ const FIGMA_TOKEN = process.env.FIGMA_TOKEN;
512
+ const FIGMA_FILE_URL = process.env.FIGMA_FILE_URL;
513
+ const OUTPUT_ROOT_DIR = process.env.OUTPUT_ROOT_DIR;
514
+ /**
515
+ * GitLab
516
+ */
517
+ const GITLAB_ACCESS_TOKEN = process.env.GITLAB_ACCESS_TOKEN;
518
+ const GITLAB_DEFAULT_BRANCH = process.env.GITLAB_DEFAULT_BRANCH;
519
+ const GITLAB_HOST = process.env.GITLAB_HOST;
520
+ const GITLAB_PROJECT_ID = process.env.GITLAB_PROJECT_ID;
521
+ /**
522
+ * GitHub
523
+ */
524
+ const GITHUB_ACCESS_TOKEN = process.env.GITHUB_ACCESS_TOKEN;
525
+ const GITHUB_REPO_OWNER = process.env.GITHUB_REPO_OWNER;
526
+ const GITHUB_REPO_NAME = process.env.GITHUB_REPO_NAME;
527
+ const GITHUB_DEFAULT_BRANCH = process.env.GITHUB_DEFAULT_BRANCH;
528
+ yargs.default.scriptName("icons-cli").command("figma:export", "Load all icons from Figma and save to files", {
529
+ format: {
530
+ default: "svg",
531
+ choices: ["svg", "pdf"],
532
+ describe: "Output format"
533
+ },
534
+ layout: {
535
+ default: "v1",
536
+ describe: "Figma icon file layout version"
537
+ }
538
+ }, async ({ format, layout }) => {
539
+ mustBeDefined(FIGMA_FILE_URL, "FIGMA_FILE_URL");
540
+ mustBeDefined(FIGMA_TOKEN, "FIGMA_TOKEN");
541
+ mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
542
+ await FigmaFileClient.runFromCli(FIGMA_FILE_URL, FIGMA_TOKEN, OUTPUT_ROOT_DIR, format, layout);
543
+ }).command("svg:optimize", "Optimize svg files in output directory", {
544
+ color: {
545
+ default: DEFAULT_CURRENT_COLOR_TARGET,
546
+ type: "string",
547
+ describe: "Color code that should be converted into `currentColor`"
548
+ },
549
+ ignoreFile: {
550
+ type: "string",
551
+ describe: "A file that contains the list of path to SVG files that should not be optimized"
552
+ }
553
+ }, async ({ color, ignoreFile }) => {
554
+ mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
555
+ await optimizeSvgInDirectory(OUTPUT_ROOT_DIR, color, ignoreFile);
556
+ }).command("files:generate", "Enumerate svg files in output directory and generate icon files", {}, () => {
557
+ mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
558
+ generateIconSource(OUTPUT_ROOT_DIR).catch((e) => {
559
+ console.error(e);
560
+ process.exit(1);
561
+ });
562
+ }).command("gitlab:mr", "Create a merge request in the name of icons-cli", {}, async () => {
563
+ mustBeDefined(GITLAB_PROJECT_ID, "GITLAB_PROJECT_ID");
564
+ mustBeDefined(GITLAB_ACCESS_TOKEN, "GITLAB_ACCESS_TOKEN");
565
+ mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
566
+ await GitlabClient.runFromCli(GITLAB_HOST ?? "https://gitlab.com", Number(GITLAB_PROJECT_ID), GITLAB_ACCESS_TOKEN, GITLAB_DEFAULT_BRANCH ?? "main", OUTPUT_ROOT_DIR);
567
+ }).command("github:pr", "Create a pull request in the name of icons-cli", {}, async () => {
568
+ mustBeDefined(GITHUB_ACCESS_TOKEN, "GITHUB_ACCESS_TOKEN");
569
+ mustBeDefined(OUTPUT_ROOT_DIR, "OUTPUT_ROOT_DIR");
570
+ await GithubClient.runFromCli(GITHUB_REPO_OWNER ?? "pixiv", GITHUB_REPO_NAME ?? "charcoal", GITHUB_ACCESS_TOKEN, GITHUB_DEFAULT_BRANCH ?? "main", OUTPUT_ROOT_DIR);
571
+ }).demandCommand().strict().help().parse();
572
+
573
+ //#endregion
702
574
  //# sourceMappingURL=index.js.map