@rebasepro/cli 0.0.1-canary.d44c30b ā 0.0.1-canary.e17585f
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 +8 -0
- package/dist/commands/start.d.ts +1 -0
- package/dist/index.cjs +261 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.es.js +262 -51
- 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 -5
- package/templates/template/.dockerignore +1 -1
- package/templates/template/.env.example +96 -0
- package/templates/template/README.md +17 -7
- package/templates/template/backend/drizzle.config.ts +24 -4
- package/templates/template/backend/package.json +3 -3
- package/templates/template/backend/src/index.ts +7 -9
- package/templates/template/config/collections/posts.ts +3 -3
- package/templates/template/docker-compose.yml +13 -38
- package/templates/template/frontend/package.json +1 -1
- package/templates/template/frontend/src/App.tsx +19 -98
- package/templates/template/frontend/vite.config.ts +32 -2
- package/templates/template/package.json +13 -7
- package/templates/template/.env.template +0 -62
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function buildCommand(): Promise<void>;
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import type { PackageManager, PMCommands } from "../utils/package-manager";
|
|
1
2
|
export interface InitOptions {
|
|
2
3
|
projectName: string;
|
|
3
4
|
git: boolean;
|
|
4
5
|
installDeps: boolean;
|
|
5
6
|
targetDirectory: string;
|
|
6
7
|
templateDirectory: string;
|
|
8
|
+
databaseUrl?: string;
|
|
9
|
+
introspect?: boolean;
|
|
10
|
+
/** Detected package manager (pnpm or npm). */
|
|
11
|
+
pm: PackageManager;
|
|
12
|
+
/** Command helpers for the detected PM. */
|
|
13
|
+
pmCommands: PMCommands;
|
|
7
14
|
}
|
|
8
15
|
export declare function createRebaseApp(rawArgs: string[]): Promise<void>;
|
|
16
|
+
export declare function configureEnvFile(targetDirectory: string, databaseUrl?: string): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function startCommand(): Promise<void>;
|
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,45 @@
|
|
|
20
20
|
return Object.freeze(n);
|
|
21
21
|
}
|
|
22
22
|
const os__namespace = /* @__PURE__ */ _interopNamespaceDefault(os);
|
|
23
|
+
function detectPackageManager(targetDir) {
|
|
24
|
+
const userAgent = process.env.npm_config_user_agent ?? "";
|
|
25
|
+
if (userAgent.startsWith("npm/")) return "npm";
|
|
26
|
+
if (userAgent.startsWith("pnpm/")) return "pnpm";
|
|
27
|
+
if (targetDir) {
|
|
28
|
+
if (fs.existsSync(path.join(targetDir, "package-lock.json"))) return "npm";
|
|
29
|
+
if (fs.existsSync(path.join(targetDir, "pnpm-lock.yaml"))) return "pnpm";
|
|
30
|
+
}
|
|
31
|
+
const cwd = process.cwd();
|
|
32
|
+
if (cwd !== targetDir) {
|
|
33
|
+
if (fs.existsSync(path.join(cwd, "package-lock.json"))) return "npm";
|
|
34
|
+
if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
35
|
+
}
|
|
36
|
+
return "pnpm";
|
|
37
|
+
}
|
|
38
|
+
function getPMCommands(pm) {
|
|
39
|
+
if (pm === "npm") {
|
|
40
|
+
return {
|
|
41
|
+
name: "npm",
|
|
42
|
+
install: ["npm", "install"],
|
|
43
|
+
run: (script) => ["npm", "run", script],
|
|
44
|
+
exec: (bin, args) => ["npx", bin, ...args],
|
|
45
|
+
view: (pkg, field) => ["npm", "view", pkg, field],
|
|
46
|
+
runAll: (script) => ["npm", "run", script, "--workspaces", "--if-present"],
|
|
47
|
+
runWorkspace: (workspace, script) => ["npm", "run", script, "-w", workspace],
|
|
48
|
+
workspaceProtocol: "*"
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
name: "pnpm",
|
|
53
|
+
install: ["pnpm", "install"],
|
|
54
|
+
run: (script) => ["pnpm", "run", script],
|
|
55
|
+
exec: (bin, args) => ["pnpm", "exec", bin, ...args],
|
|
56
|
+
view: (pkg, field) => ["pnpm", "view", pkg, field],
|
|
57
|
+
runAll: (script) => ["pnpm", "-r", "run", script],
|
|
58
|
+
runWorkspace: (workspace, script) => ["pnpm", "--filter", workspace, script],
|
|
59
|
+
workspaceProtocol: "workspace:*"
|
|
60
|
+
};
|
|
61
|
+
}
|
|
23
62
|
const access = util.promisify(fs.access);
|
|
24
63
|
const copy = util.promisify(ncp);
|
|
25
64
|
const __filename$2 = url.fileURLToPath(typeof document === "undefined" && typeof location === "undefined" ? require("url").pathToFileURL(__filename).href : typeof document === "undefined" ? location.href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index.cjs", document.baseURI).href);
|
|
@@ -39,10 +78,11 @@
|
|
|
39
78
|
console.log(`
|
|
40
79
|
${chalk.bold("Rebase")} ā Create a new project š
|
|
41
80
|
`);
|
|
42
|
-
const
|
|
81
|
+
const pm = detectPackageManager();
|
|
82
|
+
const options = await promptForOptions(rawArgs, pm);
|
|
43
83
|
await createProject(options);
|
|
44
84
|
}
|
|
45
|
-
async function promptForOptions(rawArgs) {
|
|
85
|
+
async function promptForOptions(rawArgs, pm) {
|
|
46
86
|
const args = arg(
|
|
47
87
|
{
|
|
48
88
|
"--git": Boolean,
|
|
@@ -85,20 +125,38 @@ ${chalk.bold("Rebase")} ā Create a new project š
|
|
|
85
125
|
questions.push({
|
|
86
126
|
type: "confirm",
|
|
87
127
|
name: "installDeps",
|
|
88
|
-
message:
|
|
128
|
+
message: `Install dependencies with ${pm}?`,
|
|
89
129
|
default: true
|
|
90
130
|
});
|
|
91
131
|
}
|
|
132
|
+
questions.push({
|
|
133
|
+
type: "input",
|
|
134
|
+
name: "databaseUrl",
|
|
135
|
+
message: "Enter your PostgreSQL database connection string (leave blank to use a local default):",
|
|
136
|
+
default: ""
|
|
137
|
+
});
|
|
138
|
+
questions.push({
|
|
139
|
+
type: "confirm",
|
|
140
|
+
name: "introspect",
|
|
141
|
+
message: "Would you like to introspect this database to automatically generate collections?",
|
|
142
|
+
default: true,
|
|
143
|
+
when: (answers2) => !!answers2.databaseUrl?.trim()
|
|
144
|
+
});
|
|
92
145
|
const answers = await inquirer.prompt(questions);
|
|
93
|
-
const
|
|
94
|
-
const
|
|
146
|
+
const targetDirectory = path.resolve(process.cwd(), nameArg || answers.projectName);
|
|
147
|
+
const projectName = path.basename(targetDirectory);
|
|
95
148
|
const templateDirectory = path.resolve(cliRoot, "templates", "template");
|
|
149
|
+
const pmCommands = getPMCommands(pm);
|
|
96
150
|
return {
|
|
97
151
|
projectName,
|
|
98
152
|
git: args["--git"] || answers.git || false,
|
|
99
153
|
installDeps: args["--install"] || answers.installDeps || false,
|
|
100
154
|
targetDirectory,
|
|
101
|
-
templateDirectory
|
|
155
|
+
templateDirectory,
|
|
156
|
+
databaseUrl: answers.databaseUrl?.trim() || void 0,
|
|
157
|
+
introspect: answers.introspect || false,
|
|
158
|
+
pm,
|
|
159
|
+
pmCommands
|
|
102
160
|
};
|
|
103
161
|
}
|
|
104
162
|
async function createProject(options) {
|
|
@@ -131,27 +189,7 @@ ${chalk.bold("Rebase")} ā Create a new project š
|
|
|
131
189
|
process.exit(1);
|
|
132
190
|
}
|
|
133
191
|
await replacePlaceholders(options);
|
|
134
|
-
|
|
135
|
-
const envPath = path.join(options.targetDirectory, ".env");
|
|
136
|
-
if (fs.existsSync(envTemplatePath) && !fs.existsSync(envPath)) {
|
|
137
|
-
fs.renameSync(envTemplatePath, envPath);
|
|
138
|
-
const jwtSecret = crypto.randomBytes(32).toString("hex");
|
|
139
|
-
const dbPassword = crypto.randomBytes(16).toString("hex");
|
|
140
|
-
let envContent = fs.readFileSync(envPath, "utf-8");
|
|
141
|
-
envContent = envContent.replace(
|
|
142
|
-
"postgresql://rebase:password@localhost:5432/rebase",
|
|
143
|
-
`postgresql://rebase:${dbPassword}@localhost:5432/rebase`
|
|
144
|
-
);
|
|
145
|
-
envContent = envContent.replace(
|
|
146
|
-
"change-this-to-a-secure-random-string",
|
|
147
|
-
jwtSecret
|
|
148
|
-
);
|
|
149
|
-
envContent += `
|
|
150
|
-
# Docker Compose Database Password
|
|
151
|
-
POSTGRES_PASSWORD=${dbPassword}
|
|
152
|
-
`;
|
|
153
|
-
fs.writeFileSync(envPath, envContent, "utf-8");
|
|
154
|
-
}
|
|
192
|
+
configureEnvFile(options.targetDirectory, options.databaseUrl);
|
|
155
193
|
if (options.git) {
|
|
156
194
|
console.log(chalk.gray(" Initializing git repository..."));
|
|
157
195
|
try {
|
|
@@ -160,17 +198,40 @@ POSTGRES_PASSWORD=${dbPassword}
|
|
|
160
198
|
console.warn(chalk.yellow(" Warning: Failed to initialize git repository"));
|
|
161
199
|
}
|
|
162
200
|
}
|
|
201
|
+
const { pm, pmCommands } = options;
|
|
202
|
+
const installCmd = pmCommands.install;
|
|
203
|
+
const execCmd = pmCommands.exec("rebase", ["schema", "introspect", "--force"]);
|
|
163
204
|
if (options.installDeps) {
|
|
164
205
|
console.log("");
|
|
165
|
-
console.log(chalk.gray(
|
|
206
|
+
console.log(chalk.gray(` Installing dependencies with ${pm}...`));
|
|
166
207
|
console.log("");
|
|
167
208
|
try {
|
|
168
|
-
await execa(
|
|
209
|
+
await execa(installCmd[0], installCmd.slice(1), {
|
|
169
210
|
cwd: options.targetDirectory,
|
|
170
211
|
stdio: "inherit"
|
|
171
212
|
});
|
|
172
213
|
} catch {
|
|
173
|
-
console.warn(chalk.yellow(
|
|
214
|
+
console.warn(chalk.yellow(` Warning: Failed to install dependencies. You may need to run \`${installCmd.join(" ")}\` manually.`));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (options.introspect) {
|
|
218
|
+
console.log("");
|
|
219
|
+
if (options.installDeps) {
|
|
220
|
+
console.log(chalk.gray(" Introspecting database and generating collections..."));
|
|
221
|
+
console.log("");
|
|
222
|
+
try {
|
|
223
|
+
await execa(execCmd[0], execCmd.slice(1), {
|
|
224
|
+
cwd: options.targetDirectory,
|
|
225
|
+
stdio: "inherit"
|
|
226
|
+
});
|
|
227
|
+
console.log(chalk.green(" Database successfully introspected!"));
|
|
228
|
+
} catch {
|
|
229
|
+
console.warn(chalk.yellow(" Warning: Failed to introspect database automatically."));
|
|
230
|
+
console.warn(chalk.yellow(` You can run \`${execCmd.join(" ")}\` manually after setup.`));
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
console.warn(chalk.yellow(" Skipping introspection because dependencies were not installed."));
|
|
234
|
+
console.warn(chalk.yellow(` Run \`${installCmd.join(" ")}\` then \`${execCmd.join(" ")}\` manually.`));
|
|
174
235
|
}
|
|
175
236
|
}
|
|
176
237
|
console.log("");
|
|
@@ -178,15 +239,23 @@ POSTGRES_PASSWORD=${dbPassword}
|
|
|
178
239
|
console.log("");
|
|
179
240
|
console.log(chalk.bold("Next steps:"));
|
|
180
241
|
console.log("");
|
|
242
|
+
const runDev = pmCommands.run("dev");
|
|
181
243
|
console.log(` ${chalk.cyan("cd")} ${options.projectName}`);
|
|
182
244
|
if (!options.installDeps) {
|
|
183
|
-
console.log(` ${chalk.cyan("
|
|
245
|
+
console.log(` ${chalk.cyan(installCmd.join(" "))}`);
|
|
184
246
|
}
|
|
185
247
|
console.log("");
|
|
186
|
-
|
|
187
|
-
|
|
248
|
+
if (options.databaseUrl) {
|
|
249
|
+
console.log(chalk.gray(" # Your database is configured! Start the dev server:"));
|
|
250
|
+
} else {
|
|
251
|
+
console.log(chalk.gray(" # A local database configuration has been generated in .env."));
|
|
252
|
+
console.log(chalk.gray(" # If using the included docker-compose.yml, start it with:"));
|
|
253
|
+
console.log(` ${chalk.cyan("docker compose up -d")}`);
|
|
254
|
+
console.log("");
|
|
255
|
+
console.log(chalk.gray(" # Then start the dev server:"));
|
|
256
|
+
}
|
|
188
257
|
console.log("");
|
|
189
|
-
console.log(` ${chalk.cyan("
|
|
258
|
+
console.log(` ${chalk.cyan(runDev.join(" "))}`);
|
|
190
259
|
console.log("");
|
|
191
260
|
console.log(chalk.gray("This starts both the backend (Hono + PostgreSQL)") + chalk.gray(" and the frontend (Vite + React) concurrently."));
|
|
192
261
|
console.log("");
|
|
@@ -200,16 +269,93 @@ POSTGRES_PASSWORD=${dbPassword}
|
|
|
200
269
|
"frontend/package.json",
|
|
201
270
|
"backend/package.json",
|
|
202
271
|
"config/package.json",
|
|
203
|
-
"frontend/index.html"
|
|
272
|
+
"frontend/index.html",
|
|
273
|
+
"README.md"
|
|
204
274
|
];
|
|
275
|
+
const packageJsonPath = path.resolve(cliRoot, "package.json");
|
|
276
|
+
let cliVersion = "latest";
|
|
277
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
278
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
279
|
+
cliVersion = pkg.version || "latest";
|
|
280
|
+
}
|
|
281
|
+
const versionCache = /* @__PURE__ */ new Map();
|
|
282
|
+
const viewBin = "npm";
|
|
283
|
+
const getPackageVersion = async (pkgName) => {
|
|
284
|
+
if (versionCache.has(pkgName)) return versionCache.get(pkgName);
|
|
285
|
+
let versionToUse = cliVersion;
|
|
286
|
+
try {
|
|
287
|
+
const { stdout } = await execa(viewBin, ["view", `${pkgName}@${cliVersion}`, "version"]);
|
|
288
|
+
if (!stdout.trim()) throw new Error("Not found");
|
|
289
|
+
versionToUse = stdout.trim();
|
|
290
|
+
} catch {
|
|
291
|
+
try {
|
|
292
|
+
const tag = cliVersion.includes("canary") ? "canary" : "latest";
|
|
293
|
+
const { stdout } = await execa(viewBin, ["view", `${pkgName}@${tag}`, "version"]);
|
|
294
|
+
if (!stdout.trim()) throw new Error("Not found");
|
|
295
|
+
versionToUse = stdout.trim();
|
|
296
|
+
} catch {
|
|
297
|
+
try {
|
|
298
|
+
const { stdout } = await execa(viewBin, ["view", pkgName, "version"]);
|
|
299
|
+
versionToUse = stdout.trim() || "latest";
|
|
300
|
+
} catch {
|
|
301
|
+
versionToUse = "latest";
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
versionCache.set(pkgName, versionToUse);
|
|
306
|
+
return versionToUse;
|
|
307
|
+
};
|
|
308
|
+
const allPackages = /* @__PURE__ */ new Set();
|
|
309
|
+
const fileContents = /* @__PURE__ */ new Map();
|
|
205
310
|
for (const file of filesToProcess) {
|
|
206
311
|
const fullPath = path.resolve(options.targetDirectory, file);
|
|
207
312
|
if (!fs.existsSync(fullPath)) continue;
|
|
208
|
-
|
|
209
|
-
|
|
313
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
314
|
+
fileContents.set(fullPath, content);
|
|
315
|
+
const matches = [...content.matchAll(/"(@rebasepro\/[^"]+)":\s*"workspace:\*"/g)];
|
|
316
|
+
for (const match of matches) {
|
|
317
|
+
allPackages.add(match[1]);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
console.log(chalk.gray(" Resolving package versions..."));
|
|
321
|
+
await Promise.all(Array.from(allPackages).map(getPackageVersion));
|
|
322
|
+
for (const [fullPath, originalContent] of fileContents.entries()) {
|
|
323
|
+
let content = originalContent.replace(/\{\{PROJECT_NAME\}\}/g, options.projectName);
|
|
324
|
+
const matches = [...content.matchAll(/"(@rebasepro\/[^"]+)":\s*"workspace:\*"/g)];
|
|
325
|
+
for (const match of matches) {
|
|
326
|
+
const pkgName = match[1];
|
|
327
|
+
const resolvedVersion = versionCache.get(pkgName) || "latest";
|
|
328
|
+
content = content.replace(new RegExp(`"${pkgName}":\\s*"workspace:\\*"`, "g"), `"${pkgName}": "${resolvedVersion}"`);
|
|
329
|
+
}
|
|
210
330
|
fs.writeFileSync(fullPath, content, "utf-8");
|
|
211
331
|
}
|
|
212
332
|
}
|
|
333
|
+
function configureEnvFile(targetDirectory, databaseUrl) {
|
|
334
|
+
const envExamplePath = path.join(targetDirectory, ".env.example");
|
|
335
|
+
const envPath = path.join(targetDirectory, ".env");
|
|
336
|
+
if (fs.existsSync(envExamplePath) && !fs.existsSync(envPath)) {
|
|
337
|
+
fs.copyFileSync(envExamplePath, envPath);
|
|
338
|
+
const jwtSecret = crypto.randomBytes(32).toString("hex");
|
|
339
|
+
const dbPassword = crypto.randomBytes(16).toString("hex");
|
|
340
|
+
let envContent = fs.readFileSync(envPath, "utf-8");
|
|
341
|
+
envContent = envContent.replace(
|
|
342
|
+
/^JWT_SECRET=.*$/m,
|
|
343
|
+
`JWT_SECRET=${jwtSecret}`
|
|
344
|
+
);
|
|
345
|
+
if (databaseUrl) {
|
|
346
|
+
envContent = envContent.replace(
|
|
347
|
+
/^DATABASE_URL=.*$/m,
|
|
348
|
+
`DATABASE_URL=${databaseUrl}`
|
|
349
|
+
);
|
|
350
|
+
} else {
|
|
351
|
+
envContent = envContent.replace(
|
|
352
|
+
/^DATABASE_URL=.*$/m,
|
|
353
|
+
`DATABASE_URL=postgresql://rebase:${dbPassword}@localhost:5432/rebase`
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
fs.writeFileSync(envPath, envContent, "utf-8");
|
|
357
|
+
}
|
|
358
|
+
}
|
|
213
359
|
async function loadCollections(collectionsDir) {
|
|
214
360
|
const absDir = path.resolve(collectionsDir);
|
|
215
361
|
if (!fs.existsSync(absDir)) {
|
|
@@ -362,15 +508,20 @@ Expected a default export of EntityCollection[] or an object with named collecti
|
|
|
362
508
|
if (!fs.existsSync(pkgPath)) return null;
|
|
363
509
|
try {
|
|
364
510
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
365
|
-
const deps = {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
511
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
512
|
+
const candidates = Object.keys(deps).filter(
|
|
513
|
+
(dep) => dep.startsWith("@rebasepro/server-") && dep !== "@rebasepro/server-core"
|
|
514
|
+
);
|
|
515
|
+
if (candidates.length === 0) return null;
|
|
516
|
+
if (candidates.includes("@rebasepro/server-postgresql")) {
|
|
517
|
+
return "@rebasepro/server-postgresql";
|
|
518
|
+
}
|
|
519
|
+
for (const candidate of candidates) {
|
|
520
|
+
if (resolvePluginCliScript(backendDir, candidate)) {
|
|
521
|
+
return candidate;
|
|
372
522
|
}
|
|
373
523
|
}
|
|
524
|
+
return candidates[0];
|
|
374
525
|
} catch {
|
|
375
526
|
}
|
|
376
527
|
return null;
|
|
@@ -380,6 +531,7 @@ Expected a default export of EntityCollection[] or an object with named collecti
|
|
|
380
531
|
path.join(backendDir, "node_modules", pluginName, "src", "cli.ts"),
|
|
381
532
|
path.join(backendDir, "node_modules", pluginName, "dist", "cli.js"),
|
|
382
533
|
// For monorepo dev mode:
|
|
534
|
+
path.resolve(backendDir, "..", "..", "..", "packages", pluginName.replace("@rebasepro/", ""), "src", "cli.ts"),
|
|
383
535
|
path.resolve(backendDir, "..", "..", "packages", pluginName.replace("@rebasepro/", ""), "src", "cli.ts"),
|
|
384
536
|
path.resolve(backendDir, "..", "packages", pluginName.replace("@rebasepro/", ""), "src", "cli.ts")
|
|
385
537
|
];
|
|
@@ -502,11 +654,15 @@ ${chalk.green.bold("Usage")}
|
|
|
502
654
|
${chalk.green.bold("Commands")}
|
|
503
655
|
${chalk.gray("(Commands are provided by your active database driver plugin)")}
|
|
504
656
|
${chalk.blue.bold("generate")} Generate Schema from collection definitions
|
|
657
|
+
${chalk.blue.bold("introspect")} Introspect an existing database to generate collection definitions
|
|
505
658
|
|
|
506
659
|
${chalk.green.bold("generate Options")}
|
|
507
660
|
${chalk.blue("--collections, -c")} Path to collections directory
|
|
508
661
|
${chalk.blue("--output, -o")} Output path for generated schema
|
|
509
662
|
${chalk.blue("--watch, -w")} Watch for changes and regenerate automatically
|
|
663
|
+
|
|
664
|
+
${chalk.green.bold("introspect Options")}
|
|
665
|
+
${chalk.blue("--output, -o")} Output directory for generated collection files
|
|
510
666
|
`);
|
|
511
667
|
}
|
|
512
668
|
async function dbCommand(subcommand, rawArgs) {
|
|
@@ -566,7 +722,6 @@ ${chalk.green.bold("Usage")}
|
|
|
566
722
|
${chalk.green.bold("Commands")}
|
|
567
723
|
${chalk.gray("(Commands are provided by your active database driver plugin)")}
|
|
568
724
|
${chalk.blue.bold("push")} Apply schema directly to database (development)
|
|
569
|
-
${chalk.blue.bold("pull")} Introspect database ā Schema
|
|
570
725
|
${chalk.blue.bold("generate")} Generate migration files
|
|
571
726
|
${chalk.blue.bold("migrate")} Run pending migrations
|
|
572
727
|
${chalk.blue.bold("studio")} Open Studio viewer
|
|
@@ -697,9 +852,12 @@ ${chalk.green.bold("Examples")}
|
|
|
697
852
|
frontendEnv.VITE_API_URL = `http://localhost:${backendPort}`;
|
|
698
853
|
console.log(` ${chalk.gray("ā³ VITE_API_URL")} = ${chalk.white(`http://localhost:${backendPort}`)}`);
|
|
699
854
|
}
|
|
855
|
+
const pm = detectPackageManager(projectRoot);
|
|
856
|
+
const pmCmds = getPMCommands(pm);
|
|
857
|
+
const runDevCmd = pmCmds.run("dev");
|
|
700
858
|
const frontendChild = execa(
|
|
701
|
-
|
|
702
|
-
|
|
859
|
+
runDevCmd[0],
|
|
860
|
+
runDevCmd.slice(1),
|
|
703
861
|
{
|
|
704
862
|
cwd: frontendDir,
|
|
705
863
|
stdio: ["inherit", "pipe", "pipe"],
|
|
@@ -733,8 +891,10 @@ ${chalk.green.bold("Examples")}
|
|
|
733
891
|
if (!frontendOnly && backendDir) {
|
|
734
892
|
const tsxBin = resolveTsx(projectRoot);
|
|
735
893
|
if (!tsxBin) {
|
|
894
|
+
const pmName = detectPackageManager(projectRoot);
|
|
895
|
+
const addCmd = pmName === "npm" ? "npm install -D tsx" : "pnpm add -D tsx";
|
|
736
896
|
console.error(chalk.red(" ā Could not find tsx binary for backend."));
|
|
737
|
-
console.error(chalk.gray(
|
|
897
|
+
console.error(chalk.gray(` Install it with: ${addCmd}`));
|
|
738
898
|
process.exit(1);
|
|
739
899
|
}
|
|
740
900
|
const envFile = findEnvFile(projectRoot);
|
|
@@ -835,6 +995,46 @@ ${chalk.green.bold("Description")}
|
|
|
835
995
|
backend is ready, and VITE_API_URL is injected automatically.
|
|
836
996
|
`);
|
|
837
997
|
}
|
|
998
|
+
async function buildCommand() {
|
|
999
|
+
const projectRoot = requireProjectRoot();
|
|
1000
|
+
const pm = detectPackageManager(projectRoot);
|
|
1001
|
+
const cmds = getPMCommands(pm);
|
|
1002
|
+
const buildCmd = cmds.runAll("build");
|
|
1003
|
+
console.log(`${chalk.bold("Rebase")} ā Building all workspaces with ${chalk.cyan(pm)}...
|
|
1004
|
+
`);
|
|
1005
|
+
try {
|
|
1006
|
+
await execa(buildCmd[0], buildCmd.slice(1), {
|
|
1007
|
+
cwd: projectRoot,
|
|
1008
|
+
stdio: "inherit"
|
|
1009
|
+
});
|
|
1010
|
+
} catch {
|
|
1011
|
+
console.error(chalk.red("\nā Build failed."));
|
|
1012
|
+
process.exit(1);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
async function startCommand() {
|
|
1016
|
+
const projectRoot = requireProjectRoot();
|
|
1017
|
+
const pm = detectPackageManager(projectRoot);
|
|
1018
|
+
const cmds = getPMCommands(pm);
|
|
1019
|
+
const startCmd = cmds.runWorkspace("backend", "start");
|
|
1020
|
+
const envFile = findEnvFile(projectRoot);
|
|
1021
|
+
const env = { ...process.env };
|
|
1022
|
+
if (envFile) {
|
|
1023
|
+
env.DOTENV_CONFIG_PATH = envFile;
|
|
1024
|
+
}
|
|
1025
|
+
console.log(`${chalk.bold("Rebase")} ā Starting backend server...
|
|
1026
|
+
`);
|
|
1027
|
+
try {
|
|
1028
|
+
await execa(startCmd[0], startCmd.slice(1), {
|
|
1029
|
+
cwd: projectRoot,
|
|
1030
|
+
stdio: "inherit",
|
|
1031
|
+
env
|
|
1032
|
+
});
|
|
1033
|
+
} catch {
|
|
1034
|
+
console.error(chalk.red("\nā Failed to start server."));
|
|
1035
|
+
process.exit(1);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
838
1038
|
async function authCommand(subcommand, rawArgs) {
|
|
839
1039
|
if (!subcommand || subcommand === "--help") {
|
|
840
1040
|
printAuthHelp();
|
|
@@ -1043,7 +1243,7 @@ ${chalk.green.bold("Examples")}
|
|
|
1043
1243
|
}
|
|
1044
1244
|
const command = parsedArgs._[0];
|
|
1045
1245
|
const subcommand = parsedArgs._[1];
|
|
1046
|
-
const namespacedCommands = ["schema", "db", "dev", "auth", "doctor"];
|
|
1246
|
+
const namespacedCommands = ["schema", "db", "dev", "build", "start", "auth", "doctor"];
|
|
1047
1247
|
if (!command || parsedArgs["--help"] && !namespacedCommands.includes(command)) {
|
|
1048
1248
|
printHelp();
|
|
1049
1249
|
return;
|
|
@@ -1082,6 +1282,12 @@ ${chalk.green.bold("Examples")}
|
|
|
1082
1282
|
case "dev":
|
|
1083
1283
|
await devCommand(args);
|
|
1084
1284
|
break;
|
|
1285
|
+
case "build":
|
|
1286
|
+
await buildCommand();
|
|
1287
|
+
break;
|
|
1288
|
+
case "start":
|
|
1289
|
+
await startCommand();
|
|
1290
|
+
break;
|
|
1085
1291
|
case "auth":
|
|
1086
1292
|
await authCommand(effectiveSubcommand, args);
|
|
1087
1293
|
break;
|
|
@@ -1104,14 +1310,16 @@ ${chalk.green.bold("Usage")}
|
|
|
1104
1310
|
${chalk.green.bold("Commands")}
|
|
1105
1311
|
${chalk.blue.bold("init")} Create a new Rebase project
|
|
1106
1312
|
${chalk.blue.bold("dev")} Start the development server
|
|
1313
|
+
${chalk.blue.bold("build")} Build all workspace packages
|
|
1314
|
+
${chalk.blue.bold("start")} Start the backend server ${chalk.gray("(production)")}
|
|
1107
1315
|
|
|
1108
1316
|
${chalk.green.bold("Schema")}
|
|
1109
1317
|
${chalk.blue.bold("schema generate")} Generate Drizzle schema from collections
|
|
1318
|
+
${chalk.blue.bold("schema introspect")} Introspect database ā Rebase collections
|
|
1110
1319
|
${chalk.blue.bold("schema")} ${chalk.gray("--help")} Show schema command help
|
|
1111
1320
|
|
|
1112
1321
|
${chalk.green.bold("Database")}
|
|
1113
1322
|
${chalk.blue.bold("db push")} Apply schema directly to database ${chalk.gray("(dev)")}
|
|
1114
|
-
${chalk.blue.bold("db pull")} Introspect database ā Drizzle schema
|
|
1115
1323
|
${chalk.blue.bold("db generate")} Generate SQL migration files
|
|
1116
1324
|
${chalk.blue.bold("db migrate")} Run pending migrations
|
|
1117
1325
|
${chalk.blue.bold("db studio")} Open Drizzle Studio
|
|
@@ -1178,6 +1386,8 @@ ${chalk.gray("Documentation: https://rebase.pro/docs")}
|
|
|
1178
1386
|
}
|
|
1179
1387
|
}
|
|
1180
1388
|
exports2.authCommand = authCommand;
|
|
1389
|
+
exports2.buildCommand = buildCommand;
|
|
1390
|
+
exports2.configureEnvFile = configureEnvFile;
|
|
1181
1391
|
exports2.createRebaseApp = createRebaseApp;
|
|
1182
1392
|
exports2.dbCommand = dbCommand;
|
|
1183
1393
|
exports2.devCommand = devCommand;
|
|
@@ -1198,6 +1408,7 @@ ${chalk.gray("Documentation: https://rebase.pro/docs")}
|
|
|
1198
1408
|
exports2.resolvePluginCliScript = resolvePluginCliScript;
|
|
1199
1409
|
exports2.resolveTsx = resolveTsx;
|
|
1200
1410
|
exports2.schemaCommand = schemaCommand;
|
|
1411
|
+
exports2.startCommand = startCommand;
|
|
1201
1412
|
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
1202
1413
|
}));
|
|
1203
1414
|
//# sourceMappingURL=index.cjs.map
|