swagger-typescript-api 11.0.0--beta-3 → 11.0.0--beta-4

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/cli/execute.js CHANGED
@@ -13,6 +13,7 @@ const execute = (params, commands, instance) => {
13
13
 
14
14
  if (error) {
15
15
  reject(new Error(error));
16
+ return;
16
17
  }
17
18
 
18
19
  if (!usageOptions.length && command.name === root_command) {
@@ -91,9 +92,22 @@ const processArgs = (commands, args) => {
91
92
  if (error) return;
92
93
 
93
94
  if (i === 0) {
94
- command = commands[arg] || commands[root_command];
95
- allFlagKeys = command.options.reduce((acc, option) => [...acc, ...option.flags.keys], []);
95
+ command = commands[arg];
96
+
97
+ if (!command && !arg.startsWith("-")) {
98
+ const tip = didYouMean(arg, _.keys(commands));
99
+ error = `unknown command ${arg}${tip ? `\n(Did you mean ${tip} ?)` : ""}`;
100
+ } else if (!command) {
101
+ command = commands[root_command];
102
+ }
103
+
104
+ if (command) {
105
+ allFlagKeys = command.options.reduce((acc, option) => [...acc, ...option.flags.keys], []);
106
+ }
96
107
  }
108
+
109
+ if (error) return;
110
+
97
111
  if (arg.startsWith("-")) {
98
112
  const option = command.options.find((option) => option.flags.keys.includes(arg));
99
113
 
@@ -127,6 +141,14 @@ const processArgs = (commands, args) => {
127
141
  });
128
142
  command = command || commands[root_command];
129
143
 
144
+ if (error) {
145
+ return {
146
+ command: null,
147
+ usageOptions: [],
148
+ error,
149
+ };
150
+ }
151
+
130
152
  return {
131
153
  command,
132
154
  usageOptions,
package/cli/index.js CHANGED
@@ -8,13 +8,33 @@ const { displayVersion } = require("./operations/display-version");
8
8
  const cli = (input) => {
9
9
  const commands = {};
10
10
 
11
- const addCommand = (command) => {
11
+ const addCommand = (command, { addVersion = false, addHelp = true } = {}) => {
12
12
  commands[command.name] = {
13
13
  name: command.name,
14
14
  description: `${command.description || ""}`,
15
15
  options: _.compact(_.map(command.options, processOption)),
16
16
  };
17
17
 
18
+ if (addVersion) {
19
+ commands[command.name].options.unshift(
20
+ processOption({
21
+ flags: "-v, --version",
22
+ description: "output the current version",
23
+ operation: () => displayVersion(instance),
24
+ }),
25
+ );
26
+ }
27
+
28
+ if (addHelp) {
29
+ commands[command.name].options.push(
30
+ processOption({
31
+ flags: "-h, --help",
32
+ description: "display help for command",
33
+ operation: () => displayHelp(commands, instance, commands[command.name]),
34
+ }),
35
+ );
36
+ }
37
+
18
38
  return instance;
19
39
  };
20
40
 
@@ -25,10 +45,16 @@ const cli = (input) => {
25
45
  execute: (params) => execute(params, commands, instance),
26
46
  };
27
47
 
28
- addCommand({
29
- name: root_command,
30
- options: [],
31
- });
48
+ addCommand(
49
+ {
50
+ name: root_command,
51
+ options: [],
52
+ },
53
+ {
54
+ addVersion: false,
55
+ addHelp: false,
56
+ },
57
+ );
32
58
 
33
59
  _.forEach(input.options, (option) => {
34
60
  const processed = processOption(option);
@@ -55,7 +81,7 @@ const cli = (input) => {
55
81
  processOption({
56
82
  flags: "-h, --help",
57
83
  description: "display help for command",
58
- operation: () => displayHelp(commands, instance),
84
+ operation: () => displayHelp(commands, instance, commands[root_command]),
59
85
  }),
60
86
  );
61
87
 
@@ -1,33 +1,56 @@
1
1
  const _ = require("lodash");
2
2
  const { root_command } = require("../constants");
3
3
 
4
- const displayHelp = (commands, instance) => {
5
- const generateOptionsOutput = (options) =>
6
- options.reduce(
7
- (acc, option) => {
8
- const flags = `${option.flags.keys.join(", ")}${option.flags.value?.raw ? ` ${option.flags.value?.raw}` : ""}`;
9
- const description = `${option.description || ""}${
10
- option.default === undefined || (option.flags.isNoFlag && option.default === true)
11
- ? ""
12
- : ` (default: ${typeof option.default === "string" ? `"${option.default}"` : option.default})`
13
- }`;
14
-
15
- if (flags.length > acc.maxLength) {
16
- acc.maxLength = flags.length;
17
- }
18
-
19
- acc.options.push({
20
- flags,
21
- description,
22
- });
23
- return acc;
24
- },
25
- {
26
- options: [],
27
- maxLength: 0,
28
- },
29
- );
4
+ const generateOptionsOutput = (options) =>
5
+ options.reduce(
6
+ (acc, option) => {
7
+ const flags = `${option.flags.keys.join(", ")}${option.flags.value?.raw ? ` ${option.flags.value?.raw}` : ""}`;
8
+ const description = `${option.description || ""}${
9
+ option.default === undefined || (option.flags.isNoFlag && option.default === true)
10
+ ? ""
11
+ : ` (default: ${typeof option.default === "string" ? `"${option.default}"` : option.default})`
12
+ }`;
13
+
14
+ if (flags.length > acc.maxLength) {
15
+ acc.maxLength = flags.length;
16
+ }
17
+
18
+ acc.options.push({
19
+ flags,
20
+ description,
21
+ });
22
+ return acc;
23
+ },
24
+ {
25
+ options: [],
26
+ maxLength: 0,
27
+ },
28
+ );
29
+
30
+ const generateOptionsTextOutput = (options, maxLength, spaces) =>
31
+ options
32
+ .map((option) => {
33
+ const spacesText = Array(spaces).fill(" ").join("");
34
+ const leftStr = `${spacesText}${option.flags.padEnd(maxLength, " ")} `;
35
+ const leftStrFiller = Array(leftStr.length).fill(" ").join("");
36
+ const descriptionLines = option.description.split("\n");
37
+
38
+ return (
39
+ leftStr +
40
+ descriptionLines
41
+ .map((line, i) => {
42
+ if (i === 0) {
43
+ return line;
44
+ }
45
+
46
+ return `\n${leftStrFiller}${line}`;
47
+ })
48
+ .join("")
49
+ );
50
+ })
51
+ .join("\n");
30
52
 
53
+ const displayAllHelp = (commands, instance) => {
31
54
  const { options, maxLength: maxOptionLength } = generateOptionsOutput(commands[root_command].options);
32
55
 
33
56
  const { commands: commandLabels, maxLength: maxCommandLength } = _.filter(
@@ -57,29 +80,6 @@ const displayHelp = (commands, instance) => {
57
80
  },
58
81
  );
59
82
 
60
- const generateOptionsTextOutput = (options, maxLength, spaces) =>
61
- options
62
- .map((option) => {
63
- const spacesText = Array(spaces).fill(" ").join("");
64
- const leftStr = `${spacesText}${option.flags.padEnd(maxLength, " ")} `;
65
- const leftStrFiller = Array(leftStr.length).fill(" ").join("");
66
- const descriptionLines = option.description.split("\n");
67
-
68
- return (
69
- leftStr +
70
- descriptionLines
71
- .map((line, i) => {
72
- if (i === 0) {
73
- return line;
74
- }
75
-
76
- return `\n${leftStrFiller}${line}`;
77
- })
78
- .join("")
79
- );
80
- })
81
- .join("\n");
82
-
83
83
  const optionsOutput = generateOptionsTextOutput(options, maxOptionLength, 2);
84
84
 
85
85
  const commandsOutput = commandLabels
@@ -128,6 +128,31 @@ ${instance.input.description}`
128
128
  ${outputTest}`);
129
129
  };
130
130
 
131
+ const displayHelp = (commands, instance, command) => {
132
+ const rootCommand = commands[root_command];
133
+ if (command.name === root_command) return displayAllHelp(commands, instance);
134
+
135
+ const { options, maxLength: maxOptionLength } = generateOptionsOutput(command.options);
136
+ const optionsOutput = generateOptionsTextOutput(options, maxOptionLength, 2);
137
+
138
+ const outputTest = [
139
+ optionsOutput &&
140
+ `Options:
141
+ ${optionsOutput}`,
142
+ ]
143
+ .filter(Boolean)
144
+ .join("\n\n");
145
+
146
+ console.log(`Usage: ${instance.input.name} ${command.name}${optionsOutput ? " [options]" : ""}
147
+ ${
148
+ command.description &&
149
+ `
150
+ ${command.description}`
151
+ }
152
+
153
+ ${outputTest}`);
154
+ };
155
+
131
156
  module.exports = {
132
157
  displayHelp,
133
158
  };
package/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ type HttpClientType = "axios" | "fetch";
2
+
1
3
  interface GenerateApiParamsBase {
2
4
  /**
3
5
  * default 'api.ts'
@@ -34,7 +36,7 @@ interface GenerateApiParamsBase {
34
36
  /**
35
37
  * generated http client type
36
38
  */
37
- httpClientType?: "axios" | "fetch";
39
+ httpClientType?: HttpClientType;
38
40
  /**
39
41
  * use "default" response status code as success response too.
40
42
  * some swagger schemas use "default" response status code as success response type by default.
@@ -499,3 +501,15 @@ export interface GenerateApiOutput {
499
501
  }
500
502
 
501
503
  export declare function generateApi(params: GenerateApiParams): Promise<GenerateApiOutput>;
504
+
505
+ export interface GenerateTemplatesParams {
506
+ cleanOutput?: boolean;
507
+ output?: string;
508
+ httpClientType?: HttpClientType;
509
+ modular?: boolean;
510
+ silent?: boolean;
511
+ }
512
+
513
+ export interface GenerateTemplatesOutput extends Pick<GenerateApiOutput, "files" | "createFile"> {}
514
+
515
+ export declare function generateTemplates(params: GenerateTemplatesParams): Promise<GenerateTemplatesOutput>;
package/index.js CHANGED
@@ -9,9 +9,14 @@
9
9
  const _ = require("lodash");
10
10
  const { version, name } = require("./package.json");
11
11
  const { cli } = require("./cli");
12
- const { generateApi } = require("./src");
12
+ const { generateApi, generateTemplates } = require("./src");
13
13
  const { HTTP_CLIENT } = require("./src/constants");
14
14
  const { resolve } = require("path");
15
+ const { CodeGenConfig } = require("./src/configuration");
16
+ const { TemplatesGenConfig } = require("./src/commands/generate-templates/configuration");
17
+
18
+ const codeGenBaseConfig = new CodeGenConfig({});
19
+ const templateGenBaseConfig = new TemplatesGenConfig({});
15
20
 
16
21
  const program = cli({
17
22
  name: name,
@@ -32,7 +37,7 @@ const program = cli({
32
37
  {
33
38
  flags: "-n, --name <string>",
34
39
  description: "name of output typescript api file",
35
- default: "Api.ts",
40
+ default: `${codeGenBaseConfig.apiClassName}.ts`,
36
41
  },
37
42
  {
38
43
  flags: "-t, --templates <string>",
@@ -43,134 +48,134 @@ const program = cli({
43
48
  description:
44
49
  'use "default" response status code as success response too.\n' +
45
50
  'some swagger schemas use "default" response status code as success response type by default.',
46
- default: false,
51
+ default: codeGenBaseConfig.defaultResponseAsSuccess,
47
52
  },
48
53
  {
49
54
  flags: "-r, --responses",
50
55
  description: "generate additional information about request responses\n" + "also add typings for bad responses",
51
- default: false,
56
+ default: codeGenBaseConfig.generateResponses,
52
57
  },
53
58
  {
54
59
  flags: "--union-enums",
55
60
  description: 'generate all "enum" types as union types (T1 | T2 | TN)',
56
- default: false,
61
+ default: codeGenBaseConfig.generateUnionEnums,
57
62
  },
58
63
  {
59
64
  flags: "--add-readonly",
60
65
  description: "generate readonly properties",
61
- default: false,
66
+ default: codeGenBaseConfig.addReadonly,
62
67
  },
63
68
  {
64
69
  flags: "--route-types",
65
70
  description: "generate type definitions for API routes",
66
- default: false,
71
+ default: codeGenBaseConfig.generateRouteTypes,
67
72
  },
68
73
  {
69
74
  flags: "--no-client",
70
75
  description: "do not generate an API class",
71
- default: true,
76
+ default: codeGenBaseConfig.generateClient,
72
77
  },
73
78
  {
74
79
  flags: "--enum-names-as-values",
75
80
  description: "use values in 'x-enumNames' as enum values (not only as keys)",
76
- default: false,
81
+ default: codeGenBaseConfig.enumNamesAsValues,
77
82
  },
78
83
  {
79
84
  flags: "--extract-request-params",
80
85
  description:
81
86
  "extract request params to data contract (Also combine path params and query params into one object)",
82
- default: false,
87
+ default: codeGenBaseConfig.extractRequestParams,
83
88
  },
84
89
  {
85
90
  flags: "--extract-request-body",
86
91
  description: "extract request body type to data contract",
87
- default: false,
92
+ default: codeGenBaseConfig.extractRequestBody,
88
93
  },
89
94
  {
90
95
  flags: "--extract-response-body",
91
96
  description: "extract response body type to data contract",
92
- default: false,
97
+ default: codeGenBaseConfig.extractResponseBody,
93
98
  },
94
99
  {
95
100
  flags: "--extract-response-error",
96
101
  description: "extract response error type to data contract",
97
- default: false,
102
+ default: codeGenBaseConfig.extractResponseError,
98
103
  },
99
104
  {
100
105
  flags: "--modular",
101
106
  description: "generate separated files for http client, data contracts, and routes",
102
- default: false,
107
+ default: codeGenBaseConfig.modular,
103
108
  },
104
109
  {
105
110
  flags: "--js",
106
111
  description: "generate js api module with declaration file",
107
- default: false,
112
+ default: codeGenBaseConfig.toJS,
108
113
  },
109
114
  {
110
115
  flags: "--module-name-index <number>",
111
116
  description:
112
117
  "determines which path index should be used for routes separation (example: GET:/fruites/getFruit -> index:0 -> moduleName -> fruites)",
113
- default: 0,
118
+ default: codeGenBaseConfig.moduleNameIndex,
114
119
  },
115
120
  {
116
121
  flags: "--module-name-first-tag",
117
122
  description: "splits routes based on the first tag",
118
- default: false,
123
+ default: codeGenBaseConfig.moduleNameFirstTag,
119
124
  },
120
125
  {
121
126
  flags: "--disableStrictSSL",
122
127
  description: "disabled strict SSL",
123
- default: false,
128
+ default: codeGenBaseConfig.disableStrictSSL,
124
129
  },
125
130
  {
126
131
  flags: "--disableProxy",
127
132
  description: "disabled proxy",
128
- default: false,
133
+ default: codeGenBaseConfig.disableProxy,
129
134
  },
130
135
  {
131
136
  flags: "--axios",
132
137
  description: "generate axios http client",
133
- default: false,
138
+ default: codeGenBaseConfig.httpClientType === "axios",
134
139
  },
135
140
  {
136
141
  flags: "--unwrap-response-data",
137
142
  description: "unwrap the data item from the response",
138
- default: false,
143
+ default: codeGenBaseConfig.unwrapResponseData,
139
144
  },
140
145
  {
141
146
  flags: "--disable-throw-on-error",
142
147
  description: "Do not throw an error when response.ok is not true",
143
- default: false,
148
+ default: codeGenBaseConfig.disableThrowOnError,
144
149
  },
145
150
  {
146
151
  flags: "--single-http-client",
147
152
  description: "Ability to send HttpClient instance to Api constructor",
148
- default: false,
153
+ default: codeGenBaseConfig.singleHttpClient,
149
154
  },
150
155
  {
151
156
  flags: "--silent",
152
157
  description: "Output only errors to console",
153
- default: false,
158
+ default: codeGenBaseConfig.silent,
154
159
  },
155
160
  {
156
161
  flags: "--default-response <type>",
157
162
  description: "default type for empty response schema",
158
- default: "void",
163
+ default: codeGenBaseConfig.defaultResponseType,
159
164
  },
160
165
  {
161
166
  flags: "--type-prefix <string>",
162
167
  description: "data contract name prefix",
163
- default: "",
168
+ default: codeGenBaseConfig.typePrefix,
164
169
  },
165
170
  {
166
171
  flags: "--type-suffix <string>",
167
172
  description: "data contract name suffix",
168
- default: "",
173
+ default: codeGenBaseConfig.typeSuffix,
169
174
  },
170
175
  {
171
176
  flags: "--clean-output",
172
177
  description: "clean output folder before generate api. WARNING: May cause data loss",
173
- default: false,
178
+ default: codeGenBaseConfig.cleanOutput,
174
179
  },
175
180
  {
176
181
  flags: "--api-class-name <string>",
@@ -179,22 +184,56 @@ const program = cli({
179
184
  {
180
185
  flags: "--patch",
181
186
  description: "fix up small errors in the swagger source definition",
182
- default: false,
187
+ default: codeGenBaseConfig.patch,
183
188
  },
184
189
  {
185
190
  flags: "--debug",
186
191
  description: "additional information about processes inside this tool",
187
- default: false,
192
+ default: codeGenBaseConfig.debug,
188
193
  },
189
194
  {
190
195
  flags: "--another-array-type",
191
196
  description: "generate array types as Array<Type> (by default Type[])",
192
- default: false,
197
+ default: codeGenBaseConfig.anotherArrayType,
193
198
  },
194
199
  {
195
200
  flags: "--sort-types",
196
201
  description: "sort fields and types",
197
- default: false,
202
+ default: codeGenBaseConfig.sortTypes,
203
+ },
204
+ ],
205
+ });
206
+
207
+ program.addCommand({
208
+ name: "generate-templates",
209
+ description: `Generate ".ejs" templates needed for generate api`,
210
+ options: [
211
+ {
212
+ flags: "-o, --output <string>",
213
+ description: "output path of generated templates",
214
+ default: templateGenBaseConfig.output,
215
+ },
216
+ {
217
+ flags: "-m, --modular",
218
+ description: "generate templates needed to separate files for http client, data contracts, and routes",
219
+ default: templateGenBaseConfig.modular,
220
+ },
221
+ {
222
+ flags: "--http-client <string>",
223
+ description: `http client type (possible values: ${Object.values(HTTP_CLIENT)
224
+ .map((v) => `"${v}"`)
225
+ .join(", ")})`,
226
+ default: templateGenBaseConfig.httpClientType,
227
+ },
228
+ {
229
+ flags: "-c, --clean-output",
230
+ description: "clean output folder before generate template. WARNING: May cause data loss",
231
+ default: templateGenBaseConfig.cleanOutput,
232
+ },
233
+ {
234
+ flags: "--silent",
235
+ description: "Output only errors to console",
236
+ default: templateGenBaseConfig.silent,
198
237
  },
199
238
  ],
200
239
  });
@@ -246,7 +285,7 @@ const main = async () => {
246
285
  break;
247
286
  }
248
287
  case "generate-templates": {
249
- console.info("todo");
288
+ await generateTemplates(options);
250
289
  break;
251
290
  }
252
291
  default: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swagger-typescript-api",
3
- "version": "11.0.0--beta-3",
3
+ "version": "11.0.0--beta-4",
4
4
  "description": "Generate typescript/javascript api from swagger schema",
5
5
  "scripts": {
6
6
  "cli:json": "node index.js -r -d -p ./swagger-test-cli.json -n swagger-test-cli.ts",
@@ -4,7 +4,7 @@ const prettier = require("prettier");
4
4
 
5
5
  class CodeFormatter {
6
6
  /**
7
- * @type {Configuration}
7
+ * @type {CodeGenConfig}
8
8
  */
9
9
  config;
10
10
 
@@ -6,7 +6,7 @@ const { TypeName } = require("./type-name.js");
6
6
  const _ = require("lodash");
7
7
  const { SchemaParser } = require("./schema-parser/schema-parser.js");
8
8
  const { SchemaRoutes } = require("./schema-parser/schema-routes.js");
9
- const { Configuration } = require("./configuration.js");
9
+ const { CodeGenConfig } = require("./configuration.js");
10
10
  const { FileSystem } = require("./util/file-system");
11
11
  const { Templates } = require("./templates");
12
12
  const { translate: translateToJS } = require("./translators/JavaScript");
@@ -17,7 +17,7 @@ const { internalCase } = require("./util/internal-case");
17
17
 
18
18
  class CodeGenProcess {
19
19
  /**
20
- * @type {Configuration}
20
+ * @type {CodeGenConfig}
21
21
  */
22
22
  config;
23
23
  /**
@@ -58,7 +58,7 @@ class CodeGenProcess {
58
58
  * @param config {Partial<import("../index.d.ts").GenerateApiConfiguration['config']>}
59
59
  */
60
60
  constructor(config) {
61
- this.config = new Configuration(config);
61
+ this.config = new CodeGenConfig(config);
62
62
  this.logger = new Logger(this.config);
63
63
  this.fileSystem = new FileSystem();
64
64
  this.swaggerSchemaResolver = new SwaggerSchemaResolver(this.config, this.logger, this.fileSystem);
@@ -0,0 +1,32 @@
1
+ const { objectAssign } = require("../../util/object-assign");
2
+ const { HTTP_CLIENT, PROJECT_VERSION } = require("../../constants");
3
+
4
+ /**
5
+ * @type {GenerateTemplatesParams}}
6
+ */
7
+ class TemplatesGenConfig {
8
+ cleanOutput = false;
9
+ output = undefined;
10
+ httpClientType = HTTP_CLIENT.FETCH;
11
+ modular = false;
12
+ silent = false;
13
+ version = PROJECT_VERSION;
14
+
15
+ /**
16
+ * @param config {GenerateTemplatesParams}
17
+ */
18
+ constructor(config) {
19
+ this.update(config);
20
+ }
21
+
22
+ /**
23
+ * @param update {Partial<GenerateTemplatesParams>}
24
+ */
25
+ update = (update) => {
26
+ objectAssign(this, update);
27
+ };
28
+ }
29
+
30
+ module.exports = {
31
+ TemplatesGenConfig,
32
+ };
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Copyright (c) 2019-present acacode
4
+ // Node module: swagger-typescript-api
5
+ // This file is licensed under the MIT License.
6
+ // License text available at https://opensource.org/licenses/MIT
7
+ // Repository https://github.com/acacode/swagger-typescript-api
8
+
9
+ const _ = require("lodash");
10
+ const { TemplatesGenProcess } = require("./templates-gen-process");
11
+
12
+ module.exports = {
13
+ generateTemplates: async (config) => {
14
+ const codeGenProcess = new TemplatesGenProcess(config);
15
+ return await codeGenProcess.start();
16
+ },
17
+ };