Skip to content

Conversation

@kricsleo
Copy link
Member

@kricsleo kricsleo commented Dec 27, 2025

resolves #149

This is a type-only compatibility improvement for the toFetchHandler utility, making it compatible with libraries that only support HTTP/1, e.g., express.

Summary by CodeRabbit

  • Refactor
    • Improved handling for different HTTP protocol versions to clarify server request/response flows.
  • Bug Fixes
    • More robust adapter error handling that ensures a consistent 500 response for unexpected failures.
  • Tests
    • Expanded and updated adapter tests to cover multiple server frameworks and protocol scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@kricsleo kricsleo requested a review from pi0 as a code owner December 27, 2025 17:06
@coderabbitai
Copy link

coderabbitai bot commented Dec 27, 2025

📝 Walkthrough

Walkthrough

Introduce protocol-specific Node HTTP types (HTTP/1 and HTTP/2), relax handler parameter typings by casting node request/response to any in adapter calls, add explicit error handling in one fetch path, and update tests to use NodeHttp1Handler and expand adapter fixtures.

Changes

Cohort / File(s) Summary
Type definitions
src/types.ts
Added NodeHttp1Handler and NodeHttp2Handler; replaced single NodeHttpHandler with NodeHttpHandler = NodeHttp1Handler | NodeHttp2Handler. Added NodeHTTP1Middleware and NodeHTTP2Middleware; replaced NodeHTTPMiddleware with union type.
Node adapter callsites
src/adapters/_node/call.ts, src/adapters/_node/web/fetch.ts
Cast nodeReq and nodeRes to any when invoking handlers/middleware to relax typings. In fetch.ts, added a catch branch that returns a 500 Internal Server Error on handler promise rejection.
Tests — node adapters
test/node-adapters.test.ts
Updated imports, fixtures, and test wiring to use NodeHttp1Handler; expanded fixtures to include node, express, and fastify adapters; adjusted app readiness/handler extraction logic.
Manifest
package.json
Mentioned in diff header (no behavioral changes described).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hops of code across a branch so merry,

HTTP/1 and HTTP/2 now tucked in my carry,
Casts loosen paws where types were tight,
Tests now dance with adapters alight,
I nibble bugs and bake the build — carrot bright! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: splitting HTTP/1 and HTTP/2 handler types to resolve type compatibility issues.
Linked Issues check ✅ Passed The PR introduces HTTP/1-specific handler/middleware types (NodeHttp1Handler, NodeHTTP1Middleware) enabling Express-style handlers in toFetchHandler, directly addressing issue #149's type compatibility requirement.
Out of Scope Changes check ✅ Passed All changes are scoped to type definitions and their usages; no unrelated functional changes are present beyond what's needed to support HTTP/1 and HTTP/2 handler type separation.
✨ Finishing touches
  • 📝 Generate docstrings

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.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 27, 2025

Open in StackBlitz

npm i https://pkg.pr.new/h3js/srvx@154

commit: 38a2ca4

Copy link

@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: 0

🧹 Nitpick comments (1)
src/adapters/_node/adapter.ts (1)

45-48: Consider adding JSDoc for the new type.

The NodeHttp1Handler type definition correctly represents Express-style handlers. Consider adding a brief JSDoc comment to document its purpose for future maintainers.

📝 Optional: Add documentation
+/**
+ * Node.js HTTP/1.x handler type for compatibility with libraries like Express.
+ */
 type NodeHttp1Handler = (
   req: NodeHttp.IncomingMessage,
   res: NodeHttp.ServerResponse,
 ) => void | Promise<void>;
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 879ab07 and 67f0302.

📒 Files selected for processing (1)
  • src/adapters/_node/adapter.ts
🔇 Additional comments (2)
src/adapters/_node/adapter.ts (2)

1-1: LGTM!

The type-only import is appropriate for defining the NodeHttp1Handler type and adds no runtime overhead.


54-69: The type union addition is safe. While NodeHttp1Handler is cast to NodeHttpHandler on lines 62 and 66, both handler types are compatible at runtime because WebIncomingMessage extends NodeHttp.IncomingMessage and WebServerResponse extends NodeHttp.ServerResponse, which satisfy both signatures. The actual objects passed to the handler are always HTTP/1 types, making the cast valid.

@pi0 pi0 changed the title chore(toFetchHandler): allow HTTP/1 handler type types(toFetchHandler): allow HTTP/1 handler type Dec 30, 2025
@pi0 pi0 changed the title types(toFetchHandler): allow HTTP/1 handler type fix(types): split http1 and http2 handler/middleware Dec 30, 2025
@pi0 pi0 changed the title fix(types): split http1 and http2 handler/middleware fix(types): split http1 and http2 handler/middleware types Dec 30, 2025
Copy link

@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: 0

🧹 Nitpick comments (1)
src/types.ts (1)

368-380: Middleware type split correctly mirrors handler pattern.

The middleware types follow the same HTTP/1/HTTP/2 separation pattern as the handlers, which is consistent and correct. This allows Express-style middleware (HTTP/1) to be properly typed.

Note: There's a naming inconsistency between handler and middleware types:

  • Handlers use NodeHttp1Handler / NodeHttp2Handler (mixed case "Http")
  • Middleware use NodeHTTP1Middleware / NodeHTTP2Middleware (uppercase "HTTP")

If this inconsistency existed before this PR, it can be ignored. If introduced here, consider aligning to NodeHttp1Middleware / NodeHttp2Middleware for consistency.

🔎 Optional refactor for naming consistency
-export type NodeHTTP1Middleware = (
+export type NodeHttp1Middleware = (
   req: NodeHttp.IncomingMessage,
   res: NodeHttp.ServerResponse,
   next: (error?: Error) => void,
 ) => unknown | Promise<unknown>;

-export type NodeHTTP2Middleware = (
+export type NodeHttp2Middleware = (
   req: NodeHttp2.Http2ServerRequest,
   res: NodeHttp2.Http2ServerResponse,
   next: (error?: Error) => void,
 ) => unknown | Promise<unknown>;

-export type NodeHTTPMiddleware = NodeHTTP1Middleware | NodeHTTP2Middleware;
+export type NodeHttpMiddleware = NodeHttp1Middleware | NodeHttp2Middleware;
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67f0302 and de6917f.

📒 Files selected for processing (1)
  • src/types.ts
🔇 Additional comments (1)
src/types.ts (1)

356-366: Type split is architecturally sound but Express compatibility claim is unsupported.

While the separation of HTTP/1 and HTTP/2 handler types is correct and improves type clarity, the specific claim that Express apps "explicitly match NodeHttp1Handler" is contradicted by the test code. The Express handler on line 78 of test/node-adapters.test.ts requires an explicit as NodeHttpHandler type assertion, which indicates that Express types do not naturally match either NodeHttp1Handler or the union type without forcing it. Additionally, there is no reference to issue #149 in the codebase to confirm this change addresses that specific problem.

The type split is a good improvement for code organization and type safety, but the review should avoid claiming it resolves Express compatibility issues without stronger evidence.

Likely an incorrect or invalid review comment.

@pi0 pi0 changed the title fix(types): split http1 and http2 handler/middleware types fix(types): split http1 and http2 handler types Dec 30, 2025
@pi0 pi0 merged commit 80f95b6 into h3js:main Dec 30, 2025
10 of 11 checks passed
Copy link

@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: 4

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between de6917f and 38a2ca4.

📒 Files selected for processing (3)
  • src/adapters/_node/call.ts
  • src/adapters/_node/web/fetch.ts
  • test/node-adapters.test.ts
🧰 Additional context used
🧬 Code graph analysis (3)
src/adapters/_node/call.ts (2)
examples/node-handler/server.ts (1)
  • handler (4-7)
src/types.ts (1)
  • NodeHttpHandler (366-366)
test/node-adapters.test.ts (1)
src/types.ts (1)
  • NodeHttp1Handler (356-359)
src/adapters/_node/web/fetch.ts (1)
examples/node-handler/server.ts (1)
  • handler (4-7)
🔇 Additional comments (1)
test/node-adapters.test.ts (1)

43-96: Good: Expanded test coverage for Express and Fastify.

Adding Express and Fastify fixtures provides valuable test coverage for the PR's objective of supporting HTTP/1 handlers from popular frameworks. The fixtures test different handler patterns (native Node.js, Express middleware, Fastify async handlers) which strengthens confidence in the adapter's compatibility.

However, note the type assertion concerns flagged separately - the tests should validate type compatibility without requiring as any casts.

header: req.headers["x-test"] === "1",
body: req.body?.test === true,
});
}) as NodeHttp1Handler,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the test file and view lines around 78, 93, 104
echo "=== Checking test/node-adapters.test.ts file size ==="
wc -l test/node-adapters.test.ts

echo -e "\n=== Lines 70-110 of test/node-adapters.test.ts ==="
sed -n '70,110p' test/node-adapters.test.ts

echo -e "\n=== Search for NodeHttp1Handler type definition ==="
rg 'type NodeHttp1Handler|interface NodeHttp1Handler' -A 5

echo -e "\n=== Search for NodeHttp1Handler export ==="
rg 'export.*NodeHttp1Handler' -B 2 -A 2

Repository: h3js/srvx

Length of output: 2204


🏁 Script executed:

#!/bin/bash
echo "=== Find fetchNodeHandler definition and signature ==="
rg 'function fetchNodeHandler|const fetchNodeHandler|export.*fetchNodeHandler' -A 5

echo -e "\n=== Search for fetchCallers definition in test file ==="
sed -n '1,80p' test/node-adapters.test.ts

echo -e "\n=== Check the caller implementations ==="
rg 'class.*Caller|function.*Caller' -A 10 test/node-adapters.test.ts

echo -e "\n=== Look at what happens without the as any cast ==="
sed -n '95,115p' test/node-adapters.test.ts

Repository: h3js/srvx

Length of output: 3923


🏁 Script executed:

#!/bin/bash
echo "=== Check toNodeHandler implementation ==="
rg 'export.*toNodeHandler|function toNodeHandler' -A 15

echo -e "\n=== Check if there's type acceptance for Express/Fastify apps ==="
rg 'Express.*Application|Fastify.*Instance' src/

echo -e "\n=== Look at the complete second caller definition more carefully ==="
sed -n '30,48p' test/node-adapters.test.ts

echo -e "\n=== Check PR or issue context in comments ==="
head -50 test/node-adapters.test.ts

Repository: h3js/srvx

Length of output: 4065


🏁 Script executed:

#!/bin/bash
echo "=== Get full view of fetchNodeHandler function ==="
sed -n '1,30p' src/adapters/_node/web/fetch.ts

echo -e "\n=== Check what NodeHttpHandler includes ==="
rg 'type NodeHttpHandler|interface NodeHttpHandler' -B 2 -A 2

echo -e "\n=== Verify the actual test expectations - lines 100-120 ==="
sed -n '100,120p' test/node-adapters.test.ts

echo -e "\n=== Check if there are any utility functions to wrap Express/Fastify ==="
rg 'express|fastify' src/ -l

echo -e "\n=== Look for any type overloads for NodeHttpHandler ==="
rg 'NodeHttpHandler' src/types.ts -B 2 -A 5

Repository: h3js/srvx

Length of output: 2918


🏁 Script executed:

#!/bin/bash
echo "=== Check the callNodeHandler implementation ==="
sed -n '1,50p' src/adapters/_node/call.ts

echo -e "\n=== Search for any type overloads or conditionals handling Express/Fastify ==="
rg 'typeof.*express|typeof.*fastify|instanceof.*Application|instanceof.*FastifyInstance' src/

echo -e "\n=== Look at complete adapter.ts for any special handling ==="
cat src/adapters/_node/adapter.ts

echo -e "\n=== Check if Express/Fastify have __nodeHandler properties ==="
rg '__nodeHandler' src/

Repository: h3js/srvx

Length of output: 4143


Test bypasses type validation with casts that hide Express/Fastify incompatibility.

The test uses type assertions at three locations:

  • Line 78: as NodeHttp1Handler for Express app
  • Line 93: as NodeHttp1Handler for Fastify routing
  • Line 104: as any when calling fetchNodeHandler

These casts reveal that Express.Application and Fastify's routing don't naturally match NodeHttp1Handler (which expects a (req: IncomingMessage, res: ServerResponse) => void | Promise<void> function signature). The as any cast at line 104 bypasses type checking entirely, preventing validation that the code properly accepts these handlers without type errors.

To properly validate Express/Fastify support, remove the as any cast on line 104. If type errors appear, the underlying handler type definitions need adjustment rather than working around them with casts. The fixtures' type declarations and casts on lines 78 and 93 should also be eliminated if the PR's goal is true type compatibility.

🤖 Prompt for AI Agents
In test/node-adapters.test.ts around lines 78, 93 and 104, the test is
force-casting Express and Fastify handlers to NodeHttp1Handler and using `as
any` when calling fetchNodeHandler, which hides real type incompatibilities;
remove the `as NodeHttp1Handler` casts at lines 78 and 93 and the `as any` on
line 104, then fix the type definitions instead of masking errors — either
adjust the fixture types to implement the exact (req: IncomingMessage, res:
ServerResponse) => void | Promise<void> signature or broaden the
NodeHttp1Handler/fetchNodeHandler type declarations (or add overloads/generic)
so Express.Application and Fastify routing types are accepted by the handler
callsite; run type-checks and update tests until tsc passes without casts.

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.

Type error on toFetchHandler when implementing Express

2 participants