Skip to content

Commit

Permalink
Release 4.4.0 (#148)
Browse files Browse the repository at this point in the history
* fix: problem with generation form urlencoded request body (#146 issue)

* bump: up version to 4.4.0
  • Loading branch information
js2me authored Feb 9, 2021
1 parent 34b5379 commit 0f6a69c
Show file tree
Hide file tree
Showing 60 changed files with 1,059 additions and 673 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# next release

# 4.3.0
# 4.4.0

Fixes:
- Client generation for `Content-Type: application/x-www-form-urlencoded` (issue #146, thanks @Larox)

Internal:
- Changed templates:
- `http-client.eta`
- `procedure-call.eta`

# 4.3.0

Fixes:
- enum + nullable: true doesn't compute the good type (issue #145, thanks @RoXuS)
- Underscores are omitted from enum keys (issue #108, thanks @eolant)
- CLI silently fails if the directory to put new files in doesn't exist yet (issue #141, thanks @Styn)
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "swagger-typescript-api",
"version": "4.3.0",
"version": "4.4.0",
"description": "Create typescript api module from swagger schema",
"scripts": {
"cli:json": "node index.js -r -d -p ./swagger-test-cli.json -n swagger-test-cli.ts --extract-request-params --enum-names-as-values",
Expand Down
55 changes: 23 additions & 32 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,10 @@ const getContentTypes = (requestInfo, extraContentTypes) =>
);

const CONTENT_KIND = {
JSON: "json",
QUERY: "query",
FORM_DATA: "formData",
UNKNOWN: "unknown",
JSON: "JSON",
URL_ENCODED: "URL_ENCODED",
FORM_DATA: "FORM_DATA",
OTHER: "OTHER",
};

const getContentKind = (contentTypes) => {
Expand All @@ -289,14 +289,14 @@ const getContentKind = (contentTypes) => {
}

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

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

return CONTENT_KIND.UNKNOWN;
return CONTENT_KIND.OTHER;
};

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

const specificArgs = {
query:
queryType || requestBodyInfo.contentKind === CONTENT_KIND.QUERY
? {
name: pathArgs.some((pathArg) => pathArg.name === "query")
? "queryParams"
: "query",
optional:
requestBodyInfo.contentKind === CONTENT_KIND.QUERY
? !requestBodyInfo.required &&
(!queryType || parseSchema(queryObjectSchema, null).allFieldsAreOptional)
: parseSchema(queryObjectSchema, null).allFieldsAreOptional,
type:
requestBodyInfo.contentKind === CONTENT_KIND.QUERY
? _.compact([queryType, requestBodyInfo.type]).join(" & ")
: queryType,
}
: void 0,
body:
requestBodyInfo.contentKind !== CONTENT_KIND.QUERY && requestBodyInfo.type
? {
name: requestBodyInfo.paramName,
optional: !requestBodyInfo.required,
type: requestBodyInfo.type,
}
: void 0,
query: queryType
? {
name: pathArgs.some((pathArg) => pathArg.name === "query")
? "queryParams"
: "query",
optional: parseSchema(queryObjectSchema, null).allFieldsAreOptional,
type: queryType,
}
: void 0,
body: requestBodyInfo.type
? {
name: requestBodyInfo.paramName,
optional: !requestBodyInfo.required,
type: requestBodyInfo.type,
}
: void 0,
requestParams: {
name: pathArgs.some((pathArg) => pathArg.name === "params")
? "requestParams"
Expand Down Expand Up @@ -533,7 +524,7 @@ const parseRoutes = ({ usageSchema, parsedSchemas, moduleNameIndex, extractReque
query: specificArgs.query,
path: route.replace(/{/g, "${"),
formData: requestBodyInfo.contentKind === CONTENT_KIND.FORM_DATA,
isQueryBody: requestBodyInfo.contentKind === CONTENT_KIND.QUERY,
isQueryBody: requestBodyInfo.contentKind === CONTENT_KIND.URL_ENCODED,
security: hasSecurity,
method: method,
payload: specificArgs.body,
Expand Down
9 changes: 7 additions & 2 deletions src/swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,20 @@ const fixSwaggerScheme = (usage, original) => {
const usageRouteParams = _.get(usageRouteInfo, "parameters", []);
const originalRouteParams = _.get(originalRouteInfo, "parameters", []);

usageRouteInfo.consumes = _.uniq(
_.compact([...(usageRouteInfo.consumes || []), ...(originalRouteInfo.consumes || [])]),
);
usageRouteInfo.produces = _.uniq(
_.compact([...(usageRouteInfo.produces || []), ...(originalRouteInfo.produces || [])]),
);

_.each(originalRouteParams, (originalRouteParam) => {
const existUsageParam = _.find(
usageRouteParams,
(param) => originalRouteParam.in === param.in && originalRouteParam.name === param.name,
);
if (!existUsageParam) {
usageRouteParams.push(originalRouteParam);
} else if (originalRouteParam.in === "formData") {
// console.log("HERE");
}
});
});
Expand Down
23 changes: 16 additions & 7 deletions templates/default/http-client.eta
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ interface HttpResponse<D extends unknown, E extends unknown = unknown> extends R

enum BodyType {
Json,
FormData
FormData,
UrlEncoded,
}

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

protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
protected toQueryString(rawQuery?: RequestQueryParamsType): string {
const query = rawQuery || {};
const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]);
return keys.length ? `?${keys.map(key =>
typeof query[key] === "object" && !Array.isArray(query[key]) ?
this.addQueryParams(query[key] as object).substring(1) :
this.addQueryParam(query, key)).join("&")
}` : "";
return keys
.map((key) =>
typeof query[key] === "object" && !Array.isArray(query[key])
? this.toQueryString(query[key] as object)
: this.addQueryParam(query, key),
)
.join("&");
}

protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
const queryString = this.toQueryString(rawQuery);
return queryString ? `?${queryString}` : "";
}

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

private mergeRequestOptions(params: RequestParams, securityParams?: RequestParams): RequestParams {
Expand Down
13 changes: 8 additions & 5 deletions templates/default/procedure-call.eta
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<%
const { utils, route, config } = it;
const { requestBodyInfo } = route;
const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require } = utils;
const { parameters, path, method, payload, params, query, formData, security, requestParams } = route.request;
const { type, errorType, contentTypes } = route.response;
Expand Down Expand Up @@ -33,11 +34,13 @@ const wrapperArgs = _
.map(argToTmpl)
.join(', ')

const bodyModeTmpl = formData
? 'BodyType.FormData'
: security
? 'BodyType.Json'
: null
const requestContentKind = {
"JSON": "BodyType.Json",
"URL_ENCODED": "BodyType.UrlEncoded",
"FORM_DATA": "BodyType.FormData"
}

const bodyModeTmpl = requestContentKind[requestBodyInfo.contentKind] || (security && requestContentKind.JSON) || null
const securityTmpl = security ? 'true' : null
const pathTmpl = query != null
? `\`${path}\${this.addQueryParams(${queryName})}\``
Expand Down
23 changes: 16 additions & 7 deletions templates/modular/http-client.eta
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export interface HttpResponse<D extends unknown, E extends unknown = unknown> ex

export enum BodyType {
Json,
FormData
FormData,
UrlEncoded,
}

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

protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
protected toQueryString(rawQuery?: RequestQueryParamsType): string {
const query = rawQuery || {};
const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]);
return keys.length ? `?${keys.map(key =>
typeof query[key] === "object" && !Array.isArray(query[key]) ?
this.addQueryParams(query[key] as object).substring(1) :
this.addQueryParam(query, key)).join("&")
}` : "";
return keys
.map((key) =>
typeof query[key] === "object" && !Array.isArray(query[key])
? this.toQueryString(query[key] as object)
: this.addQueryParam(query, key),
)
.join("&");
}

protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
const queryString = this.toQueryString(rawQuery);
return queryString ? `?${queryString}` : "";
}

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

private mergeRequestOptions(params: RequestParams, securityParams?: RequestParams): RequestParams {
Expand Down
13 changes: 8 additions & 5 deletions templates/modular/procedure-call.eta
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<%
const { utils, route, config } = it;
const { requestBodyInfo } = route;
const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require } = utils;
const { parameters, path, method, payload, params, query, formData, security, requestParams } = route.request;
const { type, errorType, contentTypes } = route.response;
Expand Down Expand Up @@ -33,11 +34,13 @@ const wrapperArgs = _
.map(argToTmpl)
.join(', ')

const bodyModeTmpl = formData
? 'BodyType.FormData'
: security
? 'BodyType.Json'
: null
const requestContentKind = {
"JSON": "BodyType.Json",
"URL_ENCODED": "BodyType.UrlEncoded",
"FORM_DATA": "BodyType.FormData"
}

const bodyModeTmpl = requestContentKind[requestBodyInfo.contentKind] || (security && requestContentKind.JSON) || null
const securityTmpl = security ? 'true' : null
const pathTmpl = query != null
? '`' + path + '${this.addQueryParams(' + query.name + ')}' + '`'
Expand Down
25 changes: 15 additions & 10 deletions tests/generated/v2.0/adafruit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ interface HttpResponse<D extends unknown, E extends unknown = unknown> extends R
enum BodyType {
Json,
FormData,
UrlEncoded,
}

export class HttpClient<SecurityDataType = unknown> {
Expand Down Expand Up @@ -214,18 +215,21 @@ export class HttpClient<SecurityDataType = unknown> {
);
}

protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
protected toQueryString(rawQuery?: RequestQueryParamsType): string {
const query = rawQuery || {};
const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]);
return keys.length
? `?${keys
.map((key) =>
typeof query[key] === "object" && !Array.isArray(query[key])
? this.addQueryParams(query[key] as object).substring(1)
: this.addQueryParam(query, key),
)
.join("&")}`
: "";
return keys
.map((key) =>
typeof query[key] === "object" && !Array.isArray(query[key])
? this.toQueryString(query[key] as object)
: this.addQueryParam(query, key),
)
.join("&");
}

protected addQueryParams(rawQuery?: RequestQueryParamsType): string {
const queryString = this.toQueryString(rawQuery);
return queryString ? `?${queryString}` : "";
}

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

private mergeRequestOptions(params: RequestParams, securityParams?: RequestParams): RequestParams {
Expand Down
Loading

0 comments on commit 0f6a69c

Please sign in to comment.