Socket
Socket
Sign inDemoInstall

concurrently

Package Overview
Dependencies
Maintainers
2
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

concurrently - npm Package Compare versions

Comparing version 7.2.2 to 7.3.0

20

dist/bin/concurrently.js

@@ -38,3 +38,3 @@ #!/usr/bin/env node

// Find argument separator (double dash)
const argsSepIdx = cleanArgs.findIndex((arg) => arg === '--');
const argsSepIdx = cleanArgs.findIndex(arg => arg === '--');
// Arguments before separator

@@ -61,3 +61,3 @@ const argsBeforeSep = argsSepIdx >= 0 ? cleanArgs.slice(0, argsSepIdx) : cleanArgs;

},
'names': {
names: {
alias: 'n',

@@ -73,3 +73,3 @@ describe: 'List of custom names to be used in prefix template.\n' +

},
'success': {
success: {
alias: 's',

@@ -87,3 +87,3 @@ describe: 'Which command(s) must exit with code 0 in order for concurrently exit with ' +

},
'raw': {
raw: {
alias: 'r',

@@ -100,3 +100,3 @@ describe: 'Output only raw output of processes, disables prettifying ' +

},
'hide': {
hide: {
describe: 'Comma-separated list of processes to hide the output.\n' +

@@ -107,3 +107,3 @@ 'The processes can be identified by their name or index.',

},
'group': {
group: {
alias: 'g',

@@ -113,3 +113,3 @@ describe: 'Order the output as if the commands were run sequentially.',

},
'timings': {
timings: {
describe: 'Show timing information for all processes.',

@@ -137,3 +137,3 @@ type: 'boolean',

// Prefix
'prefix': {
prefix: {
alias: 'p',

@@ -216,3 +216,5 @@ describe: 'Prefix used in logging for each process.\n' +

? ['success', 'failure']
: (args.killOthersOnFail ? ['failure'] : []),
: args.killOthersOnFail
? ['failure']
: [],
maxProcesses: args.maxProcesses,

@@ -219,0 +221,0 @@ raw: args.raw,

@@ -36,13 +36,7 @@ "use strict";

description: 'Send input to specific child identified by index',
example: [
'$ $0 --handle-input "npm run watch-js" nodemon',
'1:rs',
].join('\n'),
example: ['$ $0 --handle-input "npm run watch-js" nodemon', '1:rs'].join('\n'),
},
{
description: 'Send input to specific child identified by name',
example: [
'$ $0 --handle-input -n js,srv "npm run watch-js" nodemon',
'srv:rs',
].join('\n'),
example: ['$ $0 --handle-input -n js,srv "npm run watch-js" nodemon', 'srv:rs'].join('\n'),
},

@@ -62,22 +56,29 @@ {

{
description: 'Passthrough some additional arguments via \'{<number>}\' placeholder',
description: "Passthrough some additional arguments via '{<number>}' placeholder",
example: '$ $0 -P "echo {1}" -- foo',
},
{
description: 'Passthrough all additional arguments via \'{@}\' placeholder',
description: "Passthrough all additional arguments via '{@}' placeholder",
example: '$ $0 -P "npm:dev-* -- {@}" -- --watch --noEmit',
},
{
description: 'Passthrough all additional arguments combined via \'{*}\' placeholder',
description: "Passthrough all additional arguments combined via '{*}' placeholder",
example: '$ $0 -P "npm:dev-* -- {*}" -- --watch --noEmit',
},
];
const examplesString = examples
.map(({ example, description }) => [
` - ${description}`,
example
.split('\n')
.map(line => ` ${line}`)
.join('\n'),
].join('\n\n'))
.join('\n\n');
exports.epilogue = `
Examples:
${examples.map(({ example, description }) => `
- ${description}
${example.split('\n').map(line => ` ${line}`).join('\n')}
`).join('')}
${examplesString}
For more details, visit https://github.com/open-cli-tools/concurrently
`;

@@ -9,5 +9,9 @@ import { CommandInfo } from '../command';

constructor(additionalArguments: string[]);
parse(commandInfo: CommandInfo): CommandInfo & {
parse(commandInfo: CommandInfo): {
command: string;
name: string;
env?: Record<string, unknown>;
cwd?: string;
prefixColor?: string;
};
}

@@ -13,6 +13,6 @@ "use strict";

parse(commandInfo) {
const command = commandInfo.command.replace(/\\?\{([@\*]|[1-9][0-9]*)\}/g, (match, placeholderTarget) => {
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.substring(1);
return match.slice(1);
}

@@ -36,7 +36,5 @@ // Replace numeric placeholder if value exists in additional arguments.

});
return Object.assign({}, commandInfo, {
command,
});
return { ...commandInfo, command };
}
}
exports.ExpandArguments = ExpandArguments;

@@ -13,9 +13,9 @@ "use strict";

}
return Object.assign({}, commandInfo, {
return {
...commandInfo,
name: commandInfo.name || cmdName,
command: `${npmCmd} run ${cmdName}${args}`,
});
};
}
}
exports.ExpandNpmShortcut = ExpandNpmShortcut;
;
"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.ExpandNpmWildcard = void 0;
const fs = __importStar(require("fs"));
const _ = __importStar(require("lodash"));
const OMISSION = /\(!([^\)]+)\)/;
const fs_1 = __importDefault(require("fs"));
const lodash_1 = __importDefault(require("lodash"));
const OMISSION = /\(!([^)]+)\)/;
/**

@@ -40,3 +20,3 @@ * Finds wildcards in npm/yarn/pnpm run commands and replaces them with all matching scripts in the

try {
const json = fs.readFileSync('package.json', { encoding: 'utf-8' });
const json = fs_1.default.readFileSync('package.json', { encoding: 'utf-8' });
return JSON.parse(json);

@@ -61,4 +41,4 @@ }

const cmdNameSansOmission = cmdName.replace(OMISSION, '');
const preWildcard = _.escapeRegExp(cmdNameSansOmission.substr(0, wildcardPosition));
const postWildcard = _.escapeRegExp(cmdNameSansOmission.substr(wildcardPosition + 1));
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}$`);

@@ -76,3 +56,4 @@ const currentName = commandInfo.name || '';

if (match) {
return Object.assign({}, commandInfo, {
return {
...commandInfo,
command: `${npmCmd} run ${script}${args}`,

@@ -82,3 +63,3 @@ // Will use an empty command name if command has no name and the wildcard match is empty,

name: currentName + match[1],
});
};
}

@@ -90,2 +71,1 @@ })

exports.ExpandNpmWildcard = ExpandNpmWildcard;
;

@@ -7,5 +7,9 @@ import { CommandInfo } from '../command';

export declare class StripQuotes implements CommandParser {
parse(commandInfo: CommandInfo): CommandInfo & {
parse(commandInfo: CommandInfo): {
command: string;
name: string;
env?: Record<string, unknown>;
cwd?: string;
prefixColor?: string;
};
}

@@ -12,8 +12,7 @@ "use strict";

if (/^"(.+?)"$/.test(command) || /^'(.+?)'$/.test(command)) {
command = command.substring(1, command.length - 1);
command = command.slice(1, command.length - 1);
}
return Object.assign({}, commandInfo, { command });
return { ...commandInfo, command };
}
}
exports.StripQuotes = StripQuotes;
;
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import { ChildProcess as BaseChildProcess, SpawnOptions } from 'child_process';

@@ -21,3 +24,3 @@ import * as Rx from 'rxjs';

*/
env?: Record<string, any>;
env?: Record<string, unknown>;
/**

@@ -80,3 +83,3 @@ * The current working directory of the process when spawned.

/** @inheritdoc */
readonly env: Record<string, any>;
readonly env: Record<string, unknown>;
/** @inheritdoc */

@@ -83,0 +86,0 @@ readonly cwd?: string;

@@ -80,3 +80,3 @@ "use strict";

endDate,
durationSeconds: durationSeconds + (durationNanoSeconds / 1e9),
durationSeconds: durationSeconds + durationNanoSeconds / 1e9,
},

@@ -100,3 +100,2 @@ });

exports.Command = Command;
;
/**

@@ -103,0 +102,0 @@ * Pipes all events emitted by `stream` into `subject`.

@@ -15,7 +15,7 @@ import * as Rx from 'rxjs';

* Provides logic to determine whether lists of commands ran successfully.
*/
*/
export declare class CompletionListener {
private readonly successCondition;
private readonly scheduler?;
constructor({ successCondition, scheduler }: {
constructor({ successCondition, scheduler, }: {
/**

@@ -22,0 +22,0 @@ * How this instance will define that a list of commands ran successfully.

@@ -31,5 +31,5 @@ "use strict";

* Provides logic to determine whether lists of commands ran successfully.
*/
*/
class CompletionListener {
constructor({ successCondition = 'all', scheduler }) {
constructor({ successCondition = 'all', scheduler, }) {
this.successCondition = successCondition;

@@ -54,12 +54,10 @@ this.scheduler = scheduler;

const nameOrIndex = commandSyntaxMatch[1];
const targetCommandsEvents = events.filter(({ command, index }) => (command.name === nameOrIndex
|| index === Number(nameOrIndex)));
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));
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);
return (targetCommandsEvents.length > 0 &&
targetCommandsEvents.every(event => event.exitCode === 0));
}

@@ -73,4 +71,3 @@ /**

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)
return Rx.lastValueFrom(Rx.merge(...closeStreams).pipe((0, operators_1.bufferCount)(closeStreams.length), (0, operators_1.switchMap)(exitInfos => this.isSuccess(exitInfos)
? Rx.of(exitInfos, this.scheduler)

@@ -81,2 +78,1 @@ : Rx.throwError(exitInfos, this.scheduler)), (0, operators_1.take)(1)));

exports.CompletionListener = CompletionListener;
;

@@ -50,7 +50,8 @@ "use strict";

// Use documented behaviour of repeating last color when specifying more commands than colors
lastColor = options.prefixColors && options.prefixColors[index] || lastColor;
return new command_1.Command(Object.assign({
lastColor = (options.prefixColors && options.prefixColors[index]) || lastColor;
return new command_1.Command({
index,
prefixColor: lastColor,
}, command), (0, get_spawn_opts_1.getSpawnOpts)({
...command,
}, (0, get_spawn_opts_1.getSpawnOpts)({
raw: options.raw,

@@ -70,3 +71,3 @@ env: command.env,

commands = handleResult.commands;
if (options.logger) {
if (options.logger && options.outputStream) {
const outputWriter = new output_writer_1.OutputWriter({

@@ -87,3 +88,3 @@ outputStream: options.outputStream,

.finally(() => {
handleResult.onFinishCallbacks.forEach((onFinish) => onFinish());
handleResult.onFinishCallbacks.forEach(onFinish => onFinish());
});

@@ -96,3 +97,2 @@ return {

exports.concurrently = concurrently;
;
function mapToCommandInfo(command) {

@@ -107,3 +107,3 @@ if (typeof command === 'string') {

}
return Object.assign({
return {
command: command.command,

@@ -113,5 +113,8 @@ name: command.name || '',

cwd: command.cwd || '',
}, command.prefixColor ? {
prefixColor: command.prefixColor,
} : {});
...(command.prefixColor
? {
prefixColor: command.prefixColor,
}
: {}),
};
}

@@ -118,0 +121,0 @@ function parseCommand(command, parsers) {

@@ -20,3 +20,3 @@ /// <reference types="node" />

private readonly pauseInputStreamOnFinish;
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger }: {
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger, }: {
inputStream: Readable;

@@ -23,0 +23,0 @@ logger: Logger;

@@ -40,3 +40,3 @@ "use strict";

class InputHandler {
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger }) {
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger, }) {
this.logger = logger;

@@ -57,4 +57,4 @@ this.defaultInputTarget = defaultInputTarget || defaults.defaultInputTarget;

const input = dataParts[1] || data;
const command = commands.find(command => (command.name === targetId ||
command.index.toString() === targetId.toString()));
const command = commands.find(command => command.name === targetId ||
command.index.toString() === targetId.toString());
if (command && command.stdin) {

@@ -79,2 +79,1 @@ command.stdin.write(input);

exports.InputHandler = InputHandler;
;

@@ -25,3 +25,3 @@ "use strict";

const exitCode = caughtSignal === 'SIGINT' ? 0 : exitInfo.exitCode;
return Object.assign({}, exitInfo, { exitCode });
return { ...exitInfo, exitCode };
}));

@@ -38,2 +38,1 @@ return new Proxy(command, {

exports.KillOnSignal = KillOnSignal;
;

@@ -11,3 +11,3 @@ import { Command } from '../command';

private readonly conditions;
constructor({ logger, conditions }: {
constructor({ logger, conditions, }: {
logger: Logger;

@@ -14,0 +14,0 @@ conditions: ProcessCloseCondition | ProcessCloseCondition[];

@@ -13,3 +13,3 @@ "use strict";

class KillOthers {
constructor({ logger, conditions }) {
constructor({ logger, conditions, }) {
this.logger = logger;

@@ -19,4 +19,3 @@ this.conditions = lodash_1.default.castArray(conditions);

handle(commands) {
const conditions = this.conditions.filter(condition => (condition === 'failure' ||
condition === 'success'));
const conditions = this.conditions.filter(condition => condition === 'failure' || condition === 'success');
if (!conditions.length) {

@@ -37,2 +36,1 @@ return { commands };

exports.KillOthers = KillOthers;
;

@@ -14,3 +14,3 @@ "use strict";

this.logger.logCommandEvent(`Error occurred when executing command: ${command.command}`, command);
const errorText = String(event instanceof Error ? (event.stack || event) : event);
const errorText = String(event instanceof Error ? event.stack || event : event);
this.logger.logCommandEvent(errorText, command);

@@ -22,2 +22,1 @@ }));

exports.LogError = LogError;
;

@@ -19,2 +19,1 @@ "use strict";

exports.LogExit = LogExit;
;

@@ -20,2 +20,1 @@ "use strict";

exports.LogOutput = LogOutput;
;

@@ -15,10 +15,10 @@ import { CloseEvent, Command } from '../command';

export declare class LogTimings implements FlowController {
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode }: CloseEvent): TimingInfo;
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode, }: CloseEvent): TimingInfo;
private readonly logger?;
private readonly timestampFormat;
constructor({ logger, timestampFormat }: {
constructor({ logger, timestampFormat, }: {
logger?: Logger;
timestampFormat?: string;
});
printExitInfoTimingTable(exitInfos: CloseEvent[]): CloseEvent[];
private printExitInfoTimingTable;
handle(commands: Command[]): {

@@ -25,0 +25,0 @@ commands: Command[];

@@ -39,7 +39,7 @@ "use strict";

class LogTimings {
constructor({ logger, timestampFormat = defaults.timestampFormat }) {
constructor({ logger, timestampFormat = defaults.timestampFormat, }) {
this.logger = logger;
this.timestampFormat = timestampFormat;
}
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode }) {
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode, }) {
const readableDurationMs = (timings.endDate.getTime() - timings.startDate.getTime()).toLocaleString();

@@ -55,3 +55,2 @@ return {

printExitInfoTimingTable(exitInfos) {
var _a, _b;
const exitInfoTable = (0, lodash_1.default)(exitInfos)

@@ -62,7 +61,6 @@ .sortBy(({ timings }) => timings.durationSeconds)

.value();
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.logGlobalEvent('Timings:');
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.logTable(exitInfoTable);
this.logger.logGlobalEvent('Timings:');
this.logger.logTable(exitInfoTable);
return exitInfos;
}
;
handle(commands) {

@@ -75,6 +73,5 @@ if (!this.logger) {

command.timer.subscribe(({ startDate, endDate }) => {
var _a, _b;
if (!endDate) {
const formattedStartDate = (0, format_1.default)(startDate, this.timestampFormat);
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.logCommandEvent(`${command.command} started at ${formattedStartDate}`, command);
this.logger.logCommandEvent(`${command.command} started at ${formattedStartDate}`, command);
}

@@ -84,3 +81,3 @@ else {

const formattedEndDate = (0, format_1.default)(endDate, this.timestampFormat);
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.logCommandEvent(`${command.command} stopped at ${formattedEndDate} after ${durationMs.toLocaleString()}ms`, command);
this.logger.logCommandEvent(`${command.command} stopped at ${formattedEndDate} after ${durationMs.toLocaleString()}ms`, command);
}

@@ -92,3 +89,3 @@ });

const allProcessesClosed = Rx.merge(...closeStreams).pipe((0, operators_1.bufferCount)(closeStreams.length), (0, operators_1.take)(1));
allProcessesClosed.subscribe((exitInfos) => this.printExitInfoTimingTable(exitInfos));
allProcessesClosed.subscribe(exitInfos => this.printExitInfoTimingTable(exitInfos));
return { commands };

@@ -98,2 +95,1 @@ }

exports.LogTimings = LogTimings;
;

@@ -13,3 +13,3 @@ import * as Rx from 'rxjs';

readonly tries: number;
constructor({ delay, tries, logger, scheduler }: {
constructor({ delay, tries, logger, scheduler, }: {
delay?: number;

@@ -16,0 +16,0 @@ tries?: number;

@@ -34,3 +34,3 @@ "use strict";

class RestartProcess {
constructor({ delay, tries, logger, scheduler }) {
constructor({ delay, tries, logger, scheduler, }) {
this.logger = logger;

@@ -46,3 +46,5 @@ this.delay = delay != null ? +delay : defaults.restartDelay;

}
commands.map(command => command.close.pipe((0, operators_1.take)(this.tries), (0, operators_1.takeWhile)(({ exitCode }) => exitCode !== 0))).map((failure, index) => Rx.merge(
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),

@@ -77,2 +79,1 @@ // explicitly telling the subscriber that a restart is needed

exports.RestartProcess = RestartProcess;
;
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import { SpawnOptions } from 'child_process';

@@ -29,3 +32,3 @@ import supportsColor from 'supports-color';

*/
env?: Record<string, any>;
env?: Record<string, unknown>;
}) => SpawnOptions;

@@ -8,5 +8,12 @@ "use strict";

const supports_color_1 = __importDefault(require("supports-color"));
const getSpawnOpts = ({ colorSupport = supports_color_1.default.stdout, cwd, process = global.process, raw = false, env = {}, }) => Object.assign({
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: Object.assign(colorSupport ? { FORCE_COLOR: colorSupport.level } : {}, process.env, env) });
...(raw && { stdio: 'inherit' }),
...(/^win/.test(process.platform) && { detached: false }),
env: {
...(colorSupport ? { FORCE_COLOR: colorSupport.level.toString() } : {}),
...process.env,
...env,
},
});
exports.getSpawnOpts = getSpawnOpts;

@@ -22,3 +22,3 @@ import * as Rx from 'rxjs';

}>;
constructor({ hide, prefixFormat, prefixLength, raw, timestampFormat }: {
constructor({ hide, prefixFormat, prefixLength, raw, timestampFormat, }: {
/**

@@ -70,5 +70,5 @@ * Which command(s) should have their output hidden.

*/
logTable(tableContents: any[]): void;
logTable(tableContents: unknown[]): void;
log(prefix: string, text: string, command?: Command): void;
emit(command: Command | undefined, text: string): void;
}

@@ -36,3 +36,3 @@ "use strict";

class Logger {
constructor({ hide, prefixFormat, prefixLength, raw = false, timestampFormat }) {
constructor({ hide, prefixFormat, prefixLength, raw = false, timestampFormat, }) {
/**

@@ -46,3 +46,5 @@ * Observable that emits when there's been output logged.

// 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.hide = lodash_1.default.castArray(hide)
.filter(name => name || name === 0)
.map(String);
this.raw = raw;

@@ -61,4 +63,4 @@ this.prefixFormat = prefixFormat;

const beginningLength = prefixLength - endLength;
const beginnning = text.substring(0, beginningLength);
const end = text.substring(text.length - endLength, text.length);
const beginnning = text.slice(0, beginningLength);
const end = text.slice(text.length - endLength, text.length);
return beginnning + ellipsis + end;

@@ -143,3 +145,3 @@ }

const rowContents = [];
Object.keys(row).forEach((col) => {
Object.keys(row).forEach(col => {
if (!headers[col]) {

@@ -160,5 +162,3 @@ headers[col] = {

});
const headersFormatted = Object
.keys(headers)
.map(header => header.padEnd(headers[header].length, ' '));
const headersFormatted = Object.keys(headers).map(header => header.padEnd(headers[header].length, ' '));
if (!headersFormatted.length) {

@@ -208,2 +208,1 @@ // No columns exist.

exports.Logger = Logger;
;

@@ -12,3 +12,3 @@ /// <reference types="node" />

activeCommandIndex: number;
constructor({ outputStream, group, commands }: {
constructor({ outputStream, group, commands, }: {
outputStream: Writable;

@@ -15,0 +15,0 @@ group: boolean;

@@ -32,3 +32,3 @@ "use strict";

class OutputWriter {
constructor({ outputStream, group, commands }) {
constructor({ outputStream, group, commands, }) {
this.activeCommandIndex = 0;

@@ -39,4 +39,3 @@ this.outputStream = outputStream;

if (this.group) {
Rx.merge(...commands.map(c => c.close))
.subscribe(command => {
Rx.merge(...commands.map(c => c.close)).subscribe(command => {
if (command.index !== this.activeCommandIndex) {

@@ -75,2 +74,1 @@ return;

exports.OutputWriter = OutputWriter;
;

@@ -5,4 +5,5 @@ //

// eslint-disable-next-line @typescript-eslint/no-var-requires
const concurrently = require('./dist/src/index.js');
module.exports = exports = concurrently.default;
Object.assign(exports, concurrently);
{
"name": "concurrently",
"version": "7.2.2",
"version": "7.3.0",
"description": "Run commands concurrently",

@@ -15,6 +15,9 @@ "main": "index.js",

"exports": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js",
"types": "./dist/src/index.d.ts"
".": {
"import": "./index.mjs",
"require": "./index.js",
"default": "./index.js",
"types": "./dist/src/index.d.ts"
},
"./package.json": "./package.json"
},

@@ -25,3 +28,6 @@ "scripts": {

"clean": "tsc --build --clean",
"format": "prettier --ignore-path .gitignore --check '**/{!(package-lock).json,*.y?(a)ml,*.md}'",
"format:fix": "npm run format -- --write",
"lint": "eslint . --ext js,ts --ignore-path .gitignore",
"lint:fix": "npm run lint -- --fix",
"prepublishOnly": "npm run build",

@@ -57,2 +63,5 @@ "report-coverage": "cat coverage/lcov.info | coveralls",

"devDependencies": {
"@swc-node/register": "^1.5.1",
"@swc/core": "^1.2.204",
"@swc/jest": "^0.2.21",
"@types/jest": "^27.0.3",

@@ -68,6 +77,9 @@ "@types/lodash": "^4.14.178",

"eslint": "^8.15.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.5.1",
"jest-create-mock-instance": "^2.0.0",
"ts-jest": "^27.1.4",
"ts-node": "^10.4.0",
"lint-staged": "^12.4.1",
"prettier": "^2.6.2",
"simple-git-hooks": "^2.7.0",
"typescript": "^4.5.4"

@@ -83,19 +95,9 @@ },

],
"jest": {
"preset": "ts-jest",
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.ts",
"!src/index.ts"
],
"coveragePathIgnorePatterns": [
"/fixtures/",
"/node_modules/"
],
"testEnvironment": "node",
"testPathIgnorePatterns": [
"/node_modules/",
"/dist"
]
"simple-git-hooks": {
"pre-commit": "npx lint-staged"
},
"lint-staged": {
"*.{js,ts}": "eslint --fix",
"{!(package-lock).json,*.y?(a)ml,*.md}": "prettier --write"
}
}

@@ -1,15 +0,17 @@

# Concurrently
# concurrently
[![Build Status](https://github.com/open-cli-tools/concurrently/workflows/Tests/badge.svg)](https://github.com/open-cli-tools/concurrently/actions?workflow=Tests)
[![Coverage Status](https://coveralls.io/repos/github/open-cli-tools/concurrently/badge.svg?branch=master)](https://coveralls.io/github/open-cli-tools/concurrently?branch=master)
[![Latest Release](https://img.shields.io/github/v/release/open-cli-tools/concurrently?label=Release)](https://github.com/open-cli-tools/concurrently/releases)
[![License](https://img.shields.io/github/license/open-cli-tools/concurrently?label=License)](https://github.com/open-cli-tools/concurrently/blob/main/LICENSE)
[![Weekly Downloads on NPM](https://img.shields.io/npm/dw/concurrently?label=Downloads&logo=npm)](https://www.npmjs.com/package/concurrently)
[![CI Status](https://img.shields.io/github/workflow/status/open-cli-tools/concurrently/CI?label=CI&logo=github)](https://github.com/open-cli-tools/concurrently/actions/workflows/ci.yml)
[![Coverage Status](https://img.shields.io/coveralls/github/open-cli-tools/concurrently/main?label=Coverage&logo=coveralls)](https://coveralls.io/github/open-cli-tools/concurrently?branch=main)
[![NPM Badge](https://nodei.co/npm/concurrently.png?downloads=true)](https://www.npmjs.com/package/concurrently)
Run multiple commands concurrently.
Like `npm run watch-js & npm run watch-less` but better.
![](docs/demo.gif)
![Demo](docs/demo.gif)
**Table of contents**
- [Concurrently](#concurrently)
**Table of Contents**
- [concurrently](#concurrently)
- [Why](#why)

@@ -37,6 +39,6 @@ - [Install](#install)

* Cross platform (including Windows)
* Output is easy to follow with prefixes
* With `--kill-others` switch, all commands are killed if one dies
* Spawns commands with [spawn-command](https://github.com/mmalecki/spawn-command)
- Cross platform (including Windows)
- Output is easy to follow with prefixes
- With `--kill-others` switch, all commands are killed if one dies
- Spawns commands with [spawn-command](https://github.com/mmalecki/spawn-command)

@@ -60,2 +62,3 @@ ## Install

Remember to surround separate commands with quotes:
```bash

@@ -86,13 +89,13 @@ concurrently "command1 arg" "command2 arg"

```javascript
```jsonc
{
//...
"scripts": {
// ...
"watch-js": "...",
"watch-css": "...",
"watch-node": "...",
// ...
},
//...
"scripts": {
// ...
"watch-js": "...",
"watch-css": "...",
"watch-node": "..."
// ...
}
// ...
}

@@ -116,15 +119,17 @@ ```

Exclusion is also supported. Given the following scripts in package.json:
```javascript
```jsonc
{
// ...
"scripts": {
"lint:js": "...",
"lint:ts": "...",
"lint:fix:js": "...",
"lint:fix:ts": "..."
// ...
"scripts": {
"lint:js": "...",
"lint:ts": "...",
"lint:fix:js": "...",
"lint:fix:ts": "...",
// ...
}
// ...
}
// ...
}
```
```bash

@@ -298,4 +303,5 @@ # Running only lint:js and lint:ts

## API
concurrently can be used programmatically by using the API documented below:
**concurrently** can be used programmatically by using the API documented below:
### `concurrently(commands[, options])`

@@ -307,34 +313,35 @@

- `options` (optional): an object containing any of the below:
- `cwd`: the working directory to be used by all commands. Can be overriden per command.
- `cwd`: the working directory to be used by all commands. Can be overriden per command.
Default: `process.cwd()`.
- `defaultInputTarget`: the default input target when reading from `inputStream`.
- `defaultInputTarget`: the default input target when reading from `inputStream`.
Default: `0`.
- `handleInput`: when `true`, reads input from `process.stdin`.
- `inputStream`: a [`Readable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_readable_streams)
- `handleInput`: when `true`, reads input from `process.stdin`.
- `inputStream`: a [`Readable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_readable_streams)
to read the input from. Should only be used in the rare instance you would like to stream anything other than `process.stdin`. Overrides `handleInput`.
- `pauseInputStreamOnFinish`: by default, pauses the input stream (`process.stdin` when `handleInput` is enabled, or `inputStream` if provided) when all of the processes have finished. If you need to read from the input stream after `concurrently` has finished, set this to `false`. ([#252](https://github.com/kimmobrunfeldt/concurrently/issues/252)).
- `killOthers`: an array of exitting conditions that will cause a process to kill others.
- `pauseInputStreamOnFinish`: by default, pauses the input stream (`process.stdin` when `handleInput` is enabled, or `inputStream` if provided) when all of the processes have finished. If you need to read from the input stream after `concurrently` has finished, set this to `false`. ([#252](https://github.com/kimmobrunfeldt/concurrently/issues/252)).
- `killOthers`: an array of exitting conditions that will cause a process to kill others.
Can contain any of `success` or `failure`.
- `maxProcesses`: how many processes should run at once.
- `outputStream`: a [`Writable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_writable_streams)
- `maxProcesses`: how many processes should run at once.
- `outputStream`: a [`Writable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_writable_streams)
to write logs to. Default: `process.stdout`.
- `prefix`: the prefix type to use when logging processes output.
Possible values: `index`, `pid`, `time`, `command`, `name`, `none`, or a template (eg `[{time} process: {pid}]`).
Default: the name of the process, or its index if no name is set.
- `prefixColors`: a list of colors as supported by [chalk](https://www.npmjs.com/package/chalk).
If concurrently would run more commands than there are colors, the last color is repeated.
Prefix colors specified per-command take precedence over this list.
- `prefixLength`: how many characters to show when prefixing with `command`. Default: `10`
- `raw`: whether raw mode should be used, meaning strictly process output will
- `prefix`: the prefix type to use when logging processes output.
Possible values: `index`, `pid`, `time`, `command`, `name`, `none`, or a template (eg `[{time} process: {pid}]`).
Default: the name of the process, or its index if no name is set.
- `prefixColors`: a list of colors as supported by [chalk](https://www.npmjs.com/package/chalk).
If concurrently would run more commands than there are colors, the last color is repeated.
Prefix colors specified per-command take precedence over this list.
- `prefixLength`: how many characters to show when prefixing with `command`. Default: `10`
- `raw`: whether raw mode should be used, meaning strictly process output will
be logged, without any prefixes, colouring or extra stuff.
- `successCondition`: the condition to consider the run was successful.
- `successCondition`: the condition to consider the run was successful.
If `first`, only the first process to exit will make up the success of the run; if `last`, the last process that exits will determine whether the run succeeds.
Anything else means all processes should exit successfully.
- `restartTries`: how many attempts to restart a process that dies will be made. Default: `0`.
- `restartDelay`: how many milliseconds to wait between process restarts. Default: `0`.
- `timestampFormat`: a [date-fns format](https://date-fns.org/v2.0.1/docs/format)
- `restartTries`: how many attempts to restart a process that dies will be made. Default: `0`.
- `restartDelay`: how many milliseconds to wait between process restarts. Default: `0`.
- `timestampFormat`: a [date-fns format](https://date-fns.org/v2.0.1/docs/format)
to use when prefixing with `time`. Default: `yyyy-MM-dd HH:mm:ss.ZZZ`
- `additionalArguments`: list of additional arguments passed that will get replaced in each command. If not defined, no argument replacing will happen.
- `additionalArguments`: list of additional arguments passed that will get replaced in each command. If not defined, no argument replacing will happen.
> **Returns:** an object in the shape `{ result, commands }`.
>
> - `result`: a `Promise` that resolves if the run was successful (according to `successCondition` option),

@@ -348,8 +355,14 @@ > or rejects, containing an array of [`CloseEvent`](#CloseEvent), in the order that the commands terminated.

const concurrently = require('concurrently');
const { result } = concurrently([
const { result } = concurrently(
[
'npm:watch-*',
{ command: 'nodemon', name: 'server' },
{ command: 'deploy', name: 'deploy', env: { PUBLIC_KEY: '...' } },
{ command: 'watch', name: 'watch', cwd: path.resolve(__dirname, 'scripts/watchers')}
], {
{
command: 'watch',
name: 'watch',
cwd: path.resolve(__dirname, 'scripts/watchers'),
},
],
{
prefix: 'name',

@@ -359,3 +372,4 @@ killOthers: ['failure', 'success'],

cwd: path.resolve(__dirname, 'scripts'),
});
}
);
result.then(success, failure);

@@ -365,2 +379,3 @@ ```

### `Command`
An object that contains all information about a spawned command, and ways to interact with it.<br>

@@ -388,2 +403,3 @@ It has the following properties:

### `CloseEvent`
An object with information about a command's closing event.<br>

@@ -400,17 +416,16 @@ It contains the following properties:

* Process exited with code *null*?
- Process exited with code _null_?
From [Node child_process documentation](http://nodejs.org/api/child_process.html#child_process_event_exit), `exit` event:
From [Node child_process documentation](http://nodejs.org/api/child_process.html#child_process_event_exit), `exit` event:
> This event is emitted after the child process ends. If the process
> terminated normally, code is the final exit code of the process,
> otherwise null. If the process terminated due to receipt of a signal,
> signal is the string name of the signal, otherwise null.
> This event is emitted after the child process ends. If the process
> terminated normally, code is the final exit code of the process,
> otherwise null. If the process terminated due to receipt of a signal,
> signal is the string name of the signal, otherwise null.
So _null_ means the process didn't terminate normally. This will make **concurrently**
to return non-zero exit code too.
So *null* means the process didn't terminate normally. This will make **concurrent**
to return non-zero exit code too.
- Does this work with the npm-replacements [yarn](https://github.com/yarnpkg/yarn) or [pnpm](https://pnpm.js.org/)?
* Does this work with the npm-replacements [yarn](https://github.com/yarnpkg/yarn) or [pnpm](https://pnpm.js.org/)?
Yes! In all examples above, you may replace "`npm`" with "`yarn`" or "`pnpm`".
Yes! In all examples above, you may replace "`npm`" with "`yarn`" or "`pnpm`".
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc