@basaltkit/hono 1.0.0 → 1.2.0

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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Machize Contributors
3
+ Copyright (c) 2026 Basalt Contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/index.d.ts CHANGED
@@ -5,12 +5,20 @@ import { BasaltRoute, RequestEnricher, RouteGuard } from '@basaltkit/http';
5
5
  import { Hono } from 'hono';
6
6
 
7
7
  declare const HONO: _basaltkit_core.Token<Hono<any, hono_types.BlankSchema, "/">>;
8
+ /** Default maximum request body size (1 MiB) — override via honoPlugin({ bodyLimit }). */
9
+ declare const DEFAULT_BODY_LIMIT = 1048576;
8
10
  /** Mounts Basalt routes on a Hono app (usable without the plugin). */
9
11
  declare function registerRoutes(app: Hono<any>, routes: BasaltRoute[], container?: Container, enrichers?: RequestEnricher[], guards?: RouteGuard[]): void;
10
12
  interface HonoPluginOptions {
11
13
  routes?: BasaltRoute[];
12
14
  /** Bring your own Hono app; otherwise a fresh one is created. */
13
15
  app?: Hono<any>;
16
+ /**
17
+ * Maximum request body size in bytes. A request whose `Content-Length`
18
+ * exceeds this is rejected with 413 before the body is read — Hono/edge has
19
+ * no default cap, so without this a large upload is unbounded. Default: 1 MiB.
20
+ */
21
+ bodyLimit?: number;
14
22
  }
15
23
  /**
16
24
  * Runs Basalt on Hono (Node, Bun, Deno, edge). The same routes, enrichers and
@@ -19,4 +27,4 @@ interface HonoPluginOptions {
19
27
  */
20
28
  declare function honoPlugin(options?: HonoPluginOptions): _basaltkit_core.BasaltPlugin<unknown>;
21
29
 
22
- export { HONO, type HonoPluginOptions, honoPlugin, registerRoutes };
30
+ export { DEFAULT_BODY_LIMIT, HONO, type HonoPluginOptions, honoPlugin, registerRoutes };
package/dist/index.js CHANGED
@@ -4,10 +4,15 @@ import {
4
4
  HttpServerCollector,
5
5
  HTTP_SERVER,
6
6
  runRoute,
7
- toErrorResponse
7
+ toErrorResponse,
8
+ isSseResponse,
9
+ sseProducerOf,
10
+ driveSse,
11
+ SSE_HEADERS
8
12
  } from "@basaltkit/http";
9
13
  import { Hono } from "hono";
10
14
  var HONO = createToken("hono");
15
+ var DEFAULT_BODY_LIMIT = 1048576;
11
16
  async function parseBody(context) {
12
17
  const method = context.req.method;
13
18
  if (method === "GET" || method === "HEAD") return void 0;
@@ -33,6 +38,25 @@ async function toNeutralRequest(context) {
33
38
  raw: context
34
39
  };
35
40
  }
41
+ function sseResponse(context, producer) {
42
+ const encoder = new TextEncoder();
43
+ const stream = new ReadableStream({
44
+ start(controller) {
45
+ void driveSse(producer, {
46
+ write: (frame) => controller.enqueue(encoder.encode(frame)),
47
+ end: () => {
48
+ try {
49
+ controller.close();
50
+ } catch {
51
+ }
52
+ },
53
+ onClose: (listener) => context.req.raw.signal.addEventListener("abort", listener)
54
+ });
55
+ }
56
+ });
57
+ const { connection: _connection, ...headers } = SSE_HEADERS;
58
+ return new Response(stream, { headers });
59
+ }
36
60
  var HonoReply = class {
37
61
  constructor(context) {
38
62
  this.context = context;
@@ -90,6 +114,7 @@ function handlerFor(definition, container, enrichers, guards) {
90
114
  enrichers,
91
115
  guards
92
116
  });
117
+ if (isSseResponse(result)) return sseResponse(context, sseProducerOf(result));
93
118
  return toResponse(reply, reply.sent ? reply.payload : result);
94
119
  } catch (error) {
95
120
  const { status, body } = toErrorResponse(error);
@@ -119,7 +144,18 @@ function honoPlugin(options = {}) {
119
144
  const metadata = ensureMetadata(container);
120
145
  const enrichers = metadata.get("http:enrichers");
121
146
  const guards = metadata.get("http:guards");
147
+ const bodyLimit = options.bodyLimit ?? DEFAULT_BODY_LIMIT;
122
148
  hooks.on("app:booted", () => {
149
+ app.use(async (context, next) => {
150
+ const declared = Number(context.req.header("content-length") ?? "");
151
+ if (Number.isFinite(declared) && declared > bodyLimit) {
152
+ return context.json(
153
+ { code: "PAYLOAD_TOO_LARGE", message: `Request body exceeds the ${bodyLimit}-byte limit.` },
154
+ 413
155
+ );
156
+ }
157
+ return next();
158
+ });
123
159
  if (collector.afterHooks.length) {
124
160
  app.use(async (context, next) => {
125
161
  const start = Date.now();
@@ -157,6 +193,7 @@ function honoPlugin(options = {}) {
157
193
  });
158
194
  }
159
195
  export {
196
+ DEFAULT_BODY_LIMIT,
160
197
  HONO,
161
198
  honoPlugin,
162
199
  registerRoutes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basaltkit/hono",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Hono adapter for Basalt: run the same typed routes, enrichers and guards on Hono (Node, Bun, Deno, edge) as on Fastify or Express.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -14,8 +14,8 @@
14
14
  "dist"
15
15
  ],
16
16
  "dependencies": {
17
- "@basaltkit/core": "^1.0.0",
18
- "@basaltkit/http": "^1.0.0"
17
+ "@basaltkit/core": "^1.1.0",
18
+ "@basaltkit/http": "^1.7.0"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "hono": "^4.0.0"