Skip to content

Commit 0f6a69c

Browse files
authored
Release 4.4.0 (#148)
* fix: problem with generation form urlencoded request body (#146 issue) * bump: up version to 4.4.0
1 parent 34b5379 commit 0f6a69c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1059
-673
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
# next release
22

3-
# 4.3.0
3+
# 4.4.0
44

55
Fixes:
66
- Client generation for `Content-Type: application/x-www-form-urlencoded` (issue #146, thanks @Larox)
7+
8+
Internal:
9+
- Changed templates:
10+
- `http-client.eta`
11+
- `procedure-call.eta`
12+
13+
# 4.3.0
14+
15+
Fixes:
716
- enum + nullable: true doesn't compute the good type (issue #145, thanks @RoXuS)
817
- Underscores are omitted from enum keys (issue #108, thanks @eolant)
918
- CLI silently fails if the directory to put new files in doesn't exist yet (issue #141, thanks @Styn)

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "swagger-typescript-api",
3-
"version": "4.3.0",
3+
"version": "4.4.0",
44
"description": "Create typescript api module from swagger schema",
55
"scripts": {
66
"cli:json": "node index.js -r -d -p ./swagger-test-cli.json -n swagger-test-cli.ts --extract-request-params --enum-names-as-values",

src/routes.js

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,10 @@ const getContentTypes = (requestInfo, extraContentTypes) =>
277277
);
278278

279279
const CONTENT_KIND = {
280-
JSON: "json",
281-
QUERY: "query",
282-
FORM_DATA: "formData",
283-
UNKNOWN: "unknown",
280+
JSON: "JSON",
281+
URL_ENCODED: "URL_ENCODED",
282+
FORM_DATA: "FORM_DATA",
283+
OTHER: "OTHER",
284284
};
285285

286286
const getContentKind = (contentTypes) => {
@@ -289,14 +289,14 @@ const getContentKind = (contentTypes) => {
289289
}
290290

291291
if (contentTypes.includes("application/x-www-form-urlencoded")) {
292-
return CONTENT_KIND.QUERY;
292+
return CONTENT_KIND.URL_ENCODED;
293293
}
294294

295295
if (contentTypes.includes("multipart/form-data")) {
296296
return CONTENT_KIND.FORM_DATA;
297297
}
298298

299-
return CONTENT_KIND.UNKNOWN;
299+
return CONTENT_KIND.OTHER;
300300
};
301301

302302
const getRequestBodyInfo = (routeInfo, routeParams, parsedSchemas) => {
@@ -442,31 +442,22 @@ const parseRoutes = ({ usageSchema, parsedSchemas, moduleNameIndex, extractReque
442442
: null;
443443

444444
const specificArgs = {
445-
query:
446-
queryType || requestBodyInfo.contentKind === CONTENT_KIND.QUERY
447-
? {
448-
name: pathArgs.some((pathArg) => pathArg.name === "query")
449-
? "queryParams"
450-
: "query",
451-
optional:
452-
requestBodyInfo.contentKind === CONTENT_KIND.QUERY
453-
? !requestBodyInfo.required &&
454-
(!queryType || parseSchema(queryObjectSchema, null).allFieldsAreOptional)
455-
: parseSchema(queryObjectSchema, null).allFieldsAreOptional,
456-
type:
457-
requestBodyInfo.contentKind === CONTENT_KIND.QUERY
458-
? _.compact([queryType, requestBodyInfo.type]).join(" & ")
459-
: queryType,
460-
}
461-
: void 0,
462-
body:
463-
requestBodyInfo.contentKind !== CONTENT_KIND.QUERY && requestBodyInfo.type
464-
? {
465-
name: requestBodyInfo.paramName,
466-
optional: !requestBodyInfo.required,
467-
type: requestBodyInfo.type,
468-
}
469-
: void 0,
445+
query: queryType
446+
? {
447+
name: pathArgs.some((pathArg) => pathArg.name === "query")
448+
? "queryParams"
449+
: "query",
450+
optional: parseSchema(queryObjectSchema, null).allFieldsAreOptional,
451+
type: queryType,
452+
}
453+
: void 0,
454+
body: requestBodyInfo.type
455+
? {
456+
name: requestBodyInfo.paramName,
457+
optional: !requestBodyInfo.required,
458+
type: requestBodyInfo.type,
459+
}
460+
: void 0,
470461
requestParams: {
471462
name: pathArgs.some((pathArg) => pathArg.name === "params")
472463
? "requestParams"
@@ -533,7 +524,7 @@ const parseRoutes = ({ usageSchema, parsedSchemas, moduleNameIndex, extractReque
533524
query: specificArgs.query,
534525
path: route.replace(/{/g, "${"),
535526
formData: requestBodyInfo.contentKind === CONTENT_KIND.FORM_DATA,
536-
isQueryBody: requestBodyInfo.contentKind === CONTENT_KIND.QUERY,
527+
isQueryBody: requestBodyInfo.contentKind === CONTENT_KIND.URL_ENCODED,
537528
security: hasSecurity,
538529
method: method,
539530
payload: specificArgs.body,

src/swagger.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,20 @@ const fixSwaggerScheme = (usage, original) => {
8383
const usageRouteParams = _.get(usageRouteInfo, "parameters", []);
8484
const originalRouteParams = _.get(originalRouteInfo, "parameters", []);
8585

86+
usageRouteInfo.consumes = _.uniq(
87+
_.compact([...(usageRouteInfo.consumes || []), ...(originalRouteInfo.consumes || [])]),
88+
);
89+
usageRouteInfo.produces = _.uniq(
90+
_.compact([...(usageRouteInfo.produces || []), ...(originalRouteInfo.produces || [])]),
91+
);
92+
8693
_.each(originalRouteParams, (originalRouteParam) => {
8794
const existUsageParam = _.find(
8895
usageRouteParams,
8996
(param) => originalRouteParam.in === param.in && originalRouteParam.name === param.name,
9097
);
9198
if (!existUsageParam) {
9299
usageRouteParams.push(originalRouteParam);
93-
} else if (originalRouteParam.in === "formData") {
94-
// console.log("HERE");
95100
}
96101
});
97102
});

templates/default/http-client.eta

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ interface HttpResponse<D extends unknown, E extends unknown = unknown> extends R
3030

3131
enum BodyType {
3232
Json,
33-
FormData
33+
FormData,
34+
UrlEncoded,
3435
}
3536

3637
export class HttpClient<<%~ apiConfig.generic.map(g => `${g.name} = unknown`).join(', ') %>> {
@@ -59,14 +60,21 @@ export class HttpClient<<%~ apiConfig.generic.map(g => `${g.name} = unknown`).jo
5960
return encodeURIComponent(key) + "=" + encodeURIComponent(Array.isArray(query[key]) ? query[key].join(",") : query[key])
6061
}
6162

62-
protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
63+
protected toQueryString(rawQuery?: RequestQueryParamsType): string {
6364
const query = rawQuery || {};
6465
const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]);
65-
return keys.length ? `?${keys.map(key =>
66-
typeof query[key] === "object" && !Array.isArray(query[key]) ?
67-
this.addQueryParams(query[key] as object).substring(1) :
68-
this.addQueryParam(query, key)).join("&")
69-
}` : "";
66+
return keys
67+
.map((key) =>
68+
typeof query[key] === "object" && !Array.isArray(query[key])
69+
? this.toQueryString(query[key] as object)
70+
: this.addQueryParam(query, key),
71+
)
72+
.join("&");
73+
}
74+
75+
protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
76+
const queryString = this.toQueryString(rawQuery);
77+
return queryString ? `?${queryString}` : "";
7078
}
7179

7280
private bodyFormatters: Record<BodyType, (input: any) => any> = {
@@ -76,6 +84,7 @@ export class HttpClient<<%~ apiConfig.generic.map(g => `${g.name} = unknown`).jo
7684
data.append(key, input[key]);
7785
return data;
7886
}, new FormData()),
87+
[BodyType.UrlEncoded]: (input: any) => this.toQueryString(input),
7988
}
8089

8190
private mergeRequestOptions(params: RequestParams, securityParams?: RequestParams): RequestParams {

templates/default/procedure-call.eta

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<%
22
const { utils, route, config } = it;
3+
const { requestBodyInfo } = route;
34
const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require } = utils;
45
const { parameters, path, method, payload, params, query, formData, security, requestParams } = route.request;
56
const { type, errorType, contentTypes } = route.response;
@@ -33,11 +34,13 @@ const wrapperArgs = _
3334
.map(argToTmpl)
3435
.join(', ')
3536

36-
const bodyModeTmpl = formData
37-
? 'BodyType.FormData'
38-
: security
39-
? 'BodyType.Json'
40-
: null
37+
const requestContentKind = {
38+
"JSON": "BodyType.Json",
39+
"URL_ENCODED": "BodyType.UrlEncoded",
40+
"FORM_DATA": "BodyType.FormData"
41+
}
42+
43+
const bodyModeTmpl = requestContentKind[requestBodyInfo.contentKind] || (security && requestContentKind.JSON) || null
4144
const securityTmpl = security ? 'true' : null
4245
const pathTmpl = query != null
4346
? `\`${path}\${this.addQueryParams(${queryName})}\``

templates/modular/http-client.eta

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ export interface HttpResponse<D extends unknown, E extends unknown = unknown> ex
2727

2828
export enum BodyType {
2929
Json,
30-
FormData
30+
FormData,
31+
UrlEncoded,
3132
}
3233

3334
export class HttpClient<<%~ it.apiConfig.generic.map(g => `${g.name} = unknown`).join(', ') %>> {
@@ -56,14 +57,21 @@ export class HttpClient<<%~ it.apiConfig.generic.map(g => `${g.name} = unknown`)
5657
return encodeURIComponent(key) + "=" + encodeURIComponent(Array.isArray(query[key]) ? query[key].join(",") : query[key])
5758
}
5859

59-
protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
60+
protected toQueryString(rawQuery?: RequestQueryParamsType): string {
6061
const query = rawQuery || {};
6162
const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]);
62-
return keys.length ? `?${keys.map(key =>
63-
typeof query[key] === "object" && !Array.isArray(query[key]) ?
64-
this.addQueryParams(query[key] as object).substring(1) :
65-
this.addQueryParam(query, key)).join("&")
66-
}` : "";
63+
return keys
64+
.map((key) =>
65+
typeof query[key] === "object" && !Array.isArray(query[key])
66+
? this.toQueryString(query[key] as object)
67+
: this.addQueryParam(query, key),
68+
)
69+
.join("&");
70+
}
71+
72+
protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
73+
const queryString = this.toQueryString(rawQuery);
74+
return queryString ? `?${queryString}` : "";
6775
}
6876

6977
private bodyFormatters: Record<BodyType, (input: any) => any> = {
@@ -73,6 +81,7 @@ export class HttpClient<<%~ it.apiConfig.generic.map(g => `${g.name} = unknown`)
7381
data.append(key, input[key]);
7482
return data;
7583
}, new FormData()),
84+
[BodyType.UrlEncoded]: (input: any) => this.toQueryString(input),
7685
}
7786

7887
private mergeRequestOptions(params: RequestParams, securityParams?: RequestParams): RequestParams {

templates/modular/procedure-call.eta

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<%
22
const { utils, route, config } = it;
3+
const { requestBodyInfo } = route;
34
const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require } = utils;
45
const { parameters, path, method, payload, params, query, formData, security, requestParams } = route.request;
56
const { type, errorType, contentTypes } = route.response;
@@ -33,11 +34,13 @@ const wrapperArgs = _
3334
.map(argToTmpl)
3435
.join(', ')
3536

36-
const bodyModeTmpl = formData
37-
? 'BodyType.FormData'
38-
: security
39-
? 'BodyType.Json'
40-
: null
37+
const requestContentKind = {
38+
"JSON": "BodyType.Json",
39+
"URL_ENCODED": "BodyType.UrlEncoded",
40+
"FORM_DATA": "BodyType.FormData"
41+
}
42+
43+
const bodyModeTmpl = requestContentKind[requestBodyInfo.contentKind] || (security && requestContentKind.JSON) || null
4144
const securityTmpl = security ? 'true' : null
4245
const pathTmpl = query != null
4346
? '`' + path + '${this.addQueryParams(' + query.name + ')}' + '`'

tests/generated/v2.0/adafruit.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ interface HttpResponse<D extends unknown, E extends unknown = unknown> extends R
184184
enum BodyType {
185185
Json,
186186
FormData,
187+
UrlEncoded,
187188
}
188189

189190
export class HttpClient<SecurityDataType = unknown> {
@@ -214,18 +215,21 @@ export class HttpClient<SecurityDataType = unknown> {
214215
);
215216
}
216217

217-
protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
218+
protected toQueryString(rawQuery?: RequestQueryParamsType): string {
218219
const query = rawQuery || {};
219220
const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]);
220-
return keys.length
221-
? `?${keys
222-
.map((key) =>
223-
typeof query[key] === "object" && !Array.isArray(query[key])
224-
? this.addQueryParams(query[key] as object).substring(1)
225-
: this.addQueryParam(query, key),
226-
)
227-
.join("&")}`
228-
: "";
221+
return keys
222+
.map((key) =>
223+
typeof query[key] === "object" && !Array.isArray(query[key])
224+
? this.toQueryString(query[key] as object)
225+
: this.addQueryParam(query, key),
226+
)
227+
.join("&");
228+
}
229+
230+
protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
231+
const queryString = this.toQueryString(rawQuery);
232+
return queryString ? `?${queryString}` : "";
229233
}
230234

231235
private bodyFormatters: Record<BodyType, (input: any) => any> = {
@@ -235,6 +239,7 @@ export class HttpClient<SecurityDataType = unknown> {
235239
data.append(key, input[key]);
236240
return data;
237241
}, new FormData()),
242+
[BodyType.UrlEncoded]: (input: any) => this.toQueryString(input),
238243
};
239244

240245
private mergeRequestOptions(params: RequestParams, securityParams?: RequestParams): RequestParams {

0 commit comments

Comments
 (0)