swagger-ts-generator
Version:
Given a swagger.json file, generates a number of TypeScript files which can be used as models and model-driven forms in Angular 2 (and above)
182 lines (181 loc) • 9 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateEnumLanguageFiles = exports.generateEnumI18NHtmlFile = exports.generateEnumTSFile = void 0;
const fs_1 = require("fs");
const path_1 = require("path");
const lodash_1 = require("lodash");
const utils_1 = require("./utils");
function generateEnumTSFile(swagger, options) {
utils_1.log('generating enums...');
let outputFileName = path_1.normalize(options.enumTSFile);
// get enum definitions from swagger
let enumTypeCollection = getEnumDefinitions(swagger, options);
generateTSEnums(enumTypeCollection, outputFileName, options);
function generateTSEnums(enumTypeCollection, outputFileName, options) {
let data = {
moduleName: options.enumModuleName,
generateClasses: options.generateClasses,
enumTypeCollection: enumTypeCollection
};
let template = utils_1.readAndCompileTemplateFile(options.templates.enum);
let result = template(data);
let isChanged = utils_1.writeFileIfContentsIsChanged(outputFileName, result);
if (isChanged) {
utils_1.log(`generated ${enumTypeCollection.length} enums in ${outputFileName}`);
}
}
}
exports.generateEnumTSFile = generateEnumTSFile;
function generateEnumI18NHtmlFile(swagger, options) {
let outputFileName = path_1.normalize(options.enumI18NHtmlFile);
// get enum definitions from swagger
let enumTypeCollection = getEnumDefinitions(swagger, options);
generateI18NEnumsHtml(enumTypeCollection, outputFileName, options);
function generateI18NEnumsHtml(enumTypeCollection, outputFileName, options) {
let data = {
enumTypeCollection
};
let template = utils_1.readAndCompileTemplateFile(options.templates.enumLanguage);
let result = template(data);
let isChanged = utils_1.writeFileIfContentsIsChanged(outputFileName, result);
if (isChanged) {
utils_1.log(`generated ${enumTypeCollection.length} enums in ${outputFileName}`);
}
}
}
exports.generateEnumI18NHtmlFile = generateEnumI18NHtmlFile;
function generateEnumLanguageFiles(swagger, options) {
lodash_1.each(options.enumLanguageFiles, outputFileName => {
outputFileName = path_1.normalize(outputFileName);
// read contents of the current language file
utils_1.ensureFile(outputFileName, '{}');
let enumLanguage = JSON.parse(fs_1.readFileSync(outputFileName, utils_1.ENCODING));
// get enum definitions from swagger
let enumTypeCollection = getEnumDefinitions(swagger, options);
// add new enum types/values to the enumLanguage (leave existing ones intact)
let newValuesAdded = buildNewEnumLanguage(enumTypeCollection, enumLanguage);
// generateEnumLanguageFile
generateEnumLanguageFile(enumLanguage, outputFileName, newValuesAdded);
});
function buildNewEnumLanguage(enumTypeCollection, enumLanguage) {
let result = false;
let currentEnumLanguage = lodash_1.clone(enumLanguage);
let properties = lodash_1.keys(enumLanguage);
lodash_1.map(properties, property => {
lodash_1.unset(enumLanguage, property);
});
lodash_1.forEach(enumTypeCollection, function (enumType) {
enumLanguage[enumType.type] = '-------ENUM-TYPE-------';
lodash_1.forEach(enumType.valuesAndLabels, function (valueAndLabel, key) {
if (!lodash_1.has(enumLanguage, valueAndLabel.value)) {
if (lodash_1.has(currentEnumLanguage, valueAndLabel.value)) {
enumLanguage[valueAndLabel.value] = currentEnumLanguage[valueAndLabel.value];
}
else {
enumLanguage[valueAndLabel.value] = valueAndLabel.label;
result = true;
}
}
});
});
return result;
}
function generateEnumLanguageFile(enumLanguage, outputFileName, newValuesAdded) {
let message = newValuesAdded ? 'generated new enum values in' : 'nothing new';
utils_1.log(`${message} in ${outputFileName}`);
let isChanged = utils_1.writeFileIfContentsIsChanged(outputFileName, JSON.stringify(enumLanguage, null, 2));
//fs.writeFileSync(outputFileName, JSON.stringify(enumLanguage, null, 2), utils.ENCODING);
}
}
exports.generateEnumLanguageFiles = generateEnumLanguageFiles;
function getEnumDefinitions(swagger, options) {
let enumTypeCollection = new Array();
filterEnumDefinitions(enumTypeCollection, swagger.components.schemas, options);
// filter on unique types
enumTypeCollection = lodash_1.uniqBy(enumTypeCollection, 'type');
// patch enumTypes which have the same values (to prevent non-unique consts in Go)
enumTypeCollection = removeEnumTypesWithSameValues(enumTypeCollection);
// sort on type
if (options.sortEnumTypes) {
enumTypeCollection = lodash_1.sortBy(enumTypeCollection, 'type');
}
// console.log('enumTypeCollection', enumTypeCollection);
return enumTypeCollection;
}
function filterEnumDefinitions(enumTypeCollection, node, options, enumArrayType) {
lodash_1.forEach(node, (item, key) => {
const itemDef = item;
if (lodash_1.isObject(itemDef) && !utils_1.isInTypesToFilter(itemDef, key, options)) {
if (itemDef.enum) {
let type = enumArrayType ? enumArrayType : key;
let values = itemDef.enum;
let enumType = {
type,
valuesAndLabels: getEnumValuesAndLabels(values, options),
joinedValues: undefined
};
// // description may contain an overrule type, eg /** type coverType */
// if (hasTypeFromDescription(itemDef.description)) {
// enumType.type = lowerFirst(
// getTypeFromDescription(itemDef.description)
// );
// }
// add string with joined values so enums with the same values can be detected
enumType.joinedValues = values.join(';');
// console.log(enumType);
// console.log('----------------------');
enumTypeCollection.push(enumType);
}
else {
// enum array's has enum definition one level below (under "items")
let enumArrayType = undefined;
if (itemDef.type === 'array') {
enumArrayType = key;
// if (hasTypeFromDescription(itemDef.description)) {
// enumArrayType = lowerFirst(
// getTypeFromDescription(itemDef.description)
// );
// }
}
filterEnumDefinitions(enumTypeCollection, itemDef, options, enumArrayType);
}
}
});
}
function removeEnumTypesWithSameValues(enumTypeCollection) {
const result = lodash_1.uniqBy(enumTypeCollection, element => {
return element.type + element.joinedValues;
});
// console.log('#enumTypes with and without duplicates', enumTypeCollection.length, result.length);
// console.log('======================> original <======================', enumTypeCollection);
// console.log('======================> result <======================', result);
return result;
// // get enumTypes with duplicate enumValues
// let groupped = _.groupBy(enumTypeCollection, (e) => { return e.joinedValues });
// var duplicates = _.uniqBy(_.flatten(_.filter(groupped, (g) => { return g.length > 1 })), element => { return element.type; });
// console.log('duplicates', JSON.stringify(duplicates));
// // prefix enumValue.pascalCaseValue with typeName to make sure the genertaed Go consts are unique
// _.forEach(duplicates, (item, key) => {
// // _.forEach(item.values, (value) => {
// // value.pascalCaseValue = `${item.typeName}${value.pascalCaseValue}`;
// // });
// })
// // console.log('enumTypeCollection', JSON.stringify(enumTypeCollection));
// return enumTypeCollection;
}
function getEnumValuesAndLabels(enumValues, options) {
let result = new Array();
lodash_1.forEach(enumValues, value => {
const valueAndLabel = {
value,
// only convert label when the value contains not only uppercase chars and length > 3
// (only uppercase with short length are considered codes like Country or Currency)
label: lodash_1.upperCase(value) === value && value.length <= 3 ? value : lodash_1.startCase(value.toLowerCase())
};
result.push(valueAndLabel);
});
if (options.sortEnumTypes) {
result = lodash_1.sortBy(result, 'value');
}
return result;
}
;