Skip to content

Commit 90b02c5

Browse files
authored
Merge pull request #33 from nicolas-chaulet/fix/object-nullable-ref
fix(template): generate nullable interface when isNullable is true
2 parents e2daf50 + c1223ca commit 90b02c5

File tree

7 files changed

+168
-86
lines changed

7 files changed

+168
-86
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export interface WithEnumExtension {
2-
'x-enum-varnames'?: string[];
32
'x-enum-descriptions'?: string[];
3+
'x-enum-varnames'?: string[];
44
}

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

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,51 +9,51 @@ import type { OpenApiXml } from './OpenApiXml';
99
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#schemaObject
1010
*/
1111
export interface OpenApiSchema extends OpenApiReference, WithEnumExtension {
12-
title?: string;
13-
multipleOf?: number;
14-
maximum?: number;
15-
exclusiveMaximum?: boolean;
16-
minimum?: number;
17-
exclusiveMinimum?: boolean;
18-
maxLength?: number;
19-
minLength?: number;
20-
pattern?: string;
21-
maxItems?: number;
22-
minItems?: number;
23-
uniqueItems?: boolean;
24-
maxProperties?: number;
25-
minProperties?: number;
26-
required?: string[];
27-
enum?: (string | number)[];
28-
type?: string | string[];
29-
const?: string | number | boolean | null;
12+
additionalProperties?: boolean | OpenApiSchema;
3013
allOf?: OpenApiSchema[];
31-
oneOf?: OpenApiSchema[];
3214
anyOf?: OpenApiSchema[];
33-
not?: OpenApiSchema[];
34-
items?: OpenApiSchema;
35-
properties?: Dictionary<OpenApiSchema>;
36-
additionalProperties?: boolean | OpenApiSchema;
15+
const?: string | number | boolean | null;
16+
default?: any;
17+
deprecated?: boolean;
3718
description?: string;
19+
discriminator?: OpenApiDiscriminator;
20+
enum?: (string | number)[];
21+
example?: any;
22+
exclusiveMaximum?: boolean;
23+
exclusiveMinimum?: boolean;
24+
externalDocs?: OpenApiExternalDocs;
3825
format?:
39-
| 'int32'
40-
| 'int64'
41-
| 'float'
42-
| 'double'
43-
| 'string'
26+
| 'binary'
4427
| 'boolean'
4528
| 'byte'
46-
| 'binary'
47-
| 'date'
4829
| 'date-time'
49-
| 'password';
50-
default?: any;
30+
| 'date'
31+
| 'double'
32+
| 'float'
33+
| 'int32'
34+
| 'int64'
35+
| 'password'
36+
| 'string';
37+
items?: OpenApiSchema;
38+
maximum?: number;
39+
maxItems?: number;
40+
maxLength?: number;
41+
maxProperties?: number;
42+
minimum?: number;
43+
minItems?: number;
44+
minLength?: number;
45+
minProperties?: number;
46+
multipleOf?: number;
47+
not?: OpenApiSchema[];
5148
nullable?: boolean;
52-
discriminator?: OpenApiDiscriminator;
49+
oneOf?: OpenApiSchema[];
50+
pattern?: string;
51+
properties?: Dictionary<OpenApiSchema>;
5352
readOnly?: boolean;
53+
required?: string[];
54+
title?: string;
55+
type?: string | string[];
56+
uniqueItems?: boolean;
5457
writeOnly?: boolean;
5558
xml?: OpenApiXml;
56-
externalDocs?: OpenApiExternalDocs;
57-
example?: any;
58-
deprecated?: boolean;
5959
}

src/openApi/v3/parser/getModel.ts

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,45 @@ export const getModel = (
1717
parentDefinition: OpenApiSchema | null = null
1818
): Model => {
1919
const model: Model = {
20-
name,
21-
export: 'interface',
22-
type: 'any',
2320
base: 'any',
24-
template: null,
25-
link: null,
21+
deprecated: Boolean(definition.deprecated),
2622
description: definition.description || null,
27-
deprecated: definition.deprecated === true,
23+
enum: [],
24+
enums: [],
25+
exclusiveMaximum: definition.exclusiveMaximum,
26+
exclusiveMinimum: definition.exclusiveMinimum,
27+
export: 'interface',
28+
format: definition.format,
29+
imports: [],
2830
isDefinition,
29-
isReadOnly: definition.readOnly === true,
3031
isNullable: definition.nullable === true,
32+
isReadOnly: definition.readOnly === true,
3133
isRequired: false,
32-
format: definition.format,
34+
link: null,
3335
maximum: definition.maximum,
34-
exclusiveMaximum: definition.exclusiveMaximum,
35-
minimum: definition.minimum,
36-
exclusiveMinimum: definition.exclusiveMinimum,
37-
multipleOf: definition.multipleOf,
38-
maxLength: definition.maxLength,
39-
minLength: definition.minLength,
4036
maxItems: definition.maxItems,
41-
minItems: definition.minItems,
42-
uniqueItems: definition.uniqueItems,
37+
maxLength: definition.maxLength,
4338
maxProperties: definition.maxProperties,
39+
minimum: definition.minimum,
40+
minItems: definition.minItems,
41+
minLength: definition.minLength,
4442
minProperties: definition.minProperties,
43+
multipleOf: definition.multipleOf,
44+
name,
4545
pattern: getPattern(definition.pattern),
46-
imports: [],
47-
enum: [],
48-
enums: [],
4946
properties: [],
47+
template: null,
48+
type: 'any',
49+
uniqueItems: definition.uniqueItems,
5050
};
5151

5252
if (definition.$ref) {
5353
const definitionRef = getType(definition.$ref);
54-
model.export = 'reference';
55-
model.type = definitionRef.type;
5654
model.base = definitionRef.base;
57-
model.template = definitionRef.template;
55+
model.export = 'reference';
5856
model.imports.push(...definitionRef.imports);
57+
model.template = definitionRef.template;
58+
model.type = definitionRef.type;
5959
model.default = getModelDefault(definition, model);
6060
return model;
6161
}
@@ -64,10 +64,10 @@ export const getModel = (
6464
const enumerators = getEnum(definition.enum);
6565
const extendedEnumerators = extendEnum(enumerators, definition);
6666
if (extendedEnumerators.length) {
67-
model.export = 'enum';
68-
model.type = 'string';
6967
model.base = 'string';
7068
model.enum.push(...extendedEnumerators);
69+
model.export = 'enum';
70+
model.type = 'string';
7171
model.default = getModelDefault(definition, model);
7272
return model;
7373
}
@@ -76,11 +76,11 @@ export const getModel = (
7676
if (definition.type === 'array' && definition.items) {
7777
if (definition.items.$ref) {
7878
const arrayItems = getType(definition.items.$ref);
79-
model.export = 'array';
80-
model.type = arrayItems.type;
8179
model.base = arrayItems.base;
82-
model.template = arrayItems.template;
80+
model.export = 'array';
8381
model.imports.push(...arrayItems.imports);
82+
model.template = arrayItems.template;
83+
model.type = arrayItems.type;
8484
model.default = getModelDefault(definition, model);
8585
return model;
8686
}
@@ -93,12 +93,12 @@ export const getModel = (
9393
}
9494

9595
const arrayItems = getModel(openApi, definition.items);
96-
model.export = 'array';
97-
model.type = arrayItems.type;
9896
model.base = arrayItems.base;
99-
model.template = arrayItems.template;
100-
model.link = arrayItems;
97+
model.export = 'array';
10198
model.imports.push(...arrayItems.imports);
99+
model.link = arrayItems;
100+
model.template = arrayItems.template;
101+
model.type = arrayItems.type;
102102
model.default = getModelDefault(definition, model);
103103
return model;
104104
}
@@ -117,15 +117,15 @@ export const getModel = (
117117

118118
if (definition.type === 'object') {
119119
if (definition.properties) {
120+
model.base = 'any';
120121
model.export = 'interface';
121122
model.type = 'any';
122-
model.base = 'any';
123123
model.default = getModelDefault(definition, model);
124124

125125
const modelProperties = getModelProperties(openApi, definition, getModel, model);
126126
modelProperties.forEach(modelProperty => {
127-
model.imports.push(...modelProperty.imports);
128127
model.enums.push(...modelProperty.enums);
128+
model.imports.push(...modelProperty.imports);
129129
model.properties.push(modelProperty);
130130
if (modelProperty.export === 'enum') {
131131
model.enums.push(modelProperty);
@@ -144,23 +144,23 @@ export const getModel = (
144144
}
145145

146146
if (definition.const !== undefined) {
147-
model.export = 'const';
148147
const definitionConst = definition.const;
149148
const modelConst = typeof definitionConst === 'string' ? `"${definitionConst}"` : `${definitionConst}`;
150-
model.type = modelConst;
151149
model.base = modelConst;
150+
model.export = 'const';
151+
model.type = modelConst;
152152
return model;
153153
}
154154

155155
// If the schema has a type than it can be a basic or generic type.
156156
if (definition.type) {
157157
const definitionType = getType(definition.type, definition.format);
158-
model.export = 'generic';
159-
model.type = definitionType.type;
160158
model.base = definitionType.base;
161-
model.template = definitionType.template;
162-
model.isNullable = definitionType.isNullable || model.isNullable;
159+
model.export = 'generic';
163160
model.imports.push(...definitionType.imports);
161+
model.isNullable = definitionType.isNullable || model.isNullable;
162+
model.template = definitionType.template;
163+
model.type = definitionType.type;
164164
model.default = getModelDefault(definition, model);
165165
return model;
166166
}

src/openApi/v3/parser/getModelComposition.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,21 +99,21 @@ export const getModelComposition = ({
9999
});
100100
} else {
101101
composition.properties.push({
102-
name: 'properties',
103-
export: 'interface',
104-
type: 'any',
105102
base: 'any',
106-
template: null,
107-
link: null,
108103
description: '',
104+
enum: [],
105+
enums: [],
106+
export: 'interface',
107+
imports: [],
109108
isDefinition: false,
110-
isReadOnly: false,
111109
isNullable: false,
110+
isReadOnly: false,
112111
isRequired: false,
113-
imports: [],
114-
enum: [],
115-
enums: [],
112+
link: null,
113+
name: 'properties',
116114
properties,
115+
template: null,
116+
type: 'any',
117117
});
118118
}
119119
}

src/templates/partials/exportInterface.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export type {{{name}}} = {
2222
{{/ifdef}}
2323
{{>isReadOnly}}{{{name}}}{{>isRequired}}: {{>type parent=../name}};
2424
{{/each}}
25-
};
25+
}{{>isNullable}};
2626
{{#if enums}}
2727
{{#unless @root.useUnionTypes}}
2828

0 commit comments

Comments
 (0)