mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
5.1 KiB
109 lines
5.1 KiB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
import _debug from "debug";
|
|
import { serializeHeaders, unserializeHeaders } from "./headers.js";
|
|
const debug = _debug("fetch-mock-cache:core");
|
|
const origFetch = fetch;
|
|
/**
|
|
* Creates a new caching fetch implementation. Generally not used directly,
|
|
* instead use the same named function provided by the various run-time entry
|
|
* points.
|
|
*/
|
|
export default function createCachingMock({ Store, fetch, runtime, }) {
|
|
if (!Store)
|
|
throw new Error("No `Store` option was provided, but is required. See docs.");
|
|
if (!fetch)
|
|
fetch = origFetch;
|
|
// Init with options if passed as [ Store, { /* ... */ } ]
|
|
const store = Array.isArray(Store)
|
|
? new Store[0](Object.assign(Object.assign({}, Store[1]), { runtime }))
|
|
: new Store({ runtime });
|
|
const fetchCache = Object.assign(function cachingMockImplementation(urlOrRequest, requestInit) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
var _a, _b;
|
|
if (!urlOrRequest)
|
|
throw new Error("urlOrRequest is undefined");
|
|
// TODO, main options? merge?
|
|
const options = Array.isArray(fetchCache._options)
|
|
? fetchCache._options.shift()
|
|
: fetchCache._options;
|
|
const fetchRequest = typeof urlOrRequest === "string" || urlOrRequest instanceof URL
|
|
? new Request(urlOrRequest, requestInit)
|
|
: urlOrRequest;
|
|
const url = fetchRequest.url;
|
|
const clonedRequest = fetchRequest.clone();
|
|
const cacheContentRequest = {
|
|
url,
|
|
method: fetchRequest.method,
|
|
};
|
|
if (Array.from(fetchRequest.headers.keys()).length > 0) {
|
|
// Not really necessary as set-cookie never appears in the REQUEST headers.
|
|
cacheContentRequest.headers = serializeHeaders(fetchRequest.headers);
|
|
}
|
|
if (clonedRequest.body) {
|
|
const bodyText = yield clonedRequest.text();
|
|
if ((_a = clonedRequest.headers
|
|
.get("Content-Type")) === null || _a === void 0 ? void 0 : _a.startsWith("application/json"))
|
|
cacheContentRequest.bodyJson = JSON.parse(bodyText);
|
|
else
|
|
cacheContentRequest.bodyText = bodyText;
|
|
}
|
|
const existingContent = yield store.fetchContent(cacheContentRequest, options);
|
|
if (existingContent) {
|
|
debug("Using cached copy of %o", url);
|
|
const bodyText = existingContent.response.bodyJson
|
|
? JSON.stringify(existingContent.response.bodyJson)
|
|
: existingContent.response.bodyText;
|
|
existingContent.response.headers["X-FMC-Cache"] = "HIT";
|
|
return new Response(bodyText, {
|
|
status: existingContent.response.status,
|
|
statusText: existingContent.response.statusText,
|
|
headers: unserializeHeaders(existingContent.response.headers),
|
|
});
|
|
}
|
|
debug("Fetching and caching %o", url);
|
|
const p = fetch(url, requestInit);
|
|
const response = yield p;
|
|
const newContent = {
|
|
request: cacheContentRequest,
|
|
response: {
|
|
ok: response.ok,
|
|
status: response.status,
|
|
statusText: response.statusText,
|
|
headers: serializeHeaders(response.headers),
|
|
},
|
|
};
|
|
const bodyText = yield response.text();
|
|
if ((_b = response.headers.get("Content-Type")) === null || _b === void 0 ? void 0 : _b.startsWith("application/json"))
|
|
newContent.response.bodyJson = JSON.parse(bodyText);
|
|
else
|
|
newContent.response.bodyText = bodyText;
|
|
yield store.storeContent(newContent, options);
|
|
const headers = new Headers(response.headers);
|
|
headers.set("X-FMC-Cache", "MISS");
|
|
return new Response(bodyText, {
|
|
status: response.status,
|
|
statusText: response.statusText,
|
|
headers,
|
|
});
|
|
});
|
|
}, {
|
|
runtime,
|
|
_store: store,
|
|
_options: [], // TODO
|
|
_once(options) {
|
|
if (!Array.isArray(this._options))
|
|
this._options = [];
|
|
this._options.push(options);
|
|
},
|
|
});
|
|
// store.setFetchCache(fetchCache);
|
|
return fetchCache;
|
|
}
|
|
|