@rebasepro/cli 0.12.1-canary.g8b4f68e → 0.12.1-canary.gcc9d592
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/bin/rebase.js +27 -1
- package/dist/bundle.d.ts +36 -0
- package/dist/index.es.js +150 -5
- package/dist/index.es.js.map +1 -1
- package/package.json +7 -7
package/bin/rebase.js
CHANGED
|
@@ -88,4 +88,30 @@ if (!existsSync(distEntry)) {
|
|
|
88
88
|
|
|
89
89
|
const { entry } = await import("../dist/index.es.js");
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
/**
|
|
92
|
+
* The CLI's last line of defence.
|
|
93
|
+
*
|
|
94
|
+
* `entry()` returns a promise and nothing was awaiting it, so anything a
|
|
95
|
+
* command threw surfaced as an unhandled rejection: Node's own stack trace,
|
|
96
|
+
* rooted in `dist/index.es.js`, with the CLI's bundled line numbers and no
|
|
97
|
+
* exit code of its own. "Collections directory not found" is a sentence a
|
|
98
|
+
* developer can act on; the same sentence under ten frames of bundle internals
|
|
99
|
+
* reads as a crash in Rebase.
|
|
100
|
+
*
|
|
101
|
+
* The message is the error's own — commands that already print something
|
|
102
|
+
* friendly and exit never reach here. The stack is available behind
|
|
103
|
+
* `--debug`/`REBASE_DEBUG`, because when the message is *not* enough that is
|
|
104
|
+
* the only thing that helps.
|
|
105
|
+
*/
|
|
106
|
+
const wantsStack = process.argv.includes("--debug") || process.env.REBASE_DEBUG === "1";
|
|
107
|
+
|
|
108
|
+
entry(process.argv).catch((error) => {
|
|
109
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
110
|
+
process.stderr.write(`\x1b[31m✗ ${message}\x1b[0m\n`);
|
|
111
|
+
if (wantsStack && error instanceof Error && error.stack) {
|
|
112
|
+
process.stderr.write(`\n${error.stack}\n`);
|
|
113
|
+
} else {
|
|
114
|
+
process.stderr.write("\x1b[90m Re-run with --debug for the stack trace.\x1b[0m\n");
|
|
115
|
+
}
|
|
116
|
+
process.exit(1);
|
|
117
|
+
});
|
package/dist/bundle.d.ts
CHANGED
|
@@ -68,6 +68,41 @@ export declare function detectNativeDependencies(projectRoot: string, declared:
|
|
|
68
68
|
* own config package already travels inside the bundle.
|
|
69
69
|
*/
|
|
70
70
|
export declare function collectDeclaredDependencies(projectRoot: string): Record<string, string>;
|
|
71
|
+
/** One `@rebasepro/*` dependency as some package.json in the project declares it. */
|
|
72
|
+
export interface DeclaredFrameworkDep {
|
|
73
|
+
name: string;
|
|
74
|
+
range: string;
|
|
75
|
+
/** Project-relative package.json it was declared in. */
|
|
76
|
+
file: string;
|
|
77
|
+
}
|
|
78
|
+
export interface FrameworkDepDrift {
|
|
79
|
+
/** Declared at a version that can never reach the CLI's own. */
|
|
80
|
+
behind: DeclaredFrameworkDep[];
|
|
81
|
+
/**
|
|
82
|
+
* The distinct lower bounds found across all declared `@rebasepro/*`, when
|
|
83
|
+
* there is more than one — the project is pinning mixed-era framework
|
|
84
|
+
* packages against each other.
|
|
85
|
+
*/
|
|
86
|
+
disagreeing: string[];
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Find `@rebasepro/*` dependencies pinned to a version older than this CLI.
|
|
90
|
+
*
|
|
91
|
+
* This is the only place a developer can be told. In development, every
|
|
92
|
+
* `@rebasepro/*` resolves through pnpm's `link:`/`workspace:` overrides to the
|
|
93
|
+
* checkout, so the version STRINGS in package.json are never exercised — the
|
|
94
|
+
* project runs fine locally on whatever is on disk, and the declared numbers are
|
|
95
|
+
* first honoured when the runtime npm-installs them from a bundle in the cloud.
|
|
96
|
+
* A project scaffolded at 0.10.0 therefore keeps working on a developer's
|
|
97
|
+
* machine indefinitely while being, in the cloud, a 0.10.0 driver.
|
|
98
|
+
*
|
|
99
|
+
* That matters because the image supplies only `@rebasepro/server`; the database
|
|
100
|
+
* driver comes from these declarations and a newer runtime never updates it.
|
|
101
|
+
* Every package.json is scanned, `dependencies` and `devDependencies` both,
|
|
102
|
+
* because they have to be bumped together and the one that gets forgotten is the
|
|
103
|
+
* one nobody looks at.
|
|
104
|
+
*/
|
|
105
|
+
export declare function detectFrameworkDepDrift(projectRoot: string, cliVersion: string): FrameworkDepDrift;
|
|
71
106
|
/**
|
|
72
107
|
* Rewrite relative import specifiers in emitted JavaScript so Node can resolve them.
|
|
73
108
|
*
|
|
@@ -182,3 +217,4 @@ export declare function buildStaticBundle(options: {
|
|
|
182
217
|
manifest: RebaseBundleManifest;
|
|
183
218
|
fileCount: number;
|
|
184
219
|
};
|
|
220
|
+
export declare function resolveCliVersion(): string;
|
package/dist/index.es.js
CHANGED
|
@@ -3515,6 +3515,139 @@ function collectDeclaredDependencies(projectRoot) {
|
|
|
3515
3515
|
return declared;
|
|
3516
3516
|
}
|
|
3517
3517
|
/**
|
|
3518
|
+
* Lowest version a range could resolve to, or null if it is not a range.
|
|
3519
|
+
*
|
|
3520
|
+
* Kept deliberately tiny and local. The published range grammar here is a caret,
|
|
3521
|
+
* a tilde, an exact version or a `>=` floor, and the alternative — a semver
|
|
3522
|
+
* dependency in the CLI — buys breadth this does not need.
|
|
3523
|
+
*/
|
|
3524
|
+
function lowerBoundOf(range) {
|
|
3525
|
+
const raw = range.trim().replace(/^[\^~]/, "").replace(/^>=\s*/, "").replace(/^v/, "");
|
|
3526
|
+
if (!/^\d+(\.\d+){0,2}$/.test(raw)) return null;
|
|
3527
|
+
const [major, minor = 0, patch = 0] = raw.split(".").map(Number);
|
|
3528
|
+
return [
|
|
3529
|
+
major,
|
|
3530
|
+
minor,
|
|
3531
|
+
patch
|
|
3532
|
+
];
|
|
3533
|
+
}
|
|
3534
|
+
/** Highest version a range could resolve to (exclusive), or null. */
|
|
3535
|
+
function upperBoundOf(range) {
|
|
3536
|
+
const trimmed = range.trim();
|
|
3537
|
+
const min = lowerBoundOf(trimmed);
|
|
3538
|
+
if (!min) return null;
|
|
3539
|
+
if (trimmed.startsWith(">=")) return null;
|
|
3540
|
+
const [major, minor, patch] = min;
|
|
3541
|
+
if (trimmed.startsWith("^")) {
|
|
3542
|
+
if (major > 0) return [
|
|
3543
|
+
major + 1,
|
|
3544
|
+
0,
|
|
3545
|
+
0
|
|
3546
|
+
];
|
|
3547
|
+
if (minor > 0) return [
|
|
3548
|
+
0,
|
|
3549
|
+
minor + 1,
|
|
3550
|
+
0
|
|
3551
|
+
];
|
|
3552
|
+
return [
|
|
3553
|
+
0,
|
|
3554
|
+
0,
|
|
3555
|
+
patch + 1
|
|
3556
|
+
];
|
|
3557
|
+
}
|
|
3558
|
+
if (trimmed.startsWith("~")) return trimmed.replace(/^~v?/, "").split(".").length >= 2 ? [
|
|
3559
|
+
major,
|
|
3560
|
+
minor + 1,
|
|
3561
|
+
0
|
|
3562
|
+
] : [
|
|
3563
|
+
major + 1,
|
|
3564
|
+
0,
|
|
3565
|
+
0
|
|
3566
|
+
];
|
|
3567
|
+
const parts = trimmed.replace(/^v/, "").split(".").length;
|
|
3568
|
+
if (parts === 1) return [
|
|
3569
|
+
major + 1,
|
|
3570
|
+
0,
|
|
3571
|
+
0
|
|
3572
|
+
];
|
|
3573
|
+
if (parts === 2) return [
|
|
3574
|
+
major,
|
|
3575
|
+
minor + 1,
|
|
3576
|
+
0
|
|
3577
|
+
];
|
|
3578
|
+
return [
|
|
3579
|
+
major,
|
|
3580
|
+
minor,
|
|
3581
|
+
patch + 1
|
|
3582
|
+
];
|
|
3583
|
+
}
|
|
3584
|
+
function compareTriples(a, b) {
|
|
3585
|
+
for (let i = 0; i < 3; i++) if (a[i] !== b[i]) return a[i] < b[i] ? -1 : 1;
|
|
3586
|
+
return 0;
|
|
3587
|
+
}
|
|
3588
|
+
/**
|
|
3589
|
+
* Whether a declared range could EVER resolve at or above `target`.
|
|
3590
|
+
*
|
|
3591
|
+
* The same question the control plane asks at intake, asked here first. Only a
|
|
3592
|
+
* range whose entire span sits below the target is reported — `^0.10.0` can
|
|
3593
|
+
* never cross to 0.12 whatever npm publishes — because a false alarm on a build
|
|
3594
|
+
* that would have worked trains people to ignore the warning that matters.
|
|
3595
|
+
*/
|
|
3596
|
+
function canReach(range, target) {
|
|
3597
|
+
const ceiling = upperBoundOf(range);
|
|
3598
|
+
const floor = lowerBoundOf(target);
|
|
3599
|
+
if (!floor || !lowerBoundOf(range)) return null;
|
|
3600
|
+
if (!ceiling) return true;
|
|
3601
|
+
return compareTriples(ceiling, floor) > 0;
|
|
3602
|
+
}
|
|
3603
|
+
/**
|
|
3604
|
+
* Find `@rebasepro/*` dependencies pinned to a version older than this CLI.
|
|
3605
|
+
*
|
|
3606
|
+
* This is the only place a developer can be told. In development, every
|
|
3607
|
+
* `@rebasepro/*` resolves through pnpm's `link:`/`workspace:` overrides to the
|
|
3608
|
+
* checkout, so the version STRINGS in package.json are never exercised — the
|
|
3609
|
+
* project runs fine locally on whatever is on disk, and the declared numbers are
|
|
3610
|
+
* first honoured when the runtime npm-installs them from a bundle in the cloud.
|
|
3611
|
+
* A project scaffolded at 0.10.0 therefore keeps working on a developer's
|
|
3612
|
+
* machine indefinitely while being, in the cloud, a 0.10.0 driver.
|
|
3613
|
+
*
|
|
3614
|
+
* That matters because the image supplies only `@rebasepro/server`; the database
|
|
3615
|
+
* driver comes from these declarations and a newer runtime never updates it.
|
|
3616
|
+
* Every package.json is scanned, `dependencies` and `devDependencies` both,
|
|
3617
|
+
* because they have to be bumped together and the one that gets forgotten is the
|
|
3618
|
+
* one nobody looks at.
|
|
3619
|
+
*/
|
|
3620
|
+
function detectFrameworkDepDrift(projectRoot, cliVersion) {
|
|
3621
|
+
const found = [];
|
|
3622
|
+
for (const relative of [
|
|
3623
|
+
"package.json",
|
|
3624
|
+
"backend/package.json",
|
|
3625
|
+
"config/package.json",
|
|
3626
|
+
"frontend/package.json"
|
|
3627
|
+
]) {
|
|
3628
|
+
const file = path.join(projectRoot, relative);
|
|
3629
|
+
if (!fs.existsSync(file)) continue;
|
|
3630
|
+
try {
|
|
3631
|
+
const pkg = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
3632
|
+
for (const block of [pkg.dependencies, pkg.devDependencies]) for (const [name, range] of Object.entries(block ?? {})) {
|
|
3633
|
+
if (!name.startsWith("@rebasepro/")) continue;
|
|
3634
|
+
if (typeof range !== "string") continue;
|
|
3635
|
+
found.push({
|
|
3636
|
+
name,
|
|
3637
|
+
range,
|
|
3638
|
+
file: relative
|
|
3639
|
+
});
|
|
3640
|
+
}
|
|
3641
|
+
} catch {}
|
|
3642
|
+
}
|
|
3643
|
+
const behind = found.filter((d) => canReach(d.range, cliVersion) === false);
|
|
3644
|
+
const bounds = new Set(found.map((d) => lowerBoundOf(d.range)).filter((b) => b != null).map((b) => b.join(".")));
|
|
3645
|
+
return {
|
|
3646
|
+
behind,
|
|
3647
|
+
disagreeing: bounds.size > 1 ? [...bounds].sort() : []
|
|
3648
|
+
};
|
|
3649
|
+
}
|
|
3650
|
+
/**
|
|
3518
3651
|
* Rewrite relative import specifiers in emitted JavaScript so Node can resolve them.
|
|
3519
3652
|
*
|
|
3520
3653
|
* TypeScript deliberately does not touch specifiers: `moduleResolution: "bundler"`
|
|
@@ -4212,6 +4345,16 @@ async function buildCommand(rawArgs = []) {
|
|
|
4212
4345
|
console.log(chalk.yellow(` ⚠ native dependencies detected: ${names}`));
|
|
4213
4346
|
console.log(chalk.dim(" These cannot run on the managed runtime. See `rebase doctor`."));
|
|
4214
4347
|
}
|
|
4348
|
+
const drift = detectFrameworkDepDrift(projectRoot, resolveCliVersion());
|
|
4349
|
+
if (drift.behind.length > 0) {
|
|
4350
|
+
console.log(chalk.yellow(` ⚠ framework dependencies older than this CLI (${resolveCliVersion()}):`));
|
|
4351
|
+
for (const dep of drift.behind) console.log(chalk.dim(` ${dep.name}@${dep.range} (${dep.file})`));
|
|
4352
|
+
console.log(chalk.dim(" The image supplies the server, but your bundle supplies the database"));
|
|
4353
|
+
console.log(chalk.dim(" driver — a newer runtime does not update it. Bump these and rebuild."));
|
|
4354
|
+
} else if (drift.disagreeing.length > 0) {
|
|
4355
|
+
console.log(chalk.yellow(` ⚠ mixed @rebasepro versions declared: ${drift.disagreeing.join(", ")}`));
|
|
4356
|
+
console.log(chalk.dim(" These are published together and expect to run together; pin them alike."));
|
|
4357
|
+
}
|
|
4215
4358
|
if (!args["--no-static"]) {
|
|
4216
4359
|
const folded = await foldFrontendIntoBundle({
|
|
4217
4360
|
projectRoot,
|
|
@@ -5070,7 +5213,7 @@ function parseAgentFlags(rawArgs) {
|
|
|
5070
5213
|
return requested;
|
|
5071
5214
|
}
|
|
5072
5215
|
async function skillsInstall(rawArgs = []) {
|
|
5073
|
-
const projectDir = process.cwd();
|
|
5216
|
+
const projectDir = findProjectRoot() ?? process.cwd();
|
|
5074
5217
|
let skillsDir;
|
|
5075
5218
|
try {
|
|
5076
5219
|
skillsDir = getSkillsSourceDir();
|
|
@@ -5114,7 +5257,8 @@ async function skillsInstall(rawArgs = []) {
|
|
|
5114
5257
|
for (const agentKey of agents) {
|
|
5115
5258
|
const agent = AGENTS[agentKey];
|
|
5116
5259
|
const count = installForAgent(agentKey, skills, projectDir);
|
|
5117
|
-
|
|
5260
|
+
const shown = path.relative(process.cwd(), path.join(projectDir, agent.targetDir)) || agent.targetDir;
|
|
5261
|
+
console.log(` ${chalk.green("✓")} ${chalk.bold(agent.label)} — ${count} skills installed to ${chalk.gray(shown)}`);
|
|
5118
5262
|
}
|
|
5119
5263
|
console.log("");
|
|
5120
5264
|
console.log(chalk.gray(" Skills are project-local. Commit them to share with your team."));
|
|
@@ -9885,9 +10029,10 @@ async function entry(args) {
|
|
|
9885
10029
|
argv: args.slice(3),
|
|
9886
10030
|
permissive: true
|
|
9887
10031
|
});
|
|
10032
|
+
const sdkRoot = sdkArgs["--help"] ? process.cwd() : requireProjectRoot();
|
|
9888
10033
|
await generateSdkCommand({
|
|
9889
|
-
collectionsDir: sdkArgs["--collections-dir"] || "
|
|
9890
|
-
output: sdkArgs["--output"] || "
|
|
10034
|
+
collectionsDir: sdkArgs["--collections-dir"] || path.join(sdkRoot, "config/collections"),
|
|
10035
|
+
output: sdkArgs["--output"] || path.join(sdkRoot, "generated/sdk"),
|
|
9891
10036
|
from: sdkArgs["--from"],
|
|
9892
10037
|
token: sdkArgs["--token"],
|
|
9893
10038
|
help: sdkArgs["--help"],
|
|
@@ -9997,6 +10142,6 @@ ${chalk.gray("Documentation: https://rebase.pro/docs")}
|
|
|
9997
10142
|
`);
|
|
9998
10143
|
}
|
|
9999
10144
|
//#endregion
|
|
10000
|
-
export { CURRENT_RUNTIME_RANGE, DEFAULT_BUNDLE_DIR, DEFAULT_CONFIG_DIR, DEFAULT_CRONS_DIR, DEFAULT_FUNCTIONS_DIR, DEFAULT_SCHEMA_FILE, MANIFEST_FILENAME, ManifestError, TEMPLATE_PLACEHOLDER_FILES, appsCommand, assessManagedCompatibility, authCommand, buildBundle, buildCommand, buildInitQuestions, buildStaticBundle, buildableApps, cloudCommand, collectDeclaredDependencies, configureEnvFile, createRebaseApp, dbCommand, detectNativeDependencies, detectPackageManager, detectStorageAuthorize, devCommand, doctorCommand, ejectCommand, entry, findBackendApp, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, findUnusedServerEntry, foldStaticIntoBundle, formatCdTarget, generateSdkCommand, getActiveBackendPlugin, getPMCommands, isIdentifierLike, isPnpmAvailable, loadManifest, manifestExists, manifestPath, normalizeEsmSpecifiers, pnpmAvailabilityFromProbe, printInitHelp, requireBackendDir, requireProjectRoot, resetPnpmAvailabilityCache, resolveBackendPaths, resolveExampleBaseUrl, resolveLocalBin, resolvePluginCliScript, resolveTsx, schemaCommand, startCommand, synthesizeManifest, validateManifest, validateProjectName, validateTsxInstallation, writeManifest };
|
|
10145
|
+
export { CURRENT_RUNTIME_RANGE, DEFAULT_BUNDLE_DIR, DEFAULT_CONFIG_DIR, DEFAULT_CRONS_DIR, DEFAULT_FUNCTIONS_DIR, DEFAULT_SCHEMA_FILE, MANIFEST_FILENAME, ManifestError, TEMPLATE_PLACEHOLDER_FILES, appsCommand, assessManagedCompatibility, authCommand, buildBundle, buildCommand, buildInitQuestions, buildStaticBundle, buildableApps, cloudCommand, collectDeclaredDependencies, configureEnvFile, createRebaseApp, dbCommand, detectFrameworkDepDrift, detectNativeDependencies, detectPackageManager, detectStorageAuthorize, devCommand, doctorCommand, ejectCommand, entry, findBackendApp, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, findUnusedServerEntry, foldStaticIntoBundle, formatCdTarget, generateSdkCommand, getActiveBackendPlugin, getPMCommands, isIdentifierLike, isPnpmAvailable, loadManifest, manifestExists, manifestPath, normalizeEsmSpecifiers, pnpmAvailabilityFromProbe, printInitHelp, requireBackendDir, requireProjectRoot, resetPnpmAvailabilityCache, resolveBackendPaths, resolveCliVersion, resolveExampleBaseUrl, resolveLocalBin, resolvePluginCliScript, resolveTsx, schemaCommand, startCommand, synthesizeManifest, validateManifest, validateProjectName, validateTsxInstallation, writeManifest };
|
|
10001
10146
|
|
|
10002
10147
|
//# sourceMappingURL=index.es.js.map
|