@querykitjs/core 1.2.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/README.en.md +36 -0
- package/README.md +36 -0
- package/dist/chunk-72KNINHB.cjs +118 -0
- package/dist/chunk-72KNINHB.cjs.map +1 -0
- package/dist/chunk-XEETYJA3.js +98 -0
- package/dist/chunk-XEETYJA3.js.map +1 -0
- package/dist/index.cjs +74 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -173
- package/dist/index.d.ts +23 -173
- package/dist/index.js +3 -69
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +507 -0
- package/dist/internal.cjs.map +1 -0
- package/dist/internal.d.cts +376 -0
- package/dist/internal.d.ts +376 -0
- package/dist/internal.js +470 -0
- package/dist/internal.js.map +1 -0
- package/dist/raw-AiElbDzC.d.cts +290 -0
- package/dist/raw-AiElbDzC.d.ts +290 -0
- package/package.json +32 -6
- package/skills/querykit-core/SKILL.md +160 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import { SkippedCondition, SortDirection, Sort, CursorMeta, InfiniteMeta, OffsetMeta, Relations, QueryLimits, Filterable, FilterOperator } from './index.js';
|
|
2
|
+
export { Z as isRaw } from './raw-AiElbDzC.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Opaque cursor tokens for keyset pagination, shared by every adapter so a token
|
|
6
|
+
* is interchangeable between them. A token is the base64url encoding of
|
|
7
|
+
* `{ v: <cursor value> }`; dates travel as ISO strings.
|
|
8
|
+
*/
|
|
9
|
+
declare function encodeCursor(value: unknown): string;
|
|
10
|
+
/** The cursor value, or `undefined` for a missing or undecodable token. */
|
|
11
|
+
declare function decodeCursor(cursor?: string | null): unknown | undefined;
|
|
12
|
+
interface CursorToken {
|
|
13
|
+
k: string | number | boolean;
|
|
14
|
+
id: string | number | boolean;
|
|
15
|
+
}
|
|
16
|
+
/** A v2 token for a row's cursor value and primary key; signed when `secret` is given. */
|
|
17
|
+
declare function encodeCursorToken(payload: {
|
|
18
|
+
k: unknown;
|
|
19
|
+
id: unknown;
|
|
20
|
+
}, secret?: string): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* The `{ k, id }` of a v2 token, `undefined` for no token. A v1 token, a
|
|
23
|
+
* non-scalar `k` / `id`, a missing or wrong signature (with `secret`) or
|
|
24
|
+
* anything undecodable throws `QueryKitError` — invalid-value, site cursorKey,
|
|
25
|
+
* `key` the cursor key in use (the same key as an adapter's cast error).
|
|
26
|
+
*/
|
|
27
|
+
declare function decodeCursorToken(token: string | null | undefined, options: {
|
|
28
|
+
source: string;
|
|
29
|
+
secret?: string;
|
|
30
|
+
key?: string;
|
|
31
|
+
}): Promise<CursorToken | undefined>;
|
|
32
|
+
|
|
33
|
+
interface Diagnostics {
|
|
34
|
+
/** Table (drizzle), model (prisma, mongoose) — reported as `source`. */
|
|
35
|
+
source: string;
|
|
36
|
+
strict: boolean;
|
|
37
|
+
onSkipped?: (info: SkippedCondition) => void;
|
|
38
|
+
}
|
|
39
|
+
declare function reportSkip(diag: Diagnostics | undefined, info: Omit<SkippedCondition, "source">): void;
|
|
40
|
+
|
|
41
|
+
interface ContextStore<TContext extends object> {
|
|
42
|
+
get(): TContext | undefined;
|
|
43
|
+
/** Run `fn` with `patch` merged over the current context. */
|
|
44
|
+
run<T>(patch: TContext, fn: () => T): T;
|
|
45
|
+
}
|
|
46
|
+
declare function createContextStore<TContext extends object>(): ContextStore<TContext>;
|
|
47
|
+
|
|
48
|
+
interface NormalizedSortItem {
|
|
49
|
+
key: string;
|
|
50
|
+
direction: SortDirection;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The wire `sort` array with a direction on every item. An item without a `key`
|
|
54
|
+
* (`null`, `{}`) is dropped — sort comes from the client, and a malformed item
|
|
55
|
+
* must not crash the query — and, with `diag`, reported as `invalid-value` on
|
|
56
|
+
* `site: "sort"` (a `QueryKitError` under strict).
|
|
57
|
+
*/
|
|
58
|
+
declare function normalizeSort(sort?: Sort, diag?: Diagnostics): NormalizedSortItem[];
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Page-size clamping and the three pagination metas, computed once for every
|
|
62
|
+
* adapter so `total_pages`, `has_more`, `next_cursor` … mean the same thing on
|
|
63
|
+
* all of them. Adapters only fetch rows; these functions turn rows into a page.
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/** A requested page size, defaulted, truncated, at least 1 and at most `max`. */
|
|
67
|
+
declare function clampPageSize(requested: number | undefined, fallback: number, max: number): number;
|
|
68
|
+
/** A requested page number: an integer, at least 1. */
|
|
69
|
+
declare function clampPage(requested: number | undefined): number;
|
|
70
|
+
/** A requested offset: an integer, at least 0. */
|
|
71
|
+
declare function clampOffset(requested: number | undefined): number;
|
|
72
|
+
declare function offsetMeta(page: number, perPage: number, totalItems: number): OffsetMeta;
|
|
73
|
+
/**
|
|
74
|
+
* `withTotal: false`: rows fetched with `perPage + 1` and no count →
|
|
75
|
+
* the page and its meta; the extra row only signals `has_next`, totals are `null`.
|
|
76
|
+
*/
|
|
77
|
+
declare function offsetPageWithoutTotal<T>(rows: readonly T[], page: number, perPage: number): {
|
|
78
|
+
data: T[];
|
|
79
|
+
meta: OffsetMeta;
|
|
80
|
+
};
|
|
81
|
+
/** Rows fetched with `limit + 1` → the page and its meta (the extra row only signals `has_more`). */
|
|
82
|
+
declare function infinitePage<T>(rows: readonly T[], limit: number, offset: number): {
|
|
83
|
+
data: T[];
|
|
84
|
+
meta: InfiniteMeta;
|
|
85
|
+
};
|
|
86
|
+
interface CursorPageOptions {
|
|
87
|
+
limit: number;
|
|
88
|
+
direction: "forward" | "backward";
|
|
89
|
+
/** A cursor was supplied (the request continues from a previous page). */
|
|
90
|
+
hasCursor: boolean;
|
|
91
|
+
/** The row field the tokens are read from. */
|
|
92
|
+
cursorField: string;
|
|
93
|
+
/** The primary-key field — the tie-break value in every token. */
|
|
94
|
+
idField: string;
|
|
95
|
+
/** Signs the tokens (registry `cursorSecret`). */
|
|
96
|
+
secret?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Rows fetched with `limit + 1` in query order → the page in display order and
|
|
100
|
+
* its meta. A backward page is fetched reversed and flipped back here.
|
|
101
|
+
*/
|
|
102
|
+
declare function cursorPage<T extends Record<string, unknown>>(rows: readonly T[], options: CursorPageOptions): Promise<{
|
|
103
|
+
data: T[];
|
|
104
|
+
meta: CursorMeta;
|
|
105
|
+
}>;
|
|
106
|
+
|
|
107
|
+
/** `{ all: true }` — and nothing else — asks for every row (the scope still applies). */
|
|
108
|
+
declare function isAllRows(filter: unknown): boolean;
|
|
109
|
+
/** `undefined`, `null`, `[]` or `{}`: no condition at all. */
|
|
110
|
+
declare function isEmptyFilter(filter: unknown): boolean;
|
|
111
|
+
/** A mutation without a condition — also one whose every condition was skipped. */
|
|
112
|
+
declare function refuseEmptyFilter(source: string, method: "updateWhere" | "deleteWhere"): never;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* A repository `scope` (the server's RBAC / tenancy filter) split once for every
|
|
116
|
+
* adapter: equality values and `{ in: [...] }` lists.
|
|
117
|
+
*/
|
|
118
|
+
/** One scope condition, in the shape every adapter's `buildWhere` reads. */
|
|
119
|
+
interface ScopeCondition {
|
|
120
|
+
key: string;
|
|
121
|
+
operation: "=" | "in";
|
|
122
|
+
value: unknown;
|
|
123
|
+
}
|
|
124
|
+
/** The scope as conditions: `{ k: v }` → `k = v`, `{ k: { in: [...] } }` → `k in [...]`. */
|
|
125
|
+
declare function scopeConditions(scope: Record<string, unknown> | undefined): ScopeCondition[];
|
|
126
|
+
/** The values `create` / `upsert` fill in: the equality scopes only (a list has no single value). */
|
|
127
|
+
declare function scopeDefaults(scope: Record<string, unknown> | undefined): Record<string, unknown>;
|
|
128
|
+
|
|
129
|
+
/** How one adapter spells a relation's options. */
|
|
130
|
+
interface WithDialect {
|
|
131
|
+
/** Column selection: drizzle `columns`, prisma / mongoose `select`. */
|
|
132
|
+
columns: string;
|
|
133
|
+
/** Nested relations: drizzle `with`, prisma `include`, mongoose `populate`. */
|
|
134
|
+
nested: string;
|
|
135
|
+
/** Row filters: prisma `where`, mongoose `match`; drizzle none (its `where` is code, not JSON). */
|
|
136
|
+
filters: readonly string[];
|
|
137
|
+
/** Logical keys inside a filter, walked into: prisma `AND` / `OR` / `NOT`, mongoose `$and` / `$or` / `$nor`. */
|
|
138
|
+
logical: readonly string[];
|
|
139
|
+
/** Options that only page: drizzle `limit` / `offset`, prisma `take` / `skip`, mongoose `options.limit` / `options.skip`. */
|
|
140
|
+
paging: readonly string[];
|
|
141
|
+
/** A sort whose keys must be allowed columns: prisma `orderBy`. */
|
|
142
|
+
orderBy?: string;
|
|
143
|
+
/** An options bag whose keys must be `paging` keys: mongoose `options`. */
|
|
144
|
+
options?: string;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The checked `with`: every relation in `relations`, every selected column in its
|
|
148
|
+
* `columns`, every filter field in its `filterable`, every nested relation in its
|
|
149
|
+
* `nested`. A relation asked for with `true` (or without a selection) gets its
|
|
150
|
+
* listed columns selected, so a column list is never widened to the full row.
|
|
151
|
+
*/
|
|
152
|
+
declare function checkWith(withValue: unknown, relations: Relations | undefined, dialect: WithDialect, source: string, path?: string): Record<string, unknown> | undefined;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* The filter-limit walk shared by the validators. It runs on the raw,
|
|
156
|
+
* unvalidated payload **before** any recursive schema sees it, so it is
|
|
157
|
+
* iterative — no recursion at all, whatever the payload's depth — and a
|
|
158
|
+
* 10 000-level `not` chain is rejected after `maxDepth + 1` steps.
|
|
159
|
+
*
|
|
160
|
+
* Only size is judged here. Shape errors (a missing `key`, a bad operator) are
|
|
161
|
+
* the validator's job — a malformed node is skipped, not reported.
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
/** Where in the filter a limit was crossed — object keys and array indexes, from the root. */
|
|
165
|
+
type LimitPath = (string | number)[];
|
|
166
|
+
interface LimitViolation {
|
|
167
|
+
limit: keyof QueryLimits;
|
|
168
|
+
max: number;
|
|
169
|
+
path: LimitPath;
|
|
170
|
+
}
|
|
171
|
+
/** The limits the walk checks. */
|
|
172
|
+
type FilterLimits = Pick<QueryLimits, "maxDepth" | "maxConditions" | "maxInItems" | "maxStringLength">;
|
|
173
|
+
/** `maxInItems (200)` — the form every package's error text uses. */
|
|
174
|
+
declare const formatLimit: (limit: keyof QueryLimits, max: number) => string;
|
|
175
|
+
/**
|
|
176
|
+
* The first limit the filter crosses, depth-first in document order, or
|
|
177
|
+
* `undefined` when it is within all four. A flat array (implicit AND) puts its
|
|
178
|
+
* conditions at level 1. Key order mirrors the validators: `key` first, then
|
|
179
|
+
* `and`, `or`, `not`.
|
|
180
|
+
*/
|
|
181
|
+
declare function findFilterLimitViolation(filter: unknown, limits: FilterLimits): LimitViolation | undefined;
|
|
182
|
+
/** Whether an operator takes a SQL LIKE pattern. */
|
|
183
|
+
declare const isLikeOperator: (operation: string) => boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Unescaped wildcards in a LIKE pattern, a run of `%` counted once (`%%a%` ⇒ 2).
|
|
186
|
+
* A backslash escapes the next character, as in the adapters' LIKE translation.
|
|
187
|
+
*/
|
|
188
|
+
declare function likeWildcards(pattern: string): number;
|
|
189
|
+
/** Rows an offset-paginated request skips: `(page - 1) × perPage`, with the core default page size. */
|
|
190
|
+
declare const offsetOf: (page: number | undefined, perPage: number | undefined) => number;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* The server-side request policy every adapter applies: which fields
|
|
194
|
+
* a client may filter by and with which operators (`filterable`), which it may
|
|
195
|
+
* sort and page by (`sortable`), and the request limits (`limits`).
|
|
196
|
+
*
|
|
197
|
+
* A plain object that is not a condition, a group, a branded `raw()` node or a
|
|
198
|
+
* driver-native object (`isNative`) is refused as well (R19): it would otherwise
|
|
199
|
+
* reach the driver as its own `where`, past `filterable`.
|
|
200
|
+
*
|
|
201
|
+
* A refused request never reaches the driver and is never dropped silently:
|
|
202
|
+
* every check throws `QueryKitError`, whatever `strict` / `onSkippedCondition`
|
|
203
|
+
* say. A key the model does not have is **not** the policy's business — it goes
|
|
204
|
+
* on to the adapter's own `unknown-key` handling, unchanged.
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
interface PolicyOptions {
|
|
208
|
+
/** Table / model name for the error. */
|
|
209
|
+
source: string;
|
|
210
|
+
/** Wire key → the model's canonical field name, or `undefined` when the model has no such field. */
|
|
211
|
+
fieldOf: (key: string) => string | undefined;
|
|
212
|
+
/** Canonical primary-key field — the last-resort safe default. */
|
|
213
|
+
primaryKey: string;
|
|
214
|
+
/** Canonical `createdAt` field when the model has one (default `sortable`). */
|
|
215
|
+
createdAt?: string;
|
|
216
|
+
filterable?: Filterable;
|
|
217
|
+
sortable?: readonly string[];
|
|
218
|
+
allowedColumns?: readonly string[];
|
|
219
|
+
forcedColumns?: Readonly<Record<string, unknown>>;
|
|
220
|
+
limits?: Partial<QueryLimits>;
|
|
221
|
+
/**
|
|
222
|
+
* A driver object that cannot come from JSON and stands for itself (drizzle `SQL`).
|
|
223
|
+
* Anything else that is not a condition, a group or a {@link isRaw} node is refused (R19).
|
|
224
|
+
*/
|
|
225
|
+
isNative?: (node: object) => boolean;
|
|
226
|
+
}
|
|
227
|
+
interface Policy {
|
|
228
|
+
readonly limits: QueryLimits;
|
|
229
|
+
/** Limits, then every condition's field and operator. */
|
|
230
|
+
checkFilter(filter: unknown): void;
|
|
231
|
+
/** Field count, then every sort field. */
|
|
232
|
+
checkSort(sort: readonly {
|
|
233
|
+
key?: unknown;
|
|
234
|
+
}[] | undefined): void;
|
|
235
|
+
checkCursorKey(key: string): void;
|
|
236
|
+
/** Offset pagination: the clamped `page` × `perPage`. Infinite: the clamped `offset`. */
|
|
237
|
+
checkPage(page: {
|
|
238
|
+
page: number;
|
|
239
|
+
perPage: number;
|
|
240
|
+
} | {
|
|
241
|
+
offset: number;
|
|
242
|
+
}): void;
|
|
243
|
+
/** A `groupBy` / `sum` / `avg` / `min` / `max` field must be filterable. */
|
|
244
|
+
checkAggregateKey(key: string): void;
|
|
245
|
+
}
|
|
246
|
+
declare function resolvePolicy(options: PolicyOptions): Policy;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Wire-contract checks for validator authors: the filter, the sort and the
|
|
250
|
+
* pagination params exactly as they arrive from JSON. Framework-free and
|
|
251
|
+
* text-free — an issue carries a path, a message key and its arguments; each
|
|
252
|
+
* validator renders its own message. The size walk runs first, iteratively, so
|
|
253
|
+
* an oversized payload never reaches the recursive shape check.
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
type WireFilterIssueKey = "querykit.filter.invalid_node" | "querykit.filter.missing_key" | "querykit.filter.unknown_key" | "querykit.filter.invalid_operator" | "querykit.filter.invalid_value" | "querykit.filter.invalid_group" | "querykit.filter.max_depth" | "querykit.filter.value_requires_array" | "querykit.filter.value_requires_tuple" | "querykit.filter.value_forbidden" | "querykit.limit.exceeded";
|
|
257
|
+
type WireSortIssueKey = "querykit.sort.not_array" | "querykit.sort.invalid_item" | "querykit.sort.missing_key" | "querykit.sort.unknown_key" | "querykit.sort.invalid_direction" | "querykit.limit.exceeded";
|
|
258
|
+
type WireParamsIssueKey = "querykit.params.invalid_type" | "querykit.params.not_integer" | "querykit.params.out_of_range" | "querykit.params.invalid_enum";
|
|
259
|
+
type WireIssueKey = WireFilterIssueKey | WireSortIssueKey | WireParamsIssueKey;
|
|
260
|
+
/** Message arguments: strings and numbers only, so any message catalog can interpolate them. */
|
|
261
|
+
type WireIssueArgs = Record<string, string | number>;
|
|
262
|
+
/** One rejected spot: object keys and array indexes from the checked value, the message key and its arguments. */
|
|
263
|
+
interface WireIssue<TKey extends WireIssueKey = WireIssueKey> {
|
|
264
|
+
path: LimitPath;
|
|
265
|
+
key: TKey;
|
|
266
|
+
args: WireIssueArgs;
|
|
267
|
+
}
|
|
268
|
+
interface WireFilterOptions extends Partial<Pick<QueryLimits, "maxDepth" | "maxConditions" | "maxInItems" | "maxStringLength">> {
|
|
269
|
+
/** Only these keys may be filtered on; another key is an issue. Absent — any string key. */
|
|
270
|
+
allowedKeys?: readonly string[];
|
|
271
|
+
/** Absent — every core operator. */
|
|
272
|
+
allowedOperators?: readonly FilterOperator[];
|
|
273
|
+
/** `in`/`notIn` need an array, `between`/`notBetween` exactly two values, `isNull`/`isNotNull` no value. */
|
|
274
|
+
strictValue?: boolean;
|
|
275
|
+
}
|
|
276
|
+
interface WireSortOptions extends Partial<Pick<QueryLimits, "maxSortFields">> {
|
|
277
|
+
/** Only these keys may be sorted on. */
|
|
278
|
+
allowedKeys?: readonly string[];
|
|
279
|
+
}
|
|
280
|
+
/** Request fields only the server may set; a client sends them only where `allow` opens them. */
|
|
281
|
+
type WireServerOwnedField = "columns" | "with" | "withDeleted";
|
|
282
|
+
/** The same names and defaults as the `@querykitjs/zod` params factories. */
|
|
283
|
+
interface WireParamsOptions {
|
|
284
|
+
/** Default `DEFAULT_MAX_PER_PAGE` (200). */
|
|
285
|
+
maxPerPage?: number;
|
|
286
|
+
/** Default `DEFAULT_MAX_LIMIT` (200). */
|
|
287
|
+
maxLimit?: number;
|
|
288
|
+
limits?: Partial<QueryLimits>;
|
|
289
|
+
allow?: readonly WireServerOwnedField[];
|
|
290
|
+
}
|
|
291
|
+
type WireParamsKind = "offset" | "infinite" | "cursor";
|
|
292
|
+
interface WireParamsResult {
|
|
293
|
+
/** The accepted fields only (unknown and closed server-owned fields stripped); absent when there are issues. */
|
|
294
|
+
value?: Record<string, unknown>;
|
|
295
|
+
issues: WireIssue[];
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Checks a wire filter (a node, or a flat array as an implicit AND). An empty
|
|
299
|
+
* list means valid; `undefined` is valid. A crossed size limit is the only issue.
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```ts
|
|
303
|
+
* checkFilter({ key: "age", operation: "~" }); // [{ path: ["operation"], key: "querykit.filter.invalid_operator", args: { operation: "~" } }]
|
|
304
|
+
* ```
|
|
305
|
+
*/
|
|
306
|
+
declare function checkFilter(value: unknown, options?: WireFilterOptions): WireIssue<WireFilterIssueKey>[];
|
|
307
|
+
/** Checks a wire sort, `{ key, direction }[]`. An empty list means valid; `undefined` is valid. */
|
|
308
|
+
declare function checkSort(value: unknown, options?: WireSortOptions): WireIssue<WireSortIssueKey>[];
|
|
309
|
+
/**
|
|
310
|
+
* Checks offset, infinite or cursor params the way the `@querykitjs/zod`
|
|
311
|
+
* factories do: unknown fields and closed server-owned fields are stripped,
|
|
312
|
+
* `(page - 1) × perPage` stays within `maxOffset`, and a cursor request has no `sort`.
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```ts
|
|
316
|
+
* checkParams("offset", { page: 2, perPage: 201 }).issues;
|
|
317
|
+
* // [{ path: ["perPage"], key: "querykit.params.out_of_range", args: { max: 200 } }]
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
320
|
+
declare function checkParams(kind: WireParamsKind, value: unknown, options?: WireParamsOptions): WireParamsResult;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* English message texts for the wire-check issue keys, shared by the
|
|
324
|
+
* validators so a rejected payload reads the same everywhere. `{placeholder}`s
|
|
325
|
+
* are filled from the issue's `args`; `{path}` is the issue path as text.
|
|
326
|
+
*/
|
|
327
|
+
/**
|
|
328
|
+
* The filter, sort and limit messages — the canonical key list of
|
|
329
|
+
* `@querykitjs/class-validator`, which also ships `uz` and `ru` catalogs for it.
|
|
330
|
+
*/
|
|
331
|
+
declare const QUERYKIT_MESSAGES_EN: {
|
|
332
|
+
readonly "querykit.filter.invalid_node": "{path} must be a filter condition or an and/or/not group";
|
|
333
|
+
readonly "querykit.filter.missing_key": "{path} is missing the required `key` string";
|
|
334
|
+
readonly "querykit.filter.unknown_key": "{path}: `{key}` is not an allowed filter key";
|
|
335
|
+
readonly "querykit.filter.invalid_operator": "{path}: `{operation}` is not a supported filter operator";
|
|
336
|
+
readonly "querykit.filter.invalid_value": "{path} must be a string, number, boolean, null, or an array of those";
|
|
337
|
+
readonly "querykit.filter.invalid_group": "{path} must be an array of filter nodes";
|
|
338
|
+
readonly "querykit.filter.max_depth": "{path} exceeds maxDepth ({max})";
|
|
339
|
+
readonly "querykit.filter.value_requires_array": "{path}: `{operation}` requires an array value";
|
|
340
|
+
readonly "querykit.filter.value_requires_tuple": "{path}: `{operation}` requires exactly two values";
|
|
341
|
+
readonly "querykit.filter.value_forbidden": "{path}: `{operation}` must not carry a value";
|
|
342
|
+
readonly "querykit.sort.not_array": "{path} must be an array of { key, direction } items";
|
|
343
|
+
readonly "querykit.sort.invalid_item": "{path} must be an object with a `key` string";
|
|
344
|
+
readonly "querykit.sort.missing_key": "{path} is missing the required `key` string";
|
|
345
|
+
readonly "querykit.sort.unknown_key": "{path}: `{key}` is not an allowed sort key";
|
|
346
|
+
readonly "querykit.sort.invalid_direction": "{path}: direction must be `asc` or `desc`";
|
|
347
|
+
readonly "querykit.limit.exceeded": "{path} exceeds {limit} ({max})";
|
|
348
|
+
};
|
|
349
|
+
/** The pagination-params messages (`checkParams`); kept apart so the class-validator catalogs keep their key set. */
|
|
350
|
+
declare const QUERYKIT_PARAMS_MESSAGES_EN: {
|
|
351
|
+
readonly "querykit.params.invalid_type": "{path} must be {expected}";
|
|
352
|
+
readonly "querykit.params.not_integer": "{path} must be an integer";
|
|
353
|
+
readonly "querykit.params.out_of_range": "{path} is out of the allowed range";
|
|
354
|
+
readonly "querykit.params.invalid_enum": "{path} must be one of: {values}";
|
|
355
|
+
};
|
|
356
|
+
/** A filter, sort or limit message key. */
|
|
357
|
+
type QueryKitMessageKey = keyof typeof QUERYKIT_MESSAGES_EN;
|
|
358
|
+
/** One language's full catalog — every key required, so a new key breaks every catalog at compile time. */
|
|
359
|
+
type QueryKitMessageCatalog = Record<QueryKitMessageKey, string>;
|
|
360
|
+
/** Interpolation arguments. */
|
|
361
|
+
type MessageArgs = Record<string, string | number>;
|
|
362
|
+
/** Fills `{name}` placeholders from `args`; a placeholder with no argument stays as it is, so a message is never empty. */
|
|
363
|
+
declare const interpolate: (template: string, args: MessageArgs) => string;
|
|
364
|
+
/**
|
|
365
|
+
* The message for `key` from `catalog` (default English), placeholders filled.
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* ```ts
|
|
369
|
+
* formatMessage("querykit.limit.exceeded", { path: "filter", limit: "maxConditions", max: 30 });
|
|
370
|
+
* // "filter exceeds maxConditions (30)"
|
|
371
|
+
* ```
|
|
372
|
+
*/
|
|
373
|
+
declare function formatMessage(key: QueryKitMessageKey, args?: MessageArgs, catalog?: QueryKitMessageCatalog): string;
|
|
374
|
+
|
|
375
|
+
export { QUERYKIT_MESSAGES_EN, QUERYKIT_PARAMS_MESSAGES_EN, checkFilter, checkParams, checkSort, checkWith, clampOffset, clampPage, clampPageSize, createContextStore, cursorPage, decodeCursor, decodeCursorToken, encodeCursor, encodeCursorToken, findFilterLimitViolation, formatLimit, formatMessage, infinitePage, interpolate, isAllRows, isEmptyFilter, isLikeOperator, likeWildcards, normalizeSort, offsetMeta, offsetOf, offsetPageWithoutTotal, refuseEmptyFilter, reportSkip, resolvePolicy, scopeConditions, scopeDefaults };
|
|
376
|
+
export type { ContextStore, CursorPageOptions, CursorToken, Diagnostics, FilterLimits, LimitPath, LimitViolation, MessageArgs, NormalizedSortItem, Policy, PolicyOptions, QueryKitMessageCatalog, QueryKitMessageKey, ScopeCondition, WireFilterIssueKey, WireFilterOptions, WireIssue, WireIssueArgs, WireIssueKey, WireParamsIssueKey, WireParamsKind, WireParamsOptions, WireParamsResult, WireServerOwnedField, WireSortIssueKey, WireSortOptions, WithDialect };
|