shelving 1.166.0 → 1.167.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/api/Endpoint.d.ts CHANGED
@@ -48,11 +48,27 @@ export declare class Endpoint<P, R> {
48
48
  */
49
49
  renderURL(payload: P, caller?: AnyCaller): string;
50
50
  /**
51
- * Validate a payload against this endpoints payload schema, and return an HTTP `Request` that will send it to this endpoint.
51
+ * Get an HTTP `Request` object for this endpoint.
52
+ * - Validates a payload against this endpoints payload schema
53
+ * - Return an HTTP `Request` that will send it the valid payload to this endpoint.
54
+ *
55
+ * @throws Feedback if the payload is invalid.
52
56
  */
53
57
  request(payload: P, options?: EndpointOptions, caller?: AnyCaller): Request;
54
58
  /**
55
- * Perform a fetch to this endpoint, and validate the returned response against this endpoint's result schema.
59
+ * Validate an HTTP `Response` against this endpoint.
60
+ * @throws ResponseError if the response status is not ok (200-299)
61
+ * @throws ResponseError if the response content is invalid.
62
+ */
63
+ response(response: Response, caller?: AnyCaller): Promise<R>;
64
+ /**
65
+ * Perform a fetch to this endpoint.
66
+ * - Validate the `payload` against this endpoint's payload schema.
67
+ * - Validate the returned response against this endpoint's result schema.
68
+ *
69
+ * @throws Feedback if the payload is invalid.
70
+ * @throws ResponseError if the response status is not ok (200-299)
71
+ * @throws ResponseError if the response content is invalid.
56
72
  */
57
73
  fetch(payload: P, options?: EndpointOptions, caller?: AnyCaller): Promise<R>;
58
74
  /** Convert to string, e.g. `GET https://a.com/user/{id}` */
package/api/Endpoint.js CHANGED
@@ -70,18 +70,21 @@ export class Endpoint {
70
70
  return url;
71
71
  }
72
72
  /**
73
- * Validate a payload against this endpoints payload schema, and return an HTTP `Request` that will send it to this endpoint.
73
+ * Get an HTTP `Request` object for this endpoint.
74
+ * - Validates a payload against this endpoints payload schema
75
+ * - Return an HTTP `Request` that will send it the valid payload to this endpoint.
76
+ *
77
+ * @throws Feedback if the payload is invalid.
74
78
  */
75
79
  request(payload, options = {}, caller = this.request) {
76
80
  return createRequest(this.method, this.url, this.payload.validate(payload), options, caller);
77
81
  }
78
82
  /**
79
- * Perform a fetch to this endpoint, and validate the returned response against this endpoint's result schema.
83
+ * Validate an HTTP `Response` against this endpoint.
84
+ * @throws ResponseError if the response status is not ok (200-299)
85
+ * @throws ResponseError if the response content is invalid.
80
86
  */
81
- async fetch(payload, options = {}, caller = this.fetch) {
82
- // Fetch the response.
83
- const request = this.request(payload, options, caller);
84
- const response = await fetch(request);
87
+ async response(response, caller = this.response) {
85
88
  // Get the response.
86
89
  const { ok, status } = response;
87
90
  const content = await getResponseContent(response, caller);
@@ -91,6 +94,19 @@ export class Endpoint {
91
94
  // Validate the success response.
92
95
  return getValid(content, this.result, ResponseError, caller);
93
96
  }
97
+ /**
98
+ * Perform a fetch to this endpoint.
99
+ * - Validate the `payload` against this endpoint's payload schema.
100
+ * - Validate the returned response against this endpoint's result schema.
101
+ *
102
+ * @throws Feedback if the payload is invalid.
103
+ * @throws ResponseError if the response status is not ok (200-299)
104
+ * @throws ResponseError if the response content is invalid.
105
+ */
106
+ async fetch(payload, options = {}, caller = this.fetch) {
107
+ const response = await fetch(this.request(payload, options, caller));
108
+ return this.response(response, caller);
109
+ }
94
110
  /** Convert to string, e.g. `GET https://a.com/user/{id}` */
95
111
  toString() {
96
112
  return `${this.method} ${this.url}`;
package/api/util.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { AnyCaller } from "../util/function.js";
1
2
  import type { Endpoint } from "./Endpoint.js";
2
3
  /**
3
4
  * A function that handles a endpoint request, with a payload and returns a result.
@@ -32,9 +33,8 @@ export type EndpointHandlers = ReadonlyArray<AnyEndpointHandler>;
32
33
  *
33
34
  * 1. Define your `Endpoint` objects with a method, path, payload and result validators, e.g. `GET("/test/{id}", PAYLOAD, STRING)`
34
35
  * 2. Make an array of `EndpointHandler` objects combining an `Endpoint` with a `callback` function
35
- * -
36
36
  *
37
37
  * @returns The resulting `Response` from the first handler that matches the `Request`.
38
38
  * @throws `NotFoundError` if no handler matches the `Request`.
39
39
  */
40
- export declare function handleEndpoints(request: Request, endpoints: EndpointHandlers): Promise<Response>;
40
+ export declare function handleEndpoints(request: Request, endpoints: EndpointHandlers, caller?: AnyCaller): Promise<Response>;
package/api/util.js CHANGED
@@ -9,17 +9,16 @@ import { getURL } from "../util/url.js";
9
9
  *
10
10
  * 1. Define your `Endpoint` objects with a method, path, payload and result validators, e.g. `GET("/test/{id}", PAYLOAD, STRING)`
11
11
  * 2. Make an array of `EndpointHandler` objects combining an `Endpoint` with a `callback` function
12
- * -
13
12
  *
14
13
  * @returns The resulting `Response` from the first handler that matches the `Request`.
15
14
  * @throws `NotFoundError` if no handler matches the `Request`.
16
15
  */
17
- export function handleEndpoints(request, endpoints) {
16
+ export function handleEndpoints(request, endpoints, caller = handleEndpoints) {
18
17
  // Parse the URL of the request.
19
18
  const requestUrl = request.url;
20
19
  const url = getURL(requestUrl);
21
20
  if (!url)
22
- throw new RequestError("Invalid request URL", { received: requestUrl, caller: handleEndpoints });
21
+ throw new RequestError("Invalid request URL", { received: requestUrl, caller });
23
22
  const { origin, pathname, searchParams } = url;
24
23
  // Iterate over the handlers and return the first one that matches the request.
25
24
  for (const { endpoint, callback } of endpoints) {
@@ -28,7 +27,7 @@ export function handleEndpoints(request, endpoints) {
28
27
  continue;
29
28
  // Ensure the request URL e.g. `/user/123` matches the endpoint path e.g. `/user/{id}`
30
29
  // Any `{placeholders}` in the endpoint path are matched against the request URL to extract parameters.
31
- const pathParams = matchTemplate(endpoint.url, `${origin}${pathname}`, handleEndpoints);
30
+ const pathParams = matchTemplate(endpoint.url, `${origin}${pathname}`, caller);
32
31
  if (!pathParams)
33
32
  continue;
34
33
  // Make a simple dictionary object from the `{placeholder}` path params and the `?a=123` query params from the URL.
@@ -37,7 +36,7 @@ export function handleEndpoints(request, endpoints) {
37
36
  return handleEndpoint(endpoint, callback, combinedParams, request);
38
37
  }
39
38
  // No handler matched the request.
40
- throw new NotFoundError("No matching endpoint", { received: requestUrl, caller: handleEndpoints });
39
+ throw new NotFoundError("No matching endpoint", { received: requestUrl, caller });
41
40
  }
42
41
  /** Handle an individual call to an endpoint callback. */
43
42
  async function handleEndpoint(endpoint, callback, params, request) {
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "state-management",
12
12
  "query-builder"
13
13
  ],
14
- "version": "1.166.0",
14
+ "version": "1.167.1",
15
15
  "repository": "https://github.com/dhoulb/shelving",
16
16
  "author": "Dave Houlbrooke <dave@shax.com>",
17
17
  "license": "0BSD",