@rebasepro/cli 0.15.0 → 0.16.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/bundle.d.ts CHANGED
@@ -15,6 +15,15 @@ export interface BuildBundleOptions {
15
15
  * once, by the command that owns it.
16
16
  */
17
17
  storage?: DeclaredStorageSources;
18
+ /**
19
+ * Install the declared dependencies into the bundle at build time.
20
+ *
21
+ * Omitted means "when it is safe to" — which is every bundle whose closure
22
+ * has no native code. `false` is the escape hatch for a build that must not
23
+ * shell out to npm at all (an air-gapped CI, a offline reproducibility
24
+ * check); the bundle still works, it simply installs at boot as before.
25
+ */
26
+ vendor?: boolean;
18
27
  /** Skip type checking. Faster, and strictly worse — for iteration only. */
19
28
  skipTypeCheck?: boolean;
20
29
  /** Skip regenerating the Drizzle schema from the collections. */
@@ -26,6 +35,13 @@ export interface BuildBundleResult {
26
35
  outDir: string;
27
36
  manifest: RebaseBundleManifest;
28
37
  collectionCount: number;
38
+ /**
39
+ * Whether the dependency tree was installed into the bundle, and why not
40
+ * when it was not. Reported rather than silent: "your pods will take a
41
+ * minute to start" is a consequence a developer should hear at build time,
42
+ * not discover during an incident.
43
+ */
44
+ vendor: VendorResult;
29
45
  }
30
46
  /**
31
47
  * Whether the compiled config package exports a `storageAuthorize` hook.
@@ -147,6 +163,85 @@ export declare function findUnusedServerEntry(projectRoot: string, functionsDir:
147
163
  * Compile and assemble a bundle.
148
164
  */
149
165
  export declare function buildBundle(options: BuildBundleOptions): Promise<BuildBundleResult>;
166
+ /** Default install target: what the published runtime image runs. */
167
+ export declare const VENDOR_TARGET_OS = "linux";
168
+ export declare const VENDOR_TARGET_CPU = "x64";
169
+ export interface VendorResult {
170
+ vendored: boolean;
171
+ target?: {
172
+ os: string;
173
+ cpu: string;
174
+ node: string;
175
+ };
176
+ /** Why nothing was installed. Present exactly when `vendored` is false. */
177
+ skipped?: string;
178
+ /** Size of the installed tree on disk, when one was installed. */
179
+ bytes?: number;
180
+ }
181
+ /**
182
+ * Where a vendored bundle starts being too big to upload.
183
+ *
184
+ * The control plane refuses a bundle over 100 MB, and that ceiling is not
185
+ * arbitrary or easily raised: its pod has a 512Mi memory limit and the upload
186
+ * route holds the body while it writes it, so the cap protects the process that
187
+ * also serves the console, deploys and billing. Vendoring is the one change that
188
+ * can push a bundle near it.
189
+ *
190
+ * So the warning is here, at build time, where the remedy is one flag away —
191
+ * rather than at deploy time as a 413 nobody can act on without rebuilding. The
192
+ * threshold sits below the real cap because this measures the tree on disk and
193
+ * the upload is compressed: crossing it means "getting close", not "will fail".
194
+ */
195
+ export declare const VENDOR_SIZE_WARN_BYTES: number;
196
+ /**
197
+ * Install the bundle's declared dependencies into the bundle itself.
198
+ *
199
+ * ## What this buys
200
+ *
201
+ * A managed pod's bundle lives on an `emptyDir`, so it is re-fetched and
202
+ * re-installed on **every** start — an eviction, a node failure, an OOM, a
203
+ * runtime rollout. The install is 35–55 seconds of a 40–60 second cold start,
204
+ * which makes it the price of every unplanned restart a tenant suffers. Doing it
205
+ * once at build time instead of every time at boot takes that to roughly the
206
+ * cost of untarring.
207
+ *
208
+ * The pod side needs no change to benefit: the init container already skips
209
+ * installing when `node_modules` is present, a guard that existed for
210
+ * pre-baked images and turns out to be exactly the hook this needs.
211
+ *
212
+ * ## Why it refuses to vendor native code
213
+ *
214
+ * A compiled binary is valid only for the platform it was built for, and a
215
+ * developer's machine is rarely the deployment's. The managed runtime already
216
+ * refuses bundles containing native modules for the same reason, so this refusal
217
+ * costs nothing there — but a self-hosted project may legitimately use them, and
218
+ * for those the honest answer is to install in the container, where the platform
219
+ * is known.
220
+ *
221
+ * ## Why `--os` and `--cpu` are not optional
222
+ *
223
+ * The dangerous case is not native code, which is detectable. It is a pure-JS
224
+ * package whose real work lives in a **platform-specific optional dependency** —
225
+ * `esbuild` being the one everybody meets. Installing on an Apple Silicon Mac
226
+ * resolves `@esbuild/darwin-arm64`, produces a tree that looks complete, and
227
+ * fails at import inside a linux/amd64 pod. npm resolves optional dependencies
228
+ * for the declared target rather than the host when told to, so it is told to.
229
+ */
230
+ export declare function vendorDependencies(options: {
231
+ outDir: string;
232
+ declared: Record<string, string>;
233
+ nativeModules: NativeDependency[];
234
+ /**
235
+ * Packages the runtime resolves *from the bundle* and cannot boot without —
236
+ * in practice the database driver, which the image deliberately does not
237
+ * supply. A vendored tree missing one of these is refused; see below.
238
+ */
239
+ required?: string[];
240
+ /** `false` disables; `undefined` means "when it is safe to". */
241
+ requested?: boolean;
242
+ /** Injected in tests. */
243
+ run?: (cmd: string, args: string[], cwd: string) => void;
244
+ }): VendorResult;
150
245
  /**
151
246
  * Package a built static app (a `static` or bundled-`admin` app) into a bundle.
152
247
  *
@@ -73,6 +73,41 @@ export declare function resolveWebhookIdArg(rawArgs: string[]): string | undefin
73
73
  export declare function webhooksCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void>;
74
74
  export declare function storageCommand(action: string | undefined, rawArgs: string[]): Promise<void>;
75
75
  export declare function printStorageHelp(): void;
76
- export declare function clustersCommand(rawArgs: string[]): Promise<void>;
76
+ /**
77
+ * `rebase cloud clusters` — list, register and verify the clusters tenants run on.
78
+ *
79
+ * Registration is deliberately an operator action: the `clusters` collection is
80
+ * admin-only, and a cluster record carries a credential with enough power to
81
+ * create namespaces and read every secret in them. A self-serve "bring your own
82
+ * cluster" flow is a different feature with a different threat model.
83
+ */
84
+ export declare function clustersCommand(action: string | undefined, rawArgs: string[]): Promise<void>;
77
85
  export declare function billingCommand(rawArgs: string[]): Promise<void>;
86
+ /**
87
+ * `rebase cloud resources` — show what a project is given, and change it.
88
+ *
89
+ * ## Why nothing is validated here
90
+ *
91
+ * The rules are the *target cluster's*, not the CLI's: GKE Autopilot bills a
92
+ * 250m/512Mi floor and rewrites anything outside a 1:1–6.5:1 memory:CPU band,
93
+ * while a Hetzner or EKS node has neither constraint. A CLI that carried those
94
+ * numbers would be wrong for two of the three providers the moment it shipped,
95
+ * and would drift from the control plane the first time either changed.
96
+ *
97
+ * So the control plane validates and this reports what it said. The same
98
+ * boundary refuses a raw PATCH and a console save, which is the property worth
99
+ * having — a check in a client only covers the clients that run it.
100
+ */
101
+ export declare function resourcesCommand(action: string | undefined, rawArgs: string[]): Promise<void>;
102
+ /**
103
+ * Turn `--cpu 500m --db-instances 2` into the patch to send.
104
+ *
105
+ * Pure, and exported, so the flag handling is testable without a control plane —
106
+ * the same shape `buildSettingsPatch` uses. Returns an error string rather than
107
+ * throwing, because the caller owns how a refusal is printed in JSON mode.
108
+ */
109
+ export declare function buildDialPatch(rawArgs: string[]): {
110
+ patch: Record<string, unknown>;
111
+ error?: string;
112
+ };
78
113
  export {};
@@ -1 +1,16 @@
1
+ /**
2
+ * Rewrite local path arguments so they mean what the user typed.
3
+ *
4
+ * The plugin CLI is spawned with `cwd: backendDir` — it has to be, because that
5
+ * is where the plugin and its dependencies resolve from. But the developer runs
6
+ * `rebase db` from the project root, so a relative `--out ./backups` was being
7
+ * resolved against `backend/` and landed in `backend/backups`, while the
8
+ * success line echoed the path as typed. The file was real and the reported
9
+ * location was wrong, which is the worst way for a backup command to behave.
10
+ * `rebase db --help` documents exactly this invocation.
11
+ *
12
+ * Absolutising here rather than inside the plugin keeps the fix where the cwd
13
+ * is actually changed, and leaves the plugin usable on its own terms.
14
+ */
15
+ export declare function absolutizeLocalPathArgs(args: string[], cwd: string): string[];
1
16
  export declare function dbCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void>;
@@ -1 +1,9 @@
1
+ import { type LibpqUrlFinding } from "../utils/libpq-url";
2
+ /**
3
+ * Find connection strings libpq cannot parse, anywhere in the project.
4
+ *
5
+ * Exported for the tests; `envFile` is passed separately because a project may
6
+ * keep its `.env` outside the root (see `findEnvFile`).
7
+ */
8
+ export declare function findLibpqUrlProblems(projectRoot: string, envFile?: string | null): LibpqUrlFinding[];
1
9
  export declare function doctorCommand(rawArgs: string[]): Promise<void>;