@furkanogutcu/nest-common 0.0.3 → 1.0.1
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/README.md +180 -12
- package/dist/decorators/index.d.ts +3 -0
- package/dist/decorators/index.js +20 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/order-by.decorator.d.ts +3 -0
- package/dist/decorators/order-by.decorator.js +12 -0
- package/dist/decorators/order-by.decorator.js.map +1 -0
- package/dist/decorators/pagination.decorator.d.ts +1 -0
- package/dist/decorators/pagination.decorator.js +10 -0
- package/dist/decorators/pagination.decorator.js.map +1 -0
- package/dist/decorators/search.decorator.d.ts +3 -0
- package/dist/decorators/search.decorator.js +17 -0
- package/dist/decorators/search.decorator.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/pipes/app-zod-validation.pipe.d.ts +5 -0
- package/dist/pipes/app-zod-validation.pipe.js +28 -0
- package/dist/pipes/app-zod-validation.pipe.js.map +1 -0
- package/dist/pipes/index.d.ts +1 -0
- package/dist/pipes/index.js +18 -0
- package/dist/pipes/index.js.map +1 -0
- package/dist/responses/api-response.type.d.ts +17 -0
- package/dist/responses/api-response.type.js +3 -0
- package/dist/responses/api-response.type.js.map +1 -0
- package/dist/responses/index.d.ts +1 -0
- package/dist/responses/index.js +18 -0
- package/dist/responses/index.js.map +1 -0
- package/dist/utils/exponential-retry.util.d.ts +5 -0
- package/dist/utils/exponential-retry.util.js +23 -0
- package/dist/utils/exponential-retry.util.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +19 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/sleep.util.d.ts +1 -0
- package/dist/utils/sleep.util.js +8 -0
- package/dist/utils/sleep.util.js.map +1 -0
- package/dist/validations/index.d.ts +3 -0
- package/dist/validations/index.js +20 -0
- package/dist/validations/index.js.map +1 -0
- package/dist/validations/order-by.validation.d.ts +14 -0
- package/dist/validations/order-by.validation.js +18 -0
- package/dist/validations/order-by.validation.js.map +1 -0
- package/dist/validations/pagination.validation.d.ts +18 -0
- package/dist/validations/pagination.validation.js +16 -0
- package/dist/validations/pagination.validation.js.map +1 -0
- package/dist/validations/search.validation.d.ts +8 -0
- package/dist/validations/search.validation.js +8 -0
- package/dist/validations/search.validation.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
@@ -12,6 +12,10 @@ This package is designed to standardize structures you repeatedly use in your Ne
|
|
12
12
|
- [Installation](#installation)
|
13
13
|
- [Features](#features)
|
14
14
|
- [Exceptions](#1-exceptions)
|
15
|
+
- [API Responses](#2-api-responses)
|
16
|
+
- [Validators and Pipes](#3-validators-and-pipes)
|
17
|
+
- [Decorators](#4-decorators)
|
18
|
+
- [Utilities](#5-utilities)
|
15
19
|
- [Development](#development)
|
16
20
|
- [License](#license)
|
17
21
|
|
@@ -39,25 +43,27 @@ No additional installation steps are needed beyond installing the package.
|
|
39
43
|
|
40
44
|
- **Custom Exception Classes**: Comprehensive set of HTTP-based exception classes for consistent error responses.
|
41
45
|
|
42
|
-
| Exception Class
|
43
|
-
|
44
|
-
| `AppException`
|
45
|
-
| `AppBadRequestException`
|
46
|
-
| `AppUnauthorizedException`
|
47
|
-
| `AppForbiddenException`
|
48
|
-
| `AppNotFoundException`
|
49
|
-
| `AppConflictException`
|
50
|
-
| `AppUnprocessableEntityException` | 422
|
51
|
-
| `AppInternalException`
|
52
|
-
| `AppTooManyRequestException`
|
53
|
-
| `AppValidationException`
|
46
|
+
| Exception Class | HTTP Status | Description |
|
47
|
+
| --------------------------------- | ----------- | -------------------------------------------------- |
|
48
|
+
| `AppException` | - | Base exception class for all custom exceptions |
|
49
|
+
| `AppBadRequestException` | 400 | For invalid input, malformed requests |
|
50
|
+
| `AppUnauthorizedException` | 401 | For authentication failures |
|
51
|
+
| `AppForbiddenException` | 403 | For authorization failures |
|
52
|
+
| `AppNotFoundException` | 404 | For resources that couldn't be found |
|
53
|
+
| `AppConflictException` | 409 | For conflicting requests (e.g., duplicate entries) |
|
54
|
+
| `AppUnprocessableEntityException` | 422 | For semantically incorrect requests |
|
55
|
+
| `AppInternalException` | 500 | For server-side errors |
|
56
|
+
| `AppTooManyRequestException` | 429 | For rate limiting scenarios |
|
57
|
+
| `AppValidationException` | 400 | Specifically for input validation errors |
|
54
58
|
|
55
59
|
- **Global Exception Filter**: Automatically catches and transforms exceptions throughout your application.
|
60
|
+
|
56
61
|
- Centralized error handling logic
|
57
62
|
- Consistent error response format
|
58
63
|
- Easy to configure through NestJS's dependency injection
|
59
64
|
|
60
65
|
- **Exception Transformers**: Converts various error types to standardized app exceptions.
|
66
|
+
|
61
67
|
- NestJS built-in exception transformer
|
62
68
|
- TypeORM exception transformer
|
63
69
|
|
@@ -155,6 +161,168 @@ The `type` field in validation error details can have the following values:
|
|
155
161
|
|
156
162
|
For more detailed information about the filters, transformers, and interfaces included in the exceptions package, please check the source code.
|
157
163
|
|
164
|
+
### 2. API Responses
|
165
|
+
|
166
|
+
#### Features
|
167
|
+
|
168
|
+
- **Standardized Response Types**: Comprehensive set of response interfaces for consistent API responses.
|
169
|
+
- `APIResponse`: Generic type for creating standardized responses
|
170
|
+
- `APIResponseOnlyMessage`: Simple message-only response
|
171
|
+
- `PaginatedAPIResponse`: Response format for paginated data with metadata
|
172
|
+
|
173
|
+
#### Usage
|
174
|
+
|
175
|
+
```typescript
|
176
|
+
import { Controller, Get, Post, Body, Param, Query } from '@nestjs/common';
|
177
|
+
import {
|
178
|
+
APIResponse,
|
179
|
+
APIResponseOnlyMessage,
|
180
|
+
PaginatedAPIResponse,
|
181
|
+
Pagination,
|
182
|
+
PaginationParams,
|
183
|
+
} from '@furkanogutcu/nest-common';
|
184
|
+
import { User } from './user.entity';
|
185
|
+
import { CreateUserDto } from './dto/create-user.dto';
|
186
|
+
|
187
|
+
@Controller('users')
|
188
|
+
export class UsersController {
|
189
|
+
constructor(private readonly usersService: UsersService) {}
|
190
|
+
|
191
|
+
@Get()
|
192
|
+
async findAll(@Pagination() { skip, take }: PaginationParams): Promise<PaginatedAPIResponse<User>> {
|
193
|
+
const { items, metadata } = await this.usersService.findAll({ skip, take });
|
194
|
+
|
195
|
+
return {
|
196
|
+
data: items,
|
197
|
+
metadata,
|
198
|
+
};
|
199
|
+
}
|
200
|
+
|
201
|
+
@Get(':id')
|
202
|
+
async findOne(@Param('id') id: string): Promise<APIResponse<'user', User>> {
|
203
|
+
const user = await this.usersService.findOne(id);
|
204
|
+
|
205
|
+
return {
|
206
|
+
user,
|
207
|
+
};
|
208
|
+
}
|
209
|
+
|
210
|
+
@Post()
|
211
|
+
async create(@Body() createUserDto: CreateUserDto): Promise<APIResponseOnlyMessage> {
|
212
|
+
await this.usersService.create(createUserDto);
|
213
|
+
|
214
|
+
return {
|
215
|
+
message: 'User created successfully',
|
216
|
+
};
|
217
|
+
}
|
218
|
+
}
|
219
|
+
```
|
220
|
+
|
221
|
+
### 3. Validators and Pipes
|
222
|
+
|
223
|
+
#### Features
|
224
|
+
|
225
|
+
- **Zod Validation Pipe**: Extended validation pipe for NestJS using Zod schema validation.
|
226
|
+
|
227
|
+
- Seamless integration with NestJS validation pipeline
|
228
|
+
- Throws consistent `AppValidationException` on validation errors
|
229
|
+
- Compatible with Zod schemas
|
230
|
+
|
231
|
+
- **Common Validation Schemas**:
|
232
|
+
- `paginationSchema`: For standardizing pagination parameters
|
233
|
+
- `orderBySchema`: For standardizing sorting/ordering parameters
|
234
|
+
- `searchSchema`: For standardizing search parameters
|
235
|
+
|
236
|
+
#### Usage
|
237
|
+
|
238
|
+
##### Setting up validation globally
|
239
|
+
|
240
|
+
```typescript
|
241
|
+
import { Module } from '@nestjs/common';
|
242
|
+
import { APP_PIPE } from '@nestjs/core';
|
243
|
+
import { AppZodValidationPipe } from '@furkanogutcu/nest-common';
|
244
|
+
|
245
|
+
@Module({
|
246
|
+
imports: [
|
247
|
+
// Your other modules
|
248
|
+
],
|
249
|
+
controllers: [
|
250
|
+
// Your controllers
|
251
|
+
],
|
252
|
+
providers: [
|
253
|
+
// Your other providers
|
254
|
+
{
|
255
|
+
provide: APP_PIPE,
|
256
|
+
useClass: AppZodValidationPipe,
|
257
|
+
},
|
258
|
+
],
|
259
|
+
})
|
260
|
+
export class AppModule {}
|
261
|
+
```
|
262
|
+
|
263
|
+
### 4. Decorators
|
264
|
+
|
265
|
+
#### Features
|
266
|
+
|
267
|
+
- **Parameter Decorators**: Decorators for common query parameter extraction and validation.
|
268
|
+
- `@Pagination()`: Extracts and validates pagination parameters
|
269
|
+
- `@OrderBy()`: Extracts and validates ordering parameters
|
270
|
+
- `@Search()`: Extracts and validates search parameters
|
271
|
+
|
272
|
+
#### Usage
|
273
|
+
|
274
|
+
```typescript
|
275
|
+
import { Controller, Get } from '@nestjs/common';
|
276
|
+
import { Pagination, OrderBy, Search, PaginationParams, OrderByParam, SearchParams } from '@furkanogutcu/nest-common';
|
277
|
+
|
278
|
+
@Controller('users')
|
279
|
+
export class UsersController {
|
280
|
+
@Get()
|
281
|
+
findAll(
|
282
|
+
@Pagination() { skip, take }: PaginationParams,
|
283
|
+
@OrderBy<User>(['created_at']) orderBy: OrderByParam<User>,
|
284
|
+
@Search<User>(['email']) search: SearchParams<User>,
|
285
|
+
) {
|
286
|
+
// Implement your service call with these validated parameters
|
287
|
+
return this.usersService.findAll({ skip, take, orderBy, where: search });
|
288
|
+
}
|
289
|
+
}
|
290
|
+
```
|
291
|
+
|
292
|
+
### 5. Utilities
|
293
|
+
|
294
|
+
#### Features
|
295
|
+
|
296
|
+
- **Asynchronous Utilities**:
|
297
|
+
- `exponentialRetry`: Retry a function with exponential backoff
|
298
|
+
- `sleep`: Simple promise-based delay utility
|
299
|
+
|
300
|
+
#### Usage
|
301
|
+
|
302
|
+
```typescript
|
303
|
+
import { exponentialRetry, sleep } from '@furkanogutcu/nest-common';
|
304
|
+
|
305
|
+
// Retry a function with exponential backoff
|
306
|
+
async function fetchWithRetry() {
|
307
|
+
return exponentialRetry(
|
308
|
+
async () => {
|
309
|
+
// Potentially failing operation (e.g., API call)
|
310
|
+
return await externalApiCall();
|
311
|
+
},
|
312
|
+
{
|
313
|
+
maxAttempts: 5, // Maximum of 5 attempts
|
314
|
+
baseDelayMs: 1000, // Starting delay of 1000ms (will grow exponentially)
|
315
|
+
},
|
316
|
+
);
|
317
|
+
}
|
318
|
+
|
319
|
+
// Simple delay utility
|
320
|
+
async function processWithDelay() {
|
321
|
+
await sleep(2000); // Wait for 2 seconds
|
322
|
+
// Continue execution
|
323
|
+
}
|
324
|
+
```
|
325
|
+
|
158
326
|
## Development
|
159
327
|
|
160
328
|
### Requirements
|
@@ -0,0 +1,20 @@
|
|
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("./order-by.decorator"), exports);
|
18
|
+
__exportStar(require("./pagination.decorator"), exports);
|
19
|
+
__exportStar(require("./search.decorator"), exports);
|
20
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC;AACrC,yDAAuC;AACvC,qDAAmC"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.OrderBy = void 0;
|
4
|
+
const common_1 = require("@nestjs/common");
|
5
|
+
const order_by_validation_1 = require("../validations/order-by.validation");
|
6
|
+
const OrderBy = (fields) => (0, common_1.createParamDecorator)((data, ctx) => {
|
7
|
+
const request = ctx.switchToHttp().getRequest();
|
8
|
+
const orderBySchema = (0, order_by_validation_1.createOrderBySchema)(fields);
|
9
|
+
return orderBySchema.parse(request.query).order_by;
|
10
|
+
})();
|
11
|
+
exports.OrderBy = OrderBy;
|
12
|
+
//# sourceMappingURL=order-by.decorator.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"order-by.decorator.js","sourceRoot":"","sources":["../../src/decorators/order-by.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwE;AAIxE,4EAAyE;AAIlE,MAAM,OAAO,GAAG,CAAS,MAAwB,EAAE,EAAE,CAC1D,IAAA,6BAAoB,EAAC,CAAC,IAAa,EAAE,GAAqB,EAAwB,EAAE;IAClF,MAAM,OAAO,GAAY,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;IAEzD,MAAM,aAAa,GAAG,IAAA,yCAAmB,EAAC,MAAkB,CAAC,CAAC;IAE9D,OAAO,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAe,CAAC;AAC5D,CAAC,CAAC,EAAE,CAAC;AAPM,QAAA,OAAO,WAOb"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const Pagination: (...dataOrPipes: unknown[]) => ParameterDecorator;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.Pagination = void 0;
|
4
|
+
const common_1 = require("@nestjs/common");
|
5
|
+
const pagination_validation_1 = require("../validations/pagination.validation");
|
6
|
+
exports.Pagination = (0, common_1.createParamDecorator)((data, ctx) => {
|
7
|
+
const request = ctx.switchToHttp().getRequest();
|
8
|
+
return pagination_validation_1.paginationSchema.parse(request.query);
|
9
|
+
});
|
10
|
+
//# sourceMappingURL=pagination.decorator.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"pagination.decorator.js","sourceRoot":"","sources":["../../src/decorators/pagination.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwE;AAGxE,gFAAwE;AAE3D,QAAA,UAAU,GAAG,IAAA,6BAAoB,EAAC,CAAC,IAAa,EAAE,GAAqB,EAAE,EAAE;IACtF,MAAM,OAAO,GAAY,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;IAEzD,OAAO,wCAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC"}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.Search = void 0;
|
4
|
+
const common_1 = require("@nestjs/common");
|
5
|
+
const typeorm_1 = require("typeorm");
|
6
|
+
const search_validation_1 = require("../validations/search.validation");
|
7
|
+
const Search = (fields) => (0, common_1.createParamDecorator)((data, ctx) => {
|
8
|
+
const request = ctx.switchToHttp().getRequest();
|
9
|
+
const parsed = search_validation_1.searchSchema.parse(request.query);
|
10
|
+
if (!parsed.q)
|
11
|
+
return;
|
12
|
+
return fields.map((field) => ({
|
13
|
+
[field]: (0, typeorm_1.Raw)((alias) => `CAST(${alias} AS TEXT) ILIKE :searchTerm`, { searchTerm: `%${parsed.q}%` }),
|
14
|
+
}));
|
15
|
+
})();
|
16
|
+
exports.Search = Search;
|
17
|
+
//# sourceMappingURL=search.decorator.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"search.decorator.js","sourceRoot":"","sources":["../../src/decorators/search.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwE;AAExE,qCAAgD;AAEhD,wEAAgE;AAIzD,MAAM,MAAM,GAAG,CAAS,MAAwB,EAAE,EAAE,CACzD,IAAA,6BAAoB,EAAC,CAAC,IAAa,EAAE,GAAqB,EAAwB,EAAE;IAClF,MAAM,OAAO,GAAY,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;IAEzD,MAAM,MAAM,GAAG,gCAAY,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAEjD,IAAI,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO;IAEtB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5B,CAAC,KAAK,CAAC,EAAE,IAAA,aAAG,EAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,KAAK,6BAA6B,EAAE,EAAE,UAAU,EAAE,IAAI,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;KACrG,CAAC,CAAQ,CAAC;AACb,CAAC,CAAC,EAAE,CAAC;AAXM,QAAA,MAAM,UAWZ"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
@@ -14,5 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
15
|
};
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
__exportStar(require("./decorators"), exports);
|
17
18
|
__exportStar(require("./exceptions"), exports);
|
19
|
+
__exportStar(require("./pipes"), exports);
|
20
|
+
__exportStar(require("./responses"), exports);
|
21
|
+
__exportStar(require("./utils"), exports);
|
22
|
+
__exportStar(require("./validations"), exports);
|
18
23
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B"}
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,+CAA6B;AAC7B,0CAAwB;AACxB,8CAA4B;AAC5B,0CAAwB;AACxB,gDAA8B"}
|
@@ -0,0 +1,28 @@
|
|
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.AppZodValidationPipe = void 0;
|
10
|
+
const zod_nestjs_1 = require("@anatine/zod-nestjs");
|
11
|
+
const common_1 = require("@nestjs/common");
|
12
|
+
const exceptions_1 = require("../exceptions");
|
13
|
+
let AppZodValidationPipe = class AppZodValidationPipe extends zod_nestjs_1.ZodValidationPipe {
|
14
|
+
transform(value, metadata) {
|
15
|
+
const zodSchema = metadata?.metatype?.zodSchema;
|
16
|
+
if (!zodSchema)
|
17
|
+
return value;
|
18
|
+
const parseResult = zodSchema.safeParse(value);
|
19
|
+
if (!parseResult.success)
|
20
|
+
throw new exceptions_1.AppValidationException(parseResult.error);
|
21
|
+
return parseResult.data;
|
22
|
+
}
|
23
|
+
};
|
24
|
+
exports.AppZodValidationPipe = AppZodValidationPipe;
|
25
|
+
exports.AppZodValidationPipe = AppZodValidationPipe = __decorate([
|
26
|
+
(0, common_1.Injectable)()
|
27
|
+
], AppZodValidationPipe);
|
28
|
+
//# sourceMappingURL=app-zod-validation.pipe.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"app-zod-validation.pipe.js","sourceRoot":"","sources":["../../src/pipes/app-zod-validation.pipe.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAsE;AACtE,2CAA8D;AAE9D,8CAAuD;AAGhD,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,8BAAiB;IACzD,SAAS,CAAC,KAAc,EAAE,QAA0B;QAClD,MAAM,SAAS,GAAI,QAAQ,EAAE,QAAyB,EAAE,SAAS,CAAC;QAElE,IAAI,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC;QAE7B,MAAM,WAAW,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAE/C,IAAI,CAAC,WAAW,CAAC,OAAO;YAAE,MAAM,IAAI,mCAAsB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAE9E,OAAO,WAAW,CAAC,IAAI,CAAC;IAC1B,CAAC;CACF,CAAA;AAZY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;GACA,oBAAoB,CAYhC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './app-zod-validation.pipe';
|
@@ -0,0 +1,18 @@
|
|
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("./app-zod-validation.pipe"), exports);
|
18
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pipes/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4DAA0C"}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
type APIResponseValue = any[] | Record<string, any>;
|
2
|
+
export type APIResponse<T extends string[] | string, R = APIResponseValue> = {
|
3
|
+
[K in T extends string ? T : T[number]]: R;
|
4
|
+
};
|
5
|
+
export type APIResponseOnlyMessage = APIResponse<'message', string>;
|
6
|
+
export type APIResponseMetadata = {
|
7
|
+
metadata: {
|
8
|
+
pagination: {
|
9
|
+
page: number;
|
10
|
+
per_page: number;
|
11
|
+
total_pages: number;
|
12
|
+
total_items: number;
|
13
|
+
};
|
14
|
+
};
|
15
|
+
};
|
16
|
+
export type PaginatedAPIResponse<R = APIResponseValue> = APIResponse<'data', R[]> & APIResponseMetadata;
|
17
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"api-response.type.js","sourceRoot":"","sources":["../../src/responses/api-response.type.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './api-response.type';
|
@@ -0,0 +1,18 @@
|
|
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("./api-response.type"), exports);
|
18
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/responses/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC"}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.exponentialRetry = exponentialRetry;
|
4
|
+
const sleep_util_1 = require("./sleep.util");
|
5
|
+
async function exponentialRetry(fn, options) {
|
6
|
+
const maxAttempts = options?.maxAttempts ?? 3;
|
7
|
+
const baseDelayMs = options?.baseDelayMs ?? 2000;
|
8
|
+
let lastError = null;
|
9
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
10
|
+
try {
|
11
|
+
return await fn();
|
12
|
+
}
|
13
|
+
catch (error) {
|
14
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
15
|
+
if (attempt === maxAttempts)
|
16
|
+
throw lastError;
|
17
|
+
const delay = Math.pow(2, attempt) * baseDelayMs;
|
18
|
+
await (0, sleep_util_1.sleep)(delay);
|
19
|
+
}
|
20
|
+
}
|
21
|
+
throw lastError || new Error('Unknown error');
|
22
|
+
}
|
23
|
+
//# sourceMappingURL=exponential-retry.util.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"exponential-retry.util.js","sourceRoot":"","sources":["../../src/utils/exponential-retry.util.ts"],"names":[],"mappings":";;AAOA,4CAqBC;AA5BD,6CAAqC;AAO9B,KAAK,UAAU,gBAAgB,CAAI,EAAoB,EAAE,OAAiC;IAC/F,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,CAAC,CAAC;IAC9C,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,IAAI,CAAC;IAEjD,IAAI,SAAS,GAAiB,IAAI,CAAC;IAEnC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAEtE,IAAI,OAAO,KAAK,WAAW;gBAAE,MAAM,SAAS,CAAC;YAE7C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC;YAEjD,MAAM,IAAA,kBAAK,EAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;AAChD,CAAC"}
|
@@ -0,0 +1,19 @@
|
|
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("./exponential-retry.util"), exports);
|
18
|
+
__exportStar(require("./sleep.util"), exports);
|
19
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAyC;AACzC,+CAA6B"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const sleep: (timeout: number) => Promise<void>;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.sleep = void 0;
|
4
|
+
const sleep = async (timeout) => {
|
5
|
+
return await new Promise((resolve) => setTimeout(resolve, timeout));
|
6
|
+
};
|
7
|
+
exports.sleep = sleep;
|
8
|
+
//# sourceMappingURL=sleep.util.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"sleep.util.js","sourceRoot":"","sources":["../../src/utils/sleep.util.ts"],"names":[],"mappings":";;;AAAO,MAAM,KAAK,GAAG,KAAK,EAAE,OAAe,EAAE,EAAE;IAC7C,OAAO,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5E,CAAC,CAAC;AAFW,QAAA,KAAK,SAEhB"}
|
@@ -0,0 +1,20 @@
|
|
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("./order-by.validation"), exports);
|
18
|
+
__exportStar(require("./pagination.validation"), exports);
|
19
|
+
__exportStar(require("./search.validation"), exports);
|
20
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validations/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AACtC,0DAAwC;AACxC,sDAAoC"}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { z } from 'zod';
|
2
|
+
export declare const createOrderBySchema: (fields: string[]) => z.ZodObject<{
|
3
|
+
order_by: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, {
|
4
|
+
[x: string]: string;
|
5
|
+
}, string>, {
|
6
|
+
[x: string]: string;
|
7
|
+
}, string>>;
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
9
|
+
order_by?: {
|
10
|
+
[x: string]: string;
|
11
|
+
} | undefined;
|
12
|
+
}, {
|
13
|
+
order_by?: string | undefined;
|
14
|
+
}>;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.createOrderBySchema = void 0;
|
4
|
+
const zod_1 = require("zod");
|
5
|
+
const createOrderBySchema = (fields) => zod_1.z.object({
|
6
|
+
order_by: zod_1.z
|
7
|
+
.string()
|
8
|
+
.transform((val) => {
|
9
|
+
const [direction, field] = val.startsWith('-') ? ['desc', val.slice(1)] : ['asc', val];
|
10
|
+
return { [field]: direction };
|
11
|
+
})
|
12
|
+
.refine((val) => fields.includes(Object.keys(val)[0]), {
|
13
|
+
message: `Field must be one of: ${fields.join(', ')} `,
|
14
|
+
})
|
15
|
+
.optional(),
|
16
|
+
});
|
17
|
+
exports.createOrderBySchema = createOrderBySchema;
|
18
|
+
//# sourceMappingURL=order-by.validation.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"order-by.validation.js","sourceRoot":"","sources":["../../src/validations/order-by.validation.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAEjB,MAAM,mBAAmB,GAAG,CAAC,MAAgB,EAAE,EAAE,CACtD,OAAC,CAAC,MAAM,CAAC;IACP,QAAQ,EAAE,OAAC;SACR,MAAM,EAAE;SACR,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;QACjB,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAEvF,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IAChC,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;QACrD,OAAO,EAAE,yBAAyB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;KACvD,CAAC;SACD,QAAQ,EAAE;CACd,CAAC,CAAC;AAbQ,QAAA,mBAAmB,uBAa3B"}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { z } from 'zod';
|
2
|
+
export declare const paginationSchema: z.ZodEffects<z.ZodObject<{
|
3
|
+
page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
4
|
+
per_page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
6
|
+
page: number;
|
7
|
+
per_page: number;
|
8
|
+
}, {
|
9
|
+
page?: number | undefined;
|
10
|
+
per_page?: number | undefined;
|
11
|
+
}>, {
|
12
|
+
skip: number;
|
13
|
+
take: number;
|
14
|
+
}, {
|
15
|
+
page?: number | undefined;
|
16
|
+
per_page?: number | undefined;
|
17
|
+
}>;
|
18
|
+
export type PaginationParams = z.output<typeof paginationSchema>;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.paginationSchema = void 0;
|
4
|
+
const zod_1 = require("zod");
|
5
|
+
exports.paginationSchema = zod_1.z
|
6
|
+
.object({
|
7
|
+
page: zod_1.z.coerce.number().int().positive().optional().default(1),
|
8
|
+
per_page: zod_1.z.coerce.number().int().positive().optional().default(20),
|
9
|
+
})
|
10
|
+
.transform(({ page, per_page }) => {
|
11
|
+
return {
|
12
|
+
skip: (page - 1) * per_page,
|
13
|
+
take: per_page,
|
14
|
+
};
|
15
|
+
});
|
16
|
+
//# sourceMappingURL=pagination.validation.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"pagination.validation.js","sourceRoot":"","sources":["../../src/validations/pagination.validation.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAEX,QAAA,gBAAgB,GAAG,OAAC;KAC9B,MAAM,CAAC;IACN,IAAI,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,QAAQ,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CACpE,CAAC;KACD,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;IAChC,OAAO;QACL,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ;QAC3B,IAAI,EAAE,QAAQ;KACf,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.searchSchema = void 0;
|
4
|
+
const zod_1 = require("zod");
|
5
|
+
exports.searchSchema = zod_1.z.object({
|
6
|
+
q: zod_1.z.string().optional(),
|
7
|
+
});
|
8
|
+
//# sourceMappingURL=search.validation.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"search.validation.js","sourceRoot":"","sources":["../../src/validations/search.validation.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAEX,QAAA,YAAY,GAAG,OAAC,CAAC,MAAM,CAAC;IACnC,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACzB,CAAC,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@furkanogutcu/nest-common",
|
3
|
-
"version": "
|
3
|
+
"version": "1.0.1",
|
4
4
|
"description": "Package of common structures for NestJS.",
|
5
5
|
"author": "Furkan Ogutcu",
|
6
6
|
"license": "MIT",
|
@@ -51,7 +51,8 @@
|
|
51
51
|
"@nestjs/testing": "11.1.0",
|
52
52
|
"@nestjs/platform-express": "^11.1.0",
|
53
53
|
"zod": "^3.24.3",
|
54
|
-
"typeorm": "^0.3.22"
|
54
|
+
"typeorm": "^0.3.22",
|
55
|
+
"@anatine/zod-nestjs": "^2.0.12"
|
55
56
|
},
|
56
57
|
"dependencies": {},
|
57
58
|
"devDependencies": {
|