{"_id":"@blogcode/nest-typeorm-pagination","_rev":"4-f5e7e2c8a1c028e0ca9ccb6b6263f63b","name":"@blogcode/nest-typeorm-pagination","dist-tags":{"latest":"0.0.5"},"versions":{"0.0.1":{"name":"@blogcode/nest-typeorm-pagination","version":"0.0.1","author":{"name":"Canh Nguyen Van","email":"ngvcanh2014@gmail.com"},"license":"MIT","_id":"@blogcode/nest-typeorm-pagination@0.0.1","maintainers":[{"name":"kensoni","email":"ngvcanh2014@gmail.com"}],"dist":{"shasum":"3c1d1727556eef95ee1f2c59b8ec3f66a4389a78","tarball":"https://registry.npmjs.org/@blogcode/nest-typeorm-pagination/-/nest-typeorm-pagination-0.0.1.tgz","fileCount":17,"integrity":"sha512-XEejTbaWzp5t/EvVbaP3TTn8HooRwRKhktH0zdvqfe0aJ8Hu9FzT41yuQsWXwkXp6RLutyR6zTS7TPYp4fv0HA==","signatures":[{"sig":"MEUCIEhg1pDQEddCi8xhoAn0rf7HNXtXj8Chue2u0JMEMQGyAiEAyS4ZhgtjpR9hM6UCZWmJuQNjolwlLplnH2X6KVZZEJg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":34646},"main":"./index.js","types":"./index.d.ts","scripts":{"build":"tsc"},"_npmUser":{"name":"kensoni","email":"ngvcanh2014@gmail.com"},"repository":{"url":"git@github.com:blogcodevn/nest-typeorm-pagination.git","type":"git"},"description":"Pagination offset-based and cursor-based for NestJS","directories":{},"licenseText":"MIT License\n\nCopyright (c) 2024 blogcodevn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.19.2","typeorm":"^0.3.20","typescript":"^5.5.3","@nestjs/common":"^10.3.10","@types/express":"^4.17.21"},"peerDependencies":{"typeorm":"^0.3.20","@nestjs/common":"^10.3.10"},"_npmOperationalInternal":{"tmp":"tmp/nest-typeorm-pagination_0.0.1_1720979404213_0.10113115893662461","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"@blogcode/nest-typeorm-pagination","version":"0.0.2","keywords":["nestjs","typeorm","pagination","offset-based","cursor-based"],"author":{"name":"Canh Nguyen Van","email":"ngvcanh2014@gmail.com"},"license":"MIT","_id":"@blogcode/nest-typeorm-pagination@0.0.2","maintainers":[{"name":"kensoni","email":"ngvcanh2014@gmail.com"}],"homepage":"https://github.com/blogcodevn/nest-typeorm-pagination#readme","dist":{"shasum":"6c530860f77e14f52602ba0aaa15efa36ab1f194","tarball":"https://registry.npmjs.org/@blogcode/nest-typeorm-pagination/-/nest-typeorm-pagination-0.0.2.tgz","fileCount":18,"integrity":"sha512-CQQuKGUbCAtY5QPafP9zz490Di1nql4c1BJeim4Q9KSWh+a8b5AaovYSj4hZlVDSrTiOIzDoPpA5DczfO3/PcA==","signatures":[{"sig":"MEUCIBq18fXEe+Je7zSQwkznb6CGpjSvJL/31UDE/rwLU50+AiEAw3pe0oP9gok7Q4Q04tvxqzc2JdOAcxwhvZ4TitW+Rq0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":36744},"main":"./index.js","types":"./index.d.ts","scripts":{"build":"tsc"},"_npmUser":{"name":"kensoni","email":"ngvcanh2014@gmail.com"},"repository":{"url":"git+https://github.com/blogcodevn/nest-typeorm-pagination.git","type":"git"},"description":"Pagination offset-based and cursor-based for NestJS","directories":{},"licenseText":"MIT License\n\nCopyright (c) 2024 blogcodevn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.19.2","typeorm":"^0.3.20","typescript":"^5.5.3","@nestjs/common":"^10.3.10","@types/express":"^4.17.21"},"peerDependencies":{"typeorm":"^0.3.20","@nestjs/common":"^10.3.10"},"_npmOperationalInternal":{"tmp":"tmp/nest-typeorm-pagination_0.0.2_1723789435757_0.6177425336209892","host":"s3://npm-registry-packages"}},"0.0.3":{"name":"@blogcode/nest-typeorm-pagination","version":"0.0.3","keywords":["nestjs","typeorm","pagination","offset-based","cursor-based"],"author":{"name":"Canh Nguyen Van","email":"ngvcanh2014@gmail.com"},"license":"MIT","_id":"@blogcode/nest-typeorm-pagination@0.0.3","maintainers":[{"name":"kensoni","email":"ngvcanh2014@gmail.com"}],"homepage":"https://github.com/blogcodevn/nest-typeorm-pagination#readme","dist":{"shasum":"c523c5d72413cd22e0826ecd7fd63c73a586d7bd","tarball":"https://registry.npmjs.org/@blogcode/nest-typeorm-pagination/-/nest-typeorm-pagination-0.0.3.tgz","fileCount":18,"integrity":"sha512-achv/MvLicZLhzJinBqMPRJkHkRn9M61dt6ZQdFEsriIpf//bgNwDDiLznfIXWHjDdxJ5ldF2Tu0XLZ81TDhXw==","signatures":[{"sig":"MEQCIEk9DQmOIJWJTatcVjvCTq6ESW0U/2BAW8ydXDL8ndxuAiBa8Z4kFKNvDfsar+p4qI3NE5rZD9kTGAHwkfKWk160nQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":36824},"main":"./index.js","types":"./index.d.ts","scripts":{"build":"tsc"},"_npmUser":{"name":"kensoni","email":"ngvcanh2014@gmail.com"},"repository":{"url":"git+https://github.com/blogcodevn/nest-typeorm-pagination.git","type":"git"},"description":"Pagination offset-based and cursor-based for NestJS","directories":{},"licenseText":"MIT License\n\nCopyright (c) 2024 blogcodevn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.19.2","typeorm":"^0.3.20","typescript":"^5.5.3","@nestjs/common":"^10.3.10","@types/express":"^4.17.21"},"peerDependencies":{"typeorm":"^0.3.20","@nestjs/common":"^10.3.10"},"_npmOperationalInternal":{"tmp":"tmp/nest-typeorm-pagination_0.0.3_1737106897815_0.6984806993489503","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@blogcode/nest-typeorm-pagination","version":"0.0.4","keywords":["nestjs","typeorm","pagination","offset-based","cursor-based"],"author":{"name":"Canh Nguyen Van","email":"ngvcanh2014@gmail.com"},"license":"MIT","_id":"@blogcode/nest-typeorm-pagination@0.0.4","maintainers":[{"name":"kensoni","email":"ngvcanh2014@gmail.com"}],"homepage":"https://github.com/blogcodevn/nest-typeorm-pagination#readme","dist":{"shasum":"cf615e408c670b06850628347f2ea93b8ef0302c","tarball":"https://registry.npmjs.org/@blogcode/nest-typeorm-pagination/-/nest-typeorm-pagination-0.0.4.tgz","fileCount":18,"integrity":"sha512-GzQEW0nhKKZRb8bsBVmIi75WGxPBGbFacZfT3ltp/SGAXebpeqZdxamQi7T7EV93Qk0HvKy6VIQi1c0b4b+87w==","signatures":[{"sig":"MEYCIQDvSG+5sjThiToOgAy/0SYdYOMFLae6eKehX/LcuR3aRAIhAKqGjLAihbBBRM+I+FpNOZhSe5HrWHWlrWY5sNWaG7K2","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37462},"main":"./index.js","types":"./index.d.ts","scripts":{"build":"tsc"},"_npmUser":{"name":"kensoni","email":"ngvcanh2014@gmail.com"},"repository":{"url":"git+https://github.com/blogcodevn/nest-typeorm-pagination.git","type":"git"},"description":"Pagination offset-based and cursor-based for NestJS","directories":{},"licenseText":"MIT License\n\nCopyright (c) 2024 blogcodevn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.19.2","typeorm":"^0.3.20","typescript":"^5.5.3","@nestjs/common":"^10.3.10","@types/express":"^4.17.21"},"peerDependencies":{"typeorm":"^0.3.20","@nestjs/common":"^10.3.10"},"_npmOperationalInternal":{"tmp":"tmp/nest-typeorm-pagination_0.0.4_1737107746814_0.6691270594770098","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@blogcode/nest-typeorm-pagination","version":"0.0.5","description":"Pagination offset-based and cursor-based for NestJS","keywords":["nestjs","typeorm","pagination","offset-based","cursor-based"],"main":"./index.js","types":"./index.d.ts","repository":{"type":"git","url":"git+https://github.com/blogcodevn/nest-typeorm-pagination.git"},"homepage":"https://github.com/blogcodevn/nest-typeorm-pagination#readme","author":{"name":"Canh Nguyen Van","email":"ngvcanh2014@gmail.com"},"license":"MIT","publishConfig":{"access":"public"},"scripts":{"build":"tsc"},"peerDependencies":{"@nestjs/common":"^10.3.10","typeorm":"^0.3.20"},"devDependencies":{"@nestjs/common":"^10.3.10","@types/express":"^4.17.21","express":"^4.19.2","typeorm":"^0.3.20","typescript":"^5.5.3"},"licenseText":"MIT License\n\nCopyright (c) 2024 blogcodevn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"@blogcode/nest-typeorm-pagination@0.0.5","dist":{"shasum":"6e28e3bb9ecdd4f83a3ed0c5deea7c9800995273","integrity":"sha512-Tl4BPWp7kSUwCOeiw+PxjWwHR5tQ1IgNXESY3ys1NL3YDZ0wPIyVj+aSqJFGoMlVGuNgXjtPJy6ntWFz3XX/Cw==","tarball":"https://registry.npmjs.org/@blogcode/nest-typeorm-pagination/-/nest-typeorm-pagination-0.0.5.tgz","fileCount":18,"unpackedSize":38349,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG+Hqm7LQwtGYAa8r5D/JLuTnZ0f5HoPgJAHSvUwuBSZAiA9BA4OxImWfxiiiSAmfjcGrsyB17Za+zVmFGEC+/vHqg=="}]},"_npmUser":{"name":"kensoni","email":"ngvcanh2014@gmail.com"},"directories":{},"maintainers":[{"name":"kensoni","email":"ngvcanh2014@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nest-typeorm-pagination_0.0.5_1737109889270_0.18403112064058913"},"_hasShrinkwrap":false}},"time":{"created":"2024-07-14T17:50:04.110Z","modified":"2025-01-17T10:31:29.676Z","0.0.1":"2024-07-14T17:50:04.386Z","0.0.2":"2024-08-16T06:23:55.957Z","0.0.3":"2025-01-17T09:41:37.995Z","0.0.4":"2025-01-17T09:55:47.006Z","0.0.5":"2025-01-17T10:31:29.479Z"},"author":{"name":"Canh Nguyen Van","email":"ngvcanh2014@gmail.com"},"license":"MIT","homepage":"https://github.com/blogcodevn/nest-typeorm-pagination#readme","keywords":["nestjs","typeorm","pagination","offset-based","cursor-based"],"repository":{"type":"git","url":"git+https://github.com/blogcodevn/nest-typeorm-pagination.git"},"description":"Pagination offset-based and cursor-based for NestJS","maintainers":[{"name":"kensoni","email":"ngvcanh2014@gmail.com"}],"readme":"# @blogcode/nest-typeorm-pagination\n\n- Current support `PostgresQL`, `MySQL`, `MariaDB`.\n- Others DB does not tested.\n\n## CHANGELOG\n\n- `0.0.5`:\n  - Fix build condition where with `IS NULL` and `IS NOT NULL`;\n\n- `0.0.4`:\n  - Normalize field for query. (EX: group => \"group\" with PostgresQL)\n\n- `0.0.3`:\n  - Add `null` is base type.\n\n- `0.0.2`:\n  - Support search `OR`\n  - Support operator `fts` (Full Text Search)\n\n## Installation\n\nInstall dependencies\n\n```bash\n# npm\nnpm i @nestjs/common typeorm\n\n# OR\n\n# yarn\nyarn add @nestjs/common typeorm\n```\n\nInstall package\n\n```bash\n# npm\nnpm i @blogcode/nest-typeorm-pagination\n\n# OR\n\n# yarn\nyarn add @blogcode/nest-typeorm-pagination\n```\n\n## Using\n\n### Filter string for Offset bases\n\n```\npage=1&limit=10&filters[name]=abc&filters[age][value]=18&filters[age][operator]=gte&order[name]=1&order[age]=0\n```\n\n- `page=1`: Get page 1, offset 0\n- `limit=10`: Per page 10 records.\n- `filters[name]=abc`: Field `name` or alias `name` equal to `abc`.\n- `filters[age][value]=18`: Field `age` or alias `age` will be compare.\n- `filters[age][operator]=gte`: Field `age` or alias `age` compare greater than or equal to `18`.\n- `order[name]=1`: Order by `name` or alias `name` is `DESC`.\n- `order[age]=0`: Order by `age` or alias `age` is `ASC`.\n\n### Filter string for Cursor based\n\n```\ncursor=10&limit=10&direction=next&filters[name]=abc&filters[age][value]=18&filters[age][operator]=gte&order[name]=1&order[age]=0\n```\n\n- `cursor=10`: This indicates the current position in the dataset. The cursor is typically a unique identifier or an offset that helps the server know where to continue fetching records from.\n- `limit=10`: This specifies the number of records to return in the response. In this case, the client is requesting 10 records.\n- `direction=next`: This indicates the direction in which to paginate. The value `next` suggests that the client wants to fetch the next set of records following the current cursor position.\n- `filters[name]=abc`: This applies a filter on the `name` field, where the value must be `abc`.\n- `filters[age][value]=18` and `filters[age][operator]=gte`: These two parameters work together to filter the `age` field. The `value` is set to `18`, and the `operator` is `gte`, which stands for \"greater than or equal to.\" Thus, this filter will include records where the age is 18 or older.\n- `order[name]=1` and `order[age]=0`: These parameters specify the sorting order of the results. The `order[name]=1` indicates that the results should be sorted by the `name` field in ascending order, while `order[age]=0` indicates that the results should be sorted by the `age` field in descending order.\n\n### Operator\n\n| Operator Group | Description                                                            |\n|----------------|------------------------------------------------------------------------|\n| `eq`, `=`      | Equal to                                                               |\n| `neq`, `!=`    | Not equal to                                                           |\n| `gt`, `>`      | Greater than                                                           |\n| `lt`, `<`      | Less than                                                              |\n| `gte`, `>=`    | Greater than or equal to                                               |\n| `lte`, `<=`    | Less than or equal to                                                  |\n| `in`           | In (within a specified set)                                            |\n| `nin`          | Not in (not within a specified set)                                    |\n| `like`         | Like (matches a pattern)                                               |\n| `ilike`        | Case-insensitive like (matches a pattern)                              |\n| `nlike`        | Not like (does not match a pattern)                                    |\n| `nilike`       | Case-insensitive not like (does not match a pattern)                   |\n| `is`           | Is (matches a specific value, often used for null checks)              |\n| `isnot`        | Is not (does not match a specific value, often used for null checks)   |\n| `bw`           | Between (within a specified range)                                     |\n| `nbw`          | Not between (not within a specified range)                             |\n\n### DEFAULT_LIMIT\n\n```typescript\nexport const DEFAULT_LIMIT = 10;\n```\n- **Description**: This constant sets the default limit for pagination to 10 records.\n\n### MAX_LIMIT\n\n```typescript\nexport const MAX_LIMIT = 1000;\n```\n- **Description**: This constant sets the maximum limit for pagination to 1000 records.\n\n## Functions\n\n### isBaseType\n\n```typescript\nexport function isBaseType(value: any): value is string | number | boolean {\n  return ['string', 'number', 'boolean'].includes(typeof value);\n}\n```\n- **Description**: Checks if the given value is a base type (string, number, or boolean).\n- **Parameters**:\n  - `value`: The value to check.\n- **Returns**: `true` if the value is a string, number, or boolean; otherwise `false`.\n\n### getFilters\n\n```typescript\nexport function getFilters(query: Record<string, any> | undefined) {\n  const filters: PaginationFilters = {};\n\n  if (typeof query?.filters === 'object') {\n    Object.keys(query.filters).forEach((key) => {\n      const value = query.filters[key];\n\n      if (typeof value === 'object') {\n        filters[key] = {\n          value: value.value,\n          operator: value.operator,\n        };\n      } else if (isBaseType(value)) {\n        filters[key] = {\n          value,\n          operator: 'eq',\n        };\n      }\n    });\n  }\n\n  return filters;\n}\n```\n- **Description**: Extracts filters from the query object.\n- **Parameters**:\n  - `query`: An object containing the query parameters.\n- **Returns**: An object representing the filters for pagination.\n\n### getOrder\n```typescript\nexport function getOrder(query: Record<string, any> | undefined) {\n  const order: PaginationOrder = {};\n\n  if (typeof query?.order === 'object') {\n    Object.keys(query.order).forEach((key) => {\n      order[key] = parseInt(query.order[key]) === 1 ? 1 : 0;\n    });\n  }\n\n  return order;\n}\n```\n- **Description**: Extracts the order for sorting from the query object.\n- **Parameters**:\n  - `query`: An object containing the query parameters.\n- **Returns**: An object representing the order for pagination.\n\n### getCursorDirection\n```typescript\nexport function getCursorDirection(query: Record<string, any> | undefined) {\n  const direction = query?.direction as string;\n  return direction?.toLowerCase() === 'prev' ? 'prev' : 'next';\n}\n```\n- **Description**: Determines the cursor direction for pagination from the query object.\n- **Parameters**:\n  - `query`: An object containing the query parameters.\n- **Returns**: A string indicating the cursor direction (`'prev'` or `'next'`).\n\n## Decorators\n\n### Offset\n- **Description**: This decorator is used to extract pagination parameters from the request query for offset-based pagination.\n- **Returns**: An object of type `PaginationOffsetDto` containing the following properties:\n  - `page`: The current page number, defaulting to 1 if not provided in the query.\n  - `limit`: The number of records per page, defaulting to `DEFAULT_LIMIT` if not provided in the query.\n  - `filters`: An object representing the filters for pagination, extracted from the query.\n  - `order`: An object representing the order for sorting, extracted from the query.\n\n#### Usage Example in a Controller\n```typescript\n// src/modules/item.repo.ts\nimport { Injectable } from '@nestjs/common';\nimport { Repository } from 'typeorm';\nimport { PaginationService, PaginationOffsetDto } from '@blogcode/nest-typeorm-pagination';\n\n@Injectable()\nexport class ItemService {\n  constructor(\n    private readonly itemRepo: Repository<ItemEntity>,\n    private readonly paginationService: PaginationService,\n  ) {\n    this.paginationService.setPrimaryKey('id'); // value `id` is default inside package.\n    // Set others value if need\n  }\n\n  getItemsOffset(query: PaginationOffsetDto) {\n    return this.paginationService.offset(this.itemRepo, query);\n  }\n\n  getItemsCursor(query: PaginationCursorDto) {\n    return this.paginationService.cursor(this.itemRepo, query);\n  }\n\n  getTotalItemCursor(query: PaginationCursorDto) {\n    return this.paginationService.getCursorTotal(this.itemRepo, query);\n  }\n}\n```\n\n```typescript\n// src/modules/item.controlller.ts\nimport { Controller, Get } from '@nestjs/common';\nimport { Offset, PaginationOffsetDto } from '@blogcode/nest-typeorm-pagination';\nimport { ItemRepo } from './item.repo';\n\n@Controller('items')\nexport class ItemsController {\n  constructor(private readonly itemRepo: ItemRepo) {}\n  @Get('get-paging-items-by-offset')\n  getItems(@Offset() query: PaginationOffsetDto) {\n    // Your logic to handle the pagination\n    return this.itemsService.getItemsOffset(query);\n  }\n}\n```\n\n### Cursor\n- **Description**: This decorator is used to extract pagination parameters from the request query for cursor-based pagination.\n- **Returns**: An object of type `PaginationOffsetDto` containing the following properties:\n  - `cursor`: The current cursor position, extracted from the query.\n  - `direction`: The direction of pagination (`'prev'` or `'next'`), determined from the query.\n  - `limit`: The number of records to return, defaulting to `DEFAULT_LIMIT` if not provided in the query.\n  - `filters`: An object representing the filters for pagination, extracted from the query.\n  - `order`: An object representing the order for sorting, extracted from the query.\n\n#### Usage Example in a Controller\n```typescript\n// src/modules/item.controlller.ts\nimport { Controller, Get } from '@nestjs/common';\nimport { Offset, PaginationCursorDto } from '@blogcode/nest-typeorm-pagination';\nimport { ItemRepo } from './item.repo';\n\n@Controller('items')\nexport class ItemsController {\n  constructor(private readonly itemRepo: ItemRepo) {}\n  @Get('get-paging-items-by-cursor')\n  getItems(@Cursor() query: PaginationCursorDto) {\n    // Your logic to handle the pagination\n    return this.itemsService.getItemsCursor(query);\n  }\n}\n```\n\n## Class: PaginationService\n\nPaginationService provides methods for performing data pagination in two ways: offset-based and cursor-based. It supports applying filters, sorting, and setting limits on the number of returned results.\n\n### setFilterMapping\n\n```typescript\nsetFilterMapping(mapping: Record<string, string>): this\n```\n\n- **Description**: Sets the mapping between DTO fields and database fields.\n- **Parameters**:\n  - `mapping`: Object mapping between DTO field names and database field names.\n- **Returns**: `this` - allows method chaining.\n\n### setDefaultLimit\n\n```typescript\nsetDefaultLimit(limit: number): this\n```\n\n- **Description**: Sets the default limit for the number of returned results.\n- **Parameters**:\n  - `limit`: Default number of results (must be greater than 0).\n- **Returns**: `this` - allows method chaining.\n\n### setMaxLimit\n\n```typescript\nsetMaxLimit(limit: number): this\n```\n\n- **Description**: Sets the maximum limit for the number of returned results.\n- **Parameters**:\n  - `limit`: Maximum number of results (must be greater than 0).\n- **Returns**: `this` - allows method chaining.\n\n### setEntityName\n\n```typescript\nsetEntityName(name: string): this\n```\n\n- **Description**: Sets the entity name for the queries.\n- **Parameters**:\n  - `name`: Name of the entity.\n- **Returns**: `this` - allows method chaining.\n\n### setResultName\n\n```typescript\nsetResultName(name: string): this\n```\n\n- **Description**: Sets the field name for the returned results.\n- **Parameters**:\n  - `name`: Name of the result field.\n- **Returns**: `this` - allows method chaining.\n\n### setPrimaryKey\n\n```typescript\nsetPrimaryKey(key: string): this\n```\n\n- **Description**: Sets the primary key of the entity.\n- **Parameters**:\n  - `key`: Name of the primary key.\n- **Returns**: `this` - allows method chaining.\n\n### offset\n\n```typescript\nasync offset<T extends ObjectLiteral, K extends string = string>(\n  repository: Repository<T>,\n  dto: PaginationOffsetDto,\n): Promise<PaginationOffsetResult<K, T>>\n```\n\n- **Description**: Performs offset-based pagination.\n- **Parameters**:\n  - `repository`: Repository of the entity.\n  - `dto`: DTO object containing pagination, filters, and sorting information.\n- **Returns**: `Promise<PaginationOffsetResult<K, T>>` - Result of offset-based pagination.\n\n### cursor\n\n```typescript\nasync cursor<T extends ObjectLiteral, K extends string = string>(\n  repository: Repository<T>,\n  dto: PaginationCursorDto,\n): Promise<PaginationCursorResult<K, T>>\n```\n\n- **Description**: Performs cursor-based pagination.\n- **Parameters**:\n  - `repository`: Repository of the entity.\n  - `dto`: DTO object containing pagination, filters, sorting information, and cursor.\n- **Returns**: `Promise<PaginationCursorResult<K, T>>` - Result of cursor-based pagination, including next and previous cursors.\n\n### getCursorTotal\n\n```typescript\nasync getCursorTotal<T extends ObjectLiteral>(\n  repository: Repository<T>,\n  dto: PaginationCursorDto,\n): Promise<number>\n```\n\n- **Description**: Retrieves the total number of items based on the filters for cursor-based pagination.\n- **Parameters**:\n  - `repository`: Repository of the entity.\n  - `dto`: DTO object containing filter information.\n- **Returns**: `Promise<number>` - Total number of items based on the filters.\n\n## Search OR\n\nSet mapping fields\n\n```ts\n@Injectable()\nexport class UserService {\n  constructor(private readonly paginationService: PaginationService) {\n    this.paginationService.setFilterMapping({\n      name: 'username, email, firstname, lastname'\n    });\n  }\n}\n```\n\nQuery string:\n\n```txt\nfilters[name]=text\n```\n\n**Result:**\n\n```sql\nWHERE (username = \"text\" OR email = \"text\" OR firstname = \"text\" OR lastname = \"text\")\n```\n\nQuery string:\n\n```txt\nfilters[name][value]=text&filter[name][operator]=like\n```\n\n**Result:**\n\n```sql\nWHERE (username LIKE \"%text%\" OR email LIKE \"%text%\" OR firstname LIKE \"%text%\" OR lastname = \"%text%\")\n```\n\n## Full Text Search\n\n### PostgreSQL\n\nSet mapping fields\n\n```ts\n@Injectable()\nexport class UserService {\n  constructor(private readonly paginationService: PaginationService) {\n    this.paginationService.setFilterMapping({\n      name: \"to_tsquery('english', ':name')\"\n    });\n  }\n}\n```\n\nProperty `name` and `:name` must be same word.\n\nQuery string\n\n```txt\nfilters[name][value]=search%20keyword&filters[name][operator]=fts\n```\n\n**Result:**\n\n```sql\nWHERE name @@ to_tsquery('english', 'search 20keyword')\n```\n\n### MySQL\n\nSet mapping fields\n\n```ts\n@Injectable()\nexport class UserService {\n  constructor(private readonly paginationService: PaginationService) {\n    this.paginationService.setFilterMapping({\n      name: 'username, email, firstname, lastname'\n    });\n  }\n}\n```\n\nQuery string\n\n```txt\nfilters[name][value]=search%20keyword&filters[name][operator]=fts\n```\n\n**Result:**\n\n```sql\nWHERE MATCH (username, email, firstname, lastname) AGAINST ('search keyword' IN BOOLEAN MODE)\n```\n","readmeFilename":"README.md"}