@rest-vir/run-service 0.20.0 → 0.21.0
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/handle-request-method.js +1 -1
- package/dist/handle-request/handle-route.js +7 -2
- package/dist/handle-request/run-post-hook.js +6 -2
- package/dist/start-service/attach-service.js +7 -2
- package/dist/test/test-service.d.ts +18 -8
- package/dist/test/test-service.js +6 -2
- package/package.json +12 -12
|
@@ -22,7 +22,7 @@ export function handleRequestMethod({ route, request, }) {
|
|
|
22
22
|
[HttpMethod.Get]: true,
|
|
23
23
|
};
|
|
24
24
|
if (!requestMethod || !allowedMethods[requestMethod]) {
|
|
25
|
-
route.service.logger.error(new RestVirHandlerError(route, `Method '${
|
|
25
|
+
route.service.logger.error(new RestVirHandlerError(route, `Method '${request.method.toUpperCase()}' rejected: '${request.originalUrl}'`, HttpStatus.MethodNotAllowed));
|
|
26
26
|
return {
|
|
27
27
|
statusCode: HttpStatus.MethodNotAllowed,
|
|
28
28
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { assert, check } from '@augment-vir/assert';
|
|
2
2
|
import { ensureError, HttpStatus } from '@augment-vir/common';
|
|
3
|
-
import { RestVirHandlerError, } from '@rest-vir/implement-service';
|
|
3
|
+
import { RejectRequestError, RestVirHandlerError, } from '@rest-vir/implement-service';
|
|
4
4
|
import cluster from 'node:cluster';
|
|
5
5
|
import { handleHandlerOutput, handleHandlerOutputWithoutSending, } from './endpoint-handler.js';
|
|
6
6
|
import { handleEndpointRequest } from './handle-endpoint.js';
|
|
@@ -25,7 +25,7 @@ export async function handleRoute({ webSocket, request, response, route, attachI
|
|
|
25
25
|
].filter(check.isTruthy);
|
|
26
26
|
route.service.logger.info(logParts.join('\t'));
|
|
27
27
|
if (route.isEndpoint) {
|
|
28
|
-
assert.isDefined(response);
|
|
28
|
+
assert.isDefined(response, 'no response object');
|
|
29
29
|
const result = await handleEndpointRequest({
|
|
30
30
|
request,
|
|
31
31
|
response,
|
|
@@ -71,6 +71,11 @@ export async function handleRoute({ webSocket, request, response, route, attachI
|
|
|
71
71
|
throw new RestVirHandlerError(route, 'Request was not handled.');
|
|
72
72
|
}
|
|
73
73
|
catch (error) {
|
|
74
|
+
if (error instanceof RejectRequestError) {
|
|
75
|
+
assert.isDefined(response, 'no response object');
|
|
76
|
+
await handleHandlerOutput({ statusCode: error.httpStatus, body: error.responseErrorMessage }, response);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
74
79
|
route.service.logger.error(ensureError(error));
|
|
75
80
|
if (options.throwErrorsForExternalHandling) {
|
|
76
81
|
throw error;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { assert,
|
|
1
|
+
import { assert, checkWrap } from '@augment-vir/assert';
|
|
2
2
|
import { matchUrlToService } from '@rest-vir/define-service';
|
|
3
3
|
import { HttpMethod, } from '@rest-vir/implement-service';
|
|
4
4
|
export async function runPostHook({ request, response, attachId, server, postHook, service, originalBody, originalStatus, }) {
|
|
5
|
+
const method = checkWrap.isEnumValue(request.method.toUpperCase(), HttpMethod);
|
|
6
|
+
if (!method) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
5
9
|
const restVirContext = request.restVirContext?.[attachId];
|
|
6
10
|
assert.isDefined(restVirContext, 'restVirContext is not defined');
|
|
7
11
|
const context = restVirContext.context;
|
|
@@ -20,7 +24,7 @@ export async function runPostHook({ request, response, attachId, server, postHoo
|
|
|
20
24
|
: undefined;
|
|
21
25
|
const postHookParams = {
|
|
22
26
|
pathParams: request.params,
|
|
23
|
-
method
|
|
27
|
+
method,
|
|
24
28
|
request,
|
|
25
29
|
requestData,
|
|
26
30
|
requestHeaders: request.headers,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assert, check } from '@augment-vir/assert';
|
|
2
|
-
import { ensureError, extractErrorMessage, getEnumValues, getObjectTypedKeys, HttpMethod, HttpStatus, randomString, } from '@augment-vir/common';
|
|
2
|
+
import { ensureError, ensureErrorClass, extractErrorMessage, getEnumValues, getObjectTypedKeys, HttpMethod, HttpStatus, randomString, } from '@augment-vir/common';
|
|
3
3
|
import fastifyWs from '@fastify/websocket';
|
|
4
4
|
import { RestVirHandlerError, } from '@rest-vir/implement-service';
|
|
5
5
|
import { buildUrl, parseUrl } from 'url-vir';
|
|
@@ -81,7 +81,12 @@ export async function attachService(server, service, options = {}) {
|
|
|
81
81
|
return handleHandlerOutput(preHandlerResult, response);
|
|
82
82
|
}
|
|
83
83
|
catch (error) {
|
|
84
|
-
service.logger.error(
|
|
84
|
+
service.logger.error(ensureErrorClass(error, RestVirHandlerError, {
|
|
85
|
+
isEndpoint: undefined,
|
|
86
|
+
isWebSocket: undefined,
|
|
87
|
+
path: request.originalUrl,
|
|
88
|
+
service,
|
|
89
|
+
}, 'Unexpected error'));
|
|
85
90
|
if (options.throwErrorsForExternalHandling) {
|
|
86
91
|
throw error;
|
|
87
92
|
/* node:coverage ignore next 5 */
|
|
@@ -250,6 +250,20 @@ export type ConnectTestServiceWebSocket<Service extends SelectFrom<GenericServic
|
|
|
250
250
|
export type TestServiceOptions = Overwrite<StartServiceUserOptions, {
|
|
251
251
|
port?: number | undefined | false;
|
|
252
252
|
}>;
|
|
253
|
+
export type ServiceTestSuite<Service extends Readonly<SelectFrom<GenericServiceImplementation, {
|
|
254
|
+
webSockets: true;
|
|
255
|
+
endpoints: true;
|
|
256
|
+
serviceName: true;
|
|
257
|
+
createContext: true;
|
|
258
|
+
serviceOrigin: true;
|
|
259
|
+
requiredClientOrigin: true;
|
|
260
|
+
logger: true;
|
|
261
|
+
postHook: true;
|
|
262
|
+
}>>> = {
|
|
263
|
+
fetchEndpoint: FetchTestService<Service>;
|
|
264
|
+
connectWebSocket: ConnectTestServiceWebSocket<Service>;
|
|
265
|
+
server: Readonly<FastifyInstance>;
|
|
266
|
+
};
|
|
253
267
|
/**
|
|
254
268
|
* Test your service with actual Request and Response objects! The returned object includes
|
|
255
269
|
* utilities for sending fetch requests and WebSocket connections to the service.
|
|
@@ -288,10 +302,9 @@ export declare function testService<const Service extends Readonly<SelectFrom<Ge
|
|
|
288
302
|
}>>>(service: Readonly<Service>, testServiceOptions?: Readonly<Omit<PartialWithUndefined<StartServiceUserOptions>, 'workerCount' | 'preventWorkerRespawn' | ''>>): Promise<{
|
|
289
303
|
/** Kill the server being tested. This should always be called after your tests are finished. */
|
|
290
304
|
kill(this: void): Promise<void>;
|
|
291
|
-
/** Send a request to the service. */
|
|
292
305
|
fetchEndpoint: FetchTestService<Service>;
|
|
293
|
-
/** Connect to a service WebSocket. */
|
|
294
306
|
connectWebSocket: ConnectTestServiceWebSocket<Service>;
|
|
307
|
+
server: Readonly<FastifyInstance>;
|
|
295
308
|
}>;
|
|
296
309
|
/**
|
|
297
310
|
* Similar to {@link testService} but used to test against a Fastify server that you've already
|
|
@@ -315,12 +328,7 @@ export declare function testExistingServer<const Service extends Readonly<Select
|
|
|
315
328
|
requiredClientOrigin: true;
|
|
316
329
|
logger: true;
|
|
317
330
|
postHook: true;
|
|
318
|
-
}>>>(server: Readonly<FastifyInstance>, service: Readonly<Service>, options?: Readonly<HandleRouteOptions & Omit<PartialWithUndefined<StartServiceOptions>, 'workerCount' | 'preventWorkerRespawn'>>): Promise<
|
|
319
|
-
/** Send a request to the service. */
|
|
320
|
-
fetchEndpoint: FetchTestService<Service>;
|
|
321
|
-
/** Connect to a service WebSocket. */
|
|
322
|
-
connectWebSocket: ConnectTestServiceWebSocket<Service>;
|
|
323
|
-
}>;
|
|
331
|
+
}>>>(server: Readonly<FastifyInstance>, service: Readonly<Service>, options?: Readonly<HandleRouteOptions & Omit<PartialWithUndefined<StartServiceOptions>, 'workerCount' | 'preventWorkerRespawn'>>): Promise<ServiceTestSuite<Service>>;
|
|
324
332
|
/**
|
|
325
333
|
* Use this in conjunction with
|
|
326
334
|
* [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test) or the Node.js built-in
|
|
@@ -364,4 +372,6 @@ export declare function describeService<const Service extends Readonly<SelectFro
|
|
|
364
372
|
}, describeCallback: (params: {
|
|
365
373
|
/** Send a request to the service. */
|
|
366
374
|
fetchEndpoint: FetchTestService<Service>;
|
|
375
|
+
getServer: () => Promise<Readonly<FastifyInstance>>;
|
|
376
|
+
service: Readonly<Service>;
|
|
367
377
|
}) => void | undefined): void;
|
|
@@ -126,7 +126,6 @@ export async function testExistingServer(server, service, options = {}) {
|
|
|
126
126
|
}).origin;
|
|
127
127
|
const fetchEndpoint = mapObjectValues(service.endpoints, (endpointPath, endpoint) => {
|
|
128
128
|
return async (...args) => {
|
|
129
|
-
await server.ready();
|
|
130
129
|
const overwrittenOriginEndpoint = mergeDeep(endpoint, fetchOrigin
|
|
131
130
|
? {
|
|
132
131
|
service: {
|
|
@@ -170,7 +169,6 @@ export async function testExistingServer(server, service, options = {}) {
|
|
|
170
169
|
}).origin;
|
|
171
170
|
const connectWebSocket = mapObjectValues(service.webSockets, (webSocketPath, webSocketDefinition) => {
|
|
172
171
|
return async (...args) => {
|
|
173
|
-
await server.ready();
|
|
174
172
|
const [{ protocols = [], listeners } = {}] = args;
|
|
175
173
|
const overwrittenOriginWebSocket = mergeDeep(webSocketDefinition, webSocketOrigin
|
|
176
174
|
? {
|
|
@@ -205,11 +203,13 @@ export async function testExistingServer(server, service, options = {}) {
|
|
|
205
203
|
return finalized;
|
|
206
204
|
};
|
|
207
205
|
});
|
|
206
|
+
await server.ready();
|
|
208
207
|
return {
|
|
209
208
|
/** Send a request to the service. */
|
|
210
209
|
fetchEndpoint,
|
|
211
210
|
/** Connect to a service WebSocket. */
|
|
212
211
|
connectWebSocket,
|
|
212
|
+
server,
|
|
213
213
|
};
|
|
214
214
|
}
|
|
215
215
|
/**
|
|
@@ -249,6 +249,10 @@ export function describeService({ service, options, }, describeCallback) {
|
|
|
249
249
|
describe(service.serviceName, () => {
|
|
250
250
|
describeCallback({
|
|
251
251
|
fetchEndpoint: fetchServiceObject,
|
|
252
|
+
async getServer() {
|
|
253
|
+
return (await servicePromise).server;
|
|
254
|
+
},
|
|
255
|
+
service,
|
|
252
256
|
});
|
|
253
257
|
/**
|
|
254
258
|
* The built-in Node.js test runner runs `it` calls sequentially so this will always be
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rest-vir/run-service",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
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,30 +39,30 @@
|
|
|
39
39
|
"test:update": "npm test update"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@augment-vir/assert": "^31.
|
|
43
|
-
"@augment-vir/common": "^31.
|
|
44
|
-
"@augment-vir/node": "^31.
|
|
45
|
-
"@fastify/websocket": "^11.0
|
|
46
|
-
"@rest-vir/define-service": "^0.
|
|
47
|
-
"@rest-vir/implement-service": "^0.
|
|
42
|
+
"@augment-vir/assert": "^31.28.0",
|
|
43
|
+
"@augment-vir/common": "^31.28.0",
|
|
44
|
+
"@augment-vir/node": "^31.28.0",
|
|
45
|
+
"@fastify/websocket": "^11.2.0",
|
|
46
|
+
"@rest-vir/define-service": "^0.21.0",
|
|
47
|
+
"@rest-vir/implement-service": "^0.21.0",
|
|
48
48
|
"cluster-vir": "^0.1.0",
|
|
49
|
-
"date-vir": "^7.
|
|
50
|
-
"fastify": "^5.
|
|
49
|
+
"date-vir": "^7.4.0",
|
|
50
|
+
"fastify": "^5.4.0",
|
|
51
51
|
"light-my-request": "^6.6.0",
|
|
52
52
|
"portfinder": "^1.0.37",
|
|
53
53
|
"type-fest": "^4.41.0",
|
|
54
54
|
"url-vir": "^2.1.3"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@augment-vir/test": "^31.
|
|
57
|
+
"@augment-vir/test": "^31.28.0",
|
|
58
58
|
"@fastify/multipart": "^9.0.3",
|
|
59
59
|
"@types/connect": "^3.4.38",
|
|
60
|
-
"@types/node": "^
|
|
60
|
+
"@types/node": "^24.1.0",
|
|
61
61
|
"@types/ws": "^8.18.1",
|
|
62
62
|
"c8": "^10.1.3",
|
|
63
63
|
"istanbul-smart-text-reporter": "^1.1.5",
|
|
64
64
|
"markdown-code-example-inserter": "^3.0.3",
|
|
65
|
-
"object-shape-tester": "^5.
|
|
65
|
+
"object-shape-tester": "^5.3.0"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"@augment-vir/test": ">=30",
|