dmp-cli
Version:
Dmp component's cli
229 lines (211 loc) • 8.25 kB
JavaScript
/* eslint-disable */
const inquirer = require('inquirer')
const fs = require('fs')
// const shelljs = require('shelljs')
const Path = require('path')
const urllib = require('urllib')
const log = require('./utils/log')
const unzip = require('unzipper')
const stream = require('stream')
const getTemplate = ({ comJsFramework, comChartType }) => {
const chartType = comChartType && comChartType.substring(0, comChartType.indexOf('('))
switch (true) {
case comJsFramework === 'vue' && (chartType === 'chart' || chartType === 'chart-map'):
return 'vue_chart_template.zip'
case comJsFramework === 'vue':
return 'vue_base_template.zip'
case chartType === 'chart' || chartType === 'chart-map':
return 'react_chart_template.zip'
default:
return 'react_base_template.zip'
}
}
module.exports = function (config) {
// shelljs.config.verbose = true
// shelljs.config.silent = true
function __download(answers) {
log.debug('[3]下载示例组件.')
const zipName = getTemplate(answers)
const repository = `${config.server}/mic-open/dmp/component/template/${zipName}`
return urllib.request(repository).then((res) => {
if (!res || !res.data || !res.headers || res.status !== 200) throw new Error('下载组件失败.')
return res
}).then(data => new Promise((resolve) => {
// const fileurl = Path.join(config.root, config.cacheDir, zipName)
// console.log(Object.getPrototypeOf(data.data))
const bufferStream = new stream.PassThrough()
bufferStream.end(data.data)
// fs.writeFileSync(fileurl, data.data)
bufferStream.pipe(unzip.Parse())
.on('entry', (entry) => {
const fileName = entry.path
const type = entry.type // 'Directory' or 'File'
if (type === 'Directory') {
fs.mkdirSync(Path.join('.', fileName))
}
if (type === 'File' && fileName.indexOf('DS_Store') === -1) {
if (fileName !== 'package.json') {
entry.pipe(fs.createWriteStream(Path.join('.', fileName)))
return
}
entry.on('data', (content) => {
log.debug(`entry on data [${fileName}]:`)
// 修改package.json
const comChartType = answers.comChartType && answers.comChartType.substring(0, answers.comChartType.indexOf('('))
let comDataLogicType = ''
let dataSourceOrigin = ''
switch (comChartType) {
case 'chart':
case 'chart-map':
comDataLogicType = 'column'
dataSourceOrigin = 'dataSet'
break
// 区间类型的数据(时间区间筛选、数值区间筛选)
case 'filter-interval':
comDataLogicType = 'interval'
dataSourceOrigin = 'dataSet'
break
case 'filter':
comDataLogicType = 'assist'
dataSourceOrigin = 'dataSet'
break
case 'auxiliary':
comDataLogicType = 'nondataset'
dataSourceOrigin = 'manual'
break
case 'auxiliary-none':
comDataLogicType = 'nondataset'
dataSourceOrigin = 'none'
break
default:
}
const baseChartLib = answers.baseChartLib && answers.baseChartLib.substring(0, answers.baseChartLib.indexOf('('))
const runTerminal = (answers.runTerminal && answers.runTerminal.map(terminal => terminal.substring(0, terminal.indexOf('(')))) || []
content = content.toString('utf-8')
content = JSON.parse(content)
content.name = answers.comName
content.version = '0.0.1'
content.description = answers.comDesc
if (content.platform) {
content.platform.name = answers.comCnName
// 针对filter-interval与auxiliary-none类型进行处理
content.platform.chartType = comChartType.replace(/-.*$/, '')
content.platform.dataLogicType = comDataLogicType
content.platform.containMapGallery = comChartType === 'chart-map'
content.platform.baseChartLib = baseChartLib ? [baseChartLib] : []
content.platform.runTerminal = runTerminal
}
if (content.config) {
content.config.dataSourceOrigin = dataSourceOrigin
}
content = JSON.stringify(content, null, 2)
fs.writeFileSync(Path.join('.', fileName), content)
})
}
}).on('close', () => {
resolve()
}).on('error', (err) => {
console.log('err:', err)
})
})).catch((e) => {
throw e.stack || e
})
}
function createDirForCom(answers) {
log.debug('[2]创建组件目录.')
const err = fs.mkdirSync(`./${answers.comName}`)
if (!err) {
process.chdir(`./${answers.comName}`)
return __download(answers).then(() => {
// shelljs.exec('npm install') // 无初始依赖 暂时不需要运行
})
} else {
throw new Error(`创建组件目录失败:${err.stack || err}`)
}
}
function showQuestions() {
log.debug('[1]输入组件信息.')
const questions = [
{
type: 'input',
name: 'comName',
message: '组件英文名(字母, _, 数字)是...',
validate(value) {
if (!value) {
return '不允许为空'
}
if (!/^[a-z0-9_]*$/.test(value)) {
return '请输入合法的包名, 支持小写字母,数字和下划线'
}
if (fs.existsSync(value)) {
return '该组件目录本地已存在!'
}
return true
}
},
{
type: 'input',
name: 'comCnName',
message: '组件中文名是...',
validate(value) {
if (!value) {
return '不允许为空'
}
return true
}
},
{
type: 'input',
name: 'comDesc',
message: '组件描述是...',
validate(value) {
if (!value) {
return '不允许为空'
}
return true
}
},
{
type: 'checkbox',
name: 'runTerminal',
message: '组件运行终端类型是...(可多选,面向多端)',
default: ['large_screen(大屏报告)'],
choices: ['large_screen(大屏报告)', 'pc_screen(PC仪表板)', 'mobile_screen(移动报告)']
},
{
type: 'list',
name: 'baseChartLib',
message: '组件基础图表库是...',
choices: ['(无)', 'echarts(百度echarts图表库)', 'f2(蚂蚁F2移动图表库)', 'd3(有数据集的筛选器图表)']
},
/*
新增chartType时 如需要与另一个类型公用相同的chartType
请使用[chartType]-类型描述的方式进行命名 例如filter与filter-interval
*/
{
type: 'list',
name: 'comChartType',
message: '组件图表类型是...',
choices: ['chart(有数据集的普通图表)', 'chart-map(有数据集的地图图表)', 'filter(有数据集的筛选器图表)', 'filter-interval(有数据集的区间筛选器图表)', 'auxiliary(无数据集、可配置数据的辅助图形)', 'auxiliary-none(无数据集、不可配置数据的辅助图形)']
},
{
type: 'list',
name: 'comJsFramework',
message: '开发组件所使用的JS框架是...',
choices: ['react', 'vue']
}
]
return inquirer.prompt(questions).then(answers => answers)
}
showQuestions()
.then(createDirForCom)
.then(() => {
log.info('组件创建完毕')
}).catch((e) => {
const msg = e.message
log.err(e.message, e)
if (msg && msg.includes('Prompts can not be meaningfully rendered in non-TTY environments')) {
log.info('Window 下请使用 CMD/PowerShell 或其他 TTY-environments 命令行工具运行')
}
})
}