fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #2159 from Joshua-hypt/feature/zod-handle-array-union-types

authored by

Lubos and committed by
GitHub
66fecce2 01134c59

+214 -42
+5
.changeset/popular-apples-fail.md
··· 1 + --- 2 + '@hey-api/openapi-ts': patch 3 + --- 4 + 5 + fix(zod): handle array union types
+29 -5
packages/openapi-ts-tests/test/__snapshots__/3.0.x/plugins/zod/default/zod.gen.ts
··· 170 170 /** 171 171 * This is a simple array with any of properties 172 172 */ 173 - export const zArrayWithAnyOfProperties = z.array(z.unknown()); 173 + export const zArrayWithAnyOfProperties = z.array(z.union([ 174 + z.object({ 175 + foo: z.string().optional().default('test') 176 + }), 177 + z.object({ 178 + bar: z.string().optional() 179 + }) 180 + ])); 174 181 175 182 export const zAnyOfAnyAndNull = z.object({ 176 183 data: z.unknown().optional() ··· 180 187 * This is a simple array with any of properties 181 188 */ 182 189 export const zAnyOfArrays = z.object({ 183 - results: z.array(z.unknown()).optional() 190 + results: z.array(z.union([ 191 + z.object({ 192 + foo: z.string().optional() 193 + }), 194 + z.object({ 195 + bar: z.string().optional() 196 + }) 197 + ])).optional() 184 198 }); 185 199 186 200 /** ··· 508 522 */ 509 523 export const zCompositionWithNestedAnyOfAndNull = z.object({ 510 524 propA: z.union([ 511 - z.array(z.unknown()), 525 + z.array(z.union([ 526 + z3eNum1Период, 527 + zConstValue 528 + ])), 512 529 z.null() 513 530 ]).optional() 514 531 }); ··· 731 748 732 749 export const zNestedAnyOfArraysNullable = z.object({ 733 750 nullableArray: z.union([ 734 - z.array(z.unknown()), 751 + z.array(z.union([ 752 + z.string(), 753 + z.boolean() 754 + ])), 735 755 z.null() 736 756 ]).optional() 737 757 }); ··· 833 853 834 854 export const zModelWithAnyOfConstantSizeArray = z.unknown(); 835 855 836 - export const zModelWithPrefixItemsConstantSizeArray = z.array(z.unknown()); 856 + export const zModelWithPrefixItemsConstantSizeArray = z.array(z.union([ 857 + zModelWithInteger, 858 + z.number(), 859 + z.string() 860 + ])); 837 861 838 862 export const zModelWithAnyOfConstantSizeArrayNullable = z.unknown(); 839 863
+32 -6
packages/openapi-ts-tests/test/__snapshots__/3.1.x/plugins/zod/default/zod.gen.ts
··· 170 170 /** 171 171 * This is a simple array with any of properties 172 172 */ 173 - export const zArrayWithAnyOfProperties = z.array(z.unknown()); 173 + export const zArrayWithAnyOfProperties = z.array(z.union([ 174 + z.object({ 175 + foo: z.string().optional().default('test') 176 + }), 177 + z.object({ 178 + bar: z.string().optional() 179 + }) 180 + ])); 174 181 175 182 export const zAnyOfAnyAndNull = z.object({ 176 183 data: z.union([ ··· 183 190 * This is a simple array with any of properties 184 191 */ 185 192 export const zAnyOfArrays = z.object({ 186 - results: z.array(z.unknown()).optional() 193 + results: z.array(z.union([ 194 + z.object({ 195 + foo: z.string().optional() 196 + }), 197 + z.object({ 198 + bar: z.string().optional() 199 + }) 200 + ])).optional() 187 201 }); 188 202 189 203 /** ··· 486 500 */ 487 501 export const zCompositionWithNestedAnyAndTypeNull = z.object({ 488 502 propA: z.union([ 489 - z.array(z.unknown()), 490 - z.array(z.unknown()) 503 + z.array(z.union([ 504 + zModelWithDictionary, 505 + z.null() 506 + ])), 507 + z.array(z.union([ 508 + zModelWithArray, 509 + z.null() 510 + ])) 491 511 ]).optional() 492 512 }); 493 513 ··· 503 523 */ 504 524 export const zCompositionWithNestedAnyOfAndNull = z.object({ 505 525 propA: z.union([ 506 - z.array(z.unknown()), 526 + z.array(z.union([ 527 + z3eNum1Период, 528 + zConstValue 529 + ])), 507 530 z.null() 508 531 ]).optional() 509 532 }); ··· 722 745 723 746 export const zNestedAnyOfArraysNullable = z.object({ 724 747 nullableArray: z.union([ 725 - z.array(z.unknown()), 748 + z.array(z.union([ 749 + z.string(), 750 + z.boolean() 751 + ])), 726 752 z.null() 727 753 ]).optional() 728 754 });
+35 -7
packages/openapi-ts-tests/test/__snapshots__/3.1.x/validators-union-merge/valibot.gen.ts
··· 2 2 3 3 import * as v from 'valibot'; 4 4 5 - export const vBar = v.union([ 5 + export const vContact = v.union([ 6 6 v.object({ 7 - bar: v.string() 7 + email: v.string() 8 8 }), 9 9 v.object({ 10 - baz: v.string() 10 + phone: v.string() 11 11 }) 12 12 ]); 13 13 14 - export const vFoo = v.intersect([ 15 - vBar, 14 + export const vUser = v.intersect([ 15 + vContact, 16 16 v.object({ 17 - foo: v.string() 17 + username: v.string() 18 18 }) 19 - ]); 19 + ]); 20 + 21 + export const vDogDetails = v.object({ 22 + breed: v.string(), 23 + barkVolume: v.pipe(v.number(), v.integer(), v.minValue(1), v.maxValue(10)) 24 + }); 25 + 26 + export const vCatDetails = v.object({ 27 + furLength: v.picklist([ 28 + 'short', 29 + 'medium', 30 + 'long' 31 + ]), 32 + purrs: v.boolean() 33 + }); 34 + 35 + export const vPetStore = v.object({ 36 + animals: v.array(v.object({ 37 + name: v.string(), 38 + type: v.optional(v.picklist([ 39 + 'dog', 40 + 'cat' 41 + ])), 42 + details: v.union([ 43 + vDogDetails, 44 + vCatDetails 45 + ]) 46 + })) 47 + });
+34 -6
packages/openapi-ts-tests/test/__snapshots__/3.1.x/validators-union-merge/zod.gen.ts
··· 2 2 3 3 import { z } from 'zod'; 4 4 5 - export const zBar = z.union([ 5 + export const zContact = z.union([ 6 6 z.object({ 7 - bar: z.string() 7 + email: z.string() 8 8 }), 9 9 z.object({ 10 - baz: z.string() 10 + phone: z.string() 11 11 }) 12 12 ]); 13 13 14 - export const zFoo = zBar.and(z.object({ 15 - foo: z.string() 16 - })); 14 + export const zUser = zContact.and(z.object({ 15 + username: z.string() 16 + })); 17 + 18 + export const zDogDetails = z.object({ 19 + breed: z.string(), 20 + barkVolume: z.number().int().gte(1).lte(10) 21 + }); 22 + 23 + export const zCatDetails = z.object({ 24 + furLength: z.enum([ 25 + 'short', 26 + 'medium', 27 + 'long' 28 + ]), 29 + purrs: z.boolean() 30 + }); 31 + 32 + export const zPetStore = z.object({ 33 + animals: z.array(z.object({ 34 + name: z.string(), 35 + type: z.enum([ 36 + 'dog', 37 + 'cat' 38 + ]).optional(), 39 + details: z.union([ 40 + zDogDetails, 41 + zCatDetails 42 + ]) 43 + })) 44 + });
+65 -9
packages/openapi-ts-tests/test/spec/3.1.x/validators-union-merge.json
··· 6 6 }, 7 7 "components": { 8 8 "schemas": { 9 - "Foo": { 9 + "User": { 10 10 "allOf": [ 11 11 { 12 - "$ref": "#/components/schemas/Bar" 12 + "$ref": "#/components/schemas/Contact" 13 13 }, 14 14 { 15 15 "properties": { 16 - "foo": { 16 + "username": { 17 17 "type": "string" 18 18 } 19 19 }, 20 - "required": ["foo"], 20 + "required": ["username"], 21 21 "type": "object" 22 22 } 23 23 ] 24 24 }, 25 - "Bar": { 25 + "Contact": { 26 26 "oneOf": [ 27 27 { 28 28 "properties": { 29 - "bar": { 29 + "email": { 30 30 "type": "string" 31 31 } 32 32 }, 33 - "required": ["bar"], 33 + "required": ["email"], 34 34 "type": "object" 35 35 }, 36 36 { 37 37 "properties": { 38 - "baz": { 38 + "phone": { 39 39 "type": "string" 40 40 } 41 41 }, 42 - "required": ["baz"], 42 + "required": ["phone"], 43 43 "type": "object" 44 44 } 45 45 ] 46 + }, 47 + "PetStore": { 48 + "type": "object", 49 + "required": ["animals"], 50 + "properties": { 51 + "animals": { 52 + "type": "array", 53 + "items": { 54 + "type": "object", 55 + "required": ["name", "details"], 56 + "properties": { 57 + "name": { 58 + "type": "string" 59 + }, 60 + "type": { 61 + "type": "string", 62 + "enum": ["dog", "cat"], 63 + "default": "dog" 64 + }, 65 + "details": { 66 + "oneOf": [ 67 + { "$ref": "#/components/schemas/DogDetails" }, 68 + { "$ref": "#/components/schemas/CatDetails" } 69 + ] 70 + } 71 + } 72 + } 73 + } 74 + } 75 + }, 76 + "DogDetails": { 77 + "type": "object", 78 + "required": ["breed", "barkVolume"], 79 + "properties": { 80 + "breed": { 81 + "type": "string" 82 + }, 83 + "barkVolume": { 84 + "type": "integer", 85 + "minimum": 1, 86 + "maximum": 10 87 + } 88 + } 89 + }, 90 + "CatDetails": { 91 + "type": "object", 92 + "required": ["furLength", "purrs"], 93 + "properties": { 94 + "furLength": { 95 + "type": "string", 96 + "enum": ["short", "medium", "long"] 97 + }, 98 + "purrs": { 99 + "type": "boolean" 100 + } 101 + } 46 102 } 47 103 } 48 104 }
+14 -9
packages/openapi-ts/src/plugins/zod/plugin.ts
··· 97 97 // ); 98 98 } 99 99 100 - // TODO: parser - handle union 101 - // return compiler.typeArrayNode(compiler.typeUnionNode({ types: itemExpressions })); 102 - 103 100 arrayExpression = compiler.callExpression({ 104 - functionName, 101 + functionName: compiler.propertyAccessExpression({ 102 + expression: zIdentifier, 103 + name: compiler.identifier({ text: 'array' }), 104 + }), 105 105 parameters: [ 106 - unknownTypeToZodSchema({ 107 - context, 108 - schema: { 109 - type: 'unknown', 110 - }, 106 + compiler.callExpression({ 107 + functionName: compiler.propertyAccessExpression({ 108 + expression: zIdentifier, 109 + name: unionIdentifier, 110 + }), 111 + parameters: [ 112 + compiler.arrayLiteralExpression({ 113 + elements: itemExpressions, 114 + }), 115 + ], 111 116 }), 112 117 ], 113 118 });