@rebasepro/types 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 (35) hide show
  1. package/dist/call_context.d.ts +8 -4
  2. package/dist/controllers/client.d.ts +113 -24
  3. package/dist/controllers/collection_registry.d.ts +17 -0
  4. package/dist/controllers/data.d.ts +570 -122
  5. package/dist/controllers/data_driver.d.ts +85 -1
  6. package/dist/controllers/index.d.ts +1 -0
  7. package/dist/controllers/storage-references.d.ts +114 -0
  8. package/dist/controllers/storage.d.ts +73 -13
  9. package/dist/errors.d.ts +15 -1
  10. package/dist/index.es.js +1228 -43
  11. package/dist/index.es.js.map +1 -1
  12. package/dist/types/admin_block.d.ts +1 -1
  13. package/dist/types/api_keys.d.ts +68 -36
  14. package/dist/types/auth_adapter.d.ts +97 -2
  15. package/dist/types/backend.d.ts +356 -9
  16. package/dist/types/backup.d.ts +102 -0
  17. package/dist/types/collection_patch.d.ts +74 -0
  18. package/dist/types/collections.d.ts +23 -0
  19. package/dist/types/cron.d.ts +58 -7
  20. package/dist/types/database_adapter.d.ts +34 -8
  21. package/dist/types/entities.d.ts +11 -0
  22. package/dist/types/history.d.ts +15 -1
  23. package/dist/types/index.d.ts +3 -0
  24. package/dist/types/project_manifest.d.ts +73 -1
  25. package/dist/types/properties.d.ts +39 -2
  26. package/dist/types/register.d.ts +43 -0
  27. package/dist/types/relations.d.ts +37 -1
  28. package/dist/types/resource_kinds.d.ts +20 -10
  29. package/dist/types/schema_editing.d.ts +39 -13
  30. package/dist/types/scopes.d.ts +272 -0
  31. package/dist/types/storage_authorize.d.ts +10 -1
  32. package/dist/types/storage_source.d.ts +2 -6
  33. package/dist/types/websockets.d.ts +32 -1
  34. package/dist/users/user.d.ts +7 -0
  35. package/package.json +1 -1
@@ -3,6 +3,7 @@ import type { StorageSource } from "./controllers/storage.js";
3
3
  import type { RebaseClient } from "./controllers/client.js";
4
4
  import type { RebaseSdkData } from "./controllers/data.js";
5
5
  import type { User } from "./users/index.js";
6
+ import type { RegisteredDatabase } from "./types/register.js";
6
7
  /**
7
8
  * The client a collection callback is handed as `context.client`: the Rebase
8
9
  * client **without `data`**.
@@ -21,7 +22,7 @@ import type { User } from "./users/index.js";
21
22
  *
22
23
  * @group Hooks and utilities
23
24
  */
24
- export type RebaseCallbackClient<DB = unknown> = Omit<RebaseClient<DB>, "data">;
25
+ export type RebaseCallbackClient<DB = RegisteredDatabase> = Omit<RebaseClient<DB>, "data">;
25
26
  /**
26
27
  * Context that is provided to entity callbacks (hooks).
27
28
  * It contains only the dependencies that are available in both the frontend and the backend.
@@ -54,7 +55,7 @@ export type RebaseCallbackClient<DB = unknown> = Omit<RebaseClient<DB>, "data">;
54
55
  *
55
56
  * @group Hooks and utilities
56
57
  */
57
- export type RebaseCallContext<USER extends User = User> = {
58
+ export type RebaseCallContext<USER extends User = User, DB = RegisteredDatabase> = {
58
59
  /**
59
60
  * The Rebase client instance.
60
61
  * Available in all entity callbacks (beforeSave, afterSave, afterRead,
@@ -81,7 +82,7 @@ export type RebaseCallContext<USER extends User = User> = {
81
82
  * const { client } = props.context;
82
83
  * const result = await client.functions.invoke('extract-job', { url });
83
84
  */
84
- client: RebaseCallbackClient;
85
+ client: RebaseCallbackClient<DB>;
85
86
  /**
86
87
  * Unified data access — `context.data.products.create(...)`.
87
88
  * Access any collection as a dynamic property.
@@ -119,8 +120,11 @@ export type RebaseCallContext<USER extends User = User> = {
119
120
  * frontend SDK client — so `context.data` in a backend callback and
120
121
  * `client.data` in the frontend are accessed the same way (`row.title`,
121
122
  * never `row.values.title`). Shape only: privilege differs as above.
123
+ *
124
+ * Untyped until the project registers its generated `Database` on
125
+ * {@link Register}; typed from it from then on.
122
126
  */
123
- data: RebaseSdkData;
127
+ data: RebaseSdkData<DB>;
124
128
  /**
125
129
  * The driver executing the operation this callback is attached to.
126
130
  *
@@ -3,10 +3,12 @@ import type { ResourceRef } from "../types/resources.js";
3
3
  import type { RebaseSdkData } from "./data.js";
4
4
  import type { EmailService } from "./email.js";
5
5
  import type { StorageSource } from "./storage.js";
6
- import type { CronJobStatus, CronJobLogEntry } from "../types/cron.js";
7
- import type { BackupInfo, BackupDestinationKind } from "../types/backup.js";
8
- import type { ApiKeysAPI } from "../types/api_keys.js";
6
+ import type { CronJobStatus, CronJobLogEntry, CronJobListing, CronJobStarted } from "../types/cron.js";
7
+ import type { BackupDownloadLink, BackupListing } from "../types/backup.js";
8
+ import type { ApiKeysAPI, PersonalKeysAPI } from "../types/api_keys.js";
9
+ import type { RoleSummary } from "../types/scopes.js";
9
10
  import type { StorageSourceDefinition } from "../types/storage_source.js";
11
+ import type { RegisteredDatabase } from "../types/register.js";
10
12
  /**
11
13
  * Event type for authentication state changes
12
14
  */
@@ -19,6 +21,10 @@ export type AuthChangeEvent = "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "
19
21
  */
20
22
  export interface RebaseSession {
21
23
  accessToken: string;
24
+ /**
25
+ * `""` under `authFlowMode: "cookie"`: the refresh token is in an HttpOnly
26
+ * cookie that no script can read, so the session does not hold it.
27
+ */
22
28
  refreshToken: string;
23
29
  expiresAt: number;
24
30
  user: User;
@@ -134,10 +140,27 @@ export interface AdminUser {
134
140
  */
135
141
  providerId: string;
136
142
  roles: string[];
143
+ /**
144
+ * Switched off by an administrator (`PUT /admin/users/:uid { disabled }`):
145
+ * it signs in nowhere and the tokens it holds are refused.
146
+ */
147
+ disabled?: boolean;
137
148
  metadata?: Record<string, any>;
138
149
  createdAt: string;
139
150
  updatedAt: string;
140
151
  }
152
+ /**
153
+ * A user as the user picker sees one (`GET /admin/users/pick`): who the person
154
+ * is, and nothing about their account — no roles, no status, no timestamps.
155
+ *
156
+ * @group Admin
157
+ */
158
+ export interface PickedUser {
159
+ uid: string;
160
+ email: string;
161
+ displayName: string | null;
162
+ photoURL: string | null;
163
+ }
141
164
  /**
142
165
  * Client-side Admin API interface.
143
166
  * Provides user management operations.
@@ -170,6 +193,9 @@ export interface AdminAPI {
170
193
  metadata?: Record<string, any>;
171
194
  }): Promise<{
172
195
  user: AdminUser;
196
+ temporaryPassword?: string;
197
+ invitationSent?: boolean;
198
+ emailDeliveryFailed?: boolean;
173
199
  }>;
174
200
  updateUser(uid: string, data: {
175
201
  email?: string;
@@ -191,11 +217,9 @@ export interface AdminAPI {
191
217
  invitationSent?: boolean;
192
218
  emailDeliveryFailed?: boolean;
193
219
  }>;
220
+ /** The built-in `admin` role and the app's declared roles, with the scopes each holds. */
194
221
  listRoles(): Promise<{
195
- roles: Array<{
196
- id: string;
197
- name: string;
198
- }>;
222
+ roles: RoleSummary[];
199
223
  }>;
200
224
  bootstrap(): Promise<{
201
225
  success: boolean;
@@ -211,16 +235,30 @@ export interface AdminAPI {
211
235
  * @group Cron
212
236
  */
213
237
  export interface CronAPI {
214
- listJobs(): Promise<{
215
- jobs: CronJobStatus[];
216
- }>;
238
+ /** The registered jobs, and the cron files and jobs that did not become one. */
239
+ listJobs(): Promise<CronJobListing>;
217
240
  getJob(jobId: string): Promise<{
218
241
  job: CronJobStatus;
219
242
  }>;
220
- triggerJob(jobId: string): Promise<{
243
+ /**
244
+ * Run a job now and wait for it to finish. A proxy in front of the server
245
+ * may cut a long run's answer short while the run carries on; pass
246
+ * `{ async: true }` for those.
247
+ */
248
+ triggerJob(jobId: string, options?: {
249
+ async?: false;
250
+ }): Promise<{
221
251
  log: CronJobLogEntry;
222
252
  job: CronJobStatus;
223
253
  }>;
254
+ /**
255
+ * Start a job now and answer as soon as it has started. Read its outcome
256
+ * from {@link CronAPI.getJobLogs}: the entry with `manual: true` and the
257
+ * returned `startedAt`.
258
+ */
259
+ triggerJob(jobId: string, options: {
260
+ async: true;
261
+ }): Promise<CronJobStarted>;
224
262
  getJobLogs(jobId: string, options?: {
225
263
  limit?: number;
226
264
  }): Promise<{
@@ -235,14 +273,25 @@ export interface CronAPI {
235
273
  * @group Backups
236
274
  */
237
275
  export interface BackupsAPI {
238
- /** List available backups at the configured destination, newest first. */
239
- list(): Promise<{
240
- backups: BackupInfo[];
241
- destinationKind: BackupDestinationKind;
242
- configured: boolean;
276
+ /**
277
+ * List available backups at the configured destination, newest first, and
278
+ * the scheduled backup job's last run.
279
+ */
280
+ list(): Promise<BackupListing>;
281
+ /**
282
+ * Save a backup in the browser: the browser is sent to a
283
+ * {@link downloadUrl} link and streams the dump to disk; the page never
284
+ * holds it. Browser only — elsewhere use {@link stream} or {@link downloadUrl}.
285
+ */
286
+ download(key: string): Promise<void>;
287
+ /** A link to one backup's bytes, good for 60 seconds, that needs no `Authorization` header. */
288
+ downloadUrl(key: string): Promise<BackupDownloadLink>;
289
+ /** A backup's bytes as a stream, read as consumed — to write one to a file outside a browser. */
290
+ stream(key: string): Promise<{
291
+ stream: ReadableStream<Uint8Array>;
292
+ size?: number;
293
+ name: string;
243
294
  }>;
244
- /** Fetch a backup's bytes for download (authenticated). */
245
- download(key: string): Promise<Blob>;
246
295
  }
247
296
  /**
248
297
  * Options for invoking a custom backend function.
@@ -255,6 +304,15 @@ export interface FunctionInvokeOptions {
255
304
  path?: string;
256
305
  /** Extra headers merged into the request. */
257
306
  headers?: Record<string, string>;
307
+ /**
308
+ * How to read the function's answer — defaults to `"json"`.
309
+ *
310
+ * A function is a Hono route, so it may answer `c.text(csv)` or
311
+ * `c.body(pdf)`: ask for `"text"` (a string), `"blob"` (a `Blob`) or
312
+ * `"response"` (the `Response` itself, body unread, for streaming or
313
+ * headers). An error status is thrown as a `RebaseApiError` in every mode.
314
+ */
315
+ responseType?: "json" | "text" | "blob" | "response";
258
316
  }
259
317
  /**
260
318
  * Client interface for invoking custom backend functions.
@@ -280,6 +338,25 @@ export interface FunctionsAPI {
280
338
  export type HistoryConfig = boolean | {
281
339
  retention?: number;
282
340
  };
341
+ /**
342
+ * Where the realtime connection is.
343
+ *
344
+ * - `idle` — no socket, and none wanted yet (the connection is lazy), or the
345
+ * last one was dropped by a sign-out.
346
+ * - `connecting` — dialling, with no outage in progress.
347
+ * - `connected` — the socket is open.
348
+ * - `reconnecting` — the socket dropped and the client is redialling. A blip,
349
+ * so far: nothing has been reported.
350
+ * - `disconnected` — the outage has outlasted the blip budget (about 15 s).
351
+ * Every live subscription and joined channel has been told
352
+ * `CONNECTION_LOST` once, and the client keeps redialling — every 30 s at
353
+ * most — for as long as any exists. When the socket is back each is
354
+ * re-subscribed, and its next update carries what changed meanwhile.
355
+ * - `closed` — `client.close()`. Final.
356
+ *
357
+ * @group Realtime
358
+ */
359
+ export type RealtimeConnectionState = "idle" | "connecting" | "connected" | "reconnecting" | "disconnected" | "closed";
283
360
  /**
284
361
  * Minimal WebSocket client contract exposed on {@link RebaseClient}.
285
362
  *
@@ -291,10 +368,19 @@ export interface RebaseWebSocket {
291
368
  disconnect(): void;
292
369
  /** Send an authentication token to the server. */
293
370
  authenticate(token: string): Promise<void>;
294
- /** Set a function that lazily resolves the auth token for auto-authentication. */
371
+ /**
372
+ * Set a function that lazily resolves the auth token for auto-authentication.
373
+ *
374
+ * @deprecated Use `client.setAuthTokenGetter()` instead, which authenticates
375
+ * HTTP requests and this socket together. Will be removed in a future release.
376
+ */
295
377
  setAuthTokenGetter(getter: () => Promise<string | null>): void;
296
378
  /** Listen for connection lifecycle events. */
297
379
  on(event: "connect" | "disconnect" | "reconnect" | "error", cb: (...args: unknown[]) => void): () => void;
380
+ /** Where the connection is. See {@link RealtimeConnectionState}. */
381
+ readonly state: RealtimeConnectionState;
382
+ /** Called on every change of {@link state}. Returns the unsubscribe. */
383
+ onStateChange(listener: (state: RealtimeConnectionState) => void): () => void;
298
384
  }
299
385
  /**
300
386
  * The single, canonical Rebase client interface.
@@ -390,8 +476,10 @@ export interface RebaseClient<DB = unknown> {
390
476
  backups?: BackupsAPI;
391
477
  /** Custom backend functions API */
392
478
  functions?: FunctionsAPI;
393
- /** Service API keys management API */
479
+ /** The project's service keys. Requires `keys:read` / `keys:write`. */
394
480
  apiKeys?: ApiKeysAPI;
481
+ /** The signed-in person's own API keys, when the backend enables `auth.personalKeys`. */
482
+ personalKeys?: PersonalKeysAPI;
395
483
  /** Base HTTP URL of the backend server */
396
484
  baseUrl?: string;
397
485
  /**
@@ -457,7 +545,7 @@ export interface RebaseClient<DB = unknown> {
457
545
  * connection, no policies. For user-scoped queries inside a request handler use
458
546
  * the request-scoped driver (`c.var.driver`) instead — never `dataAsAdmin`.
459
547
  */
460
- export interface RebaseServerClient<DB = unknown> extends Omit<RebaseClient<DB>, "data"> {
548
+ export interface RebaseServerClient<DB = RegisteredDatabase> extends Omit<RebaseClient<DB>, "data"> {
461
549
  /**
462
550
  * Admin-scoped data accessor (RLS is evaluated as the service identity, not
463
551
  * skipped). Always present server-side. See {@link RebaseClient.dataAsAdmin}
@@ -530,10 +618,11 @@ export interface StorageSourceRegistry {
530
618
  */
531
619
  getDefault(): StorageSource;
532
620
  /**
533
- * Get a storage source by key, with fallback to default.
621
+ * Get a storage source by key, or the default one for no key.
534
622
  * @param key - Storage source key, or undefined/null for default
535
- * @returns The StorageSource (falls back to default if key not found)
536
- * @throws Error if neither the specified nor default storage exists
623
+ * @returns The StorageSource registered under `key` (the default for no key)
624
+ * @throws Error if `key` names no registered source — never the default in
625
+ * its place — or no key is given and no default is registered
537
626
  */
538
627
  getOrDefault(key: string | undefined | null): StorageSource;
539
628
  /** Check if a storage source with the given key exists */
@@ -31,6 +31,23 @@ export type CollectionRegistryController<DB = Record<string, unknown>, EC extend
31
31
  * This is strictly for the Visual Editor to manipulate AST code without persisting runtime state.
32
32
  */
33
33
  getRawCollection: (slugOrPath: string) => EC | undefined;
34
+ /**
35
+ * The path a collection's rows are stored under, for the path the admin
36
+ * addresses it by. A Firestore or MongoDB collection may declare a `path`
37
+ * other than its slug — `slug: "fs_diagnosis", path: "diagnosis"` — and
38
+ * `fs_diagnosis/abc/locales` is then stored at `diagnosis/abc/locales`.
39
+ * This is what a reference to one of its records stores. Unchanged for a
40
+ * collection stored under its slug.
41
+ */
42
+ resolveDataPath: (path: string) => string;
43
+ /**
44
+ * The path the admin addresses a collection by, for a path its rows are
45
+ * stored under: the inverse of {@link resolveDataPath}, for a reference
46
+ * read back. `diagnosis` may be both where a Firestore collection is stored
47
+ * and the slug of a Postgres one; `preferredDriver` — the reference's
48
+ * `driver`, or the data source of the record it was read from — decides.
49
+ */
50
+ resolveCollectionPath: (path: string, preferredDriver?: string) => string;
34
51
  /**
35
52
  * Retrieve all the related parent references for a given path
36
53
  * @param path