@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.
- package/dist/controllers/client.d.ts +53 -1
- package/dist/controllers/data.d.ts +19 -47
- package/dist/controllers/registry.d.ts +0 -2
- package/dist/index.es.js +157 -10
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +163 -9
- package/dist/index.umd.js.map +1 -1
- package/dist/types/auth_adapter.d.ts +5 -5
- package/dist/types/backend.d.ts +4 -0
- package/dist/types/collections.d.ts +158 -82
- package/dist/types/data_source.d.ts +3 -3
- package/dist/types/entity_callbacks.d.ts +18 -6
- package/dist/types/filter-operators.d.ts +108 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/policy.d.ts +137 -0
- package/dist/types/properties.d.ts +115 -37
- package/dist/types/property_config.d.ts +1 -1
- package/dist/types/storage_source.d.ts +83 -0
- package/package.json +1 -1
- package/src/controllers/client.ts +61 -1
- package/src/controllers/data.ts +20 -59
- package/src/controllers/registry.ts +0 -2
- package/src/types/auth_adapter.ts +5 -5
- package/src/types/backend.ts +5 -0
- package/src/types/collections.ts +191 -106
- package/src/types/data_source.ts +5 -5
- package/src/types/entity_callbacks.ts +18 -7
- package/src/types/filter-operators.ts +167 -0
- package/src/types/index.ts +3 -2
- package/src/types/policy.ts +173 -0
- package/src/types/properties.ts +123 -38
- package/src/types/property_config.tsx +0 -1
- package/src/types/storage_source.ts +90 -0
- package/dist/types/backend_hooks.d.ts +0 -109
- package/dist/types/entity_overrides.d.ts +0 -10
- package/src/types/backend_hooks.ts +0 -114
- package/src/types/entity_overrides.tsx +0 -11
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured, engine-agnostic policy expressions.
|
|
3
|
+
*
|
|
4
|
+
* A {@link PolicyExpression} is the single source of truth for a row-level
|
|
5
|
+
* security condition. It is compiled to Postgres `USING`/`WITH CHECK` SQL
|
|
6
|
+
* (authoritative enforcement) and independently evaluated in JavaScript (to
|
|
7
|
+
* drive the admin UI, and — in future — to enforce on engines without native
|
|
8
|
+
* RLS such as MongoDB). Because both the SQL and the JS decision derive from
|
|
9
|
+
* the *same* expression, the UI matches database enforcement by construction —
|
|
10
|
+
* no drift between two hand-written implementations.
|
|
11
|
+
*
|
|
12
|
+
* The only escape hatch that cannot be evaluated client-side is the
|
|
13
|
+
* {@link RawPolicyExpression} node (`{ kind: "raw" }`): it preserves full
|
|
14
|
+
* PostgreSQL power but, being arbitrary SQL, is treated as *unknown* by the
|
|
15
|
+
* JavaScript evaluator (never silently allowed) and reflected exactly in the UI
|
|
16
|
+
* via server-computed capability flags.
|
|
17
|
+
*
|
|
18
|
+
* @group Models
|
|
19
|
+
*/
|
|
20
|
+
export type PolicyExpression = TruePolicyExpression | FalsePolicyExpression | AndPolicyExpression | OrPolicyExpression | NotPolicyExpression | ComparePolicyExpression | RolesOverlapPolicyExpression | RolesContainPolicyExpression | AuthenticatedPolicyExpression | RawPolicyExpression;
|
|
21
|
+
/** Always allows. Compiles to `true`. @group Models */
|
|
22
|
+
export interface TruePolicyExpression {
|
|
23
|
+
kind: "true";
|
|
24
|
+
}
|
|
25
|
+
/** Always denies. Compiles to `false`. @group Models */
|
|
26
|
+
export interface FalsePolicyExpression {
|
|
27
|
+
kind: "false";
|
|
28
|
+
}
|
|
29
|
+
/** Logical AND — every operand must pass. @group Models */
|
|
30
|
+
export interface AndPolicyExpression {
|
|
31
|
+
kind: "and";
|
|
32
|
+
operands: PolicyExpression[];
|
|
33
|
+
}
|
|
34
|
+
/** Logical OR — at least one operand must pass. @group Models */
|
|
35
|
+
export interface OrPolicyExpression {
|
|
36
|
+
kind: "or";
|
|
37
|
+
operands: PolicyExpression[];
|
|
38
|
+
}
|
|
39
|
+
/** Logical negation. @group Models */
|
|
40
|
+
export interface NotPolicyExpression {
|
|
41
|
+
kind: "not";
|
|
42
|
+
operand: PolicyExpression;
|
|
43
|
+
}
|
|
44
|
+
/** Comparison operators available to {@link ComparePolicyExpression}. @group Models */
|
|
45
|
+
export type PolicyCompareOperator = "eq" | "neq" | "lt" | "lte" | "gt" | "gte";
|
|
46
|
+
/**
|
|
47
|
+
* Compares two operands, e.g. `owner_id = auth.uid()`.
|
|
48
|
+
* @group Models
|
|
49
|
+
*/
|
|
50
|
+
export interface ComparePolicyExpression {
|
|
51
|
+
kind: "compare";
|
|
52
|
+
op: PolicyCompareOperator;
|
|
53
|
+
left: PolicyOperand;
|
|
54
|
+
right: PolicyOperand;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* True when the user holds *at least one* of the given application roles.
|
|
58
|
+
* Compiles to `string_to_array(auth.roles(), ',') && ARRAY[...]`.
|
|
59
|
+
* @group Models
|
|
60
|
+
*/
|
|
61
|
+
export interface RolesOverlapPolicyExpression {
|
|
62
|
+
kind: "rolesOverlap";
|
|
63
|
+
roles: string[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* True when the user holds *all* of the given application roles.
|
|
67
|
+
* Compiles to `string_to_array(auth.roles(), ',') @> ARRAY[...]`.
|
|
68
|
+
* @group Models
|
|
69
|
+
*/
|
|
70
|
+
export interface RolesContainPolicyExpression {
|
|
71
|
+
kind: "rolesContain";
|
|
72
|
+
roles: string[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* True when there is an authenticated user (`auth.uid() IS NOT NULL`).
|
|
76
|
+
* @group Models
|
|
77
|
+
*/
|
|
78
|
+
export interface AuthenticatedPolicyExpression {
|
|
79
|
+
kind: "authenticated";
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A raw PostgreSQL boolean expression — the full-power escape hatch.
|
|
83
|
+
*
|
|
84
|
+
* Columns can be referenced as `{column_name}`. This is Postgres-only and
|
|
85
|
+
* **server-authoritative**: the JavaScript evaluator cannot evaluate arbitrary
|
|
86
|
+
* SQL, so it treats this node as *unknown* rather than guessing.
|
|
87
|
+
* @group Models
|
|
88
|
+
*/
|
|
89
|
+
export interface RawPolicyExpression {
|
|
90
|
+
kind: "raw";
|
|
91
|
+
sql: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* An operand referenced by a {@link ComparePolicyExpression}.
|
|
95
|
+
* @group Models
|
|
96
|
+
*/
|
|
97
|
+
export type PolicyOperand = FieldPolicyOperand | LiteralPolicyOperand | AuthUidPolicyOperand | AuthRolesPolicyOperand;
|
|
98
|
+
/** A column value on the row being evaluated. @group Models */
|
|
99
|
+
export interface FieldPolicyOperand {
|
|
100
|
+
kind: "field";
|
|
101
|
+
/** The property/column name (resolved to its DB column when compiled). */
|
|
102
|
+
name: string;
|
|
103
|
+
}
|
|
104
|
+
/** A constant value. @group Models */
|
|
105
|
+
export interface LiteralPolicyOperand {
|
|
106
|
+
kind: "literal";
|
|
107
|
+
value: string | number | boolean | null;
|
|
108
|
+
}
|
|
109
|
+
/** The current user's id — compiles to `auth.uid()`. @group Models */
|
|
110
|
+
export interface AuthUidPolicyOperand {
|
|
111
|
+
kind: "authUid";
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The current user's roles as an array — compiles to
|
|
115
|
+
* `string_to_array(auth.roles(), ',')`.
|
|
116
|
+
* @group Models
|
|
117
|
+
*/
|
|
118
|
+
export interface AuthRolesPolicyOperand {
|
|
119
|
+
kind: "authRoles";
|
|
120
|
+
}
|
|
121
|
+
/** @group Models */
|
|
122
|
+
export declare const policy: {
|
|
123
|
+
true: () => TruePolicyExpression;
|
|
124
|
+
false: () => FalsePolicyExpression;
|
|
125
|
+
and: (...operands: PolicyExpression[]) => AndPolicyExpression;
|
|
126
|
+
or: (...operands: PolicyExpression[]) => OrPolicyExpression;
|
|
127
|
+
not: (operand: PolicyExpression) => NotPolicyExpression;
|
|
128
|
+
compare: (left: PolicyOperand, op: PolicyCompareOperator, right: PolicyOperand) => ComparePolicyExpression;
|
|
129
|
+
rolesOverlap: (roles: string[]) => RolesOverlapPolicyExpression;
|
|
130
|
+
rolesContain: (roles: string[]) => RolesContainPolicyExpression;
|
|
131
|
+
authenticated: () => AuthenticatedPolicyExpression;
|
|
132
|
+
raw: (sql: string) => RawPolicyExpression;
|
|
133
|
+
field: (name: string) => FieldPolicyOperand;
|
|
134
|
+
literal: (value: string | number | boolean | null) => LiteralPolicyOperand;
|
|
135
|
+
authUid: () => AuthUidPolicyOperand;
|
|
136
|
+
authRoles: () => AuthRolesPolicyOperand;
|
|
137
|
+
};
|
|
@@ -44,6 +44,16 @@ export type FirebaseProperty = Exclude<Property, RelationProperty>;
|
|
|
44
44
|
export type FirebaseProperties = {
|
|
45
45
|
[key: string]: FirebaseProperty;
|
|
46
46
|
};
|
|
47
|
+
export type MongoProperty = Exclude<Property, RelationProperty>;
|
|
48
|
+
export type MongoProperties = {
|
|
49
|
+
[key: string]: MongoProperty;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Union of all engine-specific property maps. Use this at engine-agnostic
|
|
53
|
+
* boundaries (collection editor, normalization) where the concrete engine is
|
|
54
|
+
* unknown but the narrowed property constraint must be satisfied.
|
|
55
|
+
*/
|
|
56
|
+
export type EngineProperties = PostgresProperties | FirebaseProperties | MongoProperties;
|
|
47
57
|
/**
|
|
48
58
|
* A helper type to infer the underlying data type from a Property definition.
|
|
49
59
|
* This is the core of the type inference system.
|
|
@@ -140,10 +150,6 @@ export interface BaseProperty<CustomProps = unknown> {
|
|
|
140
150
|
* Rules for validating this property
|
|
141
151
|
*/
|
|
142
152
|
validation?: PropertyValidationSchema;
|
|
143
|
-
/**
|
|
144
|
-
* This value will be set by default for new entities.
|
|
145
|
-
*/
|
|
146
|
-
defaultValue?: unknown;
|
|
147
153
|
/**
|
|
148
154
|
* Use this to define dynamic properties that change based on certain conditions
|
|
149
155
|
* or on the entity's values. For example, you can make a field read-only if
|
|
@@ -179,15 +185,36 @@ export interface BaseProperty<CustomProps = unknown> {
|
|
|
179
185
|
* @group Entity properties
|
|
180
186
|
*/
|
|
181
187
|
export interface StringUIConfig extends BaseUIConfig {
|
|
188
|
+
/**
|
|
189
|
+
* Is this string property long enough so it should be displayed in
|
|
190
|
+
* a multiple line field. Defaults to false. If set to true,
|
|
191
|
+
* the number of lines adapts to the content
|
|
192
|
+
*/
|
|
182
193
|
multiline?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Should this string property be displayed as a markdown field. If true,
|
|
196
|
+
* the field is rendered as a text editor that supports markdown highlight
|
|
197
|
+
* syntax. It also includes a preview of the result.
|
|
198
|
+
*/
|
|
183
199
|
markdown?: boolean;
|
|
200
|
+
/**
|
|
201
|
+
* Should this string be rendered as a tag instead of just text.
|
|
202
|
+
*/
|
|
184
203
|
previewAsTag?: boolean;
|
|
185
204
|
clearable?: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* If the value of this property is a URL, you can set this flag to true
|
|
207
|
+
* to add a link, or one of the supported media types to render a preview
|
|
208
|
+
*/
|
|
186
209
|
url?: boolean | PreviewType;
|
|
187
210
|
}
|
|
188
211
|
export interface StringProperty extends BaseProperty {
|
|
189
212
|
ui?: StringUIConfig;
|
|
190
213
|
type: "string";
|
|
214
|
+
/**
|
|
215
|
+
* Default value for new entities. Must be a string.
|
|
216
|
+
*/
|
|
217
|
+
defaultValue?: string;
|
|
191
218
|
/**
|
|
192
219
|
* Optional database column type. If not set, it defaults to `varchar` or `uuid` depending on `isId` configuration.
|
|
193
220
|
* Use `text` for strings with unbound length, `char` for fixed-length strings, or `varchar` for variable-length strings with a limit.
|
|
@@ -222,18 +249,6 @@ export interface StringProperty extends BaseProperty {
|
|
|
222
249
|
*
|
|
223
250
|
*/
|
|
224
251
|
enum?: EnumValues;
|
|
225
|
-
/**
|
|
226
|
-
* Is this string property long enough so it should be displayed in
|
|
227
|
-
* a multiple line field. Defaults to false. If set to true,
|
|
228
|
-
* the number of lines adapts to the content
|
|
229
|
-
*/
|
|
230
|
-
multiline?: boolean;
|
|
231
|
-
/**
|
|
232
|
-
* Should this string property be displayed as a markdown field. If true,
|
|
233
|
-
* the field is rendered as a text editors that supports markdown highlight
|
|
234
|
-
* syntax. It also includes a preview of the result.
|
|
235
|
-
*/
|
|
236
|
-
markdown?: boolean;
|
|
237
252
|
/**
|
|
238
253
|
* You can specify a `Storage` configuration. It is used to
|
|
239
254
|
* indicate that this string refers to a path in your storage provider.
|
|
@@ -243,31 +258,15 @@ export interface StringProperty extends BaseProperty {
|
|
|
243
258
|
* This property is used to indicate that the string is a user ID, and
|
|
244
259
|
* it will be rendered as a user picker.
|
|
245
260
|
* Note that the user ID needs to be the one used in your authentication
|
|
246
|
-
* provider
|
|
261
|
+
* provider (e.g. the ID in your `users` table).
|
|
247
262
|
* You can also use a property builder to specify the user path dynamically
|
|
248
263
|
* based on other values of the entity.
|
|
249
264
|
*/
|
|
250
265
|
userSelect?: boolean;
|
|
251
|
-
/**
|
|
252
|
-
* If the value of this property is a URL, you can set this flag to true
|
|
253
|
-
* to add a link, or one of the supported media types to render a preview
|
|
254
|
-
*/
|
|
255
|
-
url?: boolean | PreviewType;
|
|
256
266
|
/**
|
|
257
267
|
* Does this field include an email
|
|
258
268
|
*/
|
|
259
269
|
email?: boolean;
|
|
260
|
-
/**
|
|
261
|
-
* Should this string be rendered as a tag instead of just text.
|
|
262
|
-
*/
|
|
263
|
-
previewAsTag?: boolean;
|
|
264
|
-
/**
|
|
265
|
-
* You can use this property (a string) to behave as a reference to another
|
|
266
|
-
* collection. The stored value is the ID of the entity in the
|
|
267
|
-
* collection, and the `path` prop is used to
|
|
268
|
-
* define the collection this reference points to.
|
|
269
|
-
*/
|
|
270
|
-
reference?: ReferenceProperty;
|
|
271
270
|
}
|
|
272
271
|
/**
|
|
273
272
|
* @group Entity properties
|
|
@@ -278,6 +277,10 @@ export interface NumberUIConfig extends BaseUIConfig {
|
|
|
278
277
|
export interface NumberProperty extends BaseProperty {
|
|
279
278
|
ui?: NumberUIConfig;
|
|
280
279
|
type: "number";
|
|
280
|
+
/**
|
|
281
|
+
* Default value for new entities. Must be a number.
|
|
282
|
+
*/
|
|
283
|
+
defaultValue?: number;
|
|
281
284
|
/**
|
|
282
285
|
* Optional database column type. Allows specifying exact database numeric types.
|
|
283
286
|
* If not provided, integer fields (where validation.integer is true or isId is true) default to `integer`, others to `numeric`.
|
|
@@ -311,6 +314,10 @@ export interface NumberProperty extends BaseProperty {
|
|
|
311
314
|
export interface BooleanProperty extends BaseProperty {
|
|
312
315
|
ui?: BaseUIConfig;
|
|
313
316
|
type: "boolean";
|
|
317
|
+
/**
|
|
318
|
+
* Default value for new entities. Must be a boolean.
|
|
319
|
+
*/
|
|
320
|
+
defaultValue?: boolean;
|
|
314
321
|
/**
|
|
315
322
|
* Rules for validating this property
|
|
316
323
|
*/
|
|
@@ -325,6 +332,10 @@ export interface VectorUIConfig extends BaseUIConfig {
|
|
|
325
332
|
export interface VectorProperty extends BaseProperty {
|
|
326
333
|
ui?: VectorUIConfig;
|
|
327
334
|
type: "vector";
|
|
335
|
+
/**
|
|
336
|
+
* Default value for new entities.
|
|
337
|
+
*/
|
|
338
|
+
defaultValue?: Vector;
|
|
328
339
|
dimensions: number;
|
|
329
340
|
validation?: PropertyValidationSchema;
|
|
330
341
|
}
|
|
@@ -333,17 +344,28 @@ export interface VectorProperty extends BaseProperty {
|
|
|
333
344
|
*/
|
|
334
345
|
export interface BinaryProperty extends BaseProperty {
|
|
335
346
|
type: "binary";
|
|
347
|
+
/**
|
|
348
|
+
* Default value for new entities. Must be a base64-encoded string.
|
|
349
|
+
*/
|
|
350
|
+
defaultValue?: string;
|
|
336
351
|
validation?: PropertyValidationSchema;
|
|
337
352
|
}
|
|
338
353
|
/**
|
|
339
354
|
* @group Entity properties
|
|
340
355
|
*/
|
|
341
356
|
export interface DateUIConfig extends BaseUIConfig {
|
|
357
|
+
/**
|
|
358
|
+
* Add an icon to clear the value and set it to `null`. Defaults to `false`
|
|
359
|
+
*/
|
|
342
360
|
clearable?: boolean;
|
|
343
361
|
}
|
|
344
362
|
export interface DateProperty extends BaseProperty {
|
|
345
363
|
ui?: DateUIConfig;
|
|
346
364
|
type: "date";
|
|
365
|
+
/**
|
|
366
|
+
* Default value for new entities. Must be a Date.
|
|
367
|
+
*/
|
|
368
|
+
defaultValue?: Date;
|
|
347
369
|
/**
|
|
348
370
|
* Optional database column type. If not set, defaults to `timestamp` with timezone.
|
|
349
371
|
*/
|
|
@@ -369,10 +391,6 @@ export interface DateProperty extends BaseProperty {
|
|
|
369
391
|
* `updated_on` fields
|
|
370
392
|
*/
|
|
371
393
|
autoValue?: "on_create" | "on_update";
|
|
372
|
-
/**
|
|
373
|
-
* Add an icon to clear the value and set it to `null`. Defaults to `false`
|
|
374
|
-
*/
|
|
375
|
-
clearable?: boolean;
|
|
376
394
|
}
|
|
377
395
|
/**
|
|
378
396
|
* @group Entity properties
|
|
@@ -380,6 +398,10 @@ export interface DateProperty extends BaseProperty {
|
|
|
380
398
|
export interface GeopointProperty extends BaseProperty {
|
|
381
399
|
ui?: BaseUIConfig;
|
|
382
400
|
type: "geopoint";
|
|
401
|
+
/**
|
|
402
|
+
* Default value for new entities. Must be a GeoPoint.
|
|
403
|
+
*/
|
|
404
|
+
defaultValue?: GeoPoint;
|
|
383
405
|
/**
|
|
384
406
|
* Rules for validating this property
|
|
385
407
|
*/
|
|
@@ -391,9 +413,29 @@ export interface GeopointProperty extends BaseProperty {
|
|
|
391
413
|
export interface ReferenceUIConfig extends BaseUIConfig {
|
|
392
414
|
previewProperties?: string[];
|
|
393
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* A pointer to an entity, stored **as a value** on the row (id + path, and
|
|
418
|
+
* optionally a `driver`/`databaseId` for cross-datasource pointers).
|
|
419
|
+
*
|
|
420
|
+
* This is the native primitive of **document databases** — it maps 1:1 to a
|
|
421
|
+
* Firestore `DocumentReference`, and is persisted by the MongoDB driver as a
|
|
422
|
+
* tagged sub-document. It carries no schema-level relationship (no foreign key,
|
|
423
|
+
* no join, no cascade) and is resolved on demand.
|
|
424
|
+
*
|
|
425
|
+
* **Which to use:**
|
|
426
|
+
* - Firestore / MongoDB collection → use `reference`.
|
|
427
|
+
* - Postgres collection → use {@link RelationProperty} (`type: "relation"`),
|
|
428
|
+
* which models a real foreign key / join with prefetch and cascade.
|
|
429
|
+
*
|
|
430
|
+
* @group Entity properties
|
|
431
|
+
*/
|
|
394
432
|
export interface ReferenceProperty extends BaseProperty {
|
|
395
433
|
ui?: ReferenceUIConfig;
|
|
396
434
|
type: "reference";
|
|
435
|
+
/**
|
|
436
|
+
* Default value for new entities. Must be an EntityReference.
|
|
437
|
+
*/
|
|
438
|
+
defaultValue?: EntityReference;
|
|
397
439
|
/**
|
|
398
440
|
* Marks this field as a Primary Key / Unique Identifier.
|
|
399
441
|
* Framework behavior: Auto-maps to `collection.primaryKeys` internally if not explicitly set.
|
|
@@ -432,9 +474,29 @@ export interface RelationUIConfig extends BaseUIConfig {
|
|
|
432
474
|
previewProperties?: string[];
|
|
433
475
|
widget?: "select" | "dialog";
|
|
434
476
|
}
|
|
477
|
+
/**
|
|
478
|
+
* A schema-level relationship between collections **within a single
|
|
479
|
+
* datasource** — backed by a foreign key, junction table, or explicit join
|
|
480
|
+
* path. The resolved value (an `EntityRelation`) can carry a prefetched entity
|
|
481
|
+
* payload to eliminate N+1 queries, and supports `onUpdate`/`onDelete` cascade.
|
|
482
|
+
*
|
|
483
|
+
* This is the native primitive of **relational databases** (Postgres). It is
|
|
484
|
+
* the SQL counterpart to {@link ReferenceProperty}.
|
|
485
|
+
*
|
|
486
|
+
* **Which to use:**
|
|
487
|
+
* - Postgres collection → use `relation`.
|
|
488
|
+
* - Firestore / MongoDB collection → use {@link ReferenceProperty}
|
|
489
|
+
* (`type: "reference"`), a stored pointer with no join engine.
|
|
490
|
+
*
|
|
491
|
+
* @group Entity properties
|
|
492
|
+
*/
|
|
435
493
|
export interface RelationProperty extends BaseProperty {
|
|
436
494
|
ui?: RelationUIConfig;
|
|
437
495
|
type: "relation";
|
|
496
|
+
/**
|
|
497
|
+
* Default value for new entities. Must be an EntityRelation or array of EntityRelation.
|
|
498
|
+
*/
|
|
499
|
+
defaultValue?: EntityRelation | EntityRelation[];
|
|
438
500
|
/**
|
|
439
501
|
* Marks this field as a Primary Key / Unique Identifier.
|
|
440
502
|
* Framework behavior: Auto-maps to `collection.primaryKeys` internally if not explicitly set.
|
|
@@ -547,6 +609,10 @@ export interface ArrayUIConfig extends BaseUIConfig {
|
|
|
547
609
|
export interface ArrayProperty extends BaseProperty {
|
|
548
610
|
ui?: ArrayUIConfig;
|
|
549
611
|
type: "array";
|
|
612
|
+
/**
|
|
613
|
+
* Default value for new entities. Must be an array.
|
|
614
|
+
*/
|
|
615
|
+
defaultValue?: unknown[];
|
|
550
616
|
/**
|
|
551
617
|
* Optional database column type. By default, maps to a native Postgres array
|
|
552
618
|
* (e.g. `text[]`, `integer[]`/`numeric[]`, `boolean[]`) if the element type
|
|
@@ -624,6 +690,10 @@ export interface MapUIConfig extends BaseUIConfig {
|
|
|
624
690
|
export interface MapProperty extends BaseProperty {
|
|
625
691
|
ui?: MapUIConfig;
|
|
626
692
|
type: "map";
|
|
693
|
+
/**
|
|
694
|
+
* Default value for new entities. Must be a record/object.
|
|
695
|
+
*/
|
|
696
|
+
defaultValue?: Record<string, unknown>;
|
|
627
697
|
/**
|
|
628
698
|
* Optional database column type. Defaults to `jsonb`.
|
|
629
699
|
*/
|
|
@@ -801,6 +871,14 @@ export interface ArrayPropertyValidationSchema extends PropertyValidationSchema
|
|
|
801
871
|
* @group Entity properties
|
|
802
872
|
*/
|
|
803
873
|
export type StorageConfig = {
|
|
874
|
+
/**
|
|
875
|
+
* Key referencing a named storage backend from the StorageRegistry.
|
|
876
|
+
* Must match a `StorageSourceDefinition.key` or a key registered
|
|
877
|
+
* in `initializeRebaseBackend({ storage: { ... } })`.
|
|
878
|
+
*
|
|
879
|
+
* When omitted, the default storage source is used.
|
|
880
|
+
*/
|
|
881
|
+
storageSource?: string;
|
|
804
882
|
/**
|
|
805
883
|
* File MIME types that can be uploaded to this reference. Don't specify for
|
|
806
884
|
* all.
|
|
@@ -70,5 +70,5 @@ export type PropertyConfig = {
|
|
|
70
70
|
*/
|
|
71
71
|
description?: string;
|
|
72
72
|
};
|
|
73
|
-
export type PropertyConfigId = "text_field" | "multiline" | "markdown" | "url" | "email" | "user_select" | "select" | "multi_select" | "number_input" | "number_select" | "multi_number_select" | "file_upload" | "multi_file_upload" | "group" | "key_value" | "reference" | "
|
|
73
|
+
export type PropertyConfigId = "text_field" | "multiline" | "markdown" | "url" | "email" | "user_select" | "select" | "multi_select" | "number_input" | "number_select" | "multi_number_select" | "file_upload" | "multi_file_upload" | "group" | "key_value" | "reference" | "multi_references" | "relation" | "switch" | "date_time" | "repeat" | "custom_array" | "block" | "vector_input";
|
|
74
74
|
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes a named storage backend — a place files live.
|
|
3
|
+
*
|
|
4
|
+
* Declared once and shared front + back: the frontend uses it to decide
|
|
5
|
+
* transport (HTTP proxy vs direct SDK), the backend uses the same `key`
|
|
6
|
+
* to resolve a StorageController, and collection properties reference
|
|
7
|
+
* a definition by its `key` via `StorageConfig.storageSource`.
|
|
8
|
+
*
|
|
9
|
+
* This mirrors the {@link DataSourceDefinition} pattern used for databases.
|
|
10
|
+
*
|
|
11
|
+
* @group Models
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The default storage source key, used when a property does not specify
|
|
15
|
+
* a `storageSource`. Shared by the frontend and backend registries so
|
|
16
|
+
* both agree on "the default storage backend".
|
|
17
|
+
* @group Models
|
|
18
|
+
*/
|
|
19
|
+
export declare const DEFAULT_STORAGE_SOURCE_KEY = "(default)";
|
|
20
|
+
/**
|
|
21
|
+
* How the *frontend* reaches a storage backend.
|
|
22
|
+
*
|
|
23
|
+
* - `"server"` — through the Rebase backend REST API (`/api/storage`).
|
|
24
|
+
* The backend holds the actual `StorageController` and routes by
|
|
25
|
+
* storage-source key. This is the default and covers Local, S3, GCS,
|
|
26
|
+
* and any other server-mediated engine.
|
|
27
|
+
* - `"direct"` — straight from the client to the external backend via
|
|
28
|
+
* its own SDK (e.g. Firebase Storage via `@firebase/storage`).
|
|
29
|
+
* The Rebase backend is **not** in the upload/download path.
|
|
30
|
+
*
|
|
31
|
+
* @group Models
|
|
32
|
+
*/
|
|
33
|
+
export type StorageSourceTransport = "server" | "direct";
|
|
34
|
+
/**
|
|
35
|
+
* Declarative definition of a storage source — a named place files live.
|
|
36
|
+
*
|
|
37
|
+
* Declared once and shared front and back: the frontend uses it to decide
|
|
38
|
+
* transport (client HTTP proxy vs direct provider SDK), the backend uses
|
|
39
|
+
* the same `key` to resolve a `StorageController`, and collection
|
|
40
|
+
* properties reference a definition by its `key` via
|
|
41
|
+
* `StorageConfig.storageSource`.
|
|
42
|
+
*
|
|
43
|
+
* @group Models
|
|
44
|
+
*/
|
|
45
|
+
export interface StorageSourceDefinition {
|
|
46
|
+
/**
|
|
47
|
+
* Unique identifier for this storage source. Collection properties
|
|
48
|
+
* point at it via `StorageConfig.storageSource`.
|
|
49
|
+
* Defaults to {@link DEFAULT_STORAGE_SOURCE_KEY}.
|
|
50
|
+
*/
|
|
51
|
+
key: string;
|
|
52
|
+
/**
|
|
53
|
+
* The engine backing this storage source (e.g. `"local"`, `"s3"`,
|
|
54
|
+
* `"gcs"`, `"firebase"`, `"azure"`, or a custom id).
|
|
55
|
+
*/
|
|
56
|
+
engine: string;
|
|
57
|
+
/**
|
|
58
|
+
* How the frontend reaches this storage. Defaults to `"server"`.
|
|
59
|
+
*
|
|
60
|
+
* When `"direct"`, the client uses a provider-specific SDK
|
|
61
|
+
* (e.g. `@firebase/storage`) and the backend does not proxy
|
|
62
|
+
* upload/download traffic for this source.
|
|
63
|
+
*/
|
|
64
|
+
transport: StorageSourceTransport;
|
|
65
|
+
/** Human-readable label for the UI (e.g. "Firebase Storage", "S3 Media"). */
|
|
66
|
+
label?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* A resolved storage source: the single source of truth that the frontend
|
|
70
|
+
* router and backend registry both derive from.
|
|
71
|
+
*
|
|
72
|
+
* @group Models
|
|
73
|
+
*/
|
|
74
|
+
export interface ResolvedStorageSource {
|
|
75
|
+
/** Storage source key (routing key, shared front + back). */
|
|
76
|
+
key: string;
|
|
77
|
+
/** Engine backing the source. */
|
|
78
|
+
engine: string;
|
|
79
|
+
/** Frontend transport. */
|
|
80
|
+
transport: StorageSourceTransport;
|
|
81
|
+
/** Human-readable label. */
|
|
82
|
+
label?: string;
|
|
83
|
+
}
|
package/package.json
CHANGED
|
@@ -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
|
|
|
9
10
|
/**
|
|
@@ -157,9 +158,30 @@ export interface RebaseClient<DB = unknown> {
|
|
|
157
158
|
/** Unified Authentication layer */
|
|
158
159
|
auth: AuthClient;
|
|
159
160
|
|
|
160
|
-
/** Unified Storage layer */
|
|
161
|
+
/** Unified Storage layer (default storage source, backward-compatible) */
|
|
161
162
|
storage?: StorageSource;
|
|
162
163
|
|
|
164
|
+
/** Registry of all named storage sources for multi-backend support */
|
|
165
|
+
storageRegistry?: StorageSourceRegistry;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Build a server-backed {@link StorageSource} for a named storage source.
|
|
169
|
+
* The returned source forwards `storageId` to the backend so requests are
|
|
170
|
+
* routed to the matching `StorageController`. Used to lazily wire
|
|
171
|
+
* `transport: "server"` sources on the frontend.
|
|
172
|
+
*/
|
|
173
|
+
createStorageSource?(storageId: string): StorageSource;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Discover the storage sources declared on the backend via
|
|
177
|
+
* `GET /api/storage/sources`. Server-transport sources are auto-registered
|
|
178
|
+
* into {@link storageRegistry}; `direct` sources are returned so the app
|
|
179
|
+
* can supply the live {@link StorageSource} instance. The result is cached
|
|
180
|
+
* (a failed call is retryable). This makes the backend the single source of
|
|
181
|
+
* truth for storage-source configuration.
|
|
182
|
+
*/
|
|
183
|
+
fetchStorageSources?(): Promise<StorageSourceDefinition[]>;
|
|
184
|
+
|
|
163
185
|
/**
|
|
164
186
|
* Server-side email service.
|
|
165
187
|
* Available when SMTP or a custom `sendEmail` function is configured.
|
|
@@ -207,3 +229,41 @@ export interface RebaseClient<DB = unknown> {
|
|
|
207
229
|
sql?(query: string, options?: { database?: string; role?: string }): Promise<Record<string, unknown>[]>;
|
|
208
230
|
}
|
|
209
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Client-side registry for managing multiple storage sources.
|
|
234
|
+
*
|
|
235
|
+
* Mirrors the server-side `StorageRegistry` pattern. Allows collection
|
|
236
|
+
* properties to reference a named storage backend via
|
|
237
|
+
* `StorageConfig.storageSource`.
|
|
238
|
+
*
|
|
239
|
+
* @group Models
|
|
240
|
+
*/
|
|
241
|
+
export interface StorageSourceRegistry {
|
|
242
|
+
/**
|
|
243
|
+
* Get a storage source by key.
|
|
244
|
+
* @param key - Storage source key, or undefined/null for default
|
|
245
|
+
* @returns The StorageSource, or undefined if not found
|
|
246
|
+
*/
|
|
247
|
+
get(key: string | undefined | null): StorageSource | undefined;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Get the default storage source (key = "(default)").
|
|
251
|
+
* @throws Error if no default storage is registered
|
|
252
|
+
*/
|
|
253
|
+
getDefault(): StorageSource;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Get a storage source by key, with fallback to default.
|
|
257
|
+
* @param key - Storage source key, or undefined/null for default
|
|
258
|
+
* @returns The StorageSource (falls back to default if key not found)
|
|
259
|
+
* @throws Error if neither the specified nor default storage exists
|
|
260
|
+
*/
|
|
261
|
+
getOrDefault(key: string | undefined | null): StorageSource;
|
|
262
|
+
|
|
263
|
+
/** Check if a storage source with the given key exists */
|
|
264
|
+
has(key: string): boolean;
|
|
265
|
+
|
|
266
|
+
/** List all registered storage source keys */
|
|
267
|
+
list(): string[];
|
|
268
|
+
}
|
|
269
|
+
|