97 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import path from 'node:path';
 | |
| import process from 'node:process';
 | |
| import crossSpawn from 'cross-spawn';
 | |
| import {npmRunPathEnv} from 'npm-run-path';
 | |
| import {normalizeForceKillAfterDelay} from '../terminate/kill.js';
 | |
| import {normalizeKillSignal} from '../terminate/signal.js';
 | |
| import {validateCancelSignal} from '../terminate/cancel.js';
 | |
| import {validateGracefulCancel} from '../terminate/graceful.js';
 | |
| import {validateTimeout} from '../terminate/timeout.js';
 | |
| import {handleNodeOption} from '../methods/node.js';
 | |
| import {validateIpcInputOption} from '../ipc/ipc-input.js';
 | |
| import {validateEncoding, BINARY_ENCODINGS} from './encoding-option.js';
 | |
| import {normalizeCwd} from './cwd.js';
 | |
| import {normalizeFileUrl} from './file-url.js';
 | |
| import {normalizeFdSpecificOptions} from './specific.js';
 | |
| 
 | |
| // Normalize the options object, and sometimes also the file paths and arguments.
 | |
| // Applies default values, validate allowed options, normalize them.
 | |
| export const normalizeOptions = (filePath, rawArguments, rawOptions) => {
 | |
| 	rawOptions.cwd = normalizeCwd(rawOptions.cwd);
 | |
| 	const [processedFile, processedArguments, processedOptions] = handleNodeOption(filePath, rawArguments, rawOptions);
 | |
| 
 | |
| 	const {command: file, args: commandArguments, options: initialOptions} = crossSpawn._parse(processedFile, processedArguments, processedOptions);
 | |
| 
 | |
| 	const fdOptions = normalizeFdSpecificOptions(initialOptions);
 | |
| 	const options = addDefaultOptions(fdOptions);
 | |
| 	validateTimeout(options);
 | |
| 	validateEncoding(options);
 | |
| 	validateIpcInputOption(options);
 | |
| 	validateCancelSignal(options);
 | |
| 	validateGracefulCancel(options);
 | |
| 	options.shell = normalizeFileUrl(options.shell);
 | |
| 	options.env = getEnv(options);
 | |
| 	options.killSignal = normalizeKillSignal(options.killSignal);
 | |
| 	options.forceKillAfterDelay = normalizeForceKillAfterDelay(options.forceKillAfterDelay);
 | |
| 	options.lines = options.lines.map((lines, fdNumber) => lines && !BINARY_ENCODINGS.has(options.encoding) && options.buffer[fdNumber]);
 | |
| 
 | |
| 	if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') {
 | |
| 		// #116
 | |
| 		commandArguments.unshift('/q');
 | |
| 	}
 | |
| 
 | |
| 	return {file, commandArguments, options};
 | |
| };
 | |
| 
 | |
| const addDefaultOptions = ({
 | |
| 	extendEnv = true,
 | |
| 	preferLocal = false,
 | |
| 	cwd,
 | |
| 	localDir: localDirectory = cwd,
 | |
| 	encoding = 'utf8',
 | |
| 	reject = true,
 | |
| 	cleanup = true,
 | |
| 	all = false,
 | |
| 	windowsHide = true,
 | |
| 	killSignal = 'SIGTERM',
 | |
| 	forceKillAfterDelay = true,
 | |
| 	gracefulCancel = false,
 | |
| 	ipcInput,
 | |
| 	ipc = ipcInput !== undefined || gracefulCancel,
 | |
| 	serialization = 'advanced',
 | |
| 	...options
 | |
| }) => ({
 | |
| 	...options,
 | |
| 	extendEnv,
 | |
| 	preferLocal,
 | |
| 	cwd,
 | |
| 	localDirectory,
 | |
| 	encoding,
 | |
| 	reject,
 | |
| 	cleanup,
 | |
| 	all,
 | |
| 	windowsHide,
 | |
| 	killSignal,
 | |
| 	forceKillAfterDelay,
 | |
| 	gracefulCancel,
 | |
| 	ipcInput,
 | |
| 	ipc,
 | |
| 	serialization,
 | |
| });
 | |
| 
 | |
| const getEnv = ({env: envOption, extendEnv, preferLocal, node, localDirectory, nodePath}) => {
 | |
| 	const env = extendEnv ? {...process.env, ...envOption} : envOption;
 | |
| 
 | |
| 	if (preferLocal || node) {
 | |
| 		return npmRunPathEnv({
 | |
| 			env,
 | |
| 			cwd: localDirectory,
 | |
| 			execPath: nodePath,
 | |
| 			preferLocal,
 | |
| 			addExecPath: node,
 | |
| 		});
 | |
| 	}
 | |
| 
 | |
| 	return env;
 | |
| };
 |