@kiyasov/platform-hono 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/cjs/src/adapters/hono-adapter.d.ts +58 -0
  2. package/dist/cjs/src/adapters/hono-adapter.js +206 -0
  3. package/dist/cjs/src/adapters/hono-adapter.js.map +1 -0
  4. package/dist/cjs/src/adapters/index.d.ts +1 -0
  5. package/dist/cjs/src/adapters/index.js +18 -0
  6. package/dist/cjs/src/adapters/index.js.map +1 -0
  7. package/dist/cjs/src/interfaces/index.d.ts +1 -0
  8. package/dist/cjs/src/interfaces/index.js +18 -0
  9. package/dist/cjs/src/interfaces/index.js.map +1 -0
  10. package/dist/cjs/src/interfaces/nest-hono-application.interface.d.ts +18 -0
  11. package/dist/cjs/src/interfaces/nest-hono-application.interface.js +3 -0
  12. package/dist/cjs/src/interfaces/nest-hono-application.interface.js.map +1 -0
  13. package/dist/esm/src/adapters/hono-adapter.d.ts +58 -0
  14. package/dist/esm/src/adapters/hono-adapter.js +202 -0
  15. package/dist/esm/src/adapters/hono-adapter.js.map +1 -0
  16. package/dist/esm/src/adapters/index.d.ts +1 -0
  17. package/dist/esm/src/adapters/index.js +2 -0
  18. package/dist/esm/src/adapters/index.js.map +1 -0
  19. package/dist/esm/src/interfaces/index.d.ts +1 -0
  20. package/dist/esm/src/interfaces/index.js +2 -0
  21. package/dist/esm/src/interfaces/index.js.map +1 -0
  22. package/dist/esm/src/interfaces/nest-hono-application.interface.d.ts +18 -0
  23. package/dist/esm/src/interfaces/nest-hono-application.interface.js +2 -0
  24. package/dist/esm/src/interfaces/nest-hono-application.interface.js.map +1 -0
  25. package/package.json +9 -3
  26. package/src/adapters/hono-adapter.ts +293 -0
  27. package/src/adapters/index.ts +1 -0
  28. package/src/interfaces/index.ts +1 -0
  29. package/src/interfaces/nest-hono-application.interface.ts +72 -0
@@ -0,0 +1,58 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { Server } from "node:net";
4
+ import { HttpBindings } from "@hono/node-server";
5
+ import { RequestMethod } from "@nestjs/common";
6
+ import { ErrorHandler, NestApplicationOptions, RequestHandler } from "@nestjs/common/interfaces";
7
+ import { ServeStaticOptions } from "@hono/node-server/serve-static";
8
+ import { AbstractHttpAdapter } from "@nestjs/core/adapters/http-adapter";
9
+ import { Context, HonoRequest } from "hono";
10
+ import { Hono } from "hono";
11
+ import { RedirectStatusCode, StatusCode } from "hono/utils/http-status";
12
+ import { Http2SecureServer, Http2Server } from "http2";
13
+ import { TypeBodyParser } from "../interfaces";
14
+ type HonoHandler = RequestHandler<HonoRequest, Context>;
15
+ type ServerType = Server | Http2Server | Http2SecureServer;
16
+ export declare class HonoAdapter extends AbstractHttpAdapter<ServerType, HonoRequest, Context> {
17
+ protected readonly instance: Hono<{
18
+ Bindings: HttpBindings;
19
+ }>;
20
+ constructor();
21
+ private getRouteAndHandler;
22
+ private createRouteHandler;
23
+ private send;
24
+ get(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
25
+ post(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
26
+ put(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
27
+ delete(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
28
+ use(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
29
+ patch(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
30
+ options(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
31
+ reply(ctx: Context, body: any, statusCode?: StatusCode): Promise<void>;
32
+ status(ctx: Context, statusCode: StatusCode): void;
33
+ end(): Promise<Response>;
34
+ render(response: any, view: string, options: any): void;
35
+ redirect(ctx: Context, statusCode: RedirectStatusCode, url: string): void;
36
+ setErrorHandler(handler: ErrorHandler): void;
37
+ setNotFoundHandler(handler: RequestHandler): void;
38
+ useStaticAssets(path: string, options: ServeStaticOptions): void;
39
+ setViewEngine(options: any | string): void;
40
+ isHeadersSent(ctx: Context): boolean;
41
+ getHeader?(ctx: Context, name: string): string;
42
+ setHeader(ctx: Context, name: string, value: string): void;
43
+ appendHeader?(ctx: Context, name: string, value: string): void;
44
+ getRequestHostname(ctx: Context): string;
45
+ getRequestMethod(request: HonoRequest): string;
46
+ getRequestUrl(request: HonoRequest): string;
47
+ enableCors(options: any): void;
48
+ useBodyParser(type: TypeBodyParser, bodyLimit?: number): void;
49
+ close(): Promise<void>;
50
+ initHttpServer(options: NestApplicationOptions): void;
51
+ getType(): string;
52
+ registerParserMiddleware(prefix?: string, rawBody?: boolean): void;
53
+ createMiddlewareFactory(requestMethod: RequestMethod): Promise<(path: string, callback: Function) => void>;
54
+ applyVersionFilter(): () => () => any;
55
+ listen(port: string | number, ...args: any[]): ServerType;
56
+ bodyLimit(maxSize: number): import("hono").MiddlewareHandler;
57
+ }
58
+ export {};
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HonoAdapter = void 0;
4
+ const node_server_1 = require("@hono/node-server");
5
+ const response_1 = require("@hono/node-server/utils/response");
6
+ const common_1 = require("@nestjs/common");
7
+ const common_2 = require("@nestjs/common");
8
+ const body_limit_1 = require("hono/body-limit");
9
+ const serve_static_1 = require("@hono/node-server/serve-static");
10
+ const http_adapter_1 = require("@nestjs/core/adapters/http-adapter");
11
+ const hono_1 = require("hono");
12
+ const cors_1 = require("hono/cors");
13
+ const http = require("http");
14
+ const https = require("https");
15
+ class HonoAdapter extends http_adapter_1.AbstractHttpAdapter {
16
+ constructor() {
17
+ super(new hono_1.Hono());
18
+ }
19
+ getRouteAndHandler(pathOrHandler, handler) {
20
+ let path = typeof pathOrHandler === "function" ? "" : pathOrHandler;
21
+ handler = typeof pathOrHandler === "function" ? pathOrHandler : handler;
22
+ return [path, handler];
23
+ }
24
+ createRouteHandler(routeHandler) {
25
+ return async (ctx, next) => {
26
+ await routeHandler(ctx.req, ctx, next);
27
+ return this.send(ctx);
28
+ };
29
+ }
30
+ send(ctx) {
31
+ const body = ctx.get("body");
32
+ return typeof body === "string" ? ctx.text(body) : ctx.json(body);
33
+ }
34
+ get(pathOrHandler, handler) {
35
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
36
+ this.instance.get(routePath, this.createRouteHandler(routeHandler));
37
+ }
38
+ post(pathOrHandler, handler) {
39
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
40
+ this.instance.post(routePath, this.createRouteHandler(routeHandler));
41
+ }
42
+ put(pathOrHandler, handler) {
43
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
44
+ this.instance.put(routePath, this.createRouteHandler(routeHandler));
45
+ }
46
+ delete(pathOrHandler, handler) {
47
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
48
+ this.instance.delete(routePath, this.createRouteHandler(routeHandler));
49
+ }
50
+ use(pathOrHandler, handler) {
51
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
52
+ this.instance.use(routePath, this.createRouteHandler(routeHandler));
53
+ }
54
+ patch(pathOrHandler, handler) {
55
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
56
+ this.instance.patch(routePath, this.createRouteHandler(routeHandler));
57
+ }
58
+ options(pathOrHandler, handler) {
59
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
60
+ this.instance.options(routePath, this.createRouteHandler(routeHandler));
61
+ }
62
+ async reply(ctx, body, statusCode) {
63
+ if (statusCode)
64
+ ctx.status(statusCode);
65
+ const responseContentType = this.getHeader(ctx, "Content-Type");
66
+ if (!responseContentType?.startsWith("application/json") &&
67
+ body?.statusCode >= common_2.HttpStatus.BAD_REQUEST) {
68
+ common_2.Logger.warn("Content-Type doesn't match Reply body, you might need a custom ExceptionFilter for non-JSON responses");
69
+ this.setHeader(ctx, "Content-Type", "application/json");
70
+ }
71
+ ctx.set("body", body);
72
+ }
73
+ status(ctx, statusCode) {
74
+ ctx.status(statusCode);
75
+ }
76
+ async end() {
77
+ return response_1.RESPONSE_ALREADY_SENT;
78
+ }
79
+ render(response, view, options) {
80
+ throw new Error("Method not implemented.");
81
+ }
82
+ redirect(ctx, statusCode, url) {
83
+ ctx.redirect(url, statusCode);
84
+ }
85
+ setErrorHandler(handler) {
86
+ this.instance.onError(async (err, ctx) => {
87
+ await handler(err, ctx.req, ctx);
88
+ return this.send(ctx);
89
+ });
90
+ }
91
+ setNotFoundHandler(handler) {
92
+ this.instance.notFound(async (ctx) => {
93
+ await handler(ctx.req, ctx);
94
+ return this.send(ctx);
95
+ });
96
+ }
97
+ useStaticAssets(path, options) {
98
+ common_2.Logger.log("Registering static assets middleware");
99
+ this.instance.use(path, (0, serve_static_1.serveStatic)(options));
100
+ }
101
+ setViewEngine(options) {
102
+ throw new Error("Method not implemented.");
103
+ }
104
+ isHeadersSent(ctx) {
105
+ return true;
106
+ }
107
+ getHeader(ctx, name) {
108
+ return ctx.req.header(name);
109
+ }
110
+ setHeader(ctx, name, value) {
111
+ ctx.header(name, value);
112
+ }
113
+ appendHeader(ctx, name, value) {
114
+ ctx.res.headers.append(name, value);
115
+ }
116
+ getRequestHostname(ctx) {
117
+ return ctx.req.header().host;
118
+ }
119
+ getRequestMethod(request) {
120
+ return request.method;
121
+ }
122
+ getRequestUrl(request) {
123
+ return request.url;
124
+ }
125
+ enableCors(options) {
126
+ this.instance.use((0, cors_1.cors)(options));
127
+ }
128
+ useBodyParser(type, bodyLimit = 1e6) {
129
+ common_2.Logger.log("Registering body parser middleware");
130
+ this.instance.use(this.bodyLimit(bodyLimit), async (ctx, next) => {
131
+ const contentType = ctx.req.header("content-type");
132
+ switch (type) {
133
+ case "application/json":
134
+ if (contentType === "application/json")
135
+ ctx.req.body = await ctx.req.json();
136
+ break;
137
+ case "text/plain":
138
+ if (contentType === "text/plain") {
139
+ ctx.req.rawBody = Buffer.from(await ctx.req.text());
140
+ ctx.req.body = await ctx.req.json();
141
+ }
142
+ break;
143
+ default:
144
+ ctx.req.body = await ctx.req.parseBody({ all: true });
145
+ break;
146
+ }
147
+ await next();
148
+ });
149
+ }
150
+ close() {
151
+ return new Promise((resolve) => this.httpServer.close(() => resolve()));
152
+ }
153
+ initHttpServer(options) {
154
+ const isHttpsEnabled = options?.httpsOptions;
155
+ const createServer = isHttpsEnabled
156
+ ? https.createServer
157
+ : http.createServer;
158
+ this.httpServer = (0, node_server_1.createAdaptorServer)({
159
+ fetch: this.instance.fetch,
160
+ createServer,
161
+ overrideGlobalObjects: false,
162
+ });
163
+ }
164
+ getType() {
165
+ return "hono";
166
+ }
167
+ registerParserMiddleware(prefix, rawBody) {
168
+ common_2.Logger.log("Registering parser middleware");
169
+ this.useBodyParser("application/x-www-form-urlencoded");
170
+ this.useBodyParser("application/json");
171
+ this.useBodyParser("text/plain");
172
+ }
173
+ async createMiddlewareFactory(requestMethod) {
174
+ return (path, callback) => {
175
+ const routeMethodsMap = {
176
+ [common_1.RequestMethod.ALL]: this.instance.all,
177
+ [common_1.RequestMethod.DELETE]: this.instance.delete,
178
+ [common_1.RequestMethod.GET]: this.instance.get,
179
+ [common_1.RequestMethod.OPTIONS]: this.instance.options,
180
+ [common_1.RequestMethod.PATCH]: this.instance.patch,
181
+ [common_1.RequestMethod.POST]: this.instance.post,
182
+ [common_1.RequestMethod.PUT]: this.instance.put,
183
+ };
184
+ const routeMethod = (routeMethodsMap[requestMethod] || this.instance.get).bind(this.instance);
185
+ routeMethod(path, async (ctx, next) => {
186
+ await callback(ctx.req, ctx, next);
187
+ });
188
+ };
189
+ }
190
+ applyVersionFilter() {
191
+ throw new Error("Versioning not yet supported in Hono");
192
+ }
193
+ listen(port, ...args) {
194
+ return this.httpServer.listen(port, ...args);
195
+ }
196
+ bodyLimit(maxSize) {
197
+ return (0, body_limit_1.bodyLimit)({
198
+ maxSize,
199
+ onError: () => {
200
+ throw new Error("Body too large");
201
+ },
202
+ });
203
+ }
204
+ }
205
+ exports.HonoAdapter = HonoAdapter;
206
+ //# sourceMappingURL=hono-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hono-adapter.js","sourceRoot":"","sources":["../../../../src/adapters/hono-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from "./hono-adapter";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./hono-adapter"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapters/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B"}
@@ -0,0 +1 @@
1
+ export * from './nest-hono-application.interface';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./nest-hono-application.interface"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/interfaces/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oEAAkD"}
@@ -0,0 +1,18 @@
1
+ import { ServeStaticOptions } from "@hono/node-server/serve-static";
2
+ import { HttpServer, INestApplication } from "@nestjs/common";
3
+ import { Context, Hono, MiddlewareHandler } from "hono";
4
+ export type TypeBodyParser = "application/json" | "text/plain" | "application/x-www-form-urlencoded";
5
+ interface HonoViewOptions {
6
+ engine: string;
7
+ templates: string;
8
+ }
9
+ export interface NestHonoApplication<TServer extends Hono = Hono> extends INestApplication<TServer> {
10
+ getHttpAdapter(): HttpServer<Context, MiddlewareHandler, Hono>;
11
+ useBodyParser(type: TypeBodyParser, bodyLimit?: number): this;
12
+ useStaticAssets(path: string, options: ServeStaticOptions): this;
13
+ setViewEngine(options: HonoViewOptions | string): this;
14
+ listen(port: number | string, callback?: (err: Error, address: string) => void): Promise<TServer>;
15
+ listen(port: number | string, address: string, callback?: (err: Error, address: string) => void): Promise<TServer>;
16
+ listen(port: number | string, address: string, backlog: number, callback?: (err: Error, address: string) => void): Promise<TServer>;
17
+ }
18
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=nest-hono-application.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nest-hono-application.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/nest-hono-application.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,58 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { Server } from "node:net";
4
+ import { HttpBindings } from "@hono/node-server";
5
+ import { RequestMethod } from "@nestjs/common";
6
+ import { ErrorHandler, NestApplicationOptions, RequestHandler } from "@nestjs/common/interfaces";
7
+ import { ServeStaticOptions } from "@hono/node-server/serve-static";
8
+ import { AbstractHttpAdapter } from "@nestjs/core/adapters/http-adapter";
9
+ import { Context, HonoRequest } from "hono";
10
+ import { Hono } from "hono";
11
+ import { RedirectStatusCode, StatusCode } from "hono/utils/http-status";
12
+ import { Http2SecureServer, Http2Server } from "http2";
13
+ import { TypeBodyParser } from "../interfaces";
14
+ type HonoHandler = RequestHandler<HonoRequest, Context>;
15
+ type ServerType = Server | Http2Server | Http2SecureServer;
16
+ export declare class HonoAdapter extends AbstractHttpAdapter<ServerType, HonoRequest, Context> {
17
+ protected readonly instance: Hono<{
18
+ Bindings: HttpBindings;
19
+ }>;
20
+ constructor();
21
+ private getRouteAndHandler;
22
+ private createRouteHandler;
23
+ private send;
24
+ get(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
25
+ post(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
26
+ put(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
27
+ delete(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
28
+ use(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
29
+ patch(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
30
+ options(pathOrHandler: string | HonoHandler, handler?: HonoHandler): void;
31
+ reply(ctx: Context, body: any, statusCode?: StatusCode): Promise<void>;
32
+ status(ctx: Context, statusCode: StatusCode): void;
33
+ end(): Promise<Response>;
34
+ render(response: any, view: string, options: any): void;
35
+ redirect(ctx: Context, statusCode: RedirectStatusCode, url: string): void;
36
+ setErrorHandler(handler: ErrorHandler): void;
37
+ setNotFoundHandler(handler: RequestHandler): void;
38
+ useStaticAssets(path: string, options: ServeStaticOptions): void;
39
+ setViewEngine(options: any | string): void;
40
+ isHeadersSent(ctx: Context): boolean;
41
+ getHeader?(ctx: Context, name: string): string;
42
+ setHeader(ctx: Context, name: string, value: string): void;
43
+ appendHeader?(ctx: Context, name: string, value: string): void;
44
+ getRequestHostname(ctx: Context): string;
45
+ getRequestMethod(request: HonoRequest): string;
46
+ getRequestUrl(request: HonoRequest): string;
47
+ enableCors(options: any): void;
48
+ useBodyParser(type: TypeBodyParser, bodyLimit?: number): void;
49
+ close(): Promise<void>;
50
+ initHttpServer(options: NestApplicationOptions): void;
51
+ getType(): string;
52
+ registerParserMiddleware(prefix?: string, rawBody?: boolean): void;
53
+ createMiddlewareFactory(requestMethod: RequestMethod): Promise<(path: string, callback: Function) => void>;
54
+ applyVersionFilter(): () => () => any;
55
+ listen(port: string | number, ...args: any[]): ServerType;
56
+ bodyLimit(maxSize: number): import("hono").MiddlewareHandler;
57
+ }
58
+ export {};
@@ -0,0 +1,202 @@
1
+ import { createAdaptorServer } from "@hono/node-server";
2
+ import { RESPONSE_ALREADY_SENT } from "@hono/node-server/utils/response";
3
+ import { RequestMethod } from "@nestjs/common";
4
+ import { HttpStatus, Logger } from "@nestjs/common";
5
+ import { bodyLimit } from "hono/body-limit";
6
+ import { serveStatic, } from "@hono/node-server/serve-static";
7
+ import { AbstractHttpAdapter } from "@nestjs/core/adapters/http-adapter";
8
+ import { Hono } from "hono";
9
+ import { cors } from "hono/cors";
10
+ import * as http from "http";
11
+ import * as https from "https";
12
+ export class HonoAdapter extends AbstractHttpAdapter {
13
+ constructor() {
14
+ super(new Hono());
15
+ }
16
+ getRouteAndHandler(pathOrHandler, handler) {
17
+ let path = typeof pathOrHandler === "function" ? "" : pathOrHandler;
18
+ handler = typeof pathOrHandler === "function" ? pathOrHandler : handler;
19
+ return [path, handler];
20
+ }
21
+ createRouteHandler(routeHandler) {
22
+ return async (ctx, next) => {
23
+ await routeHandler(ctx.req, ctx, next);
24
+ return this.send(ctx);
25
+ };
26
+ }
27
+ send(ctx) {
28
+ const body = ctx.get("body");
29
+ return typeof body === "string" ? ctx.text(body) : ctx.json(body);
30
+ }
31
+ get(pathOrHandler, handler) {
32
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
33
+ this.instance.get(routePath, this.createRouteHandler(routeHandler));
34
+ }
35
+ post(pathOrHandler, handler) {
36
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
37
+ this.instance.post(routePath, this.createRouteHandler(routeHandler));
38
+ }
39
+ put(pathOrHandler, handler) {
40
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
41
+ this.instance.put(routePath, this.createRouteHandler(routeHandler));
42
+ }
43
+ delete(pathOrHandler, handler) {
44
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
45
+ this.instance.delete(routePath, this.createRouteHandler(routeHandler));
46
+ }
47
+ use(pathOrHandler, handler) {
48
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
49
+ this.instance.use(routePath, this.createRouteHandler(routeHandler));
50
+ }
51
+ patch(pathOrHandler, handler) {
52
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
53
+ this.instance.patch(routePath, this.createRouteHandler(routeHandler));
54
+ }
55
+ options(pathOrHandler, handler) {
56
+ const [routePath, routeHandler] = this.getRouteAndHandler(pathOrHandler, handler);
57
+ this.instance.options(routePath, this.createRouteHandler(routeHandler));
58
+ }
59
+ async reply(ctx, body, statusCode) {
60
+ if (statusCode)
61
+ ctx.status(statusCode);
62
+ const responseContentType = this.getHeader(ctx, "Content-Type");
63
+ if (!responseContentType?.startsWith("application/json") &&
64
+ body?.statusCode >= HttpStatus.BAD_REQUEST) {
65
+ Logger.warn("Content-Type doesn't match Reply body, you might need a custom ExceptionFilter for non-JSON responses");
66
+ this.setHeader(ctx, "Content-Type", "application/json");
67
+ }
68
+ ctx.set("body", body);
69
+ }
70
+ status(ctx, statusCode) {
71
+ ctx.status(statusCode);
72
+ }
73
+ async end() {
74
+ return RESPONSE_ALREADY_SENT;
75
+ }
76
+ render(response, view, options) {
77
+ throw new Error("Method not implemented.");
78
+ }
79
+ redirect(ctx, statusCode, url) {
80
+ ctx.redirect(url, statusCode);
81
+ }
82
+ setErrorHandler(handler) {
83
+ this.instance.onError(async (err, ctx) => {
84
+ await handler(err, ctx.req, ctx);
85
+ return this.send(ctx);
86
+ });
87
+ }
88
+ setNotFoundHandler(handler) {
89
+ this.instance.notFound(async (ctx) => {
90
+ await handler(ctx.req, ctx);
91
+ return this.send(ctx);
92
+ });
93
+ }
94
+ useStaticAssets(path, options) {
95
+ Logger.log("Registering static assets middleware");
96
+ this.instance.use(path, serveStatic(options));
97
+ }
98
+ setViewEngine(options) {
99
+ throw new Error("Method not implemented.");
100
+ }
101
+ isHeadersSent(ctx) {
102
+ return true;
103
+ }
104
+ getHeader(ctx, name) {
105
+ return ctx.req.header(name);
106
+ }
107
+ setHeader(ctx, name, value) {
108
+ ctx.header(name, value);
109
+ }
110
+ appendHeader(ctx, name, value) {
111
+ ctx.res.headers.append(name, value);
112
+ }
113
+ getRequestHostname(ctx) {
114
+ return ctx.req.header().host;
115
+ }
116
+ getRequestMethod(request) {
117
+ return request.method;
118
+ }
119
+ getRequestUrl(request) {
120
+ return request.url;
121
+ }
122
+ enableCors(options) {
123
+ this.instance.use(cors(options));
124
+ }
125
+ useBodyParser(type, bodyLimit = 1e6) {
126
+ Logger.log("Registering body parser middleware");
127
+ this.instance.use(this.bodyLimit(bodyLimit), async (ctx, next) => {
128
+ const contentType = ctx.req.header("content-type");
129
+ switch (type) {
130
+ case "application/json":
131
+ if (contentType === "application/json")
132
+ ctx.req.body = await ctx.req.json();
133
+ break;
134
+ case "text/plain":
135
+ if (contentType === "text/plain") {
136
+ ctx.req.rawBody = Buffer.from(await ctx.req.text());
137
+ ctx.req.body = await ctx.req.json();
138
+ }
139
+ break;
140
+ default:
141
+ ctx.req.body = await ctx.req.parseBody({ all: true });
142
+ break;
143
+ }
144
+ await next();
145
+ });
146
+ }
147
+ close() {
148
+ return new Promise((resolve) => this.httpServer.close(() => resolve()));
149
+ }
150
+ initHttpServer(options) {
151
+ const isHttpsEnabled = options?.httpsOptions;
152
+ const createServer = isHttpsEnabled
153
+ ? https.createServer
154
+ : http.createServer;
155
+ this.httpServer = createAdaptorServer({
156
+ fetch: this.instance.fetch,
157
+ createServer,
158
+ overrideGlobalObjects: false,
159
+ });
160
+ }
161
+ getType() {
162
+ return "hono";
163
+ }
164
+ registerParserMiddleware(prefix, rawBody) {
165
+ Logger.log("Registering parser middleware");
166
+ this.useBodyParser("application/x-www-form-urlencoded");
167
+ this.useBodyParser("application/json");
168
+ this.useBodyParser("text/plain");
169
+ }
170
+ async createMiddlewareFactory(requestMethod) {
171
+ return (path, callback) => {
172
+ const routeMethodsMap = {
173
+ [RequestMethod.ALL]: this.instance.all,
174
+ [RequestMethod.DELETE]: this.instance.delete,
175
+ [RequestMethod.GET]: this.instance.get,
176
+ [RequestMethod.OPTIONS]: this.instance.options,
177
+ [RequestMethod.PATCH]: this.instance.patch,
178
+ [RequestMethod.POST]: this.instance.post,
179
+ [RequestMethod.PUT]: this.instance.put,
180
+ };
181
+ const routeMethod = (routeMethodsMap[requestMethod] || this.instance.get).bind(this.instance);
182
+ routeMethod(path, async (ctx, next) => {
183
+ await callback(ctx.req, ctx, next);
184
+ });
185
+ };
186
+ }
187
+ applyVersionFilter() {
188
+ throw new Error("Versioning not yet supported in Hono");
189
+ }
190
+ listen(port, ...args) {
191
+ return this.httpServer.listen(port, ...args);
192
+ }
193
+ bodyLimit(maxSize) {
194
+ return bodyLimit({
195
+ maxSize,
196
+ onError: () => {
197
+ throw new Error("Body too large");
198
+ },
199
+ });
200
+ }
201
+ }
202
+ //# sourceMappingURL=hono-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hono-adapter.js","sourceRoot":"","sources":["../../../../src/adapters/hono-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAM5C,OAAO,EAEL,WAAW,GACZ,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,MAAM,OAAO,WAAY,SAAQ,mBAIhC;IAGC;QACE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACpB,CAAC;IAEO,kBAAkB,CACxB,aAAmC,EACnC,OAAqB;QAErB,IAAI,IAAI,GAAG,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QACpE,OAAO,GAAG,OAAO,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC;QACxE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzB,CAAC;IAEO,kBAAkB,CAAC,YAAyB;QAClD,OAAO,KAAK,EAAE,GAAY,EAAE,IAAU,EAAE,EAAE;YACxC,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YACvC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC,CAAC;IACJ,CAAC;IAEO,IAAI,CAAC,GAAY;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpE,CAAC;IAEM,GAAG,CAAC,aAAmC,EAAE,OAAqB;QACnE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAI,CAAC,kBAAkB,CACvD,aAAa,EACb,OAAO,CACR,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;IACtE,CAAC;IAEM,IAAI,CAAC,aAAmC,EAAE,OAAqB;QACpE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAI,CAAC,kBAAkB,CACvD,aAAa,EACb,OAAO,CACR,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;IACvE,CAAC;IAEM,GAAG,CAAC,aAAmC,EAAE,OAAqB;QACnE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAI,CAAC,kBAAkB,CACvD,aAAa,EACb,OAAO,CACR,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;IACtE,CAAC;IAEM,MAAM,CAAC,aAAmC,EAAE,OAAqB;QACtE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAI,CAAC,kBAAkB,CACvD,aAAa,EACb,OAAO,CACR,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;IACzE,CAAC;IAEM,GAAG,CAAC,aAAmC,EAAE,OAAqB;QACnE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAI,CAAC,kBAAkB,CACvD,aAAa,EACb,OAAO,CACR,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;IACtE,CAAC;IAEM,KAAK,CAAC,aAAmC,EAAE,OAAqB;QACrE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAI,CAAC,kBAAkB,CACvD,aAAa,EACb,OAAO,CACR,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;IACxE,CAAC;IAEM,OAAO,CAAC,aAAmC,EAAE,OAAqB;QACvE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAI,CAAC,kBAAkB,CACvD,aAAa,EACb,OAAO,CACR,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;IAC1E,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,GAAY,EAAE,IAAS,EAAE,UAAuB;QACjE,IAAI,UAAU;YAAE,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAChE,IACE,CAAC,mBAAmB,EAAE,UAAU,CAAC,kBAAkB,CAAC;YACpD,IAAI,EAAE,UAAU,IAAI,UAAU,CAAC,WAAW,EAC1C,CAAC;YACD,MAAM,CAAC,IAAI,CACT,uGAAuG,CACxG,CAAC;YACF,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,kBAAkB,CAAC,CAAC;QAC1D,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAEM,MAAM,CAAC,GAAY,EAAE,UAAsB;QAChD,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,GAAG;QACd,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAEM,MAAM,CAAC,QAAa,EAAE,IAAY,EAAE,OAAY;QACrD,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAEM,QAAQ,CAAC,GAAY,EAAE,UAA8B,EAAE,GAAW;QACvE,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAChC,CAAC;IAEM,eAAe,CAAC,OAAqB;QAC1C,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAU,EAAE,GAAY,EAAE,EAAE;YACvD,MAAM,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,kBAAkB,CAAC,OAAuB;QAC/C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAY,EAAE,EAAE;YAC5C,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,eAAe,CAAC,IAAY,EAAE,OAA2B;QAC9D,MAAM,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,CAAC;IAEM,aAAa,CAAC,OAAqB;QACxC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAEM,aAAa,CAAC,GAAY;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,SAAS,CAAE,GAAY,EAAE,IAAY;QAC1C,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAEM,SAAS,CAAC,GAAY,EAAE,IAAY,EAAE,KAAa;QACxD,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;IAEM,YAAY,CAAE,GAAY,EAAE,IAAY,EAAE,KAAa;QAC5D,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAEM,kBAAkB,CAAC,GAAY;QACpC,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;IAC/B,CAAC;IAEM,gBAAgB,CAAC,OAAoB;QAC1C,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;IAEM,aAAa,CAAC,OAAoB;QACvC,OAAO,OAAO,CAAC,GAAG,CAAC;IACrB,CAAC;IAEM,UAAU,CAAC,OAAY;QAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACnC,CAAC;IAEM,aAAa,CAAC,IAAoB,EAAE,YAAoB,GAAG;QAChE,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;YAC/D,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACnD,QAAQ,IAAI,EAAE,CAAC;gBACb,KAAK,kBAAkB;oBACrB,IAAI,WAAW,KAAK,kBAAkB;wBACnC,GAAG,CAAC,GAAW,CAAC,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;oBAC/C,MAAM;gBACR,KAAK,YAAY;oBACf,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;wBAChC,GAAG,CAAC,GAAW,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;wBAC5D,GAAG,CAAC,GAAW,CAAC,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;oBAC/C,CAAC;oBACD,MAAM;gBACR;oBACG,GAAG,CAAC,GAAW,CAAC,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC/D,MAAM;YACV,CAAC;YACD,MAAM,IAAI,EAAE,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,KAAK;QACV,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;IAEM,cAAc,CAAC,OAA+B;QACnD,MAAM,cAAc,GAAG,OAAO,EAAE,YAAY,CAAC;QAC7C,MAAM,YAAY,GAAG,cAAc;YACjC,CAAC,CAAC,KAAK,CAAC,YAAY;YACpB,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QACtB,IAAI,CAAC,UAAU,GAAG,mBAAmB,CAAC;YACpC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;YAC1B,YAAY;YACZ,qBAAqB,EAAE,KAAK;SAC7B,CAAC,CAAC;IACL,CAAC;IAEM,OAAO;QACZ,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,wBAAwB,CAAC,MAAe,EAAE,OAAiB;QAChE,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC5C,IAAI,CAAC,aAAa,CAAC,mCAAmC,CAAC,CAAC;QACxD,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;QACvC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACnC,CAAC;IAEM,KAAK,CAAC,uBAAuB,CAAC,aAA4B;QAC/D,OAAO,CAAC,IAAY,EAAE,QAAkB,EAAE,EAAE;YAC1C,MAAM,eAAe,GAAG;gBACtB,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG;gBACtC,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;gBAC5C,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG;gBACtC,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO;gBAC9C,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;gBAC1C,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;gBACxC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG;aACvC,CAAC;YACF,MAAM,WAAW,GAAG,CAClB,eAAe,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CACpD,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtB,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,GAAY,EAAE,IAAc,EAAE,EAAE;gBACvD,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YACrC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;IAEM,kBAAkB;QACvB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAEM,MAAM,CAAC,IAAqB,EAAE,GAAG,IAAW;QACjD,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;IAC/C,CAAC;IAEM,SAAS,CAAC,OAAe;QAC9B,OAAO,SAAS,CAAC;YACf,OAAO;YACP,OAAO,EAAE,GAAG,EAAE;gBACZ,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACpC,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1 @@
1
+ export * from "./hono-adapter";
@@ -0,0 +1,2 @@
1
+ export * from "./hono-adapter";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './nest-hono-application.interface';
@@ -0,0 +1,2 @@
1
+ export * from './nest-hono-application.interface';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { ServeStaticOptions } from "@hono/node-server/serve-static";
2
+ import { HttpServer, INestApplication } from "@nestjs/common";
3
+ import { Context, Hono, MiddlewareHandler } from "hono";
4
+ export type TypeBodyParser = "application/json" | "text/plain" | "application/x-www-form-urlencoded";
5
+ interface HonoViewOptions {
6
+ engine: string;
7
+ templates: string;
8
+ }
9
+ export interface NestHonoApplication<TServer extends Hono = Hono> extends INestApplication<TServer> {
10
+ getHttpAdapter(): HttpServer<Context, MiddlewareHandler, Hono>;
11
+ useBodyParser(type: TypeBodyParser, bodyLimit?: number): this;
12
+ useStaticAssets(path: string, options: ServeStaticOptions): this;
13
+ setViewEngine(options: HonoViewOptions | string): this;
14
+ listen(port: number | string, callback?: (err: Error, address: string) => void): Promise<TServer>;
15
+ listen(port: number | string, address: string, callback?: (err: Error, address: string) => void): Promise<TServer>;
16
+ listen(port: number | string, address: string, backlog: number, callback?: (err: Error, address: string) => void): Promise<TServer>;
17
+ }
18
+ export {};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=nest-hono-application.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nest-hono-application.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/nest-hono-application.interface.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,11 +1,17 @@
1
1
  {
2
2
  "name": "@kiyasov/platform-hono",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Nest adapter for Hono",
5
5
  "author": "Islam Kiiasov",
6
6
  "license": "MIT",
7
- "main": "dist/cjs/index.js",
8
- "module": "dist/esm/index.js",
7
+ "main": "./dist/cjs/index.js",
8
+ "module": "./dist/esm/index.js",
9
+ "exports": {
10
+ ".": {
11
+ "require": "./dist/cjs/index.js",
12
+ "import": "./dist/esm/index.js"
13
+ }
14
+ },
9
15
  "publishConfig": {
10
16
  "access": "public"
11
17
  },
@@ -0,0 +1,293 @@
1
+ import { Server } from "node:net";
2
+ import { HttpBindings, createAdaptorServer } from "@hono/node-server";
3
+ import { RESPONSE_ALREADY_SENT } from "@hono/node-server/utils/response";
4
+ import { RequestMethod } from "@nestjs/common";
5
+ import { HttpStatus, Logger } from "@nestjs/common";
6
+ import { bodyLimit } from "hono/body-limit";
7
+ import {
8
+ ErrorHandler,
9
+ NestApplicationOptions,
10
+ RequestHandler,
11
+ } from "@nestjs/common/interfaces";
12
+ import {
13
+ ServeStaticOptions,
14
+ serveStatic,
15
+ } from "@hono/node-server/serve-static";
16
+ import { AbstractHttpAdapter } from "@nestjs/core/adapters/http-adapter";
17
+ import { Context, HonoRequest, Next } from "hono";
18
+ import { Hono } from "hono";
19
+ import { cors } from "hono/cors";
20
+ import { RedirectStatusCode, StatusCode } from "hono/utils/http-status";
21
+ import * as http from "http";
22
+ import { Http2SecureServer, Http2Server } from "http2";
23
+ import * as https from "https";
24
+ import { TypeBodyParser } from "../interfaces";
25
+
26
+ type HonoHandler = RequestHandler<HonoRequest, Context>;
27
+
28
+ type ServerType = Server | Http2Server | Http2SecureServer;
29
+
30
+ /**
31
+ * Adapter for using Hono with NestJS.
32
+ */
33
+ export class HonoAdapter extends AbstractHttpAdapter<
34
+ ServerType,
35
+ HonoRequest,
36
+ Context
37
+ > {
38
+ protected readonly instance: Hono<{ Bindings: HttpBindings }>;
39
+
40
+ constructor() {
41
+ super(new Hono());
42
+ }
43
+
44
+ private getRouteAndHandler(
45
+ pathOrHandler: string | HonoHandler,
46
+ handler?: HonoHandler
47
+ ): [string, HonoHandler] {
48
+ let path = typeof pathOrHandler === "function" ? "" : pathOrHandler;
49
+ handler = typeof pathOrHandler === "function" ? pathOrHandler : handler;
50
+ return [path, handler];
51
+ }
52
+
53
+ private createRouteHandler(routeHandler: HonoHandler) {
54
+ return async (ctx: Context, next: Next) => {
55
+ await routeHandler(ctx.req, ctx, next);
56
+ return this.send(ctx);
57
+ };
58
+ }
59
+
60
+ private send(ctx: Context) {
61
+ const body = ctx.get("body");
62
+ return typeof body === "string" ? ctx.text(body) : ctx.json(body);
63
+ }
64
+
65
+ public get(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
66
+ const [routePath, routeHandler] = this.getRouteAndHandler(
67
+ pathOrHandler,
68
+ handler
69
+ );
70
+ this.instance.get(routePath, this.createRouteHandler(routeHandler));
71
+ }
72
+
73
+ public post(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
74
+ const [routePath, routeHandler] = this.getRouteAndHandler(
75
+ pathOrHandler,
76
+ handler
77
+ );
78
+ this.instance.post(routePath, this.createRouteHandler(routeHandler));
79
+ }
80
+
81
+ public put(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
82
+ const [routePath, routeHandler] = this.getRouteAndHandler(
83
+ pathOrHandler,
84
+ handler
85
+ );
86
+ this.instance.put(routePath, this.createRouteHandler(routeHandler));
87
+ }
88
+
89
+ public delete(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
90
+ const [routePath, routeHandler] = this.getRouteAndHandler(
91
+ pathOrHandler,
92
+ handler
93
+ );
94
+ this.instance.delete(routePath, this.createRouteHandler(routeHandler));
95
+ }
96
+
97
+ public use(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
98
+ const [routePath, routeHandler] = this.getRouteAndHandler(
99
+ pathOrHandler,
100
+ handler
101
+ );
102
+ this.instance.use(routePath, this.createRouteHandler(routeHandler));
103
+ }
104
+
105
+ public patch(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
106
+ const [routePath, routeHandler] = this.getRouteAndHandler(
107
+ pathOrHandler,
108
+ handler
109
+ );
110
+ this.instance.patch(routePath, this.createRouteHandler(routeHandler));
111
+ }
112
+
113
+ public options(pathOrHandler: string | HonoHandler, handler?: HonoHandler) {
114
+ const [routePath, routeHandler] = this.getRouteAndHandler(
115
+ pathOrHandler,
116
+ handler
117
+ );
118
+ this.instance.options(routePath, this.createRouteHandler(routeHandler));
119
+ }
120
+
121
+ public async reply(ctx: Context, body: any, statusCode?: StatusCode) {
122
+ if (statusCode) ctx.status(statusCode);
123
+ const responseContentType = this.getHeader(ctx, "Content-Type");
124
+ if (
125
+ !responseContentType?.startsWith("application/json") &&
126
+ body?.statusCode >= HttpStatus.BAD_REQUEST
127
+ ) {
128
+ Logger.warn(
129
+ "Content-Type doesn't match Reply body, you might need a custom ExceptionFilter for non-JSON responses"
130
+ );
131
+ this.setHeader(ctx, "Content-Type", "application/json");
132
+ }
133
+ ctx.set("body", body);
134
+ }
135
+
136
+ public status(ctx: Context, statusCode: StatusCode) {
137
+ ctx.status(statusCode);
138
+ }
139
+
140
+ public async end() {
141
+ return RESPONSE_ALREADY_SENT;
142
+ }
143
+
144
+ public render(response: any, view: string, options: any) {
145
+ throw new Error("Method not implemented.");
146
+ }
147
+
148
+ public redirect(ctx: Context, statusCode: RedirectStatusCode, url: string) {
149
+ ctx.redirect(url, statusCode);
150
+ }
151
+
152
+ public setErrorHandler(handler: ErrorHandler) {
153
+ this.instance.onError(async (err: Error, ctx: Context) => {
154
+ await handler(err, ctx.req, ctx);
155
+ return this.send(ctx);
156
+ });
157
+ }
158
+
159
+ public setNotFoundHandler(handler: RequestHandler) {
160
+ this.instance.notFound(async (ctx: Context) => {
161
+ await handler(ctx.req, ctx);
162
+ return this.send(ctx);
163
+ });
164
+ }
165
+
166
+ public useStaticAssets(path: string, options: ServeStaticOptions) {
167
+ Logger.log("Registering static assets middleware");
168
+ this.instance.use(path, serveStatic(options));
169
+ }
170
+
171
+ public setViewEngine(options: any | string) {
172
+ throw new Error("Method not implemented.");
173
+ }
174
+
175
+ public isHeadersSent(ctx: Context): boolean {
176
+ return true;
177
+ }
178
+
179
+ public getHeader?(ctx: Context, name: string) {
180
+ return ctx.req.header(name);
181
+ }
182
+
183
+ public setHeader(ctx: Context, name: string, value: string) {
184
+ ctx.header(name, value);
185
+ }
186
+
187
+ public appendHeader?(ctx: Context, name: string, value: string) {
188
+ ctx.res.headers.append(name, value);
189
+ }
190
+
191
+ public getRequestHostname(ctx: Context): string {
192
+ return ctx.req.header().host;
193
+ }
194
+
195
+ public getRequestMethod(request: HonoRequest): string {
196
+ return request.method;
197
+ }
198
+
199
+ public getRequestUrl(request: HonoRequest): string {
200
+ return request.url;
201
+ }
202
+
203
+ public enableCors(options: any) {
204
+ this.instance.use(cors(options));
205
+ }
206
+
207
+ public useBodyParser(type: TypeBodyParser, bodyLimit: number = 1e6) {
208
+ Logger.log("Registering body parser middleware");
209
+ this.instance.use(this.bodyLimit(bodyLimit), async (ctx, next) => {
210
+ const contentType = ctx.req.header("content-type");
211
+ switch (type) {
212
+ case "application/json":
213
+ if (contentType === "application/json")
214
+ (ctx.req as any).body = await ctx.req.json();
215
+ break;
216
+ case "text/plain":
217
+ if (contentType === "text/plain") {
218
+ (ctx.req as any).rawBody = Buffer.from(await ctx.req.text());
219
+ (ctx.req as any).body = await ctx.req.json();
220
+ }
221
+ break;
222
+ default:
223
+ (ctx.req as any).body = await ctx.req.parseBody({ all: true });
224
+ break;
225
+ }
226
+ await next();
227
+ });
228
+ }
229
+
230
+ public close(): Promise<void> {
231
+ return new Promise((resolve) => this.httpServer.close(() => resolve()));
232
+ }
233
+
234
+ public initHttpServer(options: NestApplicationOptions) {
235
+ const isHttpsEnabled = options?.httpsOptions;
236
+ const createServer = isHttpsEnabled
237
+ ? https.createServer
238
+ : http.createServer;
239
+ this.httpServer = createAdaptorServer({
240
+ fetch: this.instance.fetch,
241
+ createServer,
242
+ overrideGlobalObjects: false,
243
+ });
244
+ }
245
+
246
+ public getType(): string {
247
+ return "hono";
248
+ }
249
+
250
+ public registerParserMiddleware(prefix?: string, rawBody?: boolean) {
251
+ Logger.log("Registering parser middleware");
252
+ this.useBodyParser("application/x-www-form-urlencoded");
253
+ this.useBodyParser("application/json");
254
+ this.useBodyParser("text/plain");
255
+ }
256
+
257
+ public async createMiddlewareFactory(requestMethod: RequestMethod) {
258
+ return (path: string, callback: Function) => {
259
+ const routeMethodsMap = {
260
+ [RequestMethod.ALL]: this.instance.all,
261
+ [RequestMethod.DELETE]: this.instance.delete,
262
+ [RequestMethod.GET]: this.instance.get,
263
+ [RequestMethod.OPTIONS]: this.instance.options,
264
+ [RequestMethod.PATCH]: this.instance.patch,
265
+ [RequestMethod.POST]: this.instance.post,
266
+ [RequestMethod.PUT]: this.instance.put,
267
+ };
268
+ const routeMethod = (
269
+ routeMethodsMap[requestMethod] || this.instance.get
270
+ ).bind(this.instance);
271
+ routeMethod(path, async (ctx: Context, next: Function) => {
272
+ await callback(ctx.req, ctx, next);
273
+ });
274
+ };
275
+ }
276
+
277
+ public applyVersionFilter(): () => () => any {
278
+ throw new Error("Versioning not yet supported in Hono");
279
+ }
280
+
281
+ public listen(port: string | number, ...args: any[]): ServerType {
282
+ return this.httpServer.listen(port, ...args);
283
+ }
284
+
285
+ public bodyLimit(maxSize: number) {
286
+ return bodyLimit({
287
+ maxSize,
288
+ onError: () => {
289
+ throw new Error("Body too large");
290
+ },
291
+ });
292
+ }
293
+ }
@@ -0,0 +1 @@
1
+ export * from "./hono-adapter";
@@ -0,0 +1 @@
1
+ export * from './nest-hono-application.interface';
@@ -0,0 +1,72 @@
1
+ import { ServeStaticOptions } from "@hono/node-server/serve-static";
2
+ import { HttpServer, INestApplication } from "@nestjs/common";
3
+ import { Context, Hono, MiddlewareHandler } from "hono";
4
+
5
+ export type TypeBodyParser =
6
+ | "application/json"
7
+ | "text/plain"
8
+ | "application/x-www-form-urlencoded";
9
+
10
+ interface HonoViewOptions {
11
+ engine: string;
12
+ templates: string;
13
+ }
14
+
15
+ /**
16
+ * @publicApi
17
+ */
18
+ export interface NestHonoApplication<TServer extends Hono = Hono>
19
+ extends INestApplication<TServer> {
20
+ /**
21
+ * Returns the underlying HTTP adapter bounded to a Hono app.
22
+ *
23
+ * @returns {HttpServer}
24
+ */
25
+ getHttpAdapter(): HttpServer<Context, MiddlewareHandler, Hono>;
26
+
27
+ /**
28
+ * Register Hono body parsers on the fly.
29
+ *
30
+ * @example
31
+ * // enable the json parser with a parser limit of 50mb
32
+ * app.useBodyParser('application/json', 50 * 1024 * 1024);
33
+ *
34
+ * @returns {this}
35
+ */
36
+ useBodyParser(type: TypeBodyParser, bodyLimit?: number): this;
37
+
38
+ /**
39
+ * Sets a base directory for public assets.
40
+ * Example `app.useStaticAssets('public', { root: '/' })`
41
+ * @returns {this}
42
+ */
43
+ useStaticAssets(path: string, options: ServeStaticOptions): this;
44
+
45
+ /**
46
+ * Sets a view engine for templates (views), for example: `pug`, `handlebars`, or `ejs`.
47
+ *
48
+ * Don't pass in a string. The string type in the argument is for compatibility reason and will cause an exception.
49
+ * @returns {this}
50
+ */
51
+ setViewEngine(options: HonoViewOptions | string): this;
52
+
53
+ /**
54
+ * Starts the application.
55
+ * @returns A Promise that, when resolved, is a reference to the underlying HttpServer.
56
+ */
57
+ listen(
58
+ port: number | string,
59
+ callback?: (err: Error, address: string) => void
60
+ ): Promise<TServer>;
61
+ listen(
62
+ port: number | string,
63
+ address: string,
64
+ callback?: (err: Error, address: string) => void
65
+ ): Promise<TServer>;
66
+ listen(
67
+ port: number | string,
68
+ address: string,
69
+ backlog: number,
70
+ callback?: (err: Error, address: string) => void
71
+ ): Promise<TServer>;
72
+ }