@composite-fetcher/core
Version:
Fetcher core
204 lines (198 loc) • 6.75 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
BasePlugin: () => BasePlugin,
Fetcher: () => Fetcher,
PluginLifecycleHook: () => PluginLifecycleHook
});
module.exports = __toCommonJS(src_exports);
// src/interfaces/index.ts
var PluginLifecycleHook = /* @__PURE__ */ ((PluginLifecycleHook2) => {
PluginLifecycleHook2["PRE_REQUEST"] = "preRequest";
PluginLifecycleHook2["POST_REQUEST"] = "postRequest";
return PluginLifecycleHook2;
})(PluginLifecycleHook || {});
// src/lib/PluginManager.ts
var PluginManager = class {
plugins = [];
requestIdCounter = 0;
modifiedRequest;
processingContext = /* @__PURE__ */ new Map();
modifiedResponse;
processedHooks = /* @__PURE__ */ new Map();
addPlugins(plugin) {
if (Array.isArray(plugin)) {
this.plugins = this.plugins.concat(plugin);
} else {
this.plugins.push(plugin);
}
}
hasBeenProcessed(requestId, plugin, hook) {
if (!this.processedHooks.has(requestId)) {
return false;
}
const hooksForRequest = this.processedHooks.get(requestId);
return hooksForRequest && hooksForRequest[hook].has(plugin);
}
isPreRequestContext(context) {
return "request" in context && context.request instanceof Request && context.originalRequest instanceof Request;
}
isPostRequestContext(context) {
return "response" in context && context.response instanceof Response && context.originalRequest instanceof Request;
}
async processPlugins(requestId, hook, context, resolve) {
for (let index = 0; index < this.plugins.length; index++) {
const plugin = this.plugins[index];
if (this.hasBeenProcessed(requestId, plugin, hook)) {
continue;
}
this.processedHooks.get(requestId)[hook].add(plugin);
const method = this.isPreRequestContext(context) ? "onPreRequest" : "onPostRequest";
try {
const result = await plugin[method]?.(context);
if (result instanceof Response) {
resolve(result);
return;
}
if (this.isPreRequestContext(context)) {
context.request = this.processingContext.get(requestId).request;
} else if (this.isPostRequestContext(context)) {
context.response = this.processingContext.get(requestId).response;
}
} catch (error) {
console.error(`Error in plugin: ${error}`);
continue;
}
}
if (this.isPreRequestContext(context)) {
resolve(context.request);
} else if (this.isPostRequestContext(context)) {
resolve(context.response);
}
}
runPreRequestHooks(requestId, request) {
return new Promise((resolve) => {
const modifiedRequest = request.clone();
this.processingContext.set(requestId, { request: modifiedRequest });
const context = {
request: modifiedRequest,
originalRequest: request,
pluginManager: this
};
this.processPlugins(
requestId,
"preRequest" /* PRE_REQUEST */,
context,
resolve
);
});
}
runPostRequestHooks(requestId, response, originalRequest) {
return new Promise((resolve) => {
const modifiedResponse = response.clone();
if (!this.processingContext.has(requestId)) {
this.processingContext.set(requestId, {});
}
this.processingContext.get(requestId).response = modifiedResponse;
const context = {
response: modifiedResponse,
originalRequest,
pluginManager: this
};
this.processPlugins(
requestId,
"postRequest" /* POST_REQUEST */,
context,
resolve
);
});
}
getModifiedRequest(requestId) {
return this.processingContext.get(requestId)?.request;
}
getModifiedResponse(requestId) {
return this.processingContext.get(requestId)?.response;
}
getPlugins() {
return this.plugins;
}
generateNewRequestId() {
const newId = this.requestIdCounter++;
this.processedHooks.set(newId, {
preRequest: /* @__PURE__ */ new Set(),
postRequest: /* @__PURE__ */ new Set()
});
return newId;
}
clearProcessedPlugins(requestId) {
this.processedHooks.delete(requestId);
}
};
// src/Fetcher.ts
var import_isomorphic_fetch = __toESM(require("isomorphic-fetch"), 1);
var Fetcher = class {
pluginManager = new PluginManager();
use(plugin) {
this.pluginManager.addPlugins(plugin);
}
async fetch(input, init) {
const requestId = this.pluginManager.generateNewRequestId();
const originalRequest = new Request(input, init);
const modifiedRequest = await this.pluginManager.runPreRequestHooks(
requestId,
originalRequest.clone()
);
if (modifiedRequest instanceof Response) {
return modifiedRequest;
}
const response = await (0, import_isomorphic_fetch.default)(modifiedRequest);
const modifiedResponse = await this.pluginManager.runPostRequestHooks(
requestId,
response.clone(),
originalRequest.clone()
);
this.pluginManager.clearProcessedPlugins(requestId);
return modifiedResponse;
}
};
// src/lib/BasePlugin.ts
var BasePlugin = class {
async onPreRequest(context) {
}
async onPostRequest(context) {
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
BasePlugin,
Fetcher,
PluginLifecycleHook
});