UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

128 lines (127 loc) 7.73 kB
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>;