@penkov/swagger-code-gen 1.3.2 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/method.js +10 -4
- package/dist/parameter.js +27 -6
- package/dist/schemas.js +3 -2
- package/dist/templates/index.ejs +2 -1
- package/dist/templates/method.ejs +23 -18
- package/dist/templates/scats-method.ejs +3 -3
- package/package.json +2 -1
package/dist/method.js
CHANGED
|
@@ -9,7 +9,9 @@ export class Method {
|
|
|
9
9
|
this.method = method;
|
|
10
10
|
this.tags = option(def.tags).getOrElseValue([]);
|
|
11
11
|
this.summary = def.summary;
|
|
12
|
-
|
|
12
|
+
this.description = def.description;
|
|
13
|
+
this.operationId = option(def.operationId);
|
|
14
|
+
const parameters = Collection.from(option(def.parameters).getOrElseValue([]))
|
|
13
15
|
.map(p => Parameter.fromDefinition(p, schemasTypes, options))
|
|
14
16
|
.sort((a, b) => {
|
|
15
17
|
const r1 = a.required ? 1 : 0;
|
|
@@ -41,12 +43,15 @@ export class Method {
|
|
|
41
43
|
.orElseValue(mimeTypes.headOption)
|
|
42
44
|
.map(mt => SchemaFactory.build('body', body[mt].schema, schemasTypes, options));
|
|
43
45
|
});
|
|
46
|
+
this.bodyDescription = option(def.requestBody).flatMap(body => option(body.description));
|
|
44
47
|
const statusCodes = Collection.from(Object.keys(def.responses))
|
|
45
48
|
.map(x => parseInt(x));
|
|
46
49
|
const successCode = statusCodes
|
|
47
50
|
.filter(code => code / 100 === 2)
|
|
48
51
|
.minByOption(identity);
|
|
49
|
-
const respDef = successCode.map(_ => def.responses[_])
|
|
52
|
+
const respDef = successCode.map(_ => def.responses[_])
|
|
53
|
+
.orElse(() => option(def.responses['default']))
|
|
54
|
+
.getOrElseValue(def.responses[statusCodes.head]);
|
|
50
55
|
const mimeTypes = option(respDef.content)
|
|
51
56
|
.map(content => Collection.from(Object.keys(content)).toMap(mimeType => [mimeType, content[mimeType]])).getOrElseValue(HashMap.empty);
|
|
52
57
|
this.response = mimeTypes.get('application/json')
|
|
@@ -63,12 +68,13 @@ export class Method {
|
|
|
63
68
|
asProperty: Property.fromDefinition('UNKNOWN', { type: 'any' }, schemasTypes, options),
|
|
64
69
|
responseType: 'any'
|
|
65
70
|
}));
|
|
71
|
+
this.wrapParamsInObject = this.parameters.size > 2 || (this.body.isDefined) && this.parameters.nonEmpty;
|
|
66
72
|
}
|
|
67
73
|
get endpointName() {
|
|
68
|
-
return `${this.method}${Method.pathToName(this.path)}
|
|
74
|
+
return this.operationId.getOrElse(() => `${this.method}${Method.pathToName(this.path)}`);
|
|
69
75
|
}
|
|
70
76
|
get pathWithSubstitutions() {
|
|
71
|
-
const paramPrefix = `${this.
|
|
77
|
+
const paramPrefix = `${this.wrapParamsInObject ? 'params.' : ''}`;
|
|
72
78
|
return this.path.replace(/\{(\w+?)\}/g, (matched, group) => {
|
|
73
79
|
const remappedName = this.parameters.find(p => p.name === group && p.in === 'path')
|
|
74
80
|
.map(_ => _.uniqueName)
|
package/dist/parameter.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { SchemaEnum, SchemaFactory, SchemaObject } from './schemas.js';
|
|
2
|
-
import { Collection, identity, option } from 'scats';
|
|
2
|
+
import { Collection, identity, none, option } from 'scats';
|
|
3
3
|
import { Method } from './method.js';
|
|
4
4
|
import { Property } from './property.js';
|
|
5
5
|
export class Parameter {
|
|
6
|
-
constructor(name, uniqueName, inValue, jsType, required, description) {
|
|
6
|
+
constructor(name, uniqueName, inValue, jsType, required, defaultValue, description) {
|
|
7
7
|
this.name = name;
|
|
8
8
|
this.uniqueName = uniqueName;
|
|
9
9
|
this.jsType = jsType;
|
|
10
10
|
this.required = required;
|
|
11
|
+
this.defaultValue = defaultValue;
|
|
11
12
|
this.description = description;
|
|
12
13
|
this.in = inValue;
|
|
13
14
|
}
|
|
@@ -15,14 +16,33 @@ export class Parameter {
|
|
|
15
16
|
const name = Parameter.toJSName(def.name);
|
|
16
17
|
const inValue = def.in;
|
|
17
18
|
const desc = option(def.description);
|
|
18
|
-
|
|
19
|
+
let defaultValue = none;
|
|
19
20
|
const schema = SchemaFactory.build(def.name, def.schema, schemas, options);
|
|
20
21
|
let jsType;
|
|
21
22
|
if (schema instanceof SchemaObject) {
|
|
22
23
|
jsType = schema.type;
|
|
23
24
|
}
|
|
24
25
|
else if (schema instanceof SchemaEnum) {
|
|
25
|
-
|
|
26
|
+
if (schemas.containsKey(schema.name)) {
|
|
27
|
+
jsType = schema.name;
|
|
28
|
+
}
|
|
29
|
+
else if (schema.type === 'string') {
|
|
30
|
+
jsType = `${schema.values.map(x => `'${x}'`).mkString(' | ')}`;
|
|
31
|
+
}
|
|
32
|
+
else if (schema.type === 'integer') {
|
|
33
|
+
jsType = `${schema.values.map(x => `${x}`).mkString(' | ')}`;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
jsType = schema.type;
|
|
37
|
+
}
|
|
38
|
+
defaultValue = schema.defaultValue.map(x => {
|
|
39
|
+
if (schema.type === 'string') {
|
|
40
|
+
return `'${x}'`;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return x;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
26
46
|
}
|
|
27
47
|
else if (schema instanceof Property) {
|
|
28
48
|
jsType = schema.jsType;
|
|
@@ -30,7 +50,8 @@ export class Parameter {
|
|
|
30
50
|
else {
|
|
31
51
|
throw new Error('Unknown schema type');
|
|
32
52
|
}
|
|
33
|
-
|
|
53
|
+
const required = option(def.required).exists(identity) || defaultValue.nonEmpty;
|
|
54
|
+
return new Parameter(name, name, inValue, jsType, required, defaultValue, desc);
|
|
34
55
|
}
|
|
35
56
|
static toJSName(path) {
|
|
36
57
|
const tokens = Collection.from(path.split(/\W/)).filter(t => t.length > 0);
|
|
@@ -39,6 +60,6 @@ export class Parameter {
|
|
|
39
60
|
}).mkString();
|
|
40
61
|
}
|
|
41
62
|
copy(p) {
|
|
42
|
-
return new Parameter(option(p.name).getOrElseValue(this.name), option(p.uniqueName).getOrElseValue(this.uniqueName), option(p.in).getOrElseValue(this.in), option(p.jsType).getOrElseValue(this.jsType), option(p.required).getOrElseValue(this.required), option(p.description).getOrElseValue(this.description));
|
|
63
|
+
return new Parameter(option(p.name).getOrElseValue(this.name), option(p.uniqueName).getOrElseValue(this.uniqueName), option(p.in).getOrElseValue(this.in), option(p.jsType).getOrElseValue(this.jsType), option(p.required).getOrElseValue(this.required), option(p.defaultValue).getOrElseValue(this.defaultValue), option(p.description).getOrElseValue(this.description));
|
|
43
64
|
}
|
|
44
65
|
}
|
package/dist/schemas.js
CHANGED
|
@@ -37,15 +37,16 @@ export class SchemaFactory {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
export class SchemaEnum {
|
|
40
|
-
constructor(name, title, type, values) {
|
|
40
|
+
constructor(name, title, type, defaultValue, values) {
|
|
41
41
|
this.name = name;
|
|
42
42
|
this.title = title;
|
|
43
43
|
this.type = type;
|
|
44
|
+
this.defaultValue = defaultValue;
|
|
44
45
|
this.values = values;
|
|
45
46
|
this.schemaType = 'enum';
|
|
46
47
|
}
|
|
47
48
|
static fromDefinition(name, def) {
|
|
48
|
-
return new SchemaEnum(name, def.title, def.type, option(def.enum).map(Collection.from).getOrElseValue(Nil));
|
|
49
|
+
return new SchemaEnum(name, def.title, def.type, option(def.default), option(def.enum).map(Collection.from).getOrElseValue(Nil));
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
export class SchemaObject {
|
package/dist/templates/index.ejs
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
*********************************************************
|
|
12
12
|
*********************************************************/
|
|
13
13
|
import fetch, {Request, Response} from 'node-fetch';
|
|
14
|
+
import {option, Option} from 'scats';
|
|
14
15
|
<% if (scats) {%>
|
|
15
|
-
import {
|
|
16
|
+
import {Collection, Try, TryLike, none} from 'scats';
|
|
16
17
|
<% } %>
|
|
17
18
|
|
|
18
19
|
export interface RequestOptions {
|
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* <%= method.method.toUpperCase() %> <%= method.path %>
|
|
3
|
-
<% if (method.
|
|
3
|
+
<% if (method.summary) { -%>
|
|
4
|
+
* @summary <%= method.summary %>
|
|
5
|
+
<% } -%>
|
|
6
|
+
<% if (method.description) { -%>
|
|
7
|
+
* @description <%= method.description %>
|
|
8
|
+
<% } -%>
|
|
9
|
+
<% if (method.wrapParamsInObject) { -%>
|
|
4
10
|
* @param {Object} params
|
|
5
11
|
<% } -%>
|
|
6
12
|
<% method.parameters.foreach(p => { -%>
|
|
7
|
-
* @param {<%= p.jsType %>} <%= method.
|
|
13
|
+
* @param {<%= p.jsType %>} <%= method.wrapParamsInObject ? 'params.' : '' %><%= p.uniqueName %> <%= p.description.getOrElseValue('')%>
|
|
8
14
|
<% }); -%>
|
|
9
15
|
<%_ if (method.body.nonEmpty) { -%>
|
|
10
|
-
* @param {<%= method.body.get.
|
|
16
|
+
* @param {<%= method.body.get.jsType %>} body <%= method.bodyDescription.getOrElseValue('') %>
|
|
11
17
|
<%_ } -%>
|
|
12
18
|
* @param {RequestOptions} requestOptions Additional request params
|
|
13
|
-
* @summary <%= method.summary %>
|
|
14
19
|
* @return {<%= method.response.responseType %>} <%= method.response.description %>
|
|
15
20
|
*/
|
|
16
21
|
export async function <%= method.endpointName %>(
|
|
17
|
-
<%_ if (method.
|
|
22
|
+
<%_ if (!method.wrapParamsInObject) { -%>
|
|
18
23
|
<%_ method.parameters.foreach(p => { -%>
|
|
19
|
-
<%= p.uniqueName %><%= p.required ? '' : '?'%>: <%- p.jsType %>,
|
|
24
|
+
<%= p.uniqueName %><%= p.required ? '' : '?'%>: <%- p.jsType %><%- p.defaultValue.map(x => ` = ${x}`).getOrElseValue('') %>,
|
|
20
25
|
<%_ }) -%>
|
|
21
26
|
<%_ } else { -%>
|
|
22
27
|
params: {
|
|
@@ -26,7 +31,7 @@ export async function <%= method.endpointName %>(
|
|
|
26
31
|
},
|
|
27
32
|
<%_ } -%>
|
|
28
33
|
<%_ if (method.body.nonEmpty) { -%>
|
|
29
|
-
body:
|
|
34
|
+
body: <%- method.body.get.jsType %>,
|
|
30
35
|
<%_ } -%>
|
|
31
36
|
requestOptions: RequestOptions = defaultRequestOptions()
|
|
32
37
|
): Promise<<%- method.response.responseType %>> {
|
|
@@ -35,17 +40,17 @@ export async function <%= method.endpointName %>(
|
|
|
35
40
|
const queryParams = [];
|
|
36
41
|
<%_ method.parameters.filter(x => x.in === 'query' && x.required).foreach(p => { -%>
|
|
37
42
|
<%_ if (p.jsType === 'string') { -%>
|
|
38
|
-
queryParams.push(`<%= p.name %>=${encodeURIComponent(<%= method.
|
|
43
|
+
queryParams.push(`<%= p.name %>=${encodeURIComponent(<%= method.wrapParamsInObject ? 'params.' : '' %><%= p.uniqueName %>)}`);
|
|
39
44
|
<%_ } else { -%>
|
|
40
|
-
queryParams.push(`<%= p.name %>=${<%= method.
|
|
45
|
+
queryParams.push(`<%= p.name %>=${<%= method.wrapParamsInObject ? 'params.' : '' %><%= p.uniqueName %>}`);
|
|
41
46
|
<%_ } -%>
|
|
42
47
|
<%_ }) -%>
|
|
43
48
|
<%_ method.parameters.filter(x => x.in === 'query' && !x.required).foreach(p => { -%>
|
|
44
|
-
if (!!<%= method.
|
|
49
|
+
if (!!<%= method.wrapParamsInObject ? 'params.' : '' %><%= p.uniqueName %>) {
|
|
45
50
|
<%_ if (p.jsType === 'string') { -%>
|
|
46
|
-
queryParams.push(`<%= p.name %>=${encodeURIComponent(<%= method.
|
|
51
|
+
queryParams.push(`<%= p.name %>=${encodeURIComponent(<%= method.wrapParamsInObject ? 'params.' : '' %><%= p.uniqueName %>)}`);
|
|
47
52
|
<%_ } else { -%>
|
|
48
|
-
queryParams.push(`<%= p.name %>=${<%= method.
|
|
53
|
+
queryParams.push(`<%= p.name %>=${<%= method.wrapParamsInObject ? 'params.' : '' %><%= p.uniqueName %>}`);
|
|
49
54
|
<%_ } -%>
|
|
50
55
|
}
|
|
51
56
|
<%_ }) -%>
|
|
@@ -60,20 +65,20 @@ export async function <%= method.endpointName %>(
|
|
|
60
65
|
...option(requestOptions.headers).getOrElseValue({}),
|
|
61
66
|
<%_ if (method.parameters.filter(x => x.in === 'header').nonEmpty) { -%>
|
|
62
67
|
<%_ method.parameters.filter(x => x.in === 'header').foreach(p => { -%>
|
|
63
|
-
<%= p.name %>: <%= method.
|
|
68
|
+
<%= p.name %>: <%= method.wrapParamsInObject ? 'params.' : '' %><%= p.uniqueName %>
|
|
64
69
|
<%_ }) -%>
|
|
65
70
|
<%_ } -%>
|
|
66
71
|
}
|
|
67
72
|
});
|
|
68
|
-
const
|
|
69
|
-
const resp = await fetch(
|
|
73
|
+
const preProcessed = option(requestOptions.preProcessRequest).map(cb => cb(request)).getOrElseValue(request);
|
|
74
|
+
const resp = await fetch(preProcessed);
|
|
70
75
|
if (resp.ok) {
|
|
71
|
-
const
|
|
72
|
-
.map(cb => cb(
|
|
76
|
+
const postProcessed = option(requestOptions.postProcessResponse)
|
|
77
|
+
.map(cb => cb(preProcessed, resp))
|
|
73
78
|
.getOrElseValue(resp);
|
|
74
79
|
const json = option(resp.headers.get('content-length'))
|
|
75
80
|
.map(x => parseInt(x))
|
|
76
|
-
.getOrElseValue(0) > 0 ? await
|
|
81
|
+
.getOrElseValue(0) > 0 ? await postProcessed.json() : null;
|
|
77
82
|
return json as <%- method.response.responseType %>;
|
|
78
83
|
} else {
|
|
79
84
|
throw resp;
|
|
@@ -6,7 +6,7 @@ export class ApiClient {
|
|
|
6
6
|
|
|
7
7
|
<% methods.foreach(method => { %>
|
|
8
8
|
async <%= method.endpointName %>(
|
|
9
|
-
<%_ if (method.
|
|
9
|
+
<%_ if (!method.wrapParamsInObject) { -%>
|
|
10
10
|
<%_ method.parameters.foreach(p => { -%>
|
|
11
11
|
<%= p.uniqueName %>: <%- p.required && !p.nullable ? p.jsType : `Option<${p.jsType}> = none` %>,
|
|
12
12
|
<%_ }) -%>
|
|
@@ -18,13 +18,13 @@ export class ApiClient {
|
|
|
18
18
|
},
|
|
19
19
|
<%_ } -%>
|
|
20
20
|
<%_ method.body.foreach(body => { -%>
|
|
21
|
-
body:
|
|
21
|
+
body: <%- body.jsType %>,
|
|
22
22
|
<%_ }); -%>
|
|
23
23
|
requestOptions: RequestOptions = this.requestOptions
|
|
24
24
|
): Promise<TryLike<<%- method.response.asProperty.scatsWrapperType %>>> {
|
|
25
25
|
return (await Try.promise(() =>
|
|
26
26
|
<%= method.endpointName %>(
|
|
27
|
-
<%_ if (method.
|
|
27
|
+
<%_ if (!method.wrapParamsInObject) { -%>
|
|
28
28
|
<%_ method.parameters.foreach(p => { -%>
|
|
29
29
|
<%= p.uniqueName %><%- p.required && !p.nullable ? '' : `.orUndefined` %>,
|
|
30
30
|
<%_ }) -%>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@penkov/swagger-code-gen",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"generate-client": "./dist/cli.mjs"
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/papirosko/swagger-code-gen#readme",
|
|
24
24
|
"scripts": {
|
|
25
|
+
"test:petstore": "mkdir -p tmp && ts-node-esm ./src/cli.mjs --enableScats --url https://petstore3.swagger.io/api/v3/openapi.json tmp/petstore.ts",
|
|
25
26
|
"clean": "rimraf dist",
|
|
26
27
|
"lint": "eslint \"{src,test}/**/*.ts\" --fix",
|
|
27
28
|
"prebuild": "npm run lint && npm run clean",
|