UNPKG

nest-commander

Version:

A module for making CLI applications with NestJS. Decorators for running commands and separating out config parsers included. This package works on top of commander.

139 lines 6.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CompletionFactory = void 0; const commander_1 = require("commander"); const constants_1 = require("./constants"); /** * @description Factory to generate completion script for BASH and ZSH */ class CompletionFactory { /** * @description Register the completion command for either Bash, ZSH or Fig * @usage * ### Fig completion * Applying new command to generate the completion spec * @see https://fig.io/docs/guides/private-autocomplete * * @see https://fig.io/docs/guides/autocomplete-for-internal-tools * * ### Bash & ZSH completion * Put this script in your .bashrc or .zshrc * ```bash * source <(YOUR-CLI-NAMESPACE completion-script) * ``` * @param options - {@link CompletionFactoryOptions} */ static async registerCompletionCommand(app, options) { const commander = app.get(constants_1.Commander); const parsedOptions = CompletionFactory.getOptions(options); const { cmd } = parsedOptions; if (!cmd) { throw new Error('cmd is required'); } if (parsedOptions.nativeShell) { const { executablePath } = parsedOptions.nativeShell; CompletionFactory.setupNativeShellCompletion(commander, cmd, executablePath); } if (parsedOptions.fig) { try { // eslint-disable-next-line @typescript-eslint/no-var-requires const { addCompletionSpecCommand } = require('@fig/complete-commander'); addCompletionSpecCommand(commander); } catch (_a) { throw new Error(`There was a problem creating the fig completion. Did you make sure to install "@fig/complete-commander"?`); } } } static getOptions(options) { const parsedOptions = Object.assign({ fig: false, nativeShell: false }, options); return parsedOptions; } static setupNativeShellCompletion(commander, cmd, executablePath) { var _a, _b; const isZsh = (_b = (_a = process.env.SHELL) === null || _a === void 0 ? void 0 : _a.includes('zsh')) !== null && _b !== void 0 ? _b : false; const script = CompletionFactory.generateCompletionScript(executablePath, cmd, cmd, isZsh); const completionScriptCommand = new commander_1.Command() .command('completion-script', { hidden: true }) .action(() => { console.log(script); }); const completionCommand = new commander_1.Command() .command('completion', { hidden: true }) .action(() => { var _a; // @ts-expect-error - _prepareUserArgs is not a public property const _prepareUserArgs = commander._prepareUserArgs(process.argv); const parsed = commander.parseOptions(_prepareUserArgs); const { operands } = parsed; const filteredOperands = operands.filter((operand) => !['completion', cmd].includes(operand)); const [firstCommandName, ...restOperands] = filteredOperands; const firstCommand = // @ts-expect-error - _findCommand is not a public property (_a = commander._findCommand(firstCommandName)) !== null && _a !== void 0 ? _a : commander; const lastKnownCommand = restOperands.reduce((acc, operand) => { var _a; // @ts-expect-error - _findCommand is not a public property return (_a = acc === null || acc === void 0 ? void 0 : acc._findCommand(operand)) !== null && _a !== void 0 ? _a : acc; }, firstCommand); const completions = CompletionFactory.getCompletion(lastKnownCommand); console.log(completions.join('\n')); }); commander.addCommand(completionCommand); commander.addCommand(completionScriptCommand); } static generateCompletionScript(executablePath, cliName, command, isZsh) { let scriptTemplate = isZsh ? constants_1.COMPLETION_ZSH_TEMPLATE : constants_1.COMPLETION_SH_TEMPLATE; // apply ./ execution prefix if the executable path is a js file if (executablePath.match(/\.js$/)) { executablePath = `./${executablePath}`; } scriptTemplate = scriptTemplate.replace(/{{app_name}}/g, cliName); scriptTemplate = scriptTemplate.replace(/{{completion_command}}/g, command); scriptTemplate = scriptTemplate.replace(/{{app_path}}/g, executablePath); return scriptTemplate; } static defaultCompletion(command) { const completions = []; if (!command) { return []; } CompletionFactory.commandCompletions(completions, command); CompletionFactory.optionCompletions(completions, command); return completions; } static commandCompletions(completions, command) { const { commands } = command; for (const subcommand of commands) { // @ts-expect-error - _hidden is not a public property if (subcommand._hidden) { continue; } completions.push(subcommand.name()); } } static optionCompletions(completions, command) { var _a; const { options } = command; for (const option of options) { if (option.hidden) { continue; } const key = (_a = option.long) !== null && _a !== void 0 ? _a : option.short; if (!key) { continue; } completions.push(key); } } static getCompletion(command) { const defaultCompletion = CompletionFactory.defaultCompletion(command); const unique = new Set([...defaultCompletion, '--help']); const res = Array.from(unique); return res; } } exports.CompletionFactory = CompletionFactory; //# sourceMappingURL=completion.factory.js.map