chore: update dependencies and refactor application structure
- Bump AWS SDK packages to version 3.966.0 - Update @hono-di packages to version 0.0.15 - Update @types/node to version 25.0.5 - Refactor main application entry point to integrate NestJS with Hono - Remove unused gRPC and user module files - Add HonoAdapter for NestJS integration - Implement basic AppController and AppService - Configure Vite server to run on port 3000
This commit is contained in:
73
src/main.ts
73
src/main.ts
@@ -4,30 +4,57 @@ import { cors } from "hono/cors";
|
||||
import isMobile from 'is-mobile';
|
||||
import { rpcServer } from './api/rpc';
|
||||
import { ssrRender } from './worker/ssrRender';
|
||||
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './server/app.module';
|
||||
import { HonoAdapter } from './server/HonoAdapter/adapter';
|
||||
import { NestHonoApplication } from './server/HonoAdapter/interfaces';
|
||||
// import { serveStatic } from "hono/bun";
|
||||
// @ts-ignore
|
||||
const app = new Hono()
|
||||
const isDev = import.meta.env.DEV;
|
||||
// const app = new Hono()
|
||||
// const isDev = import.meta.env.DEV;
|
||||
|
||||
// app.use(renderer)
|
||||
app.use('*', contextStorage());
|
||||
app.use(cors(), async (c, next) => {
|
||||
c.set("fetch", app.request.bind(app));
|
||||
const ua = c.req.header("User-Agent")
|
||||
if (!ua) {
|
||||
return c.json({ error: "User-Agent header is missing" }, 400);
|
||||
};
|
||||
c.set("isMobile", isMobile({ ua }));
|
||||
await next();
|
||||
}, rpcServer);
|
||||
if (!isDev) {
|
||||
if ((process as any).versions?.bun) {
|
||||
const { serveStatic } = await import("hono/bun");
|
||||
app.use(serveStatic({ root: "./dist/client" }))
|
||||
}
|
||||
}
|
||||
app.get("/.well-known/*", (c) => {
|
||||
return c.json({ ok: true });
|
||||
});
|
||||
app.get("*", ssrRender);
|
||||
// // app.use(renderer)
|
||||
// app.use('*', contextStorage());
|
||||
// app.use(cors(), async (c, next) => {
|
||||
// c.set("fetch", app.request.bind(app));
|
||||
// const ua = c.req.header("User-Agent")
|
||||
// if (!ua) {
|
||||
// return c.json({ error: "User-Agent header is missing" }, 400);
|
||||
// };
|
||||
// c.set("isMobile", isMobile({ ua }));
|
||||
// await next();
|
||||
// }, rpcServer);
|
||||
// if (!isDev) {
|
||||
// if ((process as any).versions?.bun) {
|
||||
// const { serveStatic } = await import("hono/bun");
|
||||
// app.use(serveStatic({ root: "./dist/client" }))
|
||||
// }
|
||||
// }
|
||||
// app.get("/.well-known/*", (c) => {
|
||||
// return c.json({ ok: true });
|
||||
// });
|
||||
const app = await NestFactory.create<NestHonoApplication>(
|
||||
AppModule,
|
||||
new HonoAdapter(),
|
||||
{
|
||||
rawBody: true,
|
||||
},
|
||||
);
|
||||
// app.get('*', (c) => {
|
||||
// console.log("Request URL:", c);
|
||||
// // return next();
|
||||
// });
|
||||
// app.use(ssrRender);
|
||||
// app.use(function (req, next) {
|
||||
// console.log("Request:", arguments[1]);
|
||||
// return (c, next) => {
|
||||
// next();
|
||||
// }
|
||||
// });
|
||||
const honoInstance = app.getHonoInstance();
|
||||
honoInstance.use(contextStorage());
|
||||
honoInstance.get("*", ssrRender);
|
||||
// app.use('*', contextStorage());
|
||||
await app.init();
|
||||
const httpAdapter = app.get(HttpAdapterHost);
|
||||
export default app
|
||||
|
||||
445
src/server/HonoAdapter/adapter.ts
Normal file
445
src/server/HonoAdapter/adapter.ts
Normal file
@@ -0,0 +1,445 @@
|
||||
// @ts-ignore
|
||||
// @ts-nocheck
|
||||
import { HttpBindings, createAdaptorServer } from '@hono/node-server';
|
||||
import {
|
||||
ServeStaticOptions,
|
||||
serveStatic,
|
||||
} from '@hono/node-server/serve-static';
|
||||
import { RESPONSE_ALREADY_SENT } from '@hono/node-server/utils/response';
|
||||
import { RequestMethod } from '@nestjs/common';
|
||||
import { HttpStatus, Logger } from '@nestjs/common';
|
||||
import {
|
||||
ErrorHandler,
|
||||
NestApplicationOptions,
|
||||
RequestHandler,
|
||||
} from '@nestjs/common/interfaces';
|
||||
import { isObject } from '@nestjs/common/utils/shared.utils';
|
||||
import { AbstractHttpAdapter } from '@nestjs/core/adapters/http-adapter';
|
||||
import { Context, Next, Hono } from 'hono';
|
||||
import { bodyLimit } from 'hono/body-limit';
|
||||
import { cors } from 'hono/cors';
|
||||
// import { Data } from 'hono/dist/types/context';
|
||||
import { RedirectStatusCode, StatusCode } from 'hono/utils/http-status';
|
||||
import * as http from 'http';
|
||||
import http2 from 'http2';
|
||||
import * as https from 'https';
|
||||
|
||||
import { HonoRequest, TypeBodyParser } from './interfaces';
|
||||
import { Data } from 'node_modules/hono/dist/types/context';
|
||||
|
||||
type HonoHandler = RequestHandler<HonoRequest, Context>;
|
||||
type ServerType = http.Server | http2.Http2Server | http2.Http2SecureServer;
|
||||
type Ctx = Context | (() => Promise<Context>);
|
||||
type Method =
|
||||
| 'all'
|
||||
| 'get'
|
||||
| 'post'
|
||||
| 'put'
|
||||
| 'delete'
|
||||
| 'use'
|
||||
| 'patch'
|
||||
| 'options';
|
||||
|
||||
/**
|
||||
* Adapter for using Hono with NestJS.
|
||||
*/
|
||||
export class HonoAdapter extends AbstractHttpAdapter<
|
||||
ServerType,
|
||||
HonoRequest,
|
||||
Context
|
||||
> {
|
||||
private _isParserRegistered: boolean;
|
||||
|
||||
protected readonly instance: Hono<{ Bindings: HttpBindings }>;
|
||||
|
||||
constructor() {
|
||||
const honoInstance = new Hono<{ Bindings: HttpBindings }>();
|
||||
super(honoInstance);
|
||||
this.instance = honoInstance;
|
||||
}
|
||||
|
||||
get isParserRegistered(): boolean {
|
||||
return !!this._isParserRegistered;
|
||||
}
|
||||
|
||||
private getRouteAndHandler(
|
||||
pathOrHandler: string | HonoHandler,
|
||||
handler?: HonoHandler,
|
||||
): [string, HonoHandler] {
|
||||
const path = typeof pathOrHandler === 'function' ? '' : pathOrHandler;
|
||||
handler = typeof pathOrHandler === 'function' ? pathOrHandler : handler;
|
||||
|
||||
return [path, handler!];
|
||||
}
|
||||
|
||||
private createRouteHandler(routeHandler: HonoHandler) {
|
||||
return async (ctx: Context, next: Next) => {
|
||||
ctx.req['params'] = ctx.req.param();
|
||||
|
||||
await routeHandler(ctx.req, ctx, next);
|
||||
|
||||
return this.getBody(ctx);
|
||||
};
|
||||
}
|
||||
|
||||
private async normalizeContext(ctx: Ctx): Promise<Context> {
|
||||
if (typeof ctx === 'function') {
|
||||
return await ctx();
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
private async getBody(ctx: Ctx, body?: Data) {
|
||||
ctx = await this.normalizeContext(ctx);
|
||||
|
||||
if (body === undefined && ctx.res && ctx.res.body !== null) {
|
||||
return ctx.res;
|
||||
}
|
||||
|
||||
let responseContentType = await this.getHeader(ctx, 'Content-Type');
|
||||
|
||||
if (!responseContentType || responseContentType.startsWith('text/plain')) {
|
||||
if (
|
||||
body instanceof Buffer ||
|
||||
body instanceof Uint8Array ||
|
||||
body instanceof ArrayBuffer ||
|
||||
body instanceof ReadableStream
|
||||
) {
|
||||
responseContentType = 'application/octet-stream';
|
||||
} else if (isObject(body)) {
|
||||
responseContentType = 'application/json';
|
||||
}
|
||||
|
||||
await this.setHeader(ctx, 'Content-Type', responseContentType);
|
||||
}
|
||||
|
||||
if (responseContentType === 'application/json' && isObject(body)) {
|
||||
return ctx.json(body);
|
||||
} else if (body === undefined) {
|
||||
return ctx.newResponse(null);
|
||||
}
|
||||
|
||||
return ctx.body(body);
|
||||
}
|
||||
|
||||
private registerRoute(
|
||||
method: Method,
|
||||
pathOrHandler: string | HonoHandler,
|
||||
handler?: HonoHandler,
|
||||
) {
|
||||
const [routePath, routeHandler] = this.getRouteAndHandler(
|
||||
pathOrHandler,
|
||||
handler,
|
||||
);
|
||||
const routeHandler2 = this.createRouteHandler(routeHandler);
|
||||
|
||||
switch (method) {
|
||||
case 'all':
|
||||
this.instance.all(routePath, routeHandler2);
|
||||
break;
|
||||
case 'get':
|
||||
this.instance.get(routePath, routeHandler2);
|
||||
break;
|
||||
case 'post':
|
||||
this.instance.post(routePath, routeHandler2);
|
||||
break;
|
||||
case 'put':
|
||||
this.instance.put(routePath, routeHandler2);
|
||||
break;
|
||||
case 'delete':
|
||||
this.instance.delete(routePath, routeHandler2);
|
||||
break;
|
||||
case 'use':
|
||||
this.instance.use(routePath, routeHandler2);
|
||||
break;
|
||||
case 'patch':
|
||||
this.instance.patch(routePath, routeHandler2);
|
||||
break;
|
||||
case 'options':
|
||||
this.instance.options(routePath, routeHandler2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public all(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
|
||||
this.registerRoute('all', pathOrHandler, handler);
|
||||
}
|
||||
|
||||
public get(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
|
||||
this.registerRoute('get', pathOrHandler, handler);
|
||||
}
|
||||
|
||||
public post(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
|
||||
this.registerRoute('post', pathOrHandler, handler);
|
||||
}
|
||||
|
||||
public put(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
|
||||
this.registerRoute('put', pathOrHandler, handler);
|
||||
}
|
||||
|
||||
public delete(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
|
||||
this.registerRoute('delete', pathOrHandler, handler);
|
||||
}
|
||||
|
||||
public use(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
|
||||
this.registerRoute('use', pathOrHandler, handler);
|
||||
}
|
||||
|
||||
public patch(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
|
||||
this.registerRoute('patch', pathOrHandler, handler);
|
||||
}
|
||||
|
||||
public options(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
|
||||
this.registerRoute('options', pathOrHandler, handler);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public async reply(ctx: Ctx, body: any, statusCode?: StatusCode) {
|
||||
ctx = await this.normalizeContext(ctx);
|
||||
|
||||
if (statusCode) {
|
||||
ctx.status(statusCode);
|
||||
}
|
||||
|
||||
ctx.res = await this.getBody(ctx, body);
|
||||
}
|
||||
|
||||
public async status(ctx: Ctx, statusCode: StatusCode) {
|
||||
ctx = await this.normalizeContext(ctx);
|
||||
return ctx.status(statusCode);
|
||||
}
|
||||
|
||||
public async end() {
|
||||
return RESPONSE_ALREADY_SENT;
|
||||
}
|
||||
|
||||
public render() {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public async redirect(ctx: Ctx, statusCode: RedirectStatusCode, url: string) {
|
||||
ctx = await this.normalizeContext(ctx);
|
||||
ctx.res = ctx.redirect(url, statusCode);
|
||||
}
|
||||
|
||||
public setErrorHandler(handler: ErrorHandler) {
|
||||
this.instance.onError(async (err: Error, ctx: Context) => {
|
||||
await handler(err, ctx.req, ctx);
|
||||
|
||||
return this.getBody(ctx);
|
||||
});
|
||||
}
|
||||
|
||||
public setNotFoundHandler(handler: RequestHandler) {
|
||||
this.instance.notFound(async (ctx: Context) => {
|
||||
await handler(ctx.req, ctx);
|
||||
await this.status(ctx, HttpStatus.NOT_FOUND);
|
||||
|
||||
return this.getBody(ctx, 'Not Found');
|
||||
});
|
||||
}
|
||||
|
||||
public useStaticAssets(path: string, options: ServeStaticOptions) {
|
||||
Logger.log('Registering static assets middleware');
|
||||
this.instance.use(path, serveStatic(options));
|
||||
}
|
||||
|
||||
public setViewEngine() {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public async isHeadersSent(ctx: Ctx): Promise<boolean> {
|
||||
ctx = await this.normalizeContext(ctx);
|
||||
return ctx.finalized;
|
||||
}
|
||||
|
||||
public async getHeader(ctx: Ctx, name: string) {
|
||||
ctx = await this.normalizeContext(ctx);
|
||||
return ctx.res.headers.get(name);
|
||||
}
|
||||
|
||||
public async setHeader(ctx: Ctx, name: string, value: string) {
|
||||
ctx = await this.normalizeContext(ctx);
|
||||
ctx.res.headers.set(name, value);
|
||||
}
|
||||
|
||||
public async appendHeader(ctx: Ctx, name: string, value: string) {
|
||||
ctx = await this.normalizeContext(ctx);
|
||||
ctx.res.headers.append(name, value);
|
||||
}
|
||||
|
||||
public async getRequestHostname(ctx: Ctx): Promise<string> {
|
||||
ctx = await this.normalizeContext(ctx);
|
||||
return ctx.req.header().host;
|
||||
}
|
||||
|
||||
public getRequestMethod(request: HonoRequest): string {
|
||||
return request.method;
|
||||
}
|
||||
|
||||
public getRequestUrl(request: HonoRequest): string {
|
||||
return request.url;
|
||||
}
|
||||
|
||||
public enableCors(options: {
|
||||
origin:
|
||||
| string
|
||||
| string[]
|
||||
| ((origin: string, c: Context) => string | undefined | null);
|
||||
allowMethods?: string[];
|
||||
allowHeaders?: string[];
|
||||
maxAge?: number;
|
||||
credentials?: boolean;
|
||||
exposeHeaders?: string[];
|
||||
}) {
|
||||
this.instance.use(cors(options));
|
||||
}
|
||||
|
||||
public useBodyParser(
|
||||
type: TypeBodyParser,
|
||||
rawBody?: boolean,
|
||||
bodyLimit?: number,
|
||||
) {
|
||||
Logger.log(
|
||||
`Registering body parser middleware for type: ${type} | bodyLimit: ${bodyLimit}`,
|
||||
);
|
||||
this.instance.use(this.bodyLimit(bodyLimit));
|
||||
|
||||
// To avoid the Nest application init to override our custom
|
||||
// body parser, we mark the parsers as registered.
|
||||
this._isParserRegistered = true;
|
||||
}
|
||||
|
||||
public close(): Promise<void> {
|
||||
return new Promise((resolve) => this.httpServer.close(() => resolve()));
|
||||
}
|
||||
|
||||
private extractClientIp(ctx: Context): string {
|
||||
return (
|
||||
ctx.req.header('cf-connecting-ip') ??
|
||||
ctx.req.header('x-forwarded-for') ??
|
||||
ctx.req.header('x-real-ip') ??
|
||||
ctx.req.header('forwarded') ??
|
||||
ctx.req.header('true-client-ip') ??
|
||||
ctx.req.header('x-client-ip') ??
|
||||
ctx.req.header('x-cluster-client-ip') ??
|
||||
ctx.req.header('x-forwarded') ??
|
||||
ctx.req.header('forwarded-for') ??
|
||||
ctx.req.header('via')
|
||||
);
|
||||
}
|
||||
|
||||
private async parseRequestBody(
|
||||
ctx: Context,
|
||||
contentType: string,
|
||||
rawBody: boolean,
|
||||
): Promise<void> {
|
||||
if (
|
||||
contentType?.startsWith('multipart/form-data') ||
|
||||
contentType?.startsWith('application/x-www-form-urlencoded')
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(ctx.req as any).body = await ctx.req
|
||||
.parseBody({
|
||||
all: true,
|
||||
})
|
||||
.catch(() => {});
|
||||
} else if (
|
||||
contentType?.startsWith('application/json') ||
|
||||
contentType?.startsWith('text/plain')
|
||||
) {
|
||||
if (rawBody) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(ctx.req as any).rawBody = Buffer.from(await ctx.req.text());
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(ctx.req as any).body = await ctx.req.json().catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
public initHttpServer(options: NestApplicationOptions) {
|
||||
this.instance.use(async (ctx, next) => {
|
||||
ctx.req['ip'] = this.extractClientIp(ctx);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
ctx.req['query'] = ctx.req.query() as any;
|
||||
ctx.req['headers'] = Object.fromEntries(ctx.req.raw.headers);
|
||||
|
||||
const contentType = ctx.req.header('content-type');
|
||||
await this.parseRequestBody(ctx, contentType, options.rawBody);
|
||||
|
||||
await next();
|
||||
});
|
||||
const isHttpsEnabled = options?.httpsOptions;
|
||||
const createServer = isHttpsEnabled
|
||||
? https.createServer
|
||||
: http.createServer;
|
||||
this.httpServer = createAdaptorServer({
|
||||
fetch: this.instance.fetch,
|
||||
createServer,
|
||||
overrideGlobalObjects: false,
|
||||
});
|
||||
}
|
||||
|
||||
public getType(): string {
|
||||
return 'hono';
|
||||
}
|
||||
|
||||
public registerParserMiddleware(_prefix?: string, rawBody?: boolean) {
|
||||
if (this._isParserRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.log('Registering parser middleware');
|
||||
this.useBodyParser('application/x-www-form-urlencoded', rawBody);
|
||||
this.useBodyParser('application/json', rawBody);
|
||||
this.useBodyParser('text/plain', rawBody);
|
||||
|
||||
this._isParserRegistered = true;
|
||||
}
|
||||
|
||||
public async createMiddlewareFactory(requestMethod: RequestMethod) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||
return (path: string, callback: Function) => {
|
||||
const routeMethodsMap = {
|
||||
[RequestMethod.ALL]: this.instance.all,
|
||||
[RequestMethod.DELETE]: this.instance.delete,
|
||||
[RequestMethod.GET]: this.instance.get,
|
||||
[RequestMethod.OPTIONS]: this.instance.options,
|
||||
[RequestMethod.PATCH]: this.instance.patch,
|
||||
[RequestMethod.POST]: this.instance.post,
|
||||
[RequestMethod.PUT]: this.instance.put,
|
||||
};
|
||||
const routeMethod = (
|
||||
routeMethodsMap[requestMethod] || this.instance.get
|
||||
).bind(this.instance);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||
routeMethod(path, async (ctx: Context, next: Function) => {
|
||||
await callback(ctx.req, ctx, next);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
public applyVersionFilter(): () => () => unknown {
|
||||
throw new Error('Versioning not yet supported in Hono');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
public listen(port: string | number, ...args: any[]): ServerType {
|
||||
return this.httpServer.listen(port, ...args);
|
||||
}
|
||||
public fetch(input: RequestInfo, init?: RequestInit): Promise<Response> {
|
||||
return this.instance.fetch(input, init);
|
||||
}
|
||||
public getHonoInstance(): Hono<{ Bindings: HttpBindings }> {
|
||||
return this.instance;
|
||||
}
|
||||
public bodyLimit(maxSize: number) {
|
||||
return bodyLimit({
|
||||
maxSize,
|
||||
onError: (ctx) => {
|
||||
const errorMessage = `Body size exceeded: ${maxSize} bytes. Size: ${ctx.req.header('Content-Length')} bytes. Method: ${ctx.req.method}. Path: ${ctx.req.path}`;
|
||||
throw new Error(errorMessage);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
80
src/server/HonoAdapter/interfaces.ts
Normal file
80
src/server/HonoAdapter/interfaces.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { HonoRequest as Request } from 'hono';
|
||||
// import { ServeStaticOptions } from '@hono/node-server/serve-static';
|
||||
import { HttpServer, INestApplication } from '@nestjs/common';
|
||||
import { Context, Hono, MiddlewareHandler } from 'hono';
|
||||
import { ServeStaticOptions } from 'hono/serve-static';
|
||||
|
||||
export type TypeBodyParser =
|
||||
| 'application/json'
|
||||
| 'text/plain'
|
||||
| 'application/x-www-form-urlencoded';
|
||||
|
||||
interface HonoViewOptions {
|
||||
engine: string;
|
||||
templates: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @publicApi
|
||||
*/
|
||||
export interface NestHonoApplication<
|
||||
TServer extends Hono = Hono,
|
||||
> extends INestApplication<TServer> {
|
||||
/**
|
||||
* Returns the underlying HTTP adapter bounded to a Hono app.
|
||||
*
|
||||
* @returns {HttpServer}
|
||||
*/
|
||||
getHttpAdapter(): HttpServer<Context, MiddlewareHandler, Hono>;
|
||||
|
||||
/**
|
||||
* Register Hono body parsers on the fly.
|
||||
*
|
||||
* @example
|
||||
* // enable the json parser with a parser limit of 50mb
|
||||
* app.useBodyParser('application/json', 50 * 1024 * 1024);
|
||||
*
|
||||
* @returns {this}
|
||||
*/
|
||||
useBodyParser(type: TypeBodyParser, bodyLimit?: number): this;
|
||||
|
||||
/**
|
||||
* Sets a base directory for public assets.
|
||||
* Example `app.useStaticAssets('public', { root: '/' })`
|
||||
* @returns {this}
|
||||
*/
|
||||
useStaticAssets(path: string, options: ServeStaticOptions): this;
|
||||
|
||||
/**
|
||||
* Sets a view engine for templates (views), for example: `pug`, `handlebars`, or `ejs`.
|
||||
*
|
||||
* Don't pass in a string. The string type in the argument is for compatibility reason and will cause an exception.
|
||||
* @returns {this}
|
||||
*/
|
||||
setViewEngine(options: HonoViewOptions | string): this;
|
||||
|
||||
/**
|
||||
* Starts the application.
|
||||
* @returns A Promise that, when resolved, is a reference to the underlying HttpServer.
|
||||
*/
|
||||
listen(
|
||||
port: number | string,
|
||||
callback?: (err: Error, address: string) => void,
|
||||
): Promise<TServer>;
|
||||
listen(
|
||||
port: number | string,
|
||||
address: string,
|
||||
callback?: (err: Error, address: string) => void,
|
||||
): Promise<TServer>;
|
||||
listen(
|
||||
port: number | string,
|
||||
address: string,
|
||||
backlog: number,
|
||||
callback?: (err: Error, address: string) => void,
|
||||
): Promise<TServer>;
|
||||
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
getHonoInstance(): Hono<{ Bindings: any }>;
|
||||
}
|
||||
export type HonoRequest = Request & {
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
13
src/server/app.controller.ts
Normal file
13
src/server/app.controller.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
// import { Controller, Get } from '@hono-di/core';
|
||||
|
||||
import { Controller, Get } from "@nestjs/common";
|
||||
|
||||
@Controller('app')
|
||||
export class AppController {
|
||||
constructor() {}
|
||||
|
||||
@Get('/')
|
||||
index() {
|
||||
return 'Hello App';
|
||||
}
|
||||
}
|
||||
16
src/server/app.module.ts
Normal file
16
src/server/app.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
// hono-di:imports
|
||||
],
|
||||
controllers: [
|
||||
AppController, // hono-di:controllers
|
||||
],
|
||||
providers: [
|
||||
AppService, // hono-di:providers
|
||||
],
|
||||
})
|
||||
export class AppModule {}
|
||||
6
src/server/app.service.ts
Normal file
6
src/server/app.service.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
constructor() {}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export {}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { Controller, Get } from '@hono-di/core';
|
||||
|
||||
@Controller('user')
|
||||
export class UserController {
|
||||
constructor() {}
|
||||
|
||||
@Get('/')
|
||||
index() {
|
||||
return 'Hello User';
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Module } from '@hono-di/core';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
// hono-di:imports
|
||||
],
|
||||
controllers: [
|
||||
// hono-di:controllers
|
||||
],
|
||||
providers: [
|
||||
// hono-di:providers
|
||||
],
|
||||
})
|
||||
export class UserModule {}
|
||||
@@ -1,6 +0,0 @@
|
||||
import { Injectable } from '@hono-di/core';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor() {}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export {}
|
||||
Reference in New Issue
Block a user