@rebasepro/cli 0.9.1-canary.74adfbe → 0.9.1-canary.78ab3dc

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.
@@ -24,6 +24,8 @@ export interface InitOptions {
24
24
  introspect?: boolean;
25
25
  /** Starter template preset. */
26
26
  preset: TemplatePreset;
27
+ /** Whether `preset` came from an explicit --template rather than the default. */
28
+ explicitPreset?: boolean;
27
29
  /** Which parts of Rebase to scaffold. */
28
30
  flavor: TemplateFlavor;
29
31
  /** Detected package manager (pnpm or npm). */
@@ -51,5 +53,15 @@ export interface BuildQuestionsParams {
51
53
  * types registered by the installed version of inquirer.
52
54
  */
53
55
  export declare function buildInitQuestions(params: BuildQuestionsParams): Record<string, unknown>[];
56
+ /**
57
+ * The `cd` a user must type to enter the new project.
58
+ *
59
+ * Not the project's basename: `init apps/my-app` has to say `cd apps/my-app`,
60
+ * and `init .` returns "" because they are already in the project.
61
+ */
62
+ export declare function formatCdTarget(cwd: string, targetDirectory: string): string;
63
+ /** Help for `rebase init` — the flags were previously only discoverable by
64
+ * triggering the non-TTY error. */
65
+ export declare function printInitHelp(): void;
54
66
  export declare function createRebaseApp(rawArgs: string[]): Promise<void>;
55
67
  export declare function configureEnvFile(targetDirectory: string, databaseUrl?: string): Promise<void>;
package/dist/index.es.js CHANGED
@@ -875,7 +875,54 @@ function buildInitQuestions(params) {
875
875
  });
876
876
  return questions;
877
877
  }
878
+ /**
879
+ * The `cd` a user must type to enter the new project.
880
+ *
881
+ * Not the project's basename: `init apps/my-app` has to say `cd apps/my-app`,
882
+ * and `init .` returns "" because they are already in the project.
883
+ */
884
+ function formatCdTarget(cwd, targetDirectory) {
885
+ return path.relative(cwd, targetDirectory);
886
+ }
887
+ /** Help for `rebase init` — the flags were previously only discoverable by
888
+ * triggering the non-TTY error. */
889
+ function printInitHelp() {
890
+ console.log(`
891
+ ${chalk.bold("rebase init")} — Create a new Rebase project
892
+
893
+ ${chalk.bold("Usage")}
894
+ rebase init ${chalk.blue("[name]")} [options]
895
+
896
+ ${chalk.gray("The name may be a nested path (apps/my-app) or \".\" for the current directory.")}
897
+ ${chalk.gray("Defaults to \"my-rebase-app\" when omitted with --yes.")}
898
+
899
+ ${chalk.bold("Options")}
900
+ ${chalk.blue("-t, --template")} ${chalk.gray("<preset>")} blog | ecommerce | blank ${chalk.gray("(default: blog)")}
901
+ ${chalk.blue("-f, --flavor")} ${chalk.gray("<flavor>")} cms | baas ${chalk.gray("(default: cms)")}
902
+ ${chalk.blue("-y, --yes")} Accept defaults, never prompt ${chalk.gray("(required for CI / non-TTY)")}
903
+ ${chalk.blue("-i, --install")} Install dependencies after scaffolding
904
+ ${chalk.blue("-g, --git")} Initialize a git repository and make an initial commit
905
+ ${chalk.blue("--database-url")} ${chalk.gray("<url>")} Use an existing database instead of the generated one
906
+ ${chalk.blue("--introspect")} Generate collections from that database ${chalk.gray("(implies --template blank; needs --install)")}
907
+ ${chalk.blue("--project")} ${chalk.gray("<slug>")} Link the scaffold to a Rebase Cloud project
908
+ ${chalk.blue("--setup-key")} ${chalk.gray("<key>")} One-time key authenticating the cloud link ${chalk.gray("(use with --project)")}
909
+
910
+ ${chalk.bold("Flavors")}
911
+ ${chalk.blue("cms")} BaaS + admin UI, driven by collections you define ${chalk.gray("(like Payload/Directus)")}
912
+ ${chalk.blue("baas")} Headless API over your database — no collections, no UI ${chalk.gray("(like Supabase)")}
913
+ ${chalk.gray("--template has no effect on this flavor.")}
914
+
915
+ ${chalk.bold("Examples")}
916
+ ${chalk.gray("$")} rebase init my-shop --template ecommerce --install
917
+ ${chalk.gray("$")} rebase init my-api --flavor baas --yes
918
+ ${chalk.gray("$")} rebase init . --yes --git
919
+ `);
920
+ }
878
921
  async function createRebaseApp(rawArgs) {
922
+ if (rawArgs.includes("--help") || rawArgs.includes("-h")) {
923
+ printInitHelp();
924
+ return;
925
+ }
879
926
  console.log(`
880
927
  ${chalk.bold("Rebase")} — Create a new project 🚀
881
928
  `);
@@ -935,6 +982,7 @@ async function promptForOptions(rawArgs, pm) {
935
982
  databaseUrl: args["--database-url"] || void 0,
936
983
  introspect: args["--introspect"] || false,
937
984
  preset: templateArg || "blog",
985
+ explicitPreset: !!templateArg,
938
986
  flavor: flavorArg || "cms",
939
987
  pm,
940
988
  pmCommands,
@@ -972,6 +1020,7 @@ async function promptForOptions(rawArgs, pm) {
972
1020
  databaseUrl: answers.databaseUrl?.trim() || void 0,
973
1021
  introspect: answers.introspect || false,
974
1022
  preset: templateArg || answers.preset || "blog",
1023
+ explicitPreset: !!templateArg,
975
1024
  flavor: flavorArg || answers.flavor || "cms",
976
1025
  pm,
977
1026
  pmCommands,
@@ -1056,6 +1105,7 @@ async function createProject$1(options) {
1056
1105
  const shipped = path.join(options.targetDirectory, from);
1057
1106
  if (fs.existsSync(shipped)) fs.renameSync(shipped, path.join(options.targetDirectory, to));
1058
1107
  }
1108
+ if (options.flavor === "baas" && options.explicitPreset) console.log(chalk.yellow(` Ignoring --template ${options.preset}: the baas flavor has no collections.`));
1059
1109
  if (options.flavor !== "baas") {
1060
1110
  if (options.introspect && options.preset !== "blank") console.log(chalk.gray(" Using the blank template: collections will come from your database."));
1061
1111
  await applyPreset(options.targetDirectory, options.introspect ? "blank" : options.preset);
@@ -1067,6 +1117,33 @@ async function createProject$1(options) {
1067
1117
  console.log(chalk.gray(" Initializing git repository..."));
1068
1118
  try {
1069
1119
  await execa("git", ["init"], { cwd: options.targetDirectory });
1120
+ try {
1121
+ await execa("git", [
1122
+ "symbolic-ref",
1123
+ "HEAD",
1124
+ "refs/heads/main"
1125
+ ], { cwd: options.targetDirectory });
1126
+ } catch {}
1127
+ await execa("git", ["add", "-A"], { cwd: options.targetDirectory });
1128
+ let identity = {};
1129
+ try {
1130
+ await execa("git", ["config", "user.email"], { cwd: options.targetDirectory });
1131
+ } catch {
1132
+ identity = {
1133
+ GIT_AUTHOR_NAME: "Rebase",
1134
+ GIT_AUTHOR_EMAIL: "noreply@rebase.pro",
1135
+ GIT_COMMITTER_NAME: "Rebase",
1136
+ GIT_COMMITTER_EMAIL: "noreply@rebase.pro"
1137
+ };
1138
+ }
1139
+ await execa("git", [
1140
+ "commit",
1141
+ "-m",
1142
+ "Initial commit from Rebase"
1143
+ ], {
1144
+ cwd: options.targetDirectory,
1145
+ env: identity
1146
+ });
1070
1147
  } catch {
1071
1148
  console.warn(chalk.yellow(" Warning: Failed to initialize git repository"));
1072
1149
  }
@@ -1097,6 +1174,7 @@ async function createProject$1(options) {
1097
1174
  console.warn(chalk.yellow(` Warning: Failed to install dependencies. You may need to run \`${installCmd.join(" ")}\` manually.`));
1098
1175
  }
1099
1176
  }
1177
+ let introspected = false;
1100
1178
  if (options.introspect) {
1101
1179
  console.log("");
1102
1180
  if (options.installDeps) {
@@ -1112,6 +1190,7 @@ async function createProject$1(options) {
1112
1190
  stdio: "inherit"
1113
1191
  });
1114
1192
  console.log(chalk.green(" Database successfully introspected!"));
1193
+ introspected = true;
1115
1194
  } catch {
1116
1195
  console.warn(chalk.yellow(" Warning: Failed to introspect database automatically."));
1117
1196
  console.warn(chalk.yellow(` You can run \`${execCmd.join(" ")}\` then \`${generateCmd.join(" ")}\` manually after setup.`));
@@ -1130,13 +1209,21 @@ async function createProject$1(options) {
1130
1209
  const runDev = pmCommands.run("dev");
1131
1210
  const runDbPush = pmCommands.run("db:push");
1132
1211
  const isBaas = options.flavor === "baas";
1133
- console.log(` ${chalk.cyan("cd")} ${options.projectName}`);
1212
+ const cdTarget = formatCdTarget(process.cwd(), options.targetDirectory);
1213
+ if (cdTarget) console.log(` ${chalk.cyan("cd")} ${cdTarget}`);
1134
1214
  if (!options.installDeps) console.log(` ${chalk.cyan(installCmd.join(" "))}`);
1135
1215
  console.log("");
1136
- if (options.databaseUrl) if (options.introspect) {
1216
+ if (options.databaseUrl) if (introspected) {
1137
1217
  console.log(chalk.gray(" # Database has been introspected & collections generated!"));
1138
1218
  console.log(chalk.gray(" # Start the development server (frontend + backend):"));
1139
1219
  console.log(` ${chalk.cyan(runDev.join(" "))}`);
1220
+ } else if (options.introspect) {
1221
+ console.log(chalk.gray(" # Introspection did not run — finish it with:"));
1222
+ console.log(` ${chalk.cyan(execCmd.join(" "))}`);
1223
+ console.log(` ${chalk.cyan(generateCmd.join(" "))}`);
1224
+ console.log("");
1225
+ console.log(chalk.gray(" # Then start the development server:"));
1226
+ console.log(` ${chalk.cyan(runDev.join(" "))}`);
1140
1227
  } else {
1141
1228
  console.log(chalk.gray(" # Your custom database is configured in .env."));
1142
1229
  console.log(chalk.gray(" # If the database is empty, push the Rebase schema to initialize it:"));
@@ -1365,7 +1452,7 @@ async function configureEnvFile(targetDirectory, databaseUrl) {
1365
1452
  envContent = envContent.replace(/^#\s*REBASE_SERVICE_KEY=.*$/m, `REBASE_SERVICE_KEY=${serviceKey}`);
1366
1453
  if (databaseUrl) {
1367
1454
  if (/[\r\n]/.test(databaseUrl)) throw new Error("Invalid DATABASE_URL: multiline values are not allowed.");
1368
- envContent = envContent.replace(/^DATABASE_URL=.*$/m, `DATABASE_URL=${databaseUrl}`);
1455
+ envContent = envContent.replace(/^DATABASE_URL=.*$/m, `DATABASE_URL=${databaseUrl}\nDATABASE_PASSWORD=${dbPassword}`);
1369
1456
  } else {
1370
1457
  const dbPort = await findAvailablePort(5432);
1371
1458
  envContent = envContent.replace(/^DATABASE_URL=.*$/m, `DATABASE_URL=postgresql://rebase:${dbPassword}@localhost:${dbPort}/rebase?options=-c%20search_path=public&sslmode=disable\nDATABASE_PASSWORD=${dbPassword}`);
@@ -6454,6 +6541,7 @@ async function entry(args) {
6454
6541
  const command = parsedArgs._[0];
6455
6542
  const subcommand = parsedArgs._[1];
6456
6543
  if (!command || parsedArgs["--help"] && ![
6544
+ "init",
6457
6545
  "schema",
6458
6546
  "db",
6459
6547
  "dev",
@@ -6584,6 +6672,6 @@ ${chalk.gray("Documentation: https://rebase.pro/docs")}
6584
6672
  `);
6585
6673
  }
6586
6674
  //#endregion
6587
- export { authCommand, buildCommand, buildInitQuestions, cloudCommand, configureEnvFile, createRebaseApp, dbCommand, detectPackageManager, devCommand, doctorCommand, entry, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, generateSdkCommand, getActiveBackendPlugin, getPMCommands, isPnpmAvailable, requireBackendDir, requireProjectRoot, resolveLocalBin, resolvePluginCliScript, resolveTsx, schemaCommand, startCommand, validateProjectName, validateTsxInstallation };
6675
+ export { authCommand, buildCommand, buildInitQuestions, cloudCommand, configureEnvFile, createRebaseApp, dbCommand, detectPackageManager, devCommand, doctorCommand, entry, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, formatCdTarget, generateSdkCommand, getActiveBackendPlugin, getPMCommands, isPnpmAvailable, printInitHelp, requireBackendDir, requireProjectRoot, resolveLocalBin, resolvePluginCliScript, resolveTsx, schemaCommand, startCommand, validateProjectName, validateTsxInstallation };
6588
6676
 
6589
6677
  //# sourceMappingURL=index.es.js.map