import { DeepReadonly } from 'apprt-core/Types'; /** * Exports some default content types as optional utilities. * * @example use JSON content type in request headers * ```ts * import { apprtFetch, ContentType } from "apprt-fetch"; * * apprtFetch(url, { * method: "POST", * headers: { * "Content-Type": ContentType.JSON_UTF8, * "Accept": ContentType.JSON * } * }); * ``` */ declare enum ContentType { /** * Content-Type: text/plain */ TEXT_PLAIN = "text/plain", /** * Content-Type: text/plain;charset=UTF-8 */ TEXT_PLAIN_UTF8 = "text/plain;charset=UTF-8", /** * Content-Type: application/json */ JSON = "application/json", /** * Content-Type: application/json;charset=UTF-8 */ JSON_UTF8 = "application/json;charset=UTF-8", /** * Content-Type: application/xml */ XML = "application/xml", /** * Content-Type: application/xml;charset=UTF-8 */ XML_UTF8 = "application/xml;charset=UTF-8", /** * Content-Type: text/xml */ TEXT_XML = "text/xml", /** * Content-Type: text/xml;charset=UTF-8 */ TEXT_XML_UTF8 = "text/xml;charset=UTF-8", /** * Content-Type: application/x-www-form-urlencoded */ FORM_URLENCODED = "application/x-www-form-urlencoded", /** * Content-Type: application/x-www-form-urlencoded;charset=UTF-8 */ FORM_URLENCODED_UTF8 = "application/x-www-form-urlencoded;charset=UTF-8" } /** * Provides a wrapper around the browsers `fetch` API. * * @example Fetch a json file * ```ts * import { apprtFetch, ContentType} from "apprt-fetch"; * * // execute a get request * const response = await apprtFetch("https://httpbin.org/json", { * // query parameters f=json * query: { f: "json" }, * headers: { * // accept only json responses * "Accept": ContentType.JSON * }, * // throw error if response status is not 2XX * checkStatus: true * }); * * // Parse the response body as json. * const data = await response.json(); * ``` * @example Fetch a json file with apprtFetchJson * ```ts * import { apprtFetchJson } from "apprt-fetch"; * * // execute a get request * const data = await apprtFetchJson("https://httpbin.org/json", { * // query parameters f=json * query: { f: "json" } * }); * ``` * * @example POST x-www-form-urlencoded content * ```ts * import { apprtFetch, ContentType } from "apprt-fetch"; * * // execute a POST request * const response = await apprtFetch("https://httpbin.org/post", { * // declare that POST should be used * method: "POST", * // throw error if response status is not 2XX * checkStatus: true, * headers: { * // accept only json responses * "Accept": ContentType.JSON * }, * // Specify the POST-Body with URLSearchParams. * // The "Content-Type" Header is automatically set to * // "application/x-www-form-urlencoded;charset=UTF-8" * body: new URLSearchParams({ f: "json" }) * }); * * // Parse the response body as json. * const data = await response.json(); * ``` * * @example POST x-www-form-urlencoded content with flag queryTransport:'form' * ```ts * import { apprtFetch, ContentType } from "apprt-fetch"; * * // execute a POST request * const response = await apprtFetch("https://httpbin.org/post", { * // declare that POST should be used * method: "POST", * // throw error if response status is not 2XX * checkStatus: true, * * headers: { * // accept only json responses * "Accept": ContentType.JSON * }, * * // normally this would stay url parameters ?f=json * query: { f: "json" }, * * // but this flags converts the query to the body * queryTransport: "form" * }); * * // Parse the response body as json. * const data = await response.json(); * ``` * @example POST application/json content * ```ts * import { apprtFetch, ContentType } from "apprt-fetch"; * * // execute a POST request * const response = await apprtFetch("https://httpbin.org/post", { * // declare that POST should be used * method: "POST", * // throw error if response status is not 2XX * checkStatus: true, * headers: { * // Set the Content-Type of the body * "Content-Type": ContentType.JSON_UTF8, * // accept only json responses * "Accept": ContentType.JSON * }, * // Specify the POST-Body * body: JSON.stringify({ id: "test" }) * }); * * // Parse the response body as json. * const data = await response.json(); * ``` * @module */ /** * Specifies a proxy rule. * Requests targeting the `origin` server of a proxy rule will use the configured proxy server * to fetch the resource. */ interface ProxyRule { /** * An origin to match against request URLs. * URLs matching this origin pattern will use the configured `proxyUrl` (if present) * or the default proxy URL. * * Origins must contain protocol, a hostname and (optionally) a port. * For example, `https://subdomain.arcgis.com` is a valid origin. */ origin: string; /** * URL to a server endpoint that can act as proxy. * If this URL is not specified, a default proxy will be used. */ proxyUrl?: string; } /** * Represents a trusted server configuration. * * Trusted servers automatically receive user credentials (e.g. cookies) by default, * so there is no need to specify security settings on individual requests. */ interface TrustedServer { /** * An origin to match against request URLs. * * Origins must contain protocol, a hostname and (optionally) a port. * For example, `https://subdomain.arcgis.com` is a valid origin. */ origin: string; } /** Properties that should not be changed from an interceptor. */ type ReadonlyInitProperties = "query" | "timeoutMillis" | "checkStatus" | "signal" | "context"; /** * Options passed into interceptors. * Most options can be modified to customize the request that is about to be sent. */ type InterceptorOptions = Omit & Readonly> & { method: string; headers: Headers; query: undefined; }; /** * Arguments available to 'before' interceptors. */ interface BeforeInterceptorData { /** * The current request's target URL, including query parameters. * Can be modified to redirect the request to a different location. */ target: URL; /** Other request options (e.g. headers). */ readonly options: InterceptorOptions; /** * The context object is a per-request object that is passed to all * interceptors. * It can be used to keep interceptor state for a request. * * Use a sensible namespace string or a symbol to store state * to avoid naming collisions. */ readonly context: Record; /** AbortSignal for cancellation support. */ readonly signal?: AbortSignal; } /** * Arguments available to 'after' interceptors. */ interface AfterInterceptorData { /** * The request's target URL, including query parameters. * This is the original URL, before the request was potentially re-routed over a proxy server. */ readonly target: URL; /** The options used when making the request. */ readonly options: InterceptorOptions; /** The request that was sent to the server. */ readonly request: Request; /** The response returned by the server. */ readonly response: Response; /** * The context object is a per-request object that is passed to all * interceptors. * It can be used to keep interceptor state for a request. * * Use a sensible namespace string or a symbol to store state * to avoid naming collisions. */ readonly context: Record; /** AbortSignal for cancellation support. */ readonly signal?: AbortSignal; } /** * An interceptor can intercept and manipulate requests (and their responses) before * or after they have been sent to the server. */ interface Interceptor { /** * This method will be invoked before a request is sent to the server. * The implementor may alter the input arguments (e.g. query parameters in {@link BeforeInterceptorData.target}). */ before?(data: BeforeInterceptorData): void | undefined | Promise; /** * This method will be invoked after the server responded to a request. * The implementor may substitute a custom response instead. */ after?(data: AfterInterceptorData): void | Response | Promise; } /** * A handle allows the holder to destroy or remove a resource. */ interface Handle { /** * Performs a cleanup action. */ remove(): void; } /** * Global configuration of this bundle. */ interface Config { /** * Maximum length of an url before a GET request is switched to POST * (if {@link ApprtRequestInit.supportsPostSwitching | supportsPostSwitching} is true for a request). * GET requests altered in this way will have their query parameters * placed into the new POST request's body (as content-type application/x-www-form-urlencoded). * * Switching to POST requests can be disabled entirely by setting this property to a value `<= 0`. */ maxUrlLength: number; /** * Default time in milliseconds after which fetch aborts with a timeout. */ timeoutMillis: number; /** * The default proxy to use. */ defaultProxy: string | undefined; /** * If this is `true`, proxy support will be completely disabled. */ disableProxySupport: boolean; /** * Usage rules for proxied requests. * * When a proxy rule matches a request URL, the proxy will be * chosen to perform the request instead. */ readonly proxyRules: DeepReadonly[]; /** * Usages rules for trusted servers. * * apprt-fetch will automatically send credentials to these servers. */ readonly trustedServers: DeepReadonly[]; /** * Globally registered interceptors. */ readonly interceptors: DeepReadonly[]; /** * Adds a new proxy rule to the configuration. * Requests that match the rule's `origin` will use the specified `proxyUrl`. * * Note: there can only be one proxy rule for an origin. */ addProxyRule(rule: ProxyRule): void; /** * Removes a proxy rule from the configuration. */ removeProxyRule(rule: Pick): void; /** * Adds a new trusted server rule to the configuration. * Requests that match the rule will send credentials automatically, * without the need to declare it in individual requests. * * Note: there can only be one trusted server rule for an origin. */ addTrustedServer(server: TrustedServer): void; /** * Removes a trusted server rule from the configuration. */ removeTrustedServer(server: Pick): void; /** * Registers a global interceptor. * Use the handle returned by this method to deregister the interceptor * when it is no longer needed. */ registerInterceptor(interceptor: Interceptor): Handle; } /** Used to control the proxy mode for requests. */ type ProxyMode = "force-on" | "force-off" | "default"; /** * Request options supported by apprt-fetch. * This is an extension of the Browser's native fetch options. * * See also the init parameter of [apprt-fetch](https://developer.mozilla.org/en-US/docs/Web/API/fetch) * for a list of all options provided by the browser. */ interface ApprtRequestInit extends RequestInit { /** * Time in milliseconds after which the fetch aborts with a timeout. * Defaults to the timeout settings on the global configuration object: `config`. */ timeoutMillis?: number; /** * Ensures that the target resource is fresh from the server. * This is a shorthand for the fetch option `cache: "no-store"`. */ preventCache?: boolean; /** * If true, throws an error if the response is not `ok`, i.e. if * the response status code is not between 200 and 299. * * Default: false. */ checkStatus?: boolean; /** * By default, requests will use a proxy only if a proxy rule matches. * * If `"force-on"` is configured, the request will always use a proxy server, * falling back to the default proxy if no proxy rule matches. * An error will be thrown if no default proxy is configured in this case. * * If `"force-off"` is used, no proxy server will be used, even if a proxy rule would match. */ proxyMode?: ProxyMode; /** * If set to `true`, GET requests with very long URLs (see {@link Config.maxUrlLength}) * will automatically switch to POST requests. * * Default: `false` */ supportsPostSwitching?: boolean; /** * Convenience option to add additional query arguments to the request. * The transport of the given value depends on the value of `queryTransport`. * By default, query arguments passed here will be appended to the query part of the request URL. */ query?: string | URLSearchParams | Record; /** * Configures the way the `query` value is transported to the server. * * - Use the value `"url"` (the default) to append the query to the request url. * - Use `"form"` instead to set the request body to `query` (encoded as `application/x-www-form-urlencoded`). * No other request body should be specified in this case. * * If `query` is a string, then it should already be URL encoded. * If `query` is an instance of URLSearchParams, all params will simply be copied. * If `query` is a plain object, all properties will be serialized by calling `objectToQuery()` from * `apprt-core/url-utils`. * * Default: `"url"`. */ queryTransport?: "url" | "form"; /** * Arbitrary settings that can be read by interceptors. */ context?: Record; } /** * Represents a request location. * Can be used as an argument to this bundle's `fetch()` function. */ type ApprtRequestTarget = string | URL; /** * Get global configuration options for the apprt-fetch bundle. */ declare function getConfig(): Config; /** * Fetches the specified resource. * Works like the browser's `fetch()` function, but supports a few extensions. * * @see https://developer.mozilla.org/en-US/docs/Web/API/fetch * * @example * * Basic usage: * * ```ts * import { apprtFetch } from "apprt-fetch"; * const response = await apprtFetch("https://httpbin.org/get"); * if (!response.ok) { * throw new Error(`Request failed with status: ${response.status}`); * } * const data = await response.json(); * ``` * * See the bundle `README` for more advanced use cases. */ declare function apprtFetch(target: ApprtRequestTarget, init?: ApprtRequestInit): Promise; /** * Fetches the specified resource and expects a JSON encoded response. * It is a small helper to make fetching of json data more simple. * It has the `checkStatus` flag enabled by default and sets the Accept Header to 'application/json'. * * @example * * Basic usage: * * ```ts * import { apprtFetchJson } from "apprt-fetch"; * const jsonData = await apprtFetchJson("https://httpbin.org/get"); * // do something with the json data * ``` */ declare function apprtFetchJson(target: ApprtRequestTarget, init?: ApprtRequestInit): Promise; /** * Options for the {@link getProxiedUrl} function. */ interface ProxyUrlOptions { /** Force usage of default proxy if no proxy rule matches the given target URL. */ force?: boolean; /** Return undefined if no proxy server is being used. */ check?: boolean; } /** * Returns an URL to fetch the resource at `target` that uses a proxy server if necessary. * * By default, a proxy server will only be used if there is a matching proxy server rule. * If `force` is `true`, the default proxy (if configured) will always be used if no other rule matches. * * The default configuration always returns a valid URL, even if no proxy server will be used. * If `check` is `true`, the function will return `undefined` instead to signal that there was no matching rule. */ declare function getProxiedUrl(target: ApprtRequestTarget): URL; declare function getProxiedUrl(target: ApprtRequestTarget, options?: ProxyUrlOptions & { check?: false; }): URL; declare function getProxiedUrl(target: ApprtRequestTarget, options?: ProxyUrlOptions): URL | undefined; /** * Represents a custom implementation of the apprt-fetch library. * Used for testing. */ interface CustomFetch { /** A separate instance of the configuration (non-global). */ readonly config: Config; /** Call this method to clean up any state associated with this instance. */ destroy(): void; /** Fetches the given target and returns the response. */ fetch(target: ApprtRequestTarget, init?: ApprtRequestInit): Promise; /** Fetches JSON data from the given target and returns the response data. */ fetchJson(target: ApprtRequestTarget, init?: ApprtRequestInit): Promise; } /** Function signature required by `createCustomFetch`. */ type BasicFetchFunction = (request: Request) => Promise; /** * Creates a custom fetch instance with a user defined 'backend' function. * This is useful for testing if you do not want your requests to against an actual backend service. * * The implementation returned by this function will implement all the usual features of apprt-fetch * but will call the provided `impl` function instead of using the browser's `fetch` API * to retrieve a response. */ declare function createCustomFetch(options: { impl: BasicFetchFunction; }): CustomFetch; /** * Returns an implementation of `CustomFetch` that uses the global fetch function(s). * This is convenient for writing testable code: a class can accept a `CustomFetch` instance * for testing and for production. */ declare function getGlobalImpl(): CustomFetch; export { ContentType, apprtFetch, apprtFetchJson, createCustomFetch, apprtFetch as fetch, getConfig, getGlobalImpl, getProxiedUrl }; export type { AfterInterceptorData, ApprtRequestInit, ApprtRequestTarget, BasicFetchFunction, BeforeInterceptorData, Config, CustomFetch, Handle, Interceptor, InterceptorOptions, ProxyMode, ProxyRule, ProxyUrlOptions, TrustedServer };