Spaces:
Paused
Paused
// src/Interceptor.ts | |
import { Logger } from "@open-draft/logger"; | |
import { Emitter } from "strict-event-emitter"; | |
var INTERNAL_REQUEST_ID_HEADER_NAME = "x-interceptors-internal-request-id"; | |
function getGlobalSymbol(symbol) { | |
return ( | |
// @ts-ignore https://github.com/Microsoft/TypeScript/issues/24587 | |
globalThis[symbol] || void 0 | |
); | |
} | |
function setGlobalSymbol(symbol, value) { | |
globalThis[symbol] = value; | |
} | |
function deleteGlobalSymbol(symbol) { | |
delete globalThis[symbol]; | |
} | |
var InterceptorReadyState = /* @__PURE__ */ ((InterceptorReadyState2) => { | |
InterceptorReadyState2["INACTIVE"] = "INACTIVE"; | |
InterceptorReadyState2["APPLYING"] = "APPLYING"; | |
InterceptorReadyState2["APPLIED"] = "APPLIED"; | |
InterceptorReadyState2["DISPOSING"] = "DISPOSING"; | |
InterceptorReadyState2["DISPOSED"] = "DISPOSED"; | |
return InterceptorReadyState2; | |
})(InterceptorReadyState || {}); | |
var Interceptor = class { | |
constructor(symbol) { | |
this.symbol = symbol; | |
this.readyState = "INACTIVE" /* INACTIVE */; | |
this.emitter = new Emitter(); | |
this.subscriptions = []; | |
this.logger = new Logger(symbol.description); | |
this.emitter.setMaxListeners(0); | |
this.logger.info("constructing the interceptor..."); | |
} | |
/** | |
* Determine if this interceptor can be applied | |
* in the current environment. | |
*/ | |
checkEnvironment() { | |
return true; | |
} | |
/** | |
* Apply this interceptor to the current process. | |
* Returns an already running interceptor instance if it's present. | |
*/ | |
apply() { | |
const logger = this.logger.extend("apply"); | |
logger.info("applying the interceptor..."); | |
if (this.readyState === "APPLIED" /* APPLIED */) { | |
logger.info("intercepted already applied!"); | |
return; | |
} | |
const shouldApply = this.checkEnvironment(); | |
if (!shouldApply) { | |
logger.info("the interceptor cannot be applied in this environment!"); | |
return; | |
} | |
this.readyState = "APPLYING" /* APPLYING */; | |
const runningInstance = this.getInstance(); | |
if (runningInstance) { | |
logger.info("found a running instance, reusing..."); | |
this.on = (event, listener) => { | |
logger.info('proxying the "%s" listener', event); | |
runningInstance.emitter.addListener(event, listener); | |
this.subscriptions.push(() => { | |
runningInstance.emitter.removeListener(event, listener); | |
logger.info('removed proxied "%s" listener!', event); | |
}); | |
return this; | |
}; | |
this.readyState = "APPLIED" /* APPLIED */; | |
return; | |
} | |
logger.info("no running instance found, setting up a new instance..."); | |
this.setup(); | |
this.setInstance(); | |
this.readyState = "APPLIED" /* APPLIED */; | |
} | |
/** | |
* Setup the module augments and stubs necessary for this interceptor. | |
* This method is not run if there's a running interceptor instance | |
* to prevent instantiating an interceptor multiple times. | |
*/ | |
setup() { | |
} | |
/** | |
* Listen to the interceptor's public events. | |
*/ | |
on(event, listener) { | |
const logger = this.logger.extend("on"); | |
if (this.readyState === "DISPOSING" /* DISPOSING */ || this.readyState === "DISPOSED" /* DISPOSED */) { | |
logger.info("cannot listen to events, already disposed!"); | |
return this; | |
} | |
logger.info('adding "%s" event listener:', event, listener); | |
this.emitter.on(event, listener); | |
return this; | |
} | |
once(event, listener) { | |
this.emitter.once(event, listener); | |
return this; | |
} | |
off(event, listener) { | |
this.emitter.off(event, listener); | |
return this; | |
} | |
removeAllListeners(event) { | |
this.emitter.removeAllListeners(event); | |
return this; | |
} | |
/** | |
* Disposes of any side-effects this interceptor has introduced. | |
*/ | |
dispose() { | |
const logger = this.logger.extend("dispose"); | |
if (this.readyState === "DISPOSED" /* DISPOSED */) { | |
logger.info("cannot dispose, already disposed!"); | |
return; | |
} | |
logger.info("disposing the interceptor..."); | |
this.readyState = "DISPOSING" /* DISPOSING */; | |
if (!this.getInstance()) { | |
logger.info("no interceptors running, skipping dispose..."); | |
return; | |
} | |
this.clearInstance(); | |
logger.info("global symbol deleted:", getGlobalSymbol(this.symbol)); | |
if (this.subscriptions.length > 0) { | |
logger.info("disposing of %d subscriptions...", this.subscriptions.length); | |
for (const dispose of this.subscriptions) { | |
dispose(); | |
} | |
this.subscriptions = []; | |
logger.info("disposed of all subscriptions!", this.subscriptions.length); | |
} | |
this.emitter.removeAllListeners(); | |
logger.info("destroyed the listener!"); | |
this.readyState = "DISPOSED" /* DISPOSED */; | |
} | |
getInstance() { | |
var _a; | |
const instance = getGlobalSymbol(this.symbol); | |
this.logger.info("retrieved global instance:", (_a = instance == null ? void 0 : instance.constructor) == null ? void 0 : _a.name); | |
return instance; | |
} | |
setInstance() { | |
setGlobalSymbol(this.symbol, this); | |
this.logger.info("set global instance!", this.symbol.description); | |
} | |
clearInstance() { | |
deleteGlobalSymbol(this.symbol); | |
this.logger.info("cleared global instance!", this.symbol.description); | |
} | |
}; | |
// src/createRequestId.ts | |
function createRequestId() { | |
return Math.random().toString(16).slice(2); | |
} | |
// src/utils/isPropertyAccessible.ts | |
function isPropertyAccessible(obj, key) { | |
try { | |
obj[key]; | |
return true; | |
} catch (e) { | |
return false; | |
} | |
} | |
// src/utils/responseUtils.ts | |
var RESPONSE_STATUS_CODES_WITHOUT_BODY = /* @__PURE__ */ new Set([ | |
101, | |
103, | |
204, | |
205, | |
304 | |
]); | |
function isResponseWithoutBody(status) { | |
return RESPONSE_STATUS_CODES_WITHOUT_BODY.has(status); | |
} | |
function createServerErrorResponse(body) { | |
return new Response( | |
JSON.stringify( | |
body instanceof Error ? { | |
name: body.name, | |
message: body.message, | |
stack: body.stack | |
} : body | |
), | |
{ | |
status: 500, | |
statusText: "Unhandled Exception", | |
headers: { | |
"Content-Type": "application/json" | |
} | |
} | |
); | |
} | |
function isResponseError(response) { | |
return isPropertyAccessible(response, "type") && response.type === "error"; | |
} | |
export { | |
INTERNAL_REQUEST_ID_HEADER_NAME, | |
getGlobalSymbol, | |
deleteGlobalSymbol, | |
InterceptorReadyState, | |
Interceptor, | |
createRequestId, | |
isResponseWithoutBody, | |
createServerErrorResponse, | |
isResponseError | |
}; | |
//# sourceMappingURL=chunk-Q7POAM5N.mjs.map |