"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.js var index_exports = {}; __export(index_exports, { createFinalURL: () => createFinalURL, createPathBasedClient: () => createPathBasedClient, createQuerySerializer: () => createQuerySerializer, default: () => createClient, defaultBodySerializer: () => defaultBodySerializer, defaultPathSerializer: () => defaultPathSerializer, mergeHeaders: () => mergeHeaders, randomID: () => randomID, removeTrailingSlash: () => removeTrailingSlash, serializeArrayParam: () => serializeArrayParam, serializeObjectParam: () => serializeObjectParam, serializePrimitiveParam: () => serializePrimitiveParam, wrapAsPathBasedClient: () => wrapAsPathBasedClient }); module.exports = __toCommonJS(index_exports); var PATH_PARAM_RE = /\{[^{}]+\}/g; var supportsRequestInitExt = () => { return typeof process === "object" && Number.parseInt(process?.versions?.node?.substring(0, 2)) >= 18 && process.versions.undici; }; function randomID() { return Math.random().toString(36).slice(2, 11); } function createClient(clientOptions) { let { baseUrl = "", Request: CustomRequest = globalThis.Request, fetch: baseFetch = globalThis.fetch, querySerializer: globalQuerySerializer, bodySerializer: globalBodySerializer, headers: baseHeaders, requestInitExt = void 0, ...baseOptions } = { ...clientOptions }; requestInitExt = supportsRequestInitExt() ? requestInitExt : void 0; baseUrl = removeTrailingSlash(baseUrl); const middlewares = []; async function coreFetch(schemaPath, fetchOptions) { const { baseUrl: localBaseUrl, fetch = baseFetch, Request = CustomRequest, headers, params = {}, parseAs = "json", querySerializer: requestQuerySerializer, bodySerializer = globalBodySerializer ?? defaultBodySerializer, body, ...init } = fetchOptions || {}; let finalBaseUrl = baseUrl; if (localBaseUrl) { finalBaseUrl = removeTrailingSlash(localBaseUrl) ?? baseUrl; } let querySerializer = typeof globalQuerySerializer === "function" ? globalQuerySerializer : createQuerySerializer(globalQuerySerializer); if (requestQuerySerializer) { querySerializer = typeof requestQuerySerializer === "function" ? requestQuerySerializer : createQuerySerializer({ ...typeof globalQuerySerializer === "object" ? globalQuerySerializer : {}, ...requestQuerySerializer }); } const serializedBody = body === void 0 ? void 0 : bodySerializer( body, // Note: we declare mergeHeaders() both here and below because it’s a bit of a chicken-or-egg situation: // bodySerializer() needs all headers so we aren’t dropping ones set by the user, however, // the result of this ALSO sets the lowest-priority content-type header. So we re-merge below, // setting the content-type at the very beginning to be overwritten. // Lastly, based on the way headers work, it’s not a simple “present-or-not” check becauase null intentionally un-sets headers. mergeHeaders(baseHeaders, headers, params.header) ); const finalHeaders = mergeHeaders( // with no body, we should not to set Content-Type serializedBody === void 0 || // if serialized body is FormData; browser will correctly set Content-Type & boundary expression serializedBody instanceof FormData ? {} : { "Content-Type": "application/json" }, baseHeaders, headers, params.header ); const requestInit = { redirect: "follow", ...baseOptions, ...init, body: serializedBody, headers: finalHeaders }; let id; let options; let request = new CustomRequest( createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer }), requestInit ); let response; for (const key in init) { if (!(key in request)) { request[key] = init[key]; } } if (middlewares.length) { id = randomID(); options = Object.freeze({ baseUrl: finalBaseUrl, fetch, parseAs, querySerializer, bodySerializer }); for (const m of middlewares) { if (m && typeof m === "object" && typeof m.onRequest === "function") { const result = await m.onRequest({ request, schemaPath, params, options, id }); if (result) { if (result instanceof CustomRequest) { request = result; } else if (result instanceof Response) { response = result; break; } else { throw new Error("onRequest: must return new Request() or Response() when modifying the request"); } } } } } if (!response) { try { response = await fetch(request, requestInitExt); } catch (error2) { let errorAfterMiddleware = error2; if (middlewares.length) { for (let i = middlewares.length - 1; i >= 0; i--) { const m = middlewares[i]; if (m && typeof m === "object" && typeof m.onError === "function") { const result = await m.onError({ request, error: errorAfterMiddleware, schemaPath, params, options, id }); if (result) { if (result instanceof Response) { errorAfterMiddleware = void 0; response = result; break; } if (result instanceof Error) { errorAfterMiddleware = result; continue; } throw new Error("onError: must return new Response() or instance of Error"); } } } } if (errorAfterMiddleware) { throw errorAfterMiddleware; } } if (middlewares.length) { for (let i = middlewares.length - 1; i >= 0; i--) { const m = middlewares[i]; if (m && typeof m === "object" && typeof m.onResponse === "function") { const result = await m.onResponse({ request, response, schemaPath, params, options, id }); if (result) { if (!(result instanceof Response)) { throw new Error("onResponse: must return new Response() when modifying the response"); } response = result; } } } } } if (response.status === 204 || request.method === "HEAD" || response.headers.get("Content-Length") === "0") { return response.ok ? { data: void 0, response } : { error: void 0, response }; } if (response.ok) { if (parseAs === "stream") { return { data: response.body, response }; } return { data: await response[parseAs](), response }; } let error = await response.text(); try { error = JSON.parse(error); } catch { } return { error, response }; } return { request(method, url, init) { return coreFetch(url, { ...init, method: method.toUpperCase() }); }, /** Call a GET endpoint */ GET(url, init) { return coreFetch(url, { ...init, method: "GET" }); }, /** Call a PUT endpoint */ PUT(url, init) { return coreFetch(url, { ...init, method: "PUT" }); }, /** Call a POST endpoint */ POST(url, init) { return coreFetch(url, { ...init, method: "POST" }); }, /** Call a DELETE endpoint */ DELETE(url, init) { return coreFetch(url, { ...init, method: "DELETE" }); }, /** Call a OPTIONS endpoint */ OPTIONS(url, init) { return coreFetch(url, { ...init, method: "OPTIONS" }); }, /** Call a HEAD endpoint */ HEAD(url, init) { return coreFetch(url, { ...init, method: "HEAD" }); }, /** Call a PATCH endpoint */ PATCH(url, init) { return coreFetch(url, { ...init, method: "PATCH" }); }, /** Call a TRACE endpoint */ TRACE(url, init) { return coreFetch(url, { ...init, method: "TRACE" }); }, /** Register middleware */ use(...middleware) { for (const m of middleware) { if (!m) { continue; } if (typeof m !== "object" || !("onRequest" in m || "onResponse" in m || "onError" in m)) { throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`"); } middlewares.push(m); } }, /** Unregister middleware */ eject(...middleware) { for (const m of middleware) { const i = middlewares.indexOf(m); if (i !== -1) { middlewares.splice(i, 1); } } } }; } var PathCallForwarder = class { constructor(client, url) { this.client = client; this.url = url; } GET = (init) => { return this.client.GET(this.url, init); }; PUT = (init) => { return this.client.PUT(this.url, init); }; POST = (init) => { return this.client.POST(this.url, init); }; DELETE = (init) => { return this.client.DELETE(this.url, init); }; OPTIONS = (init) => { return this.client.OPTIONS(this.url, init); }; HEAD = (init) => { return this.client.HEAD(this.url, init); }; PATCH = (init) => { return this.client.PATCH(this.url, init); }; TRACE = (init) => { return this.client.TRACE(this.url, init); }; }; var PathClientProxyHandler = class { constructor() { this.client = null; } // Assume the property is an URL. get(coreClient, url) { const forwarder = new PathCallForwarder(coreClient, url); this.client[url] = forwarder; return forwarder; } }; function wrapAsPathBasedClient(coreClient) { const handler = new PathClientProxyHandler(); const proxy = new Proxy(coreClient, handler); function Client() { } Client.prototype = proxy; const client = new Client(); handler.client = client; return client; } function createPathBasedClient(clientOptions) { return wrapAsPathBasedClient(createClient(clientOptions)); } function serializePrimitiveParam(name, value, options) { if (value === void 0 || value === null) { return ""; } if (typeof value === "object") { throw new Error( "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these." ); } return `${name}=${options?.allowReserved === true ? value : encodeURIComponent(value)}`; } function serializeObjectParam(name, value, options) { if (!value || typeof value !== "object") { return ""; } const values = []; const joiner = { simple: ",", label: ".", matrix: ";" }[options.style] || "&"; if (options.style !== "deepObject" && options.explode === false) { for (const k in value) { values.push(k, options.allowReserved === true ? value[k] : encodeURIComponent(value[k])); } const final2 = values.join(","); switch (options.style) { case "form": { return `${name}=${final2}`; } case "label": { return `.${final2}`; } case "matrix": { return `;${name}=${final2}`; } default: { return final2; } } } for (const k in value) { const finalName = options.style === "deepObject" ? `${name}[${k}]` : k; values.push(serializePrimitiveParam(finalName, value[k], options)); } const final = values.join(joiner); return options.style === "label" || options.style === "matrix" ? `${joiner}${final}` : final; } function serializeArrayParam(name, value, options) { if (!Array.isArray(value)) { return ""; } if (options.explode === false) { const joiner2 = { form: ",", spaceDelimited: "%20", pipeDelimited: "|" }[options.style] || ","; const final = (options.allowReserved === true ? value : value.map((v) => encodeURIComponent(v))).join(joiner2); switch (options.style) { case "simple": { return final; } case "label": { return `.${final}`; } case "matrix": { return `;${name}=${final}`; } // case "spaceDelimited": // case "pipeDelimited": default: { return `${name}=${final}`; } } } const joiner = { simple: ",", label: ".", matrix: ";" }[options.style] || "&"; const values = []; for (const v of value) { if (options.style === "simple" || options.style === "label") { values.push(options.allowReserved === true ? v : encodeURIComponent(v)); } else { values.push(serializePrimitiveParam(name, v, options)); } } return options.style === "label" || options.style === "matrix" ? `${joiner}${values.join(joiner)}` : values.join(joiner); } function createQuerySerializer(options) { return function querySerializer(queryParams) { const search = []; if (queryParams && typeof queryParams === "object") { for (const name in queryParams) { const value = queryParams[name]; if (value === void 0 || value === null) { continue; } if (Array.isArray(value)) { if (value.length === 0) { continue; } search.push( serializeArrayParam(name, value, { style: "form", explode: true, ...options?.array, allowReserved: options?.allowReserved || false }) ); continue; } if (typeof value === "object") { search.push( serializeObjectParam(name, value, { style: "deepObject", explode: true, ...options?.object, allowReserved: options?.allowReserved || false }) ); continue; } search.push(serializePrimitiveParam(name, value, options)); } } return search.join("&"); }; } function defaultPathSerializer(pathname, pathParams) { let nextURL = pathname; for (const match of pathname.match(PATH_PARAM_RE) ?? []) { let name = match.substring(1, match.length - 1); let explode = false; let style = "simple"; if (name.endsWith("*")) { explode = true; name = name.substring(0, name.length - 1); } if (name.startsWith(".")) { style = "label"; name = name.substring(1); } else if (name.startsWith(";")) { style = "matrix"; name = name.substring(1); } if (!pathParams || pathParams[name] === void 0 || pathParams[name] === null) { continue; } const value = pathParams[name]; if (Array.isArray(value)) { nextURL = nextURL.replace(match, serializeArrayParam(name, value, { style, explode })); continue; } if (typeof value === "object") { nextURL = nextURL.replace(match, serializeObjectParam(name, value, { style, explode })); continue; } if (style === "matrix") { nextURL = nextURL.replace(match, `;${serializePrimitiveParam(name, value)}`); continue; } nextURL = nextURL.replace(match, style === "label" ? `.${encodeURIComponent(value)}` : encodeURIComponent(value)); } return nextURL; } function defaultBodySerializer(body, headers) { if (body instanceof FormData) { return body; } if (headers) { const contentType = headers.get instanceof Function ? headers.get("Content-Type") ?? headers.get("content-type") : headers["Content-Type"] ?? headers["content-type"]; if (contentType === "application/x-www-form-urlencoded") { return new URLSearchParams(body).toString(); } } return JSON.stringify(body); } function createFinalURL(pathname, options) { let finalURL = `${options.baseUrl}${pathname}`; if (options.params?.path) { finalURL = defaultPathSerializer(finalURL, options.params.path); } let search = options.querySerializer(options.params.query ?? {}); if (search.startsWith("?")) { search = search.substring(1); } if (search) { finalURL += `?${search}`; } return finalURL; } function mergeHeaders(...allHeaders) { const finalHeaders = new Headers(); for (const h of allHeaders) { if (!h || typeof h !== "object") { continue; } const iterator = h instanceof Headers ? h.entries() : Object.entries(h); for (const [k, v] of iterator) { if (v === null) { finalHeaders.delete(k); } else if (Array.isArray(v)) { for (const v2 of v) { finalHeaders.append(k, v2); } } else if (v !== void 0) { finalHeaders.set(k, v); } } } return finalHeaders; } function removeTrailingSlash(url) { if (url.endsWith("/")) { return url.substring(0, url.length - 1); } return url; }