@querykitjs/class-validator 2.0.0 → 2.0.1

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.
@@ -1,207 +0,0 @@
1
- 'use strict';
2
-
3
- var core = require('@querykitjs/core');
4
- var internal = require('@querykitjs/core/internal');
5
-
6
- var __defProp = Object.defineProperty;
7
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
- var __decorateClass = (decorators, target, key, kind) => {
9
- for (var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target, i = decorators.length - 1, decorator; i >= 0; i--)
10
- (decorator = decorators[i]) && (result = (kind ? decorator(target, key, result) : decorator(result)) || result);
11
- return kind && result && __defProp(target, key, result), result;
12
- };
13
-
14
- // src/locales.ts
15
- var QUERYKIT_MESSAGES_EN = {
16
- "querykit.filter.invalid_node": "{path} must be a filter condition or an and/or/not group",
17
- "querykit.filter.missing_key": "{path} is missing the required `key` string",
18
- "querykit.filter.unknown_key": "{path}: `{key}` is not an allowed filter key",
19
- "querykit.filter.invalid_operator": "{path}: `{operation}` is not a supported filter operator",
20
- "querykit.filter.invalid_value": "{path} must be a string, number, boolean, null, or an array of those",
21
- "querykit.filter.invalid_group": "{path} must be an array of filter nodes",
22
- "querykit.filter.max_depth": "{path} exceeds maxDepth ({max})",
23
- "querykit.filter.value_requires_array": "{path}: `{operation}` requires an array value",
24
- "querykit.filter.value_requires_tuple": "{path}: `{operation}` requires exactly two values",
25
- "querykit.filter.value_forbidden": "{path}: `{operation}` must not carry a value",
26
- "querykit.sort.not_array": "{path} must be an array of { key, direction } items",
27
- "querykit.sort.invalid_item": "{path} must be an object with a `key` string",
28
- "querykit.sort.missing_key": "{path} is missing the required `key` string",
29
- "querykit.sort.unknown_key": "{path}: `{key}` is not an allowed sort key",
30
- "querykit.sort.invalid_direction": "{path}: direction must be `asc` or `desc`",
31
- "querykit.limit.exceeded": "{path} exceeds {limit} ({max})"
32
- }, QUERYKIT_MESSAGES_UZ = {
33
- "querykit.filter.invalid_node": "{path} filter sharti yoki and/or/not guruhi bo'lishi kerak",
34
- "querykit.filter.missing_key": "{path} da majburiy `key` (string) yo'q",
35
- "querykit.filter.unknown_key": "{path}: `{key}` ruxsat etilgan filter kaliti emas",
36
- "querykit.filter.invalid_operator": "{path}: `{operation}` qo'llab-quvvatlanadigan filter operatori emas",
37
- "querykit.filter.invalid_value": "{path} string, raqam, boolean, null yoki shularning massivi bo'lishi kerak",
38
- "querykit.filter.invalid_group": "{path} filter tugunlari massivi bo'lishi kerak",
39
- "querykit.filter.max_depth": "{path} limitdan oshdi: maxDepth ({max})",
40
- "querykit.filter.value_requires_array": "{path}: `{operation}` massiv qiymat talab qiladi",
41
- "querykit.filter.value_requires_tuple": "{path}: `{operation}` aynan ikkita qiymat talab qiladi",
42
- "querykit.filter.value_forbidden": "{path}: `{operation}` qiymat qabul qilmaydi",
43
- "querykit.sort.not_array": "{path} `{ key, direction }` elementlaridan iborat massiv bo'lishi kerak",
44
- "querykit.sort.invalid_item": "{path} `key` (string) maydoniga ega obyekt bo'lishi kerak",
45
- "querykit.sort.missing_key": "{path} da majburiy `key` (string) yo'q",
46
- "querykit.sort.unknown_key": "{path}: `{key}` ruxsat etilgan sort kaliti emas",
47
- "querykit.sort.invalid_direction": "{path}: direction `asc` yoki `desc` bo'lishi kerak",
48
- "querykit.limit.exceeded": "{path} limitdan oshdi: {limit} ({max})"
49
- }, QUERYKIT_MESSAGES_RU = {
50
- "querykit.filter.invalid_node": "{path} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0443\u0441\u043B\u043E\u0432\u0438\u0435\u043C \u0444\u0438\u043B\u044C\u0442\u0440\u0430 \u0438\u043B\u0438 \u0433\u0440\u0443\u043F\u043F\u043E\u0439 and/or/not",
51
- "querykit.filter.missing_key": "\u0432 {path} \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u043F\u043E\u043B\u0435 `key` (\u0441\u0442\u0440\u043E\u043A\u0430)",
52
- "querykit.filter.unknown_key": "{path}: `{key}` \u2014 \u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 \u043A\u043B\u044E\u0447 \u0444\u0438\u043B\u044C\u0442\u0440\u0430",
53
- "querykit.filter.invalid_operator": "{path}: `{operation}` \u2014 \u043D\u0435\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0439 \u043E\u043F\u0435\u0440\u0430\u0442\u043E\u0440 \u0444\u0438\u043B\u044C\u0442\u0440\u0430",
54
- "querykit.filter.invalid_value": "{path} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0441\u0442\u0440\u043E\u043A\u043E\u0439, \u0447\u0438\u0441\u043B\u043E\u043C, boolean, null \u0438\u043B\u0438 \u043C\u0430\u0441\u0441\u0438\u0432\u043E\u043C \u0438\u0437 \u043D\u0438\u0445",
55
- "querykit.filter.invalid_group": "{path} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043C\u0430\u0441\u0441\u0438\u0432\u043E\u043C \u0443\u0437\u043B\u043E\u0432 \u0444\u0438\u043B\u044C\u0442\u0440\u0430",
56
- "querykit.filter.max_depth": "{path} \u043F\u0440\u0435\u0432\u044B\u0448\u0430\u0435\u0442 \u043B\u0438\u043C\u0438\u0442 maxDepth ({max})",
57
- "querykit.filter.value_requires_array": "{path}: `{operation}` \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435-\u043C\u0430\u0441\u0441\u0438\u0432",
58
- "querykit.filter.value_requires_tuple": "{path}: `{operation}` \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0440\u043E\u0432\u043D\u043E \u0434\u0432\u0430 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F",
59
- "querykit.filter.value_forbidden": "{path}: `{operation}` \u043D\u0435 \u0434\u043E\u043B\u0436\u0435\u043D \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435",
60
- "querykit.sort.not_array": "{path} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043C\u0430\u0441\u0441\u0438\u0432\u043E\u043C \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432 `{ key, direction }`",
61
- "querykit.sort.invalid_item": "{path} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u043C \u0441 \u043F\u043E\u043B\u0435\u043C `key` (\u0441\u0442\u0440\u043E\u043A\u0430)",
62
- "querykit.sort.missing_key": "\u0432 {path} \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u043F\u043E\u043B\u0435 `key` (\u0441\u0442\u0440\u043E\u043A\u0430)",
63
- "querykit.sort.unknown_key": "{path}: `{key}` \u2014 \u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439 \u043A\u043B\u044E\u0447 \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438",
64
- "querykit.sort.invalid_direction": "{path}: direction \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C `asc` \u0438\u043B\u0438 `desc`",
65
- "querykit.limit.exceeded": "{path} \u043F\u0440\u0435\u0432\u044B\u0448\u0430\u0435\u0442 \u043B\u0438\u043C\u0438\u0442 {limit} ({max})"
66
- }, QUERYKIT_LOCALES = {
67
- en: QUERYKIT_MESSAGES_EN,
68
- uz: QUERYKIT_MESSAGES_UZ,
69
- ru: QUERYKIT_MESSAGES_RU
70
- };
71
-
72
- // src/messages.ts
73
- var PLACEHOLDER = /\{(\w+)\}/g;
74
- function formatMessage(key, args = {}, catalog = QUERYKIT_MESSAGES_EN) {
75
- return catalog[key].replace(PLACEHOLDER, (match, name) => {
76
- let value = args[name];
77
- return value === void 0 ? match : String(value);
78
- });
79
- }
80
- function localizeIssue(issue2, catalog) {
81
- return formatMessage(issue2.key, issue2.args, catalog);
82
- }
83
-
84
- // src/validate.ts
85
- var ALL_OPERATORS = new Set(core.FILTER_OPERATORS), ARRAY_OPERATORS = /* @__PURE__ */ new Set(["in", "notIn"]), TUPLE_OPERATORS = /* @__PURE__ */ new Set(["between", "notBetween"]), NULLARY_OPERATORS = /* @__PURE__ */ new Set(["isNull", "isNotNull"]), isRecord = (value) => typeof value == "object" && value !== null && !Array.isArray(value), isScalar = (value) => value === null || typeof value == "string" || typeof value == "boolean" || typeof value == "number" && Number.isFinite(value), isFilterValue = (value) => Array.isArray(value) ? value.every(isScalar) : isScalar(value), label = (value) => {
86
- try {
87
- return String(value);
88
- } catch {
89
- return Object.prototype.toString.call(value);
90
- }
91
- }, joinPath = (root, path) => path.reduce((joined, part) => typeof part == "number" ? `${joined}[${part}]` : `${joined}.${part}`, root), issue = (key, path, extra = {}) => {
92
- let args = { path, ...extra };
93
- return { path, key, message: formatMessage(key, args), args };
94
- };
95
- function checkCondition(node, path, ctx) {
96
- if (!isRecord(node)) {
97
- ctx.issues.push(issue("querykit.filter.invalid_node", path));
98
- return;
99
- }
100
- let { key, operation, value } = node;
101
- if (typeof key != "string") {
102
- ctx.issues.push(issue("querykit.filter.missing_key", path));
103
- return;
104
- }
105
- ctx.allowedKeys && !ctx.allowedKeys.has(key) && ctx.issues.push(issue("querykit.filter.unknown_key", path, { key }));
106
- let operator;
107
- operation !== void 0 && (typeof operation == "string" && ctx.operators.has(operation) ? operator = operation : ctx.issues.push(issue("querykit.filter.invalid_operator", `${path}.operation`, { operation: label(operation) }))), value !== void 0 && !isFilterValue(value) && ctx.issues.push(issue("querykit.filter.invalid_value", `${path}.value`)), ctx.strictValue && operator !== void 0 && checkValueShape(operator, value, path, ctx);
108
- }
109
- function checkValueShape(operator, value, path, ctx) {
110
- let valuePath = `${path}.value`;
111
- if (ARRAY_OPERATORS.has(operator)) {
112
- Array.isArray(value) || ctx.issues.push(issue("querykit.filter.value_requires_array", valuePath, { operation: operator }));
113
- return;
114
- }
115
- if (TUPLE_OPERATORS.has(operator)) {
116
- (!Array.isArray(value) || value.length !== 2) && ctx.issues.push(issue("querykit.filter.value_requires_tuple", valuePath, { operation: operator }));
117
- return;
118
- }
119
- NULLARY_OPERATORS.has(operator) && value !== void 0 && ctx.issues.push(issue("querykit.filter.value_forbidden", valuePath, { operation: operator }));
120
- }
121
- function walkGroup(group, depth, path, ctx) {
122
- if (!Array.isArray(group)) {
123
- ctx.issues.push(issue("querykit.filter.invalid_group", path));
124
- return;
125
- }
126
- group.forEach((child, index) => walkNode(child, depth + 1, `${path}[${index}]`, ctx));
127
- }
128
- function walkNode(node, depth, path, ctx) {
129
- if (depth > ctx.maxDepth) {
130
- ctx.issues.push(issue("querykit.filter.max_depth", path, { max: ctx.maxDepth }));
131
- return;
132
- }
133
- if (!isRecord(node)) {
134
- ctx.issues.push(issue("querykit.filter.invalid_node", path));
135
- return;
136
- }
137
- if ("key" in node) {
138
- checkCondition(node, path, ctx);
139
- return;
140
- }
141
- if ("and" in node) {
142
- walkGroup(node.and, depth, `${path}.and`, ctx);
143
- return;
144
- }
145
- if ("or" in node) {
146
- walkGroup(node.or, depth, `${path}.or`, ctx);
147
- return;
148
- }
149
- if ("not" in node) {
150
- walkNode(node.not, depth + 1, `${path}.not`, ctx);
151
- return;
152
- }
153
- ctx.issues.push(issue("querykit.filter.missing_key", path));
154
- }
155
- function validateFilter(value, options = {}) {
156
- if (value === void 0) return [];
157
- let root = options.rootPath ?? "filter", limits = core.resolveLimits(options), violation = internal.findFilterLimitViolation(value, limits);
158
- if (violation) {
159
- let key = violation.limit === "maxDepth" ? "querykit.filter.max_depth" : "querykit.limit.exceeded";
160
- return [issue(key, joinPath(root, violation.path), { limit: violation.limit, max: violation.max })];
161
- }
162
- let ctx = {
163
- issues: [],
164
- allowedKeys: options.allowedKeys ? new Set(options.allowedKeys) : void 0,
165
- operators: options.allowedOperators ? new Set(options.allowedOperators) : ALL_OPERATORS,
166
- maxDepth: limits.maxDepth,
167
- strictValue: options.strictValue ?? false
168
- };
169
- return Array.isArray(value) ? (value.forEach((item, index) => checkCondition(item, `${root}[${index}]`, ctx)), ctx.issues) : (walkNode(value, 1, root, ctx), ctx.issues);
170
- }
171
- function validateSort(value, options = {}) {
172
- if (value === void 0) return [];
173
- let root = options.rootPath ?? "sort";
174
- if (!Array.isArray(value)) return [issue("querykit.sort.not_array", root)];
175
- let { maxSortFields } = core.resolveLimits(options);
176
- if (value.length > maxSortFields) return [issue("querykit.limit.exceeded", root, { limit: "maxSortFields", max: maxSortFields })];
177
- let allowedKeys = options.allowedKeys ? new Set(options.allowedKeys) : void 0, issues = [];
178
- return value.forEach((item, index) => {
179
- let path = `${root}[${index}]`;
180
- if (!isRecord(item)) {
181
- issues.push(issue("querykit.sort.invalid_item", path));
182
- return;
183
- }
184
- let { key, direction } = item;
185
- if (typeof key != "string") {
186
- issues.push(issue("querykit.sort.missing_key", path));
187
- return;
188
- }
189
- allowedKeys && !allowedKeys.has(key) && issues.push(issue("querykit.sort.unknown_key", path, { key })), direction !== void 0 && direction !== "asc" && direction !== "desc" && issues.push(issue("querykit.sort.invalid_direction", `${path}.direction`));
190
- }), issues;
191
- }
192
-
193
- Object.defineProperty(exports, "DEFAULT_MAX_FILTER_DEPTH", {
194
- enumerable: true,
195
- get: function () { return core.DEFAULT_MAX_FILTER_DEPTH; }
196
- });
197
- exports.QUERYKIT_LOCALES = QUERYKIT_LOCALES;
198
- exports.QUERYKIT_MESSAGES_EN = QUERYKIT_MESSAGES_EN;
199
- exports.QUERYKIT_MESSAGES_RU = QUERYKIT_MESSAGES_RU;
200
- exports.QUERYKIT_MESSAGES_UZ = QUERYKIT_MESSAGES_UZ;
201
- exports.__decorateClass = __decorateClass;
202
- exports.formatMessage = formatMessage;
203
- exports.localizeIssue = localizeIssue;
204
- exports.validateFilter = validateFilter;
205
- exports.validateSort = validateSort;
206
- //# sourceMappingURL=chunk-KXCJO556.cjs.map
207
- //# sourceMappingURL=chunk-KXCJO556.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/locales.ts","../src/messages.ts","../src/validate.ts"],"names":["issue","FILTER_OPERATORS","resolveLimits","findFilterLimitViolation"],"mappings":"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","file":"chunk-KXCJO556.cjs","sourcesContent":["/**\n * Xabar kataloglari — **yagona manba**. Har bir til bir xil kalitlar to'plamini\n * to'ldiradi; kalitlarning o'zi shu yerdagi inglizcha katalogdan chiqadi.\n *\n * Paket xatoni kalit bilan qaytargani uchun tillar soni cheklanmagan: tarjima\n * har doim iste'molchi tomonida (`nestjs-i18n` `I18nValidationPipe` yoki oddiy\n * `formatMessage(key, args, catalog)`). Bu yerdagi uchta katalog shunchaki eng\n * ko'p kerak bo'ladiganini qutidan beradi — hech biri majburiy emas.\n *\n * `QueryKitMessageCatalog` ataylab qat'iy (`Record<QueryKitMessageKey, string>`):\n * inglizchaga yangi kalit qo'shilsa, qolgan kataloglar **compile-time**da yorilib\n * beradi va eskirib qololmaydi.\n */\n\n/**\n * Inglizcha katalog — kalitlarning kanonik ro'yxati va default fallback.\n * `{placeholder}` lar `formatMessage` bilan to'ldiriladi.\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/**\n * Har bir validatsiya xatosining i18n kaliti. Union inglizcha katalogdan chiqadi —\n * yangi xabar qo'shilsa tip o'zi kengayadi, qo'lda ro'yxat yuritilmaydi.\n */\nexport type QueryKitMessageKey = keyof typeof QUERYKIT_MESSAGES_EN;\n\n/** Bitta tilning to'liq katalogi — barcha kalitlar majburiy. */\nexport type QueryKitMessageCatalog = Record<QueryKitMessageKey, string>;\n\n/** O'zbekcha katalog. Placeholder nomlari inglizchasi bilan bir xil. */\nexport const QUERYKIT_MESSAGES_UZ: QueryKitMessageCatalog = {\n \"querykit.filter.invalid_node\": \"{path} filter sharti yoki and/or/not guruhi bo'lishi kerak\",\n \"querykit.filter.missing_key\": \"{path} da majburiy `key` (string) yo'q\",\n \"querykit.filter.unknown_key\": \"{path}: `{key}` ruxsat etilgan filter kaliti emas\",\n \"querykit.filter.invalid_operator\": \"{path}: `{operation}` qo'llab-quvvatlanadigan filter operatori emas\",\n \"querykit.filter.invalid_value\": \"{path} string, raqam, boolean, null yoki shularning massivi bo'lishi kerak\",\n \"querykit.filter.invalid_group\": \"{path} filter tugunlari massivi bo'lishi kerak\",\n \"querykit.filter.max_depth\": \"{path} limitdan oshdi: maxDepth ({max})\",\n \"querykit.filter.value_requires_array\": \"{path}: `{operation}` massiv qiymat talab qiladi\",\n \"querykit.filter.value_requires_tuple\": \"{path}: `{operation}` aynan ikkita qiymat talab qiladi\",\n \"querykit.filter.value_forbidden\": \"{path}: `{operation}` qiymat qabul qilmaydi\",\n \"querykit.sort.not_array\": \"{path} `{ key, direction }` elementlaridan iborat massiv bo'lishi kerak\",\n \"querykit.sort.invalid_item\": \"{path} `key` (string) maydoniga ega obyekt bo'lishi kerak\",\n \"querykit.sort.missing_key\": \"{path} da majburiy `key` (string) yo'q\",\n \"querykit.sort.unknown_key\": \"{path}: `{key}` ruxsat etilgan sort kaliti emas\",\n \"querykit.sort.invalid_direction\": \"{path}: direction `asc` yoki `desc` bo'lishi kerak\",\n \"querykit.limit.exceeded\": \"{path} limitdan oshdi: {limit} ({max})\",\n};\n\n/** Ruscha katalog. */\nexport const QUERYKIT_MESSAGES_RU: QueryKitMessageCatalog = {\n \"querykit.filter.invalid_node\": \"{path} должен быть условием фильтра или группой and/or/not\",\n \"querykit.filter.missing_key\": \"в {path} отсутствует обязательное поле `key` (строка)\",\n \"querykit.filter.unknown_key\": \"{path}: `{key}` — недопустимый ключ фильтра\",\n \"querykit.filter.invalid_operator\": \"{path}: `{operation}` — неподдерживаемый оператор фильтра\",\n \"querykit.filter.invalid_value\": \"{path} должен быть строкой, числом, boolean, null или массивом из них\",\n \"querykit.filter.invalid_group\": \"{path} должен быть массивом узлов фильтра\",\n \"querykit.filter.max_depth\": \"{path} превышает лимит maxDepth ({max})\",\n \"querykit.filter.value_requires_array\": \"{path}: `{operation}` требует значение-массив\",\n \"querykit.filter.value_requires_tuple\": \"{path}: `{operation}` требует ровно два значения\",\n \"querykit.filter.value_forbidden\": \"{path}: `{operation}` не должен содержать значение\",\n \"querykit.sort.not_array\": \"{path} должен быть массивом элементов `{ key, direction }`\",\n \"querykit.sort.invalid_item\": \"{path} должен быть объектом с полем `key` (строка)\",\n \"querykit.sort.missing_key\": \"в {path} отсутствует обязательное поле `key` (строка)\",\n \"querykit.sort.unknown_key\": \"{path}: `{key}` — недопустимый ключ сортировки\",\n \"querykit.sort.invalid_direction\": \"{path}: direction должен быть `asc` или `desc`\",\n \"querykit.limit.exceeded\": \"{path} превышает лимит {limit} ({max})\",\n};\n\n/**\n * Til kodi → katalog. Qutidagi tillar; iste'molchi o'z katalogini shu shaklda\n * qo'shib, `formatMessage`ga uzata oladi.\n */\nexport const QUERYKIT_LOCALES = {\n en: QUERYKIT_MESSAGES_EN,\n uz: QUERYKIT_MESSAGES_UZ,\n ru: QUERYKIT_MESSAGES_RU,\n} as const satisfies Record<string, QueryKitMessageCatalog>;\n\n/** Qutidan chiqadigan til kodlari. */\nexport type QueryKitLocale = keyof typeof QUERYKIT_LOCALES;\n","/**\n * Xabar formatlash. Kataloglarning o'zi `locales.ts`da — bu fayl faqat\n * `{placeholder}` interpolatsiyasini biladi va hech qanday tilga bog'lanmagan.\n *\n * Har bir {@link ValidationIssue} uchta narsani olib yuradi: `key` (tarjima\n * kaliti), `message` (tayyor matn) va `args` (interpolatsiya qiymatlari). Shu\n * sababli paket i18n'ga **majburlamaydi**, lekin unga to'liq mos.\n */\nimport { QUERYKIT_MESSAGES_EN, type QueryKitMessageCatalog, type QueryKitMessageKey } from \"./locales\";\n\n/** Shablon interpolatsiyasi argumentlari — `I18nValidationPipe`ga ham shu shaklda uzatiladi. */\nexport type MessageArgs = Record<string, string | number>;\n\nconst PLACEHOLDER = /\\{(\\w+)\\}/g;\n\n/**\n * Kalitni matnga aylantiradi: katalogdan shablon olinadi va `{placeholder}` lar\n * `args` bilan almashtiriladi. Mos argument topilmasa placeholder o'z holicha\n * qoladi — xabar hech qachon bo'sh chiqmaydi.\n *\n * @param catalog Til katalogi. Default — inglizcha; `QUERYKIT_MESSAGES_UZ`,\n * `QUERYKIT_MESSAGES_RU` yoki o'zingizniki uzatilishi mumkin.\n *\n * @example\n * ```ts\n * formatMessage(issue.key, issue.args, QUERYKIT_MESSAGES_UZ);\n * ```\n */\nexport function formatMessage(key: QueryKitMessageKey, args: MessageArgs = {}, catalog: QueryKitMessageCatalog = QUERYKIT_MESSAGES_EN): string {\n return catalog[key].replace(PLACEHOLDER, (match, name: string) => {\n const value = args[name];\n return value === undefined ? match : String(value);\n });\n}\n\n/**\n * Issue'ni tanlangan tilda qayta formatlaydi — `message` inglizcha yozilgan\n * bo'lsa ham, javobni boshqa tilda berish uchun.\n *\n * @example\n * ```ts\n * issues.map(issue => localizeIssue(issue, QUERYKIT_MESSAGES_RU));\n * ```\n */\nexport function localizeIssue(issue: { key: QueryKitMessageKey; args: MessageArgs }, catalog: QueryKitMessageCatalog): string {\n return formatMessage(issue.key, issue.args, catalog);\n}\n","/**\n * Sof TS validatsiya yadrosi — **framework-agnostik**. Butun rekursiya va qaror\n * mantiqi shu yerda; `class-validator` dekoratorlari (`decorators.ts`) faqat\n * yupqa o'rov. Shu sababli yadroni Nest'siz ham (Express, Hono, oddiy funksiya)\n * ishlatish mumkin va uni test qilish uchun dekorator mashinasi kerak emas.\n *\n * Kontrakt manbasi — `@querykitjs/core`: operatorlar `FILTER_OPERATORS`dan,\n * daraxt shakli esa `Filter`/`FilterNode`/`FieldCondition` tiplaridan.\n */\nimport { DEFAULT_MAX_FILTER_DEPTH, FILTER_OPERATORS, resolveLimits } from \"@querykitjs/core\";\nimport type { FilterOperator } from \"@querykitjs/core\";\nimport { findFilterLimitViolation, type LimitPath } from \"@querykitjs/core/internal\";\nimport { formatMessage, type MessageArgs } from \"./messages\";\nimport type { QueryKitMessageKey } from \"./locales\";\n\n/** Filter daraxti chuqurligi default limiti — core'dan (yagona manba, R7). */\nexport { DEFAULT_MAX_FILTER_DEPTH };\n\nexport interface QueryFilterOptions {\n /**\n * Berilsa — faqat shu kalitlarga ruxsat; noma'lum kalit **rad etiladi**.\n * Backend adapterlari noma'lum kalitni jimgina tashlaydi, bu qatlam esa\n * qat'iyroq: mijoz mavjud bo'lmagan maydon bo'yicha filtr yubora olmaydi.\n * Berilmasa — istalgan string kalit o'tadi (`@querykitjs/zod` bilan parity).\n */\n allowedKeys?: readonly string[];\n /** Ruxsat etilgan operatorlar. Default — core `FILTER_OPERATORS`ning hammasi. */\n allowedOperators?: readonly FilterOperator[];\n /** Ildizdan bargacha tugunlar soni (ildiz 1, har `and`/`or`/`not` va shart +1). Default — core `DEFAULT_MAX_FILTER_DEPTH` (5). */\n maxDepth?: number;\n /** Barcha guruhlardagi shartlar (barglar) soni. Default — core `DEFAULT_MAX_CONDITIONS` (30). */\n maxConditions?: number;\n /** Bitta massiv qiymatdagi elementlar (`in`, `notIn`, …). Default — core `DEFAULT_MAX_IN_ITEMS` (200). */\n maxInItems?: number;\n /** Bitta satr qiymatdagi belgilar (massiv ichida ham). Default — core `DEFAULT_MAX_STRING_LENGTH` (256). */\n maxStringLength?: number;\n /**\n * Operator↔qiymat shakli tekshiruvi (opt-in): `in`/`notIn` massiv talab qiladi,\n * `between`/`notBetween` — aynan ikki element, `isNull`/`isNotNull` — qiymatsiz.\n * Default `false`, ya'ni `@querykitjs/zod` bilan bir xil qat'iylik.\n */\n strictValue?: boolean;\n /**\n * `path`ning ildizi. Default `\"filter\"`. Dekorator buni DTO property nomiga\n * qo'yadi, ya'ni `where` deb nomlangan maydon xatosi `filter.operation` emas,\n * `where.operation` deb chiqadi.\n */\n rootPath?: string;\n}\n\nexport interface QuerySortOptions {\n /** Berilsa — faqat shu kalitlar bo'yicha saralashga ruxsat. */\n allowedKeys?: readonly string[];\n /** `sort` massividagi maydonlar soni. Default — core `DEFAULT_MAX_SORT_FIELDS` (3). */\n maxSortFields?: number;\n /** `path`ning ildizi. Default `\"sort\"`. Qarang: {@link QueryFilterOptions.rootPath}. */\n rootPath?: string;\n}\n\n/** Bitta validatsiya xatosi. */\nexport interface ValidationIssue {\n /** Xato joyi, masalan `filter.and[1].or[0].value`. */\n path: string;\n /** i18n kaliti — iste'molchi tarjima faylida shu kalit qidiriladi. */\n key: QueryKitMessageKey;\n /** Tayyor inglizcha matn — tarjimasiz ham o'qiladi. */\n message: string;\n /** Interpolatsiya argumentlari (`path` har doim bor) — `I18nValidationPipe` uchun. */\n args: MessageArgs;\n}\n\n/* ------------------------------- internals -------------------------------- */\n\nconst ALL_OPERATORS: ReadonlySet<string> = new Set<string>(FILTER_OPERATORS);\n\n/* `strictValue` uchun operator tasnifi. */\nconst ARRAY_OPERATORS: ReadonlySet<string> = new Set([\"in\", \"notIn\"]);\nconst TUPLE_OPERATORS: ReadonlySet<string> = new Set([\"between\", \"notBetween\"]);\nconst NULLARY_OPERATORS: ReadonlySet<string> = new Set([\"isNull\", \"isNotNull\"]);\n\ntype UnknownRecord = Record<string, unknown>;\n\nconst isRecord = (value: unknown): value is UnknownRecord => typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/**\n * Wire skalyari — `Date`siz (JSON'da sana ISO string bo'ladi) va `NaN`/`Infinity`siz\n * (ikkalasi ham JSON'da mavjud emas va SQL/Mongo'ga tushsa xato beradi).\n */\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/** Xabarga qo'yish uchun xavfsiz matn — kirish ishonchsiz, `String()` yiqilishi mumkin. */\nconst label = (value: unknown): string => {\n try {\n return String(value);\n } catch {\n return Object.prototype.toString.call(value);\n }\n};\n\n/** Core walk'ining yo'li → `filter.and[1].or[0].value` shakli. */\nconst joinPath = (root: string, path: LimitPath): string =>\n path.reduce<string>((joined, part) => (typeof part === \"number\" ? `${joined}[${part}]` : `${joined}.${part}`), root);\n\nconst issue = (key: QueryKitMessageKey, path: string, extra: MessageArgs = {}): ValidationIssue => {\n const args: MessageArgs = { path, ...extra };\n return { path, key, message: formatMessage(key, args), args };\n};\n\ninterface FilterContext {\n issues: ValidationIssue[];\n allowedKeys?: ReadonlySet<string>;\n operators: ReadonlySet<string>;\n maxDepth: number;\n strictValue: boolean;\n}\n\n/**\n * Bitta maydon sharti. Noma'lum propertylar (masalan legacy `type`) **e'tiborsiz**\n * qoldiriladi — `@querykitjs/zod` ham ularni rad etmay, jimgina tashlaydi.\n */\nfunction checkCondition(node: unknown, path: string, ctx: FilterContext): void {\n if (!isRecord(node)) {\n ctx.issues.push(issue(\"querykit.filter.invalid_node\", path));\n return;\n }\n\n const { key, operation, value } = node;\n\n if (typeof key !== \"string\") {\n ctx.issues.push(issue(\"querykit.filter.missing_key\", path));\n return;\n }\n if (ctx.allowedKeys && !ctx.allowedKeys.has(key)) {\n ctx.issues.push(issue(\"querykit.filter.unknown_key\", path, { key }));\n }\n\n let operator: string | undefined;\n if (operation !== undefined) {\n if (typeof operation === \"string\" && ctx.operators.has(operation)) {\n operator = operation;\n } else {\n ctx.issues.push(issue(\"querykit.filter.invalid_operator\", `${path}.operation`, { operation: label(operation) }));\n }\n }\n\n if (value !== undefined && !isFilterValue(value)) {\n ctx.issues.push(issue(\"querykit.filter.invalid_value\", `${path}.value`));\n }\n\n if (ctx.strictValue && operator !== undefined) {\n checkValueShape(operator, value, path, ctx);\n }\n}\n\n/** `strictValue` shoxobchasi — operator qanday qiymat shaklini talab qilishi. */\nfunction checkValueShape(operator: string, value: unknown, path: string, ctx: FilterContext): void {\n const valuePath = `${path}.value`;\n\n if (ARRAY_OPERATORS.has(operator)) {\n if (!Array.isArray(value)) {\n ctx.issues.push(issue(\"querykit.filter.value_requires_array\", valuePath, { operation: operator }));\n }\n return;\n }\n if (TUPLE_OPERATORS.has(operator)) {\n if (!Array.isArray(value) || value.length !== 2) {\n ctx.issues.push(issue(\"querykit.filter.value_requires_tuple\", valuePath, { operation: operator }));\n }\n return;\n }\n if (NULLARY_OPERATORS.has(operator) && value !== undefined) {\n ctx.issues.push(issue(\"querykit.filter.value_forbidden\", valuePath, { operation: operator }));\n }\n}\n\nfunction walkGroup(group: unknown, depth: number, path: string, ctx: FilterContext): void {\n if (!Array.isArray(group)) {\n ctx.issues.push(issue(\"querykit.filter.invalid_group\", path));\n return;\n }\n group.forEach((child, index) => walkNode(child, depth + 1, `${path}[${index}]`, ctx));\n}\n\nfunction walkNode(node: unknown, depth: number, path: string, ctx: FilterContext): void {\n if (depth > ctx.maxDepth) {\n ctx.issues.push(issue(\"querykit.filter.max_depth\", path, { max: ctx.maxDepth }));\n return;\n }\n if (!isRecord(node)) {\n ctx.issues.push(issue(\"querykit.filter.invalid_node\", path));\n return;\n }\n\n /* Diskriminatsiya zod union tartibini aynan takrorlaydi: u yerda\n * `fieldConditionSchema` birinchi turadi, ya'ni `key` olib yurgan har qanday\n * obyekt shart deb o'qiladi va ortiqcha propertylar tashlanadi. */\n if (\"key\" in node) {\n checkCondition(node, path, ctx);\n return;\n }\n if (\"and\" in node) {\n walkGroup(node.and, depth, `${path}.and`, ctx);\n return;\n }\n if (\"or\" in node) {\n walkGroup(node.or, depth, `${path}.or`, ctx);\n return;\n }\n if (\"not\" in node) {\n walkNode(node.not, depth + 1, `${path}.not`, ctx);\n return;\n }\n\n ctx.issues.push(issue(\"querykit.filter.missing_key\", path));\n}\n\n/* -------------------------------- public ---------------------------------- */\n\n/**\n * Filter daraxtini core kontraktiga tekshiradi. Bo'sh massiv = valid.\n *\n * @example\n * ```ts\n * const issues = validateFilter(body.filter, { allowedKeys: [\"id\", \"name\"] });\n * if (issues.length) throw new BadRequestException(issues);\n * ```\n */\nexport function validateFilter(value: unknown, options: QueryFilterOptions = {}): ValidationIssue[] {\n if (value === undefined) return [];\n\n const root = options.rootPath ?? \"filter\";\n const limits = resolveLimits(options);\n\n /* Hajm birinchi, iterativ: limitdan oshgan payload shakl tekshiruviga yetib bormaydi. */\n const violation = findFilterLimitViolation(value, limits);\n if (violation) {\n const key = violation.limit === \"maxDepth\" ? \"querykit.filter.max_depth\" : \"querykit.limit.exceeded\";\n return [issue(key, joinPath(root, violation.path), { limit: violation.limit, max: violation.max })];\n }\n\n const ctx: FilterContext = {\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\n if (Array.isArray(value)) {\n /* Flat massiv = implicit AND. Core uni `FieldCondition[]` deb tiplaydi —\n * ya'ni elementlari faqat shart, nested guruh emas (zod'da ham shunday). */\n value.forEach((item, index) => checkCondition(item, `${root}[${index}]`, ctx));\n return ctx.issues;\n }\n\n walkNode(value, 1, root, ctx);\n return ctx.issues;\n}\n\n/**\n * Sort massivini core kontraktiga tekshiradi (`{ key, direction }[]`). Bo'sh massiv = valid.\n */\nexport function validateSort(value: unknown, options: QuerySortOptions = {}): ValidationIssue[] {\n if (value === undefined) return [];\n\n const root = options.rootPath ?? \"sort\";\n if (!Array.isArray(value)) return [issue(\"querykit.sort.not_array\", root)];\n\n const { maxSortFields } = resolveLimits(options);\n if (value.length > maxSortFields) return [issue(\"querykit.limit.exceeded\", root, { limit: \"maxSortFields\", max: maxSortFields })];\n\n const allowedKeys = options.allowedKeys ? new Set(options.allowedKeys) : undefined;\n const issues: ValidationIssue[] = [];\n\n value.forEach((item, index) => {\n const path = `${root}[${index}]`;\n\n if (!isRecord(item)) {\n issues.push(issue(\"querykit.sort.invalid_item\", path));\n return;\n }\n\n const { key, direction } = item;\n\n if (typeof key !== \"string\") {\n issues.push(issue(\"querykit.sort.missing_key\", path));\n return;\n }\n if (allowedKeys && !allowedKeys.has(key)) {\n issues.push(issue(\"querykit.sort.unknown_key\", path, { key }));\n }\n if (direction !== undefined && direction !== \"asc\" && direction !== \"desc\") {\n issues.push(issue(\"querykit.sort.invalid_direction\", `${path}.direction`));\n }\n });\n\n return issues;\n}\n"]}