@querykitjs/class-validator 1.0.0 → 2.0.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.
@@ -0,0 +1,85 @@
1
+ import { __decorateClass, validateFilter, validateSort, formatMessage } from './chunk-KT5JRG6S.js';
2
+ import { ValidatorConstraint, registerDecorator } from 'class-validator';
3
+ import { DEFAULT_MAX_OFFSET } from '@querykitjs/core';
4
+ import { offsetOf } from '@querykitjs/core/internal';
5
+
6
+ var optionsOf = (args, fallbackPath) => {
7
+ let given = args?.constraints?.[0] ?? {};
8
+ return { rootPath: args?.property ?? fallbackPath, ...given };
9
+ }, firstMessage = (issues, options, args, fallback) => {
10
+ let first = issues[0];
11
+ return first ? options.messageStyle === "key" ? first.key : first.message : `${args?.property ?? "value"} ${fallback}`;
12
+ }, IsQueryFilterConstraint = class {
13
+ validate(value, args) {
14
+ return validateFilter(value, optionsOf(args, "filter")).length === 0;
15
+ }
16
+ defaultMessage(args) {
17
+ let options = optionsOf(args, "filter");
18
+ return firstMessage(validateFilter(args?.value, options), options, args, "is not a valid querykit filter");
19
+ }
20
+ };
21
+ IsQueryFilterConstraint = __decorateClass([
22
+ ValidatorConstraint({ name: "isQueryFilter", async: false })
23
+ ], IsQueryFilterConstraint);
24
+ var IsQuerySortConstraint = class {
25
+ validate(value, args) {
26
+ return validateSort(value, optionsOf(args, "sort")).length === 0;
27
+ }
28
+ defaultMessage(args) {
29
+ let options = optionsOf(args, "sort");
30
+ return firstMessage(validateSort(args?.value, options), options, args, "is not a valid querykit sort");
31
+ }
32
+ };
33
+ IsQuerySortConstraint = __decorateClass([
34
+ ValidatorConstraint({ name: "isQuerySort", async: false })
35
+ ], IsQuerySortConstraint);
36
+ var maxOffsetOf = (args) => args?.constraints?.[0]?.maxOffset ?? DEFAULT_MAX_OFFSET, IsWithinMaxOffsetConstraint = class {
37
+ validate(value, args) {
38
+ if (typeof value != "number") return true;
39
+ let perPage = args?.object?.perPage;
40
+ return (args?.constraints?.[0]?.mode === "page" ? offsetOf(value, typeof perPage == "number" ? perPage : void 0) : value) <= maxOffsetOf(args);
41
+ }
42
+ defaultMessage(args) {
43
+ return formatMessage("querykit.limit.exceeded", { path: args?.property ?? "offset", limit: "maxOffset", max: maxOffsetOf(args) });
44
+ }
45
+ };
46
+ IsWithinMaxOffsetConstraint = __decorateClass([
47
+ ValidatorConstraint({ name: "isWithinMaxOffset", async: false })
48
+ ], IsWithinMaxOffsetConstraint);
49
+ function IsWithinMaxOffset(options, validationOptions) {
50
+ return (target, propertyName) => {
51
+ registerDecorator({
52
+ target: target.constructor,
53
+ propertyName,
54
+ options: validationOptions,
55
+ constraints: [options],
56
+ validator: IsWithinMaxOffsetConstraint
57
+ });
58
+ };
59
+ }
60
+ function IsQueryFilter(options, validationOptions) {
61
+ return (target, propertyName) => {
62
+ registerDecorator({
63
+ target: target.constructor,
64
+ propertyName,
65
+ options: validationOptions,
66
+ constraints: [options],
67
+ validator: IsQueryFilterConstraint
68
+ });
69
+ };
70
+ }
71
+ function IsQuerySort(options, validationOptions) {
72
+ return (target, propertyName) => {
73
+ registerDecorator({
74
+ target: target.constructor,
75
+ propertyName,
76
+ options: validationOptions,
77
+ constraints: [options],
78
+ validator: IsQuerySortConstraint
79
+ });
80
+ };
81
+ }
82
+
83
+ export { IsQueryFilter, IsQueryFilterConstraint, IsQuerySort, IsQuerySortConstraint, IsWithinMaxOffset, IsWithinMaxOffsetConstraint };
84
+ //# sourceMappingURL=chunk-UICYH7OH.js.map
85
+ //# sourceMappingURL=chunk-UICYH7OH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/decorators.ts"],"names":[],"mappings":"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","file":"chunk-UICYH7OH.js","sourcesContent":["/**\n * `class-validator` o'rovi. Butun mantiq `validate.ts`da — bu yerda faqat\n * konstraint klasslari va ularni property'ga bog'laydigan dekorator factory'lari.\n *\n * Rekursiya `validateFilter` ichida bo'lgani uchun nested DTO klassi ham,\n * `@ValidateNested` ham kerak emas: butun `and`/`or`/`not` daraxti bitta\n * dekorator bilan tekshiriladi.\n */\nimport { registerDecorator, ValidatorConstraint } from \"class-validator\";\nimport type { ValidationArguments, ValidationOptions, ValidatorConstraintInterface } from \"class-validator\";\nimport { DEFAULT_MAX_OFFSET } from \"@querykitjs/core\";\nimport { offsetOf } from \"@querykitjs/core/internal\";\nimport { formatMessage } from \"./messages\";\nimport { validateFilter, validateSort, type QueryFilterOptions, type QuerySortOptions, type ValidationIssue } from \"./validate\";\n\n/** Dekorator darajasidagi qo'shimcha — yadro buni o'qimaydi. */\nexport interface MessageStyleOptions {\n /**\n * Xato matni qanday shaklda qaytsin:\n * - `\"text\"` (default) — tayyor inglizcha jumla, i18n'siz app ham o'qiydi;\n * - `\"key\"` — `querykit.filter.*` kaliti, `nestjs-i18n`ning `I18nValidationPipe`i\n * uni so'rovning tiliga tarjima qiladi.\n */\n messageStyle?: \"text\" | \"key\";\n}\n\nexport type IsQueryFilterOptions = QueryFilterOptions & MessageStyleOptions;\nexport type IsQuerySortOptions = QuerySortOptions & MessageStyleOptions;\n\n/* -------------------------------- helpers --------------------------------- */\n\nconst optionsOf = <TOptions extends MessageStyleOptions>(args: ValidationArguments | undefined, fallbackPath: string): TOptions => {\n const given = (args?.constraints?.[0] ?? {}) as TOptions;\n /* Xato yo'li DTO property nomidan boshlansin: `where` deb nomlangan maydon\n * `filter.operation` emas, `where.operation` deb chiqadi. */\n return { rootPath: args?.property ?? fallbackPath, ...given };\n};\n\nconst firstMessage = (issues: ValidationIssue[], options: MessageStyleOptions, args: ValidationArguments | undefined, fallback: string): string => {\n const first = issues[0];\n if (!first) return `${args?.property ?? \"value\"} ${fallback}`;\n return options.messageStyle === \"key\" ? first.key : first.message;\n};\n\n/* ------------------------------- constraints ------------------------------ */\n/* DIQQAT: class-validator konstraint instansiyasini bir marta yaratib, barcha\n * so'rovlar uchun qayta ishlatadi. Shu sababli issue'lar `this`da HECH QACHON\n * keshlanmaydi — parallel so'rovlarda xabarlar aralashib ketardi. `defaultMessage`\n * `validateFilter`ni qayta chaqiradi: u sof, holatsiz va arzon. */\n\n/** `@IsQueryFilter()` ortidagi konstraint — test va qayta ishlatish uchun ochiq. */\n@ValidatorConstraint({ name: \"isQueryFilter\", async: false })\nexport class IsQueryFilterConstraint implements ValidatorConstraintInterface {\n validate(value: unknown, args?: ValidationArguments): boolean {\n return validateFilter(value, optionsOf<IsQueryFilterOptions>(args, \"filter\")).length === 0;\n }\n\n defaultMessage(args?: ValidationArguments): string {\n const options = optionsOf<IsQueryFilterOptions>(args, \"filter\");\n return firstMessage(validateFilter(args?.value, options), options, args, \"is not a valid querykit filter\");\n }\n}\n\n/** `@IsQuerySort()` ortidagi konstraint. */\n@ValidatorConstraint({ name: \"isQuerySort\", async: false })\nexport class IsQuerySortConstraint implements ValidatorConstraintInterface {\n validate(value: unknown, args?: ValidationArguments): boolean {\n return validateSort(value, optionsOf<IsQuerySortOptions>(args, \"sort\")).length === 0;\n }\n\n defaultMessage(args?: ValidationArguments): string {\n const options = optionsOf<IsQuerySortOptions>(args, \"sort\");\n return firstMessage(validateSort(args?.value, options), options, args, \"is not a valid querykit sort\");\n }\n}\n\n/** `@IsWithinMaxOffset()` opsiyalari. */\nexport interface IsWithinMaxOffsetOptions {\n /**\n * `\"page\"` — property `page`, offset `(page - 1) × perPage` (o'sha obyektning `perPage`i,\n * yo'q bo'lsa core `DEFAULT_PER_PAGE`); `\"offset\"` — property qiymatining o'zi (infinite).\n */\n mode: \"page\" | \"offset\";\n /** Default — core `DEFAULT_MAX_OFFSET` (10 000). `Infinity` tekshiruvni o'chiradi. */\n maxOffset?: number;\n}\n\nconst maxOffsetOf = (args: ValidationArguments | undefined): number =>\n (args?.constraints?.[0] as IsWithinMaxOffsetOptions | undefined)?.maxOffset ?? DEFAULT_MAX_OFFSET;\n\n/** `@IsWithinMaxOffset()` ortidagi konstraint. Raqam bo'lmagan qiymatni `@IsInt()` rad etadi, bu yerda o'tadi. */\n@ValidatorConstraint({ name: \"isWithinMaxOffset\", async: false })\nexport class IsWithinMaxOffsetConstraint implements ValidatorConstraintInterface {\n validate(value: unknown, args?: ValidationArguments): boolean {\n if (typeof value !== \"number\") return true;\n const perPage = (args?.object as { perPage?: unknown } | undefined)?.perPage;\n const isPage = (args?.constraints?.[0] as IsWithinMaxOffsetOptions | undefined)?.mode === \"page\";\n return (isPage ? offsetOf(value, typeof perPage === \"number\" ? perPage : undefined) : value) <= maxOffsetOf(args);\n }\n\n defaultMessage(args?: ValidationArguments): string {\n return formatMessage(\"querykit.limit.exceeded\", { path: args?.property ?? \"offset\", limit: \"maxOffset\", max: maxOffsetOf(args) });\n }\n}\n\n/* ------------------------------- decorators ------------------------------- */\n\n/**\n * Sahifa chuqurligini cheklaydi: `page` uchun `(page - 1) × perPage`, infinite `offset` uchun\n * qiymatning o'zi `maxOffset`dan oshmasin. Chuqurroq sahifalar — cursor paginatsiya.\n *\n * @example\n * ```ts\n * class ListDto {\n * @IsOptional() @Type(() => Number) @IsInt() @IsPositive() @IsWithinMaxOffset({ mode: \"page\" })\n * page?: number;\n * }\n * ```\n */\nexport function IsWithinMaxOffset(options: IsWithinMaxOffsetOptions, validationOptions?: ValidationOptions): PropertyDecorator {\n return (target, propertyName) => {\n registerDecorator({\n target: target.constructor,\n propertyName: propertyName as string,\n options: validationOptions,\n constraints: [options],\n validator: IsWithinMaxOffsetConstraint,\n });\n };\n}\n\n/**\n * Property'ni querykit `Filter` kontraktiga tekshiradi: flat massiv (implicit AND),\n * nested `and`/`or`/`not` daraxti va core `FILTER_OPERATORS`ning to'liq to'plami.\n *\n * `undefined` qiymatni **rad etmaydi** — maydonni ixtiyoriy qilish uchun\n * `@IsOptional()` bilan birga ishlating (DTO'lardagi kabi).\n *\n * @example\n * ```ts\n * class ListUsersDto extends OffsetParamsDto {\n * @IsOptional()\n * @IsQueryFilter({ allowedKeys: [\"id\", \"name\", \"createdAt\"] })\n * declare filter?: Filter;\n * }\n * ```\n */\nexport function IsQueryFilter(options?: IsQueryFilterOptions, validationOptions?: ValidationOptions): PropertyDecorator {\n return (target, propertyName) => {\n registerDecorator({\n target: target.constructor,\n propertyName: propertyName as string,\n options: validationOptions,\n constraints: [options],\n validator: IsQueryFilterConstraint,\n });\n };\n}\n\n/**\n * Property'ni querykit `Sort` kontraktiga tekshiradi — `{ key, direction }[]`.\n * Qarang: {@link IsQueryFilter}.\n */\nexport function IsQuerySort(options?: IsQuerySortOptions, validationOptions?: ValidationOptions): PropertyDecorator {\n return (target, propertyName) => {\n registerDecorator({\n target: target.constructor,\n propertyName: propertyName as string,\n options: validationOptions,\n constraints: [options],\n validator: IsQuerySortConstraint,\n });\n };\n}\n"]}
@@ -0,0 +1,89 @@
1
+ 'use strict';
2
+
3
+ var chunkKXCJO556_cjs = require('./chunk-KXCJO556.cjs');
4
+ var classValidator = require('class-validator');
5
+ var core = require('@querykitjs/core');
6
+ var internal = require('@querykitjs/core/internal');
7
+
8
+ var optionsOf = (args, fallbackPath) => {
9
+ let given = args?.constraints?.[0] ?? {};
10
+ return { rootPath: args?.property ?? fallbackPath, ...given };
11
+ }, firstMessage = (issues, options, args, fallback) => {
12
+ let first = issues[0];
13
+ return first ? options.messageStyle === "key" ? first.key : first.message : `${args?.property ?? "value"} ${fallback}`;
14
+ }; exports.IsQueryFilterConstraint = class IsQueryFilterConstraint {
15
+ validate(value, args) {
16
+ return chunkKXCJO556_cjs.validateFilter(value, optionsOf(args, "filter")).length === 0;
17
+ }
18
+ defaultMessage(args) {
19
+ let options = optionsOf(args, "filter");
20
+ return firstMessage(chunkKXCJO556_cjs.validateFilter(args?.value, options), options, args, "is not a valid querykit filter");
21
+ }
22
+ };
23
+ exports.IsQueryFilterConstraint = chunkKXCJO556_cjs.__decorateClass([
24
+ classValidator.ValidatorConstraint({ name: "isQueryFilter", async: false })
25
+ ], exports.IsQueryFilterConstraint);
26
+ exports.IsQuerySortConstraint = class IsQuerySortConstraint {
27
+ validate(value, args) {
28
+ return chunkKXCJO556_cjs.validateSort(value, optionsOf(args, "sort")).length === 0;
29
+ }
30
+ defaultMessage(args) {
31
+ let options = optionsOf(args, "sort");
32
+ return firstMessage(chunkKXCJO556_cjs.validateSort(args?.value, options), options, args, "is not a valid querykit sort");
33
+ }
34
+ };
35
+ exports.IsQuerySortConstraint = chunkKXCJO556_cjs.__decorateClass([
36
+ classValidator.ValidatorConstraint({ name: "isQuerySort", async: false })
37
+ ], exports.IsQuerySortConstraint);
38
+ var maxOffsetOf = (args) => args?.constraints?.[0]?.maxOffset ?? core.DEFAULT_MAX_OFFSET; exports.IsWithinMaxOffsetConstraint = class IsWithinMaxOffsetConstraint {
39
+ validate(value, args) {
40
+ if (typeof value != "number") return true;
41
+ let perPage = args?.object?.perPage;
42
+ return (args?.constraints?.[0]?.mode === "page" ? internal.offsetOf(value, typeof perPage == "number" ? perPage : void 0) : value) <= maxOffsetOf(args);
43
+ }
44
+ defaultMessage(args) {
45
+ return chunkKXCJO556_cjs.formatMessage("querykit.limit.exceeded", { path: args?.property ?? "offset", limit: "maxOffset", max: maxOffsetOf(args) });
46
+ }
47
+ };
48
+ exports.IsWithinMaxOffsetConstraint = chunkKXCJO556_cjs.__decorateClass([
49
+ classValidator.ValidatorConstraint({ name: "isWithinMaxOffset", async: false })
50
+ ], exports.IsWithinMaxOffsetConstraint);
51
+ function IsWithinMaxOffset(options, validationOptions) {
52
+ return (target, propertyName) => {
53
+ classValidator.registerDecorator({
54
+ target: target.constructor,
55
+ propertyName,
56
+ options: validationOptions,
57
+ constraints: [options],
58
+ validator: exports.IsWithinMaxOffsetConstraint
59
+ });
60
+ };
61
+ }
62
+ function IsQueryFilter(options, validationOptions) {
63
+ return (target, propertyName) => {
64
+ classValidator.registerDecorator({
65
+ target: target.constructor,
66
+ propertyName,
67
+ options: validationOptions,
68
+ constraints: [options],
69
+ validator: exports.IsQueryFilterConstraint
70
+ });
71
+ };
72
+ }
73
+ function IsQuerySort(options, validationOptions) {
74
+ return (target, propertyName) => {
75
+ classValidator.registerDecorator({
76
+ target: target.constructor,
77
+ propertyName,
78
+ options: validationOptions,
79
+ constraints: [options],
80
+ validator: exports.IsQuerySortConstraint
81
+ });
82
+ };
83
+ }
84
+
85
+ exports.IsQueryFilter = IsQueryFilter;
86
+ exports.IsQuerySort = IsQuerySort;
87
+ exports.IsWithinMaxOffset = IsWithinMaxOffset;
88
+ //# sourceMappingURL=chunk-X7HMP7H7.cjs.map
89
+ //# sourceMappingURL=chunk-X7HMP7H7.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/decorators.ts"],"names":["IsQueryFilterConstraint","validateFilter","__decorateClass","ValidatorConstraint","IsQuerySortConstraint","validateSort","DEFAULT_MAX_OFFSET","IsWithinMaxOffsetConstraint","offsetOf","formatMessage","registerDecorator"],"mappings":"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","file":"chunk-X7HMP7H7.cjs","sourcesContent":["/**\n * `class-validator` o'rovi. Butun mantiq `validate.ts`da — bu yerda faqat\n * konstraint klasslari va ularni property'ga bog'laydigan dekorator factory'lari.\n *\n * Rekursiya `validateFilter` ichida bo'lgani uchun nested DTO klassi ham,\n * `@ValidateNested` ham kerak emas: butun `and`/`or`/`not` daraxti bitta\n * dekorator bilan tekshiriladi.\n */\nimport { registerDecorator, ValidatorConstraint } from \"class-validator\";\nimport type { ValidationArguments, ValidationOptions, ValidatorConstraintInterface } from \"class-validator\";\nimport { DEFAULT_MAX_OFFSET } from \"@querykitjs/core\";\nimport { offsetOf } from \"@querykitjs/core/internal\";\nimport { formatMessage } from \"./messages\";\nimport { validateFilter, validateSort, type QueryFilterOptions, type QuerySortOptions, type ValidationIssue } from \"./validate\";\n\n/** Dekorator darajasidagi qo'shimcha — yadro buni o'qimaydi. */\nexport interface MessageStyleOptions {\n /**\n * Xato matni qanday shaklda qaytsin:\n * - `\"text\"` (default) — tayyor inglizcha jumla, i18n'siz app ham o'qiydi;\n * - `\"key\"` — `querykit.filter.*` kaliti, `nestjs-i18n`ning `I18nValidationPipe`i\n * uni so'rovning tiliga tarjima qiladi.\n */\n messageStyle?: \"text\" | \"key\";\n}\n\nexport type IsQueryFilterOptions = QueryFilterOptions & MessageStyleOptions;\nexport type IsQuerySortOptions = QuerySortOptions & MessageStyleOptions;\n\n/* -------------------------------- helpers --------------------------------- */\n\nconst optionsOf = <TOptions extends MessageStyleOptions>(args: ValidationArguments | undefined, fallbackPath: string): TOptions => {\n const given = (args?.constraints?.[0] ?? {}) as TOptions;\n /* Xato yo'li DTO property nomidan boshlansin: `where` deb nomlangan maydon\n * `filter.operation` emas, `where.operation` deb chiqadi. */\n return { rootPath: args?.property ?? fallbackPath, ...given };\n};\n\nconst firstMessage = (issues: ValidationIssue[], options: MessageStyleOptions, args: ValidationArguments | undefined, fallback: string): string => {\n const first = issues[0];\n if (!first) return `${args?.property ?? \"value\"} ${fallback}`;\n return options.messageStyle === \"key\" ? first.key : first.message;\n};\n\n/* ------------------------------- constraints ------------------------------ */\n/* DIQQAT: class-validator konstraint instansiyasini bir marta yaratib, barcha\n * so'rovlar uchun qayta ishlatadi. Shu sababli issue'lar `this`da HECH QACHON\n * keshlanmaydi — parallel so'rovlarda xabarlar aralashib ketardi. `defaultMessage`\n * `validateFilter`ni qayta chaqiradi: u sof, holatsiz va arzon. */\n\n/** `@IsQueryFilter()` ortidagi konstraint — test va qayta ishlatish uchun ochiq. */\n@ValidatorConstraint({ name: \"isQueryFilter\", async: false })\nexport class IsQueryFilterConstraint implements ValidatorConstraintInterface {\n validate(value: unknown, args?: ValidationArguments): boolean {\n return validateFilter(value, optionsOf<IsQueryFilterOptions>(args, \"filter\")).length === 0;\n }\n\n defaultMessage(args?: ValidationArguments): string {\n const options = optionsOf<IsQueryFilterOptions>(args, \"filter\");\n return firstMessage(validateFilter(args?.value, options), options, args, \"is not a valid querykit filter\");\n }\n}\n\n/** `@IsQuerySort()` ortidagi konstraint. */\n@ValidatorConstraint({ name: \"isQuerySort\", async: false })\nexport class IsQuerySortConstraint implements ValidatorConstraintInterface {\n validate(value: unknown, args?: ValidationArguments): boolean {\n return validateSort(value, optionsOf<IsQuerySortOptions>(args, \"sort\")).length === 0;\n }\n\n defaultMessage(args?: ValidationArguments): string {\n const options = optionsOf<IsQuerySortOptions>(args, \"sort\");\n return firstMessage(validateSort(args?.value, options), options, args, \"is not a valid querykit sort\");\n }\n}\n\n/** `@IsWithinMaxOffset()` opsiyalari. */\nexport interface IsWithinMaxOffsetOptions {\n /**\n * `\"page\"` — property `page`, offset `(page - 1) × perPage` (o'sha obyektning `perPage`i,\n * yo'q bo'lsa core `DEFAULT_PER_PAGE`); `\"offset\"` — property qiymatining o'zi (infinite).\n */\n mode: \"page\" | \"offset\";\n /** Default — core `DEFAULT_MAX_OFFSET` (10 000). `Infinity` tekshiruvni o'chiradi. */\n maxOffset?: number;\n}\n\nconst maxOffsetOf = (args: ValidationArguments | undefined): number =>\n (args?.constraints?.[0] as IsWithinMaxOffsetOptions | undefined)?.maxOffset ?? DEFAULT_MAX_OFFSET;\n\n/** `@IsWithinMaxOffset()` ortidagi konstraint. Raqam bo'lmagan qiymatni `@IsInt()` rad etadi, bu yerda o'tadi. */\n@ValidatorConstraint({ name: \"isWithinMaxOffset\", async: false })\nexport class IsWithinMaxOffsetConstraint implements ValidatorConstraintInterface {\n validate(value: unknown, args?: ValidationArguments): boolean {\n if (typeof value !== \"number\") return true;\n const perPage = (args?.object as { perPage?: unknown } | undefined)?.perPage;\n const isPage = (args?.constraints?.[0] as IsWithinMaxOffsetOptions | undefined)?.mode === \"page\";\n return (isPage ? offsetOf(value, typeof perPage === \"number\" ? perPage : undefined) : value) <= maxOffsetOf(args);\n }\n\n defaultMessage(args?: ValidationArguments): string {\n return formatMessage(\"querykit.limit.exceeded\", { path: args?.property ?? \"offset\", limit: \"maxOffset\", max: maxOffsetOf(args) });\n }\n}\n\n/* ------------------------------- decorators ------------------------------- */\n\n/**\n * Sahifa chuqurligini cheklaydi: `page` uchun `(page - 1) × perPage`, infinite `offset` uchun\n * qiymatning o'zi `maxOffset`dan oshmasin. Chuqurroq sahifalar — cursor paginatsiya.\n *\n * @example\n * ```ts\n * class ListDto {\n * @IsOptional() @Type(() => Number) @IsInt() @IsPositive() @IsWithinMaxOffset({ mode: \"page\" })\n * page?: number;\n * }\n * ```\n */\nexport function IsWithinMaxOffset(options: IsWithinMaxOffsetOptions, validationOptions?: ValidationOptions): PropertyDecorator {\n return (target, propertyName) => {\n registerDecorator({\n target: target.constructor,\n propertyName: propertyName as string,\n options: validationOptions,\n constraints: [options],\n validator: IsWithinMaxOffsetConstraint,\n });\n };\n}\n\n/**\n * Property'ni querykit `Filter` kontraktiga tekshiradi: flat massiv (implicit AND),\n * nested `and`/`or`/`not` daraxti va core `FILTER_OPERATORS`ning to'liq to'plami.\n *\n * `undefined` qiymatni **rad etmaydi** — maydonni ixtiyoriy qilish uchun\n * `@IsOptional()` bilan birga ishlating (DTO'lardagi kabi).\n *\n * @example\n * ```ts\n * class ListUsersDto extends OffsetParamsDto {\n * @IsOptional()\n * @IsQueryFilter({ allowedKeys: [\"id\", \"name\", \"createdAt\"] })\n * declare filter?: Filter;\n * }\n * ```\n */\nexport function IsQueryFilter(options?: IsQueryFilterOptions, validationOptions?: ValidationOptions): PropertyDecorator {\n return (target, propertyName) => {\n registerDecorator({\n target: target.constructor,\n propertyName: propertyName as string,\n options: validationOptions,\n constraints: [options],\n validator: IsQueryFilterConstraint,\n });\n };\n}\n\n/**\n * Property'ni querykit `Sort` kontraktiga tekshiradi — `{ key, direction }[]`.\n * Qarang: {@link IsQueryFilter}.\n */\nexport function IsQuerySort(options?: IsQuerySortOptions, validationOptions?: ValidationOptions): PropertyDecorator {\n return (target, propertyName) => {\n registerDecorator({\n target: target.constructor,\n propertyName: propertyName as string,\n options: validationOptions,\n constraints: [options],\n validator: IsQuerySortConstraint,\n });\n };\n}\n"]}
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ var chunkX7HMP7H7_cjs = require('./chunk-X7HMP7H7.cjs');
4
+ require('./chunk-KXCJO556.cjs');
5
+
6
+
7
+
8
+ Object.defineProperty(exports, "IsQueryFilter", {
9
+ enumerable: true,
10
+ get: function () { return chunkX7HMP7H7_cjs.IsQueryFilter; }
11
+ });
12
+ Object.defineProperty(exports, "IsQueryFilterConstraint", {
13
+ enumerable: true,
14
+ get: function () { return chunkX7HMP7H7_cjs.IsQueryFilterConstraint; }
15
+ });
16
+ Object.defineProperty(exports, "IsQuerySort", {
17
+ enumerable: true,
18
+ get: function () { return chunkX7HMP7H7_cjs.IsQuerySort; }
19
+ });
20
+ Object.defineProperty(exports, "IsQuerySortConstraint", {
21
+ enumerable: true,
22
+ get: function () { return chunkX7HMP7H7_cjs.IsQuerySortConstraint; }
23
+ });
24
+ Object.defineProperty(exports, "IsWithinMaxOffset", {
25
+ enumerable: true,
26
+ get: function () { return chunkX7HMP7H7_cjs.IsWithinMaxOffset; }
27
+ });
28
+ Object.defineProperty(exports, "IsWithinMaxOffsetConstraint", {
29
+ enumerable: true,
30
+ get: function () { return chunkX7HMP7H7_cjs.IsWithinMaxOffsetConstraint; }
31
+ });
32
+ //# sourceMappingURL=decorators.cjs.map
33
+ //# sourceMappingURL=decorators.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"decorators.cjs"}
@@ -0,0 +1,4 @@
1
+ export { IsQueryFilter, IsQueryFilterConstraint, IsQuerySort, IsQuerySortConstraint, IsWithinMaxOffset, IsWithinMaxOffsetConstraint } from './chunk-UICYH7OH.js';
2
+ import './chunk-KT5JRG6S.js';
3
+ //# sourceMappingURL=decorators.js.map
4
+ //# sourceMappingURL=decorators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"decorators.js"}