@rebasepro/cli 0.0.1-canary.f81da60 → 0.1.2

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/dist/index.es.js CHANGED
@@ -11,6 +11,45 @@ import crypto from "crypto";
11
11
  import { generateSDK } from "@rebasepro/sdk-generator";
12
12
  import { execSync, spawn } from "child_process";
13
13
  import * as os from "os";
14
+ function detectPackageManager(targetDir) {
15
+ const userAgent = process.env.npm_config_user_agent ?? "";
16
+ if (userAgent.startsWith("npm/")) return "npm";
17
+ if (userAgent.startsWith("pnpm/")) return "pnpm";
18
+ if (targetDir) {
19
+ if (fs.existsSync(path.join(targetDir, "package-lock.json"))) return "npm";
20
+ if (fs.existsSync(path.join(targetDir, "pnpm-lock.yaml"))) return "pnpm";
21
+ }
22
+ const cwd = process.cwd();
23
+ if (cwd !== targetDir) {
24
+ if (fs.existsSync(path.join(cwd, "package-lock.json"))) return "npm";
25
+ if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
26
+ }
27
+ return "pnpm";
28
+ }
29
+ function getPMCommands(pm) {
30
+ if (pm === "npm") {
31
+ return {
32
+ name: "npm",
33
+ install: ["npm", "install"],
34
+ run: (script) => ["npm", "run", script],
35
+ exec: (bin, args) => ["npx", bin, ...args],
36
+ view: (pkg, field) => ["npm", "view", pkg, field],
37
+ runAll: (script) => ["npm", "run", script, "--workspaces", "--if-present"],
38
+ runWorkspace: (workspace, script) => ["npm", "run", script, "-w", workspace],
39
+ workspaceProtocol: "*"
40
+ };
41
+ }
42
+ return {
43
+ name: "pnpm",
44
+ install: ["pnpm", "install"],
45
+ run: (script) => ["pnpm", "run", script],
46
+ exec: (bin, args) => ["pnpm", "exec", bin, ...args],
47
+ view: (pkg, field) => ["pnpm", "view", pkg, field],
48
+ runAll: (script) => ["pnpm", "-r", "run", script],
49
+ runWorkspace: (workspace, script) => ["pnpm", "--filter", workspace, script],
50
+ workspaceProtocol: "workspace:*"
51
+ };
52
+ }
14
53
  const access = promisify(fs.access);
15
54
  const copy = promisify(ncp);
16
55
  const __filename$2 = fileURLToPath(import.meta.url);
@@ -30,10 +69,11 @@ async function createRebaseApp(rawArgs) {
30
69
  console.log(`
31
70
  ${chalk.bold("Rebase")} — Create a new project šŸš€
32
71
  `);
33
- const options = await promptForOptions(rawArgs);
72
+ const pm = detectPackageManager();
73
+ const options = await promptForOptions(rawArgs, pm);
34
74
  await createProject(options);
35
75
  }
36
- async function promptForOptions(rawArgs) {
76
+ async function promptForOptions(rawArgs, pm) {
37
77
  const args = arg(
38
78
  {
39
79
  "--git": Boolean,
@@ -76,7 +116,7 @@ async function promptForOptions(rawArgs) {
76
116
  questions.push({
77
117
  type: "confirm",
78
118
  name: "installDeps",
79
- message: "Install dependencies with pnpm?",
119
+ message: `Install dependencies with ${pm}?`,
80
120
  default: true
81
121
  });
82
122
  }
@@ -97,6 +137,7 @@ async function promptForOptions(rawArgs) {
97
137
  const targetDirectory = path.resolve(process.cwd(), nameArg || answers.projectName);
98
138
  const projectName = path.basename(targetDirectory);
99
139
  const templateDirectory = path.resolve(cliRoot, "templates", "template");
140
+ const pmCommands = getPMCommands(pm);
100
141
  return {
101
142
  projectName,
102
143
  git: args["--git"] || answers.git || false,
@@ -104,7 +145,9 @@ async function promptForOptions(rawArgs) {
104
145
  targetDirectory,
105
146
  templateDirectory,
106
147
  databaseUrl: answers.databaseUrl?.trim() || void 0,
107
- introspect: answers.introspect || false
148
+ introspect: answers.introspect || false,
149
+ pm,
150
+ pmCommands
108
151
  };
109
152
  }
110
153
  async function createProject(options) {
@@ -146,17 +189,20 @@ async function createProject(options) {
146
189
  console.warn(chalk.yellow(" Warning: Failed to initialize git repository"));
147
190
  }
148
191
  }
192
+ const { pm, pmCommands } = options;
193
+ const installCmd = pmCommands.install;
194
+ const execCmd = pmCommands.exec("rebase", ["schema", "introspect", "--force"]);
149
195
  if (options.installDeps) {
150
196
  console.log("");
151
- console.log(chalk.gray(" Installing dependencies with pnpm..."));
197
+ console.log(chalk.gray(` Installing dependencies with ${pm}...`));
152
198
  console.log("");
153
199
  try {
154
- await execa("pnpm", ["install"], {
200
+ await execa(installCmd[0], installCmd.slice(1), {
155
201
  cwd: options.targetDirectory,
156
202
  stdio: "inherit"
157
203
  });
158
204
  } catch {
159
- console.warn(chalk.yellow(" Warning: Failed to install dependencies. You may need to run `pnpm install` manually."));
205
+ console.warn(chalk.yellow(` Warning: Failed to install dependencies. You may need to run \`${installCmd.join(" ")}\` manually.`));
160
206
  }
161
207
  }
162
208
  if (options.introspect) {
@@ -165,18 +211,18 @@ async function createProject(options) {
165
211
  console.log(chalk.gray(" Introspecting database and generating collections..."));
166
212
  console.log("");
167
213
  try {
168
- await execa("pnpm", ["exec", "rebase", "schema", "introspect", "--force"], {
214
+ await execa(execCmd[0], execCmd.slice(1), {
169
215
  cwd: options.targetDirectory,
170
216
  stdio: "inherit"
171
217
  });
172
218
  console.log(chalk.green(" Database successfully introspected!"));
173
219
  } catch {
174
220
  console.warn(chalk.yellow(" Warning: Failed to introspect database automatically."));
175
- console.warn(chalk.yellow(" You can run `pnpm exec rebase schema introspect` manually after setup."));
221
+ console.warn(chalk.yellow(` You can run \`${execCmd.join(" ")}\` manually after setup.`));
176
222
  }
177
223
  } else {
178
224
  console.warn(chalk.yellow(" Skipping introspection because dependencies were not installed."));
179
- console.warn(chalk.yellow(" Run `pnpm install` then `pnpm exec rebase schema introspect` manually."));
225
+ console.warn(chalk.yellow(` Run \`${installCmd.join(" ")}\` then \`${execCmd.join(" ")}\` manually.`));
180
226
  }
181
227
  }
182
228
  console.log("");
@@ -184,9 +230,10 @@ async function createProject(options) {
184
230
  console.log("");
185
231
  console.log(chalk.bold("Next steps:"));
186
232
  console.log("");
233
+ const runDev = pmCommands.run("dev");
187
234
  console.log(` ${chalk.cyan("cd")} ${options.projectName}`);
188
235
  if (!options.installDeps) {
189
- console.log(` ${chalk.cyan("pnpm install")}`);
236
+ console.log(` ${chalk.cyan(installCmd.join(" "))}`);
190
237
  }
191
238
  console.log("");
192
239
  if (options.databaseUrl) {
@@ -199,7 +246,7 @@ async function createProject(options) {
199
246
  console.log(chalk.gray(" # Then start the dev server:"));
200
247
  }
201
248
  console.log("");
202
- console.log(` ${chalk.cyan("pnpm dev")}`);
249
+ console.log(` ${chalk.cyan(runDev.join(" "))}`);
203
250
  console.log("");
204
251
  console.log(chalk.gray("This starts both the backend (Hono + PostgreSQL)") + chalk.gray(" and the frontend (Vite + React) concurrently."));
205
252
  console.log("");
@@ -213,7 +260,8 @@ async function replacePlaceholders(options) {
213
260
  "frontend/package.json",
214
261
  "backend/package.json",
215
262
  "config/package.json",
216
- "frontend/index.html"
263
+ "frontend/index.html",
264
+ "README.md"
217
265
  ];
218
266
  const packageJsonPath = path.resolve(cliRoot, "package.json");
219
267
  let cliVersion = "latest";
@@ -222,22 +270,23 @@ async function replacePlaceholders(options) {
222
270
  cliVersion = pkg.version || "latest";
223
271
  }
224
272
  const versionCache = /* @__PURE__ */ new Map();
273
+ const viewBin = "npm";
225
274
  const getPackageVersion = async (pkgName) => {
226
275
  if (versionCache.has(pkgName)) return versionCache.get(pkgName);
227
276
  let versionToUse = cliVersion;
228
277
  try {
229
- const { stdout } = await execa("pnpm", ["view", `${pkgName}@${cliVersion}`, "version"]);
278
+ const { stdout } = await execa(viewBin, ["view", `${pkgName}@${cliVersion}`, "version"]);
230
279
  if (!stdout.trim()) throw new Error("Not found");
231
280
  versionToUse = stdout.trim();
232
281
  } catch {
233
282
  try {
234
283
  const tag = cliVersion.includes("canary") ? "canary" : "latest";
235
- const { stdout } = await execa("pnpm", ["view", `${pkgName}@${tag}`, "version"]);
284
+ const { stdout } = await execa(viewBin, ["view", `${pkgName}@${tag}`, "version"]);
236
285
  if (!stdout.trim()) throw new Error("Not found");
237
286
  versionToUse = stdout.trim();
238
287
  } catch {
239
288
  try {
240
- const { stdout } = await execa("pnpm", ["view", pkgName, "version"]);
289
+ const { stdout } = await execa(viewBin, ["view", pkgName, "version"]);
241
290
  versionToUse = stdout.trim() || "latest";
242
291
  } catch {
243
292
  versionToUse = "latest";
@@ -659,7 +708,6 @@ ${chalk.green.bold("Usage")}
659
708
  ${chalk.green.bold("Commands")}
660
709
  ${chalk.gray("(Commands are provided by your active database driver plugin)")}
661
710
  ${chalk.blue.bold("push")} Apply schema directly to database (development)
662
- ${chalk.blue.bold("pull")} Introspect database → Schema
663
711
  ${chalk.blue.bold("generate")} Generate migration files
664
712
  ${chalk.blue.bold("migrate")} Run pending migrations
665
713
  ${chalk.blue.bold("studio")} Open Studio viewer
@@ -790,9 +838,12 @@ async function devCommand(rawArgs) {
790
838
  frontendEnv.VITE_API_URL = `http://localhost:${backendPort}`;
791
839
  console.log(` ${chalk.gray("↳ VITE_API_URL")} = ${chalk.white(`http://localhost:${backendPort}`)}`);
792
840
  }
841
+ const pm = detectPackageManager(projectRoot);
842
+ const pmCmds = getPMCommands(pm);
843
+ const runDevCmd = pmCmds.run("dev");
793
844
  const frontendChild = execa(
794
- "pnpm",
795
- ["run", "dev"],
845
+ runDevCmd[0],
846
+ runDevCmd.slice(1),
796
847
  {
797
848
  cwd: frontendDir,
798
849
  stdio: ["inherit", "pipe", "pipe"],
@@ -826,8 +877,10 @@ async function devCommand(rawArgs) {
826
877
  if (!frontendOnly && backendDir) {
827
878
  const tsxBin = resolveTsx(projectRoot);
828
879
  if (!tsxBin) {
880
+ const pmName = detectPackageManager(projectRoot);
881
+ const addCmd = pmName === "npm" ? "npm install -D tsx" : "pnpm add -D tsx";
829
882
  console.error(chalk.red(" āœ— Could not find tsx binary for backend."));
830
- console.error(chalk.gray(" Install it with: pnpm add -D tsx"));
883
+ console.error(chalk.gray(` Install it with: ${addCmd}`));
831
884
  process.exit(1);
832
885
  }
833
886
  const envFile = findEnvFile(projectRoot);
@@ -928,6 +981,46 @@ ${chalk.green.bold("Description")}
928
981
  backend is ready, and VITE_API_URL is injected automatically.
929
982
  `);
930
983
  }
984
+ async function buildCommand() {
985
+ const projectRoot = requireProjectRoot();
986
+ const pm = detectPackageManager(projectRoot);
987
+ const cmds = getPMCommands(pm);
988
+ const buildCmd = cmds.runAll("build");
989
+ console.log(`${chalk.bold("Rebase")} — Building all workspaces with ${chalk.cyan(pm)}...
990
+ `);
991
+ try {
992
+ await execa(buildCmd[0], buildCmd.slice(1), {
993
+ cwd: projectRoot,
994
+ stdio: "inherit"
995
+ });
996
+ } catch {
997
+ console.error(chalk.red("\nāœ— Build failed."));
998
+ process.exit(1);
999
+ }
1000
+ }
1001
+ async function startCommand() {
1002
+ const projectRoot = requireProjectRoot();
1003
+ const pm = detectPackageManager(projectRoot);
1004
+ const cmds = getPMCommands(pm);
1005
+ const startCmd = cmds.runWorkspace("backend", "start");
1006
+ const envFile = findEnvFile(projectRoot);
1007
+ const env = { ...process.env };
1008
+ if (envFile) {
1009
+ env.DOTENV_CONFIG_PATH = envFile;
1010
+ }
1011
+ console.log(`${chalk.bold("Rebase")} — Starting backend server...
1012
+ `);
1013
+ try {
1014
+ await execa(startCmd[0], startCmd.slice(1), {
1015
+ cwd: projectRoot,
1016
+ stdio: "inherit",
1017
+ env
1018
+ });
1019
+ } catch {
1020
+ console.error(chalk.red("\nāœ— Failed to start server."));
1021
+ process.exit(1);
1022
+ }
1023
+ }
931
1024
  async function authCommand(subcommand, rawArgs) {
932
1025
  if (!subcommand || subcommand === "--help") {
933
1026
  printAuthHelp();
@@ -1136,7 +1229,7 @@ async function entry(args) {
1136
1229
  }
1137
1230
  const command = parsedArgs._[0];
1138
1231
  const subcommand = parsedArgs._[1];
1139
- const namespacedCommands = ["schema", "db", "dev", "auth", "doctor"];
1232
+ const namespacedCommands = ["schema", "db", "dev", "build", "start", "auth", "doctor"];
1140
1233
  if (!command || parsedArgs["--help"] && !namespacedCommands.includes(command)) {
1141
1234
  printHelp();
1142
1235
  return;
@@ -1175,6 +1268,12 @@ async function entry(args) {
1175
1268
  case "dev":
1176
1269
  await devCommand(args);
1177
1270
  break;
1271
+ case "build":
1272
+ await buildCommand();
1273
+ break;
1274
+ case "start":
1275
+ await startCommand();
1276
+ break;
1178
1277
  case "auth":
1179
1278
  await authCommand(effectiveSubcommand, args);
1180
1279
  break;
@@ -1197,14 +1296,16 @@ ${chalk.green.bold("Usage")}
1197
1296
  ${chalk.green.bold("Commands")}
1198
1297
  ${chalk.blue.bold("init")} Create a new Rebase project
1199
1298
  ${chalk.blue.bold("dev")} Start the development server
1299
+ ${chalk.blue.bold("build")} Build all workspace packages
1300
+ ${chalk.blue.bold("start")} Start the backend server ${chalk.gray("(production)")}
1200
1301
 
1201
1302
  ${chalk.green.bold("Schema")}
1202
1303
  ${chalk.blue.bold("schema generate")} Generate Drizzle schema from collections
1304
+ ${chalk.blue.bold("schema introspect")} Introspect database → Rebase collections
1203
1305
  ${chalk.blue.bold("schema")} ${chalk.gray("--help")} Show schema command help
1204
1306
 
1205
1307
  ${chalk.green.bold("Database")}
1206
1308
  ${chalk.blue.bold("db push")} Apply schema directly to database ${chalk.gray("(dev)")}
1207
- ${chalk.blue.bold("db pull")} Introspect database → Drizzle schema
1208
1309
  ${chalk.blue.bold("db generate")} Generate SQL migration files
1209
1310
  ${chalk.blue.bold("db migrate")} Run pending migrations
1210
1311
  ${chalk.blue.bold("db studio")} Open Drizzle Studio
@@ -1272,6 +1373,7 @@ async function logout(env, _debug) {
1272
1373
  }
1273
1374
  export {
1274
1375
  authCommand,
1376
+ buildCommand,
1275
1377
  configureEnvFile,
1276
1378
  createRebaseApp,
1277
1379
  dbCommand,
@@ -1292,6 +1394,7 @@ export {
1292
1394
  resolveLocalBin,
1293
1395
  resolvePluginCliScript,
1294
1396
  resolveTsx,
1295
- schemaCommand
1397
+ schemaCommand,
1398
+ startCommand
1296
1399
  };
1297
1400
  //# sourceMappingURL=index.es.js.map