concurrently 9.2.1 → 10.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -14
- package/dist/bin/bin-options.d.ts +1 -0
- package/dist/bin/bin-options.js +1 -0
- package/dist/bin/{concurrently.js → index.js} +23 -62
- package/dist/bin/normalize-cli-command.d.ts +1 -0
- package/dist/bin/normalize-cli-command.js +15 -0
- package/dist/bin/read-package-json.d.ts +4 -0
- package/dist/bin/read-package-json.js +17 -0
- package/dist/lib/assert.d.ts +10 -0
- package/dist/lib/assert.js +24 -0
- package/dist/{src → lib}/command-parser/expand-arguments.d.ts +2 -2
- package/dist/{src → lib}/command-parser/expand-arguments.js +7 -12
- package/dist/{src → lib}/command-parser/expand-shortcut.d.ts +2 -2
- package/dist/{src → lib}/command-parser/expand-shortcut.js +1 -5
- package/dist/{src → lib}/command-parser/expand-wildcard.d.ts +2 -2
- package/dist/{src → lib}/command-parser/expand-wildcard.js +21 -28
- package/dist/{src → lib}/command.d.ts +5 -4
- package/dist/{src → lib}/command.js +3 -39
- package/dist/{src → lib}/completion-listener.d.ts +2 -2
- package/dist/{src → lib}/completion-listener.js +9 -46
- package/dist/{src → lib}/concurrently.d.ts +10 -10
- package/dist/{src → lib}/concurrently.js +29 -40
- package/dist/{src → lib}/date-format.d.ts +2 -2
- package/dist/{src → lib}/date-format.js +97 -76
- package/dist/{src → lib}/defaults.d.ts +2 -6
- package/dist/{src → lib}/defaults.js +16 -23
- package/dist/{src → lib}/flow-control/flow-controller.d.ts +1 -1
- package/dist/lib/flow-control/flow-controller.js +1 -0
- package/dist/{src → lib}/flow-control/input-handler.d.ts +4 -4
- package/dist/{src → lib}/flow-control/input-handler.js +8 -44
- package/dist/{src → lib}/flow-control/kill-on-signal.d.ts +3 -3
- package/dist/{src → lib}/flow-control/kill-on-signal.js +3 -7
- package/dist/{src → lib}/flow-control/kill-others.d.ts +3 -3
- package/dist/{src → lib}/flow-control/kill-others.js +8 -12
- package/dist/{src → lib}/flow-control/log-error.d.ts +3 -3
- package/dist/{src → lib}/flow-control/log-error.js +1 -5
- package/dist/{src → lib}/flow-control/log-exit.d.ts +3 -3
- package/dist/{src → lib}/flow-control/log-exit.js +1 -5
- package/dist/{src → lib}/flow-control/log-output.d.ts +3 -3
- package/dist/{src → lib}/flow-control/log-output.js +1 -5
- package/dist/{src → lib}/flow-control/log-timings.d.ts +3 -3
- package/dist/{src → lib}/flow-control/log-timings.js +8 -45
- package/dist/{src → lib}/flow-control/logger-padding.d.ts +3 -3
- package/dist/{src → lib}/flow-control/logger-padding.js +7 -7
- package/dist/{src → lib}/flow-control/output-error-handler.d.ts +4 -4
- package/dist/{src → lib}/flow-control/output-error-handler.js +3 -7
- package/dist/{src → lib}/flow-control/restart-process.d.ts +4 -4
- package/dist/lib/flow-control/restart-process.js +61 -0
- package/dist/{src → lib}/flow-control/teardown.d.ts +4 -5
- package/dist/lib/flow-control/teardown.js +45 -0
- package/dist/{src → lib}/index.d.ts +21 -19
- package/dist/lib/index.js +98 -0
- package/dist/{src → lib}/jsonc.js +3 -8
- package/dist/{src → lib}/logger.d.ts +3 -2
- package/dist/{src → lib}/logger.js +109 -65
- package/dist/{src → lib}/observables.d.ts +1 -1
- package/dist/{src → lib}/observables.js +3 -6
- package/dist/{src → lib}/output-writer.d.ts +3 -3
- package/dist/{src → lib}/output-writer.js +4 -41
- package/dist/lib/prefix-color-selector.d.ts +21 -0
- package/dist/{src → lib}/prefix-color-selector.js +14 -31
- package/dist/{src → lib}/spawn.d.ts +14 -5
- package/dist/lib/spawn.js +105 -0
- package/dist/lib/utils.d.ts +25 -0
- package/dist/lib/utils.js +52 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/README.md +6 -0
- package/docs/cli/prefixing.md +44 -4
- package/docs/shell-resolution.md +48 -0
- package/package.json +48 -67
- package/dist/bin/read-package.d.ts +0 -6
- package/dist/bin/read-package.js +0 -56
- package/dist/src/assert.d.ts +0 -5
- package/dist/src/assert.js +0 -15
- package/dist/src/command-parser/command-parser.d.ts +0 -19
- package/dist/src/command-parser/command-parser.js +0 -2
- package/dist/src/command-parser/strip-quotes.d.ts +0 -16
- package/dist/src/command-parser/strip-quotes.js +0 -17
- package/dist/src/flow-control/flow-controller.js +0 -2
- package/dist/src/flow-control/restart-process.js +0 -98
- package/dist/src/flow-control/teardown.js +0 -82
- package/dist/src/index.js +0 -96
- package/dist/src/prefix-color-selector.d.ts +0 -11
- package/dist/src/spawn.js +0 -49
- package/dist/src/utils.d.ts +0 -10
- package/dist/src/utils.js +0 -16
- package/index.d.mts +0 -7
- package/index.d.ts +0 -11
- package/index.js +0 -14
- package/index.mjs +0 -9
- /package/dist/bin/{concurrently.d.ts → index.d.ts} +0 -0
- /package/dist/{src → lib}/jsonc.d.ts +0 -0
|
@@ -1,45 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.CompletionListener = void 0;
|
|
37
|
-
const Rx = __importStar(require("rxjs"));
|
|
38
|
-
const operators_1 = require("rxjs/operators");
|
|
1
|
+
import Rx from 'rxjs';
|
|
2
|
+
import { delay, filter, map, share, switchMap, take } from 'rxjs/operators';
|
|
39
3
|
/**
|
|
40
4
|
* Provides logic to determine whether lists of commands ran successfully.
|
|
41
5
|
*/
|
|
42
|
-
class CompletionListener {
|
|
6
|
+
export class CompletionListener {
|
|
43
7
|
successCondition;
|
|
44
8
|
scheduler;
|
|
45
9
|
constructor({ successCondition = 'all', scheduler, }) {
|
|
@@ -91,24 +55,23 @@ class CompletionListener {
|
|
|
91
55
|
// The abort signal must happen before commands are killed, otherwise new commands
|
|
92
56
|
// might spawn. Because of this, it's not be possible to capture the close events
|
|
93
57
|
// without an immediate delay
|
|
94
|
-
|
|
58
|
+
delay(0, this.scheduler), map(() => undefined),
|
|
95
59
|
// #502 - node might warn of too many active listeners on this object if it isn't shared,
|
|
96
60
|
// as each command subscribes to abort event over and over
|
|
97
|
-
|
|
61
|
+
share());
|
|
98
62
|
const closeStreams = commands.map((command) => abort
|
|
99
63
|
? // Commands that have been started must close.
|
|
100
|
-
Rx.race(command.close, abort.pipe(
|
|
64
|
+
Rx.race(command.close, abort.pipe(filter(() => command.state === 'stopped')))
|
|
101
65
|
: command.close);
|
|
102
|
-
return Rx.lastValueFrom(Rx.combineLatest(closeStreams).pipe(
|
|
66
|
+
return Rx.lastValueFrom(Rx.combineLatest(closeStreams).pipe(filter(() => commands.every((command) => command.state !== 'started')), map((events) => events
|
|
103
67
|
// Filter out aborts, since they cannot be sorted and are considered success condition anyways
|
|
104
68
|
.filter((event) => event != null)
|
|
105
69
|
// Sort according to exit time
|
|
106
|
-
.sort((first, second) => first.timings.endDate.getTime() - second.timings.endDate.getTime())),
|
|
70
|
+
.sort((first, second) => first.timings.endDate.getTime() - second.timings.endDate.getTime())), switchMap((events) => this.isSuccess(events)
|
|
107
71
|
? this.emitWithScheduler(Rx.of(events))
|
|
108
|
-
: this.emitWithScheduler(Rx.throwError(() => events))),
|
|
72
|
+
: this.emitWithScheduler(Rx.throwError(() => events))), take(1)));
|
|
109
73
|
}
|
|
110
74
|
emitWithScheduler(input) {
|
|
111
75
|
return this.scheduler ? input.pipe(Rx.observeOn(this.scheduler)) : input;
|
|
112
76
|
}
|
|
113
77
|
}
|
|
114
|
-
exports.CompletionListener = CompletionListener;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Writable } from 'stream';
|
|
2
|
-
import { CloseEvent, Command, CommandIdentifier, CommandInfo, KillProcess, SpawnCommand } from './command';
|
|
3
|
-
import { SuccessCondition } from './completion-listener';
|
|
4
|
-
import { FlowController } from './flow-control/flow-controller';
|
|
5
|
-
import { Logger } from './logger';
|
|
1
|
+
import { Writable } from 'node:stream';
|
|
2
|
+
import { CloseEvent, Command, CommandIdentifier, CommandInfo, KillProcess, SpawnCommand } from './command.js';
|
|
3
|
+
import { SuccessCondition } from './completion-listener.js';
|
|
4
|
+
import { FlowController } from './flow-control/flow-controller.js';
|
|
5
|
+
import { Logger } from './logger.js';
|
|
6
6
|
/**
|
|
7
7
|
* A command that is to be passed into `concurrently()`.
|
|
8
8
|
* If value is a string, then that's the command's command line.
|
|
@@ -11,7 +11,7 @@ import { Logger } from './logger';
|
|
|
11
11
|
export type ConcurrentlyCommandInput = string | ({
|
|
12
12
|
command: string;
|
|
13
13
|
} & Partial<CommandInfo>);
|
|
14
|
-
export
|
|
14
|
+
export interface ConcurrentlyResult {
|
|
15
15
|
/**
|
|
16
16
|
* All commands created and ran by concurrently.
|
|
17
17
|
*/
|
|
@@ -24,8 +24,8 @@ export type ConcurrentlyResult = {
|
|
|
24
24
|
* spawned; commands that didn't spawn are filtered out.
|
|
25
25
|
*/
|
|
26
26
|
result: Promise<CloseEvent[]>;
|
|
27
|
-
}
|
|
28
|
-
export
|
|
27
|
+
}
|
|
28
|
+
export interface ConcurrentlyOptions {
|
|
29
29
|
logger?: Logger;
|
|
30
30
|
/**
|
|
31
31
|
* Which stream should the commands output be written to.
|
|
@@ -36,7 +36,7 @@ export type ConcurrentlyOptions = {
|
|
|
36
36
|
*/
|
|
37
37
|
group?: boolean;
|
|
38
38
|
/**
|
|
39
|
-
* A comma-separated list of
|
|
39
|
+
* A comma-separated list of Chalk colors or a string for available styles listed below to use on prefixes.
|
|
40
40
|
* If there are more commands than colors, the last color will be repeated.
|
|
41
41
|
*
|
|
42
42
|
* Available modifiers:
|
|
@@ -106,7 +106,7 @@ export type ConcurrentlyOptions = {
|
|
|
106
106
|
* @see ExpandArguments
|
|
107
107
|
*/
|
|
108
108
|
additionalArguments?: string[];
|
|
109
|
-
}
|
|
109
|
+
}
|
|
110
110
|
/**
|
|
111
111
|
* Core concurrently functionality -- spawns the given commands concurrently and
|
|
112
112
|
* returns the commands themselves + the result according to the specified success condition.
|
|
@@ -1,26 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const expand_wildcard_1 = require("./command-parser/expand-wildcard");
|
|
15
|
-
const strip_quotes_1 = require("./command-parser/strip-quotes");
|
|
16
|
-
const completion_listener_1 = require("./completion-listener");
|
|
17
|
-
const output_writer_1 = require("./output-writer");
|
|
18
|
-
const prefix_color_selector_1 = require("./prefix-color-selector");
|
|
19
|
-
const spawn_1 = require("./spawn");
|
|
20
|
-
const utils_1 = require("./utils");
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import { takeUntil } from 'rxjs';
|
|
4
|
+
import treeKill from 'tree-kill';
|
|
5
|
+
import { Command, } from './command.js';
|
|
6
|
+
import { ExpandArguments } from './command-parser/expand-arguments.js';
|
|
7
|
+
import { ExpandShortcut } from './command-parser/expand-shortcut.js';
|
|
8
|
+
import { ExpandWildcard } from './command-parser/expand-wildcard.js';
|
|
9
|
+
import { CompletionListener } from './completion-listener.js';
|
|
10
|
+
import { OutputWriter } from './output-writer.js';
|
|
11
|
+
import { PrefixColorSelector } from './prefix-color-selector.js';
|
|
12
|
+
import { createSpawn, getSpawnOpts } from './spawn.js';
|
|
13
|
+
import { castArray } from './utils.js';
|
|
21
14
|
const defaults = {
|
|
22
|
-
spawn:
|
|
23
|
-
kill:
|
|
15
|
+
spawn: createSpawn(),
|
|
16
|
+
kill: treeKill,
|
|
24
17
|
raw: false,
|
|
25
18
|
controllers: [],
|
|
26
19
|
cwd: undefined,
|
|
@@ -31,18 +24,14 @@ const defaults = {
|
|
|
31
24
|
*
|
|
32
25
|
* @see CompletionListener
|
|
33
26
|
*/
|
|
34
|
-
function concurrently(baseCommands, baseOptions) {
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
export function concurrently(baseCommands, baseOptions) {
|
|
28
|
+
assert.ok(Array.isArray(baseCommands), '[concurrently] commands should be an array');
|
|
29
|
+
assert.notStrictEqual(baseCommands.length, 0, '[concurrently] no commands provided');
|
|
37
30
|
const options = { ...defaults, ...baseOptions };
|
|
38
|
-
const prefixColorSelector = new
|
|
39
|
-
const commandParsers = [
|
|
40
|
-
new strip_quotes_1.StripQuotes(),
|
|
41
|
-
new expand_shortcut_1.ExpandShortcut(),
|
|
42
|
-
new expand_wildcard_1.ExpandWildcard(),
|
|
43
|
-
];
|
|
31
|
+
const prefixColorSelector = new PrefixColorSelector(options.prefixColors || []);
|
|
32
|
+
const commandParsers = [new ExpandShortcut(), new ExpandWildcard()];
|
|
44
33
|
if (options.additionalArguments) {
|
|
45
|
-
commandParsers.push(new
|
|
34
|
+
commandParsers.push(new ExpandArguments(options.additionalArguments));
|
|
46
35
|
}
|
|
47
36
|
const hide = (options.hide || []).map(String);
|
|
48
37
|
let commands = baseCommands
|
|
@@ -50,11 +39,11 @@ function concurrently(baseCommands, baseOptions) {
|
|
|
50
39
|
.flatMap((command) => parseCommand(command, commandParsers))
|
|
51
40
|
.map((command, index) => {
|
|
52
41
|
const hidden = hide.includes(command.name) || hide.includes(String(index));
|
|
53
|
-
return new
|
|
42
|
+
return new Command({
|
|
54
43
|
index,
|
|
55
44
|
prefixColor: prefixColorSelector.getNextColor(),
|
|
56
45
|
...command,
|
|
57
|
-
},
|
|
46
|
+
}, getSpawnOpts({
|
|
58
47
|
ipc: command.ipc,
|
|
59
48
|
stdio: hidden ? 'hidden' : (command.raw ?? options.raw) ? 'raw' : 'normal',
|
|
60
49
|
env: command.env,
|
|
@@ -70,24 +59,24 @@ function concurrently(baseCommands, baseOptions) {
|
|
|
70
59
|
}, { commands, onFinishCallbacks: [] });
|
|
71
60
|
commands = handleResult.commands;
|
|
72
61
|
if (options.logger && options.outputStream) {
|
|
73
|
-
const outputWriter = new
|
|
62
|
+
const outputWriter = new OutputWriter({
|
|
74
63
|
outputStream: options.outputStream,
|
|
75
64
|
group: !!options.group,
|
|
76
65
|
commands,
|
|
77
66
|
});
|
|
78
67
|
options.logger.output
|
|
79
68
|
// Stop trying to write after there's been an error.
|
|
80
|
-
.pipe(
|
|
69
|
+
.pipe(takeUntil(outputWriter.error))
|
|
81
70
|
.subscribe(({ command, text }) => outputWriter.write(command, text));
|
|
82
71
|
}
|
|
83
72
|
const commandsLeft = commands.slice();
|
|
84
73
|
const maxProcesses = Math.max(1, (typeof options.maxProcesses === 'string' && options.maxProcesses.endsWith('%')
|
|
85
|
-
? Math.round((
|
|
74
|
+
? Math.round((os.cpus().length * Number(options.maxProcesses.slice(0, -1))) / 100)
|
|
86
75
|
: Number(options.maxProcesses)) || commandsLeft.length);
|
|
87
76
|
for (let i = 0; i < maxProcesses; i++) {
|
|
88
77
|
maybeRunMore(commandsLeft, options.abortSignal);
|
|
89
78
|
}
|
|
90
|
-
const result = new
|
|
79
|
+
const result = new CompletionListener({ successCondition: options.successCondition })
|
|
91
80
|
.listen(commands, options.abortSignal)
|
|
92
81
|
.finally(() => Promise.all(handleResult.onFinishCallbacks.map((onFinish) => onFinish())));
|
|
93
82
|
return {
|
|
@@ -99,7 +88,7 @@ function mapToCommandInfo(command) {
|
|
|
99
88
|
if (typeof command === 'string') {
|
|
100
89
|
return mapToCommandInfo({ command });
|
|
101
90
|
}
|
|
102
|
-
|
|
91
|
+
assert.ok(command.command, '[concurrently] command cannot be empty');
|
|
103
92
|
return {
|
|
104
93
|
command: command.command,
|
|
105
94
|
name: command.name || '',
|
|
@@ -119,7 +108,7 @@ function mapToCommandInfo(command) {
|
|
|
119
108
|
};
|
|
120
109
|
}
|
|
121
110
|
function parseCommand(command, parsers) {
|
|
122
|
-
return parsers.reduce((commands, parser) => commands.flatMap((command) => parser.parse(command)),
|
|
111
|
+
return parsers.reduce((commands, parser) => commands.flatMap((command) => parser.parse(command)), castArray(command));
|
|
123
112
|
}
|
|
124
113
|
function maybeRunMore(commandsLeft, abortSignal) {
|
|
125
114
|
const command = commandsLeft.shift();
|
|
@@ -1,76 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DateFormatter = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Unicode-compliant date/time formatter.
|
|
6
|
-
*
|
|
7
|
-
* @see https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
|
|
8
|
-
*/
|
|
9
|
-
class DateFormatter {
|
|
10
|
-
options;
|
|
11
|
-
static tokenRegex = /[A-Z]/i;
|
|
12
|
-
parts = [];
|
|
13
|
-
constructor(pattern, options = {}) {
|
|
14
|
-
this.options = options;
|
|
15
|
-
let i = 0;
|
|
16
|
-
while (i < pattern.length) {
|
|
17
|
-
const char = pattern[i];
|
|
18
|
-
const { fn, length } = char === "'"
|
|
19
|
-
? this.compileLiteral(pattern, i)
|
|
20
|
-
: DateFormatter.tokenRegex.test(char)
|
|
21
|
-
? this.compileToken(pattern, i)
|
|
22
|
-
: this.compileOther(pattern, i);
|
|
23
|
-
this.parts.push(fn);
|
|
24
|
-
i += length;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
compileLiteral(pattern, offset) {
|
|
28
|
-
let length = 1;
|
|
29
|
-
let value = '';
|
|
30
|
-
for (; length < pattern.length; length++) {
|
|
31
|
-
const i = offset + length;
|
|
32
|
-
const char = pattern[i];
|
|
33
|
-
if (char === "'") {
|
|
34
|
-
const nextChar = pattern[i + 1];
|
|
35
|
-
length++;
|
|
36
|
-
// if the next character is another single quote, it's been escaped.
|
|
37
|
-
// if not, then the literal has been closed
|
|
38
|
-
if (nextChar !== "'") {
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
value += char;
|
|
43
|
-
}
|
|
44
|
-
return { fn: () => value || "'", length };
|
|
45
|
-
}
|
|
46
|
-
compileOther(pattern, offset) {
|
|
47
|
-
let value = '';
|
|
48
|
-
while (!DateFormatter.tokenRegex.test(pattern[offset]) && pattern[offset] !== "'") {
|
|
49
|
-
value += pattern[offset++];
|
|
50
|
-
}
|
|
51
|
-
return { fn: () => value, length: value.length };
|
|
52
|
-
}
|
|
53
|
-
compileToken(pattern, offset) {
|
|
54
|
-
const type = pattern[offset];
|
|
55
|
-
const token = tokens.get(type);
|
|
56
|
-
if (!token) {
|
|
57
|
-
throw new SyntaxError(`Formatting token "${type}" is invalid`);
|
|
58
|
-
}
|
|
59
|
-
let length = 0;
|
|
60
|
-
while (pattern[offset + length] === type) {
|
|
61
|
-
length++;
|
|
62
|
-
}
|
|
63
|
-
const tokenFn = token[length - 1];
|
|
64
|
-
if (!tokenFn) {
|
|
65
|
-
throw new RangeError(`Formatting token "${type.repeat(length)}" is unsupported`);
|
|
66
|
-
}
|
|
67
|
-
return { fn: tokenFn, length };
|
|
68
|
-
}
|
|
69
|
-
format(date) {
|
|
70
|
-
return this.parts.reduce((output, part) => output + String(part(date, this.options)), '');
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
exports.DateFormatter = DateFormatter;
|
|
74
1
|
/**
|
|
75
2
|
* A map of token to its implementations by length.
|
|
76
3
|
* If an index is undefined, then that token length is unsupported.
|
|
@@ -241,6 +168,99 @@ function getLocale(options) {
|
|
|
241
168
|
}
|
|
242
169
|
return locale;
|
|
243
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Unicode-compliant date/time formatter.
|
|
173
|
+
*
|
|
174
|
+
* @see https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
|
|
175
|
+
*/
|
|
176
|
+
export class DateFormatter {
|
|
177
|
+
options;
|
|
178
|
+
static tokenRegex = /[A-Z]/i;
|
|
179
|
+
parts = [];
|
|
180
|
+
constructor(pattern, options = {}) {
|
|
181
|
+
this.options = options;
|
|
182
|
+
let i = 0;
|
|
183
|
+
while (i < pattern.length) {
|
|
184
|
+
const char = pattern[i];
|
|
185
|
+
const { fn, length } = char === "'"
|
|
186
|
+
? this.compileLiteral(pattern, i)
|
|
187
|
+
: DateFormatter.tokenRegex.test(char)
|
|
188
|
+
? this.compileToken(pattern, i)
|
|
189
|
+
: this.compileOther(pattern, i);
|
|
190
|
+
this.parts.push(fn);
|
|
191
|
+
i += length;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
compileLiteral(pattern, offset) {
|
|
195
|
+
let length = 1;
|
|
196
|
+
let value = '';
|
|
197
|
+
for (; length < pattern.length; length++) {
|
|
198
|
+
const i = offset + length;
|
|
199
|
+
const char = pattern[i];
|
|
200
|
+
if (char === "'") {
|
|
201
|
+
const nextChar = pattern[i + 1];
|
|
202
|
+
length++;
|
|
203
|
+
// if the next character is another single quote, it's been escaped.
|
|
204
|
+
// if not, then the literal has been closed
|
|
205
|
+
if (nextChar !== "'") {
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
value += char;
|
|
210
|
+
}
|
|
211
|
+
return { fn: () => value || "'", length };
|
|
212
|
+
}
|
|
213
|
+
compileOther(pattern, offset) {
|
|
214
|
+
let value = '';
|
|
215
|
+
while (!DateFormatter.tokenRegex.test(pattern[offset]) && pattern[offset] !== "'") {
|
|
216
|
+
value += pattern[offset++];
|
|
217
|
+
}
|
|
218
|
+
return { fn: () => value, length: value.length };
|
|
219
|
+
}
|
|
220
|
+
compileToken(pattern, offset) {
|
|
221
|
+
const type = pattern[offset];
|
|
222
|
+
const token = tokens.get(type);
|
|
223
|
+
if (!token) {
|
|
224
|
+
throw new SyntaxError(`Formatting token "${type}" is invalid`);
|
|
225
|
+
}
|
|
226
|
+
let length = 0;
|
|
227
|
+
while (pattern[offset + length] === type) {
|
|
228
|
+
length++;
|
|
229
|
+
}
|
|
230
|
+
const tokenFn = token[length - 1];
|
|
231
|
+
if (!tokenFn) {
|
|
232
|
+
throw new RangeError(`Formatting token "${type.repeat(length)}" is unsupported`);
|
|
233
|
+
}
|
|
234
|
+
return { fn: tokenFn, length };
|
|
235
|
+
}
|
|
236
|
+
format(date) {
|
|
237
|
+
return this.parts.reduce((output, part) => output + String(part(date, this.options)), '');
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* See https://github.com/moment/luxon/issues/1693
|
|
242
|
+
*
|
|
243
|
+
* @todo Replace once there's a suitable alternative implementation
|
|
244
|
+
*/
|
|
245
|
+
const fallbackWeekInfo = {
|
|
246
|
+
minimalDays: 4,
|
|
247
|
+
};
|
|
248
|
+
const weekInfoCache = new Map();
|
|
249
|
+
function getWeekInfo(locale) {
|
|
250
|
+
let data = weekInfoCache.get(locale.baseName);
|
|
251
|
+
if (!data) {
|
|
252
|
+
// The specs now envisage a method for this,
|
|
253
|
+
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/getWeekInfo
|
|
254
|
+
data = locale.getWeekInfo?.() ?? locale.weekInfo;
|
|
255
|
+
// The specs have dropped minimalDays,
|
|
256
|
+
// see https://github.com/tc39/proposal-intl-locale-info/issues/86
|
|
257
|
+
if (!data.minimalDays) {
|
|
258
|
+
data = { ...fallbackWeekInfo, ...data };
|
|
259
|
+
}
|
|
260
|
+
weekInfoCache.set(locale.baseName, data);
|
|
261
|
+
}
|
|
262
|
+
return data;
|
|
263
|
+
}
|
|
244
264
|
/**
|
|
245
265
|
* Creates a token formatting function that returns the value of the chosen part type,
|
|
246
266
|
* using the current locale's settings.
|
|
@@ -269,7 +289,8 @@ function makeTokenFn(options, type, fallback) {
|
|
|
269
289
|
}
|
|
270
290
|
function startOfWeek(date, options) {
|
|
271
291
|
const locale = getLocale(options);
|
|
272
|
-
const
|
|
292
|
+
const weekInfo = getWeekInfo(locale);
|
|
293
|
+
const firstDay = weekInfo.firstDay === 7 ? 0 : weekInfo.firstDay;
|
|
273
294
|
const day = date.getDay();
|
|
274
295
|
const diff = (day < firstDay ? 7 : 0) + day - firstDay;
|
|
275
296
|
date.setDate(date.getDate() - diff);
|
|
@@ -278,7 +299,7 @@ function startOfWeek(date, options) {
|
|
|
278
299
|
}
|
|
279
300
|
function getWeekYear(date, options) {
|
|
280
301
|
const locale = getLocale(options);
|
|
281
|
-
const minimalDays = locale.
|
|
302
|
+
const minimalDays = getWeekInfo(locale).minimalDays;
|
|
282
303
|
const year = date.getFullYear();
|
|
283
304
|
const thisYear = startOfWeek(new Date(year, 0, minimalDays), options);
|
|
284
305
|
const nextYear = startOfWeek(new Date(year + 1, 0, minimalDays), options);
|
|
@@ -296,7 +317,7 @@ function getWeek(date, options) {
|
|
|
296
317
|
const locale = getLocale(options);
|
|
297
318
|
const weekMs = 7 * 24 * 3600 * 1000;
|
|
298
319
|
const temp = startOfWeek(new Date(date), options);
|
|
299
|
-
const thisYear = new Date(getWeekYear(date, options), 0, locale.
|
|
320
|
+
const thisYear = new Date(getWeekYear(date, options), 0, getWeekInfo(locale).minimalDays);
|
|
300
321
|
startOfWeek(thisYear, options);
|
|
301
322
|
const diff = temp.getTime() - thisYear.getTime();
|
|
302
323
|
return Math.round(diff / weekMs) + 1;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SuccessCondition } from './completion-listener';
|
|
1
|
+
import { SuccessCondition } from './completion-listener.js';
|
|
2
2
|
export declare const defaultInputTarget = 0;
|
|
3
3
|
/**
|
|
4
4
|
* Whether process.stdin should be forwarded to child processes.
|
|
@@ -12,10 +12,6 @@ export declare const maxProcesses = 0;
|
|
|
12
12
|
* Indices and names of commands whose output are not to be logged.
|
|
13
13
|
*/
|
|
14
14
|
export declare const hide = "";
|
|
15
|
-
/**
|
|
16
|
-
* The character to split <names> on.
|
|
17
|
-
*/
|
|
18
|
-
export declare const nameSeparator = ",";
|
|
19
15
|
/**
|
|
20
16
|
* Which prefix style to use when logging processes output.
|
|
21
17
|
*/
|
|
@@ -24,7 +20,7 @@ export declare const prefix = "";
|
|
|
24
20
|
* Default prefix color.
|
|
25
21
|
* @see https://www.npmjs.com/package/chalk
|
|
26
22
|
*/
|
|
27
|
-
export declare const prefixColors = "
|
|
23
|
+
export declare const prefixColors = "auto";
|
|
28
24
|
/**
|
|
29
25
|
* How many bytes we'll show on the command prefix.
|
|
30
26
|
*/
|
|
@@ -1,73 +1,66 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// This file is meant to be a shared place for default configs.
|
|
3
2
|
// It's read by the flow controllers, the executable, etc.
|
|
4
3
|
// Refer to tests for the meaning of the different possible values.
|
|
5
|
-
|
|
6
|
-
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;
|
|
7
|
-
exports.defaultInputTarget = 0;
|
|
4
|
+
export const defaultInputTarget = 0;
|
|
8
5
|
/**
|
|
9
6
|
* Whether process.stdin should be forwarded to child processes.
|
|
10
7
|
*/
|
|
11
|
-
|
|
8
|
+
export const handleInput = false;
|
|
12
9
|
/**
|
|
13
10
|
* How many processes to run at once.
|
|
14
11
|
*/
|
|
15
|
-
|
|
12
|
+
export const maxProcesses = 0;
|
|
16
13
|
/**
|
|
17
14
|
* Indices and names of commands whose output are not to be logged.
|
|
18
15
|
*/
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The character to split <names> on.
|
|
22
|
-
*/
|
|
23
|
-
exports.nameSeparator = ',';
|
|
16
|
+
export const hide = '';
|
|
24
17
|
/**
|
|
25
18
|
* Which prefix style to use when logging processes output.
|
|
26
19
|
*/
|
|
27
|
-
|
|
20
|
+
export const prefix = '';
|
|
28
21
|
/**
|
|
29
22
|
* Default prefix color.
|
|
30
23
|
* @see https://www.npmjs.com/package/chalk
|
|
31
24
|
*/
|
|
32
|
-
|
|
25
|
+
export const prefixColors = 'auto';
|
|
33
26
|
/**
|
|
34
27
|
* How many bytes we'll show on the command prefix.
|
|
35
28
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
export const prefixLength = 10;
|
|
30
|
+
export const raw = false;
|
|
38
31
|
/**
|
|
39
32
|
* Number of attempts of restarting a process, if it exits with non-0 code.
|
|
40
33
|
*/
|
|
41
|
-
|
|
34
|
+
export const restartTries = 0;
|
|
42
35
|
/**
|
|
43
36
|
* How many milliseconds concurrently should wait before restarting a process.
|
|
44
37
|
*/
|
|
45
|
-
|
|
38
|
+
export const restartDelay = 0;
|
|
46
39
|
/**
|
|
47
40
|
* Condition of success for concurrently itself.
|
|
48
41
|
*/
|
|
49
|
-
|
|
42
|
+
export const success = 'all';
|
|
50
43
|
/**
|
|
51
44
|
* Date format used when logging date/time.
|
|
52
45
|
* @see https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
|
|
53
46
|
*/
|
|
54
|
-
|
|
47
|
+
export const timestampFormat = 'yyyy-MM-dd HH:mm:ss.SSS';
|
|
55
48
|
/**
|
|
56
49
|
* Current working dir passed as option to spawn command.
|
|
57
50
|
* Defaults to process.cwd()
|
|
58
51
|
*/
|
|
59
|
-
|
|
52
|
+
export const cwd = undefined;
|
|
60
53
|
/**
|
|
61
54
|
* Whether to show timing information for processes in console output.
|
|
62
55
|
*/
|
|
63
|
-
|
|
56
|
+
export const timings = false;
|
|
64
57
|
/**
|
|
65
58
|
* Passthrough additional arguments to commands (accessible via placeholders) instead of treating them as commands.
|
|
66
59
|
*/
|
|
67
|
-
|
|
60
|
+
export const passthroughArguments = false;
|
|
68
61
|
/**
|
|
69
62
|
* Signal to send to other processes if one exits or dies.
|
|
70
63
|
*
|
|
71
64
|
* Defaults to OS specific signal. (SIGTERM on Linux/MacOS)
|
|
72
65
|
*/
|
|
73
|
-
|
|
66
|
+
export const killSignal = undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Readable } from 'stream';
|
|
2
|
-
import { Command, CommandIdentifier } from '../command';
|
|
3
|
-
import { Logger } from '../logger';
|
|
4
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import { Command, CommandIdentifier } from '../command.js';
|
|
3
|
+
import { Logger } from '../logger.js';
|
|
4
|
+
import { FlowController } from './flow-controller.js';
|
|
5
5
|
/**
|
|
6
6
|
* Sends input from concurrently through to commands.
|
|
7
7
|
*
|