123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- 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);
- }
- }
- };
|