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

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;
}