function _matches(val, cmp) { var ret = false; switch (true) { case type.isString(cmp): ret = val === cmp; break; case type.isRegExp(cmp): ret = cmp.test(val); break; case type.isArray(cmp): ret = cmp.indexOf(val) !== -1; break; } return ret; }
/** * Clones the object by traversing through it and setting up new instances of anything that can be referenced. * Dereferences most things, including Regular Expressions. * Will not dereference functions and classes, they will throw. * @param {object} source * @returns {object} dereferenced source * @throws {Error} Throws in the case it encounters something it cannot dereference. */ function dereference(source) { if (typeChecker.isString(source)) { return source.toString() } if (typeChecker.isUndefined(source)) { return } if (typeChecker.isNull(source)) { return null } if (typeChecker.isNumber(source) || typeChecker.isBoolean(source)) { return dereferenceJSON(source) } if (typeChecker.isPlainObject(source)) { const result = {} for (const key in source) { if (source.hasOwnProperty(key)) { const value = source[key] result[key] = dereference(value) } } return result } if (typeChecker.isArray(source)) { return source.map(function(item) { return dereference(item) }) } if (typeChecker.isDate(source)) { return new Date(source.toISOString()) } if (typeChecker.isRegExp(source)) { if (source.flags == null) { throw new Error( 'extendr cannot derefence RegExps on this older version of node' ) } else { return new RegExp(source.source, source.flags) } } throw new Error( 'extendr was passed an object type that it does not know how to derefence' ) }
safeps.openProcess(function (closeProcess) { // If the command is a string, then convert it into an array if ( typeChecker.isString(command) ) { command = command.split(' ') } // Prepare const result = { pid: null, stdout: null, stderr: null, output: null, error: null, status: null, signal: null } let exited = false // Tasks const tasks = new TaskGroup().done(function (err) { exited = true closeProcess() next(err || result.error, result.stdout, result.stderr, result.status, result.signal) }) // Get correct executable path if ( opts.safe ) { tasks.addTask(function (complete) { safeps.getExecPath(command[0], opts, function (err, execPath) { if ( err ) return complete(err) command[0] = execPath complete() }) }) } // Spawn tasks.addTask(function (complete) { // Spawn result.pid = require('child_process').spawn(command[0], command.slice(1), opts) // Write if we want to // result.pid.stdin may be null of stdio is 'inherit' if ( opts.stdin && result.pid.stdin) { result.pid.stdin.write(opts.stdin) result.pid.stdin.end() } // Read if we want to by listening to the streams and updating our result variables if ( opts.read ) { // result.pid.stdout may be null of stdio is 'inherit' if ( result.pid.stdout ) { result.pid.stdout.on('data', function (data) { if ( opts.output ) { safeps.outputData(data, 'stdout', opts.outputPrefix) } if ( result.stdout ) { result.stdout = Buffer.concat([result.stdout, data]) } else { result.stdout = data } }) } // result.pid.stderr may be null of stdio is 'inherit' if ( result.pid.stderr ) { result.pid.stderr.on('data', function (data) { if ( opts.output) { safeps.outputData(data, 'stderr', opts.outputPrefix) } if ( result.stderr ) { result.stderr = Buffer.concat([result.stderr, data]) } else { result.stderr = data } }) } } // Wait result.pid.on('close', function (status, signal) { // Apply to local global result.status = status result.signal = signal // Check if we have already exited due to domains // as without this, then we will fire the completion callback twice // once for the domain error that will happen first // then again for the close error // if it happens the other way round, close, then error, we want to be alerted of that if ( exited === true ) return // Check result and complete opts.output = false safeps.updateExecutableResult(result, opts) return complete(result.error) }) }) // Run tasks.run() })
* @param {Function} [next] callback * @param {Error} next.error * @param {Stream} next.stdout out stream * @param {Stream} next.stderr error stream * @param {Number} next.status node.js exit code * @param {String} next.signal unix style signal such as SIGKILL or SIGHUP * @return {Object} {error, pid, output, stdout, stderr, status, signal} */ spawnSync (command, opts, next) { // Prepare [opts, next] = extractOptsAndCallback(opts, next) opts = safeps.prepareExecutableOptions(opts) opts.sync = true // If the command is a string, then convert it into an array if ( typeChecker.isString(command) ) { command = command.split(' ') } // Get correct executable path // Only possible if sync abilities are possible (node 0.12 and up) or if it is cached // Otherwise, don't worry about it and output a warning to stderr if ( opts.safe ) { let wasSync = 0 safeps.getExecPath(command[0], opts, function (err, execPath) { if ( err ) return command[0] = execPath wasSync = 1 }) if ( wasSync === 0 ) { process.stderr.write('safeps.spawnSync: was unable to get the executable path synchronously')