swagger-typescript-api 10.0.3 → 11.0.0--alpha
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/README.md +218 -0
- package/index.d.ts +93 -0
- package/index.js +230 -103
- package/package.json +121 -119
- package/src/code-formatter.js +101 -0
- package/src/code-gen-process.js +456 -0
- package/src/configuration.js +425 -0
- package/src/constants.js +14 -31
- package/src/index.js +6 -257
- package/src/schema-components-map.js +60 -0
- package/src/schema-parser/schema-formatters.js +145 -0
- package/src/schema-parser/schema-parser.js +497 -0
- package/src/schema-parser/schema-routes.js +902 -0
- package/src/swagger-schema-resolver.js +187 -0
- package/src/templates.js +141 -122
- package/src/translators/JavaScript.js +49 -49
- package/src/type-name.js +79 -0
- package/src/util/file-system.js +76 -0
- package/src/{utils → util}/id.js +0 -0
- package/src/util/internal-case.js +5 -0
- package/src/util/logger.js +100 -0
- package/src/{utils/resolveName.js → util/name-resolver.js} +1 -1
- package/src/util/object-assign.js +11 -0
- package/src/util/pascal-case.js +5 -0
- package/src/{utils → util}/random.js +1 -1
- package/templates/base/data-contract-jsdoc.ejs +29 -24
- package/templates/base/data-contracts.ejs +3 -3
- package/templates/base/interface-data-contract.ejs +1 -0
- package/templates/base/route-docs.ejs +2 -2
- package/templates/base/route-type.ejs +2 -2
- package/templates/default/route-types.ejs +2 -2
- package/templates/modular/api.ejs +2 -2
- package/templates/modular/route-types.ejs +2 -2
- package/src/apiConfig.js +0 -30
- package/src/common.js +0 -28
- package/src/components.js +0 -91
- package/src/config.js +0 -108
- package/src/filePrefix.js +0 -14
- package/src/files.js +0 -56
- package/src/formatFileContent.js +0 -81
- package/src/logger.js +0 -68
- package/src/modelNames.js +0 -74
- package/src/modelTypes.js +0 -31
- package/src/output.js +0 -165
- package/src/prettierOptions.js +0 -23
- package/src/render/utils/fmtToJSDocLine.js +0 -10
- package/src/render/utils/index.js +0 -31
- package/src/render/utils/templateRequire.js +0 -17
- package/src/routeNames.js +0 -46
- package/src/routes.js +0 -809
- package/src/schema.js +0 -474
- package/src/swagger.js +0 -152
- package/src/typeFormatters.js +0 -121
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
const { Configuration } = require("./configuration.js");
|
|
2
|
+
const _ = require("lodash");
|
|
3
|
+
const converter = require("swagger2openapi");
|
|
4
|
+
const https = require("https");
|
|
5
|
+
const axios = require("axios");
|
|
6
|
+
const yaml = require("js-yaml");
|
|
7
|
+
|
|
8
|
+
class SwaggerSchemaResolver {
|
|
9
|
+
/**
|
|
10
|
+
* @type {Configuration}
|
|
11
|
+
*/
|
|
12
|
+
config;
|
|
13
|
+
/**
|
|
14
|
+
* @type {Logger}
|
|
15
|
+
*/
|
|
16
|
+
logger;
|
|
17
|
+
/**
|
|
18
|
+
* @type {FileSystem}
|
|
19
|
+
*/
|
|
20
|
+
fileSystem;
|
|
21
|
+
|
|
22
|
+
constructor(configuration, logger, fileSystem) {
|
|
23
|
+
this.config = configuration;
|
|
24
|
+
this.logger = logger;
|
|
25
|
+
this.fileSystem = fileSystem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @returns {Promise<{usageSchema: Record<string, *>, originalSchema: Record<string, *>}>}
|
|
31
|
+
*/
|
|
32
|
+
async create() {
|
|
33
|
+
const { spec, patch, input, url, disableStrictSSL, disableProxy, authorizationToken } = this.config;
|
|
34
|
+
|
|
35
|
+
if (this.config.spec) {
|
|
36
|
+
return await this.convertSwaggerObject(spec, { patch });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const swaggerSchemaFile = await this.fetchSwaggerSchemaFile(
|
|
40
|
+
input,
|
|
41
|
+
url,
|
|
42
|
+
disableStrictSSL,
|
|
43
|
+
disableProxy,
|
|
44
|
+
authorizationToken,
|
|
45
|
+
);
|
|
46
|
+
const swaggerSchemaObject = this.processSwaggerSchemaFile(swaggerSchemaFile);
|
|
47
|
+
return await this.convertSwaggerObject(swaggerSchemaObject, { patch });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @param swaggerSchema {Record<string, any>}
|
|
53
|
+
* @param converterOptions {{ patch?: boolean }}
|
|
54
|
+
* @returns {Promise<{ usageSchema: Record<string, any>, originalSchema: Record<string, any>}>}
|
|
55
|
+
*/
|
|
56
|
+
convertSwaggerObject(swaggerSchema, converterOptions) {
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
const result = _.cloneDeep(swaggerSchema);
|
|
59
|
+
result.info = _.merge(
|
|
60
|
+
{
|
|
61
|
+
title: "No title",
|
|
62
|
+
version: "",
|
|
63
|
+
},
|
|
64
|
+
result.info,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
if (!result.openapi) {
|
|
68
|
+
result.paths = _.merge({}, result.paths);
|
|
69
|
+
|
|
70
|
+
converter.convertObj(
|
|
71
|
+
result,
|
|
72
|
+
{
|
|
73
|
+
...converterOptions,
|
|
74
|
+
warnOnly: true,
|
|
75
|
+
refSiblings: "preserve",
|
|
76
|
+
rbname: "requestBodyName",
|
|
77
|
+
},
|
|
78
|
+
(err, options) => {
|
|
79
|
+
const parsedSwaggerSchema = _.get(err, "options.openapi", _.get(options, "openapi"));
|
|
80
|
+
if (!parsedSwaggerSchema && err) {
|
|
81
|
+
throw new Error(err);
|
|
82
|
+
}
|
|
83
|
+
this.config.update({ convertedFromSwagger2: true });
|
|
84
|
+
resolve({
|
|
85
|
+
usageSchema: parsedSwaggerSchema,
|
|
86
|
+
originalSchema: result,
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
} else {
|
|
91
|
+
resolve({
|
|
92
|
+
usageSchema: result,
|
|
93
|
+
originalSchema: _.cloneDeep(result),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
fetchSwaggerSchemaFile(pathToSwagger, urlToSwagger, disableStrictSSL, disableProxy, authorizationToken) {
|
|
100
|
+
return new Promise((resolve, reject) => {
|
|
101
|
+
if (this.fileSystem.pathIsExist(pathToSwagger)) {
|
|
102
|
+
this.logger.log(`try to get swagger by path "${pathToSwagger}"`);
|
|
103
|
+
resolve(this.fileSystem.getFileContent(pathToSwagger));
|
|
104
|
+
} else {
|
|
105
|
+
this.logger.log(`try to get swagger by URL "${urlToSwagger}"`);
|
|
106
|
+
// setup options for Axios
|
|
107
|
+
const axiosOptions = {
|
|
108
|
+
maxContentLength: Infinity,
|
|
109
|
+
maxBodyLength: Infinity,
|
|
110
|
+
};
|
|
111
|
+
//
|
|
112
|
+
if (disableStrictSSL) {
|
|
113
|
+
axiosOptions.httpsAgent = new https.Agent({
|
|
114
|
+
rejectUnauthorized: false,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//
|
|
118
|
+
if (authorizationToken) {
|
|
119
|
+
axiosOptions.headers = {
|
|
120
|
+
Authorization: authorizationToken,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//
|
|
124
|
+
if (disableProxy) axiosOptions.proxy = false;
|
|
125
|
+
//
|
|
126
|
+
axios
|
|
127
|
+
.get(urlToSwagger, axiosOptions)
|
|
128
|
+
.then((res) => resolve(res.data))
|
|
129
|
+
.catch((error) => {
|
|
130
|
+
const message = `error while getting swagger by URL ${urlToSwagger}`;
|
|
131
|
+
|
|
132
|
+
this.logger.error(message, "response" in error ? error.response : error);
|
|
133
|
+
|
|
134
|
+
reject(message);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
processSwaggerSchemaFile(file) {
|
|
141
|
+
if (typeof file !== "string") return file;
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
return JSON.parse(file);
|
|
145
|
+
} catch (e) {
|
|
146
|
+
return yaml.load(file);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
fixSwaggerSchema({ usageSchema, originalSchema }) {
|
|
151
|
+
const usagePaths = _.get(usageSchema, "paths");
|
|
152
|
+
const originalPaths = _.get(originalSchema, "paths");
|
|
153
|
+
|
|
154
|
+
// walk by routes
|
|
155
|
+
_.each(usagePaths, (usagePathObject, route) => {
|
|
156
|
+
const originalPathObject = _.get(originalPaths, route);
|
|
157
|
+
|
|
158
|
+
// walk by methods
|
|
159
|
+
_.each(usagePathObject, (usageRouteInfo, methodName) => {
|
|
160
|
+
const originalRouteInfo = _.get(originalPathObject, methodName);
|
|
161
|
+
const usageRouteParams = _.get(usageRouteInfo, "parameters", []);
|
|
162
|
+
const originalRouteParams = _.get(originalRouteInfo, "parameters", []);
|
|
163
|
+
|
|
164
|
+
usageRouteInfo.consumes = _.uniq(
|
|
165
|
+
_.compact([...(usageRouteInfo.consumes || []), ...(originalRouteInfo.consumes || [])]),
|
|
166
|
+
);
|
|
167
|
+
usageRouteInfo.produces = _.uniq(
|
|
168
|
+
_.compact([...(usageRouteInfo.produces || []), ...(originalRouteInfo.produces || [])]),
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
_.each(originalRouteParams, (originalRouteParam) => {
|
|
172
|
+
const existUsageParam = _.find(
|
|
173
|
+
usageRouteParams,
|
|
174
|
+
(param) => originalRouteParam.in === param.in && originalRouteParam.name === param.name,
|
|
175
|
+
);
|
|
176
|
+
if (!existUsageParam) {
|
|
177
|
+
usageRouteParams.push(originalRouteParam);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
module.exports = {
|
|
186
|
+
SwaggerSchemaResolver,
|
|
187
|
+
};
|
package/src/templates.js
CHANGED
|
@@ -1,155 +1,174 @@
|
|
|
1
|
+
const { resolve } = require("path");
|
|
1
2
|
const _ = require("lodash");
|
|
2
3
|
const Eta = require("eta");
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const defaultTemplatesPath = resolve(__dirname, "../templates/default");
|
|
30
|
-
const modularTemplatesPath = resolve(__dirname, "../templates/modular");
|
|
31
|
-
const originalTemplatesPath = modular ? modularTemplatesPath : defaultTemplatesPath;
|
|
32
|
-
const customTemplatesPath = templates ? resolve(process.cwd(), templates) : originalTemplatesPath;
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
/** `templates/base` */
|
|
36
|
-
base: baseTemplatesPath,
|
|
37
|
-
/** `templates/default` */
|
|
38
|
-
default: defaultTemplatesPath,
|
|
39
|
-
/** `templates/modular` */
|
|
40
|
-
modular: modularTemplatesPath,
|
|
41
|
-
/** usage path if `--templates` option is not set */
|
|
42
|
-
original: originalTemplatesPath,
|
|
43
|
-
/** custom path to templates (`--templates`) */
|
|
44
|
-
custom: customTemplatesPath,
|
|
45
|
-
};
|
|
46
|
-
};
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
class Templates {
|
|
7
|
+
/**
|
|
8
|
+
* @type {Configuration}
|
|
9
|
+
*/
|
|
10
|
+
config;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @type {Logger}
|
|
14
|
+
*/
|
|
15
|
+
logger;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @type {FileSystem}
|
|
19
|
+
*/
|
|
20
|
+
fileSystem;
|
|
21
|
+
|
|
22
|
+
getRenderTemplateData;
|
|
23
|
+
|
|
24
|
+
constructor(config, logger, fileSystem, getRenderTemplateData) {
|
|
25
|
+
this.config = config;
|
|
26
|
+
this.logger = logger;
|
|
27
|
+
this.fileSystem = fileSystem;
|
|
28
|
+
this.getRenderTemplateData = getRenderTemplateData;
|
|
29
|
+
}
|
|
47
30
|
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
getTemplatePaths = ({ templates, modular }) => {
|
|
32
|
+
const baseTemplatesPath = resolve(__dirname, "../templates/base");
|
|
33
|
+
const defaultTemplatesPath = resolve(__dirname, "../templates/default");
|
|
34
|
+
const modularTemplatesPath = resolve(__dirname, "../templates/modular");
|
|
35
|
+
const originalTemplatesPath = modular ? modularTemplatesPath : defaultTemplatesPath;
|
|
36
|
+
const customTemplatesPath = templates ? resolve(process.cwd(), templates) : originalTemplatesPath;
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
/** `templates/base` */
|
|
40
|
+
base: baseTemplatesPath,
|
|
41
|
+
/** `templates/default` */
|
|
42
|
+
default: defaultTemplatesPath,
|
|
43
|
+
/** `templates/modular` */
|
|
44
|
+
modular: modularTemplatesPath,
|
|
45
|
+
/** usage path if `--templates` option is not set */
|
|
46
|
+
original: originalTemplatesPath,
|
|
47
|
+
/** custom path to templates (`--templates`) */
|
|
48
|
+
custom: customTemplatesPath,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const pathVariants = TEMPLATE_EXTENSIONS.map((extension) => `${raw}${extension}`);
|
|
52
|
+
cropExtension = (path) =>
|
|
53
|
+
this.config.templateExtensions.reduce((path, ext) => (_.endsWith(path, ext) ? path.replace(ext, "") : path), path);
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
getTemplateFullPath = (path, fileName) => {
|
|
56
|
+
const raw = resolve(path, "./", this.cropExtension(fileName));
|
|
57
|
+
const pathVariants = this.config.templateExtensions.map((extension) => `${raw}${extension}`);
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
return pathVariants.find((variant) => !!this.fileSystem.pathIsExist(variant));
|
|
60
|
+
};
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
62
|
+
requireFnFromTemplate = (packageOrPath) => {
|
|
63
|
+
const isPath = _.startsWith(packageOrPath, "./") || _.startsWith(packageOrPath, "../");
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
if (isPath) {
|
|
66
|
+
return require(path.resolve(this.config.templates, packageOrPath));
|
|
67
|
+
}
|
|
66
68
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
return require(packageOrPath);
|
|
70
|
+
};
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
+
getTemplate = ({ fileName, name, path }) => {
|
|
73
|
+
const { templatePaths } = this.config;
|
|
72
74
|
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
} else {
|
|
76
|
-
logger.warn(
|
|
77
|
-
`${_.lowerCase(name)} template not found in ${customFullPath}`,
|
|
78
|
-
`\nCode generator will use the default template`,
|
|
79
|
-
);
|
|
75
|
+
if (path) {
|
|
76
|
+
return this.fileSystem.getFileContent(path);
|
|
80
77
|
}
|
|
81
78
|
|
|
82
|
-
|
|
79
|
+
if (!fileName) return "";
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
}
|
|
81
|
+
const customFullPath = this.getTemplateFullPath(templatePaths.custom, fileName);
|
|
82
|
+
let fileContent = customFullPath && this.fileSystem.getFileContent(customFullPath);
|
|
88
83
|
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
if (!fileContent) {
|
|
85
|
+
const baseFullPath = this.getTemplateFullPath(templatePaths.base, fileName);
|
|
91
86
|
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
if (baseFullPath) {
|
|
88
|
+
fileContent = this.fileSystem.getFileContent(baseFullPath);
|
|
89
|
+
} else {
|
|
90
|
+
this.logger.warn(
|
|
91
|
+
`${_.lowerCase(name)} template not found in ${customFullPath}`,
|
|
92
|
+
`\nCode generator will use the default template`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
94
95
|
|
|
95
|
-
|
|
96
|
-
TEMPLATE_INFOS,
|
|
97
|
-
(acc, { fileName, name }) => ({
|
|
98
|
-
...acc,
|
|
99
|
-
[name]: getTemplate({ fileName, name }),
|
|
100
|
-
}),
|
|
101
|
-
{},
|
|
102
|
-
);
|
|
96
|
+
const originalFullPath = this.getTemplateFullPath(templatePaths.original, fileName);
|
|
103
97
|
|
|
104
|
-
|
|
105
|
-
|
|
98
|
+
if (originalFullPath) {
|
|
99
|
+
fileContent = this.fileSystem.getFileContent(originalFullPath);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
106
102
|
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
return fileContent;
|
|
104
|
+
};
|
|
109
105
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return
|
|
106
|
+
getTemplates = ({ templatePaths }) => {
|
|
107
|
+
this.logger.log(`try to read templates from directory "${templatePaths.custom}"`);
|
|
108
|
+
|
|
109
|
+
return _.reduce(
|
|
110
|
+
this.config.templateInfos,
|
|
111
|
+
(acc, { fileName, name }) => ({
|
|
112
|
+
...acc,
|
|
113
|
+
[name]: this.getTemplate({ fileName, name }),
|
|
114
|
+
}),
|
|
115
|
+
{},
|
|
116
|
+
);
|
|
114
117
|
};
|
|
115
118
|
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
getTemplateContent = (path) => {
|
|
120
|
+
const foundTemplatePathKey = _.keys(this.config.templatePaths).find((key) => _.startsWith(path, `@${key}`));
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
const findPathWithExt = (path) => {
|
|
123
|
+
const raw = this.cropExtension(path);
|
|
124
|
+
const pathVariants = this.config.templateExtensions.map((extension) => `${raw}${extension}`);
|
|
125
|
+
return pathVariants.find((variant) => this.fileSystem.pathIsExist(variant));
|
|
126
|
+
};
|
|
122
127
|
|
|
123
|
-
|
|
128
|
+
const rawPath = resolve(
|
|
129
|
+
_.replace(path, `@${foundTemplatePathKey}`, this.config.templatePaths[foundTemplatePathKey]),
|
|
130
|
+
);
|
|
131
|
+
const fixedPath = findPathWithExt(rawPath);
|
|
124
132
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
if (fixedPath) {
|
|
134
|
+
return this.fileSystem.getFileContent(fixedPath);
|
|
135
|
+
}
|
|
128
136
|
|
|
129
|
-
|
|
137
|
+
const customPath = findPathWithExt(resolve(this.config.templatePaths.custom, path));
|
|
130
138
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
139
|
+
if (customPath) {
|
|
140
|
+
return this.fileSystem.getFileContent(customPath);
|
|
141
|
+
}
|
|
134
142
|
|
|
135
|
-
|
|
136
|
-
};
|
|
143
|
+
const originalPath = findPathWithExt(resolve(this.config.templatePaths.original, path));
|
|
137
144
|
|
|
138
|
-
|
|
139
|
-
|
|
145
|
+
if (originalPath) {
|
|
146
|
+
return this.fileSystem.getFileContent(originalPath);
|
|
147
|
+
}
|
|
140
148
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
return "";
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
renderTemplate = (template, configuration, options) => {
|
|
153
|
+
if (!template) return "";
|
|
154
|
+
|
|
155
|
+
return Eta.render(
|
|
156
|
+
template,
|
|
157
|
+
{
|
|
158
|
+
...this.getRenderTemplateData(),
|
|
159
|
+
...configuration,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
async: false,
|
|
163
|
+
...(options || {}),
|
|
164
|
+
includeFile: (path, payload, options) => {
|
|
165
|
+
return this.renderTemplate(this.getTemplateContent(path), payload, options);
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
);
|
|
169
|
+
};
|
|
170
|
+
}
|
|
149
171
|
|
|
150
172
|
module.exports = {
|
|
151
|
-
|
|
152
|
-
getTemplates,
|
|
153
|
-
getTemplatePaths,
|
|
154
|
-
renderTemplate,
|
|
173
|
+
Templates,
|
|
155
174
|
};
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
const ts = require("typescript");
|
|
2
|
-
|
|
3
|
-
function translate(fileName, content, options) {
|
|
4
|
-
const output = {};
|
|
5
|
-
const host = ts.createCompilerHost(options, true);
|
|
6
|
-
const fileNames = [fileName];
|
|
7
|
-
const originalSourceFileGet = host.getSourceFile.bind(host);
|
|
8
|
-
host.getSourceFile = (sourceFileName, languageVersion, onError, shouldCreateNewSourceFile) => {
|
|
9
|
-
if (sourceFileName !== fileName)
|
|
10
|
-
return originalSourceFileGet(sourceFileName, languageVersion, onError, shouldCreateNewSourceFile);
|
|
11
|
-
|
|
12
|
-
return ts.createSourceFile(sourceFileName, content, languageVersion, true, ts.ScriptKind.External);
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
host.writeFile = (fileName, contents) => {
|
|
16
|
-
output[fileName] = contents;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
ts.createProgram(fileNames, options, host).emit();
|
|
20
|
-
|
|
21
|
-
return output;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
module.exports = {
|
|
25
|
-
translate: (fileName, sourceTypeScript) => {
|
|
26
|
-
const translated = translate(fileName, sourceTypeScript, {
|
|
27
|
-
module: "ESNext",
|
|
28
|
-
noImplicitReturns: true,
|
|
29
|
-
alwaysStrict: true,
|
|
30
|
-
target: ts.ScriptTarget.ESNext,
|
|
31
|
-
declaration: true,
|
|
32
|
-
noImplicitAny: false,
|
|
33
|
-
sourceMap: false,
|
|
34
|
-
removeComments: false,
|
|
35
|
-
disableSizeLimit: true,
|
|
36
|
-
esModuleInterop: true,
|
|
37
|
-
emitDecoratorMetadata: true,
|
|
38
|
-
skipLibCheck: true,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const sourceFileName = fileName.replace(ts.Extension.Ts, ts.Extension.Js);
|
|
42
|
-
const declarationFileName = fileName.replace(ts.Extension.Ts, ts.Extension.Dts);
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
sourceContent: translated[sourceFileName],
|
|
46
|
-
declarationContent: translated[declarationFileName],
|
|
47
|
-
};
|
|
48
|
-
},
|
|
49
|
-
};
|
|
1
|
+
const ts = require("typescript");
|
|
2
|
+
|
|
3
|
+
function translate(fileName, content, options) {
|
|
4
|
+
const output = {};
|
|
5
|
+
const host = ts.createCompilerHost(options, true);
|
|
6
|
+
const fileNames = [fileName];
|
|
7
|
+
const originalSourceFileGet = host.getSourceFile.bind(host);
|
|
8
|
+
host.getSourceFile = (sourceFileName, languageVersion, onError, shouldCreateNewSourceFile) => {
|
|
9
|
+
if (sourceFileName !== fileName)
|
|
10
|
+
return originalSourceFileGet(sourceFileName, languageVersion, onError, shouldCreateNewSourceFile);
|
|
11
|
+
|
|
12
|
+
return ts.createSourceFile(sourceFileName, content, languageVersion, true, ts.ScriptKind.External);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
host.writeFile = (fileName, contents) => {
|
|
16
|
+
output[fileName] = contents;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
ts.createProgram(fileNames, options, host).emit();
|
|
20
|
+
|
|
21
|
+
return output;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
translate: (fileName, sourceTypeScript) => {
|
|
26
|
+
const translated = translate(fileName, sourceTypeScript, {
|
|
27
|
+
module: "ESNext",
|
|
28
|
+
noImplicitReturns: true,
|
|
29
|
+
alwaysStrict: true,
|
|
30
|
+
target: ts.ScriptTarget.ESNext,
|
|
31
|
+
declaration: true,
|
|
32
|
+
noImplicitAny: false,
|
|
33
|
+
sourceMap: false,
|
|
34
|
+
removeComments: false,
|
|
35
|
+
disableSizeLimit: true,
|
|
36
|
+
esModuleInterop: true,
|
|
37
|
+
emitDecoratorMetadata: true,
|
|
38
|
+
skipLibCheck: true,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const sourceFileName = fileName.replace(ts.Extension.Ts, ts.Extension.Js);
|
|
42
|
+
const declarationFileName = fileName.replace(ts.Extension.Ts, ts.Extension.Dts);
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
sourceContent: translated[sourceFileName],
|
|
46
|
+
declarationContent: translated[declarationFileName],
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
};
|
package/src/type-name.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const _ = require("lodash");
|
|
2
|
+
|
|
3
|
+
class TypeName {
|
|
4
|
+
/** @type {Map<string, string>} */
|
|
5
|
+
formattedModelNamesMap = new Map();
|
|
6
|
+
|
|
7
|
+
/** @type {Configuration} */
|
|
8
|
+
config;
|
|
9
|
+
|
|
10
|
+
/** @type {Logger} */
|
|
11
|
+
logger;
|
|
12
|
+
|
|
13
|
+
constructor(config, logger) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param name
|
|
20
|
+
* @param options {{ ignorePrefix?: boolean, ignoreSuffix?: boolean }}
|
|
21
|
+
* @return {string}
|
|
22
|
+
*/
|
|
23
|
+
format = (name, options) => {
|
|
24
|
+
const typePrefix = options && options.ignorePrefix ? "" : this.config.typePrefix;
|
|
25
|
+
const typeSuffix = options && options.ignoreSuffix ? "" : this.config.typeSuffix;
|
|
26
|
+
const hashKey = `${typePrefix}_${name}_${typeSuffix}`;
|
|
27
|
+
|
|
28
|
+
if (typeof name !== "string") {
|
|
29
|
+
this.logger.warn("wrong name of the model name", name);
|
|
30
|
+
return name;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (/^([A-Z_]{1,})$/g.test(name)) {
|
|
34
|
+
return _.compact([typePrefix, name, typeSuffix]).join("_");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (this.formattedModelNamesMap.has(hashKey)) {
|
|
38
|
+
return this.formattedModelNamesMap.get(hashKey);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const fixedModelName = fixModelName(name);
|
|
42
|
+
|
|
43
|
+
const formattedModelName = _.replace(_.startCase(`${typePrefix}_${fixedModelName}_${typeSuffix}`), /\s/g, "");
|
|
44
|
+
const modelName = this.config.hooks.onFormatTypeName(formattedModelName, name) || formattedModelName;
|
|
45
|
+
|
|
46
|
+
this.formattedModelNamesMap.set(hashKey, modelName);
|
|
47
|
+
|
|
48
|
+
return modelName;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
isValidName = isValidName;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const isValidName = (name) => /^([A-Za-z$_]{1,})$/g.test(name);
|
|
55
|
+
|
|
56
|
+
const fixModelName = (name) => {
|
|
57
|
+
if (!isValidName(name)) {
|
|
58
|
+
if (!/^[a-zA-Z_$]/g.test(name)) {
|
|
59
|
+
name = `Type ${name}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// specific replaces for TSOA 3.x
|
|
63
|
+
if (name.includes("."))
|
|
64
|
+
name = name
|
|
65
|
+
.replace(/Exclude_keyof[A-Za-z]{1,}/g, (match) => "ExcludeKeys")
|
|
66
|
+
.replace(/%22\~AND\~%22/g, "And")
|
|
67
|
+
.replace(/%22\~OR\~%22/g, "Or")
|
|
68
|
+
.replace(/(\.?%22)|\./g, "_")
|
|
69
|
+
.replace(/__+$/, "");
|
|
70
|
+
|
|
71
|
+
if (name.includes("-")) name = _.startCase(name).replace(/ /g, "");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return name;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
TypeName,
|
|
79
|
+
};
|