DCFronted/node_modules/execa/lib/io/output-sync.js
zyb 0c0b5d869c 加入了node_modules
添加了新的功能项
2025-05-13 21:23:41 +08:00

136 lines
3.8 KiB
JavaScript

import {writeFileSync, appendFileSync} from 'node:fs';
import {shouldLogOutput, logLinesSync} from '../verbose/output.js';
import {runGeneratorsSync} from '../transform/generator.js';
import {splitLinesSync} from '../transform/split.js';
import {joinToString, joinToUint8Array, bufferToUint8Array} from '../utils/uint-array.js';
import {FILE_TYPES} from '../stdio/type.js';
import {truncateMaxBufferSync} from './max-buffer.js';
// Apply `stdout`/`stderr` options, after spawning, in sync mode
export const transformOutputSync = ({fileDescriptors, syncResult: {output}, options, isMaxBuffer, verboseInfo}) => {
if (output === null) {
return {output: Array.from({length: 3})};
}
const state = {};
const outputFiles = new Set([]);
const transformedOutput = output.map((result, fdNumber) =>
transformOutputResultSync({
result,
fileDescriptors,
fdNumber,
state,
outputFiles,
isMaxBuffer,
verboseInfo,
}, options));
return {output: transformedOutput, ...state};
};
const transformOutputResultSync = (
{result, fileDescriptors, fdNumber, state, outputFiles, isMaxBuffer, verboseInfo},
{buffer, encoding, lines, stripFinalNewline, maxBuffer},
) => {
if (result === null) {
return;
}
const truncatedResult = truncateMaxBufferSync(result, isMaxBuffer, maxBuffer);
const uint8ArrayResult = bufferToUint8Array(truncatedResult);
const {stdioItems, objectMode} = fileDescriptors[fdNumber];
const chunks = runOutputGeneratorsSync([uint8ArrayResult], stdioItems, encoding, state);
const {serializedResult, finalResult = serializedResult} = serializeChunks({
chunks,
objectMode,
encoding,
lines,
stripFinalNewline,
fdNumber,
});
logOutputSync({
serializedResult,
fdNumber,
state,
verboseInfo,
encoding,
stdioItems,
objectMode,
});
const returnedResult = buffer[fdNumber] ? finalResult : undefined;
try {
if (state.error === undefined) {
writeToFiles(serializedResult, stdioItems, outputFiles);
}
return returnedResult;
} catch (error) {
state.error = error;
return returnedResult;
}
};
// Applies transform generators to `stdout`/`stderr`
const runOutputGeneratorsSync = (chunks, stdioItems, encoding, state) => {
try {
return runGeneratorsSync(chunks, stdioItems, encoding, false);
} catch (error) {
state.error = error;
return chunks;
}
};
// The contents is converted to three stages:
// - serializedResult: used when the target is a file path/URL or a file descriptor (including 'inherit')
// - finalResult/returnedResult: returned as `result.std*`
const serializeChunks = ({chunks, objectMode, encoding, lines, stripFinalNewline, fdNumber}) => {
if (objectMode) {
return {serializedResult: chunks};
}
if (encoding === 'buffer') {
return {serializedResult: joinToUint8Array(chunks)};
}
const serializedResult = joinToString(chunks, encoding);
if (lines[fdNumber]) {
return {serializedResult, finalResult: splitLinesSync(serializedResult, !stripFinalNewline[fdNumber], objectMode)};
}
return {serializedResult};
};
const logOutputSync = ({serializedResult, fdNumber, state, verboseInfo, encoding, stdioItems, objectMode}) => {
if (!shouldLogOutput({
stdioItems,
encoding,
verboseInfo,
fdNumber,
})) {
return;
}
const linesArray = splitLinesSync(serializedResult, false, objectMode);
try {
logLinesSync(linesArray, fdNumber, verboseInfo);
} catch (error) {
state.error ??= error;
}
};
// When the `std*` target is a file path/URL or a file descriptor
const writeToFiles = (serializedResult, stdioItems, outputFiles) => {
for (const {path, append} of stdioItems.filter(({type}) => FILE_TYPES.has(type))) {
const pathString = typeof path === 'string' ? path : path.toString();
if (append || outputFiles.has(pathString)) {
appendFileSync(path, serializedResult);
} else {
outputFiles.add(pathString);
writeFileSync(path, serializedResult);
}
}
};