create-nextblock 0.2.5 → 0.2.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.
@@ -5,6 +5,7 @@ import { spawn } from 'node:child_process';
5
5
  import crypto from 'node:crypto';
6
6
  import { dirname, resolve, relative, sep, basename } from 'node:path';
7
7
  import { fileURLToPath } from 'node:url';
8
+ import { createRequire } from 'node:module';
8
9
  import { execa } from 'execa';
9
10
  import { program } from 'commander';
10
11
  import inquirer from 'inquirer';
@@ -12,11 +13,12 @@ import chalk from 'chalk';
12
13
  import fs from 'fs-extra';
13
14
  import open from 'open';
14
15
 
15
- const DEFAULT_PROJECT_NAME = 'nextblock-cms';
16
- const __filename = fileURLToPath(import.meta.url);
17
- const __dirname = dirname(__filename);
18
- const TEMPLATE_DIR = resolve(__dirname, '../templates/nextblock-template');
19
- const REPO_ROOT = resolve(__dirname, '../../..');
16
+ const DEFAULT_PROJECT_NAME = 'nextblock-cms';
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = dirname(__filename);
19
+ const TEMPLATE_DIR = resolve(__dirname, '../templates/nextblock-template');
20
+ const REPO_ROOT = resolve(__dirname, '../../..');
21
+ const require = createRequire(import.meta.url);
20
22
  const EDITOR_UTILS_SOURCE_DIR = resolve(REPO_ROOT, 'libs/editor/src/lib/utils');
21
23
  const IS_WINDOWS = process.platform === 'win32';
22
24
 
@@ -161,19 +163,12 @@ async function handleCommand(projectDirectory, options) {
161
163
  console.log(chalk.yellow('Skipping dependency installation.'));
162
164
  }
163
165
 
164
- await initializeGit(projectDir);
165
- console.log(chalk.green('Initialized a new Git repository.'));
166
-
167
- console.log(
168
- chalk.green(
169
- `\nSuccess! Your NextBlock CMS project "${projectName}" is ready.\n\n` +
170
- 'Next steps:\n' +
171
- `1. \`cd ${projectName}\`\n` +
172
- '2. Copy your existing `.env` file or rename `.env.example` to `.env` and fill in your credentials.\n' +
173
- '3. `npm run dev` to start the development server.\n\n' +
174
- 'Happy building!',
175
- ),
176
- );
166
+ await initializeGit(projectDir);
167
+ console.log(chalk.green('Initialized a new Git repository.'));
168
+
169
+ console.log(chalk.green(`\nSuccess! Your NextBlock CMS project "${projectName}" is ready.\n`));
170
+ console.log(chalk.cyan('Next step:'));
171
+ console.log(chalk.cyan(' npm run dev'));
177
172
  } catch (error) {
178
173
  console.error(
179
174
  chalk.red(error instanceof Error ? error.message : 'An unexpected error occurred'),
@@ -225,9 +220,13 @@ async function runSetupWizard(projectDir, projectName) {
225
220
  } catch (_) {
226
221
  // ignore if not supported
227
222
  }
223
+ process.stdin.setEncoding('utf8');
228
224
  }
229
225
  process.stdin.resume();
230
226
 
227
+ // Ensure supabase assets exist (config + migrations) after link in case the CLI created/overrode files
228
+ await ensureSupabaseAssets(projectPath);
229
+
231
230
  const configTomlPath = resolve(projectPath, 'supabase', 'config.toml');
232
231
  let configToml = '';
233
232
  if (!(await fs.pathExists(configTomlPath))) {
@@ -333,8 +332,16 @@ async function runSetupWizard(projectDir, projectName) {
333
332
  dbPushSpinner.start('Pushing database schema... (This may take a minute)');
334
333
  try {
335
334
  process.env.POSTGRES_URL = postgresUrl;
336
- await execa('npx', ['supabase', 'db', 'push'], { stdio: 'inherit', cwd: projectPath });
337
- dbPushSpinner.stop('Database schema pushed successfully!');
335
+ const migrationsDir = resolve(projectPath, 'supabase', 'migrations');
336
+ const hasMigrations =
337
+ (await fs.pathExists(migrationsDir)) &&
338
+ (await fs.readdir(migrationsDir)).some((name) => name.endsWith('.sql'));
339
+ if (!hasMigrations) {
340
+ dbPushSpinner.stop('No migrations found in supabase/migrations; skipping db push.');
341
+ } else {
342
+ await execa('npx', ['supabase', 'db', 'push'], { stdio: 'inherit', cwd: projectPath });
343
+ dbPushSpinner.stop('Database schema pushed successfully!');
344
+ }
338
345
  } catch (error) {
339
346
  dbPushSpinner.stop('Database push failed. Please run `npx supabase db push` manually.');
340
347
  if (error instanceof Error) {
@@ -463,9 +470,7 @@ async function runSetupWizard(projectDir, projectName) {
463
470
  }
464
471
  }
465
472
 
466
- clack.outro(
467
- `🎉 Your NextBlock project ${projectName ? `"${projectName}" ` : ''}is ready!\n\nNext steps:\n 1. cd ${projectName || projectPath}\n 2. npm run dev`,
468
- );
473
+ clack.outro(`🎉 Your NextBlock project ${projectName ? `"${projectName}" ` : ''}is ready!\n\nNext step:\n npm run dev`);
469
474
  }
470
475
 
471
476
  function handleWizardCancel(message) {
@@ -693,26 +698,40 @@ SMTP_FROM_NAME=
693
698
  }
694
699
 
695
700
  async function ensureSupabaseAssets(projectDir) {
696
- const sourceSupabaseDir = resolve(REPO_ROOT, 'libs/db/src/supabase');
697
701
  const destSupabaseDir = resolve(projectDir, 'supabase');
702
+ await fs.ensureDir(destSupabaseDir);
698
703
 
699
- if (!(await fs.pathExists(sourceSupabaseDir))) {
700
- return;
701
- }
704
+ const packageSupabaseDir = await resolvePackageSupabaseDir();
705
+ const templateSupabaseDir = resolve(TEMPLATE_DIR, 'supabase');
702
706
 
703
- await fs.ensureDir(destSupabaseDir);
707
+ const sources = [packageSupabaseDir, templateSupabaseDir].filter(Boolean);
708
+ for (const sourceSupabaseDir of sources) {
709
+ const sourceConfig = resolve(sourceSupabaseDir, 'config.toml');
710
+ const destConfig = resolve(destSupabaseDir, 'config.toml');
711
+ if (await fs.pathExists(sourceConfig)) {
712
+ await fs.copy(sourceConfig, destConfig, { overwrite: true });
713
+ }
704
714
 
705
- const sourceConfig = resolve(sourceSupabaseDir, 'config.toml');
706
- const destConfig = resolve(destSupabaseDir, 'config.toml');
707
- if (!(await fs.pathExists(destConfig)) && (await fs.pathExists(sourceConfig))) {
708
- await fs.copy(sourceConfig, destConfig);
715
+ const sourceMigrations = resolve(sourceSupabaseDir, 'migrations');
716
+ const destMigrations = resolve(destSupabaseDir, 'migrations');
717
+ if (await fs.pathExists(sourceMigrations)) {
718
+ await fs.copy(sourceMigrations, destMigrations, { overwrite: true, errorOnExist: false });
719
+ }
709
720
  }
721
+ }
710
722
 
711
- const sourceMigrations = resolve(sourceSupabaseDir, 'migrations');
712
- const destMigrations = resolve(destSupabaseDir, 'migrations');
713
- if (await fs.pathExists(sourceMigrations)) {
714
- await fs.copy(sourceMigrations, destMigrations, { overwrite: false, errorOnExist: false });
723
+ async function resolvePackageSupabaseDir() {
724
+ try {
725
+ const pkgPath = require.resolve('@nextblock-cms/db/package.json');
726
+ const pkgDir = dirname(pkgPath);
727
+ const candidate = resolve(pkgDir, 'supabase');
728
+ if (await fs.pathExists(candidate)) {
729
+ return candidate;
730
+ }
731
+ } catch {
732
+ return null;
715
733
  }
734
+ return null;
716
735
  }
717
736
 
718
737
  async function ensureClientComponents(projectDir) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nextblock",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -17,6 +17,7 @@
17
17
  "type": "module",
18
18
  "dependencies": {
19
19
  "@clack/prompts": "^0.8.1",
20
+ "@nextblock-cms/db": "latest",
20
21
  "chalk": "^5.6.2",
21
22
  "commander": "^14.0.1",
22
23
  "execa": "^9.3.0",