mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 15:07:55 -05:00
feat(npm): simplify project structure by moving from @simstudio/cli to simstudio package
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,6 +22,7 @@
|
|||||||
/build
|
/build
|
||||||
/dist
|
/dist
|
||||||
**/dist/
|
**/dist/
|
||||||
|
**/standalone/
|
||||||
sim-standalone.tar.gz
|
sim-standalone.tar.gz
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
|
|||||||
2119
package-lock.json
generated
2119
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@@ -15,10 +15,10 @@
|
|||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
"test:coverage": "jest --coverage",
|
"test:coverage": "jest --coverage",
|
||||||
"cli:build": "npm run build -w packages/@simstudio/cli",
|
"cli:build": "npm run build -w packages/simstudio",
|
||||||
"cli:dev": "npm run build -w packages/@simstudio/cli && cd packages/@simstudio/cli && node ./dist/index.js",
|
"cli:dev": "npm run build -w packages/simstudio && cd packages/simstudio && node ./dist/index.js",
|
||||||
"cli:publish": "cd packages/@simstudio/cli && npm publish --access public",
|
"cli:publish": "cd packages/simstudio && npm publish",
|
||||||
"cli:start": "cd packages/@simstudio/cli && node ./dist/index.js start",
|
"cli:start": "cd packages/simstudio && node ./dist/index.js start",
|
||||||
"build:standalone": "node scripts/build-standalone.js",
|
"build:standalone": "node scripts/build-standalone.js",
|
||||||
"build:cli": "npm run cli:build && npm run build:standalone",
|
"build:cli": "npm run cli:build && npm run build:standalone",
|
||||||
"publish:cli": "npm run build:cli && npm run cli:publish"
|
"publish:cli": "npm run build:cli && npm run cli:publish"
|
||||||
@@ -99,6 +99,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/@sim/*"
|
"packages/@sim/*",
|
||||||
|
"packages/simstudio"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
# Environment variables and secrets
|
|
||||||
.env
|
|
||||||
.env.*
|
|
||||||
*.env
|
|
||||||
.env.local
|
|
||||||
.env.development
|
|
||||||
.env.test
|
|
||||||
.env.production
|
|
||||||
|
|
||||||
# Development files
|
|
||||||
node_modules
|
|
||||||
.git
|
|
||||||
.gitignore
|
|
||||||
.github
|
|
||||||
.vscode
|
|
||||||
.idea
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
||||||
# Test files
|
|
||||||
test
|
|
||||||
tests
|
|
||||||
__tests__
|
|
||||||
coverage
|
|
||||||
|
|
||||||
# Build artifacts
|
|
||||||
.DS_Store
|
|
||||||
.cache
|
|
||||||
.next/cache
|
|
||||||
|
|
||||||
# Project specific
|
|
||||||
.sim-studio-dev
|
|
||||||
22
packages/@simstudio/cli/node_modules/commander/LICENSE
generated
vendored
22
packages/@simstudio/cli/node_modules/commander/LICENSE
generated
vendored
@@ -1,22 +0,0 @@
|
|||||||
(The MIT License)
|
|
||||||
|
|
||||||
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
'Software'), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
1148
packages/@simstudio/cli/node_modules/commander/Readme.md
generated
vendored
1148
packages/@simstudio/cli/node_modules/commander/Readme.md
generated
vendored
File diff suppressed because it is too large
Load Diff
16
packages/@simstudio/cli/node_modules/commander/esm.mjs
generated
vendored
16
packages/@simstudio/cli/node_modules/commander/esm.mjs
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
import commander from './index.js';
|
|
||||||
|
|
||||||
// wrapper to provide named exports for ESM.
|
|
||||||
export const {
|
|
||||||
program,
|
|
||||||
createCommand,
|
|
||||||
createArgument,
|
|
||||||
createOption,
|
|
||||||
CommanderError,
|
|
||||||
InvalidArgumentError,
|
|
||||||
InvalidOptionArgumentError, // deprecated old name
|
|
||||||
Command,
|
|
||||||
Argument,
|
|
||||||
Option,
|
|
||||||
Help
|
|
||||||
} = commander;
|
|
||||||
26
packages/@simstudio/cli/node_modules/commander/index.js
generated
vendored
26
packages/@simstudio/cli/node_modules/commander/index.js
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
const { Argument } = require('./lib/argument.js');
|
|
||||||
const { Command } = require('./lib/command.js');
|
|
||||||
const { CommanderError, InvalidArgumentError } = require('./lib/error.js');
|
|
||||||
const { Help } = require('./lib/help.js');
|
|
||||||
const { Option } = require('./lib/option.js');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Expose the root command.
|
|
||||||
*/
|
|
||||||
|
|
||||||
exports = module.exports = new Command();
|
|
||||||
exports.program = exports; // More explicit access to global command.
|
|
||||||
// createArgument, createCommand, and createOption are implicitly available as they are methods on program.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Expose classes
|
|
||||||
*/
|
|
||||||
|
|
||||||
exports.Command = Command;
|
|
||||||
exports.Option = Option;
|
|
||||||
exports.Argument = Argument;
|
|
||||||
exports.Help = Help;
|
|
||||||
|
|
||||||
exports.CommanderError = CommanderError;
|
|
||||||
exports.InvalidArgumentError = InvalidArgumentError;
|
|
||||||
exports.InvalidOptionArgumentError = InvalidArgumentError; // Deprecated
|
|
||||||
145
packages/@simstudio/cli/node_modules/commander/lib/argument.js
generated
vendored
145
packages/@simstudio/cli/node_modules/commander/lib/argument.js
generated
vendored
@@ -1,145 +0,0 @@
|
|||||||
const { InvalidArgumentError } = require('./error.js');
|
|
||||||
|
|
||||||
class Argument {
|
|
||||||
/**
|
|
||||||
* Initialize a new command argument with the given name and description.
|
|
||||||
* The default is that the argument is required, and you can explicitly
|
|
||||||
* indicate this with <> around the name. Put [] around the name for an optional argument.
|
|
||||||
*
|
|
||||||
* @param {string} name
|
|
||||||
* @param {string} [description]
|
|
||||||
*/
|
|
||||||
|
|
||||||
constructor(name, description) {
|
|
||||||
this.description = description || '';
|
|
||||||
this.variadic = false;
|
|
||||||
this.parseArg = undefined;
|
|
||||||
this.defaultValue = undefined;
|
|
||||||
this.defaultValueDescription = undefined;
|
|
||||||
this.argChoices = undefined;
|
|
||||||
|
|
||||||
switch (name[0]) {
|
|
||||||
case '<': // e.g. <required>
|
|
||||||
this.required = true;
|
|
||||||
this._name = name.slice(1, -1);
|
|
||||||
break;
|
|
||||||
case '[': // e.g. [optional]
|
|
||||||
this.required = false;
|
|
||||||
this._name = name.slice(1, -1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.required = true;
|
|
||||||
this._name = name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._name.length > 3 && this._name.slice(-3) === '...') {
|
|
||||||
this.variadic = true;
|
|
||||||
this._name = this._name.slice(0, -3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return argument name.
|
|
||||||
*
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
name() {
|
|
||||||
return this._name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
_concatValue(value, previous) {
|
|
||||||
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
||||||
return [value];
|
|
||||||
}
|
|
||||||
|
|
||||||
return previous.concat(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the default value, and optionally supply the description to be displayed in the help.
|
|
||||||
*
|
|
||||||
* @param {*} value
|
|
||||||
* @param {string} [description]
|
|
||||||
* @return {Argument}
|
|
||||||
*/
|
|
||||||
|
|
||||||
default(value, description) {
|
|
||||||
this.defaultValue = value;
|
|
||||||
this.defaultValueDescription = description;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the custom handler for processing CLI command arguments into argument values.
|
|
||||||
*
|
|
||||||
* @param {Function} [fn]
|
|
||||||
* @return {Argument}
|
|
||||||
*/
|
|
||||||
|
|
||||||
argParser(fn) {
|
|
||||||
this.parseArg = fn;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only allow argument value to be one of choices.
|
|
||||||
*
|
|
||||||
* @param {string[]} values
|
|
||||||
* @return {Argument}
|
|
||||||
*/
|
|
||||||
|
|
||||||
choices(values) {
|
|
||||||
this.argChoices = values.slice();
|
|
||||||
this.parseArg = (arg, previous) => {
|
|
||||||
if (!this.argChoices.includes(arg)) {
|
|
||||||
throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(', ')}.`);
|
|
||||||
}
|
|
||||||
if (this.variadic) {
|
|
||||||
return this._concatValue(arg, previous);
|
|
||||||
}
|
|
||||||
return arg;
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make argument required.
|
|
||||||
*/
|
|
||||||
argRequired() {
|
|
||||||
this.required = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make argument optional.
|
|
||||||
*/
|
|
||||||
argOptional() {
|
|
||||||
this.required = false;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes an argument and returns its human readable equivalent for help usage.
|
|
||||||
*
|
|
||||||
* @param {Argument} arg
|
|
||||||
* @return {string}
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
function humanReadableArgName(arg) {
|
|
||||||
const nameOutput = arg.name() + (arg.variadic === true ? '...' : '');
|
|
||||||
|
|
||||||
return arg.required
|
|
||||||
? '<' + nameOutput + '>'
|
|
||||||
: '[' + nameOutput + ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.Argument = Argument;
|
|
||||||
exports.humanReadableArgName = humanReadableArgName;
|
|
||||||
2179
packages/@simstudio/cli/node_modules/commander/lib/command.js
generated
vendored
2179
packages/@simstudio/cli/node_modules/commander/lib/command.js
generated
vendored
File diff suppressed because it is too large
Load Diff
43
packages/@simstudio/cli/node_modules/commander/lib/error.js
generated
vendored
43
packages/@simstudio/cli/node_modules/commander/lib/error.js
generated
vendored
@@ -1,43 +0,0 @@
|
|||||||
/**
|
|
||||||
* CommanderError class
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
class CommanderError extends Error {
|
|
||||||
/**
|
|
||||||
* Constructs the CommanderError class
|
|
||||||
* @param {number} exitCode suggested exit code which could be used with process.exit
|
|
||||||
* @param {string} code an id string representing the error
|
|
||||||
* @param {string} message human-readable description of the error
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
constructor(exitCode, code, message) {
|
|
||||||
super(message);
|
|
||||||
// properly capture stack trace in Node.js
|
|
||||||
Error.captureStackTrace(this, this.constructor);
|
|
||||||
this.name = this.constructor.name;
|
|
||||||
this.code = code;
|
|
||||||
this.exitCode = exitCode;
|
|
||||||
this.nestedError = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* InvalidArgumentError class
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
class InvalidArgumentError extends CommanderError {
|
|
||||||
/**
|
|
||||||
* Constructs the InvalidArgumentError class
|
|
||||||
* @param {string} [message] explanation of why argument is invalid
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
constructor(message) {
|
|
||||||
super(1, 'commander.invalidArgument', message);
|
|
||||||
// properly capture stack trace in Node.js
|
|
||||||
Error.captureStackTrace(this, this.constructor);
|
|
||||||
this.name = this.constructor.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.CommanderError = CommanderError;
|
|
||||||
exports.InvalidArgumentError = InvalidArgumentError;
|
|
||||||
462
packages/@simstudio/cli/node_modules/commander/lib/help.js
generated
vendored
462
packages/@simstudio/cli/node_modules/commander/lib/help.js
generated
vendored
@@ -1,462 +0,0 @@
|
|||||||
const { humanReadableArgName } = require('./argument.js');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TypeScript import types for JSDoc, used by Visual Studio Code IntelliSense and `npm run typescript-checkJS`
|
|
||||||
* https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#import-types
|
|
||||||
* @typedef { import("./argument.js").Argument } Argument
|
|
||||||
* @typedef { import("./command.js").Command } Command
|
|
||||||
* @typedef { import("./option.js").Option } Option
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Although this is a class, methods are static in style to allow override using subclass or just functions.
|
|
||||||
class Help {
|
|
||||||
constructor() {
|
|
||||||
this.helpWidth = undefined;
|
|
||||||
this.sortSubcommands = false;
|
|
||||||
this.sortOptions = false;
|
|
||||||
this.showGlobalOptions = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @returns {Command[]}
|
|
||||||
*/
|
|
||||||
|
|
||||||
visibleCommands(cmd) {
|
|
||||||
const visibleCommands = cmd.commands.filter(cmd => !cmd._hidden);
|
|
||||||
if (cmd._hasImplicitHelpCommand()) {
|
|
||||||
// Create a command matching the implicit help command.
|
|
||||||
const [, helpName, helpArgs] = cmd._helpCommandnameAndArgs.match(/([^ ]+) *(.*)/);
|
|
||||||
const helpCommand = cmd.createCommand(helpName)
|
|
||||||
.helpOption(false);
|
|
||||||
helpCommand.description(cmd._helpCommandDescription);
|
|
||||||
if (helpArgs) helpCommand.arguments(helpArgs);
|
|
||||||
visibleCommands.push(helpCommand);
|
|
||||||
}
|
|
||||||
if (this.sortSubcommands) {
|
|
||||||
visibleCommands.sort((a, b) => {
|
|
||||||
// @ts-ignore: overloaded return type
|
|
||||||
return a.name().localeCompare(b.name());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return visibleCommands;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare options for sort.
|
|
||||||
*
|
|
||||||
* @param {Option} a
|
|
||||||
* @param {Option} b
|
|
||||||
* @returns number
|
|
||||||
*/
|
|
||||||
compareOptions(a, b) {
|
|
||||||
const getSortKey = (option) => {
|
|
||||||
// WYSIWYG for order displayed in help. Short used for comparison if present. No special handling for negated.
|
|
||||||
return option.short ? option.short.replace(/^-/, '') : option.long.replace(/^--/, '');
|
|
||||||
};
|
|
||||||
return getSortKey(a).localeCompare(getSortKey(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an array of the visible options. Includes a placeholder for the implicit help option, if there is one.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @returns {Option[]}
|
|
||||||
*/
|
|
||||||
|
|
||||||
visibleOptions(cmd) {
|
|
||||||
const visibleOptions = cmd.options.filter((option) => !option.hidden);
|
|
||||||
// Implicit help
|
|
||||||
const showShortHelpFlag = cmd._hasHelpOption && cmd._helpShortFlag && !cmd._findOption(cmd._helpShortFlag);
|
|
||||||
const showLongHelpFlag = cmd._hasHelpOption && !cmd._findOption(cmd._helpLongFlag);
|
|
||||||
if (showShortHelpFlag || showLongHelpFlag) {
|
|
||||||
let helpOption;
|
|
||||||
if (!showShortHelpFlag) {
|
|
||||||
helpOption = cmd.createOption(cmd._helpLongFlag, cmd._helpDescription);
|
|
||||||
} else if (!showLongHelpFlag) {
|
|
||||||
helpOption = cmd.createOption(cmd._helpShortFlag, cmd._helpDescription);
|
|
||||||
} else {
|
|
||||||
helpOption = cmd.createOption(cmd._helpFlags, cmd._helpDescription);
|
|
||||||
}
|
|
||||||
visibleOptions.push(helpOption);
|
|
||||||
}
|
|
||||||
if (this.sortOptions) {
|
|
||||||
visibleOptions.sort(this.compareOptions);
|
|
||||||
}
|
|
||||||
return visibleOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an array of the visible global options. (Not including help.)
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @returns {Option[]}
|
|
||||||
*/
|
|
||||||
|
|
||||||
visibleGlobalOptions(cmd) {
|
|
||||||
if (!this.showGlobalOptions) return [];
|
|
||||||
|
|
||||||
const globalOptions = [];
|
|
||||||
for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
|
|
||||||
const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
|
|
||||||
globalOptions.push(...visibleOptions);
|
|
||||||
}
|
|
||||||
if (this.sortOptions) {
|
|
||||||
globalOptions.sort(this.compareOptions);
|
|
||||||
}
|
|
||||||
return globalOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an array of the arguments if any have a description.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @returns {Argument[]}
|
|
||||||
*/
|
|
||||||
|
|
||||||
visibleArguments(cmd) {
|
|
||||||
// Side effect! Apply the legacy descriptions before the arguments are displayed.
|
|
||||||
if (cmd._argsDescription) {
|
|
||||||
cmd.registeredArguments.forEach(argument => {
|
|
||||||
argument.description = argument.description || cmd._argsDescription[argument.name()] || '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are any arguments with a description then return all the arguments.
|
|
||||||
if (cmd.registeredArguments.find(argument => argument.description)) {
|
|
||||||
return cmd.registeredArguments;
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the command term to show in the list of subcommands.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
subcommandTerm(cmd) {
|
|
||||||
// Legacy. Ignores custom usage string, and nested commands.
|
|
||||||
const args = cmd.registeredArguments.map(arg => humanReadableArgName(arg)).join(' ');
|
|
||||||
return cmd._name +
|
|
||||||
(cmd._aliases[0] ? '|' + cmd._aliases[0] : '') +
|
|
||||||
(cmd.options.length ? ' [options]' : '') + // simplistic check for non-help option
|
|
||||||
(args ? ' ' + args : '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the option term to show in the list of options.
|
|
||||||
*
|
|
||||||
* @param {Option} option
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
optionTerm(option) {
|
|
||||||
return option.flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the argument term to show in the list of arguments.
|
|
||||||
*
|
|
||||||
* @param {Argument} argument
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
argumentTerm(argument) {
|
|
||||||
return argument.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the longest command term length.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @param {Help} helper
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
|
|
||||||
longestSubcommandTermLength(cmd, helper) {
|
|
||||||
return helper.visibleCommands(cmd).reduce((max, command) => {
|
|
||||||
return Math.max(max, helper.subcommandTerm(command).length);
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the longest option term length.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @param {Help} helper
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
|
|
||||||
longestOptionTermLength(cmd, helper) {
|
|
||||||
return helper.visibleOptions(cmd).reduce((max, option) => {
|
|
||||||
return Math.max(max, helper.optionTerm(option).length);
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the longest global option term length.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @param {Help} helper
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
|
|
||||||
longestGlobalOptionTermLength(cmd, helper) {
|
|
||||||
return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
|
|
||||||
return Math.max(max, helper.optionTerm(option).length);
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the longest argument term length.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @param {Help} helper
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
|
|
||||||
longestArgumentTermLength(cmd, helper) {
|
|
||||||
return helper.visibleArguments(cmd).reduce((max, argument) => {
|
|
||||||
return Math.max(max, helper.argumentTerm(argument).length);
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the command usage to be displayed at the top of the built-in help.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
commandUsage(cmd) {
|
|
||||||
// Usage
|
|
||||||
let cmdName = cmd._name;
|
|
||||||
if (cmd._aliases[0]) {
|
|
||||||
cmdName = cmdName + '|' + cmd._aliases[0];
|
|
||||||
}
|
|
||||||
let ancestorCmdNames = '';
|
|
||||||
for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
|
|
||||||
ancestorCmdNames = ancestorCmd.name() + ' ' + ancestorCmdNames;
|
|
||||||
}
|
|
||||||
return ancestorCmdNames + cmdName + ' ' + cmd.usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the description for the command.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
commandDescription(cmd) {
|
|
||||||
// @ts-ignore: overloaded return type
|
|
||||||
return cmd.description();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the subcommand summary to show in the list of subcommands.
|
|
||||||
* (Fallback to description for backwards compatibility.)
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
subcommandDescription(cmd) {
|
|
||||||
// @ts-ignore: overloaded return type
|
|
||||||
return cmd.summary() || cmd.description();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the option description to show in the list of options.
|
|
||||||
*
|
|
||||||
* @param {Option} option
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
optionDescription(option) {
|
|
||||||
const extraInfo = [];
|
|
||||||
|
|
||||||
if (option.argChoices) {
|
|
||||||
extraInfo.push(
|
|
||||||
// use stringify to match the display of the default value
|
|
||||||
`choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(', ')}`);
|
|
||||||
}
|
|
||||||
if (option.defaultValue !== undefined) {
|
|
||||||
// default for boolean and negated more for programmer than end user,
|
|
||||||
// but show true/false for boolean option as may be for hand-rolled env or config processing.
|
|
||||||
const showDefault = option.required || option.optional ||
|
|
||||||
(option.isBoolean() && typeof option.defaultValue === 'boolean');
|
|
||||||
if (showDefault) {
|
|
||||||
extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// preset for boolean and negated are more for programmer than end user
|
|
||||||
if (option.presetArg !== undefined && option.optional) {
|
|
||||||
extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
|
|
||||||
}
|
|
||||||
if (option.envVar !== undefined) {
|
|
||||||
extraInfo.push(`env: ${option.envVar}`);
|
|
||||||
}
|
|
||||||
if (extraInfo.length > 0) {
|
|
||||||
return `${option.description} (${extraInfo.join(', ')})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return option.description;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the argument description to show in the list of arguments.
|
|
||||||
*
|
|
||||||
* @param {Argument} argument
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
argumentDescription(argument) {
|
|
||||||
const extraInfo = [];
|
|
||||||
if (argument.argChoices) {
|
|
||||||
extraInfo.push(
|
|
||||||
// use stringify to match the display of the default value
|
|
||||||
`choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(', ')}`);
|
|
||||||
}
|
|
||||||
if (argument.defaultValue !== undefined) {
|
|
||||||
extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
|
|
||||||
}
|
|
||||||
if (extraInfo.length > 0) {
|
|
||||||
const extraDescripton = `(${extraInfo.join(', ')})`;
|
|
||||||
if (argument.description) {
|
|
||||||
return `${argument.description} ${extraDescripton}`;
|
|
||||||
}
|
|
||||||
return extraDescripton;
|
|
||||||
}
|
|
||||||
return argument.description;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate the built-in help text.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @param {Help} helper
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
formatHelp(cmd, helper) {
|
|
||||||
const termWidth = helper.padWidth(cmd, helper);
|
|
||||||
const helpWidth = helper.helpWidth || 80;
|
|
||||||
const itemIndentWidth = 2;
|
|
||||||
const itemSeparatorWidth = 2; // between term and description
|
|
||||||
function formatItem(term, description) {
|
|
||||||
if (description) {
|
|
||||||
const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`;
|
|
||||||
return helper.wrap(fullText, helpWidth - itemIndentWidth, termWidth + itemSeparatorWidth);
|
|
||||||
}
|
|
||||||
return term;
|
|
||||||
}
|
|
||||||
function formatList(textArray) {
|
|
||||||
return textArray.join('\n').replace(/^/gm, ' '.repeat(itemIndentWidth));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Usage
|
|
||||||
let output = [`Usage: ${helper.commandUsage(cmd)}`, ''];
|
|
||||||
|
|
||||||
// Description
|
|
||||||
const commandDescription = helper.commandDescription(cmd);
|
|
||||||
if (commandDescription.length > 0) {
|
|
||||||
output = output.concat([helper.wrap(commandDescription, helpWidth, 0), '']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Arguments
|
|
||||||
const argumentList = helper.visibleArguments(cmd).map((argument) => {
|
|
||||||
return formatItem(helper.argumentTerm(argument), helper.argumentDescription(argument));
|
|
||||||
});
|
|
||||||
if (argumentList.length > 0) {
|
|
||||||
output = output.concat(['Arguments:', formatList(argumentList), '']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Options
|
|
||||||
const optionList = helper.visibleOptions(cmd).map((option) => {
|
|
||||||
return formatItem(helper.optionTerm(option), helper.optionDescription(option));
|
|
||||||
});
|
|
||||||
if (optionList.length > 0) {
|
|
||||||
output = output.concat(['Options:', formatList(optionList), '']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.showGlobalOptions) {
|
|
||||||
const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
|
|
||||||
return formatItem(helper.optionTerm(option), helper.optionDescription(option));
|
|
||||||
});
|
|
||||||
if (globalOptionList.length > 0) {
|
|
||||||
output = output.concat(['Global Options:', formatList(globalOptionList), '']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commands
|
|
||||||
const commandList = helper.visibleCommands(cmd).map((cmd) => {
|
|
||||||
return formatItem(helper.subcommandTerm(cmd), helper.subcommandDescription(cmd));
|
|
||||||
});
|
|
||||||
if (commandList.length > 0) {
|
|
||||||
output = output.concat(['Commands:', formatList(commandList), '']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return output.join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the pad width from the maximum term length.
|
|
||||||
*
|
|
||||||
* @param {Command} cmd
|
|
||||||
* @param {Help} helper
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
|
|
||||||
padWidth(cmd, helper) {
|
|
||||||
return Math.max(
|
|
||||||
helper.longestOptionTermLength(cmd, helper),
|
|
||||||
helper.longestGlobalOptionTermLength(cmd, helper),
|
|
||||||
helper.longestSubcommandTermLength(cmd, helper),
|
|
||||||
helper.longestArgumentTermLength(cmd, helper)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap the given string to width characters per line, with lines after the first indented.
|
|
||||||
* Do not wrap if insufficient room for wrapping (minColumnWidth), or string is manually formatted.
|
|
||||||
*
|
|
||||||
* @param {string} str
|
|
||||||
* @param {number} width
|
|
||||||
* @param {number} indent
|
|
||||||
* @param {number} [minColumnWidth=40]
|
|
||||||
* @return {string}
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
wrap(str, width, indent, minColumnWidth = 40) {
|
|
||||||
// Full \s characters, minus the linefeeds.
|
|
||||||
const indents = ' \\f\\t\\v\u00a0\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff';
|
|
||||||
// Detect manually wrapped and indented strings by searching for line break followed by spaces.
|
|
||||||
const manualIndent = new RegExp(`[\\n][${indents}]+`);
|
|
||||||
if (str.match(manualIndent)) return str;
|
|
||||||
// Do not wrap if not enough room for a wrapped column of text (as could end up with a word per line).
|
|
||||||
const columnWidth = width - indent;
|
|
||||||
if (columnWidth < minColumnWidth) return str;
|
|
||||||
|
|
||||||
const leadingStr = str.slice(0, indent);
|
|
||||||
const columnText = str.slice(indent).replace('\r\n', '\n');
|
|
||||||
const indentString = ' '.repeat(indent);
|
|
||||||
const zeroWidthSpace = '\u200B';
|
|
||||||
const breaks = `\\s${zeroWidthSpace}`;
|
|
||||||
// Match line end (so empty lines don't collapse),
|
|
||||||
// or as much text as will fit in column, or excess text up to first break.
|
|
||||||
const regex = new RegExp(`\n|.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`, 'g');
|
|
||||||
const lines = columnText.match(regex) || [];
|
|
||||||
return leadingStr + lines.map((line, i) => {
|
|
||||||
if (line === '\n') return ''; // preserve empty lines
|
|
||||||
return ((i > 0) ? indentString : '') + line.trimEnd();
|
|
||||||
}).join('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.Help = Help;
|
|
||||||
329
packages/@simstudio/cli/node_modules/commander/lib/option.js
generated
vendored
329
packages/@simstudio/cli/node_modules/commander/lib/option.js
generated
vendored
@@ -1,329 +0,0 @@
|
|||||||
const { InvalidArgumentError } = require('./error.js');
|
|
||||||
|
|
||||||
class Option {
|
|
||||||
/**
|
|
||||||
* Initialize a new `Option` with the given `flags` and `description`.
|
|
||||||
*
|
|
||||||
* @param {string} flags
|
|
||||||
* @param {string} [description]
|
|
||||||
*/
|
|
||||||
|
|
||||||
constructor(flags, description) {
|
|
||||||
this.flags = flags;
|
|
||||||
this.description = description || '';
|
|
||||||
|
|
||||||
this.required = flags.includes('<'); // A value must be supplied when the option is specified.
|
|
||||||
this.optional = flags.includes('['); // A value is optional when the option is specified.
|
|
||||||
// variadic test ignores <value,...> et al which might be used to describe custom splitting of single argument
|
|
||||||
this.variadic = /\w\.\.\.[>\]]$/.test(flags); // The option can take multiple values.
|
|
||||||
this.mandatory = false; // The option must have a value after parsing, which usually means it must be specified on command line.
|
|
||||||
const optionFlags = splitOptionFlags(flags);
|
|
||||||
this.short = optionFlags.shortFlag;
|
|
||||||
this.long = optionFlags.longFlag;
|
|
||||||
this.negate = false;
|
|
||||||
if (this.long) {
|
|
||||||
this.negate = this.long.startsWith('--no-');
|
|
||||||
}
|
|
||||||
this.defaultValue = undefined;
|
|
||||||
this.defaultValueDescription = undefined;
|
|
||||||
this.presetArg = undefined;
|
|
||||||
this.envVar = undefined;
|
|
||||||
this.parseArg = undefined;
|
|
||||||
this.hidden = false;
|
|
||||||
this.argChoices = undefined;
|
|
||||||
this.conflictsWith = [];
|
|
||||||
this.implied = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the default value, and optionally supply the description to be displayed in the help.
|
|
||||||
*
|
|
||||||
* @param {*} value
|
|
||||||
* @param {string} [description]
|
|
||||||
* @return {Option}
|
|
||||||
*/
|
|
||||||
|
|
||||||
default(value, description) {
|
|
||||||
this.defaultValue = value;
|
|
||||||
this.defaultValueDescription = description;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preset to use when option used without option-argument, especially optional but also boolean and negated.
|
|
||||||
* The custom processing (parseArg) is called.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* new Option('--color').default('GREYSCALE').preset('RGB');
|
|
||||||
* new Option('--donate [amount]').preset('20').argParser(parseFloat);
|
|
||||||
*
|
|
||||||
* @param {*} arg
|
|
||||||
* @return {Option}
|
|
||||||
*/
|
|
||||||
|
|
||||||
preset(arg) {
|
|
||||||
this.presetArg = arg;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add option name(s) that conflict with this option.
|
|
||||||
* An error will be displayed if conflicting options are found during parsing.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* new Option('--rgb').conflicts('cmyk');
|
|
||||||
* new Option('--js').conflicts(['ts', 'jsx']);
|
|
||||||
*
|
|
||||||
* @param {string | string[]} names
|
|
||||||
* @return {Option}
|
|
||||||
*/
|
|
||||||
|
|
||||||
conflicts(names) {
|
|
||||||
this.conflictsWith = this.conflictsWith.concat(names);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify implied option values for when this option is set and the implied options are not.
|
|
||||||
*
|
|
||||||
* The custom processing (parseArg) is not called on the implied values.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* program
|
|
||||||
* .addOption(new Option('--log', 'write logging information to file'))
|
|
||||||
* .addOption(new Option('--trace', 'log extra details').implies({ log: 'trace.txt' }));
|
|
||||||
*
|
|
||||||
* @param {Object} impliedOptionValues
|
|
||||||
* @return {Option}
|
|
||||||
*/
|
|
||||||
implies(impliedOptionValues) {
|
|
||||||
let newImplied = impliedOptionValues;
|
|
||||||
if (typeof impliedOptionValues === 'string') {
|
|
||||||
// string is not documented, but easy mistake and we can do what user probably intended.
|
|
||||||
newImplied = { [impliedOptionValues]: true };
|
|
||||||
}
|
|
||||||
this.implied = Object.assign(this.implied || {}, newImplied);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set environment variable to check for option value.
|
|
||||||
*
|
|
||||||
* An environment variable is only used if when processed the current option value is
|
|
||||||
* undefined, or the source of the current value is 'default' or 'config' or 'env'.
|
|
||||||
*
|
|
||||||
* @param {string} name
|
|
||||||
* @return {Option}
|
|
||||||
*/
|
|
||||||
|
|
||||||
env(name) {
|
|
||||||
this.envVar = name;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the custom handler for processing CLI option arguments into option values.
|
|
||||||
*
|
|
||||||
* @param {Function} [fn]
|
|
||||||
* @return {Option}
|
|
||||||
*/
|
|
||||||
|
|
||||||
argParser(fn) {
|
|
||||||
this.parseArg = fn;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the option is mandatory and must have a value after parsing.
|
|
||||||
*
|
|
||||||
* @param {boolean} [mandatory=true]
|
|
||||||
* @return {Option}
|
|
||||||
*/
|
|
||||||
|
|
||||||
makeOptionMandatory(mandatory = true) {
|
|
||||||
this.mandatory = !!mandatory;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide option in help.
|
|
||||||
*
|
|
||||||
* @param {boolean} [hide=true]
|
|
||||||
* @return {Option}
|
|
||||||
*/
|
|
||||||
|
|
||||||
hideHelp(hide = true) {
|
|
||||||
this.hidden = !!hide;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
_concatValue(value, previous) {
|
|
||||||
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
||||||
return [value];
|
|
||||||
}
|
|
||||||
|
|
||||||
return previous.concat(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only allow option value to be one of choices.
|
|
||||||
*
|
|
||||||
* @param {string[]} values
|
|
||||||
* @return {Option}
|
|
||||||
*/
|
|
||||||
|
|
||||||
choices(values) {
|
|
||||||
this.argChoices = values.slice();
|
|
||||||
this.parseArg = (arg, previous) => {
|
|
||||||
if (!this.argChoices.includes(arg)) {
|
|
||||||
throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(', ')}.`);
|
|
||||||
}
|
|
||||||
if (this.variadic) {
|
|
||||||
return this._concatValue(arg, previous);
|
|
||||||
}
|
|
||||||
return arg;
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return option name.
|
|
||||||
*
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
name() {
|
|
||||||
if (this.long) {
|
|
||||||
return this.long.replace(/^--/, '');
|
|
||||||
}
|
|
||||||
return this.short.replace(/^-/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return option name, in a camelcase format that can be used
|
|
||||||
* as a object attribute key.
|
|
||||||
*
|
|
||||||
* @return {string}
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
attributeName() {
|
|
||||||
return camelcase(this.name().replace(/^no-/, ''));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if `arg` matches the short or long flag.
|
|
||||||
*
|
|
||||||
* @param {string} arg
|
|
||||||
* @return {boolean}
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
is(arg) {
|
|
||||||
return this.short === arg || this.long === arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether a boolean option.
|
|
||||||
*
|
|
||||||
* Options are one of boolean, negated, required argument, or optional argument.
|
|
||||||
*
|
|
||||||
* @return {boolean}
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
isBoolean() {
|
|
||||||
return !this.required && !this.optional && !this.negate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is to make it easier to work with dual options, without changing the existing
|
|
||||||
* implementation. We support separate dual options for separate positive and negative options,
|
|
||||||
* like `--build` and `--no-build`, which share a single option value. This works nicely for some
|
|
||||||
* use cases, but is tricky for others where we want separate behaviours despite
|
|
||||||
* the single shared option value.
|
|
||||||
*/
|
|
||||||
class DualOptions {
|
|
||||||
/**
|
|
||||||
* @param {Option[]} options
|
|
||||||
*/
|
|
||||||
constructor(options) {
|
|
||||||
this.positiveOptions = new Map();
|
|
||||||
this.negativeOptions = new Map();
|
|
||||||
this.dualOptions = new Set();
|
|
||||||
options.forEach(option => {
|
|
||||||
if (option.negate) {
|
|
||||||
this.negativeOptions.set(option.attributeName(), option);
|
|
||||||
} else {
|
|
||||||
this.positiveOptions.set(option.attributeName(), option);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.negativeOptions.forEach((value, key) => {
|
|
||||||
if (this.positiveOptions.has(key)) {
|
|
||||||
this.dualOptions.add(key);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Did the value come from the option, and not from possible matching dual option?
|
|
||||||
*
|
|
||||||
* @param {*} value
|
|
||||||
* @param {Option} option
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
valueFromOption(value, option) {
|
|
||||||
const optionKey = option.attributeName();
|
|
||||||
if (!this.dualOptions.has(optionKey)) return true;
|
|
||||||
|
|
||||||
// Use the value to deduce if (probably) came from the option.
|
|
||||||
const preset = this.negativeOptions.get(optionKey).presetArg;
|
|
||||||
const negativeValue = (preset !== undefined) ? preset : false;
|
|
||||||
return option.negate === (negativeValue === value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert string from kebab-case to camelCase.
|
|
||||||
*
|
|
||||||
* @param {string} str
|
|
||||||
* @return {string}
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
function camelcase(str) {
|
|
||||||
return str.split('-').reduce((str, word) => {
|
|
||||||
return str + word[0].toUpperCase() + word.slice(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Split the short and long flag out of something like '-m,--mixed <value>'
|
|
||||||
*
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
function splitOptionFlags(flags) {
|
|
||||||
let shortFlag;
|
|
||||||
let longFlag;
|
|
||||||
// Use original very loose parsing to maintain backwards compatibility for now,
|
|
||||||
// which allowed for example unintended `-sw, --short-word` [sic].
|
|
||||||
const flagParts = flags.split(/[ |,]+/);
|
|
||||||
if (flagParts.length > 1 && !/^[[<]/.test(flagParts[1])) shortFlag = flagParts.shift();
|
|
||||||
longFlag = flagParts.shift();
|
|
||||||
// Add support for lone short flag without significantly changing parsing!
|
|
||||||
if (!shortFlag && /^-[^-]$/.test(longFlag)) {
|
|
||||||
shortFlag = longFlag;
|
|
||||||
longFlag = undefined;
|
|
||||||
}
|
|
||||||
return { shortFlag, longFlag };
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.Option = Option;
|
|
||||||
exports.splitOptionFlags = splitOptionFlags;
|
|
||||||
exports.DualOptions = DualOptions;
|
|
||||||
100
packages/@simstudio/cli/node_modules/commander/lib/suggestSimilar.js
generated
vendored
100
packages/@simstudio/cli/node_modules/commander/lib/suggestSimilar.js
generated
vendored
@@ -1,100 +0,0 @@
|
|||||||
const maxDistance = 3;
|
|
||||||
|
|
||||||
function editDistance(a, b) {
|
|
||||||
// https://en.wikipedia.org/wiki/Damerau–Levenshtein_distance
|
|
||||||
// Calculating optimal string alignment distance, no substring is edited more than once.
|
|
||||||
// (Simple implementation.)
|
|
||||||
|
|
||||||
// Quick early exit, return worst case.
|
|
||||||
if (Math.abs(a.length - b.length) > maxDistance) return Math.max(a.length, b.length);
|
|
||||||
|
|
||||||
// distance between prefix substrings of a and b
|
|
||||||
const d = [];
|
|
||||||
|
|
||||||
// pure deletions turn a into empty string
|
|
||||||
for (let i = 0; i <= a.length; i++) {
|
|
||||||
d[i] = [i];
|
|
||||||
}
|
|
||||||
// pure insertions turn empty string into b
|
|
||||||
for (let j = 0; j <= b.length; j++) {
|
|
||||||
d[0][j] = j;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fill matrix
|
|
||||||
for (let j = 1; j <= b.length; j++) {
|
|
||||||
for (let i = 1; i <= a.length; i++) {
|
|
||||||
let cost = 1;
|
|
||||||
if (a[i - 1] === b[j - 1]) {
|
|
||||||
cost = 0;
|
|
||||||
} else {
|
|
||||||
cost = 1;
|
|
||||||
}
|
|
||||||
d[i][j] = Math.min(
|
|
||||||
d[i - 1][j] + 1, // deletion
|
|
||||||
d[i][j - 1] + 1, // insertion
|
|
||||||
d[i - 1][j - 1] + cost // substitution
|
|
||||||
);
|
|
||||||
// transposition
|
|
||||||
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
||||||
d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return d[a.length][b.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find close matches, restricted to same number of edits.
|
|
||||||
*
|
|
||||||
* @param {string} word
|
|
||||||
* @param {string[]} candidates
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function suggestSimilar(word, candidates) {
|
|
||||||
if (!candidates || candidates.length === 0) return '';
|
|
||||||
// remove possible duplicates
|
|
||||||
candidates = Array.from(new Set(candidates));
|
|
||||||
|
|
||||||
const searchingOptions = word.startsWith('--');
|
|
||||||
if (searchingOptions) {
|
|
||||||
word = word.slice(2);
|
|
||||||
candidates = candidates.map(candidate => candidate.slice(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
let similar = [];
|
|
||||||
let bestDistance = maxDistance;
|
|
||||||
const minSimilarity = 0.4;
|
|
||||||
candidates.forEach((candidate) => {
|
|
||||||
if (candidate.length <= 1) return; // no one character guesses
|
|
||||||
|
|
||||||
const distance = editDistance(word, candidate);
|
|
||||||
const length = Math.max(word.length, candidate.length);
|
|
||||||
const similarity = (length - distance) / length;
|
|
||||||
if (similarity > minSimilarity) {
|
|
||||||
if (distance < bestDistance) {
|
|
||||||
// better edit distance, throw away previous worse matches
|
|
||||||
bestDistance = distance;
|
|
||||||
similar = [candidate];
|
|
||||||
} else if (distance === bestDistance) {
|
|
||||||
similar.push(candidate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
similar.sort((a, b) => a.localeCompare(b));
|
|
||||||
if (searchingOptions) {
|
|
||||||
similar = similar.map(candidate => `--${candidate}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (similar.length > 1) {
|
|
||||||
return `\n(Did you mean one of ${similar.join(', ')}?)`;
|
|
||||||
}
|
|
||||||
if (similar.length === 1) {
|
|
||||||
return `\n(Did you mean ${similar[0]}?)`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.suggestSimilar = suggestSimilar;
|
|
||||||
16
packages/@simstudio/cli/node_modules/commander/package-support.json
generated
vendored
16
packages/@simstudio/cli/node_modules/commander/package-support.json
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"versions": [
|
|
||||||
{
|
|
||||||
"version": "*",
|
|
||||||
"target": {
|
|
||||||
"node": "supported"
|
|
||||||
},
|
|
||||||
"response": {
|
|
||||||
"type": "time-permitting"
|
|
||||||
},
|
|
||||||
"backing": {
|
|
||||||
"npm-funding": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
80
packages/@simstudio/cli/node_modules/commander/package.json
generated
vendored
80
packages/@simstudio/cli/node_modules/commander/package.json
generated
vendored
@@ -1,80 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "commander",
|
|
||||||
"version": "11.1.0",
|
|
||||||
"description": "the complete solution for node.js command-line programs",
|
|
||||||
"keywords": [
|
|
||||||
"commander",
|
|
||||||
"command",
|
|
||||||
"option",
|
|
||||||
"parser",
|
|
||||||
"cli",
|
|
||||||
"argument",
|
|
||||||
"args",
|
|
||||||
"argv"
|
|
||||||
],
|
|
||||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
|
||||||
"license": "MIT",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/tj/commander.js.git"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"lint": "npm run lint:javascript && npm run lint:typescript",
|
|
||||||
"lint:javascript": "eslint index.js esm.mjs \"lib/*.js\" \"tests/**/*.js\"",
|
|
||||||
"lint:typescript": "eslint typings/*.ts tests/*.ts",
|
|
||||||
"test": "jest && npm run typecheck-ts",
|
|
||||||
"test-esm": "node ./tests/esm-imports-test.mjs",
|
|
||||||
"typecheck-ts": "tsd && tsc -p tsconfig.ts.json",
|
|
||||||
"typecheck-js": "tsc -p tsconfig.js.json",
|
|
||||||
"test-all": "npm run test && npm run lint && npm run typecheck-js && npm run test-esm"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"index.js",
|
|
||||||
"lib/*.js",
|
|
||||||
"esm.mjs",
|
|
||||||
"typings/index.d.ts",
|
|
||||||
"typings/esm.d.mts",
|
|
||||||
"package-support.json"
|
|
||||||
],
|
|
||||||
"type": "commonjs",
|
|
||||||
"main": "./index.js",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"require": {
|
|
||||||
"types": "./typings/index.d.ts",
|
|
||||||
"default": "./index.js"
|
|
||||||
},
|
|
||||||
"import": {
|
|
||||||
"types": "./typings/esm.d.mts",
|
|
||||||
"default": "./esm.mjs"
|
|
||||||
},
|
|
||||||
"default": "./index.js"
|
|
||||||
},
|
|
||||||
"./esm.mjs": {
|
|
||||||
"types": "./typings/esm.d.mts",
|
|
||||||
"import": "./esm.mjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/jest": "^29.2.4",
|
|
||||||
"@types/node": "^20.2.5",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^5.47.1",
|
|
||||||
"@typescript-eslint/parser": "^5.47.1",
|
|
||||||
"eslint": "^8.30.0",
|
|
||||||
"eslint-config-standard": "^17.0.0",
|
|
||||||
"eslint-config-standard-with-typescript": "^33.0.0",
|
|
||||||
"eslint-plugin-import": "^2.26.0",
|
|
||||||
"eslint-plugin-jest": "^27.1.7",
|
|
||||||
"eslint-plugin-n": "^15.6.0",
|
|
||||||
"eslint-plugin-promise": "^6.1.1",
|
|
||||||
"jest": "^29.3.1",
|
|
||||||
"ts-jest": "^29.0.3",
|
|
||||||
"tsd": "^0.28.1",
|
|
||||||
"typescript": "^5.0.4"
|
|
||||||
},
|
|
||||||
"types": "typings/index.d.ts",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
},
|
|
||||||
"support": true
|
|
||||||
}
|
|
||||||
3
packages/@simstudio/cli/node_modules/commander/typings/esm.d.mts
generated
vendored
3
packages/@simstudio/cli/node_modules/commander/typings/esm.d.mts
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
// Just reexport the types from cjs
|
|
||||||
// This is a bit indirect. There is not an index.js, but TypeScript will look for index.d.ts for types.
|
|
||||||
export * from './index.js';
|
|
||||||
884
packages/@simstudio/cli/node_modules/commander/typings/index.d.ts
generated
vendored
884
packages/@simstudio/cli/node_modules/commander/typings/index.d.ts
generated
vendored
@@ -1,884 +0,0 @@
|
|||||||
// Type definitions for commander
|
|
||||||
// Original definitions by: Alan Agius <https://github.com/alan-agius4>, Marcelo Dezem <https://github.com/mdezem>, vvakame <https://github.com/vvakame>, Jules Randolph <https://github.com/sveinburne>
|
|
||||||
|
|
||||||
// Using method rather than property for method-signature-style, to document method overloads separately. Allow either.
|
|
||||||
/* eslint-disable @typescript-eslint/method-signature-style */
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
||||||
|
|
||||||
// This is a trick to encourage editor to suggest the known literals while still
|
|
||||||
// allowing any BaseType value.
|
|
||||||
// References:
|
|
||||||
// - https://github.com/microsoft/TypeScript/issues/29729
|
|
||||||
// - https://github.com/sindresorhus/type-fest/blob/main/source/literal-union.d.ts
|
|
||||||
// - https://github.com/sindresorhus/type-fest/blob/main/source/primitive.d.ts
|
|
||||||
type LiteralUnion<LiteralType, BaseType extends string | number> = LiteralType | (BaseType & Record<never, never>);
|
|
||||||
|
|
||||||
export class CommanderError extends Error {
|
|
||||||
code: string;
|
|
||||||
exitCode: number;
|
|
||||||
message: string;
|
|
||||||
nestedError?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs the CommanderError class
|
|
||||||
* @param exitCode - suggested exit code which could be used with process.exit
|
|
||||||
* @param code - an id string representing the error
|
|
||||||
* @param message - human-readable description of the error
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
constructor(exitCode: number, code: string, message: string);
|
|
||||||
}
|
|
||||||
|
|
||||||
export class InvalidArgumentError extends CommanderError {
|
|
||||||
/**
|
|
||||||
* Constructs the InvalidArgumentError class
|
|
||||||
* @param message - explanation of why argument is invalid
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
constructor(message: string);
|
|
||||||
}
|
|
||||||
export { InvalidArgumentError as InvalidOptionArgumentError }; // deprecated old name
|
|
||||||
|
|
||||||
export interface ErrorOptions { // optional parameter for error()
|
|
||||||
/** an id string representing the error */
|
|
||||||
code?: string;
|
|
||||||
/** suggested exit code which could be used with process.exit */
|
|
||||||
exitCode?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Argument {
|
|
||||||
description: string;
|
|
||||||
required: boolean;
|
|
||||||
variadic: boolean;
|
|
||||||
defaultValue?: any;
|
|
||||||
defaultValueDescription?: string;
|
|
||||||
argChoices?: string[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a new command argument with the given name and description.
|
|
||||||
* The default is that the argument is required, and you can explicitly
|
|
||||||
* indicate this with <> around the name. Put [] around the name for an optional argument.
|
|
||||||
*/
|
|
||||||
constructor(arg: string, description?: string);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return argument name.
|
|
||||||
*/
|
|
||||||
name(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the default value, and optionally supply the description to be displayed in the help.
|
|
||||||
*/
|
|
||||||
default(value: unknown, description?: string): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the custom handler for processing CLI command arguments into argument values.
|
|
||||||
*/
|
|
||||||
argParser<T>(fn: (value: string, previous: T) => T): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only allow argument value to be one of choices.
|
|
||||||
*/
|
|
||||||
choices(values: readonly string[]): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make argument required.
|
|
||||||
*/
|
|
||||||
argRequired(): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make argument optional.
|
|
||||||
*/
|
|
||||||
argOptional(): this;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Option {
|
|
||||||
flags: string;
|
|
||||||
description: string;
|
|
||||||
|
|
||||||
required: boolean; // A value must be supplied when the option is specified.
|
|
||||||
optional: boolean; // A value is optional when the option is specified.
|
|
||||||
variadic: boolean;
|
|
||||||
mandatory: boolean; // The option must have a value after parsing, which usually means it must be specified on command line.
|
|
||||||
short?: string;
|
|
||||||
long?: string;
|
|
||||||
negate: boolean;
|
|
||||||
defaultValue?: any;
|
|
||||||
defaultValueDescription?: string;
|
|
||||||
presetArg?: unknown;
|
|
||||||
envVar?: string;
|
|
||||||
parseArg?: <T>(value: string, previous: T) => T;
|
|
||||||
hidden: boolean;
|
|
||||||
argChoices?: string[];
|
|
||||||
|
|
||||||
constructor(flags: string, description?: string);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the default value, and optionally supply the description to be displayed in the help.
|
|
||||||
*/
|
|
||||||
default(value: unknown, description?: string): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Preset to use when option used without option-argument, especially optional but also boolean and negated.
|
|
||||||
* The custom processing (parseArg) is called.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* new Option('--color').default('GREYSCALE').preset('RGB');
|
|
||||||
* new Option('--donate [amount]').preset('20').argParser(parseFloat);
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
preset(arg: unknown): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add option name(s) that conflict with this option.
|
|
||||||
* An error will be displayed if conflicting options are found during parsing.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* new Option('--rgb').conflicts('cmyk');
|
|
||||||
* new Option('--js').conflicts(['ts', 'jsx']);
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
conflicts(names: string | string[]): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify implied option values for when this option is set and the implied options are not.
|
|
||||||
*
|
|
||||||
* The custom processing (parseArg) is not called on the implied values.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* program
|
|
||||||
* .addOption(new Option('--log', 'write logging information to file'))
|
|
||||||
* .addOption(new Option('--trace', 'log extra details').implies({ log: 'trace.txt' }));
|
|
||||||
*/
|
|
||||||
implies(optionValues: OptionValues): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set environment variable to check for option value.
|
|
||||||
*
|
|
||||||
* An environment variables is only used if when processed the current option value is
|
|
||||||
* undefined, or the source of the current value is 'default' or 'config' or 'env'.
|
|
||||||
*/
|
|
||||||
env(name: string): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the full description, including defaultValue etc.
|
|
||||||
*/
|
|
||||||
fullDescription(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the custom handler for processing CLI option arguments into option values.
|
|
||||||
*/
|
|
||||||
argParser<T>(fn: (value: string, previous: T) => T): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the option is mandatory and must have a value after parsing.
|
|
||||||
*/
|
|
||||||
makeOptionMandatory(mandatory?: boolean): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide option in help.
|
|
||||||
*/
|
|
||||||
hideHelp(hide?: boolean): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only allow option value to be one of choices.
|
|
||||||
*/
|
|
||||||
choices(values: readonly string[]): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return option name.
|
|
||||||
*/
|
|
||||||
name(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return option name, in a camelcase format that can be used
|
|
||||||
* as a object attribute key.
|
|
||||||
*/
|
|
||||||
attributeName(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return whether a boolean option.
|
|
||||||
*
|
|
||||||
* Options are one of boolean, negated, required argument, or optional argument.
|
|
||||||
*/
|
|
||||||
isBoolean(): boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Help {
|
|
||||||
/** output helpWidth, long lines are wrapped to fit */
|
|
||||||
helpWidth?: number;
|
|
||||||
sortSubcommands: boolean;
|
|
||||||
sortOptions: boolean;
|
|
||||||
showGlobalOptions: boolean;
|
|
||||||
|
|
||||||
constructor();
|
|
||||||
|
|
||||||
/** Get the command term to show in the list of subcommands. */
|
|
||||||
subcommandTerm(cmd: Command): string;
|
|
||||||
/** Get the command summary to show in the list of subcommands. */
|
|
||||||
subcommandDescription(cmd: Command): string;
|
|
||||||
/** Get the option term to show in the list of options. */
|
|
||||||
optionTerm(option: Option): string;
|
|
||||||
/** Get the option description to show in the list of options. */
|
|
||||||
optionDescription(option: Option): string;
|
|
||||||
/** Get the argument term to show in the list of arguments. */
|
|
||||||
argumentTerm(argument: Argument): string;
|
|
||||||
/** Get the argument description to show in the list of arguments. */
|
|
||||||
argumentDescription(argument: Argument): string;
|
|
||||||
|
|
||||||
/** Get the command usage to be displayed at the top of the built-in help. */
|
|
||||||
commandUsage(cmd: Command): string;
|
|
||||||
/** Get the description for the command. */
|
|
||||||
commandDescription(cmd: Command): string;
|
|
||||||
|
|
||||||
/** Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one. */
|
|
||||||
visibleCommands(cmd: Command): Command[];
|
|
||||||
/** Get an array of the visible options. Includes a placeholder for the implicit help option, if there is one. */
|
|
||||||
visibleOptions(cmd: Command): Option[];
|
|
||||||
/** Get an array of the visible global options. (Not including help.) */
|
|
||||||
visibleGlobalOptions(cmd: Command): Option[];
|
|
||||||
/** Get an array of the arguments which have descriptions. */
|
|
||||||
visibleArguments(cmd: Command): Argument[];
|
|
||||||
|
|
||||||
/** Get the longest command term length. */
|
|
||||||
longestSubcommandTermLength(cmd: Command, helper: Help): number;
|
|
||||||
/** Get the longest option term length. */
|
|
||||||
longestOptionTermLength(cmd: Command, helper: Help): number;
|
|
||||||
/** Get the longest global option term length. */
|
|
||||||
longestGlobalOptionTermLength(cmd: Command, helper: Help): number;
|
|
||||||
/** Get the longest argument term length. */
|
|
||||||
longestArgumentTermLength(cmd: Command, helper: Help): number;
|
|
||||||
/** Calculate the pad width from the maximum term length. */
|
|
||||||
padWidth(cmd: Command, helper: Help): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap the given string to width characters per line, with lines after the first indented.
|
|
||||||
* Do not wrap if insufficient room for wrapping (minColumnWidth), or string is manually formatted.
|
|
||||||
*/
|
|
||||||
wrap(str: string, width: number, indent: number, minColumnWidth?: number): string;
|
|
||||||
|
|
||||||
/** Generate the built-in help text. */
|
|
||||||
formatHelp(cmd: Command, helper: Help): string;
|
|
||||||
}
|
|
||||||
export type HelpConfiguration = Partial<Help>;
|
|
||||||
|
|
||||||
export interface ParseOptions {
|
|
||||||
from: 'node' | 'electron' | 'user';
|
|
||||||
}
|
|
||||||
export interface HelpContext { // optional parameter for .help() and .outputHelp()
|
|
||||||
error: boolean;
|
|
||||||
}
|
|
||||||
export interface AddHelpTextContext { // passed to text function used with .addHelpText()
|
|
||||||
error: boolean;
|
|
||||||
command: Command;
|
|
||||||
}
|
|
||||||
export interface OutputConfiguration {
|
|
||||||
writeOut?(str: string): void;
|
|
||||||
writeErr?(str: string): void;
|
|
||||||
getOutHelpWidth?(): number;
|
|
||||||
getErrHelpWidth?(): number;
|
|
||||||
outputError?(str: string, write: (str: string) => void): void;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AddHelpTextPosition = 'beforeAll' | 'before' | 'after' | 'afterAll';
|
|
||||||
export type HookEvent = 'preSubcommand' | 'preAction' | 'postAction';
|
|
||||||
// The source is a string so author can define their own too.
|
|
||||||
export type OptionValueSource = LiteralUnion<'default' | 'config' | 'env' | 'cli' | 'implied', string> | undefined;
|
|
||||||
|
|
||||||
export type OptionValues = Record<string, any>;
|
|
||||||
|
|
||||||
export class Command {
|
|
||||||
args: string[];
|
|
||||||
processedArgs: any[];
|
|
||||||
readonly commands: readonly Command[];
|
|
||||||
readonly options: readonly Option[];
|
|
||||||
readonly registeredArguments: readonly Argument[];
|
|
||||||
parent: Command | null;
|
|
||||||
|
|
||||||
constructor(name?: string);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the program version to `str`.
|
|
||||||
*
|
|
||||||
* This method auto-registers the "-V, --version" flag
|
|
||||||
* which will print the version number when passed.
|
|
||||||
*
|
|
||||||
* You can optionally supply the flags and description to override the defaults.
|
|
||||||
*/
|
|
||||||
version(str: string, flags?: string, description?: string): this;
|
|
||||||
/**
|
|
||||||
* Get the program version.
|
|
||||||
*/
|
|
||||||
version(): string | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a command, implemented using an action handler.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The command description is supplied using `.description`, not as a parameter to `.command`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* program
|
|
||||||
* .command('clone <source> [destination]')
|
|
||||||
* .description('clone a repository into a newly created directory')
|
|
||||||
* .action((source, destination) => {
|
|
||||||
* console.log('clone command called');
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @param nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
|
|
||||||
* @param opts - configuration options
|
|
||||||
* @returns new command
|
|
||||||
*/
|
|
||||||
command(nameAndArgs: string, opts?: CommandOptions): ReturnType<this['createCommand']>;
|
|
||||||
/**
|
|
||||||
* Define a command, implemented in a separate executable file.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The command description is supplied as the second parameter to `.command`.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* program
|
|
||||||
* .command('start <service>', 'start named service')
|
|
||||||
* .command('stop [service]', 'stop named service, or all if no name supplied');
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @param nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
|
|
||||||
* @param description - description of executable command
|
|
||||||
* @param opts - configuration options
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
command(nameAndArgs: string, description: string, opts?: ExecutableCommandOptions): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory routine to create a new unattached command.
|
|
||||||
*
|
|
||||||
* See .command() for creating an attached subcommand, which uses this routine to
|
|
||||||
* create the command. You can override createCommand to customise subcommands.
|
|
||||||
*/
|
|
||||||
createCommand(name?: string): Command;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a prepared subcommand.
|
|
||||||
*
|
|
||||||
* See .command() for creating an attached subcommand which inherits settings from its parent.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
addCommand(cmd: Command, opts?: CommandOptions): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory routine to create a new unattached argument.
|
|
||||||
*
|
|
||||||
* See .argument() for creating an attached argument, which uses this routine to
|
|
||||||
* create the argument. You can override createArgument to return a custom argument.
|
|
||||||
*/
|
|
||||||
createArgument(name: string, description?: string): Argument;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define argument syntax for command.
|
|
||||||
*
|
|
||||||
* The default is that the argument is required, and you can explicitly
|
|
||||||
* indicate this with <> around the name. Put [] around the name for an optional argument.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* program.argument('<input-file>');
|
|
||||||
* program.argument('[output-file]');
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
argument<T>(flags: string, description: string, fn: (value: string, previous: T) => T, defaultValue?: T): this;
|
|
||||||
argument(name: string, description?: string, defaultValue?: unknown): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define argument syntax for command, adding a prepared argument.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
addArgument(arg: Argument): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define argument syntax for command, adding multiple at once (without descriptions).
|
|
||||||
*
|
|
||||||
* See also .argument().
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* program.arguments('<cmd> [env]');
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
arguments(names: string): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override default decision whether to add implicit help command.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* addHelpCommand() // force on
|
|
||||||
* addHelpCommand(false); // force off
|
|
||||||
* addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom details
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
addHelpCommand(enableOrNameAndArgs?: string | boolean, description?: string): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add hook for life cycle event.
|
|
||||||
*/
|
|
||||||
hook(event: HookEvent, listener: (thisCommand: Command, actionCommand: Command) => void | Promise<void>): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register callback to use as replacement for calling process.exit.
|
|
||||||
*/
|
|
||||||
exitOverride(callback?: (err: CommanderError) => never | void): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display error message and exit (or call exitOverride).
|
|
||||||
*/
|
|
||||||
error(message: string, errorOptions?: ErrorOptions): never;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* You can customise the help with a subclass of Help by overriding createHelp,
|
|
||||||
* or by overriding Help properties using configureHelp().
|
|
||||||
*/
|
|
||||||
createHelp(): Help;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* You can customise the help by overriding Help properties using configureHelp(),
|
|
||||||
* or with a subclass of Help by overriding createHelp().
|
|
||||||
*/
|
|
||||||
configureHelp(configuration: HelpConfiguration): this;
|
|
||||||
/** Get configuration */
|
|
||||||
configureHelp(): HelpConfiguration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default output goes to stdout and stderr. You can customise this for special
|
|
||||||
* applications. You can also customise the display of errors by overriding outputError.
|
|
||||||
*
|
|
||||||
* The configuration properties are all functions:
|
|
||||||
* ```
|
|
||||||
* // functions to change where being written, stdout and stderr
|
|
||||||
* writeOut(str)
|
|
||||||
* writeErr(str)
|
|
||||||
* // matching functions to specify width for wrapping help
|
|
||||||
* getOutHelpWidth()
|
|
||||||
* getErrHelpWidth()
|
|
||||||
* // functions based on what is being written out
|
|
||||||
* outputError(str, write) // used for displaying errors, and not used for displaying help
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
configureOutput(configuration: OutputConfiguration): this;
|
|
||||||
/** Get configuration */
|
|
||||||
configureOutput(): OutputConfiguration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy settings that are useful to have in common across root command and subcommands.
|
|
||||||
*
|
|
||||||
* (Used internally when adding a command using `.command()` so subcommands inherit parent settings.)
|
|
||||||
*/
|
|
||||||
copyInheritedSettings(sourceCommand: Command): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the help or a custom message after an error occurs.
|
|
||||||
*/
|
|
||||||
showHelpAfterError(displayHelp?: boolean | string): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display suggestion of similar commands for unknown commands, or options for unknown options.
|
|
||||||
*/
|
|
||||||
showSuggestionAfterError(displaySuggestion?: boolean): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register callback `fn` for the command.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* program
|
|
||||||
* .command('serve')
|
|
||||||
* .description('start service')
|
|
||||||
* .action(function() {
|
|
||||||
* // do work here
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
action(fn: (...args: any[]) => void | Promise<void>): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define option with `flags`, `description`, and optional argument parsing function or `defaultValue` or both.
|
|
||||||
*
|
|
||||||
* The `flags` string contains the short and/or long flags, separated by comma, a pipe or space. A required
|
|
||||||
* option-argument is indicated by `<>` and an optional option-argument by `[]`.
|
|
||||||
*
|
|
||||||
* See the README for more details, and see also addOption() and requiredOption().
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
*
|
|
||||||
* ```js
|
|
||||||
* program
|
|
||||||
* .option('-p, --pepper', 'add pepper')
|
|
||||||
* .option('-p, --pizza-type <TYPE>', 'type of pizza') // required option-argument
|
|
||||||
* .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
|
|
||||||
* .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
option(flags: string, description?: string, defaultValue?: string | boolean | string[]): this;
|
|
||||||
option<T>(flags: string, description: string, parseArg: (value: string, previous: T) => T, defaultValue?: T): this;
|
|
||||||
/** @deprecated since v7, instead use choices or a custom function */
|
|
||||||
option(flags: string, description: string, regexp: RegExp, defaultValue?: string | boolean | string[]): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a required option, which must have a value after parsing. This usually means
|
|
||||||
* the option must be specified on the command line. (Otherwise the same as .option().)
|
|
||||||
*
|
|
||||||
* The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
|
|
||||||
*/
|
|
||||||
requiredOption(flags: string, description?: string, defaultValue?: string | boolean | string[]): this;
|
|
||||||
requiredOption<T>(flags: string, description: string, parseArg: (value: string, previous: T) => T, defaultValue?: T): this;
|
|
||||||
/** @deprecated since v7, instead use choices or a custom function */
|
|
||||||
requiredOption(flags: string, description: string, regexp: RegExp, defaultValue?: string | boolean | string[]): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory routine to create a new unattached option.
|
|
||||||
*
|
|
||||||
* See .option() for creating an attached option, which uses this routine to
|
|
||||||
* create the option. You can override createOption to return a custom option.
|
|
||||||
*/
|
|
||||||
|
|
||||||
createOption(flags: string, description?: string): Option;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a prepared Option.
|
|
||||||
*
|
|
||||||
* See .option() and .requiredOption() for creating and attaching an option in a single call.
|
|
||||||
*/
|
|
||||||
addOption(option: Option): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to store option values as properties on command object,
|
|
||||||
* or store separately (specify false). In both cases the option values can be accessed using .opts().
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
storeOptionsAsProperties<T extends OptionValues>(): this & T;
|
|
||||||
storeOptionsAsProperties<T extends OptionValues>(storeAsProperties: true): this & T;
|
|
||||||
storeOptionsAsProperties(storeAsProperties?: boolean): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve option value.
|
|
||||||
*/
|
|
||||||
getOptionValue(key: string): any;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store option value.
|
|
||||||
*/
|
|
||||||
setOptionValue(key: string, value: unknown): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store option value and where the value came from.
|
|
||||||
*/
|
|
||||||
setOptionValueWithSource(key: string, value: unknown, source: OptionValueSource): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get source of option value.
|
|
||||||
*/
|
|
||||||
getOptionValueSource(key: string): OptionValueSource | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get source of option value. See also .optsWithGlobals().
|
|
||||||
*/
|
|
||||||
getOptionValueSourceWithGlobals(key: string): OptionValueSource | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alter parsing of short flags with optional values.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* // for `.option('-f,--flag [value]'):
|
|
||||||
* .combineFlagAndOptionalValue(true) // `-f80` is treated like `--flag=80`, this is the default behaviour
|
|
||||||
* .combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
combineFlagAndOptionalValue(combine?: boolean): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow unknown options on the command line.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
allowUnknownOption(allowUnknown?: boolean): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
allowExcessArguments(allowExcess?: boolean): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable positional options. Positional means global options are specified before subcommands which lets
|
|
||||||
* subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
|
|
||||||
*
|
|
||||||
* The default behaviour is non-positional and global options may appear anywhere on the command line.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
enablePositionalOptions(positional?: boolean): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pass through options that come after command-arguments rather than treat them as command-options,
|
|
||||||
* so actual command-options come before command-arguments. Turning this on for a subcommand requires
|
|
||||||
* positional options to have been enabled on the program (parent commands).
|
|
||||||
*
|
|
||||||
* The default behaviour is non-positional and options may appear before or after command-arguments.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
passThroughOptions(passThrough?: boolean): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse `argv`, setting options and invoking commands when defined.
|
|
||||||
*
|
|
||||||
* The default expectation is that the arguments are from node and have the application as argv[0]
|
|
||||||
* and the script being run in argv[1], with user parameters after that.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* program.parse(process.argv);
|
|
||||||
* program.parse(); // implicitly use process.argv and auto-detect node vs electron conventions
|
|
||||||
* program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
parse(argv?: readonly string[], options?: ParseOptions): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse `argv`, setting options and invoking commands when defined.
|
|
||||||
*
|
|
||||||
* Use parseAsync instead of parse if any of your action handlers are async. Returns a Promise.
|
|
||||||
*
|
|
||||||
* The default expectation is that the arguments are from node and have the application as argv[0]
|
|
||||||
* and the script being run in argv[1], with user parameters after that.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```
|
|
||||||
* program.parseAsync(process.argv);
|
|
||||||
* program.parseAsync(); // implicitly use process.argv and auto-detect node vs electron conventions
|
|
||||||
* program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns Promise
|
|
||||||
*/
|
|
||||||
parseAsync(argv?: readonly string[], options?: ParseOptions): Promise<this>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse options from `argv` removing known options,
|
|
||||||
* and return argv split into operands and unknown arguments.
|
|
||||||
*
|
|
||||||
* argv => operands, unknown
|
|
||||||
* --known kkk op => [op], []
|
|
||||||
* op --known kkk => [op], []
|
|
||||||
* sub --unknown uuu op => [sub], [--unknown uuu op]
|
|
||||||
* sub -- --unknown uuu op => [sub --unknown uuu op], []
|
|
||||||
*/
|
|
||||||
parseOptions(argv: string[]): ParseOptionsResult;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an object containing local option values as key-value pairs
|
|
||||||
*/
|
|
||||||
opts<T extends OptionValues>(): T;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an object containing merged local and global option values as key-value pairs.
|
|
||||||
*/
|
|
||||||
optsWithGlobals<T extends OptionValues>(): T;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the description.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
|
|
||||||
description(str: string): this;
|
|
||||||
/** @deprecated since v8, instead use .argument to add command argument with description */
|
|
||||||
description(str: string, argsDescription: Record<string, string>): this;
|
|
||||||
/**
|
|
||||||
* Get the description.
|
|
||||||
*/
|
|
||||||
description(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the summary. Used when listed as subcommand of parent.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
|
|
||||||
summary(str: string): this;
|
|
||||||
/**
|
|
||||||
* Get the summary.
|
|
||||||
*/
|
|
||||||
summary(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an alias for the command.
|
|
||||||
*
|
|
||||||
* You may call more than once to add multiple aliases. Only the first alias is shown in the auto-generated help.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
alias(alias: string): this;
|
|
||||||
/**
|
|
||||||
* Get alias for the command.
|
|
||||||
*/
|
|
||||||
alias(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set aliases for the command.
|
|
||||||
*
|
|
||||||
* Only the first alias is shown in the auto-generated help.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
aliases(aliases: readonly string[]): this;
|
|
||||||
/**
|
|
||||||
* Get aliases for the command.
|
|
||||||
*/
|
|
||||||
aliases(): string[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the command usage.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
usage(str: string): this;
|
|
||||||
/**
|
|
||||||
* Get the command usage.
|
|
||||||
*/
|
|
||||||
usage(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the name of the command.
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
name(str: string): this;
|
|
||||||
/**
|
|
||||||
* Get the name of the command.
|
|
||||||
*/
|
|
||||||
name(): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the name of the command from script filename, such as process.argv[1],
|
|
||||||
* or require.main.filename, or __filename.
|
|
||||||
*
|
|
||||||
* (Used internally and public although not documented in README.)
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* program.nameFromFilename(require.main.filename);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
nameFromFilename(filename: string): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the directory for searching for executable subcommands of this command.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* program.executableDir(__dirname);
|
|
||||||
* // or
|
|
||||||
* program.executableDir('subcommands');
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @returns `this` command for chaining
|
|
||||||
*/
|
|
||||||
executableDir(path: string): this;
|
|
||||||
/**
|
|
||||||
* Get the executable search directory.
|
|
||||||
*/
|
|
||||||
executableDir(): string | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Output help information for this command.
|
|
||||||
*
|
|
||||||
* Outputs built-in help, and custom text added using `.addHelpText()`.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
outputHelp(context?: HelpContext): void;
|
|
||||||
/** @deprecated since v7 */
|
|
||||||
outputHelp(cb?: (str: string) => string): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return command help documentation.
|
|
||||||
*/
|
|
||||||
helpInformation(context?: HelpContext): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* You can pass in flags and a description to override the help
|
|
||||||
* flags and help description for your command. Pass in false
|
|
||||||
* to disable the built-in help option.
|
|
||||||
*/
|
|
||||||
helpOption(flags?: string | boolean, description?: string): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Output help information and exit.
|
|
||||||
*
|
|
||||||
* Outputs built-in help, and custom text added using `.addHelpText()`.
|
|
||||||
*/
|
|
||||||
help(context?: HelpContext): never;
|
|
||||||
/** @deprecated since v7 */
|
|
||||||
help(cb?: (str: string) => string): never;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add additional text to be displayed with the built-in help.
|
|
||||||
*
|
|
||||||
* Position is 'before' or 'after' to affect just this command,
|
|
||||||
* and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.
|
|
||||||
*/
|
|
||||||
addHelpText(position: AddHelpTextPosition, text: string): this;
|
|
||||||
addHelpText(position: AddHelpTextPosition, text: (context: AddHelpTextContext) => string): this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a listener (callback) for when events occur. (Implemented using EventEmitter.)
|
|
||||||
*/
|
|
||||||
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CommandOptions {
|
|
||||||
hidden?: boolean;
|
|
||||||
isDefault?: boolean;
|
|
||||||
/** @deprecated since v7, replaced by hidden */
|
|
||||||
noHelp?: boolean;
|
|
||||||
}
|
|
||||||
export interface ExecutableCommandOptions extends CommandOptions {
|
|
||||||
executableFile?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ParseOptionsResult {
|
|
||||||
operands: string[];
|
|
||||||
unknown: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createCommand(name?: string): Command;
|
|
||||||
export function createOption(flags: string, description?: string): Option;
|
|
||||||
export function createArgument(name: string, description?: string): Argument;
|
|
||||||
|
|
||||||
export const program: Command;
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Sim Studio CLI
|
# Sim Studio
|
||||||
|
|
||||||
A command-line interface for Sim Studio - a powerful, user-friendly platform for building, testing, and optimizing agentic workflows.
|
A command-line interface for Sim Studio - a powerful, user-friendly platform for building, testing, and optimizing agentic workflows.
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ All your data is stored in your browser's localStorage, so you can close the app
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
To contribute to the development of Sim Studio CLI:
|
To contribute to the development of Sim Studio:
|
||||||
|
|
||||||
1. Clone the repository
|
1. Clone the repository
|
||||||
2. Install dependencies with `npm install`
|
2. Install dependencies with `npm install`
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@simstudio/cli",
|
"name": "@simstudio/cli",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@simstudio/cli",
|
"name": "@simstudio/cli",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
"conf": "^10.2.0",
|
"conf": "^10.2.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"inquirer": "^8.2.6",
|
"inquirer": "^8.2.6",
|
||||||
|
"open": "^10.1.0",
|
||||||
"tar": "^6.2.1",
|
"tar": "^6.2.1",
|
||||||
"update-notifier": "^5.1.0"
|
"update-notifier": "^5.1.0"
|
||||||
},
|
},
|
||||||
@@ -541,6 +542,21 @@
|
|||||||
"ieee754": "^1.1.13"
|
"ieee754": "^1.1.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bundle-name": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"run-applescript": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cacheable-request": {
|
"node_modules/cacheable-request": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
|
||||||
@@ -841,6 +857,34 @@
|
|||||||
"node": ">=4.0.0"
|
"node": ">=4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/default-browser": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bundle-name": "^4.1.0",
|
||||||
|
"default-browser-id": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/default-browser-id": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/defaults": {
|
"node_modules/defaults": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
|
||||||
@@ -859,6 +903,18 @@
|
|||||||
"integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
|
"integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/define-lazy-prop": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/diff": {
|
"node_modules/diff": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||||
@@ -1281,6 +1337,21 @@
|
|||||||
"is-ci": "bin.js"
|
"is-ci": "bin.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-docker": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"is-docker": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-fullwidth-code-point": {
|
"node_modules/is-fullwidth-code-point": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||||
@@ -1290,6 +1361,24 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-inside-container": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-docker": "^3.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"is-inside-container": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-installed-globally": {
|
"node_modules/is-installed-globally": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz",
|
||||||
@@ -1363,6 +1452,21 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-wsl": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-inside-container": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-yarn-global": {
|
"node_modules/is-yarn-global": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
|
||||||
@@ -1651,6 +1755,24 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/open": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"default-browser": "^5.2.1",
|
||||||
|
"define-lazy-prop": "^3.0.0",
|
||||||
|
"is-inside-container": "^1.0.0",
|
||||||
|
"is-wsl": "^3.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ora": {
|
"node_modules/ora": {
|
||||||
"version": "5.4.1",
|
"version": "5.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
|
||||||
@@ -1954,6 +2076,18 @@
|
|||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/run-applescript": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/run-async": {
|
"node_modules/run-async": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@simstudio/cli",
|
"name": "simstudio",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"description": "CLI tool for Sim Studio - easily start, build and test agent workflows",
|
"description": "CLI tool for Sim Studio - easily start, build and test agent workflows",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Sim Studio Team",
|
"author": "Sim Studio Team",
|
||||||
@@ -12,8 +12,7 @@
|
|||||||
"files": [
|
"files": [
|
||||||
"bin",
|
"bin",
|
||||||
"dist",
|
"dist",
|
||||||
"README.md",
|
"README.md"
|
||||||
"standalone"
|
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
@@ -21,7 +20,7 @@
|
|||||||
"dev": "ts-node src/index.ts",
|
"dev": "ts-node src/index.ts",
|
||||||
"clean": "rimraf dist",
|
"clean": "rimraf dist",
|
||||||
"prepublishOnly": "npm run clean && npm run build && npm run prepare-standalone && echo 'Checking for sensitive files...' && (! find . -name '.env*' -not -path '*/node_modules/*' -not -path '*/standalone/*' | grep -q .)",
|
"prepublishOnly": "npm run clean && npm run build && npm run prepare-standalone && echo 'Checking for sensitive files...' && (! find . -name '.env*' -not -path '*/node_modules/*' -not -path '*/standalone/*' | grep -q .)",
|
||||||
"prepare-standalone": "node ../../../scripts/build-standalone.js"
|
"prepare-standalone": "node ../../scripts/build-standalone.js"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"sim",
|
"sim",
|
||||||
@@ -39,6 +38,7 @@
|
|||||||
"conf": "^10.2.0",
|
"conf": "^10.2.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"inquirer": "^8.2.6",
|
"inquirer": "^8.2.6",
|
||||||
|
"open": "^10.1.0",
|
||||||
"tar": "^6.2.1",
|
"tar": "^6.2.1",
|
||||||
"update-notifier": "^5.1.0"
|
"update-notifier": "^5.1.0"
|
||||||
},
|
},
|
||||||
@@ -61,8 +61,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/simstudioai/sim/issues"
|
"url": "https://github.com/simstudioai/sim/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/simstudioai/sim#readme",
|
"homepage": "https://github.com/simstudioai/sim#readme"
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,7 @@ import { SimpleSpinner, createSpinner } from '../utils/spinner'
|
|||||||
interface StartOptions {
|
interface StartOptions {
|
||||||
port: string
|
port: string
|
||||||
debug: boolean
|
debug: boolean
|
||||||
|
noOpen?: boolean // Add option to not open browser
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constants for standalone app
|
// Constants for standalone app
|
||||||
@@ -45,6 +46,8 @@ export async function start(options: StartOptions) {
|
|||||||
USE_LOCAL_STORAGE: 'true', // Key environment variable to switch to local storage
|
USE_LOCAL_STORAGE: 'true', // Key environment variable to switch to local storage
|
||||||
NEXT_PUBLIC_USE_LOCAL_STORAGE: 'true', // For client-side code
|
NEXT_PUBLIC_USE_LOCAL_STORAGE: 'true', // For client-side code
|
||||||
DISABLE_DB_SYNC: 'true', // Disable database sync
|
DISABLE_DB_SYNC: 'true', // Disable database sync
|
||||||
|
DISABLE_AUTH: 'true', // Disable authentication
|
||||||
|
NEXT_PUBLIC_DISABLE_AUTH: 'true', // For client-side authentication check
|
||||||
NODE_ENV: debug ? 'development' : ('production' as const),
|
NODE_ENV: debug ? 'development' : ('production' as const),
|
||||||
DEBUG: debug ? '*' : undefined,
|
DEBUG: debug ? '*' : undefined,
|
||||||
}
|
}
|
||||||
@@ -171,9 +174,29 @@ export async function start(options: StartOptions) {
|
|||||||
console.log(`
|
console.log(`
|
||||||
${chalk.green('✓')} Using local storage mode - your data will be stored in the browser
|
${chalk.green('✓')} Using local storage mode - your data will be stored in the browser
|
||||||
${chalk.green('✓')} Any changes will be persisted between sessions through localStorage
|
${chalk.green('✓')} Any changes will be persisted between sessions through localStorage
|
||||||
|
${chalk.green('✓')} Authentication is disabled - you have immediate access to all features
|
||||||
|
${chalk.yellow('i')} Navigate to ${chalk.cyan(`http://localhost:${port}/w`)} to create a new workflow
|
||||||
${chalk.yellow('i')} Press ${chalk.bold('Ctrl+C')} to stop the server
|
${chalk.yellow('i')} Press ${chalk.bold('Ctrl+C')} to stop the server
|
||||||
`)
|
`)
|
||||||
|
|
||||||
|
// Auto-open browser to workflow page
|
||||||
|
if (!options.noOpen) {
|
||||||
|
try {
|
||||||
|
// Dynamically import open to avoid adding it as a dependency for production builds
|
||||||
|
const open = await import('open').then((m) => m.default)
|
||||||
|
|
||||||
|
// Wait a short time for the server to fully start
|
||||||
|
setTimeout(() => {
|
||||||
|
open(`http://localhost:${port}/w`)
|
||||||
|
console.log(`${chalk.green('✓')} Opened browser to workflow canvas`)
|
||||||
|
}, 1000)
|
||||||
|
} catch (error) {
|
||||||
|
console.log(
|
||||||
|
`${chalk.yellow('i')} Could not automatically open browser. Please navigate to ${chalk.cyan(`http://localhost:${port}/w`)} manually.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle process termination
|
// Handle process termination
|
||||||
process.on('SIGINT', () => {
|
process.on('SIGINT', () => {
|
||||||
console.log(`\n${chalk.yellow('⚠️')} Shutting down Sim Studio...`)
|
console.log(`\n${chalk.yellow('⚠️')} Shutting down Sim Studio...`)
|
||||||
@@ -18,7 +18,7 @@ const crypto = require('crypto')
|
|||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
const ROOT_DIR = path.resolve(__dirname, '..')
|
const ROOT_DIR = path.resolve(__dirname, '..')
|
||||||
const STANDALONE_DIR = path.join(ROOT_DIR, 'packages/@simstudio/cli/standalone')
|
const STANDALONE_DIR = path.join(ROOT_DIR, 'packages/simstudio/standalone')
|
||||||
const STANDALONE_PACKAGE_JSON = path.join(STANDALONE_DIR, 'package.json')
|
const STANDALONE_PACKAGE_JSON = path.join(STANDALONE_DIR, 'package.json')
|
||||||
const STANDALONE_SERVER_JS = path.join(STANDALONE_DIR, 'server.js')
|
const STANDALONE_SERVER_JS = path.join(STANDALONE_DIR, 'server.js')
|
||||||
const OUTPUT_TARBALL = path.join(ROOT_DIR, 'sim-standalone.tar.gz')
|
const OUTPUT_TARBALL = path.join(ROOT_DIR, 'sim-standalone.tar.gz')
|
||||||
|
|||||||
Reference in New Issue
Block a user