xmzs
Version:
274 lines (235 loc) • 8.4 kB
JavaScript
const { program } = require('commander')
const PKG = require('../package.json')
const registries = require('../registries.json');
const inquirer = require('inquirer');
const { exec, execSync } = require('child_process')
const ping = require('node-http-ping')
const fs = require('fs')
const chalk = require("chalk");
const path = require('path')
program.version(PKG.version)
const whiteList = ['npm', 'yarn', 'tencent', 'cnpm', 'taobao', 'npmMirror'] //白名单
const getOrigin = async () => {
return await execSync('npm get registry', { encoding: "utf-8" })
}
program.command('ls').description('查看镜像').action(async () => {
const res = await getOrigin()
const keys = Object.keys(registries)
const message = []
const max = Math.max(...keys.map(v => v.length)) + 3
keys.forEach(k => {
const newK = registries[k].registry == res.trim() ? ('* ' + k) : (' ' + k)
const Arr = new Array(...newK)
Arr.length = max;
const prefix = Array.from(Arr).map(v => v ? v : '-').join('')
message.push(prefix + ' ' + registries[k].registry)
})
console.log(message.join('\n'))
})
program.command('use').description('请选择镜像').action(() => {
inquirer.prompt([
{
type: "list",
name: "sel",
message: "请选择镜像",
choices: Object.keys(registries)
}
]).then(result => {
const reg = registries[result.sel].registry
exec(`npm config set registry ${reg}`, null, (err, stdout, stderr) => {
if (err) {
console.error('切换错误', err)
} else {
console.log('切换成功')
}
})
})
})
program.command('current').description('查看当前源').action(async () => {
const reg = await getOrigin()
const v = Object.keys(registries).find(k => {
if (registries[k].registry === reg.trim()) {
return k;
}
})
if (v) {
console.log(chalk.blue('当前源:', v))
} else {
console.log(chalk.green('当前源:', reg))
}
})
program.command('ping').description('测试镜像地址速度').action(() => {
inquirer.prompt([
{
type: "list",
name: "sel",
message: "请选择镜像",
choices: Object.keys(registries)
}
]).then(result => {
const url = registries[result.sel].ping.trim()
ping(url).then(time => console.log(chalk.blue(`响应时长: ${time}ms`)))
.catch(() => console.log(chalk.red('GG', 'timeout')))
})
})
program.command('add').description('自定义镜像').action(() => {
inquirer.prompt([
{
type: "input",
name: "name",
message: "请输入镜像名称",
validate(answer) {
const keys = Object.keys(registries)
if (keys.includes(answer)) {
return `不能起名${answer}跟保留字冲突`
}
if (!answer.trim()) {
return '名称不能为空'
}
return true
}
},
{
type: "input",
name: "url",
message: "请输入镜像地址",
validate(answer) {
if (!answer.trim()) {
return `url不能为空`
}
return true
}
}
]).then(result => {
const del = (url) => {
const arr = url.split('')
return arr[arr.length - 1] == '/' ? (arr.pop() && arr.join('')) : arr.join('')
}
registries[result.name] = {
home: result.url.trim(),
registry: result.url.trim(),
ping: del(result.url.trim()),
}
try {
fs.writeFileSync(path.join(__dirname, '../registries.json'), JSON.stringify(registries, null, 4))
console.log(chalk.blue('添加完成'))
}
catch (e) {
console.log(chalk.red(err))
}
})
})
program.command('delete').description('删除自定义的源').action(() => {
const keys = Object.keys(registries)
if (keys.length === whiteList.length) {
return console.log(chalk.red('当前无自定义源可以删除'))
} else {
const Difference = keys.filter((key) => !whiteList.includes(key))
inquirer.prompt([
{
type: "list",
name: "sel",
message: "请选择删除的镜像",
choices: Difference
}
]).then(async result => {
const current = await getOrigin()
const selOrigin = registries[result.sel]
if (current.trim() == selOrigin.registry.trim()) {
console.log(chalk.red(`当前还在使用该镜像${registries[result.sel].registry},请切换其他镜像删除`))
} else {
try {
delete registries[result.sel]
fs.writeFileSync(path.join(__dirname, '../registries.json'), JSON.stringify(registries, null, 4))
console.log(chalk.green('SUCCESS 操作完成'))
}
catch (e) {
console.log(chalk.red(err))
}
}
})
}
})
program.command('rename').description('重命名').action(() => {
const keys = Object.keys(registries)
if (keys.length === whiteList.length) {
return console.log(chalk.red('当前无自定义源可以重命名'))
} else {
const Difference = keys.filter((key) => !whiteList.includes(key))
inquirer.prompt([
{
type: "list",
name: "sel",
message: "请选择名称",
choices: Difference
},
{
type: "input",
name: "rename",
message: "请输入新名称",
validate(answer) {
const keys = Object.keys(registries)
if (keys.includes(answer)) {
return `不能起名${answer}跟保留字冲突`
}
if (!answer.trim()) {
return `名称不能为空`
}
return true;
}
}
]).then(async result => {
registries[result.rename] = Object.assign({}, registries[result.sel])
delete registries[result.sel]
try {
fs.writeFileSync(path.join(__dirname, '../registries.json'), JSON.stringify(registries, null, 4))
console.log(chalk.greenBright(`SUCCESS 重命名完成 ${result.rename}`))
}
catch (e) {
console.log(chalk.red(err))
}
})
}
})
program.command('edit').description('编辑自定义的源').action(async () => {
const keys = Object.keys(registries)
if (keys.length === whiteList.length) {
return console.log(chalk.red('当前无自定义源可以编辑'))
}
const Difference = keys.filter((key) => !whiteList.includes(key))
const { sel } = await inquirer.prompt([{
type: "list",
name: "sel",
message: "请选择需要编辑的源",
choices: Difference
}])
const { registerUrl } = await inquirer.prompt([{
type: "input",
name: "registerUrl",
message: "输入修改后的镜像地址",
default: () => registries[sel].registry,
validate(registerUrl) {
if (!registerUrl.trim())
return "镜像地址不能为空"
return true
}
}])
const del = (url) => {
const arr = url.split('')
return arr[arr.length - 1] == '/' ? (arr.pop() && arr.join('')) : arr.join('')
}
registries[sel] = {
home: registerUrl.trim(),
registry: registerUrl.trim(),
ping: del(registerUrl.trim()),
}
try {
fs.writeFileSync(path.join(__dirname, '../registries.json'), JSON.stringify(registries, null, 4))
console.log(chalk.blue('修改完成'))
}
catch (e) {
console.log(chalk.red(err))
}
})
program.parse(process.argv)