@rebasepro/server 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/rebase-server.js +4 -2
- package/dist/{GCSStorageController-CjrA4PMo.js → GCSStorageController-BSiP1c-f.js} +22 -8
- package/dist/GCSStorageController-BSiP1c-f.js.map +1 -0
- package/dist/{S3StorageController-B6pKDNVj.js → S3StorageController-CAwFRgjV.js} +19 -7
- package/dist/S3StorageController-CAwFRgjV.js.map +1 -0
- package/dist/api/ast-schema-editor.d.ts +92 -1
- package/dist/api/errors.d.ts +9 -0
- package/dist/api/live-schema-routes.d.ts +38 -8
- package/dist/api/logs-routes.d.ts +39 -1
- package/dist/api/openapi-generator.d.ts +17 -0
- package/dist/api/rest/api-generator.d.ts +44 -10
- package/dist/api/rest/write-validation.d.ts +2 -2
- package/dist/api/types.d.ts +17 -1
- package/dist/{ast-schema-editor-Mvr50v_S.js → ast-schema-editor-CWqS_sLJ.js} +309 -11
- package/dist/ast-schema-editor-CWqS_sLJ.js.map +1 -0
- package/dist/auth/access.d.ts +105 -0
- package/dist/auth/adapter-middleware.d.ts +2 -1
- package/dist/auth/address-ownership.d.ts +16 -1
- package/dist/auth/admin-roles-route.d.ts +4 -2
- package/dist/auth/admin-roles.d.ts +17 -20
- package/dist/auth/admin-users-route.d.ts +1 -0
- package/dist/auth/api-keys/api-key-middleware.d.ts +56 -55
- package/dist/auth/api-keys/api-key-routes.d.ts +41 -11
- package/dist/auth/api-keys/api-key-store.d.ts +31 -8
- package/dist/auth/api-keys/api-key-types.d.ts +14 -16
- package/dist/auth/api-keys/http-operation.d.ts +19 -0
- package/dist/auth/api-keys/index.d.ts +11 -11
- package/dist/auth/api-keys/key-grant.d.ts +41 -0
- package/dist/auth/api-keys/legacy-permissions.d.ts +33 -0
- package/dist/auth/auth-hooks.d.ts +46 -7
- package/dist/auth/builtin-auth-adapter.d.ts +8 -0
- package/dist/auth/cookie-utils.d.ts +7 -0
- package/dist/auth/deliverable-address.d.ts +6 -0
- package/dist/auth/email-change-routes.d.ts +41 -0
- package/dist/auth/expired-token-sweep.d.ts +67 -0
- package/dist/auth/impersonation.d.ts +110 -0
- package/dist/auth/index.d.ts +4 -2
- package/dist/auth/interfaces.d.ts +110 -59
- package/dist/auth/jwt.d.ts +49 -3
- package/dist/auth/magic-link-routes.d.ts +2 -6
- package/dist/auth/mfa-routes.d.ts +2 -9
- package/dist/auth/middleware.d.ts +17 -5
- package/dist/auth/otp-routes.d.ts +2 -6
- package/dist/auth/passwordless-signup.d.ts +27 -0
- package/dist/auth/platform-token.d.ts +122 -0
- package/dist/auth/rate-limiter.d.ts +41 -0
- package/dist/auth/routes.d.ts +45 -0
- package/dist/auth/scope-routes.d.ts +22 -0
- package/dist/auth/session-routes.d.ts +11 -6
- package/dist/auth/token-revocation.d.ts +50 -1
- package/dist/auth/verify-credential.d.ts +28 -0
- package/dist/{auth-B-GIMpDG.js → auth-DMLngxn_.js} +2159 -569
- package/dist/auth-DMLngxn_.js.map +1 -0
- package/dist/backend-DTAOsLQc.js.map +1 -1
- package/dist/backup/backup-common.d.ts +10 -0
- package/dist/backup/backup-routes.d.ts +24 -4
- package/dist/backup/backup-schedule.d.ts +33 -0
- package/dist/backup/backup-storage.d.ts +14 -0
- package/dist/backup/index.d.ts +2 -0
- package/dist/backup-CN0s50D2.js +444 -0
- package/dist/backup-CN0s50D2.js.map +1 -0
- package/dist/boot/bundle.d.ts +19 -0
- package/dist/boot/env.d.ts +49 -4
- package/dist/boot/security-headers.d.ts +26 -0
- package/dist/boot/static-routing.d.ts +56 -0
- package/dist/collection_patch-BRu-BvDv.js +472 -0
- package/dist/collection_patch-BRu-BvDv.js.map +1 -0
- package/dist/{contract-routes-CbFjuBwa.js → contract-routes-fz8i4pxs.js} +17 -4
- package/dist/contract-routes-fz8i4pxs.js.map +1 -0
- package/dist/cron/cron-scheduler.d.ts +25 -20
- package/dist/cron/cron-store.d.ts +6 -2
- package/dist/{cron-loader-DfTj2Hbi.js → cron-loader-CwaANlOG.js} +4 -4
- package/dist/cron-loader-CwaANlOG.js.map +1 -0
- package/dist/{cron-routes-eE8nif_b.js → cron-routes-Bc-SB0Se.js} +10 -7
- package/dist/cron-routes-Bc-SB0Se.js.map +1 -0
- package/dist/{cron-scheduler-B0pLfAix.js → cron-scheduler-CYQgco86.js} +52 -34
- package/dist/cron-scheduler-CYQgco86.js.map +1 -0
- package/dist/{cron-store-TcoGz-xS.js → cron-store-D2Q9-Aco.js} +10 -15
- package/dist/cron-store-D2Q9-Aco.js.map +1 -0
- package/dist/{ddl-bootstrap-C6mo0Kmz.js → ddl-bootstrap-BaqMSa4Y.js} +2 -2
- package/dist/{ddl-bootstrap-C6mo0Kmz.js.map → ddl-bootstrap-BaqMSa4Y.js.map} +1 -1
- package/dist/email/index.d.ts +2 -2
- package/dist/email/templates.d.ts +22 -0
- package/dist/email/types.d.ts +26 -0
- package/dist/env.d.ts +1 -2
- package/dist/{errors-DWsX4yTd.js → errors-D6_y86c5.js} +102 -8
- package/dist/errors-D6_y86c5.js.map +1 -0
- package/dist/{function-loader-xnbDAPfa.js → function-loader-D7o5Epjj.js} +2 -2
- package/dist/{function-loader-xnbDAPfa.js.map → function-loader-D7o5Epjj.js.map} +1 -1
- package/dist/{function-routes-Chet4-lB.js → function-routes-CaNG4waN.js} +24 -12
- package/dist/function-routes-CaNG4waN.js.map +1 -0
- package/dist/functions/context.d.ts +17 -6
- package/dist/functions/guards.d.ts +22 -5
- package/dist/functions/index.d.ts +2 -2
- package/dist/functions/index.js +90 -36
- package/dist/functions/index.js.map +1 -1
- package/dist/{history-recorder-B4MpJfJK.js → history-recorder-Nr8zLvoU.js} +4 -4
- package/dist/{history-recorder-B4MpJfJK.js.map → history-recorder-Nr8zLvoU.js.map} +1 -1
- package/dist/{history-store-BhxWOuz9.js → history-store-rcAm_xFR.js} +2 -2
- package/dist/{history-store-BhxWOuz9.js.map → history-store-rcAm_xFR.js.map} +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.es.js +3084 -753
- package/dist/index.es.js.map +1 -1
- package/dist/init/health.d.ts +17 -2
- package/dist/init/shutdown.d.ts +10 -0
- package/dist/init.d.ts +54 -0
- package/dist/{jobs-CazMYhyy.js → jobs-DqYNfquG.js} +5 -5
- package/dist/{jobs-CazMYhyy.js.map → jobs-DqYNfquG.js.map} +1 -1
- package/dist/{jwt-DnQHNFCl.js → jwt-R6bSPMjk.js} +39 -15
- package/dist/{jwt-DnQHNFCl.js.map → jwt-R6bSPMjk.js.map} +1 -1
- package/dist/{keys-CogCQpxG.js → keys-GAVZqbqx.js} +3 -17
- package/dist/{keys-CogCQpxG.js.map → keys-GAVZqbqx.js.map} +1 -1
- package/dist/{logger-DO2PZc4i.js → logger-D-S-hO5e.js} +26 -3
- package/dist/logger-D-S-hO5e.js.map +1 -0
- package/dist/{logs-routes-Bj4TYYUl.js → logs-routes-DAdv37GI.js} +48 -8
- package/dist/logs-routes-DAdv37GI.js.map +1 -0
- package/dist/mcp/consent-page.d.ts +1 -1
- package/dist/mcp/mcp-routes.d.ts +7 -0
- package/dist/mcp/mcp-tools.d.ts +15 -9
- package/dist/mcp/oauth-metadata.d.ts +21 -16
- package/dist/mcp/oauth-routes.d.ts +7 -1
- package/dist/{openapi-generator-O_O24MAT.js → openapi-generator-DAq_XVDu.js} +104 -13
- package/dist/openapi-generator-DAq_XVDu.js.map +1 -0
- package/dist/{proxy-Czngl3p9.js → proxy-qRlqeUmO.js} +2 -2
- package/dist/{proxy-Czngl3p9.js.map → proxy-qRlqeUmO.js.map} +1 -1
- package/dist/{query-parser-DGRVFNM3.js → query-parser-BgiKJKvc.js} +6 -56
- package/dist/query-parser-BgiKJKvc.js.map +1 -0
- package/dist/{request-timeout-C_4C2BeR.js → request-timeout-DgH7j8qO.js} +3 -3
- package/dist/{request-timeout-C_4C2BeR.js.map → request-timeout-DgH7j8qO.js.map} +1 -1
- package/dist/schema-edit/apply-schema-change.d.ts +63 -3
- package/dist/schema-edit/project-root.d.ts +3 -2
- package/dist/schema-edit/remote-source.d.ts +9 -4
- package/dist/{schema-editor-routes-C5-lh_jO.js → schema-editor-routes-oIyuWl3L.js} +12 -7
- package/dist/schema-editor-routes-oIyuWl3L.js.map +1 -0
- package/dist/serve-spa.d.ts +58 -0
- package/dist/services/routed-realtime-service.d.ts +11 -0
- package/dist/soft-delete-params-BWPilMPF.js +59 -0
- package/dist/soft-delete-params-BWPilMPF.js.map +1 -0
- package/dist/{src-vkcwKXbT.js → src-CatHFUym.js} +439 -20
- package/dist/src-CatHFUym.js.map +1 -0
- package/dist/{src-pmvW7BFx.js → src-I3aG1PcY.js} +252 -70
- package/dist/src-I3aG1PcY.js.map +1 -0
- package/dist/storage/GCSStorageController.d.ts +2 -0
- package/dist/storage/LocalStorageController.d.ts +2 -0
- package/dist/storage/S3StorageController.d.ts +2 -0
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/property-limits.d.ts +41 -6
- package/dist/storage/request-keys.d.ts +15 -0
- package/dist/storage/requested-object.d.ts +74 -0
- package/dist/storage/routes.d.ts +36 -18
- package/dist/storage/tus-handler.d.ts +30 -5
- package/dist/storage/types.d.ts +19 -0
- package/dist/types-BfKcm9do.js.map +1 -1
- package/dist/utils/logger.d.ts +12 -0
- package/package.json +5 -5
- package/dist/GCSStorageController-CjrA4PMo.js.map +0 -1
- package/dist/S3StorageController-B6pKDNVj.js.map +0 -1
- package/dist/admin-roles-vYdp_Pil.js +0 -36
- package/dist/admin-roles-vYdp_Pil.js.map +0 -1
- package/dist/admin_block-DxKLmdiv.js +0 -206
- package/dist/admin_block-DxKLmdiv.js.map +0 -1
- package/dist/ast-schema-editor-Mvr50v_S.js.map +0 -1
- package/dist/auth/api-keys/api-key-permission-guard.d.ts +0 -65
- package/dist/auth-B-GIMpDG.js.map +0 -1
- package/dist/backup-D7YR94N3.js +0 -253
- package/dist/backup-D7YR94N3.js.map +0 -1
- package/dist/contract-routes-CbFjuBwa.js.map +0 -1
- package/dist/cron-loader-DfTj2Hbi.js.map +0 -1
- package/dist/cron-routes-eE8nif_b.js.map +0 -1
- package/dist/cron-scheduler-B0pLfAix.js.map +0 -1
- package/dist/cron-store-TcoGz-xS.js.map +0 -1
- package/dist/errors-DWsX4yTd.js.map +0 -1
- package/dist/function-routes-Chet4-lB.js.map +0 -1
- package/dist/logger-DO2PZc4i.js.map +0 -1
- package/dist/logs-routes-Bj4TYYUl.js.map +0 -1
- package/dist/openapi-generator-O_O24MAT.js.map +0 -1
- package/dist/query-parser-DGRVFNM3.js.map +0 -1
- package/dist/schema-editor-routes-C5-lh_jO.js.map +0 -1
- package/dist/src-pmvW7BFx.js.map +0 -1
- package/dist/src-vkcwKXbT.js.map +0 -1
|
@@ -3,7 +3,7 @@ import __rebaseProcess from "process";
|
|
|
3
3
|
globalThis.process ??= __rebaseProcess;
|
|
4
4
|
__rebaseCreateRequire(import.meta.url);
|
|
5
5
|
import { r as __require, t as __commonJSMin } from "./rolldown-runtime-dW7B1o5h.js";
|
|
6
|
-
import {
|
|
6
|
+
import { B as rewriteLegacyRlsFunctions, H as getDeclaredSubcollections, J as CANONICAL_TO_REST, K as getDataSourceCapabilities, M as resolveResourceRefs, Q as isRelationAggregateSort, U as isPostgresCollectionConfig, V as getCollectionDataPath, W as isRelationalCollectionConfig, X as NULL_OPS, Y as LIST_OPS, Z as REST_TO_CANONICAL, et as sortKeyToString, q as ALL_WHERE_FILTER_OPS, tt as toCanonicalOp } from "./src-CatHFUym.js";
|
|
7
7
|
//#region ../types/src/errors.ts
|
|
8
8
|
/**
|
|
9
9
|
* The single error type thrown across the entire Rebase client surface —
|
|
@@ -4018,6 +4018,13 @@ var CollectionRegistry = class {
|
|
|
4018
4018
|
}
|
|
4019
4019
|
collectionsByTableName = /* @__PURE__ */ new Map();
|
|
4020
4020
|
collectionsBySlug = /* @__PURE__ */ new Map();
|
|
4021
|
+
/**
|
|
4022
|
+
* Root collections whose driver stores them under a `path` other than
|
|
4023
|
+
* their slug, by that path. A list, because the path is only unique within
|
|
4024
|
+
* a data source: two collections in different databases may both be stored
|
|
4025
|
+
* at `customer`.
|
|
4026
|
+
*/
|
|
4027
|
+
collectionsByDataPath = /* @__PURE__ */ new Map();
|
|
4021
4028
|
rootCollections = [];
|
|
4022
4029
|
cachedCollectionsList = null;
|
|
4023
4030
|
rawCollectionsByTableName = /* @__PURE__ */ new Map();
|
|
@@ -4042,6 +4049,7 @@ var CollectionRegistry = class {
|
|
|
4042
4049
|
reset() {
|
|
4043
4050
|
this.collectionsByTableName.clear();
|
|
4044
4051
|
this.collectionsBySlug.clear();
|
|
4052
|
+
this.collectionsByDataPath.clear();
|
|
4045
4053
|
this.rootCollections = [];
|
|
4046
4054
|
this.cachedCollectionsList = null;
|
|
4047
4055
|
this.rawCollectionsByTableName.clear();
|
|
@@ -4074,6 +4082,7 @@ var CollectionRegistry = class {
|
|
|
4074
4082
|
this.collectionsByTableName.set(getTableName(normalized), normalized);
|
|
4075
4083
|
this.rawCollectionsByTableName.set(getTableName(raw), raw);
|
|
4076
4084
|
if (normalized.slug) this.collectionsBySlug.set(normalized.slug, normalized);
|
|
4085
|
+
this.indexDataPath(normalized);
|
|
4077
4086
|
if (raw.slug) this.rawCollectionsBySlug.set(raw.slug, raw);
|
|
4078
4087
|
});
|
|
4079
4088
|
normalizedCollections.forEach((c) => {
|
|
@@ -4091,6 +4100,19 @@ var CollectionRegistry = class {
|
|
|
4091
4100
|
this.rootCollections.push(collection);
|
|
4092
4101
|
this.rawRootCollections.push(raw);
|
|
4093
4102
|
this._registerRecursively(collection, raw);
|
|
4103
|
+
const registered = this.collectionsByTableName.get(getTableName(collection));
|
|
4104
|
+
if (registered) this.indexDataPath(registered);
|
|
4105
|
+
}
|
|
4106
|
+
/**
|
|
4107
|
+
* Index a root collection by the path its driver stores it under, when
|
|
4108
|
+
* that is not its slug. Only roots: a subcollection's `path` is relative to
|
|
4109
|
+
* the record it hangs off, so it names nothing on its own.
|
|
4110
|
+
*/
|
|
4111
|
+
indexDataPath(collection) {
|
|
4112
|
+
const dataPath = getCollectionDataPath(collection);
|
|
4113
|
+
if (!dataPath || dataPath === collection.slug) return;
|
|
4114
|
+
const indexed = this.collectionsByDataPath.get(dataPath) ?? [];
|
|
4115
|
+
if (!indexed.includes(collection)) this.collectionsByDataPath.set(dataPath, [...indexed, collection]);
|
|
4094
4116
|
}
|
|
4095
4117
|
_registerRecursively(collection, rawCollection) {
|
|
4096
4118
|
if (this.collectionsByTableName.has(getTableName(collection))) return;
|
|
@@ -4144,7 +4166,24 @@ var CollectionRegistry = class {
|
|
|
4144
4166
|
}
|
|
4145
4167
|
return newProperty;
|
|
4146
4168
|
}
|
|
4147
|
-
|
|
4169
|
+
/**
|
|
4170
|
+
* The collection registered under `path`: by slug, by slug with hyphens
|
|
4171
|
+
* for underscores, by table name, and last by the `path` a root Firestore
|
|
4172
|
+
* or MongoDB collection declares for its driver.
|
|
4173
|
+
*
|
|
4174
|
+
* One string can name two collections. Declaring `slug: "fs_diagnosis",
|
|
4175
|
+
* path: "diagnosis"` is how a Firestore collection sits beside a Postgres
|
|
4176
|
+
* collection whose slug is `diagnosis` — and a reference read back from
|
|
4177
|
+
* Firestore carries `diagnosis`. The order above settles it in favour of the
|
|
4178
|
+
* slug unless `preferredDriver` is given: then the first collection whose
|
|
4179
|
+
* data source or engine is `preferredDriver` wins. Pass a reference's
|
|
4180
|
+
* `driver`, or the data source of the record the path was read from.
|
|
4181
|
+
*/
|
|
4182
|
+
get(path, preferredDriver) {
|
|
4183
|
+
if (preferredDriver) {
|
|
4184
|
+
const preferred = this.candidatesFor(path).find((collection) => collection.dataSource === preferredDriver || collection.engine === preferredDriver);
|
|
4185
|
+
if (preferred) return preferred;
|
|
4186
|
+
}
|
|
4148
4187
|
const bySlug = this.collectionsBySlug.get(path);
|
|
4149
4188
|
if (bySlug) return bySlug;
|
|
4150
4189
|
if (path.includes("-")) {
|
|
@@ -4152,7 +4191,84 @@ var CollectionRegistry = class {
|
|
|
4152
4191
|
const byNormalized = this.collectionsBySlug.get(normalized);
|
|
4153
4192
|
if (byNormalized) return byNormalized;
|
|
4154
4193
|
}
|
|
4155
|
-
|
|
4194
|
+
const byTableName = this.collectionsByTableName.get(path);
|
|
4195
|
+
if (byTableName) return byTableName;
|
|
4196
|
+
return this.collectionsByDataPath.get(path)?.[0];
|
|
4197
|
+
}
|
|
4198
|
+
/** Every collection {@link get} could answer `path` with, in its order. */
|
|
4199
|
+
candidatesFor(path) {
|
|
4200
|
+
const candidates = [
|
|
4201
|
+
this.collectionsBySlug.get(path),
|
|
4202
|
+
path.includes("-") ? this.collectionsBySlug.get(path.replace(/-/g, "_")) : void 0,
|
|
4203
|
+
this.collectionsByTableName.get(path),
|
|
4204
|
+
...this.collectionsByDataPath.get(path) ?? []
|
|
4205
|
+
];
|
|
4206
|
+
return candidates.filter((collection, index) => collection !== void 0 && candidates.indexOf(collection) === index);
|
|
4207
|
+
}
|
|
4208
|
+
/**
|
|
4209
|
+
* The path a collection's rows are stored under, for the path the admin
|
|
4210
|
+
* addresses it by.
|
|
4211
|
+
*
|
|
4212
|
+
* The admin addresses a collection by its slug — in routes, in
|
|
4213
|
+
* `data.collection(...)`, in the `path` of every entity it lists — because
|
|
4214
|
+
* the slug is what is unique. A Firestore or MongoDB collection may declare
|
|
4215
|
+
* a `path` of its own ({@link getCollectionDataPath}), and its driver has to
|
|
4216
|
+
* be handed that one, under every record and subcollection too:
|
|
4217
|
+
* `fs_diagnosis/abc/locales` is stored at `diagnosis/abc/locales`.
|
|
4218
|
+
*
|
|
4219
|
+
* A path that names no registered collection, or runs only through
|
|
4220
|
+
* collections stored under their slugs, comes back unchanged.
|
|
4221
|
+
*/
|
|
4222
|
+
resolveDataPath(path) {
|
|
4223
|
+
let resolved;
|
|
4224
|
+
const exact = this.get(path);
|
|
4225
|
+
if (exact) resolved = {
|
|
4226
|
+
collections: [exact],
|
|
4227
|
+
entityIds: []
|
|
4228
|
+
};
|
|
4229
|
+
else try {
|
|
4230
|
+
resolved = this.resolvePathToCollections(path);
|
|
4231
|
+
} catch {
|
|
4232
|
+
return path;
|
|
4233
|
+
}
|
|
4234
|
+
const { collections, entityIds } = resolved;
|
|
4235
|
+
if (collections.every((collection) => getCollectionDataPath(collection) === collection.slug)) return path;
|
|
4236
|
+
return collections.map((collection, index) => index < entityIds.length ? `${getCollectionDataPath(collection)}/${entityIds[index]}` : getCollectionDataPath(collection)).join("/");
|
|
4237
|
+
}
|
|
4238
|
+
/**
|
|
4239
|
+
* The path the admin addresses a collection by, for a path its rows are
|
|
4240
|
+
* stored under: the inverse of {@link resolveDataPath}, for a reference
|
|
4241
|
+
* read back from its driver.
|
|
4242
|
+
*
|
|
4243
|
+
* The root is the longest leading run of segments naming a collection, and
|
|
4244
|
+
* becomes its slug when the run is where that collection is stored. Each
|
|
4245
|
+
* subcollection after a record id is matched by where it is stored too. A
|
|
4246
|
+
* path that already names its collections by slug comes back unchanged.
|
|
4247
|
+
*
|
|
4248
|
+
* `preferredDriver` decides between a collection stored at the path and one
|
|
4249
|
+
* whose slug it is, as in {@link get}.
|
|
4250
|
+
*/
|
|
4251
|
+
resolveCollectionPath(path, preferredDriver) {
|
|
4252
|
+
const segments = path.split("/").filter(Boolean);
|
|
4253
|
+
for (let length = segments.length; length > 0; length--) {
|
|
4254
|
+
const prefix = segments.slice(0, length).join("/");
|
|
4255
|
+
const root = this.get(prefix, preferredDriver);
|
|
4256
|
+
if (!root) continue;
|
|
4257
|
+
const translated = [getCollectionDataPath(root) === prefix ? root.slug : prefix];
|
|
4258
|
+
let current = root;
|
|
4259
|
+
let rest = segments.slice(length);
|
|
4260
|
+
while (rest.length >= 2) {
|
|
4261
|
+
const [entityId, storedAt, ...after] = rest;
|
|
4262
|
+
const child = getSubcollections(current).find((subcollection) => getCollectionDataPath(subcollection) === storedAt);
|
|
4263
|
+
if (!child) break;
|
|
4264
|
+
translated.push(entityId, child.slug);
|
|
4265
|
+
current = child;
|
|
4266
|
+
rest = after;
|
|
4267
|
+
}
|
|
4268
|
+
const collectionPath = [...translated, ...rest].join("/");
|
|
4269
|
+
return collectionPath === segments.join("/") ? path : collectionPath;
|
|
4270
|
+
}
|
|
4271
|
+
return path;
|
|
4156
4272
|
}
|
|
4157
4273
|
/**
|
|
4158
4274
|
* Gets the pristine, un-normalized collection exactly as it was provided.
|
|
@@ -4200,29 +4316,41 @@ var CollectionRegistry = class {
|
|
|
4200
4316
|
}
|
|
4201
4317
|
/**
|
|
4202
4318
|
* Resolves a multi-segment path like "products/123/locales" and returns
|
|
4203
|
-
* information about the collections and entity IDs along the path
|
|
4319
|
+
* information about the collections and entity IDs along the path.
|
|
4320
|
+
*
|
|
4321
|
+
* A slug may contain slashes (`content/de-DE/podcasts`), so the root is
|
|
4322
|
+
* the longest leading run of segments naming a registered collection, and
|
|
4323
|
+
* each subcollection is matched the same way among its parent's.
|
|
4324
|
+
*
|
|
4325
|
+
* @param options.allowRecordPath accept a path that ends at a record
|
|
4326
|
+
* (`…/{id}`) and resolve it to the collection holding that record, with the
|
|
4327
|
+
* id last in `entityIds`. Without it such a path is an error. Only the
|
|
4328
|
+
* registry can tell the two shapes apart, because only it knows where each
|
|
4329
|
+
* slug ends.
|
|
4204
4330
|
*/
|
|
4205
|
-
resolvePathToCollections(path) {
|
|
4331
|
+
resolvePathToCollections(path, options) {
|
|
4206
4332
|
const pathSegments = path.split("/").filter((p) => p);
|
|
4207
4333
|
if (pathSegments.length === 0) throw new Error(`Invalid path: ${path}`);
|
|
4208
|
-
|
|
4209
|
-
|
|
4334
|
+
const root = splitAtLeadingCollection(pathSegments, (candidate) => this.get(candidate));
|
|
4335
|
+
if (!root) throw new Error(`Unknown collection path or slug: ${path}`);
|
|
4336
|
+
let currentCollection = root.collection;
|
|
4337
|
+
const collections = [currentCollection];
|
|
4210
4338
|
const entityIds = [];
|
|
4211
|
-
let
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
for (let i = 1; i < pathSegments.length; i += 2) {
|
|
4215
|
-
const entityId = pathSegments[i];
|
|
4339
|
+
let rest = root.rest;
|
|
4340
|
+
while (rest.length > 0) {
|
|
4341
|
+
const [entityId, ...afterEntity] = rest;
|
|
4216
4342
|
entityIds.push(entityId);
|
|
4217
|
-
if (
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
if (!subcollections || subcollections.length === 0) throw new Error(`No subcollections found for ${currentCollection.slug} in path: ${path}`);
|
|
4221
|
-
const subcollection = subcollections.find((c) => c.slug === subcollectionSlug);
|
|
4222
|
-
if (!subcollection) throw new Error(`Subcollection '${subcollectionSlug}' not found in ${currentCollection.slug}`);
|
|
4223
|
-
currentCollection = this.normalizeCollection(subcollection);
|
|
4224
|
-
collections.push(currentCollection);
|
|
4343
|
+
if (afterEntity.length === 0) {
|
|
4344
|
+
if (options?.allowRecordPath) break;
|
|
4345
|
+
throw new Error(`Invalid collection path: ${path}. It ends at the record '${entityId}' of '${currentCollection.slug}', not at a collection.`);
|
|
4225
4346
|
}
|
|
4347
|
+
const subcollections = getSubcollections(currentCollection);
|
|
4348
|
+
if (!subcollections || subcollections.length === 0) throw new Error(`No subcollections found for ${currentCollection.slug} in path: ${path}`);
|
|
4349
|
+
const child = splitAtLeadingCollection(afterEntity, (candidate) => subcollections.find((c) => c.slug === candidate));
|
|
4350
|
+
if (!child) throw new Error(`Subcollection '${afterEntity[0]}' not found in ${currentCollection.slug}`);
|
|
4351
|
+
currentCollection = this.normalizeCollection(child.collection);
|
|
4352
|
+
collections.push(currentCollection);
|
|
4353
|
+
rest = child.rest;
|
|
4226
4354
|
}
|
|
4227
4355
|
return {
|
|
4228
4356
|
collections,
|
|
@@ -4231,6 +4359,26 @@ var CollectionRegistry = class {
|
|
|
4231
4359
|
};
|
|
4232
4360
|
}
|
|
4233
4361
|
};
|
|
4362
|
+
/**
|
|
4363
|
+
* Split path segments at the collection they start with.
|
|
4364
|
+
*
|
|
4365
|
+
* A slug may contain slashes, and several drivers need it to: a Firestore
|
|
4366
|
+
* collection partitioned by locale is declared as `content/de-DE/podcasts`,
|
|
4367
|
+
* and that string is its *name*. So the collection a path starts with is not
|
|
4368
|
+
* its first segment but the longest run of whole leading segments that names
|
|
4369
|
+
* one, and what follows it is `entityId/subcollection/…`.
|
|
4370
|
+
*
|
|
4371
|
+
* Whole segments only, so `content` never matches the start of `contents/1`.
|
|
4372
|
+
*/
|
|
4373
|
+
function splitAtLeadingCollection(segments, find) {
|
|
4374
|
+
for (let length = segments.length; length > 0; length--) {
|
|
4375
|
+
const collection = find(segments.slice(0, length).join("/"));
|
|
4376
|
+
if (collection) return {
|
|
4377
|
+
collection,
|
|
4378
|
+
rest: segments.slice(length)
|
|
4379
|
+
};
|
|
4380
|
+
}
|
|
4381
|
+
}
|
|
4234
4382
|
//#endregion
|
|
4235
4383
|
//#region ../common/src/collections/engine-support.ts
|
|
4236
4384
|
/**
|
|
@@ -4785,23 +4933,6 @@ function includePaths(tree, prefix = "") {
|
|
|
4785
4933
|
}
|
|
4786
4934
|
return out;
|
|
4787
4935
|
}
|
|
4788
|
-
/**
|
|
4789
|
-
* The relation names an `include` asks for at the top level.
|
|
4790
|
-
*
|
|
4791
|
-
* `["author", "comments.author"]` and `{author: true, comments: {...}}` both
|
|
4792
|
-
* answer `["author", "comments"]` — a *hop*, not a path, because the only
|
|
4793
|
-
* consumer is `?fields=`, which names keys on the row being returned and a
|
|
4794
|
-
* nested relation is not one of those.
|
|
4795
|
-
*
|
|
4796
|
-
* Derived rather than passed: `include` has four spellings and three of them
|
|
4797
|
-
* are not a `string[]`, so every consumer that wants the plain names either
|
|
4798
|
-
* calls this or reimplements the flattening.
|
|
4799
|
-
*/
|
|
4800
|
-
function topLevelIncludeNames(spec) {
|
|
4801
|
-
const normalized = normalizeInclude(spec);
|
|
4802
|
-
if (!normalized) return [];
|
|
4803
|
-
return Object.keys(normalized.tree);
|
|
4804
|
-
}
|
|
4805
4936
|
/** Whether any node in the tree carries per-relation options. */
|
|
4806
4937
|
function hasOptions(tree) {
|
|
4807
4938
|
return Object.values(tree).some((node) => node.limit !== void 0 || node.where !== void 0 || node.logical !== void 0 || node.orderBy !== void 0 || node.fields !== void 0 || hasOptions(node.children));
|
|
@@ -6110,7 +6241,7 @@ function inlineRelationRefs(row) {
|
|
|
6110
6241
|
}
|
|
6111
6242
|
return out ?? row;
|
|
6112
6243
|
}
|
|
6113
|
-
function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
6244
|
+
function createDriverAccessor(driver, slug, getPks = () => [], toViewModel, storedPath = () => slug) {
|
|
6114
6245
|
const accessor = {
|
|
6115
6246
|
async find(params) {
|
|
6116
6247
|
const filter = params?.where ? deserializeFilter(params.where) : void 0;
|
|
@@ -6120,7 +6251,7 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6120
6251
|
const startAfter = cursor ? cursorToStartAfter(cursor) : void 0;
|
|
6121
6252
|
const probeLimit = startAfter ? limit + 1 : limit;
|
|
6122
6253
|
const fetchService = driver.restFetchService;
|
|
6123
|
-
const fetched = fetchService ? await fetchService.fetchCollectionForRest(
|
|
6254
|
+
const fetched = fetchService ? await fetchService.fetchCollectionForRest(storedPath(), {
|
|
6124
6255
|
filter,
|
|
6125
6256
|
logical: params?.logical,
|
|
6126
6257
|
limit: probeLimit,
|
|
@@ -6131,7 +6262,7 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6131
6262
|
fields: params?.fields,
|
|
6132
6263
|
distinct: params?.distinct
|
|
6133
6264
|
}, params?.include) : await driver.fetchCollection({
|
|
6134
|
-
path:
|
|
6265
|
+
path: storedPath(),
|
|
6135
6266
|
limit: probeLimit,
|
|
6136
6267
|
offset: startAfter ? void 0 : driverOffset,
|
|
6137
6268
|
startAfter,
|
|
@@ -6149,7 +6280,7 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6149
6280
|
let hasMore = seeking ? fetched.length > limit : rows.length >= limit;
|
|
6150
6281
|
if (driver.count) {
|
|
6151
6282
|
total = await driver.count({
|
|
6152
|
-
path:
|
|
6283
|
+
path: storedPath(),
|
|
6153
6284
|
filter,
|
|
6154
6285
|
logical: params?.logical,
|
|
6155
6286
|
searchString: params?.searchString
|
|
@@ -6157,7 +6288,7 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6157
6288
|
if (!seeking) hasMore = offset + rows.length < total;
|
|
6158
6289
|
}
|
|
6159
6290
|
const last = rows[rows.length - 1];
|
|
6160
|
-
const nextCursor = hasMore && last && driver.restFetchService?.cursorFor ? driver.restFetchService.cursorFor(
|
|
6291
|
+
const nextCursor = hasMore && last && driver.restFetchService?.cursorFor ? driver.restFetchService.cursorFor(storedPath(), last, orderBy) : void 0;
|
|
6161
6292
|
return {
|
|
6162
6293
|
data: rows.map((row) => rowToEntity(row, slug, getPks(), toViewModel)),
|
|
6163
6294
|
meta: {
|
|
@@ -6171,23 +6302,39 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6171
6302
|
},
|
|
6172
6303
|
async findById(id) {
|
|
6173
6304
|
const fetchService = driver.restFetchService;
|
|
6174
|
-
const row = fetchService ? await fetchService.fetchOneForRest(
|
|
6175
|
-
path:
|
|
6305
|
+
const row = fetchService ? await fetchService.fetchOneForRest(storedPath(), id) : await driver.fetchOne({
|
|
6306
|
+
path: storedPath(),
|
|
6176
6307
|
id
|
|
6177
6308
|
});
|
|
6178
6309
|
return row ? rowToEntity(row, slug, getPks(), toViewModel) : void 0;
|
|
6179
6310
|
},
|
|
6180
|
-
aggregate: driver.restFetchService?.aggregate ? async (params) =>
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6311
|
+
aggregate: driver.restFetchService?.aggregate ? async (params) => {
|
|
6312
|
+
const limit = (params.groupBy?.length ?? 0) > 0 ? params.limit : void 0;
|
|
6313
|
+
const rows = await driver.restFetchService.aggregate(storedPath(), {
|
|
6314
|
+
aggregates: params.select.map(toDriverAggregate),
|
|
6315
|
+
groupBy: params.groupBy,
|
|
6316
|
+
filter: params.where ? deserializeFilter(params.where) : void 0,
|
|
6317
|
+
logical: params.logical,
|
|
6318
|
+
searchString: params.searchString,
|
|
6319
|
+
limit: limit !== void 0 ? limit + 1 : params.limit,
|
|
6320
|
+
offset: params.offset
|
|
6321
|
+
});
|
|
6322
|
+
if (limit === void 0) return rows;
|
|
6323
|
+
const page = rows.slice(0, limit);
|
|
6324
|
+
const meta = {
|
|
6325
|
+
limit,
|
|
6326
|
+
offset: params.offset ?? 0,
|
|
6327
|
+
hasMore: rows.length > limit
|
|
6328
|
+
};
|
|
6329
|
+
Object.defineProperty(page, "meta", {
|
|
6330
|
+
value: meta,
|
|
6331
|
+
enumerable: false
|
|
6332
|
+
});
|
|
6333
|
+
return page;
|
|
6334
|
+
} : void 0,
|
|
6188
6335
|
async create(data, id) {
|
|
6189
6336
|
return rowToEntity(await driver.save({
|
|
6190
|
-
path:
|
|
6337
|
+
path: storedPath(),
|
|
6191
6338
|
values: data,
|
|
6192
6339
|
id,
|
|
6193
6340
|
status: "new"
|
|
@@ -6195,7 +6342,7 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6195
6342
|
},
|
|
6196
6343
|
createMany: driver.saveMany ? async (data, options) => {
|
|
6197
6344
|
return (await driver.saveMany({
|
|
6198
|
-
path:
|
|
6345
|
+
path: storedPath(),
|
|
6199
6346
|
rows: data,
|
|
6200
6347
|
upsert: options?.upsert,
|
|
6201
6348
|
onConflict: options?.onConflict
|
|
@@ -6203,7 +6350,7 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6203
6350
|
} : void 0,
|
|
6204
6351
|
async update(id, data) {
|
|
6205
6352
|
return rowToEntity(await driver.save({
|
|
6206
|
-
path:
|
|
6353
|
+
path: storedPath(),
|
|
6207
6354
|
values: data,
|
|
6208
6355
|
id,
|
|
6209
6356
|
status: "existing"
|
|
@@ -6212,12 +6359,12 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6212
6359
|
async delete(id) {
|
|
6213
6360
|
return driver.delete({ row: {
|
|
6214
6361
|
id,
|
|
6215
|
-
path:
|
|
6362
|
+
path: storedPath()
|
|
6216
6363
|
} });
|
|
6217
6364
|
},
|
|
6218
6365
|
updateMany: driver.updateMany ? async (updates) => {
|
|
6219
6366
|
return (await driver.updateMany({
|
|
6220
|
-
path:
|
|
6367
|
+
path: storedPath(),
|
|
6221
6368
|
updates: updates.map((u) => ({
|
|
6222
6369
|
id: u.id,
|
|
6223
6370
|
values: u.data
|
|
@@ -6226,14 +6373,14 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6226
6373
|
} : void 0,
|
|
6227
6374
|
deleteMany: driver.deleteMany ? async (ids) => {
|
|
6228
6375
|
await driver.deleteMany({
|
|
6229
|
-
path:
|
|
6376
|
+
path: storedPath(),
|
|
6230
6377
|
ids
|
|
6231
6378
|
});
|
|
6232
6379
|
} : void 0,
|
|
6233
6380
|
count: driver.count ? async (params) => {
|
|
6234
6381
|
const filter = params?.where ? deserializeFilter(params.where) : void 0;
|
|
6235
6382
|
return driver.count({
|
|
6236
|
-
path:
|
|
6383
|
+
path: storedPath(),
|
|
6237
6384
|
filter,
|
|
6238
6385
|
logical: params?.logical,
|
|
6239
6386
|
searchString: params?.searchString
|
|
@@ -6243,7 +6390,7 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6243
6390
|
const { limit, offset, driverOffset } = resolveFindWindow(params);
|
|
6244
6391
|
const normalize = driver.restFetchService ? inlineRelationRefs : (row) => row;
|
|
6245
6392
|
return driver.listenCollection({
|
|
6246
|
-
path:
|
|
6393
|
+
path: storedPath(),
|
|
6247
6394
|
limit,
|
|
6248
6395
|
offset: driverOffset,
|
|
6249
6396
|
filter: params?.where,
|
|
@@ -6269,7 +6416,7 @@ function createDriverAccessor(driver, slug, getPks = () => [], toViewModel) {
|
|
|
6269
6416
|
listenById: driver.listenOne ? (id, onUpdate, onError) => {
|
|
6270
6417
|
const normalize = driver.restFetchService ? inlineRelationRefs : (row) => row;
|
|
6271
6418
|
return driver.listenOne({
|
|
6272
|
-
path:
|
|
6419
|
+
path: storedPath(),
|
|
6273
6420
|
id,
|
|
6274
6421
|
onUpdate: (entity) => onUpdate(entity ? rowToEntity(normalize(entity), slug, getPks(), toViewModel) : void 0),
|
|
6275
6422
|
onError
|
|
@@ -6338,7 +6485,7 @@ function buildRebaseData(driver, options) {
|
|
|
6338
6485
|
function getAccessor(slug) {
|
|
6339
6486
|
let accessor = cache.get(slug);
|
|
6340
6487
|
if (!accessor) {
|
|
6341
|
-
accessor = createDriverAccessor(driver, slug, () => primaryKeysFor(slug), viewModelFor(slug));
|
|
6488
|
+
accessor = createDriverAccessor(driver, slug, () => primaryKeysFor(slug), viewModelFor(slug), () => options?.resolveDataPath?.(slug) ?? slug);
|
|
6342
6489
|
cache.set(slug, accessor);
|
|
6343
6490
|
}
|
|
6344
6491
|
return accessor;
|
|
@@ -6495,6 +6642,31 @@ var SdkQueryBuilder = class {
|
|
|
6495
6642
|
}
|
|
6496
6643
|
};
|
|
6497
6644
|
/**
|
|
6645
|
+
* Refuse a write option this door cannot honour, by name, before anything is
|
|
6646
|
+
* written.
|
|
6647
|
+
*
|
|
6648
|
+
* The in-process accessor implements the same `SDKCollectionClient` as the HTTP
|
|
6649
|
+
* client, whose `ifMatch` is "Honoured on `update` and `delete`" — and its
|
|
6650
|
+
* writes took no options at all, so `rebase.data.posts.update(id, data, {
|
|
6651
|
+
* ifMatch: staleEtag })` overwrote the row and resolved. A precondition the
|
|
6652
|
+
* caller wrote, dropped without a word, is the worst thing a door can do with
|
|
6653
|
+
* it. The driver's `save` has no precondition and no idempotency store to hand
|
|
6654
|
+
* these to, so they are refused rather than ignored. An `undefined` value is no
|
|
6655
|
+
* option, as it is over HTTP: `etagOf(row)` is `undefined` for a row that
|
|
6656
|
+
* carries no version, and that means "write unconditionally".
|
|
6657
|
+
*/
|
|
6658
|
+
function refuseUnhonouredWriteOptions(method, slug, options) {
|
|
6659
|
+
const unsupported = ["ifMatch", "idempotencyKey"].filter((key) => options?.[key]);
|
|
6660
|
+
if (unsupported.length === 0) return;
|
|
6661
|
+
throw new RebaseClientError(`${method}() on "${slug}" in-process (context.data, rebase.data) cannot honour ${unsupported.join(" or ")}: this door has no ${unsupported.includes("ifMatch") ? "precondition check" : "idempotency store"}, and ignoring the option would write as though it had been checked. Drop it here, or send the write through the HTTP client, which honours it.`, {
|
|
6662
|
+
code: "UNSUPPORTED_OPTION",
|
|
6663
|
+
details: {
|
|
6664
|
+
method,
|
|
6665
|
+
options: unsupported
|
|
6666
|
+
}
|
|
6667
|
+
});
|
|
6668
|
+
}
|
|
6669
|
+
/**
|
|
6498
6670
|
* Wrap a Entity-shaped {@link CollectionAccessor} into a flat
|
|
6499
6671
|
* {@link SDKCollectionClient}. Every returned record is unwrapped to a flat row
|
|
6500
6672
|
* so the backend SDK is byte-for-byte the same shape as the frontend client.
|
|
@@ -6526,14 +6698,19 @@ function toSdkCollectionClient(snap, slug = "collection") {
|
|
|
6526
6698
|
});
|
|
6527
6699
|
return entityToRow(s);
|
|
6528
6700
|
},
|
|
6529
|
-
async create(data, id) {
|
|
6701
|
+
async create(data, id, options) {
|
|
6702
|
+
refuseUnhonouredWriteOptions("create", slug, options);
|
|
6530
6703
|
return entityToRow(await snap.create(data, id));
|
|
6531
6704
|
},
|
|
6532
6705
|
async createMany(data, options) {
|
|
6706
|
+
refuseUnhonouredWriteOptions("createMany", slug, options);
|
|
6533
6707
|
if (!Array.isArray(data)) throw new TypeError("createMany expects an array of records.");
|
|
6534
6708
|
if (data.length === 0) return [];
|
|
6535
6709
|
if (!snap.createMany) throw new Error("Bulk writes are not supported by this collection's data source. Fall back to create() per record.");
|
|
6536
|
-
return (await snap.createMany(data,
|
|
6710
|
+
return (await snap.createMany(data, {
|
|
6711
|
+
upsert: options?.upsert,
|
|
6712
|
+
onConflict: options?.onConflict
|
|
6713
|
+
})).map(entityToRow);
|
|
6537
6714
|
},
|
|
6538
6715
|
/**
|
|
6539
6716
|
* One row through the bulk path, because the bulk path is where the
|
|
@@ -6545,6 +6722,7 @@ function toSdkCollectionClient(snap, slug = "collection") {
|
|
|
6545
6722
|
* one is exactly an upsert of one.
|
|
6546
6723
|
*/
|
|
6547
6724
|
async upsert(data, options) {
|
|
6725
|
+
refuseUnhonouredWriteOptions("upsert", slug, options);
|
|
6548
6726
|
if (!snap.createMany) throw new Error("Upsert is not supported by this collection's data source: it needs a bulk write, which this driver does not implement. Fall back to create() or update().");
|
|
6549
6727
|
const row = (await snap.createMany([data], {
|
|
6550
6728
|
upsert: true,
|
|
@@ -6553,10 +6731,12 @@ function toSdkCollectionClient(snap, slug = "collection") {
|
|
|
6553
6731
|
if (!row) throw new Error(`Upsert into "${slug}" returned no row.`);
|
|
6554
6732
|
return entityToRow(row);
|
|
6555
6733
|
},
|
|
6556
|
-
async update(id, data) {
|
|
6734
|
+
async update(id, data, options) {
|
|
6735
|
+
refuseUnhonouredWriteOptions("update", slug, options);
|
|
6557
6736
|
return entityToRow(await snap.update(id, data));
|
|
6558
6737
|
},
|
|
6559
|
-
async updateMany(updates) {
|
|
6738
|
+
async updateMany(updates, options) {
|
|
6739
|
+
refuseUnhonouredWriteOptions("updateMany", slug, options);
|
|
6560
6740
|
if (!Array.isArray(updates)) throw new TypeError("updateMany expects an array of { id, data } entries.");
|
|
6561
6741
|
if (updates.length === 0) return [];
|
|
6562
6742
|
if (!snap.updateMany) throw new Error("Bulk updates are not supported by this collection's data source. Fall back to update() per record.");
|
|
@@ -6565,10 +6745,12 @@ function toSdkCollectionClient(snap, slug = "collection") {
|
|
|
6565
6745
|
data: u.data
|
|
6566
6746
|
})))).map(entityToRow);
|
|
6567
6747
|
},
|
|
6568
|
-
delete(id) {
|
|
6748
|
+
async delete(id, options) {
|
|
6749
|
+
refuseUnhonouredWriteOptions("delete", slug, options);
|
|
6569
6750
|
return snap.delete(id);
|
|
6570
6751
|
},
|
|
6571
|
-
async deleteMany(ids) {
|
|
6752
|
+
async deleteMany(ids, options) {
|
|
6753
|
+
refuseUnhonouredWriteOptions("deleteMany", slug, options);
|
|
6572
6754
|
if (!Array.isArray(ids)) throw new TypeError("deleteMany expects an array of ids.");
|
|
6573
6755
|
if (ids.length === 0) return;
|
|
6574
6756
|
if (!snap.deleteMany) throw new Error("Bulk deletes are not supported by this collection's data source. Fall back to delete() per record.");
|
|
@@ -6683,6 +6865,6 @@ function buildRoutedRebaseData({ defaultData, sources, resolveKey }) {
|
|
|
6683
6865
|
}
|
|
6684
6866
|
new Set(REBASE_INTERNAL_TABLES);
|
|
6685
6867
|
//#endregion
|
|
6686
|
-
export {
|
|
6868
|
+
export { unref as $, isRelationalCollection as A, findRelation as B, decodeCursor as C, assertBeforeQueryIsPostgresOnly as D, restrictedFieldNames as E, getJunctionConfigForRelation as F, enumToObjectEntries as G, isRelationRequired as H, getEffectiveSecurityRules as I, hydrateRegExp as J, buildCompositeId as K, getTenantConfig as L, authSecretsMissingExclusion as M, REBASE_USER_ROLE as N, CollectionRegistry as O, revokeInternalTableSql as P, toSnakeCase as Q, securityRuleToConditions as R, cursorToStartAfter as S, effectiveAccess as T, relationDeclaringProperty as U, getTableName as V, resolveCollectionRelations as W, splitSearchTerms as X, isObject as Y, suggestNearMiss as Z, OrderBySpecError as _, RebaseApiError as _t, deserializeFilter as a, hasFieldOperation as at, CursorError as b, unsupportedMethod as bt, serializeLogicalCondition as c, isAnonymousUid as ct, resolveFindWindow as d, isManyToMany as dt, ListLimitError as et, IncludeSpecError as f, isToMany as ft, serializeInclude as g, Vector as gt, normalizeInclude as h, GeoPoint as ht, UnknownFilterOperatorError as i, FIELD_OPERATORS as it, resolveDataSource as j, createDataSourceRegistry as k, collectAllPages as l, JUNCTION_PIVOT_KEY as lt, mergeIncludeSpecs as m, EntityRelation as mt, buildSdkData as n, resolveClientListLimit as nt, deserializeLogicalCondition as o, isFieldOperation as ot, deserializeInclude as p, EntityReference as pt, resolvePrimaryKeys as q, RESERVED_QUERY_KEYS as r, BATCH_REF_KEY as rt, serializeFilter as s, ANONYMOUS_USER_ID as st, buildRoutedRebaseData as t, MAX_LIST_LIMIT as tt, paginateFind as u, hasForeignKeyOnTarget as ut, normalizeOrderBy as v, RebaseClientError as vt, reconcileCursorOrder as w, CursorMismatchError as x, serializeOrderBy as y, isUnsupported as yt, fieldKeyForColumn as z };
|
|
6687
6869
|
|
|
6688
|
-
//# sourceMappingURL=src-
|
|
6870
|
+
//# sourceMappingURL=src-I3aG1PcY.js.map
|