Socket
Socket
Sign inDemoInstall

clipanion

Package Overview
Dependencies
1
Maintainers
1
Versions
83
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.2.1 to 4.0.0-rc.1

lib/advanced/builtins/tokens.d.ts

1

lib/advanced/builtins/index.d.ts
export * from './definitions';
export * from './help';
export * from './tokens';
export * from './version';

@@ -7,2 +7,3 @@ 'use strict';

var advanced_builtins_help = require('./help.js');
var advanced_builtins_tokens = require('./tokens.js');
var advanced_builtins_version = require('./version.js');

@@ -14,2 +15,3 @@

exports.HelpCommand = advanced_builtins_help.HelpCommand;
exports.TokensCommand = advanced_builtins_tokens.TokensCommand;
exports.VersionCommand = advanced_builtins_version.VersionCommand;

@@ -98,2 +98,6 @@ /// <reference types="node" />

/**
* Get the definition of a particular command.
*/
definition(command: CommandClass<Context>): Definition | null;
/**
* Formats errors using colors.

@@ -142,2 +146,19 @@ *

};
export declare type MandatoryContextKeys<Context extends BaseContext> = keyof MandatoryContext<Context>;
export declare type MandatoryContext<Context extends BaseContext> = {
[K in Exclude<keyof Context, keyof BaseContext> as undefined extends Context[K] ? never : K]: Context[K];
};
export declare type UserProvidedContext<Context extends BaseContext> = MandatoryContext<Context> & Partial<Omit<Context, MandatoryContextKeys<Context>>>;
export declare type MaybeProvidedContext<Context extends BaseContext> = MandatoryContextKeys<Context> extends never ? {
context?: UserProvidedContext<Context>;
} : {
context: UserProvidedContext<Context>;
};
export declare type ProcessOptions<Context extends BaseContext> = MaybeProvidedContext<Context> & {
input: Array<string>;
/**
* @deprecated Experimental setting, exact behavior may change
*/
partial?: boolean;
};
/**

@@ -222,2 +243,3 @@ * An all-in-one helper that simultaneously instantiate a CLI and immediately

register(commandClass: CommandClass<Context>): void;
process(opts: ProcessOptions<Context>): Command<Context>;
process(input: Array<string>, context: VoidIfEmpty<Omit<Context, keyof BaseContext>>): Command<Context>;

@@ -237,3 +259,5 @@ process(input: Array<string>, context: MakeOptional<Context, keyof BaseContext>): Command<Context>;

runExit(input: Command<Context> | Array<string>, context: MakeOptional<Context, keyof BaseContext>): Promise<void>;
suggest(input: Array<string>, partial: boolean): string[][];
definition(commandClass: CommandClass<Context>, { colored }?: {
colored?: boolean;
}): Definition | null;
definitions({ colored }?: {

@@ -258,2 +282,4 @@ colored?: boolean;

options: {
preferredName: string;
nameSet: string[];
definition: string;

@@ -270,2 +296,4 @@ description: string;

options: {
preferredName: string;
nameSet: string[];
definition: string;

@@ -272,0 +300,0 @@ description: string;

52

lib/advanced/Cli.js

@@ -144,5 +144,8 @@ 'use strict';

}
process(input, userContext) {
process(opts, contextArg) {
const { input, context: userContext, partial } = typeof opts === `object` && Array.isArray(opts)
? { input: opts, context: contextArg }
: opts;
const { contexts, process } = this.builder.compile();
const state = process(input);
const state = process(input, { partial });
const context = {

@@ -157,2 +160,3 @@ ...Cli.defaultContext,

command.context = context;
command.tokens = state.tokens;
return command;

@@ -168,2 +172,3 @@ }

command.context = context;
command.tokens = state.tokens;
command.path = state.path;

@@ -215,2 +220,3 @@ try {

definitions: () => this.definitions(),
definition: command => this.definition(command),
error: (error, opts) => this.error(error, opts),

@@ -238,26 +244,28 @@ format: colored => this.format(colored),

}
suggest(input, partial) {
const { suggest } = this.builder.compile();
return suggest(input, partial);
definition(commandClass, { colored = false } = {}) {
if (!commandClass.usage)
return null;
const { usage: path } = this.getUsageByRegistration(commandClass, { detailed: false });
const { usage, options } = this.getUsageByRegistration(commandClass, { detailed: true, inlineOptions: false });
const category = typeof commandClass.usage.category !== `undefined`
? format.formatMarkdownish(commandClass.usage.category, { format: this.format(colored), paragraphs: false })
: undefined;
const description = typeof commandClass.usage.description !== `undefined`
? format.formatMarkdownish(commandClass.usage.description, { format: this.format(colored), paragraphs: false })
: undefined;
const details = typeof commandClass.usage.details !== `undefined`
? format.formatMarkdownish(commandClass.usage.details, { format: this.format(colored), paragraphs: true })
: undefined;
const examples = typeof commandClass.usage.examples !== `undefined`
? commandClass.usage.examples.map(([label, cli]) => [format.formatMarkdownish(label, { format: this.format(colored), paragraphs: false }), cli.replace(/\$0/g, this.binaryName)])
: undefined;
return { path, usage, category, description, details, examples, options };
}
definitions({ colored = false } = {}) {
const data = [];
for (const [commandClass, { index }] of this.registrations) {
if (typeof commandClass.usage === `undefined`)
for (const commandClass of this.registrations.keys()) {
const usage = this.definition(commandClass, { colored });
if (!usage)
continue;
const { usage: path } = this.getUsageByIndex(index, { detailed: false });
const { usage, options } = this.getUsageByIndex(index, { detailed: true, inlineOptions: false });
const category = typeof commandClass.usage.category !== `undefined`
? format.formatMarkdownish(commandClass.usage.category, { format: this.format(colored), paragraphs: false })
: undefined;
const description = typeof commandClass.usage.description !== `undefined`
? format.formatMarkdownish(commandClass.usage.description, { format: this.format(colored), paragraphs: false })
: undefined;
const details = typeof commandClass.usage.details !== `undefined`
? format.formatMarkdownish(commandClass.usage.details, { format: this.format(colored), paragraphs: true })
: undefined;
const examples = typeof commandClass.usage.examples !== `undefined`
? commandClass.usage.examples.map(([label, cli]) => [format.formatMarkdownish(label, { format: this.format(colored), paragraphs: false }), cli.replace(/\$0/g, this.binaryName)])
: undefined;
data.push({ path, usage, category, description, details, examples, options });
data.push(usage);
}

@@ -264,0 +272,0 @@ return data;

import { LooseTest } from 'typanion';
import { Token } from '../core';
import { BaseContext, MiniCli } from './Cli';

@@ -52,2 +53,4 @@ import { isOptionSymbol } from './options/utils';

options: Array<{
preferredName: string;
nameSet: Array<string>;
definition: string;

@@ -73,2 +76,3 @@ description?: string;

export declare abstract class Command<Context extends BaseContext = BaseContext> {
[`constructor`]: CommandClass<Context>;
/**

@@ -137,2 +141,7 @@ * @deprecated Do not use this; prefer the static `paths` property instead.

path: Array<string>;
/**
* Predefined variable that will be populated with the tokens found when
* interpreting the command line.
*/
tokens: Array<Token>;
validateAndExecute(): Promise<number>;

@@ -139,0 +148,0 @@ /**

export { Command } from './Command';
export { BaseContext, Cli, RunContext, CliOptions } from './Cli';
export { CommandClass, Usage, Definition } from './Command';
export { Token } from '../core';
export { UsageError, ErrorMeta, ErrorWithMeta } from '../errors';

@@ -5,0 +6,0 @@ export { formatMarkdownish, ColorFormat } from '../format';

@@ -6,6 +6,6 @@ 'use strict';

var advanced_options_utils = require('./utils.js');
var advanced_options_Proxy = require('./Proxy.js');
var advanced_options_Array = require('./Array.js');
var advanced_options_Boolean = require('./Boolean.js');
var advanced_options_Counter = require('./Counter.js');
var advanced_options_Proxy = require('./Proxy.js');
var advanced_options_Rest = require('./Rest.js');

@@ -22,7 +22,7 @@ var advanced_options_String = require('./String.js');

exports.rerouteArguments = advanced_options_utils.rerouteArguments;
exports.Proxy = advanced_options_Proxy.Proxy;
exports.Array = advanced_options_Array.Array;
exports.Boolean = advanced_options_Boolean.Boolean;
exports.Counter = advanced_options_Counter.Counter;
exports.Proxy = advanced_options_Proxy.Proxy;
exports.Rest = advanced_options_Rest.Rest;
exports.String = advanced_options_String.String;

@@ -1,6 +0,12 @@

export declare const NODE_INITIAL = 0;
export declare const NODE_SUCCESS = 1;
export declare const NODE_ERRORED = 2;
export declare const START_OF_INPUT = "\u0001";
export declare const END_OF_INPUT = "\0";
export declare enum SpecialToken {
StartOfInput = "\0",
EndOfInput = "\u0001",
EndOfPartialInput = "\u0002"
}
export declare enum NodeType {
InitialNode = 0,
SuccessNode = 1,
ErrorNode = 2,
CustomNode = 3
}
export declare const HELP_COMMAND_INDEX = -1;

@@ -11,2 +17,2 @@ export declare const HELP_REGEX: RegExp;

export declare const BINDING_REGEX: RegExp;
export declare const DEBUG: boolean;
export declare const IS_DEBUG: boolean;

@@ -5,7 +5,13 @@ 'use strict';

const NODE_INITIAL = 0;
const NODE_SUCCESS = 1;
const NODE_ERRORED = 2;
const START_OF_INPUT = `\u0001`;
const END_OF_INPUT = `\u0000`;
(function (SpecialToken) {
SpecialToken["StartOfInput"] = "\0";
SpecialToken["EndOfInput"] = "\u0001";
SpecialToken["EndOfPartialInput"] = "\u0002";
})(exports.SpecialToken || (exports.SpecialToken = {}));
(function (NodeType) {
NodeType[NodeType["InitialNode"] = 0] = "InitialNode";
NodeType[NodeType["SuccessNode"] = 1] = "SuccessNode";
NodeType[NodeType["ErrorNode"] = 2] = "ErrorNode";
NodeType[NodeType["CustomNode"] = 3] = "CustomNode";
})(exports.NodeType || (exports.NodeType = {}));
const HELP_COMMAND_INDEX = -1;

@@ -16,14 +22,9 @@ const HELP_REGEX = /^(-h|--help)(?:=([0-9]+))?$/;

const BINDING_REGEX = /^([^=]+)=([\s\S]*)$/;
const DEBUG = process.env.DEBUG_CLI === `1`;
const IS_DEBUG = process.env.DEBUG_CLI === `1`;
exports.BATCH_REGEX = BATCH_REGEX;
exports.BINDING_REGEX = BINDING_REGEX;
exports.DEBUG = DEBUG;
exports.END_OF_INPUT = END_OF_INPUT;
exports.HELP_COMMAND_INDEX = HELP_COMMAND_INDEX;
exports.HELP_REGEX = HELP_REGEX;
exports.NODE_ERRORED = NODE_ERRORED;
exports.NODE_INITIAL = NODE_INITIAL;
exports.NODE_SUCCESS = NODE_SUCCESS;
exports.IS_DEBUG = IS_DEBUG;
exports.OPTION_REGEX = OPTION_REGEX;
exports.START_OF_INPUT = START_OF_INPUT;

@@ -0,1 +1,2 @@

import { NodeType } from './constants';
export declare function debug(str: string): void;

@@ -5,2 +6,27 @@ export declare type StateMachine = {

};
export declare type TokenBase = {
segmentIndex: number;
};
export declare type PathToken = TokenBase & {
type: `path`;
slice?: undefined;
};
export declare type PositionalToken = TokenBase & {
type: `positional`;
slice?: undefined;
};
export declare type OptionToken = TokenBase & {
type: `option`;
slice?: [number, number];
option: string;
};
export declare type AssignToken = TokenBase & {
type: `assign`;
slice: [number, number];
};
export declare type ValueToken = TokenBase & {
type: `value`;
slice?: [number, number];
};
export declare type Token = PathToken | PositionalToken | OptionToken | AssignToken | ValueToken;
export declare type RunState = {

@@ -22,2 +48,3 @@ candidateUsage: string | null;

selectedIndex: number | null;
tokens: Array<Token>;
};

@@ -59,8 +86,8 @@ export declare function makeStateMachine(): StateMachine;

to: number;
reducer: "setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError" | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError"] | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError", Partial<RunState>] | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError", number] | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError", (string | undefined)?] | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError", string] | undefined;
reducer: "setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError" | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError"] | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError", Partial<RunState>] | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError", number] | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError", Map<string, string>] | ["setCandidateState" | "setSelectedIndex" | "pushBatch" | "pushBound" | "pushPath" | "pushPositional" | "pushExtra" | "pushExtraNoLimits" | "pushTrue" | "pushFalse" | "pushUndefined" | "pushStringValue" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | "setOptionArityError", string] | undefined;
};
export declare function cloneNode(input: Node, offset?: number): Node;
export declare function registerDynamic<T extends keyof typeof tests, R extends keyof typeof reducers>(machine: StateMachine, from: number, test: Callback<T, typeof tests>, to: number, reducer?: Callback<R, typeof reducers>): void;
export declare function registerShortcut<R extends keyof typeof reducers>(machine: StateMachine, from: number, to: number, reducer?: Callback<R, typeof reducers>): void;
export declare function registerStatic<R extends keyof typeof reducers>(machine: StateMachine, from: number, test: string, to: number, reducer?: Callback<R, typeof reducers>): void;
export declare function registerDynamic<T extends keyof typeof tests, R extends keyof typeof reducers>(machine: StateMachine, from: NodeType | number, test: Callback<T, typeof tests>, to: NodeType | number, reducer?: Callback<R, typeof reducers>): void;
export declare function registerShortcut<R extends keyof typeof reducers>(machine: StateMachine, from: NodeType | number, to: NodeType | number, reducer?: Callback<R, typeof reducers>): void;
export declare function registerStatic<R extends keyof typeof reducers>(machine: StateMachine, from: NodeType | number, test: string, to: NodeType | number, reducer?: Callback<R, typeof reducers>): void;
declare type UndefinedKeys<T> = {

@@ -71,4 +98,4 @@ [P in keyof T]-?: undefined extends T[P] ? P : never;

declare type TupleKeys<T> = Exclude<keyof T, keyof []>;
export declare type CallbackFn<P extends Array<any>, R> = (state: RunState, segment: string, ...args: P) => R;
export declare type CallbackFnParameters<T extends CallbackFn<any, any>> = T extends ((state: RunState, segment: string, ...args: infer P) => any) ? P : never;
export declare type CallbackFn<P extends Array<any>, R> = (state: RunState, segment: string, segmentIndex: number, ...args: P) => R;
export declare type CallbackFnParameters<T extends CallbackFn<any, any>> = T extends ((state: RunState, segment: string, segmentIndex: number, ...args: infer P) => any) ? P : never;
export declare type CallbackStore<T extends string, R> = Record<T, CallbackFn<any, R>>;

@@ -78,4 +105,3 @@ export declare type Callback<T extends string, S extends CallbackStore<T, any>> = [

] extends [UndefinedTupleKeys<CallbackFnParameters<S[T]>>] ? (T | [T, ...CallbackFnParameters<S[T]>]) : [T, ...CallbackFnParameters<S[T]>];
export declare function execute<T extends string, R, S extends CallbackStore<T, R>>(store: S, callback: Callback<T, S>, state: RunState, segment: string): R;
export declare function suggest(callback: Callback<keyof typeof tests, typeof tests>, state: RunState): Array<string> | null;
export declare function execute<T extends string, R, S extends CallbackStore<T, R>>(store: S, callback: Callback<T, S>, state: RunState, segment: string, segmentIndex: number): R;
export declare const tests: {

@@ -85,12 +111,12 @@ always: () => boolean;

isNotOptionLike: (state: RunState, segment: string) => boolean;
isOption: (state: RunState, segment: string, name: string, hidden?: boolean) => boolean;
isBatchOption: (state: RunState, segment: string, names: Array<string>) => boolean;
isBoundOption: (state: RunState, segment: string, names: Array<string>, options: Array<OptDefinition>) => boolean;
isNegatedOption: (state: RunState, segment: string, name: string) => boolean;
isOption: (state: RunState, segment: string, segmentIndex: number, name: string) => boolean;
isBatchOption: (state: RunState, segment: string, segmentIndex: number, names: Map<string, string>) => boolean;
isBoundOption: (state: RunState, segment: string, segmentIndex: number, names: Map<string, string>, options: Array<OptDefinition>) => boolean;
isNegatedOption: (state: RunState, segment: string, segmentIndex: number, name: string) => boolean;
isHelp: (state: RunState, segment: string) => boolean;
isUnsupportedOption: (state: RunState, segment: string, names: Array<string>) => boolean;
isUnsupportedOption: (state: RunState, segment: string, segmentIndex: number, names: Map<string, string>) => boolean;
isInvalidOption: (state: RunState, segment: string) => boolean;
};
export declare const reducers: {
setCandidateState: (state: RunState, segment: string, candidateState: Partial<RunState>) => {
setCandidateState: (state: RunState, segment: string, segmentIndex: number, candidateState: Partial<RunState>) => {
candidateUsage: string | null;

@@ -111,4 +137,5 @@ requiredOptions: Array<Array<string>>;

selectedIndex: number | null;
tokens: Array<Token>;
};
setSelectedIndex: (state: RunState, segment: string, index: number) => {
setSelectedIndex: (state: RunState, segment: string, segmentIndex: number, index: number) => {
selectedIndex: number;

@@ -129,4 +156,5 @@ candidateUsage: string | null;

remainder: string | null;
tokens: Array<Token>;
};
pushBatch: (state: RunState, segment: string) => {
pushBatch: (state: RunState, segment: string, segmentIndex: number, names: Map<string, string>) => {
options: {

@@ -136,2 +164,3 @@ name: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -149,3 +178,3 @@ requiredOptions: Array<Array<string>>;

};
pushBound: (state: RunState, segment: string) => {
pushBound: (state: RunState, segment: string, segmentIndex: number) => {
options: {

@@ -155,2 +184,3 @@ name: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -168,4 +198,5 @@ requiredOptions: Array<Array<string>>;

};
pushPath: (state: RunState, segment: string) => {
pushPath: (state: RunState, segment: string, segmentIndex: number) => {
path: string[];
tokens: Token[];
candidateUsage: string | null;

@@ -186,3 +217,3 @@ requiredOptions: Array<Array<string>>;

};
pushPositional: (state: RunState, segment: string) => {
pushPositional: (state: RunState, segment: string, segmentIndex: number) => {
positionals: {

@@ -192,2 +223,3 @@ value: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -205,3 +237,3 @@ requiredOptions: Array<Array<string>>;

};
pushExtra: (state: RunState, segment: string) => {
pushExtra: (state: RunState, segment: string, segmentIndex: number) => {
positionals: {

@@ -211,2 +243,3 @@ value: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -224,3 +257,3 @@ requiredOptions: Array<Array<string>>;

};
pushExtraNoLimits: (state: RunState, segment: string) => {
pushExtraNoLimits: (state: RunState, segment: string, segmentIndex: number) => {
positionals: {

@@ -230,2 +263,3 @@ value: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -243,3 +277,3 @@ requiredOptions: Array<Array<string>>;

};
pushTrue: (state: RunState, segment: string, name?: string) => {
pushTrue: (state: RunState, segment: string, segmentIndex: number, name: string) => {
options: {

@@ -249,2 +283,3 @@ name: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -262,3 +297,3 @@ requiredOptions: Array<Array<string>>;

};
pushFalse: (state: RunState, segment: string, name?: string) => {
pushFalse: (state: RunState, segment: string, segmentIndex: number, name: string) => {
options: {

@@ -268,2 +303,3 @@ name: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -281,3 +317,3 @@ requiredOptions: Array<Array<string>>;

};
pushUndefined: (state: RunState, segment: string) => {
pushUndefined: (state: RunState, segment: string, segmentIndex: number, name: string) => {
options: {

@@ -287,2 +323,3 @@ name: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -300,3 +337,3 @@ requiredOptions: Array<Array<string>>;

};
pushStringValue: (state: RunState, segment: string) => {
pushStringValue: (state: RunState, segment: string, segmentIndex: number) => {
options: {

@@ -306,2 +343,3 @@ name: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -319,3 +357,3 @@ requiredOptions: Array<Array<string>>;

};
setStringValue: (state: RunState, segment: string) => {
setStringValue: (state: RunState, segment: string, segmentIndex: number) => {
options: {

@@ -325,2 +363,3 @@ name: string;

}[];
tokens: Token[];
candidateUsage: string | null;

@@ -354,4 +393,5 @@ requiredOptions: Array<Array<string>>;

selectedIndex: number | null;
tokens: Array<Token>;
};
useHelp: (state: RunState, segment: string, command: number) => {
useHelp: (state: RunState, segment: string, segmentIndex: number, command: number) => {
options: {

@@ -372,4 +412,5 @@ name: string;

selectedIndex: number | null;
tokens: Array<Token>;
};
setError: (state: RunState, segment: string, errorMessage: string) => {
setError: (state: RunState, segment: string, segmentIndex: number, errorMessage: string) => {
errorMessage: string;

@@ -390,2 +431,3 @@ candidateUsage: string | null;

selectedIndex: number | null;
tokens: Array<Token>;
};

@@ -408,2 +450,3 @@ setOptionArityError: (state: RunState, segment: string) => {

selectedIndex: number | null;
tokens: Array<Token>;
};

@@ -419,3 +462,4 @@ };

export declare type OptDefinition = {
names: Array<string>;
preferredName: string;
nameSet: Array<string>;
description?: string;

@@ -430,3 +474,3 @@ arity: number;

readonly cliOpts: Readonly<CliOptions>;
readonly allOptionNames: Array<string>;
readonly allOptionNames: Map<string, string>;
readonly arity: ArityDefinition;

@@ -451,3 +495,3 @@ readonly options: Array<OptDefinition>;

}): void;
addOption({ names, description, arity, hidden, required, allowBinding }: Partial<OptDefinition> & {
addOption({ names: nameSet, description, arity, hidden, required, allowBinding }: Partial<OptDefinition> & {
names: Array<string>;

@@ -462,2 +506,4 @@ }): void;

options: {
preferredName: string;
nameSet: Array<string>;
definition: string;

@@ -484,4 +530,5 @@ description: string;

contexts: Context[];
process: (input: string[]) => RunState;
suggest: (input: string[], partial: boolean) => string[][];
process: (input: string[], { partial }?: {
partial?: boolean | undefined;
}) => RunState;
};

@@ -495,6 +542,7 @@ constructor({ binaryName }?: Partial<CliOptions>);

contexts: Context[];
process: (input: Array<string>) => RunState;
suggest: (input: Array<string>, partial: boolean) => string[][];
process: (input: Array<string>, { partial }?: {
partial?: boolean | undefined;
}) => RunState;
};
}
export {};

@@ -10,3 +10,3 @@ 'use strict';

function debug(str) {
if (constants.DEBUG) {
if (constants.IS_DEBUG) {
console.log(str);

@@ -25,7 +25,11 @@ }

selectedIndex: constants.HELP_COMMAND_INDEX,
tokens: [],
};
function makeStateMachine() {
return {
nodes: [makeNode(), makeNode(), makeNode()],
const stateMachine = {
nodes: [],
};
for (let t = 0; t < constants.NodeType.CustomNode; ++t)
stateMachine.nodes.push(makeNode());
return stateMachine;
}

@@ -41,6 +45,6 @@ function makeAnyOfMachine(inputs) {

output.nodes.push(cloneNode(input.nodes[t], offset));
offset += input.nodes.length - 2;
offset += input.nodes.length - constants.NodeType.CustomNode + 1;
}
for (const head of heads)
registerShortcut(output, constants.NODE_INITIAL, head);
registerShortcut(output, constants.NodeType.InitialNode, head);
return output;

@@ -91,7 +95,7 @@ }

};
process(constants.NODE_INITIAL);
process(constants.NodeType.InitialNode);
}
function debugMachine(machine, { prefix = `` } = {}) {
// Don't iterate unless it's needed
if (constants.DEBUG) {
if (constants.IS_DEBUG) {
debug(`${prefix}Nodes are:`);

@@ -105,3 +109,5 @@ for (let t = 0; t < machine.nodes.length; ++t) {

debug(`Running a vm on ${JSON.stringify(input)}`);
let branches = [{ node: constants.NODE_INITIAL, state: {
let branches = [{
node: constants.NodeType.InitialNode,
state: {
candidateUsage: null,

@@ -116,7 +122,12 @@ requiredOptions: [],

selectedIndex: null,
} }];
tokens: [],
},
}];
debugMachine(machine, { prefix: ` ` });
const tokens = [constants.START_OF_INPUT, ...input];
const tokens = [constants.SpecialToken.StartOfInput, ...input];
for (let t = 0; t < tokens.length; ++t) {
const segment = tokens[t];
const isEOI = segment === constants.SpecialToken.EndOfInput || segment === constants.SpecialToken.EndOfPartialInput;
// The -1 is because we added a START_OF_INPUT token
const segmentIndex = t - 1;
debug(` Processing ${JSON.stringify(segment)}`);

@@ -127,3 +138,3 @@ const nextBranches = [];

const nodeDef = machine.nodes[node];
if (node === constants.NODE_ERRORED) {
if (node === constants.NodeType.ErrorNode) {
nextBranches.push({ node, state });

@@ -138,3 +149,3 @@ continue;

for (const { to, reducer } of transitions) {
nextBranches.push({ node: to, state: typeof reducer !== `undefined` ? execute(reducers, reducer, state, segment) : state });
nextBranches.push({ node: to, state: typeof reducer !== `undefined` ? execute(reducers, reducer, state, segment, segmentIndex) : state });
debug(` Static transition to ${to} found`);

@@ -154,3 +165,3 @@ }

for (const { to, reducer } of nodeDef.statics[candidate]) {
nextBranches.push({ node: to, state: typeof reducer !== `undefined` ? execute(reducers, reducer, state, segment) : state });
nextBranches.push({ node: to, state: typeof reducer !== `undefined` ? execute(reducers, reducer, state, segment, segmentIndex) : state });
debug(` Static transition to ${to} found`);

@@ -171,6 +182,6 @@ }

}
if (segment !== constants.END_OF_INPUT) {
if (!isEOI) {
for (const [test, { to, reducer }] of nodeDef.dynamics) {
if (execute(tests, test, state, segment)) {
nextBranches.push({ node: to, state: typeof reducer !== `undefined` ? execute(reducers, reducer, state, segment) : state });
if (execute(tests, test, state, segment, segmentIndex)) {
nextBranches.push({ node: to, state: typeof reducer !== `undefined` ? execute(reducers, reducer, state, segment, segmentIndex) : state });
debug(` Dynamic transition to ${to} found (via ${test})`);

@@ -181,5 +192,5 @@ }

}
if (nextBranches.length === 0 && segment === constants.END_OF_INPUT && input.length === 1) {
if (nextBranches.length === 0 && isEOI && input.length === 1) {
return [{
node: constants.NODE_INITIAL,
node: constants.NodeType.InitialNode,
state: basicHelpState,

@@ -190,3 +201,3 @@ }];

throw new errors.UnknownSyntaxError(input, branches.filter(({ node }) => {
return node !== constants.NODE_ERRORED;
return node !== constants.NodeType.ErrorNode;
}).map(({ state }) => {

@@ -196,3 +207,3 @@ return { usage: state.candidateUsage, reason: null };

}
if (nextBranches.every(({ node }) => node === constants.NODE_ERRORED)) {
if (nextBranches.every(({ node }) => node === constants.NodeType.ErrorNode)) {
throw new errors.UnknownSyntaxError(input, nextBranches.map(({ state }) => {

@@ -215,75 +226,4 @@ return { usage: state.candidateUsage, reason: state.errorMessage };

}
function checkIfNodeIsFinished(node, state) {
if (state.selectedIndex !== null)
return true;
if (Object.prototype.hasOwnProperty.call(node.statics, constants.END_OF_INPUT))
for (const { to } of node.statics[constants.END_OF_INPUT])
if (to === constants.NODE_SUCCESS)
return true;
return false;
}
function suggestMachine(machine, input, partial) {
// If we're accepting partial matches, then exact matches need to be
// prefixed with an extra space.
const prefix = partial && input.length > 0 ? [``] : [];
const branches = runMachineInternal(machine, input, partial);
const suggestions = [];
const suggestionsJson = new Set();
const traverseSuggestion = (suggestion, node, skipFirst = true) => {
let nextNodes = [node];
while (nextNodes.length > 0) {
const currentNodes = nextNodes;
nextNodes = [];
for (const node of currentNodes) {
const nodeDef = machine.nodes[node];
const keys = Object.keys(nodeDef.statics);
// The fact that `key` is unused is likely a bug, but no one has investigated it yet.
// TODO: Investigate it.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const key of Object.keys(nodeDef.statics)) {
const segment = keys[0];
for (const { to, reducer } of nodeDef.statics[segment]) {
if (reducer !== `pushPath`)
continue;
if (!skipFirst)
suggestion.push(segment);
nextNodes.push(to);
}
}
}
skipFirst = false;
}
const json = JSON.stringify(suggestion);
if (suggestionsJson.has(json))
return;
suggestions.push(suggestion);
suggestionsJson.add(json);
};
for (const { node, state } of branches) {
if (state.remainder !== null) {
traverseSuggestion([state.remainder], node);
continue;
}
const nodeDef = machine.nodes[node];
const isFinished = checkIfNodeIsFinished(nodeDef, state);
for (const [candidate, transitions] of Object.entries(nodeDef.statics))
if ((isFinished && candidate !== constants.END_OF_INPUT) || (!candidate.startsWith(`-`) && transitions.some(({ reducer }) => reducer === `pushPath`)))
traverseSuggestion([...prefix, candidate], node);
if (!isFinished)
continue;
for (const [test, { to }] of nodeDef.dynamics) {
if (to === constants.NODE_ERRORED)
continue;
const tokens = suggest(test, state);
if (tokens === null)
continue;
for (const token of tokens) {
traverseSuggestion([...prefix, token], node);
}
}
}
return [...suggestions].sort();
}
function runMachine(machine, input) {
const branches = runMachineInternal(machine, [...input, constants.END_OF_INPUT]);
function runMachine(machine, input, { endToken = constants.SpecialToken.EndOfInput } = {}) {
const branches = runMachineInternal(machine, [...input, endToken]);
return selectBestState(input, branches.map(({ state }) => {

@@ -375,7 +315,12 @@ return state;

function isTerminalNode(node) {
return node === constants.NODE_SUCCESS || node === constants.NODE_ERRORED;
return node === constants.NodeType.SuccessNode || node === constants.NodeType.ErrorNode;
}
function cloneTransition(input, offset = 0) {
const to = !isTerminalNode(input.to)
? input.to >= constants.NodeType.CustomNode
? input.to + offset - constants.NodeType.CustomNode + 1
: input.to + offset
: input.to;
return {
to: !isTerminalNode(input.to) ? input.to > 2 ? input.to + offset - 2 : input.to + offset : input.to,
to,
reducer: input.reducer,

@@ -409,3 +354,3 @@ };

}
function execute(store, callback, state, segment) {
function execute(store, callback, state, segment, segmentIndex) {
// TypeScript's control flow can't properly narrow

@@ -415,21 +360,8 @@ // generic conditionals for some mysterious reason

const [name, ...args] = callback;
return store[name](state, segment, ...args);
return store[name](state, segment, segmentIndex, ...args);
}
else {
return store[callback](state, segment);
return store[callback](state, segment, segmentIndex);
}
}
function suggest(callback, state) {
const fn = Array.isArray(callback)
? tests[callback[0]]
: tests[callback];
// @ts-ignore
if (typeof fn.suggest === `undefined`)
return null;
const args = Array.isArray(callback)
? callback.slice(1)
: [];
// @ts-ignore
return fn.suggest(state, ...args);
}
const tests = {

@@ -445,15 +377,15 @@ always: () => {

},
isOption: (state, segment, name, hidden) => {
isOption: (state, segment, segmentIndex, name) => {
return !state.ignoreOptions && segment === name;
},
isBatchOption: (state, segment, names) => {
return !state.ignoreOptions && constants.BATCH_REGEX.test(segment) && [...segment.slice(1)].every(name => names.includes(`-${name}`));
isBatchOption: (state, segment, segmentIndex, names) => {
return !state.ignoreOptions && constants.BATCH_REGEX.test(segment) && [...segment.slice(1)].every(name => names.has(`-${name}`));
},
isBoundOption: (state, segment, names, options) => {
isBoundOption: (state, segment, segmentIndex, names, options) => {
const optionParsing = segment.match(constants.BINDING_REGEX);
return !state.ignoreOptions && !!optionParsing && constants.OPTION_REGEX.test(optionParsing[1]) && names.includes(optionParsing[1])
return !state.ignoreOptions && !!optionParsing && constants.OPTION_REGEX.test(optionParsing[1]) && names.has(optionParsing[1])
// Disallow bound options with no arguments (i.e. booleans)
&& options.filter(opt => opt.names.includes(optionParsing[1])).every(opt => opt.allowBinding);
&& options.filter(opt => opt.nameSet.includes(optionParsing[1])).every(opt => opt.allowBinding);
},
isNegatedOption: (state, segment, name) => {
isNegatedOption: (state, segment, segmentIndex, name) => {
return !state.ignoreOptions && segment === `--no-${name.slice(2)}`;

@@ -464,4 +396,4 @@ },

},
isUnsupportedOption: (state, segment, names) => {
return !state.ignoreOptions && segment.startsWith(`-`) && constants.OPTION_REGEX.test(segment) && !names.includes(segment);
isUnsupportedOption: (state, segment, segmentIndex, names) => {
return !state.ignoreOptions && segment.startsWith(`-`) && constants.OPTION_REGEX.test(segment) && !names.has(segment);
},

@@ -472,53 +404,79 @@ isInvalidOption: (state, segment) => {

};
// @ts-ignore
tests.isOption.suggest = (state, name, hidden = true) => {
return !hidden ? [name] : null;
};
const reducers = {
setCandidateState: (state, segment, candidateState) => {
setCandidateState: (state, segment, segmentIndex, candidateState) => {
return { ...state, ...candidateState };
},
setSelectedIndex: (state, segment, index) => {
setSelectedIndex: (state, segment, segmentIndex, index) => {
return { ...state, selectedIndex: index };
},
pushBatch: (state, segment) => {
return { ...state, options: state.options.concat([...segment.slice(1)].map(name => ({ name: `-${name}`, value: true }))) };
pushBatch: (state, segment, segmentIndex, names) => {
const options = state.options.slice();
const tokens = state.tokens.slice();
for (let t = 1; t < segment.length; ++t) {
const name = names.get(`-${segment[t]}`);
const slice = t === 1 ? [0, 2] : [t, t + 1];
options.push({ name, value: true });
tokens.push({ segmentIndex, type: `option`, option: name, slice });
}
return { ...state, options, tokens };
},
pushBound: (state, segment) => {
pushBound: (state, segment, segmentIndex) => {
const [, name, value] = segment.match(constants.BINDING_REGEX);
return { ...state, options: state.options.concat({ name, value }) };
const options = state.options.concat({ name, value });
const tokens = state.tokens.concat([
{ segmentIndex, type: `option`, slice: [0, name.length], option: name },
{ segmentIndex, type: `assign`, slice: [name.length, name.length + 1] },
{ segmentIndex, type: `value`, slice: [name.length + 1, name.length + value.length + 1] },
]);
return { ...state, options, tokens };
},
pushPath: (state, segment) => {
return { ...state, path: state.path.concat(segment) };
pushPath: (state, segment, segmentIndex) => {
const path = state.path.concat(segment);
const tokens = state.tokens.concat({ segmentIndex, type: `path` });
return { ...state, path, tokens };
},
pushPositional: (state, segment) => {
return { ...state, positionals: state.positionals.concat({ value: segment, extra: false }) };
pushPositional: (state, segment, segmentIndex) => {
const positionals = state.positionals.concat({ value: segment, extra: false });
const tokens = state.tokens.concat({ segmentIndex, type: `positional` });
return { ...state, positionals, tokens };
},
pushExtra: (state, segment) => {
return { ...state, positionals: state.positionals.concat({ value: segment, extra: true }) };
pushExtra: (state, segment, segmentIndex) => {
const positionals = state.positionals.concat({ value: segment, extra: true });
const tokens = state.tokens.concat({ segmentIndex, type: `positional` });
return { ...state, positionals, tokens };
},
pushExtraNoLimits: (state, segment) => {
return { ...state, positionals: state.positionals.concat({ value: segment, extra: NoLimits }) };
pushExtraNoLimits: (state, segment, segmentIndex) => {
const positionals = state.positionals.concat({ value: segment, extra: NoLimits });
const tokens = state.tokens.concat({ segmentIndex, type: `positional` });
return { ...state, positionals, tokens };
},
pushTrue: (state, segment, name = segment) => {
return { ...state, options: state.options.concat({ name: segment, value: true }) };
pushTrue: (state, segment, segmentIndex, name) => {
const options = state.options.concat({ name, value: true });
const tokens = state.tokens.concat({ segmentIndex, type: `option`, option: name });
return { ...state, options, tokens };
},
pushFalse: (state, segment, name = segment) => {
return { ...state, options: state.options.concat({ name, value: false }) };
pushFalse: (state, segment, segmentIndex, name) => {
const options = state.options.concat({ name, value: false });
const tokens = state.tokens.concat({ segmentIndex, type: `option`, option: name });
return { ...state, options, tokens };
},
pushUndefined: (state, segment) => {
return { ...state, options: state.options.concat({ name: segment, value: undefined }) };
pushUndefined: (state, segment, segmentIndex, name) => {
const options = state.options.concat({ name: segment, value: undefined });
const tokens = state.tokens.concat({ segmentIndex, type: `option`, option: segment });
return { ...state, options, tokens };
},
pushStringValue: (state, segment) => {
pushStringValue: (state, segment, segmentIndex) => {
var _a;
const copy = { ...state, options: [...state.options] };
const lastOption = state.options[state.options.length - 1];
const options = state.options.slice();
const tokens = state.tokens.concat({ segmentIndex, type: `value` });
lastOption.value = ((_a = lastOption.value) !== null && _a !== void 0 ? _a : []).concat([segment]);
return copy;
return { ...state, options, tokens };
},
setStringValue: (state, segment) => {
const copy = { ...state, options: [...state.options] };
setStringValue: (state, segment, segmentIndex) => {
const lastOption = state.options[state.options.length - 1];
const options = state.options.slice();
const tokens = state.tokens.concat({ segmentIndex, type: `value` });
lastOption.value = segment;
return copy;
return { ...state, options, tokens };
},

@@ -528,3 +486,3 @@ inhibateOptions: (state) => {

},
useHelp: (state, segment, command) => {
useHelp: (state, segment, segmentIndex, command) => {
const [, /* name */ , index] = segment.match(constants.HELP_REGEX);

@@ -538,4 +496,4 @@ if (typeof index !== `undefined`) {

},
setError: (state, segment, errorMessage) => {
if (segment === constants.END_OF_INPUT) {
setError: (state, segment, segmentIndex, errorMessage) => {
if (segment === constants.SpecialToken.EndOfInput || segment === constants.SpecialToken.EndOfPartialInput) {
return { ...state, errorMessage: `${errorMessage}.` };

@@ -556,3 +514,3 @@ }

constructor(cliIndex, cliOpts) {
this.allOptionNames = [];
this.allOptionNames = new Map();
this.arity = { leading: [], trailing: [], extra: [], proxy: false };

@@ -598,3 +556,3 @@ this.options = [];

}
addOption({ names, description, arity = 0, hidden = false, required = false, allowBinding = true }) {
addOption({ names: nameSet, description, arity = 0, hidden = false, required = false, allowBinding = true }) {
if (!allowBinding && arity > 1)

@@ -606,4 +564,8 @@ throw new Error(`The arity cannot be higher than 1 when the option only supports the --arg=value syntax`);

throw new Error(`The arity must be positive, got ${arity}`);
this.allOptionNames.push(...names);
this.options.push({ names, description, arity, hidden, required, allowBinding });
const preferredName = nameSet.reduce((longestName, name) => {
return name.length > longestName.length ? name : longestName;
}, ``);
for (const name of nameSet)
this.allOptionNames.set(name, preferredName);
this.options.push({ preferredName, nameSet, description, arity, hidden, required, allowBinding });
}

@@ -619,3 +581,3 @@ setContext(context) {

if (detailed) {
for (const { names, arity, hidden, description, required } of this.options) {
for (const { preferredName, nameSet, arity, hidden, description, required } of this.options) {
if (hidden)

@@ -626,5 +588,5 @@ continue;

args.push(` #${t}`);
const definition = `${names.join(`,`)}${args.join(``)}`;
const definition = `${nameSet.join(`,`)}${args.join(``)}`;
if (!inlineOptions && description) {
detailedOptionList.push({ definition, description, required });
detailedOptionList.push({ preferredName, nameSet, definition, description, required });
}

@@ -649,9 +611,9 @@ else {

const machine = makeStateMachine();
let firstNode = constants.NODE_INITIAL;
let firstNode = constants.NodeType.InitialNode;
const candidateUsage = this.usage().usage;
const requiredOptions = this.options
.filter(opt => opt.required)
.map(opt => opt.names);
.map(opt => opt.nameSet);
firstNode = injectNode(machine, makeNode());
registerStatic(machine, constants.NODE_INITIAL, constants.START_OF_INPUT, firstNode, [`setCandidateState`, { candidateUsage, requiredOptions }]);
registerStatic(machine, constants.NodeType.InitialNode, constants.SpecialToken.StartOfInput, firstNode, [`setCandidateState`, { candidateUsage, requiredOptions }]);
const positionalArgument = this.arity.proxy

@@ -683,7 +645,9 @@ ? `always`

registerDynamic(machine, helpNode, `always`, helpNode, `pushExtra`);
registerStatic(machine, helpNode, constants.END_OF_INPUT, constants.NODE_SUCCESS, [`setSelectedIndex`, constants.HELP_COMMAND_INDEX]);
registerStatic(machine, helpNode, constants.SpecialToken.EndOfInput, constants.NodeType.SuccessNode, [`setSelectedIndex`, constants.HELP_COMMAND_INDEX]);
this.registerOptions(machine, lastPathNode);
}
if (this.arity.leading.length > 0)
registerStatic(machine, lastPathNode, constants.END_OF_INPUT, constants.NODE_ERRORED, [`setError`, `Not enough positional arguments`]);
if (this.arity.leading.length > 0) {
registerStatic(machine, lastPathNode, constants.SpecialToken.EndOfInput, constants.NodeType.ErrorNode, [`setError`, `Not enough positional arguments`]);
registerStatic(machine, lastPathNode, constants.SpecialToken.EndOfPartialInput, constants.NodeType.SuccessNode, [`setSelectedIndex`, this.cliIndex]);
}
let lastLeadingNode = lastPathNode;

@@ -694,4 +658,6 @@ for (let t = 0; t < this.arity.leading.length; ++t) {

this.registerOptions(machine, nextLeadingNode);
if (this.arity.trailing.length > 0 || t + 1 !== this.arity.leading.length)
registerStatic(machine, nextLeadingNode, constants.END_OF_INPUT, constants.NODE_ERRORED, [`setError`, `Not enough positional arguments`]);
if (this.arity.trailing.length > 0 || t + 1 !== this.arity.leading.length) {
registerStatic(machine, nextLeadingNode, constants.SpecialToken.EndOfInput, constants.NodeType.ErrorNode, [`setError`, `Not enough positional arguments`]);
registerStatic(machine, nextLeadingNode, constants.SpecialToken.EndOfPartialInput, constants.NodeType.SuccessNode, [`setSelectedIndex`, this.cliIndex]);
}
registerDynamic(machine, lastLeadingNode, `isNotOptionLike`, nextLeadingNode, `pushPositional`);

@@ -724,4 +690,6 @@ lastLeadingNode = nextLeadingNode;

}
if (this.arity.trailing.length > 0)
registerStatic(machine, lastExtraNode, constants.END_OF_INPUT, constants.NODE_ERRORED, [`setError`, `Not enough positional arguments`]);
if (this.arity.trailing.length > 0) {
registerStatic(machine, lastExtraNode, constants.SpecialToken.EndOfInput, constants.NodeType.ErrorNode, [`setError`, `Not enough positional arguments`]);
registerStatic(machine, lastExtraNode, constants.SpecialToken.EndOfPartialInput, constants.NodeType.SuccessNode, [`setSelectedIndex`, this.cliIndex]);
}
let lastTrailingNode = lastExtraNode;

@@ -732,9 +700,12 @@ for (let t = 0; t < this.arity.trailing.length; ++t) {

this.registerOptions(machine, nextTrailingNode);
if (t + 1 < this.arity.trailing.length)
registerStatic(machine, nextTrailingNode, constants.END_OF_INPUT, constants.NODE_ERRORED, [`setError`, `Not enough positional arguments`]);
if (t + 1 < this.arity.trailing.length) {
registerStatic(machine, nextTrailingNode, constants.SpecialToken.EndOfInput, constants.NodeType.ErrorNode, [`setError`, `Not enough positional arguments`]);
registerStatic(machine, nextTrailingNode, constants.SpecialToken.EndOfPartialInput, constants.NodeType.SuccessNode, [`setSelectedIndex`, this.cliIndex]);
}
registerDynamic(machine, lastTrailingNode, `isNotOptionLike`, nextTrailingNode, `pushPositional`);
lastTrailingNode = nextTrailingNode;
}
registerDynamic(machine, lastTrailingNode, positionalArgument, constants.NODE_ERRORED, [`setError`, `Extraneous positional argument`]);
registerStatic(machine, lastTrailingNode, constants.END_OF_INPUT, constants.NODE_SUCCESS, [`setSelectedIndex`, this.cliIndex]);
registerDynamic(machine, lastTrailingNode, positionalArgument, constants.NodeType.ErrorNode, [`setError`, `Extraneous positional argument`]);
registerStatic(machine, lastTrailingNode, constants.SpecialToken.EndOfInput, constants.NodeType.SuccessNode, [`setSelectedIndex`, this.cliIndex]);
registerStatic(machine, lastTrailingNode, constants.SpecialToken.EndOfPartialInput, constants.NodeType.SuccessNode, [`setSelectedIndex`, this.cliIndex]);
}

@@ -748,15 +719,12 @@ return {

registerDynamic(machine, node, [`isOption`, `--`], node, `inhibateOptions`);
registerDynamic(machine, node, [`isBatchOption`, this.allOptionNames], node, `pushBatch`);
registerDynamic(machine, node, [`isBatchOption`, this.allOptionNames], node, [`pushBatch`, this.allOptionNames]);
registerDynamic(machine, node, [`isBoundOption`, this.allOptionNames, this.options], node, `pushBound`);
registerDynamic(machine, node, [`isUnsupportedOption`, this.allOptionNames], constants.NODE_ERRORED, [`setError`, `Unsupported option name`]);
registerDynamic(machine, node, [`isInvalidOption`], constants.NODE_ERRORED, [`setError`, `Invalid option name`]);
registerDynamic(machine, node, [`isUnsupportedOption`, this.allOptionNames], constants.NodeType.ErrorNode, [`setError`, `Unsupported option name`]);
registerDynamic(machine, node, [`isInvalidOption`], constants.NodeType.ErrorNode, [`setError`, `Invalid option name`]);
for (const option of this.options) {
const longestName = option.names.reduce((longestName, name) => {
return name.length > longestName.length ? name : longestName;
}, ``);
if (option.arity === 0) {
for (const name of option.names) {
registerDynamic(machine, node, [`isOption`, name, option.hidden || name !== longestName], node, `pushTrue`);
for (const name of option.nameSet) {
registerDynamic(machine, node, [`isOption`, name], node, [`pushTrue`, option.preferredName]);
if (name.startsWith(`--`) && !name.startsWith(`--no-`)) {
registerDynamic(machine, node, [`isNegatedOption`, name], node, [`pushFalse`, name]);
registerDynamic(machine, node, [`isNegatedOption`, name], node, [`pushFalse`, option.preferredName]);
}

@@ -769,4 +737,4 @@ }

// We register transitions from the starting node to this new node
for (const name of option.names)
registerDynamic(machine, node, [`isOption`, name, option.hidden || name !== longestName], lastNode, `pushUndefined`);
for (const name of option.nameSet)
registerDynamic(machine, node, [`isOption`, name], lastNode, [`pushUndefined`, option.preferredName]);
// For each argument, we inject a new node at the end and we

@@ -776,5 +744,6 @@ // register a transition from the current node to this new node

const nextNode = injectNode(machine, makeNode());
// We can provide better errors when another option or END_OF_INPUT is encountered
registerStatic(machine, lastNode, constants.END_OF_INPUT, constants.NODE_ERRORED, `setOptionArityError`);
registerDynamic(machine, lastNode, `isOptionLike`, constants.NODE_ERRORED, `setOptionArityError`);
// We can provide better errors when another option or EndOfInput is encountered
registerStatic(machine, lastNode, constants.SpecialToken.EndOfInput, constants.NodeType.ErrorNode, `setOptionArityError`);
registerStatic(machine, lastNode, constants.SpecialToken.EndOfPartialInput, constants.NodeType.ErrorNode, `setOptionArityError`);
registerDynamic(machine, lastNode, `isOptionLike`, constants.NodeType.ErrorNode, `setOptionArityError`);
// If the option has a single argument, no need to store it in an array

@@ -830,8 +799,8 @@ const action = option.arity === 1

contexts,
process: (input) => {
return runMachine(machine, input);
process: (input, { partial } = {}) => {
const endToken = partial
? constants.SpecialToken.EndOfPartialInput
: constants.SpecialToken.EndOfInput;
return runMachine(machine, input, { endToken });
},
suggest: (input, partial) => {
return suggestMachine(machine, input, partial);
},
};

@@ -862,4 +831,3 @@ }

exports.simplifyMachine = simplifyMachine;
exports.suggest = suggest;
exports.tests = tests;
exports.trimSmallerBranches = trimSmallerBranches;

@@ -57,3 +57,3 @@ 'use strict';

const whileRunning = (input) => `While running ${input.filter(token => {
return token !== constants.END_OF_INPUT;
return token !== constants.SpecialToken.EndOfInput && token !== constants.SpecialToken.EndOfPartialInput;
}).map(token => {

@@ -60,0 +60,0 @@ const json = JSON.stringify(token);

@@ -15,3 +15,3 @@ {

],
"version": "3.2.1",
"version": "4.0.0-rc.1",
"main": "lib/advanced/index",

@@ -18,0 +18,0 @@ "license": "MIT",

@@ -5,3 +5,3 @@ # <img src="./logo.svg" height="25" /> Clipanion

[![npm version](https://img.shields.io/npm/v/clipanion.svg)](https://yarnpkg.com/package/clipanion) [![Licence](https://img.shields.io/npm/l/clipanion.svg)](https://github.com/arcanis/clipanion#license-mit) [![Yarn](https://img.shields.io/badge/developed%20with-Yarn%202-blue)](https://github.com/yarnpkg/berry)
[![npm version](https://img.shields.io/npm/v/clipanion.svg)](https://yarnpkg.com/package/clipanion) [![Licence](https://img.shields.io/npm/l/clipanion.svg)](https://github.com/arcanis/clipanion#license-mit) [![Yarn](https://img.shields.io/github/package-json/packageManager/arcanis/clipanion)](https://github.com/yarnpkg/berry)

@@ -8,0 +8,0 @@ ## Installation

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc