@rest-vir/run-service 0.18.1 → 0.19.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.
@@ -65,6 +65,15 @@ export type EndpointHandlerParams = {
65
65
  * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
66
66
  */
67
67
  export type EndpointHandler = (params: Readonly<EndpointHandlerParams>) => MaybePromise<HandledOutput>;
68
+ /**
69
+ * Handle the output of a handler without sending the response. Similar to
70
+ * {@link handleHandlerOutput} but this one does not send the response.
71
+ *
72
+ * @category Internal
73
+ * @category Package : @rest-vir/run-service
74
+ * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
75
+ */
76
+ export declare function handleHandlerOutputWithoutSending(result: Readonly<HandledOutput>, response: ServerResponse): undefined | HandledOutput;
68
77
  /**
69
78
  * Handle the output of a handler. Setting headers, sending the response, etc.
70
79
  *
@@ -72,4 +81,4 @@ export type EndpointHandler = (params: Readonly<EndpointHandlerParams>) => Maybe
72
81
  * @category Package : @rest-vir/run-service
73
82
  * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
74
83
  */
75
- export declare function handleHandlerResult(result: Readonly<HandledOutput>, response: ServerResponse): undefined | FastifyReply;
84
+ export declare function handleHandlerOutput(result: Readonly<HandledOutput>, response: ServerResponse): undefined | FastifyReply;
@@ -1,5 +1,26 @@
1
1
  /* node:coverage disable: this file is just types */
2
2
  import { setResponseHeaders } from '../util/headers.js';
3
+ /**
4
+ * Handle the output of a handler without sending the response. Similar to
5
+ * {@link handleHandlerOutput} but this one does not send the response.
6
+ *
7
+ * @category Internal
8
+ * @category Package : @rest-vir/run-service
9
+ * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
10
+ */
11
+ export function handleHandlerOutputWithoutSending(result, response) {
12
+ if (result?.headers) {
13
+ setResponseHeaders(response, result.headers);
14
+ }
15
+ if (result?.statusCode) {
16
+ response.statusCode = result.statusCode;
17
+ return {
18
+ body: result.body,
19
+ statusCode: result.statusCode,
20
+ };
21
+ }
22
+ return undefined;
23
+ }
3
24
  /**
4
25
  * Handle the output of a handler. Setting headers, sending the response, etc.
5
26
  *
@@ -7,7 +28,7 @@ import { setResponseHeaders } from '../util/headers.js';
7
28
  * @category Package : @rest-vir/run-service
8
29
  * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
9
30
  */
10
- export function handleHandlerResult(result, response) {
31
+ export function handleHandlerOutput(result, response) {
11
32
  if (result?.headers) {
12
33
  setResponseHeaders(response, result.headers);
13
34
  }
@@ -1,4 +1,5 @@
1
- import { type ImplementedEndpoint, type ImplementedWebSocket, type RunningServerInfo, type ServerRequest, type ServerResponse } from '@rest-vir/implement-service';
1
+ import { type SelectFrom } from '@augment-vir/common';
2
+ import { type GenericServiceImplementation, type ImplementedEndpoint, type ImplementedWebSocket, type PostHook, type RunningServerInfo, type ServerRequest, type ServerResponse } from '@rest-vir/implement-service';
2
3
  import { type WebSocket as WsWebSocket } from 'ws';
3
4
  import { type HandleRouteOptions } from './endpoint-handler.js';
4
5
  /**
@@ -8,8 +9,20 @@ import { type HandleRouteOptions } from './endpoint-handler.js';
8
9
  * @category Package : @rest-vir/run-service
9
10
  * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
10
11
  */
11
- export declare function handleRoute(
12
- /** Endpoint requests won't have a `WebSocket`. */
13
- webSocket: WsWebSocket | undefined, request: ServerRequest,
14
- /** `WebSocket` requests won't have a response. */
15
- response: ServerResponse | undefined, route: Readonly<ImplementedEndpoint | ImplementedWebSocket>, attachId: string, server: Readonly<RunningServerInfo>, options?: Readonly<Pick<HandleRouteOptions, 'throwErrorsForExternalHandling'>>): Promise<void>;
12
+ export declare function handleRoute({ webSocket, request, response, route, attachId, server, options, postHook, service, }: {
13
+ /** Endpoint requests won't have a `WebSocket`. */ webSocket: WsWebSocket | undefined;
14
+ request: ServerRequest /** `WebSocket` requests won't have a response. */;
15
+ response: ServerResponse | undefined;
16
+ route: Readonly<ImplementedEndpoint | ImplementedWebSocket>;
17
+ attachId: string;
18
+ server: Readonly<RunningServerInfo>;
19
+ options: Readonly<Pick<HandleRouteOptions, 'throwErrorsForExternalHandling'>>;
20
+ postHook: PostHook | undefined;
21
+ service: Readonly<SelectFrom<GenericServiceImplementation, {
22
+ webSockets: true;
23
+ endpoints: true;
24
+ serviceName: true;
25
+ serviceOrigin: true;
26
+ requiredClientOrigin: true;
27
+ }>>;
28
+ }): Promise<void>;
@@ -2,9 +2,10 @@ import { assert, check } from '@augment-vir/assert';
2
2
  import { ensureError, HttpStatus } from '@augment-vir/common';
3
3
  import { RestVirHandlerError, } from '@rest-vir/implement-service';
4
4
  import cluster from 'node:cluster';
5
- import { handleHandlerResult } from './endpoint-handler.js';
5
+ import { handleHandlerOutput, handleHandlerOutputWithoutSending, } from './endpoint-handler.js';
6
6
  import { handleEndpointRequest } from './handle-endpoint.js';
7
7
  import { handleWebSocketRequest } from './handle-web-socket.js';
8
+ import { runPostHook } from './run-post-hook.js';
8
9
  /**
9
10
  * Handles a WebSocket or Endpoint request.
10
11
  *
@@ -12,11 +13,7 @@ import { handleWebSocketRequest } from './handle-web-socket.js';
12
13
  * @category Package : @rest-vir/run-service
13
14
  * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
14
15
  */
15
- export async function handleRoute(
16
- /** Endpoint requests won't have a `WebSocket`. */
17
- webSocket, request,
18
- /** `WebSocket` requests won't have a response. */
19
- response, route, attachId, server, options = {}) {
16
+ export async function handleRoute({ webSocket, request, response, route, attachId, server, options = {}, postHook, service, }) {
20
17
  try {
21
18
  const workerPid = cluster.isPrimary ? '' : process.pid;
22
19
  const webSocketMarker = route.isWebSocket ? '(ws)' : '';
@@ -36,9 +33,28 @@ response, route, attachId, server, options = {}) {
36
33
  attachId,
37
34
  server,
38
35
  });
39
- const sentResponse = handleHandlerResult(result, response);
40
- if (sentResponse) {
41
- return sentResponse;
36
+ const endpointResult = handleHandlerOutputWithoutSending(result, response);
37
+ const postHookResult = (postHook &&
38
+ endpointResult?.statusCode &&
39
+ (await runPostHook({
40
+ attachId,
41
+ originalBody: endpointResult.body,
42
+ originalStatus: endpointResult.statusCode,
43
+ postHook,
44
+ request,
45
+ response,
46
+ server,
47
+ service,
48
+ }))) ||
49
+ endpointResult;
50
+ if (postHookResult) {
51
+ if (postHookResult.body == undefined) {
52
+ postHookResult.headers = {
53
+ ...postHookResult.headers,
54
+ 'content-type': undefined,
55
+ };
56
+ }
57
+ return handleHandlerOutput(postHookResult, response);
42
58
  }
43
59
  }
44
60
  else if (route.isWebSocket) {
@@ -1,6 +1,6 @@
1
1
  import { type SelectFrom } from '@augment-vir/common';
2
2
  import { type GenericServiceImplementation, type RunningServerInfo, type ServerRequest, type ServerResponse } from '@rest-vir/implement-service';
3
- import { type FastifyReply } from 'fastify';
3
+ import { type HandledOutput } from './endpoint-handler.js';
4
4
  /**
5
5
  * Handles a request before it gets to the actual route handlers.
6
6
  *
@@ -8,12 +8,18 @@ import { type FastifyReply } from 'fastify';
8
8
  * @category Package : @rest-vir/run-service
9
9
  * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
10
10
  */
11
- export declare function preHandler(request: ServerRequest, response: ServerResponse, service: Readonly<SelectFrom<GenericServiceImplementation, {
12
- webSockets: true;
13
- endpoints: true;
14
- serviceName: true;
15
- createContext: true;
16
- serviceOrigin: true;
17
- requiredClientOrigin: true;
18
- logger: true;
19
- }>>, server: Readonly<RunningServerInfo>, attachId: string): Promise<FastifyReply | undefined>;
11
+ export declare function preHandler({ request, response, service, server, attachId, }: {
12
+ request: ServerRequest;
13
+ response: ServerResponse;
14
+ service: Readonly<SelectFrom<GenericServiceImplementation, {
15
+ webSockets: true;
16
+ endpoints: true;
17
+ serviceName: true;
18
+ createContext: true;
19
+ serviceOrigin: true;
20
+ requiredClientOrigin: true;
21
+ logger: true;
22
+ }>>;
23
+ server: Readonly<RunningServerInfo>;
24
+ attachId: string;
25
+ }): Promise<Readonly<HandledOutput>>;
@@ -3,7 +3,7 @@ import { ensureErrorAndPrependMessage, extractErrorMessage, HttpStatus, stringif
3
3
  import { isFormDataShape, matchUrlToService, restVirServiceNameHeader, } from '@rest-vir/define-service';
4
4
  import { HttpMethod, RestVirHandlerError, } from '@rest-vir/implement-service';
5
5
  import { assertValidShape, isValidShape } from 'object-shape-tester';
6
- import { handleHandlerResult } from './endpoint-handler.js';
6
+ import { handleHandlerOutputWithoutSending } from './endpoint-handler.js';
7
7
  import { handleCors } from './handle-cors.js';
8
8
  import { handleRequestMethod } from './handle-request-method.js';
9
9
  import { handleSearchParams } from './handle-search-params.js';
@@ -14,7 +14,7 @@ import { handleSearchParams } from './handle-search-params.js';
14
14
  * @category Package : @rest-vir/run-service
15
15
  * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
16
16
  */
17
- export async function preHandler(request, response, service, server, attachId) {
17
+ export async function preHandler({ request, response, service, server, attachId, }) {
18
18
  response.header(restVirServiceNameHeader, service.serviceName);
19
19
  const pathMatch = matchUrlToService(service, request.originalUrl);
20
20
  if (!pathMatch) {
@@ -41,15 +41,16 @@ export async function preHandler(request, response, service, server, attachId) {
41
41
  : undefined;
42
42
  if (protocolShapeError) {
43
43
  service.logger.error(new RestVirHandlerError(route, extractErrorMessage(ensureErrorAndPrependMessage(protocolShapeError, `WebSocket protocols rejected (${stringify(protocols)}):`))));
44
- response.statusCode = HttpStatus.BadRequest;
45
- response.send('Invalid protocols.');
46
- return undefined;
44
+ return {
45
+ statusCode: HttpStatus.BadRequest,
46
+ body: 'Invalid protocol.',
47
+ };
47
48
  }
48
- const subHandlerResponse = handleHandlerResult(await handleCors({
49
+ const subHandlerResponse = handleHandlerOutputWithoutSending(await handleCors({
49
50
  request,
50
51
  route,
51
52
  }), response) ||
52
- handleHandlerResult(handleRequestMethod({
53
+ handleHandlerOutputWithoutSending(handleRequestMethod({
53
54
  request,
54
55
  route,
55
56
  }), response);
@@ -59,15 +60,17 @@ export async function preHandler(request, response, service, server, attachId) {
59
60
  const requestData = wrapInTry(() => extractRequestData(request.body, request.headers, route));
60
61
  if (requestData instanceof Error) {
61
62
  service.logger.error(new RestVirHandlerError(route, `Rejected request body from '${request.originalUrl}': ${stringify(requestData)}`));
62
- response.statusCode = HttpStatus.BadRequest;
63
- response.send('Invalid body.');
64
- return undefined;
63
+ return {
64
+ statusCode: HttpStatus.BadRequest,
65
+ body: 'Invalid body.',
66
+ };
65
67
  }
66
68
  const searchParams = handleSearchParams({ request, route });
67
69
  if (!('data' in searchParams)) {
68
- return handleHandlerResult(searchParams, response);
70
+ return handleHandlerOutputWithoutSending(searchParams, response);
69
71
  }
70
72
  const contextParams = {
73
+ pathParams: request.params,
71
74
  method: assertWrap.isEnumValue(request.method.toUpperCase(), HttpMethod),
72
75
  request,
73
76
  requestData,
@@ -81,23 +84,23 @@ export async function preHandler(request, response, service, server, attachId) {
81
84
  };
82
85
  try {
83
86
  const contextOutput = await service.createContext?.(contextParams);
84
- if (contextOutput?.reject) {
85
- service.logger.error(new RestVirHandlerError(route, `Context creation rejected: '${request.originalUrl}'`));
86
- return handleHandlerResult({
87
- body: contextOutput.reject.responseErrorMessage,
88
- statusCode: contextOutput.reject.statusCode,
89
- headers: contextOutput.reject.headers,
90
- }, response);
91
- }
92
87
  if (!request.restVirContext) {
93
88
  request.restVirContext = {};
94
89
  }
95
90
  request.restVirContext[attachId] = {
96
- context: contextOutput?.context,
91
+ context: contextOutput?.reject ? undefined : contextOutput?.context,
97
92
  requestData,
98
93
  protocols,
99
94
  searchParams: searchParams.data,
100
95
  };
96
+ if (contextOutput?.reject) {
97
+ service.logger.error(new RestVirHandlerError(route, `Context creation rejected: '${request.originalUrl}'`));
98
+ return handleHandlerOutputWithoutSending({
99
+ body: contextOutput.reject.responseErrorMessage,
100
+ statusCode: contextOutput.reject.statusCode,
101
+ headers: contextOutput.reject.headers,
102
+ }, response);
103
+ }
101
104
  return undefined;
102
105
  }
103
106
  catch (error) {
@@ -0,0 +1,17 @@
1
+ import { type HttpStatus, type SelectFrom } from '@augment-vir/common';
2
+ import { type GenericServiceImplementation, type PostHook, type RunningServerInfo } from '@rest-vir/implement-service';
3
+ import { type EndpointHandlerParams, type HandledOutput } from './endpoint-handler.js';
4
+ export declare function runPostHook(this: void, { request, response, attachId, server, postHook, service, originalBody, originalStatus, }: Readonly<Omit<EndpointHandlerParams, 'route'> & {
5
+ attachId: string;
6
+ server: Readonly<RunningServerInfo>;
7
+ postHook: PostHook;
8
+ originalBody: unknown;
9
+ originalStatus: HttpStatus;
10
+ service: Readonly<SelectFrom<GenericServiceImplementation, {
11
+ webSockets: true;
12
+ endpoints: true;
13
+ serviceName: true;
14
+ serviceOrigin: true;
15
+ requiredClientOrigin: true;
16
+ }>>;
17
+ }>): Promise<HandledOutput>;
@@ -0,0 +1,59 @@
1
+ import { assert, assertWrap } from '@augment-vir/assert';
2
+ import { matchUrlToService } from '@rest-vir/define-service';
3
+ import { HttpMethod, } from '@rest-vir/implement-service';
4
+ export async function runPostHook({ request, response, attachId, server, postHook, service, originalBody, originalStatus, }) {
5
+ const restVirContext = request.restVirContext?.[attachId];
6
+ assert.isDefined(restVirContext, 'restVirContext is not defined');
7
+ const context = restVirContext.context;
8
+ const requestData = restVirContext.requestData;
9
+ const searchParams = restVirContext.searchParams;
10
+ const pathMatch = matchUrlToService(service, request.originalUrl);
11
+ /* node:coverage ignore next 10 */
12
+ if (!pathMatch) {
13
+ return undefined;
14
+ }
15
+ const endpointDefinition = pathMatch.endpointPath
16
+ ? service.endpoints[pathMatch.endpointPath]
17
+ : undefined;
18
+ const webSocketDefinition = request.ws && pathMatch.webSocketPath
19
+ ? service.webSockets[pathMatch.webSocketPath]
20
+ : undefined;
21
+ const postHookParams = {
22
+ pathParams: request.params,
23
+ method: assertWrap.isEnumValue(request.method.toUpperCase(), HttpMethod),
24
+ request,
25
+ requestData,
26
+ requestHeaders: request.headers,
27
+ response,
28
+ service,
29
+ endpointDefinition,
30
+ webSocketDefinition,
31
+ context,
32
+ searchParams,
33
+ server,
34
+ originalResponseData: originalBody,
35
+ originalStatus,
36
+ };
37
+ const result = await postHook(postHookParams);
38
+ if (result) {
39
+ return {
40
+ body: 'responseErrorMessage' in result
41
+ ? result.responseErrorMessage
42
+ : 'responseData' in result
43
+ ? result.responseData
44
+ : originalBody,
45
+ statusCode: 'statusCode' in result ? result.statusCode : originalStatus,
46
+ headers: {
47
+ ...result.headers,
48
+ ...(result.dataType
49
+ ? {
50
+ 'content-type': result.dataType,
51
+ }
52
+ : {}),
53
+ },
54
+ };
55
+ }
56
+ else {
57
+ return undefined;
58
+ }
59
+ }
@@ -42,6 +42,7 @@ export declare function attachService(server: Readonly<FastifyInstance>, service
42
42
  serviceOrigin: true;
43
43
  requiredClientOrigin: true;
44
44
  logger: true;
45
+ postHook: true;
45
46
  }>>, options?: Readonly<HandleRouteOptions>): Promise<void>;
46
47
  /**
47
48
  * Merge the running Fastify server's port with the given service's origin port (if it has a port).
@@ -1,10 +1,12 @@
1
- import { check } from '@augment-vir/assert';
1
+ import { assert, check } from '@augment-vir/assert';
2
2
  import { ensureError, 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';
6
+ import { handleHandlerOutput } from '../handle-request/endpoint-handler.js';
6
7
  import { handleRoute } from '../handle-request/handle-route.js';
7
8
  import { preHandler } from '../handle-request/pre-handler.js';
9
+ import { runPostHook } from '../handle-request/run-post-hook.js';
8
10
  const endpointFastifyMethods = getEnumValues(HttpMethod).filter((value) => {
9
11
  return (
10
12
  /** Fastify doesn't support the CONNECT method. */
@@ -51,18 +53,45 @@ export async function attachService(server, service, options = {}) {
51
53
  },
52
54
  });
53
55
  }
56
+ const postHook = service.postHook;
54
57
  server.addHook('preValidation', async (request, response) => {
55
58
  try {
56
- return await preHandler(request, response, service, extractRunningServerInfo(service, server), attachId);
59
+ const preHandlerResult = await preHandler({
60
+ request,
61
+ response,
62
+ service,
63
+ server: extractRunningServerInfo(service, server),
64
+ attachId,
65
+ });
66
+ if (preHandlerResult?.statusCode && postHook) {
67
+ const postHookResult = await runPostHook({
68
+ attachId,
69
+ originalBody: preHandlerResult.body,
70
+ originalStatus: preHandlerResult.statusCode,
71
+ postHook,
72
+ request,
73
+ response,
74
+ server: extractRunningServerInfo(service, server),
75
+ service,
76
+ });
77
+ if (postHookResult) {
78
+ return handleHandlerOutput(postHookResult, response);
79
+ }
80
+ }
81
+ return handleHandlerOutput(preHandlerResult, response);
57
82
  }
58
83
  catch (error) {
59
84
  service.logger.error(ensureError(error));
60
85
  if (options.throwErrorsForExternalHandling) {
61
86
  throw error;
87
+ /* node:coverage ignore next 5 */
88
+ }
89
+ else if (response.sent) {
90
+ assert.never("Error encountered but response was already sent so there's nothing we can do about it.");
62
91
  }
63
- else if (!response.sent) {
92
+ else {
64
93
  response.statusCode = HttpStatus.InternalServerError;
65
- response.send();
94
+ return response.send();
66
95
  }
67
96
  }
68
97
  });
@@ -78,17 +107,47 @@ export async function attachService(server, service, options = {}) {
78
107
  method: endpointFastifyMethods,
79
108
  url: path,
80
109
  handler(request, response) {
81
- return handleRoute(undefined, request, response, endpoint, attachId, extractRunningServerInfo(service, server), options);
110
+ return handleRoute({
111
+ webSocket: undefined,
112
+ request,
113
+ response,
114
+ route: endpoint,
115
+ attachId,
116
+ server: extractRunningServerInfo(service, server),
117
+ options,
118
+ postHook,
119
+ service,
120
+ });
82
121
  },
83
122
  });
84
123
  server.route({
85
124
  method: HttpMethod.Get,
86
125
  url: path,
87
126
  handler(request, response) {
88
- return handleRoute(undefined, request, response, endpoint, attachId, extractRunningServerInfo(service, server), options);
127
+ return handleRoute({
128
+ webSocket: undefined,
129
+ request,
130
+ response,
131
+ route: endpoint,
132
+ attachId,
133
+ server: extractRunningServerInfo(service, server),
134
+ options,
135
+ postHook,
136
+ service,
137
+ });
89
138
  },
90
139
  wsHandler(webSocket, request) {
91
- return handleRoute(webSocket, request, undefined, webSocketDefinition, attachId, extractRunningServerInfo(service, server), options);
140
+ return handleRoute({
141
+ webSocket,
142
+ request,
143
+ response: undefined,
144
+ route: webSocketDefinition,
145
+ attachId,
146
+ server: extractRunningServerInfo(service, server),
147
+ options,
148
+ postHook,
149
+ service,
150
+ });
92
151
  },
93
152
  });
94
153
  }
@@ -100,7 +159,17 @@ export async function attachService(server, service, options = {}) {
100
159
  ],
101
160
  url: path,
102
161
  handler(request, response) {
103
- return handleRoute(undefined, request, response, endpoint, attachId, extractRunningServerInfo(service, server), options);
162
+ return handleRoute({
163
+ webSocket: undefined,
164
+ request,
165
+ response,
166
+ route: endpoint,
167
+ attachId,
168
+ server: extractRunningServerInfo(service, server),
169
+ options,
170
+ postHook,
171
+ service,
172
+ });
104
173
  },
105
174
  });
106
175
  }
@@ -112,7 +181,17 @@ export async function attachService(server, service, options = {}) {
112
181
  return response.status(HttpStatus.NotFound).send();
113
182
  },
114
183
  wsHandler(webSocket, request) {
115
- return handleRoute(webSocket, request, undefined, webSocketDefinition, attachId, extractRunningServerInfo(service, server), options);
184
+ return handleRoute({
185
+ webSocket,
186
+ request,
187
+ response: undefined,
188
+ route: webSocketDefinition,
189
+ attachId,
190
+ server: extractRunningServerInfo(service, server),
191
+ options,
192
+ postHook,
193
+ service,
194
+ });
116
195
  },
117
196
  });
118
197
  }
@@ -69,4 +69,5 @@ export declare function startService(service: Readonly<SelectFrom<GenericService
69
69
  serviceOrigin: true;
70
70
  requiredClientOrigin: true;
71
71
  logger: true;
72
+ postHook: true;
72
73
  }>>, userOptions?: Readonly<StartServiceUserOptions>, fastifyPlugins?: Readonly<FastifyPlugins>): Promise<StartServiceOutput>;
@@ -284,6 +284,7 @@ export declare function testService<const Service extends Readonly<SelectFrom<Ge
284
284
  serviceOrigin: true;
285
285
  requiredClientOrigin: true;
286
286
  logger: true;
287
+ postHook: true;
287
288
  }>>>(service: Readonly<Service>, testServiceOptions?: Readonly<Omit<PartialWithUndefined<StartServiceUserOptions>, 'workerCount' | 'preventWorkerRespawn' | ''>>): Promise<{
288
289
  /** Kill the server being tested. This should always be called after your tests are finished. */
289
290
  kill(this: void): Promise<void>;
@@ -313,6 +314,7 @@ export declare function testExistingServer<const Service extends Readonly<Select
313
314
  serviceOrigin: true;
314
315
  requiredClientOrigin: true;
315
316
  logger: true;
317
+ postHook: true;
316
318
  }>>>(server: Readonly<FastifyInstance>, service: Readonly<Service>, options?: Readonly<HandleRouteOptions & Omit<PartialWithUndefined<StartServiceOptions>, 'workerCount' | 'preventWorkerRespawn'>>): Promise<{
317
319
  /** Send a request to the service. */
318
320
  fetchEndpoint: FetchTestService<Service>;
@@ -353,6 +355,7 @@ export declare function describeService<const Service extends Readonly<SelectFro
353
355
  serviceOrigin: true;
354
356
  requiredClientOrigin: true;
355
357
  logger: true;
358
+ postHook: true;
356
359
  }>>>({ service, options, }: {
357
360
  /** The service to startup and send requests to. */
358
361
  service: Readonly<Service>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rest-vir/run-service",
3
- "version": "0.18.1",
3
+ "version": "0.19.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.16.0",
43
- "@augment-vir/common": "^31.16.0",
44
- "@augment-vir/node": "^31.16.0",
42
+ "@augment-vir/assert": "^31.19.1",
43
+ "@augment-vir/common": "^31.19.1",
44
+ "@augment-vir/node": "^31.19.1",
45
45
  "@fastify/websocket": "^11.0.2",
46
- "@rest-vir/define-service": "^0.18.1",
47
- "@rest-vir/implement-service": "^0.18.1",
46
+ "@rest-vir/define-service": "^0.19.1",
47
+ "@rest-vir/implement-service": "^0.19.1",
48
48
  "cluster-vir": "^0.1.0",
49
49
  "date-vir": "^7.3.1",
50
- "fastify": "^5.3.2",
50
+ "fastify": "^5.3.3",
51
51
  "light-my-request": "^6.6.0",
52
52
  "portfinder": "^1.0.37",
53
- "type-fest": "^4.40.1",
53
+ "type-fest": "^4.41.0",
54
54
  "url-vir": "^2.1.3"
55
55
  },
56
56
  "devDependencies": {
57
- "@augment-vir/test": "^31.16.0",
57
+ "@augment-vir/test": "^31.19.1",
58
58
  "@fastify/multipart": "^9.0.3",
59
59
  "@types/connect": "^3.4.38",
60
- "@types/node": "^22.15.3",
60
+ "@types/node": "^22.15.18",
61
61
  "@types/ws": "^8.18.1",
62
62
  "c8": "^10.1.3",
63
63
  "istanbul-smart-text-reporter": "^1.1.5",