fix(hono): refresh handler preamble and fix import paths for hono.handlers option - #3292
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughRegenerates Hono handler preamble (header/imports/factory/validator wiring) while preserving existing user-authored handler bodies by parsing and splicing them back in; fixes tags-split import resolution; exports extractExistingHandlerBodies and adds parsing utilities and tests; also short-circuits zValidator response-hook when the hook returns a Response. ChangesHono handler regeneration (preamble refresh + body preservation)
Response-hook short-circuit (zValidator)
Sequence Diagram(s)sequenceDiagram
actor User
participant Orval as Orval Generator
participant FS as File System
participant Parser as extractExistingHandlerBodies
participant Generator as Preamble Generator
User->>Orval: run generation (existing handler file present)
Orval->>FS: read existing handler file
FS-->>Orval: file contents
Orval->>Parser: extractExistingHandlerBodies(source)
Parser->>Parser: parse exports, track nested braces/strings/regex/comments
Parser-->>Orval: Map<handlerName, handlerBody>
Orval->>Generator: compute fresh preamble (header/imports/factory/validators)
Generator-->>Orval: preamble text
Orval->>Orval: merge preamble + generated wrappers, splice extracted handler bodies
Orval->>FS: write updated handler file
FS-->>User: handler file updated (preamble refreshed, user bodies preserved)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/hono/src/index.ts`:
- Around line 352-375: The current logic preserves the entire previous handler
block (including factory.createHandlers(...) and zValidator(...) entries) when
extracting existing handlers via extractExistingHandlers, causing stale
validators to survive; change the merge in the loop that builds content so that
for each handlerName you extract only the inner async handler body from existing
(not the surrounding factory.createHandlers wrapper) and then always regenerate
the wrapper and validator chain (using verbOption and getHonoHandlers) based on
current metadata; additionally detect if the list of emitted validators
(zValidator entries) differs from the current verbOption validators and in that
case ignore the old wrapper and emit a fresh handler block so imports and
middleware reflect the new configuration.
- Around line 398-424: extractExistingHandlers currently uses naive parenthesis
depth counting (exportRegex + manual loop) and will break when ) appears inside
strings, templates, regexes, or comments; update it to either (preferred) use
the TypeScript tokenizer/parser to locate the factory.createHandlers call and
extract the full node text, or (if not adding a parser) implement a
lexical-state loop that skips over single-quoted, double-quoted, template
literals, regex literals and both line and block comments while counting
parentheses so you only decrement depth for ) characters outside those ranges;
keep the exported symbol detection (exportRegex / match[1]) but replace the
character-scanning loop in extractExistingHandlers so it advances past
quoted/comment/regex ranges correctly before treating parentheses as
depth-affecting.
In
`@tests/__snapshots__/hono/petstore-tags-split-with-handlers/endpoints.validator.ts`:
- Around line 161-193: The hook result handling overwrites c.res later,
nullifying hook-provided responses; update the validator logic in
endpoints.validator.ts (the block using hook, hookResult, c.res and success) to
return early or skip the final c.res assignment when hookResult is a Response or
contains response: Response — i.e., after setting c.res from hookResult,
short-circuit out of the function (or set a flag like handled) so the subsequent
success/failure branch that rebuilds c.res is not executed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2cf7dd6e-0267-4269-8f71-b63248a0b7d5
📒 Files selected for processing (41)
docs/content/docs/guides/hono.mdxpackages/hono/src/index.test.tspackages/hono/src/index.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.context.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.schemas.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.validator.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.zod.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/createPets.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/deletePetById.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/healthCheck.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/listPets.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/showPetById.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/showPetWithOwner.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/endpoints.schemas.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/endpoints.validator.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/health/health.context.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/health/health.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/pets/pets.context.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/pets/pets.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/pets/pets.zod.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/createPets.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/deletePetById.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/healthCheck.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/listPets.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/showPetById.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/showPetWithOwner.tstests/__snapshots__/hono/petstore-tags-with-handlers/endpoints.schemas.tstests/__snapshots__/hono/petstore-tags-with-handlers/endpoints.validator.tstests/__snapshots__/hono/petstore-tags-with-handlers/health.context.tstests/__snapshots__/hono/petstore-tags-with-handlers/health.tstests/__snapshots__/hono/petstore-tags-with-handlers/pets.context.tstests/__snapshots__/hono/petstore-tags-with-handlers/pets.tstests/__snapshots__/hono/petstore-tags-with-handlers/pets.zod.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/createPets.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/deletePetById.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/healthCheck.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/listPets.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/showPetById.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/showPetWithOwner.tstests/configs/hono.config.ts
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@samples/hono/hono-with-fetch-client/hono-app/src/handlers/createPets.ts`:
- Around line 10-15: The zValidator calls use the old camelCase names
(createPetsBody, createPetsResponse) but the file imports PascalCase types
CreatePetsBody and CreatePetsResponse; update the zValidator invocations in the
createPetsHandlers call to reference the imported PascalCase identifiers
(CreatePetsBody, CreatePetsResponse) so they match the imports and resolve
correctly—look for createFactory, createPetsHandlers and zValidator to locate
and fix the mismatched identifiers.
In `@samples/hono/hono-with-fetch-client/hono-app/src/handlers/listPets.ts`:
- Around line 14-15: The validators are referencing old identifiers
listPetsQueryParams and listPetsResponse which no longer exist; update the
zValidator calls in the listPets handler to use the imported renamed Zod schemas
ListPetsQueryParams and ListPetsResponse (e.g., zValidator('query',
ListPetsQueryParams) and zValidator('response', ListPetsResponse)) so the
identifiers match the imports and resolve correctly (references: zValidator,
ListPetsQueryParams, ListPetsResponse, listPets handler).
In `@samples/hono/hono-with-fetch-client/hono-app/src/handlers/updatePets.ts`:
- Around line 10-15: The handlers import the Zod types UpdatePetsBody and
UpdatePetsResponse but pass undefined identifiers
updatePetsBody/updatePetsResponse into zValidator; fix by using the imported
symbols (pass UpdatePetsBody and UpdatePetsResponse to zValidator) or adjust the
import to match the validator calls, i.e., ensure the identifiers passed to
zValidator in factory.createHandlers match the actual exported names
(UpdatePetsBody, UpdatePetsResponse) so zValidator('json', ...) and
zValidator('response', ...) receive the correct Zod schemas.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9770e5d6-5905-482b-99c2-c867b34065ad
📒 Files selected for processing (16)
samples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/createPets.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/listPets.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/showPetById.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/updatePets.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/createPets.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/listPets.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/showPetById.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/updatePets.tssamples/hono/hono-with-zod/__snapshots__/handlers/createPets.tssamples/hono/hono-with-zod/__snapshots__/handlers/listPets.tssamples/hono/hono-with-zod/__snapshots__/handlers/showPetById.tssamples/hono/hono-with-zod/__snapshots__/handlers/updatePets.tssamples/hono/hono-with-zod/src/handlers/createPets.tssamples/hono/hono-with-zod/src/handlers/listPets.tssamples/hono/hono-with-zod/src/handlers/showPetById.tssamples/hono/hono-with-zod/src/handlers/updatePets.ts
✅ Files skipped from review due to trivial changes (9)
- samples/hono/hono-with-zod/src/handlers/createPets.ts
- samples/hono/hono-with-fetch-client/hono-app/src/handlers/showPetById.ts
- samples/hono/hono-with-fetch-client/snapshots/hono-app/handlers/listPets.ts
- samples/hono/hono-with-zod/src/handlers/listPets.ts
- samples/hono/hono-with-zod/src/handlers/updatePets.ts
- samples/hono/hono-with-zod/snapshots/handlers/createPets.ts
- samples/hono/hono-with-zod/snapshots/handlers/updatePets.ts
- samples/hono/hono-with-zod/snapshots/handlers/showPetById.ts
- samples/hono/hono-with-zod/snapshots/handlers/listPets.ts
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/hono/src/index.ts`:
- Around line 522-528: The isRegexContext function misclassifies slashes after
keywords as division; update it to, after skipping whitespace, detect whether
the preceding characters form one of the keywords or tokens that allow a regex
literal (e.g., return, throw, yield, await, case) or a spread ('...') instead of
a generic word char check. Concretely: in isRegexContext, when you hit a
non-whitespace char walking backward, if that char is '.' check for a preceding
'...' sequence and treat it as a regex context; if the char is an identifier
char (letter/underscore/$), scan further backward to extract the full token and
compare against the allowed keyword set (return, throw, yield, await, case); if
it matches, return true (regex), otherwise fall back to the existing division
detection logic. This ensures findMatchingClose and related bracket tracking
treat regex literals after those keywords correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 59f2d7cc-2f36-46d0-a0dc-51e09d8de35b
📒 Files selected for processing (26)
packages/hono/src/index.test.tspackages/hono/src/index.tspackages/hono/src/zValidator.tssamples/hono/composite-routes-with-tags-split/__snapshots__/endpoints/validator.tssamples/hono/composite-routes-with-tags-split/src/endpoints/validator.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/createPets.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/listPets.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/showPetById.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/updatePets.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/petstore.validator.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/createPets.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/listPets.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/showPetById.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/updatePets.tssamples/hono/hono-with-fetch-client/hono-app/src/petstore.validator.tssamples/hono/hono-with-zod/__snapshots__/petstore.validator.tssamples/hono/hono-with-zod/src/petstore.validator.tstests/__snapshots__/hono/endpoint-parameters/endpoints.validator.tstests/__snapshots__/hono/petstore-single/endpoints.validator.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.validator.tstests/__snapshots__/hono/petstore-split/endpoints.validator.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/endpoints.validator.tstests/__snapshots__/hono/petstore-tags-split/endpoints.validator.tstests/__snapshots__/hono/petstore-tags-with-handlers/endpoints.validator.tstests/__snapshots__/hono/petstore-tags/endpoints.validator.tstests/__snapshots__/hono/zod-schema-response/endpoints.validator.ts
✅ Files skipped from review due to trivial changes (8)
- samples/hono/hono-with-fetch-client/snapshots/hono-app/handlers/listPets.ts
- samples/hono/hono-with-fetch-client/snapshots/hono-app/handlers/createPets.ts
- samples/hono/hono-with-fetch-client/hono-app/src/handlers/createPets.ts
- samples/hono/hono-with-fetch-client/hono-app/src/handlers/updatePets.ts
- samples/hono/hono-with-fetch-client/snapshots/hono-app/handlers/updatePets.ts
- samples/hono/hono-with-fetch-client/hono-app/src/handlers/showPetById.ts
- samples/hono/hono-with-fetch-client/hono-app/src/handlers/listPets.ts
- samples/hono/hono-with-fetch-client/snapshots/hono-app/handlers/showPetById.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/hono/src/index.test.ts
|
@snebjorn |
763007a to
d7cb16a
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
packages/hono/src/index.ts (2)
522-529:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
isRegexContextstill misclassifies regex literals after keywords.The check
!/[\w)\]]/.test(c)rejects any preceding word char, soreturn /…/,throw /…/,yield /…/,await /…/,case /…/are all treated as division. When such a regex contains)or}(e.g.return /[)]/.test(x)orreturn /\}+/.exec(s)),findMatchingClosethen mis-counts depth and the body extraction terminates inside the regex literal — corrupting or dropping the preserved body.When walking back hits an identifier char, scan the whole token and treat the slash as a regex when the token is one of
return | throw | yield | await | case | new | typeof | void | delete | in | of | instanceof(and handle the...spread case for.).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/hono/src/index.ts` around lines 522 - 529, isRegexContext currently treats any preceding identifier char as division; update isRegexContext to, when walking back finds an identifier-char (/[A-Za-z0-9_$]/), scan to extract the full preceding token (including handling a leading "..." for spread when encountering '.'), then treat the slash as a regex literal only if that token is one of the keywords: return, throw, yield, await, case, new, typeof, void, delete, in, of, instanceof; keep the existing whitespace-skipping and punctuation logic for non-identifier chars so ) ] etc still mark division; ensure the function references the same name isRegexContext and adjust the slashIdx/backward-scan logic so returning true/false reflects this token-check.
537-549:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftBody extraction still drops handlers that contain nested arrow functions.
lastIndexOf('=>')(Line 538) scans the entirecallBodyand picks up any user-authored arrow inside the handler —arr.map(x => x),arr.filter(x => x.id), even type positions likeArray<() => void>. When the picked=>is not followed by{, Line 543 returnsundefinedand the user's body is silently dropped during regeneration. Arrow callbacks are extremely common in handler bodies, so this is reachable in normal usage.Locate the trailing async arrow argument by walking the top-level argument list with the existing lex-aware scanner (skipping strings/comments/regex and nested parens/braces) instead of a raw
lastIndexOf('=>').🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/hono/src/index.ts` around lines 537 - 549, The extractAsyncArrowBody currently uses lastIndexOf('=>') which can pick up nested arrow callbacks; change extractAsyncArrowBody to scan the callBody from the start and walk the top-level function argument list using the existing lex-aware scanner (the same token-skipping logic used elsewhere) so you only consider arrows at top-level argument positions, skipping strings, comments, regexes and nested parens/braces; when you find a top-level '=>' ensure the next non-whitespace char is '{', use findMatchingClose(i, '{','}') to get the block end, and return the slice between braces; keep existing fallback behavior (return undefined) when no top-level async arrow block is found.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/hono/src/index.test.ts`:
- Around line 32-62: Add two new test cases to cover edge cases missed by the
current tests in the index.test.ts file: one that verifies extraction works
correctly with nested arrow functions inside the handler body (e.g., using
pets.map(p => p.id)) and another that ensures regex literals appearing
immediately after keywords like return are properly handled (e.g., return
/[)]/.test(...)). These tests should be added alongside existing ones using
extractExistingHandlerBodies and verify the returned body includes the nested
arrow and regex expressions as expected.
---
Duplicate comments:
In `@packages/hono/src/index.ts`:
- Around line 522-529: isRegexContext currently treats any preceding identifier
char as division; update isRegexContext to, when walking back finds an
identifier-char (/[A-Za-z0-9_$]/), scan to extract the full preceding token
(including handling a leading "..." for spread when encountering '.'), then
treat the slash as a regex literal only if that token is one of the keywords:
return, throw, yield, await, case, new, typeof, void, delete, in, of,
instanceof; keep the existing whitespace-skipping and punctuation logic for
non-identifier chars so ) ] etc still mark division; ensure the function
references the same name isRegexContext and adjust the slashIdx/backward-scan
logic so returning true/false reflects this token-check.
- Around line 537-549: The extractAsyncArrowBody currently uses
lastIndexOf('=>') which can pick up nested arrow callbacks; change
extractAsyncArrowBody to scan the callBody from the start and walk the top-level
function argument list using the existing lex-aware scanner (the same
token-skipping logic used elsewhere) so you only consider arrows at top-level
argument positions, skipping strings, comments, regexes and nested
parens/braces; when you find a top-level '=>' ensure the next non-whitespace
char is '{', use findMatchingClose(i, '{','}') to get the block end, and return
the slice between braces; keep existing fallback behavior (return undefined)
when no top-level async arrow block is found.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cce320d3-7d13-42c5-b8d2-ad009f3499d6
📒 Files selected for processing (5)
docs/content/docs/guides/hono.mdxpackages/hono/src/index.test.tspackages/hono/src/index.tspackages/hono/src/zValidator.tssamples/hono/composite-routes-with-tags-split/__snapshots__/endpoints/validator.ts
✅ Files skipped from review due to trivial changes (1)
- docs/content/docs/guides/hono.mdx
melloware
left a comment
There was a problem hiding this comment.
Looks like this PR needs to be updated from main
d7cb16a to
cc59b57
Compare
…rval-labs#2989) The hono client emitted a stale handler file once it existed: imports were never updated, so a wrong path baked in by an earlier generation (or by a config change) stuck around forever. The path computation itself also fell through to the tags-split layout for split/single modes, producing imports like `../pets/pets.context` when modules actually live at `../endpoints.context`. - Always re-emit the file header, imports, and `const factory = createFactory();` preamble on regeneration so config changes propagate to existing files. - Preserve the body of each `factory.createHandlers(...)` block verbatim via a paren-aware extractor so user business logic survives across regenerations. - Branch zod/context module resolution by mode (tags / tags-split / split|single) so each layout matches what generateZodFiles and generateContextFiles emit. - Fix getHonoHeader's per-tag join so `tags` (flat) imports resolve relative to targetInfo.dirname instead of a non-existent tag sub-directory.
…plit (orval-labs#2989) Adds three regression snapshot fixtures driven by the override.hono.handlers option (one per mode) plus unit tests for extractExistingHandlers covering nested parens in user-edited bodies and empty inputs.
…h fix (orval-labs#2989) The hono-with-zod and hono-with-fetch-client samples shipped the broken output documented in the issue (e.g. `../pets/pets.context` in split mode). Re-running orval with the fix produces the corrected imports and the orval file header, so the committed sample files and their snapshots are updated to match.
…response hook (orval-labs#2989) Two CodeRabbit findings on the previous preservation implementation: 1. Reusing the entire previous `factory.createHandlers(...)` block let stale `zValidator(...)` calls survive across regenerations even though their imports were rewritten — the visible failure was camelCase identifiers (e.g. `createPetsBody`) referencing PascalCase imports (`CreatePetsBody`). Now we extract only the user-authored async body and always rebuild the wrapper and validator chain from current verb metadata. 2. The naive paren-counting extractor terminated on any `)` character, so handler bodies containing `)` inside strings/templates/regex/comments produced invalid TypeScript. Replaced with a lex-aware scanner that skips strings, template literals, regex literals, and both line and block comments while tracking parenthesis/brace depth. Also returns early in the generated zValidator wrper after a hook supplies a `Response` so the custom body is no longer overwritten by the default success/failure branch.
…tor (orval-labs#2989) Re-running orval propagates the body-only preservation change and the zValidator hook early-return into the committed sample handlers and the generated validator middleware across every hono snapshot fixture.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
packages/hono/src/index.ts (2)
522-527:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
isRegexContextmisclassifies keyword-led regex literals.At Line 522, the one-character lookback treats
return /[)]/.test(x)as division. That lets)inside regex literals affect bracket depth infindMatchingClose, which can truncate preserved handler code.🛠️ Proposed fix
+const REGEX_PREFIX_KEYWORDS = new Set([ + 'return', + 'throw', + 'yield', + 'await', + 'case', +]); + const isRegexContext = (source: string, slashIdx: number): boolean => { for (let j = slashIdx - 1; j >= 0; j--) { const c = source[j]; if (c === ' ' || c === '\t' || c === '\n') continue; - return !/[\w)\]]/.test(c); + if (c === '.') { + return source.slice(Math.max(0, j - 2), j + 1) === '...'; + } + if (/[A-Za-z0-9_$]/.test(c)) { + let start = j; + while (start - 1 >= 0 && /[A-Za-z0-9_$]/.test(source[start - 1])) { + start--; + } + const token = source.slice(start, j + 1); + return REGEX_PREFIX_KEYWORDS.has(token); + } + return !/[)\]}]/.test(c); } return true; };#!/bin/bash python - <<'PY' import re def is_regex_context(source, slash_idx): for j in range(slash_idx - 1, -1, -1): c = source[j] if c in " \t\n": continue return not re.search(r'[\w)\]]', c) return True cases = [ ("return /[)]/.test(x)", True), ("throw /[)]/.test(x)", True), ("const re = /[)]/", True), ("value / 2", False), ] for src, expected in cases: actual = is_regex_context(src, src.index('/')) print(f"{src!r} -> {actual} (expected {expected})") PY
537-543:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
extractAsyncArrowBodydrops bodies containing nested arrows.At Line 538,
lastIndexOf('=>')can lock onto inner arrows (e.g.,items.map((p) => p.id)), so Line 543 misses the outer{...}and returnsundefined. That silently loses user handler bodies on regeneration.🛠️ Proposed fix
const extractAsyncArrowBody = (callBody: string): string | undefined => { - const arrowIdx = callBody.lastIndexOf('=>'); + // Parse the last top-level argument of createHandlers(...) first, + // then find the outer async arrow inside that argument. + const handlerArg = getLastTopLevelArgument(callBody); + const arrowIdx = handlerArg.indexOf('=>'); if (arrowIdx === -1) return undefined; let i = arrowIdx + 2; - while (i < callBody.length && /\s/.test(callBody[i])) i++; - if (callBody[i] !== '{') return undefined; + while (i < handlerArg.length && /\s/.test(handlerArg[i])) i++; + if (handlerArg[i] !== '{') return undefined; - const closeIdx = findMatchingClose(callBody, i, '{', '}'); + const closeIdx = findMatchingClose(handlerArg, i, '{', '}'); if (closeIdx === -1) return undefined; - return callBody.slice(i + 1, closeIdx); + return handlerArg.slice(i + 1, closeIdx); };#!/bin/bash python - <<'PY' def extract_async_arrow_body(call_body): arrow_idx = call_body.rfind("=>") if arrow_idx == -1: return None i = arrow_idx + 2 while i < len(call_body) and call_body[i].isspace(): i += 1 if i >= len(call_body) or call_body[i] != "{": return None return "BODY_FOUND" samples = [ "zValidator('json', S), async (c: Ctx) => { return c.json([]); }", "zValidator('json', S), async (c: Ctx) => { const ids = pets.map((p) => p.id); return c.json(ids); }", ] for s in samples: print(extract_async_arrow_body(s)) PY🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/hono/src/index.ts` around lines 537 - 543, The function extractAsyncArrowBody currently uses lastIndexOf('=>') which can match inner arrow functions; change the logic to scan all occurrences of '=>' in callBody (e.g., loop from start using indexOf('=>', fromPos)) and choose the rightmost occurrence whose following non-whitespace character is '{' (ensure you check i < callBody.length before accessing callBody[i]); update extractAsyncArrowBody to return the block body for that occurrence and skip any '=>' whose following char is not '{' so nested non-block arrows (like items.map((p) => p.id)) are ignored.
🧹 Nitpick comments (1)
docs/content/docs/guides/hono.mdx (1)
64-70: 💤 Low valueOptional: example identifiers no longer match generated output.
The example block still references
listPetsQueryParams/listPetsResponse(camelCase) at Lines 64 and 69-70 (and again at Lines 88-89), but the regenerated handlers in this PR now import PascalCaseListPetsQueryParams/ListPetsResponsefrompetstore.zod(seesamples/hono/hono-with-fetch-client/hono-app/src/handlers/listPets.tsLine 10). Worth refreshing the snippet so the docs match whatorvalactually emits.📝 Proposed doc update
-import { listPetsQueryParams, listPetsResponse } from '../petstore.zod'; +import { ListPetsQueryParams, ListPetsResponse } from '../petstore.zod'; const factory = createFactory(); export const listPetsHandlers = factory.createHandlers( - zValidator('query', listPetsQueryParams), - zValidator('response', listPetsResponse), + zValidator('query', ListPetsQueryParams), + zValidator('response', ListPetsResponse), async (c: ListPetsContext) => {…and the same rename in the second snippet around Lines 88-89.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/content/docs/guides/hono.mdx` around lines 64 - 70, The docs import and handler examples reference old camelCase identifiers listPetsQueryParams and listPetsResponse but the generated code now exports PascalCase names ListPetsQueryParams and ListPetsResponse; update the import and usages in the example(s) (the top import and the factory.createHandlers call that uses zValidator('query', ...) and zValidator('response', ...)) to use ListPetsQueryParams and ListPetsResponse so the snippet matches the actual output from petstore.zod and the samples/hono handler file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/__snapshots__/hono/petstore-tags-with-handlers/endpoints.validator.ts`:
- Around line 157-159: The validator currently always calls the v3 instance
method (schema as v3.ZodType).safeParseAsync(value), which breaks for v4 core
schemas that require the top-level v4.safeParseAsync(schema, value); update the
code to detect whether the provided schema is a v4 core schema (or otherwise
lacks the instance safeParseAsync) and, if so, call v4.safeParseAsync(schema,
value), otherwise retain the existing (schema as
v3.ZodType).safeParseAsync(value) call and keep the returned shape as
ZodSafeParseResult<InferredValue, Out, T>.
In
`@tests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/listPets.ts`:
- Around line 8-15: The handler only validates query params but misses the
generated header schema; update the createHandlers call for listPetsHandlers to
include the header validator by passing zValidator('header', ListPetsHeader)
(alongside the existing zValidator('query', ListPetsQueryParams)) so the
X-EXAMPLE header is validated and mapped into the request context type used by
ListPetsContext; ensure the validators are passed before the async handler in
the factory.createHandlers invocation.
---
Duplicate comments:
In `@packages/hono/src/index.ts`:
- Around line 537-543: The function extractAsyncArrowBody currently uses
lastIndexOf('=>') which can match inner arrow functions; change the logic to
scan all occurrences of '=>' in callBody (e.g., loop from start using
indexOf('=>', fromPos)) and choose the rightmost occurrence whose following
non-whitespace character is '{' (ensure you check i < callBody.length before
accessing callBody[i]); update extractAsyncArrowBody to return the block body
for that occurrence and skip any '=>' whose following char is not '{' so nested
non-block arrows (like items.map((p) => p.id)) are ignored.
---
Nitpick comments:
In `@docs/content/docs/guides/hono.mdx`:
- Around line 64-70: The docs import and handler examples reference old
camelCase identifiers listPetsQueryParams and listPetsResponse but the generated
code now exports PascalCase names ListPetsQueryParams and ListPetsResponse;
update the import and usages in the example(s) (the top import and the
factory.createHandlers call that uses zValidator('query', ...) and
zValidator('response', ...)) to use ListPetsQueryParams and ListPetsResponse so
the snippet matches the actual output from petstore.zod and the samples/hono
handler file.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a4ba7bff-e46b-49c9-aea2-e3a6279b2d74
📒 Files selected for processing (70)
docs/content/docs/guides/hono.mdxpackages/hono/src/index.test.tspackages/hono/src/index.tspackages/hono/src/zValidator.tssamples/hono/composite-routes-with-tags-split/__snapshots__/endpoints/validator.tssamples/hono/composite-routes-with-tags-split/src/endpoints/validator.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/createPets.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/listPets.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/showPetById.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/handlers/updatePets.tssamples/hono/hono-with-fetch-client/__snapshots__/hono-app/petstore.validator.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/createPets.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/listPets.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/showPetById.tssamples/hono/hono-with-fetch-client/hono-app/src/handlers/updatePets.tssamples/hono/hono-with-fetch-client/hono-app/src/petstore.validator.tssamples/hono/hono-with-zod/__snapshots__/handlers/createPets.tssamples/hono/hono-with-zod/__snapshots__/handlers/listPets.tssamples/hono/hono-with-zod/__snapshots__/handlers/showPetById.tssamples/hono/hono-with-zod/__snapshots__/handlers/updatePets.tssamples/hono/hono-with-zod/__snapshots__/petstore.validator.tssamples/hono/hono-with-zod/src/handlers/createPets.tssamples/hono/hono-with-zod/src/handlers/listPets.tssamples/hono/hono-with-zod/src/handlers/showPetById.tssamples/hono/hono-with-zod/src/handlers/updatePets.tssamples/hono/hono-with-zod/src/petstore.validator.tstests/__snapshots__/hono/endpoint-parameters/endpoints.validator.tstests/__snapshots__/hono/petstore-single/endpoints.validator.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.context.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.schemas.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.validator.tstests/__snapshots__/hono/petstore-split-with-handlers/endpoints.zod.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/createPets.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/deletePetById.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/healthCheck.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/listPets.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/showPetById.tstests/__snapshots__/hono/petstore-split-with-handlers/src/handlers/showPetWithOwner.tstests/__snapshots__/hono/petstore-split/endpoints.validator.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/endpoints.schemas.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/endpoints.validator.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/health/health.context.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/health/health.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/pets/pets.context.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/pets/pets.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/pets/pets.zod.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/createPets.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/deletePetById.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/healthCheck.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/listPets.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/showPetById.tstests/__snapshots__/hono/petstore-tags-split-with-handlers/src/handlers/showPetWithOwner.tstests/__snapshots__/hono/petstore-tags-split/endpoints.validator.tstests/__snapshots__/hono/petstore-tags-with-handlers/endpoints.schemas.tstests/__snapshots__/hono/petstore-tags-with-handlers/endpoints.validator.tstests/__snapshots__/hono/petstore-tags-with-handlers/health.context.tstests/__snapshots__/hono/petstore-tags-with-handlers/health.tstests/__snapshots__/hono/petstore-tags-with-handlers/pets.context.tstests/__snapshots__/hono/petstore-tags-with-handlers/pets.tstests/__snapshots__/hono/petstore-tags-with-handlers/pets.zod.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/createPets.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/deletePetById.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/healthCheck.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/listPets.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/showPetById.tstests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/showPetWithOwner.tstests/__snapshots__/hono/petstore-tags/endpoints.validator.tstests/__snapshots__/hono/zod-schema-response/endpoints.validator.tstests/configs/hono.config.ts
✅ Files skipped from review due to trivial changes (1)
- tests/snapshots/hono/petstore-tags-split-with-handlers/src/handlers/showPetById.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- tests/snapshots/hono/petstore-split-with-handlers/endpoints.context.ts
- tests/snapshots/hono/petstore-tags-split-with-handlers/health/health.ts
- tests/snapshots/hono/petstore-tags-split-with-handlers/src/handlers/createPets.ts
- tests/snapshots/hono/petstore-tags-split-with-handlers/endpoints.schemas.ts
- tests/snapshots/hono/petstore-tags-split/endpoints.validator.ts
- tests/snapshots/hono/petstore-tags-with-handlers/health.ts
| const { success, data, error } = (await ( | ||
| schema as v3.ZodType | ||
| ).safeParseAsync(value)) as ZodSafeParseResult<InferredValue, Out, T>; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n tests/__snapshots__/hono/petstore-tags-with-handlers/endpoints.validator.ts | head -200Repository: orval-labs/orval
Length of output: 6802
🌐 Web query:
Zod v4 core API safeParseAsync top-level function vs instance method
💡 Result:
In Zod v4, there is no top-level safeParseAsync function on the main z object. The safeParseAsync method is available as an instance method on schema objects (e.g., schema.safeParseAsync(data)), identical to Zod v3 and continuing in the full Zod package.[1][2][3][4] However, in the new zod/v4/core sub-package (the foundational core API shared between full Zod and Zod Mini), parsing functions including safeParseAsync are provided as top-level functions that take a schema instance as the first argument: z.safeParseAsync(schema, data).[5][4][6] This design accommodates the core's schema classes, which lack instance methods, requiring top-level functions for parsing.[4] In the full Zod and Zod Mini packages, schema instances retain instance methods like safeParseAsync for convenience and backward compatibility.[7][8][9] Example from core: import * as z from 'zod/v4/core'; const schema = new z.$ZodString({ type: 'string' }); await z.safeParseAsync(schema, 'hello');[4] Example from full Zod: import { z } from 'zod'; const schema = z.string; await schema.safeParseAsync('hello');[1][3]
Citations:
- 1: https://zod.dev/?id=safeparseasync
- 2: https://zod.dev/basics
- 3: https://tessl.io/registry/tessl/npm-zod/4.1.1/docs/parsing.md
- 4: https://v4.zod.dev/packages/core?id=parsing
- 5: https://github.com/colinhacks/zod/blob/c7805073/packages/zod/src/v4/classic/parse.ts
- 6: https://github.com/colinhacks/zod/blob/main/packages/zod/src/v4/classic/parse.ts
- 7: https://zod.dev/v4
- 8: https://www.zod.dev/v4?id=an-extensible-foundation-zodv4core
- 9: https://www.zod.dev/v4?id=65x-faster-object-parsing
🏁 Script executed:
# Let's check if there are any usage examples or tests that show actual v4 core schema usage
rg "v4\.\$ZodType|v4\.safeParseAsync" tests/ -A 3 -B 3Repository: orval-labs/orval
Length of output: 42
🏁 Script executed:
# Check if there are any conditions or runtime checks that handle v4 differently
rg "safeParseAsync" tests/__snapshots__/hono/petstore-tags-with-handlers/ -B 5 -A 5Repository: orval-labs/orval
Length of output: 1147
Use the Zod v4 core parse helper for v4 schemas.
This validator accepts v4.$ZodType, but lines 157-159 unconditionally use the v3 instance API. Zod v4 core schemas lack instance methods and require the top-level v4.safeParseAsync(schema, value) function. A v4 core schema will type-check but fail at runtime when validating responses.
Suggested fix
- const { success, data, error } = (await (
- schema as v3.ZodType
- ).safeParseAsync(value)) as ZodSafeParseResult<InferredValue, Out, T>;
+ const parseResult =
+ 'safeParseAsync' in schema
+ ? await schema.safeParseAsync(value)
+ : await v4.safeParseAsync(schema, value);
+
+ const { success, data, error } =
+ parseResult as ZodSafeParseResult<InferredValue, Out, T>;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const { success, data, error } = (await ( | |
| schema as v3.ZodType | |
| ).safeParseAsync(value)) as ZodSafeParseResult<InferredValue, Out, T>; | |
| const parseResult = | |
| 'safeParseAsync' in schema | |
| ? await schema.safeParseAsync(value) | |
| : await v4.safeParseAsync(schema, value); | |
| const { success, data, error } = | |
| parseResult as ZodSafeParseResult<InferredValue, Out, T>; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/__snapshots__/hono/petstore-tags-with-handlers/endpoints.validator.ts`
around lines 157 - 159, The validator currently always calls the v3 instance
method (schema as v3.ZodType).safeParseAsync(value), which breaks for v4 core
schemas that require the top-level v4.safeParseAsync(schema, value); update the
code to detect whether the provided schema is a v4 core schema (or otherwise
lacks the instance safeParseAsync) and, if so, call v4.safeParseAsync(schema,
value), otherwise retain the existing (schema as
v3.ZodType).safeParseAsync(value) call and keep the returned shape as
ZodSafeParseResult<InferredValue, Out, T>.
| import { zValidator } from '../../endpoints.validator'; | ||
| import { ListPetsContext } from '../../pets.context'; | ||
| import { ListPetsQueryParams } from '../../pets.zod'; | ||
|
|
||
| const factory = createFactory(); | ||
| export const listPetsHandlers = factory.createHandlers( | ||
| zValidator('query', ListPetsQueryParams), | ||
| async (c: ListPetsContext) => {}, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find tests/__snapshots__/hono/petstore-tags-with-handlers -type f -name "*.ts" | head -20Repository: orval-labs/orval
Length of output: 1028
🏁 Script executed:
find tests/__snapshots__/hono/petstore-tags-with-handlers -type f -name "pets.*" | head -20Repository: orval-labs/orval
Length of output: 255
🏁 Script executed:
cat tests/__snapshots__/hono/petstore-tags-with-handlers/pets.zod.tsRepository: orval-labs/orval
Length of output: 4369
🏁 Script executed:
cat tests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/listPets.tsRepository: orval-labs/orval
Length of output: 559
🏁 Script executed:
cat tests/__snapshots__/hono/petstore-tags-with-handlers/pets.context.tsRepository: orval-labs/orval
Length of output: 1366
🏁 Script executed:
cat tests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/createPets.tsRepository: orval-labs/orval
Length of output: 696
🏁 Script executed:
cat tests/__snapshots__/hono/petstore-tags-with-handlers/endpoints.schemas.ts | head -100Repository: orval-labs/orval
Length of output: 2009
Wire the generated header schema into this handler preamble.
pets.zod.ts exports ListPetsHeader, but this handler only validates the query string. That leaves the documented X-EXAMPLE header unenforced at runtime and unmapped in the context type, even though Hono supports header-target validators in the same middleware chain.
Suggested fix
import { createFactory } from 'hono/factory';
import { zValidator } from '../../endpoints.validator';
import { ListPetsContext } from '../../pets.context';
-import { ListPetsQueryParams } from '../../pets.zod';
+import { ListPetsHeader, ListPetsQueryParams } from '../../pets.zod';
const factory = createFactory();
export const listPetsHandlers = factory.createHandlers(
+ zValidator('header', ListPetsHeader),
zValidator('query', ListPetsQueryParams),
async (c: ListPetsContext) => {},
);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@tests/__snapshots__/hono/petstore-tags-with-handlers/src/handlers/listPets.ts`
around lines 8 - 15, The handler only validates query params but misses the
generated header schema; update the createHandlers call for listPetsHandlers to
include the header validator by passing zValidator('header', ListPetsHeader)
(alongside the existing zValidator('query', ListPetsQueryParams)) so the
X-EXAMPLE header is validated and mapped into the request context type used by
ListPetsContext; ensure the validators are passed before the async handler in
the factory.createHandlers invocation.
…y extraction (orval-labs#2989) Address two preservation edge cases flagged by CodeRabbit on extractExistingHandlerBodies: - isRegexContext now matches the preceding token against the keyword set that permits a regex literal (return, throw, yield, await, case, new, typeof, void, delete, in, of, instanceof) and the spread `...`. Previously a body like `return /[)]/.test(x)` was treated as division, so the bracket inside the regex character class corrupted depth tracking in findMatchingClose and the preserved body was truncated. - extractAsyncArrowBody walks the top-level argument list with the existing lex-aware scanner instead of `lastIndexOf('=>')`, so an inner arrow callback (e.g. `pets.map((p) => p.id)`) is no longer mistaken for the handler arrow and bodies containing nested arrows survive regeneration. Adds regression tests for both shapes.
cc59b57 to
1e50a78
Compare
|
uh how do i prevent orval from eating the imports my handler implementations need to function |
|
@xandris might have to do some analysis and submit a PR? |
|
@melloware @xandris gonna work on this because this pr make for me hono unusable I cannot add import or custom middleware I will do add a feature with multiple mode like full handled like now, skip completly when file already exist and a smart mode that try to fix the stuff that the generator need |
|
@anymaniax sounds good! |
Summary
Closes #2989.
Two bugs caused generated Hono handler files to drift out of sync with the rest of the output:
override.hono.handlerswas set, the zod/context module paths used thetags-splitlayout (dirname/tag/tag.zod) for every non-tagsmode. Insplit/singlemodes the generated imports therefore pointed at../<tag>/<tag>.context, whilegenerateContextFilesactually emitted../<filename>.context.getHonoHeaderhad the symmetrical mistake fortagsmode, joining a tag sub-directory that does not exist on disk.This PR splits path resolution by mode (
tags/tags-split/ split-or-single) so it mirrors wheregenerateZodFilesandgenerateContextFilesactually write, and rewrites the existing-file branch to always regenerate the file header, imports, andconst factory = createFactory();preamble while preserving eachfactory.createHandlers(...)body verbatim via a paren-aware extractor. New handlers are appended at the end as before.Changes
packages/hono/src/index.ts: per-modezodModule/contextModuleresolution inside theoverride.hono.handlersbranch; correctedgetHonoHeaderper-tag join (onlytags-splitjoins a sub-directory);generateHandlerFilenow refreshes preamble and preserves bodies via a new exportedextractExistingHandlershelper.packages/hono/src/index.test.ts: unit tests forextractExistingHandlers(multi-handler files, nested parens in user-edited bodies, empty input).tests/configs/hono.config.ts: three new regression fixtures exercisingoverride.hono.handlerswithmode: 'split',mode: 'tags', andmode: 'tags-split'.docs/content/docs/guides/hono.mdx: brief note that re-running orval refreshes the preamble while preserving handler bodies.Test plan
bun vitest run— newextractExistingHandlerstests pass.bun run test:snapshots— 3776 snapshots pass, including the three newpetstore-*-with-handlersfixtures.bun run lintandbun run typecheck— clean.tests/scripts/typecheck-generated.mjs— all 15 generated clients (including the new hono fixtures) typecheck.clean: false. Imports get refreshed; the user-edited body is preserved verbatim.Summary by CodeRabbit
Bug Fixes
New Features
Tests
Documentation