@querykitjs/core 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-VD7XT52J.cjs → chunk-72KNINHB.cjs} +48 -2
- package/dist/chunk-72KNINHB.cjs.map +1 -0
- package/dist/{chunk-NHNDPIPM.js → chunk-XEETYJA3.js} +47 -3
- package/dist/chunk-XEETYJA3.js.map +1 -0
- package/dist/index.cjs +25 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -46
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +160 -10
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +138 -11
- package/dist/internal.d.ts +138 -11
- package/dist/internal.js +148 -5
- package/dist/internal.js.map +1 -1
- package/dist/{raw-Bx8c-TrC.d.cts → raw-AiElbDzC.d.cts} +2 -2
- package/dist/{raw-Bx8c-TrC.d.ts → raw-AiElbDzC.d.ts} +2 -2
- package/package.json +1 -1
- package/dist/chunk-NHNDPIPM.js.map +0 -1
- package/dist/chunk-VD7XT52J.cjs.map +0 -1
package/dist/internal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/cursor.ts","../src/internal/diagnostics.ts","../src/internal/context.ts","../src/internal/sort.ts","../src/internal/pagination.ts","../src/internal/mutation.ts","../src/internal/scope.ts","../src/internal/with.ts","../src/internal/limits.ts","../src/internal/policy.ts"],"names":["isPlainObject","isRecord"],"mappings":"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","file":"internal.js","sourcesContent":["/**\n * Opaque cursor tokens for keyset pagination, shared by every adapter so a token\n * is interchangeable between them. A token is the base64url encoding of\n * `{ v: <cursor value> }`; dates travel as ISO strings.\n */\n\nimport { QueryKitError } from \"../errors\";\n\ninterface CursorPayload {\n v: unknown;\n}\n\nexport function encodeCursor(value: unknown): string {\n const normalized = value instanceof Date ? value.toISOString() : value;\n const json = JSON.stringify({ v: normalized } satisfies CursorPayload);\n return Buffer.from(json, \"utf8\").toString(\"base64url\");\n}\n\n/** The cursor value, or `undefined` for a missing or undecodable token. */\nexport function decodeCursor(cursor?: string | null): unknown | undefined {\n if (!cursor) return undefined;\n try {\n const json = Buffer.from(cursor, \"base64url\").toString(\"utf8\");\n const payload = JSON.parse(json) as CursorPayload;\n return payload.v;\n } catch {\n return undefined;\n }\n}\n\n/* ------------------------------- token v2 -------------------------------- */\n/* Task 012: `{ v: 2, k, id, s? }` — the cursor key's value and the primary key\n * (tie-break), both scalars; `s` is an HMAC-SHA256 signature when the registry\n * has a `cursorSecret`. Anything else is invalid-value on site cursorKey. */\n\nexport interface CursorToken {\n k: string | number | boolean;\n id: string | number | boolean;\n}\n\nconst isScalar = (value: unknown): value is CursorToken[\"k\"] =>\n typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value));\n\nconst scalarOf = (value: unknown): CursorToken[\"k\"] | undefined => {\n // A Date becomes its ISO string; a driver id (a Mongo ObjectId) its own JSON form (hex).\n const normalized =\n value instanceof Date\n ? value.toISOString()\n : typeof value === \"object\" && value !== null && typeof (value as { toJSON?: unknown }).toJSON === \"function\"\n ? (value as { toJSON: () => unknown }).toJSON()\n : value;\n return isScalar(normalized) ? normalized : undefined;\n};\n\nasync function sign(body: string, secret: string): Promise<string> {\n const encoder = new TextEncoder();\n const key = await crypto.subtle.importKey(\"raw\", encoder.encode(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n const signature = await crypto.subtle.sign(\"HMAC\", key, encoder.encode(body));\n return Buffer.from(signature).toString(\"base64url\");\n}\n\n/** Constant-time compare, so a forged signature cannot be found byte by byte. */\nfunction sameSignature(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let index = 0; index < a.length; index++) diff |= a.charCodeAt(index) ^ b.charCodeAt(index);\n return diff === 0;\n}\n\n/** A v2 token for a row's cursor value and primary key; signed when `secret` is given. */\nexport async function encodeCursorToken(payload: { k: unknown; id: unknown }, secret?: string): Promise<string> {\n const body = JSON.stringify({ v: 2, k: scalarOf(payload.k) ?? null, id: scalarOf(payload.id) ?? null });\n const signed = secret ? JSON.stringify({ ...JSON.parse(body), s: await sign(body, secret) }) : body;\n return Buffer.from(signed, \"utf8\").toString(\"base64url\");\n}\n\n/**\n * The `{ k, id }` of a v2 token, `undefined` for no token. A v1 token, a\n * non-scalar `k` / `id`, a missing or wrong signature (with `secret`) or\n * anything undecodable throws `QueryKitError` — invalid-value, site cursorKey,\n * `key` the cursor key in use (the same key as an adapter's cast error).\n */\nexport async function decodeCursorToken(\n token: string | null | undefined,\n options: { source: string; secret?: string; key?: string },\n): Promise<CursorToken | undefined> {\n if (!token) return undefined;\n const refuse = (): never => {\n throw new QueryKitError({ source: options.source, site: \"cursorKey\", key: options.key ?? \"cursor\", reason: \"invalid-value\" });\n };\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(Buffer.from(token, \"base64url\").toString(\"utf8\")) as Record<string, unknown>;\n } catch {\n return refuse();\n }\n if (typeof payload !== \"object\" || payload === null || payload.v !== 2 || !isScalar(payload.k) || !isScalar(payload.id)) return refuse();\n if (options.secret) {\n const body = JSON.stringify({ v: 2, k: payload.k, id: payload.id });\n if (typeof payload.s !== \"string\" || !sameSignature(payload.s, await sign(body, options.secret))) return refuse();\n }\n return { k: payload.k, id: payload.id };\n}\n","/**\n * Skip diagnostics shared by every adapter: a condition the adapter cannot apply\n * (unknown key, uncastable value) is reported through `onSkippedCondition`, or —\n * under `strict` — thrown as a `QueryKitError`, so all adapters fail the same way.\n */\nimport { QueryKitError } from \"../errors\";\nimport type { SkippedCondition } from \"../types\";\n\nexport interface Diagnostics {\n /** Table (drizzle), model (prisma, mongoose) — reported as `source`. */\n source: string;\n strict: boolean;\n onSkipped?: (info: SkippedCondition) => void;\n}\n\nexport function reportSkip(diag: Diagnostics | undefined, info: Omit<SkippedCondition, \"source\">): void {\n if (!diag) return;\n const full: SkippedCondition = { ...info, source: diag.source };\n if (diag.strict) throw new QueryKitError(full);\n diag.onSkipped?.(full);\n}\n","/**\n * Per-async-call repository context (the transaction executor or session), so a\n * repository called inside `registry.transaction(...)` joins the transaction\n * without threading it through every call. Each adapter supplies its own context\n * shape (`{ executor }` for SQL clients, `{ session }` for mongoose).\n *\n * `node:async_hooks` is loaded when a store is created (adapters, on the server),\n * not imported statically: the validators also import `@querykitjs/core/internal`\n * for the limit helpers, and a static import of a node built-in would stop a\n * browser bundle of `@querykitjs/zod` / `@querykitjs/class-validator` (task 016).\n */\nimport type { AsyncLocalStorage as AsyncLocalStorageType } from \"node:async_hooks\";\n\nexport interface ContextStore<TContext extends object> {\n get(): TContext | undefined;\n /** Run `fn` with `patch` merged over the current context. */\n run<T>(patch: TContext, fn: () => T): T;\n}\n\n/** Node ≥ 22.3 and Bun (`engines` ≥ 22.12); anywhere else the adapter cannot start. */\nfunction loadAsyncLocalStorage(): typeof AsyncLocalStorageType {\n const asyncHooks =\n typeof process !== \"undefined\" && typeof process.getBuiltinModule === \"function\" ? process.getBuiltinModule(\"node:async_hooks\") : undefined;\n if (!asyncHooks?.AsyncLocalStorage)\n throw new Error(\"querykit: the repository context needs node:async_hooks (Node >= 22.12 or Bun) — a querykit adapter cannot run in this runtime\");\n return asyncHooks.AsyncLocalStorage;\n}\n\nexport function createContextStore<TContext extends object>(): ContextStore<TContext> {\n const AsyncLocalStorage = loadAsyncLocalStorage();\n const als = new AsyncLocalStorage<TContext>();\n return {\n get: () => als.getStore(),\n run: (patch, fn) => als.run({ ...als.getStore(), ...patch }, fn),\n };\n}\n","import type { Sort, SortDirection } from \"../types\";\n\nimport { reportSkip, type Diagnostics } from \"./diagnostics\";\n\nexport interface NormalizedSortItem {\n key: string;\n direction: SortDirection;\n}\n\n/**\n * The wire `sort` array with a direction on every item. An item without a `key`\n * (`null`, `{}`) is dropped — sort comes from the client, and a malformed item\n * must not crash the query — and, with `diag`, reported as `invalid-value` on\n * `site: \"sort\"` (a `QueryKitError` under strict; task 021 B14).\n */\nexport function normalizeSort(sort?: Sort, diag?: Diagnostics): NormalizedSortItem[] {\n if (!sort) return [];\n const items: NormalizedSortItem[] = [];\n for (const item of sort) {\n if (item && typeof item.key === \"string\" && item.key) items.push({ key: item.key, direction: item.direction ?? \"asc\" });\n else reportSkip(diag, { site: \"sort\", key: \"\", reason: \"invalid-value\" });\n }\n return items;\n}\n","/**\n * Page-size clamping and the three pagination metas, computed once for every\n * adapter so `total_pages`, `has_more`, `next_cursor` … mean the same thing on\n * all of them. Adapters only fetch rows; these functions turn rows into a page.\n */\nimport type { CursorMeta, InfiniteMeta, OffsetMeta } from \"../types\";\n\nimport { encodeCursorToken } from \"./cursor\";\n\n/** A requested page size, defaulted, truncated, at least 1 and at most `max`. */\nexport function clampPageSize(requested: number | undefined, fallback: number, max: number): number {\n return Math.min(max, Math.max(1, Math.trunc(requested ?? fallback)));\n}\n\n/** A requested page number: an integer, at least 1. */\nexport function clampPage(requested: number | undefined): number {\n return Math.max(1, Math.trunc(requested ?? 1));\n}\n\n/** A requested offset: an integer, at least 0. */\nexport function clampOffset(requested: number | undefined): number {\n return Math.max(0, Math.trunc(requested ?? 0));\n}\n\nexport function offsetMeta(page: number, perPage: number, totalItems: number): OffsetMeta {\n const totalPages = Math.ceil(totalItems / perPage);\n return {\n total_items: totalItems,\n total_pages: totalPages,\n current_page: page,\n per_page: perPage,\n has_next: page < totalPages,\n has_prev: page > 1,\n };\n}\n\n/**\n * `withTotal: false` (task 013): rows fetched with `perPage + 1` and no count →\n * the page and its meta; the extra row only signals `has_next`, totals are `null`.\n */\nexport function offsetPageWithoutTotal<T>(rows: readonly T[], page: number, perPage: number): { data: T[]; meta: OffsetMeta } {\n const hasNext = rows.length > perPage;\n return {\n data: hasNext ? rows.slice(0, perPage) : [...rows],\n meta: { total_items: null, total_pages: null, current_page: page, per_page: perPage, has_next: hasNext, has_prev: page > 1 },\n };\n}\n\n/** Rows fetched with `limit + 1` → the page and its meta (the extra row only signals `has_more`). */\nexport function infinitePage<T>(rows: readonly T[], limit: number, offset: number): { data: T[]; meta: InfiniteMeta } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : [...rows];\n return {\n data,\n meta: { limit, offset, count: data.length, has_more: hasMore, next_offset: hasMore ? offset + limit : null },\n };\n}\n\nexport interface CursorPageOptions {\n limit: number;\n direction: \"forward\" | \"backward\";\n /** A cursor was supplied (the request continues from a previous page). */\n hasCursor: boolean;\n /** The row field the tokens are read from. */\n cursorField: string;\n /** The primary-key field — the tie-break value in every token (task 012). */\n idField: string;\n /** Signs the tokens (registry `cursorSecret`). */\n secret?: string;\n}\n\n/**\n * Rows fetched with `limit + 1` in query order → the page in display order and\n * its meta. A backward page is fetched reversed and flipped back here.\n */\nexport async function cursorPage<T extends Record<string, unknown>>(rows: readonly T[], options: CursorPageOptions): Promise<{ data: T[]; meta: CursorMeta }> {\n const { limit, direction, hasCursor, cursorField, idField, secret } = options;\n const hasExtra = rows.length > limit;\n let data = hasExtra ? rows.slice(0, limit) : [...rows];\n if (direction === \"backward\") data = data.reverse();\n\n const first = data[0];\n const last = data[data.length - 1];\n const hasNext = direction === \"forward\" ? hasExtra : hasCursor;\n const hasPrev = direction === \"forward\" ? hasCursor : hasExtra;\n\n return {\n data,\n meta: {\n limit,\n has_next: hasNext,\n has_prev: hasPrev,\n next_cursor: hasNext && last ? await encodeCursorToken({ k: last[cursorField], id: last[idField] }, secret) : null,\n prev_cursor: hasPrev && first ? await encodeCursorToken({ k: first[cursorField], id: first[idField] }, secret) : null,\n },\n };\n}\n","/**\n * Bulk-mutation guards shared by every adapter (task 013): a filterless\n * `updateWhere` / `deleteWhere` runs only on an explicit `{ all: true }`.\n */\nimport { QueryKitError } from \"../errors\";\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;\n\n/** `{ all: true }` — and nothing else — asks for every row (the scope still applies). */\nexport function isAllRows(filter: unknown): boolean {\n return isPlainObject(filter) && filter.all === true && Object.keys(filter).length === 1;\n}\n\n/** `undefined`, `null`, `[]` or `{}`: no condition at all. */\nexport function isEmptyFilter(filter: unknown): boolean {\n return (\n filter === undefined || filter === null || (Array.isArray(filter) && filter.length === 0) || (isPlainObject(filter) && Object.keys(filter).length === 0)\n );\n}\n\n/** A mutation without a condition — also one whose every condition was skipped. */\nexport function refuseEmptyFilter(source: string, method: \"updateWhere\" | \"deleteWhere\"): never {\n throw new QueryKitError({ source, site: \"mutation\", key: method, reason: \"empty-filter\" });\n}\n","/**\n * A repository `scope` (the server's RBAC / tenancy filter) split once for every\n * adapter (task 014): equality values and `{ in: [...] }` lists.\n */\n\n/** One scope condition, in the shape every adapter's `buildWhere` reads. */\nexport interface ScopeCondition {\n key: string;\n operation: \"=\" | \"in\";\n value: unknown;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;\n\n/** `{ in: [...] }` — and nothing else — is a list scope; any other value is equality (as before). */\nconst isInScope = (value: unknown): value is { in: readonly unknown[] } => isPlainObject(value) && Object.keys(value).length === 1 && Array.isArray(value.in);\n\n/** The scope as conditions: `{ k: v }` → `k = v`, `{ k: { in: [...] } }` → `k in [...]`. */\nexport function scopeConditions(scope: Record<string, unknown> | undefined): ScopeCondition[] {\n return Object.entries(scope ?? {}).map(([key, value]) =>\n isInScope(value) ? { key, operation: \"in\", value: [...value.in] } : { key, operation: \"=\", value },\n );\n}\n\n/** The values `create` / `upsert` fill in: the equality scopes only (a list has no single value). */\nexport function scopeDefaults(scope: Record<string, unknown> | undefined): Record<string, unknown> {\n return Object.fromEntries(Object.entries(scope ?? {}).filter(([, value]) => !isInScope(value)));\n}\n","/**\n * The client's `with` against the repository's `relations` allow-list (task 014, R21),\n * one walker for every adapter. Each adapter names its own option keys (a \"dialect\");\n * the rules are the same: an unlisted relation, column, filter field, nested relation\n * or option is `QueryKitError` `forbidden-key`, `site: \"with\"`, before the driver runs.\n */\nimport { QueryKitError } from \"../errors\";\nimport type { RelationRule, Relations } from \"../types\";\n\n/** How one adapter spells a relation's options. */\nexport interface WithDialect {\n /** Column selection: drizzle `columns`, prisma / mongoose `select`. */\n columns: string;\n /** Nested relations: drizzle `with`, prisma `include`, mongoose `populate`. */\n nested: string;\n /** Row filters: prisma `where`, mongoose `match`; drizzle none (its `where` is code, not JSON). */\n filters: readonly string[];\n /** Logical keys inside a filter, walked into: prisma `AND` / `OR` / `NOT`, mongoose `$and` / `$or` / `$nor`. */\n logical: readonly string[];\n /** Options that only page: drizzle `limit` / `offset`, prisma `take` / `skip`, mongoose `options.limit` / `options.skip`. */\n paging: readonly string[];\n /** A sort whose keys must be allowed columns: prisma `orderBy`. */\n orderBy?: string;\n /** An options bag whose keys must be `paging` keys: mongoose `options`. */\n options?: string;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;\n\n/** A rule that opens a relation: an object with `columns` (a list or `\"*\"`). A bare model (mongoose shorthand) does not. */\nconst ruleOf = (relations: Relations | undefined, name: string): RelationRule | undefined => {\n const rule = relations && Object.prototype.hasOwnProperty.call(relations, name) ? (relations as Record<string, unknown>)[name] : undefined;\n return isPlainObject(rule) && (rule.columns === \"*\" || Array.isArray(rule.columns)) ? (rule as unknown as RelationRule) : undefined;\n};\n\n/** Keys named by a selection: `{ a: true, b: 1 }` or mongoose's `\"a b -c\"`. */\nconst selectedKeys = (selection: unknown): string[] | undefined => {\n if (typeof selection === \"string\") return selection.split(/\\s+/).filter(Boolean);\n if (isPlainObject(selection)) return Object.keys(selection).filter(key => Boolean(selection[key]));\n return undefined;\n};\n\n/**\n * The checked `with`: every relation in `relations`, every selected column in its\n * `columns`, every filter field in its `filterable`, every nested relation in its\n * `nested`. A relation asked for with `true` (or without a selection) gets its\n * listed columns selected, so a column list is never widened to the full row.\n */\nexport function checkWith(\n withValue: unknown,\n relations: Relations | undefined,\n dialect: WithDialect,\n source: string,\n path = \"\",\n): Record<string, unknown> | undefined {\n if (withValue === undefined || withValue === null) return undefined;\n const refuse = (key: string): never => {\n throw new QueryKitError({ source, site: \"with\", key: path + key, reason: \"forbidden-key\" });\n };\n if (!isPlainObject(withValue)) return refuse(\"with\");\n\n const checked: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(withValue)) {\n if (value === false || value === undefined) continue;\n const rule = ruleOf(relations, name) ?? refuse(name);\n const listed = rule.columns === \"*\" ? undefined : new Set(rule.columns);\n const selectListed = () => Object.fromEntries([...listed!].map(column => [column, true]));\n if (value === true) {\n checked[name] = listed ? { [dialect.columns]: selectListed() } : true;\n continue;\n }\n if (!isPlainObject(value)) refuse(name);\n const options = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const [key, option] of Object.entries(options)) {\n const at = `${name}.${key}`;\n if (key === dialect.columns) {\n const keys = selectedKeys(option) ?? refuse(at);\n // An exclusion (\"-secret\") selects every other column: only with \"*\".\n for (const column of keys) if (listed && (column.startsWith(\"-\") || !listed.has(column))) refuse(`${name}.${column}`);\n out[key] = option;\n } else if (key === dialect.nested) {\n out[key] = checkWith(option, rule.nested, dialect, source, `${name}.`);\n } else if (dialect.filters.includes(key)) {\n checkFilterFields(option, rule, dialect, (field: string) => refuse(`${name}.${field}`));\n out[key] = option;\n } else if (dialect.paging.includes(key)) {\n out[key] = option;\n } else if (key === dialect.orderBy) {\n for (const item of Array.isArray(option) ? option : [option]) {\n for (const column of selectedKeys(item) ?? refuse(at)) if (listed && !listed.has(column)) refuse(`${name}.${column}`);\n }\n out[key] = option;\n } else if (key === dialect.options) {\n for (const sub of Object.keys(isPlainObject(option) ? option : refuse(at))) if (!dialect.paging.includes(sub)) refuse(`${at}.${sub}`);\n out[key] = option;\n } else {\n refuse(at);\n }\n }\n if (listed && out[dialect.columns] === undefined) out[dialect.columns] = selectListed();\n checked[name] = out;\n }\n return checked;\n}\n\n/** Every field of a relation filter (through the logical keys) must be in `filterable`. */\nfunction checkFilterFields(filter: unknown, rule: RelationRule, dialect: WithDialect, refuse: (field: string) => never): void {\n if (!isPlainObject(filter)) refuse(\"filter\");\n for (const [key, value] of Object.entries(filter as Record<string, unknown>)) {\n if (dialect.logical.includes(key)) {\n for (const part of Array.isArray(value) ? value : [value]) checkFilterFields(part, rule, dialect, refuse);\n } else if (key.startsWith(\"$\") || !rule.filterable || rule.filterable[key] === undefined) {\n // `$where`, `$expr` and any field outside the allow-list.\n refuse(key);\n }\n }\n}\n","/**\n * The filter-limit walk shared by the validators (task 008). It runs on the raw,\n * unvalidated payload **before** any recursive schema sees it, so it is\n * iterative — no recursion at all, whatever the payload's depth — and a\n * 10 000-level `not` chain is rejected after `maxDepth + 1` steps.\n *\n * Only size is judged here. Shape errors (a missing `key`, a bad operator) are\n * the validator's job — a malformed node is skipped, not reported.\n */\nimport { DEFAULT_PER_PAGE, type QueryLimits } from \"../defaults\";\n\n/** Where in the filter a limit was crossed — object keys and array indexes, from the root. */\nexport type LimitPath = (string | number)[];\n\nexport interface LimitViolation {\n limit: keyof QueryLimits;\n max: number;\n path: LimitPath;\n}\n\n/** The limits the walk checks. */\nexport type FilterLimits = Pick<QueryLimits, \"maxDepth\" | \"maxConditions\" | \"maxInItems\" | \"maxStringLength\">;\n\n/** A node still to visit: the node, its level (the root is 1) and its path. */\ntype Pending = [node: unknown, depth: number, path: LimitPath];\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** `maxInItems (200)` — the form every package's error text uses. */\nexport const formatLimit = (limit: keyof QueryLimits, max: number): string => `${limit} (${max})`;\n\n/**\n * The first limit the filter crosses, depth-first in document order, or\n * `undefined` when it is within all four. A flat array (implicit AND) puts its\n * conditions at level 1. Key order mirrors the validators: `key` first, then\n * `and`, `or`, `not`.\n */\nexport function findFilterLimitViolation(filter: unknown, limits: FilterLimits): LimitViolation | undefined {\n const hit = (limit: keyof FilterLimits, path: LimitPath): LimitViolation => ({ limit, max: limits[limit], path });\n const pending: Pending[] = [];\n /* Children go on the stack last-first, so they pop in document order. */\n const push = (children: readonly unknown[], depth: number, path: LimitPath) => {\n for (let index = children.length - 1; index >= 0; index--) pending.push([children[index], depth, [...path, index]]);\n };\n if (Array.isArray(filter)) push(filter, 1, []);\n else if (filter !== undefined) pending.push([filter, 1, []]);\n\n let conditions = 0;\n for (let next = pending.pop(); next; next = pending.pop()) {\n const [node, depth, path] = next;\n if (depth > limits.maxDepth) return hit(\"maxDepth\", path);\n if (!isRecord(node)) continue;\n\n if (\"key\" in node) {\n if (++conditions > limits.maxConditions) return hit(\"maxConditions\", path);\n const { value } = node;\n const valuePath = [...path, \"value\"];\n if (Array.isArray(value) && value.length > limits.maxInItems) return hit(\"maxInItems\", valuePath);\n const items: unknown[] = Array.isArray(value) ? value : [value];\n const tooLong = items.findIndex(item => typeof item === \"string\" && item.length > limits.maxStringLength);\n if (tooLong >= 0) return hit(\"maxStringLength\", Array.isArray(value) ? [...valuePath, tooLong] : valuePath);\n continue;\n }\n\n const group = \"and\" in node ? \"and\" : \"or\" in node ? \"or\" : undefined;\n if (group) {\n const children = node[group];\n if (Array.isArray(children)) push(children, depth + 1, [...path, group]);\n } else if (\"not\" in node) pending.push([node.not, depth + 1, [...path, \"not\"]]);\n }\n return undefined;\n}\n\nconst LIKE_OPERATORS: ReadonlySet<string> = new Set([\"like\", \"ilike\", \"notLike\"]);\n\n/** Whether an operator takes a SQL LIKE pattern. */\nexport const isLikeOperator = (operation: string): boolean => LIKE_OPERATORS.has(operation);\n\n/**\n * Unescaped wildcards in a LIKE pattern, a run of `%` counted once (`%%a%` ⇒ 2).\n * A backslash escapes the next character, as in the adapters' LIKE translation.\n */\nexport function likeWildcards(pattern: string): number {\n let count = 0;\n let previous = \"\";\n for (let index = 0; index < pattern.length; index++) {\n const char = pattern[index]!;\n if (char === \"\\\\\") {\n index++;\n previous = \"\";\n continue;\n }\n if (char === \"_\" || (char === \"%\" && previous !== \"%\")) count++;\n previous = char;\n }\n return count;\n}\n\n/** Rows an offset-paginated request skips: `(page - 1) × perPage`, with the core default page size. */\nexport const offsetOf = (page: number | undefined, perPage: number | undefined): number => ((page ?? 1) - 1) * (perPage ?? DEFAULT_PER_PAGE);\n","/**\n * The server-side request policy every adapter applies (task 009): which fields\n * a client may filter by and with which operators (`filterable`), which it may\n * sort and page by (`sortable`), and the request limits (`limits`, task 008).\n *\n * A plain object that is not a condition, a group, a branded `raw()` node or a\n * driver-native object (`isNative`) is refused as well (R19): it would otherwise\n * reach the driver as its own `where`, past `filterable`.\n *\n * A refused request never reaches the driver and is never dropped silently:\n * every check throws `QueryKitError`, whatever `strict` / `onSkippedCondition`\n * say. A key the model does not have is **not** the policy's business — it goes\n * on to the adapter's own `unknown-key` handling, unchanged.\n */\nimport { resolveLimits, type QueryLimits } from \"../defaults\";\nimport { QueryKitError } from \"../errors\";\nimport type { Filterable, SkipReason, SkipSite } from \"../types\";\nimport { isRaw } from \"../raw\";\nimport { findFilterLimitViolation, isLikeOperator, likeWildcards, offsetOf } from \"./limits\";\n\nexport interface PolicyOptions {\n /** Table / model name for the error. */\n source: string;\n /** Wire key → the model's canonical field name, or `undefined` when the model has no such field. */\n fieldOf: (key: string) => string | undefined;\n /** Canonical primary-key field — the last-resort safe default. */\n primaryKey: string;\n /** Canonical `createdAt` field when the model has one (default `sortable`). */\n createdAt?: string;\n filterable?: Filterable;\n sortable?: readonly string[];\n allowedColumns?: readonly string[];\n forcedColumns?: Readonly<Record<string, unknown>>;\n limits?: Partial<QueryLimits>;\n /**\n * A driver object that cannot come from JSON and stands for itself (drizzle `SQL`).\n * Anything else that is not a condition, a group or a {@link isRaw} node is refused (R19).\n */\n isNative?: (node: object) => boolean;\n}\n\nexport interface Policy {\n readonly limits: QueryLimits;\n /** Limits, then every condition's field and operator. */\n checkFilter(filter: unknown): void;\n /** Field count, then every sort field. */\n checkSort(sort: readonly { key?: unknown }[] | undefined): void;\n checkCursorKey(key: string): void;\n /** Offset pagination: the clamped `page` × `perPage`. Infinite: the clamped `offset`. */\n checkPage(page: { page: number; perPage: number } | { offset: number }): void;\n /** A `groupBy` / `sum` / `avg` / `min` / `max` field must be filterable. */\n checkAggregateKey(key: string): void;\n}\n\n/** The safe default when `filterable` is not given: equality only. */\nconst DEFAULT_OPERATORS = [\"=\", \"in\"] as const;\n\n/** Alias → the token it means, so `[\"=\"]` also admits `eq` and `[\"contains\"]` admits `%_%`. */\nconst OPERATOR_TOKEN: Readonly<Record<string, string>> = {\n eq: \"=\",\n ne: \"!=\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n contains: \"%_%\",\n startsWith: \"%_\",\n endsWith: \"_%\",\n};\nconst tokenOf = (operation: string): string => OPERATOR_TOKEN[operation] ?? operation;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** Field → admitted operator tokens, or `\"*\"`. */\ntype Rules = ReadonlyMap<string, ReadonlySet<string> | \"*\">;\n\nfunction filterRules(options: PolicyOptions, canonical: (key: string) => string): Rules {\n const rules = new Map<string, ReadonlySet<string> | \"*\">();\n if (options.filterable) {\n for (const [key, operators] of Object.entries(options.filterable)) {\n if (operators) rules.set(canonical(key), operators === \"*\" ? \"*\" : new Set(operators.map(tokenOf)));\n }\n return rules;\n }\n const fields =\n options.allowedColumns ?? (options.forcedColumns ? Object.keys(options.forcedColumns).filter(key => options.forcedColumns![key]) : [options.primaryKey]);\n const equality = new Set<string>(DEFAULT_OPERATORS);\n for (const field of fields) rules.set(canonical(field), equality);\n return rules;\n}\n\nexport function resolvePolicy(options: PolicyOptions): Policy {\n const limits = resolveLimits(options.limits);\n const canonical = (key: string) => options.fieldOf(key) ?? key;\n const rules = filterRules(options, canonical);\n const sortable = new Set((options.sortable ?? [options.primaryKey, ...(options.createdAt ? [options.createdAt] : [])]).map(canonical));\n\n const refuse = (site: SkipSite, key: string, reason: SkipReason, operation?: string): never => {\n throw new QueryKitError({ source: options.source, site, key, reason, ...(operation ? { operation: operation as never } : {}) });\n };\n\n const checkCondition = (node: Record<string, unknown>): void => {\n const key = String(node.key);\n const field = options.fieldOf(key);\n if (field === undefined) return; // not in the model — the adapter's unknown-key path\n const operation = typeof node.operation === \"string\" ? node.operation : \"=\";\n const rule = rules.get(field);\n if (!rule) refuse(\"filter\", key, \"forbidden-key\", operation);\n if (rule !== \"*\" && !rule!.has(tokenOf(operation))) refuse(\"filter\", key, \"forbidden-operator\", operation);\n if (isLikeOperator(operation) && typeof node.value === \"string\" && likeWildcards(node.value) > limits.maxLikeWildcards) {\n refuse(\"filter\", \"maxLikeWildcards\", \"limit-exceeded\", operation);\n }\n };\n\n const checkSortKey = (site: SkipSite, key: string): void => {\n const field = options.fieldOf(key);\n if (field !== undefined && !sortable.has(field)) refuse(site, key, \"forbidden-key\");\n };\n\n return {\n limits,\n\n checkFilter(filter) {\n const violation = findFilterLimitViolation(filter, limits);\n if (violation) refuse(\"filter\", violation.limit, \"limit-exceeded\");\n /* Bounded by maxDepth now, but kept iterative so `maxDepth: Infinity` cannot overflow the stack. */\n const pending: unknown[] = Array.isArray(filter) ? [...filter] : [filter];\n while (pending.length > 0) {\n const node = pending.pop();\n if (!isRecord(node)) continue;\n if (\"key\" in node) checkCondition(node);\n else if (Array.isArray(node.and)) pending.push(...node.and);\n else if (Array.isArray(node.or)) pending.push(...node.or);\n else if (\"not\" in node) pending.push(node.not);\n // R19: a JSON body cannot brand a node, so an unbranded driver object is refused.\n else if (!isRaw(node) && !options.isNative?.(node)) refuse(\"filter\", Object.keys(node)[0] ?? \"\", \"forbidden-key\");\n }\n },\n\n checkSort(sort) {\n if (!sort) return;\n if (sort.length > limits.maxSortFields) refuse(\"sort\", \"maxSortFields\", \"limit-exceeded\");\n for (const item of sort) if (item && typeof item.key === \"string\" && item.key) checkSortKey(\"sort\", item.key);\n },\n\n checkCursorKey(key) {\n checkSortKey(\"cursorKey\", key);\n },\n\n checkPage(page) {\n const offset = \"offset\" in page ? page.offset : offsetOf(page.page, page.perPage);\n if (offset > limits.maxOffset) refuse(\"page\", \"maxOffset\", \"limit-exceeded\");\n },\n\n checkAggregateKey(key) {\n const field = options.fieldOf(key);\n if (field !== undefined && !rules.has(field)) refuse(\"aggregate\", key, \"forbidden-key\");\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/cursor.ts","../src/internal/diagnostics.ts","../src/internal/context.ts","../src/internal/sort.ts","../src/internal/pagination.ts","../src/internal/mutation.ts","../src/internal/scope.ts","../src/internal/with.ts","../src/internal/limits.ts","../src/internal/policy.ts","../src/internal/wire-checks.ts","../src/internal/messages.ts"],"names":["isPlainObject","isRecord","checkCondition","isScalar"],"mappings":"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","file":"internal.js","sourcesContent":["/**\n * Opaque cursor tokens for keyset pagination, shared by every adapter so a token\n * is interchangeable between them. A token is the base64url encoding of\n * `{ v: <cursor value> }`; dates travel as ISO strings.\n */\n\nimport { QueryKitError } from \"../errors\";\n\ninterface CursorPayload {\n v: unknown;\n}\n\nexport function encodeCursor(value: unknown): string {\n const normalized = value instanceof Date ? value.toISOString() : value;\n const json = JSON.stringify({ v: normalized } satisfies CursorPayload);\n return Buffer.from(json, \"utf8\").toString(\"base64url\");\n}\n\n/** The cursor value, or `undefined` for a missing or undecodable token. */\nexport function decodeCursor(cursor?: string | null): unknown | undefined {\n if (!cursor) return undefined;\n try {\n const json = Buffer.from(cursor, \"base64url\").toString(\"utf8\");\n const payload = JSON.parse(json) as CursorPayload;\n return payload.v;\n } catch {\n return undefined;\n }\n}\n\n/* ------------------------------- token v2 -------------------------------- */\n/* `{ v: 2, k, id, s? }` — the cursor key's value and the primary key\n * (tie-break), both scalars; `s` is an HMAC-SHA256 signature when the registry\n * has a `cursorSecret`. Anything else is invalid-value on site cursorKey. */\n\nexport interface CursorToken {\n k: string | number | boolean;\n id: string | number | boolean;\n}\n\nconst isScalar = (value: unknown): value is CursorToken[\"k\"] =>\n typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value));\n\nconst scalarOf = (value: unknown): CursorToken[\"k\"] | undefined => {\n // A Date becomes its ISO string; a driver id (a Mongo ObjectId) its own JSON form (hex).\n const normalized =\n value instanceof Date\n ? value.toISOString()\n : typeof value === \"object\" && value !== null && typeof (value as { toJSON?: unknown }).toJSON === \"function\"\n ? (value as { toJSON: () => unknown }).toJSON()\n : value;\n return isScalar(normalized) ? normalized : undefined;\n};\n\nasync function sign(body: string, secret: string): Promise<string> {\n const encoder = new TextEncoder();\n const key = await crypto.subtle.importKey(\"raw\", encoder.encode(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n const signature = await crypto.subtle.sign(\"HMAC\", key, encoder.encode(body));\n return Buffer.from(signature).toString(\"base64url\");\n}\n\n/** Constant-time compare, so a forged signature cannot be found byte by byte. */\nfunction sameSignature(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let index = 0; index < a.length; index++) diff |= a.charCodeAt(index) ^ b.charCodeAt(index);\n return diff === 0;\n}\n\n/** A v2 token for a row's cursor value and primary key; signed when `secret` is given. */\nexport async function encodeCursorToken(payload: { k: unknown; id: unknown }, secret?: string): Promise<string> {\n const body = JSON.stringify({ v: 2, k: scalarOf(payload.k) ?? null, id: scalarOf(payload.id) ?? null });\n const signed = secret ? JSON.stringify({ ...JSON.parse(body), s: await sign(body, secret) }) : body;\n return Buffer.from(signed, \"utf8\").toString(\"base64url\");\n}\n\n/**\n * The `{ k, id }` of a v2 token, `undefined` for no token. A v1 token, a\n * non-scalar `k` / `id`, a missing or wrong signature (with `secret`) or\n * anything undecodable throws `QueryKitError` — invalid-value, site cursorKey,\n * `key` the cursor key in use (the same key as an adapter's cast error).\n */\nexport async function decodeCursorToken(\n token: string | null | undefined,\n options: { source: string; secret?: string; key?: string },\n): Promise<CursorToken | undefined> {\n if (!token) return undefined;\n const refuse = (): never => {\n throw new QueryKitError({ source: options.source, site: \"cursorKey\", key: options.key ?? \"cursor\", reason: \"invalid-value\" });\n };\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(Buffer.from(token, \"base64url\").toString(\"utf8\")) as Record<string, unknown>;\n } catch {\n return refuse();\n }\n if (typeof payload !== \"object\" || payload === null || payload.v !== 2 || !isScalar(payload.k) || !isScalar(payload.id)) return refuse();\n if (options.secret) {\n const body = JSON.stringify({ v: 2, k: payload.k, id: payload.id });\n if (typeof payload.s !== \"string\" || !sameSignature(payload.s, await sign(body, options.secret))) return refuse();\n }\n return { k: payload.k, id: payload.id };\n}\n","/**\n * Skip diagnostics shared by every adapter: a condition the adapter cannot apply\n * (unknown key, uncastable value) is reported through `onSkippedCondition`, or —\n * under `strict` — thrown as a `QueryKitError`, so all adapters fail the same way.\n */\nimport { QueryKitError } from \"../errors\";\nimport type { SkippedCondition } from \"../types\";\n\nexport interface Diagnostics {\n /** Table (drizzle), model (prisma, mongoose) — reported as `source`. */\n source: string;\n strict: boolean;\n onSkipped?: (info: SkippedCondition) => void;\n}\n\nexport function reportSkip(diag: Diagnostics | undefined, info: Omit<SkippedCondition, \"source\">): void {\n if (!diag) return;\n const full: SkippedCondition = { ...info, source: diag.source };\n if (diag.strict) throw new QueryKitError(full);\n diag.onSkipped?.(full);\n}\n","/**\n * Per-async-call repository context (the transaction executor or session), so a\n * repository called inside `registry.transaction(...)` joins the transaction\n * without threading it through every call. Each adapter supplies its own context\n * shape (`{ executor }` for SQL clients, `{ session }` for mongoose).\n *\n * `node:async_hooks` is loaded when a store is created (adapters, on the server),\n * not imported statically: the validators also import `@querykitjs/core/internal`\n * for the limit helpers, and a static import of a node built-in would stop a\n * browser bundle of `@querykitjs/zod` / `@querykitjs/class-validator`.\n */\nimport type { AsyncLocalStorage as AsyncLocalStorageType } from \"node:async_hooks\";\n\nexport interface ContextStore<TContext extends object> {\n get(): TContext | undefined;\n /** Run `fn` with `patch` merged over the current context. */\n run<T>(patch: TContext, fn: () => T): T;\n}\n\n/** Node ≥ 22.3 and Bun (`engines` ≥ 22.12); anywhere else the adapter cannot start. */\nfunction loadAsyncLocalStorage(): typeof AsyncLocalStorageType {\n const asyncHooks =\n typeof process !== \"undefined\" && typeof process.getBuiltinModule === \"function\" ? process.getBuiltinModule(\"node:async_hooks\") : undefined;\n if (!asyncHooks?.AsyncLocalStorage)\n throw new Error(\"querykit: the repository context needs node:async_hooks (Node >= 22.12 or Bun) — a querykit adapter cannot run in this runtime\");\n return asyncHooks.AsyncLocalStorage;\n}\n\nexport function createContextStore<TContext extends object>(): ContextStore<TContext> {\n const AsyncLocalStorage = loadAsyncLocalStorage();\n const als = new AsyncLocalStorage<TContext>();\n return {\n get: () => als.getStore(),\n run: (patch, fn) => als.run({ ...als.getStore(), ...patch }, fn),\n };\n}\n","import type { Sort, SortDirection } from \"../types\";\n\nimport { reportSkip, type Diagnostics } from \"./diagnostics\";\n\nexport interface NormalizedSortItem {\n key: string;\n direction: SortDirection;\n}\n\n/**\n * The wire `sort` array with a direction on every item. An item without a `key`\n * (`null`, `{}`) is dropped — sort comes from the client, and a malformed item\n * must not crash the query — and, with `diag`, reported as `invalid-value` on\n * `site: \"sort\"` (a `QueryKitError` under strict).\n */\nexport function normalizeSort(sort?: Sort, diag?: Diagnostics): NormalizedSortItem[] {\n if (!sort) return [];\n const items: NormalizedSortItem[] = [];\n for (const item of sort) {\n if (item && typeof item.key === \"string\" && item.key) items.push({ key: item.key, direction: item.direction ?? \"asc\" });\n else reportSkip(diag, { site: \"sort\", key: \"\", reason: \"invalid-value\" });\n }\n return items;\n}\n","/**\n * Page-size clamping and the three pagination metas, computed once for every\n * adapter so `total_pages`, `has_more`, `next_cursor` … mean the same thing on\n * all of them. Adapters only fetch rows; these functions turn rows into a page.\n */\nimport type { CursorMeta, InfiniteMeta, OffsetMeta } from \"../types\";\n\nimport { encodeCursorToken } from \"./cursor\";\n\n/** A requested page size, defaulted, truncated, at least 1 and at most `max`. */\nexport function clampPageSize(requested: number | undefined, fallback: number, max: number): number {\n return Math.min(max, Math.max(1, Math.trunc(requested ?? fallback)));\n}\n\n/** A requested page number: an integer, at least 1. */\nexport function clampPage(requested: number | undefined): number {\n return Math.max(1, Math.trunc(requested ?? 1));\n}\n\n/** A requested offset: an integer, at least 0. */\nexport function clampOffset(requested: number | undefined): number {\n return Math.max(0, Math.trunc(requested ?? 0));\n}\n\nexport function offsetMeta(page: number, perPage: number, totalItems: number): OffsetMeta {\n const totalPages = Math.ceil(totalItems / perPage);\n return {\n total_items: totalItems,\n total_pages: totalPages,\n current_page: page,\n per_page: perPage,\n has_next: page < totalPages,\n has_prev: page > 1,\n };\n}\n\n/**\n * `withTotal: false`: rows fetched with `perPage + 1` and no count →\n * the page and its meta; the extra row only signals `has_next`, totals are `null`.\n */\nexport function offsetPageWithoutTotal<T>(rows: readonly T[], page: number, perPage: number): { data: T[]; meta: OffsetMeta } {\n const hasNext = rows.length > perPage;\n return {\n data: hasNext ? rows.slice(0, perPage) : [...rows],\n meta: { total_items: null, total_pages: null, current_page: page, per_page: perPage, has_next: hasNext, has_prev: page > 1 },\n };\n}\n\n/** Rows fetched with `limit + 1` → the page and its meta (the extra row only signals `has_more`). */\nexport function infinitePage<T>(rows: readonly T[], limit: number, offset: number): { data: T[]; meta: InfiniteMeta } {\n const hasMore = rows.length > limit;\n const data = hasMore ? rows.slice(0, limit) : [...rows];\n return {\n data,\n meta: { limit, offset, count: data.length, has_more: hasMore, next_offset: hasMore ? offset + limit : null },\n };\n}\n\nexport interface CursorPageOptions {\n limit: number;\n direction: \"forward\" | \"backward\";\n /** A cursor was supplied (the request continues from a previous page). */\n hasCursor: boolean;\n /** The row field the tokens are read from. */\n cursorField: string;\n /** The primary-key field — the tie-break value in every token. */\n idField: string;\n /** Signs the tokens (registry `cursorSecret`). */\n secret?: string;\n}\n\n/**\n * Rows fetched with `limit + 1` in query order → the page in display order and\n * its meta. A backward page is fetched reversed and flipped back here.\n */\nexport async function cursorPage<T extends Record<string, unknown>>(rows: readonly T[], options: CursorPageOptions): Promise<{ data: T[]; meta: CursorMeta }> {\n const { limit, direction, hasCursor, cursorField, idField, secret } = options;\n const hasExtra = rows.length > limit;\n let data = hasExtra ? rows.slice(0, limit) : [...rows];\n if (direction === \"backward\") data = data.reverse();\n\n const first = data[0];\n const last = data[data.length - 1];\n const hasNext = direction === \"forward\" ? hasExtra : hasCursor;\n const hasPrev = direction === \"forward\" ? hasCursor : hasExtra;\n\n return {\n data,\n meta: {\n limit,\n has_next: hasNext,\n has_prev: hasPrev,\n next_cursor: hasNext && last ? await encodeCursorToken({ k: last[cursorField], id: last[idField] }, secret) : null,\n prev_cursor: hasPrev && first ? await encodeCursorToken({ k: first[cursorField], id: first[idField] }, secret) : null,\n },\n };\n}\n","/**\n * Bulk-mutation guards shared by every adapter: a filterless\n * `updateWhere` / `deleteWhere` runs only on an explicit `{ all: true }`.\n */\nimport { QueryKitError } from \"../errors\";\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;\n\n/** `{ all: true }` — and nothing else — asks for every row (the scope still applies). */\nexport function isAllRows(filter: unknown): boolean {\n return isPlainObject(filter) && filter.all === true && Object.keys(filter).length === 1;\n}\n\n/** `undefined`, `null`, `[]` or `{}`: no condition at all. */\nexport function isEmptyFilter(filter: unknown): boolean {\n return (\n filter === undefined || filter === null || (Array.isArray(filter) && filter.length === 0) || (isPlainObject(filter) && Object.keys(filter).length === 0)\n );\n}\n\n/** A mutation without a condition — also one whose every condition was skipped. */\nexport function refuseEmptyFilter(source: string, method: \"updateWhere\" | \"deleteWhere\"): never {\n throw new QueryKitError({ source, site: \"mutation\", key: method, reason: \"empty-filter\" });\n}\n","/**\n * A repository `scope` (the server's RBAC / tenancy filter) split once for every\n * adapter: equality values and `{ in: [...] }` lists.\n */\n\n/** One scope condition, in the shape every adapter's `buildWhere` reads. */\nexport interface ScopeCondition {\n key: string;\n operation: \"=\" | \"in\";\n value: unknown;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;\n\n/** `{ in: [...] }` — and nothing else — is a list scope; any other value is equality (as before). */\nconst isInScope = (value: unknown): value is { in: readonly unknown[] } => isPlainObject(value) && Object.keys(value).length === 1 && Array.isArray(value.in);\n\n/** The scope as conditions: `{ k: v }` → `k = v`, `{ k: { in: [...] } }` → `k in [...]`. */\nexport function scopeConditions(scope: Record<string, unknown> | undefined): ScopeCondition[] {\n return Object.entries(scope ?? {}).map(([key, value]) =>\n isInScope(value) ? { key, operation: \"in\", value: [...value.in] } : { key, operation: \"=\", value },\n );\n}\n\n/** The values `create` / `upsert` fill in: the equality scopes only (a list has no single value). */\nexport function scopeDefaults(scope: Record<string, unknown> | undefined): Record<string, unknown> {\n return Object.fromEntries(Object.entries(scope ?? {}).filter(([, value]) => !isInScope(value)));\n}\n","/**\n * The client's `with` against the repository's `relations` allow-list (R21),\n * one walker for every adapter. Each adapter names its own option keys (a \"dialect\");\n * the rules are the same: an unlisted relation, column, filter field, nested relation\n * or option is `QueryKitError` `forbidden-key`, `site: \"with\"`, before the driver runs.\n */\nimport { QueryKitError } from \"../errors\";\nimport type { RelationRule, Relations } from \"../types\";\n\n/** How one adapter spells a relation's options. */\nexport interface WithDialect {\n /** Column selection: drizzle `columns`, prisma / mongoose `select`. */\n columns: string;\n /** Nested relations: drizzle `with`, prisma `include`, mongoose `populate`. */\n nested: string;\n /** Row filters: prisma `where`, mongoose `match`; drizzle none (its `where` is code, not JSON). */\n filters: readonly string[];\n /** Logical keys inside a filter, walked into: prisma `AND` / `OR` / `NOT`, mongoose `$and` / `$or` / `$nor`. */\n logical: readonly string[];\n /** Options that only page: drizzle `limit` / `offset`, prisma `take` / `skip`, mongoose `options.limit` / `options.skip`. */\n paging: readonly string[];\n /** A sort whose keys must be allowed columns: prisma `orderBy`. */\n orderBy?: string;\n /** An options bag whose keys must be `paging` keys: mongoose `options`. */\n options?: string;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;\n\n/** A rule that opens a relation: an object with `columns` (a list or `\"*\"`). A bare model (mongoose shorthand) does not. */\nconst ruleOf = (relations: Relations | undefined, name: string): RelationRule | undefined => {\n const rule = relations && Object.prototype.hasOwnProperty.call(relations, name) ? (relations as Record<string, unknown>)[name] : undefined;\n return isPlainObject(rule) && (rule.columns === \"*\" || Array.isArray(rule.columns)) ? (rule as unknown as RelationRule) : undefined;\n};\n\n/** Keys named by a selection: `{ a: true, b: 1 }` or mongoose's `\"a b -c\"`. */\nconst selectedKeys = (selection: unknown): string[] | undefined => {\n if (typeof selection === \"string\") return selection.split(/\\s+/).filter(Boolean);\n if (isPlainObject(selection)) return Object.keys(selection).filter(key => Boolean(selection[key]));\n return undefined;\n};\n\n/**\n * The checked `with`: every relation in `relations`, every selected column in its\n * `columns`, every filter field in its `filterable`, every nested relation in its\n * `nested`. A relation asked for with `true` (or without a selection) gets its\n * listed columns selected, so a column list is never widened to the full row.\n */\nexport function checkWith(\n withValue: unknown,\n relations: Relations | undefined,\n dialect: WithDialect,\n source: string,\n path = \"\",\n): Record<string, unknown> | undefined {\n if (withValue === undefined || withValue === null) return undefined;\n const refuse = (key: string): never => {\n throw new QueryKitError({ source, site: \"with\", key: path + key, reason: \"forbidden-key\" });\n };\n if (!isPlainObject(withValue)) return refuse(\"with\");\n\n const checked: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(withValue)) {\n if (value === false || value === undefined) continue;\n const rule = ruleOf(relations, name) ?? refuse(name);\n const listed = rule.columns === \"*\" ? undefined : new Set(rule.columns);\n const selectListed = () => Object.fromEntries([...listed!].map(column => [column, true]));\n if (value === true) {\n checked[name] = listed ? { [dialect.columns]: selectListed() } : true;\n continue;\n }\n if (!isPlainObject(value)) refuse(name);\n const options = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const [key, option] of Object.entries(options)) {\n const at = `${name}.${key}`;\n if (key === dialect.columns) {\n const keys = selectedKeys(option) ?? refuse(at);\n // An exclusion (\"-secret\") selects every other column: only with \"*\".\n for (const column of keys) if (listed && (column.startsWith(\"-\") || !listed.has(column))) refuse(`${name}.${column}`);\n out[key] = option;\n } else if (key === dialect.nested) {\n out[key] = checkWith(option, rule.nested, dialect, source, `${name}.`);\n } else if (dialect.filters.includes(key)) {\n checkFilterFields(option, rule, dialect, (field: string) => refuse(`${name}.${field}`));\n out[key] = option;\n } else if (dialect.paging.includes(key)) {\n out[key] = option;\n } else if (key === dialect.orderBy) {\n for (const item of Array.isArray(option) ? option : [option]) {\n for (const column of selectedKeys(item) ?? refuse(at)) if (listed && !listed.has(column)) refuse(`${name}.${column}`);\n }\n out[key] = option;\n } else if (key === dialect.options) {\n for (const sub of Object.keys(isPlainObject(option) ? option : refuse(at))) if (!dialect.paging.includes(sub)) refuse(`${at}.${sub}`);\n out[key] = option;\n } else {\n refuse(at);\n }\n }\n if (listed && out[dialect.columns] === undefined) out[dialect.columns] = selectListed();\n checked[name] = out;\n }\n return checked;\n}\n\n/** Every field of a relation filter (through the logical keys) must be in `filterable`. */\nfunction checkFilterFields(filter: unknown, rule: RelationRule, dialect: WithDialect, refuse: (field: string) => never): void {\n if (!isPlainObject(filter)) refuse(\"filter\");\n for (const [key, value] of Object.entries(filter as Record<string, unknown>)) {\n if (dialect.logical.includes(key)) {\n for (const part of Array.isArray(value) ? value : [value]) checkFilterFields(part, rule, dialect, refuse);\n } else if (key.startsWith(\"$\") || !rule.filterable || rule.filterable[key] === undefined) {\n // `$where`, `$expr` and any field outside the allow-list.\n refuse(key);\n }\n }\n}\n","/**\n * The filter-limit walk shared by the validators. It runs on the raw,\n * unvalidated payload **before** any recursive schema sees it, so it is\n * iterative — no recursion at all, whatever the payload's depth — and a\n * 10 000-level `not` chain is rejected after `maxDepth + 1` steps.\n *\n * Only size is judged here. Shape errors (a missing `key`, a bad operator) are\n * the validator's job — a malformed node is skipped, not reported.\n */\nimport { DEFAULT_PER_PAGE, type QueryLimits } from \"../defaults\";\n\n/** Where in the filter a limit was crossed — object keys and array indexes, from the root. */\nexport type LimitPath = (string | number)[];\n\nexport interface LimitViolation {\n limit: keyof QueryLimits;\n max: number;\n path: LimitPath;\n}\n\n/** The limits the walk checks. */\nexport type FilterLimits = Pick<QueryLimits, \"maxDepth\" | \"maxConditions\" | \"maxInItems\" | \"maxStringLength\">;\n\n/** A node still to visit: the node, its level (the root is 1) and its path. */\ntype Pending = [node: unknown, depth: number, path: LimitPath];\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** `maxInItems (200)` — the form every package's error text uses. */\nexport const formatLimit = (limit: keyof QueryLimits, max: number): string => `${limit} (${max})`;\n\n/**\n * The first limit the filter crosses, depth-first in document order, or\n * `undefined` when it is within all four. A flat array (implicit AND) puts its\n * conditions at level 1. Key order mirrors the validators: `key` first, then\n * `and`, `or`, `not`.\n */\nexport function findFilterLimitViolation(filter: unknown, limits: FilterLimits): LimitViolation | undefined {\n const hit = (limit: keyof FilterLimits, path: LimitPath): LimitViolation => ({ limit, max: limits[limit], path });\n const pending: Pending[] = [];\n /* Children go on the stack last-first, so they pop in document order. */\n const push = (children: readonly unknown[], depth: number, path: LimitPath) => {\n for (let index = children.length - 1; index >= 0; index--) pending.push([children[index], depth, [...path, index]]);\n };\n if (Array.isArray(filter)) push(filter, 1, []);\n else if (filter !== undefined) pending.push([filter, 1, []]);\n\n let conditions = 0;\n for (let next = pending.pop(); next; next = pending.pop()) {\n const [node, depth, path] = next;\n if (depth > limits.maxDepth) return hit(\"maxDepth\", path);\n if (!isRecord(node)) continue;\n\n if (\"key\" in node) {\n if (++conditions > limits.maxConditions) return hit(\"maxConditions\", path);\n const { value } = node;\n const valuePath = [...path, \"value\"];\n if (Array.isArray(value) && value.length > limits.maxInItems) return hit(\"maxInItems\", valuePath);\n const items: unknown[] = Array.isArray(value) ? value : [value];\n const tooLong = items.findIndex(item => typeof item === \"string\" && item.length > limits.maxStringLength);\n if (tooLong >= 0) return hit(\"maxStringLength\", Array.isArray(value) ? [...valuePath, tooLong] : valuePath);\n continue;\n }\n\n const group = \"and\" in node ? \"and\" : \"or\" in node ? \"or\" : undefined;\n if (group) {\n const children = node[group];\n if (Array.isArray(children)) push(children, depth + 1, [...path, group]);\n } else if (\"not\" in node) pending.push([node.not, depth + 1, [...path, \"not\"]]);\n }\n return undefined;\n}\n\nconst LIKE_OPERATORS: ReadonlySet<string> = new Set([\"like\", \"ilike\", \"notLike\"]);\n\n/** Whether an operator takes a SQL LIKE pattern. */\nexport const isLikeOperator = (operation: string): boolean => LIKE_OPERATORS.has(operation);\n\n/**\n * Unescaped wildcards in a LIKE pattern, a run of `%` counted once (`%%a%` ⇒ 2).\n * A backslash escapes the next character, as in the adapters' LIKE translation.\n */\nexport function likeWildcards(pattern: string): number {\n let count = 0;\n let previous = \"\";\n for (let index = 0; index < pattern.length; index++) {\n const char = pattern[index]!;\n if (char === \"\\\\\") {\n index++;\n previous = \"\";\n continue;\n }\n if (char === \"_\" || (char === \"%\" && previous !== \"%\")) count++;\n previous = char;\n }\n return count;\n}\n\n/** Rows an offset-paginated request skips: `(page - 1) × perPage`, with the core default page size. */\nexport const offsetOf = (page: number | undefined, perPage: number | undefined): number => ((page ?? 1) - 1) * (perPage ?? DEFAULT_PER_PAGE);\n","/**\n * The server-side request policy every adapter applies: which fields\n * a client may filter by and with which operators (`filterable`), which it may\n * sort and page by (`sortable`), and the request limits (`limits`).\n *\n * A plain object that is not a condition, a group, a branded `raw()` node or a\n * driver-native object (`isNative`) is refused as well (R19): it would otherwise\n * reach the driver as its own `where`, past `filterable`.\n *\n * A refused request never reaches the driver and is never dropped silently:\n * every check throws `QueryKitError`, whatever `strict` / `onSkippedCondition`\n * say. A key the model does not have is **not** the policy's business — it goes\n * on to the adapter's own `unknown-key` handling, unchanged.\n */\nimport { resolveLimits, type QueryLimits } from \"../defaults\";\nimport { QueryKitError } from \"../errors\";\nimport type { Filterable, SkipReason, SkipSite } from \"../types\";\nimport { isRaw } from \"../raw\";\nimport { findFilterLimitViolation, isLikeOperator, likeWildcards, offsetOf } from \"./limits\";\n\nexport interface PolicyOptions {\n /** Table / model name for the error. */\n source: string;\n /** Wire key → the model's canonical field name, or `undefined` when the model has no such field. */\n fieldOf: (key: string) => string | undefined;\n /** Canonical primary-key field — the last-resort safe default. */\n primaryKey: string;\n /** Canonical `createdAt` field when the model has one (default `sortable`). */\n createdAt?: string;\n filterable?: Filterable;\n sortable?: readonly string[];\n allowedColumns?: readonly string[];\n forcedColumns?: Readonly<Record<string, unknown>>;\n limits?: Partial<QueryLimits>;\n /**\n * A driver object that cannot come from JSON and stands for itself (drizzle `SQL`).\n * Anything else that is not a condition, a group or a {@link isRaw} node is refused (R19).\n */\n isNative?: (node: object) => boolean;\n}\n\nexport interface Policy {\n readonly limits: QueryLimits;\n /** Limits, then every condition's field and operator. */\n checkFilter(filter: unknown): void;\n /** Field count, then every sort field. */\n checkSort(sort: readonly { key?: unknown }[] | undefined): void;\n checkCursorKey(key: string): void;\n /** Offset pagination: the clamped `page` × `perPage`. Infinite: the clamped `offset`. */\n checkPage(page: { page: number; perPage: number } | { offset: number }): void;\n /** A `groupBy` / `sum` / `avg` / `min` / `max` field must be filterable. */\n checkAggregateKey(key: string): void;\n}\n\n/** The safe default when `filterable` is not given: equality only. */\nconst DEFAULT_OPERATORS = [\"=\", \"in\"] as const;\n\n/** Alias → the token it means, so `[\"=\"]` also admits `eq` and `[\"contains\"]` admits `%_%`. */\nconst OPERATOR_TOKEN: Readonly<Record<string, string>> = {\n eq: \"=\",\n ne: \"!=\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n contains: \"%_%\",\n startsWith: \"%_\",\n endsWith: \"_%\",\n};\nconst tokenOf = (operation: string): string => OPERATOR_TOKEN[operation] ?? operation;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** Field → admitted operator tokens, or `\"*\"`. */\ntype Rules = ReadonlyMap<string, ReadonlySet<string> | \"*\">;\n\nfunction filterRules(options: PolicyOptions, canonical: (key: string) => string): Rules {\n const rules = new Map<string, ReadonlySet<string> | \"*\">();\n if (options.filterable) {\n for (const [key, operators] of Object.entries(options.filterable)) {\n if (operators) rules.set(canonical(key), operators === \"*\" ? \"*\" : new Set(operators.map(tokenOf)));\n }\n return rules;\n }\n const fields =\n options.allowedColumns ?? (options.forcedColumns ? Object.keys(options.forcedColumns).filter(key => options.forcedColumns![key]) : [options.primaryKey]);\n const equality = new Set<string>(DEFAULT_OPERATORS);\n for (const field of fields) rules.set(canonical(field), equality);\n return rules;\n}\n\nexport function resolvePolicy(options: PolicyOptions): Policy {\n const limits = resolveLimits(options.limits);\n const canonical = (key: string) => options.fieldOf(key) ?? key;\n const rules = filterRules(options, canonical);\n const sortable = new Set((options.sortable ?? [options.primaryKey, ...(options.createdAt ? [options.createdAt] : [])]).map(canonical));\n\n const refuse = (site: SkipSite, key: string, reason: SkipReason, operation?: string): never => {\n throw new QueryKitError({ source: options.source, site, key, reason, ...(operation ? { operation: operation as never } : {}) });\n };\n\n const checkCondition = (node: Record<string, unknown>): void => {\n const key = String(node.key);\n const field = options.fieldOf(key);\n if (field === undefined) return; // not in the model — the adapter's unknown-key path\n const operation = typeof node.operation === \"string\" ? node.operation : \"=\";\n const rule = rules.get(field);\n if (!rule) refuse(\"filter\", key, \"forbidden-key\", operation);\n if (rule !== \"*\" && !rule!.has(tokenOf(operation))) refuse(\"filter\", key, \"forbidden-operator\", operation);\n if (isLikeOperator(operation) && typeof node.value === \"string\" && likeWildcards(node.value) > limits.maxLikeWildcards) {\n refuse(\"filter\", \"maxLikeWildcards\", \"limit-exceeded\", operation);\n }\n };\n\n const checkSortKey = (site: SkipSite, key: string): void => {\n const field = options.fieldOf(key);\n if (field !== undefined && !sortable.has(field)) refuse(site, key, \"forbidden-key\");\n };\n\n return {\n limits,\n\n checkFilter(filter) {\n const violation = findFilterLimitViolation(filter, limits);\n if (violation) refuse(\"filter\", violation.limit, \"limit-exceeded\");\n /* Bounded by maxDepth now, but kept iterative so `maxDepth: Infinity` cannot overflow the stack. */\n const pending: unknown[] = Array.isArray(filter) ? [...filter] : [filter];\n while (pending.length > 0) {\n const node = pending.pop();\n if (!isRecord(node)) continue;\n if (\"key\" in node) checkCondition(node);\n else if (Array.isArray(node.and)) pending.push(...node.and);\n else if (Array.isArray(node.or)) pending.push(...node.or);\n else if (\"not\" in node) pending.push(node.not);\n // R19: a JSON body cannot brand a node, so an unbranded driver object is refused.\n else if (!isRaw(node) && !options.isNative?.(node)) refuse(\"filter\", Object.keys(node)[0] ?? \"\", \"forbidden-key\");\n }\n },\n\n checkSort(sort) {\n if (!sort) return;\n if (sort.length > limits.maxSortFields) refuse(\"sort\", \"maxSortFields\", \"limit-exceeded\");\n for (const item of sort) if (item && typeof item.key === \"string\" && item.key) checkSortKey(\"sort\", item.key);\n },\n\n checkCursorKey(key) {\n checkSortKey(\"cursorKey\", key);\n },\n\n checkPage(page) {\n const offset = \"offset\" in page ? page.offset : offsetOf(page.page, page.perPage);\n if (offset > limits.maxOffset) refuse(\"page\", \"maxOffset\", \"limit-exceeded\");\n },\n\n checkAggregateKey(key) {\n const field = options.fieldOf(key);\n if (field !== undefined && !rules.has(field)) refuse(\"aggregate\", key, \"forbidden-key\");\n },\n };\n}\n","/**\n * Wire-contract checks for validator authors: the filter, the sort and the\n * pagination params exactly as they arrive from JSON. Framework-free and\n * text-free — an issue carries a path, a message key and its arguments; each\n * validator renders its own message. The size walk runs first, iteratively, so\n * an oversized payload never reaches the recursive shape check.\n */\nimport { DEFAULT_MAX_LIMIT, DEFAULT_MAX_PER_PAGE, resolveLimits, type QueryLimits } from \"../defaults\";\nimport { FILTER_OPERATORS } from \"../operators\";\nimport type { FilterOperator } from \"../types\";\nimport { findFilterLimitViolation, offsetOf, type LimitPath } from \"./limits\";\n\nexport type WireFilterIssueKey =\n | \"querykit.filter.invalid_node\"\n | \"querykit.filter.missing_key\"\n | \"querykit.filter.unknown_key\"\n | \"querykit.filter.invalid_operator\"\n | \"querykit.filter.invalid_value\"\n | \"querykit.filter.invalid_group\"\n | \"querykit.filter.max_depth\"\n | \"querykit.filter.value_requires_array\"\n | \"querykit.filter.value_requires_tuple\"\n | \"querykit.filter.value_forbidden\"\n | \"querykit.limit.exceeded\";\n\nexport type WireSortIssueKey =\n | \"querykit.sort.not_array\"\n | \"querykit.sort.invalid_item\"\n | \"querykit.sort.missing_key\"\n | \"querykit.sort.unknown_key\"\n | \"querykit.sort.invalid_direction\"\n | \"querykit.limit.exceeded\";\n\nexport type WireParamsIssueKey =\n \"querykit.params.invalid_type\" | \"querykit.params.not_integer\" | \"querykit.params.out_of_range\" | \"querykit.params.invalid_enum\";\n\nexport type WireIssueKey = WireFilterIssueKey | WireSortIssueKey | WireParamsIssueKey;\n\n/** Message arguments: strings and numbers only, so any message catalog can interpolate them. */\nexport type WireIssueArgs = Record<string, string | number>;\n\n/** One rejected spot: object keys and array indexes from the checked value, the message key and its arguments. */\nexport interface WireIssue<TKey extends WireIssueKey = WireIssueKey> {\n path: LimitPath;\n key: TKey;\n args: WireIssueArgs;\n}\n\nexport interface WireFilterOptions extends Partial<Pick<QueryLimits, \"maxDepth\" | \"maxConditions\" | \"maxInItems\" | \"maxStringLength\">> {\n /** Only these keys may be filtered on; another key is an issue. Absent — any string key. */\n allowedKeys?: readonly string[];\n /** Absent — every core operator. */\n allowedOperators?: readonly FilterOperator[];\n /** `in`/`notIn` need an array, `between`/`notBetween` exactly two values, `isNull`/`isNotNull` no value. */\n strictValue?: boolean;\n}\n\nexport interface WireSortOptions extends Partial<Pick<QueryLimits, \"maxSortFields\">> {\n /** Only these keys may be sorted on. */\n allowedKeys?: readonly string[];\n}\n\n/** Request fields only the server may set; a client sends them only where `allow` opens them. */\nexport type WireServerOwnedField = \"columns\" | \"with\" | \"withDeleted\";\n\n/** The same names and defaults as the `@querykitjs/zod` params factories. */\nexport interface WireParamsOptions {\n /** Default `DEFAULT_MAX_PER_PAGE` (200). */\n maxPerPage?: number;\n /** Default `DEFAULT_MAX_LIMIT` (200). */\n maxLimit?: number;\n limits?: Partial<QueryLimits>;\n allow?: readonly WireServerOwnedField[];\n}\n\nexport type WireParamsKind = \"offset\" | \"infinite\" | \"cursor\";\n\nexport interface WireParamsResult {\n /** The accepted fields only (unknown and closed server-owned fields stripped); absent when there are issues. */\n value?: Record<string, unknown>;\n issues: WireIssue[];\n}\n\ntype UnknownRecord = Record<string, unknown>;\n\nconst ALL_OPERATORS: ReadonlySet<string> = /* @__PURE__ */ new Set<string>(FILTER_OPERATORS);\n\nconst isRecord = (value: unknown): value is UnknownRecord => typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** JSON has no `Date`, `NaN` or `Infinity`; a date arrives as an ISO string. */\nconst isScalar = (value: unknown): boolean =>\n value === null || typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value));\n\nconst isFilterValue = (value: unknown): boolean => (Array.isArray(value) ? value.every(isScalar) : isScalar(value));\n\n/** Text for a message argument; the input is untrusted, so `String()` may throw. */\nconst label = (value: unknown): string => {\n try {\n return String(value);\n } catch {\n return Object.prototype.toString.call(value);\n }\n};\n\nconst wireIssue = <TKey extends WireIssueKey>(key: TKey, path: LimitPath, args: WireIssueArgs = {}): WireIssue<TKey> => ({ path, key, args });\n\n/* --------------------------------- filter ---------------------------------- */\n\ninterface FilterWalk {\n issues: WireIssue<WireFilterIssueKey>[];\n allowedKeys?: ReadonlySet<string>;\n operators: ReadonlySet<string>;\n maxDepth: number;\n strictValue: boolean;\n}\n\n/** Extra properties (a legacy `type`) are ignored, as the zod schemas strip them. */\nfunction checkCondition(node: unknown, path: LimitPath, walk: FilterWalk): void {\n if (!isRecord(node)) {\n walk.issues.push(wireIssue(\"querykit.filter.invalid_node\", path));\n return;\n }\n const { key, operation, value } = node;\n if (typeof key !== \"string\") {\n walk.issues.push(wireIssue(\"querykit.filter.missing_key\", path));\n return;\n }\n if (walk.allowedKeys && !walk.allowedKeys.has(key)) walk.issues.push(wireIssue(\"querykit.filter.unknown_key\", path, { key }));\n\n let operator: string | undefined;\n if (operation !== undefined) {\n if (typeof operation === \"string\" && walk.operators.has(operation)) operator = operation;\n else walk.issues.push(wireIssue(\"querykit.filter.invalid_operator\", [...path, \"operation\"], { operation: label(operation) }));\n }\n if (value !== undefined && !isFilterValue(value)) walk.issues.push(wireIssue(\"querykit.filter.invalid_value\", [...path, \"value\"]));\n if (walk.strictValue && operator !== undefined) checkValueShape(operator, value, [...path, \"value\"], walk);\n}\n\n/** The `strictValue` check: `in`/`notIn` an array, `between`/`notBetween` two values, `isNull`/`isNotNull` none. */\nfunction checkValueShape(operator: string, value: unknown, path: LimitPath, walk: FilterWalk): void {\n const key =\n (operator === \"in\" || operator === \"notIn\") && !Array.isArray(value)\n ? \"querykit.filter.value_requires_array\"\n : (operator === \"between\" || operator === \"notBetween\") && (!Array.isArray(value) || value.length !== 2)\n ? \"querykit.filter.value_requires_tuple\"\n : (operator === \"isNull\" || operator === \"isNotNull\") && value !== undefined\n ? \"querykit.filter.value_forbidden\"\n : undefined;\n if (key) walk.issues.push(wireIssue(key, path, { operation: operator }));\n}\n\nfunction walkGroup(group: unknown, depth: number, path: LimitPath, walk: FilterWalk): void {\n if (!Array.isArray(group)) {\n walk.issues.push(wireIssue(\"querykit.filter.invalid_group\", path));\n return;\n }\n group.forEach((child, index) => walkNode(child, depth + 1, [...path, index], walk));\n}\n\n/** Recursive, but only after the size walk has bounded the depth. */\nfunction walkNode(node: unknown, depth: number, path: LimitPath, walk: FilterWalk): void {\n if (depth > walk.maxDepth) {\n walk.issues.push(wireIssue(\"querykit.filter.max_depth\", path, { max: walk.maxDepth }));\n return;\n }\n if (!isRecord(node)) {\n walk.issues.push(wireIssue(\"querykit.filter.invalid_node\", path));\n return;\n }\n // The zod union tries the condition first: any object with `key` is a condition.\n if (\"key\" in node) checkCondition(node, path, walk);\n else if (\"and\" in node) walkGroup(node.and, depth, [...path, \"and\"], walk);\n else if (\"or\" in node) walkGroup(node.or, depth, [...path, \"or\"], walk);\n else if (\"not\" in node) walkNode(node.not, depth + 1, [...path, \"not\"], walk);\n else walk.issues.push(wireIssue(\"querykit.filter.missing_key\", path));\n}\n\n/**\n * Checks a wire filter (a node, or a flat array as an implicit AND). An empty\n * list means valid; `undefined` is valid. A crossed size limit is the only issue.\n *\n * @example\n * ```ts\n * checkFilter({ key: \"age\", operation: \"~\" }); // [{ path: [\"operation\"], key: \"querykit.filter.invalid_operator\", args: { operation: \"~\" } }]\n * ```\n */\nexport function checkFilter(value: unknown, options: WireFilterOptions = {}): WireIssue<WireFilterIssueKey>[] {\n if (value === undefined) return [];\n const limits = resolveLimits(options);\n const violation = findFilterLimitViolation(value, limits);\n if (violation) {\n const key = violation.limit === \"maxDepth\" ? \"querykit.filter.max_depth\" : \"querykit.limit.exceeded\";\n return [wireIssue(key, violation.path, { limit: violation.limit, max: violation.max })];\n }\n\n const walk: FilterWalk = {\n issues: [],\n allowedKeys: options.allowedKeys ? new Set(options.allowedKeys) : undefined,\n operators: options.allowedOperators ? new Set<string>(options.allowedOperators) : ALL_OPERATORS,\n maxDepth: limits.maxDepth,\n strictValue: options.strictValue ?? false,\n };\n // A flat array holds conditions only, never nested groups — as the core `FieldCondition[]` type says.\n if (Array.isArray(value)) value.forEach((item, index) => checkCondition(item, [index], walk));\n else walkNode(value, 1, [], walk);\n return walk.issues;\n}\n\n/* ---------------------------------- sort ----------------------------------- */\n\n/** Checks a wire sort, `{ key, direction }[]`. An empty list means valid; `undefined` is valid. */\nexport function checkSort(value: unknown, options: WireSortOptions = {}): WireIssue<WireSortIssueKey>[] {\n if (value === undefined) return [];\n if (!Array.isArray(value)) return [wireIssue(\"querykit.sort.not_array\", [])];\n const { maxSortFields } = resolveLimits(options);\n if (value.length > maxSortFields) return [wireIssue(\"querykit.limit.exceeded\", [], { limit: \"maxSortFields\", max: maxSortFields })];\n\n const allowedKeys = options.allowedKeys ? new Set(options.allowedKeys) : undefined;\n const issues: WireIssue<WireSortIssueKey>[] = [];\n value.forEach((item, index) => {\n if (!isRecord(item)) {\n issues.push(wireIssue(\"querykit.sort.invalid_item\", [index]));\n return;\n }\n const { key, direction } = item;\n if (typeof key !== \"string\") {\n issues.push(wireIssue(\"querykit.sort.missing_key\", [index]));\n return;\n }\n if (allowedKeys && !allowedKeys.has(key)) issues.push(wireIssue(\"querykit.sort.unknown_key\", [index], { key }));\n if (direction !== undefined && direction !== \"asc\" && direction !== \"desc\") {\n issues.push(wireIssue(\"querykit.sort.invalid_direction\", [index, \"direction\"]));\n }\n });\n return issues;\n}\n\n/* --------------------------------- params ---------------------------------- */\n\n/** Checks one present field and reports into `issues`; the field is kept when it adds none. */\ntype FieldCheck = (value: unknown, path: LimitPath, issues: WireIssue[]) => void;\n\nconst prefixed = (path: LimitPath, issues: readonly WireIssue[]): WireIssue[] => issues.map(found => ({ ...found, path: [...path, ...found.path] }));\n\ntype Expected = \"boolean\" | \"string\" | \"object\" | \"string or null\";\n\nconst accepts = (expected: Expected, value: unknown): boolean =>\n expected === \"object\" ? isRecord(value) : expected === \"string or null\" ? value === null || typeof value === \"string\" : typeof value === expected;\n\nconst typed =\n (expected: Expected): FieldCheck =>\n (value, path, issues) => {\n if (!accepts(expected, value))\n issues.push(wireIssue(\"querykit.params.invalid_type\", path, { expected: `${expected === \"object\" ? \"an\" : \"a\"} ${expected}` }));\n };\n\nconst oneOf =\n (values: readonly string[]): FieldCheck =>\n (value, path, issues) => {\n if (typeof value !== \"string\" || !values.includes(value)) issues.push(wireIssue(\"querykit.params.invalid_enum\", path, { values: values.join(\", \") }));\n };\n\n/** An integer in `[min, max]`; above `maxOffset`, a limit issue instead of a range issue. */\nconst integer =\n (min: number, max: number, overLimit?: keyof QueryLimits): FieldCheck =>\n (value, path, issues) => {\n if (typeof value !== \"number\" || !Number.isFinite(value)) issues.push(wireIssue(\"querykit.params.invalid_type\", path, { expected: \"a number\" }));\n else if (!Number.isInteger(value)) issues.push(wireIssue(\"querykit.params.not_integer\", path));\n else if (value < min) issues.push(wireIssue(\"querykit.params.out_of_range\", path, { min }));\n else if (value > max && overLimit) issues.push(wireIssue(\"querykit.limit.exceeded\", path, { limit: overLimit, max }));\n else if (value > max) issues.push(wireIssue(\"querykit.params.out_of_range\", path, { max }));\n };\n\n/** `columns` is a map of column name → boolean. */\nconst checkColumns: FieldCheck = (value, path, issues) => {\n typed(\"object\")(value, path, issues);\n if (isRecord(value)) for (const [name, flag] of Object.entries(value)) typed(\"boolean\")(flag, [...path, name], issues);\n};\n\nconst serverOwnedCheck = (field: WireServerOwnedField): FieldCheck => (field === \"columns\" ? checkColumns : typed(field === \"with\" ? \"object\" : \"boolean\"));\n\nfunction fieldChecks(kind: WireParamsKind, options: WireParamsOptions, limits: QueryLimits): Map<string, FieldCheck> {\n const checks = new Map<string, FieldCheck>();\n checks.set(\"filter\", (value, path, issues) => issues.push(...prefixed(path, checkFilter(value, limits))));\n if (kind !== \"cursor\") checks.set(\"sort\", (value, path, issues) => issues.push(...prefixed(path, checkSort(value, limits))));\n for (const field of options.allow ?? []) checks.set(field, serverOwnedCheck(field));\n\n const maxLimit = options.maxLimit ?? DEFAULT_MAX_LIMIT;\n if (kind === \"offset\") {\n checks.set(\"page\", integer(1, Number.POSITIVE_INFINITY));\n checks.set(\"perPage\", integer(1, options.maxPerPage ?? DEFAULT_MAX_PER_PAGE));\n checks.set(\"withTotal\", typed(\"boolean\"));\n } else if (kind === \"infinite\") {\n checks.set(\"limit\", integer(1, maxLimit));\n checks.set(\"offset\", integer(0, limits.maxOffset, \"maxOffset\"));\n } else {\n checks.set(\"limit\", integer(1, maxLimit));\n checks.set(\"cursor\", typed(\"string or null\"));\n checks.set(\"cursorKey\", typed(\"string\"));\n checks.set(\"order\", oneOf([\"asc\", \"desc\"]));\n checks.set(\"direction\", oneOf([\"forward\", \"backward\"]));\n }\n return checks;\n}\n\n/**\n * Checks offset, infinite or cursor params the way the `@querykitjs/zod`\n * factories do: unknown fields and closed server-owned fields are stripped,\n * `(page - 1) × perPage` stays within `maxOffset`, and a cursor request has no `sort`.\n *\n * @example\n * ```ts\n * checkParams(\"offset\", { page: 2, perPage: 201 }).issues;\n * // [{ path: [\"perPage\"], key: \"querykit.params.out_of_range\", args: { max: 200 } }]\n * ```\n */\nexport function checkParams(kind: WireParamsKind, value: unknown, options: WireParamsOptions = {}): WireParamsResult {\n if (!isRecord(value)) return { issues: [wireIssue(\"querykit.params.invalid_type\", [], { expected: \"an object\" })] };\n\n const limits = resolveLimits(options.limits);\n const checks = fieldChecks(kind, options, limits);\n const issues: WireIssue[] = [];\n const accepted: UnknownRecord = {};\n for (const [name, field] of Object.entries(value)) {\n const check = checks.get(name);\n if (!check || field === undefined) continue;\n const before = issues.length;\n check(field, [name], issues);\n if (issues.length === before) accepted[name] = field;\n }\n\n if (kind === \"offset\" && issues.length === 0) {\n const page = typeof accepted.page === \"number\" ? accepted.page : undefined;\n const perPage = typeof accepted.perPage === \"number\" ? accepted.perPage : undefined;\n if (offsetOf(page, perPage) > limits.maxOffset) issues.push(wireIssue(\"querykit.limit.exceeded\", [\"page\"], { limit: \"maxOffset\", max: limits.maxOffset }));\n }\n return issues.length ? { issues } : { value: accepted, issues };\n}\n","/**\n * English message texts for the wire-check issue keys, shared by the\n * validators so a rejected payload reads the same everywhere. `{placeholder}`s\n * are filled from the issue's `args`; `{path}` is the issue path as text.\n */\n\n/**\n * The filter, sort and limit messages — the canonical key list of\n * `@querykitjs/class-validator`, which also ships `uz` and `ru` catalogs for it.\n */\nexport const QUERYKIT_MESSAGES_EN = {\n \"querykit.filter.invalid_node\": \"{path} must be a filter condition or an and/or/not group\",\n \"querykit.filter.missing_key\": \"{path} is missing the required `key` string\",\n \"querykit.filter.unknown_key\": \"{path}: `{key}` is not an allowed filter key\",\n \"querykit.filter.invalid_operator\": \"{path}: `{operation}` is not a supported filter operator\",\n \"querykit.filter.invalid_value\": \"{path} must be a string, number, boolean, null, or an array of those\",\n \"querykit.filter.invalid_group\": \"{path} must be an array of filter nodes\",\n \"querykit.filter.max_depth\": \"{path} exceeds maxDepth ({max})\",\n \"querykit.filter.value_requires_array\": \"{path}: `{operation}` requires an array value\",\n \"querykit.filter.value_requires_tuple\": \"{path}: `{operation}` requires exactly two values\",\n \"querykit.filter.value_forbidden\": \"{path}: `{operation}` must not carry a value\",\n \"querykit.sort.not_array\": \"{path} must be an array of { key, direction } items\",\n \"querykit.sort.invalid_item\": \"{path} must be an object with a `key` string\",\n \"querykit.sort.missing_key\": \"{path} is missing the required `key` string\",\n \"querykit.sort.unknown_key\": \"{path}: `{key}` is not an allowed sort key\",\n \"querykit.sort.invalid_direction\": \"{path}: direction must be `asc` or `desc`\",\n \"querykit.limit.exceeded\": \"{path} exceeds {limit} ({max})\",\n} as const satisfies Record<string, string>;\n\n/** The pagination-params messages (`checkParams`); kept apart so the class-validator catalogs keep their key set. */\nexport const QUERYKIT_PARAMS_MESSAGES_EN = {\n \"querykit.params.invalid_type\": \"{path} must be {expected}\",\n \"querykit.params.not_integer\": \"{path} must be an integer\",\n // args carry only the crossed bound (`min` or `max`), so the text names neither\n \"querykit.params.out_of_range\": \"{path} is out of the allowed range\",\n \"querykit.params.invalid_enum\": \"{path} must be one of: {values}\",\n} as const satisfies Record<string, string>;\n\n/** A filter, sort or limit message key. */\nexport type QueryKitMessageKey = keyof typeof QUERYKIT_MESSAGES_EN;\n\n/** One language's full catalog — every key required, so a new key breaks every catalog at compile time. */\nexport type QueryKitMessageCatalog = Record<QueryKitMessageKey, string>;\n\n/** Interpolation arguments. */\nexport type MessageArgs = Record<string, string | number>;\n\nconst PLACEHOLDER = /\\{(\\w+)\\}/g;\n\n/** Fills `{name}` placeholders from `args`; a placeholder with no argument stays as it is, so a message is never empty. */\nexport const interpolate = (template: string, args: MessageArgs): string =>\n template.replace(PLACEHOLDER, (match, name: string) => {\n const value = args[name];\n return value === undefined ? match : String(value);\n });\n\n/**\n * The message for `key` from `catalog` (default English), placeholders filled.\n *\n * @example\n * ```ts\n * formatMessage(\"querykit.limit.exceeded\", { path: \"filter\", limit: \"maxConditions\", max: 30 });\n * // \"filter exceeds maxConditions (30)\"\n * ```\n */\nexport function formatMessage(key: QueryKitMessageKey, args: MessageArgs = {}, catalog: QueryKitMessageCatalog = QUERYKIT_MESSAGES_EN): string {\n return interpolate(catalog[key], args);\n}\n"]}
|
|
@@ -67,7 +67,7 @@ interface SortItem<TKey extends string = string> {
|
|
|
67
67
|
}
|
|
68
68
|
/** Sort is **always an array** of {@link SortItem} (multi-field capable). */
|
|
69
69
|
type Sort<TKey extends string = string> = SortItem<TKey>[];
|
|
70
|
-
/** Scope qiymati ro'yxat bo'yicha
|
|
70
|
+
/** Scope qiymati ro'yxat bo'yicha: `{ in: [...] }`; bo'sh ro'yxat — hech qanday qator. */
|
|
71
71
|
interface ScopeIn {
|
|
72
72
|
in: readonly FilterScalar[];
|
|
73
73
|
}
|
|
@@ -201,7 +201,7 @@ interface MutationRows<TRow> extends MutationCount {
|
|
|
201
201
|
rows: TRow[];
|
|
202
202
|
}
|
|
203
203
|
/**
|
|
204
|
-
* Bitta relation uchun mijoz `with` ruxsati (
|
|
204
|
+
* Bitta relation uchun mijoz `with` ruxsati (R21): `columns` majburiy — ro'yxat yoki aniq `"*"`;
|
|
205
205
|
* `filterable` — relation filtrida (prisma `where`, mongoose `match`) ruxsat etilgan maydonlar;
|
|
206
206
|
* `nested` — shu relation ichidagi `with` uchun xuddi shu shakl (yo'q ⇒ ichki `with` — `forbidden-key`).
|
|
207
207
|
*/
|
|
@@ -67,7 +67,7 @@ interface SortItem<TKey extends string = string> {
|
|
|
67
67
|
}
|
|
68
68
|
/** Sort is **always an array** of {@link SortItem} (multi-field capable). */
|
|
69
69
|
type Sort<TKey extends string = string> = SortItem<TKey>[];
|
|
70
|
-
/** Scope qiymati ro'yxat bo'yicha
|
|
70
|
+
/** Scope qiymati ro'yxat bo'yicha: `{ in: [...] }`; bo'sh ro'yxat — hech qanday qator. */
|
|
71
71
|
interface ScopeIn {
|
|
72
72
|
in: readonly FilterScalar[];
|
|
73
73
|
}
|
|
@@ -201,7 +201,7 @@ interface MutationRows<TRow> extends MutationCount {
|
|
|
201
201
|
rows: TRow[];
|
|
202
202
|
}
|
|
203
203
|
/**
|
|
204
|
-
* Bitta relation uchun mijoz `with` ruxsati (
|
|
204
|
+
* Bitta relation uchun mijoz `with` ruxsati (R21): `columns` majburiy — ro'yxat yoki aniq `"*"`;
|
|
205
205
|
* `filterable` — relation filtrida (prisma `where`, mongoose `match`) ruxsat etilgan maydonlar;
|
|
206
206
|
* `nested` — shu relation ichidagi `with` uchun xuddi shu shakl (yo'q ⇒ ichki `with` — `forbidden-key`).
|
|
207
207
|
*/
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/defaults.ts","../src/raw.ts","../src/errors.ts"],"names":[],"mappings":";;;;;AAOO,IAAM,gBAAA,GAAmB,EAAA,CAAA,CAGnB,aAAA,GAAgB,EAAA,CAAA,CAOhB,oBAAA,GAAuB,KAGvB,iBAAA,GAAoB,GAAA,CAAA,CASpB,wBAAA,GAA2B,CAAA,CAAA,CAG3B,sBAAA,GAAyB,EAAA,CAAA,CAGzB,uBAAuB,GAAA,CAAA,CAGvB,yBAAA,GAA4B,GAAA,CAAA,CAG5B,kBAAA,GAAqB,GAAA,CAAA,CAGrB,uBAAA,GAA0B,GAO1B,0BAAA,GAA6B,CAAA,CAAA,CAc7B,oBAAA,GAA8C,MAAA,CAAO,MAAA,CAAO;AAAA,EACvE,QAAA,EAAU,CAAA;AAAA,EACV,aAAA,EAAe,EAAA;AAAA,EACf,UAAA,EAAY,GAAA;AAAA,EACZ,eAAA,EAAiB,GAAA;AAAA,EACjB,SAAA,EAAW,GAAA;AAAA,EACX,aAAA,EAAe,CAAA;AAAA,EACf,gBAAA,EAAkB;AACpB,CAAC;AAWM,SAAS,aAAA,CAAc,MAAA,GAA+B,EAAC,EAAgB;AAC5E,EAAA,IAAM,QAAA,GAAW,EAAE,GAAG,oBAAA,EAAqB;AAC3C,EAAA,KAAA,IAAW,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,oBAAoB,CAAA,EAA4B;AAC7E,IAAA,IAAM,KAAA,GAAQ,OAAO,IAAI,CAAA;AACzB,IAAI,KAAA,KAAU,MAAA,KAAW,QAAA,CAAS,IAAI,CAAA,GAAI,KAAA,CAAA;AAAA,EAC5C;AACA,EAAA,OAAO,QAAA;AACT;;;AClFA,IAAM,GAAA,mBAAM,MAAA,CAAO,GAAA,CAAI,cAAc,CAAA;AAa9B,SAAS,IAAsB,KAAA,EAAa;AACjD,EAAA,OAAA,MAAA,CAAO,cAAA,CAAe,OAAO,GAAA,EAAK,EAAE,OAAO,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,CAAA,EAC7D,KAAA;AACT;AAGO,IAAM,KAAA,GAAQ,CAAC,IAAA,KAA2B,OAAO,IAAA,IAAS,YAAY,IAAA,KAAS,IAAA,IAAS,IAAA,CAAiC,GAAG,CAAA,KAAM;;;ACRlI,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EAOvC,YAAY,IAAA,EAAwB;AAClC,IAAA,KAAA,CAAM,CAAA,UAAA,EAAa,IAAA,CAAK,MAAM,CAAA,SAAA,EAAO,IAAA,CAAK,GAAG,CAAA,GAAA,EAAM,IAAA,CAAK,IAAI,CAAA,MAAA,EAAS,IAAA,CAAK,MAAM,CAAA,EAAA,CAAI,CAAA;AANtF;AAAA,IAAA,aAAA,CAAA,IAAA,EAAS,MAAA,EAAO,4BAAA,CAAA;AAGhB;AAAA,IAAA,aAAA,CAAA,IAAA,EAAS,MAAA,CAAA;AAIP,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA,EACZ,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AACF,CAAA,CAAA,CAOa,oBAAA,GAAN,cAAmC,KAAA,CAAM;AAAA,EAI9C,WAAA,CAEW,MAAA,EAEA,SAAA,EACT,OAAA,EACA;AACA,IAAA,KAAA,CAAM,CAAA,qBAAA,EAAwB,MAAM,CAAA,sBAAA,EAAyB,SAAS,SAAS,OAAO,CAAA;AAL7E,IAAA,aAAA,CAAA,IAAA,EAAA,QAAA,EAAA,MAAA,CAAA;AAEA,IAAA,aAAA,CAAA,IAAA,EAAA,WAAA,EAAA,SAAA,CAAA;AANX;AAAA,IAAA,aAAA,CAAA,IAAA,EAAS,MAAA,EAAO,kBAAA,CAAA;AAUd,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AAAA,EACd;AACF","file":"chunk-NHNDPIPM.js","sourcesContent":["/**\n * Umumiy pagination default'lari — yagona manba. Backend adapter (`createRegistry`\n * options) va frontend (`createQuery` config) shu qiymatlarni fallback sifatida\n * ishlatadi, shuning uchun ular hech qachon bir-biridan farq qilmaydi.\n */\n\n/** Offset (list) sahifa o'lchami default'i. */\nexport const DEFAULT_PER_PAGE = 20;\n\n/** Infinite/cursor `limit` default'i. */\nexport const DEFAULT_LIMIT = 20;\n\n/**\n * `perPage` uchun yuqori chegara — cap'siz paginatsiya DoS yuzasi. Validatsiya\n * (`@querykitjs/zod` factory'lari), backend repositorylari va frontend `createQuery`\n * shu bitta qiymatga tayanadi, shuning uchun ular hech qachon farq qilmaydi.\n */\nexport const DEFAULT_MAX_PER_PAGE = 200;\n\n/** Infinite/cursor `limit` uchun yuqori chegara. Qarang: {@link DEFAULT_MAX_PER_PAGE}. */\nexport const DEFAULT_MAX_LIMIT = 200;\n\n/* ----------------------------- request limits ------------------------------ */\n/* Parse-time size limits for every filter and pagination request. The\n * validators (`@querykitjs/zod`, `@querykitjs/class-validator`) reject a payload\n * past any of them; `@querykitjs/web` refuses to build one past the offset or\n * sort limit. Raise one per schema/DTO with `limits`, never globally. */\n\n/** Longest root-to-leaf path of a filter tree, in nodes: the root is level 1, every `and`/`or`/`not` and the condition itself add one. */\nexport const DEFAULT_MAX_FILTER_DEPTH = 5;\n\n/** Field conditions (leaves) in one filter, across all groups. */\nexport const DEFAULT_MAX_CONDITIONS = 30;\n\n/** Items in one array filter value (`in`, `notIn`, …). */\nexport const DEFAULT_MAX_IN_ITEMS = 200;\n\n/** Characters in one string filter value, also inside an array value. */\nexport const DEFAULT_MAX_STRING_LENGTH = 256;\n\n/** Rows skipped before a page: `(page - 1) × perPage` for offset pagination, `offset` for infinite. Deeper pages need a cursor. */\nexport const DEFAULT_MAX_OFFSET = 10_000;\n\n/** Fields in one `sort` array. */\nexport const DEFAULT_MAX_SORT_FIELDS = 3;\n\n/**\n * Wildcards (`%`, `_`) in one `like` / `ilike` / `notLike` pattern, after a run\n * of `%` counts as one. Each extra wildcard multiplies the matcher's backtracking\n * (`%a%a%a…%b`), on MongoDB's regex engine and on Postgres alike.\n */\nexport const DEFAULT_MAX_LIKE_WILDCARDS = 2;\n\n/** The six request limits, by the option name every package uses. */\nexport interface QueryLimits {\n maxDepth: number;\n maxConditions: number;\n maxInItems: number;\n maxStringLength: number;\n maxOffset: number;\n maxSortFields: number;\n maxLikeWildcards: number;\n}\n\n/** The core defaults as one object. */\nexport const DEFAULT_QUERY_LIMITS: Readonly<QueryLimits> = Object.freeze({\n maxDepth: DEFAULT_MAX_FILTER_DEPTH,\n maxConditions: DEFAULT_MAX_CONDITIONS,\n maxInItems: DEFAULT_MAX_IN_ITEMS,\n maxStringLength: DEFAULT_MAX_STRING_LENGTH,\n maxOffset: DEFAULT_MAX_OFFSET,\n maxSortFields: DEFAULT_MAX_SORT_FIELDS,\n maxLikeWildcards: DEFAULT_MAX_LIKE_WILDCARDS,\n});\n\n/**\n * The defaults with the given limits on top; an `undefined` entry keeps the\n * default. `Infinity` turns a limit off (⚠️ a DoS surface).\n *\n * @example\n * ```ts\n * resolveLimits({ maxInItems: 50 }); // { maxDepth: 5, …, maxInItems: 50, … }\n * ```\n */\nexport function resolveLimits(limits: Partial<QueryLimits> = {}): QueryLimits {\n const resolved = { ...DEFAULT_QUERY_LIMITS };\n for (const name of Object.keys(DEFAULT_QUERY_LIMITS) as (keyof QueryLimits)[]) {\n const value = limits[name];\n if (value !== undefined) resolved[name] = value;\n }\n return resolved;\n}\n","/**\n * The branded raw-filter escape hatch (REQUIREMENTS R19). A driver's own `where`\n * object (Prisma `where`, Mongo filter) is accepted inside a querykit filter only\n * when server code wraps it in `raw(...)`: the brand is a `Symbol`, which no JSON\n * body can carry. An unbranded plain object is refused (`forbidden-key`).\n *\n * ⚠️ A raw node is server code — the `filterable` policy does **not** look inside it.\n * Never build one from request data.\n */\nconst RAW = Symbol.for(\"querykit.raw\");\n\n/**\n * Brand a driver-native filter object so an adapter accepts it as a filter node.\n * The object itself is returned (non-enumerable brand), so the driver receives\n * exactly what you wrote.\n *\n * @example\n * ```ts\n * import { raw } from \"@querykitjs/core\";\n * repo.findAll({ filter: { and: [{ key: \"status\", value: \"active\" }, raw({ posts: { some: { published: true } } })] } });\n * ```\n */\nexport function raw<T extends object>(value: T): T {\n Object.defineProperty(value, RAW, { value: true, enumerable: false });\n return value;\n}\n\n/** Whether a filter node was branded with {@link raw}. */\nexport const isRaw = (node: unknown): boolean => typeof node === \"object\" && node !== null && (node as Record<symbol, unknown>)[RAW] === true;\n","/**\n * querykit xatolari. Backend adapterlari (`drizzle-pg`, `mongoose`) `strict`\n * rejimda shu bitta klassni tashlaydi — ya'ni ikkala backend uchun xatoni\n * ushlash usuli bir xil.\n */\nimport type { SkippedCondition } from \"./types\";\n\n/**\n * `strict` rejimda noto'g'ri so'rov shartida tashlanadi (noma'lum kalit yoki\n * operatorga mos kelmagan qiymat). Backend'da 400 qilib qaytarish uchun:\n *\n * ```ts\n * try {\n * return await usersRepository.findList(params);\n * } catch (err) {\n * if (err instanceof QueryKitError) return c.json({ error: err.message }, 400);\n * throw err;\n * }\n * ```\n */\nexport class QueryKitError extends Error {\n /** Barqaror kod — `instanceof` ishlamaydigan chegaralarda (RPC, worker) tekshirish uchun. */\n readonly code = \"QUERYKIT_INVALID_CONDITION\";\n\n /** Tashlab yuborilgan shart haqida to'liq ma'lumot (hook argumenti bilan bir xil shakl). */\n readonly info: SkippedCondition;\n\n constructor(info: SkippedCondition) {\n super(`querykit: ${info.reason} — \"${info.key}\" (${info.site}) on \"${info.source}\".`);\n this.name = \"QueryKitError\";\n this.info = info;\n }\n}\n\n/**\n * A read ran past its time limit (`maxTimeMS` on MongoDB). Kept apart from\n * {@link QueryKitError}: the request was valid, the database was slow — map it to\n * 503 / 504, not 400.\n */\nexport class QueryKitTimeoutError extends Error {\n /** Stable code for boundaries where `instanceof` does not work. */\n readonly code = \"QUERYKIT_TIMEOUT\";\n\n constructor(\n /** Collection / model name. */\n readonly source: string,\n /** The limit that was hit, in milliseconds. */\n readonly maxTimeMS: number,\n options?: { cause?: unknown },\n ) {\n super(`querykit: a read on \"${source}\" ran past maxTimeMS (${maxTimeMS} ms).`, options);\n this.name = \"QueryKitTimeoutError\";\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/defaults.ts","../src/raw.ts","../src/errors.ts"],"names":[],"mappings":";;;;;;;AAOO,IAAM,gBAAA,GAAmB,EAAA,CAAA,CAGnB,aAAA,GAAgB,EAAA,CAAA,CAOhB,oBAAA,GAAuB,KAGvB,iBAAA,GAAoB,GAAA,CAAA,CASpB,wBAAA,GAA2B,CAAA,CAAA,CAG3B,sBAAA,GAAyB,EAAA,CAAA,CAGzB,uBAAuB,GAAA,CAAA,CAGvB,yBAAA,GAA4B,GAAA,CAAA,CAG5B,kBAAA,GAAqB,GAAA,CAAA,CAGrB,uBAAA,GAA0B,GAO1B,0BAAA,GAA6B,CAAA,CAAA,CAc7B,oBAAA,GAA8C,MAAA,CAAO,MAAA,CAAO;AAAA,EACvE,QAAA,EAAU,CAAA;AAAA,EACV,aAAA,EAAe,EAAA;AAAA,EACf,UAAA,EAAY,GAAA;AAAA,EACZ,eAAA,EAAiB,GAAA;AAAA,EACjB,SAAA,EAAW,GAAA;AAAA,EACX,aAAA,EAAe,CAAA;AAAA,EACf,gBAAA,EAAkB;AACpB,CAAC;AAWM,SAAS,aAAA,CAAc,MAAA,GAA+B,EAAC,EAAgB;AAC5E,EAAA,IAAM,QAAA,GAAW,EAAE,GAAG,oBAAA,EAAqB;AAC3C,EAAA,KAAA,IAAW,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,oBAAoB,CAAA,EAA4B;AAC7E,IAAA,IAAM,KAAA,GAAQ,OAAO,IAAI,CAAA;AACzB,IAAI,KAAA,KAAU,MAAA,KAAW,QAAA,CAAS,IAAI,CAAA,GAAI,KAAA,CAAA;AAAA,EAC5C;AACA,EAAA,OAAO,QAAA;AACT;;;AClFA,IAAM,GAAA,mBAAM,MAAA,CAAO,GAAA,CAAI,cAAc,CAAA;AAa9B,SAAS,IAAsB,KAAA,EAAa;AACjD,EAAA,OAAA,MAAA,CAAO,cAAA,CAAe,OAAO,GAAA,EAAK,EAAE,OAAO,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,CAAA,EAC7D,KAAA;AACT;AAGO,IAAM,KAAA,GAAQ,CAAC,IAAA,KAA2B,OAAO,IAAA,IAAS,YAAY,IAAA,KAAS,IAAA,IAAS,IAAA,CAAiC,GAAG,CAAA,KAAM;;;ACRlI,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EAOvC,YAAY,IAAA,EAAwB;AAClC,IAAA,KAAA,CAAM,CAAA,UAAA,EAAa,IAAA,CAAK,MAAM,CAAA,SAAA,EAAO,IAAA,CAAK,GAAG,CAAA,GAAA,EAAM,IAAA,CAAK,IAAI,CAAA,MAAA,EAAS,IAAA,CAAK,MAAM,CAAA,EAAA,CAAI,CAAA;AANtF;AAAA,IAAA,aAAA,CAAA,IAAA,EAAS,MAAA,EAAO,4BAAA,CAAA;AAGhB;AAAA,IAAA,aAAA,CAAA,IAAA,EAAS,MAAA,CAAA;AAIP,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA,EACZ,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AACF,CAAA,CAAA,CAOa,oBAAA,GAAN,cAAmC,KAAA,CAAM;AAAA,EAI9C,WAAA,CAEW,MAAA,EAEA,SAAA,EACT,OAAA,EACA;AACA,IAAA,KAAA,CAAM,CAAA,qBAAA,EAAwB,MAAM,CAAA,sBAAA,EAAyB,SAAS,SAAS,OAAO,CAAA;AAL7E,IAAA,aAAA,CAAA,IAAA,EAAA,QAAA,EAAA,MAAA,CAAA;AAEA,IAAA,aAAA,CAAA,IAAA,EAAA,WAAA,EAAA,SAAA,CAAA;AANX;AAAA,IAAA,aAAA,CAAA,IAAA,EAAS,MAAA,EAAO,kBAAA,CAAA;AAUd,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AAAA,EACd;AACF","file":"chunk-VD7XT52J.cjs","sourcesContent":["/**\n * Umumiy pagination default'lari — yagona manba. Backend adapter (`createRegistry`\n * options) va frontend (`createQuery` config) shu qiymatlarni fallback sifatida\n * ishlatadi, shuning uchun ular hech qachon bir-biridan farq qilmaydi.\n */\n\n/** Offset (list) sahifa o'lchami default'i. */\nexport const DEFAULT_PER_PAGE = 20;\n\n/** Infinite/cursor `limit` default'i. */\nexport const DEFAULT_LIMIT = 20;\n\n/**\n * `perPage` uchun yuqori chegara — cap'siz paginatsiya DoS yuzasi. Validatsiya\n * (`@querykitjs/zod` factory'lari), backend repositorylari va frontend `createQuery`\n * shu bitta qiymatga tayanadi, shuning uchun ular hech qachon farq qilmaydi.\n */\nexport const DEFAULT_MAX_PER_PAGE = 200;\n\n/** Infinite/cursor `limit` uchun yuqori chegara. Qarang: {@link DEFAULT_MAX_PER_PAGE}. */\nexport const DEFAULT_MAX_LIMIT = 200;\n\n/* ----------------------------- request limits ------------------------------ */\n/* Parse-time size limits for every filter and pagination request. The\n * validators (`@querykitjs/zod`, `@querykitjs/class-validator`) reject a payload\n * past any of them; `@querykitjs/web` refuses to build one past the offset or\n * sort limit. Raise one per schema/DTO with `limits`, never globally. */\n\n/** Longest root-to-leaf path of a filter tree, in nodes: the root is level 1, every `and`/`or`/`not` and the condition itself add one. */\nexport const DEFAULT_MAX_FILTER_DEPTH = 5;\n\n/** Field conditions (leaves) in one filter, across all groups. */\nexport const DEFAULT_MAX_CONDITIONS = 30;\n\n/** Items in one array filter value (`in`, `notIn`, …). */\nexport const DEFAULT_MAX_IN_ITEMS = 200;\n\n/** Characters in one string filter value, also inside an array value. */\nexport const DEFAULT_MAX_STRING_LENGTH = 256;\n\n/** Rows skipped before a page: `(page - 1) × perPage` for offset pagination, `offset` for infinite. Deeper pages need a cursor. */\nexport const DEFAULT_MAX_OFFSET = 10_000;\n\n/** Fields in one `sort` array. */\nexport const DEFAULT_MAX_SORT_FIELDS = 3;\n\n/**\n * Wildcards (`%`, `_`) in one `like` / `ilike` / `notLike` pattern, after a run\n * of `%` counts as one. Each extra wildcard multiplies the matcher's backtracking\n * (`%a%a%a…%b`), on MongoDB's regex engine and on Postgres alike.\n */\nexport const DEFAULT_MAX_LIKE_WILDCARDS = 2;\n\n/** The six request limits, by the option name every package uses. */\nexport interface QueryLimits {\n maxDepth: number;\n maxConditions: number;\n maxInItems: number;\n maxStringLength: number;\n maxOffset: number;\n maxSortFields: number;\n maxLikeWildcards: number;\n}\n\n/** The core defaults as one object. */\nexport const DEFAULT_QUERY_LIMITS: Readonly<QueryLimits> = Object.freeze({\n maxDepth: DEFAULT_MAX_FILTER_DEPTH,\n maxConditions: DEFAULT_MAX_CONDITIONS,\n maxInItems: DEFAULT_MAX_IN_ITEMS,\n maxStringLength: DEFAULT_MAX_STRING_LENGTH,\n maxOffset: DEFAULT_MAX_OFFSET,\n maxSortFields: DEFAULT_MAX_SORT_FIELDS,\n maxLikeWildcards: DEFAULT_MAX_LIKE_WILDCARDS,\n});\n\n/**\n * The defaults with the given limits on top; an `undefined` entry keeps the\n * default. `Infinity` turns a limit off (⚠️ a DoS surface).\n *\n * @example\n * ```ts\n * resolveLimits({ maxInItems: 50 }); // { maxDepth: 5, …, maxInItems: 50, … }\n * ```\n */\nexport function resolveLimits(limits: Partial<QueryLimits> = {}): QueryLimits {\n const resolved = { ...DEFAULT_QUERY_LIMITS };\n for (const name of Object.keys(DEFAULT_QUERY_LIMITS) as (keyof QueryLimits)[]) {\n const value = limits[name];\n if (value !== undefined) resolved[name] = value;\n }\n return resolved;\n}\n","/**\n * The branded raw-filter escape hatch (REQUIREMENTS R19). A driver's own `where`\n * object (Prisma `where`, Mongo filter) is accepted inside a querykit filter only\n * when server code wraps it in `raw(...)`: the brand is a `Symbol`, which no JSON\n * body can carry. An unbranded plain object is refused (`forbidden-key`).\n *\n * ⚠️ A raw node is server code — the `filterable` policy does **not** look inside it.\n * Never build one from request data.\n */\nconst RAW = Symbol.for(\"querykit.raw\");\n\n/**\n * Brand a driver-native filter object so an adapter accepts it as a filter node.\n * The object itself is returned (non-enumerable brand), so the driver receives\n * exactly what you wrote.\n *\n * @example\n * ```ts\n * import { raw } from \"@querykitjs/core\";\n * repo.findAll({ filter: { and: [{ key: \"status\", value: \"active\" }, raw({ posts: { some: { published: true } } })] } });\n * ```\n */\nexport function raw<T extends object>(value: T): T {\n Object.defineProperty(value, RAW, { value: true, enumerable: false });\n return value;\n}\n\n/** Whether a filter node was branded with {@link raw}. */\nexport const isRaw = (node: unknown): boolean => typeof node === \"object\" && node !== null && (node as Record<symbol, unknown>)[RAW] === true;\n","/**\n * querykit xatolari. Backend adapterlari (`drizzle-pg`, `mongoose`) `strict`\n * rejimda shu bitta klassni tashlaydi — ya'ni ikkala backend uchun xatoni\n * ushlash usuli bir xil.\n */\nimport type { SkippedCondition } from \"./types\";\n\n/**\n * `strict` rejimda noto'g'ri so'rov shartida tashlanadi (noma'lum kalit yoki\n * operatorga mos kelmagan qiymat). Backend'da 400 qilib qaytarish uchun:\n *\n * ```ts\n * try {\n * return await usersRepository.findList(params);\n * } catch (err) {\n * if (err instanceof QueryKitError) return c.json({ error: err.message }, 400);\n * throw err;\n * }\n * ```\n */\nexport class QueryKitError extends Error {\n /** Barqaror kod — `instanceof` ishlamaydigan chegaralarda (RPC, worker) tekshirish uchun. */\n readonly code = \"QUERYKIT_INVALID_CONDITION\";\n\n /** Tashlab yuborilgan shart haqida to'liq ma'lumot (hook argumenti bilan bir xil shakl). */\n readonly info: SkippedCondition;\n\n constructor(info: SkippedCondition) {\n super(`querykit: ${info.reason} — \"${info.key}\" (${info.site}) on \"${info.source}\".`);\n this.name = \"QueryKitError\";\n this.info = info;\n }\n}\n\n/**\n * A read ran past its time limit (`maxTimeMS` on MongoDB). Kept apart from\n * {@link QueryKitError}: the request was valid, the database was slow — map it to\n * 503 / 504, not 400.\n */\nexport class QueryKitTimeoutError extends Error {\n /** Stable code for boundaries where `instanceof` does not work. */\n readonly code = \"QUERYKIT_TIMEOUT\";\n\n constructor(\n /** Collection / model name. */\n readonly source: string,\n /** The limit that was hit, in milliseconds. */\n readonly maxTimeMS: number,\n options?: { cause?: unknown },\n ) {\n super(`querykit: a read on \"${source}\" ran past maxTimeMS (${maxTimeMS} ms).`, options);\n this.name = \"QueryKitTimeoutError\";\n }\n}\n"]}
|