openapi-hooks
Version:
Magical fetch inference for OpenAPI with React Query support
132 lines • 3.6 kB
JavaScript
// src/index.ts
var ApiError = class _ApiError extends Error {
constructor(message, status, response, data) {
super(message);
this.status = status;
this.response = response;
this.data = data;
this.name = "ApiError";
}
static fromResponse(response, data) {
return new _ApiError(
response.statusText || `HTTP ${response.status}`,
response.status,
response,
data
);
}
static fromNetworkError(error) {
return new _ApiError(
`Network error: ${error.message}`,
0,
void 0,
void 0
);
}
};
var defaultEncodeBody = (data, contentType) => {
if (contentType === void 0) {
return;
}
switch (contentType) {
case "application/json":
case "application/json; charset=utf-8":
return JSON.stringify(data);
default:
throw new Error("Unsupported content type: " + contentType);
}
};
var defaultDecodeResponse = async (response, responseContentType) => {
switch (responseContentType) {
// eslint-disable-next-line unicorn/no-null
case null:
return {
status: response.status,
headers: response.headers
};
case "text/plain; charset=utf-8":
return {
status: response.status,
contentType: responseContentType,
data: await response.text()
};
case "application/json; charset=utf-8":
return {
status: response.status,
contentType: responseContentType,
data: await response.json(),
headers: response.headers
};
default:
throw new Error("Unsupported content type: " + responseContentType);
}
};
var createFetch = (options) => {
const {
baseUrl = window.location.toString(),
headers: defaultHeaders,
onError,
fetch: fetchFn = fetch,
decodeResponse = defaultDecodeResponse,
encodeBody = defaultEncodeBody
} = options ?? {};
return async (path, method, options2) => {
const {
query,
header,
path: pathParameters,
contentType,
data,
fetchOptions
} = options2;
if (pathParameters) {
for (const [key, value] of Object.entries(pathParameters)) {
path = path.toString().replace(`{${key}}`, value);
}
}
const url = new URL(`.${path.toString()}`, baseUrl);
if (query) {
for (const [key, value] of Object.entries(query)) {
if (!value) continue;
url.searchParams.set(key, value.toString());
}
}
const headers = new Headers();
if (defaultHeaders) {
let addDefaultHeaders = typeof defaultHeaders === "function" ? await defaultHeaders() : defaultHeaders;
for (const [key, value] of Object.entries(addDefaultHeaders)) {
headers.set(key, value);
}
}
if (contentType) {
headers.set("Content-Type", contentType);
}
if (header) {
for (const [key, value] of Object.entries(header)) {
headers.set(key, value.toString());
}
}
const baseOptions = {
method: method.toUpperCase(),
headers,
body: encodeBody(data, contentType)
};
const response = await fetchFn(
url,
fetchOptions ? typeof fetchOptions === "function" ? fetchOptions(baseOptions) : {
...baseOptions,
...fetchOptions
} : baseOptions
);
if (!response.ok) {
onError?.(ApiError.fromResponse(response));
}
const responseContentType = response.headers.get("content-type");
return await decodeResponse(response, responseContentType);
};
};
export {
ApiError,
createFetch
};
//# sourceMappingURL=index.js.map