@rest-vir/run-service 0.19.0 → 0.19.2

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
  }
@@ -11,6 +11,7 @@ import { assertValidShape } from 'object-shape-tester';
11
11
  */
12
12
  export async function handleEndpointRequest({ endpoint, request, response, attachId, server, }) {
13
13
  try {
14
+ // by this point in the request lifecycle, we know that these properties have been set.
14
15
  const restVirContext = request.restVirContext?.[attachId];
15
16
  assert.isDefined(restVirContext, 'restVirContext is not defined');
16
17
  const context = restVirContext.context;
@@ -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) {
@@ -11,6 +11,7 @@ import { assertValidShape } from 'object-shape-tester';
11
11
  * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
12
12
  */
13
13
  export async function handleWebSocketRequest({ attachId, request, implementedWebSocket, webSocket: wsWebSocket, server, }) {
14
+ // by this point in the request lifecycle, we know that these properties have been set.
14
15
  const restVirContext = request.restVirContext?.[attachId];
15
16
  assert.isDefined(restVirContext, 'restVirContext is not defined');
16
17
  const webSocket = overwriteWebSocketMethods(implementedWebSocket, wsWebSocket, WebSocketLocation.OnHost);
@@ -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>>;
@@ -1,9 +1,9 @@
1
1
  import { assertWrap } from '@augment-vir/assert';
2
- import { ensureErrorAndPrependMessage, extractErrorMessage, HttpStatus, stringify, wrapInTry, } from '@augment-vir/common';
2
+ import { ensureErrorAndPrependMessage, extractErrorMessage, getOrSet, HttpStatus, stringify, wrapInTry, } from '@augment-vir/common';
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,13 @@ 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
+ if (!request.restVirContext) {
19
+ request.restVirContext = {};
20
+ }
21
+ const attachedRestVirContext = getOrSet(request.restVirContext, attachId, () => {
22
+ return {};
23
+ });
18
24
  response.header(restVirServiceNameHeader, service.serviceName);
19
25
  const pathMatch = matchUrlToService(service, request.originalUrl);
20
26
  if (!pathMatch) {
@@ -41,15 +47,17 @@ export async function preHandler(request, response, service, server, attachId) {
41
47
  : undefined;
42
48
  if (protocolShapeError) {
43
49
  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;
50
+ return {
51
+ statusCode: HttpStatus.BadRequest,
52
+ body: 'Invalid protocol.',
53
+ };
47
54
  }
48
- const subHandlerResponse = handleHandlerResult(await handleCors({
55
+ attachedRestVirContext.protocols = protocols;
56
+ const subHandlerResponse = handleHandlerOutputWithoutSending(await handleCors({
49
57
  request,
50
58
  route,
51
59
  }), response) ||
52
- handleHandlerResult(handleRequestMethod({
60
+ handleHandlerOutputWithoutSending(handleRequestMethod({
53
61
  request,
54
62
  route,
55
63
  }), response);
@@ -59,15 +67,19 @@ export async function preHandler(request, response, service, server, attachId) {
59
67
  const requestData = wrapInTry(() => extractRequestData(request.body, request.headers, route));
60
68
  if (requestData instanceof Error) {
61
69
  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;
70
+ return {
71
+ statusCode: HttpStatus.BadRequest,
72
+ body: 'Invalid body.',
73
+ };
65
74
  }
75
+ attachedRestVirContext.requestData = requestData;
66
76
  const searchParams = handleSearchParams({ request, route });
67
77
  if (!('data' in searchParams)) {
68
- return handleHandlerResult(searchParams, response);
78
+ return handleHandlerOutputWithoutSending(searchParams, response);
69
79
  }
80
+ attachedRestVirContext.searchParams = searchParams.data;
70
81
  const contextParams = {
82
+ pathParams: request.params,
71
83
  method: assertWrap.isEnumValue(request.method.toUpperCase(), HttpMethod),
72
84
  request,
73
85
  requestData,
@@ -83,21 +95,13 @@ export async function preHandler(request, response, service, server, attachId) {
83
95
  const contextOutput = await service.createContext?.(contextParams);
84
96
  if (contextOutput?.reject) {
85
97
  service.logger.error(new RestVirHandlerError(route, `Context creation rejected: '${request.originalUrl}'`));
86
- return handleHandlerResult({
98
+ return handleHandlerOutputWithoutSending({
87
99
  body: contextOutput.reject.responseErrorMessage,
88
100
  statusCode: contextOutput.reject.statusCode,
89
101
  headers: contextOutput.reject.headers,
90
102
  }, response);
91
103
  }
92
- if (!request.restVirContext) {
93
- request.restVirContext = {};
94
- }
95
- request.restVirContext[attachId] = {
96
- context: contextOutput?.context,
97
- requestData,
98
- protocols,
99
- searchParams: searchParams.data,
100
- };
104
+ attachedRestVirContext.context = contextOutput?.context;
101
105
  return undefined;
102
106
  }
103
107
  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
+ }
@@ -3,15 +3,23 @@ import { type BaseSearchParams, type MinimalService } from '@rest-vir/define-ser
3
3
  import { type GenericServiceImplementation, type RunningServerInfo } from '@rest-vir/implement-service';
4
4
  import { type FastifyInstance } from 'fastify';
5
5
  import { type HandleRouteOptions } from '../handle-request/endpoint-handler.js';
6
+ /**
7
+ * Context attached to each fastify request object.
8
+ *
9
+ * @category Internal
10
+ * @category Package : @rest-vir/run-service
11
+ * @package [`@rest-vir/run-service`](https://www.npmjs.com/package/@rest-vir/run-service)
12
+ */
13
+ export type RestVirRequestContext = {
14
+ context: unknown;
15
+ requestData: unknown;
16
+ protocols: string[];
17
+ searchParams: BaseSearchParams;
18
+ };
6
19
  declare module 'fastify' {
7
20
  interface FastifyRequest {
8
21
  restVirContext: {
9
- [AttachId in string]: {
10
- context: unknown;
11
- requestData: unknown;
12
- protocols: string[];
13
- searchParams: BaseSearchParams;
14
- };
22
+ [AttachId in string]: Partial<RestVirRequestContext>;
15
23
  } | undefined;
16
24
  }
17
25
  }
@@ -1,12 +1,12 @@
1
- import { assertWrap, check } from '@augment-vir/assert';
2
- import { ensureError, extractErrorMessage, getEnumValues, getObjectTypedKeys, HttpMethod, HttpStatus, isErrorHttpStatus, randomString, } from '@augment-vir/common';
1
+ import { assert, check } from '@augment-vir/assert';
2
+ import { ensureError, extractErrorMessage, getEnumValues, getObjectTypedKeys, HttpMethod, HttpStatus, randomString, } from '@augment-vir/common';
3
3
  import fastifyWs from '@fastify/websocket';
4
- import { matchUrlToService, } from '@rest-vir/define-service';
5
4
  import { RestVirHandlerError, } from '@rest-vir/implement-service';
6
5
  import { buildUrl, parseUrl } from 'url-vir';
6
+ import { handleHandlerOutput } from '../handle-request/endpoint-handler.js';
7
7
  import { handleRoute } from '../handle-request/handle-route.js';
8
8
  import { preHandler } from '../handle-request/pre-handler.js';
9
- import { setResponseHeaders } from '../util/headers.js';
9
+ import { runPostHook } from '../handle-request/run-post-hook.js';
10
10
  const endpointFastifyMethods = getEnumValues(HttpMethod).filter((value) => {
11
11
  return (
12
12
  /** Fastify doesn't support the CONNECT method. */
@@ -53,94 +53,48 @@ export async function attachService(server, service, options = {}) {
53
53
  },
54
54
  });
55
55
  }
56
+ const postHook = service.postHook;
56
57
  server.addHook('preValidation', async (request, response) => {
57
58
  try {
58
- 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);
59
82
  }
60
83
  catch (error) {
61
84
  service.logger.error(ensureError(error));
62
85
  if (options.throwErrorsForExternalHandling) {
63
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.");
64
91
  }
65
- else if (!response.sent) {
92
+ else {
66
93
  response.statusCode = HttpStatus.InternalServerError;
67
- response.send();
94
+ return response.send();
68
95
  }
69
96
  }
70
97
  });
71
- const postHook = service.postHook;
72
- if (postHook) {
73
- server.addHook('onSend', async (request, response, body) => {
74
- /* node:coverage ignore next 4 */
75
- const restVirContext = request.restVirContext?.[attachId];
76
- if (!restVirContext) {
77
- return undefined;
78
- }
79
- const context = restVirContext.context;
80
- const requestData = restVirContext.requestData;
81
- const searchParams = restVirContext.searchParams;
82
- const pathMatch = matchUrlToService(service, request.originalUrl);
83
- /* node:coverage ignore next 10 */
84
- if (!pathMatch) {
85
- return undefined;
86
- }
87
- const endpointDefinition = pathMatch.endpointPath
88
- ? service.endpoints[pathMatch.endpointPath]
89
- : undefined;
90
- const webSocketDefinition = request.ws && pathMatch.webSocketPath
91
- ? service.webSockets[pathMatch.webSocketPath]
92
- : undefined;
93
- const postHookParams = {
94
- context,
95
- method: assertWrap.isEnumValue(request.method.toUpperCase(), HttpMethod),
96
- request,
97
- requestData,
98
- requestHeaders: request.headers,
99
- response,
100
- service,
101
- endpointDefinition: endpointDefinition,
102
- webSocketDefinition: webSocketDefinition,
103
- server: extractRunningServerInfo(service, server),
104
- searchParams,
105
- originalResponseData: body,
106
- originalStatus: response.statusCode,
107
- };
108
- const result = await postHook(postHookParams);
109
- if (result) {
110
- if (result.headers) {
111
- setResponseHeaders(response, result.headers);
112
- }
113
- if (result.dataType) {
114
- setResponseHeaders(response, {
115
- 'content-type': result.dataType,
116
- });
117
- }
118
- if (result.statusCode) {
119
- response.status(result.statusCode);
120
- }
121
- if (isErrorHttpStatus(result.statusCode ?? response.statusCode) &&
122
- 'responseErrorMessage' in result) {
123
- if (result.responseErrorMessage == undefined) {
124
- /** Clear the body. */
125
- return null;
126
- }
127
- else {
128
- return result.responseErrorMessage;
129
- }
130
- }
131
- else if ('responseData' in result) {
132
- if (result.responseData == undefined) {
133
- /** Clear the body. */
134
- return null;
135
- }
136
- else {
137
- return result.responseData;
138
- }
139
- }
140
- }
141
- return undefined;
142
- });
143
- }
144
98
  const allPaths = new Set([
145
99
  ...getObjectTypedKeys(service.webSockets),
146
100
  ...getObjectTypedKeys(service.endpoints),
@@ -153,17 +107,47 @@ export async function attachService(server, service, options = {}) {
153
107
  method: endpointFastifyMethods,
154
108
  url: path,
155
109
  handler(request, response) {
156
- 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
+ });
157
121
  },
158
122
  });
159
123
  server.route({
160
124
  method: HttpMethod.Get,
161
125
  url: path,
162
126
  handler(request, response) {
163
- 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
+ });
164
138
  },
165
139
  wsHandler(webSocket, request) {
166
- 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
+ });
167
151
  },
168
152
  });
169
153
  }
@@ -175,7 +159,17 @@ export async function attachService(server, service, options = {}) {
175
159
  ],
176
160
  url: path,
177
161
  handler(request, response) {
178
- 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
+ });
179
173
  },
180
174
  });
181
175
  }
@@ -187,7 +181,17 @@ export async function attachService(server, service, options = {}) {
187
181
  return response.status(HttpStatus.NotFound).send();
188
182
  },
189
183
  wsHandler(webSocket, request) {
190
- 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
+ });
191
195
  },
192
196
  });
193
197
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rest-vir/run-service",
3
- "version": "0.19.0",
3
+ "version": "0.19.2",
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,12 +39,12 @@
39
39
  "test:update": "npm test update"
40
40
  },
41
41
  "dependencies": {
42
- "@augment-vir/assert": "^31.19.1",
43
- "@augment-vir/common": "^31.19.1",
44
- "@augment-vir/node": "^31.19.1",
42
+ "@augment-vir/assert": "^31.20.0",
43
+ "@augment-vir/common": "^31.20.0",
44
+ "@augment-vir/node": "^31.20.0",
45
45
  "@fastify/websocket": "^11.0.2",
46
- "@rest-vir/define-service": "^0.19.0",
47
- "@rest-vir/implement-service": "^0.19.0",
46
+ "@rest-vir/define-service": "^0.19.2",
47
+ "@rest-vir/implement-service": "^0.19.2",
48
48
  "cluster-vir": "^0.1.0",
49
49
  "date-vir": "^7.3.1",
50
50
  "fastify": "^5.3.3",
@@ -54,10 +54,10 @@
54
54
  "url-vir": "^2.1.3"
55
55
  },
56
56
  "devDependencies": {
57
- "@augment-vir/test": "^31.19.1",
57
+ "@augment-vir/test": "^31.20.0",
58
58
  "@fastify/multipart": "^9.0.3",
59
59
  "@types/connect": "^3.4.38",
60
- "@types/node": "^22.15.18",
60
+ "@types/node": "^22.15.21",
61
61
  "@types/ws": "^8.18.1",
62
62
  "c8": "^10.1.3",
63
63
  "istanbul-smart-text-reporter": "^1.1.5",