UNPKG

@basetime/a2w-api-ts

Version:

Client library that communicates with the addtowallet API.

145 lines (144 loc) 4.71 kB
import { Logger } from '../Logger'; import { AuthProvider } from '../provider/AuthProvider'; import { Requester } from './Requester'; /** * Options accepted by `HttpRequester`. */ export interface HttpRequesterOptions { /** * The API base URL. Defaults to {@link DEFAULT_BASE_URL}. */ baseUrl?: string; } /** * Makes authenticated HTTP requests to the Addtowallet API. * * All state — base URL, auth provider, logger, user agent — lives on the instance, so * multiple `HttpRequester` (and therefore `Client`) instances may coexist in the same * process targeting different environments. */ export default class HttpRequester implements Requester { /** * The authentication object. * * Exposed via a read-only getter. Use {@link setAuth} to change it so the logger and * base URL are wired into the new provider. */ private _auth?; /** * The logger. */ protected logger: Logger; /** * The user agent string. */ protected userAgent: string; /** * The API base URL (e.g. `https://app.addtowallet.io/api/v1`). */ protected baseUrl: string; /** * The derived site base URL (the API base URL with a trailing `/api/v1` stripped). * * Used by `siteRoot`-mode endpoints like `BarcodesEndpoint` and `WidgetsEndpoint` * to target routes mounted outside `/api/v1`. */ protected siteBaseUrl: string; /** * Constructor. * * @param auth The authentication provider. * @param logger The logger to use. * @param options Additional options (currently just `baseUrl`). */ constructor(auth?: AuthProvider, logger?: Logger, options?: HttpRequesterOptions); /** * The authentication provider currently in use. * * Read-only from outside the class; assignment is a TypeScript error. Use * {@link setAuth} to change it. */ get auth(): AuthProvider | undefined; /** * @inheritdoc */ setBaseUrl: (url: string) => void; /** * @inheritdoc */ getBaseUrl: () => string; /** * @inheritdoc */ getSiteBaseUrl: () => string; /** * @inheritdoc */ setAuth: (auth: AuthProvider) => void; /** * @inheritdoc */ setUserAgent: (userAgent: string) => void; /** * @inheritdoc */ getLogger: () => Logger; /** * @inheritdoc */ doGet: <T>(url: string, authenticate?: boolean) => Promise<T>; /** * @inheritdoc */ doPost: <T>(url: string, body: any, authenticate?: boolean) => Promise<T>; /** * @inheritdoc */ doPut: <T>(url: string, body: any, authenticate?: boolean) => Promise<T>; /** * @inheritdoc */ doDelete: <T>(url: string, authenticate?: boolean, body?: any) => Promise<T>; /** * @inheritdoc * * When `url` is a fully-qualified URL (starts with `http://` or `https://`) it is used * as-is without prepending the configured API base URL and without injecting the * `api=true` marker. This lets endpoint helpers target routes that live outside * `/api/v1` (e.g. `/barcodes`, `/widgets`) while still benefiting from the shared * header, auth, and error-handling logic. * * On a 401 response and when an auth provider is configured, the request is retried * once after `auth.refresh()` succeeds; further 401s are surfaced as `ApiError`s. */ fetch: <T>(url: string, options?: RequestInit, authenticate?: boolean) => Promise<T>; /** * Internal implementation of {@link fetch} that tracks whether the current call is * already a 401 retry, so we never recurse more than once. * * @param url The url to send the request to. * @param options The fetch options. * @param authenticate Whether to authenticate the request. * @param isRetry Whether this is the 401-recovery retry pass. */ private fetchInternal; /** * Resolves a caller-supplied URL into the final absolute URL that will be sent. * * - Absolute URLs (`http://`/`https://`) are returned unchanged. * - Relative URLs are joined with {@link baseUrl}. * - The `api=true` marker is appended to the resolved URL's query string only when * it isn't already present. * * @param url The raw URL passed to {@link fetch}. */ private resolveUrl; /** * Builds the headers for a single request: User-Agent, default Accept/Content-Type, * and (when applicable) Authorization. * * @param options The caller's fetch options. * @param authenticate Whether to attach the bearer token. */ private buildHeaders; }