@happyvertical/smrt-core 0.57.31 → 0.57.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +25 -1
  2. package/agents/data-query.md +21 -0
  3. package/dist/browser.d.ts +3 -2
  4. package/dist/browser.d.ts.map +1 -1
  5. package/dist/browser.js +4 -3
  6. package/dist/class.d.ts.map +1 -1
  7. package/dist/class.js +1 -1
  8. package/dist/class.js.map +1 -1
  9. package/dist/consumer-plugin/index.d.ts +2 -2
  10. package/dist/consumer-plugin/index.d.ts.map +1 -1
  11. package/dist/consumer-plugin/index.js.map +1 -1
  12. package/dist/data-query.d.ts +16 -1
  13. package/dist/data-query.d.ts.map +1 -1
  14. package/dist/data-query.js +104 -4
  15. package/dist/data-query.js.map +1 -1
  16. package/dist/db-errors.d.ts +7 -0
  17. package/dist/db-errors.d.ts.map +1 -1
  18. package/dist/db-errors.js +34 -1
  19. package/dist/db-errors.js.map +1 -1
  20. package/dist/dispatch/bus.d.ts +3 -0
  21. package/dist/dispatch/bus.d.ts.map +1 -1
  22. package/dist/dispatch/bus.js +27 -4
  23. package/dist/dispatch/bus.js.map +1 -1
  24. package/dist/dispatch/index.d.ts +1 -1
  25. package/dist/dispatch/index.d.ts.map +1 -1
  26. package/dist/dispatch/types.d.ts +17 -0
  27. package/dist/dispatch/types.d.ts.map +1 -1
  28. package/dist/external-agent-usage.d.ts +90 -0
  29. package/dist/external-agent-usage.d.ts.map +1 -0
  30. package/dist/external-agent-usage.js +272 -0
  31. package/dist/external-agent-usage.js.map +1 -0
  32. package/dist/index.d.ts +3 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +4 -3
  35. package/dist/manifest/static-manifest.js +1 -1
  36. package/dist/manifest/static-manifest.js.map +1 -1
  37. package/dist/manifest/store.js +1 -1
  38. package/dist/manifest.json +1 -1
  39. package/dist/smrt-knowledge.json +5 -6
  40. package/dist/system/retention.d.ts.map +1 -1
  41. package/dist/system/retention.js +1 -0
  42. package/dist/system/retention.js.map +1 -1
  43. package/dist/testing/database.d.ts.map +1 -1
  44. package/dist/testing/database.js +18 -0
  45. package/dist/testing/database.js.map +1 -1
  46. package/dist/vite-plugin/asset-url-compatibility.d.ts +2 -2
  47. package/dist/vite-plugin/asset-url-compatibility.d.ts.map +1 -1
  48. package/dist/vite-plugin/asset-url-compatibility.js +13 -3
  49. package/dist/vite-plugin/asset-url-compatibility.js.map +1 -1
  50. package/dist/vite-plugin/index.d.ts +5 -2
  51. package/dist/vite-plugin/index.d.ts.map +1 -1
  52. package/dist/vite-plugin/index.js.map +1 -1
  53. package/dist/vite-plugin/plugin-contract.d.ts +164 -0
  54. package/dist/vite-plugin/plugin-contract.d.ts.map +1 -0
  55. package/dist/vite-plugin/sveltekit-route-coordinator.d.ts +5 -5
  56. package/dist/vite-plugin/sveltekit-route-coordinator.d.ts.map +1 -1
  57. package/dist/vite-plugin/sveltekit-route-coordinator.js.map +1 -1
  58. package/dist/vite-plugin/worker-registration.d.ts +4 -4
  59. package/dist/vite-plugin/worker-registration.d.ts.map +1 -1
  60. package/dist/vite-plugin/worker-registration.js.map +1 -1
  61. package/dist/vite-preset/index.d.ts +2 -2
  62. package/dist/vite-preset/index.d.ts.map +1 -1
  63. package/dist/vite-preset/index.js +9 -1
  64. package/dist/vite-preset/index.js.map +1 -1
  65. package/package.json +4 -5
@@ -16,6 +16,25 @@ var MAX_DATA_QUERY_WARNINGS = 100;
16
16
  var MAX_DATA_QUERY_CURSOR_LENGTH = 2048;
17
17
  var MAX_DATA_QUERY_JSON_CONTAINER_ITEMS = 1e3;
18
18
  var MAX_DATA_QUERY_JSON_STRING_LENGTH = 65536;
19
+ /**
20
+ * Bounds for host-declared allowed field values (#4381). The count matches
21
+ * {@link MAX_DATA_QUERY_IN_VALUES} so a whole declared set fits one `in`.
22
+ */
23
+ var MAX_DATA_QUERY_FIELD_VALUES = 100;
24
+ var MAX_DATA_QUERY_FIELD_VALUE_LENGTH = 256;
25
+ var MAX_DATA_QUERY_FIELD_VALUE_LABEL_LENGTH = 128;
26
+ var MAX_DATA_QUERY_FIELD_VALUE_DESCRIPTION_LENGTH = 512;
27
+ /**
28
+ * Allowed values listed in a rejected-filter message and its
29
+ * `details.allowedValues` before truncation, so neither grows with the set.
30
+ */
31
+ var MAX_LISTED_ALLOWED_VALUES = 20;
32
+ /**
33
+ * Control (C0/C1/DEL), format (bidi overrides/isolates, zero-width, BOM),
34
+ * lone-surrogate, and line/paragraph-separator characters: none belongs in
35
+ * schema text an agent reads, and bidi controls can disguise a value.
36
+ */
37
+ var UNSAFE_SCHEMA_TEXT = /[\p{Cc}\p{Cf}\p{Cs}\p{Zl}\p{Zp}]/u;
19
38
  var FILTER_OPERATORS = /* @__PURE__ */ new Set([
20
39
  "eq",
21
40
  "ne",
@@ -231,7 +250,9 @@ function normalizeFieldDescriptor(value) {
231
250
  "projectable",
232
251
  "sortable",
233
252
  "facetable",
234
- "filterOperators"
253
+ "filterOperators",
254
+ "values",
255
+ "valuesEnforced"
235
256
  ], "Data query schema field");
236
257
  const id = stringValue(object.id, "Data query field id");
237
258
  const type = stringValue(object.type, `Data query field ${id} type`);
@@ -259,15 +280,88 @@ function normalizeFieldDescriptor(value) {
259
280
  const projectable = typeof object.projectable === "boolean" ? object.projectable : void 0;
260
281
  const sortable = typeof object.sortable === "boolean" ? object.sortable : void 0;
261
282
  const facetable = typeof object.facetable === "boolean" ? object.facetable : void 0;
283
+ const values = object.values === void 0 ? void 0 : normalizeDataQueryFieldValues(object.values, type, id);
284
+ if (object.valuesEnforced !== void 0) {
285
+ if (typeof object.valuesEnforced !== "boolean") return fail(`Data query field ${id} valuesEnforced must be boolean`);
286
+ if (!values) return fail(`Data query field ${id} valuesEnforced requires values`);
287
+ }
288
+ const advisory = values !== void 0 && object.valuesEnforced === false;
262
289
  return {
263
290
  id,
264
291
  type,
265
292
  ...projectable === void 0 ? {} : { projectable },
266
293
  ...sortable === void 0 ? {} : { sortable },
267
294
  ...facetable === void 0 ? {} : { facetable },
268
- ...filterOperators ? { filterOperators } : {}
295
+ ...filterOperators ? { filterOperators } : {},
296
+ ...values ? { values } : {},
297
+ ...advisory ? { valuesEnforced: false } : {}
269
298
  };
270
299
  }
300
+ function schemaText(value, label, maxLength) {
301
+ const text = stringValue(value, label, maxLength);
302
+ if (UNSAFE_SCHEMA_TEXT.test(text)) return fail(`${label} cannot contain control, format, or bidirectional characters`);
303
+ return text;
304
+ }
305
+ /**
306
+ * Validate a field's host-declared allowed values (#4381): a non-empty,
307
+ * bounded, duplicate-free list whose values match the field type, with
308
+ * optional label/description text free of control and bidi characters.
309
+ * Declaration order is preserved. Throws {@link DataQueryValidationError}.
310
+ */
311
+ function normalizeDataQueryFieldValues(value, type, fieldId) {
312
+ const label = `Data query field ${fieldId} values`;
313
+ if (type !== "string" && type !== "number" && type !== "boolean") return fail(`${label} are only supported on string, number, or boolean fields`);
314
+ if (!Array.isArray(value) || value.length === 0) return fail(`${label} must be a non-empty array`);
315
+ if (value.length > 100) return fail(`${label} cannot exceed 100 entries`);
316
+ const seen = /* @__PURE__ */ new Set();
317
+ return value.map((entry, index) => {
318
+ const entryLabel = `${label}[${index}]`;
319
+ const object = plainObject(entry, entryLabel);
320
+ exactKeys(object, [
321
+ "value",
322
+ "label",
323
+ "description"
324
+ ], entryLabel);
325
+ const raw = object.value;
326
+ let allowed;
327
+ if (type === "string") allowed = schemaText(raw, `${entryLabel} value`, 256);
328
+ else if (type === "number") {
329
+ if (typeof raw !== "number" || !Number.isFinite(raw)) return fail(`${entryLabel} value must be a finite number`);
330
+ allowed = raw;
331
+ } else {
332
+ if (typeof raw !== "boolean") return fail(`${entryLabel} value must be a boolean`);
333
+ allowed = raw;
334
+ }
335
+ const key = signature(allowed);
336
+ if (seen.has(key)) return fail(`${label} must be unique`);
337
+ seen.add(key);
338
+ const valueLabel = object.label === void 0 ? void 0 : schemaText(object.label, `${entryLabel} label`, 128);
339
+ const description = object.description === void 0 ? void 0 : schemaText(object.description, `${entryLabel} description`, 512);
340
+ return {
341
+ value: allowed,
342
+ ...valueLabel === void 0 ? {} : { label: valueLabel },
343
+ ...description === void 0 ? {} : { description }
344
+ };
345
+ });
346
+ }
347
+ /**
348
+ * Reject an equality-family filter value outside a field's enforced closed
349
+ * set with a message the caller can act on. `null` stays allowed, and an
350
+ * advisory set (`valuesEnforced: false`) accepts any value.
351
+ */
352
+ function assertDeclaredValue(scalar, descriptor, label) {
353
+ if (scalar === null || !descriptor.values || descriptor.valuesEnforced === false) return;
354
+ if (descriptor.values.some((entry) => entry.value === scalar)) return;
355
+ const allowed = descriptor.values.map((entry) => entry.value);
356
+ const shown = allowed.slice(0, MAX_LISTED_ALLOWED_VALUES);
357
+ const listed = shown.map((entry) => JSON.stringify(entry)).join(", ");
358
+ const more = allowed.length > MAX_LISTED_ALLOWED_VALUES ? `, and ${allowed.length - MAX_LISTED_ALLOWED_VALUES} more` : "";
359
+ fail(`${label} is not an allowed value for ${descriptor.id}; use one of: ${listed}${more}`, "DATA_QUERY_VALUE_NOT_ALLOWED", {
360
+ field: descriptor.id,
361
+ allowedValues: shown,
362
+ allowedValueCount: allowed.length
363
+ });
364
+ }
271
365
  /** Validate and canonicalize trusted adapter query policy before use. */
272
366
  function normalizeDataQuerySchema(value) {
273
367
  const object = plainObject(value, "Data query schema");
@@ -368,7 +462,12 @@ function normalizeFilter(value, fields, depth = 0, budget = { nodes: 0 }) {
368
462
  if (operator === "in" || operator === "notIn") {
369
463
  if (!Array.isArray(object.value) || object.value.length === 0) return fail(`Data query ${operator} value must be a non-empty array`);
370
464
  if (object.value.length > 100) return fail(`Data query ${operator} value cannot exceed 100 items`);
371
- const values = object.value.map((entry, index) => scalarForField(entry, descriptor, `Data query ${operator} value ${index}`));
465
+ const values = object.value.map((entry, index) => {
466
+ const entryLabel = `Data query ${operator} value ${index}`;
467
+ const scalar = scalarForField(entry, descriptor, entryLabel);
468
+ assertDeclaredValue(scalar, descriptor, entryLabel);
469
+ return scalar;
470
+ });
372
471
  return {
373
472
  kind: "condition",
374
473
  field,
@@ -378,6 +477,7 @@ function normalizeFilter(value, fields, depth = 0, budget = { nodes: 0 }) {
378
477
  }
379
478
  if (Array.isArray(object.value)) return fail(`Data query ${operator} value must be a scalar`);
380
479
  const scalar = scalarForField(object.value, descriptor, `Data query ${operator} value`);
480
+ if (operator === "eq" || operator === "ne") assertDeclaredValue(scalar, descriptor, `Data query ${operator} value`);
381
481
  if (operator === "like" && descriptor.type !== "string") return fail("Data query like is only available for string fields");
382
482
  if (operator === "like" && typeof scalar !== "string") return fail("Data query like value must be a string");
383
483
  if ([
@@ -806,6 +906,6 @@ function normalizeDataQueryResult(value, inputRequest, inputSchema) {
806
906
  return normalized;
807
907
  }
808
908
  //#endregion
809
- export { DEFAULT_DATA_QUERY_PAGE_LIMIT, DEFAULT_DATA_QUERY_RESULT_BYTES, DataQueryValidationError, MAX_DATA_QUERY_CURSOR_LENGTH, MAX_DATA_QUERY_FACETS, MAX_DATA_QUERY_FILTERS, MAX_DATA_QUERY_FILTER_DEPTH, MAX_DATA_QUERY_IN_VALUES, MAX_DATA_QUERY_JSON_CONTAINER_ITEMS, MAX_DATA_QUERY_JSON_STRING_LENGTH, MAX_DATA_QUERY_OFFSET, MAX_DATA_QUERY_PAGE_LIMIT, MAX_DATA_QUERY_REQUEST_BYTES, MAX_DATA_QUERY_RESULT_BYTES, MAX_DATA_QUERY_WARNINGS, canonicalizeDataQuery, createDataQueryFingerprint, normalizeDataQueryRequest, normalizeDataQueryResult, normalizeDataQuerySchema };
909
+ export { DEFAULT_DATA_QUERY_PAGE_LIMIT, DEFAULT_DATA_QUERY_RESULT_BYTES, DataQueryValidationError, MAX_DATA_QUERY_CURSOR_LENGTH, MAX_DATA_QUERY_FACETS, MAX_DATA_QUERY_FIELD_VALUES, MAX_DATA_QUERY_FIELD_VALUE_DESCRIPTION_LENGTH, MAX_DATA_QUERY_FIELD_VALUE_LABEL_LENGTH, MAX_DATA_QUERY_FIELD_VALUE_LENGTH, MAX_DATA_QUERY_FILTERS, MAX_DATA_QUERY_FILTER_DEPTH, MAX_DATA_QUERY_IN_VALUES, MAX_DATA_QUERY_JSON_CONTAINER_ITEMS, MAX_DATA_QUERY_JSON_STRING_LENGTH, MAX_DATA_QUERY_OFFSET, MAX_DATA_QUERY_PAGE_LIMIT, MAX_DATA_QUERY_REQUEST_BYTES, MAX_DATA_QUERY_RESULT_BYTES, MAX_DATA_QUERY_WARNINGS, canonicalizeDataQuery, createDataQueryFingerprint, normalizeDataQueryFieldValues, normalizeDataQueryRequest, normalizeDataQueryResult, normalizeDataQuerySchema };
810
910
 
811
911
  //# sourceMappingURL=data-query.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-query.js","names":[],"sources":["../src/data-query.ts"],"sourcesContent":["/**\n * Canonical bounded data-query normalization (#2444).\n *\n * The shared package supplies only portable types. This server/runtime module\n * makes the contract executable at every trust boundary: it accepts only an\n * adapter-declared field/operator allowlist, canonicalizes equivalent\n * requests, creates a collision-resistant match fingerprint, and validates\n * that adapters return bounded, policy-filtered rows. It deliberately does\n * not execute SQL or resolve tenant/principal state; authenticated domain\n * adapters supply the schema and perform those responsibilities separately.\n */\n\nimport type {\n DataQueryCondition,\n DataQueryConsistency,\n DataQueryFacetRequest,\n DataQueryFacetResult,\n DataQueryFieldDescriptor,\n DataQueryFilter,\n DataQueryFilterOperator,\n DataQueryFreshness,\n DataQueryPage,\n DataQueryRequest,\n DataQueryResult,\n DataQueryRow,\n DataQueryScalar,\n DataQuerySchema,\n DataQuerySort,\n DataQueryTotal,\n} from '@happyvertical/smrt-types';\nimport { ValidationError } from './errors';\nimport { sha256Base64Url } from './utils/sha256.js';\n\n/** Default and hard ceilings for normalized data-query input and output. */\nexport const DEFAULT_DATA_QUERY_PAGE_LIMIT = 50;\nexport const MAX_DATA_QUERY_PAGE_LIMIT = 1_000;\nexport const DEFAULT_DATA_QUERY_RESULT_BYTES = 1_000_000;\nexport const MAX_DATA_QUERY_RESULT_BYTES = 10_000_000;\nexport const MAX_DATA_QUERY_REQUEST_BYTES = 100_000;\nexport const MAX_DATA_QUERY_OFFSET = 1_000_000;\nexport const MAX_DATA_QUERY_FILTER_DEPTH = 8;\nexport const MAX_DATA_QUERY_FILTERS = 50;\nexport const MAX_DATA_QUERY_IN_VALUES = 100;\nexport const MAX_DATA_QUERY_FACETS = 20;\nexport const MAX_DATA_QUERY_WARNINGS = 100;\nexport const MAX_DATA_QUERY_CURSOR_LENGTH = 2_048;\nexport const MAX_DATA_QUERY_JSON_DEPTH = 16;\nexport const MAX_DATA_QUERY_JSON_CONTAINER_ITEMS = 1_000;\nexport const MAX_DATA_QUERY_JSON_STRING_LENGTH = 65_536;\n\nconst FILTER_OPERATORS = new Set<DataQueryFilterOperator>([\n 'eq',\n 'ne',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'in',\n 'notIn',\n 'like',\n]);\nconst FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** A typed 400-class failure for malformed or policy-disallowed data queries. */\nexport class DataQueryValidationError extends ValidationError {\n readonly status = 400;\n readonly publicMessage: string;\n\n constructor(\n message: string,\n code = 'INVALID_DATA_QUERY',\n details?: Record<string, unknown>,\n ) {\n super(message, code, details);\n this.name = 'DataQueryValidationError';\n this.publicMessage = message;\n }\n}\n\ntype JsonObject = Record<string, unknown>;\n\ninterface JsonBudget {\n remaining: number;\n failureCode: string;\n}\n\nconst encoder = new TextEncoder();\nconst RFC_3339_INSTANT =\n /^(\\d{4})-(\\d{2})-(\\d{2})T([01]\\d|2[0-3]):([0-5]\\d):([0-5]\\d)(?:\\.\\d{1,9})?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$/;\n\nfunction fail(\n message: string,\n code = 'INVALID_DATA_QUERY',\n details?: Record<string, unknown>,\n): never {\n throw new DataQueryValidationError(message, code, details);\n}\n\nfunction plainObject(value: unknown, label: string): JsonObject {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return fail(`${label} must be an object`);\n }\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n return fail(`${label} must be a plain object`);\n }\n for (const key of Object.keys(value)) {\n if (FORBIDDEN_KEYS.has(key)) {\n return fail(`${label} contains a forbidden key`, 'FORBIDDEN_DATA_QUERY');\n }\n }\n return value as JsonObject;\n}\n\nfunction exactKeys(\n object: JsonObject,\n allowed: readonly string[],\n label: string,\n): void {\n const allowedKeys = new Set(allowed);\n for (const key of Object.keys(object)) {\n if (!allowedKeys.has(key)) {\n fail(\n `${label} contains unsupported key \"${key}\"`,\n 'FORBIDDEN_DATA_QUERY',\n );\n }\n }\n}\n\nfunction stringValue(value: unknown, label: string, maxLength = 256): string {\n if (\n typeof value !== 'string' ||\n value.length === 0 ||\n value.length > maxLength\n ) {\n return fail(\n `${label} must be a non-empty string up to ${maxLength} characters`,\n );\n }\n return value;\n}\n\nfunction nonNegativeInteger(value: unknown, label: string): number {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n return fail(`${label} must be a non-negative safe integer`);\n }\n return value as number;\n}\n\nfunction positiveInteger(value: unknown, label: string): number {\n const normalized = nonNegativeInteger(value, label);\n if (normalized === 0) return fail(`${label} must be a positive safe integer`);\n return normalized;\n}\n\nfunction normalizedInstant(value: unknown, label: string): string {\n const input = stringValue(value, label, 128);\n const match = RFC_3339_INSTANT.exec(input);\n if (!match) return fail(`${label} must be an RFC 3339 instant`);\n const [year, month, day] = match.slice(1, 4).map(Number);\n const calendar = new Date(0);\n calendar.setUTCFullYear(year, month - 1, day);\n calendar.setUTCHours(0, 0, 0, 0);\n if (\n calendar.getUTCFullYear() !== year ||\n calendar.getUTCMonth() !== month - 1 ||\n calendar.getUTCDate() !== day\n ) {\n return fail(`${label} must be an RFC 3339 instant`);\n }\n const milliseconds = Date.parse(input);\n if (!Number.isFinite(milliseconds)) {\n return fail(`${label} must be an RFC 3339 instant`);\n }\n return new Date(milliseconds).toISOString();\n}\n\nfunction dataQueryScalar(value: unknown, label: string): DataQueryScalar {\n if (value === null || typeof value === 'boolean') {\n return value;\n }\n if (typeof value === 'string') {\n if (value.length > 4_096) {\n return fail(`${label} cannot exceed 4096 characters`);\n }\n return value;\n }\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n return fail(`${label} must be a JSON scalar`);\n}\n\nfunction consumeJsonSegment(\n budget: JsonBudget | undefined,\n text: string,\n label: string,\n): void {\n if (!budget) return;\n if (text.length > budget.remaining) {\n fail(`${label} exceeds the maximum byte limit`, budget.failureCode);\n }\n const bytes = encoder.encode(text).byteLength;\n if (bytes > budget.remaining) {\n fail(`${label} exceeds the maximum byte limit`, budget.failureCode);\n }\n budget.remaining -= bytes;\n}\n\nfunction canonicalJson(\n value: unknown,\n label = 'Data query JSON',\n budget?: JsonBudget,\n depth = 0,\n ancestors = new Set<object>(),\n): unknown {\n if (depth > MAX_DATA_QUERY_JSON_DEPTH) {\n return fail(`${label} exceeds the JSON depth limit`);\n }\n if (value === null || typeof value === 'boolean') {\n consumeJsonSegment(budget, JSON.stringify(value), label);\n return value;\n }\n if (typeof value === 'string') {\n if (value.length > MAX_DATA_QUERY_JSON_STRING_LENGTH) {\n return fail(`${label} exceeds the JSON string limit`);\n }\n consumeJsonSegment(budget, JSON.stringify(value), label);\n return value;\n }\n if (typeof value === 'number') {\n if (!Number.isFinite(value))\n return fail(`${label} cannot contain a non-finite number`);\n const normalized = value === 0 ? 0 : value;\n consumeJsonSegment(budget, JSON.stringify(normalized), label);\n return normalized;\n }\n if (Array.isArray(value)) {\n if (value.length > MAX_DATA_QUERY_JSON_CONTAINER_ITEMS) {\n return fail(`${label} exceeds the JSON container-item limit`);\n }\n if (ancestors.has(value)) return fail(`${label} cannot contain a cycle`);\n ancestors.add(value);\n try {\n const result: unknown[] = [];\n consumeJsonSegment(budget, '[', label);\n for (const [index, entry] of value.entries()) {\n if (index > 0) consumeJsonSegment(budget, ',', label);\n result.push(\n canonicalJson(\n entry,\n `${label}[${index}]`,\n budget,\n depth + 1,\n ancestors,\n ),\n );\n }\n consumeJsonSegment(budget, ']', label);\n return result;\n } finally {\n ancestors.delete(value);\n }\n }\n const object = plainObject(value, label);\n const keys = Object.keys(object).sort(compareCanonicalStrings);\n if (keys.length > MAX_DATA_QUERY_JSON_CONTAINER_ITEMS) {\n return fail(`${label} exceeds the JSON container-item limit`);\n }\n if (ancestors.has(object)) return fail(`${label} cannot contain a cycle`);\n ancestors.add(object);\n try {\n const result: JsonObject = Object.create(null) as JsonObject;\n consumeJsonSegment(budget, '{', label);\n for (const [index, key] of keys.entries()) {\n if (key.length > MAX_DATA_QUERY_JSON_STRING_LENGTH) {\n return fail(`${label}.${key} exceeds the JSON string limit`);\n }\n if (index > 0) consumeJsonSegment(budget, ',', label);\n consumeJsonSegment(budget, JSON.stringify(key), `${label}.${key}`);\n consumeJsonSegment(budget, ':', label);\n Object.defineProperty(result, key, {\n value: canonicalJson(\n object[key],\n `${label}.${key}`,\n budget,\n depth + 1,\n ancestors,\n ),\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n consumeJsonSegment(budget, '}', label);\n return result;\n } finally {\n ancestors.delete(object);\n }\n}\n\nfunction signature(value: unknown): string {\n return JSON.stringify(canonicalJson(value));\n}\n\n/** Reject an over-limit raw request before canonicalization can collapse it. */\nfunction assertBoundedRawRequest(value: unknown): void {\n const budget: JsonBudget = {\n remaining: MAX_DATA_QUERY_REQUEST_BYTES,\n failureCode: 'DATA_QUERY_REQUEST_TOO_LARGE',\n };\n const ancestors = new Set<object>();\n\n const measure = (candidate: unknown, label: string, depth = 0): void => {\n if (depth > MAX_DATA_QUERY_JSON_DEPTH) {\n fail(`${label} exceeds the JSON depth limit`);\n }\n if (candidate === null || typeof candidate === 'boolean') {\n consumeJsonSegment(budget, JSON.stringify(candidate), label);\n return;\n }\n if (typeof candidate === 'string') {\n consumeJsonSegment(budget, JSON.stringify(candidate), label);\n return;\n }\n if (typeof candidate === 'number') {\n if (!Number.isFinite(candidate)) {\n fail(`${label} cannot contain a non-finite number`);\n }\n consumeJsonSegment(\n budget,\n JSON.stringify(candidate === 0 ? 0 : candidate),\n label,\n );\n return;\n }\n if (Array.isArray(candidate)) {\n if (ancestors.has(candidate)) fail(`${label} cannot contain a cycle`);\n ancestors.add(candidate);\n try {\n consumeJsonSegment(budget, '[', label);\n for (const [index, entry] of candidate.entries()) {\n if (index > 0) consumeJsonSegment(budget, ',', label);\n measure(entry, `${label}[${index}]`, depth + 1);\n }\n consumeJsonSegment(budget, ']', label);\n } finally {\n ancestors.delete(candidate);\n }\n return;\n }\n const object = plainObject(candidate, label);\n if (ancestors.has(object)) fail(`${label} cannot contain a cycle`);\n ancestors.add(object);\n try {\n consumeJsonSegment(budget, '{', label);\n for (const [index, key] of Object.keys(object).entries()) {\n if (index > 0) consumeJsonSegment(budget, ',', label);\n consumeJsonSegment(budget, JSON.stringify(key), `${label}.${key}`);\n consumeJsonSegment(budget, ':', label);\n measure(object[key], `${label}.${key}`, depth + 1);\n }\n consumeJsonSegment(budget, '}', label);\n } finally {\n ancestors.delete(object);\n }\n };\n\n measure(value, 'Data query request');\n}\n\n/** Locale-independent ordering for canonical envelopes and fingerprints. */\nfunction compareCanonicalStrings(left: string, right: string): number {\n if (left === right) return 0;\n return left < right ? -1 : 1;\n}\n\nfunction normalizeFieldDescriptor(value: unknown): DataQueryFieldDescriptor {\n const object = plainObject(value, 'Data query schema field');\n exactKeys(\n object,\n ['id', 'type', 'projectable', 'sortable', 'facetable', 'filterOperators'],\n 'Data query schema field',\n );\n const id = stringValue(object.id, 'Data query field id');\n const type = stringValue(object.type, `Data query field ${id} type`);\n if (!['string', 'number', 'boolean', 'datetime', 'json'].includes(type)) {\n return fail(`Unsupported data query field type: ${type}`);\n }\n for (const flag of ['projectable', 'sortable', 'facetable'] as const) {\n if (object[flag] !== undefined && typeof object[flag] !== 'boolean') {\n fail(`Data query field ${id} ${flag} must be boolean`);\n }\n }\n let filterOperators: DataQueryFilterOperator[] | undefined;\n if (object.filterOperators !== undefined) {\n if (!Array.isArray(object.filterOperators)) {\n return fail(`Data query field ${id} filterOperators must be an array`);\n }\n filterOperators = [\n ...new Set(\n object.filterOperators.map((operator) => {\n const normalized = stringValue(\n operator,\n `Data query field ${id} filter operator`,\n ) as DataQueryFilterOperator;\n if (!FILTER_OPERATORS.has(normalized)) {\n fail(`Unsupported data query filter operator: ${normalized}`);\n }\n return normalized;\n }),\n ),\n ].sort();\n }\n const projectable =\n typeof object.projectable === 'boolean' ? object.projectable : undefined;\n const sortable =\n typeof object.sortable === 'boolean' ? object.sortable : undefined;\n const facetable =\n typeof object.facetable === 'boolean' ? object.facetable : undefined;\n return {\n id,\n type: type as DataQueryFieldDescriptor['type'],\n ...(projectable === undefined ? {} : { projectable }),\n ...(sortable === undefined ? {} : { sortable }),\n ...(facetable === undefined ? {} : { facetable }),\n ...(filterOperators ? { filterOperators } : {}),\n };\n}\n\n/** Validate and canonicalize trusted adapter query policy before use. */\nexport function normalizeDataQuerySchema(value: unknown): DataQuerySchema {\n const object = plainObject(value, 'Data query schema');\n exactKeys(\n object,\n [\n 'version',\n 'identityField',\n 'fields',\n 'defaultPageLimit',\n 'maxPageLimit',\n 'maxResultBytes',\n 'defaultSort',\n 'supports',\n ],\n 'Data query schema',\n );\n if (object.version !== 1)\n return fail('Unsupported data query schema version');\n if (!Array.isArray(object.fields) || object.fields.length === 0) {\n return fail('Data query schema fields must be a non-empty array');\n }\n const fields = object.fields\n .map(normalizeFieldDescriptor)\n .sort((left, right) => compareCanonicalStrings(left.id, right.id));\n if (new Set(fields.map((field) => field.id)).size !== fields.length) {\n return fail('Data query schema field ids must be unique');\n }\n const identityField = stringValue(\n object.identityField,\n 'Data query identity field',\n );\n const identity = fields.find((field) => field.id === identityField);\n if (!identity) return fail('Data query identity field must be declared');\n if (identity.projectable === false) {\n return fail('Data query identity field must be projectable');\n }\n if (!['string', 'number', 'datetime'].includes(identity.type)) {\n return fail(\n 'Data query identity field must use a string, number, or datetime type',\n );\n }\n const maxPageLimit =\n object.maxPageLimit === undefined\n ? MAX_DATA_QUERY_PAGE_LIMIT\n : positiveInteger(object.maxPageLimit, 'Data query maximum page limit');\n if (maxPageLimit > MAX_DATA_QUERY_PAGE_LIMIT) {\n return fail(\n `Data query maximum page limit cannot exceed ${MAX_DATA_QUERY_PAGE_LIMIT}`,\n );\n }\n const defaultPageLimit =\n object.defaultPageLimit === undefined\n ? Math.min(DEFAULT_DATA_QUERY_PAGE_LIMIT, maxPageLimit)\n : positiveInteger(\n object.defaultPageLimit,\n 'Data query default page limit',\n );\n if (defaultPageLimit > maxPageLimit) {\n return fail(\n 'Data query default page limit cannot exceed the maximum page limit',\n );\n }\n const maxResultBytes =\n object.maxResultBytes === undefined\n ? DEFAULT_DATA_QUERY_RESULT_BYTES\n : positiveInteger(\n object.maxResultBytes,\n 'Data query maximum result bytes',\n );\n if (maxResultBytes > MAX_DATA_QUERY_RESULT_BYTES) {\n return fail(\n `Data query maximum result bytes cannot exceed ${MAX_DATA_QUERY_RESULT_BYTES}`,\n );\n }\n let supports: DataQuerySchema['supports'];\n if (object.supports !== undefined) {\n const supportObject = plainObject(\n object.supports,\n 'Data query schema supports',\n );\n exactKeys(\n supportObject,\n ['cursorPagination', 'consistency', 'facets'],\n 'Data query schema supports',\n );\n for (const key of ['cursorPagination', 'consistency', 'facets'] as const) {\n if (\n supportObject[key] !== undefined &&\n typeof supportObject[key] !== 'boolean'\n ) {\n fail(`Data query schema supports.${key} must be boolean`);\n }\n }\n const cursorPagination =\n typeof supportObject.cursorPagination === 'boolean'\n ? supportObject.cursorPagination\n : undefined;\n const consistency =\n typeof supportObject.consistency === 'boolean'\n ? supportObject.consistency\n : undefined;\n const facets =\n typeof supportObject.facets === 'boolean'\n ? supportObject.facets\n : undefined;\n supports = {\n ...(cursorPagination === undefined ? {} : { cursorPagination }),\n ...(consistency === undefined ? {} : { consistency }),\n ...(facets === undefined ? {} : { facets }),\n };\n }\n const fieldMap = new Map(fields.map((field) => [field.id, field]));\n const defaultSort = normalizeSort(\n object.defaultSort,\n fieldMap,\n identityField,\n 'Data query default sort',\n false,\n );\n return {\n version: 1,\n identityField,\n fields,\n defaultPageLimit,\n maxPageLimit,\n maxResultBytes,\n ...(defaultSort.length > 0 ? { defaultSort } : {}),\n ...(supports ? { supports } : {}),\n };\n}\n\ninterface FilterBudget {\n nodes: number;\n}\n\nfunction scalarForField(\n value: unknown,\n descriptor: DataQueryFieldDescriptor,\n label: string,\n): DataQueryScalar {\n const scalar = dataQueryScalar(value, label);\n if (scalar === null) return scalar;\n if (descriptor.type === 'number' && typeof scalar !== 'number') {\n return fail(`${label} must be a number for ${descriptor.id}`);\n }\n if (descriptor.type === 'boolean' && typeof scalar !== 'boolean') {\n return fail(`${label} must be a boolean for ${descriptor.id}`);\n }\n if (descriptor.type === 'string' && typeof scalar !== 'string') {\n return fail(`${label} must be a string for ${descriptor.id}`);\n }\n if (descriptor.type === 'datetime') {\n if (typeof scalar !== 'string') {\n return fail(`${label} must be an RFC 3339 instant for ${descriptor.id}`);\n }\n return normalizedInstant(scalar, label);\n }\n return scalar;\n}\n\nfunction normalizeFilter(\n value: unknown,\n fields: Map<string, DataQueryFieldDescriptor>,\n depth = 0,\n budget: FilterBudget = { nodes: 0 },\n): DataQueryFilter {\n if (depth > MAX_DATA_QUERY_FILTER_DEPTH) {\n return fail(\n `Data query filter cannot exceed depth ${MAX_DATA_QUERY_FILTER_DEPTH}`,\n );\n }\n budget.nodes += 1;\n if (budget.nodes > MAX_DATA_QUERY_FILTERS) {\n return fail(\n `Data query filter cannot exceed ${MAX_DATA_QUERY_FILTERS} expressions`,\n );\n }\n const object = plainObject(value, 'Data query filter');\n const kind = stringValue(object.kind, 'Data query filter kind');\n if (kind === 'condition') {\n exactKeys(\n object,\n ['kind', 'field', 'operator', 'value'],\n 'Data query condition',\n );\n const field = stringValue(object.field, 'Data query condition field');\n const descriptor = fields.get(field);\n if (!descriptor)\n return fail(\n `Data query field is not declared: ${field}`,\n 'DATA_QUERY_FIELD_NOT_ALLOWED',\n );\n const operator = stringValue(\n object.operator,\n 'Data query condition operator',\n ) as DataQueryFilterOperator;\n if (\n !FILTER_OPERATORS.has(operator) ||\n !descriptor.filterOperators?.includes(operator)\n ) {\n return fail(\n `Data query operator ${operator} is not allowed for ${field}`,\n 'DATA_QUERY_OPERATOR_NOT_ALLOWED',\n );\n }\n if (operator === 'in' || operator === 'notIn') {\n if (!Array.isArray(object.value) || object.value.length === 0) {\n return fail(`Data query ${operator} value must be a non-empty array`);\n }\n if (object.value.length > MAX_DATA_QUERY_IN_VALUES) {\n return fail(\n `Data query ${operator} value cannot exceed ${MAX_DATA_QUERY_IN_VALUES} items`,\n );\n }\n const values = object.value.map((entry, index) =>\n scalarForField(\n entry,\n descriptor,\n `Data query ${operator} value ${index}`,\n ),\n );\n const canonicalValues = [\n ...new Map(values.map((entry) => [signature(entry), entry])).values(),\n ].sort((left, right) =>\n compareCanonicalStrings(signature(left), signature(right)),\n );\n return { kind: 'condition', field, operator, value: canonicalValues };\n }\n if (Array.isArray(object.value)) {\n return fail(`Data query ${operator} value must be a scalar`);\n }\n const scalar = scalarForField(\n object.value,\n descriptor,\n `Data query ${operator} value`,\n );\n if (operator === 'like' && descriptor.type !== 'string') {\n return fail('Data query like is only available for string fields');\n }\n if (operator === 'like' && typeof scalar !== 'string') {\n return fail('Data query like value must be a string');\n }\n if (\n ['gt', 'gte', 'lt', 'lte'].includes(operator) &&\n !['number', 'string', 'datetime'].includes(descriptor.type)\n ) {\n return fail(\n `Data query ${operator} is not available for ${descriptor.type} fields`,\n );\n }\n if (\n ['gt', 'gte', 'lt', 'lte', 'like'].includes(operator) &&\n scalar === null\n ) {\n return fail(`Data query ${operator} value cannot be null`);\n }\n return {\n kind: 'condition',\n field,\n operator,\n value: scalar,\n } as DataQueryCondition;\n }\n if (kind === 'all' || kind === 'any') {\n exactKeys(object, ['kind', 'filters'], `Data query ${kind} filter`);\n if (!Array.isArray(object.filters) || object.filters.length === 0) {\n return fail(`Data query ${kind} filter must contain at least one child`);\n }\n if (object.filters.length > MAX_DATA_QUERY_FILTERS) {\n return fail(\n `Data query ${kind} filter cannot exceed ${MAX_DATA_QUERY_FILTERS} children`,\n );\n }\n const filters = object.filters\n .map((filter) => normalizeFilter(filter, fields, depth + 1, budget))\n .sort((left, right) =>\n compareCanonicalStrings(signature(left), signature(right)),\n );\n return { kind, filters };\n }\n if (kind === 'not') {\n exactKeys(object, ['kind', 'filter'], 'Data query not filter');\n return {\n kind: 'not',\n filter: normalizeFilter(object.filter, fields, depth + 1, budget),\n };\n }\n return fail(`Unsupported data query filter kind: ${kind}`);\n}\n\nfunction normalizeSort(\n value: unknown,\n fields: Map<string, DataQueryFieldDescriptor>,\n identityField: string,\n label: string,\n appendIdentity: boolean,\n): DataQuerySort[] {\n if (value === undefined)\n return appendIdentity ? [{ field: identityField, direction: 'asc' }] : [];\n if (!Array.isArray(value)) return fail(`${label} must be an array`);\n if (value.length > MAX_DATA_QUERY_FILTERS) {\n return fail(`${label} cannot exceed ${MAX_DATA_QUERY_FILTERS} terms`);\n }\n const sort = value.map((entry) => {\n const object = plainObject(entry, label);\n exactKeys(object, ['field', 'direction'], label);\n const field = stringValue(object.field, `${label} field`);\n if (!fields.get(field)?.sortable && field !== identityField) {\n fail(\n `Data query sort field is not allowed: ${field}`,\n 'DATA_QUERY_SORT_NOT_ALLOWED',\n );\n }\n const direction = stringValue(object.direction, `${label} direction`);\n if (direction !== 'asc' && direction !== 'desc') {\n fail(`Data query sort direction must be asc or desc`);\n }\n return { field, direction } as DataQuerySort;\n });\n if (new Set(sort.map((term) => term.field)).size !== sort.length) {\n return fail(`${label} field ids must be unique`);\n }\n if (appendIdentity && !sort.some((term) => term.field === identityField)) {\n sort.push({ field: identityField, direction: 'asc' });\n }\n return sort;\n}\n\nfunction normalizePage(value: unknown, schema: DataQuerySchema): DataQueryPage {\n if (value === undefined) {\n return {\n kind: 'offset',\n offset: 0,\n limit: schema.defaultPageLimit ?? DEFAULT_DATA_QUERY_PAGE_LIMIT,\n };\n }\n const object = plainObject(value, 'Data query page');\n const kind = stringValue(object.kind, 'Data query page kind');\n if (kind === 'offset') {\n exactKeys(object, ['kind', 'offset', 'limit'], 'Data query offset page');\n const offset = nonNegativeInteger(object.offset, 'Data query offset');\n if (offset > MAX_DATA_QUERY_OFFSET) {\n return fail(`Data query offset cannot exceed ${MAX_DATA_QUERY_OFFSET}`);\n }\n return {\n kind,\n offset,\n limit: Math.min(\n positiveInteger(object.limit, 'Data query page limit'),\n schema.maxPageLimit ?? MAX_DATA_QUERY_PAGE_LIMIT,\n ),\n };\n }\n if (kind === 'cursor') {\n if (!schema.supports?.cursorPagination) {\n return fail(\n 'Data query cursor pagination is not supported',\n 'DATA_QUERY_UNSUPPORTED',\n );\n }\n exactKeys(object, ['kind', 'after', 'limit'], 'Data query cursor page');\n const after =\n object.after === undefined\n ? undefined\n : stringValue(\n object.after,\n 'Data query cursor',\n MAX_DATA_QUERY_CURSOR_LENGTH,\n );\n return {\n kind,\n ...(after === undefined ? {} : { after }),\n limit: Math.min(\n positiveInteger(object.limit, 'Data query page limit'),\n schema.maxPageLimit ?? MAX_DATA_QUERY_PAGE_LIMIT,\n ),\n };\n }\n return fail(`Unsupported data query page kind: ${kind}`);\n}\n\nfunction normalizeConsistency(\n value: unknown,\n schema: DataQuerySchema,\n): DataQueryConsistency | undefined {\n if (value === undefined) return undefined;\n if (!schema.supports?.consistency) {\n return fail(\n 'Data query consistency options are not supported',\n 'DATA_QUERY_UNSUPPORTED',\n );\n }\n const object = plainObject(value, 'Data query consistency');\n exactKeys(object, ['mode', 'asOf'], 'Data query consistency');\n if (object.mode !== 'eventual' && object.mode !== 'snapshot')\n return fail('Unsupported data query consistency mode');\n const asOf =\n object.asOf === undefined\n ? undefined\n : normalizedInstant(object.asOf, 'Data query consistency asOf');\n return {\n mode: object.mode,\n ...(asOf === undefined ? {} : { asOf }),\n } as DataQueryConsistency;\n}\n\nfunction normalizeFacets(\n value: unknown,\n schema: DataQuerySchema,\n fields: Map<string, DataQueryFieldDescriptor>,\n): DataQueryFacetRequest[] {\n if (!schema.supports?.facets) {\n return fail(\n 'Data query facets are not supported',\n 'DATA_QUERY_UNSUPPORTED',\n );\n }\n if (!Array.isArray(value) || value.length === 0) {\n return fail('Data query facets must be a non-empty array');\n }\n if (value.length > MAX_DATA_QUERY_FACETS) {\n return fail(`Data query facets cannot exceed ${MAX_DATA_QUERY_FACETS}`);\n }\n const facets = value.map((entry) => {\n const object = plainObject(entry, 'Data query facet request');\n exactKeys(object, ['field', 'limit'], 'Data query facet request');\n const field = stringValue(object.field, 'Data query facet field');\n if (!fields.get(field)?.facetable) {\n fail(\n `Data query facet field is not allowed: ${field}`,\n 'DATA_QUERY_FACET_NOT_ALLOWED',\n );\n }\n return {\n field,\n limit: Math.min(\n positiveInteger(object.limit, 'Data query facet limit'),\n schema.maxPageLimit ?? MAX_DATA_QUERY_PAGE_LIMIT,\n ),\n };\n });\n if (new Set(facets.map((facet) => facet.field)).size !== facets.length) {\n return fail('Data query facet fields must be unique');\n }\n return facets.sort((left, right) =>\n compareCanonicalStrings(left.field, right.field),\n );\n}\n\nfunction boundRequestSize(request: DataQueryRequest): DataQueryRequest {\n const bytes = new TextEncoder().encode(JSON.stringify(request)).byteLength;\n if (bytes > MAX_DATA_QUERY_REQUEST_BYTES) {\n return fail(\n 'Data query request exceeds its maximum byte limit',\n 'DATA_QUERY_REQUEST_TOO_LARGE',\n );\n }\n return request;\n}\n\n/**\n * Normalize an untrusted request against its trusted adapter schema. Equivalent\n * projection/filter/facet orderings produce byte-identical output; sort order\n * remains intact because it is semantically meaningful. The identity field is\n * always projected even when a caller omits it.\n */\nexport function normalizeDataQueryRequest(\n value: unknown,\n inputSchema: unknown,\n): DataQueryRequest {\n const schema = normalizeDataQuerySchema(inputSchema);\n const fields = new Map(schema.fields.map((field) => [field.id, field]));\n const object = plainObject(value, 'Data query request');\n assertBoundedRawRequest(value);\n exactKeys(\n object,\n [\n 'version',\n 'requestId',\n 'mode',\n 'projection',\n 'filter',\n 'sort',\n 'page',\n 'consistency',\n 'facets',\n ],\n 'Data query request',\n );\n if (object.version !== 1)\n return fail('Unsupported data query request version');\n const requestId = stringValue(object.requestId, 'Data query request id', 128);\n const mode = stringValue(object.mode, 'Data query mode');\n if (!['rows', 'count', 'facets'].includes(mode))\n return fail(`Unsupported data query mode: ${mode}`);\n const filter =\n object.filter === undefined\n ? undefined\n : normalizeFilter(object.filter, fields);\n const consistency = normalizeConsistency(object.consistency, schema);\n if (mode === 'rows') {\n if (object.facets !== undefined)\n return fail('Rows queries cannot request facets');\n if (object.projection !== undefined && !Array.isArray(object.projection)) {\n return fail('Data query projection must be an array');\n }\n if (\n Array.isArray(object.projection) &&\n object.projection.length > MAX_DATA_QUERY_FILTERS\n ) {\n return fail(\n `Data query projection cannot exceed ${MAX_DATA_QUERY_FILTERS} fields`,\n );\n }\n const requestedProjection = (object.projection ?? []).map((field) =>\n stringValue(field, 'Data query projection field'),\n );\n for (const field of requestedProjection) {\n if (!fields.get(field)?.projectable && field !== schema.identityField) {\n fail(\n `Data query projection field is not allowed: ${field}`,\n 'DATA_QUERY_PROJECTION_NOT_ALLOWED',\n );\n }\n }\n const projection = [\n ...new Set([...requestedProjection, schema.identityField]),\n ].sort();\n const sort = normalizeSort(\n object.sort === undefined ? schema.defaultSort : object.sort,\n fields,\n schema.identityField,\n 'Data query sort',\n true,\n );\n return boundRequestSize({\n version: 1,\n requestId,\n mode,\n projection,\n ...(filter === undefined ? {} : { filter }),\n sort,\n page: normalizePage(object.page, schema),\n ...(consistency === undefined ? {} : { consistency }),\n });\n }\n if (\n object.projection !== undefined ||\n object.sort !== undefined ||\n object.page !== undefined\n ) {\n return fail(`${mode} data queries cannot carry projection, sort, or page`);\n }\n if (mode === 'facets') {\n return boundRequestSize({\n version: 1,\n requestId,\n mode,\n ...(filter === undefined ? {} : { filter }),\n ...(consistency === undefined ? {} : { consistency }),\n facets: normalizeFacets(object.facets, schema, fields),\n });\n }\n if (object.facets !== undefined)\n return fail('Count data queries cannot request facets');\n return boundRequestSize({\n version: 1,\n requestId,\n mode: 'count',\n ...(filter === undefined ? {} : { filter }),\n ...(consistency === undefined ? {} : { consistency }),\n });\n}\n\n/** Canonical match/query form used for stable fingerprints (no request id/page). */\nexport function canonicalizeDataQuery(value: unknown, schema: unknown): string {\n const request = normalizeDataQueryRequest(value, schema);\n const { requestId: _requestId, page: _page, ...semanticQuery } = request;\n return signature(semanticQuery);\n}\n\n/** Collision-resistant canonical fingerprint for result correlation and selection scope. */\nexport function createDataQueryFingerprint(\n value: unknown,\n schema: unknown,\n): string {\n return `dq1_${sha256Base64Url(canonicalizeDataQuery(value, schema))}`;\n}\n\nfunction normalizeResultFieldValue(\n value: unknown,\n descriptor: DataQueryFieldDescriptor,\n label: string,\n budget: JsonBudget,\n): unknown {\n if (descriptor.type === 'json') return canonicalJson(value, label, budget);\n const normalized = scalarForField(value, descriptor, label);\n consumeJsonSegment(budget, JSON.stringify(normalized), label);\n return normalized;\n}\n\nfunction normalizeRow(\n value: unknown,\n projection: readonly string[],\n identityField: string,\n fields: Map<string, DataQueryFieldDescriptor>,\n budget: JsonBudget,\n): DataQueryRow {\n const object = plainObject(value, 'Data query row');\n const allowed = new Set(projection);\n const normalized: JsonObject = Object.create(null) as JsonObject;\n consumeJsonSegment(budget, '{', 'Data query row');\n for (const [index, key] of Object.keys(object).entries()) {\n if (!allowed.has(key)) {\n fail(\n `Data query row returned a non-projected field: ${key}`,\n 'DATA_QUERY_RESULT_NOT_ALLOWED',\n );\n }\n const descriptor = fields.get(key);\n if (!descriptor) {\n return fail(\n `Data query row returned an undeclared field: ${key}`,\n 'DATA_QUERY_RESULT_NOT_ALLOWED',\n );\n }\n if (index > 0) consumeJsonSegment(budget, ',', 'Data query row');\n consumeJsonSegment(budget, JSON.stringify(key), `Data query row ${key}`);\n consumeJsonSegment(budget, ':', `Data query row ${key}`);\n normalized[key] = normalizeResultFieldValue(\n object[key],\n descriptor,\n `Data query row ${key}`,\n budget,\n );\n }\n consumeJsonSegment(budget, '}', 'Data query row');\n const identity = normalized[identityField];\n if (\n (typeof identity !== 'string' && typeof identity !== 'number') ||\n identity === ''\n ) {\n fail(\n 'Data query row must return a string or number identity field',\n 'DATA_QUERY_RESULT_INVALID',\n );\n }\n return normalized as DataQueryRow;\n}\n\nfunction normalizeTotal(value: unknown): DataQueryTotal {\n const object = plainObject(value, 'Data query total');\n const kind = stringValue(object.kind, 'Data query total kind');\n if (kind === 'unavailable') {\n exactKeys(object, ['kind', 'reason'], 'Data query unavailable total');\n const reason =\n object.reason === undefined\n ? undefined\n : stringValue(object.reason, 'Data query total reason');\n return { kind, ...(reason === undefined ? {} : { reason }) };\n }\n if (kind !== 'exact' && kind !== 'estimated') {\n return fail(`Unsupported data query total kind: ${kind}`);\n }\n exactKeys(object, ['kind', 'value', 'asOf'], 'Data query total');\n const asOf =\n object.asOf === undefined\n ? undefined\n : normalizedInstant(object.asOf, 'Data query total asOf');\n return {\n kind,\n value: nonNegativeInteger(object.value, 'Data query total value'),\n ...(asOf === undefined ? {} : { asOf }),\n };\n}\n\nfunction normalizeFreshness(value: unknown): DataQueryFreshness {\n const object = plainObject(value, 'Data query freshness');\n exactKeys(object, ['state', 'asOf'], 'Data query freshness');\n const state = stringValue(object.state, 'Data query freshness state');\n if (!['fresh', 'stale', 'unknown'].includes(state)) {\n return fail(`Unsupported data query freshness state: ${state}`);\n }\n const asOf =\n object.asOf === undefined\n ? undefined\n : normalizedInstant(object.asOf, 'Data query freshness asOf');\n return {\n state: state as DataQueryFreshness['state'],\n ...(asOf === undefined ? {} : { asOf }),\n };\n}\n\nfunction normalizeFacetsResult(\n value: unknown,\n requested: readonly DataQueryFacetRequest[],\n fields: Map<string, DataQueryFieldDescriptor>,\n budget: JsonBudget,\n): DataQueryFacetResult[] {\n if (!Array.isArray(value))\n return fail('Data query result facets must be an array');\n if (value.length > requested.length) {\n return fail('Data query result returned too many facets');\n }\n const limits = new Map(requested.map((facet) => [facet.field, facet.limit]));\n consumeJsonSegment(budget, '[', 'Data query result facets');\n const results = value.map((entry, index) => {\n if (index > 0) consumeJsonSegment(budget, ',', 'Data query result facets');\n const object = plainObject(entry, 'Data query facet result');\n exactKeys(\n object,\n ['field', 'values', 'truncated'],\n 'Data query facet result',\n );\n const field = stringValue(object.field, 'Data query facet result field');\n const limit = limits.get(field);\n if (limit === undefined)\n return fail(`Data query returned an unrequested facet: ${field}`);\n if (!Array.isArray(object.values) || object.values.length > limit) {\n return fail(`Data query facet ${field} exceeds its requested limit`);\n }\n if (typeof object.truncated !== 'boolean')\n return fail('Data query facet truncated must be boolean');\n const descriptor = fields.get(field);\n if (!descriptor)\n return fail(`Data query facet field is not declared: ${field}`);\n consumeJsonSegment(budget, '{\"field\":', `Data query facet ${field}`);\n consumeJsonSegment(\n budget,\n JSON.stringify(field),\n `Data query facet ${field}`,\n );\n consumeJsonSegment(budget, ',\"values\":[', `Data query facet ${field}`);\n const values = object.values.map((candidate, valueIndex) => {\n if (valueIndex > 0)\n consumeJsonSegment(budget, ',', `Data query facet ${field}`);\n const facet = plainObject(candidate, 'Data query facet value');\n exactKeys(facet, ['value', 'count'], 'Data query facet value');\n const normalizedValue = scalarForField(\n facet.value,\n descriptor,\n `Data query facet ${field} value`,\n );\n const count = nonNegativeInteger(facet.count, 'Data query facet count');\n consumeJsonSegment(\n budget,\n `{\"value\":${JSON.stringify(normalizedValue)},\"count\":${JSON.stringify(count)}}`,\n `Data query facet ${field} value`,\n );\n return {\n value: normalizedValue,\n count,\n };\n });\n consumeJsonSegment(\n budget,\n `],\"truncated\":${object.truncated}}`,\n `Data query facet ${field}`,\n );\n return { field, values, truncated: object.truncated };\n });\n consumeJsonSegment(budget, ']', 'Data query result facets');\n if (new Set(results.map((facet) => facet.field)).size !== results.length) {\n return fail('Data query result facet fields must be unique');\n }\n return results.sort((left, right) =>\n compareCanonicalStrings(left.field, right.field),\n );\n}\n\n/**\n * Validate an adapter result against the normalized request and its schema.\n * This is the final projection boundary: undeclared fields, malformed totals,\n * forged fingerprints, oversized rows, and authority-shaped prototype payloads\n * cannot cross into REST, MCP, WebMCP, or browser consumers unnoticed.\n */\nexport function normalizeDataQueryResult(\n value: unknown,\n inputRequest: unknown,\n inputSchema: unknown,\n): DataQueryResult {\n const schema = normalizeDataQuerySchema(inputSchema);\n const request = normalizeDataQueryRequest(inputRequest, schema);\n const fields = new Map(schema.fields.map((field) => [field.id, field]));\n const object = plainObject(value, 'Data query result');\n exactKeys(\n object,\n [\n 'version',\n 'requestId',\n 'queryFingerprint',\n 'identityField',\n 'rows',\n 'page',\n 'total',\n 'facets',\n 'freshness',\n 'warnings',\n 'truncated',\n ],\n 'Data query result',\n );\n if (object.version !== 1)\n return fail('Unsupported data query result version');\n if (\n stringValue(object.requestId, 'Data query result request id', 128) !==\n request.requestId\n ) {\n return fail(\n 'Data query result request id does not match its request',\n 'DATA_QUERY_RESULT_INVALID',\n );\n }\n const fingerprint = createDataQueryFingerprint(request, schema);\n if (\n stringValue(\n object.queryFingerprint,\n 'Data query result fingerprint',\n 128,\n ) !== fingerprint\n ) {\n return fail(\n 'Data query result fingerprint does not match its request',\n 'DATA_QUERY_RESULT_INVALID',\n );\n }\n if (\n stringValue(object.identityField, 'Data query result identity field') !==\n schema.identityField\n ) {\n return fail(\n 'Data query result identity field does not match its schema',\n 'DATA_QUERY_RESULT_INVALID',\n );\n }\n if (!Array.isArray(object.rows))\n return fail('Data query result rows must be an array');\n const projection =\n request.mode === 'rows'\n ? (request.projection ?? [schema.identityField])\n : [];\n const page = request.mode === 'rows' ? request.page : undefined;\n if (request.mode !== 'rows' && object.rows.length > 0) {\n return fail(`${request.mode} data query results cannot return rows`);\n }\n if (page && object.rows.length > page.limit) {\n return fail('Data query result rows exceed its requested page limit');\n }\n const budget: JsonBudget = {\n remaining: schema.maxResultBytes ?? DEFAULT_DATA_QUERY_RESULT_BYTES,\n failureCode: 'DATA_QUERY_RESULT_TOO_LARGE',\n };\n consumeJsonSegment(budget, '[', 'Data query result rows');\n const rows = object.rows.map((row, index) => {\n if (index > 0) consumeJsonSegment(budget, ',', 'Data query result rows');\n return normalizeRow(row, projection, schema.identityField, fields, budget);\n });\n consumeJsonSegment(budget, ']', 'Data query result rows');\n let normalizedPage: DataQueryResult['page'];\n if (page) {\n const pageObject = plainObject(object.page, 'Data query result page');\n exactKeys(\n pageObject,\n ['kind', 'limit', 'offset', 'nextCursor', 'hasMore'],\n 'Data query result page',\n );\n if (\n pageObject.kind !== page.kind ||\n nonNegativeInteger(pageObject.limit, 'Data query result page limit') !==\n page.limit\n ) {\n return fail('Data query result page does not match its request');\n }\n if (typeof pageObject.hasMore !== 'boolean')\n return fail('Data query result page hasMore must be boolean');\n if (page.kind === 'offset') {\n if (\n nonNegativeInteger(pageObject.offset, 'Data query result offset') !==\n page.offset\n ) {\n return fail('Data query result offset does not match its request');\n }\n if (pageObject.nextCursor !== undefined)\n return fail('Offset data query results cannot return a cursor');\n normalizedPage = {\n kind: 'offset',\n limit: page.limit,\n offset: page.offset,\n hasMore: pageObject.hasMore,\n };\n } else {\n if (pageObject.offset !== undefined) {\n return fail('Cursor data query results cannot return an offset');\n }\n const nextCursor =\n pageObject.nextCursor === undefined\n ? undefined\n : stringValue(\n pageObject.nextCursor,\n 'Data query result next cursor',\n MAX_DATA_QUERY_CURSOR_LENGTH,\n );\n if (pageObject.hasMore !== Boolean(nextCursor)) {\n return fail('Data query cursor result hasMore must match nextCursor');\n }\n normalizedPage = {\n kind: 'cursor',\n limit: page.limit,\n hasMore: pageObject.hasMore,\n ...(nextCursor === undefined ? {} : { nextCursor }),\n };\n }\n } else if (object.page !== undefined) {\n return fail(`${request.mode} data query results cannot return a page`);\n }\n const total = normalizeTotal(object.total);\n const freshness = normalizeFreshness(object.freshness);\n if (\n !Array.isArray(object.warnings) ||\n object.warnings.length > MAX_DATA_QUERY_WARNINGS ||\n object.warnings.some(\n (warning) =>\n typeof warning !== 'string' ||\n warning.length === 0 ||\n warning.length > 512,\n )\n ) {\n return fail('Data query result warnings must be at most 100 short strings');\n }\n if (typeof object.truncated !== 'boolean')\n return fail('Data query result truncated must be boolean');\n const facets =\n request.mode === 'facets'\n ? normalizeFacetsResult(\n object.facets,\n request.facets ?? [],\n fields,\n budget,\n )\n : object.facets === undefined\n ? undefined\n : fail(`${request.mode} data query results cannot return facets`);\n const normalized: DataQueryResult = {\n version: 1,\n requestId: request.requestId,\n queryFingerprint: fingerprint,\n identityField: schema.identityField,\n rows,\n ...(normalizedPage === undefined ? {} : { page: normalizedPage }),\n total,\n ...(facets === undefined ? {} : { facets }),\n freshness,\n warnings: [...new Set(object.warnings)].sort(),\n truncated: object.truncated,\n };\n const bytes = new TextEncoder().encode(JSON.stringify(normalized)).byteLength;\n if (bytes > (schema.maxResultBytes ?? DEFAULT_DATA_QUERY_RESULT_BYTES)) {\n return fail(\n 'Data query result exceeds its maximum byte limit',\n 'DATA_QUERY_RESULT_TOO_LARGE',\n );\n }\n return normalized;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"data-query.js","names":[],"sources":["../src/data-query.ts"],"sourcesContent":["/**\n * Canonical bounded data-query normalization (#2444).\n *\n * The shared package supplies only portable types. This server/runtime module\n * makes the contract executable at every trust boundary: it accepts only an\n * adapter-declared field/operator allowlist, canonicalizes equivalent\n * requests, creates a collision-resistant match fingerprint, and validates\n * that adapters return bounded, policy-filtered rows. It deliberately does\n * not execute SQL or resolve tenant/principal state; authenticated domain\n * adapters supply the schema and perform those responsibilities separately.\n */\n\nimport type {\n DataQueryAllowedValue,\n DataQueryCondition,\n DataQueryConsistency,\n DataQueryFacetRequest,\n DataQueryFacetResult,\n DataQueryFieldDescriptor,\n DataQueryFilter,\n DataQueryFilterOperator,\n DataQueryFreshness,\n DataQueryPage,\n DataQueryRequest,\n DataQueryResult,\n DataQueryRow,\n DataQueryScalar,\n DataQuerySchema,\n DataQuerySort,\n DataQueryTotal,\n} from '@happyvertical/smrt-types';\nimport { ValidationError } from './errors';\nimport { sha256Base64Url } from './utils/sha256.js';\n\n/** Default and hard ceilings for normalized data-query input and output. */\nexport const DEFAULT_DATA_QUERY_PAGE_LIMIT = 50;\nexport const MAX_DATA_QUERY_PAGE_LIMIT = 1_000;\nexport const DEFAULT_DATA_QUERY_RESULT_BYTES = 1_000_000;\nexport const MAX_DATA_QUERY_RESULT_BYTES = 10_000_000;\nexport const MAX_DATA_QUERY_REQUEST_BYTES = 100_000;\nexport const MAX_DATA_QUERY_OFFSET = 1_000_000;\nexport const MAX_DATA_QUERY_FILTER_DEPTH = 8;\nexport const MAX_DATA_QUERY_FILTERS = 50;\nexport const MAX_DATA_QUERY_IN_VALUES = 100;\nexport const MAX_DATA_QUERY_FACETS = 20;\nexport const MAX_DATA_QUERY_WARNINGS = 100;\nexport const MAX_DATA_QUERY_CURSOR_LENGTH = 2_048;\nexport const MAX_DATA_QUERY_JSON_DEPTH = 16;\nexport const MAX_DATA_QUERY_JSON_CONTAINER_ITEMS = 1_000;\nexport const MAX_DATA_QUERY_JSON_STRING_LENGTH = 65_536;\n/**\n * Bounds for host-declared allowed field values (#4381). The count matches\n * {@link MAX_DATA_QUERY_IN_VALUES} so a whole declared set fits one `in`.\n */\nexport const MAX_DATA_QUERY_FIELD_VALUES = 100;\nexport const MAX_DATA_QUERY_FIELD_VALUE_LENGTH = 256;\nexport const MAX_DATA_QUERY_FIELD_VALUE_LABEL_LENGTH = 128;\nexport const MAX_DATA_QUERY_FIELD_VALUE_DESCRIPTION_LENGTH = 512;\n/**\n * Allowed values listed in a rejected-filter message and its\n * `details.allowedValues` before truncation, so neither grows with the set.\n */\nconst MAX_LISTED_ALLOWED_VALUES = 20;\n/**\n * Control (C0/C1/DEL), format (bidi overrides/isolates, zero-width, BOM),\n * lone-surrogate, and line/paragraph-separator characters: none belongs in\n * schema text an agent reads, and bidi controls can disguise a value.\n */\nconst UNSAFE_SCHEMA_TEXT = /[\\p{Cc}\\p{Cf}\\p{Cs}\\p{Zl}\\p{Zp}]/u;\n\nconst FILTER_OPERATORS = new Set<DataQueryFilterOperator>([\n 'eq',\n 'ne',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'in',\n 'notIn',\n 'like',\n]);\nconst FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** A typed 400-class failure for malformed or policy-disallowed data queries. */\nexport class DataQueryValidationError extends ValidationError {\n readonly status = 400;\n readonly publicMessage: string;\n\n constructor(\n message: string,\n code = 'INVALID_DATA_QUERY',\n details?: Record<string, unknown>,\n ) {\n super(message, code, details);\n this.name = 'DataQueryValidationError';\n this.publicMessage = message;\n }\n}\n\ntype JsonObject = Record<string, unknown>;\n\ninterface JsonBudget {\n remaining: number;\n failureCode: string;\n}\n\nconst encoder = new TextEncoder();\nconst RFC_3339_INSTANT =\n /^(\\d{4})-(\\d{2})-(\\d{2})T([01]\\d|2[0-3]):([0-5]\\d):([0-5]\\d)(?:\\.\\d{1,9})?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$/;\n\nfunction fail(\n message: string,\n code = 'INVALID_DATA_QUERY',\n details?: Record<string, unknown>,\n): never {\n throw new DataQueryValidationError(message, code, details);\n}\n\nfunction plainObject(value: unknown, label: string): JsonObject {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return fail(`${label} must be an object`);\n }\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n return fail(`${label} must be a plain object`);\n }\n for (const key of Object.keys(value)) {\n if (FORBIDDEN_KEYS.has(key)) {\n return fail(`${label} contains a forbidden key`, 'FORBIDDEN_DATA_QUERY');\n }\n }\n return value as JsonObject;\n}\n\nfunction exactKeys(\n object: JsonObject,\n allowed: readonly string[],\n label: string,\n): void {\n const allowedKeys = new Set(allowed);\n for (const key of Object.keys(object)) {\n if (!allowedKeys.has(key)) {\n fail(\n `${label} contains unsupported key \"${key}\"`,\n 'FORBIDDEN_DATA_QUERY',\n );\n }\n }\n}\n\nfunction stringValue(value: unknown, label: string, maxLength = 256): string {\n if (\n typeof value !== 'string' ||\n value.length === 0 ||\n value.length > maxLength\n ) {\n return fail(\n `${label} must be a non-empty string up to ${maxLength} characters`,\n );\n }\n return value;\n}\n\nfunction nonNegativeInteger(value: unknown, label: string): number {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n return fail(`${label} must be a non-negative safe integer`);\n }\n return value as number;\n}\n\nfunction positiveInteger(value: unknown, label: string): number {\n const normalized = nonNegativeInteger(value, label);\n if (normalized === 0) return fail(`${label} must be a positive safe integer`);\n return normalized;\n}\n\nfunction normalizedInstant(value: unknown, label: string): string {\n const input = stringValue(value, label, 128);\n const match = RFC_3339_INSTANT.exec(input);\n if (!match) return fail(`${label} must be an RFC 3339 instant`);\n const [year, month, day] = match.slice(1, 4).map(Number);\n const calendar = new Date(0);\n calendar.setUTCFullYear(year, month - 1, day);\n calendar.setUTCHours(0, 0, 0, 0);\n if (\n calendar.getUTCFullYear() !== year ||\n calendar.getUTCMonth() !== month - 1 ||\n calendar.getUTCDate() !== day\n ) {\n return fail(`${label} must be an RFC 3339 instant`);\n }\n const milliseconds = Date.parse(input);\n if (!Number.isFinite(milliseconds)) {\n return fail(`${label} must be an RFC 3339 instant`);\n }\n return new Date(milliseconds).toISOString();\n}\n\nfunction dataQueryScalar(value: unknown, label: string): DataQueryScalar {\n if (value === null || typeof value === 'boolean') {\n return value;\n }\n if (typeof value === 'string') {\n if (value.length > 4_096) {\n return fail(`${label} cannot exceed 4096 characters`);\n }\n return value;\n }\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n return fail(`${label} must be a JSON scalar`);\n}\n\nfunction consumeJsonSegment(\n budget: JsonBudget | undefined,\n text: string,\n label: string,\n): void {\n if (!budget) return;\n if (text.length > budget.remaining) {\n fail(`${label} exceeds the maximum byte limit`, budget.failureCode);\n }\n const bytes = encoder.encode(text).byteLength;\n if (bytes > budget.remaining) {\n fail(`${label} exceeds the maximum byte limit`, budget.failureCode);\n }\n budget.remaining -= bytes;\n}\n\nfunction canonicalJson(\n value: unknown,\n label = 'Data query JSON',\n budget?: JsonBudget,\n depth = 0,\n ancestors = new Set<object>(),\n): unknown {\n if (depth > MAX_DATA_QUERY_JSON_DEPTH) {\n return fail(`${label} exceeds the JSON depth limit`);\n }\n if (value === null || typeof value === 'boolean') {\n consumeJsonSegment(budget, JSON.stringify(value), label);\n return value;\n }\n if (typeof value === 'string') {\n if (value.length > MAX_DATA_QUERY_JSON_STRING_LENGTH) {\n return fail(`${label} exceeds the JSON string limit`);\n }\n consumeJsonSegment(budget, JSON.stringify(value), label);\n return value;\n }\n if (typeof value === 'number') {\n if (!Number.isFinite(value))\n return fail(`${label} cannot contain a non-finite number`);\n const normalized = value === 0 ? 0 : value;\n consumeJsonSegment(budget, JSON.stringify(normalized), label);\n return normalized;\n }\n if (Array.isArray(value)) {\n if (value.length > MAX_DATA_QUERY_JSON_CONTAINER_ITEMS) {\n return fail(`${label} exceeds the JSON container-item limit`);\n }\n if (ancestors.has(value)) return fail(`${label} cannot contain a cycle`);\n ancestors.add(value);\n try {\n const result: unknown[] = [];\n consumeJsonSegment(budget, '[', label);\n for (const [index, entry] of value.entries()) {\n if (index > 0) consumeJsonSegment(budget, ',', label);\n result.push(\n canonicalJson(\n entry,\n `${label}[${index}]`,\n budget,\n depth + 1,\n ancestors,\n ),\n );\n }\n consumeJsonSegment(budget, ']', label);\n return result;\n } finally {\n ancestors.delete(value);\n }\n }\n const object = plainObject(value, label);\n const keys = Object.keys(object).sort(compareCanonicalStrings);\n if (keys.length > MAX_DATA_QUERY_JSON_CONTAINER_ITEMS) {\n return fail(`${label} exceeds the JSON container-item limit`);\n }\n if (ancestors.has(object)) return fail(`${label} cannot contain a cycle`);\n ancestors.add(object);\n try {\n const result: JsonObject = Object.create(null) as JsonObject;\n consumeJsonSegment(budget, '{', label);\n for (const [index, key] of keys.entries()) {\n if (key.length > MAX_DATA_QUERY_JSON_STRING_LENGTH) {\n return fail(`${label}.${key} exceeds the JSON string limit`);\n }\n if (index > 0) consumeJsonSegment(budget, ',', label);\n consumeJsonSegment(budget, JSON.stringify(key), `${label}.${key}`);\n consumeJsonSegment(budget, ':', label);\n Object.defineProperty(result, key, {\n value: canonicalJson(\n object[key],\n `${label}.${key}`,\n budget,\n depth + 1,\n ancestors,\n ),\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n consumeJsonSegment(budget, '}', label);\n return result;\n } finally {\n ancestors.delete(object);\n }\n}\n\nfunction signature(value: unknown): string {\n return JSON.stringify(canonicalJson(value));\n}\n\n/** Reject an over-limit raw request before canonicalization can collapse it. */\nfunction assertBoundedRawRequest(value: unknown): void {\n const budget: JsonBudget = {\n remaining: MAX_DATA_QUERY_REQUEST_BYTES,\n failureCode: 'DATA_QUERY_REQUEST_TOO_LARGE',\n };\n const ancestors = new Set<object>();\n\n const measure = (candidate: unknown, label: string, depth = 0): void => {\n if (depth > MAX_DATA_QUERY_JSON_DEPTH) {\n fail(`${label} exceeds the JSON depth limit`);\n }\n if (candidate === null || typeof candidate === 'boolean') {\n consumeJsonSegment(budget, JSON.stringify(candidate), label);\n return;\n }\n if (typeof candidate === 'string') {\n consumeJsonSegment(budget, JSON.stringify(candidate), label);\n return;\n }\n if (typeof candidate === 'number') {\n if (!Number.isFinite(candidate)) {\n fail(`${label} cannot contain a non-finite number`);\n }\n consumeJsonSegment(\n budget,\n JSON.stringify(candidate === 0 ? 0 : candidate),\n label,\n );\n return;\n }\n if (Array.isArray(candidate)) {\n if (ancestors.has(candidate)) fail(`${label} cannot contain a cycle`);\n ancestors.add(candidate);\n try {\n consumeJsonSegment(budget, '[', label);\n for (const [index, entry] of candidate.entries()) {\n if (index > 0) consumeJsonSegment(budget, ',', label);\n measure(entry, `${label}[${index}]`, depth + 1);\n }\n consumeJsonSegment(budget, ']', label);\n } finally {\n ancestors.delete(candidate);\n }\n return;\n }\n const object = plainObject(candidate, label);\n if (ancestors.has(object)) fail(`${label} cannot contain a cycle`);\n ancestors.add(object);\n try {\n consumeJsonSegment(budget, '{', label);\n for (const [index, key] of Object.keys(object).entries()) {\n if (index > 0) consumeJsonSegment(budget, ',', label);\n consumeJsonSegment(budget, JSON.stringify(key), `${label}.${key}`);\n consumeJsonSegment(budget, ':', label);\n measure(object[key], `${label}.${key}`, depth + 1);\n }\n consumeJsonSegment(budget, '}', label);\n } finally {\n ancestors.delete(object);\n }\n };\n\n measure(value, 'Data query request');\n}\n\n/** Locale-independent ordering for canonical envelopes and fingerprints. */\nfunction compareCanonicalStrings(left: string, right: string): number {\n if (left === right) return 0;\n return left < right ? -1 : 1;\n}\n\nfunction normalizeFieldDescriptor(value: unknown): DataQueryFieldDescriptor {\n const object = plainObject(value, 'Data query schema field');\n exactKeys(\n object,\n [\n 'id',\n 'type',\n 'projectable',\n 'sortable',\n 'facetable',\n 'filterOperators',\n 'values',\n 'valuesEnforced',\n ],\n 'Data query schema field',\n );\n const id = stringValue(object.id, 'Data query field id');\n const type = stringValue(object.type, `Data query field ${id} type`);\n if (!['string', 'number', 'boolean', 'datetime', 'json'].includes(type)) {\n return fail(`Unsupported data query field type: ${type}`);\n }\n for (const flag of ['projectable', 'sortable', 'facetable'] as const) {\n if (object[flag] !== undefined && typeof object[flag] !== 'boolean') {\n fail(`Data query field ${id} ${flag} must be boolean`);\n }\n }\n let filterOperators: DataQueryFilterOperator[] | undefined;\n if (object.filterOperators !== undefined) {\n if (!Array.isArray(object.filterOperators)) {\n return fail(`Data query field ${id} filterOperators must be an array`);\n }\n filterOperators = [\n ...new Set(\n object.filterOperators.map((operator) => {\n const normalized = stringValue(\n operator,\n `Data query field ${id} filter operator`,\n ) as DataQueryFilterOperator;\n if (!FILTER_OPERATORS.has(normalized)) {\n fail(`Unsupported data query filter operator: ${normalized}`);\n }\n return normalized;\n }),\n ),\n ].sort();\n }\n const projectable =\n typeof object.projectable === 'boolean' ? object.projectable : undefined;\n const sortable =\n typeof object.sortable === 'boolean' ? object.sortable : undefined;\n const facetable =\n typeof object.facetable === 'boolean' ? object.facetable : undefined;\n const values =\n object.values === undefined\n ? undefined\n : normalizeDataQueryFieldValues(\n object.values,\n type as DataQueryFieldDescriptor['type'],\n id,\n );\n if (object.valuesEnforced !== undefined) {\n if (typeof object.valuesEnforced !== 'boolean') {\n return fail(`Data query field ${id} valuesEnforced must be boolean`);\n }\n if (!values) {\n return fail(`Data query field ${id} valuesEnforced requires values`);\n }\n }\n // Enforcement is the default, so only the advisory form is kept.\n const advisory = values !== undefined && object.valuesEnforced === false;\n return {\n id,\n type: type as DataQueryFieldDescriptor['type'],\n ...(projectable === undefined ? {} : { projectable }),\n ...(sortable === undefined ? {} : { sortable }),\n ...(facetable === undefined ? {} : { facetable }),\n ...(filterOperators ? { filterOperators } : {}),\n ...(values ? { values } : {}),\n ...(advisory ? { valuesEnforced: false } : {}),\n };\n}\n\nfunction schemaText(value: unknown, label: string, maxLength: number): string {\n const text = stringValue(value, label, maxLength);\n if (UNSAFE_SCHEMA_TEXT.test(text)) {\n return fail(\n `${label} cannot contain control, format, or bidirectional characters`,\n );\n }\n return text;\n}\n\n/**\n * Validate a field's host-declared allowed values (#4381): a non-empty,\n * bounded, duplicate-free list whose values match the field type, with\n * optional label/description text free of control and bidi characters.\n * Declaration order is preserved. Throws {@link DataQueryValidationError}.\n */\nexport function normalizeDataQueryFieldValues(\n value: unknown,\n type: DataQueryFieldDescriptor['type'],\n fieldId: string,\n): DataQueryAllowedValue[] {\n const label = `Data query field ${fieldId} values`;\n if (type !== 'string' && type !== 'number' && type !== 'boolean') {\n return fail(\n `${label} are only supported on string, number, or boolean fields`,\n );\n }\n if (!Array.isArray(value) || value.length === 0) {\n return fail(`${label} must be a non-empty array`);\n }\n if (value.length > MAX_DATA_QUERY_FIELD_VALUES) {\n return fail(\n `${label} cannot exceed ${MAX_DATA_QUERY_FIELD_VALUES} entries`,\n );\n }\n const seen = new Set<string>();\n return value.map((entry, index) => {\n const entryLabel = `${label}[${index}]`;\n const object = plainObject(entry, entryLabel);\n exactKeys(object, ['value', 'label', 'description'], entryLabel);\n const raw = object.value;\n let allowed: string | number | boolean;\n if (type === 'string') {\n allowed = schemaText(\n raw,\n `${entryLabel} value`,\n MAX_DATA_QUERY_FIELD_VALUE_LENGTH,\n );\n } else if (type === 'number') {\n if (typeof raw !== 'number' || !Number.isFinite(raw)) {\n return fail(`${entryLabel} value must be a finite number`);\n }\n allowed = raw;\n } else {\n if (typeof raw !== 'boolean') {\n return fail(`${entryLabel} value must be a boolean`);\n }\n allowed = raw;\n }\n const key = signature(allowed);\n if (seen.has(key)) return fail(`${label} must be unique`);\n seen.add(key);\n const valueLabel =\n object.label === undefined\n ? undefined\n : schemaText(\n object.label,\n `${entryLabel} label`,\n MAX_DATA_QUERY_FIELD_VALUE_LABEL_LENGTH,\n );\n const description =\n object.description === undefined\n ? undefined\n : schemaText(\n object.description,\n `${entryLabel} description`,\n MAX_DATA_QUERY_FIELD_VALUE_DESCRIPTION_LENGTH,\n );\n return {\n value: allowed,\n ...(valueLabel === undefined ? {} : { label: valueLabel }),\n ...(description === undefined ? {} : { description }),\n };\n });\n}\n\n/**\n * Reject an equality-family filter value outside a field's enforced closed\n * set with a message the caller can act on. `null` stays allowed, and an\n * advisory set (`valuesEnforced: false`) accepts any value.\n */\nfunction assertDeclaredValue(\n scalar: DataQueryScalar,\n descriptor: DataQueryFieldDescriptor,\n label: string,\n): void {\n if (\n scalar === null ||\n !descriptor.values ||\n descriptor.valuesEnforced === false\n ) {\n return;\n }\n if (descriptor.values.some((entry) => entry.value === scalar)) return;\n const allowed = descriptor.values.map((entry) => entry.value);\n const shown = allowed.slice(0, MAX_LISTED_ALLOWED_VALUES);\n const listed = shown.map((entry) => JSON.stringify(entry)).join(', ');\n const more =\n allowed.length > MAX_LISTED_ALLOWED_VALUES\n ? `, and ${allowed.length - MAX_LISTED_ALLOWED_VALUES} more`\n : '';\n fail(\n `${label} is not an allowed value for ${descriptor.id}; use one of: ${listed}${more}`,\n 'DATA_QUERY_VALUE_NOT_ALLOWED',\n {\n field: descriptor.id,\n allowedValues: shown,\n allowedValueCount: allowed.length,\n },\n );\n}\n\n/** Validate and canonicalize trusted adapter query policy before use. */\nexport function normalizeDataQuerySchema(value: unknown): DataQuerySchema {\n const object = plainObject(value, 'Data query schema');\n exactKeys(\n object,\n [\n 'version',\n 'identityField',\n 'fields',\n 'defaultPageLimit',\n 'maxPageLimit',\n 'maxResultBytes',\n 'defaultSort',\n 'supports',\n ],\n 'Data query schema',\n );\n if (object.version !== 1)\n return fail('Unsupported data query schema version');\n if (!Array.isArray(object.fields) || object.fields.length === 0) {\n return fail('Data query schema fields must be a non-empty array');\n }\n const fields = object.fields\n .map(normalizeFieldDescriptor)\n .sort((left, right) => compareCanonicalStrings(left.id, right.id));\n if (new Set(fields.map((field) => field.id)).size !== fields.length) {\n return fail('Data query schema field ids must be unique');\n }\n const identityField = stringValue(\n object.identityField,\n 'Data query identity field',\n );\n const identity = fields.find((field) => field.id === identityField);\n if (!identity) return fail('Data query identity field must be declared');\n if (identity.projectable === false) {\n return fail('Data query identity field must be projectable');\n }\n if (!['string', 'number', 'datetime'].includes(identity.type)) {\n return fail(\n 'Data query identity field must use a string, number, or datetime type',\n );\n }\n const maxPageLimit =\n object.maxPageLimit === undefined\n ? MAX_DATA_QUERY_PAGE_LIMIT\n : positiveInteger(object.maxPageLimit, 'Data query maximum page limit');\n if (maxPageLimit > MAX_DATA_QUERY_PAGE_LIMIT) {\n return fail(\n `Data query maximum page limit cannot exceed ${MAX_DATA_QUERY_PAGE_LIMIT}`,\n );\n }\n const defaultPageLimit =\n object.defaultPageLimit === undefined\n ? Math.min(DEFAULT_DATA_QUERY_PAGE_LIMIT, maxPageLimit)\n : positiveInteger(\n object.defaultPageLimit,\n 'Data query default page limit',\n );\n if (defaultPageLimit > maxPageLimit) {\n return fail(\n 'Data query default page limit cannot exceed the maximum page limit',\n );\n }\n const maxResultBytes =\n object.maxResultBytes === undefined\n ? DEFAULT_DATA_QUERY_RESULT_BYTES\n : positiveInteger(\n object.maxResultBytes,\n 'Data query maximum result bytes',\n );\n if (maxResultBytes > MAX_DATA_QUERY_RESULT_BYTES) {\n return fail(\n `Data query maximum result bytes cannot exceed ${MAX_DATA_QUERY_RESULT_BYTES}`,\n );\n }\n let supports: DataQuerySchema['supports'];\n if (object.supports !== undefined) {\n const supportObject = plainObject(\n object.supports,\n 'Data query schema supports',\n );\n exactKeys(\n supportObject,\n ['cursorPagination', 'consistency', 'facets'],\n 'Data query schema supports',\n );\n for (const key of ['cursorPagination', 'consistency', 'facets'] as const) {\n if (\n supportObject[key] !== undefined &&\n typeof supportObject[key] !== 'boolean'\n ) {\n fail(`Data query schema supports.${key} must be boolean`);\n }\n }\n const cursorPagination =\n typeof supportObject.cursorPagination === 'boolean'\n ? supportObject.cursorPagination\n : undefined;\n const consistency =\n typeof supportObject.consistency === 'boolean'\n ? supportObject.consistency\n : undefined;\n const facets =\n typeof supportObject.facets === 'boolean'\n ? supportObject.facets\n : undefined;\n supports = {\n ...(cursorPagination === undefined ? {} : { cursorPagination }),\n ...(consistency === undefined ? {} : { consistency }),\n ...(facets === undefined ? {} : { facets }),\n };\n }\n const fieldMap = new Map(fields.map((field) => [field.id, field]));\n const defaultSort = normalizeSort(\n object.defaultSort,\n fieldMap,\n identityField,\n 'Data query default sort',\n false,\n );\n return {\n version: 1,\n identityField,\n fields,\n defaultPageLimit,\n maxPageLimit,\n maxResultBytes,\n ...(defaultSort.length > 0 ? { defaultSort } : {}),\n ...(supports ? { supports } : {}),\n };\n}\n\ninterface FilterBudget {\n nodes: number;\n}\n\nfunction scalarForField(\n value: unknown,\n descriptor: DataQueryFieldDescriptor,\n label: string,\n): DataQueryScalar {\n const scalar = dataQueryScalar(value, label);\n if (scalar === null) return scalar;\n if (descriptor.type === 'number' && typeof scalar !== 'number') {\n return fail(`${label} must be a number for ${descriptor.id}`);\n }\n if (descriptor.type === 'boolean' && typeof scalar !== 'boolean') {\n return fail(`${label} must be a boolean for ${descriptor.id}`);\n }\n if (descriptor.type === 'string' && typeof scalar !== 'string') {\n return fail(`${label} must be a string for ${descriptor.id}`);\n }\n if (descriptor.type === 'datetime') {\n if (typeof scalar !== 'string') {\n return fail(`${label} must be an RFC 3339 instant for ${descriptor.id}`);\n }\n return normalizedInstant(scalar, label);\n }\n return scalar;\n}\n\nfunction normalizeFilter(\n value: unknown,\n fields: Map<string, DataQueryFieldDescriptor>,\n depth = 0,\n budget: FilterBudget = { nodes: 0 },\n): DataQueryFilter {\n if (depth > MAX_DATA_QUERY_FILTER_DEPTH) {\n return fail(\n `Data query filter cannot exceed depth ${MAX_DATA_QUERY_FILTER_DEPTH}`,\n );\n }\n budget.nodes += 1;\n if (budget.nodes > MAX_DATA_QUERY_FILTERS) {\n return fail(\n `Data query filter cannot exceed ${MAX_DATA_QUERY_FILTERS} expressions`,\n );\n }\n const object = plainObject(value, 'Data query filter');\n const kind = stringValue(object.kind, 'Data query filter kind');\n if (kind === 'condition') {\n exactKeys(\n object,\n ['kind', 'field', 'operator', 'value'],\n 'Data query condition',\n );\n const field = stringValue(object.field, 'Data query condition field');\n const descriptor = fields.get(field);\n if (!descriptor)\n return fail(\n `Data query field is not declared: ${field}`,\n 'DATA_QUERY_FIELD_NOT_ALLOWED',\n );\n const operator = stringValue(\n object.operator,\n 'Data query condition operator',\n ) as DataQueryFilterOperator;\n if (\n !FILTER_OPERATORS.has(operator) ||\n !descriptor.filterOperators?.includes(operator)\n ) {\n return fail(\n `Data query operator ${operator} is not allowed for ${field}`,\n 'DATA_QUERY_OPERATOR_NOT_ALLOWED',\n );\n }\n if (operator === 'in' || operator === 'notIn') {\n if (!Array.isArray(object.value) || object.value.length === 0) {\n return fail(`Data query ${operator} value must be a non-empty array`);\n }\n if (object.value.length > MAX_DATA_QUERY_IN_VALUES) {\n return fail(\n `Data query ${operator} value cannot exceed ${MAX_DATA_QUERY_IN_VALUES} items`,\n );\n }\n const values = object.value.map((entry, index) => {\n const entryLabel = `Data query ${operator} value ${index}`;\n const scalar = scalarForField(entry, descriptor, entryLabel);\n assertDeclaredValue(scalar, descriptor, entryLabel);\n return scalar;\n });\n const canonicalValues = [\n ...new Map(values.map((entry) => [signature(entry), entry])).values(),\n ].sort((left, right) =>\n compareCanonicalStrings(signature(left), signature(right)),\n );\n return { kind: 'condition', field, operator, value: canonicalValues };\n }\n if (Array.isArray(object.value)) {\n return fail(`Data query ${operator} value must be a scalar`);\n }\n const scalar = scalarForField(\n object.value,\n descriptor,\n `Data query ${operator} value`,\n );\n if (operator === 'eq' || operator === 'ne') {\n assertDeclaredValue(scalar, descriptor, `Data query ${operator} value`);\n }\n if (operator === 'like' && descriptor.type !== 'string') {\n return fail('Data query like is only available for string fields');\n }\n if (operator === 'like' && typeof scalar !== 'string') {\n return fail('Data query like value must be a string');\n }\n if (\n ['gt', 'gte', 'lt', 'lte'].includes(operator) &&\n !['number', 'string', 'datetime'].includes(descriptor.type)\n ) {\n return fail(\n `Data query ${operator} is not available for ${descriptor.type} fields`,\n );\n }\n if (\n ['gt', 'gte', 'lt', 'lte', 'like'].includes(operator) &&\n scalar === null\n ) {\n return fail(`Data query ${operator} value cannot be null`);\n }\n return {\n kind: 'condition',\n field,\n operator,\n value: scalar,\n } as DataQueryCondition;\n }\n if (kind === 'all' || kind === 'any') {\n exactKeys(object, ['kind', 'filters'], `Data query ${kind} filter`);\n if (!Array.isArray(object.filters) || object.filters.length === 0) {\n return fail(`Data query ${kind} filter must contain at least one child`);\n }\n if (object.filters.length > MAX_DATA_QUERY_FILTERS) {\n return fail(\n `Data query ${kind} filter cannot exceed ${MAX_DATA_QUERY_FILTERS} children`,\n );\n }\n const filters = object.filters\n .map((filter) => normalizeFilter(filter, fields, depth + 1, budget))\n .sort((left, right) =>\n compareCanonicalStrings(signature(left), signature(right)),\n );\n return { kind, filters };\n }\n if (kind === 'not') {\n exactKeys(object, ['kind', 'filter'], 'Data query not filter');\n return {\n kind: 'not',\n filter: normalizeFilter(object.filter, fields, depth + 1, budget),\n };\n }\n return fail(`Unsupported data query filter kind: ${kind}`);\n}\n\nfunction normalizeSort(\n value: unknown,\n fields: Map<string, DataQueryFieldDescriptor>,\n identityField: string,\n label: string,\n appendIdentity: boolean,\n): DataQuerySort[] {\n if (value === undefined)\n return appendIdentity ? [{ field: identityField, direction: 'asc' }] : [];\n if (!Array.isArray(value)) return fail(`${label} must be an array`);\n if (value.length > MAX_DATA_QUERY_FILTERS) {\n return fail(`${label} cannot exceed ${MAX_DATA_QUERY_FILTERS} terms`);\n }\n const sort = value.map((entry) => {\n const object = plainObject(entry, label);\n exactKeys(object, ['field', 'direction'], label);\n const field = stringValue(object.field, `${label} field`);\n if (!fields.get(field)?.sortable && field !== identityField) {\n fail(\n `Data query sort field is not allowed: ${field}`,\n 'DATA_QUERY_SORT_NOT_ALLOWED',\n );\n }\n const direction = stringValue(object.direction, `${label} direction`);\n if (direction !== 'asc' && direction !== 'desc') {\n fail(`Data query sort direction must be asc or desc`);\n }\n return { field, direction } as DataQuerySort;\n });\n if (new Set(sort.map((term) => term.field)).size !== sort.length) {\n return fail(`${label} field ids must be unique`);\n }\n if (appendIdentity && !sort.some((term) => term.field === identityField)) {\n sort.push({ field: identityField, direction: 'asc' });\n }\n return sort;\n}\n\nfunction normalizePage(value: unknown, schema: DataQuerySchema): DataQueryPage {\n if (value === undefined) {\n return {\n kind: 'offset',\n offset: 0,\n limit: schema.defaultPageLimit ?? DEFAULT_DATA_QUERY_PAGE_LIMIT,\n };\n }\n const object = plainObject(value, 'Data query page');\n const kind = stringValue(object.kind, 'Data query page kind');\n if (kind === 'offset') {\n exactKeys(object, ['kind', 'offset', 'limit'], 'Data query offset page');\n const offset = nonNegativeInteger(object.offset, 'Data query offset');\n if (offset > MAX_DATA_QUERY_OFFSET) {\n return fail(`Data query offset cannot exceed ${MAX_DATA_QUERY_OFFSET}`);\n }\n return {\n kind,\n offset,\n limit: Math.min(\n positiveInteger(object.limit, 'Data query page limit'),\n schema.maxPageLimit ?? MAX_DATA_QUERY_PAGE_LIMIT,\n ),\n };\n }\n if (kind === 'cursor') {\n if (!schema.supports?.cursorPagination) {\n return fail(\n 'Data query cursor pagination is not supported',\n 'DATA_QUERY_UNSUPPORTED',\n );\n }\n exactKeys(object, ['kind', 'after', 'limit'], 'Data query cursor page');\n const after =\n object.after === undefined\n ? undefined\n : stringValue(\n object.after,\n 'Data query cursor',\n MAX_DATA_QUERY_CURSOR_LENGTH,\n );\n return {\n kind,\n ...(after === undefined ? {} : { after }),\n limit: Math.min(\n positiveInteger(object.limit, 'Data query page limit'),\n schema.maxPageLimit ?? MAX_DATA_QUERY_PAGE_LIMIT,\n ),\n };\n }\n return fail(`Unsupported data query page kind: ${kind}`);\n}\n\nfunction normalizeConsistency(\n value: unknown,\n schema: DataQuerySchema,\n): DataQueryConsistency | undefined {\n if (value === undefined) return undefined;\n if (!schema.supports?.consistency) {\n return fail(\n 'Data query consistency options are not supported',\n 'DATA_QUERY_UNSUPPORTED',\n );\n }\n const object = plainObject(value, 'Data query consistency');\n exactKeys(object, ['mode', 'asOf'], 'Data query consistency');\n if (object.mode !== 'eventual' && object.mode !== 'snapshot')\n return fail('Unsupported data query consistency mode');\n const asOf =\n object.asOf === undefined\n ? undefined\n : normalizedInstant(object.asOf, 'Data query consistency asOf');\n return {\n mode: object.mode,\n ...(asOf === undefined ? {} : { asOf }),\n } as DataQueryConsistency;\n}\n\nfunction normalizeFacets(\n value: unknown,\n schema: DataQuerySchema,\n fields: Map<string, DataQueryFieldDescriptor>,\n): DataQueryFacetRequest[] {\n if (!schema.supports?.facets) {\n return fail(\n 'Data query facets are not supported',\n 'DATA_QUERY_UNSUPPORTED',\n );\n }\n if (!Array.isArray(value) || value.length === 0) {\n return fail('Data query facets must be a non-empty array');\n }\n if (value.length > MAX_DATA_QUERY_FACETS) {\n return fail(`Data query facets cannot exceed ${MAX_DATA_QUERY_FACETS}`);\n }\n const facets = value.map((entry) => {\n const object = plainObject(entry, 'Data query facet request');\n exactKeys(object, ['field', 'limit'], 'Data query facet request');\n const field = stringValue(object.field, 'Data query facet field');\n if (!fields.get(field)?.facetable) {\n fail(\n `Data query facet field is not allowed: ${field}`,\n 'DATA_QUERY_FACET_NOT_ALLOWED',\n );\n }\n return {\n field,\n limit: Math.min(\n positiveInteger(object.limit, 'Data query facet limit'),\n schema.maxPageLimit ?? MAX_DATA_QUERY_PAGE_LIMIT,\n ),\n };\n });\n if (new Set(facets.map((facet) => facet.field)).size !== facets.length) {\n return fail('Data query facet fields must be unique');\n }\n return facets.sort((left, right) =>\n compareCanonicalStrings(left.field, right.field),\n );\n}\n\nfunction boundRequestSize(request: DataQueryRequest): DataQueryRequest {\n const bytes = new TextEncoder().encode(JSON.stringify(request)).byteLength;\n if (bytes > MAX_DATA_QUERY_REQUEST_BYTES) {\n return fail(\n 'Data query request exceeds its maximum byte limit',\n 'DATA_QUERY_REQUEST_TOO_LARGE',\n );\n }\n return request;\n}\n\n/**\n * Normalize an untrusted request against its trusted adapter schema. Equivalent\n * projection/filter/facet orderings produce byte-identical output; sort order\n * remains intact because it is semantically meaningful. The identity field is\n * always projected even when a caller omits it.\n */\nexport function normalizeDataQueryRequest(\n value: unknown,\n inputSchema: unknown,\n): DataQueryRequest {\n const schema = normalizeDataQuerySchema(inputSchema);\n const fields = new Map(schema.fields.map((field) => [field.id, field]));\n const object = plainObject(value, 'Data query request');\n assertBoundedRawRequest(value);\n exactKeys(\n object,\n [\n 'version',\n 'requestId',\n 'mode',\n 'projection',\n 'filter',\n 'sort',\n 'page',\n 'consistency',\n 'facets',\n ],\n 'Data query request',\n );\n if (object.version !== 1)\n return fail('Unsupported data query request version');\n const requestId = stringValue(object.requestId, 'Data query request id', 128);\n const mode = stringValue(object.mode, 'Data query mode');\n if (!['rows', 'count', 'facets'].includes(mode))\n return fail(`Unsupported data query mode: ${mode}`);\n const filter =\n object.filter === undefined\n ? undefined\n : normalizeFilter(object.filter, fields);\n const consistency = normalizeConsistency(object.consistency, schema);\n if (mode === 'rows') {\n if (object.facets !== undefined)\n return fail('Rows queries cannot request facets');\n if (object.projection !== undefined && !Array.isArray(object.projection)) {\n return fail('Data query projection must be an array');\n }\n if (\n Array.isArray(object.projection) &&\n object.projection.length > MAX_DATA_QUERY_FILTERS\n ) {\n return fail(\n `Data query projection cannot exceed ${MAX_DATA_QUERY_FILTERS} fields`,\n );\n }\n const requestedProjection = (object.projection ?? []).map((field) =>\n stringValue(field, 'Data query projection field'),\n );\n for (const field of requestedProjection) {\n if (!fields.get(field)?.projectable && field !== schema.identityField) {\n fail(\n `Data query projection field is not allowed: ${field}`,\n 'DATA_QUERY_PROJECTION_NOT_ALLOWED',\n );\n }\n }\n const projection = [\n ...new Set([...requestedProjection, schema.identityField]),\n ].sort();\n const sort = normalizeSort(\n object.sort === undefined ? schema.defaultSort : object.sort,\n fields,\n schema.identityField,\n 'Data query sort',\n true,\n );\n return boundRequestSize({\n version: 1,\n requestId,\n mode,\n projection,\n ...(filter === undefined ? {} : { filter }),\n sort,\n page: normalizePage(object.page, schema),\n ...(consistency === undefined ? {} : { consistency }),\n });\n }\n if (\n object.projection !== undefined ||\n object.sort !== undefined ||\n object.page !== undefined\n ) {\n return fail(`${mode} data queries cannot carry projection, sort, or page`);\n }\n if (mode === 'facets') {\n return boundRequestSize({\n version: 1,\n requestId,\n mode,\n ...(filter === undefined ? {} : { filter }),\n ...(consistency === undefined ? {} : { consistency }),\n facets: normalizeFacets(object.facets, schema, fields),\n });\n }\n if (object.facets !== undefined)\n return fail('Count data queries cannot request facets');\n return boundRequestSize({\n version: 1,\n requestId,\n mode: 'count',\n ...(filter === undefined ? {} : { filter }),\n ...(consistency === undefined ? {} : { consistency }),\n });\n}\n\n/** Canonical match/query form used for stable fingerprints (no request id/page). */\nexport function canonicalizeDataQuery(value: unknown, schema: unknown): string {\n const request = normalizeDataQueryRequest(value, schema);\n const { requestId: _requestId, page: _page, ...semanticQuery } = request;\n return signature(semanticQuery);\n}\n\n/** Collision-resistant canonical fingerprint for result correlation and selection scope. */\nexport function createDataQueryFingerprint(\n value: unknown,\n schema: unknown,\n): string {\n return `dq1_${sha256Base64Url(canonicalizeDataQuery(value, schema))}`;\n}\n\nfunction normalizeResultFieldValue(\n value: unknown,\n descriptor: DataQueryFieldDescriptor,\n label: string,\n budget: JsonBudget,\n): unknown {\n if (descriptor.type === 'json') return canonicalJson(value, label, budget);\n const normalized = scalarForField(value, descriptor, label);\n consumeJsonSegment(budget, JSON.stringify(normalized), label);\n return normalized;\n}\n\nfunction normalizeRow(\n value: unknown,\n projection: readonly string[],\n identityField: string,\n fields: Map<string, DataQueryFieldDescriptor>,\n budget: JsonBudget,\n): DataQueryRow {\n const object = plainObject(value, 'Data query row');\n const allowed = new Set(projection);\n const normalized: JsonObject = Object.create(null) as JsonObject;\n consumeJsonSegment(budget, '{', 'Data query row');\n for (const [index, key] of Object.keys(object).entries()) {\n if (!allowed.has(key)) {\n fail(\n `Data query row returned a non-projected field: ${key}`,\n 'DATA_QUERY_RESULT_NOT_ALLOWED',\n );\n }\n const descriptor = fields.get(key);\n if (!descriptor) {\n return fail(\n `Data query row returned an undeclared field: ${key}`,\n 'DATA_QUERY_RESULT_NOT_ALLOWED',\n );\n }\n if (index > 0) consumeJsonSegment(budget, ',', 'Data query row');\n consumeJsonSegment(budget, JSON.stringify(key), `Data query row ${key}`);\n consumeJsonSegment(budget, ':', `Data query row ${key}`);\n normalized[key] = normalizeResultFieldValue(\n object[key],\n descriptor,\n `Data query row ${key}`,\n budget,\n );\n }\n consumeJsonSegment(budget, '}', 'Data query row');\n const identity = normalized[identityField];\n if (\n (typeof identity !== 'string' && typeof identity !== 'number') ||\n identity === ''\n ) {\n fail(\n 'Data query row must return a string or number identity field',\n 'DATA_QUERY_RESULT_INVALID',\n );\n }\n return normalized as DataQueryRow;\n}\n\nfunction normalizeTotal(value: unknown): DataQueryTotal {\n const object = plainObject(value, 'Data query total');\n const kind = stringValue(object.kind, 'Data query total kind');\n if (kind === 'unavailable') {\n exactKeys(object, ['kind', 'reason'], 'Data query unavailable total');\n const reason =\n object.reason === undefined\n ? undefined\n : stringValue(object.reason, 'Data query total reason');\n return { kind, ...(reason === undefined ? {} : { reason }) };\n }\n if (kind !== 'exact' && kind !== 'estimated') {\n return fail(`Unsupported data query total kind: ${kind}`);\n }\n exactKeys(object, ['kind', 'value', 'asOf'], 'Data query total');\n const asOf =\n object.asOf === undefined\n ? undefined\n : normalizedInstant(object.asOf, 'Data query total asOf');\n return {\n kind,\n value: nonNegativeInteger(object.value, 'Data query total value'),\n ...(asOf === undefined ? {} : { asOf }),\n };\n}\n\nfunction normalizeFreshness(value: unknown): DataQueryFreshness {\n const object = plainObject(value, 'Data query freshness');\n exactKeys(object, ['state', 'asOf'], 'Data query freshness');\n const state = stringValue(object.state, 'Data query freshness state');\n if (!['fresh', 'stale', 'unknown'].includes(state)) {\n return fail(`Unsupported data query freshness state: ${state}`);\n }\n const asOf =\n object.asOf === undefined\n ? undefined\n : normalizedInstant(object.asOf, 'Data query freshness asOf');\n return {\n state: state as DataQueryFreshness['state'],\n ...(asOf === undefined ? {} : { asOf }),\n };\n}\n\nfunction normalizeFacetsResult(\n value: unknown,\n requested: readonly DataQueryFacetRequest[],\n fields: Map<string, DataQueryFieldDescriptor>,\n budget: JsonBudget,\n): DataQueryFacetResult[] {\n if (!Array.isArray(value))\n return fail('Data query result facets must be an array');\n if (value.length > requested.length) {\n return fail('Data query result returned too many facets');\n }\n const limits = new Map(requested.map((facet) => [facet.field, facet.limit]));\n consumeJsonSegment(budget, '[', 'Data query result facets');\n const results = value.map((entry, index) => {\n if (index > 0) consumeJsonSegment(budget, ',', 'Data query result facets');\n const object = plainObject(entry, 'Data query facet result');\n exactKeys(\n object,\n ['field', 'values', 'truncated'],\n 'Data query facet result',\n );\n const field = stringValue(object.field, 'Data query facet result field');\n const limit = limits.get(field);\n if (limit === undefined)\n return fail(`Data query returned an unrequested facet: ${field}`);\n if (!Array.isArray(object.values) || object.values.length > limit) {\n return fail(`Data query facet ${field} exceeds its requested limit`);\n }\n if (typeof object.truncated !== 'boolean')\n return fail('Data query facet truncated must be boolean');\n const descriptor = fields.get(field);\n if (!descriptor)\n return fail(`Data query facet field is not declared: ${field}`);\n consumeJsonSegment(budget, '{\"field\":', `Data query facet ${field}`);\n consumeJsonSegment(\n budget,\n JSON.stringify(field),\n `Data query facet ${field}`,\n );\n consumeJsonSegment(budget, ',\"values\":[', `Data query facet ${field}`);\n const values = object.values.map((candidate, valueIndex) => {\n if (valueIndex > 0)\n consumeJsonSegment(budget, ',', `Data query facet ${field}`);\n const facet = plainObject(candidate, 'Data query facet value');\n exactKeys(facet, ['value', 'count'], 'Data query facet value');\n const normalizedValue = scalarForField(\n facet.value,\n descriptor,\n `Data query facet ${field} value`,\n );\n const count = nonNegativeInteger(facet.count, 'Data query facet count');\n consumeJsonSegment(\n budget,\n `{\"value\":${JSON.stringify(normalizedValue)},\"count\":${JSON.stringify(count)}}`,\n `Data query facet ${field} value`,\n );\n return {\n value: normalizedValue,\n count,\n };\n });\n consumeJsonSegment(\n budget,\n `],\"truncated\":${object.truncated}}`,\n `Data query facet ${field}`,\n );\n return { field, values, truncated: object.truncated };\n });\n consumeJsonSegment(budget, ']', 'Data query result facets');\n if (new Set(results.map((facet) => facet.field)).size !== results.length) {\n return fail('Data query result facet fields must be unique');\n }\n return results.sort((left, right) =>\n compareCanonicalStrings(left.field, right.field),\n );\n}\n\n/**\n * Validate an adapter result against the normalized request and its schema.\n * This is the final projection boundary: undeclared fields, malformed totals,\n * forged fingerprints, oversized rows, and authority-shaped prototype payloads\n * cannot cross into REST, MCP, WebMCP, or browser consumers unnoticed.\n */\nexport function normalizeDataQueryResult(\n value: unknown,\n inputRequest: unknown,\n inputSchema: unknown,\n): DataQueryResult {\n const schema = normalizeDataQuerySchema(inputSchema);\n const request = normalizeDataQueryRequest(inputRequest, schema);\n const fields = new Map(schema.fields.map((field) => [field.id, field]));\n const object = plainObject(value, 'Data query result');\n exactKeys(\n object,\n [\n 'version',\n 'requestId',\n 'queryFingerprint',\n 'identityField',\n 'rows',\n 'page',\n 'total',\n 'facets',\n 'freshness',\n 'warnings',\n 'truncated',\n ],\n 'Data query result',\n );\n if (object.version !== 1)\n return fail('Unsupported data query result version');\n if (\n stringValue(object.requestId, 'Data query result request id', 128) !==\n request.requestId\n ) {\n return fail(\n 'Data query result request id does not match its request',\n 'DATA_QUERY_RESULT_INVALID',\n );\n }\n const fingerprint = createDataQueryFingerprint(request, schema);\n if (\n stringValue(\n object.queryFingerprint,\n 'Data query result fingerprint',\n 128,\n ) !== fingerprint\n ) {\n return fail(\n 'Data query result fingerprint does not match its request',\n 'DATA_QUERY_RESULT_INVALID',\n );\n }\n if (\n stringValue(object.identityField, 'Data query result identity field') !==\n schema.identityField\n ) {\n return fail(\n 'Data query result identity field does not match its schema',\n 'DATA_QUERY_RESULT_INVALID',\n );\n }\n if (!Array.isArray(object.rows))\n return fail('Data query result rows must be an array');\n const projection =\n request.mode === 'rows'\n ? (request.projection ?? [schema.identityField])\n : [];\n const page = request.mode === 'rows' ? request.page : undefined;\n if (request.mode !== 'rows' && object.rows.length > 0) {\n return fail(`${request.mode} data query results cannot return rows`);\n }\n if (page && object.rows.length > page.limit) {\n return fail('Data query result rows exceed its requested page limit');\n }\n const budget: JsonBudget = {\n remaining: schema.maxResultBytes ?? DEFAULT_DATA_QUERY_RESULT_BYTES,\n failureCode: 'DATA_QUERY_RESULT_TOO_LARGE',\n };\n consumeJsonSegment(budget, '[', 'Data query result rows');\n const rows = object.rows.map((row, index) => {\n if (index > 0) consumeJsonSegment(budget, ',', 'Data query result rows');\n return normalizeRow(row, projection, schema.identityField, fields, budget);\n });\n consumeJsonSegment(budget, ']', 'Data query result rows');\n let normalizedPage: DataQueryResult['page'];\n if (page) {\n const pageObject = plainObject(object.page, 'Data query result page');\n exactKeys(\n pageObject,\n ['kind', 'limit', 'offset', 'nextCursor', 'hasMore'],\n 'Data query result page',\n );\n if (\n pageObject.kind !== page.kind ||\n nonNegativeInteger(pageObject.limit, 'Data query result page limit') !==\n page.limit\n ) {\n return fail('Data query result page does not match its request');\n }\n if (typeof pageObject.hasMore !== 'boolean')\n return fail('Data query result page hasMore must be boolean');\n if (page.kind === 'offset') {\n if (\n nonNegativeInteger(pageObject.offset, 'Data query result offset') !==\n page.offset\n ) {\n return fail('Data query result offset does not match its request');\n }\n if (pageObject.nextCursor !== undefined)\n return fail('Offset data query results cannot return a cursor');\n normalizedPage = {\n kind: 'offset',\n limit: page.limit,\n offset: page.offset,\n hasMore: pageObject.hasMore,\n };\n } else {\n if (pageObject.offset !== undefined) {\n return fail('Cursor data query results cannot return an offset');\n }\n const nextCursor =\n pageObject.nextCursor === undefined\n ? undefined\n : stringValue(\n pageObject.nextCursor,\n 'Data query result next cursor',\n MAX_DATA_QUERY_CURSOR_LENGTH,\n );\n if (pageObject.hasMore !== Boolean(nextCursor)) {\n return fail('Data query cursor result hasMore must match nextCursor');\n }\n normalizedPage = {\n kind: 'cursor',\n limit: page.limit,\n hasMore: pageObject.hasMore,\n ...(nextCursor === undefined ? {} : { nextCursor }),\n };\n }\n } else if (object.page !== undefined) {\n return fail(`${request.mode} data query results cannot return a page`);\n }\n const total = normalizeTotal(object.total);\n const freshness = normalizeFreshness(object.freshness);\n if (\n !Array.isArray(object.warnings) ||\n object.warnings.length > MAX_DATA_QUERY_WARNINGS ||\n object.warnings.some(\n (warning) =>\n typeof warning !== 'string' ||\n warning.length === 0 ||\n warning.length > 512,\n )\n ) {\n return fail('Data query result warnings must be at most 100 short strings');\n }\n if (typeof object.truncated !== 'boolean')\n return fail('Data query result truncated must be boolean');\n const facets =\n request.mode === 'facets'\n ? normalizeFacetsResult(\n object.facets,\n request.facets ?? [],\n fields,\n budget,\n )\n : object.facets === undefined\n ? undefined\n : fail(`${request.mode} data query results cannot return facets`);\n const normalized: DataQueryResult = {\n version: 1,\n requestId: request.requestId,\n queryFingerprint: fingerprint,\n identityField: schema.identityField,\n rows,\n ...(normalizedPage === undefined ? {} : { page: normalizedPage }),\n total,\n ...(facets === undefined ? {} : { facets }),\n freshness,\n warnings: [...new Set(object.warnings)].sort(),\n truncated: object.truncated,\n };\n const bytes = new TextEncoder().encode(JSON.stringify(normalized)).byteLength;\n if (bytes > (schema.maxResultBytes ?? DEFAULT_DATA_QUERY_RESULT_BYTES)) {\n return fail(\n 'Data query result exceeds its maximum byte limit',\n 'DATA_QUERY_RESULT_TOO_LARGE',\n );\n }\n return normalized;\n}\n"],"mappings":"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"}
@@ -90,6 +90,13 @@ export declare function classifyDatabaseError(error: unknown): DatabaseErrorClas
90
90
  export declare function isDeterministicDatabaseError(error: unknown): boolean;
91
91
  /** True when the failure is contention or availability and may clear. */
92
92
  export declare function isTransientDatabaseError(error: unknown): boolean;
93
+ /**
94
+ * True when the failure is a transient *connection* failure: the database
95
+ * dropped, refused or could not yet accept the connection (#3657). Narrower
96
+ * than {@link isTransientDatabaseError}, which also covers contention
97
+ * (deadlocks, serialization, locks). Used to retry startup bootstrap only.
98
+ */
99
+ export declare function isTransientConnectionError(error: unknown): boolean;
93
100
  /** True when a unique or primary-key constraint was violated. */
94
101
  export declare function isUniqueViolationError(error: unknown): boolean;
95
102
  /** True when a NOT NULL constraint was violated. */
@@ -1 +1 @@
1
- {"version":3,"file":"db-errors.d.ts","sourceRoot":"","sources":["../src/db-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,0DAA0D;AAC1D,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB,oBAAoB,GACpB,uBAAuB,GACvB,iBAAiB,GACjB,qBAAqB,GACrB,eAAe,GACf,qBAAqB,GACrB,kBAAkB,GAClB,wBAAwB,GACxB,cAAc,GACd,WAAW,GACX,SAAS,CAAC;AAEd,0DAA0D;AAC1D,MAAM,WAAW,2BAA2B;IAC1C,yEAAyE;IACzE,IAAI,EAAE,iBAAiB,CAAC;IACxB,oDAAoD;IACpD,aAAa,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,SAAS,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B;;;;;OAKG;IACH,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAgWD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAMzE;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,GACb,2BAA2B,CA6G7B;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpE;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEhE;AAED,iEAAiE;AACjE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE9D;AAED,oDAAoD;AACpD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE/D;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAWjE"}
1
+ {"version":3,"file":"db-errors.d.ts","sourceRoot":"","sources":["../src/db-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,0DAA0D;AAC1D,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB,oBAAoB,GACpB,uBAAuB,GACvB,iBAAiB,GACjB,qBAAqB,GACrB,eAAe,GACf,qBAAqB,GACrB,kBAAkB,GAClB,wBAAwB,GACxB,cAAc,GACd,WAAW,GACX,SAAS,CAAC;AAEd,0DAA0D;AAC1D,MAAM,WAAW,2BAA2B;IAC1C,yEAAyE;IACzE,IAAI,EAAE,iBAAiB,CAAC;IACxB,oDAAoD;IACpD,aAAa,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,SAAS,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B;;;;;OAKG;IACH,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAgWD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAMzE;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,GACb,2BAA2B,CA6G7B;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpE;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEhE;AAqBD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAclE;AAED,iEAAiE;AACjE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE9D;AAED,oDAAoD;AACpD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE/D;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAWjE"}
package/dist/db-errors.js CHANGED
@@ -356,6 +356,39 @@ function isDeterministicDatabaseError(error) {
356
356
  function isTransientDatabaseError(error) {
357
357
  return classifyDatabaseError(error).retryable;
358
358
  }
359
+ /**
360
+ * Codes that mean the connection itself failed or the server would not take
361
+ * it yet: SQLSTATE class `08`, server shutdown/startup `57P01`–`57P03`,
362
+ * `53300 too_many_connections`, and the socket codes a server that is still
363
+ * starting or settling produces. Deliberately narrower than
364
+ * `TRANSIENT_NETWORK_CODES`: an unresolvable or unreachable host
365
+ * (`ENOTFOUND`, `EHOSTUNREACH`, `ENETUNREACH`) is a configuration error and
366
+ * must fail at once (#3657).
367
+ */
368
+ var CONNECTION_SQLSTATES = /* @__PURE__ */ new Set([
369
+ "53300",
370
+ "57P01",
371
+ "57P02",
372
+ "57P03"
373
+ ]);
374
+ var CONNECTION_SOCKET_CODES = /* @__PURE__ */ new Set([
375
+ "ECONNREFUSED",
376
+ "ECONNRESET",
377
+ "ETIMEDOUT",
378
+ "EAI_AGAIN"
379
+ ]);
380
+ var CONNECTION_MESSAGE = /connection terminated|server closed the connection|too many clients|the database system is (?:starting up|shutting down|in recovery mode)/i;
381
+ /**
382
+ * True when the failure is a transient *connection* failure: the database
383
+ * dropped, refused or could not yet accept the connection (#3657). Narrower
384
+ * than {@link isTransientDatabaseError}, which also covers contention
385
+ * (deadlocks, serialization, locks). Used to retry startup bootstrap only.
386
+ */
387
+ function isTransientConnectionError(error) {
388
+ const classification = classifyDatabaseError(error);
389
+ if (classification.deterministic) return false;
390
+ return classification.driverCodes.some((code) => CONNECTION_SQLSTATES.has(code) || CONNECTION_SOCKET_CODES.has(code) || /^08[0-9A-Z]{3}$/.test(code)) || classification.driverMessages.some((message) => CONNECTION_MESSAGE.test(message));
391
+ }
359
392
  /** True when a unique or primary-key constraint was violated. */
360
393
  function isUniqueViolationError(error) {
361
394
  return classifyDatabaseError(error).kind === "unique_violation";
@@ -377,6 +410,6 @@ function isAbortedTransactionError(error) {
377
410
  return signals.messages.some((message) => /current transaction is aborted/i.test(message));
378
411
  }
379
412
  //#endregion
380
- export { classifyDatabaseError, classifyDialectMessage, isAbortedTransactionError, isDeterministicDatabaseError, isNotNullViolationError, isTransientDatabaseError, isUniqueViolationError };
413
+ export { classifyDatabaseError, classifyDialectMessage, isAbortedTransactionError, isDeterministicDatabaseError, isNotNullViolationError, isTransientConnectionError, isTransientDatabaseError, isUniqueViolationError };
381
414
 
382
415
  //# sourceMappingURL=db-errors.js.map