@rebasepro/types 0.8.0 → 0.9.1-canary.09aaf62
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/README.md +13 -13
- package/dist/controllers/auth.d.ts +7 -1
- package/dist/controllers/client.d.ts +204 -6
- package/dist/controllers/collection_registry.d.ts +3 -3
- package/dist/controllers/customization_controller.d.ts +1 -1
- package/dist/controllers/data.d.ts +309 -35
- package/dist/controllers/data_driver.d.ts +92 -37
- package/dist/controllers/email.d.ts +2 -2
- package/dist/controllers/index.d.ts +1 -1
- package/dist/controllers/local_config_persistence.d.ts +4 -4
- package/dist/controllers/navigation.d.ts +2 -2
- package/dist/controllers/registry.d.ts +21 -8
- package/dist/controllers/{side_entity_controller.d.ts → side_panel_controller.d.ts} +7 -7
- package/dist/controllers/storage.d.ts +39 -0
- package/dist/errors.d.ts +64 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +160 -15
- package/dist/index.es.js.map +1 -1
- package/dist/rebase_context.d.ts +8 -4
- package/dist/types/auth_adapter.d.ts +29 -4
- package/dist/types/backend.d.ts +33 -26
- package/dist/types/backup.d.ts +20 -0
- package/dist/types/builders.d.ts +2 -2
- package/dist/types/collections.d.ts +84 -75
- package/dist/types/component_overrides.d.ts +61 -3
- package/dist/types/cron.d.ts +11 -2
- package/dist/types/data_source.d.ts +15 -2
- package/dist/types/database_adapter.d.ts +21 -4
- package/dist/types/entities.d.ts +7 -7
- package/dist/types/entity_actions.d.ts +7 -7
- package/dist/types/entity_callbacks.d.ts +39 -39
- package/dist/types/entity_views.d.ts +3 -3
- package/dist/types/filter-operators.d.ts +62 -17
- package/dist/types/index.d.ts +1 -0
- package/dist/types/modify_collections.d.ts +2 -2
- package/dist/types/plugins.d.ts +9 -9
- package/dist/types/policy.d.ts +111 -11
- package/dist/types/properties.d.ts +54 -9
- package/dist/types/relations.d.ts +3 -3
- package/dist/types/slots.d.ts +14 -14
- package/dist/types/translations.d.ts +5 -1
- package/dist/types/user_management_delegate.d.ts +8 -2
- package/dist/types/websockets.d.ts +46 -13
- package/dist/users/user.d.ts +21 -9
- package/package.json +5 -6
- package/src/controllers/auth.tsx +7 -1
- package/src/controllers/client.ts +235 -7
- package/src/controllers/collection_registry.ts +3 -3
- package/src/controllers/customization_controller.tsx +1 -1
- package/src/controllers/data.ts +330 -39
- package/src/controllers/data_driver.ts +93 -40
- package/src/controllers/email.ts +2 -2
- package/src/controllers/index.ts +1 -1
- package/src/controllers/local_config_persistence.tsx +4 -4
- package/src/controllers/navigation.ts +2 -2
- package/src/controllers/registry.ts +22 -8
- package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
- package/src/controllers/storage.ts +60 -1
- package/src/errors.ts +80 -0
- package/src/index.ts +1 -0
- package/src/rebase_context.tsx +8 -4
- package/src/types/auth_adapter.ts +29 -4
- package/src/types/backend.ts +44 -36
- package/src/types/backup.ts +26 -0
- package/src/types/builders.ts +2 -2
- package/src/types/collections.ts +101 -91
- package/src/types/component_overrides.ts +72 -5
- package/src/types/cron.ts +11 -2
- package/src/types/data_source.ts +24 -2
- package/src/types/database_adapter.ts +19 -4
- package/src/types/entities.ts +7 -7
- package/src/types/entity_actions.tsx +7 -7
- package/src/types/entity_callbacks.ts +42 -42
- package/src/types/entity_views.tsx +3 -3
- package/src/types/filter-operators.ts +96 -23
- package/src/types/index.ts +1 -0
- package/src/types/modify_collections.tsx +2 -2
- package/src/types/plugins.tsx +9 -9
- package/src/types/policy.ts +114 -9
- package/src/types/properties.ts +58 -9
- package/src/types/relations.ts +3 -3
- package/src/types/slots.tsx +14 -14
- package/src/types/translations.ts +5 -1
- package/src/types/user_management_delegate.ts +8 -2
- package/src/types/websockets.ts +43 -14
- package/src/users/user.ts +22 -9
- package/dist/index.umd.js +0 -458
- package/dist/index.umd.js.map +0 -1
package/dist/types/policy.d.ts
CHANGED
|
@@ -17,7 +17,24 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @group Models
|
|
19
19
|
*/
|
|
20
|
-
export type PolicyExpression = TruePolicyExpression | FalsePolicyExpression | AndPolicyExpression | OrPolicyExpression | NotPolicyExpression | ComparePolicyExpression | RolesOverlapPolicyExpression | RolesContainPolicyExpression | AuthenticatedPolicyExpression | RawPolicyExpression;
|
|
20
|
+
export type PolicyExpression = TruePolicyExpression | FalsePolicyExpression | AndPolicyExpression | OrPolicyExpression | NotPolicyExpression | ComparePolicyExpression | RolesOverlapPolicyExpression | RolesContainPolicyExpression | AuthenticatedPolicyExpression | ServerContextPolicyExpression | ExistsInPolicyExpression | RawPolicyExpression;
|
|
21
|
+
/**
|
|
22
|
+
* The id a request without a logged-in user reports as `auth.uid()`.
|
|
23
|
+
*
|
|
24
|
+
* A user-context request always sets `app.user_id`: blank would read back as
|
|
25
|
+
* `NULL`, and `NULL` is how the trusted server context is recognised, so an
|
|
26
|
+
* anonymous visitor would be promoted to server privileges. The driver
|
|
27
|
+
* therefore substitutes this sentinel at the single chokepoint where the GUC
|
|
28
|
+
* is set.
|
|
29
|
+
*
|
|
30
|
+
* The consequence for policy authors is that **`auth.uid() IS NOT NULL` is a
|
|
31
|
+
* tautology on the user path** — it is true for anonymous visitors too. Use
|
|
32
|
+
* {@link policy.authenticated} (or `auth.uid() <> 'anonymous'`) to mean "signed
|
|
33
|
+
* in", and {@link policy.serverContext} to mean "the trusted server context".
|
|
34
|
+
*
|
|
35
|
+
* @group Models
|
|
36
|
+
*/
|
|
37
|
+
export declare const ANONYMOUS_USER_ID = "anonymous";
|
|
21
38
|
/** Always allows. Compiles to `true`. @group Models */
|
|
22
39
|
export interface TruePolicyExpression {
|
|
23
40
|
kind: "true";
|
|
@@ -29,12 +46,12 @@ export interface FalsePolicyExpression {
|
|
|
29
46
|
/** Logical AND — every operand must pass. @group Models */
|
|
30
47
|
export interface AndPolicyExpression {
|
|
31
48
|
kind: "and";
|
|
32
|
-
operands: PolicyExpression[];
|
|
49
|
+
operands: readonly PolicyExpression[];
|
|
33
50
|
}
|
|
34
51
|
/** Logical OR — at least one operand must pass. @group Models */
|
|
35
52
|
export interface OrPolicyExpression {
|
|
36
53
|
kind: "or";
|
|
37
|
-
operands: PolicyExpression[];
|
|
54
|
+
operands: readonly PolicyExpression[];
|
|
38
55
|
}
|
|
39
56
|
/** Logical negation. @group Models */
|
|
40
57
|
export interface NotPolicyExpression {
|
|
@@ -60,7 +77,7 @@ export interface ComparePolicyExpression {
|
|
|
60
77
|
*/
|
|
61
78
|
export interface RolesOverlapPolicyExpression {
|
|
62
79
|
kind: "rolesOverlap";
|
|
63
|
-
roles: string[];
|
|
80
|
+
roles: readonly string[];
|
|
64
81
|
}
|
|
65
82
|
/**
|
|
66
83
|
* True when the user holds *all* of the given application roles.
|
|
@@ -69,15 +86,81 @@ export interface RolesOverlapPolicyExpression {
|
|
|
69
86
|
*/
|
|
70
87
|
export interface RolesContainPolicyExpression {
|
|
71
88
|
kind: "rolesContain";
|
|
72
|
-
roles: string[];
|
|
89
|
+
roles: readonly string[];
|
|
73
90
|
}
|
|
74
91
|
/**
|
|
75
|
-
* True when
|
|
92
|
+
* True when a signed-in user is making the request. Compiles to
|
|
93
|
+
* `auth.uid() IS NOT NULL AND auth.uid() <> 'anonymous'`.
|
|
94
|
+
*
|
|
95
|
+
* Both halves are load-bearing. `IS NOT NULL` excludes the server context;
|
|
96
|
+
* the {@link ANONYMOUS_USER_ID} comparison excludes anonymous visitors, who
|
|
97
|
+
* *do* carry a non-null `auth.uid()`. Checking only `IS NOT NULL` grants to
|
|
98
|
+
* everyone — see {@link ANONYMOUS_USER_ID}.
|
|
99
|
+
*
|
|
100
|
+
* `policy.not(policy.authenticated())` therefore means "anonymous visitor or
|
|
101
|
+
* the server context". To single out the server context, use
|
|
102
|
+
* {@link ServerContextPolicyExpression}.
|
|
76
103
|
* @group Models
|
|
77
104
|
*/
|
|
78
105
|
export interface AuthenticatedPolicyExpression {
|
|
79
106
|
kind: "authenticated";
|
|
80
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* True only in the trusted **server context** — the built-in flows that run
|
|
110
|
+
* without a user (signup, migrations, `dataAsAdmin`) set no user GUC, so
|
|
111
|
+
* `auth.uid()` is `NULL` for them and only for them. Compiles to
|
|
112
|
+
* `auth.uid() IS NULL`.
|
|
113
|
+
*
|
|
114
|
+
* This is what lets the owner connection satisfy a policy even under FORCE RLS.
|
|
115
|
+
* It is deliberately a primitive rather than `not(authenticated())`: the two
|
|
116
|
+
* meant the same thing while `authenticated` ignored {@link ANONYMOUS_USER_ID},
|
|
117
|
+
* and conflating them is what turns a server-only grant into an anonymous one.
|
|
118
|
+
*
|
|
119
|
+
* The JavaScript evaluator always returns `false` for this node — a client is
|
|
120
|
+
* never the server context.
|
|
121
|
+
* @group Models
|
|
122
|
+
*/
|
|
123
|
+
export interface ServerContextPolicyExpression {
|
|
124
|
+
kind: "serverContext";
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Membership / relational access: true when at least one row exists in another
|
|
128
|
+
* collection (a join/membership table) matching `where`. This is what lets you
|
|
129
|
+
* scope reads to "rows whose team the caller belongs to" without an N+1
|
|
130
|
+
* per-row lookup — it compiles to a single correlated `EXISTS` subquery.
|
|
131
|
+
*
|
|
132
|
+
* Inside `where`, {@link FieldPolicyOperand} (`policy.field`) references a column
|
|
133
|
+
* of the joined collection, while {@link OuterFieldPolicyOperand}
|
|
134
|
+
* (`policy.outerField`) references a column of the row being checked (the outer
|
|
135
|
+
* table under RLS). Combine with {@link AuthUidPolicyOperand} to correlate to
|
|
136
|
+
* the caller.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* // documents visible only to members of the document's team:
|
|
141
|
+
* policy.existsIn({
|
|
142
|
+
* collection: "team_members",
|
|
143
|
+
* where: policy.and(
|
|
144
|
+
* policy.compare(policy.field("team_id"), "eq", policy.outerField("team_id")),
|
|
145
|
+
* policy.compare(policy.field("user_id"), "eq", policy.authUid()),
|
|
146
|
+
* ),
|
|
147
|
+
* })
|
|
148
|
+
* // → EXISTS (SELECT 1 FROM team_members _ex0
|
|
149
|
+
* // WHERE _ex0.team_id = documents.team_id AND _ex0.user_id = auth.uid())
|
|
150
|
+
* ```
|
|
151
|
+
*
|
|
152
|
+
* Postgres-authoritative: like {@link RawPolicyExpression}, the JavaScript
|
|
153
|
+
* evaluator treats it as *unknown* (it cannot run a subquery client-side), so
|
|
154
|
+
* enforcement is always the database's.
|
|
155
|
+
* @group Models
|
|
156
|
+
*/
|
|
157
|
+
export interface ExistsInPolicyExpression {
|
|
158
|
+
kind: "existsIn";
|
|
159
|
+
/** Slug of the collection to search (the join / membership table). */
|
|
160
|
+
collection: string;
|
|
161
|
+
/** Condition evaluated against the joined collection's rows. */
|
|
162
|
+
where: PolicyExpression;
|
|
163
|
+
}
|
|
81
164
|
/**
|
|
82
165
|
* A raw PostgreSQL boolean expression — the full-power escape hatch.
|
|
83
166
|
*
|
|
@@ -94,13 +177,24 @@ export interface RawPolicyExpression {
|
|
|
94
177
|
* An operand referenced by a {@link ComparePolicyExpression}.
|
|
95
178
|
* @group Models
|
|
96
179
|
*/
|
|
97
|
-
export type PolicyOperand = FieldPolicyOperand | LiteralPolicyOperand | AuthUidPolicyOperand | AuthRolesPolicyOperand;
|
|
180
|
+
export type PolicyOperand = FieldPolicyOperand | OuterFieldPolicyOperand | LiteralPolicyOperand | AuthUidPolicyOperand | AuthRolesPolicyOperand;
|
|
98
181
|
/** A column value on the row being evaluated. @group Models */
|
|
99
182
|
export interface FieldPolicyOperand {
|
|
100
183
|
kind: "field";
|
|
101
184
|
/** The property/column name (resolved to its DB column when compiled). */
|
|
102
185
|
name: string;
|
|
103
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* A column value on the *outer* row when used inside {@link ExistsInPolicyExpression}
|
|
189
|
+
* — i.e. the row the RLS policy is being evaluated for, referenced from within the
|
|
190
|
+
* subquery. Outside an `existsIn` it is equivalent to {@link FieldPolicyOperand}.
|
|
191
|
+
* @group Models
|
|
192
|
+
*/
|
|
193
|
+
export interface OuterFieldPolicyOperand {
|
|
194
|
+
kind: "outerField";
|
|
195
|
+
/** The property/column name on the outer collection. */
|
|
196
|
+
name: string;
|
|
197
|
+
}
|
|
104
198
|
/** A constant value. @group Models */
|
|
105
199
|
export interface LiteralPolicyOperand {
|
|
106
200
|
kind: "literal";
|
|
@@ -122,15 +216,21 @@ export interface AuthRolesPolicyOperand {
|
|
|
122
216
|
export declare const policy: {
|
|
123
217
|
true: () => TruePolicyExpression;
|
|
124
218
|
false: () => FalsePolicyExpression;
|
|
125
|
-
and: (...operands: PolicyExpression[]) => AndPolicyExpression;
|
|
126
|
-
or: (...operands: PolicyExpression[]) => OrPolicyExpression;
|
|
219
|
+
and: (...operands: readonly PolicyExpression[]) => AndPolicyExpression;
|
|
220
|
+
or: (...operands: readonly PolicyExpression[]) => OrPolicyExpression;
|
|
127
221
|
not: (operand: PolicyExpression) => NotPolicyExpression;
|
|
128
222
|
compare: (left: PolicyOperand, op: PolicyCompareOperator, right: PolicyOperand) => ComparePolicyExpression;
|
|
129
|
-
rolesOverlap: (roles: string[]) => RolesOverlapPolicyExpression;
|
|
130
|
-
rolesContain: (roles: string[]) => RolesContainPolicyExpression;
|
|
223
|
+
rolesOverlap: (roles: readonly string[]) => RolesOverlapPolicyExpression;
|
|
224
|
+
rolesContain: (roles: readonly string[]) => RolesContainPolicyExpression;
|
|
131
225
|
authenticated: () => AuthenticatedPolicyExpression;
|
|
226
|
+
serverContext: () => ServerContextPolicyExpression;
|
|
227
|
+
existsIn: (args: {
|
|
228
|
+
collection: string;
|
|
229
|
+
where: PolicyExpression;
|
|
230
|
+
}) => ExistsInPolicyExpression;
|
|
132
231
|
raw: (sql: string) => RawPolicyExpression;
|
|
133
232
|
field: (name: string) => FieldPolicyOperand;
|
|
233
|
+
outerField: (name: string) => OuterFieldPolicyOperand;
|
|
134
234
|
literal: (value: string | number | boolean | null) => LiteralPolicyOperand;
|
|
135
235
|
authUid: () => AuthUidPolicyOperand;
|
|
136
236
|
authRoles: () => AuthRolesPolicyOperand;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { ComponentRef } from "./component_ref";
|
|
2
2
|
import type { Entity, EntityReference, EntityRelation, EntityValues, GeoPoint, Vector } from "./entities";
|
|
3
3
|
import type { JoinStep, OnAction, Relation } from "./relations";
|
|
4
|
-
import type {
|
|
4
|
+
import type { CollectionConfig, FilterValues, WhereFilterOp } from "./collections";
|
|
5
5
|
import type { ColorKey, ColorScheme } from "./chips";
|
|
6
6
|
import type { AuthController } from "../controllers/auth";
|
|
7
|
-
import type {
|
|
7
|
+
import type { AfterReadProps, BeforeSaveProps } from "./entity_callbacks";
|
|
8
8
|
import type { User } from "../users";
|
|
9
9
|
/**
|
|
10
10
|
* Callbacks/Hooks for individual property fields
|
|
@@ -14,7 +14,7 @@ export type PropertyCallbacks<T = unknown, M extends Record<string, unknown> = R
|
|
|
14
14
|
/**
|
|
15
15
|
* Callback used after fetching data, to transform the value before rendering
|
|
16
16
|
*/
|
|
17
|
-
afterRead?(props: Omit<
|
|
17
|
+
afterRead?(props: Omit<AfterReadProps<M, USER>, "entity"> & {
|
|
18
18
|
value: T;
|
|
19
19
|
entity: Entity<M> | undefined;
|
|
20
20
|
}): Promise<T> | T;
|
|
@@ -22,7 +22,7 @@ export type PropertyCallbacks<T = unknown, M extends Record<string, unknown> = R
|
|
|
22
22
|
* Callback used before saving, after validation.
|
|
23
23
|
* You can modify the value before it's saved.
|
|
24
24
|
*/
|
|
25
|
-
beforeSave?(props: Omit<
|
|
25
|
+
beforeSave?(props: Omit<BeforeSaveProps<M, USER>, "values"> & {
|
|
26
26
|
value: T;
|
|
27
27
|
previousValue: T | undefined;
|
|
28
28
|
values: Partial<M>;
|
|
@@ -116,6 +116,31 @@ export interface BaseUIConfig<CustomProps = unknown> {
|
|
|
116
116
|
customProps?: CustomProps;
|
|
117
117
|
Field?: ComponentRef<any>;
|
|
118
118
|
Preview?: ComponentRef<any>;
|
|
119
|
+
/**
|
|
120
|
+
* Narrow the filter operators offered for this property in collection
|
|
121
|
+
* filter UIs (table header filters and the Filters dialog).
|
|
122
|
+
*
|
|
123
|
+
* The final offered set is the **intersection** of the engine's
|
|
124
|
+
* capabilities, the property-type defaults, and this list — you can only
|
|
125
|
+
* *restrict*, never enable an operator the underlying engine cannot run.
|
|
126
|
+
*
|
|
127
|
+
* Pass an empty array to disable filtering on this property entirely.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* // Email column: exact match, contains, and null check only
|
|
131
|
+
* ui: { filterOperators: ["==", "ilike", "is-null"] }
|
|
132
|
+
*/
|
|
133
|
+
filterOperators?: readonly WhereFilterOp[];
|
|
134
|
+
/**
|
|
135
|
+
* Replace the filter field rendered for this property in collection
|
|
136
|
+
* filter UIs. The component receives `FilterFieldBindingProps`
|
|
137
|
+
* (property, resolved `operators`, `value`, `setValue`, …).
|
|
138
|
+
*
|
|
139
|
+
* Takes precedence over the collection-level
|
|
140
|
+
* `components["Collection.FilterField"]` override and the built-in
|
|
141
|
+
* per-type filter fields.
|
|
142
|
+
*/
|
|
143
|
+
Filter?: ComponentRef<any>;
|
|
119
144
|
}
|
|
120
145
|
export interface BaseProperty<CustomProps = unknown> {
|
|
121
146
|
ui?: BaseUIConfig<CustomProps>;
|
|
@@ -150,6 +175,19 @@ export interface BaseProperty<CustomProps = unknown> {
|
|
|
150
175
|
* Rules for validating this property
|
|
151
176
|
*/
|
|
152
177
|
validation?: PropertyValidationSchema;
|
|
178
|
+
/**
|
|
179
|
+
* Never include this column in an API response.
|
|
180
|
+
*
|
|
181
|
+
* For secrets the server must store and read but no client should ever
|
|
182
|
+
* receive — password hashes, verification tokens. The value is still
|
|
183
|
+
* written and queryable server-side; it is stripped from every row the API
|
|
184
|
+
* serves, for every caller, including admins and service keys.
|
|
185
|
+
*
|
|
186
|
+
* This is a server-side guarantee, unlike `ui.hideFromCollection`, which
|
|
187
|
+
* only stops the admin panel from *rendering* a field and leaves it in the
|
|
188
|
+
* JSON payload.
|
|
189
|
+
*/
|
|
190
|
+
excludeFromApi?: boolean;
|
|
153
191
|
/**
|
|
154
192
|
* Use this to define dynamic properties that change based on certain conditions
|
|
155
193
|
* or on the entity's values. For example, you can make a field read-only if
|
|
@@ -414,7 +452,7 @@ export interface ReferenceUIConfig extends BaseUIConfig {
|
|
|
414
452
|
previewProperties?: string[];
|
|
415
453
|
}
|
|
416
454
|
/**
|
|
417
|
-
* A pointer to
|
|
455
|
+
* A pointer to a entity, stored **as a value** on the row (id + path, and
|
|
418
456
|
* optionally a `driver`/`databaseId` for cross-datasource pointers).
|
|
419
457
|
*
|
|
420
458
|
* This is the native primitive of **document databases** — it maps 1:1 to a
|
|
@@ -433,7 +471,7 @@ export interface ReferenceProperty extends BaseProperty {
|
|
|
433
471
|
ui?: ReferenceUIConfig;
|
|
434
472
|
type: "reference";
|
|
435
473
|
/**
|
|
436
|
-
* Default value for new entities. Must be
|
|
474
|
+
* Default value for new entities. Must be a EntityReference.
|
|
437
475
|
*/
|
|
438
476
|
defaultValue?: EntityReference;
|
|
439
477
|
/**
|
|
@@ -494,7 +532,7 @@ export interface RelationProperty extends BaseProperty {
|
|
|
494
532
|
ui?: RelationUIConfig;
|
|
495
533
|
type: "relation";
|
|
496
534
|
/**
|
|
497
|
-
* Default value for new entities. Must be
|
|
535
|
+
* Default value for new entities. Must be a EntityRelation or array of EntityRelation.
|
|
498
536
|
*/
|
|
499
537
|
defaultValue?: EntityRelation | EntityRelation[];
|
|
500
538
|
/**
|
|
@@ -509,7 +547,7 @@ export interface RelationProperty extends BaseProperty {
|
|
|
509
547
|
* When set, the framework treats this property as a self-contained relation
|
|
510
548
|
* definition and no separate `relations[]` entry is needed.
|
|
511
549
|
*/
|
|
512
|
-
target?: string | (() =>
|
|
550
|
+
target?: string | (() => CollectionConfig | string);
|
|
513
551
|
/**
|
|
514
552
|
* Whether this property references one or many records.
|
|
515
553
|
* Defaults to `"one"`.
|
|
@@ -567,7 +605,7 @@ export interface RelationProperty extends BaseProperty {
|
|
|
567
605
|
/**
|
|
568
606
|
* Overrides applied to the target collection when rendered as a subcollection tab.
|
|
569
607
|
*/
|
|
570
|
-
overrides?: Partial<
|
|
608
|
+
overrides?: Partial<CollectionConfig>;
|
|
571
609
|
/**
|
|
572
610
|
* Optional name for this relation. Defaults to the property key at runtime.
|
|
573
611
|
* Only needed when the relation name should differ from the property key,
|
|
@@ -879,6 +917,13 @@ export type StorageConfig = {
|
|
|
879
917
|
* When omitted, the default storage source is used.
|
|
880
918
|
*/
|
|
881
919
|
storageSource?: string;
|
|
920
|
+
/**
|
|
921
|
+
* Store files for this property as **public**: they are placed under the
|
|
922
|
+
* public prefix and served via stable, token-less, permanent, CDN-cacheable
|
|
923
|
+
* URLs (safe to persist and hotlink). Use for public assets like avatars or
|
|
924
|
+
* storefront images. Defaults to `false` (private, short-lived signed URLs).
|
|
925
|
+
*/
|
|
926
|
+
public?: boolean;
|
|
882
927
|
/**
|
|
883
928
|
* File MIME types that can be uploaded to this reference. Don't specify for
|
|
884
929
|
* all.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CollectionConfig } from "./collections";
|
|
2
2
|
/**
|
|
3
3
|
* @group Models
|
|
4
4
|
*/
|
|
@@ -17,7 +17,7 @@ export interface Relation {
|
|
|
17
17
|
/**
|
|
18
18
|
* The final collection you want to retrieve records from.
|
|
19
19
|
*/
|
|
20
|
-
target: (() =>
|
|
20
|
+
target: (() => CollectionConfig) | any;
|
|
21
21
|
/**
|
|
22
22
|
* The nature of the relationship, determining if one or many records are returned.
|
|
23
23
|
*/
|
|
@@ -270,7 +270,7 @@ export interface Relation {
|
|
|
270
270
|
* Action to perform on delete.
|
|
271
271
|
*/
|
|
272
272
|
onDelete?: OnAction;
|
|
273
|
-
overrides?: Partial<
|
|
273
|
+
overrides?: Partial<CollectionConfig>;
|
|
274
274
|
validation?: {
|
|
275
275
|
required?: boolean;
|
|
276
276
|
};
|
package/dist/types/slots.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { CollectionActionsProps, EntityTableController, SelectionController,
|
|
2
|
+
import type { CollectionActionsProps, EntityTableController, SelectionController, CollectionConfig } from "./collections";
|
|
3
3
|
import type { Entity } from "./entities";
|
|
4
4
|
import type { PluginFormActionProps, PluginGenericProps, PluginHomePageActionsProps, PluginHomePageAdditionalCardsProps } from "./plugins";
|
|
5
5
|
import type { Property } from "./properties";
|
|
@@ -99,7 +99,7 @@ export interface NavigationSlotProps {
|
|
|
99
99
|
*/
|
|
100
100
|
export interface CollectionToolbarProps {
|
|
101
101
|
path: string;
|
|
102
|
-
collection:
|
|
102
|
+
collection: CollectionConfig;
|
|
103
103
|
parentCollectionSlugs: string[];
|
|
104
104
|
parentEntityIds: string[];
|
|
105
105
|
tableController: EntityTableController;
|
|
@@ -111,7 +111,7 @@ export interface CollectionToolbarProps {
|
|
|
111
111
|
*/
|
|
112
112
|
export interface CollectionEmptyStateProps {
|
|
113
113
|
path: string;
|
|
114
|
-
collection:
|
|
114
|
+
collection: CollectionConfig;
|
|
115
115
|
parentCollectionSlugs: string[];
|
|
116
116
|
parentEntityIds: string[];
|
|
117
117
|
canCreate: boolean;
|
|
@@ -128,7 +128,7 @@ export interface CollectionHeaderActionProps {
|
|
|
128
128
|
parentCollectionSlugs: string[];
|
|
129
129
|
parentEntityIds: string[];
|
|
130
130
|
onHover: boolean;
|
|
131
|
-
collection:
|
|
131
|
+
collection: CollectionConfig;
|
|
132
132
|
tableController: EntityTableController;
|
|
133
133
|
}
|
|
134
134
|
/**
|
|
@@ -139,7 +139,7 @@ export interface CollectionAddColumnProps {
|
|
|
139
139
|
path: string;
|
|
140
140
|
parentCollectionSlugs: string[];
|
|
141
141
|
parentEntityIds: string[];
|
|
142
|
-
collection:
|
|
142
|
+
collection: CollectionConfig;
|
|
143
143
|
tableController: EntityTableController;
|
|
144
144
|
}
|
|
145
145
|
/**
|
|
@@ -148,7 +148,7 @@ export interface CollectionAddColumnProps {
|
|
|
148
148
|
*/
|
|
149
149
|
export interface CollectionErrorProps {
|
|
150
150
|
path: string;
|
|
151
|
-
collection:
|
|
151
|
+
collection: CollectionConfig;
|
|
152
152
|
parentCollectionSlugs?: string[];
|
|
153
153
|
parentEntityIds?: string[];
|
|
154
154
|
error: Error;
|
|
@@ -158,7 +158,7 @@ export interface CollectionErrorProps {
|
|
|
158
158
|
* @group Plugins
|
|
159
159
|
*/
|
|
160
160
|
export interface KanbanSetupProps {
|
|
161
|
-
collection:
|
|
161
|
+
collection: CollectionConfig;
|
|
162
162
|
fullPath: string;
|
|
163
163
|
parentCollectionSlugs: string[];
|
|
164
164
|
parentEntityIds: string[];
|
|
@@ -168,7 +168,7 @@ export interface KanbanSetupProps {
|
|
|
168
168
|
* @group Plugins
|
|
169
169
|
*/
|
|
170
170
|
export interface KanbanAddColumnProps {
|
|
171
|
-
collection:
|
|
171
|
+
collection: CollectionConfig;
|
|
172
172
|
fullPath: string;
|
|
173
173
|
parentCollectionSlugs: string[];
|
|
174
174
|
parentEntityIds: string[];
|
|
@@ -176,14 +176,14 @@ export interface KanbanAddColumnProps {
|
|
|
176
176
|
}
|
|
177
177
|
/**
|
|
178
178
|
* Props for `entity.row.actions` slot.
|
|
179
|
-
* Rendered for each row in
|
|
179
|
+
* Rendered for each row in a entity collection table.
|
|
180
180
|
* @group Plugins
|
|
181
181
|
*/
|
|
182
182
|
export interface EntityRowActionsProps {
|
|
183
183
|
entity: Entity;
|
|
184
184
|
entityId: string;
|
|
185
185
|
path: string;
|
|
186
|
-
collection:
|
|
186
|
+
collection: CollectionConfig;
|
|
187
187
|
parentCollectionSlugs: string[];
|
|
188
188
|
parentEntityIds: string[];
|
|
189
189
|
selectionController: SelectionController;
|
|
@@ -199,7 +199,7 @@ export interface EntityFieldSlotProps {
|
|
|
199
199
|
property: Property;
|
|
200
200
|
path: string;
|
|
201
201
|
entityId?: string | number;
|
|
202
|
-
collection:
|
|
202
|
+
collection: CollectionConfig;
|
|
203
203
|
context: RebaseContext;
|
|
204
204
|
}
|
|
205
205
|
/**
|
|
@@ -209,7 +209,7 @@ export interface EntityFieldSlotProps {
|
|
|
209
209
|
*/
|
|
210
210
|
export interface CollectionFilterPanelProps {
|
|
211
211
|
path: string;
|
|
212
|
-
collection:
|
|
212
|
+
collection: CollectionConfig;
|
|
213
213
|
parentCollectionSlugs: string[];
|
|
214
214
|
parentEntityIds: string[];
|
|
215
215
|
tableController: EntityTableController;
|
|
@@ -246,7 +246,7 @@ export interface ShellToolbarProps {
|
|
|
246
246
|
*/
|
|
247
247
|
export interface CollectionInsightsSlotProps {
|
|
248
248
|
path: string;
|
|
249
|
-
collection:
|
|
249
|
+
collection: CollectionConfig;
|
|
250
250
|
parentCollectionSlugs: string[];
|
|
251
251
|
parentEntityIds: string[];
|
|
252
252
|
}
|
|
@@ -257,6 +257,6 @@ export interface CollectionInsightsSlotProps {
|
|
|
257
257
|
*/
|
|
258
258
|
export interface HomeCardInsightSlotProps {
|
|
259
259
|
slug: string;
|
|
260
|
-
collection:
|
|
260
|
+
collection: CollectionConfig;
|
|
261
261
|
context: RebaseContext;
|
|
262
262
|
}
|
|
@@ -6,7 +6,7 @@ export type DeepPartial<T> = T extends object ? {
|
|
|
6
6
|
[K in keyof T]?: DeepPartial<T[K]>;
|
|
7
7
|
} : T;
|
|
8
8
|
/**
|
|
9
|
-
* All user-visible strings used internally by @rebasepro/
|
|
9
|
+
* All user-visible strings used internally by @rebasepro/app.
|
|
10
10
|
* Pass a `DeepPartial<RebaseTranslations>` via the `translations` prop
|
|
11
11
|
* on your Rebase entry-point component to override any key, or to add
|
|
12
12
|
* a new locale.
|
|
@@ -487,6 +487,7 @@ export interface RebaseTranslations {
|
|
|
487
487
|
invitation_sent_title?: string;
|
|
488
488
|
temporary_password?: string;
|
|
489
489
|
temporary_password_description?: string;
|
|
490
|
+
temporary_password_email_failed_description?: string;
|
|
490
491
|
copy_password?: string;
|
|
491
492
|
password_copied?: string;
|
|
492
493
|
/** UsersView — pagination & search */
|
|
@@ -497,6 +498,9 @@ export interface RebaseTranslations {
|
|
|
497
498
|
reset_password?: string;
|
|
498
499
|
reset_password_success?: string;
|
|
499
500
|
reset_password_confirmation?: string;
|
|
501
|
+
reset_password_send_email?: string;
|
|
502
|
+
reset_password_set_manually?: string;
|
|
503
|
+
reset_password_set_manually_description?: string;
|
|
500
504
|
error_resetting_password?: string;
|
|
501
505
|
/** Permission-denied empty states */
|
|
502
506
|
no_permission_to_view_users?: string;
|
|
@@ -9,8 +9,14 @@ export interface UserCreationResult<USER extends User = User> {
|
|
|
9
9
|
/** Whether an invitation email was sent to the user */
|
|
10
10
|
invitationSent: boolean;
|
|
11
11
|
/**
|
|
12
|
-
* Temporary password
|
|
13
|
-
*
|
|
12
|
+
* Temporary password, present when no invitation email could be delivered —
|
|
13
|
+
* either because no email service is configured, or because delivery failed
|
|
14
|
+
* (see `emailDeliveryFailed`). Returned one-time, to be shared manually.
|
|
14
15
|
*/
|
|
15
16
|
temporaryPassword?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Whether an email service was configured but delivery failed, causing the
|
|
19
|
+
* fallback to `temporaryPassword`. Absent when no email service is configured.
|
|
20
|
+
*/
|
|
21
|
+
emailDeliveryFailed?: boolean;
|
|
16
22
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Entity } from "./entities";
|
|
2
1
|
export interface WebSocketErrorPayload {
|
|
3
2
|
error?: string | {
|
|
4
3
|
message: string;
|
|
@@ -12,32 +11,66 @@ export interface WebSocketMessage {
|
|
|
12
11
|
payload?: unknown;
|
|
13
12
|
subscriptionId?: string;
|
|
14
13
|
requestId?: string;
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
rows?: Record<string, unknown>[];
|
|
15
|
+
row?: Record<string, unknown> | null;
|
|
17
16
|
error?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Channel name, on broadcast and presence frames.
|
|
19
|
+
*
|
|
20
|
+
* These are addressed by channel rather than by `requestId` or
|
|
21
|
+
* `subscriptionId`, so this is the only field that routes them.
|
|
22
|
+
*/
|
|
23
|
+
channel?: string;
|
|
18
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* The key columns a collection's rows are addressed by.
|
|
27
|
+
*
|
|
28
|
+
* A row is exactly its columns and carries no address, so a subscriber that has
|
|
29
|
+
* to recognise one — to patch it, or to keep its reference across a refetch —
|
|
30
|
+
* derives the address from these. The SDK is usable with no collections
|
|
31
|
+
* declared at all, so the server is the only side that knows them.
|
|
32
|
+
*
|
|
33
|
+
* Undefined when the server cannot resolve them: a table with no primary key
|
|
34
|
+
* and no `id` column has no address, and rows of it cannot be recognised by
|
|
35
|
+
* anyone.
|
|
36
|
+
*/
|
|
37
|
+
export type WirePrimaryKeys = {
|
|
38
|
+
fieldName: string;
|
|
39
|
+
type: "string" | "number";
|
|
40
|
+
isUUID?: boolean;
|
|
41
|
+
}[];
|
|
19
42
|
export interface CollectionUpdateMessage extends WebSocketMessage {
|
|
20
43
|
type: "collection_update";
|
|
21
44
|
subscriptionId: string;
|
|
22
|
-
|
|
45
|
+
rows: Record<string, unknown>[];
|
|
46
|
+
/**
|
|
47
|
+
* See {@link WirePrimaryKeys}. Sent with the rows themselves — and not only
|
|
48
|
+
* with a patch — because a CDC-originated change sends no patch at all: it
|
|
49
|
+
* invalidates and goes straight to a refetch, and the merge that preserves
|
|
50
|
+
* unchanged rows' references needs an address to match them by.
|
|
51
|
+
*/
|
|
52
|
+
pks?: WirePrimaryKeys;
|
|
23
53
|
}
|
|
24
|
-
export interface
|
|
25
|
-
type: "
|
|
54
|
+
export interface SingleUpdateMessage extends WebSocketMessage {
|
|
55
|
+
type: "single_update";
|
|
26
56
|
subscriptionId: string;
|
|
27
|
-
|
|
57
|
+
row: Record<string, unknown> | null;
|
|
28
58
|
}
|
|
29
59
|
/**
|
|
30
60
|
* Lightweight patch message sent to collection subscribers when a single
|
|
31
|
-
*
|
|
61
|
+
* row is created, updated, or deleted. The client can merge this into
|
|
32
62
|
* its cached collection data for near-instant cross-tab updates without
|
|
33
63
|
* waiting for a full collection refetch.
|
|
34
64
|
*/
|
|
35
|
-
export interface
|
|
36
|
-
type: "
|
|
65
|
+
export interface CollectionPatchMessage extends WebSocketMessage {
|
|
66
|
+
type: "collection_patch";
|
|
37
67
|
subscriptionId: string;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
68
|
+
/** The address of the row this patch refers to — derived, never read off it. */
|
|
69
|
+
id: string;
|
|
70
|
+
/** The updated row, or null if deleted */
|
|
71
|
+
row: Record<string, unknown> | null;
|
|
72
|
+
/** See {@link WirePrimaryKeys}: how the subscriber finds {@link id} in its cache. */
|
|
73
|
+
pks?: WirePrimaryKeys;
|
|
41
74
|
}
|
|
42
75
|
/**
|
|
43
76
|
* Column metadata returned by table introspection.
|
package/dist/users/user.d.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* and
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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/app` 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
|
-
*
|
|
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
|
/**
|