{"_id":"@borscht/prisma-extension-pagination","name":"@borscht/prisma-extension-pagination","dist-tags":{"latest":"0.8.0"},"versions":{"0.8.0":{"name":"@borscht/prisma-extension-pagination","version":"0.8.0","description":"Prisma Client extension for pagination with updated response body","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","dev":"tsc -w","test":"jest","lint":"eslint \"src/**/*.ts\" \"test/**/*.ts\"","format":"npm run lint -- --fix","prepare":"npm run build","setup":"prisma generate && prisma migrate deploy"},"repository":{"type":"git","url":"git+https://github.com/ZeroSkillCoding/prisma-extension-pagination.git"},"keywords":["node","prisma","prisma-client","prisma-extension"],"author":{"name":"deptyped","email":"deptyped@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/deptyped/prisma-extension-pagination/issues"},"homepage":"https://github.com/deptyped/prisma-extension-pagination#readme","peerDependencies":{"@prisma/client":"^4.9.0 || ^5.0.0 || ^6.0.0"},"devDependencies":{"@prisma/client":"^6.0.1","@types/jest":"^29.5.14","@types/node":"^20.12.7","@typescript-eslint/eslint-plugin":"^7.6.0","@typescript-eslint/parser":"^7.6.0","eslint":"^8.55.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.2.1","jest":"^29.7.0","prisma":"^6.0.1","ts-jest":"^29.2.5","typescript":"^5.7.2"},"_id":"@borscht/prisma-extension-pagination@0.8.0","gitHead":"dc82f437cb81621f92344f3739511c51a768a1b7","_nodeVersion":"22.19.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-CIVsk27MDi3UkVb1euC3ZZiFNxJmoYTDxIz4ybvzzTJ1IChwcn1+Ne5pt1znXf9B0N/O+Lnkip9w2yL+/EAu2A==","shasum":"b0757511a03cbe562df5c2c5aaae947d9b0a8b39","tarball":"https://registry.npmjs.org/@borscht/prisma-extension-pagination/-/prisma-extension-pagination-0.8.0.tgz","fileCount":15,"unpackedSize":24591,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIA47fFidG+XNUT2r63h43Lh5fcAHCx7pKJ+JT0dpnt2CAiEA7eC/p7kt70+OmIcMcPFUKVycOXEHUzPBjib//k/pnz0="}]},"_npmUser":{"name":"borscht","email":"nestevhenii@gmail.com"},"directories":{},"maintainers":[{"name":"borscht","email":"nestevhenii@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/prisma-extension-pagination_0.8.0_1758664230466_0.171542208890755"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-23T21:50:30.365Z","0.8.0":"2025-09-23T21:50:30.635Z","modified":"2025-09-23T21:50:30.928Z"},"maintainers":[{"name":"borscht","email":"nestevhenii@gmail.com"}],"description":"Prisma Client extension for pagination with updated response body","homepage":"https://github.com/deptyped/prisma-extension-pagination#readme","keywords":["node","prisma","prisma-client","prisma-extension"],"repository":{"type":"git","url":"git+https://github.com/ZeroSkillCoding/prisma-extension-pagination.git"},"author":{"name":"deptyped","email":"deptyped@gmail.com"},"bugs":{"url":"https://github.com/deptyped/prisma-extension-pagination/issues"},"license":"MIT","readme":"# Prisma Pagination Extension\r\n\r\n## Introduction\r\n\r\nPrisma Client extension for pagination.\r\n\r\n> **Note**\r\n> [Breaking change in `0.5.0`](https://github.com/deptyped/prisma-extension-pagination/releases/tag/v0.5.0)\r\n\r\n## Features\r\n\r\n- [Page number pagination](#page-number-pagination)\r\n- [Cursor-based pagination](#cursor-based-pagination)\r\n- Fully tested\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm i prisma-extension-pagination\r\n```\r\n\r\n### Install extension to all models\r\n\r\n```ts\r\nimport { PrismaClient } from \"@prisma/client\";\r\nimport { pagination } from \"prisma-extension-pagination\";\r\n\r\nconst prisma = new PrismaClient().$extends(pagination());\r\n```\r\n\r\n### Install extension on some models\r\n\r\n```ts\r\nimport { PrismaClient } from \"@prisma/client\";\r\nimport { paginate } from \"prisma-extension-pagination\";\r\n\r\nconst prisma = new PrismaClient().$extends({\r\n  model: {\r\n    user: {\r\n      paginate,\r\n    },\r\n  },\r\n});\r\n```\r\n\r\n### Change default settings\r\n\r\n```ts\r\nimport { PrismaClient } from \"@prisma/client\";\r\nimport { pagination } from \"prisma-extension-pagination\";\r\n\r\nconst prisma = new PrismaClient().$extends(\r\n  pagination({\r\n    pages: {\r\n      limit: 10, // set default limit to 10\r\n      includePageCount: true, // include counters by default\r\n    },\r\n    cursor: {\r\n      limit: 10, // set default limit to 10\r\n\r\n      // set default cursor serialization/deserialization\r\n      getCursor(user: UserType) {\r\n        // ...\r\n      },\r\n      parseCursor(cursor) {\r\n        // ...\r\n      },\r\n    },\r\n  })\r\n);\r\n```\r\n\r\nWhen using the extension on some models, you need to use `createPaginator` function to set the default values:\r\n\r\n```ts\r\nimport { PrismaClient } from \"@prisma/client\";\r\nimport { createPaginator } from \"prisma-extension-pagination\";\r\n\r\nconst paginate = createPaginator({\r\n  // available settings are the same as above\r\n  pages: {\r\n    // ...\r\n  },\r\n  cursor: {\r\n    //...\r\n  },\r\n});\r\n\r\n// You can create many paginators with different settings.\r\n// They can be reused for different models.\r\n\r\nconst prisma = new PrismaClient().$extends({\r\n  model: {\r\n    user: {\r\n      paginate,\r\n    },\r\n    post: {\r\n      paginate,\r\n    },\r\n  },\r\n});\r\n```\r\n\r\n## Usage\r\n\r\n### Page number pagination\r\n\r\nPage number pagination uses `limit` to select a limited range and `page` to load a specific page of results.\r\n\r\n- [Load first page](#load-first-page)\r\n- [Load specific page](#load-specific-page)\r\n- [Calculate page count](#calculate-page-count)\r\n\r\n#### Load first page\r\n\r\n```ts\r\nconst [users, meta] = await prisma.user\r\n  .paginate({\r\n    select: {\r\n      id: true,\r\n    }\r\n  })\r\n  .withPages({\r\n    limit: 10,\r\n  });\r\n\r\n// meta contains the following\r\n{\r\n  currentPage: 1,\r\n  isFirstPage: true,\r\n  isLastPage: false,\r\n  previousPage: null,\r\n  nextPage: 2,\r\n}\r\n```\r\n\r\n#### Load specific page\r\n\r\n```ts\r\nconst [users, meta] = await prisma.user\r\n  .paginate()\r\n  .withPages({\r\n    limit: 10,\r\n    page: 2,\r\n  });\r\n\r\n// meta contains the following\r\n{\r\n  currentPage: 2,\r\n  isFirstPage: false,\r\n  isLastPage: false,\r\n  previousPage: 1,\r\n  nextPage: 3,\r\n}\r\n```\r\n\r\n#### Calculate page count\r\n\r\n```ts\r\nconst [users, meta] = await prisma.user\r\n  .paginate()\r\n  .withPages({\r\n    limit: 10,\r\n    page: 2,\r\n    includePageCount: true,\r\n  });\r\n\r\n// meta contains the following\r\n{\r\n  currentPage: 2,\r\n  isFirstPage: false,\r\n  isLastPage: false,\r\n  previousPage: 1,\r\n  nextPage: 3,\r\n  pageCount: 10, // the number of pages is calculated\r\n  totalCount: 100, // the total number of results is calculated\r\n}\r\n```\r\n\r\n### Cursor-based pagination\r\n\r\nCursor-based pagination uses `limit` to select a limited range\r\nand `before` or `after` to return a set of results before or after a given cursor.\r\n\r\n- [Load first records](#load-first-records)\r\n- [Load next page](#load-next-page)\r\n- [Load previous page](#load-previous-page)\r\n- [Custom cursor serialization](#custom-cursor-serialization)\r\n- [Load all results](#load-all-results)\r\n\r\n#### Load first records\r\n\r\n```ts\r\nconst [users, meta] = await prisma.user\r\n  .paginate({\r\n    select: {\r\n      id: true,\r\n    }\r\n  })\r\n  .withCursor({\r\n    limit: 10,\r\n  });\r\n\r\n// meta contains the following\r\n{\r\n  hasPreviousPage: false,\r\n  hasNextPage: true,\r\n  startCursor: \"1\",\r\n  endCursor: \"10\"\r\n}\r\n```\r\n\r\n#### Load next page\r\n\r\n```ts\r\nconst [users, meta] = await prisma.user\r\n  .paginate()\r\n  .withCursor({\r\n    limit: 10,\r\n    after: \"10\"\r\n  });\r\n\r\n// meta contains the following\r\n{\r\n  hasPreviousPage: true,\r\n  hasNextPage: true,\r\n  startCursor: \"11\",\r\n  endCursor: \"20\"\r\n}\r\n```\r\n\r\n#### Load previous page\r\n\r\n```ts\r\nconst [users, meta] = await prisma.user\r\n  .paginate()\r\n  .withCursor({\r\n    limit: 10,\r\n    before: \"11\"\r\n  });\r\n\r\n// meta contains the following\r\n{\r\n  hasPreviousPage: false,\r\n  hasNextPage: true,\r\n  startCursor: \"1\",\r\n  endCursor: \"10\"\r\n}\r\n```\r\n\r\n#### Custom cursor serialization\r\n\r\n```ts\r\nconst getCustomCursor = (postId: number, userId: number) =>\r\n  [postId, userId].join(\":\");\r\n\r\nconst parseCustomCursor = (cursor: string) =>\r\n  cursor.split(\":\");\r\n\r\nconst [results, meta] = await prisma.postOnUser\r\n  .paginate({\r\n    select: {\r\n      postId: true,\r\n      userId: true,\r\n    },\r\n  })\r\n  .withCursor({\r\n    limit: 10,\r\n    after: getCustomCursor(1, 1), // \"1:1\"\r\n\r\n    // custom cursor serialization\r\n    getCursor({ postId, userId }) {\r\n      return getCustomCursor(postId, userId)\r\n    },\r\n\r\n    // custom cursor deserialization\r\n    parseCursor(cursor) {\r\n      const [postId, userId] = parseCustomCursor(cursor);\r\n\r\n      return {\r\n        userId_postId: {\r\n          postId: parseInt(postId),\r\n          userId: parseInt(userId),\r\n        },\r\n      };\r\n    },\r\n  });\r\n\r\n// meta contains the following\r\n{\r\n  hasPreviousPage: false,\r\n  hasNextPage: true,\r\n  startCursor: \"1:2\",\r\n  endCursor: \"1:11\"\r\n}\r\n```\r\n\r\n### Load all results\r\n\r\nSometimes it's useful to return all results, if you need to do that, you can pass `limit: null`.\r\n\r\n## License\r\n\r\nThis project is licensed under the terms of the MIT license.\r\n","readmeFilename":"README.md","_rev":"1-f956d171a5cfa5ca2878ca2cd9ac2c67"}