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.
- package/LICENSE +21 -21
- package/README.md +22 -12
- package/cli/constants.js +3 -3
- package/cli/execute.js +52 -31
- package/cli/index.d.ts +1 -2
- package/cli/index.js +18 -17
- package/cli/operations/display-help.js +51 -29
- package/cli/parse-args.js +3 -3
- package/cli/process-option.js +28 -20
- package/index.d.ts +113 -8
- package/index.js +158 -135
- package/package.json +35 -30
- package/src/code-formatter.js +28 -13
- package/src/code-gen-process.js +357 -259
- package/src/commands/generate-templates/configuration.js +2 -2
- package/src/commands/generate-templates/index.js +1 -2
- package/src/commands/generate-templates/templates-gen-process.js +62 -35
- package/src/component-type-name-resolver.js +44 -0
- package/src/configuration.js +167 -95
- package/src/constants.js +28 -22
- package/src/index.js +3 -4
- package/src/schema-components-map.js +39 -23
- package/src/schema-parser/base-schema-parsers/array.js +43 -0
- package/src/schema-parser/base-schema-parsers/complex.js +51 -0
- package/src/schema-parser/base-schema-parsers/discriminator.js +301 -0
- package/src/schema-parser/base-schema-parsers/enum.js +158 -0
- package/src/schema-parser/base-schema-parsers/object.js +105 -0
- package/src/schema-parser/base-schema-parsers/primitive.js +63 -0
- package/src/schema-parser/complex-schema-parsers/all-of.js +26 -0
- package/src/schema-parser/complex-schema-parsers/any-of.js +34 -0
- package/src/schema-parser/complex-schema-parsers/not.js +9 -0
- package/src/schema-parser/complex-schema-parsers/one-of.js +27 -0
- package/src/schema-parser/mono-schema-parser.js +48 -0
- package/src/schema-parser/schema-formatters.js +69 -60
- package/src/schema-parser/schema-parser-fabric.js +131 -0
- package/src/schema-parser/schema-parser.js +208 -427
- package/src/schema-parser/schema-utils.js +123 -58
- package/src/schema-parser/util/enum-key-resolver.js +26 -0
- package/src/schema-routes/schema-routes.js +1225 -0
- package/src/schema-routes/util/specific-arg-name-resolver.js +26 -0
- package/src/schema-walker.js +93 -0
- package/src/swagger-schema-resolver.js +61 -28
- package/src/templates-worker.js +240 -0
- package/src/translators/javascript.js +83 -0
- package/src/translators/translator.js +35 -0
- package/src/type-name-formatter.js +33 -18
- package/src/util/file-system.js +30 -14
- package/src/util/id.js +2 -2
- package/src/util/internal-case.js +1 -1
- package/src/util/logger.js +46 -20
- package/src/util/name-resolver.js +52 -60
- package/src/util/object-assign.js +7 -3
- package/src/util/pascal-case.js +1 -1
- package/src/util/request.js +5 -5
- package/src/util/sort-by-property.js +17 -0
- package/templates/README.md +17 -17
- package/templates/base/README.md +7 -7
- package/templates/base/data-contract-jsdoc.ejs +37 -37
- package/templates/base/data-contracts.ejs +40 -27
- package/templates/base/enum-data-contract.ejs +12 -12
- package/templates/base/http-client.ejs +3 -3
- package/templates/base/http-clients/axios-http-client.ejs +139 -138
- package/templates/base/http-clients/fetch-http-client.ejs +224 -224
- package/templates/base/interface-data-contract.ejs +10 -10
- package/templates/base/object-field-jsdoc.ejs +28 -28
- package/templates/base/route-docs.ejs +30 -30
- package/templates/base/route-name.ejs +42 -42
- package/templates/base/route-type.ejs +22 -21
- package/templates/base/type-data-contract.ejs +15 -15
- package/templates/default/README.md +6 -6
- package/templates/default/api.ejs +69 -68
- package/templates/default/procedure-call.ejs +100 -100
- package/templates/default/route-types.ejs +32 -32
- package/templates/modular/README.md +6 -6
- package/templates/modular/api.ejs +28 -28
- package/templates/modular/procedure-call.ejs +100 -100
- package/templates/modular/route-types.ejs +18 -18
- package/src/schema-parser/schema-processor.js +0 -79
- package/src/schema-parser/schema-routes.js +0 -950
- package/src/templates.js +0 -182
- package/src/translators/JavaScript.js +0 -60
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const _ = require(
|
|
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 ||
|
|
33
|
+
const schemaType = options.type || 'type-name';
|
|
34
34
|
|
|
35
|
-
const typePrefix =
|
|
36
|
-
|
|
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 !==
|
|
41
|
-
this.logger.warn(
|
|
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(
|
|
56
|
-
|
|
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
|
-
|
|
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]
|
|
84
|
-
.replace(/%22
|
|
85
|
-
.replace(/%22
|
|
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(
|
|
104
|
+
if (name.includes('-')) name = _.startCase(name).replace(/ /g, '');
|
|
90
105
|
}
|
|
91
106
|
|
|
92
107
|
return name;
|
package/src/util/file-system.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
const fs = require(
|
|
2
|
-
const makeDir = require(
|
|
3
|
-
const { resolve } = require(
|
|
4
|
-
const _ = require(
|
|
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
|
-
|
|
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:
|
|
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 ===
|
|
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) =>
|
|
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
|
-
|
|
75
|
-
|
|
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(
|
|
1
|
+
const { customAlphabet } = require('nanoid');
|
|
2
2
|
|
|
3
|
-
const ALPHABET =
|
|
3
|
+
const ALPHABET = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
4
4
|
|
|
5
5
|
const generateId = customAlphabet(ALPHABET, 12);
|
|
6
6
|
|
package/src/util/logger.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const { emojify } = require(
|
|
2
|
-
const _ = require(
|
|
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
|
|
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 (
|
|
30
|
-
|
|
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,
|
|
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:
|
|
50
|
-
emojiName:
|
|
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:
|
|
62
|
-
emojiName:
|
|
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:
|
|
74
|
-
emojiName:
|
|
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:
|
|
86
|
-
emojiName:
|
|
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:
|
|
98
|
-
emojiName:
|
|
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
|
-
|
|
135
|
+
type: 'debug',
|
|
136
|
+
emojiName: ':black_large_square:',
|
|
137
|
+
messages,
|
|
112
138
|
});
|
|
113
139
|
};
|
|
114
140
|
}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
const _ = require(
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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[])
|
|
48
|
+
* @param {(string[])} variants
|
|
49
|
+
* @param {(reserved: string[]) => string)} [resolver]
|
|
50
|
+
* @param {any} [extras]
|
|
41
51
|
* @returns {string | null}
|
|
42
52
|
*/
|
|
43
|
-
resolve(
|
|
44
|
-
|
|
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
|
-
|
|
56
|
+
while (usageName === null) {
|
|
57
|
+
const variant = resolver(variants, extras);
|
|
49
58
|
|
|
50
|
-
|
|
51
|
-
|
|
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.
|
|
62
|
-
return
|
|
63
|
-
} else if (
|
|
71
|
+
shouldReserve && this.reserve([usageName]);
|
|
72
|
+
return usageName;
|
|
73
|
+
} else if (Array.isArray(variants)) {
|
|
64
74
|
let usageName = null;
|
|
65
|
-
|
|
66
|
-
const variant = variantsOrResolver(this.reservedNames);
|
|
75
|
+
const uniqVariants = _.uniq(_.compact(variants));
|
|
67
76
|
|
|
68
|
-
|
|
69
|
-
|
|
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.
|
|
78
|
-
|
|
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(
|
|
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
|
-
|
|
112
|
-
ComponentTypeNameResolver,
|
|
104
|
+
NameResolver,
|
|
113
105
|
};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
const _ = require(
|
|
1
|
+
const _ = require('lodash');
|
|
2
2
|
|
|
3
3
|
const objectAssign = (target, updaterFn) => {
|
|
4
4
|
if (!updaterFn) return;
|
|
5
|
-
const update =
|
|
6
|
-
|
|
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;
|
package/src/util/pascal-case.js
CHANGED
package/src/util/request.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const _ = require(
|
|
2
|
-
const https = require(
|
|
3
|
-
const fetch = require(
|
|
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,
|
|
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,
|
|
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
|
+
};
|
package/templates/README.md
CHANGED
|
@@ -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` - *(subtemplate)* generates `enum` data contract (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/enum-data-contract.ejs)))
|
|
16
|
-
[//]: # (- `interface-data-contract.ejs` - *(subtemplate)* generates `interface` data contract (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/interface-data-contract.ejs)))
|
|
17
|
-
[//]: # (- `type-data-contract.ejs` - *(subtemplate)* generates `type` data contract (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/type-data-contract.ejs)))
|
|
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` - *(subtemplate)* generates `enum` data contract (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/enum-data-contract.ejs)))
|
|
16
|
+
[//]: # (- `interface-data-contract.ejs` - *(subtemplate)* generates `interface` data contract (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/interface-data-contract.ejs)))
|
|
17
|
+
[//]: # (- `type-data-contract.ejs` - *(subtemplate)* generates `type` data contract (locations: [base](https://github.com/acacode/swagger-typescript-api/tree/next/templates/base/type-data-contract.ejs)))
|
package/templates/base/README.md
CHANGED
|
@@ -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`
|