reset-framework-cli 1.1.2 → 1.1.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/LICENSE +20 -20
- package/README.md +47 -47
- package/package.json +4 -4
- package/src/commands/build.js +114 -113
- package/src/commands/dev.js +157 -153
- package/src/commands/doctor.js +89 -89
- package/src/commands/init.js +925 -920
- package/src/commands/package.js +49 -44
- package/src/index.js +213 -213
- package/src/lib/context.js +66 -66
- package/src/lib/framework.js +150 -28
- package/src/lib/logger.js +11 -11
- package/src/lib/output.js +214 -106
- package/src/lib/process.js +188 -181
- package/src/lib/project.js +559 -475
- package/src/lib/toolchain.js +62 -62
- package/src/lib/ui.js +244 -244
- package/templates/basic/README.md +15 -15
- package/templates/basic/frontend/README.md +73 -73
- package/templates/basic/frontend/eslint.config.js +23 -23
- package/templates/basic/frontend/index.html +13 -13
- package/templates/basic/frontend/package.json +31 -31
- package/templates/basic/frontend/public/icons.svg +24 -24
- package/templates/basic/frontend/src/App.css +216 -138
- package/templates/basic/frontend/src/App.tsx +77 -76
- package/templates/basic/frontend/src/assets/vite.svg +1 -1
- package/templates/basic/frontend/src/index.css +111 -111
- package/templates/basic/frontend/src/lib/reset.ts +1 -1
- package/templates/basic/frontend/src/main.tsx +10 -10
- package/templates/basic/frontend/tsconfig.app.json +28 -28
- package/templates/basic/frontend/tsconfig.json +7 -7
- package/templates/basic/frontend/tsconfig.node.json +26 -26
- package/templates/basic/frontend/vite.config.ts +16 -16
- package/templates/basic/reset.config.json +58 -58
package/src/lib/process.js
CHANGED
|
@@ -1,206 +1,213 @@
|
|
|
1
|
-
import { spawn } from "node:child_process"
|
|
2
|
-
|
|
3
|
-
import { logger } from "./logger.js"
|
|
4
|
-
|
|
5
|
-
function sleep(ms) {
|
|
6
|
-
return new Promise((resolve) => {
|
|
7
|
-
setTimeout(resolve, ms)
|
|
8
|
-
})
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function resolveNpmCommand() {
|
|
12
|
-
return process.platform === "win32" ? "npm.cmd" : "npm"
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function resolvePackageManagerCommand(packageManager = "npm") {
|
|
16
|
-
if (packageManager === "npm") {
|
|
17
|
-
return resolveNpmCommand()
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (packageManager === "yarn") {
|
|
21
|
-
return process.platform === "win32" ? "yarn.cmd" : "yarn"
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (packageManager === "pnpm") {
|
|
25
|
-
return process.platform === "win32" ? "pnpm.cmd" : "pnpm"
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (packageManager === "bun") {
|
|
29
|
-
return process.platform === "win32" ? "bun.exe" : "bun"
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
throw new Error(`Unsupported package manager: ${packageManager}`)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function getInstallCommandArgs(packageManager = "npm") {
|
|
36
|
-
if (packageManager === "npm") {
|
|
37
|
-
return ["install", "--include=optional"]
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (packageManager === "yarn") {
|
|
41
|
-
return ["install"]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return ["install"]
|
|
45
|
-
}
|
|
46
|
-
|
|
1
|
+
import { spawn } from "node:child_process"
|
|
2
|
+
|
|
3
|
+
import { logger } from "./logger.js"
|
|
4
|
+
|
|
5
|
+
function sleep(ms) {
|
|
6
|
+
return new Promise((resolve) => {
|
|
7
|
+
setTimeout(resolve, ms)
|
|
8
|
+
})
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function resolveNpmCommand() {
|
|
12
|
+
return process.platform === "win32" ? "npm.cmd" : "npm"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function resolvePackageManagerCommand(packageManager = "npm") {
|
|
16
|
+
if (packageManager === "npm") {
|
|
17
|
+
return resolveNpmCommand()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (packageManager === "yarn") {
|
|
21
|
+
return process.platform === "win32" ? "yarn.cmd" : "yarn"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (packageManager === "pnpm") {
|
|
25
|
+
return process.platform === "win32" ? "pnpm.cmd" : "pnpm"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (packageManager === "bun") {
|
|
29
|
+
return process.platform === "win32" ? "bun.exe" : "bun"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
throw new Error(`Unsupported package manager: ${packageManager}`)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getInstallCommandArgs(packageManager = "npm") {
|
|
36
|
+
if (packageManager === "npm") {
|
|
37
|
+
return ["install", "--include=optional"]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (packageManager === "yarn") {
|
|
41
|
+
return ["install"]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return ["install"]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
47
|
export function formatCommand(command, args = []) {
|
|
48
48
|
return [command, ...args].join(" ")
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
function shouldUseShell(command) {
|
|
52
|
+
return process.platform === "win32" && typeof command === "string" && /\.(cmd|bat)$/i.test(command)
|
|
53
|
+
}
|
|
54
|
+
|
|
51
55
|
export async function runCommand(command, args = [], options = {}) {
|
|
52
56
|
const { cwd, dryRun = false, env } = options
|
|
53
57
|
|
|
54
58
|
logger.info(`$ ${formatCommand(command, args)}`)
|
|
55
|
-
|
|
56
|
-
if (dryRun) {
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
|
|
59
|
+
|
|
60
|
+
if (dryRun) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
60
64
|
await new Promise((resolve, reject) => {
|
|
61
65
|
const child = spawn(command, args, {
|
|
62
66
|
cwd,
|
|
63
67
|
env: env ? { ...process.env, ...env } : process.env,
|
|
64
|
-
stdio: "inherit"
|
|
68
|
+
stdio: "inherit",
|
|
69
|
+
shell: shouldUseShell(command)
|
|
65
70
|
})
|
|
66
71
|
|
|
67
72
|
child.once("error", reject)
|
|
68
|
-
child.once("exit", (code, signal) => {
|
|
69
|
-
if (code === 0) {
|
|
70
|
-
resolve(undefined)
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
reject(
|
|
75
|
-
new Error(
|
|
76
|
-
signal
|
|
77
|
-
? `Command terminated by signal: ${signal}`
|
|
78
|
-
: `Command exited with code ${code}`
|
|
79
|
-
)
|
|
80
|
-
)
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export async function captureCommandOutput(command, args = [], options = {}) {
|
|
86
|
-
const { cwd, env } = options
|
|
87
|
-
|
|
88
|
-
await Promise.resolve()
|
|
89
|
-
|
|
73
|
+
child.once("exit", (code, signal) => {
|
|
74
|
+
if (code === 0) {
|
|
75
|
+
resolve(undefined)
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
reject(
|
|
80
|
+
new Error(
|
|
81
|
+
signal
|
|
82
|
+
? `Command terminated by signal: ${signal}`
|
|
83
|
+
: `Command exited with code ${code}`
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export async function captureCommandOutput(command, args = [], options = {}) {
|
|
91
|
+
const { cwd, env } = options
|
|
92
|
+
|
|
93
|
+
await Promise.resolve()
|
|
94
|
+
|
|
90
95
|
return await new Promise((resolve, reject) => {
|
|
91
96
|
const child = spawn(command, args, {
|
|
92
97
|
cwd,
|
|
93
98
|
env: env ? { ...process.env, ...env } : process.env,
|
|
94
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
let stdout = ""
|
|
98
|
-
let stderr = ""
|
|
99
|
-
|
|
100
|
-
child.stdout?.on("data", (chunk) => {
|
|
101
|
-
stdout += String(chunk)
|
|
99
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
100
|
+
shell: shouldUseShell(command)
|
|
102
101
|
})
|
|
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
|
-
|
|
134
|
-
|
|
102
|
+
|
|
103
|
+
let stdout = ""
|
|
104
|
+
let stderr = ""
|
|
105
|
+
|
|
106
|
+
child.stdout?.on("data", (chunk) => {
|
|
107
|
+
stdout += String(chunk)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
child.stderr?.on("data", (chunk) => {
|
|
111
|
+
stderr += String(chunk)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
child.once("error", reject)
|
|
115
|
+
child.once("exit", (code, signal) => {
|
|
116
|
+
if (code === 0) {
|
|
117
|
+
resolve(stdout.trim())
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
reject(
|
|
122
|
+
new Error(
|
|
123
|
+
signal
|
|
124
|
+
? `Command terminated by signal: ${signal}`
|
|
125
|
+
: (stderr.trim() || stdout.trim() || `Command exited with code ${code}`)
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function spawnCommand(command, args = [], options = {}) {
|
|
133
|
+
const { cwd, dryRun = false, env } = options
|
|
134
|
+
|
|
135
|
+
logger.info(`$ ${formatCommand(command, args)}`)
|
|
136
|
+
|
|
137
|
+
if (dryRun) {
|
|
138
|
+
return null
|
|
139
|
+
}
|
|
140
|
+
|
|
135
141
|
return spawn(command, args, {
|
|
136
142
|
cwd,
|
|
137
143
|
env: env ? { ...process.env, ...env } : process.env,
|
|
138
|
-
stdio: "inherit"
|
|
144
|
+
stdio: "inherit",
|
|
145
|
+
shell: shouldUseShell(command)
|
|
139
146
|
})
|
|
140
147
|
}
|
|
141
|
-
|
|
142
|
-
export function waitForProcessExit(child, label) {
|
|
143
|
-
return new Promise((resolve, reject) => {
|
|
144
|
-
child.once("error", reject)
|
|
145
|
-
child.once("exit", (code, signal) => {
|
|
146
|
-
if (code === 0 || signal === "SIGINT" || signal === "SIGTERM") {
|
|
147
|
-
resolve(undefined)
|
|
148
|
-
return
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
reject(
|
|
152
|
-
new Error(
|
|
153
|
-
signal
|
|
154
|
-
? `${label} terminated by signal: ${signal}`
|
|
155
|
-
: `${label} exited with code ${code}`
|
|
156
|
-
)
|
|
157
|
-
)
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export function registerChildCleanup(children) {
|
|
163
|
-
const activeChildren = children.filter(Boolean)
|
|
164
|
-
|
|
165
|
-
const cleanup = () => {
|
|
166
|
-
for (const child of activeChildren) {
|
|
167
|
-
if (child.exitCode === null && !child.killed) {
|
|
168
|
-
child.kill("SIGTERM")
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const handleSignal = () => {
|
|
174
|
-
cleanup()
|
|
175
|
-
process.exit(0)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
process.on("SIGINT", handleSignal)
|
|
179
|
-
process.on("SIGTERM", handleSignal)
|
|
180
|
-
|
|
181
|
-
return () => {
|
|
182
|
-
process.off("SIGINT", handleSignal)
|
|
183
|
-
process.off("SIGTERM", handleSignal)
|
|
184
|
-
cleanup()
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export async function waitForUrl(url, options = {}) {
|
|
189
|
-
const { intervalMs = 250, timeoutMs = 15000 } = options
|
|
190
|
-
const deadline = Date.now() + timeoutMs
|
|
191
|
-
|
|
192
|
-
while (Date.now() < deadline) {
|
|
193
|
-
try {
|
|
194
|
-
const response = await fetch(url)
|
|
195
|
-
if (response.status < 500) {
|
|
196
|
-
return
|
|
197
|
-
}
|
|
198
|
-
} catch {
|
|
199
|
-
// Retry until timeout.
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
await sleep(intervalMs)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
throw new Error(`Timed out waiting for ${url}`)
|
|
206
|
-
}
|
|
148
|
+
|
|
149
|
+
export function waitForProcessExit(child, label) {
|
|
150
|
+
return new Promise((resolve, reject) => {
|
|
151
|
+
child.once("error", reject)
|
|
152
|
+
child.once("exit", (code, signal) => {
|
|
153
|
+
if (code === 0 || signal === "SIGINT" || signal === "SIGTERM") {
|
|
154
|
+
resolve(undefined)
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
reject(
|
|
159
|
+
new Error(
|
|
160
|
+
signal
|
|
161
|
+
? `${label} terminated by signal: ${signal}`
|
|
162
|
+
: `${label} exited with code ${code}`
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
})
|
|
166
|
+
})
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function registerChildCleanup(children) {
|
|
170
|
+
const activeChildren = children.filter(Boolean)
|
|
171
|
+
|
|
172
|
+
const cleanup = () => {
|
|
173
|
+
for (const child of activeChildren) {
|
|
174
|
+
if (child.exitCode === null && !child.killed) {
|
|
175
|
+
child.kill("SIGTERM")
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const handleSignal = () => {
|
|
181
|
+
cleanup()
|
|
182
|
+
process.exit(0)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
process.on("SIGINT", handleSignal)
|
|
186
|
+
process.on("SIGTERM", handleSignal)
|
|
187
|
+
|
|
188
|
+
return () => {
|
|
189
|
+
process.off("SIGINT", handleSignal)
|
|
190
|
+
process.off("SIGTERM", handleSignal)
|
|
191
|
+
cleanup()
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export async function waitForUrl(url, options = {}) {
|
|
196
|
+
const { intervalMs = 250, timeoutMs = 15000 } = options
|
|
197
|
+
const deadline = Date.now() + timeoutMs
|
|
198
|
+
|
|
199
|
+
while (Date.now() < deadline) {
|
|
200
|
+
try {
|
|
201
|
+
const response = await fetch(url)
|
|
202
|
+
if (response.status < 500) {
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
} catch {
|
|
206
|
+
// Retry until timeout.
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await sleep(intervalMs)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
throw new Error(`Timed out waiting for ${url}`)
|
|
213
|
+
}
|