@querykitjs/core 1.1.0 → 1.2.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/index.cjs +35 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +120 -1
- package/dist/index.d.ts +120 -1
- package/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
|
+
|
|
3
7
|
// src/filters.ts
|
|
4
8
|
function field(key, operation, value) {
|
|
5
9
|
return { key, operation, value };
|
|
@@ -21,6 +25,7 @@ function createFilters() {
|
|
|
21
25
|
in: (key, value) => field(key, "in", value),
|
|
22
26
|
notIn: (key, value) => field(key, "notIn", value),
|
|
23
27
|
between: (key, min, max) => field(key, "between", [min, max]),
|
|
28
|
+
notBetween: (key, min, max) => field(key, "notBetween", [min, max]),
|
|
24
29
|
/** Diapazon — ikkita shart (`>=` va `<=`) massivi (flat filterga spread qilinadi). */
|
|
25
30
|
range: (key, from, to) => [
|
|
26
31
|
field(key, ">=", from),
|
|
@@ -38,6 +43,21 @@ var f = createFilters();
|
|
|
38
43
|
// src/defaults.ts
|
|
39
44
|
var DEFAULT_PER_PAGE = 20;
|
|
40
45
|
var DEFAULT_LIMIT = 20;
|
|
46
|
+
var DEFAULT_MAX_PER_PAGE = 200;
|
|
47
|
+
var DEFAULT_MAX_LIMIT = 200;
|
|
48
|
+
|
|
49
|
+
// src/errors.ts
|
|
50
|
+
var QueryKitError = class extends Error {
|
|
51
|
+
constructor(info) {
|
|
52
|
+
super(`querykit: ${info.reason} \u2014 "${info.key}" (${info.site}) on "${info.source}".`);
|
|
53
|
+
/** Barqaror kod — `instanceof` ishlamaydigan chegaralarda (RPC, worker) tekshirish uchun. */
|
|
54
|
+
__publicField(this, "code", "QUERYKIT_INVALID_CONDITION");
|
|
55
|
+
/** Tashlab yuborilgan shart haqida to'liq ma'lumot (hook argumenti bilan bir xil shakl). */
|
|
56
|
+
__publicField(this, "info");
|
|
57
|
+
this.name = "QueryKitError";
|
|
58
|
+
this.info = info;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
41
61
|
|
|
42
62
|
// src/operators.ts
|
|
43
63
|
var FILTER_OPERATORS = [
|
|
@@ -72,10 +92,25 @@ var FILTER_OPERATORS = [
|
|
|
72
92
|
"isNull",
|
|
73
93
|
"isNotNull"
|
|
74
94
|
];
|
|
95
|
+
var TEXT_FILTER_OPERATORS = [
|
|
96
|
+
"like",
|
|
97
|
+
"ilike",
|
|
98
|
+
"notLike",
|
|
99
|
+
"contains",
|
|
100
|
+
"startsWith",
|
|
101
|
+
"endsWith",
|
|
102
|
+
"%_%",
|
|
103
|
+
"%_",
|
|
104
|
+
"_%"
|
|
105
|
+
];
|
|
75
106
|
|
|
76
107
|
exports.DEFAULT_LIMIT = DEFAULT_LIMIT;
|
|
108
|
+
exports.DEFAULT_MAX_LIMIT = DEFAULT_MAX_LIMIT;
|
|
109
|
+
exports.DEFAULT_MAX_PER_PAGE = DEFAULT_MAX_PER_PAGE;
|
|
77
110
|
exports.DEFAULT_PER_PAGE = DEFAULT_PER_PAGE;
|
|
78
111
|
exports.FILTER_OPERATORS = FILTER_OPERATORS;
|
|
112
|
+
exports.QueryKitError = QueryKitError;
|
|
113
|
+
exports.TEXT_FILTER_OPERATORS = TEXT_FILTER_OPERATORS;
|
|
79
114
|
exports.createFilters = createFilters;
|
|
80
115
|
exports.f = f;
|
|
81
116
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/filters.ts","../src/defaults.ts","../src/operators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/filters.ts","../src/defaults.ts","../src/errors.ts","../src/operators.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { AndGroup, FieldCondition, FilterNode, FilterOperator, FilterScalar, FilterValue, NotGroup, OrGroup } from \"./types\";\n\nfunction field<TKey extends string>(key: TKey, operation: FilterOperator, value?: FilterValue): FieldCondition<TKey> {\n return { key, operation, value };\n}\n\n/**\n * Filter shartlarini tipli, ergonomik quruvchilar to'plamini qaytaradi. Kalit\n * tipiga (`TKey`) bog'lanadi; adapterlar uni o'z ustun/maydon kaliti bilan\n * chaqiradi. `TRaw` — guruhlarga (`and/or/not`) qo'shsa bo'ladigan raw tugun tipi.\n *\n * @typeParam TKey - ustun/maydon kaliti (string union).\n * @typeParam TRaw - raw escape-hatch tugun tipi (masalan Drizzle `SQL`).\n * @example\n * ```ts\n * const f = createFilters<\"status\" | \"age\">();\n * f.and(f.eq(\"status\", \"active\"), f.gte(\"age\", 18));\n * ```\n */\nexport function createFilters<TKey extends string = string, TRaw = never>() {\n type Node = FilterNode<TKey, TRaw>;\n\n return {\n eq: (key: TKey, value: FilterValue) => field(key, \"=\", value),\n ne: (key: TKey, value: FilterValue) => field(key, \"!=\", value),\n gt: (key: TKey, value: FilterValue) => field(key, \">\", value),\n gte: (key: TKey, value: FilterValue) => field(key, \">=\", value),\n lt: (key: TKey, value: FilterValue) => field(key, \"<\", value),\n lte: (key: TKey, value: FilterValue) => field(key, \"<=\", value),\n\n contains: (key: TKey, value: string) => field(key, \"%_%\", value),\n startsWith: (key: TKey, value: string) => field(key, \"%_\", value),\n endsWith: (key: TKey, value: string) => field(key, \"_%\", value),\n like: (key: TKey, value: string) => field(key, \"like\", value),\n ilike: (key: TKey, value: string) => field(key, \"ilike\", value),\n notLike: (key: TKey, value: string) => field(key, \"notLike\", value),\n\n in: (key: TKey, value: Array<string | number>) => field(key, \"in\", value),\n notIn: (key: TKey, value: Array<string | number>) => field(key, \"notIn\", value),\n between: (key: TKey, min: FilterScalar | Date, max: FilterScalar | Date) => field(key, \"between\", [min, max] as FilterValue),\n notBetween: (key: TKey, min: FilterScalar | Date, max: FilterScalar | Date) => field(key, \"notBetween\", [min, max] as FilterValue),\n /** Diapazon — ikkita shart (`>=` va `<=`) massivi (flat filterga spread qilinadi). */\n range: (key: TKey, from: FilterScalar | Date, to: FilterScalar | Date): FieldCondition<TKey>[] => [\n field(key, \">=\", from as FilterValue),\n field(key, \"<=\", to as FilterValue),\n ],\n\n isNull: (key: TKey) => field(key, \"isNull\"),\n isNotNull: (key: TKey) => field(key, \"isNotNull\"),\n\n and: (...nodes: Node[]): AndGroup<TKey, TRaw> => ({ and: nodes }),\n or: (...nodes: Node[]): OrGroup<TKey, TRaw> => ({ or: nodes }),\n not: (node: Node): NotGroup<TKey, TRaw> => ({ not: node }),\n };\n}\n\n/** Tipsiz (kalitga bog'lanmagan) filter quruvchilar — tez foydalanish uchun. */\nexport const f = createFilters();\n","/**\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 * 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 * Filter operatorlari — yagona runtime manba. `FilterOperator` tipi (`types.ts`)\n * shundan chiqadi; `@querykitjs/zod` shu massivdan zod enum quradi.\n */\nexport const FILTER_OPERATORS = [\n \"=\",\n \"!=\",\n \">\",\n \">=\",\n \"<\",\n \"<=\",\n \"eq\",\n \"ne\",\n \"gt\",\n \"gte\",\n \"lt\",\n \"lte\",\n \"like\",\n \"ilike\",\n \"notLike\",\n \"contains\",\n \"startsWith\",\n \"endsWith\",\n \"%_%\", // contains\n \"%_\", // startsWith\n \"_%\", // endsWith\n \"in\",\n \"notIn\",\n \"between\",\n \"notBetween\",\n \"isNull\",\n \"isNotNull\",\n] as const;\n\n/**\n * Qiymati **text pattern** bo'lgan operatorlar. Backend adapterlari wire qiymatni\n * ustun/path tipiga cast qilishda shularni chetlab o'tadi — aks holda\n * `ilike(dateColumn, \"%2026%\")` ISO string o'rniga `String(Date)` olardi\n * (`\"Mon Jul 28 2026 …\"`). Ro'yxat ikki adapterda divergent bo'lmasligi uchun\n * shu yerda — yagona manba.\n */\nexport const TEXT_FILTER_OPERATORS = [\n \"like\",\n \"ilike\",\n \"notLike\",\n \"contains\",\n \"startsWith\",\n \"endsWith\",\n \"%_%\",\n \"%_\",\n \"_%\",\n] as const satisfies readonly (typeof FILTER_OPERATORS)[number][];\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
* shundan chiqadi; `@querykitjs/zod` shu massivdan zod enum quradi.
|
|
4
4
|
*/
|
|
5
5
|
declare const FILTER_OPERATORS: readonly ["=", "!=", ">", ">=", "<", "<=", "eq", "ne", "gt", "gte", "lt", "lte", "like", "ilike", "notLike", "contains", "startsWith", "endsWith", "%_%", "%_", "_%", "in", "notIn", "between", "notBetween", "isNull", "isNotNull"];
|
|
6
|
+
/**
|
|
7
|
+
* Qiymati **text pattern** bo'lgan operatorlar. Backend adapterlari wire qiymatni
|
|
8
|
+
* ustun/path tipiga cast qilishda shularni chetlab o'tadi — aks holda
|
|
9
|
+
* `ilike(dateColumn, "%2026%")` ISO string o'rniga `String(Date)` olardi
|
|
10
|
+
* (`"Mon Jul 28 2026 …"`). Ro'yxat ikki adapterda divergent bo'lmasligi uchun
|
|
11
|
+
* shu yerda — yagona manba.
|
|
12
|
+
*/
|
|
13
|
+
declare const TEXT_FILTER_OPERATORS: readonly ["like", "ilike", "notLike", "contains", "startsWith", "endsWith", "%_%", "%_", "_%"];
|
|
6
14
|
|
|
7
15
|
/**
|
|
8
16
|
* `@querykitjs/core` — ORM-agnostik query DSL tiplari. Backend adapterlar
|
|
@@ -13,6 +21,20 @@ declare const FILTER_OPERATORS: readonly ["=", "!=", ">", ">=", "<", "<=", "eq",
|
|
|
13
21
|
|
|
14
22
|
/** Qo'llab-quvvatlanadigan filter operatorlari (token va nom aliaslari). */
|
|
15
23
|
type FilterOperator = (typeof FILTER_OPERATORS)[number];
|
|
24
|
+
/**
|
|
25
|
+
* Tiplangan kalit, lekin har qanday `string` ham qabul qilinadi. Wire (JSON) har
|
|
26
|
+
* doim string-keyed keladi va adapterlar noma'lum kalitni baribir skip qiladi —
|
|
27
|
+
* tip shunchaki haqiqatni aytsin, route'da `as` cast kerak bo'lmasin.
|
|
28
|
+
*
|
|
29
|
+
* `(string & {})` — autocomplete'ni saqlaydigan TS trick'i: IDE `TKey`
|
|
30
|
+
* variantlarini taklif qiladi, boshqa string esa xato bermaydi.
|
|
31
|
+
*/
|
|
32
|
+
type LooseKey<TKey extends string> = TKey | (string & {});
|
|
33
|
+
/**
|
|
34
|
+
* A filter scalar. `Date` is accepted **in-memory** (adapters cast it for local
|
|
35
|
+
* queries); over the JSON wire it serializes to an ISO string, so
|
|
36
|
+
* `@querykitjs/zod` validates scalars **without** `Date` (string/number/boolean/null).
|
|
37
|
+
*/
|
|
16
38
|
type FilterScalar = string | number | boolean | Date | null;
|
|
17
39
|
type FilterValue = FilterScalar | FilterScalar[];
|
|
18
40
|
/** Bitta maydon sharti (`operation` default `"="`). */
|
|
@@ -45,6 +67,66 @@ interface SortItem<TKey extends string = string> {
|
|
|
45
67
|
}
|
|
46
68
|
/** Sort is **always an array** of {@link SortItem} (multi-field capable). */
|
|
47
69
|
type Sort<TKey extends string = string> = SortItem<TKey>[];
|
|
70
|
+
/** Equality scope applied to every operation of a scoped repository. */
|
|
71
|
+
type Scope<TKey extends string = string> = Partial<Record<TKey, FilterScalar>>;
|
|
72
|
+
/** Options for upsert / upsertMany — conflict target(s) + optional update set. */
|
|
73
|
+
interface UpsertOptions<TKey extends string = string, TInsert = Record<string, unknown>> {
|
|
74
|
+
/** Unique/conflict key(s) whose match triggers an update instead of an insert. */
|
|
75
|
+
target: TKey | TKey[];
|
|
76
|
+
/** Columns/fields to update on conflict. Defaults to the inserted values minus `target`. */
|
|
77
|
+
set?: Partial<TInsert>;
|
|
78
|
+
}
|
|
79
|
+
/** Aggregate query spec — group + count/sum/avg/min/max, each keyed by field. */
|
|
80
|
+
interface AggregateSpec<TKey extends string = string, TFilter = unknown> {
|
|
81
|
+
filter?: TFilter;
|
|
82
|
+
/** Group rows by these field(s); each appears in the output rows. */
|
|
83
|
+
groupBy?: TKey | TKey[];
|
|
84
|
+
count?: boolean;
|
|
85
|
+
sum?: TKey | TKey[];
|
|
86
|
+
avg?: TKey | TKey[];
|
|
87
|
+
min?: TKey | TKey[];
|
|
88
|
+
max?: TKey | TKey[];
|
|
89
|
+
withDeleted?: boolean;
|
|
90
|
+
}
|
|
91
|
+
/** Paginatsiyasiz umumiy wire params. */
|
|
92
|
+
interface WireBaseParams {
|
|
93
|
+
filter?: Filter;
|
|
94
|
+
sort?: Sort;
|
|
95
|
+
columns?: Record<string, boolean>;
|
|
96
|
+
with?: Record<string, unknown>;
|
|
97
|
+
withDeleted?: boolean;
|
|
98
|
+
}
|
|
99
|
+
/** Offset (sahifali) wire params. */
|
|
100
|
+
interface WireOffsetParams extends WireBaseParams {
|
|
101
|
+
page?: number;
|
|
102
|
+
perPage?: number;
|
|
103
|
+
}
|
|
104
|
+
/** Infinite-scroll wire params. */
|
|
105
|
+
interface WireInfiniteParams extends WireBaseParams {
|
|
106
|
+
limit?: number;
|
|
107
|
+
offset?: number;
|
|
108
|
+
}
|
|
109
|
+
/** Cursor (keyset) wire params — `sort` yo'q, tartib `order` + `direction` bilan. */
|
|
110
|
+
interface WireCursorParams extends Omit<WireBaseParams, "sort"> {
|
|
111
|
+
limit?: number;
|
|
112
|
+
cursor?: string | null;
|
|
113
|
+
cursorKey?: string;
|
|
114
|
+
order?: SortDirection;
|
|
115
|
+
direction?: "forward" | "backward";
|
|
116
|
+
}
|
|
117
|
+
/** Shart nima uchun tashlab yuborilgani. */
|
|
118
|
+
type SkipReason = "unknown-key" | "invalid-value";
|
|
119
|
+
/** Shart qayerda tashlab yuborilgani. */
|
|
120
|
+
type SkipSite = "filter" | "sort" | "cursorKey" | "aggregate";
|
|
121
|
+
/** Tashlab yuborilgan bitta shart haqida ma'lumot. */
|
|
122
|
+
interface SkippedCondition {
|
|
123
|
+
/** Jadval (drizzle) yoki model (mongoose) nomi. */
|
|
124
|
+
source: string;
|
|
125
|
+
site: SkipSite;
|
|
126
|
+
key: string;
|
|
127
|
+
operation?: FilterOperator;
|
|
128
|
+
reason: SkipReason;
|
|
129
|
+
}
|
|
48
130
|
/** Offset (sahifali) paginatsiya meta'si. */
|
|
49
131
|
interface OffsetMeta {
|
|
50
132
|
total_items: number;
|
|
@@ -100,6 +182,7 @@ declare function createFilters<TKey extends string = string, TRaw = never>(): {
|
|
|
100
182
|
in: (key: TKey, value: Array<string | number>) => FieldCondition<TKey>;
|
|
101
183
|
notIn: (key: TKey, value: Array<string | number>) => FieldCondition<TKey>;
|
|
102
184
|
between: (key: TKey, min: FilterScalar | Date, max: FilterScalar | Date) => FieldCondition<TKey>;
|
|
185
|
+
notBetween: (key: TKey, min: FilterScalar | Date, max: FilterScalar | Date) => FieldCondition<TKey>;
|
|
103
186
|
/** Diapazon — ikkita shart (`>=` va `<=`) massivi (flat filterga spread qilinadi). */
|
|
104
187
|
range: (key: TKey, from: FilterScalar | Date, to: FilterScalar | Date) => FieldCondition<TKey>[];
|
|
105
188
|
isNull: (key: TKey) => FieldCondition<TKey>;
|
|
@@ -125,6 +208,7 @@ declare const f: {
|
|
|
125
208
|
in: (key: string, value: Array<string | number>) => FieldCondition<string>;
|
|
126
209
|
notIn: (key: string, value: Array<string | number>) => FieldCondition<string>;
|
|
127
210
|
between: (key: string, min: FilterScalar | Date, max: FilterScalar | Date) => FieldCondition<string>;
|
|
211
|
+
notBetween: (key: string, min: FilterScalar | Date, max: FilterScalar | Date) => FieldCondition<string>;
|
|
128
212
|
/** Diapazon — ikkita shart (`>=` va `<=`) massivi (flat filterga spread qilinadi). */
|
|
129
213
|
range: (key: string, from: FilterScalar | Date, to: FilterScalar | Date) => FieldCondition<string>[];
|
|
130
214
|
isNull: (key: string) => FieldCondition<string>;
|
|
@@ -143,5 +227,40 @@ declare const f: {
|
|
|
143
227
|
declare const DEFAULT_PER_PAGE = 20;
|
|
144
228
|
/** Infinite/cursor `limit` default'i. */
|
|
145
229
|
declare const DEFAULT_LIMIT = 20;
|
|
230
|
+
/**
|
|
231
|
+
* `perPage` uchun yuqori chegara — cap'siz paginatsiya DoS yuzasi. Validatsiya
|
|
232
|
+
* (`@querykitjs/zod` factory'lari), backend repositorylari va frontend `createQuery`
|
|
233
|
+
* shu bitta qiymatga tayanadi, shuning uchun ular hech qachon farq qilmaydi.
|
|
234
|
+
*/
|
|
235
|
+
declare const DEFAULT_MAX_PER_PAGE = 200;
|
|
236
|
+
/** Infinite/cursor `limit` uchun yuqori chegara. Qarang: {@link DEFAULT_MAX_PER_PAGE}. */
|
|
237
|
+
declare const DEFAULT_MAX_LIMIT = 200;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* querykit xatolari. Backend adapterlari (`drizzle-pg`, `mongoose`) `strict`
|
|
241
|
+
* rejimda shu bitta klassni tashlaydi — ya'ni ikkala backend uchun xatoni
|
|
242
|
+
* ushlash usuli bir xil.
|
|
243
|
+
*/
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* `strict` rejimda noto'g'ri so'rov shartida tashlanadi (noma'lum kalit yoki
|
|
247
|
+
* operatorga mos kelmagan qiymat). Backend'da 400 qilib qaytarish uchun:
|
|
248
|
+
*
|
|
249
|
+
* ```ts
|
|
250
|
+
* try {
|
|
251
|
+
* return await usersRepository.findList(params);
|
|
252
|
+
* } catch (err) {
|
|
253
|
+
* if (err instanceof QueryKitError) return c.json({ error: err.message }, 400);
|
|
254
|
+
* throw err;
|
|
255
|
+
* }
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
declare class QueryKitError extends Error {
|
|
259
|
+
/** Barqaror kod — `instanceof` ishlamaydigan chegaralarda (RPC, worker) tekshirish uchun. */
|
|
260
|
+
readonly code = "QUERYKIT_INVALID_CONDITION";
|
|
261
|
+
/** Tashlab yuborilgan shart haqida to'liq ma'lumot (hook argumenti bilan bir xil shakl). */
|
|
262
|
+
readonly info: SkippedCondition;
|
|
263
|
+
constructor(info: SkippedCondition);
|
|
264
|
+
}
|
|
146
265
|
|
|
147
|
-
export { type AndGroup, type CursorMeta, DEFAULT_LIMIT, DEFAULT_PER_PAGE, FILTER_OPERATORS, type FieldCondition, type Filter, type FilterNode, type FilterOperator, type FilterScalar, type FilterValue, type InfiniteMeta, type NotGroup, type OffsetMeta, type OrGroup, type Sort, type SortDirection, type SortItem, createFilters, f };
|
|
266
|
+
export { type AggregateSpec, type AndGroup, type CursorMeta, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_MAX_PER_PAGE, DEFAULT_PER_PAGE, FILTER_OPERATORS, type FieldCondition, type Filter, type FilterNode, type FilterOperator, type FilterScalar, type FilterValue, type InfiniteMeta, type LooseKey, type NotGroup, type OffsetMeta, type OrGroup, QueryKitError, type Scope, type SkipReason, type SkipSite, type SkippedCondition, type Sort, type SortDirection, type SortItem, TEXT_FILTER_OPERATORS, type UpsertOptions, type WireBaseParams, type WireCursorParams, type WireInfiniteParams, type WireOffsetParams, createFilters, f };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
* shundan chiqadi; `@querykitjs/zod` shu massivdan zod enum quradi.
|
|
4
4
|
*/
|
|
5
5
|
declare const FILTER_OPERATORS: readonly ["=", "!=", ">", ">=", "<", "<=", "eq", "ne", "gt", "gte", "lt", "lte", "like", "ilike", "notLike", "contains", "startsWith", "endsWith", "%_%", "%_", "_%", "in", "notIn", "between", "notBetween", "isNull", "isNotNull"];
|
|
6
|
+
/**
|
|
7
|
+
* Qiymati **text pattern** bo'lgan operatorlar. Backend adapterlari wire qiymatni
|
|
8
|
+
* ustun/path tipiga cast qilishda shularni chetlab o'tadi — aks holda
|
|
9
|
+
* `ilike(dateColumn, "%2026%")` ISO string o'rniga `String(Date)` olardi
|
|
10
|
+
* (`"Mon Jul 28 2026 …"`). Ro'yxat ikki adapterda divergent bo'lmasligi uchun
|
|
11
|
+
* shu yerda — yagona manba.
|
|
12
|
+
*/
|
|
13
|
+
declare const TEXT_FILTER_OPERATORS: readonly ["like", "ilike", "notLike", "contains", "startsWith", "endsWith", "%_%", "%_", "_%"];
|
|
6
14
|
|
|
7
15
|
/**
|
|
8
16
|
* `@querykitjs/core` — ORM-agnostik query DSL tiplari. Backend adapterlar
|
|
@@ -13,6 +21,20 @@ declare const FILTER_OPERATORS: readonly ["=", "!=", ">", ">=", "<", "<=", "eq",
|
|
|
13
21
|
|
|
14
22
|
/** Qo'llab-quvvatlanadigan filter operatorlari (token va nom aliaslari). */
|
|
15
23
|
type FilterOperator = (typeof FILTER_OPERATORS)[number];
|
|
24
|
+
/**
|
|
25
|
+
* Tiplangan kalit, lekin har qanday `string` ham qabul qilinadi. Wire (JSON) har
|
|
26
|
+
* doim string-keyed keladi va adapterlar noma'lum kalitni baribir skip qiladi —
|
|
27
|
+
* tip shunchaki haqiqatni aytsin, route'da `as` cast kerak bo'lmasin.
|
|
28
|
+
*
|
|
29
|
+
* `(string & {})` — autocomplete'ni saqlaydigan TS trick'i: IDE `TKey`
|
|
30
|
+
* variantlarini taklif qiladi, boshqa string esa xato bermaydi.
|
|
31
|
+
*/
|
|
32
|
+
type LooseKey<TKey extends string> = TKey | (string & {});
|
|
33
|
+
/**
|
|
34
|
+
* A filter scalar. `Date` is accepted **in-memory** (adapters cast it for local
|
|
35
|
+
* queries); over the JSON wire it serializes to an ISO string, so
|
|
36
|
+
* `@querykitjs/zod` validates scalars **without** `Date` (string/number/boolean/null).
|
|
37
|
+
*/
|
|
16
38
|
type FilterScalar = string | number | boolean | Date | null;
|
|
17
39
|
type FilterValue = FilterScalar | FilterScalar[];
|
|
18
40
|
/** Bitta maydon sharti (`operation` default `"="`). */
|
|
@@ -45,6 +67,66 @@ interface SortItem<TKey extends string = string> {
|
|
|
45
67
|
}
|
|
46
68
|
/** Sort is **always an array** of {@link SortItem} (multi-field capable). */
|
|
47
69
|
type Sort<TKey extends string = string> = SortItem<TKey>[];
|
|
70
|
+
/** Equality scope applied to every operation of a scoped repository. */
|
|
71
|
+
type Scope<TKey extends string = string> = Partial<Record<TKey, FilterScalar>>;
|
|
72
|
+
/** Options for upsert / upsertMany — conflict target(s) + optional update set. */
|
|
73
|
+
interface UpsertOptions<TKey extends string = string, TInsert = Record<string, unknown>> {
|
|
74
|
+
/** Unique/conflict key(s) whose match triggers an update instead of an insert. */
|
|
75
|
+
target: TKey | TKey[];
|
|
76
|
+
/** Columns/fields to update on conflict. Defaults to the inserted values minus `target`. */
|
|
77
|
+
set?: Partial<TInsert>;
|
|
78
|
+
}
|
|
79
|
+
/** Aggregate query spec — group + count/sum/avg/min/max, each keyed by field. */
|
|
80
|
+
interface AggregateSpec<TKey extends string = string, TFilter = unknown> {
|
|
81
|
+
filter?: TFilter;
|
|
82
|
+
/** Group rows by these field(s); each appears in the output rows. */
|
|
83
|
+
groupBy?: TKey | TKey[];
|
|
84
|
+
count?: boolean;
|
|
85
|
+
sum?: TKey | TKey[];
|
|
86
|
+
avg?: TKey | TKey[];
|
|
87
|
+
min?: TKey | TKey[];
|
|
88
|
+
max?: TKey | TKey[];
|
|
89
|
+
withDeleted?: boolean;
|
|
90
|
+
}
|
|
91
|
+
/** Paginatsiyasiz umumiy wire params. */
|
|
92
|
+
interface WireBaseParams {
|
|
93
|
+
filter?: Filter;
|
|
94
|
+
sort?: Sort;
|
|
95
|
+
columns?: Record<string, boolean>;
|
|
96
|
+
with?: Record<string, unknown>;
|
|
97
|
+
withDeleted?: boolean;
|
|
98
|
+
}
|
|
99
|
+
/** Offset (sahifali) wire params. */
|
|
100
|
+
interface WireOffsetParams extends WireBaseParams {
|
|
101
|
+
page?: number;
|
|
102
|
+
perPage?: number;
|
|
103
|
+
}
|
|
104
|
+
/** Infinite-scroll wire params. */
|
|
105
|
+
interface WireInfiniteParams extends WireBaseParams {
|
|
106
|
+
limit?: number;
|
|
107
|
+
offset?: number;
|
|
108
|
+
}
|
|
109
|
+
/** Cursor (keyset) wire params — `sort` yo'q, tartib `order` + `direction` bilan. */
|
|
110
|
+
interface WireCursorParams extends Omit<WireBaseParams, "sort"> {
|
|
111
|
+
limit?: number;
|
|
112
|
+
cursor?: string | null;
|
|
113
|
+
cursorKey?: string;
|
|
114
|
+
order?: SortDirection;
|
|
115
|
+
direction?: "forward" | "backward";
|
|
116
|
+
}
|
|
117
|
+
/** Shart nima uchun tashlab yuborilgani. */
|
|
118
|
+
type SkipReason = "unknown-key" | "invalid-value";
|
|
119
|
+
/** Shart qayerda tashlab yuborilgani. */
|
|
120
|
+
type SkipSite = "filter" | "sort" | "cursorKey" | "aggregate";
|
|
121
|
+
/** Tashlab yuborilgan bitta shart haqida ma'lumot. */
|
|
122
|
+
interface SkippedCondition {
|
|
123
|
+
/** Jadval (drizzle) yoki model (mongoose) nomi. */
|
|
124
|
+
source: string;
|
|
125
|
+
site: SkipSite;
|
|
126
|
+
key: string;
|
|
127
|
+
operation?: FilterOperator;
|
|
128
|
+
reason: SkipReason;
|
|
129
|
+
}
|
|
48
130
|
/** Offset (sahifali) paginatsiya meta'si. */
|
|
49
131
|
interface OffsetMeta {
|
|
50
132
|
total_items: number;
|
|
@@ -100,6 +182,7 @@ declare function createFilters<TKey extends string = string, TRaw = never>(): {
|
|
|
100
182
|
in: (key: TKey, value: Array<string | number>) => FieldCondition<TKey>;
|
|
101
183
|
notIn: (key: TKey, value: Array<string | number>) => FieldCondition<TKey>;
|
|
102
184
|
between: (key: TKey, min: FilterScalar | Date, max: FilterScalar | Date) => FieldCondition<TKey>;
|
|
185
|
+
notBetween: (key: TKey, min: FilterScalar | Date, max: FilterScalar | Date) => FieldCondition<TKey>;
|
|
103
186
|
/** Diapazon — ikkita shart (`>=` va `<=`) massivi (flat filterga spread qilinadi). */
|
|
104
187
|
range: (key: TKey, from: FilterScalar | Date, to: FilterScalar | Date) => FieldCondition<TKey>[];
|
|
105
188
|
isNull: (key: TKey) => FieldCondition<TKey>;
|
|
@@ -125,6 +208,7 @@ declare const f: {
|
|
|
125
208
|
in: (key: string, value: Array<string | number>) => FieldCondition<string>;
|
|
126
209
|
notIn: (key: string, value: Array<string | number>) => FieldCondition<string>;
|
|
127
210
|
between: (key: string, min: FilterScalar | Date, max: FilterScalar | Date) => FieldCondition<string>;
|
|
211
|
+
notBetween: (key: string, min: FilterScalar | Date, max: FilterScalar | Date) => FieldCondition<string>;
|
|
128
212
|
/** Diapazon — ikkita shart (`>=` va `<=`) massivi (flat filterga spread qilinadi). */
|
|
129
213
|
range: (key: string, from: FilterScalar | Date, to: FilterScalar | Date) => FieldCondition<string>[];
|
|
130
214
|
isNull: (key: string) => FieldCondition<string>;
|
|
@@ -143,5 +227,40 @@ declare const f: {
|
|
|
143
227
|
declare const DEFAULT_PER_PAGE = 20;
|
|
144
228
|
/** Infinite/cursor `limit` default'i. */
|
|
145
229
|
declare const DEFAULT_LIMIT = 20;
|
|
230
|
+
/**
|
|
231
|
+
* `perPage` uchun yuqori chegara — cap'siz paginatsiya DoS yuzasi. Validatsiya
|
|
232
|
+
* (`@querykitjs/zod` factory'lari), backend repositorylari va frontend `createQuery`
|
|
233
|
+
* shu bitta qiymatga tayanadi, shuning uchun ular hech qachon farq qilmaydi.
|
|
234
|
+
*/
|
|
235
|
+
declare const DEFAULT_MAX_PER_PAGE = 200;
|
|
236
|
+
/** Infinite/cursor `limit` uchun yuqori chegara. Qarang: {@link DEFAULT_MAX_PER_PAGE}. */
|
|
237
|
+
declare const DEFAULT_MAX_LIMIT = 200;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* querykit xatolari. Backend adapterlari (`drizzle-pg`, `mongoose`) `strict`
|
|
241
|
+
* rejimda shu bitta klassni tashlaydi — ya'ni ikkala backend uchun xatoni
|
|
242
|
+
* ushlash usuli bir xil.
|
|
243
|
+
*/
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* `strict` rejimda noto'g'ri so'rov shartida tashlanadi (noma'lum kalit yoki
|
|
247
|
+
* operatorga mos kelmagan qiymat). Backend'da 400 qilib qaytarish uchun:
|
|
248
|
+
*
|
|
249
|
+
* ```ts
|
|
250
|
+
* try {
|
|
251
|
+
* return await usersRepository.findList(params);
|
|
252
|
+
* } catch (err) {
|
|
253
|
+
* if (err instanceof QueryKitError) return c.json({ error: err.message }, 400);
|
|
254
|
+
* throw err;
|
|
255
|
+
* }
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
declare class QueryKitError extends Error {
|
|
259
|
+
/** Barqaror kod — `instanceof` ishlamaydigan chegaralarda (RPC, worker) tekshirish uchun. */
|
|
260
|
+
readonly code = "QUERYKIT_INVALID_CONDITION";
|
|
261
|
+
/** Tashlab yuborilgan shart haqida to'liq ma'lumot (hook argumenti bilan bir xil shakl). */
|
|
262
|
+
readonly info: SkippedCondition;
|
|
263
|
+
constructor(info: SkippedCondition);
|
|
264
|
+
}
|
|
146
265
|
|
|
147
|
-
export { type AndGroup, type CursorMeta, DEFAULT_LIMIT, DEFAULT_PER_PAGE, FILTER_OPERATORS, type FieldCondition, type Filter, type FilterNode, type FilterOperator, type FilterScalar, type FilterValue, type InfiniteMeta, type NotGroup, type OffsetMeta, type OrGroup, type Sort, type SortDirection, type SortItem, createFilters, f };
|
|
266
|
+
export { type AggregateSpec, type AndGroup, type CursorMeta, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_MAX_PER_PAGE, DEFAULT_PER_PAGE, FILTER_OPERATORS, type FieldCondition, type Filter, type FilterNode, type FilterOperator, type FilterScalar, type FilterValue, type InfiniteMeta, type LooseKey, type NotGroup, type OffsetMeta, type OrGroup, QueryKitError, type Scope, type SkipReason, type SkipSite, type SkippedCondition, type Sort, type SortDirection, type SortItem, TEXT_FILTER_OPERATORS, type UpsertOptions, type WireBaseParams, type WireCursorParams, type WireInfiniteParams, type WireOffsetParams, createFilters, f };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
1
5
|
// src/filters.ts
|
|
2
6
|
function field(key, operation, value) {
|
|
3
7
|
return { key, operation, value };
|
|
@@ -19,6 +23,7 @@ function createFilters() {
|
|
|
19
23
|
in: (key, value) => field(key, "in", value),
|
|
20
24
|
notIn: (key, value) => field(key, "notIn", value),
|
|
21
25
|
between: (key, min, max) => field(key, "between", [min, max]),
|
|
26
|
+
notBetween: (key, min, max) => field(key, "notBetween", [min, max]),
|
|
22
27
|
/** Diapazon — ikkita shart (`>=` va `<=`) massivi (flat filterga spread qilinadi). */
|
|
23
28
|
range: (key, from, to) => [
|
|
24
29
|
field(key, ">=", from),
|
|
@@ -36,6 +41,21 @@ var f = createFilters();
|
|
|
36
41
|
// src/defaults.ts
|
|
37
42
|
var DEFAULT_PER_PAGE = 20;
|
|
38
43
|
var DEFAULT_LIMIT = 20;
|
|
44
|
+
var DEFAULT_MAX_PER_PAGE = 200;
|
|
45
|
+
var DEFAULT_MAX_LIMIT = 200;
|
|
46
|
+
|
|
47
|
+
// src/errors.ts
|
|
48
|
+
var QueryKitError = class extends Error {
|
|
49
|
+
constructor(info) {
|
|
50
|
+
super(`querykit: ${info.reason} \u2014 "${info.key}" (${info.site}) on "${info.source}".`);
|
|
51
|
+
/** Barqaror kod — `instanceof` ishlamaydigan chegaralarda (RPC, worker) tekshirish uchun. */
|
|
52
|
+
__publicField(this, "code", "QUERYKIT_INVALID_CONDITION");
|
|
53
|
+
/** Tashlab yuborilgan shart haqida to'liq ma'lumot (hook argumenti bilan bir xil shakl). */
|
|
54
|
+
__publicField(this, "info");
|
|
55
|
+
this.name = "QueryKitError";
|
|
56
|
+
this.info = info;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
39
59
|
|
|
40
60
|
// src/operators.ts
|
|
41
61
|
var FILTER_OPERATORS = [
|
|
@@ -70,7 +90,18 @@ var FILTER_OPERATORS = [
|
|
|
70
90
|
"isNull",
|
|
71
91
|
"isNotNull"
|
|
72
92
|
];
|
|
93
|
+
var TEXT_FILTER_OPERATORS = [
|
|
94
|
+
"like",
|
|
95
|
+
"ilike",
|
|
96
|
+
"notLike",
|
|
97
|
+
"contains",
|
|
98
|
+
"startsWith",
|
|
99
|
+
"endsWith",
|
|
100
|
+
"%_%",
|
|
101
|
+
"%_",
|
|
102
|
+
"_%"
|
|
103
|
+
];
|
|
73
104
|
|
|
74
|
-
export { DEFAULT_LIMIT, DEFAULT_PER_PAGE, FILTER_OPERATORS, createFilters, f };
|
|
105
|
+
export { DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_MAX_PER_PAGE, DEFAULT_PER_PAGE, FILTER_OPERATORS, QueryKitError, TEXT_FILTER_OPERATORS, createFilters, f };
|
|
75
106
|
//# sourceMappingURL=index.js.map
|
|
76
107
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/filters.ts","../src/defaults.ts","../src/operators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/filters.ts","../src/defaults.ts","../src/errors.ts","../src/operators.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { AndGroup, FieldCondition, FilterNode, FilterOperator, FilterScalar, FilterValue, NotGroup, OrGroup } from \"./types\";\n\nfunction field<TKey extends string>(key: TKey, operation: FilterOperator, value?: FilterValue): FieldCondition<TKey> {\n return { key, operation, value };\n}\n\n/**\n * Filter shartlarini tipli, ergonomik quruvchilar to'plamini qaytaradi. Kalit\n * tipiga (`TKey`) bog'lanadi; adapterlar uni o'z ustun/maydon kaliti bilan\n * chaqiradi. `TRaw` — guruhlarga (`and/or/not`) qo'shsa bo'ladigan raw tugun tipi.\n *\n * @typeParam TKey - ustun/maydon kaliti (string union).\n * @typeParam TRaw - raw escape-hatch tugun tipi (masalan Drizzle `SQL`).\n * @example\n * ```ts\n * const f = createFilters<\"status\" | \"age\">();\n * f.and(f.eq(\"status\", \"active\"), f.gte(\"age\", 18));\n * ```\n */\nexport function createFilters<TKey extends string = string, TRaw = never>() {\n type Node = FilterNode<TKey, TRaw>;\n\n return {\n eq: (key: TKey, value: FilterValue) => field(key, \"=\", value),\n ne: (key: TKey, value: FilterValue) => field(key, \"!=\", value),\n gt: (key: TKey, value: FilterValue) => field(key, \">\", value),\n gte: (key: TKey, value: FilterValue) => field(key, \">=\", value),\n lt: (key: TKey, value: FilterValue) => field(key, \"<\", value),\n lte: (key: TKey, value: FilterValue) => field(key, \"<=\", value),\n\n contains: (key: TKey, value: string) => field(key, \"%_%\", value),\n startsWith: (key: TKey, value: string) => field(key, \"%_\", value),\n endsWith: (key: TKey, value: string) => field(key, \"_%\", value),\n like: (key: TKey, value: string) => field(key, \"like\", value),\n ilike: (key: TKey, value: string) => field(key, \"ilike\", value),\n notLike: (key: TKey, value: string) => field(key, \"notLike\", value),\n\n in: (key: TKey, value: Array<string | number>) => field(key, \"in\", value),\n notIn: (key: TKey, value: Array<string | number>) => field(key, \"notIn\", value),\n between: (key: TKey, min: FilterScalar | Date, max: FilterScalar | Date) => field(key, \"between\", [min, max] as FilterValue),\n notBetween: (key: TKey, min: FilterScalar | Date, max: FilterScalar | Date) => field(key, \"notBetween\", [min, max] as FilterValue),\n /** Diapazon — ikkita shart (`>=` va `<=`) massivi (flat filterga spread qilinadi). */\n range: (key: TKey, from: FilterScalar | Date, to: FilterScalar | Date): FieldCondition<TKey>[] => [\n field(key, \">=\", from as FilterValue),\n field(key, \"<=\", to as FilterValue),\n ],\n\n isNull: (key: TKey) => field(key, \"isNull\"),\n isNotNull: (key: TKey) => field(key, \"isNotNull\"),\n\n and: (...nodes: Node[]): AndGroup<TKey, TRaw> => ({ and: nodes }),\n or: (...nodes: Node[]): OrGroup<TKey, TRaw> => ({ or: nodes }),\n not: (node: Node): NotGroup<TKey, TRaw> => ({ not: node }),\n };\n}\n\n/** Tipsiz (kalitga bog'lanmagan) filter quruvchilar — tez foydalanish uchun. */\nexport const f = createFilters();\n","/**\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 * 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 * Filter operatorlari — yagona runtime manba. `FilterOperator` tipi (`types.ts`)\n * shundan chiqadi; `@querykitjs/zod` shu massivdan zod enum quradi.\n */\nexport const FILTER_OPERATORS = [\n \"=\",\n \"!=\",\n \">\",\n \">=\",\n \"<\",\n \"<=\",\n \"eq\",\n \"ne\",\n \"gt\",\n \"gte\",\n \"lt\",\n \"lte\",\n \"like\",\n \"ilike\",\n \"notLike\",\n \"contains\",\n \"startsWith\",\n \"endsWith\",\n \"%_%\", // contains\n \"%_\", // startsWith\n \"_%\", // endsWith\n \"in\",\n \"notIn\",\n \"between\",\n \"notBetween\",\n \"isNull\",\n \"isNotNull\",\n] as const;\n\n/**\n * Qiymati **text pattern** bo'lgan operatorlar. Backend adapterlari wire qiymatni\n * ustun/path tipiga cast qilishda shularni chetlab o'tadi — aks holda\n * `ilike(dateColumn, \"%2026%\")` ISO string o'rniga `String(Date)` olardi\n * (`\"Mon Jul 28 2026 …\"`). Ro'yxat ikki adapterda divergent bo'lmasligi uchun\n * shu yerda — yagona manba.\n */\nexport const TEXT_FILTER_OPERATORS = [\n \"like\",\n \"ilike\",\n \"notLike\",\n \"contains\",\n \"startsWith\",\n \"endsWith\",\n \"%_%\",\n \"%_\",\n \"_%\",\n] as const satisfies readonly (typeof FILTER_OPERATORS)[number][];\n"]}
|