@metreeca/http - v0.1.1
    Preparing search index...

    Module index

    Client assembly and HTTP utilities.

    Provides a composable middleware layer over the standard fetch function, with ready-made middlewares for recurring concerns published as subpath modules. A Middleware wraps a Fetch implementation, returning a drop-in replacement that adjusts requests and responses as they flow through, and createFetch assembles a chain of them into a single client to be shared across an application.

    Named constants for the HTTP status codes are provided alongside, so that response handling reads as intent rather than as bare numeric literals. Coverage is complete for the codes defined by RFC 9110 § 15, extended with the registered codes in common use defined by later specifications; placeholders reserved without a name and codes registered by narrower protocol extensions are left out and compared as plain numbers.

    Parsing helpers turn the textual field values HTTP exchanges are made of into plain JavaScript ones, sparing each call site the splitting, unquoting and date conversion the field grammars call for. Malformed input is reported as stated or as missing, never as an error, so the consumer decides how to handle whatever a peer got wrong.

    Usage

    A named constant stands in for the status code it names:

    import { NotFound } from "@metreeca/http";

    (await fetch("https://api.example.com/data")).status === NotFound; // rather than 404

    A middleware of your own is written as a function wrapping the client it delegates to:

    import { Middleware } from "@metreeca/http";

    const trace: Middleware = fetch => async (input, init) => {

    const response = await fetch(input, init);

    console.log(response.status);

    return response;

    };

    A client is assembled once from the middlewares an application needs and shared wherever an exchange is performed:

    import { createFetch } from "@metreeca/http";
    import { basic } from "@metreeca/http/basic";
    import { success } from "@metreeca/http/success";

    const client = createFetch(
    basic("user", "secret"),
    trace,
    success()
    );

    // rejects unless response.ok

    const response = await client("https://api.example.com/data");

    The request accessors report what an exchange states, wherever it is stated, so that a bare target, a Request and a target paired with options are all read alike:

    import { getHeaders, getMethod, getTarget } from "@metreeca/http";

    getMethod("https://api.example.com/data", { method: "post" }); // "POST"
    getTarget("https://api.example.com/data#section").href; // "https://api.example.com/data"
    getHeaders(new Request("https://api.example.com/data", { headers: { Accept: "text/plain" } })); // Headers

    Numbers, dates and durations are reported as plain numbers and milliseconds:

    import { parseDuration, parseInstant, parseInteger } from "@metreeca/http";

    const { headers } = response; // as fetched above

    // undefined unless the field states a usable value

    parseInteger(headers.get("content-length")); // 1024
    parseInstant(headers.get("date")); // milliseconds since the epoch
    parseDuration(headers.get("age")); // milliseconds

    Structured values are taken apart along the separators their field grammar uses, one helper per separator: quotes protect whatever they enclose, a comma splits a list into elements, an equals sign splits a parameter into a name and a value, and a semicolon splits an item into a value and the parameters qualifying it:

    import { parseItem, parseList, parseParameter, parseQuoted } from "@metreeca/http";

    parseQuoted("\"quoted, value\""); // "quoted, value"
    parseList(headers.get("vary")); // [ "accept", "accept-encoding" ]
    parseParameter("max-age=60"); // [ "max-age", "60" ]
    parseItem(headers.get("content-type"))[1].get("charset"); // "utf-8"

    Composing them reads a field with more structure, and equally one whose grammar this package doesn't cover, with a parser of your own in place of the second step:

    parseList(headers.get("accept-encoding"))
    .map(element => parseItem(element)); // one value and its parameters per coding

    new Map(parseList(headers.get("cache-control"))
    .map(directive => parseParameter(directive))); // Map { "no-store" => "", "max-age" => "60" }
    Fetch

    Fetch function signature.

    Middleware

    Fetch middleware.

    createFetch

    Creates a fetch client from a chain of middlewares.

    getMethod

    Retrieves the method of a request.

    getTarget

    Retrieves the target URI of a request.

    getHeaders

    Retrieves the header fields of a request.

    parseInteger

    Parses a numeric field value.

    parseInstant

    Parses a date field value.

    parseDuration

    Parses a duration field value.

    parseQuoted

    Parses a value stated as a quoted string.

    parseList

    Parses a list field value.

    parseParameter

    Parses a name / value pair.

    parseItem

    Parses an item field value.

    Continue

    The initial part of the request was received and not yet rejected.

    SwitchingProtocols

    The server is switching to the protocol requested through the Upgrade header field.

    EarlyHints

    The server is likely to send a final response including the header fields of this informational response.

    OK

    The request succeeded.

    Created

    The request was fulfilled and one or more new resources were created.

    Accepted

    The request was accepted for processing, which hasn't completed.

    NonAuthoritativeInformation

    The request succeeded, but a transforming proxy modified the enclosed content.

    NoContent

    The request was fulfilled and there is no additional content to send.

    ResetContent

    The request was fulfilled and the user agent is expected to reset the document view that sent it.

    PartialContent

    The range request was fulfilled by transferring one or more parts of the selected representation.

    MultipleChoices

    The target resource has more than one representation, with information about the alternatives provided for selection.

    MovedPermanently

    The target resource was assigned a new permanent URI, to be used by future references.

    Found

    The target resource resides temporarily under a different URI.

    SeeOther

    The user agent is redirected to a different resource, as an indirect response to the original request.

    NotModified

    The condition of a conditional GET or HEAD request evaluated to false, leaving the cached response current.

    UseProxy

    The target resource is to be accessed through a proxy.

    TemporaryRedirect

    The target resource resides temporarily under a different URI, to be requested with the same method.

    PermanentRedirect

    The target resource was assigned a new permanent URI, to be requested with the same method.

    BadRequest

    The request won't be processed, as it is perceived to be a client error.

    Unauthorized

    The request lacks valid authentication credentials for the target resource.

    PaymentRequired

    Reserved for future use.

    Forbidden

    The server understood the request but refuses to fulfil it.

    NotFound

    The origin server found no current representation for the target resource, or won't disclose that one exists.

    MethodNotAllowed

    The request method is known by the origin server but not supported by the target resource.

    NotAcceptable

    No response matching the proactive content negotiation header fields of the request can be produced.

    ProxyAuthenticationRequired

    The client needs to authenticate with a proxy.

    RequestTimeout

    No complete request message was received within the time the server was prepared to wait.

    Conflict

    The request conflicts with the current state of the target resource.

    Gone

    Access to the target resource is no longer available at the origin server, likely permanently.

    LengthRequired

    The request is refused without a defined Content-Length header field.

    PreconditionFailed

    One or more conditions given in the request header fields evaluated to false.

    ContentTooLarge

    The request content is larger than the server is willing or able to process.

    URITooLong

    The target URI is longer than the server is willing to interpret.

    UnsupportedMediaType

    The request content is in a format unsupported by this method on the target resource.

    RangeNotSatisfiable

    The ranges in the Range header field were rejected, none of them being satisfiable for the selected representation or too many having been requested.

    ExpectationFailed

    The expectation given in the Expect header field couldn't be met.

    MisdirectedRequest

    The request was directed at a server unable or unwilling to answer authoritatively for the target URI.

    UnprocessableContent

    The request content was syntactically correct, but its instructions couldn't be processed.

    UpgradeRequired

    The request is refused under the current protocol, but might be served after an upgrade.

    PreconditionRequired

    The origin server requires the request to be conditional.

    TooManyRequests

    The client sent too many requests within a given amount of time.

    RequestHeaderFieldsTooLarge

    The request is refused because its header fields are too large.

    UnavailableForLegalReasons

    Access to the resource is denied as a consequence of a legal demand.

    InternalServerError

    The server met an unexpected condition preventing it from fulfilling the request.

    NotImplemented

    The server doesn't support the functionality required to fulfil the request.

    BadGateway

    The server, acting as a gateway or proxy, received an invalid response from an inbound server.

    ServiceUnavailable

    The server is temporarily unable to handle the request, for instance under overload or scheduled maintenance.

    GatewayTimeout

    The server, acting as a gateway or proxy, received no timely response from an upstream server.

    HTTPVersionNotSupported

    The server doesn't support, or refuses to support, the major HTTP version of the request.

    NetworkAuthenticationRequired

    The client needs to authenticate to gain network access.