@nest-omni/core 1.0.49 → 1.0.51

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.
@@ -12,6 +12,7 @@ const typeorm_1 = require("typeorm");
12
12
  const nestjs_i18n_1 = require("nestjs-i18n");
13
13
  let HttpExceptionFilter = class HttpExceptionFilter {
14
14
  catch(exception, host) {
15
+ var _a, _b, _c, _d;
15
16
  const i18n = nestjs_i18n_1.I18nContext.current(host);
16
17
  const ctx = host.switchToHttp();
17
18
  const response = ctx.getResponse();
@@ -25,7 +26,17 @@ let HttpExceptionFilter = class HttpExceptionFilter {
25
26
  error = 'Entity not found';
26
27
  }
27
28
  if (statusCode === 500) {
28
- console.error(exception);
29
+ console.error({
30
+ message: exception.message,
31
+ stack: exception.stack,
32
+ connection: {
33
+ localAddress: (_a = request.socket) === null || _a === void 0 ? void 0 : _a.localAddress,
34
+ remoteAddress: (_b = request.socket) === null || _b === void 0 ? void 0 : _b.remoteAddress,
35
+ bytesRead: (_c = request.socket) === null || _c === void 0 ? void 0 : _c.bytesRead,
36
+ bytesWritten: (_d = request.socket) === null || _d === void 0 ? void 0 : _d.bytesWritten,
37
+ },
38
+ headers: request.headers,
39
+ });
29
40
  }
30
41
  const getFirstError = (error, property = '') => {
31
42
  var _a;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nest-omni/core",
3
- "version": "1.0.49",
3
+ "version": "1.0.51",
4
4
  "description": "framework",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -23,61 +23,120 @@ const nestjs_sentry_1 = require("@ntegral/nestjs-sentry");
23
23
  const nestjs_i18n_1 = require("nestjs-i18n");
24
24
  const crud_1 = require("@dataui/crud");
25
25
  const nestjs_cls_1 = require("nestjs-cls");
26
- crud_1.CrudConfigService.load({
27
- auth: {
28
- property: 'user',
29
- },
30
- params: {
31
- id: {
32
- field: 'id',
33
- type: 'string',
34
- primary: true,
26
+ const configureCrud = () => {
27
+ crud_1.CrudConfigService.load({
28
+ auth: {
29
+ property: 'user',
35
30
  },
36
- },
37
- query: {
38
- limit: 10,
39
- alwaysPaginate: true,
40
- },
41
- routes: {
42
- updateOneBase: {
43
- allowParamsOverride: false,
31
+ params: {
32
+ id: {
33
+ field: 'id',
34
+ type: 'string',
35
+ primary: true,
36
+ },
44
37
  },
45
- deleteOneBase: {
46
- returnDeleted: false,
38
+ query: {
39
+ limit: 10,
40
+ alwaysPaginate: true,
47
41
  },
48
- createOneBase: {
49
- returnShallow: false,
42
+ routes: {
43
+ updateOneBase: {
44
+ allowParamsOverride: false,
45
+ },
46
+ deleteOneBase: {
47
+ returnDeleted: false,
48
+ },
49
+ createOneBase: {
50
+ returnShallow: false,
51
+ },
50
52
  },
51
- },
52
- });
53
+ });
54
+ };
55
+ const setupProcessHandlers = (app) => {
56
+ const logger = app.get(nestjs_pino_1.Logger);
57
+ process.on('uncaughtException', (error) => {
58
+ logger.fatal({ error, stack: error.stack, pid: process.pid }, 'Uncaught Exception');
59
+ process.exit(1);
60
+ });
61
+ process.on('unhandledRejection', (reason, promise) => {
62
+ logger.error({
63
+ reason: {
64
+ message: reason.message,
65
+ stack: reason.stack,
66
+ name: reason.name,
67
+ },
68
+ promise,
69
+ pid: process.pid,
70
+ }, 'Unhandled Rejection');
71
+ });
72
+ process.on('exit', (code) => {
73
+ logger.warn(`Process exiting with code ${code}`, {
74
+ uptime: process.uptime(),
75
+ memoryUsage: process.memoryUsage(),
76
+ });
77
+ });
78
+ };
79
+ const setupGracefulShutdown = (app) => {
80
+ const logger = app.get(nestjs_pino_1.Logger);
81
+ const shutdown = (signal) => __awaiter(void 0, void 0, void 0, function* () {
82
+ var _a;
83
+ try {
84
+ logger.warn(`Received ${signal}, starting graceful shutdown...`, {
85
+ uptime: process.uptime(),
86
+ connections: (_a = app.getHttpServer()) === null || _a === void 0 ? void 0 : _a.address(),
87
+ });
88
+ yield Promise.race([
89
+ app.close(),
90
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Shutdown timeout exceeded')), 15000)),
91
+ ]);
92
+ logger.log('Application successfully closed', {
93
+ resourcesReleased: true,
94
+ pid: process.pid,
95
+ });
96
+ process.exit(0);
97
+ }
98
+ catch (err) {
99
+ logger.error('Graceful shutdown failed', {
100
+ error: {
101
+ message: err.message,
102
+ stack: err.stack,
103
+ name: err.name,
104
+ },
105
+ critical: true,
106
+ pid: process.pid,
107
+ });
108
+ process.exit(1);
109
+ }
110
+ });
111
+ process.on('SIGQUIT', () => shutdown('SIGQUIT'));
112
+ process.on('SIGHUP', () => shutdown('SIGHUP'));
113
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
114
+ process.on('SIGINT', () => shutdown('SIGINT'));
115
+ };
53
116
  function bootstrapSetup(AppModule, SetupSwagger) {
54
117
  return __awaiter(this, void 0, void 0, function* () {
55
118
  (0, typeorm_transactional_1.initializeTransactionalContext)();
119
+ configureCrud();
56
120
  const app = yield core_1.NestFactory.create(AppModule, {
57
121
  bufferLogs: true,
58
122
  });
59
123
  const configService = app.select(__1.ServiceRegistryModule).get(__1.ApiConfigService);
60
- app.useLogger(app.get(nestjs_pino_1.Logger));
61
- app.flushLogs();
124
+ const logger = app.get(nestjs_pino_1.Logger);
125
+ setupProcessHandlers(app);
62
126
  app.enableShutdownHooks();
127
+ setupGracefulShutdown(app);
63
128
  app.enableVersioning();
64
129
  app.enable('trust proxy');
130
+ app.use(bodyParse.json({ limit: '50mb' }), new nestjs_cls_1.ClsMiddleware({}).use, (0, __1.RequestIdMiddleware)(), (0, __1.PowerByMiddleware)(), (0, __1.OmniAuthMiddleware)());
65
131
  const reflector = app.get(core_1.Reflector);
66
132
  app.useGlobalFilters(new __1.HttpExceptionFilter(), new __1.QueryFailedFilter(reflector));
67
- app.use(bodyParse.json({
68
- limit: '50mb',
69
- }), new nestjs_cls_1.ClsMiddleware({}).use, (0, __1.RequestIdMiddleware)(), (0, __1.PowerByMiddleware)(), (0, __1.OmniAuthMiddleware)());
70
- app.useStaticAssets('public', { prefix: '/' });
71
133
  app.useGlobalInterceptors(new __1.LanguageInterceptor(), new __1.TranslationInterceptor(), new nestjs_pino_1.LoggerErrorInterceptor(), new nestjs_sentry_1.SentryInterceptor({
72
134
  filters: [
73
135
  {
74
136
  type: common_1.HttpException,
75
137
  filter: (exception) => {
76
138
  const status = exception.getStatus();
77
- if (status === 401 || status === 404) {
78
- return true;
79
- }
80
- return 200 > status;
139
+ return status === 401 || status === 404 || 200 > status;
81
140
  },
82
141
  },
83
142
  ],
@@ -91,23 +150,28 @@ function bootstrapSetup(AppModule, SetupSwagger) {
91
150
  }));
92
151
  if (configService.skywalkingEnabled) {
93
152
  skywalking_backend_js_1.default.start();
153
+ logger.log('SkyWalking agent initialized');
94
154
  }
95
155
  if (configService.documentationEnabled && SetupSwagger) {
96
156
  SetupSwagger(app, configService.documentationPath);
157
+ logger.log(`Swagger docs available at ${configService.documentationPath}`);
97
158
  }
98
159
  if (configService.viewsEnabled) {
99
160
  app.setBaseViewsDir((0, path_1.join)(__1.ApiConfigService.rootPath, 'views'));
100
161
  app.setViewEngine('ejs');
162
+ logger.log('View engine initialized');
101
163
  }
102
164
  if (configService.sessionEnabled) {
103
165
  app.use(session(configService.sessionConfig));
166
+ logger.log('Session middleware enabled');
104
167
  }
105
168
  if (configService.corsEnabled) {
106
169
  app.enableCors(configService.corsConfig);
170
+ logger.log('CORS configuration applied');
107
171
  }
108
172
  const port = configService.appConfig.port;
109
173
  yield app.listen(port);
110
- console.info(`server running on ${yield app.getUrl()}`);
174
+ logger.log(`Server running on ${yield app.getUrl()}`);
111
175
  return app;
112
176
  });
113
177
  }
@@ -228,8 +228,29 @@ let ApiConfigService = ApiConfigService_1 = class ApiConfigService {
228
228
  }
229
229
  get bullConfig() {
230
230
  return {
231
- redis: this.ioRedisConfig,
231
+ redis: Object.assign(Object.assign({}, this.ioRedisConfig), { retryStrategy: (times) => Math.min(times * 1000, 5000) }),
232
232
  prefix: this.getString('BULL_PREFIX'),
233
+ defaultJobOptions: {
234
+ removeOnComplete: this.getNumber('BULL_REMOVE_COMPLETED_DAYS') * 24 * 3600 ||
235
+ 7 * 24 * 3600,
236
+ removeOnFail: this.getNumber('BULL_REMOVE_FAILED_DAYS') * 24 * 3600 ||
237
+ 30 * 24 * 3600,
238
+ attempts: this.getNumber('BULL_JOB_ATTEMPTS') || 5,
239
+ backoff: {
240
+ type: 'exponential',
241
+ delay: this.getNumber('BULL_JOB_BACKOFF_DELAY_MS') || 5000,
242
+ },
243
+ timeout: this.getNumber('BULL_JOB_TIMEOUT_MS') || 30 * 1000,
244
+ },
245
+ settings: {
246
+ maxStalledCount: 2,
247
+ guardInterval: 5000,
248
+ retryProcessDelay: 1000,
249
+ },
250
+ limiter: {
251
+ max: this.getNumber('BULL_MAX_CONCURRENT_JOBS') || 100,
252
+ duration: 1000,
253
+ },
233
254
  };
234
255
  }
235
256
  cacheConfig() {