@rest-vir/implement-service 0.14.0 → 0.15.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 +1 -1
- package/dist/implementation/implement-endpoint.d.ts +3 -3
- package/dist/implementation/implement-service.d.ts +14 -9
- package/dist/implementation/implement-service.js +56 -45
- package/dist/implementation/implement-web-socket.d.ts +1 -1
- package/dist/implementation/service-context-init.d.ts +2 -2
- package/package.json +7 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Overwrite } from '@augment-vir/common';
|
|
2
|
-
import { EndpointDefinition, EndpointPathBase,
|
|
2
|
+
import { type EndpointDefinition, type EndpointPathBase, type GenericEndpointDefinition, type GenericWebSocketDefinition, type NoParam, type ServiceDefinition, type WebSocketDefinition } from '@rest-vir/define-service';
|
|
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';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ErrorHttpStatusCategories, ExtractKeysWithMatchingValues, HttpMethod, HttpStatusByCategory, MaybePromise, SuccessHttpStatusCategories } from '@augment-vir/common';
|
|
2
|
-
import { BaseSearchParams, BaseServiceEndpointsInit, EndpointDefinition, EndpointInit, EndpointPathBase, MinimalService, NoParam,
|
|
1
|
+
import { type ErrorHttpStatusCategories, type ExtractKeysWithMatchingValues, type HttpMethod, type HttpStatusByCategory, type MaybePromise, type SuccessHttpStatusCategories } from '@augment-vir/common';
|
|
2
|
+
import { type BaseSearchParams, type BaseServiceEndpointsInit, type EndpointDefinition, type EndpointInit, type EndpointPathBase, type MinimalService, type NoParam, type PathParams, type ServiceDefinition, type WithFinalEndpointProps } from '@rest-vir/define-service';
|
|
3
3
|
import { type IncomingHttpHeaders, type OutgoingHttpHeaders } from 'node:http';
|
|
4
4
|
import { type IsEqual, type IsNever } from 'type-fest';
|
|
5
|
-
import { ServerRequest, type ServerResponse } from '../util/data.js';
|
|
5
|
+
import { type ServerRequest, type ServerResponse } from '../util/data.js';
|
|
6
6
|
import { type ServiceLogger } from '../util/service-logger.js';
|
|
7
7
|
/**
|
|
8
8
|
* The part of {@link EndpointImplementationOutput} allowed for error responses.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type KeyCount, type MaybePromise } from '@augment-vir/common';
|
|
2
|
-
import { BaseServiceEndpointsInit, EndpointPathBase, NoParam,
|
|
2
|
+
import { type BaseServiceEndpointsInit, type BaseServiceWebSocketsInit, type EndpointPathBase, type NoParam, type ServiceDefinition } from '@rest-vir/define-service';
|
|
3
3
|
import { type IsEqual, type OmitIndexSignature } from 'type-fest';
|
|
4
|
-
import {
|
|
4
|
+
import { type ServiceLogger, type ServiceLoggerOption } from '../util/service-logger.js';
|
|
5
5
|
import { type ImplementedEndpoint, type ImplementedWebSocket } from './generic-service-implementation.js';
|
|
6
6
|
import { type EndpointImplementations } from './implement-endpoint.js';
|
|
7
|
-
import { WebSocketImplementations } from './implement-web-socket.js';
|
|
7
|
+
import { type WebSocketImplementations } from './implement-web-socket.js';
|
|
8
8
|
import { type ContextInit } from './service-context-init.js';
|
|
9
9
|
/**
|
|
10
10
|
* A user-defined endpoint error handler for service (and its endpoints) errors.
|
|
@@ -21,7 +21,7 @@ export type CustomErrorHandler = (error: Error) => MaybePromise<void>;
|
|
|
21
21
|
* @category Package : @rest-vir/implement-service
|
|
22
22
|
* @package [`@rest-vir/implement-service`](https://www.npmjs.com/package/@rest-vir/implement-service)
|
|
23
23
|
*/
|
|
24
|
-
export type ServiceImplementationInit<ServiceName extends string, EndpointsInit extends BaseServiceEndpointsInit, WebSocketsInit extends BaseServiceWebSocketsInit> = {
|
|
24
|
+
export type ServiceImplementationInit<Context, ServiceName extends string, EndpointsInit extends BaseServiceEndpointsInit, WebSocketsInit extends BaseServiceWebSocketsInit> = {
|
|
25
25
|
/** Set all custom headers that you'll be using here so that CORS will allow them. */
|
|
26
26
|
customHeaders?: string[];
|
|
27
27
|
service: ServiceDefinition<ServiceName, EndpointsInit, WebSocketsInit>;
|
|
@@ -31,7 +31,11 @@ export type ServiceImplementationInit<ServiceName extends string, EndpointsInit
|
|
|
31
31
|
* keys will fallback to the efault logger.
|
|
32
32
|
*/
|
|
33
33
|
logger?: ServiceLoggerOption;
|
|
34
|
-
}
|
|
34
|
+
} & (IsEqual<Context, undefined> extends true ? {
|
|
35
|
+
createContext?: undefined | ContextInit<Context, NoInfer<ServiceName>, NoInfer<EndpointsInit>, NoInfer<WebSocketsInit>>;
|
|
36
|
+
} : {
|
|
37
|
+
createContext: ContextInit<Context, NoInfer<ServiceName>, NoInfer<EndpointsInit>, NoInfer<WebSocketsInit>>;
|
|
38
|
+
});
|
|
35
39
|
/**
|
|
36
40
|
* Parameters for implementations for {@link implementService}.
|
|
37
41
|
*
|
|
@@ -52,15 +56,15 @@ export type ServiceImplementationsParams<Context, ServiceName extends string, En
|
|
|
52
56
|
* Creates an implemented service that is fully ready to be run as a server by attaching endpoint
|
|
53
57
|
* implementations to the given {@link ServiceDefinition}.
|
|
54
58
|
*
|
|
55
|
-
* This
|
|
59
|
+
* This should _only_ be run in backend code.
|
|
56
60
|
*
|
|
57
61
|
* @category Implement Service
|
|
58
62
|
* @category Package : @rest-vir/implement-service
|
|
59
63
|
* @package [`@rest-vir/implement-service`](https://www.npmjs.com/package/@rest-vir/implement-service)
|
|
60
64
|
*/
|
|
61
|
-
export declare function implementService<const ServiceName extends string, const EndpointsInit extends BaseServiceEndpointsInit, const WebSocketsInit extends BaseServiceWebSocketsInit,
|
|
65
|
+
export declare function implementService<const ServiceName extends string, const EndpointsInit extends BaseServiceEndpointsInit, const WebSocketsInit extends BaseServiceWebSocketsInit, Context = undefined>(
|
|
62
66
|
/** Init must be first so that TypeScript can infer the type for `Context`. */
|
|
63
|
-
{ service, logger, customHeaders, }: ServiceImplementationInit<
|
|
67
|
+
{ 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>;
|
|
64
68
|
/**
|
|
65
69
|
* A finalized service implementation created by {@link implementService}.
|
|
66
70
|
*
|
|
@@ -68,13 +72,14 @@ export declare function implementService<const ServiceName extends string, const
|
|
|
68
72
|
* @category Package : @rest-vir/implement-service
|
|
69
73
|
* @package [`@rest-vir/implement-service`](https://www.npmjs.com/package/@rest-vir/implement-service)
|
|
70
74
|
*/
|
|
71
|
-
export type ServiceImplementation<Context =
|
|
75
|
+
export type ServiceImplementation<Context = undefined, ServiceName extends string = any, EndpointsInit extends BaseServiceEndpointsInit | NoParam = NoParam, WebSocketsInit extends BaseServiceWebSocketsInit | NoParam = NoParam> = Omit<ServiceDefinition<ServiceName, EndpointsInit, WebSocketsInit>, 'endpoints' | 'webSockets'> & {
|
|
72
76
|
endpoints: {
|
|
73
77
|
[EndpointPath in keyof ServiceDefinition<ServiceName, EndpointsInit, WebSocketsInit>['endpoints']]: EndpointPath extends EndpointPathBase ? ImplementedEndpoint<Context, ServiceDefinition<ServiceName, EndpointsInit, WebSocketsInit>['endpoints'][EndpointPath], ServiceName> : never;
|
|
74
78
|
};
|
|
75
79
|
webSockets: {
|
|
76
80
|
[WebSocketPath in keyof ServiceDefinition<ServiceName, EndpointsInit, WebSocketsInit>['webSockets']]: WebSocketPath extends EndpointPathBase ? ImplementedWebSocket<Context, ServiceName, ServiceDefinition<ServiceName, EndpointsInit, WebSocketsInit>['webSockets'][WebSocketPath]> : never;
|
|
77
81
|
};
|
|
82
|
+
ContextType: Context;
|
|
78
83
|
createContext: ContextInit<Context, ServiceName, EndpointsInit, WebSocketsInit> | undefined;
|
|
79
84
|
logger: ServiceLogger;
|
|
80
85
|
customHeaders: string[];
|
|
@@ -7,7 +7,7 @@ import { assertValidWebSocketImplementations, } from './implement-web-socket.js'
|
|
|
7
7
|
* Creates an implemented service that is fully ready to be run as a server by attaching endpoint
|
|
8
8
|
* implementations to the given {@link ServiceDefinition}.
|
|
9
9
|
*
|
|
10
|
-
* This
|
|
10
|
+
* This should _only_ be run in backend code.
|
|
11
11
|
*
|
|
12
12
|
* @category Implement Service
|
|
13
13
|
* @category Package : @rest-vir/implement-service
|
|
@@ -15,50 +15,61 @@ import { assertValidWebSocketImplementations, } from './implement-web-socket.js'
|
|
|
15
15
|
*/
|
|
16
16
|
export function implementService(
|
|
17
17
|
/** Init must be first so that TypeScript can infer the type for `Context`. */
|
|
18
|
-
{ service,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
{ service, createContext, logger, customHeaders, }) {
|
|
19
|
+
return ({ endpoints: endpointImplementations, webSockets: webSocketImplementations }) => {
|
|
20
|
+
assertValidEndpointImplementations(service, endpointImplementations || {});
|
|
21
|
+
assertValidWebSocketImplementations(service, webSocketImplementations || {});
|
|
22
|
+
const endpoints = mapObjectValues(service.endpoints, (endpointPath, endpoint) => {
|
|
23
|
+
const implementation = endpointImplementations?.[endpointPath];
|
|
24
|
+
assert.isDefined(implementation);
|
|
25
|
+
assert.isNotString(implementation);
|
|
26
|
+
/**
|
|
27
|
+
* Note: this return object is actually wrong. The service property will not be correct
|
|
28
|
+
* as the `endpoint` here only has the minimal service. Below, after
|
|
29
|
+
* `serviceImplementation` is created, we attach the correct service to all endpoints.
|
|
30
|
+
*/
|
|
31
|
+
return {
|
|
32
|
+
...endpoint,
|
|
33
|
+
implementation,
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
const webSockets = mapObjectValues(service.webSockets, (webSocketPath, webSocketImplementation) => {
|
|
37
|
+
const implementation = webSocketImplementations?.[webSocketPath];
|
|
38
|
+
assert.isDefined(implementation);
|
|
39
|
+
assert.isNotString(webSocketImplementation);
|
|
40
|
+
/**
|
|
41
|
+
* Note: this return object is actually wrong. The service property will not be
|
|
42
|
+
* correct as the WebSocket here only has the minimal service. Below, after
|
|
43
|
+
* `serviceImplementation` is created, we attach the correct service to all
|
|
44
|
+
* WebSockets.
|
|
45
|
+
*/
|
|
46
|
+
return {
|
|
47
|
+
...webSocketImplementation,
|
|
48
|
+
implementation,
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
const serviceImplementation = {
|
|
52
|
+
...service,
|
|
53
|
+
customHeaders: customHeaders || [],
|
|
54
|
+
endpoints,
|
|
55
|
+
webSockets,
|
|
56
|
+
createContext,
|
|
57
|
+
logger: createServiceLogger(logger),
|
|
33
58
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const serviceImplementation = {
|
|
50
|
-
...service,
|
|
51
|
-
customHeaders: customHeaders || [],
|
|
52
|
-
endpoints,
|
|
53
|
-
webSockets,
|
|
54
|
-
createContext,
|
|
55
|
-
logger: createServiceLogger(logger),
|
|
59
|
+
Object.defineProperties(serviceImplementation, {
|
|
60
|
+
ContextType: {
|
|
61
|
+
enumerable: false,
|
|
62
|
+
get() {
|
|
63
|
+
throw new Error('.ContextType should not be used as a value.');
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
Object.values(endpoints).forEach((endpoint) => {
|
|
68
|
+
endpoint.service = serviceImplementation;
|
|
69
|
+
});
|
|
70
|
+
Object.values(webSockets).forEach((webSocket) => {
|
|
71
|
+
webSocket.service = serviceImplementation;
|
|
72
|
+
});
|
|
73
|
+
return serviceImplementation;
|
|
56
74
|
};
|
|
57
|
-
Object.values(endpoints).forEach((endpoint) => {
|
|
58
|
-
endpoint.service = serviceImplementation;
|
|
59
|
-
});
|
|
60
|
-
Object.values(webSockets).forEach((webSocket) => {
|
|
61
|
-
webSocket.service = serviceImplementation;
|
|
62
|
-
});
|
|
63
|
-
return serviceImplementation;
|
|
64
75
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type MaybePromise } from '@augment-vir/common';
|
|
2
|
-
import { BaseSearchParams, BaseServiceWebSocketsInit, EndpointPathBase, MinimalService, NoParam, ServiceDefinition, WebSocketDefinition, WebSocketInit, WithFinalWebSocketProps } from '@rest-vir/define-service';
|
|
2
|
+
import { type BaseSearchParams, type BaseServiceWebSocketsInit, type EndpointPathBase, type MinimalService, type NoParam, type ServiceDefinition, type WebSocketDefinition, type WebSocketInit, type WithFinalWebSocketProps } from '@rest-vir/define-service';
|
|
3
3
|
import { type IncomingHttpHeaders } from 'node:http';
|
|
4
4
|
import { type IsEqual } from 'type-fest';
|
|
5
5
|
import { type ServerRequest, type ServerWebSocket } from '../util/data.js';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { HttpMethod, MaybePromise, Values } from '@augment-vir/common';
|
|
1
|
+
import { type HttpMethod, type MaybePromise, type Values } from '@augment-vir/common';
|
|
2
2
|
import { type BaseServiceEndpointsInit, type BaseServiceWebSocketsInit, type EndpointDefinition, type EndpointPathBase, type MinimalService, type NoParam, 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 { EndpointImplementationErrorOutput, type RunningServerInfo } from './implement-endpoint.js';
|
|
6
|
+
import { type EndpointImplementationErrorOutput, type RunningServerInfo } from './implement-endpoint.js';
|
|
7
7
|
/**
|
|
8
8
|
* Output of {@link ContextInit}.
|
|
9
9
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rest-vir/implement-service",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.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.16.0",
|
|
43
|
+
"@augment-vir/common": "^31.16.0",
|
|
44
|
+
"@rest-vir/define-service": "^0.15.1",
|
|
45
45
|
"@types/ws": "^8.18.1",
|
|
46
46
|
"fastify": "^5.3.2",
|
|
47
47
|
"path-to-regexp": "^8.2.0",
|
|
48
|
-
"type-fest": "^4.40.
|
|
48
|
+
"type-fest": "^4.40.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@augment-vir/test": "^31.
|
|
52
|
-
"@types/node": "^22.
|
|
51
|
+
"@augment-vir/test": "^31.16.0",
|
|
52
|
+
"@types/node": "^22.15.3",
|
|
53
53
|
"c8": "^10.1.3",
|
|
54
54
|
"istanbul-smart-text-reporter": "^1.1.5",
|
|
55
55
|
"markdown-code-example-inserter": "^3.0.3",
|