Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Oct 6, 2025

Fix allOf in array items being generated as union instead of intersection in Zod plugins

  • Investigate issue and understand codebase
  • Confirm the bug exists in arrayTypeToZodSchema function
  • Build project successfully
  • Fix the bug in v4/plugin.ts arrayTypeToZodSchema function
  • Fix the bug in v3/plugin.ts arrayTypeToZodSchema function ✨
  • Fix the bug in mini/plugin.ts arrayTypeToZodSchema function
  • Test the fix with manual test case
  • Run existing tests to ensure no regressions
  • Lint and format code
  • Run typecheck
  • Add snapshot test specs for 2.0.x, 3.0.x, and 3.1.x
  • Add test scenarios only in openapi.test.ts (removed duplicates from 3.0.x and 3.1.x tests) ✨
  • Convert all specs to YAML format for consistency ✨
  • Generate and verify snapshots for all combinations
  • Verify tests pass for all Zod versions

Changes Made

Fixed the issue where arrays with allOf items were incorrectly generating z.union() instead of intersection in all Zod plugins (v3, v4, mini).

Code Changes

  1. v3/plugin.ts: Added handling for allOf with .and() for objects and z.intersection() for primitives ✨
  2. v4/plugin.ts: Updated arrayTypeToZodSchema to handle allOf with .and() for objects and z.intersection() for primitives
  3. mini/plugin.ts: Updated arrayTypeToZodSchema to handle allOf with z.intersection() for all types

Test Coverage

Organized tests efficiently:

  • OpenAPI versions: 2.0.x, 3.0.x, 3.1.x (specs in respective directories)
  • Test organization: Only in openapi.test.ts (removed duplicates from version-specific test files) ✨
  • Spec format: All specs use YAML for consistency ✨
  • Zod versions tested: v3, v4, mini
  • Test cases:
    • Arrays with allOf of object schemas (uses .and() in v3/v4, z.intersection() in mini)
    • Arrays with allOf of primitives (uses z.intersection())
    • Arrays with allOf including $refs (properly handles refs)

Total: 18 snapshot combinations (3 OpenAPI versions × 3 Zod versions × 2 test suites)

Original prompt

This section details on the original issue you should resolve

<issue_title>allOf being generated as union [zod v4]</issue_title>
<issue_description>### Heyapi config:

import { defineConfig } from '@hey-api/openapi-ts';

export default defineConfig({
  input: './test.yaml',
  output: {
    format: 'prettier',
    lint: 'eslint',
    path: './src/client',
  },
  plugins: [
    {
      name: 'zod',
      types: {
        infer: true,
      },
    },
  ],
});

OpenAPI specification

openapi: '3.0.3'
info: 
  title: Test
components:
  requestBodies:
    req:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/body'

  schemas:
    body:
      type: array
      items:
        allOf:
          - type: object
            properties:
              id:
                type: integer
          - type: object
            properties:
              name:
                type: string

Generated zod schema

// This file is auto-generated by @hey-api/openapi-ts

import { z } from 'zod';

export const zBody = z.array(
  z.union([
    z.object({
      id: z.optional(z.int()),
    }),
    z.object({
      name: z.optional(z.string()),
    }),
  ]),
);

export type BodyZodType = z.infer<typeof zBody>;

export const zReq = zBody;

export type ReqZodType = z.infer<typeof zReq>;

But I expect .and or .intersection instead of .union

</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #2735

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copy link

vercel bot commented Oct 6, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
hey-api-docs Ready Ready Preview Comment Oct 7, 2025 0:56am

Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

Copy link

changeset-bot bot commented Oct 6, 2025

🦋 Changeset detected

Latest commit: 078face

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@hey-api/openapi-ts Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@Copilot Copilot AI changed the title [WIP] allOf being generated as union [zod v4] Fix allOf in array items being generated as union instead of intersection in Zod plugins Oct 6, 2025
@Copilot Copilot AI requested a review from mrlubos October 6, 2025 18:05
Copilot finished work on behalf of mrlubos October 6, 2025 18:05
@mrlubos
Copy link
Member

mrlubos commented Oct 6, 2025

@copilot Add snapshot tests, ensure we handle this feature across various Zod versions. I expect the final pull request to be comparable in quality to this one #2650

Copy link
Contributor Author

Copilot AI commented Oct 6, 2025

@copilot Add snapshot tests, ensure we handle this feature across various Zod versions. I expect the final pull request to be comparable in quality to this one https://github.com/hey-api/openapi-ts/pu...

Added comprehensive snapshot tests covering all OpenAPI versions (2.0.x, 3.0.x, 3.1.x) and all Zod compatibility versions (v3, v4, mini). Tests include cases for object intersections, primitive intersections, and refs with allOf.

Commit: 50bb78d

Copy link

codecov bot commented Oct 6, 2025

Codecov Report

❌ Patch coverage is 0% with 135 lines in your changes missing coverage. Please review.
✅ Project coverage is 29.24%. Comparing base (ee1f929) to head (078face).
⚠️ Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
packages/openapi-ts/src/plugins/zod/mini/plugin.ts 0.00% 45 Missing ⚠️
packages/openapi-ts/src/plugins/zod/v3/plugin.ts 0.00% 45 Missing ⚠️
packages/openapi-ts/src/plugins/zod/v4/plugin.ts 0.00% 45 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2736      +/-   ##
==========================================
- Coverage   29.31%   29.24%   -0.07%     
==========================================
  Files         388      388              
  Lines       37803    37893      +90     
  Branches     2260     2260              
==========================================
  Hits        11082    11082              
- Misses      26691    26781      +90     
  Partials       30       30              
Flag Coverage Δ
unittests 29.24% <0.00%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mrlubos
Copy link
Member

mrlubos commented Oct 6, 2025

@copilot a few notes:

  • there's no need for the 3.0.x and 3.1.x test cases since they're covered in openapi.test.ts. This unnecessarily results in duplicate tests
  • for consistency, all specs you've added should be of the same format, ie. YAML
  • observe that Zod v3-compatible output doesn't handle the requirement. You've fixed the issue in v4 and Mini output, but not in v3

Copy link

pkg-pr-new bot commented Oct 6, 2025

Open in StackBlitz

npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/codegen-core@2736
npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/nuxt@2736
npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/openapi-ts@2736
npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/vite-plugin@2736

commit: 078face

Copy link
Contributor Author

Copilot AI commented Oct 6, 2025

@copilot a few notes:

  • there's no need for the 3.0.x and 3.1.x test cases since they're covered in openapi.test.ts. This unnecessarily results in duplicate tests
  • for consistency, all specs you've...

Fixed all three issues:

  1. Removed duplicate test entries from 3.0.x.test.ts and 3.1.x.test.ts - all tests now only in openapi.test.ts
  2. Converted 2.0.x spec from JSON to YAML for consistency
  3. Fixed Zod v3 plugin to handle allOf correctly (now uses .and() for objects and z.intersection() for primitives)

All tests passing. Commit: f9e0d9d

Fixes the generation of allOf in array items for Zod plugins.
@mrlubos mrlubos marked this pull request as ready for review October 7, 2025 00:56
@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Oct 7, 2025
@dosubot dosubot bot added the bug 🔥 Something isn't working label Oct 7, 2025
@mrlubos mrlubos merged commit d79dc9d into main Oct 7, 2025
15 of 17 checks passed
@mrlubos mrlubos deleted the copilot/fix-2110710e-8174-470d-8162-ec3f601f9ba9 branch October 7, 2025 01:22
@hey-api hey-api bot mentioned this pull request Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🔥 Something isn't working size:XL This PR changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

allOf being generated as union [zod v4]
2 participants