swagger-typescript-api 13.0.0-experimental-1 → 13.0.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.
Files changed (81) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +22 -12
  3. package/cli/constants.js +3 -3
  4. package/cli/execute.js +52 -31
  5. package/cli/index.d.ts +1 -2
  6. package/cli/index.js +18 -17
  7. package/cli/operations/display-help.js +51 -29
  8. package/cli/parse-args.js +3 -3
  9. package/cli/process-option.js +28 -20
  10. package/index.d.ts +113 -8
  11. package/index.js +158 -135
  12. package/package.json +35 -30
  13. package/src/code-formatter.js +28 -13
  14. package/src/code-gen-process.js +357 -259
  15. package/src/commands/generate-templates/configuration.js +2 -2
  16. package/src/commands/generate-templates/index.js +1 -2
  17. package/src/commands/generate-templates/templates-gen-process.js +62 -35
  18. package/src/component-type-name-resolver.js +44 -0
  19. package/src/configuration.js +167 -95
  20. package/src/constants.js +28 -22
  21. package/src/index.js +3 -4
  22. package/src/schema-components-map.js +39 -23
  23. package/src/schema-parser/base-schema-parsers/array.js +43 -0
  24. package/src/schema-parser/base-schema-parsers/complex.js +51 -0
  25. package/src/schema-parser/base-schema-parsers/discriminator.js +301 -0
  26. package/src/schema-parser/base-schema-parsers/enum.js +158 -0
  27. package/src/schema-parser/base-schema-parsers/object.js +105 -0
  28. package/src/schema-parser/base-schema-parsers/primitive.js +63 -0
  29. package/src/schema-parser/complex-schema-parsers/all-of.js +26 -0
  30. package/src/schema-parser/complex-schema-parsers/any-of.js +34 -0
  31. package/src/schema-parser/complex-schema-parsers/not.js +9 -0
  32. package/src/schema-parser/complex-schema-parsers/one-of.js +27 -0
  33. package/src/schema-parser/mono-schema-parser.js +48 -0
  34. package/src/schema-parser/schema-formatters.js +69 -60
  35. package/src/schema-parser/schema-parser-fabric.js +131 -0
  36. package/src/schema-parser/schema-parser.js +208 -427
  37. package/src/schema-parser/schema-utils.js +123 -58
  38. package/src/schema-parser/util/enum-key-resolver.js +26 -0
  39. package/src/schema-routes/schema-routes.js +1225 -0
  40. package/src/schema-routes/util/specific-arg-name-resolver.js +26 -0
  41. package/src/schema-walker.js +93 -0
  42. package/src/swagger-schema-resolver.js +61 -28
  43. package/src/templates-worker.js +240 -0
  44. package/src/translators/javascript.js +83 -0
  45. package/src/translators/translator.js +35 -0
  46. package/src/type-name-formatter.js +33 -18
  47. package/src/util/file-system.js +30 -14
  48. package/src/util/id.js +2 -2
  49. package/src/util/internal-case.js +1 -1
  50. package/src/util/logger.js +46 -20
  51. package/src/util/name-resolver.js +52 -60
  52. package/src/util/object-assign.js +7 -3
  53. package/src/util/pascal-case.js +1 -1
  54. package/src/util/request.js +5 -5
  55. package/src/util/sort-by-property.js +17 -0
  56. package/templates/README.md +17 -17
  57. package/templates/base/README.md +7 -7
  58. package/templates/base/data-contract-jsdoc.ejs +37 -37
  59. package/templates/base/data-contracts.ejs +40 -27
  60. package/templates/base/enum-data-contract.ejs +12 -12
  61. package/templates/base/http-client.ejs +3 -3
  62. package/templates/base/http-clients/axios-http-client.ejs +139 -138
  63. package/templates/base/http-clients/fetch-http-client.ejs +224 -224
  64. package/templates/base/interface-data-contract.ejs +10 -10
  65. package/templates/base/object-field-jsdoc.ejs +28 -28
  66. package/templates/base/route-docs.ejs +30 -30
  67. package/templates/base/route-name.ejs +42 -42
  68. package/templates/base/route-type.ejs +22 -21
  69. package/templates/base/type-data-contract.ejs +15 -15
  70. package/templates/default/README.md +6 -6
  71. package/templates/default/api.ejs +69 -68
  72. package/templates/default/procedure-call.ejs +100 -100
  73. package/templates/default/route-types.ejs +32 -32
  74. package/templates/modular/README.md +6 -6
  75. package/templates/modular/api.ejs +28 -28
  76. package/templates/modular/procedure-call.ejs +100 -100
  77. package/templates/modular/route-types.ejs +18 -18
  78. package/src/schema-parser/schema-processor.js +0 -79
  79. package/src/schema-parser/schema-routes.js +0 -950
  80. package/src/templates.js +0 -182
  81. package/src/translators/JavaScript.js +0 -60
@@ -1,4 +1,4 @@
1
- const _ = require("lodash");
1
+ const _ = require('lodash');
2
2
 
3
3
  /**
4
4
  * @typedef {"enum-key" | "type-name"} FormattingSchemaType
@@ -14,7 +14,7 @@ class TypeNameFormatter {
14
14
  /** @type {Logger} */
15
15
  logger;
16
16
 
17
- constructor(config, logger) {
17
+ constructor({ config, logger }) {
18
18
  this.config = config;
19
19
  this.logger = logger;
20
20
  }
@@ -30,20 +30,27 @@ class TypeNameFormatter {
30
30
  /**
31
31
  * @type {FormattingSchemaType}
32
32
  */
33
- const schemaType = options.type || "type-name";
33
+ const schemaType = options.type || 'type-name';
34
34
 
35
- const typePrefix = schemaType === "enum-key" ? this.config.enumKeyPrefix : this.config.typePrefix;
36
- const typeSuffix = schemaType === "enum-key" ? this.config.enumKeySuffix : this.config.typeSuffix;
35
+ const typePrefix =
36
+ schemaType === 'enum-key'
37
+ ? this.config.enumKeyPrefix
38
+ : this.config.typePrefix;
39
+ const typeSuffix =
40
+ schemaType === 'enum-key'
41
+ ? this.config.enumKeySuffix
42
+ : this.config.typeSuffix;
37
43
 
38
44
  const hashKey = `${typePrefix}_${name}_${typeSuffix}`;
39
45
 
40
- if (typeof name !== "string") {
41
- this.logger.warn("wrong name of the model name", name);
46
+ if (typeof name !== 'string') {
47
+ this.logger.warn('wrong name of the model name', name);
42
48
  return name;
43
49
  }
44
50
 
51
+ // constant names like LEFT_ARROW, RIGHT_FORWARD, ETC_KEY, _KEY_NUM_
45
52
  if (/^([A-Z_]{1,})$/g.test(name)) {
46
- return _.compact([typePrefix, name, typeSuffix]).join("_");
53
+ return _.compact([typePrefix, name, typeSuffix]).join('_');
47
54
  }
48
55
 
49
56
  if (this.formattedModelNamesMap.has(hashKey)) {
@@ -52,8 +59,14 @@ class TypeNameFormatter {
52
59
 
53
60
  const fixedModelName = this.fixModelName(name, { type: schemaType });
54
61
 
55
- const formattedName = _.replace(_.startCase(`${typePrefix}_${fixedModelName}_${typeSuffix}`), /\s/g, "");
56
- const formattedResultName = this.config.hooks.onFormatTypeName(formattedName, name, schemaType) || formattedName;
62
+ const formattedName = _.replace(
63
+ _.startCase(`${typePrefix}_${fixedModelName}_${typeSuffix}`),
64
+ /\s/g,
65
+ '',
66
+ );
67
+ const formattedResultName =
68
+ this.config.hooks.onFormatTypeName(formattedName, name, schemaType) ||
69
+ formattedName;
57
70
 
58
71
  this.formattedModelNamesMap.set(hashKey, formattedResultName);
59
72
 
@@ -68,25 +81,27 @@ class TypeNameFormatter {
68
81
  * @return {string}
69
82
  */
70
83
  fixModelName = (name, options) => {
84
+ const { type } = options || {};
85
+
71
86
  if (!this.isValidName(name)) {
72
87
  if (!/^[a-zA-Z_$]/g.test(name)) {
73
88
  const fixPrefix =
74
- options && options.type === "enum-key"
89
+ type === 'enum-key'
75
90
  ? this.config.fixInvalidEnumKeyPrefix
76
91
  : this.config.fixInvalidTypeNamePrefix;
77
92
  name = `${fixPrefix} ${name}`;
78
93
  }
79
94
 
80
95
  // specific replaces for TSOA 3.x
81
- if (name.includes("."))
96
+ if (name.includes('.'))
82
97
  name = name
83
- .replace(/Exclude_keyof[A-Za-z]{1,}/g, (match) => "ExcludeKeys")
84
- .replace(/%22\~AND\~%22/g, "And")
85
- .replace(/%22\~OR\~%22/g, "Or")
86
- .replace(/(\.?%22)|\./g, "_")
87
- .replace(/__+$/, "");
98
+ .replace(/Exclude_keyof[A-Za-z]+/g, () => 'ExcludeKeys')
99
+ .replace(/%22~AND~%22/g, 'And')
100
+ .replace(/%22~OR~%22/g, 'Or')
101
+ .replace(/(\.?%22)|\./g, '_')
102
+ .replace(/__+$/, '');
88
103
 
89
- if (name.includes("-")) name = _.startCase(name).replace(/ /g, "");
104
+ if (name.includes('-')) name = _.startCase(name).replace(/ /g, '');
90
105
  }
91
106
 
92
107
  return name;
@@ -1,7 +1,8 @@
1
- const fs = require("fs");
2
- const makeDir = require("make-dir");
3
- const { resolve } = require("path");
4
- const _ = require("lodash");
1
+ const fs = require('fs');
2
+ const makeDir = require('make-dir');
3
+ const { resolve } = require('path');
4
+ const _ = require('lodash');
5
+ const { Logger } = require('./logger');
5
6
 
6
7
  const FILE_PREFIX = `/* eslint-disable */
7
8
  /* tslint:disable */
@@ -17,10 +18,15 @@ const FILE_PREFIX = `/* eslint-disable */
17
18
  `;
18
19
 
19
20
  class FileSystem {
20
- constructor() {}
21
+ /** @type {Logger} */
22
+ logger;
23
+
24
+ constructor({ logger = new Logger('file-system') } = {}) {
25
+ this.logger = logger;
26
+ }
21
27
 
22
28
  getFileContent = (path) => {
23
- return fs.readFileSync(path, { encoding: "UTF-8" });
29
+ return fs.readFileSync(path, { encoding: 'UTF-8' });
24
30
  };
25
31
 
26
32
  readDir = (path) => {
@@ -39,29 +45,33 @@ class FileSystem {
39
45
  };
40
46
 
41
47
  cropExtension = (fileName) => {
42
- const fileNameParts = _.split(fileName, ".");
48
+ const fileNameParts = _.split(fileName, '.');
43
49
 
44
50
  if (fileNameParts.length > 1) {
45
51
  fileNameParts.pop();
46
52
  }
47
53
 
48
- return fileNameParts.join(".");
54
+ return fileNameParts.join('.');
49
55
  };
50
56
 
51
57
  removeDir = (path) => {
52
58
  try {
53
- if (typeof fs.rmSync === "function") {
59
+ if (typeof fs.rmSync === 'function') {
54
60
  fs.rmSync(path, { recursive: true });
55
61
  } else {
56
62
  fs.rmdirSync(path, { recursive: true });
57
63
  }
58
- } catch (e) {}
64
+ } catch (e) {
65
+ this.logger.debug('failed to remove dir', e);
66
+ }
59
67
  };
60
68
 
61
69
  createDir = (path) => {
62
70
  try {
63
71
  makeDir.sync(path);
64
- } catch (e) {}
72
+ } catch (e) {
73
+ this.logger.debug('failed to create dir', e);
74
+ }
65
75
  };
66
76
 
67
77
  cleanDir = (path) => {
@@ -69,10 +79,16 @@ class FileSystem {
69
79
  this.createDir(path);
70
80
  };
71
81
 
72
- pathIsExist = (path) => path && fs.existsSync(path);
82
+ pathIsExist = (path) => {
83
+ return !!path && fs.existsSync(path);
84
+ };
85
+
86
+ createFile = ({ path, fileName, content, withPrefix }) => {
87
+ const absolutePath = resolve(__dirname, path, `./${fileName}`);
88
+ const fileContent = `${withPrefix ? FILE_PREFIX : ''}${content}`;
73
89
 
74
- createFile = ({ path, fileName, content, withPrefix }) =>
75
- fs.writeFileSync(resolve(__dirname, path, `./${fileName}`), `${withPrefix ? FILE_PREFIX : ""}${content}`, _.noop);
90
+ return fs.writeFileSync(absolutePath, fileContent, _.noop);
91
+ };
76
92
  }
77
93
 
78
94
  module.exports = {
package/src/util/id.js CHANGED
@@ -1,6 +1,6 @@
1
- const { customAlphabet } = require("nanoid");
1
+ const { customAlphabet } = require('nanoid');
2
2
 
3
- const ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789";
3
+ const ALPHABET = 'abcdefghijklmnopqrstuvwxyz0123456789';
4
4
 
5
5
  const generateId = customAlphabet(ALPHABET, 12);
6
6
 
@@ -1,4 +1,4 @@
1
- const _ = require("lodash");
1
+ const _ = require('lodash');
2
2
 
3
3
  module.exports = {
4
4
  internalCase: (value) => _.camelCase(_.lowerCase(value)),
@@ -1,5 +1,5 @@
1
- const { emojify } = require("node-emoji");
2
- const _ = require("lodash");
1
+ const { emojify } = require('node-emoji');
2
+ const _ = require('lodash');
3
3
 
4
4
  class Logger {
5
5
  firstLog = true;
@@ -8,11 +8,11 @@ class Logger {
8
8
  */
9
9
  config;
10
10
 
11
- constructor(config) {
11
+ constructor({ config }) {
12
12
  this.config = config;
13
13
  }
14
14
 
15
- createLogMessage = ({ type, emojiName, messages, raw }) => {
15
+ createLogMessage = ({ type, emojiName, messages }) => {
16
16
  if (this.config.silent) return;
17
17
 
18
18
  const emoji = emojify(emojiName);
@@ -22,20 +22,44 @@ class Logger {
22
22
  this.log(
23
23
  `swagger-typescript-api(${this.config.version}),${
24
24
  process.env.npm_config_user_agent || `nodejs(${process.version})`
25
- }`,
25
+ },debug mode ${this.config.debug ? 'ENABLED' : 'DISABLED'}`,
26
26
  );
27
27
  }
28
28
 
29
- if (raw) {
30
- console.log(...raw);
29
+ if (type === 'debug' || this.config.debug) {
30
+ const trace = new Error().stack
31
+ .split('\n')
32
+ .splice(3)
33
+ .filter(
34
+ (line) =>
35
+ !line.includes('swagger-typescript-api\\node_modules') &&
36
+ !line.includes('swagger-typescript-api/node_modules'),
37
+ )
38
+ .slice(0, 10);
39
+ const logFn = console[type] || console.log;
40
+ logFn(`${emoji} [${type}]`, new Date().toISOString());
41
+ if (this.config.debugExtras && Array.isArray(this.config.debugExtras)) {
42
+ logFn(`[${this.config.debugExtras.join(' ')}]`);
43
+ }
44
+ logFn(
45
+ '[message]',
46
+ ..._.map(messages, (message) =>
47
+ _.startsWith(message, '\n')
48
+ ? `\n ${message.replace(/\n/, '')}`
49
+ : message,
50
+ ),
51
+ );
52
+ logFn(trace.join('\n') + '\n---');
31
53
  return;
32
54
  }
33
55
 
34
56
  console[type](
35
57
  emoji,
36
- " ",
58
+ ' ',
37
59
  ..._.map(messages, (message) =>
38
- _.startsWith(message, "\n") ? `\n${emoji} ${message.replace(/\n/, "")}` : message,
60
+ _.startsWith(message, '\n')
61
+ ? `\n${emoji} ${message.replace(/\n/, '')}`
62
+ : message,
39
63
  ),
40
64
  );
41
65
  };
@@ -46,8 +70,8 @@ class Logger {
46
70
  */
47
71
  log = (...messages) =>
48
72
  this.createLogMessage({
49
- type: "log",
50
- emojiName: ":sparkles:",
73
+ type: 'log',
74
+ emojiName: ':sparkles:',
51
75
  messages,
52
76
  });
53
77
 
@@ -58,8 +82,8 @@ class Logger {
58
82
  */
59
83
  event = (...messages) =>
60
84
  this.createLogMessage({
61
- type: "log",
62
- emojiName: ":comet: ",
85
+ type: 'log',
86
+ emojiName: ':star:',
63
87
  messages,
64
88
  });
65
89
 
@@ -70,8 +94,8 @@ class Logger {
70
94
  */
71
95
  success = (...messages) =>
72
96
  this.createLogMessage({
73
- type: "log",
74
- emojiName: ":white_check_mark:",
97
+ type: 'log',
98
+ emojiName: ':white_check_mark:',
75
99
  messages,
76
100
  });
77
101
 
@@ -82,8 +106,8 @@ class Logger {
82
106
  */
83
107
  warn = (...messages) =>
84
108
  this.createLogMessage({
85
- type: "warn",
86
- emojiName: ":warning: ",
109
+ type: 'warn',
110
+ emojiName: ':exclamation:',
87
111
  messages,
88
112
  });
89
113
 
@@ -94,8 +118,8 @@ class Logger {
94
118
  */
95
119
  error = (...messages) =>
96
120
  this.createLogMessage({
97
- type: "error",
98
- emojiName: ":exclamation:",
121
+ type: 'error',
122
+ emojiName: ':no_entry:',
99
123
  messages,
100
124
  });
101
125
 
@@ -108,7 +132,9 @@ class Logger {
108
132
  if (!this.config.debug) return;
109
133
 
110
134
  this.createLogMessage({
111
- raw: messages,
135
+ type: 'debug',
136
+ emojiName: ':black_large_square:',
137
+ messages,
112
138
  });
113
139
  };
114
140
  }
@@ -1,20 +1,21 @@
1
- const _ = require("lodash");
2
- const { getRandomInt } = require("./random.js");
1
+ const _ = require('lodash');
3
2
 
4
3
  class NameResolver {
5
4
  reservedNames = [];
6
5
  getFallbackName = null;
7
6
 
8
- /**
9
- * @type {Logger}
10
- */
7
+ /** @type {CodeGenConfig} */
8
+ config;
9
+ /** @type {Logger} */
11
10
  logger;
12
11
 
13
12
  /**
13
+ * @param {CodeGenConfig} config;
14
14
  * @param {Logger} logger;
15
15
  * @param {string[]} reservedNames
16
16
  */
17
- constructor(logger, reservedNames, getFallbackName) {
17
+ constructor(config, logger, reservedNames, getFallbackName) {
18
+ this.config = config;
18
19
  this.logger = logger;
19
20
  this.getFallbackName = getFallbackName;
20
21
  this.reserve(reservedNames);
@@ -24,11 +25,18 @@ class NameResolver {
24
25
  * @param {string[]} names
25
26
  */
26
27
  reserve(names) {
27
- this.reservedNames.push(..._.uniq(_.compact(names)));
28
+ const fixedNames = _.uniq(_.compact(names));
29
+ for (const name of fixedNames) {
30
+ if (this.reservedNames.indexOf(name) === -1) {
31
+ this.reservedNames.push(name);
32
+ }
33
+ }
28
34
  }
29
35
 
30
36
  unreserve(names) {
31
- this.reservedNames.filter((reservedName) => !names.some((name) => name === reservedName));
37
+ this.reservedNames.filter(
38
+ (reservedName) => !names.some((name) => name === reservedName),
39
+ );
32
40
  }
33
41
 
34
42
  isReserved(name) {
@@ -37,77 +45,61 @@ class NameResolver {
37
45
 
38
46
  /**
39
47
  *
40
- * @param {(string[]) | ((reserved: string[]) => string)} variantsOrResolver
48
+ * @param {(string[])} variants
49
+ * @param {(reserved: string[]) => string)} [resolver]
50
+ * @param {any} [extras]
41
51
  * @returns {string | null}
42
52
  */
43
- resolve(variantsOrResolver) {
44
- this.logger.debug("resolving name with using", variantsOrResolver);
45
- if (Array.isArray(variantsOrResolver)) {
46
- const variants = variantsOrResolver;
53
+ resolve(variants, resolver, extras, shouldReserve = true) {
54
+ if (typeof resolver === 'function') {
47
55
  let usageName = null;
48
- const uniqVariants = _.uniq(_.compact(variants));
56
+ while (usageName === null) {
57
+ const variant = resolver(variants, extras);
49
58
 
50
- _.forEach(uniqVariants, (variant) => {
51
- if (!usageName && !this.isReserved(variant)) {
59
+ if (variant === undefined) {
60
+ this.logger.warn(
61
+ 'unable to resolve name. current reserved names: ',
62
+ this.reservedNames,
63
+ );
64
+ return null;
65
+ }
66
+ if (!shouldReserve || !this.isReserved(variant)) {
52
67
  usageName = variant;
53
68
  }
54
- });
55
-
56
- if (usageName) {
57
- this.reserve([usageName]);
58
- return usageName;
59
69
  }
60
70
 
61
- this.logger.debug("trying to resolve name with using fallback name generator");
62
- return this.resolve(this.getFallbackName);
63
- } else if (typeof variantsOrResolver === "function") {
71
+ shouldReserve && this.reserve([usageName]);
72
+ return usageName;
73
+ } else if (Array.isArray(variants)) {
64
74
  let usageName = null;
65
- while (usageName === null) {
66
- const variant = variantsOrResolver(this.reservedNames);
75
+ const uniqVariants = _.uniq(_.compact(variants));
67
76
 
68
- if (variant === undefined) {
69
- this.logger.warn("unable to resolve name. current reserved names: ", this.reservedNames);
70
- return null;
71
- }
72
- if (!this.isReserved(variant)) {
77
+ _.forEach(uniqVariants, (variant) => {
78
+ if (!usageName && (!shouldReserve || !this.isReserved(variant))) {
73
79
  usageName = variant;
74
80
  }
81
+ });
82
+
83
+ if (usageName) {
84
+ shouldReserve && this.reserve([usageName]);
85
+ return usageName;
75
86
  }
76
87
 
77
- this.reserve([usageName]);
78
- return usageName;
88
+ this.logger.debug(
89
+ 'trying to resolve name with using fallback name generator using variants',
90
+ variants,
91
+ );
92
+ return this.resolve(variants, this.getFallbackName, extras);
79
93
  }
80
94
 
81
- this.logger.debug("problem with reserving names. current reserved names: ", this.reservedNames);
95
+ this.logger.debug(
96
+ 'problem with reserving names. current reserved names: ',
97
+ this.reservedNames,
98
+ );
82
99
  return null;
83
100
  }
84
101
  }
85
102
 
86
- class SpecificArgNameResolver extends NameResolver {
87
- /**
88
- * @param {Logger} logger;
89
- * @param {string[]} reservedNames
90
- */
91
- constructor(logger, reservedNames) {
92
- super(logger, reservedNames, (variants) => {
93
- return (variants[0] && `${variants[0]}${getRandomInt(1, 10)}`) || `arg${getRandomInt(1, 10)}`;
94
- });
95
- }
96
- }
97
-
98
- class ComponentTypeNameResolver extends NameResolver {
99
- /**
100
- * @param {Logger} logger;
101
- * @param {string[]} reservedNames
102
- */
103
- constructor(logger, reservedNames) {
104
- super(logger, reservedNames, (variants) => {
105
- return (variants[0] && `${variants[0]}${getRandomInt(1, 10)}`) || `ComponentType${getRandomInt(1, 10)}`;
106
- });
107
- }
108
- }
109
-
110
103
  module.exports = {
111
- SpecificArgNameResolver,
112
- ComponentTypeNameResolver,
104
+ NameResolver,
113
105
  };
@@ -1,9 +1,13 @@
1
- const _ = require("lodash");
1
+ const _ = require('lodash');
2
2
 
3
3
  const objectAssign = (target, updaterFn) => {
4
4
  if (!updaterFn) return;
5
- const update = typeof updaterFn === "function" ? updaterFn(target) : updaterFn;
6
- const undefinedKeys = _.map(update, (value, key) => value === undefined && key).filter(Boolean);
5
+ const update =
6
+ typeof updaterFn === 'function' ? updaterFn(target) : updaterFn;
7
+ const undefinedKeys = _.map(
8
+ update,
9
+ (value, key) => value === undefined && key,
10
+ ).filter(Boolean);
7
11
  Object.assign(target, _.merge(target, update));
8
12
  undefinedKeys.forEach((key) => {
9
13
  target[key] = undefined;
@@ -1,4 +1,4 @@
1
- const _ = require("lodash");
1
+ const _ = require('lodash');
2
2
 
3
3
  module.exports = {
4
4
  pascalCase: (value) => _.upperFirst(_.camelCase(value)),
@@ -1,6 +1,6 @@
1
- const _ = require("lodash");
2
- const https = require("https");
3
- const fetch = require("node-fetch-h2");
1
+ const _ = require('lodash');
2
+ const https = require('https');
3
+ const fetch = require('node-fetch-h2');
4
4
 
5
5
  class Request {
6
6
  /**
@@ -31,7 +31,7 @@ class Request {
31
31
  */
32
32
  const requestOptions = {};
33
33
 
34
- if (disableStrictSSL && !_.startsWith(url, "http://")) {
34
+ if (disableStrictSSL && !_.startsWith(url, 'http://')) {
35
35
  requestOptions.agent = new https.Agent({
36
36
  rejectUnauthorized: false,
37
37
  });
@@ -49,7 +49,7 @@ class Request {
49
49
  return await response.text();
50
50
  } catch (error) {
51
51
  const message = `error while fetching data from URL "${url}"`;
52
- this.logger.error(message, "response" in error ? error.response : error);
52
+ this.logger.error(message, 'response' in error ? error.response : error);
53
53
  return message;
54
54
  }
55
55
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @param propertyName {string}
3
+ * @returns {(o1: Record<string, any>, o2: Record<string, any>) => 1 | -1 | 0}
4
+ */
5
+ const sortByProperty = (propertyName) => (o1, o2) => {
6
+ if (o1[propertyName] > o2[propertyName]) {
7
+ return 1;
8
+ }
9
+ if (o1[propertyName] < o2[propertyName]) {
10
+ return -1;
11
+ }
12
+ return 0;
13
+ };
14
+
15
+ module.exports = {
16
+ sortByProperty,
17
+ };
@@ -1,17 +1,17 @@
1
- # swagger-typescript-api
2
-
3
- # templates
4
-
5
- Templates:
6
- - `api.ejs` - *(generates file)* Api class module (locations: [default](https://github.com/acacode/swagger-typescript-api/tree/next/templates/default/api.ejs), [modular](https://github.com/acacode/swagger-typescript-api/tree/next/templates/modular/api.ejs))
7
- - `data-contracts.ejs` - *(generates file)* all types (data contracts) from swagger schema (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/data-contracts.ejs))
8
- - `http-client.ejs` - *(generates file)* HttpClient class module (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/http-client.ejs))
9
- - `procedure-call.ejs` - *(subtemplate)* route in Api class (locations: [default](https://github.com/acacode/swagger-typescript-api/tree/next/templates/default/procedure-call.ejs), [modular](https://github.com/acacode/swagger-typescript-api/tree/next/templates/modular/procedure-call.ejs))
10
- - `route-docs.ejs` - *(generates file)* documentation for route in Api class (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/route-docs.ejs))
11
- - `route-name.ejs` - *(subtemplate)* route name for route in Api class (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/route-name.ejs))
12
- - `route-type.ejs` - *(`--route-types` option)* *(subtemplate)* (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/route-type.ejs))
13
- - `route-types.ejs` - *(`--route-types` option)* *(subtemplate)* (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/route-types.ejs)) - `data-contract-jsdoc.ejs` - *(subtemplate)* generates JSDOC for data contract (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/data-contract-jsdoc.ejs))
14
-
15
- [//]: # (- `enum-data-contract.ejs` - *&#40;subtemplate&#41;* generates `enum` data contract &#40;locations: [base]&#40;https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/enum-data-contract.ejs&#41;&#41;)
16
- [//]: # (- `interface-data-contract.ejs` - *&#40;subtemplate&#41;* generates `interface` data contract &#40;locations: [base]&#40;https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/interface-data-contract.ejs&#41;&#41;)
17
- [//]: # (- `type-data-contract.ejs` - *&#40;subtemplate&#41;* generates `type` data contract &#40;locations: [base]&#40;https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/type-data-contract.ejs&#41;&#41;)
1
+ # swagger-typescript-api
2
+
3
+ # templates
4
+
5
+ Templates:
6
+ - `api.ejs` - *(generates file)* Api class module (locations: [default](https://github.com/acacode/swagger-typescript-api/tree/next/templates/default/api.ejs), [modular](https://github.com/acacode/swagger-typescript-api/tree/next/templates/modular/api.ejs))
7
+ - `data-contracts.ejs` - *(generates file)* all types (data contracts) from swagger schema (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/data-contracts.ejs))
8
+ - `http-client.ejs` - *(generates file)* HttpClient class module (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/http-client.ejs))
9
+ - `procedure-call.ejs` - *(subtemplate)* route in Api class (locations: [default](https://github.com/acacode/swagger-typescript-api/tree/next/templates/default/procedure-call.ejs), [modular](https://github.com/acacode/swagger-typescript-api/tree/next/templates/modular/procedure-call.ejs))
10
+ - `route-docs.ejs` - *(generates file)* documentation for route in Api class (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/route-docs.ejs))
11
+ - `route-name.ejs` - *(subtemplate)* route name for route in Api class (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/route-name.ejs))
12
+ - `route-type.ejs` - *(`--route-types` option)* *(subtemplate)* (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/route-type.ejs))
13
+ - `route-types.ejs` - *(`--route-types` option)* *(subtemplate)* (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/route-types.ejs)) - `data-contract-jsdoc.ejs` - *(subtemplate)* generates JSDOC for data contract (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/data-contract-jsdoc.ejs))
14
+
15
+ [//]: # (- `enum-data-contract.ejs` - *&#40;subtemplate&#41;* generates `enum` data contract &#40;locations: [base]&#40;https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/enum-data-contract.ejs&#41;&#41;)
16
+ [//]: # (- `interface-data-contract.ejs` - *&#40;subtemplate&#41;* generates `interface` data contract &#40;locations: [base]&#40;https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/interface-data-contract.ejs&#41;&#41;)
17
+ [//]: # (- `type-data-contract.ejs` - *&#40;subtemplate&#41;* generates `type` data contract &#40;locations: [base]&#40;https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/type-data-contract.ejs&#41;&#41;)
@@ -1,8 +1,8 @@
1
- # swagger-typescript-api
2
-
3
- # templates/base
4
-
5
- This templates use both for multiple api files and single api file
6
-
7
-
1
+ # swagger-typescript-api
2
+
3
+ # templates/base
4
+
5
+ This templates use both for multiple api files and single api file
6
+
7
+
8
8
  path prefix `@base`