{"_id":"@azhulin/pagination-class-validator","_rev":"3-f26dafd154592b59474d9524f15f7cfa","name":"@azhulin/pagination-class-validator","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.0":{"name":"@azhulin/pagination-class-validator","version":"1.0.0","keywords":["pagination","cursor","cursor-pagination","keyset-pagination","offset-pagination","class-validator","validation","dto","connection-arguments","relay","graphql","typescript"],"author":{"name":"Alex Zhulin"},"license":"MIT","_id":"@azhulin/pagination-class-validator@1.0.0","maintainers":[{"name":"azhulin","email":"zhulin.dem@gmail.com"}],"homepage":"https://github.com/azhulin/pagination#readme","bugs":{"url":"https://github.com/azhulin/pagination/issues"},"dist":{"shasum":"93033ca177cd8d64f912680e899d593d55398186","tarball":"https://registry.npmjs.org/@azhulin/pagination-class-validator/-/pagination-class-validator-1.0.0.tgz","fileCount":9,"integrity":"sha512-UazLCOsaBm1bxtJ5Ii3CIu4x57rGjAR/UcVNGm5pUQH1pUC1hCbe+lR1UmpR/wi1YhweNqJ89lJ4/UhFi7XgHA==","signatures":[{"sig":"MEYCIQDl/zUHpbhpTz328bN2cT4KN8lVnuJp745OkInooybGogIhAJPbjrrdf+EAhaxHAPl7bM9GbKkDARwEpK/W9LFVJa1W","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":10469},"main":"dist/index.js","_from":"file:azhulin-pagination-class-validator-1.0.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{},"_npmUser":{"name":"azhulin","email":"zhulin.dem@gmail.com"},"_resolved":"/private/var/folders/y0/gfj8tg7s6_56fbbh64kygfpc0000gp/T/fabc74a4ae9b9073beb11a5b8b188ab2/azhulin-pagination-class-validator-1.0.0.tgz","_integrity":"sha512-UazLCOsaBm1bxtJ5Ii3CIu4x57rGjAR/UcVNGm5pUQH1pUC1hCbe+lR1UmpR/wi1YhweNqJ89lJ4/UhFi7XgHA==","repository":{"url":"git+https://github.com/azhulin/pagination.git","type":"git","directory":"packages/class-validator"},"_npmVersion":"11.6.2","description":"class-validator connection arguments for @azhulin/pagination-core.","directories":{},"_nodeVersion":"22.19.0","dependencies":{"@azhulin/pagination-core":"^1.0.0"},"_hasShrinkwrap":false,"peerDependencies":{"class-validator":"^0.14.2","reflect-metadata":"^0.1.0 || ^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/pagination-class-validator_1.0.0_1784640922972_0.3956953851136469","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@azhulin/pagination-class-validator","version":"1.1.0","keywords":["pagination","cursor","cursor-pagination","keyset-pagination","offset-pagination","class-validator","validation","dto","connection-arguments","relay","graphql","typescript"],"author":{"name":"Alex Zhulin"},"license":"MIT","_id":"@azhulin/pagination-class-validator@1.1.0","maintainers":[{"name":"azhulin","email":"zhulin.dem@gmail.com"}],"homepage":"https://github.com/azhulin/pagination#readme","bugs":{"url":"https://github.com/azhulin/pagination/issues"},"dist":{"shasum":"94bcc2aff0cbab03f3cd87fb79e8198752711465","tarball":"https://registry.npmjs.org/@azhulin/pagination-class-validator/-/pagination-class-validator-1.1.0.tgz","fileCount":11,"integrity":"sha512-tmL00gFgAAjGsj4kRT98sMBi8Mwwjo/zqRKQcfCcdRryXPMIFVRr1K1PI1WJkhY3eUmAZ1l/5LUdb9B8tCWJew==","signatures":[{"sig":"MEUCIHcIE+iCa2G1u1h52Ac3HDFhSeDRRaU2AjEtVK/DuYLJAiEAoUiviev3N/XLketvQ/xYqTZU3d7oxtIBrX+q2wrSzEg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14345},"main":"dist/index.js","_from":"file:azhulin-pagination-class-validator-1.1.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{},"_npmUser":{"name":"azhulin","email":"zhulin.dem@gmail.com"},"_resolved":"/private/var/folders/y0/gfj8tg7s6_56fbbh64kygfpc0000gp/T/b88ea647f53a211664e244b1835a25ed/azhulin-pagination-class-validator-1.1.0.tgz","_integrity":"sha512-tmL00gFgAAjGsj4kRT98sMBi8Mwwjo/zqRKQcfCcdRryXPMIFVRr1K1PI1WJkhY3eUmAZ1l/5LUdb9B8tCWJew==","repository":{"url":"git+https://github.com/azhulin/pagination.git","type":"git","directory":"packages/class-validator"},"_npmVersion":"11.6.2","description":"class-validator connection arguments for @azhulin/pagination-core.","directories":{},"_nodeVersion":"22.19.0","dependencies":{"@azhulin/pagination-core":"^1.0.0"},"_hasShrinkwrap":false,"peerDependencies":{"class-validator":"^0.14.2","reflect-metadata":"^0.1.0 || ^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/pagination-class-validator_1.1.0_1784710505611_0.21978013893759907","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@azhulin/pagination-class-validator","version":"1.2.0","description":"class-validator connection arguments for @azhulin/pagination-core.","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"keywords":["pagination","cursor","cursor-pagination","keyset-pagination","offset-pagination","class-validator","validation","dto","connection-arguments","relay","graphql","typescript"],"author":{"name":"Alex Zhulin"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/azhulin/pagination.git","directory":"packages/class-validator"},"dependencies":{"@azhulin/pagination-core":"^1.2.0"},"peerDependencies":{"class-validator":"^0.14.2","reflect-metadata":"^0.1.0 || ^0.2.0"},"scripts":{},"_id":"@azhulin/pagination-class-validator@1.2.0","bugs":{"url":"https://github.com/azhulin/pagination/issues"},"homepage":"https://github.com/azhulin/pagination#readme","_integrity":"sha512-rqw9cQNjMdb7SvS2cpb7zyRakY7cq4oVES5fna0xKuC4bbjfPNRIgQ0+VZbhg6g7U3OzBh0IyIOxmLe2pBUaow==","_resolved":"/private/var/folders/y0/gfj8tg7s6_56fbbh64kygfpc0000gp/T/5da900cad0e7d03543dcf9e01fc63c55/azhulin-pagination-class-validator-1.2.0.tgz","_from":"file:azhulin-pagination-class-validator-1.2.0.tgz","_nodeVersion":"22.19.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-rqw9cQNjMdb7SvS2cpb7zyRakY7cq4oVES5fna0xKuC4bbjfPNRIgQ0+VZbhg6g7U3OzBh0IyIOxmLe2pBUaow==","shasum":"6305de515cd4e8d048845977f0387534ecb669c5","tarball":"https://registry.npmjs.org/@azhulin/pagination-class-validator/-/pagination-class-validator-1.2.0.tgz","fileCount":11,"unpackedSize":14345,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIF6OaCQU1sFKpnX87IdkFG5J4spP8YbcmVWKhekL2KCRAiEA2dGz6JB2lHS8mqShWNsTIycl+04RLG1voIbxUbZdz9c="}]},"_npmUser":{"name":"azhulin","email":"zhulin.dem@gmail.com"},"directories":{},"maintainers":[{"name":"azhulin","email":"zhulin.dem@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pagination-class-validator_1.2.0_1784726761116_0.8042968964686943"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-21T13:35:22.808Z","modified":"2026-07-22T13:26:01.389Z","1.0.0":"2026-07-21T13:35:23.112Z","1.1.0":"2026-07-22T08:55:05.745Z","1.2.0":"2026-07-22T13:26:01.248Z"},"bugs":{"url":"https://github.com/azhulin/pagination/issues"},"author":{"name":"Alex Zhulin"},"license":"MIT","homepage":"https://github.com/azhulin/pagination#readme","keywords":["pagination","cursor","cursor-pagination","keyset-pagination","offset-pagination","class-validator","validation","dto","connection-arguments","relay","graphql","typescript"],"repository":{"type":"git","url":"git+https://github.com/azhulin/pagination.git","directory":"packages/class-validator"},"description":"class-validator connection arguments for @azhulin/pagination-core.","maintainers":[{"name":"azhulin","email":"zhulin.dem@gmail.com"}],"readme":"# Pagination (class-validator)\n\nA [`class-validator`](https://github.com/typestack/class-validator) DTO for the core connection arguments: validates\nthem and keeps cursor and offset modes mutually exclusive, so you can return clean `400`s.\n\n```shell\nnpm i @azhulin/pagination-class-validator\n```\n\nPeer dependencies: `class-validator`, `reflect-metadata`.\n\n## `ConnectionArgsDto`\n\nUse it standalone, or extend it with your own filtering/sorting arguments:\n\n```ts\nimport { ConnectionArgsDto } from '@azhulin/pagination-class-validator'\nimport { IsNotEmpty } from 'class-validator'\n\nexport class UserConnectionArgsDto extends ConnectionArgsDto {\n  @IsNotEmpty()\n  public readonly groupId!: string\n}\n```\n\nRules applied:\n\n| Field              | Rules                                      |\n|--------------------|--------------------------------------------|\n| `after`, `before`  | optional, URL-safe base64, min length 1    |\n| `first`, `last`    | optional integer, `≥ 0` (Relay allows `0`) |\n| `page`, `pageSize` | optional integer, `≥ 1`                    |\n\nPlus **mode exclusivity**: any cursor argument (`after`/`before`/`first`/`last`) set alongside any offset argument\n(`page`/`pageSize`) fails validation. `first` + `last` together is allowed (Relay \"last of first\").\n\n```ts\nimport { validate } from 'class-validator'\nimport { plainToInstance } from 'class-transformer'\n\nconst dto = plainToInstance(ConnectionArgsDto, { page: 1, after: 'eyJpZCI6MX0' })\nawait validate(dto) // → 2 errors: `page` and `after` can't be combined\n```\n\n`ConnectionArgsDto` layers `@IsOptional` over `BaseConnectionArgsDto`, which holds the same value constraints and mode\nexclusivity but no optionality policy. Extend `BaseConnectionArgsDto` instead when you need a stricter policy (e.g.\nreject `null`) while reusing those constraints.\n\n## `MutuallyExclusive`\n\nThe decorator behind the mode check, exported for reuse — fails validation when the decorated property is set alongside\nany of the given siblings:\n\n```ts\nimport { MutuallyExclusive } from '@azhulin/pagination-class-validator'\n\nclass Filter {\n  @MutuallyExclusive(['ids'])\n  public readonly query?: string // rejected if `ids` is also set\n\n  public readonly ids?: string[]\n}\n```\n\n## License\n\nMIT © 2022–2026 Alex Zhulin\n","readmeFilename":"README.md"}