@rebasepro/cli 0.9.1-canary.7dddf96 → 0.9.1-canary.a57c262

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.
@@ -1,4 +1,6 @@
1
1
  import type { PackageManager, PMCommands } from "../utils/package-manager";
2
+ /** Returns an error message, or null when the name is a valid package name. */
3
+ export declare function validateProjectName(name: string): string | null;
2
4
  export type TemplatePreset = "blog" | "ecommerce" | "blank";
3
5
  /**
4
6
  * How much of Rebase to scaffold.
package/dist/index.es.js CHANGED
@@ -144,6 +144,13 @@ function findParentDir(currentDir, targetName) {
144
144
  return null;
145
145
  }
146
146
  var cliRoot = findParentDir(__dirname$1, "cli");
147
+ var PROJECT_NAME_RE = /^[a-z0-9][a-z0-9._-]*$/;
148
+ /** Returns an error message, or null when the name is a valid package name. */
149
+ function validateProjectName(name) {
150
+ if (!name.trim()) return "Project name is required";
151
+ if (!PROJECT_NAME_RE.test(name)) return "Project name must start with a lowercase letter or number and contain only lowercase letters, numbers, hyphens, dots, or underscores";
152
+ return null;
153
+ }
147
154
  var FLAVOR_CHOICES = [{
148
155
  name: "BaaS + admin — API plus an admin UI, driven by collections you define (like Payload/Directus)",
149
156
  value: "cms",
@@ -183,11 +190,7 @@ function buildInitQuestions(params) {
183
190
  name: "projectName",
184
191
  message: "Project name:",
185
192
  default: "my-rebase-app",
186
- validate: (input) => {
187
- if (!input.trim()) return "Project name is required";
188
- if (!/^[a-z0-9][a-z0-9._-]*$/.test(input)) return "Project name must start with a lowercase letter or number and contain only lowercase letters, numbers, hyphens, dots, or underscores";
189
- return true;
190
- }
193
+ validate: (input) => validateProjectName(input) ?? true
191
194
  });
192
195
  if (!flavorArg) questions.push({
193
196
  type: "select",
@@ -261,6 +264,14 @@ async function promptForOptions(rawArgs, pm) {
261
264
  });
262
265
  const nameArg = args._[0];
263
266
  const isNonInteractive = args["--yes"] || false;
267
+ if (nameArg) {
268
+ const resolvedName = path.basename(path.resolve(process.cwd(), nameArg));
269
+ const nameError = validateProjectName(resolvedName);
270
+ if (nameError) {
271
+ console.error(chalk.red(`Invalid project name "${resolvedName}": ${nameError}`));
272
+ process.exit(1);
273
+ }
274
+ }
264
275
  const templateArg = args["--template"];
265
276
  if (templateArg && !PRESET_CHOICES.some((p) => p.value === templateArg)) {
266
277
  console.error(chalk.red(`Unknown template "${templateArg}". Available: ${PRESET_CHOICES.map((p) => p.value).join(", ")}`));
@@ -343,7 +354,14 @@ async function createProject$1(options) {
343
354
  console.error(`${chalk.red.bold("ERROR")} Failed to copy template files: ${err instanceof Error ? err.message : String(err)}`);
344
355
  process.exit(1);
345
356
  }
346
- if (options.flavor !== "baas") await applyPreset(options.targetDirectory, options.preset);
357
+ for (const [from, to] of [["gitignore", ".gitignore"], ["npmrc", ".npmrc"]]) {
358
+ const shipped = path.join(options.targetDirectory, from);
359
+ if (fs.existsSync(shipped)) fs.renameSync(shipped, path.join(options.targetDirectory, to));
360
+ }
361
+ if (options.flavor !== "baas") {
362
+ if (options.introspect && options.preset !== "blank") console.log(chalk.gray(" Using the blank template: collections will come from your database."));
363
+ await applyPreset(options.targetDirectory, options.introspect ? "blank" : options.preset);
364
+ }
347
365
  await applyFlavor(options.targetDirectory, options.flavor);
348
366
  await replacePlaceholders(options);
349
367
  await configureEnvFile(options.targetDirectory, options.databaseUrl);
@@ -362,6 +380,12 @@ async function createProject$1(options) {
362
380
  "introspect",
363
381
  "--force"
364
382
  ]);
383
+ const generateCmd = pmCommands.exec("rebase", [
384
+ "schema",
385
+ "generate",
386
+ "--collections",
387
+ "../config/collections"
388
+ ]);
365
389
  if (options.installDeps) {
366
390
  console.log("");
367
391
  console.log(chalk.gray(` Installing dependencies with ${pm}...`));
@@ -385,10 +409,14 @@ async function createProject$1(options) {
385
409
  cwd: options.targetDirectory,
386
410
  stdio: "inherit"
387
411
  });
412
+ await execa(generateCmd[0], generateCmd.slice(1), {
413
+ cwd: options.targetDirectory,
414
+ stdio: "inherit"
415
+ });
388
416
  console.log(chalk.green(" Database successfully introspected!"));
389
417
  } catch {
390
418
  console.warn(chalk.yellow(" Warning: Failed to introspect database automatically."));
391
- console.warn(chalk.yellow(` You can run \`${execCmd.join(" ")}\` manually after setup.`));
419
+ console.warn(chalk.yellow(` You can run \`${execCmd.join(" ")}\` then \`${generateCmd.join(" ")}\` manually after setup.`));
392
420
  }
393
421
  } else {
394
422
  console.warn(chalk.yellow(" Skipping introspection because dependencies were not installed."));
@@ -635,7 +663,7 @@ async function configureEnvFile(targetDirectory, databaseUrl) {
635
663
  envContent = envContent.replace(/^DATABASE_URL=.*$/m, `DATABASE_URL=${databaseUrl}`);
636
664
  } else {
637
665
  const dbPort = await findAvailablePort(5432);
638
- envContent = envContent.replace(/^DATABASE_URL=.*$/m, `DATABASE_URL=postgresql://rebase:${dbPassword}@localhost:${dbPort}/rebase?options=-c%20search_path=public\nDATABASE_PASSWORD=${dbPassword}`);
666
+ envContent = envContent.replace(/^DATABASE_URL=.*$/m, `DATABASE_URL=postgresql://rebase:${dbPassword}@localhost:${dbPort}/rebase?options=-c%20search_path=public&sslmode=disable\nDATABASE_PASSWORD=${dbPassword}`);
639
667
  const dockerComposePath = path.join(targetDirectory, "docker-compose.yml");
640
668
  if (fs.existsSync(dockerComposePath)) {
641
669
  let dockerComposeContent = fs.readFileSync(dockerComposePath, "utf-8");
@@ -838,13 +866,14 @@ function getActiveBackendPlugin(backendDir) {
838
866
  * Resolve the active plugin's CLI script.
839
867
  */
840
868
  function resolvePluginCliScript(backendDir, pluginName) {
841
- const candidates = [
842
- path.join(backendDir, "node_modules", pluginName, "src", "cli.ts"),
843
- path.join(backendDir, "node_modules", pluginName, "dist", "cli.js"),
844
- path.resolve(backendDir, "..", "..", "..", "packages", pluginName.replace("@rebasepro/", ""), "src", "cli.ts"),
845
- path.resolve(backendDir, "..", "..", "packages", pluginName.replace("@rebasepro/", ""), "src", "cli.ts"),
846
- path.resolve(backendDir, "..", "packages", pluginName.replace("@rebasepro/", ""), "src", "cli.ts")
847
- ];
869
+ const candidates = [];
870
+ let dir = path.resolve(backendDir);
871
+ const fsRoot = path.parse(dir).root;
872
+ while (dir !== fsRoot) {
873
+ candidates.push(path.join(dir, "node_modules", pluginName, "src", "cli.ts"), path.join(dir, "node_modules", pluginName, "dist", "cli.js"));
874
+ dir = path.dirname(dir);
875
+ }
876
+ candidates.push(path.resolve(backendDir, "..", "..", "..", "packages", pluginName.replace("@rebasepro/", ""), "src", "cli.ts"), path.resolve(backendDir, "..", "..", "packages", pluginName.replace("@rebasepro/", ""), "src", "cli.ts"), path.resolve(backendDir, "..", "packages", pluginName.replace("@rebasepro/", ""), "src", "cli.ts"));
848
877
  for (const candidate of candidates) if (fs.existsSync(candidate)) return candidate;
849
878
  return null;
850
879
  }
@@ -3993,6 +4022,6 @@ ${chalk.gray("Documentation: https://rebase.pro/docs")}
3993
4022
  `);
3994
4023
  }
3995
4024
  //#endregion
3996
- export { authCommand, buildCommand, buildInitQuestions, cloudCommand, configureEnvFile, createRebaseApp, dbCommand, detectPackageManager, devCommand, doctorCommand, entry, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, generateSdkCommand, getActiveBackendPlugin, getPMCommands, requireBackendDir, requireProjectRoot, resolveLocalBin, resolvePluginCliScript, resolveTsx, schemaCommand, startCommand, validateTsxInstallation };
4025
+ export { authCommand, buildCommand, buildInitQuestions, cloudCommand, configureEnvFile, createRebaseApp, dbCommand, detectPackageManager, devCommand, doctorCommand, entry, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, generateSdkCommand, getActiveBackendPlugin, getPMCommands, requireBackendDir, requireProjectRoot, resolveLocalBin, resolvePluginCliScript, resolveTsx, schemaCommand, startCommand, validateProjectName, validateTsxInstallation };
3997
4026
 
3998
4027
  //# sourceMappingURL=index.es.js.map