@rebasepro/cli 0.7.0 → 0.9.0
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 +80 -3
- package/dist/index.es.js.map +1 -1
- package/dist/utils/project.d.ts +15 -0
- package/package.json +13 -19
- package/templates/template/.env.example +4 -0
- package/templates/template/backend/Dockerfile +4 -3
- package/templates/template/backend/functions/hello.ts +36 -32
- package/templates/template/backend/package.json +3 -1
- package/templates/template/backend/src/env.ts +2 -1
- package/templates/template/backend/src/index.ts +12 -12
- package/templates/template/config/collections/authors.ts +2 -2
- package/templates/template/config/collections/posts.ts +5 -3
- package/templates/template/config/collections/presets/ecommerce/categories.ts +5 -3
- package/templates/template/config/collections/presets/ecommerce/orders.ts +5 -3
- package/templates/template/config/collections/presets/ecommerce/products.ts +5 -3
- package/templates/template/config/collections/tags.ts +2 -2
- package/templates/template/config/collections/users.ts +5 -3
- package/templates/template/frontend/Dockerfile +5 -3
- package/templates/template/frontend/src/App.tsx +4 -1
- package/templates/template/frontend/vite.config.ts +14 -0
- package/templates/template/package.json +3 -1
- package/templates/template/pnpm-workspace.yaml +2 -0
- package/templates/template/scripts/example.ts +1 -1
package/dist/index.es.js
CHANGED
|
@@ -583,7 +583,7 @@ async function configureEnvFile(targetDirectory, databaseUrl) {
|
|
|
583
583
|
* Dynamically load collection definitions from a directory.
|
|
584
584
|
*
|
|
585
585
|
* Expects the directory to have an index.ts/index.js that exports a default
|
|
586
|
-
* array of
|
|
586
|
+
* array of CollectionConfig objects (matching the app/config/collections pattern).
|
|
587
587
|
*/
|
|
588
588
|
async function loadCollections(collectionsDir) {
|
|
589
589
|
const absDir = path.resolve(collectionsDir);
|
|
@@ -640,7 +640,7 @@ async function loadCollections(collectionsDir) {
|
|
|
640
640
|
for (const value of Object.values(exported)) if (value && typeof value === "object" && "slug" in value) collections.push(value);
|
|
641
641
|
if (collections.length > 0) return collections;
|
|
642
642
|
}
|
|
643
|
-
throw new Error(`Could not extract collections from ${indexPath}.\nExpected a default export of
|
|
643
|
+
throw new Error(`Could not extract collections from ${indexPath}.\nExpected a default export of CollectionConfig[] or an object with named collection exports.`);
|
|
644
644
|
}
|
|
645
645
|
/**
|
|
646
646
|
* Write generated files to the output directory.
|
|
@@ -812,6 +812,41 @@ function resolveTsx(projectRoot) {
|
|
|
812
812
|
return resolveLocalBin(projectRoot, "tsx");
|
|
813
813
|
}
|
|
814
814
|
/**
|
|
815
|
+
* Validate that a resolved tsx binary actually has an intact installation.
|
|
816
|
+
*
|
|
817
|
+
* `resolveLocalBin` only checks whether `node_modules/.bin/tsx` (a symlink)
|
|
818
|
+
* exists. If the pnpm content-addressable store was cleaned or a previous
|
|
819
|
+
* install was interrupted, the symlink can exist while critical files inside
|
|
820
|
+
* the tsx package (e.g. `dist/preflight.cjs`) are missing — causing a
|
|
821
|
+
* confusing MODULE_NOT_FOUND error at runtime.
|
|
822
|
+
*
|
|
823
|
+
* This function follows the symlink, walks up to find the tsx package root
|
|
824
|
+
* (`package.json` with `name: "tsx"`), and verifies that `dist/preflight.cjs`
|
|
825
|
+
* is present. Returns `null` when the installation looks healthy, or an
|
|
826
|
+
* error description string when it appears corrupted.
|
|
827
|
+
*/
|
|
828
|
+
function validateTsxInstallation(tsxBinPath) {
|
|
829
|
+
try {
|
|
830
|
+
const realPath = fs.realpathSync(tsxBinPath);
|
|
831
|
+
let dir = path.dirname(realPath);
|
|
832
|
+
const fsRoot = path.parse(dir).root;
|
|
833
|
+
for (let depth = 0; depth < 10 && dir !== fsRoot; depth++) {
|
|
834
|
+
const pkgPath = path.join(dir, "package.json");
|
|
835
|
+
if (fs.existsSync(pkgPath)) try {
|
|
836
|
+
if (JSON.parse(fs.readFileSync(pkgPath, "utf-8")).name === "tsx") {
|
|
837
|
+
const preflightPath = path.join(dir, "dist", "preflight.cjs");
|
|
838
|
+
if (!fs.existsSync(preflightPath)) return `tsx package at ${dir} is missing dist/preflight.cjs`;
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
841
|
+
} catch {}
|
|
842
|
+
dir = path.dirname(dir);
|
|
843
|
+
}
|
|
844
|
+
return null;
|
|
845
|
+
} catch (err) {
|
|
846
|
+
return `tsx binary symlink is broken: ${err instanceof Error ? err.message : String(err)}`;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
815
850
|
* Require the project root or exit with a helpful error.
|
|
816
851
|
*/
|
|
817
852
|
function requireProjectRoot() {
|
|
@@ -1156,12 +1191,35 @@ async function devCommand(rawArgs) {
|
|
|
1156
1191
|
console.error(chalk.gray(` Install it with: ${addCmd}`));
|
|
1157
1192
|
process.exit(1);
|
|
1158
1193
|
}
|
|
1194
|
+
const tsxValidationError = validateTsxInstallation(tsxBin);
|
|
1195
|
+
if (tsxValidationError) {
|
|
1196
|
+
const installCmd = getPMCommands(detectPackageManager(projectRoot)).install.join(" ");
|
|
1197
|
+
console.error(chalk.red(" ✗ tsx installation appears corrupted."));
|
|
1198
|
+
console.error(chalk.gray(` ${tsxValidationError}`));
|
|
1199
|
+
console.error("");
|
|
1200
|
+
console.error(chalk.gray(" To fix, run:"));
|
|
1201
|
+
console.error(chalk.cyan(` rm -rf node_modules && ${installCmd}`));
|
|
1202
|
+
process.exit(1);
|
|
1203
|
+
}
|
|
1159
1204
|
const envFile = findEnvFile(projectRoot);
|
|
1160
1205
|
const env = { ...process.env };
|
|
1161
1206
|
if (envFile) env.DOTENV_CONFIG_PATH = envFile;
|
|
1162
1207
|
env.PORT = String(startPort);
|
|
1163
1208
|
console.log(` ${chalk.cyan("▶")} Backend: ${chalk.gray(backendDir)}`);
|
|
1164
1209
|
console.log(` ${chalk.gray("↳ PORT")} = ${chalk.white(String(startPort))}`);
|
|
1210
|
+
if (envFile) try {
|
|
1211
|
+
const envText = fs.readFileSync(envFile, "utf-8");
|
|
1212
|
+
const readEnvKey = (key) => {
|
|
1213
|
+
const m = envText.match(new RegExp(`^\\s*${key}\\s*=\\s*(.+?)\\s*$`, "m"));
|
|
1214
|
+
return m ? m[1].replace(/^["']|["']$/g, "") : void 0;
|
|
1215
|
+
};
|
|
1216
|
+
const envPort = readEnvKey("PORT");
|
|
1217
|
+
const envApiUrl = readEnvKey("VITE_API_URL");
|
|
1218
|
+
const overridden = [];
|
|
1219
|
+
if (envPort && envPort !== String(startPort)) overridden.push("PORT");
|
|
1220
|
+
if (envApiUrl && envApiUrl !== `http://localhost:${startPort}`) overridden.push("VITE_API_URL");
|
|
1221
|
+
if (overridden.length > 0) console.log(chalk.yellow(` ⚠ dev uses a derived per-project port (${startPort}); your .env ${overridden.join(" / ")} ${overridden.length > 1 ? "are" : "is"} ignored here (avoids cross-project collisions). Pass ${chalk.white("--port")} to pin a port.`));
|
|
1222
|
+
} catch {}
|
|
1165
1223
|
/** Whether the frontend has been launched (we only launch it once). */
|
|
1166
1224
|
let frontendLaunched = false;
|
|
1167
1225
|
if (shouldGenerate) {
|
|
@@ -1286,9 +1344,28 @@ async function devCommand(rawArgs) {
|
|
|
1286
1344
|
}
|
|
1287
1345
|
});
|
|
1288
1346
|
});
|
|
1347
|
+
/** Whether we've already shown a corrupted-modules recovery hint. */
|
|
1348
|
+
let corruptedModulesWarned = false;
|
|
1289
1349
|
backendChild.stderr?.on("data", (data) => {
|
|
1290
1350
|
data.toString().split("\n").filter(Boolean).forEach((line) => {
|
|
1291
1351
|
console.log(`${chalk.cyan.bold("[backend]")} ${line}`);
|
|
1352
|
+
if (!corruptedModulesWarned) {
|
|
1353
|
+
const cleanLine = stripAnsi(line);
|
|
1354
|
+
if (cleanLine.includes("Cannot find module") && cleanLine.includes("node_modules/.pnpm/")) {
|
|
1355
|
+
corruptedModulesWarned = true;
|
|
1356
|
+
setTimeout(() => {
|
|
1357
|
+
const installCmd = getPMCommands(detectPackageManager(projectRoot)).install.join(" ");
|
|
1358
|
+
console.error("");
|
|
1359
|
+
console.error(chalk.red(" ✗ node_modules appears corrupted — a required file is missing."));
|
|
1360
|
+
console.error(chalk.gray(" This usually happens when a previous install was interrupted"));
|
|
1361
|
+
console.error(chalk.gray(" or the package manager store was cleaned."));
|
|
1362
|
+
console.error("");
|
|
1363
|
+
console.error(chalk.gray(" To fix, stop the dev server and run:"));
|
|
1364
|
+
console.error(chalk.cyan(` rm -rf node_modules && ${installCmd}`));
|
|
1365
|
+
console.error("");
|
|
1366
|
+
}, 200);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1292
1369
|
});
|
|
1293
1370
|
});
|
|
1294
1371
|
children.push(backendChild);
|
|
@@ -2243,6 +2320,6 @@ ${chalk.gray("Documentation: https://rebase.pro/docs")}
|
|
|
2243
2320
|
`);
|
|
2244
2321
|
}
|
|
2245
2322
|
//#endregion
|
|
2246
|
-
export { authCommand, buildCommand, buildInitQuestions, configureEnvFile, createRebaseApp, dbCommand, detectPackageManager, devCommand, doctorCommand, entry, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, generateSdkCommand, getActiveBackendPlugin, getPMCommands, requireBackendDir, requireProjectRoot, resolveLocalBin, resolvePluginCliScript, resolveTsx, schemaCommand, startCommand };
|
|
2323
|
+
export { authCommand, buildCommand, buildInitQuestions, configureEnvFile, createRebaseApp, dbCommand, detectPackageManager, devCommand, doctorCommand, entry, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, generateSdkCommand, getActiveBackendPlugin, getPMCommands, requireBackendDir, requireProjectRoot, resolveLocalBin, resolvePluginCliScript, resolveTsx, schemaCommand, startCommand, validateTsxInstallation };
|
|
2247
2324
|
|
|
2248
2325
|
//# sourceMappingURL=index.es.js.map
|