Skip to content

fix: Bun HTML imports returning empty object (#1771)#1788

Open
NongTham wants to merge 5 commits intoelysiajs:mainfrom
NongTham:fix/bun-html-import-1771
Open

fix: Bun HTML imports returning empty object (#1771)#1788
NongTham wants to merge 5 commits intoelysiajs:mainfrom
NongTham:fix/bun-html-import-1771

Conversation

@NongTham
Copy link
Contributor

@NongTham NongTham commented Mar 7, 2026

This PR addresses a regression introduced during the transition to the system-level router (optimized in recent versions), where Bun's native HTMLBundle objects were no longer correctly identified during the response lifecycle, resulting in an empty JSON object {} fallback.

Changes:

  • Unified HTMLBundle Utility: Introduced a robust detection utility in src/adapter/bun/utils.ts to replace localized and potentially fragile toString checks. This ensures reliable identification of imported HTML files across all deployment environments, including compiled or minified production builds.
  • Enhanced Response Lifecycle Mapping: Integrated the unified detection into mapResponse, mapEarlyResponse, and mapCompactResponse. This ensures that any HTMLBundle returned from a handler is correctly recognized and served via Bun's high-performance file-serving path (handleFile).
  • Dynamic Context Fix: Specifically resolves the serialization issue in dynamic handlers (e.g., arrow functions or routes with middleware hooks) that were unintentionally bypassing the specialized HTML handling logic.

(Note: This regression likely stemmed from the shift toward manual route handling for performance optimizations. Physical verification confirms that static, hook-based, and pure dynamic handlers now correctly serve imported HTML content with appropriate headers.)

Summary by CodeRabbit

  • Improvements

    • Enhanced HTML bundle handling for more reliable file-based delivery in Bun environments.
    • Improved schema meta-property detection with deeper, more consistent nested checks.
  • API

    • Route definitions now accept an optional options object to specify query validation.
  • Tests

    • Added tests for nested schema meta detection and updated tests to reflect shallow-cloned response shapes and concurrent request behavior.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5fa0a512-91be-4811-852e-259ef58bfd12

📥 Commits

Reviewing files that changed from the base of the PR and between 49f90a6 and ad41a05.

📒 Files selected for processing (1)
  • test/bun/router.test.ts

Walkthrough

Moved HTML bundle detection into a new Bun utils module, updated Bun adapter handlers to route HTML-bundle-shaped responses through Bun.file, removed the isHTMLBundle export from the adapter index, refactored hasElysiaMeta to a recursive check, and added tests for hasElysiaMeta and updated several tests to return shallow copies and adjusted expectations.

Changes

Cohort / File(s) Summary
Bun adapter — handlers & utils
src/adapter/bun/handler-native.ts, src/adapter/bun/handler.ts, src/adapter/bun/index.ts, src/adapter/bun/utils.ts
Extracted isHTMLBundle into utils.ts and updated imports; removed isHTMLBundle export from index.ts; added isHTMLBundle checks in response mapping branches to route HTML-bundle-shaped responses via Bun.file(...); minor formatting tweaks.
Schema — hasElysiaMeta refactor
src/schema.ts
Rewrote hasElysiaMeta to perform a unified recursive evaluation of nested properties (removed earlier selective branching/early returns); other formatting and type-layout adjustments.
Tests — new & updates
test/schema/schema-utils.test.ts, test/aot/response.test.ts, test/core/normalize.test.ts, test/lifecycle/parser.test.ts, test/path/path.test.ts, test/sucrose/query.test.ts, test/validator/body.test.ts, test/bun/router.test.ts
Added tests for hasElysiaMeta; updated many tests to return shallow copies ({ ...obj }), adjusted concurrency test behavior, added query/body schemas in some tests, updated expectations and server teardown in Bun tests.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Adapter as BunAdapter
    participant BunRuntime as Bun
    participant FS as FileSystem

    Client->>Adapter: send request
    Adapter->>Adapter: mapResponse / mapEarlyResponse
    alt response is HTML bundle (isHTMLBundle)
        Adapter->>BunRuntime: call Bun.file(index)
        BunRuntime->>FS: read file
        FS-->>BunRuntime: file stream
        BunRuntime-->>Adapter: file-based response
        Adapter-->>Client: file-based response
    else other response types
        Adapter-->>Client: normal mapped response (JSON/String/FormData/Response/etc.)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • 1.4.8 patch #1440 — Modifies Bun adapter response mapping and ElysiaFile/File/Blob handling; strongly related to response-routing changes here.
  • 1.4.6 patch #1411 — Related Bun HTML bundle handling changes and HTML-bundle detection adjustments.

Poem

🐰 I hopped through handlers, light and keen,
pulled bundle-detect into a shared scene.
Meta now digs deep, no stone left undone,
tests stand watch till the checks are run,
Bun hums along — a carrot-sweet run! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically identifies the main fix: resolving Bun HTML imports that were returning empty objects. It directly matches the core objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
test/schema/schema-utils.test.ts (1)

175-176: Consider using ES module imports for consistency.

The test file uses ES module imports elsewhere (import { describe, it, expect } from 'bun:test'), but hasElysiaMeta is imported via require. This creates inconsistency and may not benefit from static analysis or TypeScript type-checking.

♻️ Suggested refactor
+import { hasElysiaMeta } from '../../src/schema'
+
 describe('hasElysiaMeta', () => {
-	const { hasElysiaMeta } = require('../../src/schema')
-
 	it('finds elysiaMeta in Object properties even if placed after another property', () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/schema/schema-utils.test.ts` around lines 175 - 176, The test currently
uses require to load hasElysiaMeta, causing inconsistent module syntax; replace
the CommonJS require with an ES module import (e.g., add an import {
hasElysiaMeta } from '../../src/schema' at the top of the test) so hasElysiaMeta
is imported using the same ESM style as the rest of the file; update any
existing require(...) reference in the describe('hasElysiaMeta', ...) block to
use the imported symbol instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/adapter/bun/handler.ts`:
- Line 168: The mapEarlyResponse function currently returns new Response('')
when given undefined or null input, which breaks semantics—change the
early-return branch in src/adapter/bun/handler.ts (the guard that checks
response === undefined || response === null) to return undefined instead of new
Response(''), so mapEarlyResponse returns Response | undefined with undefined
preserved for null/undefined inputs and downstream checks like if (result) / if
(result !== undefined) behave correctly.

In `@src/adapter/bun/utils.ts`:
- Around line 1-8: The current isHTMLBundle duck-typing is too permissive
because it treats any object with a string index as an HTMLBundle; update
isHTMLBundle to require the existing toString() check OR both a string index and
a bundle-like property (e.g., a non-null object `files`) to better match
BunHTMLBundlelike. In other words, change the fallback from just `typeof
handle.index === 'string'` to `typeof handle.index === 'string' && typeof
handle.files === 'object' && handle.files !== null` (keep the original
toString() check) so the function `isHTMLBundle` only returns true for real
bundle-like shapes.

---

Nitpick comments:
In `@test/schema/schema-utils.test.ts`:
- Around line 175-176: The test currently uses require to load hasElysiaMeta,
causing inconsistent module syntax; replace the CommonJS require with an ES
module import (e.g., add an import { hasElysiaMeta } from '../../src/schema' at
the top of the test) so hasElysiaMeta is imported using the same ESM style as
the rest of the file; update any existing require(...) reference in the
describe('hasElysiaMeta', ...) block to use the imported symbol instead.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 513afe18-978a-4ba9-8095-c4afe9f7438d

📥 Commits

Reviewing files that changed from the base of the PR and between 169e54a and d333670.

📒 Files selected for processing (6)
  • src/adapter/bun/handler-native.ts
  • src/adapter/bun/handler.ts
  • src/adapter/bun/index.ts
  • src/adapter/bun/utils.ts
  • src/schema.ts
  • test/schema/schema-utils.test.ts

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 7, 2026

Open in StackBlitz

npm i https://pkg.pr.new/elysia@1788

commit: b004116

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant