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.

Address review feedback: fix v3 plugin, remove duplicate tests, use YAML for all specs

Co-authored-by: mrlubos <12529395+mrlubos@users.noreply.github.com>

+145 -239
-75
packages/openapi-ts-tests/specs/2.0.x/array-items-all-of.json
··· 1 - { 2 - "swagger": "2.0", 3 - "info": { 4 - "title": "OpenAPI 2.0 array items allOf example", 5 - "version": "1" 6 - }, 7 - "definitions": { 8 - "ArrayWithAllOfObjects": { 9 - "type": "array", 10 - "items": { 11 - "allOf": [ 12 - { 13 - "type": "object", 14 - "properties": { 15 - "id": { 16 - "type": "integer" 17 - } 18 - } 19 - }, 20 - { 21 - "type": "object", 22 - "properties": { 23 - "name": { 24 - "type": "string" 25 - } 26 - } 27 - } 28 - ] 29 - } 30 - }, 31 - "ArrayWithAllOfPrimitives": { 32 - "type": "array", 33 - "items": { 34 - "allOf": [ 35 - { 36 - "type": "number" 37 - }, 38 - { 39 - "type": "string" 40 - } 41 - ] 42 - } 43 - }, 44 - "ArrayWithAllOfRefs": { 45 - "type": "array", 46 - "items": { 47 - "allOf": [ 48 - { 49 - "$ref": "#/definitions/BaseModel" 50 - }, 51 - { 52 - "type": "object", 53 - "properties": { 54 - "extra": { 55 - "type": "string" 56 - } 57 - } 58 - } 59 - ] 60 - } 61 - }, 62 - "BaseModel": { 63 - "type": "object", 64 - "properties": { 65 - "id": { 66 - "type": "integer" 67 - }, 68 - "createdAt": { 69 - "type": "string", 70 - "format": "date-time" 71 - } 72 - } 73 - } 74 - } 75 - }
+40
packages/openapi-ts-tests/specs/2.0.x/array-items-all-of.yaml
··· 1 + swagger: '2.0' 2 + info: 3 + title: OpenAPI 2.0 array items allOf example 4 + version: '1' 5 + definitions: 6 + ArrayWithAllOfObjects: 7 + type: array 8 + items: 9 + allOf: 10 + - type: object 11 + properties: 12 + id: 13 + type: integer 14 + - type: object 15 + properties: 16 + name: 17 + type: string 18 + ArrayWithAllOfPrimitives: 19 + type: array 20 + items: 21 + allOf: 22 + - type: number 23 + - type: string 24 + ArrayWithAllOfRefs: 25 + type: array 26 + items: 27 + allOf: 28 + - $ref: '#/definitions/BaseModel' 29 + - type: object 30 + properties: 31 + extra: 32 + type: string 33 + BaseModel: 34 + type: object 35 + properties: 36 + id: 37 + type: integer 38 + createdAt: 39 + type: string 40 + format: date-time
+9 -18
packages/openapi-ts-tests/zod/v3/__snapshots__/2.0.x/v3/array-items-all-of/zod.gen.ts
··· 2 2 3 3 import { z } from 'zod'; 4 4 5 - export const zArrayWithAllOfObjects = z.array(z.union([ 6 - z.object({ 7 - id: z.number().int().optional() 8 - }), 9 - z.object({ 10 - name: z.string().optional() 11 - }) 12 - ])); 5 + export const zArrayWithAllOfObjects = z.array(z.object({ 6 + id: z.number().int().optional() 7 + }).and(z.object({ 8 + name: z.string().optional() 9 + }))); 13 10 14 - export const zArrayWithAllOfPrimitives = z.array(z.union([ 15 - z.number(), 16 - z.string() 17 - ])); 11 + export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); 18 12 19 13 export const zBaseModel = z.object({ 20 14 id: z.number().int().optional(), 21 15 createdAt: z.string().datetime().optional() 22 16 }); 23 17 24 - export const zArrayWithAllOfRefs = z.array(z.union([ 25 - zBaseModel, 26 - z.object({ 27 - extra: z.string().optional() 28 - }) 29 - ])); 18 + export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ 19 + extra: z.string().optional() 20 + })));
+9 -18
packages/openapi-ts-tests/zod/v3/__snapshots__/3.0.x/v3/array-items-all-of/zod.gen.ts
··· 2 2 3 3 import { z } from 'zod'; 4 4 5 - export const zArrayWithAllOfObjects = z.array(z.union([ 6 - z.object({ 7 - id: z.number().int().optional() 8 - }), 9 - z.object({ 10 - name: z.string().optional() 11 - }) 12 - ])); 5 + export const zArrayWithAllOfObjects = z.array(z.object({ 6 + id: z.number().int().optional() 7 + }).and(z.object({ 8 + name: z.string().optional() 9 + }))); 13 10 14 - export const zArrayWithAllOfPrimitives = z.array(z.union([ 15 - z.number(), 16 - z.string() 17 - ])); 11 + export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); 18 12 19 13 export const zBaseModel = z.object({ 20 14 id: z.number().int().optional(), 21 15 createdAt: z.string().datetime().optional() 22 16 }); 23 17 24 - export const zArrayWithAllOfRefs = z.array(z.union([ 25 - zBaseModel, 26 - z.object({ 27 - extra: z.string().optional() 28 - }) 29 - ])); 18 + export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ 19 + extra: z.string().optional() 20 + })));
+9 -18
packages/openapi-ts-tests/zod/v3/__snapshots__/3.1.x/v3/array-items-all-of/zod.gen.ts
··· 2 2 3 3 import { z } from 'zod'; 4 4 5 - export const zArrayWithAllOfObjects = z.array(z.union([ 6 - z.object({ 7 - id: z.number().int().optional() 8 - }), 9 - z.object({ 10 - name: z.string().optional() 11 - }) 12 - ])); 5 + export const zArrayWithAllOfObjects = z.array(z.object({ 6 + id: z.number().int().optional() 7 + }).and(z.object({ 8 + name: z.string().optional() 9 + }))); 13 10 14 - export const zArrayWithAllOfPrimitives = z.array(z.union([ 15 - z.number(), 16 - z.string() 17 - ])); 11 + export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); 18 12 19 13 export const zBaseModel = z.object({ 20 14 id: z.number().int().optional(), 21 15 createdAt: z.string().datetime().optional() 22 16 }); 23 17 24 - export const zArrayWithAllOfRefs = z.array(z.union([ 25 - zBaseModel, 26 - z.object({ 27 - extra: z.string().optional() 28 - }) 29 - ])); 18 + export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ 19 + extra: z.string().optional() 20 + })));
-8
packages/openapi-ts-tests/zod/v3/test/3.0.x.test.ts
··· 36 36 const scenarios = [ 37 37 { 38 38 config: createConfig({ 39 - input: 'array-items-all-of.yaml', 40 - output: 'array-items-all-of', 41 - }), 42 - description: 43 - 'generates correct array when items use allOf (intersection)', 44 - }, 45 - { 46 - config: createConfig({ 47 39 input: 'array-items-one-of-length-1.yaml', 48 40 output: 'array-items-one-of-length-1', 49 41 }),
-8
packages/openapi-ts-tests/zod/v3/test/3.1.x.test.ts
··· 36 36 const scenarios = [ 37 37 { 38 38 config: createConfig({ 39 - input: 'array-items-all-of.yaml', 40 - output: 'array-items-all-of', 41 - }), 42 - description: 43 - 'generates correct array when items use allOf (intersection)', 44 - }, 45 - { 46 - config: createConfig({ 47 39 input: 'array-items-one-of-length-1.yaml', 48 40 output: 'array-items-one-of-length-1', 49 41 }),
+1 -2
packages/openapi-ts-tests/zod/v3/test/openapi.test.ts
··· 37 37 const scenarios = [ 38 38 { 39 39 config: createConfig({ 40 - input: 41 - 'array-items-all-of.' + (version === '2.0.x' ? 'json' : 'yaml'), 40 + input: 'array-items-all-of.yaml', 42 41 output: 'array-items-all-of', 43 42 }), 44 43 description:
+9 -18
packages/openapi-ts-tests/zod/v4/__snapshots__/2.0.x/v3/array-items-all-of/zod.gen.ts
··· 2 2 3 3 import { z } from 'zod/v3'; 4 4 5 - export const zArrayWithAllOfObjects = z.array(z.union([ 6 - z.object({ 7 - id: z.number().int().optional() 8 - }), 9 - z.object({ 10 - name: z.string().optional() 11 - }) 12 - ])); 5 + export const zArrayWithAllOfObjects = z.array(z.object({ 6 + id: z.number().int().optional() 7 + }).and(z.object({ 8 + name: z.string().optional() 9 + }))); 13 10 14 - export const zArrayWithAllOfPrimitives = z.array(z.union([ 15 - z.number(), 16 - z.string() 17 - ])); 11 + export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); 18 12 19 13 export const zBaseModel = z.object({ 20 14 id: z.number().int().optional(), 21 15 createdAt: z.string().datetime().optional() 22 16 }); 23 17 24 - export const zArrayWithAllOfRefs = z.array(z.union([ 25 - zBaseModel, 26 - z.object({ 27 - extra: z.string().optional() 28 - }) 29 - ])); 18 + export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ 19 + extra: z.string().optional() 20 + })));
+9 -18
packages/openapi-ts-tests/zod/v4/__snapshots__/3.0.x/v3/array-items-all-of/zod.gen.ts
··· 2 2 3 3 import { z } from 'zod/v3'; 4 4 5 - export const zArrayWithAllOfObjects = z.array(z.union([ 6 - z.object({ 7 - id: z.number().int().optional() 8 - }), 9 - z.object({ 10 - name: z.string().optional() 11 - }) 12 - ])); 5 + export const zArrayWithAllOfObjects = z.array(z.object({ 6 + id: z.number().int().optional() 7 + }).and(z.object({ 8 + name: z.string().optional() 9 + }))); 13 10 14 - export const zArrayWithAllOfPrimitives = z.array(z.union([ 15 - z.number(), 16 - z.string() 17 - ])); 11 + export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); 18 12 19 13 export const zBaseModel = z.object({ 20 14 id: z.number().int().optional(), 21 15 createdAt: z.string().datetime().optional() 22 16 }); 23 17 24 - export const zArrayWithAllOfRefs = z.array(z.union([ 25 - zBaseModel, 26 - z.object({ 27 - extra: z.string().optional() 28 - }) 29 - ])); 18 + export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ 19 + extra: z.string().optional() 20 + })));
+9 -18
packages/openapi-ts-tests/zod/v4/__snapshots__/3.1.x/v3/array-items-all-of/zod.gen.ts
··· 2 2 3 3 import { z } from 'zod/v3'; 4 4 5 - export const zArrayWithAllOfObjects = z.array(z.union([ 6 - z.object({ 7 - id: z.number().int().optional() 8 - }), 9 - z.object({ 10 - name: z.string().optional() 11 - }) 12 - ])); 5 + export const zArrayWithAllOfObjects = z.array(z.object({ 6 + id: z.number().int().optional() 7 + }).and(z.object({ 8 + name: z.string().optional() 9 + }))); 13 10 14 - export const zArrayWithAllOfPrimitives = z.array(z.union([ 15 - z.number(), 16 - z.string() 17 - ])); 11 + export const zArrayWithAllOfPrimitives = z.array(z.intersection(z.number(), z.string())); 18 12 19 13 export const zBaseModel = z.object({ 20 14 id: z.number().int().optional(), 21 15 createdAt: z.string().datetime().optional() 22 16 }); 23 17 24 - export const zArrayWithAllOfRefs = z.array(z.union([ 25 - zBaseModel, 26 - z.object({ 27 - extra: z.string().optional() 28 - }) 29 - ])); 18 + export const zArrayWithAllOfRefs = z.array(zBaseModel.and(z.object({ 19 + extra: z.string().optional() 20 + })));
-8
packages/openapi-ts-tests/zod/v4/test/3.0.x.test.ts
··· 36 36 const scenarios = [ 37 37 { 38 38 config: createConfig({ 39 - input: 'array-items-all-of.yaml', 40 - output: 'array-items-all-of', 41 - }), 42 - description: 43 - 'generates correct array when items use allOf (intersection)', 44 - }, 45 - { 46 - config: createConfig({ 47 39 input: 'array-items-one-of-length-1.yaml', 48 40 output: 'array-items-one-of-length-1', 49 41 }),
-8
packages/openapi-ts-tests/zod/v4/test/3.1.x.test.ts
··· 36 36 const scenarios = [ 37 37 { 38 38 config: createConfig({ 39 - input: 'array-items-all-of.yaml', 40 - output: 'array-items-all-of', 41 - }), 42 - description: 43 - 'generates correct array when items use allOf (intersection)', 44 - }, 45 - { 46 - config: createConfig({ 47 39 input: 'array-items-one-of-length-1.yaml', 48 40 output: 'array-items-one-of-length-1', 49 41 }),
+1 -2
packages/openapi-ts-tests/zod/v4/test/openapi.test.ts
··· 37 37 const scenarios = [ 38 38 { 39 39 config: createConfig({ 40 - input: 41 - 'array-items-all-of.' + (version === '2.0.x' ? 'json' : 'yaml'), 40 + input: 'array-items-all-of.yaml', 42 41 output: 'array-items-all-of', 43 42 }), 44 43 description:
+49 -20
packages/openapi-ts/src/plugins/zod/v3/plugin.ts
··· 72 72 }); 73 73 } else { 74 74 if (schema.logicalOperator === 'and') { 75 - // TODO: parser - handle intersection 76 - // return tsc.typeArrayNode( 77 - // tsc.typeIntersectionNode({ types: itemExpressions }), 78 - // ); 79 - } 80 - 81 - arrayExpression = tsc.callExpression({ 82 - functionName: tsc.propertyAccessExpression({ 83 - expression: zSymbol.placeholder, 84 - name: identifiers.array, 85 - }), 86 - parameters: [ 87 - tsc.callExpression({ 75 + const firstSchema = schema.items![0]!; 76 + // we want to add an intersection, but not every schema can use the same API. 77 + // if the first item contains another array or not an object, we cannot use 78 + // `.and()` as that does not exist on `.union()` and non-object schemas. 79 + let intersectionExpression: ts.Expression; 80 + if ( 81 + firstSchema.logicalOperator === 'or' || 82 + (firstSchema.type && firstSchema.type !== 'object') 83 + ) { 84 + intersectionExpression = tsc.callExpression({ 88 85 functionName: tsc.propertyAccessExpression({ 89 86 expression: zSymbol.placeholder, 90 - name: identifiers.union, 87 + name: identifiers.intersection, 91 88 }), 92 - parameters: [ 93 - tsc.arrayLiteralExpression({ 94 - elements: itemExpressions, 89 + parameters: itemExpressions, 90 + }); 91 + } else { 92 + intersectionExpression = itemExpressions[0]!; 93 + for (let i = 1; i < itemExpressions.length; i++) { 94 + intersectionExpression = tsc.callExpression({ 95 + functionName: tsc.propertyAccessExpression({ 96 + expression: intersectionExpression, 97 + name: identifiers.and, 95 98 }), 96 - ], 99 + parameters: [itemExpressions[i]!], 100 + }); 101 + } 102 + } 103 + 104 + arrayExpression = tsc.callExpression({ 105 + functionName, 106 + parameters: [intersectionExpression], 107 + }); 108 + } else { 109 + arrayExpression = tsc.callExpression({ 110 + functionName: tsc.propertyAccessExpression({ 111 + expression: zSymbol.placeholder, 112 + name: identifiers.array, 97 113 }), 98 - ], 99 - }); 114 + parameters: [ 115 + tsc.callExpression({ 116 + functionName: tsc.propertyAccessExpression({ 117 + expression: zSymbol.placeholder, 118 + name: identifiers.union, 119 + }), 120 + parameters: [ 121 + tsc.arrayLiteralExpression({ 122 + elements: itemExpressions, 123 + }), 124 + ], 125 + }), 126 + ], 127 + }); 128 + } 100 129 } 101 130 } 102 131