@charcoal-ui/icons-cli 1.0.1-alpha.5 → 2.0.0-rc.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 +26 -7
- package/dist/{FigmaFileClient.d.ts → figma/FigmaFileClient.d.ts} +0 -5
- package/dist/figma/FigmaFileClient.d.ts.map +1 -0
- package/dist/generateSource.d.ts +3 -0
- package/dist/generateSource.d.ts.map +1 -0
- package/dist/index.cjs +163 -137
- package/dist/index.cjs.map +1 -1
- package/dist/index.modern.js +154 -130
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +154 -130
- package/dist/index.module.js.map +1 -1
- package/dist/svg/optimizeSvg.d.ts +17 -0
- package/dist/svg/optimizeSvg.d.ts.map +1 -0
- package/dist/svg/optimizeSvgInDirectory.d.ts +2 -0
- package/dist/svg/optimizeSvgInDirectory.d.ts.map +1 -0
- package/package.json +4 -3
- package/src/{FigmaFileClient.ts → figma/FigmaFileClient.ts} +29 -93
- package/src/generateSource.ts +83 -0
- package/src/index.ts +52 -44
- package/src/{optimizeSvg.ts → svg/optimizeSvg.ts} +22 -6
- package/src/svg/optimizeSvgInDirectory.ts +38 -0
- package/dist/FigmaFileClient.d.ts.map +0 -1
- package/dist/optimizeSvg.d.ts +0 -3
- package/dist/optimizeSvg.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -28,11 +28,11 @@ yarn icons-cli figma:export
|
|
|
28
28
|
|
|
29
29
|
必要な環境変数は以下です。
|
|
30
30
|
|
|
31
|
-
| 名前 | 必須 | 説明
|
|
32
|
-
| --------------- | ---- |
|
|
33
|
-
| FIGMA_FILE_URL | yes | Figma の URL です。node-id
|
|
34
|
-
| FIGMA_TOKEN | yes | Figma API のアクセストークンです
|
|
35
|
-
| OUTPUT_ROOT_DIR | yes | svg
|
|
31
|
+
| 名前 | 必須 | 説明 |
|
|
32
|
+
| --------------- | ---- | --------------------------------------------------------------------------------------------- |
|
|
33
|
+
| FIGMA_FILE_URL | yes | Figma の URL です。node-id を含んでいる場合、その子孫のコンポーネントのみダウンロードします。 |
|
|
34
|
+
| FIGMA_TOKEN | yes | Figma API のアクセストークンです |
|
|
35
|
+
| OUTPUT_ROOT_DIR | yes | svg をダウンロードするディレクトリです(例: `packages/icon-files`) |
|
|
36
36
|
|
|
37
37
|
Figma 内のコンポーネントは以下の命名規則に従います( 例: `16/Add` `Inline/Add` )。
|
|
38
38
|
|
|
@@ -42,10 +42,29 @@ Figma 内のコンポーネントは以下の命名規則に従います( 例:
|
|
|
42
42
|
### SVG ファイルにアイコン向けの変換をかける
|
|
43
43
|
|
|
44
44
|
```
|
|
45
|
-
yarn icons-cli svg:optimize --
|
|
45
|
+
yarn icons-cli svg:optimize --color "#000" --ignoreFile ./misc/icons-cli-denylist
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
SVG ファイルに SVGO による最適化をかけつつ、指定した色を `currentColor` に置換します。
|
|
49
|
+
`ignoreFile`では、処理から除外する SVG ファイルの一覧を記したファイルを指定することができます。[fast-glob](https://github.com/mrmlnc/fast-glob#pattern-syntax)のパターンを使用できます。
|
|
50
|
+
|
|
51
|
+
必要な環境変数は以下です。
|
|
52
|
+
|
|
53
|
+
| 名前 | 必須 | 説明 |
|
|
54
|
+
| --------------- | ---- | ----------------------------------------------------------------------- |
|
|
55
|
+
| OUTPUT_ROOT_DIR | yes | svg ディレクトリが存在するディレクトリです(例: `packages/icon-files`) |
|
|
56
|
+
|
|
57
|
+
### SVG コードを dynamic import するファイルを生成する
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
yarn icons-cli files:generate
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
必要な環境変数は以下です。
|
|
64
|
+
|
|
65
|
+
| 名前 | 必須 | 説明 |
|
|
66
|
+
| --------------- | ---- | ----------------------------------------------------------------------- |
|
|
67
|
+
| OUTPUT_ROOT_DIR | yes | svg ディレクトリが存在するディレクトリです(例: `packages/icon-files`) |
|
|
49
68
|
|
|
50
69
|
### GitHub に Pull Request を作成する
|
|
51
70
|
|
|
@@ -5,14 +5,9 @@ export declare class FigmaFileClient {
|
|
|
5
5
|
private readonly exportFormat;
|
|
6
6
|
private readonly client;
|
|
7
7
|
private components;
|
|
8
|
-
private targets;
|
|
9
8
|
static runFromCli(url: string, token: string, outputRootDir: string, exportFormat: ExportFormat): Promise<void>;
|
|
10
9
|
constructor(url: string, personalAccessToken: string, exportFormat: ExportFormat);
|
|
11
10
|
loadSvg(outputDir: string): Promise<void>;
|
|
12
|
-
/**
|
|
13
|
-
* Generate union of file names for typing
|
|
14
|
-
*/
|
|
15
|
-
writeTypeDef(outputDir: string): Promise<void>;
|
|
16
11
|
private loadComponents;
|
|
17
12
|
private loadImageUrls;
|
|
18
13
|
private downloadImages;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FigmaFileClient.d.ts","sourceRoot":"","sources":["../../src/figma/FigmaFileClient.ts"],"names":[],"mappings":"AAkCA,aAAK,YAAY,GAAG,KAAK,GAAG,KAAK,CAAA;AAQjC,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAE9C,OAAO,CAAC,UAAU,CAAgC;WAErC,UAAU,CACrB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,YAAY;gBAe1B,GAAG,EAAE,MAAM,EACX,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,YAAY;IAatB,OAAO,CAAC,SAAS,EAAE,MAAM;YASjB,cAAc;YAkBd,aAAa;YAeb,cAAc;YAsBd,OAAO;IASrB,OAAO,CAAC,yBAAyB;CAgBlC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateSource.d.ts","sourceRoot":"","sources":["../src/generateSource.ts"],"names":[],"mappings":"AA4CA,eAAO,MAAM,kBAAkB,cAClB,MAAM,SACV,MAAM,EAAE,kBAchB,CAAA;AAED,eAAO,MAAM,kBAAkB,cAAqB,MAAM,kBAoBzD,CAAA"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var fsExtra = require('fs-extra');
|
|
3
2
|
var yargs = require('yargs');
|
|
4
3
|
var path = require('path');
|
|
5
4
|
var camelCase = require('camelcase');
|
|
6
5
|
var Figma = require('figma-js');
|
|
6
|
+
var fs = require('fs-extra');
|
|
7
7
|
var got = require('got');
|
|
8
8
|
var pathToRegexp = require('path-to-regexp');
|
|
9
9
|
var PQueue = require('p-queue');
|
|
10
10
|
var rest = require('@octokit/rest');
|
|
11
|
-
var fs = require('fs');
|
|
11
|
+
var fs$1 = require('fs');
|
|
12
12
|
var child_process = require('child_process');
|
|
13
13
|
var node = require('@gitbeaker/node');
|
|
14
14
|
var jsdom = require('jsdom');
|
|
15
15
|
var polished = require('polished');
|
|
16
16
|
var Svgo = require('svgo');
|
|
17
|
+
var glob = require('fast-glob');
|
|
17
18
|
|
|
18
19
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
19
20
|
|
|
@@ -21,9 +22,11 @@ var yargs__default = /*#__PURE__*/_interopDefaultLegacy(yargs);
|
|
|
21
22
|
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
22
23
|
var camelCase__default = /*#__PURE__*/_interopDefaultLegacy(camelCase);
|
|
23
24
|
var Figma__default = /*#__PURE__*/_interopDefaultLegacy(Figma);
|
|
25
|
+
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
24
26
|
var got__default = /*#__PURE__*/_interopDefaultLegacy(got);
|
|
25
27
|
var PQueue__default = /*#__PURE__*/_interopDefaultLegacy(PQueue);
|
|
26
28
|
var Svgo__default = /*#__PURE__*/_interopDefaultLegacy(Svgo);
|
|
29
|
+
var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
|
|
27
30
|
|
|
28
31
|
function concurrently(tasks) {
|
|
29
32
|
const queue = new PQueue__default["default"]({
|
|
@@ -38,70 +41,47 @@ function concurrently(tasks) {
|
|
|
38
41
|
return queue.onIdle();
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
const
|
|
44
|
+
const matchPath = pathToRegexp.match('/file/:fileId/:name');
|
|
42
45
|
|
|
43
|
-
function
|
|
44
|
-
|
|
46
|
+
function extractParams(url) {
|
|
47
|
+
var _searchParams$get;
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function extractNodeId(url) {
|
|
54
|
-
if (!url.includes('?')) {
|
|
55
|
-
return undefined;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const [, query] = url.split('?');
|
|
59
|
-
const params = new URLSearchParams(query);
|
|
60
|
-
const nodeId = params.get('node-id');
|
|
49
|
+
const {
|
|
50
|
+
pathname,
|
|
51
|
+
searchParams
|
|
52
|
+
} = new URL(url);
|
|
53
|
+
const result = matchPath(pathname);
|
|
61
54
|
|
|
62
|
-
if (
|
|
63
|
-
|
|
55
|
+
if (result === false) {
|
|
56
|
+
throw new Error('No fileId found in url');
|
|
64
57
|
}
|
|
65
58
|
|
|
66
|
-
return
|
|
59
|
+
return {
|
|
60
|
+
fileId: result.params.fileId,
|
|
61
|
+
nodeId: (_searchParams$get = searchParams.get('node-id')) != null ? _searchParams$get : undefined
|
|
62
|
+
};
|
|
67
63
|
}
|
|
68
64
|
|
|
69
65
|
function filenamify(name) {
|
|
70
66
|
return camelCase__default["default"](name, {
|
|
71
67
|
pascalCase: true
|
|
72
68
|
}).replace(' ', '');
|
|
73
|
-
}
|
|
74
|
-
|
|
69
|
+
}
|
|
75
70
|
|
|
76
|
-
const iconName = /^(
|
|
71
|
+
const iconName = /^(?:\d+|Inline)\s*\//u;
|
|
77
72
|
|
|
78
73
|
function isIconNode(node) {
|
|
79
74
|
return iconName.test(node.name);
|
|
80
75
|
}
|
|
81
76
|
|
|
82
|
-
function getContentType(exportFormat) {
|
|
83
|
-
switch (exportFormat) {
|
|
84
|
-
case 'svg':
|
|
85
|
-
return 'image/svg+xml';
|
|
86
|
-
|
|
87
|
-
case 'pdf':
|
|
88
|
-
return 'application/pdf';
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
77
|
class FigmaFileClient {
|
|
93
78
|
static async runFromCli(url, token, outputRootDir, exportFormat) {
|
|
94
79
|
const client = new this(url, token, exportFormat);
|
|
95
|
-
const
|
|
96
|
-
const outputDir = path__default["default"].join(root, outputRootDir, exportFormat); // eslint-disable-next-line no-console
|
|
80
|
+
const outputDir = path__default["default"].join(process.cwd(), outputRootDir, exportFormat); // eslint-disable-next-line no-console
|
|
97
81
|
|
|
98
|
-
console.log(`Exporting ${url}
|
|
82
|
+
console.log(`Exporting components from ${url}`);
|
|
99
83
|
await client.loadSvg(outputDir); // eslint-disable-next-line no-console
|
|
100
84
|
|
|
101
|
-
console.log(`Exporting components type`);
|
|
102
|
-
const typedefDir = path__default["default"].join(root, outputRootDir, 'src');
|
|
103
|
-
await client.writeTypeDef(typedefDir); // eslint-disable-next-line no-console
|
|
104
|
-
|
|
105
85
|
console.log('success!');
|
|
106
86
|
}
|
|
107
87
|
|
|
@@ -111,63 +91,37 @@ class FigmaFileClient {
|
|
|
111
91
|
this.exportFormat = void 0;
|
|
112
92
|
this.client = void 0;
|
|
113
93
|
this.components = {};
|
|
114
|
-
this.targets = [];
|
|
115
94
|
this.client = Figma__default["default"].Client({
|
|
116
95
|
personalAccessToken
|
|
117
96
|
});
|
|
118
|
-
|
|
119
|
-
|
|
97
|
+
const {
|
|
98
|
+
fileId,
|
|
99
|
+
nodeId
|
|
100
|
+
} = extractParams(url);
|
|
101
|
+
this.fileId = fileId;
|
|
102
|
+
this.nodeId = nodeId;
|
|
120
103
|
this.exportFormat = exportFormat;
|
|
121
104
|
}
|
|
122
105
|
|
|
123
106
|
async loadSvg(outputDir) {
|
|
124
|
-
await
|
|
125
|
-
await
|
|
107
|
+
await fs.remove(outputDir);
|
|
108
|
+
await fs.ensureDir(outputDir);
|
|
126
109
|
await this.loadComponents();
|
|
127
110
|
await this.loadImageUrls();
|
|
128
111
|
await this.downloadImages(outputDir);
|
|
129
112
|
}
|
|
130
|
-
/**
|
|
131
|
-
* Generate union of file names for typing
|
|
132
|
-
*/
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
async writeTypeDef(outputDir) {
|
|
136
|
-
const fullname = path__default["default"].resolve(outputDir, 'icons.ts');
|
|
137
|
-
const knownIconFiles = Array.from(new Set(Object.values(this.components).map(({
|
|
138
|
-
name
|
|
139
|
-
}) => filenamify(name)))); // eslint-disable-next-line no-console
|
|
140
|
-
|
|
141
|
-
console.log(`writing to ${outputDir}`);
|
|
142
|
-
await fsExtra.ensureFile(fullname);
|
|
143
|
-
await fsExtra.writeFile(fullname, `/** This file is auto generated. DO NOT EDIT BY HAND. */
|
|
144
|
-
|
|
145
|
-
const icons = {
|
|
146
|
-
${knownIconFiles.map(fullName => ` '${fullName}': require('../svg/${fullName}.svg'),`).join('\n')}
|
|
147
|
-
} as const;
|
|
148
|
-
|
|
149
|
-
export default icons;
|
|
150
|
-
export type KnownIconFile = keyof typeof icons;
|
|
151
|
-
export const KNOWN_ICON_FILES = Object.keys(icons) as KnownIconFile[];
|
|
152
|
-
`, {
|
|
153
|
-
encoding: 'utf8'
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
113
|
|
|
157
114
|
async loadComponents() {
|
|
158
115
|
const {
|
|
159
116
|
document
|
|
160
|
-
} = await this.getFile();
|
|
161
|
-
|
|
162
|
-
if (this.nodeId !== undefined) {
|
|
163
|
-
return node.id === this.nodeId;
|
|
164
|
-
}
|
|
117
|
+
} = await this.getFile(); // nodeIdが指定されている場合は、IDが一致するノードのみを探索対象にする
|
|
118
|
+
// 指定されていない場合はドキュメント全体が探索対象
|
|
165
119
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
120
|
+
const targets = this.nodeId !== undefined ? document.children.filter(node => node.id === this.nodeId) : document.children; // 対象ノードの子孫を探索してアイコンのコンポーネントを見つける
|
|
121
|
+
|
|
122
|
+
targets.forEach(child => this.findComponentsRecursively(child));
|
|
169
123
|
|
|
170
|
-
if (Object.
|
|
124
|
+
if (Object.keys(this.components).length === 0) {
|
|
171
125
|
throw new Error('No components found!');
|
|
172
126
|
}
|
|
173
127
|
}
|
|
@@ -194,19 +148,14 @@ export const KNOWN_ICON_FILES = Object.keys(icons) as KnownIconFile[];
|
|
|
194
148
|
return;
|
|
195
149
|
}
|
|
196
150
|
|
|
197
|
-
const
|
|
198
|
-
headers: {
|
|
199
|
-
'Content-Type': getContentType(this.exportFormat)
|
|
200
|
-
},
|
|
201
|
-
encoding: 'utf8'
|
|
202
|
-
});
|
|
151
|
+
const svg = await got__default["default"](component.image).text();
|
|
203
152
|
const filename = `${filenamify(component.name)}.${this.exportFormat}`;
|
|
204
153
|
const fullname = path__default["default"].join(outputDir, filename);
|
|
205
154
|
const dirname = path__default["default"].dirname(fullname);
|
|
206
|
-
await
|
|
155
|
+
await fs.ensureDir(dirname); // eslint-disable-next-line no-console
|
|
207
156
|
|
|
208
157
|
console.log(`found: ${filename} => ✅ writing...`);
|
|
209
|
-
await
|
|
158
|
+
await fs.writeFile(fullname, svg, 'utf8');
|
|
210
159
|
}));
|
|
211
160
|
}
|
|
212
161
|
|
|
@@ -445,7 +394,7 @@ function getChangedFiles() {
|
|
|
445
394
|
|
|
446
395
|
function _getChangedFiles() {
|
|
447
396
|
_getChangedFiles = _wrapAsyncGenerator(function* (dir = targetDir) {
|
|
448
|
-
if (!fs.existsSync(dir)) throw new Error(`icons-cli: target directory not found (${dir})`);
|
|
397
|
+
if (!fs$1.existsSync(dir)) throw new Error(`icons-cli: target directory not found (${dir})`);
|
|
449
398
|
const gitStatus = yield _awaitAsyncGenerator(collectGitStatus());
|
|
450
399
|
|
|
451
400
|
for (const [relativePath, status] of gitStatus) {
|
|
@@ -455,8 +404,8 @@ function _getChangedFiles() {
|
|
|
455
404
|
continue;
|
|
456
405
|
}
|
|
457
406
|
|
|
458
|
-
if (!fs.existsSync(fullpath)) throw new Error(`icons-cli: could not load svg (${fullpath})`);
|
|
459
|
-
const content = yield _awaitAsyncGenerator(fs.promises.readFile(fullpath, {
|
|
407
|
+
if (!fs$1.existsSync(fullpath)) throw new Error(`icons-cli: could not load svg (${fullpath})`);
|
|
408
|
+
const content = yield _awaitAsyncGenerator(fs$1.promises.readFile(fullpath, {
|
|
460
409
|
encoding: 'utf-8'
|
|
461
410
|
}));
|
|
462
411
|
yield {
|
|
@@ -732,20 +681,17 @@ const svgo = new Svgo__default["default"]({
|
|
|
732
681
|
// なので、convertColors plugin は使わない
|
|
733
682
|
// { convertColors: { currentColor: true } },
|
|
734
683
|
{
|
|
735
|
-
removeViewBox:
|
|
684
|
+
removeViewBox: false
|
|
736
685
|
}, {
|
|
737
686
|
removeAttrs: {
|
|
738
687
|
attrs: ['stroke-opacity', 'fill-opacity']
|
|
739
688
|
}
|
|
740
689
|
}]
|
|
741
690
|
});
|
|
742
|
-
async function optimizeSvg(input,
|
|
743
|
-
const {
|
|
744
|
-
data
|
|
745
|
-
} = await svgo.optimize(input);
|
|
691
|
+
async function optimizeSvg(input, options) {
|
|
746
692
|
const {
|
|
747
693
|
document
|
|
748
|
-
} = new jsdom.JSDOM(
|
|
694
|
+
} = new jsdom.JSDOM(input).window;
|
|
749
695
|
const svg = document.querySelector('svg');
|
|
750
696
|
|
|
751
697
|
if (!svg) {
|
|
@@ -753,8 +699,13 @@ async function optimizeSvg(input, convertedColor) {
|
|
|
753
699
|
}
|
|
754
700
|
|
|
755
701
|
addViewboxToRootSvg(svg);
|
|
756
|
-
convertToCurrentColor(svg, convertedColor);
|
|
757
|
-
|
|
702
|
+
convertToCurrentColor(svg, options.convertedColor);
|
|
703
|
+
|
|
704
|
+
if (options.withoutOptimizeBySVGO === true) {
|
|
705
|
+
return svg.outerHTML;
|
|
706
|
+
} else {
|
|
707
|
+
return (await svgo.optimize(svg.outerHTML)).data;
|
|
708
|
+
}
|
|
758
709
|
}
|
|
759
710
|
const TARGET_ATTRS = ['fill', 'stroke'];
|
|
760
711
|
|
|
@@ -828,6 +779,85 @@ function addViewboxToRootSvg(svg) {
|
|
|
828
779
|
svg.setAttribute('viewBox', `0 0 ${width} ${height}`);
|
|
829
780
|
}
|
|
830
781
|
|
|
782
|
+
/* eslint-disable no-console */
|
|
783
|
+
|
|
784
|
+
const optimizeSvgInDirectory = async (outputDir, replaceColor, ignoreFile) => {
|
|
785
|
+
const rootDir = path__default["default"].join(outputDir, 'svg');
|
|
786
|
+
const ignorePatterns = ignoreFile !== undefined ? (await fs__default["default"].readFile(ignoreFile, 'utf8')).trim().split(/\r?\n/u) : [];
|
|
787
|
+
const files = await glob__default["default"]('**/*.svg', {
|
|
788
|
+
cwd: rootDir
|
|
789
|
+
});
|
|
790
|
+
await concurrently(files.map(file => async () => {
|
|
791
|
+
console.log(`Optimizing ${file}...`);
|
|
792
|
+
const fullPath = path__default["default"].join(rootDir, file);
|
|
793
|
+
const originalSvg = await fs__default["default"].readFile(fullPath, 'utf8');
|
|
794
|
+
const optimizedSvg = await optimizeSvg(originalSvg, {
|
|
795
|
+
convertedColor: replaceColor,
|
|
796
|
+
withoutOptimizeBySVGO: ignorePatterns.includes(file)
|
|
797
|
+
});
|
|
798
|
+
await fs__default["default"].writeFile(fullPath, optimizedSvg);
|
|
799
|
+
}));
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
const generateIconSvgEmbededSource = svgString => {
|
|
803
|
+
const str = svgString.replace(/\r?\n/g, '');
|
|
804
|
+
return `/** This file is auto generated. DO NOT EDIT BY HAND. */
|
|
805
|
+
export default '${str}'
|
|
806
|
+
`;
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
const generateMjsEntrypoint = icons => `/** This file is auto generated. DO NOT EDIT BY HAND. */
|
|
810
|
+
|
|
811
|
+
export default {
|
|
812
|
+
${icons.map(it => ` '${it}': () => import('./${it}.js').then(m => m.default)`).join(',\n')}
|
|
813
|
+
}
|
|
814
|
+
`;
|
|
815
|
+
|
|
816
|
+
const generateCjsEntrypoint = icons => `/** This file is auto generated. DO NOT EDIT BY HAND. */
|
|
817
|
+
|
|
818
|
+
export default {
|
|
819
|
+
${icons.map(it => ` '${it}': () => import('./${it}.js').then(m => m.default)`).join(',\n')}
|
|
820
|
+
}
|
|
821
|
+
`;
|
|
822
|
+
|
|
823
|
+
const generateTypeDefinitionEntrypoint = icons => `/** This file is auto generated. DO NOt EDIT BY HAND. */
|
|
824
|
+
|
|
825
|
+
declare var _default: {
|
|
826
|
+
${icons.map(it => ` '${it}': () => Promise<string>`).join(';\n')}
|
|
827
|
+
};
|
|
828
|
+
export default _default;
|
|
829
|
+
`;
|
|
830
|
+
|
|
831
|
+
const generateEntrypoint = async (outputDir, icons) => {
|
|
832
|
+
const srcRoot = path__default["default"].join(outputDir, 'src');
|
|
833
|
+
const mjsPath = path__default["default"].join(srcRoot, 'index.js');
|
|
834
|
+
await fs__default["default"].ensureFile(mjsPath);
|
|
835
|
+
await fs__default["default"].writeFile(mjsPath, generateMjsEntrypoint(icons));
|
|
836
|
+
const cjsPath = path__default["default"].join(srcRoot, 'index.cjs');
|
|
837
|
+
await fs__default["default"].ensureFile(cjsPath);
|
|
838
|
+
await fs__default["default"].writeFile(cjsPath, generateCjsEntrypoint(icons));
|
|
839
|
+
const dtsPath = path__default["default"].join(srcRoot, 'index.d.ts');
|
|
840
|
+
await fs__default["default"].ensureFile(dtsPath);
|
|
841
|
+
await fs__default["default"].writeFile(dtsPath, generateTypeDefinitionEntrypoint(icons));
|
|
842
|
+
};
|
|
843
|
+
const generateIconSource = async outputDir => {
|
|
844
|
+
const svgRoot = path__default["default"].join(outputDir, 'svg');
|
|
845
|
+
const srcRoot = path__default["default"].join(outputDir, 'src');
|
|
846
|
+
const icons = (await glob__default["default"]('**/*.svg', {
|
|
847
|
+
cwd: svgRoot
|
|
848
|
+
})).map(path => path.slice(0, -4) // e.g. '16/Add.svg' -> '16/Add'
|
|
849
|
+
).sort();
|
|
850
|
+
|
|
851
|
+
for (const it of icons) {
|
|
852
|
+
const data = await fs__default["default"].readFile(path__default["default"].join(svgRoot, `${it}.svg`));
|
|
853
|
+
const outputPath = path__default["default"].join(srcRoot, `${it}.js`);
|
|
854
|
+
await fs__default["default"].ensureFile(outputPath);
|
|
855
|
+
await fs__default["default"].writeFile(outputPath, generateIconSvgEmbededSource(data.toString()));
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
await generateEntrypoint(outputDir, icons);
|
|
859
|
+
};
|
|
860
|
+
|
|
831
861
|
/**
|
|
832
862
|
* Figma
|
|
833
863
|
*/
|
|
@@ -851,52 +881,48 @@ const GITHUB_ACCESS_TOKEN = process.env.GITHUB_ACCESS_TOKEN;
|
|
|
851
881
|
const GITHUB_REPO_OWNER = process.env.GITHUB_REPO_OWNER;
|
|
852
882
|
const GITHUB_REPO_NAME = process.env.GITHUB_REPO_NAME;
|
|
853
883
|
const GITHUB_DEFAULT_BRANCH = process.env.GITHUB_DEFAULT_BRANCH;
|
|
854
|
-
void yargs__default["default"].scriptName('icons-cli').command('figma:export', 'Load all icons from Figma and save to files',
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
884
|
+
void yargs__default["default"].scriptName('icons-cli').command('figma:export', 'Load all icons from Figma and save to files', {
|
|
885
|
+
format: {
|
|
886
|
+
default: 'svg',
|
|
887
|
+
choices: ['svg', 'pdf'],
|
|
888
|
+
describe: 'Output format'
|
|
889
|
+
}
|
|
890
|
+
}, async ({
|
|
858
891
|
format
|
|
859
892
|
}) => {
|
|
860
893
|
mustBeDefined(FIGMA_FILE_URL, 'FIGMA_FILE_URL');
|
|
861
894
|
mustBeDefined(FIGMA_TOKEN, 'FIGMA_TOKEN');
|
|
862
895
|
mustBeDefined(OUTPUT_ROOT_DIR, 'OUTPUT_ROOT_DIR');
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
color
|
|
896
|
+
await FigmaFileClient.runFromCli(FIGMA_FILE_URL, FIGMA_TOKEN, OUTPUT_ROOT_DIR, format);
|
|
897
|
+
}).command('svg:optimize', 'Optimize svg files in output directory', {
|
|
898
|
+
color: {
|
|
899
|
+
default: DEFAULT_CURRENT_COLOR_TARGET,
|
|
900
|
+
type: 'string',
|
|
901
|
+
describe: 'Color code that should be converted into `currentColor`'
|
|
902
|
+
},
|
|
903
|
+
ignoreFile: {
|
|
904
|
+
type: 'string',
|
|
905
|
+
describe: 'A file that contains the list of path to SVG files that should not be optimized'
|
|
906
|
+
}
|
|
907
|
+
}, async ({
|
|
908
|
+
color,
|
|
909
|
+
ignoreFile
|
|
878
910
|
}) => {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
911
|
+
mustBeDefined(OUTPUT_ROOT_DIR, 'OUTPUT_ROOT_DIR');
|
|
912
|
+
await optimizeSvgInDirectory(OUTPUT_ROOT_DIR, color, ignoreFile);
|
|
913
|
+
}).command('files:generate', 'Enumerate svg files in output directory and generate icon files', {}, () => {
|
|
914
|
+
mustBeDefined(OUTPUT_ROOT_DIR, 'OUTPUT_ROOT_DIR');
|
|
915
|
+
void generateIconSource(OUTPUT_ROOT_DIR).catch(e => {
|
|
882
916
|
// eslint-disable-next-line no-console
|
|
883
917
|
console.error(e);
|
|
884
918
|
process.exit(1);
|
|
885
919
|
});
|
|
886
|
-
}).command('gitlab:mr', 'Create a merge request in the name of icons-cli', {}, () => {
|
|
920
|
+
}).command('gitlab:mr', 'Create a merge request in the name of icons-cli', {}, async () => {
|
|
887
921
|
mustBeDefined(GITLAB_PROJECT_ID, 'GITLAB_PROJECT_ID');
|
|
888
922
|
mustBeDefined(GITLAB_ACCESS_TOKEN, 'GITLAB_ACCESS_TOKEN');
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
console.error(e);
|
|
892
|
-
process.exit(1);
|
|
893
|
-
});
|
|
894
|
-
}).command('github:pr', 'Create a pull request in the name of icons-cli', {}, () => {
|
|
923
|
+
await GitlabClient.runFromCli(GITLAB_HOST != null ? GITLAB_HOST : 'https://gitlab.com', Number(GITLAB_PROJECT_ID), GITLAB_ACCESS_TOKEN, GITLAB_DEFAULT_BRANCH != null ? GITLAB_DEFAULT_BRANCH : 'main');
|
|
924
|
+
}).command('github:pr', 'Create a pull request in the name of icons-cli', {}, async () => {
|
|
895
925
|
mustBeDefined(GITHUB_ACCESS_TOKEN, 'GITHUB_ACCESS_TOKEN');
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
console.error(e);
|
|
899
|
-
process.exit(1);
|
|
900
|
-
});
|
|
901
|
-
}).demandCommand().help().parse();
|
|
926
|
+
await GithubClient.runFromCli(GITHUB_REPO_OWNER != null ? GITHUB_REPO_OWNER : 'pixiv', GITHUB_REPO_NAME != null ? GITHUB_REPO_NAME : 'charcoal', GITHUB_ACCESS_TOKEN, GITHUB_DEFAULT_BRANCH != null ? GITHUB_DEFAULT_BRANCH : 'main');
|
|
927
|
+
}).demandCommand().strict().help().parse();
|
|
902
928
|
//# sourceMappingURL=index.cjs.map
|