@rebasepro/cli 0.0.1-canary.892f711 ā 0.0.1-canary.a6becfb
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/commands/build.d.ts +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/start.d.ts +1 -0
- package/dist/index.cjs +137 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.es.js +138 -29
- package/dist/index.es.js.map +1 -1
- package/dist/utils/package-manager.d.ts +31 -0
- package/dist/utils/package-manager.test.d.ts +1 -0
- package/package.json +4 -4
- package/templates/template/README.md +3 -3
- package/templates/template/backend/package.json +1 -1
- package/templates/template/docker-compose.yml +1 -1
- package/templates/template/frontend/package.json +1 -1
- package/templates/template/package.json +9 -4
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
|
|
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:
|
|
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(
|
|
197
|
+
console.log(chalk.gray(` Installing dependencies with ${pm}...`));
|
|
152
198
|
console.log("");
|
|
153
199
|
try {
|
|
154
|
-
await execa(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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("
|
|
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("
|
|
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(
|
|
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(
|
|
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(
|
|
289
|
+
const { stdout } = await execa(viewBin, ["view", pkgName, "version"]);
|
|
241
290
|
versionToUse = stdout.trim() || "latest";
|
|
242
291
|
} catch {
|
|
243
292
|
versionToUse = "latest";
|
|
@@ -450,15 +499,20 @@ function getActiveBackendPlugin(backendDir) {
|
|
|
450
499
|
if (!fs.existsSync(pkgPath)) return null;
|
|
451
500
|
try {
|
|
452
501
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
453
|
-
const deps = {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
502
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
503
|
+
const candidates = Object.keys(deps).filter(
|
|
504
|
+
(dep) => dep.startsWith("@rebasepro/server-") && dep !== "@rebasepro/server-core"
|
|
505
|
+
);
|
|
506
|
+
if (candidates.length === 0) return null;
|
|
507
|
+
if (candidates.includes("@rebasepro/server-postgresql")) {
|
|
508
|
+
return "@rebasepro/server-postgresql";
|
|
509
|
+
}
|
|
510
|
+
for (const candidate of candidates) {
|
|
511
|
+
if (resolvePluginCliScript(backendDir, candidate)) {
|
|
512
|
+
return candidate;
|
|
460
513
|
}
|
|
461
514
|
}
|
|
515
|
+
return candidates[0];
|
|
462
516
|
} catch {
|
|
463
517
|
}
|
|
464
518
|
return null;
|
|
@@ -789,9 +843,12 @@ async function devCommand(rawArgs) {
|
|
|
789
843
|
frontendEnv.VITE_API_URL = `http://localhost:${backendPort}`;
|
|
790
844
|
console.log(` ${chalk.gray("ā³ VITE_API_URL")} = ${chalk.white(`http://localhost:${backendPort}`)}`);
|
|
791
845
|
}
|
|
846
|
+
const pm = detectPackageManager(projectRoot);
|
|
847
|
+
const pmCmds = getPMCommands(pm);
|
|
848
|
+
const runDevCmd = pmCmds.run("dev");
|
|
792
849
|
const frontendChild = execa(
|
|
793
|
-
|
|
794
|
-
|
|
850
|
+
runDevCmd[0],
|
|
851
|
+
runDevCmd.slice(1),
|
|
795
852
|
{
|
|
796
853
|
cwd: frontendDir,
|
|
797
854
|
stdio: ["inherit", "pipe", "pipe"],
|
|
@@ -825,8 +882,10 @@ async function devCommand(rawArgs) {
|
|
|
825
882
|
if (!frontendOnly && backendDir) {
|
|
826
883
|
const tsxBin = resolveTsx(projectRoot);
|
|
827
884
|
if (!tsxBin) {
|
|
885
|
+
const pmName = detectPackageManager(projectRoot);
|
|
886
|
+
const addCmd = pmName === "npm" ? "npm install -D tsx" : "pnpm add -D tsx";
|
|
828
887
|
console.error(chalk.red(" ā Could not find tsx binary for backend."));
|
|
829
|
-
console.error(chalk.gray(
|
|
888
|
+
console.error(chalk.gray(` Install it with: ${addCmd}`));
|
|
830
889
|
process.exit(1);
|
|
831
890
|
}
|
|
832
891
|
const envFile = findEnvFile(projectRoot);
|
|
@@ -927,6 +986,46 @@ ${chalk.green.bold("Description")}
|
|
|
927
986
|
backend is ready, and VITE_API_URL is injected automatically.
|
|
928
987
|
`);
|
|
929
988
|
}
|
|
989
|
+
async function buildCommand() {
|
|
990
|
+
const projectRoot = requireProjectRoot();
|
|
991
|
+
const pm = detectPackageManager(projectRoot);
|
|
992
|
+
const cmds = getPMCommands(pm);
|
|
993
|
+
const buildCmd = cmds.runAll("build");
|
|
994
|
+
console.log(`${chalk.bold("Rebase")} ā Building all workspaces with ${chalk.cyan(pm)}...
|
|
995
|
+
`);
|
|
996
|
+
try {
|
|
997
|
+
await execa(buildCmd[0], buildCmd.slice(1), {
|
|
998
|
+
cwd: projectRoot,
|
|
999
|
+
stdio: "inherit"
|
|
1000
|
+
});
|
|
1001
|
+
} catch {
|
|
1002
|
+
console.error(chalk.red("\nā Build failed."));
|
|
1003
|
+
process.exit(1);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
async function startCommand() {
|
|
1007
|
+
const projectRoot = requireProjectRoot();
|
|
1008
|
+
const pm = detectPackageManager(projectRoot);
|
|
1009
|
+
const cmds = getPMCommands(pm);
|
|
1010
|
+
const startCmd = cmds.runWorkspace("backend", "start");
|
|
1011
|
+
const envFile = findEnvFile(projectRoot);
|
|
1012
|
+
const env = { ...process.env };
|
|
1013
|
+
if (envFile) {
|
|
1014
|
+
env.DOTENV_CONFIG_PATH = envFile;
|
|
1015
|
+
}
|
|
1016
|
+
console.log(`${chalk.bold("Rebase")} ā Starting backend server...
|
|
1017
|
+
`);
|
|
1018
|
+
try {
|
|
1019
|
+
await execa(startCmd[0], startCmd.slice(1), {
|
|
1020
|
+
cwd: projectRoot,
|
|
1021
|
+
stdio: "inherit",
|
|
1022
|
+
env
|
|
1023
|
+
});
|
|
1024
|
+
} catch {
|
|
1025
|
+
console.error(chalk.red("\nā Failed to start server."));
|
|
1026
|
+
process.exit(1);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
930
1029
|
async function authCommand(subcommand, rawArgs) {
|
|
931
1030
|
if (!subcommand || subcommand === "--help") {
|
|
932
1031
|
printAuthHelp();
|
|
@@ -1135,7 +1234,7 @@ async function entry(args) {
|
|
|
1135
1234
|
}
|
|
1136
1235
|
const command = parsedArgs._[0];
|
|
1137
1236
|
const subcommand = parsedArgs._[1];
|
|
1138
|
-
const namespacedCommands = ["schema", "db", "dev", "auth", "doctor"];
|
|
1237
|
+
const namespacedCommands = ["schema", "db", "dev", "build", "start", "auth", "doctor"];
|
|
1139
1238
|
if (!command || parsedArgs["--help"] && !namespacedCommands.includes(command)) {
|
|
1140
1239
|
printHelp();
|
|
1141
1240
|
return;
|
|
@@ -1174,6 +1273,12 @@ async function entry(args) {
|
|
|
1174
1273
|
case "dev":
|
|
1175
1274
|
await devCommand(args);
|
|
1176
1275
|
break;
|
|
1276
|
+
case "build":
|
|
1277
|
+
await buildCommand();
|
|
1278
|
+
break;
|
|
1279
|
+
case "start":
|
|
1280
|
+
await startCommand();
|
|
1281
|
+
break;
|
|
1177
1282
|
case "auth":
|
|
1178
1283
|
await authCommand(effectiveSubcommand, args);
|
|
1179
1284
|
break;
|
|
@@ -1196,14 +1301,16 @@ ${chalk.green.bold("Usage")}
|
|
|
1196
1301
|
${chalk.green.bold("Commands")}
|
|
1197
1302
|
${chalk.blue.bold("init")} Create a new Rebase project
|
|
1198
1303
|
${chalk.blue.bold("dev")} Start the development server
|
|
1304
|
+
${chalk.blue.bold("build")} Build all workspace packages
|
|
1305
|
+
${chalk.blue.bold("start")} Start the backend server ${chalk.gray("(production)")}
|
|
1199
1306
|
|
|
1200
1307
|
${chalk.green.bold("Schema")}
|
|
1201
1308
|
${chalk.blue.bold("schema generate")} Generate Drizzle schema from collections
|
|
1309
|
+
${chalk.blue.bold("schema introspect")} Introspect database ā Rebase collections
|
|
1202
1310
|
${chalk.blue.bold("schema")} ${chalk.gray("--help")} Show schema command help
|
|
1203
1311
|
|
|
1204
1312
|
${chalk.green.bold("Database")}
|
|
1205
1313
|
${chalk.blue.bold("db push")} Apply schema directly to database ${chalk.gray("(dev)")}
|
|
1206
|
-
${chalk.blue.bold("db pull")} Introspect database ā Drizzle schema
|
|
1207
1314
|
${chalk.blue.bold("db generate")} Generate SQL migration files
|
|
1208
1315
|
${chalk.blue.bold("db migrate")} Run pending migrations
|
|
1209
1316
|
${chalk.blue.bold("db studio")} Open Drizzle Studio
|
|
@@ -1271,6 +1378,7 @@ async function logout(env, _debug) {
|
|
|
1271
1378
|
}
|
|
1272
1379
|
export {
|
|
1273
1380
|
authCommand,
|
|
1381
|
+
buildCommand,
|
|
1274
1382
|
configureEnvFile,
|
|
1275
1383
|
createRebaseApp,
|
|
1276
1384
|
dbCommand,
|
|
@@ -1291,6 +1399,7 @@ export {
|
|
|
1291
1399
|
resolveLocalBin,
|
|
1292
1400
|
resolvePluginCliScript,
|
|
1293
1401
|
resolveTsx,
|
|
1294
|
-
schemaCommand
|
|
1402
|
+
schemaCommand,
|
|
1403
|
+
startCommand
|
|
1295
1404
|
};
|
|
1296
1405
|
//# sourceMappingURL=index.es.js.map
|