change architecture

This commit is contained in:
2026-01-12 02:08:47 +07:00
parent f80ea881c6
commit 27bcb8bbef
76 changed files with 997 additions and 621 deletions

View File

@@ -0,0 +1,154 @@
import type { NestHttpServerRequired, NestReqRequired } from "./_nest.ts";
import type { Context } from "hono";
export function createHonoReq(
ctx: Context,
info: {
body: Record<string, any>;
params: Record<string, string>;
rawBody: any;
},
): InternalHonoReq {
const { params, rawBody } = info;
let body = info.body ?? {};
const honoReq = ctx as InternalHonoReq;
if (Object.hasOwn(honoReq, IS_HONO_REQUEST)) return honoReq;
const nestReq: Omit<NestReqRequired, "headers" | "query" | "body" | "ip"> = {
rawBody,
session: ctx.get("session") ?? {},
//hosts: {}, //nest sets up hosts automatically
files: {}, //TODO files
params: params,
};
Object.assign(honoReq, nestReq);
let ip: string | undefined;
let headers: Record<string, any> | undefined;
let query: Record<string, any> | undefined;
Object.defineProperties(honoReq, {
headers: {
get(this: Context) {
return headers ?? (headers = Object.fromEntries(this.req.raw.headers as any));
},
enumerable: true,
},
query: {
get(this: Context) {
return query ?? (query = this.req.query());
},
enumerable: true,
},
// Hono Context already has a body attribute, so we need to use a Proxy to override it
body: {
value: new Proxy(ctx.body, {
get(rawBody, key: string) {
return body[key];
},
ownKeys(rawBody) {
return Object.keys(body);
},
apply(rawBody, thisArg, args) {
return rawBody.apply(ctx, args as any);
},
}),
enumerable: true,
writable: false,
},
ip: {
get() {
return "";
},
enumerable: true,
},
[IS_HONO_REQUEST]: {
value: true,
},
});
return honoReq;
}
const IS_HONO_REQUEST = Symbol("Is Hono Request");
function mountResponse(ctx: Context, data: any) {
Reflect.set(ctx, NEST_BODY, data);
}
export function createHonoRes(context: Context): InternalHonoRes {
Reflect.set(context, "send", function (this: Context, response: any = this.newResponse(null)) {
mountResponse(this, response);
});
return context as any as InternalHonoRes;
}
export function sendResult(ctx: Context, headers: Record<string, string>) {
const body = Reflect.get(ctx, NEST_BODY);
let response: Response;
switch (typeof body) {
case "string": {
response = ctx.text(body);
break;
}
case "object": {
if (body === null) response = ctx.body(null);
else if (body instanceof Response) response = body;
else if (body instanceof ReadableStream) response = ctx.body(body);
else if (body instanceof Uint8Array) response = ctx.body(body as any);
else if (body instanceof Blob) response = ctx.body(body.stream());
else response = ctx.json(body);
break;
}
case "undefined": {
response = ctx.body(null);
break;
}
default:
return ctx.text("HonoAdapter cannot convert unknown types", 500);
}
Object.entries(headers).forEach(([key, value]) => response.headers.set(key, value));
return response;
}
export type InternalHonoReq = NestReqRequired & Context;
export type InternalHonoRes = Context & {
send(data?: any): void;
};
const NEST_BODY = Symbol("nest_body");
const FakeHttpServer = Symbol("Fake HTTP Server");
export function isFakeHttpServer(server: any) {
return Reflect.get(server, FakeHttpServer);
}
export function createNestRequiredHttpServer(): NestHttpServerRequired {
return new Proxy(
{
once() {
return this;
},
removeListener() {
return this;
},
address() {
return null;
},
then: undefined,
[FakeHttpServer]: true,
},
{
get(target, key) {
if (typeof key === "symbol" || Object.hasOwn(target, key)) {
//@ts-ignore
return target[key];
}
console.trace("Nest Adapter: Nest uses undefined httpServer property", key);
const value = function () {
throw new Error(`Nest call undefined httpServer property '${String(key)}'`);
};
//@ts-ignore
target[key] = value;
return value;
},
},
);
}