shelving
Version:
Toolkit for using data in JavaScript.
128 lines (127 loc) • 7.73 kB
TypeScript
import { type Schema } from "../schema/Schema.js";
import { type Data } from "../util/data.js";
import type { AnyCaller } from "../util/function.js";
import { type RequestMethod, type RequestOptions } from "../util/http.js";
import type { URLString } from "../util/url.js";
import type { EndpointCallback, EndpointHandler } from "./util.js";
/**
* An abstract API resource definition, used to specify types for e.g. serverless functions.
*
* @param method The method of the endpoint, e.g. `GET`
* @param url Endpoint URL, possibly including placeholders e.g. `https://api.mysite.com/users/{id}`
* @param payload A `Schema` for the payload of the endpoint.
* @param result A `Schema` for the result of the endpoint.
*/
export declare class Endpoint<P, R> {
/** Endpoint method. */
readonly method: RequestMethod;
/** Endpoint URL, possibly including placeholders e.g. `https://api.mysite.com/users/{id}` */
readonly url: URLString;
/** Payload schema. */
readonly payload: Schema<P>;
/** Result schema. */
readonly result: Schema<R>;
constructor(method: RequestMethod, url: URLString, payload: Schema<P>, result: Schema<R>);
/**
* Return an `EndpointHandler` for this endpoint.
*
* @param callback The callback function that implements the logic for this endpoint by receiving the payload and returning the response.
*/
handler(callback: EndpointCallback<P, R>): EndpointHandler<P, R>;
/**
* Handle a request to this endpoint with a callback implementation, with a given payload and request.
*
* @param callback The endpoint callback function that implements the logic for this endpoint by receiving the payload and returning the response.
* @param unsafePayload The payload to pass into the callback (will be validated against this endpoint's payload schema).
* @param request The entire HTTP request that is being handled (payload was possibly extracted from this somehow).
*
* @throws `string` if the payload is invalid.
* @throws `ValueError` if `callback()` returns an invalid result.
*/
handle(callback: EndpointCallback<P, R>, unsafePayload: unknown, request: Request, caller?: AnyCaller): Promise<Response>;
/**
* Render the URL for this endpoint with the given payload.
* - URL might contain `{placeholder}` values that are replaced with values from the payload.
*
* @returns Rendered URL with `{placeholders}` rendered with values from `payload`
* @throws {RequiredError} if `{placeholders}` are set in the URL but `payload` is not a data object.
*/
renderURL(payload: P, caller?: AnyCaller): string;
/**
* Get an HTTP `Request` object for this endpoint.
* - Validates a payload against this endpoints payload schema
* - Return an HTTP `Request` that will send it the valid payload to this endpoint.
*
* @throws `string` if the payload is invalid.
*/
request(payload: P, options?: RequestOptions, caller?: AnyCaller): Request;
/**
* Validate an HTTP `Response` against this endpoint.
*
* @throws `ResponseError` if the response status is not ok (200-299)
* @throws `ResponseError` if the response content is invalid.
*/
response(response: Response, caller?: AnyCaller): Promise<R>;
/**
* Perform a fetch to this endpoint.
* - Validate the `payload` against this endpoint's payload schema.
* - Validate the returned response against this endpoint's result schema.
*
* @throws `string` if the payload is invalid.
* @throws `ResponseError` if the response status is not ok (200-299)
* @throws `ResponseError` if the response content is invalid.
*/
fetch(payload: P, options?: RequestOptions, caller?: AnyCaller): Promise<R>;
/** Convert to string, e.g. `GET https://a.com/user/{id}` */
toString(): string;
}
/** Extract the payload type from a `Endpoint`. */
export type PayloadType<X extends Endpoint<unknown, unknown>> = X extends Endpoint<infer Y, unknown> ? Y : never;
/** Extract the result type from a `Endpoint`. */
export type EndpointType<X extends Endpoint<unknown, unknown>> = X extends Endpoint<unknown, infer Y> ? Y : never;
/**
* Represent a HEAD request to a specified URL, with validated payload and return types.
* "The HEAD method requests a representation of the specified resource. Requests using HEAD should only retrieve data and should not contain a request content."
*
* - Because HEAD requests have no body payload can only be a data object (where props get sent as `{placeholders}` or `?query` params in the URL).
*/
export declare function HEAD<P extends Data, R>(url: URLString, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
export declare function HEAD<P extends Data>(url: URLString, payload: Schema<P>): Endpoint<P, undefined>;
export declare function HEAD<R>(url: URLString, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
/**
* Represent a GET request to a specified URL, with validated payload and return types.
* "The GET method requests a representation of the specified resource. Requests using GET should only retrieve data and should not contain a request content."
*
* - Because GET requests have no body payload can only be a data object (where props get sent as `{placeholders}` or `?query` params in the URL).
*/
export declare function GET<P extends Data, R>(url: URLString, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
export declare function GET<P extends Data>(url: URLString, payload: Schema<P>): Endpoint<P, undefined>;
export declare function GET<R>(url: URLString, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
/**
* Represent a POST request to a specified URL, with validated payload and return types.
* "The POST method submits an entity to the specified resource, often causing a change in state or side effects on the server.
*/
export declare function POST<P, R>(url: URLString, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
export declare function POST<P>(url: URLString, payload: Schema<P>): Endpoint<P, undefined>;
export declare function POST<R>(url: URLString, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
/**
* Represent a PUT request to a specified URL, with validated payload and return types.
* "The PUT method replaces all current representations of the target resource with the request content."
*/
export declare function PUT<P, R>(url: URLString, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
export declare function PUT<P>(url: URLString, payload: Schema<P>): Endpoint<P, undefined>;
export declare function PUT<R>(url: URLString, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
/**
* Represent a PATCH request to a specified URL, with validated payload and return types.
* "The PATCH method applies partial modifications to a resource."
*/
export declare function PATCH<P, R>(url: URLString, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
export declare function PATCH<P>(url: URLString, payload: Schema<P>): Endpoint<P, undefined>;
export declare function PATCH<R>(url: URLString, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
/**
* Represent a DELETE request to a specified URL, with validated payload and return types.
* "The DELETE method deletes the specified resource."
*/
export declare function DELETE<P, R>(url: URLString, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
export declare function DELETE<P>(url: URLString, payload: Schema<P>): Endpoint<P, undefined>;
export declare function DELETE<R>(url: URLString, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;