71 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import {constants} from 'node:os';
 | |
| import {signalsByName} from 'human-signals';
 | |
| 
 | |
| // Normalize signals for comparison purpose.
 | |
| // Also validate the signal exists.
 | |
| export const normalizeKillSignal = killSignal => {
 | |
| 	const optionName = 'option `killSignal`';
 | |
| 	if (killSignal === 0) {
 | |
| 		throw new TypeError(`Invalid ${optionName}: 0 cannot be used.`);
 | |
| 	}
 | |
| 
 | |
| 	return normalizeSignal(killSignal, optionName);
 | |
| };
 | |
| 
 | |
| export const normalizeSignalArgument = signal => signal === 0
 | |
| 	? signal
 | |
| 	: normalizeSignal(signal, '`subprocess.kill()`\'s argument');
 | |
| 
 | |
| const normalizeSignal = (signalNameOrInteger, optionName) => {
 | |
| 	if (Number.isInteger(signalNameOrInteger)) {
 | |
| 		return normalizeSignalInteger(signalNameOrInteger, optionName);
 | |
| 	}
 | |
| 
 | |
| 	if (typeof signalNameOrInteger === 'string') {
 | |
| 		return normalizeSignalName(signalNameOrInteger, optionName);
 | |
| 	}
 | |
| 
 | |
| 	throw new TypeError(`Invalid ${optionName} ${String(signalNameOrInteger)}: it must be a string or an integer.\n${getAvailableSignals()}`);
 | |
| };
 | |
| 
 | |
| const normalizeSignalInteger = (signalInteger, optionName) => {
 | |
| 	if (signalsIntegerToName.has(signalInteger)) {
 | |
| 		return signalsIntegerToName.get(signalInteger);
 | |
| 	}
 | |
| 
 | |
| 	throw new TypeError(`Invalid ${optionName} ${signalInteger}: this signal integer does not exist.\n${getAvailableSignals()}`);
 | |
| };
 | |
| 
 | |
| const getSignalsIntegerToName = () => new Map(Object.entries(constants.signals)
 | |
| 	.reverse()
 | |
| 	.map(([signalName, signalInteger]) => [signalInteger, signalName]));
 | |
| 
 | |
| const signalsIntegerToName = getSignalsIntegerToName();
 | |
| 
 | |
| const normalizeSignalName = (signalName, optionName) => {
 | |
| 	if (signalName in constants.signals) {
 | |
| 		return signalName;
 | |
| 	}
 | |
| 
 | |
| 	if (signalName.toUpperCase() in constants.signals) {
 | |
| 		throw new TypeError(`Invalid ${optionName} '${signalName}': please rename it to '${signalName.toUpperCase()}'.`);
 | |
| 	}
 | |
| 
 | |
| 	throw new TypeError(`Invalid ${optionName} '${signalName}': this signal name does not exist.\n${getAvailableSignals()}`);
 | |
| };
 | |
| 
 | |
| const getAvailableSignals = () => `Available signal names: ${getAvailableSignalNames()}.
 | |
| Available signal numbers: ${getAvailableSignalIntegers()}.`;
 | |
| 
 | |
| const getAvailableSignalNames = () => Object.keys(constants.signals)
 | |
| 	.sort()
 | |
| 	.map(signalName => `'${signalName}'`)
 | |
| 	.join(', ');
 | |
| 
 | |
| const getAvailableSignalIntegers = () => [...new Set(Object.values(constants.signals)
 | |
| 	.sort((signalInteger, signalIntegerTwo) => signalInteger - signalIntegerTwo))]
 | |
| 	.join(', ');
 | |
| 
 | |
| // Human-friendly description of a signal
 | |
| export const getSignalDescription = signal => signalsByName[signal].description;
 |