diff --git a/bin/cmd.generate.js b/bin/cmd.generate.js index 69fdcfc..f385863 100644 --- a/bin/cmd.generate.js +++ b/bin/cmd.generate.js @@ -1,17 +1,34 @@ const path = require('path'); const fs = require('fs'); const linter = require('./linter'); +const prompt = require('./prompt'); + +function defaultTemplatePath() { + return path.join(__dirname, '..', 'templates', 'default.json'); +} + +function defaultOutputPath(name) { + return path.join(process.cwd(), `${name}.json`) +} function doInteractiveGeneration(args) { + prompt.start([ + { question: 'Service name', name: 'name', validator: linter.regex.NAME_REGEX, error: "Name must only contain lowercase letters, numbers or '-_'!" }, + { question: 'Service description', name: 'description', validator: linter.regex.DESCRIPTION_REGEX, error: "Description must be a descriptive sentence starting with a uppercase letter and ending with a '.'!" }, + { question: 'Template', name: 'template', default: defaultTemplatePath}, + { question: 'Output', name: 'output', default: results => defaultOutputPath(results.name) } + ], results => { + generateTemplate(results); + }); } function doSilentGeneration(args) { let config = {}; - config.template = args.template || path.join(__dirname, '..', 'templates', 'default.json') + config.template = args.template || defaultTemplatePath(); config.name = args.name; config.description = args.description; - config.output = args.output || path.join(process.cwd(), `${args.name}.json`) + config.output = args.output || defaultOutputPath(args.name) generateTemplate(config); } diff --git a/bin/linter.js b/bin/linter.js index c195b6b..4a0053f 100644 --- a/bin/linter.js +++ b/bin/linter.js @@ -1,5 +1,7 @@ const objectPath = require('object-path'); +const NAME_REGEX = /^[a-z0-9_-]+$/; +const DESCRIPTION_REGEX = /^[A-Z]{1}.+\.$/ function required() { return (path, input, msgs) => { @@ -30,8 +32,8 @@ function regex(regex) { const linterMappings = [ - { path: 'name', linters: [ required(), length(4), regex(/^[a-z0-9_-]+$/) ] }, - { path: 'description', linters: [ required(), length(4), regex(/^[A-Z]{1}[a-z0-9_-]+\.$/) ] } + { path: 'name', linters: [ required(), length(4), regex(NAME_REGEX) ] }, + { path: 'description', linters: [ required(), length(4), regex(DESCRIPTION_REGEX) ] } ] @@ -44,4 +46,9 @@ module.exports.lint = function(spec) { }); }); return messages; +} + +module.exports.regex = { + NAME_REGEX, + DESCRIPTION_REGEX } \ No newline at end of file diff --git a/bin/prompt.js b/bin/prompt.js new file mode 100644 index 0000000..48c84de --- /dev/null +++ b/bin/prompt.js @@ -0,0 +1,48 @@ +const readline = require('readline'); + +function createQuestion(item, result) { + let question = item.question || item.name; + if(item.default) { + question += ` (${item.default(result)})` + } + question += ': ' + return question +} + +function promptQuestion(question, results) { + process.stdout.write(createQuestion(question, results)) +} + +module.exports.start = function(schema, cb) { + + let rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + terminal: true + }); + + let results = {}; + let idx = 0; + let currentQuestion = schema[idx]; + + promptQuestion(currentQuestion, results); + + rl.on('line', function(line){ + if(currentQuestion.validator && !line.match(currentQuestion.validator)) { + console.error('Error:', currentQuestion.error || 'Invalid input!') + } else { + if(!line && currentQuestion.default) { + line = currentQuestion.default(results) + } + results[currentQuestion.name] = line; + idx++; + if(idx >= schema.length) { + rl.close(); + cb(results); + return; + } + currentQuestion = schema[idx]; + } + promptQuestion(currentQuestion, results); + }) +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7003665..437a87c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,11 @@ "version": "0.11.5", "resolved": "https://nexus.nclazz.de/repository/npm_public/object-path/-/object-path-0.11.5.tgz", "integrity": "sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg==" + }, + "readline": { + "version": "1.3.0", + "resolved": "https://nexus.nclazz.de/repository/npm_public/readline/-/readline-1.3.0.tgz", + "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw=" } } } diff --git a/package.json b/package.json index f7b3aac..4543f2a 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "license": "MIT", "dependencies": { "args-parser": "^1.2.0", - "object-path": "^0.11.5" + "object-path": "^0.11.5", + "readline": "^1.3.0" } }