@rebasepro/cli 0.2.3 → 0.2.4

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,7 +11,6 @@ import { fileURLToPath } from "url";
11
11
  import crypto from "crypto";
12
12
  import { generateSDK } from "@rebasepro/sdk-generator";
13
13
  import { execSync, spawn } from "child_process";
14
- import * as os from "os";
15
14
  function detectPackageManager(targetDir) {
16
15
  const userAgent = process.env.npm_config_user_agent ?? "";
17
16
  if (userAgent.startsWith("npm/")) return "npm";
@@ -146,7 +145,13 @@ async function promptForOptions(rawArgs, pm) {
146
145
  type: "input",
147
146
  name: "databaseUrl",
148
147
  message: "Enter your PostgreSQL database connection string (leave blank to use a local default):",
149
- default: ""
148
+ default: "",
149
+ validate: (input) => {
150
+ if (input.trim() && /[\r\n]/.test(input)) {
151
+ return "Database URL cannot contain newline characters.";
152
+ }
153
+ return true;
154
+ }
150
155
  });
151
156
  questions.push({
152
157
  type: "confirm",
@@ -252,23 +257,37 @@ async function createProject(options) {
252
257
  console.log(chalk.bold("Next steps:"));
253
258
  console.log("");
254
259
  const runDev = pmCommands.run("dev");
260
+ const runDbPush = pmCommands.run("db:push");
255
261
  console.log(` ${chalk.cyan("cd")} ${options.projectName}`);
256
262
  if (!options.installDeps) {
257
263
  console.log(` ${chalk.cyan(installCmd.join(" "))}`);
258
264
  }
259
265
  console.log("");
260
266
  if (options.databaseUrl) {
261
- console.log(chalk.gray(" # Your database is configured! Start the dev server:"));
267
+ if (options.introspect) {
268
+ console.log(chalk.gray(" # Database has been introspected & collections generated!"));
269
+ console.log(chalk.gray(" # Start the development server (frontend + backend):"));
270
+ console.log(` ${chalk.cyan(runDev.join(" "))}`);
271
+ } else {
272
+ console.log(chalk.gray(" # Your custom database is configured in .env."));
273
+ console.log(chalk.gray(" # If the database is empty, push the Rebase schema to initialize it:"));
274
+ console.log(` ${chalk.cyan(runDbPush.join(" "))}`);
275
+ console.log("");
276
+ console.log(chalk.gray(" # Then start the development server:"));
277
+ console.log(` ${chalk.cyan(runDev.join(" "))}`);
278
+ }
262
279
  } else {
263
280
  console.log(chalk.gray(" # A local database configuration has been generated in .env."));
264
- console.log(chalk.gray(" # If using the included docker-compose.yml, start the database with:"));
281
+ console.log(chalk.gray(" # 1. Start the PostgreSQL database container:"));
265
282
  console.log(` ${chalk.cyan("docker compose up -d db")}`);
266
283
  console.log("");
267
- console.log(chalk.gray(" # Then start the dev server:"));
284
+ console.log(chalk.gray(" # 2. Push the Rebase schema to initialize database tables:"));
285
+ console.log(` ${chalk.cyan(runDbPush.join(" "))}`);
286
+ console.log("");
287
+ console.log(chalk.gray(" # 3. Start the development server (frontend + backend):"));
288
+ console.log(` ${chalk.cyan(runDev.join(" "))}`);
268
289
  }
269
290
  console.log("");
270
- console.log(` ${chalk.cyan(runDev.join(" "))}`);
271
- console.log("");
272
291
  console.log(chalk.gray("This starts both the backend (Hono + PostgreSQL)") + chalk.gray(" and the frontend (Vite + React) concurrently."));
273
292
  console.log("");
274
293
  console.log(chalk.gray("Docs: https://rebase.pro/docs"));
@@ -379,6 +398,9 @@ async function configureEnvFile(targetDirectory, databaseUrl) {
379
398
  `JWT_SECRET=${jwtSecret}`
380
399
  );
381
400
  if (databaseUrl) {
401
+ if (/[\r\n]/.test(databaseUrl)) {
402
+ throw new Error("Invalid DATABASE_URL: multiline values are not allowed.");
403
+ }
382
404
  envContent = envContent.replace(
383
405
  /^DATABASE_URL=.*$/m,
384
406
  `DATABASE_URL=${databaseUrl}`
@@ -688,7 +710,7 @@ async function schemaCommand(subcommand, rawArgs) {
688
710
  env
689
711
  });
690
712
  }
691
- } catch (err) {
713
+ } catch {
692
714
  process.exit(1);
693
715
  }
694
716
  }
@@ -756,7 +778,7 @@ async function dbCommand(subcommand, rawArgs) {
756
778
  env
757
779
  });
758
780
  }
759
- } catch (err) {
781
+ } catch {
760
782
  process.exit(1);
761
783
  }
762
784
  }
@@ -976,7 +998,7 @@ async function devCommand(rawArgs) {
976
998
  });
977
999
  console.log(chalk.green(" ✓ Initial schema and SDK generated successfully.\n"));
978
1000
  } catch (err) {
979
- console.error(chalk.red(` ✗ Initial schema/SDK generation failed: ${err.message || err}
1001
+ console.error(chalk.red(` ✗ Initial schema/SDK generation failed: ${err instanceof Error ? err.message : err}
980
1002
  `));
981
1003
  }
982
1004
  const collectionsDir = path.join(projectRoot, "config", "collections");
@@ -1005,7 +1027,7 @@ async function devCommand(rawArgs) {
1005
1027
  });
1006
1028
  console.log(chalk.green(" ✓ Schema & SDK regenerated successfully. Hono will reload."));
1007
1029
  } catch (err) {
1008
- console.error(chalk.red(` ✗ Failed to regenerate schema/SDK: ${err.message || err}`));
1030
+ console.error(chalk.red(` ✗ Failed to regenerate schema/SDK: ${err instanceof Error ? err.message : err}`));
1009
1031
  }
1010
1032
  }, 300);
1011
1033
  });
@@ -1200,6 +1222,9 @@ async function resetPassword(rawArgs) {
1200
1222
  if (envFile) {
1201
1223
  env.DOTENV_CONFIG_PATH = envFile;
1202
1224
  }
1225
+ env.REBASE_RESET_EMAIL = email;
1226
+ env.REBASE_RESET_PASSWORD = newPassword || "NewPassword123!";
1227
+ env.REBASE_ENV_FILE_PATH = envFile || path.join(projectRoot, ".env");
1203
1228
  const scriptContent = `
1204
1229
  import { createPostgresDatabaseConnection } from "@rebasepro/server-postgresql";
1205
1230
  import { hashPassword } from "@rebasepro/server-core";
@@ -1208,10 +1233,10 @@ import * as dotenv from "dotenv";
1208
1233
  import path from "path";
1209
1234
  import fs from "fs";
1210
1235
 
1211
- dotenv.config({ path: "${envFile || path.join(projectRoot, ".env")}" });
1236
+ dotenv.config({ path: process.env.REBASE_ENV_FILE_PATH });
1212
1237
 
1213
- const email = "${email}";
1214
- const newPassword = "${newPassword || "NewPassword123!"}";
1238
+ const email = process.env.REBASE_RESET_EMAIL!;
1239
+ const newPassword = process.env.REBASE_RESET_PASSWORD!;
1215
1240
 
1216
1241
  async function resetPassword() {
1217
1242
  const { db } = createPostgresDatabaseConnection(process.env.DATABASE_URL!);
@@ -1474,67 +1499,23 @@ ${chalk.green.bold("Options")}
1474
1499
  ${chalk.gray("Documentation: https://rebase.pro/docs")}
1475
1500
  `);
1476
1501
  }
1477
- const TOKEN_DIR = path.join(os.homedir(), ".rebase");
1478
- function tokenPath(env) {
1479
- return path.join(TOKEN_DIR, (env === "dev" ? "staging." : "") + "tokens.json");
1480
- }
1481
- async function getTokens(env, _debug) {
1482
- const fp = tokenPath(env);
1483
- if (!fs.existsSync(fp)) return null;
1484
- try {
1485
- const data = fs.readFileSync(fp, "utf-8");
1486
- return JSON.parse(data);
1487
- } catch {
1488
- return null;
1489
- }
1490
- }
1491
- function parseJwt(token) {
1492
- if (!token) throw new Error("No JWT token");
1493
- const base64Url = token.split(".")[1];
1494
- const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
1495
- const buffer = Buffer.from(base64, "base64");
1496
- return JSON.parse(buffer.toString());
1497
- }
1498
- async function refreshCredentials(env, credentials, _onErr) {
1499
- if (!credentials) return null;
1500
- const expiryDate = new Date(credentials["expiry_date"]);
1501
- if (expiryDate.getTime() > Date.now()) {
1502
- return credentials;
1503
- }
1504
- return null;
1505
- }
1506
- async function login(env, _debug) {
1507
- console.log(
1508
- "Interactive login is not yet implemented in @rebasepro/cli.\nPlease authenticate via the Rebase dashboard and copy your tokens to " + tokenPath(env)
1509
- );
1510
- }
1511
- async function logout(env, _debug) {
1512
- const fp = tokenPath(env);
1513
- if (fs.existsSync(fp)) {
1514
- fs.unlinkSync(fp);
1515
- console.log("You have been logged out.");
1516
- } else {
1517
- console.log("You are not logged in.");
1518
- }
1519
- }
1520
1502
  export {
1521
1503
  authCommand,
1522
1504
  buildCommand,
1523
1505
  configureEnvFile,
1524
1506
  createRebaseApp,
1525
1507
  dbCommand,
1508
+ detectPackageManager,
1526
1509
  devCommand,
1510
+ doctorCommand,
1527
1511
  entry,
1528
1512
  findBackendDir,
1529
1513
  findEnvFile,
1530
1514
  findFrontendDir,
1531
1515
  findProjectRoot,
1516
+ generateSdkCommand,
1532
1517
  getActiveBackendPlugin,
1533
- getTokens,
1534
- login,
1535
- logout,
1536
- parseJwt,
1537
- refreshCredentials,
1518
+ getPMCommands,
1538
1519
  requireBackendDir,
1539
1520
  requireProjectRoot,
1540
1521
  resolveLocalBin,