-
Notifications
You must be signed in to change notification settings - Fork 8
/
builder.ts
90 lines (79 loc) 路 2.94 KB
/
builder.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* eslint-disable no-console */
import { readdir, readFile, stat, writeFile } from 'fs'
import { extname, basename, resolve } from 'path'
import { promisify } from 'util'
import * as prettier from 'prettier'
// @ts-ignore
import * as htm from 'htm'
function toHump(name: string, capitalized: boolean = true): string {
return capitalized
? name
.replace(/-(\w)/g, (all, letter): string => letter.toUpperCase())
.replace(/( |^)[a-z]/g, (all): string => all.toUpperCase())
: name.replace(/-(\w)/g, (all, letter): string => letter.toUpperCase())
}
function h(type: string, props: any, ...children: any[]): any {
const allPropKey = props ? Object.keys(props) : []
const match = allPropKey.find((prop): boolean => prop.includes('-'))
if (match) {
props[toHump(match, false)] = props[match]
delete props[match]
}
return { type, props, children }
}
const html = htm.bind(h)
const readdirAsync = promisify(readdir)
const readFileAsync = promisify(readFile)
const writeFileAsync = promisify(writeFile)
const statAsync = promisify(stat)
const basePath = resolve(__dirname, './remix')
function toJson(data: object): string {
return JSON.stringify(data, null, '\t')
}
async function getAllSvgs(dir: string): Promise<string[]> {
const files = await readdirAsync(dir)
const allFiles = await Promise.all(
files.map(
(file): Promise<Promise<string[]> | string> => {
const path = resolve(dir, file)
// @ts-ignore
return statAsync(path).then((stat): Promise<string[]> | string => {
return stat.isDirectory() ? getAllSvgs(path) : path
})
}
)
)
return Array.prototype.concat(...allFiles).filter((file): boolean => extname(file) === '.svg')
}
function getComponentName(fileName: string, withSuffix: boolean): string {
return withSuffix ? basename(fileName) : basename(fileName).split('.')[0]
}
async function worker(): Promise<void> {
try {
const allSvg = await getAllSvgs(basePath)
const template = await readFileAsync(resolve(__dirname, './template'), { encoding: 'utf8' })
for (const svg of allSvg) {
const data = await readFileAsync(svg, { encoding: 'utf8' })
const jsx = html([data])
const componentName = getComponentName(svg, false)
const jsxReplace = template
.replace('{{jsx}}', toJson(jsx))
.replace('{{componentName}}', toHump(componentName))
await writeFileAsync(
resolve(__dirname, `src/${toHump(componentName)}.ts`),
prettier.format(jsxReplace, { singleQuote: true, semi: false, parser: 'typescript' })
)
}
const index = allSvg.reduce((acc, cur): string => {
const componentName = getComponentName(cur, false)
return (
acc + `export { default as ${toHump(componentName)} } from './${toHump(componentName)}'\n`
)
}, '')
await writeFileAsync(resolve(__dirname, `src/index.ts`), index)
} catch (error) {
console.error(error)
process.exit(1)
}
}
worker()