Comparing version 2.0.0-rc.16 to 2.0.0
@@ -30,2 +30,3 @@ /// <reference types="node" /> | ||
readonly binaryVersion?: string; | ||
static from<Context extends BaseContext = BaseContext>(commandClasses: CommandClass<Context>[]): Cli<Context>; | ||
constructor({ binaryLabel, binaryName, binaryVersion }?: { | ||
@@ -32,0 +33,0 @@ binaryLabel?: string; |
@@ -19,2 +19,8 @@ "use strict"; | ||
} | ||
static from(commandClasses) { | ||
const cli = new Cli(); | ||
for (const commandClass of commandClasses) | ||
cli.register(commandClass); | ||
return cli; | ||
} | ||
register(commandClass) { | ||
@@ -195,5 +201,4 @@ const commandBuilder = this.builder.command(); | ||
result += `\n`; | ||
result += description; | ||
result += `\n`; | ||
result += example.replace(/^/m, ` `); | ||
result += format_1.formatMarkdownish(description, false); | ||
result += [].concat(example.replace(/^/m, ` ${chalk_1.default.bold(prefix)}${this.binaryName} `)).join(`\n`) + `\n`; | ||
} | ||
@@ -200,0 +205,0 @@ } |
@@ -26,2 +26,4 @@ import { CommandBuilder, RunState } from '../core'; | ||
private static registerTransformer; | ||
static addPath(...path: string[]): void; | ||
static addOption<Context extends BaseContext>(name: string, builder: (prototype: Command<Context>, propertyName: string) => void): void; | ||
/** | ||
@@ -28,0 +30,0 @@ * Wrap the specified command to be attached to the given path on the command line. |
@@ -33,2 +33,8 @@ "use strict"; | ||
} | ||
static addPath(...path) { | ||
this.Path(...path)(this.prototype, `execute`); | ||
} | ||
static addOption(name, builder) { | ||
builder(this.prototype, name); | ||
} | ||
/** | ||
@@ -35,0 +41,0 @@ * Wrap the specified command to be attached to the given path on the command line. |
@@ -8,2 +8,4 @@ export declare const NODE_INITIAL = 0; | ||
export declare const HELP_REGEX: RegExp; | ||
export declare const OPTION_REGEX: RegExp; | ||
export declare const BATCH_REGEX: RegExp; | ||
export declare const DEBUG: boolean; | ||
@@ -61,3 +63,3 @@ export declare function debug(str: string): void; | ||
to: number; | ||
reducer: "setCandidateUsage" | "setSelectedIndex" | "pushPath" | "pushPositional" | "pushExtra" | "pushBoolean" | "pushString" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | ["setCandidateUsage" | "setSelectedIndex" | "pushPath" | "pushPositional" | "pushExtra" | "pushBoolean" | "pushString" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError", ...any[]] | undefined; | ||
reducer: "setCandidateUsage" | "setSelectedIndex" | "pushBatch" | "pushPath" | "pushPositional" | "pushExtra" | "pushTrue" | "pushFalse" | "pushUndefined" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError" | ["setCandidateUsage" | "setSelectedIndex" | "pushBatch" | "pushPath" | "pushPositional" | "pushExtra" | "pushTrue" | "pushFalse" | "pushUndefined" | "setStringValue" | "inhibateOptions" | "useHelp" | "setError", ...any[]] | undefined; | ||
}; | ||
@@ -77,4 +79,7 @@ export declare function cloneNode(input: Node, offset?: number): Node; | ||
isOption: (state: RunState, segment: string, name: string) => boolean; | ||
isBatchOption: (state: RunState, segment: string, names: string[]) => boolean; | ||
isNegatedOption: (state: RunState, segment: string, name: string) => boolean; | ||
isHelp: (state: RunState, segment: string) => boolean; | ||
isUnsupportedOption: (state: RunState, segment: string, names: string[]) => boolean; | ||
isInvalidOption: (state: RunState, segment: string) => boolean; | ||
}; | ||
@@ -112,2 +117,17 @@ export declare const reducers: { | ||
}; | ||
pushBatch: (state: RunState, segment: string) => { | ||
options: { | ||
name: string; | ||
value: any; | ||
}[]; | ||
candidateUsage: string | null; | ||
errorMessage: string | null; | ||
ignoreOptions: boolean; | ||
path: string[]; | ||
positionals: { | ||
value: string; | ||
extra: boolean; | ||
}[]; | ||
selectedIndex: number | null; | ||
}; | ||
pushPath: (state: RunState, segment: string) => { | ||
@@ -158,3 +178,3 @@ path: string[]; | ||
}; | ||
pushBoolean: (state: RunState, segment: string) => { | ||
pushTrue: (state: RunState, segment: string, name?: string) => { | ||
options: { | ||
@@ -174,3 +194,3 @@ name: string; | ||
}; | ||
pushString: (state: RunState, segment: string) => { | ||
pushFalse: (state: RunState, segment: string, name?: string) => { | ||
options: { | ||
@@ -190,2 +210,17 @@ name: string; | ||
}; | ||
pushUndefined: (state: RunState, segment: string) => { | ||
options: { | ||
name: string; | ||
value: any; | ||
}[]; | ||
candidateUsage: string | null; | ||
errorMessage: string | null; | ||
ignoreOptions: boolean; | ||
path: string[]; | ||
positionals: { | ||
value: string; | ||
extra: boolean; | ||
}[]; | ||
selectedIndex: number | null; | ||
}; | ||
setStringValue: (state: RunState, segment: string) => { | ||
@@ -192,0 +227,0 @@ options: { |
@@ -18,2 +18,4 @@ "use strict"; | ||
exports.HELP_REGEX = /^(-h|--help)(?:=([0-9]+))?$/; | ||
exports.OPTION_REGEX = /^(--[a-z]+(-[a-z]+)*|-[a-zA-Z]+)$/; | ||
exports.BATCH_REGEX = /^-[a-zA-Z]{2,}$/; | ||
// ------------------------------------------------------------------------ | ||
@@ -145,6 +147,11 @@ exports.DEBUG = process.env.DEBUG_CLI === `1`; | ||
} | ||
if (nextBranches.length === 0) { | ||
throw new errors.UnknownSyntaxError(branches.filter(({ node }) => { | ||
return node !== exports.NODE_ERRORED; | ||
}).map(({ state }) => { | ||
return { usage: state.candidateUsage, reason: null }; | ||
})); | ||
} | ||
if (nextBranches.every(({ node }) => node === exports.NODE_ERRORED)) { | ||
throw new errors.UnknownSyntaxError(nextBranches.filter(({ state }) => { | ||
return state.candidateUsage !== null; | ||
}).map(({ state }) => { | ||
throw new errors.UnknownSyntaxError(nextBranches.map(({ state }) => { | ||
return { usage: state.candidateUsage, reason: state.errorMessage }; | ||
@@ -303,2 +310,8 @@ })); | ||
}, | ||
isBatchOption: (state, segment, names) => { | ||
return !state.ignoreOptions && exports.BATCH_REGEX.test(segment) && [...segment.slice(1)].every(name => names.includes(`-${name}`)); | ||
}, | ||
isNegatedOption: (state, segment, name) => { | ||
return !state.ignoreOptions && segment === `--no-${name.slice(2)}`; | ||
}, | ||
isHelp: (state, segment) => { | ||
@@ -308,4 +321,7 @@ return !state.ignoreOptions && exports.HELP_REGEX.test(segment); | ||
isUnsupportedOption: (state, segment, names) => { | ||
return !state.ignoreOptions && segment.startsWith(`-`) && !names.includes(segment); | ||
return !state.ignoreOptions && segment.startsWith(`-`) && exports.OPTION_REGEX.test(segment) && !names.includes(segment); | ||
}, | ||
isInvalidOption: (state, segment) => { | ||
return !state.ignoreOptions && segment.startsWith(`-`) && !exports.OPTION_REGEX.test(segment); | ||
}, | ||
}; | ||
@@ -319,2 +335,5 @@ exports.reducers = { | ||
}, | ||
pushBatch: (state, segment) => { | ||
return Object.assign({}, state, { options: state.options.concat([...segment.slice(1)].map(name => ({ name: `-${name}`, value: true }))) }); | ||
}, | ||
pushPath: (state, segment) => { | ||
@@ -329,6 +348,9 @@ return Object.assign({}, state, { path: state.path.concat(segment) }); | ||
}, | ||
pushBoolean: (state, segment) => { | ||
pushTrue: (state, segment, name = segment) => { | ||
return Object.assign({}, state, { options: state.options.concat({ name: segment, value: true }) }); | ||
}, | ||
pushString: (state, segment) => { | ||
pushFalse: (state, segment, name = segment) => { | ||
return Object.assign({}, state, { options: state.options.concat({ name, value: false }) }); | ||
}, | ||
pushUndefined: (state, segment) => { | ||
return Object.assign({}, state, { options: state.options.concat({ name: segment, value: undefined }) }); | ||
@@ -514,7 +536,12 @@ }, | ||
registerDynamic(machine, node, [`isOption`, `--`], node, `inhibateOptions`); | ||
registerDynamic(machine, node, [`isBatchOption`, this.allOptionNames], node, `pushBatch`); | ||
registerDynamic(machine, node, [`isUnsupportedOption`, this.allOptionNames], exports.NODE_ERRORED, [`setError`, `Unsupported option name`]); | ||
registerDynamic(machine, node, [`isInvalidOption`], exports.NODE_ERRORED, [`setError`, `Invalid option name`]); | ||
for (const option of this.options) { | ||
if (option.arity === 0) { | ||
for (const name of option.names) { | ||
registerDynamic(machine, node, [`isOption`, name], node, `pushBoolean`); | ||
registerDynamic(machine, node, [`isOption`, name], node, `pushTrue`); | ||
if (name.startsWith(`--`)) { | ||
registerDynamic(machine, node, [`isNegatedOption`, name], node, [`pushFalse`, name]); | ||
} | ||
} | ||
@@ -526,3 +553,3 @@ } | ||
for (const name of option.names) { | ||
registerDynamic(machine, node, [`isOption`, name], argNode, `pushString`); | ||
registerDynamic(machine, node, [`isOption`, name], argNode, `pushUndefined`); | ||
} | ||
@@ -529,0 +556,0 @@ } |
@@ -20,6 +20,10 @@ "use strict"; | ||
} | ||
else if (this.candidates.length === 1) { | ||
else if (this.candidates.length === 1 && this.candidates[0].reason !== null) { | ||
const [{ usage, reason }] = this.candidates; | ||
this.message = `${reason}\n\n$ ${usage}`; | ||
} | ||
else if (this.candidates.length === 1) { | ||
const [{ usage }] = this.candidates; | ||
this.message = `Command not found; did you mean:\n\n$ ${usage}`; | ||
} | ||
else { | ||
@@ -26,0 +30,0 @@ this.message = `Command not found; did you mean one of:\n\n${this.candidates.map(({ usage }, index) => { |
@@ -14,2 +14,4 @@ "use strict"; | ||
text = text.replace(/^\n+|\n+$/g, ``); | ||
// List items always end with at least two newlines (in order to not be collapsed) | ||
text = text.replace(/^-([^\n]*?)\n+/gm, `-$1\n\n`); | ||
// Single newlines are removed; larger than that are collapsed into one | ||
@@ -19,3 +21,3 @@ text = text.replace(/\n(\n)?\n*/g, `$1`); | ||
text = text.split(/\n/).map(function (paragraph) { | ||
// Does the paragraph starts with a bullet? | ||
// Does the paragraph starts with a list? | ||
let bulletMatch = paragraph.match(/^[*-][\t ]+(.*)/); | ||
@@ -22,0 +24,0 @@ if (!bulletMatch) |
{ | ||
"name": "clipanion", | ||
"version": "2.0.0-rc.16", | ||
"version": "2.0.0", | ||
"main": "lib/advanced", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
70905
1696
1