UNPKG

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
"use strict"; 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; }