Skip to content

Conversation

@RobinTail
Copy link
Owner

@RobinTail RobinTail commented Jul 13, 2025

Based on #2791

MUST NOT send content in the response

Findings in Express:

  • no need to set app.head() handler, it's automatically set for all app.get() ones:
  • No extra handling required for res.send() — it automatically sends Content-Length header instead of response body for requests having HEAD method:
  • For streams, Content-Length should not be set anyway because of Transfer-encoding: chunked, according to RFC:
  • HOWEVER, for HEAD it SHOULD be there:
    • The relevant nuance is described in [RFC 9110, Section 9.3.2. HEAD(https://datatracker.ietf.org/doc/html/rfc9110#section-9.3.2):
    • The server SHOULD send the same header fields in response to a HEAD request as it would have sent if the request had been a GET, except that the payload header fields (Section 6.4) MAY be omitted. This includes sending headers such as Content-Length, even though there is no response body.

    • And in RFC 9110, Section 6.4.1. Content-Length:
    • A server MAY send a Content-Length header field in a response to a HEAD request (Section 9.3.2; see also Section 9.3.6), indicating the size of the payload body that would have been sent had the request been a GET.

    • This means that even if a GET response would use chunked encoding and omit Content-Length, the HEAD response can and should include Content-Length if the size is known.

Summary by CodeRabbit

  • New Features

    • Enhanced support for HTTP HEAD requests across multiple API endpoints with proper Content-Length headers and input handling.
    • API specification extended to include HEAD operations mirroring existing GET endpoints.
    • Client and server now fully recognize HEAD as a standard HTTP method with appropriate response and input processing.
    • Improved routing and documentation generation to incorporate HEAD methods alongside GET.
  • Bug Fixes

    • HEAD requests now correctly return headers without streaming content, ensuring compliance with HTTP standards.
  • Tests

    • Added comprehensive tests verifying HEAD request handling, response headers, and allowed methods across endpoints.
  • Documentation

    • Updated API documentation and CORS headers to include HEAD method support and accurate method listings.

@RobinTail RobinTail added the enhancement New feature or request label Jul 13, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 13, 2025

Walkthrough

The changes implement and test proper support for the HTTP HEAD method throughout the codebase. Adjustments include treating HEAD requests like GET for input extraction, ensuring HEAD is included in allowed methods and CORS headers, and handling HEAD requests correctly in file streaming endpoints by setting headers without sending the file body. Several new and updated tests verify this behavior.

Changes

Files/Groups Change Summary
example/factories.ts Updated file streaming handler to support asynchronous HEAD requests, set Content-Length, and skip file streaming.
example/index.spec.ts Added tests for HEAD requests to image endpoints, verifying headers and Content-Length.
example/example.client.ts, example/example.documentation.yaml Added support for HEAD method in client types, implementations, and OpenAPI docs for multiple endpoints.
express-zod-api/src/common-helpers.ts, tests/common-helpers.spec.ts Added getInputSources helper; modified getInput to treat HEAD like GET for input extraction; added test.
express-zod-api/src/method.ts, tests/method.spec.ts Expanded AuxMethod type to include "head"; added clientMethods array and ClientMethod type alias; updated tests.
express-zod-api/src/routing.ts, tests/routing.spec.ts, tests/system.spec.ts Added HEAD to allowed methods and CORS headers; updated method sorting to prioritize actual methods; updated tests.
express-zod-api/src/documentation-helpers.ts, express-zod-api/src/documentation.ts Replaced Method with ClientMethod type; updated method annotations; duplicated docs for HEAD corresponding to GET.
express-zod-api/src/endpoint.ts Changed getOperationId method signature to use ClientMethod instead of Method.
express-zod-api/src/endpoints-factory.ts Updated operationId type to use ClientMethod; adjusted operation ID generation to append __HEAD suffix for HEAD.
express-zod-api/src/integration-base.ts Replaced Method with ClientMethod; included HEAD in method lists and body presence checks.
express-zod-api/src/integration.ts Updated onEndpoint callback to use ClientMethod; duplicated "get" endpoints as "head" for processing; excluded content for HEAD positive responses.
express-zod-api/src/routing-walker.ts Added a generic OnEndpoint type; introduced withHead wrapper to invoke callbacks for HEAD methods alongside GET.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Server
    participant FileHandler

    Client->>Server: HEAD /file
    Server->>FileHandler: get file metadata
    FileHandler-->>Server: filename, size
    Server-->>Client: 200 OK + headers (Content-Type, Content-Length, etc.)
    Note right of Server: No file body is sent
Loading

Possibly related PRs

  • v24 is for Ashley Burton #2546: The main PR and this PR are the same, both describing the major v24 upgrade with explicit HTTP HEAD method support, documentation, and internal API refactoring.

Suggested labels

documentation, refactoring, breaking

Poem

🐇
HEAD requests now hop in line,
With GET they share their input sign.
No file streamed, just headers neat—
Content-Length makes tests complete!
CORS and Allow now list them too,
A tidy warren, through and through.
Hooray for HEAD, and code anew!


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between daa2da6 and 35134cd.

📒 Files selected for processing (2)
  • express-zod-api/src/method.ts (1 hunks)
  • express-zod-api/tests/method.spec.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • express-zod-api/src/method.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2697
File: CHANGELOG.md:5-5
Timestamp: 2025-06-02T21:11:20.768Z
Learning: In the express-zod-api repository, RobinTail follows a release workflow where package.json version is only updated on the master branch after merging all planned release changes. Changelog entries may show future version numbers while package.json remains at the previous version during feature development, and this is intentional workflow, not a version inconsistency that needs to be flagged.
express-zod-api/tests/method.spec.ts (9)
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2428
File: express-zod-api/src/index.ts:44-44
Timestamp: 2025-05-28T18:58:10.064Z
Learning: The type-only import `import type {} from "qs";` in express-zod-api/src/index.ts is necessary to avoid TS2742 errors for exported functions like attachRouting, makeRequestMock, testEndpoint, and testMiddleware that have types depending on @types/qs. This import provides the reference TypeScript needs to infer portable type names.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/zts.spec.ts:160-162
Timestamp: 2025-05-27T20:22:30.428Z
Learning: In express-zod-api/tests/zts.spec.ts, the `Fruits` enum intentionally contains both string and numeric members (Apple = "apple", Banana = "banana", Cantaloupe = "cantaloupe", A = 5) and is used with `z.enum(Fruits)` to test how the system handles mixed enum types. This is by design for testing purposes.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2736
File: express-zod-api/tsup.config.ts:12-26
Timestamp: 2025-06-14T16:42:52.972Z
Learning: In express-zod-api tsup configurations, the direct mutation of `options.supported` in the `esbuildOptions` callback is intentional behavior and should not be flagged as a side effect issue.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2697
File: CHANGELOG.md:5-5
Timestamp: 2025-06-02T21:08:56.475Z
Learning: The `cjs-test` directory in the express-zod-api repository is a test workspace and should be excluded when checking for main project version consistency with changelog entries.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/buffer-schema.spec.ts:32-37
Timestamp: 2025-05-27T19:35:57.357Z
Learning: In the express-zod-api project, tests are run from the `express-zod-api` workspace directory, and the project uses an ESM-first environment without `__dirname`. Relative paths like `../logo.svg` in test files correctly resolve to the repository root due to this test execution context.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/json-schema-helpers.ts:1-3
Timestamp: 2025-05-27T20:27:17.015Z
Learning: Ramda is correctly listed as a dependency in express-zod-api/package.json, so imports of ramda utilities are properly supported.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/json-schema-helpers.ts:1-3
Timestamp: 2025-05-27T20:27:17.015Z
Learning: Ramda is correctly listed as a dependency in express-zod-api/package.json, so imports of ramda utilities are properly supported.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/io-schema.ts:5-8
Timestamp: 2025-05-28T05:04:40.327Z
Learning: The Base type `object & { [Symbol.iterator]?: never }` in express-zod-api correctly excludes arrays and other iterables from IOSchema. Arrays are properly rejected because they have a defined Symbol.iterator method which conflicts with the never constraint, as demonstrated by TypeScript compiler errors when attempting to assign z.array() to IOSchema.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/json-schema-helpers.ts:75-87
Timestamp: 2025-05-27T20:40:19.548Z
Learning: In express-zod-api's `flattenIO` function in json-schema-helpers.ts, the `additionalProperties` field is used as a template to generate property schemas for literal property names extracted from `propertyNames.const` and `propertyNames.enum`. Converting boolean `additionalProperties` values to empty objects `{}` via `Object(entry.additionalProperties)` is intentional behavior, as the function only needs property schema templates, not the boolean semantics of `additionalProperties`.
🧬 Code Graph Analysis (1)
express-zod-api/tests/method.spec.ts (1)
express-zod-api/src/method.ts (3)
  • clientMethods (24-26)
  • ClientMethod (32-32)
  • AuxMethod (22-22)
🪛 GitHub Check: build (24.0.0)
express-zod-api/tests/method.spec.ts

[warning] 10-10:
use node:node:test for the built-in module

🪛 GitHub Check: build (24.x)
express-zod-api/tests/method.spec.ts

[warning] 10-10:
use node:node:test for the built-in module

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (4)
express-zod-api/tests/method.spec.ts (4)

2-10: LGTM! Import updates correctly reflect the new functionality.

The imports are properly updated to include the new clientMethods array and ClientMethod type. The explicit import of describe from node:test is also correct.

Note: The static analysis warning about "use node:node:test" appears to be a false positive - node:test is the correct import path for Node.js built-in test module.


19-30: Excellent test coverage for the new clientMethods array.

The test correctly verifies that clientMethods contains all standard HTTP methods plus the newly added "head" method. This aligns with the implementation in express-zod-api/src/method.ts where clientMethods is defined as [...methods, "head"].


43-53: Comprehensive type testing for ClientMethod.

The test thoroughly validates that the ClientMethod type includes all standard HTTP methods plus "head" while properly excluding invalid strings. This ensures type safety for the expanded method support.


56-59: Correctly updated to test expanded AuxMethod type.

The test now properly validates that AuxMethod includes both "options" and "head", reflecting the expanded type definition in the source code that supports HEAD method handling.

✨ 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coveralls-official
Copy link

coveralls-official bot commented Jul 13, 2025

Coverage Status

coverage: 100.0%. remained the same
when pulling 16e0520 on feat-method-head
into 6b78d2e on master.

@RobinTail
Copy link
Owner Author

RobinTail commented Jul 13, 2025

turned out that .head() handler is called automatically by Express when .get() is called.

@RobinTail RobinTail marked this pull request as ready for review July 14, 2025 21:19
@RobinTail
Copy link
Owner Author

Should somehow reflect head in Documentation and Integration

@RobinTail RobinTail changed the title feat: HEAD method feat: HEAD method handling Jul 15, 2025
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: 0

🧹 Nitpick comments (1)
example/example.client.ts (1)

189-206: Replace '{}' type with a more explicit empty object type.

The HEAD endpoint implementation is correct, but the input type uses '{}' which is discouraged. Consider using a more explicit type for empty objects.

Apply this diff to improve type safety:

-/** head /v1/user/list */
-type HeadV1UserListInput = {};
+/** head /v1/user/list */
+type HeadV1UserListInput = Record<string, never>;

Alternatively, you could define an explicit empty interface:

-/** head /v1/user/list */
-type HeadV1UserListInput = {};
+/** head /v1/user/list */
+interface HeadV1UserListInput {}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e74a0bf and 00ca5c0.

⛔ Files ignored due to path filters (2)
  • express-zod-api/tests/__snapshots__/documentation.spec.ts.snap is excluded by !**/*.snap
  • express-zod-api/tests/__snapshots__/integration.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (11)
  • example/example.client.ts (12 hunks)
  • example/example.documentation.yaml (5 hunks)
  • express-zod-api/src/common-helpers.ts (1 hunks)
  • express-zod-api/src/documentation-helpers.ts (3 hunks)
  • express-zod-api/src/documentation.ts (7 hunks)
  • express-zod-api/src/endpoint.ts (4 hunks)
  • express-zod-api/src/endpoints-factory.ts (3 hunks)
  • express-zod-api/src/integration-base.ts (5 hunks)
  • express-zod-api/src/integration.ts (4 hunks)
  • express-zod-api/src/method.ts (1 hunks)
  • express-zod-api/src/routing-walker.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • express-zod-api/src/routing-walker.ts
  • express-zod-api/src/documentation-helpers.ts
  • example/example.documentation.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • express-zod-api/src/method.ts
  • express-zod-api/src/common-helpers.ts
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2697
File: CHANGELOG.md:5-5
Timestamp: 2025-06-02T21:11:20.768Z
Learning: In the express-zod-api repository, RobinTail follows a release workflow where package.json version is only updated on the master branch after merging all planned release changes. Changelog entries may show future version numbers while package.json remains at the previous version during feature development, and this is intentional workflow, not a version inconsistency that needs to be flagged.
express-zod-api/src/endpoints-factory.ts (2)
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2428
File: express-zod-api/src/index.ts:44-44
Timestamp: 2025-05-28T18:58:10.064Z
Learning: The type-only import `import type {} from "qs";` in express-zod-api/src/index.ts is necessary to avoid TS2742 errors for exported functions like attachRouting, makeRequestMock, testEndpoint, and testMiddleware that have types depending on @types/qs. This import provides the reference TypeScript needs to infer portable type names.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2736
File: express-zod-api/tsup.config.ts:12-26
Timestamp: 2025-06-14T16:42:52.972Z
Learning: In express-zod-api tsup configurations, the direct mutation of `options.supported` in the `esbuildOptions` callback is intentional behavior and should not be flagged as a side effect issue.
express-zod-api/src/integration.ts (10)
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2428
File: express-zod-api/src/index.ts:44-44
Timestamp: 2025-05-28T18:58:10.064Z
Learning: The type-only import `import type {} from "qs";` in express-zod-api/src/index.ts is necessary to avoid TS2742 errors for exported functions like attachRouting, makeRequestMock, testEndpoint, and testMiddleware that have types depending on @types/qs. This import provides the reference TypeScript needs to infer portable type names.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2736
File: express-zod-api/tsup.config.ts:12-26
Timestamp: 2025-06-14T16:42:52.972Z
Learning: In express-zod-api tsup configurations, the direct mutation of `options.supported` in the `esbuildOptions` callback is intentional behavior and should not be flagged as a side effect issue.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: example/factories.ts:35-42
Timestamp: 2025-05-27T20:03:34.213Z
Learning: The `./example` directory in the express-zod-api repository contains demonstration code for educational purposes only, not intended for production use. Example code can make simplified assumptions for brevity and clarity, and should not be flagged for missing production-level error handling, security measures, or edge case handling.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/documentation-helpers.ts:508-512
Timestamp: 2025-05-28T07:58:09.853Z
Learning: In express-zod-api, when working with Zod's JSON schema override callbacks, using `delete` to mutate `ctx.jsonSchema` is the recommended approach per Zod's official documentation, even if it triggers performance linting warnings. This is preferable to creating copies with `undefined` values, especially for snapshot testing.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/json-schema-helpers.ts:1-3
Timestamp: 2025-05-27T20:27:17.015Z
Learning: Ramda is correctly listed as a dependency in express-zod-api/package.json, so imports of ramda utilities are properly supported.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/json-schema-helpers.ts:1-3
Timestamp: 2025-05-27T20:27:17.015Z
Learning: Ramda is correctly listed as a dependency in express-zod-api/package.json, so imports of ramda utilities are properly supported.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2697
File: CHANGELOG.md:5-5
Timestamp: 2025-06-02T21:08:56.475Z
Learning: The `cjs-test` directory in the express-zod-api repository is a test workspace and should be excluded when checking for main project version consistency with changelog entries.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/json-schema-helpers.ts:75-87
Timestamp: 2025-05-27T20:40:19.548Z
Learning: In express-zod-api's `flattenIO` function in json-schema-helpers.ts, the `additionalProperties` field is used as a template to generate property schemas for literal property names extracted from `propertyNames.const` and `propertyNames.enum`. Converting boolean `additionalProperties` values to empty objects `{}` via `Object(entry.additionalProperties)` is intentional behavior, as the function only needs property schema templates, not the boolean semantics of `additionalProperties`.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/form-schema.spec.ts:31-31
Timestamp: 2025-05-27T19:27:13.492Z
Learning: Zod version 3.25.0 and later expose the Zod v4 API through the special import paths "zod/v4" and "zod/v4/core", allowing v4 features like .loose() to be used even when the package.json dependency shows a 3.x version.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/buffer-schema.spec.ts:32-37
Timestamp: 2025-05-27T19:35:57.357Z
Learning: In the express-zod-api project, tests are run from the `express-zod-api` workspace directory, and the project uses an ESM-first environment without `__dirname`. Relative paths like `../logo.svg` in test files correctly resolve to the repository root due to this test execution context.
express-zod-api/src/integration-base.ts (4)
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2428
File: express-zod-api/src/index.ts:44-44
Timestamp: 2025-05-28T18:58:10.064Z
Learning: The type-only import `import type {} from "qs";` in express-zod-api/src/index.ts is necessary to avoid TS2742 errors for exported functions like attachRouting, makeRequestMock, testEndpoint, and testMiddleware that have types depending on @types/qs. This import provides the reference TypeScript needs to infer portable type names.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2736
File: express-zod-api/tsup.config.ts:12-26
Timestamp: 2025-06-14T16:42:52.972Z
Learning: In express-zod-api tsup configurations, the direct mutation of `options.supported` in the `esbuildOptions` callback is intentional behavior and should not be flagged as a side effect issue.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/form-schema.spec.ts:31-31
Timestamp: 2025-05-27T19:27:13.492Z
Learning: Zod version 3.25.0 and later expose the Zod v4 API through the special import paths "zod/v4" and "zod/v4/core", allowing v4 features like .loose() to be used even when the package.json dependency shows a 3.x version.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: example/factories.ts:35-42
Timestamp: 2025-05-27T20:03:34.213Z
Learning: The `./example` directory in the express-zod-api repository contains demonstration code for educational purposes only, not intended for production use. Example code can make simplified assumptions for brevity and clarity, and should not be flagged for missing production-level error handling, security measures, or edge case handling.
express-zod-api/src/endpoint.ts (3)
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2428
File: express-zod-api/src/index.ts:44-44
Timestamp: 2025-05-28T18:58:10.064Z
Learning: The type-only import `import type {} from "qs";` in express-zod-api/src/index.ts is necessary to avoid TS2742 errors for exported functions like attachRouting, makeRequestMock, testEndpoint, and testMiddleware that have types depending on @types/qs. This import provides the reference TypeScript needs to infer portable type names.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2736
File: express-zod-api/tsup.config.ts:12-26
Timestamp: 2025-06-14T16:42:52.972Z
Learning: In express-zod-api tsup configurations, the direct mutation of `options.supported` in the `esbuildOptions` callback is intentional behavior and should not be flagged as a side effect issue.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/buffer-schema.spec.ts:32-37
Timestamp: 2025-05-27T19:35:57.357Z
Learning: In the express-zod-api project, tests are run from the `express-zod-api` workspace directory, and the project uses an ESM-first environment without `__dirname`. Relative paths like `../logo.svg` in test files correctly resolve to the repository root due to this test execution context.
express-zod-api/src/documentation.ts (4)
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2428
File: express-zod-api/src/index.ts:44-44
Timestamp: 2025-05-28T18:58:10.064Z
Learning: The type-only import `import type {} from "qs";` in express-zod-api/src/index.ts is necessary to avoid TS2742 errors for exported functions like attachRouting, makeRequestMock, testEndpoint, and testMiddleware that have types depending on @types/qs. This import provides the reference TypeScript needs to infer portable type names.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2736
File: express-zod-api/tsup.config.ts:12-26
Timestamp: 2025-06-14T16:42:52.972Z
Learning: In express-zod-api tsup configurations, the direct mutation of `options.supported` in the `esbuildOptions` callback is intentional behavior and should not be flagged as a side effect issue.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/form-schema.spec.ts:31-31
Timestamp: 2025-05-27T19:27:13.492Z
Learning: Zod version 3.25.0 and later expose the Zod v4 API through the special import paths "zod/v4" and "zod/v4/core", allowing v4 features like .loose() to be used even when the package.json dependency shows a 3.x version.
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: example/factories.ts:35-42
Timestamp: 2025-05-27T20:03:34.213Z
Learning: The `./example` directory in the express-zod-api repository contains demonstration code for educational purposes only, not intended for production use. Example code can make simplified assumptions for brevity and clarity, and should not be flagged for missing production-level error handling, security measures, or edge case handling.
🧬 Code Graph Analysis (2)
express-zod-api/src/endpoints-factory.ts (1)
express-zod-api/src/method.ts (1)
  • ClientMethod (19-19)
express-zod-api/src/endpoint.ts (1)
express-zod-api/src/method.ts (1)
  • ClientMethod (19-19)
🪛 Biome (1.9.4)
example/example.client.ts

[error] 190-190: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: report
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (28)
express-zod-api/src/endpoints-factory.ts (3)

10-10: Import update looks good.

The addition of ClientMethod import is necessary to support the new HEAD method handling functionality.


48-48: Correct type update for operation ID.

Updating the operationId property to accept ClientMethod parameter aligns with the new HEAD method support and ensures consistent typing across the framework.


131-134: Well-implemented HEAD operation ID handling.

The logic correctly ensures unique operation IDs for HEAD methods by appending "__HEAD" suffix while preserving backward compatibility for other methods. This follows the non-breaking change principle mentioned in the comment.

express-zod-api/src/integration-base.ts (5)

5-5: Correct import update for HEAD method support.

Replacing Method and methods with ClientMethod and clientMethods properly supports the new HEAD method functionality.


99-99: Documentation updated to reflect HEAD method support.

The example comment correctly includes "head" in the list of supported methods.


102-102: Method type property correctly updated.

Using clientMethods instead of methods ensures the type includes the HEAD method.


419-421: Correct HEAD method handling in request body logic.

Adding "head" to the list of methods that don't have request bodies is correct according to HTTP specifications. HEAD requests, like GET and DELETE, should not include a request body.


629-629: Usage examples properly typed.

The usage statements correctly use ClientMethod type assertions for the example endpoints, maintaining type safety.

Also applies to: 638-638

express-zod-api/src/endpoint.ts (4)

26-26: Import update is correct.

Adding ClientMethod import supports the type updates for HEAD method handling.


57-57: Abstract method signature correctly updated.

Changing the parameter type from Method to ClientMethod aligns with the HEAD method support and maintains consistency across the framework.


108-108: Constructor parameter type correctly updated.

The getOperationId function parameter type change to ClientMethod maintains consistency with the abstract method signature.


197-197: Implementation method signature correctly updated.

The override method parameter type change to ClientMethod maintains consistency with the abstract method and constructor.

express-zod-api/src/integration.ts (5)

25-26: Import updates support HEAD method functionality.

Adding AbstractEndpoint and ClientMethod imports provides the necessary types for the HEAD method implementation.


99-103: Explicit typing improves code clarity.

The explicit parameter types for the onEndpoint callback enhance type safety and make the HEAD method support more apparent.


115-117: Correct HEAD method response handling.

The hasContent logic properly implements HTTP HEAD method specification by excluding response content for HEAD requests with positive responses, while preserving content for error responses.


120-120: Proper use of hasContent flag.

Using hasContent instead of just mimeTypes ensures HEAD responses are correctly handled as no-content responses.


156-162: Correct HEAD endpoint duplication strategy.

The approach of duplicating GET endpoints as HEAD endpoints aligns with HTTP specifications and Express.js behavior, where HEAD automatically handles GET routes.

express-zod-api/src/documentation.ts (6)

14-14: Import updates support HEAD method functionality.

The updated imports for getInputSources, ClientMethod, and AbstractEndpoint provide the necessary functionality for HEAD method documentation generation.

Also applies to: 17-17, 33-34


105-109: Method parameter type correctly updated.

Updating the #ensureUniqOperationId method to use ClientMethod maintains consistency with other parts of the framework.


159-163: Explicit callback typing improves clarity.

The explicit parameter types for the onEndpoint callback enhance type safety and make the HEAD method support clear.


178-178: Correct use of input sources helper.

Using getInputSources(method, config.inputSources) instead of direct config access ensures proper input source determination for different HTTP methods, including HEAD.


209-210: Correct HEAD response documentation.

Setting mimeTypes to null for HEAD method positive responses correctly implements the HTTP specification where HEAD responses should not include a response body.


263-269: Proper HEAD endpoint documentation strategy.

Duplicating GET endpoints as HEAD endpoints in the documentation aligns with the HTTP specification and ensures comprehensive API documentation.

example/example.client.ts (5)

42-67: HEAD method implementation looks correct.

The HEAD endpoint types properly mirror the GET endpoint with undefined positive response, which correctly follows HTTP HEAD specification where no response body should be sent.


451-451: Method union type correctly updated to include HEAD.

The addition of "head" to the Method union type is necessary and properly implemented to support the new HEAD endpoints.


455-624: Interface updates for HEAD method support are comprehensive and consistent.

All interfaces have been properly updated to include HEAD endpoints with correct type mappings. The HEAD endpoints correctly use undefined for positive responses and maintain appropriate error response types.


649-649: HEAD method correctly treated as bodyless request.

The update to include "head" in the bodyless methods array is correct. HEAD requests should be handled like GET requests - with parameters in the query string rather than request body.


229-248: Remaining HEAD endpoint definitions follow correct pattern.

All remaining HEAD endpoint type definitions consistently follow the proper HTTP HEAD specification with matching input parameters to their GET counterparts and undefined positive responses.

Also applies to: 271-290, 383-403

Copy link
Owner Author

@RobinTail RobinTail left a comment

Choose a reason for hiding this comment

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

ready

@RobinTail RobinTail merged commit b1762bf into master Jul 20, 2025
13 checks passed
@RobinTail RobinTail deleted the feat-method-head branch July 20, 2025 10:33
RobinTail added a commit that referenced this pull request Jul 20, 2025
Due to #2816 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Improved and unified type definitions for HTTP methods, enhancing
consistency and clarity in method handling across the application.
* Updated method handling logic to better support CORS and HTTP method
distinctions.

* **Tests**
  * Removed obsolete tests related to deprecated method types.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants