diff --git a/jhipster-uml.js b/jhipster-uml.js index 7e50620..298f114 100755 --- a/jhipster-uml.js +++ b/jhipster-uml.js @@ -1,4 +1,4 @@ -#!/usr/bin/env node +#!/usr/bin/env node --max-old-space-size=2048 /* eslint-disable global-require */ const chalk = require('chalk'); diff --git a/lib/editors/editor_detector.js b/lib/editors/editor_detector.js index 388b988..dc7e0b7 100644 --- a/lib/editors/editor_detector.js +++ b/lib/editors/editor_detector.js @@ -33,7 +33,7 @@ module.exports = { * @param root {Object} the document's root. * @return {string} the editor's name. */ -function detect(root) { +async function detect(root) { if (!root) { throw new BuildException( exceptions.NullPointer, 'The root element can not be null.'); @@ -53,16 +53,16 @@ function detect(root) { 'Your editor has not been detected, and this should not be happening.' + '\nPlease report this issue by mentioning what your editor is.'); } - return askForEditor(); + return await askForEditor(); } -function askForEditor() { +async function askForEditor() { const choices = UndetectedEditors; choices.push({ value: 'ERROR', name: 'I don\'t see my editor.' }); - const choice = selectMultipleChoices({ + const choice = await selectMultipleChoices({ choices, question: 'Please choose between the available editors:' }); diff --git a/lib/editors/parser_factory.js b/lib/editors/parser_factory.js index 425ed7b..f0da9fa 100644 --- a/lib/editors/parser_factory.js +++ b/lib/editors/parser_factory.js @@ -36,7 +36,7 @@ module.exports = { * @param args {Object} the arguments: file, files, databaseType, and the noUserManagement flag. * @return {Parser} the created parser. */ -function createParser(args) { +async function createParser(args) { if (!args || !args.file || !args.databaseType) { throw new BuildException( exceptions.IllegalArgument, @@ -47,16 +47,16 @@ function createParser(args) { const root = getRootElement(readFileContent(args.file)); return getFileParserByEditor(args.editor, root, types, args.noUserManagement); } - return getParserForSingleFile(args.file, types, args.noUserManagement); + return await getParserForSingleFile(args.file, types, args.noUserManagement); } -function getParserForSingleFile(file, types, noUserManagement) { - return getXMIFileParser(file, types, noUserManagement); +async function getParserForSingleFile(file, types, noUserManagement) { + return await getXMIFileParser(file, types, noUserManagement); } -function getXMIFileParser(file, databaseType, noUserManagement) { +async function getXMIFileParser(file, databaseType, noUserManagement) { const root = getRootElement(readFileContent(file)); - const detectedEditor = EditorDetector.detect(root); + const detectedEditor = await EditorDetector.detect(root); return getFileParserByEditor(detectedEditor, root, databaseType, noUserManagement); } diff --git a/lib/helpers/jhipster_option_helper.js b/lib/helpers/jhipster_option_helper.js index ca8bb72..1bd6823 100644 --- a/lib/helpers/jhipster_option_helper.js +++ b/lib/helpers/jhipster_option_helper.js @@ -31,20 +31,20 @@ module.exports = { askForClassesWithJPAMetamodelFiltering }; -function askForClassesToPaginate(classes, value) { - return QuestionAsker.selectMultipleChoices({ +async function askForClassesToPaginate(classes, value) { + return await QuestionAsker.selectMultipleChoices({ classes, question: `Please choose the entities you want to paginate with ${value}:` }); } -function askForPagination(classes, values) { +async function askForPagination(classes, values) { if (!(values instanceof Array)) { values = [values]; } const listPagination = {}; for (let i = 0; i < values.length; i++) { - const classesToPaginate = askForClassesToPaginate(classes, values[i]); + const classesToPaginate = await askForClassesToPaginate(classes, values[i]); for (let j = 0; j < classesToPaginate.length; j++) { listPagination[classesToPaginate[j]] = values[i]; } @@ -52,20 +52,20 @@ function askForPagination(classes, values) { return listPagination; } -function askForClassesToService(classes, value) { - return QuestionAsker.selectMultipleChoices({ +async function askForClassesToService(classes, value) { + return await QuestionAsker.selectMultipleChoices({ classes, question: `Please choose the entities you want to add a service ${value ? `with ${value}` : ''}:` }); } -function askForService(classes, values) { +async function askForService(classes, values) { if (!(values instanceof Array)) { values = [values]; } const listService = {}; for (let i = 0; i < values.length; i++) { - const classesToService = askForClassesToService(classes, values[i]); + const classesToService = await askForClassesToService(classes, values[i]); for (let j = 0; j < classesToService.length; j++) { listService[classesToService[j]] = values[i]; } @@ -73,20 +73,20 @@ function askForService(classes, values) { return listService; } -function askForClassesToDto(classes, value) { - return QuestionAsker.selectMultipleChoices({ +async function askForClassesToDto(classes, value) { + return await QuestionAsker.selectMultipleChoices({ classes, question: `Please choose the entities you want to generate the DTO with ${value}:` }); } -function askForDTO(classes, values) { +async function askForDTO(classes, values) { if (!(values instanceof Array)) { values = [values]; } const listDto = {}; for (let i = 0; i < values.length; i++) { - const classesToDto = askForClassesToDto(classes, values[i]); + const classesToDto = await askForClassesToDto(classes, values[i]); for (let j = 0; j < classesToDto.length; j++) { listDto[classesToDto[j]] = values[i]; } @@ -94,41 +94,41 @@ function askForDTO(classes, values) { return listDto; } -function askForClassesToSkipClientCode(classes) { - return QuestionAsker.selectMultipleChoices({ +async function askForClassesToSkipClientCode(classes) { + return await QuestionAsker.selectMultipleChoices({ classes, question: 'Please choose the entities that won\'t have any client code:' }); } -function askForClassesWithFluentMethods(classes) { - return QuestionAsker.selectMultipleChoices({ +async function askForClassesWithFluentMethods(classes) { + return await QuestionAsker.selectMultipleChoices({ classes, question: 'Please choose the entities that will have fluent methods:' }); } -function askForClassesWithJPAMetamodelFiltering(classes) { - return QuestionAsker.selectMultipleChoices({ +async function askForClassesWithJPAMetamodelFiltering(classes) { + return await QuestionAsker.selectMultipleChoices({ classes, question: 'Please choose the entities that will be filtered (JPA metamodel filtering):' }); } -function askForClassesToSkipServerCode(classes) { - return QuestionAsker.selectMultipleChoices({ +async function askForClassesToSkipServerCode(classes) { + return await QuestionAsker.selectMultipleChoices({ classes, question: 'Please choose the entities that won\'t have any server code:' }); } -function askForAngularSuffixes(classes, values) { +async function askForAngularSuffixes(classes, values) { if (!(values instanceof Array)) { values = [values]; } const angularSuffixes = {}; for (let i = 0; i < values.length; i++) { - const classesToSuffix = askForAngularSuffixesClasses(classes, values[i]); + const classesToSuffix = await askForAngularSuffixesClasses(classes, values[i]); for (let j = 0; j < classesToSuffix.length; j++) { angularSuffixes[classesToSuffix[j]] = values[i]; } @@ -136,20 +136,20 @@ function askForAngularSuffixes(classes, values) { return angularSuffixes; } -function askForAngularSuffixesClasses(classes, value) { - return QuestionAsker.selectMultipleChoices({ +async function askForAngularSuffixesClasses(classes, value) { + return await QuestionAsker.selectMultipleChoices({ classes, question: `Please choose the entities you want to add an angular suffix with ${value}:` }); } -function askForMicroserviceNames(classes, values) { +async function askForMicroserviceNames(classes, values) { if (!(values instanceof Array)) { values = [values]; } const microserviceNames = {}; for (let i = 0; i < values.length; i++) { - const classesToTreat = askForMicroserviceNamesClasses(classes, values[i]); + const classesToTreat = await askForMicroserviceNamesClasses(classes, values[i]); for (let j = 0; j < classesToTreat.length; j++) { microserviceNames[classesToTreat[j]] = values[i]; } @@ -157,27 +157,27 @@ function askForMicroserviceNames(classes, values) { return microserviceNames; } -function askForMicroserviceNamesClasses(classes, value) { - return QuestionAsker.selectMultipleChoices({ +async function askForMicroserviceNamesClasses(classes, value) { + return await QuestionAsker.selectMultipleChoices({ classes, question: `Please choose the entities included in microservice ${value}:` }); } -function askForClassesToBeSearched(classes, value) { - return QuestionAsker.selectMultipleChoices({ +async function askForClassesToBeSearched(classes, value) { + return await QuestionAsker.selectMultipleChoices({ classes, question: `Please choose the entities that can be searched with ${value}:` }); } -function askForSearchEngines(classes, values) { +async function askForSearchEngines(classes, values) { if (!(values instanceof Array)) { values = [values]; } const listSearchEngine = {}; for (let i = 0; i < values.length; i++) { - const classesToSearch = askForClassesToBeSearched(classes, values[i]); + const classesToSearch = await askForClassesToBeSearched(classes, values[i]); for (let j = 0; j < classesToSearch.length; j++) { listSearchEngine[classesToSearch[j]] = values[i]; } diff --git a/lib/helpers/question_asker.js b/lib/helpers/question_asker.js index e50ef29..47af0d4 100644 --- a/lib/helpers/question_asker.js +++ b/lib/helpers/question_asker.js @@ -17,7 +17,6 @@ * limitations under the License. */ const inquirer = require('inquirer'); -const deasync = require('deasync'); const merge = require('jhipster-core').ObjectUtils.merge; module.exports = { @@ -55,22 +54,18 @@ const DEFAULTS = { * @param args {object} keys: question, defaultValue * @return {boolean} the user's answer. */ -function askConfirmation(args) { +async function askConfirmation(args) { let userAnswer = 'no-answer'; const merged = merge(DEFAULTS.CONFIRMATIONS, args); - inquirer.prompt([ + const answers = await inquirer.prompt([ { type: DEFAULTS.QUESTION_TYPES.CONFIRM, name: 'choice', message: merged.question, default: merged.defaultValue } - ]).then((answer) => { - userAnswer = answer.choice; - }); - while (userAnswer === 'no-answer') { - wait(100); - } + ]); + userAnswer = answers.choice; return userAnswer; } @@ -79,11 +74,15 @@ function askConfirmation(args) { * @param args {object} keys: classes, choices, question, filterFunction * @return the choice. */ -function selectMultipleChoices(args) { +async function selectMultipleChoices(args) { + const result = await asyncfuncSelectMultipleChoices(args); + return result; +} + +async function asyncfuncSelectMultipleChoices(args) { args.choices = args.choices || prepareChoices(args.classes); - let result = null; const merged = merge(DEFAULTS.MULTIPLE_CHOICES, args); - inquirer.prompt([ + const answers = await inquirer.prompt([ { type: DEFAULTS.QUESTION_TYPES.CHECKBOX, name: 'answer', @@ -91,23 +90,16 @@ function selectMultipleChoices(args) { choices: merged.choices, filter: merged.filterFunction } - ]).then((answers) => { - if (answers.answer.length === 0) { + ]); + let result; + if (answers.answer.length === 0) { result = DEFAULTS.NOTHING; } else { result = answers.answer; } - }); - while (!result) { - wait(100); - } return result; } function prepareChoices(classes) { return Object.keys(classes).map(classId => classes[classId].name); } - -function wait(time) { - deasync.sleep(time); -} diff --git a/lib/jhipsteruml.js b/lib/jhipsteruml.js index 2ba053d..fceb679 100644 --- a/lib/jhipsteruml.js +++ b/lib/jhipsteruml.js @@ -19,7 +19,6 @@ const fs = require('fs'); const chalk = require('chalk'); -const values = require('jhipster-core').ObjectUtils.values; const logger = require('./utils/logger'); const argv = require('./jhipsteruml/command_line_option_handler').handle().argv; const CommandLineOptionHandler = require('./jhipsteruml/command_line_option_handler'); @@ -66,87 +65,102 @@ if (!argv.db && !JHipsterUtils.isYoRcFilePresent()) { )['generator-jhipster'].databaseType; } -const noUserManagement = !!argv['skip-user-management']; -const parserData = ParserFactory.createParser(initParserFactoryArgs()); -const parser = parserData.parser; -const parsedData = parser.parse(parserData.data); +async function main() { + + const noUserManagement = !!argv['skip-user-management']; + const parserData = await ParserFactory.createParser(initParserFactoryArgs()); + const parser = parserData.parser; + const parsedData = await parser.parse(parserData.data); + + const options = { + force: argv.f, + listDTO: (argv.dto) ? await JHipsterOptionHelper.askForDTO(parsedData.classes, argv.dto) : {}, + listPagination: (argv.paginate) ? await JHipsterOptionHelper.askForPagination(parsedData.classes, argv.paginate) : {}, + listService: (argv.service) ? await JHipsterOptionHelper.askForService(parsedData.classes, argv.service) : {}, + listOfNoClient: (argv['skip-client']) ? await JHipsterOptionHelper.askForClassesToSkipClientCode(parsedData.classes) : [], + listOfNoServer: (argv['skip-server']) ? await JHipsterOptionHelper.askForClassesToSkipServerCode(parsedData.classes) : [], + angularSuffixes: (argv['angular-suffix']) ? await JHipsterOptionHelper.askForAngularSuffixes(parsedData.classes, argv['angular-suffix']) : {}, + microserviceNames: (argv['microservice-name']) ? await JHipsterOptionHelper.askForMicroserviceNames(parsedData.classes, argv['microservice-name']) : {}, + searchEngines: (argv['search-engine']) ? await JHipsterOptionHelper.askForSearchEngines(parsedData.classes, argv['search-engine']) : {}, + fluentMethods: (argv['fluent-methods']) ? await JHipsterOptionHelper.askForClassesWithFluentMethods(parsedData.classes) : [], + jpaMetamodelFiltering: (argv['jpa-metamodel-filtering']) ? await JHipsterOptionHelper.askForClassesWithJPAMetamodelFiltering(parsedData.classes) : [] + }; + + + if (argv['to-jdl']) { + writeJdlFile(argv['to-jdl'], parsedData, options); + process.exit(0); + } + + const entities = EntityCreator.createEntities(parsedData, parserData.data.databaseTypes, options); + + const entityIdsByName = {}; + for (let i = 0, entityIds = Object.keys(parsedData.classes); i < parsedData.classNames.length; i++) { + entityIdsByName[parsedData.getClass(entityIds[i]).name] = entityIds[i]; + } + let entityNamesToGenerate = filterOutUnchangedEntities(entities, parsedData); + + if (JHipsterUMLFileHandler.isJHipsterUMLFilePresent()) { + if (entityNamesToGenerate.length !== 0) { + entityNamesToGenerate = await getEntitiesToGenerate(entityNamesToGenerate); + } + } else { + options.force = true; + writeFile({ + fileName: 'jumlfile', + content: '' + }); + } + + exportToJSON(entities, values(entityIdsByName), parsedData, entityNamesToGenerate); + EntityGenerator.generateEntities(Object.keys(entities), parsedData.classes, entityNamesToGenerate, options); + + function initParserFactoryArgs() { + const parserFactoryArgs = { + databaseType: argv.db, + noUserManagement, + editor: argv.editor + }; + if (argv._.length >= 1) { + parserFactoryArgs.file = argv._[0]; + } else { + logger.error('At least one file to parse must be passed.'); + process.exit(1); + } + return parserFactoryArgs; + } + function filterOutUnchangedEntities(entities, parsedData) { + const onDiskEntities = JHipsterUtils.readJSONFiles(parsedData.classNames); + return parsedData.classNames.filter((name) => { + const currEntity = onDiskEntities[name]; + const newEntity = entities[entityIdsByName[name]]; + if (!newEntity) { + // if the entity is not in entities, we don't want it generated at all + return false; + } + if (!currEntity) { + return true; + } + return !areJHipsterEntitiesEqual(currEntity, newEntity); + }); + } + function writeJdlFile(fileName, parsedData, options) { + writeFile({ + fileName, + content: toJDLString(parsedData, options) + }); + logger.info(`The file '${fileName}' has been written.`); + } -const options = { - force: argv.f, - listDTO: (argv.dto) ? JHipsterOptionHelper.askForDTO(parsedData.classes, argv.dto) : {}, - listPagination: (argv.paginate) ? JHipsterOptionHelper.askForPagination(parsedData.classes, argv.paginate) : {}, - listService: (argv.service) ? JHipsterOptionHelper.askForService(parsedData.classes, argv.service) : {}, - listOfNoClient: (argv['skip-client']) ? JHipsterOptionHelper.askForClassesToSkipClientCode(parsedData.classes) : [], - listOfNoServer: (argv['skip-server']) ? JHipsterOptionHelper.askForClassesToSkipServerCode(parsedData.classes) : [], - angularSuffixes: (argv['angular-suffix']) ? JHipsterOptionHelper.askForAngularSuffixes(parsedData.classes, argv['angular-suffix']) : {}, - microserviceNames: (argv['microservice-name']) ? JHipsterOptionHelper.askForMicroserviceNames(parsedData.classes, argv['microservice-name']) : {}, - searchEngines: (argv['search-engine']) ? JHipsterOptionHelper.askForSearchEngines(parsedData.classes, argv['search-engine']) : {}, - fluentMethods: (argv['fluent-methods']) ? JHipsterOptionHelper.askForClassesWithFluentMethods(parsedData.classes) : [], - jpaMetamodelFiltering: (argv['jpa-metamodel-filtering']) ? JHipsterOptionHelper.askForClassesWithJPAMetamodelFiltering(parsedData.classes) : [] -}; - - -if (argv['to-jdl']) { - writeJdlFile(argv['to-jdl'], parsedData, options); - process.exit(0); -} - -const entities = EntityCreator.createEntities(parsedData, parserData.data.databaseTypes, options); - -const entityIdsByName = {}; -for (let i = 0, entityIds = Object.keys(parsedData.classes); i < parsedData.classNames.length; i++) { - entityIdsByName[parsedData.getClass(entityIds[i]).name] = entityIds[i]; -} -let entityNamesToGenerate = filterOutUnchangedEntities(entities, parsedData); - -if (JHipsterUMLFileHandler.isJHipsterUMLFilePresent()) { - if (entityNamesToGenerate.length !== 0) { - entityNamesToGenerate = getEntitiesToGenerate(entityNamesToGenerate); - } -} else { - options.force = true; - writeFile({ - fileName: 'jumlfile', - content: '' - }); -} - -exportToJSON(entities, values(entityIdsByName), parsedData, entityNamesToGenerate); -EntityGenerator.generateEntities(Object.keys(entities), parsedData.classes, entityNamesToGenerate, options); - -function initParserFactoryArgs() { - const parserFactoryArgs = { - databaseType: argv.db, - noUserManagement, - editor: argv.editor - }; - if (argv._.length >= 1) { - parserFactoryArgs.file = argv._[0]; - } else { - logger.error('At least one file to parse must be passed.'); - process.exit(1); - } - return parserFactoryArgs; -} -function filterOutUnchangedEntities(entities, parsedData) { - const onDiskEntities = JHipsterUtils.readJSONFiles(parsedData.classNames); - return parsedData.classNames.filter((name) => { - const currEntity = onDiskEntities[name]; - const newEntity = entities[entityIdsByName[name]]; - if (!newEntity) { - // if the entity is not in entities, we don't want it generated at all - return false; + function values(object) { + if (object == null) { + throw new Error('The passed object must not be nil.'); } - if (!currEntity) { - return true; + const values = []; + for (let i = 0, keys = Object.keys(object); i < keys.length; i++) { + values.push(object[keys[i]]); } - return !areJHipsterEntitiesEqual(currEntity, newEntity); - }); -} -function writeJdlFile(fileName, parsedData, options) { - writeFile({ - fileName, - content: toJDLString(parsedData, options) - }); - logger.info(`The file '${fileName}' has been written.`); + return values; + } } +main() diff --git a/lib/jhipsteruml/entities_to_generate_handler.js b/lib/jhipsteruml/entities_to_generate_handler.js index ad89698..7e66b77 100644 --- a/lib/jhipsteruml/entities_to_generate_handler.js +++ b/lib/jhipsteruml/entities_to_generate_handler.js @@ -24,17 +24,17 @@ module.exports = { getEntitiesToGenerate }; -function getEntitiesToGenerate(entityNames) { +async function getEntitiesToGenerate(entityNames) { if (!entityNames || entityNames.length === 0) { return []; } logger.info(`The following ${entityNames.length === 1 ? 'class has' : 'classes have'} changed: ${entityNames.join(', ')}.`); if (entityNames.length === 1) { - return QuestionAsker.askConfirmation({ question: `Generate ${entityNames[0]}?`, defaultValue: true }) + return await QuestionAsker.askConfirmation({ question: `Generate ${entityNames[0]}?`, defaultValue: true }) ? entityNames : []; } - return QuestionAsker.selectMultipleChoices({ + return await QuestionAsker.selectMultipleChoices({ choices: entityNames, question: 'Select the entities to override.' }); diff --git a/package-lock.json b/package-lock.json index 7ba907e..7416f89 100644 --- a/package-lock.json +++ b/package-lock.json @@ -253,11 +253,6 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "bindings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", - "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=" - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -511,15 +506,6 @@ "which": "^1.2.9" } }, - "deasync": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.15.tgz", - "integrity": "sha512-pxMaCYu8cQIbGkA4Y1R0PLSooPIpH1WgFBLeJ+zLxQgHfkZG86ViJSmZmONSjZJ/R3NjwkMcIWZAzpLB2G9/CA==", - "requires": { - "bindings": "~1.2.1", - "node-addon-api": "^1.6.0" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -2112,11 +2098,6 @@ } } }, - "node-addon-api": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.6.3.tgz", - "integrity": "sha512-FXWH6mqjWgU8ewuahp4spec8LkroFZK2NicOv6bNwZC3kcwZUI8LeZdG80UzTSLLhK4T7MsgNwlYDVRlDdfTDg==" - }, "node-environment-flags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", diff --git a/package.json b/package.json index 7b0164a..adc06cd 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ }, "dependencies": { "chalk": "2.4.2", - "deasync": "0.1.15", "inquirer": "6.3.1", "jhipster-core": "3.6.14", "lodash": "4.17.13",