@tmlmobilidade/fastify 20251202.1817.5
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/dist/authorization-middleware.d.ts +17 -0
- package/dist/authorization-middleware.js +59 -0
- package/dist/fastify-service.d.ts +84 -0
- package/dist/fastify-service.js +251 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/package.json +58 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FastifyReply, type FastifyRequest } from './fastify-service.js';
|
|
2
|
+
import { type ActionsOf, type Organization, type Permission, type User } from '@tmlmobilidade/types';
|
|
3
|
+
declare module 'fastify' {
|
|
4
|
+
interface FastifyRequest {
|
|
5
|
+
me: User;
|
|
6
|
+
organization: Organization;
|
|
7
|
+
permissions: Permission[];
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Creates an authorization middleware that validates user authentication and permissions.
|
|
12
|
+
* @param scope The permission scope to check (optional).
|
|
13
|
+
* @param action The permission action(s) to check (optional).
|
|
14
|
+
* @param requireAll Whether all actions must be true or at least one must be true.
|
|
15
|
+
* @returns Fastify middleware function.
|
|
16
|
+
*/
|
|
17
|
+
export declare function authorizationMiddleware<S extends Permission['scope']>(scope?: S, actions?: ActionsOf<S>[], requireAll?: boolean): (request: FastifyRequest, reply: FastifyReply<string>) => Promise<void>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import { HttpException, HttpStatus } from '@tmlmobilidade/consts';
|
|
3
|
+
import { AUTH_SESSION_COOKIE_NAME, authProvider } from '@tmlmobilidade/interfaces';
|
|
4
|
+
import { PermissionCatalog } from '@tmlmobilidade/types';
|
|
5
|
+
/**
|
|
6
|
+
* Creates an authorization middleware that validates user authentication and permissions.
|
|
7
|
+
* @param scope The permission scope to check (optional).
|
|
8
|
+
* @param action The permission action(s) to check (optional).
|
|
9
|
+
* @param requireAll Whether all actions must be true or at least one must be true.
|
|
10
|
+
* @returns Fastify middleware function.
|
|
11
|
+
*/
|
|
12
|
+
export function authorizationMiddleware(scope, actions, requireAll = false) {
|
|
13
|
+
return async (request, reply) => {
|
|
14
|
+
//
|
|
15
|
+
//
|
|
16
|
+
// Extract the session token from request cookies
|
|
17
|
+
const sessionToken = request.cookies.session_token;
|
|
18
|
+
if (!sessionToken) {
|
|
19
|
+
return reply
|
|
20
|
+
.setCookie(AUTH_SESSION_COOKIE_NAME, '', { httpOnly: true, maxAge: 0, path: '/', sameSite: 'lax', secure: true })
|
|
21
|
+
.send({ data: 'Session token is missing', error: null, statusCode: HttpStatus.UNAUTHORIZED });
|
|
22
|
+
}
|
|
23
|
+
//
|
|
24
|
+
// Get user and permissions from cache or auth provider.
|
|
25
|
+
// Cache is per session token, and valid for 5 minutes.
|
|
26
|
+
// This reduces the number of calls to the auth provider.
|
|
27
|
+
try {
|
|
28
|
+
const userData = await authProvider.getUserFromSessionToken(sessionToken);
|
|
29
|
+
const permissionsData = await authProvider.getPermissionsFromSessionToken(sessionToken);
|
|
30
|
+
const organizationData = await authProvider.getOrganizationFromSessionToken(sessionToken);
|
|
31
|
+
if (!userData || !permissionsData || !organizationData) {
|
|
32
|
+
return reply
|
|
33
|
+
.setCookie(AUTH_SESSION_COOKIE_NAME, '', { httpOnly: true, maxAge: 0, path: '/', sameSite: 'lax', secure: true })
|
|
34
|
+
.send({ data: 'Session token is missing', error: null, statusCode: HttpStatus.UNAUTHORIZED });
|
|
35
|
+
}
|
|
36
|
+
request.me = userData;
|
|
37
|
+
request.permissions = permissionsData;
|
|
38
|
+
request.organization = organizationData;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error('Authorization Middleware Error:', error);
|
|
42
|
+
return reply
|
|
43
|
+
.setCookie(AUTH_SESSION_COOKIE_NAME, '', { httpOnly: true, maxAge: 0, path: '/', sameSite: 'lax', secure: true })
|
|
44
|
+
.send({ data: 'Session token is missing', error: null, statusCode: HttpStatus.UNAUTHORIZED });
|
|
45
|
+
}
|
|
46
|
+
//
|
|
47
|
+
// Evaluate the retrieved permissions,
|
|
48
|
+
// if scope and actions are provided.
|
|
49
|
+
if (!scope)
|
|
50
|
+
return;
|
|
51
|
+
const permissionChecks = actions.map(action => PermissionCatalog.hasPermission(request.permissions, scope, action));
|
|
52
|
+
const isAllowed = requireAll
|
|
53
|
+
? permissionChecks.every(Boolean) // all must be true
|
|
54
|
+
: permissionChecks.some(Boolean); // at least one must be true
|
|
55
|
+
if (!isAllowed)
|
|
56
|
+
throw new HttpException(HttpStatus.FORBIDDEN, `Insufficient permissions | User: ${request.me._id} | Scope: "${scope}" | Actions: [${actions.join(',')}]`);
|
|
57
|
+
//
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import '@fastify/cors';
|
|
2
|
+
import '@fastify/cookie';
|
|
3
|
+
import '@fastify/multipart';
|
|
4
|
+
import { HttpResponse, WithPagination } from '@tmlmobilidade/utils';
|
|
5
|
+
import { type FastifyInstance as FastifyInstanceType, type FastifyReply as FastifyReplyType } from 'fastify';
|
|
6
|
+
import { type ContextConfigDefault, type FastifyBaseLogger, type FastifySchema, type FastifyServerOptions, type FastifyTypeProviderDefault, type RawReplyDefaultExpression, type RawRequestDefaultExpression, type RawServerBase, type RawServerDefault, type RouteGenericInterface } from 'fastify';
|
|
7
|
+
export { type FastifyRequest } from 'fastify';
|
|
8
|
+
export type FastifyReply<T> = FastifyReplyType<RouteGenericInterface, RawServerBase, RawRequestDefaultExpression<RawServerBase>, RawReplyDefaultExpression<RawServerBase>, ContextConfigDefault, FastifySchema, FastifyTypeProviderDefault, HttpResponse<T> | ReadableStream | WithPagination<HttpResponse<T>>>;
|
|
9
|
+
export type FastifyResponse<T> = FastifyReplyType<RouteGenericInterface & {
|
|
10
|
+
Reply: HttpResponse<T> | WithPagination<HttpResponse<T>>;
|
|
11
|
+
}, RawServerBase, RawRequestDefaultExpression<RawServerBase>, RawReplyDefaultExpression<RawServerBase>, ContextConfigDefault, FastifySchema, FastifyTypeProviderDefault, HttpResponse<T> | WithPagination<HttpResponse<T>>>;
|
|
12
|
+
export type FastifyInstance = FastifyInstanceType<RawServerDefault, RawRequestDefaultExpression, RawReplyDefaultExpression, FastifyBaseLogger, FastifyTypeProviderDefault>;
|
|
13
|
+
/**
|
|
14
|
+
* FastifyServiceOptions interface defines the options for the Fastify server.
|
|
15
|
+
* It extends FastifyServerOptions and adds optional properties for origin and port.
|
|
16
|
+
*/
|
|
17
|
+
export interface FastifyServiceOptions extends FastifyServerOptions {
|
|
18
|
+
/**
|
|
19
|
+
* The host on which the Fastify server will listen.
|
|
20
|
+
* If not provided, it defaults to '0.0.0.0'.
|
|
21
|
+
* @default '0.0.0.0'
|
|
22
|
+
*/
|
|
23
|
+
host?: string;
|
|
24
|
+
/**
|
|
25
|
+
* The origin for CORS requests.
|
|
26
|
+
* Defaults to `true` if not provided.
|
|
27
|
+
* @default true
|
|
28
|
+
* @example 'https://example.com'
|
|
29
|
+
*/
|
|
30
|
+
origin?: RegExp | string | true;
|
|
31
|
+
/**
|
|
32
|
+
* The port on which the Fastify server will listen.
|
|
33
|
+
* If not provided, it defaults to 5050.
|
|
34
|
+
* @default 5050
|
|
35
|
+
*/
|
|
36
|
+
port?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* FastifyService is a singleton class that provides a Fastify server instance.
|
|
40
|
+
* It allows for setting up routes, plugins, and starting/stopping the server.
|
|
41
|
+
* This class is designed to be used as a service in a Node.js application.
|
|
42
|
+
* It uses the Fastify framework for building web applications and APIs.
|
|
43
|
+
*/
|
|
44
|
+
export declare class FastifyService {
|
|
45
|
+
private static _instance;
|
|
46
|
+
readonly server: FastifyInstance;
|
|
47
|
+
private readonly options;
|
|
48
|
+
/**
|
|
49
|
+
* Creates an instance of FastifyService.
|
|
50
|
+
* @param options The options for the Fastify server.
|
|
51
|
+
*/
|
|
52
|
+
private constructor();
|
|
53
|
+
/**
|
|
54
|
+
* Gets the singleton instance of FastifyService.
|
|
55
|
+
* @param options The options for the Fastify server.
|
|
56
|
+
* @return The singleton instance of FastifyService.
|
|
57
|
+
*/
|
|
58
|
+
static getInstance(options?: FastifyServiceOptions): FastifyService;
|
|
59
|
+
/**
|
|
60
|
+
* Starts the Fastify server.
|
|
61
|
+
* @return A promise that resolves to the URL of the Fastify server.
|
|
62
|
+
* @throws Will throw an error if the server fails to start.
|
|
63
|
+
*/
|
|
64
|
+
start(): Promise<string>;
|
|
65
|
+
/**
|
|
66
|
+
* Stops the Fastify server.
|
|
67
|
+
* @return A promise that resolves when the server is stopped.
|
|
68
|
+
*/
|
|
69
|
+
stop(): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Sets the URL of the Fastify server.
|
|
72
|
+
* @return The URL of the Fastify server.
|
|
73
|
+
*/
|
|
74
|
+
private _setupDefaultRoutes;
|
|
75
|
+
/**
|
|
76
|
+
* Sets up hooks for the Fastify server including error handling and response processing.
|
|
77
|
+
*/
|
|
78
|
+
private _setupHooks;
|
|
79
|
+
/**
|
|
80
|
+
* Sets up the plugins for the Fastify server.
|
|
81
|
+
* @return A promise that resolves when the plugins are set up.
|
|
82
|
+
*/
|
|
83
|
+
private _setupPlugins;
|
|
84
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
import '@fastify/cors';
|
|
3
|
+
import '@fastify/cookie';
|
|
4
|
+
import '@fastify/multipart';
|
|
5
|
+
/* * */
|
|
6
|
+
import fastifyCookie from '@fastify/cookie';
|
|
7
|
+
import fastifyCors from '@fastify/cors';
|
|
8
|
+
import oneLineLogger from '@fastify/one-line-logger';
|
|
9
|
+
import { HttpException, HttpStatus } from '@tmlmobilidade/consts';
|
|
10
|
+
import fastify from 'fastify';
|
|
11
|
+
const defaultFastifyServiceOptions = {
|
|
12
|
+
bodyLimit: 1024 * 1024 * 10, // 10MB
|
|
13
|
+
host: '0.0.0.0',
|
|
14
|
+
logger: true,
|
|
15
|
+
origin: true,
|
|
16
|
+
port: 5050,
|
|
17
|
+
routerOptions: {
|
|
18
|
+
ignoreTrailingSlash: true,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
const loggerOptions = {
|
|
22
|
+
level: 'debug',
|
|
23
|
+
stream: oneLineLogger({
|
|
24
|
+
colorize: true, // nice colors,
|
|
25
|
+
colorizeObjects: true,
|
|
26
|
+
messageFormat(log, messageKey, _, extras) {
|
|
27
|
+
const c = extras.colors;
|
|
28
|
+
const palette = {
|
|
29
|
+
error: c.redBright,
|
|
30
|
+
highlight: c.yellowBright, // URLs / routes
|
|
31
|
+
message: c.whiteBright,
|
|
32
|
+
method: c.greenBright,
|
|
33
|
+
methodLabel: c.gray,
|
|
34
|
+
pipe: c.cyanBright,
|
|
35
|
+
reqId: c.cyanBright,
|
|
36
|
+
reqIdLabel: c.gray,
|
|
37
|
+
stack: c.red,
|
|
38
|
+
status: c.yellowBright,
|
|
39
|
+
statusLabel: c.gray,
|
|
40
|
+
timestamp: c.cyanBright,
|
|
41
|
+
};
|
|
42
|
+
const colorize = (text) => {
|
|
43
|
+
const urlPattern = /(https?:\/\/[^\s]+)/g;
|
|
44
|
+
const routePattern = /Route "(.+?)"/g;
|
|
45
|
+
const pathPattern = /([A-Z]+):\/[^\s]+/g;
|
|
46
|
+
return text
|
|
47
|
+
.replace(urlPattern, palette.highlight('$&'))
|
|
48
|
+
.replace(routePattern, (_, r) => palette.highlight(`Route "${r}"`))
|
|
49
|
+
.replace(pathPattern, palette.highlight('$&'));
|
|
50
|
+
};
|
|
51
|
+
const safe = (val, fallback = '') => typeof val === 'string' || typeof val === 'number' ? String(val) : fallback;
|
|
52
|
+
const formatMethod = (method) => {
|
|
53
|
+
if (!method)
|
|
54
|
+
return '-----';
|
|
55
|
+
if (method === 'GET' || method === 'PUT')
|
|
56
|
+
return `${method} `;
|
|
57
|
+
return method.padEnd(5, '-');
|
|
58
|
+
};
|
|
59
|
+
const timestamp = new Date(log.time).toLocaleString('pt-PT', {
|
|
60
|
+
day: '2-digit',
|
|
61
|
+
hour: '2-digit',
|
|
62
|
+
minute: '2-digit',
|
|
63
|
+
month: '2-digit',
|
|
64
|
+
second: '2-digit',
|
|
65
|
+
year: 'numeric',
|
|
66
|
+
});
|
|
67
|
+
const reqId = log.reqId ? safe(log.reqId).padEnd(10, ' ') : Array(10).fill('-').join('');
|
|
68
|
+
const statusCode = typeof log.res === 'object' && log.res && 'statusCode' in log.res ? safe(log.res.statusCode).padEnd(3, '-') : '---';
|
|
69
|
+
const method = typeof log.req === 'object' && log.req && 'method' in log.req ? formatMethod(log.req.method ?? '') : '-----';
|
|
70
|
+
// Extract error information
|
|
71
|
+
// Pino serializes errors, so log.err is an object with type, message, stack, etc.
|
|
72
|
+
const errorObj = log.err || log.error;
|
|
73
|
+
let errorMessage = safe(log[messageKey]);
|
|
74
|
+
let errorStack;
|
|
75
|
+
if (errorObj) {
|
|
76
|
+
// Pino serialized error object
|
|
77
|
+
errorMessage = errorObj.message || errorMessage;
|
|
78
|
+
errorStack = errorObj.stack;
|
|
79
|
+
}
|
|
80
|
+
else if (log[messageKey] instanceof Error) {
|
|
81
|
+
// Direct Error instance (shouldn't happen with Pino, but just in case)
|
|
82
|
+
errorMessage = log[messageKey].message || errorMessage;
|
|
83
|
+
errorStack = log[messageKey].stack;
|
|
84
|
+
}
|
|
85
|
+
const message = palette.message(colorize(errorMessage));
|
|
86
|
+
// Add stack trace on new lines, indented for readability
|
|
87
|
+
const stackTrace = errorStack ? `\n${palette.stack(errorStack.split('\n').map(line => ` ${line}`).join('\n'))}` : '';
|
|
88
|
+
const parts = [
|
|
89
|
+
palette.timestamp(timestamp),
|
|
90
|
+
palette.reqIdLabel(`reqId: ${palette.reqId(reqId)}`),
|
|
91
|
+
palette.statusLabel(`statusCode: ${palette.status(statusCode)}`),
|
|
92
|
+
palette.methodLabel(`Method: ${palette.method(method)}`),
|
|
93
|
+
message,
|
|
94
|
+
];
|
|
95
|
+
return palette.pipe(parts.join(' | ')) + stackTrace;
|
|
96
|
+
},
|
|
97
|
+
}),
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* FastifyService is a singleton class that provides a Fastify server instance.
|
|
101
|
+
* It allows for setting up routes, plugins, and starting/stopping the server.
|
|
102
|
+
* This class is designed to be used as a service in a Node.js application.
|
|
103
|
+
* It uses the Fastify framework for building web applications and APIs.
|
|
104
|
+
*/
|
|
105
|
+
export class FastifyService {
|
|
106
|
+
//
|
|
107
|
+
static _instance;
|
|
108
|
+
server;
|
|
109
|
+
options;
|
|
110
|
+
/**
|
|
111
|
+
* Creates an instance of FastifyService.
|
|
112
|
+
* @param options The options for the Fastify server.
|
|
113
|
+
*/
|
|
114
|
+
constructor(options) {
|
|
115
|
+
const mergedOptions = { ...defaultFastifyServiceOptions, ...options };
|
|
116
|
+
this.server = fastify({ ...mergedOptions, logger: loggerOptions });
|
|
117
|
+
this.options = mergedOptions;
|
|
118
|
+
this._setupDefaultRoutes();
|
|
119
|
+
this._setupPlugins();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Gets the singleton instance of FastifyService.
|
|
123
|
+
* @param options The options for the Fastify server.
|
|
124
|
+
* @return The singleton instance of FastifyService.
|
|
125
|
+
*/
|
|
126
|
+
static getInstance(options) {
|
|
127
|
+
if (!FastifyService._instance) {
|
|
128
|
+
// Create a new instance if it doesn't exist yet
|
|
129
|
+
FastifyService._instance = new FastifyService(options || {});
|
|
130
|
+
FastifyService._instance._setupHooks();
|
|
131
|
+
}
|
|
132
|
+
// Return the existing instance
|
|
133
|
+
return FastifyService._instance;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Starts the Fastify server.
|
|
137
|
+
* @return A promise that resolves to the URL of the Fastify server.
|
|
138
|
+
* @throws Will throw an error if the server fails to start.
|
|
139
|
+
*/
|
|
140
|
+
async start() {
|
|
141
|
+
try {
|
|
142
|
+
const serverUrl = await this.server.listen({ host: this.options.host, port: this.options.port });
|
|
143
|
+
this.server.log.info(`Server is running at ${serverUrl}`);
|
|
144
|
+
this.server.log.info(`CORS enabled for origin: ${this.options.origin}`);
|
|
145
|
+
this.server.log.info(`Listening on ${this.options.host}:${this.options.port}`);
|
|
146
|
+
return serverUrl;
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
this.server.log.error({ error, message: 'Error starting server.' });
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Stops the Fastify server.
|
|
155
|
+
* @return A promise that resolves when the server is stopped.
|
|
156
|
+
*/
|
|
157
|
+
async stop() {
|
|
158
|
+
try {
|
|
159
|
+
await this.server.close();
|
|
160
|
+
console.log('Fastify server stopped.');
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
this.server.log.error({ err: error }, error instanceof Error ? error.message : 'Error stopping server');
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Sets the URL of the Fastify server.
|
|
169
|
+
* @return The URL of the Fastify server.
|
|
170
|
+
*/
|
|
171
|
+
_setupDefaultRoutes() {
|
|
172
|
+
this.server.get('/', (req, res) => {
|
|
173
|
+
res.send('Jusi was here!');
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Sets up hooks for the Fastify server including error handling and response processing.
|
|
178
|
+
*/
|
|
179
|
+
_setupHooks() {
|
|
180
|
+
/**
|
|
181
|
+
* Sets a global error handler for the Fastify server instance.
|
|
182
|
+
* This handler checks if the error is an instance of HttpException.
|
|
183
|
+
* If so, it sends a response with the appropriate status code and error message.
|
|
184
|
+
* This ensures consistent error responses for HTTP exceptions throughout the application.
|
|
185
|
+
*/
|
|
186
|
+
this.server.setErrorHandler((error, _, reply) => {
|
|
187
|
+
// Log the error with full stack trace
|
|
188
|
+
const errorMessage = error instanceof Error ? error.message : 'Unhandled error';
|
|
189
|
+
this.server.log.error({ err: error }, errorMessage);
|
|
190
|
+
// Handle HttpException errors
|
|
191
|
+
if (error instanceof HttpException) {
|
|
192
|
+
reply
|
|
193
|
+
.status(error.statusCode)
|
|
194
|
+
.send({
|
|
195
|
+
data: undefined,
|
|
196
|
+
error: error.message,
|
|
197
|
+
statusCode: error.statusCode,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
reply
|
|
202
|
+
.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
|
203
|
+
.send({
|
|
204
|
+
data: undefined,
|
|
205
|
+
error: 'Internal server error',
|
|
206
|
+
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
/**
|
|
211
|
+
* Adds an 'onSend' hook to the Fastify server instance.
|
|
212
|
+
* This hook intercepts every outgoing response before it is sent.
|
|
213
|
+
* It parses the payload as a JSON object (assuming it matches the HttpResponse<T> structure),
|
|
214
|
+
* and sets the HTTP status code of the reply to the value of 'statusCode' in the payload,
|
|
215
|
+
* defaulting to HttpStatus.OK if not present.
|
|
216
|
+
* This ensures that the HTTP status code in the response matches the statusCode property
|
|
217
|
+
* in the application's response payload, providing consistent status handling.
|
|
218
|
+
*/
|
|
219
|
+
this.server.addHook('onSend', (_, reply, payload, done) => {
|
|
220
|
+
try {
|
|
221
|
+
const payloadJson = JSON.parse(payload);
|
|
222
|
+
reply.code(payloadJson.statusCode ?? HttpStatus.OK);
|
|
223
|
+
}
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
225
|
+
catch (error) {
|
|
226
|
+
// Do nothing
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
done();
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Sets up the plugins for the Fastify server.
|
|
235
|
+
* @return A promise that resolves when the plugins are set up.
|
|
236
|
+
*/
|
|
237
|
+
async _setupPlugins() {
|
|
238
|
+
// CORS plugin
|
|
239
|
+
await this.server.register(fastifyCors, {
|
|
240
|
+
credentials: true,
|
|
241
|
+
methods: ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE'],
|
|
242
|
+
origin: this.options.origin,
|
|
243
|
+
});
|
|
244
|
+
// Cookie plugin
|
|
245
|
+
await this.server.register(fastifyCookie);
|
|
246
|
+
// Multipart plugin
|
|
247
|
+
// await this.server.register(fastifyMultipart, {
|
|
248
|
+
// limits: { fileSize: this.options.bodyLimit },
|
|
249
|
+
// });
|
|
250
|
+
}
|
|
251
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tmlmobilidade/fastify",
|
|
3
|
+
"version": "20251202.1817.5",
|
|
4
|
+
"author": {
|
|
5
|
+
"email": "iso@tmlmobilidade.pt",
|
|
6
|
+
"name": "TML-ISO"
|
|
7
|
+
},
|
|
8
|
+
"license": "AGPL-3.0-or-later",
|
|
9
|
+
"homepage": "https://github.com/tmlmobilidade/go#readme",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/tmlmobilidade/go/issues"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/tmlmobilidade/go.git"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"public transit",
|
|
19
|
+
"tml",
|
|
20
|
+
"transportes metropolitanos de lisboa",
|
|
21
|
+
"go"
|
|
22
|
+
],
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"main": "./dist/index.js",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc && resolve-tspaths",
|
|
34
|
+
"lint": "eslint ./src && tsc --noEmit",
|
|
35
|
+
"lint:fix": "eslint . --fix",
|
|
36
|
+
"watch": "tsc-watch --onSuccess 'resolve-tspaths'"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@fastify/cookie": "11.0.2",
|
|
40
|
+
"@fastify/cors": "11.1.0",
|
|
41
|
+
"@fastify/multipart": "9.3.0",
|
|
42
|
+
"@fastify/one-line-logger": "^2.0.2",
|
|
43
|
+
"@tmlmobilidade/consts": "*",
|
|
44
|
+
"@tmlmobilidade/interfaces": "*",
|
|
45
|
+
"@tmlmobilidade/utils": "*",
|
|
46
|
+
"fastify": "5.6.2",
|
|
47
|
+
"pino": "^10.1.0",
|
|
48
|
+
"pino-pretty": "^13.1.3"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@tmlmobilidade/tsconfig": "*",
|
|
52
|
+
"@tmlmobilidade/types": "*",
|
|
53
|
+
"@types/node": "24.10.1",
|
|
54
|
+
"resolve-tspaths": "0.8.23",
|
|
55
|
+
"tsc-watch": "7.2.0",
|
|
56
|
+
"typescript": "5.9.3"
|
|
57
|
+
}
|
|
58
|
+
}
|