mirror of
https://github.com/directus/directus.git
synced 2026-01-28 17:28:06 -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>
121 lines
3.0 KiB
TypeScript
121 lines
3.0 KiB
TypeScript
import { defaults } from './utils';
|
|
import { Argv } from 'yargs';
|
|
import { IOptions } from '../options';
|
|
import { IOutput, IUIComposer, IOutputFormat } from '../output';
|
|
import { TableOutputFormat } from './output/formats/table';
|
|
import { UIBuilder } from './output/ui';
|
|
import { CLIError, CLIRuntimeError } from './exceptions';
|
|
import { CommandHelp, GeneralHelp } from '../help';
|
|
import { WriteStream } from 'fs';
|
|
|
|
export type OutputOptions = {
|
|
format: string;
|
|
};
|
|
|
|
export class Output implements IOutput {
|
|
private options: IOptions;
|
|
private formats: {
|
|
table: IOutputFormat;
|
|
[name: string]: IOutputFormat;
|
|
};
|
|
private _text: string[];
|
|
private _help?: GeneralHelp | CommandHelp;
|
|
private _value?: any;
|
|
private _errors: CLIError[];
|
|
|
|
constructor(options: IOptions) {
|
|
this.formats = {
|
|
table: new TableOutputFormat(),
|
|
};
|
|
this._text = [];
|
|
this._errors = [];
|
|
this.options = options;
|
|
this.options.feature('output', (builder: Argv, _, raw) => {
|
|
builder.option('format', {
|
|
description: 'The output format',
|
|
default: 'table',
|
|
choices: [...Object.keys(this.formats)],
|
|
});
|
|
|
|
const explicitFormat = raw.format ?? 'table';
|
|
Object.entries(this.formats).forEach(([name, format]) => {
|
|
if (name === explicitFormat) {
|
|
format.registerOptions(builder);
|
|
}
|
|
});
|
|
|
|
if (explicitFormat != 'table' && !(explicitFormat in this.formats)) {
|
|
this.formats['table']!.registerOptions(builder);
|
|
throw new CLIRuntimeError(`Unknown output format: ${explicitFormat}`);
|
|
}
|
|
});
|
|
}
|
|
|
|
async help(help: GeneralHelp | CommandHelp): Promise<void> {
|
|
this._help = help;
|
|
}
|
|
|
|
async text(text: string): Promise<void> {
|
|
this._text.push(text);
|
|
}
|
|
|
|
async value<T>(value: T): Promise<void> {
|
|
this._value = value;
|
|
}
|
|
|
|
async error(err: CLIError): Promise<void> {
|
|
this._errors.push({
|
|
code: err.code,
|
|
name: err.name,
|
|
message: err.message,
|
|
stack: err.stack,
|
|
});
|
|
}
|
|
|
|
async flush(stream: WriteStream): Promise<void> {
|
|
stream.write(
|
|
await this.getFormatter().format(
|
|
{
|
|
value: {
|
|
result: this._value,
|
|
help: this._help,
|
|
errors: this._errors.length > 0 ? this._errors : undefined,
|
|
},
|
|
help: this._help,
|
|
text: this._text,
|
|
errors: this._errors,
|
|
},
|
|
this.getOptions()
|
|
)
|
|
);
|
|
|
|
this._help = undefined;
|
|
this._value = undefined;
|
|
this._errors = [];
|
|
this._text = [];
|
|
}
|
|
|
|
registerFormat(name: string, format: IOutputFormat): void {
|
|
this.formats[name] = format;
|
|
}
|
|
|
|
async compose(builder: (builder: IUIComposer) => Promise<void>): Promise<void> {
|
|
const outputBuilder = new UIBuilder();
|
|
await builder(outputBuilder);
|
|
await this.text(await outputBuilder.get());
|
|
}
|
|
|
|
getFormatter(): IOutputFormat {
|
|
const { format } = this.getOptions();
|
|
return this.formats[format] ?? this.formats['table']!;
|
|
}
|
|
|
|
getOptions(options?: Partial<OutputOptions>): OutputOptions {
|
|
const opts = this.options.values() as OutputOptions & { [k: string]: any };
|
|
return defaults(options, {
|
|
...opts,
|
|
format: (opts.format as any) ?? 'table',
|
|
}) as OutputOptions;
|
|
}
|
|
}
|