reset-framework-cli 1.2.2 → 1.2.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.
Files changed (35) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +25 -25
  3. package/package.json +7 -7
  4. package/src/commands/build.js +144 -144
  5. package/src/commands/dev.js +195 -195
  6. package/src/commands/doctor.js +140 -140
  7. package/src/commands/init.js +946 -946
  8. package/src/commands/package.js +68 -68
  9. package/src/index.js +195 -195
  10. package/src/lib/backend.js +123 -123
  11. package/src/lib/context.js +66 -66
  12. package/src/lib/framework.js +57 -57
  13. package/src/lib/logger.js +11 -11
  14. package/src/lib/output.js +283 -283
  15. package/src/lib/process.js +303 -303
  16. package/src/lib/project.js +893 -866
  17. package/src/lib/toolchain.js +62 -62
  18. package/src/lib/ui.js +244 -244
  19. package/templates/basic/README.md +15 -15
  20. package/templates/basic/frontend/README.md +73 -73
  21. package/templates/basic/frontend/eslint.config.js +23 -23
  22. package/templates/basic/frontend/index.html +13 -13
  23. package/templates/basic/frontend/package.json +31 -31
  24. package/templates/basic/frontend/public/icons.svg +24 -24
  25. package/templates/basic/frontend/src/App.css +216 -216
  26. package/templates/basic/frontend/src/App.tsx +77 -77
  27. package/templates/basic/frontend/src/assets/vite.svg +1 -1
  28. package/templates/basic/frontend/src/index.css +111 -111
  29. package/templates/basic/frontend/src/lib/reset.ts +1 -1
  30. package/templates/basic/frontend/src/main.tsx +10 -10
  31. package/templates/basic/frontend/tsconfig.app.json +28 -28
  32. package/templates/basic/frontend/tsconfig.json +7 -7
  33. package/templates/basic/frontend/tsconfig.node.json +26 -26
  34. package/templates/basic/frontend/vite.config.ts +16 -16
  35. package/templates/basic/reset.config.json +58 -58
@@ -1,303 +1,303 @@
1
- import { spawn, spawnSync } 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
- export function formatCommand(command, args = []) {
48
- return [command, ...args].join(" ")
49
- }
50
-
51
- function shouldUseShell(command) {
52
- return process.platform === "win32" && typeof command === "string" && /\.(cmd|bat)$/i.test(command)
53
- }
54
-
55
- export async function runCommand(command, args = [], options = {}) {
56
- const { cwd, dryRun = false, env } = options
57
-
58
- logger.info(`$ ${formatCommand(command, args)}`)
59
-
60
- if (dryRun) {
61
- return
62
- }
63
-
64
- await new Promise((resolve, reject) => {
65
- const child = spawn(command, args, {
66
- cwd,
67
- env: env ? { ...process.env, ...env } : process.env,
68
- stdio: "inherit",
69
- shell: shouldUseShell(command)
70
- })
71
-
72
- child.once("error", reject)
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
-
95
- return await new Promise((resolve, reject) => {
96
- const child = spawn(command, args, {
97
- cwd,
98
- env: env ? { ...process.env, ...env } : process.env,
99
- stdio: ["ignore", "pipe", "pipe"],
100
- shell: shouldUseShell(command)
101
- })
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
-
141
- return spawn(command, args, {
142
- cwd,
143
- env: env ? { ...process.env, ...env } : process.env,
144
- detached: process.platform !== "win32",
145
- stdio: "inherit",
146
- shell: shouldUseShell(command)
147
- })
148
- }
149
-
150
- export function waitForProcessExit(child, label) {
151
- return new Promise((resolve, reject) => {
152
- child.once("error", reject)
153
- child.once("exit", (code, signal) => {
154
- if (code === 0 || signal === "SIGINT" || signal === "SIGTERM") {
155
- resolve(undefined)
156
- return
157
- }
158
-
159
- reject(
160
- new Error(
161
- signal
162
- ? `${label} terminated by signal: ${signal}`
163
- : `${label} exited with code ${code}`
164
- )
165
- )
166
- })
167
- })
168
- }
169
-
170
- export function registerChildCleanup(children) {
171
- const activeChildren = children.filter(Boolean)
172
- let cleanupPromise = null
173
-
174
- const waitForChildExit = (child, timeoutMs = 3000) =>
175
- new Promise((resolve) => {
176
- if (!child || child.exitCode !== null || child.signalCode !== null) {
177
- resolve(true)
178
- return
179
- }
180
-
181
- const handleExit = () => {
182
- clearTimeout(timeout)
183
- child.off("error", handleError)
184
- resolve(true)
185
- }
186
-
187
- const handleError = () => {
188
- clearTimeout(timeout)
189
- child.off("exit", handleExit)
190
- resolve(true)
191
- }
192
-
193
- const timeout = setTimeout(() => {
194
- child.off("exit", handleExit)
195
- child.off("error", handleError)
196
- resolve(false)
197
- }, timeoutMs)
198
-
199
- child.once("exit", handleExit)
200
- child.once("error", handleError)
201
- })
202
-
203
- const terminateChild = async (child) => {
204
- if (!child || child.pid == null || child.exitCode !== null || child.signalCode !== null) {
205
- return
206
- }
207
-
208
- if (process.platform === "win32") {
209
- const result = spawnSync("taskkill.exe", ["/pid", String(child.pid), "/t", "/f"], {
210
- stdio: "ignore",
211
- windowsHide: true
212
- })
213
-
214
- if (result.status !== 0 && child.exitCode === null && child.signalCode === null) {
215
- try {
216
- child.kill("SIGTERM")
217
- } catch {
218
- // Ignore late shutdown races.
219
- }
220
- }
221
-
222
- await waitForChildExit(child, 2000)
223
- return
224
- }
225
-
226
- try {
227
- process.kill(-child.pid, "SIGTERM")
228
- } catch (error) {
229
- if (error?.code !== "ESRCH") {
230
- try {
231
- child.kill("SIGTERM")
232
- } catch {
233
- // Ignore late shutdown races.
234
- }
235
- }
236
- }
237
-
238
- if (await waitForChildExit(child, 3000)) {
239
- return
240
- }
241
-
242
- try {
243
- process.kill(-child.pid, "SIGKILL")
244
- } catch (error) {
245
- if (error?.code !== "ESRCH") {
246
- try {
247
- child.kill("SIGKILL")
248
- } catch {
249
- // Ignore late shutdown races.
250
- }
251
- }
252
- }
253
-
254
- await waitForChildExit(child, 1000)
255
- }
256
-
257
- const cleanup = async () => {
258
- if (cleanupPromise) {
259
- return cleanupPromise
260
- }
261
-
262
- cleanupPromise = (async () => {
263
- await Promise.all(activeChildren.map((child) => terminateChild(child)))
264
- })()
265
-
266
- return cleanupPromise
267
- }
268
-
269
- const handleSignal = () => {
270
- void cleanup().finally(() => {
271
- process.exit(0)
272
- })
273
- }
274
-
275
- process.on("SIGINT", handleSignal)
276
- process.on("SIGTERM", handleSignal)
277
-
278
- return async () => {
279
- process.off("SIGINT", handleSignal)
280
- process.off("SIGTERM", handleSignal)
281
- await cleanup()
282
- }
283
- }
284
-
285
- export async function waitForUrl(url, options = {}) {
286
- const { intervalMs = 250, timeoutMs = 15000 } = options
287
- const deadline = Date.now() + timeoutMs
288
-
289
- while (Date.now() < deadline) {
290
- try {
291
- const response = await fetch(url)
292
- if (response.status < 500) {
293
- return
294
- }
295
- } catch {
296
- // Retry until timeout.
297
- }
298
-
299
- await sleep(intervalMs)
300
- }
301
-
302
- throw new Error(`Timed out waiting for ${url}`)
303
- }
1
+ import { spawn, spawnSync } 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
+ export function formatCommand(command, args = []) {
48
+ return [command, ...args].join(" ")
49
+ }
50
+
51
+ function shouldUseShell(command) {
52
+ return process.platform === "win32" && typeof command === "string" && /\.(cmd|bat)$/i.test(command)
53
+ }
54
+
55
+ export async function runCommand(command, args = [], options = {}) {
56
+ const { cwd, dryRun = false, env } = options
57
+
58
+ logger.info(`$ ${formatCommand(command, args)}`)
59
+
60
+ if (dryRun) {
61
+ return
62
+ }
63
+
64
+ await new Promise((resolve, reject) => {
65
+ const child = spawn(command, args, {
66
+ cwd,
67
+ env: env ? { ...process.env, ...env } : process.env,
68
+ stdio: "inherit",
69
+ shell: shouldUseShell(command)
70
+ })
71
+
72
+ child.once("error", reject)
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
+
95
+ return await new Promise((resolve, reject) => {
96
+ const child = spawn(command, args, {
97
+ cwd,
98
+ env: env ? { ...process.env, ...env } : process.env,
99
+ stdio: ["ignore", "pipe", "pipe"],
100
+ shell: shouldUseShell(command)
101
+ })
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
+
141
+ return spawn(command, args, {
142
+ cwd,
143
+ env: env ? { ...process.env, ...env } : process.env,
144
+ detached: process.platform !== "win32",
145
+ stdio: "inherit",
146
+ shell: shouldUseShell(command)
147
+ })
148
+ }
149
+
150
+ export function waitForProcessExit(child, label) {
151
+ return new Promise((resolve, reject) => {
152
+ child.once("error", reject)
153
+ child.once("exit", (code, signal) => {
154
+ if (code === 0 || signal === "SIGINT" || signal === "SIGTERM") {
155
+ resolve(undefined)
156
+ return
157
+ }
158
+
159
+ reject(
160
+ new Error(
161
+ signal
162
+ ? `${label} terminated by signal: ${signal}`
163
+ : `${label} exited with code ${code}`
164
+ )
165
+ )
166
+ })
167
+ })
168
+ }
169
+
170
+ export function registerChildCleanup(children) {
171
+ const activeChildren = children.filter(Boolean)
172
+ let cleanupPromise = null
173
+
174
+ const waitForChildExit = (child, timeoutMs = 3000) =>
175
+ new Promise((resolve) => {
176
+ if (!child || child.exitCode !== null || child.signalCode !== null) {
177
+ resolve(true)
178
+ return
179
+ }
180
+
181
+ const handleExit = () => {
182
+ clearTimeout(timeout)
183
+ child.off("error", handleError)
184
+ resolve(true)
185
+ }
186
+
187
+ const handleError = () => {
188
+ clearTimeout(timeout)
189
+ child.off("exit", handleExit)
190
+ resolve(true)
191
+ }
192
+
193
+ const timeout = setTimeout(() => {
194
+ child.off("exit", handleExit)
195
+ child.off("error", handleError)
196
+ resolve(false)
197
+ }, timeoutMs)
198
+
199
+ child.once("exit", handleExit)
200
+ child.once("error", handleError)
201
+ })
202
+
203
+ const terminateChild = async (child) => {
204
+ if (!child || child.pid == null || child.exitCode !== null || child.signalCode !== null) {
205
+ return
206
+ }
207
+
208
+ if (process.platform === "win32") {
209
+ const result = spawnSync("taskkill.exe", ["/pid", String(child.pid), "/t", "/f"], {
210
+ stdio: "ignore",
211
+ windowsHide: true
212
+ })
213
+
214
+ if (result.status !== 0 && child.exitCode === null && child.signalCode === null) {
215
+ try {
216
+ child.kill("SIGTERM")
217
+ } catch {
218
+ // Ignore late shutdown races.
219
+ }
220
+ }
221
+
222
+ await waitForChildExit(child, 2000)
223
+ return
224
+ }
225
+
226
+ try {
227
+ process.kill(-child.pid, "SIGTERM")
228
+ } catch (error) {
229
+ if (error?.code !== "ESRCH") {
230
+ try {
231
+ child.kill("SIGTERM")
232
+ } catch {
233
+ // Ignore late shutdown races.
234
+ }
235
+ }
236
+ }
237
+
238
+ if (await waitForChildExit(child, 3000)) {
239
+ return
240
+ }
241
+
242
+ try {
243
+ process.kill(-child.pid, "SIGKILL")
244
+ } catch (error) {
245
+ if (error?.code !== "ESRCH") {
246
+ try {
247
+ child.kill("SIGKILL")
248
+ } catch {
249
+ // Ignore late shutdown races.
250
+ }
251
+ }
252
+ }
253
+
254
+ await waitForChildExit(child, 1000)
255
+ }
256
+
257
+ const cleanup = async () => {
258
+ if (cleanupPromise) {
259
+ return cleanupPromise
260
+ }
261
+
262
+ cleanupPromise = (async () => {
263
+ await Promise.all(activeChildren.map((child) => terminateChild(child)))
264
+ })()
265
+
266
+ return cleanupPromise
267
+ }
268
+
269
+ const handleSignal = () => {
270
+ void cleanup().finally(() => {
271
+ process.exit(0)
272
+ })
273
+ }
274
+
275
+ process.on("SIGINT", handleSignal)
276
+ process.on("SIGTERM", handleSignal)
277
+
278
+ return async () => {
279
+ process.off("SIGINT", handleSignal)
280
+ process.off("SIGTERM", handleSignal)
281
+ await cleanup()
282
+ }
283
+ }
284
+
285
+ export async function waitForUrl(url, options = {}) {
286
+ const { intervalMs = 250, timeoutMs = 15000 } = options
287
+ const deadline = Date.now() + timeoutMs
288
+
289
+ while (Date.now() < deadline) {
290
+ try {
291
+ const response = await fetch(url)
292
+ if (response.status < 500) {
293
+ return
294
+ }
295
+ } catch {
296
+ // Retry until timeout.
297
+ }
298
+
299
+ await sleep(intervalMs)
300
+ }
301
+
302
+ throw new Error(`Timed out waiting for ${url}`)
303
+ }