diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3b9471f0e6..0b1c212329 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
## Version 25
+### v25.1.0
+
+- Ability to disable the depiction of the `HEAD` method:
+ - New option `hasHeadMethod` on the argument of `Documentation` and `Integration` constructors;
+ - Depicts the HEAD method for each Endpoint supporting the GET method;
+ - The option is enabled by default (the behaviour introduced in [v24.7.0](#v2470));
+ - The feature suggested by [@GreaterTamarack](https://github.com/GreaterTamarack).
+
### v25.0.0
- Supported Node.js versions: `^20.19.0 || ^22.12.0 || ^24.0.0`;
diff --git a/README.md b/README.md
index daf9af3275..59bef7ea17 100644
--- a/README.md
+++ b/README.md
@@ -84,6 +84,7 @@ Therefore, many basic tasks can be accomplished faster and easier, in particular
These people contributed to the improvement of the framework by reporting bugs, making changes and suggesting ideas:
+[
](https://github.com/GreaterTamarack)
[
](https://github.com/pepegc)
[
](https://github.com/MichaelHindley)
[
](https://github.com/zoton2)
diff --git a/express-zod-api/src/documentation.ts b/express-zod-api/src/documentation.ts
index fa395d19bb..987f82acc8 100644
--- a/express-zod-api/src/documentation.ts
+++ b/express-zod-api/src/documentation.ts
@@ -59,6 +59,11 @@ interface DocumentationParams {
descriptions?: Partial>;
/** @default true */
hasSummaryFromDescription?: boolean;
+ /**
+ * @desc Depict the HEAD method for each Endpoint supporting the GET method (feature of Express)
+ * @default true
+ * */
+ hasHeadMethod?: boolean;
/** @default inline */
composition?: "inline" | "components";
/**
@@ -149,6 +154,7 @@ export class Documentation extends OpenApiBuilder {
tags,
isHeader,
hasSummaryFromDescription = true,
+ hasHeadMethod = true,
composition = "inline",
}: DocumentationParams) {
super();
@@ -256,7 +262,7 @@ export class Documentation extends OpenApiBuilder {
};
walkRouting({
routing,
- onEndpoint: withHead(onEndpoint),
+ onEndpoint: hasHeadMethod ? withHead(onEndpoint) : onEndpoint,
});
if (tags) this.rootDoc.tags = depictTags(tags);
}
diff --git a/express-zod-api/src/integration.ts b/express-zod-api/src/integration.ts
index 2447bde556..6baa5e7adf 100644
--- a/express-zod-api/src/integration.ts
+++ b/express-zod-api/src/integration.ts
@@ -47,6 +47,11 @@ interface IntegrationParams {
* @default z.undefined()
* */
noContent?: z.ZodType;
+ /**
+ * @desc Depict the HEAD method for each Endpoint supporting the GET method (feature of Express)
+ * @default true
+ * */
+ hasHeadMethod?: boolean;
/**
* @desc Handling rules for your own branded schemas.
* @desc Keys: brands (recommended to use unique symbols).
@@ -90,6 +95,7 @@ export class Integration extends IntegrationBase {
subscriptionClassName = "Subscription",
serverUrl = "https://example.com",
noContent = z.undefined(),
+ hasHeadMethod = true,
}: IntegrationParams) {
super(serverUrl);
const commons = { makeAlias: this.#makeAlias.bind(this) };
@@ -148,7 +154,7 @@ export class Integration extends IntegrationBase {
};
walkRouting({
routing,
- onEndpoint: withHead(onEndpoint),
+ onEndpoint: hasHeadMethod ? withHead(onEndpoint) : onEndpoint,
});
this.#program.unshift(...this.#aliases.values());
this.#program.push(
diff --git a/express-zod-api/tests/__snapshots__/documentation.spec.ts.snap b/express-zod-api/tests/__snapshots__/documentation.spec.ts.snap
index ef43dbf30f..25ad042490 100644
--- a/express-zod-api/tests/__snapshots__/documentation.spec.ts.snap
+++ b/express-zod-api/tests/__snapshots__/documentation.spec.ts.snap
@@ -789,40 +789,6 @@ paths:
status: error
error:
message: Sample error message
- head:
- operationId: HeadV1GetSomething
- parameters:
- - name: array
- in: query
- required: true
- description: HEAD /v1/getSomething Parameter
- schema:
- minItems: 1
- maxItems: 3
- type: array
- items:
- type: integer
- exclusiveMinimum: 0
- maximum: 9007199254740991
- - name: unlimited
- in: query
- required: true
- description: HEAD /v1/getSomething Parameter
- schema:
- type: array
- items:
- type: boolean
- - name: transformer
- in: query
- required: true
- description: HEAD /v1/getSomething Parameter
- schema:
- type: string
- responses:
- "200":
- description: HEAD /v1/getSomething Positive response
- "400":
- description: HEAD /v1/getSomething Negative response
components:
schemas: {}
responses: {}
diff --git a/express-zod-api/tests/__snapshots__/integration.spec.ts.snap b/express-zod-api/tests/__snapshots__/integration.spec.ts.snap
index 51918b3dac..fd3c5e9668 100644
--- a/express-zod-api/tests/__snapshots__/integration.spec.ts.snap
+++ b/express-zod-api/tests/__snapshots__/integration.spec.ts.snap
@@ -66,6 +66,161 @@ export type Request = keyof Input;
"
`;
+exports[`Integration > Should support HEAD method by default 0 1`] = `
+"type SomeOf = T[keyof T];
+
+/** get /v1/path */
+type GetV1PathInput = {
+ some: string;
+};
+
+/** get /v1/path */
+type GetV1PathPositiveVariant1 = {
+ status: "success";
+ data: {};
+};
+
+/** get /v1/path */
+interface GetV1PathPositiveResponseVariants {
+ 200: GetV1PathPositiveVariant1;
+}
+
+/** get /v1/path */
+type GetV1PathNegativeVariant1 = {
+ status: "error";
+ error: {
+ message: string;
+ };
+};
+
+/** get /v1/path */
+interface GetV1PathNegativeResponseVariants {
+ 400: GetV1PathNegativeVariant1;
+}
+
+/** head /v1/path */
+type HeadV1PathInput = {
+ some: string;
+};
+
+/** head /v1/path */
+type HeadV1PathPositiveVariant1 = undefined;
+
+/** head /v1/path */
+interface HeadV1PathPositiveResponseVariants {
+ 200: HeadV1PathPositiveVariant1;
+}
+
+/** head /v1/path */
+type HeadV1PathNegativeVariant1 = undefined;
+
+/** head /v1/path */
+interface HeadV1PathNegativeResponseVariants {
+ 400: HeadV1PathNegativeVariant1;
+}
+
+export type Path = "/v1/path";
+
+export type Method = "get" | "post" | "put" | "delete" | "patch" | "head";
+
+export interface Input {
+ "get /v1/path": GetV1PathInput;
+ "head /v1/path": HeadV1PathInput;
+}
+
+export interface PositiveResponse {
+ "get /v1/path": SomeOf;
+ "head /v1/path": SomeOf;
+}
+
+export interface NegativeResponse {
+ "get /v1/path": SomeOf;
+ "head /v1/path": SomeOf;
+}
+
+export interface EncodedResponse {
+ "get /v1/path": GetV1PathPositiveResponseVariants &
+ GetV1PathNegativeResponseVariants;
+ "head /v1/path": HeadV1PathPositiveResponseVariants &
+ HeadV1PathNegativeResponseVariants;
+}
+
+export interface Response {
+ "get /v1/path":
+ | PositiveResponse["get /v1/path"]
+ | NegativeResponse["get /v1/path"];
+ "head /v1/path":
+ | PositiveResponse["head /v1/path"]
+ | NegativeResponse["head /v1/path"];
+}
+
+export type Request = keyof Input;
+"
+`;
+
+exports[`Integration > Should support HEAD method by default 1 1`] = `
+"type SomeOf = T[keyof T];
+
+/** get /v1/path */
+type GetV1PathInput = {
+ some: string;
+};
+
+/** get /v1/path */
+type GetV1PathPositiveVariant1 = {
+ status: "success";
+ data: {};
+};
+
+/** get /v1/path */
+interface GetV1PathPositiveResponseVariants {
+ 200: GetV1PathPositiveVariant1;
+}
+
+/** get /v1/path */
+type GetV1PathNegativeVariant1 = {
+ status: "error";
+ error: {
+ message: string;
+ };
+};
+
+/** get /v1/path */
+interface GetV1PathNegativeResponseVariants {
+ 400: GetV1PathNegativeVariant1;
+}
+
+export type Path = "/v1/path";
+
+export type Method = "get" | "post" | "put" | "delete" | "patch" | "head";
+
+export interface Input {
+ "get /v1/path": GetV1PathInput;
+}
+
+export interface PositiveResponse {
+ "get /v1/path": SomeOf;
+}
+
+export interface NegativeResponse {
+ "get /v1/path": SomeOf;
+}
+
+export interface EncodedResponse {
+ "get /v1/path": GetV1PathPositiveResponseVariants &
+ GetV1PathNegativeResponseVariants;
+}
+
+export interface Response {
+ "get /v1/path":
+ | PositiveResponse["get /v1/path"]
+ | NegativeResponse["get /v1/path"];
+}
+
+export type Request = keyof Input;
+"
+`;
+
exports[`Integration > Should support multiple response schemas depending on status code 1`] = `
"type SomeOf = T[keyof T];
diff --git a/express-zod-api/tests/documentation.spec.ts b/express-zod-api/tests/documentation.spec.ts
index 979afb038e..06b4e47f2a 100644
--- a/express-zod-api/tests/documentation.spec.ts
+++ b/express-zod-api/tests/documentation.spec.ts
@@ -52,6 +52,7 @@ describe("Documentation", () => {
const literalValue = "something" as const;
const spec = new Documentation({
config: sampleConfig,
+ hasHeadMethod: false,
routing: {
v1: {
getSomething: defaultEndpointsFactory.build({
diff --git a/express-zod-api/tests/integration.spec.ts b/express-zod-api/tests/integration.spec.ts
index 1a2bf304fc..eb44ed47c3 100644
--- a/express-zod-api/tests/integration.spec.ts
+++ b/express-zod-api/tests/integration.spec.ts
@@ -66,6 +66,25 @@ describe("Integration", () => {
expect(await client.printFormatted()).toMatchSnapshot();
});
+ test.each([undefined, false])(
+ "Should support HEAD method by default %#",
+ async (hasHeadMethod) => {
+ const client = new Integration({
+ hasHeadMethod,
+ variant: "types",
+ routing: {
+ v1: {
+ "get path": defaultEndpointsFactory.buildVoid({
+ input: z.object({ some: z.string() }),
+ handler: vi.fn(),
+ }),
+ },
+ },
+ });
+ expect(await client.printFormatted()).toMatchSnapshot();
+ },
+ );
+
test("Should support multiple response schemas depending on status code", async () => {
const factory = new EndpointsFactory(
new ResultHandler({