create-strapi-launchpad 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -43,9 +43,9 @@ npx create-strapi-launchpad my-app --framework astro
43
43
  - Node.js 20.19 or newer
44
44
  - Git
45
45
 
46
- Yarn is required LaunchPad pins `yarn@4.5.0` in its root `package.json`, so
47
- npm and pnpm will not work. If yarn is missing, the CLI enables it through
48
- Corepack for you.
46
+ Yarn is required. Every LaunchPad directory ships a `yarn.lock` and its
47
+ scripts call yarn directly, so that is what the CLI drives. If yarn is
48
+ missing, the CLI enables it through Corepack for you.
49
49
 
50
50
  ## What it does
51
51
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-strapi-launchpad",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "CLI to scaffold the official Strapi LaunchPad demo application with the frontend of your choice",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,8 +38,10 @@ function normalizeRepo(repo) {
38
38
  return { url: `file://${abs}`, local: true };
39
39
  }
40
40
 
41
- // LaunchPad pins yarn in its root package.json, so Corepack will refuse any
42
- // other package manager. There is no point offering a choice.
41
+ // Every LaunchPad directory ships a yarn.lock and its scripts shell out to
42
+ // yarn, so that is what the CLI drives. npm technically runs here, but it
43
+ // would resolve against no lockfile and write a package-lock beside the
44
+ // yarn one.
43
45
  const PM = 'yarn';
44
46
 
45
47
  /**
@@ -333,6 +335,33 @@ export async function createLaunchpadApp(directory, options) {
333
335
  log.info(`Strapi admin → http://localhost:${STRAPI_PORT}/admin`);
334
336
  log.info(`${framework.label} → http://localhost:${framework.port}`);
335
337
  console.log();
338
+ // Printed before the dev servers take the terminal over, because their
339
+ // output scrolls past immediately and this is what people need after the
340
+ // first Ctrl+C. `yarn dev` is Next for every scaffold, so naming the
341
+ // frontend-specific script matters.
342
+ console.log(
343
+ ` To restart later: cd ${directory} && ${PM} ${framework.devScript}`
344
+ );
345
+ console.log();
346
+
347
+ // Ctrl+C sends SIGINT to the whole process group, so Node tears this process
348
+ // down before anything after the await can run. Handling it explicitly is
349
+ // the only way to get the last word — without this the message never prints,
350
+ // which is exactly what happened the first time round.
351
+ let printed = false;
352
+ const sayGoodbye = () => {
353
+ if (printed) return;
354
+ printed = true;
355
+ printRestartHelp(directory, framework);
356
+ };
357
+ process.on('SIGINT', () => {
358
+ sayGoodbye();
359
+ process.exit(0);
360
+ });
361
+ process.on('SIGTERM', () => {
362
+ sayGoodbye();
363
+ process.exit(0);
364
+ });
336
365
 
337
366
  try {
338
367
  await execa(PM, [framework.devScript], {
@@ -340,6 +369,36 @@ export async function createLaunchpadApp(directory, options) {
340
369
  stdio: 'inherit',
341
370
  });
342
371
  } catch {
343
- // Ctrl+C is the normal way out of a dev server.
372
+ // The dev servers exiting non-zero is normal on shutdown.
344
373
  }
374
+
375
+ // Covers the servers stopping on their own rather than by Ctrl+C.
376
+ sayGoodbye();
377
+ }
378
+
379
+ /**
380
+ * Printed when the dev servers stop.
381
+ *
382
+ * The same command is shown before they start, but by then it is hundreds of
383
+ * lines up — a real run buries it under about 280 lines of server output. The
384
+ * moment someone actually needs it is right after Ctrl+C, so this puts it on
385
+ * the last line of the terminal.
386
+ *
387
+ * `yarn dev` is named explicitly as Next. It is the command people reach for,
388
+ * and in a scaffold built for another frontend it silently starts the wrong
389
+ * one — worth saying out loud rather than letting them discover it.
390
+ */
391
+ function printRestartHelp(directory, framework) {
392
+ const others = FRAMEWORKS.filter((f) => f.name !== framework.name).map((f) =>
393
+ f.devScript === 'dev' ? `${PM} dev (${f.label})` : `${PM} ${f.devScript}`
394
+ );
395
+
396
+ console.log();
397
+ log.info('Stopped.');
398
+ console.log();
399
+ console.log(
400
+ ` Restart: cd ${directory} && ${PM} ${framework.devScript}`
401
+ );
402
+ console.log(` Other frontends: ${others.join(', ')}`);
403
+ console.log();
345
404
  }
@@ -37,9 +37,9 @@ export async function checkPrerequisites() {
37
37
  process.exit(1);
38
38
  }
39
39
 
40
- // LaunchPad pins yarn@4.5.0 in its root package.json, so this is the only
41
- // package manager that will work. Corepack ships with Node and can provide
42
- // it without a global install.
40
+ // Every LaunchPad directory ships a yarn.lock and its scripts shell out to
41
+ // yarn, so that is what the CLI drives. Corepack comes with Node and can
42
+ // provide yarn without a global install.
43
43
  try {
44
44
  await execaCommand('yarn --version');
45
45
  log.success('Yarn available');
@@ -54,7 +54,8 @@ export async function checkPrerequisites() {
54
54
  ' corepack enable\n' +
55
55
  ' — or —\n' +
56
56
  ' npm install -g yarn\n\n' +
57
- 'LaunchPad pins yarn@4.5.0, so npm and pnpm will not work.'
57
+ 'LaunchPad is set up for yarn: every directory ships a yarn.lock\n' +
58
+ 'and its scripts call yarn directly.'
58
59
  );
59
60
  process.exit(1);
60
61
  }