create-nextblock 0.8.0 → 0.8.1

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.
@@ -19,6 +19,7 @@ const TEMPLATE_DIR = resolve(__dirname, '../templates/nextblock-template');
19
19
  const REPO_ROOT = resolve(__dirname, '../../..');
20
20
  const EDITOR_UTILS_SOURCE_DIR = resolve(REPO_ROOT, 'libs/editor/src/lib/utils');
21
21
  const IS_WINDOWS = process.platform === 'win32';
22
+ const CLI_VERSION = createRequire(import.meta.url)('../package.json').version;
22
23
 
23
24
  const UI_PROXY_MODULES = [
24
25
  'avatar',
@@ -52,7 +53,10 @@ const PACKAGE_VERSION_SOURCES = {
52
53
  '@nextblock-cms/sdk': resolve(REPO_ROOT, 'libs/sdk/package.json'),
53
54
  };
54
55
 
55
- program.name('create-nextblock').description('NextBlock™ CMS CLI');
56
+ program
57
+ .name('create-nextblock')
58
+ .description('NextBlock™ CMS CLI')
59
+ .version(CLI_VERSION, '-v, --version');
56
60
 
57
61
  program
58
62
  .command('create [project-directory]', { isDefault: true })
@@ -77,6 +81,46 @@ async function handleCommand(projectDirectory, options) {
77
81
  const { skipInstall, yes } = options;
78
82
 
79
83
  try {
84
+ console.log(chalk.bold.cyan(`\n🧱 create-nextblock v${CLI_VERSION}\n`));
85
+
86
+ // Prerequisites gate (interactive only) — shown BEFORE we ask for a name, scaffold, or
87
+ // install, so anyone who isn't ready can cancel without creating anything.
88
+ if (!yes) {
89
+ clack.note(
90
+ [
91
+ '1. A Supabase project https://supabase.com/dashboard',
92
+ ' • Reference ID — Project Settings > General > "Reference ID"',
93
+ ' • Connection string — Connect (top bar) > Direct connection > URI',
94
+ ' • anon + service_role keys — Project Settings > API Keys',
95
+ ' • Personal Access Token — Account > Access Tokens > Generate new token',
96
+ '',
97
+ '2. A Cloudflare R2 bucket https://dash.cloudflare.com > R2',
98
+ ' • Create a bucket, then enable its Public Development URL (Bucket > Settings > General)',
99
+ ' • Create an R2 API token (Object Read & Write); copy the Access Key ID + Secret (shown once)',
100
+ '',
101
+ '3. SMTP credentials SMTP2GO works very well: https://www.smtp2go.com',
102
+ ' • Required so Supabase can email the confirmation link your first admin needs to sign in',
103
+ ].join('\n'),
104
+ 'Before you continue, have all of the following ready',
105
+ );
106
+
107
+ const ready = await clack.confirm({
108
+ message:
109
+ 'Do you have your Supabase, Cloudflare R2, and SMTP details ready?',
110
+ initialValue: true,
111
+ });
112
+ if (clack.isCancel(ready)) {
113
+ handleWizardCancel('Setup cancelled.');
114
+ }
115
+ if (!ready) {
116
+ clack.note(
117
+ 'No problem — nothing was created. Gather the items above, then run\n`npm create nextblock` again. Full guide: docs/05-DEVELOPER-GUIDE.md',
118
+ 'Come back when ready',
119
+ );
120
+ return;
121
+ }
122
+ }
123
+
80
124
  let projectName = projectDirectory;
81
125
 
82
126
  if (!projectName) {
@@ -162,32 +206,35 @@ async function handleCommand(projectDirectory, options) {
162
206
  await ensurePublicNpmrc(projectDir);
163
207
  console.log(chalk.green('Enforced public registry for initial install.'));
164
208
 
209
+ await initializeGit(projectDir);
210
+
165
211
  if (!skipInstall) {
166
212
  await installDependencies(projectDir);
167
213
  } else {
168
214
  console.log(chalk.yellow('Skipping dependency installation.'));
169
215
  }
170
216
 
171
- // Run setup wizard after dependencies are installed so package assets are available
217
+ // Run the setup wizard after dependencies are installed so package assets are available.
218
+ // When it runs, its own "next steps" outro (cd + npm run dev) is the final message, so we
219
+ // don't print a second closing block here — the whole flow completes in this one command.
172
220
  if (!yes) {
173
221
  await runSetupWizard(projectDir, projectName);
174
222
  } else {
223
+ // Non-interactive path: nothing was configured, so point the user at their env file.
224
+ console.log(
225
+ chalk.green(
226
+ `\nSuccess! Your NextBlock™ CMS project "${projectName}" is scaffolded.\n`,
227
+ ),
228
+ );
229
+ console.log(chalk.cyan('Next steps:'));
230
+ console.log(chalk.cyan(` 1. cd ${projectName}`));
175
231
  console.log(
176
- chalk.yellow(
177
- 'Skipping interactive setup wizard because --yes was provided.',
232
+ chalk.gray(
233
+ ' 2. Add your Supabase / R2 / SMTP values to .env.local (template in .env.example)',
178
234
  ),
179
235
  );
236
+ console.log(chalk.cyan(' 3. npm run dev'));
180
237
  }
181
-
182
- await initializeGit(projectDir);
183
-
184
- console.log(
185
- chalk.green(
186
- `\nSuccess! Your NextBlock™ CMS project "${projectName}" is ready.\n`,
187
- ),
188
- );
189
- console.log(chalk.cyan('Next step:'));
190
- console.log(chalk.cyan(` cd ${projectName} && npm run dev`));
191
238
  } catch (error) {
192
239
  console.error(
193
240
  chalk.red(
@@ -506,42 +553,9 @@ async function runSetupWizard(projectDir, projectName) {
506
553
  const projectPath = resolve(projectDir);
507
554
  process.chdir(projectPath);
508
555
 
509
- clack.intro('🚀 NextBlock™ CMS setup wizard');
510
-
511
- // 0. Prerequisites mirror `npm run setup` (tools/scripts/setup.mjs). Make sure the
512
- // developer has everything BEFORE we start prompting.
513
- clack.note(
514
- [
515
- '1. A Supabase project https://supabase.com/dashboard',
516
- ' • Reference ID — Project Settings > General > "Reference ID"',
517
- ' • Connection string — Connect (top bar) > Direct connection > URI',
518
- ' • anon + service_role keys — Project Settings > API Keys',
519
- ' • Personal Access Token — Account > Access Tokens > Generate new token',
520
- '',
521
- '2. A Cloudflare R2 bucket https://dash.cloudflare.com > R2',
522
- ' • Create a bucket, then enable its Public Development URL (Bucket > Settings > General)',
523
- ' • Create an R2 API token (Object Read & Write); copy the Access Key ID + Secret (shown once)',
524
- '',
525
- '3. SMTP credentials SMTP2GO works very well: https://www.smtp2go.com',
526
- ' • Required so Supabase can email the confirmation link your first admin needs to sign in',
527
- ].join('\n'),
528
- 'Before you continue, have all of the following ready',
529
- );
530
-
531
- const ready = await clack.confirm({
532
- message: 'Do you have your Supabase, Cloudflare R2, and SMTP details ready?',
533
- initialValue: true,
534
- });
535
- if (clack.isCancel(ready)) {
536
- handleWizardCancel('Setup cancelled.');
537
- }
538
- if (!ready) {
539
- clack.note(
540
- 'No problem — your project files are ready. Gather the items above, then copy\n.env.example to .env.local and fill it in. Full guide: docs/05-DEVELOPER-GUIDE.md',
541
- 'Setup paused',
542
- );
543
- return;
544
- }
556
+ // Prerequisites + readiness were already confirmed up front in handleCommand (before any
557
+ // scaffolding), so the wizard goes straight to collecting configuration.
558
+ clack.intro('🚀 NextBlock™ CMS setup');
545
559
 
546
560
  await fs.ensureDir(resolve(projectPath, 'supabase'));
547
561
 
@@ -1801,6 +1815,32 @@ async function transformPackageJson(projectDir) {
1801
1815
  }
1802
1816
  }
1803
1817
 
1818
+ // Mirror the monorepo's defensive dependency overrides into the generated project so a
1819
+ // fresh `npm install` reproduces the "0 vulnerabilities" posture and silences deprecated
1820
+ // transitive deps (e.g. uuid@10). Read live from the repo root when available (local dev /
1821
+ // `npm run test-create`); fall back to this baked-in set in the published CLI where the
1822
+ // monorepo root is not on disk. Keep the fallback in sync with the root package.json.
1823
+ const FALLBACK_OVERRIDES = {
1824
+ postcss: '^8.5.12',
1825
+ qs: '^6.15.2',
1826
+ uuid: '^11.1.1',
1827
+ glob: '^10.4.5',
1828
+ 'whatwg-encoding': 'npm:@exodus/bytes@latest',
1829
+ 'node-domexception': 'npm:domexception@latest',
1830
+ keygrip: 'npm:keygrip@latest',
1831
+ };
1832
+ let rootOverrides = FALLBACK_OVERRIDES;
1833
+ try {
1834
+ const rootPkg = await fs.readJSON(resolve(REPO_ROOT, 'package.json'));
1835
+ if (rootPkg?.overrides && Object.keys(rootPkg.overrides).length > 0) {
1836
+ rootOverrides = rootPkg.overrides;
1837
+ }
1838
+ } catch {
1839
+ // Published CLI: repo root package.json not present — keep the baked-in fallback.
1840
+ }
1841
+ // Project-specific overrides (if any) win over the inherited defaults.
1842
+ packageJson.overrides = { ...rootOverrides, ...(packageJson.overrides ?? {}) };
1843
+
1804
1844
  await fs.writeJSON(packageJsonPath, packageJson, { spaces: 2 });
1805
1845
  }
1806
1846
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nextblock",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextblock-cms/template",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "dev": "next dev",