@rest-vir/run-service 0.10.0 → 0.11.1
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/handle-request/endpoint-handler.d.ts +2 -3
- package/dist/handle-request/endpoint-handler.js +3 -8
- package/dist/handle-request/handle-route.js +4 -4
- package/dist/handle-request/pre-handler.d.ts +2 -1
- package/dist/handle-request/pre-handler.js +12 -12
- package/dist/start-service/attach-service.js +12 -12
- package/dist/start-service/start-service.js +4 -1
- package/package.json +9 -9
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type HttpStatus, type MaybePromise, type PartialWithUndefined } from '@augment-vir/common';
|
|
2
2
|
import { ServerRequest, ServerResponse, type ImplementedEndpoint, type ImplementedWebSocket } from '@rest-vir/implement-service';
|
|
3
|
+
import type { FastifyReply } from 'fastify';
|
|
3
4
|
import { OutgoingHttpHeaders } from 'node:http';
|
|
4
5
|
/**
|
|
5
6
|
* Options for `handleRoute`.
|
|
@@ -71,6 +72,4 @@ export type EndpointHandler = (params: Readonly<EndpointHandlerParams>) => Maybe
|
|
|
71
72
|
* @category Package : @rest-vir/run-service
|
|
72
73
|
* @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
|
|
73
74
|
*/
|
|
74
|
-
export declare function handleHandlerResult(result: Readonly<HandledOutput>, response: ServerResponse):
|
|
75
|
-
responseSent: boolean;
|
|
76
|
-
};
|
|
75
|
+
export declare function handleHandlerResult(result: Readonly<HandledOutput>, response: ServerResponse): undefined | FastifyReply;
|
|
@@ -14,16 +14,11 @@ export function handleHandlerResult(result, response) {
|
|
|
14
14
|
if (result?.statusCode) {
|
|
15
15
|
response.statusCode = result.statusCode;
|
|
16
16
|
if (result.body) {
|
|
17
|
-
response.send(result.body);
|
|
17
|
+
return response.send(result.body);
|
|
18
18
|
}
|
|
19
19
|
else {
|
|
20
|
-
response.send();
|
|
20
|
+
return response.send();
|
|
21
21
|
}
|
|
22
|
-
return {
|
|
23
|
-
responseSent: true,
|
|
24
|
-
};
|
|
25
22
|
}
|
|
26
|
-
return
|
|
27
|
-
responseSent: false,
|
|
28
|
-
};
|
|
23
|
+
return undefined;
|
|
29
24
|
}
|
|
@@ -35,19 +35,19 @@ response, route, attachId, options = {}) {
|
|
|
35
35
|
endpoint: route,
|
|
36
36
|
attachId,
|
|
37
37
|
});
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const sentResponse = handleHandlerResult(result, response);
|
|
39
|
+
if (sentResponse) {
|
|
40
|
+
return sentResponse;
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
else if (route.isWebSocket) {
|
|
43
44
|
assert.isDefined(webSocket);
|
|
44
|
-
await handleWebSocketRequest({
|
|
45
|
+
return await handleWebSocketRequest({
|
|
45
46
|
request,
|
|
46
47
|
implementedWebSocket: route,
|
|
47
48
|
webSocket,
|
|
48
49
|
attachId,
|
|
49
50
|
});
|
|
50
|
-
return;
|
|
51
51
|
}
|
|
52
52
|
/* node:coverage ignore next: this can't actually be triggered but it should be covered as a potential future edge case. */
|
|
53
53
|
throw new RestVirHandlerError(route, 'Request was not handled.');
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type SelectFrom } from '@augment-vir/common';
|
|
2
2
|
import { GenericServiceImplementation, ServerRequest, ServerResponse } from '@rest-vir/implement-service';
|
|
3
|
+
import { type FastifyReply } from 'fastify';
|
|
3
4
|
/**
|
|
4
5
|
* Handles a request before it gets to the actual route handlers.
|
|
5
6
|
*
|
|
@@ -15,4 +16,4 @@ export declare function preHandler(request: ServerRequest, response: ServerRespo
|
|
|
15
16
|
serviceOrigin: true;
|
|
16
17
|
requiredClientOrigin: true;
|
|
17
18
|
logger: true;
|
|
18
|
-
}>>, attachId: string): Promise<
|
|
19
|
+
}>>, attachId: string): Promise<FastifyReply | undefined>;
|
|
@@ -19,7 +19,7 @@ export async function preHandler(request, response, service, attachId) {
|
|
|
19
19
|
const pathMatch = matchUrlToService(service, request.originalUrl);
|
|
20
20
|
if (!pathMatch) {
|
|
21
21
|
/** Nothing to do. */
|
|
22
|
-
return;
|
|
22
|
+
return undefined;
|
|
23
23
|
}
|
|
24
24
|
const endpointDefinition = pathMatch.endpointPath
|
|
25
25
|
? service.endpoints[pathMatch.endpointPath]
|
|
@@ -29,7 +29,7 @@ export async function preHandler(request, response, service, attachId) {
|
|
|
29
29
|
: undefined;
|
|
30
30
|
const route = endpointDefinition || webSocketDefinition;
|
|
31
31
|
if (!route) {
|
|
32
|
-
return;
|
|
32
|
+
return undefined;
|
|
33
33
|
}
|
|
34
34
|
const protocols = webSocketDefinition
|
|
35
35
|
? (request.headers['sec-websocket-protocol'] || '').split(', ')
|
|
@@ -43,24 +43,25 @@ export async function preHandler(request, response, service, attachId) {
|
|
|
43
43
|
service.logger.error(new RestVirHandlerError(route, extractErrorMessage(ensureErrorAndPrependMessage(protocolShapeError, `WebSocket protocols rejected (${stringify(protocols)}):`))));
|
|
44
44
|
response.statusCode = HttpStatus.BadRequest;
|
|
45
45
|
response.send('Invalid protocols.');
|
|
46
|
-
return;
|
|
46
|
+
return undefined;
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
const subHandlerResponse = handleHandlerResult(await handleCors({
|
|
49
49
|
request,
|
|
50
50
|
route,
|
|
51
|
-
}), response)
|
|
51
|
+
}), response) ||
|
|
52
52
|
handleHandlerResult(handleRequestMethod({
|
|
53
53
|
request,
|
|
54
54
|
route,
|
|
55
|
-
}), response)
|
|
56
|
-
|
|
55
|
+
}), response);
|
|
56
|
+
if (subHandlerResponse) {
|
|
57
|
+
return subHandlerResponse;
|
|
57
58
|
}
|
|
58
59
|
const requestData = wrapInTry(() => extractRequestData(request.body, request.headers, route));
|
|
59
60
|
if (requestData instanceof Error) {
|
|
60
61
|
service.logger.error(new RestVirHandlerError(route, `Rejected request body from '${request.originalUrl}': ${stringify(requestData)}`));
|
|
61
62
|
response.statusCode = HttpStatus.BadRequest;
|
|
62
63
|
response.send('Invalid body.');
|
|
63
|
-
return;
|
|
64
|
+
return undefined;
|
|
64
65
|
}
|
|
65
66
|
const contextParams = {
|
|
66
67
|
method: assertWrap.isEnumValue(request.method.toUpperCase(), HttpMethod),
|
|
@@ -74,19 +75,17 @@ export async function preHandler(request, response, service, attachId) {
|
|
|
74
75
|
};
|
|
75
76
|
const searchParams = handleSearchParams({ request, route });
|
|
76
77
|
if (!('data' in searchParams)) {
|
|
77
|
-
handleHandlerResult(searchParams, response);
|
|
78
|
-
return;
|
|
78
|
+
return handleHandlerResult(searchParams, response);
|
|
79
79
|
}
|
|
80
80
|
try {
|
|
81
81
|
const contextOutput = await service.createContext?.(contextParams);
|
|
82
82
|
if (contextOutput?.reject) {
|
|
83
83
|
service.logger.error(new RestVirHandlerError(route, `Context creation rejected: '${request.originalUrl}'`));
|
|
84
|
-
handleHandlerResult({
|
|
84
|
+
return handleHandlerResult({
|
|
85
85
|
body: contextOutput.reject.responseErrorMessage,
|
|
86
86
|
statusCode: contextOutput.reject.statusCode,
|
|
87
87
|
headers: contextOutput.reject.headers,
|
|
88
88
|
}, response);
|
|
89
|
-
return;
|
|
90
89
|
}
|
|
91
90
|
if (!request.restVirContext) {
|
|
92
91
|
request.restVirContext = {};
|
|
@@ -97,6 +96,7 @@ export async function preHandler(request, response, service, attachId) {
|
|
|
97
96
|
protocols,
|
|
98
97
|
searchParams: searchParams.data,
|
|
99
98
|
};
|
|
99
|
+
return undefined;
|
|
100
100
|
}
|
|
101
101
|
catch (error) {
|
|
102
102
|
throw ensureErrorAndPrependMessage(error, 'Failed to generate request context.');
|
|
@@ -51,7 +51,7 @@ export async function attachService(server, service, options = {}) {
|
|
|
51
51
|
}
|
|
52
52
|
server.addHook('preValidation', async (request, response) => {
|
|
53
53
|
try {
|
|
54
|
-
await preHandler(request, response, service, attachId);
|
|
54
|
+
return await preHandler(request, response, service, attachId);
|
|
55
55
|
}
|
|
56
56
|
catch (error) {
|
|
57
57
|
service.logger.error(ensureError(error));
|
|
@@ -75,18 +75,18 @@ export async function attachService(server, service, options = {}) {
|
|
|
75
75
|
server.route({
|
|
76
76
|
method: endpointFastifyMethods,
|
|
77
77
|
url: path,
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
handler(request, response) {
|
|
79
|
+
return handleRoute(undefined, request, response, endpoint, attachId, options);
|
|
80
80
|
},
|
|
81
81
|
});
|
|
82
82
|
server.route({
|
|
83
83
|
method: HttpMethod.Get,
|
|
84
84
|
url: path,
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
handler(request, response) {
|
|
86
|
+
return handleRoute(undefined, request, response, endpoint, attachId, options);
|
|
87
87
|
},
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
wsHandler(webSocket, request) {
|
|
89
|
+
return handleRoute(webSocket, request, undefined, webSocketDefinition, attachId, options);
|
|
90
90
|
},
|
|
91
91
|
});
|
|
92
92
|
}
|
|
@@ -97,8 +97,8 @@ export async function attachService(server, service, options = {}) {
|
|
|
97
97
|
HttpMethod.Get,
|
|
98
98
|
],
|
|
99
99
|
url: path,
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
handler(request, response) {
|
|
101
|
+
return handleRoute(undefined, request, response, endpoint, attachId, options);
|
|
102
102
|
},
|
|
103
103
|
});
|
|
104
104
|
}
|
|
@@ -107,10 +107,10 @@ export async function attachService(server, service, options = {}) {
|
|
|
107
107
|
method: HttpMethod.Get,
|
|
108
108
|
url: path,
|
|
109
109
|
handler(request, response) {
|
|
110
|
-
response.status(HttpStatus.NotFound).send();
|
|
110
|
+
return response.status(HttpStatus.NotFound).send();
|
|
111
111
|
},
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
wsHandler(webSocket, request) {
|
|
113
|
+
return handleRoute(webSocket, request, undefined, webSocketDefinition, attachId, options);
|
|
114
114
|
},
|
|
115
115
|
});
|
|
116
116
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { check } from '@augment-vir/assert';
|
|
2
|
-
import { awaitedForEach } from '@augment-vir/common';
|
|
2
|
+
import { awaitedForEach, ensureErrorAndPrependMessage } from '@augment-vir/common';
|
|
3
3
|
import { ClusterManager, runInCluster } from 'cluster-vir';
|
|
4
4
|
import fastify from 'fastify';
|
|
5
5
|
import { getPortPromise } from 'portfinder';
|
|
@@ -16,6 +16,9 @@ import { finalizeOptions, } from './start-service-options.js';
|
|
|
16
16
|
* @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
|
|
17
17
|
*/
|
|
18
18
|
export async function startService(service, userOptions = {}, fastifyPlugins = []) {
|
|
19
|
+
process.on('unhandledRejection', (reason) => {
|
|
20
|
+
service.logger.error(ensureErrorAndPrependMessage(reason, `Unhandled async rejection in ${service.serviceName}:`));
|
|
21
|
+
});
|
|
19
22
|
const options = finalizeOptions(service.serviceOrigin, userOptions);
|
|
20
23
|
const port = options.lockPort || check.isFalse(options.port)
|
|
21
24
|
? options.port
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rest-vir/run-service",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Run a service defined by @rest-vir/define-service and implemented by @rest-vir/implement-service.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rest",
|
|
@@ -39,25 +39,25 @@
|
|
|
39
39
|
"test:update": "npm test update"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@augment-vir/assert": "^31.10.
|
|
43
|
-
"@augment-vir/common": "^31.10.
|
|
44
|
-
"@augment-vir/node": "^31.10.
|
|
42
|
+
"@augment-vir/assert": "^31.10.2",
|
|
43
|
+
"@augment-vir/common": "^31.10.2",
|
|
44
|
+
"@augment-vir/node": "^31.10.2",
|
|
45
45
|
"@fastify/websocket": "^11.0.2",
|
|
46
|
-
"@rest-vir/define-service": "^0.
|
|
47
|
-
"@rest-vir/implement-service": "^0.
|
|
46
|
+
"@rest-vir/define-service": "^0.11.1",
|
|
47
|
+
"@rest-vir/implement-service": "^0.11.1",
|
|
48
48
|
"cluster-vir": "^0.1.0",
|
|
49
49
|
"date-vir": "^7.3.1",
|
|
50
50
|
"fastify": "^5.2.2",
|
|
51
51
|
"light-my-request": "^6.6.0",
|
|
52
52
|
"portfinder": "^1.0.35",
|
|
53
|
-
"type-fest": "^4.39.
|
|
53
|
+
"type-fest": "^4.39.1",
|
|
54
54
|
"url-vir": "^2.1.3"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@augment-vir/test": "^31.10.
|
|
57
|
+
"@augment-vir/test": "^31.10.2",
|
|
58
58
|
"@fastify/multipart": "^9.0.3",
|
|
59
59
|
"@types/connect": "^3.4.38",
|
|
60
|
-
"@types/node": "^22.
|
|
60
|
+
"@types/node": "^22.14.0",
|
|
61
61
|
"@types/ws": "^8.18.1",
|
|
62
62
|
"c8": "^10.1.3",
|
|
63
63
|
"istanbul-smart-text-reporter": "^1.1.5",
|