@x-spacy/pagination 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/index.d.ts +18 -0
- package/LICENSE +9 -0
- package/README.md +214 -0
- package/dist/enums/PaginationLinkType.js +11 -0
- package/dist/index.js +22 -0
- package/dist/interceptors/PaginationInterceptor.js +52 -0
- package/dist/operators/paginate.js +7 -0
- package/dist/schemas/Page.js +12 -0
- package/dist/schemas/PaginatedResponse.js +67 -0
- package/dist/schemas/PaginationLink.js +43 -0
- package/dist/schemas/PaginationMeta.js +54 -0
- package/package.json +43 -0
- package/tsconfig.json +33 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare module '@x-spacy/pagination' {
|
|
2
|
+
import { Page } from '@x-spacy/pagination/schemas/Page';
|
|
3
|
+
import { PaginatedResponse } from '@x-spacy/pagination/schemas/Paginate';
|
|
4
|
+
|
|
5
|
+
export enum PaginationLinkType {
|
|
6
|
+
FIRST = 'FIRST',
|
|
7
|
+
LAST = 'LAST',
|
|
8
|
+
PREV = 'PREV',
|
|
9
|
+
NEXT = 'NEXT',
|
|
10
|
+
PAGE = 'PAGE'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export declare class PaginateInterceptor<T> implements NestInterceptor {
|
|
14
|
+
intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<PaginatedResponse<T>>>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function paginate<T>(items: Array<T>, total: number): Page<T>;
|
|
18
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
(The MIT License)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 X Spacy <https://xspacy.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Pagination
|
|
2
|
+
|
|
3
|
+
A pagination library for NestJS with metadata and navigation links support.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Using npm
|
|
9
|
+
npm install @x-spacy/pagination
|
|
10
|
+
|
|
11
|
+
# Using yarn
|
|
12
|
+
yarn add @x-spacy/pagination
|
|
13
|
+
|
|
14
|
+
# Using pnpm
|
|
15
|
+
pnpm add @x-spacy/pagination
|
|
16
|
+
|
|
17
|
+
# Using bun
|
|
18
|
+
bun add @x-spacy/pagination
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Configuration
|
|
22
|
+
|
|
23
|
+
### Required: `reflect-metadata`
|
|
24
|
+
|
|
25
|
+
This library uses `class-transformer` for object serialization, which relies on **decorators** and **metadata reflection**. For the transformers to work correctly, it is **mandatory** to have `reflect-metadata` configured in your project.
|
|
26
|
+
|
|
27
|
+
#### 1. Install `reflect-metadata`
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Using npm
|
|
31
|
+
npm install reflect-metadata
|
|
32
|
+
|
|
33
|
+
# Using yarn
|
|
34
|
+
yarn add reflect-metadata
|
|
35
|
+
|
|
36
|
+
# Using pnpm
|
|
37
|
+
pnpm add reflect-metadata
|
|
38
|
+
|
|
39
|
+
# Using bun
|
|
40
|
+
bun add reflect-metadata
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### 2. Import in Entry Point
|
|
44
|
+
|
|
45
|
+
Add the `reflect-metadata` import in your application's entry file (`main.ts`) **before any other imports**:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import 'reflect-metadata';
|
|
49
|
+
|
|
50
|
+
import { NestFactory } from '@nestjs/core';
|
|
51
|
+
import { AppModule } from './app.module';
|
|
52
|
+
|
|
53
|
+
async function bootstrap() {
|
|
54
|
+
const app = await NestFactory.create(AppModule);
|
|
55
|
+
await app.listen(3000);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
bootstrap();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### 3. Configure `tsconfig.json`
|
|
62
|
+
|
|
63
|
+
Make sure the following options are enabled in your `tsconfig.json`:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"compilerOptions": {
|
|
68
|
+
"experimentalDecorators": true,
|
|
69
|
+
"emitDecoratorMetadata": true
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
### Basic Example
|
|
77
|
+
|
|
78
|
+
To use pagination, you need **two mandatory elements**:
|
|
79
|
+
|
|
80
|
+
1. **`PaginateInterceptor`**: Interceptor that processes the response and generates pagination metadata
|
|
81
|
+
2. **`paginate()`**: Function that wraps the data to be processed by the interceptor
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { Controller, Get, HttpCode, HttpStatus, Query, UseInterceptors } from '@nestjs/common';
|
|
85
|
+
|
|
86
|
+
import { PaginateInterceptor, paginate } from '@x-spacy/pagination';
|
|
87
|
+
|
|
88
|
+
import { ListServicesService } from './list-services.service';
|
|
89
|
+
import { ListServicesHttpControllerQueryValidator } from './validators/list-services-http-controller-query.validator';
|
|
90
|
+
import { ServiceHttpControllerSerializer } from './serializers/service-http-controller.serializer';
|
|
91
|
+
|
|
92
|
+
@Controller('services')
|
|
93
|
+
export class ListServicesHttpController {
|
|
94
|
+
@Inject('ListServicesService')
|
|
95
|
+
private readonly listServicesService: ListServicesService
|
|
96
|
+
|
|
97
|
+
@Get()
|
|
98
|
+
@HttpCode(HttpStatus.OK)
|
|
99
|
+
@UseInterceptors(PaginateInterceptor)
|
|
100
|
+
public async list(@Query() { page, perPage }: ListServicesHttpControllerQueryValidator) {
|
|
101
|
+
const { services, total } = await this.listServicesService.execute(page, perPage);
|
|
102
|
+
|
|
103
|
+
return paginate(services.map(service => ServiceHttpControllerSerializer.serialize(service)), total);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Query Parameters
|
|
109
|
+
|
|
110
|
+
The interceptor expects the following query parameters:
|
|
111
|
+
|
|
112
|
+
| Parameter | Type | Default | Description |
|
|
113
|
+
|-----------|--------|---------|------------------------------------------|
|
|
114
|
+
| `page` | number | 1 | Current page number |
|
|
115
|
+
| `perPage` | number | 10 | Number of items per page (max: 100) |
|
|
116
|
+
|
|
117
|
+
## Response Structure
|
|
118
|
+
|
|
119
|
+
The paginated response follows this format:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"items": [...],
|
|
124
|
+
"meta": {
|
|
125
|
+
"from": 1,
|
|
126
|
+
"to": 10,
|
|
127
|
+
"current_page": 1,
|
|
128
|
+
"last_page": 5,
|
|
129
|
+
"per_page": 10,
|
|
130
|
+
"total": 50
|
|
131
|
+
},
|
|
132
|
+
"path": "https://api.example.com/services",
|
|
133
|
+
"first_page_url": "https://api.example.com/services?page=1&perPage=10",
|
|
134
|
+
"prev_page_url": null,
|
|
135
|
+
"next_page_url": "https://api.example.com/services?page=2&perPage=10",
|
|
136
|
+
"last_page_url": "https://api.example.com/services?page=5&perPage=10",
|
|
137
|
+
"links": [
|
|
138
|
+
{
|
|
139
|
+
"url": null,
|
|
140
|
+
"label": "« Previous",
|
|
141
|
+
"type": "PREV",
|
|
142
|
+
"active": false
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"url": "https://api.example.com/services?page=1&perPage=10",
|
|
146
|
+
"label": "1",
|
|
147
|
+
"type": "PAGE",
|
|
148
|
+
"active": true
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"url": "https://api.example.com/services?page=2&perPage=10",
|
|
152
|
+
"label": "2",
|
|
153
|
+
"type": "PAGE",
|
|
154
|
+
"active": false
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"url": "https://api.example.com/services?page=2&perPage=10",
|
|
158
|
+
"label": "Next »",
|
|
159
|
+
"type": "NEXT",
|
|
160
|
+
"active": false
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## API Reference
|
|
167
|
+
|
|
168
|
+
### `paginate<T>(items: Array<T>, total: number): Page<T>`
|
|
169
|
+
|
|
170
|
+
Wraps the items and total to be processed by `PaginateInterceptor`.
|
|
171
|
+
|
|
172
|
+
**Parameters:**
|
|
173
|
+
|
|
174
|
+
- `items`: Array of items for the current page
|
|
175
|
+
- `total`: Total number of items (used to calculate pagination)
|
|
176
|
+
|
|
177
|
+
**Returns:**
|
|
178
|
+
|
|
179
|
+
- `Page<T>`: Object that will be intercepted and transformed into `PaginatedResponse<T>`
|
|
180
|
+
|
|
181
|
+
### `PaginateInterceptor`
|
|
182
|
+
|
|
183
|
+
NestJS interceptor that transforms a `Page<T>` into a complete paginated response with metadata and navigation links.
|
|
184
|
+
|
|
185
|
+
### Exported Types
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
// Enums
|
|
189
|
+
export { PaginationLinkType } from '@x-spacy/pagination';
|
|
190
|
+
|
|
191
|
+
// Interceptors
|
|
192
|
+
export { PaginateInterceptor } from '@x-spacy/pagination';
|
|
193
|
+
|
|
194
|
+
// Operators
|
|
195
|
+
export { paginate } from '@x-spacy/pagination';
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### `PaginationLinkType`
|
|
199
|
+
|
|
200
|
+
Enum that defines the types of navigation links:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
enum PaginationLinkType {
|
|
204
|
+
FIRST = 'FIRST',
|
|
205
|
+
LAST = 'LAST',
|
|
206
|
+
PREV = 'PREV',
|
|
207
|
+
NEXT = 'NEXT',
|
|
208
|
+
PAGE = 'PAGE'
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
[MIT licensed](LICENSE).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PaginationLinkType = void 0;
|
|
4
|
+
var PaginationLinkType;
|
|
5
|
+
(function (PaginationLinkType) {
|
|
6
|
+
PaginationLinkType["FIRST"] = "FIRST";
|
|
7
|
+
PaginationLinkType["LAST"] = "LAST";
|
|
8
|
+
PaginationLinkType["PREV"] = "PREV";
|
|
9
|
+
PaginationLinkType["NEXT"] = "NEXT";
|
|
10
|
+
PaginationLinkType["PAGE"] = "PAGE";
|
|
11
|
+
})(PaginationLinkType || (exports.PaginationLinkType = PaginationLinkType = {}));
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./interceptors/PaginationInterceptor"), exports);
|
|
18
|
+
__exportStar(require("./operators/paginate"), exports);
|
|
19
|
+
__exportStar(require("./schemas/Page"), exports);
|
|
20
|
+
__exportStar(require("./schemas/PaginatedResponse"), exports);
|
|
21
|
+
__exportStar(require("./schemas/PaginationLink"), exports);
|
|
22
|
+
__exportStar(require("./schemas/PaginationMeta"), exports);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.PaginateInterceptor = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const operators_1 = require("rxjs/operators");
|
|
12
|
+
const Page_1 = require("../schemas/Page");
|
|
13
|
+
const PaginatedResponse_1 = require("../schemas/PaginatedResponse");
|
|
14
|
+
const PaginationLink_1 = require("../schemas/PaginationLink");
|
|
15
|
+
const PaginationMeta_1 = require("../schemas/PaginationMeta");
|
|
16
|
+
const PaginationLinkType_1 = require("../enums/PaginationLinkType");
|
|
17
|
+
let PaginateInterceptor = class PaginateInterceptor {
|
|
18
|
+
intercept(context, next) {
|
|
19
|
+
const request = context.switchToHttp().getRequest();
|
|
20
|
+
const page = Math.max(1, parseInt(request.query.page, 10) ?? 1);
|
|
21
|
+
const perPage = Math.min(100, Math.max(1, parseInt(request.query.perPage, 10) ?? 10));
|
|
22
|
+
const path = `${request.protocol}://${request.get('host') + request.path}`;
|
|
23
|
+
return next.handle().pipe((0, operators_1.map)((data) => {
|
|
24
|
+
if (!(data instanceof Page_1.Page)) {
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
const { total, items } = data;
|
|
28
|
+
const lastPage = Math.max(1, Math.ceil(total / perPage));
|
|
29
|
+
const currentPage = Math.min(page, lastPage);
|
|
30
|
+
const startIndex = (currentPage - 1) * perPage;
|
|
31
|
+
const endIndex = Math.min(startIndex + perPage, total);
|
|
32
|
+
const from = total > 0 ? startIndex + 1 : 0;
|
|
33
|
+
const to = endIndex;
|
|
34
|
+
const buildUrl = (pageNumber) => `${path}?page=${pageNumber}&perPage=${perPage}`;
|
|
35
|
+
const links = this.buildLinks(currentPage, lastPage, buildUrl);
|
|
36
|
+
return new PaginatedResponse_1.PaginatedResponse(items, new PaginationMeta_1.PaginationMeta(from, to, currentPage, lastPage, perPage, total), path, buildUrl(1), currentPage > 1 ? buildUrl(currentPage - 1) : null, currentPage < lastPage ? buildUrl(currentPage + 1) : null, buildUrl(lastPage), links);
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
buildLinks(currentPage, lastPage, buildUrl) {
|
|
40
|
+
const links = new Array();
|
|
41
|
+
links.push(new PaginationLink_1.PaginationLink(currentPage > 1 ? buildUrl(currentPage - 1) : null, '« Anterior', PaginationLinkType_1.PaginationLinkType.PREV, false));
|
|
42
|
+
for (let i = 1; i <= lastPage; i++) {
|
|
43
|
+
links.push(new PaginationLink_1.PaginationLink(buildUrl(i), String(i), PaginationLinkType_1.PaginationLinkType.PAGE, i === currentPage));
|
|
44
|
+
}
|
|
45
|
+
links.push(new PaginationLink_1.PaginationLink(currentPage < lastPage ? buildUrl(currentPage + 1) : null, 'Próximo »', PaginationLinkType_1.PaginationLinkType.NEXT, false));
|
|
46
|
+
return links;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.PaginateInterceptor = PaginateInterceptor;
|
|
50
|
+
exports.PaginateInterceptor = PaginateInterceptor = __decorate([
|
|
51
|
+
(0, common_1.Injectable)()
|
|
52
|
+
], PaginateInterceptor);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PaginatedResponse = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const PaginationMeta_1 = require("./PaginationMeta");
|
|
15
|
+
class PaginatedResponse {
|
|
16
|
+
items;
|
|
17
|
+
meta;
|
|
18
|
+
path;
|
|
19
|
+
firstPageUrl;
|
|
20
|
+
prevPageUrl;
|
|
21
|
+
nextPageUrl;
|
|
22
|
+
lastPageUrl;
|
|
23
|
+
links;
|
|
24
|
+
constructor(items, meta, path, firstPageUrl, prevPageUrl, nextPageUrl, lastPageUrl, links) {
|
|
25
|
+
this.items = items;
|
|
26
|
+
this.meta = meta;
|
|
27
|
+
this.path = path;
|
|
28
|
+
this.firstPageUrl = firstPageUrl;
|
|
29
|
+
this.prevPageUrl = prevPageUrl;
|
|
30
|
+
this.nextPageUrl = nextPageUrl;
|
|
31
|
+
this.lastPageUrl = lastPageUrl;
|
|
32
|
+
this.links = links;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.PaginatedResponse = PaginatedResponse;
|
|
36
|
+
__decorate([
|
|
37
|
+
(0, class_transformer_1.Expose)({ name: 'items' }),
|
|
38
|
+
__metadata("design:type", Array)
|
|
39
|
+
], PaginatedResponse.prototype, "items", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, class_transformer_1.Expose)({ name: 'meta' }),
|
|
42
|
+
__metadata("design:type", PaginationMeta_1.PaginationMeta)
|
|
43
|
+
], PaginatedResponse.prototype, "meta", void 0);
|
|
44
|
+
__decorate([
|
|
45
|
+
(0, class_transformer_1.Expose)({ name: 'path' }),
|
|
46
|
+
__metadata("design:type", String)
|
|
47
|
+
], PaginatedResponse.prototype, "path", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
(0, class_transformer_1.Expose)({ name: 'first_page_url' }),
|
|
50
|
+
__metadata("design:type", String)
|
|
51
|
+
], PaginatedResponse.prototype, "firstPageUrl", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
(0, class_transformer_1.Expose)({ name: 'prev_page_url' }),
|
|
54
|
+
__metadata("design:type", Object)
|
|
55
|
+
], PaginatedResponse.prototype, "prevPageUrl", void 0);
|
|
56
|
+
__decorate([
|
|
57
|
+
(0, class_transformer_1.Expose)({ name: 'next_page_url' }),
|
|
58
|
+
__metadata("design:type", Object)
|
|
59
|
+
], PaginatedResponse.prototype, "nextPageUrl", void 0);
|
|
60
|
+
__decorate([
|
|
61
|
+
(0, class_transformer_1.Expose)({ name: 'last_page_url' }),
|
|
62
|
+
__metadata("design:type", String)
|
|
63
|
+
], PaginatedResponse.prototype, "lastPageUrl", void 0);
|
|
64
|
+
__decorate([
|
|
65
|
+
(0, class_transformer_1.Expose)({ name: 'links' }),
|
|
66
|
+
__metadata("design:type", Array)
|
|
67
|
+
], PaginatedResponse.prototype, "links", void 0);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PaginationLink = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const PaginationLinkType_1 = require("../enums/PaginationLinkType");
|
|
15
|
+
class PaginationLink {
|
|
16
|
+
url;
|
|
17
|
+
label;
|
|
18
|
+
type;
|
|
19
|
+
active;
|
|
20
|
+
constructor(url, label, type, active) {
|
|
21
|
+
this.url = url;
|
|
22
|
+
this.label = label;
|
|
23
|
+
this.type = type;
|
|
24
|
+
this.active = active;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.PaginationLink = PaginationLink;
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, class_transformer_1.Expose)({ name: 'url' }),
|
|
30
|
+
__metadata("design:type", Object)
|
|
31
|
+
], PaginationLink.prototype, "url", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, class_transformer_1.Expose)({ name: 'label' }),
|
|
34
|
+
__metadata("design:type", String)
|
|
35
|
+
], PaginationLink.prototype, "label", void 0);
|
|
36
|
+
__decorate([
|
|
37
|
+
(0, class_transformer_1.Expose)({ name: 'type' }),
|
|
38
|
+
__metadata("design:type", String)
|
|
39
|
+
], PaginationLink.prototype, "type", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, class_transformer_1.Expose)({ name: 'active' }),
|
|
42
|
+
__metadata("design:type", Boolean)
|
|
43
|
+
], PaginationLink.prototype, "active", void 0);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PaginationMeta = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
class PaginationMeta {
|
|
15
|
+
from;
|
|
16
|
+
to;
|
|
17
|
+
currentPage;
|
|
18
|
+
lastPage;
|
|
19
|
+
perPage;
|
|
20
|
+
total;
|
|
21
|
+
constructor(from, to, currentPage, lastPage, perPage, total) {
|
|
22
|
+
this.from = from;
|
|
23
|
+
this.to = to;
|
|
24
|
+
this.currentPage = currentPage;
|
|
25
|
+
this.lastPage = lastPage;
|
|
26
|
+
this.perPage = perPage;
|
|
27
|
+
this.total = total;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.PaginationMeta = PaginationMeta;
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, class_transformer_1.Expose)({ name: 'from' }),
|
|
33
|
+
__metadata("design:type", Number)
|
|
34
|
+
], PaginationMeta.prototype, "from", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, class_transformer_1.Expose)({ name: 'to' }),
|
|
37
|
+
__metadata("design:type", Number)
|
|
38
|
+
], PaginationMeta.prototype, "to", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, class_transformer_1.Expose)({ name: 'current_page' }),
|
|
41
|
+
__metadata("design:type", Number)
|
|
42
|
+
], PaginationMeta.prototype, "currentPage", void 0);
|
|
43
|
+
__decorate([
|
|
44
|
+
(0, class_transformer_1.Expose)({ name: 'last_page' }),
|
|
45
|
+
__metadata("design:type", Number)
|
|
46
|
+
], PaginationMeta.prototype, "lastPage", void 0);
|
|
47
|
+
__decorate([
|
|
48
|
+
(0, class_transformer_1.Expose)({ name: 'per_page' }),
|
|
49
|
+
__metadata("design:type", Number)
|
|
50
|
+
], PaginationMeta.prototype, "perPage", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
(0, class_transformer_1.Expose)({ name: 'total' }),
|
|
53
|
+
__metadata("design:type", Number)
|
|
54
|
+
], PaginationMeta.prototype, "total", void 0);
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@x-spacy/pagination",
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"description": "A pagination library for NestJS",
|
|
5
|
+
"license": "X SPACY LICENSE AGREEMENT",
|
|
6
|
+
"private": false,
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "@types/index.d.ts",
|
|
9
|
+
"author": {
|
|
10
|
+
"name": "Vinícius Gutierrez da Silva Rocha",
|
|
11
|
+
"email": "srgutyerrez@gmail.com",
|
|
12
|
+
"url": "https://github.com/gutyerrez"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/x-spacy/pagination.git"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"registry": "https://registry.npmjs.org",
|
|
20
|
+
"access": "public",
|
|
21
|
+
"tag": "latest"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"bun": ">=1.3.9"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "nest build"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@nestjs/common": "^11.1.13",
|
|
31
|
+
"@nestjs/core": "^11.1.13",
|
|
32
|
+
"@x-spacy/eslint-config": "^1.35.0",
|
|
33
|
+
"class-transformer": "^0.5.1",
|
|
34
|
+
"express": "^5.2.1",
|
|
35
|
+
"reflect-metadata": "^0.2.2",
|
|
36
|
+
"rxjs": "^7.8.2"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@nestjs/cli": "^11.0.16",
|
|
40
|
+
"@types/express": "^5.0.6",
|
|
41
|
+
"typescript": "^5.9.3"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2024",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"outDir": "dist",
|
|
6
|
+
"paths": {
|
|
7
|
+
"@x-spacy/pagination/*": [
|
|
8
|
+
"./src/*"
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
"strict": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"removeComments": true,
|
|
14
|
+
"esModuleInterop": true,
|
|
15
|
+
"strictNullChecks": true,
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"strictBindCallApply": false,
|
|
18
|
+
"emitDecoratorMetadata": true,
|
|
19
|
+
"experimentalDecorators": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"allowSyntheticDefaultImports": true,
|
|
22
|
+
"strictPropertyInitialization": false,
|
|
23
|
+
"forceConsistentCasingInFileNames": true
|
|
24
|
+
},
|
|
25
|
+
"include": [
|
|
26
|
+
"@types/**/*",
|
|
27
|
+
"src/**/*"
|
|
28
|
+
],
|
|
29
|
+
"exclude": [
|
|
30
|
+
"node_modules",
|
|
31
|
+
"dist"
|
|
32
|
+
]
|
|
33
|
+
}
|