Skip to content

Commit 4a01f7d

Browse files
Fix nested any-of
1 parent 5568964 commit 4a01f7d

File tree

5 files changed

+226
-2
lines changed

5 files changed

+226
-2
lines changed

src/openApi/v3/interfaces/OpenApiSchema.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export interface OpenApiSchema extends OpenApiReference, WithEnumExtension {
2626
required?: string[];
2727
enum?: (string | number)[];
2828
type?: string | string[];
29-
const?: string | number | boolean | null;
29+
const?: string | number | null;
3030
allOf?: OpenApiSchema[];
3131
oneOf?: OpenApiSchema[];
3232
anyOf?: OpenApiSchema[];
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { reservedWords } from '../../../utils/reservedWords';
2+
import { getModel } from './getModel';
3+
import { getType } from './getType';
4+
5+
const openApi = {
6+
openapi: '3.0',
7+
info: {
8+
title: 'dummy',
9+
version: '1.0',
10+
},
11+
paths: {},
12+
servers: [
13+
{
14+
url: 'https://localhost:8080/api',
15+
},
16+
],
17+
components: {
18+
schemas: {
19+
Enum1: {
20+
enum: ['Bird', 'Dog'],
21+
type: 'string',
22+
},
23+
ConstValue: {
24+
type: 'string',
25+
const: 'ConstValue',
26+
},
27+
CompositionWithAnyOfAndNull: {
28+
description:
29+
"This is a model with one property with a 'any of' relationship where the options are not $ref",
30+
type: 'object',
31+
properties: {
32+
propA: {
33+
anyOf: [
34+
{
35+
items: {
36+
anyOf: [
37+
{
38+
$ref: '#/components/schemas/Enum1',
39+
},
40+
{
41+
$ref: '#/components/schemas/ConstValue',
42+
},
43+
],
44+
},
45+
type: 'array',
46+
},
47+
{
48+
type: 'null',
49+
},
50+
],
51+
},
52+
},
53+
},
54+
CompositionWithAny: {
55+
description:
56+
"This is a model with one property with a 'any of' relationship where the options are not $ref",
57+
type: 'object',
58+
properties: {
59+
propA: {
60+
anyOf: [
61+
{
62+
$ref: '#/components/schemas/Enum1',
63+
},
64+
{
65+
$ref: '#/components/schemas/ConstValue',
66+
},
67+
{
68+
type: 'null',
69+
},
70+
],
71+
},
72+
},
73+
},
74+
},
75+
},
76+
};
77+
78+
describe('getModel', () => {
79+
it('Parses any of', () => {
80+
const definition = openApi.components.schemas.CompositionWithAnyOfAndNull;
81+
const definitionType = getType('CompositionWithAnyOfAndNull');
82+
const model = getModel(openApi, definition, true, definitionType.base.replace(reservedWords, '_$1'));
83+
expect(model.properties[0].properties.length).toBe(2);
84+
});
85+
86+
it('Parses any of 2', () => {
87+
const definition = openApi.components.schemas.CompositionWithAny;
88+
const definitionType = getType('CompositionWithAny');
89+
const model = getModel(openApi, definition, true, definitionType.base.replace(reservedWords, '_$1'));
90+
expect(model.properties[0].properties.length).toBe(3);
91+
});
92+
});

src/openApi/v3/parser/getModel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ export const getModel = (
8282
model.imports.push(...arrayItems.imports);
8383
model.default = getModelDefault(definition, model);
8484
return model;
85+
} else if (definition.items.anyOf) {
86+
return getModel(openApi, definition.items);
8587
} else {
8688
const arrayItems = getModel(openApi, definition.items);
8789
model.export = 'array';

test/__snapshots__/index.spec.ts.snap

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3686,19 +3686,22 @@ export type { CompositionWithAllOfAndNullable } from './models/CompositionWithAl
36863686
export type { CompositionWithAnyOf } from './models/CompositionWithAnyOf';
36873687
export type { CompositionWithAnyOfAndNullable } from './models/CompositionWithAnyOfAndNullable';
36883688
export type { CompositionWithAnyOfAnonymous } from './models/CompositionWithAnyOfAnonymous';
3689+
export type { CompositionWithNestedAnyOfAndNull } from './models/CompositionWithNestedAnyOfAndNull';
36893690
export type { CompositionWithOneOf } from './models/CompositionWithOneOf';
36903691
export type { CompositionWithOneOfAndComplexArrayDictionary } from './models/CompositionWithOneOfAndComplexArrayDictionary';
36913692
export type { CompositionWithOneOfAndNullable } from './models/CompositionWithOneOfAndNullable';
36923693
export type { CompositionWithOneOfAndSimpleArrayDictionary } from './models/CompositionWithOneOfAndSimpleArrayDictionary';
36933694
export type { CompositionWithOneOfAndSimpleDictionary } from './models/CompositionWithOneOfAndSimpleDictionary';
36943695
export type { CompositionWithOneOfAnonymous } from './models/CompositionWithOneOfAnonymous';
36953696
export type { CompositionWithOneOfDiscriminator } from './models/CompositionWithOneOfDiscriminator';
3697+
export type { ConstValue } from './models/ConstValue';
36963698
export type { DeprecatedModel } from './models/DeprecatedModel';
36973699
export type { DictionaryWithArray } from './models/DictionaryWithArray';
36983700
export type { DictionaryWithDictionary } from './models/DictionaryWithDictionary';
36993701
export type { DictionaryWithProperties } from './models/DictionaryWithProperties';
37003702
export type { DictionaryWithReference } from './models/DictionaryWithReference';
37013703
export type { DictionaryWithString } from './models/DictionaryWithString';
3704+
export { Enum1 } from './models/Enum1';
37023705
export type { EnumFromDescription } from './models/EnumFromDescription';
37033706
export { EnumWithExtensions } from './models/EnumWithExtensions';
37043707
export { EnumWithNumbers } from './models/EnumWithNumbers';
@@ -3757,19 +3760,22 @@ export { $CompositionWithAllOfAndNullable } from './schemas/$CompositionWithAllO
37573760
export { $CompositionWithAnyOf } from './schemas/$CompositionWithAnyOf';
37583761
export { $CompositionWithAnyOfAndNullable } from './schemas/$CompositionWithAnyOfAndNullable';
37593762
export { $CompositionWithAnyOfAnonymous } from './schemas/$CompositionWithAnyOfAnonymous';
3763+
export { $CompositionWithNestedAnyOfAndNull } from './schemas/$CompositionWithNestedAnyOfAndNull';
37603764
export { $CompositionWithOneOf } from './schemas/$CompositionWithOneOf';
37613765
export { $CompositionWithOneOfAndComplexArrayDictionary } from './schemas/$CompositionWithOneOfAndComplexArrayDictionary';
37623766
export { $CompositionWithOneOfAndNullable } from './schemas/$CompositionWithOneOfAndNullable';
37633767
export { $CompositionWithOneOfAndSimpleArrayDictionary } from './schemas/$CompositionWithOneOfAndSimpleArrayDictionary';
37643768
export { $CompositionWithOneOfAndSimpleDictionary } from './schemas/$CompositionWithOneOfAndSimpleDictionary';
37653769
export { $CompositionWithOneOfAnonymous } from './schemas/$CompositionWithOneOfAnonymous';
37663770
export { $CompositionWithOneOfDiscriminator } from './schemas/$CompositionWithOneOfDiscriminator';
3771+
export { $ConstValue } from './schemas/$ConstValue';
37673772
export { $DeprecatedModel } from './schemas/$DeprecatedModel';
37683773
export { $DictionaryWithArray } from './schemas/$DictionaryWithArray';
37693774
export { $DictionaryWithDictionary } from './schemas/$DictionaryWithDictionary';
37703775
export { $DictionaryWithProperties } from './schemas/$DictionaryWithProperties';
37713776
export { $DictionaryWithReference } from './schemas/$DictionaryWithReference';
37723777
export { $DictionaryWithString } from './schemas/$DictionaryWithString';
3778+
export { $Enum1 } from './schemas/$Enum1';
37733779
export { $EnumFromDescription } from './schemas/$EnumFromDescription';
37743780
export { $EnumWithExtensions } from './schemas/$EnumWithExtensions';
37753781
export { $EnumWithNumbers } from './schemas/$EnumWithNumbers';
@@ -4107,6 +4113,23 @@ export type CompositionWithAnyOfAnonymous = {
41074113
"
41084114
`;
41094115

4116+
exports[`v3 should generate: test/generated/v3/models/CompositionWithNestedAnyOfAndNull.ts 1`] = `
4117+
"/* generated using openapi-typescript-codegen -- do no edit */
4118+
/* istanbul ignore file */
4119+
/* tslint:disable */
4120+
/* eslint-disable */
4121+
import type { ConstValue } from './ConstValue';
4122+
import type { Enum1 } from './Enum1';
4123+
/**
4124+
* This is a model with one property with a 'any of' relationship where the options are not $ref
4125+
*/
4126+
export type CompositionWithNestedAnyOfAndNull = {
4127+
propA?: ((Enum1 | ConstValue) | null);
4128+
};
4129+
4130+
"
4131+
`;
4132+
41104133
exports[`v3 should generate: test/generated/v3/models/CompositionWithOneOf.ts 1`] = `
41114134
"/* generated using openapi-typescript-codegen -- do no edit */
41124135
/* istanbul ignore file */
@@ -4223,6 +4246,15 @@ export type CompositionWithOneOfDiscriminator = (ModelCircle | ModelSquare);
42234246
"
42244247
`;
42254248

4249+
exports[`v3 should generate: test/generated/v3/models/ConstValue.ts 1`] = `
4250+
"/* generated using openapi-typescript-codegen -- do no edit */
4251+
/* istanbul ignore file */
4252+
/* tslint:disable */
4253+
/* eslint-disable */
4254+
export type ConstValue = "ConstValue";
4255+
"
4256+
`;
4257+
42264258
exports[`v3 should generate: test/generated/v3/models/DeprecatedModel.ts 1`] = `
42274259
"/* generated using openapi-typescript-codegen -- do no edit */
42284260
/* istanbul ignore file */
@@ -4308,6 +4340,18 @@ export type DictionaryWithString = Record<string, string>;
43084340
"
43094341
`;
43104342

4343+
exports[`v3 should generate: test/generated/v3/models/Enum1.ts 1`] = `
4344+
"/* generated using openapi-typescript-codegen -- do no edit */
4345+
/* istanbul ignore file */
4346+
/* tslint:disable */
4347+
/* eslint-disable */
4348+
export enum Enum1 {
4349+
BIRD = 'Bird',
4350+
DOG = 'Dog',
4351+
}
4352+
"
4353+
`;
4354+
43114355
exports[`v3 should generate: test/generated/v3/models/EnumFromDescription.ts 1`] = `
43124356
"/* generated using openapi-typescript-codegen -- do no edit */
43134357
/* istanbul ignore file */
@@ -5320,6 +5364,32 @@ export const $CompositionWithAnyOfAnonymous = {
53205364
"
53215365
`;
53225366

5367+
exports[`v3 should generate: test/generated/v3/schemas/$CompositionWithNestedAnyOfAndNull.ts 1`] = `
5368+
"/* generated using openapi-typescript-codegen -- do no edit */
5369+
/* istanbul ignore file */
5370+
/* tslint:disable */
5371+
/* eslint-disable */
5372+
export const $CompositionWithNestedAnyOfAndNull = {
5373+
description: \`This is a model with one property with a 'any of' relationship where the options are not $ref\`,
5374+
properties: {
5375+
propA: {
5376+
type: 'any-of',
5377+
contains: [{
5378+
type: 'any-of',
5379+
contains: [{
5380+
type: 'Enum1',
5381+
}, {
5382+
type: 'ConstValue',
5383+
}],
5384+
}, {
5385+
type: 'null',
5386+
}],
5387+
},
5388+
},
5389+
} as const;
5390+
"
5391+
`;
5392+
53235393
exports[`v3 should generate: test/generated/v3/schemas/$CompositionWithOneOf.ts 1`] = `
53245394
"/* generated using openapi-typescript-codegen -- do no edit */
53255395
/* istanbul ignore file */
@@ -5505,6 +5575,17 @@ export const $CompositionWithOneOfDiscriminator = {
55055575
"
55065576
`;
55075577

5578+
exports[`v3 should generate: test/generated/v3/schemas/$ConstValue.ts 1`] = `
5579+
"/* generated using openapi-typescript-codegen -- do no edit */
5580+
/* istanbul ignore file */
5581+
/* tslint:disable */
5582+
/* eslint-disable */
5583+
export const $ConstValue = {
5584+
type: '"ConstValue"',
5585+
} as const;
5586+
"
5587+
`;
5588+
55085589
exports[`v3 should generate: test/generated/v3/schemas/$DeprecatedModel.ts 1`] = `
55095590
"/* generated using openapi-typescript-codegen -- do no edit */
55105591
/* istanbul ignore file */
@@ -5605,6 +5686,17 @@ export const $DictionaryWithString = {
56055686
"
56065687
`;
56075688

5689+
exports[`v3 should generate: test/generated/v3/schemas/$Enum1.ts 1`] = `
5690+
"/* generated using openapi-typescript-codegen -- do no edit */
5691+
/* istanbul ignore file */
5692+
/* tslint:disable */
5693+
/* eslint-disable */
5694+
export const $Enum1 = {
5695+
type: 'Enum',
5696+
} as const;
5697+
"
5698+
`;
5699+
56085700
exports[`v3 should generate: test/generated/v3/schemas/$EnumFromDescription.ts 1`] = `
56095701
"/* generated using openapi-typescript-codegen -- do no edit */
56105702
/* istanbul ignore file */

test/spec/v3.json

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2071,6 +2071,44 @@
20712071
}
20722072
}
20732073
},
2074+
"Enum1":{
2075+
"enum": [
2076+
"Bird",
2077+
"Dog"
2078+
],
2079+
"type": "string"
2080+
},
2081+
"ConstValue": {
2082+
"type": "string",
2083+
"const": "ConstValue"
2084+
},
2085+
"CompositionWithNestedAnyOfAndNull": {
2086+
"description": "This is a model with one property with a 'any of' relationship where the options are not $ref",
2087+
"type": "object",
2088+
"properties": {
2089+
"propA": {
2090+
"anyOf": [
2091+
{
2092+
"items": {
2093+
"anyOf": [
2094+
{
2095+
"$ref": "#/components/schemas/Enum1"
2096+
},
2097+
{
2098+
"$ref": "#/components/schemas/ConstValue"
2099+
}
2100+
]
2101+
},
2102+
"type": "array"
2103+
},
2104+
{
2105+
"type": "null"
2106+
}
2107+
],
2108+
"title": "Scopes"
2109+
}
2110+
}
2111+
},
20742112
"CompositionWithOneOfAndNullable": {
20752113
"description": "This is a model with one property with a 'one of' relationship",
20762114
"type": "object",
@@ -2574,4 +2612,4 @@
25742612
}
25752613
}
25762614
}
2577-
}
2615+
}

0 commit comments

Comments
 (0)