Skip to content

Commit 9621fed

Browse files
authored
Release 6.1.0 (#185)
* fix: bug with `kebab-case` path params (issue #184, thanks @Mr-sgreen) * fix: typings for --js option; feat: --silent option (output only errors to console) * bump: up version to 6.1.0
1 parent 1cea367 commit 9621fed

File tree

54 files changed

+32481
-1007
lines changed

Some content is hidden

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

54 files changed

+32481
-1007
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# next release
22

3+
Features:
4+
- `--silent` option. Output only errors to console (default: false)
5+
6+
Fixes:
7+
- Bug with `kebab-case` path params (issue #184, thanks @Mr-sgreen)
8+
- Typings for `--js` option
9+
310
# 6.0.0
411

512
BREAKING_CHANGES:

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Options:
5757
--clean-output clean output folder before generate api. WARNING: May cause data loss (default: false)
5858
--axios generate axios http client (default: false)
5959
--single-http-client Ability to send HttpClient instance to Api constructor (default: false)
60+
--silent Output only errors to console (default: false)
6061
--default-response <type> default type for empty response schema (default: "void")
6162
-h, --help display help for command
6263
```

index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ program
6464
.option("--disableStrictSSL", "disabled strict SSL", false)
6565
.option("--axios", "generate axios http client", false)
6666
.option("--single-http-client", "Ability to send HttpClient instance to Api constructor", false)
67+
.option("--silent", "Output only errors to console", false)
6768
.option("--default-response <type>", "default type for empty response schema", TS_KEYWORDS.VOID)
6869
.option(
6970
"--clean-output",
@@ -93,6 +94,7 @@ const {
9394
defaultResponse,
9495
singleHttpClient,
9596
axios,
97+
silent,
9698
} = program;
9799

98100
generateApi({
@@ -116,4 +118,5 @@ generateApi({
116118
disableStrictSSL: !!disableStrictSSL,
117119
singleHttpClient: !!singleHttpClient,
118120
cleanOutput: !!cleanOutput,
121+
silent: !!silent,
119122
});

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "swagger-typescript-api",
3-
"version": "6.0.0",
3+
"version": "6.1.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",
@@ -30,6 +30,7 @@
3030
"test:--enum-names-as-values": "node tests/spec/enumNamesAsValues/test.js",
3131
"test:--default-response": "node tests/spec/defaultResponse/test.js",
3232
"test:--js": "node tests/spec/js/test.js",
33+
"test:--js--axios": "node tests/spec/jsAxios/test.js",
3334
"test:--axios": "node tests/spec/axios/test.js",
3435
"test:partialBaseTemplate": "node tests/spec/partialBaseTemplate/test.js",
3536
"test:partialDefaultTemplate": "node tests/spec/partialDefaultTemplate/test.js"

src/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ const config = {
6464
},
6565
/** Record<templateName, templateContent> */
6666
templatesToRender: {},
67+
toJS: false,
68+
silent: false,
6769
};
6870

6971
/** needs to use data everywhere in project */

src/index.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module.exports = {
2626
url,
2727
spec,
2828
name: fileName,
29-
toJS: translateToJavaScript,
29+
toJS: translateToJavaScript = config.toJS,
3030
modular,
3131
templates,
3232
generateResponses = config.generateResponses,
@@ -45,6 +45,7 @@ module.exports = {
4545
enumNamesAsValues,
4646
disableStrictSSL = config.disableStrictSSL,
4747
cleanOutput,
48+
silent = config.silent,
4849
}) =>
4950
new Promise((resolve, reject) => {
5051
addToConfig({
@@ -66,6 +67,8 @@ module.exports = {
6667
defaultResponseType,
6768
singleHttpClient,
6869
constants,
70+
silent,
71+
toJS: translateToJavaScript,
6972
});
7073
(spec ? convertSwaggerObject(spec) : getSwaggerObject(input, url, disableStrictSSL))
7174
.then(({ usageSchema, originalSchema }) => {
@@ -75,7 +78,7 @@ module.exports = {
7578

7679
const templatesToRender = getTemplates(config);
7780

78-
console.log("☄️ start generating your typescript api");
81+
if (!config.silent) console.log("☄️ start generating your typescript api");
7982

8083
fixSwaggerScheme(usageSchema, originalSchema);
8184

@@ -148,10 +151,12 @@ module.exports = {
148151
if (translateToJavaScript) {
149152
createFile(output, file.name, file.content);
150153
createFile(output, file.declaration.name, file.declaration.content);
151-
console.log(`✔️ your javascript api file created in "${output}"`);
154+
if (!config.silent)
155+
console.log(`✔️ your javascript api file created in "${output}"`);
152156
} else {
153157
createFile(output, file.name, file.content);
154-
console.log(`✔️ your typescript api file created in "${output}"`);
158+
if (!config.silent)
159+
console.log(`✔️ your typescript api file created in "${output}"`);
155160
}
156161

157162
return file;

src/modelNames.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
const _ = require("lodash");
2+
const { config } = require("./config");
23

34
const isValidName = (name) => /^([A-Za-z$_]{1,})$/g.test(name);
45

56
const formattedModelNamesMap = new Map();
67

78
const checkAndRenameModelName = (name) => {
89
if (typeof name !== "string") {
9-
console.warn("🔨 wrong name of the model name", name);
10+
if (!config.silent) console.warn("🔨 wrong name of the model name", name, config.silent);
1011

1112
return name;
1213
}

src/routeNames.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ const getRouteName = (routeInfo) => {
2222
duplicateIdentifier,
2323
routeNameDuplicatesMap.get(duplicateIdentifier) + 1,
2424
);
25-
console.warn(
26-
`🥵 Module "${moduleName}" already have method "${routeName}()"`,
27-
`\n🥵 This method has been renamed to "${
28-
routeName + routeNameDuplicatesMap.get(duplicateIdentifier)
29-
}()" to solve conflict names.`,
30-
);
25+
if (!config.silent)
26+
console.warn(
27+
`🥵 Module "${moduleName}" already have method "${routeName}()"`,
28+
`\n🥵 This method has been renamed to "${
29+
routeName + routeNameDuplicatesMap.get(duplicateIdentifier)
30+
}()" to solve conflict names.`,
31+
);
3132
} else {
3233
routeNameDuplicatesMap.set(duplicateIdentifier, 1);
3334
}

src/routes.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,14 @@ const parseRoute = (route) => {
132132
if (!paramName) return pathParams;
133133

134134
if (_.includes(paramName, "-")) {
135-
console.warn("🔨 wrong path param name", paramName);
135+
if (!config.silent) console.warn("🔨 wrong path param name", paramName);
136136
}
137137

138138
return [
139139
...pathParams,
140140
{
141141
$match: match,
142-
name: paramName,
142+
name: _.camelCase(paramName),
143143
required: true,
144144
type: "string",
145145
description: "",
@@ -162,6 +162,7 @@ const parseRoute = (route) => {
162162
);
163163

164164
return {
165+
originalRoute: route || "",
165166
route: fixedRoute,
166167
pathParams,
167168
};
@@ -206,6 +207,10 @@ const getRouteParams = (routeInfo, pathParams) => {
206207
};
207208
}
208209

210+
if (routeParam.in === "path" && routeParam.name) {
211+
routeParam.name = _.camelCase(routeParam.name);
212+
}
213+
209214
if (routeParam) {
210215
routeParams[routeParam.in].push(routeParam);
211216
}

src/swagger.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const yaml = require("js-yaml");
33
const axios = require("axios");
44
const converter = require("swagger2openapi");
55
const https = require("https");
6-
const { addToConfig } = require("./config");
6+
const { addToConfig, config } = require("./config");
77
const { pathIsExist, getFileContent } = require("./files");
88

99
const parseSwaggerFile = (file) => {
@@ -19,10 +19,10 @@ const parseSwaggerFile = (file) => {
1919
const getSwaggerFile = (pathToSwagger, urlToSwagger, disableStrictSSL) =>
2020
new Promise((resolve) => {
2121
if (pathIsExist(pathToSwagger)) {
22-
console.log(`✨ try to get swagger by path "${pathToSwagger}"`);
22+
if (!config.silent) console.log(`✨ try to get swagger by path "${pathToSwagger}"`);
2323
resolve(getFileContent(pathToSwagger));
2424
} else {
25-
console.log(`✨ try to get swagger by url "${urlToSwagger}"`);
25+
if (!config.silent) console.log(`✨ try to get swagger by url "${urlToSwagger}"`);
2626
let agent = undefined;
2727
if (disableStrictSSL) {
2828
agent = new https.Agent({

src/templates.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const _ = require("lodash");
22
const Eta = require("eta");
33
const { getFileContent, pathIsExist } = require("./files");
4-
const { config, addToConfig } = require("./config");
4+
const { config } = require("./config");
55
const { resolve } = require("path");
66

77
/**
@@ -38,7 +38,8 @@ const getTemplatePaths = ({ templates, modular }) => {
3838
};
3939

4040
const getTemplates = ({ templatePaths }) => {
41-
console.log(`✨ try to read templates from directory "${templatePaths.custom}"`);
41+
if (!config.silent)
42+
console.log(`✨ try to read templates from directory "${templatePaths.custom}"`);
4243

4344
const templatesMap = _.reduce(
4445
TEMPLATE_INFOS,
@@ -53,10 +54,11 @@ const getTemplates = ({ templatePaths }) => {
5354
if (pathIsExist(baseFullPath)) {
5455
fileContent = getFileContent(baseFullPath);
5556
} else {
56-
console.log(
57-
`❗❗❗ ${_.lowerCase(name)} template not found in ${customFullPath}\n` +
58-
`Code generator will use the default template`,
59-
);
57+
if (!config.silent)
58+
console.log(
59+
`❗❗❗ ${_.lowerCase(name)} template not found in ${customFullPath}\n` +
60+
`Code generator will use the default template`,
61+
);
6062
}
6163

6264
if (pathIsExist(originalFullPath)) {

templates/default/api.eta

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const descriptionLines = _.compact([
1313
]);
1414

1515
%>
16-
<% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import { AxiosRequestConfig } from "axios"; <% } %>
16+
<% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import { AxiosRequestConfig, AxiosResponse } from "axios"; <% } %>
1717
<% if (descriptionLines.length) { %>
1818
/**
1919
<% descriptionLines.forEach((descriptionLine) => { %>

templates/default/procedure-call.eta

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@ const bodyContentKindTmpl = requestContentKind[requestBodyInfo.contentKind] || n
6060
const responseFormatTmpl = responseContentKind[responseBodyInfo.success && responseBodyInfo.success.schema && responseBodyInfo.success.schema.contentKind] || null;
6161
const securityTmpl = security ? 'true' : null;
6262

63+
const describeReturnType = () => {
64+
if (!config.toJS) return "";
65+
66+
switch(config.httpClientType) {
67+
case config.constants.HTTP_CLIENT.AXIOS: {
68+
return `Promise<AxiosResponse<${type}>>`
69+
}
70+
default: {
71+
return `Promise<HttpResponse<${type}, ${errorType}>`
72+
}
73+
}
74+
}
75+
6376
%>
6477
/**
6578
<%~ routeDocs.description %>
@@ -69,7 +82,7 @@ const securityTmpl = security ? 'true' : null;
6982
<%~ routeDocs.lines %>
7083

7184
*/
72-
<%~ route.routeName.usage %><%~ route.namespace ? ': ' : ' = ' %>(<%~ wrapperArgs %>) =>
85+
<%~ route.routeName.usage %><%~ route.namespace ? ': ' : ' = ' %>(<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> =>
7386
<%~ config.singleHttpClient ? 'this.http.request' : 'this.request' %><<%~ type %>, <%~ errorType %>>({
7487
path: `<%~ path %>`,
7588
method: '<%~ _.upperCase(method) %>',

templates/modular/api.eta

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const apiClassName = classNameCase(route.moduleName);
55
const routes = route.routes;
66
const dataContracts = _.map(modelTypes, "name");
77
%>
8-
<% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import { AxiosRequestConfig } from "axios"; <% } %>
8+
<% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import { AxiosRequestConfig, AxiosResponse } from "axios"; <% } %>
99
import { HttpClient, RequestParams, ContentType } from "./<%~ config.fileNames.httpClient %>";
1010
<% if (dataContracts.length) { %>
1111
import { <%~ dataContracts.join(", ") %> } from "./<%~ config.fileNames.dataContracts %>"

templates/modular/procedure-call.eta

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ const queryTmpl = (query != null && queryName) || null;
5959
const bodyContentKindTmpl = requestContentKind[requestBodyInfo.contentKind] || null;
6060
const responseFormatTmpl = responseContentKind[responseBodyInfo.success && responseBodyInfo.success.schema && responseBodyInfo.success.schema.contentKind] || null;
6161
const securityTmpl = security ? 'true' : null;
62+
63+
const describeReturnType = () => {
64+
if (!config.toJS) return "";
65+
66+
switch(config.httpClientType) {
67+
case config.constants.HTTP_CLIENT.AXIOS: {
68+
return `Promise<AxiosResponse<${type}>>`
69+
}
70+
default: {
71+
return `Promise<HttpResponse<${type}, ${errorType}>`
72+
}
73+
}
74+
}
75+
6276
%>
6377
/**
6478
<%~ routeDocs.description %>
@@ -68,7 +82,7 @@ const securityTmpl = security ? 'true' : null;
6882
<%~ routeDocs.lines %>
6983

7084
*/
71-
<%~ route.routeName.usage %> = (<%~ wrapperArgs %>) =>
85+
<%~ route.routeName.usage %> = (<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> =>
7286
<%~ config.singleHttpClient ? 'this.http.request' : 'this.request' %><<%~ type %>, <%~ errorType %>>({
7387
path: `<%~ path %>`,
7488
method: '<%~ _.upperCase(method) %>',

tests/generate.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,25 @@
11
const { resolve } = require("path");
2-
const createSchemasInfos = require("./helpers/createSchemaInfos")
3-
const { generateApi } = require('../src');
2+
const createSchemasInfos = require("./helpers/createSchemaInfos");
3+
const { generateApi } = require("../src");
44

55
const schemas = [
66
...createSchemasInfos({
77
absolutePathToSchemas: resolve(__dirname, "./schemas/v2.0"),
8-
absoluteOutputPath: resolve(__dirname, "./generated/v2.0")
8+
absoluteOutputPath: resolve(__dirname, "./generated/v2.0"),
99
}),
1010
...createSchemasInfos({
1111
absolutePathToSchemas: resolve(__dirname, "./schemas/v3.0"),
12-
absoluteOutputPath: resolve(__dirname, "./generated/v3.0")
12+
absoluteOutputPath: resolve(__dirname, "./generated/v3.0"),
1313
}),
14-
]
14+
];
1515

16-
schemas.forEach(({
17-
absolutePath,
18-
apiFileName,
19-
outputPath,
20-
}) => {
16+
schemas.forEach(({ absolutePath, apiFileName, outputPath }) => {
2117
generateApi({
2218
name: apiFileName,
2319
input: absolutePath,
2420
output: outputPath,
2521
generateClient: true,
26-
generateRouteTypes: false
22+
generateRouteTypes: false,
23+
silent: true,
2724
});
28-
})
25+
});

0 commit comments

Comments
 (0)