@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(
|
|
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
package/setup/bootstrap.setup.js
CHANGED
|
@@ -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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
updateOneBase: {
|
|
43
|
-
allowParamsOverride: false,
|
|
31
|
+
params: {
|
|
32
|
+
id: {
|
|
33
|
+
field: 'id',
|
|
34
|
+
type: 'string',
|
|
35
|
+
primary: true,
|
|
36
|
+
},
|
|
44
37
|
},
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
query: {
|
|
39
|
+
limit: 10,
|
|
40
|
+
alwaysPaginate: true,
|
|
47
41
|
},
|
|
48
|
-
|
|
49
|
-
|
|
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.
|
|
61
|
-
app
|
|
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
|
-
|
|
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
|
-
|
|
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() {
|