@rebasepro/types 0.7.0 → 0.8.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 (37) hide show
  1. package/dist/controllers/client.d.ts +53 -1
  2. package/dist/controllers/data.d.ts +19 -47
  3. package/dist/controllers/registry.d.ts +0 -2
  4. package/dist/index.es.js +157 -10
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/index.umd.js +163 -9
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/types/auth_adapter.d.ts +5 -5
  9. package/dist/types/backend.d.ts +4 -0
  10. package/dist/types/collections.d.ts +158 -82
  11. package/dist/types/data_source.d.ts +3 -3
  12. package/dist/types/entity_callbacks.d.ts +18 -6
  13. package/dist/types/filter-operators.d.ts +108 -0
  14. package/dist/types/index.d.ts +3 -2
  15. package/dist/types/policy.d.ts +137 -0
  16. package/dist/types/properties.d.ts +115 -37
  17. package/dist/types/property_config.d.ts +1 -1
  18. package/dist/types/storage_source.d.ts +83 -0
  19. package/package.json +1 -1
  20. package/src/controllers/client.ts +61 -1
  21. package/src/controllers/data.ts +20 -59
  22. package/src/controllers/registry.ts +0 -2
  23. package/src/types/auth_adapter.ts +5 -5
  24. package/src/types/backend.ts +5 -0
  25. package/src/types/collections.ts +191 -106
  26. package/src/types/data_source.ts +5 -5
  27. package/src/types/entity_callbacks.ts +18 -7
  28. package/src/types/filter-operators.ts +167 -0
  29. package/src/types/index.ts +3 -2
  30. package/src/types/policy.ts +173 -0
  31. package/src/types/properties.ts +123 -38
  32. package/src/types/property_config.tsx +0 -1
  33. package/src/types/storage_source.ts +90 -0
  34. package/dist/types/backend_hooks.d.ts +0 -109
  35. package/dist/types/entity_overrides.d.ts +0 -10
  36. package/src/types/backend_hooks.ts +0 -114
  37. package/src/types/entity_overrides.tsx +0 -11
@@ -4,6 +4,7 @@ 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
  * Event type for authentication state changes
9
10
  */
@@ -191,8 +192,26 @@ export interface RebaseClient<DB = unknown> {
191
192
  data: RebaseData;
192
193
  /** Unified Authentication layer */
193
194
  auth: AuthClient;
194
- /** Unified Storage layer */
195
+ /** Unified Storage layer (default storage source, backward-compatible) */
195
196
  storage?: StorageSource;
197
+ /** Registry of all named storage sources for multi-backend support */
198
+ storageRegistry?: StorageSourceRegistry;
199
+ /**
200
+ * Build a server-backed {@link StorageSource} for a named storage source.
201
+ * The returned source forwards `storageId` to the backend so requests are
202
+ * routed to the matching `StorageController`. Used to lazily wire
203
+ * `transport: "server"` sources on the frontend.
204
+ */
205
+ createStorageSource?(storageId: string): StorageSource;
206
+ /**
207
+ * Discover the storage sources declared on the backend via
208
+ * `GET /api/storage/sources`. Server-transport sources are auto-registered
209
+ * into {@link storageRegistry}; `direct` sources are returned so the app
210
+ * can supply the live {@link StorageSource} instance. The result is cached
211
+ * (a failed call is retryable). This makes the backend the single source of
212
+ * truth for storage-source configuration.
213
+ */
214
+ fetchStorageSources?(): Promise<StorageSourceDefinition[]>;
196
215
  /**
197
216
  * Server-side email service.
198
217
  * Available when SMTP or a custom `sendEmail` function is configured.
@@ -229,3 +248,36 @@ export interface RebaseClient<DB = unknown> {
229
248
  role?: string;
230
249
  }): Promise<Record<string, unknown>[]>;
231
250
  }
251
+ /**
252
+ * Client-side registry for managing multiple storage sources.
253
+ *
254
+ * Mirrors the server-side `StorageRegistry` pattern. Allows collection
255
+ * properties to reference a named storage backend via
256
+ * `StorageConfig.storageSource`.
257
+ *
258
+ * @group Models
259
+ */
260
+ export interface StorageSourceRegistry {
261
+ /**
262
+ * Get a storage source by key.
263
+ * @param key - Storage source key, or undefined/null for default
264
+ * @returns The StorageSource, or undefined if not found
265
+ */
266
+ get(key: string | undefined | null): StorageSource | undefined;
267
+ /**
268
+ * Get the default storage source (key = "(default)").
269
+ * @throws Error if no default storage is registered
270
+ */
271
+ getDefault(): StorageSource;
272
+ /**
273
+ * Get a storage source by key, with fallback to default.
274
+ * @param key - Storage source key, or undefined/null for default
275
+ * @returns The StorageSource (falls back to default if key not found)
276
+ * @throws Error if neither the specified nor default storage exists
277
+ */
278
+ getOrDefault(key: string | undefined | null): StorageSource;
279
+ /** Check if a storage source with the given key exists */
280
+ has(key: string): boolean;
281
+ /** List all registered storage source keys */
282
+ list(): string[];
283
+ }
@@ -1,22 +1,5 @@
1
1
  import { Entity, EntityValues } from "../types/entities";
2
- /**
3
- * Parameters for querying a collection.
4
- * Uses PostgREST-style filter syntax for consistency between
5
- * the SDK (HTTP) and framework (in-process) contexts.
6
- *
7
- * @group Data
8
- */
9
- /**
10
- * A where-clause value for a single field.
11
- *
12
- * Supports three syntaxes:
13
- * 1. **Equality shorthand**: raw JS values — `null`, `"active"`, `42`, `true`
14
- * 2. **Tuple syntax**: `[operator, value]` — `[">", 18]`, `["in", ["a","b"]]`
15
- * 3. **PostgREST string**: `"eq.published"`, `"gte.18"`, `"in.(a,b)"`
16
- *
17
- * @group Data
18
- */
19
- export type WhereFieldValue = string | number | boolean | null | [WhereFilterOpShort, any] | [WhereFilterOpShort, any][];
2
+ import { WhereFilterOp, FilterValues } from "../types/filter-operators";
20
3
  export type WhereValue<T> = T | T[] | null;
21
4
  export interface LogicalCondition {
22
5
  type: "and" | "or";
@@ -24,11 +7,14 @@ export interface LogicalCondition {
24
7
  }
25
8
  export interface FilterCondition {
26
9
  column: string;
27
- operator: FilterOperator;
10
+ operator: WhereFilterOp;
28
11
  value: unknown;
29
12
  }
30
- /** Short operator strings accepted in the tuple syntax. */
31
- export type WhereFilterOpShort = "==" | "!=" | ">" | ">=" | "<" | "<=" | "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "nin" | "not-in" | "array-contains" | "array-contains-any" | "cs" | "csa";
13
+ /**
14
+ * Parameters for querying a collection.
15
+ *
16
+ * @group Data
17
+ */
32
18
  export interface FindParams {
33
19
  /** Maximum number of items to return (default: 20) */
34
20
  limit?: number;
@@ -37,30 +23,17 @@ export interface FindParams {
37
23
  /** Page number (1-indexed), alternative to offset */
38
24
  page?: number;
39
25
  /**
40
- * Filter object. Supports multiple syntaxes per field:
41
- *
42
- * **Equality shorthand** raw JS values (null, string, number, boolean):
43
- * ```ts
44
- * { company_profile_id: null }
45
- * { status: "active" }
46
- * { age: 18 }
47
- * ```
26
+ * Filter conditions keyed by field name.
27
+ * Each value is a `[WhereFilterOp, value]` tuple or an array of tuples
28
+ * for multiple conditions on the same field.
48
29
  *
49
- * **Tuple syntax** — `[operator, value]`:
50
- * ```ts
30
+ * @example
31
+ * { status: ["==", "active"] }
51
32
  * { age: [">=", 18] }
52
33
  * { role: ["in", ["admin", "editor"]] }
53
- * { deleted_at: ["!=", null] }
54
- * ```
55
- *
56
- * **PostgREST string syntax** (original format):
57
- * ```ts
58
- * { status: "eq.published" }
59
- * { age: "gte.18" }
60
- * { role: "in.(admin,editor)" }
61
- * ```
34
+ * { age: [[">=", 18], ["<", 65]] }
62
35
  */
63
- where?: Record<string, WhereFieldValue>;
36
+ where?: FilterValues<string>;
64
37
  /** Logical grouping conditions (AND/OR) */
65
38
  logical?: LogicalCondition;
66
39
  /**
@@ -88,15 +61,14 @@ export interface FindResponse<M extends Record<string, unknown> = Record<string,
88
61
  hasMore: boolean;
89
62
  };
90
63
  }
91
- export type FilterOperator = WhereFilterOpShort;
92
64
  /**
93
65
  * Fluent Query Builder Interface supported on both client and server accessors.
94
66
  * @group Data
95
67
  */
96
68
  export interface QueryBuilderInterface<M extends Record<string, unknown> = Record<string, unknown>> {
97
- where<K extends keyof M & string>(column: K, operator: FilterOperator, value: WhereValue<M[K]>): this;
69
+ where<K extends keyof M & string>(column: K, operator: WhereFilterOp, value: WhereValue<M[K]>): this;
98
70
  where(logicalCondition: LogicalCondition): this;
99
- orderBy(column: keyof M & string, ascending?: "asc" | "desc"): this;
71
+ orderBy(column: keyof M & string, direction?: "asc" | "desc"): this;
100
72
  limit(count: number): this;
101
73
  offset(count: number): this;
102
74
  search(searchString: string): this;
@@ -156,9 +128,9 @@ export interface CollectionAccessor<M extends Record<string, unknown> = Record<s
156
128
  * Count the number of records matching the given filter.
157
129
  */
158
130
  count?(params?: FindParams): Promise<number>;
159
- where<K extends keyof M & string>(column: K, operator: FilterOperator, value: WhereValue<M[K]>): QueryBuilderInterface<M>;
131
+ where<K extends keyof M & string>(column: K, operator: WhereFilterOp, value: WhereValue<M[K]>): QueryBuilderInterface<M>;
160
132
  where(logicalCondition: LogicalCondition): QueryBuilderInterface<M>;
161
- orderBy(column: keyof M & string, ascending?: "asc" | "desc"): QueryBuilderInterface<M>;
133
+ orderBy(column: keyof M & string, direction?: "asc" | "desc"): QueryBuilderInterface<M>;
162
134
  limit(count: number): QueryBuilderInterface<M>;
163
135
  offset(count: number): QueryBuilderInterface<M>;
164
136
  search(searchString: string): QueryBuilderInterface<M>;
@@ -195,7 +167,7 @@ export interface RebaseData {
195
167
  * const accessor = data.collection("products");
196
168
  * await accessor.find({ limit: 10 });
197
169
  */
198
- collection(slug: string): CollectionAccessor;
170
+ collection<M extends Record<string, unknown> = Record<string, unknown>>(slug: string): CollectionAccessor<M>;
199
171
  /**
200
172
  * Dynamic collection accessor.
201
173
  * Access any collection by its slug as a property.
@@ -4,7 +4,6 @@ import type { EntityCollectionsBuilder, AppViewsBuilder } from "../types/builder
4
4
  import type { EntityCustomView } from "../types/entity_views";
5
5
  import type { EntityAction } from "../types/entity_actions";
6
6
  import type { AppView, NavigationGroupMapping } from "./navigation";
7
- import type { RebasePlugin } from "../types/plugins";
8
7
  /**
9
8
  * Options to enable the built-in collection editor.
10
9
  * When provided to `<RebaseCMS>`, the editor is auto-wired as a native feature.
@@ -31,7 +30,6 @@ export interface RebaseCMSConfig<EC extends EntityCollection = EntityCollection>
31
30
  homePage?: ReactNode;
32
31
  entityViews?: EntityCustomView[];
33
32
  entityActions?: EntityAction[];
34
- plugins?: RebasePlugin[];
35
33
  /**
36
34
  * Centralized configuration for how collections and views are grouped
37
35
  * in the navigation sidebar and home page.
package/dist/index.es.js CHANGED
@@ -122,29 +122,155 @@ var Vector = class {
122
122
  }
123
123
  };
124
124
  //#endregion
125
+ //#region src/types/filter-operators.ts
126
+ /** Maps canonical operators to their REST short-code equivalents. */
127
+ var CANONICAL_TO_REST = {
128
+ "==": "eq",
129
+ "!=": "neq",
130
+ ">": "gt",
131
+ ">=": "gte",
132
+ "<": "lt",
133
+ "<=": "lte",
134
+ "in": "in",
135
+ "not-in": "nin",
136
+ "array-contains": "cs",
137
+ "array-contains-any": "csa"
138
+ };
139
+ /** Maps REST short-code operators to their canonical equivalents. */
140
+ var REST_TO_CANONICAL = {
141
+ "eq": "==",
142
+ "neq": "!=",
143
+ "gt": ">",
144
+ "gte": ">=",
145
+ "lt": "<",
146
+ "lte": "<=",
147
+ "in": "in",
148
+ "nin": "not-in",
149
+ "cs": "array-contains",
150
+ "csa": "array-contains-any"
151
+ };
152
+ /** All canonical operator strings for runtime validation. */
153
+ var CANONICAL_OPS = new Set([
154
+ "<",
155
+ "<=",
156
+ "==",
157
+ "!=",
158
+ ">=",
159
+ ">",
160
+ "in",
161
+ "not-in",
162
+ "array-contains",
163
+ "array-contains-any"
164
+ ]);
165
+ /**
166
+ * Resolve any operator string (canonical or REST short-code) to its
167
+ * canonical `WhereFilterOp` form. Returns `undefined` for unknown operators.
168
+ *
169
+ * @example
170
+ * toCanonicalOp("==") // "=="
171
+ * toCanonicalOp("eq") // "=="
172
+ * toCanonicalOp("cs") // "array-contains"
173
+ * toCanonicalOp("xyz") // undefined
174
+ */
175
+ function toCanonicalOp(op) {
176
+ if (CANONICAL_OPS.has(op)) return op;
177
+ return REST_TO_CANONICAL[op];
178
+ }
179
+ //#endregion
125
180
  //#region src/types/collections.ts
126
181
  /**
127
182
  * Type guard for PostgreSQL collections.
128
- * Returns true if the collection uses the Postgres driver (or the default driver).
183
+ * Returns true if the collection uses the Postgres engine (or the default engine).
129
184
  * @group Models
130
185
  */
131
186
  function isPostgresCollection(collection) {
132
- return !collection.driver || collection.driver === "postgres";
187
+ return !collection.engine || collection.engine === "postgres";
133
188
  }
134
189
  /**
135
190
  * Type guard for Firebase / Firestore collections.
136
191
  * @group Models
137
192
  */
138
193
  function isFirebaseCollection(collection) {
139
- return collection.driver === "firestore";
194
+ return collection.engine === "firestore";
140
195
  }
141
196
  /**
142
197
  * Type guard for MongoDB collections.
143
198
  * @group Models
144
199
  */
145
200
  function isMongoDBCollection(collection) {
146
- return collection.driver === "mongodb";
201
+ return collection.engine === "mongodb";
147
202
  }
203
+ /**
204
+ * Returns the data path for a collection.
205
+ * For Firestore or MongoDB collections with a `path`, returns that value;
206
+ * otherwise falls back to `slug`.
207
+ */
208
+ function getCollectionDataPath(collection) {
209
+ if (isFirebaseCollection(collection) && collection.path) return collection.path;
210
+ if (isMongoDBCollection(collection) && collection.path) return collection.path;
211
+ return collection.slug;
212
+ }
213
+ /**
214
+ * Reads a collection's driver-declared subcollections thunk (the `subcollections`
215
+ * field) independent of engine identity, so engine-agnostic code doesn't have to
216
+ * type-guard against a specific driver. Returns `undefined` when the collection
217
+ * declares none.
218
+ *
219
+ * Pair with `getDataSourceCapabilities(engine).supportsSubcollections` to decide
220
+ * whether the engine honours subcollections at all before reading them.
221
+ * @group Models
222
+ */
223
+ function getDeclaredSubcollections(collection) {
224
+ return collection.subcollections;
225
+ }
226
+ //#endregion
227
+ //#region src/types/policy.ts
228
+ /** @group Models */
229
+ var policy = {
230
+ true: () => ({ kind: "true" }),
231
+ false: () => ({ kind: "false" }),
232
+ and: (...operands) => ({
233
+ kind: "and",
234
+ operands
235
+ }),
236
+ or: (...operands) => ({
237
+ kind: "or",
238
+ operands
239
+ }),
240
+ not: (operand) => ({
241
+ kind: "not",
242
+ operand
243
+ }),
244
+ compare: (left, op, right) => ({
245
+ kind: "compare",
246
+ op,
247
+ left,
248
+ right
249
+ }),
250
+ rolesOverlap: (roles) => ({
251
+ kind: "rolesOverlap",
252
+ roles
253
+ }),
254
+ rolesContain: (roles) => ({
255
+ kind: "rolesContain",
256
+ roles
257
+ }),
258
+ authenticated: () => ({ kind: "authenticated" }),
259
+ raw: (sql) => ({
260
+ kind: "raw",
261
+ sql
262
+ }),
263
+ field: (name) => ({
264
+ kind: "field",
265
+ name
266
+ }),
267
+ literal: (value) => ({
268
+ kind: "literal",
269
+ value
270
+ }),
271
+ authUid: () => ({ kind: "authUid" }),
272
+ authRoles: () => ({ kind: "authRoles" })
273
+ };
148
274
  //#endregion
149
275
  //#region src/types/backend.ts
150
276
  /**
@@ -251,13 +377,13 @@ var CAPABILITIES_REGISTRY = {
251
377
  "(default)": DEFAULT_CAPABILITIES
252
378
  };
253
379
  /**
254
- * Look up capabilities for a given driver key.
255
- * If `driver` is undefined or not found, returns `DEFAULT_CAPABILITIES`.
380
+ * Look up capabilities for a given engine key.
381
+ * If `engine` is undefined or not found, returns `DEFAULT_CAPABILITIES`.
256
382
  * @group Models
257
383
  */
258
- function getDataSourceCapabilities(driver) {
259
- if (!driver) return POSTGRES_CAPABILITIES;
260
- return CAPABILITIES_REGISTRY[driver] ?? DEFAULT_CAPABILITIES;
384
+ function getDataSourceCapabilities(engine) {
385
+ if (!engine) return POSTGRES_CAPABILITIES;
386
+ return CAPABILITIES_REGISTRY[engine] ?? DEFAULT_CAPABILITIES;
261
387
  }
262
388
  /**
263
389
  * Register custom capabilities for a third-party driver.
@@ -267,6 +393,27 @@ function registerDataSourceCapabilities(capabilities) {
267
393
  CAPABILITIES_REGISTRY[capabilities.key] = capabilities;
268
394
  }
269
395
  //#endregion
396
+ //#region src/types/storage_source.ts
397
+ /**
398
+ * Describes a named storage backend — a place files live.
399
+ *
400
+ * Declared once and shared front + back: the frontend uses it to decide
401
+ * transport (HTTP proxy vs direct SDK), the backend uses the same `key`
402
+ * to resolve a StorageController, and collection properties reference
403
+ * a definition by its `key` via `StorageConfig.storageSource`.
404
+ *
405
+ * This mirrors the {@link DataSourceDefinition} pattern used for databases.
406
+ *
407
+ * @group Models
408
+ */
409
+ /**
410
+ * The default storage source key, used when a property does not specify
411
+ * a `storageSource`. Shared by the frontend and backend registries so
412
+ * both agree on "the default storage backend".
413
+ * @group Models
414
+ */
415
+ var DEFAULT_STORAGE_SOURCE_KEY = "(default)";
416
+ //#endregion
270
417
  //#region src/types/component_ref.ts
271
418
  /**
272
419
  * Type guard: checks if a value is a `LazyComponentRef` produced by the
@@ -276,6 +423,6 @@ function isLazyComponentRef(ref) {
276
423
  return typeof ref === "object" && ref !== null && "__rebaseLazy" in ref && ref.__rebaseLazy === true;
277
424
  }
278
425
  //#endregion
279
- export { DEFAULT_CAPABILITIES, DEFAULT_DATA_SOURCE_KEY, EntityReference, EntityRelation, FIREBASE_CAPABILITIES, GeoPoint, MONGODB_CAPABILITIES, POSTGRES_CAPABILITIES, Vector, getDataSourceCapabilities, isBranchAdmin, isDocumentAdmin, isFirebaseCollection, isLazyComponentRef, isMongoDBCollection, isPostgresCollection, isSQLAdmin, isSchemaAdmin, registerDataSourceCapabilities };
426
+ export { CANONICAL_TO_REST, DEFAULT_CAPABILITIES, DEFAULT_DATA_SOURCE_KEY, DEFAULT_STORAGE_SOURCE_KEY, EntityReference, EntityRelation, FIREBASE_CAPABILITIES, GeoPoint, MONGODB_CAPABILITIES, POSTGRES_CAPABILITIES, REST_TO_CANONICAL, Vector, getCollectionDataPath, getDataSourceCapabilities, getDeclaredSubcollections, isBranchAdmin, isDocumentAdmin, isFirebaseCollection, isLazyComponentRef, isMongoDBCollection, isPostgresCollection, isSQLAdmin, isSchemaAdmin, policy, registerDataSourceCapabilities, toCanonicalOp };
280
427
 
281
428
  //# sourceMappingURL=index.es.js.map