UNPKG

@qigy/run

Version:

A collection of tools capable of executing complex commands through their abbreviation.

135 lines (131 loc) 4.83 kB
const { fs, spawn } = require('./libs'); const { Item, Result, configPath, batPath, uiPath, includesPro, isUnix, ulid, welcome, yellow } = require('./utils'); class Core { list = []; constructor() { this.#readCfg(); } get indexMapping() { return this.list.reduce((pre, next, index) => { pre.set(next.alias, index); return pre; }, new Map()); } get commandMapping() { return this.list.reduce((pre, next, index) => { pre.set(next.alias, next.command); return pre; }, new Map()); } get aliasList() { return this.list.map((it) => it.alias); } #readCfg() { const config = fs.readFileSync(configPath, 'utf-8'); this.list = JSON.parse(config); } #writeCfg() { fs.writeFileSync(configPath, JSON.stringify(this.list, null, 2), 'utf-8'); } async get(keyword = '') { await this.#readCfg(); const query = decodeURIComponent(keyword); const result = this.list.filter((it) => { return includesPro(it.alias, query) || includesPro(it.command, query) || includesPro(it.remark || '', query); }); return new Result(true, result); } async del(aliasList = []) { const validData = aliasList.filter(Boolean); if (!validData.length) return new Result(false, null, 'Alias cannot be empty'); const target = validData.find((it) => !this.aliasList.includes(it)); if (target) return new Result(false, null, `Alias ${target} is not exists`); for (const alias of validData) { const index = this.indexMapping.get(alias); this.list.splice(index, 1); } await this.#writeCfg(); return new Result(true, null, `${validData.toString()} are deleted successfully`); } async add(alias, command, remark = '') { if (!alias || !command) return new Result(false, null, 'Alias or Command cannot be empty'); if (this.aliasList.includes(alias)) return new Result(false, null, `Alias ${alias} is already exists`); this.list.push(new Item(alias, command, remark)); await this.#writeCfg(); return new Result(true, null, `Alias ${alias} are added successfully`); } async update(alias, command, remark = '') { if (!alias || !command) return new Result(false, null, 'Alias or Command cannot be empty'); if (!this.aliasList.includes(alias)) return new Result(false, null, `Alias ${alias} is not exists`); const index = this.indexMapping.get(alias); this.list[index] = new Item(alias, command, remark); await this.#writeCfg(); return new Result(true, null, `Alias ${alias} are updated successfully`); } ui() { const { status } = spawn.sync('node', ['server.js'], { cwd: uiPath, stdio: 'inherit' }); return status; } run(alias = '', options = []) { if (!alias) return new Result(false, null, 'Alias cannot be empty'); let command = this.commandMapping.get(alias); if (!command) return new Result(false, null, `Alias ${alias} is not exists`); const varList = [...new Set(command.match(/\{([^}]*)\}/gi))]; for (const i in varList) { command = command.replaceAll(varList[i], options[i] || ''); } options = options.slice(varList.length); if (!isUnix) command = command.replaceAll('/', '\\'); fs.writeFileSync(batPath, command); const { status } = spawn.sync(isUnix ? 'sh' : batPath, [...(isUnix ? [batPath] : []), ...options], { stdio: 'inherit' }); return status; } async import(cfgList = []) { if (!Array.isArray(cfgList) || !cfgList.length) { return new Result(false, null, 'Config list cannot be empty'); } const tmp = {}; const newCfg = cfgList.reduce((pre, it) => { if (!it.alias || !it.command) return pre; let alias = it.alias; const command = it.command; const remark = it.remark || ''; if (!tmp[alias]) { tmp[alias] = true; } else { alias = `${alias}_${ulid()}`; } if (this.aliasList.includes(alias)) { alias = `${alias}_${ulid()}`; } pre.push({ alias, command, remark }); return pre; }, []); this.list = [...this.list, ...newCfg]; await this.#writeCfg(); return new Result(true, null, `Import successfully`); } doc() { console.log(welcome()); const document = ` Commands: add <alias> <command> <?remark> Add the config [command] or [remark] corresponding to [alias] update <alias> <command> <?remark> Update the config [command] or [remark] corresponding to [alias] del <alias> Delete the config corresponding to [alias] get [?keyword] Get the config corresponding to [keyword] ui Open the UI interface Use: You can use ${yellow('run alias')} to execute the corresponding command Variable: set: run add md "mkdir { dirName }" use: run md dirName `; console.log(document); } } module.exports = new Core();