forked from antfu/starter-ts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
executable file
·133 lines (121 loc) · 3.35 KB
/
index.js
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env node
// @refer https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js
const path = require('path')
const fs = require('fs-extra')
const prompts = require('prompts')
const {
// yellow,
// green,
cyan,
// blue,
// magenta,
// lightRed,
red,
reset
} = require('kolorist')
const pkg = require('./package.json')
let targetDir = process.argv[2]
const defaultProjectName = !targetDir ? pkg.name : targetDir
function isEmpty(path) {
return fs.readdirSync(path).length === 0
}
function emptyDir(dir) {
if (!fs.existsSync(dir)) {
return
}
for (const file of fs.readdirSync(dir)) {
const abs = path.resolve(dir, file)
// baseline is Node 12 so can't use rmSync :(
if (fs.lstatSync(abs).isDirectory()) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
emptyDir(abs)
fs.rmdirSync(abs)
} else {
fs.unlinkSync(abs)
}
}
}
function isValidPackageName(projectName) {
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(
projectName
)
}
function toValidPackageName(projectName) {
return projectName
.trim()
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/^[._]/, '')
.replace(/[^a-z0-9-~]+/g, '-')
}
async function init() {
const res = await prompts([
{
type: targetDir ? null : 'text',
name: 'projectName',
message: reset('Project name:'),
initial: defaultProjectName,
onState: state =>
(targetDir = state.value.trim() || defaultProjectName)
},
{
type: () =>
!fs.existsSync(targetDir) || isEmpty(targetDir) ? null : 'toggle',
name: 'overwrite',
message: () =>
`${targetDir === '.'
? 'Current directory'
: `Target directory "${targetDir}"`
} is not empty. Remove existing files and continue?`,
initial: false,
active: 'yes',
inactive: 'no'
},
{
type: (_, { overwrite } = {}) => {
if (overwrite === false) {
throw new Error(`${red('✖')} Operation cancelled`)
}
return null
},
name: 'overwriteChecker'
},
{
type: () => (isValidPackageName(targetDir) ? null : 'text'),
name: 'packageName',
message: reset('Package name:'),
initial: () => toValidPackageName(targetDir),
validate: dir =>
isValidPackageName(dir) || 'Invalid package.json name'
},
{
onCancel: () => {
throw new Error(`${red('✖')} Operation cancelled`)
}
}
])
const packageName = res.packageName || targetDir
if (res.overwrite) {
emptyDir(path.join(process.cwd(), targetDir))
}
if (!res.projectName && (!process.argv[2])) {
throw new Error(`${red('✖')} Operation cancelled`)
}
fs.copy(path.resolve(__dirname, './template'), packageName, () => {
// regenerate package.json
pkg.name = packageName
pkg.version = '0.0.0'
pkg.homepage = pkg.homepage.replace('create-wn-ts', '[repo]')
pkg.bugs.url = pkg.bugs.url.replace('create-wn-ts', '[repo]')
pkg.repository.url = pkg.repository.url.replace('create-wn-ts', '[repo]')
fs.writeFileSync(path.resolve(__dirname, './template/package.json'), JSON.stringify(pkg, null, 2))
console.log(cyan(`
project ${packageName} success created
cd ${packageName}
npm install
`))
})
}
init().catch((err) => {
console.log(red(err))
})