UNPKG

dalao-proxy

Version:

An expandable HTTP proxy based on the plug-in system for frontend developers with request caching request mock and development!

187 lines (158 loc) 6.35 kB
const chalk = require('chalk'); const readline = require('readline'); const fs = require('fs'); const path = require('path'); const _ = require('lodash'); const { program } = require('../../../src'); const { Plugin } = require('../../plugin'); const defaultConfig = require('../../../config'); const custom_assign = require('../../utils').custom_assign; const pwd = process.cwd(); const Generator = module.exports; // questions let questionObjs = [ { label: 'Config file name', value: 'configFileName', text: true, radio: false }, { label: 'Proxy server host', value: 'host', text: true, radio: false }, { label: 'Proxy server port', value: 'port', text: true, radio: false }, { label: 'Proxy target server address', value: 'target', text: true, radio: false }, ]; // default answers let defaultAnswers = [ defaultConfig.configFileName, defaultConfig.host, defaultConfig.port, defaultConfig.target, true, ]; // user answers const answers = []; let index = 0; function createConfigFile(config) { const { force: forceSkip, js: inJsFormat, } = config; let generateConfig = {}; const saveFileExtention = inJsFormat ? '.js' : '.json'; const saveFileWrapper = context => inJsFormat ? `module.exports = ${context};` : context; questionObjs.forEach(function (questionObj, index) { generateConfig[questionObj.value] = answers[index]; }); generateConfig = _.assignWith({}, _.omit(defaultConfig, ['version', 'debug', 'logger', 'configFileName']), generateConfig, custom_assign); // prevent build-in plugins exposing generateConfig.plugins = []; const fullConfigFilePath = path.resolve(pwd, forceSkip ? defaultAnswers[0] : generateConfig.configFileName) + saveFileExtention; const fileContent = saveFileWrapper(JSON.stringify(generateConfig, null, 4)); fs.writeFileSync(fullConfigFilePath, fileContent); console.log(chalk.green(`> 🎉 Congratulations, \`${fullConfigFilePath}\` has generated for you.`)); console.log(chalk.grey(' More details about proxy config or cache config, please see ') + chalk.yellow('https://github.com/CalvinVon/dalao-proxy#docs\n')); } /** * Run question loop * @param {Object} config * @param {Boolean} config.forceSkip if true skip all the questions */ function runQuestionLoop(config, callback) { const { force: forceSkip } = config; const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); if (forceSkip || index === questionObjs.length) { createConfigFile(config); rl.close(); callback(); } const questionObj = questionObjs[index]; const defaultAnswer = defaultAnswers[index]; let question = '> '; const { label, radio, text } = questionObj; if (text) { question += label + ' (' + defaultAnswer + '): '; } else if (radio) { question += label + ' (y/n, default: ' + (defaultAnswer ? 'yes' : 'no') + '): '; } rl.question(question, function (answer) { if (text) { answers.push(answer || defaultAnswer); index++; } else if (radio) { if (!answer) { answers.push(defaultAnswer); index++; } else { const yesMatched = /^(true|y|yes)$/i.test(answer); const noMatched = /^(false|no?)$/i.test(answer); if (yesMatched || noMatched) { answers.push(yesMatched || defaultAnswer); index++; } else { console.log(chalk.red('> dalao says: 👋 enter `y/yes` or `n/no`')); } } } rl.close(); runQuestionLoop(config, callback); }); } function addPluginConfig(config) { const { plugin: pluginName, config: configFilePath, js: inJsFormat, } = config; const fileConfig = require(configFilePath); const plugin = new Plugin(pluginName, program.context); const pluginDefaultConfig = plugin.parser({}); const pluginConfigField = plugin.setting.optionsField; if (Array.isArray(pluginConfigField)) { console.warn(chalk.yellow('Init warning: this plugin(' + pluginName + ') contains multiple options fields(' + pluginConfigField.join(', ') + '), \n' + 'We are trying to generate the corresponding configuration for you as much as possible, but it is not guaranteed to\n' + 'be correct, please find the corresponding plugin configuration document.\n')); for (const field of pluginConfigField) { fileConfig[field] = pluginDefaultConfig[field]; } } else { fileConfig[pluginConfigField] = pluginDefaultConfig; } const saveFileExtention = inJsFormat ? '.js' : '.json'; const saveFileWrapper = context => inJsFormat ? `module.exports = ${context};` : context; const fileContent = saveFileWrapper(JSON.stringify(fileConfig, null, 4)); const filePath = configFilePath.replace(path.extname(configFilePath), '') + saveFileExtention; fs.writeFileSync(filePath, fileContent); console.log(chalk.green(`> Config for plugin \`${pluginName}\` updated in field \`${pluginConfigField}\` of \`${filePath}\`.`)); console.log(chalk.grey(' More config about the plugin, please use the command ') + chalk.yellow(`\`dalao-proxy plugin config ${pluginName}.\`\n`)); } Generator.generateConfigFile = function generateConfigFile(config, callback) { if (!config.force) { const preHint = ` This utility will walk you through creating a config file. It only covers the most common items, and tries to guess sensible defaults. See \`dalao-proxy --help\` for definitive documentation on these fields and exactly what they do. Press ^C at any time to quit. `; console.log(preHint); } return runQuestionLoop(config, callback); }; Generator.generatePluginConfig = function (config, callback) { const { config: configFilePath, } = config; if (!fs.existsSync(configFilePath)) { Generator.generateConfigFile(config, () => { addPluginConfig(config); callback(); }); } else { addPluginConfig(config); callback(); } };