'use strict'; var inspect = require('util').inspect; function assert(value, message) { if (!value) throw new ERR_INTERNAL_ASSERTION(message); } assert.fail = function fail(message) { throw new ERR_INTERNAL_ASSERTION(message); }; // Only use this for integers! Decimal numbers do not work with this function. function addNumericalSeparator(val) { var res = ''; var i = val.length; var start = val[0] === '-' ? 1 : 0; for (; i >= start + 4; i -= 3) res = `_${val.slice(i - 3, i)}${res}`; return `${val.slice(0, i)}${res}`; } function oneOf(expected, thing) { assert(typeof thing === 'string', '`thing` has to be of type string'); if (Array.isArray(expected)) { var len = expected.length; assert(len > 0, 'At least one expected value needs to be specified'); expected = expected.map((i) => String(i)); if (len > 2) { return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` + expected[len - 1]; } else if (len === 2) { return `one of ${thing} ${expected[0]} or ${expected[1]}`; } else { return `of ${thing} ${expected[0]}`; } } else { return `of ${thing} ${String(expected)}`; } } exports.ERR_INTERNAL_ASSERTION = class ERR_INTERNAL_ASSERTION extends Error { constructor(message) { super(); Error.captureStackTrace(this, ERR_INTERNAL_ASSERTION); var suffix = 'This is caused by either a bug in ssh2-streams ' + 'or incorrect usage of ssh2-streams internals.\n' + 'Please open an issue with this stack trace at ' + 'https://github.com/mscdex/ssh2-streams/issues\n'; this.message = (message === undefined ? suffix : `${message}\n${suffix}`); } }; var MAX_32BIT_INT = Math.pow(2, 32); var MAX_32BIT_BIGINT = (function() { try { return new Function('return 2n ** 32n')(); } catch (ex) {} })(); exports.ERR_OUT_OF_RANGE = class ERR_OUT_OF_RANGE extends RangeError { constructor(str, range, input, replaceDefaultBoolean) { super(); Error.captureStackTrace(this, ERR_OUT_OF_RANGE); assert(range, 'Missing "range" argument'); var msg = (replaceDefaultBoolean ? str : `The value of "${str}" is out of range.`); var received; if (Number.isInteger(input) && Math.abs(input) > MAX_32BIT_INT) { received = addNumericalSeparator(String(input)); } else if (typeof input === 'bigint') { received = String(input); if (input > MAX_32BIT_BIGINT || input < -MAX_32BIT_BIGINT) received = addNumericalSeparator(received); received += 'n'; } else { received = inspect(input); } msg += ` It must be ${range}. Received ${received}`; this.message = msg; } }; exports.ERR_INVALID_ARG_TYPE = class ERR_INVALID_ARG_TYPE extends TypeError { constructor(name, expected, actual) { super(); Error.captureStackTrace(this, ERR_INVALID_ARG_TYPE); assert(typeof name === 'string', `'name' must be a string`); // determiner: 'must be' or 'must not be' var determiner; if (typeof expected === 'string' && expected.startsWith('not ')) { determiner = 'must not be'; expected = expected.replace(/^not /, ''); } else { determiner = 'must be'; } var msg; if (name.endsWith(' argument')) { // For cases like 'first argument' msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`; } else { var type = (name.includes('.') ? 'property' : 'argument'); msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`; } msg += `. Received type ${typeof actual}`; this.message = msg; } }; exports.validateNumber = function validateNumber(value, name) { if (typeof value !== 'number') throw new ERR_INVALID_ARG_TYPE(name, 'number', value); }; // ============================================================================= // Following code is only needed to support node v6.x .... // Undocumented cb() API, needed for core, not for public API exports.destroyImpl = function destroy(err, cb) { const readableDestroyed = this._readableState && this._readableState.destroyed; const writableDestroyed = this._writableState && this._writableState.destroyed; if (readableDestroyed || writableDestroyed) { if (cb) { cb(err); } else if (err) { if (!this._writableState) { process.nextTick(emitErrorNT, this, err); } else if (!this._writableState.errorEmitted) { this._writableState.errorEmitted = true; process.nextTick(emitErrorNT, this, err); } } return this; } // We set destroyed to true before firing error callbacks in order // to make it re-entrance safe in case destroy() is called within callbacks if (this._readableState) { this._readableState.destroyed = true; } // If this is a duplex stream mark the writable part as destroyed as well if (this._writableState) { this._writableState.destroyed = true; } this._destroy(err || null, (err) => { if (!cb && err) { if (!this._writableState) { process.nextTick(emitErrorAndCloseNT, this, err); } else if (!this._writableState.errorEmitted) { this._writableState.errorEmitted = true; process.nextTick(emitErrorAndCloseNT, this, err); } else { process.nextTick(emitCloseNT, this); } } else if (cb) { process.nextTick(emitCloseNT, this); cb(err); } else { process.nextTick(emitCloseNT, this); } }); return this; }; function emitErrorAndCloseNT(self, err) { emitErrorNT(self, err); emitCloseNT(self); } function emitCloseNT(self) { if (self._writableState && !self._writableState.emitClose) return; if (self._readableState && !self._readableState.emitClose) return; self.emit('close'); } // =============================================================================