add header to fetch

This commit is contained in:
Lee 2023-10-17 23:30:42 +01:00
parent ee299274a1
commit 4095d8d2b3

View File

@ -1,21 +1,23 @@
import { SsrDataFormatError } from "../others/errors";
import ssrConfig from "../ssr-config";
import { MINUTE } from "../utils/date";
import createNetworkCache from "./cache";
import {
SsrHttpClientError,
SsrHttpNotFoundError,
SsrHttpRateLimitError,
SsrHttpResponseError,
SsrHttpServerError, SsrHttpUnauthenticatedError,
SsrHttpServerError,
SsrHttpUnauthenticatedError,
SsrHttpUnauthorizedError,
SsrHttpUnprocessableEntityError,
SsrNetworkError,
} from './errors'
import {SsrDataFormatError} from '../others/errors'
import {parseRateLimitHeaders} from './utils'
import {MINUTE} from '../utils/date'
import createNetworkCache from './cache';
} from "./errors";
import { parseRateLimitHeaders } from "./utils";
const networkCache = createNetworkCache();
const checkResponse = response => {
const checkResponse = (response) => {
if (response.ok) {
// response.status >= 200 && response.status < 300
return response;
@ -39,7 +41,7 @@ const checkResponse = response => {
default:
throw new SsrHttpResponseError(response);
}
}
};
const getOptionsWithCacheKey = (url, options, cacheType = null) => {
if (options && options.cacheKey) {
@ -48,7 +50,7 @@ const getOptionsWithCacheKey = (url, options, cacheType = null) => {
return options;
}
if (options && options.method && options.method.toLowerCase() !== 'get') {
if (options && options.method && options.method.toLowerCase() !== "get") {
delete options.cacheKey;
delete options.cacheTtl;
@ -56,68 +58,121 @@ const getOptionsWithCacheKey = (url, options, cacheType = null) => {
return options;
}
const newOptions = options ? {...options} : {};
const newOptions = options ? { ...options } : {};
if (!newOptions || !newOptions.hasOwnProperty('cacheTtl')) {
if (!newOptions || !newOptions.hasOwnProperty("cacheTtl")) {
newOptions.cacheTtl = MINUTE;
}
return {...newOptions, cacheKey: `${cacheType ? cacheType + ':' : ''}${url}`};
}
return {
...newOptions,
cacheKey: `${cacheType ? cacheType + ":" : ""}${url}`,
};
};
const setCacheIfNeeded = (response, cacheKey, cacheTtl) => {
if (cacheKey && cacheTtl) networkCache.set(cacheKey, response, cacheTtl);
return {...response, cached: false};
}
return { ...response, cached: false };
};
export async function fetchUrl(url, options = {}, cors = true) {
try {
const response = await fetch(url, {...options, ...(cors ? {mode: 'cors'} : null)});
console.log(ssrConfig.name);
const response = await fetch(url, {
...options,
headers: {
"x-requested-with": ssrConfig.name,
},
...(cors ? { mode: "cors" } : null),
});
return checkResponse(response);
} catch (err) {
if (err instanceof TypeError) throw new SsrNetworkError('Network error');
if (err instanceof TypeError) throw new SsrNetworkError("Network error");
throw err;
}
}
export async function fetchJson(url, {cacheTtl = null, maxAge = null, ...restOptions} = {}) {
const options = getOptionsWithCacheKey(url, {cacheTtl, maxAge, ...restOptions}, 'json');
export async function fetchJson(
url,
{ cacheTtl = null, maxAge = null, ...restOptions } = {}
) {
const options = getOptionsWithCacheKey(
url,
{ cacheTtl, maxAge, ...restOptions },
"json"
);
const {cacheKey: fetchCacheKey, cacheTtl: fetchCacheTtl, maxAge: fetchMaxAge, ...fetchOptions} = getOptionsWithCacheKey(url, options, 'json');
const {
cacheKey: fetchCacheKey,
cacheTtl: fetchCacheTtl,
maxAge: fetchMaxAge,
...fetchOptions
} = getOptionsWithCacheKey(url, options, "json");
if (fetchCacheKey && fetchCacheTtl) {
const cachedResponse = networkCache.get(fetchCacheKey, fetchMaxAge);
if (cachedResponse !== undefined) return {...cachedResponse, cached: true};
if (cachedResponse !== undefined)
return { ...cachedResponse, cached: true };
}
return fetchUrl(url, fetchOptions)
.then(async response => {
.then(async (response) => {
const body = await response.json();
return setCacheIfNeeded({headers: response.headers, rateLimit: parseRateLimitHeaders(response), body}, fetchCacheKey, fetchCacheTtl);
})
.catch(err => {
throw (err instanceof SyntaxError ? new SsrDataFormatError('JSON parse error', err) : err);
return setCacheIfNeeded(
{
headers: response.headers,
rateLimit: parseRateLimitHeaders(response),
body,
},
fetchCacheKey,
fetchCacheTtl
);
})
.catch((err) => {
throw err instanceof SyntaxError
? new SsrDataFormatError("JSON parse error", err)
: err;
});
}
export async function fetchHtml(url, {cacheTtl = null, maxAge = null, ...restOptions} = {}) {
const options = getOptionsWithCacheKey(url, {cacheTtl, maxAge, ...restOptions}, 'json');
export async function fetchHtml(
url,
{ cacheTtl = null, maxAge = null, ...restOptions } = {}
) {
const options = getOptionsWithCacheKey(
url,
{ cacheTtl, maxAge, ...restOptions },
"json"
);
const {cacheKey: fetchCacheKey, cacheTtl: fetchCacheTtl, maxAge: fetchMaxAge, ...fetchOptions} = getOptionsWithCacheKey(url, options, 'html');
const {
cacheKey: fetchCacheKey,
cacheTtl: fetchCacheTtl,
maxAge: fetchMaxAge,
...fetchOptions
} = getOptionsWithCacheKey(url, options, "html");
if (fetchCacheKey && fetchCacheTtl) {
const cachedResponse = networkCache.get(fetchCacheKey, fetchMaxAge);
if (cachedResponse !== undefined) return {...cachedResponse, cached: true};
if (cachedResponse !== undefined)
return { ...cachedResponse, cached: true };
}
return fetchUrl(url, fetchOptions)
.then(async response => {
const body = await response.text();
return fetchUrl(url, fetchOptions).then(async (response) => {
const body = await response.text();
return setCacheIfNeeded({headers: response.headers, rateLimit: parseRateLimitHeaders(response), body: new DOMParser().parseFromString(body, 'text/html')}, fetchCacheKey, fetchCacheTtl);
})
}
return setCacheIfNeeded(
{
headers: response.headers,
rateLimit: parseRateLimitHeaders(response),
body: new DOMParser().parseFromString(body, "text/html"),
},
fetchCacheKey,
fetchCacheTtl
);
});
}