@rebasepro/server 0.21.2-canary.g1ea48be → 0.23.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/dist/{GCSStorageController-CLIJXwGS.js → GCSStorageController-CjrA4PMo.js} +37 -23
- package/dist/GCSStorageController-CjrA4PMo.js.map +1 -0
- package/dist/{S3StorageController-Dcuf8lMA.js → S3StorageController-B6pKDNVj.js} +2 -2
- package/dist/{S3StorageController-Dcuf8lMA.js.map → S3StorageController-B6pKDNVj.js.map} +1 -1
- package/dist/api/ast-schema-editor.d.ts +35 -0
- package/dist/api/live-schema-routes.d.ts +14 -0
- package/dist/api/rest/api-generator.d.ts +117 -35
- package/dist/api/rest/auth-collection-writes.d.ts +85 -0
- package/dist/api/rest/field-access-query.d.ts +6 -2
- package/dist/api/rest/idempotency.d.ts +7 -1
- package/dist/api/rest/nested-write-access.d.ts +46 -0
- package/dist/api/rest/write-validation.d.ts +32 -0
- package/dist/{ast-schema-editor-CslO8Oje.js → ast-schema-editor-Mvr50v_S.js} +104 -4
- package/dist/ast-schema-editor-Mvr50v_S.js.map +1 -0
- package/dist/auth/address-ownership.d.ts +53 -0
- package/dist/auth/admin-user-ops.d.ts +35 -2
- package/dist/auth/auth-hooks.d.ts +4 -0
- package/dist/auth/captcha.d.ts +5 -0
- package/dist/auth/interfaces.d.ts +36 -6
- package/dist/auth/jwt.d.ts +17 -0
- package/dist/auth/oauth-signin-policy.d.ts +25 -8
- package/dist/auth/rate-limiter.d.ts +31 -1
- package/dist/auth/session-routes.d.ts +7 -0
- package/dist/auth/token-revocation.d.ts +4 -1
- package/dist/{auth-DZXQRmYD.js → auth-B-GIMpDG.js} +643 -230
- package/dist/auth-B-GIMpDG.js.map +1 -0
- package/dist/backend-DTAOsLQc.js +30 -0
- package/dist/backend-DTAOsLQc.js.map +1 -0
- package/dist/backup/backup-common.d.ts +19 -0
- package/dist/{backup-DzI9jLwc.js → backup-D7YR94N3.js} +69 -8
- package/dist/backup-D7YR94N3.js.map +1 -0
- package/dist/boot/driver.d.ts +10 -0
- package/dist/boot/env.d.ts +2 -2
- package/dist/boot/fetch-bundle.d.ts +18 -1
- package/dist/boot/rls-audit-option.d.ts +26 -0
- package/dist/boot/sources.d.ts +1 -0
- package/dist/{contract-routes-eLxV0le1.js → contract-routes-CbFjuBwa.js} +2 -2
- package/dist/{contract-routes-eLxV0le1.js.map → contract-routes-CbFjuBwa.js.map} +1 -1
- package/dist/cron/cron-routes.d.ts +7 -2
- package/dist/cron/cron-scheduler.d.ts +128 -8
- package/dist/cron/cron-store.d.ts +72 -8
- package/dist/cron/index.d.ts +1 -1
- package/dist/{cron-loader-CQjvjpEw.js → cron-loader-DfTj2Hbi.js} +2 -2
- package/dist/{cron-loader-CQjvjpEw.js.map → cron-loader-DfTj2Hbi.js.map} +1 -1
- package/dist/{cron-routes-cv0hSd-O.js → cron-routes-eE8nif_b.js} +33 -12
- package/dist/cron-routes-eE8nif_b.js.map +1 -0
- package/dist/{cron-scheduler-COPQxlEq.js → cron-scheduler-B0pLfAix.js} +394 -68
- package/dist/cron-scheduler-B0pLfAix.js.map +1 -0
- package/dist/{cron-store-Bdm7JqFB.js → cron-store-TcoGz-xS.js} +133 -12
- package/dist/cron-store-TcoGz-xS.js.map +1 -0
- package/dist/{ddl-bootstrap-CfNvxMuK.js → ddl-bootstrap-C6mo0Kmz.js} +2 -25
- package/dist/ddl-bootstrap-C6mo0Kmz.js.map +1 -0
- package/dist/email/link-base.d.ts +5 -4
- package/dist/email/smtp-email-service.d.ts +13 -1
- package/dist/email/templates.d.ts +9 -0
- package/dist/email/types.d.ts +3 -2
- package/dist/env.d.ts +24 -5
- package/dist/{history-recorder-CYfkqP2X.js → history-recorder-B4MpJfJK.js} +8 -6
- package/dist/history-recorder-B4MpJfJK.js.map +1 -0
- package/dist/{history-store-B1CBwLfi.js → history-store-BhxWOuz9.js} +2 -2
- package/dist/{history-store-B1CBwLfi.js.map → history-store-BhxWOuz9.js.map} +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.es.js +2769 -878
- package/dist/index.es.js.map +1 -1
- package/dist/init/docs.d.ts +5 -2
- package/dist/init/global-callbacks.d.ts +21 -0
- package/dist/init/shutdown.d.ts +8 -3
- package/dist/jobs/index.d.ts +2 -2
- package/dist/jobs/job-queue.d.ts +23 -2
- package/dist/jobs/job-store.d.ts +37 -5
- package/dist/jobs/types.d.ts +8 -6
- package/dist/{jobs-2fO2BI8P.js → jobs-CazMYhyy.js} +305 -166
- package/dist/jobs-CazMYhyy.js.map +1 -0
- package/dist/{jwt-C4OW-DNq.js → jwt-DnQHNFCl.js} +77 -25
- package/dist/{jwt-C4OW-DNq.js.map → jwt-DnQHNFCl.js.map} +1 -1
- package/dist/{keys-Qfc4XieN.js → keys-CogCQpxG.js} +18 -3
- package/dist/{keys-Qfc4XieN.js.map → keys-CogCQpxG.js.map} +1 -1
- package/dist/{logs-routes-3EEzPjhl.js → logs-routes-Bj4TYYUl.js} +7 -4
- package/dist/{logs-routes-3EEzPjhl.js.map → logs-routes-Bj4TYYUl.js.map} +1 -1
- package/dist/mcp/mcp-routes.d.ts +38 -2
- package/dist/mcp/mcp-tools.d.ts +7 -1
- package/dist/mcp/oauth-routes.d.ts +27 -0
- package/dist/mcp/oauth-store.d.ts +29 -13
- package/dist/metrics/history-recorder.d.ts +1 -1
- package/dist/{openapi-generator-D8ZIN_ss.js → openapi-generator-O_O24MAT.js} +34 -12
- package/dist/openapi-generator-O_O24MAT.js.map +1 -0
- package/dist/{query-parser-CoIOmflr.js → query-parser-DGRVFNM3.js} +39 -30
- package/dist/query-parser-DGRVFNM3.js.map +1 -0
- package/dist/rls-audit/index.d.ts +4 -0
- package/dist/{schema-editor-routes-DdLihzp0.js → schema-editor-routes-C5-lh_jO.js} +2 -2
- package/dist/{schema-editor-routes-DdLihzp0.js.map → schema-editor-routes-C5-lh_jO.js.map} +1 -1
- package/dist/{src-BYax9_rm.js → src-pmvW7BFx.js} +189 -14
- package/dist/src-pmvW7BFx.js.map +1 -0
- package/dist/{src-Br6ARbs6.js → src-vkcwKXbT.js} +2 -27
- package/dist/{src-Br6ARbs6.js.map → src-vkcwKXbT.js.map} +1 -1
- package/dist/storage/GCSStorageController.d.ts +11 -1
- package/dist/storage/keys.d.ts +12 -0
- package/dist/storage/rendition-cache.d.ts +11 -1
- package/dist/storage/request-keys.d.ts +67 -0
- package/dist/storage/types.d.ts +17 -1
- package/dist/types-BfKcm9do.js.map +1 -1
- package/package.json +9 -9
- package/dist/GCSStorageController-CLIJXwGS.js.map +0 -1
- package/dist/ast-schema-editor-CslO8Oje.js.map +0 -1
- package/dist/auth-DZXQRmYD.js.map +0 -1
- package/dist/backup-DzI9jLwc.js.map +0 -1
- package/dist/cron-routes-cv0hSd-O.js.map +0 -1
- package/dist/cron-scheduler-COPQxlEq.js.map +0 -1
- package/dist/cron-store-Bdm7JqFB.js.map +0 -1
- package/dist/ddl-bootstrap-CfNvxMuK.js.map +0 -1
- package/dist/history-recorder-CYfkqP2X.js.map +0 -1
- package/dist/jobs-2fO2BI8P.js.map +0 -1
- package/dist/openapi-generator-D8ZIN_ss.js.map +0 -1
- package/dist/query-parser-CoIOmflr.js.map +0 -1
- package/dist/src-BYax9_rm.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 { A as
|
|
6
|
+
import { A as NULL_OPS, C as isPostgresCollectionConfig, D as ALL_WHERE_FILTER_OPS, E as getDataSourceCapabilities, F as toCanonicalOp, M as isRelationAggregateSort, O as CANONICAL_TO_REST, P as sortKeyToString, S as getDeclaredSubcollections, b as rewriteLegacyRlsFunctions, f as resolveResourceRefs, j as REST_TO_CANONICAL, k as LIST_OPS, w as isRelationalCollectionConfig } from "./src-vkcwKXbT.js";
|
|
7
7
|
//#region ../types/src/errors.ts
|
|
8
8
|
/**
|
|
9
9
|
* The single error type thrown across the entire Rebase client surface —
|
|
@@ -261,6 +261,10 @@ var Vector = class {
|
|
|
261
261
|
*/
|
|
262
262
|
var JUNCTION_PIVOT_KEY = "_pivot";
|
|
263
263
|
/** @group Models */
|
|
264
|
+
function hasForeignKeyOnTarget(relation) {
|
|
265
|
+
return relation.kind === "hasOne" || relation.kind === "hasMany";
|
|
266
|
+
}
|
|
267
|
+
/** @group Models */
|
|
264
268
|
function isManyToMany(relation) {
|
|
265
269
|
return relation.kind === "manyToMany";
|
|
266
270
|
}
|
|
@@ -1528,6 +1532,42 @@ function suggestNearMiss(known, key) {
|
|
|
1528
1532
|
return known.find((candidate) => isNearMiss(candidate, key));
|
|
1529
1533
|
}
|
|
1530
1534
|
/**
|
|
1535
|
+
* The terms a user meant when they typed into a search box.
|
|
1536
|
+
*
|
|
1537
|
+
* A search box is not a substring box. Typing `sebastian melendez` on a
|
|
1538
|
+
* collection whose name is split across `first_name` and `last_name` has to
|
|
1539
|
+
* find the row, and matching the whole string against each field separately
|
|
1540
|
+
* cannot: no single column holds both words. Splitting on whitespace and
|
|
1541
|
+
* requiring *every* term to match *some* field is what does, and it is what
|
|
1542
|
+
* `websearch_to_tsquery` already does for collections that declared a `search`
|
|
1543
|
+
* block — so this is also what keeps the two search paths answering the same
|
|
1544
|
+
* question.
|
|
1545
|
+
*
|
|
1546
|
+
* It fixes the trailing space too: `sebastian ` matched nothing at all, because
|
|
1547
|
+
* the space was part of the pattern.
|
|
1548
|
+
*
|
|
1549
|
+
* A double-quoted run is one term, again matching the full-text path, so a
|
|
1550
|
+
* caller who really does want the phrase can ask for it. An unbalanced quote is
|
|
1551
|
+
* stripped rather than honoured — the alternative is that everything after a
|
|
1552
|
+
* stray `"` silently becomes one long term that matches nothing.
|
|
1553
|
+
*
|
|
1554
|
+
* Returns an empty array for a string with no terms in it at all (whitespace,
|
|
1555
|
+
* or nothing but quotes); the caller decides what an empty search means, since
|
|
1556
|
+
* only it knows whether "no constraint" or "no rows" is the safe reading.
|
|
1557
|
+
*/
|
|
1558
|
+
function splitSearchTerms(searchString, maxTerms = 8) {
|
|
1559
|
+
const terms = [];
|
|
1560
|
+
const pattern = /"([^"]*)"|(\S+)/g;
|
|
1561
|
+
let match;
|
|
1562
|
+
while ((match = pattern.exec(searchString)) !== null) {
|
|
1563
|
+
const term = (match[1] ?? match[2].replace(/"/g, "")).trim();
|
|
1564
|
+
if (!term) continue;
|
|
1565
|
+
terms.push(term);
|
|
1566
|
+
if (terms.length >= maxTerms) break;
|
|
1567
|
+
}
|
|
1568
|
+
return terms;
|
|
1569
|
+
}
|
|
1570
|
+
/**
|
|
1531
1571
|
* Deep clone a value, preserving function references and class instances.
|
|
1532
1572
|
* Unlike structuredClone, this handles objects that contain functions
|
|
1533
1573
|
* (e.g. CollectionConfig with target(), childCollections(), callbacks).
|
|
@@ -3230,6 +3270,7 @@ var REBASE_INTERNAL_TABLES = [
|
|
|
3230
3270
|
"api_keys",
|
|
3231
3271
|
"cron_logs",
|
|
3232
3272
|
"cron_claims",
|
|
3273
|
+
"cron_job_state",
|
|
3233
3274
|
"jobs",
|
|
3234
3275
|
"rate_limit_hits",
|
|
3235
3276
|
"idempotency_keys",
|
|
@@ -4190,6 +4231,37 @@ var CollectionRegistry = class {
|
|
|
4190
4231
|
};
|
|
4191
4232
|
}
|
|
4192
4233
|
};
|
|
4234
|
+
//#endregion
|
|
4235
|
+
//#region ../common/src/collections/engine-support.ts
|
|
4236
|
+
/**
|
|
4237
|
+
* Refuse a `beforeQuery` hook on a collection Postgres does not serve.
|
|
4238
|
+
*
|
|
4239
|
+
* `beforeQuery` narrows a read *before it is compiled*, which means compiling
|
|
4240
|
+
* a declarative filter into the query the engine is about to run. Only
|
|
4241
|
+
* `@rebasepro/server-postgres` does that today. On any other engine the hook
|
|
4242
|
+
* would look configured and do nothing — and for a hook whose whole purpose is
|
|
4243
|
+
* to restrict which rows come back, "nothing" means every row served to
|
|
4244
|
+
* everybody.
|
|
4245
|
+
*
|
|
4246
|
+
* So it is a boot failure, named. The alternative — declaring the hook only on
|
|
4247
|
+
* `PostgresCollectionConfig`, the way `search` is — is not available:
|
|
4248
|
+
* `callbacks` is one engine-agnostic type shared by every collection, and
|
|
4249
|
+
* splitting it would fork `afterRead` and the five write hooks along with it.
|
|
4250
|
+
*
|
|
4251
|
+
* Lives here rather than in either driver because both have to run it: the
|
|
4252
|
+
* Postgres schema planner sees every collection in a mixed app, and a
|
|
4253
|
+
* Mongo-only app never boots a Postgres planner at all.
|
|
4254
|
+
*
|
|
4255
|
+
* Called with *every* collection, before an engine filters any out.
|
|
4256
|
+
*/
|
|
4257
|
+
var assertBeforeQueryIsPostgresOnly = (collections) => {
|
|
4258
|
+
for (const collection of collections) {
|
|
4259
|
+
if (isPostgresCollectionConfig(collection)) continue;
|
|
4260
|
+
if (!collection.callbacks?.beforeQuery) continue;
|
|
4261
|
+
const engine = collection.engine ?? "non-postgres";
|
|
4262
|
+
throw new Error(`${collection.slug}.callbacks.beforeQuery: narrowing a read before it is compiled is a Postgres feature, and this collection is served by \`${engine}\`. Remove the hook — it would otherwise look configured while every read kept returning every row the engine allows. Redaction that works on every engine is \`afterRead\`.`);
|
|
4263
|
+
}
|
|
4264
|
+
};
|
|
4193
4265
|
/**
|
|
4194
4266
|
* What a property's access rules actually are, with `excludeFromApi` expanded.
|
|
4195
4267
|
*
|
|
@@ -4250,18 +4322,36 @@ function canWriteField(property, viewer) {
|
|
|
4250
4322
|
* who knows the table can send `password_hash` as readily as `passwordHash`, and
|
|
4251
4323
|
* a rule that only knew the wire name would be one rename away from useless.
|
|
4252
4324
|
*
|
|
4325
|
+
* A restricted to-one relation takes its foreign key with it. `bandId: 7` names
|
|
4326
|
+
* the band exactly as `band: { id: 7 }` does, and the row carries the column
|
|
4327
|
+
* beside the relation — so a rule on the relation that left the key alone
|
|
4328
|
+
* withheld the value from the row and still let `?bandId=7` ask for it.
|
|
4329
|
+
*
|
|
4253
4330
|
* `kind` picks which half of the rule is read; nothing else differs.
|
|
4254
4331
|
*/
|
|
4255
4332
|
function restrictedFieldNames(collection, viewer, kind) {
|
|
4256
4333
|
const declared = [];
|
|
4257
4334
|
const refused = /* @__PURE__ */ new Set();
|
|
4258
4335
|
const allowed = kind === "read" ? canReadField : canWriteField;
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4336
|
+
const properties = collection.properties ?? {};
|
|
4337
|
+
let relations;
|
|
4338
|
+
const restrict = (name) => {
|
|
4339
|
+
if (name in properties && !declared.includes(name)) declared.push(name);
|
|
4262
4340
|
refused.add(name);
|
|
4341
|
+
};
|
|
4342
|
+
for (const [name, property] of Object.entries(properties)) {
|
|
4343
|
+
if (allowed(property, viewer)) continue;
|
|
4344
|
+
restrict(name);
|
|
4263
4345
|
const columnName = property.columnName;
|
|
4264
4346
|
if (columnName) refused.add(columnName);
|
|
4347
|
+
if (property.type === "relation") {
|
|
4348
|
+
relations ??= resolveCollectionRelations(collection);
|
|
4349
|
+
const relation = findRelation(relations, name);
|
|
4350
|
+
if (relation?.kind === "belongsTo") {
|
|
4351
|
+
restrict(fieldKeyForColumn(collection, relation.localKey));
|
|
4352
|
+
refused.add(relation.localKey);
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4265
4355
|
}
|
|
4266
4356
|
return {
|
|
4267
4357
|
declared,
|
|
@@ -5027,19 +5117,23 @@ function normalizeMaxRows(raw) {
|
|
|
5027
5117
|
* @param label the collection name, so an error says which walk failed
|
|
5028
5118
|
*/
|
|
5029
5119
|
async function* paginateFind(find, params, label = "collection") {
|
|
5030
|
-
const { pageSize, cursor, maxPages, ...rest } = params ?? {};
|
|
5120
|
+
const { pageSize, cursor, maxPages, after: startAfter, offset: startOffset, page: startPage, ...rest } = params ?? {};
|
|
5031
5121
|
const findParams = { ...rest };
|
|
5032
5122
|
const size = normalizePageSize(pageSize);
|
|
5033
5123
|
const pageCap = normalizeMaxPages(maxPages);
|
|
5034
|
-
const seekRequested = cursor !== void 0 && cursor !== null;
|
|
5035
|
-
if (
|
|
5124
|
+
const seekRequested = cursor !== void 0 && cursor !== null || !!startAfter;
|
|
5125
|
+
if (cursor !== void 0 && cursor !== null) {
|
|
5036
5126
|
const field = typeof cursor === "string" ? cursor : cursor.field;
|
|
5037
5127
|
const requested = typeof cursor === "object" && cursor !== null ? cursor.direction : void 0;
|
|
5038
5128
|
if (!normalizeOrderBy(findParams.orderBy)) findParams.orderBy = [field, requested ?? "asc"];
|
|
5039
5129
|
}
|
|
5040
|
-
let offset =
|
|
5130
|
+
let offset = resolveFindWindow({
|
|
5131
|
+
limit: size,
|
|
5132
|
+
offset: startOffset,
|
|
5133
|
+
page: startPage
|
|
5134
|
+
}).offset;
|
|
5041
5135
|
let pages = 0;
|
|
5042
|
-
let after;
|
|
5136
|
+
let after = startAfter || void 0;
|
|
5043
5137
|
for (;;) {
|
|
5044
5138
|
if (pages >= pageCap) throw new RebasePaginationError("max-pages", `Iterating "${label}" made ${pages} requests without the server reporting the end of the collection. Stopping rather than looping forever — raise \`maxPages\` if the walk is genuinely this long, or check that the backend sets \`meta.hasMore\`.`);
|
|
5045
5139
|
const pageParams = {
|
|
@@ -5104,9 +5198,16 @@ async function collectAllPages(find, params, label = "collection") {
|
|
|
5104
5198
|
* Relation values (`EntityRelation` instances or `{ __type: "relation", id, path }`
|
|
5105
5199
|
* objects) are serialized as their raw id — the wire format only carries the
|
|
5106
5200
|
* value to compare against the FK column.
|
|
5201
|
+
*
|
|
5202
|
+
* A `Date` is its ISO 8601 instant — what JSON makes of it on the socket and
|
|
5203
|
+
* in-process, so one filter names one instant through every door. `String()`
|
|
5204
|
+
* gave the viewer's local zone, no milliseconds and a parenthesised zone name
|
|
5205
|
+
* Postgres cannot parse. An invalid date keeps its "Invalid Date" spelling for
|
|
5206
|
+
* the server to refuse, rather than throwing a `RangeError` from here.
|
|
5107
5207
|
*/
|
|
5108
5208
|
function stringifyValue(value) {
|
|
5109
5209
|
if (value === null) return "null";
|
|
5210
|
+
if (value instanceof Date && !Number.isNaN(value.getTime())) return value.toISOString();
|
|
5110
5211
|
const relation = normalizeToEntityRelation(value);
|
|
5111
5212
|
if (relation) return String(relation.id);
|
|
5112
5213
|
return String(value);
|
|
@@ -5164,6 +5265,41 @@ function unescapeWireValue(value) {
|
|
|
5164
5265
|
return result;
|
|
5165
5266
|
}
|
|
5166
5267
|
/**
|
|
5268
|
+
* Whether a scalar, sent raw as a query parameter's operand, would be read
|
|
5269
|
+
* back as something other than itself.
|
|
5270
|
+
*
|
|
5271
|
+
* A query parameter owns its whole value, so its scalar goes out unescaped —
|
|
5272
|
+
* `eq.a,b`, `eq.C:\x` — and the decoder returns it verbatim. Two shapes break
|
|
5273
|
+
* that. A parenthesised operand is a list for every operator (so that
|
|
5274
|
+
* `["==", ["a","b"]]` on an array column stays a list), so raw, the scalar
|
|
5275
|
+
* `"(deleted)"` would arrive as `["deleted"]`: an `==` matching nothing, a
|
|
5276
|
+
* `!=` returning the very rows it excludes. Such a scalar is sent escaped,
|
|
5277
|
+
* `eq.\(deleted\)`. And that spelling has to be told apart from a raw value
|
|
5278
|
+
* that looks the same, so a scalar of *that* shape is escaped in turn.
|
|
5279
|
+
*
|
|
5280
|
+
* Everything else stays raw, so a value an older client sends decodes as it
|
|
5281
|
+
* always has — unless it is exactly the escaped spelling of such a scalar,
|
|
5282
|
+
* which decodes to the scalar it spells.
|
|
5283
|
+
*/
|
|
5284
|
+
function scalarNeedsEscape(value) {
|
|
5285
|
+
if (value.startsWith("(") && value.endsWith(")")) return true;
|
|
5286
|
+
return decodeEscapedScalar(value) !== void 0;
|
|
5287
|
+
}
|
|
5288
|
+
/**
|
|
5289
|
+
* The scalar an operand is the escaped spelling of, when it is one.
|
|
5290
|
+
*
|
|
5291
|
+
* Exact on purpose: only an operand that {@link escapeWireValue} produces from
|
|
5292
|
+
* a scalar that {@link scalarNeedsEscape} is decoded. Any other operand —
|
|
5293
|
+
* including a raw backslash an older client sent, like `\\server\share` — is
|
|
5294
|
+
* left verbatim. Terminates because an operand that matches contains an
|
|
5295
|
+
* escape pair, so the value is strictly shorter than it.
|
|
5296
|
+
*/
|
|
5297
|
+
function decodeEscapedScalar(operand) {
|
|
5298
|
+
if (!operand.startsWith("\\")) return void 0;
|
|
5299
|
+
const value = unescapeWireValue(operand);
|
|
5300
|
+
return escapeWireValue(value) === operand && scalarNeedsEscape(value) ? value : void 0;
|
|
5301
|
+
}
|
|
5302
|
+
/**
|
|
5167
5303
|
* Split a parenthesized list string on unescaped commas.
|
|
5168
5304
|
* Input is the content between `(` and `)`.
|
|
5169
5305
|
*
|
|
@@ -5408,6 +5544,42 @@ function readTuple(field, raw) {
|
|
|
5408
5544
|
if (isOperatorShaped(op)) throw new UnknownFilterOperatorError(field, op);
|
|
5409
5545
|
}
|
|
5410
5546
|
/**
|
|
5547
|
+
* The query-parameter names a REST listing reads as something other than a
|
|
5548
|
+
* field filter: pagination, sorting, includes, projection, search, the logical
|
|
5549
|
+
* groups, the JSON `where` dialect, an aggregate's `select`/`groupBy`, and the
|
|
5550
|
+
* soft-delete switches.
|
|
5551
|
+
*
|
|
5552
|
+
* One list for both ends. The server skips these names when it collects
|
|
5553
|
+
* `?<field>=<op>.<value>` filters, and the SDK sends a filter on a column with
|
|
5554
|
+
* one of these names inside `?where=` instead — a collection is free to have a
|
|
5555
|
+
* `page`, `select` or `hard` column, and a filter on it sent as its own
|
|
5556
|
+
* parameter was read as the parameter and never applied.
|
|
5557
|
+
*/
|
|
5558
|
+
var RESERVED_QUERY_KEYS = /* @__PURE__ */ new Set([
|
|
5559
|
+
"limit",
|
|
5560
|
+
"offset",
|
|
5561
|
+
"page",
|
|
5562
|
+
"after",
|
|
5563
|
+
"orderBy",
|
|
5564
|
+
"include",
|
|
5565
|
+
"fields",
|
|
5566
|
+
"distinct",
|
|
5567
|
+
"searchString",
|
|
5568
|
+
"searchExplain",
|
|
5569
|
+
"vector_search",
|
|
5570
|
+
"vector",
|
|
5571
|
+
"vector_distance",
|
|
5572
|
+
"vector_threshold",
|
|
5573
|
+
"or",
|
|
5574
|
+
"and",
|
|
5575
|
+
"not",
|
|
5576
|
+
"where",
|
|
5577
|
+
"select",
|
|
5578
|
+
"groupBy",
|
|
5579
|
+
"deleted",
|
|
5580
|
+
"hard"
|
|
5581
|
+
]);
|
|
5582
|
+
/**
|
|
5411
5583
|
* Encode the `<op>.<value>` half of a wire condition.
|
|
5412
5584
|
*
|
|
5413
5585
|
* This is the single leaf encoder. Both wire positions that carry a condition
|
|
@@ -5435,7 +5607,7 @@ function serializeOperatorAndValue(op, value, { escapeScalar, where }) {
|
|
|
5435
5607
|
return `${restOp}.(${value.map((v) => escapeWireValue(stringifyValue(v))).join(",")})`;
|
|
5436
5608
|
}
|
|
5437
5609
|
const scalar = stringifyValue(value);
|
|
5438
|
-
return `${restOp}.${escapeScalar ? escapeWireValue(scalar) : scalar}`;
|
|
5610
|
+
return `${restOp}.${escapeScalar || !LIST_OPS.has(op) && scalarNeedsEscape(scalar) ? escapeWireValue(scalar) : scalar}`;
|
|
5439
5611
|
}
|
|
5440
5612
|
/**
|
|
5441
5613
|
* Serialize a single canonical condition tuple to a PostgREST dot-string.
|
|
@@ -5531,7 +5703,10 @@ var NULL_OPERANDS = /* @__PURE__ */ new Set([
|
|
|
5531
5703
|
* operand: only {@link NULL_OPERANDS}. `notnull.reason` is the value
|
|
5532
5704
|
* `"notnull.reason"`, not "reason is not null".
|
|
5533
5705
|
* - **Everything else** takes one scalar, and any remainder is one — including
|
|
5534
|
-
* the empty string, so `eq.` really is "equals the empty string".
|
|
5706
|
+
* the empty string, so `eq.` really is "equals the empty string". A
|
|
5707
|
+
* parenthesised remainder is a list for these too (`eq.(a,b)` is array
|
|
5708
|
+
* equality); a scalar that is itself parenthesised arrives escaped,
|
|
5709
|
+
* `eq.\(none\)`, and is decoded here — see {@link scalarNeedsEscape}.
|
|
5535
5710
|
*
|
|
5536
5711
|
* ### The one ambiguity that remains, and how to write past it
|
|
5537
5712
|
*
|
|
@@ -5566,7 +5741,7 @@ function deserializeSingle(raw) {
|
|
|
5566
5741
|
return [canonicalOp, inner === EMPTY_LIST_TOKEN ? [] : splitListItems(inner)];
|
|
5567
5742
|
}
|
|
5568
5743
|
if (LIST_OPS.has(canonicalOp)) return ["==", raw];
|
|
5569
|
-
return [canonicalOp, rest];
|
|
5744
|
+
return [canonicalOp, decodeEscapedScalar(rest) ?? rest];
|
|
5570
5745
|
}
|
|
5571
5746
|
/**
|
|
5572
5747
|
* Convert a PostgREST-style querystring record to `FilterValues`.
|
|
@@ -6508,6 +6683,6 @@ function buildRoutedRebaseData({ defaultData, sources, resolveKey }) {
|
|
|
6508
6683
|
}
|
|
6509
6684
|
new Set(REBASE_INTERNAL_TABLES);
|
|
6510
6685
|
//#endregion
|
|
6511
|
-
export {
|
|
6686
|
+
export { toSnakeCase as $, createDataSourceRegistry as A, fieldKeyForColumn as B, cursorToStartAfter as C, restrictedFieldNames as D, effectiveAccess as E, revokeInternalTableSql as F, resolveCollectionRelations as G, getTableName as H, getJunctionConfigForRelation as I, resolvePrimaryKeys as J, enumToObjectEntries as K, getEffectiveSecurityRules as L, resolveDataSource as M, authSecretsMissingExclusion as N, assertBeforeQueryIsPostgresOnly as O, REBASE_USER_ROLE as P, suggestNearMiss as Q, getTenantConfig as R, CursorMismatchError as S, reconcileCursorOrder as T, isRelationRequired as U, findRelation as V, relationDeclaringProperty as W, isObject as X, hydrateRegExp as Y, splitSearchTerms as Z, topLevelIncludeNames as _, Vector as _t, deserializeFilter as a, FIELD_OPERATORS as at, serializeOrderBy as b, isUnsupported as bt, serializeLogicalCondition as c, ANONYMOUS_USER_ID as ct, resolveFindWindow as d, hasForeignKeyOnTarget as dt, unref as et, IncludeSpecError as f, isManyToMany as ft, serializeInclude as g, GeoPoint as gt, normalizeInclude as h, EntityRelation as ht, UnknownFilterOperatorError as i, BATCH_REF_KEY as it, isRelationalCollection as j, CollectionRegistry as k, collectAllPages as l, isAnonymousUid as lt, mergeIncludeSpecs as m, EntityReference as mt, buildSdkData as n, MAX_LIST_LIMIT as nt, deserializeLogicalCondition as o, hasFieldOperation as ot, deserializeInclude as p, isToMany as pt, buildCompositeId as q, RESERVED_QUERY_KEYS as r, resolveClientListLimit as rt, serializeFilter as s, isFieldOperation as st, buildRoutedRebaseData as t, ListLimitError as tt, paginateFind as u, JUNCTION_PIVOT_KEY as ut, OrderBySpecError as v, RebaseApiError as vt, decodeCursor as w, CursorError as x, unsupportedMethod as xt, normalizeOrderBy as y, RebaseClientError as yt, securityRuleToConditions as z };
|
|
6512
6687
|
|
|
6513
|
-
//# sourceMappingURL=src-
|
|
6688
|
+
//# sourceMappingURL=src-pmvW7BFx.js.map
|