UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

69 lines (68 loc) 2.88 kB
import { getResponse } from "../util/http.js"; import { UNDEFINED } from "../util/validate.js"; /** * An abstract API resource definition, used to specify types for e.g. serverless functions. * * @param method The method of the resource, e.g. `GET` * @param path The path of the resource optionally including `{placeholder}` values, e.g. `/patient/{id}` * @param payload A `Validator` for the payload of the resource. * @param result A `Validator` for the result of the resource. */ export class Endpoint { /** Endpoint method. */ method; /** Endpoint path, e.g. `/patient/{id}` */ path; /** Payload validator. */ payload; /** Result validator. */ result; constructor(method, path, payload, result) { this.method = method; this.path = path; this.payload = payload; this.result = result; } /** * 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) { return { endpoint: this, callback }; } /** * 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). */ async handle(callback, unsafePayload, request) { // Validate the payload against this endpoint's payload type. const payload = this.payload.validate(unsafePayload); // Call the callback with the validated payload to get the result. const result = await callback(payload, request); // Convert the result to a `Response` object. return getResponse(result); } /** Convert to string, e.g. `GET /user/{id}` */ toString() { return `${this.method} ${this.path}`; } } export function GET(path, payload, result) { return new Endpoint("GET", path, payload || UNDEFINED, result || UNDEFINED); } export function POST(path, payload, result) { return new Endpoint("POST", path, payload || UNDEFINED, result || UNDEFINED); } export function PUT(path, payload, result) { return new Endpoint("PUT", path, payload || UNDEFINED, result || UNDEFINED); } export function PATCH(path, payload, result) { return new Endpoint("PATCH", path, payload || UNDEFINED, result || UNDEFINED); } export function DELETE(path, payload, result) { return new Endpoint("DELETE", path, payload || UNDEFINED, result || UNDEFINED); }