Skip to content

Commit 7163a52

Browse files
committed
feat: Support x-nullable vendor extension
1 parent 84099ee commit 7163a52

File tree

7 files changed

+103
-6
lines changed

7 files changed

+103
-6
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,39 @@ enum EnumWithStrings {
328328
}
329329
```
330330

331+
### Nullable in OpenApi v2
332+
You can use the unofficial `x-nullable` backport in your specification to generate nullable properties in OpenApi v2.
333+
334+
```json
335+
{
336+
"ModelWithNullableString": {
337+
"required": ["requiredProp"],
338+
"description": "This is a model with one string property",
339+
"type": "object",
340+
"properties": {
341+
"prop": {
342+
"description": "This is a simple string property",
343+
"type": "string",
344+
"x-nullable": true
345+
},
346+
"requiredProp": {
347+
"description": "This is a simple string property",
348+
"type": "string",
349+
"x-nullable": true,
350+
}
351+
}
352+
}
353+
}
354+
```
355+
356+
Generated code:
357+
```typescript
358+
enum ModelWithNullableString {
359+
prop?: string | null,
360+
requiredProp: string | null
361+
}
362+
```
363+
331364

332365
### Authorization
333366
The OpenAPI generator supports Bearer Token authorization. In order to enable the sending

src/index.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import * as OpenAPI from './index';
33
describe('index', () => {
44
it('parses v2 without issues', async () => {
55
await OpenAPI.generate({
6-
input: './test/spec/v3.json',
7-
output: './generated/v3/',
6+
input: './test/spec/v2.json',
7+
output: './generated/v2/',
88
write: false,
99
});
1010
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Supported extension for enums
3+
*/
4+
export interface WithNullableExtension {
5+
'x-nullable'?: boolean;
6+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import type { Dictionary } from '../../../utils/types';
22
import type { WithEnumExtension } from './Extensions/WithEnumExtension';
3+
import type { WithNullableExtension } from './Extensions/WithNullableExtension';
34
import type { OpenApiExternalDocs } from './OpenApiExternalDocs';
45
import type { OpenApiReference } from './OpenApiReference';
56
import type { OpenApiXml } from './OpenApiXml';
67

78
/**
89
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#schemaObject
910
*/
10-
export interface OpenApiSchema extends OpenApiReference, WithEnumExtension {
11+
export interface OpenApiSchema extends OpenApiReference, WithEnumExtension, WithNullableExtension {
1112
title?: string;
1213
description?: string;
1314
default?: any;

src/openApi/v2/parser/getModelProperties.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema,
2626
isDefinition: false,
2727
isReadOnly: property.readOnly === true,
2828
isRequired: propertyRequired === true,
29-
isNullable: false,
29+
isNullable: property['x-nullable'] === true,
3030
format: property.format,
3131
maximum: property.maximum,
3232
exclusiveMaximum: property.exclusiveMaximum,
@@ -60,7 +60,7 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema,
6060
isDefinition: false,
6161
isReadOnly: property.readOnly === true,
6262
isRequired: propertyRequired === true,
63-
isNullable: false,
63+
isNullable: property['x-nullable'] === true,
6464
format: property.format,
6565
maximum: property.maximum,
6666
exclusiveMaximum: property.exclusiveMaximum,
@@ -84,6 +84,5 @@ export function getModelProperties(openApi: OpenApi, definition: OpenApiSchema,
8484
}
8585
}
8686
}
87-
8887
return models;
8988
}

test/__snapshots__/index.spec.js.snap

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ export type { ModelWithInteger } from './models/ModelWithInteger';
293293
export type { ModelWithLink } from './models/ModelWithLink';
294294
export type { ModelWithNestedEnums } from './models/ModelWithNestedEnums';
295295
export type { ModelWithNestedProperties } from './models/ModelWithNestedProperties';
296+
export type { ModelWithNullableString } from './models/ModelWithNullableString';
296297
export type { ModelWithOrderedProperties } from './models/ModelWithOrderedProperties';
297298
export type { ModelWithPattern } from './models/ModelWithPattern';
298299
export type { ModelWithProperties } from './models/ModelWithProperties';
@@ -335,6 +336,7 @@ export { $ModelWithInteger } from './schemas/$ModelWithInteger';
335336
export { $ModelWithLink } from './schemas/$ModelWithLink';
336337
export { $ModelWithNestedEnums } from './schemas/$ModelWithNestedEnums';
337338
export { $ModelWithNestedProperties } from './schemas/$ModelWithNestedProperties';
339+
export { $ModelWithNullableString } from './schemas/$ModelWithNullableString';
338340
export { $ModelWithOrderedProperties } from './schemas/$ModelWithOrderedProperties';
339341
export { $ModelWithPattern } from './schemas/$ModelWithPattern';
340342
export { $ModelWithProperties } from './schemas/$ModelWithProperties';
@@ -825,6 +827,26 @@ export interface ModelWithNestedProperties {
825827
"
826828
`;
827829

830+
exports[`v2 should generate: ./test/generated/v2/models/ModelWithNullableString.ts 1`] = `
831+
"/* istanbul ignore file */
832+
/* tslint:disable */
833+
/* eslint-disable */
834+
/**
835+
* This is a model with one string property
836+
*/
837+
export interface ModelWithNullableString {
838+
/**
839+
* This is a simple string property
840+
*/
841+
nullableProp?: string | null;
842+
/**
843+
* This is a simple string property
844+
*/
845+
nullableRequiredProp: string | null;
846+
}
847+
"
848+
`;
849+
828850
exports[`v2 should generate: ./test/generated/v2/models/ModelWithOrderedProperties.ts 1`] = `
829851
"/* istanbul ignore file */
830852
/* tslint:disable */
@@ -1354,6 +1376,25 @@ export const $ModelWithNestedProperties = {
13541376
};"
13551377
`;
13561378

1379+
exports[`v2 should generate: ./test/generated/v2/schemas/$ModelWithNullableString.ts 1`] = `
1380+
"/* istanbul ignore file */
1381+
/* tslint:disable */
1382+
/* eslint-disable */
1383+
export const $ModelWithNullableString = {
1384+
properties: {
1385+
nullableProp: {
1386+
type: 'string',
1387+
isNullable: true,
1388+
},
1389+
nullableRequiredProp: {
1390+
type: 'string',
1391+
isRequired: true,
1392+
isNullable: true,
1393+
},
1394+
},
1395+
};"
1396+
`;
1397+
13571398
exports[`v2 should generate: ./test/generated/v2/schemas/$ModelWithOrderedProperties.ts 1`] = `
13581399
"/* istanbul ignore file */
13591400
/* tslint:disable */

test/spec/v2.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,23 @@
858858
}
859859
}
860860
},
861+
"ModelWithNullableString": {
862+
"description": "This is a model with one string property",
863+
"type": "object",
864+
"required": ["nullableRequiredProp"],
865+
"properties": {
866+
"nullableProp": {
867+
"description": "This is a simple string property",
868+
"type": "string",
869+
"x-nullable": true
870+
},
871+
"nullableRequiredProp": {
872+
"description": "This is a simple string property",
873+
"type": "string",
874+
"x-nullable": true
875+
}
876+
}
877+
},
861878
"ModelWithEnum": {
862879
"description": "This is a model with one enum",
863880
"type": "object",

0 commit comments

Comments
 (0)