UNPKG

dax

Version:

Cross platform shell tools inspired by zx.

306 lines 13.4 kB
import * as dntShim from "../_dnt.shims.js"; import { Path } from "../deps/jsr.io/@david/path/0.3.2/mod.js"; import { type Delay, type WriteFileOptions } from "../deps/jsr.io/@david/shell/0.5.4/mod.js"; import { symbols } from "../deps/jsr.io/@david/shell/0.5.4/internal.js"; import type { ProgressBar } from "./console/mod.js"; interface RequestBuilderState { noThrow: boolean | number[]; url: string | URL | undefined; body: dntShim.BodyInit | undefined; cache: dntShim.RequestCache | undefined; headers: Record<string, string | undefined>; integrity: string | undefined; keepalive: boolean | undefined; method: string | undefined; mode: dntShim.RequestMode | undefined; progressBarFactory: ((message: string) => ProgressBar) | undefined; redirect: dntShim.RequestRedirect | undefined; referrer: string | undefined; referrerPolicy: dntShim.ReferrerPolicy | undefined; progressOptions: { noClear: boolean; } | undefined; onProgress: ((event: ProgressEvent) => void)[]; timeout: number | undefined; signal: AbortSignal | undefined; beforeRequest: BeforeRequestCallback[] | undefined; } /** Callback invoked before a request is sent. * * Receives the current builder and may return a (possibly modified) builder * to use for the request. Returning the builder unchanged — or returning * nothing — is a no-op. * * The builder passed to the callback is wrapped in a Proxy that hides its * `.then`, so it isn't detected as a thenable by the JavaScript Promise * machinery. That makes it safe to `return builder.header(...)` from an * `async` function without the runtime recursively unwrapping the thenable * and triggering a fetch. Methods like `.header(...)` that return a new * builder return another such wrapped Proxy. * * The return type is loose because TypeScript infers the async return type * by following `PromiseLike` (the same logic the runtime uses), so e.g. * `async b => b.header(...)` is inferred as `Promise<RequestResponse>`. */ export type BeforeRequestCallback = (builder: RequestBuilder) => RequestBuilder | Promise<RequestBuilder> | Promise<RequestResponse> | void | Promise<void>; /** Event passed to an `onProgress` callback as bytes are received. */ export interface ProgressEvent { /** Cumulative number of bytes received so far. */ loaded: number; /** Total number of bytes expected from the `content-length` header, * or `undefined` if not provided by the server. */ total: number | undefined; } /** @internal */ export declare const withProgressBarFactorySymbol: unique symbol; /** * Builder API for downloading files. */ export declare class RequestBuilder implements PromiseLike<RequestResponse> { #private; [symbols.readable]: () => dntShim.ReadableStream<Uint8Array>; then<TResult1 = RequestResponse, TResult2 = never>(onfulfilled?: ((value: RequestResponse) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): PromiseLike<TResult1 | TResult2>; /** Fetches and gets the response. */ fetch(): Promise<RequestResponse>; /** Specifies the URL to send the request to. */ url(value: string | URL | undefined): RequestBuilder; /** Sets multiple headers at the same time via an object literal. */ header(items: Record<string, string | undefined>): RequestBuilder; /** Sets a header to send with the request. */ header(name: string, value: string | undefined): RequestBuilder; /** * Do not throw if a non-2xx status code is received. * * By default the request builder will throw when * receiving a non-2xx status code. Specify this * to have it not throw. */ noThrow(value?: boolean): RequestBuilder; /** * Do not throw if a non-2xx status code is received * except for these excluded provided status codes. * * This overload may be especially useful when wanting to ignore * 404 status codes and have it return undefined instead. For example: * * ```ts * const data = await $.request(`https://crates.io/api/v1/crates/${crateName}`) * .noThrow(404) * .json<CratesIoMetadata | undefined>(); * ``` * * Note, use multiple arguments to ignore multiple status codes (ex. `.noThrow(400, 404)`) as * multiple calls to `.noThrow()` will overwrite the previous. */ noThrow(exclusionStatusCode: number, ...additional: number[]): RequestBuilder; body(value: dntShim.BodyInit | undefined): RequestBuilder; cache(value: dntShim.RequestCache | undefined): RequestBuilder; integrity(value: string | undefined): RequestBuilder; keepalive(value: boolean): RequestBuilder; method(value: string): RequestBuilder; mode(value: dntShim.RequestMode): RequestBuilder; /** @internal */ [withProgressBarFactorySymbol](factory: (message: string) => ProgressBar): RequestBuilder; redirect(value: dntShim.RequestRedirect): RequestBuilder; referrer(value: string | undefined): RequestBuilder; referrerPolicy(value: dntShim.ReferrerPolicy | undefined): RequestBuilder; /** Shows a progress bar while downloading with the provided options. */ showProgress(opts: { noClear?: boolean; }): RequestBuilder; /** Shows a progress bar while downloading. */ showProgress(show?: boolean): RequestBuilder; /** Adds a callback that is invoked as bytes are received from the response body. * * The callback fires once per chunk read from the network with the cumulative * number of bytes received and the total expected size (from the `content-length` * header, or `undefined` if the server didn't provide one). Multiple callbacks * may be registered by calling this method repeatedly; each is invoked in the * order it was added. */ onProgress(callback: (event: ProgressEvent) => void): RequestBuilder; /** Timeout the request after the specified delay throwing a `TimeoutError`. */ timeout(delay: Delay | undefined): RequestBuilder; /** Sets an abort signal for the request. When the signal is * aborted, the request will be cancelled. */ signal(signal: AbortSignal): RequestBuilder; /** Registers a callback that runs just before each request is sent. * * The callback receives the current builder and may return a (possibly * modified) builder to use for the request. Useful for asynchronously * resolving values such as auth tokens. * * ```ts * $.request(url).beforeRequest(async (builder) => { * return builder.header("Authorization", `Bearer ${await getAccessToken()}`); * }); * ``` * * Multiple `.beforeRequest(...)` calls compose: each registered callback runs * in the order it was added, with the builder produced by the previous one. * * The builder passed to the callback is in a special "passthrough" mode so * its `.then(...)` resolves with the builder itself (instead of fetching) — * this is what makes `return builder.header(...)` from an `async` function * safe. If you construct a fresh `new RequestBuilder()` inside the callback, * return it as `{ requestBuilder: ... }` to avoid accidental fetching. */ beforeRequest(callback: BeforeRequestCallback): RequestBuilder; /** Fetches and gets the response as an array buffer. */ arrayBuffer(): Promise<ArrayBuffer>; /** Fetches and gets the response as a blob. */ blob(): Promise<Blob>; /** Fetches and gets the response as form data. */ formData(): Promise<FormData>; /** Fetches and gets the response as JSON additionally setting * a JSON accept header if not set. */ json<TResult = any>(): Promise<TResult>; /** Fetches and gets the response as text. */ text(): Promise<string>; /** Pipes the response body to the provided writable stream. */ pipeTo(dest: dntShim.WritableStream<Uint8Array>, options?: dntShim.StreamPipeOptions): Promise<void>; /** * Pipes the response body to a file. * * @remarks The path will be derived from the request's url * and downloaded to the current working directory. * * @returns The path reference of the downloaded file. */ pipeToPath(options?: WriteFileOptions): Promise<Path>; /** * Pipes the response body to a file. * * @remarks If no path is provided then it will be derived from the * request's url and downloaded to the current working directory. * * @returns The path reference of the downloaded file. */ pipeToPath(path?: string | URL | Path | undefined, options?: WriteFileOptions): Promise<Path>; /** Pipes the response body through the provided transform. */ pipeThrough<T>(transform: { writable: dntShim.WritableStream<Uint8Array>; readable: dntShim.ReadableStream<T>; }): Promise<dntShim.ReadableStream<T>>; } interface RequestAbortController { controller: AbortController; /** Clears the timeout that may be set if there's a delay */ clearTimeout(): void; } /** Response of making a request where the body can be read. */ export declare class RequestResponse { #private; /** @internal */ constructor(opts: { response: Response; originalUrl: string; progressBar: ProgressBar | undefined; onProgress: ((event: ProgressEvent) => void)[]; contentLength: number | undefined; abortController: RequestAbortController; }); /** Raw response. */ get response(): Response; /** Response headers. */ get headers(): Headers; /** If the response had a 2xx code. */ get ok(): boolean; /** If the response is the result of a redirect. */ get redirected(): boolean; /** The underlying `AbortSignal` used to abort the request body * when a timeout is reached or when the `.abort()` method is called. */ get signal(): AbortSignal; /** Status code of the response. */ get status(): number; /** Status text of the response. */ get statusText(): string; /** URL of the response. */ get url(): string; /** Aborts */ abort(reason?: unknown): void; /** * Throws if the response doesn't have a 2xx code. * * This might be useful if the request was built with `.noThrow()`, but * otherwise this is called automatically for any non-2xx response codes. * * Note: this does not consume the body. If you don't intend to read the * body, call `cancelBody()` first to release the underlying resources. */ throwIfNotOk(): void; /** * Cancels the response body, releasing the underlying resources. * * Useful in conjunction with `.noThrow()` and `throwIfNotOk()` when you * don't intend to read the body. */ cancelBody(): Promise<void>; /** * Respose body as an array buffer. * * Note: Returns `undefined` when `.noThrow(404)` and status code is 404. */ arrayBuffer(): Promise<ArrayBuffer>; /** * Response body as a blog. * * Note: Returns `undefined` when `.noThrow(404)` and status code is 404. */ blob(): Promise<Blob>; /** * Response body as a form data. * * Note: Returns `undefined` when `.noThrow(404)` and status code is 404. */ formData(): Promise<FormData>; /** * Respose body as JSON. * * Note: Returns `undefined` when `.noThrow(404)` and status code is 404. */ json<TResult = any>(): Promise<TResult>; /** * Respose body as text. * * Note: Returns `undefined` when `.noThrow(404)` and status code is 404. */ text(): Promise<string>; /** Pipes the response body to the provided writable stream. */ pipeTo(dest: dntShim.WritableStream<Uint8Array>, options?: dntShim.StreamPipeOptions): Promise<void>; /** * Pipes the response body to a file. * * @remarks The path will be derived from the request's url * and downloaded to the current working directory. * * @remarks If the path is a directory, then the file name will be derived * from the request's url and the file will be downloaded to the provided directory * * @returns The path reference of the downloaded file */ pipeToPath(options?: WriteFileOptions): Promise<Path>; /** * Pipes the response body to a file. * * @remarks If no path is provided then it will be derived from the * request's url and downloaded to the current working directory. * * @remarks If the path is a directory, then the file name will be derived * from the request's url and the file will be downloaded to the provided directory * * @returns The path reference of the downloaded file */ pipeToPath(path?: string | URL | Path | undefined, options?: WriteFileOptions): Promise<Path>; /** Pipes the response body through the provided transform. */ pipeThrough<T>(transform: { writable: dntShim.WritableStream<Uint8Array>; readable: dntShim.ReadableStream<T>; }): dntShim.ReadableStream<T>; get readable(): dntShim.ReadableStream<Uint8Array>; } export declare function makeRequest(state: RequestBuilderState): Promise<RequestResponse>; export {}; //# sourceMappingURL=request.d.ts.map