create-meridian-app 0.1.13 → 0.1.15

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.
@@ -419,6 +419,7 @@ ${handlers.join("\n\n")}
419
419
 
420
420
  // src/utils.ts
421
421
  import path from "path";
422
+ import { randomBytes } from "crypto";
422
423
  import fs from "fs/promises";
423
424
  import { existsSync } from "fs";
424
425
  import { execa } from "execa";
@@ -462,8 +463,8 @@ process.stdout.write(JSON.stringify({
462
463
  dashboardPort: c?.admin?.port ?? 5174,
463
464
  }))
464
465
  `;
465
- const scriptPath = path.join(rootDir, ".meridian-ports-tmp.mjs");
466
- await fs.writeFile(scriptPath, script, "utf-8");
466
+ const scriptPath = path.join(rootDir, `.meridian-ports-${randomBytes(8).toString("hex")}.mjs`);
467
+ await fs.writeFile(scriptPath, script, { encoding: "utf-8", mode: 384 });
467
468
  try {
468
469
  const result = await execa("node", ["--import", "tsx/esm", scriptPath], { cwd: rootDir });
469
470
  return JSON.parse(result.stdout);
@@ -480,6 +481,10 @@ async function runNew(projectName) {
480
481
  console.log(chalk.bold(" Create Meridian App"));
481
482
  console.log();
482
483
  let name = projectName;
484
+ if (name && !/^[a-z0-9-_]+$/.test(name)) {
485
+ console.error(chalk.red(" \u2716 Project name must contain only lowercase letters, numbers, hyphens, and underscores"));
486
+ process.exit(1);
487
+ }
483
488
  if (!name) {
484
489
  const res = await prompts(
485
490
  {
package/dist/cli.js CHANGED
@@ -14,10 +14,11 @@ import {
14
14
  toKebabCase,
15
15
  toPascalCase,
16
16
  writeFile
17
- } from "./chunk-U5TMTVEV.js";
17
+ } from "./chunk-DUCNQ62I.js";
18
18
 
19
19
  // src/cli.ts
20
20
  import { Command } from "commander";
21
+ import chalk13 from "chalk";
21
22
 
22
23
  // src/commands/dev.ts
23
24
  import path2 from "path";
@@ -131,6 +132,13 @@ function startDashboardServer(distDir, port, apiPort, apiHost = "localhost", adm
131
132
  return;
132
133
  }
133
134
  let filePath = path.join(distDir, urlPath === "/" ? "index.html" : urlPath);
135
+ const resolvedFile = path.resolve(filePath);
136
+ const resolvedDist = path.resolve(distDir);
137
+ if (!resolvedFile.startsWith(resolvedDist + path.sep) && resolvedFile !== resolvedDist) {
138
+ res.writeHead(403);
139
+ res.end("Forbidden");
140
+ return;
141
+ }
134
142
  if (!existsSync(filePath) || fs.statSync(filePath).isDirectory()) {
135
143
  filePath = path.join(distDir, "index.html");
136
144
  }
@@ -306,9 +314,10 @@ const app = await bootstrap({ rootDir: ${JSON.stringify(rootDir)} })
306
314
  await app.stop()
307
315
  process.exit(0)
308
316
  `;
309
- const scriptPath = path3.join(rootDir, ".meridian-migrate-tmp.mjs");
317
+ const { randomBytes } = await import("crypto");
318
+ const scriptPath = path3.join(rootDir, `.meridian-migrate-${randomBytes(8).toString("hex")}.mjs`);
310
319
  const { writeFile: writeFile2, unlink } = await import("fs/promises");
311
- await writeFile2(scriptPath, script, "utf-8");
320
+ await writeFile2(scriptPath, script, { encoding: "utf-8", mode: 384 });
312
321
  try {
313
322
  await execa3("node", ["--import", "tsx/esm", scriptPath], {
314
323
  cwd: rootDir,
@@ -586,6 +595,12 @@ async function generateRoute(routePath, methods) {
586
595
  }
587
596
  const normalized = routePath.replace(/^\//, "");
588
597
  const filePath = path10.join(rootDir, "src", "api", normalized, "route.ts");
598
+ const resolvedFile = path10.resolve(filePath);
599
+ const resolvedBase = path10.resolve(rootDir, "src", "api");
600
+ if (!resolvedFile.startsWith(resolvedBase + path10.sep)) {
601
+ console.error(chalk11.red(" \u2716 Invalid route path: must resolve within src/api/"));
602
+ process.exit(1);
603
+ }
589
604
  if (existsSync8(filePath)) {
590
605
  console.error(chalk11.red(` \u2716 Route already exists: src/api/${normalized}/route.ts`));
591
606
  process.exit(1);
@@ -613,6 +628,7 @@ import chalk12 from "chalk";
613
628
  import ora2 from "ora";
614
629
  import prompts from "prompts";
615
630
  import { execa as execa4 } from "execa";
631
+ var ROLES = ["super-admin", "admin", "moderator", "member"];
616
632
  async function runUserCreate(opts) {
617
633
  const rootDir = findProjectRoot();
618
634
  if (!rootDir) {
@@ -623,6 +639,10 @@ async function runUserCreate(opts) {
623
639
  );
624
640
  process.exit(1);
625
641
  }
642
+ if (opts.role && !ROLES.includes(opts.role)) {
643
+ console.error(chalk12.red(` \u2716 Invalid role "${opts.role}". Must be one of: ${ROLES.join(", ")}`));
644
+ process.exit(1);
645
+ }
626
646
  const response = await prompts(
627
647
  [
628
648
  {
@@ -703,7 +723,7 @@ let output
703
723
  try {
704
724
  const result = await authService.register({
705
725
  email: ${JSON.stringify(email)},
706
- password: ${JSON.stringify(password)},
726
+ password: process.env.MERIDIAN_USER_PASSWORD,
707
727
  first_name: ${JSON.stringify(first_name || null)},
708
728
  last_name: ${JSON.stringify(last_name || null)},
709
729
  role: ${JSON.stringify(role)},
@@ -717,14 +737,15 @@ console.log(JSON.stringify(output))
717
737
  await app.stop()
718
738
  process.exit(output.success ? 0 : 1)
719
739
  `;
720
- const scriptPath = path11.join(rootDir, ".meridian-user-create-tmp.mjs");
740
+ const { randomBytes } = await import("crypto");
741
+ const scriptPath = path11.join(rootDir, `.meridian-user-create-${randomBytes(8).toString("hex")}.mjs`);
721
742
  const { writeFile: writeFile2, unlink } = await import("fs/promises");
722
- await writeFile2(scriptPath, script, "utf-8");
743
+ await writeFile2(scriptPath, script, { encoding: "utf-8", mode: 384 });
723
744
  try {
724
745
  const result = await execa4("node", ["--import", "tsx/esm", scriptPath], {
725
746
  cwd: rootDir,
726
747
  stdio: "pipe",
727
- env: { ...process.env, NODE_ENV: "development" }
748
+ env: { ...process.env, NODE_ENV: "development", MERIDIAN_USER_PASSWORD: password }
728
749
  });
729
750
  const lines = result.stdout.trim().split("\n");
730
751
  const output = JSON.parse(lines[lines.length - 1]);
@@ -788,7 +809,12 @@ program.command("db:generate <name>").description("Generate a new migration file
788
809
  });
789
810
  });
790
811
  program.command("serve-dashboard").description("Serve the admin dashboard as a static site").option("-p, --port <port>", "Port to serve on", "5174").action((options) => {
791
- runServeDashboard(Number(options.port)).catch((err) => {
812
+ const port = Number(options.port);
813
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
814
+ console.error(chalk13.red(` \u2716 Invalid port: ${options.port}`));
815
+ process.exit(1);
816
+ }
817
+ runServeDashboard(port).catch((err) => {
792
818
  console.error(err);
793
819
  process.exit(1);
794
820
  });
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runNew
4
- } from "./chunk-U5TMTVEV.js";
4
+ } from "./chunk-DUCNQ62I.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.13",
3
+ "version": "0.1.15",
4
4
  "description": "Create a new Meridian project or manage an existing one",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",