{"_id":"@azhulin/pagination-typeorm","_rev":"3-c34fcb93e636dfca852fa57acc223b3f","name":"@azhulin/pagination-typeorm","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.0":{"name":"@azhulin/pagination-typeorm","version":"1.0.0","keywords":["pagination","cursor","cursor-pagination","keyset","keyset-pagination","offset-pagination","seek-pagination","typeorm","sql","postgres","query-builder","relay","typescript"],"author":{"name":"Alex Zhulin"},"license":"MIT","_id":"@azhulin/pagination-typeorm@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":"9ca93e79a720f596fadc7091e05736e3becf808f","tarball":"https://registry.npmjs.org/@azhulin/pagination-typeorm/-/pagination-typeorm-1.0.0.tgz","fileCount":9,"integrity":"sha512-BN0qsKL+XGNzyDYvO/XaBxLYXfBxX4nXn5Rbf/04TkMsP6CoV7ykeHZAZP2n9DXA3rwQTJIw6q3Zd0q5gPjjXg==","signatures":[{"sig":"MEUCIQDfdLRyMl3QICwzfIbllFETOK6Hz50ztSSc89uNEx+CIQIgDwkEKxInpxFPP0pGa+JPQhe2jJBhjFoyjUN8zgMbF1w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":9263},"main":"dist/index.js","_from":"file:azhulin-pagination-typeorm-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/1f5280a3d4afa8d1ee381386d760c3cf/azhulin-pagination-typeorm-1.0.0.tgz","_integrity":"sha512-BN0qsKL+XGNzyDYvO/XaBxLYXfBxX4nXn5Rbf/04TkMsP6CoV7ykeHZAZP2n9DXA3rwQTJIw6q3Zd0q5gPjjXg==","repository":{"url":"git+https://github.com/azhulin/pagination.git","type":"git","directory":"packages/typeorm"},"_npmVersion":"11.6.2","description":"TypeORM query-plan renderer for @azhulin/pagination-core (cursor + offset).","directories":{},"_nodeVersion":"22.19.0","dependencies":{"@azhulin/pagination-core":"^1.0.0"},"_hasShrinkwrap":false,"peerDependencies":{"typeorm":"^0.3.0"},"_npmOperationalInternal":{"tmp":"tmp/pagination-typeorm_1.0.0_1784640925404_0.5175611840318142","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@azhulin/pagination-typeorm","version":"1.1.0","keywords":["pagination","cursor","cursor-pagination","keyset","keyset-pagination","offset-pagination","seek-pagination","typeorm","sql","postgres","query-builder","relay","typescript"],"author":{"name":"Alex Zhulin"},"license":"MIT","_id":"@azhulin/pagination-typeorm@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":"00b882544bc657e7463fd58f68f30ab23158f65a","tarball":"https://registry.npmjs.org/@azhulin/pagination-typeorm/-/pagination-typeorm-1.1.0.tgz","fileCount":9,"integrity":"sha512-A36LtcO3TFf/HT3fgpefMhFkPdbB79uKBLZ/nXnl5aMlNHoXbLSGbmar8juFX6r/HZKB9dL41rhURXYJNSi1kg==","signatures":[{"sig":"MEUCIQCXRwZISwkcAib4NspKWjqGh7lN71p9JifwRU5zp5SpLwIgT0sTAHyMqjUHaNJM9w/Jb+bitfaCIgS+fbtvrYoc/g0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":9263},"main":"dist/index.js","_from":"file:azhulin-pagination-typeorm-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/89c97a283efd0ef5de15593c8073b3d8/azhulin-pagination-typeorm-1.1.0.tgz","_integrity":"sha512-A36LtcO3TFf/HT3fgpefMhFkPdbB79uKBLZ/nXnl5aMlNHoXbLSGbmar8juFX6r/HZKB9dL41rhURXYJNSi1kg==","repository":{"url":"git+https://github.com/azhulin/pagination.git","type":"git","directory":"packages/typeorm"},"_npmVersion":"11.6.2","description":"TypeORM query-plan renderer for @azhulin/pagination-core (cursor + offset).","directories":{},"_nodeVersion":"22.19.0","dependencies":{"@azhulin/pagination-core":"^1.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"typeorm":"^0.3.0"},"_npmOperationalInternal":{"tmp":"tmp/pagination-typeorm_1.1.0_1784712852277_0.20581700866071695","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@azhulin/pagination-typeorm","version":"1.2.0","description":"TypeORM query-plan renderer for @azhulin/pagination-core (cursor + offset).","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","keyset-pagination","offset-pagination","seek-pagination","typeorm","sql","postgres","query-builder","relay","typescript"],"author":{"name":"Alex Zhulin"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/azhulin/pagination.git","directory":"packages/typeorm"},"dependencies":{"@azhulin/pagination-core":"^1.2.0"},"peerDependencies":{"typeorm":"^0.3.0"},"scripts":{},"_id":"@azhulin/pagination-typeorm@1.2.0","bugs":{"url":"https://github.com/azhulin/pagination/issues"},"homepage":"https://github.com/azhulin/pagination#readme","_integrity":"sha512-kcV5+O6pQeGgD4TZLWmT2gQU3YPy4gwucTdmf5T7uzLi1BcpH5+QY9kNEVbJArXsb+G+n/02FdUmJ9juytNWhQ==","_resolved":"/private/var/folders/y0/gfj8tg7s6_56fbbh64kygfpc0000gp/T/3f557bf89e412e53b0fb5d109f191acd/azhulin-pagination-typeorm-1.2.0.tgz","_from":"file:azhulin-pagination-typeorm-1.2.0.tgz","_nodeVersion":"22.19.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-kcV5+O6pQeGgD4TZLWmT2gQU3YPy4gwucTdmf5T7uzLi1BcpH5+QY9kNEVbJArXsb+G+n/02FdUmJ9juytNWhQ==","shasum":"a80bb5db791eba7b2f0fd607f8f7a8213ce7dc2c","tarball":"https://registry.npmjs.org/@azhulin/pagination-typeorm/-/pagination-typeorm-1.2.0.tgz","fileCount":9,"unpackedSize":9263,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDOQ/a+ZgvjHiG5rnC0zhWQzVU3dPVviA/DyABgPgT3jQIhAK+iSW8NUNyDZcuixzGBnklf/QpFjR03yahXmFWUz+Ny"}]},"_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-typeorm_1.2.0_1784726763783_0.9212940023347911"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-21T13:35:25.253Z","modified":"2026-07-22T13:26:04.064Z","1.0.0":"2026-07-21T13:35:25.560Z","1.1.0":"2026-07-22T09:34:12.414Z","1.2.0":"2026-07-22T13:26:03.920Z"},"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","keyset-pagination","offset-pagination","seek-pagination","typeorm","sql","postgres","query-builder","relay","typescript"],"repository":{"type":"git","url":"git+https://github.com/azhulin/pagination.git","directory":"packages/typeorm"},"description":"TypeORM query-plan renderer for @azhulin/pagination-core (cursor + offset).","maintainers":[{"name":"azhulin","email":"zhulin.dem@gmail.com"}],"readme":"# Pagination (TypeORM)\n\nRuns a [`@azhulin/pagination-core`](../core) `QueryPlan` on a TypeORM `SelectQueryBuilder` — keyset bounds as `WHERE`,\nthe resolved order, and `take`/`skip`.\n\n```shell\nnpm i @azhulin/pagination-typeorm\n```\n\n`typeorm` is a peer dependency, so this adapter never pins your version — pass any real `SelectQueryBuilder`.\n\n## `applyQueryPlan`\n\n```ts\napplyQueryPlan(query: PaginatableQueryBuilder, plan: QueryPlan): void\n```\n\nPass your query builder (`SelectQueryBuilder<T>` satisfies `PaginatableQueryBuilder` structurally). It mutates `query`\nin place: adds each `ORDER BY` key (with `NULLS FIRST/LAST`), applies keyset `WHERE` bounds (cursor mode) or\n`skip(offset)` (offset mode), and `take(limit)` unless unbounded. Only cursor _values_ are parameterized; sort-key\n`field` identifiers are interpolated verbatim, so keep them trusted/whitelisted.\n\n## End to end\n\nBuild your base query (filters, joins), then let the paginator plan, render, and run:\n\n```ts\nimport { PaginationMode } from '@azhulin/pagination-core'\nimport type { Connection, ConnectionArgs, ConnectionEdge } from '@azhulin/pagination-core'\nimport { applyQueryPlan } from '@azhulin/pagination-typeorm'\nimport { UserPaginator } from './user.paginator' // the subclass from @azhulin/pagination-core's README\n\nasync function paginateUsersByGroup(args: ConnectionArgs, groupId: string): Promise<Connection<ConnectionEdge<User>>> {\n  const paginator = new UserPaginator(args, { maxLimit: 50, defaultLimit: 20 })\n  const plan = paginator.plan()\n\n  const query = dataSource.getRepository(User).createQueryBuilder('user').where('user.groupId = :groupId', { groupId })\n  applyQueryPlan(query, plan)\n\n  const rows = await query.getMany()\n  const totalCount = PaginationMode.Offset === plan.mode ? await query.getCount() : undefined // cursor mode runs no count\n\n  return paginator.connection({ rows, totalCount })\n}\n```\n\n## Generated SQL\n\nFor sort keys `email ASC, id ASC` and a forward `after` cursor, the adapter applies the tuple keyset comparison, order,\nand limit — shown here simplified:\n\n```sql\nWHERE user.groupId = $1\n  AND (user.email > $2 OR (user.email = $2 AND user.id > $3))  -- keyset tuple comparison (simplified)\nORDER BY user.email ASC NULLS LAST, user.id ASC NULLS LAST\nLIMIT 21   -- requested 20 + 1 probe row\n```\n\nThe emitted `WHERE` is more verbose: values use named `:cursor_*` parameters, and each key's `NULLS FIRST/LAST` is\nspelled out so nullable columns page correctly. Backward pages (`last`/`before`) flip both the direction and null\nplacement, and `connection()` reverses the rows back to natural order for you.\n\n## License\n\nMIT © 2022–2026 Alex Zhulin\n","readmeFilename":"README.md"}