concurrently 10.0.0 → 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.
Files changed (63) hide show
  1. package/dist/lib/flow-control/flow-controller.d.ts +13 -0
  2. package/dist/tsconfig.tsbuildinfo +1 -1
  3. package/package.json +11 -14
  4. package/dist/bin/index.spec.js +0 -368
  5. package/dist/bin/normalize-cli-command.spec.js +0 -36
  6. package/dist/lib/__fixtures__/create-mock-instance.d.ts +0 -2
  7. package/dist/lib/__fixtures__/create-mock-instance.js +0 -5
  8. package/dist/lib/__fixtures__/fake-command.d.ts +0 -6
  9. package/dist/lib/__fixtures__/fake-command.js +0 -37
  10. package/dist/lib/assert.spec.js +0 -41
  11. package/dist/lib/command-parser/expand-arguments.spec.d.ts +0 -1
  12. package/dist/lib/command-parser/expand-arguments.spec.js +0 -57
  13. package/dist/lib/command-parser/expand-shortcut.spec.d.ts +0 -1
  14. package/dist/lib/command-parser/expand-shortcut.spec.js +0 -36
  15. package/dist/lib/command-parser/expand-wildcard.spec.d.ts +0 -1
  16. package/dist/lib/command-parser/expand-wildcard.spec.js +0 -288
  17. package/dist/lib/command.spec.d.ts +0 -1
  18. package/dist/lib/command.spec.js +0 -369
  19. package/dist/lib/completion-listener.spec.d.ts +0 -1
  20. package/dist/lib/completion-listener.spec.js +0 -229
  21. package/dist/lib/concurrently.spec.d.ts +0 -1
  22. package/dist/lib/concurrently.spec.js +0 -320
  23. package/dist/lib/date-format.spec.d.ts +0 -1
  24. package/dist/lib/date-format.spec.js +0 -480
  25. package/dist/lib/flow-control/input-handler.spec.d.ts +0 -1
  26. package/dist/lib/flow-control/input-handler.spec.js +0 -116
  27. package/dist/lib/flow-control/kill-on-signal.spec.d.ts +0 -1
  28. package/dist/lib/flow-control/kill-on-signal.spec.js +0 -63
  29. package/dist/lib/flow-control/kill-others.spec.d.ts +0 -1
  30. package/dist/lib/flow-control/kill-others.spec.js +0 -98
  31. package/dist/lib/flow-control/log-error.spec.d.ts +0 -1
  32. package/dist/lib/flow-control/log-error.spec.js +0 -33
  33. package/dist/lib/flow-control/log-exit.spec.d.ts +0 -1
  34. package/dist/lib/flow-control/log-exit.spec.js +0 -24
  35. package/dist/lib/flow-control/log-output.spec.d.ts +0 -1
  36. package/dist/lib/flow-control/log-output.spec.js +0 -33
  37. package/dist/lib/flow-control/log-timings.spec.d.ts +0 -1
  38. package/dist/lib/flow-control/log-timings.spec.js +0 -89
  39. package/dist/lib/flow-control/logger-padding.spec.d.ts +0 -1
  40. package/dist/lib/flow-control/logger-padding.spec.js +0 -60
  41. package/dist/lib/flow-control/output-error-handler.spec.d.ts +0 -1
  42. package/dist/lib/flow-control/output-error-handler.spec.js +0 -41
  43. package/dist/lib/flow-control/restart-process.spec.d.ts +0 -1
  44. package/dist/lib/flow-control/restart-process.spec.js +0 -127
  45. package/dist/lib/flow-control/teardown.spec.d.ts +0 -1
  46. package/dist/lib/flow-control/teardown.spec.js +0 -93
  47. package/dist/lib/jsonc.spec.d.ts +0 -1
  48. package/dist/lib/jsonc.spec.js +0 -73
  49. package/dist/lib/logger.spec.d.ts +0 -1
  50. package/dist/lib/logger.spec.js +0 -507
  51. package/dist/lib/observables.spec.d.ts +0 -1
  52. package/dist/lib/observables.spec.js +0 -29
  53. package/dist/lib/output-writer.spec.d.ts +0 -1
  54. package/dist/lib/output-writer.spec.js +0 -96
  55. package/dist/lib/prefix-color-selector.spec.d.ts +0 -1
  56. package/dist/lib/prefix-color-selector.spec.js +0 -159
  57. package/dist/lib/spawn.spec.d.ts +0 -1
  58. package/dist/lib/spawn.spec.js +0 -100
  59. package/dist/lib/utils.spec.d.ts +0 -1
  60. package/dist/lib/utils.spec.js +0 -58
  61. /package/dist/bin/{index.spec.d.ts → bin-options.d.ts} +0 -0
  62. /package/dist/bin/{normalize-cli-command.spec.d.ts → bin-options.js} +0 -0
  63. /package/dist/lib/{assert.spec.d.ts → flow-control/flow-controller.js} +0 -0
@@ -1,96 +0,0 @@
1
- import { Writable } from 'node:stream';
2
- import { beforeEach, describe, expect, it } from 'vitest';
3
- import { createMockInstance } from './__fixtures__/create-mock-instance.js';
4
- import { createFakeCloseEvent, FakeCommand } from './__fixtures__/fake-command.js';
5
- import { OutputWriter } from './output-writer.js';
6
- let outputStream;
7
- let commands;
8
- function createWriter(overrides) {
9
- const options = {
10
- outputStream,
11
- group: false,
12
- commands,
13
- ...overrides,
14
- };
15
- return new OutputWriter(options);
16
- }
17
- function closeCommand(command) {
18
- command.state = 'exited';
19
- command.close.next(createFakeCloseEvent({ command, index: command.index }));
20
- }
21
- beforeEach(() => {
22
- outputStream = createMockInstance(Writable);
23
- commands = [
24
- new FakeCommand('', undefined, 0),
25
- new FakeCommand('', undefined, 1),
26
- new FakeCommand('', undefined, 2),
27
- ];
28
- });
29
- it('throws if outputStream already is in errored state', () => {
30
- Object.defineProperty(outputStream, 'errored', { value: new Error('test') });
31
- expect(() => createWriter()).toThrow(TypeError);
32
- });
33
- describe('#write()', () => {
34
- it('throws if outputStream has errored', () => {
35
- const writer = createWriter();
36
- Object.defineProperty(outputStream, 'errored', { value: new Error('test') });
37
- expect(() => writer.write(commands[0], 'hello')).toThrow(TypeError);
38
- });
39
- describe('with group=false', () => {
40
- it('writes instantly', () => {
41
- const writer = createWriter({ group: false });
42
- writer.write(commands[2], 'hello');
43
- expect(outputStream.write).toHaveBeenCalledExactlyOnceWith('hello');
44
- });
45
- });
46
- describe('with group=true', () => {
47
- it('writes for null commands', () => {
48
- const writer = createWriter({ group: true });
49
- writer.write(undefined, 'hello');
50
- expect(outputStream.write).toHaveBeenCalledExactlyOnceWith('hello');
51
- });
52
- it('does not write instantly for non-active command', () => {
53
- const writer = createWriter({ group: true });
54
- writer.write(commands[2], 'hello');
55
- expect(outputStream.write).toHaveBeenCalledTimes(0);
56
- expect(writer.buffers[2]).toEqual(['hello']);
57
- });
58
- it('write instantly for active command', () => {
59
- const writer = createWriter({ group: true });
60
- writer.write(commands[0], 'hello');
61
- expect(outputStream.write).toHaveBeenCalledExactlyOnceWith('hello');
62
- });
63
- it('does not wait for write from next command to flush', () => {
64
- const writer = createWriter({ group: true });
65
- writer.write(commands[1], 'hello');
66
- writer.write(commands[1], 'foo bar');
67
- expect(outputStream.write).toHaveBeenCalledTimes(0);
68
- closeCommand(commands[0]);
69
- expect(outputStream.write).toHaveBeenCalledTimes(2);
70
- expect(writer.activeCommandIndex).toBe(1);
71
- outputStream.write.mockClear();
72
- writer.write(commands[1], 'blah');
73
- expect(outputStream.write).toHaveBeenCalledTimes(1);
74
- });
75
- it('does not flush for non-active command', () => {
76
- const writer = createWriter({ group: true });
77
- writer.write(commands[1], 'hello');
78
- writer.write(commands[1], 'foo bar');
79
- expect(outputStream.write).toHaveBeenCalledTimes(0);
80
- closeCommand(commands[1]);
81
- expect(outputStream.write).toHaveBeenCalledTimes(0);
82
- closeCommand(commands[0]);
83
- expect(outputStream.write).toHaveBeenCalledTimes(2);
84
- });
85
- it('flushes multiple commands at a time if necessary', () => {
86
- const writer = createWriter({ group: true });
87
- writer.write(commands[2], 'hello');
88
- closeCommand(commands[1]);
89
- closeCommand(commands[2]);
90
- expect(outputStream.write).toHaveBeenCalledTimes(0);
91
- closeCommand(commands[0]);
92
- expect(outputStream.write).toHaveBeenCalledExactlyOnceWith('hello');
93
- expect(writer.activeCommandIndex).toBe(2);
94
- });
95
- });
96
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,159 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import { PrefixColorSelector } from './prefix-color-selector.js';
3
- afterEach(() => {
4
- vi.restoreAllMocks();
5
- });
6
- describe('#getNextColor()', () => {
7
- const customTests = {
8
- 'does not produce a color if prefixColors empty': {
9
- customColors: [],
10
- expectedColors: ['', '', ''],
11
- },
12
- 'does not produce a color if prefixColors undefined': {
13
- expectedColors: ['', '', ''],
14
- },
15
- 'uses user defined prefix colors only, if no auto is used': {
16
- customColors: ['red', 'green', 'blue'],
17
- expectedColors: [
18
- 'red',
19
- 'green',
20
- 'blue',
21
- // Uses last color if last color is not "auto"
22
- 'blue',
23
- 'blue',
24
- 'blue',
25
- ],
26
- },
27
- 'trims colors': {
28
- customColors: [' red ', ' green ', ' blue '],
29
- expectedColors: ['red', 'green', 'blue'],
30
- },
31
- 'accepts a string value for customColors': {
32
- customColors: 'red',
33
- expectedColors: ['red', 'red'],
34
- },
35
- 'picks varying colors when user defines an auto color': {
36
- acceptableConsoleColors: ['green', 'blue'],
37
- customColors: [
38
- 'red',
39
- 'green',
40
- 'auto',
41
- 'green',
42
- 'auto',
43
- 'green',
44
- 'auto',
45
- 'blue',
46
- 'auto',
47
- 'orange',
48
- ],
49
- expectedColors: [
50
- // Custom colors
51
- 'red',
52
- 'green',
53
- 'blue', // Picks auto color "blue", not repeating consecutive "green" color
54
- 'green', // Manual
55
- 'blue', // Auto picks "blue" not to repeat last
56
- 'green', // Manual
57
- 'blue', // Auto picks "blue" again not to repeat last
58
- 'blue', // Manual
59
- 'green', // Auto picks "green" again not to repeat last
60
- 'orange',
61
- // Uses last color if last color is not "auto"
62
- 'orange',
63
- 'orange',
64
- 'orange',
65
- ],
66
- },
67
- 'uses user defined colors then recurring auto colors without repeating consecutive colors': {
68
- acceptableConsoleColors: ['green', 'blue'],
69
- customColors: ['red', 'green', 'auto'],
70
- expectedColors: [
71
- // Custom colors
72
- 'red',
73
- 'green',
74
- // Picks auto colors, not repeating consecutive "green" color
75
- 'blue',
76
- 'green',
77
- 'blue',
78
- 'green',
79
- ],
80
- },
81
- 'can sometimes produce consecutive colors': {
82
- acceptableConsoleColors: ['green', 'blue'],
83
- customColors: ['blue', 'auto'],
84
- expectedColors: [
85
- // Custom colors
86
- 'blue',
87
- // Picks auto colors
88
- 'green',
89
- // Does not repeat custom colors for initial auto colors, i.e. does not use "blue" again so soon
90
- 'green', // Consecutive color picked, however practically there would be a lot of colors that need to be set in a particular order for this to occur
91
- 'blue',
92
- 'green',
93
- 'blue',
94
- 'green',
95
- 'blue',
96
- ],
97
- },
98
- 'considers the Bright variants of colors equal to the normal colors to avoid similar colors': {
99
- acceptableConsoleColors: ['greenBright', 'blueBright', 'green', 'blue', 'magenta'],
100
- customColors: ['green', 'blue', 'auto'],
101
- expectedColors: [
102
- // Custom colors
103
- 'green',
104
- 'blue',
105
- // Picks auto colors, not repeating green and blue colors and variants initially
106
- 'magenta',
107
- // Picks auto colors
108
- 'greenBright',
109
- 'blueBright',
110
- 'green',
111
- 'blue',
112
- 'magenta',
113
- ],
114
- },
115
- };
116
- it.each(Object.entries(customTests))('%s', (_, { acceptableConsoleColors, customColors, expectedColors }) => {
117
- if (acceptableConsoleColors) {
118
- vi.spyOn(PrefixColorSelector, 'ACCEPTABLE_CONSOLE_COLORS', 'get').mockReturnValue(acceptableConsoleColors);
119
- }
120
- const prefixColorSelector = new PrefixColorSelector(customColors);
121
- const prefixColorSelectorValues = expectedColors.map(() => prefixColorSelector.getNextColor());
122
- expect(prefixColorSelectorValues).toEqual(expectedColors);
123
- });
124
- const autoTests = {
125
- 'does not repeat consecutive colors when last prefixColor is auto': false,
126
- 'handles when more individual auto prefixColors exist than acceptable console colors': true,
127
- };
128
- it.each(Object.entries(autoTests))('%s', (_, map) => {
129
- // Pick auto colors over 2 sets
130
- const expectedColors = [
131
- ...PrefixColorSelector.ACCEPTABLE_CONSOLE_COLORS,
132
- ...PrefixColorSelector.ACCEPTABLE_CONSOLE_COLORS,
133
- ];
134
- const prefixColorSelector = new PrefixColorSelector(map ? expectedColors.map(() => 'auto') : ['auto']);
135
- let previousColor = '';
136
- for (const expectedColor of expectedColors) {
137
- const actualSelectedColor = prefixColorSelector.getNextColor();
138
- expect(actualSelectedColor).not.toBe(previousColor); // No consecutive colors
139
- expect(actualSelectedColor).toBe(expectedColor); // Expected color
140
- previousColor = actualSelectedColor;
141
- }
142
- });
143
- });
144
- describe('#ACCEPTABLE_CONSOLE_COLORS', () => {
145
- it('has more than 1 auto color defined', () => {
146
- // (!) The current implementation is based on the assumption that 'ACCEPTABLE_CONSOLE_COLORS'
147
- // always has more than one entry, which is what we enforce via this test
148
- expect(PrefixColorSelector.ACCEPTABLE_CONSOLE_COLORS.length).toBeGreaterThan(1);
149
- });
150
- it('only includes colors that are visually distinct, semantically neutral, and lightweight', () => {
151
- expect(PrefixColorSelector.ACCEPTABLE_CONSOLE_COLORS).toEqual([
152
- 'cyan',
153
- 'magenta',
154
- 'green',
155
- 'yellow',
156
- 'blue',
157
- ]);
158
- });
159
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,100 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { createSpawn, getSpawnOpts } from './spawn.js';
3
- import { UnreachableError } from './utils.js';
4
- const baseProcess = {
5
- platform: 'win32',
6
- cwd: () => '',
7
- env: {},
8
- };
9
- describe('createSpawn()', () => {
10
- const command = 'echo banana';
11
- const makeShellArgs = (kind) => {
12
- switch (kind) {
13
- case 'cmd':
14
- return ['/s', '/c', `"${command}"`];
15
- case 'posix':
16
- return ['-c', command];
17
- case 'powershell':
18
- return ['-NoProfile', '-Command', command];
19
- default:
20
- throw new UnreachableError(kind);
21
- }
22
- };
23
- describe('when shell is not provided', () => {
24
- it('uses npm_config_script_shell when set', () => {
25
- const fakeSpawn = vi.fn();
26
- const spawn = createSpawn(undefined, fakeSpawn, {
27
- ...baseProcess,
28
- env: { npm_config_script_shell: 'C:\\Git\\bin\\bash.exe' },
29
- });
30
- spawn(command, {});
31
- expect(fakeSpawn).toHaveBeenCalledWith('C:\\Git\\bin\\bash.exe', ['-c', command], {});
32
- });
33
- it('creates spawn function that uses cmd.exe on Windows', () => {
34
- const fakeSpawn = vi.fn();
35
- const spawn = createSpawn(undefined, fakeSpawn, { ...baseProcess, platform: 'win32' });
36
- spawn(command, {});
37
- expect(fakeSpawn).toHaveBeenCalledWith('cmd.exe', ['/s', '/c', `"${command}"`], {
38
- windowsVerbatimArguments: true,
39
- });
40
- });
41
- it('creates spawn function that uses /bin/sh on non-Windows platforms', () => {
42
- const fakeSpawn = vi.fn();
43
- const spawn = createSpawn(undefined, fakeSpawn, { ...baseProcess, platform: 'linux' });
44
- spawn(command, {});
45
- expect(fakeSpawn).toHaveBeenCalledWith('/bin/sh', ['-c', command], expect.objectContaining({}));
46
- });
47
- });
48
- describe.each([
49
- { style: 'cmd', file: 'cmd.exe' },
50
- { style: 'posix', file: 'C:\\bash.exe' },
51
- { style: 'powershell', file: 'pwsh' },
52
- { style: 'posix', file: '/bin/sh' },
53
- { style: 'posix', file: '/bin/zsh' },
54
- ])('when shell is set to $file', ({ style, file }) => {
55
- it(`creates spawn function that uses ${file} as shell with ${style} style arguments`, () => {
56
- const fakeSpawn = vi.fn();
57
- const spawn = createSpawn(file, fakeSpawn, baseProcess);
58
- spawn(command, {});
59
- expect(fakeSpawn).toHaveBeenCalledWith(file, makeShellArgs(style), expect.objectContaining({}));
60
- });
61
- });
62
- });
63
- describe('getSpawnOpts()', () => {
64
- it('sets detached mode to false for Windows platform', () => {
65
- expect(getSpawnOpts({ process: baseProcess }).detached).toBe(false);
66
- });
67
- it('sets stdio to pipe when stdio mode is normal', () => {
68
- expect(getSpawnOpts({ stdio: 'normal' }).stdio).toEqual(['pipe', 'pipe', 'pipe']);
69
- });
70
- it('sets stdio to inherit when stdio mode is raw', () => {
71
- expect(getSpawnOpts({ stdio: 'raw' }).stdio).toEqual(['inherit', 'inherit', 'inherit']);
72
- });
73
- it('sets stdio to ignore stdout + stderr when stdio mode is hidden', () => {
74
- expect(getSpawnOpts({ stdio: 'hidden' }).stdio).toEqual(['pipe', 'ignore', 'ignore']);
75
- });
76
- it('sets an ipc channel at the specified descriptor index', () => {
77
- const opts = getSpawnOpts({ ipc: 3 });
78
- expect(opts.stdio?.[3]).toBe('ipc');
79
- });
80
- it('throws if the ipc channel is <= 2', () => {
81
- const fn = () => getSpawnOpts({ ipc: 0 });
82
- expect(fn).toThrow();
83
- });
84
- it('merges FORCE_COLOR into env vars if color supported', () => {
85
- const process = { ...baseProcess, env: { foo: 'bar' } };
86
- expect(getSpawnOpts({ process, colorSupport: false }).env).toEqual(process.env);
87
- expect(getSpawnOpts({ process, colorSupport: { level: 1 } }).env).toEqual({
88
- FORCE_COLOR: '1',
89
- foo: 'bar',
90
- });
91
- });
92
- it('sets default cwd to process.cwd()', () => {
93
- const process = { ...baseProcess, cwd: () => 'process-cwd' };
94
- expect(getSpawnOpts({ process }).cwd).toBe('process-cwd');
95
- });
96
- it('overrides default cwd', () => {
97
- const cwd = 'foobar';
98
- expect(getSpawnOpts({ cwd }).cwd).toBe(cwd);
99
- });
100
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,58 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { castArray, escapeRegExp, splitOutsideParens } from './utils.js';
3
- describe('#escapeRegExp()', () => {
4
- it('escapes all RegExp chars', () => {
5
- // eslint-disable-next-line no-useless-escape
6
- const result = escapeRegExp('\*?{}.(?<test>.)|[]');
7
- expect(result).toBe('\\*\\?\\{\\}\\.\\(\\?<test>\\.\\)\\|\\[\\]');
8
- });
9
- });
10
- describe('#castArray()', () => {
11
- it('returns empty array for nullish input values', () => {
12
- const result1 = castArray();
13
- const result2 = castArray(undefined);
14
- const result3 = castArray(null);
15
- expect(result1).toStrictEqual([]);
16
- expect(result2).toStrictEqual([]);
17
- expect(result3).toStrictEqual([]);
18
- });
19
- it('directly returns value if it is already of type array', () => {
20
- const value = ['example'];
21
- const result = castArray(value);
22
- expect(result).toBe(value);
23
- });
24
- describe('casts primitives to an array', () => {
25
- it.each([1, 'example', {}])('%s', (value) => {
26
- const result = castArray(value);
27
- expect(result).toStrictEqual([value]);
28
- });
29
- });
30
- });
31
- describe('#splitOutsideParens()', () => {
32
- it('splits on the given delimiter', () => {
33
- expect(splitOutsideParens('red,blue', ',')).toEqual(['red', 'blue']);
34
- });
35
- it('preserves delimiters inside parentheses', () => {
36
- expect(splitOutsideParens('red,rgb(255,0,0),blue', ',')).toEqual([
37
- 'red',
38
- 'rgb(255,0,0)',
39
- 'blue',
40
- ]);
41
- });
42
- it('splits chalk-style dotted color paths, preserving function calls', () => {
43
- expect(splitOutsideParens('black.bgHex(#533AFD).dim', '.')).toEqual([
44
- 'black',
45
- 'bgHex(#533AFD)',
46
- 'dim',
47
- ]);
48
- });
49
- it('trims whitespace around each segment', () => {
50
- expect(splitOutsideParens(' red , blue ', ',')).toEqual(['red', 'blue']);
51
- });
52
- it('drops empty segments', () => {
53
- expect(splitOutsideParens(',,red,,', ',')).toEqual(['red']);
54
- });
55
- it('returns an empty array for an empty input', () => {
56
- expect(splitOutsideParens('', ',')).toEqual([]);
57
- });
58
- });
File without changes