create-sonicjs 2.0.0-beta.5 → 2.0.0-beta.7

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +159 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-sonicjs",
3
- "version": "2.0.0-beta.5",
3
+ "version": "2.0.0-beta.7",
4
4
  "description": "Create a new SonicJS application with zero configuration",
5
5
  "type": "module",
6
6
  "bin": {
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.5'
15
+ const VERSION = '2.0.0-beta.7'
16
16
 
17
17
  // Templates available
18
18
  const TEMPLATES = {
@@ -181,6 +181,22 @@ async function getProjectDetails(initialName) {
181
181
  })
182
182
  }
183
183
 
184
+ // Run migrations
185
+ questions.push({
186
+ type: 'confirm',
187
+ name: 'runMigrations',
188
+ message: 'Run database migrations now?',
189
+ initial: true
190
+ })
191
+
192
+ // Seed admin user
193
+ questions.push({
194
+ type: 'confirm',
195
+ name: 'seedAdmin',
196
+ message: 'Seed admin user now?',
197
+ initial: true
198
+ })
199
+
184
200
  // Initialize git
185
201
  if (!flags.skipGit) {
186
202
  questions.push({
@@ -206,6 +222,8 @@ async function getProjectDetails(initialName) {
206
222
  adminPassword: answers.adminPassword,
207
223
  includeExample: flags.skipExample ? false : (flags.includeExample ? true : (answers.includeExample !== undefined ? answers.includeExample : true)),
208
224
  createResources: flags.skipCloudflare ? false : answers.createResources,
225
+ runMigrations: answers.runMigrations !== undefined ? answers.runMigrations : true,
226
+ seedAdmin: answers.seedAdmin !== undefined ? answers.seedAdmin : true,
209
227
  initGit: flags.skipGit ? false : answers.initGit,
210
228
  skipInstall: flags.skipInstall
211
229
  }
@@ -221,6 +239,8 @@ async function createProject(answers, flags) {
221
239
  adminPassword,
222
240
  includeExample,
223
241
  createResources,
242
+ runMigrations,
243
+ seedAdmin,
224
244
  initGit,
225
245
  skipInstall
226
246
  } = answers
@@ -277,6 +297,11 @@ async function createProject(answers, flags) {
277
297
  spinner.start('Installing dependencies...')
278
298
  await installDependencies(targetDir)
279
299
  spinner.succeed('Installed dependencies')
300
+
301
+ // Copy migrations after install
302
+ spinner.start('Copying database migrations...')
303
+ await copyMigrationsFromCore(targetDir)
304
+ spinner.succeed('Copied database migrations')
280
305
  }
281
306
 
282
307
  // 5. Initialize git
@@ -286,6 +311,45 @@ async function createProject(answers, flags) {
286
311
  spinner.succeed('Initialized git repository')
287
312
  }
288
313
 
314
+ // 6. Run migrations
315
+ if (runMigrations && !skipInstall && resourcesCreated) {
316
+ spinner.start('Running database migrations...')
317
+ try {
318
+ await runDatabaseMigrations(targetDir)
319
+ spinner.succeed('Database migrations completed')
320
+ answers.migrationsRan = true
321
+ } catch (error) {
322
+ spinner.warn('Failed to run migrations')
323
+ console.log(kleur.dim(` ${error.message}`))
324
+ console.log(kleur.dim(' You can run them manually with: npm run db:migrate:local'))
325
+ answers.migrationsRan = false
326
+ }
327
+ } else if (runMigrations && skipInstall) {
328
+ spinner.info('Skipping migrations - run after npm install')
329
+ answers.migrationsRan = false
330
+ } else if (runMigrations && !resourcesCreated) {
331
+ spinner.info('Skipping migrations - database not created yet')
332
+ answers.migrationsRan = false
333
+ }
334
+
335
+ // 7. Seed admin user
336
+ if (seedAdmin && !skipInstall && answers.migrationsRan) {
337
+ spinner.start('Seeding admin user...')
338
+ try {
339
+ await seedAdminUser(targetDir)
340
+ spinner.succeed('Admin user created')
341
+ answers.adminSeeded = true
342
+ } catch (error) {
343
+ spinner.warn('Failed to seed admin user')
344
+ console.log(kleur.dim(` ${error.message}`))
345
+ console.log(kleur.dim(' You can run it manually with: npm run seed'))
346
+ answers.adminSeeded = false
347
+ }
348
+ } else if (seedAdmin && !answers.migrationsRan) {
349
+ spinner.info('Skipping seed - migrations not completed')
350
+ answers.adminSeeded = false
351
+ }
352
+
289
353
  spinner.succeed(kleur.bold().green('✓ Project created successfully!'))
290
354
 
291
355
  } catch (error) {
@@ -470,6 +534,34 @@ seed()
470
534
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 })
471
535
  }
472
536
 
537
+ async function copyMigrationsFromCore(targetDir) {
538
+ // The migrations are in @sonicjs-cms/core/migrations
539
+ // After npm install, they'll be in node_modules/@sonicjs-cms/core/migrations
540
+ const coreMigrationsPath = path.join(targetDir, 'node_modules', '@sonicjs-cms', 'core', 'migrations')
541
+ const projectMigrationsPath = path.join(targetDir, 'migrations')
542
+
543
+ // Check if core migrations exist (they should after npm install)
544
+ if (fs.existsSync(coreMigrationsPath)) {
545
+ // Copy migrations to project directory
546
+ await fs.copy(coreMigrationsPath, projectMigrationsPath)
547
+ } else {
548
+ // If migrations don't exist yet (npm install hasn't run), create a note file
549
+ await fs.ensureDir(projectMigrationsPath)
550
+ const noteContent = `# Migrations
551
+
552
+ Migrations will be copied from @sonicjs-cms/core after running npm install.
553
+
554
+ To manually copy migrations:
555
+ 1. Install dependencies: npm install
556
+ 2. Copy from: node_modules/@sonicjs-cms/core/migrations/
557
+ 3. Copy to: migrations/
558
+
559
+ Or they should be automatically available after installation.
560
+ `
561
+ await fs.writeFile(path.join(projectMigrationsPath, 'README.md'), noteContent)
562
+ }
563
+ }
564
+
473
565
  async function createCloudflareResources(databaseName, bucketName, targetDir) {
474
566
  // Check if wrangler is installed
475
567
  try {
@@ -590,8 +682,42 @@ async function initializeGit(targetDir) {
590
682
  }
591
683
  }
592
684
 
685
+ async function runDatabaseMigrations(targetDir) {
686
+ try {
687
+ const { stdout, stderr } = await execa('npm', ['run', 'db:migrate:local'], {
688
+ cwd: targetDir
689
+ })
690
+
691
+ // Check if migrations were successful
692
+ if (stderr && stderr.includes('error')) {
693
+ throw new Error(stderr)
694
+ }
695
+
696
+ return stdout
697
+ } catch (error) {
698
+ throw new Error(`Migration failed: ${error.message}`)
699
+ }
700
+ }
701
+
702
+ async function seedAdminUser(targetDir) {
703
+ try {
704
+ const { stdout, stderr } = await execa('npm', ['run', 'seed'], {
705
+ cwd: targetDir
706
+ })
707
+
708
+ // Check if seeding was successful
709
+ if (stderr && stderr.includes('error')) {
710
+ throw new Error(stderr)
711
+ }
712
+
713
+ return stdout
714
+ } catch (error) {
715
+ throw new Error(`Seeding failed: ${error.message}`)
716
+ }
717
+ }
718
+
593
719
  function printSuccessMessage(answers) {
594
- const { projectName, createResources, skipInstall, resourcesCreated, databaseIdSet } = answers
720
+ const { projectName, createResources, skipInstall, resourcesCreated, databaseIdSet, migrationsRan, adminSeeded } = answers
595
721
 
596
722
  console.log()
597
723
  console.log(kleur.bold().green('🎉 Success!'))
@@ -602,6 +728,9 @@ function printSuccessMessage(answers) {
602
728
 
603
729
  if (skipInstall) {
604
730
  console.log(kleur.cyan(' npm install'))
731
+ console.log()
732
+ console.log(kleur.yellow('⚠ Important: After npm install, copy migrations:'))
733
+ console.log(kleur.dim(' cp -r node_modules/@sonicjs-cms/core/migrations ./'))
605
734
  }
606
735
 
607
736
  // Show resource creation steps if they weren't created or failed
@@ -615,13 +744,31 @@ function printSuccessMessage(answers) {
615
744
  console.log(kleur.cyan(` wrangler r2 bucket create ${answers.bucketName}`))
616
745
  }
617
746
 
618
- console.log()
619
- console.log(kleur.bold('Run migrations and seed admin user:'))
620
- console.log(kleur.cyan(' npm run db:migrate:local'))
621
- console.log(kleur.cyan(' npm run seed'))
747
+ // Only show migration/seed steps if they weren't completed
748
+ const needsMigrations = !migrationsRan
749
+ const needsSeeding = !adminSeeded
750
+
751
+ if (needsMigrations || needsSeeding) {
752
+ console.log()
753
+ console.log(kleur.bold('⚡ IMPORTANT - Setup database:'))
754
+ if (needsMigrations) {
755
+ console.log(kleur.cyan(' npm run db:migrate:local'))
756
+ }
757
+ if (needsSeeding) {
758
+ console.log(kleur.cyan(' npm run seed'))
759
+ }
760
+ if (needsMigrations) {
761
+ console.log()
762
+ console.log(kleur.dim(' Without migrations, you will get "no such table" errors!'))
763
+ }
764
+ }
622
765
 
623
766
  console.log()
624
- console.log(kleur.bold('Start development:'))
767
+ if (migrationsRan && adminSeeded) {
768
+ console.log(kleur.bold().green('✓ Database is ready! Start development:'))
769
+ } else {
770
+ console.log(kleur.bold('Start development:'))
771
+ }
625
772
  console.log(kleur.cyan(' npm run dev'))
626
773
 
627
774
  console.log()
@@ -629,6 +776,11 @@ function printSuccessMessage(answers) {
629
776
  console.log(kleur.cyan(` Email: ${answers.adminEmail}`))
630
777
  console.log(kleur.dim(` Password: [as entered]`))
631
778
 
779
+ if (migrationsRan && adminSeeded) {
780
+ console.log()
781
+ console.log(kleur.green('✓ Everything is set up! Just run npm run dev and login.'))
782
+ }
783
+
632
784
  console.log()
633
785
  console.log(kleur.bold('Visit:'))
634
786
  console.log(kleur.cyan(' http://localhost:8787/admin'))