@rebasepro/cli 0.23.0 → 0.24.1-canary.g19596ef

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.
Files changed (186) hide show
  1. package/README.md +19 -3
  2. package/bin/rebase.js +4 -1
  3. package/dist/agent-setup-B31F00DC.js +324 -0
  4. package/dist/agent-setup-B31F00DC.js.map +1 -0
  5. package/dist/api-keys-Bl1I9q7M.js +525 -0
  6. package/dist/api-keys-Bl1I9q7M.js.map +1 -0
  7. package/dist/apps-CNgQJjg5.js +340 -0
  8. package/dist/apps-CNgQJjg5.js.map +1 -0
  9. package/dist/args-BnmsEXvu.js +109 -0
  10. package/dist/args-BnmsEXvu.js.map +1 -0
  11. package/dist/atlas-dev-database-D_LP_Woq.js +62 -0
  12. package/dist/atlas-dev-database-D_LP_Woq.js.map +1 -0
  13. package/dist/auth-aySHEF45.js +414 -0
  14. package/dist/auth-aySHEF45.js.map +1 -0
  15. package/dist/branch-pointer-DvSHBjjz.js +2 -0
  16. package/dist/build-DIHWIqO4.js +336 -0
  17. package/dist/build-DIHWIqO4.js.map +1 -0
  18. package/dist/bundle-CqURVN-K.js +1621 -0
  19. package/dist/bundle-CqURVN-K.js.map +1 -0
  20. package/dist/bundle.d.ts +12 -3
  21. package/dist/cli.d.ts +23 -2
  22. package/dist/cloud-DjByQlkW.js +9667 -0
  23. package/dist/cloud-DjByQlkW.js.map +1 -0
  24. package/dist/collection-drift-BKj_BoMq.js +106 -0
  25. package/dist/collection-drift-BKj_BoMq.js.map +1 -0
  26. package/dist/commands/__test_support__/parser-specs.d.ts +13 -0
  27. package/dist/commands/agent-setup.d.ts +116 -0
  28. package/dist/commands/api-keys.d.ts +86 -23
  29. package/dist/commands/apps.d.ts +17 -0
  30. package/dist/commands/auth.d.ts +7 -0
  31. package/dist/commands/build.d.ts +5 -1
  32. package/dist/commands/cloud/auth.d.ts +4 -3
  33. package/dist/commands/cloud/bundle-deploy.d.ts +45 -0
  34. package/dist/commands/cloud/context.d.ts +44 -5
  35. package/dist/commands/cloud/cron.d.ts +53 -0
  36. package/dist/commands/cloud/debug.d.ts +134 -0
  37. package/dist/commands/cloud/index.d.ts +89 -12
  38. package/dist/commands/cloud/token-capabilities.d.ts +76 -0
  39. package/dist/commands/cloud/tokens.d.ts +23 -0
  40. package/dist/commands/console.d.ts +12 -0
  41. package/dist/commands/db.d.ts +79 -25
  42. package/dist/commands/dev.d.ts +181 -13
  43. package/dist/commands/doctor.d.ts +5 -0
  44. package/dist/commands/generate_sdk.d.ts +29 -2
  45. package/dist/commands/init.d.ts +115 -14
  46. package/dist/commands/schema.d.ts +6 -0
  47. package/dist/commands/skills.d.ts +126 -7
  48. package/dist/commands/start.d.ts +44 -0
  49. package/dist/commands/storage.d.ts +46 -0
  50. package/dist/commands/upgrade.d.ts +1 -0
  51. package/dist/consent-ClRHmcxf.js +76 -0
  52. package/dist/consent-ClRHmcxf.js.map +1 -0
  53. package/dist/console-D6SJf8k_.js +102 -0
  54. package/dist/console-D6SJf8k_.js.map +1 -0
  55. package/dist/context-BqhRydBg.js +1234 -0
  56. package/dist/context-BqhRydBg.js.map +1 -0
  57. package/dist/{daemon-entry-LTFKtpHy.js → daemon-entry-Da-D3rmH.js} +3 -4
  58. package/dist/daemon-entry-Da-D3rmH.js.map +1 -0
  59. package/dist/daemon-pzsQwDHa.js +2 -0
  60. package/dist/db-B7RuNuaQ.js +1312 -0
  61. package/dist/db-B7RuNuaQ.js.map +1 -0
  62. package/dist/derive-Dl0z2OWi.js +484 -0
  63. package/dist/derive-Dl0z2OWi.js.map +1 -0
  64. package/dist/dev-CYr_WXan.js +1599 -0
  65. package/dist/dev-CYr_WXan.js.map +1 -0
  66. package/dist/dev-db/atlas-dev-database.d.ts +32 -0
  67. package/dist/dev-db/daemon-entry.d.ts +13 -0
  68. package/dist/dev-db/daemon.d.ts +10 -0
  69. package/dist/dev-db/last-dev-database.d.ts +41 -0
  70. package/dist/dev-db/prepare.d.ts +29 -3
  71. package/dist/dev-db/pull.d.ts +90 -5
  72. package/dist/dev-db/resolve.d.ts +26 -2
  73. package/dist/dev-preflight-B-LYyBf1.js +2 -0
  74. package/dist/dev-server-DG8Tt-uf.js +96 -0
  75. package/dist/dev-server-DG8Tt-uf.js.map +1 -0
  76. package/dist/doctor-BP8cZ-7F.js +771 -0
  77. package/dist/doctor-BP8cZ-7F.js.map +1 -0
  78. package/dist/eject-DizdoecV.js +335 -0
  79. package/dist/eject-DizdoecV.js.map +1 -0
  80. package/dist/fold-static-BC9CYicw.js +201 -0
  81. package/dist/fold-static-BC9CYicw.js.map +1 -0
  82. package/dist/fold-static.d.ts +26 -3
  83. package/dist/function-portability-BIvlvR9q.js +265 -0
  84. package/dist/function-portability-BIvlvR9q.js.map +1 -0
  85. package/dist/generate_sdk-BPqdJc3Q.js +489 -0
  86. package/dist/generate_sdk-BPqdJc3Q.js.map +1 -0
  87. package/dist/index.es.js +199 -22095
  88. package/dist/index.es.js.map +1 -1
  89. package/dist/init-Utstvh2Q.js +1149 -0
  90. package/dist/init-Utstvh2Q.js.map +1 -0
  91. package/dist/last-dev-database-B58g89uA.js +2 -0
  92. package/dist/manifest-DRp0UVTj.js +880 -0
  93. package/dist/manifest-DRp0UVTj.js.map +1 -0
  94. package/dist/manifest.d.ts +56 -4
  95. package/dist/normalize-imports-X0Tgze9y.js +107 -0
  96. package/dist/normalize-imports-X0Tgze9y.js.map +1 -0
  97. package/dist/package-manager-DSEOwTqM.js +193 -0
  98. package/dist/package-manager-DSEOwTqM.js.map +1 -0
  99. package/dist/path-flags-BFgG9V6y.js +91 -0
  100. package/dist/path-flags-BFgG9V6y.js.map +1 -0
  101. package/dist/precompress.d.ts +17 -0
  102. package/dist/prepare-CDN6lSpz.js +1236 -0
  103. package/dist/prepare-CDN6lSpz.js.map +1 -0
  104. package/dist/{project-3WCbrrfW.js → project-Wp2zoyeN.js} +34 -184
  105. package/dist/project-Wp2zoyeN.js.map +1 -0
  106. package/dist/pull-CrGYMEsy.js +458 -0
  107. package/dist/pull-CrGYMEsy.js.map +1 -0
  108. package/dist/resolve-B2O-wKKk.js +2 -0
  109. package/dist/resources-FD7AfZx8.js +183 -0
  110. package/dist/resources-FD7AfZx8.js.map +1 -0
  111. package/dist/schema-DMdr431S.js +125 -0
  112. package/dist/schema-DMdr431S.js.map +1 -0
  113. package/dist/skills-DTFibT1m.js +642 -0
  114. package/dist/skills-DTFibT1m.js.map +1 -0
  115. package/dist/start-DEa-hOBh.js +267 -0
  116. package/dist/start-DEa-hOBh.js.map +1 -0
  117. package/dist/{state-C59Elrnt.js → state-Do7ZJYkF.js} +49 -4
  118. package/dist/state-Do7ZJYkF.js.map +1 -0
  119. package/dist/status-DxnJTekv.js +352 -0
  120. package/dist/status-DxnJTekv.js.map +1 -0
  121. package/dist/storage-DyVq-f_F.js +303 -0
  122. package/dist/storage-DyVq-f_F.js.map +1 -0
  123. package/dist/telemetry/identity.d.ts +10 -1
  124. package/dist/telemetry-C8Uq8phb.js +129 -0
  125. package/dist/telemetry-C8Uq8phb.js.map +1 -0
  126. package/dist/telemetry-EMFRVRQi.js +351 -0
  127. package/dist/telemetry-EMFRVRQi.js.map +1 -0
  128. package/dist/unknown-command-DNwDcX3w.js +98 -0
  129. package/dist/unknown-command-DNwDcX3w.js.map +1 -0
  130. package/dist/upgrade-CtZtRkTE.js +1332 -0
  131. package/dist/upgrade-CtZtRkTE.js.map +1 -0
  132. package/dist/upgrade.d.ts +38 -5
  133. package/dist/utils/dev-preflight.d.ts +47 -5
  134. package/dist/utils/dev-server.d.ts +30 -0
  135. package/dist/utils/path-flags.d.ts +31 -0
  136. package/dist/utils/project.d.ts +16 -0
  137. package/dist/utils/temp-archive.d.ts +9 -0
  138. package/dist/version-Buyyo1ut.js +58 -0
  139. package/dist/version-Buyyo1ut.js.map +1 -0
  140. package/package.json +7 -7
  141. package/templates/eject/Dockerfile +4 -2
  142. package/templates/eject/backend/src/env.ts +1 -1
  143. package/templates/eject/backend/src/index.ts +42 -4
  144. package/templates/eject/docker-compose.custom.yml +8 -4
  145. package/templates/generated-schemas/blank.ts +40 -0
  146. package/templates/generated-schemas/blog.ts +127 -0
  147. package/templates/generated-schemas/ecommerce.ts +93 -0
  148. package/templates/overlays/baas/ai-instructions.md +1 -1
  149. package/templates/overlays/baas/config/package.json +1 -0
  150. package/templates/overlays/baas/config/storage.ts +5 -3
  151. package/templates/overlays/baas/package.json +1 -0
  152. package/templates/template/.cursorrules +1 -1
  153. package/templates/template/.env.example +20 -10
  154. package/templates/template/.github/copilot-instructions.md +1 -1
  155. package/templates/template/.mcp.json +2 -2
  156. package/templates/template/.windsurfrules +1 -1
  157. package/templates/template/AGENTS.md +1 -1
  158. package/templates/template/CLAUDE.md +1 -1
  159. package/templates/template/README.md +21 -15
  160. package/templates/template/ai-instructions.md +5 -4
  161. package/templates/template/backend/functions/hello.ts +8 -0
  162. package/templates/template/backend/package.json +1 -1
  163. package/templates/template/config/resources.ts +7 -6
  164. package/templates/template/config/storage.ts +5 -3
  165. package/templates/template/docker-compose.yml +15 -9
  166. package/templates/template/frontend/vite.config.ts +13 -3
  167. package/templates/template/gitignore +6 -1
  168. package/templates/template/package.json +5 -3
  169. package/templates/template/scripts/example.ts +6 -4
  170. package/templates/template/tsconfig.json +25 -0
  171. package/dist/branch-pointer-dBiClJ0p.js +0 -111
  172. package/dist/branch-pointer-dBiClJ0p.js.map +0 -1
  173. package/dist/constraints-DKGbNfUW.js +0 -48
  174. package/dist/constraints-DKGbNfUW.js.map +0 -1
  175. package/dist/daemon-DR9Tk0La.js +0 -355
  176. package/dist/daemon-DR9Tk0La.js.map +0 -1
  177. package/dist/daemon-entry-LTFKtpHy.js.map +0 -1
  178. package/dist/dev-preflight-CNLl4rdo.js +0 -367
  179. package/dist/dev-preflight-CNLl4rdo.js.map +0 -1
  180. package/dist/project-3WCbrrfW.js.map +0 -1
  181. package/dist/pull-Dywm5FWP.js +0 -232
  182. package/dist/pull-Dywm5FWP.js.map +0 -1
  183. package/dist/resolve-BAeRUBhg.js +0 -74
  184. package/dist/resolve-BAeRUBhg.js.map +0 -1
  185. package/dist/state-C59Elrnt.js.map +0 -1
  186. package/templates/template/backend/src/schema.generated.ts +0 -13
@@ -1,3 +1,4 @@
1
+ import { type CloudClient } from "./context.js";
1
2
  /** How a probe's outcome should be read. */
2
3
  export type Verdict =
3
4
  /** Behaving as a healthy deployment should. */
@@ -114,5 +115,138 @@ export declare function formatDuration(seconds: number): string;
114
115
  * into seconds. Returns null when it is not a duration.
115
116
  */
116
117
  export declare function parseSince(input: string | undefined): number | null;
118
+ /** One pod's entry in a `runtime-logs` answer. */
119
+ export interface RuntimeLogsPod {
120
+ pod: string;
121
+ state: string;
122
+ /** Lines this pod returned. */
123
+ lines: number;
124
+ message: string | null;
125
+ hint: string | null;
126
+ /** The server's per-pod BYTE budget cut this pod's output. Says nothing about the line limit. */
127
+ truncated?: boolean;
128
+ }
129
+ export interface RuntimeLogsResponse {
130
+ logs?: string;
131
+ pods?: RuntimeLogsPod[];
132
+ ordering?: string;
133
+ /** A byte budget or the pod-count ceiling cut the result. Says nothing about the line limit. */
134
+ truncated?: boolean;
135
+ state?: string;
136
+ message?: string | null;
137
+ }
138
+ /**
139
+ * The most lines `runtime-logs` returns per pod.
140
+ *
141
+ * The control plane enforces this (`MAX_TAIL_LINES` in
142
+ * `saas/backend/functions/runtime-logs.ts`) by clamping a larger `tailLines`
143
+ * without saying so: its answer names neither the limit nor the value it used.
144
+ * `--tail 200000` therefore came back as 2000 lines reported as untruncated.
145
+ * The CLI clamps first, with the same number, so the lowering is something it
146
+ * can print rather than something that happened out of sight.
147
+ */
148
+ export declare const SERVER_MAX_TAIL_LINES = 2000;
149
+ /** How many lines per pod a read asks for, and why that may be less than requested. */
150
+ export interface TailLimit {
151
+ /** What `--tail` asked for, or the view's default. */
152
+ requested: number;
153
+ /** What is sent: `requested`, lowered to {@link SERVER_MAX_TAIL_LINES}. */
154
+ applied: number;
155
+ /** Whether `--tail` was given, so a message can name the flag or the default. */
156
+ explicit: boolean;
157
+ /** Set when `applied < requested`: the sentence that says so. */
158
+ note: string | null;
159
+ }
160
+ export declare function resolveTail(requested: number, explicit: boolean): TailLimit;
161
+ /** What one pod's lines actually cover. */
162
+ export interface PodCoverage extends RuntimeLogsPod {
163
+ /** Earliest and latest timestamps among the lines this pod returned. */
164
+ firstTimestamp: string | null;
165
+ lastTimestamp: string | null;
166
+ /** A limit cut what this pod would otherwise have returned for the window. */
167
+ truncated: boolean;
168
+ /** Which limit: the per-pod line limit, or the server's byte budget. */
169
+ truncatedBy: "tail" | "bytes" | null;
170
+ /** The plain explanation, when truncated. */
171
+ truncatedReason: string | null;
172
+ /**
173
+ * Every line this pod holds in the window came back. With no window (read
174
+ * from the start), its first line is the start of its log.
175
+ */
176
+ complete: boolean;
177
+ }
178
+ /** The window asked for against the window delivered. */
179
+ export interface LogCoverage {
180
+ /** Start of the window asked for, ISO. Null when reading each pod from its start. */
181
+ requestedFrom: string | null;
182
+ /** Earliest and latest timestamps across every line returned. */
183
+ firstTimestamp: string | null;
184
+ lastTimestamp: string | null;
185
+ pods: PodCoverage[];
186
+ truncated: boolean;
187
+ truncatedReasons: string[];
188
+ }
189
+ /** A span of milliseconds as `29d 23h`, `2h 5m`, `35m`, `40s`. */
190
+ export declare function formatSpan(ms: number): string;
191
+ /**
192
+ * Compare what a read covered with what it asked for.
193
+ *
194
+ * The server's `truncated` describes only its byte budgets and pod ceiling, so
195
+ * a pod that filled the line limit came back marked complete however much of
196
+ * the window it left unread. The line limit is the cut that matters most, and
197
+ * it is detected here: a pod that returned as many lines as the limit, whose
198
+ * earliest line is later than the start of the window, was cut by it.
199
+ *
200
+ * Filling the limit is the half that separates a cut from a young pod. A pod
201
+ * that started an hour ago also has no line older than an hour; it returned
202
+ * fewer lines than the limit, so what came back is its whole log, and nothing
203
+ * was cut.
204
+ */
205
+ export declare function assessCoverage(opts: {
206
+ res: RuntimeLogsResponse;
207
+ lines: ParsedLogLine[];
208
+ /** The window asked for. Null reads each pod from its start. */
209
+ sinceSeconds: number | null;
210
+ tail: TailLimit;
211
+ now: number;
212
+ }): LogCoverage;
213
+ /**
214
+ * Resolve the public origin a project is served at — or `--host`, when given.
215
+ *
216
+ * Shared with `rebase cloud cron`, which reads the runtime at the same address
217
+ * `debug health` probes.
218
+ */
219
+ export declare function resolveOrigin(rawArgs: string[], client: CloudClient, url: string, projectId: string): Promise<string>;
220
+ /** What `debug logs`, `errors` and `boot` parse. Their help pairs against this. */
221
+ export declare const LOG_VIEW_FLAGS: {
222
+ readonly "--since": StringConstructor;
223
+ readonly "--tail": NumberConstructor;
224
+ readonly "--previous": BooleanConstructor;
225
+ };
226
+ /** What `debug requests` parses. */
227
+ export declare const REQUESTS_FLAGS: {
228
+ readonly "--since": StringConstructor;
229
+ readonly "--tail": NumberConstructor;
230
+ };
231
+ /** What `debug health` parses. */
232
+ export declare const HEALTH_FLAGS: {
233
+ readonly "--collection": StringConstructor;
234
+ readonly "--function": StringConstructor;
235
+ readonly "--host": StringConstructor;
236
+ };
237
+ /**
238
+ * Whether a boot read reached each pod's start, which is where its startup
239
+ * lines are. A pod whose read was cut has not been looked at there, so finding
240
+ * no startup lines in it means nothing — and a line from later in its life
241
+ * that happens to mention `storage` is not its startup.
242
+ *
243
+ * Under `--since` a pod is never counted as reached: a complete read of the
244
+ * window starts at the pod's first line only if the pod started inside it, and
245
+ * nothing in the answer says whether it did.
246
+ */
247
+ export declare function bootReach(pods: PodCoverage[], sinceSeconds: number | null): {
248
+ reachedStart: boolean;
249
+ unreached: string[];
250
+ };
117
251
  export declare function debugCommand(action: string | undefined, rawArgs: string[]): Promise<void>;
118
252
  export declare function printDebugHelp(): void;
@@ -1,19 +1,96 @@
1
1
  import { type HelpAction } from "./context.js";
2
+ /**
3
+ * Every flag in the `rebase cloud` family that takes a value, and the short
4
+ * spellings of them — the globals aside, which `GLOBAL_CLOUD_FLAGS` declares.
5
+ *
6
+ * {@link positionals} needs them for one reason: `arg` only consumes a flag's
7
+ * value when the flag is declared, and an undeclared one leaves its value
8
+ * behind as a bare word in the action's position. `rebase cloud deployments
9
+ * --limit 5` dispatched to an action called "5", `rebase cloud debug --host
10
+ * staging.example.com` to one called "staging.example.com", and `rebase cloud
11
+ * projects --name shop create` to one called "shop" — each refused as an unknown
12
+ * command, for a line the command's own help offers.
13
+ *
14
+ * Every value is `String` whatever the command reads it as: only consumption
15
+ * matters here, and the command parses the value itself. One list for the whole
16
+ * family works because no flag takes a value in one command and none in
17
+ * another; `value-flags.test.ts` holds that, and holds this list to the specs
18
+ * the commands declare in both directions, so a new value flag fails a test
19
+ * until it is added here.
20
+ */
21
+ export declare const CLOUD_VALUE_FLAGS: {
22
+ readonly "--access-key-id": StringConstructor;
23
+ readonly "--autoscale-cpu-target": StringConstructor;
24
+ readonly "--autoscale-max": StringConstructor;
25
+ readonly "--backup-access-key-id": StringConstructor;
26
+ readonly "--backup-bucket": StringConstructor;
27
+ readonly "--backup-endpoint": StringConstructor;
28
+ readonly "--backup-secret-access-key": StringConstructor;
29
+ readonly "--base-domain": StringConstructor;
30
+ readonly "--branch": StringConstructor;
31
+ readonly "--bucket": StringConstructor;
32
+ readonly "--bundle-dir": StringConstructor;
33
+ readonly "--can": StringConstructor;
34
+ readonly "--collection": StringConstructor;
35
+ readonly "--connection-string": StringConstructor;
36
+ readonly "--cpu": StringConstructor;
37
+ readonly "--db": StringConstructor;
38
+ readonly "--db-cpu": StringConstructor;
39
+ readonly "--db-instances": StringConstructor;
40
+ readonly "--db-memory": StringConstructor;
41
+ readonly "--email": StringConstructor;
42
+ readonly "--endpoint": StringConstructor;
43
+ readonly "--events": StringConstructor;
44
+ readonly "--expires-in": StringConstructor;
45
+ readonly "--function": StringConstructor;
46
+ readonly "--host": StringConstructor;
47
+ readonly "--ingress-address": StringConstructor;
48
+ readonly "--kubeconfig": StringConstructor;
49
+ readonly "--limit": StringConstructor;
50
+ readonly "--memory": StringConstructor;
51
+ readonly "--message": StringConstructor;
52
+ readonly "--name": StringConstructor;
53
+ readonly "--org": StringConstructor;
54
+ readonly "--output": StringConstructor;
55
+ readonly "--password": StringConstructor;
56
+ readonly "--platform-rebuilds": StringConstructor;
57
+ readonly "--port": StringConstructor;
58
+ readonly "--provider": StringConstructor;
59
+ readonly "--region": StringConstructor;
60
+ readonly "--replicas": StringConstructor;
61
+ readonly "--repo": StringConstructor;
62
+ readonly "--scale-to-zero": StringConstructor;
63
+ readonly "--secret-access-key": StringConstructor;
64
+ readonly "--since": StringConstructor;
65
+ readonly "--slug": StringConstructor;
66
+ readonly "--source": StringConstructor;
67
+ readonly "--spot": StringConstructor;
68
+ readonly "--storage": StringConstructor;
69
+ readonly "--subdomain": StringConstructor;
70
+ readonly "--table": StringConstructor;
71
+ readonly "--tail": StringConstructor;
72
+ readonly "--target": StringConstructor;
73
+ readonly "--timeout": StringConstructor;
74
+ readonly "--type": StringConstructor;
75
+ readonly "--out": "--output";
76
+ readonly "-e": "--email";
77
+ readonly "-m": "--message";
78
+ readonly "-n": "--name";
79
+ };
2
80
  /**
3
81
  * Positional tokens after `rebase cloud` (group, action, …).
4
82
  *
5
- * Two things stop a flag being mistaken for the group. `GLOBAL_CLOUD_FLAGS` is
6
- * declared so `arg` *consumes* the flags that may precede it — critically
7
- * together with their values, which is the half that filtering cannot do. The
8
- * leading-`-` skip then covers a flag nobody declared, so an unrecognised
9
- * boolean shifts nothing.
10
- *
11
- * Only leading tokens are skipped: past the group and action, an undeclared
12
- * flag and its value are somebody else's positionals and none of our business.
13
- * A flag this file has never heard of, that takes a value, placed before the
14
- * group, is the one shape still unresolvable here — there is no way to know
15
- * whether the token after it is its value or the group, and guessing either way
16
- * is worse than the handler reporting an unknown group.
83
+ * Two things stop a flag being mistaken for the group or the action.
84
+ * `GLOBAL_CLOUD_FLAGS` and {@link CLOUD_VALUE_FLAGS} are declared so `arg`
85
+ * *consumes* every flag of the family that takes a value — critically together
86
+ * with its value, which is the half that filtering cannot do. The leading-`-`
87
+ * skip then covers a flag nobody declared, so an unrecognised boolean shifts
88
+ * nothing.
89
+ *
90
+ * A flag this family has never heard of, that takes a value, is the one shape
91
+ * still unresolvable here — there is no way to know whether the token after it
92
+ * is its value or the action. The command's own strict parse refuses that flag
93
+ * anyway, so the only cost is which refusal the caller reads.
17
94
  *
18
95
  * Exported so its tests can drive the real thing. The dispatch test used to
19
96
  * re-implement it locally as `slice(3).filter(a => !a.startsWith("-"))` — which
@@ -0,0 +1,76 @@
1
+ /**
2
+ * What a Rebase Cloud token may do, named the way a person asks for it.
3
+ *
4
+ * A token is a personal API key on the control plane: it acts as the account
5
+ * that created it, and holds only the scopes it was given. Nobody should have
6
+ * to know that `rebase cloud deploy` reads the `deployments` collection, uploads
7
+ * through the `deploy` function and needs `project:deploy` on one project — so
8
+ * `rebase cloud tokens create --can deploy` and the console's token screen both
9
+ * ask for a capability, and this module turns capabilities into scopes.
10
+ *
11
+ * One map, read by the CLI and by the console. Each capability covers exactly
12
+ * the control-plane calls its commands make, traced from the commands
13
+ * themselves and held there by `token-capabilities.test.ts`, which runs them
14
+ * against a stand-in control plane that refuses everything a token does not
15
+ * hold:
16
+ *
17
+ * - `deploy` — `rebase cloud deploy` (bundle and source paths, uploads, the
18
+ * build follow) and `rebase cloud deployments`.
19
+ * - `logs` — `rebase cloud logs` (build, `--follow`, `--runtime`),
20
+ * `rebase cloud metrics` and `rebase cloud cron` — whose
21
+ * `runtime-token` call is how a token reads the app's own
22
+ * cron history.
23
+ * - `env` — `rebase cloud env list|set|unset|reveal|pull`.
24
+ * - `database` — `rebase cloud db list|info|connect`.
25
+ * - `backups` — `rebase cloud db backup list|create|status|download` and
26
+ * `db pitr status`. Restoring takes `project:restore`, which no
27
+ * capability grants: putting old data over a live database is
28
+ * for a signed-in person.
29
+ *
30
+ * Every project-level scope is narrowed to the one project the token is for
31
+ * (`project:deploy:<projectId>`). The data and function scopes cannot be: they
32
+ * name a collection or a function, not a row, and the control plane's
33
+ * row-level security keeps the token to what its owner can see.
34
+ *
35
+ * Deliberately free of imports, so the control plane's console can read the
36
+ * same file.
37
+ *
38
+ * @module
39
+ */
40
+ /** A capability a token can be given. */
41
+ export type TokenCapability = "deploy" | "logs" | "env" | "database" | "backups";
42
+ /** Every capability, in the order they are offered. */
43
+ export declare const TOKEN_CAPABILITY_NAMES: readonly TokenCapability[];
44
+ /**
45
+ * Scopes every token holds, whatever it was created for: resolving a project
46
+ * by its slug, reading the deployment a command follows, the organization a
47
+ * project belongs to, and the control plane's public description of itself.
48
+ */
49
+ export declare const ALWAYS_SCOPES: string[];
50
+ /** Each capability: what it lets a token do, and the scopes that does on one project. */
51
+ export declare const TOKEN_CAPABILITIES: Record<TokenCapability, {
52
+ label: string;
53
+ scopes: (projectId: string) => string[];
54
+ }>;
55
+ /** Whether a word names a capability. */
56
+ export declare function isTokenCapability(value: string): value is TokenCapability;
57
+ /**
58
+ * The scopes a token for `capabilities` on one project holds: {@link ALWAYS_SCOPES}
59
+ * first, then each capability's, each scope once.
60
+ *
61
+ * Throws on a project id a scope cannot carry — empty, or with whitespace — and
62
+ * on an unknown capability, both of which are a caller's mistake rather than
63
+ * something to mint a token from.
64
+ */
65
+ export declare function scopesForCapabilities(projectId: string, capabilities: readonly TokenCapability[]): string[];
66
+ /**
67
+ * Read a token's scopes back as capabilities: the projects its project scopes
68
+ * name, and, for each, the capabilities it holds every scope of.
69
+ *
70
+ * For showing a token — `rebase cloud tokens list`, `rebase cloud whoami` — so
71
+ * a list of fifteen scope strings reads as "deploy, logs on <project>".
72
+ */
73
+ export declare function capabilitiesInScopes(scopes: readonly string[]): Array<{
74
+ projectId: string;
75
+ capabilities: TokenCapability[];
76
+ }>;
@@ -0,0 +1,23 @@
1
+ import { type TokenCapability } from "./token-capabilities.js";
2
+ /** Every action the group dispatches. */
3
+ export declare const TOKENS_ACTIONS: readonly ["list", "create", "revoke"];
4
+ /** What `rebase cloud tokens create` parses, beside the global flags (`--project` among them). */
5
+ export declare const CREATE_TOKEN_FLAGS: {
6
+ "--can": [StringConstructor];
7
+ "--name": StringConstructor;
8
+ "--expires-in": StringConstructor;
9
+ };
10
+ export declare function tokensCommand(action: string | undefined, rawArgs: string[]): Promise<void>;
11
+ /**
12
+ * The capabilities `--can` names, comma-separated or repeated, each once.
13
+ *
14
+ * Exported so its tests can drive it without a session.
15
+ */
16
+ export declare function parseCapabilities(values: readonly string[] | undefined): TokenCapability[];
17
+ /**
18
+ * `--expires-in <days>` as an ISO timestamp, or null for a token that does not
19
+ * expire.
20
+ *
21
+ * Exported so its tests can drive it without a session.
22
+ */
23
+ export declare function resolveTokenExpiry(value: string | undefined, now?: Date): string | null;
@@ -0,0 +1,12 @@
1
+ export declare const CONSOLE_FLAGS: {
2
+ readonly "--eval": StringConstructor;
3
+ readonly "-e": "--eval";
4
+ readonly "--collections": StringConstructor;
5
+ readonly "-c": "--collections";
6
+ readonly "--database-url": StringConstructor;
7
+ readonly "--docker": BooleanConstructor;
8
+ };
9
+ /** Where the REPL keeps its history: the project's own `.rebase/`, which the scaffold ignores. */
10
+ export declare function consoleHistoryPath(projectRoot: string): string;
11
+ export declare function printConsoleHelp(): void;
12
+ export declare function consoleCommand(rawArgs: string[]): Promise<void>;
@@ -1,5 +1,6 @@
1
1
  import { type PreparedDatabase } from "../dev-db/prepare.js";
2
2
  import { type DevDatabase } from "../dev-db/resolve.js";
3
+ import type { AtlasDevDatabase } from "../dev-db/atlas-dev-database.js";
3
4
  /**
4
5
  * The connection string a prepared database actually answers on.
5
6
  *
@@ -17,6 +18,20 @@ import { type DevDatabase } from "../dev-db/resolve.js";
17
18
  * it open.
18
19
  */
19
20
  export declare function databaseUrlOf(prepared: Pick<PreparedDatabase, "env" | "database">, envFile: Record<string, string>): string | undefined;
21
+ /**
22
+ * The flags whose value is a local path, on every line the CLI relays.
23
+ *
24
+ * All three spellings of the destination, because the driver accepts all
25
+ * three: `backup-cli.ts` maps `--output` and `-o` onto `--out`, and `rebase db
26
+ * backup --help` advertises `--output` as an alias. Only `--out` and `-o` were
27
+ * absolutised once, so the one spelling the help page names was the one that
28
+ * landed in `backend/` — and the success line still echoed the path as typed.
29
+ *
30
+ * And `--collections`, which was not absolutised at all: from the project root,
31
+ * `rebase schema generate --collections ./config/collections` was "not found",
32
+ * while the same spelling worked for `generate-sdk`. See `utils/path-flags.ts`.
33
+ */
34
+ export declare const LOCAL_PATH_FLAGS: readonly string[];
20
35
  /**
21
36
  * Rewrite local path arguments so they mean what the user typed.
22
37
  *
@@ -31,7 +46,7 @@ export declare function databaseUrlOf(prepared: Pick<PreparedDatabase, "env" | "
31
46
  * Absolutising here rather than inside the plugin keeps the fix where the cwd
32
47
  * is actually changed, and leaves the plugin usable on its own terms.
33
48
  */
34
- export declare function absolutizeLocalPathArgs(args: string[], cwd: string): string[];
49
+ export declare function absolutizeLocalPathArgs(args: string[], cwd: string, pathFlags?: readonly string[]): string[];
35
50
  /**
36
51
  * A managed-database refusal, raised so the caller decides what it costs.
37
52
  *
@@ -55,30 +70,35 @@ export declare class ManagedDatabaseRefusal extends Error {
55
70
  /** Print a refusal exactly as the guards used to print it themselves. */
56
71
  export declare function printManagedDatabaseRefusal(refusal: ManagedDatabaseRefusal): void;
57
72
  /**
58
- * Stop an Atlas-backed subcommand before it fails inside Atlas on the managed
73
+ * The variable the driver reads for Atlas's dev database
74
+ * (`ATLAS_DEV_URL_ENV` in `@rebasepro/server-postgres`, which this CLI does not
75
+ * depend on).
76
+ */
77
+ export declare const ATLAS_DEV_URL_ENV = "REBASE_ATLAS_DEV_URL";
78
+ /**
79
+ * The empty database an Atlas-backed subcommand plans against, on the managed
59
80
  * development database.
60
81
  *
61
- * **PGlite serves exactly one database.** `CREATE DATABASE "postgres_dev_diff"`
62
- * against it reports success and creates nothing, so Atlas connects its dev-url
63
- * straight back to the database it is meant to be comparing against, finds the
64
- * project's own tables there, and stops with
65
- * `connected database is not clean: found schema "public"`. Verified on a
66
- * completely fresh scaffold, so this is not a leftover-state problem that a
67
- * reset would fix — the model does not fit the engine.
68
- *
69
- * Before this guard the failure was worse than unhelpful. The first thing the
70
- * reader hit was `pq: SSL is not enabled on the server`, whose remedy box said
71
- * to append `sslmode=disable` to `DATABASE_URL` — a variable `rebase init`
72
- * deliberately leaves unset, which is the very reason the managed database was
73
- * in use. Two errors deep, about a variable that does not exist, for a command
74
- * the quickstart told them to run.
75
- *
76
- * There is nothing to fix by trying harder here: Atlas's other dev-url option
77
- * is `docker://`, and needing Docker is precisely what the managed database
78
- * exists to avoid. So this says what the managed database can and cannot do,
79
- * and names the two things that work.
82
+ * **PGlite serves exactly one database.** Atlas computes a change by replaying
83
+ * the desired schema into a second, empty one; on a real server the driver
84
+ * makes it as `<db>_dev_diff`, but `CREATE DATABASE` against PGlite reports
85
+ * success and creates nothing, so Atlas connected straight back to the
86
+ * database it was comparing and stopped with `connected database is not
87
+ * clean`. These commands were refused outright on the managed database — and
88
+ * with them every way to drop, rename or narrow a column there, since boot
89
+ * only adds.
90
+ *
91
+ * So a throwaway second PGlite is started for the command instead — in
92
+ * memory, in this process, gone when the command ends — and handed to the
93
+ * driver as `REBASE_ATLAS_DEV_URL`. Nothing else about the push changes: the
94
+ * destructive gate is the driver's, and holds as it does everywhere.
95
+ *
96
+ * `undefined` when none is needed: another database kind (the driver makes its
97
+ * own), a subcommand that is not Atlas's, or a `REBASE_ATLAS_DEV_URL` the
98
+ * developer set. When one cannot be started — PGlite is an optional
99
+ * dependency — the old refusal stands, with the reason.
80
100
  */
81
- export declare function refuseAtlasOnManagedDatabase(rawArgs: string[], kind: string): void;
101
+ export declare function atlasDevDatabaseFor(rawArgs: string[], kind: string, env: Readonly<Record<string, string | undefined>>, start?: () => Promise<AtlasDevDatabase>): Promise<AtlasDevDatabase | undefined>;
82
102
  /**
83
103
  * Stop `rebase db branch` before it reports a branch that is not one.
84
104
  *
@@ -107,11 +127,25 @@ export declare function refuseAtlasOnManagedDatabase(rawArgs: string[], kind: st
107
127
  * an invitation to do the broken thing, and `info` would confirm a size for a
108
128
  * database that was never made.
109
129
  *
110
- * `refuseAtlasOnManagedDatabase` above is the same shape for a different
111
- * reason, and its comment named `branch` as one of the subcommands it does not
112
- * cover. It does now.
130
+ * Push, generate and migrate had the same problem — Atlas's scratch database
131
+ * is a second database too — and get a throwaway PGlite of their own instead
132
+ * (`atlasDevDatabaseFor` above). A branch cannot: it is meant to keep the
133
+ * project's data, and a throwaway instance has none.
113
134
  */
114
135
  export declare function refuseBranchOnManagedDatabase(rawArgs: string[], kind: string): void;
136
+ /**
137
+ * Resolve the active driver's CLI and the environment it should run in.
138
+ *
139
+ * Shared by the two runners below. Deliberately does NOT resolve a database:
140
+ * `schema generate` reads collection files and writes one file, and starting a
141
+ * database to run it would be a side effect nobody asked for.
142
+ */
143
+ export declare function resolveDriverCli(): Promise<{
144
+ projectRoot: string;
145
+ backendDir: string;
146
+ pluginCli: string;
147
+ env: Record<string, string>;
148
+ }>;
115
149
  /**
116
150
  * The one place this CLI spawns the driver's own CLI.
117
151
  *
@@ -133,6 +167,12 @@ export declare function refuseBranchOnManagedDatabase(rawArgs: string[], kind: s
133
167
  * tsx whenever it is installed — a devDependency of every scaffold, for exactly
134
168
  * this reason. Without it a `.ts` entry cannot run at all; a built entry still
135
169
  * runs, and the subcommands that never touch the project's TypeScript still work.
170
+ *
171
+ * tsx's loader in one Node (`node --import`) rather than the `tsx` binary,
172
+ * which is a shell shim and a relay Node in front of the same loader: one Node
173
+ * start instead of two, ~50–100 ms on each of the driver runs every `rebase
174
+ * dev` start and every collection save makes. The binary stays the fallback for
175
+ * a tsx whose loader does not resolve as a package — a global install.
136
176
  */
137
177
  export declare function spawnDriverCli(resolved: {
138
178
  projectRoot: string;
@@ -157,6 +197,20 @@ export declare function runDriverDbCommand(rawArgs: string[], options?: {
157
197
  quiet?: boolean;
158
198
  }): Promise<void>;
159
199
  export declare function dbCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void>;
200
+ /**
201
+ * Start the compose database a `db … --docker` was asked to talk to.
202
+ *
203
+ * `--docker` resolved the compose URL and stopped there, so every `db`
204
+ * subcommand carrying it reached a container nobody had started —
205
+ * `ECONNREFUSED 127.0.0.1:5436`, two lines, no diagnosis — including the
206
+ * commands the managed-database refusals send readers to `--docker` for.
207
+ *
208
+ * `rebase dev --docker`'s preflight, called with the compose URL and nothing
209
+ * to push: this is not a schema step, and `rebase db push --docker` is the
210
+ * push. A failure here is reported and not fatal — the command runs and its
211
+ * own connection error follows, which is the same contract `dev` keeps.
212
+ */
213
+ export declare function ensureDockerDatabase(projectRoot: string, rawArgs: readonly string[]): Promise<void>;
160
214
  /** Every subcommand the family dispatches — the help table's keys. */
161
215
  export declare const DB_SUBCOMMANDS: string[];
162
216
  /**