@rebasepro/types 0.8.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 (78) hide show
  1. package/README.md +10 -10
  2. package/dist/controllers/auth.d.ts +1 -1
  3. package/dist/controllers/client.d.ts +184 -6
  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 +267 -35
  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 -4
  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 +142 -15
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.umd.js +150 -17
  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 +4 -1
  22. package/dist/types/backend.d.ts +26 -26
  23. package/dist/types/builders.d.ts +2 -2
  24. package/dist/types/collections.d.ts +62 -63
  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 +15 -2
  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 +39 -39
  32. package/dist/types/entity_views.d.ts +3 -3
  33. package/dist/types/filter-operators.d.ts +62 -17
  34. package/dist/types/modify_collections.d.ts +2 -2
  35. package/dist/types/plugins.d.ts +9 -9
  36. package/dist/types/policy.d.ts +64 -10
  37. package/dist/types/properties.d.ts +41 -9
  38. package/dist/types/relations.d.ts +3 -3
  39. package/dist/types/slots.d.ts +14 -14
  40. package/dist/types/websockets.d.ts +12 -13
  41. package/dist/users/user.d.ts +21 -9
  42. package/package.json +1 -1
  43. package/src/controllers/auth.tsx +1 -1
  44. package/src/controllers/client.ts +214 -6
  45. package/src/controllers/collection_registry.ts +3 -3
  46. package/src/controllers/customization_controller.tsx +1 -1
  47. package/src/controllers/data.ts +290 -39
  48. package/src/controllers/data_driver.ts +49 -40
  49. package/src/controllers/index.ts +1 -1
  50. package/src/controllers/local_config_persistence.tsx +4 -4
  51. package/src/controllers/navigation.ts +2 -2
  52. package/src/controllers/registry.ts +18 -4
  53. package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
  54. package/src/controllers/storage.ts +60 -1
  55. package/src/errors.ts +80 -0
  56. package/src/index.ts +1 -0
  57. package/src/rebase_context.tsx +8 -4
  58. package/src/types/auth_adapter.ts +4 -1
  59. package/src/types/backend.ts +36 -36
  60. package/src/types/builders.ts +2 -2
  61. package/src/types/collections.ts +78 -79
  62. package/src/types/component_overrides.ts +72 -5
  63. package/src/types/cron.ts +10 -1
  64. package/src/types/data_source.ts +24 -2
  65. package/src/types/database_adapter.ts +4 -3
  66. package/src/types/entities.ts +7 -7
  67. package/src/types/entity_actions.tsx +7 -7
  68. package/src/types/entity_callbacks.ts +42 -42
  69. package/src/types/entity_views.tsx +3 -3
  70. package/src/types/filter-operators.ts +96 -23
  71. package/src/types/modify_collections.tsx +2 -2
  72. package/src/types/plugins.tsx +9 -9
  73. package/src/types/policy.ts +64 -8
  74. package/src/types/properties.ts +44 -9
  75. package/src/types/relations.ts +3 -3
  76. package/src/types/slots.tsx +14 -14
  77. package/src/types/websockets.ts +12 -14
  78. package/src/users/user.ts +22 -9
@@ -1,5 +1,5 @@
1
1
  import React, { PropsWithChildren } from "react";
2
- import type { EntityCollection } from "./collections";
2
+ import type { CollectionConfig } from "./collections";
3
3
  import type { EntityStatus } from "./entities";
4
4
  import type { InferPropertyType, Property } from "./properties";
5
5
  import type { FormContext } from "./entity_views";
@@ -136,17 +136,17 @@ export interface PluginHooks {
136
136
  /**
137
137
  * Modify a single collection before it is rendered (synchronous).
138
138
  */
139
- modifyCollection?: (collection: EntityCollection) => EntityCollection;
139
+ modifyCollection?: (collection: CollectionConfig) => CollectionConfig;
140
140
  /**
141
141
  * Async version of modifyCollection — supports fetching remote config.
142
142
  * Runs during navigation resolution. If provided alongside `modifyCollection`,
143
143
  * the sync version runs first, then the async version.
144
144
  */
145
- modifyCollectionAsync?: (collection: EntityCollection) => Promise<EntityCollection>;
145
+ modifyCollectionAsync?: (collection: CollectionConfig) => Promise<CollectionConfig>;
146
146
  /**
147
147
  * Modify, add or remove collections.
148
148
  */
149
- injectCollections?: (collections: EntityCollection[]) => EntityCollection[];
149
+ injectCollections?: (collections: CollectionConfig[]) => CollectionConfig[];
150
150
  /**
151
151
  * Callback called when columns are reordered via drag and drop.
152
152
  */
@@ -154,7 +154,7 @@ export interface PluginHooks {
154
154
  fullPath: string;
155
155
  parentCollectionSlugs: string[];
156
156
  parentEntityIds: string[];
157
- collection: EntityCollection;
157
+ collection: CollectionConfig;
158
158
  newPropertiesOrder: string[];
159
159
  }) => void;
160
160
  /**
@@ -164,7 +164,7 @@ export interface PluginHooks {
164
164
  fullPath: string;
165
165
  parentCollectionSlugs: string[];
166
166
  parentEntityIds: string[];
167
- collection: EntityCollection;
167
+ collection: CollectionConfig;
168
168
  kanbanColumnProperty: string;
169
169
  newColumnsOrder: string[];
170
170
  }) => void;
@@ -226,7 +226,7 @@ export interface FieldBuilderConfig {
226
226
  * Props passed to home page collection card action components.
227
227
  * @group Models
228
228
  */
229
- export interface PluginHomePageActionsProps<EP extends object = object, M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User, EC extends EntityCollection<M> = EntityCollection<M>> {
229
+ export interface PluginHomePageActionsProps<EP extends object = object, M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User, EC extends CollectionConfig<M> = CollectionConfig<M>> {
230
230
  slug: string;
231
231
  collection: EC;
232
232
  context: RebaseContext<USER>;
@@ -235,7 +235,7 @@ export interface PluginHomePageActionsProps<EP extends object = object, M extend
235
235
  * Props passed to form action components in entity edit/form views.
236
236
  * @group Models
237
237
  */
238
- export interface PluginFormActionProps<USER extends User = User, EC extends EntityCollection = EntityCollection> {
238
+ export interface PluginFormActionProps<USER extends User = User, EC extends CollectionConfig = CollectionConfig> {
239
239
  entityId?: string | number;
240
240
  path: string;
241
241
  parentCollectionSlugs: string[];
@@ -251,7 +251,7 @@ export interface PluginFormActionProps<USER extends User = User, EC extends Enti
251
251
  * Parameters passed to the field builder wrap function.
252
252
  * @group Models
253
253
  */
254
- export type PluginFieldBuilderParams<M extends Record<string, unknown> = Record<string, unknown>, EC extends EntityCollection<M> = EntityCollection<M>> = {
254
+ export type PluginFieldBuilderParams<M extends Record<string, unknown> = Record<string, unknown>, EC extends CollectionConfig<M> = CollectionConfig<M>> = {
255
255
  fieldConfigId: string;
256
256
  propertyKey: string;
257
257
  property: Property;
@@ -17,7 +17,7 @@
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 | ExistsInPolicyExpression | RawPolicyExpression;
21
21
  /** Always allows. Compiles to `true`. @group Models */
22
22
  export interface TruePolicyExpression {
23
23
  kind: "true";
@@ -29,12 +29,12 @@ export interface FalsePolicyExpression {
29
29
  /** Logical AND — every operand must pass. @group Models */
30
30
  export interface AndPolicyExpression {
31
31
  kind: "and";
32
- operands: PolicyExpression[];
32
+ operands: readonly PolicyExpression[];
33
33
  }
34
34
  /** Logical OR — at least one operand must pass. @group Models */
35
35
  export interface OrPolicyExpression {
36
36
  kind: "or";
37
- operands: PolicyExpression[];
37
+ operands: readonly PolicyExpression[];
38
38
  }
39
39
  /** Logical negation. @group Models */
40
40
  export interface NotPolicyExpression {
@@ -60,7 +60,7 @@ export interface ComparePolicyExpression {
60
60
  */
61
61
  export interface RolesOverlapPolicyExpression {
62
62
  kind: "rolesOverlap";
63
- roles: string[];
63
+ roles: readonly string[];
64
64
  }
65
65
  /**
66
66
  * True when the user holds *all* of the given application roles.
@@ -69,7 +69,7 @@ export interface RolesOverlapPolicyExpression {
69
69
  */
70
70
  export interface RolesContainPolicyExpression {
71
71
  kind: "rolesContain";
72
- roles: string[];
72
+ roles: readonly string[];
73
73
  }
74
74
  /**
75
75
  * True when there is an authenticated user (`auth.uid() IS NOT NULL`).
@@ -78,6 +78,44 @@ export interface RolesContainPolicyExpression {
78
78
  export interface AuthenticatedPolicyExpression {
79
79
  kind: "authenticated";
80
80
  }
81
+ /**
82
+ * Membership / relational access: true when at least one row exists in another
83
+ * collection (a join/membership table) matching `where`. This is what lets you
84
+ * scope reads to "rows whose team the caller belongs to" without an N+1
85
+ * per-row lookup — it compiles to a single correlated `EXISTS` subquery.
86
+ *
87
+ * Inside `where`, {@link FieldPolicyOperand} (`policy.field`) references a column
88
+ * of the joined collection, while {@link OuterFieldPolicyOperand}
89
+ * (`policy.outerField`) references a column of the row being checked (the outer
90
+ * table under RLS). Combine with {@link AuthUidPolicyOperand} to correlate to
91
+ * the caller.
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * // documents visible only to members of the document's team:
96
+ * policy.existsIn({
97
+ * collection: "team_members",
98
+ * where: policy.and(
99
+ * policy.compare(policy.field("team_id"), "eq", policy.outerField("team_id")),
100
+ * policy.compare(policy.field("user_id"), "eq", policy.authUid()),
101
+ * ),
102
+ * })
103
+ * // → EXISTS (SELECT 1 FROM team_members _ex0
104
+ * // WHERE _ex0.team_id = documents.team_id AND _ex0.user_id = auth.uid())
105
+ * ```
106
+ *
107
+ * Postgres-authoritative: like {@link RawPolicyExpression}, the JavaScript
108
+ * evaluator treats it as *unknown* (it cannot run a subquery client-side), so
109
+ * enforcement is always the database's.
110
+ * @group Models
111
+ */
112
+ export interface ExistsInPolicyExpression {
113
+ kind: "existsIn";
114
+ /** Slug of the collection to search (the join / membership table). */
115
+ collection: string;
116
+ /** Condition evaluated against the joined collection's rows. */
117
+ where: PolicyExpression;
118
+ }
81
119
  /**
82
120
  * A raw PostgreSQL boolean expression — the full-power escape hatch.
83
121
  *
@@ -94,13 +132,24 @@ export interface RawPolicyExpression {
94
132
  * An operand referenced by a {@link ComparePolicyExpression}.
95
133
  * @group Models
96
134
  */
97
- export type PolicyOperand = FieldPolicyOperand | LiteralPolicyOperand | AuthUidPolicyOperand | AuthRolesPolicyOperand;
135
+ export type PolicyOperand = FieldPolicyOperand | OuterFieldPolicyOperand | LiteralPolicyOperand | AuthUidPolicyOperand | AuthRolesPolicyOperand;
98
136
  /** A column value on the row being evaluated. @group Models */
99
137
  export interface FieldPolicyOperand {
100
138
  kind: "field";
101
139
  /** The property/column name (resolved to its DB column when compiled). */
102
140
  name: string;
103
141
  }
142
+ /**
143
+ * A column value on the *outer* row when used inside {@link ExistsInPolicyExpression}
144
+ * — i.e. the row the RLS policy is being evaluated for, referenced from within the
145
+ * subquery. Outside an `existsIn` it is equivalent to {@link FieldPolicyOperand}.
146
+ * @group Models
147
+ */
148
+ export interface OuterFieldPolicyOperand {
149
+ kind: "outerField";
150
+ /** The property/column name on the outer collection. */
151
+ name: string;
152
+ }
104
153
  /** A constant value. @group Models */
105
154
  export interface LiteralPolicyOperand {
106
155
  kind: "literal";
@@ -122,15 +171,20 @@ export interface AuthRolesPolicyOperand {
122
171
  export declare const policy: {
123
172
  true: () => TruePolicyExpression;
124
173
  false: () => FalsePolicyExpression;
125
- and: (...operands: PolicyExpression[]) => AndPolicyExpression;
126
- or: (...operands: PolicyExpression[]) => OrPolicyExpression;
174
+ and: (...operands: readonly PolicyExpression[]) => AndPolicyExpression;
175
+ or: (...operands: readonly PolicyExpression[]) => OrPolicyExpression;
127
176
  not: (operand: PolicyExpression) => NotPolicyExpression;
128
177
  compare: (left: PolicyOperand, op: PolicyCompareOperator, right: PolicyOperand) => ComparePolicyExpression;
129
- rolesOverlap: (roles: string[]) => RolesOverlapPolicyExpression;
130
- rolesContain: (roles: string[]) => RolesContainPolicyExpression;
178
+ rolesOverlap: (roles: readonly string[]) => RolesOverlapPolicyExpression;
179
+ rolesContain: (roles: readonly string[]) => RolesContainPolicyExpression;
131
180
  authenticated: () => AuthenticatedPolicyExpression;
181
+ existsIn: (args: {
182
+ collection: string;
183
+ where: PolicyExpression;
184
+ }) => ExistsInPolicyExpression;
132
185
  raw: (sql: string) => RawPolicyExpression;
133
186
  field: (name: string) => FieldPolicyOperand;
187
+ outerField: (name: string) => OuterFieldPolicyOperand;
134
188
  literal: (value: string | number | boolean | null) => LiteralPolicyOperand;
135
189
  authUid: () => AuthUidPolicyOperand;
136
190
  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 { EntityCollection, FilterValues } from "./collections";
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 { EntityAfterReadProps, EntityBeforeSaveProps } from "./entity_callbacks";
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<EntityAfterReadProps<M, USER>, "entity"> & {
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<EntityBeforeSaveProps<M, USER>, "values"> & {
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>;
@@ -414,7 +439,7 @@ export interface ReferenceUIConfig extends BaseUIConfig {
414
439
  previewProperties?: string[];
415
440
  }
416
441
  /**
417
- * A pointer to an entity, stored **as a value** on the row (id + path, and
442
+ * A pointer to a entity, stored **as a value** on the row (id + path, and
418
443
  * optionally a `driver`/`databaseId` for cross-datasource pointers).
419
444
  *
420
445
  * This is the native primitive of **document databases** — it maps 1:1 to a
@@ -433,7 +458,7 @@ export interface ReferenceProperty extends BaseProperty {
433
458
  ui?: ReferenceUIConfig;
434
459
  type: "reference";
435
460
  /**
436
- * Default value for new entities. Must be an EntityReference.
461
+ * Default value for new entities. Must be a EntityReference.
437
462
  */
438
463
  defaultValue?: EntityReference;
439
464
  /**
@@ -494,7 +519,7 @@ export interface RelationProperty extends BaseProperty {
494
519
  ui?: RelationUIConfig;
495
520
  type: "relation";
496
521
  /**
497
- * Default value for new entities. Must be an EntityRelation or array of EntityRelation.
522
+ * Default value for new entities. Must be a EntityRelation or array of EntityRelation.
498
523
  */
499
524
  defaultValue?: EntityRelation | EntityRelation[];
500
525
  /**
@@ -509,7 +534,7 @@ export interface RelationProperty extends BaseProperty {
509
534
  * When set, the framework treats this property as a self-contained relation
510
535
  * definition and no separate `relations[]` entry is needed.
511
536
  */
512
- target?: string | (() => EntityCollection | string);
537
+ target?: string | (() => CollectionConfig | string);
513
538
  /**
514
539
  * Whether this property references one or many records.
515
540
  * Defaults to `"one"`.
@@ -567,7 +592,7 @@ export interface RelationProperty extends BaseProperty {
567
592
  /**
568
593
  * Overrides applied to the target collection when rendered as a subcollection tab.
569
594
  */
570
- overrides?: Partial<EntityCollection>;
595
+ overrides?: Partial<CollectionConfig>;
571
596
  /**
572
597
  * Optional name for this relation. Defaults to the property key at runtime.
573
598
  * Only needed when the relation name should differ from the property key,
@@ -879,6 +904,13 @@ export type StorageConfig = {
879
904
  * When omitted, the default storage source is used.
880
905
  */
881
906
  storageSource?: string;
907
+ /**
908
+ * Store files for this property as **public**: they are placed under the
909
+ * public prefix and served via stable, token-less, permanent, CDN-cacheable
910
+ * URLs (safe to persist and hotlink). Use for public assets like avatars or
911
+ * storefront images. Defaults to `false` (private, short-lived signed URLs).
912
+ */
913
+ public?: boolean;
882
914
  /**
883
915
  * File MIME types that can be uploaded to this reference. Don't specify for
884
916
  * all.
@@ -1,4 +1,4 @@
1
- import type { EntityCollection } from "./collections";
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: (() => EntityCollection) | any;
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<EntityCollection>;
273
+ overrides?: Partial<CollectionConfig>;
274
274
  validation?: {
275
275
  required?: boolean;
276
276
  };
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import type { CollectionActionsProps, EntityTableController, SelectionController, EntityCollection } from "./collections";
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: EntityCollection;
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: EntityCollection;
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: EntityCollection;
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: EntityCollection;
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: EntityCollection;
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: EntityCollection;
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: EntityCollection;
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 an entity collection table.
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: EntityCollection;
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: EntityCollection;
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: EntityCollection;
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: EntityCollection;
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: EntityCollection;
260
+ collection: CollectionConfig;
261
261
  context: RebaseContext;
262
262
  }
@@ -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,32 @@ export interface WebSocketMessage {
12
11
  payload?: unknown;
13
12
  subscriptionId?: string;
14
13
  requestId?: string;
15
- entities?: Entity<Record<string, unknown>>[];
16
- entity?: Entity<Record<string, unknown>> | null;
14
+ rows?: Record<string, unknown>[];
15
+ row?: Record<string, unknown> | null;
17
16
  error?: string;
18
17
  }
19
18
  export interface CollectionUpdateMessage extends WebSocketMessage {
20
19
  type: "collection_update";
21
20
  subscriptionId: string;
22
- entities: Entity<Record<string, unknown>>[];
21
+ rows: Record<string, unknown>[];
23
22
  }
24
- export interface EntityUpdateMessage extends WebSocketMessage {
25
- type: "entity_update";
23
+ export interface SingleUpdateMessage extends WebSocketMessage {
24
+ type: "single_update";
26
25
  subscriptionId: string;
27
- entity: Entity<Record<string, unknown>> | null;
26
+ row: Record<string, unknown> | null;
28
27
  }
29
28
  /**
30
29
  * Lightweight patch message sent to collection subscribers when a single
31
- * entity is created, updated, or deleted. The client can merge this into
30
+ * row is created, updated, or deleted. The client can merge this into
32
31
  * its cached collection data for near-instant cross-tab updates without
33
32
  * waiting for a full collection refetch.
34
33
  */
35
- export interface CollectionEntityPatchMessage extends WebSocketMessage {
36
- type: "collection_entity_patch";
34
+ export interface CollectionPatchMessage extends WebSocketMessage {
35
+ type: "collection_patch";
37
36
  subscriptionId: string;
38
- entityId: string;
39
- /** The updated entity, or null if deleted */
40
- entity: Entity<Record<string, unknown>> | null;
37
+ id: string;
38
+ /** The updated row, or null if deleted */
39
+ row: Record<string, unknown> | null;
41
40
  }
42
41
  /**
43
42
  * Column metadata returned by table introspection.
@@ -1,10 +1,17 @@
1
1
  /**
2
- * This interface represents a user.
3
- * It has some of the same fields as a Firebase User.
4
- * Note that in the default implementation, we simply take the Firebase user
5
- * and use it as a Rebase user, so that means that even if they are not mapped
6
- * in this interface, it contains all the methods of the former, such as `delete`,
7
- * `getIdToken`, etc.
2
+ * The canonical representation of an authenticated user in the Rebase ecosystem.
3
+ *
4
+ * Used by {@link AuthController}, collections, callbacks, and both the
5
+ * `@rebasepro/client` and `@rebasepro/auth` packages. All other user types
6
+ * (`RebaseUser`, `UserInfo`) are deprecated aliases of this type.
7
+ *
8
+ * **Backend-managed fields** (`uid`, `email`, `roles`, `metadata`, `createdAt`)
9
+ * are populated by the server. **Client-visible fields** (`displayName`,
10
+ * `photoURL`, `providerId`, `isAnonymous`, `emailVerified`) may be set during
11
+ * authentication or profile updates.
12
+ *
13
+ * @see AdminUser — the admin-API DTO, which adds audit fields (`createdAt`,
14
+ * `updatedAt`) and required `roles`.
8
15
  *
9
16
  * @group Models
10
17
  */
@@ -26,15 +33,20 @@ export type User = {
26
33
  */
27
34
  readonly photoURL: string | null;
28
35
  /**
29
- * The provider used to authenticate the user.
36
+ * The provider used to authenticate the user (e.g. `"password"`,
37
+ * `"google"`, `"github"`).
30
38
  */
31
39
  readonly providerId: string;
32
40
  /**
33
- *
41
+ * Whether the user is anonymous (created via anonymous sign-in).
34
42
  */
35
43
  readonly isAnonymous: boolean;
36
44
  /**
37
- * Role IDs assigned to this user (e.g. ["admin", "editor"]).
45
+ * Whether the user's email address has been verified.
46
+ */
47
+ readonly emailVerified?: boolean;
48
+ /**
49
+ * Role IDs assigned to this user (e.g. `["admin", "editor"]`).
38
50
  */
39
51
  roles?: string[];
40
52
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rebasepro/types",
3
3
  "type": "module",
4
- "version": "0.8.0",
4
+ "version": "0.9.0",
5
5
  "description": "Rebase type definitions — shared interfaces and controller types",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/rebaseco"
@@ -89,7 +89,7 @@ export type AuthController<USER extends User = User, ExtraData = unknown> = {
89
89
 
90
90
  /**
91
91
  * Extended auth controller with common optional auth methods.
92
- * Backend implementations (Rebase backend, Firebase, Supabase, etc.)
92
+ * Backend implementations (Rebase backend, Firebase, etc.)
93
93
  * extend this with their own backend-specific extras.
94
94
  * @group Hooks and utilities
95
95
  */