swagger-typescript-api 10.0.1 → 10.0.2

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 (56) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +284 -262
  3. package/index.d.ts +7 -1
  4. package/index.js +115 -113
  5. package/package.json +116 -114
  6. package/src/apiConfig.js +30 -30
  7. package/src/common.js +28 -28
  8. package/src/components.js +3 -5
  9. package/src/config.js +4 -0
  10. package/src/constants.js +7 -0
  11. package/src/filePrefix.js +14 -14
  12. package/src/files.js +6 -6
  13. package/src/formatFileContent.js +13 -6
  14. package/src/index.js +271 -270
  15. package/src/logger.js +59 -59
  16. package/src/modelNames.js +78 -78
  17. package/src/modelTypes.js +31 -30
  18. package/src/output.js +165 -166
  19. package/src/prettierOptions.js +23 -23
  20. package/src/render/utils/fmtToJSDocLine.js +10 -10
  21. package/src/render/utils/index.js +31 -23
  22. package/src/render/utils/templateRequire.js +17 -17
  23. package/src/routeNames.js +46 -46
  24. package/src/routes.js +4 -1
  25. package/src/schema.js +87 -64
  26. package/src/swagger.js +4 -1
  27. package/src/templates.js +155 -132
  28. package/src/translators/JavaScript.js +60 -60
  29. package/src/typeFormatters.js +121 -75
  30. package/src/utils/id.js +9 -9
  31. package/src/utils/random.js +14 -14
  32. package/src/utils/resolveName.js +97 -97
  33. package/templates/README.md +17 -13
  34. package/templates/base/README.md +7 -7
  35. package/templates/base/data-contract-jsdoc.ejs +32 -0
  36. package/templates/base/data-contracts.ejs +28 -0
  37. package/templates/base/enum-data-contract.ejs +15 -0
  38. package/templates/base/{http-client.eta → http-client.ejs} +2 -2
  39. package/templates/base/http-clients/{axios-http-client.eta → axios-http-client.ejs} +133 -145
  40. package/templates/base/http-clients/{fetch-http-client.eta → fetch-http-client.ejs} +222 -222
  41. package/templates/base/interface-data-contract.ejs +10 -0
  42. package/templates/base/object-field-jsdoc.ejs +28 -0
  43. package/templates/base/{route-docs.eta → route-docs.ejs} +31 -31
  44. package/templates/base/{route-name.eta → route-name.ejs} +42 -42
  45. package/templates/base/{route-type.eta → route-type.ejs} +21 -21
  46. package/templates/base/type-data-contract.ejs +15 -0
  47. package/templates/default/README.md +6 -6
  48. package/templates/default/{api.eta → api.ejs} +65 -65
  49. package/templates/default/{procedure-call.eta → procedure-call.ejs} +98 -98
  50. package/templates/default/{route-types.eta → route-types.ejs} +28 -28
  51. package/templates/modular/README.md +6 -6
  52. package/templates/modular/{api.eta → api.ejs} +28 -28
  53. package/templates/modular/{procedure-call.eta → procedure-call.ejs} +98 -98
  54. package/templates/modular/{route-types.eta → route-types.ejs} +18 -18
  55. package/CHANGELOG.md +0 -872
  56. package/templates/base/data-contracts.eta +0 -45
@@ -1,23 +1,31 @@
1
- const { classNameCase, formatDescription, internalCase } = require("../../common");
2
- const { getComponentByRef } = require("../../components");
3
- const { formatModelName } = require("../../modelNames");
4
- const { getInlineParseContent, getParseContent, parseSchema } = require("../../schema");
5
- const { formatters, inlineExtraFormatters } = require("../../typeFormatters");
6
- const { NameResolver } = require("../../utils/resolveName");
7
-
8
- module.exports = {
9
- formatDescription,
10
- internalCase,
11
- classNameCase,
12
- getInlineParseContent,
13
- getParseContent,
14
- getComponentByRef,
15
- parseSchema,
16
- formatters,
17
- inlineExtraFormatters,
18
- formatModelName,
19
- fmtToJSDocLine: require("./fmtToJSDocLine"),
20
- NameResolver: NameResolver,
21
- _: require("lodash"),
22
- require: require("./templateRequire").templateRequire,
23
- };
1
+ const { classNameCase, formatDescription, internalCase } = require("../../common");
2
+ const { getComponentByRef } = require("../../components");
3
+ const { formatModelName } = require("../../modelNames");
4
+ const {
5
+ getInlineParseContent,
6
+ getParseContent,
7
+ parseSchema,
8
+ checkAndAddNull,
9
+ isNeedToAddNull,
10
+ } = require("../../schema");
11
+ const { formatters, inlineExtraFormatters } = require("../../typeFormatters");
12
+ const { NameResolver } = require("../../utils/resolveName");
13
+
14
+ module.exports = {
15
+ formatDescription,
16
+ internalCase,
17
+ classNameCase,
18
+ getInlineParseContent,
19
+ getParseContent,
20
+ getComponentByRef,
21
+ parseSchema,
22
+ formatters,
23
+ checkAndAddNull,
24
+ isNeedToAddNull,
25
+ inlineExtraFormatters,
26
+ formatModelName,
27
+ fmtToJSDocLine: require("./fmtToJSDocLine"),
28
+ NameResolver: NameResolver,
29
+ _: require("lodash"),
30
+ require: require("./templateRequire").templateRequire,
31
+ };
@@ -1,17 +1,17 @@
1
- const _ = require("lodash");
2
- const path = require("path");
3
- const { config } = require("../../config");
4
-
5
- const templateRequire = (packageOrPath) => {
6
- const isPath = _.startsWith(packageOrPath, "./") || _.startsWith(packageOrPath, "../");
7
-
8
- if (isPath) {
9
- return require(path.resolve(config.templates, packageOrPath));
10
- }
11
-
12
- return require(packageOrPath);
13
- };
14
-
15
- module.exports = {
16
- templateRequire,
17
- };
1
+ const _ = require("lodash");
2
+ const path = require("path");
3
+ const { config } = require("../../config");
4
+
5
+ const templateRequire = (packageOrPath) => {
6
+ const isPath = _.startsWith(packageOrPath, "./") || _.startsWith(packageOrPath, "../");
7
+
8
+ if (isPath) {
9
+ return require(path.resolve(config.templates, packageOrPath));
10
+ }
11
+
12
+ return require(packageOrPath);
13
+ };
14
+
15
+ module.exports = {
16
+ templateRequire,
17
+ };
package/src/routeNames.js CHANGED
@@ -1,46 +1,46 @@
1
- const { config } = require("./config");
2
- const { logger } = require("./logger");
3
- const { renderTemplate } = require("./templates");
4
-
5
- const getRouteName = (routeInfo) => {
6
- const { moduleName } = routeInfo;
7
- const { routeNameDuplicatesMap, templatesToRender } = config;
8
- const routeNameTemplate = templatesToRender.routeName;
9
-
10
- const routeNameFromTemplate = renderTemplate(routeNameTemplate, {
11
- routeInfo: routeInfo,
12
- utils: require("./render/utils"),
13
- config,
14
- });
15
-
16
- const routeName = config.hooks.onFormatRouteName(routeInfo, routeNameFromTemplate) || routeNameFromTemplate;
17
-
18
- const duplicateIdentifier = `${moduleName}|${routeName}`;
19
-
20
- if (routeNameDuplicatesMap.has(duplicateIdentifier)) {
21
- routeNameDuplicatesMap.set(duplicateIdentifier, routeNameDuplicatesMap.get(duplicateIdentifier) + 1);
22
-
23
- logger.warn(
24
- `Module "${moduleName}" already has method "${routeName}()"`,
25
- `\nThis method has been renamed to "${
26
- routeName + routeNameDuplicatesMap.get(duplicateIdentifier)
27
- }()" to solve conflict names.`,
28
- );
29
- } else {
30
- routeNameDuplicatesMap.set(duplicateIdentifier, 1);
31
- }
32
-
33
- const duplicates = routeNameDuplicatesMap.get(duplicateIdentifier);
34
-
35
- const routeNameInfo = {
36
- usage: routeName + (duplicates > 1 ? duplicates : ""),
37
- original: routeName,
38
- duplicate: duplicates > 1,
39
- };
40
-
41
- return config.hooks.onCreateRouteName(routeNameInfo, routeInfo) || routeNameInfo;
42
- };
43
-
44
- module.exports = {
45
- getRouteName,
46
- };
1
+ const { config } = require("./config");
2
+ const { logger } = require("./logger");
3
+ const { renderTemplate } = require("./templates");
4
+
5
+ const getRouteName = (routeInfo) => {
6
+ const { moduleName } = routeInfo;
7
+ const { routeNameDuplicatesMap, templatesToRender } = config;
8
+ const routeNameTemplate = templatesToRender.routeName;
9
+
10
+ const routeNameFromTemplate = renderTemplate(routeNameTemplate, {
11
+ routeInfo: routeInfo,
12
+ utils: require("./render/utils"),
13
+ config,
14
+ });
15
+
16
+ const routeName = config.hooks.onFormatRouteName(routeInfo, routeNameFromTemplate) || routeNameFromTemplate;
17
+
18
+ const duplicateIdentifier = `${moduleName}|${routeName}`;
19
+
20
+ if (routeNameDuplicatesMap.has(duplicateIdentifier)) {
21
+ routeNameDuplicatesMap.set(duplicateIdentifier, routeNameDuplicatesMap.get(duplicateIdentifier) + 1);
22
+
23
+ logger.warn(
24
+ `Module "${moduleName}" already has method "${routeName}()"`,
25
+ `\nThis method has been renamed to "${
26
+ routeName + routeNameDuplicatesMap.get(duplicateIdentifier)
27
+ }()" to solve conflict names.`,
28
+ );
29
+ } else {
30
+ routeNameDuplicatesMap.set(duplicateIdentifier, 1);
31
+ }
32
+
33
+ const duplicates = routeNameDuplicatesMap.get(duplicateIdentifier);
34
+
35
+ const routeNameInfo = {
36
+ usage: routeName + (duplicates > 1 ? duplicates : ""),
37
+ original: routeName,
38
+ duplicate: duplicates > 1,
39
+ };
40
+
41
+ return config.hooks.onCreateRouteName(routeNameInfo, routeInfo) || routeNameInfo;
42
+ };
43
+
44
+ module.exports = {
45
+ getRouteName,
46
+ };
package/src/routes.js CHANGED
@@ -520,7 +520,10 @@ const parseRoutes = ({ usageSchema, parsedSchemas, moduleNameIndex, moduleNameFi
520
520
  moduleNameFirstTag && firstTag
521
521
  ? _.camelCase(firstTag)
522
522
  : _.camelCase(_.compact(_.split(route, "/"))[moduleNameIndex]);
523
- const hasSecurity = !!((globalSecurity && globalSecurity.length) || (security && security.length));
523
+ let hasSecurity = !!(globalSecurity && globalSecurity.length);
524
+ if (security) {
525
+ hasSecurity = security.length > 0;
526
+ }
524
527
 
525
528
  const routeParams = getRouteParams(routeInfo, pathParams);
526
529
 
package/src/schema.js CHANGED
@@ -74,6 +74,23 @@ const getInternalSchemaType = (schema) => {
74
74
  return SCHEMA_TYPES.PRIMITIVE;
75
75
  };
76
76
 
77
+ const isNeedToAddNull = (contract, value) => {
78
+ const { nullable, type } = contract || {};
79
+ return (
80
+ (nullable || !!_.get(contract, "x-nullable") || type === TS_KEYWORDS.NULL) &&
81
+ (!_.isString(value) || (!value.includes(` ${TS_KEYWORDS.NULL}`) && !value.includes(`${TS_KEYWORDS.NULL} `)))
82
+ );
83
+ };
84
+
85
+ const checkAndAddRequiredKeys = (schema, resultType) => {
86
+ if ("$$requiredKeys" in schema && schema.$$requiredKeys.length) {
87
+ config.internalTemplateOptions.addUtilRequiredKeysType = true;
88
+ return `UtilRequiredKeys<${resultType}, ${schema.$$requiredKeys.map((k) => `"${k}"`).join(" | ")}>`;
89
+ }
90
+
91
+ return resultType;
92
+ };
93
+
77
94
  const checkAndAddNull = (schema, value) => {
78
95
  const { nullable, type } = schema || {};
79
96
  return (nullable || !!_.get(schema, "x-nullable") || type === TS_KEYWORDS.NULL) &&
@@ -88,9 +105,9 @@ const isRef = (property) => {
88
105
  return !!(property && property["$ref"]);
89
106
  };
90
107
 
91
- const getRefType = (property) => {
92
- const ref = property && property["$ref"];
93
- return (ref && config.componentsMap[ref]) || null;
108
+ const getRefType = (schema) => {
109
+ const ref = schema && schema["$ref"];
110
+ return config.componentsMap[ref] || null;
94
111
  };
95
112
 
96
113
  const getType = (schema) => {
@@ -99,11 +116,11 @@ const getType = (schema) => {
99
116
  const refTypeInfo = getRefType(schema);
100
117
 
101
118
  if (refTypeInfo) {
102
- return checkAndAddNull(schema, formatModelName(refTypeInfo.typeName));
119
+ return checkAndAddRequiredKeys(schema, checkAndAddNull(schema, formatModelName(refTypeInfo.typeName)));
103
120
  }
104
121
 
105
122
  const primitiveType = getTypeAlias(schema);
106
- return primitiveType ? checkAndAddNull(schema, primitiveType) : TS_KEYWORDS.ANY;
123
+ return primitiveType ? checkAndAddRequiredKeys(schema, checkAndAddNull(schema, primitiveType)) : TS_KEYWORDS.ANY;
107
124
  };
108
125
 
109
126
  const isRequired = (property, name, requiredProperties) => {
@@ -177,73 +194,76 @@ const getObjectTypeContent = (schema) => {
177
194
  return propertiesContent;
178
195
  };
179
196
 
180
- const complexTypeGetter = (schema) => getInlineParseContent(schema);
181
- const filterContents = (contents, types) => _.filter(contents, (type) => !_.includes(types, type));
182
-
183
- const makeAddRequiredToChildSchema = (parentSchema) => (childSchema) => {
184
- let required = childSchema.required || [];
185
- let properties = childSchema.properties || {};
186
-
187
- // Inherit all the required fields from the parent schema that are defined
188
- // either on the parent schema or on the child schema
189
- // TODO: any that are defined at grandparents or higher are ignored
190
- required = required.concat(
191
- (parentSchema.required || []).filter(
192
- (key) =>
193
- !required.includes(key) && (_.keys(properties).includes(key) || _.keys(parentSchema.properties).includes(key)),
194
- ),
195
- );
197
+ const filterContents = (contents, types) => _.uniq(_.filter(contents, (type) => !_.includes(types, type)));
196
198
 
197
- // Identify properties that are required in the child schema, but
198
- // defined only in the parent schema (TODO: this only works one level deep)
199
- const parentPropertiesRequiredByChild = required.filter(
200
- (key) => !_.keys(childSchema.properties).includes(key) && _.keys(parentSchema.properties).includes(key),
201
- );
199
+ const makeAddRequiredToChildSchema = (parentSchema, childSchema) => {
200
+ if (!childSchema) return childSchema;
202
201
 
203
- // Add such properties to the child so that they can be overriden and made required
204
- properties = {
205
- ...properties,
206
- ...parentPropertiesRequiredByChild.reduce(
207
- (additionalProperties, key) => ({
208
- ...additionalProperties,
209
- [key]: (parentSchema.properties || {})[key],
210
- }),
211
- {},
212
- ),
213
- };
214
-
215
- return _.merge(
216
- {
217
- required: required,
218
- properties: properties,
219
- },
220
- childSchema,
221
- );
202
+ const required = _.uniq([...(parentSchema.required || []), ...(childSchema.required || [])]);
203
+
204
+ const refData = getRefType(childSchema);
205
+
206
+ if (refData) {
207
+ const refObjectProperties = _.keys((refData.rawTypeData && refData.rawTypeData.properties) || {});
208
+ const existedRequiredKeys = refObjectProperties.filter((key) => required.includes(key));
209
+
210
+ if (!existedRequiredKeys.length) return childSchema;
211
+
212
+ return {
213
+ ...childSchema,
214
+ $$requiredKeys: existedRequiredKeys,
215
+ };
216
+ } else if (childSchema.properties) {
217
+ const childSchemaProperties = _.keys(childSchema.properties);
218
+ const existedRequiredKeys = childSchemaProperties.filter((key) => required.includes(key));
219
+
220
+ if (!existedRequiredKeys.length) return childSchema;
221
+
222
+ return {
223
+ required: _.uniq([...(childSchema.required || []), ...existedRequiredKeys]),
224
+ ...childSchema,
225
+ };
226
+ }
227
+
228
+ return childSchema;
222
229
  };
223
230
 
224
231
  const complexSchemaParsers = {
232
+ // T1 | T2
225
233
  [SCHEMA_TYPES.COMPLEX_ONE_OF]: (schema) => {
226
- // T1 | T2
227
- const combined = _.map(_.map(schema.oneOf, makeAddRequiredToChildSchema(schema)), complexTypeGetter);
234
+ const combined = _.map(schema.oneOf, (childSchema) =>
235
+ getInlineParseContent(makeAddRequiredToChildSchema(schema, childSchema)),
236
+ );
237
+ const filtered = filterContents(combined, [TS_KEYWORDS.ANY]);
228
238
 
229
- return checkAndAddNull(schema, filterContents(combined, [TS_KEYWORDS.ANY]).join(" | "));
239
+ const type = filtered.join(" | ");
240
+
241
+ return checkAndAddNull(schema, type);
230
242
  },
243
+ // T1 & T2
231
244
  [SCHEMA_TYPES.COMPLEX_ALL_OF]: (schema) => {
232
- // T1 & T2
233
- const combined = _.map(_.map(schema.allOf, makeAddRequiredToChildSchema(schema)), complexTypeGetter);
234
- return checkAndAddNull(
235
- schema,
236
- filterContents(combined, [...JS_EMPTY_TYPES, ...JS_PRIMITIVE_TYPES, TS_KEYWORDS.ANY]).join(" & "),
245
+ const combined = _.map(schema.allOf, (childSchema) =>
246
+ getInlineParseContent(makeAddRequiredToChildSchema(schema, childSchema)),
237
247
  );
248
+ const filtered = filterContents(combined, [...JS_PRIMITIVE_TYPES, TS_KEYWORDS.ANY]);
249
+
250
+ const type = filtered.join(TS_KEYWORDS.TYPE_AND_OPERATOR);
251
+
252
+ return checkAndAddNull(schema, type);
238
253
  },
254
+ // T1 | T2 | (T1 & T2)
239
255
  [SCHEMA_TYPES.COMPLEX_ANY_OF]: (schema) => {
240
- // T1 | T2 | (T1 & T2)
241
- const combined = _.map(_.map(schema.anyOf, makeAddRequiredToChildSchema(schema)), complexTypeGetter);
242
- const nonEmptyTypesCombined = filterContents(combined, [...JS_EMPTY_TYPES, ...JS_PRIMITIVE_TYPES, TS_KEYWORDS.ANY]);
243
- return checkAndAddNull(
244
- schema,
245
- `${combined.join(" | ")}` + (nonEmptyTypesCombined.length > 1 ? ` | (${nonEmptyTypesCombined.join(" & ")})` : ""),
256
+ const combined = _.map(schema.anyOf, (childSchema) =>
257
+ getInlineParseContent(makeAddRequiredToChildSchema(schema, childSchema)),
246
258
  );
259
+ const filtered = filterContents(combined, [...JS_PRIMITIVE_TYPES, TS_KEYWORDS.ANY]);
260
+
261
+ const type = _.compact([
262
+ ...filtered,
263
+ filtered.length > 1 && `(${filtered.join(TS_KEYWORDS.TYPE_AND_OPERATOR)})`,
264
+ ]).join(TS_KEYWORDS.TYPE_OR_OPERATOR);
265
+
266
+ return checkAndAddNull(schema, type);
247
267
  },
248
268
  // TODO
249
269
  [SCHEMA_TYPES.COMPLEX_NOT]: (schema) => {
@@ -357,15 +377,17 @@ const schemaParsers = {
357
377
  schema.description || _.compact(_.map(schema[complexType], "description"))[0] || "",
358
378
  ),
359
379
  content:
360
- _.compact([
361
- complexSchemaContent && `(${complexSchemaContent})`,
362
- getInternalSchemaType(simpleSchema) === TS_KEYWORDS.OBJECT && getInlineParseContent(simpleSchema),
363
- ]).join(" & ") || TS_KEYWORDS.ANY,
380
+ _.uniq(
381
+ _.compact([
382
+ complexSchemaContent && `(${complexSchemaContent})`,
383
+ getInternalSchemaType(simpleSchema) === SCHEMA_TYPES.OBJECT && `(${getInlineParseContent(simpleSchema)})`,
384
+ ]),
385
+ ).join(" & ") || TS_KEYWORDS.ANY,
364
386
  });
365
387
  },
366
388
  [SCHEMA_TYPES.PRIMITIVE]: (schema, typeName) => {
367
389
  let contentType = null;
368
- const { additionalProperties, type, description } = schema || {};
390
+ const { additionalProperties, type, description, $$requiredKeys } = schema || {};
369
391
 
370
392
  if (type === TS_KEYWORDS.OBJECT && additionalProperties) {
371
393
  const fieldType = _.isObject(additionalProperties)
@@ -444,6 +466,7 @@ module.exports = {
444
466
  parseSchemas,
445
467
  getInlineParseContent,
446
468
  getParseContent,
469
+ isNeedToAddNull,
447
470
  getType,
448
471
  getRefType,
449
472
  SCHEMA_TYPES,
package/src/swagger.js CHANGED
@@ -25,7 +25,10 @@ const getSwaggerFile = (pathToSwagger, urlToSwagger, disableStrictSSL, disablePr
25
25
  } else {
26
26
  logger.log(`try to get swagger by URL "${urlToSwagger}"`);
27
27
  // setup options for Axios
28
- const axiosOptions = {};
28
+ const axiosOptions = {
29
+ maxContentLength: Infinity,
30
+ maxBodyLength: Infinity,
31
+ };
29
32
  //
30
33
  if (disableStrictSSL) {
31
34
  axiosOptions.httpsAgent = new https.Agent({