@karmaniverous/get-dotenv 4.5.0 → 4.5.2
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/dist/getdotenv.cli.mjs +496 -378
- package/dist/index.cjs +496 -378
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +496 -378
- package/package.json +16 -16
package/dist/index.mjs
CHANGED
|
@@ -5,8 +5,8 @@ import fs$v, { writeFileSync as writeFileSync$1, statSync as statSync$1, readFil
|
|
|
5
5
|
import process$3, { platform as platform$1, hrtime, execPath, execArgv } from 'node:process';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { StringDecoder } from 'node:string_decoder';
|
|
8
|
-
import tty from 'node:tty';
|
|
9
8
|
import { debuglog, stripVTControlCharacters, inspect, promisify as promisify$1, callbackify, aborted } from 'node:util';
|
|
9
|
+
import tty from 'node:tty';
|
|
10
10
|
import require$$0$3 from 'child_process';
|
|
11
11
|
import require$$0$2, { join } from 'path';
|
|
12
12
|
import require$$0$1 from 'fs';
|
|
@@ -4119,56 +4119,220 @@ const getSubprocessResult = ({stdout}) => {
|
|
|
4119
4119
|
throw new TypeError(`Unexpected "${typeof stdout}" stdout in template expression`);
|
|
4120
4120
|
};
|
|
4121
4121
|
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
const
|
|
4122
|
+
const isStandardStream = stream => STANDARD_STREAMS.includes(stream);
|
|
4123
|
+
const STANDARD_STREAMS = [process$3.stdin, process$3.stdout, process$3.stderr];
|
|
4124
|
+
const STANDARD_STREAMS_ALIASES = ['stdin', 'stdout', 'stderr'];
|
|
4125
|
+
const getStreamName = fdNumber => STANDARD_STREAMS_ALIASES[fdNumber] ?? `stdio[${fdNumber}]`;
|
|
4125
4126
|
|
|
4126
|
-
//
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
const
|
|
4127
|
+
// Some options can have different values for `stdout`/`stderr`/`fd3`.
|
|
4128
|
+
// This normalizes those to array of values.
|
|
4129
|
+
// For example, `{verbose: {stdout: 'none', stderr: 'full'}}` becomes `{verbose: ['none', 'none', 'full']}`
|
|
4130
|
+
const normalizeFdSpecificOptions = options => {
|
|
4131
|
+
const optionsCopy = {...options};
|
|
4130
4132
|
|
|
4131
|
-
const
|
|
4132
|
-
|
|
4133
|
+
for (const optionName of FD_SPECIFIC_OPTIONS) {
|
|
4134
|
+
optionsCopy[optionName] = normalizeFdSpecificOption(options, optionName);
|
|
4135
|
+
}
|
|
4136
|
+
|
|
4137
|
+
return optionsCopy;
|
|
4138
|
+
};
|
|
4139
|
+
|
|
4140
|
+
const normalizeFdSpecificOption = (options, optionName) => {
|
|
4141
|
+
const optionBaseArray = Array.from({length: getStdioLength(options) + 1});
|
|
4142
|
+
const optionArray = normalizeFdSpecificValue(options[optionName], optionBaseArray, optionName);
|
|
4143
|
+
return addDefaultValue$1(optionArray, optionName);
|
|
4144
|
+
};
|
|
4145
|
+
|
|
4146
|
+
const getStdioLength = ({stdio}) => Array.isArray(stdio)
|
|
4147
|
+
? Math.max(stdio.length, STANDARD_STREAMS_ALIASES.length)
|
|
4148
|
+
: STANDARD_STREAMS_ALIASES.length;
|
|
4149
|
+
|
|
4150
|
+
const normalizeFdSpecificValue = (optionValue, optionArray, optionName) => isPlainObject(optionValue)
|
|
4151
|
+
? normalizeOptionObject(optionValue, optionArray, optionName)
|
|
4152
|
+
: optionArray.fill(optionValue);
|
|
4153
|
+
|
|
4154
|
+
const normalizeOptionObject = (optionValue, optionArray, optionName) => {
|
|
4155
|
+
for (const fdName of Object.keys(optionValue).sort(compareFdName)) {
|
|
4156
|
+
for (const fdNumber of parseFdName(fdName, optionName, optionArray)) {
|
|
4157
|
+
optionArray[fdNumber] = optionValue[fdName];
|
|
4158
|
+
}
|
|
4159
|
+
}
|
|
4160
|
+
|
|
4161
|
+
return optionArray;
|
|
4162
|
+
};
|
|
4163
|
+
|
|
4164
|
+
// Ensure priority order when setting both `stdout`/`stderr`, `fd1`/`fd2`, and `all`
|
|
4165
|
+
const compareFdName = (fdNameA, fdNameB) => getFdNameOrder(fdNameA) < getFdNameOrder(fdNameB) ? 1 : -1;
|
|
4166
|
+
|
|
4167
|
+
const getFdNameOrder = fdName => {
|
|
4168
|
+
if (fdName === 'stdout' || fdName === 'stderr') {
|
|
4169
|
+
return 0;
|
|
4170
|
+
}
|
|
4171
|
+
|
|
4172
|
+
return fdName === 'all' ? 2 : 1;
|
|
4173
|
+
};
|
|
4174
|
+
|
|
4175
|
+
const parseFdName = (fdName, optionName, optionArray) => {
|
|
4176
|
+
if (fdName === 'ipc') {
|
|
4177
|
+
return [optionArray.length - 1];
|
|
4178
|
+
}
|
|
4179
|
+
|
|
4180
|
+
const fdNumber = parseFd(fdName);
|
|
4181
|
+
if (fdNumber === undefined || fdNumber === 0) {
|
|
4182
|
+
throw new TypeError(`"${optionName}.${fdName}" is invalid.
|
|
4183
|
+
It must be "${optionName}.stdout", "${optionName}.stderr", "${optionName}.all", "${optionName}.ipc", or "${optionName}.fd3", "${optionName}.fd4" (and so on).`);
|
|
4184
|
+
}
|
|
4185
|
+
|
|
4186
|
+
if (fdNumber >= optionArray.length) {
|
|
4187
|
+
throw new TypeError(`"${optionName}.${fdName}" is invalid: that file descriptor does not exist.
|
|
4188
|
+
Please set the "stdio" option to ensure that file descriptor exists.`);
|
|
4189
|
+
}
|
|
4190
|
+
|
|
4191
|
+
return fdNumber === 'all' ? [1, 2] : [fdNumber];
|
|
4192
|
+
};
|
|
4193
|
+
|
|
4194
|
+
// Use the same syntax for fd-specific options and the `from`/`to` options
|
|
4195
|
+
const parseFd = fdName => {
|
|
4196
|
+
if (fdName === 'all') {
|
|
4197
|
+
return fdName;
|
|
4198
|
+
}
|
|
4199
|
+
|
|
4200
|
+
if (STANDARD_STREAMS_ALIASES.includes(fdName)) {
|
|
4201
|
+
return STANDARD_STREAMS_ALIASES.indexOf(fdName);
|
|
4202
|
+
}
|
|
4203
|
+
|
|
4204
|
+
const regexpResult = FD_REGEXP.exec(fdName);
|
|
4205
|
+
if (regexpResult !== null) {
|
|
4206
|
+
return Number(regexpResult[1]);
|
|
4207
|
+
}
|
|
4208
|
+
};
|
|
4209
|
+
|
|
4210
|
+
const FD_REGEXP = /^fd(\d+)$/;
|
|
4211
|
+
|
|
4212
|
+
const addDefaultValue$1 = (optionArray, optionName) => optionArray.map(optionValue => optionValue === undefined
|
|
4213
|
+
? DEFAULT_OPTIONS[optionName]
|
|
4214
|
+
: optionValue);
|
|
4133
4215
|
|
|
4134
4216
|
// Default value for the `verbose` option
|
|
4135
4217
|
const verboseDefault = debuglog('execa').enabled ? 'full' : 'none';
|
|
4136
4218
|
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4219
|
+
const DEFAULT_OPTIONS = {
|
|
4220
|
+
lines: false,
|
|
4221
|
+
buffer: true,
|
|
4222
|
+
maxBuffer: 1000 * 1000 * 100,
|
|
4223
|
+
verbose: verboseDefault,
|
|
4224
|
+
stripFinalNewline: true,
|
|
4142
4225
|
};
|
|
4143
4226
|
|
|
4144
|
-
//
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
//
|
|
4148
|
-
|
|
4149
|
-
|
|
4227
|
+
// List of options which can have different values for `stdout`/`stderr`
|
|
4228
|
+
const FD_SPECIFIC_OPTIONS = ['lines', 'buffer', 'maxBuffer', 'verbose', 'stripFinalNewline'];
|
|
4229
|
+
|
|
4230
|
+
// Retrieve fd-specific option
|
|
4231
|
+
const getFdSpecificValue = (optionArray, fdNumber) => fdNumber === 'ipc'
|
|
4232
|
+
? optionArray.at(-1)
|
|
4233
|
+
: optionArray[fdNumber];
|
|
4150
4234
|
|
|
4151
4235
|
// The `verbose` option can have different values for `stdout`/`stderr`
|
|
4152
|
-
const isVerbose = verbose => verbose
|
|
4236
|
+
const isVerbose = ({verbose}, fdNumber) => getFdVerbose(verbose, fdNumber) !== 'none';
|
|
4153
4237
|
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
if (verboseItem === false) {
|
|
4157
|
-
throw new TypeError('The "verbose: false" option was renamed to "verbose: \'none\'".');
|
|
4158
|
-
}
|
|
4238
|
+
// Whether IPC and output and logged
|
|
4239
|
+
const isFullVerbose = ({verbose}, fdNumber) => !['none', 'short'].includes(getFdVerbose(verbose, fdNumber));
|
|
4159
4240
|
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4241
|
+
// The `verbose` option can be a function to customize logging
|
|
4242
|
+
const getVerboseFunction = ({verbose}, fdNumber) => {
|
|
4243
|
+
const fdVerbose = getFdVerbose(verbose, fdNumber);
|
|
4244
|
+
return isVerboseFunction(fdVerbose) ? fdVerbose : undefined;
|
|
4245
|
+
};
|
|
4163
4246
|
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4247
|
+
// When using `verbose: {stdout, stderr, fd3, ipc}`:
|
|
4248
|
+
// - `verbose.stdout|stderr|fd3` is used for 'output'
|
|
4249
|
+
// - `verbose.ipc` is only used for 'ipc'
|
|
4250
|
+
// - highest `verbose.*` value is used for 'command', 'error' and 'duration'
|
|
4251
|
+
const getFdVerbose = (verbose, fdNumber) => fdNumber === undefined
|
|
4252
|
+
? getFdGenericVerbose(verbose)
|
|
4253
|
+
: getFdSpecificValue(verbose, fdNumber);
|
|
4254
|
+
|
|
4255
|
+
// When using `verbose: {stdout, stderr, fd3, ipc}` and logging is not specific to a file descriptor.
|
|
4256
|
+
// We then use the highest `verbose.*` value, using the following order:
|
|
4257
|
+
// - function > 'full' > 'short' > 'none'
|
|
4258
|
+
// - if several functions are defined: stdout > stderr > fd3 > ipc
|
|
4259
|
+
const getFdGenericVerbose = verbose => verbose.find(fdVerbose => isVerboseFunction(fdVerbose))
|
|
4260
|
+
?? VERBOSE_VALUES.findLast(fdVerbose => verbose.includes(fdVerbose));
|
|
4261
|
+
|
|
4262
|
+
// Whether the `verbose` option is customized using a function
|
|
4263
|
+
const isVerboseFunction = fdVerbose => typeof fdVerbose === 'function';
|
|
4264
|
+
|
|
4265
|
+
const VERBOSE_VALUES = ['none', 'short', 'full'];
|
|
4266
|
+
|
|
4267
|
+
// Compute `result.command` and `result.escapedCommand`
|
|
4268
|
+
const joinCommand = (filePath, rawArguments) => {
|
|
4269
|
+
const fileAndArguments = [filePath, ...rawArguments];
|
|
4270
|
+
const command = fileAndArguments.join(' ');
|
|
4271
|
+
const escapedCommand = fileAndArguments
|
|
4272
|
+
.map(fileAndArgument => quoteString(escapeControlCharacters(fileAndArgument)))
|
|
4273
|
+
.join(' ');
|
|
4274
|
+
return {command, escapedCommand};
|
|
4275
|
+
};
|
|
4276
|
+
|
|
4277
|
+
// Remove ANSI sequences and escape control characters and newlines
|
|
4278
|
+
const escapeLines = lines => stripVTControlCharacters(lines)
|
|
4279
|
+
.split('\n')
|
|
4280
|
+
.map(line => escapeControlCharacters(line))
|
|
4281
|
+
.join('\n');
|
|
4282
|
+
|
|
4283
|
+
const escapeControlCharacters = line => line.replaceAll(SPECIAL_CHAR_REGEXP, character => escapeControlCharacter(character));
|
|
4284
|
+
|
|
4285
|
+
const escapeControlCharacter = character => {
|
|
4286
|
+
const commonEscape = COMMON_ESCAPES[character];
|
|
4287
|
+
if (commonEscape !== undefined) {
|
|
4288
|
+
return commonEscape;
|
|
4289
|
+
}
|
|
4290
|
+
|
|
4291
|
+
const codepoint = character.codePointAt(0);
|
|
4292
|
+
const codepointHex = codepoint.toString(16);
|
|
4293
|
+
return codepoint <= ASTRAL_START
|
|
4294
|
+
? `\\u${codepointHex.padStart(4, '0')}`
|
|
4295
|
+
: `\\U${codepointHex}`;
|
|
4296
|
+
};
|
|
4297
|
+
|
|
4298
|
+
// Characters that would create issues when printed are escaped using the \u or \U notation.
|
|
4299
|
+
// Those include control characters and newlines.
|
|
4300
|
+
// The \u and \U notation is Bash specific, but there is no way to do this in a shell-agnostic way.
|
|
4301
|
+
// Some shells do not even have a way to print those characters in an escaped fashion.
|
|
4302
|
+
// Therefore, we prioritize printing those safely, instead of allowing those to be copy-pasted.
|
|
4303
|
+
// List of Unicode character categories: https://www.fileformat.info/info/unicode/category/index.htm
|
|
4304
|
+
const SPECIAL_CHAR_REGEXP = /\p{Separator}|\p{Other}/gu;
|
|
4305
|
+
|
|
4306
|
+
// Accepted by $'...' in Bash.
|
|
4307
|
+
// Exclude \a \e \v which are accepted in Bash but not in JavaScript (except \v) and JSON.
|
|
4308
|
+
const COMMON_ESCAPES = {
|
|
4309
|
+
' ': ' ',
|
|
4310
|
+
'\b': '\\b',
|
|
4311
|
+
'\f': '\\f',
|
|
4312
|
+
'\n': '\\n',
|
|
4313
|
+
'\r': '\\r',
|
|
4314
|
+
'\t': '\\t',
|
|
4315
|
+
};
|
|
4316
|
+
|
|
4317
|
+
// Up until that codepoint, \u notation can be used instead of \U
|
|
4318
|
+
const ASTRAL_START = 65_535;
|
|
4319
|
+
|
|
4320
|
+
// Some characters are shell-specific, i.e. need to be escaped when the command is copy-pasted then run.
|
|
4321
|
+
// Escaping is shell-specific. We cannot know which shell is used: `process.platform` detection is not enough.
|
|
4322
|
+
// For example, Windows users could be using `cmd.exe`, Powershell or Bash for Windows which all use different escaping.
|
|
4323
|
+
// We use '...' on Unix, which is POSIX shell compliant and escape all characters but ' so this is fairly safe.
|
|
4324
|
+
// On Windows, we assume cmd.exe is used and escape with "...", which also works with Powershell.
|
|
4325
|
+
const quoteString = escapedArgument => {
|
|
4326
|
+
if (NO_ESCAPE_REGEXP.test(escapedArgument)) {
|
|
4327
|
+
return escapedArgument;
|
|
4168
4328
|
}
|
|
4329
|
+
|
|
4330
|
+
return platform$1 === 'win32'
|
|
4331
|
+
? `"${escapedArgument.replaceAll('"', '""')}"`
|
|
4332
|
+
: `'${escapedArgument.replaceAll('\'', '\'\\\'\'')}'`;
|
|
4169
4333
|
};
|
|
4170
4334
|
|
|
4171
|
-
const
|
|
4335
|
+
const NO_ESCAPE_REGEXP = /^[\w./-]+$/;
|
|
4172
4336
|
|
|
4173
4337
|
function isUnicodeSupported() {
|
|
4174
4338
|
if (process$3.platform !== 'win32') {
|
|
@@ -4462,120 +4626,126 @@ const fallbackSymbols = {...common$7, ...specialFallbackSymbols};
|
|
|
4462
4626
|
const shouldUseMain = isUnicodeSupported();
|
|
4463
4627
|
const figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
4464
4628
|
|
|
4465
|
-
//
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4629
|
+
// eslint-disable-next-line no-warning-comments
|
|
4630
|
+
// TODO: Use a better method when it's added to Node.js (https://github.com/nodejs/node/pull/40240)
|
|
4631
|
+
const hasColors = tty.WriteStream.prototype.hasColors();
|
|
4632
|
+
|
|
4633
|
+
// Intentionally not using template literal for performance.
|
|
4634
|
+
const format = (startCode, endCode) => hasColors ? string => '\u001B[' + startCode + 'm' + string + '\u001B[' + endCode + 'm' : string => string;
|
|
4635
|
+
const bold = format(1, 22);
|
|
4636
|
+
const gray = format(90, 39);
|
|
4637
|
+
|
|
4638
|
+
const redBright = format(91, 39);
|
|
4639
|
+
const yellowBright = format(93, 39);
|
|
4640
|
+
|
|
4641
|
+
// Default when `verbose` is not a function
|
|
4642
|
+
const defaultVerboseFunction = ({
|
|
4643
|
+
type,
|
|
4644
|
+
message,
|
|
4645
|
+
timestamp,
|
|
4646
|
+
piped,
|
|
4647
|
+
commandId,
|
|
4648
|
+
result: {failed = false} = {},
|
|
4649
|
+
options: {reject = true},
|
|
4650
|
+
}) => {
|
|
4651
|
+
const timestampString = serializeTimestamp(timestamp);
|
|
4652
|
+
const icon = ICONS[type]({failed, reject, piped});
|
|
4653
|
+
const color = COLORS[type]({reject});
|
|
4654
|
+
return `${gray(`[${timestampString}]`)} ${gray(`[${commandId}]`)} ${color(icon)} ${color(message)}`;
|
|
4473
4655
|
};
|
|
4474
4656
|
|
|
4475
|
-
//
|
|
4476
|
-
const
|
|
4477
|
-
.split('\n')
|
|
4478
|
-
.map(line => escapeControlCharacters(line))
|
|
4479
|
-
.join('\n');
|
|
4657
|
+
// Prepending the timestamp allows debugging the slow paths of a subprocess
|
|
4658
|
+
const serializeTimestamp = timestamp => `${padField(timestamp.getHours(), 2)}:${padField(timestamp.getMinutes(), 2)}:${padField(timestamp.getSeconds(), 2)}.${padField(timestamp.getMilliseconds(), 3)}`;
|
|
4480
4659
|
|
|
4481
|
-
const
|
|
4660
|
+
const padField = (field, padding) => String(field).padStart(padding, '0');
|
|
4482
4661
|
|
|
4483
|
-
const
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
return commonEscape;
|
|
4662
|
+
const getFinalIcon = ({failed, reject}) => {
|
|
4663
|
+
if (!failed) {
|
|
4664
|
+
return figures.tick;
|
|
4487
4665
|
}
|
|
4488
4666
|
|
|
4489
|
-
|
|
4490
|
-
const codepointHex = codepoint.toString(16);
|
|
4491
|
-
return codepoint <= ASTRAL_START
|
|
4492
|
-
? `\\u${codepointHex.padStart(4, '0')}`
|
|
4493
|
-
: `\\U${codepointHex}`;
|
|
4667
|
+
return reject ? figures.cross : figures.warning;
|
|
4494
4668
|
};
|
|
4495
4669
|
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4670
|
+
const ICONS = {
|
|
4671
|
+
command: ({piped}) => piped ? '|' : '$',
|
|
4672
|
+
output: () => ' ',
|
|
4673
|
+
ipc: () => '*',
|
|
4674
|
+
error: getFinalIcon,
|
|
4675
|
+
duration: getFinalIcon,
|
|
4676
|
+
};
|
|
4503
4677
|
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
const
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
'\t': '\\t',
|
|
4678
|
+
const identity$1 = string => string;
|
|
4679
|
+
|
|
4680
|
+
const COLORS = {
|
|
4681
|
+
command: () => bold,
|
|
4682
|
+
output: () => identity$1,
|
|
4683
|
+
ipc: () => identity$1,
|
|
4684
|
+
error: ({reject}) => reject ? redBright : yellowBright,
|
|
4685
|
+
duration: () => gray,
|
|
4513
4686
|
};
|
|
4514
4687
|
|
|
4515
|
-
//
|
|
4516
|
-
const
|
|
4688
|
+
// Apply the `verbose` function on each line
|
|
4689
|
+
const applyVerboseOnLines = (printedLines, verboseInfo, fdNumber) => {
|
|
4690
|
+
const verboseFunction = getVerboseFunction(verboseInfo, fdNumber);
|
|
4691
|
+
return printedLines
|
|
4692
|
+
.map(({verboseLine, verboseObject}) => applyVerboseFunction(verboseLine, verboseObject, verboseFunction))
|
|
4693
|
+
.filter(printedLine => printedLine !== undefined)
|
|
4694
|
+
.map(printedLine => appendNewline(printedLine))
|
|
4695
|
+
.join('');
|
|
4696
|
+
};
|
|
4517
4697
|
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
// We use '...' on Unix, which is POSIX shell compliant and escape all characters but ' so this is fairly safe.
|
|
4522
|
-
// On Windows, we assume cmd.exe is used and escape with "...", which also works with Powershell.
|
|
4523
|
-
const quoteString = escapedArgument => {
|
|
4524
|
-
if (NO_ESCAPE_REGEXP.test(escapedArgument)) {
|
|
4525
|
-
return escapedArgument;
|
|
4698
|
+
const applyVerboseFunction = (verboseLine, verboseObject, verboseFunction) => {
|
|
4699
|
+
if (verboseFunction === undefined) {
|
|
4700
|
+
return verboseLine;
|
|
4526
4701
|
}
|
|
4527
4702
|
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4703
|
+
const printedLine = verboseFunction(verboseLine, verboseObject);
|
|
4704
|
+
if (typeof printedLine === 'string') {
|
|
4705
|
+
return printedLine;
|
|
4706
|
+
}
|
|
4531
4707
|
};
|
|
4532
4708
|
|
|
4533
|
-
const
|
|
4709
|
+
const appendNewline = printedLine => printedLine.endsWith('\n')
|
|
4710
|
+
? printedLine
|
|
4711
|
+
: `${printedLine}\n`;
|
|
4534
4712
|
|
|
4535
4713
|
// Write synchronously to ensure lines are properly ordered and not interleaved with `stdout`
|
|
4536
|
-
const verboseLog = (
|
|
4537
|
-
const
|
|
4538
|
-
|
|
4714
|
+
const verboseLog = ({type, verboseMessage, fdNumber, verboseInfo, result}) => {
|
|
4715
|
+
const verboseObject = getVerboseObject({type, result, verboseInfo});
|
|
4716
|
+
const printedLines = getPrintedLines(verboseMessage, verboseObject);
|
|
4717
|
+
const finalLines = applyVerboseOnLines(printedLines, verboseInfo, fdNumber);
|
|
4718
|
+
writeFileSync$1(STDERR_FD, finalLines);
|
|
4539
4719
|
};
|
|
4540
4720
|
|
|
4541
|
-
const
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
:
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
color(line),
|
|
4555
|
-
].join(' ');
|
|
4721
|
+
const getVerboseObject = ({
|
|
4722
|
+
type,
|
|
4723
|
+
result,
|
|
4724
|
+
verboseInfo: {escapedCommand, commandId, rawOptions: {piped = false, ...options}},
|
|
4725
|
+
}) => ({
|
|
4726
|
+
type,
|
|
4727
|
+
escapedCommand,
|
|
4728
|
+
commandId: `${commandId}`,
|
|
4729
|
+
timestamp: new Date(),
|
|
4730
|
+
piped,
|
|
4731
|
+
result,
|
|
4732
|
+
options,
|
|
4733
|
+
});
|
|
4556
4734
|
|
|
4557
|
-
const
|
|
4735
|
+
const getPrintedLines = (verboseMessage, verboseObject) => verboseMessage
|
|
4736
|
+
.split('\n')
|
|
4737
|
+
.map(message => getPrintedLine({...verboseObject, message}));
|
|
4558
4738
|
|
|
4559
|
-
|
|
4560
|
-
const
|
|
4561
|
-
|
|
4562
|
-
return `${padField(date.getHours(), 2)}:${padField(date.getMinutes(), 2)}:${padField(date.getSeconds(), 2)}.${padField(date.getMilliseconds(), 3)}`;
|
|
4739
|
+
const getPrintedLine = verboseObject => {
|
|
4740
|
+
const verboseLine = defaultVerboseFunction(verboseObject);
|
|
4741
|
+
return {verboseLine, verboseObject};
|
|
4563
4742
|
};
|
|
4564
4743
|
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
const ICONS = {
|
|
4568
|
-
command: '$',
|
|
4569
|
-
pipedCommand: '|',
|
|
4570
|
-
output: ' ',
|
|
4571
|
-
ipc: '*',
|
|
4572
|
-
error: figures.cross,
|
|
4573
|
-
warning: figures.warning,
|
|
4574
|
-
success: figures.tick,
|
|
4575
|
-
};
|
|
4744
|
+
// Unless a `verbose` function is used, print all logs on `stderr`
|
|
4745
|
+
const STDERR_FD = 2;
|
|
4576
4746
|
|
|
4577
4747
|
// Serialize any type to a line string, for logging
|
|
4578
|
-
const
|
|
4748
|
+
const serializeVerboseMessage = message => {
|
|
4579
4749
|
const messageString = typeof message === 'string' ? message : inspect(message);
|
|
4580
4750
|
const escapedMessage = escapeLines(messageString);
|
|
4581
4751
|
return escapedMessage.replaceAll('\t', ' '.repeat(TAB_SIZE));
|
|
@@ -4584,134 +4754,71 @@ const serializeLogMessage = message => {
|
|
|
4584
4754
|
// Same as `util.inspect()`
|
|
4585
4755
|
const TAB_SIZE = 2;
|
|
4586
4756
|
|
|
4587
|
-
// When `verbose` is `short|full`, print each command
|
|
4588
|
-
const logCommand = (escapedCommand,
|
|
4589
|
-
if (!isVerbose(
|
|
4757
|
+
// When `verbose` is `short|full|custom`, print each command
|
|
4758
|
+
const logCommand = (escapedCommand, verboseInfo) => {
|
|
4759
|
+
if (!isVerbose(verboseInfo)) {
|
|
4590
4760
|
return;
|
|
4591
4761
|
}
|
|
4592
4762
|
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
const getStartTime = () => hrtime.bigint();
|
|
4599
|
-
|
|
4600
|
-
// Compute duration after the subprocess ended.
|
|
4601
|
-
// Printed by the `verbose` option.
|
|
4602
|
-
const getDurationMs = startTime => Number(hrtime.bigint() - startTime) / 1e6;
|
|
4603
|
-
|
|
4604
|
-
const isStandardStream = stream => STANDARD_STREAMS.includes(stream);
|
|
4605
|
-
const STANDARD_STREAMS = [process$3.stdin, process$3.stdout, process$3.stderr];
|
|
4606
|
-
const STANDARD_STREAMS_ALIASES = ['stdin', 'stdout', 'stderr'];
|
|
4607
|
-
const getStreamName = fdNumber => STANDARD_STREAMS_ALIASES[fdNumber] ?? `stdio[${fdNumber}]`;
|
|
4608
|
-
|
|
4609
|
-
// Some options can have different values for `stdout`/`stderr`/`fd3`.
|
|
4610
|
-
// This normalizes those to array of values.
|
|
4611
|
-
// For example, `{verbose: {stdout: 'none', stderr: 'full'}}` becomes `{verbose: ['none', 'none', 'full']}`
|
|
4612
|
-
const normalizeFdSpecificOptions = options => {
|
|
4613
|
-
const optionsCopy = {...options};
|
|
4614
|
-
|
|
4615
|
-
for (const optionName of FD_SPECIFIC_OPTIONS) {
|
|
4616
|
-
optionsCopy[optionName] = normalizeFdSpecificOption(options, optionName);
|
|
4617
|
-
}
|
|
4618
|
-
|
|
4619
|
-
return optionsCopy;
|
|
4763
|
+
verboseLog({
|
|
4764
|
+
type: 'command',
|
|
4765
|
+
verboseMessage: escapedCommand,
|
|
4766
|
+
verboseInfo,
|
|
4767
|
+
});
|
|
4620
4768
|
};
|
|
4621
4769
|
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4770
|
+
// Information computed before spawning, used by the `verbose` option
|
|
4771
|
+
const getVerboseInfo = (verbose, escapedCommand, rawOptions) => {
|
|
4772
|
+
validateVerbose(verbose);
|
|
4773
|
+
const commandId = getCommandId(verbose);
|
|
4774
|
+
return {
|
|
4775
|
+
verbose,
|
|
4776
|
+
escapedCommand,
|
|
4777
|
+
commandId,
|
|
4778
|
+
rawOptions,
|
|
4779
|
+
};
|
|
4626
4780
|
};
|
|
4627
4781
|
|
|
4628
|
-
const
|
|
4629
|
-
? Math.max(stdio.length, STANDARD_STREAMS_ALIASES.length)
|
|
4630
|
-
: STANDARD_STREAMS_ALIASES.length;
|
|
4782
|
+
const getCommandId = verbose => isVerbose({verbose}) ? COMMAND_ID++ : undefined;
|
|
4631
4783
|
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4784
|
+
// Prepending the `pid` is useful when multiple commands print their output at the same time.
|
|
4785
|
+
// However, we cannot use the real PID since this is not available with `child_process.spawnSync()`.
|
|
4786
|
+
// Also, we cannot use the real PID if we want to print it before `child_process.spawn()` is run.
|
|
4787
|
+
// As a pro, it is shorter than a normal PID and never re-uses the same id.
|
|
4788
|
+
// As a con, it cannot be used to send signals.
|
|
4789
|
+
let COMMAND_ID = 0n;
|
|
4635
4790
|
|
|
4636
|
-
const
|
|
4637
|
-
for (const
|
|
4638
|
-
|
|
4639
|
-
|
|
4791
|
+
const validateVerbose = verbose => {
|
|
4792
|
+
for (const fdVerbose of verbose) {
|
|
4793
|
+
if (fdVerbose === false) {
|
|
4794
|
+
throw new TypeError('The "verbose: false" option was renamed to "verbose: \'none\'".');
|
|
4640
4795
|
}
|
|
4641
|
-
}
|
|
4642
|
-
|
|
4643
|
-
return optionArray;
|
|
4644
|
-
};
|
|
4645
4796
|
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
const getFdNameOrder = fdName => {
|
|
4650
|
-
if (fdName === 'stdout' || fdName === 'stderr') {
|
|
4651
|
-
return 0;
|
|
4652
|
-
}
|
|
4653
|
-
|
|
4654
|
-
return fdName === 'all' ? 2 : 1;
|
|
4655
|
-
};
|
|
4656
|
-
|
|
4657
|
-
const parseFdName = (fdName, optionName, optionArray) => {
|
|
4658
|
-
if (fdName === 'ipc') {
|
|
4659
|
-
return [optionArray.length - 1];
|
|
4660
|
-
}
|
|
4661
|
-
|
|
4662
|
-
const fdNumber = parseFd(fdName);
|
|
4663
|
-
if (fdNumber === undefined || fdNumber === 0) {
|
|
4664
|
-
throw new TypeError(`"${optionName}.${fdName}" is invalid.
|
|
4665
|
-
It must be "${optionName}.stdout", "${optionName}.stderr", "${optionName}.all", "${optionName}.ipc", or "${optionName}.fd3", "${optionName}.fd4" (and so on).`);
|
|
4666
|
-
}
|
|
4667
|
-
|
|
4668
|
-
if (fdNumber >= optionArray.length) {
|
|
4669
|
-
throw new TypeError(`"${optionName}.${fdName}" is invalid: that file descriptor does not exist.
|
|
4670
|
-
Please set the "stdio" option to ensure that file descriptor exists.`);
|
|
4671
|
-
}
|
|
4672
|
-
|
|
4673
|
-
return fdNumber === 'all' ? [1, 2] : [fdNumber];
|
|
4674
|
-
};
|
|
4675
|
-
|
|
4676
|
-
// Use the same syntax for fd-specific options and the `from`/`to` options
|
|
4677
|
-
const parseFd = fdName => {
|
|
4678
|
-
if (fdName === 'all') {
|
|
4679
|
-
return fdName;
|
|
4680
|
-
}
|
|
4681
|
-
|
|
4682
|
-
if (STANDARD_STREAMS_ALIASES.includes(fdName)) {
|
|
4683
|
-
return STANDARD_STREAMS_ALIASES.indexOf(fdName);
|
|
4684
|
-
}
|
|
4797
|
+
if (fdVerbose === true) {
|
|
4798
|
+
throw new TypeError('The "verbose: true" option was renamed to "verbose: \'short\'".');
|
|
4799
|
+
}
|
|
4685
4800
|
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4801
|
+
if (!VERBOSE_VALUES.includes(fdVerbose) && !isVerboseFunction(fdVerbose)) {
|
|
4802
|
+
const allowedValues = VERBOSE_VALUES.map(allowedValue => `'${allowedValue}'`).join(', ');
|
|
4803
|
+
throw new TypeError(`The "verbose" option must not be ${fdVerbose}. Allowed values are: ${allowedValues} or a function.`);
|
|
4804
|
+
}
|
|
4689
4805
|
}
|
|
4690
4806
|
};
|
|
4691
4807
|
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
const addDefaultValue$1 = (optionArray, optionName) => optionArray.map(optionValue => optionValue === undefined
|
|
4695
|
-
? DEFAULT_OPTIONS[optionName]
|
|
4696
|
-
: optionValue);
|
|
4697
|
-
|
|
4698
|
-
const DEFAULT_OPTIONS = {
|
|
4699
|
-
lines: false,
|
|
4700
|
-
buffer: true,
|
|
4701
|
-
maxBuffer: 1000 * 1000 * 100,
|
|
4702
|
-
verbose: verboseDefault,
|
|
4703
|
-
stripFinalNewline: true,
|
|
4704
|
-
};
|
|
4808
|
+
// Start counting time before spawning the subprocess
|
|
4809
|
+
const getStartTime = () => hrtime.bigint();
|
|
4705
4810
|
|
|
4706
|
-
//
|
|
4707
|
-
|
|
4811
|
+
// Compute duration after the subprocess ended.
|
|
4812
|
+
// Printed by the `verbose` option.
|
|
4813
|
+
const getDurationMs = startTime => Number(hrtime.bigint() - startTime) / 1e6;
|
|
4708
4814
|
|
|
4709
4815
|
// Compute `result.command`, `result.escapedCommand` and `verbose`-related information
|
|
4710
4816
|
const handleCommand = (filePath, rawArguments, rawOptions) => {
|
|
4711
4817
|
const startTime = getStartTime();
|
|
4712
4818
|
const {command, escapedCommand} = joinCommand(filePath, rawArguments);
|
|
4713
|
-
const
|
|
4714
|
-
|
|
4819
|
+
const verbose = normalizeFdSpecificOption(rawOptions, 'verbose');
|
|
4820
|
+
const verboseInfo = getVerboseInfo(verbose, escapedCommand, {...rawOptions});
|
|
4821
|
+
logCommand(escapedCommand, verboseInfo);
|
|
4715
4822
|
return {
|
|
4716
4823
|
command,
|
|
4717
4824
|
escapedCommand,
|
|
@@ -6576,7 +6683,7 @@ const hasMessageListeners = (anyProcess, ipcEmitter) => ipcEmitter.listenerCount
|
|
|
6576
6683
|
// When `buffer` is `false`, we set up a `message` listener that should be ignored.
|
|
6577
6684
|
// That listener is only meant to intercept `strict` acknowledgement responses.
|
|
6578
6685
|
const getMinListenerCount = anyProcess => SUBPROCESS_OPTIONS.has(anyProcess)
|
|
6579
|
-
&& !SUBPROCESS_OPTIONS.get(anyProcess).options.buffer
|
|
6686
|
+
&& !getFdSpecificValue(SUBPROCESS_OPTIONS.get(anyProcess).options.buffer, 'ipc')
|
|
6580
6687
|
? 1
|
|
6581
6688
|
: 0;
|
|
6582
6689
|
|
|
@@ -7621,11 +7728,12 @@ const getMaxBufferInfo = (error, maxBuffer) => {
|
|
|
7621
7728
|
const {maxBufferInfo: {fdNumber, unit}} = error;
|
|
7622
7729
|
delete error.maxBufferInfo;
|
|
7623
7730
|
|
|
7731
|
+
const threshold = getFdSpecificValue(maxBuffer, fdNumber);
|
|
7624
7732
|
if (fdNumber === 'ipc') {
|
|
7625
|
-
return {streamName: 'IPC output', threshold
|
|
7733
|
+
return {streamName: 'IPC output', threshold, unit: 'messages'};
|
|
7626
7734
|
}
|
|
7627
7735
|
|
|
7628
|
-
return {streamName: getStreamName(fdNumber), threshold
|
|
7736
|
+
return {streamName: getStreamName(fdNumber), threshold, unit};
|
|
7629
7737
|
};
|
|
7630
7738
|
|
|
7631
7739
|
// The only way to apply `maxBuffer` with `spawnSync()` is to use the native `maxBuffer` option Node.js provides.
|
|
@@ -8158,71 +8266,42 @@ function prettyMilliseconds(milliseconds, options) {
|
|
|
8158
8266
|
return result.join(separator);
|
|
8159
8267
|
}
|
|
8160
8268
|
|
|
8161
|
-
// When `verbose` is `short|full`, print each command's error when it fails
|
|
8162
|
-
const logError = (
|
|
8163
|
-
if (
|
|
8164
|
-
|
|
8269
|
+
// When `verbose` is `short|full|custom`, print each command's error when it fails
|
|
8270
|
+
const logError = (result, verboseInfo) => {
|
|
8271
|
+
if (result.failed) {
|
|
8272
|
+
verboseLog({
|
|
8273
|
+
type: 'error',
|
|
8274
|
+
verboseMessage: result.shortMessage,
|
|
8275
|
+
verboseInfo,
|
|
8276
|
+
result,
|
|
8277
|
+
});
|
|
8165
8278
|
}
|
|
8166
|
-
|
|
8167
|
-
const color = reject ? redBright : yellowBright;
|
|
8168
|
-
verboseLog(message, verboseId, icon, color);
|
|
8169
8279
|
};
|
|
8170
8280
|
|
|
8171
|
-
// When `verbose` is `short|full`, print each command's completion, duration and error
|
|
8172
|
-
const
|
|
8173
|
-
|
|
8174
|
-
message: shortMessage,
|
|
8175
|
-
failed,
|
|
8176
|
-
reject,
|
|
8177
|
-
durationMs,
|
|
8178
|
-
verboseInfo,
|
|
8179
|
-
});
|
|
8180
|
-
};
|
|
8181
|
-
|
|
8182
|
-
// Same but for early validation errors
|
|
8183
|
-
const logEarlyResult = (error, startTime, verboseInfo) => {
|
|
8184
|
-
logResult({
|
|
8185
|
-
message: escapeLines(String(error)),
|
|
8186
|
-
failed: true,
|
|
8187
|
-
reject: true,
|
|
8188
|
-
durationMs: getDurationMs(startTime),
|
|
8189
|
-
verboseInfo,
|
|
8190
|
-
});
|
|
8191
|
-
};
|
|
8192
|
-
|
|
8193
|
-
const logResult = ({message, failed, reject, durationMs, verboseInfo: {verbose, verboseId}}) => {
|
|
8194
|
-
if (!isVerbose(verbose)) {
|
|
8281
|
+
// When `verbose` is `short|full|custom`, print each command's completion, duration and error
|
|
8282
|
+
const logResult = (result, verboseInfo) => {
|
|
8283
|
+
if (!isVerbose(verboseInfo)) {
|
|
8195
8284
|
return;
|
|
8196
8285
|
}
|
|
8197
8286
|
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
message,
|
|
8201
|
-
failed,
|
|
8202
|
-
reject,
|
|
8203
|
-
verboseId,
|
|
8204
|
-
icon,
|
|
8205
|
-
});
|
|
8206
|
-
logDuration(durationMs, verboseId, icon);
|
|
8207
|
-
};
|
|
8208
|
-
|
|
8209
|
-
const logDuration = (durationMs, verboseId, icon) => {
|
|
8210
|
-
const durationMessage = `(done in ${prettyMilliseconds(durationMs)})`;
|
|
8211
|
-
verboseLog(durationMessage, verboseId, icon, gray);
|
|
8287
|
+
logError(result, verboseInfo);
|
|
8288
|
+
logDuration(result, verboseInfo);
|
|
8212
8289
|
};
|
|
8213
8290
|
|
|
8214
|
-
const
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8291
|
+
const logDuration = (result, verboseInfo) => {
|
|
8292
|
+
const verboseMessage = `(done in ${prettyMilliseconds(result.durationMs)})`;
|
|
8293
|
+
verboseLog({
|
|
8294
|
+
type: 'duration',
|
|
8295
|
+
verboseMessage,
|
|
8296
|
+
verboseInfo,
|
|
8297
|
+
result,
|
|
8298
|
+
});
|
|
8220
8299
|
};
|
|
8221
8300
|
|
|
8222
8301
|
// Applies the `reject` option.
|
|
8223
8302
|
// Also print the final log line with `verbose`.
|
|
8224
8303
|
const handleResult = (result, verboseInfo, {reject}) => {
|
|
8225
|
-
|
|
8304
|
+
logResult(result, verboseInfo);
|
|
8226
8305
|
|
|
8227
8306
|
if (result.failed && reject) {
|
|
8228
8307
|
throw result;
|
|
@@ -8622,10 +8701,10 @@ const normalizeIpcStdioArray = (stdioArray, ipc) => ipc && !stdioArray.includes(
|
|
|
8622
8701
|
|
|
8623
8702
|
// Add support for `stdin`/`stdout`/`stderr` as an alias for `stdio`.
|
|
8624
8703
|
// Also normalize the `stdio` option.
|
|
8625
|
-
const normalizeStdioOption = ({stdio, ipc, buffer,
|
|
8704
|
+
const normalizeStdioOption = ({stdio, ipc, buffer, ...options}, verboseInfo, isSync) => {
|
|
8626
8705
|
const stdioArray = getStdioArray(stdio, options).map((stdioOption, fdNumber) => addDefaultValue(stdioOption, fdNumber));
|
|
8627
8706
|
return isSync
|
|
8628
|
-
? normalizeStdioSync(stdioArray, buffer,
|
|
8707
|
+
? normalizeStdioSync(stdioArray, buffer, verboseInfo)
|
|
8629
8708
|
: normalizeIpcStdioArray(stdioArray, ipc);
|
|
8630
8709
|
};
|
|
8631
8710
|
|
|
@@ -8666,10 +8745,10 @@ const addDefaultValue = (stdioOption, fdNumber) => {
|
|
|
8666
8745
|
|
|
8667
8746
|
// Using `buffer: false` with synchronous methods implies `stdout`/`stderr`: `ignore`.
|
|
8668
8747
|
// Unless the output is needed, e.g. due to `verbose: 'full'` or to redirecting to a file.
|
|
8669
|
-
const normalizeStdioSync = (stdioArray, buffer,
|
|
8748
|
+
const normalizeStdioSync = (stdioArray, buffer, verboseInfo) => stdioArray.map((stdioOption, fdNumber) =>
|
|
8670
8749
|
!buffer[fdNumber]
|
|
8671
8750
|
&& fdNumber !== 0
|
|
8672
|
-
&&
|
|
8751
|
+
&& !isFullVerbose(verboseInfo, fdNumber)
|
|
8673
8752
|
&& isOutputPipeOnly(stdioOption)
|
|
8674
8753
|
? 'ignore'
|
|
8675
8754
|
: stdioOption);
|
|
@@ -8938,7 +9017,7 @@ const throwOnDuplicateStream = (stdioItem, optionName, type) => {
|
|
|
8938
9017
|
// They are converted into an array of `fileDescriptors`.
|
|
8939
9018
|
// Each `fileDescriptor` is normalized, validated and contains all information necessary for further handling.
|
|
8940
9019
|
const handleStdio = (addProperties, options, verboseInfo, isSync) => {
|
|
8941
|
-
const stdio = normalizeStdioOption(options, isSync);
|
|
9020
|
+
const stdio = normalizeStdioOption(options, verboseInfo, isSync);
|
|
8942
9021
|
const initialFileDescriptors = stdio.map((stdioOption, fdNumber) => getFileDescriptor({
|
|
8943
9022
|
stdioOption,
|
|
8944
9023
|
fdNumber,
|
|
@@ -9644,8 +9723,8 @@ const validateSerializable = newContents => {
|
|
|
9644
9723
|
// `inherit` would result in double printing.
|
|
9645
9724
|
// They can also lead to double printing when passing file descriptor integers or `process.std*`.
|
|
9646
9725
|
// This only leaves with `pipe` and `overlapped`.
|
|
9647
|
-
const shouldLogOutput = ({stdioItems, encoding, verboseInfo
|
|
9648
|
-
&&
|
|
9726
|
+
const shouldLogOutput = ({stdioItems, encoding, verboseInfo, fdNumber}) => fdNumber !== 'all'
|
|
9727
|
+
&& isFullVerbose(verboseInfo, fdNumber)
|
|
9649
9728
|
&& !BINARY_ENCODINGS.has(encoding)
|
|
9650
9729
|
&& fdUsesVerbose(fdNumber)
|
|
9651
9730
|
&& (stdioItems.some(({type, value}) => type === 'native' && PIPED_STDIO_VALUES.has(value))
|
|
@@ -9660,18 +9739,18 @@ const fdUsesVerbose = fdNumber => fdNumber === 1 || fdNumber === 2;
|
|
|
9660
9739
|
const PIPED_STDIO_VALUES = new Set(['pipe', 'overlapped']);
|
|
9661
9740
|
|
|
9662
9741
|
// `verbose: 'full'` printing logic with async methods
|
|
9663
|
-
const logLines = async (linesIterable, stream, verboseInfo) => {
|
|
9742
|
+
const logLines = async (linesIterable, stream, fdNumber, verboseInfo) => {
|
|
9664
9743
|
for await (const line of linesIterable) {
|
|
9665
9744
|
if (!isPipingStream(stream)) {
|
|
9666
|
-
logLine(line, verboseInfo);
|
|
9745
|
+
logLine(line, fdNumber, verboseInfo);
|
|
9667
9746
|
}
|
|
9668
9747
|
}
|
|
9669
9748
|
};
|
|
9670
9749
|
|
|
9671
9750
|
// `verbose: 'full'` printing logic with sync methods
|
|
9672
|
-
const logLinesSync = (linesArray, verboseInfo) => {
|
|
9751
|
+
const logLinesSync = (linesArray, fdNumber, verboseInfo) => {
|
|
9673
9752
|
for (const line of linesArray) {
|
|
9674
|
-
logLine(line, verboseInfo);
|
|
9753
|
+
logLine(line, fdNumber, verboseInfo);
|
|
9675
9754
|
}
|
|
9676
9755
|
};
|
|
9677
9756
|
|
|
@@ -9685,8 +9764,14 @@ const logLinesSync = (linesArray, verboseInfo) => {
|
|
|
9685
9764
|
const isPipingStream = stream => stream._readableState.pipes.length > 0;
|
|
9686
9765
|
|
|
9687
9766
|
// When `verbose` is `full`, print stdout|stderr
|
|
9688
|
-
const logLine = (line,
|
|
9689
|
-
|
|
9767
|
+
const logLine = (line, fdNumber, verboseInfo) => {
|
|
9768
|
+
const verboseMessage = serializeVerboseMessage(line);
|
|
9769
|
+
verboseLog({
|
|
9770
|
+
type: 'output',
|
|
9771
|
+
verboseMessage,
|
|
9772
|
+
fdNumber,
|
|
9773
|
+
verboseInfo,
|
|
9774
|
+
});
|
|
9690
9775
|
};
|
|
9691
9776
|
|
|
9692
9777
|
// Apply `stdout`/`stderr` options, after spawning, in sync mode
|
|
@@ -9731,15 +9816,15 @@ const transformOutputResultSync = (
|
|
|
9731
9816
|
fdNumber,
|
|
9732
9817
|
});
|
|
9733
9818
|
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
encoding,
|
|
9737
|
-
verboseInfo,
|
|
9819
|
+
logOutputSync({
|
|
9820
|
+
serializedResult,
|
|
9738
9821
|
fdNumber,
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
|
|
9742
|
-
|
|
9822
|
+
state,
|
|
9823
|
+
verboseInfo,
|
|
9824
|
+
encoding,
|
|
9825
|
+
stdioItems,
|
|
9826
|
+
objectMode,
|
|
9827
|
+
});
|
|
9743
9828
|
|
|
9744
9829
|
const returnedResult = buffer[fdNumber] ? finalResult : undefined;
|
|
9745
9830
|
|
|
@@ -9785,6 +9870,25 @@ const serializeChunks = ({chunks, objectMode, encoding, lines, stripFinalNewline
|
|
|
9785
9870
|
return {serializedResult};
|
|
9786
9871
|
};
|
|
9787
9872
|
|
|
9873
|
+
const logOutputSync = ({serializedResult, fdNumber, state, verboseInfo, encoding, stdioItems, objectMode}) => {
|
|
9874
|
+
if (!shouldLogOutput({
|
|
9875
|
+
stdioItems,
|
|
9876
|
+
encoding,
|
|
9877
|
+
verboseInfo,
|
|
9878
|
+
fdNumber,
|
|
9879
|
+
})) {
|
|
9880
|
+
return;
|
|
9881
|
+
}
|
|
9882
|
+
|
|
9883
|
+
const linesArray = splitLinesSync(serializedResult, false, objectMode);
|
|
9884
|
+
|
|
9885
|
+
try {
|
|
9886
|
+
logLinesSync(linesArray, fdNumber, verboseInfo);
|
|
9887
|
+
} catch (error) {
|
|
9888
|
+
state.error ??= error;
|
|
9889
|
+
}
|
|
9890
|
+
};
|
|
9891
|
+
|
|
9788
9892
|
// When the `std*` target is a file path/URL or a file descriptor
|
|
9789
9893
|
const writeToFiles = (serializedResult, stdioItems, outputFiles) => {
|
|
9790
9894
|
for (const {path} of stdioItems.filter(({type}) => FILE_TYPES.has(type))) {
|
|
@@ -9922,26 +10026,20 @@ const execaCoreSync = (rawFile, rawArguments, rawOptions) => {
|
|
|
9922
10026
|
// Compute arguments to pass to `child_process.spawnSync()`
|
|
9923
10027
|
const handleSyncArguments = (rawFile, rawArguments, rawOptions) => {
|
|
9924
10028
|
const {command, escapedCommand, startTime, verboseInfo} = handleCommand(rawFile, rawArguments, rawOptions);
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
9929
|
-
|
|
9930
|
-
|
|
9931
|
-
|
|
9932
|
-
|
|
9933
|
-
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
|
|
9938
|
-
|
|
9939
|
-
fileDescriptors,
|
|
9940
|
-
};
|
|
9941
|
-
} catch (error) {
|
|
9942
|
-
logEarlyResult(error, startTime, verboseInfo);
|
|
9943
|
-
throw error;
|
|
9944
|
-
}
|
|
10029
|
+
const syncOptions = normalizeSyncOptions(rawOptions);
|
|
10030
|
+
const {file, commandArguments, options} = normalizeOptions$2(rawFile, rawArguments, syncOptions);
|
|
10031
|
+
validateSyncOptions(options);
|
|
10032
|
+
const fileDescriptors = handleStdioSync(options, verboseInfo);
|
|
10033
|
+
return {
|
|
10034
|
+
file,
|
|
10035
|
+
commandArguments,
|
|
10036
|
+
command,
|
|
10037
|
+
escapedCommand,
|
|
10038
|
+
startTime,
|
|
10039
|
+
verboseInfo,
|
|
10040
|
+
options,
|
|
10041
|
+
fileDescriptors,
|
|
10042
|
+
};
|
|
9945
10043
|
};
|
|
9946
10044
|
|
|
9947
10045
|
// Options normalization logic specific to sync methods
|
|
@@ -11458,26 +11556,19 @@ const getGenerators = ({binary, shouldEncode, encoding, shouldSplit, preserveNew
|
|
|
11458
11556
|
].filter(Boolean);
|
|
11459
11557
|
|
|
11460
11558
|
// Retrieve `result.stdout|stderr|all|stdio[*]`
|
|
11461
|
-
const getStreamOutput = async ({stream, onStreamEnd, fdNumber, encoding, buffer, maxBuffer, lines, allMixed, stripFinalNewline, verboseInfo, streamInfo
|
|
11462
|
-
|
|
11463
|
-
|
|
11559
|
+
const getStreamOutput = async ({stream, onStreamEnd, fdNumber, encoding, buffer, maxBuffer, lines, allMixed, stripFinalNewline, verboseInfo, streamInfo}) => {
|
|
11560
|
+
const logPromise = logOutputAsync({
|
|
11561
|
+
stream,
|
|
11562
|
+
onStreamEnd,
|
|
11563
|
+
fdNumber,
|
|
11464
11564
|
encoding,
|
|
11565
|
+
allMixed,
|
|
11465
11566
|
verboseInfo,
|
|
11466
|
-
|
|
11467
|
-
})
|
|
11468
|
-
const linesIterable = iterateForResult({
|
|
11469
|
-
stream,
|
|
11470
|
-
onStreamEnd,
|
|
11471
|
-
lines: true,
|
|
11472
|
-
encoding,
|
|
11473
|
-
stripFinalNewline: true,
|
|
11474
|
-
allMixed,
|
|
11475
|
-
});
|
|
11476
|
-
logLines(linesIterable, stream, verboseInfo);
|
|
11477
|
-
}
|
|
11567
|
+
streamInfo,
|
|
11568
|
+
});
|
|
11478
11569
|
|
|
11479
11570
|
if (!buffer) {
|
|
11480
|
-
await resumeStream(stream);
|
|
11571
|
+
await Promise.all([resumeStream(stream), logPromise]);
|
|
11481
11572
|
return;
|
|
11482
11573
|
}
|
|
11483
11574
|
|
|
@@ -11490,14 +11581,39 @@ const getStreamOutput = async ({stream, onStreamEnd, fdNumber, encoding, buffer,
|
|
|
11490
11581
|
stripFinalNewline: stripFinalNewlineValue,
|
|
11491
11582
|
allMixed,
|
|
11492
11583
|
});
|
|
11493
|
-
|
|
11494
|
-
|
|
11495
|
-
|
|
11584
|
+
const [output] = await Promise.all([
|
|
11585
|
+
getStreamContents({
|
|
11586
|
+
stream,
|
|
11587
|
+
iterable,
|
|
11588
|
+
fdNumber,
|
|
11589
|
+
encoding,
|
|
11590
|
+
maxBuffer,
|
|
11591
|
+
lines,
|
|
11592
|
+
}),
|
|
11593
|
+
logPromise,
|
|
11594
|
+
]);
|
|
11595
|
+
return output;
|
|
11596
|
+
};
|
|
11597
|
+
|
|
11598
|
+
const logOutputAsync = async ({stream, onStreamEnd, fdNumber, encoding, allMixed, verboseInfo, streamInfo: {fileDescriptors}}) => {
|
|
11599
|
+
if (!shouldLogOutput({
|
|
11600
|
+
stdioItems: fileDescriptors[fdNumber]?.stdioItems,
|
|
11601
|
+
encoding,
|
|
11602
|
+
verboseInfo,
|
|
11496
11603
|
fdNumber,
|
|
11604
|
+
})) {
|
|
11605
|
+
return;
|
|
11606
|
+
}
|
|
11607
|
+
|
|
11608
|
+
const linesIterable = iterateForResult({
|
|
11609
|
+
stream,
|
|
11610
|
+
onStreamEnd,
|
|
11611
|
+
lines: true,
|
|
11497
11612
|
encoding,
|
|
11498
|
-
|
|
11499
|
-
|
|
11613
|
+
stripFinalNewline: true,
|
|
11614
|
+
allMixed,
|
|
11500
11615
|
});
|
|
11616
|
+
await logLines(linesIterable, stream, fdNumber, verboseInfo);
|
|
11501
11617
|
};
|
|
11502
11618
|
|
|
11503
11619
|
// When using `buffer: false`, users need to read `subprocess.stdout|stderr|all` right away
|
|
@@ -11733,10 +11849,16 @@ const getAllMixed = ({all, stdout, stderr}) => all
|
|
|
11733
11849
|
&& stdout.readableObjectMode !== stderr.readableObjectMode;
|
|
11734
11850
|
|
|
11735
11851
|
// When `verbose` is `'full'`, print IPC messages from the subprocess
|
|
11736
|
-
const shouldLogIpc =
|
|
11737
|
-
|
|
11738
|
-
const logIpcOutput = (message,
|
|
11739
|
-
|
|
11852
|
+
const shouldLogIpc = verboseInfo => isFullVerbose(verboseInfo, 'ipc');
|
|
11853
|
+
|
|
11854
|
+
const logIpcOutput = (message, verboseInfo) => {
|
|
11855
|
+
const verboseMessage = serializeVerboseMessage(message);
|
|
11856
|
+
verboseLog({
|
|
11857
|
+
type: 'ipc',
|
|
11858
|
+
verboseMessage,
|
|
11859
|
+
fdNumber: 'ipc',
|
|
11860
|
+
verboseInfo,
|
|
11861
|
+
});
|
|
11740
11862
|
};
|
|
11741
11863
|
|
|
11742
11864
|
// Iterate through IPC messages sent by the subprocess
|
|
@@ -11753,8 +11875,8 @@ const waitForIpcOutput = async ({
|
|
|
11753
11875
|
}
|
|
11754
11876
|
|
|
11755
11877
|
const isVerbose = shouldLogIpc(verboseInfo);
|
|
11756
|
-
const buffer = bufferArray
|
|
11757
|
-
const maxBuffer = maxBufferArray
|
|
11878
|
+
const buffer = getFdSpecificValue(bufferArray, 'ipc');
|
|
11879
|
+
const maxBuffer = getFdSpecificValue(maxBufferArray, 'ipc');
|
|
11758
11880
|
|
|
11759
11881
|
for await (const message of loopOnMessages({
|
|
11760
11882
|
anyProcess: subprocess,
|
|
@@ -12307,25 +12429,19 @@ const execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => {
|
|
|
12307
12429
|
// Compute arguments to pass to `child_process.spawn()`
|
|
12308
12430
|
const handleAsyncArguments = (rawFile, rawArguments, rawOptions) => {
|
|
12309
12431
|
const {command, escapedCommand, startTime, verboseInfo} = handleCommand(rawFile, rawArguments, rawOptions);
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
|
|
12322
|
-
|
|
12323
|
-
fileDescriptors,
|
|
12324
|
-
};
|
|
12325
|
-
} catch (error) {
|
|
12326
|
-
logEarlyResult(error, startTime, verboseInfo);
|
|
12327
|
-
throw error;
|
|
12328
|
-
}
|
|
12432
|
+
const {file, commandArguments, options: normalizedOptions} = normalizeOptions$2(rawFile, rawArguments, rawOptions);
|
|
12433
|
+
const options = handleAsyncOptions(normalizedOptions);
|
|
12434
|
+
const fileDescriptors = handleStdioAsync(options, verboseInfo);
|
|
12435
|
+
return {
|
|
12436
|
+
file,
|
|
12437
|
+
commandArguments,
|
|
12438
|
+
command,
|
|
12439
|
+
escapedCommand,
|
|
12440
|
+
startTime,
|
|
12441
|
+
verboseInfo,
|
|
12442
|
+
options,
|
|
12443
|
+
fileDescriptors,
|
|
12444
|
+
};
|
|
12329
12445
|
};
|
|
12330
12446
|
|
|
12331
12447
|
// Options normalization logic specific to async methods.
|
|
@@ -32346,14 +32462,14 @@ const getDotenvCliOptions2Options = ({ paths, pathsDelimiter, pathsDelimiterPatt
|
|
|
32346
32462
|
..._.omit(rest, ['debug', 'scripts']),
|
|
32347
32463
|
paths: paths?.split(pathsDelimiterPattern
|
|
32348
32464
|
? RegExp(pathsDelimiterPattern)
|
|
32349
|
-
: pathsDelimiter ?? ' ') ?? [],
|
|
32465
|
+
: (pathsDelimiter ?? ' ')) ?? [],
|
|
32350
32466
|
vars: _.fromPairs(vars
|
|
32351
32467
|
?.split(varsDelimiterPattern
|
|
32352
32468
|
? RegExp(varsDelimiterPattern)
|
|
32353
|
-
: varsDelimiter ?? ' ')
|
|
32469
|
+
: (varsDelimiter ?? ' '))
|
|
32354
32470
|
.map((v) => v.split(varsAssignorPattern
|
|
32355
32471
|
? RegExp(varsAssignorPattern)
|
|
32356
|
-
: varsAssignor ?? '='))),
|
|
32472
|
+
: (varsAssignor ?? '=')))),
|
|
32357
32473
|
});
|
|
32358
32474
|
const resolveGetDotenvOptions = async (customOptions) => {
|
|
32359
32475
|
const localPkgDir = await packageDirectory();
|
|
@@ -32885,7 +33001,8 @@ const getDotenv = async (options = {}) => {
|
|
|
32885
33001
|
for (const key in dynamic)
|
|
32886
33002
|
Object.assign(dotenv, {
|
|
32887
33003
|
[key]: _.isFunction(dynamic[key])
|
|
32888
|
-
?
|
|
33004
|
+
? // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
33005
|
+
dynamic[key](dotenv, env ?? defaultEnv)
|
|
32889
33006
|
: dynamic[key],
|
|
32890
33007
|
});
|
|
32891
33008
|
}
|
|
@@ -32917,9 +33034,10 @@ const getDotenv = async (options = {}) => {
|
|
|
32917
33034
|
|
|
32918
33035
|
const resolveCommand = (scripts, command) => (scripts && _.isObject(scripts[command])
|
|
32919
33036
|
? scripts[command].cmd
|
|
32920
|
-
: scripts?.[command] ?? command);
|
|
33037
|
+
: (scripts?.[command] ?? command));
|
|
32921
33038
|
const resolveShell = (scripts, command, shell) => scripts && _.isObject(scripts[command])
|
|
32922
|
-
?
|
|
33039
|
+
? // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
33040
|
+
scripts[command].shell
|
|
32923
33041
|
: shell;
|
|
32924
33042
|
|
|
32925
33043
|
/*
|