@moostjs/event-http
Version:
@moostjs/event-http
789 lines (781 loc) • 27 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
let _wooksjs_event_core = require("@wooksjs/event-core");
let _wooksjs_event_http = require("@wooksjs/event-http");
let moost = require("moost");
let _wooksjs_http_body = require("@wooksjs/http-body");
let _prostojs_infact = require("@prostojs/infact");
let http = require("http");
let https = require("https");
//#region packages/event-http/src/auth-guard.ts
function _define_property$1(obj, key, value) {
if (key in obj) Object.defineProperty(obj, key, {
value,
enumerable: true,
configurable: true,
writable: true
});
else obj[key] = value;
return obj;
}
function _ts_decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function _ts_metadata(k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
}
function _ts_param(paramIndex, decorator) {
return function(target, key) {
decorator(target, key, paramIndex);
};
}
/** Extracts auth credentials from the current request based on transport declarations. Throws 401 if none found. */ function extractTransports(declaration) {
const ctx = (0, _wooksjs_event_core.current)();
const result = {};
let found = false;
if (declaration.bearer) {
const auth = (0, _wooksjs_event_http.useAuthorization)(ctx);
if (auth.is("bearer")) {
result.bearer = auth.credentials();
found = true;
}
}
if (declaration.basic) {
const auth = (0, _wooksjs_event_http.useAuthorization)(ctx);
if (auth.is("basic")) {
result.basic = auth.basicCredentials();
found = true;
}
}
if (declaration.cookie) {
const { getCookie } = (0, _wooksjs_event_http.useCookies)(ctx);
const val = getCookie(declaration.cookie.name);
if (val) {
result.cookie = val;
found = true;
}
}
if (declaration.apiKey) {
const { name, in: location } = declaration.apiKey;
if (location === "header") {
const headers = (0, _wooksjs_event_http.useHeaders)(ctx);
if (headers[name.toLowerCase()]) {
result.apiKey = headers[name.toLowerCase()];
found = true;
}
} else if (location === "query") {
const { params } = (0, _wooksjs_event_http.useUrlParams)(ctx);
const val = params().get(name);
if (val) {
result.apiKey = String(val);
found = true;
}
} else if (location === "cookie") {
const { getCookie } = (0, _wooksjs_event_http.useCookies)(ctx);
const val = getCookie(name);
if (val) {
result.apiKey = val;
found = true;
}
}
}
if (!found) throw new _wooksjs_event_http.HttpError(401, "No authentication credentials provided");
return result;
}
/**
* Creates a functional auth guard interceptor.
* Extracts credentials from declared transports and passes them to the handler.
* Return a value from the handler to short-circuit with that response.
*/ function defineAuthGuard(transports, handler) {
const def = (0, moost.defineBeforeInterceptor)((reply) => {
const result = handler(extractTransports(transports));
if (result !== null && result !== void 0 && typeof result.then === "function") return result.then((r) => {
if (r !== void 0) reply(r);
});
if (result !== void 0) reply(result);
}, moost.TInterceptorPriority.GUARD);
return Object.assign(def, { __authTransports: transports });
}
var AuthGuard = class {
__intercept(reply) {
const ctor = this.constructor;
const extracted = extractTransports(ctor.transports);
const result = this.handle(extracted);
if (result !== null && result !== void 0 && typeof result.then === "function") return result.then((r) => {
if (r !== void 0) reply(r);
});
if (result !== void 0) reply(result);
}
};
_define_property$1(AuthGuard, "transports", void 0);
_define_property$1(AuthGuard, "priority", moost.TInterceptorPriority.GUARD);
_ts_decorate([
(0, moost.Before)(),
_ts_param(0, (0, moost.Overtake)()),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [typeof TOvertakeFn === "undefined" ? Object : TOvertakeFn]),
_ts_metadata("design:returntype", void 0)
], AuthGuard.prototype, "__intercept", null);
AuthGuard = _ts_decorate([(0, moost.Interceptor)(moost.TInterceptorPriority.GUARD)], AuthGuard);
/**
* Registers an auth guard as an interceptor and stores its transport
* declarations in metadata for swagger auto-discovery.
*
* Accepts either a functional guard from `defineAuthGuard()` or a
* class-based guard extending `AuthGuard`.
*/ function Authenticate(handler) {
const mate = (0, moost.getMoostMate)();
const isClass = typeof handler === "function";
const transports = isClass ? handler.transports : handler.__authTransports;
const priority = isClass ? handler.priority : handler.priority || moost.TInterceptorPriority.GUARD;
const name = isClass ? handler.name : "AuthGuard";
return mate.apply(mate.decorate("interceptors", {
handler,
priority,
name
}, true), mate.decorate("authTransports", transports, true));
}
//#endregion
//#region packages/event-http/src/decorators/http-method.decorator.ts
/** Base decorator for registering an HTTP route handler with an explicit method. */ function HttpMethod(method, path) {
return (0, moost.getMoostMate)().decorate("handlers", {
method,
path,
type: "HTTP"
}, true);
}
/** Register a catch-all route handler matching any HTTP method. */ const All = (path) => HttpMethod("*", path);
/** Register a GET route handler. */ const Get = (path) => HttpMethod("GET", path);
/** Register a POST route handler. */ const Post = (path) => HttpMethod("POST", path);
/** Register a PUT route handler. */ const Put = (path) => HttpMethod("PUT", path);
/** Register a DELETE route handler. */ const Delete = (path) => HttpMethod("DELETE", path);
/** Register a PATCH route handler. */ const Patch = (path) => HttpMethod("PATCH", path);
/**
* Register an UPGRADE route handler for WebSocket upgrade requests.
*
* Use together with `WooksWs` (injected via DI) to complete the handshake:
* ```ts
* @Upgrade('/ws')
* handleUpgrade(ws: WooksWs) {
* return ws.upgrade()
* }
* ```
*/ const Upgrade = (path) => HttpMethod("UPGRADE", path);
//#endregion
//#region packages/event-http/src/decorators/resolve.decorator.ts
function createRef(getter, setter) {
return new Proxy({}, {
get: (_target, prop) => prop === "value" ? getter() : void 0,
set: (_target, prop, v) => {
if (prop === "value") setter(v);
return true;
}
});
}
/**
* Ref to the Response Status
* @decorator
* @paramType TStatusRef
*/ const StatusRef = () => (0, moost.Resolve)((metas, level) => {
const response = (0, _wooksjs_event_http.useResponse)();
if (level === "PARAM") return createRef(() => response.status, (v) => {
response.status = v;
});
if (level === "PROP" && metas.instance && metas.key) {
const initialValue = metas.instance[metas.key];
Object.defineProperty(metas.instance, metas.key, {
get: () => response.status,
set: (v) => {
response.status = v;
},
configurable: true
});
return typeof initialValue === "number" ? initialValue : 200;
}
}, "statusCode");
/**
* Ref to the Response Header
* @decorator
* @param name - header name
* @paramType THeaderRef
*/ const HeaderRef = (name) => (0, moost.Resolve)((metas, level) => {
const response = (0, _wooksjs_event_http.useResponse)();
if (level === "PARAM") return createRef(() => response.getHeader(name), (v) => response.setHeader(name, v));
if (level === "PROP" && metas.instance && metas.key) {
const initialValue = metas.instance[metas.key];
Object.defineProperty(metas.instance, metas.key, {
get: () => response.getHeader(name),
set: (v) => response.setHeader(name, v),
configurable: true
});
return typeof initialValue === "string" ? initialValue : "";
}
}, name);
/**
* Ref to the Response Cookie
* @decorator
* @param name - cookie name
* @paramType TCookieRef
*/ const CookieRef = (name) => (0, moost.Resolve)((metas, level) => {
const response = (0, _wooksjs_event_http.useResponse)();
if (level === "PARAM") return createRef(() => response.getCookie(name)?.value, (v) => response.setCookie(name, v ?? ""));
if (level === "PROP" && metas.instance && metas.key) {
const initialValue = metas.instance[metas.key];
Object.defineProperty(metas.instance, metas.key, {
get: () => response.getCookie(name)?.value,
set: (v) => response.setCookie(name, v ?? ""),
configurable: true
});
return typeof initialValue === "string" ? initialValue : "";
}
}, name);
/**
* Ref to the Response Cookie Attributes
* @decorator
* @param name - cookie name
* @paramType TCookieAttributes
*/ const CookieAttrsRef = (name) => (0, moost.Resolve)((metas, level) => {
const response = (0, _wooksjs_event_http.useResponse)();
const getAttrs = () => response.getCookie(name)?.attrs ?? {};
const setAttrs = (v) => {
const existing = response.getCookie(name);
response.setCookie(name, existing?.value ?? "", v);
};
if (level === "PARAM") return createRef(getAttrs, setAttrs);
if (level === "PROP" && metas.instance && metas.key) {
const initialValue = metas.instance[metas.key];
Object.defineProperty(metas.instance, metas.key, {
get: getAttrs,
set: setAttrs,
configurable: true
});
return typeof initialValue === "object" ? initialValue : {};
}
}, name);
/**
* Parse Authorisation Header
* @decorator
* @param name - define what to take from the Auth header
* @paramType string
*/ function Authorization(name) {
return (0, moost.Resolve)(() => {
const auth = (0, _wooksjs_event_http.useAuthorization)();
switch (name) {
case "username": return auth.is("basic") ? auth.basicCredentials()?.username : void 0;
case "password": return auth.is("basic") ? auth.basicCredentials()?.password : void 0;
case "bearer": return auth.is("bearer") ? auth.authorization : void 0;
case "raw": return auth.credentials();
case "type": return auth.type();
default: return;
}
}, "authorization");
}
/**
* Get Request Header Value
* @decorator
* @param name - header name
* @paramType string
*/ function Header(name) {
return (0, moost.Resolve)(() => {
return (0, _wooksjs_event_http.useHeaders)()[name];
}, `header: ${name}`);
}
/**
* Get Request Cookie Value
* @decorator
* @param name - cookie name
* @paramType string
*/ function Cookie(name) {
return (0, moost.Resolve)(() => (0, _wooksjs_event_http.useCookies)().getCookie(name), `cookie: ${name}`);
}
/**
* Get Query Item value or the whole parsed Query as an object
* @decorator
* @param name - query item name (optional)
* @paramType string | object
*/ function Query(name) {
const isItem = !!name;
const _name = isItem ? name : "Query";
return (0, moost.getMoostMate)().apply((0, moost.getMoostMate)().decorate("paramSource", isItem ? "QUERY_ITEM" : "QUERY"), (0, moost.getMoostMate)().decorate("paramName", _name), (0, moost.Resolve)(() => {
const { toJson, params } = (0, _wooksjs_event_http.useUrlParams)();
if (isItem) {
const value = params().get(name);
return value === null ? void 0 : value;
}
const json = toJson();
return Object.keys(json).length > 0 ? json : void 0;
}, _name));
}
/**
* Get Requested URL
* @decorator
* @paramType string
*/ function Url() {
return (0, moost.Resolve)(() => (0, _wooksjs_event_http.useRequest)().url || "", "url");
}
/**
* Get Requested HTTP Method
* @decorator
* @paramType string
*/ function Method() {
return (0, moost.Resolve)(() => (0, _wooksjs_event_http.useRequest)().method, "http_method");
}
/**
* Get Raw Request Instance
* @decorator
* @paramType IncomingMessage
*/ function Req() {
return (0, moost.Resolve)(() => (0, _wooksjs_event_http.useRequest)().raw, "request");
}
/**
* Get Raw Response Instance
* @decorator
* @param opts (optional) { passthrough: boolean }
* @paramType ServerResponse
*/ function Res(opts) {
return (0, moost.Resolve)(() => (0, _wooksjs_event_http.useResponse)().getRawRes(opts?.passthrough), "response");
}
/**
* Get Request Unique Identificator (UUID)
* @decorator
* @paramType string
*/ function ReqId() {
return (0, moost.Resolve)(() => (0, _wooksjs_event_http.useRequest)().reqId(), "reqId");
}
/**
* Get Request IP Address
* @decorator
* @paramType string
*/ function Ip(opts) {
return (0, moost.Resolve)(() => (0, _wooksjs_event_http.useRequest)().getIp(opts), "ip");
}
/**
* Get Request IP Address list
* @decorator
* @paramType string[]
*/ function IpList() {
return (0, moost.Resolve)(() => (0, _wooksjs_event_http.useRequest)().getIpList(), "ipList");
}
/**
* Get Parsed Request Body
* @decorator
* @paramType object | string | unknown
*/ function Body() {
return (0, moost.getMoostMate)().apply((0, moost.getMoostMate)().decorate("paramSource", "BODY"), (0, moost.Resolve)(() => (0, _wooksjs_http_body.useBody)().parseBody(), "body"));
}
/**
* Get Raw Request Body Buffer
* @decorator
* @paramType Promise<Buffer>
*/ function RawBody() {
return (0, moost.Resolve)(() => (0, _wooksjs_http_body.useBody)().rawBody(), "body");
}
//#endregion
//#region packages/event-http/src/decorators/set.decorator.ts
const setHeaderInterceptor = (name, value, opts) => {
const cb = () => {
const response = (0, _wooksjs_event_http.useResponse)();
if ((!response.getHeader(name) || opts?.force) && (!opts?.status || opts.status === response.status)) response.setHeader(name, value);
};
const def = { priority: moost.TInterceptorPriority.AFTER_ALL };
if (opts?.when !== "error") def.after = cb;
if (opts?.when === "always" || opts?.when === "error") def.error = cb;
return def;
};
/**
* Set Header for Request Handler
*
* ```ts
* import { Get, SetHeader } from '@moostjs/event-http';
* import { Controller } from 'moost';
*
* @Controller()
* export class ExampleController {
* @Get('test')
* // setting header for request handler
* @SetHeader('x-server', 'my-server')
* testHandler() {
* return '...'
* }
* }
* ```
*
* ```ts
* import { Get, SetHeader } from '@moostjs/event-http';
* import { Controller } from 'moost';
*
* @Controller()
* export class ExampleController {
* @Get('test')
* // setting header only if status = 400
* @SetHeader('content-type', 'text/plain', { status: 400 })
* testHandler() {
* return '...'
* }
* }
* ```
*
* @param name name of header
* @param value value for header
* @param options options { status?: number, force?: boolean }
*/ function SetHeader(...args) {
return (0, moost.Intercept)(setHeaderInterceptor(...args));
}
const setCookieInterceptor = (name, value, attrs) => ({
after() {
const response = (0, _wooksjs_event_http.useResponse)();
if (!response.getCookie(name)) response.setCookie(name, value, attrs);
},
priority: moost.TInterceptorPriority.AFTER_ALL
});
/**
* Set Cookie for Request Handler
* ```ts
* import { Get, SetCookie } from '@moostjs/event-http';
* import { Controller } from 'moost';
*
* @Controller()
* export class ExampleController {
* @Get('test')
* // setting 'my-cookie' = 'value' with maxAge of 10 minutes
* @SetCookie('my-cookie', 'value', { maxAge: '10m' })
* testHandler() {
* return '...'
* }
* }
* ```
*
* @param name name of cookie
* @param value value for cookie
* @param attrs cookie attributes
*/ function SetCookie(...args) {
return (0, moost.Intercept)(setCookieInterceptor(...args));
}
const setStatusInterceptor = (code, opts) => ({
after() {
const response = (0, _wooksjs_event_http.useResponse)();
if (!response.status || opts?.force) response.status = code;
},
priority: moost.TInterceptorPriority.AFTER_ALL
});
/**
* Set Response Status for Request Handler
*
* ```ts
* import { Get, SetStatus } from '@moostjs/event-http';
* import { Controller } from 'moost';
*
* @Controller()
* export class ExampleController {
* @Get('test')
* @SetStatus(201)
* testHandler() {
* return '...'
* }
* }
* ```
* @param code number
* @param opts optional { force?: boolean }
*/ function SetStatus(...args) {
return (0, moost.Intercept)(setStatusInterceptor(...args));
}
//#endregion
//#region packages/event-http/src/decorators/limits.decorator.ts
/**
* Creates an interceptor that sets the maximum allowed inflated body size in bytes.
*
* @param n - Maximum body size in bytes after decompression.
* @returns Interceptor def to enforce the limit.
*/ const globalBodySizeLimit = (n) => (0, moost.defineBeforeInterceptor)(() => {
(0, _wooksjs_event_http.useRequest)().setMaxInflated(n);
}, moost.TInterceptorPriority.BEFORE_ALL);
/**
* Creates an interceptor that sets the maximum allowed compressed body size in bytes.
*
* @param n - Maximum body size in bytes before decompression.
* @returns Interceptor def to enforce the limit.
*/ const globalCompressedBodySizeLimit = (n) => (0, moost.defineBeforeInterceptor)(() => {
(0, _wooksjs_event_http.useRequest)().setMaxCompressed(n);
}, moost.TInterceptorPriority.BEFORE_ALL);
/**
* Creates an interceptor that sets the timeout for reading the request body.
*
* @param n - Timeout in milliseconds.
* @returns Interceptor def to enforce the timeout.
*/ const globalBodyReadTimeoutMs = (n) => (0, moost.defineBeforeInterceptor)(() => {
(0, _wooksjs_event_http.useRequest)().setReadTimeoutMs(n);
}, moost.TInterceptorPriority.BEFORE_ALL);
/**
* Decorator to limit the maximum inflated body size for the request. Default: 10 MB
*
* @param n - Maximum body size in bytes after decompression.
*/ const BodySizeLimit = (n) => (0, moost.Intercept)(globalBodySizeLimit(n));
/**
* Decorator to limit the maximum compressed body size for the request. Default: 1 MB
*
* @param n - Maximum body size in bytes before decompression.
*/ const CompressedBodySizeLimit = (n) => (0, moost.Intercept)(globalCompressedBodySizeLimit(n));
/**
* Decorator to set a timeout (in milliseconds) for reading the request body. Default: 10 s
*
* @param n - Timeout duration in milliseconds.
*/ const BodyReadTimeoutMs = (n) => (0, moost.Intercept)(globalBodyReadTimeoutMs(n));
//#endregion
//#region packages/event-http/src/event-http.ts
function _define_property(obj, key, value) {
if (key in obj) Object.defineProperty(obj, key, {
value,
enumerable: true,
configurable: true,
writable: true
});
else obj[key] = value;
return obj;
}
const LOGGER_TITLE = "moost-http";
/**
* ## Moost HTTP Adapter
*
* Moost Adapter for HTTP events
*
* ```ts
* │ // HTTP server example
* │ import { MoostHttp, Get } from '@moostjs/event-http'
* │ import { Moost, Param } from 'moost'
* │
* │ class MyServer extends Moost {
* │ @Get('test/:name')
* │ test(@Param('name') name: string) {
* │ return { message: `Hello ${name}!` }
* │ }
* │ }
* │
* │ const app = new MyServer()
* │ const http = new MoostHttp()
* │ app.adapter(http).listen(3000, () => {
* │ app.getLogger('MyApp').log('Up on port 3000')
* │ })
* │ app.init()
* ```
*/ var MoostHttp = class {
getHttpApp() {
return this.httpApp;
}
getServerCb(onNoMatch) {
return this.httpApp.getServerCb(onNoMatch);
}
/**
* Programmatic route invocation using the Web Standard fetch API.
* Goes through the full Moost pipeline: DI scoping, interceptors,
* argument resolution, pipes, validation, and handler execution.
*
* When called from within an existing HTTP context (e.g. during SSR),
* identity headers (authorization, cookie) are automatically forwarded.
*/ fetch(request) {
return this.httpApp.fetch(request);
}
/**
* Convenience wrapper for programmatic route invocation.
* Accepts a URL string (relative paths auto-prefixed with `http://localhost`),
* URL object, or Request, plus optional `RequestInit`.
*
* Returns `null` when no route matches the request.
*/ request(input, init) {
return this.httpApp.request(input, init);
}
/**
* Runs `fn` inside an HTTP event context seeded from a real `(req, res)` pair,
* without route dispatch. Nested `fetch()`/`request()` calls made during `fn`
* see this context as their caller, so `forwardHeaders` and parent `Set-Cookie`
* propagation apply. Never writes to `res` — apply buffered response state
* (e.g. `response.getSetCookieStrings()`) yourself.
*/ withHttpContext(req, res, fn) {
return this.httpApp.withHttpContext(req, res, fn);
}
listen(port, hostname, backlog, listeningListener) {
return this.httpApp.listen(port, hostname, backlog, listeningListener);
}
async onNotFound() {
return (0, moost.defineMoostEventHandler)({
loggerTitle: LOGGER_TITLE,
getIterceptorHandler: () => this.moost?.getGlobalInterceptorHandler(),
getControllerInstance: () => this.moost,
callControllerMethod: () => new _wooksjs_event_http.HttpError(404, "Resource Not Found"),
targetPath: "",
handlerType: "__SYSTEM__"
})();
}
onInit(moost$1) {
this.moost = moost$1;
}
getProvideRegistry() {
return (0, _prostojs_infact.createProvideRegistry)([_wooksjs_event_http.WooksHttp, () => this.getHttpApp()], ["WooksHttp", () => this.getHttpApp()], [http.Server, () => this.getHttpApp().getServer()], [https.Server, () => this.getHttpApp().getServer()]);
}
getLogger() {
return this.getHttpApp().getLogger("[moost-http]");
}
bindHandler(opts) {
let fn;
for (const handler of opts.handlers) {
if (handler.type !== "HTTP") continue;
const httpPath = handler.path;
const path = typeof httpPath === "string" ? httpPath : typeof opts.method === "string" ? opts.method : "";
const targetPath = `${`${opts.prefix || ""}/${path}`.replaceAll(/\/\/+/g, "/")}${path.endsWith("//") ? "/" : ""}`;
fn = (0, moost.defineMoostEventHandler)({
loggerTitle: LOGGER_TITLE,
getIterceptorHandler: opts.getIterceptorHandler,
getControllerInstance: opts.getInstance,
controllerMethod: opts.method,
controllerName: opts.controllerName,
resolveArgs: opts.resolveArgs,
manualUnscope: true,
hooks: { init: ({ unscope }) => {
const { raw } = (0, _wooksjs_event_http.useRequest)();
raw.on("end", unscope);
} },
targetPath,
controllerPrefix: opts.prefix,
handlerType: handler.type
});
const routerBinding = handler.method === "UPGRADE" ? this.httpApp.upgrade(targetPath, fn) : this.httpApp.on(handler.method, targetPath, fn);
const { getPath: pathBuilder } = routerBinding;
const id = ((0, moost.getMoostMate)().read(opts.fakeInstance, opts.method) || {}).id || opts.method;
if (id) {
const methods = this.pathBuilders[id] = this.pathBuilders[id] || {};
if (handler.method === "*") {
methods.GET = pathBuilder;
methods.PUT = pathBuilder;
methods.PATCH = pathBuilder;
methods.POST = pathBuilder;
methods.DELETE = pathBuilder;
} else methods[handler.method] = pathBuilder;
}
opts.logHandler(`[36m(${handler.method})[32m${targetPath}`);
const args = routerBinding.getArgs();
const params = {};
args.forEach((a) => params[a] = `{${a}}`);
opts.register(handler, routerBinding.getPath(params), args);
}
}
constructor(httpApp) {
_define_property(this, "name", "http");
_define_property(this, "httpApp", void 0);
_define_property(this, "pathBuilders", {});
_define_property(this, "moost", void 0);
_wooksjs_event_http.WooksHttpResponse.registerFramework({
image: "https://moost.org/moost-full-logo.svg",
link: "https://moost.org/",
poweredBy: "moostjs",
version: "0.6.34"
});
if (httpApp && httpApp instanceof _wooksjs_event_http.WooksHttp) this.httpApp = httpApp;
else if (httpApp) this.httpApp = (0, _wooksjs_event_http.createHttpApp)({
...httpApp,
onNotFound: this.onNotFound.bind(this)
});
else this.httpApp = (0, _wooksjs_event_http.createHttpApp)({ onNotFound: this.onNotFound.bind(this) });
}
};
//#endregion
//#region packages/event-http/src/local-fetch.ts
/**
* Patches `globalThis.fetch` so that requests to local paths (starting with `/`)
* are routed through `MoostHttp` in-process instead of making a network request.
* Falls back to the original `fetch` when no Moost route matches.
*
* Useful for SSR scenarios where server-side code needs to call its own API endpoints
* without the overhead of a TCP round-trip.
*
* @returns A teardown function that restores the original `globalThis.fetch`.
*/ function enableLocalFetch(http) {
const originalFetch = globalThis.fetch;
globalThis.fetch = async (input, init) => {
if (typeof input === "string") {
if (input.startsWith("/")) {
const response = await http.request(input, init);
if (response) return response;
}
} else if (input instanceof URL) {
if (isLocalOrigin(input)) {
const response = await http.request(input, init);
if (response) return response;
}
} else if (isLocalOrigin(new URL(input.url))) {
const response = await http.fetch(input);
if (response) return response;
}
return originalFetch(input, init);
};
return () => {
globalThis.fetch = originalFetch;
};
}
function isLocalOrigin(url) {
return url.hostname === "localhost" || url.hostname === "127.0.0.1";
}
//#endregion
exports.All = All;
Object.defineProperty(exports, 'AuthGuard', {
enumerable: true,
get: function () {
return AuthGuard;
}
});
exports.Authenticate = Authenticate;
exports.Authorization = Authorization;
exports.Body = Body;
exports.BodyReadTimeoutMs = BodyReadTimeoutMs;
exports.BodySizeLimit = BodySizeLimit;
exports.CompressedBodySizeLimit = CompressedBodySizeLimit;
exports.Cookie = Cookie;
exports.CookieAttrsRef = CookieAttrsRef;
exports.CookieRef = CookieRef;
exports.Delete = Delete;
exports.Get = Get;
exports.Header = Header;
exports.HeaderRef = HeaderRef;
Object.defineProperty(exports, 'HttpError', {
enumerable: true,
get: function () {
return _wooksjs_event_http.HttpError;
}
});
exports.HttpMethod = HttpMethod;
exports.Ip = Ip;
exports.IpList = IpList;
exports.Method = Method;
exports.MoostHttp = MoostHttp;
exports.Patch = Patch;
exports.Post = Post;
exports.Put = Put;
exports.Query = Query;
exports.RawBody = RawBody;
exports.Req = Req;
exports.ReqId = ReqId;
exports.Res = Res;
exports.SetCookie = SetCookie;
exports.SetHeader = SetHeader;
exports.SetStatus = SetStatus;
exports.StatusRef = StatusRef;
exports.Upgrade = Upgrade;
exports.Url = Url;
exports.defineAuthGuard = defineAuthGuard;
exports.enableLocalFetch = enableLocalFetch;
exports.extractTransports = extractTransports;
exports.globalBodyReadTimeoutMs = globalBodyReadTimeoutMs;
exports.globalBodySizeLimit = globalBodySizeLimit;
exports.globalCompressedBodySizeLimit = globalCompressedBodySizeLimit;
Object.defineProperty(exports, 'httpKind', {
enumerable: true,
get: function () {
return _wooksjs_event_http.httpKind;
}
});
Object.defineProperty(exports, 'useHttpContext', {
enumerable: true,
get: function () {
return _wooksjs_event_http.useHttpContext;
}
});