Skip to content

Conversation

@sentik
Copy link
Contributor

@sentik sentik commented Oct 28, 2025

Fix: Support for exclusiveMinimum and exclusiveMaximum in Zod schema generation

Fixes #2182

Problem

Currently, Orval's Zod client generates only basic primitives (z.number(), z.string(), etc.) and does not translate JSON Schema numeric constraints (minimum, exclusiveMinimum, maximum, exclusiveMaximum) into Zod refinements. This means numeric constraints declared in OpenAPI definitions are lost in the generated schemas, creating gaps between backend validation (e.g., Pydantic's gt=0) and frontend validation in libraries like React Hook Form.

Example:
Given an OpenAPI schema with exclusiveMinimum: 0, the current implementation generates:

export const BaseBidSchema = z.object({
  price: z.number(), // Missing .gt(0) constraint
});

Instead of:

export const BaseBidSchema = z.object({
  price: z.number().gt(0), // Correct exclusive constraint
});

Solution

Added support for both OpenAPI 3.0 and 3.1 formats:

  • OpenAPI 3.0: exclusiveMinimum and exclusiveMaximum are boolean flags indicating whether minimum/maximum should be exclusive
  • OpenAPI 3.1: exclusiveMinimum and exclusiveMaximum are numeric values themselves

The implementation automatically detects the format and generates the appropriate Zod constraints:

  • minimum: n.min(n) (inclusive)
  • exclusiveMinimum: n or exclusiveMinimum: true.gt(n) (exclusive)
  • maximum: n.max(n) (inclusive)
  • exclusiveMaximum: n or exclusiveMaximum: true.lt(n) (exclusive)

Changes

  1. Enhanced field extraction in generateZodValidationSchemaDefinition():

    • Extract exclusiveMinimum and exclusiveMaximum from schema
    • Handle both boolean (OpenAPI 3.0) and numeric (OpenAPI 3.1) formats
    • Convert boolean flags to numeric values when needed
  2. Updated constraint generation logic:

    • When exclusive minimum/maximum are present, generate .gt() and .lt() instead of .min() and .max()
    • Added comprehensive inline comments explaining the logic
  3. Comprehensive test coverage:

    • Created 6 new tests organized in two groups:
      • OpenAPI 3.1 format tests (numeric exclusiveMinimum/exclusiveMaximum)
      • OpenAPI 3.0 format tests (boolean exclusiveMinimum/exclusiveMaximum)
    • Each group covers: single exclusiveMinimum, single exclusiveMaximum, and both combined

@melloware melloware added the zod Zod related issue label Oct 28, 2025
@melloware
Copy link
Collaborator

Keep all these Zod fixes coming!

@melloware melloware merged commit 1da0c2d into orval-labs:master Oct 28, 2025
0 of 2 checks passed
zhu-hong pushed a commit to zhu-hong/orval that referenced this pull request Oct 29, 2025
melloware pushed a commit that referenced this pull request Oct 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

zod Zod related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Zod: Support JSON-Schema minimum/exclusiveMinimum → Zod .min()/.gt()

2 participants