@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,16 +1,16 @@
1
- import type { EntityCollection } from "../types/collections";
1
+ import type { CollectionConfig } from "../types/collections";
2
2
  /**
3
3
  * @group Models
4
4
  */
5
- export type PartialEntityCollection<M extends Record<string, unknown> = Record<string, unknown>> = Partial<EntityCollection<M>>;
5
+ export type PartialCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>> = Partial<CollectionConfig<M>>;
6
6
  /**
7
7
  * This interface is in charge of defining the controller that persists
8
8
  * modifications to a collection or collection, and retrieves them back from
9
9
  * a data source, such as local storage or Firestore.
10
10
  */
11
11
  export interface UserConfigurationPersistence {
12
- onCollectionModified: <M extends Record<string, unknown> = Record<string, unknown>>(path: string, partialCollection: PartialEntityCollection<M>) => void;
13
- getCollectionConfig: <M extends Record<string, unknown> = Record<string, unknown>>(path: string) => PartialEntityCollection<M>;
12
+ onCollectionModified: <M extends Record<string, unknown> = Record<string, unknown>>(path: string, partialCollection: PartialCollectionConfig<M>) => void;
13
+ getCollectionConfig: <M extends Record<string, unknown> = Record<string, unknown>>(path: string) => PartialCollectionConfig<M>;
14
14
  recentlyVisitedPaths: string[];
15
15
  setRecentlyVisitedPaths: (paths: string[]) => void;
16
16
  favouritePaths: string[];
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import type { EntityCollection } from "../types/collections";
2
+ import type { CollectionConfig } from "../types/collections";
3
3
  /**
4
4
  * Controller that handles URL path building and resolution.
5
5
  * @group Models
@@ -212,7 +212,7 @@ export interface NavigationEntry {
212
212
  name: string;
213
213
  slug: string;
214
214
  type: "collection" | "view" | "admin";
215
- collection?: EntityCollection;
215
+ collection?: CollectionConfig;
216
216
  view?: AppView;
217
217
  description?: string;
218
218
  group: string;
@@ -1,10 +1,9 @@
1
1
  import { ReactNode } from "react";
2
- import type { EntityCollection } from "../types/collections";
3
- import type { EntityCollectionsBuilder, AppViewsBuilder } from "../types/builders";
2
+ import type { CollectionConfig } from "../types/collections";
3
+ import type { CollectionConfigsBuilder, AppViewsBuilder } from "../types/builders";
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.
@@ -20,8 +19,8 @@ export interface CollectionEditorOptions {
20
19
  /** Suggested base paths shown when creating new collections. */
21
20
  pathSuggestions?: string[];
22
21
  }
23
- export interface RebaseCMSConfig<EC extends EntityCollection = EntityCollection> {
24
- collections?: EC[] | EntityCollectionsBuilder<EC>;
22
+ export interface RebaseCMSConfig<EC extends CollectionConfig = CollectionConfig> {
23
+ collections?: EC[] | CollectionConfigsBuilder<EC>;
25
24
  /**
26
25
  * Custom top-level views added to the main navigation.
27
26
  * Accepts a static array of views or an async builder function
@@ -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.
@@ -47,6 +45,19 @@ export interface RebaseCMSConfig<EC extends EntityCollection = EntityCollection>
47
45
  * are all auto-wired — no plugin or manual view injection needed.
48
46
  */
49
47
  collectionEditor?: boolean | CollectionEditorOptions;
48
+ /**
49
+ * URL path prefix the admin is mounted under, when it does not live at the
50
+ * site root. Set this when the admin is rendered inside a path-prefixed
51
+ * route (e.g. `<Route path="/admin/*">`) so URL⇄collection resolution
52
+ * accounts for the prefix — otherwise the current path won't be recognized
53
+ * as a collection path and views hang on a spinner with no data fetch.
54
+ *
55
+ * Do NOT set this when mounting via a react-router `basename` — react-router
56
+ * already strips the prefix from the location, so the default (`/`) is correct.
57
+ *
58
+ * @default "/"
59
+ */
60
+ basePath?: string;
50
61
  }
51
62
  export interface RebaseStudioConfig {
52
63
  tools?: ("sql" | "js" | "rls" | "schema" | "storage" | "cron" | "schema-visualizer" | "branches" | "api" | "logs" | "api-keys")[];
@@ -1,10 +1,10 @@
1
1
  import type { Entity } from "../types/entities";
2
- import type { EntityCollection } from "../types/collections";
2
+ import type { CollectionConfig } from "../types/collections";
3
3
  /**
4
4
  * Props used to open a side dialog
5
5
  * @group Hooks and utilities
6
6
  */
7
- export interface EntitySidePanelProps<M extends Record<string, unknown> = Record<string, unknown>> {
7
+ export interface SidePanelBindingProps<M extends Record<string, unknown> = Record<string, unknown>> {
8
8
  /**
9
9
  * Absolute path of the entity
10
10
  */
@@ -31,7 +31,7 @@ export interface EntitySidePanelProps<M extends Record<string, unknown> = Record
31
31
  * Collection representing the entities of this view.
32
32
  * If you leave it blank it will be induced by your navigation
33
33
  */
34
- collection?: EntityCollection<M>;
34
+ collection?: CollectionConfig<M>;
35
35
  /**
36
36
  * Should update the URL when opening the dialog.
37
37
  * Consider that if the collection that you provide is not defined in the base
@@ -74,7 +74,7 @@ export interface EntitySidePanelProps<M extends Record<string, unknown> = Record
74
74
  * Controller to open the side dialog displaying entity forms
75
75
  * @group Hooks and utilities
76
76
  */
77
- export interface SideEntityController {
77
+ export interface SidePanelController {
78
78
  /**
79
79
  * Close the last panel
80
80
  */
@@ -84,14 +84,14 @@ export interface SideEntityController {
84
84
  * of the view is fetched from the collections you have specified in the
85
85
  * navigation.
86
86
  * At least you need to pass the path of the entity you would like
87
- * to edit. You can set an entityId if you would like to edit and existing one
87
+ * to edit. You can set a entityId if you would like to edit and existing one
88
88
  * (or a new one with that id).
89
89
  * @param props
90
90
  */
91
- open: <M extends Record<string, unknown> = Record<string, unknown>>(props: EntitySidePanelProps<M>) => void;
91
+ open: <M extends Record<string, unknown> = Record<string, unknown>>(props: SidePanelBindingProps<M>) => void;
92
92
  /**
93
93
  * Replace the last open entity panel with the given one.
94
94
  * @param props
95
95
  */
96
- replace: <M extends Record<string, unknown> = Record<string, unknown>>(props: EntitySidePanelProps<M>) => void;
96
+ replace: <M extends Record<string, unknown> = Record<string, unknown>>(props: SidePanelBindingProps<M>) => void;
97
97
  }
@@ -1,3 +1,20 @@
1
+ /**
2
+ * Path prefix that marks an object as **public**. Files stored under this
3
+ * prefix are served without any auth token via a stable, permanent,
4
+ * CDN-cacheable URL (see {@link StorageSource.getSignedUrl}). Shared by the
5
+ * client SDK and the backend so both agree on which objects are public.
6
+ *
7
+ * @group Models
8
+ */
9
+ export declare const PUBLIC_STORAGE_PREFIX = "public/";
10
+ /**
11
+ * True when a storage key/path points at a public object (lives under
12
+ * {@link PUBLIC_STORAGE_PREFIX}). The check is applied to the key *within the
13
+ * bucket* — strip any `bucket/` and `scheme://` prefixes first.
14
+ *
15
+ * @group Models
16
+ */
17
+ export declare function isPublicStoragePath(path: string | null | undefined): boolean;
1
18
  /**
2
19
  * @group Models
3
20
  */
@@ -6,6 +23,13 @@ export interface UploadFileProps {
6
23
  key: string;
7
24
  metadata?: Record<string, unknown>;
8
25
  bucket?: string;
26
+ /**
27
+ * Store this object as **public**: it is placed under
28
+ * {@link PUBLIC_STORAGE_PREFIX} and served via a stable, token-less,
29
+ * permanent URL (safe to persist in a database and cache on a CDN).
30
+ * Defaults to `false` (private, short-lived signed URLs).
31
+ */
32
+ public?: boolean;
9
33
  }
10
34
  /**
11
35
  * @group Models
@@ -67,6 +91,21 @@ export declare interface DownloadMetadata {
67
91
  */
68
92
  contentType: string;
69
93
  customMetadata: Record<string, unknown>;
94
+ /**
95
+ * Optional short-lived download token (for local/server-mediated storage).
96
+ * Absent for public objects, which need no token.
97
+ */
98
+ token?: string;
99
+ /**
100
+ * Optional remaining lifetime of the token, in seconds.
101
+ */
102
+ tokenExpiresIn?: number;
103
+ /**
104
+ * True when this object is public: it is served without a token via a
105
+ * stable, permanent, CDN-cacheable URL. When set, the client builds a
106
+ * token-less URL and caches it indefinitely.
107
+ */
108
+ public?: boolean;
70
109
  }
71
110
  /**
72
111
  * @group Models
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Structured initializer for {@link RebaseApiError}.
3
+ *
4
+ * @group Errors
5
+ */
6
+ export interface RebaseErrorInit {
7
+ /**
8
+ * HTTP status code, when the error originated from an HTTP response.
9
+ * Left `undefined` for realtime/WebSocket, network, and client-side
10
+ * logic errors that have no HTTP status.
11
+ */
12
+ status?: number;
13
+ /** Stable, machine-readable error code (e.g. `"NOT_FOUND"`, `"BAD_REQUEST"`). */
14
+ code?: string;
15
+ /** Structured error payload returned by the server, when present. */
16
+ details?: unknown;
17
+ /** The underlying error this one wraps, if any. */
18
+ cause?: unknown;
19
+ }
20
+ /**
21
+ * The single error type thrown across the entire Rebase client surface —
22
+ * HTTP data/control-plane calls, realtime/WebSocket operations, and
23
+ * client-side logic errors (e.g. an unknown collection accessor). A `catch`
24
+ * block only ever needs to check for this one class:
25
+ *
26
+ * ```ts
27
+ * import { RebaseApiError } from "@rebasepro/client"; // re-exported
28
+ *
29
+ * try {
30
+ * await client.data.products.update(id, { price: 9 });
31
+ * } catch (e) {
32
+ * if (e instanceof RebaseApiError) {
33
+ * if (e.status === 404) { ... } // HTTP failures carry a status
34
+ * console.error(e.code, e.details);
35
+ * }
36
+ * }
37
+ * ```
38
+ *
39
+ * `status` is present for HTTP failures and `undefined` otherwise, so its
40
+ * presence distinguishes transport-level errors from realtime/logic errors.
41
+ *
42
+ * @group Errors
43
+ */
44
+ export declare class RebaseApiError extends Error {
45
+ /** HTTP status code, or `undefined` for non-HTTP errors. */
46
+ readonly status?: number;
47
+ /** Stable machine-readable error code, when the server supplied one. */
48
+ readonly code?: string;
49
+ /** Structured error payload from the server, when present. */
50
+ readonly details?: unknown;
51
+ constructor(message: string, init?: RebaseErrorInit);
52
+ }
53
+ /**
54
+ * Client-side logic error — raised before any request is made (e.g. accessing
55
+ * an unknown collection accessor when a typed dictionary is configured).
56
+ *
57
+ * A subclass of {@link RebaseApiError} (with no `status`), so a single
58
+ * `catch (e) { if (e instanceof RebaseApiError) ... }` handles it too.
59
+ *
60
+ * @group Errors
61
+ */
62
+ export declare class RebaseClientError extends RebaseApiError {
63
+ constructor(message: string);
64
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from "./errors";
1
2
  export * from "./rebase_context";
2
3
  export * from "./types";
3
4
  export * from "./controllers";
package/dist/index.es.js CHANGED
@@ -1,6 +1,63 @@
1
+ //#region src/errors.ts
2
+ /**
3
+ * The single error type thrown across the entire Rebase client surface —
4
+ * HTTP data/control-plane calls, realtime/WebSocket operations, and
5
+ * client-side logic errors (e.g. an unknown collection accessor). A `catch`
6
+ * block only ever needs to check for this one class:
7
+ *
8
+ * ```ts
9
+ * import { RebaseApiError } from "@rebasepro/client"; // re-exported
10
+ *
11
+ * try {
12
+ * await client.data.products.update(id, { price: 9 });
13
+ * } catch (e) {
14
+ * if (e instanceof RebaseApiError) {
15
+ * if (e.status === 404) { ... } // HTTP failures carry a status
16
+ * console.error(e.code, e.details);
17
+ * }
18
+ * }
19
+ * ```
20
+ *
21
+ * `status` is present for HTTP failures and `undefined` otherwise, so its
22
+ * presence distinguishes transport-level errors from realtime/logic errors.
23
+ *
24
+ * @group Errors
25
+ */
26
+ var RebaseApiError = class extends Error {
27
+ /** HTTP status code, or `undefined` for non-HTTP errors. */
28
+ status;
29
+ /** Stable machine-readable error code, when the server supplied one. */
30
+ code;
31
+ /** Structured error payload from the server, when present. */
32
+ details;
33
+ constructor(message, init = {}) {
34
+ super(message);
35
+ this.name = "RebaseApiError";
36
+ this.status = init.status;
37
+ this.code = init.code;
38
+ this.details = init.details;
39
+ if (init.cause !== void 0) this.cause = init.cause;
40
+ }
41
+ };
42
+ /**
43
+ * Client-side logic error — raised before any request is made (e.g. accessing
44
+ * an unknown collection accessor when a typed dictionary is configured).
45
+ *
46
+ * A subclass of {@link RebaseApiError} (with no `status`), so a single
47
+ * `catch (e) { if (e instanceof RebaseApiError) ... }` handles it too.
48
+ *
49
+ * @group Errors
50
+ */
51
+ var RebaseClientError = class extends RebaseApiError {
52
+ constructor(message) {
53
+ super(message);
54
+ this.name = "RebaseClientError";
55
+ }
56
+ };
57
+ //#endregion
1
58
  //#region src/types/entities.ts
2
59
  /**
3
- * Class used to create a reference to an entity in a different path.
60
+ * Class used to create a reference to a entity in a different path.
4
61
  *
5
62
  * @example
6
63
  * // Simple reference (most common case - single driver, single db)
@@ -34,7 +91,7 @@ var EntityReference = class {
34
91
  */
35
92
  databaseId;
36
93
  /**
37
- * Create a reference to an entity.
94
+ * Create a reference to a entity.
38
95
  *
39
96
  * @example
40
97
  * // Simple reference (most common case)
@@ -68,7 +125,7 @@ var EntityReference = class {
68
125
  }
69
126
  };
70
127
  /**
71
- * Class used to create a reference to an entity in a different path
128
+ * Class used to create a reference to a entity in a different path
72
129
  */
73
130
  var EntityRelation = class {
74
131
  __type = "relation";
@@ -122,30 +179,195 @@ var Vector = class {
122
179
  }
123
180
  };
124
181
  //#endregion
182
+ //#region src/types/filter-operators.ts
183
+ /** Maps canonical operators to their REST short-code equivalents. */
184
+ var CANONICAL_TO_REST = {
185
+ "==": "eq",
186
+ "!=": "neq",
187
+ ">": "gt",
188
+ ">=": "gte",
189
+ "<": "lt",
190
+ "<=": "lte",
191
+ "in": "in",
192
+ "not-in": "nin",
193
+ "array-contains": "cs",
194
+ "array-contains-any": "csa",
195
+ "like": "like",
196
+ "ilike": "ilike",
197
+ "not-like": "nlike",
198
+ "not-ilike": "nilike",
199
+ "is-null": "isnull",
200
+ "is-not-null": "notnull"
201
+ };
202
+ /** Maps REST short-code operators to their canonical equivalents. */
203
+ var REST_TO_CANONICAL = {
204
+ "eq": "==",
205
+ "neq": "!=",
206
+ "gt": ">",
207
+ "gte": ">=",
208
+ "lt": "<",
209
+ "lte": "<=",
210
+ "in": "in",
211
+ "nin": "not-in",
212
+ "cs": "array-contains",
213
+ "csa": "array-contains-any",
214
+ "like": "like",
215
+ "ilike": "ilike",
216
+ "nlike": "not-like",
217
+ "nilike": "not-ilike",
218
+ "isnull": "is-null",
219
+ "notnull": "is-not-null"
220
+ };
221
+ /**
222
+ * Operators that test for null/not-null and therefore ignore their value.
223
+ * Codecs normalize the value of these conditions to `null`.
224
+ */
225
+ var NULL_OPS = new Set(["is-null", "is-not-null"]);
226
+ /**
227
+ * Every canonical operator, in a stable order. Useful for engine capability
228
+ * declarations ({@link DataSourceCapabilities.filterOperators}) and for
229
+ * building operator subsets.
230
+ * @group Models
231
+ */
232
+ var ALL_WHERE_FILTER_OPS = [
233
+ "<",
234
+ "<=",
235
+ "==",
236
+ "!=",
237
+ ">=",
238
+ ">",
239
+ "in",
240
+ "not-in",
241
+ "array-contains",
242
+ "array-contains-any",
243
+ "like",
244
+ "ilike",
245
+ "not-like",
246
+ "not-ilike",
247
+ "is-null",
248
+ "is-not-null"
249
+ ];
250
+ /** All canonical operator strings for runtime validation. */
251
+ var CANONICAL_OPS = new Set(ALL_WHERE_FILTER_OPS);
252
+ /**
253
+ * Resolve any operator string (canonical or REST short-code) to its
254
+ * canonical `WhereFilterOp` form. Returns `undefined` for unknown operators.
255
+ *
256
+ * @example
257
+ * toCanonicalOp("==") // "=="
258
+ * toCanonicalOp("eq") // "=="
259
+ * toCanonicalOp("cs") // "array-contains"
260
+ * toCanonicalOp("xyz") // undefined
261
+ */
262
+ function toCanonicalOp(op) {
263
+ if (CANONICAL_OPS.has(op)) return op;
264
+ return REST_TO_CANONICAL[op];
265
+ }
266
+ //#endregion
125
267
  //#region src/types/collections.ts
126
268
  /**
127
269
  * Type guard for PostgreSQL collections.
128
- * Returns true if the collection uses the Postgres driver (or the default driver).
270
+ * Returns true if the collection uses the Postgres engine (or the default engine).
129
271
  * @group Models
130
272
  */
131
- function isPostgresCollection(collection) {
132
- return !collection.driver || collection.driver === "postgres";
273
+ function isPostgresCollectionConfig(collection) {
274
+ return !collection.engine || collection.engine === "postgres";
133
275
  }
134
276
  /**
135
277
  * Type guard for Firebase / Firestore collections.
136
278
  * @group Models
137
279
  */
138
- function isFirebaseCollection(collection) {
139
- return collection.driver === "firestore";
280
+ function isFirebaseCollectionConfig(collection) {
281
+ return collection.engine === "firestore";
140
282
  }
141
283
  /**
142
284
  * Type guard for MongoDB collections.
143
285
  * @group Models
144
286
  */
145
- function isMongoDBCollection(collection) {
146
- return collection.driver === "mongodb";
287
+ function isMongoDBCollectionConfig(collection) {
288
+ return collection.engine === "mongodb";
289
+ }
290
+ /**
291
+ * Returns the data path for a collection.
292
+ * For Firestore or MongoDB collections with a `path`, returns that value;
293
+ * otherwise falls back to `slug`.
294
+ */
295
+ function getCollectionDataPath(collection) {
296
+ if (isFirebaseCollectionConfig(collection) && collection.path) return collection.path;
297
+ if (isMongoDBCollectionConfig(collection) && collection.path) return collection.path;
298
+ return collection.slug;
299
+ }
300
+ /**
301
+ * Reads a collection's driver-declared subcollections thunk (the `subcollections`
302
+ * field) independent of engine identity, so engine-agnostic code doesn't have to
303
+ * type-guard against a specific driver. Returns `undefined` when the collection
304
+ * declares none.
305
+ *
306
+ * Pair with `getDataSourceCapabilities(engine).supportsSubcollections` to decide
307
+ * whether the engine honours subcollections at all before reading them.
308
+ * @group Models
309
+ */
310
+ function getDeclaredSubcollections(collection) {
311
+ return collection.subcollections;
147
312
  }
148
313
  //#endregion
314
+ //#region src/types/policy.ts
315
+ /** @group Models */
316
+ var policy = {
317
+ true: () => ({ kind: "true" }),
318
+ false: () => ({ kind: "false" }),
319
+ and: (...operands) => ({
320
+ kind: "and",
321
+ operands
322
+ }),
323
+ or: (...operands) => ({
324
+ kind: "or",
325
+ operands
326
+ }),
327
+ not: (operand) => ({
328
+ kind: "not",
329
+ operand
330
+ }),
331
+ compare: (left, op, right) => ({
332
+ kind: "compare",
333
+ op,
334
+ left,
335
+ right
336
+ }),
337
+ rolesOverlap: (roles) => ({
338
+ kind: "rolesOverlap",
339
+ roles
340
+ }),
341
+ rolesContain: (roles) => ({
342
+ kind: "rolesContain",
343
+ roles
344
+ }),
345
+ authenticated: () => ({ kind: "authenticated" }),
346
+ existsIn: (args) => ({
347
+ kind: "existsIn",
348
+ collection: args.collection,
349
+ where: args.where
350
+ }),
351
+ raw: (sql) => ({
352
+ kind: "raw",
353
+ sql
354
+ }),
355
+ field: (name) => ({
356
+ kind: "field",
357
+ name
358
+ }),
359
+ outerField: (name) => ({
360
+ kind: "outerField",
361
+ name
362
+ }),
363
+ literal: (value) => ({
364
+ kind: "literal",
365
+ value
366
+ }),
367
+ authUid: () => ({ kind: "authUid" }),
368
+ authRoles: () => ({ kind: "authRoles" })
369
+ };
370
+ //#endregion
149
371
  //#region src/types/backend.ts
150
372
  /**
151
373
  * Type guard: does this admin support SQL operations?
@@ -194,6 +416,7 @@ var POSTGRES_CAPABILITIES = {
194
416
  supportsReferences: false,
195
417
  supportsColumnTypes: true,
196
418
  supportsRealtime: true,
419
+ filterOperators: ALL_WHERE_FILTER_OPS,
197
420
  supportsSQLAdmin: true,
198
421
  supportsDocumentAdmin: false,
199
422
  supportsSchemaAdmin: true
@@ -208,6 +431,7 @@ var FIREBASE_CAPABILITIES = {
208
431
  supportsReferences: true,
209
432
  supportsColumnTypes: false,
210
433
  supportsRealtime: true,
434
+ filterOperators: ALL_WHERE_FILTER_OPS.filter((op) => op !== "like" && op !== "ilike" && op !== "not-like" && op !== "not-ilike"),
211
435
  supportsSQLAdmin: false,
212
436
  supportsDocumentAdmin: false,
213
437
  supportsSchemaAdmin: false
@@ -222,6 +446,7 @@ var MONGODB_CAPABILITIES = {
222
446
  supportsReferences: true,
223
447
  supportsColumnTypes: false,
224
448
  supportsRealtime: false,
449
+ filterOperators: ALL_WHERE_FILTER_OPS,
225
450
  supportsSQLAdmin: false,
226
451
  supportsDocumentAdmin: true,
227
452
  supportsSchemaAdmin: true
@@ -240,6 +465,7 @@ var DEFAULT_CAPABILITIES = {
240
465
  supportsReferences: true,
241
466
  supportsColumnTypes: true,
242
467
  supportsRealtime: true,
468
+ filterOperators: ALL_WHERE_FILTER_OPS,
243
469
  supportsSQLAdmin: true,
244
470
  supportsDocumentAdmin: true,
245
471
  supportsSchemaAdmin: true
@@ -251,13 +477,13 @@ var CAPABILITIES_REGISTRY = {
251
477
  "(default)": DEFAULT_CAPABILITIES
252
478
  };
253
479
  /**
254
- * Look up capabilities for a given driver key.
255
- * If `driver` is undefined or not found, returns `DEFAULT_CAPABILITIES`.
480
+ * Look up capabilities for a given engine key.
481
+ * If `engine` is undefined or not found, returns `DEFAULT_CAPABILITIES`.
256
482
  * @group Models
257
483
  */
258
- function getDataSourceCapabilities(driver) {
259
- if (!driver) return POSTGRES_CAPABILITIES;
260
- return CAPABILITIES_REGISTRY[driver] ?? DEFAULT_CAPABILITIES;
484
+ function getDataSourceCapabilities(engine) {
485
+ if (!engine) return POSTGRES_CAPABILITIES;
486
+ return CAPABILITIES_REGISTRY[engine] ?? DEFAULT_CAPABILITIES;
261
487
  }
262
488
  /**
263
489
  * Register custom capabilities for a third-party driver.
@@ -267,6 +493,27 @@ function registerDataSourceCapabilities(capabilities) {
267
493
  CAPABILITIES_REGISTRY[capabilities.key] = capabilities;
268
494
  }
269
495
  //#endregion
496
+ //#region src/types/storage_source.ts
497
+ /**
498
+ * Describes a named storage backend — a place files live.
499
+ *
500
+ * Declared once and shared front + back: the frontend uses it to decide
501
+ * transport (HTTP proxy vs direct SDK), the backend uses the same `key`
502
+ * to resolve a StorageController, and collection properties reference
503
+ * a definition by its `key` via `StorageConfig.storageSource`.
504
+ *
505
+ * This mirrors the {@link DataSourceDefinition} pattern used for databases.
506
+ *
507
+ * @group Models
508
+ */
509
+ /**
510
+ * The default storage source key, used when a property does not specify
511
+ * a `storageSource`. Shared by the frontend and backend registries so
512
+ * both agree on "the default storage backend".
513
+ * @group Models
514
+ */
515
+ var DEFAULT_STORAGE_SOURCE_KEY = "(default)";
516
+ //#endregion
270
517
  //#region src/types/component_ref.ts
271
518
  /**
272
519
  * Type guard: checks if a value is a `LazyComponentRef` produced by the
@@ -276,6 +523,33 @@ function isLazyComponentRef(ref) {
276
523
  return typeof ref === "object" && ref !== null && "__rebaseLazy" in ref && ref.__rebaseLazy === true;
277
524
  }
278
525
  //#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 };
526
+ //#region src/controllers/storage.ts
527
+ /**
528
+ * Path prefix that marks an object as **public**. Files stored under this
529
+ * prefix are served without any auth token via a stable, permanent,
530
+ * CDN-cacheable URL (see {@link StorageSource.getSignedUrl}). Shared by the
531
+ * client SDK and the backend so both agree on which objects are public.
532
+ *
533
+ * @group Models
534
+ */
535
+ var PUBLIC_STORAGE_PREFIX = "public/";
536
+ /**
537
+ * True when a storage key/path points at a public object (lives under
538
+ * {@link PUBLIC_STORAGE_PREFIX}). The check is applied to the key *within the
539
+ * bucket* — strip any `bucket/` and `scheme://` prefixes first.
540
+ *
541
+ * @group Models
542
+ */
543
+ function isPublicStoragePath(path) {
544
+ if (!path) return false;
545
+ let p = path;
546
+ const scheme = p.indexOf("://");
547
+ if (scheme !== -1) p = p.substring(scheme + 3);
548
+ p = p.replace(/^\/+/, "");
549
+ if (p.split("/").some((seg) => seg === "..")) return false;
550
+ return p.startsWith("public/") || p.startsWith(`default/public/`);
551
+ }
552
+ //#endregion
553
+ export { ALL_WHERE_FILTER_OPS, CANONICAL_TO_REST, DEFAULT_CAPABILITIES, DEFAULT_DATA_SOURCE_KEY, DEFAULT_STORAGE_SOURCE_KEY, EntityReference, EntityRelation, FIREBASE_CAPABILITIES, GeoPoint, MONGODB_CAPABILITIES, NULL_OPS, POSTGRES_CAPABILITIES, PUBLIC_STORAGE_PREFIX, REST_TO_CANONICAL, RebaseApiError, RebaseClientError, Vector, getCollectionDataPath, getDataSourceCapabilities, getDeclaredSubcollections, isBranchAdmin, isDocumentAdmin, isFirebaseCollectionConfig, isLazyComponentRef, isMongoDBCollectionConfig, isPostgresCollectionConfig, isPublicStoragePath, isSQLAdmin, isSchemaAdmin, policy, registerDataSourceCapabilities, toCanonicalOp };
280
554
 
281
555
  //# sourceMappingURL=index.es.js.map