Skip to content

Commit d00e9c8

Browse files
committed
feat: const keyword OpenAPI 3.0 draft
1 parent f5960b9 commit d00e9c8

File tree

8 files changed

+341
-14
lines changed

8 files changed

+341
-14
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# next release
22

3+
feat: `const` keyword OpenAPI 3.0 draft
34
fix: problem with using `anyOf`
45
feat: `--extract-responses` (nodejs: `extractResponses`) option to extract all schemas from `/components/responses`
56

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"test:--extract-response-error": "node tests/spec/extractResponseError/test.js",
4141
"test:--enum-names-as-values": "node tests/spec/enumNamesAsValues/test.js",
4242
"test:--default-response": "node tests/spec/defaultResponse/test.js",
43+
"test:const-keyword": "node tests/spec/const-keyword/test.js",
4344
"test:--js": "node tests/spec/js/test.js",
4445
"test:jsSingleHttpClientModular": "node tests/spec/jsSingleHttpClientModular/test.js",
4546
"test:--js--axios": "node tests/spec/jsAxios/test.js",

src/configuration.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ class CodeGenConfig {
241241
/**
242242
* $A
243243
*/
244-
NullValue: (content) => content,
244+
NullValue: (content) => `null`,
245245
/**
246246
* $A1 | $A2
247247
*/

src/schema-parser/schema-utils.js

+46-13
Original file line numberDiff line numberDiff line change
@@ -248,24 +248,32 @@ class SchemaUtils {
248248
);
249249
}
250250

251-
const primitiveType = this.getSchemaPrimitiveType(schema);
252-
253-
if (primitiveType == null) return this.config.Ts.Keyword.Any;
254-
255251
let resultType;
256252

257-
const typeAlias =
258-
_.get(this.config.primitiveTypes, [primitiveType, schema.format]) ||
259-
_.get(this.config.primitiveTypes, [primitiveType, '$default']) ||
260-
this.config.primitiveTypes[primitiveType];
261-
262-
if (_.isFunction(typeAlias)) {
263-
resultType = typeAlias(schema, this);
253+
if (this.isConstantSchema(schema)) {
254+
resultType = this.formatJsValue(schema.const);
264255
} else {
265-
resultType = typeAlias || primitiveType;
256+
const primitiveType = this.getSchemaPrimitiveType(schema);
257+
258+
if (primitiveType == null) {
259+
return this.config.Ts.Keyword.Any;
260+
}
261+
262+
const typeAlias =
263+
_.get(this.config.primitiveTypes, [primitiveType, schema.format]) ||
264+
_.get(this.config.primitiveTypes, [primitiveType, '$default']) ||
265+
this.config.primitiveTypes[primitiveType];
266+
267+
if (_.isFunction(typeAlias)) {
268+
resultType = typeAlias(schema, this);
269+
} else {
270+
resultType = typeAlias || primitiveType;
271+
}
266272
}
267273

268-
if (!resultType) return this.config.Ts.Keyword.Any;
274+
if (!resultType) {
275+
return this.config.Ts.Keyword.Any;
276+
}
269277

270278
return this.checkAndAddRequiredKeys(
271279
schema,
@@ -284,6 +292,31 @@ class SchemaUtils {
284292
),
285293
);
286294
};
295+
296+
isConstantSchema(schema) {
297+
return 'const' in schema;
298+
}
299+
300+
formatJsValue = (value) => {
301+
switch (typeof value) {
302+
case 'string': {
303+
return this.config.Ts.StringValue(value);
304+
}
305+
case 'boolean': {
306+
return this.config.Ts.BooleanValue(value);
307+
}
308+
case 'number': {
309+
return this.config.Ts.NumberValue(value);
310+
}
311+
default: {
312+
if (value === null) {
313+
return this.config.Ts.NullValue(value);
314+
}
315+
316+
return this.config.Ts.Keyword.Any;
317+
}
318+
}
319+
};
287320
}
288321

289322
module.exports = {

tests/spec/const-keyword/expected.ts

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/* eslint-disable */
2+
/* tslint:disable */
3+
/*
4+
* ---------------------------------------------------------------
5+
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
6+
* ## ##
7+
* ## AUTHOR: acacode ##
8+
* ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
9+
* ---------------------------------------------------------------
10+
*/
11+
12+
export interface ObjTest {
13+
/**
14+
* title
15+
* description
16+
* @default "main"
17+
*/
18+
page_type?: "main";
19+
/**
20+
* title
21+
* description
22+
*/
23+
page_type_nullable?: "main" | null;
24+
}
25+
26+
/**
27+
* title
28+
* description
29+
* @default "string"
30+
*/
31+
export type TestString = "string";
32+
33+
/**
34+
* title
35+
* description
36+
*/
37+
export type TestStringNullable = "string" | null;
38+
39+
/**
40+
* title
41+
* description
42+
*/
43+
export type TestBooleanNullable = false | null;
44+
45+
/**
46+
* title
47+
* description
48+
* @default false
49+
*/
50+
export type TestBooleanFalse = false;
51+
52+
/**
53+
* title
54+
* description
55+
* @default true
56+
*/
57+
export type TestBooleanTrue = true;
58+
59+
/**
60+
* title
61+
* description
62+
* @default 5
63+
*/
64+
export type TestNumber5 = 5;
65+
66+
/**
67+
* title
68+
* description
69+
*/
70+
export type TestNumberNullable = 666 | null;
71+
72+
/**
73+
* title
74+
* description
75+
* @default 0
76+
*/
77+
export type TestNumber0 = 0;
78+
79+
/**
80+
* title
81+
* description
82+
* @default 10
83+
*/
84+
export type TestNumber10 = 10;
85+
86+
/**
87+
* title
88+
* description
89+
* @default null
90+
*/
91+
export type TestNull = null;

tests/spec/const-keyword/schema.json

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "Nullable Refs Example",
5+
"version": "1.0.0"
6+
},
7+
"components": {
8+
"schemas": {
9+
"obj-test": {
10+
"type": "object",
11+
"properties": {
12+
"page_type": {
13+
"const": "main",
14+
"default": "main",
15+
"description": "description",
16+
"title": "title"
17+
},
18+
"page_type_nullable": {
19+
"const": "main",
20+
"description": "description",
21+
"title": "title",
22+
"nullable": true
23+
}
24+
}
25+
},
26+
"test-string": {
27+
"const": "string",
28+
"default": "string",
29+
"description": "description",
30+
"title": "title"
31+
},
32+
"test-string-nullable": {
33+
"const": "string",
34+
"description": "description",
35+
"title": "title",
36+
"nullable": true
37+
},
38+
"test-boolean-nullable": {
39+
"const": false,
40+
"description": "description",
41+
"title": "title",
42+
"nullable": true
43+
},
44+
"test-boolean-false": {
45+
"const": false,
46+
"default": false,
47+
"description": "description",
48+
"title": "title"
49+
},
50+
"test-boolean-true": {
51+
"const": true,
52+
"default": true,
53+
"description": "description",
54+
"title": "title"
55+
},
56+
"test-number-5": {
57+
"const": 5,
58+
"default": 5,
59+
"description": "description",
60+
"title": "title"
61+
},
62+
"test-number-nullable": {
63+
"const": 666,
64+
"description": "description",
65+
"title": "title",
66+
"nullable": true,
67+
},
68+
"test-number-0": {
69+
"const": 0,
70+
"default": 0,
71+
"description": "description",
72+
"title": "title"
73+
},
74+
"test-number-10": {
75+
"const": 10,
76+
"default": 10,
77+
"description": "description",
78+
"title": "title"
79+
},
80+
"test-null": {
81+
"const": null,
82+
"default": null,
83+
"description": "description",
84+
"title": "title"
85+
}
86+
}
87+
}
88+
}

tests/spec/const-keyword/schema.ts

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/* eslint-disable */
2+
/* tslint:disable */
3+
/*
4+
* ---------------------------------------------------------------
5+
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
6+
* ## ##
7+
* ## AUTHOR: acacode ##
8+
* ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
9+
* ---------------------------------------------------------------
10+
*/
11+
12+
export interface ObjTest {
13+
/**
14+
* title
15+
* description
16+
* @default "main"
17+
*/
18+
page_type?: "main";
19+
/**
20+
* title
21+
* description
22+
*/
23+
page_type_nullable?: "main" | null;
24+
}
25+
26+
/**
27+
* title
28+
* description
29+
* @default "string"
30+
*/
31+
export type TestString = "string";
32+
33+
/**
34+
* title
35+
* description
36+
*/
37+
export type TestStringNullable = "string" | null;
38+
39+
/**
40+
* title
41+
* description
42+
*/
43+
export type TestBooleanNullable = false | null;
44+
45+
/**
46+
* title
47+
* description
48+
* @default false
49+
*/
50+
export type TestBooleanFalse = false;
51+
52+
/**
53+
* title
54+
* description
55+
* @default true
56+
*/
57+
export type TestBooleanTrue = true;
58+
59+
/**
60+
* title
61+
* description
62+
* @default 5
63+
*/
64+
export type TestNumber5 = 5;
65+
66+
/**
67+
* title
68+
* description
69+
*/
70+
export type TestNumberNullable = 666 | null;
71+
72+
/**
73+
* title
74+
* description
75+
* @default 0
76+
*/
77+
export type TestNumber0 = 0;
78+
79+
/**
80+
* title
81+
* description
82+
* @default 10
83+
*/
84+
export type TestNumber10 = 10;
85+
86+
/**
87+
* title
88+
* description
89+
* @default null
90+
*/
91+
export type TestNull = null;

tests/spec/const-keyword/test.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const { generateApiForTest } = require("../../helpers/generateApiForTest");
2+
const { resolve } = require("path");
3+
const validateGeneratedModule = require("../../helpers/validateGeneratedModule");
4+
const assertGeneratedModule = require("../../helpers/assertGeneratedModule");
5+
const createSchemaInfos = require("../../helpers/createSchemaInfos");
6+
7+
const schemas = createSchemaInfos({ absolutePathToSchemas: resolve(__dirname, "./") });
8+
9+
schemas.forEach(({ absolutePath, apiFileName }) => {
10+
generateApiForTest({
11+
testName: "const-keyword test",
12+
silent: true,
13+
name: apiFileName,
14+
input: absolutePath,
15+
output: resolve(__dirname, "./"),
16+
addReadonly: true,
17+
generateClient: false,
18+
}).then(() => {
19+
validateGeneratedModule(resolve(__dirname, `./${apiFileName}`));
20+
assertGeneratedModule(resolve(__dirname, `./${apiFileName}`), resolve(__dirname, `./expected.ts`));
21+
});
22+
});

0 commit comments

Comments
 (0)