@rebasepro/types 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.
Files changed (88) hide show
  1. package/README.md +10 -10
  2. package/dist/controllers/auth.d.ts +1 -1
  3. package/dist/controllers/client.d.ts +237 -7
  4. package/dist/controllers/collection_registry.d.ts +3 -3
  5. package/dist/controllers/customization_controller.d.ts +1 -1
  6. package/dist/controllers/data.d.ts +285 -81
  7. package/dist/controllers/data_driver.d.ts +50 -37
  8. package/dist/controllers/index.d.ts +1 -1
  9. package/dist/controllers/local_config_persistence.d.ts +4 -4
  10. package/dist/controllers/navigation.d.ts +2 -2
  11. package/dist/controllers/registry.d.ts +17 -6
  12. package/dist/controllers/{side_entity_controller.d.ts → side_panel_controller.d.ts} +7 -7
  13. package/dist/controllers/storage.d.ts +39 -0
  14. package/dist/errors.d.ts +64 -0
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.es.js +290 -16
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.umd.js +305 -18
  19. package/dist/index.umd.js.map +1 -1
  20. package/dist/rebase_context.d.ts +8 -4
  21. package/dist/types/auth_adapter.d.ts +9 -6
  22. package/dist/types/backend.d.ts +30 -26
  23. package/dist/types/builders.d.ts +2 -2
  24. package/dist/types/collections.d.ts +211 -136
  25. package/dist/types/component_overrides.d.ts +61 -3
  26. package/dist/types/cron.d.ts +10 -1
  27. package/dist/types/data_source.d.ts +18 -5
  28. package/dist/types/database_adapter.d.ts +4 -3
  29. package/dist/types/entities.d.ts +7 -7
  30. package/dist/types/entity_actions.d.ts +7 -7
  31. package/dist/types/entity_callbacks.d.ts +55 -43
  32. package/dist/types/entity_views.d.ts +3 -3
  33. package/dist/types/filter-operators.d.ts +153 -0
  34. package/dist/types/index.d.ts +3 -2
  35. package/dist/types/modify_collections.d.ts +2 -2
  36. package/dist/types/plugins.d.ts +9 -9
  37. package/dist/types/policy.d.ts +191 -0
  38. package/dist/types/properties.d.ts +153 -43
  39. package/dist/types/property_config.d.ts +1 -1
  40. package/dist/types/relations.d.ts +3 -3
  41. package/dist/types/slots.d.ts +14 -14
  42. package/dist/types/storage_source.d.ts +83 -0
  43. package/dist/types/websockets.d.ts +12 -13
  44. package/dist/users/user.d.ts +21 -9
  45. package/package.json +1 -1
  46. package/src/controllers/auth.tsx +1 -1
  47. package/src/controllers/client.ts +275 -7
  48. package/src/controllers/collection_registry.ts +3 -3
  49. package/src/controllers/customization_controller.tsx +1 -1
  50. package/src/controllers/data.ts +309 -97
  51. package/src/controllers/data_driver.ts +49 -40
  52. package/src/controllers/index.ts +1 -1
  53. package/src/controllers/local_config_persistence.tsx +4 -4
  54. package/src/controllers/navigation.ts +2 -2
  55. package/src/controllers/registry.ts +18 -6
  56. package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
  57. package/src/controllers/storage.ts +60 -1
  58. package/src/errors.ts +80 -0
  59. package/src/index.ts +1 -0
  60. package/src/rebase_context.tsx +8 -4
  61. package/src/types/auth_adapter.ts +9 -6
  62. package/src/types/backend.ts +41 -36
  63. package/src/types/builders.ts +2 -2
  64. package/src/types/collections.ts +256 -172
  65. package/src/types/component_overrides.ts +72 -5
  66. package/src/types/cron.ts +10 -1
  67. package/src/types/data_source.ts +29 -7
  68. package/src/types/database_adapter.ts +4 -3
  69. package/src/types/entities.ts +7 -7
  70. package/src/types/entity_actions.tsx +7 -7
  71. package/src/types/entity_callbacks.ts +58 -47
  72. package/src/types/entity_views.tsx +3 -3
  73. package/src/types/filter-operators.ts +240 -0
  74. package/src/types/index.ts +3 -2
  75. package/src/types/modify_collections.tsx +2 -2
  76. package/src/types/plugins.tsx +9 -9
  77. package/src/types/policy.ts +229 -0
  78. package/src/types/properties.ts +164 -44
  79. package/src/types/property_config.tsx +0 -1
  80. package/src/types/relations.ts +3 -3
  81. package/src/types/slots.tsx +14 -14
  82. package/src/types/storage_source.ts +90 -0
  83. package/src/types/websockets.ts +12 -14
  84. package/src/users/user.ts +22 -9
  85. package/dist/types/backend_hooks.d.ts +0 -109
  86. package/dist/types/entity_overrides.d.ts +0 -10
  87. package/src/types/backend_hooks.ts +0 -114
  88. package/src/types/entity_overrides.tsx +0 -11
@@ -1,10 +1,17 @@
1
1
  /**
2
- * This interface represents a user.
3
- * It has some of the same fields as a Firebase User.
4
- * Note that in the default implementation, we simply take the Firebase user
5
- * and use it as a Rebase user, so that means that even if they are not mapped
6
- * in this interface, it contains all the methods of the former, such as `delete`,
7
- * `getIdToken`, etc.
2
+ * The canonical representation of an authenticated user in the Rebase ecosystem.
3
+ *
4
+ * Used by {@link AuthController}, collections, callbacks, and both the
5
+ * `@rebasepro/client` and `@rebasepro/auth` packages. All other user types
6
+ * (`RebaseUser`, `UserInfo`) are deprecated aliases of this type.
7
+ *
8
+ * **Backend-managed fields** (`uid`, `email`, `roles`, `metadata`, `createdAt`)
9
+ * are populated by the server. **Client-visible fields** (`displayName`,
10
+ * `photoURL`, `providerId`, `isAnonymous`, `emailVerified`) may be set during
11
+ * authentication or profile updates.
12
+ *
13
+ * @see AdminUser — the admin-API DTO, which adds audit fields (`createdAt`,
14
+ * `updatedAt`) and required `roles`.
8
15
  *
9
16
  * @group Models
10
17
  */
@@ -26,15 +33,20 @@ export type User = {
26
33
  */
27
34
  readonly photoURL: string | null;
28
35
  /**
29
- * The provider used to authenticate the user.
36
+ * The provider used to authenticate the user (e.g. `"password"`,
37
+ * `"google"`, `"github"`).
30
38
  */
31
39
  readonly providerId: string;
32
40
  /**
33
- *
41
+ * Whether the user is anonymous (created via anonymous sign-in).
34
42
  */
35
43
  readonly isAnonymous: boolean;
36
44
  /**
37
- * Role IDs assigned to this user (e.g. ["admin", "editor"]).
45
+ * Whether the user's email address has been verified.
46
+ */
47
+ readonly emailVerified?: boolean;
48
+ /**
49
+ * Role IDs assigned to this user (e.g. `["admin", "editor"]`).
38
50
  */
39
51
  roles?: string[];
40
52
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rebasepro/types",
3
3
  "type": "module",
4
- "version": "0.7.0",
4
+ "version": "0.9.0",
5
5
  "description": "Rebase type definitions — shared interfaces and controller types",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/rebaseco"
@@ -89,7 +89,7 @@ export type AuthController<USER extends User = User, ExtraData = unknown> = {
89
89
 
90
90
  /**
91
91
  * Extended auth controller with common optional auth methods.
92
- * Backend implementations (Rebase backend, Firebase, Supabase, etc.)
92
+ * Backend implementations (Rebase backend, Firebase, etc.)
93
93
  * extend this with their own backend-specific extras.
94
94
  * @group Hooks and utilities
95
95
  */
@@ -1,9 +1,10 @@
1
1
  import type { User } from "../users";
2
- import type { RebaseData } from "./data";
2
+ import type { RebaseSdkData } from "./data";
3
3
  import type { EmailService } from "./email";
4
4
  import type { StorageSource } from "./storage";
5
5
  import type { CronJobStatus, CronJobLogEntry } from "../types/cron";
6
6
  import type { ApiKeysAPI } from "../types/api_keys";
7
+ import type { StorageSourceDefinition } from "../types/storage_source";
7
8
 
8
9
 
9
10
  /**
@@ -12,7 +13,10 @@ import type { ApiKeysAPI } from "../types/api_keys";
12
13
  export type AuthChangeEvent = "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "USER_UPDATED";
13
14
 
14
15
  /**
15
- * Standard session interface representing an authenticated state
16
+ * Standard session interface representing an authenticated state.
17
+ *
18
+ * There is exactly one canonical definition of this type (here in
19
+ * `@rebasepro/types`). The `@rebasepro/client` package re-exports it.
16
20
  */
17
21
  export interface RebaseSession {
18
22
  accessToken: string;
@@ -21,6 +25,38 @@ export interface RebaseSession {
21
25
  user: User;
22
26
  }
23
27
 
28
+ /**
29
+ * Access and refresh token pair returned by authentication endpoints.
30
+ *
31
+ * Replaces the former `RebaseTokens` (client) and `AuthTokens` (auth) types,
32
+ * which had identical shapes.
33
+ *
34
+ * @group Auth
35
+ */
36
+ export interface AuthTokens {
37
+ accessToken: string;
38
+ refreshToken: string;
39
+ /** Unix timestamp (ms) when the access token expires. */
40
+ accessTokenExpiresAt: number;
41
+ }
42
+
43
+ /**
44
+ * A device-level session entry as returned by `GET /auth/sessions`.
45
+ *
46
+ * Represents one refresh-token / device pair. Not to be confused with
47
+ * {@link RebaseSession}, which is the client-side representation of the
48
+ * *current* authenticated state (user + tokens).
49
+ *
50
+ * @group Auth
51
+ */
52
+ export interface DeviceSession {
53
+ id: string;
54
+ userAgent?: string;
55
+ ipAddress?: string;
56
+ createdAt: string;
57
+ isCurrentSession?: boolean;
58
+ }
59
+
24
60
  /**
25
61
  * Unified Authentication Client Interface
26
62
  * Pure functional SDK interface, decoupled from UI and React hooks
@@ -36,6 +72,13 @@ export interface AuthClient {
36
72
  */
37
73
  getSession(): RebaseSession | null;
38
74
 
75
+ /**
76
+ * Get the current user's active sessions
77
+ */
78
+ getSessions?: () => Promise<DeviceSession[]>;
79
+ revokeSession?: (sessionId: string) => Promise<void>;
80
+ revokeAllSessions?: () => Promise<void>;
81
+
39
82
  /**
40
83
  * Sign out the current user and clear local session
41
84
  */
@@ -55,7 +98,14 @@ export interface AuthClient {
55
98
  // ─── Admin API ───────────────────────────────────────────────────────────────
56
99
 
57
100
  /**
58
- * User record as returned by the Admin API.
101
+ * User record as returned by the Admin API (`GET /admin/users`, etc.).
102
+ *
103
+ * This is a dedicated DTO for admin operations and differs from {@link User}:
104
+ * - `roles` is required (always an array), vs optional on `User`
105
+ * - Includes audit timestamps (`createdAt`, `updatedAt`) as ISO strings
106
+ * - `email` is non-nullable (admin users always have an email)
107
+ *
108
+ * @see User — the canonical client-facing user type
59
109
  * @group Admin
60
110
  */
61
111
  export interface AdminUser {
@@ -63,7 +113,11 @@ export interface AdminUser {
63
113
  email: string;
64
114
  displayName: string | null;
65
115
  photoURL: string | null;
66
- provider: string;
116
+ /**
117
+ * The provider used to authenticate the user (e.g. `"password"`,
118
+ * `"google"`). Named to match the canonical {@link User.providerId}.
119
+ */
120
+ providerId: string;
67
121
  roles: string[];
68
122
  metadata?: Record<string, any>;
69
123
  createdAt: string;
@@ -138,6 +192,35 @@ export interface FunctionsAPI {
138
192
  invoke<T = unknown>(name: string, payload?: unknown, options?: FunctionInvokeOptions): Promise<T>;
139
193
  }
140
194
 
195
+ // ─── HistoryConfig ───────────────────────────────────────────────────────────
196
+
197
+ /**
198
+ * Configuration for entity history / audit-log tracking.
199
+ *
200
+ * - `true` — enable history with default settings
201
+ * - `{ retention?: number }` — enable with optional retention period in days
202
+ */
203
+ export type HistoryConfig = boolean | { retention?: number };
204
+
205
+ // ─── RebaseWebSocket ─────────────────────────────────────────────────────────
206
+
207
+ /**
208
+ * Minimal WebSocket client contract exposed on {@link RebaseClient}.
209
+ *
210
+ * The full implementation (`RebaseWebSocketClient` in `@rebasepro/client`)
211
+ * adds subscription helpers, CRUD-over-WS, SQL execution, etc.
212
+ */
213
+ export interface RebaseWebSocket {
214
+ /** Disconnect the WebSocket and stop reconnecting. */
215
+ disconnect(): void;
216
+ /** Send an authentication token to the server. */
217
+ authenticate(token: string): Promise<void>;
218
+ /** Set a function that lazily resolves the auth token for auto-authentication. */
219
+ setAuthTokenGetter(getter: () => Promise<string | null>): void;
220
+ /** Listen for connection lifecycle events. */
221
+ on(event: "connect" | "disconnect" | "reconnect" | "error", cb: (...args: unknown[]) => void): () => void;
222
+ }
223
+
141
224
  // ─── RebaseClient ────────────────────────────────────────────────────────────
142
225
 
143
226
  /**
@@ -152,14 +235,53 @@ export interface FunctionsAPI {
152
235
  */
153
236
  export interface RebaseClient<DB = unknown> {
154
237
  /** Unified Data access layer */
155
- data: RebaseData;
238
+ data: RebaseSdkData<DB>;
239
+
240
+ /**
241
+ * Admin-scoped, **RLS-bypassing** data accessor.
242
+ *
243
+ * Present on the **server** singleton only (see {@link RebaseServerClient}).
244
+ * It runs with `{ uid: "service", roles: ["admin"] }` — every read and write
245
+ * bypasses row-level-security policies. This is the correct tool for trusted
246
+ * background work (cron jobs, migrations, service-to-service tasks).
247
+ *
248
+ * ⚠️ **Do NOT use it to serve user-facing data.** Inside a request handler,
249
+ * user-scoped queries must go through the request-scoped driver
250
+ * (`c.var.driver`), which carries the caller's identity so RLS applies.
251
+ * Reaching for `dataAsAdmin` (or its alias {@link data}) in a request handler
252
+ * silently exposes every row to every caller.
253
+ *
254
+ * Undefined in the browser SDK.
255
+ */
256
+ dataAsAdmin?: RebaseSdkData<DB>;
156
257
 
157
258
  /** Unified Authentication layer */
158
259
  auth: AuthClient;
159
260
 
160
- /** Unified Storage layer */
261
+ /** Unified Storage layer (default storage source, backward-compatible) */
161
262
  storage?: StorageSource;
162
263
 
264
+ /** Registry of all named storage sources for multi-backend support */
265
+ storageRegistry?: StorageSourceRegistry;
266
+
267
+ /**
268
+ * Build a server-backed {@link StorageSource} for a named storage source.
269
+ * The returned source forwards `storageId` to the backend so requests are
270
+ * routed to the matching `StorageController`. Used to lazily wire
271
+ * `transport: "server"` sources on the frontend.
272
+ */
273
+ createStorageSource?(storageId: string): StorageSource;
274
+
275
+ /**
276
+ * Discover the storage sources declared on the backend via
277
+ * `GET /api/storage/sources`. Server-transport sources are auto-registered
278
+ * into {@link storageRegistry}; `direct` sources are returned so the app
279
+ * can supply the live {@link StorageSource} instance. The result is cached
280
+ * (a failed call is retryable). This makes the backend the single source of
281
+ * truth for storage-source configuration.
282
+ */
283
+ fetchStorageSources?(): Promise<StorageSourceDefinition[]>;
284
+
163
285
  /**
164
286
  * Server-side email service.
165
287
  * Available when SMTP or a custom `sendEmail` function is configured.
@@ -183,7 +305,7 @@ export interface RebaseClient<DB = unknown> {
183
305
  baseUrl?: string;
184
306
 
185
307
  /** WebSocket client for realtime subscriptions */
186
- ws?: unknown;
308
+ ws?: RebaseWebSocket;
187
309
 
188
310
  /** Set the auth token for subsequent requests */
189
311
  setToken?(token: string | null): void;
@@ -207,3 +329,149 @@ export interface RebaseClient<DB = unknown> {
207
329
  sql?(query: string, options?: { database?: string; role?: string }): Promise<Record<string, unknown>[]>;
208
330
  }
209
331
 
332
+ // ─── RebaseServerClient ──────────────────────────────────────────────────────
333
+
334
+ /**
335
+ * The server-side Rebase surface — the shape of the `rebase` singleton exported
336
+ * from `@rebasepro/server-core`.
337
+ *
338
+ * Narrows {@link RebaseClient} to the guarantees that always hold on the server:
339
+ * the admin-scoped {@link dataAsAdmin} accessor, raw {@link sql}, and the
340
+ * {@link email} service are all present (non-optional).
341
+ *
342
+ * **Trust levels.** Both {@link dataAsAdmin} and the deprecated {@link data}
343
+ * alias point at the same admin-scoped, **RLS-bypassing** driver. Prefer
344
+ * `dataAsAdmin` so the privilege is explicit at every call site. For user-scoped
345
+ * queries inside a request handler use the request-scoped driver
346
+ * (`c.var.driver`) instead — never `dataAsAdmin`/`data`.
347
+ */
348
+ export interface RebaseServerClient<DB = unknown> extends RebaseClient<DB> {
349
+ /**
350
+ * @deprecated On the server, prefer {@link dataAsAdmin} for admin scope or
351
+ * the request-scoped driver (`c.var.driver`) for user scope. This alias
352
+ * points at the same admin-scoped, RLS-bypassing accessor as `dataAsAdmin`.
353
+ */
354
+ data: RebaseSdkData<DB>;
355
+
356
+ /**
357
+ * Admin-scoped, **RLS-bypassing** data accessor. Always present server-side.
358
+ * See {@link RebaseClient.dataAsAdmin} for the full safety contract.
359
+ */
360
+ dataAsAdmin: RebaseSdkData<DB>;
361
+
362
+ /**
363
+ * Server-side email service. Always present server-side (a no-op sender is
364
+ * wired when SMTP is not configured).
365
+ */
366
+ email: EmailService;
367
+
368
+ /**
369
+ * Execute raw SQL against the database. Always present server-side for SQL
370
+ * engines.
371
+ */
372
+ sql(query: string, options?: { database?: string; role?: string }): Promise<Record<string, unknown>[]>;
373
+ }
374
+
375
+ // ─── RebaseBrowserClient ─────────────────────────────────────────────────────
376
+
377
+ /**
378
+ * The browser-side Rebase surface — the shape produced by
379
+ * `createRebaseClient()` in `@rebasepro/client`.
380
+ *
381
+ * Its {@link data} accessor is **user-scoped**: every call carries the signed-in
382
+ * user's token, so backend RLS policies apply. It deliberately omits the
383
+ * server-only members — there is no `sql`, no `email`, and no
384
+ * `dataAsAdmin`, so the RLS-bypassing accessor can never be reached from
385
+ * browser code.
386
+ */
387
+ export interface RebaseBrowserClient<DB = unknown> {
388
+ /** User-scoped data access layer (carries the signed-in user's token). */
389
+ data: RebaseSdkData<DB>;
390
+
391
+ /** Unified Authentication layer */
392
+ auth: AuthClient;
393
+
394
+ /** Unified Storage layer (default storage source, backward-compatible) */
395
+ storage?: StorageSource;
396
+
397
+ /** Registry of all named storage sources for multi-backend support */
398
+ storageRegistry?: StorageSourceRegistry;
399
+
400
+ /** Build a server-backed {@link StorageSource} for a named storage source. */
401
+ createStorageSource?(storageId: string): StorageSource;
402
+
403
+ /** Discover the storage sources declared on the backend. */
404
+ fetchStorageSources?(): Promise<StorageSourceDefinition[]>;
405
+
406
+ /** Admin API for user management */
407
+ admin?: AdminAPI;
408
+
409
+ /** Cron job management API */
410
+ cron?: CronAPI;
411
+
412
+ /** Custom backend functions API */
413
+ functions?: FunctionsAPI;
414
+
415
+ /** Service API keys management API */
416
+ apiKeys?: ApiKeysAPI;
417
+
418
+ /** Base HTTP URL of the backend server */
419
+ baseUrl?: string;
420
+
421
+ /** WebSocket client for realtime subscriptions */
422
+ ws?: RebaseWebSocket;
423
+
424
+ /** Set the auth token for subsequent requests */
425
+ setToken?(token: string | null): void;
426
+
427
+ /** Set a function that lazily resolves the auth token */
428
+ setAuthTokenGetter?(getter: () => Promise<string | null>): void;
429
+
430
+ /** Set handler called when a request returns 401 */
431
+ setOnUnauthorized?(handler: () => Promise<boolean>): void;
432
+
433
+ /** Resolve the current auth token */
434
+ resolveToken?(): Promise<string | null>;
435
+
436
+ /** Make a raw HTTP call to the backend */
437
+ call?<T = unknown>(endpoint: string, payload?: unknown): Promise<T>;
438
+ }
439
+
440
+ /**
441
+ * Client-side registry for managing multiple storage sources.
442
+ *
443
+ * Mirrors the server-side `StorageRegistry` pattern. Allows collection
444
+ * properties to reference a named storage backend via
445
+ * `StorageConfig.storageSource`.
446
+ *
447
+ * @group Models
448
+ */
449
+ export interface StorageSourceRegistry {
450
+ /**
451
+ * Get a storage source by key.
452
+ * @param key - Storage source key, or undefined/null for default
453
+ * @returns The StorageSource, or undefined if not found
454
+ */
455
+ get(key: string | undefined | null): StorageSource | undefined;
456
+
457
+ /**
458
+ * Get the default storage source (key = "(default)").
459
+ * @throws Error if no default storage is registered
460
+ */
461
+ getDefault(): StorageSource;
462
+
463
+ /**
464
+ * Get a storage source by key, with fallback to default.
465
+ * @param key - Storage source key, or undefined/null for default
466
+ * @returns The StorageSource (falls back to default if key not found)
467
+ * @throws Error if neither the specified nor default storage exists
468
+ */
469
+ getOrDefault(key: string | undefined | null): StorageSource;
470
+
471
+ /** Check if a storage source with the given key exists */
472
+ has(key: string): boolean;
473
+
474
+ /** List all registered storage source keys */
475
+ list(): string[];
476
+ }
477
+
@@ -1,4 +1,4 @@
1
- import type { EntityCollection } from "../types/collections";
1
+ import type { CollectionConfig } from "../types/collections";
2
2
  import type { EntityReference } from "../types/entities";
3
3
 
4
4
  /**
@@ -7,7 +7,7 @@ import type { EntityReference } from "../types/entities";
7
7
  */
8
8
  export type CollectionRegistryController<
9
9
  DB = Record<string, unknown>,
10
- EC extends EntityCollection = EntityCollection
10
+ EC extends CollectionConfig = CollectionConfig
11
11
  > = {
12
12
 
13
13
  /**
@@ -16,7 +16,7 @@ export type CollectionRegistryController<
16
16
  * Each of the navigation entries in this field
17
17
  * generates an entry in the main menu.
18
18
  */
19
- collections?: EntityCollection[];
19
+ collections?: CollectionConfig[];
20
20
 
21
21
  /**
22
22
  * Is the registry ready to be used
@@ -30,7 +30,7 @@ export type CustomizationController = {
30
30
  * You can use the key to reference the custom view in
31
31
  * the `entityViews` prop of a collection.
32
32
  *
33
- * You can also define an entity view from the UI.
33
+ * You can also define a entity view from the UI.
34
34
  */
35
35
  entityViews?: EntityCustomView[];
36
36