@querykitjs/class-validator 1.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.
- package/README.en.md +68 -15
- package/README.md +68 -15
- package/dist/chunk-AX53IY63.cjs +89 -0
- package/dist/chunk-AX53IY63.cjs.map +1 -0
- package/dist/chunk-HKLXL3NW.cjs +42 -0
- package/dist/chunk-HKLXL3NW.cjs.map +1 -0
- package/dist/chunk-PKGWV2JC.cjs +81 -0
- package/dist/chunk-PKGWV2JC.cjs.map +1 -0
- package/dist/chunk-QMFPUYJO.js +30 -0
- package/dist/chunk-QMFPUYJO.js.map +1 -0
- package/dist/chunk-V4E73HMQ.js +85 -0
- package/dist/chunk-V4E73HMQ.js.map +1 -0
- package/dist/chunk-XF6C4EG2.js +76 -0
- package/dist/chunk-XF6C4EG2.js.map +1 -0
- package/dist/decorators.cjs +33 -0
- package/dist/decorators.cjs.map +1 -0
- package/dist/decorators.js +4 -0
- package/dist/decorators.js.map +1 -0
- package/dist/index.cjs +92 -375
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -73
- package/dist/index.d.ts +101 -73
- package/dist/index.js +30 -363
- package/dist/index.js.map +1 -1
- package/dist/legacy-dto.cjs +26 -0
- package/dist/legacy-dto.cjs.map +1 -0
- package/dist/legacy-dto.js +5 -0
- package/dist/legacy-dto.js.map +1 -0
- package/dist/validate.cjs +20 -0
- package/dist/validate.cjs.map +1 -0
- package/dist/validate.js +3 -0
- package/dist/validate.js.map +1 -0
- package/package.json +20 -11
- package/skills/querykit-class-validator/SKILL.md +124 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { QueryKitMessageKey, MessageArgs, QueryKitMessageCatalog } from '@querykitjs/core/internal';
|
|
2
|
+
export { MessageArgs, QUERYKIT_MESSAGES_EN, QueryKitMessageCatalog, QueryKitMessageKey, formatMessage } from '@querykitjs/core/internal';
|
|
3
|
+
import { FilterOperator, Filter, Sort, SortDirection, QueryLimits } from '@querykitjs/core';
|
|
4
|
+
export { DEFAULT_MAX_FILTER_DEPTH } from '@querykitjs/core';
|
|
2
5
|
import { ValidationOptions, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
|
|
3
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Xabar formatlash. Kataloglar `locales.ts`da; `formatMessage` core'da
|
|
9
|
+
* (boshqa validatorlar bilan bitta), bu yerda faqat `localizeIssue`.
|
|
10
|
+
*
|
|
11
|
+
* Har bir {@link ValidationIssue} uchta narsani olib yuradi: `key` (tarjima
|
|
12
|
+
* kaliti), `message` (tayyor matn) va `args` (interpolatsiya qiymatlari). Shu
|
|
13
|
+
* sababli paket i18n'ga **majburlamaydi**, lekin unga to'liq mos.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Issue'ni tanlangan tilda qayta formatlaydi — `message` inglizcha yozilgan
|
|
18
|
+
* bo'lsa ham, javobni boshqa tilda berish uchun.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* issues.map(issue => localizeIssue(issue, QUERYKIT_MESSAGES_RU));
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare function localizeIssue(issue: {
|
|
26
|
+
key: QueryKitMessageKey;
|
|
27
|
+
args: MessageArgs;
|
|
28
|
+
}, catalog: QueryKitMessageCatalog): string;
|
|
29
|
+
|
|
4
30
|
/**
|
|
5
31
|
* Xabar kataloglari — **yagona manba**. Har bir til bir xil kalitlar to'plamini
|
|
6
32
|
* to'ldiradi; kalitlarning o'zi shu yerdagi inglizcha katalogdan chiqadi.
|
|
@@ -14,34 +40,7 @@ import { ValidationOptions, ValidatorConstraintInterface, ValidationArguments }
|
|
|
14
40
|
* inglizchaga yangi kalit qo'shilsa, qolgan kataloglar **compile-time**da yorilib
|
|
15
41
|
* beradi va eskirib qololmaydi.
|
|
16
42
|
*/
|
|
17
|
-
|
|
18
|
-
* Inglizcha katalog — kalitlarning kanonik ro'yxati va default fallback.
|
|
19
|
-
* `{placeholder}` lar `formatMessage` bilan to'ldiriladi.
|
|
20
|
-
*/
|
|
21
|
-
declare const QUERYKIT_MESSAGES_EN: {
|
|
22
|
-
readonly "querykit.filter.invalid_node": "{path} must be a filter condition or an and/or/not group";
|
|
23
|
-
readonly "querykit.filter.missing_key": "{path} is missing the required `key` string";
|
|
24
|
-
readonly "querykit.filter.unknown_key": "{path}: `{key}` is not an allowed filter key";
|
|
25
|
-
readonly "querykit.filter.invalid_operator": "{path}: `{operation}` is not a supported filter operator";
|
|
26
|
-
readonly "querykit.filter.invalid_value": "{path} must be a string, number, boolean, null, or an array of those";
|
|
27
|
-
readonly "querykit.filter.invalid_group": "{path} must be an array of filter nodes";
|
|
28
|
-
readonly "querykit.filter.max_depth": "{path} exceeds the maximum filter depth of {max}";
|
|
29
|
-
readonly "querykit.filter.value_requires_array": "{path}: `{operation}` requires an array value";
|
|
30
|
-
readonly "querykit.filter.value_requires_tuple": "{path}: `{operation}` requires exactly two values";
|
|
31
|
-
readonly "querykit.filter.value_forbidden": "{path}: `{operation}` must not carry a value";
|
|
32
|
-
readonly "querykit.sort.not_array": "{path} must be an array of { key, direction } items";
|
|
33
|
-
readonly "querykit.sort.invalid_item": "{path} must be an object with a `key` string";
|
|
34
|
-
readonly "querykit.sort.missing_key": "{path} is missing the required `key` string";
|
|
35
|
-
readonly "querykit.sort.unknown_key": "{path}: `{key}` is not an allowed sort key";
|
|
36
|
-
readonly "querykit.sort.invalid_direction": "{path}: direction must be `asc` or `desc`";
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Har bir validatsiya xatosining i18n kaliti. Union inglizcha katalogdan chiqadi —
|
|
40
|
-
* yangi xabar qo'shilsa tip o'zi kengayadi, qo'lda ro'yxat yuritilmaydi.
|
|
41
|
-
*/
|
|
42
|
-
type QueryKitMessageKey = keyof typeof QUERYKIT_MESSAGES_EN;
|
|
43
|
-
/** Bitta tilning to'liq katalogi — barcha kalitlar majburiy. */
|
|
44
|
-
type QueryKitMessageCatalog = Record<QueryKitMessageKey, string>;
|
|
43
|
+
|
|
45
44
|
/** O'zbekcha katalog. Placeholder nomlari inglizchasi bilan bir xil. */
|
|
46
45
|
declare const QUERYKIT_MESSAGES_UZ: QueryKitMessageCatalog;
|
|
47
46
|
/** Ruscha katalog. */
|
|
@@ -58,7 +57,7 @@ declare const QUERYKIT_LOCALES: {
|
|
|
58
57
|
readonly "querykit.filter.invalid_operator": "{path}: `{operation}` is not a supported filter operator";
|
|
59
58
|
readonly "querykit.filter.invalid_value": "{path} must be a string, number, boolean, null, or an array of those";
|
|
60
59
|
readonly "querykit.filter.invalid_group": "{path} must be an array of filter nodes";
|
|
61
|
-
readonly "querykit.filter.max_depth": "{path} exceeds
|
|
60
|
+
readonly "querykit.filter.max_depth": "{path} exceeds maxDepth ({max})";
|
|
62
61
|
readonly "querykit.filter.value_requires_array": "{path}: `{operation}` requires an array value";
|
|
63
62
|
readonly "querykit.filter.value_requires_tuple": "{path}: `{operation}` requires exactly two values";
|
|
64
63
|
readonly "querykit.filter.value_forbidden": "{path}: `{operation}` must not carry a value";
|
|
@@ -67,6 +66,7 @@ declare const QUERYKIT_LOCALES: {
|
|
|
67
66
|
readonly "querykit.sort.missing_key": "{path} is missing the required `key` string";
|
|
68
67
|
readonly "querykit.sort.unknown_key": "{path}: `{key}` is not an allowed sort key";
|
|
69
68
|
readonly "querykit.sort.invalid_direction": "{path}: direction must be `asc` or `desc`";
|
|
69
|
+
readonly "querykit.limit.exceeded": "{path} exceeds {limit} ({max})";
|
|
70
70
|
};
|
|
71
71
|
readonly uz: QueryKitMessageCatalog;
|
|
72
72
|
readonly ru: QueryKitMessageCatalog;
|
|
@@ -75,46 +75,13 @@ declare const QUERYKIT_LOCALES: {
|
|
|
75
75
|
type QueryKitLocale = keyof typeof QUERYKIT_LOCALES;
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
79
|
-
* `
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* sababli paket i18n'ga **majburlamaydi**, lekin unga to'liq mos.
|
|
84
|
-
*/
|
|
85
|
-
|
|
86
|
-
/** Shablon interpolatsiyasi argumentlari — `I18nValidationPipe`ga ham shu shaklda uzatiladi. */
|
|
87
|
-
type MessageArgs = Record<string, string | number>;
|
|
88
|
-
/**
|
|
89
|
-
* Kalitni matnga aylantiradi: katalogdan shablon olinadi va `{placeholder}` lar
|
|
90
|
-
* `args` bilan almashtiriladi. Mos argument topilmasa placeholder o'z holicha
|
|
91
|
-
* qoladi — xabar hech qachon bo'sh chiqmaydi.
|
|
92
|
-
*
|
|
93
|
-
* @param catalog Til katalogi. Default — inglizcha; `QUERYKIT_MESSAGES_UZ`,
|
|
94
|
-
* `QUERYKIT_MESSAGES_RU` yoki o'zingizniki uzatilishi mumkin.
|
|
95
|
-
*
|
|
96
|
-
* @example
|
|
97
|
-
* ```ts
|
|
98
|
-
* formatMessage(issue.key, issue.args, QUERYKIT_MESSAGES_UZ);
|
|
99
|
-
* ```
|
|
100
|
-
*/
|
|
101
|
-
declare function formatMessage(key: QueryKitMessageKey, args?: MessageArgs, catalog?: QueryKitMessageCatalog): string;
|
|
102
|
-
/**
|
|
103
|
-
* Issue'ni tanlangan tilda qayta formatlaydi — `message` inglizcha yozilgan
|
|
104
|
-
* bo'lsa ham, javobni boshqa tilda berish uchun.
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* ```ts
|
|
108
|
-
* issues.map(issue => localizeIssue(issue, QUERYKIT_MESSAGES_RU));
|
|
109
|
-
* ```
|
|
78
|
+
* Sof TS validatsiya yadrosi — **framework-agnostik**. Tekshiruv mantiqi core
|
|
79
|
+
* `checkFilter`/`checkSort` da (`@querykitjs/core/internal`) — boshqa validatorlar
|
|
80
|
+
* bilan bitta; bu yerda faqat yo'l satri va xabar matni quriladi.
|
|
81
|
+
* `class-validator` dekoratorlari (`decorators.ts`) faqat yupqa o'rov, shuning
|
|
82
|
+
* uchun yadroni Nest'siz ham (Express, Hono, oddiy funksiya) ishlatish mumkin.
|
|
110
83
|
*/
|
|
111
|
-
declare function localizeIssue(issue: {
|
|
112
|
-
key: QueryKitMessageKey;
|
|
113
|
-
args: MessageArgs;
|
|
114
|
-
}, catalog: QueryKitMessageCatalog): string;
|
|
115
84
|
|
|
116
|
-
/** Filter daraxti chuqurligi default limiti — cheklovsiz rekursiya DoS yuzasi. */
|
|
117
|
-
declare const DEFAULT_MAX_FILTER_DEPTH = 5;
|
|
118
85
|
interface QueryFilterOptions {
|
|
119
86
|
/**
|
|
120
87
|
* Berilsa — faqat shu kalitlarga ruxsat; noma'lum kalit **rad etiladi**.
|
|
@@ -125,8 +92,14 @@ interface QueryFilterOptions {
|
|
|
125
92
|
allowedKeys?: readonly string[];
|
|
126
93
|
/** Ruxsat etilgan operatorlar. Default — core `FILTER_OPERATORS`ning hammasi. */
|
|
127
94
|
allowedOperators?: readonly FilterOperator[];
|
|
128
|
-
/** `and`/`or`/`not`
|
|
95
|
+
/** Ildizdan bargacha tugunlar soni (ildiz 1, har `and`/`or`/`not` va shart +1). Default — core `DEFAULT_MAX_FILTER_DEPTH` (5). */
|
|
129
96
|
maxDepth?: number;
|
|
97
|
+
/** Barcha guruhlardagi shartlar (barglar) soni. Default — core `DEFAULT_MAX_CONDITIONS` (30). */
|
|
98
|
+
maxConditions?: number;
|
|
99
|
+
/** Bitta massiv qiymatdagi elementlar (`in`, `notIn`, …). Default — core `DEFAULT_MAX_IN_ITEMS` (200). */
|
|
100
|
+
maxInItems?: number;
|
|
101
|
+
/** Bitta satr qiymatdagi belgilar (massiv ichida ham). Default — core `DEFAULT_MAX_STRING_LENGTH` (256). */
|
|
102
|
+
maxStringLength?: number;
|
|
130
103
|
/**
|
|
131
104
|
* Operator↔qiymat shakli tekshiruvi (opt-in): `in`/`notIn` massiv talab qiladi,
|
|
132
105
|
* `between`/`notBetween` — aynan ikki element, `isNull`/`isNotNull` — qiymatsiz.
|
|
@@ -143,6 +116,8 @@ interface QueryFilterOptions {
|
|
|
143
116
|
interface QuerySortOptions {
|
|
144
117
|
/** Berilsa — faqat shu kalitlar bo'yicha saralashga ruxsat. */
|
|
145
118
|
allowedKeys?: readonly string[];
|
|
119
|
+
/** `sort` massividagi maydonlar soni. Default — core `DEFAULT_MAX_SORT_FIELDS` (3). */
|
|
120
|
+
maxSortFields?: number;
|
|
146
121
|
/** `path`ning ildizi. Default `"sort"`. Qarang: {@link QueryFilterOptions.rootPath}. */
|
|
147
122
|
rootPath?: string;
|
|
148
123
|
}
|
|
@@ -194,6 +169,34 @@ declare class IsQuerySortConstraint implements ValidatorConstraintInterface {
|
|
|
194
169
|
validate(value: unknown, args?: ValidationArguments): boolean;
|
|
195
170
|
defaultMessage(args?: ValidationArguments): string;
|
|
196
171
|
}
|
|
172
|
+
/** `@IsWithinMaxOffset()` opsiyalari. */
|
|
173
|
+
interface IsWithinMaxOffsetOptions {
|
|
174
|
+
/**
|
|
175
|
+
* `"page"` — property `page`, offset `(page - 1) × perPage` (o'sha obyektning `perPage`i,
|
|
176
|
+
* yo'q bo'lsa core `DEFAULT_PER_PAGE`); `"offset"` — property qiymatining o'zi (infinite).
|
|
177
|
+
*/
|
|
178
|
+
mode: "page" | "offset";
|
|
179
|
+
/** Default — core `DEFAULT_MAX_OFFSET` (10 000). `Infinity` tekshiruvni o'chiradi. */
|
|
180
|
+
maxOffset?: number;
|
|
181
|
+
}
|
|
182
|
+
/** `@IsWithinMaxOffset()` ortidagi konstraint. Raqam bo'lmagan qiymatni `@IsInt()` rad etadi, bu yerda o'tadi. */
|
|
183
|
+
declare class IsWithinMaxOffsetConstraint implements ValidatorConstraintInterface {
|
|
184
|
+
validate(value: unknown, args?: ValidationArguments): boolean;
|
|
185
|
+
defaultMessage(args?: ValidationArguments): string;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Sahifa chuqurligini cheklaydi: `page` uchun `(page - 1) × perPage`, infinite `offset` uchun
|
|
189
|
+
* qiymatning o'zi `maxOffset`dan oshmasin. Chuqurroq sahifalar — cursor paginatsiya.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* class ListDto {
|
|
194
|
+
* @IsOptional() @Type(() => Number) @IsInt() @IsPositive() @IsWithinMaxOffset({ mode: "page" })
|
|
195
|
+
* page?: number;
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
declare function IsWithinMaxOffset(options: IsWithinMaxOffsetOptions, validationOptions?: ValidationOptions): PropertyDecorator;
|
|
197
200
|
/**
|
|
198
201
|
* Property'ni querykit `Filter` kontraktiga tekshiradi: flat massiv (implicit AND),
|
|
199
202
|
* nested `and`/`or`/`not` daraxti va core `FILTER_OPERATORS`ning to'liq to'plami.
|
|
@@ -217,17 +220,31 @@ declare function IsQueryFilter(options?: IsQueryFilterOptions, validationOptions
|
|
|
217
220
|
*/
|
|
218
221
|
declare function IsQuerySort(options?: IsQuerySortOptions, validationOptions?: ValidationOptions): PropertyDecorator;
|
|
219
222
|
|
|
220
|
-
/**
|
|
223
|
+
/**
|
|
224
|
+
* Paginatsiyasiz umumiy params — `filter` + `sort`.
|
|
225
|
+
*
|
|
226
|
+
* @deprecated Use `makeOffsetParamsDto` / `makeInfiniteParamsDto` / `makeCursorParamsDto` (safe defaults). Removed in the next major.
|
|
227
|
+
*/
|
|
221
228
|
declare class BaseParamsDto {
|
|
222
229
|
filter?: Filter;
|
|
223
230
|
sort?: Sort;
|
|
224
231
|
}
|
|
225
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* Offset (sahifali) params — `page` + `perPage` (`perPage` ≤ core cap).
|
|
234
|
+
*
|
|
235
|
+
* @deprecated Use `makeOffsetParamsDto` (safe defaults). Removed in the next major.
|
|
236
|
+
*/
|
|
226
237
|
declare class OffsetParamsDto extends BaseParamsDto {
|
|
227
238
|
page?: number;
|
|
228
239
|
perPage?: number;
|
|
240
|
+
/** `false` — no count; the meta totals are `null`. */
|
|
241
|
+
withTotal?: boolean;
|
|
229
242
|
}
|
|
230
|
-
/**
|
|
243
|
+
/**
|
|
244
|
+
* Infinite-scroll params — `limit` + `offset`.
|
|
245
|
+
*
|
|
246
|
+
* @deprecated Use `makeInfiniteParamsDto` (safe defaults). Removed in the next major.
|
|
247
|
+
*/
|
|
231
248
|
declare class InfiniteParamsDto extends BaseParamsDto {
|
|
232
249
|
limit?: number;
|
|
233
250
|
offset?: number;
|
|
@@ -236,6 +253,8 @@ declare class InfiniteParamsDto extends BaseParamsDto {
|
|
|
236
253
|
* Cursor (keyset) params. `sort` **yo'q**: tartib `order` + `direction` bilan
|
|
237
254
|
* boshqariladi. Shu sababli `BaseParamsDto`dan meros olinmaydi — aks holda
|
|
238
255
|
* `sort` kontraktga qarshi ravishda meros bo'lib qolardi.
|
|
256
|
+
*
|
|
257
|
+
* @deprecated Use `makeCursorParamsDto` (safe defaults). Removed in the next major.
|
|
239
258
|
*/
|
|
240
259
|
declare class CursorParamsDto {
|
|
241
260
|
filter?: Filter;
|
|
@@ -245,6 +264,7 @@ declare class CursorParamsDto {
|
|
|
245
264
|
order?: SortDirection;
|
|
246
265
|
direction?: "forward" | "backward";
|
|
247
266
|
}
|
|
267
|
+
|
|
248
268
|
/** Server'ga tegishli, default'da clientdan qabul qilinmaydigan maydonlar. */
|
|
249
269
|
type ServerOwnedField = "columns" | "with" | "withDeleted";
|
|
250
270
|
/** `allow` bilan ochiladigan maydonlarning shakli. */
|
|
@@ -267,6 +287,12 @@ interface ParamsDtoOptions {
|
|
|
267
287
|
maxPerPage?: number;
|
|
268
288
|
/** `limit` yuqori chegarasi. Default — core `DEFAULT_MAX_LIMIT` (200). */
|
|
269
289
|
maxLimit?: number;
|
|
290
|
+
/**
|
|
291
|
+
* So'rov limitlari; berilmaganlari core default'ida (`DEFAULT_QUERY_LIMITS`). Aniq
|
|
292
|
+
* berilgan `filter.maxDepth`, `sort.maxSortFields`, … bundan **ustun**.
|
|
293
|
+
* `Infinity` limitni o'chiradi (⚠️ DoS yuzasi).
|
|
294
|
+
*/
|
|
295
|
+
limits?: Partial<QueryLimits>;
|
|
270
296
|
/** Server-owned maydonlarni **ataylab** ochish. Default — bo'sh. */
|
|
271
297
|
allow?: readonly ServerOwnedField[];
|
|
272
298
|
}
|
|
@@ -290,6 +316,7 @@ declare function makeOffsetParamsDto(options?: ParamsDtoOptions): {
|
|
|
290
316
|
sort?: Sort;
|
|
291
317
|
page?: number;
|
|
292
318
|
perPage?: number;
|
|
319
|
+
withTotal?: boolean;
|
|
293
320
|
columns?: Record<string, boolean>;
|
|
294
321
|
with?: Record<string, unknown>;
|
|
295
322
|
withDeleted?: boolean;
|
|
@@ -322,4 +349,5 @@ declare function makeCursorParamsDto(options?: ParamsDtoOptions): {
|
|
|
322
349
|
};
|
|
323
350
|
};
|
|
324
351
|
|
|
325
|
-
export { BaseParamsDto, CursorParamsDto,
|
|
352
|
+
export { BaseParamsDto, CursorParamsDto, InfiniteParamsDto, IsQueryFilter, IsQueryFilterConstraint, IsQuerySort, IsQuerySortConstraint, IsWithinMaxOffset, IsWithinMaxOffsetConstraint, OffsetParamsDto, QUERYKIT_LOCALES, QUERYKIT_MESSAGES_RU, QUERYKIT_MESSAGES_UZ, localizeIssue, makeCursorParamsDto, makeInfiniteParamsDto, makeOffsetParamsDto, validateFilter, validateSort };
|
|
353
|
+
export type { IsQueryFilterOptions, IsQuerySortOptions, IsWithinMaxOffsetOptions, MessageStyleOptions, ParamsDtoOptions, QueryFilterOptions, QueryKitLocale, QuerySortOptions, ServerOwnedField, ServerOwnedParams, ValidationIssue };
|