@rest-vir/implement-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.
- package/dist/implementation/generic-service-implementation.d.ts +2 -0
- package/dist/implementation/implement-endpoint.d.ts +2 -1
- package/dist/implementation/implement-service.d.ts +10 -2
- package/dist/implementation/implement-service.js +2 -1
- package/dist/implementation/post-hook.d.ts +25 -0
- package/dist/implementation/post-hook.js +1 -0
- package/dist/implementation/service-context-init.d.ts +6 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/util/types.d.ts +10 -0
- package/dist/util/types.js +2 -0
- package/package.json +8 -8
|
@@ -3,6 +3,7 @@ import { type EndpointDefinition, type EndpointPathBase, type GenericEndpointDef
|
|
|
3
3
|
import { type ServiceLogger } from '../util/service-logger.js';
|
|
4
4
|
import { type EndpointImplementation } from './implement-endpoint.js';
|
|
5
5
|
import { type WebSocketImplementation } from './implement-web-socket.js';
|
|
6
|
+
import { type PostHook } from './post-hook.js';
|
|
6
7
|
import { type ContextInit } from './service-context-init.js';
|
|
7
8
|
/**
|
|
8
9
|
* A fully implemented endpoint.
|
|
@@ -30,6 +31,7 @@ export type GenericServiceImplementation = Omit<ServiceDefinition, 'endpoints' |
|
|
|
30
31
|
createContext: ContextInit<any, any, any, any> | undefined;
|
|
31
32
|
logger: ServiceLogger;
|
|
32
33
|
customHeaders: string[];
|
|
34
|
+
postHook: PostHook | undefined;
|
|
33
35
|
};
|
|
34
36
|
/**
|
|
35
37
|
* A fully implemented WebSocket.
|
|
@@ -4,6 +4,7 @@ import { type IncomingHttpHeaders, type OutgoingHttpHeaders } from 'node:http';
|
|
|
4
4
|
import { type IsEqual, type IsNever } from 'type-fest';
|
|
5
5
|
import { type ServerRequest, type ServerResponse } from '../util/data.js';
|
|
6
6
|
import { type ServiceLogger } from '../util/service-logger.js';
|
|
7
|
+
import { type ReplaceUndefinedWithEmptyObject } from '../util/types.js';
|
|
7
8
|
/**
|
|
8
9
|
* The part of {@link EndpointImplementationOutput} allowed for error responses.
|
|
9
10
|
*
|
|
@@ -62,7 +63,7 @@ export type EndpointImplementationParams<Context = any, SpecificEndpoint extends
|
|
|
62
63
|
request: ServerRequest;
|
|
63
64
|
response: ServerResponse;
|
|
64
65
|
log: Readonly<ServiceLogger>;
|
|
65
|
-
searchParams: SpecificEndpoint extends NoParam ? BaseSearchParams : Exclude<SpecificEndpoint, NoParam>['SearchParamsType']
|
|
66
|
+
searchParams: ReplaceUndefinedWithEmptyObject<SpecificEndpoint extends NoParam ? BaseSearchParams : Exclude<SpecificEndpoint, NoParam>['SearchParamsType']>;
|
|
66
67
|
/** The actual running server info. */
|
|
67
68
|
server: RunningServerInfo;
|
|
68
69
|
};
|
|
@@ -5,6 +5,7 @@ import { type ServiceLogger, type ServiceLoggerOption } from '../util/service-lo
|
|
|
5
5
|
import { type ImplementedEndpoint, type ImplementedWebSocket } from './generic-service-implementation.js';
|
|
6
6
|
import { type EndpointImplementations } from './implement-endpoint.js';
|
|
7
7
|
import { type WebSocketImplementations } from './implement-web-socket.js';
|
|
8
|
+
import { type PostHook } from './post-hook.js';
|
|
8
9
|
import { type ContextInit } from './service-context-init.js';
|
|
9
10
|
/**
|
|
10
11
|
* A user-defined endpoint error handler for service (and its endpoints) errors.
|
|
@@ -51,7 +52,13 @@ export type ServiceImplementationsParams<Context, ServiceName extends string, En
|
|
|
51
52
|
webSockets?: never;
|
|
52
53
|
} : {
|
|
53
54
|
webSockets: WebSocketImplementations<NoInfer<Context>, NoInfer<ServiceName>, NoInfer<WebSocketsInit>>;
|
|
54
|
-
})
|
|
55
|
+
}) & {
|
|
56
|
+
/**
|
|
57
|
+
* Fired after every request resolves, before it is sent. This hooks into Fastify with the
|
|
58
|
+
* `onSend` hook.
|
|
59
|
+
*/
|
|
60
|
+
postHook?: PostHook<Context, ServiceName, EndpointsInit, WebSocketsInit> | undefined;
|
|
61
|
+
};
|
|
55
62
|
/**
|
|
56
63
|
* Creates an implemented service that is fully ready to be run as a server by attaching endpoint
|
|
57
64
|
* implementations to the given {@link ServiceDefinition}.
|
|
@@ -62,7 +69,7 @@ export type ServiceImplementationsParams<Context, ServiceName extends string, En
|
|
|
62
69
|
* @category Package : @rest-vir/implement-service
|
|
63
70
|
* @package [`@rest-vir/implement-service`](https://www.npmjs.com/package/@rest-vir/implement-service)
|
|
64
71
|
*/
|
|
65
|
-
export declare function implementService<const ServiceName extends string,
|
|
72
|
+
export declare function implementService<const ServiceName extends string, EndpointsInit extends BaseServiceEndpointsInit, WebSocketsInit extends BaseServiceWebSocketsInit, Context = undefined>(
|
|
66
73
|
/** Init must be first so that TypeScript can infer the type for `Context`. */
|
|
67
74
|
{ service, createContext, logger, customHeaders, }: ServiceImplementationInit<Context, ServiceName, EndpointsInit, WebSocketsInit>): (implementations: ServiceImplementationsParams<NoInfer<Context>, NoInfer<ServiceName>, NoInfer<EndpointsInit>, NoInfer<WebSocketsInit>>) => ServiceImplementation<NoInfer<Context>, ServiceName, EndpointsInit, WebSocketsInit>;
|
|
68
75
|
/**
|
|
@@ -83,6 +90,7 @@ export type ServiceImplementation<Context = undefined, ServiceName extends strin
|
|
|
83
90
|
createContext: ContextInit<Context, ServiceName, EndpointsInit, WebSocketsInit> | undefined;
|
|
84
91
|
logger: ServiceLogger;
|
|
85
92
|
customHeaders: string[];
|
|
93
|
+
postHook: PostHook | undefined;
|
|
86
94
|
};
|
|
87
95
|
/**
|
|
88
96
|
* A type util that converts a {@link ServiceDefinition} instance type into its companion
|
|
@@ -16,7 +16,7 @@ import { assertValidWebSocketImplementations, } from './implement-web-socket.js'
|
|
|
16
16
|
export function implementService(
|
|
17
17
|
/** Init must be first so that TypeScript can infer the type for `Context`. */
|
|
18
18
|
{ service, createContext, logger, customHeaders, }) {
|
|
19
|
-
return ({ endpoints: endpointImplementations, webSockets: webSocketImplementations }) => {
|
|
19
|
+
return ({ endpoints: endpointImplementations, webSockets: webSocketImplementations, postHook, }) => {
|
|
20
20
|
assertValidEndpointImplementations(service, endpointImplementations || {});
|
|
21
21
|
assertValidWebSocketImplementations(service, webSocketImplementations || {});
|
|
22
22
|
const endpoints = mapObjectValues(service.endpoints, (endpointPath, endpoint) => {
|
|
@@ -55,6 +55,7 @@ export function implementService(
|
|
|
55
55
|
webSockets,
|
|
56
56
|
createContext,
|
|
57
57
|
logger: createServiceLogger(logger),
|
|
58
|
+
postHook: postHook || undefined,
|
|
58
59
|
};
|
|
59
60
|
Object.defineProperties(serviceImplementation, {
|
|
60
61
|
ContextType: {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type HttpStatus, type MaybePromise, type Values } from '@augment-vir/common';
|
|
2
|
+
import { type BaseServiceEndpointsInit, type BaseServiceWebSocketsInit, type EndpointPathBase, type NoParam, type WithFinalEndpointProps } from '@rest-vir/define-service';
|
|
3
|
+
import { type EndpointImplementationOutput } from './implement-endpoint.js';
|
|
4
|
+
import { type ContextInitParams } from './service-context-init.js';
|
|
5
|
+
/**
|
|
6
|
+
* Params for {@link PostHook}.
|
|
7
|
+
*
|
|
8
|
+
* @category Internal
|
|
9
|
+
* @category Package : @rest-vir/implement-service
|
|
10
|
+
* @package [`@rest-vir/implement-service`](https://www.npmjs.com/package/@rest-vir/implement-service)
|
|
11
|
+
*/
|
|
12
|
+
export type PostHookParams<Context = any, ServiceName extends string = any, EndpointsInit extends BaseServiceEndpointsInit | NoParam = NoParam, WebSocketsInit extends BaseServiceWebSocketsInit | NoParam = NoParam> = ContextInitParams<ServiceName, EndpointsInit, WebSocketsInit> & {
|
|
13
|
+
originalResponseData: EndpointsInit extends NoParam ? unknown : WithFinalEndpointProps<Values<EndpointsInit>, Extract<keyof EndpointsInit, EndpointPathBase>>['ResponseType'];
|
|
14
|
+
originalStatus: HttpStatus;
|
|
15
|
+
/** This will be `undefined` if your `createContext` method rejects the request. */
|
|
16
|
+
context: Context | undefined;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Type for `ServiceImplementationsParams.postHook`.
|
|
20
|
+
*
|
|
21
|
+
* @category Internal
|
|
22
|
+
* @category Package : @rest-vir/implement-service
|
|
23
|
+
* @package [`@rest-vir/implement-service`](https://www.npmjs.com/package/@rest-vir/implement-service)
|
|
24
|
+
*/
|
|
25
|
+
export type PostHook<Context = any, ServiceName extends string = any, EndpointsInit extends BaseServiceEndpointsInit | NoParam = NoParam, WebSocketsInit extends BaseServiceWebSocketsInit | NoParam = NoParam> = (params: PostHookParams<Context, ServiceName, EndpointsInit, WebSocketsInit>) => MaybePromise<Partial<EndpointImplementationOutput> | undefined | void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type HttpMethod, type MaybePromise, type Values } from '@augment-vir/common';
|
|
2
|
-
import { type BaseSearchParams, type BaseServiceEndpointsInit, type BaseServiceWebSocketsInit, type EndpointDefinition, type EndpointPathBase, type MinimalService, type NoParam, type WebSocketDefinition, type WithFinalEndpointProps, type WithFinalWebSocketProps } from '@rest-vir/define-service';
|
|
2
|
+
import { type BaseSearchParams, type BaseServiceEndpointsInit, type BaseServiceWebSocketsInit, type EndpointDefinition, type EndpointPathBase, type MinimalService, type NoParam, type PathParams, type WebSocketDefinition, type WithFinalEndpointProps, type WithFinalWebSocketProps } from '@rest-vir/define-service';
|
|
3
3
|
import { type IncomingHttpHeaders } from 'node:http';
|
|
4
4
|
import { type RequireExactlyOne } from 'type-fest';
|
|
5
5
|
import { type ServerRequest, type ServerResponse } from '../util/data.js';
|
|
6
|
+
import { type ReplaceUndefinedWithEmptyObject } from '../util/types.js';
|
|
6
7
|
import { type EndpointImplementationErrorOutput, type RunningServerInfo } from './implement-endpoint.js';
|
|
7
8
|
/**
|
|
8
9
|
* Output of {@link ContextInit}.
|
|
@@ -27,7 +28,7 @@ export type ContextInitOutput<Context> = RequireExactlyOne<{
|
|
|
27
28
|
* @category Package : @rest-vir/implement-service
|
|
28
29
|
* @package [`@rest-vir/implement-service`](https://www.npmjs.com/package/@rest-vir/implement-service)
|
|
29
30
|
*/
|
|
30
|
-
export type ContextInit<Context, ServiceName extends string, EndpointsInit extends BaseServiceEndpointsInit | NoParam, WebSocketsInit extends BaseServiceWebSocketsInit | NoParam> = (params: Readonly<
|
|
31
|
+
export type ContextInit<Context, ServiceName extends string, EndpointsInit extends BaseServiceEndpointsInit | NoParam, WebSocketsInit extends BaseServiceWebSocketsInit | NoParam> = (params: Readonly<ContextInitParams<ServiceName, EndpointsInit, WebSocketsInit>>) => MaybePromise<ContextInitOutput<Context>>;
|
|
31
32
|
/**
|
|
32
33
|
* Parameters for {@link ContextInit}.
|
|
33
34
|
*
|
|
@@ -35,8 +36,9 @@ export type ContextInit<Context, ServiceName extends string, EndpointsInit exten
|
|
|
35
36
|
* @category Package : @rest-vir/implement-service
|
|
36
37
|
* @package [`@rest-vir/implement-service`](https://www.npmjs.com/package/@rest-vir/implement-service)
|
|
37
38
|
*/
|
|
38
|
-
export type
|
|
39
|
-
|
|
39
|
+
export type ContextInitParams<ServiceName extends string = any, EndpointsInit extends BaseServiceEndpointsInit | NoParam = NoParam, WebSocketsInit extends BaseServiceWebSocketsInit | NoParam = NoParam> = {
|
|
40
|
+
pathParams: EndpointsInit extends NoParam ? Readonly<Record<string, string>> : PathParams<WithFinalWebSocketProps<Values<WebSocketsInit>, any>['path']> extends string ? Readonly<Record<PathParams<WithFinalWebSocketProps<Values<WebSocketsInit>, any>['path']>, string>> : Readonly<Record<string, string>>;
|
|
41
|
+
searchParams: ReplaceUndefinedWithEmptyObject<(WebSocketsInit extends NoParam ? BaseSearchParams | undefined : WithFinalWebSocketProps<Values<WebSocketsInit>, any>['SearchParamsType']) | (EndpointsInit extends NoParam ? BaseSearchParams | undefined : WithFinalEndpointProps<Values<EndpointsInit>, any>['SearchParamsType'])>;
|
|
40
42
|
service: MinimalService<ServiceName>;
|
|
41
43
|
requestHeaders: IncomingHttpHeaders;
|
|
42
44
|
method: HttpMethod;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ export * from './implementation/generic-service-implementation.js';
|
|
|
3
3
|
export * from './implementation/implement-endpoint.js';
|
|
4
4
|
export * from './implementation/implement-service.js';
|
|
5
5
|
export * from './implementation/implement-web-socket.js';
|
|
6
|
+
export * from './implementation/post-hook.js';
|
|
6
7
|
export * from './implementation/service-context-init.js';
|
|
7
8
|
export * from './util/data.js';
|
|
8
9
|
export * from './util/handler.error.js';
|
|
9
10
|
export * from './util/service-logger.js';
|
|
11
|
+
export * from './util/types.js';
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,9 @@ export * from './implementation/generic-service-implementation.js';
|
|
|
3
3
|
export * from './implementation/implement-endpoint.js';
|
|
4
4
|
export * from './implementation/implement-service.js';
|
|
5
5
|
export * from './implementation/implement-web-socket.js';
|
|
6
|
+
export * from './implementation/post-hook.js';
|
|
6
7
|
export * from './implementation/service-context-init.js';
|
|
7
8
|
export * from './util/data.js';
|
|
8
9
|
export * from './util/handler.error.js';
|
|
9
10
|
export * from './util/service-logger.js';
|
|
11
|
+
export * from './util/types.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type EmptyObject } from 'type-fest';
|
|
2
|
+
/**
|
|
3
|
+
* Removes `undefined` unions from the given type and replaces it with `EmptyObject`. This is used
|
|
4
|
+
* specifically for SearchParamsType.
|
|
5
|
+
*
|
|
6
|
+
* @category Internal
|
|
7
|
+
* @category Package : @rest-vir/implement-service
|
|
8
|
+
* @package [`@rest-vir/implement-service`](https://www.npmjs.com/package/@rest-vir/implement-service)
|
|
9
|
+
*/
|
|
10
|
+
export type ReplaceUndefinedWithEmptyObject<T> = T extends undefined ? Exclude<T, undefined> | EmptyObject : T;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rest-vir/implement-service",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "Implement a service defined by @rest-vir/define-service.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rest",
|
|
@@ -39,17 +39,17 @@
|
|
|
39
39
|
"test:update": "npm test update"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@augment-vir/assert": "^31.
|
|
43
|
-
"@augment-vir/common": "^31.
|
|
44
|
-
"@rest-vir/define-service": "^0.
|
|
42
|
+
"@augment-vir/assert": "^31.19.1",
|
|
43
|
+
"@augment-vir/common": "^31.19.1",
|
|
44
|
+
"@rest-vir/define-service": "^0.19.1",
|
|
45
45
|
"@types/ws": "^8.18.1",
|
|
46
|
-
"fastify": "^5.3.
|
|
46
|
+
"fastify": "^5.3.3",
|
|
47
47
|
"path-to-regexp": "^8.2.0",
|
|
48
|
-
"type-fest": "^4.
|
|
48
|
+
"type-fest": "^4.41.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@augment-vir/test": "^31.
|
|
52
|
-
"@types/node": "^22.15.
|
|
51
|
+
"@augment-vir/test": "^31.19.1",
|
|
52
|
+
"@types/node": "^22.15.18",
|
|
53
53
|
"c8": "^10.1.3",
|
|
54
54
|
"istanbul-smart-text-reporter": "^1.1.5",
|
|
55
55
|
"markdown-code-example-inserter": "^3.0.3",
|