diff --git a/.gitignore b/.gitignore index 47267a0..06985cc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ node_modules /types /api-doc coverage +/mod.d.ts +/mod.js diff --git a/README.md b/README.md index 67c0b20..22978fd 100644 --- a/README.md +++ b/README.md @@ -281,9 +281,10 @@ import { cac } from 'cac' ### With Deno ```ts +// deno-types="https://unpkg.com/cac/mod.d.ts" import { cac } from 'https://unpkg.com/cac/mod.js' -// ... +const cli = cac('my-program') ``` ## Projects Using CAC diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..cf76294 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,191 @@ +/// +import { EventEmitter } from 'events'; + +interface OptionConfig { + default?: any; + type?: any[]; +} +declare class Option { + rawName: string; + description: string; + /** Option name */ + name: string; + /** Option name and aliases */ + names: string[]; + isBoolean?: boolean; + required?: boolean; + config: OptionConfig; + negated: boolean; + constructor(rawName: string, description: string, config?: OptionConfig); +} + +interface CommandArg { + required: boolean; + value: string; + variadic: boolean; +} +interface HelpSection { + title?: string; + body: string; +} +interface CommandConfig { + allowUnknownOptions?: boolean; + ignoreOptionDefaultValue?: boolean; +} +declare type HelpCallback = (sections: HelpSection[]) => void; +declare type CommandExample = ((bin: string) => string) | string; +declare class Command { + rawName: string; + description: string; + config: CommandConfig; + cli: CAC; + options: Option[]; + aliasNames: string[]; + name: string; + args: CommandArg[]; + commandAction?: (...args: any[]) => any; + usageText?: string; + versionNumber?: string; + examples: CommandExample[]; + helpCallback?: HelpCallback; + globalCommand?: GlobalCommand; + constructor(rawName: string, description: string, config: CommandConfig, cli: CAC); + usage(text: string): this; + allowUnknownOptions(): this; + ignoreOptionDefaultValue(): this; + version(version: string, customFlags?: string): this; + example(example: CommandExample): this; + /** + * Add a option for this command + * @param rawName Raw option name(s) + * @param description Option description + * @param config Option config + */ + option(rawName: string, description: string, config?: OptionConfig): this; + alias(name: string): this; + action(callback: (...args: any[]) => any): this; + /** + * Check if a command name is matched by this command + * @param name Command name + */ + isMatched(name: string): boolean; + get isDefaultCommand(): boolean; + get isGlobalCommand(): boolean; + /** + * Check if an option is registered in this command + * @param name Option name + */ + hasOption(name: string): Option | undefined; + outputHelp(): void; + outputVersion(): void; + checkRequiredArgs(): void; + /** + * Check if the parsed options contain any unknown options + * + * Exit and output error when true + */ + checkUnknownOptions(): void; + /** + * Check if the required string-type options exist + */ + checkOptionValue(): void; +} +declare class GlobalCommand extends Command { + constructor(cli: CAC); +} + +interface ParsedArgv { + args: ReadonlyArray; + options: { + [k: string]: any; + }; +} +declare class CAC extends EventEmitter { + /** The program name to display in help and version message */ + name: string; + commands: Command[]; + globalCommand: GlobalCommand; + matchedCommand?: Command; + matchedCommandName?: string; + /** + * Raw CLI arguments + */ + rawArgs: string[]; + /** + * Parsed CLI arguments + */ + args: ParsedArgv['args']; + /** + * Parsed CLI options, camelCased + */ + options: ParsedArgv['options']; + private showHelpOnExit; + private showVersionOnExit; + /** + * @param name The program name to display in help and version message + */ + constructor(name?: string); + /** + * Add a global usage text. + * + * This is not used by sub-commands. + */ + usage(text: string): this; + /** + * Add a sub-command + */ + command(rawName: string, description?: string, config?: CommandConfig): Command; + /** + * Add a global CLI option. + * + * Which is also applied to sub-commands. + */ + option(rawName: string, description: string, config?: OptionConfig): this; + /** + * Show help message when `-h, --help` flags appear. + * + */ + help(callback?: HelpCallback): this; + /** + * Show version number when `-v, --version` flags appear. + * + */ + version(version: string, customFlags?: string): this; + /** + * Add a global example. + * + * This example added here will not be used by sub-commands. + */ + example(example: CommandExample): this; + /** + * Output the corresponding help message + * When a sub-command is matched, output the help message for the command + * Otherwise output the global one. + * + */ + outputHelp(): void; + /** + * Output the version number. + * + */ + outputVersion(): void; + private setParsedInfo; + /** + * Parse argv + */ + parse(argv?: string[], { + /** Whether to run the action for matched command */ + run }?: { + run?: boolean | undefined; + }): ParsedArgv; + private mri; + runMatchedCommand(): any; +} + +/** + * @param name The program name to display in help and version message + */ +declare const cac: (name?: string) => CAC; + +export default cac; +export { cac }; diff --git a/dist/index.js b/dist/index.js index 6e77518..4e62a1b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -116,615 +116,488 @@ var lib = function (args, opts) { return out; }; -const removeBrackets = (v) => v.replace(/[<[].+/, '').trim(); +const removeBrackets = (v) => v.replace(/[<[].+/, "").trim(); const findAllBrackets = (v) => { - const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g; - const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g; - const res = []; - const parse = (match) => { - let variadic = false; - let value = match[1]; - if (value.startsWith('...')) { - value = value.slice(3); - variadic = true; - } - return { - required: match[0].startsWith('<'), - value, - variadic - }; + const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g; + const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g; + const res = []; + const parse = (match) => { + let variadic = false; + let value = match[1]; + if (value.startsWith("...")) { + value = value.slice(3); + variadic = true; + } + return { + required: match[0].startsWith("<"), + value, + variadic }; - let angledMatch; - while ((angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v))) { - res.push(parse(angledMatch)); - } - let squareMatch; - while ((squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v))) { - res.push(parse(squareMatch)); - } - return res; + }; + let angledMatch; + while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(angledMatch)); + } + let squareMatch; + while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) { + res.push(parse(squareMatch)); + } + return res; }; const getMriOptions = (options) => { - const result = { alias: {}, boolean: [] }; - for (const [index, option] of options.entries()) { - // We do not set default values in mri options - // Since its type (typeof) will be used to cast parsed arguments. - // Which mean `--foo foo` will be parsed as `{foo: true}` if we have `{default:{foo: true}}` - // Set alias - if (option.names.length > 1) { - result.alias[option.names[0]] = option.names.slice(1); - } - // Set boolean - if (option.isBoolean) { - if (option.negated) { - // For negated option - // We only set it to `boolean` type when there's no string-type option with the same name - const hasStringTypeOption = options.some((o, i) => { - return (i !== index && - o.names.some(name => option.names.includes(name)) && - typeof o.required === 'boolean'); - }); - if (!hasStringTypeOption) { - result.boolean.push(option.names[0]); - } - } - else { - result.boolean.push(option.names[0]); - } + const result = { + alias: {}, + boolean: [] + }; + for (const [index, option] of options.entries()) { + if (option.names.length > 1) { + result.alias[option.names[0]] = option.names.slice(1); + } + if (option.isBoolean) { + if (option.negated) { + const hasStringTypeOption = options.some((o, i) => { + return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean"; + }); + if (!hasStringTypeOption) { + result.boolean.push(option.names[0]); } + } else { + result.boolean.push(option.names[0]); + } } - return result; + } + return result; }; const findLongest = (arr) => { - return arr.sort((a, b) => { - return a.length > b.length ? -1 : 1; - })[0]; + return arr.sort((a, b) => { + return a.length > b.length ? -1 : 1; + })[0]; }; const padRight = (str, length) => { - return str.length >= length ? str : `${str}${' '.repeat(length - str.length)}`; + return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`; }; const camelcase = (input) => { - return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => { - return p1 + p2.toUpperCase(); - }); + return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => { + return p1 + p2.toUpperCase(); + }); }; const setDotProp = (obj, keys, val) => { - let i = 0; - let length = keys.length; - let t = obj; - let x; - for (; i < length; ++i) { - x = t[keys[i]]; - t = t[keys[i]] = - i === length - 1 - ? val - : x != null - ? x - : !!~keys[i + 1].indexOf('.') || !(+keys[i + 1] > -1) - ? {} - : []; - } + let i = 0; + let length = keys.length; + let t = obj; + let x; + for (; i < length; ++i) { + x = t[keys[i]]; + t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : []; + } }; const setByType = (obj, transforms) => { - for (const key of Object.keys(transforms)) { - const transform = transforms[key]; - if (transform.shouldTransform) { - obj[key] = Array.prototype.concat.call([], obj[key]); - if (typeof transform.transformFunction === 'function') { - obj[key] = obj[key].map(transform.transformFunction); - } - } - } + for (const key of Object.keys(transforms)) { + const transform = transforms[key]; + if (transform.shouldTransform) { + obj[key] = Array.prototype.concat.call([], obj[key]); + if (typeof transform.transformFunction === "function") { + obj[key] = obj[key].map(transform.transformFunction); + } + } + } }; const getFileName = (input) => { - const m = /([^\\\/]+)$/.exec(input); - return m ? m[1] : ''; + const m = /([^\\\/]+)$/.exec(input); + return m ? m[1] : ""; }; const camelcaseOptionName = (name) => { - // Camelcase the option name - // Don't camelcase anything after the dot `.` - return name - .split('.') - .map((v, i) => { - return i === 0 ? camelcase(v) : v; - }) - .join('.'); + return name.split(".").map((v, i) => { + return i === 0 ? camelcase(v) : v; + }).join("."); }; class CACError extends Error { - constructor(message) { - super(message); - this.name = this.constructor.name; - if (typeof Error.captureStackTrace === 'function') { - Error.captureStackTrace(this, this.constructor); - } - else { - this.stack = new Error(message).stack; - } - } + constructor(message) { + super(message); + this.name = this.constructor.name; + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = new Error(message).stack; + } + } } class Option { - constructor(rawName, description, config) { - this.rawName = rawName; - this.description = description; - this.config = Object.assign({}, config); - // You may use cli.option('--env.* [value]', 'desc') to denote a dot-nested option - rawName = rawName.replace(/\.\*/g, ''); - this.negated = false; - this.names = removeBrackets(rawName) - .split(',') - .map((v) => { - let name = v.trim().replace(/^-{1,2}/, ''); - if (name.startsWith('no-')) { - this.negated = true; - name = name.replace(/^no-/, ''); - } - return camelcaseOptionName(name); - }) - .sort((a, b) => (a.length > b.length ? 1 : -1)); // Sort names - // Use the longest name (last one) as actual option name - this.name = this.names[this.names.length - 1]; - if (this.negated) { - this.config.default = true; - } - if (rawName.includes('<')) { - this.required = true; - } - else if (rawName.includes('[')) { - this.required = false; - } - else { - // No arg needed, it's boolean flag - this.isBoolean = true; - } - } + constructor(rawName, description, config) { + this.rawName = rawName; + this.description = description; + this.config = Object.assign({}, config); + rawName = rawName.replace(/\.\*/g, ""); + this.negated = false; + this.names = removeBrackets(rawName).split(",").map((v) => { + let name = v.trim().replace(/^-{1,2}/, ""); + if (name.startsWith("no-")) { + this.negated = true; + name = name.replace(/^no-/, ""); + } + return camelcaseOptionName(name); + }).sort((a, b) => a.length > b.length ? 1 : -1); + this.name = this.names[this.names.length - 1]; + if (this.negated) { + this.config.default = true; + } + if (rawName.includes("<")) { + this.required = true; + } else if (rawName.includes("[")) { + this.required = false; + } else { + this.isBoolean = true; + } + } } -const deno = typeof window !== 'undefined' && window.Deno; -const denoScriptPath = deno && typeof window !== 'undefined' && window.location.pathname; -// Adds deno executable and script path to processArgs as "compatibility" layer for node -// See https://github.com/cacjs/cac/issues/69 -const processArgs = deno ? ['deno', denoScriptPath].concat(Deno.args) : process.argv; -const platformInfo = deno - ? `${Deno.build.os}-${Deno.build.arch} deno-${Deno.version.deno}` - : `${process.platform}-${process.arch} node-${process.version}`; +const deno = typeof window !== "undefined" && window.Deno; +const denoScriptPath = "__DENO_SCRIPT_PATH__"; +const processArgs = deno ? ["deno", denoScriptPath].concat(Deno.args) : process.argv; +const platformInfo = deno ? `${Deno.build.os}-${Deno.build.arch} deno-${Deno.version.deno}` : `${process.platform}-${process.arch} node-${process.version}`; class Command { - constructor(rawName, description, config = {}, cli) { - this.rawName = rawName; - this.description = description; - this.config = config; - this.cli = cli; - this.options = []; - this.aliasNames = []; - this.name = removeBrackets(rawName); - this.args = findAllBrackets(rawName); - this.examples = []; - } - usage(text) { - this.usageText = text; - return this; - } - allowUnknownOptions() { - this.config.allowUnknownOptions = true; - return this; - } - ignoreOptionDefaultValue() { - this.config.ignoreOptionDefaultValue = true; - return this; - } - version(version, customFlags = '-v, --version') { - this.versionNumber = version; - this.option(customFlags, 'Display version number'); - return this; - } - example(example) { - this.examples.push(example); - return this; - } - /** - * Add a option for this command - * @param rawName Raw option name(s) - * @param description Option description - * @param config Option config - */ - option(rawName, description, config) { - const option = new Option(rawName, description, config); - this.options.push(option); - return this; - } - alias(name) { - this.aliasNames.push(name); - return this; - } - action(callback) { - this.commandAction = callback; - return this; - } - /** - * Check if a command name is matched by this command - * @param name Command name - */ - isMatched(name) { - return this.name === name || this.aliasNames.includes(name); - } - get isDefaultCommand() { - return this.name === '' || this.aliasNames.includes('!'); - } - get isGlobalCommand() { - return this instanceof GlobalCommand; - } - /** - * Check if an option is registered in this command - * @param name Option name - */ - hasOption(name) { - name = name.split('.')[0]; - return this.options.find(option => { - return option.names.includes(name); - }); - } - outputHelp() { - const { name, commands } = this.cli; - const { versionNumber, options: globalOptions, helpCallback } = this.cli.globalCommand; - const sections = [ - { - body: `${name}${versionNumber ? ` v${versionNumber}` : ''}` - } - ]; - sections.push({ - title: 'Usage', - body: ` $ ${name} ${this.usageText || this.rawName}` - }); - const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0; - if (showCommands) { - const longestCommandName = findLongest(commands.map(command => command.rawName)); - sections.push({ - title: 'Commands', - body: commands - .map(command => { - return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`; - }) - .join('\n') - }); - sections.push({ - title: `For more info, run any command with the \`--help\` flag`, - body: commands - .map(command => ` $ ${name}${command.name === '' ? '' : ` ${command.name}`} --help`) - .join('\n') - }); - } - const options = this.isGlobalCommand - ? globalOptions - : [...this.options, ...(globalOptions || [])]; - if (options.length > 0) { - const longestOptionName = findLongest(options.map(option => option.rawName)); - sections.push({ - title: 'Options', - body: options - .map(option => { - return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === undefined - ? '' - : `(default: ${option.config.default})`}`; - }) - .join('\n') - }); - } - if (this.examples.length > 0) { - sections.push({ - title: 'Examples', - body: this.examples - .map(example => { - if (typeof example === 'function') { - return example(name); - } - return example; - }) - .join('\n') - }); - } - if (helpCallback) { - helpCallback(sections); - } - console.log(sections - .map(section => { - return section.title - ? `${section.title}:\n${section.body}` - : section.body; - }) - .join('\n\n')); - } - outputVersion() { - const { name } = this.cli; - const { versionNumber } = this.cli.globalCommand; - if (versionNumber) { - console.log(`${name}/${versionNumber} ${platformInfo}`); - } - } - checkRequiredArgs() { - const minimalArgsCount = this.args.filter(arg => arg.required).length; - if (this.cli.args.length < minimalArgsCount) { - throw new CACError(`missing required args for command \`${this.rawName}\``); - } - } - /** - * Check if the parsed options contain any unknown options - * - * Exit and output error when true - */ - checkUnknownOptions() { - const { options, globalCommand } = this.cli; - if (!this.config.allowUnknownOptions) { - for (const name of Object.keys(options)) { - if (name !== '--' && - !this.hasOption(name) && - !globalCommand.hasOption(name)) { - throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``); - } - } - } - } - /** - * Check if the required string-type options exist - */ - checkOptionValue() { - const { options: parsedOptions, globalCommand } = this.cli; - const options = [...globalCommand.options, ...this.options]; - for (const option of options) { - const value = parsedOptions[option.name.split('.')[0]]; - // Check required option value - if (option.required) { - const hasNegated = options.some(o => o.negated && o.names.includes(option.name)); - if (value === true || (value === false && !hasNegated)) { - throw new CACError(`option \`${option.rawName}\` value is missing`); - } - } - } - } + constructor(rawName, description, config = {}, cli) { + this.rawName = rawName; + this.description = description; + this.config = config; + this.cli = cli; + this.options = []; + this.aliasNames = []; + this.name = removeBrackets(rawName); + this.args = findAllBrackets(rawName); + this.examples = []; + } + usage(text) { + this.usageText = text; + return this; + } + allowUnknownOptions() { + this.config.allowUnknownOptions = true; + return this; + } + ignoreOptionDefaultValue() { + this.config.ignoreOptionDefaultValue = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.versionNumber = version; + this.option(customFlags, "Display version number"); + return this; + } + example(example) { + this.examples.push(example); + return this; + } + option(rawName, description, config) { + const option = new Option(rawName, description, config); + this.options.push(option); + return this; + } + alias(name) { + this.aliasNames.push(name); + return this; + } + action(callback) { + this.commandAction = callback; + return this; + } + isMatched(name) { + return this.name === name || this.aliasNames.includes(name); + } + get isDefaultCommand() { + return this.name === "" || this.aliasNames.includes("!"); + } + get isGlobalCommand() { + return this instanceof GlobalCommand; + } + hasOption(name) { + name = name.split(".")[0]; + return this.options.find((option) => { + return option.names.includes(name); + }); + } + outputHelp() { + const {name, commands} = this.cli; + const {versionNumber, options: globalOptions, helpCallback} = this.cli.globalCommand; + const sections = [{ + body: `${name}${versionNumber ? ` v${versionNumber}` : ""}` + }]; + sections.push({ + title: "Usage", + body: ` $ ${name} ${this.usageText || this.rawName}` + }); + const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0; + if (showCommands) { + const longestCommandName = findLongest(commands.map((command) => command.rawName)); + sections.push({ + title: "Commands", + body: commands.map((command) => { + return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`; + }).join("\n") + }); + sections.push({ + title: `For more info, run any command with the \`--help\` flag`, + body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join("\n") + }); + } + const options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []]; + if (options.length > 0) { + const longestOptionName = findLongest(options.map((option) => option.rawName)); + sections.push({ + title: "Options", + body: options.map((option) => { + return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? "" : `(default: ${option.config.default})`}`; + }).join("\n") + }); + } + if (this.examples.length > 0) { + sections.push({ + title: "Examples", + body: this.examples.map((example) => { + if (typeof example === "function") { + return example(name); + } + return example; + }).join("\n") + }); + } + if (helpCallback) { + helpCallback(sections); + } + console.log(sections.map((section) => { + return section.title ? `${section.title}: +${section.body}` : section.body; + }).join("\n\n")); + } + outputVersion() { + const {name} = this.cli; + const {versionNumber} = this.cli.globalCommand; + if (versionNumber) { + console.log(`${name}/${versionNumber} ${platformInfo}`); + } + } + checkRequiredArgs() { + const minimalArgsCount = this.args.filter((arg) => arg.required).length; + if (this.cli.args.length < minimalArgsCount) { + throw new CACError(`missing required args for command \`${this.rawName}\``); + } + } + checkUnknownOptions() { + const {options, globalCommand} = this.cli; + if (!this.config.allowUnknownOptions) { + for (const name of Object.keys(options)) { + if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) { + throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``); + } + } + } + } + checkOptionValue() { + const {options: parsedOptions, globalCommand} = this.cli; + const options = [...globalCommand.options, ...this.options]; + for (const option of options) { + const value = parsedOptions[option.name.split(".")[0]]; + if (option.required) { + const hasNegated = options.some((o) => o.negated && o.names.includes(option.name)); + if (value === true || value === false && !hasNegated) { + throw new CACError(`option \`${option.rawName}\` value is missing`); + } + } + } + } } class GlobalCommand extends Command { - constructor(cli) { - super('@@global@@', '', {}, cli); - } + constructor(cli) { + super("@@global@@", "", {}, cli); + } } +let __assign = Object.assign; class CAC extends events.EventEmitter { - /** - * @param name The program name to display in help and version message - */ - constructor(name = '') { - super(); - this.name = name; - this.commands = []; - this.globalCommand = new GlobalCommand(this); - this.globalCommand.usage(' [options]'); - } - /** - * Add a global usage text. - * - * This is not used by sub-commands. - */ - usage(text) { - this.globalCommand.usage(text); - return this; - } - /** - * Add a sub-command - */ - command(rawName, description, config) { - const command = new Command(rawName, description || '', config, this); - command.globalCommand = this.globalCommand; - this.commands.push(command); - return command; - } - /** - * Add a global CLI option. - * - * Which is also applied to sub-commands. - */ - option(rawName, description, config) { - this.globalCommand.option(rawName, description, config); - return this; - } - /** - * Show help message when `-h, --help` flags appear. - * - */ - help(callback) { - this.globalCommand.option('-h, --help', 'Display this message'); - this.globalCommand.helpCallback = callback; - this.showHelpOnExit = true; - return this; - } - /** - * Show version number when `-v, --version` flags appear. - * - */ - version(version, customFlags = '-v, --version') { - this.globalCommand.version(version, customFlags); - this.showVersionOnExit = true; - return this; - } - /** - * Add a global example. - * - * This example added here will not be used by sub-commands. - */ - example(example) { - this.globalCommand.example(example); - return this; - } - /** - * Output the corresponding help message - * When a sub-command is matched, output the help message for the command - * Otherwise output the global one. - * - */ - outputHelp() { - if (this.matchedCommand) { - this.matchedCommand.outputHelp(); - } - else { - this.globalCommand.outputHelp(); - } - } - /** - * Output the version number. - * - */ - outputVersion() { - this.globalCommand.outputVersion(); - } - setParsedInfo({ args, options }, matchedCommand, matchedCommandName) { - this.args = args; - this.options = options; - if (matchedCommand) { - this.matchedCommand = matchedCommand; - } - if (matchedCommandName) { - this.matchedCommandName = matchedCommandName; - } - return this; - } - /** - * Parse argv - */ - parse(argv = processArgs, { - /** Whether to run the action for matched command */ - run = true } = {}) { - this.rawArgs = argv; - if (!this.name) { - this.name = argv[1] ? getFileName(argv[1]) : 'cli'; - } - let shouldParse = true; - // Search sub-commands - for (const command of this.commands) { - const parsed = this.mri(argv.slice(2), command); - const commandName = parsed.args[0]; - if (command.isMatched(commandName)) { - shouldParse = false; - const parsedInfo = Object.assign({}, parsed, { args: parsed.args.slice(1) }); - this.setParsedInfo(parsedInfo, command, commandName); - this.emit(`command:${commandName}`, command); - } - } - if (shouldParse) { - // Search the default command - for (const command of this.commands) { - if (command.name === '') { - shouldParse = false; - const parsed = this.mri(argv.slice(2), command); - this.setParsedInfo(parsed, command); - this.emit(`command:!`, command); - } - } - } - if (shouldParse) { - const parsed = this.mri(argv.slice(2)); - this.setParsedInfo(parsed); - } - if (this.options.help && this.showHelpOnExit) { - this.outputHelp(); - run = false; - } - if (this.options.version && this.showVersionOnExit) { - this.outputVersion(); - run = false; - } - const parsedArgv = { args: this.args, options: this.options }; - if (run) { - this.runMatchedCommand(); - } - if (!this.matchedCommand && this.args[0]) { - this.emit('command:*'); - } - return parsedArgv; - } - mri(argv, - /** Matched command */ command) { - // All added options - const cliOptions = [ - ...this.globalCommand.options, - ...(command ? command.options : []) - ]; - const mriOptions = getMriOptions(cliOptions); - // Extract everything after `--` since mri doesn't support it - let argsAfterDoubleDashes = []; - const doubleDashesIndex = argv.indexOf('--'); - if (doubleDashesIndex > -1) { - argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1); - argv = argv.slice(0, doubleDashesIndex); - } - let parsed = lib(argv, mriOptions); - parsed = Object.keys(parsed).reduce((res, name) => { - return Object.assign({}, res, { [camelcaseOptionName(name)]: parsed[name] }); - }, { _: [] }); - const args = parsed._; - delete parsed._; - const options = { - '--': argsAfterDoubleDashes - }; - // Set option default value - const ignoreDefault = command && command.config.ignoreOptionDefaultValue - ? command.config.ignoreOptionDefaultValue - : this.globalCommand.config.ignoreOptionDefaultValue; - let transforms = Object.create(null); - for (const cliOption of cliOptions) { - if (!ignoreDefault && cliOption.config.default !== undefined) { - for (const name of cliOption.names) { - options[name] = cliOption.config.default; - } - } - // If options type is defined - if (Array.isArray(cliOption.config.type)) { - if (transforms[cliOption.name] === undefined) { - transforms[cliOption.name] = Object.create(null); - transforms[cliOption.name]['shouldTransform'] = true; - transforms[cliOption.name]['transformFunction'] = - cliOption.config.type[0]; - } - } - } - // Set dot nested option values - for (const key of Object.keys(parsed)) { - const keys = key.split('.'); - setDotProp(options, keys, parsed[key]); - setByType(options, transforms); - } - return { - args, - options - }; - } - runMatchedCommand() { - const { args, options, matchedCommand: command } = this; - if (!command || !command.commandAction) - return; - command.checkUnknownOptions(); - command.checkOptionValue(); - command.checkRequiredArgs(); - const actionArgs = []; - command.args.forEach((arg, index) => { - if (arg.variadic) { - actionArgs.push(args.slice(index)); - } - else { - actionArgs.push(args[index]); - } + constructor(name = "") { + super(); + this.name = name; + this.commands = []; + this.globalCommand = new GlobalCommand(this); + this.globalCommand.usage(" [options]"); + } + usage(text) { + this.globalCommand.usage(text); + return this; + } + command(rawName, description, config) { + const command = new Command(rawName, description || "", config, this); + command.globalCommand = this.globalCommand; + this.commands.push(command); + return command; + } + option(rawName, description, config) { + this.globalCommand.option(rawName, description, config); + return this; + } + help(callback) { + this.globalCommand.option("-h, --help", "Display this message"); + this.globalCommand.helpCallback = callback; + this.showHelpOnExit = true; + return this; + } + version(version, customFlags = "-v, --version") { + this.globalCommand.version(version, customFlags); + this.showVersionOnExit = true; + return this; + } + example(example) { + this.globalCommand.example(example); + return this; + } + outputHelp() { + if (this.matchedCommand) { + this.matchedCommand.outputHelp(); + } else { + this.globalCommand.outputHelp(); + } + } + outputVersion() { + this.globalCommand.outputVersion(); + } + setParsedInfo({args, options}, matchedCommand, matchedCommandName) { + this.args = args; + this.options = options; + if (matchedCommand) { + this.matchedCommand = matchedCommand; + } + if (matchedCommandName) { + this.matchedCommandName = matchedCommandName; + } + return this; + } + parse(argv = processArgs, {run = true} = {}) { + this.rawArgs = argv; + if (!this.name) { + this.name = argv[1] ? getFileName(argv[1]) : "cli"; + } + let shouldParse = true; + for (const command of this.commands) { + const parsed = this.mri(argv.slice(2), command); + const commandName = parsed.args[0]; + if (command.isMatched(commandName)) { + shouldParse = false; + const parsedInfo = __assign(__assign({}, parsed), { + args: parsed.args.slice(1) }); - actionArgs.push(options); - return command.commandAction.apply(this, actionArgs); - } + this.setParsedInfo(parsedInfo, command, commandName); + this.emit(`command:${commandName}`, command); + } + } + if (shouldParse) { + for (const command of this.commands) { + if (command.name === "") { + shouldParse = false; + const parsed = this.mri(argv.slice(2), command); + this.setParsedInfo(parsed, command); + this.emit(`command:!`, command); + } + } + } + if (shouldParse) { + const parsed = this.mri(argv.slice(2)); + this.setParsedInfo(parsed); + } + if (this.options.help && this.showHelpOnExit) { + this.outputHelp(); + run = false; + } + if (this.options.version && this.showVersionOnExit) { + this.outputVersion(); + run = false; + } + const parsedArgv = { + args: this.args, + options: this.options + }; + if (run) { + this.runMatchedCommand(); + } + if (!this.matchedCommand && this.args[0]) { + this.emit("command:*"); + } + return parsedArgv; + } + mri(argv, command) { + const cliOptions = [...this.globalCommand.options, ...command ? command.options : []]; + const mriOptions = getMriOptions(cliOptions); + let argsAfterDoubleDashes = []; + const doubleDashesIndex = argv.indexOf("--"); + if (doubleDashesIndex > -1) { + argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1); + argv = argv.slice(0, doubleDashesIndex); + } + let parsed = lib(argv, mriOptions); + parsed = Object.keys(parsed).reduce((res, name) => { + return __assign(__assign({}, res), { + [camelcaseOptionName(name)]: parsed[name] + }); + }, { + _: [] + }); + const args = parsed._; + delete parsed._; + const options = { + "--": argsAfterDoubleDashes + }; + const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue; + let transforms = Object.create(null); + for (const cliOption of cliOptions) { + if (!ignoreDefault && cliOption.config.default !== void 0) { + for (const name of cliOption.names) { + options[name] = cliOption.config.default; + } + } + if (Array.isArray(cliOption.config.type)) { + if (transforms[cliOption.name] === void 0) { + transforms[cliOption.name] = Object.create(null); + transforms[cliOption.name]["shouldTransform"] = true; + transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0]; + } + } + } + for (const key of Object.keys(parsed)) { + const keys = key.split("."); + setDotProp(options, keys, parsed[key]); + setByType(options, transforms); + } + return { + args, + options + }; + } + runMatchedCommand() { + const {args, options, matchedCommand: command} = this; + if (!command || !command.commandAction) + return; + command.checkUnknownOptions(); + command.checkOptionValue(); + command.checkRequiredArgs(); + const actionArgs = []; + command.args.forEach((arg, index) => { + if (arg.variadic) { + actionArgs.push(args.slice(index)); + } else { + actionArgs.push(args[index]); + } + }); + actionArgs.push(options); + return command.commandAction.apply(this, actionArgs); + } } -/** - * @param name The program name to display in help and version message - */ -const cac = (name = '') => new CAC(name); -if (typeof module !== 'undefined') { - module.exports = cac; - module.exports.default = cac; - module.exports.cac = cac; +const cac = (name = "") => new CAC(name); +if (typeof module !== "undefined") { + module.exports = cac; + module.exports.default = cac; + module.exports.cac = cac; } exports.cac = cac; diff --git a/mod.js b/mod.js deleted file mode 100644 index 64bb35e..0000000 --- a/mod.js +++ /dev/null @@ -1,1154 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. - -var R = typeof Reflect === 'object' ? Reflect : null; -var ReflectApply = R && typeof R.apply === 'function' - ? R.apply - : function ReflectApply(target, receiver, args) { - return Function.prototype.apply.call(target, receiver, args); - }; - -var ReflectOwnKeys; -if (R && typeof R.ownKeys === 'function') { - ReflectOwnKeys = R.ownKeys; -} else if (Object.getOwnPropertySymbols) { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target) - .concat(Object.getOwnPropertySymbols(target)); - }; -} else { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target); - }; -} - -function ProcessEmitWarning(warning) { - if (console && console.warn) console.warn(warning); -} - -var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { - return value !== value; -}; - -function EventEmitter() { - EventEmitter.init.call(this); -} -var events = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._eventsCount = 0; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -var defaultMaxListeners = 10; - -Object.defineProperty(EventEmitter, 'defaultMaxListeners', { - enumerable: true, - get: function() { - return defaultMaxListeners; - }, - set: function(arg) { - if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { - throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); - } - defaultMaxListeners = arg; - } -}); - -EventEmitter.init = function() { - - if (this._events === undefined || - this._events === Object.getPrototypeOf(this)._events) { - this._events = Object.create(null); - this._eventsCount = 0; - } - - this._maxListeners = this._maxListeners || undefined; -}; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { - if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { - throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); - } - this._maxListeners = n; - return this; -}; - -function $getMaxListeners(that) { - if (that._maxListeners === undefined) - return EventEmitter.defaultMaxListeners; - return that._maxListeners; -} - -EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return $getMaxListeners(this); -}; - -EventEmitter.prototype.emit = function emit(type) { - var args = []; - for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); - var doError = (type === 'error'); - - var events = this._events; - if (events !== undefined) - doError = (doError && events.error === undefined); - else if (!doError) - return false; - - // If there is no 'error' event listener then throw. - if (doError) { - var er; - if (args.length > 0) - er = args[0]; - if (er instanceof Error) { - // Note: The comments on the `throw` lines are intentional, they show - // up in Node's output if this results in an unhandled exception. - throw er; // Unhandled 'error' event - } - // At least give some kind of context to the user - var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); - err.context = er; - throw err; // Unhandled 'error' event - } - - var handler = events[type]; - - if (handler === undefined) - return false; - - if (typeof handler === 'function') { - ReflectApply(handler, this, args); - } else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) - ReflectApply(listeners[i], this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } - - events = target._events; - if (events === undefined) { - events = target._events = Object.create(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener !== undefined) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (existing === undefined) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - // If we've already got an array, just append. - } else if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - - // Check for listener leak - m = $getMaxListeners(target); - if (m > 0 && existing.length > m && !existing.warned) { - existing.warned = true; - // No error code for this since it is a Warning - // eslint-disable-next-line no-restricted-syntax - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' ' + String(type) + ' listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - ProcessEmitWarning(w); - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - var args = []; - for (var i = 0; i < arguments.length; i++) args.push(arguments[i]); - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - ReflectApply(this.listener, this.target, args); - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = onceWrapper.bind(state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } - - events = this._events; - if (events === undefined) - return this; - - list = events[type]; - if (list === undefined) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = Object.create(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else { - spliceOne(list, position); - } - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener !== undefined) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (events === undefined) - return this; - - // not listening for removeListener, no need to emit - if (events.removeListener === undefined) { - if (arguments.length === 0) { - this._events = Object.create(null); - this._eventsCount = 0; - } else if (events[type] !== undefined) { - if (--this._eventsCount === 0) - this._events = Object.create(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = Object.keys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = Object.create(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners !== undefined) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (events === undefined) - return []; - - var evlistener = events[type]; - if (evlistener === undefined) - return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap ? - unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events !== undefined) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener !== undefined) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; -}; - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function spliceOne(list, index) { - for (; index + 1 < list.length; index++) - list[index] = list[index + 1]; - list.pop(); -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} -var events_1 = events.EventEmitter; - -function toArr(any) { - return any == null ? [] : Array.isArray(any) ? any : [any]; -} - -function toVal(out, key, val, opts) { - var x, old=out[key], nxt=( - !!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val)) - : typeof val === 'boolean' ? val - : !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val)) - : (x = +val,x * 0 === 0) ? x : val - ); - out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]); -} - -var lib = function (args, opts) { - args = args || []; - opts = opts || {}; - - var k, arr, arg, name, val, out={ _:[] }; - var i=0, j=0, idx=0, len=args.length; - - const alibi = opts.alias !== void 0; - const strict = opts.unknown !== void 0; - const defaults = opts.default !== void 0; - - opts.alias = opts.alias || {}; - opts.string = toArr(opts.string); - opts.boolean = toArr(opts.boolean); - - if (alibi) { - for (k in opts.alias) { - arr = opts.alias[k] = toArr(opts.alias[k]); - for (i=0; i < arr.length; i++) { - (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1); - } - } - } - - opts.boolean.forEach(key => { - opts.boolean = opts.boolean.concat(opts.alias[key] = opts.alias[key] || []); - }); - - opts.string.forEach(key => { - opts.string = opts.string.concat(opts.alias[key] = opts.alias[key] || []); - }); - - if (defaults) { - for (k in opts.default) { - opts.alias[k] = opts.alias[k] || []; - (opts[typeof opts.default[k]] || []).push(k); - } - } - - const keys = strict ? Object.keys(opts.alias) : []; - - for (i=0; i < len; i++) { - arg = args[i]; - - if (arg === '--') { - out._ = out._.concat(args.slice(++i)); - break; - } - - for (j=0; j < arg.length; j++) { - if (arg.charCodeAt(j) !== 45) break; // "-" - } - - if (j === 0) { - out._.push(arg); - } else if (arg.substring(j, j + 3) === 'no-') { - name = arg.substring(j + 3); - if (strict && !~keys.indexOf(name)) { - return opts.unknown(arg); - } - out[name] = false; - } else { - for (idx=j+1; idx < arg.length; idx++) { - if (arg.charCodeAt(idx) === 61) break; // "=" - } - - name = arg.substring(j, idx); - val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]); - arr = (j === 2 ? [name] : name); - - for (idx=0; idx < arr.length; idx++) { - name = arr[idx]; - if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name); - toVal(out, name, (idx + 1 < arr.length) || val, opts); - } - } - } - - if (defaults) { - for (k in opts.default) { - if (out[k] === void 0) { - out[k] = opts.default[k]; - } - } - } - - if (alibi) { - for (k in out) { - arr = opts.alias[k] || []; - while (arr.length > 0) { - out[arr.shift()] = out[k]; - } - } - } - - return out; -}; - -const removeBrackets = (v) => v.replace(/[<[].+/, '').trim(); -const findAllBrackets = (v) => { - const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g; - const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g; - const res = []; - const parse = (match) => { - let variadic = false; - let value = match[1]; - if (value.startsWith('...')) { - value = value.slice(3); - variadic = true; - } - return { - required: match[0].startsWith('<'), - value, - variadic - }; - }; - let angledMatch; - while ((angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v))) { - res.push(parse(angledMatch)); - } - let squareMatch; - while ((squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v))) { - res.push(parse(squareMatch)); - } - return res; -}; -const getMriOptions = (options) => { - const result = { alias: {}, boolean: [] }; - for (const [index, option] of options.entries()) { - // We do not set default values in mri options - // Since its type (typeof) will be used to cast parsed arguments. - // Which mean `--foo foo` will be parsed as `{foo: true}` if we have `{default:{foo: true}}` - // Set alias - if (option.names.length > 1) { - result.alias[option.names[0]] = option.names.slice(1); - } - // Set boolean - if (option.isBoolean) { - if (option.negated) { - // For negated option - // We only set it to `boolean` type when there's no string-type option with the same name - const hasStringTypeOption = options.some((o, i) => { - return (i !== index && - o.names.some(name => option.names.includes(name)) && - typeof o.required === 'boolean'); - }); - if (!hasStringTypeOption) { - result.boolean.push(option.names[0]); - } - } - else { - result.boolean.push(option.names[0]); - } - } - } - return result; -}; -const findLongest = (arr) => { - return arr.sort((a, b) => { - return a.length > b.length ? -1 : 1; - })[0]; -}; -const padRight = (str, length) => { - return str.length >= length ? str : `${str}${' '.repeat(length - str.length)}`; -}; -const camelcase = (input) => { - return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => { - return p1 + p2.toUpperCase(); - }); -}; -const setDotProp = (obj, keys, val) => { - let i = 0; - let length = keys.length; - let t = obj; - let x; - for (; i < length; ++i) { - x = t[keys[i]]; - t = t[keys[i]] = - i === length - 1 - ? val - : x != null - ? x - : !!~keys[i + 1].indexOf('.') || !(+keys[i + 1] > -1) - ? {} - : []; - } -}; -const setByType = (obj, transforms) => { - for (const key of Object.keys(transforms)) { - const transform = transforms[key]; - if (transform.shouldTransform) { - obj[key] = Array.prototype.concat.call([], obj[key]); - if (typeof transform.transformFunction === 'function') { - obj[key] = obj[key].map(transform.transformFunction); - } - } - } -}; -const getFileName = (input) => { - const m = /([^\\\/]+)$/.exec(input); - return m ? m[1] : ''; -}; -const camelcaseOptionName = (name) => { - // Camelcase the option name - // Don't camelcase anything after the dot `.` - return name - .split('.') - .map((v, i) => { - return i === 0 ? camelcase(v) : v; - }) - .join('.'); -}; -class CACError extends Error { - constructor(message) { - super(message); - this.name = this.constructor.name; - if (typeof Error.captureStackTrace === 'function') { - Error.captureStackTrace(this, this.constructor); - } - else { - this.stack = new Error(message).stack; - } - } -} - -class Option { - constructor(rawName, description, config) { - this.rawName = rawName; - this.description = description; - this.config = Object.assign({}, config); - // You may use cli.option('--env.* [value]', 'desc') to denote a dot-nested option - rawName = rawName.replace(/\.\*/g, ''); - this.negated = false; - this.names = removeBrackets(rawName) - .split(',') - .map((v) => { - let name = v.trim().replace(/^-{1,2}/, ''); - if (name.startsWith('no-')) { - this.negated = true; - name = name.replace(/^no-/, ''); - } - return camelcaseOptionName(name); - }) - .sort((a, b) => (a.length > b.length ? 1 : -1)); // Sort names - // Use the longest name (last one) as actual option name - this.name = this.names[this.names.length - 1]; - if (this.negated) { - this.config.default = true; - } - if (rawName.includes('<')) { - this.required = true; - } - else if (rawName.includes('[')) { - this.required = false; - } - else { - // No arg needed, it's boolean flag - this.isBoolean = true; - } - } -} - -const deno = typeof window !== 'undefined' && window.Deno; -const denoScriptPath = deno && typeof window !== 'undefined' && window.location.pathname; -// Adds deno executable and script path to processArgs as "compatibility" layer for node -// See https://github.com/cacjs/cac/issues/69 -const processArgs = deno ? ['deno', denoScriptPath].concat(Deno.args) : process.argv; -const platformInfo = deno - ? `${Deno.build.os}-${Deno.build.arch} deno-${Deno.version.deno}` - : `${process.platform}-${process.arch} node-${process.version}`; - -class Command { - constructor(rawName, description, config = {}, cli) { - this.rawName = rawName; - this.description = description; - this.config = config; - this.cli = cli; - this.options = []; - this.aliasNames = []; - this.name = removeBrackets(rawName); - this.args = findAllBrackets(rawName); - this.examples = []; - } - usage(text) { - this.usageText = text; - return this; - } - allowUnknownOptions() { - this.config.allowUnknownOptions = true; - return this; - } - ignoreOptionDefaultValue() { - this.config.ignoreOptionDefaultValue = true; - return this; - } - version(version, customFlags = '-v, --version') { - this.versionNumber = version; - this.option(customFlags, 'Display version number'); - return this; - } - example(example) { - this.examples.push(example); - return this; - } - /** - * Add a option for this command - * @param rawName Raw option name(s) - * @param description Option description - * @param config Option config - */ - option(rawName, description, config) { - const option = new Option(rawName, description, config); - this.options.push(option); - return this; - } - alias(name) { - this.aliasNames.push(name); - return this; - } - action(callback) { - this.commandAction = callback; - return this; - } - /** - * Check if a command name is matched by this command - * @param name Command name - */ - isMatched(name) { - return this.name === name || this.aliasNames.includes(name); - } - get isDefaultCommand() { - return this.name === '' || this.aliasNames.includes('!'); - } - get isGlobalCommand() { - return this instanceof GlobalCommand; - } - /** - * Check if an option is registered in this command - * @param name Option name - */ - hasOption(name) { - name = name.split('.')[0]; - return this.options.find(option => { - return option.names.includes(name); - }); - } - outputHelp() { - const { name, commands } = this.cli; - const { versionNumber, options: globalOptions, helpCallback } = this.cli.globalCommand; - const sections = [ - { - body: `${name}${versionNumber ? ` v${versionNumber}` : ''}` - } - ]; - sections.push({ - title: 'Usage', - body: ` $ ${name} ${this.usageText || this.rawName}` - }); - const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0; - if (showCommands) { - const longestCommandName = findLongest(commands.map(command => command.rawName)); - sections.push({ - title: 'Commands', - body: commands - .map(command => { - return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`; - }) - .join('\n') - }); - sections.push({ - title: `For more info, run any command with the \`--help\` flag`, - body: commands - .map(command => ` $ ${name}${command.name === '' ? '' : ` ${command.name}`} --help`) - .join('\n') - }); - } - const options = this.isGlobalCommand - ? globalOptions - : [...this.options, ...(globalOptions || [])]; - if (options.length > 0) { - const longestOptionName = findLongest(options.map(option => option.rawName)); - sections.push({ - title: 'Options', - body: options - .map(option => { - return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === undefined - ? '' - : `(default: ${option.config.default})`}`; - }) - .join('\n') - }); - } - if (this.examples.length > 0) { - sections.push({ - title: 'Examples', - body: this.examples - .map(example => { - if (typeof example === 'function') { - return example(name); - } - return example; - }) - .join('\n') - }); - } - if (helpCallback) { - helpCallback(sections); - } - console.log(sections - .map(section => { - return section.title - ? `${section.title}:\n${section.body}` - : section.body; - }) - .join('\n\n')); - } - outputVersion() { - const { name } = this.cli; - const { versionNumber } = this.cli.globalCommand; - if (versionNumber) { - console.log(`${name}/${versionNumber} ${platformInfo}`); - } - } - checkRequiredArgs() { - const minimalArgsCount = this.args.filter(arg => arg.required).length; - if (this.cli.args.length < minimalArgsCount) { - throw new CACError(`missing required args for command \`${this.rawName}\``); - } - } - /** - * Check if the parsed options contain any unknown options - * - * Exit and output error when true - */ - checkUnknownOptions() { - const { options, globalCommand } = this.cli; - if (!this.config.allowUnknownOptions) { - for (const name of Object.keys(options)) { - if (name !== '--' && - !this.hasOption(name) && - !globalCommand.hasOption(name)) { - throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``); - } - } - } - } - /** - * Check if the required string-type options exist - */ - checkOptionValue() { - const { options: parsedOptions, globalCommand } = this.cli; - const options = [...globalCommand.options, ...this.options]; - for (const option of options) { - const value = parsedOptions[option.name.split('.')[0]]; - // Check required option value - if (option.required) { - const hasNegated = options.some(o => o.negated && o.names.includes(option.name)); - if (value === true || (value === false && !hasNegated)) { - throw new CACError(`option \`${option.rawName}\` value is missing`); - } - } - } - } -} -class GlobalCommand extends Command { - constructor(cli) { - super('@@global@@', '', {}, cli); - } -} - -class CAC extends events_1 { - /** - * @param name The program name to display in help and version message - */ - constructor(name = '') { - super(); - this.name = name; - this.commands = []; - this.globalCommand = new GlobalCommand(this); - this.globalCommand.usage(' [options]'); - } - /** - * Add a global usage text. - * - * This is not used by sub-commands. - */ - usage(text) { - this.globalCommand.usage(text); - return this; - } - /** - * Add a sub-command - */ - command(rawName, description, config) { - const command = new Command(rawName, description || '', config, this); - command.globalCommand = this.globalCommand; - this.commands.push(command); - return command; - } - /** - * Add a global CLI option. - * - * Which is also applied to sub-commands. - */ - option(rawName, description, config) { - this.globalCommand.option(rawName, description, config); - return this; - } - /** - * Show help message when `-h, --help` flags appear. - * - */ - help(callback) { - this.globalCommand.option('-h, --help', 'Display this message'); - this.globalCommand.helpCallback = callback; - this.showHelpOnExit = true; - return this; - } - /** - * Show version number when `-v, --version` flags appear. - * - */ - version(version, customFlags = '-v, --version') { - this.globalCommand.version(version, customFlags); - this.showVersionOnExit = true; - return this; - } - /** - * Add a global example. - * - * This example added here will not be used by sub-commands. - */ - example(example) { - this.globalCommand.example(example); - return this; - } - /** - * Output the corresponding help message - * When a sub-command is matched, output the help message for the command - * Otherwise output the global one. - * - */ - outputHelp() { - if (this.matchedCommand) { - this.matchedCommand.outputHelp(); - } - else { - this.globalCommand.outputHelp(); - } - } - /** - * Output the version number. - * - */ - outputVersion() { - this.globalCommand.outputVersion(); - } - setParsedInfo({ args, options }, matchedCommand, matchedCommandName) { - this.args = args; - this.options = options; - if (matchedCommand) { - this.matchedCommand = matchedCommand; - } - if (matchedCommandName) { - this.matchedCommandName = matchedCommandName; - } - return this; - } - /** - * Parse argv - */ - parse(argv = processArgs, { - /** Whether to run the action for matched command */ - run = true } = {}) { - this.rawArgs = argv; - if (!this.name) { - this.name = argv[1] ? getFileName(argv[1]) : 'cli'; - } - let shouldParse = true; - // Search sub-commands - for (const command of this.commands) { - const parsed = this.mri(argv.slice(2), command); - const commandName = parsed.args[0]; - if (command.isMatched(commandName)) { - shouldParse = false; - const parsedInfo = Object.assign({}, parsed, { args: parsed.args.slice(1) }); - this.setParsedInfo(parsedInfo, command, commandName); - this.emit(`command:${commandName}`, command); - } - } - if (shouldParse) { - // Search the default command - for (const command of this.commands) { - if (command.name === '') { - shouldParse = false; - const parsed = this.mri(argv.slice(2), command); - this.setParsedInfo(parsed, command); - this.emit(`command:!`, command); - } - } - } - if (shouldParse) { - const parsed = this.mri(argv.slice(2)); - this.setParsedInfo(parsed); - } - if (this.options.help && this.showHelpOnExit) { - this.outputHelp(); - run = false; - } - if (this.options.version && this.showVersionOnExit) { - this.outputVersion(); - run = false; - } - const parsedArgv = { args: this.args, options: this.options }; - if (run) { - this.runMatchedCommand(); - } - if (!this.matchedCommand && this.args[0]) { - this.emit('command:*'); - } - return parsedArgv; - } - mri(argv, - /** Matched command */ command) { - // All added options - const cliOptions = [ - ...this.globalCommand.options, - ...(command ? command.options : []) - ]; - const mriOptions = getMriOptions(cliOptions); - // Extract everything after `--` since mri doesn't support it - let argsAfterDoubleDashes = []; - const doubleDashesIndex = argv.indexOf('--'); - if (doubleDashesIndex > -1) { - argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1); - argv = argv.slice(0, doubleDashesIndex); - } - let parsed = lib(argv, mriOptions); - parsed = Object.keys(parsed).reduce((res, name) => { - return Object.assign({}, res, { [camelcaseOptionName(name)]: parsed[name] }); - }, { _: [] }); - const args = parsed._; - delete parsed._; - const options = { - '--': argsAfterDoubleDashes - }; - // Set option default value - const ignoreDefault = command && command.config.ignoreOptionDefaultValue - ? command.config.ignoreOptionDefaultValue - : this.globalCommand.config.ignoreOptionDefaultValue; - let transforms = Object.create(null); - for (const cliOption of cliOptions) { - if (!ignoreDefault && cliOption.config.default !== undefined) { - for (const name of cliOption.names) { - options[name] = cliOption.config.default; - } - } - // If options type is defined - if (Array.isArray(cliOption.config.type)) { - if (transforms[cliOption.name] === undefined) { - transforms[cliOption.name] = Object.create(null); - transforms[cliOption.name]['shouldTransform'] = true; - transforms[cliOption.name]['transformFunction'] = - cliOption.config.type[0]; - } - } - } - // Set dot nested option values - for (const key of Object.keys(parsed)) { - const keys = key.split('.'); - setDotProp(options, keys, parsed[key]); - setByType(options, transforms); - } - return { - args, - options - }; - } - runMatchedCommand() { - const { args, options, matchedCommand: command } = this; - if (!command || !command.commandAction) - return; - command.checkUnknownOptions(); - command.checkOptionValue(); - command.checkRequiredArgs(); - const actionArgs = []; - command.args.forEach((arg, index) => { - if (arg.variadic) { - actionArgs.push(args.slice(index)); - } - else { - actionArgs.push(args[index]); - } - }); - actionArgs.push(options); - return command.commandAction.apply(this, actionArgs); - } -} - -/** - * @param name The program name to display in help and version message - */ -const cac = (name = '') => new CAC(name); -if (typeof module !== 'undefined') { - module.exports = cac; - module.exports.default = cac; - module.exports.cac = cac; -} - -export default cac; -export { cac }; diff --git a/mod_test.js b/mod_test.ts similarity index 59% rename from mod_test.js rename to mod_test.ts index cb9f6ba..28e3bb9 100644 --- a/mod_test.js +++ b/mod_test.ts @@ -1,9 +1,11 @@ +// @deno-types="./mod.d.ts" import { cac } from './mod.js' -const cli = cac() +const cli = cac('my-program') cli.command('[any]', '').action(() => console.log('any')) cli.help() +cli.version('0.0.0') cli.parse() diff --git a/package.json b/package.json index 481b6e8..3097ffb 100644 --- a/package.json +++ b/package.json @@ -7,17 +7,17 @@ "type": "git" }, "main": "dist/index.js", - "types": "types/index.d.ts", + "types": "dist/index.d.ts", "files": [ "dist", - "types", "!**/__test__/**", - "/mod.js" + "/mod.js", + "/mod.d.ts" ], "scripts": { "test": "jest", "test:cov": "jest --coverage", - "build": "tsc -m ESNext && rollup -c", + "build": "rollup -c", "toc": "markdown-toc -i README.md", "prepublishOnly": "npm run build", "docs:api": "typedoc --out api-doc --readme none --exclude \"**/__test__/**\" --theme minimal" @@ -25,6 +25,8 @@ "author": "egoist <0x142857@gmail.com>", "license": "MIT", "devDependencies": { + "@rollup/plugin-commonjs": "^11.1.0", + "@rollup/plugin-node-resolve": "^7.1.3", "@types/execa": "^0.9.0", "@types/jest": "^23.3.9", "@types/mri": "^1.1.0", @@ -38,14 +40,14 @@ "markdown-toc": "^1.2.0", "mri": "^1.1.1", "prettier": "^1.15.2", - "rollup": "^1.32.0", - "@rollup/plugin-commonjs": "^11.0.2", - "@rollup/plugin-node-resolve": "^7.1.1", + "rollup": "^2.10.0", + "rollup-plugin-dts": "^1.4.3", + "rollup-plugin-esbuild": "^1.4.1", "semantic-release": "^15.12.1", "ts-jest": "^23.10.5", "ts-node": "^7.0.1", - "typedoc": "^0.13.0", - "typescript": "^3.1.6" + "typedoc": "^0.17.6", + "typescript": "^3.9.2" }, "engines": { "node": ">=8" diff --git a/rollup.config.js b/rollup.config.js index 352df42..796e9c7 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,24 +1,56 @@ -function createConfig(target) { +import nodeResolvePlugin from '@rollup/plugin-node-resolve' +import esbuildPlugin from 'rollup-plugin-esbuild' +import dtsPlugin from 'rollup-plugin-dts' + +function createConfig(target, dts) { const deno = target === 'deno' + let file = deno ? 'mod.js' : 'dist/index.js' + if (dts) { + file = file.replace('.js', '.d.ts') + } return { - input: 'lib/index.js', + input: 'src/index.ts', output: { - format: deno ? 'esm' : 'cjs', - file: deno ? 'mod.js' : 'dist/index.js', + format: deno || dts ? 'esm' : 'cjs', + file, exports: 'named' }, plugins: [ - require('@rollup/plugin-node-resolve')({ - preferBuiltins: !deno + nodeResolvePlugin({ + preferBuiltins: !deno, + mainFields: dts ? ['types', 'typings'] : ['module', 'main'], + extensions: dts ? ['.d.ts', '.ts'] : ['.js', '.json', '.mjs'], + customResolveOptions: { + moduleDirectory: dts + ? ['node_modules/@types', 'node_modules'] + : 'node_modules' + } }), - require('@rollup/plugin-commonjs')({ - namedExports: { - path: ['basename'], - events: ['EventEmitter'] + !dts && + require('@rollup/plugin-commonjs')({ + namedExports: { + path: ['basename'], + events: ['EventEmitter'] + } + }), + !dts && + esbuildPlugin({ + target: 'es2017' + }), + dts && dtsPlugin(), + deno && { + renderChunk(code) { + // Remove triple slashes reference since Deno doesn't support that + return code.replace(/^\/\/\/(.+)/, '') } - }) - ] + } + ].filter(Boolean) } } -export default [createConfig('node'), createConfig('deno')] +export default [ + createConfig('node'), + createConfig('deno'), + createConfig('node', true), + createConfig('deno', true) +] diff --git a/src/Command.ts b/src/Command.ts index fa05ecf..91224e1 100644 --- a/src/Command.ts +++ b/src/Command.ts @@ -115,7 +115,7 @@ class Command { return this.name === '' || this.aliasNames.includes('!') } - get isGlobalCommand() { + get isGlobalCommand(): boolean { return this instanceof GlobalCommand } diff --git a/src/node.ts b/src/node.ts index 6f0824c..521bfe3 100644 --- a/src/node.ts +++ b/src/node.ts @@ -2,13 +2,9 @@ declare let window: any declare let Deno: any const deno = typeof window !== 'undefined' && window.Deno -const denoScriptPath = - deno && typeof window !== 'undefined' && window.location.pathname -// Adds deno executable and script path to processArgs as "compatibility" layer for node -// See https://github.com/cacjs/cac/issues/69 export const processArgs = deno - ? ['deno', denoScriptPath].concat(Deno.args) + ? ['deno', 'cli'].concat(Deno.args) : process.argv export const platformInfo = deno diff --git a/yarn.lock b/yarn.lock index 9f1e314..609ac98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -357,34 +357,38 @@ universal-user-agent "^2.0.0" url-template "^2.0.8" -"@rollup/plugin-commonjs@^11.0.2": - version "11.0.2" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-11.0.2.tgz#837cc6950752327cb90177b608f0928a4e60b582" - integrity sha512-MPYGZr0qdbV5zZj8/2AuomVpnRVXRU5XKXb3HVniwRoRCreGlf5kOE081isNWeiLIi6IYkwTX9zE0/c7V8g81g== +"@rollup/plugin-commonjs@^11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-11.1.0.tgz#60636c7a722f54b41e419e1709df05c7234557ef" + integrity sha512-Ycr12N3ZPN96Fw2STurD21jMqzKwL9QuFhms3SD7KKRK7oaXUsBU9Zt0jL/rOPHiPYisI21/rXGO3jr9BnLHUA== dependencies: - "@rollup/pluginutils" "^3.0.0" + "@rollup/pluginutils" "^3.0.8" + commondir "^1.0.1" estree-walker "^1.0.1" + glob "^7.1.2" is-reference "^1.1.2" magic-string "^0.25.2" resolve "^1.11.0" -"@rollup/plugin-node-resolve@^7.1.1": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.1.tgz#8c6e59c4b28baf9d223028d0e450e06a485bb2b7" - integrity sha512-14ddhD7TnemeHE97a4rLOhobfYvUVcaYuqTnL8Ti7Jxi9V9Jr5LY7Gko4HZ5k4h4vqQM0gBQt6tsp9xXW94WPA== +"@rollup/plugin-node-resolve@^7.1.3": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca" + integrity sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q== dependencies: - "@rollup/pluginutils" "^3.0.6" + "@rollup/pluginutils" "^3.0.8" "@types/resolve" "0.0.8" builtin-modules "^3.1.0" is-module "^1.0.0" resolve "^1.14.2" -"@rollup/pluginutils@^3.0.0", "@rollup/pluginutils@^3.0.6": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.0.8.tgz#4e94d128d94b90699e517ef045422960d18c8fde" - integrity sha512-rYGeAc4sxcZ+kPG/Tw4/fwJODC3IXHYDH4qusdN/b6aLw5LPUbzpecYbEJh4sVQGPFJxd2dBU4kc1H3oy9/bnw== +"@rollup/pluginutils@^3.0.10", "@rollup/pluginutils@^3.0.8": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.0.10.tgz#a659b9025920378494cd8f8c59fbf9b3a50d5f12" + integrity sha512-d44M7t+PjmMrASHbhgpSbVgtL6EFyX7J4mYxwQ/c5eoaE6N2VgCgEcWVzNnwycIloti+/MpwFr8qfw+nRw00sw== dependencies: + "@types/estree" "0.0.39" estree-walker "^1.0.1" + picomatch "^2.2.2" "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" @@ -498,11 +502,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/estree@*": - version "0.0.42" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.42.tgz#8d0c1f480339efedb3e46070e22dd63e0430dd11" - integrity sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ== - "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.npm.taobao.org/@types/estree/download/@types/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" @@ -520,14 +519,7 @@ dependencies: "@types/node" "*" -"@types/fs-extra@^5.0.3": - version "5.1.0" - resolved "https://registry.npm.taobao.org/@types/fs-extra/download/@types/fs-extra-5.1.0.tgz#2a325ef97901504a3828718c390d34b8426a10a1" - integrity sha1-KjJe+XkBUEo4KHGMOQ00uEJqEKE= - dependencies: - "@types/node" "*" - -"@types/glob@*", "@types/glob@^7.1.1": +"@types/glob@^7.1.1": version "7.1.1" resolved "https://registry.npm.taobao.org/@types/glob/download/@types/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" integrity sha1-qlmhxuP7xCHgfM0xqUTDDrpSFXU= @@ -536,18 +528,6 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/handlebars@^4.0.38": - version "4.1.0" - resolved "https://registry.npm.taobao.org/@types/handlebars/download/@types/handlebars-4.1.0.tgz#3fcce9bf88f85fe73dc932240ab3fb682c624850" - integrity sha1-P8zpv4j4X+c9yTIkCrP7aCxiSFA= - dependencies: - handlebars "*" - -"@types/highlight.js@^9.12.3": - version "9.12.3" - resolved "https://registry.npm.taobao.org/@types/highlight.js/download/@types/highlight.js-9.12.3.tgz#b672cfaac25cbbc634a0fd92c515f66faa18dbca" - integrity sha1-tnLPqsJcu8Y0oP2SxRX2b6oY28o= - "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -573,17 +553,7 @@ resolved "https://registry.npm.taobao.org/@types/jest/download/@types/jest-23.3.14.tgz#37daaf78069e7948520474c87b80092ea912520a" integrity sha1-N9qveAaeeUhSBHTIe4AJLqkSUgo= -"@types/lodash@^4.14.110": - version "4.14.133" - resolved "https://registry.npm.taobao.org/@types/lodash/download/@types/lodash-4.14.133.tgz#430721c96da22dd1694443e68e6cec7ba1c1003d" - integrity sha1-QwchyW2iLdFpREPmjmzse6HBAD0= - -"@types/marked@^0.4.0": - version "0.4.2" - resolved "https://registry.npm.taobao.org/@types/marked/download/@types/marked-0.4.2.tgz#64a89e53ea37f61cc0f3ee1732c555c2dbf6452f" - integrity sha1-ZKieU+o39hzA8+4XMsVVwtv2RS8= - -"@types/minimatch@*", "@types/minimatch@3.0.3": +"@types/minimatch@*": version "3.0.3" resolved "https://registry.npm.taobao.org/@types/minimatch/download/@types/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha1-PcoOPzOyAPx9ETnAzZbBJoyt/Z0= @@ -610,14 +580,6 @@ dependencies: "@types/node" "*" -"@types/shelljs@^0.8.0": - version "0.8.5" - resolved "https://registry.npm.taobao.org/@types/shelljs/download/@types/shelljs-0.8.5.tgz#1e507b2f6d1f893269bd3e851ec24419ef9beeea" - integrity sha1-HlB7L20fiTJpvT6FHsJEGe+b7uo= - dependencies: - "@types/glob" "*" - "@types/node" "*" - "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -676,11 +638,6 @@ acorn@^6.0.1: resolved "https://registry.npm.taobao.org/acorn/download/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha1-fSWuBbuK0fm2mRCOEJTs14hK3B8= -acorn@^7.1.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" - integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== - agent-base@4, agent-base@^4.1.0, agent-base@~4.2.1: version "4.2.1" resolved "https://registry.npm.taobao.org/agent-base/download/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -1489,6 +1446,11 @@ commander@^2.14.1, commander@^2.9.0, commander@~2.20.0: resolved "https://registry.npm.taobao.org/commander/download/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha1-1YuytcHuj4ew00ACfp6U4iLFpCI= +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + compare-func@^1.3.1: version "1.3.2" resolved "https://registry.npm.taobao.org/compare-func/download/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" @@ -2050,6 +2012,11 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" +esbuild@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.3.1.tgz#3ca7628fe47daa6ef0dcaf100ebad967006d2126" + integrity sha512-q8fqHk1FyaokBq85slRun9nwRaEm4vRc9dXSsNrEiz9+b8o1Wk5+7clDQ+cD67Ks/cDOCOytHjUwLatQkJqHQA== + escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescape-string-regexp%2Fdownload%2Fescape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -2424,6 +2391,15 @@ fs-extra@^7.0.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-minipass@^1.2.5: version "1.2.6" resolved "https://registry.npm.taobao.org/fs-minipass/download/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" @@ -2463,6 +2439,11 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + fstream@^1.0.0, fstream@^1.0.12: version "1.0.12" resolved "https://registry.npm.taobao.org/fstream/download/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" @@ -2677,6 +2658,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha1-/7cD4QZuig7qpMi4C6klPu77+wA= +graceful-fs@^4.2.0: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + gray-matter@^2.1.0: version "2.1.1" resolved "https://registry.npm.taobao.org/gray-matter/download/gray-matter-2.1.1.tgz#3042d9adec2a1ded6a7707a9ed2380f8a17a430e" @@ -2693,7 +2679,7 @@ growly@^1.3.0: resolved "https://registry.npm.taobao.org/growly/download/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -handlebars@*, handlebars@^4.0.6, handlebars@^4.1.0: +handlebars@^4.1.0: version "4.1.2" resolved "https://registry.npm.taobao.org/handlebars/download/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" integrity sha1-trN8HO0DBrIh4JT8eso+wjsTG2c= @@ -2704,6 +2690,18 @@ handlebars@*, handlebars@^4.0.6, handlebars@^4.1.0: optionalDependencies: uglify-js "^3.1.4" +handlebars@^4.7.6: + version "4.7.6" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e" + integrity sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -2782,10 +2780,10 @@ has@^1.0.1, has@^1.0.3: dependencies: function-bind "^1.1.1" -highlight.js@^9.0.0: - version "9.15.8" - resolved "https://registry.npm.taobao.org/highlight.js/download/highlight.js-9.15.8.tgz#f344fda123f36f1a65490e932cf90569e4999971" - integrity sha1-80T9oSPzbxplSQ6TLPkFaeSZmXE= +highlight.js@^10.0.0: + version "10.0.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.0.3.tgz#5effcc58420f113f279a0badb8ac50c4be06e63b" + integrity sha512-9FG7SSzv9yOY5CGGxfI6NDm7xLYtMOjKtPBxw7Zff3t5UcRcUNTGEeS8lNjhceL34KeetLMoGMFTGoaa83HwyQ== hook-std@^2.0.0: version "2.0.0" @@ -4330,12 +4328,12 @@ lodash.without@~4.4.0: resolved "https://registry.npm.taobao.org/lodash.without/download/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw= -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.2.1: +lodash@^4.17.11, lodash@^4.17.4, lodash@^4.2.1: version "4.17.14" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== -lodash@^4.17.13: +lodash@^4.17.13, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -4403,6 +4401,11 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lunr@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.8.tgz#a8b89c31f30b5a044b97d2d28e2da191b6ba2072" + integrity sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg== + macos-release@^2.2.0: version "2.2.0" resolved "https://registry.npm.taobao.org/macos-release/download/macos-release-2.2.0.tgz#ab58d55dd4714f0a05ad4b0e90f4370fef5cdea8" @@ -4528,10 +4531,10 @@ marked-terminal@^3.2.0: node-emoji "^1.4.1" supports-hyperlinks "^1.0.1" -marked@^0.4.0: - version "0.4.0" - resolved "https://registry.npm.taobao.org/marked/download/marked-0.4.0.tgz#9ad2c2a7a1791f10a852e0112f77b571dce10c66" - integrity sha1-mtLCp6F5HxCoUuARL3e1cdzhDGY= +marked@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-1.0.0.tgz#d35784245a04871e5988a491e28867362e941693" + integrity sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng== marked@^0.6.0: version "0.6.2" @@ -4667,6 +4670,11 @@ minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: resolved "https://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + minimist@~0.0.1: version "0.0.10" resolved "https://registry.npm.taobao.org/minimist/download/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" @@ -5529,6 +5537,11 @@ performance-now@^2.1.0: resolved "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picomatch@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + pify@^2.0.0: version "2.3.0" resolved "https://registry.npm.taobao.org/pify/download/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -5625,10 +5638,10 @@ process-nextick-args@~2.0.0: resolved "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" integrity sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o= -progress@^2.0.0: +progress@^2.0.3: version "2.0.3" - resolved "https://registry.npm.taobao.org/progress/download/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha1-foz42PW48jnBvGi+tOt4Vn1XLvg= + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise-inflight@^1.0.1, promise-inflight@~1.0.1: version "1.0.1" @@ -6179,14 +6192,27 @@ rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2. dependencies: glob "^7.1.3" -rollup@^1.32.0: - version "1.32.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.32.0.tgz#c65ce134850aca1ce595fcac07d1dc5d53bf227c" - integrity sha512-ab2tF5pdDqm2zuI8j02ceyrJSScl9V2C24FgWQ1v1kTFTu1UrG5H0hpP++mDZlEFyZX4k0chtGEHU2i+pAzBgA== +rollup-plugin-dts@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/rollup-plugin-dts/-/rollup-plugin-dts-1.4.3.tgz#debd56abd4c08bcaa619268927e13ad643a82bb5" + integrity sha512-/zs3KkyN7xEC3RJMrfcY0z1Hvn3TIuen4pjOh9ASAWMcoXsMNVnZZIO75izE8VyWopSJrNz3Rm4EXF2gjqvt5A== + optionalDependencies: + "@babel/code-frame" "^7.8.3" + +rollup-plugin-esbuild@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-esbuild/-/rollup-plugin-esbuild-1.4.1.tgz#b388ebd4cda1198208d7746feea7656d485019b0" + integrity sha512-gTzKtVo/OiOOe6pwRFHQCyCtEeYxcxLmjpqMiT4TnwXtPdF8RNP9c5wh/NZPztQydcMdEe1W+TO7poXwbLQekw== dependencies: - "@types/estree" "*" - "@types/node" "*" - acorn "^7.1.0" + "@rollup/pluginutils" "^3.0.10" + esbuild "^0.3.0" + +rollup@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.10.0.tgz#73332273fa177cd85c1042659dee6f103761be0d" + integrity sha512-7BmpEfUN9P6esJzWIn3DmR//90mW6YwYB1t3y48LpF8ITpYtL8s1kEirMKqUu44dVH/6a/rs0EuwYVL3FuRDoA== + optionalDependencies: + fsevents "~2.1.2" rsvp@^4.8.4: version "4.8.5" @@ -6370,10 +6396,10 @@ shebang-regex@^1.0.0: resolved "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -shelljs@^0.8.2: - version "0.8.3" - resolved "https://registry.npm.taobao.org/shelljs/download/shelljs-0.8.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fshelljs%2Fdownload%2Fshelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" - integrity sha1-p/MxlSDr8J7oEnWyNorbKGZZsJc= +shelljs@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" + integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -7084,43 +7110,33 @@ typedarray@^0.0.6: resolved "https://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typedoc-default-themes@^0.5.0: - version "0.5.0" - resolved "https://registry.npm.taobao.org/typedoc-default-themes/download/typedoc-default-themes-0.5.0.tgz#6dc2433e78ed8bea8e887a3acde2f31785bd6227" - integrity sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic= - -typedoc@^0.13.0: - version "0.13.0" - resolved "https://registry.npm.taobao.org/typedoc/download/typedoc-0.13.0.tgz#9efdf352bd54873955cd161bd4b75f24a8c59dde" - integrity sha1-nv3zUr1UhzlVzRYb1LdfJKjFnd4= - dependencies: - "@types/fs-extra" "^5.0.3" - "@types/handlebars" "^4.0.38" - "@types/highlight.js" "^9.12.3" - "@types/lodash" "^4.14.110" - "@types/marked" "^0.4.0" - "@types/minimatch" "3.0.3" - "@types/shelljs" "^0.8.0" - fs-extra "^7.0.0" - handlebars "^4.0.6" - highlight.js "^9.0.0" - lodash "^4.17.10" - marked "^0.4.0" +typedoc-default-themes@^0.10.1: + version "0.10.1" + resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.10.1.tgz#eb27b7d689457c7ec843e47ec0d3e500581296a7" + integrity sha512-SuqAQI0CkwhqSJ2kaVTgl37cWs733uy9UGUqwtcds8pkFK8oRF4rZmCq+FXTGIb9hIUOu40rf5Kojg0Ha6akeg== + dependencies: + lunr "^2.3.8" + +typedoc@^0.17.6: + version "0.17.6" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.17.6.tgz#cab87a72c10e05429016d659a4c3071a5a3ffb61" + integrity sha512-pQiYnhG3yJk7939cv2n8uFoTsSgy5Hfiw0dgOQYa9nT9Ya1013dMctQdAXMj8JbNu7KhcauQyq9Zql9D/TziLw== + dependencies: + fs-extra "^8.1.0" + handlebars "^4.7.6" + highlight.js "^10.0.0" + lodash "^4.17.15" + lunr "^2.3.8" + marked "1.0.0" minimatch "^3.0.0" - progress "^2.0.0" - shelljs "^0.8.2" - typedoc-default-themes "^0.5.0" - typescript "3.1.x" + progress "^2.0.3" + shelljs "^0.8.4" + typedoc-default-themes "^0.10.1" -typescript@3.1.x: - version "3.1.6" - resolved "https://registry.npm.taobao.org/typescript/download/typescript-3.1.6.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftypescript%2Fdownload%2Ftypescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68" - integrity sha1-tlQ6g8/Iwr77P0yPumiW9bDJvmg= - -typescript@^3.1.6: - version "3.5.1" - resolved "https://registry.npm.taobao.org/typescript/download/typescript-3.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftypescript%2Fdownload%2Ftypescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202" - integrity sha1-unKmpgCyFYE5xd2IUPcA4jFGQgI= +typescript@^3.9.2: + version "3.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.2.tgz#64e9c8e9be6ea583c54607677dd4680a1cf35db9" + integrity sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw== uglify-js@^3.1.4: version "3.6.0" @@ -7475,16 +7491,16 @@ word-wrap@^1.0.3: resolved "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha1-YQY29rH3A4kb00dxzLF/uTtHB5w= +wordwrap@^1.0.0, wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/wordwrap/download/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.npm.taobao.org/wordwrap/download/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - worker-farm@^1.6.0: version "1.7.0" resolved "https://registry.npm.taobao.org/worker-farm/download/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"