@rebasepro/types 0.9.1-canary.fd3754b → 0.9.1-canary.ff338b5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllers/data.d.ts +44 -2
- package/dist/controllers/data_driver.d.ts +45 -3
- package/dist/index.es.js +19 -1
- package/dist/index.es.js.map +1 -1
- package/dist/types/collections.d.ts +11 -0
- package/dist/types/entity_callbacks.d.ts +3 -3
- package/dist/types/policy.d.ts +48 -2
- package/dist/types/properties.d.ts +13 -0
- package/dist/types/websockets.d.ts +34 -0
- package/package.json +5 -6
- package/src/controllers/data.ts +42 -2
- package/src/controllers/data_driver.ts +47 -3
- package/src/types/collections.ts +12 -0
- package/src/types/entity_callbacks.ts +3 -3
- package/src/types/policy.ts +50 -1
- package/src/types/properties.ts +14 -0
- package/src/types/websockets.ts +31 -0
- package/dist/index.umd.js +0 -591
- package/dist/index.umd.js.map +0 -1
|
@@ -149,6 +149,15 @@ export interface CollectionAccessor<M extends Record<string, unknown> = Record<s
|
|
|
149
149
|
* @returns The created entity
|
|
150
150
|
*/
|
|
151
151
|
create(data: Partial<EntityValues<M>>, id?: string | number): Promise<Entity<M>>;
|
|
152
|
+
/**
|
|
153
|
+
* Create many records in a single transaction.
|
|
154
|
+
*
|
|
155
|
+
* See {@link SDKCollectionClient.createMany}. Optional: not every driver can
|
|
156
|
+
* write in bulk, and callers should fall back to `create` per record.
|
|
157
|
+
*/
|
|
158
|
+
createMany?(data: Partial<EntityValues<M>>[], options?: {
|
|
159
|
+
upsert?: boolean;
|
|
160
|
+
}): Promise<Entity<M>[]>;
|
|
152
161
|
/**
|
|
153
162
|
* Update an existing record by ID.
|
|
154
163
|
* @returns The updated entity
|
|
@@ -262,10 +271,43 @@ export interface SDKCollectionClient<M extends Record<string, unknown> = Record<
|
|
|
262
271
|
/**
|
|
263
272
|
* Create a new record.
|
|
264
273
|
* @param data The record data to create (the collection's `Insert` shape).
|
|
265
|
-
* @param id Optional specific
|
|
274
|
+
* @param id Optional specific id, sent as an `id` column. This is for tables
|
|
275
|
+
* whose key *is* `id`: the value goes in as that column. For a table keyed
|
|
276
|
+
* on anything else (a `sku`, a composite key), there is no `id` column to
|
|
277
|
+
* receive it — put the key in `data` instead, where it belongs among the
|
|
278
|
+
* columns.
|
|
266
279
|
* @returns The created row
|
|
267
280
|
*/
|
|
268
281
|
create(data: I, id?: string | number): Promise<M>;
|
|
282
|
+
/**
|
|
283
|
+
* Write many records in a single request and a single transaction.
|
|
284
|
+
*
|
|
285
|
+
* Built for imports and ETL, where one call per row means one HTTP round
|
|
286
|
+
* trip and one transaction per row. Every record still runs the normal
|
|
287
|
+
* pipeline — callbacks, relations, row-level security — and the batch is
|
|
288
|
+
* all-or-nothing: if any record is rejected, none of them land and the
|
|
289
|
+
* error names the offending index.
|
|
290
|
+
*
|
|
291
|
+
* A record carrying its primary key updates that row; one without inserts.
|
|
292
|
+
* With `{ upsert: true }` each record is written as INSERT ... ON CONFLICT
|
|
293
|
+
* DO UPDATE on the primary key instead, which is what makes a re-runnable
|
|
294
|
+
* import idempotent.
|
|
295
|
+
*
|
|
296
|
+
* Batches are capped server-side (1000 rows by default) because one batch
|
|
297
|
+
* holds its locks for the whole transaction — chunk larger jobs.
|
|
298
|
+
*
|
|
299
|
+
* @returns The written rows, in the order given.
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```ts
|
|
303
|
+
* for (const chunk of chunks(rows, 1000)) {
|
|
304
|
+
* await client.data.products.createMany(chunk, { upsert: true });
|
|
305
|
+
* }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
createMany(data: I[], options?: {
|
|
309
|
+
upsert?: boolean;
|
|
310
|
+
}): Promise<M[]>;
|
|
269
311
|
/**
|
|
270
312
|
* Update an existing record by ID.
|
|
271
313
|
* @param data The fields to update (the collection's `Update` shape).
|
|
@@ -345,7 +387,7 @@ export type RebaseData<DB = unknown> = {
|
|
|
345
387
|
* - The frontend SDK client (`client.data.products.find()`)
|
|
346
388
|
* - Backend framework callbacks & scripts (`context.data.products.find()`)
|
|
347
389
|
*
|
|
348
|
-
* Every accessor returns flat rows (
|
|
390
|
+
* Every accessor returns flat rows (the table's columns) via
|
|
349
391
|
* {@link SDKCollectionClient} — access fields directly (`row.title`), never
|
|
350
392
|
* `row.values.title`. The admin CMS uses {@link RebaseData} (Entity) instead.
|
|
351
393
|
*
|
|
@@ -65,6 +65,30 @@ export interface SaveProps<M extends Record<string, unknown> = Record<string, un
|
|
|
65
65
|
previousValues?: Partial<EntityValues<M>>;
|
|
66
66
|
collection?: CollectionConfig<M>;
|
|
67
67
|
status: EntityStatus;
|
|
68
|
+
/**
|
|
69
|
+
* Write the row with INSERT ... ON CONFLICT DO UPDATE on the primary key
|
|
70
|
+
* instead of choosing between insert and update up front.
|
|
71
|
+
*
|
|
72
|
+
* One statement, so it does not lose the race a read-then-write can, and it
|
|
73
|
+
* succeeds whether or not the row is already there — what a re-runnable
|
|
74
|
+
* import needs. Requires every primary key column to be present; without
|
|
75
|
+
* them there is no conflict target and the row is inserted normally.
|
|
76
|
+
*/
|
|
77
|
+
upsert?: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
export interface SaveManyProps<M extends Record<string, unknown> = Record<string, unknown>> {
|
|
83
|
+
path: string;
|
|
84
|
+
/**
|
|
85
|
+
* The rows to write. A row carrying its primary key updates (or, with
|
|
86
|
+
* `upsert`, inserts-or-updates) that row; one without inserts.
|
|
87
|
+
*/
|
|
88
|
+
rows: Partial<EntityValues<M>>[];
|
|
89
|
+
collection?: CollectionConfig<M>;
|
|
90
|
+
/** Apply every row as INSERT ... ON CONFLICT DO UPDATE. See {@link SaveProps.upsert}. */
|
|
91
|
+
upsert?: boolean;
|
|
68
92
|
}
|
|
69
93
|
/**
|
|
70
94
|
* @internal
|
|
@@ -135,6 +159,19 @@ export interface DataDriver {
|
|
|
135
159
|
* @param props
|
|
136
160
|
*/
|
|
137
161
|
save<M extends Record<string, unknown> = Record<string, unknown>>(props: SaveProps<M>): Promise<Record<string, unknown>>;
|
|
162
|
+
/**
|
|
163
|
+
* Save many rows as one unit of work.
|
|
164
|
+
*
|
|
165
|
+
* Every row runs the same pipeline as {@link save} — callbacks, relations
|
|
166
|
+
* and row-level security all still apply — but they share a single
|
|
167
|
+
* transaction, so the batch either lands whole or not at all. That, and the
|
|
168
|
+
* single round trip, is what makes importing tens of thousands of rows
|
|
169
|
+
* viable without dropping to raw SQL.
|
|
170
|
+
*
|
|
171
|
+
* Optional: drivers that cannot do this leave it undefined and callers fall
|
|
172
|
+
* back to `save` per row.
|
|
173
|
+
*/
|
|
174
|
+
saveMany?<M extends Record<string, unknown> = Record<string, unknown>>(props: SaveManyProps<M>): Promise<Record<string, unknown>[]>;
|
|
138
175
|
/**
|
|
139
176
|
* Delete a entity
|
|
140
177
|
* @param props
|
|
@@ -203,9 +240,14 @@ export interface DataDriver {
|
|
|
203
240
|
* REST-optimised fetch service exposed by drivers that support
|
|
204
241
|
* eager-loading of relations via `include`.
|
|
205
242
|
*
|
|
206
|
-
* The methods return flattened rows
|
|
207
|
-
*
|
|
208
|
-
*
|
|
243
|
+
* The methods return flattened rows — exactly the table's columns, under their
|
|
244
|
+
* own names and with the types the database returned — and included relations
|
|
245
|
+
* inlined as plain nested rows. This is the shape served to app developers
|
|
246
|
+
* through the REST API / SDK client.
|
|
247
|
+
*
|
|
248
|
+
* No synthesized `id`: identity is a primary key, which may be named anything
|
|
249
|
+
* and span several columns, so an address is derived by whoever needs one (see
|
|
250
|
+
* `buildCompositeId`) rather than written into the row on top of the data.
|
|
209
251
|
*
|
|
210
252
|
* @group DataDriver
|
|
211
253
|
*/
|
package/dist/index.es.js
CHANGED
|
@@ -312,6 +312,23 @@ function getDeclaredSubcollections(collection) {
|
|
|
312
312
|
}
|
|
313
313
|
//#endregion
|
|
314
314
|
//#region src/types/policy.ts
|
|
315
|
+
/**
|
|
316
|
+
* The id a request without a logged-in user reports as `auth.uid()`.
|
|
317
|
+
*
|
|
318
|
+
* A user-context request always sets `app.user_id`: blank would read back as
|
|
319
|
+
* `NULL`, and `NULL` is how the trusted server context is recognised, so an
|
|
320
|
+
* anonymous visitor would be promoted to server privileges. The driver
|
|
321
|
+
* therefore substitutes this sentinel at the single chokepoint where the GUC
|
|
322
|
+
* is set.
|
|
323
|
+
*
|
|
324
|
+
* The consequence for policy authors is that **`auth.uid() IS NOT NULL` is a
|
|
325
|
+
* tautology on the user path** — it is true for anonymous visitors too. Use
|
|
326
|
+
* {@link policy.authenticated} (or `auth.uid() <> 'anonymous'`) to mean "signed
|
|
327
|
+
* in", and {@link policy.serverContext} to mean "the trusted server context".
|
|
328
|
+
*
|
|
329
|
+
* @group Models
|
|
330
|
+
*/
|
|
331
|
+
var ANONYMOUS_USER_ID = "anonymous";
|
|
315
332
|
/** @group Models */
|
|
316
333
|
var policy = {
|
|
317
334
|
true: () => ({ kind: "true" }),
|
|
@@ -343,6 +360,7 @@ var policy = {
|
|
|
343
360
|
roles
|
|
344
361
|
}),
|
|
345
362
|
authenticated: () => ({ kind: "authenticated" }),
|
|
363
|
+
serverContext: () => ({ kind: "serverContext" }),
|
|
346
364
|
existsIn: (args) => ({
|
|
347
365
|
kind: "existsIn",
|
|
348
366
|
collection: args.collection,
|
|
@@ -550,6 +568,6 @@ function isPublicStoragePath(path) {
|
|
|
550
568
|
return p.startsWith("public/") || p.startsWith(`default/public/`);
|
|
551
569
|
}
|
|
552
570
|
//#endregion
|
|
553
|
-
export { ALL_WHERE_FILTER_OPS, CANONICAL_TO_REST, DEFAULT_CAPABILITIES, DEFAULT_DATA_SOURCE_KEY, DEFAULT_STORAGE_SOURCE_KEY, EntityReference, EntityRelation, FIREBASE_CAPABILITIES, GeoPoint, MONGODB_CAPABILITIES, NULL_OPS, POSTGRES_CAPABILITIES, PUBLIC_STORAGE_PREFIX, REST_TO_CANONICAL, RebaseApiError, RebaseClientError, Vector, getCollectionDataPath, getDataSourceCapabilities, getDeclaredSubcollections, isBranchAdmin, isDocumentAdmin, isFirebaseCollectionConfig, isLazyComponentRef, isMongoDBCollectionConfig, isPostgresCollectionConfig, isPublicStoragePath, isSQLAdmin, isSchemaAdmin, policy, registerDataSourceCapabilities, toCanonicalOp };
|
|
571
|
+
export { ALL_WHERE_FILTER_OPS, ANONYMOUS_USER_ID, CANONICAL_TO_REST, DEFAULT_CAPABILITIES, DEFAULT_DATA_SOURCE_KEY, DEFAULT_STORAGE_SOURCE_KEY, EntityReference, EntityRelation, FIREBASE_CAPABILITIES, GeoPoint, MONGODB_CAPABILITIES, NULL_OPS, POSTGRES_CAPABILITIES, PUBLIC_STORAGE_PREFIX, REST_TO_CANONICAL, RebaseApiError, RebaseClientError, Vector, getCollectionDataPath, getDataSourceCapabilities, getDeclaredSubcollections, isBranchAdmin, isDocumentAdmin, isFirebaseCollectionConfig, isLazyComponentRef, isMongoDBCollectionConfig, isPostgresCollectionConfig, isPublicStoragePath, isSQLAdmin, isSchemaAdmin, policy, registerDataSourceCapabilities, toCanonicalOp };
|
|
554
572
|
|
|
555
573
|
//# sourceMappingURL=index.es.js.map
|