@charcoal-ui/icons-cli 5.9.0-beta.0 → 5.9.0-beta.1
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 +74 -23
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/GitHubClient.ts +1 -1
- package/src/GitlabClient.ts +1 -1
- package/src/codegen.test.ts +86 -0
- package/src/codegen.ts +28 -0
- package/src/figma/FigmaFileClient.test.ts +218 -0
- package/src/figma/FigmaFileClient.ts +96 -27
- package/src/generateSource.test.ts +68 -0
- package/src/generateSource.ts +17 -8
- package/src/getChangedFiles.ts +15 -10
- package/src/index.ts +10 -1
- package/src/v2/transformCSS.test.ts +113 -0
- package/src/v2/transformCSS.ts +52 -63
- package/src/v2/transformDataUri.test.ts +97 -0
- package/src/v2/transformDataUri.ts +20 -28
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { mkdtemp, readFile, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import fs from 'fs-extra'
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
6
|
+
|
|
7
|
+
async function waitForFile(filePath: string) {
|
|
8
|
+
for (let i = 0; i < 100; i += 1) {
|
|
9
|
+
if (await fs.pathExists(filePath)) {
|
|
10
|
+
return
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
throw new Error(`timed out waiting for ${filePath}`)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function runTransformCss(
|
|
20
|
+
sourceDir: string,
|
|
21
|
+
outputDir: string,
|
|
22
|
+
version: 'v1' | 'v2',
|
|
23
|
+
) {
|
|
24
|
+
const previousVersion = process.env.VERSION
|
|
25
|
+
const previousSourceRootDir = process.env.SOURCE_ROOT_DIR
|
|
26
|
+
const previousOutputRootDir = process.env.OUTPUT_ROOT_DIR
|
|
27
|
+
|
|
28
|
+
process.env.VERSION = version
|
|
29
|
+
process.env.SOURCE_ROOT_DIR = path.relative(import.meta.dirname, sourceDir)
|
|
30
|
+
process.env.OUTPUT_ROOT_DIR = outputDir
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
vi.resetModules()
|
|
34
|
+
await import('./transformCSS')
|
|
35
|
+
await waitForFile(path.join(outputDir, 'index.story.tsx'))
|
|
36
|
+
} finally {
|
|
37
|
+
if (previousVersion === undefined) {
|
|
38
|
+
delete process.env.VERSION
|
|
39
|
+
} else {
|
|
40
|
+
process.env.VERSION = previousVersion
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (previousSourceRootDir === undefined) {
|
|
44
|
+
delete process.env.SOURCE_ROOT_DIR
|
|
45
|
+
} else {
|
|
46
|
+
process.env.SOURCE_ROOT_DIR = previousSourceRootDir
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (previousOutputRootDir === undefined) {
|
|
50
|
+
delete process.env.OUTPUT_ROOT_DIR
|
|
51
|
+
} else {
|
|
52
|
+
process.env.OUTPUT_ROOT_DIR = previousOutputRootDir
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
describe('transformCSS regression', () => {
|
|
58
|
+
let workDir: string
|
|
59
|
+
|
|
60
|
+
beforeEach(async () => {
|
|
61
|
+
workDir = await mkdtemp(path.join(tmpdir(), 'icons-cli-transform-css-'))
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
afterEach(async () => {
|
|
65
|
+
await fs.remove(workDir)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('通常のv2アイコン名では既存のclass名を維持する', async () => {
|
|
69
|
+
const sourceDir = path.join(workDir, 'input')
|
|
70
|
+
const outputDir = path.join(workDir, 'output')
|
|
71
|
+
|
|
72
|
+
await fs.ensureDir(path.join(sourceDir, '24', 'regular'))
|
|
73
|
+
await writeFile(
|
|
74
|
+
path.join(sourceDir, '24', 'regular', 'Add.Circle.svg'),
|
|
75
|
+
'<svg />',
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
await runTransformCss(sourceDir, outputDir, 'v2')
|
|
79
|
+
|
|
80
|
+
const css = await readFile(path.join(outputDir, 'index.css'), 'utf8')
|
|
81
|
+
|
|
82
|
+
expect(css).toContain('.charcoal-icon-v2-add-circle')
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('危険な文字を含むv2ファイル名でも安全なclass名だけを生成する', async () => {
|
|
86
|
+
const sourceDir = path.join(workDir, 'input')
|
|
87
|
+
const outputDir = path.join(workDir, 'output')
|
|
88
|
+
const safeClassName = 'charcoal-icon-v2-bad-name-16'
|
|
89
|
+
|
|
90
|
+
await fs.ensureDir(path.join(sourceDir, '16', 'regular'))
|
|
91
|
+
await writeFile(
|
|
92
|
+
path.join(sourceDir, '16', 'regular', 'Bad "Name"..svg'),
|
|
93
|
+
'<svg />',
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
await runTransformCss(sourceDir, outputDir, 'v2')
|
|
97
|
+
|
|
98
|
+
const css = await readFile(path.join(outputDir, 'index.css'), 'utf8')
|
|
99
|
+
const html = await readFile(path.join(outputDir, 'index.html'), 'utf8')
|
|
100
|
+
const story = await readFile(
|
|
101
|
+
path.join(outputDir, 'index.story.tsx'),
|
|
102
|
+
'utf8',
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
expect(css).toContain(`.${safeClassName}`)
|
|
106
|
+
expect(html).toContain(`class="${safeClassName}"`)
|
|
107
|
+
expect(story).toContain(`className="${safeClassName}"`)
|
|
108
|
+
|
|
109
|
+
expect(css).not.toContain('Bad "Name"')
|
|
110
|
+
expect(html).not.toContain('Bad "Name"')
|
|
111
|
+
expect(story).not.toContain('Bad "Name"')
|
|
112
|
+
})
|
|
113
|
+
})
|
package/src/v2/transformCSS.ts
CHANGED
|
@@ -2,14 +2,51 @@ import { mustBeDefined } from '../utils'
|
|
|
2
2
|
import { glob, readFile, writeFile } from 'fs/promises'
|
|
3
3
|
import { ensureDir } from 'fs-extra'
|
|
4
4
|
import path from 'path'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
createCssClassNameSegment,
|
|
7
|
+
createSvgDataUri,
|
|
8
|
+
serializeJavaScriptValue,
|
|
9
|
+
} from '../codegen'
|
|
10
|
+
|
|
11
|
+
const previewStyles = `:root {
|
|
12
|
+
font-size: 24px;
|
|
13
|
+
}
|
|
14
|
+
.icons {
|
|
15
|
+
display: grid;
|
|
16
|
+
gap: 8px;
|
|
17
|
+
grid-template-columns: repeat(auto-fill, 300px);
|
|
18
|
+
}
|
|
19
|
+
.icons div {
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
gap: 8px;
|
|
22
|
+
align-items: center;
|
|
23
|
+
}
|
|
24
|
+
code {
|
|
25
|
+
font-size: 14px;
|
|
26
|
+
}`
|
|
27
|
+
|
|
28
|
+
function createPreviewItems(
|
|
29
|
+
classNames: string[],
|
|
30
|
+
classAttributeName: 'class' | 'className',
|
|
31
|
+
) {
|
|
32
|
+
return classNames
|
|
33
|
+
.map(
|
|
34
|
+
(icon) => `
|
|
35
|
+
<div>
|
|
36
|
+
<div ${classAttributeName}="${icon}" aria-label=".${icon}" role="img"></div>
|
|
37
|
+
<code>.${icon}</code>
|
|
38
|
+
</div>`,
|
|
39
|
+
)
|
|
40
|
+
.join('\n')
|
|
41
|
+
}
|
|
6
42
|
|
|
7
43
|
async function transformV2(filePath: string, fileName: string) {
|
|
8
44
|
const content = await readFile(filePath, 'utf-8')
|
|
9
45
|
const [size, variant, name] = fileName.split('/')
|
|
46
|
+
const dataUri = createSvgDataUri(content)
|
|
10
47
|
const cssName = [
|
|
11
48
|
'charcoal-icon-v2',
|
|
12
|
-
name
|
|
49
|
+
createCssClassNameSegment(name),
|
|
13
50
|
...(variant === 'regular' ? [] : [variant]),
|
|
14
51
|
...(size === '24' ? [] : [size]),
|
|
15
52
|
].join('-')
|
|
@@ -19,9 +56,7 @@ async function transformV2(filePath: string, fileName: string) {
|
|
|
19
56
|
display: inline-block;
|
|
20
57
|
width: 1em;
|
|
21
58
|
height: 1em;
|
|
22
|
-
background: url(
|
|
23
|
-
content,
|
|
24
|
-
).replace("'", "\\'")}');
|
|
59
|
+
background: url("${dataUri}");
|
|
25
60
|
aspect-ratio: 1/1;
|
|
26
61
|
}`
|
|
27
62
|
: `
|
|
@@ -29,9 +64,7 @@ async function transformV2(filePath: string, fileName: string) {
|
|
|
29
64
|
display: inline-block;
|
|
30
65
|
width: 1em;
|
|
31
66
|
height: 1em;
|
|
32
|
-
mask-image: url(
|
|
33
|
-
content,
|
|
34
|
-
).replace("'", "\\'")}');
|
|
67
|
+
mask-image: url("${dataUri}");
|
|
35
68
|
mask-size: 100% 100%;
|
|
36
69
|
background: currentColor;
|
|
37
70
|
aspect-ratio: 1/1;
|
|
@@ -47,9 +80,10 @@ async function transformV2(filePath: string, fileName: string) {
|
|
|
47
80
|
async function transformV1(filePath: string, fileName: string) {
|
|
48
81
|
const content = await readFile(filePath, 'utf-8')
|
|
49
82
|
const [size, name] = fileName.split('/')
|
|
83
|
+
const dataUri = createSvgDataUri(content)
|
|
50
84
|
const cssName = [
|
|
51
85
|
'charcoal-icon-v1',
|
|
52
|
-
name
|
|
86
|
+
createCssClassNameSegment(name),
|
|
53
87
|
...(size === '24' ? [] : [size]),
|
|
54
88
|
].join('-')
|
|
55
89
|
const css = content.includes('<def')
|
|
@@ -58,9 +92,7 @@ async function transformV1(filePath: string, fileName: string) {
|
|
|
58
92
|
display: inline-block;
|
|
59
93
|
width: 1em;
|
|
60
94
|
height: 1em;
|
|
61
|
-
background: url(
|
|
62
|
-
content,
|
|
63
|
-
).replace("'", "\\'")}');
|
|
95
|
+
background: url("${dataUri}");
|
|
64
96
|
aspect-ratio: 1/1;
|
|
65
97
|
}`
|
|
66
98
|
: `
|
|
@@ -68,9 +100,7 @@ async function transformV1(filePath: string, fileName: string) {
|
|
|
68
100
|
display: inline-block;
|
|
69
101
|
width: 1em;
|
|
70
102
|
height: 1em;
|
|
71
|
-
mask-image: url(
|
|
72
|
-
content,
|
|
73
|
-
).replace("'", "\\'")}');
|
|
103
|
+
mask-image: url("${dataUri}");
|
|
74
104
|
mask-size: 100% 100%;
|
|
75
105
|
background: currentColor;
|
|
76
106
|
aspect-ratio: 1/1;
|
|
@@ -125,38 +155,12 @@ async function main() {
|
|
|
125
155
|
classNames = classNames.sort()
|
|
126
156
|
const html = `
|
|
127
157
|
<div class="icons">
|
|
128
|
-
${classNames
|
|
129
|
-
.map(
|
|
130
|
-
(icon) => `
|
|
131
|
-
<div>
|
|
132
|
-
<div class="${icon}" aria-label=".${icon}" role="img" />
|
|
133
|
-
<code>.${icon}</code>
|
|
134
|
-
</div>
|
|
135
|
-
`,
|
|
136
|
-
)
|
|
137
|
-
.join('\n')}
|
|
158
|
+
${createPreviewItems(classNames, 'class')}
|
|
138
159
|
</div>`
|
|
139
160
|
|
|
140
161
|
await writeFile(
|
|
141
162
|
path.join(outDir, 'index.html'),
|
|
142
|
-
`<link rel="stylesheet" href="./index.css"><style
|
|
143
|
-
:root {
|
|
144
|
-
font-size: 24px;
|
|
145
|
-
}
|
|
146
|
-
.icons {
|
|
147
|
-
display: grid;
|
|
148
|
-
gap: 8px;
|
|
149
|
-
grid-template-columns: repeat(auto-fill, 300px);
|
|
150
|
-
}
|
|
151
|
-
.icons div {
|
|
152
|
-
display: inline-flex;
|
|
153
|
-
gap: 8px;
|
|
154
|
-
align-items: center;
|
|
155
|
-
}
|
|
156
|
-
code {
|
|
157
|
-
font-size: 14px;
|
|
158
|
-
}
|
|
159
|
-
</style>${html}`,
|
|
163
|
+
`<link rel="stylesheet" href="./index.css"><style>${previewStyles}</style>${html}`,
|
|
160
164
|
)
|
|
161
165
|
await writeFile(
|
|
162
166
|
path.join(outDir, 'index.story.tsx'),
|
|
@@ -175,26 +179,11 @@ export default {
|
|
|
175
179
|
render(): JSX.Element {
|
|
176
180
|
return (
|
|
177
181
|
<>
|
|
178
|
-
<style>{
|
|
179
|
-
<style>
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
.icons {
|
|
184
|
-
display: grid;
|
|
185
|
-
gap: 8px;
|
|
186
|
-
grid-template-columns: repeat(auto-fill, 300px);
|
|
187
|
-
}
|
|
188
|
-
.icons div {
|
|
189
|
-
display: inline-flex;
|
|
190
|
-
gap: 8px;
|
|
191
|
-
align-items: center;
|
|
192
|
-
}
|
|
193
|
-
code {
|
|
194
|
-
font-size: 14px;
|
|
195
|
-
}\`}
|
|
196
|
-
</style>
|
|
197
|
-
${html.replaceAll('class', 'className')}
|
|
182
|
+
<style>{${serializeJavaScriptValue(cssContent)}}</style>
|
|
183
|
+
<style>{${serializeJavaScriptValue(previewStyles)}}</style>
|
|
184
|
+
<div className="icons">
|
|
185
|
+
${createPreviewItems(classNames, 'className')}
|
|
186
|
+
</div>
|
|
198
187
|
</>
|
|
199
188
|
)
|
|
200
189
|
},
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { mkdtemp, readFile, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import vm from 'node:vm'
|
|
5
|
+
import fs from 'fs-extra'
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
7
|
+
|
|
8
|
+
async function waitForFile(filePath: string) {
|
|
9
|
+
for (let i = 0; i < 100; i += 1) {
|
|
10
|
+
if (await fs.pathExists(filePath)) {
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
throw new Error(`timed out waiting for ${filePath}`)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function runTransformDataUri(sourceDir: string, outputDir: string) {
|
|
21
|
+
const previousSourceRootDir = process.env.SOURCE_ROOT_DIR
|
|
22
|
+
const previousOutputRootDir = process.env.OUTPUT_ROOT_DIR
|
|
23
|
+
|
|
24
|
+
process.env.SOURCE_ROOT_DIR = path.relative(import.meta.dirname, sourceDir)
|
|
25
|
+
process.env.OUTPUT_ROOT_DIR = outputDir
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
vi.resetModules()
|
|
29
|
+
await import('./transformDataUri')
|
|
30
|
+
await waitForFile(path.join(outputDir, 'index.d.ts'))
|
|
31
|
+
} finally {
|
|
32
|
+
if (previousSourceRootDir === undefined) {
|
|
33
|
+
delete process.env.SOURCE_ROOT_DIR
|
|
34
|
+
} else {
|
|
35
|
+
process.env.SOURCE_ROOT_DIR = previousSourceRootDir
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (previousOutputRootDir === undefined) {
|
|
39
|
+
delete process.env.OUTPUT_ROOT_DIR
|
|
40
|
+
} else {
|
|
41
|
+
process.env.OUTPUT_ROOT_DIR = previousOutputRootDir
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
describe('transformDataUri regression', () => {
|
|
47
|
+
let workDir: string
|
|
48
|
+
|
|
49
|
+
beforeEach(async () => {
|
|
50
|
+
workDir = await mkdtemp(
|
|
51
|
+
path.join(tmpdir(), 'icons-cli-transform-data-uri-'),
|
|
52
|
+
)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
afterEach(async () => {
|
|
56
|
+
await fs.remove(workDir)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('危険なキー名を含んでもCJS出力が壊れない', async () => {
|
|
60
|
+
const sourceDir = path.join(workDir, 'input')
|
|
61
|
+
const outputDir = path.join(workDir, 'output')
|
|
62
|
+
const iconName = String.raw`16/Bad'"Name\Icon`
|
|
63
|
+
|
|
64
|
+
await fs.ensureDir(path.join(sourceDir, '16'))
|
|
65
|
+
await writeFile(path.join(sourceDir, `${iconName}.svg`), '<svg />')
|
|
66
|
+
|
|
67
|
+
await runTransformDataUri(sourceDir, outputDir)
|
|
68
|
+
|
|
69
|
+
const cjs = await readFile(path.join(outputDir, 'index.cjs'), 'utf8')
|
|
70
|
+
const context = {
|
|
71
|
+
module: { exports: {} as Record<string, unknown> },
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const script = new vm.Script(cjs)
|
|
75
|
+
script.runInNewContext(context)
|
|
76
|
+
|
|
77
|
+
expect(Object.keys(context.module.exports)).toEqual([iconName])
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('危険なSVG文字列でもdata URIを生で埋め込まない', async () => {
|
|
81
|
+
const sourceDir = path.join(workDir, 'input')
|
|
82
|
+
const outputDir = path.join(workDir, 'output')
|
|
83
|
+
const svgContent =
|
|
84
|
+
'<svg><text></style><script>alert("xss")</script></text></svg>'
|
|
85
|
+
|
|
86
|
+
await fs.ensureDir(path.join(sourceDir, '16'))
|
|
87
|
+
await writeFile(path.join(sourceDir, '16', 'Add.svg'), svgContent)
|
|
88
|
+
|
|
89
|
+
await runTransformDataUri(sourceDir, outputDir)
|
|
90
|
+
|
|
91
|
+
const mjs = await readFile(path.join(outputDir, 'index.mjs'), 'utf8')
|
|
92
|
+
|
|
93
|
+
expect(mjs).not.toContain('</style>')
|
|
94
|
+
expect(mjs).not.toContain('<script>')
|
|
95
|
+
expect(mjs).toContain('%3Csvg%3E')
|
|
96
|
+
})
|
|
97
|
+
})
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { glob, readFile, writeFile } from 'fs/promises'
|
|
2
2
|
import { ensureDir } from 'fs-extra'
|
|
3
3
|
import path from 'path'
|
|
4
|
-
import {
|
|
4
|
+
import { createSvgDataUri, serializeJavaScriptValue } from '../codegen'
|
|
5
|
+
import { mustBeDefined } from '../utils'
|
|
5
6
|
|
|
6
7
|
async function main() {
|
|
7
8
|
mustBeDefined(process.env.SOURCE_ROOT_DIR, 'SOURCE_ROOT_DIR')
|
|
@@ -20,48 +21,39 @@ async function main() {
|
|
|
20
21
|
|
|
21
22
|
return {
|
|
22
23
|
iconName: fileName.replace('.svg', ''),
|
|
23
|
-
uri:
|
|
24
|
-
"'",
|
|
25
|
-
"\\'",
|
|
26
|
-
)}`,
|
|
24
|
+
uri: createSvgDataUri(content),
|
|
27
25
|
isSetCurrentcolor: !content.includes('<def'),
|
|
28
26
|
}
|
|
29
27
|
}),
|
|
30
28
|
)
|
|
31
29
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
(it) =>
|
|
38
|
-
`'${it.iconName}': {uri: '${it.uri}', isSetCurrentcolor: ${
|
|
39
|
-
it.isSetCurrentcolor ? 'true' : 'false'
|
|
40
|
-
}}`,
|
|
30
|
+
const dataUriMap = Object.fromEntries(
|
|
31
|
+
dataUris.map(({ iconName, uri, isSetCurrentcolor }) => [
|
|
32
|
+
iconName,
|
|
33
|
+
{ uri, isSetCurrentcolor },
|
|
34
|
+
]),
|
|
41
35
|
)
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
|
|
37
|
+
const js = `/** This file is auto generated. DO NOT EDIT BY HAND. */
|
|
38
|
+
|
|
39
|
+
export default ${serializeJavaScriptValue(dataUriMap)}
|
|
40
|
+
`
|
|
44
41
|
await writeFile(path.join(outDir, 'index.mjs'), js)
|
|
45
42
|
|
|
46
43
|
const cjs = `/** This file is auto generated. DO NOT EDIT BY HAND. */
|
|
47
|
-
|
|
48
|
-
module.exports = {
|
|
49
|
-
|
|
50
|
-
.map(
|
|
51
|
-
(it) =>
|
|
52
|
-
`'${it.iconName}': {uri: '${it.uri}', isSetCurrentcolor: ${
|
|
53
|
-
it.isSetCurrentcolor ? 'true' : 'false'
|
|
54
|
-
}}`,
|
|
55
|
-
)
|
|
56
|
-
.join(',\n')}
|
|
57
|
-
}`
|
|
44
|
+
|
|
45
|
+
module.exports = ${serializeJavaScriptValue(dataUriMap)}
|
|
46
|
+
`
|
|
58
47
|
await writeFile(path.join(outDir, 'index.cjs'), cjs)
|
|
59
48
|
|
|
60
49
|
const dts = `/** This file is auto generated. DO NOT EDIT BY HAND. */
|
|
61
50
|
|
|
62
51
|
declare var _default: {
|
|
63
52
|
${dataUris
|
|
64
|
-
.map(
|
|
53
|
+
.map(
|
|
54
|
+
(it) =>
|
|
55
|
+
`${serializeJavaScriptValue(it.iconName)}: { uri: string, isSetCurrentcolor: boolean }`,
|
|
56
|
+
)
|
|
65
57
|
.join(';\n')}}
|
|
66
58
|
export default _default;
|
|
67
59
|
`
|