@rebasepro/types 0.17.3 → 0.18.1
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 +4 -0
- package/dist/call_context.d.ts +20 -0
- package/dist/controllers/client.d.ts +36 -4
- package/dist/controllers/data.d.ts +120 -10
- package/dist/errors.d.ts +83 -4
- package/dist/index.es.js +522 -160
- package/dist/index.es.js.map +1 -1
- package/dist/types/admin_block.d.ts +2 -2
- package/dist/types/auth_adapter.d.ts +41 -6
- package/dist/types/backend.d.ts +48 -0
- package/dist/types/collections.d.ts +25 -1
- package/dist/types/cron.d.ts +34 -0
- package/dist/types/database_adapter.d.ts +39 -0
- package/dist/types/entity_callbacks.d.ts +14 -1
- package/dist/types/filter-operators.d.ts +24 -1
- package/dist/types/policy.d.ts +29 -1
- package/dist/types/properties.d.ts +216 -3
- package/dist/types/relations.d.ts +65 -7
- package/dist/types/resource_kinds.d.ts +173 -17
- package/dist/types/resources.d.ts +108 -7
- package/dist/types/rls-functions.d.ts +11 -0
- package/dist/types/storage_source.d.ts +12 -23
- package/package.json +24 -23
- package/src/call_context.ts +0 -120
- package/src/controllers/auth_state.ts +0 -24
- package/src/controllers/client.ts +0 -494
- package/src/controllers/collection_registry.ts +0 -62
- package/src/controllers/data.ts +0 -1012
- package/src/controllers/data_driver.ts +0 -576
- package/src/controllers/effective_role.ts +0 -4
- package/src/controllers/email.ts +0 -91
- package/src/controllers/index.ts +0 -11
- package/src/controllers/storage.ts +0 -252
- package/src/errors.ts +0 -119
- package/src/index.ts +0 -5
- package/src/types/admin_block.ts +0 -209
- package/src/types/api_keys.ts +0 -108
- package/src/types/auth_adapter.ts +0 -580
- package/src/types/backend.ts +0 -987
- package/src/types/backup.ts +0 -26
- package/src/types/channel_bus.ts +0 -202
- package/src/types/chips.ts +0 -34
- package/src/types/collection_contract.ts +0 -278
- package/src/types/collections.ts +0 -763
- package/src/types/component_ref.ts +0 -92
- package/src/types/cron.ts +0 -213
- package/src/types/data_source.ts +0 -357
- package/src/types/database_adapter.ts +0 -267
- package/src/types/entities.ts +0 -226
- package/src/types/entity_callbacks.ts +0 -229
- package/src/types/filter-operators.ts +0 -444
- package/src/types/history.ts +0 -66
- package/src/types/index.ts +0 -36
- package/src/types/indexes.ts +0 -180
- package/src/types/policy.ts +0 -328
- package/src/types/postgres_introspection.ts +0 -101
- package/src/types/project_manifest.ts +0 -598
- package/src/types/properties.ts +0 -1368
- package/src/types/relations.ts +0 -417
- package/src/types/resource_kinds.ts +0 -390
- package/src/types/resources.ts +0 -368
- package/src/types/rls-functions.ts +0 -98
- package/src/types/schema_editing.ts +0 -157
- package/src/types/schema_version.ts +0 -112
- package/src/types/search.ts +0 -247
- package/src/types/security_rules.ts +0 -344
- package/src/types/storage_authorize.ts +0 -77
- package/src/types/storage_source.ts +0 -248
- package/src/types/websockets.ts +0 -117
- package/src/users/index.ts +0 -2
- package/src/users/user.ts +0 -69
package/src/types/collections.ts
DELETED
|
@@ -1,763 +0,0 @@
|
|
|
1
|
-
import type { CollectionCallbacks } from "./entity_callbacks";
|
|
2
|
-
|
|
3
|
-
import type { EnumValues, Properties, PostgresProperties, FirebaseProperties, MongoProperties } from "./properties";
|
|
4
|
-
|
|
5
|
-
import type { User } from "../users";
|
|
6
|
-
import type { EmailSendResult } from "../controllers/email";
|
|
7
|
-
import type { Relation } from "./relations";
|
|
8
|
-
import type { SecurityRule } from "./security_rules";
|
|
9
|
-
import { getDataSourceCapabilities } from "./data_source";
|
|
10
|
-
import type { WhereFilterOp, FilterValues, FilterPreset } from "./filter-operators";
|
|
11
|
-
import type { SearchConfig } from "./search";
|
|
12
|
-
import type { CollectionIndex } from "./indexes";
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Base interface containing all driver-agnostic collection properties.
|
|
16
|
-
* Use {@link PostgresCollectionConfig} or {@link FirebaseCollectionConfig} for
|
|
17
|
-
* driver-specific type safety, or {@link CollectionConfig} when you
|
|
18
|
-
* need to handle any collection regardless of backend.
|
|
19
|
-
*
|
|
20
|
-
* @group Models
|
|
21
|
-
*/
|
|
22
|
-
export interface BaseCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> {
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* The collection's identity. Required, and the value nearly everything else
|
|
26
|
-
* keys on:
|
|
27
|
-
*
|
|
28
|
-
* - the REST path — `/api/data/<slug>`
|
|
29
|
-
* - the SDK accessor — `client.data.<slug>` / `client.data.collection("<slug>")`
|
|
30
|
-
* - the admin panel's URL
|
|
31
|
-
* - the target of a `reference` or `relation` property
|
|
32
|
-
*
|
|
33
|
-
* Conventionally kebab-case and plural (`blog-posts`). It is independent of
|
|
34
|
-
* {@link table}: the slug is what callers say, the table is where the rows
|
|
35
|
-
* live, and renaming one does not rename the other.
|
|
36
|
-
*
|
|
37
|
-
* Treat it as frozen once anything has shipped against it — changing a slug
|
|
38
|
-
* changes every URL and every generated accessor at once.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* defineCollection({
|
|
42
|
-
* slug: "blog-posts", // /api/data/blog-posts, client.data.blogPosts
|
|
43
|
-
* table: "posts",
|
|
44
|
-
* properties: { … }
|
|
45
|
-
* })
|
|
46
|
-
*/
|
|
47
|
-
slug: string;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Name of the collection, typically plural.
|
|
51
|
-
* E.g. `Products`, `Blog`
|
|
52
|
-
*/
|
|
53
|
-
name: string;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Singular name of an entry in this collection
|
|
57
|
-
* E.g. `Product`, `Blog entry`
|
|
58
|
-
*/
|
|
59
|
-
singularName?: string;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Optional description of this view. You can use Markdown.
|
|
63
|
-
*/
|
|
64
|
-
description?: string;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Child collections nested under entities of this collection.
|
|
68
|
-
* Populated automatically during normalization from driver-specific fields
|
|
69
|
-
* (e.g. Firebase `subcollections`, Postgres `relations` with many-cardinality).
|
|
70
|
-
*
|
|
71
|
-
* Custom drivers can set this directly to expose child collections to the UI.
|
|
72
|
-
*/
|
|
73
|
-
childCollections?: () => CollectionConfig<Record<string, unknown>>[];
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* The data source this collection belongs to — the routing key shared by
|
|
78
|
-
* the frontend router and the backend driver registry. It points at a
|
|
79
|
-
* {@link DataSourceDefinition} registered on `<Rebase dataSources>` (front)
|
|
80
|
-
* and `initializeRebaseBackend({ dataSources })` (back).
|
|
81
|
-
*
|
|
82
|
-
* If not specified, the default data source `"(default)"` is used, which
|
|
83
|
-
* for a standard Rebase app is the server-mediated Postgres backend.
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* // Default data source (server-mediated Postgres)
|
|
87
|
-
* { slug: "products" }
|
|
88
|
-
*
|
|
89
|
-
* // A direct-transport Firestore data source registered as "analytics"
|
|
90
|
-
* { slug: "events", dataSource: "analytics" }
|
|
91
|
-
*/
|
|
92
|
-
dataSource?: string;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* The database engine backing this collection (`"postgres"`, `"firestore"`,
|
|
96
|
-
* `"mongodb"`, or a custom id).
|
|
97
|
-
*
|
|
98
|
-
* On concrete collection types ({@link PostgresCollectionConfig},
|
|
99
|
-
* {@link FirebaseCollectionConfig}, {@link MongoDBCollectionConfig}) this is a literal
|
|
100
|
-
* discriminant. On the base type it is optional and gets stamped
|
|
101
|
-
* automatically during collection normalization from the registered
|
|
102
|
-
* {@link DataSourceDefinition}.
|
|
103
|
-
*
|
|
104
|
-
* Prefer setting {@link dataSource} and letting the engine be resolved.
|
|
105
|
-
*/
|
|
106
|
-
engine?: string;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Which database within the engine.
|
|
110
|
-
* - For Firestore: The Firestore database ID (e.g., for multi-database projects)
|
|
111
|
-
* - For PostgreSQL: Schema or database name
|
|
112
|
-
* - For MongoDB: Database name
|
|
113
|
-
*
|
|
114
|
-
* If not specified, the default database of the engine is used. Resolved
|
|
115
|
-
* from the collection's {@link DataSourceDefinition} when omitted here.
|
|
116
|
-
*/
|
|
117
|
-
databaseId?: string;
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Set of properties that compose a entity
|
|
121
|
-
*/
|
|
122
|
-
properties: Properties;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Mark this collection as an authentication collection.
|
|
137
|
-
* When true, this collection is used for user management, login, password hashing, and invitation flows.
|
|
138
|
-
*/
|
|
139
|
-
auth?: boolean | AuthCollectionConfig;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Row-level authorization rules for this collection.
|
|
149
|
-
*
|
|
150
|
-
* Driver-agnostic on purpose, unlike `disableDefaultPolicies`, `table` and
|
|
151
|
-
* `relations`, which are declared on {@link PostgresCollectionConfig} only.
|
|
152
|
-
* The rules are a *contract* — who may read or write which rows — and each
|
|
153
|
-
* engine enforces it its own way:
|
|
154
|
-
*
|
|
155
|
-
* - **Postgres** compiles them to real `CREATE POLICY` statements and lets
|
|
156
|
-
* the database enforce them (see {@link PostgresCollectionConfig.securityRules},
|
|
157
|
-
* which narrows this with the raw-SQL details).
|
|
158
|
-
* - **MongoDB** translates them into a query filter it AND-s into every
|
|
159
|
-
* read and write, honouring `access`, `ownerField`, `roles`, `mode` and
|
|
160
|
-
* the `operation`/`operations` selectors, and making a best effort at raw
|
|
161
|
-
* `using`/`withCheck` SQL.
|
|
162
|
-
* - **Firestore** does not implement them at all; its own rules language is
|
|
163
|
-
* evaluated by Google, not from here. `supportsRLS` on
|
|
164
|
-
* {@link DataSourceCapabilities} reports which engines generate policies,
|
|
165
|
-
* which is not the same question as whether an engine honours a rule.
|
|
166
|
-
*/
|
|
167
|
-
securityRules?: readonly SecurityRule[];
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* This interface defines all the callbacks that can be used when a entity
|
|
171
|
-
* is being created, updated or deleted.
|
|
172
|
-
* Useful for adding your own logic or blocking the execution of the operation.
|
|
173
|
-
*/
|
|
174
|
-
readonly callbacks?: CollectionCallbacks<M, USER>;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* User id of the owner of this collection. This is used only by plugins, or if you
|
|
192
|
-
* are writing custom code
|
|
193
|
-
*/
|
|
194
|
-
ownerId?: string;
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Arbitrary key-value metadata for external consumers.
|
|
198
|
-
* Not interpreted by Rebase — passed through serialization unchanged.
|
|
199
|
-
* Used by domain apps to store custom per-collection config.
|
|
200
|
-
*/
|
|
201
|
-
metadata?: Record<string, unknown>;
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* If set to true, changes to the entity will be saved in a subcollection.
|
|
208
|
-
* This prop has no effect if the history plugin is not enabled
|
|
209
|
-
*/
|
|
210
|
-
history?: boolean;
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Whether a write naming a field this collection does not declare is
|
|
214
|
-
* rejected with a 400. Defaults to `true`.
|
|
215
|
-
*
|
|
216
|
-
* Set to `false` where a column really does exist that the config never
|
|
217
|
-
* declared — populated by a trigger, or introspected rather than declared —
|
|
218
|
-
* and callers need to write it. The column still has to exist: the driver
|
|
219
|
-
* checks the key against the table's own columns whatever this is set to,
|
|
220
|
-
* because a key with no column behind it is not passed to the database and
|
|
221
|
-
* refused, it is dropped from the statement and answered 201.
|
|
222
|
-
*
|
|
223
|
-
* It does not let a typo through to Postgres for Postgres to judge. That is
|
|
224
|
-
* what this flag was documented as doing, and no such judgment ever
|
|
225
|
-
* happened.
|
|
226
|
-
*/
|
|
227
|
-
strictWrites?: boolean;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// ── Driver-specific collection types ──────────────────────────────────
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* A collection backed by PostgreSQL (or any SQL database).
|
|
242
|
-
* Adds support for SQL-style relations (JOINs) and Row Level Security.
|
|
243
|
-
*
|
|
244
|
-
* Use this type instead of {@link CollectionConfig} when you want
|
|
245
|
-
* compile-time safety that only SQL-relevant fields appear.
|
|
246
|
-
*
|
|
247
|
-
* @group Models
|
|
248
|
-
*/
|
|
249
|
-
export interface PostgresCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
|
|
250
|
-
extends BaseCollectionConfig<M, USER> {
|
|
251
|
-
properties: PostgresProperties;
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* The database engine for this collection. For Postgres collections this
|
|
255
|
-
* can be omitted (Postgres is the default) or set to `"postgres"`.
|
|
256
|
-
*/
|
|
257
|
-
engine?: "postgres" | undefined;
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* The PostgreSQL table name for this collection.
|
|
261
|
-
*/
|
|
262
|
-
table: string;
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* The PostgreSQL schema name for this table.
|
|
266
|
-
* E.g. "public", "rebase", "auth".
|
|
267
|
-
* If not specified, "public" is used (or the default search path).
|
|
268
|
-
*/
|
|
269
|
-
schema?: string;
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* For SQL databases, you can define the relations between collections here.
|
|
273
|
-
* Relations describe JOINs, foreign keys, and junction tables.
|
|
274
|
-
*/
|
|
275
|
-
relations?: Relation[];
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Security rules for this collection (PostgreSQL Row Level Security).
|
|
279
|
-
* When defined, the schema generator will enable RLS on the table and
|
|
280
|
-
* create the corresponding PostgreSQL policies.
|
|
281
|
-
*
|
|
282
|
-
* Supports three levels of expressiveness:
|
|
283
|
-
* 1. **Convenience shortcuts** — `ownerField`, `access`, `roles`
|
|
284
|
-
* 2. **Raw SQL** — `using` and `withCheck` for full PostgreSQL power
|
|
285
|
-
* 3. **Combined** — mix shortcuts with `roles` for common patterns
|
|
286
|
-
*
|
|
287
|
-
* The authenticated user context is available in raw SQL via:
|
|
288
|
-
* - `rebase.uid()` — the current user's ID
|
|
289
|
-
* - `rebase.roles()` — comma-separated app role IDs
|
|
290
|
-
* - `rebase.jwt()` — full JWT claims as JSONB
|
|
291
|
-
*/
|
|
292
|
-
securityRules?: readonly SecurityRule[];
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Opt out of the framework's default Row Level Security policies.
|
|
296
|
-
*
|
|
297
|
-
* The schema generator automatically injects, for every collection, a
|
|
298
|
-
* baseline SELECT policy granting the trusted server context and the
|
|
299
|
-
* `admin` role read access (reads run under a restricted role, so RLS
|
|
300
|
-
* default-denies without it). For auth collections it additionally injects
|
|
301
|
-
* a self-read policy (`id = rebase.uid()`) and an admin-only write gate
|
|
302
|
-
* (INSERT/UPDATE/DELETE require the `admin` role or the trusted server
|
|
303
|
-
* context), making privileged columns such as `roles` safe by default.
|
|
304
|
-
*
|
|
305
|
-
* Author-defined `securityRules` are permissive and broaden access on top
|
|
306
|
-
* of these defaults. Set this flag to `true` to remove the defaults
|
|
307
|
-
* entirely and take full responsibility for the collection's RLS.
|
|
308
|
-
*
|
|
309
|
-
* @default false
|
|
310
|
-
*/
|
|
311
|
-
disableDefaultPolicies?: boolean;
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Opt in to Postgres full-text search for this collection.
|
|
315
|
-
*
|
|
316
|
-
* Omit it and `.search()` keeps its existing behaviour exactly — an
|
|
317
|
-
* `ILIKE '%term%'` across top-level string properties. Declare it and the
|
|
318
|
-
* collection gains one generated `tsvector` column and a GIN index, and
|
|
319
|
-
* `.search()` compiles to a ranked `@@ websearch_to_tsquery` against them.
|
|
320
|
-
*
|
|
321
|
-
* Postgres-only, like {@link VectorProperty}: the block is rejected at boot
|
|
322
|
-
* on other engines rather than silently ignored.
|
|
323
|
-
*
|
|
324
|
-
* @see SearchConfig
|
|
325
|
-
*/
|
|
326
|
-
search?: SearchConfig;
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Ordinary indexes on this collection's table.
|
|
330
|
-
*
|
|
331
|
-
* Collection-level, not per-property, because an index over two columns
|
|
332
|
-
* has no single property to hang on and a partial index has none at all —
|
|
333
|
-
* and because a second declaration site for the single-column case would
|
|
334
|
-
* put the same object in two places. An index's identity is a column list
|
|
335
|
-
* in an order; the single-column case is a degenerate one, not a special
|
|
336
|
-
* one.
|
|
337
|
-
*
|
|
338
|
-
* `VectorProperty.index` stays where it is: an ANN structure is a property
|
|
339
|
-
* of the column's type, not of a query.
|
|
340
|
-
*
|
|
341
|
-
* Postgres-only, like {@link SearchConfig}: refused on another engine
|
|
342
|
-
* rather than silently ignored.
|
|
343
|
-
*/
|
|
344
|
-
indexes?: readonly CollectionIndex<Extract<keyof M, string>>[];
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* A collection backed by Firebase / Firestore.
|
|
349
|
-
* Adds support for subcollections (nested document collections).
|
|
350
|
-
*
|
|
351
|
-
* Use this type instead of {@link CollectionConfig} when you want
|
|
352
|
-
* compile-time safety that only Firestore-relevant fields appear.
|
|
353
|
-
*
|
|
354
|
-
* @group Models
|
|
355
|
-
*/
|
|
356
|
-
export interface FirebaseCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
|
|
357
|
-
extends BaseCollectionConfig<M, USER> {
|
|
358
|
-
/**
|
|
359
|
-
* The database engine for this collection. Must be set to `"firestore"`.
|
|
360
|
-
*/
|
|
361
|
-
engine: "firestore";
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Set of properties that compose a entity.
|
|
365
|
-
* Firestore collections support `reference` properties but not `relation`.
|
|
366
|
-
*/
|
|
367
|
-
properties: FirebaseProperties;
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* The Firestore collection path to query. Defaults to `slug` if not set.
|
|
371
|
-
* Use this when the Firestore path differs from the slug
|
|
372
|
-
* (e.g., when a PostgreSQL collection already uses the same slug).
|
|
373
|
-
*
|
|
374
|
-
* @example
|
|
375
|
-
* ```typescript
|
|
376
|
-
* const fsCustomer: FirebaseCollectionConfig = {
|
|
377
|
-
* slug: "fs_customer", // URL: /c/fs_customer
|
|
378
|
-
* path: "customer", // Firestore path: customer
|
|
379
|
-
* name: "Customers (Firestore)",
|
|
380
|
-
* engine: "firestore",
|
|
381
|
-
* properties: { ... }
|
|
382
|
-
* };
|
|
383
|
-
* ```
|
|
384
|
-
*/
|
|
385
|
-
path?: string;
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* You can add subcollections to your entity in the same way you define the root
|
|
389
|
-
* collections. The collections added here will be displayed when opening
|
|
390
|
-
* the side dialog of a entity.
|
|
391
|
-
*/
|
|
392
|
-
subcollections?: () => CollectionConfig<Record<string, unknown>>[];
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* A collection backed by MongoDB.
|
|
397
|
-
*
|
|
398
|
-
* Use this type instead of {@link CollectionConfig} when you want
|
|
399
|
-
* compile-time safety that only MongoDB-relevant fields appear.
|
|
400
|
-
*
|
|
401
|
-
* @group Models
|
|
402
|
-
*/
|
|
403
|
-
export interface MongoDBCollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>
|
|
404
|
-
extends BaseCollectionConfig<M, USER> {
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* The database engine for this collection. Must be set to `"mongodb"`.
|
|
408
|
-
*/
|
|
409
|
-
engine: "mongodb";
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* Set of properties that compose a entity.
|
|
413
|
-
* MongoDB collections support `reference` properties but not `relation`.
|
|
414
|
-
*/
|
|
415
|
-
properties: MongoProperties;
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* The MongoDB collection name to use. Defaults to `slug` if not set.
|
|
419
|
-
* Use this when the MongoDB collection name differs from the slug
|
|
420
|
-
* (e.g., when a PostgreSQL collection already uses the same slug).
|
|
421
|
-
*
|
|
422
|
-
* @example
|
|
423
|
-
* ```typescript
|
|
424
|
-
* const mongoCustomer: MongoDBCollectionConfig = {
|
|
425
|
-
* slug: "mongo_customer", // URL: /c/mongo_customer
|
|
426
|
-
* path: "customer", // MongoDB collection: customer
|
|
427
|
-
* name: "Customers (MongoDB)",
|
|
428
|
-
* engine: "mongodb",
|
|
429
|
-
* properties: { ... }
|
|
430
|
-
* };
|
|
431
|
-
* ```
|
|
432
|
-
*/
|
|
433
|
-
path?: string;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* A collection backed by any data source.
|
|
438
|
-
* This is a discriminated union — use {@link PostgresCollectionConfig},
|
|
439
|
-
* {@link FirebaseCollectionConfig}, or {@link MongoDBCollectionConfig} for
|
|
440
|
-
* driver-specific type safety.
|
|
441
|
-
*
|
|
442
|
-
* @group Models
|
|
443
|
-
*/
|
|
444
|
-
export type CollectionConfig<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> =
|
|
445
|
-
| PostgresCollectionConfig<M, USER>
|
|
446
|
-
| FirebaseCollectionConfig<M, USER>
|
|
447
|
-
| MongoDBCollectionConfig<M, USER>;
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* A collection of *any* row type.
|
|
451
|
-
*
|
|
452
|
-
* `CollectionConfig` is **invariant** in `M`: `callbacks` both consumes `M`
|
|
453
|
-
* (`AfterReadProps<M>`) and produces it, so neither direction of assignment
|
|
454
|
-
* holds. `CollectionConfig<SomeRow>` is therefore not assignable to a bare
|
|
455
|
-
* `CollectionConfig`, whose `M` defaults to `Record<string, unknown>`.
|
|
456
|
-
*
|
|
457
|
-
* That matters wherever a collection is merely *referred to* rather than read
|
|
458
|
-
* from. `defineCollection` returns a config whose `M` is inferred from the
|
|
459
|
-
* properties — the whole point of it — so a field typed `() => CollectionConfig`
|
|
460
|
-
* rejects every collection the builder produces, and `target: () => otherCollection`
|
|
461
|
-
* (the documented way to point a relation at its other end) does not compile in
|
|
462
|
-
* any project that uses the builder.
|
|
463
|
-
*
|
|
464
|
-
* `any` is deliberate and is what it is for here: these positions never read the
|
|
465
|
-
* target's rows, they only identify which collection is meant, so there is no
|
|
466
|
-
* type safety to preserve and invariance is pure obstruction.
|
|
467
|
-
*
|
|
468
|
-
* @group Models
|
|
469
|
-
*/
|
|
470
|
-
export type AnyCollectionConfig = CollectionConfig<any, any>;
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* Type guard for PostgreSQL collections.
|
|
474
|
-
* Returns true if the collection uses the Postgres engine (or the default engine).
|
|
475
|
-
*
|
|
476
|
-
* Generic over the *input* type, and narrows by intersection rather than
|
|
477
|
-
* replacement. Narrowing to a bare `PostgresCollectionConfig` discarded whatever
|
|
478
|
-
* the caller actually had — most visibly the admin panel's view model, whose
|
|
479
|
-
* flattened presentation fields vanished the moment a collection passed through
|
|
480
|
-
* one of these guards.
|
|
481
|
-
*
|
|
482
|
-
* @group Models
|
|
483
|
-
*/
|
|
484
|
-
export function isPostgresCollectionConfig<C extends CollectionConfig<any, any>>(
|
|
485
|
-
collection: C
|
|
486
|
-
): collection is C & PostgresCollectionConfig<any, any> {
|
|
487
|
-
return !collection.engine || collection.engine === "postgres";
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Narrows to the SQL collection fields — `table`, `relations`,
|
|
492
|
-
* `disableDefaultPolicies` — by asking the engine's declared capabilities
|
|
493
|
-
* rather than by naming Postgres.
|
|
494
|
-
*
|
|
495
|
-
* The two halves of this already existed and were never joined. The engine
|
|
496
|
-
* split (`PostgresCollectionConfig` / `FirebaseCollectionConfig` /
|
|
497
|
-
* `MongoDBCollectionConfig`) said which fields belong to which engine at the
|
|
498
|
-
* type level; {@link DataSourceCapabilities} said the same thing at runtime,
|
|
499
|
-
* down to a `supportsRelations` flag. So call sites guarded on the capability
|
|
500
|
-
* and then read a field the base type had to declare for them — which is why
|
|
501
|
-
* those fields were on the base, and why a MongoDB collection could be written
|
|
502
|
-
* with a `table`.
|
|
503
|
-
*
|
|
504
|
-
* Prefer this over {@link isPostgresCollectionConfig} wherever the question is
|
|
505
|
-
* "does this collection live in a SQL table", so a custom SQL engine
|
|
506
|
-
* registered through `registerDataSourceCapabilities` is included.
|
|
507
|
-
*
|
|
508
|
-
* @group Models
|
|
509
|
-
*/
|
|
510
|
-
export function isRelationalCollectionConfig<C extends CollectionConfig<any, any>>(
|
|
511
|
-
collection: C
|
|
512
|
-
): collection is C & PostgresCollectionConfig<any, any> {
|
|
513
|
-
return getDataSourceCapabilities(collection.engine).supportsRelations;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
/**
|
|
517
|
-
* Type guard for Firebase / Firestore collections.
|
|
518
|
-
* @group Models
|
|
519
|
-
*/
|
|
520
|
-
export function isFirebaseCollectionConfig<C extends CollectionConfig<any, any>>(
|
|
521
|
-
collection: C
|
|
522
|
-
): collection is C & FirebaseCollectionConfig<any, any> {
|
|
523
|
-
return collection.engine === "firestore";
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/**
|
|
527
|
-
* Type guard for MongoDB collections.
|
|
528
|
-
* @group Models
|
|
529
|
-
*/
|
|
530
|
-
export function isMongoDBCollectionConfig<C extends CollectionConfig<any, any>>(
|
|
531
|
-
collection: C
|
|
532
|
-
): collection is C & MongoDBCollectionConfig<any, any> {
|
|
533
|
-
return collection.engine === "mongodb";
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
/**
|
|
537
|
-
* Returns the data path for a collection.
|
|
538
|
-
* For Firestore or MongoDB collections with a `path`, returns that value;
|
|
539
|
-
* otherwise falls back to `slug`.
|
|
540
|
-
*/
|
|
541
|
-
export function getCollectionDataPath<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
|
|
542
|
-
collection: CollectionConfig<M, USER>
|
|
543
|
-
): string {
|
|
544
|
-
if (isFirebaseCollectionConfig(collection) && collection.path) {
|
|
545
|
-
return collection.path;
|
|
546
|
-
}
|
|
547
|
-
if (isMongoDBCollectionConfig(collection) && collection.path) {
|
|
548
|
-
return collection.path;
|
|
549
|
-
}
|
|
550
|
-
return collection.slug;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
/**
|
|
554
|
-
* Reads a collection's driver-declared subcollections thunk (the `subcollections`
|
|
555
|
-
* field) independent of engine identity, so engine-agnostic code doesn't have to
|
|
556
|
-
* type-guard against a specific driver. Returns `undefined` when the collection
|
|
557
|
-
* declares none.
|
|
558
|
-
*
|
|
559
|
-
* Pair with `getDataSourceCapabilities(engine).supportsSubcollections` to decide
|
|
560
|
-
* whether the engine honours subcollections at all before reading them.
|
|
561
|
-
* @group Models
|
|
562
|
-
*/
|
|
563
|
-
export function getDeclaredSubcollections<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(
|
|
564
|
-
collection: CollectionConfig<M, USER>
|
|
565
|
-
): (() => CollectionConfig<Record<string, unknown>>[]) | undefined {
|
|
566
|
-
return (collection as FirebaseCollectionConfig<M, USER>).subcollections;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/**
|
|
570
|
-
* Where the rows in an {@link EntityChildView} come from.
|
|
571
|
-
*
|
|
572
|
-
* The two are not the same thing, and conflating them is what made a Postgres
|
|
573
|
-
* relation borrow Firestore's addressing:
|
|
574
|
-
*
|
|
575
|
-
* - `subcollection` is **containment**. The rows live under the parent; the
|
|
576
|
-
* path is their identity, and they cannot exist without it. This is what
|
|
577
|
-
* Firestore has natively.
|
|
578
|
-
* - `relation` is a **link**. The rows are an ordinary collection, narrowed to
|
|
579
|
-
* those the parent reaches. `owned` means the child carries the parent's
|
|
580
|
-
* foreign key and belongs to it alone; `linked` means the row is shared
|
|
581
|
-
* through a junction, so what the parent controls is the link, not the row.
|
|
582
|
-
*
|
|
583
|
-
* @group Models
|
|
584
|
-
*/
|
|
585
|
-
export type ChildViewSource =
|
|
586
|
-
| { kind: "subcollection" }
|
|
587
|
-
| {
|
|
588
|
-
kind: "relation";
|
|
589
|
-
relationKey: string;
|
|
590
|
-
mode: "owned" | "linked";
|
|
591
|
-
/**
|
|
592
|
-
* Slug of the collection the rows actually live in.
|
|
593
|
-
*
|
|
594
|
-
* Distinct from the view's `key`, which is the relation. A `linked` view
|
|
595
|
-
* needs both: the key addresses the parent's set, and this addresses the
|
|
596
|
-
* whole collection to pick an existing row out of.
|
|
597
|
-
*/
|
|
598
|
-
targetSlug: string;
|
|
599
|
-
};
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
* A list of rows rendered inside an entity view — the tab under a record.
|
|
603
|
-
*
|
|
604
|
-
* This is a *presentation* descriptor, which is the whole point: rendering a
|
|
605
|
-
* related list as a tab used to require minting a child `CollectionConfig` with
|
|
606
|
-
* its own slug, which dragged a URL grammar, a path resolver and a second
|
|
607
|
-
* read/write pipeline along with it. A tab needs a key, a collection to list,
|
|
608
|
-
* and to know where its rows come from.
|
|
609
|
-
*
|
|
610
|
-
* @group Models
|
|
611
|
-
*/
|
|
612
|
-
export interface EntityChildView<M extends Record<string, unknown> = Record<string, unknown>> {
|
|
613
|
-
/**
|
|
614
|
-
* Stable identifier for this view: the tab id and the path segment.
|
|
615
|
-
*
|
|
616
|
-
* For a relation this is the **relation key** — the name the backend
|
|
617
|
-
* resolves a nested path segment by — not the target collection's slug.
|
|
618
|
-
* Those differ whenever a relation is named, which is every inline relation
|
|
619
|
-
* property, and the mismatch is why such a tab used to open onto an error.
|
|
620
|
-
*/
|
|
621
|
-
key: string;
|
|
622
|
-
|
|
623
|
-
/** The collection whose rows this view lists, with any overrides applied. */
|
|
624
|
-
collection: CollectionConfig<M>;
|
|
625
|
-
|
|
626
|
-
source: ChildViewSource;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
export type { WhereFilterOp, FilterValues, WireFilterValues, FilterPreset } from "./filter-operators";
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
export type InferCollectionConfigType<S extends CollectionConfig> = S extends CollectionConfig<infer M> ? M : never;
|
|
634
|
-
|
|
635
|
-
/**
|
|
636
|
-
* Configuration for authentication collections.
|
|
637
|
-
*
|
|
638
|
-
* Controls what happens when admins create users, reset passwords,
|
|
639
|
-
* and which entity actions are auto-injected.
|
|
640
|
-
*
|
|
641
|
-
* Use `auth: true` as sugar for `{ enabled: true }` with all defaults.
|
|
642
|
-
*
|
|
643
|
-
* @example Override user creation
|
|
644
|
-
* ```ts
|
|
645
|
-
* auth: {
|
|
646
|
-
* enabled: true,
|
|
647
|
-
* onCreateUser: async (values, ctx) => {
|
|
648
|
-
* const hash = await ctx.hashPassword("welcome123");
|
|
649
|
-
* return {
|
|
650
|
-
* values: { ...values, passwordHash: hash, emailVerified: true },
|
|
651
|
-
* temporaryPassword: "welcome123",
|
|
652
|
-
* };
|
|
653
|
-
* },
|
|
654
|
-
* }
|
|
655
|
-
* ```
|
|
656
|
-
*
|
|
657
|
-
* @example Disable the reset-password entity action
|
|
658
|
-
* ```ts
|
|
659
|
-
* auth: {
|
|
660
|
-
* enabled: true,
|
|
661
|
-
* actions: { resetPassword: false },
|
|
662
|
-
* }
|
|
663
|
-
* ```
|
|
664
|
-
*
|
|
665
|
-
* @group Models
|
|
666
|
-
*/
|
|
667
|
-
export interface AuthCollectionConfig {
|
|
668
|
-
/** Set to true to mark this collection as the authentication collection. */
|
|
669
|
-
enabled: boolean;
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
* Called when an admin creates a user via the collection REST API.
|
|
673
|
-
*
|
|
674
|
-
* Default: generate password → hash → normalize email → save →
|
|
675
|
-
* send invitation email (or return temp password if no email configured).
|
|
676
|
-
*
|
|
677
|
-
* Override to implement custom invitation flows, LDAP sync, etc.
|
|
678
|
-
*/
|
|
679
|
-
onCreateUser?: (
|
|
680
|
-
values: Record<string, unknown>,
|
|
681
|
-
ctx: AuthCollectionContext
|
|
682
|
-
) => Promise<AuthCollectionCreateResult>;
|
|
683
|
-
|
|
684
|
-
/**
|
|
685
|
-
* Called when an admin resets a user's password via the admin panel.
|
|
686
|
-
*
|
|
687
|
-
* Default: generate reset token → send email (or generate + return temp password).
|
|
688
|
-
* Override for custom reset flows.
|
|
689
|
-
*/
|
|
690
|
-
onResetPassword?: (
|
|
691
|
-
uid: string,
|
|
692
|
-
ctx: AuthCollectionContext
|
|
693
|
-
) => Promise<AuthCollectionResetResult>;
|
|
694
|
-
|
|
695
|
-
/**
|
|
696
|
-
* Control which auth-specific entity actions are auto-injected.
|
|
697
|
-
*
|
|
698
|
-
* Default: `{ resetPassword: true }` — the framework auto-injects
|
|
699
|
-
* the built-in `resetPasswordAction` into the collection's entity actions.
|
|
700
|
-
*
|
|
701
|
-
* Set to `false` to disable, or pass a custom `EntityAction` to replace the UI.
|
|
702
|
-
*
|
|
703
|
-
* The object form is an `EntityAction` from `@rebasepro/cms-types`, typed
|
|
704
|
-
* here as `object` because it is a React component with admin controllers in
|
|
705
|
-
* its props and nothing on the server reads it — only whether the built-in
|
|
706
|
-
* action is injected, which is the boolean.
|
|
707
|
-
*/
|
|
708
|
-
actions?: {
|
|
709
|
-
resetPassword?: boolean | object;
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
/**
|
|
714
|
-
* Context provided to collection-level auth hooks.
|
|
715
|
-
*
|
|
716
|
-
* This is a simplified facade over the server internals —
|
|
717
|
-
* it exposes only what's needed for custom auth flows without
|
|
718
|
-
* coupling collection config to internal interfaces.
|
|
719
|
-
*
|
|
720
|
-
* @group Models
|
|
721
|
-
*/
|
|
722
|
-
export interface AuthCollectionContext {
|
|
723
|
-
/** Hash a password using the configured algorithm (scrypt by default). */
|
|
724
|
-
hashPassword: (password: string) => Promise<string>;
|
|
725
|
-
/**
|
|
726
|
-
* Send an email. Only available when email service is configured.
|
|
727
|
-
*
|
|
728
|
-
* Resolves with what the provider reported — the assigned Message-ID, most
|
|
729
|
-
* usefully — so a hook that sends a message can store the id and later
|
|
730
|
-
* thread a reply back to it. Callers that do not care may ignore it.
|
|
731
|
-
*/
|
|
732
|
-
sendEmail?: (options: { to: string; subject: string; html: string; text?: string }) => Promise<EmailSendResult>;
|
|
733
|
-
/** Whether the email service is configured and available. */
|
|
734
|
-
emailConfigured: boolean;
|
|
735
|
-
/** The app name from email config (for templates). */
|
|
736
|
-
appName: string;
|
|
737
|
-
/** The base URL for password reset links. */
|
|
738
|
-
resetPasswordUrl: string;
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
/**
|
|
742
|
-
* Result of a collection-level `onCreateUser` hook.
|
|
743
|
-
* @group Models
|
|
744
|
-
*/
|
|
745
|
-
export interface AuthCollectionCreateResult {
|
|
746
|
-
/** Processed values to persist (must include passwordHash, NOT raw password). */
|
|
747
|
-
values: Record<string, unknown>;
|
|
748
|
-
/** If set, shown to the admin in the creation result dialog. */
|
|
749
|
-
temporaryPassword?: string;
|
|
750
|
-
/** Whether an invitation email was sent. */
|
|
751
|
-
invitationSent?: boolean;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
/**
|
|
755
|
-
* Result of a collection-level `onResetPassword` hook.
|
|
756
|
-
* @group Models
|
|
757
|
-
*/
|
|
758
|
-
export interface AuthCollectionResetResult {
|
|
759
|
-
/** If set, shown to the admin. */
|
|
760
|
-
temporaryPassword?: string;
|
|
761
|
-
/** Whether a reset email was sent. */
|
|
762
|
-
invitationSent?: boolean;
|
|
763
|
-
}
|