feat: enable cross-type constraint interpretation by default#1580
Merged
ernado merged 5 commits intoogen-go:mainfrom Nov 25, 2025
Merged
feat: enable cross-type constraint interpretation by default#1580ernado merged 5 commits intoogen-go:mainfrom
ernado merged 5 commits intoogen-go:mainfrom
Conversation
540df33 to
b37b7d0
Compare
Adds support for interpreting schema constraints that cross type boundaries, which is common in real-world vendor OpenAPI specs. When enabled (default), the parser and code generator correctly interpret: - pattern constraints on numeric types (validates string representation) - minimum/maximum constraints on string types (parses as number and validates) This feature is ON by default because these constraints represent the spec author's clear intent - they chose the correct types but used constraints from a different type. Rather than rejecting these specs, we interpret the constraints correctly. Key Changes: - Added AllowCrossTypeConstraints option (default: true) - Added --strict CLI flag to disable interpretation and reject cross-type constraints - Extended validation logic in validate package to support cross-type constraints - Added comprehensive test coverage for both modes Implementation Details: - Pattern on numbers: Formats number as string, validates against regex - Min/max on strings: Parses string as float64, validates numeric bounds - Uses pointer type (*bool) to distinguish unset from explicitly false - Full backward compatibility: existing behavior unchanged unless --strict used Fixes #5
…ction The RegexStrings() function was only collecting String.Regex and MapPattern, but the lenient-validation-mode feature added Pattern support to Int and Float validators. This caused regexMap to be undefined when generating code with pattern constraints on numeric types. This fix adds typ.Validators.Int.Pattern and typ.Validators.Float.Pattern to the list of regex patterns collected, ensuring regexMap is properly populated for all pattern validators. Fixes the error: ./oas_validators_gen.go:2673:21: cannot use regexMap[pattern] (map index expression of type *regexp.Regexp) as ogenregex.Regexp value in struct literal: *regexp.Regexp does not implement ogenregex.Regexp
Add comprehensive tests to ensure RegexStrings() collects regex patterns from all validator types (String.Regex, Int.Pattern, Float.Pattern, MapPattern). These tests prevent regression of the bug where Int.Pattern and Float.Pattern were not being collected, causing undefined regexMap errors when generating code with pattern constraints on numeric types. Tests cover: - Collection of all pattern types - Handling of nil patterns - Deduplication of duplicate patterns
Generated code updated to include cross-type constraint validation logic for patterns on numbers and min/max on strings.
69ba432 to
dcbb634
Compare
ernado
approved these changes
Nov 25, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Enables cross-type constraint interpretation by default, allowing ogen to generate code from real-world vendor specs that have minor OpenAPI violations (pattern on numbers, min/max on strings).
Fixes #5
Changes
--strictflag to disable interpretation (restore old behavior)allow_cross_type_constraints(default: true)API Example
Before: Generation fails
After: Interprets constraints and generates validation
Generated validator enforces numeric bounds on strings:
Why Interpretation > Ignoring
Originally considered silently ignoring invalid constraints. This implementation interprets them instead, preserving validation intent:
type: string, maximum: 1000→ validates string parses as number ≤ 1000type: number, pattern: '^\d+(\.\d{1,2})?$'→ validates at most 2 decimal placesSpec authors chose correct types but used wrong constraint keywords. Interpretation is objectively better than ignoring.
Why Default ON
Real-world vendor specs (Royal Mail, Hermes, others) have these constraints. Making interpretation the default means:
--strictavailable for pure JSON Schema complianceTesting
Implementation
Cross-type validation in 3 layers:
Clean separation of concerns, minimal performance impact, full backward compatibility.