@tmlmobilidade/fastify 20260617.1318.33 → 20260617.1703.12
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.
|
@@ -52,8 +52,9 @@ export function authorizationMiddleware(scope, actions, requireAll = false) {
|
|
|
52
52
|
const isAllowed = requireAll
|
|
53
53
|
? permissionChecks.every(Boolean) // all must be true
|
|
54
54
|
: permissionChecks.some(Boolean); // at least one must be true
|
|
55
|
-
if (!isAllowed)
|
|
55
|
+
if (!isAllowed) {
|
|
56
56
|
throw new HttpException(HTTP_STATUS.FORBIDDEN, `Insufficient permissions | User: ${request.me._id} | Scope: "${scope}" | Actions: [${actions.join(',')}]`);
|
|
57
|
+
}
|
|
57
58
|
//
|
|
58
59
|
};
|
|
59
60
|
}
|
|
@@ -21,6 +21,11 @@ export interface FastifyServiceOptions extends FastifyServerOptions {
|
|
|
21
21
|
* @default '0.0.0.0'
|
|
22
22
|
*/
|
|
23
23
|
host?: string;
|
|
24
|
+
/**
|
|
25
|
+
* The module name for the Fastify server.
|
|
26
|
+
* @default 'fastify'
|
|
27
|
+
*/
|
|
28
|
+
module?: string;
|
|
24
29
|
/**
|
|
25
30
|
* The origin for CORS requests.
|
|
26
31
|
* Defaults to `true` if not provided.
|
|
@@ -61,7 +66,7 @@ export declare class FastifyService {
|
|
|
61
66
|
* @return A promise that resolves to the URL of the Fastify server.
|
|
62
67
|
* @throws Will throw an error if the server fails to start.
|
|
63
68
|
*/
|
|
64
|
-
start(): Promise<string>;
|
|
69
|
+
start(moduleName?: string): Promise<string>;
|
|
65
70
|
/**
|
|
66
71
|
* Stops the Fastify server.
|
|
67
72
|
* @return A promise that resolves when the server is stopped.
|
package/dist/fastify-service.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
1
2
|
/* * */
|
|
2
3
|
import '@fastify/cors';
|
|
3
4
|
import '@fastify/cookie';
|
|
@@ -7,24 +8,29 @@ import fastifyCookie from '@fastify/cookie';
|
|
|
7
8
|
import fastifyCors from '@fastify/cors';
|
|
8
9
|
import oneLineLogger from '@fastify/one-line-logger';
|
|
9
10
|
import { HTTP_STATUS, HttpException } from '@tmlmobilidade/consts';
|
|
11
|
+
import { Logger } from '@tmlmobilidade/logger';
|
|
12
|
+
import { initSentryNode } from '@tmlmobilidade/logger';
|
|
10
13
|
import fastify from 'fastify';
|
|
11
14
|
const defaultFastifyServiceOptions = {
|
|
12
15
|
bodyLimit: 1024 * 1024 * 10, // 10MB
|
|
13
16
|
host: '0.0.0.0',
|
|
14
17
|
logger: true,
|
|
18
|
+
module: 'fastify',
|
|
15
19
|
origin: true,
|
|
16
20
|
port: 5050,
|
|
17
21
|
routerOptions: {
|
|
18
22
|
ignoreTrailingSlash: true,
|
|
19
23
|
},
|
|
20
24
|
};
|
|
21
|
-
const
|
|
25
|
+
const createLoggerOptions = (getModuleName) => ({
|
|
22
26
|
level: 'debug',
|
|
27
|
+
module: getModuleName(),
|
|
23
28
|
stream: oneLineLogger({
|
|
24
29
|
colorize: true, // nice colors,
|
|
25
30
|
colorizeObjects: true,
|
|
26
31
|
messageFormat(log, messageKey, _, extras) {
|
|
27
32
|
const c = extras.colors;
|
|
33
|
+
const moduleName = getModuleName();
|
|
28
34
|
const palette = {
|
|
29
35
|
error: c.redBright,
|
|
30
36
|
highlight: c.yellowBright, // URLs / routes
|
|
@@ -96,10 +102,24 @@ const loggerOptions = {
|
|
|
96
102
|
palette.pathLabel(`Path: ${palette.path(path)}`),
|
|
97
103
|
message,
|
|
98
104
|
];
|
|
99
|
-
|
|
105
|
+
const logMessage = palette.pipe(parts.join(' | ')) + stackTrace;
|
|
106
|
+
const shouldSendToSentry = message !== 'incoming request' && message !== 'request completed';
|
|
107
|
+
if (shouldSendToSentry) {
|
|
108
|
+
Logger.startNodeLogs({
|
|
109
|
+
app: 'api',
|
|
110
|
+
message: message,
|
|
111
|
+
method: method,
|
|
112
|
+
module: moduleName,
|
|
113
|
+
path: path,
|
|
114
|
+
reqId: reqId,
|
|
115
|
+
severity: 'info',
|
|
116
|
+
status: statusCode,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return logMessage;
|
|
100
120
|
},
|
|
101
121
|
}),
|
|
102
|
-
};
|
|
122
|
+
});
|
|
103
123
|
/**
|
|
104
124
|
* FastifyService is a singleton class that provides a Fastify server instance.
|
|
105
125
|
* It allows for setting up routes, plugins, and starting/stopping the server.
|
|
@@ -117,8 +137,8 @@ export class FastifyService {
|
|
|
117
137
|
*/
|
|
118
138
|
constructor(options) {
|
|
119
139
|
const mergedOptions = { ...defaultFastifyServiceOptions, ...options };
|
|
120
|
-
this.server = fastify({ ...mergedOptions, logger: loggerOptions });
|
|
121
140
|
this.options = mergedOptions;
|
|
141
|
+
this.server = fastify({ ...mergedOptions, logger: createLoggerOptions(() => this.options.module ?? 'fastify') });
|
|
122
142
|
this._setupDefaultRoutes();
|
|
123
143
|
this._setupPlugins();
|
|
124
144
|
}
|
|
@@ -141,16 +161,25 @@ export class FastifyService {
|
|
|
141
161
|
* @return A promise that resolves to the URL of the Fastify server.
|
|
142
162
|
* @throws Will throw an error if the server fails to start.
|
|
143
163
|
*/
|
|
144
|
-
async start() {
|
|
164
|
+
async start(moduleName) {
|
|
165
|
+
if (moduleName)
|
|
166
|
+
this.options.module = moduleName;
|
|
167
|
+
try {
|
|
168
|
+
await initSentryNode();
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
this.server.log.error({ err: error }, 'Error sending startup log to Sentry.');
|
|
172
|
+
}
|
|
145
173
|
try {
|
|
146
|
-
const serverUrl = await this.server.listen({
|
|
174
|
+
const serverUrl = await this.server.listen({
|
|
175
|
+
host: this.options.host,
|
|
176
|
+
port: this.options.port,
|
|
177
|
+
});
|
|
147
178
|
this.server.log.info(`Server is running at ${serverUrl}`);
|
|
148
|
-
this.server.log.info(`CORS enabled for origin: ${this.options.origin}`);
|
|
149
|
-
this.server.log.info(`Listening on ${this.options.host}:${this.options.port}`);
|
|
150
179
|
return serverUrl;
|
|
151
180
|
}
|
|
152
181
|
catch (error) {
|
|
153
|
-
this.server.log.error({ error,
|
|
182
|
+
this.server.log.error({ err: error }, 'Error starting server.');
|
|
154
183
|
process.exit(1);
|
|
155
184
|
}
|
|
156
185
|
}
|
|
@@ -190,12 +219,15 @@ export class FastifyService {
|
|
|
190
219
|
* If so, it sends a response with the appropriate status code and error message.
|
|
191
220
|
* This ensures consistent error responses for HTTP exceptions throughout the application.
|
|
192
221
|
*/
|
|
193
|
-
this.server.setErrorHandler((error,
|
|
222
|
+
this.server.setErrorHandler((error, request, reply) => {
|
|
194
223
|
// Log the error with full stack trace
|
|
195
224
|
const errorMessage = error instanceof Error ? error.message : 'Unhandled error';
|
|
196
225
|
this.server.log.error({ err: error }, errorMessage);
|
|
197
226
|
// Handle HttpException errors
|
|
198
227
|
if (error instanceof HttpException) {
|
|
228
|
+
if (error.statusCode === HTTP_STATUS.INTERNAL_SERVER_ERROR) {
|
|
229
|
+
Logger.issue({ context: { action: 'errorHandler', feature: this.options.module, request, value: request.body }, level: 'error', messageOrError: error });
|
|
230
|
+
}
|
|
199
231
|
reply
|
|
200
232
|
.status(error.statusCode)
|
|
201
233
|
.send({
|
|
@@ -205,6 +237,7 @@ export class FastifyService {
|
|
|
205
237
|
});
|
|
206
238
|
}
|
|
207
239
|
else {
|
|
240
|
+
Logger.issue({ context: { action: 'errorHandler', feature: this.options.module, request, value: request.body }, level: 'error', messageOrError: 'Internal server error' });
|
|
208
241
|
reply
|
|
209
242
|
.status(HTTP_STATUS.INTERNAL_SERVER_ERROR)
|
|
210
243
|
.send({
|
|
@@ -228,8 +261,7 @@ export class FastifyService {
|
|
|
228
261
|
const payloadJson = JSON.parse(payload);
|
|
229
262
|
reply.code(payloadJson.statusCode ?? HTTP_STATUS.OK);
|
|
230
263
|
}
|
|
231
|
-
|
|
232
|
-
catch (error) {
|
|
264
|
+
catch {
|
|
233
265
|
// Do nothing
|
|
234
266
|
}
|
|
235
267
|
finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tmlmobilidade/fastify",
|
|
3
|
-
"version": "20260617.
|
|
3
|
+
"version": "20260617.1703.12",
|
|
4
4
|
"author": {
|
|
5
5
|
"email": "iso@tmlmobilidade.pt",
|
|
6
6
|
"name": "TML-ISO"
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"@fastify/one-line-logger": "^2.1.0",
|
|
43
43
|
"@tmlmobilidade/consts": "*",
|
|
44
44
|
"@tmlmobilidade/interfaces": "*",
|
|
45
|
+
"@tmlmobilidade/logger": "*",
|
|
45
46
|
"@tmlmobilidade/utils": "*",
|
|
46
47
|
"fastify": "5.8.5"
|
|
47
48
|
},
|