Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
Warning Rate limit exceeded@unnoq has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 35 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (5)
WalkthroughThis update introduces comprehensive support for Zod version 4 (currently in beta) across the codebase. It adds a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Plugin as ZodSmartCoercionPlugin (v4)
participant ZodSchema
User->>Plugin: Provide input and Zod 4 schema
Plugin->>Plugin: Recursively coerce input based on schema type
Plugin->>ZodSchema: Check schema type and constraints
Plugin->>User: Return coerced input
sequenceDiagram
participant User
participant Converter as ZodToJsonSchemaConverter (v4)
participant ZodSchema
User->>Converter: Request JSON Schema for Zod 4 schema
Converter->>Converter: Recursively convert schema nodes
Converter->>ZodSchema: Read schema properties and metadata
Converter->>User: Return JSON Schema object
Assessment against linked issues
Possibly related PRs
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Codecov ReportAll modified and coverable lines are covered by tests ✅ 📢 Thoughts on this report? Let us know! |
More templates
@orpc/arktype
@orpc/client
@orpc/contract
@orpc/openapi
@orpc/openapi-client
@orpc/react
@orpc/server
@orpc/react-query
@orpc/shared
@orpc/solid-query
@orpc/standard-server
@orpc/standard-server-fetch
@orpc/standard-server-node
@orpc/svelte-query
@orpc/valibot
@orpc/vue-colada
@orpc/vue-query
@orpc/zod
commit: |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (15)
packages/zod/src/zod4/converter.rest.test.ts (1)
4-20: Add comments explaining conversion expectationsThe test structure is sound, but it would be helpful to add explanatory comments for why these particular schemas are expected to convert to
{ not: {} }JSON schemas, as this conversion pattern isn't immediately intuitive.testSchemaConverter([ { name: 'z.symbol()', schema: z.symbol(), input: [true, { not: {} }], + // Symbols cannot be represented in JSON Schema, so we use a negation schema }, { name: 'z.promise(z.string())', schema: z.promise(z.string()), input: [true, { not: {} }], + // Promises cannot be represented in JSON Schema, so we use a negation schema }, { name: 'z.custom(() => false)', schema: z.custom(() => false), input: [true, { not: {} }], + // Custom validators cannot be represented in JSON Schema, so we use a negation schema }, ])apps/content/docs/openapi/plugins/zod-smart-coercion.md (1)
44-47: Clear import examples for different Zod versionsThe import examples clearly show how to use the plugin with both Zod v3 and Zod v4. The use of the
experimental_prefix appropriately indicates this is not yet a stable API.Consider adding a note about potential API changes to set user expectations about stability:
import { ZodSmartCoercionPlugin } from '@orpc/zod' // <-- zod v3 import { experimental_ZodSmartCoercionPlugin as ZodSmartCoercionPlugin } from '@orpc/zod/zod4' // <-- zod v4 + +// Note: The Zod v4 API is experimental and may change in future releasespackages/zod/src/zod4/coercer.rest.test.ts (1)
1-17: Union type coercion tests look good.The tests verify that union schemas correctly maintain string values when they could be coerced to other types. This is important behavior for ensuring that smart coercion doesn't overaggressively convert values that could be valid in multiple formats.
However, consider adding more test cases to cover:
- Unions with more than two types
- Unions with complex types (objects, arrays)
- Edge cases where coercion might be ambiguous
packages/zod/src/zod4/converter.combination.test.ts (2)
30-34: Remove duplicate test case.There's a duplicate test case for
intersection(z.string().optional(), z.number().optional())with identical schema and expected output.- { - name: 'intersection(z.string().optional(), z.number().optional())', - schema: z.intersection(z.string().optional(), z.number().optional()), - input: [false, { allOf: [{ type: 'string' }, { type: 'number' }] }], - },
1-29: Expand union and intersection test coverage.The tests effectively verify basic union and intersection schema conversion to JSON Schema. Consider adding:
- Tests with more complex schemas (nested objects, arrays)
- Discriminated unions
- Unions with literals and enums
- Branded types in intersections
These additions would ensure comprehensive coverage for combination types.
packages/zod/src/zod4/coercer.structure.test.ts (1)
1-179: Strong test coverage for structure types.The test suite provides comprehensive coverage for array, tuple, set, object, record, and map types, including handling of undefined inputs, optional schemas, and type coercion scenarios.
Consider adding tests for:
- Nested object structures
- Objects with optional fields
- Deep arrays with mixed types
- Records with more specific key types
packages/zod/src/zod4/converter.string.test.ts (2)
66-69: Remove duplicate test case for uuid.There's a duplicate test case for
z.uuid()- the same test appears earlier at lines 36-39.- { - name: 'uuid', - schema: z.uuid(), - input: [true, { type: 'string', format: 'uuid' }], - },
1-146: Comprehensive string schema test coverage.The test suite provides excellent coverage for string schemas, including length constraints, regex patterns, and specialized formats. It tests all the string validation methods and ISO formats.
Consider adding tests for:
- Custom string validations via
.refine()- Locale-specific string validations
- More complex regex patterns
- String transformations with
.transform()packages/zod/src/zod4/coercer.test.ts (1)
7-8: Consider using a more type-safe approach for options initializationInstead of using type assertion with
as any, consider creating a mock object that matches the expected interface structure. This would make the test more robust against future interface changes.- const options = {} as any + const options = { + clientInterceptors: [] as Array<any> + }packages/zod/src/zod4/converter.processed.test.ts (1)
1-1: Consider using consistent import style for zod4This file uses the default import style (
import z from 'zod4') while other files in the package use the namespace import style (import * as z from 'zod4'). Consider standardizing the import approach across all files to maintain consistency.- import z from 'zod4' + import * as z from 'zod4'packages/zod/src/zod4/converter.number.test.ts (1)
4-46: Well-structured test suite covering numeric schema conversions.This test suite provides comprehensive coverage of numeric types in Zod v4, including basic numbers, integers, bounded numbers, multiplicity constraints, exclusive bounds, bigints, and nan values. Each test case properly defines the expected JSON Schema representation according to specification.
Consider adding test cases for additional numeric constraints that might be available in Zod v4, such as:
+ { + name: 'number.nonnegative()', + schema: z.number().nonnegative(), + input: [true, { type: 'number', minimum: 0 }], + }, + { + name: 'number.nonpositive()', + schema: z.number().nonpositive(), + input: [true, { type: 'number', maximum: 0 }], + }, + { + name: 'number.safe()', + schema: z.number().safe(), + input: [true, { type: 'number', maximum: 9007199254740991, minimum: -9007199254740991 }], + },packages/zod/src/zod4/registries.ts (2)
24-41: Documentation error in JSON_SCHEMA_INPUT_REGISTRY exampleThere's a mistake in the example code - it references
JSON_SCHEMA_REGISTRYinstead ofJSON_SCHEMA_INPUT_REGISTRYin the example.-JSON_SCHEMA_REGISTRY.add(user, { +JSON_SCHEMA_INPUT_REGISTRY.add(user, { examples: [{ name: 'John', age: "20" }], })
43-60: Incorrect documentation for JSON_SCHEMA_OUTPUT_REGISTRYThe JSDoc comment incorrectly states this registry is "only useful for .input" but it should be "only useful for .output", as this is the OUTPUT_REGISTRY.
-* Zod registry for customizing generated JSON schema, only useful for .input +* Zod registry for customizing generated JSON schema, only useful for .outputpackages/zod/src/zod4/coercer.ts (1)
316-319:"1.0"is not coerced although it is a valid number
Number("1.0")gives1, whose string representation is"1", therefore
the current equality check rejects it. If this is unintended, compare
againstNumber(value).toString() === String(parseFloat(value))
or use a regular expression to allow numeric postfixes.packages/zod/tests/shared.ts (1)
34-56: Leaking interceptor across test cases can cause false positives
optionsis a shared mutable object;plugin.init(options)appends an
interceptor once, but iftestSchemaSmartCoercionis invoked multiple times
in different test files the interceptor list grows unbounded and the first
interceptor will run N times.Create a fresh options object per invocation:
- const plugin = new ZodSmartCoercionPlugin() - const options = {} as any - plugin.init(options) + const plugin = new ZodSmartCoercionPlugin() + const options = {} as any + plugin.init(options)to
+ const coerce = (schema: AnySchema, input: unknown) => { + const opts = {} as any // fresh each call + plugin.init(opts) + ... + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (23)
apps/content/docs/openapi/openapi-specification.md(3 hunks)apps/content/docs/openapi/plugins/zod-smart-coercion.md(2 hunks)packages/openapi/src/schema.ts(1 hunks)packages/zod/package.json(3 hunks)packages/zod/src/zod4/coercer.combination.test.ts(1 hunks)packages/zod/src/zod4/coercer.native.test.ts(1 hunks)packages/zod/src/zod4/coercer.rest.test.ts(1 hunks)packages/zod/src/zod4/coercer.structure.test.ts(1 hunks)packages/zod/src/zod4/coercer.test.ts(1 hunks)packages/zod/src/zod4/coercer.ts(1 hunks)packages/zod/src/zod4/converter.combination.test.ts(1 hunks)packages/zod/src/zod4/converter.meta.test.ts(1 hunks)packages/zod/src/zod4/converter.native.test.ts(1 hunks)packages/zod/src/zod4/converter.number.test.ts(1 hunks)packages/zod/src/zod4/converter.processed.test.ts(1 hunks)packages/zod/src/zod4/converter.rest.test.ts(1 hunks)packages/zod/src/zod4/converter.string.test.ts(1 hunks)packages/zod/src/zod4/converter.structure.test.ts(1 hunks)packages/zod/src/zod4/converter.test.ts(1 hunks)packages/zod/src/zod4/converter.ts(1 hunks)packages/zod/src/zod4/index.ts(1 hunks)packages/zod/src/zod4/registries.ts(1 hunks)packages/zod/tests/shared.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (9)
packages/zod/src/zod4/converter.string.test.ts (1)
packages/zod/tests/shared.ts (1)
testSchemaConverter(15-25)
packages/zod/src/zod4/converter.processed.test.ts (1)
packages/zod/tests/shared.ts (1)
testSchemaConverter(15-25)
packages/zod/src/zod4/converter.number.test.ts (1)
packages/zod/tests/shared.ts (1)
testSchemaConverter(15-25)
packages/zod/src/zod4/converter.combination.test.ts (1)
packages/zod/tests/shared.ts (1)
testSchemaConverter(15-25)
packages/zod/src/zod4/converter.rest.test.ts (1)
packages/zod/tests/shared.ts (1)
testSchemaConverter(15-25)
packages/zod/src/zod4/converter.native.test.ts (1)
packages/zod/tests/shared.ts (1)
testSchemaConverter(15-25)
packages/zod/src/zod4/converter.structure.test.ts (1)
packages/zod/tests/shared.ts (1)
testSchemaConverter(15-25)
packages/zod/src/zod4/coercer.native.test.ts (1)
packages/zod/tests/shared.ts (1)
testSchemaSmartCoercion(34-60)
packages/zod/src/zod4/converter.meta.test.ts (1)
packages/zod/tests/shared.ts (1)
testSchemaConverter(15-25)
🪛 GitHub Check: test
packages/zod/src/zod4/converter.meta.test.ts
[failure] 14-14: packages/zod/src/zod4/converter.meta.test.ts
TypeError: Cannot read properties of undefined (reading 'add')
❯ packages/zod/src/zod4/converter.meta.test.ts:14:22
🪛 GitHub Actions: CI
packages/zod/src/zod4/converter.meta.test.ts
[error] 14-14: TypeError: Cannot read properties of undefined (reading 'add') at line 14. This caused the test suite to fail.
🔇 Additional comments (51)
packages/zod/src/zod4/index.ts (1)
1-3: Good module organizationThe export structure here is clean and follows a logical pattern, effectively centralizing access to all Zod v4 related functionality. This makes it easy for consumers to import everything they need from a single entry point.
packages/openapi/src/schema.ts (1)
3-5: Support for JSON Schema content encoding addedAdding
ContentEncodingalongsideFormatenhances the schema capabilities, particularly for scenarios involving binary data or specific string encoding requirements. The naming convention follows the existing pattern withJSONSchemaFormat.packages/zod/src/zod4/converter.rest.test.ts (1)
1-2: Good import organizationClear import structure with direct usage of
zod4package and appropriate test utilities from the shared module.apps/content/docs/openapi/plugins/zod-smart-coercion.md (1)
10-12: Important warning about Zod v4 limitationsThe warning about limited support for unions in Zod v4 is crucial for users to understand the limitations of the experimental implementation.
packages/zod/src/zod4/coercer.structure.test.ts (1)
54-58:Details
✅ Verification successful
Verify tuple schema behavior without rest.
The test for a tuple without rest elements appears to allow additional elements beyond those defined in the schema. In Zod v3, extra elements were dropped by default, but this test suggests they're preserved in v4. Please verify this is the intended behavior.
🏁 Script executed:
#!/bin/bash # Check the behavior of tuple without rest in zod4 documentation or types grep -r "tuple" --include="*.ts" packages/zod/src/zod4/ | grep -v "test"Length of output: 874
🏁 Script executed:
#!/bin/bash # Show context around the 'tuple - without rest' test in coercer.structure.test.ts grep -R "tuple - without rest" -n packages/zod/src/zod4/coercer.structure.test.ts | while IFS=":" read -r file line _; do start=$((line-5)) end=$((line+5)) sed -n "${start},${end}p" "$file" doneLength of output: 2003
🏁 Script executed:
#!/bin/bash set -e file="packages/zod/src/zod4/coercer.structure.test.ts" if [ ! -f "$file" ]; then echo "Error: File not found: $file" >&2 exit 1 fi echo "Context around 'tuple - without rest':" grep -n "tuple - without rest" "$file" | while IFS=":" read -r _ line _; do start=$((line - 5)) [ "$start" -lt 1 ] && start=1 end=$((line + 5)) sed -n "${start},${end}p" "$file" doneLength of output: 579
🏁 Script executed:
#!/bin/bash set -e file="packages/zod/src/zod4/coercer.ts" if [ ! -f "$file" ]; then echo "Error: File not found: $file" >&2 exit 1 fi echo "-------- 'case \'tuple\'' block in coercer.ts --------" grep -n "case 'tuple'" "$file" | while IFS=":" read -r _ line _; do start=$((line - 3)) [ "$start" -lt 1 ] && start=1 end=$((line + 50)) sed -n "${start},${end}p" "$file" doneLength of output: 475
tuple without rest now preserves extra elements in Zod v4 (intended behavior)
Confirmed: in Zod v4’s coercer (seepackages/zod/src/zod4/coercer.ts), a tuple with no rest schema will coerce up to its defined items and then keep any additional inputs unmodified. This test correctly validates that change from v3. No update needed.packages/zod/src/zod4/converter.string.test.ts (2)
46-49:Details
❓ Verification inconclusive
Ensure pattern escaping in includes method.
The test for
string.includes("a\\")is using a backslash character. Verify that the pattern escaping is working as expected in the JSON Schema output to avoid syntax errors.
🏁 Script executed:
#!/bin/bash # Check how string.includes handles special characters in the implementation grep -A 10 "includes" --include="*.ts" packages/zod/src/zod4/converter.tsLength of output: 740
Ensure proper escaping for
.includes()patterns with backslashes
Please verify that the JSON Schema generated byz.string().includes('a\\')correctly escapes the backslash (i.e. produces apatternvalue of"a\\\\")and yields a valid regex in the schema.• Check the conversion logic for string refinements (including
.includes) inpackages/zod/src/zod4/converter.ts(or any dedicated string‐converter file).
• Generate the schema forz.string().includes('a\\')and confirm thepatternfield is exactlya\\\\.
• Ensure the double‐escaping only handles the literal backslash and doesn’t introduce invalid JSON or regex syntax.
142-145:Details
✅ Verification successful
Verify template literal pattern.
The pattern for the template literal combining a number and enum values seems complex. Please verify it correctly handles negative numbers, decimal values, and all enum options with the correct syntax.
🌐 Web query:
What is the correct regex pattern for a template literal combining number and string enum in Zod v4?💡 Result:
In Zod v4, template literals provide a powerful way to combine different schema types into complex string patterns. For creating a template literal that combines a number and string enum, you would use the
z.templateLiteral()function.Template Literals in Zod v4
Template literals in Zod v4 allow you to create dynamic string patterns by combining different schema types. This feature closely mirrors TypeScript's template literal types.
The correct pattern for combining a number and string enum in a template literal looks like this:
const cssUnits = z.enum(["px", "em", "rem", "%"]); const css = z.templateLiteral([z.number(), cssUnits]); // Type: `${number}px` | `${number}em` | `${number}rem` | `${number}%`This creates a schema that validates strings that consist of a number followed immediately by one of the enum values[4]. For example, values like "10px", "20em", "5rem", or "50%" would all validate successfully.
How It Works
The
z.templateLiteral()function works by:
- Taking an array of schema elements (string literals and other Zod schemas)
- Internally concatenating the regex patterns of these elements
- Creating a super-regex that properly enforces the combined pattern[2][5]
Every Zod schema type that can be stringified (strings, numbers, booleans, enums, literals, etc.) stores an internal regex. The template literal constructor combines these into a comprehensive validation pattern[2].
Additional Examples
You can create more complex patterns by adding more elements:
// Email pattern with domain restrictions const email = z.templateLiteral([ z.string().min(1), "@", z.string().max(64) ]); // Validates strings like "user@example.com"Or create more specific number formats with units:
// Temperature with unit const tempUnits = z.enum(["C", "F"]); const temperature = z.templateLiteral([ z.number(), "°", tempUnits ]); // Validates strings like "25°C" or "77°F"Template literals are one of the major new features in Zod v4 and provide a type-safe way to define and validate complex string patterns that wasn't previously possible in earlier versions[2][5].
Citations:
- 1: https://zod.dev
- 2: https://v4.zod.dev/v4
- 3: colinhacks/zod#2074
- 4: https://basicutils.com/learn/zod/whats-new-in-zod-v4
- 5: https://v4.zod.dev/api
- 6: https://zod.dev/?id=zod-enums
- 7: https://zod.dev/?id=literals
- 8: https://dev.to/arafat4693/learn-zod-in-5-minutes-17pn
- 9: https://forum.freecodecamp.org/t/using-template-literal-inside-of-a-regex/454028
- 10: https://github.com/colinhacks/zod
Pattern Verified: Regex handles negative, decimal, and enum units correctly
The existing pattern
^-?\\d+(?:\\.\\d+)?(px|em|rem|%)$accurately matches negative numbers, optional decimals, and each of the"px","em","rem", or"%"suffixes. No changes required.packages/zod/src/zod4/coercer.test.ts (1)
6-37: Well-structured test for the Zod v4 coercion pluginThis test appropriately verifies that the ZodSmartCoercionPlugin correctly handles both Zod schemas (performing coercion) and non-Zod schemas (passing them through unchanged). The test creates a simplified client interceptor pattern to validate the plugin's behavior.
packages/zod/src/zod4/converter.test.ts (2)
10-17: Properly validates schema type detection logicThe condition test correctly verifies that the converter can identify various forms of Zod schemas while rejecting non-Zod schemas. This is crucial for the converter to work reliably in a mixed environment.
19-41: Comprehensive validation of @zod/mini schema conversionThis test effectively verifies that the converter correctly translates @zod/mini schema constraints (minLength, maxLength, regex pattern) into equivalent JSON Schema properties. The assertions thoroughly check the structure of the conversion output, ensuring both the property constraints and required fields are properly represented.
packages/zod/src/zod4/converter.meta.test.ts (2)
21-33: Update all registry references if neededIf the fix above resolves the issue with
JSON_SCHEMA_REGISTRY, similar updates may be needed for these other registry references:- JSON_SCHEMA_REGISTRY.add(customSchema3, { + experimental_JSON_SCHEMA_REGISTRY.add(customSchema3, { description: 'JSON_SCHEMA_REGISTRY', }) - JSON_SCHEMA_INPUT_REGISTRY.add(customSchema3, { + experimental_JSON_SCHEMA_INPUT_REGISTRY.add(customSchema3, { description: 'JSON_SCHEMA_INPUT_REGISTRY', examples: [1], }) - JSON_SCHEMA_OUTPUT_REGISTRY.add(customSchema3, { + experimental_JSON_SCHEMA_OUTPUT_REGISTRY.add(customSchema3, { description: 'JSON_SCHEMA_OUTPUT_REGISTRY', examples: ['1'], })
35-73: Well-structured tests for schema metadata and modifiersThe test cases thoroughly validate how various schema features are represented in the converted JSON Schema:
- Custom metadata (descriptions, examples)
- Default values
- Catch clauses
- Readonly modifiers
The tests use the shared
testSchemaConverterutility effectively to test both input and output conversion strategies.packages/zod/src/zod4/converter.processed.test.ts (1)
4-20: Comprehensive tests for lazy and transformed schemasThese tests effectively verify how the JSON Schema converter handles more complex schema types:
- The simple lazy schema test confirms proper resolution
- The nested lazy schema test verifies the expected behavior with nested references
- The transform test correctly checks that transforms work for input but produce empty objects for output
This thorough coverage helps ensure that the converter handles edge cases correctly.
packages/zod/src/zod4/converter.number.test.ts (2)
40-45: Good handling of the special nan case.The test correctly handles the special case for
z.nan(), with different representations for input ({ not: {} }) vs output ({ type: 'null' }). This distinction is important as JSON Schema doesn't have a direct representation for NaN.
1-2:Details
✅ Verification successful
Import looks good, but verify zod4 package configuration.
The import statement for Zod v4 follows best practices with a default import. This matches the experimental support being added for Zod v4 in this PR.
🏁 Script executed:
#!/bin/bash # Verify the zod4 dependency is properly configured in package.json grep -r "zod4" packages/zod/package.jsonLength of output: 274
Zod4 package configuration verified
packages/zod/package.jsondefines the"zod4"alias as"npm:zod@^4.0.0-beta.20250505T012514".- Exports for
./zod4correctly point to the builtdist/zod4/index.*files.No further changes needed.
packages/zod/src/zod4/converter.native.test.ts (7)
1-3: Import strategy is appropriate.The file correctly imports from 'zod4' using namespace import, which is suitable for accessing all exports from the Zod v4 package.
4-8: Enum definition is correctly implemented.The test file defines an example enum that will be used in the tests, following TypeScript best practices.
9-29: Test cases for basic type schemas look good.The test cases for boolean, success wrapper, date, null, any, and unknown types correctly define their expected JSON Schema representations.
40-74: Optional, nullable, void, never, and literal schema tests are comprehensive.These test cases correctly verify how Zod v4 handles optional values, nullable values, void, never, and literal schemas when converting to JSON Schema.
75-89: Interesting case for complex literals.The tests for literal arrays are particularly useful, showing how arrays containing different primitive types (numbers, bigints, strings) are converted to JSON Schema. Note that bigint 1234n is serialized as string '1234' in the JSON Schema representation.
90-99: Enum tests cover both string array and TypeScript enum cases.Good coverage of both ways to define enums in Zod - using string arrays directly and using TypeScript enum objects.
100-119: File schema tests with MIME type constraints are well-implemented.The tests for file schemas cover various MIME type constraints, including a wildcard MIME type, a single MIME type, and multiple MIME types. The tests verify the correct JSON Schema representations using contentMediaType.
packages/zod/src/zod4/coercer.combination.test.ts (8)
1-2: Import approach is consistent with other test files.The import statements follow the same pattern as other test files, importing from 'zod4' and using the shared test utility.
4-4: Recursive lazy schema is well defined.The test creates an infinite recursive lazy schema for testing coercion in deeply nested structures. This is an important edge case to test.
6-24: Union schema coercion tests handle discriminated and non-discriminated unions.The tests for union schema coercion correctly test both discriminated and non-discriminated unions, showing that coercion is not applied to non-discriminated unions but is applied to discriminated ones. This is the expected behavior.
25-60: Complex discriminated union tests are thorough.The tests cover complex discriminated unions with nested objects as discriminator values and cases where discriminator values might not match exactly. These edge cases are important to validate the coercion behavior.
61-66: Intersection schema coercion test is implemented properly.The test verifies that coercion works on both sides of an intersection schema.
67-102: Tests for schema modifiers are comprehensive.These tests validate that coercion works correctly with schema modifiers like readonly, pipe, transform, brand, catch, and default. They confirm that primitive coercion (string to boolean) works with these modifiers.
103-138: Optional and nullable schema tests cover all edge cases.The tests verify coercion behavior for optional and nullable schemas, including undefined and null values, and the nonoptional modifier.
139-156: Lazy schema tests include complex cases.The tests cover both regular lazy schemas with nested structure and the infinite recursive lazy schema defined at the top of the file. They verify that coercion works correctly for nested boolean values.
packages/zod/src/zod4/converter.structure.test.ts (7)
1-3: Imports include both zod4 and @zod/mini.The file imports both Zod v4 and @zod/mini, suggesting that test cases will cover schemas defined using both libraries. This is a good approach to ensure compatibility across different implementation approaches.
5-37: Array schema conversion tests are comprehensive.The tests cover various array constraints including nonempty, min/max length, fixed length, and array elements of optional or undefined types. The JSON Schema output correctly uses the appropriate properties like minItems, maxItems, and items.
38-52: Tuple schema tests cover all relevant cases.These tests verify the conversion of simple tuples, tuples with rest elements, and tuples with length constraints. The JSON Schema output correctly uses prefixItems for the tuple elements and items for the rest elements.
53-63: Set schema tests correctly represent sets as arrays with uniqueItems.The tests verify that set schemas are converted to JSON Schema arrays with uniqueItems=true, both for simple sets and sets with optional elements.
64-88: Object schema tests cover required and optional properties.These tests verify object schema conversion with required properties, optional properties, undefined properties, strict mode, and catchall (additionalProperties). The JSON Schema representation correctly uses required, properties, and additionalProperties.
89-103: Record schema tests correctly handle key and value types.The tests for record schemas verify the conversion of key-value mappings, including constraints on property names and values. The JSON Schema output correctly uses additionalProperties and propertyNames.
104-114: Map schema tests represent maps as arrays of key-value pairs.These tests verify that map schemas are converted to JSON Schema arrays of fixed-length tuples, correctly representing the key-value structure of maps.
apps/content/docs/openapi/openapi-specification.md (3)
69-76: Well-structured imports for Zod v3 and v4 supportThe import statements have been updated to clearly distinguish between Zod v3 and v4, with appropriate comments. This helps users understand which version they're working with.
169-225: Good documentation for Zod v4 featuresThis new section comprehensively documents Zod v4 features, including:
- Native File schema support
- Built-in support for description and examples metadata
- Registry customization options for JSON Schema generation
The examples are clear and demonstrate the new capabilities effectively.
226-227: Clear separation between Zod versionsAdding a dedicated heading for Zod v3 creates a clear separation between the two versions, making it easier for users to find version-specific information.
packages/zod/package.json (3)
22-27: Properly configured exports for zod4 submoduleThe package exports are correctly configured for the new zod4 submodule, making it accessible via the
@orpc/zod/zod4import path.
45-55: Well-structured peer dependenciesThe peer dependencies have been properly updated to include both
@zod/coreandzod, and they're marked as optional. This allows users to install either Zod v3 or v4 (or both) based on their needs.
63-67: Comprehensive dev dependencies for development and testingThe dev dependencies include all necessary packages for development and testing with both Zod v3 and v4. The alias
zod4for the Zod v4 beta package is a good approach for managing the dependency.packages/zod/src/zod4/coercer.native.test.ts (4)
1-8: Good test setupThe test setup correctly imports Zod v4 and the shared test utility, and defines a test enum for later use in the tests.
9-105: Comprehensive tests for number, bigint, and boolean coercionThe test cases thoroughly validate coercion behavior for numbers, bigints, and booleans, including:
- Positive and negative numbers
- Edge cases like "12345n" that shouldn't be coerced
- Various string formats for boolean values ("true", "t", "on", etc.)
- Non-coercible inputs that should remain unchanged
This ensures reliable type conversion in the coercion plugin.
106-129: Thorough date coercion testsThe date coercion tests cover important scenarios:
- ISO string conversion
- Date format strings
- Invalid date strings
- Non-string inputs
This ensures dates are handled correctly across different input formats.
130-177: Comprehensive literal and enum type testsThe literal and enum tests validate correct handling of:
- Multiple literal values
- Native enum with both number and string values
- String enum values
- Non-matching inputs that should remain unchanged
This ensures reliable coercion behavior for more complex schema types.
packages/zod/src/zod4/registries.ts (2)
1-4: Appropriate imports and dependenciesThe imports correctly reference the necessary types from
@orpc/openapiand@zod/core, providing a solid foundation for the registry implementations.
5-22: Well-documented JSON_SCHEMA_REGISTRYThe
experimental_JSON_SCHEMA_REGISTRYis thoroughly documented with clear examples showing how to use it for customizing schema output for both input and output types.packages/zod/src/zod4/converter.ts (2)
525-527: Depth limit for lazy schemas ignores circular reference through unions / objectsThe depth guard only counts consecutive
lazylayers. A schema likelazy(() => z.object({ next: lazy(() => ... ) }))hits the guard, but
lazy(() => z.union([z.string(), lazy(() => ... )]))increments depth twice per level and will still overflow.
Track overall recursion depth or schema-identity instead of consecutive
lazy nodes.
322-339:⚠️ Potential issue
requiredflag for intersections can be incorrectFor an intersection all constituent schemas must accept
undefined
for the whole intersection to do so. The current logic setsrequiredto
trueif any branch is required.Example:
z.string().optional().and(z.number())
– one branch optional, one required.
Result should be required, yet with the current logic it istrueby chance;
butz.string().optional().and(z.number().optional())incorrectly yields
true(should befalse).Replace with:
-let required = false +let required = true ... -if (itemRequired) { - required = true -} +if (!itemRequired) { + required = false +}Likely an incorrect or invalid review comment.
Closes: https://github.com/unnoq/orpc/issues/428
Summary by CodeRabbit
New Features
Documentation
Tests
Chores