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