alia
Version:
Alias To Go
97 lines (96 loc) • 3.19 kB
JavaScript
import logger from '../utils/logger.js';
export class FlagService {
confService;
gistService;
flagLoaderService;
dashTypes = {
'-': 'short',
'--': 'key'
};
constructor(confService, gistService, flagLoaderService) {
this.confService = confService;
this.gistService = gistService;
this.flagLoaderService = flagLoaderService;
}
async getFlags() {
let flags = await this.flagLoaderService.loadFlags(this.confService, this.gistService);
flags = flags.map((f) => {
if (f.flag.key === 'help') {
f.run = () => this.showHelp();
}
return f;
});
return flags;
}
async run(argv) {
const [arg, ...args] = argv;
if (!arg) {
return this.showHelp();
}
const flags = await this.getFlags();
const flag = flags.find((f) => this.dashMatch(f.flag, arg));
if (!flag?.flag.noConf && !this.confService.isReady) {
logger.init();
return true;
}
if (!flag) {
return false;
}
const dashRegex = /^-{1,2}\w/;
const cut = flag.flag.key === 'set' ? args.findIndex((a) => a === this.confService.separator) - 1 : undefined;
let rawData = args.slice(0, cut);
const mods = rawData.filter((a) => dashRegex.test(a));
const data = {};
for (const rawMod of mods) {
const mod = flag.mods.find((f) => this.dashMatch(f, rawMod));
if (!mod) {
logger.info(`unknown flag: ${rawMod}`);
logger.info('flag usage:');
this.flagHelp(flag, '');
return true;
}
data[mod.key] ??= [];
const next = rawData[1];
const end = mods.includes(next) ? -1 : 1;
const { [0]: _, [end]: value, ...rest } = rawData;
if (value) {
data[mod.key].push(value);
}
rawData = Object.values(rest);
}
const result = await flag.run(args, data);
if (!result) {
logger.info('flag usage:');
this.flagHelp(flag, '');
}
return true;
}
dashMatch(flagLike, value) {
const result = /(-{1,2})((?:\w-?)+)/.exec(value);
if (!result) {
return false;
}
const [_, dashes, rawKey] = result;
const key = this.dashTypes[dashes];
return flagLike[key] === rawKey;
}
async showHelp() {
const flags = await this.getFlags();
logger.info(`usage: al [options] [alias] [separator] [command]`);
logger.info();
logger.info('options:');
flags.forEach((flag) => {
this.flagHelp(flag);
});
return true;
}
flagHelp({ flag, mods }, pad = '\t') {
const desc = (f) => `\t\t${f.desc}`;
const short = (f) => `, -${f.short}`;
logger.info(`${pad}--${flag.key}${short(flag)}${desc(flag)}`);
mods.forEach((m) => {
logger.info(`${pad}\t--${m.key}${short(m)}${desc(m)}`);
});
logger.info();
}
}