@rest-vir/define-service 1.2.5 → 1.2.6
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.
|
@@ -1,11 +1,56 @@
|
|
|
1
|
+
import { type IsEqual, type IsNever } from 'type-fest';
|
|
2
|
+
import { type NoParam } from '../util/no-param.js';
|
|
1
3
|
/**
|
|
2
|
-
* Extracts all path parameters from an endpoint path.
|
|
4
|
+
* Extracts all named path parameters from an endpoint path.
|
|
3
5
|
*
|
|
4
6
|
* @category Internal
|
|
5
7
|
* @category Package : @rest-vir/define-service
|
|
6
8
|
* @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
|
|
7
9
|
*/
|
|
8
|
-
export type
|
|
10
|
+
export type NamedPathParams<EndpointPath extends string> = string extends EndpointPath ? string : EndpointPath extends `${string}:${infer Param}/${infer Rest}` ? Param | NamedPathParams<`/${Rest}`> : EndpointPath extends `${string}:${infer Param}` ? Param : IsEqual<`/${string}`, EndpointPath> extends true ? string : never;
|
|
11
|
+
/**
|
|
12
|
+
* Determines if the given endpoint path has a trailing wildcard.
|
|
13
|
+
*
|
|
14
|
+
* @category Internal
|
|
15
|
+
* @category Package : @rest-vir/define-service
|
|
16
|
+
* @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
|
|
17
|
+
*/
|
|
18
|
+
export type HasWildcardParam<EndpointPath extends string> = string extends EndpointPath ? boolean : EndpointPath extends `${string}/*` ? true : IsEqual<`/${string}`, EndpointPath> extends true ? boolean : false;
|
|
19
|
+
/**
|
|
20
|
+
* Extracts named and wildcard path params.
|
|
21
|
+
*
|
|
22
|
+
* @category Internal
|
|
23
|
+
* @category Package : @rest-vir/define-service
|
|
24
|
+
* @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
|
|
25
|
+
*/
|
|
26
|
+
export type PathParams<EndpointPath extends string> = {
|
|
27
|
+
namedParams: NamedPathParams<EndpointPath>;
|
|
28
|
+
hasWildcard: HasWildcardParam<EndpointPath>;
|
|
29
|
+
};
|
|
30
|
+
export type GenericPathParams = {
|
|
31
|
+
pathParams: Readonly<Record<string, string>>;
|
|
32
|
+
wildcard: string | undefined;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Converts an endpoint path into the fetch params needed for its to operate.
|
|
36
|
+
*
|
|
37
|
+
* @category Internal
|
|
38
|
+
* @category Package : @rest-vir/define-service
|
|
39
|
+
* @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
|
|
40
|
+
*/
|
|
41
|
+
export type ConstructPathParams<EndpointPath extends string | NoParam> = EndpointPath extends NoParam ? GenericPathParams : (IsEqual<PathParams<Exclude<EndpointPath, NoParam>>['hasWildcard'], true> extends true ? Readonly<{
|
|
42
|
+
wildcard: string;
|
|
43
|
+
}> : IsEqual<PathParams<Exclude<EndpointPath, NoParam>>['hasWildcard'], false> extends true ? Readonly<{
|
|
44
|
+
wildcard?: undefined;
|
|
45
|
+
}> : Readonly<{
|
|
46
|
+
wildcard?: string | undefined;
|
|
47
|
+
}>) & (IsNever<PathParams<Exclude<EndpointPath, NoParam>>['namedParams']> extends true ? Readonly<{
|
|
48
|
+
pathParams?: undefined;
|
|
49
|
+
}> : PathParams<Exclude<EndpointPath, NoParam>>['namedParams'] extends string ? Readonly<{
|
|
50
|
+
pathParams: Readonly<Record<PathParams<Exclude<EndpointPath, NoParam>>['namedParams'], string>>;
|
|
51
|
+
}> : Readonly<{
|
|
52
|
+
pathParams?: undefined;
|
|
53
|
+
}>);
|
|
9
54
|
/**
|
|
10
55
|
* Base requirement for endpoint paths.
|
|
11
56
|
*
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type RequiredKeysOf, type SelectFrom } from '@augment-vir/common';
|
|
2
|
-
import { type
|
|
3
|
-
import { type PathParams } from '../endpoint/endpoint-path.js';
|
|
2
|
+
import { type ConstructPathParams } from '../endpoint/endpoint-path.js';
|
|
4
3
|
import { type NoParam } from '../util/no-param.js';
|
|
5
4
|
import { type CommonWebSocket } from '../web-socket/common-web-socket.js';
|
|
6
5
|
import { type ClientWebSocket, type ConnectWebSocketListeners, type GenericConnectWebSocketParams } from '../web-socket/overwrite-web-socket-methods.js';
|
|
@@ -51,16 +50,7 @@ export type ConnectWebSocketParams<WebSocketToConnect extends Readonly<SelectFro
|
|
|
51
50
|
* requiring externally adding them.
|
|
52
51
|
*/
|
|
53
52
|
listeners?: ConnectWebSocketListeners<WebSocketToConnect, WebSocketClass>;
|
|
54
|
-
} &
|
|
55
|
-
/** This WebSocket has no path parameters to configure. */
|
|
56
|
-
pathParams?: undefined;
|
|
57
|
-
} : PathParams<WebSocketToConnect['path']> extends string ? {
|
|
58
|
-
/** Required path params for this WebSocket's path. */
|
|
59
|
-
pathParams: Readonly<Record<PathParams<WebSocketToConnect['path']>, string>>;
|
|
60
|
-
} : {
|
|
61
|
-
/** This WebSocket has no path parameters to configure. */
|
|
62
|
-
pathParams?: undefined;
|
|
63
|
-
}) & (AllowWebSocketMock extends true ? Pick<GenericConnectWebSocketParams<WebSocketClass>, 'webSocketConstructor'> : unknown) & (WebSocketToConnect['protocolsShape'] extends undefined ? {
|
|
53
|
+
} & ConstructPathParams<WebSocketToConnect['path']> & (AllowWebSocketMock extends true ? Pick<GenericConnectWebSocketParams<WebSocketClass>, 'webSocketConstructor'> : unknown) & (WebSocketToConnect['protocolsShape'] extends undefined ? {
|
|
64
54
|
protocols?: string[];
|
|
65
55
|
} : {
|
|
66
56
|
protocols: WebSocketToConnect['ProtocolsType'];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { HttpMethod, type ExtractKeysWithMatchingValues, type KeyCount, type MaybePromise, type RequiredKeysOf, type SelectFrom } from '@augment-vir/common';
|
|
1
|
+
import { HttpMethod, type ExtractKeysWithMatchingValues, type KeyCount, type MaybePromise, type PartialWithUndefined, type RequiredKeysOf, type SelectFrom } from '@augment-vir/common';
|
|
2
2
|
import { type IsEqual, type IsNever } from 'type-fest';
|
|
3
|
-
import { type
|
|
3
|
+
import { type ConstructPathParams, type GenericPathParams } from '../endpoint/endpoint-path.js';
|
|
4
4
|
import { type EndpointDefinition, type EndpointExecutorData, type GenericEndpointDefinition } from '../endpoint/endpoint.js';
|
|
5
5
|
import { type NoParam } from '../util/no-param.js';
|
|
6
6
|
import { type BaseSearchParams } from '../util/search-params.js';
|
|
@@ -12,8 +12,7 @@ import { type BaseSearchParams } from '../util/search-params.js';
|
|
|
12
12
|
* @category Package : @rest-vir/define-service
|
|
13
13
|
* @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
|
|
14
14
|
*/
|
|
15
|
-
export type GenericFetchEndpointParams = {
|
|
16
|
-
pathParams?: Record<string, string> | undefined;
|
|
15
|
+
export type GenericFetchEndpointParams = PartialWithUndefined<GenericPathParams> & {
|
|
17
16
|
requestData?: any;
|
|
18
17
|
searchParams?: BaseSearchParams | undefined;
|
|
19
18
|
bypassResponseValidation?: undefined | boolean;
|
|
@@ -45,15 +44,7 @@ export type FetchEndpointParams<EndpointToFetch extends SelectFrom<EndpointDefin
|
|
|
45
44
|
requestDataShape: true;
|
|
46
45
|
responseDataShape: true;
|
|
47
46
|
methods: true;
|
|
48
|
-
}>, AllowFetchMock extends boolean = true> = EndpointToFetch extends EndpointDefinition ? Readonly<
|
|
49
|
-
/** This endpoint has no path parameters to configure. */
|
|
50
|
-
pathParams?: undefined;
|
|
51
|
-
} : PathParams<EndpointToFetch['path']> extends string ? {
|
|
52
|
-
pathParams: Readonly<Record<PathParams<EndpointToFetch['path']>, string>>;
|
|
53
|
-
} : {
|
|
54
|
-
/** This endpoint has no path parameters to configure. */
|
|
55
|
-
pathParams?: undefined;
|
|
56
|
-
}) & (EndpointToFetch['SearchParamsType'] extends undefined ? {
|
|
47
|
+
}>, AllowFetchMock extends boolean = true> = EndpointToFetch extends EndpointDefinition ? Readonly<ConstructPathParams<EndpointToFetch['path']> & (EndpointToFetch['SearchParamsType'] extends undefined ? {
|
|
57
48
|
searchParams?: never;
|
|
58
49
|
} : {
|
|
59
50
|
searchParams: EndpointToFetch['SearchParamsType'];
|
|
@@ -181,7 +172,7 @@ export declare function buildEndpointRequestInit<const EndpointToFetch extends R
|
|
|
181
172
|
serviceOrigin: true;
|
|
182
173
|
serviceName: true;
|
|
183
174
|
};
|
|
184
|
-
}>, ...[{ method, options, pathParams, requestData, searchParams },]: CollapsedFetchEndpointParams<EndpointToFetch, false>): {
|
|
175
|
+
}>, ...[{ method, options, pathParams, requestData, searchParams, wildcard },]: CollapsedFetchEndpointParams<EndpointToFetch, false>): {
|
|
185
176
|
url: string;
|
|
186
177
|
requestInit: RequestInit;
|
|
187
178
|
};
|
|
@@ -212,4 +203,4 @@ export declare function buildEndpointUrl<const EndpointToFetch extends Readonly<
|
|
|
212
203
|
searchParamsShape: true;
|
|
213
204
|
responseDataShape: true;
|
|
214
205
|
methods: true;
|
|
215
|
-
}>, { pathParams, searchParams, }: Pick<EndpointToFetch extends NoParam ? Readonly<GenericFetchEndpointParams> : Readonly<FetchEndpointParams<Exclude<EndpointToFetch, NoParam>>>, 'pathParams' | 'searchParams'>): string;
|
|
206
|
+
}>, { pathParams, searchParams, wildcard, }: Pick<EndpointToFetch extends NoParam ? Readonly<GenericFetchEndpointParams> : Readonly<FetchEndpointParams<Exclude<EndpointToFetch, NoParam>>>, 'pathParams' | 'searchParams' | 'wildcard'>): string;
|
|
@@ -93,7 +93,7 @@ export async function fetchEndpoint(endpoint, ...params) {
|
|
|
93
93
|
* @category Package : @rest-vir/define-service
|
|
94
94
|
* @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
|
|
95
95
|
*/
|
|
96
|
-
export function buildEndpointRequestInit(endpoint, ...[{ method, options = {}, pathParams, requestData, searchParams } = {},]) {
|
|
96
|
+
export function buildEndpointRequestInit(endpoint, ...[{ method, options = {}, pathParams, requestData, searchParams, wildcard } = {},]) {
|
|
97
97
|
const headers = options.headers instanceof Headers
|
|
98
98
|
? Object.fromEntries(options.headers.entries())
|
|
99
99
|
: check.isArray(options.headers)
|
|
@@ -115,6 +115,7 @@ export function buildEndpointRequestInit(endpoint, ...[{ method, options = {}, p
|
|
|
115
115
|
const url = buildEndpointUrl(endpoint, {
|
|
116
116
|
pathParams,
|
|
117
117
|
searchParams,
|
|
118
|
+
wildcard,
|
|
118
119
|
});
|
|
119
120
|
const requestInit = {
|
|
120
121
|
...options,
|
|
@@ -142,7 +143,7 @@ export function buildEndpointRequestInit(endpoint, ...[{ method, options = {}, p
|
|
|
142
143
|
* @category Package : @rest-vir/define-service
|
|
143
144
|
* @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
|
|
144
145
|
*/
|
|
145
|
-
export function buildEndpointUrl(endpoint, { pathParams, searchParams, }) {
|
|
146
|
+
export function buildEndpointUrl(endpoint, { pathParams, searchParams, wildcard, }) {
|
|
146
147
|
let pathParamsCount = 0;
|
|
147
148
|
if (endpoint.searchParamsShape) {
|
|
148
149
|
assertValidShape(searchParams, endpoint.searchParamsShape, {
|
|
@@ -150,20 +151,26 @@ export function buildEndpointUrl(endpoint, { pathParams, searchParams, }) {
|
|
|
150
151
|
allowExtraKeys: true,
|
|
151
152
|
}, `Invalid search params given to '${endpoint.path}' in service '${endpoint.service.serviceName}'`);
|
|
152
153
|
}
|
|
154
|
+
if (endpoint.path.endsWith('/*') && wildcard == undefined) {
|
|
155
|
+
throw new Error('Missing value for wildcard param.');
|
|
156
|
+
}
|
|
157
|
+
const pathname = endpoint.path
|
|
158
|
+
.replaceAll(/\/:([^/]+)/g, (wholeMatch, paramName) => {
|
|
159
|
+
pathParamsCount++;
|
|
160
|
+
if (pathParams && check.hasKey(pathParams, paramName) && pathParams[paramName]) {
|
|
161
|
+
return addPrefix({
|
|
162
|
+
value: pathParams[paramName],
|
|
163
|
+
prefix: '/',
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
throw new Error(`Missing value for path param '${paramName}'.`);
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
.replace(/\/\*$/, addPrefix({ value: wildcard || '', prefix: '/' }));
|
|
153
171
|
const builtUrl = buildUrl(endpoint.service.serviceOrigin, {
|
|
154
172
|
search: searchParams,
|
|
155
|
-
pathname
|
|
156
|
-
pathParamsCount++;
|
|
157
|
-
if (pathParams && check.hasKey(pathParams, paramName) && pathParams[paramName]) {
|
|
158
|
-
return addPrefix({
|
|
159
|
-
value: pathParams[paramName],
|
|
160
|
-
prefix: '/',
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
throw new Error(`Missing value for path param '${paramName}'.`);
|
|
165
|
-
}
|
|
166
|
-
}),
|
|
173
|
+
pathname,
|
|
167
174
|
}).href;
|
|
168
175
|
if (!pathParamsCount && pathParams) {
|
|
169
176
|
throw new Error(`'${endpoint.path}' in service '${endpoint.service.serviceName}' does not allow any path params but some where set.`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rest-vir/define-service",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"description": "Define an connect to a declarative and type safe REST and WebSocket service.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rest",
|
|
@@ -40,14 +40,14 @@
|
|
|
40
40
|
"test:update": "npm test update"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@augment-vir/assert": "^31.
|
|
44
|
-
"@augment-vir/common": "^31.
|
|
43
|
+
"@augment-vir/assert": "^31.46.1",
|
|
44
|
+
"@augment-vir/common": "^31.46.1",
|
|
45
45
|
"date-vir": "^8.0.0",
|
|
46
46
|
"type-fest": "^5.1.0",
|
|
47
47
|
"url-vir": "^2.1.6"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@augment-vir/test": "^31.
|
|
50
|
+
"@augment-vir/test": "^31.46.1",
|
|
51
51
|
"@web/dev-server-esbuild": "^1.0.4",
|
|
52
52
|
"@web/test-runner": "^0.20.2",
|
|
53
53
|
"@web/test-runner-commands": "^0.9.0",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@web/test-runner-visual-regression": "^0.10.0",
|
|
56
56
|
"istanbul-smart-text-reporter": "^1.1.5",
|
|
57
57
|
"markdown-code-example-inserter": "^3.0.3",
|
|
58
|
-
"object-shape-tester": "^6.9.
|
|
58
|
+
"object-shape-tester": "^6.9.3",
|
|
59
59
|
"typedoc": "^0.28.14",
|
|
60
60
|
"ws": "^8.18.3"
|
|
61
61
|
},
|