shelving 1.141.0 → 1.142.0
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/api/util.d.ts +10 -2
- package/api/util.js +16 -8
- package/package.json +1 -1
- package/util/http.d.ts +1 -1
package/api/util.d.ts
CHANGED
|
@@ -6,8 +6,12 @@ import type { Endpoint } from "./Endpoint.js";
|
|
|
6
6
|
* - Payload is validated by the payload validator for the `Endpoint`.
|
|
7
7
|
* - If the body of the `Request` is a data object (i.e. a plain object), then body data is merged with the path and query parameters to form a single flat object.
|
|
8
8
|
* - If payload is _not_ a data object (i.e. it's another JSON type like `string` or `number`) then the payload include the path and query parameters, and a key called `content` that contains the body of the request.
|
|
9
|
+
*
|
|
10
|
+
* @param request The raw `Request` object in case it needs any additional processing.
|
|
11
|
+
*
|
|
12
|
+
* @returns The correct `Result` type for the `Endpoint`, or a raw `Response` object if you wish to return a custom response.
|
|
9
13
|
*/
|
|
10
|
-
export type EndpointCallback<P, R> = (payload: P, request: Request) => R | Promise<R>;
|
|
14
|
+
export type EndpointCallback<P, R> = (payload: P, request: Request) => R | Response | Promise<R | Response>;
|
|
11
15
|
/**
|
|
12
16
|
* Object combining an abstract `Endpoint` and an `EndpointCallback` implementation.
|
|
13
17
|
*/
|
|
@@ -24,7 +28,11 @@ export type AnyEndpointHandler = EndpointHandler<any, any>;
|
|
|
24
28
|
*/
|
|
25
29
|
export type EndpointHandlers = ReadonlyArray<AnyEndpointHandler>;
|
|
26
30
|
/**
|
|
27
|
-
* Handler a `Request` with the first matching `
|
|
31
|
+
* Handler a `Request` with the first matching `EndpointHandlers`.
|
|
32
|
+
*
|
|
33
|
+
* 1. Define your `Endpoint` objects with a method, path, payload and result validators, e.g. `GET("/test/{id}", PAYLOAD, STRING)`
|
|
34
|
+
* 2. Make an array of `EndpointHandler` objects combining an `Endpoint` with a `callback` function
|
|
35
|
+
* -
|
|
28
36
|
*
|
|
29
37
|
* @returns The resulting `Response` from the first handler that matches the `Request`.
|
|
30
38
|
* @throws `NotFoundError` if no handler matches the `Request`.
|
package/api/util.js
CHANGED
|
@@ -7,7 +7,11 @@ import { matchTemplate } from "../util/template.js";
|
|
|
7
7
|
import { getURL } from "../util/url.js";
|
|
8
8
|
import { getValid } from "../util/validate.js";
|
|
9
9
|
/**
|
|
10
|
-
* Handler a `Request` with the first matching `
|
|
10
|
+
* Handler a `Request` with the first matching `EndpointHandlers`.
|
|
11
|
+
*
|
|
12
|
+
* 1. Define your `Endpoint` objects with a method, path, payload and result validators, e.g. `GET("/test/{id}", PAYLOAD, STRING)`
|
|
13
|
+
* 2. Make an array of `EndpointHandler` objects combining an `Endpoint` with a `callback` function
|
|
14
|
+
* -
|
|
11
15
|
*
|
|
12
16
|
* @returns The resulting `Response` from the first handler that matches the `Request`.
|
|
13
17
|
* @throws `NotFoundError` if no handler matches the `Request`.
|
|
@@ -28,14 +32,15 @@ export function handleEndpoints(request, endpoints) {
|
|
|
28
32
|
const pathParams = matchTemplate(endpoint.path, pathname, handleEndpoints);
|
|
29
33
|
if (!pathParams)
|
|
30
34
|
continue;
|
|
31
|
-
//
|
|
35
|
+
// Make a simple dictionary object from the `{placeholder}` path params and the `?a=123` query params from the URL.
|
|
32
36
|
const params = searchParams.size ? { ...getDictionary(searchParams), ...pathParams } : pathParams;
|
|
33
37
|
// Get the response by calling the callback.
|
|
34
|
-
return
|
|
38
|
+
return getEndpointResponse(endpoint, callback, params, request);
|
|
35
39
|
}
|
|
40
|
+
// No handler matched the request.
|
|
36
41
|
throw new NotFoundError("Not found", { request, caller: handleEndpoints });
|
|
37
42
|
}
|
|
38
|
-
async function
|
|
43
|
+
async function getEndpointResponse(endpoint, callback, params, request) {
|
|
39
44
|
// Extract a data object from the request body and validate it against the endpoint's payload type.
|
|
40
45
|
const content = await getRequestContent(request, handleEndpoints);
|
|
41
46
|
// If content is undefined, it means the request has no body, so params are the only payload.
|
|
@@ -43,11 +48,14 @@ async function _getResponse(endpoint, callback, params, request) {
|
|
|
43
48
|
// If the content is not a data object (e.g. string, number, array), set a single `content` property and merge it with the params.
|
|
44
49
|
const unsafePayload = content === undefined ? params : isData(content) ? { ...content, ...params } : { content, ...params };
|
|
45
50
|
const payload = endpoint.prepare(unsafePayload);
|
|
46
|
-
// Call the
|
|
47
|
-
const
|
|
48
|
-
//
|
|
51
|
+
// Call the callback with the validated payload to get the result.
|
|
52
|
+
const returned = await callback(payload, request);
|
|
53
|
+
// If the callback returned a `Response`, return it directly.
|
|
54
|
+
if (returned instanceof Response)
|
|
55
|
+
return returned;
|
|
56
|
+
// Otherwise validate the result against the endpoint's result type.
|
|
49
57
|
// Throw a `ValueError` if the result is not valid, which indicates an internal error in the callback implementation.
|
|
50
|
-
const result = getValid(
|
|
58
|
+
const result = getValid(returned, endpoint, ValueError, handleEndpoints);
|
|
51
59
|
// Return a new `Response` with a 200 status and the validated result data.
|
|
52
60
|
return Response.json(result);
|
|
53
61
|
}
|
package/package.json
CHANGED
package/util/http.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { AnyCaller } from "../error/BaseError.js";
|
|
|
2
2
|
import { RequestError } from "../error/RequestError.js";
|
|
3
3
|
import { ResponseError } from "../error/ResponseError.js";
|
|
4
4
|
/** A handler function takes a `Request` and returns a `Response` (possibly asynchronously). */
|
|
5
|
-
export type
|
|
5
|
+
export type RequestHandler = (request: Request) => Response | Promise<Response>;
|
|
6
6
|
export declare function _getMessageJSON(message: Request | Response, MessageError: typeof RequestError | typeof ResponseError, caller: AnyCaller): Promise<unknown>;
|
|
7
7
|
export declare function _getMessageFormData(message: Request | Response, MessageError: typeof RequestError | typeof ResponseError, caller: AnyCaller): Promise<unknown>;
|
|
8
8
|
export declare function _getMessageContent(message: Request | Response, MessageError: typeof RequestError | typeof ResponseError, caller: AnyCaller): Promise<unknown>;
|