mirror of
https://github.com/directus/directus.git
synced 2026-02-12 03:35:07 -05:00
* merge components merge args, parser, docs, formatter, help and handlers * change directus command and add auto debug * output format fixes * adds back some reformatted and documented commands * better help output format * refactor all output flow * export cli types * more formatting fixes and param rework * fix table spacing * add yaml formatting and fix string colors * finished formatting docs * remove log * remove package-lock * update dependency versions * fix command description * workaround typescript loading * module loading fixes added command error rename human to table fix disconnect usage * add typescript loader redirect execution to local package if installed locally added command alias `directus-ctl` * fix module load directories * reimplement stdin pipe to work on linux * fix sdk server info type * info command * Fix stdin bug Disable community extensions to discourage use for now Added template to config files Added password stdin to connect to instances Fixed typescript command load * Added command suggestions and QOL features * Linter fixes * Add command hints * Separate positional options * Add back delete many, fix delete one location * Change score logic * Add whoami util command * Add short online docs * Fix typo * Fix typo * Update commands * Param consistency fix and docs update * Create commands * Update package.json version * Update package-lock * Fixed several linting problems * Update dependencies * Update lock * Remove locked dependencies * Stop conflicts when in home directory * Package lock update and npm audit fix * Fix formatting errors * Comment out extending cli section until we figure out cli ext * Update readme * Tweak dev/build/prebuild script naming * Use up to date deps * Fix dependency version in lock (fix build) Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
127 lines
3.1 KiB
TypeScript
127 lines
3.1 KiB
TypeScript
//import * as util from 'util';
|
|
import { GluegunCommand } from 'gluegun';
|
|
import yargs, { Argv } from 'yargs';
|
|
import yargsParser from 'yargs-parser';
|
|
|
|
import { Command } from '../command';
|
|
import { IEvents } from '../events';
|
|
import { IOptions, Option } from '../options';
|
|
import { CLIRuntimeError } from './exceptions';
|
|
|
|
export type Registrator = (builder: Argv, command: Command, raw: any) => void;
|
|
|
|
export class Options implements IOptions {
|
|
private _raw: any;
|
|
private _parser: Argv;
|
|
private _parsed?: any;
|
|
private _error?: Error;
|
|
private _registrators: Registrator[];
|
|
|
|
constructor(events: IEvents, argv: string[]) {
|
|
this._parser = yargs(argv).help(false).version(false);
|
|
this._registrators = [];
|
|
this._parsed = null;
|
|
this._raw = yargsParser(argv);
|
|
|
|
events.on('command.options.register', (command: Command) => {
|
|
const cmd = command as any as GluegunCommand;
|
|
const name = cmd.commandPath
|
|
?.concat(...[command.settings?.parameters ?? ''])
|
|
.filter((p) => p != '')
|
|
.join(' ');
|
|
this._parser.fail((message, err) => {
|
|
this._error = err || new CLIRuntimeError(message);
|
|
});
|
|
|
|
this._parser.showHelpOnFail(false).exitProcess(false);
|
|
this._parser.command(
|
|
name ?? '$0',
|
|
cmd.description ?? '',
|
|
(builder) => {
|
|
for (const registrator of this._registrators) {
|
|
registrator(builder, command, this._raw);
|
|
}
|
|
return this._parser;
|
|
},
|
|
(values) => {
|
|
this._parsed = values;
|
|
}
|
|
);
|
|
|
|
this._parser.argv;
|
|
});
|
|
}
|
|
|
|
register(registrator: Registrator): void {
|
|
this._registrators.push(registrator);
|
|
}
|
|
|
|
feature(name: string, registrator: Registrator): void {
|
|
this._registrators.push((options: Argv, command: Command) => {
|
|
const { settings } = command;
|
|
if (!settings) {
|
|
return;
|
|
}
|
|
|
|
const { features } = settings;
|
|
if (!features || !(name in features) || !features[name]) {
|
|
return;
|
|
}
|
|
|
|
registrator(options, command, this._raw);
|
|
});
|
|
}
|
|
|
|
failed(): boolean {
|
|
return !!this._error;
|
|
}
|
|
|
|
error(): Error | undefined {
|
|
return this._error;
|
|
}
|
|
|
|
values(): any {
|
|
return this._parsed || {};
|
|
}
|
|
|
|
list(): Option[] {
|
|
const freeParser = this._parser as any;
|
|
const usage = freeParser.getUsageInstance();
|
|
const descriptions = usage.getDescriptions();
|
|
const keys = Object.keys(descriptions);
|
|
const options = freeParser.getOptions() as any;
|
|
const positionalGroup = usage.getPositionalGroupName() as any;
|
|
const groups = freeParser.getGroups() as any;
|
|
|
|
return keys.map<Option>((key) => {
|
|
const name = key;
|
|
const description = descriptions[key];
|
|
const value = options.default[key] ?? undefined;
|
|
const required = key in options.demandedOptions;
|
|
const choices = options.choices[key];
|
|
|
|
let type = 'string';
|
|
if (options.boolean.indexOf(key) >= 0) {
|
|
type = 'boolean';
|
|
} else if (options.number.indexOf(key) >= 0) {
|
|
type = 'number';
|
|
}
|
|
|
|
let positional = false;
|
|
if (positionalGroup in groups) {
|
|
positional = groups[positionalGroup].indexOf(key) >= 0;
|
|
}
|
|
|
|
return {
|
|
name,
|
|
description,
|
|
type,
|
|
required,
|
|
choices,
|
|
positional,
|
|
default: value,
|
|
};
|
|
});
|
|
}
|
|
}
|