microservice-common-nestjs 1.0.0
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 +452 -0
- package/dist/cache/cache.module.d.ts +5 -0
- package/dist/cache/cache.module.js +32 -0
- package/dist/cache/cache.module.js.map +1 -0
- package/dist/cache/cache.service.d.ts +18 -0
- package/dist/cache/cache.service.js +68 -0
- package/dist/cache/cache.service.js.map +1 -0
- package/dist/client/client.interface.d.ts +14 -0
- package/dist/client/client.interface.js +3 -0
- package/dist/client/client.interface.js.map +1 -0
- package/dist/client/http-client.module.d.ts +2 -0
- package/dist/client/http-client.module.js +22 -0
- package/dist/client/http-client.module.js.map +1 -0
- package/dist/client/http-client.service.d.ts +12 -0
- package/dist/client/http-client.service.js +100 -0
- package/dist/client/http-client.service.js.map +1 -0
- package/dist/config/config.interface.d.ts +42 -0
- package/dist/config/config.interface.js +3 -0
- package/dist/config/config.interface.js.map +1 -0
- package/dist/config/config.module.d.ts +2 -0
- package/dist/config/config.module.js +28 -0
- package/dist/config/config.module.js.map +1 -0
- package/dist/config/config.service.d.ts +10 -0
- package/dist/config/config.service.js +85 -0
- package/dist/config/config.service.js.map +1 -0
- package/dist/database/prisma.module.d.ts +21 -0
- package/dist/database/prisma.module.js +121 -0
- package/dist/database/prisma.module.js.map +1 -0
- package/dist/health/health.controller.d.ts +10 -0
- package/dist/health/health.controller.js +75 -0
- package/dist/health/health.controller.js.map +1 -0
- package/dist/health/health.interface.d.ts +14 -0
- package/dist/health/health.interface.js +3 -0
- package/dist/health/health.interface.js.map +1 -0
- package/dist/health/health.module.d.ts +2 -0
- package/dist/health/health.module.js +23 -0
- package/dist/health/health.module.js.map +1 -0
- package/dist/health/health.service.d.ts +10 -0
- package/dist/health/health.service.js +25 -0
- package/dist/health/health.service.js.map +1 -0
- package/dist/http/http-response.decorator.d.ts +6 -0
- package/dist/http/http-response.decorator.js +8 -0
- package/dist/http/http-response.decorator.js.map +1 -0
- package/dist/http/http-response.module.d.ts +2 -0
- package/dist/http/http-response.module.js +22 -0
- package/dist/http/http-response.module.js.map +1 -0
- package/dist/http/http-response.service.d.ts +17 -0
- package/dist/http/http-response.service.js +73 -0
- package/dist/http/http-response.service.js.map +1 -0
- package/dist/http/response.interface.d.ts +10 -0
- package/dist/http/response.interface.js +3 -0
- package/dist/http/response.interface.js.map +1 -0
- package/dist/i18n/i18n.module.d.ts +5 -0
- package/dist/i18n/i18n.module.js +32 -0
- package/dist/i18n/i18n.module.js.map +1 -0
- package/dist/i18n/i18n.service.d.ts +16 -0
- package/dist/i18n/i18n.service.js +58 -0
- package/dist/i18n/i18n.service.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/microservice-common.module.d.ts +17 -0
- package/dist/microservice-common.module.js +76 -0
- package/dist/microservice-common.module.js.map +1 -0
- package/dist/middleware/correlation-id.middleware.d.ts +9 -0
- package/dist/middleware/correlation-id.middleware.js +34 -0
- package/dist/middleware/correlation-id.middleware.js.map +1 -0
- package/dist/middleware/cors.middleware.d.ts +9 -0
- package/dist/middleware/cors.middleware.js +71 -0
- package/dist/middleware/cors.middleware.js.map +1 -0
- package/dist/middleware/logging.middleware.d.ts +10 -0
- package/dist/middleware/logging.middleware.js +75 -0
- package/dist/middleware/logging.middleware.js.map +1 -0
- package/dist/middleware/middleware.interface.d.ts +18 -0
- package/dist/middleware/middleware.interface.js +3 -0
- package/dist/middleware/middleware.interface.js.map +1 -0
- package/dist/middleware/middleware.module.d.ts +9 -0
- package/dist/middleware/middleware.module.js +61 -0
- package/dist/middleware/middleware.module.js.map +1 -0
- package/dist/prometheus/prometheus.module.d.ts +8 -0
- package/dist/prometheus/prometheus.module.js +44 -0
- package/dist/prometheus/prometheus.module.js.map +1 -0
- package/dist/prometheus/prometheus.service.d.ts +14 -0
- package/dist/prometheus/prometheus.service.js +56 -0
- package/dist/prometheus/prometheus.service.js.map +1 -0
- package/dist/rate-limit/rate-limit.module.d.ts +4 -0
- package/dist/rate-limit/rate-limit.module.js +47 -0
- package/dist/rate-limit/rate-limit.module.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +88 -0
package/README.md
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# Microservice Common NestJS
|
|
2
|
+
|
|
3
|
+
A comprehensive common library for NestJS microservices with health checks, database management, logging, HTTP client, caching, and more.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Health Check** - `/health` and `/ping` endpoints
|
|
8
|
+
- ✅ **Configuration Management** - Environment-based configuration with validation
|
|
9
|
+
- ✅ **Database** - TypeORM support for PostgreSQL, MySQL, and MariaDB
|
|
10
|
+
- ✅ **HTTP Response Helpers** - Standardized API response format
|
|
11
|
+
- ✅ **Middleware** - CORS, correlation ID, logging
|
|
12
|
+
- ✅ **HTTP Client** - Axios-based client with retry mechanism
|
|
13
|
+
- ✅ **Caching** - In-memory caching with TTL support
|
|
14
|
+
- ✅ **Rate Limiting** - Request rate limiting
|
|
15
|
+
- ✅ **Prometheus Metrics** - Built-in metrics endpoint
|
|
16
|
+
- ✅ **i18n** - Internationalization support
|
|
17
|
+
- ✅ **TypeScript** - Fully typed with no `any` types
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @projectzero/microservice-common-nestjs
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### Basic Setup
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { Module } from '@nestjs/common';
|
|
31
|
+
import { MicroserviceCommonModule } from '@projectzero/microservice-common-nestjs';
|
|
32
|
+
|
|
33
|
+
@Module({
|
|
34
|
+
imports: [
|
|
35
|
+
MicroserviceCommonModule.forRoot({
|
|
36
|
+
enableDatabase: true,
|
|
37
|
+
enableCache: true,
|
|
38
|
+
enableRateLimit: true,
|
|
39
|
+
enablePrometheus: true,
|
|
40
|
+
}),
|
|
41
|
+
],
|
|
42
|
+
})
|
|
43
|
+
export class AppModule {}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Main Application
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { NestFactory } from '@nestjs/core';
|
|
50
|
+
import { AppModule } from './app.module';
|
|
51
|
+
import { ConfigService } from '@projectzero/microservice-common-nestjs';
|
|
52
|
+
|
|
53
|
+
async function bootstrap() {
|
|
54
|
+
const app = await NestFactory.create(AppModule);
|
|
55
|
+
|
|
56
|
+
const configService = app.get(ConfigService);
|
|
57
|
+
const config = configService.getConfig();
|
|
58
|
+
|
|
59
|
+
await app.listen(config.http.port);
|
|
60
|
+
console.log(`Application is running on: ${await app.getUrl()}`);
|
|
61
|
+
}
|
|
62
|
+
bootstrap();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
### Environment Variables
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Server
|
|
71
|
+
PORT=8080
|
|
72
|
+
GRACEFUL_SHUTDOWN_TIMEOUT=5000
|
|
73
|
+
|
|
74
|
+
# Database
|
|
75
|
+
DB_TYPE=postgres # postgres, mysql, mariadb
|
|
76
|
+
DB_HOST=localhost
|
|
77
|
+
DB_PORT=5432
|
|
78
|
+
DB_USER=user
|
|
79
|
+
DB_PASSWORD=password
|
|
80
|
+
DB_NAME=mydb
|
|
81
|
+
DB_SSLMODE=disable
|
|
82
|
+
DB_SYNCHRONIZE=false
|
|
83
|
+
DB_MIGRATE=false
|
|
84
|
+
DB_LOGGING=false
|
|
85
|
+
|
|
86
|
+
# Logging
|
|
87
|
+
LOG_LEVEL=info # debug, info, warn, error
|
|
88
|
+
LOG_FORMAT=json # json, text
|
|
89
|
+
|
|
90
|
+
# CORS
|
|
91
|
+
CORS_ORIGIN=*
|
|
92
|
+
CORS_METHODS=GET,POST,PUT,DELETE,OPTIONS,PATCH,HEAD
|
|
93
|
+
CORS_ALLOWED_HEADERS=Content-Type,Authorization,X-Request-ID
|
|
94
|
+
CORS_CREDENTIALS=false
|
|
95
|
+
|
|
96
|
+
# JWT
|
|
97
|
+
JWT_SECRET=your-secret-key
|
|
98
|
+
JWT_EXPIRES_IN=1h
|
|
99
|
+
|
|
100
|
+
# Rate Limiting
|
|
101
|
+
RATE_LIMIT_TTL=60
|
|
102
|
+
RATE_LIMIT_LIMIT=100
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Usage Examples
|
|
106
|
+
|
|
107
|
+
### Health Check
|
|
108
|
+
|
|
109
|
+
The health check endpoints are automatically available:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Health check
|
|
113
|
+
curl http://localhost:8080/health
|
|
114
|
+
|
|
115
|
+
# Ping
|
|
116
|
+
curl http://localhost:8080/ping
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### HTTP Response Helpers
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { Controller, Get } from '@nestjs/common';
|
|
123
|
+
import { HttpResponseService } from '@projectzero/microservice-common-nestjs';
|
|
124
|
+
|
|
125
|
+
@Controller('users')
|
|
126
|
+
export class UsersController {
|
|
127
|
+
constructor(private readonly httpResponse: HttpResponseService) {}
|
|
128
|
+
|
|
129
|
+
@Get()
|
|
130
|
+
findAll() {
|
|
131
|
+
const data = [{ id: 1, name: 'John' }];
|
|
132
|
+
return this.httpResponse.success('1000', 'Users retrieved successfully', data);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@Get(':id')
|
|
136
|
+
findOne(id: string) {
|
|
137
|
+
if (!id) {
|
|
138
|
+
this.httpResponse.throwBadRequest('User ID is required');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const user = { id, name: 'John' };
|
|
142
|
+
return this.httpResponse.success('1000', 'User retrieved successfully', user);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Database
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { Module } from '@nestjs/common';
|
|
151
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
152
|
+
import { DatabaseModule } from '@projectzero/microservice-common-nestjs';
|
|
153
|
+
import { User } from './user.entity';
|
|
154
|
+
|
|
155
|
+
@Module({
|
|
156
|
+
imports: [
|
|
157
|
+
DatabaseModule.forRoot({
|
|
158
|
+
entities: [User],
|
|
159
|
+
migrations: ['dist/migrations/*.js'],
|
|
160
|
+
}),
|
|
161
|
+
],
|
|
162
|
+
})
|
|
163
|
+
export class AppModule {}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### HTTP Client with Retry
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { Injectable } from '@nestjs/common';
|
|
170
|
+
import { HttpClientService } from '@projectzero/microservice-common-nestjs';
|
|
171
|
+
|
|
172
|
+
@Injectable()
|
|
173
|
+
export class ExternalApiService {
|
|
174
|
+
constructor(private readonly httpClient: HttpClientService) {}
|
|
175
|
+
|
|
176
|
+
async fetchData() {
|
|
177
|
+
// Create a client
|
|
178
|
+
const client = this.httpClient.createClient('external-api', {
|
|
179
|
+
baseURL: 'https://api.example.com',
|
|
180
|
+
timeout: 5000,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Use the client
|
|
184
|
+
const data = await client.get('/data');
|
|
185
|
+
return data;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async requestWithRetry() {
|
|
189
|
+
// Request with automatic retry
|
|
190
|
+
const data = await this.httpClient.request({
|
|
191
|
+
url: 'https://api.example.com/data',
|
|
192
|
+
method: 'GET',
|
|
193
|
+
retry: {
|
|
194
|
+
retries: 3,
|
|
195
|
+
delay: 1000,
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
return data;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Caching
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
import { Injectable } from '@nestjs/common';
|
|
207
|
+
import { CacheService } from '@projectzero/microservice-common-nestjs';
|
|
208
|
+
|
|
209
|
+
@Injectable()
|
|
210
|
+
export class DataService {
|
|
211
|
+
constructor(private readonly cache: CacheService) {}
|
|
212
|
+
|
|
213
|
+
async getData(key: string) {
|
|
214
|
+
// Check cache first
|
|
215
|
+
const cached = this.cache.get<string>(key);
|
|
216
|
+
if (cached) {
|
|
217
|
+
return cached;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Fetch from source
|
|
221
|
+
const data = await this.fetchFromSource();
|
|
222
|
+
|
|
223
|
+
// Cache for 5 minutes
|
|
224
|
+
this.cache.set(key, data, 300);
|
|
225
|
+
return data;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### i18n
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { Injectable } from '@nestjs/common';
|
|
234
|
+
import { I18nService } from '@projectzero/microservice-common-nestjs';
|
|
235
|
+
import { Request } from 'express';
|
|
236
|
+
|
|
237
|
+
@Injectable()
|
|
238
|
+
export class MessageService {
|
|
239
|
+
constructor(private readonly i18n: I18nService) {}
|
|
240
|
+
|
|
241
|
+
getMessage(req: Request, key: string) {
|
|
242
|
+
return this.i18n.translateFromRequest(req, key);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Rate Limiting
|
|
248
|
+
|
|
249
|
+
Rate limiting is automatically applied. To customize:
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import { ThrottlerGuard } from '@nestjs/throttler';
|
|
253
|
+
import { UseGuards } from '@nestjs/common';
|
|
254
|
+
|
|
255
|
+
@Controller('api')
|
|
256
|
+
@UseGuards(ThrottlerGuard)
|
|
257
|
+
export class ApiController {
|
|
258
|
+
// Rate limited endpoints
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Module Options
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
MicroserviceCommonModule.forRoot({
|
|
266
|
+
// Enable database connection
|
|
267
|
+
enableDatabase: true,
|
|
268
|
+
databaseOptions: {
|
|
269
|
+
entities: [User, Product],
|
|
270
|
+
migrations: ['dist/migrations/*.js'],
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
// Enable caching
|
|
274
|
+
enableCache: true,
|
|
275
|
+
cacheOptions: {
|
|
276
|
+
stdTTL: 600, // 10 minutes
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
// Enable rate limiting
|
|
280
|
+
enableRateLimit: true,
|
|
281
|
+
|
|
282
|
+
// Enable Prometheus metrics
|
|
283
|
+
enablePrometheus: true,
|
|
284
|
+
|
|
285
|
+
// Enable i18n
|
|
286
|
+
enableI18n: true,
|
|
287
|
+
i18nOptions: {
|
|
288
|
+
defaultLanguage: 'en',
|
|
289
|
+
fallbackLanguage: 'en',
|
|
290
|
+
resources: {
|
|
291
|
+
en: {
|
|
292
|
+
translation: {
|
|
293
|
+
'user.not_found': 'User not found',
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
// Correlation ID options
|
|
300
|
+
correlationIdOptions: {
|
|
301
|
+
headerName: 'x-correlation-id',
|
|
302
|
+
generateIfMissing: true,
|
|
303
|
+
},
|
|
304
|
+
|
|
305
|
+
// Logging options
|
|
306
|
+
loggingOptions: {
|
|
307
|
+
logRequestBody: false,
|
|
308
|
+
logResponseBody: false,
|
|
309
|
+
ignoreRoutes: ['/health', '/ping'],
|
|
310
|
+
},
|
|
311
|
+
})
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Response Format
|
|
315
|
+
|
|
316
|
+
All API responses follow a standard format:
|
|
317
|
+
|
|
318
|
+
```json
|
|
319
|
+
{
|
|
320
|
+
"status": {
|
|
321
|
+
"code": "1000",
|
|
322
|
+
"description": "Success",
|
|
323
|
+
"http_code": 200
|
|
324
|
+
},
|
|
325
|
+
"data": {
|
|
326
|
+
// Your data here
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Error responses:
|
|
332
|
+
|
|
333
|
+
```json
|
|
334
|
+
{
|
|
335
|
+
"status": {
|
|
336
|
+
"code": "1999",
|
|
337
|
+
"description": "Error message",
|
|
338
|
+
"http_code": 400,
|
|
339
|
+
"details": {
|
|
340
|
+
// Additional error details
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Best Practices
|
|
347
|
+
|
|
348
|
+
1. **Always use TypeScript types** - The library is fully typed, avoid using `any`
|
|
349
|
+
2. **Use dependency injection** - All services are injectable via NestJS DI
|
|
350
|
+
3. **Configure via environment variables** - Use `.env` files for configuration
|
|
351
|
+
4. **Enable only what you need** - Disable unused features to reduce overhead
|
|
352
|
+
5. **Use correlation IDs** - They're automatically added to all requests
|
|
353
|
+
6. **Monitor with Prometheus** - Enable metrics for production monitoring
|
|
354
|
+
|
|
355
|
+
## Development
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
# Install dependencies
|
|
359
|
+
npm install
|
|
360
|
+
|
|
361
|
+
# Build
|
|
362
|
+
npm run build
|
|
363
|
+
|
|
364
|
+
# Run tests
|
|
365
|
+
npm test
|
|
366
|
+
|
|
367
|
+
# Lint
|
|
368
|
+
npm run lint
|
|
369
|
+
|
|
370
|
+
# Format code
|
|
371
|
+
npm run format
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Publishing to Private NPM
|
|
375
|
+
|
|
376
|
+
This package is configured to be published as a **private package** to npm. Scoped packages (packages starting with `@projectzero/`) are private by default on npm.
|
|
377
|
+
|
|
378
|
+
### Prerequisites
|
|
379
|
+
|
|
380
|
+
1. **NPM Account**: You need an npm account with access to the `@projectzero` organization
|
|
381
|
+
2. **Authentication**: Login to npm using `npm login`
|
|
382
|
+
3. **Organization Access**: Ensure you have publish permissions for the `@projectzero` scope
|
|
383
|
+
|
|
384
|
+
### Publishing Steps
|
|
385
|
+
|
|
386
|
+
1. **Login to npm** (if not already logged in):
|
|
387
|
+
```bash
|
|
388
|
+
npm login
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
2. **Build the package** (automatically runs before publish):
|
|
392
|
+
```bash
|
|
393
|
+
npm run build
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
3. **Publish to npm**:
|
|
397
|
+
```bash
|
|
398
|
+
npm publish
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
The package will be published as **private** automatically because:
|
|
402
|
+
- It's a scoped package (`@projectzero/microservice-common-nestjs`)
|
|
403
|
+
- `publishConfig.access` is set to `"restricted"` in `package.json`
|
|
404
|
+
|
|
405
|
+
### Important Notes
|
|
406
|
+
|
|
407
|
+
- **Private by Default**: Scoped packages are private on npm by default. They will NOT automatically become public.
|
|
408
|
+
- **Access Control**: Only users/organizations with access to the `@projectzero` scope can install this package.
|
|
409
|
+
- **Version Management**: Update the version in `package.json` before publishing a new version:
|
|
410
|
+
```bash
|
|
411
|
+
npm version patch # 1.0.0 -> 1.0.1
|
|
412
|
+
npm version minor # 1.0.0 -> 1.1.0
|
|
413
|
+
npm version major # 1.0.0 -> 2.0.0
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Using a Private NPM Registry
|
|
417
|
+
|
|
418
|
+
If you're using a private npm registry (like npm Enterprise, Verdaccio, etc.):
|
|
419
|
+
|
|
420
|
+
1. **Configure `.npmrc`** in the project root:
|
|
421
|
+
```ini
|
|
422
|
+
registry=https://your-private-registry.com/
|
|
423
|
+
//your-private-registry.com/:_authToken=${NPM_TOKEN}
|
|
424
|
+
@projectzero:registry=https://your-private-registry.com/
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
2. **Set environment variable**:
|
|
428
|
+
```bash
|
|
429
|
+
export NPM_TOKEN=your-auth-token
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
3. **Publish**:
|
|
433
|
+
```bash
|
|
434
|
+
npm publish
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Installing the Published Package
|
|
438
|
+
|
|
439
|
+
After publishing, other projects can install it using:
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
npm install @projectzero/microservice-common-nestjs
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
**Note**: Users installing this package must:
|
|
446
|
+
- Be logged in to npm (`npm login`)
|
|
447
|
+
- Have access to the `@projectzero` organization/scope
|
|
448
|
+
- Or have the private registry configured in their `.npmrc`
|
|
449
|
+
|
|
450
|
+
## License
|
|
451
|
+
|
|
452
|
+
MIT
|
|
@@ -0,0 +1,32 @@
|
|
|
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 CacheModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CacheModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const cache_service_1 = require("../cache/cache.service");
|
|
13
|
+
let CacheModule = CacheModule_1 = class CacheModule {
|
|
14
|
+
static forRoot(options) {
|
|
15
|
+
return {
|
|
16
|
+
module: CacheModule_1,
|
|
17
|
+
providers: [
|
|
18
|
+
{
|
|
19
|
+
provide: cache_service_1.CacheService,
|
|
20
|
+
useValue: new cache_service_1.CacheService(options),
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
exports: [cache_service_1.CacheService],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
exports.CacheModule = CacheModule;
|
|
28
|
+
exports.CacheModule = CacheModule = CacheModule_1 = __decorate([
|
|
29
|
+
(0, common_1.Global)(),
|
|
30
|
+
(0, common_1.Module)({})
|
|
31
|
+
], CacheModule);
|
|
32
|
+
//# sourceMappingURL=cache.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.module.js","sourceRoot":"","sources":["../../src/cache/cache.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+D;AAC/D,yDAAmE;AAI5D,IAAM,WAAW,mBAAjB,MAAM,WAAW;IACtB,MAAM,CAAC,OAAO,CAAC,OAAsB;QACnC,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,4BAAY;oBACrB,QAAQ,EAAE,IAAI,4BAAY,CAAC,OAAO,CAAC;iBACpC;aACF;YACD,OAAO,EAAE,CAAC,4BAAY,CAAC;SACxB,CAAC;IACJ,CAAC;CACF,CAAA;AAbY,kCAAW;sBAAX,WAAW;IAFvB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,WAAW,CAavB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import NodeCache from 'node-cache';
|
|
2
|
+
export interface CacheOptions {
|
|
3
|
+
stdTTL?: number;
|
|
4
|
+
checkperiod?: number;
|
|
5
|
+
useClones?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class CacheService {
|
|
8
|
+
private readonly logger;
|
|
9
|
+
private readonly cache;
|
|
10
|
+
constructor(options?: CacheOptions);
|
|
11
|
+
get<T>(key: string): T | undefined;
|
|
12
|
+
set<T>(key: string, value: T, ttl?: number): boolean;
|
|
13
|
+
del(key: string): number;
|
|
14
|
+
has(key: string): boolean;
|
|
15
|
+
flush(): void;
|
|
16
|
+
getStats(): NodeCache.Stats;
|
|
17
|
+
keys(): string[];
|
|
18
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
var CacheService_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.CacheService = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const node_cache_1 = __importDefault(require("node-cache"));
|
|
19
|
+
let CacheService = CacheService_1 = class CacheService {
|
|
20
|
+
constructor(options) {
|
|
21
|
+
this.logger = new common_1.Logger(CacheService_1.name);
|
|
22
|
+
this.cache = new node_cache_1.default({
|
|
23
|
+
stdTTL: options?.stdTTL || 600,
|
|
24
|
+
checkperiod: options?.checkperiod || 120,
|
|
25
|
+
useClones: options?.useClones ?? true,
|
|
26
|
+
});
|
|
27
|
+
this.cache.on('set', (key) => {
|
|
28
|
+
this.logger.debug(`Cache set: ${key}`);
|
|
29
|
+
});
|
|
30
|
+
this.cache.on('del', (key) => {
|
|
31
|
+
this.logger.debug(`Cache deleted: ${key}`);
|
|
32
|
+
});
|
|
33
|
+
this.cache.on('expired', (key) => {
|
|
34
|
+
this.logger.debug(`Cache expired: ${key}`);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
get(key) {
|
|
38
|
+
return this.cache.get(key);
|
|
39
|
+
}
|
|
40
|
+
set(key, value, ttl) {
|
|
41
|
+
if (ttl) {
|
|
42
|
+
return this.cache.set(key, value, ttl);
|
|
43
|
+
}
|
|
44
|
+
return this.cache.set(key, value);
|
|
45
|
+
}
|
|
46
|
+
del(key) {
|
|
47
|
+
return this.cache.del(key);
|
|
48
|
+
}
|
|
49
|
+
has(key) {
|
|
50
|
+
return this.cache.has(key);
|
|
51
|
+
}
|
|
52
|
+
flush() {
|
|
53
|
+
this.cache.flushAll();
|
|
54
|
+
this.logger.log('Cache flushed');
|
|
55
|
+
}
|
|
56
|
+
getStats() {
|
|
57
|
+
return this.cache.getStats();
|
|
58
|
+
}
|
|
59
|
+
keys() {
|
|
60
|
+
return this.cache.keys();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
exports.CacheService = CacheService;
|
|
64
|
+
exports.CacheService = CacheService = CacheService_1 = __decorate([
|
|
65
|
+
(0, common_1.Injectable)(),
|
|
66
|
+
__metadata("design:paramtypes", [Object])
|
|
67
|
+
], CacheService);
|
|
68
|
+
//# sourceMappingURL=cache.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.service.js","sourceRoot":"","sources":["../../src/cache/cache.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,4DAAmC;AAS5B,IAAM,YAAY,oBAAlB,MAAM,YAAY;IAIvB,YAAY,OAAsB;QAHjB,WAAM,GAAG,IAAI,eAAM,CAAC,cAAY,CAAC,IAAI,CAAC,CAAC;QAItD,IAAI,CAAC,KAAK,GAAG,IAAI,oBAAS,CAAC;YACzB,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG;YAC9B,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,GAAG;YACxC,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,IAAI;SACtC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;YAC3B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;YAC3B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;YAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAI,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAI,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,GAAG,CAAI,GAAW,EAAE,KAAQ,EAAE,GAAY;QACxC,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF,CAAA;AAvDY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;;GACA,YAAY,CAuDxB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AxiosRequestConfig } from 'axios';
|
|
2
|
+
export interface RetryOptions {
|
|
3
|
+
retries?: number;
|
|
4
|
+
delay?: number;
|
|
5
|
+
retryCondition?: (error: unknown) => boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface HttpClientConfig extends AxiosRequestConfig {
|
|
8
|
+
retry?: RetryOptions;
|
|
9
|
+
}
|
|
10
|
+
export interface RestApiConfig {
|
|
11
|
+
key: string;
|
|
12
|
+
baseURL: string;
|
|
13
|
+
config?: AxiosRequestConfig;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.interface.js","sourceRoot":"","sources":["../../src/client/client.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
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.HttpClientModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const http_client_service_1 = require("../client/http-client.service");
|
|
12
|
+
let HttpClientModule = class HttpClientModule {
|
|
13
|
+
};
|
|
14
|
+
exports.HttpClientModule = HttpClientModule;
|
|
15
|
+
exports.HttpClientModule = HttpClientModule = __decorate([
|
|
16
|
+
(0, common_1.Global)(),
|
|
17
|
+
(0, common_1.Module)({
|
|
18
|
+
providers: [http_client_service_1.HttpClientService],
|
|
19
|
+
exports: [http_client_service_1.HttpClientService],
|
|
20
|
+
})
|
|
21
|
+
], HttpClientModule);
|
|
22
|
+
//# sourceMappingURL=http-client.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.module.js","sourceRoot":"","sources":["../../src/client/http-client.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAgD;AAChD,sEAAiE;AAO1D,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;CAAG,CAAA;AAAnB,4CAAgB;2BAAhB,gBAAgB;IAL5B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,CAAC,uCAAiB,CAAC;QAC9B,OAAO,EAAE,CAAC,uCAAiB,CAAC;KAC7B,CAAC;GACW,gBAAgB,CAAG"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
2
|
+
import { HttpClientConfig } from '../client/client.interface';
|
|
3
|
+
export declare class HttpClientService {
|
|
4
|
+
private readonly logger;
|
|
5
|
+
private readonly clients;
|
|
6
|
+
createClient(name: string, config: AxiosRequestConfig): AxiosInstance;
|
|
7
|
+
getClient(name: string): AxiosInstance;
|
|
8
|
+
request<T = unknown>(config: HttpClientConfig): Promise<T>;
|
|
9
|
+
withRetry<T>(promise: Promise<T>, delay?: number, retries?: number): Promise<T>;
|
|
10
|
+
private defaultRetryCondition;
|
|
11
|
+
private sleep;
|
|
12
|
+
}
|