update
This commit is contained in:
21
node_modules/concurrently/LICENSE
generated
vendored
Normal file
21
node_modules/concurrently/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Kimmo Brunfeldt
|
||||
|
||||
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.
|
229
node_modules/concurrently/README.md
generated
vendored
Normal file
229
node_modules/concurrently/README.md
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
# concurrently
|
||||
|
||||
[](https://github.com/open-cli-tools/concurrently/releases)
|
||||
[](https://github.com/open-cli-tools/concurrently/blob/main/LICENSE)
|
||||
[](https://www.npmjs.com/package/concurrently)
|
||||
[](https://github.com/open-cli-tools/concurrently/actions/workflows/test.yml)
|
||||
[](https://coveralls.io/github/open-cli-tools/concurrently?branch=main)
|
||||
|
||||
Run multiple commands concurrently.
|
||||
Like `npm run watch-js & npm run watch-less` but better.
|
||||
|
||||

|
||||
|
||||
**Table of Contents**
|
||||
|
||||
- [concurrently](#concurrently)
|
||||
- [Why](#why)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [API](#api)
|
||||
- [`concurrently(commands[, options])`](#concurrentlycommands-options)
|
||||
- [`Command`](#command)
|
||||
- [`CloseEvent`](#closeevent)
|
||||
- [FAQ](#faq)
|
||||
|
||||
## Why
|
||||
|
||||
I like [task automation with npm](https://web.archive.org/web/20220531064025/https://github.com/substack/blog/blob/master/npm_run.markdown)
|
||||
but the usual way to run multiple commands concurrently is
|
||||
`npm run watch-js & npm run watch-css`. That's fine but it's hard to keep
|
||||
on track of different outputs. Also if one process fails, others still keep running
|
||||
and you won't even notice the difference.
|
||||
|
||||
Another option would be to just run all commands in separate terminals. I got
|
||||
tired of opening terminals and made **concurrently**.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Cross platform (including Windows)
|
||||
- Output is easy to follow with prefixes
|
||||
- With `--kill-others` switch, all commands are killed if one dies
|
||||
|
||||
## Installation
|
||||
|
||||
**concurrently** can be installed in the global scope (if you'd like to have it available and use it on the whole system) or locally for a specific package (for example if you'd like to use it in the `scripts` section of your package):
|
||||
|
||||
| | npm | Yarn | pnpm | Bun |
|
||||
| ----------- | ----------------------- | ------------------------------ | -------------------------- | ------------------------- |
|
||||
| **Global** | `npm i -g concurrently` | `yarn global add concurrently` | `pnpm add -g concurrently` | `bun add -g concurrently` |
|
||||
| **Local**\* | `npm i -D concurrently` | `yarn add -D concurrently` | `pnpm add -D concurrently` | `bun add -d concurrently` |
|
||||
|
||||
<sub>\* It's recommended to add **concurrently** to `devDependencies` as it's usually used for developing purposes. Please adjust the command if this doesn't apply in your case.</sub>
|
||||
|
||||
## Usage
|
||||
|
||||
> **Note**
|
||||
> The `concurrently` command is also available under the shorthand alias `conc`.
|
||||
|
||||
The tool is written in Node.js, but you can use it to run **any** commands.
|
||||
|
||||
Remember to surround separate commands with quotes:
|
||||
|
||||
```bash
|
||||
concurrently "command1 arg" "command2 arg"
|
||||
```
|
||||
|
||||
Otherwise **concurrently** would try to run 4 separate commands:
|
||||
`command1`, `arg`, `command2`, `arg`.
|
||||
|
||||
In package.json, escape quotes:
|
||||
|
||||
```bash
|
||||
"start": "concurrently \"command1 arg\" \"command2 arg\""
|
||||
```
|
||||
|
||||
You can always check concurrently's flag list by running `concurrently --help`.
|
||||
For the version, run `concurrently --version`.
|
||||
|
||||
Check out documentation and other usage examples in the [`docs` directory](./docs/README.md).
|
||||
|
||||
## API
|
||||
|
||||
**concurrently** can be used programmatically by using the API documented below:
|
||||
|
||||
### `concurrently(commands[, options])`
|
||||
|
||||
- `commands`: an array of either strings (containing the commands to run) or objects
|
||||
with the shape `{ command, name, prefixColor, env, cwd, ipc }`.
|
||||
|
||||
- `options` (optional): an object containing any of the below:
|
||||
- `cwd`: the working directory to be used by all commands. Can be overriden per command.
|
||||
Default: `process.cwd()`.
|
||||
- `defaultInputTarget`: the default input target when reading from `inputStream`.
|
||||
Default: `0`.
|
||||
- `handleInput`: when `true`, reads input from `process.stdin`.
|
||||
- `inputStream`: a [`Readable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_readable_streams)
|
||||
to read the input from. Should only be used in the rare instance you would like to stream anything other than `process.stdin`. Overrides `handleInput`.
|
||||
- `pauseInputStreamOnFinish`: by default, pauses the input stream (`process.stdin` when `handleInput` is enabled, or `inputStream` if provided) when all of the processes have finished. If you need to read from the input stream after `concurrently` has finished, set this to `false`. ([#252](https://github.com/kimmobrunfeldt/concurrently/issues/252)).
|
||||
- `killOthers`: an array of exitting conditions that will cause a process to kill others.
|
||||
Can contain any of `success` or `failure`.
|
||||
- `maxProcesses`: how many processes should run at once.
|
||||
- `outputStream`: a [`Writable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_writable_streams)
|
||||
to write logs to. Default: `process.stdout`.
|
||||
- `prefix`: the prefix type to use when logging processes output.
|
||||
Possible values: `index`, `pid`, `time`, `command`, `name`, `none`, or a template (eg `[{time} process: {pid}]`).
|
||||
Default: the name of the process, or its index if no name is set.
|
||||
- `prefixColors`: a list of colors or a string as supported by [chalk](https://www.npmjs.com/package/chalk) and additional style `auto` for an automatically picked color.
|
||||
If concurrently would run more commands than there are colors, the last color is repeated, unless if the last color value is `auto` which means following colors are automatically picked to vary.
|
||||
Prefix colors specified per-command take precedence over this list.
|
||||
- `prefixLength`: how many characters to show when prefixing with `command`. Default: `10`
|
||||
- `raw`: whether raw mode should be used, meaning strictly process output will
|
||||
be logged, without any prefixes, coloring or extra stuff. Can be overriden per command.
|
||||
- `successCondition`: the condition to consider the run was successful.
|
||||
If `first`, only the first process to exit will make up the success of the run; if `last`, the last process that exits will determine whether the run succeeds.
|
||||
Anything else means all processes should exit successfully.
|
||||
- `restartTries`: how many attempts to restart a process that dies will be made. Default: `0`.
|
||||
- `restartDelay`: how many milliseconds to wait between process restarts. Default: `0`.
|
||||
- `timestampFormat`: a [Unicode format](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table)
|
||||
to use when prefixing with `time`. Default: `yyyy-MM-dd HH:mm:ss.ZZZ`
|
||||
- `additionalArguments`: list of additional arguments passed that will get replaced in each command. If not defined, no argument replacing will happen.
|
||||
|
||||
> **Returns:** an object in the shape `{ result, commands }`.
|
||||
>
|
||||
> - `result`: a `Promise` that resolves if the run was successful (according to `successCondition` option),
|
||||
> or rejects, containing an array of [`CloseEvent`](#CloseEvent), in the order that the commands terminated.
|
||||
> - `commands`: an array of all spawned [`Command`s](#Command).
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
const concurrently = require('concurrently');
|
||||
const { result } = concurrently(
|
||||
[
|
||||
'npm:watch-*',
|
||||
{ command: 'nodemon', name: 'server' },
|
||||
{ command: 'deploy', name: 'deploy', env: { PUBLIC_KEY: '...' } },
|
||||
{
|
||||
command: 'watch',
|
||||
name: 'watch',
|
||||
cwd: path.resolve(__dirname, 'scripts/watchers'),
|
||||
},
|
||||
],
|
||||
{
|
||||
prefix: 'name',
|
||||
killOthers: ['failure', 'success'],
|
||||
restartTries: 3,
|
||||
cwd: path.resolve(__dirname, 'scripts'),
|
||||
},
|
||||
);
|
||||
result.then(success, failure);
|
||||
```
|
||||
|
||||
### `Command`
|
||||
|
||||
An object that contains all information about a spawned command, and ways to interact with it.<br>
|
||||
It has the following properties:
|
||||
|
||||
- `index`: the index of the command among all commands spawned.
|
||||
- `command`: the command line of the command.
|
||||
- `name`: the name of the command; defaults to an empty string.
|
||||
- `cwd`: the current working directory of the command.
|
||||
- `env`: an object with all the environment variables that the command will be spawned with.
|
||||
- `killed`: whether the command has been killed.
|
||||
- `state`: the command's state. Can be one of
|
||||
- `stopped`: if the command was never started
|
||||
- `started`: if the command is currently running
|
||||
- `errored`: if the command failed spawning
|
||||
- `exited`: if the command is not running anymore, e.g. it received a close event
|
||||
- `pid`: the command's process ID.
|
||||
- `stdin`: a Writable stream to the command's `stdin`.
|
||||
- `stdout`: an RxJS observable to the command's `stdout`.
|
||||
- `stderr`: an RxJS observable to the command's `stderr`.
|
||||
- `error`: an RxJS observable to the command's error events (e.g. when it fails to spawn).
|
||||
- `timer`: an RxJS observable to the command's timing events (e.g. starting, stopping).
|
||||
- `messages`: an object with the following properties:
|
||||
|
||||
- `incoming`: an RxJS observable for the IPC messages received from the underlying process.
|
||||
- `outgoing`: an RxJS observable for the IPC messages sent to the underlying process.
|
||||
|
||||
Both observables emit [`MessageEvent`](#messageevent)s.<br>
|
||||
Note that if the command wasn't spawned with IPC support, these won't emit any values.
|
||||
|
||||
- `close`: an RxJS observable to the command's close events.
|
||||
See [`CloseEvent`](#CloseEvent) for more information.
|
||||
- `start()`: starts the command and sets up all of the above streams
|
||||
- `send(message[, handle, options])`: sends a message to the underlying process via IPC channels,
|
||||
returning a promise that resolves once the message has been sent.
|
||||
See [Node.js docs](https://nodejs.org/docs/latest/api/child_process.html#subprocesssendmessage-sendhandle-options-callback).
|
||||
- `kill([signal])`: kills the command, optionally specifying a signal (e.g. `SIGTERM`, `SIGKILL`, etc).
|
||||
|
||||
### `MessageEvent`
|
||||
|
||||
An object that represents a message that was received from/sent to the underlying command process.<br>
|
||||
It has the following properties:
|
||||
|
||||
- `message`: the message itself.
|
||||
- `handle`: a [`net.Socket`](https://nodejs.org/docs/latest/api/net.html#class-netsocket),
|
||||
[`net.Server`](https://nodejs.org/docs/latest/api/net.html#class-netserver) or
|
||||
[`dgram.Socket`](https://nodejs.org/docs/latest/api/dgram.html#class-dgramsocket),
|
||||
if one was sent, or `undefined`.
|
||||
|
||||
### `CloseEvent`
|
||||
|
||||
An object with information about a command's closing event.<br>
|
||||
It contains the following properties:
|
||||
|
||||
- `command`: a stripped down version of [`Command`](#command), including only `name`, `command`, `env` and `cwd` properties.
|
||||
- `index`: the index of the command among all commands spawned.
|
||||
- `killed`: whether the command exited because it was killed.
|
||||
- `exitCode`: the exit code of the command's process, or the signal which it was killed with.
|
||||
- `timings`: an object in the shape `{ startDate, endDate, durationSeconds }`.
|
||||
|
||||
## FAQ
|
||||
|
||||
- Process exited with code _null_?
|
||||
|
||||
From [Node child_process documentation](http://nodejs.org/api/child_process.html#child_process_event_exit), `exit` event:
|
||||
|
||||
> This event is emitted after the child process ends. If the process
|
||||
> terminated normally, code is the final exit code of the process,
|
||||
> otherwise null. If the process terminated due to receipt of a signal,
|
||||
> signal is the string name of the signal, otherwise null.
|
||||
|
||||
So _null_ means the process didn't terminate normally. This will make **concurrently**
|
||||
to return non-zero exit code too.
|
||||
|
||||
- Does this work with the npm-replacements [yarn](https://github.com/yarnpkg/yarn), [pnpm](https://pnpm.js.org/), or [Bun](https://bun.sh/)?
|
||||
|
||||
Yes! In all examples above, you may replace "`npm`" with "`yarn`", "`pnpm`", or "`bun`".
|
2
node_modules/concurrently/dist/bin/concurrently.d.ts
generated
vendored
Normal file
2
node_modules/concurrently/dist/bin/concurrently.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env node
|
||||
export {};
|
251
node_modules/concurrently/dist/bin/concurrently.js
generated
vendored
Normal file
251
node_modules/concurrently/dist/bin/concurrently.js
generated
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
#!/usr/bin/env node
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const lodash_1 = __importDefault(require("lodash"));
|
||||
const yargs_1 = __importDefault(require("yargs"));
|
||||
const helpers_1 = require("yargs/helpers");
|
||||
const defaults = __importStar(require("../src/defaults"));
|
||||
const index_1 = require("../src/index");
|
||||
const read_package_1 = require("./read-package");
|
||||
const version = String((0, read_package_1.readPackage)().version);
|
||||
const epilogue = `For documentation and more examples, visit:\nhttps://github.com/open-cli-tools/concurrently/tree/v${version}/docs`;
|
||||
// Clean-up arguments (yargs expects only the arguments after the program name)
|
||||
const program = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
||||
.parserConfiguration({
|
||||
// Avoids options that can be specified multiple times from requiring a `--` to pass commands
|
||||
'greedy-arrays': false,
|
||||
// Makes sure that --passthrough-arguments works correctly
|
||||
'populate--': true,
|
||||
})
|
||||
.usage('$0 [options] <command ...>')
|
||||
.help('h')
|
||||
.alias('h', 'help')
|
||||
.version(version)
|
||||
.alias('version', 'v')
|
||||
.alias('version', 'V')
|
||||
// TODO: Add some tests for this.
|
||||
.env('CONCURRENTLY')
|
||||
.options({
|
||||
// General
|
||||
'max-processes': {
|
||||
alias: 'm',
|
||||
describe: 'How many processes should run at once.\n' +
|
||||
'New processes only spawn after all restart tries of a process.\n' +
|
||||
'Exact number or a percent of CPUs available (for example "50%")',
|
||||
type: 'string',
|
||||
},
|
||||
names: {
|
||||
alias: 'n',
|
||||
describe: 'List of custom names to be used in prefix template.\n' +
|
||||
'Example names: "main,browser,server"',
|
||||
type: 'string',
|
||||
},
|
||||
'name-separator': {
|
||||
describe: 'The character to split <names> on. Example usage:\n' +
|
||||
'-n "styles|scripts|server" --name-separator "|"',
|
||||
default: defaults.nameSeparator,
|
||||
},
|
||||
success: {
|
||||
alias: 's',
|
||||
describe: 'Which command(s) must exit with code 0 in order for concurrently exit with ' +
|
||||
'code 0 too. Options are:\n' +
|
||||
'- "first" for the first command to exit;\n' +
|
||||
'- "last" for the last command to exit;\n' +
|
||||
'- "all" for all commands;\n' +
|
||||
// Note: not a typo. Multiple commands can have the same name.
|
||||
'- "command-{name}"/"command-{index}" for the commands with that name or index;\n' +
|
||||
'- "!command-{name}"/"!command-{index}" for all commands but the ones with that ' +
|
||||
'name or index.\n',
|
||||
default: defaults.success,
|
||||
},
|
||||
raw: {
|
||||
alias: 'r',
|
||||
describe: 'Output only raw output of processes, disables prettifying ' +
|
||||
'and concurrently coloring.',
|
||||
type: 'boolean',
|
||||
},
|
||||
// This one is provided for free. Chalk reads this itself and removes colors.
|
||||
// https://www.npmjs.com/package/chalk#chalksupportscolor
|
||||
'no-color': {
|
||||
describe: 'Disables colors from logging',
|
||||
type: 'boolean',
|
||||
},
|
||||
hide: {
|
||||
describe: 'Comma-separated list of processes to hide the output.\n' +
|
||||
'The processes can be identified by their name or index.',
|
||||
default: defaults.hide,
|
||||
type: 'string',
|
||||
},
|
||||
group: {
|
||||
alias: 'g',
|
||||
describe: 'Order the output as if the commands were run sequentially.',
|
||||
type: 'boolean',
|
||||
},
|
||||
timings: {
|
||||
describe: 'Show timing information for all processes.',
|
||||
type: 'boolean',
|
||||
default: defaults.timings,
|
||||
},
|
||||
'passthrough-arguments': {
|
||||
alias: 'P',
|
||||
describe: 'Passthrough additional arguments to commands (accessible via placeholders) ' +
|
||||
'instead of treating them as commands.',
|
||||
type: 'boolean',
|
||||
default: defaults.passthroughArguments,
|
||||
},
|
||||
teardown: {
|
||||
describe: 'Clean up command(s) to execute before exiting concurrently. Might be specified multiple times.\n' +
|
||||
"These aren't prefixed and they don't affect concurrently's exit code.",
|
||||
type: 'string',
|
||||
array: true,
|
||||
},
|
||||
// Kill others
|
||||
'kill-others': {
|
||||
alias: 'k',
|
||||
describe: 'Kill other processes if one exits or dies.',
|
||||
type: 'boolean',
|
||||
},
|
||||
'kill-others-on-fail': {
|
||||
describe: 'Kill other processes if one exits with non zero status code.',
|
||||
type: 'boolean',
|
||||
},
|
||||
'kill-signal': {
|
||||
alias: 'ks',
|
||||
describe: 'Signal to send to other processes if one exits or dies. (SIGTERM/SIGKILL, defaults to SIGTERM)',
|
||||
type: 'string',
|
||||
default: defaults.killSignal,
|
||||
},
|
||||
// Prefix
|
||||
prefix: {
|
||||
alias: 'p',
|
||||
describe: 'Prefix used in logging for each process.\n' +
|
||||
'Possible values: index, pid, time, command, name, none, or a template. ' +
|
||||
'Example template: "{time}-{pid}"',
|
||||
defaultDescription: 'index or name (when --names is set)',
|
||||
type: 'string',
|
||||
},
|
||||
'prefix-colors': {
|
||||
alias: 'c',
|
||||
describe: 'Comma-separated list of chalk colors to use on prefixes. ' +
|
||||
'If there are more commands than colors, the last color will be repeated.\n' +
|
||||
'- Available modifiers: reset, bold, dim, italic, underline, inverse, hidden, strikethrough\n' +
|
||||
'- Available colors: black, red, green, yellow, blue, magenta, cyan, white, gray, \n' +
|
||||
'any hex values for colors (e.g. #23de43) or auto for an automatically picked color\n' +
|
||||
'- Available background colors: bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite\n' +
|
||||
'See https://www.npmjs.com/package/chalk for more information.',
|
||||
default: defaults.prefixColors,
|
||||
type: 'string',
|
||||
},
|
||||
'prefix-length': {
|
||||
alias: 'l',
|
||||
describe: 'Limit how many characters of the command is displayed in prefix. ' +
|
||||
'The option can be used to shorten the prefix when it is set to "command"',
|
||||
default: defaults.prefixLength,
|
||||
type: 'number',
|
||||
},
|
||||
'pad-prefix': {
|
||||
describe: 'Pads short prefixes with spaces so that the length of all prefixes match',
|
||||
type: 'boolean',
|
||||
},
|
||||
'timestamp-format': {
|
||||
alias: 't',
|
||||
describe: 'Specify the timestamp in Unicode format:\n' +
|
||||
'https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table',
|
||||
default: defaults.timestampFormat,
|
||||
type: 'string',
|
||||
},
|
||||
// Restarting
|
||||
'restart-tries': {
|
||||
describe: 'How many times a process that died should restart.\n' +
|
||||
'Negative numbers will make the process restart forever.',
|
||||
default: defaults.restartTries,
|
||||
type: 'number',
|
||||
},
|
||||
'restart-after': {
|
||||
describe: 'Delay before restarting the process, in milliseconds, or "exponential".',
|
||||
default: defaults.restartDelay,
|
||||
type: 'string',
|
||||
},
|
||||
// Input
|
||||
'handle-input': {
|
||||
alias: 'i',
|
||||
describe: 'Whether input should be forwarded to the child processes. ' +
|
||||
'See examples for more information.',
|
||||
type: 'boolean',
|
||||
},
|
||||
'default-input-target': {
|
||||
default: defaults.defaultInputTarget,
|
||||
describe: 'Identifier for child process to which input on stdin ' +
|
||||
'should be sent if not specified at start of input.\n' +
|
||||
'Can be either the index or the name of the process.',
|
||||
},
|
||||
})
|
||||
.group(['m', 'n', 'name-separator', 's', 'r', 'no-color', 'hide', 'g', 'timings', 'P', 'teardown'], 'General')
|
||||
.group(['p', 'c', 'l', 't', 'pad-prefix'], 'Prefix styling')
|
||||
.group(['i', 'default-input-target'], 'Input handling')
|
||||
.group(['k', 'kill-others-on-fail', 'kill-signal'], 'Killing other processes')
|
||||
.group(['restart-tries', 'restart-after'], 'Restarting')
|
||||
.epilogue(epilogue);
|
||||
const args = program.parseSync();
|
||||
// Get names of commands by the specified separator
|
||||
const names = (args.names || '').split(args.nameSeparator);
|
||||
const additionalArguments = lodash_1.default.castArray(args['--'] ?? []).map(String);
|
||||
const commands = args.passthroughArguments ? args._ : args._.concat(additionalArguments);
|
||||
if (!commands.length) {
|
||||
program.showHelp();
|
||||
process.exit();
|
||||
}
|
||||
(0, index_1.concurrently)(commands.map((command, index) => ({
|
||||
command: String(command),
|
||||
name: names[index],
|
||||
})), {
|
||||
handleInput: args.handleInput,
|
||||
defaultInputTarget: args.defaultInputTarget,
|
||||
killOthers: args.killOthers
|
||||
? ['success', 'failure']
|
||||
: args.killOthersOnFail
|
||||
? ['failure']
|
||||
: [],
|
||||
killSignal: args.killSignal,
|
||||
maxProcesses: args.maxProcesses,
|
||||
raw: args.raw,
|
||||
hide: args.hide.split(','),
|
||||
group: args.group,
|
||||
prefix: args.prefix,
|
||||
prefixColors: args.prefixColors.split(','),
|
||||
prefixLength: args.prefixLength,
|
||||
padPrefix: args.padPrefix,
|
||||
restartDelay: args.restartAfter === 'exponential' ? 'exponential' : Number(args.restartAfter),
|
||||
restartTries: args.restartTries,
|
||||
successCondition: args.success,
|
||||
timestampFormat: args.timestampFormat,
|
||||
timings: args.timings,
|
||||
teardown: args.teardown,
|
||||
additionalArguments: args.passthroughArguments ? additionalArguments : undefined,
|
||||
}).result.then(() => process.exit(0), () => process.exit(1));
|
6
node_modules/concurrently/dist/bin/read-package.d.ts
generated
vendored
Normal file
6
node_modules/concurrently/dist/bin/read-package.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Traverses the directory tree until a package.json file is found.
|
||||
*
|
||||
* @throws if the root directory is reached, and no package.json is found.
|
||||
*/
|
||||
export declare function readPackage(): Record<string, unknown>;
|
47
node_modules/concurrently/dist/bin/read-package.js
generated
vendored
Normal file
47
node_modules/concurrently/dist/bin/read-package.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.readPackage = void 0;
|
||||
const fs = __importStar(require("fs"));
|
||||
const path = __importStar(require("path"));
|
||||
/**
|
||||
* Traverses the directory tree until a package.json file is found.
|
||||
*
|
||||
* @throws if the root directory is reached, and no package.json is found.
|
||||
*/
|
||||
function readPackage() {
|
||||
let dir = require.main?.path ?? process.cwd();
|
||||
let oldDir = dir;
|
||||
do {
|
||||
const pkgPath = path.join(dir, 'package.json');
|
||||
if (fs.existsSync(pkgPath)) {
|
||||
return JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
||||
}
|
||||
oldDir = dir;
|
||||
dir = path.dirname(dir);
|
||||
} while (oldDir !== dir);
|
||||
throw new Error('package.json not found');
|
||||
}
|
||||
exports.readPackage = readPackage;
|
19
node_modules/concurrently/dist/src/command-parser/command-parser.d.ts
generated
vendored
Normal file
19
node_modules/concurrently/dist/src/command-parser/command-parser.d.ts
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import { CommandInfo } from '../command';
|
||||
/**
|
||||
* A command parser encapsulates a specific logic for mapping `CommandInfo` objects
|
||||
* into another `CommandInfo`.
|
||||
*
|
||||
* A prime example is turning an abstract `npm:foo` into `npm run foo`, but it could also turn
|
||||
* the prefix color of a command brighter, or maybe even prefixing each command with `time(1)`.
|
||||
*/
|
||||
export interface CommandParser {
|
||||
/**
|
||||
* Parses `commandInfo` and returns one or more `CommandInfo`s.
|
||||
*
|
||||
* Returning multiple `CommandInfo` is used when there are multiple possibilities of commands to
|
||||
* run given the original input.
|
||||
* An example of this is when the command contains a wildcard and it must be expanded into all
|
||||
* viable options so that the consumer can decide which ones to run.
|
||||
*/
|
||||
parse(commandInfo: CommandInfo): CommandInfo | CommandInfo[];
|
||||
}
|
2
node_modules/concurrently/dist/src/command-parser/command-parser.js
generated
vendored
Normal file
2
node_modules/concurrently/dist/src/command-parser/command-parser.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
18
node_modules/concurrently/dist/src/command-parser/expand-arguments.d.ts
generated
vendored
Normal file
18
node_modules/concurrently/dist/src/command-parser/expand-arguments.d.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import { CommandInfo } from '../command';
|
||||
import { CommandParser } from './command-parser';
|
||||
/**
|
||||
* Replace placeholders with additional arguments.
|
||||
*/
|
||||
export declare class ExpandArguments implements CommandParser {
|
||||
private readonly additionalArguments;
|
||||
constructor(additionalArguments: string[]);
|
||||
parse(commandInfo: CommandInfo): {
|
||||
command: string;
|
||||
name: string;
|
||||
env?: Record<string, unknown> | undefined;
|
||||
cwd?: string | undefined;
|
||||
prefixColor?: string | undefined;
|
||||
ipc?: number | undefined;
|
||||
raw?: boolean | undefined;
|
||||
};
|
||||
}
|
39
node_modules/concurrently/dist/src/command-parser/expand-arguments.js
generated
vendored
Normal file
39
node_modules/concurrently/dist/src/command-parser/expand-arguments.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ExpandArguments = void 0;
|
||||
const shell_quote_1 = require("shell-quote");
|
||||
/**
|
||||
* Replace placeholders with additional arguments.
|
||||
*/
|
||||
class ExpandArguments {
|
||||
additionalArguments;
|
||||
constructor(additionalArguments) {
|
||||
this.additionalArguments = additionalArguments;
|
||||
}
|
||||
parse(commandInfo) {
|
||||
const command = commandInfo.command.replace(/\\?\{([@*]|[1-9][0-9]*)\}/g, (match, placeholderTarget) => {
|
||||
// Don't replace the placeholder if it is escaped by a backslash.
|
||||
if (match.startsWith('\\')) {
|
||||
return match.slice(1);
|
||||
}
|
||||
// Replace numeric placeholder if value exists in additional arguments.
|
||||
if (!isNaN(placeholderTarget) &&
|
||||
placeholderTarget <= this.additionalArguments.length) {
|
||||
return (0, shell_quote_1.quote)([this.additionalArguments[placeholderTarget - 1]]);
|
||||
}
|
||||
// Replace all arguments placeholder.
|
||||
if (placeholderTarget === '@') {
|
||||
return (0, shell_quote_1.quote)(this.additionalArguments);
|
||||
}
|
||||
// Replace combined arguments placeholder.
|
||||
if (placeholderTarget === '*') {
|
||||
return (0, shell_quote_1.quote)([this.additionalArguments.join(' ')]);
|
||||
}
|
||||
// Replace placeholder with empty string
|
||||
// if value doesn't exist in additional arguments.
|
||||
return '';
|
||||
});
|
||||
return { ...commandInfo, command };
|
||||
}
|
||||
}
|
||||
exports.ExpandArguments = ExpandArguments;
|
17
node_modules/concurrently/dist/src/command-parser/expand-shortcut.d.ts
generated
vendored
Normal file
17
node_modules/concurrently/dist/src/command-parser/expand-shortcut.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { CommandInfo } from '../command';
|
||||
import { CommandParser } from './command-parser';
|
||||
/**
|
||||
* Expands shortcuts according to the following table:
|
||||
*
|
||||
* | Syntax | Expands to |
|
||||
* | --------------- | --------------------- |
|
||||
* | `npm:<script>` | `npm run <script>` |
|
||||
* | `pnpm:<script>` | `pnpm run <script>` |
|
||||
* | `yarn:<script>` | `yarn run <script>` |
|
||||
* | `bun:<script>` | `bun run <script>` |
|
||||
* | `node:<script>` | `node --run <script>` |
|
||||
* | `deno:<script>` | `deno task <script>` |
|
||||
*/
|
||||
export declare class ExpandShortcut implements CommandParser {
|
||||
parse(commandInfo: CommandInfo): CommandInfo;
|
||||
}
|
39
node_modules/concurrently/dist/src/command-parser/expand-shortcut.js
generated
vendored
Normal file
39
node_modules/concurrently/dist/src/command-parser/expand-shortcut.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ExpandShortcut = void 0;
|
||||
/**
|
||||
* Expands shortcuts according to the following table:
|
||||
*
|
||||
* | Syntax | Expands to |
|
||||
* | --------------- | --------------------- |
|
||||
* | `npm:<script>` | `npm run <script>` |
|
||||
* | `pnpm:<script>` | `pnpm run <script>` |
|
||||
* | `yarn:<script>` | `yarn run <script>` |
|
||||
* | `bun:<script>` | `bun run <script>` |
|
||||
* | `node:<script>` | `node --run <script>` |
|
||||
* | `deno:<script>` | `deno task <script>` |
|
||||
*/
|
||||
class ExpandShortcut {
|
||||
parse(commandInfo) {
|
||||
const [, prefix, script, args] = /^(npm|yarn|pnpm|bun|node|deno):(\S+)(.*)/.exec(commandInfo.command) || [];
|
||||
if (!script) {
|
||||
return commandInfo;
|
||||
}
|
||||
let command;
|
||||
if (prefix === 'node') {
|
||||
command = 'node --run';
|
||||
}
|
||||
else if (prefix === 'deno') {
|
||||
command = 'deno task';
|
||||
}
|
||||
else {
|
||||
command = `${prefix} run`;
|
||||
}
|
||||
return {
|
||||
...commandInfo,
|
||||
name: commandInfo.name || script,
|
||||
command: `${command} ${script}${args}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.ExpandShortcut = ExpandShortcut;
|
18
node_modules/concurrently/dist/src/command-parser/expand-wildcard.d.ts
generated
vendored
Normal file
18
node_modules/concurrently/dist/src/command-parser/expand-wildcard.d.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import { CommandInfo } from '../command';
|
||||
import { CommandParser } from './command-parser';
|
||||
/**
|
||||
* Finds wildcards in 'npm/yarn/pnpm/bun run', 'node --run' and 'deno task'
|
||||
* commands and replaces them with all matching scripts in the NodeJS and Deno
|
||||
* configuration files of the current directory.
|
||||
*/
|
||||
export declare class ExpandWildcard implements CommandParser {
|
||||
private readonly readDeno;
|
||||
private readonly readPackage;
|
||||
static readDeno(): any;
|
||||
static readPackage(): any;
|
||||
private packageScripts?;
|
||||
private denoTasks?;
|
||||
constructor(readDeno?: typeof ExpandWildcard.readDeno, readPackage?: typeof ExpandWildcard.readPackage);
|
||||
private relevantScripts;
|
||||
parse(commandInfo: CommandInfo): CommandInfo | CommandInfo[];
|
||||
}
|
107
node_modules/concurrently/dist/src/command-parser/expand-wildcard.js
generated
vendored
Normal file
107
node_modules/concurrently/dist/src/command-parser/expand-wildcard.js
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ExpandWildcard = void 0;
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
const lodash_1 = __importDefault(require("lodash"));
|
||||
const jsonc_1 = __importDefault(require("../jsonc"));
|
||||
// Matches a negative filter surrounded by '(!' and ')'.
|
||||
const OMISSION = /\(!([^)]+)\)/;
|
||||
/**
|
||||
* Finds wildcards in 'npm/yarn/pnpm/bun run', 'node --run' and 'deno task'
|
||||
* commands and replaces them with all matching scripts in the NodeJS and Deno
|
||||
* configuration files of the current directory.
|
||||
*/
|
||||
class ExpandWildcard {
|
||||
readDeno;
|
||||
readPackage;
|
||||
static readDeno() {
|
||||
try {
|
||||
let json = '{}';
|
||||
if (fs_1.default.existsSync('deno.json')) {
|
||||
json = fs_1.default.readFileSync('deno.json', { encoding: 'utf-8' });
|
||||
}
|
||||
else if (fs_1.default.existsSync('deno.jsonc')) {
|
||||
json = fs_1.default.readFileSync('deno.jsonc', { encoding: 'utf-8' });
|
||||
}
|
||||
return jsonc_1.default.parse(json);
|
||||
}
|
||||
catch (e) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
static readPackage() {
|
||||
try {
|
||||
const json = fs_1.default.readFileSync('package.json', { encoding: 'utf-8' });
|
||||
return JSON.parse(json);
|
||||
}
|
||||
catch (e) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
packageScripts;
|
||||
denoTasks;
|
||||
constructor(readDeno = ExpandWildcard.readDeno, readPackage = ExpandWildcard.readPackage) {
|
||||
this.readDeno = readDeno;
|
||||
this.readPackage = readPackage;
|
||||
}
|
||||
relevantScripts(command) {
|
||||
if (!this.packageScripts) {
|
||||
this.packageScripts = Object.keys(this.readPackage().scripts || {});
|
||||
}
|
||||
if (command === 'deno task') {
|
||||
if (!this.denoTasks) {
|
||||
// If Deno tries to run a task that doesn't exist,
|
||||
// it can fall back to running a script with the same name.
|
||||
// Therefore, the actual list of tasks is the union of the tasks and scripts.
|
||||
this.denoTasks = [
|
||||
...Object.keys(this.readDeno().tasks || {}),
|
||||
...this.packageScripts,
|
||||
];
|
||||
}
|
||||
return this.denoTasks;
|
||||
}
|
||||
return this.packageScripts;
|
||||
}
|
||||
parse(commandInfo) {
|
||||
// We expect one of the following patterns:
|
||||
// - <npm|yarn|pnpm|bun> run <script> [args]
|
||||
// - node --run <script> [args]
|
||||
// - deno task <script> [args]
|
||||
const [, command, scriptGlob, args] = /((?:npm|yarn|pnpm|bun) (?:run)|node --run|deno task) (\S+)([^&]*)/.exec(commandInfo.command) || [];
|
||||
const wildcardPosition = (scriptGlob || '').indexOf('*');
|
||||
// If the regex didn't match an npm script, or it has no wildcard,
|
||||
// then we have nothing to do here
|
||||
if (wildcardPosition === -1) {
|
||||
return commandInfo;
|
||||
}
|
||||
const [, omission] = OMISSION.exec(scriptGlob) || [];
|
||||
const scriptGlobSansOmission = scriptGlob.replace(OMISSION, '');
|
||||
const preWildcard = lodash_1.default.escapeRegExp(scriptGlobSansOmission.slice(0, wildcardPosition));
|
||||
const postWildcard = lodash_1.default.escapeRegExp(scriptGlobSansOmission.slice(wildcardPosition + 1));
|
||||
const wildcardRegex = new RegExp(`^${preWildcard}(.*?)${postWildcard}$`);
|
||||
// If 'commandInfo.name' doesn't match 'scriptGlob', this means a custom name
|
||||
// has been specified and thus becomes the prefix (as described in the README).
|
||||
const prefix = commandInfo.name !== scriptGlob ? commandInfo.name : '';
|
||||
return this.relevantScripts(command)
|
||||
.map((script) => {
|
||||
if (omission && RegExp(omission).test(script)) {
|
||||
return;
|
||||
}
|
||||
const [, match] = wildcardRegex.exec(script) || [];
|
||||
if (match !== undefined) {
|
||||
return {
|
||||
...commandInfo,
|
||||
command: `${command} ${script}${args}`,
|
||||
// Will use an empty command name if no prefix has been specified and
|
||||
// the wildcard match is empty, e.g. if `npm:watch-*` matches `npm run watch-`.
|
||||
name: prefix + match,
|
||||
};
|
||||
}
|
||||
})
|
||||
.filter((commandInfo) => !!commandInfo);
|
||||
}
|
||||
}
|
||||
exports.ExpandWildcard = ExpandWildcard;
|
16
node_modules/concurrently/dist/src/command-parser/strip-quotes.d.ts
generated
vendored
Normal file
16
node_modules/concurrently/dist/src/command-parser/strip-quotes.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import { CommandInfo } from '../command';
|
||||
import { CommandParser } from './command-parser';
|
||||
/**
|
||||
* Strips quotes around commands so that they can run on the current shell.
|
||||
*/
|
||||
export declare class StripQuotes implements CommandParser {
|
||||
parse(commandInfo: CommandInfo): {
|
||||
command: string;
|
||||
name: string;
|
||||
env?: Record<string, unknown> | undefined;
|
||||
cwd?: string | undefined;
|
||||
prefixColor?: string | undefined;
|
||||
ipc?: number | undefined;
|
||||
raw?: boolean | undefined;
|
||||
};
|
||||
}
|
17
node_modules/concurrently/dist/src/command-parser/strip-quotes.js
generated
vendored
Normal file
17
node_modules/concurrently/dist/src/command-parser/strip-quotes.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.StripQuotes = void 0;
|
||||
/**
|
||||
* Strips quotes around commands so that they can run on the current shell.
|
||||
*/
|
||||
class StripQuotes {
|
||||
parse(commandInfo) {
|
||||
let { command } = commandInfo;
|
||||
// Removes the quotes surrounding a command.
|
||||
if (/^"(.+?)"$/.test(command) || /^'(.+?)'$/.test(command)) {
|
||||
command = command.slice(1, command.length - 1);
|
||||
}
|
||||
return { ...commandInfo, command };
|
||||
}
|
||||
}
|
||||
exports.StripQuotes = StripQuotes;
|
162
node_modules/concurrently/dist/src/command.d.ts
generated
vendored
Normal file
162
node_modules/concurrently/dist/src/command.d.ts
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { ChildProcess as BaseChildProcess, MessageOptions, SendHandle, SpawnOptions } from 'child_process';
|
||||
import * as Rx from 'rxjs';
|
||||
import { EventEmitter, Writable } from 'stream';
|
||||
/**
|
||||
* Identifier for a command; if string, it's the command's name, if number, it's the index.
|
||||
*/
|
||||
export type CommandIdentifier = string | number;
|
||||
export interface CommandInfo {
|
||||
/**
|
||||
* Command's name.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Which command line the command has.
|
||||
*/
|
||||
command: string;
|
||||
/**
|
||||
* Which environment variables should the spawned process have.
|
||||
*/
|
||||
env?: Record<string, unknown>;
|
||||
/**
|
||||
* The current working directory of the process when spawned.
|
||||
*/
|
||||
cwd?: string;
|
||||
/**
|
||||
* Color to use on prefix of the command.
|
||||
*/
|
||||
prefixColor?: string;
|
||||
/**
|
||||
* Whether sending of messages to/from this command (also known as "inter-process communication")
|
||||
* should be enabled, and using which file descriptor number.
|
||||
*
|
||||
* If set, must be > 2.
|
||||
*/
|
||||
ipc?: number;
|
||||
/**
|
||||
* Output command in raw format.
|
||||
*/
|
||||
raw?: boolean;
|
||||
}
|
||||
export interface CloseEvent {
|
||||
command: CommandInfo;
|
||||
/**
|
||||
* The command's index among all commands ran.
|
||||
*/
|
||||
index: number;
|
||||
/**
|
||||
* Whether the command exited because it was killed.
|
||||
*/
|
||||
killed: boolean;
|
||||
/**
|
||||
* The exit code or signal for the command.
|
||||
*/
|
||||
exitCode: string | number;
|
||||
timings: {
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
durationSeconds: number;
|
||||
};
|
||||
}
|
||||
export interface TimerEvent {
|
||||
startDate: Date;
|
||||
endDate?: Date;
|
||||
}
|
||||
export interface MessageEvent {
|
||||
message: object;
|
||||
handle?: SendHandle;
|
||||
}
|
||||
interface OutgoingMessageEvent extends MessageEvent {
|
||||
options?: MessageOptions;
|
||||
onSent(error?: unknown): void;
|
||||
}
|
||||
/**
|
||||
* Subtype of NodeJS's child_process including only what's actually needed for a command to work.
|
||||
*/
|
||||
export type ChildProcess = EventEmitter & Pick<BaseChildProcess, 'pid' | 'stdin' | 'stdout' | 'stderr' | 'send'>;
|
||||
/**
|
||||
* Interface for a function that must kill the process with `pid`, optionally sending `signal` to it.
|
||||
*/
|
||||
export type KillProcess = (pid: number, signal?: string) => void;
|
||||
/**
|
||||
* Interface for a function that spawns a command and returns its child process instance.
|
||||
*/
|
||||
export type SpawnCommand = (command: string, options: SpawnOptions) => ChildProcess;
|
||||
/**
|
||||
* The state of a command.
|
||||
*
|
||||
* - `stopped`: command was never started
|
||||
* - `started`: command is currently running
|
||||
* - `errored`: command failed spawning
|
||||
* - `exited`: command is not running anymore, e.g. it received a close event
|
||||
*/
|
||||
type CommandState = 'stopped' | 'started' | 'errored' | 'exited';
|
||||
export declare class Command implements CommandInfo {
|
||||
private readonly killProcess;
|
||||
private readonly spawn;
|
||||
private readonly spawnOpts;
|
||||
readonly index: number;
|
||||
/** @inheritdoc */
|
||||
readonly name: string;
|
||||
/** @inheritdoc */
|
||||
readonly command: string;
|
||||
/** @inheritdoc */
|
||||
readonly prefixColor?: string;
|
||||
/** @inheritdoc */
|
||||
readonly env: Record<string, unknown>;
|
||||
/** @inheritdoc */
|
||||
readonly cwd?: string;
|
||||
/** @inheritdoc */
|
||||
readonly ipc?: number;
|
||||
readonly close: Rx.Subject<CloseEvent>;
|
||||
readonly error: Rx.Subject<unknown>;
|
||||
readonly stdout: Rx.Subject<Buffer>;
|
||||
readonly stderr: Rx.Subject<Buffer>;
|
||||
readonly timer: Rx.Subject<TimerEvent>;
|
||||
readonly messages: {
|
||||
incoming: Rx.Subject<MessageEvent>;
|
||||
outgoing: Rx.ReplaySubject<OutgoingMessageEvent>;
|
||||
};
|
||||
process?: ChildProcess;
|
||||
private subscriptions;
|
||||
stdin?: Writable;
|
||||
pid?: number;
|
||||
killed: boolean;
|
||||
exited: boolean;
|
||||
state: CommandState;
|
||||
constructor({ index, name, command, prefixColor, env, cwd, ipc }: CommandInfo & {
|
||||
index: number;
|
||||
}, spawnOpts: SpawnOptions, spawn: SpawnCommand, killProcess: KillProcess);
|
||||
/**
|
||||
* Starts this command, piping output, error and close events onto the corresponding observables.
|
||||
*/
|
||||
start(): void;
|
||||
private maybeSetupIPC;
|
||||
/**
|
||||
* Sends a message to the underlying process once it starts.
|
||||
*
|
||||
* @throws If the command doesn't have an IPC channel enabled
|
||||
* @returns Promise that resolves when the message is sent,
|
||||
* or rejects if it fails to deliver the message.
|
||||
*/
|
||||
send(message: object, handle?: SendHandle, options?: MessageOptions): Promise<void>;
|
||||
/**
|
||||
* Kills this command, optionally specifying a signal to send to it.
|
||||
*/
|
||||
kill(code?: string): void;
|
||||
private cleanUp;
|
||||
/**
|
||||
* Detects whether a command can be killed.
|
||||
*
|
||||
* Also works as a type guard on the input `command`.
|
||||
*/
|
||||
static canKill(command: Command): command is Command & {
|
||||
pid: number;
|
||||
process: ChildProcess;
|
||||
};
|
||||
}
|
||||
export {};
|
192
node_modules/concurrently/dist/src/command.js
generated
vendored
Normal file
192
node_modules/concurrently/dist/src/command.js
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Command = void 0;
|
||||
const Rx = __importStar(require("rxjs"));
|
||||
class Command {
|
||||
killProcess;
|
||||
spawn;
|
||||
spawnOpts;
|
||||
index;
|
||||
/** @inheritdoc */
|
||||
name;
|
||||
/** @inheritdoc */
|
||||
command;
|
||||
/** @inheritdoc */
|
||||
prefixColor;
|
||||
/** @inheritdoc */
|
||||
env;
|
||||
/** @inheritdoc */
|
||||
cwd;
|
||||
/** @inheritdoc */
|
||||
ipc;
|
||||
close = new Rx.Subject();
|
||||
error = new Rx.Subject();
|
||||
stdout = new Rx.Subject();
|
||||
stderr = new Rx.Subject();
|
||||
timer = new Rx.Subject();
|
||||
messages = {
|
||||
incoming: new Rx.Subject(),
|
||||
outgoing: new Rx.ReplaySubject(),
|
||||
};
|
||||
process;
|
||||
// TODO: Should exit/error/stdio subscriptions be added here?
|
||||
subscriptions = [];
|
||||
stdin;
|
||||
pid;
|
||||
killed = false;
|
||||
exited = false;
|
||||
state = 'stopped';
|
||||
constructor({ index, name, command, prefixColor, env, cwd, ipc }, spawnOpts, spawn, killProcess) {
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
this.command = command;
|
||||
this.prefixColor = prefixColor;
|
||||
this.env = env || {};
|
||||
this.cwd = cwd;
|
||||
this.ipc = ipc;
|
||||
this.killProcess = killProcess;
|
||||
this.spawn = spawn;
|
||||
this.spawnOpts = spawnOpts;
|
||||
}
|
||||
/**
|
||||
* Starts this command, piping output, error and close events onto the corresponding observables.
|
||||
*/
|
||||
start() {
|
||||
const child = this.spawn(this.command, this.spawnOpts);
|
||||
this.state = 'started';
|
||||
this.process = child;
|
||||
this.pid = child.pid;
|
||||
const startDate = new Date(Date.now());
|
||||
const highResStartTime = process.hrtime();
|
||||
this.timer.next({ startDate });
|
||||
this.subscriptions = [...this.maybeSetupIPC(child)];
|
||||
Rx.fromEvent(child, 'error').subscribe((event) => {
|
||||
this.cleanUp();
|
||||
const endDate = new Date(Date.now());
|
||||
this.timer.next({ startDate, endDate });
|
||||
this.error.next(event);
|
||||
this.state = 'errored';
|
||||
});
|
||||
Rx.fromEvent(child, 'close')
|
||||
.pipe(Rx.map((event) => event))
|
||||
.subscribe(([exitCode, signal]) => {
|
||||
this.cleanUp();
|
||||
// Don't override error event
|
||||
if (this.state !== 'errored') {
|
||||
this.state = 'exited';
|
||||
}
|
||||
const endDate = new Date(Date.now());
|
||||
this.timer.next({ startDate, endDate });
|
||||
const [durationSeconds, durationNanoSeconds] = process.hrtime(highResStartTime);
|
||||
this.close.next({
|
||||
command: this,
|
||||
index: this.index,
|
||||
exitCode: exitCode ?? String(signal),
|
||||
killed: this.killed,
|
||||
timings: {
|
||||
startDate,
|
||||
endDate,
|
||||
durationSeconds: durationSeconds + durationNanoSeconds / 1e9,
|
||||
},
|
||||
});
|
||||
});
|
||||
child.stdout &&
|
||||
pipeTo(Rx.fromEvent(child.stdout, 'data').pipe(Rx.map((event) => event)), this.stdout);
|
||||
child.stderr &&
|
||||
pipeTo(Rx.fromEvent(child.stderr, 'data').pipe(Rx.map((event) => event)), this.stderr);
|
||||
this.stdin = child.stdin || undefined;
|
||||
}
|
||||
maybeSetupIPC(child) {
|
||||
if (!this.ipc) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
pipeTo(Rx.fromEvent(child, 'message').pipe(Rx.map((event) => {
|
||||
const [message, handle] = event;
|
||||
return { message, handle };
|
||||
})), this.messages.incoming),
|
||||
this.messages.outgoing.subscribe((message) => {
|
||||
if (!child.send) {
|
||||
return message.onSent(new Error('Command does not have an IPC channel'));
|
||||
}
|
||||
child.send(message.message, message.handle, message.options, (error) => {
|
||||
message.onSent(error);
|
||||
});
|
||||
}),
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Sends a message to the underlying process once it starts.
|
||||
*
|
||||
* @throws If the command doesn't have an IPC channel enabled
|
||||
* @returns Promise that resolves when the message is sent,
|
||||
* or rejects if it fails to deliver the message.
|
||||
*/
|
||||
send(message, handle, options) {
|
||||
if (this.ipc == null) {
|
||||
throw new Error('Command IPC is disabled');
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this.messages.outgoing.next({
|
||||
message,
|
||||
handle,
|
||||
options,
|
||||
onSent(error) {
|
||||
error ? reject(error) : resolve();
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Kills this command, optionally specifying a signal to send to it.
|
||||
*/
|
||||
kill(code) {
|
||||
if (Command.canKill(this)) {
|
||||
this.killed = true;
|
||||
this.killProcess(this.pid, code);
|
||||
}
|
||||
}
|
||||
cleanUp() {
|
||||
this.subscriptions?.forEach((sub) => sub.unsubscribe());
|
||||
this.messages.outgoing = new Rx.ReplaySubject();
|
||||
this.process = undefined;
|
||||
}
|
||||
/**
|
||||
* Detects whether a command can be killed.
|
||||
*
|
||||
* Also works as a type guard on the input `command`.
|
||||
*/
|
||||
static canKill(command) {
|
||||
return !!command.pid && !!command.process;
|
||||
}
|
||||
}
|
||||
exports.Command = Command;
|
||||
/**
|
||||
* Pipes all events emitted by `stream` into `subject`.
|
||||
*/
|
||||
function pipeTo(stream, subject) {
|
||||
return stream.subscribe((event) => subject.next(event));
|
||||
}
|
43
node_modules/concurrently/dist/src/completion-listener.d.ts
generated
vendored
Normal file
43
node_modules/concurrently/dist/src/completion-listener.d.ts
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/// <reference types="node" />
|
||||
import * as Rx from 'rxjs';
|
||||
import { CloseEvent, Command } from './command';
|
||||
/**
|
||||
* Defines which command(s) in a list must exit successfully (with an exit code of `0`):
|
||||
*
|
||||
* - `first`: only the first specified command;
|
||||
* - `last`: only the last specified command;
|
||||
* - `all`: all commands.
|
||||
* - `command-{name|index}`: only the commands with the specified names or index.
|
||||
* - `!command-{name|index}`: all commands but the ones with the specified names or index.
|
||||
*/
|
||||
export type SuccessCondition = 'first' | 'last' | 'all' | `command-${string | number}` | `!command-${string | number}`;
|
||||
/**
|
||||
* Provides logic to determine whether lists of commands ran successfully.
|
||||
*/
|
||||
export declare class CompletionListener {
|
||||
private readonly successCondition;
|
||||
private readonly scheduler?;
|
||||
constructor({ successCondition, scheduler, }: {
|
||||
/**
|
||||
* How this instance will define that a list of commands ran successfully.
|
||||
* Defaults to `all`.
|
||||
*
|
||||
* @see {SuccessCondition}
|
||||
*/
|
||||
successCondition?: SuccessCondition;
|
||||
/**
|
||||
* For testing only.
|
||||
*/
|
||||
scheduler?: Rx.SchedulerLike;
|
||||
});
|
||||
private isSuccess;
|
||||
/**
|
||||
* Given a list of commands, wait for all of them to exit and then evaluate their exit codes.
|
||||
*
|
||||
* @returns A Promise that resolves if the success condition is met, or rejects otherwise.
|
||||
* In either case, the value is a list of close events for commands that spawned.
|
||||
* Commands that didn't spawn are filtered out.
|
||||
*/
|
||||
listen(commands: Command[], abortSignal?: AbortSignal): Promise<CloseEvent[]>;
|
||||
private emitWithScheduler;
|
||||
}
|
101
node_modules/concurrently/dist/src/completion-listener.js
generated
vendored
Normal file
101
node_modules/concurrently/dist/src/completion-listener.js
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CompletionListener = void 0;
|
||||
const Rx = __importStar(require("rxjs"));
|
||||
const operators_1 = require("rxjs/operators");
|
||||
/**
|
||||
* Provides logic to determine whether lists of commands ran successfully.
|
||||
*/
|
||||
class CompletionListener {
|
||||
successCondition;
|
||||
scheduler;
|
||||
constructor({ successCondition = 'all', scheduler, }) {
|
||||
this.successCondition = successCondition;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
isSuccess(events) {
|
||||
if (!events.length) {
|
||||
// When every command was aborted, consider a success.
|
||||
return true;
|
||||
}
|
||||
if (this.successCondition === 'first') {
|
||||
return events[0].exitCode === 0;
|
||||
}
|
||||
else if (this.successCondition === 'last') {
|
||||
return events[events.length - 1].exitCode === 0;
|
||||
}
|
||||
const commandSyntaxMatch = this.successCondition.match(/^!?command-(.+)$/);
|
||||
if (commandSyntaxMatch == null) {
|
||||
// If not a `command-` syntax, then it's an 'all' condition or it's treated as such.
|
||||
return events.every(({ exitCode }) => exitCode === 0);
|
||||
}
|
||||
// Check `command-` syntax condition.
|
||||
// Note that a command's `name` is not necessarily unique,
|
||||
// in which case all of them must meet the success condition.
|
||||
const nameOrIndex = commandSyntaxMatch[1];
|
||||
const targetCommandsEvents = events.filter(({ command, index }) => command.name === nameOrIndex || index === Number(nameOrIndex));
|
||||
if (this.successCondition.startsWith('!')) {
|
||||
// All commands except the specified ones must exit successfully
|
||||
return events.every((event) => targetCommandsEvents.includes(event) || event.exitCode === 0);
|
||||
}
|
||||
// Only the specified commands must exit succesfully
|
||||
return (targetCommandsEvents.length > 0 &&
|
||||
targetCommandsEvents.every((event) => event.exitCode === 0));
|
||||
}
|
||||
/**
|
||||
* Given a list of commands, wait for all of them to exit and then evaluate their exit codes.
|
||||
*
|
||||
* @returns A Promise that resolves if the success condition is met, or rejects otherwise.
|
||||
* In either case, the value is a list of close events for commands that spawned.
|
||||
* Commands that didn't spawn are filtered out.
|
||||
*/
|
||||
listen(commands, abortSignal) {
|
||||
const abort = abortSignal &&
|
||||
Rx.fromEvent(abortSignal, 'abort', { once: true }).pipe(
|
||||
// The abort signal must happen before commands are killed, otherwise new commands
|
||||
// might spawn. Because of this, it's not be possible to capture the close events
|
||||
// without an immediate delay
|
||||
(0, operators_1.delay)(0, this.scheduler), (0, operators_1.map)(() => undefined),
|
||||
// #502 - node might warn of too many active listeners on this object if it isn't shared,
|
||||
// as each command subscribes to abort event over and over
|
||||
(0, operators_1.share)());
|
||||
const closeStreams = commands.map((command) => abort
|
||||
? // Commands that have been started must close.
|
||||
Rx.race(command.close, abort.pipe((0, operators_1.filter)(() => command.state === 'stopped')))
|
||||
: command.close);
|
||||
return Rx.lastValueFrom(Rx.combineLatest(closeStreams).pipe((0, operators_1.filter)(() => commands.every((command) => command.state !== 'started')), (0, operators_1.map)((events) => events
|
||||
// Filter out aborts, since they cannot be sorted and are considered success condition anyways
|
||||
.filter((event) => event != null)
|
||||
// Sort according to exit time
|
||||
.sort((first, second) => first.timings.endDate.getTime() - second.timings.endDate.getTime())), (0, operators_1.switchMap)((events) => this.isSuccess(events)
|
||||
? this.emitWithScheduler(Rx.of(events))
|
||||
: this.emitWithScheduler(Rx.throwError(() => events))), (0, operators_1.take)(1)));
|
||||
}
|
||||
emitWithScheduler(input) {
|
||||
return this.scheduler ? input.pipe(Rx.observeOn(this.scheduler)) : input;
|
||||
}
|
||||
}
|
||||
exports.CompletionListener = CompletionListener;
|
122
node_modules/concurrently/dist/src/concurrently.d.ts
generated
vendored
Normal file
122
node_modules/concurrently/dist/src/concurrently.d.ts
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { Writable } from 'stream';
|
||||
import { CloseEvent, Command, CommandIdentifier, CommandInfo, KillProcess, SpawnCommand } from './command';
|
||||
import { SuccessCondition } from './completion-listener';
|
||||
import { FlowController } from './flow-control/flow-controller';
|
||||
import { Logger } from './logger';
|
||||
/**
|
||||
* A command that is to be passed into `concurrently()`.
|
||||
* If value is a string, then that's the command's command line.
|
||||
* Fine grained options can be defined by using the object format.
|
||||
*/
|
||||
export type ConcurrentlyCommandInput = string | ({
|
||||
command: string;
|
||||
} & Partial<CommandInfo>);
|
||||
export type ConcurrentlyResult = {
|
||||
/**
|
||||
* All commands created and ran by concurrently.
|
||||
*/
|
||||
commands: Command[];
|
||||
/**
|
||||
* A promise that resolves when concurrently ran successfully according to the specified
|
||||
* success condition, or reject otherwise.
|
||||
*
|
||||
* Both the resolved and rejected value is a list of all the close events for commands that
|
||||
* spawned; commands that didn't spawn are filtered out.
|
||||
*/
|
||||
result: Promise<CloseEvent[]>;
|
||||
};
|
||||
export type ConcurrentlyOptions = {
|
||||
logger?: Logger;
|
||||
/**
|
||||
* Which stream should the commands output be written to.
|
||||
*/
|
||||
outputStream?: Writable;
|
||||
/**
|
||||
* Whether the output should be ordered as if the commands were run sequentially.
|
||||
*/
|
||||
group?: boolean;
|
||||
/**
|
||||
* A comma-separated list of chalk colors or a string for available styles listed below to use on prefixes.
|
||||
* If there are more commands than colors, the last color will be repeated.
|
||||
*
|
||||
* Available modifiers:
|
||||
* - `reset`, `bold`, `dim`, `italic`, `underline`, `inverse`, `hidden`, `strikethrough`
|
||||
*
|
||||
* Available colors:
|
||||
* - `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `gray`,
|
||||
* any hex values for colors (e.g. `#23de43`) or `auto` for an automatically picked color
|
||||
*
|
||||
* Available background colors:
|
||||
* - `bgBlack`, `bgRed`, `bgGreen`, `bgYellow`, `bgBlue`, `bgMagenta`, `bgCyan`, `bgWhite`
|
||||
*
|
||||
* Set to `false` to disable colors.
|
||||
*
|
||||
* @see {@link https://www.npmjs.com/package/chalk} for more information.
|
||||
*/
|
||||
prefixColors?: string | string[] | false;
|
||||
/**
|
||||
* Maximum number of commands to run at once.
|
||||
* Exact number or a percent of CPUs available (for example "50%").
|
||||
*
|
||||
* If undefined, then all processes will start in parallel.
|
||||
* Setting this value to 1 will achieve sequential running.
|
||||
*/
|
||||
maxProcesses?: number | string;
|
||||
/**
|
||||
* Whether commands should be spawned in raw mode.
|
||||
* Defaults to false.
|
||||
*/
|
||||
raw?: boolean;
|
||||
/**
|
||||
* Which commands should have their output hidden.
|
||||
*/
|
||||
hide?: CommandIdentifier[];
|
||||
/**
|
||||
* The current working directory of commands which didn't specify one.
|
||||
* Defaults to `process.cwd()`.
|
||||
*/
|
||||
cwd?: string;
|
||||
/**
|
||||
* @see CompletionListener
|
||||
*/
|
||||
successCondition?: SuccessCondition;
|
||||
/**
|
||||
* A signal to stop spawning further processes.
|
||||
*/
|
||||
abortSignal?: AbortSignal;
|
||||
/**
|
||||
* Which flow controllers should be applied on commands spawned by concurrently.
|
||||
* Defaults to an empty array.
|
||||
*/
|
||||
controllers: FlowController[];
|
||||
/**
|
||||
* A function that will spawn commands.
|
||||
* Defaults to a function that spawns using either `cmd.exe` or `/bin/sh`.
|
||||
*/
|
||||
spawn: SpawnCommand;
|
||||
/**
|
||||
* A function that will kill processes.
|
||||
* Defaults to the `tree-kill` module.
|
||||
*/
|
||||
kill: KillProcess;
|
||||
/**
|
||||
* Signal to send to killed processes.
|
||||
*/
|
||||
killSignal?: string;
|
||||
/**
|
||||
* List of additional arguments passed that will get replaced in each command.
|
||||
* If not defined, no argument replacing will happen.
|
||||
*
|
||||
* @see ExpandArguments
|
||||
*/
|
||||
additionalArguments?: string[];
|
||||
};
|
||||
/**
|
||||
* Core concurrently functionality -- spawns the given commands concurrently and
|
||||
* returns the commands themselves + the result according to the specified success condition.
|
||||
*
|
||||
* @see CompletionListener
|
||||
*/
|
||||
export declare function concurrently(baseCommands: ConcurrentlyCommandInput[], baseOptions?: Partial<ConcurrentlyOptions>): ConcurrentlyResult;
|
131
node_modules/concurrently/dist/src/concurrently.js
generated
vendored
Normal file
131
node_modules/concurrently/dist/src/concurrently.js
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.concurrently = void 0;
|
||||
const assert_1 = __importDefault(require("assert"));
|
||||
const lodash_1 = __importDefault(require("lodash"));
|
||||
const os_1 = require("os");
|
||||
const tree_kill_1 = __importDefault(require("tree-kill"));
|
||||
const command_1 = require("./command");
|
||||
const expand_arguments_1 = require("./command-parser/expand-arguments");
|
||||
const expand_shortcut_1 = require("./command-parser/expand-shortcut");
|
||||
const expand_wildcard_1 = require("./command-parser/expand-wildcard");
|
||||
const strip_quotes_1 = require("./command-parser/strip-quotes");
|
||||
const completion_listener_1 = require("./completion-listener");
|
||||
const output_writer_1 = require("./output-writer");
|
||||
const prefix_color_selector_1 = require("./prefix-color-selector");
|
||||
const spawn_1 = require("./spawn");
|
||||
const defaults = {
|
||||
spawn: spawn_1.spawn,
|
||||
kill: tree_kill_1.default,
|
||||
raw: false,
|
||||
controllers: [],
|
||||
cwd: undefined,
|
||||
};
|
||||
/**
|
||||
* Core concurrently functionality -- spawns the given commands concurrently and
|
||||
* returns the commands themselves + the result according to the specified success condition.
|
||||
*
|
||||
* @see CompletionListener
|
||||
*/
|
||||
function concurrently(baseCommands, baseOptions) {
|
||||
assert_1.default.ok(Array.isArray(baseCommands), '[concurrently] commands should be an array');
|
||||
assert_1.default.notStrictEqual(baseCommands.length, 0, '[concurrently] no commands provided');
|
||||
const options = lodash_1.default.defaults(baseOptions, defaults);
|
||||
const prefixColorSelector = new prefix_color_selector_1.PrefixColorSelector(options.prefixColors || []);
|
||||
const commandParsers = [
|
||||
new strip_quotes_1.StripQuotes(),
|
||||
new expand_shortcut_1.ExpandShortcut(),
|
||||
new expand_wildcard_1.ExpandWildcard(),
|
||||
];
|
||||
if (options.additionalArguments) {
|
||||
commandParsers.push(new expand_arguments_1.ExpandArguments(options.additionalArguments));
|
||||
}
|
||||
const hide = (options.hide || []).map(String);
|
||||
let commands = (0, lodash_1.default)(baseCommands)
|
||||
.map(mapToCommandInfo)
|
||||
.flatMap((command) => parseCommand(command, commandParsers))
|
||||
.map((command, index) => {
|
||||
const hidden = hide.includes(command.name) || hide.includes(String(index));
|
||||
return new command_1.Command({
|
||||
index,
|
||||
prefixColor: prefixColorSelector.getNextColor(),
|
||||
...command,
|
||||
}, (0, spawn_1.getSpawnOpts)({
|
||||
ipc: command.ipc,
|
||||
stdio: hidden ? 'hidden' : command.raw ?? options.raw ? 'raw' : 'normal',
|
||||
env: command.env,
|
||||
cwd: command.cwd || options.cwd,
|
||||
}), options.spawn, options.kill);
|
||||
})
|
||||
.value();
|
||||
const handleResult = options.controllers.reduce(({ commands: prevCommands, onFinishCallbacks }, controller) => {
|
||||
const { commands, onFinish } = controller.handle(prevCommands);
|
||||
return {
|
||||
commands,
|
||||
onFinishCallbacks: lodash_1.default.concat(onFinishCallbacks, onFinish ? [onFinish] : []),
|
||||
};
|
||||
}, { commands, onFinishCallbacks: [] });
|
||||
commands = handleResult.commands;
|
||||
if (options.logger && options.outputStream) {
|
||||
const outputWriter = new output_writer_1.OutputWriter({
|
||||
outputStream: options.outputStream,
|
||||
group: !!options.group,
|
||||
commands,
|
||||
});
|
||||
options.logger.output.subscribe(({ command, text }) => outputWriter.write(command, text));
|
||||
}
|
||||
const commandsLeft = commands.slice();
|
||||
const maxProcesses = Math.max(1, (typeof options.maxProcesses === 'string' && options.maxProcesses.endsWith('%')
|
||||
? Math.round(((0, os_1.cpus)().length * Number(options.maxProcesses.slice(0, -1))) / 100)
|
||||
: Number(options.maxProcesses)) || commandsLeft.length);
|
||||
for (let i = 0; i < maxProcesses; i++) {
|
||||
maybeRunMore(commandsLeft, options.abortSignal);
|
||||
}
|
||||
const result = new completion_listener_1.CompletionListener({ successCondition: options.successCondition })
|
||||
.listen(commands, options.abortSignal)
|
||||
.finally(() => Promise.all(handleResult.onFinishCallbacks.map((onFinish) => onFinish())));
|
||||
return {
|
||||
result,
|
||||
commands,
|
||||
};
|
||||
}
|
||||
exports.concurrently = concurrently;
|
||||
function mapToCommandInfo(command) {
|
||||
if (typeof command === 'string') {
|
||||
return mapToCommandInfo({ command });
|
||||
}
|
||||
assert_1.default.ok(command.command, '[concurrently] command cannot be empty');
|
||||
return {
|
||||
command: command.command,
|
||||
name: command.name || '',
|
||||
env: command.env || {},
|
||||
cwd: command.cwd || '',
|
||||
ipc: command.ipc,
|
||||
...(command.prefixColor
|
||||
? {
|
||||
prefixColor: command.prefixColor,
|
||||
}
|
||||
: {}),
|
||||
...(command.raw !== undefined
|
||||
? {
|
||||
raw: command.raw,
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
function parseCommand(command, parsers) {
|
||||
return parsers.reduce((commands, parser) => lodash_1.default.flatMap(commands, (command) => parser.parse(command)), lodash_1.default.castArray(command));
|
||||
}
|
||||
function maybeRunMore(commandsLeft, abortSignal) {
|
||||
const command = commandsLeft.shift();
|
||||
if (!command || abortSignal?.aborted) {
|
||||
return;
|
||||
}
|
||||
command.start();
|
||||
command.close.subscribe(() => {
|
||||
maybeRunMore(commandsLeft, abortSignal);
|
||||
});
|
||||
}
|
19
node_modules/concurrently/dist/src/date-format.d.ts
generated
vendored
Normal file
19
node_modules/concurrently/dist/src/date-format.d.ts
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
export type FormatterOptions = {
|
||||
locale?: string;
|
||||
calendar?: string;
|
||||
};
|
||||
/**
|
||||
* Unicode-compliant date/time formatter.
|
||||
*
|
||||
* @see https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
|
||||
*/
|
||||
export declare class DateFormatter {
|
||||
private readonly options;
|
||||
private static tokenRegex;
|
||||
private readonly parts;
|
||||
constructor(pattern: string, options?: FormatterOptions);
|
||||
private compileLiteral;
|
||||
private compileOther;
|
||||
private compileToken;
|
||||
format(date: Date): string;
|
||||
}
|
318
node_modules/concurrently/dist/src/date-format.js
generated
vendored
Normal file
318
node_modules/concurrently/dist/src/date-format.js
generated
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DateFormatter = void 0;
|
||||
/**
|
||||
* Unicode-compliant date/time formatter.
|
||||
*
|
||||
* @see https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
|
||||
*/
|
||||
class DateFormatter {
|
||||
options;
|
||||
static tokenRegex = /[A-Z]/i;
|
||||
parts = [];
|
||||
constructor(pattern, options = {}) {
|
||||
this.options = options;
|
||||
let i = 0;
|
||||
while (i < pattern.length) {
|
||||
const char = pattern[i];
|
||||
const { fn, length } = char === "'"
|
||||
? this.compileLiteral(pattern, i)
|
||||
: DateFormatter.tokenRegex.test(char)
|
||||
? this.compileToken(pattern, i)
|
||||
: this.compileOther(pattern, i);
|
||||
this.parts.push(fn);
|
||||
i += length;
|
||||
}
|
||||
}
|
||||
compileLiteral(pattern, offset) {
|
||||
let length = 1;
|
||||
let value = '';
|
||||
for (; length < pattern.length; length++) {
|
||||
const i = offset + length;
|
||||
const char = pattern[i];
|
||||
if (char === "'") {
|
||||
const nextChar = pattern[i + 1];
|
||||
length++;
|
||||
// if the next character is another single quote, it's been escaped.
|
||||
// if not, then the literal has been closed
|
||||
if (nextChar !== "'") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
value += char;
|
||||
}
|
||||
return { fn: () => value || "'", length };
|
||||
}
|
||||
compileOther(pattern, offset) {
|
||||
let value = '';
|
||||
while (!DateFormatter.tokenRegex.test(pattern[offset]) && pattern[offset] !== "'") {
|
||||
value += pattern[offset++];
|
||||
}
|
||||
return { fn: () => value, length: value.length };
|
||||
}
|
||||
compileToken(pattern, offset) {
|
||||
const type = pattern[offset];
|
||||
const token = tokens.get(type);
|
||||
if (!token) {
|
||||
throw new SyntaxError(`Formatting token "${type}" is invalid`);
|
||||
}
|
||||
let length = 0;
|
||||
while (pattern[offset + length] === type) {
|
||||
length++;
|
||||
}
|
||||
const tokenFn = token[length - 1];
|
||||
if (!tokenFn) {
|
||||
throw new RangeError(`Formatting token "${type.repeat(length)}" is unsupported`);
|
||||
}
|
||||
return { fn: tokenFn, length };
|
||||
}
|
||||
format(date) {
|
||||
return this.parts.reduce((output, part) => output + String(part(date, this.options)), '');
|
||||
}
|
||||
}
|
||||
exports.DateFormatter = DateFormatter;
|
||||
/**
|
||||
* A map of token to its implementations by length.
|
||||
* If an index is undefined, then that token length is unsupported.
|
||||
*/
|
||||
const tokens = new Map()
|
||||
// era
|
||||
.set('G', [
|
||||
makeTokenFn({ era: 'short' }, 'era'),
|
||||
makeTokenFn({ era: 'short' }, 'era'),
|
||||
makeTokenFn({ era: 'short' }, 'era'),
|
||||
makeTokenFn({ era: 'long' }, 'era'),
|
||||
makeTokenFn({ era: 'narrow' }, 'era'),
|
||||
])
|
||||
// year
|
||||
.set('y', [
|
||||
// TODO: does not support BC years.
|
||||
// https://stackoverflow.com/a/41345095/2083599
|
||||
(date) => date.getFullYear(),
|
||||
(date) => pad(2, date.getFullYear()).slice(-2),
|
||||
(date) => pad(3, date.getFullYear()),
|
||||
(date) => pad(4, date.getFullYear()),
|
||||
(date) => pad(5, date.getFullYear()),
|
||||
])
|
||||
.set('Y', [
|
||||
getWeekYear,
|
||||
(date, options) => pad(2, getWeekYear(date, options)).slice(-2),
|
||||
(date, options) => pad(3, getWeekYear(date, options)),
|
||||
(date, options) => pad(4, getWeekYear(date, options)),
|
||||
(date, options) => pad(5, getWeekYear(date, options)),
|
||||
])
|
||||
.set('u', [])
|
||||
.set('U', [
|
||||
// Fallback implemented as yearName is not available in gregorian calendars, for instance.
|
||||
makeTokenFn({ dateStyle: 'full' }, 'yearName', (date) => String(date.getFullYear())),
|
||||
])
|
||||
.set('r', [
|
||||
// Fallback implemented as relatedYear is not available in gregorian calendars, for instance.
|
||||
makeTokenFn({ dateStyle: 'full' }, 'relatedYear', (date) => String(date.getFullYear())),
|
||||
])
|
||||
// quarter
|
||||
.set('Q', [
|
||||
(date) => Math.floor(date.getMonth() / 3) + 1,
|
||||
(date) => pad(2, Math.floor(date.getMonth() / 3) + 1),
|
||||
// these aren't localized in Intl.DateTimeFormat.
|
||||
undefined,
|
||||
undefined,
|
||||
(date) => Math.floor(date.getMonth() / 3) + 1,
|
||||
])
|
||||
.set('q', [
|
||||
(date) => Math.floor(date.getMonth() / 3) + 1,
|
||||
(date) => pad(2, Math.floor(date.getMonth() / 3) + 1),
|
||||
// these aren't localized in Intl.DateTimeFormat.
|
||||
undefined,
|
||||
undefined,
|
||||
(date) => Math.floor(date.getMonth() / 3) + 1,
|
||||
])
|
||||
// month
|
||||
.set('M', [
|
||||
(date) => date.getMonth() + 1,
|
||||
(date) => pad(2, date.getMonth() + 1),
|
||||
// these include the day so that it forces non-stand-alone month part
|
||||
makeTokenFn({ day: 'numeric', month: 'short' }, 'month'),
|
||||
makeTokenFn({ day: 'numeric', month: 'long' }, 'month'),
|
||||
makeTokenFn({ day: 'numeric', month: 'narrow' }, 'month'),
|
||||
])
|
||||
.set('L', [
|
||||
(date) => date.getMonth() + 1,
|
||||
(date) => pad(2, date.getMonth() + 1),
|
||||
makeTokenFn({ month: 'short' }, 'month'),
|
||||
makeTokenFn({ month: 'long' }, 'month'),
|
||||
makeTokenFn({ month: 'narrow' }, 'month'),
|
||||
])
|
||||
.set('l', [() => ''])
|
||||
// week
|
||||
.set('w', [getWeek, (date, options) => pad(2, getWeek(date, options))])
|
||||
.set('W', [getWeekOfMonth])
|
||||
// day
|
||||
.set('d', [(date) => date.getDate(), (date) => pad(2, date.getDate())])
|
||||
.set('D', [
|
||||
getDayOfYear,
|
||||
(date) => pad(2, getDayOfYear(date)),
|
||||
(date) => pad(3, getDayOfYear(date)),
|
||||
])
|
||||
.set('F', [(date) => Math.ceil(date.getDate() / 7)])
|
||||
.set('g', [])
|
||||
// week day
|
||||
.set('E', [
|
||||
makeTokenFn({ weekday: 'short' }, 'weekday'),
|
||||
makeTokenFn({ weekday: 'short' }, 'weekday'),
|
||||
makeTokenFn({ weekday: 'short' }, 'weekday'),
|
||||
makeTokenFn({ weekday: 'long' }, 'weekday'),
|
||||
])
|
||||
.set('e', [
|
||||
undefined,
|
||||
undefined,
|
||||
makeTokenFn({ weekday: 'short' }, 'weekday'),
|
||||
makeTokenFn({ weekday: 'long' }, 'weekday'),
|
||||
])
|
||||
.set('c', [])
|
||||
// period
|
||||
.set('a', [
|
||||
makeTokenFn({ hour12: true, timeStyle: 'full' }, 'dayPeriod'),
|
||||
makeTokenFn({ hour12: true, timeStyle: 'full' }, 'dayPeriod'),
|
||||
makeTokenFn({ hour12: true, timeStyle: 'full' }, 'dayPeriod'),
|
||||
])
|
||||
.set('b', [])
|
||||
.set('B', [
|
||||
makeTokenFn({ dayPeriod: 'short' }, 'dayPeriod'),
|
||||
makeTokenFn({ dayPeriod: 'short' }, 'dayPeriod'),
|
||||
makeTokenFn({ dayPeriod: 'short' }, 'dayPeriod'),
|
||||
makeTokenFn({ dayPeriod: 'long' }, 'dayPeriod'),
|
||||
])
|
||||
// hour
|
||||
.set('h', [(date) => date.getHours() % 12 || 12, (date) => pad(2, date.getHours() % 12 || 12)])
|
||||
.set('H', [(date) => date.getHours(), (date) => pad(2, date.getHours())])
|
||||
.set('K', [(date) => date.getHours() % 12, (date) => pad(2, date.getHours() % 12)])
|
||||
.set('k', [(date) => date.getHours() % 24 || 24, (date) => pad(2, date.getHours() % 24 || 24)])
|
||||
.set('j', [])
|
||||
.set('J', [])
|
||||
.set('C', [])
|
||||
// minute
|
||||
.set('m', [(date) => date.getMinutes(), (date) => pad(2, date.getMinutes())])
|
||||
// second
|
||||
.set('s', [(date) => date.getSeconds(), (date) => pad(2, date.getSeconds())])
|
||||
.set('S', [
|
||||
(date) => Math.trunc(date.getMilliseconds() / 100),
|
||||
(date) => pad(2, Math.trunc(date.getMilliseconds() / 10)),
|
||||
(date) => pad(3, Math.trunc(date.getMilliseconds())),
|
||||
])
|
||||
.set('A', [])
|
||||
// zone
|
||||
// none of these have tests
|
||||
.set('z', [
|
||||
makeTokenFn({ timeZoneName: 'short' }, 'timeZoneName'),
|
||||
makeTokenFn({ timeZoneName: 'short' }, 'timeZoneName'),
|
||||
makeTokenFn({ timeZoneName: 'short' }, 'timeZoneName'),
|
||||
makeTokenFn({ timeZoneName: 'long' }, 'timeZoneName'),
|
||||
])
|
||||
.set('Z', [
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
// equivalent to `OOOO`.
|
||||
makeTokenFn({ timeZoneName: 'longOffset' }, 'timeZoneName'),
|
||||
])
|
||||
.set('O', [
|
||||
makeTokenFn({ timeZoneName: 'shortOffset' }, 'timeZoneName'),
|
||||
undefined,
|
||||
undefined,
|
||||
// equivalent to `ZZZZ`.
|
||||
makeTokenFn({ timeZoneName: 'longOffset' }, 'timeZoneName'),
|
||||
])
|
||||
.set('v', [
|
||||
makeTokenFn({ timeZoneName: 'shortGeneric' }, 'timeZoneName'),
|
||||
undefined,
|
||||
undefined,
|
||||
makeTokenFn({ timeZoneName: 'longGeneric' }, 'timeZoneName'),
|
||||
])
|
||||
.set('V', [])
|
||||
.set('X', [])
|
||||
.set('x', []);
|
||||
let locale;
|
||||
function getLocale(options) {
|
||||
if (!locale || locale.baseName !== options.locale) {
|
||||
locale = new Intl.Locale(options.locale || new Intl.DateTimeFormat().resolvedOptions().locale);
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
/**
|
||||
* Creates a token formatting function that returns the value of the chosen part type,
|
||||
* using the current locale's settings.
|
||||
*
|
||||
* If the date/formatter settings doesn't include the requested part type,
|
||||
* the `fallback` function is invoked, if specified. If none has been specified, returns an
|
||||
* empty string.
|
||||
*/
|
||||
function makeTokenFn(options, type, fallback) {
|
||||
let formatter;
|
||||
return (date, formatterOptions) => {
|
||||
// Allow tests to set a different locale and have that cause the formatter to be recreated
|
||||
if (!formatter ||
|
||||
formatter.resolvedOptions().locale !== formatterOptions.locale ||
|
||||
formatter.resolvedOptions().calendar !== formatterOptions.calendar) {
|
||||
formatter = new Intl.DateTimeFormat(formatterOptions.locale, {
|
||||
...options,
|
||||
calendar: options.calendar ?? formatterOptions.calendar,
|
||||
});
|
||||
}
|
||||
const parts = formatter.formatToParts(date);
|
||||
const part = parts.find((p) => p.type === type);
|
||||
return part?.value ?? (fallback ? fallback(date, formatterOptions) : '');
|
||||
};
|
||||
}
|
||||
function startOfWeek(date, options) {
|
||||
const locale = getLocale(options);
|
||||
const firstDay = locale.weekInfo.firstDay === 7 ? 0 : locale.weekInfo.firstDay;
|
||||
const day = date.getDay();
|
||||
const diff = (day < firstDay ? 7 : 0) + day - firstDay;
|
||||
date.setDate(date.getDate() - diff);
|
||||
date.setHours(0, 0, 0, 0);
|
||||
return date;
|
||||
}
|
||||
function getWeekYear(date, options) {
|
||||
const locale = getLocale(options);
|
||||
const minimalDays = locale.weekInfo.minimalDays;
|
||||
const year = date.getFullYear();
|
||||
const thisYear = startOfWeek(new Date(year, 0, minimalDays), options);
|
||||
const nextYear = startOfWeek(new Date(year + 1, 0, minimalDays), options);
|
||||
if (date.getTime() >= nextYear.getTime()) {
|
||||
return year + 1;
|
||||
}
|
||||
else if (date.getTime() >= thisYear.getTime()) {
|
||||
return year;
|
||||
}
|
||||
else {
|
||||
return year - 1;
|
||||
}
|
||||
}
|
||||
function getWeek(date, options) {
|
||||
const locale = getLocale(options);
|
||||
const weekMs = 7 * 24 * 3600 * 1000;
|
||||
const temp = startOfWeek(new Date(date), options);
|
||||
const thisYear = new Date(getWeekYear(date, options), 0, locale.weekInfo.minimalDays);
|
||||
startOfWeek(thisYear, options);
|
||||
const diff = temp.getTime() - thisYear.getTime();
|
||||
return Math.round(diff / weekMs) + 1;
|
||||
}
|
||||
function getWeekOfMonth(date, options) {
|
||||
const current = new Date(date);
|
||||
current.setHours(0, 0, 0, 0);
|
||||
const monthWeekStart = startOfWeek(new Date(date.getFullYear(), date.getMonth(), 1), options);
|
||||
const weekMs = 7 * 24 * 3600 * 1000;
|
||||
return Math.floor((date.getTime() - monthWeekStart.getTime()) / weekMs) + 1;
|
||||
}
|
||||
function getDayOfYear(date) {
|
||||
let days = 0;
|
||||
for (let i = 0; i <= date.getMonth() - 1; i++) {
|
||||
const temp = new Date(date.getFullYear(), i + 1, 0, 0, 0, 0);
|
||||
days += temp.getDate();
|
||||
}
|
||||
return days + date.getDate();
|
||||
}
|
||||
function pad(length, val) {
|
||||
return String(val).padStart(length, '0');
|
||||
}
|
68
node_modules/concurrently/dist/src/defaults.d.ts
generated
vendored
Normal file
68
node_modules/concurrently/dist/src/defaults.d.ts
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
import { SuccessCondition } from './completion-listener';
|
||||
export declare const defaultInputTarget = 0;
|
||||
/**
|
||||
* Whether process.stdin should be forwarded to child processes.
|
||||
*/
|
||||
export declare const handleInput = false;
|
||||
/**
|
||||
* How many processes to run at once.
|
||||
*/
|
||||
export declare const maxProcesses = 0;
|
||||
/**
|
||||
* Indices and names of commands whose output are not to be logged.
|
||||
*/
|
||||
export declare const hide = "";
|
||||
/**
|
||||
* The character to split <names> on.
|
||||
*/
|
||||
export declare const nameSeparator = ",";
|
||||
/**
|
||||
* Which prefix style to use when logging processes output.
|
||||
*/
|
||||
export declare const prefix = "";
|
||||
/**
|
||||
* Default prefix color.
|
||||
* @see https://www.npmjs.com/package/chalk
|
||||
*/
|
||||
export declare const prefixColors = "reset";
|
||||
/**
|
||||
* How many bytes we'll show on the command prefix.
|
||||
*/
|
||||
export declare const prefixLength = 10;
|
||||
export declare const raw = false;
|
||||
/**
|
||||
* Number of attempts of restarting a process, if it exits with non-0 code.
|
||||
*/
|
||||
export declare const restartTries = 0;
|
||||
/**
|
||||
* How many milliseconds concurrently should wait before restarting a process.
|
||||
*/
|
||||
export declare const restartDelay = 0;
|
||||
/**
|
||||
* Condition of success for concurrently itself.
|
||||
*/
|
||||
export declare const success: SuccessCondition;
|
||||
/**
|
||||
* Date format used when logging date/time.
|
||||
* @see https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
|
||||
*/
|
||||
export declare const timestampFormat = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
/**
|
||||
* Current working dir passed as option to spawn command.
|
||||
* Defaults to process.cwd()
|
||||
*/
|
||||
export declare const cwd: string | undefined;
|
||||
/**
|
||||
* Whether to show timing information for processes in console output.
|
||||
*/
|
||||
export declare const timings = false;
|
||||
/**
|
||||
* Passthrough additional arguments to commands (accessible via placeholders) instead of treating them as commands.
|
||||
*/
|
||||
export declare const passthroughArguments = false;
|
||||
/**
|
||||
* Signal to send to other processes if one exits or dies.
|
||||
*
|
||||
* Defaults to OS specific signal. (SIGTERM on Linux/MacOS)
|
||||
*/
|
||||
export declare const killSignal: string | undefined;
|
73
node_modules/concurrently/dist/src/defaults.js
generated
vendored
Normal file
73
node_modules/concurrently/dist/src/defaults.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
"use strict";
|
||||
// This file is meant to be a shared place for default configs.
|
||||
// It's read by the flow controllers, the executable, etc.
|
||||
// Refer to tests for the meaning of the different possible values.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.killSignal = exports.passthroughArguments = exports.timings = exports.cwd = exports.timestampFormat = exports.success = exports.restartDelay = exports.restartTries = exports.raw = exports.prefixLength = exports.prefixColors = exports.prefix = exports.nameSeparator = exports.hide = exports.maxProcesses = exports.handleInput = exports.defaultInputTarget = void 0;
|
||||
exports.defaultInputTarget = 0;
|
||||
/**
|
||||
* Whether process.stdin should be forwarded to child processes.
|
||||
*/
|
||||
exports.handleInput = false;
|
||||
/**
|
||||
* How many processes to run at once.
|
||||
*/
|
||||
exports.maxProcesses = 0;
|
||||
/**
|
||||
* Indices and names of commands whose output are not to be logged.
|
||||
*/
|
||||
exports.hide = '';
|
||||
/**
|
||||
* The character to split <names> on.
|
||||
*/
|
||||
exports.nameSeparator = ',';
|
||||
/**
|
||||
* Which prefix style to use when logging processes output.
|
||||
*/
|
||||
exports.prefix = '';
|
||||
/**
|
||||
* Default prefix color.
|
||||
* @see https://www.npmjs.com/package/chalk
|
||||
*/
|
||||
exports.prefixColors = 'reset';
|
||||
/**
|
||||
* How many bytes we'll show on the command prefix.
|
||||
*/
|
||||
exports.prefixLength = 10;
|
||||
exports.raw = false;
|
||||
/**
|
||||
* Number of attempts of restarting a process, if it exits with non-0 code.
|
||||
*/
|
||||
exports.restartTries = 0;
|
||||
/**
|
||||
* How many milliseconds concurrently should wait before restarting a process.
|
||||
*/
|
||||
exports.restartDelay = 0;
|
||||
/**
|
||||
* Condition of success for concurrently itself.
|
||||
*/
|
||||
exports.success = 'all';
|
||||
/**
|
||||
* Date format used when logging date/time.
|
||||
* @see https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
|
||||
*/
|
||||
exports.timestampFormat = 'yyyy-MM-dd HH:mm:ss.SSS';
|
||||
/**
|
||||
* Current working dir passed as option to spawn command.
|
||||
* Defaults to process.cwd()
|
||||
*/
|
||||
exports.cwd = undefined;
|
||||
/**
|
||||
* Whether to show timing information for processes in console output.
|
||||
*/
|
||||
exports.timings = false;
|
||||
/**
|
||||
* Passthrough additional arguments to commands (accessible via placeholders) instead of treating them as commands.
|
||||
*/
|
||||
exports.passthroughArguments = false;
|
||||
/**
|
||||
* Signal to send to other processes if one exits or dies.
|
||||
*
|
||||
* Defaults to OS specific signal. (SIGTERM on Linux/MacOS)
|
||||
*/
|
||||
exports.killSignal = undefined;
|
13
node_modules/concurrently/dist/src/flow-control/flow-controller.d.ts
generated
vendored
Normal file
13
node_modules/concurrently/dist/src/flow-control/flow-controller.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Command } from '../command';
|
||||
/**
|
||||
* Interface for a class that controls and/or watches the behavior of commands.
|
||||
*
|
||||
* This may include logging their output, creating interactions between them, or changing when they
|
||||
* actually finish.
|
||||
*/
|
||||
export interface FlowController {
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
onFinish?: () => void | Promise<void>;
|
||||
};
|
||||
}
|
2
node_modules/concurrently/dist/src/flow-control/flow-controller.js
generated
vendored
Normal file
2
node_modules/concurrently/dist/src/flow-control/flow-controller.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
30
node_modules/concurrently/dist/src/flow-control/input-handler.d.ts
generated
vendored
Normal file
30
node_modules/concurrently/dist/src/flow-control/input-handler.d.ts
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/// <reference types="node" />
|
||||
import { Readable } from 'stream';
|
||||
import { Command, CommandIdentifier } from '../command';
|
||||
import { Logger } from '../logger';
|
||||
import { FlowController } from './flow-controller';
|
||||
/**
|
||||
* Sends input from concurrently through to commands.
|
||||
*
|
||||
* Input can start with a command identifier, in which case it will be sent to that specific command.
|
||||
* For instance, `0:bla` will send `bla` to command at index `0`, and `server:stop` will send `stop`
|
||||
* to command with name `server`.
|
||||
*
|
||||
* If the input doesn't start with a command identifier, it is then always sent to the default target.
|
||||
*/
|
||||
export declare class InputHandler implements FlowController {
|
||||
private readonly logger;
|
||||
private readonly defaultInputTarget;
|
||||
private readonly inputStream?;
|
||||
private readonly pauseInputStreamOnFinish;
|
||||
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger, }: {
|
||||
inputStream?: Readable;
|
||||
logger: Logger;
|
||||
defaultInputTarget?: CommandIdentifier;
|
||||
pauseInputStreamOnFinish?: boolean;
|
||||
});
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
onFinish?: () => void | undefined;
|
||||
};
|
||||
}
|
94
node_modules/concurrently/dist/src/flow-control/input-handler.js
generated
vendored
Normal file
94
node_modules/concurrently/dist/src/flow-control/input-handler.js
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.InputHandler = void 0;
|
||||
const Rx = __importStar(require("rxjs"));
|
||||
const operators_1 = require("rxjs/operators");
|
||||
const defaults = __importStar(require("../defaults"));
|
||||
/**
|
||||
* Sends input from concurrently through to commands.
|
||||
*
|
||||
* Input can start with a command identifier, in which case it will be sent to that specific command.
|
||||
* For instance, `0:bla` will send `bla` to command at index `0`, and `server:stop` will send `stop`
|
||||
* to command with name `server`.
|
||||
*
|
||||
* If the input doesn't start with a command identifier, it is then always sent to the default target.
|
||||
*/
|
||||
class InputHandler {
|
||||
logger;
|
||||
defaultInputTarget;
|
||||
inputStream;
|
||||
pauseInputStreamOnFinish;
|
||||
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger, }) {
|
||||
this.logger = logger;
|
||||
this.defaultInputTarget = defaultInputTarget || defaults.defaultInputTarget;
|
||||
this.inputStream = inputStream;
|
||||
this.pauseInputStreamOnFinish = pauseInputStreamOnFinish !== false;
|
||||
}
|
||||
handle(commands) {
|
||||
const { inputStream } = this;
|
||||
if (!inputStream) {
|
||||
return { commands };
|
||||
}
|
||||
const commandsMap = new Map();
|
||||
for (const command of commands) {
|
||||
commandsMap.set(command.index.toString(), command);
|
||||
commandsMap.set(command.name, command);
|
||||
}
|
||||
Rx.fromEvent(inputStream, 'data')
|
||||
.pipe((0, operators_1.map)((data) => String(data)))
|
||||
.subscribe((data) => {
|
||||
let command, input;
|
||||
const dataParts = data.split(/:(.+)/s);
|
||||
let target = dataParts[0];
|
||||
if (dataParts.length > 1 && (command = commandsMap.get(target))) {
|
||||
input = dataParts[1];
|
||||
}
|
||||
else {
|
||||
// If `target` does not match a registered command,
|
||||
// fallback to `defaultInputTarget` and forward the whole input data
|
||||
target = this.defaultInputTarget.toString();
|
||||
command = commandsMap.get(target);
|
||||
input = data;
|
||||
}
|
||||
if (command && command.stdin) {
|
||||
command.stdin.write(input);
|
||||
}
|
||||
else {
|
||||
this.logger.logGlobalEvent(`Unable to find command "${target}", or it has no stdin open\n`);
|
||||
}
|
||||
});
|
||||
return {
|
||||
commands,
|
||||
onFinish: () => {
|
||||
if (this.pauseInputStreamOnFinish) {
|
||||
// https://github.com/kimmobrunfeldt/concurrently/issues/252
|
||||
inputStream.pause();
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.InputHandler = InputHandler;
|
21
node_modules/concurrently/dist/src/flow-control/kill-on-signal.d.ts
generated
vendored
Normal file
21
node_modules/concurrently/dist/src/flow-control/kill-on-signal.d.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import EventEmitter from 'events';
|
||||
import { Command } from '../command';
|
||||
import { FlowController } from './flow-controller';
|
||||
/**
|
||||
* Watches the main concurrently process for signals and sends the same signal down to each spawned
|
||||
* command.
|
||||
*/
|
||||
export declare class KillOnSignal implements FlowController {
|
||||
private readonly process;
|
||||
private readonly abortController?;
|
||||
constructor({ process, abortController, }: {
|
||||
process: EventEmitter;
|
||||
abortController?: AbortController;
|
||||
});
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
onFinish: () => void;
|
||||
};
|
||||
}
|
47
node_modules/concurrently/dist/src/flow-control/kill-on-signal.js
generated
vendored
Normal file
47
node_modules/concurrently/dist/src/flow-control/kill-on-signal.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.KillOnSignal = void 0;
|
||||
const operators_1 = require("rxjs/operators");
|
||||
const SIGNALS = ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
||||
/**
|
||||
* Watches the main concurrently process for signals and sends the same signal down to each spawned
|
||||
* command.
|
||||
*/
|
||||
class KillOnSignal {
|
||||
process;
|
||||
abortController;
|
||||
constructor({ process, abortController, }) {
|
||||
this.process = process;
|
||||
this.abortController = abortController;
|
||||
}
|
||||
handle(commands) {
|
||||
let caughtSignal;
|
||||
const signalListener = (signal) => {
|
||||
caughtSignal = signal;
|
||||
this.abortController?.abort();
|
||||
commands.forEach((command) => command.kill(signal));
|
||||
};
|
||||
SIGNALS.forEach((signal) => this.process.on(signal, signalListener));
|
||||
return {
|
||||
commands: commands.map((command) => {
|
||||
const closeStream = command.close.pipe((0, operators_1.map)((exitInfo) => {
|
||||
const exitCode = caughtSignal === 'SIGINT' ? 0 : exitInfo.exitCode;
|
||||
return { ...exitInfo, exitCode };
|
||||
}));
|
||||
// Return a proxy so that mutations happen on the original Command object.
|
||||
// If either `Object.assign()` or `Object.create()` were used, it'd be hard to
|
||||
// reflect the mutations on Command objects referenced by previous flow controllers.
|
||||
return new Proxy(command, {
|
||||
get(target, prop) {
|
||||
return prop === 'close' ? closeStream : target[prop];
|
||||
},
|
||||
});
|
||||
}),
|
||||
onFinish: () => {
|
||||
// Avoids MaxListenersExceededWarning when running programmatically
|
||||
SIGNALS.forEach((signal) => this.process.off(signal, signalListener));
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.KillOnSignal = KillOnSignal;
|
23
node_modules/concurrently/dist/src/flow-control/kill-others.d.ts
generated
vendored
Normal file
23
node_modules/concurrently/dist/src/flow-control/kill-others.d.ts
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/// <reference types="node" />
|
||||
import { Command } from '../command';
|
||||
import { Logger } from '../logger';
|
||||
import { FlowController } from './flow-controller';
|
||||
export type ProcessCloseCondition = 'failure' | 'success';
|
||||
/**
|
||||
* Sends a SIGTERM signal to all commands when one of the commands exits with a matching condition.
|
||||
*/
|
||||
export declare class KillOthers implements FlowController {
|
||||
private readonly logger;
|
||||
private readonly abortController?;
|
||||
private readonly conditions;
|
||||
private readonly killSignal;
|
||||
constructor({ logger, abortController, conditions, killSignal, }: {
|
||||
logger: Logger;
|
||||
abortController?: AbortController;
|
||||
conditions: ProcessCloseCondition | ProcessCloseCondition[];
|
||||
killSignal: string | undefined;
|
||||
});
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
};
|
||||
}
|
41
node_modules/concurrently/dist/src/flow-control/kill-others.js
generated
vendored
Normal file
41
node_modules/concurrently/dist/src/flow-control/kill-others.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.KillOthers = void 0;
|
||||
const lodash_1 = __importDefault(require("lodash"));
|
||||
const operators_1 = require("rxjs/operators");
|
||||
const command_1 = require("../command");
|
||||
/**
|
||||
* Sends a SIGTERM signal to all commands when one of the commands exits with a matching condition.
|
||||
*/
|
||||
class KillOthers {
|
||||
logger;
|
||||
abortController;
|
||||
conditions;
|
||||
killSignal;
|
||||
constructor({ logger, abortController, conditions, killSignal, }) {
|
||||
this.logger = logger;
|
||||
this.abortController = abortController;
|
||||
this.conditions = lodash_1.default.castArray(conditions);
|
||||
this.killSignal = killSignal;
|
||||
}
|
||||
handle(commands) {
|
||||
const conditions = this.conditions.filter((condition) => condition === 'failure' || condition === 'success');
|
||||
if (!conditions.length) {
|
||||
return { commands };
|
||||
}
|
||||
const closeStates = commands.map((command) => command.close.pipe((0, operators_1.map)(({ exitCode }) => exitCode === 0 ? 'success' : 'failure'), (0, operators_1.filter)((state) => conditions.includes(state))));
|
||||
closeStates.forEach((closeState) => closeState.subscribe(() => {
|
||||
this.abortController?.abort();
|
||||
const killableCommands = commands.filter((command) => command_1.Command.canKill(command));
|
||||
if (killableCommands.length) {
|
||||
this.logger.logGlobalEvent(`Sending ${this.killSignal || 'SIGTERM'} to other processes..`);
|
||||
killableCommands.forEach((command) => command.kill(this.killSignal));
|
||||
}
|
||||
}));
|
||||
return { commands };
|
||||
}
|
||||
}
|
||||
exports.KillOthers = KillOthers;
|
15
node_modules/concurrently/dist/src/flow-control/log-error.d.ts
generated
vendored
Normal file
15
node_modules/concurrently/dist/src/flow-control/log-error.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Command } from '../command';
|
||||
import { Logger } from '../logger';
|
||||
import { FlowController } from './flow-controller';
|
||||
/**
|
||||
* Logs when commands failed executing, e.g. due to the executable not existing in the system.
|
||||
*/
|
||||
export declare class LogError implements FlowController {
|
||||
private readonly logger;
|
||||
constructor({ logger }: {
|
||||
logger: Logger;
|
||||
});
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
};
|
||||
}
|
21
node_modules/concurrently/dist/src/flow-control/log-error.js
generated
vendored
Normal file
21
node_modules/concurrently/dist/src/flow-control/log-error.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LogError = void 0;
|
||||
/**
|
||||
* Logs when commands failed executing, e.g. due to the executable not existing in the system.
|
||||
*/
|
||||
class LogError {
|
||||
logger;
|
||||
constructor({ logger }) {
|
||||
this.logger = logger;
|
||||
}
|
||||
handle(commands) {
|
||||
commands.forEach((command) => command.error.subscribe((event) => {
|
||||
this.logger.logCommandEvent(`Error occurred when executing command: ${command.command}`, command);
|
||||
const errorText = String(event instanceof Error ? event.stack || event : event);
|
||||
this.logger.logCommandEvent(errorText, command);
|
||||
}));
|
||||
return { commands };
|
||||
}
|
||||
}
|
||||
exports.LogError = LogError;
|
15
node_modules/concurrently/dist/src/flow-control/log-exit.d.ts
generated
vendored
Normal file
15
node_modules/concurrently/dist/src/flow-control/log-exit.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Command } from '../command';
|
||||
import { Logger } from '../logger';
|
||||
import { FlowController } from './flow-controller';
|
||||
/**
|
||||
* Logs the exit code/signal of commands.
|
||||
*/
|
||||
export declare class LogExit implements FlowController {
|
||||
private readonly logger;
|
||||
constructor({ logger }: {
|
||||
logger: Logger;
|
||||
});
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
};
|
||||
}
|
19
node_modules/concurrently/dist/src/flow-control/log-exit.js
generated
vendored
Normal file
19
node_modules/concurrently/dist/src/flow-control/log-exit.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LogExit = void 0;
|
||||
/**
|
||||
* Logs the exit code/signal of commands.
|
||||
*/
|
||||
class LogExit {
|
||||
logger;
|
||||
constructor({ logger }) {
|
||||
this.logger = logger;
|
||||
}
|
||||
handle(commands) {
|
||||
commands.forEach((command) => command.close.subscribe(({ exitCode }) => {
|
||||
this.logger.logCommandEvent(`${command.command} exited with code ${exitCode}`, command);
|
||||
}));
|
||||
return { commands };
|
||||
}
|
||||
}
|
||||
exports.LogExit = LogExit;
|
15
node_modules/concurrently/dist/src/flow-control/log-output.d.ts
generated
vendored
Normal file
15
node_modules/concurrently/dist/src/flow-control/log-output.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Command } from '../command';
|
||||
import { Logger } from '../logger';
|
||||
import { FlowController } from './flow-controller';
|
||||
/**
|
||||
* Logs the stdout and stderr output of commands.
|
||||
*/
|
||||
export declare class LogOutput implements FlowController {
|
||||
private readonly logger;
|
||||
constructor({ logger }: {
|
||||
logger: Logger;
|
||||
});
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
};
|
||||
}
|
20
node_modules/concurrently/dist/src/flow-control/log-output.js
generated
vendored
Normal file
20
node_modules/concurrently/dist/src/flow-control/log-output.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LogOutput = void 0;
|
||||
/**
|
||||
* Logs the stdout and stderr output of commands.
|
||||
*/
|
||||
class LogOutput {
|
||||
logger;
|
||||
constructor({ logger }) {
|
||||
this.logger = logger;
|
||||
}
|
||||
handle(commands) {
|
||||
commands.forEach((command) => {
|
||||
command.stdout.subscribe((text) => this.logger.logCommandText(text.toString(), command));
|
||||
command.stderr.subscribe((text) => this.logger.logCommandText(text.toString(), command));
|
||||
});
|
||||
return { commands };
|
||||
}
|
||||
}
|
||||
exports.LogOutput = LogOutput;
|
31
node_modules/concurrently/dist/src/flow-control/log-timings.d.ts
generated
vendored
Normal file
31
node_modules/concurrently/dist/src/flow-control/log-timings.d.ts
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import { CloseEvent, Command } from '../command';
|
||||
import { Logger } from '../logger';
|
||||
import { FlowController } from './flow-controller';
|
||||
type TimingInfo = {
|
||||
name: string;
|
||||
duration: string;
|
||||
'exit code': string | number;
|
||||
killed: boolean;
|
||||
command: string;
|
||||
};
|
||||
/**
|
||||
* Logs timing information about commands as they start/stop and then a summary when all commands finish.
|
||||
*/
|
||||
export declare class LogTimings implements FlowController {
|
||||
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode, }: CloseEvent): TimingInfo;
|
||||
private readonly logger?;
|
||||
private readonly dateFormatter;
|
||||
constructor({ logger, timestampFormat, }: {
|
||||
logger?: Logger;
|
||||
timestampFormat?: string;
|
||||
});
|
||||
private printExitInfoTimingTable;
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
onFinish?: undefined;
|
||||
} | {
|
||||
commands: Command[];
|
||||
onFinish: () => void;
|
||||
};
|
||||
}
|
||||
export {};
|
94
node_modules/concurrently/dist/src/flow-control/log-timings.js
generated
vendored
Normal file
94
node_modules/concurrently/dist/src/flow-control/log-timings.js
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LogTimings = void 0;
|
||||
const assert = __importStar(require("assert"));
|
||||
const lodash_1 = __importDefault(require("lodash"));
|
||||
const Rx = __importStar(require("rxjs"));
|
||||
const operators_1 = require("rxjs/operators");
|
||||
const date_format_1 = require("../date-format");
|
||||
const defaults = __importStar(require("../defaults"));
|
||||
/**
|
||||
* Logs timing information about commands as they start/stop and then a summary when all commands finish.
|
||||
*/
|
||||
class LogTimings {
|
||||
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode, }) {
|
||||
const readableDurationMs = (timings.endDate.getTime() - timings.startDate.getTime()).toLocaleString();
|
||||
return {
|
||||
name: command.name,
|
||||
duration: readableDurationMs,
|
||||
'exit code': exitCode,
|
||||
killed,
|
||||
command: command.command,
|
||||
};
|
||||
}
|
||||
logger;
|
||||
dateFormatter;
|
||||
constructor({ logger, timestampFormat = defaults.timestampFormat, }) {
|
||||
this.logger = logger;
|
||||
this.dateFormatter = new date_format_1.DateFormatter(timestampFormat);
|
||||
}
|
||||
printExitInfoTimingTable(exitInfos) {
|
||||
assert.ok(this.logger);
|
||||
const exitInfoTable = (0, lodash_1.default)(exitInfos)
|
||||
.sortBy(({ timings }) => timings.durationSeconds)
|
||||
.reverse()
|
||||
.map(LogTimings.mapCloseEventToTimingInfo)
|
||||
.value();
|
||||
this.logger.logGlobalEvent('Timings:');
|
||||
this.logger.logTable(exitInfoTable);
|
||||
return exitInfos;
|
||||
}
|
||||
handle(commands) {
|
||||
const { logger } = this;
|
||||
if (!logger) {
|
||||
return { commands };
|
||||
}
|
||||
// individual process timings
|
||||
commands.forEach((command) => {
|
||||
command.timer.subscribe(({ startDate, endDate }) => {
|
||||
if (!endDate) {
|
||||
const formattedStartDate = this.dateFormatter.format(startDate);
|
||||
logger.logCommandEvent(`${command.command} started at ${formattedStartDate}`, command);
|
||||
}
|
||||
else {
|
||||
const durationMs = endDate.getTime() - startDate.getTime();
|
||||
const formattedEndDate = this.dateFormatter.format(endDate);
|
||||
logger.logCommandEvent(`${command.command} stopped at ${formattedEndDate} after ${durationMs.toLocaleString()}ms`, command);
|
||||
}
|
||||
});
|
||||
});
|
||||
// overall summary timings
|
||||
const closeStreams = commands.map((command) => command.close);
|
||||
const finished = new Rx.Subject();
|
||||
const allProcessesClosed = Rx.merge(...closeStreams).pipe((0, operators_1.bufferCount)(closeStreams.length), (0, operators_1.take)(1), (0, operators_1.combineLatestWith)(finished));
|
||||
allProcessesClosed.subscribe(([exitInfos]) => this.printExitInfoTimingTable(exitInfos));
|
||||
return { commands, onFinish: () => finished.next() };
|
||||
}
|
||||
}
|
||||
exports.LogTimings = LogTimings;
|
13
node_modules/concurrently/dist/src/flow-control/logger-padding.d.ts
generated
vendored
Normal file
13
node_modules/concurrently/dist/src/flow-control/logger-padding.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Command } from '../command';
|
||||
import { Logger } from '../logger';
|
||||
import { FlowController } from './flow-controller';
|
||||
export declare class LoggerPadding implements FlowController {
|
||||
private readonly logger;
|
||||
constructor({ logger }: {
|
||||
logger: Logger;
|
||||
});
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
onFinish: () => void;
|
||||
};
|
||||
}
|
35
node_modules/concurrently/dist/src/flow-control/logger-padding.js
generated
vendored
Normal file
35
node_modules/concurrently/dist/src/flow-control/logger-padding.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LoggerPadding = void 0;
|
||||
class LoggerPadding {
|
||||
logger;
|
||||
constructor({ logger }) {
|
||||
this.logger = logger;
|
||||
}
|
||||
handle(commands) {
|
||||
// Sometimes there's limited concurrency, so not all commands will spawn straight away.
|
||||
// Compute the prefix length now, which works for all styles but those with a PID.
|
||||
let length = commands.reduce((length, command) => {
|
||||
const content = this.logger.getPrefixContent(command);
|
||||
return Math.max(length, content?.value.length || 0);
|
||||
}, 0);
|
||||
this.logger.setPrefixLength(length);
|
||||
// The length of prefixes is somewhat stable, except for PIDs, which might change when a
|
||||
// process spawns (e.g. PIDs might look like 1, 10 or 100), therefore listen to command starts
|
||||
// and update the prefix length when this happens.
|
||||
const subs = commands.map((command) => command.timer.subscribe((event) => {
|
||||
if (!event.endDate) {
|
||||
const content = this.logger.getPrefixContent(command);
|
||||
length = Math.max(length, content?.value.length || 0);
|
||||
this.logger.setPrefixLength(length);
|
||||
}
|
||||
}));
|
||||
return {
|
||||
commands,
|
||||
onFinish() {
|
||||
subs.forEach((sub) => sub.unsubscribe());
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.LoggerPadding = LoggerPadding;
|
23
node_modules/concurrently/dist/src/flow-control/restart-process.d.ts
generated
vendored
Normal file
23
node_modules/concurrently/dist/src/flow-control/restart-process.d.ts
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import * as Rx from 'rxjs';
|
||||
import { Command } from '../command';
|
||||
import { Logger } from '../logger';
|
||||
import { FlowController } from './flow-controller';
|
||||
export type RestartDelay = number | 'exponential';
|
||||
/**
|
||||
* Restarts commands that fail up to a defined number of times.
|
||||
*/
|
||||
export declare class RestartProcess implements FlowController {
|
||||
private readonly logger;
|
||||
private readonly scheduler?;
|
||||
private readonly delay;
|
||||
readonly tries: number;
|
||||
constructor({ delay, tries, logger, scheduler, }: {
|
||||
delay?: RestartDelay;
|
||||
tries?: number;
|
||||
logger: Logger;
|
||||
scheduler?: Rx.SchedulerLike;
|
||||
});
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
};
|
||||
}
|
88
node_modules/concurrently/dist/src/flow-control/restart-process.js
generated
vendored
Normal file
88
node_modules/concurrently/dist/src/flow-control/restart-process.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RestartProcess = void 0;
|
||||
const Rx = __importStar(require("rxjs"));
|
||||
const operators_1 = require("rxjs/operators");
|
||||
const defaults = __importStar(require("../defaults"));
|
||||
/**
|
||||
* Restarts commands that fail up to a defined number of times.
|
||||
*/
|
||||
class RestartProcess {
|
||||
logger;
|
||||
scheduler;
|
||||
delay;
|
||||
tries;
|
||||
constructor({ delay, tries, logger, scheduler, }) {
|
||||
this.logger = logger;
|
||||
this.delay = delay ?? 0;
|
||||
this.tries = tries != null ? +tries : defaults.restartTries;
|
||||
this.tries = this.tries < 0 ? Infinity : this.tries;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
handle(commands) {
|
||||
if (this.tries === 0) {
|
||||
return { commands };
|
||||
}
|
||||
const delayOperator = (0, operators_1.delayWhen)((_, index) => {
|
||||
const { delay } = this;
|
||||
const value = delay === 'exponential' ? Math.pow(2, index) * 1000 : delay;
|
||||
return Rx.timer(value, this.scheduler);
|
||||
});
|
||||
commands
|
||||
.map((command) => command.close.pipe((0, operators_1.take)(this.tries), (0, operators_1.takeWhile)(({ exitCode }) => exitCode !== 0)))
|
||||
.map((failure, index) => Rx.merge(
|
||||
// Delay the emission (so that the restarts happen on time),
|
||||
// explicitly telling the subscriber that a restart is needed
|
||||
failure.pipe(delayOperator, (0, operators_1.map)(() => true)),
|
||||
// Skip the first N emissions (as these would be duplicates of the above),
|
||||
// meaning it will be empty because of success, or failed all N times,
|
||||
// and no more restarts should be attempted.
|
||||
failure.pipe((0, operators_1.skip)(this.tries), (0, operators_1.map)(() => false), (0, operators_1.defaultIfEmpty)(false))).subscribe((restart) => {
|
||||
const command = commands[index];
|
||||
if (restart) {
|
||||
this.logger.logCommandEvent(`${command.command} restarted`, command);
|
||||
command.start();
|
||||
}
|
||||
}));
|
||||
return {
|
||||
commands: commands.map((command) => {
|
||||
const closeStream = command.close.pipe((0, operators_1.filter)(({ exitCode }, emission) => {
|
||||
// We let all success codes pass, and failures only after restarting won't happen again
|
||||
return exitCode === 0 || emission >= this.tries;
|
||||
}));
|
||||
// Return a proxy so that mutations happen on the original Command object.
|
||||
// If either `Object.assign()` or `Object.create()` were used, it'd be hard to
|
||||
// reflect the mutations on Command objects referenced by previous flow controllers.
|
||||
return new Proxy(command, {
|
||||
get(target, prop) {
|
||||
return prop === 'close' ? closeStream : target[prop];
|
||||
},
|
||||
});
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.RestartProcess = RestartProcess;
|
21
node_modules/concurrently/dist/src/flow-control/teardown.d.ts
generated
vendored
Normal file
21
node_modules/concurrently/dist/src/flow-control/teardown.d.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { Command, SpawnCommand } from '../command';
|
||||
import { Logger } from '../logger';
|
||||
import { FlowController } from './flow-controller';
|
||||
export declare class Teardown implements FlowController {
|
||||
private readonly logger;
|
||||
private readonly spawn;
|
||||
private readonly teardown;
|
||||
constructor({ logger, spawn, commands, }: {
|
||||
logger: Logger;
|
||||
/**
|
||||
* Which function to use to spawn commands.
|
||||
* Defaults to the same used by the rest of concurrently.
|
||||
*/
|
||||
spawn?: SpawnCommand;
|
||||
commands: readonly string[];
|
||||
});
|
||||
handle(commands: Command[]): {
|
||||
commands: Command[];
|
||||
onFinish: () => Promise<void>;
|
||||
};
|
||||
}
|
72
node_modules/concurrently/dist/src/flow-control/teardown.js
generated
vendored
Normal file
72
node_modules/concurrently/dist/src/flow-control/teardown.js
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Teardown = void 0;
|
||||
const Rx = __importStar(require("rxjs"));
|
||||
const spawn_1 = require("../spawn");
|
||||
class Teardown {
|
||||
logger;
|
||||
spawn;
|
||||
teardown;
|
||||
constructor({ logger, spawn, commands, }) {
|
||||
this.logger = logger;
|
||||
this.spawn = spawn || spawn_1.spawn;
|
||||
this.teardown = commands;
|
||||
}
|
||||
handle(commands) {
|
||||
const { logger, teardown, spawn } = this;
|
||||
const onFinish = async () => {
|
||||
if (!teardown.length) {
|
||||
return;
|
||||
}
|
||||
for (const command of teardown) {
|
||||
logger.logGlobalEvent(`Running teardown command "${command}"`);
|
||||
const child = spawn(command, (0, spawn_1.getSpawnOpts)({ stdio: 'raw' }));
|
||||
const error = Rx.fromEvent(child, 'error');
|
||||
const close = Rx.fromEvent(child, 'close');
|
||||
try {
|
||||
const [exitCode, signal] = await Promise.race([
|
||||
Rx.firstValueFrom(error).then((event) => {
|
||||
throw event;
|
||||
}),
|
||||
Rx.firstValueFrom(close).then((event) => event),
|
||||
]);
|
||||
logger.logGlobalEvent(`Teardown command "${command}" exited with code ${exitCode ?? signal}`);
|
||||
if (signal === 'SIGINT') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
const errorText = String(error instanceof Error ? error.stack || error : error);
|
||||
logger.logGlobalEvent(`Teardown command "${command}" errored:`);
|
||||
logger.logGlobalEvent(errorText);
|
||||
return Promise.reject();
|
||||
}
|
||||
}
|
||||
};
|
||||
return { commands, onFinish };
|
||||
}
|
||||
}
|
||||
exports.Teardown = Teardown;
|
84
node_modules/concurrently/dist/src/index.d.ts
generated
vendored
Normal file
84
node_modules/concurrently/dist/src/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/// <reference types="node" />
|
||||
import { Readable } from 'stream';
|
||||
import { CloseEvent, Command, CommandIdentifier, TimerEvent } from './command';
|
||||
import { concurrently as createConcurrently, ConcurrentlyCommandInput, ConcurrentlyOptions as BaseConcurrentlyOptions, ConcurrentlyResult } from './concurrently';
|
||||
import { FlowController } from './flow-control/flow-controller';
|
||||
import { InputHandler } from './flow-control/input-handler';
|
||||
import { KillOnSignal } from './flow-control/kill-on-signal';
|
||||
import { KillOthers, ProcessCloseCondition } from './flow-control/kill-others';
|
||||
import { LogError } from './flow-control/log-error';
|
||||
import { LogExit } from './flow-control/log-exit';
|
||||
import { LogOutput } from './flow-control/log-output';
|
||||
import { LogTimings } from './flow-control/log-timings';
|
||||
import { RestartDelay, RestartProcess } from './flow-control/restart-process';
|
||||
import { Logger } from './logger';
|
||||
export type ConcurrentlyOptions = Omit<BaseConcurrentlyOptions, 'abortSignal' | 'hide'> & {
|
||||
/**
|
||||
* Which command(s) should have their output hidden.
|
||||
*/
|
||||
hide?: CommandIdentifier | CommandIdentifier[];
|
||||
/**
|
||||
* The prefix format to use when logging a command's output.
|
||||
* Defaults to the command's index.
|
||||
*/
|
||||
prefix?: string;
|
||||
/**
|
||||
* How many characters should a prefix have at most, used when the prefix format is `command`.
|
||||
*/
|
||||
prefixLength?: number;
|
||||
/**
|
||||
* Pads short prefixes with spaces so that all prefixes have the same length.
|
||||
*/
|
||||
padPrefix?: boolean;
|
||||
/**
|
||||
* Whether output should be formatted to include prefixes and whether "event" logs will be logged.
|
||||
*/
|
||||
raw?: boolean;
|
||||
/**
|
||||
* Date format used when logging date/time.
|
||||
* @see https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
|
||||
*/
|
||||
timestampFormat?: string;
|
||||
defaultInputTarget?: CommandIdentifier;
|
||||
inputStream?: Readable;
|
||||
handleInput?: boolean;
|
||||
pauseInputStreamOnFinish?: boolean;
|
||||
/**
|
||||
* How much time in milliseconds to wait before restarting a command.
|
||||
*
|
||||
* @see RestartProcess
|
||||
*/
|
||||
restartDelay?: RestartDelay;
|
||||
/**
|
||||
* How many times commands should be restarted when they exit with a failure.
|
||||
*
|
||||
* @see RestartProcess
|
||||
*/
|
||||
restartTries?: number;
|
||||
/**
|
||||
* Under which condition(s) should other commands be killed when the first one exits.
|
||||
*
|
||||
* @see KillOthers
|
||||
*/
|
||||
killOthers?: ProcessCloseCondition | ProcessCloseCondition[];
|
||||
/**
|
||||
* Whether to output timing information for processes.
|
||||
*
|
||||
* @see LogTimings
|
||||
*/
|
||||
timings?: boolean;
|
||||
/**
|
||||
* Clean up command(s) to execute before exiting concurrently.
|
||||
* These won't be prefixed and don't affect concurrently's exit code.
|
||||
*/
|
||||
teardown?: readonly string[];
|
||||
/**
|
||||
* List of additional arguments passed that will get replaced in each command.
|
||||
* If not defined, no argument replacing will happen.
|
||||
*/
|
||||
additionalArguments?: string[];
|
||||
};
|
||||
export declare function concurrently(commands: ConcurrentlyCommandInput[], options?: Partial<ConcurrentlyOptions>): ConcurrentlyResult;
|
||||
export { ConcurrentlyCommandInput, ConcurrentlyResult, createConcurrently, Logger };
|
||||
export { CloseEvent, Command, CommandIdentifier, TimerEvent };
|
||||
export { FlowController, InputHandler, KillOnSignal, KillOthers, LogError, LogExit, LogOutput, LogTimings, RestartProcess, };
|
93
node_modules/concurrently/dist/src/index.js
generated
vendored
Normal file
93
node_modules/concurrently/dist/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RestartProcess = exports.LogTimings = exports.LogOutput = exports.LogExit = exports.LogError = exports.KillOthers = exports.KillOnSignal = exports.InputHandler = exports.Command = exports.Logger = exports.createConcurrently = exports.concurrently = void 0;
|
||||
const lodash_1 = __importDefault(require("lodash"));
|
||||
const command_1 = require("./command");
|
||||
Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return command_1.Command; } });
|
||||
const concurrently_1 = require("./concurrently");
|
||||
Object.defineProperty(exports, "createConcurrently", { enumerable: true, get: function () { return concurrently_1.concurrently; } });
|
||||
const input_handler_1 = require("./flow-control/input-handler");
|
||||
Object.defineProperty(exports, "InputHandler", { enumerable: true, get: function () { return input_handler_1.InputHandler; } });
|
||||
const kill_on_signal_1 = require("./flow-control/kill-on-signal");
|
||||
Object.defineProperty(exports, "KillOnSignal", { enumerable: true, get: function () { return kill_on_signal_1.KillOnSignal; } });
|
||||
const kill_others_1 = require("./flow-control/kill-others");
|
||||
Object.defineProperty(exports, "KillOthers", { enumerable: true, get: function () { return kill_others_1.KillOthers; } });
|
||||
const log_error_1 = require("./flow-control/log-error");
|
||||
Object.defineProperty(exports, "LogError", { enumerable: true, get: function () { return log_error_1.LogError; } });
|
||||
const log_exit_1 = require("./flow-control/log-exit");
|
||||
Object.defineProperty(exports, "LogExit", { enumerable: true, get: function () { return log_exit_1.LogExit; } });
|
||||
const log_output_1 = require("./flow-control/log-output");
|
||||
Object.defineProperty(exports, "LogOutput", { enumerable: true, get: function () { return log_output_1.LogOutput; } });
|
||||
const log_timings_1 = require("./flow-control/log-timings");
|
||||
Object.defineProperty(exports, "LogTimings", { enumerable: true, get: function () { return log_timings_1.LogTimings; } });
|
||||
const logger_padding_1 = require("./flow-control/logger-padding");
|
||||
const restart_process_1 = require("./flow-control/restart-process");
|
||||
Object.defineProperty(exports, "RestartProcess", { enumerable: true, get: function () { return restart_process_1.RestartProcess; } });
|
||||
const teardown_1 = require("./flow-control/teardown");
|
||||
const logger_1 = require("./logger");
|
||||
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
|
||||
function concurrently(commands, options = {}) {
|
||||
// To avoid empty strings from hiding the output of commands that don't have a name,
|
||||
// keep in the list of commands to hide only strings with some length.
|
||||
// This might happen through the CLI when no `--hide` argument is specified, for example.
|
||||
const hide = lodash_1.default.castArray(options.hide).filter((id) => id || id === 0);
|
||||
const logger = options.logger ||
|
||||
new logger_1.Logger({
|
||||
hide,
|
||||
prefixFormat: options.prefix,
|
||||
commandLength: options.prefixLength,
|
||||
raw: options.raw,
|
||||
timestampFormat: options.timestampFormat,
|
||||
});
|
||||
if (options.prefixColors === false) {
|
||||
logger.toggleColors(false);
|
||||
}
|
||||
const abortController = new AbortController();
|
||||
return (0, concurrently_1.concurrently)(commands, {
|
||||
maxProcesses: options.maxProcesses,
|
||||
raw: options.raw,
|
||||
successCondition: options.successCondition,
|
||||
cwd: options.cwd,
|
||||
hide,
|
||||
logger,
|
||||
outputStream: options.outputStream || process.stdout,
|
||||
group: options.group,
|
||||
abortSignal: abortController.signal,
|
||||
controllers: [
|
||||
// LoggerPadding needs to run before any other controllers that might output something
|
||||
...(options.padPrefix ? [new logger_padding_1.LoggerPadding({ logger })] : []),
|
||||
new log_error_1.LogError({ logger }),
|
||||
new log_output_1.LogOutput({ logger }),
|
||||
new log_exit_1.LogExit({ logger }),
|
||||
new input_handler_1.InputHandler({
|
||||
logger,
|
||||
defaultInputTarget: options.defaultInputTarget,
|
||||
inputStream: options.inputStream || (options.handleInput ? process.stdin : undefined),
|
||||
pauseInputStreamOnFinish: options.pauseInputStreamOnFinish,
|
||||
}),
|
||||
new kill_on_signal_1.KillOnSignal({ process, abortController }),
|
||||
new restart_process_1.RestartProcess({
|
||||
logger,
|
||||
delay: options.restartDelay,
|
||||
tries: options.restartTries,
|
||||
}),
|
||||
new kill_others_1.KillOthers({
|
||||
logger,
|
||||
conditions: options.killOthers || [],
|
||||
killSignal: options.killSignal,
|
||||
abortController,
|
||||
}),
|
||||
new log_timings_1.LogTimings({
|
||||
logger: options.timings ? logger : undefined,
|
||||
timestampFormat: options.timestampFormat,
|
||||
}),
|
||||
new teardown_1.Teardown({ logger, spawn: options.spawn, commands: options.teardown || [] }),
|
||||
],
|
||||
prefixColors: options.prefixColors || [],
|
||||
additionalArguments: options.additionalArguments,
|
||||
});
|
||||
}
|
||||
exports.concurrently = concurrently;
|
8
node_modules/concurrently/dist/src/jsonc.d.ts
generated
vendored
Normal file
8
node_modules/concurrently/dist/src/jsonc.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
declare const JSONC: {
|
||||
parse: (text: string) => any;
|
||||
stringify: {
|
||||
(value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string;
|
||||
(value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string;
|
||||
};
|
||||
};
|
||||
export default JSONC;
|
29
node_modules/concurrently/dist/src/jsonc.js
generated
vendored
Normal file
29
node_modules/concurrently/dist/src/jsonc.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
/*
|
||||
ORIGINAL https://www.npmjs.com/package/tiny-jsonc
|
||||
BY Fabio Spampinato
|
||||
MIT license
|
||||
|
||||
Copied due to the dependency not being compatible with CommonJS
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/* HELPERS */
|
||||
const stringOrCommentRe = /("(?:\\?[^])*?")|(\/\/.*)|(\/\*[^]*?\*\/)/g;
|
||||
const stringOrTrailingCommaRe = /("(?:\\?[^])*?")|(,\s*)(?=]|})/g;
|
||||
/* MAIN */
|
||||
const JSONC = {
|
||||
parse: (text) => {
|
||||
text = String(text); // To be extra safe
|
||||
try {
|
||||
// Fast path for valid JSON
|
||||
return JSON.parse(text);
|
||||
}
|
||||
catch {
|
||||
// Slow path for JSONC and invalid inputs
|
||||
return JSON.parse(text.replace(stringOrCommentRe, '$1').replace(stringOrTrailingCommaRe, '$1'));
|
||||
}
|
||||
},
|
||||
stringify: JSON.stringify,
|
||||
};
|
||||
/* EXPORT */
|
||||
exports.default = JSONC;
|
87
node_modules/concurrently/dist/src/logger.d.ts
generated
vendored
Normal file
87
node_modules/concurrently/dist/src/logger.d.ts
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
import * as Rx from 'rxjs';
|
||||
import { Command, CommandIdentifier } from './command';
|
||||
export declare class Logger {
|
||||
private readonly hide;
|
||||
private readonly raw;
|
||||
private readonly prefixFormat?;
|
||||
private readonly commandLength;
|
||||
private readonly dateFormatter;
|
||||
private chalk;
|
||||
/**
|
||||
* How many characters should a prefix have.
|
||||
* Prefixes shorter than this will be padded with spaces to the right.
|
||||
*/
|
||||
private prefixLength;
|
||||
/**
|
||||
* Last character emitted, and from which command.
|
||||
* If `undefined`, then nothing has been logged yet.
|
||||
*/
|
||||
private lastWrite?;
|
||||
/**
|
||||
* Observable that emits when there's been output logged.
|
||||
* If `command` is is `undefined`, then the log is for a global event.
|
||||
*/
|
||||
readonly output: Rx.Subject<{
|
||||
command: Command | undefined;
|
||||
text: string;
|
||||
}>;
|
||||
constructor({ hide, prefixFormat, commandLength, raw, timestampFormat, }: {
|
||||
/**
|
||||
* Which commands should have their output hidden.
|
||||
*/
|
||||
hide?: CommandIdentifier[];
|
||||
/**
|
||||
* Whether output should be formatted to include prefixes and whether "event" logs will be
|
||||
* logged.
|
||||
*/
|
||||
raw?: boolean;
|
||||
/**
|
||||
* The prefix format to use when logging a command's output.
|
||||
* Defaults to the command's index.
|
||||
*/
|
||||
prefixFormat?: string;
|
||||
/**
|
||||
* How many characters should a prefix have at most when the format is `command`.
|
||||
*/
|
||||
commandLength?: number;
|
||||
/**
|
||||
* Date format used when logging date/time.
|
||||
* @see https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
|
||||
*/
|
||||
timestampFormat?: string;
|
||||
});
|
||||
/**
|
||||
* Toggles colors on/off globally.
|
||||
*/
|
||||
toggleColors(on: boolean): void;
|
||||
private shortenText;
|
||||
private getPrefixesFor;
|
||||
getPrefixContent(command: Command): {
|
||||
type: 'default' | 'template';
|
||||
value: string;
|
||||
} | undefined;
|
||||
getPrefix(command: Command): string;
|
||||
setPrefixLength(length: number): void;
|
||||
colorText(command: Command, text: string): string;
|
||||
/**
|
||||
* Logs an event for a command (e.g. start, stop).
|
||||
*
|
||||
* If raw mode is on, then nothing is logged.
|
||||
*/
|
||||
logCommandEvent(text: string, command: Command): void;
|
||||
logCommandText(text: string, command: Command): void;
|
||||
/**
|
||||
* Logs a global event (e.g. sending signals to processes).
|
||||
*
|
||||
* If raw mode is on, then nothing is logged.
|
||||
*/
|
||||
logGlobalEvent(text: string): void;
|
||||
/**
|
||||
* Logs a table from an input object array, like `console.table`.
|
||||
*
|
||||
* Each row is a single input item, and they are presented in the input order.
|
||||
*/
|
||||
logTable(tableContents: Record<string, unknown>[]): void;
|
||||
log(prefix: string, text: string, command?: Command): void;
|
||||
emit(command: Command | undefined, text: string): void;
|
||||
}
|
241
node_modules/concurrently/dist/src/logger.js
generated
vendored
Normal file
241
node_modules/concurrently/dist/src/logger.js
generated
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Logger = void 0;
|
||||
const chalk_1 = __importDefault(require("chalk"));
|
||||
const lodash_1 = __importDefault(require("lodash"));
|
||||
const Rx = __importStar(require("rxjs"));
|
||||
const date_format_1 = require("./date-format");
|
||||
const defaults = __importStar(require("./defaults"));
|
||||
const defaultChalk = chalk_1.default;
|
||||
const noColorChalk = new chalk_1.default.Instance({ level: 0 });
|
||||
class Logger {
|
||||
hide;
|
||||
raw;
|
||||
prefixFormat;
|
||||
commandLength;
|
||||
dateFormatter;
|
||||
chalk = defaultChalk;
|
||||
/**
|
||||
* How many characters should a prefix have.
|
||||
* Prefixes shorter than this will be padded with spaces to the right.
|
||||
*/
|
||||
prefixLength = 0;
|
||||
/**
|
||||
* Last character emitted, and from which command.
|
||||
* If `undefined`, then nothing has been logged yet.
|
||||
*/
|
||||
lastWrite;
|
||||
/**
|
||||
* Observable that emits when there's been output logged.
|
||||
* If `command` is is `undefined`, then the log is for a global event.
|
||||
*/
|
||||
output = new Rx.Subject();
|
||||
constructor({ hide, prefixFormat, commandLength, raw = false, timestampFormat, }) {
|
||||
this.hide = (hide || []).map(String);
|
||||
this.raw = raw;
|
||||
this.prefixFormat = prefixFormat;
|
||||
this.commandLength = commandLength || defaults.prefixLength;
|
||||
this.dateFormatter = new date_format_1.DateFormatter(timestampFormat || defaults.timestampFormat);
|
||||
}
|
||||
/**
|
||||
* Toggles colors on/off globally.
|
||||
*/
|
||||
toggleColors(on) {
|
||||
this.chalk = on ? defaultChalk : noColorChalk;
|
||||
}
|
||||
shortenText(text) {
|
||||
if (!text || text.length <= this.commandLength) {
|
||||
return text;
|
||||
}
|
||||
const ellipsis = '..';
|
||||
const prefixLength = this.commandLength - ellipsis.length;
|
||||
const endLength = Math.floor(prefixLength / 2);
|
||||
const beginningLength = prefixLength - endLength;
|
||||
const beginnning = text.slice(0, beginningLength);
|
||||
const end = text.slice(text.length - endLength, text.length);
|
||||
return beginnning + ellipsis + end;
|
||||
}
|
||||
getPrefixesFor(command) {
|
||||
return {
|
||||
// When there's limited concurrency, the PID might not be immediately available,
|
||||
// so avoid the string 'undefined' from becoming a prefix
|
||||
pid: command.pid != null ? String(command.pid) : '',
|
||||
index: String(command.index),
|
||||
name: command.name,
|
||||
command: this.shortenText(command.command),
|
||||
time: this.dateFormatter.format(new Date()),
|
||||
};
|
||||
}
|
||||
getPrefixContent(command) {
|
||||
const prefix = this.prefixFormat || (command.name ? 'name' : 'index');
|
||||
if (prefix === 'none') {
|
||||
return;
|
||||
}
|
||||
const prefixes = this.getPrefixesFor(command);
|
||||
if (Object.keys(prefixes).includes(prefix)) {
|
||||
return { type: 'default', value: prefixes[prefix] };
|
||||
}
|
||||
const value = lodash_1.default.reduce(prefixes, (prev, val, key) => {
|
||||
const keyRegex = new RegExp(lodash_1.default.escapeRegExp(`{${key}}`), 'g');
|
||||
return prev.replace(keyRegex, String(val));
|
||||
}, prefix);
|
||||
return { type: 'template', value };
|
||||
}
|
||||
getPrefix(command) {
|
||||
const content = this.getPrefixContent(command);
|
||||
if (!content) {
|
||||
return '';
|
||||
}
|
||||
return content.type === 'template'
|
||||
? content.value.padEnd(this.prefixLength, ' ')
|
||||
: `[${content.value.padEnd(this.prefixLength, ' ')}]`;
|
||||
}
|
||||
setPrefixLength(length) {
|
||||
this.prefixLength = length;
|
||||
}
|
||||
colorText(command, text) {
|
||||
let color;
|
||||
if (command.prefixColor && command.prefixColor.startsWith('#')) {
|
||||
color = this.chalk.hex(command.prefixColor);
|
||||
}
|
||||
else {
|
||||
const defaultColor = lodash_1.default.get(this.chalk, defaults.prefixColors, this.chalk.reset);
|
||||
color = lodash_1.default.get(this.chalk, command.prefixColor ?? '', defaultColor);
|
||||
}
|
||||
return color(text);
|
||||
}
|
||||
/**
|
||||
* Logs an event for a command (e.g. start, stop).
|
||||
*
|
||||
* If raw mode is on, then nothing is logged.
|
||||
*/
|
||||
logCommandEvent(text, command) {
|
||||
if (this.raw) {
|
||||
return;
|
||||
}
|
||||
// Last write was from this command, but it didn't end with a line feed.
|
||||
// Prepend one, otherwise the event's text will be concatenated to that write.
|
||||
// A line feed is otherwise inserted anyway.
|
||||
let prefix = '';
|
||||
if (this.lastWrite?.command === command && this.lastWrite.char !== '\n') {
|
||||
prefix = '\n';
|
||||
}
|
||||
this.logCommandText(prefix + this.chalk.reset(text) + '\n', command);
|
||||
}
|
||||
logCommandText(text, command) {
|
||||
if (this.hide.includes(String(command.index)) || this.hide.includes(command.name)) {
|
||||
return;
|
||||
}
|
||||
const prefix = this.colorText(command, this.getPrefix(command));
|
||||
return this.log(prefix + (prefix ? ' ' : ''), text, command);
|
||||
}
|
||||
/**
|
||||
* Logs a global event (e.g. sending signals to processes).
|
||||
*
|
||||
* If raw mode is on, then nothing is logged.
|
||||
*/
|
||||
logGlobalEvent(text) {
|
||||
if (this.raw) {
|
||||
return;
|
||||
}
|
||||
this.log(this.chalk.reset('-->') + ' ', this.chalk.reset(text) + '\n');
|
||||
}
|
||||
/**
|
||||
* Logs a table from an input object array, like `console.table`.
|
||||
*
|
||||
* Each row is a single input item, and they are presented in the input order.
|
||||
*/
|
||||
logTable(tableContents) {
|
||||
// For now, can only print array tables with some content.
|
||||
if (this.raw || !Array.isArray(tableContents) || !tableContents.length) {
|
||||
return;
|
||||
}
|
||||
let nextColIndex = 0;
|
||||
const headers = {};
|
||||
const contentRows = tableContents.map((row) => {
|
||||
const rowContents = [];
|
||||
Object.keys(row).forEach((col) => {
|
||||
if (!headers[col]) {
|
||||
headers[col] = {
|
||||
index: nextColIndex++,
|
||||
length: col.length,
|
||||
};
|
||||
}
|
||||
const colIndex = headers[col].index;
|
||||
const formattedValue = String(row[col] == null ? '' : row[col]);
|
||||
// Update the column length in case this rows value is longer than the previous length for the column.
|
||||
headers[col].length = Math.max(formattedValue.length, headers[col].length);
|
||||
rowContents[colIndex] = formattedValue;
|
||||
return rowContents;
|
||||
});
|
||||
return rowContents;
|
||||
});
|
||||
const headersFormatted = Object.keys(headers).map((header) => header.padEnd(headers[header].length, ' '));
|
||||
if (!headersFormatted.length) {
|
||||
// No columns exist.
|
||||
return;
|
||||
}
|
||||
const borderRowFormatted = headersFormatted.map((header) => '─'.padEnd(header.length, '─'));
|
||||
this.logGlobalEvent(`┌─${borderRowFormatted.join('─┬─')}─┐`);
|
||||
this.logGlobalEvent(`│ ${headersFormatted.join(' │ ')} │`);
|
||||
this.logGlobalEvent(`├─${borderRowFormatted.join('─┼─')}─┤`);
|
||||
contentRows.forEach((contentRow) => {
|
||||
const contentRowFormatted = headersFormatted.map((header, colIndex) => {
|
||||
// If the table was expanded after this row was processed, it won't have this column.
|
||||
// Use an empty string in this case.
|
||||
const col = contentRow[colIndex] || '';
|
||||
return col.padEnd(header.length, ' ');
|
||||
});
|
||||
this.logGlobalEvent(`│ ${contentRowFormatted.join(' │ ')} │`);
|
||||
});
|
||||
this.logGlobalEvent(`└─${borderRowFormatted.join('─┴─')}─┘`);
|
||||
}
|
||||
log(prefix, text, command) {
|
||||
if (this.raw) {
|
||||
return this.emit(command, text);
|
||||
}
|
||||
// #70 - replace some ANSI code that would impact clearing lines
|
||||
text = text.replace(/\u2026/g, '...');
|
||||
// This write's interrupting another command, emit a line feed to start clean.
|
||||
if (this.lastWrite && this.lastWrite.command !== command && this.lastWrite.char !== '\n') {
|
||||
this.emit(this.lastWrite.command, '\n');
|
||||
}
|
||||
// Clean lines should emit a prefix
|
||||
if (!this.lastWrite || this.lastWrite.char === '\n') {
|
||||
this.emit(command, prefix);
|
||||
}
|
||||
const textToWrite = text.replaceAll('\n', (lf, i) => lf + (text[i + 1] ? prefix : ''));
|
||||
this.emit(command, textToWrite);
|
||||
}
|
||||
emit(command, text) {
|
||||
this.lastWrite = { command, char: text[text.length - 1] };
|
||||
this.output.next({ command, text });
|
||||
}
|
||||
}
|
||||
exports.Logger = Logger;
|
19
node_modules/concurrently/dist/src/output-writer.d.ts
generated
vendored
Normal file
19
node_modules/concurrently/dist/src/output-writer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/// <reference types="node" />
|
||||
import { Writable } from 'stream';
|
||||
import { Command } from './command';
|
||||
/**
|
||||
* Class responsible for actually writing output onto a writable stream.
|
||||
*/
|
||||
export declare class OutputWriter {
|
||||
private readonly outputStream;
|
||||
private readonly group;
|
||||
readonly buffers: string[][];
|
||||
activeCommandIndex: number;
|
||||
constructor({ outputStream, group, commands, }: {
|
||||
outputStream: Writable;
|
||||
group: boolean;
|
||||
commands: Command[];
|
||||
});
|
||||
write(command: Command | undefined, text: string): void;
|
||||
private flushBuffer;
|
||||
}
|
75
node_modules/concurrently/dist/src/output-writer.js
generated
vendored
Normal file
75
node_modules/concurrently/dist/src/output-writer.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.OutputWriter = void 0;
|
||||
const Rx = __importStar(require("rxjs"));
|
||||
/**
|
||||
* Class responsible for actually writing output onto a writable stream.
|
||||
*/
|
||||
class OutputWriter {
|
||||
outputStream;
|
||||
group;
|
||||
buffers;
|
||||
activeCommandIndex = 0;
|
||||
constructor({ outputStream, group, commands, }) {
|
||||
this.outputStream = outputStream;
|
||||
this.group = group;
|
||||
this.buffers = commands.map(() => []);
|
||||
if (this.group) {
|
||||
Rx.merge(...commands.map((c) => c.close)).subscribe((command) => {
|
||||
if (command.index !== this.activeCommandIndex) {
|
||||
return;
|
||||
}
|
||||
for (let i = command.index + 1; i < commands.length; i++) {
|
||||
this.activeCommandIndex = i;
|
||||
this.flushBuffer(i);
|
||||
// TODO: Should errored commands also flush buffer?
|
||||
if (commands[i].state !== 'exited') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
write(command, text) {
|
||||
if (this.group && command) {
|
||||
if (command.index <= this.activeCommandIndex) {
|
||||
this.outputStream.write(text);
|
||||
}
|
||||
else {
|
||||
this.buffers[command.index].push(text);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// "global" logs (command=null) are output out of order
|
||||
this.outputStream.write(text);
|
||||
}
|
||||
}
|
||||
flushBuffer(index) {
|
||||
this.buffers[index].forEach((t) => this.outputStream.write(t));
|
||||
this.buffers[index] = [];
|
||||
}
|
||||
}
|
||||
exports.OutputWriter = OutputWriter;
|
11
node_modules/concurrently/dist/src/prefix-color-selector.d.ts
generated
vendored
Normal file
11
node_modules/concurrently/dist/src/prefix-color-selector.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import chalk from 'chalk';
|
||||
export declare class PrefixColorSelector {
|
||||
private colorGenerator;
|
||||
constructor(customColors?: string | string[]);
|
||||
/** A list of colors that are readable in a terminal. */
|
||||
static get ACCEPTABLE_CONSOLE_COLORS(): ("stderr" | keyof chalk.Chalk | "supportsColor" | "Level" | "Color" | "ForegroundColor" | "BackgroundColor" | "Modifiers")[];
|
||||
/**
|
||||
* @returns The given custom colors then a set of acceptable console colors indefinitely.
|
||||
*/
|
||||
getNextColor(): string;
|
||||
}
|
94
node_modules/concurrently/dist/src/prefix-color-selector.js
generated
vendored
Normal file
94
node_modules/concurrently/dist/src/prefix-color-selector.js
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PrefixColorSelector = void 0;
|
||||
function getConsoleColorsWithoutCustomColors(customColors) {
|
||||
return PrefixColorSelector.ACCEPTABLE_CONSOLE_COLORS.filter(
|
||||
// Consider the "Bright" variants of colors to be the same as the plain color to avoid similar colors
|
||||
(color) => !customColors.includes(color.replace(/Bright$/, '')));
|
||||
}
|
||||
/**
|
||||
* Creates a generator that yields an infinite stream of colors.
|
||||
*/
|
||||
function* createColorGenerator(customColors) {
|
||||
// Custom colors should be used as is, except for "auto"
|
||||
const nextAutoColors = getConsoleColorsWithoutCustomColors(customColors);
|
||||
let lastColor;
|
||||
for (const customColor of customColors) {
|
||||
let currentColor = customColor;
|
||||
if (currentColor !== 'auto') {
|
||||
yield currentColor; // Manual color
|
||||
}
|
||||
else {
|
||||
// Find the first auto color that is not the same as the last color
|
||||
while (currentColor === 'auto' || lastColor === currentColor) {
|
||||
if (!nextAutoColors.length) {
|
||||
// There could be more "auto" values than auto colors so this needs to be able to refill
|
||||
nextAutoColors.push(...PrefixColorSelector.ACCEPTABLE_CONSOLE_COLORS);
|
||||
}
|
||||
currentColor = String(nextAutoColors.shift());
|
||||
}
|
||||
yield currentColor; // Auto color
|
||||
}
|
||||
lastColor = currentColor;
|
||||
}
|
||||
const lastCustomColor = customColors[customColors.length - 1] || '';
|
||||
if (lastCustomColor !== 'auto') {
|
||||
while (true) {
|
||||
yield lastCustomColor; // If last custom color was not "auto" then return same color forever, to maintain existing behaviour
|
||||
}
|
||||
}
|
||||
// Finish the initial set(s) of auto colors to avoid repetition
|
||||
for (const color of nextAutoColors) {
|
||||
yield color;
|
||||
}
|
||||
// Yield an infinite stream of acceptable console colors
|
||||
//
|
||||
// If the given custom colors use every ACCEPTABLE_CONSOLE_COLORS except one then there is a chance a color will be repeated,
|
||||
// however its highly unlikely and low consequence so not worth the extra complexity to account for it
|
||||
while (true) {
|
||||
for (const color of PrefixColorSelector.ACCEPTABLE_CONSOLE_COLORS) {
|
||||
yield color; // Repeat colors forever
|
||||
}
|
||||
}
|
||||
}
|
||||
class PrefixColorSelector {
|
||||
colorGenerator;
|
||||
constructor(customColors = []) {
|
||||
const normalizedColors = typeof customColors === 'string' ? [customColors] : customColors;
|
||||
this.colorGenerator = createColorGenerator(normalizedColors);
|
||||
}
|
||||
/** A list of colors that are readable in a terminal. */
|
||||
static get ACCEPTABLE_CONSOLE_COLORS() {
|
||||
// Colors picked randomly, can be amended if required
|
||||
return [
|
||||
// Prevent duplicates, in case the list becomes significantly large
|
||||
...new Set([
|
||||
// Text colors
|
||||
'cyan',
|
||||
'yellow',
|
||||
'greenBright',
|
||||
'blueBright',
|
||||
'magentaBright',
|
||||
'white',
|
||||
'grey',
|
||||
'red',
|
||||
// Background colors
|
||||
'bgCyan',
|
||||
'bgYellow',
|
||||
'bgGreenBright',
|
||||
'bgBlueBright',
|
||||
'bgMagenta',
|
||||
'bgWhiteBright',
|
||||
'bgGrey',
|
||||
'bgRed',
|
||||
]),
|
||||
];
|
||||
}
|
||||
/**
|
||||
* @returns The given custom colors then a set of acceptable console colors indefinitely.
|
||||
*/
|
||||
getNextColor() {
|
||||
return this.colorGenerator.next().value;
|
||||
}
|
||||
}
|
||||
exports.PrefixColorSelector = PrefixColorSelector;
|
49
node_modules/concurrently/dist/src/spawn.d.ts
generated
vendored
Normal file
49
node_modules/concurrently/dist/src/spawn.d.ts
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { ChildProcess, SpawnOptions } from 'child_process';
|
||||
import supportsColor from 'supports-color';
|
||||
/**
|
||||
* Spawns a command using `cmd.exe` on Windows, or `/bin/sh` elsewhere.
|
||||
*/
|
||||
export declare function spawn(command: string, options: SpawnOptions, spawn?: (command: string, args: string[], options: SpawnOptions) => ChildProcess, process?: Pick<NodeJS.Process, 'platform'>): ChildProcess;
|
||||
export declare const getSpawnOpts: ({ colorSupport, cwd, process, ipc, stdio, env, }: {
|
||||
/**
|
||||
* What the color support of the spawned processes should be.
|
||||
* If set to `false`, then no colors should be output.
|
||||
*
|
||||
* Defaults to whatever the terminal's stdout support is.
|
||||
*/
|
||||
colorSupport?: false | Pick<supportsColor.supportsColor.Level, "level"> | undefined;
|
||||
/**
|
||||
* The NodeJS process.
|
||||
*/
|
||||
process?: Pick<NodeJS.Process, "platform" | "cwd" | "env"> | undefined;
|
||||
/**
|
||||
* A custom working directory to spawn processes in.
|
||||
* Defaults to `process.cwd()`.
|
||||
*/
|
||||
cwd?: string | undefined;
|
||||
/**
|
||||
* The file descriptor number at which the channel for inter-process communication
|
||||
* should be set up.
|
||||
*/
|
||||
ipc?: number | undefined;
|
||||
/**
|
||||
* Which stdio mode to use. Raw implies inheriting the parent process' stdio.
|
||||
*
|
||||
* - `normal`: all of stdout, stderr and stdin are piped
|
||||
* - `hidden`: stdin is piped, stdout/stderr outputs are ignored
|
||||
* - `raw`: all of stdout, stderr and stdin are inherited from the main process
|
||||
*
|
||||
* Defaults to `normal`.
|
||||
*/
|
||||
stdio?: "raw" | "hidden" | "normal" | undefined;
|
||||
/**
|
||||
* Map of custom environment variables to include in the spawn options.
|
||||
*/
|
||||
env?: Record<string, unknown> | undefined;
|
||||
}) => SpawnOptions;
|
49
node_modules/concurrently/dist/src/spawn.js
generated
vendored
Normal file
49
node_modules/concurrently/dist/src/spawn.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getSpawnOpts = exports.spawn = void 0;
|
||||
const assert_1 = __importDefault(require("assert"));
|
||||
const child_process_1 = require("child_process");
|
||||
const supports_color_1 = __importDefault(require("supports-color"));
|
||||
/**
|
||||
* Spawns a command using `cmd.exe` on Windows, or `/bin/sh` elsewhere.
|
||||
*/
|
||||
// Implementation based off of https://github.com/mmalecki/spawn-command/blob/v0.0.2-1/lib/spawn-command.js
|
||||
function spawn(command, options,
|
||||
// For testing
|
||||
spawn = child_process_1.spawn, process = global.process) {
|
||||
let file = '/bin/sh';
|
||||
let args = ['-c', command];
|
||||
if (process.platform === 'win32') {
|
||||
file = 'cmd.exe';
|
||||
args = ['/s', '/c', `"${command}"`];
|
||||
options.windowsVerbatimArguments = true;
|
||||
}
|
||||
return spawn(file, args, options);
|
||||
}
|
||||
exports.spawn = spawn;
|
||||
const getSpawnOpts = ({ colorSupport = supports_color_1.default.stdout, cwd, process = global.process, ipc, stdio = 'normal', env = {}, }) => {
|
||||
const stdioValues = stdio === 'normal'
|
||||
? ['pipe', 'pipe', 'pipe']
|
||||
: stdio === 'raw'
|
||||
? ['inherit', 'inherit', 'inherit']
|
||||
: ['pipe', 'ignore', 'ignore'];
|
||||
if (ipc != null) {
|
||||
// Avoid overriding the stdout/stderr/stdin
|
||||
assert_1.default.ok(ipc > 2, '[concurrently] the IPC channel number should be > 2');
|
||||
stdioValues[ipc] = 'ipc';
|
||||
}
|
||||
return {
|
||||
cwd: cwd || process.cwd(),
|
||||
stdio: stdioValues,
|
||||
...(/^win/.test(process.platform) && { detached: false }),
|
||||
env: {
|
||||
...(colorSupport ? { FORCE_COLOR: colorSupport.level.toString() } : {}),
|
||||
...process.env,
|
||||
...env,
|
||||
},
|
||||
};
|
||||
};
|
||||
exports.getSpawnOpts = getSpawnOpts;
|
13
node_modules/concurrently/docs/README.md
generated
vendored
Normal file
13
node_modules/concurrently/docs/README.md
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Concurrently Documentation
|
||||
|
||||
## CLI
|
||||
|
||||
These articles cover using concurrently through CLI:
|
||||
|
||||
- [Prefixing](./cli/prefixing.md)
|
||||
- [Output Control](./cli/output-control.md)
|
||||
- [Shortcuts](./cli/shortcuts.md)
|
||||
- [Restarting Commands](./cli/restarting.md)
|
||||
- [Input Handling](./cli/input-handling.md)
|
||||
- [Passthrough Arguments](./cli/passthrough-arguments.md)
|
||||
- [Configuration](./cli/configuration.md)
|
11
node_modules/concurrently/docs/cli/configuration.md
generated
vendored
Normal file
11
node_modules/concurrently/docs/cli/configuration.md
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# Configuration
|
||||
|
||||
You might want to configure concurrently to always have certain flags on.
|
||||
Any of concurrently's flags can be set via environment variables that are prefixed with `CONCURRENTLY_`.
|
||||
|
||||
```bash
|
||||
$ export CONCURRENTLY_KILL_OTHERS=true
|
||||
$ export CONCURRENTLY_HANDLE_INPUT=true
|
||||
# Equivalent to passing --kill-others and --handle-input
|
||||
$ concurrently nodemon "echo 'hey nodemon, you won't last long'"
|
||||
```
|
40
node_modules/concurrently/docs/cli/input-handling.md
generated
vendored
Normal file
40
node_modules/concurrently/docs/cli/input-handling.md
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# Input Handling
|
||||
|
||||
By default, concurrently doesn't send input to any commands it spawns.<br/>
|
||||
In the below example, typing `rs` to manually restart [nodemon](https://nodemon.io/) does nothing:
|
||||
|
||||
```bash
|
||||
$ concurrently "nodemon" "npm run watch-js"
|
||||
rs
|
||||
```
|
||||
|
||||
To turn on input handling, it's necessary to set the `--handle-input`/`-i` flag.<br/>
|
||||
This will send `rs` to the first command:
|
||||
|
||||
```bash
|
||||
$ concurrently --handle-input "nodemon" "npm run watch-js"
|
||||
rs
|
||||
```
|
||||
|
||||
To send input to a different command instead, it's possible to prefix the input with the command index, followed by a `:`.<br/>
|
||||
For example, the below sends `rs` to the second command:
|
||||
|
||||
```bash
|
||||
$ concurrently --handle-input "npm run watch-js" "nodemon"
|
||||
1:rs
|
||||
```
|
||||
|
||||
If the command has a name, it's also possible to target it using that command's name:
|
||||
|
||||
```bash
|
||||
$ concurrently --handle-input --names js,server "npm run watch-js" "nodemon"
|
||||
server:rs
|
||||
```
|
||||
|
||||
It's also possible to change the default command that receives input.<br/>
|
||||
To do this, set the `--default-input-target` flag to a command's index or name.
|
||||
|
||||
```bash
|
||||
$ concurrently --handle-input --default-input-target 1 "npm run watch-js" "nodemon"
|
||||
rs
|
||||
```
|
35
node_modules/concurrently/docs/cli/output-control.md
generated
vendored
Normal file
35
node_modules/concurrently/docs/cli/output-control.md
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# Output Control
|
||||
|
||||
concurrently offers a few ways to control a command's output.
|
||||
|
||||
## Hiding
|
||||
|
||||
A command's outputs (and all its events) can be hidden by using the `--hide` flag.
|
||||
|
||||
```bash
|
||||
$ concurrently --hide 0 "echo Hello there" "echo 'General Kenobi!'"
|
||||
[1] General Kenobi!
|
||||
[1] echo 'General Kenobi!' exited with code 0
|
||||
```
|
||||
|
||||
## Grouping
|
||||
|
||||
It might be useful at times to make sure that the commands outputs are grouped together, while running them in parallel.<br/>
|
||||
This can be done with the `--group` flag.
|
||||
|
||||
```bash
|
||||
$ concurrently --group "echo Hello there && sleep 2 && echo 'General Kenobi!'" "echo hi Star Wars fans"
|
||||
[0] Hello there
|
||||
[0] General Kenobi!
|
||||
[0] echo Hello there && sleep 2 && echo 'General Kenobi!' exited with code 0
|
||||
[1] hi Star Wars fans
|
||||
[1] echo hi Star Wars fans exited with code 0
|
||||
```
|
||||
|
||||
## No Colors
|
||||
|
||||
When piping concurrently's outputs to another command or file, you might want to force it to not use colors, as these can break the other command's parsing, or reduce the legibility of the output in non-terminal environments.
|
||||
|
||||
```bash
|
||||
$ concurrently -c red,blue --no-color "echo Hello there" "echo 'General Kenobi!'"
|
||||
```
|
80
node_modules/concurrently/docs/cli/passthrough-arguments.md
generated
vendored
Normal file
80
node_modules/concurrently/docs/cli/passthrough-arguments.md
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
# Passthrough Arguments
|
||||
|
||||
If you have a shortcut for running a specific combination of commands through concurrently,
|
||||
you might need at some point to pass additional arguments/flags to some of these.
|
||||
|
||||
For example, imagine you have in your `package.json` file scripts like this:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// ...
|
||||
"scripts": {
|
||||
"build:client": "tsc -p client",
|
||||
"build:server": "tsc -p server",
|
||||
"build": "concurrently npm:build:client npm:build:server"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you wanted to run only either `build:server` or `build:client` with an additional `--noEmit` flag,
|
||||
you can do so with `npm run build:server -- --noEmit`, for example.<br/>
|
||||
However, if you want to do that while using concurrently, as `npm run build -- --noEmit` for example,
|
||||
you might find that concurrently actually parses `--noEmit` as its own flag, which does nothing,
|
||||
because it doesn't exist.
|
||||
|
||||
To solve this, you can set the `--passthrough-arguments`/`-P` flag, which instructs concurrently to
|
||||
take everything after a `--` as additional arguments that are passed through to the input commands
|
||||
via a few placeholder styles:
|
||||
|
||||
## Single argument
|
||||
|
||||
We can modify the original `build` script to pass a single additional argument/flag to a script by using
|
||||
a 1-indexed `{number}` placeholder to the command you want it to apply to:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// ...
|
||||
"scripts": {
|
||||
// ...
|
||||
"build": "concurrently -P 'npm:build:client -- {1}' npm:build:server --",
|
||||
"typecheck": "npm run build -- --noEmit"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With this, running `npm run typecheck` will pass `--noEmit` only to `npm run build:client`.
|
||||
|
||||
## All arguments
|
||||
|
||||
In the original `build` example script, you're more likely to want to pass every additional argument/flag
|
||||
to your commands. This can be done with the `{@}` placeholder.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// ...
|
||||
"scripts": {
|
||||
// ...
|
||||
"build": "concurrently -P 'npm:build:client -- {@}' 'npm:build:server -- {@}' --",
|
||||
"typecheck": "npm run build -- --watch --noEmit"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the above example, both `--watch` and `--noEmit` are passed to each command.
|
||||
|
||||
## All arguments, combined
|
||||
|
||||
If for some reason you wish to combine all additional arguments into a single one, you can do that with the `{*}` placeholder,
|
||||
which wraps the arguments in quotes.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// ...
|
||||
"scripts": {
|
||||
// ...
|
||||
"build": "concurrently -P 'npm:build:client -- --outDir {*}/client' 'npm:build:server -- --outDir {*}/server' -- $(date)"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the above example, the output of the `date` command, which looks like `Sun 1 Sep 2024 23:50:00 AEST` will be passed as a single string to the `--outDir` parameter of both commands.
|
147
node_modules/concurrently/docs/cli/prefixing.md
generated
vendored
Normal file
147
node_modules/concurrently/docs/cli/prefixing.md
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
# Prefixing
|
||||
|
||||
## Prefix Styles
|
||||
|
||||
concurrently will by default prefix each command's outputs with a zero-based index, wrapped in square brackets:
|
||||
|
||||
```bash
|
||||
$ concurrently "echo Hello there" "echo 'General Kenobi!'"
|
||||
[0] Hello there
|
||||
[1] General Kenobi!
|
||||
[0] echo Hello there exited with code 0
|
||||
[1] echo 'General Kenobi!' exited with code 0
|
||||
```
|
||||
|
||||
If you've given the commands names, they are used instead:
|
||||
|
||||
```bash
|
||||
$ concurrently --names one,two "echo Hello there" "echo 'General Kenobi!'"
|
||||
[one] Hello there
|
||||
[two] General Kenobi!
|
||||
[one] echo Hello there exited with code 0
|
||||
[two] echo 'General Kenobi!' exited with code 0
|
||||
```
|
||||
|
||||
There are other prefix styles available too:
|
||||
|
||||
| Style | Description |
|
||||
| --------- | --------------------------------- |
|
||||
| `index` | Zero-based command's index |
|
||||
| `name` | The command's name |
|
||||
| `command` | The command's line |
|
||||
| `time` | Time of output |
|
||||
| `pid` | ID of the command's process (PID) |
|
||||
| `none` | No prefix |
|
||||
|
||||
Any of these can be used by setting the `--prefix`/`-p` flag. For example:
|
||||
|
||||
```bash
|
||||
$ concurrently --prefix pid "echo Hello there" "echo 'General Kenobi!'"
|
||||
[2222] Hello there
|
||||
[2223] General Kenobi!
|
||||
[2222] echo Hello there exited with code 0
|
||||
[2223] echo 'General Kenobi!' exited with code 0
|
||||
```
|
||||
|
||||
It's also possible to have a prefix based on a template. Any of the styles listed above can be used by wrapping it in `{}`.
|
||||
Doing so will also remove the square brackets:
|
||||
|
||||
```bash
|
||||
$ concurrently --prefix "{index}-{pid}" "echo Hello there" "echo 'General Kenobi!'"
|
||||
0-2222 Hello there
|
||||
1-2223 General Kenobi!
|
||||
0-2222 echo Hello there exited with code 0
|
||||
1-2223 echo 'General Kenobi!' exited with code 0
|
||||
```
|
||||
|
||||
## Prefix Colors
|
||||
|
||||
By default, there are no colors applied to concurrently prefixes, and they just use whatever the terminal's defaults are.
|
||||
|
||||
This can be changed by using the `--prefix-colors`/`-c` flag, which takes a comma-separated list of colors to use.<br/>
|
||||
The available values are color names (e.g. `green`, `magenta`, `gray`, etc), a hex value (such as `#23de43`), or `auto`, to automatically select a color.
|
||||
|
||||
```bash
|
||||
$ concurrently -c red,blue "echo Hello there" "echo 'General Kenobi!'"
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>List of available color names</summary>
|
||||
|
||||
- `black`
|
||||
- `blue`
|
||||
- `cyan`
|
||||
- `green`
|
||||
- `gray`
|
||||
- `magenta`
|
||||
- `red`
|
||||
- `white`
|
||||
- `yellow`
|
||||
</details>
|
||||
|
||||
Colors can take modifiers too. Several can be applied at once by prepending `.<modifier 1>.<modifier 2>` and so on.
|
||||
|
||||
```bash
|
||||
$ concurrently -c red,bold.blue.dim "echo Hello there" "echo 'General Kenobi!'"
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>List of available modifiers</summary>
|
||||
|
||||
- `reset`
|
||||
- `bold`
|
||||
- `dim`
|
||||
- `hidden`
|
||||
- `inverse`
|
||||
- `italic`
|
||||
- `strikethrough`
|
||||
- `underline`
|
||||
</details>
|
||||
|
||||
A background color can be set in a similary fashion.
|
||||
|
||||
```bash
|
||||
$ concurrently -c bgGray,red.bgBlack "echo Hello there" "echo 'General Kenobi!'"
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>List of available background color names</summary>
|
||||
|
||||
- `bgBlack`
|
||||
- `bgBlue`
|
||||
- `bgCyan`
|
||||
- `bgGreen`
|
||||
- `bgGray`
|
||||
- `bgMagenta`
|
||||
- `bgRed`
|
||||
- `bgWhite`
|
||||
- `bgYellow`
|
||||
</details>
|
||||
|
||||
## Prefix Length
|
||||
|
||||
When using the `command` prefix style, it's possible that it'll be too long.<br/>
|
||||
It can be limited by setting the `--prefix-length`/`-l` flag:
|
||||
|
||||
```bash
|
||||
$ concurrently -p command -l 10 "echo Hello there" "echo 'General Kenobi!'"
|
||||
[echo..here] Hello there
|
||||
[echo..bi!'] General Kenobi!
|
||||
[echo..here] echo Hello there exited with code 0
|
||||
[echo..bi!'] echo 'General Kenobi!' exited with code 0
|
||||
```
|
||||
|
||||
It's also possible that some prefixes are too short, and you want all of them to have the same length.<br/>
|
||||
This can be done by setting the `--pad-prefix` flag:
|
||||
|
||||
```bash
|
||||
$ concurrently -n foo,barbaz --pad-prefix "echo Hello there" "echo 'General Kenobi!'"
|
||||
[foo ] Hello there
|
||||
[foo ] echo Hello there exited with code 0
|
||||
[barbaz] General Kenobi!
|
||||
[barbaz] echo 'General Kenobi!' exited with code 0
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> If using the `pid` prefix style in combination with [`--restart-tries`](./restarting.md), the length of the PID might grow, in which case all subsequent lines will match the new length.<br/>
|
||||
> This might happen, for example, if the PID was 99 and it's now 100.
|
38
node_modules/concurrently/docs/cli/restarting.md
generated
vendored
Normal file
38
node_modules/concurrently/docs/cli/restarting.md
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# Restarting Commands
|
||||
|
||||
Sometimes it's useful to have commands that exited with a non-zero status to restart automatically.<br/>
|
||||
concurrently lets you configure how many times you wish for such a command to restart through the `--restart-tries` flag:
|
||||
|
||||
```bash
|
||||
$ concurrently --restart-tries 2 "exit 1"
|
||||
[0] exit 1 exited with code 1
|
||||
[0] exit 1 restarted
|
||||
[0] exit 1 exited with code 1
|
||||
[0] exit 1 restarted
|
||||
[0] exit 1 exited with code 1
|
||||
```
|
||||
|
||||
Sometimes, it might be interesting to have commands wait before restarting.<br/>
|
||||
To do this, simply set `--restart-after` to a the number of milliseconds you'd like to delay restarting.
|
||||
|
||||
```bash
|
||||
$ concurrently -p time --restart-tries 1 --restart-after 3000 "exit 1"
|
||||
[2024-09-01 23:43:55.871] exit 1 exited with code 1
|
||||
[2024-09-01 23:43:58.874] exit 1 restarted
|
||||
[2024-09-01 23:43:58.891] exit 1 exited with code 1
|
||||
```
|
||||
|
||||
If a command is not having success spawning, you might want to instead apply an exponential back-off.<br/>
|
||||
Set `--restart-after exponential` to have commands respawn with a `2^N` seconds delay.
|
||||
|
||||
```bash
|
||||
$ concurrently -p time --restart-tries 3 --restart-after exponential "exit 1"
|
||||
|
||||
[2024-09-01 23:49:01.124] exit 1 exited with code 1
|
||||
[2024-09-01 23:49:02.127] exit 1 restarted
|
||||
[2024-09-01 23:49:02.139] exit 1 exited with code 1
|
||||
[2024-09-01 23:49:04.141] exit 1 restarted
|
||||
[2024-09-01 23:49:04.157] exit 1 exited with code 1
|
||||
[2024-09-01 23:49:08.158] exit 1 restarted
|
||||
[2024-09-01 23:49:08.174] exit 1 exited with code 1
|
||||
```
|
73
node_modules/concurrently/docs/cli/shortcuts.md
generated
vendored
Normal file
73
node_modules/concurrently/docs/cli/shortcuts.md
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
# Command Shortcuts
|
||||
|
||||
Package managers that execute scripts from a `package.json` or `deno.(json|jsonc)` file can be shortened when in concurrently.<br/>
|
||||
The following are supported:
|
||||
|
||||
| Syntax | Expands to |
|
||||
| --------------- | --------------------- |
|
||||
| `npm:<script>` | `npm run <script>` |
|
||||
| `pnpm:<script>` | `pnpm run <script>` |
|
||||
| `yarn:<script>` | `yarn run <script>` |
|
||||
| `bun:<script>` | `bun run <script>` |
|
||||
| `node:<script>` | `node --run <script>` |
|
||||
| `deno:<script>` | `deno task <script>` |
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> `node --run` is only available from [Node 22 onwards](https://nodejs.org/en/blog/announcements/v22-release-announce#running-packagejson-scripts).
|
||||
|
||||
For example, given the following `package.json` contents:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// ...
|
||||
"scripts": {
|
||||
"lint:js": "...",
|
||||
"lint:ts": "...",
|
||||
"lint:fix:js": "...",
|
||||
"lint:fix:ts": "..."
|
||||
// ...
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
It's possible to run some of these with the following command line:
|
||||
|
||||
```bash
|
||||
$ concurrently "pnpm:lint:js"
|
||||
# Is equivalent to
|
||||
$ concurrently -n lint:js "pnpm run lint:js"
|
||||
```
|
||||
|
||||
Note that the command automatically receives a name equal to the script name.
|
||||
|
||||
If you have several scripts with similar name patterns, you can use the `*` wildcard to run all of them at once.<br/>
|
||||
The spawned commands will receive names set to whatever the `*` wildcard matched.
|
||||
|
||||
```bash
|
||||
$ concurrently "npm:lint:fix:*"
|
||||
# is equivalent to
|
||||
$ concurrently -n js,ts "npm run lint:fix:js" "npm run lint:fix:ts"
|
||||
```
|
||||
|
||||
If you specify a command name when using wildcards, it'll be a prefix of what the `*` wildcard matched:
|
||||
|
||||
```bash
|
||||
$ concurrently -n fix: "npm:lint:fix:*"
|
||||
# is equivalent to
|
||||
$ concurrently -n fix:js,fix:ts "npm run lint:fix:js" "npm run lint:fix:ts"
|
||||
```
|
||||
|
||||
Filtering out commands matched by wildcard is also possible. Do this with by including `(!<some pattern>)` in the command line:
|
||||
|
||||
```bash
|
||||
$ concurrently 'yarn:lint:*(!fix)'
|
||||
# is equivalent to
|
||||
$ concurrently -n js,ts "yarn run lint:js" "yarn run lint:ts"
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> If you use this syntax with double quotes (`"`), bash and other shells might fail
|
||||
> parsing it. You'll need to escape the `!`, or use single quote (`'`) instead.<br/>
|
||||
> See [here](https://serverfault.com/a/208266/160539) for more information.
|
BIN
node_modules/concurrently/docs/demo.gif
generated
vendored
Normal file
BIN
node_modules/concurrently/docs/demo.gif
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 237 KiB |
7
node_modules/concurrently/index.d.mts
generated
vendored
Normal file
7
node_modules/concurrently/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* While in local development, make sure you've run `pnpm run build` first.
|
||||
*/
|
||||
import { concurrently } from './dist/src/index.js';
|
||||
|
||||
export * from './dist/src/index.js';
|
||||
export default concurrently;
|
11
node_modules/concurrently/index.d.ts
generated
vendored
Normal file
11
node_modules/concurrently/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* While in local development, make sure you've run `pnpm run build` first.
|
||||
*/
|
||||
import { concurrently } from './dist/src/index.js';
|
||||
|
||||
export * from './dist/src/index.js';
|
||||
// @ts-expect-error ignore the usage of `export =` along with `export default`.
|
||||
// This is seemingly fine, but the file needs to be included in the TS project, which can't be done
|
||||
// due to importing from `dist`. See https://stackoverflow.com/q/42609768/2083599
|
||||
export = concurrently;
|
||||
export default concurrently;
|
14
node_modules/concurrently/index.js
generated
vendored
Normal file
14
node_modules/concurrently/index.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* While in local development, make sure you've run `pnpm run build` first.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const concurrently = require('./dist/src/index.js');
|
||||
|
||||
// For require()
|
||||
module.exports = exports = concurrently.concurrently;
|
||||
|
||||
// For TS + import syntax; mimics `export default`
|
||||
exports.default = exports;
|
||||
|
||||
Object.assign(exports, concurrently);
|
10
node_modules/concurrently/index.mjs
generated
vendored
Normal file
10
node_modules/concurrently/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* While in local development, make sure you've run `pnpm run build` first.
|
||||
*/
|
||||
|
||||
import { concurrently } from './dist/src/index.js';
|
||||
|
||||
// NOTE: the star reexport doesn't work in Node <12.20, <14.13 and <15.
|
||||
export * from './dist/src/index.js';
|
||||
|
||||
export default concurrently;
|
111
node_modules/concurrently/package.json
generated
vendored
Normal file
111
node_modules/concurrently/package.json
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"name": "concurrently",
|
||||
"version": "9.1.2",
|
||||
"description": "Run commands concurrently",
|
||||
"packageManager": "pnpm@8.15.9+sha256.daa27a0b541bc635323ff96c2ded995467ff9fe6d69ff67021558aa9ad9dcc36",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"type": "commonjs",
|
||||
"bin": {
|
||||
"concurrently": "./dist/bin/concurrently.js",
|
||||
"conc": "./dist/bin/concurrently.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./index.d.mts",
|
||||
"default": "./index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./index.d.ts",
|
||||
"default": "./index.js"
|
||||
}
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/open-cli-tools/concurrently.git"
|
||||
},
|
||||
"funding": "https://github.com/open-cli-tools/concurrently?sponsor=1",
|
||||
"keywords": [
|
||||
"bash",
|
||||
"concurrent",
|
||||
"parallel",
|
||||
"concurrently",
|
||||
"command",
|
||||
"sh"
|
||||
],
|
||||
"author": "Kimmo Brunfeldt",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2",
|
||||
"lodash": "^4.17.21",
|
||||
"rxjs": "^7.8.1",
|
||||
"shell-quote": "^1.8.1",
|
||||
"supports-color": "^8.1.1",
|
||||
"tree-kill": "^1.2.2",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hirez_io/observer-spy": "^2.2.0",
|
||||
"@jest/types": "^29.6.3",
|
||||
"@swc/core": "^1.7.23",
|
||||
"@swc/jest": "^0.2.36",
|
||||
"@types/jest": "^29.5.6",
|
||||
"@types/lodash": "^4.17.7",
|
||||
"@types/node": "^18.19.50",
|
||||
"@types/shell-quote": "^1.7.5",
|
||||
"@types/supports-color": "^8.1.3",
|
||||
"@types/yargs": "^17.0.33",
|
||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"coveralls-next": "^4.2.1",
|
||||
"ctrlc-wrapper": "^0.0.4",
|
||||
"esbuild": "~0.23.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-jest": "^27.9.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"husky": "^9.1.5",
|
||||
"jest": "^29.7.0",
|
||||
"jest-create-mock-instance": "^2.0.0",
|
||||
"lint-staged": "^15.2.10",
|
||||
"prettier": "^3.0.3",
|
||||
"safe-publish-latest": "^2.0.0",
|
||||
"string-argv": "^0.3.2",
|
||||
"typescript": "~5.2.2"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"index.mjs",
|
||||
"index.d.mts",
|
||||
"!**/fixtures",
|
||||
"!**/*.spec.js",
|
||||
"!**/*.spec.d.ts",
|
||||
"docs"
|
||||
],
|
||||
"lint-staged": {
|
||||
"*.?(m){js,ts}": "eslint --fix",
|
||||
"*.{json,y?(a)ml,md}": "prettier --write"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"postbuild": "chmod +x dist/bin/concurrently.js",
|
||||
"clean": "tsc --build --clean",
|
||||
"format": "prettier --check '**/*.{json,y?(a)ml,md}'",
|
||||
"format:fix": "pnpm run format --write",
|
||||
"lint": "eslint --ignore-path .gitignore --ext mjs,js,ts .",
|
||||
"lint:fix": "pnpm run lint --fix",
|
||||
"report-coverage": "cat coverage/lcov.info | coveralls",
|
||||
"test": "jest --selectProjects unit",
|
||||
"test:smoke": "jest --selectProjects smoke"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user