create-sonicjs 2.0.0-beta.6 → 2.0.0-beta.8
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/package.json +1 -1
- package/src/cli.js +129 -22
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import validatePackageName from 'validate-npm-package-name'
|
|
|
12
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
13
13
|
|
|
14
14
|
// Version
|
|
15
|
-
const VERSION = '2.0.0-beta.
|
|
15
|
+
const VERSION = '2.0.0-beta.8'
|
|
16
16
|
|
|
17
17
|
// Templates available
|
|
18
18
|
const TEMPLATES = {
|
|
@@ -135,9 +135,17 @@ async function getProjectDetails(initialName) {
|
|
|
135
135
|
})
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
//
|
|
138
|
+
// Seed admin user
|
|
139
139
|
questions.push({
|
|
140
|
-
type: '
|
|
140
|
+
type: 'confirm',
|
|
141
|
+
name: 'seedAdmin',
|
|
142
|
+
message: 'Create admin user?',
|
|
143
|
+
initial: true
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
// Admin email (only if seeding)
|
|
147
|
+
questions.push({
|
|
148
|
+
type: (prev, values) => values.seedAdmin ? 'text' : null,
|
|
141
149
|
name: 'adminEmail',
|
|
142
150
|
message: 'Admin email:',
|
|
143
151
|
validate: (value) => {
|
|
@@ -149,9 +157,9 @@ async function getProjectDetails(initialName) {
|
|
|
149
157
|
}
|
|
150
158
|
})
|
|
151
159
|
|
|
152
|
-
// Admin password
|
|
160
|
+
// Admin password (only if seeding)
|
|
153
161
|
questions.push({
|
|
154
|
-
type: 'password',
|
|
162
|
+
type: (prev, values) => values.seedAdmin ? 'password' : null,
|
|
155
163
|
name: 'adminPassword',
|
|
156
164
|
message: 'Admin password:',
|
|
157
165
|
validate: (value) => {
|
|
@@ -202,10 +210,12 @@ async function getProjectDetails(initialName) {
|
|
|
202
210
|
template: flags.template || answers.template,
|
|
203
211
|
databaseName: flags.databaseName || answers.databaseName || `${initialName || answers.projectName}-db`,
|
|
204
212
|
bucketName: flags.bucketName || answers.bucketName || `${initialName || answers.projectName}-media`,
|
|
213
|
+
seedAdmin: answers.seedAdmin !== undefined ? answers.seedAdmin : true,
|
|
205
214
|
adminEmail: answers.adminEmail,
|
|
206
215
|
adminPassword: answers.adminPassword,
|
|
207
216
|
includeExample: flags.skipExample ? false : (flags.includeExample ? true : (answers.includeExample !== undefined ? answers.includeExample : true)),
|
|
208
217
|
createResources: flags.skipCloudflare ? false : answers.createResources,
|
|
218
|
+
runMigrations: true, // Always run migrations automatically
|
|
209
219
|
initGit: flags.skipGit ? false : answers.initGit,
|
|
210
220
|
skipInstall: flags.skipInstall
|
|
211
221
|
}
|
|
@@ -221,6 +231,8 @@ async function createProject(answers, flags) {
|
|
|
221
231
|
adminPassword,
|
|
222
232
|
includeExample,
|
|
223
233
|
createResources,
|
|
234
|
+
runMigrations,
|
|
235
|
+
seedAdmin,
|
|
224
236
|
initGit,
|
|
225
237
|
skipInstall
|
|
226
238
|
} = answers
|
|
@@ -237,6 +249,7 @@ async function createProject(answers, flags) {
|
|
|
237
249
|
projectName,
|
|
238
250
|
databaseName,
|
|
239
251
|
bucketName,
|
|
252
|
+
seedAdmin,
|
|
240
253
|
adminEmail,
|
|
241
254
|
adminPassword,
|
|
242
255
|
includeExample
|
|
@@ -291,6 +304,45 @@ async function createProject(answers, flags) {
|
|
|
291
304
|
spinner.succeed('Initialized git repository')
|
|
292
305
|
}
|
|
293
306
|
|
|
307
|
+
// 6. Run migrations
|
|
308
|
+
if (runMigrations && !skipInstall && resourcesCreated) {
|
|
309
|
+
spinner.start('Running database migrations...')
|
|
310
|
+
try {
|
|
311
|
+
await runDatabaseMigrations(targetDir)
|
|
312
|
+
spinner.succeed('Database migrations completed')
|
|
313
|
+
answers.migrationsRan = true
|
|
314
|
+
} catch (error) {
|
|
315
|
+
spinner.warn('Failed to run migrations')
|
|
316
|
+
console.log(kleur.dim(` ${error.message}`))
|
|
317
|
+
console.log(kleur.dim(' You can run them manually with: npm run db:migrate:local'))
|
|
318
|
+
answers.migrationsRan = false
|
|
319
|
+
}
|
|
320
|
+
} else if (runMigrations && skipInstall) {
|
|
321
|
+
spinner.info('Skipping migrations - run after npm install')
|
|
322
|
+
answers.migrationsRan = false
|
|
323
|
+
} else if (runMigrations && !resourcesCreated) {
|
|
324
|
+
spinner.info('Skipping migrations - database not created yet')
|
|
325
|
+
answers.migrationsRan = false
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// 7. Seed admin user
|
|
329
|
+
if (seedAdmin && !skipInstall && answers.migrationsRan) {
|
|
330
|
+
spinner.start('Seeding admin user...')
|
|
331
|
+
try {
|
|
332
|
+
await seedAdminUser(targetDir)
|
|
333
|
+
spinner.succeed('Admin user created')
|
|
334
|
+
answers.adminSeeded = true
|
|
335
|
+
} catch (error) {
|
|
336
|
+
spinner.warn('Failed to seed admin user')
|
|
337
|
+
console.log(kleur.dim(` ${error.message}`))
|
|
338
|
+
console.log(kleur.dim(' You can run it manually with: npm run seed'))
|
|
339
|
+
answers.adminSeeded = false
|
|
340
|
+
}
|
|
341
|
+
} else if (seedAdmin && !answers.migrationsRan) {
|
|
342
|
+
spinner.info('Skipping seed - migrations not completed')
|
|
343
|
+
answers.adminSeeded = false
|
|
344
|
+
}
|
|
345
|
+
|
|
294
346
|
spinner.succeed(kleur.bold().green('✓ Project created successfully!'))
|
|
295
347
|
|
|
296
348
|
} catch (error) {
|
|
@@ -351,11 +403,13 @@ async function copyTemplate(templateName, targetDir, options) {
|
|
|
351
403
|
}
|
|
352
404
|
}
|
|
353
405
|
|
|
354
|
-
// Create admin seed script with provided credentials
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
406
|
+
// Create admin seed script with provided credentials (only if creating admin user)
|
|
407
|
+
if (options.seedAdmin && options.adminEmail && options.adminPassword) {
|
|
408
|
+
await createAdminSeedScript(targetDir, {
|
|
409
|
+
email: options.adminEmail,
|
|
410
|
+
password: options.adminPassword
|
|
411
|
+
})
|
|
412
|
+
}
|
|
359
413
|
}
|
|
360
414
|
|
|
361
415
|
async function createAdminSeedScript(targetDir, { email, password }) {
|
|
@@ -623,8 +677,42 @@ async function initializeGit(targetDir) {
|
|
|
623
677
|
}
|
|
624
678
|
}
|
|
625
679
|
|
|
680
|
+
async function runDatabaseMigrations(targetDir) {
|
|
681
|
+
try {
|
|
682
|
+
const { stdout, stderr } = await execa('npm', ['run', 'db:migrate:local'], {
|
|
683
|
+
cwd: targetDir
|
|
684
|
+
})
|
|
685
|
+
|
|
686
|
+
// Check if migrations were successful
|
|
687
|
+
if (stderr && stderr.includes('error')) {
|
|
688
|
+
throw new Error(stderr)
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
return stdout
|
|
692
|
+
} catch (error) {
|
|
693
|
+
throw new Error(`Migration failed: ${error.message}`)
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
async function seedAdminUser(targetDir) {
|
|
698
|
+
try {
|
|
699
|
+
const { stdout, stderr } = await execa('npm', ['run', 'seed'], {
|
|
700
|
+
cwd: targetDir
|
|
701
|
+
})
|
|
702
|
+
|
|
703
|
+
// Check if seeding was successful
|
|
704
|
+
if (stderr && stderr.includes('error')) {
|
|
705
|
+
throw new Error(stderr)
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
return stdout
|
|
709
|
+
} catch (error) {
|
|
710
|
+
throw new Error(`Seeding failed: ${error.message}`)
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
626
714
|
function printSuccessMessage(answers) {
|
|
627
|
-
const { projectName, createResources, skipInstall, resourcesCreated, databaseIdSet } = answers
|
|
715
|
+
const { projectName, createResources, skipInstall, resourcesCreated, databaseIdSet, migrationsRan, adminSeeded } = answers
|
|
628
716
|
|
|
629
717
|
console.log()
|
|
630
718
|
console.log(kleur.bold().green('🎉 Success!'))
|
|
@@ -651,21 +739,40 @@ function printSuccessMessage(answers) {
|
|
|
651
739
|
console.log(kleur.cyan(` wrangler r2 bucket create ${answers.bucketName}`))
|
|
652
740
|
}
|
|
653
741
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
742
|
+
// Only show migration/seed steps if they weren't completed (shouldn't normally happen)
|
|
743
|
+
const needsMigrations = !migrationsRan
|
|
744
|
+
const needsSeeding = seedAdmin && !adminSeeded
|
|
745
|
+
|
|
746
|
+
if (needsMigrations || needsSeeding) {
|
|
747
|
+
console.log()
|
|
748
|
+
console.log(kleur.bold('Complete setup:'))
|
|
749
|
+
if (needsMigrations) {
|
|
750
|
+
console.log(kleur.cyan(' npm run db:migrate:local'))
|
|
751
|
+
}
|
|
752
|
+
if (needsSeeding) {
|
|
753
|
+
console.log(kleur.cyan(' npm run seed'))
|
|
754
|
+
}
|
|
755
|
+
}
|
|
660
756
|
|
|
661
757
|
console.log()
|
|
662
|
-
|
|
758
|
+
if (migrationsRan && (!seedAdmin || adminSeeded)) {
|
|
759
|
+
console.log(kleur.bold().green('✓ Database is ready! Start development:'))
|
|
760
|
+
} else {
|
|
761
|
+
console.log(kleur.bold('Start development:'))
|
|
762
|
+
}
|
|
663
763
|
console.log(kleur.cyan(' npm run dev'))
|
|
664
764
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
765
|
+
if (seedAdmin && answers.adminEmail) {
|
|
766
|
+
console.log()
|
|
767
|
+
console.log(kleur.bold('Login credentials:'))
|
|
768
|
+
console.log(kleur.cyan(` Email: ${answers.adminEmail}`))
|
|
769
|
+
console.log(kleur.dim(` Password: [as entered]`))
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
if (migrationsRan && (!seedAdmin || adminSeeded)) {
|
|
773
|
+
console.log()
|
|
774
|
+
console.log(kleur.green('✓ Everything is set up! Just run npm run dev and login.'))
|
|
775
|
+
}
|
|
669
776
|
|
|
670
777
|
console.log()
|
|
671
778
|
console.log(kleur.bold('Visit:'))
|