aboutsummaryrefslogtreecommitdiffstats
path: root/node_modules/concurrently/dist/src
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/concurrently/dist/src')
-rw-r--r--node_modules/concurrently/dist/src/command-parser/command-parser.d.ts19
-rw-r--r--node_modules/concurrently/dist/src/command-parser/command-parser.js2
-rw-r--r--node_modules/concurrently/dist/src/command-parser/expand-arguments.d.ts17
-rw-r--r--node_modules/concurrently/dist/src/command-parser/expand-arguments.js38
-rw-r--r--node_modules/concurrently/dist/src/command-parser/expand-npm-shortcut.d.ts8
-rw-r--r--node_modules/concurrently/dist/src/command-parser/expand-npm-shortcut.js20
-rw-r--r--node_modules/concurrently/dist/src/command-parser/expand-npm-wildcard.d.ts13
-rw-r--r--node_modules/concurrently/dist/src/command-parser/expand-npm-wildcard.js68
-rw-r--r--node_modules/concurrently/dist/src/command-parser/strip-quotes.d.ts15
-rw-r--r--node_modules/concurrently/dist/src/command-parser/strip-quotes.js17
-rw-r--r--node_modules/concurrently/dist/src/command.d.ts121
-rw-r--r--node_modules/concurrently/dist/src/command.js117
-rw-r--r--node_modules/concurrently/dist/src/completion-listener.d.ts40
-rw-r--r--node_modules/concurrently/dist/src/completion-listener.js77
-rw-r--r--node_modules/concurrently/dist/src/concurrently.d.ts110
-rw-r--r--node_modules/concurrently/dist/src/concurrently.js130
-rw-r--r--node_modules/concurrently/dist/src/defaults.d.ts68
-rw-r--r--node_modules/concurrently/dist/src/defaults.js73
-rw-r--r--node_modules/concurrently/dist/src/flow-control/flow-controller.d.ts13
-rw-r--r--node_modules/concurrently/dist/src/flow-control/flow-controller.js2
-rw-r--r--node_modules/concurrently/dist/src/flow-control/input-handler.d.ts30
-rw-r--r--node_modules/concurrently/dist/src/flow-control/input-handler.js90
-rw-r--r--node_modules/concurrently/dist/src/flow-control/kill-on-signal.d.ts17
-rw-r--r--node_modules/concurrently/dist/src/flow-control/kill-on-signal.js36
-rw-r--r--node_modules/concurrently/dist/src/flow-control/kill-others.d.ts20
-rw-r--r--node_modules/concurrently/dist/src/flow-control/kill-others.js35
-rw-r--r--node_modules/concurrently/dist/src/flow-control/log-error.d.ts15
-rw-r--r--node_modules/concurrently/dist/src/flow-control/log-error.js20
-rw-r--r--node_modules/concurrently/dist/src/flow-control/log-exit.d.ts15
-rw-r--r--node_modules/concurrently/dist/src/flow-control/log-exit.js18
-rw-r--r--node_modules/concurrently/dist/src/flow-control/log-output.d.ts15
-rw-r--r--node_modules/concurrently/dist/src/flow-control/log-output.js19
-rw-r--r--node_modules/concurrently/dist/src/flow-control/log-timings.d.ts31
-rw-r--r--node_modules/concurrently/dist/src/flow-control/log-timings.js92
-rw-r--r--node_modules/concurrently/dist/src/flow-control/restart-process.d.ts22
-rw-r--r--node_modules/concurrently/dist/src/flow-control/restart-process.js76
-rw-r--r--node_modules/concurrently/dist/src/get-spawn-opts.d.ts34
-rw-r--r--node_modules/concurrently/dist/src/get-spawn-opts.js18
-rw-r--r--node_modules/concurrently/dist/src/index.d.ts74
-rw-r--r--node_modules/concurrently/dist/src/index.js71
-rw-r--r--node_modules/concurrently/dist/src/logger.d.ts72
-rw-r--r--node_modules/concurrently/dist/src/logger.js202
-rw-r--r--node_modules/concurrently/dist/src/output-writer.d.ts19
-rw-r--r--node_modules/concurrently/dist/src/output-writer.js71
-rw-r--r--node_modules/concurrently/dist/src/prefix-color-selector.d.ts11
-rw-r--r--node_modules/concurrently/dist/src/prefix-color-selector.js93
46 files changed, 2184 insertions, 0 deletions
diff --git a/node_modules/concurrently/dist/src/command-parser/command-parser.d.ts b/node_modules/concurrently/dist/src/command-parser/command-parser.d.ts
new file mode 100644
index 0000000..37ab795
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/command-parser.d.ts
@@ -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[];
+}
diff --git a/node_modules/concurrently/dist/src/command-parser/command-parser.js b/node_modules/concurrently/dist/src/command-parser/command-parser.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/command-parser.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/concurrently/dist/src/command-parser/expand-arguments.d.ts b/node_modules/concurrently/dist/src/command-parser/expand-arguments.d.ts
new file mode 100644
index 0000000..c88e731
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/expand-arguments.d.ts
@@ -0,0 +1,17 @@
+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;
+ raw?: boolean | undefined;
+ };
+}
diff --git a/node_modules/concurrently/dist/src/command-parser/expand-arguments.js b/node_modules/concurrently/dist/src/command-parser/expand-arguments.js
new file mode 100644
index 0000000..42c087c
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/expand-arguments.js
@@ -0,0 +1,38 @@
+"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 {
+ 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;
diff --git a/node_modules/concurrently/dist/src/command-parser/expand-npm-shortcut.d.ts b/node_modules/concurrently/dist/src/command-parser/expand-npm-shortcut.d.ts
new file mode 100644
index 0000000..636018a
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/expand-npm-shortcut.d.ts
@@ -0,0 +1,8 @@
+import { CommandInfo } from '../command';
+import { CommandParser } from './command-parser';
+/**
+ * Expands commands prefixed with `npm:`, `yarn:`, `pnpm:`, or `bun:` into the full version `npm run <command>` and so on.
+ */
+export declare class ExpandNpmShortcut implements CommandParser {
+ parse(commandInfo: CommandInfo): CommandInfo;
+}
diff --git a/node_modules/concurrently/dist/src/command-parser/expand-npm-shortcut.js b/node_modules/concurrently/dist/src/command-parser/expand-npm-shortcut.js
new file mode 100644
index 0000000..9a62362
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/expand-npm-shortcut.js
@@ -0,0 +1,20 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ExpandNpmShortcut = void 0;
+/**
+ * Expands commands prefixed with `npm:`, `yarn:`, `pnpm:`, or `bun:` into the full version `npm run <command>` and so on.
+ */
+class ExpandNpmShortcut {
+ parse(commandInfo) {
+ const [, npmCmd, cmdName, args] = commandInfo.command.match(/^(npm|yarn|pnpm|bun):(\S+)(.*)/) || [];
+ if (!cmdName) {
+ return commandInfo;
+ }
+ return {
+ ...commandInfo,
+ name: commandInfo.name || cmdName,
+ command: `${npmCmd} run ${cmdName}${args}`,
+ };
+ }
+}
+exports.ExpandNpmShortcut = ExpandNpmShortcut;
diff --git a/node_modules/concurrently/dist/src/command-parser/expand-npm-wildcard.d.ts b/node_modules/concurrently/dist/src/command-parser/expand-npm-wildcard.d.ts
new file mode 100644
index 0000000..cc5f413
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/expand-npm-wildcard.d.ts
@@ -0,0 +1,13 @@
+import { CommandInfo } from '../command';
+import { CommandParser } from './command-parser';
+/**
+ * Finds wildcards in npm/yarn/pnpm/bun run commands and replaces them with all matching scripts in the
+ * `package.json` file of the current directory.
+ */
+export declare class ExpandNpmWildcard implements CommandParser {
+ private readonly readPackage;
+ static readPackage(): any;
+ private scripts?;
+ constructor(readPackage?: typeof ExpandNpmWildcard.readPackage);
+ parse(commandInfo: CommandInfo): CommandInfo | CommandInfo[];
+}
diff --git a/node_modules/concurrently/dist/src/command-parser/expand-npm-wildcard.js b/node_modules/concurrently/dist/src/command-parser/expand-npm-wildcard.js
new file mode 100644
index 0000000..0109207
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/expand-npm-wildcard.js
@@ -0,0 +1,68 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ExpandNpmWildcard = void 0;
+const fs_1 = __importDefault(require("fs"));
+const lodash_1 = __importDefault(require("lodash"));
+const OMISSION = /\(!([^)]+)\)/;
+/**
+ * Finds wildcards in npm/yarn/pnpm/bun run commands and replaces them with all matching scripts in the
+ * `package.json` file of the current directory.
+ */
+class ExpandNpmWildcard {
+ static readPackage() {
+ try {
+ const json = fs_1.default.readFileSync('package.json', { encoding: 'utf-8' });
+ return JSON.parse(json);
+ }
+ catch (e) {
+ return {};
+ }
+ }
+ constructor(readPackage = ExpandNpmWildcard.readPackage) {
+ this.readPackage = readPackage;
+ }
+ parse(commandInfo) {
+ const [, npmCmd, cmdName, args] = commandInfo.command.match(/(npm|yarn|pnpm|bun) run (\S+)([^&]*)/) || [];
+ const wildcardPosition = (cmdName || '').indexOf('*');
+ // If the regex didn't match an npm script, or it has no wildcard,
+ // then we have nothing to do here
+ if (!cmdName || wildcardPosition === -1) {
+ return commandInfo;
+ }
+ if (!this.scripts) {
+ this.scripts = Object.keys(this.readPackage().scripts || {});
+ }
+ const omissionRegex = cmdName.match(OMISSION);
+ const cmdNameSansOmission = cmdName.replace(OMISSION, '');
+ const preWildcard = lodash_1.default.escapeRegExp(cmdNameSansOmission.slice(0, wildcardPosition));
+ const postWildcard = lodash_1.default.escapeRegExp(cmdNameSansOmission.slice(wildcardPosition + 1));
+ const wildcardRegex = new RegExp(`^${preWildcard}(.*?)${postWildcard}$`);
+ // If 'commandInfo.name' doesn't match 'cmdName', this means a custom name
+ // has been specified and thus becomes the prefix (as described in the README).
+ const prefix = commandInfo.name !== cmdName ? commandInfo.name : '';
+ return this.scripts
+ .map((script) => {
+ const match = script.match(wildcardRegex);
+ if (omissionRegex) {
+ const toOmit = script.match(new RegExp(omissionRegex[1]));
+ if (toOmit) {
+ return;
+ }
+ }
+ if (match) {
+ return {
+ ...commandInfo,
+ command: `${npmCmd} run ${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[1],
+ };
+ }
+ })
+ .filter((commandInfo) => !!commandInfo);
+ }
+}
+exports.ExpandNpmWildcard = ExpandNpmWildcard;
diff --git a/node_modules/concurrently/dist/src/command-parser/strip-quotes.d.ts b/node_modules/concurrently/dist/src/command-parser/strip-quotes.d.ts
new file mode 100644
index 0000000..1a21b79
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/strip-quotes.d.ts
@@ -0,0 +1,15 @@
+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;
+ raw?: boolean | undefined;
+ };
+}
diff --git a/node_modules/concurrently/dist/src/command-parser/strip-quotes.js b/node_modules/concurrently/dist/src/command-parser/strip-quotes.js
new file mode 100644
index 0000000..971a524
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command-parser/strip-quotes.js
@@ -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;
diff --git a/node_modules/concurrently/dist/src/command.d.ts b/node_modules/concurrently/dist/src/command.d.ts
new file mode 100644
index 0000000..84c6298
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command.d.ts
@@ -0,0 +1,121 @@
+/// <reference types="node" />
+/// <reference types="node" />
+/// <reference types="node" />
+/// <reference types="node" />
+import { ChildProcess as BaseChildProcess, 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;
+ /**
+ * 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;
+}
+/**
+ * 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'>;
+/**
+ * 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;
+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;
+ 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>;
+ process?: ChildProcess;
+ stdin?: Writable;
+ pid?: number;
+ killed: boolean;
+ exited: boolean;
+ /** @deprecated */
+ get killable(): boolean;
+ constructor({ index, name, command, prefixColor, env, cwd }: CommandInfo & {
+ index: number;
+ }, spawnOpts: SpawnOptions, spawn: SpawnCommand, killProcess: KillProcess);
+ /**
+ * Starts this command, piping output, error and close events onto the corresponding observables.
+ */
+ start(): void;
+ /**
+ * Kills this command, optionally specifying a signal to send to it.
+ */
+ kill(code?: string): void;
+ /**
+ * 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;
+ };
+}
diff --git a/node_modules/concurrently/dist/src/command.js b/node_modules/concurrently/dist/src/command.js
new file mode 100644
index 0000000..e30bbb9
--- /dev/null
+++ b/node_modules/concurrently/dist/src/command.js
@@ -0,0 +1,117 @@
+"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 {
+ /** @deprecated */
+ get killable() {
+ return Command.canKill(this);
+ }
+ constructor({ index, name, command, prefixColor, env, cwd }, spawnOpts, spawn, killProcess) {
+ this.close = new Rx.Subject();
+ this.error = new Rx.Subject();
+ this.stdout = new Rx.Subject();
+ this.stderr = new Rx.Subject();
+ this.timer = new Rx.Subject();
+ this.killed = false;
+ this.exited = false;
+ this.index = index;
+ this.name = name;
+ this.command = command;
+ this.prefixColor = prefixColor;
+ this.env = env || {};
+ this.cwd = cwd;
+ 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.process = child;
+ this.pid = child.pid;
+ const startDate = new Date(Date.now());
+ const highResStartTime = process.hrtime();
+ this.timer.next({ startDate });
+ Rx.fromEvent(child, 'error').subscribe((event) => {
+ this.process = undefined;
+ const endDate = new Date(Date.now());
+ this.timer.next({ startDate, endDate });
+ this.error.next(event);
+ });
+ Rx.fromEvent(child, 'close')
+ .pipe(Rx.map((event) => event))
+ .subscribe(([exitCode, signal]) => {
+ this.process = undefined;
+ this.exited = true;
+ 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;
+ }
+ /**
+ * 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);
+ }
+ }
+ /**
+ * 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) {
+ stream.subscribe((event) => subject.next(event));
+}
diff --git a/node_modules/concurrently/dist/src/completion-listener.d.ts b/node_modules/concurrently/dist/src/completion-listener.d.ts
new file mode 100644
index 0000000..fd1ad42
--- /dev/null
+++ b/node_modules/concurrently/dist/src/completion-listener.d.ts
@@ -0,0 +1,40 @@
+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.
+ */
+ listen(commands: Command[]): Promise<CloseEvent[]>;
+ private emitWithScheduler;
+}
diff --git a/node_modules/concurrently/dist/src/completion-listener.js b/node_modules/concurrently/dist/src/completion-listener.js
new file mode 100644
index 0000000..7844fde
--- /dev/null
+++ b/node_modules/concurrently/dist/src/completion-listener.js
@@ -0,0 +1,77 @@
+"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 {
+ constructor({ successCondition = 'all', scheduler, }) {
+ this.successCondition = successCondition;
+ this.scheduler = scheduler;
+ }
+ isSuccess(events) {
+ 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 succesfully
+ 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.
+ */
+ listen(commands) {
+ const closeStreams = commands.map((command) => command.close);
+ return Rx.lastValueFrom(Rx.merge(...closeStreams).pipe((0, operators_1.bufferCount)(closeStreams.length), (0, operators_1.switchMap)((exitInfos) => this.isSuccess(exitInfos)
+ ? this.emitWithScheduler(Rx.of(exitInfos))
+ : this.emitWithScheduler(Rx.throwError(() => exitInfos))), (0, operators_1.take)(1)));
+ }
+ emitWithScheduler(input) {
+ return this.scheduler ? input.pipe(Rx.observeOn(this.scheduler)) : input;
+ }
+}
+exports.CompletionListener = CompletionListener;
diff --git a/node_modules/concurrently/dist/src/concurrently.d.ts b/node_modules/concurrently/dist/src/concurrently.d.ts
new file mode 100644
index 0000000..7af8297
--- /dev/null
+++ b/node_modules/concurrently/dist/src/concurrently.d.ts
@@ -0,0 +1,110 @@
+/// <reference types="node" />
+import { Writable } from 'stream';
+import { CloseEvent, Command, 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 the list of all command's close events.
+ */
+ 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`
+ *
+ * @see {@link https://www.npmjs.com/package/chalk} for more information.
+ */
+ prefixColors?: string | string[];
+ /**
+ * 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;
+ /**
+ * The current working directory of commands which didn't specify one.
+ * Defaults to `process.cwd()`.
+ */
+ cwd?: string;
+ /**
+ * @see CompletionListener
+ */
+ successCondition?: SuccessCondition;
+ /**
+ * 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 the `spawn-command` module.
+ */
+ 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;
diff --git a/node_modules/concurrently/dist/src/concurrently.js b/node_modules/concurrently/dist/src/concurrently.js
new file mode 100644
index 0000000..fe07fb7
--- /dev/null
+++ b/node_modules/concurrently/dist/src/concurrently.js
@@ -0,0 +1,130 @@
+"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 spawn_command_1 = __importDefault(require("spawn-command"));
+const tree_kill_1 = __importDefault(require("tree-kill"));
+const command_1 = require("./command");
+const expand_arguments_1 = require("./command-parser/expand-arguments");
+const expand_npm_shortcut_1 = require("./command-parser/expand-npm-shortcut");
+const expand_npm_wildcard_1 = require("./command-parser/expand-npm-wildcard");
+const strip_quotes_1 = require("./command-parser/strip-quotes");
+const completion_listener_1 = require("./completion-listener");
+const get_spawn_opts_1 = require("./get-spawn-opts");
+const output_writer_1 = require("./output-writer");
+const prefix_color_selector_1 = require("./prefix-color-selector");
+const defaults = {
+ spawn: spawn_command_1.default,
+ 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_npm_shortcut_1.ExpandNpmShortcut(),
+ new expand_npm_wildcard_1.ExpandNpmWildcard(),
+ ];
+ if (options.additionalArguments) {
+ commandParsers.push(new expand_arguments_1.ExpandArguments(options.additionalArguments));
+ }
+ let commands = (0, lodash_1.default)(baseCommands)
+ .map(mapToCommandInfo)
+ .flatMap((command) => parseCommand(command, commandParsers))
+ .map((command, index) => {
+ return new command_1.Command({
+ index,
+ prefixColor: prefixColorSelector.getNextColor(),
+ ...command,
+ }, (0, get_spawn_opts_1.getSpawnOpts)({
+ raw: command.raw ?? options.raw,
+ 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);
+ }
+ const result = new completion_listener_1.CompletionListener({ successCondition: options.successCondition })
+ .listen(commands)
+ .finally(() => {
+ handleResult.onFinishCallbacks.forEach((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 || '',
+ ...(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) {
+ const command = commandsLeft.shift();
+ if (!command) {
+ return;
+ }
+ command.start();
+ command.close.subscribe(() => {
+ maybeRunMore(commandsLeft);
+ });
+}
diff --git a/node_modules/concurrently/dist/src/defaults.d.ts b/node_modules/concurrently/dist/src/defaults.d.ts
new file mode 100644
index 0000000..b50a9fc
--- /dev/null
+++ b/node_modules/concurrently/dist/src/defaults.d.ts
@@ -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://date-fns.org/v2.0.1/docs/format
+ */
+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;
diff --git a/node_modules/concurrently/dist/src/defaults.js b/node_modules/concurrently/dist/src/defaults.js
new file mode 100644
index 0000000..3dcb9e4
--- /dev/null
+++ b/node_modules/concurrently/dist/src/defaults.js
@@ -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://date-fns.org/v2.0.1/docs/format
+ */
+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;
diff --git a/node_modules/concurrently/dist/src/flow-control/flow-controller.d.ts b/node_modules/concurrently/dist/src/flow-control/flow-controller.d.ts
new file mode 100644
index 0000000..b518aad
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/flow-controller.d.ts
@@ -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;
+ };
+}
diff --git a/node_modules/concurrently/dist/src/flow-control/flow-controller.js b/node_modules/concurrently/dist/src/flow-control/flow-controller.js
new file mode 100644
index 0000000..c8ad2e5
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/flow-controller.js
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/node_modules/concurrently/dist/src/flow-control/input-handler.d.ts b/node_modules/concurrently/dist/src/flow-control/input-handler.d.ts
new file mode 100644
index 0000000..3a7ee5a
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/input-handler.d.ts
@@ -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;
+ };
+}
diff --git a/node_modules/concurrently/dist/src/flow-control/input-handler.js b/node_modules/concurrently/dist/src/flow-control/input-handler.js
new file mode 100644
index 0000000..76c552f
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/input-handler.js
@@ -0,0 +1,90 @@
+"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 {
+ 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;
diff --git a/node_modules/concurrently/dist/src/flow-control/kill-on-signal.d.ts b/node_modules/concurrently/dist/src/flow-control/kill-on-signal.d.ts
new file mode 100644
index 0000000..d706694
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/kill-on-signal.d.ts
@@ -0,0 +1,17 @@
+/// <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;
+ constructor({ process }: {
+ process: EventEmitter;
+ });
+ handle(commands: Command[]): {
+ commands: Command[];
+ };
+}
diff --git a/node_modules/concurrently/dist/src/flow-control/kill-on-signal.js b/node_modules/concurrently/dist/src/flow-control/kill-on-signal.js
new file mode 100644
index 0000000..716a9bf
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/kill-on-signal.js
@@ -0,0 +1,36 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.KillOnSignal = void 0;
+const operators_1 = require("rxjs/operators");
+/**
+ * Watches the main concurrently process for signals and sends the same signal down to each spawned
+ * command.
+ */
+class KillOnSignal {
+ constructor({ process }) {
+ this.process = process;
+ }
+ handle(commands) {
+ let caughtSignal;
+ ['SIGINT', 'SIGTERM', 'SIGHUP'].forEach((signal) => {
+ this.process.on(signal, () => {
+ caughtSignal = signal;
+ commands.forEach((command) => command.kill(signal));
+ });
+ });
+ 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 new Proxy(command, {
+ get(target, prop) {
+ return prop === 'close' ? closeStream : target[prop];
+ },
+ });
+ }),
+ };
+ }
+}
+exports.KillOnSignal = KillOnSignal;
diff --git a/node_modules/concurrently/dist/src/flow-control/kill-others.d.ts b/node_modules/concurrently/dist/src/flow-control/kill-others.d.ts
new file mode 100644
index 0000000..f10b7bb
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/kill-others.d.ts
@@ -0,0 +1,20 @@
+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 conditions;
+ private readonly killSignal;
+ constructor({ logger, conditions, killSignal, }: {
+ logger: Logger;
+ conditions: ProcessCloseCondition | ProcessCloseCondition[];
+ killSignal: string | undefined;
+ });
+ handle(commands: Command[]): {
+ commands: Command[];
+ };
+}
diff --git a/node_modules/concurrently/dist/src/flow-control/kill-others.js b/node_modules/concurrently/dist/src/flow-control/kill-others.js
new file mode 100644
index 0000000..1751677
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/kill-others.js
@@ -0,0 +1,35 @@
+"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 {
+ constructor({ logger, conditions, killSignal, }) {
+ this.logger = logger;
+ 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(() => {
+ 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;
diff --git a/node_modules/concurrently/dist/src/flow-control/log-error.d.ts b/node_modules/concurrently/dist/src/flow-control/log-error.d.ts
new file mode 100644
index 0000000..8eac6dd
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/log-error.d.ts
@@ -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[];
+ };
+}
diff --git a/node_modules/concurrently/dist/src/flow-control/log-error.js b/node_modules/concurrently/dist/src/flow-control/log-error.js
new file mode 100644
index 0000000..8fc7210
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/log-error.js
@@ -0,0 +1,20 @@
+"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 {
+ 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;
diff --git a/node_modules/concurrently/dist/src/flow-control/log-exit.d.ts b/node_modules/concurrently/dist/src/flow-control/log-exit.d.ts
new file mode 100644
index 0000000..47b8718
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/log-exit.d.ts
@@ -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[];
+ };
+}
diff --git a/node_modules/concurrently/dist/src/flow-control/log-exit.js b/node_modules/concurrently/dist/src/flow-control/log-exit.js
new file mode 100644
index 0000000..6fe396d
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/log-exit.js
@@ -0,0 +1,18 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.LogExit = void 0;
+/**
+ * Logs the exit code/signal of commands.
+ */
+class LogExit {
+ 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;
diff --git a/node_modules/concurrently/dist/src/flow-control/log-output.d.ts b/node_modules/concurrently/dist/src/flow-control/log-output.d.ts
new file mode 100644
index 0000000..6c916de
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/log-output.d.ts
@@ -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[];
+ };
+}
diff --git a/node_modules/concurrently/dist/src/flow-control/log-output.js b/node_modules/concurrently/dist/src/flow-control/log-output.js
new file mode 100644
index 0000000..486a25b
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/log-output.js
@@ -0,0 +1,19 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.LogOutput = void 0;
+/**
+ * Logs the stdout and stderr output of commands.
+ */
+class LogOutput {
+ 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;
diff --git a/node_modules/concurrently/dist/src/flow-control/log-timings.d.ts b/node_modules/concurrently/dist/src/flow-control/log-timings.d.ts
new file mode 100644
index 0000000..a847707
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/log-timings.d.ts
@@ -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 timestampFormat;
+ constructor({ logger, timestampFormat, }: {
+ logger?: Logger;
+ timestampFormat?: string;
+ });
+ private printExitInfoTimingTable;
+ handle(commands: Command[]): {
+ commands: Command[];
+ onFinish?: undefined;
+ } | {
+ commands: Command[];
+ onFinish: () => void;
+ };
+}
+export {};
diff --git a/node_modules/concurrently/dist/src/flow-control/log-timings.js b/node_modules/concurrently/dist/src/flow-control/log-timings.js
new file mode 100644
index 0000000..9c8879d
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/log-timings.js
@@ -0,0 +1,92 @@
+"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 format_1 = __importDefault(require("date-fns/format"));
+const lodash_1 = __importDefault(require("lodash"));
+const Rx = __importStar(require("rxjs"));
+const operators_1 = require("rxjs/operators");
+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,
+ };
+ }
+ constructor({ logger, timestampFormat = defaults.timestampFormat, }) {
+ this.logger = logger;
+ this.timestampFormat = 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 = (0, format_1.default)(startDate, this.timestampFormat);
+ logger.logCommandEvent(`${command.command} started at ${formattedStartDate}`, command);
+ }
+ else {
+ const durationMs = endDate.getTime() - startDate.getTime();
+ const formattedEndDate = (0, format_1.default)(endDate, this.timestampFormat);
+ 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;
diff --git a/node_modules/concurrently/dist/src/flow-control/restart-process.d.ts b/node_modules/concurrently/dist/src/flow-control/restart-process.d.ts
new file mode 100644
index 0000000..735d8d5
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/restart-process.d.ts
@@ -0,0 +1,22 @@
+import * as Rx from 'rxjs';
+import { Command } from '../command';
+import { Logger } from '../logger';
+import { FlowController } from './flow-controller';
+/**
+ * Restarts commands that fail up to a defined number of times.
+ */
+export declare class RestartProcess implements FlowController {
+ private readonly logger;
+ private readonly scheduler?;
+ readonly delay: number;
+ readonly tries: number;
+ constructor({ delay, tries, logger, scheduler, }: {
+ delay?: number;
+ tries?: number;
+ logger: Logger;
+ scheduler?: Rx.SchedulerLike;
+ });
+ handle(commands: Command[]): {
+ commands: Command[];
+ };
+}
diff --git a/node_modules/concurrently/dist/src/flow-control/restart-process.js b/node_modules/concurrently/dist/src/flow-control/restart-process.js
new file mode 100644
index 0000000..79131ce
--- /dev/null
+++ b/node_modules/concurrently/dist/src/flow-control/restart-process.js
@@ -0,0 +1,76 @@
+"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 {
+ constructor({ delay, tries, logger, scheduler, }) {
+ this.logger = logger;
+ this.delay = delay != null ? +delay : defaults.restartDelay;
+ 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 };
+ }
+ 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((0, operators_1.delay)(this.delay, this.scheduler), (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 new Proxy(command, {
+ get(target, prop) {
+ return prop === 'close' ? closeStream : target[prop];
+ },
+ });
+ }),
+ };
+ }
+}
+exports.RestartProcess = RestartProcess;
diff --git a/node_modules/concurrently/dist/src/get-spawn-opts.d.ts b/node_modules/concurrently/dist/src/get-spawn-opts.d.ts
new file mode 100644
index 0000000..7538de7
--- /dev/null
+++ b/node_modules/concurrently/dist/src/get-spawn-opts.d.ts
@@ -0,0 +1,34 @@
+/// <reference types="node" />
+/// <reference types="node" />
+/// <reference types="node" />
+/// <reference types="node" />
+/// <reference types="node" />
+import { SpawnOptions } from 'child_process';
+import supportsColor from 'supports-color';
+export declare const getSpawnOpts: ({ colorSupport, cwd, process, raw, 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;
+ /**
+ * Whether to customize the options for spawning processes in raw mode.
+ * Defaults to false.
+ */
+ raw?: boolean | undefined;
+ /**
+ * Map of custom environment variables to include in the spawn options.
+ */
+ env?: Record<string, unknown> | undefined;
+}) => SpawnOptions;
diff --git a/node_modules/concurrently/dist/src/get-spawn-opts.js b/node_modules/concurrently/dist/src/get-spawn-opts.js
new file mode 100644
index 0000000..9b48af5
--- /dev/null
+++ b/node_modules/concurrently/dist/src/get-spawn-opts.js
@@ -0,0 +1,18 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getSpawnOpts = void 0;
+const supports_color_1 = __importDefault(require("supports-color"));
+const getSpawnOpts = ({ colorSupport = supports_color_1.default.stdout, cwd, process = global.process, raw = false, env = {}, }) => ({
+ cwd: cwd || process.cwd(),
+ ...(raw && { stdio: 'inherit' }),
+ ...(/^win/.test(process.platform) && { detached: false }),
+ env: {
+ ...(colorSupport ? { FORCE_COLOR: colorSupport.level.toString() } : {}),
+ ...process.env,
+ ...env,
+ },
+});
+exports.getSpawnOpts = getSpawnOpts;
diff --git a/node_modules/concurrently/dist/src/index.d.ts b/node_modules/concurrently/dist/src/index.d.ts
new file mode 100644
index 0000000..6f4e68b
--- /dev/null
+++ b/node_modules/concurrently/dist/src/index.d.ts
@@ -0,0 +1,74 @@
+/// <reference types="node" />
+import { Readable } from 'stream';
+import { CloseEvent, Command, CommandIdentifier, TimerEvent } from './command';
+import { concurrently, 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 { RestartProcess } from './flow-control/restart-process';
+import { Logger } from './logger';
+export type ConcurrentlyOptions = BaseConcurrentlyOptions & {
+ /**
+ * 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;
+ /**
+ * 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://date-fns.org/v2.0.1/docs/format
+ */
+ timestampFormat?: string;
+ defaultInputTarget?: CommandIdentifier;
+ inputStream?: Readable;
+ handleInput?: boolean;
+ pauseInputStreamOnFinish?: boolean;
+ /**
+ * How much time in milliseconds to wait before restarting a command.
+ *
+ * @see RestartProcess
+ */
+ restartDelay?: number;
+ /**
+ * 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;
+ /**
+ * List of additional arguments passed that will get replaced in each command.
+ * If not defined, no argument replacing will happen.
+ */
+ additionalArguments?: string[];
+};
+declare const _default: (commands: ConcurrentlyCommandInput[], options?: Partial<ConcurrentlyOptions>) => ConcurrentlyResult;
+export default _default;
+export { CloseEvent, Command, CommandIdentifier, concurrently, ConcurrentlyCommandInput, ConcurrentlyResult, FlowController, InputHandler, KillOnSignal, KillOthers, LogError, LogExit, Logger, LogOutput, LogTimings, RestartProcess, TimerEvent, };
diff --git a/node_modules/concurrently/dist/src/index.js b/node_modules/concurrently/dist/src/index.js
new file mode 100644
index 0000000..2d87891
--- /dev/null
+++ b/node_modules/concurrently/dist/src/index.js
@@ -0,0 +1,71 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.RestartProcess = exports.LogTimings = exports.LogOutput = exports.Logger = exports.LogExit = exports.LogError = exports.KillOthers = exports.KillOnSignal = exports.InputHandler = exports.concurrently = exports.Command = void 0;
+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, "concurrently", { 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 restart_process_1 = require("./flow-control/restart-process");
+Object.defineProperty(exports, "RestartProcess", { enumerable: true, get: function () { return restart_process_1.RestartProcess; } });
+const logger_1 = require("./logger");
+Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
+exports.default = (commands, options = {}) => {
+ const logger = new logger_1.Logger({
+ hide: options.hide,
+ prefixFormat: options.prefix,
+ prefixLength: options.prefixLength,
+ raw: options.raw,
+ timestampFormat: options.timestampFormat,
+ });
+ return (0, concurrently_1.concurrently)(commands, {
+ maxProcesses: options.maxProcesses,
+ raw: options.raw,
+ successCondition: options.successCondition,
+ cwd: options.cwd,
+ logger,
+ outputStream: options.outputStream || process.stdout,
+ group: options.group,
+ controllers: [
+ 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 }),
+ new restart_process_1.RestartProcess({
+ logger,
+ delay: options.restartDelay,
+ tries: options.restartTries,
+ }),
+ new kill_others_1.KillOthers({
+ logger,
+ conditions: options.killOthers || [],
+ killSignal: options.killSignal,
+ }),
+ new log_timings_1.LogTimings({
+ logger: options.timings ? logger : undefined,
+ timestampFormat: options.timestampFormat,
+ }),
+ ],
+ prefixColors: options.prefixColors || [],
+ additionalArguments: options.additionalArguments,
+ });
+};
diff --git a/node_modules/concurrently/dist/src/logger.d.ts b/node_modules/concurrently/dist/src/logger.d.ts
new file mode 100644
index 0000000..69b0d13
--- /dev/null
+++ b/node_modules/concurrently/dist/src/logger.d.ts
@@ -0,0 +1,72 @@
+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 prefixLength;
+ private readonly timestampFormat;
+ /**
+ * Last character emitted.
+ * If `undefined`, then nothing has been logged yet.
+ */
+ private lastChar?;
+ /**
+ * 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, prefixLength, raw, timestampFormat, }: {
+ /**
+ * Which command(s) should have their output hidden.
+ */
+ hide?: CommandIdentifier | 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, used when the prefix format is `command`.
+ */
+ prefixLength?: number;
+ /**
+ * Date format used when logging date/time.
+ * @see https://date-fns.org/v2.0.1/docs/format
+ */
+ timestampFormat?: string;
+ });
+ private shortenText;
+ private getPrefixesFor;
+ getPrefix(command: Command): string;
+ 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;
+}
diff --git a/node_modules/concurrently/dist/src/logger.js b/node_modules/concurrently/dist/src/logger.js
new file mode 100644
index 0000000..5fb368c
--- /dev/null
+++ b/node_modules/concurrently/dist/src/logger.js
@@ -0,0 +1,202 @@
+"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 format_1 = __importDefault(require("date-fns/format"));
+const lodash_1 = __importDefault(require("lodash"));
+const Rx = __importStar(require("rxjs"));
+const defaults = __importStar(require("./defaults"));
+class Logger {
+ constructor({ hide, prefixFormat, prefixLength, raw = false, timestampFormat, }) {
+ /**
+ * Observable that emits when there's been output logged.
+ * If `command` is is `undefined`, then the log is for a global event.
+ */
+ this.output = new Rx.Subject();
+ // 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.
+ this.hide = lodash_1.default.castArray(hide)
+ .filter((name) => name || name === 0)
+ .map(String);
+ this.raw = raw;
+ this.prefixFormat = prefixFormat;
+ this.prefixLength = prefixLength || defaults.prefixLength;
+ this.timestampFormat = timestampFormat || defaults.timestampFormat;
+ }
+ shortenText(text) {
+ if (!text || text.length <= this.prefixLength) {
+ return text;
+ }
+ const ellipsis = '..';
+ const prefixLength = this.prefixLength - 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 {
+ pid: String(command.pid),
+ index: String(command.index),
+ name: command.name,
+ command: this.shortenText(command.command),
+ time: (0, format_1.default)(Date.now(), this.timestampFormat),
+ };
+ }
+ getPrefix(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 `[${prefixes[prefix]}]`;
+ }
+ return 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);
+ }
+ colorText(command, text) {
+ let color;
+ if (command.prefixColor && command.prefixColor.startsWith('#')) {
+ color = chalk_1.default.hex(command.prefixColor);
+ }
+ else {
+ const defaultColor = lodash_1.default.get(chalk_1.default, defaults.prefixColors, chalk_1.default.reset);
+ color = lodash_1.default.get(chalk_1.default, 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;
+ }
+ this.logCommandText(chalk_1.default.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(chalk_1.default.reset('-->') + ' ', chalk_1.default.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, '...');
+ const lines = text.split('\n').map((line, index, lines) => {
+ // First line will write prefix only if we finished the last write with a LF.
+ // Last line won't write prefix because it should be empty.
+ if (index === 0 || index === lines.length - 1) {
+ return line;
+ }
+ return prefix + line;
+ });
+ if (!this.lastChar || this.lastChar === '\n') {
+ this.emit(command, prefix);
+ }
+ this.lastChar = text[text.length - 1];
+ this.emit(command, lines.join('\n'));
+ }
+ emit(command, text) {
+ this.output.next({ command, text });
+ }
+}
+exports.Logger = Logger;
diff --git a/node_modules/concurrently/dist/src/output-writer.d.ts b/node_modules/concurrently/dist/src/output-writer.d.ts
new file mode 100644
index 0000000..67f835b
--- /dev/null
+++ b/node_modules/concurrently/dist/src/output-writer.d.ts
@@ -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;
+}
diff --git a/node_modules/concurrently/dist/src/output-writer.js b/node_modules/concurrently/dist/src/output-writer.js
new file mode 100644
index 0000000..0795e82
--- /dev/null
+++ b/node_modules/concurrently/dist/src/output-writer.js
@@ -0,0 +1,71 @@
+"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 {
+ constructor({ outputStream, group, commands, }) {
+ this.activeCommandIndex = 0;
+ 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);
+ if (!commands[i].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;
diff --git a/node_modules/concurrently/dist/src/prefix-color-selector.d.ts b/node_modules/concurrently/dist/src/prefix-color-selector.d.ts
new file mode 100644
index 0000000..8dcf7a0
--- /dev/null
+++ b/node_modules/concurrently/dist/src/prefix-color-selector.d.ts
@@ -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;
+}
diff --git a/node_modules/concurrently/dist/src/prefix-color-selector.js b/node_modules/concurrently/dist/src/prefix-color-selector.js
new file mode 100644
index 0000000..c01b2ca
--- /dev/null
+++ b/node_modules/concurrently/dist/src/prefix-color-selector.js
@@ -0,0 +1,93 @@
+"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 {
+ 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;
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage