@penkov/swagger-code-gen 1.13.0 → 1.15.0
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 +33 -4
- package/dist/templates/index.ejs +35 -5
- package/dist/templates/method.ejs +2 -2
- package/package.json +3 -3
package/dist/method.js
CHANGED
|
@@ -7,6 +7,12 @@ export const SHARED_BODIES_PREFIX = '#/components/requestBodies/';
|
|
|
7
7
|
const sortByIn = HashMap.of(['path', 0], ['query', 1], ['header', 2], ['cookie', 3], ['body', 4]);
|
|
8
8
|
export const supportedBodyMimeTypes = HashMap.of(['application/json', 'Json'], ['application/x-www-form-urlencoded', 'Form'], ['multipart/form-data', 'File'], ['application/octet-stream', 'Binary']);
|
|
9
9
|
export class Method {
|
|
10
|
+
static parseModeByMimeType(mimeType) {
|
|
11
|
+
if (mimeType.startsWith('text/') || mimeType.includes('xml')) {
|
|
12
|
+
return 'text';
|
|
13
|
+
}
|
|
14
|
+
return 'json';
|
|
15
|
+
}
|
|
10
16
|
constructor(path, method, def, schemasTypes, options, pool) {
|
|
11
17
|
this.path = path;
|
|
12
18
|
this.method = method;
|
|
@@ -132,10 +138,27 @@ export class Method {
|
|
|
132
138
|
.getOrElseValue({});
|
|
133
139
|
const mimeTypes = option(respDef.content)
|
|
134
140
|
.map(content => Collection.from(Object.keys(content)).toMap(mimeType => [mimeType, content[mimeType]])).getOrElseValue(HashMap.empty);
|
|
135
|
-
|
|
136
|
-
.
|
|
137
|
-
.
|
|
141
|
+
const responseMimeType = mimeTypes.get('application/json')
|
|
142
|
+
.map(_ => 'application/json')
|
|
143
|
+
.orElse(() => mimeTypes.keySet.headOption)
|
|
144
|
+
.getOrElseValue('application/json');
|
|
145
|
+
const responseParseMode = Method.parseModeByMimeType(responseMimeType);
|
|
146
|
+
this.response = mimeTypes.get(responseMimeType)
|
|
147
|
+
.filter(p => option(p.schema).isDefined || responseParseMode === 'text')
|
|
138
148
|
.map(p => {
|
|
149
|
+
if (responseParseMode === 'text') {
|
|
150
|
+
const r = Property.fromDefinition('', '', { type: 'string' }, schemasTypes, options).copy({
|
|
151
|
+
nullable: false,
|
|
152
|
+
required: true,
|
|
153
|
+
});
|
|
154
|
+
return {
|
|
155
|
+
asProperty: r,
|
|
156
|
+
responseType: 'string',
|
|
157
|
+
description: respDef.description,
|
|
158
|
+
mimeType: responseMimeType,
|
|
159
|
+
parseMode: responseParseMode,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
139
162
|
if (p.schema.type === 'object' && p.schema['properties'] && Object.keys(p.schema['properties']).length > 0) {
|
|
140
163
|
const inPlaceObject = NameUtils.normaliseClassname(def.operationId + 'Response$' + method);
|
|
141
164
|
const r = Property.fromDefinition(inPlaceObject, '', {
|
|
@@ -149,7 +172,9 @@ export class Method {
|
|
|
149
172
|
asProperty: r,
|
|
150
173
|
responseType: inPlaceObject,
|
|
151
174
|
description: respDef.description,
|
|
152
|
-
inPlace: p.schema
|
|
175
|
+
inPlace: p.schema,
|
|
176
|
+
mimeType: responseMimeType,
|
|
177
|
+
parseMode: responseParseMode,
|
|
153
178
|
};
|
|
154
179
|
}
|
|
155
180
|
else {
|
|
@@ -161,12 +186,16 @@ export class Method {
|
|
|
161
186
|
asProperty: r,
|
|
162
187
|
responseType: r.jsType,
|
|
163
188
|
description: respDef.description,
|
|
189
|
+
mimeType: responseMimeType,
|
|
190
|
+
parseMode: responseParseMode,
|
|
164
191
|
};
|
|
165
192
|
}
|
|
166
193
|
})
|
|
167
194
|
.getOrElseValue(({
|
|
168
195
|
asProperty: Property.fromDefinition('', 'UNKNOWN', { type: 'any' }, schemasTypes, options),
|
|
169
196
|
responseType: 'any',
|
|
197
|
+
mimeType: responseMimeType,
|
|
198
|
+
parseMode: responseParseMode,
|
|
170
199
|
}));
|
|
171
200
|
this.wrapParamsInObject = this.parameters.size > 2 || (this.body.nonEmpty) && this.parameters.nonEmpty;
|
|
172
201
|
}
|
package/dist/templates/index.ejs
CHANGED
|
@@ -86,20 +86,52 @@ function objectToFormWwwEncoded(o: Record<string, any>): string {
|
|
|
86
86
|
.join('&');
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
type ResponseParseMode = 'json' | 'text';
|
|
90
|
+
|
|
91
|
+
function normaliseCharset(charset: string): string {
|
|
92
|
+
const normalized = charset.trim().toLowerCase();
|
|
93
|
+
if (normalized === 'cp1251') {
|
|
94
|
+
return 'windows-1251';
|
|
95
|
+
}
|
|
96
|
+
return normalized;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function extractCharset(contentType: string | null): string {
|
|
100
|
+
if (contentType == null) {
|
|
101
|
+
return 'utf-8';
|
|
102
|
+
}
|
|
103
|
+
const match = contentType.match(/charset\s*=\s*("?)([^";\s]+)\1/i);
|
|
104
|
+
return normaliseCharset(match?.[2] || 'utf-8');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function readResponseText(response: Response): Promise<string> {
|
|
108
|
+
const payload = await response.arrayBuffer();
|
|
109
|
+
const charset = extractCharset(response.headers.get('content-type'));
|
|
110
|
+
try {
|
|
111
|
+
return new TextDecoder(charset).decode(payload);
|
|
112
|
+
} catch {
|
|
113
|
+
return new TextDecoder('utf-8').decode(payload);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function requestImpl<T>(request: Request, requestOptions: RequestOptions, parseMode: ResponseParseMode = 'json'): Promise<T> {
|
|
90
118
|
const preProcessed = requestOptions.preProcessRequest ? await requestOptions.preProcessRequest(request) : request;
|
|
91
119
|
const resp = await fetch(preProcessed);
|
|
92
120
|
const postProcessed = requestOptions.postProcessResponse ? await requestOptions.postProcessResponse(preProcessed, resp) : resp;
|
|
93
121
|
if (postProcessed.ok) {
|
|
122
|
+
if (parseMode === 'text') {
|
|
123
|
+
return (await readResponseText(postProcessed)) as T;
|
|
124
|
+
}
|
|
125
|
+
|
|
94
126
|
let json: any = null;
|
|
95
127
|
if (postProcessed.headers.has('content-length')) {
|
|
96
128
|
const ctLent = postProcessed.headers.get('content-length');
|
|
97
129
|
const ct = ctLent != null ? parseInt(ctLent): 0;
|
|
98
130
|
if (ct > 0) {
|
|
99
|
-
json = await postProcessed.
|
|
131
|
+
json = JSON.parse((await readResponseText(postProcessed)).replace(/^\uFEFF/, ''))
|
|
100
132
|
}
|
|
101
133
|
} else {
|
|
102
|
-
json = await postProcessed.
|
|
134
|
+
json = JSON.parse((await readResponseText(postProcessed)).replace(/^\uFEFF/, ''))
|
|
103
135
|
}
|
|
104
136
|
return json as T;
|
|
105
137
|
} else {
|
|
@@ -139,5 +171,3 @@ methods.foreach(method => {
|
|
|
139
171
|
<%- include('scats-api-client.ejs'); %>
|
|
140
172
|
|
|
141
173
|
<% } %>
|
|
142
|
-
|
|
143
|
-
|
|
@@ -76,7 +76,7 @@ export async function <%= method.endpointName %><%= body.map(b => b.suffix).getO
|
|
|
76
76
|
|
|
77
77
|
const headers: HeadersInit = {
|
|
78
78
|
...requestOptions.headers || {},
|
|
79
|
-
'Accept': '
|
|
79
|
+
'Accept': '<%= method.response.mimeType %>',
|
|
80
80
|
<%_ if (body.nonEmpty && body.get.mimeType !== 'multipart/form-data') {%>
|
|
81
81
|
'Content-Type': '<%= body.get.mimeType %>',
|
|
82
82
|
<%_ } -%>
|
|
@@ -97,5 +97,5 @@ export async function <%= method.endpointName %><%= body.map(b => b.suffix).getO
|
|
|
97
97
|
signal: requestOptions.signal,
|
|
98
98
|
headers: headers
|
|
99
99
|
});
|
|
100
|
-
return requestImpl<<%- method.response.responseType %>>(request, requestOptions);
|
|
100
|
+
return requestImpl<<%- method.response.responseType %>>(request, requestOptions, '<%= method.response.parseMode %>');
|
|
101
101
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@penkov/swagger-code-gen",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
|
-
"generate-client": "
|
|
6
|
+
"generate-client": "dist/cli.mjs"
|
|
7
7
|
},
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/papirosko/swagger-code-gen"
|
|
10
|
+
"url": "git+https://github.com/papirosko/swagger-code-gen.git"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"swagger",
|