create-meridian-app 0.1.25 → 0.1.26

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.
@@ -17,7 +17,7 @@ function renderPackageJson(vars) {
17
17
  scripts: {
18
18
  dev: "meridian dev",
19
19
  build: "meridian build",
20
- start: "meridian dev",
20
+ start: "meridian start",
21
21
  "db:migrate": "meridian db:migrate",
22
22
  "db:generate": "meridian db:generate",
23
23
  ...vars.seedDemo ? { "seed:demo": "node --import tsx/esm src/scripts/seed-demo.ts" } : {}
package/dist/cli.js CHANGED
@@ -14,11 +14,11 @@ import {
14
14
  toKebabCase,
15
15
  toPascalCase,
16
16
  writeFile
17
- } from "./chunk-EE7FQVVB.js";
17
+ } from "./chunk-FNX5ZWEV.js";
18
18
 
19
19
  // src/cli.ts
20
20
  import { Command } from "commander";
21
- import chalk13 from "chalk";
21
+ import chalk14 from "chalk";
22
22
 
23
23
  // src/commands/dev.ts
24
24
  import path2 from "path";
@@ -274,39 +274,98 @@ async function runDev() {
274
274
  process.exit(apiProc.exitCode ?? 0);
275
275
  }
276
276
 
277
- // src/commands/build.ts
277
+ // src/commands/start.ts
278
+ import path3 from "path";
279
+ import { existsSync as existsSync3 } from "fs";
278
280
  import chalk3 from "chalk";
279
281
  import { execa as execa2 } from "execa";
280
- async function runBuild() {
282
+ import dotenv3 from "dotenv";
283
+ async function runStart() {
281
284
  const rootDir = findProjectRoot();
282
285
  if (!rootDir) {
283
286
  console.error(chalk3.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
284
287
  process.exit(1);
285
288
  }
286
- console.log(chalk3.dim(" \u2192 Type-checking project..."));
289
+ dotenv3.config({ path: path3.join(rootDir, ".env") });
290
+ const mainTs = path3.join(rootDir, "src", "main.ts");
291
+ if (!existsSync3(mainTs)) {
292
+ console.error(chalk3.red(` \u2716 Entry point not found: ${mainTs}`));
293
+ process.exit(1);
294
+ }
295
+ const dashboardDist = path3.join(rootDir, "node_modules", "@meridianjs", "admin-dashboard", "dist");
296
+ const hasDashboard = existsSync3(dashboardDist);
297
+ const { apiPort, dashboardPort } = await readProjectPorts(rootDir);
298
+ const apiUrl = process.env.API_URL ?? `http://localhost:${apiPort}`;
299
+ let dashServer = null;
300
+ if (hasDashboard) {
301
+ dashServer = await startDashboardServer(dashboardDist, dashboardPort, apiPort, "localhost", null, apiUrl);
302
+ console.log(
303
+ chalk3.dim(" \u2192 API: ") + chalk3.cyan(`http://localhost:${apiPort}`) + chalk3.dim(" dashboard: ") + chalk3.cyan(`http://localhost:${dashboardPort}`)
304
+ );
305
+ } else {
306
+ console.log(chalk3.dim(` \u2192 API: http://localhost:${apiPort}`));
307
+ }
308
+ console.log();
309
+ const apiProc = execa2(
310
+ "node",
311
+ ["--import", "tsx/esm", mainTs],
312
+ {
313
+ cwd: rootDir,
314
+ stdio: "inherit",
315
+ env: { ...process.env, NODE_ENV: "production", FORCE_COLOR: "1" }
316
+ }
317
+ );
318
+ const shutdown = (signal) => {
319
+ dashServer?.close();
320
+ apiProc.kill(signal);
321
+ process.exit(0);
322
+ };
323
+ process.on("SIGINT", () => shutdown("SIGINT"));
324
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
325
+ await apiProc.catch((err) => {
326
+ if (err.signal === "SIGINT" || err.signal === "SIGTERM") {
327
+ dashServer?.close();
328
+ process.exit(0);
329
+ }
330
+ throw err;
331
+ });
332
+ dashServer?.close();
333
+ process.exit(apiProc.exitCode ?? 0);
334
+ }
335
+
336
+ // src/commands/build.ts
337
+ import chalk4 from "chalk";
338
+ import { execa as execa3 } from "execa";
339
+ async function runBuild() {
340
+ const rootDir = findProjectRoot();
341
+ if (!rootDir) {
342
+ console.error(chalk4.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
343
+ process.exit(1);
344
+ }
345
+ console.log(chalk4.dim(" \u2192 Type-checking project..."));
287
346
  console.log();
288
- const result = await execa2("npx", ["tsc", "--noEmit"], {
347
+ const result = await execa3("npx", ["tsc", "--noEmit"], {
289
348
  cwd: rootDir,
290
349
  stdio: "inherit"
291
350
  }).catch((err) => err);
292
351
  if (result.exitCode !== 0) {
293
352
  console.log();
294
- console.error(chalk3.red(" \u2716 Type check failed"));
353
+ console.error(chalk4.red(" \u2716 Type check failed"));
295
354
  process.exit(result.exitCode ?? 1);
296
355
  }
297
356
  console.log();
298
- console.log(chalk3.green(" \u2713 Type check passed"));
357
+ console.log(chalk4.green(" \u2713 Type check passed"));
299
358
  }
300
359
 
301
360
  // src/commands/db-migrate.ts
302
- import path3 from "path";
303
- import chalk4 from "chalk";
361
+ import path4 from "path";
362
+ import chalk5 from "chalk";
304
363
  import ora from "ora";
305
- import { execa as execa3 } from "execa";
364
+ import { execa as execa4 } from "execa";
306
365
  async function runDbMigrate() {
307
366
  const rootDir = findProjectRoot();
308
367
  if (!rootDir) {
309
- console.error(chalk4.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
368
+ console.error(chalk5.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
310
369
  process.exit(1);
311
370
  }
312
371
  const spinner = ora("Synchronizing database schema...").start();
@@ -324,11 +383,11 @@ await app.stop()
324
383
  process.exit(0)
325
384
  `;
326
385
  const { randomBytes } = await import("crypto");
327
- const scriptPath = path3.join(rootDir, `.meridian-migrate-${randomBytes(8).toString("hex")}.mjs`);
386
+ const scriptPath = path4.join(rootDir, `.meridian-migrate-${randomBytes(8).toString("hex")}.mjs`);
328
387
  const { writeFile: writeFile2, unlink } = await import("fs/promises");
329
388
  await writeFile2(scriptPath, script, { encoding: "utf-8", mode: 384 });
330
389
  try {
331
- await execa3("node", ["--import", "tsx/esm", scriptPath], {
390
+ await execa4("node", ["--import", "tsx/esm", scriptPath], {
332
391
  cwd: rootDir,
333
392
  stdio: "pipe",
334
393
  env: { ...process.env, NODE_ENV: "development" }
@@ -337,7 +396,7 @@ process.exit(0)
337
396
  } catch (err) {
338
397
  spinner.fail("Schema migration failed");
339
398
  console.error();
340
- if (err.stderr) console.error(chalk4.red(err.stderr));
399
+ if (err.stderr) console.error(chalk5.red(err.stderr));
341
400
  if (err.stdout) console.error(err.stdout);
342
401
  process.exit(1);
343
402
  } finally {
@@ -346,23 +405,23 @@ process.exit(0)
346
405
  }
347
406
 
348
407
  // src/commands/db-generate.ts
349
- import path4 from "path";
408
+ import path5 from "path";
350
409
  import fs2 from "fs/promises";
351
- import chalk5 from "chalk";
410
+ import chalk6 from "chalk";
352
411
  async function runDbGenerate(migrationName) {
353
412
  const rootDir = findProjectRoot();
354
413
  if (!rootDir) {
355
- console.error(chalk5.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
414
+ console.error(chalk6.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
356
415
  process.exit(1);
357
416
  }
358
417
  if (!migrationName) {
359
- console.error(chalk5.red(" \u2716 Migration name is required. Usage: meridian db:generate <name>"));
418
+ console.error(chalk6.red(" \u2716 Migration name is required. Usage: meridian db:generate <name>"));
360
419
  process.exit(1);
361
420
  }
362
421
  const safeName = migrationName.toLowerCase().replace(/[^a-z0-9_]/g, "_").replace(/_+/g, "_");
363
422
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:T.Z]/g, "").slice(0, 14);
364
423
  const fileName = `${timestamp}_${safeName}.ts`;
365
- const migrationsDir = path4.join(rootDir, "src", "migrations");
424
+ const migrationsDir = path5.join(rootDir, "src", "migrations");
366
425
  await fs2.mkdir(migrationsDir, { recursive: true });
367
426
  const content = `/**
368
427
  * Migration: ${safeName}
@@ -381,87 +440,87 @@ export async function down(): Promise<void> {
381
440
  // Write your rollback SQL here
382
441
  }
383
442
  `;
384
- const filePath = path4.join(migrationsDir, fileName);
443
+ const filePath = path5.join(migrationsDir, fileName);
385
444
  await fs2.writeFile(filePath, content, "utf-8");
386
- console.log(chalk5.green(` \u2713 Created migration: src/migrations/${fileName}`));
445
+ console.log(chalk6.green(` \u2713 Created migration: src/migrations/${fileName}`));
387
446
  console.log();
388
- console.log(chalk5.dim(" Note: Meridian auto-syncs schema on startup via updateSchema()."));
389
- console.log(chalk5.dim(" Use this file for custom DDL that requires manual control."));
447
+ console.log(chalk6.dim(" Note: Meridian auto-syncs schema on startup via updateSchema()."));
448
+ console.log(chalk6.dim(" Use this file for custom DDL that requires manual control."));
390
449
  }
391
450
 
392
451
  // src/commands/generate/module.ts
393
- import path5 from "path";
394
- import { existsSync as existsSync3 } from "fs";
395
- import chalk6 from "chalk";
452
+ import path6 from "path";
453
+ import { existsSync as existsSync4 } from "fs";
454
+ import chalk7 from "chalk";
396
455
  async function generateModule(name) {
397
456
  const rootDir = findProjectRoot();
398
457
  if (!rootDir) {
399
- console.error(chalk6.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
458
+ console.error(chalk7.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
400
459
  process.exit(1);
401
460
  }
402
461
  if (!name) {
403
- console.error(chalk6.red(" \u2716 Module name is required. Usage: meridian generate module <name>"));
462
+ console.error(chalk7.red(" \u2716 Module name is required. Usage: meridian generate module <name>"));
404
463
  process.exit(1);
405
464
  }
406
465
  const kebab = toKebabCase(name);
407
466
  const pascal = toPascalCase(kebab);
408
- const moduleDir = path5.join(rootDir, "src", "modules", kebab);
409
- if (existsSync3(moduleDir)) {
410
- console.error(chalk6.red(` \u2716 Module directory already exists: src/modules/${kebab}`));
467
+ const moduleDir = path6.join(rootDir, "src", "modules", kebab);
468
+ if (existsSync4(moduleDir)) {
469
+ console.error(chalk7.red(` \u2716 Module directory already exists: src/modules/${kebab}`));
411
470
  process.exit(1);
412
471
  }
413
- await writeFile(path5.join(moduleDir, "index.ts"), renderModuleIndex(kebab, pascal));
414
- await writeFile(path5.join(moduleDir, `models/${kebab}.ts`), renderModuleModel(kebab, pascal));
415
- await writeFile(path5.join(moduleDir, `loaders/default.ts`), renderModuleLoader(kebab, pascal));
416
- await writeFile(path5.join(moduleDir, "service.ts"), renderModuleService(kebab, pascal));
417
- console.log(chalk6.green(` \u2713 Generated module: src/modules/${kebab}/`));
472
+ await writeFile(path6.join(moduleDir, "index.ts"), renderModuleIndex(kebab, pascal));
473
+ await writeFile(path6.join(moduleDir, `models/${kebab}.ts`), renderModuleModel(kebab, pascal));
474
+ await writeFile(path6.join(moduleDir, `loaders/default.ts`), renderModuleLoader(kebab, pascal));
475
+ await writeFile(path6.join(moduleDir, "service.ts"), renderModuleService(kebab, pascal));
476
+ console.log(chalk7.green(` \u2713 Generated module: src/modules/${kebab}/`));
418
477
  console.log();
419
478
  console.log(" Files created:");
420
- console.log(chalk6.dim(` src/modules/${kebab}/index.ts`));
421
- console.log(chalk6.dim(` src/modules/${kebab}/models/${kebab}.ts`));
422
- console.log(chalk6.dim(` src/modules/${kebab}/loaders/default.ts`));
423
- console.log(chalk6.dim(` src/modules/${kebab}/service.ts`));
479
+ console.log(chalk7.dim(` src/modules/${kebab}/index.ts`));
480
+ console.log(chalk7.dim(` src/modules/${kebab}/models/${kebab}.ts`));
481
+ console.log(chalk7.dim(` src/modules/${kebab}/loaders/default.ts`));
482
+ console.log(chalk7.dim(` src/modules/${kebab}/service.ts`));
424
483
  console.log();
425
484
  console.log(" Next steps:");
426
- console.log(chalk6.dim(` 1. Add the module to your meridian.config.ts:`));
427
- console.log(chalk6.dim(` { resolve: "./src/modules/${kebab}" }`));
428
- console.log(chalk6.dim(` 2. Run \`npm run db:migrate\` to sync the schema`));
485
+ console.log(chalk7.dim(` 1. Add the module to your meridian.config.ts:`));
486
+ console.log(chalk7.dim(` { resolve: "./src/modules/${kebab}" }`));
487
+ console.log(chalk7.dim(` 2. Run \`npm run db:migrate\` to sync the schema`));
429
488
  }
430
489
 
431
490
  // src/commands/generate/workflow.ts
432
- import path6 from "path";
433
- import { existsSync as existsSync4 } from "fs";
434
- import chalk7 from "chalk";
491
+ import path7 from "path";
492
+ import { existsSync as existsSync5 } from "fs";
493
+ import chalk8 from "chalk";
435
494
  async function generateWorkflow(name) {
436
495
  const rootDir = findProjectRoot();
437
496
  if (!rootDir) {
438
- console.error(chalk7.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
497
+ console.error(chalk8.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
439
498
  process.exit(1);
440
499
  }
441
500
  if (!name) {
442
- console.error(chalk7.red(" \u2716 Workflow name is required. Usage: meridian generate workflow <name>"));
501
+ console.error(chalk8.red(" \u2716 Workflow name is required. Usage: meridian generate workflow <name>"));
443
502
  process.exit(1);
444
503
  }
445
504
  const kebab = toKebabCase(name);
446
505
  const pascal = toPascalCase(kebab);
447
- const filePath = path6.join(rootDir, "src", "workflows", `${kebab}.ts`);
448
- if (existsSync4(filePath)) {
449
- console.error(chalk7.red(` \u2716 Workflow already exists: src/workflows/${kebab}.ts`));
506
+ const filePath = path7.join(rootDir, "src", "workflows", `${kebab}.ts`);
507
+ if (existsSync5(filePath)) {
508
+ console.error(chalk8.red(` \u2716 Workflow already exists: src/workflows/${kebab}.ts`));
450
509
  process.exit(1);
451
510
  }
452
511
  const camel = pascal.charAt(0).toLowerCase() + pascal.slice(1);
453
512
  await writeFile(filePath, renderWorkflow(kebab, pascal));
454
- console.log(chalk7.green(` \u2713 Generated workflow: src/workflows/${kebab}.ts`));
513
+ console.log(chalk8.green(` \u2713 Generated workflow: src/workflows/${kebab}.ts`));
455
514
  console.log();
456
515
  console.log(" Usage:");
457
- console.log(chalk7.dim(` import { ${camel}Workflow } from "./workflows/${kebab}.js"`));
458
- console.log(chalk7.dim(` const { result } = await ${camel}Workflow(req.scope).run({ input: {...} })`));
516
+ console.log(chalk8.dim(` import { ${camel}Workflow } from "./workflows/${kebab}.js"`));
517
+ console.log(chalk8.dim(` const { result } = await ${camel}Workflow(req.scope).run({ input: {...} })`));
459
518
  }
460
519
 
461
520
  // src/commands/generate/plugin.ts
462
- import path7 from "path";
463
- import { existsSync as existsSync5 } from "fs";
464
- import chalk8 from "chalk";
521
+ import path8 from "path";
522
+ import { existsSync as existsSync6 } from "fs";
523
+ import chalk9 from "chalk";
465
524
  function renderPluginIndex(_name, pascalName) {
466
525
  return `import { fileURLToPath } from "node:url"
467
526
  import path from "node:path"
@@ -498,158 +557,158 @@ export const GET = async (req: any, res: Response) => {
498
557
  async function generatePlugin(name) {
499
558
  const rootDir = findProjectRoot();
500
559
  if (!rootDir) {
501
- console.error(chalk8.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
560
+ console.error(chalk9.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
502
561
  process.exit(1);
503
562
  }
504
563
  if (!name) {
505
- console.error(chalk8.red(" \u2716 Plugin name is required. Usage: meridian generate plugin <name>"));
564
+ console.error(chalk9.red(" \u2716 Plugin name is required. Usage: meridian generate plugin <name>"));
506
565
  process.exit(1);
507
566
  }
508
567
  const kebab = toKebabCase(name);
509
568
  const pascal = toPascalCase(kebab);
510
- const pluginDir = path7.join(rootDir, "src", "plugins", kebab);
511
- if (existsSync5(pluginDir)) {
512
- console.error(chalk8.red(` \u2716 Plugin directory already exists: src/plugins/${kebab}`));
569
+ const pluginDir = path8.join(rootDir, "src", "plugins", kebab);
570
+ if (existsSync6(pluginDir)) {
571
+ console.error(chalk9.red(` \u2716 Plugin directory already exists: src/plugins/${kebab}`));
513
572
  process.exit(1);
514
573
  }
515
- await writeFile(path7.join(pluginDir, "index.ts"), renderPluginIndex(kebab, pascal));
574
+ await writeFile(path8.join(pluginDir, "index.ts"), renderPluginIndex(kebab, pascal));
516
575
  await writeFile(
517
- path7.join(pluginDir, "api", "admin", kebab, "route.ts"),
576
+ path8.join(pluginDir, "api", "admin", kebab, "route.ts"),
518
577
  renderPluginRoute(kebab)
519
578
  );
520
- console.log(chalk8.green(` \u2713 Generated plugin: src/plugins/${kebab}/`));
579
+ console.log(chalk9.green(` \u2713 Generated plugin: src/plugins/${kebab}/`));
521
580
  console.log();
522
581
  console.log(" Files created:");
523
- console.log(chalk8.dim(` src/plugins/${kebab}/index.ts`));
524
- console.log(chalk8.dim(` src/plugins/${kebab}/api/admin/${kebab}/route.ts`));
582
+ console.log(chalk9.dim(` src/plugins/${kebab}/index.ts`));
583
+ console.log(chalk9.dim(` src/plugins/${kebab}/api/admin/${kebab}/route.ts`));
525
584
  console.log();
526
585
  console.log(" Next steps:");
527
- console.log(chalk8.dim(` 1. Add the plugin to your meridian.config.ts:`));
528
- console.log(chalk8.dim(` plugins: [{ resolve: "./src/plugins/${kebab}" }]`));
529
- console.log(chalk8.dim(` 2. Start the dev server: \`npm run dev\``));
586
+ console.log(chalk9.dim(` 1. Add the plugin to your meridian.config.ts:`));
587
+ console.log(chalk9.dim(` plugins: [{ resolve: "./src/plugins/${kebab}" }]`));
588
+ console.log(chalk9.dim(` 2. Start the dev server: \`npm run dev\``));
530
589
  }
531
590
 
532
591
  // src/commands/generate/subscriber.ts
533
- import path8 from "path";
534
- import { existsSync as existsSync6 } from "fs";
535
- import chalk9 from "chalk";
592
+ import path9 from "path";
593
+ import { existsSync as existsSync7 } from "fs";
594
+ import chalk10 from "chalk";
536
595
  async function generateSubscriber(eventName) {
537
596
  const rootDir = findProjectRoot();
538
597
  if (!rootDir) {
539
- console.error(chalk9.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
598
+ console.error(chalk10.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
540
599
  process.exit(1);
541
600
  }
542
601
  if (!eventName) {
543
- console.error(chalk9.red(" \u2716 Event name is required. Usage: meridian generate subscriber <event>"));
602
+ console.error(chalk10.red(" \u2716 Event name is required. Usage: meridian generate subscriber <event>"));
544
603
  process.exit(1);
545
604
  }
546
605
  const fileName = toKebabCase(eventName.replace(/\./g, "-"));
547
- const filePath = path8.join(rootDir, "src", "subscribers", `${fileName}.ts`);
548
- if (existsSync6(filePath)) {
549
- console.error(chalk9.red(` \u2716 Subscriber already exists: src/subscribers/${fileName}.ts`));
606
+ const filePath = path9.join(rootDir, "src", "subscribers", `${fileName}.ts`);
607
+ if (existsSync7(filePath)) {
608
+ console.error(chalk10.red(` \u2716 Subscriber already exists: src/subscribers/${fileName}.ts`));
550
609
  process.exit(1);
551
610
  }
552
611
  await writeFile(filePath, renderSubscriber(eventName));
553
- console.log(chalk9.green(` \u2713 Generated subscriber: src/subscribers/${fileName}.ts`));
612
+ console.log(chalk10.green(` \u2713 Generated subscriber: src/subscribers/${fileName}.ts`));
554
613
  console.log();
555
614
  console.log(" Listens for event:");
556
- console.log(chalk9.dim(` "${eventName}"`));
615
+ console.log(chalk10.dim(` "${eventName}"`));
557
616
  console.log();
558
617
  console.log(" The file is auto-loaded by the framework on next dev restart.");
559
618
  }
560
619
 
561
620
  // src/commands/generate/job.ts
562
- import path9 from "path";
563
- import { existsSync as existsSync7 } from "fs";
564
- import chalk10 from "chalk";
621
+ import path10 from "path";
622
+ import { existsSync as existsSync8 } from "fs";
623
+ import chalk11 from "chalk";
565
624
  async function generateJob(name, schedule) {
566
625
  const rootDir = findProjectRoot();
567
626
  if (!rootDir) {
568
- console.error(chalk10.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
627
+ console.error(chalk11.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
569
628
  process.exit(1);
570
629
  }
571
630
  if (!name) {
572
- console.error(chalk10.red(" \u2716 Job name is required. Usage: meridian generate job <name>"));
631
+ console.error(chalk11.red(" \u2716 Job name is required. Usage: meridian generate job <name>"));
573
632
  process.exit(1);
574
633
  }
575
634
  const kebab = toKebabCase(name);
576
- const filePath = path9.join(rootDir, "src", "jobs", `${kebab}.ts`);
577
- if (existsSync7(filePath)) {
578
- console.error(chalk10.red(` \u2716 Job already exists: src/jobs/${kebab}.ts`));
635
+ const filePath = path10.join(rootDir, "src", "jobs", `${kebab}.ts`);
636
+ if (existsSync8(filePath)) {
637
+ console.error(chalk11.red(` \u2716 Job already exists: src/jobs/${kebab}.ts`));
579
638
  process.exit(1);
580
639
  }
581
640
  await writeFile(filePath, renderJob(kebab, schedule));
582
- console.log(chalk10.green(` \u2713 Generated job: src/jobs/${kebab}.ts`));
641
+ console.log(chalk11.green(` \u2713 Generated job: src/jobs/${kebab}.ts`));
583
642
  console.log();
584
643
  console.log(" Schedule:");
585
- console.log(chalk10.dim(` ${schedule}`));
644
+ console.log(chalk11.dim(` ${schedule}`));
586
645
  console.log();
587
646
  console.log(" The job is auto-loaded by the framework on next dev restart.");
588
647
  }
589
648
 
590
649
  // src/commands/generate/route.ts
591
- import path10 from "path";
592
- import { existsSync as existsSync8 } from "fs";
593
- import chalk11 from "chalk";
650
+ import path11 from "path";
651
+ import { existsSync as existsSync9 } from "fs";
652
+ import chalk12 from "chalk";
594
653
  var VALID_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
595
654
  async function generateRoute(routePath, methods) {
596
655
  const rootDir = findProjectRoot();
597
656
  if (!rootDir) {
598
- console.error(chalk11.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
657
+ console.error(chalk12.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
599
658
  process.exit(1);
600
659
  }
601
660
  if (!routePath) {
602
- console.error(chalk11.red(" \u2716 Route path is required. Usage: meridian generate route <path>"));
661
+ console.error(chalk12.red(" \u2716 Route path is required. Usage: meridian generate route <path>"));
603
662
  process.exit(1);
604
663
  }
605
664
  const normalized = routePath.replace(/^\//, "");
606
- const filePath = path10.join(rootDir, "src", "api", normalized, "route.ts");
607
- const resolvedFile = path10.resolve(filePath);
608
- const resolvedBase = path10.resolve(rootDir, "src", "api");
609
- if (!resolvedFile.startsWith(resolvedBase + path10.sep)) {
610
- console.error(chalk11.red(" \u2716 Invalid route path: must resolve within src/api/"));
665
+ const filePath = path11.join(rootDir, "src", "api", normalized, "route.ts");
666
+ const resolvedFile = path11.resolve(filePath);
667
+ const resolvedBase = path11.resolve(rootDir, "src", "api");
668
+ if (!resolvedFile.startsWith(resolvedBase + path11.sep)) {
669
+ console.error(chalk12.red(" \u2716 Invalid route path: must resolve within src/api/"));
611
670
  process.exit(1);
612
671
  }
613
- if (existsSync8(filePath)) {
614
- console.error(chalk11.red(` \u2716 Route already exists: src/api/${normalized}/route.ts`));
672
+ if (existsSync9(filePath)) {
673
+ console.error(chalk12.red(` \u2716 Route already exists: src/api/${normalized}/route.ts`));
615
674
  process.exit(1);
616
675
  }
617
676
  const normalizedMethods = methods.map((m) => m.toUpperCase());
618
677
  const invalid = normalizedMethods.filter((m) => !VALID_METHODS.includes(m));
619
678
  if (invalid.length > 0) {
620
- console.error(chalk11.red(` \u2716 Invalid HTTP methods: ${invalid.join(", ")}. Valid: ${VALID_METHODS.join(", ")}`));
679
+ console.error(chalk12.red(` \u2716 Invalid HTTP methods: ${invalid.join(", ")}. Valid: ${VALID_METHODS.join(", ")}`));
621
680
  process.exit(1);
622
681
  }
623
682
  await writeFile(filePath, renderRoute(normalizedMethods));
624
- console.log(chalk11.green(` \u2713 Generated route: src/api/${normalized}/route.ts`));
683
+ console.log(chalk12.green(` \u2713 Generated route: src/api/${normalized}/route.ts`));
625
684
  console.log();
626
685
  console.log(" Handlers exported:");
627
686
  for (const m of normalizedMethods) {
628
- console.log(chalk11.dim(` ${m} /${normalized}`));
687
+ console.log(chalk12.dim(` ${m} /${normalized}`));
629
688
  }
630
689
  console.log();
631
690
  console.log(" The route is auto-loaded by the framework on next dev restart.");
632
691
  }
633
692
 
634
693
  // src/commands/user-create.ts
635
- import path11 from "path";
636
- import chalk12 from "chalk";
694
+ import path12 from "path";
695
+ import chalk13 from "chalk";
637
696
  import ora2 from "ora";
638
697
  import prompts from "prompts";
639
- import { execa as execa4 } from "execa";
698
+ import { execa as execa5 } from "execa";
640
699
  var ROLES = ["super-admin", "admin", "moderator", "member"];
641
700
  async function runUserCreate(opts) {
642
701
  const rootDir = findProjectRoot();
643
702
  if (!rootDir) {
644
703
  console.error(
645
- chalk12.red(
704
+ chalk13.red(
646
705
  " \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"
647
706
  )
648
707
  );
649
708
  process.exit(1);
650
709
  }
651
710
  if (opts.role && !ROLES.includes(opts.role)) {
652
- console.error(chalk12.red(` \u2716 Invalid role "${opts.role}". Must be one of: ${ROLES.join(", ")}`));
711
+ console.error(chalk13.red(` \u2716 Invalid role "${opts.role}". Must be one of: ${ROLES.join(", ")}`));
653
712
  process.exit(1);
654
713
  }
655
714
  const response = await prompts(
@@ -706,7 +765,7 @@ async function runUserCreate(opts) {
706
765
  ],
707
766
  {
708
767
  onCancel: () => {
709
- console.log(chalk12.yellow("\n Cancelled."));
768
+ console.log(chalk13.yellow("\n Cancelled."));
710
769
  process.exit(0);
711
770
  }
712
771
  }
@@ -747,11 +806,11 @@ await app.stop()
747
806
  process.exit(output.success ? 0 : 1)
748
807
  `;
749
808
  const { randomBytes } = await import("crypto");
750
- const scriptPath = path11.join(rootDir, `.meridian-user-create-${randomBytes(8).toString("hex")}.mjs`);
809
+ const scriptPath = path12.join(rootDir, `.meridian-user-create-${randomBytes(8).toString("hex")}.mjs`);
751
810
  const { writeFile: writeFile2, unlink } = await import("fs/promises");
752
811
  await writeFile2(scriptPath, script, { encoding: "utf-8", mode: 384 });
753
812
  try {
754
- const result = await execa4("node", ["--import", "tsx/esm", scriptPath], {
813
+ const result = await execa5("node", ["--import", "tsx/esm", scriptPath], {
755
814
  cwd: rootDir,
756
815
  stdio: "pipe",
757
816
  env: { ...process.env, NODE_ENV: "development", MERIDIAN_USER_PASSWORD: password }
@@ -760,7 +819,7 @@ process.exit(output.success ? 0 : 1)
760
819
  const output = JSON.parse(lines[lines.length - 1]);
761
820
  if (output.success) {
762
821
  spinner.succeed(
763
- `User created: ${chalk12.green(output.user.email)} (${chalk12.cyan(role)})`
822
+ `User created: ${chalk13.green(output.user.email)} (${chalk13.cyan(role)})`
764
823
  );
765
824
  } else {
766
825
  spinner.fail(output.error ?? "Failed to create user");
@@ -772,12 +831,12 @@ process.exit(output.success ? 0 : 1)
772
831
  try {
773
832
  const lines = err.stdout.trim().split("\n");
774
833
  const output = JSON.parse(lines[lines.length - 1]);
775
- console.error(chalk12.red(` ${output.error ?? err.stdout}`));
834
+ console.error(chalk13.red(` ${output.error ?? err.stdout}`));
776
835
  } catch {
777
- console.error(chalk12.red(` ${err.stdout}`));
836
+ console.error(chalk13.red(` ${err.stdout}`));
778
837
  }
779
838
  }
780
- if (err.stderr) console.error(chalk12.red(err.stderr));
839
+ if (err.stderr) console.error(chalk13.red(err.stderr));
781
840
  process.exit(1);
782
841
  } finally {
783
842
  await unlink(scriptPath).catch(() => null);
@@ -799,6 +858,12 @@ program.command("dev").description("Start the development server").action(() =>
799
858
  process.exit(1);
800
859
  });
801
860
  });
861
+ program.command("start").description("Start the server in production mode").action(() => {
862
+ runStart().catch((err) => {
863
+ console.error(err);
864
+ process.exit(1);
865
+ });
866
+ });
802
867
  program.command("build").description("Type-check the project").action(() => {
803
868
  runBuild().catch((err) => {
804
869
  console.error(err);
@@ -820,7 +885,7 @@ program.command("db:generate <name>").description("Generate a new migration file
820
885
  program.command("serve-dashboard").description("Serve the admin dashboard as a static site").option("-p, --port <port>", "Port to serve on", "5174").action((options) => {
821
886
  const port = Number(options.port);
822
887
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
823
- console.error(chalk13.red(` \u2716 Invalid port: ${options.port}`));
888
+ console.error(chalk14.red(` \u2716 Invalid port: ${options.port}`));
824
889
  process.exit(1);
825
890
  }
826
891
  runServeDashboard(port).catch((err) => {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runNew
4
- } from "./chunk-EE7FQVVB.js";
4
+ } from "./chunk-FNX5ZWEV.js";
5
5
 
6
6
  // src/index.ts
7
7
  var projectName = process.argv[2];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-meridian-app",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "description": "Create a new Meridian project or manage an existing one",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",