create-murasaki 0.0.2 → 0.0.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/index.mjs +44 -2
- package/package.json +1 -1
- package/templates/default/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { existsSync } from 'node:fs'
|
|
|
7
7
|
import { dirname, join, resolve } from 'node:path'
|
|
8
8
|
import { fileURLToPath } from 'node:url'
|
|
9
9
|
import { createInterface } from 'node:readline/promises'
|
|
10
|
+
import { spawnSync } from 'node:child_process'
|
|
10
11
|
|
|
11
12
|
// ── ANSI truecolor (Oomurasaki palette) ────────────────────────────────
|
|
12
13
|
const BRIGHT = '\x1b[38;2;168;85;247m'
|
|
@@ -106,6 +107,31 @@ function isValidPackageName(name) {
|
|
|
106
107
|
return /^[a-z0-9][a-z0-9._-]*$/.test(name)
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
// ── Package manager detection ─────────────────────────────────────────
|
|
111
|
+
function detectPackageManager() {
|
|
112
|
+
const ua = process.env.npm_config_user_agent || ''
|
|
113
|
+
if (ua.startsWith('pnpm')) return 'pnpm'
|
|
114
|
+
if (ua.startsWith('yarn')) return 'yarn'
|
|
115
|
+
if (ua.startsWith('bun')) return 'bun'
|
|
116
|
+
return 'npm'
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function installArgs(pm) {
|
|
120
|
+
// pnpm respects parent workspace by default; --ignore-workspace makes the
|
|
121
|
+
// new app's install self-contained even when scaffolded inside a workspace.
|
|
122
|
+
if (pm === 'pnpm') return ['install', '--ignore-workspace']
|
|
123
|
+
return ['install']
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function runInstall(targetDir, pm) {
|
|
127
|
+
const result = spawnSync(pm, installArgs(pm), {
|
|
128
|
+
cwd: targetDir,
|
|
129
|
+
stdio: 'inherit',
|
|
130
|
+
shell: process.platform === 'win32',
|
|
131
|
+
})
|
|
132
|
+
return result.status === 0
|
|
133
|
+
}
|
|
134
|
+
|
|
109
135
|
async function promptForName() {
|
|
110
136
|
const rl = createInterface({ input: process.stdin, output: process.stdout })
|
|
111
137
|
const answer = await rl.question(` ${c(DEEP)}?${c(RESET)} ${c(BOLD)}Project name${c(RESET)} ${c(DIM)}(my-app):${c(RESET)} `)
|
|
@@ -143,12 +169,28 @@ async function scaffold(projectName) {
|
|
|
143
169
|
|
|
144
170
|
log(` ${c(GREEN)}${c(BOLD)}✓${c(RESET)} Created ${c(BOLD)}${projectName}/${c(RESET)}`)
|
|
145
171
|
|
|
172
|
+
// Install dependencies (Next.js-like behavior)
|
|
173
|
+
const pm = detectPackageManager()
|
|
174
|
+
const skip = process.argv.includes('--skip-install')
|
|
175
|
+
|
|
176
|
+
if (!skip) {
|
|
177
|
+
log(` ${c(DIM)}○${c(RESET)} Installing dependencies with ${c(BOLD)}${pm}${c(RESET)}...\n`)
|
|
178
|
+
const installStart = Date.now()
|
|
179
|
+
const ok = runInstall(targetDir, pm)
|
|
180
|
+
const elapsed = ((Date.now() - installStart) / 1000).toFixed(1)
|
|
181
|
+
if (ok) {
|
|
182
|
+
log(`\n ${c(GREEN)}${c(BOLD)}✓${c(RESET)} Dependencies installed ${c(DIM)}(${elapsed}s)${c(RESET)}`)
|
|
183
|
+
} else {
|
|
184
|
+
log(`\n ${c(RED)}✗${c(RESET)} ${pm} install failed; run ${c(BOLD)}${pm} install${c(RESET)} manually inside ${c(BOLD)}${projectName}/${c(RESET)}`)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
146
188
|
// Next steps
|
|
189
|
+
const runner = pm === 'npm' ? 'npm run dev' : `${pm} dev`
|
|
147
190
|
log(`
|
|
148
191
|
${c(DIM)}Next:${c(RESET)}
|
|
149
192
|
${c(BRIGHT)}cd${c(RESET)} ${projectName}
|
|
150
|
-
${c(BRIGHT)}
|
|
151
|
-
${c(BRIGHT)}npm run dev${c(RESET)} ${c(DIM)}# starts the desktop window with HMR${c(RESET)}
|
|
193
|
+
${c(BRIGHT)}${runner}${c(RESET)} ${c(DIM)}# starts the desktop window with HMR${c(RESET)}
|
|
152
194
|
|
|
153
195
|
${c(DIM)}docs${c(RESET)} ${c(DIM)}https://github.com/murasakijs/murasaki${c(RESET)}
|
|
154
196
|
`)
|
package/package.json
CHANGED