{"_id":"@benyou/nestjs-typeorm-paginate-v3","_rev":"3-aede5c3d1468dd8c7e07705944fb9f95","name":"@benyou/nestjs-typeorm-paginate-v3","dist-tags":{"latest":"3.1.4"},"versions":{"3.1.3":{"name":"@benyou/nestjs-typeorm-paginate-v3","author":{"name":"Benyou","email":"ashleighsimonelli@gmail.com"},"main":"./dist/index.js","repository":{"type":"git","url":"git+https://github.com/nestjsx/nestjs-typeorm-paginate.git"},"description":"use the original package, this is just for testing","keywords":["nestjs","typeorm","pagination","paginate"],"devDependencies":{"@nestjs/common":"^7.5.5","@nestjs/core":"^7.5.5","@nestjs/testing":"^7.0.0","@nestjs/typeorm":"^7.1.0","@types/jest":"^27.0.0","@types/node":"^16.3.3","coveralls":"^3.0.5","jest":"^26.6.3","mysql":"^2.17.1","prettier":"^2.1.2","reflect-metadata":"^0.1.13","rxjs":"^6.5.2","ts-jest":"^26.4.4","ts-node":"^10.0.0","typeorm":"^0.2.12","typescript":"^4.0.5"},"scripts":{"format":"prettier --write \"**/*.ts\"","setup:test":"ts-node node_modules/.bin/typeorm schema:sync","test":"jest --runInBand","coveralls":"yarn run test:cov --coverageReporters=text-lcov | coveralls","test:cov":"jest --coverage","build":"rm -rf ./dist && tsc && npm run build:index","build:index":"rm -rf ./index.js ./index.d.ts && tsc -d --skipLibCheck ./index.ts","prepublish":"npm run format && npm run build","postinstall":"node postinstall.js"},"peerDependencies":{"@nestjs/common":"^6.1.1 || ^5.6.2 || ^7.0.0 || ^8.0.0","typeorm":"^0.2.12"},"jest":{"coveragePathIgnorePatterns":["src/__tests__"],"moduleFileExtensions":["js","json","ts"],"rootDir":"src","testRegex":".spec.ts$","transform":{"^.+\\.(t|j)s$":"ts-jest"},"coverageDirectory":"../coverage"},"version":"3.1.3","dependencies":{"chalk":"^4.1.2"},"bugs":{"url":"https://github.com/nestjsx/nestjs-typeorm-paginate/issues"},"homepage":"https://github.com/nestjsx/nestjs-typeorm-paginate#readme","license":"ISC","gitHead":"824d3a3a5e34ecccf71fbc2bb2f0af3b77407999","_id":"@benyou/nestjs-typeorm-paginate-v3@3.1.3","_nodeVersion":"16.5.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-v4hcbWZi9YXDPtelkWrhRnwBo1RpdjiTM9IgtQc6gIkOt+nKwOIrxdV/3nGjNwQmF9IymoAsUb9eJ33I34tMSw==","shasum":"c04f94e7af30c2717880a54477111d272903a6b5","tarball":"https://registry.npmjs.org/@benyou/nestjs-typeorm-paginate-v3/-/nestjs-typeorm-paginate-v3-3.1.3.tgz","fileCount":23,"unpackedSize":34208,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHGF0TMX8TVHWu5Zfdz3Qd3LWqsdKunkRslwWcM+pnYzAiAfksD16yLhrELAZul4S9nTYYYxD6SSlRTW4P23R63oSQ=="}]},"_npmUser":{"name":"benyou","email":"benyoudev@gmail.com"},"directories":{},"maintainers":[{"name":"benyou","email":"benyoudev@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestjs-typeorm-paginate-v3_3.1.3_1634942923710_0.3369317857556049"},"_hasShrinkwrap":false},"3.1.4":{"name":"@benyou/nestjs-typeorm-paginate-v3","author":{"name":"Benyou","email":"ashleighsimonelli@gmail.com"},"main":"./dist/index.js","repository":{"type":"git","url":"git+https://github.com/nestjsx/nestjs-typeorm-paginate.git"},"description":"use the original package, this is just for testing","keywords":["nestjs","typeorm","pagination","paginate"],"devDependencies":{"@nestjs/common":"^7.5.5","@nestjs/core":"^7.5.5","@nestjs/testing":"^7.0.0","@nestjs/typeorm":"^7.1.0","@types/jest":"^27.0.0","@types/node":"^16.3.3","coveralls":"^3.0.5","jest":"^26.6.3","mysql":"^2.17.1","prettier":"^2.1.2","reflect-metadata":"^0.1.13","rxjs":"^6.5.2","ts-jest":"^26.4.4","ts-node":"^10.0.0","typeorm":"^0.2.12","typescript":"^4.0.5"},"scripts":{"format":"prettier --write \"**/*.ts\"","setup:test":"ts-node node_modules/.bin/typeorm schema:sync","test":"jest --runInBand","coveralls":"yarn run test:cov --coverageReporters=text-lcov | coveralls","test:cov":"jest --coverage","build":"rm -rf ./dist && tsc && npm run build:index","build:index":"rm -rf ./index.js ./index.d.ts && tsc -d --skipLibCheck ./index.ts","prepublish":"npm run format && npm run build","postinstall":"node postinstall.js"},"peerDependencies":{"@nestjs/common":"^6.1.1 || ^5.6.2 || ^7.0.0 || ^8.0.0","typeorm":"^0.2.12"},"jest":{"coveragePathIgnorePatterns":["src/__tests__"],"moduleFileExtensions":["js","json","ts"],"rootDir":"src","testRegex":".spec.ts$","transform":{"^.+\\.(t|j)s$":"ts-jest"},"coverageDirectory":"../coverage"},"version":"3.1.4","dependencies":{"chalk":"^4.1.2"},"bugs":{"url":"https://github.com/nestjsx/nestjs-typeorm-paginate/issues"},"homepage":"https://github.com/nestjsx/nestjs-typeorm-paginate#readme","license":"ISC","gitHead":"cbc2a3f45595a9ace2ccf03639cd171d591fdbd0","_id":"@benyou/nestjs-typeorm-paginate-v3@3.1.4","_nodeVersion":"16.5.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-2qx9SO6rC6SbdFTSfYRw+8/4DS3aJsBIH7jWGCt5YBbAaGJUyor5xKv1PmoRZyNGexzK11+09V23JTL8lbFWyQ==","shasum":"82bf36f9a3a0bff62c3aa6a750a4876ec430bf62","tarball":"https://registry.npmjs.org/@benyou/nestjs-typeorm-paginate-v3/-/nestjs-typeorm-paginate-v3-3.1.4.tgz","fileCount":23,"unpackedSize":34118,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhzHhqCRA9TVsSAnZWagAA6DYP/A+349XezV6aJlPr/vth\nE/2fhHJXOng98jyR4cZ4jzb9Ig/7F2mVKIZAO0mAUekvIdo9vq+7d3wiFaG4\nEJElNJ71wDIlaAMrwblO6YuHXaeJAmsT/3a8RQb2vk++PALIwXI/xv93gz3R\nynSNzxgprWKmC7WBQt5mZlX2PaCDAApNwCrNRZbUz80s+LRR2udayEV6sRQK\nb7tU8P3PFmTGMQCFKbiYdbJtwoGk2NF9r9XC52o5g4QgWg0mWz3QAh9CMbc7\n+L3zW35Xs3ZL36yf+IWM0p/qcf5c2MWVtifsoYz5ySjXvu0vmlwP06MlZaBT\ny1Tp59OHElY6DnWdG0MRhcFou9nQ7LIAtUsieqoz8y0PB/BI0bzjt+0d8aAq\nteXKT7AGlASj90eX+5DJah4/FlaRCUcpX3ROnEgLBs76yhCFHfjrO7RYocEC\nMEI08u6/toGlSsicJW6zkMYX1nO8sWRdvka8+2yzR2L5Rm1Y/Hx/aa6NkoUD\nWElNZdyBe6xUt/dDgHvNaEkNwfCNqXF9Ok4BrwK6IrPluFJJH75xV4AItcLC\nJuxwnLUEmr4mc7tmdu4nI7I5eUFVMWBnjuvN2/j8bxZdIb6i/+1jxTVi1wTB\n1XJPn8Bceqs5q3bOboZnWGH7wiA4IJJ1mKNuQE73aZZKYiSCHPXR9yf5doVb\n/5mT\r\n=1Ixx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAHnlrZoc789uLrP6DeIyyYW3tmUPVMGcQrX5p4WORvCAiAygOGY35NOb3WYnySOXYB5rSb2dtELJv/GcDdZJFx6pA=="}]},"_npmUser":{"name":"benyou","email":"benyoudev@gmail.com"},"directories":{},"maintainers":[{"name":"benyou","email":"benyoudev@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestjs-typeorm-paginate-v3_3.1.4_1634943676239_0.7341899119439195"},"_hasShrinkwrap":false}},"time":{"created":"2021-10-22T22:48:43.644Z","3.1.3":"2021-10-22T22:48:43.919Z","modified":"2022-04-04T18:28:31.567Z","3.1.4":"2021-10-22T23:01:16.402Z"},"maintainers":[{"name":"benyou","email":"benyoudev@gmail.com"}],"description":"use the original package, this is just for testing","homepage":"https://github.com/nestjsx/nestjs-typeorm-paginate#readme","keywords":["nestjs","typeorm","pagination","paginate"],"repository":{"type":"git","url":"git+https://github.com/nestjsx/nestjs-typeorm-paginate.git"},"author":{"name":"Benyou","email":"ashleighsimonelli@gmail.com"},"bugs":{"url":"https://github.com/nestjsx/nestjs-typeorm-paginate/issues"},"license":"ISC","readme":"<p align=\"center\"><img src=\"https://avatars1.githubusercontent.com/u/43827489?s=400&u=45ac0ac47d40b6d8f277c96bdf00244c10508aef&v=4\"/></p>\n<p align=\"center\">\n  <img src=\"https://github.com/nestjsx/nestjs-typeorm-paginate/workflows/Tests/badge.svg\"/>\n  <a href=\"https://www.npmjs.com/package/nestjs-typeorm-paginate\"><img src=\"https://img.shields.io/npm/v/nestjs-typeorm-paginate.svg\"/></a>\n  <a href='https://coveralls.io/github/nestjsx/nestjs-typeorm-paginate?branch=master'><img src='https://coveralls.io/repos/github/nestjsx/nestjs-typeorm-paginate/badge.svg?branch=master' alt='Coverage Status' /></a>\n  <img src=\"https://camo.githubusercontent.com/a34cfbf37ba6848362bf2bee0f3915c2e38b1cc1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265\" />\n  <a href=\"https://github.com/juliandavidmr/awesome-nestjs#components--libraries\"><img src=\"https://raw.githubusercontent.com/nestjsx/crud/master/img/awesome-nest.svg?sanitize=true\" alt=\"Awesome Nest\" /></a>\n  <a href=\"https://github.com/nestjs/nest\"><img src=\"https://raw.githubusercontent.com/nestjsx/crud/master/img/nest-powered.svg?sanitize=true\" alt=\"Nest Powered\" /></a>\n  <a href=\"https://packagequality.com/#?package=nestjs-typeorm-paginate\"><img src=\"https://packagequality.com/shield/nestjs-typeorm-paginate.svg\" /></a>\n  <a href=\"https://www.npmjs.com/org/nestjsx\">\n    <img src=\"https://img.shields.io/npm/dt/nestjs-typeorm-paginate.svg\" alt=\"npm downloads\" />\n  </a>\n</p>\n\n<h1 align=\"center\">Nestjs Typeorm paginate</h1>\n\n> [Please vote on your prefered method of querying! Take+Skip vs Limit+Offset](https://github.com/nestjsx/nestjs-typeorm-paginate/issues/576)\n\nPagination helper method for TypeORM repositories or queryBuilders with strict typings\n\n## Install\n\n```bash\n$ yarn add nestjs-typeorm-paginate\n```\nor\n```bash\n$ npm i nestjs-typeorm-paginate\n```\n\n## Usage\n\n##### Service\n\n###### Repository\n\n```ts\nimport { Injectable } from '@nestjs/common';\nimport { Repository } from 'typeorm';\nimport { InjectRepository } from '@nestjs/typeorm';\nimport { CatEntity } from './entities';\nimport {\n  paginate,\n  Pagination,\n  IPaginationOptions,\n} from 'nestjs-typeorm-paginate';\n\n@Injectable()\nexport class CatService {\n  constructor(\n    @InjectRepository(CatEntity)\n    private readonly repository: Repository<CatEntity>,\n  ) {}\n\n  async paginate(options: IPaginationOptions): Promise<Pagination<CatEntity>> {\n    return paginate<CatEntity>(this.repository, options);\n  }\n}\n```\n\n###### QueryBuilder\n\n```ts\nimport { Injectable } from '@nestjs/common';\nimport { Repository } from 'typeorm';\nimport { InjectRepository } from '@nestjs/typeorm';\nimport { CatEntity } from './entities';\nimport {\n  paginate,\n  Pagination,\n  IPaginationOptions,\n} from 'nestjs-typeorm-paginate';\n\n@Injectable()\nexport class CatService {\n  constructor(\n    @InjectRepository(CatEntity)\n    private readonly repository: Repository<CatEntity>,\n  ) {}\n\n  async paginate(options: IPaginationOptions): Promise<Pagination<CatEntity>> {\n    const queryBuilder = this.repository.createQueryBuilder('c');\n    queryBuilder.orderBy('c.name', 'DESC'); // Or whatever you need to do\n\n    return paginate<CatEntity>(queryBuilder, options);\n  }\n}\n```\n\n##### Controller\n\n```ts\nimport { Controller, DefaultValuePipe, Get, ParseIntPipe, Query } from '@nestjs/common';\nimport { CatService } from './cat.service';\nimport { CatEntity } from './cat.entity';\nimport { Pagination } from 'nestjs-typeorm-paginate';\n\n@Controller('cats')\nexport class CatsController {\n  constructor(private readonly catService: CatService) {}\n  @Get('')\n  async index(\n    @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number = 1,\n    @Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number = 10,\n  ): Promise<Pagination<CatEntity>> {\n    limit = limit > 100 ? 100 : limit;\n    return this.catService.paginate({\n      page,\n      limit,\n      route: 'http://cats.com/cats',\n    });\n  }\n}\n```\n\n> If you use `ParseIntPipe` on the query params (as in the example), don't forget to also add `DefaultValuePipe`. See [issue 517](https://github.com/nestjsx/nestjs-typeorm-paginate/issues/517) for more info.\n\n> the `route` property of the paginate options can also be the short version of an absolute path , In this case, it would be `/cats` instead of `http://cats.com/cats`\n\n### Example Response\n\n```json\n{\n  \"items\": [\n    {\n      \"lives\": 9,\n      \"type\": \"tabby\",\n      \"name\": \"Bobby\"\n    },\n    {\n      \"lives\": 2,\n      \"type\": \"Ginger\",\n      \"name\": \"Garfield\"\n    },\n    {\n      \"lives\": 6,\n      \"type\": \"Black\",\n      \"name\": \"Witch's mate\"\n    },\n    {\n      \"lives\": 7,\n      \"type\": \"Purssian Grey\",\n      \"name\": \"Alisdaya\"\n    },\n    {\n      \"lives\": 1,\n      \"type\": \"Alistair\",\n      \"name\": \"ali\"\n    },\n    ...\n  ],\n  \"meta\": {\n    \"itemCount\": 10,\n    \"totalItems\": 20,\n    \"itemsPerPage\": 10,\n    \"totalPages\": 5,\n    \"currentPage\": 2\n  },\n  \"links\" : {\n    \"first\": \"http://cats.com/cats?limit=10\",\n    \"previous\": \"http://cats.com/cats?page=1&limit=10\",\n    \"next\": \"http://cats.com/cats?page=3&limit=10\",\n    \"last\": \"http://cats.com/cats?page=5&limit=10\"\n  }\n}\n```\n\n`items`: An array of SomeEntity\n\n`meta.itemCount`: The length of items array (i.e., the amount of items on this page)\n`meta.totalItems`: The total amount of SomeEntity matching the filter conditions\n`meta.itemsPerPage`: The requested items per page (i.e., the `limit` parameter)\n\n`meta.totalPages`: The total amount of pages (based on the `limit`)\n`meta.currentPage`: The current page this paginator \"points\" to\n\n`links.first`: A URL for the first page to call | `\"\"` (blank) if no `route` is defined\n`links.previous`: A URL for the previous page to call | `\"\"` (blank) if no previous to call\n`links.next`: A URL for the next page to call | `\"\"` (blank) if no page to call\n`links.last`: A URL for the last page to call | `\"\"` (blank) if no `route` is defined\n\n\n> Do note that `links.first` may not have the 'page' query param defined\n\n## Find Parameters\n\n```ts\n@Injectable()\nexport class CatService {\n  constructor(\n    @InjectRepository(CatEntity)\n    private readonly repository: Repository<CatEntity>,\n  ) {}\n\n  async paginate(options: IPaginationOptions): Promise<Pagination<CatEntity>> {\n    return paginate<CatEntity>(this.repository, options, {\n      lives: 9,\n    });\n  }\n}\n```\n\n## Eager loading\n\nEager loading should work with typeorm's eager property out the box. Like so\n\n```typescript\nimport { Entity, OneToMany } from 'typeorm';\n\n@Entity()\nexport class CatEntity {\n  @OneToMany(t => TigerKingEntity, tigerKing.cats, {\n    eager: true,\n  })\n  tigerKings: TigerKingEntity[];\n}\n\n// service\nclass CatService {\n  constructor(private readonly repository: Repository<CatEntity>) {}\n\n  async paginate(page: number, limit: number): Promise<Pagination<CatEntity>> {\n    return paginate(this.repository, { page, limit });\n  }\n}\n```\n\n#### QueryBuilder\n\nHowever, when using the query builder you'll have to hydrate the entities yourself. Here is a crude example that I've used in the past. It's not great but this is partially what typeORM will do.\n\n```typescript\nconst results = paginate(queryBuilder, { page, limit });\n\nreturn new Pagination(\n  await Promise.all(\n    results.items.map(async (item: SomeEntity) => {\n      const hydrate = await this.someRepository.findByEntity(item);\n      item.hydrated = hydrate;\n\n      return item;\n    }),\n  ),\n  results.meta,\n  results.links,\n);\n```\n\n## Raw queries\n\n```typescript\nconst queryBuilder = this.repository\n  .createQueryBuilder<{ type: string; totalLives: string }>('c')\n  .select('c.type', 'type')\n  .addSelect('SUM(c.lives)', 'totalLives')\n  .groupBy('c.type')\n  .orderBy('c.type', 'DESC'); // Or whatever you need to do\n\nreturn paginateRaw(queryBuilder, options);\n```\n\n### Raw and Entities\n\nA similar approach is used for TypeORM's `getRawAndEntities`\n\nLet's assume there's a joined table that matches each cat with its cat toys.\nAnd we want to bring how many toys each cat has.\n\n```typescript\n\nconst queryBuilder = this.repository\n  .createQueryBuilder<{ type: string; totalLives: string }>('cat')\n    .leftJoinAndSelect('cat.toys', 'toys')\n    .addSelect('COUNT(toys)::INTEGER', 'toyCount')\n    .groupBy('cat.name');\n```\n\nThis will allow us to get the paginated cats information with the additional raw query to build our actual response value.\nThe return pagination object will be the same, but you're now able to handle or map the results and the raw objects as needed.\n\n```typescript\nconst [pagination, rawResults] = await paginateRawAndEntities(query, options);\npagination.items.map((item, index) => {\n  // we can do what we need with the items and raw results here\n  // change your items using rawResults.find(raw => raw.id === item.id)\n});\nreturn pagination;\n```\n\n#### Note about joined tables and raw values\n\nSince the values of the raw results will include all the joined table items as queried, you must make sure to handle the items as needed for your use case. Refer to TypeORM's [getRawAndEntities](https://github.com/typeorm/typeorm/blob/920e7812cd9d405df921f9ae9ce52ba0a9743bea/src/query-builder/SelectQueryBuilder.ts#L1047) implementation as needed.\n\nThe rawResults array will look something like this:\n\n```typescript\n[\n    { // Bobby appears 3 times due to the joined query\n      \"cat_lives\": 9,\n      \"cat_type\": \"tabby\",\n      \"cat_name\": \"Bobby\",\n      \"toyCount\": 3\n    },\n    {\n      \"cat_lives\": 9,\n      \"cat_type\": \"tabby\",\n      \"cat_name\": \"Bobby\",\n      \"toyCount\": 3\n    },\n    {\n      \"cat_lives\": 9,\n      \"cat_type\": \"tabby\",\n      \"cat_name\": \"Bobby\",\n      \"toyCount\": 3\n    },\n    {\n      \"cat_lives\": 2,\n      \"cat_type\": \"Ginger\",\n      \"cat_name\": \"Garfield\",\n      \"toyCount\": 1\n    },\n    ...\n]\n```\n\n## Custom meta data transformer\n\nIf you wanted to alter the meta data that is returned from the pagination object. Then use the `metaTransformer` in the options like so\n\n```ts\n\nclass CustomPaginationMeta {\n  constructor(\n    public readonly count: number,\n    public readonly total: number,\n  ) {}\n}\n\nreturn paginate<MyEntity, CustomPaginationMeta>(this.repository, { \n  page,\n  limit,\n  metaTransformer: (meta: IPaginationMeta): CustomPaginationMeta => new CustomPaginationMeta(\n    meta.itemCount,\n    meta.totalItems,\n  ),\n });\n```\n\nThis will result in the above returning `CustomPaginationMeta` in the `meta` property instead of the default `IPaginationMeta`.\n\n\n## Custom links query params labels\n\nIf you want to alter the `limit` and/or `page` labels in meta links, then use `routingLabels` in the options like so\n\n```ts\n\nreturn paginate<MyEntity>(this.repository, { \n  page,\n  limit,\n  routingLabels: {\n    limitLabel: 'page-size', // default: limit\n    pageLabel: 'current-page', //default: page\n  }\n });\n```\n\nThis will result links like `http://example.com/something?current-page=1&page-size=3`.\n","readmeFilename":"README.md"}