import require$$0$1 from 'url'; import require$$1 from 'util'; import require$$1$1 from 'tty'; import require$$0$2 from 'os'; import require$$0$4 from 'buffer'; import require$$0$3 from 'crypto'; import zlib$1 from 'zlib'; import require$$0$5 from 'http'; import require$$1$2 from 'https'; import require$$1$3 from 'events'; import require$$0$6 from 'assert'; import require$$1$4 from 'querystring'; import fs$j from 'fs'; import require$$1$5 from 'path'; import require$$0$7 from 'constants'; import stream from 'stream'; import require$$0$8 from 'dns'; import require$$0$9 from 'net'; import require$$1$6 from 'tls'; import require$$1$7 from 'string_decoder'; /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; var freeGlobal$1 = freeGlobal; /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal$1 || freeSelf || Function('return this')(); /** Built-in value references. */ var Symbol$1 = root.Symbol; var Symbol$2 = Symbol$1; /** Used for built-in method references. */ var objectProto$l = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$d = objectProto$l.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString$1 = objectProto$l.toString; /** Built-in value references. */ var symToStringTag$1 = Symbol$2 ? Symbol$2.toStringTag : undefined; /** * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * * @private * @param {*} value The value to query. * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { var isOwn = hasOwnProperty$d.call(value, symToStringTag$1), tag = value[symToStringTag$1]; try { value[symToStringTag$1] = undefined; var unmasked = true; } catch (e) {} var result = nativeObjectToString$1.call(value); if (unmasked) { if (isOwn) { value[symToStringTag$1] = tag; } else { delete value[symToStringTag$1]; } } return result; } /** Used for built-in method references. */ var objectProto$k = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto$k.toString; /** * Converts `value` to a string using `Object.prototype.toString`. * * @private * @param {*} value The value to convert. * @returns {string} Returns the converted string. */ function objectToString$9(value) { return nativeObjectToString.call(value); } /** `Object#toString` result references. */ var nullTag = '[object Null]', undefinedTag = '[object Undefined]'; /** Built-in value references. */ var symToStringTag = Symbol$2 ? Symbol$2.toStringTag : undefined; /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return (symToStringTag && symToStringTag in Object(value)) ? getRawTag(value) : objectToString$9(value); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike$a(value) { return value != null && typeof value == 'object'; } /** `Object#toString` result references. */ var symbolTag$5 = '[object Symbol]'; /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol$3(value) { return typeof value == 'symbol' || (isObjectLike$a(value) && baseGetTag(value) == symbolTag$5); } /** * A specialized version of `_.map` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function arrayMap$1(array, iteratee) { var index = -1, length = array == null ? 0 : array.length, result = Array(length); while (++index < length) { result[index] = iteratee(array[index], index, array); } return result; } /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray$3 = Array.isArray; var isArray$4 = isArray$3; /** Used as references for various `Number` constants. */ var INFINITY$3 = 1 / 0; /** Used to convert symbols to primitives and strings. */ var symbolProto$1 = Symbol$2 ? Symbol$2.prototype : undefined, symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined; /** * The base implementation of `_.toString` which doesn't convert nullish * values to empty strings. * * @private * @param {*} value The value to process. * @returns {string} Returns the string. */ function baseToString(value) { // Exit early for strings to avoid a performance hit in some environments. if (typeof value == 'string') { return value; } if (isArray$4(value)) { // Recursively convert values (susceptible to call stack limits). return arrayMap$1(value, baseToString) + ''; } if (isSymbol$3(value)) { return symbolToString ? symbolToString.call(value) : ''; } var result = (value + ''); return (result == '0' && (1 / value) == -INFINITY$3) ? '-0' : result; } /** Used to match a single whitespace character. */ var reWhitespace = /\s/; /** * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace * character of `string`. * * @private * @param {string} string The string to inspect. * @returns {number} Returns the index of the last non-whitespace character. */ function trimmedEndIndex(string) { var index = string.length; while (index-- && reWhitespace.test(string.charAt(index))) {} return index; } /** Used to match leading whitespace. */ var reTrimStart = /^\s+/; /** * The base implementation of `_.trim`. * * @private * @param {string} string The string to trim. * @returns {string} Returns the trimmed string. */ function baseTrim(string) { return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') : string; } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject$8(value) { var type = typeof value; return value != null && (type == 'object' || type == 'function'); } /** Used as references for various `Number` constants. */ var NAN$3 = 0 / 0; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex$3 = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary$3 = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal$3 = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt$3 = parseInt; /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber$3(value) { if (typeof value == 'number') { return value; } if (isSymbol$3(value)) { return NAN$3; } if (isObject$8(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject$8(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = baseTrim(value); var isBinary = reIsBinary$3.test(value); return (isBinary || reIsOctal$3.test(value)) ? freeParseInt$3(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex$3.test(value) ? NAN$3 : +value); } /** `Object#toString` result references. */ var asyncTag = '[object AsyncFunction]', funcTag$5 = '[object Function]', genTag$4 = '[object GeneratorFunction]', proxyTag = '[object Proxy]'; /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction$3(value) { if (!isObject$8(value)) { return false; } // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 9 which returns 'object' for typed arrays and other constructors. var tag = baseGetTag(value); return tag == funcTag$5 || tag == genTag$4 || tag == asyncTag || tag == proxyTag; } /** Used to detect overreaching core-js shims. */ var coreJsData = root['__core-js_shared__']; /** Used to detect methods masquerading as native. */ var maskSrcKey = (function() { var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); return uid ? ('Symbol(src)_1.' + uid) : ''; }()); /** * Checks if `func` has its source masked. * * @private * @param {Function} func The function to check. * @returns {boolean} Returns `true` if `func` is masked, else `false`. */ function isMasked(func) { return !!maskSrcKey && (maskSrcKey in func); } /** Used for built-in method references. */ var funcProto$2 = Function.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString$2 = funcProto$2.toString; /** * Converts `func` to its source code. * * @private * @param {Function} func The function to convert. * @returns {string} Returns the source code. */ function toSource(func) { if (func != null) { try { return funcToString$2.call(func); } catch (e) {} try { return (func + ''); } catch (e) {} } return ''; } /** * Used to match `RegExp` * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). */ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; /** Used to detect host constructors (Safari). */ var reIsHostCtor = /^\[object .+?Constructor\]$/; /** Used for built-in method references. */ var funcProto$1 = Function.prototype, objectProto$j = Object.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString$1 = funcProto$1.toString; /** Used to check objects for own properties. */ var hasOwnProperty$c = objectProto$j.hasOwnProperty; /** Used to detect if a method is native. */ var reIsNative = RegExp('^' + funcToString$1.call(hasOwnProperty$c).replace(reRegExpChar, '\\$&') .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); /** * The base implementation of `_.isNative` without bad shim checks. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a native function, * else `false`. */ function baseIsNative(value) { if (!isObject$8(value) || isMasked(value)) { return false; } var pattern = isFunction$3(value) ? reIsNative : reIsHostCtor; return pattern.test(toSource(value)); } /** * Gets the value at `key` of `object`. * * @private * @param {Object} [object] The object to query. * @param {string} key The key of the property to get. * @returns {*} Returns the property value. */ function getValue(object, key) { return object == null ? undefined : object[key]; } /** * Gets the native function at `key` of `object`. * * @private * @param {Object} object The object to query. * @param {string} key The key of the method to get. * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { var value = getValue(object, key); return baseIsNative(value) ? value : undefined; } /* Built-in method references that are verified to be native. */ var WeakMap$1 = getNative(root, 'WeakMap'); /** Built-in value references. */ var objectCreate = Object.create; /** * The base implementation of `_.create` without support for assigning * properties to the created object. * * @private * @param {Object} proto The object to inherit from. * @returns {Object} Returns the new object. */ var baseCreate = (function() { function object() {} return function(proto) { if (!isObject$8(proto)) { return {}; } if (objectCreate) { return objectCreate(proto); } object.prototype = proto; var result = new object; object.prototype = undefined; return result; }; }()); /** * Copies the values of `source` to `array`. * * @private * @param {Array} source The array to copy values from. * @param {Array} [array=[]] The array to copy values to. * @returns {Array} Returns `array`. */ function copyArray(source, array) { var index = -1, length = source.length; array || (array = Array(length)); while (++index < length) { array[index] = source[index]; } return array; } var defineProperty = (function() { try { var func = getNative(Object, 'defineProperty'); func({}, '', {}); return func; } catch (e) {} }()); /** * A specialized version of `_.forEach` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEach(array, iteratee) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (iteratee(array[index], index, array) === false) { break; } } return array; } /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER$6 = 9007199254740991; /** Used to detect unsigned integer values. */ var reIsUint$2 = /^(?:0|[1-9]\d*)$/; /** * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex$2(value, length) { var type = typeof value; length = length == null ? MAX_SAFE_INTEGER$6 : length; return !!length && (type == 'number' || (type != 'symbol' && reIsUint$2.test(value))) && (value > -1 && value % 1 == 0 && value < length); } /** * The base implementation of `assignValue` and `assignMergeValue` without * value checks. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function baseAssignValue(object, key, value) { if (key == '__proto__' && defineProperty) { defineProperty(object, key, { 'configurable': true, 'enumerable': true, 'value': value, 'writable': true }); } else { object[key] = value; } } /** * Performs a * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * comparison between two values to determine if they are equivalent. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.eq(object, object); * // => true * * _.eq(object, other); * // => false * * _.eq('a', 'a'); * // => true * * _.eq('a', Object('a')); * // => false * * _.eq(NaN, NaN); * // => true */ function eq$4(value, other) { return value === other || (value !== value && other !== other); } /** Used for built-in method references. */ var objectProto$i = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$b = objectProto$i.hasOwnProperty; /** * Assigns `value` to `key` of `object` if the existing value is not equivalent * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignValue$1(object, key, value) { var objValue = object[key]; if (!(hasOwnProperty$b.call(object, key) && eq$4(objValue, value)) || (value === undefined && !(key in object))) { baseAssignValue(object, key, value); } } /** * Copies properties of `source` to `object`. * * @private * @param {Object} source The object to copy properties from. * @param {Array} props The property identifiers to copy. * @param {Object} [object={}] The object to copy properties to. * @param {Function} [customizer] The function to customize copied values. * @returns {Object} Returns `object`. */ function copyObject$1(source, props, object, customizer) { var isNew = !object; object || (object = {}); var index = -1, length = props.length; while (++index < length) { var key = props[index]; var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined; if (newValue === undefined) { newValue = source[key]; } if (isNew) { baseAssignValue(object, key, newValue); } else { assignValue$1(object, key, newValue); } } return object; } /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER$5 = 9007199254740991; /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength$3(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$5; } /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike$3(value) { return value != null && isLength$3(value.length) && !isFunction$3(value); } /** Used for built-in method references. */ var objectProto$h = Object.prototype; /** * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype$2(value) { var Ctor = value && value.constructor, proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$h; return value === proto; } /** * The base implementation of `_.times` without support for iteratee shorthands * or max array length checks. * * @private * @param {number} n The number of times to invoke `iteratee`. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the array of results. */ function baseTimes$2(n, iteratee) { var index = -1, result = Array(n); while (++index < n) { result[index] = iteratee(index); } return result; } /** `Object#toString` result references. */ var argsTag$5 = '[object Arguments]'; /** * The base implementation of `_.isArguments`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, */ function baseIsArguments(value) { return isObjectLike$a(value) && baseGetTag(value) == argsTag$5; } /** Used for built-in method references. */ var objectProto$g = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$a = objectProto$g.hasOwnProperty; /** Built-in value references. */ var propertyIsEnumerable$4 = objectProto$g.propertyIsEnumerable; /** * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, * else `false`. * @example * * _.isArguments(function() { return arguments; }()); * // => true * * _.isArguments([1, 2, 3]); * // => false */ var isArguments$4 = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { return isObjectLike$a(value) && hasOwnProperty$a.call(value, 'callee') && !propertyIsEnumerable$4.call(value, 'callee'); }; /** * This method returns `false`. * * @static * @memberOf _ * @since 4.13.0 * @category Util * @returns {boolean} Returns `false`. * @example * * _.times(2, _.stubFalse); * // => [false, false] */ function stubFalse() { return false; } /** Detect free variable `exports`. */ var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2; /** Built-in value references. */ var Buffer$a = moduleExports$2 ? root.Buffer : undefined; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeIsBuffer = Buffer$a ? Buffer$a.isBuffer : undefined; /** * Checks if `value` is a buffer. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. * @example * * _.isBuffer(new Buffer(2)); * // => true * * _.isBuffer(new Uint8Array(2)); * // => false */ var isBuffer = nativeIsBuffer || stubFalse; /** `Object#toString` result references. */ var argsTag$4 = '[object Arguments]', arrayTag$1 = '[object Array]', boolTag$3 = '[object Boolean]', dateTag$2 = '[object Date]', errorTag$1 = '[object Error]', funcTag$4 = '[object Function]', mapTag$4 = '[object Map]', numberTag$3 = '[object Number]', objectTag$3 = '[object Object]', regexpTag$2 = '[object RegExp]', setTag$4 = '[object Set]', stringTag$4 = '[object String]', weakMapTag$2 = '[object WeakMap]'; var arrayBufferTag$2 = '[object ArrayBuffer]', dataViewTag$3 = '[object DataView]', float32Tag$2 = '[object Float32Array]', float64Tag$2 = '[object Float64Array]', int8Tag$2 = '[object Int8Array]', int16Tag$2 = '[object Int16Array]', int32Tag$2 = '[object Int32Array]', uint8Tag$2 = '[object Uint8Array]', uint8ClampedTag$2 = '[object Uint8ClampedArray]', uint16Tag$2 = '[object Uint16Array]', uint32Tag$2 = '[object Uint32Array]'; /** Used to identify `toStringTag` values of typed arrays. */ var typedArrayTags = {}; typedArrayTags[float32Tag$2] = typedArrayTags[float64Tag$2] = typedArrayTags[int8Tag$2] = typedArrayTags[int16Tag$2] = typedArrayTags[int32Tag$2] = typedArrayTags[uint8Tag$2] = typedArrayTags[uint8ClampedTag$2] = typedArrayTags[uint16Tag$2] = typedArrayTags[uint32Tag$2] = true; typedArrayTags[argsTag$4] = typedArrayTags[arrayTag$1] = typedArrayTags[arrayBufferTag$2] = typedArrayTags[boolTag$3] = typedArrayTags[dataViewTag$3] = typedArrayTags[dateTag$2] = typedArrayTags[errorTag$1] = typedArrayTags[funcTag$4] = typedArrayTags[mapTag$4] = typedArrayTags[numberTag$3] = typedArrayTags[objectTag$3] = typedArrayTags[regexpTag$2] = typedArrayTags[setTag$4] = typedArrayTags[stringTag$4] = typedArrayTags[weakMapTag$2] = false; /** * The base implementation of `_.isTypedArray` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. */ function baseIsTypedArray(value) { return isObjectLike$a(value) && isLength$3(value.length) && !!typedArrayTags[baseGetTag(value)]; } /** * The base implementation of `_.unary` without support for storing metadata. * * @private * @param {Function} func The function to cap arguments for. * @returns {Function} Returns the new capped function. */ function baseUnary(func) { return function(value) { return func(value); }; } /** Detect free variable `exports`. */ var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; /** Detect free variable `process` from Node.js. */ var freeProcess = moduleExports$1 && freeGlobal$1.process; /** Used to access faster Node.js helpers. */ var nodeUtil = (function() { try { // Use `util.types` for Node.js 10+. var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types; if (types) { return types; } // Legacy `process.binding('util')` for Node.js < 10. return freeProcess && freeProcess.binding && freeProcess.binding('util'); } catch (e) {} }()); /* Node.js helper references. */ var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; /** * Checks if `value` is classified as a typed array. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. * @example * * _.isTypedArray(new Uint8Array); * // => true * * _.isTypedArray([]); * // => false */ var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; /** Used for built-in method references. */ var objectProto$f = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$9 = objectProto$f.hasOwnProperty; /** * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. * @param {boolean} inherited Specify returning inherited property names. * @returns {Array} Returns the array of property names. */ function arrayLikeKeys$2(value, inherited) { var isArr = isArray$4(value), isArg = !isArr && isArguments$4(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes$2(value.length, String) : [], length = result.length; for (var key in value) { if ((inherited || hasOwnProperty$9.call(value, key)) && !(skipIndexes && ( // Safari 9 has enumerable `arguments.length` in strict mode. key == 'length' || // Node.js 0.10 has enumerable non-index properties on buffers. (isBuff && (key == 'offset' || key == 'parent')) || // PhantomJS 2 has enumerable non-index properties on typed arrays. (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || // Skip index properties. isIndex$2(key, length) ))) { result.push(key); } } return result; } /** * Creates a unary function that invokes `func` with its argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg$2(func, transform) { return function(arg) { return func(transform(arg)); }; } /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeKeys$1 = overArg$2(Object.keys, Object); /** Used for built-in method references. */ var objectProto$e = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$8 = objectProto$e.hasOwnProperty; /** * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeys$1(object) { if (!isPrototype$2(object)) { return nativeKeys$1(object); } var result = []; for (var key in Object(object)) { if (hasOwnProperty$8.call(object, key) && key != 'constructor') { result.push(key); } } return result; } /** * Creates an array of the own enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. See the * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * for more details. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keys(new Foo); * // => ['a', 'b'] (iteration order is not guaranteed) * * _.keys('hi'); * // => ['0', '1'] */ function keys$3(object) { return isArrayLike$3(object) ? arrayLikeKeys$2(object) : baseKeys$1(object); } /** * This function is like * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * except that it includes inherited enumerable properties. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function nativeKeysIn$1(object) { var result = []; if (object != null) { for (var key in Object(object)) { result.push(key); } } return result; } /** Used for built-in method references. */ var objectProto$d = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$7 = objectProto$d.hasOwnProperty; /** * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeysIn$1(object) { if (!isObject$8(object)) { return nativeKeysIn$1(object); } var isProto = isPrototype$2(object), result = []; for (var key in object) { if (!(key == 'constructor' && (isProto || !hasOwnProperty$7.call(object, key)))) { result.push(key); } } return result; } /** * Creates an array of the own and inherited enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ * @since 3.0.0 * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keysIn(new Foo); * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ function keysIn$1(object) { return isArrayLike$3(object) ? arrayLikeKeys$2(object, true) : baseKeysIn$1(object); } /* Built-in method references that are verified to be native. */ var nativeCreate = getNative(Object, 'create'); /** * Removes all key-value entries from the hash. * * @private * @name clear * @memberOf Hash */ function hashClear() { this.__data__ = nativeCreate ? nativeCreate(null) : {}; this.size = 0; } /** * Removes `key` and its value from the hash. * * @private * @name delete * @memberOf Hash * @param {Object} hash The hash to modify. * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function hashDelete(key) { var result = this.has(key) && delete this.__data__[key]; this.size -= result ? 1 : 0; return result; } /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; /** Used for built-in method references. */ var objectProto$c = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$6 = objectProto$c.hasOwnProperty; /** * Gets the hash value for `key`. * * @private * @name get * @memberOf Hash * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function hashGet(key) { var data = this.__data__; if (nativeCreate) { var result = data[key]; return result === HASH_UNDEFINED$1 ? undefined : result; } return hasOwnProperty$6.call(data, key) ? data[key] : undefined; } /** Used for built-in method references. */ var objectProto$b = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$5 = objectProto$b.hasOwnProperty; /** * Checks if a hash value for `key` exists. * * @private * @name has * @memberOf Hash * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function hashHas(key) { var data = this.__data__; return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$5.call(data, key); } /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED = '__lodash_hash_undefined__'; /** * Sets the hash `key` to `value`. * * @private * @name set * @memberOf Hash * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the hash instance. */ function hashSet(key, value) { var data = this.__data__; this.size += this.has(key) ? 0 : 1; data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; return this; } /** * Creates a hash object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Hash(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `Hash`. Hash.prototype.clear = hashClear; Hash.prototype['delete'] = hashDelete; Hash.prototype.get = hashGet; Hash.prototype.has = hashHas; Hash.prototype.set = hashSet; /** * Removes all key-value entries from the list cache. * * @private * @name clear * @memberOf ListCache */ function listCacheClear() { this.__data__ = []; this.size = 0; } /** * Gets the index at which the `key` is found in `array` of key-value pairs. * * @private * @param {Array} array The array to inspect. * @param {*} key The key to search for. * @returns {number} Returns the index of the matched value, else `-1`. */ function assocIndexOf(array, key) { var length = array.length; while (length--) { if (eq$4(array[length][0], key)) { return length; } } return -1; } /** Used for built-in method references. */ var arrayProto = Array.prototype; /** Built-in value references. */ var splice = arrayProto.splice; /** * Removes `key` and its value from the list cache. * * @private * @name delete * @memberOf ListCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function listCacheDelete(key) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { return false; } var lastIndex = data.length - 1; if (index == lastIndex) { data.pop(); } else { splice.call(data, index, 1); } --this.size; return true; } /** * Gets the list cache value for `key`. * * @private * @name get * @memberOf ListCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function listCacheGet(key) { var data = this.__data__, index = assocIndexOf(data, key); return index < 0 ? undefined : data[index][1]; } /** * Checks if a list cache value for `key` exists. * * @private * @name has * @memberOf ListCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function listCacheHas(key) { return assocIndexOf(this.__data__, key) > -1; } /** * Sets the list cache `key` to `value`. * * @private * @name set * @memberOf ListCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the list cache instance. */ function listCacheSet(key, value) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { ++this.size; data.push([key, value]); } else { data[index][1] = value; } return this; } /** * Creates an list cache object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function ListCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `ListCache`. ListCache.prototype.clear = listCacheClear; ListCache.prototype['delete'] = listCacheDelete; ListCache.prototype.get = listCacheGet; ListCache.prototype.has = listCacheHas; ListCache.prototype.set = listCacheSet; /* Built-in method references that are verified to be native. */ var Map$1 = getNative(root, 'Map'); /** * Removes all key-value entries from the map. * * @private * @name clear * @memberOf MapCache */ function mapCacheClear() { this.size = 0; this.__data__ = { 'hash': new Hash, 'map': new (Map$1 || ListCache), 'string': new Hash }; } /** * Checks if `value` is suitable for use as unique object key. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is suitable, else `false`. */ function isKeyable(value) { var type = typeof value; return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') ? (value !== '__proto__') : (value === null); } /** * Gets the data for `map`. * * @private * @param {Object} map The map to query. * @param {string} key The reference key. * @returns {*} Returns the map data. */ function getMapData(map, key) { var data = map.__data__; return isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map; } /** * Removes `key` and its value from the map. * * @private * @name delete * @memberOf MapCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function mapCacheDelete(key) { var result = getMapData(this, key)['delete'](key); this.size -= result ? 1 : 0; return result; } /** * Gets the map value for `key`. * * @private * @name get * @memberOf MapCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function mapCacheGet(key) { return getMapData(this, key).get(key); } /** * Checks if a map value for `key` exists. * * @private * @name has * @memberOf MapCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function mapCacheHas(key) { return getMapData(this, key).has(key); } /** * Sets the map `key` to `value`. * * @private * @name set * @memberOf MapCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the map cache instance. */ function mapCacheSet(key, value) { var data = getMapData(this, key), size = data.size; data.set(key, value); this.size += data.size == size ? 0 : 1; return this; } /** * Creates a map cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function MapCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `MapCache`. MapCache.prototype.clear = mapCacheClear; MapCache.prototype['delete'] = mapCacheDelete; MapCache.prototype.get = mapCacheGet; MapCache.prototype.has = mapCacheHas; MapCache.prototype.set = mapCacheSet; /** * Converts `value` to a string. An empty string is returned for `null` * and `undefined` values. The sign of `-0` is preserved. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {string} Returns the converted string. * @example * * _.toString(null); * // => '' * * _.toString(-0); * // => '-0' * * _.toString([1, 2, 3]); * // => '1,2,3' */ function toString$2(value) { return value == null ? '' : baseToString(value); } /** * Appends the elements of `values` to `array`. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to append. * @returns {Array} Returns `array`. */ function arrayPush(array, values) { var index = -1, length = values.length, offset = array.length; while (++index < length) { array[offset + index] = values[index]; } return array; } /** Built-in value references. */ var getPrototype$1 = overArg$2(Object.getPrototypeOf, Object); /** * Removes all key-value entries from the stack. * * @private * @name clear * @memberOf Stack */ function stackClear() { this.__data__ = new ListCache; this.size = 0; } /** * Removes `key` and its value from the stack. * * @private * @name delete * @memberOf Stack * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function stackDelete(key) { var data = this.__data__, result = data['delete'](key); this.size = data.size; return result; } /** * Gets the stack value for `key`. * * @private * @name get * @memberOf Stack * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function stackGet(key) { return this.__data__.get(key); } /** * Checks if a stack value for `key` exists. * * @private * @name has * @memberOf Stack * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function stackHas(key) { return this.__data__.has(key); } /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** * Sets the stack `key` to `value`. * * @private * @name set * @memberOf Stack * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the stack cache instance. */ function stackSet(key, value) { var data = this.__data__; if (data instanceof ListCache) { var pairs = data.__data__; if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) { pairs.push([key, value]); this.size = ++data.size; return this; } data = this.__data__ = new MapCache(pairs); } data.set(key, value); this.size = data.size; return this; } /** * Creates a stack cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Stack(entries) { var data = this.__data__ = new ListCache(entries); this.size = data.size; } // Add methods to `Stack`. Stack.prototype.clear = stackClear; Stack.prototype['delete'] = stackDelete; Stack.prototype.get = stackGet; Stack.prototype.has = stackHas; Stack.prototype.set = stackSet; /** * The base implementation of `_.assign` without support for multiple sources * or `customizer` functions. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @returns {Object} Returns `object`. */ function baseAssign(object, source) { return object && copyObject$1(source, keys$3(source), object); } /** * The base implementation of `_.assignIn` without support for multiple sources * or `customizer` functions. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @returns {Object} Returns `object`. */ function baseAssignIn(object, source) { return object && copyObject$1(source, keysIn$1(source), object); } /** Detect free variable `exports`. */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule && freeModule.exports === freeExports; /** Built-in value references. */ var Buffer$9 = moduleExports ? root.Buffer : undefined, allocUnsafe = Buffer$9 ? Buffer$9.allocUnsafe : undefined; /** * Creates a clone of `buffer`. * * @private * @param {Buffer} buffer The buffer to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Buffer} Returns the cloned buffer. */ function cloneBuffer(buffer, isDeep) { if (isDeep) { return buffer.slice(); } var length = buffer.length, result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); buffer.copy(result); return result; } /** * A specialized version of `_.filter` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function arrayFilter(array, predicate) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { result[resIndex++] = value; } } return result; } /** * This method returns a new empty array. * * @static * @memberOf _ * @since 4.13.0 * @category Util * @returns {Array} Returns the new empty array. * @example * * var arrays = _.times(2, _.stubArray); * * console.log(arrays); * // => [[], []] * * console.log(arrays[0] === arrays[1]); * // => false */ function stubArray() { return []; } /** Used for built-in method references. */ var objectProto$a = Object.prototype; /** Built-in value references. */ var propertyIsEnumerable$3 = objectProto$a.propertyIsEnumerable; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeGetSymbols$1 = Object.getOwnPropertySymbols; /** * Creates an array of the own enumerable symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of symbols. */ var getSymbols = !nativeGetSymbols$1 ? stubArray : function(object) { if (object == null) { return []; } object = Object(object); return arrayFilter(nativeGetSymbols$1(object), function(symbol) { return propertyIsEnumerable$3.call(object, symbol); }); }; /** * Copies own symbols of `source` to `object`. * * @private * @param {Object} source The object to copy symbols from. * @param {Object} [object={}] The object to copy symbols to. * @returns {Object} Returns `object`. */ function copySymbols(source, object) { return copyObject$1(source, getSymbols(source), object); } /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeGetSymbols = Object.getOwnPropertySymbols; /** * Creates an array of the own and inherited enumerable symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of symbols. */ var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { var result = []; while (object) { arrayPush(result, getSymbols(object)); object = getPrototype$1(object); } return result; }; /** * Copies own and inherited symbols of `source` to `object`. * * @private * @param {Object} source The object to copy symbols from. * @param {Object} [object={}] The object to copy symbols to. * @returns {Object} Returns `object`. */ function copySymbolsIn(source, object) { return copyObject$1(source, getSymbolsIn(source), object); } /** * The base implementation of `getAllKeys` and `getAllKeysIn` which uses * `keysFunc` and `symbolsFunc` to get the enumerable property names and * symbols of `object`. * * @private * @param {Object} object The object to query. * @param {Function} keysFunc The function to get the keys of `object`. * @param {Function} symbolsFunc The function to get the symbols of `object`. * @returns {Array} Returns the array of property names and symbols. */ function baseGetAllKeys(object, keysFunc, symbolsFunc) { var result = keysFunc(object); return isArray$4(object) ? result : arrayPush(result, symbolsFunc(object)); } /** * Creates an array of own enumerable property names and symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names and symbols. */ function getAllKeys(object) { return baseGetAllKeys(object, keys$3, getSymbols); } /** * Creates an array of own and inherited enumerable property names and * symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names and symbols. */ function getAllKeysIn(object) { return baseGetAllKeys(object, keysIn$1, getSymbolsIn); } /* Built-in method references that are verified to be native. */ var DataView = getNative(root, 'DataView'); /* Built-in method references that are verified to be native. */ var Promise$1 = getNative(root, 'Promise'); /* Built-in method references that are verified to be native. */ var Set$1 = getNative(root, 'Set'); /** `Object#toString` result references. */ var mapTag$3 = '[object Map]', objectTag$2 = '[object Object]', promiseTag = '[object Promise]', setTag$3 = '[object Set]', weakMapTag$1 = '[object WeakMap]'; var dataViewTag$2 = '[object DataView]'; /** Used to detect maps, sets, and weakmaps. */ var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map$1), promiseCtorString = toSource(Promise$1), setCtorString = toSource(Set$1), weakMapCtorString = toSource(WeakMap$1); /** * Gets the `toStringTag` of `value`. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ var getTag = baseGetTag; // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$2) || (Map$1 && getTag(new Map$1) != mapTag$3) || (Promise$1 && getTag(Promise$1.resolve()) != promiseTag) || (Set$1 && getTag(new Set$1) != setTag$3) || (WeakMap$1 && getTag(new WeakMap$1) != weakMapTag$1)) { getTag = function(value) { var result = baseGetTag(value), Ctor = result == objectTag$2 ? value.constructor : undefined, ctorString = Ctor ? toSource(Ctor) : ''; if (ctorString) { switch (ctorString) { case dataViewCtorString: return dataViewTag$2; case mapCtorString: return mapTag$3; case promiseCtorString: return promiseTag; case setCtorString: return setTag$3; case weakMapCtorString: return weakMapTag$1; } } return result; }; } var getTag$1 = getTag; /** Used for built-in method references. */ var objectProto$9 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$4 = objectProto$9.hasOwnProperty; /** * Initializes an array clone. * * @private * @param {Array} array The array to clone. * @returns {Array} Returns the initialized clone. */ function initCloneArray(array) { var length = array.length, result = new array.constructor(length); // Add properties assigned by `RegExp#exec`. if (length && typeof array[0] == 'string' && hasOwnProperty$4.call(array, 'index')) { result.index = array.index; result.input = array.input; } return result; } /** Built-in value references. */ var Uint8Array$1 = root.Uint8Array; /** * Creates a clone of `arrayBuffer`. * * @private * @param {ArrayBuffer} arrayBuffer The array buffer to clone. * @returns {ArrayBuffer} Returns the cloned array buffer. */ function cloneArrayBuffer(arrayBuffer) { var result = new arrayBuffer.constructor(arrayBuffer.byteLength); new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer)); return result; } /** * Creates a clone of `dataView`. * * @private * @param {Object} dataView The data view to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned data view. */ function cloneDataView(dataView, isDeep) { var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); } /** Used to match `RegExp` flags from their coerced string values. */ var reFlags = /\w*$/; /** * Creates a clone of `regexp`. * * @private * @param {Object} regexp The regexp to clone. * @returns {Object} Returns the cloned regexp. */ function cloneRegExp(regexp) { var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); result.lastIndex = regexp.lastIndex; return result; } /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol$2 ? Symbol$2.prototype : undefined, symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; /** * Creates a clone of the `symbol` object. * * @private * @param {Object} symbol The symbol object to clone. * @returns {Object} Returns the cloned symbol object. */ function cloneSymbol(symbol) { return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; } /** * Creates a clone of `typedArray`. * * @private * @param {Object} typedArray The typed array to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned typed array. */ function cloneTypedArray(typedArray, isDeep) { var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); } /** `Object#toString` result references. */ var boolTag$2 = '[object Boolean]', dateTag$1 = '[object Date]', mapTag$2 = '[object Map]', numberTag$2 = '[object Number]', regexpTag$1 = '[object RegExp]', setTag$2 = '[object Set]', stringTag$3 = '[object String]', symbolTag$4 = '[object Symbol]'; var arrayBufferTag$1 = '[object ArrayBuffer]', dataViewTag$1 = '[object DataView]', float32Tag$1 = '[object Float32Array]', float64Tag$1 = '[object Float64Array]', int8Tag$1 = '[object Int8Array]', int16Tag$1 = '[object Int16Array]', int32Tag$1 = '[object Int32Array]', uint8Tag$1 = '[object Uint8Array]', uint8ClampedTag$1 = '[object Uint8ClampedArray]', uint16Tag$1 = '[object Uint16Array]', uint32Tag$1 = '[object Uint32Array]'; /** * Initializes an object clone based on its `toStringTag`. * * **Note:** This function only supports cloning values with tags of * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. * * @private * @param {Object} object The object to clone. * @param {string} tag The `toStringTag` of the object to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the initialized clone. */ function initCloneByTag(object, tag, isDeep) { var Ctor = object.constructor; switch (tag) { case arrayBufferTag$1: return cloneArrayBuffer(object); case boolTag$2: case dateTag$1: return new Ctor(+object); case dataViewTag$1: return cloneDataView(object, isDeep); case float32Tag$1: case float64Tag$1: case int8Tag$1: case int16Tag$1: case int32Tag$1: case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1: return cloneTypedArray(object, isDeep); case mapTag$2: return new Ctor; case numberTag$2: case stringTag$3: return new Ctor(object); case regexpTag$1: return cloneRegExp(object); case setTag$2: return new Ctor; case symbolTag$4: return cloneSymbol(object); } } /** * Initializes an object clone. * * @private * @param {Object} object The object to clone. * @returns {Object} Returns the initialized clone. */ function initCloneObject(object) { return (typeof object.constructor == 'function' && !isPrototype$2(object)) ? baseCreate(getPrototype$1(object)) : {}; } /** `Object#toString` result references. */ var mapTag$1 = '[object Map]'; /** * The base implementation of `_.isMap` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a map, else `false`. */ function baseIsMap(value) { return isObjectLike$a(value) && getTag$1(value) == mapTag$1; } /* Node.js helper references. */ var nodeIsMap = nodeUtil && nodeUtil.isMap; /** * Checks if `value` is classified as a `Map` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a map, else `false`. * @example * * _.isMap(new Map); * // => true * * _.isMap(new WeakMap); * // => false */ var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; /** `Object#toString` result references. */ var setTag$1 = '[object Set]'; /** * The base implementation of `_.isSet` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a set, else `false`. */ function baseIsSet(value) { return isObjectLike$a(value) && getTag$1(value) == setTag$1; } /* Node.js helper references. */ var nodeIsSet = nodeUtil && nodeUtil.isSet; /** * Checks if `value` is classified as a `Set` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a set, else `false`. * @example * * _.isSet(new Set); * // => true * * _.isSet(new WeakSet); * // => false */ var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; /** Used to compose bitmasks for cloning. */ var CLONE_DEEP_FLAG = 1, CLONE_FLAT_FLAG = 2, CLONE_SYMBOLS_FLAG$1 = 4; /** `Object#toString` result references. */ var argsTag$3 = '[object Arguments]', arrayTag = '[object Array]', boolTag$1 = '[object Boolean]', dateTag = '[object Date]', errorTag = '[object Error]', funcTag$3 = '[object Function]', genTag$3 = '[object GeneratorFunction]', mapTag = '[object Map]', numberTag$1 = '[object Number]', objectTag$1 = '[object Object]', regexpTag = '[object RegExp]', setTag = '[object Set]', stringTag$2 = '[object String]', symbolTag$3 = '[object Symbol]', weakMapTag = '[object WeakMap]'; var arrayBufferTag = '[object ArrayBuffer]', dataViewTag = '[object DataView]', float32Tag = '[object Float32Array]', float64Tag = '[object Float64Array]', int8Tag = '[object Int8Array]', int16Tag = '[object Int16Array]', int32Tag = '[object Int32Array]', uint8Tag = '[object Uint8Array]', uint8ClampedTag = '[object Uint8ClampedArray]', uint16Tag = '[object Uint16Array]', uint32Tag = '[object Uint32Array]'; /** Used to identify `toStringTag` values supported by `_.clone`. */ var cloneableTags = {}; cloneableTags[argsTag$3] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = cloneableTags[boolTag$1] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag] = cloneableTags[numberTag$1] = cloneableTags[objectTag$1] = cloneableTags[regexpTag] = cloneableTags[setTag] = cloneableTags[stringTag$2] = cloneableTags[symbolTag$3] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; cloneableTags[errorTag] = cloneableTags[funcTag$3] = cloneableTags[weakMapTag] = false; /** * The base implementation of `_.clone` and `_.cloneDeep` which tracks * traversed objects. * * @private * @param {*} value The value to clone. * @param {boolean} bitmask The bitmask flags. * 1 - Deep clone * 2 - Flatten inherited properties * 4 - Clone symbols * @param {Function} [customizer] The function to customize cloning. * @param {string} [key] The key of `value`. * @param {Object} [object] The parent object of `value`. * @param {Object} [stack] Tracks traversed objects and their clone counterparts. * @returns {*} Returns the cloned value. */ function baseClone(value, bitmask, customizer, key, object, stack) { var result, isDeep = bitmask & CLONE_DEEP_FLAG, isFlat = bitmask & CLONE_FLAT_FLAG, isFull = bitmask & CLONE_SYMBOLS_FLAG$1; if (customizer) { result = object ? customizer(value, key, object, stack) : customizer(value); } if (result !== undefined) { return result; } if (!isObject$8(value)) { return value; } var isArr = isArray$4(value); if (isArr) { result = initCloneArray(value); if (!isDeep) { return copyArray(value, result); } } else { var tag = getTag$1(value), isFunc = tag == funcTag$3 || tag == genTag$3; if (isBuffer(value)) { return cloneBuffer(value, isDeep); } if (tag == objectTag$1 || tag == argsTag$3 || (isFunc && !object)) { result = (isFlat || isFunc) ? {} : initCloneObject(value); if (!isDeep) { return isFlat ? copySymbolsIn(value, baseAssignIn(result, value)) : copySymbols(value, baseAssign(result, value)); } } else { if (!cloneableTags[tag]) { return object ? value : {}; } result = initCloneByTag(value, tag, isDeep); } } // Check for circular references and return its corresponding clone. stack || (stack = new Stack); var stacked = stack.get(value); if (stacked) { return stacked; } stack.set(value, result); if (isSet(value)) { value.forEach(function(subValue) { result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); }); } else if (isMap(value)) { value.forEach(function(subValue, key) { result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); }); } var keysFunc = isFull ? (isFlat ? getAllKeysIn : getAllKeys) : (isFlat ? keysIn$1 : keys$3); var props = isArr ? undefined : keysFunc(value); arrayEach(props || value, function(subValue, key) { if (props) { key = subValue; subValue = value[key]; } // Recursively populate clone (susceptible to call stack limits). assignValue$1(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); }); return result; } /** Used to compose bitmasks for cloning. */ var CLONE_SYMBOLS_FLAG = 4; /** * Creates a shallow clone of `value`. * * **Note:** This method is loosely based on the * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) * and supports cloning arrays, array buffers, booleans, date objects, maps, * numbers, `Object` objects, regexes, sets, strings, symbols, and typed * arrays. The own enumerable properties of `arguments` objects are cloned * as plain objects. An empty object is returned for uncloneable values such * as error objects, functions, DOM nodes, and WeakMaps. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to clone. * @returns {*} Returns the cloned value. * @see _.cloneDeep * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; * * var shallow = _.clone(objects); * console.log(shallow[0] === objects[0]); * // => true */ function clone$7(value) { return baseClone(value, CLONE_SYMBOLS_FLAG); } /* micromustache v8.0.3 */ /** @internal */ /** @internal */ // eslint-disable-next-line @typescript-eslint/unbound-method var numberConstructor = (0).constructor; /** @internal */ // eslint-disable-next-line @typescript-eslint/unbound-method numberConstructor.isFinite; /** @internal */ // eslint-disable-next-line @typescript-eslint/unbound-method numberConstructor.isInteger; /** @internal */ // eslint-disable-next-line @typescript-eslint/unbound-method [].constructor.isArray; /** * @internal * The number of different varNames that will be cached. * If a varName is cached, the actual parsing algorithm will not be called * which significantly improves performance. * However, this cache is size-limited to prevent degrading the user's software * over a period of time. * If the cache is full, we start removing older varNames one at a time. */ var cacheSize = 1000; /** * @internal */ var Cache = /** @class */ (function () { function Cache(size) { this.size = size; this.reset(); } Cache.prototype.reset = function () { this.oldestIndex = 0; this.map = {}; this.cachedKeys = new Array(this.size); }; Cache.prototype.get = function (key) { return this.map[key]; }; Cache.prototype.set = function (key, value) { this.map[key] = value; var oldestKey = this.cachedKeys[this.oldestIndex]; if (oldestKey !== undefined) { delete this.map[oldestKey]; } this.cachedKeys[this.oldestIndex] = key; this.oldestIndex++; this.oldestIndex %= this.size; }; return Cache; }()); /** @internal */ new Cache(cacheSize); var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var error = {exports: {}}; var stringify$4 = function (...args) { try { return JSON.stringify(...args); } catch (err) { return '[Cannot display object: ' + err.message + ']'; } }; (function (module, exports) { const Stringify = stringify$4; module.exports = class extends Error { constructor(args) { const msgs = args .filter((arg) => arg !== '') .map((arg) => { return typeof arg === 'string' ? arg : arg instanceof Error ? arg.message : Stringify(arg); }); super(msgs.join(' ') || 'Unknown error'); if (typeof Error.captureStackTrace === 'function') { // $lab:coverage:ignore$ Error.captureStackTrace(this, exports.assert); } } }; } (error, error.exports)); var errorExports = error.exports; const AssertError = errorExports; var assert$4 = function (condition, ...args) { if (condition) { return; } if (args.length === 1 && args[0] instanceof Error) { throw args[0]; } throw new AssertError(args); }; const Assert$5 = assert$4; const internals$9 = {}; var reach = function (obj, chain, options) { if (chain === false || chain === null || chain === undefined) { return obj; } options = options || {}; if (typeof options === 'string') { options = { separator: options }; } const isChainArray = Array.isArray(chain); Assert$5(!isChainArray || !options.separator, 'Separator option is not valid for array-based chain'); const path = isChainArray ? chain : chain.split(options.separator || '.'); let ref = obj; for (let i = 0; i < path.length; ++i) { let key = path[i]; const type = options.iterables && internals$9.iterables(ref); if (Array.isArray(ref) || type === 'set') { const number = Number(key); if (Number.isInteger(number)) { key = number < 0 ? ref.length + number : number; } } if (!ref || typeof ref === 'function' && options.functions === false || // Defaults to true !type && ref[key] === undefined) { Assert$5(!options.strict || i + 1 === path.length, 'Missing segment', key, 'in reach path ', chain); Assert$5(typeof ref === 'object' || options.functions === true || typeof ref !== 'function', 'Invalid segment', key, 'in reach path ', chain); ref = options.default; break; } if (!type) { ref = ref[key]; } else if (type === 'set') { ref = [...ref][key]; } else { // type === 'map' ref = ref.get(key); } } return ref; }; internals$9.iterables = function (ref) { if (ref instanceof Set) { return 'set'; } if (ref instanceof Map) { return 'map'; } }; var types$5 = {exports: {}}; (function (module, exports) { const internals = {}; exports = module.exports = { array: Array.prototype, buffer: Buffer && Buffer.prototype, // $lab:coverage:ignore$ date: Date.prototype, error: Error.prototype, generic: Object.prototype, map: Map.prototype, promise: Promise.prototype, regex: RegExp.prototype, set: Set.prototype, weakMap: WeakMap.prototype, weakSet: WeakSet.prototype }; internals.typeMap = new Map([ ['[object Error]', exports.error], ['[object Map]', exports.map], ['[object Promise]', exports.promise], ['[object Set]', exports.set], ['[object WeakMap]', exports.weakMap], ['[object WeakSet]', exports.weakSet] ]); exports.getInternalProto = function (obj) { if (Array.isArray(obj)) { return exports.array; } if (Buffer && obj instanceof Buffer) { // $lab:coverage:ignore$ return exports.buffer; } if (obj instanceof Date) { return exports.date; } if (obj instanceof RegExp) { return exports.regex; } if (obj instanceof Error) { return exports.error; } const objName = Object.prototype.toString.call(obj); return internals.typeMap.get(objName) || exports.generic; }; } (types$5, types$5.exports)); var typesExports = types$5.exports; var utils$5 = {}; utils$5.keys = function (obj, options = {}) { return options.symbols !== false ? Reflect.ownKeys(obj) : Object.getOwnPropertyNames(obj); // Defaults to true }; const Reach$1 = reach; const Types$1 = typesExports; const Utils$1 = utils$5; const internals$8 = { needsProtoHack: new Set([Types$1.set, Types$1.map, Types$1.weakSet, Types$1.weakMap]) }; var clone$6 = internals$8.clone = function (obj, options = {}, _seen = null) { if (typeof obj !== 'object' || obj === null) { return obj; } let clone = internals$8.clone; let seen = _seen; if (options.shallow) { if (options.shallow !== true) { return internals$8.cloneWithShallow(obj, options); } clone = (value) => value; } else if (seen) { const lookup = seen.get(obj); if (lookup) { return lookup; } } else { seen = new Map(); } // Built-in object types const baseProto = Types$1.getInternalProto(obj); if (baseProto === Types$1.buffer) { return Buffer && Buffer.from(obj); // $lab:coverage:ignore$ } if (baseProto === Types$1.date) { return new Date(obj.getTime()); } if (baseProto === Types$1.regex) { return new RegExp(obj); } // Generic objects const newObj = internals$8.base(obj, baseProto, options); if (newObj === obj) { return obj; } if (seen) { seen.set(obj, newObj); // Set seen, since obj could recurse } if (baseProto === Types$1.set) { for (const value of obj) { newObj.add(clone(value, options, seen)); } } else if (baseProto === Types$1.map) { for (const [key, value] of obj) { newObj.set(key, clone(value, options, seen)); } } const keys = Utils$1.keys(obj, options); for (const key of keys) { if (key === '__proto__') { continue; } if (baseProto === Types$1.array && key === 'length') { newObj.length = obj.length; continue; } const descriptor = Object.getOwnPropertyDescriptor(obj, key); if (descriptor) { if (descriptor.get || descriptor.set) { Object.defineProperty(newObj, key, descriptor); } else if (descriptor.enumerable) { newObj[key] = clone(obj[key], options, seen); } else { Object.defineProperty(newObj, key, { enumerable: false, writable: true, configurable: true, value: clone(obj[key], options, seen) }); } } else { Object.defineProperty(newObj, key, { enumerable: true, writable: true, configurable: true, value: clone(obj[key], options, seen) }); } } return newObj; }; internals$8.cloneWithShallow = function (source, options) { const keys = options.shallow; options = Object.assign({}, options); options.shallow = false; const seen = new Map(); for (const key of keys) { const ref = Reach$1(source, key); if (typeof ref === 'object' || typeof ref === 'function') { seen.set(ref, ref); } } return internals$8.clone(source, options, seen); }; internals$8.base = function (obj, baseProto, options) { if (options.prototype === false) { // Defaults to true if (internals$8.needsProtoHack.has(baseProto)) { return new baseProto.constructor(); } return baseProto === Types$1.array ? [] : {}; } const proto = Object.getPrototypeOf(obj); if (proto && proto.isImmutable) { return obj; } if (baseProto === Types$1.array) { const newObj = []; if (proto !== baseProto) { Object.setPrototypeOf(newObj, proto); } return newObj; } if (internals$8.needsProtoHack.has(baseProto)) { const newObj = new proto.constructor(); if (proto !== baseProto) { Object.setPrototypeOf(newObj, proto); } return newObj; } return Object.create(proto); }; const internals$7 = {}; var escapeHtml = function (input) { if (!input) { return ''; } let escaped = ''; for (let i = 0; i < input.length; ++i) { const charCode = input.charCodeAt(i); if (internals$7.isSafe(charCode)) { escaped += input[i]; } else { escaped += internals$7.escapeHtmlChar(charCode); } } return escaped; }; internals$7.escapeHtmlChar = function (charCode) { const namedEscape = internals$7.namedHtml.get(charCode); if (namedEscape) { return namedEscape; } if (charCode >= 256) { return '&#' + charCode + ';'; } const hexValue = charCode.toString(16).padStart(2, '0'); return `&#x${hexValue};`; }; internals$7.isSafe = function (charCode) { return internals$7.safeCharCodes.has(charCode); }; internals$7.namedHtml = new Map([ [38, '&'], [60, '<'], [62, '>'], [34, '"'], [160, ' '], [162, '¢'], [163, '£'], [164, '¤'], [169, '©'], [174, '®'] ]); internals$7.safeCharCodes = (function () { const safe = new Set(); for (let i = 32; i < 123; ++i) { if ((i >= 97) || // a-z (i >= 65 && i <= 90) || // A-Z (i >= 48 && i <= 57) || // 0-9 i === 32 || // space i === 46 || // . i === 44 || // , i === 45 || // - i === 58 || // : i === 95) { // _ safe.add(i); } } return safe; }()); var lib$8 = {}; (function (exports) { const internals = { operators: ['!', '^', '*', '/', '%', '+', '-', '<', '<=', '>', '>=', '==', '!=', '&&', '||', '??'], operatorCharacters: ['!', '^', '*', '/', '%', '+', '-', '<', '=', '>', '&', '|', '?'], operatorsOrder: [['^'], ['*', '/', '%'], ['+', '-'], ['<', '<=', '>', '>='], ['==', '!='], ['&&'], ['||', '??']], operatorsPrefix: ['!', 'n'], literals: { '"': '"', '`': '`', '\'': '\'', '[': ']' }, numberRx: /^(?:[0-9]*(\.[0-9]*)?){1}$/, tokenRx: /^[\w\$\#\.\@\:\{\}]+$/, symbol: Symbol('formula'), settings: Symbol('settings') }; exports.Parser = class { constructor(string, options = {}) { if (!options[internals.settings] && options.constants) { for (const constant in options.constants) { const value = options.constants[constant]; if (value !== null && !['boolean', 'number', 'string'].includes(typeof value)) { throw new Error(`Formula constant ${constant} contains invalid ${typeof value} value type`); } } } this.settings = options[internals.settings] ? options : Object.assign({ [internals.settings]: true, constants: {}, functions: {} }, options); this.single = null; this._parts = null; this._parse(string); } _parse(string) { let parts = []; let current = ''; let parenthesis = 0; let literal = false; const flush = (inner) => { if (parenthesis) { throw new Error('Formula missing closing parenthesis'); } const last = parts.length ? parts[parts.length - 1] : null; if (!literal && !current && !inner) { return; } if (last && last.type === 'reference' && inner === ')') { // Function last.type = 'function'; last.value = this._subFormula(current, last.value); current = ''; return; } if (inner === ')') { // Segment const sub = new exports.Parser(current, this.settings); parts.push({ type: 'segment', value: sub }); } else if (literal) { if (literal === ']') { // Reference parts.push({ type: 'reference', value: current }); current = ''; return; } parts.push({ type: 'literal', value: current }); // Literal } else if (internals.operatorCharacters.includes(current)) { // Operator if (last && last.type === 'operator' && internals.operators.includes(last.value + current)) { // 2 characters operator last.value += current; } else { parts.push({ type: 'operator', value: current }); } } else if (current.match(internals.numberRx)) { // Number parts.push({ type: 'constant', value: parseFloat(current) }); } else if (this.settings.constants[current] !== undefined) { // Constant parts.push({ type: 'constant', value: this.settings.constants[current] }); } else { // Reference if (!current.match(internals.tokenRx)) { throw new Error(`Formula contains invalid token: ${current}`); } parts.push({ type: 'reference', value: current }); } current = ''; }; for (const c of string) { if (literal) { if (c === literal) { flush(); literal = false; } else { current += c; } } else if (parenthesis) { if (c === '(') { current += c; ++parenthesis; } else if (c === ')') { --parenthesis; if (!parenthesis) { flush(c); } else { current += c; } } else { current += c; } } else if (c in internals.literals) { literal = internals.literals[c]; } else if (c === '(') { flush(); ++parenthesis; } else if (internals.operatorCharacters.includes(c)) { flush(); current = c; flush(); } else if (c !== ' ') { current += c; } else { flush(); } } flush(); // Replace prefix - to internal negative operator parts = parts.map((part, i) => { if (part.type !== 'operator' || part.value !== '-' || i && parts[i - 1].type !== 'operator') { return part; } return { type: 'operator', value: 'n' }; }); // Validate tokens order let operator = false; for (const part of parts) { if (part.type === 'operator') { if (internals.operatorsPrefix.includes(part.value)) { continue; } if (!operator) { throw new Error('Formula contains an operator in invalid position'); } if (!internals.operators.includes(part.value)) { throw new Error(`Formula contains an unknown operator ${part.value}`); } } else if (operator) { throw new Error('Formula missing expected operator'); } operator = !operator; } if (!operator) { throw new Error('Formula contains invalid trailing operator'); } // Identify single part if (parts.length === 1 && ['reference', 'literal', 'constant'].includes(parts[0].type)) { this.single = { type: parts[0].type === 'reference' ? 'reference' : 'value', value: parts[0].value }; } // Process parts this._parts = parts.map((part) => { // Operators if (part.type === 'operator') { return internals.operatorsPrefix.includes(part.value) ? part : part.value; } // Literals, constants, segments if (part.type !== 'reference') { return part.value; } // References if (this.settings.tokenRx && !this.settings.tokenRx.test(part.value)) { throw new Error(`Formula contains invalid reference ${part.value}`); } if (this.settings.reference) { return this.settings.reference(part.value); } return internals.reference(part.value); }); } _subFormula(string, name) { const method = this.settings.functions[name]; if (typeof method !== 'function') { throw new Error(`Formula contains unknown function ${name}`); } let args = []; if (string) { let current = ''; let parenthesis = 0; let literal = false; const flush = () => { if (!current) { throw new Error(`Formula contains function ${name} with invalid arguments ${string}`); } args.push(current); current = ''; }; for (let i = 0; i < string.length; ++i) { const c = string[i]; if (literal) { current += c; if (c === literal) { literal = false; } } else if (c in internals.literals && !parenthesis) { current += c; literal = internals.literals[c]; } else if (c === ',' && !parenthesis) { flush(); } else { current += c; if (c === '(') { ++parenthesis; } else if (c === ')') { --parenthesis; } } } flush(); } args = args.map((arg) => new exports.Parser(arg, this.settings)); return function (context) { const innerValues = []; for (const arg of args) { innerValues.push(arg.evaluate(context)); } return method.call(context, ...innerValues); }; } evaluate(context) { const parts = this._parts.slice(); // Prefix operators for (let i = parts.length - 2; i >= 0; --i) { const part = parts[i]; if (part && part.type === 'operator') { const current = parts[i + 1]; parts.splice(i + 1, 1); const value = internals.evaluate(current, context); parts[i] = internals.single(part.value, value); } } // Left-right operators internals.operatorsOrder.forEach((set) => { for (let i = 1; i < parts.length - 1;) { if (set.includes(parts[i])) { const operator = parts[i]; const left = internals.evaluate(parts[i - 1], context); const right = internals.evaluate(parts[i + 1], context); parts.splice(i, 2); const result = internals.calculate(operator, left, right); parts[i - 1] = result === 0 ? 0 : result; // Convert -0 } else { i += 2; } } }); return internals.evaluate(parts[0], context); } }; exports.Parser.prototype[internals.symbol] = true; internals.reference = function (name) { return function (context) { return context && context[name] !== undefined ? context[name] : null; }; }; internals.evaluate = function (part, context) { if (part === null) { return null; } if (typeof part === 'function') { return part(context); } if (part[internals.symbol]) { return part.evaluate(context); } return part; }; internals.single = function (operator, value) { if (operator === '!') { return value ? false : true; } // operator === 'n' const negative = -value; if (negative === 0) { // Override -0 return 0; } return negative; }; internals.calculate = function (operator, left, right) { if (operator === '??') { return internals.exists(left) ? left : right; } if (typeof left === 'string' || typeof right === 'string') { if (operator === '+') { left = internals.exists(left) ? left : ''; right = internals.exists(right) ? right : ''; return left + right; } } else { switch (operator) { case '^': return Math.pow(left, right); case '*': return left * right; case '/': return left / right; case '%': return left % right; case '+': return left + right; case '-': return left - right; } } switch (operator) { case '<': return left < right; case '<=': return left <= right; case '>': return left > right; case '>=': return left >= right; case '==': return left === right; case '!=': return left !== right; case '&&': return left && right; case '||': return left || right; } return null; }; internals.exists = function (value) { return value !== null && value !== undefined; }; } (lib$8)); const Types = typesExports; const internals$6 = { mismatched: null }; var deepEqual = function (obj, ref, options) { options = Object.assign({ prototype: true }, options); return !!internals$6.isDeepEqual(obj, ref, options, []); }; internals$6.isDeepEqual = function (obj, ref, options, seen) { if (obj === ref) { // Copied from Deep-eql, copyright(c) 2013 Jake Luer, jake@alogicalparadox.com, MIT Licensed, https://github.com/chaijs/deep-eql return obj !== 0 || 1 / obj === 1 / ref; } const type = typeof obj; if (type !== typeof ref) { return false; } if (obj === null || ref === null) { return false; } if (type === 'function') { if (!options.deepFunction || obj.toString() !== ref.toString()) { return false; } // Continue as object } else if (type !== 'object') { return obj !== obj && ref !== ref; // NaN } const instanceType = internals$6.getSharedType(obj, ref, !!options.prototype); switch (instanceType) { case Types.buffer: return Buffer && Buffer.prototype.equals.call(obj, ref); // $lab:coverage:ignore$ case Types.promise: return obj === ref; case Types.regex: return obj.toString() === ref.toString(); case internals$6.mismatched: return false; } for (let i = seen.length - 1; i >= 0; --i) { if (seen[i].isSame(obj, ref)) { return true; // If previous comparison failed, it would have stopped execution } } seen.push(new internals$6.SeenEntry(obj, ref)); try { return !!internals$6.isDeepEqualObj(instanceType, obj, ref, options, seen); } finally { seen.pop(); } }; internals$6.getSharedType = function (obj, ref, checkPrototype) { if (checkPrototype) { if (Object.getPrototypeOf(obj) !== Object.getPrototypeOf(ref)) { return internals$6.mismatched; } return Types.getInternalProto(obj); } const type = Types.getInternalProto(obj); if (type !== Types.getInternalProto(ref)) { return internals$6.mismatched; } return type; }; internals$6.valueOf = function (obj) { const objValueOf = obj.valueOf; if (objValueOf === undefined) { return obj; } try { return objValueOf.call(obj); } catch (err) { return err; } }; internals$6.hasOwnEnumerableProperty = function (obj, key) { return Object.prototype.propertyIsEnumerable.call(obj, key); }; internals$6.isSetSimpleEqual = function (obj, ref) { for (const entry of Set.prototype.values.call(obj)) { if (!Set.prototype.has.call(ref, entry)) { return false; } } return true; }; internals$6.isDeepEqualObj = function (instanceType, obj, ref, options, seen) { const { isDeepEqual, valueOf, hasOwnEnumerableProperty } = internals$6; const { keys, getOwnPropertySymbols } = Object; if (instanceType === Types.array) { if (options.part) { // Check if any index match any other index for (const objValue of obj) { for (const refValue of ref) { if (isDeepEqual(objValue, refValue, options, seen)) { return true; } } } } else { if (obj.length !== ref.length) { return false; } for (let i = 0; i < obj.length; ++i) { if (!isDeepEqual(obj[i], ref[i], options, seen)) { return false; } } return true; } } else if (instanceType === Types.set) { if (obj.size !== ref.size) { return false; } if (!internals$6.isSetSimpleEqual(obj, ref)) { // Check for deep equality const ref2 = new Set(Set.prototype.values.call(ref)); for (const objEntry of Set.prototype.values.call(obj)) { if (ref2.delete(objEntry)) { continue; } let found = false; for (const refEntry of ref2) { if (isDeepEqual(objEntry, refEntry, options, seen)) { ref2.delete(refEntry); found = true; break; } } if (!found) { return false; } } } } else if (instanceType === Types.map) { if (obj.size !== ref.size) { return false; } for (const [key, value] of Map.prototype.entries.call(obj)) { if (value === undefined && !Map.prototype.has.call(ref, key)) { return false; } if (!isDeepEqual(value, Map.prototype.get.call(ref, key), options, seen)) { return false; } } } else if (instanceType === Types.error) { // Always check name and message if (obj.name !== ref.name || obj.message !== ref.message) { return false; } } // Check .valueOf() const valueOfObj = valueOf(obj); const valueOfRef = valueOf(ref); if ((obj !== valueOfObj || ref !== valueOfRef) && !isDeepEqual(valueOfObj, valueOfRef, options, seen)) { return false; } // Check properties const objKeys = keys(obj); if (!options.part && objKeys.length !== keys(ref).length && !options.skip) { return false; } let skipped = 0; for (const key of objKeys) { if (options.skip && options.skip.includes(key)) { if (ref[key] === undefined) { ++skipped; } continue; } if (!hasOwnEnumerableProperty(ref, key)) { return false; } if (!isDeepEqual(obj[key], ref[key], options, seen)) { return false; } } if (!options.part && objKeys.length - skipped !== keys(ref).length) { return false; } // Check symbols if (options.symbols !== false) { // Defaults to true const objSymbols = getOwnPropertySymbols(obj); const refSymbols = new Set(getOwnPropertySymbols(ref)); for (const key of objSymbols) { if (!options.skip || !options.skip.includes(key)) { if (hasOwnEnumerableProperty(obj, key)) { if (!hasOwnEnumerableProperty(ref, key)) { return false; } if (!isDeepEqual(obj[key], ref[key], options, seen)) { return false; } } else if (hasOwnEnumerableProperty(ref, key)) { return false; } } refSymbols.delete(key); } for (const key of refSymbols) { if (hasOwnEnumerableProperty(ref, key)) { return false; } } } return true; }; internals$6.SeenEntry = class { constructor(obj, ref) { this.obj = obj; this.ref = ref; } isSame(obj, ref) { return this.obj === obj && this.ref === ref; } }; var lib$7 = {}; lib$7.location = function (depth = 0) { const orig = Error.prepareStackTrace; Error.prepareStackTrace = (ignore, stack) => stack; const capture = {}; Error.captureStackTrace(capture, this); const line = capture.stack[depth + 1]; Error.prepareStackTrace = orig; return { filename: line.getFileName(), line: line.getLineNumber() }; }; const Assert$4 = assert$4; const Clone$1 = clone$6; const Utils = utils$5; const internals$5 = {}; var merge$3 = internals$5.merge = function (target, source, options) { Assert$4(target && typeof target === 'object', 'Invalid target value: must be an object'); Assert$4(source === null || source === undefined || typeof source === 'object', 'Invalid source value: must be null, undefined, or an object'); if (!source) { return target; } options = Object.assign({ nullOverride: true, mergeArrays: true }, options); if (Array.isArray(source)) { Assert$4(Array.isArray(target), 'Cannot merge array onto an object'); if (!options.mergeArrays) { target.length = 0; // Must not change target assignment } for (let i = 0; i < source.length; ++i) { target.push(Clone$1(source[i], { symbols: options.symbols })); } return target; } const keys = Utils.keys(source, options); for (let i = 0; i < keys.length; ++i) { const key = keys[i]; if (key === '__proto__' || !Object.prototype.propertyIsEnumerable.call(source, key)) { continue; } const value = source[key]; if (value && typeof value === 'object') { if (target[key] === value) { continue; // Can occur for shallow merges } if (!target[key] || typeof target[key] !== 'object' || (Array.isArray(target[key]) !== Array.isArray(value)) || value instanceof Date || (Buffer && Buffer.isBuffer(value)) || // $lab:coverage:ignore$ value instanceof RegExp) { target[key] = Clone$1(value, { symbols: options.symbols }); } else { internals$5.merge(target[key], value, options); } } else { if (value !== null && value !== undefined) { // Explicit to preserve empty strings target[key] = value; } else if (options.nullOverride) { target[key] = value; } } } return target; }; var ignore = function () { }; const Assert$3 = assert$4; const Clone = clone$6; const Merge = merge$3; const Reach = reach; const internals$4 = {}; var applyToDefaults = function (defaults, source, options = {}) { Assert$3(defaults && typeof defaults === 'object', 'Invalid defaults value: must be an object'); Assert$3(!source || source === true || typeof source === 'object', 'Invalid source value: must be true, falsy or an object'); Assert$3(typeof options === 'object', 'Invalid options: must be an object'); if (!source) { // If no source, return null return null; } if (options.shallow) { return internals$4.applyToDefaultsWithShallow(defaults, source, options); } const copy = Clone(defaults); if (source === true) { // If source is set to true, use defaults return copy; } const nullOverride = options.nullOverride !== undefined ? options.nullOverride : false; return Merge(copy, source, { nullOverride, mergeArrays: false }); }; internals$4.applyToDefaultsWithShallow = function (defaults, source, options) { const keys = options.shallow; Assert$3(Array.isArray(keys), 'Invalid keys'); const seen = new Map(); const merge = source === true ? null : new Set(); for (let key of keys) { key = Array.isArray(key) ? key : key.split('.'); // Pre-split optimization const ref = Reach(defaults, key); if (ref && typeof ref === 'object') { seen.set(ref, merge && Reach(source, key) || ref); } else if (merge) { merge.add(key); } } const copy = Clone(defaults, {}, seen); if (!merge) { return copy; } for (const key of merge) { internals$4.reachCopy(copy, source, key); } const nullOverride = options.nullOverride !== undefined ? options.nullOverride : false; return Merge(copy, source, { nullOverride, mergeArrays: false }); }; internals$4.reachCopy = function (dst, src, path) { for (const segment of path) { if (!(segment in src)) { return; } const val = src[segment]; if (typeof val !== 'object' || val === null) { return; } src = val; } const value = src; let ref = dst; for (let i = 0; i < path.length - 1; ++i) { const segment = path[i]; if (typeof ref[segment] !== 'object') { ref[segment] = {}; } ref = ref[segment]; } ref[path[path.length - 1]] = value; }; var lib$6 = {}; const Assert$2 = assert$4; const internals$3 = {}; lib$6.Sorter = class { constructor() { this._items = []; this.nodes = []; } add(nodes, options) { options = options || {}; // Validate rules const before = [].concat(options.before || []); const after = [].concat(options.after || []); const group = options.group || '?'; const sort = options.sort || 0; // Used for merging only Assert$2(!before.includes(group), `Item cannot come before itself: ${group}`); Assert$2(!before.includes('?'), 'Item cannot come before unassociated items'); Assert$2(!after.includes(group), `Item cannot come after itself: ${group}`); Assert$2(!after.includes('?'), 'Item cannot come after unassociated items'); if (!Array.isArray(nodes)) { nodes = [nodes]; } for (const node of nodes) { const item = { seq: this._items.length, sort, before, after, group, node }; this._items.push(item); } // Insert event if (!options.manual) { const valid = this._sort(); Assert$2(valid, 'item', group !== '?' ? `added into group ${group}` : '', 'created a dependencies error'); } return this.nodes; } merge(others) { if (!Array.isArray(others)) { others = [others]; } for (const other of others) { if (other) { for (const item of other._items) { this._items.push(Object.assign({}, item)); // Shallow cloned } } } // Sort items this._items.sort(internals$3.mergeSort); for (let i = 0; i < this._items.length; ++i) { this._items[i].seq = i; } const valid = this._sort(); Assert$2(valid, 'merge created a dependencies error'); return this.nodes; } sort() { const valid = this._sort(); Assert$2(valid, 'sort created a dependencies error'); return this.nodes; } _sort() { // Construct graph const graph = {}; const graphAfters = Object.create(null); // A prototype can bungle lookups w/ false positives const groups = Object.create(null); for (const item of this._items) { const seq = item.seq; // Unique across all items const group = item.group; // Determine Groups groups[group] = groups[group] || []; groups[group].push(seq); // Build intermediary graph using 'before' graph[seq] = item.before; // Build second intermediary graph with 'after' for (const after of item.after) { graphAfters[after] = graphAfters[after] || []; graphAfters[after].push(seq); } } // Expand intermediary graph for (const node in graph) { const expandedGroups = []; for (const graphNodeItem in graph[node]) { const group = graph[node][graphNodeItem]; groups[group] = groups[group] || []; expandedGroups.push(...groups[group]); } graph[node] = expandedGroups; } // Merge intermediary graph using graphAfters into final graph for (const group in graphAfters) { if (groups[group]) { for (const node of groups[group]) { graph[node].push(...graphAfters[group]); } } } // Compile ancestors const ancestors = {}; for (const node in graph) { const children = graph[node]; for (const child of children) { ancestors[child] = ancestors[child] || []; ancestors[child].push(node); } } // Topo sort const visited = {}; const sorted = []; for (let i = 0; i < this._items.length; ++i) { // Looping through item.seq values out of order let next = i; if (ancestors[i]) { next = null; for (let j = 0; j < this._items.length; ++j) { // As above, these are item.seq values if (visited[j] === true) { continue; } if (!ancestors[j]) { ancestors[j] = []; } const shouldSeeCount = ancestors[j].length; let seenCount = 0; for (let k = 0; k < shouldSeeCount; ++k) { if (visited[ancestors[j][k]]) { ++seenCount; } } if (seenCount === shouldSeeCount) { next = j; break; } } } if (next !== null) { visited[next] = true; sorted.push(next); } } if (sorted.length !== this._items.length) { return false; } const seqIndex = {}; for (const item of this._items) { seqIndex[item.seq] = item; } this._items = []; this.nodes = []; for (const value of sorted) { const sortedItem = seqIndex[value]; this.nodes.push(sortedItem.node); this._items.push(sortedItem); } return true; } }; internals$3.mergeSort = (a, b) => { return a.sort === b.sort ? 0 : (a.sort < b.sort ? -1 : 1); }; var domain = {}; var errors$7 = {}; (function (exports) { exports.codes = { EMPTY_STRING: 'Address must be a non-empty string', FORBIDDEN_UNICODE: 'Address contains forbidden Unicode characters', MULTIPLE_AT_CHAR: 'Address cannot contain more than one @ character', MISSING_AT_CHAR: 'Address must contain one @ character', EMPTY_LOCAL: 'Address local part cannot be empty', ADDRESS_TOO_LONG: 'Address too long', LOCAL_TOO_LONG: 'Address local part too long', EMPTY_LOCAL_SEGMENT: 'Address local part contains empty dot-separated segment', INVALID_LOCAL_CHARS: 'Address local part contains invalid character', DOMAIN_NON_EMPTY_STRING: 'Domain must be a non-empty string', DOMAIN_TOO_LONG: 'Domain too long', DOMAIN_INVALID_UNICODE_CHARS: 'Domain contains forbidden Unicode characters', DOMAIN_INVALID_CHARS: 'Domain contains invalid character', DOMAIN_INVALID_TLDS_CHARS: 'Domain contains invalid tld character', DOMAIN_SEGMENTS_COUNT: 'Domain lacks the minimum required number of segments', DOMAIN_SEGMENTS_COUNT_MAX: 'Domain contains too many segments', DOMAIN_FORBIDDEN_TLDS: 'Domain uses forbidden TLD', DOMAIN_EMPTY_SEGMENT: 'Domain contains empty dot-separated segment', DOMAIN_LONG_SEGMENT: 'Domain contains dot-separated segment that is too long' }; exports.code = function (code) { return { code, error: exports.codes[code] }; }; } (errors$7)); (function (exports) { const Url = require$$0$1; const Errors = errors$7; const internals = { minDomainSegments: 2, nonAsciiRx: /[^\x00-\x7f]/, domainControlRx: /[\x00-\x20@\:\/\\#!\$&\'\(\)\*\+,;=\?]/, // Control + space + separators tldSegmentRx: /^[a-zA-Z](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$/, domainSegmentRx: /^[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$/, URL: Url.URL || URL // $lab:coverage:ignore$ }; exports.analyze = function (domain, options = {}) { if (!domain) { // Catch null / undefined return Errors.code('DOMAIN_NON_EMPTY_STRING'); } if (typeof domain !== 'string') { throw new Error('Invalid input: domain must be a string'); } if (domain.length > 256) { return Errors.code('DOMAIN_TOO_LONG'); } const ascii = !internals.nonAsciiRx.test(domain); if (!ascii) { if (options.allowUnicode === false) { // Defaults to true return Errors.code('DOMAIN_INVALID_UNICODE_CHARS'); } domain = domain.normalize('NFC'); } if (internals.domainControlRx.test(domain)) { return Errors.code('DOMAIN_INVALID_CHARS'); } domain = internals.punycode(domain); // https://tools.ietf.org/html/rfc1035 section 2.3.1 if (options.allowFullyQualified && domain[domain.length - 1] === '.') { domain = domain.slice(0, -1); } const minDomainSegments = options.minDomainSegments || internals.minDomainSegments; const segments = domain.split('.'); if (segments.length < minDomainSegments) { return Errors.code('DOMAIN_SEGMENTS_COUNT'); } if (options.maxDomainSegments) { if (segments.length > options.maxDomainSegments) { return Errors.code('DOMAIN_SEGMENTS_COUNT_MAX'); } } const tlds = options.tlds; if (tlds) { const tld = segments[segments.length - 1].toLowerCase(); if (tlds.deny && tlds.deny.has(tld) || tlds.allow && !tlds.allow.has(tld)) { return Errors.code('DOMAIN_FORBIDDEN_TLDS'); } } for (let i = 0; i < segments.length; ++i) { const segment = segments[i]; if (!segment.length) { return Errors.code('DOMAIN_EMPTY_SEGMENT'); } if (segment.length > 63) { return Errors.code('DOMAIN_LONG_SEGMENT'); } if (i < segments.length - 1) { if (!internals.domainSegmentRx.test(segment)) { return Errors.code('DOMAIN_INVALID_CHARS'); } } else { if (!internals.tldSegmentRx.test(segment)) { return Errors.code('DOMAIN_INVALID_TLDS_CHARS'); } } } return null; }; exports.isValid = function (domain, options) { return !exports.analyze(domain, options); }; internals.punycode = function (domain) { if (domain.includes('%')) { domain = domain.replace(/%/g, '%25'); } try { return new internals.URL(`http://${domain}`).host; } catch (err) { return domain; } }; } (domain)); var email = {}; const Util = require$$1; const Domain = domain; const Errors$1 = errors$7; const internals$2 = { nonAsciiRx: /[^\x00-\x7f]/, encoder: new (Util.TextEncoder || TextEncoder)() // $lab:coverage:ignore$ }; email.analyze = function (email, options) { return internals$2.email(email, options); }; email.isValid = function (email, options) { return !internals$2.email(email, options); }; internals$2.email = function (email, options = {}) { if (typeof email !== 'string') { throw new Error('Invalid input: email must be a string'); } if (!email) { return Errors$1.code('EMPTY_STRING'); } // Unicode const ascii = !internals$2.nonAsciiRx.test(email); if (!ascii) { if (options.allowUnicode === false) { // Defaults to true return Errors$1.code('FORBIDDEN_UNICODE'); } email = email.normalize('NFC'); } // Basic structure const parts = email.split('@'); if (parts.length !== 2) { return parts.length > 2 ? Errors$1.code('MULTIPLE_AT_CHAR') : Errors$1.code('MISSING_AT_CHAR'); } const [local, domain] = parts; if (!local) { return Errors$1.code('EMPTY_LOCAL'); } if (!options.ignoreLength) { if (email.length > 254) { // http://tools.ietf.org/html/rfc5321#section-4.5.3.1.3 return Errors$1.code('ADDRESS_TOO_LONG'); } if (internals$2.encoder.encode(local).length > 64) { // http://tools.ietf.org/html/rfc5321#section-4.5.3.1.1 return Errors$1.code('LOCAL_TOO_LONG'); } } // Validate parts return internals$2.local(local, ascii) || Domain.analyze(domain, options); }; internals$2.local = function (local, ascii) { const segments = local.split('.'); for (const segment of segments) { if (!segment.length) { return Errors$1.code('EMPTY_LOCAL_SEGMENT'); } if (ascii) { if (!internals$2.atextRx.test(segment)) { return Errors$1.code('INVALID_LOCAL_CHARS'); } continue; } for (const char of segment) { if (internals$2.atextRx.test(char)) { continue; } const binary = internals$2.binary(char); if (!internals$2.atomRx.test(binary)) { return Errors$1.code('INVALID_LOCAL_CHARS'); } } } }; internals$2.binary = function (char) { return Array.from(internals$2.encoder.encode(char)).map((v) => String.fromCharCode(v)).join(''); }; /* From RFC 5321: Mailbox = Local-part "@" ( Domain / address-literal ) Local-part = Dot-string / Quoted-string Dot-string = Atom *("." Atom) Atom = 1*atext atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" Domain = sub-domain *("." sub-domain) sub-domain = Let-dig [Ldh-str] Let-dig = ALPHA / DIGIT Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig ALPHA = %x41-5A / %x61-7A ; a-z, A-Z DIGIT = %x30-39 ; 0-9 From RFC 6531: sub-domain =/ U-label atext =/ UTF8-non-ascii UTF8-non-ascii = UTF8-2 / UTF8-3 / UTF8-4 UTF8-2 = %xC2-DF UTF8-tail UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail ) UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / %xF4 %x80-8F 2( UTF8-tail ) UTF8-tail = %x80-BF Note: The following are not supported: RFC 5321: address-literal, Quoted-string RFC 5322: obs-*, CFWS */ internals$2.atextRx = /^[\w!#\$%&'\*\+\-/=\?\^`\{\|\}~]+$/; // _ included in \w internals$2.atomRx = new RegExp([ // %xC2-DF UTF8-tail '(?:[\\xc2-\\xdf][\\x80-\\xbf])', // %xE0 %xA0-BF UTF8-tail %xE1-EC 2( UTF8-tail ) %xED %x80-9F UTF8-tail %xEE-EF 2( UTF8-tail ) '(?:\\xe0[\\xa0-\\xbf][\\x80-\\xbf])|(?:[\\xe1-\\xec][\\x80-\\xbf]{2})|(?:\\xed[\\x80-\\x9f][\\x80-\\xbf])|(?:[\\xee-\\xef][\\x80-\\xbf]{2})', // %xF0 %x90-BF 2( UTF8-tail ) %xF1-F3 3( UTF8-tail ) %xF4 %x80-8F 2( UTF8-tail ) '(?:\\xf0[\\x90-\\xbf][\\x80-\\xbf]{2})|(?:[\\xf1-\\xf3][\\x80-\\xbf]{3})|(?:\\xf4[\\x80-\\x8f][\\x80-\\xbf]{2})' ].join('|')); var ip = {}; var uri = {}; var escapeRegex = function (string) { // Escape ^$.*+-?=!:|\/()[]{}, return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&'); }; const Assert$1 = assert$4; const EscapeRegex = escapeRegex; const internals$1 = {}; internals$1.generate = function () { const rfc3986 = {}; const hexDigit = '\\dA-Fa-f'; // HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" const hexDigitOnly = '[' + hexDigit + ']'; const unreserved = '\\w-\\.~'; // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" const subDelims = '!\\$&\'\\(\\)\\*\\+,;='; // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" const pctEncoded = '%' + hexDigit; // pct-encoded = "%" HEXDIG HEXDIG const pchar = unreserved + pctEncoded + subDelims + ':@'; // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" const pcharOnly = '[' + pchar + ']'; const decOctect = '(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])'; // dec-octet = DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 DIGIT / "25" %x30-35 ; 0-9 / 10-99 / 100-199 / 200-249 / 250-255 rfc3986.ipv4address = '(?:' + decOctect + '\\.){3}' + decOctect; // IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet /* h16 = 1*4HEXDIG ; 16 bits of address represented in hexadecimal ls32 = ( h16 ":" h16 ) / IPv4address ; least-significant 32 bits of address IPv6address = 6( h16 ":" ) ls32 / "::" 5( h16 ":" ) ls32 / [ h16 ] "::" 4( h16 ":" ) ls32 / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 / [ *4( h16 ":" ) h16 ] "::" ls32 / [ *5( h16 ":" ) h16 ] "::" h16 / [ *6( h16 ":" ) h16 ] "::" */ const h16 = hexDigitOnly + '{1,4}'; const ls32 = '(?:' + h16 + ':' + h16 + '|' + rfc3986.ipv4address + ')'; const IPv6SixHex = '(?:' + h16 + ':){6}' + ls32; const IPv6FiveHex = '::(?:' + h16 + ':){5}' + ls32; const IPv6FourHex = '(?:' + h16 + ')?::(?:' + h16 + ':){4}' + ls32; const IPv6ThreeHex = '(?:(?:' + h16 + ':){0,1}' + h16 + ')?::(?:' + h16 + ':){3}' + ls32; const IPv6TwoHex = '(?:(?:' + h16 + ':){0,2}' + h16 + ')?::(?:' + h16 + ':){2}' + ls32; const IPv6OneHex = '(?:(?:' + h16 + ':){0,3}' + h16 + ')?::' + h16 + ':' + ls32; const IPv6NoneHex = '(?:(?:' + h16 + ':){0,4}' + h16 + ')?::' + ls32; const IPv6NoneHex2 = '(?:(?:' + h16 + ':){0,5}' + h16 + ')?::' + h16; const IPv6NoneHex3 = '(?:(?:' + h16 + ':){0,6}' + h16 + ')?::'; rfc3986.ipv4Cidr = '(?:\\d|[1-2]\\d|3[0-2])'; // IPv4 cidr = DIGIT / %x31-32 DIGIT / "3" %x30-32 ; 0-9 / 10-29 / 30-32 rfc3986.ipv6Cidr = '(?:0{0,2}\\d|0?[1-9]\\d|1[01]\\d|12[0-8])'; // IPv6 cidr = DIGIT / %x31-39 DIGIT / "1" %x0-1 DIGIT / "12" %x0-8; 0-9 / 10-99 / 100-119 / 120-128 rfc3986.ipv6address = '(?:' + IPv6SixHex + '|' + IPv6FiveHex + '|' + IPv6FourHex + '|' + IPv6ThreeHex + '|' + IPv6TwoHex + '|' + IPv6OneHex + '|' + IPv6NoneHex + '|' + IPv6NoneHex2 + '|' + IPv6NoneHex3 + ')'; rfc3986.ipvFuture = 'v' + hexDigitOnly + '+\\.[' + unreserved + subDelims + ':]+'; // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) rfc3986.scheme = '[a-zA-Z][a-zA-Z\\d+-\\.]*'; // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) rfc3986.schemeRegex = new RegExp(rfc3986.scheme); const userinfo = '[' + unreserved + pctEncoded + subDelims + ':]*'; // userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) const IPLiteral = '\\[(?:' + rfc3986.ipv6address + '|' + rfc3986.ipvFuture + ')\\]'; // IP-literal = "[" ( IPv6address / IPvFuture ) "]" const regName = '[' + unreserved + pctEncoded + subDelims + ']{1,255}'; // reg-name = *( unreserved / pct-encoded / sub-delims ) const host = '(?:' + IPLiteral + '|' + rfc3986.ipv4address + '|' + regName + ')'; // host = IP-literal / IPv4address / reg-name const port = '\\d*'; // port = *DIGIT const authority = '(?:' + userinfo + '@)?' + host + '(?::' + port + ')?'; // authority = [ userinfo "@" ] host [ ":" port ] const authorityCapture = '(?:' + userinfo + '@)?(' + host + ')(?::' + port + ')?'; /* segment = *pchar segment-nz = 1*pchar path = path-abempty ; begins with "/" '|' is empty / path-absolute ; begins with "/" but not "//" / path-noscheme ; begins with a non-colon segment / path-rootless ; begins with a segment / path-empty ; zero characters path-abempty = *( "/" segment ) path-absolute = "/" [ segment-nz *( "/" segment ) ] path-rootless = segment-nz *( "/" segment ) */ const segment = pcharOnly + '*'; const segmentNz = pcharOnly + '+'; const segmentNzNc = '[' + unreserved + pctEncoded + subDelims + '@' + ']+'; const pathEmpty = ''; const pathAbEmpty = '(?:\\/' + segment + ')*'; const pathAbsolute = '\\/(?:' + segmentNz + pathAbEmpty + ')?'; const pathRootless = segmentNz + pathAbEmpty; const pathNoScheme = segmentNzNc + pathAbEmpty; const pathAbNoAuthority = '(?:\\/\\/\\/' + segment + pathAbEmpty + ')'; // Used by file:/// // hier-part = "//" authority path rfc3986.hierPart = '(?:' + '(?:\\/\\/' + authority + pathAbEmpty + ')' + '|' + pathAbsolute + '|' + pathRootless + '|' + pathAbNoAuthority + ')'; rfc3986.hierPartCapture = '(?:' + '(?:\\/\\/' + authorityCapture + pathAbEmpty + ')' + '|' + pathAbsolute + '|' + pathRootless + ')'; // relative-part = "//" authority path-abempty / path-absolute / path-noscheme / path-empty rfc3986.relativeRef = '(?:' + '(?:\\/\\/' + authority + pathAbEmpty + ')' + '|' + pathAbsolute + '|' + pathNoScheme + '|' + pathEmpty + ')'; rfc3986.relativeRefCapture = '(?:' + '(?:\\/\\/' + authorityCapture + pathAbEmpty + ')' + '|' + pathAbsolute + '|' + pathNoScheme + '|' + pathEmpty + ')'; // query = *( pchar / "/" / "?" ) // query = *( pchar / "[" / "]" / "/" / "?" ) rfc3986.query = '[' + pchar + '\\/\\?]*(?=#|$)'; //Finish matching either at the fragment part '|' end of the line. rfc3986.queryWithSquareBrackets = '[' + pchar + '\\[\\]\\/\\?]*(?=#|$)'; // fragment = *( pchar / "/" / "?" ) rfc3986.fragment = '[' + pchar + '\\/\\?]*'; return rfc3986; }; internals$1.rfc3986 = internals$1.generate(); uri.ip = { v4Cidr: internals$1.rfc3986.ipv4Cidr, v6Cidr: internals$1.rfc3986.ipv6Cidr, ipv4: internals$1.rfc3986.ipv4address, ipv6: internals$1.rfc3986.ipv6address, ipvfuture: internals$1.rfc3986.ipvFuture }; internals$1.createRegex = function (options) { const rfc = internals$1.rfc3986; // Construct expression const query = options.allowQuerySquareBrackets ? rfc.queryWithSquareBrackets : rfc.query; const suffix = '(?:\\?' + query + ')?' + '(?:#' + rfc.fragment + ')?'; // relative-ref = relative-part [ "?" query ] [ "#" fragment ] const relative = options.domain ? rfc.relativeRefCapture : rfc.relativeRef; if (options.relativeOnly) { return internals$1.wrap(relative + suffix); } // Custom schemes let customScheme = ''; if (options.scheme) { Assert$1(options.scheme instanceof RegExp || typeof options.scheme === 'string' || Array.isArray(options.scheme), 'scheme must be a RegExp, String, or Array'); const schemes = [].concat(options.scheme); Assert$1(schemes.length >= 1, 'scheme must have at least 1 scheme specified'); // Flatten the array into a string to be used to match the schemes const selections = []; for (let i = 0; i < schemes.length; ++i) { const scheme = schemes[i]; Assert$1(scheme instanceof RegExp || typeof scheme === 'string', 'scheme at position ' + i + ' must be a RegExp or String'); if (scheme instanceof RegExp) { selections.push(scheme.source.toString()); } else { Assert$1(rfc.schemeRegex.test(scheme), 'scheme at position ' + i + ' must be a valid scheme'); selections.push(EscapeRegex(scheme)); } } customScheme = selections.join('|'); } // URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] const scheme = customScheme ? '(?:' + customScheme + ')' : rfc.scheme; const absolute = '(?:' + scheme + ':' + (options.domain ? rfc.hierPartCapture : rfc.hierPart) + ')'; const prefix = options.allowRelative ? '(?:' + absolute + '|' + relative + ')' : absolute; return internals$1.wrap(prefix + suffix, customScheme); }; internals$1.wrap = function (raw, scheme) { raw = `(?=.)(?!https?\:/(?:$|[^/]))(?!https?\:///)(?!https?\:[^/])${raw}`; // Require at least one character and explicitly forbid 'http:/' or HTTP with empty domain return { raw, regex: new RegExp(`^${raw}$`), scheme }; }; internals$1.uriRegex = internals$1.createRegex({}); uri.regex = function (options = {}) { if (options.scheme || options.allowRelative || options.relativeOnly || options.allowQuerySquareBrackets || options.domain) { return internals$1.createRegex(options); } return internals$1.uriRegex; }; const Assert = assert$4; const Uri = uri; ip.regex = function (options = {}) { // CIDR Assert(options.cidr === undefined || typeof options.cidr === 'string', 'options.cidr must be a string'); const cidr = options.cidr ? options.cidr.toLowerCase() : 'optional'; Assert(['required', 'optional', 'forbidden'].includes(cidr), 'options.cidr must be one of required, optional, forbidden'); // Versions Assert(options.version === undefined || typeof options.version === 'string' || Array.isArray(options.version), 'options.version must be a string or an array of string'); let versions = options.version || ['ipv4', 'ipv6', 'ipvfuture']; if (!Array.isArray(versions)) { versions = [versions]; } Assert(versions.length >= 1, 'options.version must have at least 1 version specified'); for (let i = 0; i < versions.length; ++i) { Assert(typeof versions[i] === 'string', 'options.version must only contain strings'); versions[i] = versions[i].toLowerCase(); Assert(['ipv4', 'ipv6', 'ipvfuture'].includes(versions[i]), 'options.version contains unknown version ' + versions[i] + ' - must be one of ipv4, ipv6, ipvfuture'); } versions = Array.from(new Set(versions)); // Regex const parts = versions.map((version) => { // Forbidden if (cidr === 'forbidden') { return Uri.ip[version]; } // Required const cidrpart = `\\/${version === 'ipv4' ? Uri.ip.v4Cidr : Uri.ip.v6Cidr}`; if (cidr === 'required') { return `${Uri.ip[version]}${cidrpart}`; } // Optional return `${Uri.ip[version]}(?:${cidrpart})?`; }); const raw = `(?:${parts.join('|')})`; const regex = new RegExp(`^${raw}$`); return { cidr, versions, regex, raw }; }; const internals = {}; // http://data.iana.org/TLD/tlds-alpha-by-domain.txt // # Version 2024012900, Last Updated Mon Jan 29 07:07:01 2024 UTC internals.tlds = [ 'AAA', 'AARP', 'ABB', 'ABBOTT', 'ABBVIE', 'ABC', 'ABLE', 'ABOGADO', 'ABUDHABI', 'AC', 'ACADEMY', 'ACCENTURE', 'ACCOUNTANT', 'ACCOUNTANTS', 'ACO', 'ACTOR', 'AD', 'ADS', 'ADULT', 'AE', 'AEG', 'AERO', 'AETNA', 'AF', 'AFL', 'AFRICA', 'AG', 'AGAKHAN', 'AGENCY', 'AI', 'AIG', 'AIRBUS', 'AIRFORCE', 'AIRTEL', 'AKDN', 'AL', 'ALIBABA', 'ALIPAY', 'ALLFINANZ', 'ALLSTATE', 'ALLY', 'ALSACE', 'ALSTOM', 'AM', 'AMAZON', 'AMERICANEXPRESS', 'AMERICANFAMILY', 'AMEX', 'AMFAM', 'AMICA', 'AMSTERDAM', 'ANALYTICS', 'ANDROID', 'ANQUAN', 'ANZ', 'AO', 'AOL', 'APARTMENTS', 'APP', 'APPLE', 'AQ', 'AQUARELLE', 'AR', 'ARAB', 'ARAMCO', 'ARCHI', 'ARMY', 'ARPA', 'ART', 'ARTE', 'AS', 'ASDA', 'ASIA', 'ASSOCIATES', 'AT', 'ATHLETA', 'ATTORNEY', 'AU', 'AUCTION', 'AUDI', 'AUDIBLE', 'AUDIO', 'AUSPOST', 'AUTHOR', 'AUTO', 'AUTOS', 'AVIANCA', 'AW', 'AWS', 'AX', 'AXA', 'AZ', 'AZURE', 'BA', 'BABY', 'BAIDU', 'BANAMEX', 'BAND', 'BANK', 'BAR', 'BARCELONA', 'BARCLAYCARD', 'BARCLAYS', 'BAREFOOT', 'BARGAINS', 'BASEBALL', 'BASKETBALL', 'BAUHAUS', 'BAYERN', 'BB', 'BBC', 'BBT', 'BBVA', 'BCG', 'BCN', 'BD', 'BE', 'BEATS', 'BEAUTY', 'BEER', 'BENTLEY', 'BERLIN', 'BEST', 'BESTBUY', 'BET', 'BF', 'BG', 'BH', 'BHARTI', 'BI', 'BIBLE', 'BID', 'BIKE', 'BING', 'BINGO', 'BIO', 'BIZ', 'BJ', 'BLACK', 'BLACKFRIDAY', 'BLOCKBUSTER', 'BLOG', 'BLOOMBERG', 'BLUE', 'BM', 'BMS', 'BMW', 'BN', 'BNPPARIBAS', 'BO', 'BOATS', 'BOEHRINGER', 'BOFA', 'BOM', 'BOND', 'BOO', 'BOOK', 'BOOKING', 'BOSCH', 'BOSTIK', 'BOSTON', 'BOT', 'BOUTIQUE', 'BOX', 'BR', 'BRADESCO', 'BRIDGESTONE', 'BROADWAY', 'BROKER', 'BROTHER', 'BRUSSELS', 'BS', 'BT', 'BUILD', 'BUILDERS', 'BUSINESS', 'BUY', 'BUZZ', 'BV', 'BW', 'BY', 'BZ', 'BZH', 'CA', 'CAB', 'CAFE', 'CAL', 'CALL', 'CALVINKLEIN', 'CAM', 'CAMERA', 'CAMP', 'CANON', 'CAPETOWN', 'CAPITAL', 'CAPITALONE', 'CAR', 'CARAVAN', 'CARDS', 'CARE', 'CAREER', 'CAREERS', 'CARS', 'CASA', 'CASE', 'CASH', 'CASINO', 'CAT', 'CATERING', 'CATHOLIC', 'CBA', 'CBN', 'CBRE', 'CC', 'CD', 'CENTER', 'CEO', 'CERN', 'CF', 'CFA', 'CFD', 'CG', 'CH', 'CHANEL', 'CHANNEL', 'CHARITY', 'CHASE', 'CHAT', 'CHEAP', 'CHINTAI', 'CHRISTMAS', 'CHROME', 'CHURCH', 'CI', 'CIPRIANI', 'CIRCLE', 'CISCO', 'CITADEL', 'CITI', 'CITIC', 'CITY', 'CK', 'CL', 'CLAIMS', 'CLEANING', 'CLICK', 'CLINIC', 'CLINIQUE', 'CLOTHING', 'CLOUD', 'CLUB', 'CLUBMED', 'CM', 'CN', 'CO', 'COACH', 'CODES', 'COFFEE', 'COLLEGE', 'COLOGNE', 'COM', 'COMCAST', 'COMMBANK', 'COMMUNITY', 'COMPANY', 'COMPARE', 'COMPUTER', 'COMSEC', 'CONDOS', 'CONSTRUCTION', 'CONSULTING', 'CONTACT', 'CONTRACTORS', 'COOKING', 'COOL', 'COOP', 'CORSICA', 'COUNTRY', 'COUPON', 'COUPONS', 'COURSES', 'CPA', 'CR', 'CREDIT', 'CREDITCARD', 'CREDITUNION', 'CRICKET', 'CROWN', 'CRS', 'CRUISE', 'CRUISES', 'CU', 'CUISINELLA', 'CV', 'CW', 'CX', 'CY', 'CYMRU', 'CYOU', 'CZ', 'DABUR', 'DAD', 'DANCE', 'DATA', 'DATE', 'DATING', 'DATSUN', 'DAY', 'DCLK', 'DDS', 'DE', 'DEAL', 'DEALER', 'DEALS', 'DEGREE', 'DELIVERY', 'DELL', 'DELOITTE', 'DELTA', 'DEMOCRAT', 'DENTAL', 'DENTIST', 'DESI', 'DESIGN', 'DEV', 'DHL', 'DIAMONDS', 'DIET', 'DIGITAL', 'DIRECT', 'DIRECTORY', 'DISCOUNT', 'DISCOVER', 'DISH', 'DIY', 'DJ', 'DK', 'DM', 'DNP', 'DO', 'DOCS', 'DOCTOR', 'DOG', 'DOMAINS', 'DOT', 'DOWNLOAD', 'DRIVE', 'DTV', 'DUBAI', 'DUNLOP', 'DUPONT', 'DURBAN', 'DVAG', 'DVR', 'DZ', 'EARTH', 'EAT', 'EC', 'ECO', 'EDEKA', 'EDU', 'EDUCATION', 'EE', 'EG', 'EMAIL', 'EMERCK', 'ENERGY', 'ENGINEER', 'ENGINEERING', 'ENTERPRISES', 'EPSON', 'EQUIPMENT', 'ER', 'ERICSSON', 'ERNI', 'ES', 'ESQ', 'ESTATE', 'ET', 'EU', 'EUROVISION', 'EUS', 'EVENTS', 'EXCHANGE', 'EXPERT', 'EXPOSED', 'EXPRESS', 'EXTRASPACE', 'FAGE', 'FAIL', 'FAIRWINDS', 'FAITH', 'FAMILY', 'FAN', 'FANS', 'FARM', 'FARMERS', 'FASHION', 'FAST', 'FEDEX', 'FEEDBACK', 'FERRARI', 'FERRERO', 'FI', 'FIDELITY', 'FIDO', 'FILM', 'FINAL', 'FINANCE', 'FINANCIAL', 'FIRE', 'FIRESTONE', 'FIRMDALE', 'FISH', 'FISHING', 'FIT', 'FITNESS', 'FJ', 'FK', 'FLICKR', 'FLIGHTS', 'FLIR', 'FLORIST', 'FLOWERS', 'FLY', 'FM', 'FO', 'FOO', 'FOOD', 'FOOTBALL', 'FORD', 'FOREX', 'FORSALE', 'FORUM', 'FOUNDATION', 'FOX', 'FR', 'FREE', 'FRESENIUS', 'FRL', 'FROGANS', 'FRONTIER', 'FTR', 'FUJITSU', 'FUN', 'FUND', 'FURNITURE', 'FUTBOL', 'FYI', 'GA', 'GAL', 'GALLERY', 'GALLO', 'GALLUP', 'GAME', 'GAMES', 'GAP', 'GARDEN', 'GAY', 'GB', 'GBIZ', 'GD', 'GDN', 'GE', 'GEA', 'GENT', 'GENTING', 'GEORGE', 'GF', 'GG', 'GGEE', 'GH', 'GI', 'GIFT', 'GIFTS', 'GIVES', 'GIVING', 'GL', 'GLASS', 'GLE', 'GLOBAL', 'GLOBO', 'GM', 'GMAIL', 'GMBH', 'GMO', 'GMX', 'GN', 'GODADDY', 'GOLD', 'GOLDPOINT', 'GOLF', 'GOO', 'GOODYEAR', 'GOOG', 'GOOGLE', 'GOP', 'GOT', 'GOV', 'GP', 'GQ', 'GR', 'GRAINGER', 'GRAPHICS', 'GRATIS', 'GREEN', 'GRIPE', 'GROCERY', 'GROUP', 'GS', 'GT', 'GU', 'GUARDIAN', 'GUCCI', 'GUGE', 'GUIDE', 'GUITARS', 'GURU', 'GW', 'GY', 'HAIR', 'HAMBURG', 'HANGOUT', 'HAUS', 'HBO', 'HDFC', 'HDFCBANK', 'HEALTH', 'HEALTHCARE', 'HELP', 'HELSINKI', 'HERE', 'HERMES', 'HIPHOP', 'HISAMITSU', 'HITACHI', 'HIV', 'HK', 'HKT', 'HM', 'HN', 'HOCKEY', 'HOLDINGS', 'HOLIDAY', 'HOMEDEPOT', 'HOMEGOODS', 'HOMES', 'HOMESENSE', 'HONDA', 'HORSE', 'HOSPITAL', 'HOST', 'HOSTING', 'HOT', 'HOTELS', 'HOTMAIL', 'HOUSE', 'HOW', 'HR', 'HSBC', 'HT', 'HU', 'HUGHES', 'HYATT', 'HYUNDAI', 'IBM', 'ICBC', 'ICE', 'ICU', 'ID', 'IE', 'IEEE', 'IFM', 'IKANO', 'IL', 'IM', 'IMAMAT', 'IMDB', 'IMMO', 'IMMOBILIEN', 'IN', 'INC', 'INDUSTRIES', 'INFINITI', 'INFO', 'ING', 'INK', 'INSTITUTE', 'INSURANCE', 'INSURE', 'INT', 'INTERNATIONAL', 'INTUIT', 'INVESTMENTS', 'IO', 'IPIRANGA', 'IQ', 'IR', 'IRISH', 'IS', 'ISMAILI', 'IST', 'ISTANBUL', 'IT', 'ITAU', 'ITV', 'JAGUAR', 'JAVA', 'JCB', 'JE', 'JEEP', 'JETZT', 'JEWELRY', 'JIO', 'JLL', 'JM', 'JMP', 'JNJ', 'JO', 'JOBS', 'JOBURG', 'JOT', 'JOY', 'JP', 'JPMORGAN', 'JPRS', 'JUEGOS', 'JUNIPER', 'KAUFEN', 'KDDI', 'KE', 'KERRYHOTELS', 'KERRYLOGISTICS', 'KERRYPROPERTIES', 'KFH', 'KG', 'KH', 'KI', 'KIA', 'KIDS', 'KIM', 'KINDLE', 'KITCHEN', 'KIWI', 'KM', 'KN', 'KOELN', 'KOMATSU', 'KOSHER', 'KP', 'KPMG', 'KPN', 'KR', 'KRD', 'KRED', 'KUOKGROUP', 'KW', 'KY', 'KYOTO', 'KZ', 'LA', 'LACAIXA', 'LAMBORGHINI', 'LAMER', 'LANCASTER', 'LAND', 'LANDROVER', 'LANXESS', 'LASALLE', 'LAT', 'LATINO', 'LATROBE', 'LAW', 'LAWYER', 'LB', 'LC', 'LDS', 'LEASE', 'LECLERC', 'LEFRAK', 'LEGAL', 'LEGO', 'LEXUS', 'LGBT', 'LI', 'LIDL', 'LIFE', 'LIFEINSURANCE', 'LIFESTYLE', 'LIGHTING', 'LIKE', 'LILLY', 'LIMITED', 'LIMO', 'LINCOLN', 'LINK', 'LIPSY', 'LIVE', 'LIVING', 'LK', 'LLC', 'LLP', 'LOAN', 'LOANS', 'LOCKER', 'LOCUS', 'LOL', 'LONDON', 'LOTTE', 'LOTTO', 'LOVE', 'LPL', 'LPLFINANCIAL', 'LR', 'LS', 'LT', 'LTD', 'LTDA', 'LU', 'LUNDBECK', 'LUXE', 'LUXURY', 'LV', 'LY', 'MA', 'MADRID', 'MAIF', 'MAISON', 'MAKEUP', 'MAN', 'MANAGEMENT', 'MANGO', 'MAP', 'MARKET', 'MARKETING', 'MARKETS', 'MARRIOTT', 'MARSHALLS', 'MATTEL', 'MBA', 'MC', 'MCKINSEY', 'MD', 'ME', 'MED', 'MEDIA', 'MEET', 'MELBOURNE', 'MEME', 'MEMORIAL', 'MEN', 'MENU', 'MERCKMSD', 'MG', 'MH', 'MIAMI', 'MICROSOFT', 'MIL', 'MINI', 'MINT', 'MIT', 'MITSUBISHI', 'MK', 'ML', 'MLB', 'MLS', 'MM', 'MMA', 'MN', 'MO', 'MOBI', 'MOBILE', 'MODA', 'MOE', 'MOI', 'MOM', 'MONASH', 'MONEY', 'MONSTER', 'MORMON', 'MORTGAGE', 'MOSCOW', 'MOTO', 'MOTORCYCLES', 'MOV', 'MOVIE', 'MP', 'MQ', 'MR', 'MS', 'MSD', 'MT', 'MTN', 'MTR', 'MU', 'MUSEUM', 'MUSIC', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NAB', 'NAGOYA', 'NAME', 'NATURA', 'NAVY', 'NBA', 'NC', 'NE', 'NEC', 'NET', 'NETBANK', 'NETFLIX', 'NETWORK', 'NEUSTAR', 'NEW', 'NEWS', 'NEXT', 'NEXTDIRECT', 'NEXUS', 'NF', 'NFL', 'NG', 'NGO', 'NHK', 'NI', 'NICO', 'NIKE', 'NIKON', 'NINJA', 'NISSAN', 'NISSAY', 'NL', 'NO', 'NOKIA', 'NORTON', 'NOW', 'NOWRUZ', 'NOWTV', 'NP', 'NR', 'NRA', 'NRW', 'NTT', 'NU', 'NYC', 'NZ', 'OBI', 'OBSERVER', 'OFFICE', 'OKINAWA', 'OLAYAN', 'OLAYANGROUP', 'OLLO', 'OM', 'OMEGA', 'ONE', 'ONG', 'ONL', 'ONLINE', 'OOO', 'OPEN', 'ORACLE', 'ORANGE', 'ORG', 'ORGANIC', 'ORIGINS', 'OSAKA', 'OTSUKA', 'OTT', 'OVH', 'PA', 'PAGE', 'PANASONIC', 'PARIS', 'PARS', 'PARTNERS', 'PARTS', 'PARTY', 'PAY', 'PCCW', 'PE', 'PET', 'PF', 'PFIZER', 'PG', 'PH', 'PHARMACY', 'PHD', 'PHILIPS', 'PHONE', 'PHOTO', 'PHOTOGRAPHY', 'PHOTOS', 'PHYSIO', 'PICS', 'PICTET', 'PICTURES', 'PID', 'PIN', 'PING', 'PINK', 'PIONEER', 'PIZZA', 'PK', 'PL', 'PLACE', 'PLAY', 'PLAYSTATION', 'PLUMBING', 'PLUS', 'PM', 'PN', 'PNC', 'POHL', 'POKER', 'POLITIE', 'PORN', 'POST', 'PR', 'PRAMERICA', 'PRAXI', 'PRESS', 'PRIME', 'PRO', 'PROD', 'PRODUCTIONS', 'PROF', 'PROGRESSIVE', 'PROMO', 'PROPERTIES', 'PROPERTY', 'PROTECTION', 'PRU', 'PRUDENTIAL', 'PS', 'PT', 'PUB', 'PW', 'PWC', 'PY', 'QA', 'QPON', 'QUEBEC', 'QUEST', 'RACING', 'RADIO', 'RE', 'READ', 'REALESTATE', 'REALTOR', 'REALTY', 'RECIPES', 'RED', 'REDSTONE', 'REDUMBRELLA', 'REHAB', 'REISE', 'REISEN', 'REIT', 'RELIANCE', 'REN', 'RENT', 'RENTALS', 'REPAIR', 'REPORT', 'REPUBLICAN', 'REST', 'RESTAURANT', 'REVIEW', 'REVIEWS', 'REXROTH', 'RICH', 'RICHARDLI', 'RICOH', 'RIL', 'RIO', 'RIP', 'RO', 'ROCKS', 'RODEO', 'ROGERS', 'ROOM', 'RS', 'RSVP', 'RU', 'RUGBY', 'RUHR', 'RUN', 'RW', 'RWE', 'RYUKYU', 'SA', 'SAARLAND', 'SAFE', 'SAFETY', 'SAKURA', 'SALE', 'SALON', 'SAMSCLUB', 'SAMSUNG', 'SANDVIK', 'SANDVIKCOROMANT', 'SANOFI', 'SAP', 'SARL', 'SAS', 'SAVE', 'SAXO', 'SB', 'SBI', 'SBS', 'SC', 'SCB', 'SCHAEFFLER', 'SCHMIDT', 'SCHOLARSHIPS', 'SCHOOL', 'SCHULE', 'SCHWARZ', 'SCIENCE', 'SCOT', 'SD', 'SE', 'SEARCH', 'SEAT', 'SECURE', 'SECURITY', 'SEEK', 'SELECT', 'SENER', 'SERVICES', 'SEVEN', 'SEW', 'SEX', 'SEXY', 'SFR', 'SG', 'SH', 'SHANGRILA', 'SHARP', 'SHAW', 'SHELL', 'SHIA', 'SHIKSHA', 'SHOES', 'SHOP', 'SHOPPING', 'SHOUJI', 'SHOW', 'SI', 'SILK', 'SINA', 'SINGLES', 'SITE', 'SJ', 'SK', 'SKI', 'SKIN', 'SKY', 'SKYPE', 'SL', 'SLING', 'SM', 'SMART', 'SMILE', 'SN', 'SNCF', 'SO', 'SOCCER', 'SOCIAL', 'SOFTBANK', 'SOFTWARE', 'SOHU', 'SOLAR', 'SOLUTIONS', 'SONG', 'SONY', 'SOY', 'SPA', 'SPACE', 'SPORT', 'SPOT', 'SR', 'SRL', 'SS', 'ST', 'STADA', 'STAPLES', 'STAR', 'STATEBANK', 'STATEFARM', 'STC', 'STCGROUP', 'STOCKHOLM', 'STORAGE', 'STORE', 'STREAM', 'STUDIO', 'STUDY', 'STYLE', 'SU', 'SUCKS', 'SUPPLIES', 'SUPPLY', 'SUPPORT', 'SURF', 'SURGERY', 'SUZUKI', 'SV', 'SWATCH', 'SWISS', 'SX', 'SY', 'SYDNEY', 'SYSTEMS', 'SZ', 'TAB', 'TAIPEI', 'TALK', 'TAOBAO', 'TARGET', 'TATAMOTORS', 'TATAR', 'TATTOO', 'TAX', 'TAXI', 'TC', 'TCI', 'TD', 'TDK', 'TEAM', 'TECH', 'TECHNOLOGY', 'TEL', 'TEMASEK', 'TENNIS', 'TEVA', 'TF', 'TG', 'TH', 'THD', 'THEATER', 'THEATRE', 'TIAA', 'TICKETS', 'TIENDA', 'TIPS', 'TIRES', 'TIROL', 'TJ', 'TJMAXX', 'TJX', 'TK', 'TKMAXX', 'TL', 'TM', 'TMALL', 'TN', 'TO', 'TODAY', 'TOKYO', 'TOOLS', 'TOP', 'TORAY', 'TOSHIBA', 'TOTAL', 'TOURS', 'TOWN', 'TOYOTA', 'TOYS', 'TR', 'TRADE', 'TRADING', 'TRAINING', 'TRAVEL', 'TRAVELERS', 'TRAVELERSINSURANCE', 'TRUST', 'TRV', 'TT', 'TUBE', 'TUI', 'TUNES', 'TUSHU', 'TV', 'TVS', 'TW', 'TZ', 'UA', 'UBANK', 'UBS', 'UG', 'UK', 'UNICOM', 'UNIVERSITY', 'UNO', 'UOL', 'UPS', 'US', 'UY', 'UZ', 'VA', 'VACATIONS', 'VANA', 'VANGUARD', 'VC', 'VE', 'VEGAS', 'VENTURES', 'VERISIGN', 'VERSICHERUNG', 'VET', 'VG', 'VI', 'VIAJES', 'VIDEO', 'VIG', 'VIKING', 'VILLAS', 'VIN', 'VIP', 'VIRGIN', 'VISA', 'VISION', 'VIVA', 'VIVO', 'VLAANDEREN', 'VN', 'VODKA', 'VOLVO', 'VOTE', 'VOTING', 'VOTO', 'VOYAGE', 'VU', 'WALES', 'WALMART', 'WALTER', 'WANG', 'WANGGOU', 'WATCH', 'WATCHES', 'WEATHER', 'WEATHERCHANNEL', 'WEBCAM', 'WEBER', 'WEBSITE', 'WED', 'WEDDING', 'WEIBO', 'WEIR', 'WF', 'WHOSWHO', 'WIEN', 'WIKI', 'WILLIAMHILL', 'WIN', 'WINDOWS', 'WINE', 'WINNERS', 'WME', 'WOLTERSKLUWER', 'WOODSIDE', 'WORK', 'WORKS', 'WORLD', 'WOW', 'WS', 'WTC', 'WTF', 'XBOX', 'XEROX', 'XFINITY', 'XIHUAN', 'XIN', 'XN--11B4C3D', 'XN--1CK2E1B', 'XN--1QQW23A', 'XN--2SCRJ9C', 'XN--30RR7Y', 'XN--3BST00M', 'XN--3DS443G', 'XN--3E0B707E', 'XN--3HCRJ9C', 'XN--3PXU8K', 'XN--42C2D9A', 'XN--45BR5CYL', 'XN--45BRJ9C', 'XN--45Q11C', 'XN--4DBRK0CE', 'XN--4GBRIM', 'XN--54B7FTA0CC', 'XN--55QW42G', 'XN--55QX5D', 'XN--5SU34J936BGSG', 'XN--5TZM5G', 'XN--6FRZ82G', 'XN--6QQ986B3XL', 'XN--80ADXHKS', 'XN--80AO21A', 'XN--80AQECDR1A', 'XN--80ASEHDB', 'XN--80ASWG', 'XN--8Y0A063A', 'XN--90A3AC', 'XN--90AE', 'XN--90AIS', 'XN--9DBQ2A', 'XN--9ET52U', 'XN--9KRT00A', 'XN--B4W605FERD', 'XN--BCK1B9A5DRE4C', 'XN--C1AVG', 'XN--C2BR7G', 'XN--CCK2B3B', 'XN--CCKWCXETD', 'XN--CG4BKI', 'XN--CLCHC0EA0B2G2A9GCD', 'XN--CZR694B', 'XN--CZRS0T', 'XN--CZRU2D', 'XN--D1ACJ3B', 'XN--D1ALF', 'XN--E1A4C', 'XN--ECKVDTC9D', 'XN--EFVY88H', 'XN--FCT429K', 'XN--FHBEI', 'XN--FIQ228C5HS', 'XN--FIQ64B', 'XN--FIQS8S', 'XN--FIQZ9S', 'XN--FJQ720A', 'XN--FLW351E', 'XN--FPCRJ9C3D', 'XN--FZC2C9E2C', 'XN--FZYS8D69UVGM', 'XN--G2XX48C', 'XN--GCKR3F0F', 'XN--GECRJ9C', 'XN--GK3AT1E', 'XN--H2BREG3EVE', 'XN--H2BRJ9C', 'XN--H2BRJ9C8C', 'XN--HXT814E', 'XN--I1B6B1A6A2E', 'XN--IMR513N', 'XN--IO0A7I', 'XN--J1AEF', 'XN--J1AMH', 'XN--J6W193G', 'XN--JLQ480N2RG', 'XN--JVR189M', 'XN--KCRX77D1X4A', 'XN--KPRW13D', 'XN--KPRY57D', 'XN--KPUT3I', 'XN--L1ACC', 'XN--LGBBAT1AD8J', 'XN--MGB9AWBF', 'XN--MGBA3A3EJT', 'XN--MGBA3A4F16A', 'XN--MGBA7C0BBN0A', 'XN--MGBAAM7A8H', 'XN--MGBAB2BD', 'XN--MGBAH1A3HJKRD', 'XN--MGBAI9AZGQP6J', 'XN--MGBAYH7GPA', 'XN--MGBBH1A', 'XN--MGBBH1A71E', 'XN--MGBC0A9AZCG', 'XN--MGBCA7DZDO', 'XN--MGBCPQ6GPA1A', 'XN--MGBERP4A5D4AR', 'XN--MGBGU82A', 'XN--MGBI4ECEXP', 'XN--MGBPL2FH', 'XN--MGBT3DHD', 'XN--MGBTX2B', 'XN--MGBX4CD0AB', 'XN--MIX891F', 'XN--MK1BU44C', 'XN--MXTQ1M', 'XN--NGBC5AZD', 'XN--NGBE9E0A', 'XN--NGBRX', 'XN--NODE', 'XN--NQV7F', 'XN--NQV7FS00EMA', 'XN--NYQY26A', 'XN--O3CW4H', 'XN--OGBPF8FL', 'XN--OTU796D', 'XN--P1ACF', 'XN--P1AI', 'XN--PGBS0DH', 'XN--PSSY2U', 'XN--Q7CE6A', 'XN--Q9JYB4C', 'XN--QCKA1PMC', 'XN--QXA6A', 'XN--QXAM', 'XN--RHQV96G', 'XN--ROVU88B', 'XN--RVC1E0AM3E', 'XN--S9BRJ9C', 'XN--SES554G', 'XN--T60B56A', 'XN--TCKWE', 'XN--TIQ49XQYJ', 'XN--UNUP4Y', 'XN--VERMGENSBERATER-CTB', 'XN--VERMGENSBERATUNG-PWB', 'XN--VHQUV', 'XN--VUQ861B', 'XN--W4R85EL8FHU5DNRA', 'XN--W4RS40L', 'XN--WGBH1C', 'XN--WGBL6A', 'XN--XHQ521B', 'XN--XKC2AL3HYE2A', 'XN--XKC2DL3A5EE0H', 'XN--Y9A3AQ', 'XN--YFRO4I67O', 'XN--YGBI2AMMX', 'XN--ZFR164B', 'XXX', 'XYZ', 'YACHTS', 'YAHOO', 'YAMAXUN', 'YANDEX', 'YE', 'YODOBASHI', 'YOGA', 'YOKOHAMA', 'YOU', 'YOUTUBE', 'YT', 'YUN', 'ZA', 'ZAPPOS', 'ZARA', 'ZERO', 'ZIP', 'ZM', 'ZONE', 'ZUERICH', 'ZW' ]; // Keep as upper-case to make updating from source easier var tlds = new Set(internals.tlds.map((tld) => tld.toLowerCase())); var src$2 = {exports: {}}; var browser$2 = {exports: {}}; /** * Helpers. */ var ms$2; var hasRequiredMs; function requireMs () { if (hasRequiredMs) return ms$2; hasRequiredMs = 1; var s = 1000; var m = s * 60; var h = m * 60; var d = h * 24; var w = d * 7; var y = d * 365.25; /** * Parse or format the given `val`. * * Options: * * - `long` verbose formatting [false] * * @param {String|Number} val * @param {Object} [options] * @throws {Error} throw an error if val is not a non-empty string or a number * @return {String|Number} * @api public */ ms$2 = function(val, options) { options = options || {}; var type = typeof val; if (type === 'string' && val.length > 0) { return parse(val); } else if (type === 'number' && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } throw new Error( 'val is not a non-empty string or a valid number. val=' + JSON.stringify(val) ); }; /** * Parse the given `str` and return milliseconds. * * @param {String} str * @return {Number} * @api private */ function parse(str) { str = String(str); if (str.length > 100) { return; } var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( str ); if (!match) { return; } var n = parseFloat(match[1]); var type = (match[2] || 'ms').toLowerCase(); switch (type) { case 'years': case 'year': case 'yrs': case 'yr': case 'y': return n * y; case 'weeks': case 'week': case 'w': return n * w; case 'days': case 'day': case 'd': return n * d; case 'hours': case 'hour': case 'hrs': case 'hr': case 'h': return n * h; case 'minutes': case 'minute': case 'mins': case 'min': case 'm': return n * m; case 'seconds': case 'second': case 'secs': case 'sec': case 's': return n * s; case 'milliseconds': case 'millisecond': case 'msecs': case 'msec': case 'ms': return n; default: return undefined; } } /** * Short format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtShort(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return Math.round(ms / d) + 'd'; } if (msAbs >= h) { return Math.round(ms / h) + 'h'; } if (msAbs >= m) { return Math.round(ms / m) + 'm'; } if (msAbs >= s) { return Math.round(ms / s) + 's'; } return ms + 'ms'; } /** * Long format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtLong(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return plural(ms, msAbs, d, 'day'); } if (msAbs >= h) { return plural(ms, msAbs, h, 'hour'); } if (msAbs >= m) { return plural(ms, msAbs, m, 'minute'); } if (msAbs >= s) { return plural(ms, msAbs, s, 'second'); } return ms + ' ms'; } /** * Pluralization helper. */ function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); } return ms$2; } var common$2; var hasRequiredCommon$1; function requireCommon$1 () { if (hasRequiredCommon$1) return common$2; hasRequiredCommon$1 = 1; /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. */ function setup(env) { createDebug.debug = createDebug; createDebug.default = createDebug; createDebug.coerce = coerce; createDebug.disable = disable; createDebug.enable = enable; createDebug.enabled = enabled; createDebug.humanize = requireMs(); createDebug.destroy = destroy; Object.keys(env).forEach(key => { createDebug[key] = env[key]; }); /** * The currently active debug mode names, and names to skip. */ createDebug.names = []; createDebug.skips = []; /** * Map of special "%n" handling functions, for the debug "format" argument. * * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". */ createDebug.formatters = {}; /** * Selects a color for a debug namespace * @param {String} namespace The namespace string for the debug instance to be colored * @return {Number|String} An ANSI color code for the given namespace * @api private */ function selectColor(namespace) { let hash = 0; for (let i = 0; i < namespace.length; i++) { hash = ((hash << 5) - hash) + namespace.charCodeAt(i); hash |= 0; // Convert to 32bit integer } return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; } createDebug.selectColor = selectColor; /** * Create a debugger with the given `namespace`. * * @param {String} namespace * @return {Function} * @api public */ function createDebug(namespace) { let prevTime; let enableOverride = null; let namespacesCache; let enabledCache; function debug(...args) { // Disabled? if (!debug.enabled) { return; } const self = debug; // Set `diff` timestamp const curr = Number(new Date()); const ms = curr - (prevTime || curr); self.diff = ms; self.prev = prevTime; self.curr = curr; prevTime = curr; args[0] = createDebug.coerce(args[0]); if (typeof args[0] !== 'string') { // Anything else let's inspect with %O args.unshift('%O'); } // Apply any `formatters` transformations let index = 0; args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { // If we encounter an escaped % then don't increase the array index if (match === '%%') { return '%'; } index++; const formatter = createDebug.formatters[format]; if (typeof formatter === 'function') { const val = args[index]; match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` args.splice(index, 1); index--; } return match; }); // Apply env-specific formatting (colors, etc.) createDebug.formatArgs.call(self, args); const logFn = self.log || createDebug.log; logFn.apply(self, args); } debug.namespace = namespace; debug.useColors = createDebug.useColors(); debug.color = createDebug.selectColor(namespace); debug.extend = extend; debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. Object.defineProperty(debug, 'enabled', { enumerable: true, configurable: false, get: () => { if (enableOverride !== null) { return enableOverride; } if (namespacesCache !== createDebug.namespaces) { namespacesCache = createDebug.namespaces; enabledCache = createDebug.enabled(namespace); } return enabledCache; }, set: v => { enableOverride = v; } }); // Env-specific initialization logic for debug instances if (typeof createDebug.init === 'function') { createDebug.init(debug); } return debug; } function extend(namespace, delimiter) { const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); newDebug.log = this.log; return newDebug; } /** * Enables a debug mode by namespaces. This can include modes * separated by a colon and wildcards. * * @param {String} namespaces * @api public */ function enable(namespaces) { createDebug.save(namespaces); createDebug.namespaces = namespaces; createDebug.names = []; createDebug.skips = []; let i; const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); const len = split.length; for (i = 0; i < len; i++) { if (!split[i]) { // ignore empty strings continue; } namespaces = split[i].replace(/\*/g, '.*?'); if (namespaces[0] === '-') { createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$')); } else { createDebug.names.push(new RegExp('^' + namespaces + '$')); } } } /** * Disable debug output. * * @return {String} namespaces * @api public */ function disable() { const namespaces = [ ...createDebug.names.map(toNamespace), ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace) ].join(','); createDebug.enable(''); return namespaces; } /** * Returns true if the given mode name is enabled, false otherwise. * * @param {String} name * @return {Boolean} * @api public */ function enabled(name) { if (name[name.length - 1] === '*') { return true; } let i; let len; for (i = 0, len = createDebug.skips.length; i < len; i++) { if (createDebug.skips[i].test(name)) { return false; } } for (i = 0, len = createDebug.names.length; i < len; i++) { if (createDebug.names[i].test(name)) { return true; } } return false; } /** * Convert regexp to namespace * * @param {RegExp} regxep * @return {String} namespace * @api private */ function toNamespace(regexp) { return regexp.toString() .substring(2, regexp.toString().length - 2) .replace(/\.\*\?$/, '*'); } /** * Coerce `val`. * * @param {Mixed} val * @return {Mixed} * @api private */ function coerce(val) { if (val instanceof Error) { return val.stack || val.message; } return val; } /** * XXX DO NOT USE. This is a temporary stub function. * XXX It WILL be removed in the next major release. */ function destroy() { console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); } createDebug.enable(createDebug.load()); return createDebug; } common$2 = setup; return common$2; } /* eslint-env browser */ var hasRequiredBrowser; function requireBrowser () { if (hasRequiredBrowser) return browser$2.exports; hasRequiredBrowser = 1; (function (module, exports) { /** * This is the web browser implementation of `debug()`. */ exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = localstorage(); exports.destroy = (() => { let warned = false; return () => { if (!warned) { warned = true; console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); } }; })(); /** * Colors. */ exports.colors = [ '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33' ]; /** * Currently only WebKit-based Web Inspectors, Firefox >= v31, * and the Firebug extension (any Firefox version) are known * to support "%c" CSS customizations. * * TODO: add a `localStorage` variable to explicitly enable/disable colors */ // eslint-disable-next-line complexity function useColors() { // NB: In an Electron preload script, document will be defined but not fully // initialized. Since we know we're in Chrome, we'll just detect this case // explicitly if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { return true; } // Internet Explorer and Edge do not support colors. if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { return false; } // Is webkit? http://stackoverflow.com/a/16459606/376773 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || // Is firebug? http://stackoverflow.com/a/398120/376773 (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || // Is firefox >= v31? // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || // Double check webkit in userAgent just in case we are in a worker (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); } /** * Colorize log arguments if enabled. * * @api public */ function formatArgs(args) { args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); if (!this.useColors) { return; } const c = 'color: ' + this.color; args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other // arguments passed either before or after the %c, so we need to // figure out the correct index to insert the CSS into let index = 0; let lastC = 0; args[0].replace(/%[a-zA-Z%]/g, match => { if (match === '%%') { return; } index++; if (match === '%c') { // We only are interested in the *last* %c // (the user may have provided their own) lastC = index; } }); args.splice(lastC, 0, c); } /** * Invokes `console.debug()` when available. * No-op when `console.debug` is not a "function". * If `console.debug` is not available, falls back * to `console.log`. * * @api public */ exports.log = console.debug || console.log || (() => {}); /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { try { if (namespaces) { exports.storage.setItem('debug', namespaces); } else { exports.storage.removeItem('debug'); } } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? } } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { let r; try { r = exports.storage.getItem('debug'); } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? } // If debug isn't set in LS, and we're in Electron, try to load $DEBUG if (!r && typeof process !== 'undefined' && 'env' in process) { r = process.env.DEBUG; } return r; } /** * Localstorage attempts to return the localstorage. * * This is necessary because safari throws * when a user disables cookies/localstorage * and you attempt to access it. * * @return {LocalStorage} * @api private */ function localstorage() { try { // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context // The Browser also has localStorage in the global context. return localStorage; } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? } } module.exports = requireCommon$1()(exports); const {formatters} = module.exports; /** * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. */ formatters.j = function (v) { try { return JSON.stringify(v); } catch (error) { return '[UnexpectedJSONParseError]: ' + error.message; } }; } (browser$2, browser$2.exports)); return browser$2.exports; } var node = {exports: {}}; var hasFlag; var hasRequiredHasFlag; function requireHasFlag () { if (hasRequiredHasFlag) return hasFlag; hasRequiredHasFlag = 1; hasFlag = (flag, argv = process.argv) => { const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); const position = argv.indexOf(prefix + flag); const terminatorPosition = argv.indexOf('--'); return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); }; return hasFlag; } var supportsColor_1; var hasRequiredSupportsColor; function requireSupportsColor () { if (hasRequiredSupportsColor) return supportsColor_1; hasRequiredSupportsColor = 1; const os = require$$0$2; const tty = require$$1$1; const hasFlag = requireHasFlag(); const {env} = process; let forceColor; if (hasFlag('no-color') || hasFlag('no-colors') || hasFlag('color=false') || hasFlag('color=never')) { forceColor = 0; } else if (hasFlag('color') || hasFlag('colors') || hasFlag('color=true') || hasFlag('color=always')) { forceColor = 1; } if ('FORCE_COLOR' in env) { if (env.FORCE_COLOR === 'true') { forceColor = 1; } else if (env.FORCE_COLOR === 'false') { forceColor = 0; } else { forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); } } function translateLevel(level) { if (level === 0) { return false; } return { level, hasBasic: true, has256: level >= 2, has16m: level >= 3 }; } function supportsColor(haveStream, streamIsTTY) { if (forceColor === 0) { return 0; } if (hasFlag('color=16m') || hasFlag('color=full') || hasFlag('color=truecolor')) { return 3; } if (hasFlag('color=256')) { return 2; } if (haveStream && !streamIsTTY && forceColor === undefined) { return 0; } const min = forceColor || 0; if (env.TERM === 'dumb') { return min; } if (process.platform === 'win32') { // Windows 10 build 10586 is the first Windows release that supports 256 colors. // Windows 10 build 14931 is the first release that supports 16m/TrueColor. const osRelease = os.release().split('.'); if ( Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586 ) { return Number(osRelease[2]) >= 14931 ? 3 : 2; } return 1; } if ('CI' in env) { if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { return 1; } return min; } if ('TEAMCITY_VERSION' in env) { return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; } if (env.COLORTERM === 'truecolor') { return 3; } if ('TERM_PROGRAM' in env) { const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); switch (env.TERM_PROGRAM) { case 'iTerm.app': return version >= 3 ? 3 : 2; case 'Apple_Terminal': return 2; // No default } } if (/-256(color)?$/i.test(env.TERM)) { return 2; } if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { return 1; } if ('COLORTERM' in env) { return 1; } return min; } function getSupportLevel(stream) { const level = supportsColor(stream, stream && stream.isTTY); return translateLevel(level); } supportsColor_1 = { supportsColor: getSupportLevel, stdout: translateLevel(supportsColor(true, tty.isatty(1))), stderr: translateLevel(supportsColor(true, tty.isatty(2))) }; return supportsColor_1; } /** * Module dependencies. */ var hasRequiredNode; function requireNode () { if (hasRequiredNode) return node.exports; hasRequiredNode = 1; (function (module, exports) { const tty = require$$1$1; const util = require$$1; /** * This is the Node.js implementation of `debug()`. */ exports.init = init; exports.log = log; exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.destroy = util.deprecate( () => {}, 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.' ); /** * Colors. */ exports.colors = [6, 2, 3, 4, 5, 1]; try { // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) // eslint-disable-next-line import/no-extraneous-dependencies const supportsColor = requireSupportsColor(); if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { exports.colors = [ 20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68, 69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134, 135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 214, 215, 220, 221 ]; } } catch (error) { // Swallow - we only care if `supports-color` is available; it doesn't have to be. } /** * Build up the default `inspectOpts` object from the environment variables. * * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js */ exports.inspectOpts = Object.keys(process.env).filter(key => { return /^debug_/i.test(key); }).reduce((obj, key) => { // Camel-case const prop = key .substring(6) .toLowerCase() .replace(/_([a-z])/g, (_, k) => { return k.toUpperCase(); }); // Coerce string value into JS value let val = process.env[key]; if (/^(yes|on|true|enabled)$/i.test(val)) { val = true; } else if (/^(no|off|false|disabled)$/i.test(val)) { val = false; } else if (val === 'null') { val = null; } else { val = Number(val); } obj[prop] = val; return obj; }, {}); /** * Is stdout a TTY? Colored output is enabled when `true`. */ function useColors() { return 'colors' in exports.inspectOpts ? Boolean(exports.inspectOpts.colors) : tty.isatty(process.stderr.fd); } /** * Adds ANSI color escape codes if enabled. * * @api public */ function formatArgs(args) { const {namespace: name, useColors} = this; if (useColors) { const c = this.color; const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); const prefix = ` ${colorCode};1m${name} \u001B[0m`; args[0] = prefix + args[0].split('\n').join('\n' + prefix); args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); } else { args[0] = getDate() + name + ' ' + args[0]; } } function getDate() { if (exports.inspectOpts.hideDate) { return ''; } return new Date().toISOString() + ' '; } /** * Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr. */ function log(...args) { return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n'); } /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { if (namespaces) { process.env.DEBUG = namespaces; } else { // If you set a process.env field to null or undefined, it gets cast to the // string 'null' or 'undefined'. Just delete instead. delete process.env.DEBUG; } } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { return process.env.DEBUG; } /** * Init logic for `debug` instances. * * Create a new `inspectOpts` object in case `useColors` is set * differently for a particular `debug` instance. */ function init(debug) { debug.inspectOpts = {}; const keys = Object.keys(exports.inspectOpts); for (let i = 0; i < keys.length; i++) { debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; } } module.exports = requireCommon$1()(exports); const {formatters} = module.exports; /** * Map %o to `util.inspect()`, all on a single line. */ formatters.o = function (v) { this.inspectOpts.colors = this.useColors; return util.inspect(v, this.inspectOpts) .split('\n') .map(str => str.trim()) .join(' '); }; /** * Map %O to `util.inspect()`, allowing multiple lines if needed. */ formatters.O = function (v) { this.inspectOpts.colors = this.useColors; return util.inspect(v, this.inspectOpts); }; } (node, node.exports)); return node.exports; } /** * Detect Electron renderer / nwjs process, which is node, but we should * treat as a browser. */ if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { src$2.exports = requireBrowser(); } else { src$2.exports = requireNode(); } var srcExports = src$2.exports; var util$9; (function (util) { util.assertEqual = (val) => val; function assertIs(_arg) { } util.assertIs = assertIs; function assertNever(_x) { throw new Error(); } util.assertNever = assertNever; util.arrayToEnum = (items) => { const obj = {}; for (const item of items) { obj[item] = item; } return obj; }; util.getValidEnumValues = (obj) => { const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number"); const filtered = {}; for (const k of validKeys) { filtered[k] = obj[k]; } return util.objectValues(filtered); }; util.objectValues = (obj) => { return util.objectKeys(obj).map(function (e) { return obj[e]; }); }; util.objectKeys = typeof Object.keys === "function" // eslint-disable-line ban/ban ? (obj) => Object.keys(obj) // eslint-disable-line ban/ban : (object) => { const keys = []; for (const key in object) { if (Object.prototype.hasOwnProperty.call(object, key)) { keys.push(key); } } return keys; }; util.find = (arr, checker) => { for (const item of arr) { if (checker(item)) return item; } return undefined; }; util.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban : (val) => typeof val === "number" && isFinite(val) && Math.floor(val) === val; function joinValues(array, separator = " | ") { return array .map((val) => (typeof val === "string" ? `'${val}'` : val)) .join(separator); } util.joinValues = joinValues; util.jsonStringifyReplacer = (_, value) => { if (typeof value === "bigint") { return value.toString(); } return value; }; })(util$9 || (util$9 = {})); var objectUtil; (function (objectUtil) { objectUtil.mergeShapes = (first, second) => { return { ...first, ...second, // second overwrites first }; }; })(objectUtil || (objectUtil = {})); const ZodParsedType = util$9.arrayToEnum([ "string", "nan", "number", "integer", "float", "boolean", "date", "bigint", "symbol", "function", "undefined", "null", "array", "object", "unknown", "promise", "void", "never", "map", "set", ]); const getParsedType = (data) => { const t = typeof data; switch (t) { case "undefined": return ZodParsedType.undefined; case "string": return ZodParsedType.string; case "number": return isNaN(data) ? ZodParsedType.nan : ZodParsedType.number; case "boolean": return ZodParsedType.boolean; case "function": return ZodParsedType.function; case "bigint": return ZodParsedType.bigint; case "symbol": return ZodParsedType.symbol; case "object": if (Array.isArray(data)) { return ZodParsedType.array; } if (data === null) { return ZodParsedType.null; } if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") { return ZodParsedType.promise; } if (typeof Map !== "undefined" && data instanceof Map) { return ZodParsedType.map; } if (typeof Set !== "undefined" && data instanceof Set) { return ZodParsedType.set; } if (typeof Date !== "undefined" && data instanceof Date) { return ZodParsedType.date; } return ZodParsedType.object; default: return ZodParsedType.unknown; } }; const ZodIssueCode = util$9.arrayToEnum([ "invalid_type", "invalid_literal", "custom", "invalid_union", "invalid_union_discriminator", "invalid_enum_value", "unrecognized_keys", "invalid_arguments", "invalid_return_type", "invalid_date", "invalid_string", "too_small", "too_big", "invalid_intersection_types", "not_multiple_of", "not_finite", ]); const quotelessJson = (obj) => { const json = JSON.stringify(obj, null, 2); return json.replace(/"([^"]+)":/g, "$1:"); }; class ZodError extends Error { get errors() { return this.issues; } constructor(issues) { super(); this.issues = []; this.addIssue = (sub) => { this.issues = [...this.issues, sub]; }; this.addIssues = (subs = []) => { this.issues = [...this.issues, ...subs]; }; const actualProto = new.target.prototype; if (Object.setPrototypeOf) { // eslint-disable-next-line ban/ban Object.setPrototypeOf(this, actualProto); } else { this.__proto__ = actualProto; } this.name = "ZodError"; this.issues = issues; } format(_mapper) { const mapper = _mapper || function (issue) { return issue.message; }; const fieldErrors = { _errors: [] }; const processError = (error) => { for (const issue of error.issues) { if (issue.code === "invalid_union") { issue.unionErrors.map(processError); } else if (issue.code === "invalid_return_type") { processError(issue.returnTypeError); } else if (issue.code === "invalid_arguments") { processError(issue.argumentsError); } else if (issue.path.length === 0) { fieldErrors._errors.push(mapper(issue)); } else { let curr = fieldErrors; let i = 0; while (i < issue.path.length) { const el = issue.path[i]; const terminal = i === issue.path.length - 1; if (!terminal) { curr[el] = curr[el] || { _errors: [] }; // if (typeof el === "string") { // curr[el] = curr[el] || { _errors: [] }; // } else if (typeof el === "number") { // const errorArray: any = []; // errorArray._errors = []; // curr[el] = curr[el] || errorArray; // } } else { curr[el] = curr[el] || { _errors: [] }; curr[el]._errors.push(mapper(issue)); } curr = curr[el]; i++; } } } }; processError(this); return fieldErrors; } static assert(value) { if (!(value instanceof ZodError)) { throw new Error(`Not a ZodError: ${value}`); } } toString() { return this.message; } get message() { return JSON.stringify(this.issues, util$9.jsonStringifyReplacer, 2); } get isEmpty() { return this.issues.length === 0; } flatten(mapper = (issue) => issue.message) { const fieldErrors = {}; const formErrors = []; for (const sub of this.issues) { if (sub.path.length > 0) { fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || []; fieldErrors[sub.path[0]].push(mapper(sub)); } else { formErrors.push(mapper(sub)); } } return { formErrors, fieldErrors }; } get formErrors() { return this.flatten(); } } ZodError.create = (issues) => { const error = new ZodError(issues); return error; }; const errorMap = (issue, _ctx) => { let message; switch (issue.code) { case ZodIssueCode.invalid_type: if (issue.received === ZodParsedType.undefined) { message = "Required"; } else { message = `Expected ${issue.expected}, received ${issue.received}`; } break; case ZodIssueCode.invalid_literal: message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util$9.jsonStringifyReplacer)}`; break; case ZodIssueCode.unrecognized_keys: message = `Unrecognized key(s) in object: ${util$9.joinValues(issue.keys, ", ")}`; break; case ZodIssueCode.invalid_union: message = `Invalid input`; break; case ZodIssueCode.invalid_union_discriminator: message = `Invalid discriminator value. Expected ${util$9.joinValues(issue.options)}`; break; case ZodIssueCode.invalid_enum_value: message = `Invalid enum value. Expected ${util$9.joinValues(issue.options)}, received '${issue.received}'`; break; case ZodIssueCode.invalid_arguments: message = `Invalid function arguments`; break; case ZodIssueCode.invalid_return_type: message = `Invalid function return type`; break; case ZodIssueCode.invalid_date: message = `Invalid date`; break; case ZodIssueCode.invalid_string: if (typeof issue.validation === "object") { if ("includes" in issue.validation) { message = `Invalid input: must include "${issue.validation.includes}"`; if (typeof issue.validation.position === "number") { message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`; } } else if ("startsWith" in issue.validation) { message = `Invalid input: must start with "${issue.validation.startsWith}"`; } else if ("endsWith" in issue.validation) { message = `Invalid input: must end with "${issue.validation.endsWith}"`; } else { util$9.assertNever(issue.validation); } } else if (issue.validation !== "regex") { message = `Invalid ${issue.validation}`; } else { message = "Invalid"; } break; case ZodIssueCode.too_small: if (issue.type === "array") message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`; else if (issue.type === "string") message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`; else if (issue.type === "number") message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`; else if (issue.type === "date") message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`; else message = "Invalid input"; break; case ZodIssueCode.too_big: if (issue.type === "array") message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`; else if (issue.type === "string") message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`; else if (issue.type === "number") message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`; else if (issue.type === "bigint") message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`; else if (issue.type === "date") message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`; else message = "Invalid input"; break; case ZodIssueCode.custom: message = `Invalid input`; break; case ZodIssueCode.invalid_intersection_types: message = `Intersection results could not be merged`; break; case ZodIssueCode.not_multiple_of: message = `Number must be a multiple of ${issue.multipleOf}`; break; case ZodIssueCode.not_finite: message = "Number must be finite"; break; default: message = _ctx.defaultError; util$9.assertNever(issue); } return { message }; }; let overrideErrorMap = errorMap; function setErrorMap(map) { overrideErrorMap = map; } function getErrorMap() { return overrideErrorMap; } const makeIssue = (params) => { const { data, path, errorMaps, issueData } = params; const fullPath = [...path, ...(issueData.path || [])]; const fullIssue = { ...issueData, path: fullPath, }; if (issueData.message !== undefined) { return { ...issueData, path: fullPath, message: issueData.message, }; } let errorMessage = ""; const maps = errorMaps .filter((m) => !!m) .slice() .reverse(); for (const map of maps) { errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message; } return { ...issueData, path: fullPath, message: errorMessage, }; }; const EMPTY_PATH = []; function addIssueToContext(ctx, issueData) { const overrideMap = getErrorMap(); const issue = makeIssue({ issueData: issueData, data: ctx.data, path: ctx.path, errorMaps: [ ctx.common.contextualErrorMap, // contextual error map is first priority ctx.schemaErrorMap, // then schema-bound map if available overrideMap, // then global override map overrideMap === errorMap ? undefined : errorMap, // then global default map ].filter((x) => !!x), }); ctx.common.issues.push(issue); } class ParseStatus { constructor() { this.value = "valid"; } dirty() { if (this.value === "valid") this.value = "dirty"; } abort() { if (this.value !== "aborted") this.value = "aborted"; } static mergeArray(status, results) { const arrayValue = []; for (const s of results) { if (s.status === "aborted") return INVALID; if (s.status === "dirty") status.dirty(); arrayValue.push(s.value); } return { status: status.value, value: arrayValue }; } static async mergeObjectAsync(status, pairs) { const syncPairs = []; for (const pair of pairs) { const key = await pair.key; const value = await pair.value; syncPairs.push({ key, value, }); } return ParseStatus.mergeObjectSync(status, syncPairs); } static mergeObjectSync(status, pairs) { const finalObject = {}; for (const pair of pairs) { const { key, value } = pair; if (key.status === "aborted") return INVALID; if (value.status === "aborted") return INVALID; if (key.status === "dirty") status.dirty(); if (value.status === "dirty") status.dirty(); if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) { finalObject[key.value] = value.value; } } return { status: status.value, value: finalObject }; } } const INVALID = Object.freeze({ status: "aborted", }); const DIRTY = (value) => ({ status: "dirty", value }); const OK = (value) => ({ status: "valid", value }); const isAborted = (x) => x.status === "aborted"; const isDirty = (x) => x.status === "dirty"; const isValid = (x) => x.status === "valid"; const isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ function __classPrivateFieldGet(receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); } function __classPrivateFieldSet(receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var errorUtil; (function (errorUtil) { errorUtil.errToObj = (message) => typeof message === "string" ? { message } : message || {}; errorUtil.toString = (message) => typeof message === "string" ? message : message === null || message === void 0 ? void 0 : message.message; })(errorUtil || (errorUtil = {})); var _ZodEnum_cache, _ZodNativeEnum_cache; class ParseInputLazyPath { constructor(parent, value, path, key) { this._cachedPath = []; this.parent = parent; this.data = value; this._path = path; this._key = key; } get path() { if (!this._cachedPath.length) { if (this._key instanceof Array) { this._cachedPath.push(...this._path, ...this._key); } else { this._cachedPath.push(...this._path, this._key); } } return this._cachedPath; } } const handleResult = (ctx, result) => { if (isValid(result)) { return { success: true, data: result.value }; } else { if (!ctx.common.issues.length) { throw new Error("Validation failed but no issues detected."); } return { success: false, get error() { if (this._error) return this._error; const error = new ZodError(ctx.common.issues); this._error = error; return this._error; }, }; } }; function processCreateParams(params) { if (!params) return {}; const { errorMap, invalid_type_error, required_error, description } = params; if (errorMap && (invalid_type_error || required_error)) { throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`); } if (errorMap) return { errorMap: errorMap, description }; const customMap = (iss, ctx) => { var _a, _b; const { message } = params; if (iss.code === "invalid_enum_value") { return { message: message !== null && message !== void 0 ? message : ctx.defaultError }; } if (typeof ctx.data === "undefined") { return { message: (_a = message !== null && message !== void 0 ? message : required_error) !== null && _a !== void 0 ? _a : ctx.defaultError }; } if (iss.code !== "invalid_type") return { message: ctx.defaultError }; return { message: (_b = message !== null && message !== void 0 ? message : invalid_type_error) !== null && _b !== void 0 ? _b : ctx.defaultError }; }; return { errorMap: customMap, description }; } class ZodType { get description() { return this._def.description; } _getType(input) { return getParsedType(input.data); } _getOrReturnCtx(input, ctx) { return (ctx || { common: input.parent.common, data: input.data, parsedType: getParsedType(input.data), schemaErrorMap: this._def.errorMap, path: input.path, parent: input.parent, }); } _processInputParams(input) { return { status: new ParseStatus(), ctx: { common: input.parent.common, data: input.data, parsedType: getParsedType(input.data), schemaErrorMap: this._def.errorMap, path: input.path, parent: input.parent, }, }; } _parseSync(input) { const result = this._parse(input); if (isAsync(result)) { throw new Error("Synchronous parse encountered promise."); } return result; } _parseAsync(input) { const result = this._parse(input); return Promise.resolve(result); } parse(data, params) { const result = this.safeParse(data, params); if (result.success) return result.data; throw result.error; } safeParse(data, params) { var _a; const ctx = { common: { issues: [], async: (_a = params === null || params === void 0 ? void 0 : params.async) !== null && _a !== void 0 ? _a : false, contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap, }, path: (params === null || params === void 0 ? void 0 : params.path) || [], schemaErrorMap: this._def.errorMap, parent: null, data, parsedType: getParsedType(data), }; const result = this._parseSync({ data, path: ctx.path, parent: ctx }); return handleResult(ctx, result); } "~validate"(data) { var _a, _b; const ctx = { common: { issues: [], async: !!this["~standard"].async, }, path: [], schemaErrorMap: this._def.errorMap, parent: null, data, parsedType: getParsedType(data), }; if (!this["~standard"].async) { try { const result = this._parseSync({ data, path: [], parent: ctx }); return isValid(result) ? { value: result.value, } : { issues: ctx.common.issues, }; } catch (err) { if ((_b = (_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === null || _b === void 0 ? void 0 : _b.includes("encountered")) { this["~standard"].async = true; } ctx.common = { issues: [], async: true, }; } } return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result) ? { value: result.value, } : { issues: ctx.common.issues, }); } async parseAsync(data, params) { const result = await this.safeParseAsync(data, params); if (result.success) return result.data; throw result.error; } async safeParseAsync(data, params) { const ctx = { common: { issues: [], contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap, async: true, }, path: (params === null || params === void 0 ? void 0 : params.path) || [], schemaErrorMap: this._def.errorMap, parent: null, data, parsedType: getParsedType(data), }; const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx }); const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult)); return handleResult(ctx, result); } refine(check, message) { const getIssueProperties = (val) => { if (typeof message === "string" || typeof message === "undefined") { return { message }; } else if (typeof message === "function") { return message(val); } else { return message; } }; return this._refinement((val, ctx) => { const result = check(val); const setError = () => ctx.addIssue({ code: ZodIssueCode.custom, ...getIssueProperties(val), }); if (typeof Promise !== "undefined" && result instanceof Promise) { return result.then((data) => { if (!data) { setError(); return false; } else { return true; } }); } if (!result) { setError(); return false; } else { return true; } }); } refinement(check, refinementData) { return this._refinement((val, ctx) => { if (!check(val)) { ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData); return false; } else { return true; } }); } _refinement(refinement) { return new ZodEffects({ schema: this, typeName: ZodFirstPartyTypeKind.ZodEffects, effect: { type: "refinement", refinement }, }); } superRefine(refinement) { return this._refinement(refinement); } constructor(def) { /** Alias of safeParseAsync */ this.spa = this.safeParseAsync; this._def = def; this.parse = this.parse.bind(this); this.safeParse = this.safeParse.bind(this); this.parseAsync = this.parseAsync.bind(this); this.safeParseAsync = this.safeParseAsync.bind(this); this.spa = this.spa.bind(this); this.refine = this.refine.bind(this); this.refinement = this.refinement.bind(this); this.superRefine = this.superRefine.bind(this); this.optional = this.optional.bind(this); this.nullable = this.nullable.bind(this); this.nullish = this.nullish.bind(this); this.array = this.array.bind(this); this.promise = this.promise.bind(this); this.or = this.or.bind(this); this.and = this.and.bind(this); this.transform = this.transform.bind(this); this.brand = this.brand.bind(this); this.default = this.default.bind(this); this.catch = this.catch.bind(this); this.describe = this.describe.bind(this); this.pipe = this.pipe.bind(this); this.readonly = this.readonly.bind(this); this.isNullable = this.isNullable.bind(this); this.isOptional = this.isOptional.bind(this); this["~standard"] = { version: 1, vendor: "zod", validate: (data) => this["~validate"](data), }; } optional() { return ZodOptional.create(this, this._def); } nullable() { return ZodNullable.create(this, this._def); } nullish() { return this.nullable().optional(); } array() { return ZodArray.create(this); } promise() { return ZodPromise.create(this, this._def); } or(option) { return ZodUnion.create([this, option], this._def); } and(incoming) { return ZodIntersection.create(this, incoming, this._def); } transform(transform) { return new ZodEffects({ ...processCreateParams(this._def), schema: this, typeName: ZodFirstPartyTypeKind.ZodEffects, effect: { type: "transform", transform }, }); } default(def) { const defaultValueFunc = typeof def === "function" ? def : () => def; return new ZodDefault({ ...processCreateParams(this._def), innerType: this, defaultValue: defaultValueFunc, typeName: ZodFirstPartyTypeKind.ZodDefault, }); } brand() { return new ZodBranded({ typeName: ZodFirstPartyTypeKind.ZodBranded, type: this, ...processCreateParams(this._def), }); } catch(def) { const catchValueFunc = typeof def === "function" ? def : () => def; return new ZodCatch({ ...processCreateParams(this._def), innerType: this, catchValue: catchValueFunc, typeName: ZodFirstPartyTypeKind.ZodCatch, }); } describe(description) { const This = this.constructor; return new This({ ...this._def, description, }); } pipe(target) { return ZodPipeline.create(this, target); } readonly() { return ZodReadonly.create(this); } isOptional() { return this.safeParse(undefined).success; } isNullable() { return this.safeParse(null).success; } } const cuidRegex = /^c[^\s-]{8,}$/i; const cuid2Regex = /^[0-9a-z]+$/; const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i; // const uuidRegex = // /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i; const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i; const nanoidRegex = /^[a-z0-9_-]{21}$/i; const jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/; const durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/; // from https://stackoverflow.com/a/46181/1550155 // old version: too slow, didn't support unicode // const emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; //old email regex // const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@((?!-)([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{1,})[^-<>()[\].,;:\s@"]$/i; // eslint-disable-next-line // const emailRegex = // /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\])|(\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\.[A-Za-z]{2,})+))$/; // const emailRegex = // /^[a-zA-Z0-9\.\!\#\$\%\&\'\*\+\/\=\?\^\_\`\{\|\}\~\-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; // const emailRegex = // /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i; const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; // const emailRegex = // /^[a-z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-z0-9-]+(?:\.[a-z0-9\-]+)*$/i; // from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression const _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`; let emojiRegex; // faster, simpler, safer const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/; const ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/; // const ipv6Regex = // /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/; const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/; const ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/; // https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; // https://base64.guru/standards/base64url const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/; // simple // const dateRegexSource = `\\d{4}-\\d{2}-\\d{2}`; // no leap year validation // const dateRegexSource = `\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\\d|2\\d))`; // with leap year validation const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`; const dateRegex = new RegExp(`^${dateRegexSource}$`); function timeRegexSource(args) { // let regex = `\\d{2}:\\d{2}:\\d{2}`; let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`; if (args.precision) { regex = `${regex}\\.\\d{${args.precision}}`; } else if (args.precision == null) { regex = `${regex}(\\.\\d+)?`; } return regex; } function timeRegex(args) { return new RegExp(`^${timeRegexSource(args)}$`); } // Adapted from https://stackoverflow.com/a/3143231 function datetimeRegex(args) { let regex = `${dateRegexSource}T${timeRegexSource(args)}`; const opts = []; opts.push(args.local ? `Z?` : `Z`); if (args.offset) opts.push(`([+-]\\d{2}:?\\d{2})`); regex = `${regex}(${opts.join("|")})`; return new RegExp(`^${regex}$`); } function isValidIP(ip, version) { if ((version === "v4" || !version) && ipv4Regex.test(ip)) { return true; } if ((version === "v6" || !version) && ipv6Regex.test(ip)) { return true; } return false; } function isValidJWT(jwt, alg) { if (!jwtRegex.test(jwt)) return false; try { const [header] = jwt.split("."); // Convert base64url to base64 const base64 = header .replace(/-/g, "+") .replace(/_/g, "/") .padEnd(header.length + ((4 - (header.length % 4)) % 4), "="); const decoded = JSON.parse(atob(base64)); if (typeof decoded !== "object" || decoded === null) return false; if (!decoded.typ || !decoded.alg) return false; if (alg && decoded.alg !== alg) return false; return true; } catch (_a) { return false; } } function isValidCidr(ip, version) { if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) { return true; } if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) { return true; } return false; } class ZodString extends ZodType { _parse(input) { if (this._def.coerce) { input.data = String(input.data); } const parsedType = this._getType(input); if (parsedType !== ZodParsedType.string) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.string, received: ctx.parsedType, }); return INVALID; } const status = new ParseStatus(); let ctx = undefined; for (const check of this._def.checks) { if (check.kind === "min") { if (input.data.length < check.value) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.too_small, minimum: check.value, type: "string", inclusive: true, exact: false, message: check.message, }); status.dirty(); } } else if (check.kind === "max") { if (input.data.length > check.value) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.too_big, maximum: check.value, type: "string", inclusive: true, exact: false, message: check.message, }); status.dirty(); } } else if (check.kind === "length") { const tooBig = input.data.length > check.value; const tooSmall = input.data.length < check.value; if (tooBig || tooSmall) { ctx = this._getOrReturnCtx(input, ctx); if (tooBig) { addIssueToContext(ctx, { code: ZodIssueCode.too_big, maximum: check.value, type: "string", inclusive: true, exact: true, message: check.message, }); } else if (tooSmall) { addIssueToContext(ctx, { code: ZodIssueCode.too_small, minimum: check.value, type: "string", inclusive: true, exact: true, message: check.message, }); } status.dirty(); } } else if (check.kind === "email") { if (!emailRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "email", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "emoji") { if (!emojiRegex) { emojiRegex = new RegExp(_emojiRegex, "u"); } if (!emojiRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "emoji", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "uuid") { if (!uuidRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "uuid", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "nanoid") { if (!nanoidRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "nanoid", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "cuid") { if (!cuidRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "cuid", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "cuid2") { if (!cuid2Regex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "cuid2", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "ulid") { if (!ulidRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "ulid", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "url") { try { new URL(input.data); } catch (_a) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "url", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "regex") { check.regex.lastIndex = 0; const testResult = check.regex.test(input.data); if (!testResult) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "regex", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "trim") { input.data = input.data.trim(); } else if (check.kind === "includes") { if (!input.data.includes(check.value, check.position)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.invalid_string, validation: { includes: check.value, position: check.position }, message: check.message, }); status.dirty(); } } else if (check.kind === "toLowerCase") { input.data = input.data.toLowerCase(); } else if (check.kind === "toUpperCase") { input.data = input.data.toUpperCase(); } else if (check.kind === "startsWith") { if (!input.data.startsWith(check.value)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.invalid_string, validation: { startsWith: check.value }, message: check.message, }); status.dirty(); } } else if (check.kind === "endsWith") { if (!input.data.endsWith(check.value)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.invalid_string, validation: { endsWith: check.value }, message: check.message, }); status.dirty(); } } else if (check.kind === "datetime") { const regex = datetimeRegex(check); if (!regex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.invalid_string, validation: "datetime", message: check.message, }); status.dirty(); } } else if (check.kind === "date") { const regex = dateRegex; if (!regex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.invalid_string, validation: "date", message: check.message, }); status.dirty(); } } else if (check.kind === "time") { const regex = timeRegex(check); if (!regex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.invalid_string, validation: "time", message: check.message, }); status.dirty(); } } else if (check.kind === "duration") { if (!durationRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "duration", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "ip") { if (!isValidIP(input.data, check.version)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "ip", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "jwt") { if (!isValidJWT(input.data, check.alg)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "jwt", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "cidr") { if (!isValidCidr(input.data, check.version)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "cidr", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "base64") { if (!base64Regex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "base64", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else if (check.kind === "base64url") { if (!base64urlRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { validation: "base64url", code: ZodIssueCode.invalid_string, message: check.message, }); status.dirty(); } } else { util$9.assertNever(check); } } return { status: status.value, value: input.data }; } _regex(regex, validation, message) { return this.refinement((data) => regex.test(data), { validation, code: ZodIssueCode.invalid_string, ...errorUtil.errToObj(message), }); } _addCheck(check) { return new ZodString({ ...this._def, checks: [...this._def.checks, check], }); } email(message) { return this._addCheck({ kind: "email", ...errorUtil.errToObj(message) }); } url(message) { return this._addCheck({ kind: "url", ...errorUtil.errToObj(message) }); } emoji(message) { return this._addCheck({ kind: "emoji", ...errorUtil.errToObj(message) }); } uuid(message) { return this._addCheck({ kind: "uuid", ...errorUtil.errToObj(message) }); } nanoid(message) { return this._addCheck({ kind: "nanoid", ...errorUtil.errToObj(message) }); } cuid(message) { return this._addCheck({ kind: "cuid", ...errorUtil.errToObj(message) }); } cuid2(message) { return this._addCheck({ kind: "cuid2", ...errorUtil.errToObj(message) }); } ulid(message) { return this._addCheck({ kind: "ulid", ...errorUtil.errToObj(message) }); } base64(message) { return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message) }); } base64url(message) { // base64url encoding is a modification of base64 that can safely be used in URLs and filenames return this._addCheck({ kind: "base64url", ...errorUtil.errToObj(message), }); } jwt(options) { return this._addCheck({ kind: "jwt", ...errorUtil.errToObj(options) }); } ip(options) { return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) }); } cidr(options) { return this._addCheck({ kind: "cidr", ...errorUtil.errToObj(options) }); } datetime(options) { var _a, _b; if (typeof options === "string") { return this._addCheck({ kind: "datetime", precision: null, offset: false, local: false, message: options, }); } return this._addCheck({ kind: "datetime", precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision, offset: (_a = options === null || options === void 0 ? void 0 : options.offset) !== null && _a !== void 0 ? _a : false, local: (_b = options === null || options === void 0 ? void 0 : options.local) !== null && _b !== void 0 ? _b : false, ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message), }); } date(message) { return this._addCheck({ kind: "date", message }); } time(options) { if (typeof options === "string") { return this._addCheck({ kind: "time", precision: null, message: options, }); } return this._addCheck({ kind: "time", precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision, ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message), }); } duration(message) { return this._addCheck({ kind: "duration", ...errorUtil.errToObj(message) }); } regex(regex, message) { return this._addCheck({ kind: "regex", regex: regex, ...errorUtil.errToObj(message), }); } includes(value, options) { return this._addCheck({ kind: "includes", value: value, position: options === null || options === void 0 ? void 0 : options.position, ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message), }); } startsWith(value, message) { return this._addCheck({ kind: "startsWith", value: value, ...errorUtil.errToObj(message), }); } endsWith(value, message) { return this._addCheck({ kind: "endsWith", value: value, ...errorUtil.errToObj(message), }); } min(minLength, message) { return this._addCheck({ kind: "min", value: minLength, ...errorUtil.errToObj(message), }); } max(maxLength, message) { return this._addCheck({ kind: "max", value: maxLength, ...errorUtil.errToObj(message), }); } length(len, message) { return this._addCheck({ kind: "length", value: len, ...errorUtil.errToObj(message), }); } /** * Equivalent to `.min(1)` */ nonempty(message) { return this.min(1, errorUtil.errToObj(message)); } trim() { return new ZodString({ ...this._def, checks: [...this._def.checks, { kind: "trim" }], }); } toLowerCase() { return new ZodString({ ...this._def, checks: [...this._def.checks, { kind: "toLowerCase" }], }); } toUpperCase() { return new ZodString({ ...this._def, checks: [...this._def.checks, { kind: "toUpperCase" }], }); } get isDatetime() { return !!this._def.checks.find((ch) => ch.kind === "datetime"); } get isDate() { return !!this._def.checks.find((ch) => ch.kind === "date"); } get isTime() { return !!this._def.checks.find((ch) => ch.kind === "time"); } get isDuration() { return !!this._def.checks.find((ch) => ch.kind === "duration"); } get isEmail() { return !!this._def.checks.find((ch) => ch.kind === "email"); } get isURL() { return !!this._def.checks.find((ch) => ch.kind === "url"); } get isEmoji() { return !!this._def.checks.find((ch) => ch.kind === "emoji"); } get isUUID() { return !!this._def.checks.find((ch) => ch.kind === "uuid"); } get isNANOID() { return !!this._def.checks.find((ch) => ch.kind === "nanoid"); } get isCUID() { return !!this._def.checks.find((ch) => ch.kind === "cuid"); } get isCUID2() { return !!this._def.checks.find((ch) => ch.kind === "cuid2"); } get isULID() { return !!this._def.checks.find((ch) => ch.kind === "ulid"); } get isIP() { return !!this._def.checks.find((ch) => ch.kind === "ip"); } get isCIDR() { return !!this._def.checks.find((ch) => ch.kind === "cidr"); } get isBase64() { return !!this._def.checks.find((ch) => ch.kind === "base64"); } get isBase64url() { // base64url encoding is a modification of base64 that can safely be used in URLs and filenames return !!this._def.checks.find((ch) => ch.kind === "base64url"); } get minLength() { let min = null; for (const ch of this._def.checks) { if (ch.kind === "min") { if (min === null || ch.value > min) min = ch.value; } } return min; } get maxLength() { let max = null; for (const ch of this._def.checks) { if (ch.kind === "max") { if (max === null || ch.value < max) max = ch.value; } } return max; } } ZodString.create = (params) => { var _a; return new ZodString({ checks: [], typeName: ZodFirstPartyTypeKind.ZodString, coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false, ...processCreateParams(params), }); }; // https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034 function floatSafeRemainder(val, step) { const valDecCount = (val.toString().split(".")[1] || "").length; const stepDecCount = (step.toString().split(".")[1] || "").length; const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount; const valInt = parseInt(val.toFixed(decCount).replace(".", "")); const stepInt = parseInt(step.toFixed(decCount).replace(".", "")); return (valInt % stepInt) / Math.pow(10, decCount); } class ZodNumber extends ZodType { constructor() { super(...arguments); this.min = this.gte; this.max = this.lte; this.step = this.multipleOf; } _parse(input) { if (this._def.coerce) { input.data = Number(input.data); } const parsedType = this._getType(input); if (parsedType !== ZodParsedType.number) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.number, received: ctx.parsedType, }); return INVALID; } let ctx = undefined; const status = new ParseStatus(); for (const check of this._def.checks) { if (check.kind === "int") { if (!util$9.isInteger(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: "integer", received: "float", message: check.message, }); status.dirty(); } } else if (check.kind === "min") { const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value; if (tooSmall) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.too_small, minimum: check.value, type: "number", inclusive: check.inclusive, exact: false, message: check.message, }); status.dirty(); } } else if (check.kind === "max") { const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value; if (tooBig) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.too_big, maximum: check.value, type: "number", inclusive: check.inclusive, exact: false, message: check.message, }); status.dirty(); } } else if (check.kind === "multipleOf") { if (floatSafeRemainder(input.data, check.value) !== 0) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.not_multiple_of, multipleOf: check.value, message: check.message, }); status.dirty(); } } else if (check.kind === "finite") { if (!Number.isFinite(input.data)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.not_finite, message: check.message, }); status.dirty(); } } else { util$9.assertNever(check); } } return { status: status.value, value: input.data }; } gte(value, message) { return this.setLimit("min", value, true, errorUtil.toString(message)); } gt(value, message) { return this.setLimit("min", value, false, errorUtil.toString(message)); } lte(value, message) { return this.setLimit("max", value, true, errorUtil.toString(message)); } lt(value, message) { return this.setLimit("max", value, false, errorUtil.toString(message)); } setLimit(kind, value, inclusive, message) { return new ZodNumber({ ...this._def, checks: [ ...this._def.checks, { kind, value, inclusive, message: errorUtil.toString(message), }, ], }); } _addCheck(check) { return new ZodNumber({ ...this._def, checks: [...this._def.checks, check], }); } int(message) { return this._addCheck({ kind: "int", message: errorUtil.toString(message), }); } positive(message) { return this._addCheck({ kind: "min", value: 0, inclusive: false, message: errorUtil.toString(message), }); } negative(message) { return this._addCheck({ kind: "max", value: 0, inclusive: false, message: errorUtil.toString(message), }); } nonpositive(message) { return this._addCheck({ kind: "max", value: 0, inclusive: true, message: errorUtil.toString(message), }); } nonnegative(message) { return this._addCheck({ kind: "min", value: 0, inclusive: true, message: errorUtil.toString(message), }); } multipleOf(value, message) { return this._addCheck({ kind: "multipleOf", value: value, message: errorUtil.toString(message), }); } finite(message) { return this._addCheck({ kind: "finite", message: errorUtil.toString(message), }); } safe(message) { return this._addCheck({ kind: "min", inclusive: true, value: Number.MIN_SAFE_INTEGER, message: errorUtil.toString(message), })._addCheck({ kind: "max", inclusive: true, value: Number.MAX_SAFE_INTEGER, message: errorUtil.toString(message), }); } get minValue() { let min = null; for (const ch of this._def.checks) { if (ch.kind === "min") { if (min === null || ch.value > min) min = ch.value; } } return min; } get maxValue() { let max = null; for (const ch of this._def.checks) { if (ch.kind === "max") { if (max === null || ch.value < max) max = ch.value; } } return max; } get isInt() { return !!this._def.checks.find((ch) => ch.kind === "int" || (ch.kind === "multipleOf" && util$9.isInteger(ch.value))); } get isFinite() { let max = null, min = null; for (const ch of this._def.checks) { if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") { return true; } else if (ch.kind === "min") { if (min === null || ch.value > min) min = ch.value; } else if (ch.kind === "max") { if (max === null || ch.value < max) max = ch.value; } } return Number.isFinite(min) && Number.isFinite(max); } } ZodNumber.create = (params) => { return new ZodNumber({ checks: [], typeName: ZodFirstPartyTypeKind.ZodNumber, coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false, ...processCreateParams(params), }); }; class ZodBigInt extends ZodType { constructor() { super(...arguments); this.min = this.gte; this.max = this.lte; } _parse(input) { if (this._def.coerce) { try { input.data = BigInt(input.data); } catch (_a) { return this._getInvalidInput(input); } } const parsedType = this._getType(input); if (parsedType !== ZodParsedType.bigint) { return this._getInvalidInput(input); } let ctx = undefined; const status = new ParseStatus(); for (const check of this._def.checks) { if (check.kind === "min") { const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value; if (tooSmall) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.too_small, type: "bigint", minimum: check.value, inclusive: check.inclusive, message: check.message, }); status.dirty(); } } else if (check.kind === "max") { const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value; if (tooBig) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.too_big, type: "bigint", maximum: check.value, inclusive: check.inclusive, message: check.message, }); status.dirty(); } } else if (check.kind === "multipleOf") { if (input.data % check.value !== BigInt(0)) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.not_multiple_of, multipleOf: check.value, message: check.message, }); status.dirty(); } } else { util$9.assertNever(check); } } return { status: status.value, value: input.data }; } _getInvalidInput(input) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.bigint, received: ctx.parsedType, }); return INVALID; } gte(value, message) { return this.setLimit("min", value, true, errorUtil.toString(message)); } gt(value, message) { return this.setLimit("min", value, false, errorUtil.toString(message)); } lte(value, message) { return this.setLimit("max", value, true, errorUtil.toString(message)); } lt(value, message) { return this.setLimit("max", value, false, errorUtil.toString(message)); } setLimit(kind, value, inclusive, message) { return new ZodBigInt({ ...this._def, checks: [ ...this._def.checks, { kind, value, inclusive, message: errorUtil.toString(message), }, ], }); } _addCheck(check) { return new ZodBigInt({ ...this._def, checks: [...this._def.checks, check], }); } positive(message) { return this._addCheck({ kind: "min", value: BigInt(0), inclusive: false, message: errorUtil.toString(message), }); } negative(message) { return this._addCheck({ kind: "max", value: BigInt(0), inclusive: false, message: errorUtil.toString(message), }); } nonpositive(message) { return this._addCheck({ kind: "max", value: BigInt(0), inclusive: true, message: errorUtil.toString(message), }); } nonnegative(message) { return this._addCheck({ kind: "min", value: BigInt(0), inclusive: true, message: errorUtil.toString(message), }); } multipleOf(value, message) { return this._addCheck({ kind: "multipleOf", value, message: errorUtil.toString(message), }); } get minValue() { let min = null; for (const ch of this._def.checks) { if (ch.kind === "min") { if (min === null || ch.value > min) min = ch.value; } } return min; } get maxValue() { let max = null; for (const ch of this._def.checks) { if (ch.kind === "max") { if (max === null || ch.value < max) max = ch.value; } } return max; } } ZodBigInt.create = (params) => { var _a; return new ZodBigInt({ checks: [], typeName: ZodFirstPartyTypeKind.ZodBigInt, coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false, ...processCreateParams(params), }); }; class ZodBoolean extends ZodType { _parse(input) { if (this._def.coerce) { input.data = Boolean(input.data); } const parsedType = this._getType(input); if (parsedType !== ZodParsedType.boolean) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.boolean, received: ctx.parsedType, }); return INVALID; } return OK(input.data); } } ZodBoolean.create = (params) => { return new ZodBoolean({ typeName: ZodFirstPartyTypeKind.ZodBoolean, coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false, ...processCreateParams(params), }); }; class ZodDate extends ZodType { _parse(input) { if (this._def.coerce) { input.data = new Date(input.data); } const parsedType = this._getType(input); if (parsedType !== ZodParsedType.date) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.date, received: ctx.parsedType, }); return INVALID; } if (isNaN(input.data.getTime())) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_date, }); return INVALID; } const status = new ParseStatus(); let ctx = undefined; for (const check of this._def.checks) { if (check.kind === "min") { if (input.data.getTime() < check.value) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.too_small, message: check.message, inclusive: true, exact: false, minimum: check.value, type: "date", }); status.dirty(); } } else if (check.kind === "max") { if (input.data.getTime() > check.value) { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { code: ZodIssueCode.too_big, message: check.message, inclusive: true, exact: false, maximum: check.value, type: "date", }); status.dirty(); } } else { util$9.assertNever(check); } } return { status: status.value, value: new Date(input.data.getTime()), }; } _addCheck(check) { return new ZodDate({ ...this._def, checks: [...this._def.checks, check], }); } min(minDate, message) { return this._addCheck({ kind: "min", value: minDate.getTime(), message: errorUtil.toString(message), }); } max(maxDate, message) { return this._addCheck({ kind: "max", value: maxDate.getTime(), message: errorUtil.toString(message), }); } get minDate() { let min = null; for (const ch of this._def.checks) { if (ch.kind === "min") { if (min === null || ch.value > min) min = ch.value; } } return min != null ? new Date(min) : null; } get maxDate() { let max = null; for (const ch of this._def.checks) { if (ch.kind === "max") { if (max === null || ch.value < max) max = ch.value; } } return max != null ? new Date(max) : null; } } ZodDate.create = (params) => { return new ZodDate({ checks: [], coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false, typeName: ZodFirstPartyTypeKind.ZodDate, ...processCreateParams(params), }); }; class ZodSymbol extends ZodType { _parse(input) { const parsedType = this._getType(input); if (parsedType !== ZodParsedType.symbol) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.symbol, received: ctx.parsedType, }); return INVALID; } return OK(input.data); } } ZodSymbol.create = (params) => { return new ZodSymbol({ typeName: ZodFirstPartyTypeKind.ZodSymbol, ...processCreateParams(params), }); }; class ZodUndefined extends ZodType { _parse(input) { const parsedType = this._getType(input); if (parsedType !== ZodParsedType.undefined) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.undefined, received: ctx.parsedType, }); return INVALID; } return OK(input.data); } } ZodUndefined.create = (params) => { return new ZodUndefined({ typeName: ZodFirstPartyTypeKind.ZodUndefined, ...processCreateParams(params), }); }; class ZodNull extends ZodType { _parse(input) { const parsedType = this._getType(input); if (parsedType !== ZodParsedType.null) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.null, received: ctx.parsedType, }); return INVALID; } return OK(input.data); } } ZodNull.create = (params) => { return new ZodNull({ typeName: ZodFirstPartyTypeKind.ZodNull, ...processCreateParams(params), }); }; class ZodAny extends ZodType { constructor() { super(...arguments); // to prevent instances of other classes from extending ZodAny. this causes issues with catchall in ZodObject. this._any = true; } _parse(input) { return OK(input.data); } } ZodAny.create = (params) => { return new ZodAny({ typeName: ZodFirstPartyTypeKind.ZodAny, ...processCreateParams(params), }); }; class ZodUnknown extends ZodType { constructor() { super(...arguments); // required this._unknown = true; } _parse(input) { return OK(input.data); } } ZodUnknown.create = (params) => { return new ZodUnknown({ typeName: ZodFirstPartyTypeKind.ZodUnknown, ...processCreateParams(params), }); }; class ZodNever extends ZodType { _parse(input) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.never, received: ctx.parsedType, }); return INVALID; } } ZodNever.create = (params) => { return new ZodNever({ typeName: ZodFirstPartyTypeKind.ZodNever, ...processCreateParams(params), }); }; class ZodVoid extends ZodType { _parse(input) { const parsedType = this._getType(input); if (parsedType !== ZodParsedType.undefined) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.void, received: ctx.parsedType, }); return INVALID; } return OK(input.data); } } ZodVoid.create = (params) => { return new ZodVoid({ typeName: ZodFirstPartyTypeKind.ZodVoid, ...processCreateParams(params), }); }; class ZodArray extends ZodType { _parse(input) { const { ctx, status } = this._processInputParams(input); const def = this._def; if (ctx.parsedType !== ZodParsedType.array) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.array, received: ctx.parsedType, }); return INVALID; } if (def.exactLength !== null) { const tooBig = ctx.data.length > def.exactLength.value; const tooSmall = ctx.data.length < def.exactLength.value; if (tooBig || tooSmall) { addIssueToContext(ctx, { code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small, minimum: (tooSmall ? def.exactLength.value : undefined), maximum: (tooBig ? def.exactLength.value : undefined), type: "array", inclusive: true, exact: true, message: def.exactLength.message, }); status.dirty(); } } if (def.minLength !== null) { if (ctx.data.length < def.minLength.value) { addIssueToContext(ctx, { code: ZodIssueCode.too_small, minimum: def.minLength.value, type: "array", inclusive: true, exact: false, message: def.minLength.message, }); status.dirty(); } } if (def.maxLength !== null) { if (ctx.data.length > def.maxLength.value) { addIssueToContext(ctx, { code: ZodIssueCode.too_big, maximum: def.maxLength.value, type: "array", inclusive: true, exact: false, message: def.maxLength.message, }); status.dirty(); } } if (ctx.common.async) { return Promise.all([...ctx.data].map((item, i) => { return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i)); })).then((result) => { return ParseStatus.mergeArray(status, result); }); } const result = [...ctx.data].map((item, i) => { return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i)); }); return ParseStatus.mergeArray(status, result); } get element() { return this._def.type; } min(minLength, message) { return new ZodArray({ ...this._def, minLength: { value: minLength, message: errorUtil.toString(message) }, }); } max(maxLength, message) { return new ZodArray({ ...this._def, maxLength: { value: maxLength, message: errorUtil.toString(message) }, }); } length(len, message) { return new ZodArray({ ...this._def, exactLength: { value: len, message: errorUtil.toString(message) }, }); } nonempty(message) { return this.min(1, message); } } ZodArray.create = (schema, params) => { return new ZodArray({ type: schema, minLength: null, maxLength: null, exactLength: null, typeName: ZodFirstPartyTypeKind.ZodArray, ...processCreateParams(params), }); }; function deepPartialify(schema) { if (schema instanceof ZodObject) { const newShape = {}; for (const key in schema.shape) { const fieldSchema = schema.shape[key]; newShape[key] = ZodOptional.create(deepPartialify(fieldSchema)); } return new ZodObject({ ...schema._def, shape: () => newShape, }); } else if (schema instanceof ZodArray) { return new ZodArray({ ...schema._def, type: deepPartialify(schema.element), }); } else if (schema instanceof ZodOptional) { return ZodOptional.create(deepPartialify(schema.unwrap())); } else if (schema instanceof ZodNullable) { return ZodNullable.create(deepPartialify(schema.unwrap())); } else if (schema instanceof ZodTuple) { return ZodTuple.create(schema.items.map((item) => deepPartialify(item))); } else { return schema; } } class ZodObject extends ZodType { constructor() { super(...arguments); this._cached = null; /** * @deprecated In most cases, this is no longer needed - unknown properties are now silently stripped. * If you want to pass through unknown properties, use `.passthrough()` instead. */ this.nonstrict = this.passthrough; // extend< // Augmentation extends ZodRawShape, // NewOutput extends util.flatten<{ // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation // ? Augmentation[k]["_output"] // : k extends keyof Output // ? Output[k] // : never; // }>, // NewInput extends util.flatten<{ // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation // ? Augmentation[k]["_input"] // : k extends keyof Input // ? Input[k] // : never; // }> // >( // augmentation: Augmentation // ): ZodObject< // extendShape, // UnknownKeys, // Catchall, // NewOutput, // NewInput // > { // return new ZodObject({ // ...this._def, // shape: () => ({ // ...this._def.shape(), // ...augmentation, // }), // }) as any; // } /** * @deprecated Use `.extend` instead * */ this.augment = this.extend; } _getCached() { if (this._cached !== null) return this._cached; const shape = this._def.shape(); const keys = util$9.objectKeys(shape); return (this._cached = { shape, keys }); } _parse(input) { const parsedType = this._getType(input); if (parsedType !== ZodParsedType.object) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.object, received: ctx.parsedType, }); return INVALID; } const { status, ctx } = this._processInputParams(input); const { shape, keys: shapeKeys } = this._getCached(); const extraKeys = []; if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) { for (const key in ctx.data) { if (!shapeKeys.includes(key)) { extraKeys.push(key); } } } const pairs = []; for (const key of shapeKeys) { const keyValidator = shape[key]; const value = ctx.data[key]; pairs.push({ key: { status: "valid", value: key }, value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)), alwaysSet: key in ctx.data, }); } if (this._def.catchall instanceof ZodNever) { const unknownKeys = this._def.unknownKeys; if (unknownKeys === "passthrough") { for (const key of extraKeys) { pairs.push({ key: { status: "valid", value: key }, value: { status: "valid", value: ctx.data[key] }, }); } } else if (unknownKeys === "strict") { if (extraKeys.length > 0) { addIssueToContext(ctx, { code: ZodIssueCode.unrecognized_keys, keys: extraKeys, }); status.dirty(); } } else if (unknownKeys === "strip") ; else { throw new Error(`Internal ZodObject error: invalid unknownKeys value.`); } } else { // run catchall validation const catchall = this._def.catchall; for (const key of extraKeys) { const value = ctx.data[key]; pairs.push({ key: { status: "valid", value: key }, value: catchall._parse(new ParseInputLazyPath(ctx, value, ctx.path, key) //, ctx.child(key), value, getParsedType(value) ), alwaysSet: key in ctx.data, }); } } if (ctx.common.async) { return Promise.resolve() .then(async () => { const syncPairs = []; for (const pair of pairs) { const key = await pair.key; const value = await pair.value; syncPairs.push({ key, value, alwaysSet: pair.alwaysSet, }); } return syncPairs; }) .then((syncPairs) => { return ParseStatus.mergeObjectSync(status, syncPairs); }); } else { return ParseStatus.mergeObjectSync(status, pairs); } } get shape() { return this._def.shape(); } strict(message) { errorUtil.errToObj; return new ZodObject({ ...this._def, unknownKeys: "strict", ...(message !== undefined ? { errorMap: (issue, ctx) => { var _a, _b, _c, _d; const defaultError = (_c = (_b = (_a = this._def).errorMap) === null || _b === void 0 ? void 0 : _b.call(_a, issue, ctx).message) !== null && _c !== void 0 ? _c : ctx.defaultError; if (issue.code === "unrecognized_keys") return { message: (_d = errorUtil.errToObj(message).message) !== null && _d !== void 0 ? _d : defaultError, }; return { message: defaultError, }; }, } : {}), }); } strip() { return new ZodObject({ ...this._def, unknownKeys: "strip", }); } passthrough() { return new ZodObject({ ...this._def, unknownKeys: "passthrough", }); } // const AugmentFactory = // (def: Def) => // ( // augmentation: Augmentation // ): ZodObject< // extendShape, Augmentation>, // Def["unknownKeys"], // Def["catchall"] // > => { // return new ZodObject({ // ...def, // shape: () => ({ // ...def.shape(), // ...augmentation, // }), // }) as any; // }; extend(augmentation) { return new ZodObject({ ...this._def, shape: () => ({ ...this._def.shape(), ...augmentation, }), }); } /** * Prior to zod@1.0.12 there was a bug in the * inferred type of merged objects. Please * upgrade if you are experiencing issues. */ merge(merging) { const merged = new ZodObject({ unknownKeys: merging._def.unknownKeys, catchall: merging._def.catchall, shape: () => ({ ...this._def.shape(), ...merging._def.shape(), }), typeName: ZodFirstPartyTypeKind.ZodObject, }); return merged; } // merge< // Incoming extends AnyZodObject, // Augmentation extends Incoming["shape"], // NewOutput extends { // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation // ? Augmentation[k]["_output"] // : k extends keyof Output // ? Output[k] // : never; // }, // NewInput extends { // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation // ? Augmentation[k]["_input"] // : k extends keyof Input // ? Input[k] // : never; // } // >( // merging: Incoming // ): ZodObject< // extendShape>, // Incoming["_def"]["unknownKeys"], // Incoming["_def"]["catchall"], // NewOutput, // NewInput // > { // const merged: any = new ZodObject({ // unknownKeys: merging._def.unknownKeys, // catchall: merging._def.catchall, // shape: () => // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), // typeName: ZodFirstPartyTypeKind.ZodObject, // }) as any; // return merged; // } setKey(key, schema) { return this.augment({ [key]: schema }); } // merge( // merging: Incoming // ): //ZodObject = (merging) => { // ZodObject< // extendShape>, // Incoming["_def"]["unknownKeys"], // Incoming["_def"]["catchall"] // > { // // const mergedShape = objectUtil.mergeShapes( // // this._def.shape(), // // merging._def.shape() // // ); // const merged: any = new ZodObject({ // unknownKeys: merging._def.unknownKeys, // catchall: merging._def.catchall, // shape: () => // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()), // typeName: ZodFirstPartyTypeKind.ZodObject, // }) as any; // return merged; // } catchall(index) { return new ZodObject({ ...this._def, catchall: index, }); } pick(mask) { const shape = {}; util$9.objectKeys(mask).forEach((key) => { if (mask[key] && this.shape[key]) { shape[key] = this.shape[key]; } }); return new ZodObject({ ...this._def, shape: () => shape, }); } omit(mask) { const shape = {}; util$9.objectKeys(this.shape).forEach((key) => { if (!mask[key]) { shape[key] = this.shape[key]; } }); return new ZodObject({ ...this._def, shape: () => shape, }); } /** * @deprecated */ deepPartial() { return deepPartialify(this); } partial(mask) { const newShape = {}; util$9.objectKeys(this.shape).forEach((key) => { const fieldSchema = this.shape[key]; if (mask && !mask[key]) { newShape[key] = fieldSchema; } else { newShape[key] = fieldSchema.optional(); } }); return new ZodObject({ ...this._def, shape: () => newShape, }); } required(mask) { const newShape = {}; util$9.objectKeys(this.shape).forEach((key) => { if (mask && !mask[key]) { newShape[key] = this.shape[key]; } else { const fieldSchema = this.shape[key]; let newField = fieldSchema; while (newField instanceof ZodOptional) { newField = newField._def.innerType; } newShape[key] = newField; } }); return new ZodObject({ ...this._def, shape: () => newShape, }); } keyof() { return createZodEnum(util$9.objectKeys(this.shape)); } } ZodObject.create = (shape, params) => { return new ZodObject({ shape: () => shape, unknownKeys: "strip", catchall: ZodNever.create(), typeName: ZodFirstPartyTypeKind.ZodObject, ...processCreateParams(params), }); }; ZodObject.strictCreate = (shape, params) => { return new ZodObject({ shape: () => shape, unknownKeys: "strict", catchall: ZodNever.create(), typeName: ZodFirstPartyTypeKind.ZodObject, ...processCreateParams(params), }); }; ZodObject.lazycreate = (shape, params) => { return new ZodObject({ shape, unknownKeys: "strip", catchall: ZodNever.create(), typeName: ZodFirstPartyTypeKind.ZodObject, ...processCreateParams(params), }); }; class ZodUnion extends ZodType { _parse(input) { const { ctx } = this._processInputParams(input); const options = this._def.options; function handleResults(results) { // return first issue-free validation if it exists for (const result of results) { if (result.result.status === "valid") { return result.result; } } for (const result of results) { if (result.result.status === "dirty") { // add issues from dirty option ctx.common.issues.push(...result.ctx.common.issues); return result.result; } } // return invalid const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues)); addIssueToContext(ctx, { code: ZodIssueCode.invalid_union, unionErrors, }); return INVALID; } if (ctx.common.async) { return Promise.all(options.map(async (option) => { const childCtx = { ...ctx, common: { ...ctx.common, issues: [], }, parent: null, }; return { result: await option._parseAsync({ data: ctx.data, path: ctx.path, parent: childCtx, }), ctx: childCtx, }; })).then(handleResults); } else { let dirty = undefined; const issues = []; for (const option of options) { const childCtx = { ...ctx, common: { ...ctx.common, issues: [], }, parent: null, }; const result = option._parseSync({ data: ctx.data, path: ctx.path, parent: childCtx, }); if (result.status === "valid") { return result; } else if (result.status === "dirty" && !dirty) { dirty = { result, ctx: childCtx }; } if (childCtx.common.issues.length) { issues.push(childCtx.common.issues); } } if (dirty) { ctx.common.issues.push(...dirty.ctx.common.issues); return dirty.result; } const unionErrors = issues.map((issues) => new ZodError(issues)); addIssueToContext(ctx, { code: ZodIssueCode.invalid_union, unionErrors, }); return INVALID; } } get options() { return this._def.options; } } ZodUnion.create = (types, params) => { return new ZodUnion({ options: types, typeName: ZodFirstPartyTypeKind.ZodUnion, ...processCreateParams(params), }); }; ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// ////////// ////////// ////////// ZodDiscriminatedUnion ////////// ////////// ////////// ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// const getDiscriminator = (type) => { if (type instanceof ZodLazy) { return getDiscriminator(type.schema); } else if (type instanceof ZodEffects) { return getDiscriminator(type.innerType()); } else if (type instanceof ZodLiteral) { return [type.value]; } else if (type instanceof ZodEnum) { return type.options; } else if (type instanceof ZodNativeEnum) { // eslint-disable-next-line ban/ban return util$9.objectValues(type.enum); } else if (type instanceof ZodDefault) { return getDiscriminator(type._def.innerType); } else if (type instanceof ZodUndefined) { return [undefined]; } else if (type instanceof ZodNull) { return [null]; } else if (type instanceof ZodOptional) { return [undefined, ...getDiscriminator(type.unwrap())]; } else if (type instanceof ZodNullable) { return [null, ...getDiscriminator(type.unwrap())]; } else if (type instanceof ZodBranded) { return getDiscriminator(type.unwrap()); } else if (type instanceof ZodReadonly) { return getDiscriminator(type.unwrap()); } else if (type instanceof ZodCatch) { return getDiscriminator(type._def.innerType); } else { return []; } }; class ZodDiscriminatedUnion extends ZodType { _parse(input) { const { ctx } = this._processInputParams(input); if (ctx.parsedType !== ZodParsedType.object) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.object, received: ctx.parsedType, }); return INVALID; } const discriminator = this.discriminator; const discriminatorValue = ctx.data[discriminator]; const option = this.optionsMap.get(discriminatorValue); if (!option) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_union_discriminator, options: Array.from(this.optionsMap.keys()), path: [discriminator], }); return INVALID; } if (ctx.common.async) { return option._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx, }); } else { return option._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, }); } } get discriminator() { return this._def.discriminator; } get options() { return this._def.options; } get optionsMap() { return this._def.optionsMap; } /** * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor. * However, it only allows a union of objects, all of which need to share a discriminator property. This property must * have a different value for each object in the union. * @param discriminator the name of the discriminator property * @param types an array of object schemas * @param params */ static create(discriminator, options, params) { // Get all the valid discriminator values const optionsMap = new Map(); // try { for (const type of options) { const discriminatorValues = getDiscriminator(type.shape[discriminator]); if (!discriminatorValues.length) { throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`); } for (const value of discriminatorValues) { if (optionsMap.has(value)) { throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`); } optionsMap.set(value, type); } } return new ZodDiscriminatedUnion({ typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion, discriminator, options, optionsMap, ...processCreateParams(params), }); } } function mergeValues(a, b) { const aType = getParsedType(a); const bType = getParsedType(b); if (a === b) { return { valid: true, data: a }; } else if (aType === ZodParsedType.object && bType === ZodParsedType.object) { const bKeys = util$9.objectKeys(b); const sharedKeys = util$9 .objectKeys(a) .filter((key) => bKeys.indexOf(key) !== -1); const newObj = { ...a, ...b }; for (const key of sharedKeys) { const sharedValue = mergeValues(a[key], b[key]); if (!sharedValue.valid) { return { valid: false }; } newObj[key] = sharedValue.data; } return { valid: true, data: newObj }; } else if (aType === ZodParsedType.array && bType === ZodParsedType.array) { if (a.length !== b.length) { return { valid: false }; } const newArray = []; for (let index = 0; index < a.length; index++) { const itemA = a[index]; const itemB = b[index]; const sharedValue = mergeValues(itemA, itemB); if (!sharedValue.valid) { return { valid: false }; } newArray.push(sharedValue.data); } return { valid: true, data: newArray }; } else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) { return { valid: true, data: a }; } else { return { valid: false }; } } class ZodIntersection extends ZodType { _parse(input) { const { status, ctx } = this._processInputParams(input); const handleParsed = (parsedLeft, parsedRight) => { if (isAborted(parsedLeft) || isAborted(parsedRight)) { return INVALID; } const merged = mergeValues(parsedLeft.value, parsedRight.value); if (!merged.valid) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_intersection_types, }); return INVALID; } if (isDirty(parsedLeft) || isDirty(parsedRight)) { status.dirty(); } return { status: status.value, value: merged.data }; }; if (ctx.common.async) { return Promise.all([ this._def.left._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx, }), this._def.right._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx, }), ]).then(([left, right]) => handleParsed(left, right)); } else { return handleParsed(this._def.left._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, }), this._def.right._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, })); } } } ZodIntersection.create = (left, right, params) => { return new ZodIntersection({ left: left, right: right, typeName: ZodFirstPartyTypeKind.ZodIntersection, ...processCreateParams(params), }); }; class ZodTuple extends ZodType { _parse(input) { const { status, ctx } = this._processInputParams(input); if (ctx.parsedType !== ZodParsedType.array) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.array, received: ctx.parsedType, }); return INVALID; } if (ctx.data.length < this._def.items.length) { addIssueToContext(ctx, { code: ZodIssueCode.too_small, minimum: this._def.items.length, inclusive: true, exact: false, type: "array", }); return INVALID; } const rest = this._def.rest; if (!rest && ctx.data.length > this._def.items.length) { addIssueToContext(ctx, { code: ZodIssueCode.too_big, maximum: this._def.items.length, inclusive: true, exact: false, type: "array", }); status.dirty(); } const items = [...ctx.data] .map((item, itemIndex) => { const schema = this._def.items[itemIndex] || this._def.rest; if (!schema) return null; return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex)); }) .filter((x) => !!x); // filter nulls if (ctx.common.async) { return Promise.all(items).then((results) => { return ParseStatus.mergeArray(status, results); }); } else { return ParseStatus.mergeArray(status, items); } } get items() { return this._def.items; } rest(rest) { return new ZodTuple({ ...this._def, rest, }); } } ZodTuple.create = (schemas, params) => { if (!Array.isArray(schemas)) { throw new Error("You must pass an array of schemas to z.tuple([ ... ])"); } return new ZodTuple({ items: schemas, typeName: ZodFirstPartyTypeKind.ZodTuple, rest: null, ...processCreateParams(params), }); }; class ZodRecord extends ZodType { get keySchema() { return this._def.keyType; } get valueSchema() { return this._def.valueType; } _parse(input) { const { status, ctx } = this._processInputParams(input); if (ctx.parsedType !== ZodParsedType.object) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.object, received: ctx.parsedType, }); return INVALID; } const pairs = []; const keyType = this._def.keyType; const valueType = this._def.valueType; for (const key in ctx.data) { pairs.push({ key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)), value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)), alwaysSet: key in ctx.data, }); } if (ctx.common.async) { return ParseStatus.mergeObjectAsync(status, pairs); } else { return ParseStatus.mergeObjectSync(status, pairs); } } get element() { return this._def.valueType; } static create(first, second, third) { if (second instanceof ZodType) { return new ZodRecord({ keyType: first, valueType: second, typeName: ZodFirstPartyTypeKind.ZodRecord, ...processCreateParams(third), }); } return new ZodRecord({ keyType: ZodString.create(), valueType: first, typeName: ZodFirstPartyTypeKind.ZodRecord, ...processCreateParams(second), }); } } class ZodMap extends ZodType { get keySchema() { return this._def.keyType; } get valueSchema() { return this._def.valueType; } _parse(input) { const { status, ctx } = this._processInputParams(input); if (ctx.parsedType !== ZodParsedType.map) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.map, received: ctx.parsedType, }); return INVALID; } const keyType = this._def.keyType; const valueType = this._def.valueType; const pairs = [...ctx.data.entries()].map(([key, value], index) => { return { key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])), value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"])), }; }); if (ctx.common.async) { const finalMap = new Map(); return Promise.resolve().then(async () => { for (const pair of pairs) { const key = await pair.key; const value = await pair.value; if (key.status === "aborted" || value.status === "aborted") { return INVALID; } if (key.status === "dirty" || value.status === "dirty") { status.dirty(); } finalMap.set(key.value, value.value); } return { status: status.value, value: finalMap }; }); } else { const finalMap = new Map(); for (const pair of pairs) { const key = pair.key; const value = pair.value; if (key.status === "aborted" || value.status === "aborted") { return INVALID; } if (key.status === "dirty" || value.status === "dirty") { status.dirty(); } finalMap.set(key.value, value.value); } return { status: status.value, value: finalMap }; } } } ZodMap.create = (keyType, valueType, params) => { return new ZodMap({ valueType, keyType, typeName: ZodFirstPartyTypeKind.ZodMap, ...processCreateParams(params), }); }; class ZodSet extends ZodType { _parse(input) { const { status, ctx } = this._processInputParams(input); if (ctx.parsedType !== ZodParsedType.set) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.set, received: ctx.parsedType, }); return INVALID; } const def = this._def; if (def.minSize !== null) { if (ctx.data.size < def.minSize.value) { addIssueToContext(ctx, { code: ZodIssueCode.too_small, minimum: def.minSize.value, type: "set", inclusive: true, exact: false, message: def.minSize.message, }); status.dirty(); } } if (def.maxSize !== null) { if (ctx.data.size > def.maxSize.value) { addIssueToContext(ctx, { code: ZodIssueCode.too_big, maximum: def.maxSize.value, type: "set", inclusive: true, exact: false, message: def.maxSize.message, }); status.dirty(); } } const valueType = this._def.valueType; function finalizeSet(elements) { const parsedSet = new Set(); for (const element of elements) { if (element.status === "aborted") return INVALID; if (element.status === "dirty") status.dirty(); parsedSet.add(element.value); } return { status: status.value, value: parsedSet }; } const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i))); if (ctx.common.async) { return Promise.all(elements).then((elements) => finalizeSet(elements)); } else { return finalizeSet(elements); } } min(minSize, message) { return new ZodSet({ ...this._def, minSize: { value: minSize, message: errorUtil.toString(message) }, }); } max(maxSize, message) { return new ZodSet({ ...this._def, maxSize: { value: maxSize, message: errorUtil.toString(message) }, }); } size(size, message) { return this.min(size, message).max(size, message); } nonempty(message) { return this.min(1, message); } } ZodSet.create = (valueType, params) => { return new ZodSet({ valueType, minSize: null, maxSize: null, typeName: ZodFirstPartyTypeKind.ZodSet, ...processCreateParams(params), }); }; class ZodFunction extends ZodType { constructor() { super(...arguments); this.validate = this.implement; } _parse(input) { const { ctx } = this._processInputParams(input); if (ctx.parsedType !== ZodParsedType.function) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.function, received: ctx.parsedType, }); return INVALID; } function makeArgsIssue(args, error) { return makeIssue({ data: args, path: ctx.path, errorMaps: [ ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), errorMap, ].filter((x) => !!x), issueData: { code: ZodIssueCode.invalid_arguments, argumentsError: error, }, }); } function makeReturnsIssue(returns, error) { return makeIssue({ data: returns, path: ctx.path, errorMaps: [ ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), errorMap, ].filter((x) => !!x), issueData: { code: ZodIssueCode.invalid_return_type, returnTypeError: error, }, }); } const params = { errorMap: ctx.common.contextualErrorMap }; const fn = ctx.data; if (this._def.returns instanceof ZodPromise) { // Would love a way to avoid disabling this rule, but we need // an alias (using an arrow function was what caused 2651). // eslint-disable-next-line @typescript-eslint/no-this-alias const me = this; return OK(async function (...args) { const error = new ZodError([]); const parsedArgs = await me._def.args .parseAsync(args, params) .catch((e) => { error.addIssue(makeArgsIssue(args, e)); throw error; }); const result = await Reflect.apply(fn, this, parsedArgs); const parsedReturns = await me._def.returns._def.type .parseAsync(result, params) .catch((e) => { error.addIssue(makeReturnsIssue(result, e)); throw error; }); return parsedReturns; }); } else { // Would love a way to avoid disabling this rule, but we need // an alias (using an arrow function was what caused 2651). // eslint-disable-next-line @typescript-eslint/no-this-alias const me = this; return OK(function (...args) { const parsedArgs = me._def.args.safeParse(args, params); if (!parsedArgs.success) { throw new ZodError([makeArgsIssue(args, parsedArgs.error)]); } const result = Reflect.apply(fn, this, parsedArgs.data); const parsedReturns = me._def.returns.safeParse(result, params); if (!parsedReturns.success) { throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]); } return parsedReturns.data; }); } } parameters() { return this._def.args; } returnType() { return this._def.returns; } args(...items) { return new ZodFunction({ ...this._def, args: ZodTuple.create(items).rest(ZodUnknown.create()), }); } returns(returnType) { return new ZodFunction({ ...this._def, returns: returnType, }); } implement(func) { const validatedFunc = this.parse(func); return validatedFunc; } strictImplement(func) { const validatedFunc = this.parse(func); return validatedFunc; } static create(args, returns, params) { return new ZodFunction({ args: (args ? args : ZodTuple.create([]).rest(ZodUnknown.create())), returns: returns || ZodUnknown.create(), typeName: ZodFirstPartyTypeKind.ZodFunction, ...processCreateParams(params), }); } } class ZodLazy extends ZodType { get schema() { return this._def.getter(); } _parse(input) { const { ctx } = this._processInputParams(input); const lazySchema = this._def.getter(); return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx }); } } ZodLazy.create = (getter, params) => { return new ZodLazy({ getter: getter, typeName: ZodFirstPartyTypeKind.ZodLazy, ...processCreateParams(params), }); }; class ZodLiteral extends ZodType { _parse(input) { if (input.data !== this._def.value) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { received: ctx.data, code: ZodIssueCode.invalid_literal, expected: this._def.value, }); return INVALID; } return { status: "valid", value: input.data }; } get value() { return this._def.value; } } ZodLiteral.create = (value, params) => { return new ZodLiteral({ value: value, typeName: ZodFirstPartyTypeKind.ZodLiteral, ...processCreateParams(params), }); }; function createZodEnum(values, params) { return new ZodEnum({ values, typeName: ZodFirstPartyTypeKind.ZodEnum, ...processCreateParams(params), }); } class ZodEnum extends ZodType { constructor() { super(...arguments); _ZodEnum_cache.set(this, void 0); } _parse(input) { if (typeof input.data !== "string") { const ctx = this._getOrReturnCtx(input); const expectedValues = this._def.values; addIssueToContext(ctx, { expected: util$9.joinValues(expectedValues), received: ctx.parsedType, code: ZodIssueCode.invalid_type, }); return INVALID; } if (!__classPrivateFieldGet(this, _ZodEnum_cache, "f")) { __classPrivateFieldSet(this, _ZodEnum_cache, new Set(this._def.values), "f"); } if (!__classPrivateFieldGet(this, _ZodEnum_cache, "f").has(input.data)) { const ctx = this._getOrReturnCtx(input); const expectedValues = this._def.values; addIssueToContext(ctx, { received: ctx.data, code: ZodIssueCode.invalid_enum_value, options: expectedValues, }); return INVALID; } return OK(input.data); } get options() { return this._def.values; } get enum() { const enumValues = {}; for (const val of this._def.values) { enumValues[val] = val; } return enumValues; } get Values() { const enumValues = {}; for (const val of this._def.values) { enumValues[val] = val; } return enumValues; } get Enum() { const enumValues = {}; for (const val of this._def.values) { enumValues[val] = val; } return enumValues; } extract(values, newDef = this._def) { return ZodEnum.create(values, { ...this._def, ...newDef, }); } exclude(values, newDef = this._def) { return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), { ...this._def, ...newDef, }); } } _ZodEnum_cache = new WeakMap(); ZodEnum.create = createZodEnum; class ZodNativeEnum extends ZodType { constructor() { super(...arguments); _ZodNativeEnum_cache.set(this, void 0); } _parse(input) { const nativeEnumValues = util$9.getValidEnumValues(this._def.values); const ctx = this._getOrReturnCtx(input); if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) { const expectedValues = util$9.objectValues(nativeEnumValues); addIssueToContext(ctx, { expected: util$9.joinValues(expectedValues), received: ctx.parsedType, code: ZodIssueCode.invalid_type, }); return INVALID; } if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f")) { __classPrivateFieldSet(this, _ZodNativeEnum_cache, new Set(util$9.getValidEnumValues(this._def.values)), "f"); } if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f").has(input.data)) { const expectedValues = util$9.objectValues(nativeEnumValues); addIssueToContext(ctx, { received: ctx.data, code: ZodIssueCode.invalid_enum_value, options: expectedValues, }); return INVALID; } return OK(input.data); } get enum() { return this._def.values; } } _ZodNativeEnum_cache = new WeakMap(); ZodNativeEnum.create = (values, params) => { return new ZodNativeEnum({ values: values, typeName: ZodFirstPartyTypeKind.ZodNativeEnum, ...processCreateParams(params), }); }; class ZodPromise extends ZodType { unwrap() { return this._def.type; } _parse(input) { const { ctx } = this._processInputParams(input); if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) { addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.promise, received: ctx.parsedType, }); return INVALID; } const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data); return OK(promisified.then((data) => { return this._def.type.parseAsync(data, { path: ctx.path, errorMap: ctx.common.contextualErrorMap, }); })); } } ZodPromise.create = (schema, params) => { return new ZodPromise({ type: schema, typeName: ZodFirstPartyTypeKind.ZodPromise, ...processCreateParams(params), }); }; class ZodEffects extends ZodType { innerType() { return this._def.schema; } sourceType() { return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema; } _parse(input) { const { status, ctx } = this._processInputParams(input); const effect = this._def.effect || null; const checkCtx = { addIssue: (arg) => { addIssueToContext(ctx, arg); if (arg.fatal) { status.abort(); } else { status.dirty(); } }, get path() { return ctx.path; }, }; checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx); if (effect.type === "preprocess") { const processed = effect.transform(ctx.data, checkCtx); if (ctx.common.async) { return Promise.resolve(processed).then(async (processed) => { if (status.value === "aborted") return INVALID; const result = await this._def.schema._parseAsync({ data: processed, path: ctx.path, parent: ctx, }); if (result.status === "aborted") return INVALID; if (result.status === "dirty") return DIRTY(result.value); if (status.value === "dirty") return DIRTY(result.value); return result; }); } else { if (status.value === "aborted") return INVALID; const result = this._def.schema._parseSync({ data: processed, path: ctx.path, parent: ctx, }); if (result.status === "aborted") return INVALID; if (result.status === "dirty") return DIRTY(result.value); if (status.value === "dirty") return DIRTY(result.value); return result; } } if (effect.type === "refinement") { const executeRefinement = (acc) => { const result = effect.refinement(acc, checkCtx); if (ctx.common.async) { return Promise.resolve(result); } if (result instanceof Promise) { throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead."); } return acc; }; if (ctx.common.async === false) { const inner = this._def.schema._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, }); if (inner.status === "aborted") return INVALID; if (inner.status === "dirty") status.dirty(); // return value is ignored executeRefinement(inner.value); return { status: status.value, value: inner.value }; } else { return this._def.schema ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }) .then((inner) => { if (inner.status === "aborted") return INVALID; if (inner.status === "dirty") status.dirty(); return executeRefinement(inner.value).then(() => { return { status: status.value, value: inner.value }; }); }); } } if (effect.type === "transform") { if (ctx.common.async === false) { const base = this._def.schema._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, }); if (!isValid(base)) return base; const result = effect.transform(base.value, checkCtx); if (result instanceof Promise) { throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`); } return { status: status.value, value: result }; } else { return this._def.schema ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }) .then((base) => { if (!isValid(base)) return base; return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ status: status.value, value: result })); }); } } util$9.assertNever(effect); } } ZodEffects.create = (schema, effect, params) => { return new ZodEffects({ schema, typeName: ZodFirstPartyTypeKind.ZodEffects, effect, ...processCreateParams(params), }); }; ZodEffects.createWithPreprocess = (preprocess, schema, params) => { return new ZodEffects({ schema, effect: { type: "preprocess", transform: preprocess }, typeName: ZodFirstPartyTypeKind.ZodEffects, ...processCreateParams(params), }); }; class ZodOptional extends ZodType { _parse(input) { const parsedType = this._getType(input); if (parsedType === ZodParsedType.undefined) { return OK(undefined); } return this._def.innerType._parse(input); } unwrap() { return this._def.innerType; } } ZodOptional.create = (type, params) => { return new ZodOptional({ innerType: type, typeName: ZodFirstPartyTypeKind.ZodOptional, ...processCreateParams(params), }); }; class ZodNullable extends ZodType { _parse(input) { const parsedType = this._getType(input); if (parsedType === ZodParsedType.null) { return OK(null); } return this._def.innerType._parse(input); } unwrap() { return this._def.innerType; } } ZodNullable.create = (type, params) => { return new ZodNullable({ innerType: type, typeName: ZodFirstPartyTypeKind.ZodNullable, ...processCreateParams(params), }); }; class ZodDefault extends ZodType { _parse(input) { const { ctx } = this._processInputParams(input); let data = ctx.data; if (ctx.parsedType === ZodParsedType.undefined) { data = this._def.defaultValue(); } return this._def.innerType._parse({ data, path: ctx.path, parent: ctx, }); } removeDefault() { return this._def.innerType; } } ZodDefault.create = (type, params) => { return new ZodDefault({ innerType: type, typeName: ZodFirstPartyTypeKind.ZodDefault, defaultValue: typeof params.default === "function" ? params.default : () => params.default, ...processCreateParams(params), }); }; class ZodCatch extends ZodType { _parse(input) { const { ctx } = this._processInputParams(input); // newCtx is used to not collect issues from inner types in ctx const newCtx = { ...ctx, common: { ...ctx.common, issues: [], }, }; const result = this._def.innerType._parse({ data: newCtx.data, path: newCtx.path, parent: { ...newCtx, }, }); if (isAsync(result)) { return result.then((result) => { return { status: "valid", value: result.status === "valid" ? result.value : this._def.catchValue({ get error() { return new ZodError(newCtx.common.issues); }, input: newCtx.data, }), }; }); } else { return { status: "valid", value: result.status === "valid" ? result.value : this._def.catchValue({ get error() { return new ZodError(newCtx.common.issues); }, input: newCtx.data, }), }; } } removeCatch() { return this._def.innerType; } } ZodCatch.create = (type, params) => { return new ZodCatch({ innerType: type, typeName: ZodFirstPartyTypeKind.ZodCatch, catchValue: typeof params.catch === "function" ? params.catch : () => params.catch, ...processCreateParams(params), }); }; class ZodNaN extends ZodType { _parse(input) { const parsedType = this._getType(input); if (parsedType !== ZodParsedType.nan) { const ctx = this._getOrReturnCtx(input); addIssueToContext(ctx, { code: ZodIssueCode.invalid_type, expected: ZodParsedType.nan, received: ctx.parsedType, }); return INVALID; } return { status: "valid", value: input.data }; } } ZodNaN.create = (params) => { return new ZodNaN({ typeName: ZodFirstPartyTypeKind.ZodNaN, ...processCreateParams(params), }); }; const BRAND = Symbol("zod_brand"); class ZodBranded extends ZodType { _parse(input) { const { ctx } = this._processInputParams(input); const data = ctx.data; return this._def.type._parse({ data, path: ctx.path, parent: ctx, }); } unwrap() { return this._def.type; } } class ZodPipeline extends ZodType { _parse(input) { const { status, ctx } = this._processInputParams(input); if (ctx.common.async) { const handleAsync = async () => { const inResult = await this._def.in._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx, }); if (inResult.status === "aborted") return INVALID; if (inResult.status === "dirty") { status.dirty(); return DIRTY(inResult.value); } else { return this._def.out._parseAsync({ data: inResult.value, path: ctx.path, parent: ctx, }); } }; return handleAsync(); } else { const inResult = this._def.in._parseSync({ data: ctx.data, path: ctx.path, parent: ctx, }); if (inResult.status === "aborted") return INVALID; if (inResult.status === "dirty") { status.dirty(); return { status: "dirty", value: inResult.value, }; } else { return this._def.out._parseSync({ data: inResult.value, path: ctx.path, parent: ctx, }); } } } static create(a, b) { return new ZodPipeline({ in: a, out: b, typeName: ZodFirstPartyTypeKind.ZodPipeline, }); } } class ZodReadonly extends ZodType { _parse(input) { const result = this._def.innerType._parse(input); const freeze = (data) => { if (isValid(data)) { data.value = Object.freeze(data.value); } return data; }; return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result); } unwrap() { return this._def.innerType; } } ZodReadonly.create = (type, params) => { return new ZodReadonly({ innerType: type, typeName: ZodFirstPartyTypeKind.ZodReadonly, ...processCreateParams(params), }); }; function custom(check, params = {}, /** * @deprecated * * Pass `fatal` into the params object instead: * * ```ts * z.string().custom((val) => val.length > 5, { fatal: false }) * ``` * */ fatal) { if (check) return ZodAny.create().superRefine((data, ctx) => { var _a, _b; if (!check(data)) { const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params; const _fatal = (_b = (_a = p.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true; const p2 = typeof p === "string" ? { message: p } : p; ctx.addIssue({ code: "custom", ...p2, fatal: _fatal }); } }); return ZodAny.create(); } const late = { object: ZodObject.lazycreate, }; var ZodFirstPartyTypeKind; (function (ZodFirstPartyTypeKind) { ZodFirstPartyTypeKind["ZodString"] = "ZodString"; ZodFirstPartyTypeKind["ZodNumber"] = "ZodNumber"; ZodFirstPartyTypeKind["ZodNaN"] = "ZodNaN"; ZodFirstPartyTypeKind["ZodBigInt"] = "ZodBigInt"; ZodFirstPartyTypeKind["ZodBoolean"] = "ZodBoolean"; ZodFirstPartyTypeKind["ZodDate"] = "ZodDate"; ZodFirstPartyTypeKind["ZodSymbol"] = "ZodSymbol"; ZodFirstPartyTypeKind["ZodUndefined"] = "ZodUndefined"; ZodFirstPartyTypeKind["ZodNull"] = "ZodNull"; ZodFirstPartyTypeKind["ZodAny"] = "ZodAny"; ZodFirstPartyTypeKind["ZodUnknown"] = "ZodUnknown"; ZodFirstPartyTypeKind["ZodNever"] = "ZodNever"; ZodFirstPartyTypeKind["ZodVoid"] = "ZodVoid"; ZodFirstPartyTypeKind["ZodArray"] = "ZodArray"; ZodFirstPartyTypeKind["ZodObject"] = "ZodObject"; ZodFirstPartyTypeKind["ZodUnion"] = "ZodUnion"; ZodFirstPartyTypeKind["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion"; ZodFirstPartyTypeKind["ZodIntersection"] = "ZodIntersection"; ZodFirstPartyTypeKind["ZodTuple"] = "ZodTuple"; ZodFirstPartyTypeKind["ZodRecord"] = "ZodRecord"; ZodFirstPartyTypeKind["ZodMap"] = "ZodMap"; ZodFirstPartyTypeKind["ZodSet"] = "ZodSet"; ZodFirstPartyTypeKind["ZodFunction"] = "ZodFunction"; ZodFirstPartyTypeKind["ZodLazy"] = "ZodLazy"; ZodFirstPartyTypeKind["ZodLiteral"] = "ZodLiteral"; ZodFirstPartyTypeKind["ZodEnum"] = "ZodEnum"; ZodFirstPartyTypeKind["ZodEffects"] = "ZodEffects"; ZodFirstPartyTypeKind["ZodNativeEnum"] = "ZodNativeEnum"; ZodFirstPartyTypeKind["ZodOptional"] = "ZodOptional"; ZodFirstPartyTypeKind["ZodNullable"] = "ZodNullable"; ZodFirstPartyTypeKind["ZodDefault"] = "ZodDefault"; ZodFirstPartyTypeKind["ZodCatch"] = "ZodCatch"; ZodFirstPartyTypeKind["ZodPromise"] = "ZodPromise"; ZodFirstPartyTypeKind["ZodBranded"] = "ZodBranded"; ZodFirstPartyTypeKind["ZodPipeline"] = "ZodPipeline"; ZodFirstPartyTypeKind["ZodReadonly"] = "ZodReadonly"; })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {})); const instanceOfType = ( // const instanceOfType = any>( cls, params = { message: `Input not instance of ${cls.name}`, }) => custom((data) => data instanceof cls, params); const stringType = ZodString.create; const numberType = ZodNumber.create; const nanType = ZodNaN.create; const bigIntType = ZodBigInt.create; const booleanType = ZodBoolean.create; const dateType = ZodDate.create; const symbolType = ZodSymbol.create; const undefinedType = ZodUndefined.create; const nullType = ZodNull.create; const anyType = ZodAny.create; const unknownType = ZodUnknown.create; const neverType = ZodNever.create; const voidType = ZodVoid.create; const arrayType = ZodArray.create; const objectType = ZodObject.create; const strictObjectType = ZodObject.strictCreate; const unionType = ZodUnion.create; const discriminatedUnionType = ZodDiscriminatedUnion.create; const intersectionType = ZodIntersection.create; const tupleType = ZodTuple.create; const recordType = ZodRecord.create; const mapType = ZodMap.create; const setType = ZodSet.create; const functionType = ZodFunction.create; const lazyType = ZodLazy.create; const literalType = ZodLiteral.create; const enumType = ZodEnum.create; const nativeEnumType = ZodNativeEnum.create; const promiseType = ZodPromise.create; const effectsType = ZodEffects.create; const optionalType = ZodOptional.create; const nullableType = ZodNullable.create; const preprocessType = ZodEffects.createWithPreprocess; const pipelineType = ZodPipeline.create; const ostring = () => stringType().optional(); const onumber = () => numberType().optional(); const oboolean = () => booleanType().optional(); const coerce$2 = { string: ((arg) => ZodString.create({ ...arg, coerce: true })), number: ((arg) => ZodNumber.create({ ...arg, coerce: true })), boolean: ((arg) => ZodBoolean.create({ ...arg, coerce: true, })), bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })), date: ((arg) => ZodDate.create({ ...arg, coerce: true })), }; const NEVER = INVALID; var z = /*#__PURE__*/Object.freeze({ __proto__: null, defaultErrorMap: errorMap, setErrorMap: setErrorMap, getErrorMap: getErrorMap, makeIssue: makeIssue, EMPTY_PATH: EMPTY_PATH, addIssueToContext: addIssueToContext, ParseStatus: ParseStatus, INVALID: INVALID, DIRTY: DIRTY, OK: OK, isAborted: isAborted, isDirty: isDirty, isValid: isValid, isAsync: isAsync, get util () { return util$9; }, get objectUtil () { return objectUtil; }, ZodParsedType: ZodParsedType, getParsedType: getParsedType, ZodType: ZodType, datetimeRegex: datetimeRegex, ZodString: ZodString, ZodNumber: ZodNumber, ZodBigInt: ZodBigInt, ZodBoolean: ZodBoolean, ZodDate: ZodDate, ZodSymbol: ZodSymbol, ZodUndefined: ZodUndefined, ZodNull: ZodNull, ZodAny: ZodAny, ZodUnknown: ZodUnknown, ZodNever: ZodNever, ZodVoid: ZodVoid, ZodArray: ZodArray, ZodObject: ZodObject, ZodUnion: ZodUnion, ZodDiscriminatedUnion: ZodDiscriminatedUnion, ZodIntersection: ZodIntersection, ZodTuple: ZodTuple, ZodRecord: ZodRecord, ZodMap: ZodMap, ZodSet: ZodSet, ZodFunction: ZodFunction, ZodLazy: ZodLazy, ZodLiteral: ZodLiteral, ZodEnum: ZodEnum, ZodNativeEnum: ZodNativeEnum, ZodPromise: ZodPromise, ZodEffects: ZodEffects, ZodTransformer: ZodEffects, ZodOptional: ZodOptional, ZodNullable: ZodNullable, ZodDefault: ZodDefault, ZodCatch: ZodCatch, ZodNaN: ZodNaN, BRAND: BRAND, ZodBranded: ZodBranded, ZodPipeline: ZodPipeline, ZodReadonly: ZodReadonly, custom: custom, Schema: ZodType, ZodSchema: ZodType, late: late, get ZodFirstPartyTypeKind () { return ZodFirstPartyTypeKind; }, coerce: coerce$2, any: anyType, array: arrayType, bigint: bigIntType, boolean: booleanType, date: dateType, discriminatedUnion: discriminatedUnionType, effect: effectsType, 'enum': enumType, 'function': functionType, 'instanceof': instanceOfType, intersection: intersectionType, lazy: lazyType, literal: literalType, map: mapType, nan: nanType, nativeEnum: nativeEnumType, never: neverType, 'null': nullType, nullable: nullableType, number: numberType, object: objectType, oboolean: oboolean, onumber: onumber, optional: optionalType, ostring: ostring, pipeline: pipelineType, preprocess: preprocessType, promise: promiseType, record: recordType, set: setType, strictObject: strictObjectType, string: stringType, symbol: symbolType, transformer: effectsType, tuple: tupleType, 'undefined': undefinedType, union: unionType, unknown: unknownType, 'void': voidType, NEVER: NEVER, ZodIssueCode: ZodIssueCode, quotelessJson: quotelessJson, ZodError: ZodError }); // src/shared/constants/extension-types.ts var APP_EXTENSION_TYPES = ["interface", "display", "layout", "module", "panel", "theme"]; var API_EXTENSION_TYPES = ["hook", "endpoint"]; var HYBRID_EXTENSION_TYPES = ["operation"]; var BUNDLE_EXTENSION_TYPES = ["bundle"]; [ ...APP_EXTENSION_TYPES, ...API_EXTENSION_TYPES, ...HYBRID_EXTENSION_TYPES, ...BUNDLE_EXTENSION_TYPES ]; [ ...APP_EXTENSION_TYPES, ...API_EXTENSION_TYPES, ...HYBRID_EXTENSION_TYPES ]; [...APP_EXTENSION_TYPES, ...HYBRID_EXTENSION_TYPES]; // src/shared/constants/pkg-key.ts var EXTENSION_PKG_KEY = "directus:extension"; var SplitEntrypoint = z.object({ app: z.string(), api: z.string() }); var ExtensionSandboxRequestedScopes = z.object({ request: z.optional( z.object({ urls: z.array(z.string()), methods: z.array( z.union([z.literal("GET"), z.literal("POST"), z.literal("PATCH"), z.literal("PUT"), z.literal("DELETE")]) ) }) ), log: z.optional(z.object({})), sleep: z.optional(z.object({})) }); var ExtensionSandboxOptions = z.optional( z.object({ enabled: z.boolean(), requestedScopes: ExtensionSandboxRequestedScopes }) ); var ExtensionOptionsBundleEntry = z.union([ z.object({ type: z.enum(API_EXTENSION_TYPES), name: z.string(), source: z.string() }), z.object({ type: z.enum(APP_EXTENSION_TYPES), name: z.string(), source: z.string() }), z.object({ type: z.enum(HYBRID_EXTENSION_TYPES), name: z.string(), source: SplitEntrypoint }) ]); var ExtensionOptionsBase = z.object({ host: z.string(), hidden: z.boolean().optional() }); var ExtensionOptionsApp = z.object({ type: z.enum(APP_EXTENSION_TYPES), path: z.string(), source: z.string() }); var ExtensionOptionsApi = z.object({ type: z.enum(API_EXTENSION_TYPES), path: z.string(), source: z.string(), sandbox: ExtensionSandboxOptions }); var ExtensionOptionsHybrid = z.object({ type: z.enum(HYBRID_EXTENSION_TYPES), path: SplitEntrypoint, source: SplitEntrypoint, sandbox: ExtensionSandboxOptions }); var ExtensionOptionsBundle = z.object({ type: z.literal("bundle"), partial: z.boolean().optional(), path: SplitEntrypoint, entries: z.array(ExtensionOptionsBundleEntry) }); z.array(ExtensionOptionsBundleEntry); var ExtensionOptions = ExtensionOptionsBase.and( z.union([ExtensionOptionsApp, ExtensionOptionsApi, ExtensionOptionsHybrid, ExtensionOptionsBundle]) ); // src/shared/schemas/manifest.ts z.object({ name: z.string(), version: z.string(), type: z.union([z.literal("module"), z.literal("commonjs")]).optional(), description: z.string().optional(), icon: z.string().optional(), dependencies: z.record(z.string()).optional(), devDependencies: z.record(z.string()).optional(), [EXTENSION_PKG_KEY]: ExtensionOptions }); function defineHook(config) { return config; } var cache$2 = {}; var common$1 = {}; var name$2 = "joi"; var description$2 = "Object schema validation"; var version$3 = "17.13.1"; var repository$2 = "git://github.com/hapijs/joi"; var main$3 = "lib/index.js"; var types$4 = "lib/index.d.ts"; var browser$1 = "dist/joi-browser.min.js"; var files$1 = [ "lib/**/*", "dist/*" ]; var keywords$2 = [ "schema", "validation" ]; var dependencies$1 = { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" }; var devDependencies$2 = { "@hapi/bourne": "2.x.x", "@hapi/code": "8.x.x", "@hapi/joi-legacy-test": "npm:@hapi/joi@15.x.x", "@hapi/lab": "^25.1.3", "@types/node": "^14.18.63", typescript: "4.3.x" }; var scripts$2 = { prepublishOnly: "cd browser && npm install && npm run build", test: "lab -t 100 -a @hapi/code -L -Y", "test-cov-html": "lab -r html -o coverage.html -a @hapi/code" }; var license$2 = "BSD-3-Clause"; var require$$2 = { name: name$2, description: description$2, version: version$3, repository: repository$2, main: main$3, types: types$4, browser: browser$1, files: files$1, keywords: keywords$2, dependencies: dependencies$1, devDependencies: devDependencies$2, scripts: scripts$2, license: license$2 }; var schemas = {}; var hasRequiredSchemas; function requireSchemas () { if (hasRequiredSchemas) return schemas; hasRequiredSchemas = 1; const Joi = requireLib(); const internals = {}; // Preferences internals.wrap = Joi.string() .min(1) .max(2) .allow(false); schemas.preferences = Joi.object({ allowUnknown: Joi.boolean(), abortEarly: Joi.boolean(), artifacts: Joi.boolean(), cache: Joi.boolean(), context: Joi.object(), convert: Joi.boolean(), dateFormat: Joi.valid('date', 'iso', 'string', 'time', 'utc'), debug: Joi.boolean(), errors: { escapeHtml: Joi.boolean(), label: Joi.valid('path', 'key', false), language: [ Joi.string(), Joi.object().ref() ], render: Joi.boolean(), stack: Joi.boolean(), wrap: { label: internals.wrap, array: internals.wrap, string: internals.wrap } }, externals: Joi.boolean(), messages: Joi.object(), noDefaults: Joi.boolean(), nonEnumerables: Joi.boolean(), presence: Joi.valid('required', 'optional', 'forbidden'), skipFunctions: Joi.boolean(), stripUnknown: Joi.object({ arrays: Joi.boolean(), objects: Joi.boolean() }) .or('arrays', 'objects') .allow(true, false), warnings: Joi.boolean() }) .strict(); // Extensions internals.nameRx = /^[a-zA-Z0-9]\w*$/; internals.rule = Joi.object({ alias: Joi.array().items(Joi.string().pattern(internals.nameRx)).single(), args: Joi.array().items( Joi.string(), Joi.object({ name: Joi.string().pattern(internals.nameRx).required(), ref: Joi.boolean(), assert: Joi.alternatives([ Joi.function(), Joi.object().schema() ]) .conditional('ref', { is: true, then: Joi.required() }), normalize: Joi.function(), message: Joi.string().when('assert', { is: Joi.function(), then: Joi.required() }) }) ), convert: Joi.boolean(), manifest: Joi.boolean(), method: Joi.function().allow(false), multi: Joi.boolean(), validate: Joi.function() }); schemas.extension = Joi.object({ type: Joi.alternatives([ Joi.string(), Joi.object().regex() ]) .required(), args: Joi.function(), cast: Joi.object().pattern(internals.nameRx, Joi.object({ from: Joi.function().maxArity(1).required(), to: Joi.function().minArity(1).maxArity(2).required() })), base: Joi.object().schema() .when('type', { is: Joi.object().regex(), then: Joi.forbidden() }), coerce: [ Joi.function().maxArity(3), Joi.object({ method: Joi.function().maxArity(3).required(), from: Joi.array().items(Joi.string()).single() }) ], flags: Joi.object().pattern(internals.nameRx, Joi.object({ setter: Joi.string(), default: Joi.any() })), manifest: { build: Joi.function().arity(2) }, messages: [Joi.object(), Joi.string()], modifiers: Joi.object().pattern(internals.nameRx, Joi.function().minArity(1).maxArity(2)), overrides: Joi.object().pattern(internals.nameRx, Joi.function()), prepare: Joi.function().maxArity(3), rebuild: Joi.function().arity(1), rules: Joi.object().pattern(internals.nameRx, internals.rule), terms: Joi.object().pattern(internals.nameRx, Joi.object({ init: Joi.array().allow(null).required(), manifest: Joi.object().pattern(/.+/, [ Joi.valid('schema', 'single'), Joi.object({ mapped: Joi.object({ from: Joi.string().required(), to: Joi.string().required() }) .required() }) ]) })), validate: Joi.function().maxArity(3) }) .strict(); schemas.extensions = Joi.array().items(Joi.object(), Joi.function().arity(1)).strict(); // Manifest internals.desc = { buffer: Joi.object({ buffer: Joi.string() }), func: Joi.object({ function: Joi.function().required(), options: { literal: true } }), override: Joi.object({ override: true }), ref: Joi.object({ ref: Joi.object({ type: Joi.valid('value', 'global', 'local'), path: Joi.array().required(), separator: Joi.string().length(1).allow(false), ancestor: Joi.number().min(0).integer().allow('root'), map: Joi.array().items(Joi.array().length(2)).min(1), adjust: Joi.function(), iterables: Joi.boolean(), in: Joi.boolean(), render: Joi.boolean() }) .required() }), regex: Joi.object({ regex: Joi.string().min(3) }), special: Joi.object({ special: Joi.valid('deep').required() }), template: Joi.object({ template: Joi.string().required(), options: Joi.object() }), value: Joi.object({ value: Joi.alternatives([Joi.object(), Joi.array()]).required() }) }; internals.desc.entity = Joi.alternatives([ Joi.array().items(Joi.link('...')), Joi.boolean(), Joi.function(), Joi.number(), Joi.string(), internals.desc.buffer, internals.desc.func, internals.desc.ref, internals.desc.regex, internals.desc.special, internals.desc.template, internals.desc.value, Joi.link('/') ]); internals.desc.values = Joi.array() .items( null, Joi.boolean(), Joi.function(), Joi.number().allow(Infinity, -Infinity), Joi.string().allow(''), Joi.symbol(), internals.desc.buffer, internals.desc.func, internals.desc.override, internals.desc.ref, internals.desc.regex, internals.desc.template, internals.desc.value ); internals.desc.messages = Joi.object() .pattern(/.+/, [ Joi.string(), internals.desc.template, Joi.object().pattern(/.+/, [Joi.string(), internals.desc.template]) ]); schemas.description = Joi.object({ type: Joi.string().required(), flags: Joi.object({ cast: Joi.string(), default: Joi.any(), description: Joi.string(), empty: Joi.link('/'), failover: internals.desc.entity, id: Joi.string(), label: Joi.string(), only: true, presence: ['optional', 'required', 'forbidden'], result: ['raw', 'strip'], strip: Joi.boolean(), unit: Joi.string() }) .unknown(), preferences: { allowUnknown: Joi.boolean(), abortEarly: Joi.boolean(), artifacts: Joi.boolean(), cache: Joi.boolean(), convert: Joi.boolean(), dateFormat: ['date', 'iso', 'string', 'time', 'utc'], errors: { escapeHtml: Joi.boolean(), label: ['path', 'key'], language: [ Joi.string(), internals.desc.ref ], wrap: { label: internals.wrap, array: internals.wrap } }, externals: Joi.boolean(), messages: internals.desc.messages, noDefaults: Joi.boolean(), nonEnumerables: Joi.boolean(), presence: ['required', 'optional', 'forbidden'], skipFunctions: Joi.boolean(), stripUnknown: Joi.object({ arrays: Joi.boolean(), objects: Joi.boolean() }) .or('arrays', 'objects') .allow(true, false), warnings: Joi.boolean() }, allow: internals.desc.values, invalid: internals.desc.values, rules: Joi.array().min(1).items({ name: Joi.string().required(), args: Joi.object().min(1), keep: Joi.boolean(), message: [ Joi.string(), internals.desc.messages ], warn: Joi.boolean() }), // Terms keys: Joi.object().pattern(/.*/, Joi.link('/')), link: internals.desc.ref }) .pattern(/^[a-z]\w*$/, Joi.any()); return schemas; } var messages = {}; var template = {exports: {}}; var errors$6 = {}; var annotate = {}; var hasRequiredAnnotate; function requireAnnotate () { if (hasRequiredAnnotate) return annotate; hasRequiredAnnotate = 1; const Clone = clone$6; const Common = requireCommon(); const internals = { annotations: Symbol('annotations') }; annotate.error = function (stripColorCodes) { if (!this._original || typeof this._original !== 'object') { return this.details[0].message; } const redFgEscape = stripColorCodes ? '' : '\u001b[31m'; const redBgEscape = stripColorCodes ? '' : '\u001b[41m'; const endColor = stripColorCodes ? '' : '\u001b[0m'; const obj = Clone(this._original); for (let i = this.details.length - 1; i >= 0; --i) { // Reverse order to process deepest child first const pos = i + 1; const error = this.details[i]; const path = error.path; let node = obj; for (let j = 0; ; ++j) { const seg = path[j]; if (Common.isSchema(node)) { node = node.clone(); // joi schemas are not cloned by hoek, we have to take this extra step } if (j + 1 < path.length && typeof node[seg] !== 'string') { node = node[seg]; } else { const refAnnotations = node[internals.annotations] || { errors: {}, missing: {} }; node[internals.annotations] = refAnnotations; const cacheKey = seg || error.context.key; if (node[seg] !== undefined) { refAnnotations.errors[cacheKey] = refAnnotations.errors[cacheKey] || []; refAnnotations.errors[cacheKey].push(pos); } else { refAnnotations.missing[cacheKey] = pos; } break; } } } const replacers = { key: /_\$key\$_([, \d]+)_\$end\$_"/g, missing: /"_\$miss\$_([^|]+)\|(\d+)_\$end\$_": "__missing__"/g, arrayIndex: /\s*"_\$idx\$_([, \d]+)_\$end\$_",?\n(.*)/g, specials: /"\[(NaN|Symbol.*|-?Infinity|function.*|\(.*)]"/g }; let message = internals.safeStringify(obj, 2) .replace(replacers.key, ($0, $1) => `" ${redFgEscape}[${$1}]${endColor}`) .replace(replacers.missing, ($0, $1, $2) => `${redBgEscape}"${$1}"${endColor}${redFgEscape} [${$2}]: -- missing --${endColor}`) .replace(replacers.arrayIndex, ($0, $1, $2) => `\n${$2} ${redFgEscape}[${$1}]${endColor}`) .replace(replacers.specials, ($0, $1) => $1); message = `${message}\n${redFgEscape}`; for (let i = 0; i < this.details.length; ++i) { const pos = i + 1; message = `${message}\n[${pos}] ${this.details[i].message}`; } message = message + endColor; return message; }; // Inspired by json-stringify-safe internals.safeStringify = function (obj, spaces) { return JSON.stringify(obj, internals.serializer(), spaces); }; internals.serializer = function () { const keys = []; const stack = []; const cycleReplacer = (key, value) => { if (stack[0] === value) { return '[Circular ~]'; } return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'; }; return function (key, value) { if (stack.length > 0) { const thisPos = stack.indexOf(this); if (~thisPos) { stack.length = thisPos + 1; keys.length = thisPos + 1; keys[thisPos] = key; } else { stack.push(this); keys.push(key); } if (~stack.indexOf(value)) { value = cycleReplacer.call(this, key, value); } } else { stack.push(value); } if (value) { const annotations = value[internals.annotations]; if (annotations) { if (Array.isArray(value)) { const annotated = []; for (let i = 0; i < value.length; ++i) { if (annotations.errors[i]) { annotated.push(`_$idx$_${annotations.errors[i].sort().join(', ')}_$end$_`); } annotated.push(value[i]); } value = annotated; } else { for (const errorKey in annotations.errors) { value[`${errorKey}_$key$_${annotations.errors[errorKey].sort().join(', ')}_$end$_`] = value[errorKey]; value[errorKey] = undefined; } for (const missingKey in annotations.missing) { value[`_$miss$_${missingKey}|${annotations.missing[missingKey]}_$end$_`] = '__missing__'; } } return value; } } if (value === Infinity || value === -Infinity || Number.isNaN(value) || typeof value === 'function' || typeof value === 'symbol') { return '[' + value.toString() + ']'; } return value; }; }; return annotate; } var hasRequiredErrors; function requireErrors () { if (hasRequiredErrors) return errors$6; hasRequiredErrors = 1; (function (exports) { const Annotate = requireAnnotate(); const Common = requireCommon(); const Template = requireTemplate(); exports.Report = class { constructor(code, value, local, flags, messages, state, prefs) { this.code = code; this.flags = flags; this.messages = messages; this.path = state.path; this.prefs = prefs; this.state = state; this.value = value; this.message = null; this.template = null; this.local = local || {}; this.local.label = exports.label(this.flags, this.state, this.prefs, this.messages); if (this.value !== undefined && !this.local.hasOwnProperty('value')) { this.local.value = this.value; } if (this.path.length) { const key = this.path[this.path.length - 1]; if (typeof key !== 'object') { this.local.key = key; } } } _setTemplate(template) { this.template = template; if (!this.flags.label && this.path.length === 0) { const localized = this._template(this.template, 'root'); if (localized) { this.local.label = localized; } } } toString() { if (this.message) { return this.message; } const code = this.code; if (!this.prefs.errors.render) { return this.code; } const template = this._template(this.template) || this._template(this.prefs.messages) || this._template(this.messages); if (template === undefined) { return `Error code "${code}" is not defined, your custom type is missing the correct messages definition`; } // Render and cache result this.message = template.render(this.value, this.state, this.prefs, this.local, { errors: this.prefs.errors, messages: [this.prefs.messages, this.messages] }); if (!this.prefs.errors.label) { this.message = this.message.replace(/^"" /, '').trim(); } return this.message; } _template(messages, code) { return exports.template(this.value, messages, code || this.code, this.state, this.prefs); } }; exports.path = function (path) { let label = ''; for (const segment of path) { if (typeof segment === 'object') { // Exclude array single path segment continue; } if (typeof segment === 'string') { if (label) { label += '.'; } label += segment; } else { label += `[${segment}]`; } } return label; }; exports.template = function (value, messages, code, state, prefs) { if (!messages) { return; } if (Template.isTemplate(messages)) { return code !== 'root' ? messages : null; } let lang = prefs.errors.language; if (Common.isResolvable(lang)) { lang = lang.resolve(value, state, prefs); } if (lang && messages[lang]) { if (messages[lang][code] !== undefined) { return messages[lang][code]; } if (messages[lang]['*'] !== undefined) { return messages[lang]['*']; } } if (!messages[code]) { return messages['*']; } return messages[code]; }; exports.label = function (flags, state, prefs, messages) { if (!prefs.errors.label) { return ''; } if (flags.label) { return flags.label; } let path = state.path; if (prefs.errors.label === 'key' && state.path.length > 1) { path = state.path.slice(-1); } const normalized = exports.path(path); if (normalized) { return normalized; } return exports.template(null, prefs.messages, 'root', state, prefs) || messages && exports.template(null, messages, 'root', state, prefs) || 'value'; }; exports.process = function (errors, original, prefs) { if (!errors) { return null; } const { override, message, details } = exports.details(errors); if (override) { return override; } if (prefs.errors.stack) { return new exports.ValidationError(message, details, original); } const limit = Error.stackTraceLimit; Error.stackTraceLimit = 0; const validationError = new exports.ValidationError(message, details, original); Error.stackTraceLimit = limit; return validationError; }; exports.details = function (errors, options = {}) { let messages = []; const details = []; for (const item of errors) { // Override if (item instanceof Error) { if (options.override !== false) { return { override: item }; } const message = item.toString(); messages.push(message); details.push({ message, type: 'override', context: { error: item } }); continue; } // Report const message = item.toString(); messages.push(message); details.push({ message, path: item.path.filter((v) => typeof v !== 'object'), type: item.code, context: item.local }); } if (messages.length > 1) { messages = [...new Set(messages)]; } return { message: messages.join('. '), details }; }; exports.ValidationError = class extends Error { constructor(message, details, original) { super(message); this._original = original; this.details = details; } static isError(err) { return err instanceof exports.ValidationError; } }; exports.ValidationError.prototype.isJoi = true; exports.ValidationError.prototype.name = 'ValidationError'; exports.ValidationError.prototype.annotate = Annotate.error; } (errors$6)); return errors$6; } var ref = {}; var hasRequiredRef; function requireRef () { if (hasRequiredRef) return ref; hasRequiredRef = 1; (function (exports) { const Assert = assert$4; const Clone = clone$6; const Reach = reach; const Common = requireCommon(); let Template; const internals = { symbol: Symbol('ref'), // Used to internally identify references (shared with other joi versions) defaults: { adjust: null, in: false, iterables: null, map: null, separator: '.', type: 'value' } }; exports.create = function (key, options = {}) { Assert(typeof key === 'string', 'Invalid reference key:', key); Common.assertOptions(options, ['adjust', 'ancestor', 'in', 'iterables', 'map', 'prefix', 'render', 'separator']); Assert(!options.prefix || typeof options.prefix === 'object', 'options.prefix must be of type object'); const ref = Object.assign({}, internals.defaults, options); delete ref.prefix; const separator = ref.separator; const context = internals.context(key, separator, options.prefix); ref.type = context.type; key = context.key; if (ref.type === 'value') { if (context.root) { Assert(!separator || key[0] !== separator, 'Cannot specify relative path with root prefix'); ref.ancestor = 'root'; if (!key) { key = null; } } if (separator && separator === key) { key = null; ref.ancestor = 0; } else { if (ref.ancestor !== undefined) { Assert(!separator || !key || key[0] !== separator, 'Cannot combine prefix with ancestor option'); } else { const [ancestor, slice] = internals.ancestor(key, separator); if (slice) { key = key.slice(slice); if (key === '') { key = null; } } ref.ancestor = ancestor; } } } ref.path = separator ? (key === null ? [] : key.split(separator)) : [key]; return new internals.Ref(ref); }; exports.in = function (key, options = {}) { return exports.create(key, { ...options, in: true }); }; exports.isRef = function (ref) { return ref ? !!ref[Common.symbols.ref] : false; }; internals.Ref = class { constructor(options) { Assert(typeof options === 'object', 'Invalid reference construction'); Common.assertOptions(options, [ 'adjust', 'ancestor', 'in', 'iterables', 'map', 'path', 'render', 'separator', 'type', // Copied 'depth', 'key', 'root', 'display' // Overridden ]); Assert([false, undefined].includes(options.separator) || typeof options.separator === 'string' && options.separator.length === 1, 'Invalid separator'); Assert(!options.adjust || typeof options.adjust === 'function', 'options.adjust must be a function'); Assert(!options.map || Array.isArray(options.map), 'options.map must be an array'); Assert(!options.map || !options.adjust, 'Cannot set both map and adjust options'); Object.assign(this, internals.defaults, options); Assert(this.type === 'value' || this.ancestor === undefined, 'Non-value references cannot reference ancestors'); if (Array.isArray(this.map)) { this.map = new Map(this.map); } this.depth = this.path.length; this.key = this.path.length ? this.path.join(this.separator) : null; this.root = this.path[0]; this.updateDisplay(); } resolve(value, state, prefs, local, options = {}) { Assert(!this.in || options.in, 'Invalid in() reference usage'); if (this.type === 'global') { return this._resolve(prefs.context, state, options); } if (this.type === 'local') { return this._resolve(local, state, options); } if (!this.ancestor) { return this._resolve(value, state, options); } if (this.ancestor === 'root') { return this._resolve(state.ancestors[state.ancestors.length - 1], state, options); } Assert(this.ancestor <= state.ancestors.length, 'Invalid reference exceeds the schema root:', this.display); return this._resolve(state.ancestors[this.ancestor - 1], state, options); } _resolve(target, state, options) { let resolved; if (this.type === 'value' && state.mainstay.shadow && options.shadow !== false) { resolved = state.mainstay.shadow.get(this.absolute(state)); } if (resolved === undefined) { resolved = Reach(target, this.path, { iterables: this.iterables, functions: true }); } if (this.adjust) { resolved = this.adjust(resolved); } if (this.map) { const mapped = this.map.get(resolved); if (mapped !== undefined) { resolved = mapped; } } if (state.mainstay) { state.mainstay.tracer.resolve(state, this, resolved); } return resolved; } toString() { return this.display; } absolute(state) { return [...state.path.slice(0, -this.ancestor), ...this.path]; } clone() { return new internals.Ref(this); } describe() { const ref = { path: this.path }; if (this.type !== 'value') { ref.type = this.type; } if (this.separator !== '.') { ref.separator = this.separator; } if (this.type === 'value' && this.ancestor !== 1) { ref.ancestor = this.ancestor; } if (this.map) { ref.map = [...this.map]; } for (const key of ['adjust', 'iterables', 'render']) { if (this[key] !== null && this[key] !== undefined) { ref[key] = this[key]; } } if (this.in !== false) { ref.in = true; } return { ref }; } updateDisplay() { const key = this.key !== null ? this.key : ''; if (this.type !== 'value') { this.display = `ref:${this.type}:${key}`; return; } if (!this.separator) { this.display = `ref:${key}`; return; } if (!this.ancestor) { this.display = `ref:${this.separator}${key}`; return; } if (this.ancestor === 'root') { this.display = `ref:root:${key}`; return; } if (this.ancestor === 1) { this.display = `ref:${key || '..'}`; return; } const lead = new Array(this.ancestor + 1).fill(this.separator).join(''); this.display = `ref:${lead}${key || ''}`; } }; internals.Ref.prototype[Common.symbols.ref] = true; exports.build = function (desc) { desc = Object.assign({}, internals.defaults, desc); if (desc.type === 'value' && desc.ancestor === undefined) { desc.ancestor = 1; } return new internals.Ref(desc); }; internals.context = function (key, separator, prefix = {}) { key = key.trim(); if (prefix) { const globalp = prefix.global === undefined ? '$' : prefix.global; if (globalp !== separator && key.startsWith(globalp)) { return { key: key.slice(globalp.length), type: 'global' }; } const local = prefix.local === undefined ? '#' : prefix.local; if (local !== separator && key.startsWith(local)) { return { key: key.slice(local.length), type: 'local' }; } const root = prefix.root === undefined ? '/' : prefix.root; if (root !== separator && key.startsWith(root)) { return { key: key.slice(root.length), type: 'value', root: true }; } } return { key, type: 'value' }; }; internals.ancestor = function (key, separator) { if (!separator) { return [1, 0]; // 'a_b' -> 1 (parent) } if (key[0] !== separator) { // 'a.b' -> 1 (parent) return [1, 0]; } if (key[1] !== separator) { // '.a.b' -> 0 (self) return [0, 1]; } let i = 2; while (key[i] === separator) { ++i; } return [i - 1, i]; // '...a.b.' -> 2 (grandparent) }; exports.toSibling = 0; exports.toParent = 1; exports.Manager = class { constructor() { this.refs = []; // 0: [self refs], 1: [parent refs], 2: [grandparent refs], ... } register(source, target) { if (!source) { return; } target = target === undefined ? exports.toParent : target; // Array if (Array.isArray(source)) { for (const ref of source) { this.register(ref, target); } return; } // Schema if (Common.isSchema(source)) { for (const item of source._refs.refs) { if (item.ancestor - target >= 0) { this.refs.push({ ancestor: item.ancestor - target, root: item.root }); } } return; } // Reference if (exports.isRef(source) && source.type === 'value' && source.ancestor - target >= 0) { this.refs.push({ ancestor: source.ancestor - target, root: source.root }); } // Template Template = Template || requireTemplate(); if (Template.isTemplate(source)) { this.register(source.refs(), target); } } get length() { return this.refs.length; } clone() { const copy = new exports.Manager(); copy.refs = Clone(this.refs); return copy; } reset() { this.refs = []; } roots() { return this.refs.filter((ref) => !ref.ancestor).map((ref) => ref.root); } }; } (ref)); return ref; } var hasRequiredTemplate; function requireTemplate () { if (hasRequiredTemplate) return template.exports; hasRequiredTemplate = 1; (function (module, exports) { const Assert = assert$4; const Clone = clone$6; const EscapeHtml = escapeHtml; const Formula = lib$8; const Common = requireCommon(); const Errors = requireErrors(); const Ref = requireRef(); const internals = { symbol: Symbol('template'), opens: new Array(1000).join('\u0000'), closes: new Array(1000).join('\u0001'), dateFormat: { date: Date.prototype.toDateString, iso: Date.prototype.toISOString, string: Date.prototype.toString, time: Date.prototype.toTimeString, utc: Date.prototype.toUTCString } }; module.exports = internals.Template = class { constructor(source, options) { Assert(typeof source === 'string', 'Template source must be a string'); Assert(!source.includes('\u0000') && !source.includes('\u0001'), 'Template source cannot contain reserved control characters'); this.source = source; this.rendered = source; this._template = null; if (options) { const { functions, ...opts } = options; this._settings = Object.keys(opts).length ? Clone(opts) : undefined; this._functions = functions; if (this._functions) { Assert(Object.keys(this._functions).every((key) => typeof key === 'string'), 'Functions keys must be strings'); Assert(Object.values(this._functions).every((key) => typeof key === 'function'), 'Functions values must be functions'); } } else { this._settings = undefined; this._functions = undefined; } this._parse(); } _parse() { // 'text {raw} {{ref}} \\{{ignore}} {{ignore\\}} {{ignore {{ignore}' if (!this.source.includes('{')) { return; } // Encode escaped \\{{{{{ const encoded = internals.encode(this.source); // Split on first { in each set const parts = internals.split(encoded); // Process parts let refs = false; const processed = []; const head = parts.shift(); if (head) { processed.push(head); } for (const part of parts) { const raw = part[0] !== '{'; const ender = raw ? '}' : '}}'; const end = part.indexOf(ender); if (end === -1 || // Ignore non-matching closing part[1] === '{') { // Ignore more than two { processed.push(`{${internals.decode(part)}`); continue; } let variable = part.slice(raw ? 0 : 1, end); const wrapped = variable[0] === ':'; if (wrapped) { variable = variable.slice(1); } const dynamic = this._ref(internals.decode(variable), { raw, wrapped }); processed.push(dynamic); if (typeof dynamic !== 'string') { refs = true; } const rest = part.slice(end + ender.length); if (rest) { processed.push(internals.decode(rest)); } } if (!refs) { this.rendered = processed.join(''); return; } this._template = processed; } static date(date, prefs) { return internals.dateFormat[prefs.dateFormat].call(date); } describe(options = {}) { if (!this._settings && options.compact) { return this.source; } const desc = { template: this.source }; if (this._settings) { desc.options = this._settings; } if (this._functions) { desc.functions = this._functions; } return desc; } static build(desc) { return new internals.Template(desc.template, desc.options || desc.functions ? { ...desc.options, functions: desc.functions } : undefined); } isDynamic() { return !!this._template; } static isTemplate(template) { return template ? !!template[Common.symbols.template] : false; } refs() { if (!this._template) { return; } const refs = []; for (const part of this._template) { if (typeof part !== 'string') { refs.push(...part.refs); } } return refs; } resolve(value, state, prefs, local) { if (this._template && this._template.length === 1) { return this._part(this._template[0], /* context -> [*/ value, state, prefs, local, {} /*] */); } return this.render(value, state, prefs, local); } _part(part, ...args) { if (part.ref) { return part.ref.resolve(...args); } return part.formula.evaluate(args); } render(value, state, prefs, local, options = {}) { if (!this.isDynamic()) { return this.rendered; } const parts = []; for (const part of this._template) { if (typeof part === 'string') { parts.push(part); } else { const rendered = this._part(part, /* context -> [*/ value, state, prefs, local, options /*] */); const string = internals.stringify(rendered, value, state, prefs, local, options); if (string !== undefined) { const result = part.raw || (options.errors && options.errors.escapeHtml) === false ? string : EscapeHtml(string); parts.push(internals.wrap(result, part.wrapped && prefs.errors.wrap.label)); } } } return parts.join(''); } _ref(content, { raw, wrapped }) { const refs = []; const reference = (variable) => { const ref = Ref.create(variable, this._settings); refs.push(ref); return (context) => { const resolved = ref.resolve(...context); return resolved !== undefined ? resolved : null; }; }; try { const functions = this._functions ? { ...internals.functions, ...this._functions } : internals.functions; var formula = new Formula.Parser(content, { reference, functions, constants: internals.constants }); } catch (err) { err.message = `Invalid template variable "${content}" fails due to: ${err.message}`; throw err; } if (formula.single) { if (formula.single.type === 'reference') { const ref = refs[0]; return { ref, raw, refs, wrapped: wrapped || ref.type === 'local' && ref.key === 'label' }; } return internals.stringify(formula.single.value); } return { formula, raw, refs }; } toString() { return this.source; } }; internals.Template.prototype[Common.symbols.template] = true; internals.Template.prototype.isImmutable = true; // Prevents Hoek from deep cloning schema objects internals.encode = function (string) { return string .replace(/\\(\{+)/g, ($0, $1) => { return internals.opens.slice(0, $1.length); }) .replace(/\\(\}+)/g, ($0, $1) => { return internals.closes.slice(0, $1.length); }); }; internals.decode = function (string) { return string .replace(/\u0000/g, '{') .replace(/\u0001/g, '}'); }; internals.split = function (string) { const parts = []; let current = ''; for (let i = 0; i < string.length; ++i) { const char = string[i]; if (char === '{') { let next = ''; while (i + 1 < string.length && string[i + 1] === '{') { next += '{'; ++i; } parts.push(current); current = next; } else { current += char; } } parts.push(current); return parts; }; internals.wrap = function (value, ends) { if (!ends) { return value; } if (ends.length === 1) { return `${ends}${value}${ends}`; } return `${ends[0]}${value}${ends[1]}`; }; internals.stringify = function (value, original, state, prefs, local, options = {}) { const type = typeof value; const wrap = prefs && prefs.errors && prefs.errors.wrap || {}; let skipWrap = false; if (Ref.isRef(value) && value.render) { skipWrap = value.in; value = value.resolve(original, state, prefs, local, { in: value.in, ...options }); } if (value === null) { return 'null'; } if (type === 'string') { return internals.wrap(value, options.arrayItems && wrap.string); } if (type === 'number' || type === 'function' || type === 'symbol') { return value.toString(); } if (type !== 'object') { return JSON.stringify(value); } if (value instanceof Date) { return internals.Template.date(value, prefs); } if (value instanceof Map) { const pairs = []; for (const [key, sym] of value.entries()) { pairs.push(`${key.toString()} -> ${sym.toString()}`); } value = pairs; } if (!Array.isArray(value)) { return value.toString(); } const values = []; for (const item of value) { values.push(internals.stringify(item, original, state, prefs, local, { arrayItems: true, ...options })); } return internals.wrap(values.join(', '), !skipWrap && wrap.array); }; internals.constants = { true: true, false: false, null: null, second: 1000, minute: 60 * 1000, hour: 60 * 60 * 1000, day: 24 * 60 * 60 * 1000 }; internals.functions = { if(condition, then, otherwise) { return condition ? then : otherwise; }, length(item) { if (typeof item === 'string') { return item.length; } if (!item || typeof item !== 'object') { return null; } if (Array.isArray(item)) { return item.length; } return Object.keys(item).length; }, msg(code) { const [value, state, prefs, local, options] = this; const messages = options.messages; if (!messages) { return ''; } const template = Errors.template(value, messages[0], code, state, prefs) || Errors.template(value, messages[1], code, state, prefs); if (!template) { return ''; } return template.render(value, state, prefs, local, options); }, number(value) { if (typeof value === 'number') { return value; } if (typeof value === 'string') { return parseFloat(value); } if (typeof value === 'boolean') { return value ? 1 : 0; } if (value instanceof Date) { return value.getTime(); } return null; } }; } (template)); return template.exports; } var hasRequiredMessages; function requireMessages () { if (hasRequiredMessages) return messages; hasRequiredMessages = 1; (function (exports) { const Assert = assert$4; const Clone = clone$6; const Template = requireTemplate(); exports.compile = function (messages, target) { // Single value string ('plain error message', 'template {error} message') if (typeof messages === 'string') { Assert(!target, 'Cannot set single message string'); return new Template(messages); } // Single value template if (Template.isTemplate(messages)) { Assert(!target, 'Cannot set single message template'); return messages; } // By error code { 'number.min': } Assert(typeof messages === 'object' && !Array.isArray(messages), 'Invalid message options'); target = target ? Clone(target) : {}; for (let code in messages) { const message = messages[code]; if (code === 'root' || Template.isTemplate(message)) { target[code] = message; continue; } if (typeof message === 'string') { target[code] = new Template(message); continue; } // By language { english: { 'number.min': } } Assert(typeof message === 'object' && !Array.isArray(message), 'Invalid message for', code); const language = code; target[language] = target[language] || {}; for (code in message) { const localized = message[code]; if (code === 'root' || Template.isTemplate(localized)) { target[language][code] = localized; continue; } Assert(typeof localized === 'string', 'Invalid message for', code, 'in', language); target[language][code] = new Template(localized); } } return target; }; exports.decompile = function (messages) { // By error code { 'number.min': } const target = {}; for (let code in messages) { const message = messages[code]; if (code === 'root') { target.root = message; continue; } if (Template.isTemplate(message)) { target[code] = message.describe({ compact: true }); continue; } // By language { english: { 'number.min': } } const language = code; target[language] = {}; for (code in message) { const localized = message[code]; if (code === 'root') { target[language].root = localized; continue; } target[language][code] = localized.describe({ compact: true }); } } return target; }; exports.merge = function (base, extended) { if (!base) { return exports.compile(extended); } if (!extended) { return base; } // Single value string if (typeof extended === 'string') { return new Template(extended); } // Single value template if (Template.isTemplate(extended)) { return extended; } // By error code { 'number.min': } const target = Clone(base); for (let code in extended) { const message = extended[code]; if (code === 'root' || Template.isTemplate(message)) { target[code] = message; continue; } if (typeof message === 'string') { target[code] = new Template(message); continue; } // By language { english: { 'number.min': } } Assert(typeof message === 'object' && !Array.isArray(message), 'Invalid message for', code); const language = code; target[language] = target[language] || {}; for (code in message) { const localized = message[code]; if (code === 'root' || Template.isTemplate(localized)) { target[language][code] = localized; continue; } Assert(typeof localized === 'string', 'Invalid message for', code, 'in', language); target[language][code] = new Template(localized); } } return target; }; } (messages)); return messages; } var hasRequiredCommon; function requireCommon () { if (hasRequiredCommon) return common$1; hasRequiredCommon = 1; (function (exports) { const Assert = assert$4; const AssertError = errorExports; const Pkg = require$$2; let Messages; let Schemas; const internals = { isoDate: /^(?:[-+]\d{2})?(?:\d{4}(?!\d{2}\b))(?:(-?)(?:(?:0[1-9]|1[0-2])(?:\1(?:[12]\d|0[1-9]|3[01]))?|W(?:[0-4]\d|5[0-2])(?:-?[1-7])?|(?:00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[1-6])))(?![T]$|[T][\d]+Z$)(?:[T\s](?:(?:(?:[01]\d|2[0-3])(?:(:?)[0-5]\d)?|24\:?00)(?:[.,]\d+(?!:))?)(?:\2[0-5]\d(?:[.,]\d+)?)?(?:[Z]|(?:[+-])(?:[01]\d|2[0-3])(?::?[0-5]\d)?)?)?)?$/ }; exports.version = Pkg.version; exports.defaults = { abortEarly: true, allowUnknown: false, artifacts: false, cache: true, context: null, convert: true, dateFormat: 'iso', errors: { escapeHtml: false, label: 'path', language: null, render: true, stack: false, wrap: { label: '"', array: '[]' } }, externals: true, messages: {}, nonEnumerables: false, noDefaults: false, presence: 'optional', skipFunctions: false, stripUnknown: false, warnings: false }; exports.symbols = { any: Symbol.for('@hapi/joi/schema'), // Used to internally identify any-based types (shared with other joi versions) arraySingle: Symbol('arraySingle'), deepDefault: Symbol('deepDefault'), errors: Symbol('errors'), literal: Symbol('literal'), override: Symbol('override'), parent: Symbol('parent'), prefs: Symbol('prefs'), ref: Symbol('ref'), template: Symbol('template'), values: Symbol('values') }; exports.assertOptions = function (options, keys, name = 'Options') { Assert(options && typeof options === 'object' && !Array.isArray(options), 'Options must be of type object'); const unknownKeys = Object.keys(options).filter((k) => !keys.includes(k)); Assert(unknownKeys.length === 0, `${name} contain unknown keys: ${unknownKeys}`); }; exports.checkPreferences = function (prefs) { Schemas = Schemas || requireSchemas(); const result = Schemas.preferences.validate(prefs); if (result.error) { throw new AssertError([result.error.details[0].message]); } }; exports.compare = function (a, b, operator) { switch (operator) { case '=': return a === b; case '>': return a > b; case '<': return a < b; case '>=': return a >= b; case '<=': return a <= b; } }; exports.default = function (value, defaultValue) { return value === undefined ? defaultValue : value; }; exports.isIsoDate = function (date) { return internals.isoDate.test(date); }; exports.isNumber = function (value) { return typeof value === 'number' && !isNaN(value); }; exports.isResolvable = function (obj) { if (!obj) { return false; } return obj[exports.symbols.ref] || obj[exports.symbols.template]; }; exports.isSchema = function (schema, options = {}) { const any = schema && schema[exports.symbols.any]; if (!any) { return false; } Assert(options.legacy || any.version === exports.version, 'Cannot mix different versions of joi schemas'); return true; }; exports.isValues = function (obj) { return obj[exports.symbols.values]; }; exports.limit = function (value) { return Number.isSafeInteger(value) && value >= 0; }; exports.preferences = function (target, source) { Messages = Messages || requireMessages(); target = target || {}; source = source || {}; const merged = Object.assign({}, target, source); if (source.errors && target.errors) { merged.errors = Object.assign({}, target.errors, source.errors); merged.errors.wrap = Object.assign({}, target.errors.wrap, source.errors.wrap); } if (source.messages) { merged.messages = Messages.compile(source.messages, target.messages); } delete merged[exports.symbols.prefs]; return merged; }; exports.tryWithPath = function (fn, key, options = {}) { try { return fn(); } catch (err) { if (err.path !== undefined) { err.path = key + '.' + err.path; } else { err.path = key; } if (options.append) { err.message = `${err.message} (${err.path})`; } throw err; } }; exports.validateArg = function (value, label, { assert, message }) { if (exports.isSchema(assert)) { const result = assert.validate(value); if (!result.error) { return; } return result.error.message; } else if (!assert(value)) { return label ? `${label} ${message}` : message; } }; exports.verifyFlat = function (args, method) { for (const arg of args) { Assert(!Array.isArray(arg), 'Method no longer accepts array arguments:', method); } }; } (common$1)); return common$1; } var hasRequiredCache; function requireCache () { if (hasRequiredCache) return cache$2; hasRequiredCache = 1; const Assert = assert$4; const Clone = clone$6; const Common = requireCommon(); const internals = { max: 1000, supported: new Set(['undefined', 'boolean', 'number', 'string']) }; cache$2.provider = { provision(options) { return new internals.Cache(options); } }; // Least Recently Used (LRU) Cache internals.Cache = class { constructor(options = {}) { Common.assertOptions(options, ['max']); Assert(options.max === undefined || options.max && options.max > 0 && isFinite(options.max), 'Invalid max cache size'); this._max = options.max || internals.max; this._map = new Map(); // Map of nodes by key this._list = new internals.List(); // List of nodes (most recently used in head) } get length() { return this._map.size; } set(key, value) { if (key !== null && !internals.supported.has(typeof key)) { return; } let node = this._map.get(key); if (node) { node.value = value; this._list.first(node); return; } node = this._list.unshift({ key, value }); this._map.set(key, node); this._compact(); } get(key) { const node = this._map.get(key); if (node) { this._list.first(node); return Clone(node.value); } } _compact() { if (this._map.size > this._max) { const node = this._list.pop(); this._map.delete(node.key); } } }; internals.List = class { constructor() { this.tail = null; this.head = null; } unshift(node) { node.next = null; node.prev = this.head; if (this.head) { this.head.next = node; } this.head = node; if (!this.tail) { this.tail = node; } return node; } first(node) { if (node === this.head) { return; } this._remove(node); this.unshift(node); } pop() { return this._remove(this.tail); } _remove(node) { const { next, prev } = node; next.prev = prev; if (prev) { prev.next = next; } if (node === this.tail) { this.tail = next; } node.prev = null; node.next = null; return node; } }; return cache$2; } var compile = {}; var hasRequiredCompile; function requireCompile () { if (hasRequiredCompile) return compile; hasRequiredCompile = 1; (function (exports) { const Assert = assert$4; const Common = requireCommon(); const Ref = requireRef(); const internals = {}; exports.schema = function (Joi, config, options = {}) { Common.assertOptions(options, ['appendPath', 'override']); try { return internals.schema(Joi, config, options); } catch (err) { if (options.appendPath && err.path !== undefined) { err.message = `${err.message} (${err.path})`; } throw err; } }; internals.schema = function (Joi, config, options) { Assert(config !== undefined, 'Invalid undefined schema'); if (Array.isArray(config)) { Assert(config.length, 'Invalid empty array schema'); if (config.length === 1) { config = config[0]; } } const valid = (base, ...values) => { if (options.override !== false) { return base.valid(Joi.override, ...values); } return base.valid(...values); }; if (internals.simple(config)) { return valid(Joi, config); } if (typeof config === 'function') { return Joi.custom(config); } Assert(typeof config === 'object', 'Invalid schema content:', typeof config); if (Common.isResolvable(config)) { return valid(Joi, config); } if (Common.isSchema(config)) { return config; } if (Array.isArray(config)) { for (const item of config) { if (!internals.simple(item)) { return Joi.alternatives().try(...config); } } return valid(Joi, ...config); } if (config instanceof RegExp) { return Joi.string().regex(config); } if (config instanceof Date) { return valid(Joi.date(), config); } Assert(Object.getPrototypeOf(config) === Object.getPrototypeOf({}), 'Schema can only contain plain objects'); return Joi.object().keys(config); }; exports.ref = function (id, options) { return Ref.isRef(id) ? id : Ref.create(id, options); }; exports.compile = function (root, schema, options = {}) { Common.assertOptions(options, ['legacy']); // Compiled by any supported version const any = schema && schema[Common.symbols.any]; if (any) { Assert(options.legacy || any.version === Common.version, 'Cannot mix different versions of joi schemas:', any.version, Common.version); return schema; } // Uncompiled root if (typeof schema !== 'object' || !options.legacy) { return exports.schema(root, schema, { appendPath: true }); // Will error if schema contains other versions } // Scan schema for compiled parts const compiler = internals.walk(schema); if (!compiler) { return exports.schema(root, schema, { appendPath: true }); } return compiler.compile(compiler.root, schema); }; internals.walk = function (schema) { if (typeof schema !== 'object') { return null; } if (Array.isArray(schema)) { for (const item of schema) { const compiler = internals.walk(item); if (compiler) { return compiler; } } return null; } const any = schema[Common.symbols.any]; if (any) { return { root: schema[any.root], compile: any.compile }; } Assert(Object.getPrototypeOf(schema) === Object.getPrototypeOf({}), 'Schema can only contain plain objects'); for (const key in schema) { const compiler = internals.walk(schema[key]); if (compiler) { return compiler; } } return null; }; internals.simple = function (value) { return value === null || ['boolean', 'string', 'number'].includes(typeof value); }; exports.when = function (schema, condition, options) { if (options === undefined) { Assert(condition && typeof condition === 'object', 'Missing options'); options = condition; condition = Ref.create('.'); } if (Array.isArray(options)) { options = { switch: options }; } Common.assertOptions(options, ['is', 'not', 'then', 'otherwise', 'switch', 'break']); // Schema condition if (Common.isSchema(condition)) { Assert(options.is === undefined, '"is" can not be used with a schema condition'); Assert(options.not === undefined, '"not" can not be used with a schema condition'); Assert(options.switch === undefined, '"switch" can not be used with a schema condition'); return internals.condition(schema, { is: condition, then: options.then, otherwise: options.otherwise, break: options.break }); } // Single condition Assert(Ref.isRef(condition) || typeof condition === 'string', 'Invalid condition:', condition); Assert(options.not === undefined || options.is === undefined, 'Cannot combine "is" with "not"'); if (options.switch === undefined) { let rule = options; if (options.not !== undefined) { rule = { is: options.not, then: options.otherwise, otherwise: options.then, break: options.break }; } let is = rule.is !== undefined ? schema.$_compile(rule.is) : schema.$_root.invalid(null, false, 0, '').required(); Assert(rule.then !== undefined || rule.otherwise !== undefined, 'options must have at least one of "then", "otherwise", or "switch"'); Assert(rule.break === undefined || rule.then === undefined || rule.otherwise === undefined, 'Cannot specify then, otherwise, and break all together'); if (options.is !== undefined && !Ref.isRef(options.is) && !Common.isSchema(options.is)) { is = is.required(); // Only apply required if this wasn't already a schema or a ref } return internals.condition(schema, { ref: exports.ref(condition), is, then: rule.then, otherwise: rule.otherwise, break: rule.break }); } // Switch statement Assert(Array.isArray(options.switch), '"switch" must be an array'); Assert(options.is === undefined, 'Cannot combine "switch" with "is"'); Assert(options.not === undefined, 'Cannot combine "switch" with "not"'); Assert(options.then === undefined, 'Cannot combine "switch" with "then"'); const rule = { ref: exports.ref(condition), switch: [], break: options.break }; for (let i = 0; i < options.switch.length; ++i) { const test = options.switch[i]; const last = i === options.switch.length - 1; Common.assertOptions(test, last ? ['is', 'then', 'otherwise'] : ['is', 'then']); Assert(test.is !== undefined, 'Switch statement missing "is"'); Assert(test.then !== undefined, 'Switch statement missing "then"'); const item = { is: schema.$_compile(test.is), then: schema.$_compile(test.then) }; if (!Ref.isRef(test.is) && !Common.isSchema(test.is)) { item.is = item.is.required(); // Only apply required if this wasn't already a schema or a ref } if (last) { Assert(options.otherwise === undefined || test.otherwise === undefined, 'Cannot specify "otherwise" inside and outside a "switch"'); const otherwise = options.otherwise !== undefined ? options.otherwise : test.otherwise; if (otherwise !== undefined) { Assert(rule.break === undefined, 'Cannot specify both otherwise and break'); item.otherwise = schema.$_compile(otherwise); } } rule.switch.push(item); } return rule; }; internals.condition = function (schema, condition) { for (const key of ['then', 'otherwise']) { if (condition[key] === undefined) { delete condition[key]; } else { condition[key] = schema.$_compile(condition[key]); } } return condition; }; } (compile)); return compile; } var extend$1 = {}; var hasRequiredExtend; function requireExtend () { if (hasRequiredExtend) return extend$1; hasRequiredExtend = 1; const Assert = assert$4; const Clone = clone$6; const Common = requireCommon(); const Messages = requireMessages(); const internals = {}; extend$1.type = function (from, options) { const base = Object.getPrototypeOf(from); const prototype = Clone(base); const schema = from._assign(Object.create(prototype)); const def = Object.assign({}, options); // Shallow cloned delete def.base; prototype._definition = def; const parent = base._definition || {}; def.messages = Messages.merge(parent.messages, def.messages); def.properties = Object.assign({}, parent.properties, def.properties); // Type schema.type = def.type; // Flags def.flags = Object.assign({}, parent.flags, def.flags); // Terms const terms = Object.assign({}, parent.terms); if (def.terms) { for (const name in def.terms) { // Only apply own terms const term = def.terms[name]; Assert(schema.$_terms[name] === undefined, 'Invalid term override for', def.type, name); schema.$_terms[name] = term.init; terms[name] = term; } } def.terms = terms; // Constructor arguments if (!def.args) { def.args = parent.args; } // Prepare def.prepare = internals.prepare(def.prepare, parent.prepare); // Coerce if (def.coerce) { if (typeof def.coerce === 'function') { def.coerce = { method: def.coerce }; } if (def.coerce.from && !Array.isArray(def.coerce.from)) { def.coerce = { method: def.coerce.method, from: [].concat(def.coerce.from) }; } } def.coerce = internals.coerce(def.coerce, parent.coerce); // Validate def.validate = internals.validate(def.validate, parent.validate); // Rules const rules = Object.assign({}, parent.rules); if (def.rules) { for (const name in def.rules) { const rule = def.rules[name]; Assert(typeof rule === 'object', 'Invalid rule definition for', def.type, name); let method = rule.method; if (method === undefined) { method = function () { return this.$_addRule(name); }; } if (method) { Assert(!prototype[name], 'Rule conflict in', def.type, name); prototype[name] = method; } Assert(!rules[name], 'Rule conflict in', def.type, name); rules[name] = rule; if (rule.alias) { const aliases = [].concat(rule.alias); for (const alias of aliases) { prototype[alias] = rule.method; } } if (rule.args) { rule.argsByName = new Map(); rule.args = rule.args.map((arg) => { if (typeof arg === 'string') { arg = { name: arg }; } Assert(!rule.argsByName.has(arg.name), 'Duplicated argument name', arg.name); if (Common.isSchema(arg.assert)) { arg.assert = arg.assert.strict().label(arg.name); } rule.argsByName.set(arg.name, arg); return arg; }); } } } def.rules = rules; // Modifiers const modifiers = Object.assign({}, parent.modifiers); if (def.modifiers) { for (const name in def.modifiers) { Assert(!prototype[name], 'Rule conflict in', def.type, name); const modifier = def.modifiers[name]; Assert(typeof modifier === 'function', 'Invalid modifier definition for', def.type, name); const method = function (arg) { return this.rule({ [name]: arg }); }; prototype[name] = method; modifiers[name] = modifier; } } def.modifiers = modifiers; // Overrides if (def.overrides) { prototype._super = base; schema.$_super = {}; // Backwards compatibility for (const override in def.overrides) { Assert(base[override], 'Cannot override missing', override); def.overrides[override][Common.symbols.parent] = base[override]; schema.$_super[override] = base[override].bind(schema); // Backwards compatibility } Object.assign(prototype, def.overrides); } // Casts def.cast = Object.assign({}, parent.cast, def.cast); // Manifest const manifest = Object.assign({}, parent.manifest, def.manifest); manifest.build = internals.build(def.manifest && def.manifest.build, parent.manifest && parent.manifest.build); def.manifest = manifest; // Rebuild def.rebuild = internals.rebuild(def.rebuild, parent.rebuild); return schema; }; // Helpers internals.build = function (child, parent) { if (!child || !parent) { return child || parent; } return function (obj, desc) { return parent(child(obj, desc), desc); }; }; internals.coerce = function (child, parent) { if (!child || !parent) { return child || parent; } return { from: child.from && parent.from ? [...new Set([...child.from, ...parent.from])] : null, method(value, helpers) { let coerced; if (!parent.from || parent.from.includes(typeof value)) { coerced = parent.method(value, helpers); if (coerced) { if (coerced.errors || coerced.value === undefined) { return coerced; } value = coerced.value; } } if (!child.from || child.from.includes(typeof value)) { const own = child.method(value, helpers); if (own) { return own; } } return coerced; } }; }; internals.prepare = function (child, parent) { if (!child || !parent) { return child || parent; } return function (value, helpers) { const prepared = child(value, helpers); if (prepared) { if (prepared.errors || prepared.value === undefined) { return prepared; } value = prepared.value; } return parent(value, helpers) || prepared; }; }; internals.rebuild = function (child, parent) { if (!child || !parent) { return child || parent; } return function (schema) { parent(schema); child(schema); }; }; internals.validate = function (child, parent) { if (!child || !parent) { return child || parent; } return function (value, helpers) { const result = parent(value, helpers); if (result) { if (result.errors && (!Array.isArray(result.errors) || result.errors.length)) { return result; } value = result.value; } return child(value, helpers) || result; }; }; return extend$1; } var manifest = {}; var hasRequiredManifest; function requireManifest () { if (hasRequiredManifest) return manifest; hasRequiredManifest = 1; const Assert = assert$4; const Clone = clone$6; const Common = requireCommon(); const Messages = requireMessages(); const Ref = requireRef(); const Template = requireTemplate(); let Schemas; const internals = {}; manifest.describe = function (schema) { const def = schema._definition; // Type const desc = { type: schema.type, flags: {}, rules: [] }; // Flags for (const flag in schema._flags) { if (flag[0] !== '_') { desc.flags[flag] = internals.describe(schema._flags[flag]); } } if (!Object.keys(desc.flags).length) { delete desc.flags; } // Preferences if (schema._preferences) { desc.preferences = Clone(schema._preferences, { shallow: ['messages'] }); delete desc.preferences[Common.symbols.prefs]; if (desc.preferences.messages) { desc.preferences.messages = Messages.decompile(desc.preferences.messages); } } // Allow / Invalid if (schema._valids) { desc.allow = schema._valids.describe(); } if (schema._invalids) { desc.invalid = schema._invalids.describe(); } // Rules for (const rule of schema._rules) { const ruleDef = def.rules[rule.name]; if (ruleDef.manifest === false) { // Defaults to true continue; } const item = { name: rule.name }; for (const custom in def.modifiers) { if (rule[custom] !== undefined) { item[custom] = internals.describe(rule[custom]); } } if (rule.args) { item.args = {}; for (const key in rule.args) { const arg = rule.args[key]; if (key === 'options' && !Object.keys(arg).length) { continue; } item.args[key] = internals.describe(arg, { assign: key }); } if (!Object.keys(item.args).length) { delete item.args; } } desc.rules.push(item); } if (!desc.rules.length) { delete desc.rules; } // Terms (must be last to verify no name conflicts) for (const term in schema.$_terms) { if (term[0] === '_') { continue; } Assert(!desc[term], 'Cannot describe schema due to internal name conflict with', term); const items = schema.$_terms[term]; if (!items) { continue; } if (items instanceof Map) { if (items.size) { desc[term] = [...items.entries()]; } continue; } if (Common.isValues(items)) { desc[term] = items.describe(); continue; } Assert(def.terms[term], 'Term', term, 'missing configuration'); const manifest = def.terms[term].manifest; const mapped = typeof manifest === 'object'; if (!items.length && !mapped) { continue; } const normalized = []; for (const item of items) { normalized.push(internals.describe(item)); } // Mapped if (mapped) { const { from, to } = manifest.mapped; desc[term] = {}; for (const item of normalized) { desc[term][item[to]] = item[from]; } continue; } // Single if (manifest === 'single') { Assert(normalized.length === 1, 'Term', term, 'contains more than one item'); desc[term] = normalized[0]; continue; } // Array desc[term] = normalized; } internals.validate(schema.$_root, desc); return desc; }; internals.describe = function (item, options = {}) { if (Array.isArray(item)) { return item.map(internals.describe); } if (item === Common.symbols.deepDefault) { return { special: 'deep' }; } if (typeof item !== 'object' || item === null) { return item; } if (options.assign === 'options') { return Clone(item); } if (Buffer && Buffer.isBuffer(item)) { // $lab:coverage:ignore$ return { buffer: item.toString('binary') }; } if (item instanceof Date) { return item.toISOString(); } if (item instanceof Error) { return item; } if (item instanceof RegExp) { if (options.assign === 'regex') { return item.toString(); } return { regex: item.toString() }; } if (item[Common.symbols.literal]) { return { function: item.literal }; } if (typeof item.describe === 'function') { if (options.assign === 'ref') { return item.describe().ref; } return item.describe(); } const normalized = {}; for (const key in item) { const value = item[key]; if (value === undefined) { continue; } normalized[key] = internals.describe(value, { assign: key }); } return normalized; }; manifest.build = function (joi, desc) { const builder = new internals.Builder(joi); return builder.parse(desc); }; internals.Builder = class { constructor(joi) { this.joi = joi; } parse(desc) { internals.validate(this.joi, desc); // Type let schema = this.joi[desc.type]()._bare(); const def = schema._definition; // Flags if (desc.flags) { for (const flag in desc.flags) { const setter = def.flags[flag] && def.flags[flag].setter || flag; Assert(typeof schema[setter] === 'function', 'Invalid flag', flag, 'for type', desc.type); schema = schema[setter](this.build(desc.flags[flag])); } } // Preferences if (desc.preferences) { schema = schema.preferences(this.build(desc.preferences)); } // Allow / Invalid if (desc.allow) { schema = schema.allow(...this.build(desc.allow)); } if (desc.invalid) { schema = schema.invalid(...this.build(desc.invalid)); } // Rules if (desc.rules) { for (const rule of desc.rules) { Assert(typeof schema[rule.name] === 'function', 'Invalid rule', rule.name, 'for type', desc.type); const args = []; if (rule.args) { const built = {}; for (const key in rule.args) { built[key] = this.build(rule.args[key], { assign: key }); } const keys = Object.keys(built); const definition = def.rules[rule.name].args; if (definition) { Assert(keys.length <= definition.length, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to', definition.length, ', found', keys.length, ')'); for (const { name } of definition) { args.push(built[name]); } } else { Assert(keys.length === 1, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to 1, found', keys.length, ')'); args.push(built[keys[0]]); } } // Apply schema = schema[rule.name](...args); // Ruleset const options = {}; for (const custom in def.modifiers) { if (rule[custom] !== undefined) { options[custom] = this.build(rule[custom]); } } if (Object.keys(options).length) { schema = schema.rule(options); } } } // Terms const terms = {}; for (const key in desc) { if (['allow', 'flags', 'invalid', 'whens', 'preferences', 'rules', 'type'].includes(key)) { continue; } Assert(def.terms[key], 'Term', key, 'missing configuration'); const manifest = def.terms[key].manifest; if (manifest === 'schema') { terms[key] = desc[key].map((item) => this.parse(item)); continue; } if (manifest === 'values') { terms[key] = desc[key].map((item) => this.build(item)); continue; } if (manifest === 'single') { terms[key] = this.build(desc[key]); continue; } if (typeof manifest === 'object') { terms[key] = {}; for (const name in desc[key]) { const value = desc[key][name]; terms[key][name] = this.parse(value); } continue; } terms[key] = this.build(desc[key]); } if (desc.whens) { terms.whens = desc.whens.map((when) => this.build(when)); } schema = def.manifest.build(schema, terms); schema.$_temp.ruleset = false; return schema; } build(desc, options = {}) { if (desc === null) { return null; } if (Array.isArray(desc)) { return desc.map((item) => this.build(item)); } if (desc instanceof Error) { return desc; } if (options.assign === 'options') { return Clone(desc); } if (options.assign === 'regex') { return internals.regex(desc); } if (options.assign === 'ref') { return Ref.build(desc); } if (typeof desc !== 'object') { return desc; } if (Object.keys(desc).length === 1) { if (desc.buffer) { Assert(Buffer, 'Buffers are not supported'); return Buffer && Buffer.from(desc.buffer, 'binary'); // $lab:coverage:ignore$ } if (desc.function) { return { [Common.symbols.literal]: true, literal: desc.function }; } if (desc.override) { return Common.symbols.override; } if (desc.ref) { return Ref.build(desc.ref); } if (desc.regex) { return internals.regex(desc.regex); } if (desc.special) { Assert(['deep'].includes(desc.special), 'Unknown special value', desc.special); return Common.symbols.deepDefault; } if (desc.value) { return Clone(desc.value); } } if (desc.type) { return this.parse(desc); } if (desc.template) { return Template.build(desc); } const normalized = {}; for (const key in desc) { normalized[key] = this.build(desc[key], { assign: key }); } return normalized; } }; internals.regex = function (string) { const end = string.lastIndexOf('/'); const exp = string.slice(1, end); const flags = string.slice(end + 1); return new RegExp(exp, flags); }; internals.validate = function (joi, desc) { Schemas = Schemas || requireSchemas(); joi.assert(desc, Schemas.description); }; return manifest; } var trace = {}; var hasRequiredTrace; function requireTrace () { if (hasRequiredTrace) return trace; hasRequiredTrace = 1; const DeepEqual = deepEqual; const Pinpoint = lib$7; const Errors = requireErrors(); const internals = { codes: { error: 1, pass: 2, full: 3 }, labels: { 0: 'never used', 1: 'always error', 2: 'always pass' } }; trace.setup = function (root) { const trace = function () { root._tracer = root._tracer || new internals.Tracer(); return root._tracer; }; root.trace = trace; root[Symbol.for('@hapi/lab/coverage/initialize')] = trace; root.untrace = () => { root._tracer = null; }; }; trace.location = function (schema) { return schema.$_setFlag('_tracerLocation', Pinpoint.location(2)); // base.tracer(), caller }; internals.Tracer = class { constructor() { this.name = 'Joi'; this._schemas = new Map(); } _register(schema) { const existing = this._schemas.get(schema); if (existing) { return existing.store; } const store = new internals.Store(schema); const { filename, line } = schema._flags._tracerLocation || Pinpoint.location(5); // internals.tracer(), internals.entry(), exports.entry(), validate(), caller this._schemas.set(schema, { filename, line, store }); return store; } _combine(merged, sources) { for (const { store } of this._schemas.values()) { store._combine(merged, sources); } } report(file) { const coverage = []; // Process each registered schema for (const { filename, line, store } of this._schemas.values()) { if (file && file !== filename) { continue; } // Process sub schemas of the registered root const missing = []; const skipped = []; for (const [schema, log] of store._sources.entries()) { // Check if sub schema parent skipped if (internals.sub(log.paths, skipped)) { continue; } // Check if sub schema reached if (!log.entry) { missing.push({ status: 'never reached', paths: [...log.paths] }); skipped.push(...log.paths); continue; } // Check values for (const type of ['valid', 'invalid']) { const set = schema[`_${type}s`]; if (!set) { continue; } const values = new Set(set._values); const refs = new Set(set._refs); for (const { value, ref } of log[type]) { values.delete(value); refs.delete(ref); } if (values.size || refs.size) { missing.push({ status: [...values, ...[...refs].map((ref) => ref.display)], rule: `${type}s` }); } } // Check rules status const rules = schema._rules.map((rule) => rule.name); for (const type of ['default', 'failover']) { if (schema._flags[type] !== undefined) { rules.push(type); } } for (const name of rules) { const status = internals.labels[log.rule[name] || 0]; if (status) { const report = { rule: name, status }; if (log.paths.size) { report.paths = [...log.paths]; } missing.push(report); } } } if (missing.length) { coverage.push({ filename, line, missing, severity: 'error', message: `Schema missing tests for ${missing.map(internals.message).join(', ')}` }); } } return coverage.length ? coverage : null; } }; internals.Store = class { constructor(schema) { this.active = true; this._sources = new Map(); // schema -> { paths, entry, rule, valid, invalid } this._combos = new Map(); // merged -> [sources] this._scan(schema); } debug(state, source, name, result) { state.mainstay.debug && state.mainstay.debug.push({ type: source, name, result, path: state.path }); } entry(schema, state) { internals.debug(state, { type: 'entry' }); this._record(schema, (log) => { log.entry = true; }); } filter(schema, state, source, value) { internals.debug(state, { type: source, ...value }); this._record(schema, (log) => { log[source].add(value); }); } log(schema, state, source, name, result) { internals.debug(state, { type: source, name, result: result === 'full' ? 'pass' : result }); this._record(schema, (log) => { log[source][name] = log[source][name] || 0; log[source][name] |= internals.codes[result]; }); } resolve(state, ref, to) { if (!state.mainstay.debug) { return; } const log = { type: 'resolve', ref: ref.display, to, path: state.path }; state.mainstay.debug.push(log); } value(state, by, from, to, name) { if (!state.mainstay.debug || DeepEqual(from, to)) { return; } const log = { type: 'value', by, from, to, path: state.path }; if (name) { log.name = name; } state.mainstay.debug.push(log); } _record(schema, each) { const log = this._sources.get(schema); if (log) { each(log); return; } const sources = this._combos.get(schema); for (const source of sources) { this._record(source, each); } } _scan(schema, _path) { const path = _path || []; let log = this._sources.get(schema); if (!log) { log = { paths: new Set(), entry: false, rule: {}, valid: new Set(), invalid: new Set() }; this._sources.set(schema, log); } if (path.length) { log.paths.add(path); } const each = (sub, source) => { const subId = internals.id(sub, source); this._scan(sub, path.concat(subId)); }; schema.$_modify({ each, ref: false }); } _combine(merged, sources) { this._combos.set(merged, sources); } }; internals.message = function (item) { const path = item.paths ? Errors.path(item.paths[0]) + (item.rule ? ':' : '') : ''; return `${path}${item.rule || ''} (${item.status})`; }; internals.id = function (schema, { source, name, path, key }) { if (schema._flags.id) { return schema._flags.id; } if (key) { return key; } name = `@${name}`; if (source === 'terms') { return [name, path[Math.min(path.length - 1, 1)]]; } return name; }; internals.sub = function (paths, skipped) { for (const path of paths) { for (const skip of skipped) { if (DeepEqual(path.slice(0, skip.length), skip)) { return true; } } } return false; }; internals.debug = function (state, event) { if (state.mainstay.debug) { event.path = state.debug ? [...state.path, state.debug] : state.path; state.mainstay.debug.push(event); } }; return trace; } var modify = {}; var hasRequiredModify; function requireModify () { if (hasRequiredModify) return modify; hasRequiredModify = 1; (function (exports) { const Assert = assert$4; const Common = requireCommon(); const Ref = requireRef(); const internals = {}; exports.Ids = internals.Ids = class { constructor() { this._byId = new Map(); this._byKey = new Map(); this._schemaChain = false; } clone() { const clone = new internals.Ids(); clone._byId = new Map(this._byId); clone._byKey = new Map(this._byKey); clone._schemaChain = this._schemaChain; return clone; } concat(source) { if (source._schemaChain) { this._schemaChain = true; } for (const [id, value] of source._byId.entries()) { Assert(!this._byKey.has(id), 'Schema id conflicts with existing key:', id); this._byId.set(id, value); } for (const [key, value] of source._byKey.entries()) { Assert(!this._byId.has(key), 'Schema key conflicts with existing id:', key); this._byKey.set(key, value); } } fork(path, adjuster, root) { const chain = this._collect(path); chain.push({ schema: root }); const tail = chain.shift(); let adjusted = { id: tail.id, schema: adjuster(tail.schema) }; Assert(Common.isSchema(adjusted.schema), 'adjuster function failed to return a joi schema type'); for (const node of chain) { adjusted = { id: node.id, schema: internals.fork(node.schema, adjusted.id, adjusted.schema) }; } return adjusted.schema; } labels(path, behind = []) { const current = path[0]; const node = this._get(current); if (!node) { return [...behind, ...path].join('.'); } const forward = path.slice(1); behind = [...behind, node.schema._flags.label || current]; if (!forward.length) { return behind.join('.'); } return node.schema._ids.labels(forward, behind); } reach(path, behind = []) { const current = path[0]; const node = this._get(current); Assert(node, 'Schema does not contain path', [...behind, ...path].join('.')); const forward = path.slice(1); if (!forward.length) { return node.schema; } return node.schema._ids.reach(forward, [...behind, current]); } register(schema, { key } = {}) { if (!schema || !Common.isSchema(schema)) { return; } if (schema.$_property('schemaChain') || schema._ids._schemaChain) { this._schemaChain = true; } const id = schema._flags.id; if (id) { const existing = this._byId.get(id); Assert(!existing || existing.schema === schema, 'Cannot add different schemas with the same id:', id); Assert(!this._byKey.has(id), 'Schema id conflicts with existing key:', id); this._byId.set(id, { schema, id }); } if (key) { Assert(!this._byKey.has(key), 'Schema already contains key:', key); Assert(!this._byId.has(key), 'Schema key conflicts with existing id:', key); this._byKey.set(key, { schema, id: key }); } } reset() { this._byId = new Map(); this._byKey = new Map(); this._schemaChain = false; } _collect(path, behind = [], nodes = []) { const current = path[0]; const node = this._get(current); Assert(node, 'Schema does not contain path', [...behind, ...path].join('.')); nodes = [node, ...nodes]; const forward = path.slice(1); if (!forward.length) { return nodes; } return node.schema._ids._collect(forward, [...behind, current], nodes); } _get(id) { return this._byId.get(id) || this._byKey.get(id); } }; internals.fork = function (schema, id, replacement) { const each = (item, { key }) => { if (id === (item._flags.id || key)) { return replacement; } }; const obj = exports.schema(schema, { each, ref: false }); return obj ? obj.$_mutateRebuild() : schema; }; exports.schema = function (schema, options) { let obj; for (const name in schema._flags) { if (name[0] === '_') { continue; } const result = internals.scan(schema._flags[name], { source: 'flags', name }, options); if (result !== undefined) { obj = obj || schema.clone(); obj._flags[name] = result; } } for (let i = 0; i < schema._rules.length; ++i) { const rule = schema._rules[i]; const result = internals.scan(rule.args, { source: 'rules', name: rule.name }, options); if (result !== undefined) { obj = obj || schema.clone(); const clone = Object.assign({}, rule); clone.args = result; obj._rules[i] = clone; const existingUnique = obj._singleRules.get(rule.name); if (existingUnique === rule) { obj._singleRules.set(rule.name, clone); } } } for (const name in schema.$_terms) { if (name[0] === '_') { continue; } const result = internals.scan(schema.$_terms[name], { source: 'terms', name }, options); if (result !== undefined) { obj = obj || schema.clone(); obj.$_terms[name] = result; } } return obj; }; internals.scan = function (item, source, options, _path, _key) { const path = _path || []; if (item === null || typeof item !== 'object') { return; } let clone; if (Array.isArray(item)) { for (let i = 0; i < item.length; ++i) { const key = source.source === 'terms' && source.name === 'keys' && item[i].key; const result = internals.scan(item[i], source, options, [i, ...path], key); if (result !== undefined) { clone = clone || item.slice(); clone[i] = result; } } return clone; } if (options.schema !== false && Common.isSchema(item) || options.ref !== false && Ref.isRef(item)) { const result = options.each(item, { ...source, path, key: _key }); if (result === item) { return; } return result; } for (const key in item) { if (key[0] === '_') { continue; } const result = internals.scan(item[key], source, options, [key, ...path], _key); if (result !== undefined) { clone = clone || Object.assign({}, item); clone[key] = result; } } return clone; }; } (modify)); return modify; } var validator = {}; var state; var hasRequiredState; function requireState () { if (hasRequiredState) return state; hasRequiredState = 1; const Clone = clone$6; const Reach = reach; const Common = requireCommon(); const internals = { value: Symbol('value') }; state = internals.State = class { constructor(path, ancestors, state) { this.path = path; this.ancestors = ancestors; // [parent, ..., root] this.mainstay = state.mainstay; this.schemas = state.schemas; // [current, ..., root] this.debug = null; } localize(path, ancestors = null, schema = null) { const state = new internals.State(path, ancestors, this); if (schema && state.schemas) { state.schemas = [internals.schemas(schema), ...state.schemas]; } return state; } nest(schema, debug) { const state = new internals.State(this.path, this.ancestors, this); state.schemas = state.schemas && [internals.schemas(schema), ...state.schemas]; state.debug = debug; return state; } shadow(value, reason) { this.mainstay.shadow = this.mainstay.shadow || new internals.Shadow(); this.mainstay.shadow.set(this.path, value, reason); } snapshot() { if (this.mainstay.shadow) { this._snapshot = Clone(this.mainstay.shadow.node(this.path)); } this.mainstay.snapshot(); } restore() { if (this.mainstay.shadow) { this.mainstay.shadow.override(this.path, this._snapshot); this._snapshot = undefined; } this.mainstay.restore(); } commit() { if (this.mainstay.shadow) { this.mainstay.shadow.override(this.path, this._snapshot); this._snapshot = undefined; } this.mainstay.commit(); } }; internals.schemas = function (schema) { if (Common.isSchema(schema)) { return { schema }; } return schema; }; internals.Shadow = class { constructor() { this._values = null; } set(path, value, reason) { if (!path.length) { // No need to store root value return; } if (reason === 'strip' && typeof path[path.length - 1] === 'number') { // Cannot store stripped array values (due to shift) return; } this._values = this._values || new Map(); let node = this._values; for (let i = 0; i < path.length; ++i) { const segment = path[i]; let next = node.get(segment); if (!next) { next = new Map(); node.set(segment, next); } node = next; } node[internals.value] = value; } get(path) { const node = this.node(path); if (node) { return node[internals.value]; } } node(path) { if (!this._values) { return; } return Reach(this._values, path, { iterables: true }); } override(path, node) { if (!this._values) { return; } const parents = path.slice(0, -1); const own = path[path.length - 1]; const parent = Reach(this._values, parents, { iterables: true }); if (node) { parent.set(own, node); return; } if (parent) { parent.delete(own); } } }; return state; } var hasRequiredValidator; function requireValidator () { if (hasRequiredValidator) return validator; hasRequiredValidator = 1; (function (exports) { const Assert = assert$4; const Clone = clone$6; const Ignore = ignore; const Reach = reach; const Common = requireCommon(); const Errors = requireErrors(); const State = requireState(); const internals = { result: Symbol('result') }; exports.entry = function (value, schema, prefs) { let settings = Common.defaults; if (prefs) { Assert(prefs.warnings === undefined, 'Cannot override warnings preference in synchronous validation'); Assert(prefs.artifacts === undefined, 'Cannot override artifacts preference in synchronous validation'); settings = Common.preferences(Common.defaults, prefs); } const result = internals.entry(value, schema, settings); Assert(!result.mainstay.externals.length, 'Schema with external rules must use validateAsync()'); const outcome = { value: result.value }; if (result.error) { outcome.error = result.error; } if (result.mainstay.warnings.length) { outcome.warning = Errors.details(result.mainstay.warnings); } if (result.mainstay.debug) { outcome.debug = result.mainstay.debug; } if (result.mainstay.artifacts) { outcome.artifacts = result.mainstay.artifacts; } return outcome; }; exports.entryAsync = async function (value, schema, prefs) { let settings = Common.defaults; if (prefs) { settings = Common.preferences(Common.defaults, prefs); } const result = internals.entry(value, schema, settings); const mainstay = result.mainstay; if (result.error) { if (mainstay.debug) { result.error.debug = mainstay.debug; } throw result.error; } if (mainstay.externals.length) { let root = result.value; const errors = []; for (const external of mainstay.externals) { const path = external.state.path; const linked = external.schema.type === 'link' ? mainstay.links.get(external.schema) : null; let node = root; let key; let parent; const ancestors = path.length ? [root] : []; const original = path.length ? Reach(value, path) : value; if (path.length) { key = path[path.length - 1]; let current = root; for (const segment of path.slice(0, -1)) { current = current[segment]; ancestors.unshift(current); } parent = ancestors[0]; node = parent[key]; } try { const createError = (code, local) => (linked || external.schema).$_createError(code, node, local, external.state, settings); const output = await external.method(node, { schema: external.schema, linked, state: external.state, prefs, original, error: createError, errorsArray: internals.errorsArray, warn: (code, local) => mainstay.warnings.push((linked || external.schema).$_createError(code, node, local, external.state, settings)), message: (messages, local) => (linked || external.schema).$_createError('external', node, local, external.state, settings, { messages }) }); if (output === undefined || output === node) { continue; } if (output instanceof Errors.Report) { mainstay.tracer.log(external.schema, external.state, 'rule', 'external', 'error'); errors.push(output); if (settings.abortEarly) { break; } continue; } if (Array.isArray(output) && output[Common.symbols.errors]) { mainstay.tracer.log(external.schema, external.state, 'rule', 'external', 'error'); errors.push(...output); if (settings.abortEarly) { break; } continue; } if (parent) { mainstay.tracer.value(external.state, 'rule', node, output, 'external'); parent[key] = output; } else { mainstay.tracer.value(external.state, 'rule', root, output, 'external'); root = output; } } catch (err) { if (settings.errors.label) { err.message += ` (${(external.label)})`; // Change message to include path } throw err; } } result.value = root; if (errors.length) { result.error = Errors.process(errors, value, settings); if (mainstay.debug) { result.error.debug = mainstay.debug; } throw result.error; } } if (!settings.warnings && !settings.debug && !settings.artifacts) { return result.value; } const outcome = { value: result.value }; if (mainstay.warnings.length) { outcome.warning = Errors.details(mainstay.warnings); } if (mainstay.debug) { outcome.debug = mainstay.debug; } if (mainstay.artifacts) { outcome.artifacts = mainstay.artifacts; } return outcome; }; internals.Mainstay = class { constructor(tracer, debug, links) { this.externals = []; this.warnings = []; this.tracer = tracer; this.debug = debug; this.links = links; this.shadow = null; this.artifacts = null; this._snapshots = []; } snapshot() { this._snapshots.push({ externals: this.externals.slice(), warnings: this.warnings.slice() }); } restore() { const snapshot = this._snapshots.pop(); this.externals = snapshot.externals; this.warnings = snapshot.warnings; } commit() { this._snapshots.pop(); } }; internals.entry = function (value, schema, prefs) { // Prepare state const { tracer, cleanup } = internals.tracer(schema, prefs); const debug = prefs.debug ? [] : null; const links = schema._ids._schemaChain ? new Map() : null; const mainstay = new internals.Mainstay(tracer, debug, links); const schemas = schema._ids._schemaChain ? [{ schema }] : null; const state = new State([], [], { mainstay, schemas }); // Validate value const result = exports.validate(value, schema, state, prefs); // Process value and errors if (cleanup) { schema.$_root.untrace(); } const error = Errors.process(result.errors, value, prefs); return { value: result.value, error, mainstay }; }; internals.tracer = function (schema, prefs) { if (schema.$_root._tracer) { return { tracer: schema.$_root._tracer._register(schema) }; } if (prefs.debug) { Assert(schema.$_root.trace, 'Debug mode not supported'); return { tracer: schema.$_root.trace()._register(schema), cleanup: true }; } return { tracer: internals.ignore }; }; exports.validate = function (value, schema, state, prefs, overrides = {}) { if (schema.$_terms.whens) { schema = schema._generate(value, state, prefs).schema; } // Setup state and settings if (schema._preferences) { prefs = internals.prefs(schema, prefs); } // Cache if (schema._cache && prefs.cache) { const result = schema._cache.get(value); state.mainstay.tracer.debug(state, 'validate', 'cached', !!result); if (result) { return result; } } // Helpers const createError = (code, local, localState) => schema.$_createError(code, value, local, localState || state, prefs); const helpers = { original: value, prefs, schema, state, error: createError, errorsArray: internals.errorsArray, warn: (code, local, localState) => state.mainstay.warnings.push(createError(code, local, localState)), message: (messages, local) => schema.$_createError('custom', value, local, state, prefs, { messages }) }; // Prepare state.mainstay.tracer.entry(schema, state); const def = schema._definition; if (def.prepare && value !== undefined && prefs.convert) { const prepared = def.prepare(value, helpers); if (prepared) { state.mainstay.tracer.value(state, 'prepare', value, prepared.value); if (prepared.errors) { return internals.finalize(prepared.value, [].concat(prepared.errors), helpers); // Prepare error always aborts early } value = prepared.value; } } // Type coercion if (def.coerce && value !== undefined && prefs.convert && (!def.coerce.from || def.coerce.from.includes(typeof value))) { const coerced = def.coerce.method(value, helpers); if (coerced) { state.mainstay.tracer.value(state, 'coerced', value, coerced.value); if (coerced.errors) { return internals.finalize(coerced.value, [].concat(coerced.errors), helpers); // Coerce error always aborts early } value = coerced.value; } } // Empty value const empty = schema._flags.empty; if (empty && empty.$_match(internals.trim(value, schema), state.nest(empty), Common.defaults)) { state.mainstay.tracer.value(state, 'empty', value, undefined); value = undefined; } // Presence requirements (required, optional, forbidden) const presence = overrides.presence || schema._flags.presence || (schema._flags._endedSwitch ? null : prefs.presence); if (value === undefined) { if (presence === 'forbidden') { return internals.finalize(value, null, helpers); } if (presence === 'required') { return internals.finalize(value, [schema.$_createError('any.required', value, null, state, prefs)], helpers); } if (presence === 'optional') { if (schema._flags.default !== Common.symbols.deepDefault) { return internals.finalize(value, null, helpers); } state.mainstay.tracer.value(state, 'default', value, {}); value = {}; } } else if (presence === 'forbidden') { return internals.finalize(value, [schema.$_createError('any.unknown', value, null, state, prefs)], helpers); } // Allowed values const errors = []; if (schema._valids) { const match = schema._valids.get(value, state, prefs, schema._flags.insensitive); if (match) { if (prefs.convert) { state.mainstay.tracer.value(state, 'valids', value, match.value); value = match.value; } state.mainstay.tracer.filter(schema, state, 'valid', match); return internals.finalize(value, null, helpers); } if (schema._flags.only) { const report = schema.$_createError('any.only', value, { valids: schema._valids.values({ display: true }) }, state, prefs); if (prefs.abortEarly) { return internals.finalize(value, [report], helpers); } errors.push(report); } } // Denied values if (schema._invalids) { const match = schema._invalids.get(value, state, prefs, schema._flags.insensitive); if (match) { state.mainstay.tracer.filter(schema, state, 'invalid', match); const report = schema.$_createError('any.invalid', value, { invalids: schema._invalids.values({ display: true }) }, state, prefs); if (prefs.abortEarly) { return internals.finalize(value, [report], helpers); } errors.push(report); } } // Base type if (def.validate) { const base = def.validate(value, helpers); if (base) { state.mainstay.tracer.value(state, 'base', value, base.value); value = base.value; if (base.errors) { if (!Array.isArray(base.errors)) { errors.push(base.errors); return internals.finalize(value, errors, helpers); // Base error always aborts early } if (base.errors.length) { errors.push(...base.errors); return internals.finalize(value, errors, helpers); // Base error always aborts early } } } } // Validate tests if (!schema._rules.length) { return internals.finalize(value, errors, helpers); } return internals.rules(value, errors, helpers); }; internals.rules = function (value, errors, helpers) { const { schema, state, prefs } = helpers; for (const rule of schema._rules) { const definition = schema._definition.rules[rule.method]; // Skip rules that are also applied in coerce step if (definition.convert && prefs.convert) { state.mainstay.tracer.log(schema, state, 'rule', rule.name, 'full'); continue; } // Resolve references let ret; let args = rule.args; if (rule._resolve.length) { args = Object.assign({}, args); // Shallow copy for (const key of rule._resolve) { const resolver = definition.argsByName.get(key); const resolved = args[key].resolve(value, state, prefs); const normalized = resolver.normalize ? resolver.normalize(resolved) : resolved; const invalid = Common.validateArg(normalized, null, resolver); if (invalid) { ret = schema.$_createError('any.ref', resolved, { arg: key, ref: args[key], reason: invalid }, state, prefs); break; } args[key] = normalized; } } // Test rule ret = ret || definition.validate(value, helpers, args, rule); // Use ret if already set to reference error const result = internals.rule(ret, rule); if (result.errors) { state.mainstay.tracer.log(schema, state, 'rule', rule.name, 'error'); if (rule.warn) { state.mainstay.warnings.push(...result.errors); continue; } if (prefs.abortEarly) { return internals.finalize(value, result.errors, helpers); } errors.push(...result.errors); } else { state.mainstay.tracer.log(schema, state, 'rule', rule.name, 'pass'); state.mainstay.tracer.value(state, 'rule', value, result.value, rule.name); value = result.value; } } return internals.finalize(value, errors, helpers); }; internals.rule = function (ret, rule) { if (ret instanceof Errors.Report) { internals.error(ret, rule); return { errors: [ret], value: null }; } if (Array.isArray(ret) && ret[Common.symbols.errors]) { ret.forEach((report) => internals.error(report, rule)); return { errors: ret, value: null }; } return { errors: null, value: ret }; }; internals.error = function (report, rule) { if (rule.message) { report._setTemplate(rule.message); } return report; }; internals.finalize = function (value, errors, helpers) { errors = errors || []; const { schema, state, prefs } = helpers; // Failover value if (errors.length) { const failover = internals.default('failover', undefined, errors, helpers); if (failover !== undefined) { state.mainstay.tracer.value(state, 'failover', value, failover); value = failover; errors = []; } } // Error override if (errors.length && schema._flags.error) { if (typeof schema._flags.error === 'function') { errors = schema._flags.error(errors); if (!Array.isArray(errors)) { errors = [errors]; } for (const error of errors) { Assert(error instanceof Error || error instanceof Errors.Report, 'error() must return an Error object'); } } else { errors = [schema._flags.error]; } } // Default if (value === undefined) { const defaulted = internals.default('default', value, errors, helpers); state.mainstay.tracer.value(state, 'default', value, defaulted); value = defaulted; } // Cast if (schema._flags.cast && value !== undefined) { const caster = schema._definition.cast[schema._flags.cast]; if (caster.from(value)) { const casted = caster.to(value, helpers); state.mainstay.tracer.value(state, 'cast', value, casted, schema._flags.cast); value = casted; } } // Externals if (schema.$_terms.externals && prefs.externals && prefs._externals !== false) { // Disabled for matching for (const { method } of schema.$_terms.externals) { state.mainstay.externals.push({ method, schema, state, label: Errors.label(schema._flags, state, prefs) }); } } // Result const result = { value, errors: errors.length ? errors : null }; if (schema._flags.result) { result.value = schema._flags.result === 'strip' ? undefined : /* raw */ helpers.original; state.mainstay.tracer.value(state, schema._flags.result, value, result.value); state.shadow(value, schema._flags.result); } // Cache if (schema._cache && prefs.cache !== false && !schema._refs.length) { schema._cache.set(helpers.original, result); } // Artifacts if (value !== undefined && !result.errors && schema._flags.artifact !== undefined) { state.mainstay.artifacts = state.mainstay.artifacts || new Map(); if (!state.mainstay.artifacts.has(schema._flags.artifact)) { state.mainstay.artifacts.set(schema._flags.artifact, []); } state.mainstay.artifacts.get(schema._flags.artifact).push(state.path); } return result; }; internals.prefs = function (schema, prefs) { const isDefaultOptions = prefs === Common.defaults; if (isDefaultOptions && schema._preferences[Common.symbols.prefs]) { return schema._preferences[Common.symbols.prefs]; } prefs = Common.preferences(prefs, schema._preferences); if (isDefaultOptions) { schema._preferences[Common.symbols.prefs] = prefs; } return prefs; }; internals.default = function (flag, value, errors, helpers) { const { schema, state, prefs } = helpers; const source = schema._flags[flag]; if (prefs.noDefaults || source === undefined) { return value; } state.mainstay.tracer.log(schema, state, 'rule', flag, 'full'); if (!source) { return source; } if (typeof source === 'function') { const args = source.length ? [Clone(state.ancestors[0]), helpers] : []; try { return source(...args); } catch (err) { errors.push(schema.$_createError(`any.${flag}`, null, { error: err }, state, prefs)); return; } } if (typeof source !== 'object') { return source; } if (source[Common.symbols.literal]) { return source.literal; } if (Common.isResolvable(source)) { return source.resolve(value, state, prefs); } return Clone(source); }; internals.trim = function (value, schema) { if (typeof value !== 'string') { return value; } const trim = schema.$_getRule('trim'); if (!trim || !trim.args.enabled) { return value; } return value.trim(); }; internals.ignore = { active: false, debug: Ignore, entry: Ignore, filter: Ignore, log: Ignore, resolve: Ignore, value: Ignore }; internals.errorsArray = function () { const errors = []; errors[Common.symbols.errors] = true; return errors; }; } (validator)); return validator; } var values$1; var hasRequiredValues; function requireValues () { if (hasRequiredValues) return values$1; hasRequiredValues = 1; const Assert = assert$4; const DeepEqual = deepEqual; const Common = requireCommon(); const internals = {}; values$1 = internals.Values = class { constructor(values, refs) { this._values = new Set(values); this._refs = new Set(refs); this._lowercase = internals.lowercases(values); this._override = false; } get length() { return this._values.size + this._refs.size; } add(value, refs) { // Reference if (Common.isResolvable(value)) { if (!this._refs.has(value)) { this._refs.add(value); if (refs) { // Skipped in a merge refs.register(value); } } return; } // Value if (!this.has(value, null, null, false)) { this._values.add(value); if (typeof value === 'string') { this._lowercase.set(value.toLowerCase(), value); } } } static merge(target, source, remove) { target = target || new internals.Values(); if (source) { if (source._override) { return source.clone(); } for (const item of [...source._values, ...source._refs]) { target.add(item); } } if (remove) { for (const item of [...remove._values, ...remove._refs]) { target.remove(item); } } return target.length ? target : null; } remove(value) { // Reference if (Common.isResolvable(value)) { this._refs.delete(value); return; } // Value this._values.delete(value); if (typeof value === 'string') { this._lowercase.delete(value.toLowerCase()); } } has(value, state, prefs, insensitive) { return !!this.get(value, state, prefs, insensitive); } get(value, state, prefs, insensitive) { if (!this.length) { return false; } // Simple match if (this._values.has(value)) { return { value }; } // Case insensitive string match if (typeof value === 'string' && value && insensitive) { const found = this._lowercase.get(value.toLowerCase()); if (found) { return { value: found }; } } if (!this._refs.size && typeof value !== 'object') { return false; } // Objects if (typeof value === 'object') { for (const item of this._values) { if (DeepEqual(item, value)) { return { value: item }; } } } // References if (state) { for (const ref of this._refs) { const resolved = ref.resolve(value, state, prefs, null, { in: true }); if (resolved === undefined) { continue; } const items = !ref.in || typeof resolved !== 'object' ? [resolved] : Array.isArray(resolved) ? resolved : Object.keys(resolved); for (const item of items) { if (typeof item !== typeof value) { continue; } if (insensitive && value && typeof value === 'string') { if (item.toLowerCase() === value.toLowerCase()) { return { value: item, ref }; } } else { if (DeepEqual(item, value)) { return { value: item, ref }; } } } } } return false; } override() { this._override = true; } values(options) { if (options && options.display) { const values = []; for (const item of [...this._values, ...this._refs]) { if (item !== undefined) { values.push(item); } } return values; } return Array.from([...this._values, ...this._refs]); } clone() { const set = new internals.Values(this._values, this._refs); set._override = this._override; return set; } concat(source) { Assert(!source._override, 'Cannot concat override set of values'); const set = new internals.Values([...this._values, ...source._values], [...this._refs, ...source._refs]); set._override = this._override; return set; } describe() { const normalized = []; if (this._override) { normalized.push({ override: true }); } for (const value of this._values.values()) { normalized.push(value && typeof value === 'object' ? { value } : value); } for (const value of this._refs.values()) { normalized.push(value.describe()); } return normalized; } }; internals.Values.prototype[Common.symbols.values] = true; // Aliases internals.Values.prototype.slice = internals.Values.prototype.clone; // Helpers internals.lowercases = function (from) { const map = new Map(); if (from) { for (const value of from) { if (typeof value === 'string') { map.set(value.toLowerCase(), value); } } } return map; }; return values$1; } var base; var hasRequiredBase; function requireBase () { if (hasRequiredBase) return base; hasRequiredBase = 1; const Assert = assert$4; const Clone = clone$6; const DeepEqual = deepEqual; const Merge = merge$3; const Cache = requireCache(); const Common = requireCommon(); const Compile = requireCompile(); const Errors = requireErrors(); const Extend = requireExtend(); const Manifest = requireManifest(); const Messages = requireMessages(); const Modify = requireModify(); const Ref = requireRef(); const Trace = requireTrace(); const Validator = requireValidator(); const Values = requireValues(); const internals = {}; internals.Base = class { constructor(type) { // Naming: public, _private, $_extension, $_mutate{action} this.type = type; this.$_root = null; this._definition = {}; this._reset(); } _reset() { this._ids = new Modify.Ids(); this._preferences = null; this._refs = new Ref.Manager(); this._cache = null; this._valids = null; this._invalids = null; this._flags = {}; this._rules = []; this._singleRules = new Map(); // The rule options passed for non-multi rules this.$_terms = {}; // Hash of arrays of immutable objects (extended by other types) this.$_temp = { // Runtime state (not cloned) ruleset: null, // null: use last, false: error, number: start position whens: {} // Runtime cache of generated whens }; } // Manifest describe() { Assert(typeof Manifest.describe === 'function', 'Manifest functionality disabled'); return Manifest.describe(this); } // Rules allow(...values) { Common.verifyFlat(values, 'allow'); return this._values(values, '_valids'); } alter(targets) { Assert(targets && typeof targets === 'object' && !Array.isArray(targets), 'Invalid targets argument'); Assert(!this._inRuleset(), 'Cannot set alterations inside a ruleset'); const obj = this.clone(); obj.$_terms.alterations = obj.$_terms.alterations || []; for (const target in targets) { const adjuster = targets[target]; Assert(typeof adjuster === 'function', 'Alteration adjuster for', target, 'must be a function'); obj.$_terms.alterations.push({ target, adjuster }); } obj.$_temp.ruleset = false; return obj; } artifact(id) { Assert(id !== undefined, 'Artifact cannot be undefined'); Assert(!this._cache, 'Cannot set an artifact with a rule cache'); return this.$_setFlag('artifact', id); } cast(to) { Assert(to === false || typeof to === 'string', 'Invalid to value'); Assert(to === false || this._definition.cast[to], 'Type', this.type, 'does not support casting to', to); return this.$_setFlag('cast', to === false ? undefined : to); } default(value, options) { return this._default('default', value, options); } description(desc) { Assert(desc && typeof desc === 'string', 'Description must be a non-empty string'); return this.$_setFlag('description', desc); } empty(schema) { const obj = this.clone(); if (schema !== undefined) { schema = obj.$_compile(schema, { override: false }); } return obj.$_setFlag('empty', schema, { clone: false }); } error(err) { Assert(err, 'Missing error'); Assert(err instanceof Error || typeof err === 'function', 'Must provide a valid Error object or a function'); return this.$_setFlag('error', err); } example(example, options = {}) { Assert(example !== undefined, 'Missing example'); Common.assertOptions(options, ['override']); return this._inner('examples', example, { single: true, override: options.override }); } external(method, description) { if (typeof method === 'object') { Assert(!description, 'Cannot combine options with description'); description = method.description; method = method.method; } Assert(typeof method === 'function', 'Method must be a function'); Assert(description === undefined || description && typeof description === 'string', 'Description must be a non-empty string'); return this._inner('externals', { method, description }, { single: true }); } failover(value, options) { return this._default('failover', value, options); } forbidden() { return this.presence('forbidden'); } id(id) { if (!id) { return this.$_setFlag('id', undefined); } Assert(typeof id === 'string', 'id must be a non-empty string'); Assert(/^[^\.]+$/.test(id), 'id cannot contain period character'); return this.$_setFlag('id', id); } invalid(...values) { return this._values(values, '_invalids'); } label(name) { Assert(name && typeof name === 'string', 'Label name must be a non-empty string'); return this.$_setFlag('label', name); } meta(meta) { Assert(meta !== undefined, 'Meta cannot be undefined'); return this._inner('metas', meta, { single: true }); } note(...notes) { Assert(notes.length, 'Missing notes'); for (const note of notes) { Assert(note && typeof note === 'string', 'Notes must be non-empty strings'); } return this._inner('notes', notes); } only(mode = true) { Assert(typeof mode === 'boolean', 'Invalid mode:', mode); return this.$_setFlag('only', mode); } optional() { return this.presence('optional'); } prefs(prefs) { Assert(prefs, 'Missing preferences'); Assert(prefs.context === undefined, 'Cannot override context'); Assert(prefs.externals === undefined, 'Cannot override externals'); Assert(prefs.warnings === undefined, 'Cannot override warnings'); Assert(prefs.debug === undefined, 'Cannot override debug'); Common.checkPreferences(prefs); const obj = this.clone(); obj._preferences = Common.preferences(obj._preferences, prefs); return obj; } presence(mode) { Assert(['optional', 'required', 'forbidden'].includes(mode), 'Unknown presence mode', mode); return this.$_setFlag('presence', mode); } raw(enabled = true) { return this.$_setFlag('result', enabled ? 'raw' : undefined); } result(mode) { Assert(['raw', 'strip'].includes(mode), 'Unknown result mode', mode); return this.$_setFlag('result', mode); } required() { return this.presence('required'); } strict(enabled) { const obj = this.clone(); const convert = enabled === undefined ? false : !enabled; obj._preferences = Common.preferences(obj._preferences, { convert }); return obj; } strip(enabled = true) { return this.$_setFlag('result', enabled ? 'strip' : undefined); } tag(...tags) { Assert(tags.length, 'Missing tags'); for (const tag of tags) { Assert(tag && typeof tag === 'string', 'Tags must be non-empty strings'); } return this._inner('tags', tags); } unit(name) { Assert(name && typeof name === 'string', 'Unit name must be a non-empty string'); return this.$_setFlag('unit', name); } valid(...values) { Common.verifyFlat(values, 'valid'); const obj = this.allow(...values); obj.$_setFlag('only', !!obj._valids, { clone: false }); return obj; } when(condition, options) { const obj = this.clone(); if (!obj.$_terms.whens) { obj.$_terms.whens = []; } const when = Compile.when(obj, condition, options); if (!['any', 'link'].includes(obj.type)) { const conditions = when.is ? [when] : when.switch; for (const item of conditions) { Assert(!item.then || item.then.type === 'any' || item.then.type === obj.type, 'Cannot combine', obj.type, 'with', item.then && item.then.type); Assert(!item.otherwise || item.otherwise.type === 'any' || item.otherwise.type === obj.type, 'Cannot combine', obj.type, 'with', item.otherwise && item.otherwise.type); } } obj.$_terms.whens.push(when); return obj.$_mutateRebuild(); } // Helpers cache(cache) { Assert(!this._inRuleset(), 'Cannot set caching inside a ruleset'); Assert(!this._cache, 'Cannot override schema cache'); Assert(this._flags.artifact === undefined, 'Cannot cache a rule with an artifact'); const obj = this.clone(); obj._cache = cache || Cache.provider.provision(); obj.$_temp.ruleset = false; return obj; } clone() { const obj = Object.create(Object.getPrototypeOf(this)); return this._assign(obj); } concat(source) { Assert(Common.isSchema(source), 'Invalid schema object'); Assert(this.type === 'any' || source.type === 'any' || source.type === this.type, 'Cannot merge type', this.type, 'with another type:', source.type); Assert(!this._inRuleset(), 'Cannot concatenate onto a schema with open ruleset'); Assert(!source._inRuleset(), 'Cannot concatenate a schema with open ruleset'); let obj = this.clone(); if (this.type === 'any' && source.type !== 'any') { // Change obj to match source type const tmpObj = source.clone(); for (const key of Object.keys(obj)) { if (key !== 'type') { tmpObj[key] = obj[key]; } } obj = tmpObj; } obj._ids.concat(source._ids); obj._refs.register(source, Ref.toSibling); obj._preferences = obj._preferences ? Common.preferences(obj._preferences, source._preferences) : source._preferences; obj._valids = Values.merge(obj._valids, source._valids, source._invalids); obj._invalids = Values.merge(obj._invalids, source._invalids, source._valids); // Remove unique rules present in source for (const name of source._singleRules.keys()) { if (obj._singleRules.has(name)) { obj._rules = obj._rules.filter((target) => target.keep || target.name !== name); obj._singleRules.delete(name); } } // Rules for (const test of source._rules) { if (!source._definition.rules[test.method].multi) { obj._singleRules.set(test.name, test); } obj._rules.push(test); } // Flags if (obj._flags.empty && source._flags.empty) { obj._flags.empty = obj._flags.empty.concat(source._flags.empty); const flags = Object.assign({}, source._flags); delete flags.empty; Merge(obj._flags, flags); } else if (source._flags.empty) { obj._flags.empty = source._flags.empty; const flags = Object.assign({}, source._flags); delete flags.empty; Merge(obj._flags, flags); } else { Merge(obj._flags, source._flags); } // Terms for (const key in source.$_terms) { const terms = source.$_terms[key]; if (!terms) { if (!obj.$_terms[key]) { obj.$_terms[key] = terms; } continue; } if (!obj.$_terms[key]) { obj.$_terms[key] = terms.slice(); continue; } obj.$_terms[key] = obj.$_terms[key].concat(terms); } // Tracing if (this.$_root._tracer) { this.$_root._tracer._combine(obj, [this, source]); } // Rebuild return obj.$_mutateRebuild(); } extend(options) { Assert(!options.base, 'Cannot extend type with another base'); return Extend.type(this, options); } extract(path) { path = Array.isArray(path) ? path : path.split('.'); return this._ids.reach(path); } fork(paths, adjuster) { Assert(!this._inRuleset(), 'Cannot fork inside a ruleset'); let obj = this; // eslint-disable-line consistent-this for (let path of [].concat(paths)) { path = Array.isArray(path) ? path : path.split('.'); obj = obj._ids.fork(path, adjuster, obj); } obj.$_temp.ruleset = false; return obj; } rule(options) { const def = this._definition; Common.assertOptions(options, Object.keys(def.modifiers)); Assert(this.$_temp.ruleset !== false, 'Cannot apply rules to empty ruleset or the last rule added does not support rule properties'); const start = this.$_temp.ruleset === null ? this._rules.length - 1 : this.$_temp.ruleset; Assert(start >= 0 && start < this._rules.length, 'Cannot apply rules to empty ruleset'); const obj = this.clone(); for (let i = start; i < obj._rules.length; ++i) { const original = obj._rules[i]; const rule = Clone(original); for (const name in options) { def.modifiers[name](rule, options[name]); Assert(rule.name === original.name, 'Cannot change rule name'); } obj._rules[i] = rule; if (obj._singleRules.get(rule.name) === original) { obj._singleRules.set(rule.name, rule); } } obj.$_temp.ruleset = false; return obj.$_mutateRebuild(); } get ruleset() { Assert(!this._inRuleset(), 'Cannot start a new ruleset without closing the previous one'); const obj = this.clone(); obj.$_temp.ruleset = obj._rules.length; return obj; } get $() { return this.ruleset; } tailor(targets) { targets = [].concat(targets); Assert(!this._inRuleset(), 'Cannot tailor inside a ruleset'); let obj = this; // eslint-disable-line consistent-this if (this.$_terms.alterations) { for (const { target, adjuster } of this.$_terms.alterations) { if (targets.includes(target)) { obj = adjuster(obj); Assert(Common.isSchema(obj), 'Alteration adjuster for', target, 'failed to return a schema object'); } } } obj = obj.$_modify({ each: (item) => item.tailor(targets), ref: false }); obj.$_temp.ruleset = false; return obj.$_mutateRebuild(); } tracer() { return Trace.location ? Trace.location(this) : this; // $lab:coverage:ignore$ } validate(value, options) { return Validator.entry(value, this, options); } validateAsync(value, options) { return Validator.entryAsync(value, this, options); } // Extensions $_addRule(options) { // Normalize rule if (typeof options === 'string') { options = { name: options }; } Assert(options && typeof options === 'object', 'Invalid options'); Assert(options.name && typeof options.name === 'string', 'Invalid rule name'); for (const key in options) { Assert(key[0] !== '_', 'Cannot set private rule properties'); } const rule = Object.assign({}, options); // Shallow cloned rule._resolve = []; rule.method = rule.method || rule.name; const definition = this._definition.rules[rule.method]; const args = rule.args; Assert(definition, 'Unknown rule', rule.method); // Args const obj = this.clone(); if (args) { Assert(Object.keys(args).length === 1 || Object.keys(args).length === this._definition.rules[rule.name].args.length, 'Invalid rule definition for', this.type, rule.name); for (const key in args) { let arg = args[key]; if (definition.argsByName) { const resolver = definition.argsByName.get(key); if (resolver.ref && Common.isResolvable(arg)) { rule._resolve.push(key); obj.$_mutateRegister(arg); } else { if (resolver.normalize) { arg = resolver.normalize(arg); args[key] = arg; } if (resolver.assert) { const error = Common.validateArg(arg, key, resolver); Assert(!error, error, 'or reference'); } } } if (arg === undefined) { delete args[key]; continue; } args[key] = arg; } } // Unique rules if (!definition.multi) { obj._ruleRemove(rule.name, { clone: false }); obj._singleRules.set(rule.name, rule); } if (obj.$_temp.ruleset === false) { obj.$_temp.ruleset = null; } if (definition.priority) { obj._rules.unshift(rule); } else { obj._rules.push(rule); } return obj; } $_compile(schema, options) { return Compile.schema(this.$_root, schema, options); } $_createError(code, value, local, state, prefs, options = {}) { const flags = options.flags !== false ? this._flags : {}; const messages = options.messages ? Messages.merge(this._definition.messages, options.messages) : this._definition.messages; return new Errors.Report(code, value, local, flags, messages, state, prefs); } $_getFlag(name) { return this._flags[name]; } $_getRule(name) { return this._singleRules.get(name); } $_mapLabels(path) { path = Array.isArray(path) ? path : path.split('.'); return this._ids.labels(path); } $_match(value, state, prefs, overrides) { prefs = Object.assign({}, prefs); // Shallow cloned prefs.abortEarly = true; prefs._externals = false; state.snapshot(); const result = !Validator.validate(value, this, state, prefs, overrides).errors; state.restore(); return result; } $_modify(options) { Common.assertOptions(options, ['each', 'once', 'ref', 'schema']); return Modify.schema(this, options) || this; } $_mutateRebuild() { Assert(!this._inRuleset(), 'Cannot add this rule inside a ruleset'); this._refs.reset(); this._ids.reset(); const each = (item, { source, name, path, key }) => { const family = this._definition[source][name] && this._definition[source][name].register; if (family !== false) { this.$_mutateRegister(item, { family, key }); } }; this.$_modify({ each }); if (this._definition.rebuild) { this._definition.rebuild(this); } this.$_temp.ruleset = false; return this; } $_mutateRegister(schema, { family, key } = {}) { this._refs.register(schema, family); this._ids.register(schema, { key }); } $_property(name) { return this._definition.properties[name]; } $_reach(path) { return this._ids.reach(path); } $_rootReferences() { return this._refs.roots(); } $_setFlag(name, value, options = {}) { Assert(name[0] === '_' || !this._inRuleset(), 'Cannot set flag inside a ruleset'); const flag = this._definition.flags[name] || {}; if (DeepEqual(value, flag.default)) { value = undefined; } if (DeepEqual(value, this._flags[name])) { return this; } const obj = options.clone !== false ? this.clone() : this; if (value !== undefined) { obj._flags[name] = value; obj.$_mutateRegister(value); } else { delete obj._flags[name]; } if (name[0] !== '_') { obj.$_temp.ruleset = false; } return obj; } $_parent(method, ...args) { return this[method][Common.symbols.parent].call(this, ...args); } $_validate(value, state, prefs) { return Validator.validate(value, this, state, prefs); } // Internals _assign(target) { target.type = this.type; target.$_root = this.$_root; target.$_temp = Object.assign({}, this.$_temp); target.$_temp.whens = {}; target._ids = this._ids.clone(); target._preferences = this._preferences; target._valids = this._valids && this._valids.clone(); target._invalids = this._invalids && this._invalids.clone(); target._rules = this._rules.slice(); target._singleRules = Clone(this._singleRules, { shallow: true }); target._refs = this._refs.clone(); target._flags = Object.assign({}, this._flags); target._cache = null; target.$_terms = {}; for (const key in this.$_terms) { target.$_terms[key] = this.$_terms[key] ? this.$_terms[key].slice() : null; } // Backwards compatibility target.$_super = {}; for (const override in this.$_super) { target.$_super[override] = this._super[override].bind(target); } return target; } _bare() { const obj = this.clone(); obj._reset(); const terms = obj._definition.terms; for (const name in terms) { const term = terms[name]; obj.$_terms[name] = term.init; } return obj.$_mutateRebuild(); } _default(flag, value, options = {}) { Common.assertOptions(options, 'literal'); Assert(value !== undefined, 'Missing', flag, 'value'); Assert(typeof value === 'function' || !options.literal, 'Only function value supports literal option'); if (typeof value === 'function' && options.literal) { value = { [Common.symbols.literal]: true, literal: value }; } const obj = this.$_setFlag(flag, value); return obj; } _generate(value, state, prefs) { if (!this.$_terms.whens) { return { schema: this }; } // Collect matching whens const whens = []; const ids = []; for (let i = 0; i < this.$_terms.whens.length; ++i) { const when = this.$_terms.whens[i]; if (when.concat) { whens.push(when.concat); ids.push(`${i}.concat`); continue; } const input = when.ref ? when.ref.resolve(value, state, prefs) : value; const tests = when.is ? [when] : when.switch; const before = ids.length; for (let j = 0; j < tests.length; ++j) { const { is, then, otherwise } = tests[j]; const baseId = `${i}${when.switch ? '.' + j : ''}`; if (is.$_match(input, state.nest(is, `${baseId}.is`), prefs)) { if (then) { const localState = state.localize([...state.path, `${baseId}.then`], state.ancestors, state.schemas); const { schema: generated, id } = then._generate(value, localState, prefs); whens.push(generated); ids.push(`${baseId}.then${id ? `(${id})` : ''}`); break; } } else if (otherwise) { const localState = state.localize([...state.path, `${baseId}.otherwise`], state.ancestors, state.schemas); const { schema: generated, id } = otherwise._generate(value, localState, prefs); whens.push(generated); ids.push(`${baseId}.otherwise${id ? `(${id})` : ''}`); break; } } if (when.break && ids.length > before) { // Something matched break; } } // Check cache const id = ids.join(', '); state.mainstay.tracer.debug(state, 'rule', 'when', id); if (!id) { return { schema: this }; } if (!state.mainstay.tracer.active && this.$_temp.whens[id]) { return { schema: this.$_temp.whens[id], id }; } // Generate dynamic schema let obj = this; // eslint-disable-line consistent-this if (this._definition.generate) { obj = this._definition.generate(this, value, state, prefs); } // Apply whens for (const when of whens) { obj = obj.concat(when); } // Tracing if (this.$_root._tracer) { this.$_root._tracer._combine(obj, [this, ...whens]); } // Cache result this.$_temp.whens[id] = obj; return { schema: obj, id }; } _inner(type, values, options = {}) { Assert(!this._inRuleset(), `Cannot set ${type} inside a ruleset`); const obj = this.clone(); if (!obj.$_terms[type] || options.override) { obj.$_terms[type] = []; } if (options.single) { obj.$_terms[type].push(values); } else { obj.$_terms[type].push(...values); } obj.$_temp.ruleset = false; return obj; } _inRuleset() { return this.$_temp.ruleset !== null && this.$_temp.ruleset !== false; } _ruleRemove(name, options = {}) { if (!this._singleRules.has(name)) { return this; } const obj = options.clone !== false ? this.clone() : this; obj._singleRules.delete(name); const filtered = []; for (let i = 0; i < obj._rules.length; ++i) { const test = obj._rules[i]; if (test.name === name && !test.keep) { if (obj._inRuleset() && i < obj.$_temp.ruleset) { --obj.$_temp.ruleset; } continue; } filtered.push(test); } obj._rules = filtered; return obj; } _values(values, key) { Common.verifyFlat(values, key.slice(1, -1)); const obj = this.clone(); const override = values[0] === Common.symbols.override; if (override) { values = values.slice(1); } if (!obj[key] && values.length) { obj[key] = new Values(); } else if (override) { obj[key] = values.length ? new Values() : null; obj.$_mutateRebuild(); } if (!obj[key]) { return obj; } if (override) { obj[key].override(); } for (const value of values) { Assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined'); Assert(value !== Common.symbols.override, 'Override must be the first value'); const other = key === '_invalids' ? '_valids' : '_invalids'; if (obj[other]) { obj[other].remove(value); if (!obj[other].length) { Assert(key === '_valids' || !obj._flags.only, 'Setting invalid value', value, 'leaves schema rejecting all values due to previous valid rule'); obj[other] = null; } } obj[key].add(value, obj._refs); } return obj; } }; internals.Base.prototype[Common.symbols.any] = { version: Common.version, compile: Compile.compile, root: '$_root' }; internals.Base.prototype.isImmutable = true; // Prevents Hoek from deep cloning schema objects (must be on prototype) // Aliases internals.Base.prototype.deny = internals.Base.prototype.invalid; internals.Base.prototype.disallow = internals.Base.prototype.invalid; internals.Base.prototype.equal = internals.Base.prototype.valid; internals.Base.prototype.exist = internals.Base.prototype.required; internals.Base.prototype.not = internals.Base.prototype.invalid; internals.Base.prototype.options = internals.Base.prototype.prefs; internals.Base.prototype.preferences = internals.Base.prototype.prefs; base = new internals.Base(); return base; } var any; var hasRequiredAny; function requireAny () { if (hasRequiredAny) return any; hasRequiredAny = 1; const Assert = assert$4; const Base = requireBase(); const Common = requireCommon(); const Messages = requireMessages(); any = Base.extend({ type: 'any', flags: { only: { default: false } }, terms: { alterations: { init: null }, examples: { init: null }, externals: { init: null }, metas: { init: [] }, notes: { init: [] }, shared: { init: null }, tags: { init: [] }, whens: { init: null } }, rules: { custom: { method(method, description) { Assert(typeof method === 'function', 'Method must be a function'); Assert(description === undefined || description && typeof description === 'string', 'Description must be a non-empty string'); return this.$_addRule({ name: 'custom', args: { method, description } }); }, validate(value, helpers, { method }) { try { return method(value, helpers); } catch (err) { return helpers.error('any.custom', { error: err }); } }, args: ['method', 'description'], multi: true }, messages: { method(messages) { return this.prefs({ messages }); } }, shared: { method(schema) { Assert(Common.isSchema(schema) && schema._flags.id, 'Schema must be a schema with an id'); const obj = this.clone(); obj.$_terms.shared = obj.$_terms.shared || []; obj.$_terms.shared.push(schema); obj.$_mutateRegister(schema); return obj; } }, warning: { method(code, local) { Assert(code && typeof code === 'string', 'Invalid warning code'); return this.$_addRule({ name: 'warning', args: { code, local }, warn: true }); }, validate(value, helpers, { code, local }) { return helpers.error(code, local); }, args: ['code', 'local'], multi: true } }, modifiers: { keep(rule, enabled = true) { rule.keep = enabled; }, message(rule, message) { rule.message = Messages.compile(message); }, warn(rule, enabled = true) { rule.warn = enabled; } }, manifest: { build(obj, desc) { for (const key in desc) { const values = desc[key]; if (['examples', 'externals', 'metas', 'notes', 'tags'].includes(key)) { for (const value of values) { obj = obj[key.slice(0, -1)](value); } continue; } if (key === 'alterations') { const alter = {}; for (const { target, adjuster } of values) { alter[target] = adjuster; } obj = obj.alter(alter); continue; } if (key === 'whens') { for (const value of values) { const { ref, is, not, then, otherwise, concat } = value; if (concat) { obj = obj.concat(concat); } else if (ref) { obj = obj.when(ref, { is, not, then, otherwise, switch: value.switch, break: value.break }); } else { obj = obj.when(is, { then, otherwise, break: value.break }); } } continue; } if (key === 'shared') { for (const value of values) { obj = obj.shared(value); } } } return obj; } }, messages: { 'any.custom': '{{#label}} failed custom validation because {{#error.message}}', 'any.default': '{{#label}} threw an error when running default method', 'any.failover': '{{#label}} threw an error when running failover method', 'any.invalid': '{{#label}} contains an invalid value', 'any.only': '{{#label}} must be {if(#valids.length == 1, "", "one of ")}{{#valids}}', 'any.ref': '{{#label}} {{#arg}} references {{:#ref}} which {{#reason}}', 'any.required': '{{#label}} is required', 'any.unknown': '{{#label}} is not allowed' } }); return any; } var alternatives; var hasRequiredAlternatives; function requireAlternatives () { if (hasRequiredAlternatives) return alternatives; hasRequiredAlternatives = 1; const Assert = assert$4; const Merge = merge$3; const Any = requireAny(); const Common = requireCommon(); const Compile = requireCompile(); const Errors = requireErrors(); const Ref = requireRef(); const internals = {}; alternatives = Any.extend({ type: 'alternatives', flags: { match: { default: 'any' } // 'any', 'one', 'all' }, terms: { matches: { init: [], register: Ref.toSibling } }, args(schema, ...schemas) { if (schemas.length === 1) { if (Array.isArray(schemas[0])) { return schema.try(...schemas[0]); } } return schema.try(...schemas); }, validate(value, helpers) { const { schema, error, state, prefs } = helpers; // Match all or one if (schema._flags.match) { const matched = []; const failed = []; for (let i = 0; i < schema.$_terms.matches.length; ++i) { const item = schema.$_terms.matches[i]; const localState = state.nest(item.schema, `match.${i}`); localState.snapshot(); const result = item.schema.$_validate(value, localState, prefs); if (!result.errors) { matched.push(result.value); localState.commit(); } else { failed.push(result.errors); localState.restore(); } } if (matched.length === 0) { const context = { details: failed.map((f) => Errors.details(f, { override: false })) }; return { errors: error('alternatives.any', context) }; } // Match one if (schema._flags.match === 'one') { return matched.length === 1 ? { value: matched[0] } : { errors: error('alternatives.one') }; } // Match all if (matched.length !== schema.$_terms.matches.length) { const context = { details: failed.map((f) => Errors.details(f, { override: false })) }; return { errors: error('alternatives.all', context) }; } const isAnyObj = (alternative) => { return alternative.$_terms.matches.some((v) => { return v.schema.type === 'object' || (v.schema.type === 'alternatives' && isAnyObj(v.schema)); }); }; return isAnyObj(schema) ? { value: matched.reduce((acc, v) => Merge(acc, v, { mergeArrays: false })) } : { value: matched[matched.length - 1] }; } // Match any const errors = []; for (let i = 0; i < schema.$_terms.matches.length; ++i) { const item = schema.$_terms.matches[i]; // Try if (item.schema) { const localState = state.nest(item.schema, `match.${i}`); localState.snapshot(); const result = item.schema.$_validate(value, localState, prefs); if (!result.errors) { localState.commit(); return result; } localState.restore(); errors.push({ schema: item.schema, reports: result.errors }); continue; } // Conditional const input = item.ref ? item.ref.resolve(value, state, prefs) : value; const tests = item.is ? [item] : item.switch; for (let j = 0; j < tests.length; ++j) { const test = tests[j]; const { is, then, otherwise } = test; const id = `match.${i}${item.switch ? '.' + j : ''}`; if (!is.$_match(input, state.nest(is, `${id}.is`), prefs)) { if (otherwise) { return otherwise.$_validate(value, state.nest(otherwise, `${id}.otherwise`), prefs); } } else if (then) { return then.$_validate(value, state.nest(then, `${id}.then`), prefs); } } } return internals.errors(errors, helpers); }, rules: { conditional: { method(condition, options) { Assert(!this._flags._endedSwitch, 'Unreachable condition'); Assert(!this._flags.match, 'Cannot combine match mode', this._flags.match, 'with conditional rule'); Assert(options.break === undefined, 'Cannot use break option with alternatives conditional'); const obj = this.clone(); const match = Compile.when(obj, condition, options); const conditions = match.is ? [match] : match.switch; for (const item of conditions) { if (item.then && item.otherwise) { obj.$_setFlag('_endedSwitch', true, { clone: false }); break; } } obj.$_terms.matches.push(match); return obj.$_mutateRebuild(); } }, match: { method(mode) { Assert(['any', 'one', 'all'].includes(mode), 'Invalid alternatives match mode', mode); if (mode !== 'any') { for (const match of this.$_terms.matches) { Assert(match.schema, 'Cannot combine match mode', mode, 'with conditional rules'); } } return this.$_setFlag('match', mode); } }, try: { method(...schemas) { Assert(schemas.length, 'Missing alternative schemas'); Common.verifyFlat(schemas, 'try'); Assert(!this._flags._endedSwitch, 'Unreachable condition'); const obj = this.clone(); for (const schema of schemas) { obj.$_terms.matches.push({ schema: obj.$_compile(schema) }); } return obj.$_mutateRebuild(); } } }, overrides: { label(name) { const obj = this.$_parent('label', name); const each = (item, source) => { return source.path[0] !== 'is' && typeof item._flags.label !== 'string' ? item.label(name) : undefined; }; return obj.$_modify({ each, ref: false }); } }, rebuild(schema) { // Flag when an alternative type is an array const each = (item) => { if (Common.isSchema(item) && item.type === 'array') { schema.$_setFlag('_arrayItems', true, { clone: false }); } }; schema.$_modify({ each }); }, manifest: { build(obj, desc) { if (desc.matches) { for (const match of desc.matches) { const { schema, ref, is, not, then, otherwise } = match; if (schema) { obj = obj.try(schema); } else if (ref) { obj = obj.conditional(ref, { is, then, not, otherwise, switch: match.switch }); } else { obj = obj.conditional(is, { then, otherwise }); } } } return obj; } }, messages: { 'alternatives.all': '{{#label}} does not match all of the required types', 'alternatives.any': '{{#label}} does not match any of the allowed types', 'alternatives.match': '{{#label}} does not match any of the allowed types', 'alternatives.one': '{{#label}} matches more than one allowed type', 'alternatives.types': '{{#label}} must be one of {{#types}}' } }); // Helpers internals.errors = function (failures, { error, state }) { // Nothing matched due to type criteria rules if (!failures.length) { return { errors: error('alternatives.any') }; } // Single error if (failures.length === 1) { return { errors: failures[0].reports }; } // Analyze reasons const valids = new Set(); const complex = []; for (const { reports, schema } of failures) { // Multiple errors (!abortEarly) if (reports.length > 1) { return internals.unmatched(failures, error); } // Custom error const report = reports[0]; if (report instanceof Errors.Report === false) { return internals.unmatched(failures, error); } // Internal object or array error if (report.state.path.length !== state.path.length) { complex.push({ type: schema.type, report }); continue; } // Valids if (report.code === 'any.only') { for (const valid of report.local.valids) { valids.add(valid); } continue; } // Base type const [type, code] = report.code.split('.'); if (code !== 'base') { complex.push({ type: schema.type, report }); continue; } valids.add(type); } // All errors are base types or valids if (!complex.length) { return { errors: error('alternatives.types', { types: [...valids] }) }; } // Single complex error if (complex.length === 1) { return { errors: complex[0].report }; } return internals.unmatched(failures, error); }; internals.unmatched = function (failures, error) { const errors = []; for (const failure of failures) { errors.push(...failure.reports); } return { errors: error('alternatives.match', Errors.details(errors, { override: false })) }; }; return alternatives; } var array; var hasRequiredArray; function requireArray () { if (hasRequiredArray) return array; hasRequiredArray = 1; const Assert = assert$4; const DeepEqual = deepEqual; const Reach = reach; const Any = requireAny(); const Common = requireCommon(); const Compile = requireCompile(); const internals = {}; array = Any.extend({ type: 'array', flags: { single: { default: false }, sparse: { default: false } }, terms: { items: { init: [], manifest: 'schema' }, ordered: { init: [], manifest: 'schema' }, _exclusions: { init: [] }, _inclusions: { init: [] }, _requireds: { init: [] } }, coerce: { from: 'object', method(value, { schema, state, prefs }) { if (!Array.isArray(value)) { return; } const sort = schema.$_getRule('sort'); if (!sort) { return; } return internals.sort(schema, value, sort.args.options, state, prefs); } }, validate(value, { schema, error }) { if (!Array.isArray(value)) { if (schema._flags.single) { const single = [value]; single[Common.symbols.arraySingle] = true; return { value: single }; } return { errors: error('array.base') }; } if (!schema.$_getRule('items') && !schema.$_terms.externals) { return; } return { value: value.slice() }; // Clone the array so that we don't modify the original }, rules: { has: { method(schema) { schema = this.$_compile(schema, { appendPath: true }); const obj = this.$_addRule({ name: 'has', args: { schema } }); obj.$_mutateRegister(schema); return obj; }, validate(value, { state, prefs, error }, { schema: has }) { const ancestors = [value, ...state.ancestors]; for (let i = 0; i < value.length; ++i) { const localState = state.localize([...state.path, i], ancestors, has); if (has.$_match(value[i], localState, prefs)) { return value; } } const patternLabel = has._flags.label; if (patternLabel) { return error('array.hasKnown', { patternLabel }); } return error('array.hasUnknown', null); }, multi: true }, items: { method(...schemas) { Common.verifyFlat(schemas, 'items'); const obj = this.$_addRule('items'); for (let i = 0; i < schemas.length; ++i) { const type = Common.tryWithPath(() => this.$_compile(schemas[i]), i, { append: true }); obj.$_terms.items.push(type); } return obj.$_mutateRebuild(); }, validate(value, { schema, error, state, prefs, errorsArray }) { const requireds = schema.$_terms._requireds.slice(); const ordereds = schema.$_terms.ordered.slice(); const inclusions = [...schema.$_terms._inclusions, ...requireds]; const wasArray = !value[Common.symbols.arraySingle]; delete value[Common.symbols.arraySingle]; const errors = errorsArray(); let il = value.length; for (let i = 0; i < il; ++i) { const item = value[i]; let errored = false; let isValid = false; const key = wasArray ? i : new Number(i); // eslint-disable-line no-new-wrappers const path = [...state.path, key]; // Sparse if (!schema._flags.sparse && item === undefined) { errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path))); if (prefs.abortEarly) { return errors; } ordereds.shift(); continue; } // Exclusions const ancestors = [value, ...state.ancestors]; for (const exclusion of schema.$_terms._exclusions) { if (!exclusion.$_match(item, state.localize(path, ancestors, exclusion), prefs, { presence: 'ignore' })) { continue; } errors.push(error('array.excludes', { pos: i, value: item }, state.localize(path))); if (prefs.abortEarly) { return errors; } errored = true; ordereds.shift(); break; } if (errored) { continue; } // Ordered if (schema.$_terms.ordered.length) { if (ordereds.length) { const ordered = ordereds.shift(); const res = ordered.$_validate(item, state.localize(path, ancestors, ordered), prefs); if (!res.errors) { if (ordered._flags.result === 'strip') { internals.fastSplice(value, i); --i; --il; } else if (!schema._flags.sparse && res.value === undefined) { errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path))); if (prefs.abortEarly) { return errors; } continue; } else { value[i] = res.value; } } else { errors.push(...res.errors); if (prefs.abortEarly) { return errors; } } continue; } else if (!schema.$_terms.items.length) { errors.push(error('array.orderedLength', { pos: i, limit: schema.$_terms.ordered.length })); if (prefs.abortEarly) { return errors; } break; // No reason to continue since there are no other rules to validate other than array.orderedLength } } // Requireds const requiredChecks = []; let jl = requireds.length; for (let j = 0; j < jl; ++j) { const localState = state.localize(path, ancestors, requireds[j]); localState.snapshot(); const res = requireds[j].$_validate(item, localState, prefs); requiredChecks[j] = res; if (!res.errors) { localState.commit(); value[i] = res.value; isValid = true; internals.fastSplice(requireds, j); --j; --jl; if (!schema._flags.sparse && res.value === undefined) { errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path))); if (prefs.abortEarly) { return errors; } } break; } localState.restore(); } if (isValid) { continue; } // Inclusions const stripUnknown = prefs.stripUnknown && !!prefs.stripUnknown.arrays || false; jl = inclusions.length; for (const inclusion of inclusions) { // Avoid re-running requireds that already didn't match in the previous loop let res; const previousCheck = requireds.indexOf(inclusion); if (previousCheck !== -1) { res = requiredChecks[previousCheck]; } else { const localState = state.localize(path, ancestors, inclusion); localState.snapshot(); res = inclusion.$_validate(item, localState, prefs); if (!res.errors) { localState.commit(); if (inclusion._flags.result === 'strip') { internals.fastSplice(value, i); --i; --il; } else if (!schema._flags.sparse && res.value === undefined) { errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path))); errored = true; } else { value[i] = res.value; } isValid = true; break; } localState.restore(); } // Return the actual error if only one inclusion defined if (jl === 1) { if (stripUnknown) { internals.fastSplice(value, i); --i; --il; isValid = true; break; } errors.push(...res.errors); if (prefs.abortEarly) { return errors; } errored = true; break; } } if (errored) { continue; } if ((schema.$_terms._inclusions.length || schema.$_terms._requireds.length) && !isValid) { if (stripUnknown) { internals.fastSplice(value, i); --i; --il; continue; } errors.push(error('array.includes', { pos: i, value: item }, state.localize(path))); if (prefs.abortEarly) { return errors; } } } if (requireds.length) { internals.fillMissedErrors(schema, errors, requireds, value, state, prefs); } if (ordereds.length) { internals.fillOrderedErrors(schema, errors, ordereds, value, state, prefs); if (!errors.length) { internals.fillDefault(ordereds, value, state, prefs); } } return errors.length ? errors : value; }, priority: true, manifest: false }, length: { method(limit) { return this.$_addRule({ name: 'length', args: { limit }, operator: '=' }); }, validate(value, helpers, { limit }, { name, operator, args }) { if (Common.compare(value.length, limit, operator)) { return value; } return helpers.error('array.' + name, { limit: args.limit, value }); }, args: [ { name: 'limit', ref: true, assert: Common.limit, message: 'must be a positive integer' } ] }, max: { method(limit) { return this.$_addRule({ name: 'max', method: 'length', args: { limit }, operator: '<=' }); } }, min: { method(limit) { return this.$_addRule({ name: 'min', method: 'length', args: { limit }, operator: '>=' }); } }, ordered: { method(...schemas) { Common.verifyFlat(schemas, 'ordered'); const obj = this.$_addRule('items'); for (let i = 0; i < schemas.length; ++i) { const type = Common.tryWithPath(() => this.$_compile(schemas[i]), i, { append: true }); internals.validateSingle(type, obj); obj.$_mutateRegister(type); obj.$_terms.ordered.push(type); } return obj.$_mutateRebuild(); } }, single: { method(enabled) { const value = enabled === undefined ? true : !!enabled; Assert(!value || !this._flags._arrayItems, 'Cannot specify single rule when array has array items'); return this.$_setFlag('single', value); } }, sort: { method(options = {}) { Common.assertOptions(options, ['by', 'order']); const settings = { order: options.order || 'ascending' }; if (options.by) { settings.by = Compile.ref(options.by, { ancestor: 0 }); Assert(!settings.by.ancestor, 'Cannot sort by ancestor'); } return this.$_addRule({ name: 'sort', args: { options: settings } }); }, validate(value, { error, state, prefs, schema }, { options }) { const { value: sorted, errors } = internals.sort(schema, value, options, state, prefs); if (errors) { return errors; } for (let i = 0; i < value.length; ++i) { if (value[i] !== sorted[i]) { return error('array.sort', { order: options.order, by: options.by ? options.by.key : 'value' }); } } return value; }, convert: true }, sparse: { method(enabled) { const value = enabled === undefined ? true : !!enabled; if (this._flags.sparse === value) { return this; } const obj = value ? this.clone() : this.$_addRule('items'); return obj.$_setFlag('sparse', value, { clone: false }); } }, unique: { method(comparator, options = {}) { Assert(!comparator || typeof comparator === 'function' || typeof comparator === 'string', 'comparator must be a function or a string'); Common.assertOptions(options, ['ignoreUndefined', 'separator']); const rule = { name: 'unique', args: { options, comparator } }; if (comparator) { if (typeof comparator === 'string') { const separator = Common.default(options.separator, '.'); rule.path = separator ? comparator.split(separator) : [comparator]; } else { rule.comparator = comparator; } } return this.$_addRule(rule); }, validate(value, { state, error, schema }, { comparator: raw, options }, { comparator, path }) { const found = { string: Object.create(null), number: Object.create(null), undefined: Object.create(null), boolean: Object.create(null), bigint: Object.create(null), object: new Map(), function: new Map(), custom: new Map() }; const compare = comparator || DeepEqual; const ignoreUndefined = options.ignoreUndefined; for (let i = 0; i < value.length; ++i) { const item = path ? Reach(value[i], path) : value[i]; const records = comparator ? found.custom : found[typeof item]; Assert(records, 'Failed to find unique map container for type', typeof item); if (records instanceof Map) { const entries = records.entries(); let current; while (!(current = entries.next()).done) { if (compare(current.value[0], item)) { const localState = state.localize([...state.path, i], [value, ...state.ancestors]); const context = { pos: i, value: value[i], dupePos: current.value[1], dupeValue: value[current.value[1]] }; if (path) { context.path = raw; } return error('array.unique', context, localState); } } records.set(item, i); } else { if ((!ignoreUndefined || item !== undefined) && records[item] !== undefined) { const context = { pos: i, value: value[i], dupePos: records[item], dupeValue: value[records[item]] }; if (path) { context.path = raw; } const localState = state.localize([...state.path, i], [value, ...state.ancestors]); return error('array.unique', context, localState); } records[item] = i; } } return value; }, args: ['comparator', 'options'], multi: true } }, cast: { set: { from: Array.isArray, to(value, helpers) { return new Set(value); } } }, rebuild(schema) { schema.$_terms._inclusions = []; schema.$_terms._exclusions = []; schema.$_terms._requireds = []; for (const type of schema.$_terms.items) { internals.validateSingle(type, schema); if (type._flags.presence === 'required') { schema.$_terms._requireds.push(type); } else if (type._flags.presence === 'forbidden') { schema.$_terms._exclusions.push(type); } else { schema.$_terms._inclusions.push(type); } } for (const type of schema.$_terms.ordered) { internals.validateSingle(type, schema); } }, manifest: { build(obj, desc) { if (desc.items) { obj = obj.items(...desc.items); } if (desc.ordered) { obj = obj.ordered(...desc.ordered); } return obj; } }, messages: { 'array.base': '{{#label}} must be an array', 'array.excludes': '{{#label}} contains an excluded value', 'array.hasKnown': '{{#label}} does not contain at least one required match for type {:#patternLabel}', 'array.hasUnknown': '{{#label}} does not contain at least one required match', 'array.includes': '{{#label}} does not match any of the allowed types', 'array.includesRequiredBoth': '{{#label}} does not contain {{#knownMisses}} and {{#unknownMisses}} other required value(s)', 'array.includesRequiredKnowns': '{{#label}} does not contain {{#knownMisses}}', 'array.includesRequiredUnknowns': '{{#label}} does not contain {{#unknownMisses}} required value(s)', 'array.length': '{{#label}} must contain {{#limit}} items', 'array.max': '{{#label}} must contain less than or equal to {{#limit}} items', 'array.min': '{{#label}} must contain at least {{#limit}} items', 'array.orderedLength': '{{#label}} must contain at most {{#limit}} items', 'array.sort': '{{#label}} must be sorted in {#order} order by {{#by}}', 'array.sort.mismatching': '{{#label}} cannot be sorted due to mismatching types', 'array.sort.unsupported': '{{#label}} cannot be sorted due to unsupported type {#type}', 'array.sparse': '{{#label}} must not be a sparse array item', 'array.unique': '{{#label}} contains a duplicate value' } }); // Helpers internals.fillMissedErrors = function (schema, errors, requireds, value, state, prefs) { const knownMisses = []; let unknownMisses = 0; for (const required of requireds) { const label = required._flags.label; if (label) { knownMisses.push(label); } else { ++unknownMisses; } } if (knownMisses.length) { if (unknownMisses) { errors.push(schema.$_createError('array.includesRequiredBoth', value, { knownMisses, unknownMisses }, state, prefs)); } else { errors.push(schema.$_createError('array.includesRequiredKnowns', value, { knownMisses }, state, prefs)); } } else { errors.push(schema.$_createError('array.includesRequiredUnknowns', value, { unknownMisses }, state, prefs)); } }; internals.fillOrderedErrors = function (schema, errors, ordereds, value, state, prefs) { const requiredOrdereds = []; for (const ordered of ordereds) { if (ordered._flags.presence === 'required') { requiredOrdereds.push(ordered); } } if (requiredOrdereds.length) { internals.fillMissedErrors(schema, errors, requiredOrdereds, value, state, prefs); } }; internals.fillDefault = function (ordereds, value, state, prefs) { const overrides = []; let trailingUndefined = true; for (let i = ordereds.length - 1; i >= 0; --i) { const ordered = ordereds[i]; const ancestors = [value, ...state.ancestors]; const override = ordered.$_validate(undefined, state.localize(state.path, ancestors, ordered), prefs).value; if (trailingUndefined) { if (override === undefined) { continue; } trailingUndefined = false; } overrides.unshift(override); } if (overrides.length) { value.push(...overrides); } }; internals.fastSplice = function (arr, i) { let pos = i; while (pos < arr.length) { arr[pos++] = arr[pos]; } --arr.length; }; internals.validateSingle = function (type, obj) { if (type.type === 'array' || type._flags._arrayItems) { Assert(!obj._flags.single, 'Cannot specify array item with single rule enabled'); obj.$_setFlag('_arrayItems', true, { clone: false }); } }; internals.sort = function (schema, value, settings, state, prefs) { const order = settings.order === 'ascending' ? 1 : -1; const aFirst = -1 * order; const bFirst = order; const sort = (a, b) => { let compare = internals.compare(a, b, aFirst, bFirst); if (compare !== null) { return compare; } if (settings.by) { a = settings.by.resolve(a, state, prefs); b = settings.by.resolve(b, state, prefs); } compare = internals.compare(a, b, aFirst, bFirst); if (compare !== null) { return compare; } const type = typeof a; if (type !== typeof b) { throw schema.$_createError('array.sort.mismatching', value, null, state, prefs); } if (type !== 'number' && type !== 'string') { throw schema.$_createError('array.sort.unsupported', value, { type }, state, prefs); } if (type === 'number') { return (a - b) * order; } return a < b ? aFirst : bFirst; }; try { return { value: value.slice().sort(sort) }; } catch (err) { return { errors: err }; } }; internals.compare = function (a, b, aFirst, bFirst) { if (a === b) { return 0; } if (a === undefined) { return 1; // Always last regardless of sort order } if (b === undefined) { return -1; // Always last regardless of sort order } if (a === null) { return bFirst; } if (b === null) { return aFirst; } return null; }; return array; } var boolean; var hasRequiredBoolean; function requireBoolean () { if (hasRequiredBoolean) return boolean; hasRequiredBoolean = 1; const Assert = assert$4; const Any = requireAny(); const Common = requireCommon(); const Values = requireValues(); const internals = {}; internals.isBool = function (value) { return typeof value === 'boolean'; }; boolean = Any.extend({ type: 'boolean', flags: { sensitive: { default: false } }, terms: { falsy: { init: null, manifest: 'values' }, truthy: { init: null, manifest: 'values' } }, coerce(value, { schema }) { if (typeof value === 'boolean') { return; } if (typeof value === 'string') { const normalized = schema._flags.sensitive ? value : value.toLowerCase(); value = normalized === 'true' ? true : (normalized === 'false' ? false : value); } if (typeof value !== 'boolean') { value = schema.$_terms.truthy && schema.$_terms.truthy.has(value, null, null, !schema._flags.sensitive) || (schema.$_terms.falsy && schema.$_terms.falsy.has(value, null, null, !schema._flags.sensitive) ? false : value); } return { value }; }, validate(value, { error }) { if (typeof value !== 'boolean') { return { value, errors: error('boolean.base') }; } }, rules: { truthy: { method(...values) { Common.verifyFlat(values, 'truthy'); const obj = this.clone(); obj.$_terms.truthy = obj.$_terms.truthy || new Values(); for (let i = 0; i < values.length; ++i) { const value = values[i]; Assert(value !== undefined, 'Cannot call truthy with undefined'); obj.$_terms.truthy.add(value); } return obj; } }, falsy: { method(...values) { Common.verifyFlat(values, 'falsy'); const obj = this.clone(); obj.$_terms.falsy = obj.$_terms.falsy || new Values(); for (let i = 0; i < values.length; ++i) { const value = values[i]; Assert(value !== undefined, 'Cannot call falsy with undefined'); obj.$_terms.falsy.add(value); } return obj; } }, sensitive: { method(enabled = true) { return this.$_setFlag('sensitive', enabled); } } }, cast: { number: { from: internals.isBool, to(value, helpers) { return value ? 1 : 0; } }, string: { from: internals.isBool, to(value, helpers) { return value ? 'true' : 'false'; } } }, manifest: { build(obj, desc) { if (desc.truthy) { obj = obj.truthy(...desc.truthy); } if (desc.falsy) { obj = obj.falsy(...desc.falsy); } return obj; } }, messages: { 'boolean.base': '{{#label}} must be a boolean' } }); return boolean; } var date; var hasRequiredDate; function requireDate () { if (hasRequiredDate) return date; hasRequiredDate = 1; const Assert = assert$4; const Any = requireAny(); const Common = requireCommon(); const Template = requireTemplate(); const internals = {}; internals.isDate = function (value) { return value instanceof Date; }; date = Any.extend({ type: 'date', coerce: { from: ['number', 'string'], method(value, { schema }) { return { value: internals.parse(value, schema._flags.format) || value }; } }, validate(value, { schema, error, prefs }) { if (value instanceof Date && !isNaN(value.getTime())) { return; } const format = schema._flags.format; if (!prefs.convert || !format || typeof value !== 'string') { return { value, errors: error('date.base') }; } return { value, errors: error('date.format', { format }) }; }, rules: { compare: { method: false, validate(value, helpers, { date }, { name, operator, args }) { const to = date === 'now' ? Date.now() : date.getTime(); if (Common.compare(value.getTime(), to, operator)) { return value; } return helpers.error('date.' + name, { limit: args.date, value }); }, args: [ { name: 'date', ref: true, normalize: (date) => { return date === 'now' ? date : internals.parse(date); }, assert: (date) => date !== null, message: 'must have a valid date format' } ] }, format: { method(format) { Assert(['iso', 'javascript', 'unix'].includes(format), 'Unknown date format', format); return this.$_setFlag('format', format); } }, greater: { method(date) { return this.$_addRule({ name: 'greater', method: 'compare', args: { date }, operator: '>' }); } }, iso: { method() { return this.format('iso'); } }, less: { method(date) { return this.$_addRule({ name: 'less', method: 'compare', args: { date }, operator: '<' }); } }, max: { method(date) { return this.$_addRule({ name: 'max', method: 'compare', args: { date }, operator: '<=' }); } }, min: { method(date) { return this.$_addRule({ name: 'min', method: 'compare', args: { date }, operator: '>=' }); } }, timestamp: { method(type = 'javascript') { Assert(['javascript', 'unix'].includes(type), '"type" must be one of "javascript, unix"'); return this.format(type); } } }, cast: { number: { from: internals.isDate, to(value, helpers) { return value.getTime(); } }, string: { from: internals.isDate, to(value, { prefs }) { return Template.date(value, prefs); } } }, messages: { 'date.base': '{{#label}} must be a valid date', 'date.format': '{{#label}} must be in {msg("date.format." + #format) || #format} format', 'date.greater': '{{#label}} must be greater than {{:#limit}}', 'date.less': '{{#label}} must be less than {{:#limit}}', 'date.max': '{{#label}} must be less than or equal to {{:#limit}}', 'date.min': '{{#label}} must be greater than or equal to {{:#limit}}', // Messages used in date.format 'date.format.iso': 'ISO 8601 date', 'date.format.javascript': 'timestamp or number of milliseconds', 'date.format.unix': 'timestamp or number of seconds' } }); // Helpers internals.parse = function (value, format) { if (value instanceof Date) { return value; } if (typeof value !== 'string' && (isNaN(value) || !isFinite(value))) { return null; } if (/^\s*$/.test(value)) { return null; } // ISO if (format === 'iso') { if (!Common.isIsoDate(value)) { return null; } return internals.date(value.toString()); } // Normalize number string const original = value; if (typeof value === 'string' && /^[+-]?\d+(\.\d+)?$/.test(value)) { value = parseFloat(value); } // Timestamp if (format) { if (format === 'javascript') { return internals.date(1 * value); // Casting to number } if (format === 'unix') { return internals.date(1000 * value); } if (typeof original === 'string') { return null; } } // Plain return internals.date(value); }; internals.date = function (value) { const date = new Date(value); if (!isNaN(date.getTime())) { return date; } return null; }; return date; } var keys$2; var hasRequiredKeys; function requireKeys () { if (hasRequiredKeys) return keys$2; hasRequiredKeys = 1; const ApplyToDefaults = applyToDefaults; const Assert = assert$4; const Clone = clone$6; const Topo = lib$6; const Any = requireAny(); const Common = requireCommon(); const Compile = requireCompile(); const Errors = requireErrors(); const Ref = requireRef(); const Template = requireTemplate(); const internals = { renameDefaults: { alias: false, // Keep old value in place multiple: false, // Allow renaming multiple keys into the same target override: false // Overrides an existing key } }; keys$2 = Any.extend({ type: '_keys', properties: { typeof: 'object' }, flags: { unknown: { default: false } }, terms: { dependencies: { init: null }, keys: { init: null, manifest: { mapped: { from: 'schema', to: 'key' } } }, patterns: { init: null }, renames: { init: null } }, args(schema, keys) { return schema.keys(keys); }, validate(value, { schema, error, state, prefs }) { if (!value || typeof value !== schema.$_property('typeof') || Array.isArray(value)) { return { value, errors: error('object.base', { type: schema.$_property('typeof') }) }; } // Skip if there are no other rules to test if (!schema.$_terms.renames && !schema.$_terms.dependencies && !schema.$_terms.keys && // null allows any keys !schema.$_terms.patterns && !schema.$_terms.externals) { return; } // Shallow clone value value = internals.clone(value, prefs); const errors = []; // Rename keys if (schema.$_terms.renames && !internals.rename(schema, value, state, prefs, errors)) { return { value, errors }; } // Anything allowed if (!schema.$_terms.keys && // null allows any keys !schema.$_terms.patterns && !schema.$_terms.dependencies) { return { value, errors }; } // Defined keys const unprocessed = new Set(Object.keys(value)); if (schema.$_terms.keys) { const ancestors = [value, ...state.ancestors]; for (const child of schema.$_terms.keys) { const key = child.key; const item = value[key]; unprocessed.delete(key); const localState = state.localize([...state.path, key], ancestors, child); const result = child.schema.$_validate(item, localState, prefs); if (result.errors) { if (prefs.abortEarly) { return { value, errors: result.errors }; } if (result.value !== undefined) { value[key] = result.value; } errors.push(...result.errors); } else if (child.schema._flags.result === 'strip' || result.value === undefined && item !== undefined) { delete value[key]; } else if (result.value !== undefined) { value[key] = result.value; } } } // Unknown keys if (unprocessed.size || schema._flags._hasPatternMatch) { const early = internals.unknown(schema, value, unprocessed, errors, state, prefs); if (early) { return early; } } // Validate dependencies if (schema.$_terms.dependencies) { for (const dep of schema.$_terms.dependencies) { if ( dep.key !== null && internals.isPresent(dep.options)(dep.key.resolve(value, state, prefs, null, { shadow: false })) === false ) { continue; } const failed = internals.dependencies[dep.rel](schema, dep, value, state, prefs); if (failed) { const report = schema.$_createError(failed.code, value, failed.context, state, prefs); if (prefs.abortEarly) { return { value, errors: report }; } errors.push(report); } } } return { value, errors }; }, rules: { and: { method(...peers /*, [options] */) { Common.verifyFlat(peers, 'and'); return internals.dependency(this, 'and', null, peers); } }, append: { method(schema) { if (schema === null || schema === undefined || Object.keys(schema).length === 0) { return this; } return this.keys(schema); } }, assert: { method(subject, schema, message) { if (!Template.isTemplate(subject)) { subject = Compile.ref(subject); } Assert(message === undefined || typeof message === 'string', 'Message must be a string'); schema = this.$_compile(schema, { appendPath: true }); const obj = this.$_addRule({ name: 'assert', args: { subject, schema, message } }); obj.$_mutateRegister(subject); obj.$_mutateRegister(schema); return obj; }, validate(value, { error, prefs, state }, { subject, schema, message }) { const about = subject.resolve(value, state, prefs); const path = Ref.isRef(subject) ? subject.absolute(state) : []; if (schema.$_match(about, state.localize(path, [value, ...state.ancestors], schema), prefs)) { return value; } return error('object.assert', { subject, message }); }, args: ['subject', 'schema', 'message'], multi: true }, instance: { method(constructor, name) { Assert(typeof constructor === 'function', 'constructor must be a function'); name = name || constructor.name; return this.$_addRule({ name: 'instance', args: { constructor, name } }); }, validate(value, helpers, { constructor, name }) { if (value instanceof constructor) { return value; } return helpers.error('object.instance', { type: name, value }); }, args: ['constructor', 'name'] }, keys: { method(schema) { Assert(schema === undefined || typeof schema === 'object', 'Object schema must be a valid object'); Assert(!Common.isSchema(schema), 'Object schema cannot be a joi schema'); const obj = this.clone(); if (!schema) { // Allow all obj.$_terms.keys = null; } else if (!Object.keys(schema).length) { // Allow none obj.$_terms.keys = new internals.Keys(); } else { obj.$_terms.keys = obj.$_terms.keys ? obj.$_terms.keys.filter((child) => !schema.hasOwnProperty(child.key)) : new internals.Keys(); for (const key in schema) { Common.tryWithPath(() => obj.$_terms.keys.push({ key, schema: this.$_compile(schema[key]) }), key); } } return obj.$_mutateRebuild(); } }, length: { method(limit) { return this.$_addRule({ name: 'length', args: { limit }, operator: '=' }); }, validate(value, helpers, { limit }, { name, operator, args }) { if (Common.compare(Object.keys(value).length, limit, operator)) { return value; } return helpers.error('object.' + name, { limit: args.limit, value }); }, args: [ { name: 'limit', ref: true, assert: Common.limit, message: 'must be a positive integer' } ] }, max: { method(limit) { return this.$_addRule({ name: 'max', method: 'length', args: { limit }, operator: '<=' }); } }, min: { method(limit) { return this.$_addRule({ name: 'min', method: 'length', args: { limit }, operator: '>=' }); } }, nand: { method(...peers /*, [options] */) { Common.verifyFlat(peers, 'nand'); return internals.dependency(this, 'nand', null, peers); } }, or: { method(...peers /*, [options] */) { Common.verifyFlat(peers, 'or'); return internals.dependency(this, 'or', null, peers); } }, oxor: { method(...peers /*, [options] */) { return internals.dependency(this, 'oxor', null, peers); } }, pattern: { method(pattern, schema, options = {}) { const isRegExp = pattern instanceof RegExp; if (!isRegExp) { pattern = this.$_compile(pattern, { appendPath: true }); } Assert(schema !== undefined, 'Invalid rule'); Common.assertOptions(options, ['fallthrough', 'matches']); if (isRegExp) { Assert(!pattern.flags.includes('g') && !pattern.flags.includes('y'), 'pattern should not use global or sticky mode'); } schema = this.$_compile(schema, { appendPath: true }); const obj = this.clone(); obj.$_terms.patterns = obj.$_terms.patterns || []; const config = { [isRegExp ? 'regex' : 'schema']: pattern, rule: schema }; if (options.matches) { config.matches = this.$_compile(options.matches); if (config.matches.type !== 'array') { config.matches = config.matches.$_root.array().items(config.matches); } obj.$_mutateRegister(config.matches); obj.$_setFlag('_hasPatternMatch', true, { clone: false }); } if (options.fallthrough) { config.fallthrough = true; } obj.$_terms.patterns.push(config); obj.$_mutateRegister(schema); return obj; } }, ref: { method() { return this.$_addRule('ref'); }, validate(value, helpers) { if (Ref.isRef(value)) { return value; } return helpers.error('object.refType', { value }); } }, regex: { method() { return this.$_addRule('regex'); }, validate(value, helpers) { if (value instanceof RegExp) { return value; } return helpers.error('object.regex', { value }); } }, rename: { method(from, to, options = {}) { Assert(typeof from === 'string' || from instanceof RegExp, 'Rename missing the from argument'); Assert(typeof to === 'string' || to instanceof Template, 'Invalid rename to argument'); Assert(to !== from, 'Cannot rename key to same name:', from); Common.assertOptions(options, ['alias', 'ignoreUndefined', 'override', 'multiple']); const obj = this.clone(); obj.$_terms.renames = obj.$_terms.renames || []; for (const rename of obj.$_terms.renames) { Assert(rename.from !== from, 'Cannot rename the same key multiple times'); } if (to instanceof Template) { obj.$_mutateRegister(to); } obj.$_terms.renames.push({ from, to, options: ApplyToDefaults(internals.renameDefaults, options) }); return obj; } }, schema: { method(type = 'any') { return this.$_addRule({ name: 'schema', args: { type } }); }, validate(value, helpers, { type }) { if (Common.isSchema(value) && (type === 'any' || value.type === type)) { return value; } return helpers.error('object.schema', { type }); } }, unknown: { method(allow) { return this.$_setFlag('unknown', allow !== false); } }, with: { method(key, peers, options = {}) { return internals.dependency(this, 'with', key, peers, options); } }, without: { method(key, peers, options = {}) { return internals.dependency(this, 'without', key, peers, options); } }, xor: { method(...peers /*, [options] */) { Common.verifyFlat(peers, 'xor'); return internals.dependency(this, 'xor', null, peers); } } }, overrides: { default(value, options) { if (value === undefined) { value = Common.symbols.deepDefault; } return this.$_parent('default', value, options); } }, rebuild(schema) { if (schema.$_terms.keys) { const topo = new Topo.Sorter(); for (const child of schema.$_terms.keys) { Common.tryWithPath(() => topo.add(child, { after: child.schema.$_rootReferences(), group: child.key }), child.key); } schema.$_terms.keys = new internals.Keys(...topo.nodes); } }, manifest: { build(obj, desc) { if (desc.keys) { obj = obj.keys(desc.keys); } if (desc.dependencies) { for (const { rel, key = null, peers, options } of desc.dependencies) { obj = internals.dependency(obj, rel, key, peers, options); } } if (desc.patterns) { for (const { regex, schema, rule, fallthrough, matches } of desc.patterns) { obj = obj.pattern(regex || schema, rule, { fallthrough, matches }); } } if (desc.renames) { for (const { from, to, options } of desc.renames) { obj = obj.rename(from, to, options); } } return obj; } }, messages: { 'object.and': '{{#label}} contains {{#presentWithLabels}} without its required peers {{#missingWithLabels}}', 'object.assert': '{{#label}} is invalid because {if(#subject.key, `"` + #subject.key + `" failed to ` + (#message || "pass the assertion test"), #message || "the assertion failed")}', 'object.base': '{{#label}} must be of type {{#type}}', 'object.instance': '{{#label}} must be an instance of {{:#type}}', 'object.length': '{{#label}} must have {{#limit}} key{if(#limit == 1, "", "s")}', 'object.max': '{{#label}} must have less than or equal to {{#limit}} key{if(#limit == 1, "", "s")}', 'object.min': '{{#label}} must have at least {{#limit}} key{if(#limit == 1, "", "s")}', 'object.missing': '{{#label}} must contain at least one of {{#peersWithLabels}}', 'object.nand': '{{:#mainWithLabel}} must not exist simultaneously with {{#peersWithLabels}}', 'object.oxor': '{{#label}} contains a conflict between optional exclusive peers {{#peersWithLabels}}', 'object.pattern.match': '{{#label}} keys failed to match pattern requirements', 'object.refType': '{{#label}} must be a Joi reference', 'object.regex': '{{#label}} must be a RegExp object', 'object.rename.multiple': '{{#label}} cannot rename {{:#from}} because multiple renames are disabled and another key was already renamed to {{:#to}}', 'object.rename.override': '{{#label}} cannot rename {{:#from}} because override is disabled and target {{:#to}} exists', 'object.schema': '{{#label}} must be a Joi schema of {{#type}} type', 'object.unknown': '{{#label}} is not allowed', 'object.with': '{{:#mainWithLabel}} missing required peer {{:#peerWithLabel}}', 'object.without': '{{:#mainWithLabel}} conflict with forbidden peer {{:#peerWithLabel}}', 'object.xor': '{{#label}} contains a conflict between exclusive peers {{#peersWithLabels}}' } }); // Helpers internals.clone = function (value, prefs) { // Object if (typeof value === 'object') { if (prefs.nonEnumerables) { return Clone(value, { shallow: true }); } const clone = Object.create(Object.getPrototypeOf(value)); Object.assign(clone, value); return clone; } // Function const clone = function (...args) { return value.apply(this, args); }; clone.prototype = Clone(value.prototype); Object.defineProperty(clone, 'name', { value: value.name, writable: false }); Object.defineProperty(clone, 'length', { value: value.length, writable: false }); Object.assign(clone, value); return clone; }; internals.dependency = function (schema, rel, key, peers, options) { Assert(key === null || typeof key === 'string', rel, 'key must be a strings'); // Extract options from peers array if (!options) { options = peers.length > 1 && typeof peers[peers.length - 1] === 'object' ? peers.pop() : {}; } Common.assertOptions(options, ['separator', 'isPresent']); peers = [].concat(peers); // Cast peer paths const separator = Common.default(options.separator, '.'); const paths = []; for (const peer of peers) { Assert(typeof peer === 'string', rel, 'peers must be strings'); paths.push(Compile.ref(peer, { separator, ancestor: 0, prefix: false })); } // Cast key if (key !== null) { key = Compile.ref(key, { separator, ancestor: 0, prefix: false }); } // Add rule const obj = schema.clone(); obj.$_terms.dependencies = obj.$_terms.dependencies || []; obj.$_terms.dependencies.push(new internals.Dependency(rel, key, paths, peers, options)); return obj; }; internals.dependencies = { and(schema, dep, value, state, prefs) { const missing = []; const present = []; const count = dep.peers.length; const isPresent = internals.isPresent(dep.options); for (const peer of dep.peers) { if (isPresent(peer.resolve(value, state, prefs, null, { shadow: false })) === false) { missing.push(peer.key); } else { present.push(peer.key); } } if (missing.length !== count && present.length !== count) { return { code: 'object.and', context: { present, presentWithLabels: internals.keysToLabels(schema, present), missing, missingWithLabels: internals.keysToLabels(schema, missing) } }; } }, nand(schema, dep, value, state, prefs) { const present = []; const isPresent = internals.isPresent(dep.options); for (const peer of dep.peers) { if (isPresent(peer.resolve(value, state, prefs, null, { shadow: false }))) { present.push(peer.key); } } if (present.length !== dep.peers.length) { return; } const main = dep.paths[0]; const values = dep.paths.slice(1); return { code: 'object.nand', context: { main, mainWithLabel: internals.keysToLabels(schema, main), peers: values, peersWithLabels: internals.keysToLabels(schema, values) } }; }, or(schema, dep, value, state, prefs) { const isPresent = internals.isPresent(dep.options); for (const peer of dep.peers) { if (isPresent(peer.resolve(value, state, prefs, null, { shadow: false }))) { return; } } return { code: 'object.missing', context: { peers: dep.paths, peersWithLabels: internals.keysToLabels(schema, dep.paths) } }; }, oxor(schema, dep, value, state, prefs) { const present = []; const isPresent = internals.isPresent(dep.options); for (const peer of dep.peers) { if (isPresent(peer.resolve(value, state, prefs, null, { shadow: false }))) { present.push(peer.key); } } if (!present.length || present.length === 1) { return; } const context = { peers: dep.paths, peersWithLabels: internals.keysToLabels(schema, dep.paths) }; context.present = present; context.presentWithLabels = internals.keysToLabels(schema, present); return { code: 'object.oxor', context }; }, with(schema, dep, value, state, prefs) { const isPresent = internals.isPresent(dep.options); for (const peer of dep.peers) { if (isPresent(peer.resolve(value, state, prefs, null, { shadow: false })) === false) { return { code: 'object.with', context: { main: dep.key.key, mainWithLabel: internals.keysToLabels(schema, dep.key.key), peer: peer.key, peerWithLabel: internals.keysToLabels(schema, peer.key) } }; } } }, without(schema, dep, value, state, prefs) { const isPresent = internals.isPresent(dep.options); for (const peer of dep.peers) { if (isPresent(peer.resolve(value, state, prefs, null, { shadow: false }))) { return { code: 'object.without', context: { main: dep.key.key, mainWithLabel: internals.keysToLabels(schema, dep.key.key), peer: peer.key, peerWithLabel: internals.keysToLabels(schema, peer.key) } }; } } }, xor(schema, dep, value, state, prefs) { const present = []; const isPresent = internals.isPresent(dep.options); for (const peer of dep.peers) { if (isPresent(peer.resolve(value, state, prefs, null, { shadow: false }))) { present.push(peer.key); } } if (present.length === 1) { return; } const context = { peers: dep.paths, peersWithLabels: internals.keysToLabels(schema, dep.paths) }; if (present.length === 0) { return { code: 'object.missing', context }; } context.present = present; context.presentWithLabels = internals.keysToLabels(schema, present); return { code: 'object.xor', context }; } }; internals.keysToLabels = function (schema, keys) { if (Array.isArray(keys)) { return keys.map((key) => schema.$_mapLabels(key)); } return schema.$_mapLabels(keys); }; internals.isPresent = function (options) { return typeof options.isPresent === 'function' ? options.isPresent : (resolved) => resolved !== undefined; }; internals.rename = function (schema, value, state, prefs, errors) { const renamed = {}; for (const rename of schema.$_terms.renames) { const matches = []; const pattern = typeof rename.from !== 'string'; if (!pattern) { if (Object.prototype.hasOwnProperty.call(value, rename.from) && (value[rename.from] !== undefined || !rename.options.ignoreUndefined)) { matches.push(rename); } } else { for (const from in value) { if (value[from] === undefined && rename.options.ignoreUndefined) { continue; } if (from === rename.to) { continue; } const match = rename.from.exec(from); if (!match) { continue; } matches.push({ from, to: rename.to, match }); } } for (const match of matches) { const from = match.from; let to = match.to; if (to instanceof Template) { to = to.render(value, state, prefs, match.match); } if (from === to) { continue; } if (!rename.options.multiple && renamed[to]) { errors.push(schema.$_createError('object.rename.multiple', value, { from, to, pattern }, state, prefs)); if (prefs.abortEarly) { return false; } } if (Object.prototype.hasOwnProperty.call(value, to) && !rename.options.override && !renamed[to]) { errors.push(schema.$_createError('object.rename.override', value, { from, to, pattern }, state, prefs)); if (prefs.abortEarly) { return false; } } if (value[from] === undefined) { delete value[to]; } else { value[to] = value[from]; } renamed[to] = true; if (!rename.options.alias) { delete value[from]; } } } return true; }; internals.unknown = function (schema, value, unprocessed, errors, state, prefs) { if (schema.$_terms.patterns) { let hasMatches = false; const matches = schema.$_terms.patterns.map((pattern) => { if (pattern.matches) { hasMatches = true; return []; } }); const ancestors = [value, ...state.ancestors]; for (const key of unprocessed) { const item = value[key]; const path = [...state.path, key]; for (let i = 0; i < schema.$_terms.patterns.length; ++i) { const pattern = schema.$_terms.patterns[i]; if (pattern.regex) { const match = pattern.regex.test(key); state.mainstay.tracer.debug(state, 'rule', `pattern.${i}`, match ? 'pass' : 'error'); if (!match) { continue; } } else { if (!pattern.schema.$_match(key, state.nest(pattern.schema, `pattern.${i}`), prefs)) { continue; } } unprocessed.delete(key); const localState = state.localize(path, ancestors, { schema: pattern.rule, key }); const result = pattern.rule.$_validate(item, localState, prefs); if (result.errors) { if (prefs.abortEarly) { return { value, errors: result.errors }; } errors.push(...result.errors); } if (pattern.matches) { matches[i].push(key); } value[key] = result.value; if (!pattern.fallthrough) { break; } } } // Validate pattern matches rules if (hasMatches) { for (let i = 0; i < matches.length; ++i) { const match = matches[i]; if (!match) { continue; } const stpm = schema.$_terms.patterns[i].matches; const localState = state.localize(state.path, ancestors, stpm); const result = stpm.$_validate(match, localState, prefs); if (result.errors) { const details = Errors.details(result.errors, { override: false }); details.matches = match; const report = schema.$_createError('object.pattern.match', value, details, state, prefs); if (prefs.abortEarly) { return { value, errors: report }; } errors.push(report); } } } } if (!unprocessed.size || !schema.$_terms.keys && !schema.$_terms.patterns) { // If no keys or patterns specified, unknown keys allowed return; } if (prefs.stripUnknown && !schema._flags.unknown || prefs.skipFunctions) { const stripUnknown = prefs.stripUnknown ? (prefs.stripUnknown === true ? true : !!prefs.stripUnknown.objects) : false; for (const key of unprocessed) { if (stripUnknown) { delete value[key]; unprocessed.delete(key); } else if (typeof value[key] === 'function') { unprocessed.delete(key); } } } const forbidUnknown = !Common.default(schema._flags.unknown, prefs.allowUnknown); if (forbidUnknown) { for (const unprocessedKey of unprocessed) { const localState = state.localize([...state.path, unprocessedKey], []); const report = schema.$_createError('object.unknown', value[unprocessedKey], { child: unprocessedKey }, localState, prefs, { flags: false }); if (prefs.abortEarly) { return { value, errors: report }; } errors.push(report); } } }; internals.Dependency = class { constructor(rel, key, peers, paths, options) { this.rel = rel; this.key = key; this.peers = peers; this.paths = paths; this.options = options; } describe() { const desc = { rel: this.rel, peers: this.paths }; if (this.key !== null) { desc.key = this.key.key; } if (this.peers[0].separator !== '.') { desc.options = { ...desc.options, separator: this.peers[0].separator }; } if (this.options.isPresent) { desc.options = { ...desc.options, isPresent: this.options.isPresent }; } return desc; } }; internals.Keys = class extends Array { concat(source) { const result = this.slice(); const keys = new Map(); for (let i = 0; i < result.length; ++i) { keys.set(result[i].key, i); } for (const item of source) { const key = item.key; const pos = keys.get(key); if (pos !== undefined) { result[pos] = { key, schema: result[pos].schema.concat(item.schema) }; } else { result.push(item); } } return result; } }; return keys$2; } var _function; var hasRequired_function; function require_function () { if (hasRequired_function) return _function; hasRequired_function = 1; const Assert = assert$4; const Keys = requireKeys(); _function = Keys.extend({ type: 'function', properties: { typeof: 'function' }, rules: { arity: { method(n) { Assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer'); return this.$_addRule({ name: 'arity', args: { n } }); }, validate(value, helpers, { n }) { if (value.length === n) { return value; } return helpers.error('function.arity', { n }); } }, class: { method() { return this.$_addRule('class'); }, validate(value, helpers) { if ((/^\s*class\s/).test(value.toString())) { return value; } return helpers.error('function.class', { value }); } }, minArity: { method(n) { Assert(Number.isSafeInteger(n) && n > 0, 'n must be a strict positive integer'); return this.$_addRule({ name: 'minArity', args: { n } }); }, validate(value, helpers, { n }) { if (value.length >= n) { return value; } return helpers.error('function.minArity', { n }); } }, maxArity: { method(n) { Assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer'); return this.$_addRule({ name: 'maxArity', args: { n } }); }, validate(value, helpers, { n }) { if (value.length <= n) { return value; } return helpers.error('function.maxArity', { n }); } } }, messages: { 'function.arity': '{{#label}} must have an arity of {{#n}}', 'function.class': '{{#label}} must be a class', 'function.maxArity': '{{#label}} must have an arity lesser or equal to {{#n}}', 'function.minArity': '{{#label}} must have an arity greater or equal to {{#n}}' } }); return _function; } var link$1; var hasRequiredLink; function requireLink () { if (hasRequiredLink) return link$1; hasRequiredLink = 1; const Assert = assert$4; const Any = requireAny(); const Common = requireCommon(); const Compile = requireCompile(); const Errors = requireErrors(); const internals = {}; link$1 = Any.extend({ type: 'link', properties: { schemaChain: true }, terms: { link: { init: null, manifest: 'single', register: false } }, args(schema, ref) { return schema.ref(ref); }, validate(value, { schema, state, prefs }) { Assert(schema.$_terms.link, 'Uninitialized link schema'); const linked = internals.generate(schema, value, state, prefs); const ref = schema.$_terms.link[0].ref; return linked.$_validate(value, state.nest(linked, `link:${ref.display}:${linked.type}`), prefs); }, generate(schema, value, state, prefs) { return internals.generate(schema, value, state, prefs); }, rules: { ref: { method(ref) { Assert(!this.$_terms.link, 'Cannot reinitialize schema'); ref = Compile.ref(ref); Assert(ref.type === 'value' || ref.type === 'local', 'Invalid reference type:', ref.type); Assert(ref.type === 'local' || ref.ancestor === 'root' || ref.ancestor > 0, 'Link cannot reference itself'); const obj = this.clone(); obj.$_terms.link = [{ ref }]; return obj; } }, relative: { method(enabled = true) { return this.$_setFlag('relative', enabled); } } }, overrides: { concat(source) { Assert(this.$_terms.link, 'Uninitialized link schema'); Assert(Common.isSchema(source), 'Invalid schema object'); Assert(source.type !== 'link', 'Cannot merge type link with another link'); const obj = this.clone(); if (!obj.$_terms.whens) { obj.$_terms.whens = []; } obj.$_terms.whens.push({ concat: source }); return obj.$_mutateRebuild(); } }, manifest: { build(obj, desc) { Assert(desc.link, 'Invalid link description missing link'); return obj.ref(desc.link); } } }); // Helpers internals.generate = function (schema, value, state, prefs) { let linked = state.mainstay.links.get(schema); if (linked) { return linked._generate(value, state, prefs).schema; } const ref = schema.$_terms.link[0].ref; const { perspective, path } = internals.perspective(ref, state); internals.assert(perspective, 'which is outside of schema boundaries', ref, schema, state, prefs); try { linked = path.length ? perspective.$_reach(path) : perspective; } catch (ignoreErr) { internals.assert(false, 'to non-existing schema', ref, schema, state, prefs); } internals.assert(linked.type !== 'link', 'which is another link', ref, schema, state, prefs); if (!schema._flags.relative) { state.mainstay.links.set(schema, linked); } return linked._generate(value, state, prefs).schema; }; internals.perspective = function (ref, state) { if (ref.type === 'local') { for (const { schema, key } of state.schemas) { // From parent to root const id = schema._flags.id || key; if (id === ref.path[0]) { return { perspective: schema, path: ref.path.slice(1) }; } if (schema.$_terms.shared) { for (const shared of schema.$_terms.shared) { if (shared._flags.id === ref.path[0]) { return { perspective: shared, path: ref.path.slice(1) }; } } } } return { perspective: null, path: null }; } if (ref.ancestor === 'root') { return { perspective: state.schemas[state.schemas.length - 1].schema, path: ref.path }; } return { perspective: state.schemas[ref.ancestor] && state.schemas[ref.ancestor].schema, path: ref.path }; }; internals.assert = function (condition, message, ref, schema, state, prefs) { if (condition) { // Manual check to avoid generating error message on success return; } Assert(false, `"${Errors.label(schema._flags, state, prefs)}" contains link reference "${ref.display}" ${message}`); }; return link$1; } var number; var hasRequiredNumber; function requireNumber () { if (hasRequiredNumber) return number; hasRequiredNumber = 1; const Assert = assert$4; const Any = requireAny(); const Common = requireCommon(); const internals = { numberRx: /^\s*[+-]?(?:(?:\d+(?:\.\d*)?)|(?:\.\d+))(?:e([+-]?\d+))?\s*$/i, precisionRx: /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/, exponentialPartRegex: /[eE][+-]?\d+$/, leadingSignAndZerosRegex: /^[+-]?(0*)?/, dotRegex: /\./, trailingZerosRegex: /0+$/, decimalPlaces(value) { const str = value.toString(); const dindex = str.indexOf('.'); const eindex = str.indexOf('e'); return ( (dindex < 0 ? 0 : (eindex < 0 ? str.length : eindex) - dindex - 1) + (eindex < 0 ? 0 : Math.max(0, -parseInt(str.slice(eindex + 1)))) ); } }; number = Any.extend({ type: 'number', flags: { unsafe: { default: false } }, coerce: { from: 'string', method(value, { schema, error }) { const matches = value.match(internals.numberRx); if (!matches) { return; } value = value.trim(); const result = { value: parseFloat(value) }; if (result.value === 0) { result.value = 0; // -0 } if (!schema._flags.unsafe) { if (value.match(/e/i)) { if (internals.extractSignificantDigits(value) !== internals.extractSignificantDigits(String(result.value))) { result.errors = error('number.unsafe'); return result; } } else { const string = result.value.toString(); if (string.match(/e/i)) { return result; } if (string !== internals.normalizeDecimal(value)) { result.errors = error('number.unsafe'); return result; } } } return result; } }, validate(value, { schema, error, prefs }) { if (value === Infinity || value === -Infinity) { return { value, errors: error('number.infinity') }; } if (!Common.isNumber(value)) { return { value, errors: error('number.base') }; } const result = { value }; if (prefs.convert) { const rule = schema.$_getRule('precision'); if (rule) { const precision = Math.pow(10, rule.args.limit); // This is conceptually equivalent to using toFixed but it should be much faster result.value = Math.round(result.value * precision) / precision; } } if (result.value === 0) { result.value = 0; // -0 } if (!schema._flags.unsafe && (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER)) { result.errors = error('number.unsafe'); } return result; }, rules: { compare: { method: false, validate(value, helpers, { limit }, { name, operator, args }) { if (Common.compare(value, limit, operator)) { return value; } return helpers.error('number.' + name, { limit: args.limit, value }); }, args: [ { name: 'limit', ref: true, assert: Common.isNumber, message: 'must be a number' } ] }, greater: { method(limit) { return this.$_addRule({ name: 'greater', method: 'compare', args: { limit }, operator: '>' }); } }, integer: { method() { return this.$_addRule('integer'); }, validate(value, helpers) { if (Math.trunc(value) - value === 0) { return value; } return helpers.error('number.integer'); } }, less: { method(limit) { return this.$_addRule({ name: 'less', method: 'compare', args: { limit }, operator: '<' }); } }, max: { method(limit) { return this.$_addRule({ name: 'max', method: 'compare', args: { limit }, operator: '<=' }); } }, min: { method(limit) { return this.$_addRule({ name: 'min', method: 'compare', args: { limit }, operator: '>=' }); } }, multiple: { method(base) { const baseDecimalPlace = typeof base === 'number' ? internals.decimalPlaces(base) : null; const pfactor = Math.pow(10, baseDecimalPlace); return this.$_addRule({ name: 'multiple', args: { base, baseDecimalPlace, pfactor } }); }, validate(value, helpers, { base, baseDecimalPlace, pfactor }, options) { const valueDecimalPlace = internals.decimalPlaces(value); if (valueDecimalPlace > baseDecimalPlace) { // Value with higher precision than base can never be a multiple return helpers.error('number.multiple', { multiple: options.args.base, value }); } return Math.round(pfactor * value) % Math.round(pfactor * base) === 0 ? value : helpers.error('number.multiple', { multiple: options.args.base, value }); }, args: [ { name: 'base', ref: true, assert: (value) => typeof value === 'number' && isFinite(value) && value > 0, message: 'must be a positive number' }, 'baseDecimalPlace', 'pfactor' ], multi: true }, negative: { method() { return this.sign('negative'); } }, port: { method() { return this.$_addRule('port'); }, validate(value, helpers) { if (Number.isSafeInteger(value) && value >= 0 && value <= 65535) { return value; } return helpers.error('number.port'); } }, positive: { method() { return this.sign('positive'); } }, precision: { method(limit) { Assert(Number.isSafeInteger(limit), 'limit must be an integer'); return this.$_addRule({ name: 'precision', args: { limit } }); }, validate(value, helpers, { limit }) { const places = value.toString().match(internals.precisionRx); const decimals = Math.max((places[1] ? places[1].length : 0) - (places[2] ? parseInt(places[2], 10) : 0), 0); if (decimals <= limit) { return value; } return helpers.error('number.precision', { limit, value }); }, convert: true }, sign: { method(sign) { Assert(['negative', 'positive'].includes(sign), 'Invalid sign', sign); return this.$_addRule({ name: 'sign', args: { sign } }); }, validate(value, helpers, { sign }) { if (sign === 'negative' && value < 0 || sign === 'positive' && value > 0) { return value; } return helpers.error(`number.${sign}`); } }, unsafe: { method(enabled = true) { Assert(typeof enabled === 'boolean', 'enabled must be a boolean'); return this.$_setFlag('unsafe', enabled); } } }, cast: { string: { from: (value) => typeof value === 'number', to(value, helpers) { return value.toString(); } } }, messages: { 'number.base': '{{#label}} must be a number', 'number.greater': '{{#label}} must be greater than {{#limit}}', 'number.infinity': '{{#label}} cannot be infinity', 'number.integer': '{{#label}} must be an integer', 'number.less': '{{#label}} must be less than {{#limit}}', 'number.max': '{{#label}} must be less than or equal to {{#limit}}', 'number.min': '{{#label}} must be greater than or equal to {{#limit}}', 'number.multiple': '{{#label}} must be a multiple of {{#multiple}}', 'number.negative': '{{#label}} must be a negative number', 'number.port': '{{#label}} must be a valid port', 'number.positive': '{{#label}} must be a positive number', 'number.precision': '{{#label}} must have no more than {{#limit}} decimal places', 'number.unsafe': '{{#label}} must be a safe number' } }); // Helpers internals.extractSignificantDigits = function (value) { return value .replace(internals.exponentialPartRegex, '') .replace(internals.dotRegex, '') .replace(internals.trailingZerosRegex, '') .replace(internals.leadingSignAndZerosRegex, ''); }; internals.normalizeDecimal = function (str) { str = str // Remove leading plus signs .replace(/^\+/, '') // Remove trailing zeros if there is a decimal point and unecessary decimal points .replace(/\.0*$/, '') // Add a integer 0 if the numbers starts with a decimal point .replace(/^(-?)\.([^\.]*)$/, '$10.$2') // Remove leading zeros .replace(/^(-?)0+([0-9])/, '$1$2'); if (str.includes('.') && str.endsWith('0')) { str = str.replace(/0+$/, ''); } if (str === '-0') { return '0'; } return str; }; return number; } var object$1; var hasRequiredObject; function requireObject () { if (hasRequiredObject) return object$1; hasRequiredObject = 1; const Keys = requireKeys(); object$1 = Keys.extend({ type: 'object', cast: { map: { from: (value) => value && typeof value === 'object', to(value, helpers) { return new Map(Object.entries(value)); } } } }); return object$1; } var string; var hasRequiredString; function requireString () { if (hasRequiredString) return string; hasRequiredString = 1; const Assert = assert$4; const Domain = domain; const Email = email; const Ip = ip; const EscapeRegex = escapeRegex; const Tlds = tlds; const Uri = uri; const Any = requireAny(); const Common = requireCommon(); const internals = { tlds: Tlds instanceof Set ? { tlds: { allow: Tlds, deny: null } } : false, // $lab:coverage:ignore$ base64Regex: { // paddingRequired true: { // urlSafe true: /^(?:[\w\-]{2}[\w\-]{2})*(?:[\w\-]{2}==|[\w\-]{3}=)?$/, false: /^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/ }, false: { true: /^(?:[\w\-]{2}[\w\-]{2})*(?:[\w\-]{2}(==)?|[\w\-]{3}=?)?$/, false: /^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}(==)?|[A-Za-z0-9+\/]{3}=?)?$/ } }, dataUriRegex: /^data:[\w+.-]+\/[\w+.-]+;((charset=[\w-]+|base64),)?(.*)$/, hexRegex: { withPrefix: /^0x[0-9a-f]+$/i, withOptionalPrefix: /^(?:0x)?[0-9a-f]+$/i, withoutPrefix: /^[0-9a-f]+$/i }, ipRegex: Ip.regex({ cidr: 'forbidden' }).regex, isoDurationRegex: /^P(?!$)(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?$/, guidBrackets: { '{': '}', '[': ']', '(': ')', '': '' }, guidVersions: { uuidv1: '1', uuidv2: '2', uuidv3: '3', uuidv4: '4', uuidv5: '5', uuidv6: '6', uuidv7: '7', uuidv8: '8' }, guidSeparators: new Set([undefined, true, false, '-', ':']), normalizationForms: ['NFC', 'NFD', 'NFKC', 'NFKD'] }; string = Any.extend({ type: 'string', flags: { insensitive: { default: false }, truncate: { default: false } }, terms: { replacements: { init: null } }, coerce: { from: 'string', method(value, { schema, state, prefs }) { const normalize = schema.$_getRule('normalize'); if (normalize) { value = value.normalize(normalize.args.form); } const casing = schema.$_getRule('case'); if (casing) { value = casing.args.direction === 'upper' ? value.toLocaleUpperCase() : value.toLocaleLowerCase(); } const trim = schema.$_getRule('trim'); if (trim && trim.args.enabled) { value = value.trim(); } if (schema.$_terms.replacements) { for (const replacement of schema.$_terms.replacements) { value = value.replace(replacement.pattern, replacement.replacement); } } const hex = schema.$_getRule('hex'); if (hex && hex.args.options.byteAligned && value.length % 2 !== 0) { value = `0${value}`; } if (schema.$_getRule('isoDate')) { const iso = internals.isoDate(value); if (iso) { value = iso; } } if (schema._flags.truncate) { const rule = schema.$_getRule('max'); if (rule) { let limit = rule.args.limit; if (Common.isResolvable(limit)) { limit = limit.resolve(value, state, prefs); if (!Common.limit(limit)) { return { value, errors: schema.$_createError('any.ref', limit, { ref: rule.args.limit, arg: 'limit', reason: 'must be a positive integer' }, state, prefs) }; } } value = value.slice(0, limit); } } return { value }; } }, validate(value, { schema, error }) { if (typeof value !== 'string') { return { value, errors: error('string.base') }; } if (value === '') { const min = schema.$_getRule('min'); if (min && min.args.limit === 0) { return; } return { value, errors: error('string.empty') }; } }, rules: { alphanum: { method() { return this.$_addRule('alphanum'); }, validate(value, helpers) { if (/^[a-zA-Z0-9]+$/.test(value)) { return value; } return helpers.error('string.alphanum'); } }, base64: { method(options = {}) { Common.assertOptions(options, ['paddingRequired', 'urlSafe']); options = { urlSafe: false, paddingRequired: true, ...options }; Assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean'); Assert(typeof options.urlSafe === 'boolean', 'urlSafe must be boolean'); return this.$_addRule({ name: 'base64', args: { options } }); }, validate(value, helpers, { options }) { const regex = internals.base64Regex[options.paddingRequired][options.urlSafe]; if (regex.test(value)) { return value; } return helpers.error('string.base64'); } }, case: { method(direction) { Assert(['lower', 'upper'].includes(direction), 'Invalid case:', direction); return this.$_addRule({ name: 'case', args: { direction } }); }, validate(value, helpers, { direction }) { if (direction === 'lower' && value === value.toLocaleLowerCase() || direction === 'upper' && value === value.toLocaleUpperCase()) { return value; } return helpers.error(`string.${direction}case`); }, convert: true }, creditCard: { method() { return this.$_addRule('creditCard'); }, validate(value, helpers) { let i = value.length; let sum = 0; let mul = 1; while (i--) { const char = value.charAt(i) * mul; sum = sum + (char - (char > 9) * 9); mul = mul ^ 3; } if (sum > 0 && sum % 10 === 0) { return value; } return helpers.error('string.creditCard'); } }, dataUri: { method(options = {}) { Common.assertOptions(options, ['paddingRequired']); options = { paddingRequired: true, ...options }; Assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean'); return this.$_addRule({ name: 'dataUri', args: { options } }); }, validate(value, helpers, { options }) { const matches = value.match(internals.dataUriRegex); if (matches) { if (!matches[2]) { return value; } if (matches[2] !== 'base64') { return value; } const base64regex = internals.base64Regex[options.paddingRequired].false; if (base64regex.test(matches[3])) { return value; } } return helpers.error('string.dataUri'); } }, domain: { method(options) { if (options) { Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']); } const address = internals.addressOptions(options); return this.$_addRule({ name: 'domain', args: { options }, address }); }, validate(value, helpers, args, { address }) { if (Domain.isValid(value, address)) { return value; } return helpers.error('string.domain'); } }, email: { method(options = {}) { Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'ignoreLength', 'maxDomainSegments', 'minDomainSegments', 'multiple', 'separator', 'tlds']); Assert(options.multiple === undefined || typeof options.multiple === 'boolean', 'multiple option must be an boolean'); const address = internals.addressOptions(options); const regex = new RegExp(`\\s*[${options.separator ? EscapeRegex(options.separator) : ','}]\\s*`); return this.$_addRule({ name: 'email', args: { options }, regex, address }); }, validate(value, helpers, { options }, { regex, address }) { const emails = options.multiple ? value.split(regex) : [value]; const invalids = []; for (const email of emails) { if (!Email.isValid(email, address)) { invalids.push(email); } } if (!invalids.length) { return value; } return helpers.error('string.email', { value, invalids }); } }, guid: { alias: 'uuid', method(options = {}) { Common.assertOptions(options, ['version', 'separator']); let versionNumbers = ''; if (options.version) { const versions = [].concat(options.version); Assert(versions.length >= 1, 'version must have at least 1 valid version specified'); const set = new Set(); for (let i = 0; i < versions.length; ++i) { const version = versions[i]; Assert(typeof version === 'string', 'version at position ' + i + ' must be a string'); const versionNumber = internals.guidVersions[version.toLowerCase()]; Assert(versionNumber, 'version at position ' + i + ' must be one of ' + Object.keys(internals.guidVersions).join(', ')); Assert(!set.has(versionNumber), 'version at position ' + i + ' must not be a duplicate'); versionNumbers += versionNumber; set.add(versionNumber); } } Assert(internals.guidSeparators.has(options.separator), 'separator must be one of true, false, "-", or ":"'); const separator = options.separator === undefined ? '[:-]?' : options.separator === true ? '[:-]' : options.separator === false ? '[]?' : `\\${options.separator}`; const regex = new RegExp(`^([\\[{\\(]?)[0-9A-F]{8}(${separator})[0-9A-F]{4}\\2?[${versionNumbers || '0-9A-F'}][0-9A-F]{3}\\2?[${versionNumbers ? '89AB' : '0-9A-F'}][0-9A-F]{3}\\2?[0-9A-F]{12}([\\]}\\)]?)$`, 'i'); return this.$_addRule({ name: 'guid', args: { options }, regex }); }, validate(value, helpers, args, { regex }) { const results = regex.exec(value); if (!results) { return helpers.error('string.guid'); } // Matching braces if (internals.guidBrackets[results[1]] !== results[results.length - 1]) { return helpers.error('string.guid'); } return value; } }, hex: { method(options = {}) { Common.assertOptions(options, ['byteAligned', 'prefix']); options = { byteAligned: false, prefix: false, ...options }; Assert(typeof options.byteAligned === 'boolean', 'byteAligned must be boolean'); Assert(typeof options.prefix === 'boolean' || options.prefix === 'optional', 'prefix must be boolean or "optional"'); return this.$_addRule({ name: 'hex', args: { options } }); }, validate(value, helpers, { options }) { const re = options.prefix === 'optional' ? internals.hexRegex.withOptionalPrefix : options.prefix === true ? internals.hexRegex.withPrefix : internals.hexRegex.withoutPrefix; if (!re.test(value)) { return helpers.error('string.hex'); } if (options.byteAligned && value.length % 2 !== 0) { return helpers.error('string.hexAlign'); } return value; } }, hostname: { method() { return this.$_addRule('hostname'); }, validate(value, helpers) { if (Domain.isValid(value, { minDomainSegments: 1 }) || internals.ipRegex.test(value)) { return value; } return helpers.error('string.hostname'); } }, insensitive: { method() { return this.$_setFlag('insensitive', true); } }, ip: { method(options = {}) { Common.assertOptions(options, ['cidr', 'version']); const { cidr, versions, regex } = Ip.regex(options); const version = options.version ? versions : undefined; return this.$_addRule({ name: 'ip', args: { options: { cidr, version } }, regex }); }, validate(value, helpers, { options }, { regex }) { if (regex.test(value)) { return value; } if (options.version) { return helpers.error('string.ipVersion', { value, cidr: options.cidr, version: options.version }); } return helpers.error('string.ip', { value, cidr: options.cidr }); } }, isoDate: { method() { return this.$_addRule('isoDate'); }, validate(value, { error }) { if (internals.isoDate(value)) { return value; } return error('string.isoDate'); } }, isoDuration: { method() { return this.$_addRule('isoDuration'); }, validate(value, helpers) { if (internals.isoDurationRegex.test(value)) { return value; } return helpers.error('string.isoDuration'); } }, length: { method(limit, encoding) { return internals.length(this, 'length', limit, '=', encoding); }, validate(value, helpers, { limit, encoding }, { name, operator, args }) { const length = encoding ? Buffer && Buffer.byteLength(value, encoding) : value.length; // $lab:coverage:ignore$ if (Common.compare(length, limit, operator)) { return value; } return helpers.error('string.' + name, { limit: args.limit, value, encoding }); }, args: [ { name: 'limit', ref: true, assert: Common.limit, message: 'must be a positive integer' }, 'encoding' ] }, lowercase: { method() { return this.case('lower'); } }, max: { method(limit, encoding) { return internals.length(this, 'max', limit, '<=', encoding); }, args: ['limit', 'encoding'] }, min: { method(limit, encoding) { return internals.length(this, 'min', limit, '>=', encoding); }, args: ['limit', 'encoding'] }, normalize: { method(form = 'NFC') { Assert(internals.normalizationForms.includes(form), 'normalization form must be one of ' + internals.normalizationForms.join(', ')); return this.$_addRule({ name: 'normalize', args: { form } }); }, validate(value, { error }, { form }) { if (value === value.normalize(form)) { return value; } return error('string.normalize', { value, form }); }, convert: true }, pattern: { alias: 'regex', method(regex, options = {}) { Assert(regex instanceof RegExp, 'regex must be a RegExp'); Assert(!regex.flags.includes('g') && !regex.flags.includes('y'), 'regex should not use global or sticky mode'); if (typeof options === 'string') { options = { name: options }; } Common.assertOptions(options, ['invert', 'name']); const errorCode = ['string.pattern', options.invert ? '.invert' : '', options.name ? '.name' : '.base'].join(''); return this.$_addRule({ name: 'pattern', args: { regex, options }, errorCode }); }, validate(value, helpers, { regex, options }, { errorCode }) { const patternMatch = regex.test(value); if (patternMatch ^ options.invert) { return value; } return helpers.error(errorCode, { name: options.name, regex, value }); }, args: ['regex', 'options'], multi: true }, replace: { method(pattern, replacement) { if (typeof pattern === 'string') { pattern = new RegExp(EscapeRegex(pattern), 'g'); } Assert(pattern instanceof RegExp, 'pattern must be a RegExp'); Assert(typeof replacement === 'string', 'replacement must be a String'); const obj = this.clone(); if (!obj.$_terms.replacements) { obj.$_terms.replacements = []; } obj.$_terms.replacements.push({ pattern, replacement }); return obj; } }, token: { method() { return this.$_addRule('token'); }, validate(value, helpers) { if (/^\w+$/.test(value)) { return value; } return helpers.error('string.token'); } }, trim: { method(enabled = true) { Assert(typeof enabled === 'boolean', 'enabled must be a boolean'); return this.$_addRule({ name: 'trim', args: { enabled } }); }, validate(value, helpers, { enabled }) { if (!enabled || value === value.trim()) { return value; } return helpers.error('string.trim'); }, convert: true }, truncate: { method(enabled = true) { Assert(typeof enabled === 'boolean', 'enabled must be a boolean'); return this.$_setFlag('truncate', enabled); } }, uppercase: { method() { return this.case('upper'); } }, uri: { method(options = {}) { Common.assertOptions(options, ['allowRelative', 'allowQuerySquareBrackets', 'domain', 'relativeOnly', 'scheme', 'encodeUri']); if (options.domain) { Common.assertOptions(options.domain, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']); } const { regex, scheme } = Uri.regex(options); const domain = options.domain ? internals.addressOptions(options.domain) : null; return this.$_addRule({ name: 'uri', args: { options }, regex, domain, scheme }); }, validate(value, helpers, { options }, { regex, domain, scheme }) { if (['http:/', 'https:/'].includes(value)) { // scheme:/ is technically valid but makes no sense return helpers.error('string.uri'); } let match = regex.exec(value); if (!match && helpers.prefs.convert && options.encodeUri) { const encoded = encodeURI(value); match = regex.exec(encoded); if (match) { value = encoded; } } if (match) { const matched = match[1] || match[2]; if (domain && (!options.allowRelative || matched) && !Domain.isValid(matched, domain)) { return helpers.error('string.domain', { value: matched }); } return value; } if (options.relativeOnly) { return helpers.error('string.uriRelativeOnly'); } if (options.scheme) { return helpers.error('string.uriCustomScheme', { scheme, value }); } return helpers.error('string.uri'); } } }, manifest: { build(obj, desc) { if (desc.replacements) { for (const { pattern, replacement } of desc.replacements) { obj = obj.replace(pattern, replacement); } } return obj; } }, messages: { 'string.alphanum': '{{#label}} must only contain alpha-numeric characters', 'string.base': '{{#label}} must be a string', 'string.base64': '{{#label}} must be a valid base64 string', 'string.creditCard': '{{#label}} must be a credit card', 'string.dataUri': '{{#label}} must be a valid dataUri string', 'string.domain': '{{#label}} must contain a valid domain name', 'string.email': '{{#label}} must be a valid email', 'string.empty': '{{#label}} is not allowed to be empty', 'string.guid': '{{#label}} must be a valid GUID', 'string.hex': '{{#label}} must only contain hexadecimal characters', 'string.hexAlign': '{{#label}} hex decoded representation must be byte aligned', 'string.hostname': '{{#label}} must be a valid hostname', 'string.ip': '{{#label}} must be a valid ip address with a {{#cidr}} CIDR', 'string.ipVersion': '{{#label}} must be a valid ip address of one of the following versions {{#version}} with a {{#cidr}} CIDR', 'string.isoDate': '{{#label}} must be in iso format', 'string.isoDuration': '{{#label}} must be a valid ISO 8601 duration', 'string.length': '{{#label}} length must be {{#limit}} characters long', 'string.lowercase': '{{#label}} must only contain lowercase characters', 'string.max': '{{#label}} length must be less than or equal to {{#limit}} characters long', 'string.min': '{{#label}} length must be at least {{#limit}} characters long', 'string.normalize': '{{#label}} must be unicode normalized in the {{#form}} form', 'string.token': '{{#label}} must only contain alpha-numeric and underscore characters', 'string.pattern.base': '{{#label}} with value {:[.]} fails to match the required pattern: {{#regex}}', 'string.pattern.name': '{{#label}} with value {:[.]} fails to match the {{#name}} pattern', 'string.pattern.invert.base': '{{#label}} with value {:[.]} matches the inverted pattern: {{#regex}}', 'string.pattern.invert.name': '{{#label}} with value {:[.]} matches the inverted {{#name}} pattern', 'string.trim': '{{#label}} must not have leading or trailing whitespace', 'string.uri': '{{#label}} must be a valid uri', 'string.uriCustomScheme': '{{#label}} must be a valid uri with a scheme matching the {{#scheme}} pattern', 'string.uriRelativeOnly': '{{#label}} must be a valid relative uri', 'string.uppercase': '{{#label}} must only contain uppercase characters' } }); // Helpers internals.addressOptions = function (options) { if (!options) { return internals.tlds || options; // $lab:coverage:ignore$ } // minDomainSegments Assert(options.minDomainSegments === undefined || Number.isSafeInteger(options.minDomainSegments) && options.minDomainSegments > 0, 'minDomainSegments must be a positive integer'); // maxDomainSegments Assert(options.maxDomainSegments === undefined || Number.isSafeInteger(options.maxDomainSegments) && options.maxDomainSegments > 0, 'maxDomainSegments must be a positive integer'); // tlds if (options.tlds === false) { return options; } if (options.tlds === true || options.tlds === undefined) { Assert(internals.tlds, 'Built-in TLD list disabled'); return Object.assign({}, options, internals.tlds); } Assert(typeof options.tlds === 'object', 'tlds must be true, false, or an object'); const deny = options.tlds.deny; if (deny) { if (Array.isArray(deny)) { options = Object.assign({}, options, { tlds: { deny: new Set(deny) } }); } Assert(options.tlds.deny instanceof Set, 'tlds.deny must be an array, Set, or boolean'); Assert(!options.tlds.allow, 'Cannot specify both tlds.allow and tlds.deny lists'); internals.validateTlds(options.tlds.deny, 'tlds.deny'); return options; } const allow = options.tlds.allow; if (!allow) { return options; } if (allow === true) { Assert(internals.tlds, 'Built-in TLD list disabled'); return Object.assign({}, options, internals.tlds); } if (Array.isArray(allow)) { options = Object.assign({}, options, { tlds: { allow: new Set(allow) } }); } Assert(options.tlds.allow instanceof Set, 'tlds.allow must be an array, Set, or boolean'); internals.validateTlds(options.tlds.allow, 'tlds.allow'); return options; }; internals.validateTlds = function (set, source) { for (const tld of set) { Assert(Domain.isValid(tld, { minDomainSegments: 1, maxDomainSegments: 1 }), `${source} must contain valid top level domain names`); } }; internals.isoDate = function (value) { if (!Common.isIsoDate(value)) { return null; } if (/.*T.*[+-]\d\d$/.test(value)) { // Add missing trailing zeros to timeshift value += '00'; } const date = new Date(value); if (isNaN(date.getTime())) { return null; } return date.toISOString(); }; internals.length = function (schema, name, limit, operator, encoding) { Assert(!encoding || Buffer && Buffer.isEncoding(encoding), 'Invalid encoding:', encoding); // $lab:coverage:ignore$ return schema.$_addRule({ name, method: 'length', args: { limit, encoding }, operator }); }; return string; } var symbol; var hasRequiredSymbol; function requireSymbol () { if (hasRequiredSymbol) return symbol; hasRequiredSymbol = 1; const Assert = assert$4; const Any = requireAny(); const internals = {}; internals.Map = class extends Map { slice() { return new internals.Map(this); } }; symbol = Any.extend({ type: 'symbol', terms: { map: { init: new internals.Map() } }, coerce: { method(value, { schema, error }) { const lookup = schema.$_terms.map.get(value); if (lookup) { value = lookup; } if (!schema._flags.only || typeof value === 'symbol') { return { value }; } return { value, errors: error('symbol.map', { map: schema.$_terms.map }) }; } }, validate(value, { error }) { if (typeof value !== 'symbol') { return { value, errors: error('symbol.base') }; } }, rules: { map: { method(iterable) { if (iterable && !iterable[Symbol.iterator] && typeof iterable === 'object') { iterable = Object.entries(iterable); } Assert(iterable && iterable[Symbol.iterator], 'Iterable must be an iterable or object'); const obj = this.clone(); const symbols = []; for (const entry of iterable) { Assert(entry && entry[Symbol.iterator], 'Entry must be an iterable'); const [key, value] = entry; Assert(typeof key !== 'object' && typeof key !== 'function' && typeof key !== 'symbol', 'Key must not be of type object, function, or Symbol'); Assert(typeof value === 'symbol', 'Value must be a Symbol'); obj.$_terms.map.set(key, value); symbols.push(value); } return obj.valid(...symbols); } } }, manifest: { build(obj, desc) { if (desc.map) { obj = obj.map(desc.map); } return obj; } }, messages: { 'symbol.base': '{{#label}} must be a symbol', 'symbol.map': '{{#label}} must be one of {{#map}}' } }); return symbol; } var binary$1; var hasRequiredBinary; function requireBinary () { if (hasRequiredBinary) return binary$1; hasRequiredBinary = 1; const Assert = assert$4; const Any = requireAny(); const Common = requireCommon(); binary$1 = Any.extend({ type: 'binary', coerce: { from: ['string', 'object'], method(value, { schema }) { if (typeof value === 'string' || (value !== null && value.type === 'Buffer')) { try { return { value: Buffer.from(value, schema._flags.encoding) }; } catch (ignoreErr) { } } } }, validate(value, { error }) { if (!Buffer.isBuffer(value)) { return { value, errors: error('binary.base') }; } }, rules: { encoding: { method(encoding) { Assert(Buffer.isEncoding(encoding), 'Invalid encoding:', encoding); return this.$_setFlag('encoding', encoding); } }, length: { method(limit) { return this.$_addRule({ name: 'length', method: 'length', args: { limit }, operator: '=' }); }, validate(value, helpers, { limit }, { name, operator, args }) { if (Common.compare(value.length, limit, operator)) { return value; } return helpers.error('binary.' + name, { limit: args.limit, value }); }, args: [ { name: 'limit', ref: true, assert: Common.limit, message: 'must be a positive integer' } ] }, max: { method(limit) { return this.$_addRule({ name: 'max', method: 'length', args: { limit }, operator: '<=' }); } }, min: { method(limit) { return this.$_addRule({ name: 'min', method: 'length', args: { limit }, operator: '>=' }); } } }, cast: { string: { from: (value) => Buffer.isBuffer(value), to(value, helpers) { return value.toString(); } } }, messages: { 'binary.base': '{{#label}} must be a buffer or a string', 'binary.length': '{{#label}} must be {{#limit}} bytes', 'binary.max': '{{#label}} must be less than or equal to {{#limit}} bytes', 'binary.min': '{{#label}} must be at least {{#limit}} bytes' } }); return binary$1; } var lib$5; var hasRequiredLib; function requireLib () { if (hasRequiredLib) return lib$5; hasRequiredLib = 1; const Assert = assert$4; const Clone = clone$6; const Cache = requireCache(); const Common = requireCommon(); const Compile = requireCompile(); const Errors = requireErrors(); const Extend = requireExtend(); const Manifest = requireManifest(); const Ref = requireRef(); const Template = requireTemplate(); const Trace = requireTrace(); let Schemas; const internals = { types: { alternatives: requireAlternatives(), any: requireAny(), array: requireArray(), boolean: requireBoolean(), date: requireDate(), function: require_function(), link: requireLink(), number: requireNumber(), object: requireObject(), string: requireString(), symbol: requireSymbol() }, aliases: { alt: 'alternatives', bool: 'boolean', func: 'function' } }; if (Buffer) { // $lab:coverage:ignore$ internals.types.binary = requireBinary(); } internals.root = function () { const root = { _types: new Set(Object.keys(internals.types)) }; // Types for (const type of root._types) { root[type] = function (...args) { Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments'); return internals.generate(this, internals.types[type], args); }; } // Shortcuts for (const method of ['allow', 'custom', 'disallow', 'equal', 'exist', 'forbidden', 'invalid', 'not', 'only', 'optional', 'options', 'prefs', 'preferences', 'required', 'strip', 'valid', 'when']) { root[method] = function (...args) { return this.any()[method](...args); }; } // Methods Object.assign(root, internals.methods); // Aliases for (const alias in internals.aliases) { const target = internals.aliases[alias]; root[alias] = root[target]; } root.x = root.expression; // Trace if (Trace.setup) { // $lab:coverage:ignore$ Trace.setup(root); } return root; }; internals.methods = { ValidationError: Errors.ValidationError, version: Common.version, cache: Cache.provider, assert(value, schema, ...args /* [message], [options] */) { internals.assert(value, schema, true, args); }, attempt(value, schema, ...args /* [message], [options] */) { return internals.assert(value, schema, false, args); }, build(desc) { Assert(typeof Manifest.build === 'function', 'Manifest functionality disabled'); return Manifest.build(this, desc); }, checkPreferences(prefs) { Common.checkPreferences(prefs); }, compile(schema, options) { return Compile.compile(this, schema, options); }, defaults(modifier) { Assert(typeof modifier === 'function', 'modifier must be a function'); const joi = Object.assign({}, this); for (const type of joi._types) { const schema = modifier(joi[type]()); Assert(Common.isSchema(schema), 'modifier must return a valid schema object'); joi[type] = function (...args) { return internals.generate(this, schema, args); }; } return joi; }, expression(...args) { return new Template(...args); }, extend(...extensions) { Common.verifyFlat(extensions, 'extend'); Schemas = Schemas || requireSchemas(); Assert(extensions.length, 'You need to provide at least one extension'); this.assert(extensions, Schemas.extensions); const joi = Object.assign({}, this); joi._types = new Set(joi._types); for (let extension of extensions) { if (typeof extension === 'function') { extension = extension(joi); } this.assert(extension, Schemas.extension); const expanded = internals.expandExtension(extension, joi); for (const item of expanded) { Assert(joi[item.type] === undefined || joi._types.has(item.type), 'Cannot override name', item.type); const base = item.base || this.any(); const schema = Extend.type(base, item); joi._types.add(item.type); joi[item.type] = function (...args) { return internals.generate(this, schema, args); }; } } return joi; }, isError: Errors.ValidationError.isError, isExpression: Template.isTemplate, isRef: Ref.isRef, isSchema: Common.isSchema, in(...args) { return Ref.in(...args); }, override: Common.symbols.override, ref(...args) { return Ref.create(...args); }, types() { const types = {}; for (const type of this._types) { types[type] = this[type](); } for (const target in internals.aliases) { types[target] = this[target](); } return types; } }; // Helpers internals.assert = function (value, schema, annotate, args /* [message], [options] */) { const message = args[0] instanceof Error || typeof args[0] === 'string' ? args[0] : null; const options = message !== null ? args[1] : args[0]; const result = schema.validate(value, Common.preferences({ errors: { stack: true } }, options || {})); let error = result.error; if (!error) { return result.value; } if (message instanceof Error) { throw message; } const display = annotate && typeof error.annotate === 'function' ? error.annotate() : error.message; if (error instanceof Errors.ValidationError === false) { error = Clone(error); } error.message = message ? `${message} ${display}` : display; throw error; }; internals.generate = function (root, schema, args) { Assert(root, 'Must be invoked on a Joi instance.'); schema.$_root = root; if (!schema._definition.args || !args.length) { return schema; } return schema._definition.args(schema, ...args); }; internals.expandExtension = function (extension, joi) { if (typeof extension.type === 'string') { return [extension]; } const extended = []; for (const type of joi._types) { if (extension.type.test(type)) { const item = Object.assign({}, extension); item.type = type; item.base = joi[type](); extended.push(item); } } return extended; }; lib$5 = internals.root(); return lib$5; } var libExports$1 = requireLib(); var BaseJoi = /*@__PURE__*/getDefaultExportFromCjs(libExports$1); var t$2={table:"directus_collections",defaults:{collection:null,hidden:!1,singleton:!1,icon:null,note:null,translations:null,display_template:null,accountability:"all"},data:[{collection:"directus_activity",note:"$t:directus_collection.directus_activity",accountability:null},{collection:"directus_collections",icon:"database",note:"$t:directus_collection.directus_collections"},{collection:"directus_fields",icon:"input",note:"$t:directus_collection.directus_fields"},{collection:"directus_files",icon:"folder",note:"$t:directus_collection.directus_files",display_template:"{{ $thumbnail }} {{ title }}"},{collection:"directus_folders",note:"$t:directus_collection.directus_folders",display_template:"{{ name }}"},{collection:"directus_migrations",note:"$t:directus_collection.directus_migrations"},{collection:"directus_permissions",icon:"admin_panel_settings",note:"$t:directus_collection.directus_permissions"},{collection:"directus_presets",icon:"bookmark",note:"$t:directus_collection.directus_presets",accountability:null},{collection:"directus_relations",icon:"merge_type",note:"$t:directus_collection.directus_relations"},{collection:"directus_revisions",note:"$t:directus_collection.directus_revisions",accountability:null},{collection:"directus_roles",icon:"supervised_user_circle",note:"$t:directus_collection.directus_roles"},{collection:"directus_sessions",note:"$t:directus_collection.directus_sessions"},{collection:"directus_settings",singleton:!0,note:"$t:directus_collection.directus_settings"},{collection:"directus_users",archive_field:"status",archive_value:"archived",unarchive_value:"draft",icon:"people_alt",note:"$t:directus_collection.directus_users",display_template:"{{ first_name }} {{ last_name }}"},{collection:"directus_webhooks",note:"$t:directus_collection.directus_webhooks"},{collection:"directus_dashboards",note:"$t:directus_collection.directus_dashboards"},{collection:"directus_panels",note:"$t:directus_collection.directus_panels"},{collection:"directus_notifications",note:"$t:directus_collection.directus_notifications"},{collection:"directus_shares",icon:"share",note:"$t:directus_collection.directus_shares"},{collection:"directus_flows",note:"$t:directus_collection.directus_flows"},{collection:"directus_operations",note:"$t:directus_collection.directus_operations"},{collection:"directus_translations",note:"$t:directus_collection.directus_translations"},{collection:"directus_versions",note:"$t:directus_collection.directus_versions"},{collection:"directus_extensions",note:"$t:directus_collection.directus_extensions"}]};t$2.data.map(i=>({...t$2.defaults,...i,system:!0}));t$2.data.map(i=>i.collection);var l={table:"directus_relations",defaults:{many_collection:"directus_users",many_field:null,one_collection:null,one_field:null,one_allowed_collections:null,one_collection_field:null,one_deselect_action:"nullify",junction_field:null,sort_field:null},data:[{many_collection:"directus_collections",many_field:"group",one_collection:"directus_collections"},{many_collection:"directus_users",many_field:"role",one_collection:"directus_roles",one_field:"users"},{many_collection:"directus_users",many_field:"avatar",one_collection:"directus_files"},{many_collection:"directus_revisions",many_field:"activity",one_collection:"directus_activity",one_field:"revisions"},{many_collection:"directus_revisions",many_field:"parent",one_collection:"directus_revisions"},{many_collection:"directus_revisions",many_field:"version",one_collection:"directus_versions"},{many_collection:"directus_presets",many_field:"user",one_collection:"directus_users"},{many_collection:"directus_presets",many_field:"role",one_collection:"directus_roles"},{many_collection:"directus_folders",many_field:"parent",one_collection:"directus_folders"},{many_collection:"directus_files",many_field:"folder",one_collection:"directus_folders"},{many_collection:"directus_files",many_field:"uploaded_by",one_collection:"directus_users"},{many_collection:"directus_files",many_field:"modified_by",one_collection:"directus_users"},{many_collection:"directus_fields",many_field:"collection",one_collection:"directus_collections",one_field:"fields"},{many_collection:"directus_fields",many_field:"group",one_collection:"directus_fields"},{many_collection:"directus_activity",many_field:"user",one_collection:"directus_users"},{many_collection:"directus_settings",many_field:"project_logo",one_collection:"directus_files"},{many_collection:"directus_settings",many_field:"public_foreground",one_collection:"directus_files"},{many_collection:"directus_settings",many_field:"public_background",one_collection:"directus_files"},{many_collection:"directus_settings",many_field:"public_favicon",one_collection:"directus_files"},{many_collection:"directus_settings",many_field:"storage_default_folder",one_collection:"directus_folders"},{many_collection:"directus_panels",many_field:"dashboard",one_collection:"directus_dashboards",one_field:"panels"},{many_collection:"directus_panels",many_field:"user_created",one_collection:"directus_users"},{many_collection:"directus_flows",many_field:"operation",one_collection:"directus_operations"},{many_collection:"directus_flows",many_field:"user_created",one_collection:"directus_users"},{many_collection:"directus_operations",many_field:"flow",one_collection:"directus_flows",one_field:"operations",one_deselect_action:"delete"},{many_collection:"directus_operations",many_field:"resolve",one_collection:"directus_operations"},{many_collection:"directus_operations",many_field:"reject",one_collection:"directus_operations"},{many_collection:"directus_operations",many_field:"user_created",one_collection:"directus_users"},{many_collection:"directus_permissions",many_field:"role",one_collection:"directus_roles"},{many_collection:"directus_sessions",many_field:"user",one_collection:"directus_users"},{many_collection:"directus_sessions",many_field:"share",one_collection:"directus_shares"},{many_collection:"directus_dashboards",many_field:"user_created",one_collection:"directus_users"},{many_collection:"directus_notifications",many_field:"recipient",one_collection:"directus_users"},{many_collection:"directus_notifications",many_field:"sender",one_collection:"directus_users"},{many_collection:"directus_shares",many_field:"role",one_collection:"directus_roles"},{many_collection:"directus_shares",many_field:"collection",one_collection:"directus_collections"},{many_collection:"directus_shares",many_field:"user_created",one_collection:"directus_users"},{many_collection:"directus_versions",many_field:"collection",one_collection:"directus_collections"},{many_collection:"directus_versions",many_field:"user_created",one_collection:"directus_users"},{many_collection:"directus_versions",many_field:"user_updated",one_collection:"directus_users"}]};l.data.map(i=>({...l.defaults,...i,system:!0}));var o={collection:null,field:null,special:null,interface:null,options:null,display:null,display_options:null,readonly:!1,hidden:!1,sort:null,width:"full",group:null,translations:null,note:null,conditions:null,required:!1};var a={table:"directus_activity",fields:[{field:"id",width:"half"},{field:"item",width:"half"},{field:"action",display:"labels",display_options:{choices:[{text:"$t:field_options.directus_activity.create",value:"create",foreground:"var(--theme--primary)",background:"var(--theme--primary-subdued)"},{text:"$t:field_options.directus_activity.update",value:"update",foreground:"var(--blue)",background:"var(--blue-25)"},{text:"$t:field_options.directus_activity.delete",value:"delete",foreground:"var(--theme--danger)",background:"var(--danger-25)"},{text:"$t:field_options.directus_activity.login",value:"login",foreground:"var(--purple)",background:"var(--purple-25)"}]},width:"half"},{field:"collection",display:"collection",display_options:{icon:!0},width:"half"},{field:"timestamp",display:"datetime",special:["date-created","cast-timestamp"],options:{relative:!0},width:"half"},{field:"user",display:"user",width:"half"},{field:"comment",display:"formatted-value",display_options:{color:"var(--theme--foreground-subdued)"},width:"half"},{field:"user_agent",display:"formatted-value",display_options:{font:"monospace"},width:"half"},{field:"origin",display:"formatted-value",display_options:{font:"monospace"},width:"half"},{field:"ip",display:"formatted-value",display_options:{font:"monospace"},width:"half"},{field:"revisions",interface:"list-o2m",special:["o2m"],options:{fields:["collection","item"]},width:"half"}]};var s$1={table:"directus_collections",fields:[{field:"collection_divider",special:["alias","no-data"],interface:"presentation-divider",options:{icon:"box",title:"$t:field_options.directus_collections.collection_setup"},width:"full"},{field:"collection",interface:"input",options:{font:"monospace"},readonly:!0,width:"half"},{field:"note",interface:"input",options:{placeholder:"$t:field_options.directus_collections.note_placeholder"},width:"half"},{field:"icon",interface:"select-icon",options:null,width:"half"},{field:"color",interface:"select-color",options:{placeholder:"$t:interfaces.select-color.placeholder"},width:"half"},{field:"display_template",interface:"system-display-template",options:{collectionField:"collection"},width:"full"},{field:"hidden",special:["cast-boolean"],interface:"boolean",options:{label:"$t:field_options.directus_collections.hidden_label"},width:"half"},{field:"singleton",special:["cast-boolean"],interface:"boolean",options:{label:"$t:singleton_label"},width:"half"},{field:"translations",special:["cast-json"],interface:"list",options:{template:"{{ translation }} ({{ language }})",fields:[{field:"language",name:"$t:language",type:"string",schema:{default_value:"en-US"},meta:{interface:"system-language",width:"half",required:!0}},{field:"translation",name:"$t:field_options.directus_collections.collection_name",type:"string",meta:{interface:"input",width:"half",required:!0,options:{placeholder:"$t:field_options.directus_collections.translation_placeholder"}}},{field:"singular",name:"$t:field_options.directus_collections.singular_unit",type:"string",meta:{interface:"input",width:"half",options:{placeholder:"$t:field_options.directus_collections.translation_placeholder"}}},{field:"plural",name:"$t:field_options.directus_collections.plural_unit",type:"string",meta:{interface:"input",width:"half",options:{placeholder:"$t:field_options.directus_collections.translation_placeholder"}}}]},width:"full"},{field:"preview_divider",special:["alias","no-data"],interface:"presentation-divider",options:{icon:"preview",title:"$t:field_options.directus_collections.preview_divider"},width:"full"},{field:"preview_url",interface:"system-display-template",options:{collectionField:"collection",injectVersionField:!0},width:"full"},{field:"content_versioning_divider",special:["alias","no-data"],interface:"presentation-divider",options:{icon:"published_with_changes",title:"$t:field_options.directus_collections.content_versioning_divider"},width:"full"},{field:"versioning",interface:"boolean",special:["cast-boolean"],options:{label:"$t:field_options.directus_collections.enable_versioning"},width:"half"},{field:"archive_divider",special:["alias","no-data"],interface:"presentation-divider",options:{icon:"archive",title:"$t:field_options.directus_collections.archive_divider"},width:"full"},{field:"archive_field",interface:"system-field",options:{collectionField:"collection",allowNone:!0,placeholder:"$t:field_options.directus_collections.archive_field_placeholder"},width:"half"},{field:"archive_app_filter",interface:"boolean",special:["cast-boolean"],options:{label:"$t:field_options.directus_collections.archive_app_filter"},width:"half"},{field:"archive_value",interface:"input",options:{font:"monospace",iconRight:"archive",placeholder:"$t:field_options.directus_collections.archive_value"},width:"half"},{field:"unarchive_value",interface:"input",options:{font:"monospace",iconRight:"unarchive",placeholder:"$t:field_options.directus_collections.unarchive_value"},width:"half"},{field:"sort_divider",special:["alias","no-data"],interface:"presentation-divider",options:{icon:"sort",title:"$t:field_options.directus_collections.sort_divider"},width:"full"},{field:"sort_field",interface:"system-field",options:{collectionField:"collection",placeholder:"$t:field_options.directus_collections.sort_field",typeAllowList:["float","decimal","integer"],allowNone:!0,allowPrimaryKey:!1,allowForeignKeys:!1},width:"half"},{field:"accountability_divider",special:["alias","no-data"],interface:"presentation-divider",options:{icon:"admin_panel_settings",title:"$t:field_options.directus_collections.accountability_divider"},width:"full"},{field:"accountability",interface:"select-dropdown",options:{choices:[{text:"$t:field_options.directus_collections.track_activity_revisions",value:"all"},{text:"$t:field_options.directus_collections.only_track_activity",value:"activity"},{text:"$t:field_options.directus_collections.do_not_track_anything",value:null}]},width:"half"},{field:"duplication_divider",special:["alias","no-data"],interface:"presentation-divider",options:{icon:"content_copy",title:"$t:field_options.directus_collections.duplication_divider"}},{field:"item_duplication_fields",special:["cast-json"],interface:"system-field-tree",options:{collectionField:"collection"}},{field:"sort",hidden:!0},{field:"group",hidden:!0},{field:"collapse",hidden:!0}]};var n={table:"directus_fields",fields:[{collection:"directus_fields",field:"id",width:"half"},{collection:"directus_fields",field:"collection",width:"half"},{collection:"directus_fields",field:"field",width:"half"},{collection:"directus_fields",field:"special",hidden:!0,special:["cast-csv"],width:"half"},{collection:"directus_fields",field:"interface",width:"half"},{collection:"directus_fields",field:"options",hidden:!0,special:["cast-json"],width:"half"},{collection:"directus_fields",field:"display",width:"half"},{collection:"directus_fields",field:"display_options",hidden:!0,special:["cast-json"],width:"half"},{collection:"directus_fields",field:"readonly",hidden:!0,special:["cast-boolean"],width:"half"},{collection:"directus_fields",field:"hidden",hidden:!0,special:["cast-boolean"],width:"half"},{collection:"directus_fields",field:"required",hidden:!0,special:["cast-boolean"],width:"half"},{collection:"directus_fields",field:"sort",width:"half"},{collection:"directus_fields",field:"width",width:"half"},{collection:"directus_fields",field:"group",width:"half"},{collection:"directus_fields",field:"translations",hidden:!0,special:["cast-json"],width:"half"},{collection:"directus_fields",field:"note",width:"half"},{collection:"directus_fields",field:"conditions",hidden:!0,special:["cast-json"]},{collection:"directus_fields",field:"validation",hidden:!0,special:["cast-json"]},{collection:"directus_fields",field:"validation_message",hidden:!0}]};var d$1={table:"directus_files",fields:[{field:"id",hidden:!0,interface:"input",special:["uuid"]},{field:"title",interface:"input",options:{iconRight:"title",placeholder:"$t:field_options.directus_files.title"},width:"full"},{field:"description",interface:"input-multiline",width:"full",options:{placeholder:"$t:field_options.directus_files.description"}},{field:"tags",interface:"tags",options:{iconRight:"local_offer"},special:["cast-json"],width:"full",display:"labels",display_options:{choices:null,format:!1}},{field:"location",interface:"input",options:{iconRight:"place",placeholder:"$t:field_options.directus_files.location"},width:"half"},{field:"storage",interface:"input",options:{iconRight:"storage"},width:"half",readonly:!0},{field:"focal_point_divider",interface:"presentation-divider",options:{icon:"image_search",title:"$t:field_options.directus_files.focal_point_divider"},special:["alias","no-data"],width:"full"},{field:"focal_point_x",width:"half"},{field:"focal_point_y",width:"half"},{field:"storage_divider",interface:"presentation-divider",options:{icon:"insert_drive_file",title:"$t:field_options.directus_files.storage_divider"},special:["alias","no-data"],width:"full"},{field:"filename_disk",interface:"input",options:{iconRight:"publish",placeholder:"$t:field_options.directus_files.filename_disk"},readonly:!0,width:"half"},{field:"filename_download",interface:"input",options:{iconRight:"get_app",placeholder:"$t:field_options.directus_files.filename_download"},width:"half"},{field:"metadata",hidden:!0,special:["cast-json"]},{field:"type",display:"mime-type",readonly:!0},{field:"filesize",display:"filesize",readonly:!0},{field:"modified_by",interface:"select-dropdown-m2o",special:["user-updated"],width:"half",display:"user",readonly:!0,options:{template:"{{avatar.$thumbnail}} {{first_name}} {{last_name}}"}},{field:"modified_on",interface:"datetime",special:["date-updated"],width:"half",display:"datetime",readonly:!0},{field:"embed",width:"half",hidden:!0},{field:"uploaded_by",display:"user",width:"half",hidden:!0,special:["user-created"]},{field:"uploaded_on",display:"datetime",width:"half",hidden:!0},{field:"folder",width:"half",readonly:!0,special:["m2o"],display:"related-values",display_options:{template:"{{ name }}"}},{field:"width",width:"half",readonly:!0},{field:"height",width:"half",readonly:!0},{field:"charset",width:"half",readonly:!0},{field:"duration",width:"half",readonly:!0}]};var r={table:"directus_folders",fields:[{field:"id",interface:"input",special:["uuid"],width:"half"},{field:"parent",width:"half"},{field:"name",width:"full"}]};var c={table:"directus_migrations",fields:[{collection:"directus_migrations",field:"version"},{collection:"directus_migrations",field:"name"},{collection:"directus_migrations",field:"timestamp"}]};var f={table:"directus_permissions",fields:[{field:"permissions",hidden:!0,special:["cast-json"],width:"half"},{field:"presets",hidden:!0,special:["cast-json"],width:"half"},{field:"role",width:"half"},{field:"collection",width:"half"},{field:"id",width:"half"},{field:"fields",width:"half",special:["cast-csv"]},{field:"action",width:"half"},{field:"validation",width:"half",special:["cast-json"]}]};var u$f={table:"directus_presets",fields:[{field:"filter",hidden:!0,special:["cast-json"]},{field:"layout_query",hidden:!0,special:["cast-json"]},{field:"layout_options",hidden:!0,special:["cast-json"]},{field:"role",width:"half",special:["m2o"],display:"related-values",display_options:{template:"{{ name }}"}},{field:"user",width:"half",special:["m2o"],display:"related-values",display_options:{template:"{{ email }}"}},{field:"id",width:"half"},{field:"bookmark",width:"half"},{field:"icon",width:"half"},{field:"color",width:"half"},{field:"search",width:"half"},{field:"collection",width:"half"},{field:"layout",width:"half"},{field:"refresh_interval"}]};var p={table:"directus_relations",fields:[{field:"id",width:"half"},{field:"many_collection",width:"half"},{field:"many_field",width:"half"},{field:"one_collection",width:"half"},{field:"one_field",width:"half"},{field:"one_collection_field",width:"half"},{field:"one_allowed_collections",special:["cast-csv"],width:"half"},{field:"junction_field",width:"half"},{field:"sort_field",width:"half"},{field:"one_deselect_action",width:"half"}]};var _={table:"directus_revisions",fields:[{field:"id",width:"half"},{field:"activity",width:"half"},{field:"collection",width:"half"},{field:"item",width:"half"},{field:"data",hidden:!0,special:["cast-json"]},{field:"delta",hidden:!0,special:["cast-json"]},{field:"parent",width:"half"},{field:"version",width:"half"}]};var h$1={table:"directus_roles",fields:[{field:"id",hidden:!0,interface:"input",special:["uuid"]},{field:"name",interface:"input",options:{placeholder:"$t:field_options.directus_roles.name"},width:"half"},{field:"icon",interface:"select-icon",display:"icon",width:"half"},{field:"description",interface:"input",options:{placeholder:"$t:field_options.directus_roles.description"},width:"full"},{field:"app_access",interface:"boolean",special:["cast-boolean"],width:"half"},{field:"admin_access",interface:"boolean",special:["cast-boolean"],width:"half"},{field:"ip_access",interface:"tags",options:{placeholder:"$t:field_options.directus_roles.ip_access"},special:["cast-csv"],width:"full"},{field:"enforce_tfa",interface:"boolean",special:["cast-boolean"],width:"half"},{field:"users",interface:"list-o2m",special:["o2m"],options:{fields:["first_name","last_name"]},width:"full"}]};var m$1={table:"directus_sessions",fields:[{field:"token",width:"half"},{field:"user",width:"half"},{field:"expires",width:"half"},{field:"ip",width:"half"},{field:"user_agent",width:"half"},{field:"origin",width:"half"},{field:"share",width:"half"},{field:"next_token",width:"half"}]};var g={table:"directus_settings",fields:[{field:"id",hidden:!0},{field:"project_name",interface:"input",options:{iconRight:"title",placeholder:"$t:field_options.directus_settings.project_name_placeholder"},width:"half"},{field:"project_descriptor",interface:"input",options:{iconRight:"title",placeholder:"$t:field_options.directus_settings.project_name_placeholder"},width:"half"},{field:"project_url",interface:"input",options:{iconRight:"link",placeholder:"https://example.com"},width:"half"},{field:"default_language",interface:"system-language",options:{iconRight:"language",placeholder:"en-US"},width:"half"},{field:"theming_group",interface:"group-raw",special:["alias","no-data","group"]},{field:"branding_divider",interface:"presentation-divider",options:{icon:"palette",title:"$t:fields.directus_settings.branding"},special:["alias","no-data"],width:"full",group:"theming_group"},{field:"project_color",interface:"select-color",note:"$t:field_options.directus_settings.project_color_note",width:"half",group:"theming_group"},{field:"project_logo",interface:"file",note:"$t:field_options.directus_settings.project_logo_note",width:"half",group:"theming_group"},{field:"public_foreground",interface:"file",width:"half",group:"theming_group"},{field:"public_background",interface:"file",width:"half",group:"theming_group"},{field:"public_favicon",interface:"file",note:"$t:field_options.directus_settings.project_favicon_note",width:"half",group:"theming_group"},{field:"public_note",interface:"input",options:{placeholder:"$t:field_options.directus_settings.public_note_placeholder",iconRight:"info"},width:"half",group:"theming_group"},{field:"theming_divider",interface:"presentation-divider",options:{icon:"palette",title:"$t:fields.directus_settings.theming"},special:["alias","no-data"],width:"full",group:"theming_group"},{field:"default_appearance",interface:"select-dropdown",width:"half",options:{choices:[{value:"auto",text:"$t:appearance_auto"},{value:"light",text:"$t:appearance_light"},{value:"dark",text:"$t:appearance_dark"}]},group:"theming_group"},{field:"default_theme_light",width:"full",interface:"system-theme",options:{appearance:"light"},group:"theming_group"},{field:"theme_light_overrides",width:"full",interface:"system-theme-overrides",options:{appearance:"light"},group:"theming_group",special:["cast-json"]},{field:"default_theme_dark",width:"full",interface:"system-theme",options:{appearance:"dark"},group:"theming_group"},{field:"theme_dark_overrides",width:"full",interface:"system-theme-overrides",options:{appearance:"dark"},group:"theming_group",special:["cast-json"]},{field:"custom_css",interface:"input-code",options:{language:"css",lineNumber:!0,template:`#app, #main-content, body { --v-button-background-color: #6644FF !important; --v-button-background-color-hover: #5E41EC !important; } `},width:"full",group:"theming_group"},{field:"modules_divider",interface:"presentation-divider",options:{icon:"menu_open",title:"$t:modules"},special:["alias","no-data"],width:"full"},{field:"module_bar",interface:"system-modules",special:["cast-json"]},{field:"security_divider",interface:"presentation-divider",options:{icon:"shield",title:"$t:security"},special:["alias","no-data"],width:"full"},{field:"auth_password_policy",interface:"select-dropdown",options:{choices:[{value:null,text:"$t:field_options.directus_settings.auth_password_policy.none_text"},{value:"/^.{8,}$/",text:"$t:field_options.directus_settings.auth_password_policy.weak_text"},{value:"/(?=^.{8,}$)(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+}{';'?>.<,])(?!.*\\s).*$/",text:"$t:field_options.directus_settings.auth_password_policy.strong_text"}],allowOther:!0},width:"half"},{field:"auth_login_attempts",interface:"input",options:{iconRight:"lock",placeholder:"$t:unlimited"},width:"half"},{field:"public_registration_divider",interface:"presentation-divider",options:{icon:"person_add",title:"$t:fields.directus_settings.public_registration"},special:["alias","no-data"],width:"full"},{field:"public_registration",interface:"boolean",note:"$t:fields.directus_settings.public_registration_note",width:"half",options:{label:"$t:enabled"},special:["cast-boolean"]},{field:"public_registration_role",interface:"select-dropdown-m2o",note:"$t:fields.directus_settings.public_registration_role_note",options:{template:"{{ name }}",filter:{admin_access:{_eq:!1}}},special:["m2o"],width:"half",display:"related-values",display_options:{template:"{{ name }}"}},{field:"public_registration_verify_email",interface:"boolean",note:"$t:fields.directus_settings.public_registration_verify_email_note",width:"half",options:{label:"$t:enabled"},special:["cast-boolean"]},{field:"public_registration_email_filter",interface:"system-filter",note:"$t:fields.directus_settings.public_registration_email_filter_note",options:{collectionName:"directus_users",collectionField:"email",fieldName:"email"},special:["cast-json"],width:"half"},{field:"files_divider",interface:"presentation-divider",options:{icon:"folder",title:"$t:fields.directus_settings.files_and_thumbnails"},special:["alias","no-data"],width:"full"},{field:"storage_asset_transform",interface:"select-dropdown",options:{choices:[{value:"all",text:"$t:fields.directus_settings.transformations_all"},{value:"none",text:"$t:fields.directus_settings.transformations_none"},{value:"presets",text:"$t:fields.directus_settings.transformations_presets"}]},width:"half"},{field:"storage_default_folder",interface:"system-folder",width:"half",note:"$t:interfaces.system-folder.field_hint"},{field:"storage_asset_presets",interface:"list",options:{fields:[{field:"key",name:"$t:key",type:"string",schema:{is_nullable:!1},meta:{interface:"input",options:{slug:!0,onlyOnCreate:!1},width:"full",required:!0}},{field:"fit",name:"$t:field_options.directus_settings.storage_asset_presets.fit_label",type:"string",schema:{is_nullable:!1},meta:{interface:"select-dropdown",options:{choices:[{value:"contain",text:"$t:field_options.directus_settings.storage_asset_presets.fit.contain_text"},{value:"cover",text:"$t:field_options.directus_settings.storage_asset_presets.fit.cover_text"},{value:"inside",text:"$t:field_options.directus_settings.storage_asset_presets.fit.fit_text"},{value:"outside",text:"$t:field_options.directus_settings.storage_asset_presets.fit.outside_text"}]},width:"half"}},{field:"width",name:"$t:width",type:"integer",schema:{is_nullable:!1},meta:{interface:"input",width:"half"}},{field:"height",name:"$t:height",type:"integer",schema:{is_nullable:!1},meta:{interface:"input",width:"half"}},{field:"quality",type:"integer",name:"$t:quality",schema:{default_value:80,is_nullable:!1},meta:{interface:"slider",options:{max:100,min:0,step:1},width:"half"}},{field:"withoutEnlargement",name:"$t:field_options.directus_settings.storage_asset_presets.upscaling",type:"boolean",schema:{default_value:!1},meta:{interface:"boolean",width:"half",options:{label:"$t:no_upscale"}}},{field:"format",name:"$t:format",type:"string",schema:{is_nullable:!1,default_value:""},meta:{interface:"select-dropdown",options:{allowNone:!0,choices:[{value:"auto",text:"Auto"},{value:"jpeg",text:"JPEG"},{value:"png",text:"PNG"},{value:"webp",text:"WebP"},{value:"tiff",text:"Tiff"},{value:"avif",text:"AVIF"}]},width:"half"}},{field:"transforms",name:"$t:field_options.directus_settings.additional_transforms",type:"json",schema:{is_nullable:!1,default_value:[]},meta:{note:"$t:field_options.directus_settings.transforms_note",interface:"json",options:{template:`[ ["blur", 45], ["grayscale"], ["extend", { "right": 500, "background": "rgb(255, 0, 0)" }] ] `,placeholder:`[ ["blur", 45], ["grayscale"], ["extend", { "right": 500, "background": "rgb(255, 0, 0)" }] ] `},width:"full"}}],template:"{{key}}"},special:["cast-json"],width:"full"},{field:"reporting_divider",interface:"presentation-divider",options:{icon:"feedback",title:"$t:fields.directus_settings.reporting"},special:["alias","no-data"],width:"full"},{field:"report_feature_url",interface:"input",options:{iconRight:"link",placeholder:"https://example.com/feature"},width:"half"},{field:"report_bug_url",interface:"input",options:{iconRight:"link",placeholder:"https://example.com/bug"},width:"half"},{field:"report_error_url",interface:"system-display-template",options:{placeholder:"https://example.com/error",fields:[{name:"Error",field:"error",key:"error",path:"error",children:[{name:"Name",field:"name",key:"error.name",path:"error.name"},{name:"Message",field:"message",key:"error.message",path:"error.message"}]},{name:"Navigator",field:"navigator",key:"navigator",path:"navigator",children:[{name:"Language",field:"language",key:"navigator.language",path:"navigator.language"},{name:"User Agent",field:"userAgent",key:"navigator.userAgent",path:"navigator.userAgent"}]},{name:"Route",field:"route",key:"route",path:"route",children:[{name:"Full Path",field:"fullPath",key:"route.fullPath",path:"route.fullPath"},{name:"Hash",field:"hash",key:"route.hash",path:"route.hash"},{name:"Name",field:"name",key:"route.name",path:"route.name"},{name:"Path",field:"path",key:"route.path",path:"route.path"},{name:"Query",field:"query",key:"route.query",path:"route.query"}]},{name:"User",field:"user",key:"user",path:"user",children:[{name:"ID",field:"id",key:"user.id",path:"user.id"},{name:"First Name",field:"first_name",key:"user.first_name",path:"user.first_name"},{name:"Last Name",field:"last_name",key:"user.last_name",path:"user.last_name"},{name:"Status",field:"status",key:"user.status",path:"user.status"},{name:"Title",field:"title",key:"user.title",path:"user.title"},{name:"Description",field:"description",key:"user.description",path:"user.description"},{name:"Location",field:"location",key:"user.location",path:"user.location"}]},{name:"Role",field:"role",key:"role",path:"role",children:[{name:"ID",field:"id",key:"role.id",path:"role.id"},{name:"Name",field:"name",key:"role.name",path:"role.name"}]}]},width:"full"},{field:"map_divider",interface:"presentation-divider",options:{icon:"map",title:"$t:fields.directus_settings.mapping"},special:["alias","no-data"],width:"full"},{field:"mapbox_key",interface:"input",options:{icon:"key",title:"$t:field_options.directus_settings.mapbox_key",placeholder:"$t:field_options.directus_settings.mapbox_placeholder",iconLeft:"vpn_key",font:"monospace"},width:"full"},{field:"basemaps",interface:"list",special:["cast-json"],options:{template:"{{name}}",fields:[{field:"name",name:"$t:name",schema:{is_nullable:!1},meta:{interface:"text-input",required:!0,options:{placeholder:"$t:field_options.directus_settings.basemaps_name_placeholder"}}},{field:"type",name:"$t:type",meta:{interface:"select-dropdown",options:{choices:[{value:"raster",text:"$t:field_options.directus_settings.basemaps_raster"},{value:"tile",text:"$t:field_options.directus_settings.basemaps_tile"},{value:"style",text:"$t:field_options.directus_settings.basemaps_style"}]}}},{field:"url",name:"$t:url",schema:{is_nullable:!1},meta:{interface:"text-input",options:{placeholder:"http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"}}},{field:"tileSize",name:"$t:tile_size",type:"integer",schema:{is_nullable:!0},meta:{interface:"input",options:{placeholder:"512"},conditions:[{name:"typeNeqRaster",rule:{type:{_neq:"raster"}},hidden:!0}]}},{field:"attribution",name:"$t:fields.directus_settings.attribution",type:"string",schema:{is_nullable:!0},meta:{interface:"input",options:{placeholder:"$t:fields.directus_settings.attribution_placeholder"}}}]}},{field:"image_editor",interface:"presentation-divider",options:{icon:"image",title:"$t:fields.directus_settings.image_editor"},special:["alias","no-data"],width:"full"},{field:"custom_aspect_ratios",interface:"list",special:["cast-json"],options:{template:"{{text}}",fields:[{field:"text",name:"$t:text",type:"string",meta:{interface:"text-input",width:"half",required:!0,options:{placeholder:"$t:text"}}},{field:"value",name:"$t:value",type:"float",meta:{interface:"input",width:"half",required:!0,options:{placeholder:"$t:value"}}}]}}]};var y$1={table:"directus_users",fields:[{field:"first_name",interface:"input",options:{iconRight:"account_circle"},width:"half"},{field:"last_name",interface:"input",options:{iconRight:"account_circle"},width:"half"},{field:"email",interface:"input",options:{iconRight:"email"},width:"half"},{field:"password",special:["hash","conceal"],interface:"input-hash",options:{iconRight:"lock",masked:!0},width:"half"},{field:"avatar",interface:"file",width:"full",display:"image"},{field:"location",interface:"input",options:{iconRight:"place"},width:"half"},{field:"title",interface:"input",options:{iconRight:"work"},width:"half"},{field:"description",interface:"input-multiline",width:"full"},{field:"tags",interface:"tags",special:["cast-json"],width:"full",options:{iconRight:"local_offer"},display:"labels",display_options:{choices:null,format:!1}},{field:"preferences_divider",interface:"presentation-divider",options:{icon:"face",title:"$t:fields.directus_users.user_preferences"},special:["alias","no-data"],width:"full"},{field:"language",interface:"system-language",width:"half",options:{includeProjectDefault:!0}},{field:"tfa_secret",interface:"system-mfa-setup",special:["conceal"],width:"half"},{field:"email_notifications",interface:"boolean",width:"half",special:["cast-boolean"]},{field:"theming_divider",interface:"presentation-divider",options:{icon:"palette",title:"$t:theme"},special:["alias","no-data"],width:"full"},{field:"appearance",interface:"select-dropdown",options:{choices:[{value:null,text:"$t:default_sync_with_project"},{value:"auto",text:"$t:appearance_auto"},{value:"light",text:"$t:appearance_light"},{value:"dark",text:"$t:appearance_dark"}]},width:"half"},{field:"theme_light",width:"full",interface:"system-theme",options:{appearance:"light",includeNull:!0}},{field:"theme_light_overrides",width:"full",interface:"system-theme-overrides",options:{appearance:"light"},special:["cast-json"]},{field:"theme_dark",width:"full",interface:"system-theme",options:{appearance:"dark",includeNull:!0}},{field:"theme_dark_overrides",width:"full",interface:"system-theme-overrides",options:{appearance:"dark"},special:["cast-json"]},{field:"admin_divider",interface:"presentation-divider",options:{icon:"verified_user",title:"$t:fields.directus_users.admin_options",color:"var(--theme--danger)"},special:["alias","no-data"],width:"full"},{field:"status",interface:"select-dropdown",options:{choices:[{text:"$t:fields.directus_users.status_draft",value:"draft"},{text:"$t:fields.directus_users.status_invited",value:"invited"},{text:"$t:fields.directus_users.status_unverified",value:"unverified"},{text:"$t:fields.directus_users.status_active",value:"active"},{text:"$t:fields.directus_users.status_suspended",value:"suspended"},{text:"$t:fields.directus_users.status_archived",value:"archived"}]},width:"half"},{field:"role",interface:"select-dropdown-m2o",options:{template:"{{ name }}"},special:["m2o"],width:"half",display:"related-values",display_options:{template:"{{ name }}"}},{field:"token",interface:"system-token",special:["conceal"],width:"full"},{field:"id",special:["uuid"],interface:"input",options:{iconRight:"vpn_key"},width:"full"},{field:"last_page",width:"half"},{field:"last_access",width:"half",display:"datetime",readonly:!0,display_options:{relative:!0}},{field:"provider",width:"half",interface:"select-dropdown",options:{choices:[{text:"$t:default_provider",value:"default"}]}},{field:"external_identifier",width:"half",options:{iconRight:"account_circle"},interface:"input"},{field:"auth_data",hidden:!0}]};var w$1={table:"directus_webhooks",fields:[{field:"id",hidden:!0},{field:"name",interface:"input",options:{iconRight:"title"},width:"full"},{field:"method",interface:"select-dropdown",display:"labels",display_options:{choices:[{value:"POST",foreground:"var(--theme--primary)",background:"var(--theme--primary-subdued)"},{value:"GET",foreground:"var(--theme--secondary)",background:"var(--secondary-25)"}],format:!1},options:{choices:["GET","POST"]},width:"half"},{field:"url",interface:"input",options:{iconRight:"link"},width:"half"},{field:"status",interface:"select-dropdown",display:"labels",display_options:{showAsDot:!0,choices:[{text:"$t:field_options.directus_webhooks.status_options_active",value:"active",foreground:"var(--theme--primary-background)",background:"var(--theme--primary)"},{text:"$t:field_options.directus_webhooks.status_options_inactive",value:"inactive",foreground:"var(--theme--foreground)",background:"var(--background-normal-alt)"}]},options:{choices:[{text:"$t:field_options.directus_webhooks.status_options_active",value:"active"},{text:"$t:field_options.directus_webhooks.status_options_inactive",value:"inactive"}]},width:"half"},{field:"data",interface:"boolean",options:{label:"$t:fields.directus_webhooks.data_label"},special:["cast-boolean"],width:"half",display:"boolean"},{field:"headers",special:["cast-json"],interface:"list",options:{template:"{{ header }}: {{ value }}",addLabel:"$t:field_options.directus_webhooks.headers.add",fields:[{field:"header",name:"$t:field_options.directus_webhooks.headers.header",type:"string",meta:{interface:"input",width:"half"}},{field:"value",name:"$t:field_options.directus_webhooks.headers.value",type:"string",meta:{interface:"input",width:"half"}}]},width:"full"},{field:"triggers_divider",interface:"presentation-divider",options:{icon:"api",title:"$t:fields.directus_webhooks.triggers"},special:["alias","no-data"],width:"full"},{field:"actions",interface:"select-multiple-checkbox",options:{choices:[{text:"$t:create",value:"create"},{text:"$t:update",value:"update"},{text:"$t:delete_label",value:"delete"}]},special:["cast-csv"],width:"full",display:"labels",display_options:{choices:[{text:"$t:create",value:"create",foreground:"var(--theme--primary)",background:"var(--theme--primary-subdued)"},{text:"$t:update",value:"update",foreground:"var(--blue)",background:"var(--blue-25)"},{text:"$t:delete_label",value:"delete",foreground:"var(--theme--danger)",background:"var(--danger-25)"},{text:"$t:login",value:"login",foreground:"var(--purple)",background:"var(--purple-25)"}]}},{field:"collections",interface:"system-collections",special:["cast-csv"],width:"full",display:"labels",display_options:{choices:null,format:!1}},{field:"was_active_before_deprecation",hidden:!0},{field:"migrated_flow",hidden:!0}]};var v={table:"directus_dashboards",fields:[{field:"id",special:["uuid"]},{field:"name"},{field:"icon"},{field:"panels",special:["o2m"]},{field:"date_created",special:["date-created","cast-timestamp"]},{field:"user_created",special:["user-created"]},{field:"note"},{field:"color"}]};var b={table:"directus_panels",fields:[{field:"id",special:["uuid"]},{field:"name"},{field:"icon"},{field:"color"},{field:"note"},{field:"type"},{field:"show_header",special:["cast-boolean"]},{field:"position_x"},{field:"position_y"},{field:"width"},{field:"height"},{field:"options",special:["cast-json"]},{field:"date_created",special:["date-created","cast-timestamp"]},{field:"user_created",special:["user-created"]},{field:"dashboard"}]};var $={table:"directus_notifications",fields:[{field:"id"},{field:"timestamp",special:["date-created","cast-timestamp"]},{field:"status"},{field:"recipient"},{field:"sender"},{field:"subject"},{field:"message"},{field:"collection"},{field:"item"}]};var k={table:"directus_shares",fields:[{field:"id",special:["uuid"],readonly:!0,hidden:!0},{field:"name"},{field:"collection",width:"half",hidden:!0},{field:"item",width:"half",hidden:!0},{field:"role",interface:"select-dropdown-m2o",width:"half",options:{template:"{{name}}",filter:{admin_access:{_eq:!1}}}},{field:"password",special:["hash","conceal"],interface:"input-hash",options:{iconRight:"lock",masked:!0},width:"half",note:"$t:shared_leave_blank_for_passwordless_access"},{field:"date_start",width:"half",note:"$t:shared_leave_blank_for_unlimited"},{field:"date_end",width:"half",note:"$t:shared_leave_blank_for_unlimited"},{field:"max_uses",width:"half",note:"$t:shared_leave_blank_for_unlimited"},{field:"times_used",width:"half",readonly:!0},{field:"date_created",special:["date-created","cast-timestamp"],width:"half",readonly:!0,conditions:[{name:"notCreatedYet",rule:{id:{_null:!0}},hidden:!0}]},{field:"user_created",special:["user-created"],interface:"select-dropdown-m2o",width:"half",display:"user",options:{template:"{{avatar.$thumbnail}} {{first_name}} {{last_name}}"},readonly:!0,conditions:[{name:"notCreatedYet",rule:{id:{_null:!0}},hidden:!0}]}]};var x={table:"directus_flows",fields:[{field:"id",special:["uuid"]},{field:"name"},{field:"icon"},{field:"color"},{field:"description"},{field:"status"},{field:"trigger"},{field:"accountability"},{field:"options",special:["cast-json"]},{field:"operation"},{field:"operations",special:["o2m"]},{field:"date_created",special:["date-created"]},{field:"user_created",special:["user-created"]}]};var R={table:"directus_operations",fields:[{field:"id",special:["uuid"]},{field:"name"},{field:"key"},{field:"type"},{field:"position_x"},{field:"position_y"},{field:"options",special:["cast-json"]},{field:"resolve"},{field:"reject"},{field:"flow"},{field:"date_created",special:["date-created"]},{field:"user_created",special:["user-created"]}]};var j={table:"directus_translations",fields:[{field:"id",hidden:!0,sort:1,special:["uuid"]},{field:"key",width:"half",sort:2,required:!0,interface:"input",options:{font:"monospace",placeholder:"$t:translation_key_placeholder"}},{field:"language",interface:"system-language",width:"half",sort:3,required:!0},{field:"value",interface:"input-multiline",sort:4,required:!0,options:{placeholder:"$t:enter_a_value"}}]};var F={table:"directus_versions",fields:[{field:"id",special:["uuid"],readonly:!0,hidden:!0},{field:"key"},{field:"name"},{field:"collection"},{field:"item"},{field:"hash",readonly:!0,hidden:!0},{field:"date_created",special:["date-created","cast-timestamp"]},{field:"date_updated",special:["date-updated","cast-timestamp"]},{field:"user_created",special:["user-created"]},{field:"user_updated",special:["user-updated"]}]};var q={table:"directus_extensions",fields:[{collection:"directus_extensions",field:"id",special:["uuid"]},{collection:"directus_extensions",field:"folder"},{collection:"directus_extensions",field:"source"},{collection:"directus_extensions",field:"bundle"},{collection:"directus_extensions",field:"enabled",special:["cast-boolean"]}]};var ce=[];e(a);e(s$1);e(n);e(d$1);e(r);e(c);e(f);e(u$f);e(p);e(_);e(h$1);e(m$1);e(g);e(y$1);e(w$1);e(v);e(b);e($);e(k);e(x);e(R);e(j);e(F);e(q);function e(i){let{fields:P,table:U}=i;P.forEach((T,S)=>{ce.push({system:!0,...o,...T,collection:U,sort:S+1});});}var E=[{collection:"directus_collections",action:"read"},{collection:"directus_fields",action:"read"},{collection:"directus_permissions",action:"read",permissions:{role:{_eq:"$CURRENT_ROLE"}}},{collection:"directus_relations",action:"read"}];var N=[{collection:"directus_activity",action:"read",permissions:{user:{_eq:"$CURRENT_USER"}}},{collection:"directus_activity",action:"create",validation:{comment:{_nnull:!0}}},{collection:"directus_presets",action:"read",permissions:{_or:[{user:{_eq:"$CURRENT_USER"}},{_and:[{user:{_null:!0}},{role:{_eq:"$CURRENT_ROLE"}}]},{_and:[{user:{_null:!0}},{role:{_null:!0}}]}]}},{collection:"directus_presets",action:"create",validation:{user:{_eq:"$CURRENT_USER"}}},{collection:"directus_presets",action:"update",permissions:{user:{_eq:"$CURRENT_USER"}}},{collection:"directus_presets",action:"delete",permissions:{user:{_eq:"$CURRENT_USER"}}},{collection:"directus_roles",action:"read",permissions:{id:{_eq:"$CURRENT_ROLE"}}},{collection:"directus_settings",action:"read"},{collection:"directus_translations",action:"read"},{collection:"directus_notifications",action:"read",permissions:{recipient:{_eq:"$CURRENT_USER"}}},{collection:"directus_notifications",action:"update",permissions:{recipient:{_eq:"$CURRENT_USER"}},fields:["status"]},{collection:"directus_shares",action:"read",permissions:{user_created:{_eq:"$CURRENT_USER"}}},{collection:"directus_users",action:"read",permissions:{id:{_eq:"$CURRENT_USER"}},fields:["id","first_name","last_name","last_page","email","password","location","title","description","tags","preferences_divider","avatar","language","appearance","theme_light","theme_dark","tfa_secret","status","role"]}];var C={role:null,permissions:{},validation:null,presets:null,fields:["*"],system:!0},pe=E.map(i=>({...C,...i}));[...pe,...N].map(i=>({...C,...i})); // shared/abbreviate-number.ts // shared/parse-json.ts function parseJSON(input) { if (String(input).includes("__proto__")) { return JSON.parse(input, noproto); } return JSON.parse(input); } function noproto(key, value) { if (key !== "__proto__") { return value; } } BaseJoi.extend({ type: "string", base: BaseJoi.string(), messages: { "string.contains": "{{#label}} must contain [{{#substring}}]", "string.icontains": "{{#label}} must contain case insensitive [{{#substring}}]", "string.ncontains": "{{#label}} can't contain [{{#substring}}]" }, rules: { contains: { args: [ { name: "substring", ref: true, assert: (val) => typeof val === "string", message: "must be a string" } ], method(substring) { return this.$_addRule({ name: "contains", args: { substring } }); }, validate(value, helpers, { substring }) { if (value.includes(substring) === false) { return helpers.error("string.contains", { substring }); } return value; } }, icontains: { args: [ { name: "substring", ref: true, assert: (val) => typeof val === "string", message: "must be a string" } ], method(substring) { return this.$_addRule({ name: "icontains", args: { substring } }); }, validate(value, helpers, { substring }) { if (value.toLowerCase().includes(substring.toLowerCase()) === false) { return helpers.error("string.icontains", { substring }); } return value; } }, ncontains: { args: [ { name: "substring", ref: true, assert: (val) => typeof val === "string", message: "must be a string" } ], method(substring) { return this.$_addRule({ name: "ncontains", args: { substring } }); }, validate(value, helpers, { substring }) { if (value.includes(substring) === true) { return helpers.error("string.ncontains", { substring }); } return value; } } } }); // shared/to-array.ts function toArray$1(val) { if (typeof val === "string") { return val.split(","); } return Array.isArray(val) ? val : [val]; } var src$1 = {exports: {}}; var cjs = {}; var decrypt$8 = {}; var decrypt$7 = {}; var base64url$9 = {}; var buffer_utils = {}; var digest$1 = {}; Object.defineProperty(digest$1, "__esModule", { value: true }); const crypto_1$h = require$$0$3; const digest = (algorithm, data) => (0, crypto_1$h.createHash)(algorithm).update(data).digest(); digest$1.default = digest; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.concatKdf = exports.lengthAndInput = exports.uint32be = exports.uint64be = exports.p2s = exports.concat = exports.decoder = exports.encoder = void 0; const digest_js_1 = digest$1; exports.encoder = new TextEncoder(); exports.decoder = new TextDecoder(); const MAX_INT32 = 2 ** 32; function concat(...buffers) { const size = buffers.reduce((acc, { length }) => acc + length, 0); const buf = new Uint8Array(size); let i = 0; buffers.forEach((buffer) => { buf.set(buffer, i); i += buffer.length; }); return buf; } exports.concat = concat; function p2s(alg, p2sInput) { return concat(exports.encoder.encode(alg), new Uint8Array([0]), p2sInput); } exports.p2s = p2s; function writeUInt32BE(buf, value, offset) { if (value < 0 || value >= MAX_INT32) { throw new RangeError(`value must be >= 0 and <= ${MAX_INT32 - 1}. Received ${value}`); } buf.set([value >>> 24, value >>> 16, value >>> 8, value & 0xff], offset); } function uint64be(value) { const high = Math.floor(value / MAX_INT32); const low = value % MAX_INT32; const buf = new Uint8Array(8); writeUInt32BE(buf, high, 0); writeUInt32BE(buf, low, 4); return buf; } exports.uint64be = uint64be; function uint32be(value) { const buf = new Uint8Array(4); writeUInt32BE(buf, value); return buf; } exports.uint32be = uint32be; function lengthAndInput(input) { return concat(uint32be(input.length), input); } exports.lengthAndInput = lengthAndInput; async function concatKdf(secret, bits, value) { const iterations = Math.ceil((bits >> 3) / 32); const res = new Uint8Array(iterations * 32); for (let iter = 0; iter < iterations; iter++) { const buf = new Uint8Array(4 + secret.length + value.length); buf.set(uint32be(iter + 1)); buf.set(secret, 4); buf.set(value, 4 + secret.length); res.set(await (0, digest_js_1.default)('sha256', buf), iter * 32); } return res.slice(0, bits >> 3); } exports.concatKdf = concatKdf; } (buffer_utils)); Object.defineProperty(base64url$9, "__esModule", { value: true }); base64url$9.decode = base64url$9.encode = base64url$9.encodeBase64 = base64url$9.decodeBase64 = void 0; const buffer_1$4 = require$$0$4; const buffer_utils_js_1$j = buffer_utils; function normalize$1(input) { let encoded = input; if (encoded instanceof Uint8Array) { encoded = buffer_utils_js_1$j.decoder.decode(encoded); } return encoded; } if (buffer_1$4.Buffer.isEncoding('base64url')) { base64url$9.encode = (input) => buffer_1$4.Buffer.from(input).toString('base64url'); } else { base64url$9.encode = (input) => buffer_1$4.Buffer.from(input).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); } const decodeBase64 = (input) => buffer_1$4.Buffer.from(input, 'base64'); base64url$9.decodeBase64 = decodeBase64; const encodeBase64 = (input) => buffer_1$4.Buffer.from(input).toString('base64'); base64url$9.encodeBase64 = encodeBase64; const decode$3 = (input) => buffer_1$4.Buffer.from(normalize$1(input), 'base64'); base64url$9.decode = decode$3; var decrypt$6 = {}; var check_iv_length = {}; var errors$5 = {}; Object.defineProperty(errors$5, "__esModule", { value: true }); errors$5.JWSSignatureVerificationFailed = errors$5.JWKSTimeout = errors$5.JWKSMultipleMatchingKeys = errors$5.JWKSNoMatchingKey = errors$5.JWKSInvalid = errors$5.JWKInvalid = errors$5.JWTInvalid = errors$5.JWSInvalid = errors$5.JWEInvalid = errors$5.JWEDecompressionFailed = errors$5.JWEDecryptionFailed = errors$5.JOSENotSupported = errors$5.JOSEAlgNotAllowed = errors$5.JWTExpired = errors$5.JWTClaimValidationFailed = errors$5.JOSEError = void 0; class JOSEError extends Error { static get code() { return 'ERR_JOSE_GENERIC'; } constructor(message) { var _a; super(message); this.code = 'ERR_JOSE_GENERIC'; this.name = this.constructor.name; (_a = Error.captureStackTrace) === null || _a === void 0 ? void 0 : _a.call(Error, this, this.constructor); } } errors$5.JOSEError = JOSEError; class JWTClaimValidationFailed extends JOSEError { static get code() { return 'ERR_JWT_CLAIM_VALIDATION_FAILED'; } constructor(message, claim = 'unspecified', reason = 'unspecified') { super(message); this.code = 'ERR_JWT_CLAIM_VALIDATION_FAILED'; this.claim = claim; this.reason = reason; } } errors$5.JWTClaimValidationFailed = JWTClaimValidationFailed; class JWTExpired extends JOSEError { static get code() { return 'ERR_JWT_EXPIRED'; } constructor(message, claim = 'unspecified', reason = 'unspecified') { super(message); this.code = 'ERR_JWT_EXPIRED'; this.claim = claim; this.reason = reason; } } errors$5.JWTExpired = JWTExpired; class JOSEAlgNotAllowed extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JOSE_ALG_NOT_ALLOWED'; } static get code() { return 'ERR_JOSE_ALG_NOT_ALLOWED'; } } errors$5.JOSEAlgNotAllowed = JOSEAlgNotAllowed; class JOSENotSupported extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JOSE_NOT_SUPPORTED'; } static get code() { return 'ERR_JOSE_NOT_SUPPORTED'; } } errors$5.JOSENotSupported = JOSENotSupported; class JWEDecryptionFailed extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWE_DECRYPTION_FAILED'; this.message = 'decryption operation failed'; } static get code() { return 'ERR_JWE_DECRYPTION_FAILED'; } } errors$5.JWEDecryptionFailed = JWEDecryptionFailed; class JWEDecompressionFailed extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWE_DECOMPRESSION_FAILED'; this.message = 'decompression operation failed'; } static get code() { return 'ERR_JWE_DECOMPRESSION_FAILED'; } } errors$5.JWEDecompressionFailed = JWEDecompressionFailed; class JWEInvalid extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWE_INVALID'; } static get code() { return 'ERR_JWE_INVALID'; } } errors$5.JWEInvalid = JWEInvalid; class JWSInvalid extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWS_INVALID'; } static get code() { return 'ERR_JWS_INVALID'; } } errors$5.JWSInvalid = JWSInvalid; class JWTInvalid extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWT_INVALID'; } static get code() { return 'ERR_JWT_INVALID'; } } errors$5.JWTInvalid = JWTInvalid; class JWKInvalid extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWK_INVALID'; } static get code() { return 'ERR_JWK_INVALID'; } } errors$5.JWKInvalid = JWKInvalid; class JWKSInvalid extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWKS_INVALID'; } static get code() { return 'ERR_JWKS_INVALID'; } } errors$5.JWKSInvalid = JWKSInvalid; class JWKSNoMatchingKey extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWKS_NO_MATCHING_KEY'; this.message = 'no applicable key found in the JSON Web Key Set'; } static get code() { return 'ERR_JWKS_NO_MATCHING_KEY'; } } errors$5.JWKSNoMatchingKey = JWKSNoMatchingKey; class JWKSMultipleMatchingKeys extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS'; this.message = 'multiple matching keys found in the JSON Web Key Set'; } static get code() { return 'ERR_JWKS_MULTIPLE_MATCHING_KEYS'; } } errors$5.JWKSMultipleMatchingKeys = JWKSMultipleMatchingKeys; class JWKSTimeout extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWKS_TIMEOUT'; this.message = 'request timed out'; } static get code() { return 'ERR_JWKS_TIMEOUT'; } } errors$5.JWKSTimeout = JWKSTimeout; class JWSSignatureVerificationFailed extends JOSEError { constructor() { super(...arguments); this.code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED'; this.message = 'signature verification failed'; } static get code() { return 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED'; } } errors$5.JWSSignatureVerificationFailed = JWSSignatureVerificationFailed; var iv = {}; var random$4 = {}; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var crypto_1 = require$$0$3; Object.defineProperty(exports, "default", { enumerable: true, get: function () { return crypto_1.randomFillSync; } }); } (random$4)); Object.defineProperty(iv, "__esModule", { value: true }); iv.bitLength = void 0; const errors_js_1$E = errors$5; const random_js_1$3 = random$4; function bitLength$1(alg) { switch (alg) { case 'A128GCM': case 'A128GCMKW': case 'A192GCM': case 'A192GCMKW': case 'A256GCM': case 'A256GCMKW': return 96; case 'A128CBC-HS256': case 'A192CBC-HS384': case 'A256CBC-HS512': return 128; default: throw new errors_js_1$E.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`); } } iv.bitLength = bitLength$1; iv.default = (alg) => (0, random_js_1$3.default)(new Uint8Array(bitLength$1(alg) >> 3)); Object.defineProperty(check_iv_length, "__esModule", { value: true }); const errors_js_1$D = errors$5; const iv_js_1$1 = iv; const checkIvLength = (enc, iv) => { if (iv.length << 3 !== (0, iv_js_1$1.bitLength)(enc)) { throw new errors_js_1$D.JWEInvalid('Invalid Initialization Vector length'); } }; check_iv_length.default = checkIvLength; var check_cek_length = {}; var is_key_object$1 = {}; Object.defineProperty(is_key_object$1, "__esModule", { value: true }); const crypto_1$g = require$$0$3; const util$8 = require$$1; is_key_object$1.default = util$8.types.isKeyObject ? (obj) => util$8.types.isKeyObject(obj) : (obj) => obj != null && obj instanceof crypto_1$g.KeyObject; Object.defineProperty(check_cek_length, "__esModule", { value: true }); const errors_js_1$C = errors$5; const is_key_object_js_1$9 = is_key_object$1; const checkCekLength = (enc, cek) => { let expected; switch (enc) { case 'A128CBC-HS256': case 'A192CBC-HS384': case 'A256CBC-HS512': expected = parseInt(enc.slice(-3), 10); break; case 'A128GCM': case 'A192GCM': case 'A256GCM': expected = parseInt(enc.slice(1, 4), 10); break; default: throw new errors_js_1$C.JOSENotSupported(`Content Encryption Algorithm ${enc} is not supported either by JOSE or your javascript runtime`); } if (cek instanceof Uint8Array) { const actual = cek.byteLength << 3; if (actual !== expected) { throw new errors_js_1$C.JWEInvalid(`Invalid Content Encryption Key length. Expected ${expected} bits, got ${actual} bits`); } return; } if ((0, is_key_object_js_1$9.default)(cek) && cek.type === 'secret') { const actual = cek.symmetricKeySize << 3; if (actual !== expected) { throw new errors_js_1$C.JWEInvalid(`Invalid Content Encryption Key length. Expected ${expected} bits, got ${actual} bits`); } return; } throw new TypeError('Invalid Content Encryption Key type'); }; check_cek_length.default = checkCekLength; var timing_safe_equal = {}; Object.defineProperty(timing_safe_equal, "__esModule", { value: true }); const crypto_1$f = require$$0$3; const timingSafeEqual = crypto_1$f.timingSafeEqual; timing_safe_equal.default = timingSafeEqual; var cbc_tag = {}; Object.defineProperty(cbc_tag, "__esModule", { value: true }); const crypto_1$e = require$$0$3; const buffer_utils_js_1$i = buffer_utils; function cbcTag(aad, iv, ciphertext, macSize, macKey, keySize) { const macData = (0, buffer_utils_js_1$i.concat)(aad, iv, ciphertext, (0, buffer_utils_js_1$i.uint64be)(aad.length << 3)); const hmac = (0, crypto_1$e.createHmac)(`sha${macSize}`, macKey); hmac.update(macData); return hmac.digest().slice(0, keySize >> 3); } cbc_tag.default = cbcTag; var webcrypto$1 = {}; Object.defineProperty(webcrypto$1, "__esModule", { value: true }); webcrypto$1.isCryptoKey = void 0; const crypto$7 = require$$0$3; const util$7 = require$$1; const webcrypto = crypto$7.webcrypto; webcrypto$1.default = webcrypto; webcrypto$1.isCryptoKey = util$7.types.isCryptoKey ? (key) => util$7.types.isCryptoKey(key) : (key) => false; var crypto_key = {}; Object.defineProperty(crypto_key, "__esModule", { value: true }); crypto_key.checkEncCryptoKey = crypto_key.checkSigCryptoKey = void 0; function unusable(name, prop = 'algorithm.name') { return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`); } function isAlgorithm(algorithm, name) { return algorithm.name === name; } function getHashLength(hash) { return parseInt(hash.name.slice(4), 10); } function getNamedCurve(alg) { switch (alg) { case 'ES256': return 'P-256'; case 'ES384': return 'P-384'; case 'ES512': return 'P-521'; default: throw new Error('unreachable'); } } function checkUsage(key, usages) { if (usages.length && !usages.some((expected) => key.usages.includes(expected))) { let msg = 'CryptoKey does not support this operation, its usages must include '; if (usages.length > 2) { const last = usages.pop(); msg += `one of ${usages.join(', ')}, or ${last}.`; } else if (usages.length === 2) { msg += `one of ${usages[0]} or ${usages[1]}.`; } else { msg += `${usages[0]}.`; } throw new TypeError(msg); } } function checkSigCryptoKey(key, alg, ...usages) { switch (alg) { case 'HS256': case 'HS384': case 'HS512': { if (!isAlgorithm(key.algorithm, 'HMAC')) throw unusable('HMAC'); const expected = parseInt(alg.slice(2), 10); const actual = getHashLength(key.algorithm.hash); if (actual !== expected) throw unusable(`SHA-${expected}`, 'algorithm.hash'); break; } case 'RS256': case 'RS384': case 'RS512': { if (!isAlgorithm(key.algorithm, 'RSASSA-PKCS1-v1_5')) throw unusable('RSASSA-PKCS1-v1_5'); const expected = parseInt(alg.slice(2), 10); const actual = getHashLength(key.algorithm.hash); if (actual !== expected) throw unusable(`SHA-${expected}`, 'algorithm.hash'); break; } case 'PS256': case 'PS384': case 'PS512': { if (!isAlgorithm(key.algorithm, 'RSA-PSS')) throw unusable('RSA-PSS'); const expected = parseInt(alg.slice(2), 10); const actual = getHashLength(key.algorithm.hash); if (actual !== expected) throw unusable(`SHA-${expected}`, 'algorithm.hash'); break; } case 'EdDSA': { if (key.algorithm.name !== 'Ed25519' && key.algorithm.name !== 'Ed448') { throw unusable('Ed25519 or Ed448'); } break; } case 'ES256': case 'ES384': case 'ES512': { if (!isAlgorithm(key.algorithm, 'ECDSA')) throw unusable('ECDSA'); const expected = getNamedCurve(alg); const actual = key.algorithm.namedCurve; if (actual !== expected) throw unusable(expected, 'algorithm.namedCurve'); break; } default: throw new TypeError('CryptoKey does not support this operation'); } checkUsage(key, usages); } crypto_key.checkSigCryptoKey = checkSigCryptoKey; function checkEncCryptoKey(key, alg, ...usages) { switch (alg) { case 'A128GCM': case 'A192GCM': case 'A256GCM': { if (!isAlgorithm(key.algorithm, 'AES-GCM')) throw unusable('AES-GCM'); const expected = parseInt(alg.slice(1, 4), 10); const actual = key.algorithm.length; if (actual !== expected) throw unusable(expected, 'algorithm.length'); break; } case 'A128KW': case 'A192KW': case 'A256KW': { if (!isAlgorithm(key.algorithm, 'AES-KW')) throw unusable('AES-KW'); const expected = parseInt(alg.slice(1, 4), 10); const actual = key.algorithm.length; if (actual !== expected) throw unusable(expected, 'algorithm.length'); break; } case 'ECDH': { switch (key.algorithm.name) { case 'ECDH': case 'X25519': case 'X448': break; default: throw unusable('ECDH, X25519, or X448'); } break; } case 'PBES2-HS256+A128KW': case 'PBES2-HS384+A192KW': case 'PBES2-HS512+A256KW': if (!isAlgorithm(key.algorithm, 'PBKDF2')) throw unusable('PBKDF2'); break; case 'RSA-OAEP': case 'RSA-OAEP-256': case 'RSA-OAEP-384': case 'RSA-OAEP-512': { if (!isAlgorithm(key.algorithm, 'RSA-OAEP')) throw unusable('RSA-OAEP'); const expected = parseInt(alg.slice(9), 10) || 1; const actual = getHashLength(key.algorithm.hash); if (actual !== expected) throw unusable(`SHA-${expected}`, 'algorithm.hash'); break; } default: throw new TypeError('CryptoKey does not support this operation'); } checkUsage(key, usages); } crypto_key.checkEncCryptoKey = checkEncCryptoKey; var invalid_key_input = {}; Object.defineProperty(invalid_key_input, "__esModule", { value: true }); invalid_key_input.withAlg = void 0; function message(msg, actual, ...types) { if (types.length > 2) { const last = types.pop(); msg += `one of type ${types.join(', ')}, or ${last}.`; } else if (types.length === 2) { msg += `one of type ${types[0]} or ${types[1]}.`; } else { msg += `of type ${types[0]}.`; } if (actual == null) { msg += ` Received ${actual}`; } else if (typeof actual === 'function' && actual.name) { msg += ` Received function ${actual.name}`; } else if (typeof actual === 'object' && actual != null) { if (actual.constructor && actual.constructor.name) { msg += ` Received an instance of ${actual.constructor.name}`; } } return msg; } invalid_key_input.default = (actual, ...types) => { return message('Key must be ', actual, ...types); }; function withAlg(alg, actual, ...types) { return message(`Key for the ${alg} algorithm must be `, actual, ...types); } invalid_key_input.withAlg = withAlg; var ciphers$1 = {}; Object.defineProperty(ciphers$1, "__esModule", { value: true }); const crypto_1$d = require$$0$3; let ciphers; ciphers$1.default = (algorithm) => { ciphers || (ciphers = new Set((0, crypto_1$d.getCiphers)())); return ciphers.has(algorithm); }; var is_key_like = {}; Object.defineProperty(is_key_like, "__esModule", { value: true }); is_key_like.types = void 0; const webcrypto_js_1$9 = webcrypto$1; const is_key_object_js_1$8 = is_key_object$1; is_key_like.default = (key) => (0, is_key_object_js_1$8.default)(key) || (0, webcrypto_js_1$9.isCryptoKey)(key); const types$3 = ['KeyObject']; is_key_like.types = types$3; if (globalThis.CryptoKey || (webcrypto_js_1$9.default === null || webcrypto_js_1$9.default === void 0 ? void 0 : webcrypto_js_1$9.default.CryptoKey)) { types$3.push('CryptoKey'); } Object.defineProperty(decrypt$6, "__esModule", { value: true }); const crypto_1$c = require$$0$3; const check_iv_length_js_1$1 = check_iv_length; const check_cek_length_js_1$1 = check_cek_length; const buffer_utils_js_1$h = buffer_utils; const errors_js_1$B = errors$5; const timing_safe_equal_js_1 = timing_safe_equal; const cbc_tag_js_1$1 = cbc_tag; const webcrypto_js_1$8 = webcrypto$1; const crypto_key_js_1$6 = crypto_key; const is_key_object_js_1$7 = is_key_object$1; const invalid_key_input_js_1$9 = invalid_key_input; const ciphers_js_1$2 = ciphers$1; const is_key_like_js_1$9 = is_key_like; function cbcDecrypt(enc, cek, ciphertext, iv, tag, aad) { const keySize = parseInt(enc.slice(1, 4), 10); if ((0, is_key_object_js_1$7.default)(cek)) { cek = cek.export(); } const encKey = cek.subarray(keySize >> 3); const macKey = cek.subarray(0, keySize >> 3); const macSize = parseInt(enc.slice(-3), 10); const algorithm = `aes-${keySize}-cbc`; if (!(0, ciphers_js_1$2.default)(algorithm)) { throw new errors_js_1$B.JOSENotSupported(`alg ${enc} is not supported by your javascript runtime`); } const expectedTag = (0, cbc_tag_js_1$1.default)(aad, iv, ciphertext, macSize, macKey, keySize); let macCheckPassed; try { macCheckPassed = (0, timing_safe_equal_js_1.default)(tag, expectedTag); } catch { } if (!macCheckPassed) { throw new errors_js_1$B.JWEDecryptionFailed(); } let plaintext; try { const decipher = (0, crypto_1$c.createDecipheriv)(algorithm, encKey, iv); plaintext = (0, buffer_utils_js_1$h.concat)(decipher.update(ciphertext), decipher.final()); } catch { } if (!plaintext) { throw new errors_js_1$B.JWEDecryptionFailed(); } return plaintext; } function gcmDecrypt(enc, cek, ciphertext, iv, tag, aad) { const keySize = parseInt(enc.slice(1, 4), 10); const algorithm = `aes-${keySize}-gcm`; if (!(0, ciphers_js_1$2.default)(algorithm)) { throw new errors_js_1$B.JOSENotSupported(`alg ${enc} is not supported by your javascript runtime`); } try { const decipher = (0, crypto_1$c.createDecipheriv)(algorithm, cek, iv, { authTagLength: 16 }); decipher.setAuthTag(tag); if (aad.byteLength) { decipher.setAAD(aad, { plaintextLength: ciphertext.length }); } const plaintext = decipher.update(ciphertext); decipher.final(); return plaintext; } catch { throw new errors_js_1$B.JWEDecryptionFailed(); } } const decrypt$5 = (enc, cek, ciphertext, iv, tag, aad) => { let key; if ((0, webcrypto_js_1$8.isCryptoKey)(cek)) { (0, crypto_key_js_1$6.checkEncCryptoKey)(cek, enc, 'decrypt'); key = crypto_1$c.KeyObject.from(cek); } else if (cek instanceof Uint8Array || (0, is_key_object_js_1$7.default)(cek)) { key = cek; } else { throw new TypeError((0, invalid_key_input_js_1$9.default)(cek, ...is_key_like_js_1$9.types, 'Uint8Array')); } (0, check_cek_length_js_1$1.default)(enc, key); (0, check_iv_length_js_1$1.default)(enc, iv); switch (enc) { case 'A128CBC-HS256': case 'A192CBC-HS384': case 'A256CBC-HS512': return cbcDecrypt(enc, key, ciphertext, iv, tag, aad); case 'A128GCM': case 'A192GCM': case 'A256GCM': return gcmDecrypt(enc, key, ciphertext, iv, tag, aad); default: throw new errors_js_1$B.JOSENotSupported('Unsupported JWE Content Encryption Algorithm'); } }; decrypt$6.default = decrypt$5; var zlib = {}; Object.defineProperty(zlib, "__esModule", { value: true }); zlib.deflate = zlib.inflate = void 0; const util_1$6 = require$$1; const zlib_1 = zlib$1; const errors_js_1$A = errors$5; const inflateRaw = (0, util_1$6.promisify)(zlib_1.inflateRaw); const deflateRaw = (0, util_1$6.promisify)(zlib_1.deflateRaw); const inflate = (input) => inflateRaw(input, { maxOutputLength: 250000 }).catch(() => { throw new errors_js_1$A.JWEDecompressionFailed(); }); zlib.inflate = inflate; const deflate = (input) => deflateRaw(input); zlib.deflate = deflate; var is_disjoint = {}; Object.defineProperty(is_disjoint, "__esModule", { value: true }); const isDisjoint = (...headers) => { const sources = headers.filter(Boolean); if (sources.length === 0 || sources.length === 1) { return true; } let acc; for (const header of sources) { const parameters = Object.keys(header); if (!acc || acc.size === 0) { acc = new Set(parameters); continue; } for (const parameter of parameters) { if (acc.has(parameter)) { return false; } acc.add(parameter); } } return true; }; is_disjoint.default = isDisjoint; var is_object = {}; Object.defineProperty(is_object, "__esModule", { value: true }); function isObjectLike$9(value) { return typeof value === 'object' && value !== null; } function isObject$7(input) { if (!isObjectLike$9(input) || Object.prototype.toString.call(input) !== '[object Object]') { return false; } if (Object.getPrototypeOf(input) === null) { return true; } let proto = input; while (Object.getPrototypeOf(proto) !== null) { proto = Object.getPrototypeOf(proto); } return Object.getPrototypeOf(input) === proto; } is_object.default = isObject$7; var decrypt_key_management = {}; var aeskw = {}; Object.defineProperty(aeskw, "__esModule", { value: true }); aeskw.unwrap = aeskw.wrap = void 0; const buffer_1$3 = require$$0$4; const crypto_1$b = require$$0$3; const errors_js_1$z = errors$5; const buffer_utils_js_1$g = buffer_utils; const webcrypto_js_1$7 = webcrypto$1; const crypto_key_js_1$5 = crypto_key; const is_key_object_js_1$6 = is_key_object$1; const invalid_key_input_js_1$8 = invalid_key_input; const ciphers_js_1$1 = ciphers$1; const is_key_like_js_1$8 = is_key_like; function checkKeySize(key, alg) { if (key.symmetricKeySize << 3 !== parseInt(alg.slice(1, 4), 10)) { throw new TypeError(`Invalid key size for alg: ${alg}`); } } function ensureKeyObject$1(key, alg, usage) { if ((0, is_key_object_js_1$6.default)(key)) { return key; } if (key instanceof Uint8Array) { return (0, crypto_1$b.createSecretKey)(key); } if ((0, webcrypto_js_1$7.isCryptoKey)(key)) { (0, crypto_key_js_1$5.checkEncCryptoKey)(key, alg, usage); return crypto_1$b.KeyObject.from(key); } throw new TypeError((0, invalid_key_input_js_1$8.default)(key, ...is_key_like_js_1$8.types, 'Uint8Array')); } const wrap$1 = (alg, key, cek) => { const size = parseInt(alg.slice(1, 4), 10); const algorithm = `aes${size}-wrap`; if (!(0, ciphers_js_1$1.default)(algorithm)) { throw new errors_js_1$z.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`); } const keyObject = ensureKeyObject$1(key, alg, 'wrapKey'); checkKeySize(keyObject, alg); const cipher = (0, crypto_1$b.createCipheriv)(algorithm, keyObject, buffer_1$3.Buffer.alloc(8, 0xa6)); return (0, buffer_utils_js_1$g.concat)(cipher.update(cek), cipher.final()); }; aeskw.wrap = wrap$1; const unwrap$1 = (alg, key, encryptedKey) => { const size = parseInt(alg.slice(1, 4), 10); const algorithm = `aes${size}-wrap`; if (!(0, ciphers_js_1$1.default)(algorithm)) { throw new errors_js_1$z.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`); } const keyObject = ensureKeyObject$1(key, alg, 'unwrapKey'); checkKeySize(keyObject, alg); const cipher = (0, crypto_1$b.createDecipheriv)(algorithm, keyObject, buffer_1$3.Buffer.alloc(8, 0xa6)); return (0, buffer_utils_js_1$g.concat)(cipher.update(encryptedKey), cipher.final()); }; aeskw.unwrap = unwrap$1; var ecdhes = {}; var get_named_curve = {}; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.setCurve = exports.weakMap = void 0; const buffer_1 = require$$0$4; const crypto_1 = require$$0$3; const errors_js_1 = errors$5; const webcrypto_js_1 = webcrypto$1; const is_key_object_js_1 = is_key_object$1; const invalid_key_input_js_1 = invalid_key_input; const is_key_like_js_1 = is_key_like; const p256 = buffer_1.Buffer.from([42, 134, 72, 206, 61, 3, 1, 7]); const p384 = buffer_1.Buffer.from([43, 129, 4, 0, 34]); const p521 = buffer_1.Buffer.from([43, 129, 4, 0, 35]); const secp256k1 = buffer_1.Buffer.from([43, 129, 4, 0, 10]); exports.weakMap = new WeakMap(); const namedCurveToJOSE = (namedCurve) => { switch (namedCurve) { case 'prime256v1': return 'P-256'; case 'secp384r1': return 'P-384'; case 'secp521r1': return 'P-521'; case 'secp256k1': return 'secp256k1'; default: throw new errors_js_1.JOSENotSupported('Unsupported key curve for this operation'); } }; const getNamedCurve = (kee, raw) => { var _a; let key; if ((0, webcrypto_js_1.isCryptoKey)(kee)) { key = crypto_1.KeyObject.from(kee); } else if ((0, is_key_object_js_1.default)(kee)) { key = kee; } else { throw new TypeError((0, invalid_key_input_js_1.default)(kee, ...is_key_like_js_1.types)); } if (key.type === 'secret') { throw new TypeError('only "private" or "public" type keys can be used for this operation'); } switch (key.asymmetricKeyType) { case 'ed25519': case 'ed448': return `Ed${key.asymmetricKeyType.slice(2)}`; case 'x25519': case 'x448': return `X${key.asymmetricKeyType.slice(1)}`; case 'ec': { if (exports.weakMap.has(key)) { return exports.weakMap.get(key); } let namedCurve = (_a = key.asymmetricKeyDetails) === null || _a === void 0 ? void 0 : _a.namedCurve; if (!namedCurve && key.type === 'private') { namedCurve = getNamedCurve((0, crypto_1.createPublicKey)(key), true); } else if (!namedCurve) { const buf = key.export({ format: 'der', type: 'spki' }); const i = buf[1] < 128 ? 14 : 15; const len = buf[i]; const curveOid = buf.slice(i + 1, i + 1 + len); if (curveOid.equals(p256)) { namedCurve = 'prime256v1'; } else if (curveOid.equals(p384)) { namedCurve = 'secp384r1'; } else if (curveOid.equals(p521)) { namedCurve = 'secp521r1'; } else if (curveOid.equals(secp256k1)) { namedCurve = 'secp256k1'; } else { throw new errors_js_1.JOSENotSupported('Unsupported key curve for this operation'); } } if (raw) return namedCurve; const curve = namedCurveToJOSE(namedCurve); exports.weakMap.set(key, curve); return curve; } default: throw new TypeError('Invalid asymmetric key type for this operation'); } }; function setCurve(keyObject, curve) { exports.weakMap.set(keyObject, curve); } exports.setCurve = setCurve; exports.default = getNamedCurve; } (get_named_curve)); Object.defineProperty(ecdhes, "__esModule", { value: true }); ecdhes.ecdhAllowed = ecdhes.generateEpk = ecdhes.deriveKey = void 0; const crypto_1$a = require$$0$3; const util_1$5 = require$$1; const get_named_curve_js_1$3 = get_named_curve; const buffer_utils_js_1$f = buffer_utils; const errors_js_1$y = errors$5; const webcrypto_js_1$6 = webcrypto$1; const crypto_key_js_1$4 = crypto_key; const is_key_object_js_1$5 = is_key_object$1; const invalid_key_input_js_1$7 = invalid_key_input; const is_key_like_js_1$7 = is_key_like; const generateKeyPair$2 = (0, util_1$5.promisify)(crypto_1$a.generateKeyPair); async function deriveKey(publicKee, privateKee, algorithm, keyLength, apu = new Uint8Array(0), apv = new Uint8Array(0)) { let publicKey; if ((0, webcrypto_js_1$6.isCryptoKey)(publicKee)) { (0, crypto_key_js_1$4.checkEncCryptoKey)(publicKee, 'ECDH'); publicKey = crypto_1$a.KeyObject.from(publicKee); } else if ((0, is_key_object_js_1$5.default)(publicKee)) { publicKey = publicKee; } else { throw new TypeError((0, invalid_key_input_js_1$7.default)(publicKee, ...is_key_like_js_1$7.types)); } let privateKey; if ((0, webcrypto_js_1$6.isCryptoKey)(privateKee)) { (0, crypto_key_js_1$4.checkEncCryptoKey)(privateKee, 'ECDH', 'deriveBits'); privateKey = crypto_1$a.KeyObject.from(privateKee); } else if ((0, is_key_object_js_1$5.default)(privateKee)) { privateKey = privateKee; } else { throw new TypeError((0, invalid_key_input_js_1$7.default)(privateKee, ...is_key_like_js_1$7.types)); } const value = (0, buffer_utils_js_1$f.concat)((0, buffer_utils_js_1$f.lengthAndInput)(buffer_utils_js_1$f.encoder.encode(algorithm)), (0, buffer_utils_js_1$f.lengthAndInput)(apu), (0, buffer_utils_js_1$f.lengthAndInput)(apv), (0, buffer_utils_js_1$f.uint32be)(keyLength)); const sharedSecret = (0, crypto_1$a.diffieHellman)({ privateKey, publicKey }); return (0, buffer_utils_js_1$f.concatKdf)(sharedSecret, keyLength, value); } ecdhes.deriveKey = deriveKey; async function generateEpk(kee) { let key; if ((0, webcrypto_js_1$6.isCryptoKey)(kee)) { key = crypto_1$a.KeyObject.from(kee); } else if ((0, is_key_object_js_1$5.default)(kee)) { key = kee; } else { throw new TypeError((0, invalid_key_input_js_1$7.default)(kee, ...is_key_like_js_1$7.types)); } switch (key.asymmetricKeyType) { case 'x25519': return generateKeyPair$2('x25519'); case 'x448': { return generateKeyPair$2('x448'); } case 'ec': { const namedCurve = (0, get_named_curve_js_1$3.default)(key); return generateKeyPair$2('ec', { namedCurve }); } default: throw new errors_js_1$y.JOSENotSupported('Invalid or unsupported EPK'); } } ecdhes.generateEpk = generateEpk; const ecdhAllowed = (key) => ['P-256', 'P-384', 'P-521', 'X25519', 'X448'].includes((0, get_named_curve_js_1$3.default)(key)); ecdhes.ecdhAllowed = ecdhAllowed; var pbes2kw = {}; var check_p2s = {}; Object.defineProperty(check_p2s, "__esModule", { value: true }); const errors_js_1$x = errors$5; function checkP2s(p2s) { if (!(p2s instanceof Uint8Array) || p2s.length < 8) { throw new errors_js_1$x.JWEInvalid('PBES2 Salt Input must be 8 or more octets'); } } check_p2s.default = checkP2s; Object.defineProperty(pbes2kw, "__esModule", { value: true }); pbes2kw.decrypt = pbes2kw.encrypt = void 0; const util_1$4 = require$$1; const crypto_1$9 = require$$0$3; const random_js_1$2 = random$4; const buffer_utils_js_1$e = buffer_utils; const base64url_js_1$d = base64url$9; const aeskw_js_1$2 = aeskw; const check_p2s_js_1 = check_p2s; const webcrypto_js_1$5 = webcrypto$1; const crypto_key_js_1$3 = crypto_key; const is_key_object_js_1$4 = is_key_object$1; const invalid_key_input_js_1$6 = invalid_key_input; const is_key_like_js_1$6 = is_key_like; const pbkdf2 = (0, util_1$4.promisify)(crypto_1$9.pbkdf2); function getPassword(key, alg) { if ((0, is_key_object_js_1$4.default)(key)) { return key.export(); } if (key instanceof Uint8Array) { return key; } if ((0, webcrypto_js_1$5.isCryptoKey)(key)) { (0, crypto_key_js_1$3.checkEncCryptoKey)(key, alg, 'deriveBits', 'deriveKey'); return crypto_1$9.KeyObject.from(key).export(); } throw new TypeError((0, invalid_key_input_js_1$6.default)(key, ...is_key_like_js_1$6.types, 'Uint8Array')); } const encrypt$7 = async (alg, key, cek, p2c = 2048, p2s = (0, random_js_1$2.default)(new Uint8Array(16))) => { (0, check_p2s_js_1.default)(p2s); const salt = (0, buffer_utils_js_1$e.p2s)(alg, p2s); const keylen = parseInt(alg.slice(13, 16), 10) >> 3; const password = getPassword(key, alg); const derivedKey = await pbkdf2(password, salt, p2c, keylen, `sha${alg.slice(8, 11)}`); const encryptedKey = await (0, aeskw_js_1$2.wrap)(alg.slice(-6), derivedKey, cek); return { encryptedKey, p2c, p2s: (0, base64url_js_1$d.encode)(p2s) }; }; pbes2kw.encrypt = encrypt$7; const decrypt$4 = async (alg, key, encryptedKey, p2c, p2s) => { (0, check_p2s_js_1.default)(p2s); const salt = (0, buffer_utils_js_1$e.p2s)(alg, p2s); const keylen = parseInt(alg.slice(13, 16), 10) >> 3; const password = getPassword(key, alg); const derivedKey = await pbkdf2(password, salt, p2c, keylen, `sha${alg.slice(8, 11)}`); return (0, aeskw_js_1$2.unwrap)(alg.slice(-6), derivedKey, encryptedKey); }; pbes2kw.decrypt = decrypt$4; var rsaes = {}; var check_modulus_length = {}; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.setModulusLength = exports.weakMap = void 0; exports.weakMap = new WeakMap(); const getLength = (buf, index) => { let len = buf.readUInt8(1); if ((len & 0x80) === 0) { if (index === 0) { return len; } return getLength(buf.subarray(2 + len), index - 1); } const num = len & 0x7f; len = 0; for (let i = 0; i < num; i++) { len <<= 8; const j = buf.readUInt8(2 + i); len |= j; } if (index === 0) { return len; } return getLength(buf.subarray(2 + len), index - 1); }; const getLengthOfSeqIndex = (sequence, index) => { const len = sequence.readUInt8(1); if ((len & 0x80) === 0) { return getLength(sequence.subarray(2), index); } const num = len & 0x7f; return getLength(sequence.subarray(2 + num), index); }; const getModulusLength = (key) => { var _a, _b; if (exports.weakMap.has(key)) { return exports.weakMap.get(key); } const modulusLength = (_b = (_a = key.asymmetricKeyDetails) === null || _a === void 0 ? void 0 : _a.modulusLength) !== null && _b !== void 0 ? _b : (getLengthOfSeqIndex(key.export({ format: 'der', type: 'pkcs1' }), key.type === 'private' ? 1 : 0) - 1) << 3; exports.weakMap.set(key, modulusLength); return modulusLength; }; const setModulusLength = (keyObject, modulusLength) => { exports.weakMap.set(keyObject, modulusLength); }; exports.setModulusLength = setModulusLength; exports.default = (key, alg) => { if (getModulusLength(key) < 2048) { throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`); } }; } (check_modulus_length)); Object.defineProperty(rsaes, "__esModule", { value: true }); rsaes.decrypt = rsaes.encrypt = void 0; const crypto_1$8 = require$$0$3; const check_modulus_length_js_1$3 = check_modulus_length; const webcrypto_js_1$4 = webcrypto$1; const crypto_key_js_1$2 = crypto_key; const is_key_object_js_1$3 = is_key_object$1; const invalid_key_input_js_1$5 = invalid_key_input; const is_key_like_js_1$5 = is_key_like; const checkKey = (key, alg) => { if (key.asymmetricKeyType !== 'rsa') { throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be rsa'); } (0, check_modulus_length_js_1$3.default)(key, alg); }; const resolvePadding = (alg) => { switch (alg) { case 'RSA-OAEP': case 'RSA-OAEP-256': case 'RSA-OAEP-384': case 'RSA-OAEP-512': return crypto_1$8.constants.RSA_PKCS1_OAEP_PADDING; case 'RSA1_5': return crypto_1$8.constants.RSA_PKCS1_PADDING; default: return undefined; } }; const resolveOaepHash = (alg) => { switch (alg) { case 'RSA-OAEP': return 'sha1'; case 'RSA-OAEP-256': return 'sha256'; case 'RSA-OAEP-384': return 'sha384'; case 'RSA-OAEP-512': return 'sha512'; default: return undefined; } }; function ensureKeyObject(key, alg, ...usages) { if ((0, is_key_object_js_1$3.default)(key)) { return key; } if ((0, webcrypto_js_1$4.isCryptoKey)(key)) { (0, crypto_key_js_1$2.checkEncCryptoKey)(key, alg, ...usages); return crypto_1$8.KeyObject.from(key); } throw new TypeError((0, invalid_key_input_js_1$5.default)(key, ...is_key_like_js_1$5.types)); } const encrypt$6 = (alg, key, cek) => { const padding = resolvePadding(alg); const oaepHash = resolveOaepHash(alg); const keyObject = ensureKeyObject(key, alg, 'wrapKey', 'encrypt'); checkKey(keyObject, alg); return (0, crypto_1$8.publicEncrypt)({ key: keyObject, oaepHash, padding }, cek); }; rsaes.encrypt = encrypt$6; const decrypt$3 = (alg, key, encryptedKey) => { const padding = resolvePadding(alg); const oaepHash = resolveOaepHash(alg); const keyObject = ensureKeyObject(key, alg, 'unwrapKey', 'decrypt'); checkKey(keyObject, alg); return (0, crypto_1$8.privateDecrypt)({ key: keyObject, oaepHash, padding }, encryptedKey); }; rsaes.decrypt = decrypt$3; var cek = {}; Object.defineProperty(cek, "__esModule", { value: true }); cek.bitLength = void 0; const errors_js_1$w = errors$5; const random_js_1$1 = random$4; function bitLength(alg) { switch (alg) { case 'A128GCM': return 128; case 'A192GCM': return 192; case 'A256GCM': case 'A128CBC-HS256': return 256; case 'A192CBC-HS384': return 384; case 'A256CBC-HS512': return 512; default: throw new errors_js_1$w.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`); } } cek.bitLength = bitLength; cek.default = (alg) => (0, random_js_1$1.default)(new Uint8Array(bitLength(alg) >> 3)); var _import = {}; var asn1 = {}; Object.defineProperty(asn1, "__esModule", { value: true }); asn1.fromX509 = asn1.fromSPKI = asn1.fromPKCS8 = asn1.toPKCS8 = asn1.toSPKI = void 0; const crypto_1$7 = require$$0$3; const buffer_1$2 = require$$0$4; const webcrypto_js_1$3 = webcrypto$1; const is_key_object_js_1$2 = is_key_object$1; const invalid_key_input_js_1$4 = invalid_key_input; const is_key_like_js_1$4 = is_key_like; const genericExport = (keyType, keyFormat, key) => { let keyObject; if ((0, webcrypto_js_1$3.isCryptoKey)(key)) { if (!key.extractable) { throw new TypeError('CryptoKey is not extractable'); } keyObject = crypto_1$7.KeyObject.from(key); } else if ((0, is_key_object_js_1$2.default)(key)) { keyObject = key; } else { throw new TypeError((0, invalid_key_input_js_1$4.default)(key, ...is_key_like_js_1$4.types)); } if (keyObject.type !== keyType) { throw new TypeError(`key is not a ${keyType} key`); } return keyObject.export({ format: 'pem', type: keyFormat }); }; const toSPKI = (key) => { return genericExport('public', 'spki', key); }; asn1.toSPKI = toSPKI; const toPKCS8 = (key) => { return genericExport('private', 'pkcs8', key); }; asn1.toPKCS8 = toPKCS8; const fromPKCS8 = (pem) => (0, crypto_1$7.createPrivateKey)({ key: buffer_1$2.Buffer.from(pem.replace(/(?:-----(?:BEGIN|END) PRIVATE KEY-----|\s)/g, ''), 'base64'), type: 'pkcs8', format: 'der', }); asn1.fromPKCS8 = fromPKCS8; const fromSPKI = (pem) => (0, crypto_1$7.createPublicKey)({ key: buffer_1$2.Buffer.from(pem.replace(/(?:-----(?:BEGIN|END) PUBLIC KEY-----|\s)/g, ''), 'base64'), type: 'spki', format: 'der', }); asn1.fromSPKI = fromSPKI; const fromX509 = (pem) => (0, crypto_1$7.createPublicKey)({ key: pem, type: 'spki', format: 'pem', }); asn1.fromX509 = fromX509; var jwk_to_key = {}; var asn1_sequence_encoder = {}; Object.defineProperty(asn1_sequence_encoder, "__esModule", { value: true }); const buffer_1$1 = require$$0$4; const errors_js_1$v = errors$5; const tagInteger$1 = 0x02; const tagBitStr = 0x03; const tagOctStr = 0x04; const tagSequence$1 = 0x30; const bZero = buffer_1$1.Buffer.from([0x00]); const bTagInteger = buffer_1$1.Buffer.from([tagInteger$1]); const bTagBitStr = buffer_1$1.Buffer.from([tagBitStr]); const bTagSequence = buffer_1$1.Buffer.from([tagSequence$1]); const bTagOctStr = buffer_1$1.Buffer.from([tagOctStr]); const encodeLength = (len) => { if (len < 128) return buffer_1$1.Buffer.from([len]); const buffer = buffer_1$1.Buffer.alloc(5); buffer.writeUInt32BE(len, 1); let offset = 1; while (buffer[offset] === 0) offset++; buffer[offset - 1] = 0x80 | (5 - offset); return buffer.slice(offset - 1); }; const oids = new Map([ ['P-256', buffer_1$1.Buffer.from('06 08 2A 86 48 CE 3D 03 01 07'.replace(/ /g, ''), 'hex')], ['secp256k1', buffer_1$1.Buffer.from('06 05 2B 81 04 00 0A'.replace(/ /g, ''), 'hex')], ['P-384', buffer_1$1.Buffer.from('06 05 2B 81 04 00 22'.replace(/ /g, ''), 'hex')], ['P-521', buffer_1$1.Buffer.from('06 05 2B 81 04 00 23'.replace(/ /g, ''), 'hex')], ['ecPublicKey', buffer_1$1.Buffer.from('06 07 2A 86 48 CE 3D 02 01'.replace(/ /g, ''), 'hex')], ['X25519', buffer_1$1.Buffer.from('06 03 2B 65 6E'.replace(/ /g, ''), 'hex')], ['X448', buffer_1$1.Buffer.from('06 03 2B 65 6F'.replace(/ /g, ''), 'hex')], ['Ed25519', buffer_1$1.Buffer.from('06 03 2B 65 70'.replace(/ /g, ''), 'hex')], ['Ed448', buffer_1$1.Buffer.from('06 03 2B 65 71'.replace(/ /g, ''), 'hex')], ]); class DumbAsn1Encoder { constructor() { this.length = 0; this.elements = []; } oidFor(oid) { const bOid = oids.get(oid); if (!bOid) { throw new errors_js_1$v.JOSENotSupported('Invalid or unsupported OID'); } this.elements.push(bOid); this.length += bOid.length; } zero() { this.elements.push(bTagInteger, buffer_1$1.Buffer.from([0x01]), bZero); this.length += 3; } one() { this.elements.push(bTagInteger, buffer_1$1.Buffer.from([0x01]), buffer_1$1.Buffer.from([0x01])); this.length += 3; } unsignedInteger(integer) { if (integer[0] & 0x80) { const len = encodeLength(integer.length + 1); this.elements.push(bTagInteger, len, bZero, integer); this.length += 2 + len.length + integer.length; } else { let i = 0; while (integer[i] === 0 && (integer[i + 1] & 0x80) === 0) i++; const len = encodeLength(integer.length - i); this.elements.push(bTagInteger, encodeLength(integer.length - i), integer.slice(i)); this.length += 1 + len.length + integer.length - i; } } octStr(octStr) { const len = encodeLength(octStr.length); this.elements.push(bTagOctStr, encodeLength(octStr.length), octStr); this.length += 1 + len.length + octStr.length; } bitStr(bitS) { const len = encodeLength(bitS.length + 1); this.elements.push(bTagBitStr, encodeLength(bitS.length + 1), bZero, bitS); this.length += 1 + len.length + bitS.length + 1; } add(seq) { this.elements.push(seq); this.length += seq.length; } end(tag = bTagSequence) { const len = encodeLength(this.length); return buffer_1$1.Buffer.concat([tag, len, ...this.elements], 1 + len.length + this.length); } } asn1_sequence_encoder.default = DumbAsn1Encoder; var flags = {}; Object.defineProperty(flags, "__esModule", { value: true }); flags.jwkImport = flags.jwkExport = flags.rsaPssParams = flags.oneShotCallback = void 0; const [major$4, minor$4] = process.versions.node.split('.').map((str) => parseInt(str, 10)); flags.oneShotCallback = major$4 >= 16 || (major$4 === 15 && minor$4 >= 13); flags.rsaPssParams = !('electron' in process.versions) && (major$4 >= 17 || (major$4 === 16 && minor$4 >= 9)); flags.jwkExport = major$4 >= 16 || (major$4 === 15 && minor$4 >= 9); flags.jwkImport = major$4 >= 16 || (major$4 === 15 && minor$4 >= 12); Object.defineProperty(jwk_to_key, "__esModule", { value: true }); const buffer_1 = require$$0$4; const crypto_1$6 = require$$0$3; const base64url_js_1$c = base64url$9; const errors_js_1$u = errors$5; const get_named_curve_js_1$2 = get_named_curve; const check_modulus_length_js_1$2 = check_modulus_length; const asn1_sequence_encoder_js_1 = asn1_sequence_encoder; const flags_js_1$3 = flags; const parse$9 = (jwk) => { if (flags_js_1$3.jwkImport && jwk.kty !== 'oct') { return jwk.d ? (0, crypto_1$6.createPrivateKey)({ format: 'jwk', key: jwk }) : (0, crypto_1$6.createPublicKey)({ format: 'jwk', key: jwk }); } switch (jwk.kty) { case 'oct': { return (0, crypto_1$6.createSecretKey)((0, base64url_js_1$c.decode)(jwk.k)); } case 'RSA': { const enc = new asn1_sequence_encoder_js_1.default(); const isPrivate = jwk.d !== undefined; const modulus = buffer_1.Buffer.from(jwk.n, 'base64'); const exponent = buffer_1.Buffer.from(jwk.e, 'base64'); if (isPrivate) { enc.zero(); enc.unsignedInteger(modulus); enc.unsignedInteger(exponent); enc.unsignedInteger(buffer_1.Buffer.from(jwk.d, 'base64')); enc.unsignedInteger(buffer_1.Buffer.from(jwk.p, 'base64')); enc.unsignedInteger(buffer_1.Buffer.from(jwk.q, 'base64')); enc.unsignedInteger(buffer_1.Buffer.from(jwk.dp, 'base64')); enc.unsignedInteger(buffer_1.Buffer.from(jwk.dq, 'base64')); enc.unsignedInteger(buffer_1.Buffer.from(jwk.qi, 'base64')); } else { enc.unsignedInteger(modulus); enc.unsignedInteger(exponent); } const der = enc.end(); const createInput = { key: der, format: 'der', type: 'pkcs1', }; const keyObject = isPrivate ? (0, crypto_1$6.createPrivateKey)(createInput) : (0, crypto_1$6.createPublicKey)(createInput); (0, check_modulus_length_js_1$2.setModulusLength)(keyObject, modulus.length << 3); return keyObject; } case 'EC': { const enc = new asn1_sequence_encoder_js_1.default(); const isPrivate = jwk.d !== undefined; const pub = buffer_1.Buffer.concat([ buffer_1.Buffer.alloc(1, 4), buffer_1.Buffer.from(jwk.x, 'base64'), buffer_1.Buffer.from(jwk.y, 'base64'), ]); if (isPrivate) { enc.zero(); const enc$1 = new asn1_sequence_encoder_js_1.default(); enc$1.oidFor('ecPublicKey'); enc$1.oidFor(jwk.crv); enc.add(enc$1.end()); const enc$2 = new asn1_sequence_encoder_js_1.default(); enc$2.one(); enc$2.octStr(buffer_1.Buffer.from(jwk.d, 'base64')); const enc$3 = new asn1_sequence_encoder_js_1.default(); enc$3.bitStr(pub); const f2 = enc$3.end(buffer_1.Buffer.from([0xa1])); enc$2.add(f2); const f = enc$2.end(); const enc$4 = new asn1_sequence_encoder_js_1.default(); enc$4.add(f); const f3 = enc$4.end(buffer_1.Buffer.from([0x04])); enc.add(f3); const der = enc.end(); const keyObject = (0, crypto_1$6.createPrivateKey)({ key: der, format: 'der', type: 'pkcs8' }); (0, get_named_curve_js_1$2.setCurve)(keyObject, jwk.crv); return keyObject; } const enc$1 = new asn1_sequence_encoder_js_1.default(); enc$1.oidFor('ecPublicKey'); enc$1.oidFor(jwk.crv); enc.add(enc$1.end()); enc.bitStr(pub); const der = enc.end(); const keyObject = (0, crypto_1$6.createPublicKey)({ key: der, format: 'der', type: 'spki' }); (0, get_named_curve_js_1$2.setCurve)(keyObject, jwk.crv); return keyObject; } case 'OKP': { const enc = new asn1_sequence_encoder_js_1.default(); const isPrivate = jwk.d !== undefined; if (isPrivate) { enc.zero(); const enc$1 = new asn1_sequence_encoder_js_1.default(); enc$1.oidFor(jwk.crv); enc.add(enc$1.end()); const enc$2 = new asn1_sequence_encoder_js_1.default(); enc$2.octStr(buffer_1.Buffer.from(jwk.d, 'base64')); const f = enc$2.end(buffer_1.Buffer.from([0x04])); enc.add(f); const der = enc.end(); return (0, crypto_1$6.createPrivateKey)({ key: der, format: 'der', type: 'pkcs8' }); } const enc$1 = new asn1_sequence_encoder_js_1.default(); enc$1.oidFor(jwk.crv); enc.add(enc$1.end()); enc.bitStr(buffer_1.Buffer.from(jwk.x, 'base64')); const der = enc.end(); return (0, crypto_1$6.createPublicKey)({ key: der, format: 'der', type: 'spki' }); } default: throw new errors_js_1$u.JOSENotSupported('Invalid or unsupported JWK "kty" (Key Type) Parameter value'); } }; jwk_to_key.default = parse$9; Object.defineProperty(_import, "__esModule", { value: true }); _import.importJWK = _import.importPKCS8 = _import.importX509 = _import.importSPKI = void 0; const base64url_js_1$b = base64url$9; const asn1_js_1$1 = asn1; const jwk_to_key_js_1 = jwk_to_key; const errors_js_1$t = errors$5; const is_object_js_1$c = is_object; async function importSPKI(spki, alg, options) { if (typeof spki !== 'string' || spki.indexOf('-----BEGIN PUBLIC KEY-----') !== 0) { throw new TypeError('"spki" must be SPKI formatted string'); } return (0, asn1_js_1$1.fromSPKI)(spki, alg, options); } _import.importSPKI = importSPKI; async function importX509(x509, alg, options) { if (typeof x509 !== 'string' || x509.indexOf('-----BEGIN CERTIFICATE-----') !== 0) { throw new TypeError('"x509" must be X.509 formatted string'); } return (0, asn1_js_1$1.fromX509)(x509, alg, options); } _import.importX509 = importX509; async function importPKCS8(pkcs8, alg, options) { if (typeof pkcs8 !== 'string' || pkcs8.indexOf('-----BEGIN PRIVATE KEY-----') !== 0) { throw new TypeError('"pkcs8" must be PKCS#8 formatted string'); } return (0, asn1_js_1$1.fromPKCS8)(pkcs8, alg, options); } _import.importPKCS8 = importPKCS8; async function importJWK(jwk, alg, octAsKeyObject) { var _a; if (!(0, is_object_js_1$c.default)(jwk)) { throw new TypeError('JWK must be an object'); } alg || (alg = jwk.alg); switch (jwk.kty) { case 'oct': if (typeof jwk.k !== 'string' || !jwk.k) { throw new TypeError('missing "k" (Key Value) Parameter value'); } octAsKeyObject !== null && octAsKeyObject !== void 0 ? octAsKeyObject : (octAsKeyObject = jwk.ext !== true); if (octAsKeyObject) { return (0, jwk_to_key_js_1.default)({ ...jwk, alg, ext: (_a = jwk.ext) !== null && _a !== void 0 ? _a : false }); } return (0, base64url_js_1$b.decode)(jwk.k); case 'RSA': if (jwk.oth !== undefined) { throw new errors_js_1$t.JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported'); } case 'EC': case 'OKP': return (0, jwk_to_key_js_1.default)({ ...jwk, alg }); default: throw new errors_js_1$t.JOSENotSupported('Unsupported "kty" (Key Type) Parameter value'); } } _import.importJWK = importJWK; var check_key_type = {}; Object.defineProperty(check_key_type, "__esModule", { value: true }); const invalid_key_input_js_1$3 = invalid_key_input; const is_key_like_js_1$3 = is_key_like; const symmetricTypeCheck = (alg, key) => { if (key instanceof Uint8Array) return; if (!(0, is_key_like_js_1$3.default)(key)) { throw new TypeError((0, invalid_key_input_js_1$3.withAlg)(alg, key, ...is_key_like_js_1$3.types, 'Uint8Array')); } if (key.type !== 'secret') { throw new TypeError(`${is_key_like_js_1$3.types.join(' or ')} instances for symmetric algorithms must be of type "secret"`); } }; const asymmetricTypeCheck = (alg, key, usage) => { if (!(0, is_key_like_js_1$3.default)(key)) { throw new TypeError((0, invalid_key_input_js_1$3.withAlg)(alg, key, ...is_key_like_js_1$3.types)); } if (key.type === 'secret') { throw new TypeError(`${is_key_like_js_1$3.types.join(' or ')} instances for asymmetric algorithms must not be of type "secret"`); } if (usage === 'sign' && key.type === 'public') { throw new TypeError(`${is_key_like_js_1$3.types.join(' or ')} instances for asymmetric algorithm signing must be of type "private"`); } if (usage === 'decrypt' && key.type === 'public') { throw new TypeError(`${is_key_like_js_1$3.types.join(' or ')} instances for asymmetric algorithm decryption must be of type "private"`); } if (key.algorithm && usage === 'verify' && key.type === 'private') { throw new TypeError(`${is_key_like_js_1$3.types.join(' or ')} instances for asymmetric algorithm verifying must be of type "public"`); } if (key.algorithm && usage === 'encrypt' && key.type === 'private') { throw new TypeError(`${is_key_like_js_1$3.types.join(' or ')} instances for asymmetric algorithm encryption must be of type "public"`); } }; const checkKeyType = (alg, key, usage) => { const symmetric = alg.startsWith('HS') || alg === 'dir' || alg.startsWith('PBES2') || /^A\d{3}(?:GCM)?KW$/.test(alg); if (symmetric) { symmetricTypeCheck(alg, key); } else { asymmetricTypeCheck(alg, key, usage); } }; check_key_type.default = checkKeyType; var aesgcmkw = {}; var encrypt$5 = {}; Object.defineProperty(encrypt$5, "__esModule", { value: true }); const crypto_1$5 = require$$0$3; const check_iv_length_js_1 = check_iv_length; const check_cek_length_js_1 = check_cek_length; const buffer_utils_js_1$d = buffer_utils; const cbc_tag_js_1 = cbc_tag; const webcrypto_js_1$2 = webcrypto$1; const crypto_key_js_1$1 = crypto_key; const is_key_object_js_1$1 = is_key_object$1; const invalid_key_input_js_1$2 = invalid_key_input; const errors_js_1$s = errors$5; const ciphers_js_1 = ciphers$1; const is_key_like_js_1$2 = is_key_like; function cbcEncrypt(enc, plaintext, cek, iv, aad) { const keySize = parseInt(enc.slice(1, 4), 10); if ((0, is_key_object_js_1$1.default)(cek)) { cek = cek.export(); } const encKey = cek.subarray(keySize >> 3); const macKey = cek.subarray(0, keySize >> 3); const algorithm = `aes-${keySize}-cbc`; if (!(0, ciphers_js_1.default)(algorithm)) { throw new errors_js_1$s.JOSENotSupported(`alg ${enc} is not supported by your javascript runtime`); } const cipher = (0, crypto_1$5.createCipheriv)(algorithm, encKey, iv); const ciphertext = (0, buffer_utils_js_1$d.concat)(cipher.update(plaintext), cipher.final()); const macSize = parseInt(enc.slice(-3), 10); const tag = (0, cbc_tag_js_1.default)(aad, iv, ciphertext, macSize, macKey, keySize); return { ciphertext, tag }; } function gcmEncrypt(enc, plaintext, cek, iv, aad) { const keySize = parseInt(enc.slice(1, 4), 10); const algorithm = `aes-${keySize}-gcm`; if (!(0, ciphers_js_1.default)(algorithm)) { throw new errors_js_1$s.JOSENotSupported(`alg ${enc} is not supported by your javascript runtime`); } const cipher = (0, crypto_1$5.createCipheriv)(algorithm, cek, iv, { authTagLength: 16 }); if (aad.byteLength) { cipher.setAAD(aad, { plaintextLength: plaintext.length }); } const ciphertext = cipher.update(plaintext); cipher.final(); const tag = cipher.getAuthTag(); return { ciphertext, tag }; } const encrypt$4 = (enc, plaintext, cek, iv, aad) => { let key; if ((0, webcrypto_js_1$2.isCryptoKey)(cek)) { (0, crypto_key_js_1$1.checkEncCryptoKey)(cek, enc, 'encrypt'); key = crypto_1$5.KeyObject.from(cek); } else if (cek instanceof Uint8Array || (0, is_key_object_js_1$1.default)(cek)) { key = cek; } else { throw new TypeError((0, invalid_key_input_js_1$2.default)(cek, ...is_key_like_js_1$2.types, 'Uint8Array')); } (0, check_cek_length_js_1.default)(enc, key); (0, check_iv_length_js_1.default)(enc, iv); switch (enc) { case 'A128CBC-HS256': case 'A192CBC-HS384': case 'A256CBC-HS512': return cbcEncrypt(enc, plaintext, key, iv, aad); case 'A128GCM': case 'A192GCM': case 'A256GCM': return gcmEncrypt(enc, plaintext, key, iv, aad); default: throw new errors_js_1$s.JOSENotSupported('Unsupported JWE Content Encryption Algorithm'); } }; encrypt$5.default = encrypt$4; Object.defineProperty(aesgcmkw, "__esModule", { value: true }); aesgcmkw.unwrap = aesgcmkw.wrap = void 0; const encrypt_js_1$3 = encrypt$5; const decrypt_js_1$4 = decrypt$6; const iv_js_1 = iv; const base64url_js_1$a = base64url$9; async function wrap(alg, key, cek, iv) { const jweAlgorithm = alg.slice(0, 7); iv || (iv = (0, iv_js_1.default)(jweAlgorithm)); const { ciphertext: encryptedKey, tag } = await (0, encrypt_js_1$3.default)(jweAlgorithm, cek, key, iv, new Uint8Array(0)); return { encryptedKey, iv: (0, base64url_js_1$a.encode)(iv), tag: (0, base64url_js_1$a.encode)(tag) }; } aesgcmkw.wrap = wrap; async function unwrap(alg, key, encryptedKey, iv, tag) { const jweAlgorithm = alg.slice(0, 7); return (0, decrypt_js_1$4.default)(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array(0)); } aesgcmkw.unwrap = unwrap; Object.defineProperty(decrypt_key_management, "__esModule", { value: true }); const aeskw_js_1$1 = aeskw; const ECDH$1 = ecdhes; const pbes2kw_js_1$1 = pbes2kw; const rsaes_js_1$1 = rsaes; const base64url_js_1$9 = base64url$9; const errors_js_1$r = errors$5; const cek_js_1$3 = cek; const import_js_1$2 = _import; const check_key_type_js_1$3 = check_key_type; const is_object_js_1$b = is_object; const aesgcmkw_js_1$1 = aesgcmkw; async function decryptKeyManagement(alg, key, encryptedKey, joseHeader, options) { (0, check_key_type_js_1$3.default)(alg, key, 'decrypt'); switch (alg) { case 'dir': { if (encryptedKey !== undefined) throw new errors_js_1$r.JWEInvalid('Encountered unexpected JWE Encrypted Key'); return key; } case 'ECDH-ES': if (encryptedKey !== undefined) throw new errors_js_1$r.JWEInvalid('Encountered unexpected JWE Encrypted Key'); case 'ECDH-ES+A128KW': case 'ECDH-ES+A192KW': case 'ECDH-ES+A256KW': { if (!(0, is_object_js_1$b.default)(joseHeader.epk)) throw new errors_js_1$r.JWEInvalid(`JOSE Header "epk" (Ephemeral Public Key) missing or invalid`); if (!ECDH$1.ecdhAllowed(key)) throw new errors_js_1$r.JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime'); const epk = await (0, import_js_1$2.importJWK)(joseHeader.epk, alg); let partyUInfo; let partyVInfo; if (joseHeader.apu !== undefined) { if (typeof joseHeader.apu !== 'string') throw new errors_js_1$r.JWEInvalid(`JOSE Header "apu" (Agreement PartyUInfo) invalid`); try { partyUInfo = (0, base64url_js_1$9.decode)(joseHeader.apu); } catch { throw new errors_js_1$r.JWEInvalid('Failed to base64url decode the apu'); } } if (joseHeader.apv !== undefined) { if (typeof joseHeader.apv !== 'string') throw new errors_js_1$r.JWEInvalid(`JOSE Header "apv" (Agreement PartyVInfo) invalid`); try { partyVInfo = (0, base64url_js_1$9.decode)(joseHeader.apv); } catch { throw new errors_js_1$r.JWEInvalid('Failed to base64url decode the apv'); } } const sharedSecret = await ECDH$1.deriveKey(epk, key, alg === 'ECDH-ES' ? joseHeader.enc : alg, alg === 'ECDH-ES' ? (0, cek_js_1$3.bitLength)(joseHeader.enc) : parseInt(alg.slice(-5, -2), 10), partyUInfo, partyVInfo); if (alg === 'ECDH-ES') return sharedSecret; if (encryptedKey === undefined) throw new errors_js_1$r.JWEInvalid('JWE Encrypted Key missing'); return (0, aeskw_js_1$1.unwrap)(alg.slice(-6), sharedSecret, encryptedKey); } case 'RSA1_5': case 'RSA-OAEP': case 'RSA-OAEP-256': case 'RSA-OAEP-384': case 'RSA-OAEP-512': { if (encryptedKey === undefined) throw new errors_js_1$r.JWEInvalid('JWE Encrypted Key missing'); return (0, rsaes_js_1$1.decrypt)(alg, key, encryptedKey); } case 'PBES2-HS256+A128KW': case 'PBES2-HS384+A192KW': case 'PBES2-HS512+A256KW': { if (encryptedKey === undefined) throw new errors_js_1$r.JWEInvalid('JWE Encrypted Key missing'); if (typeof joseHeader.p2c !== 'number') throw new errors_js_1$r.JWEInvalid(`JOSE Header "p2c" (PBES2 Count) missing or invalid`); const p2cLimit = (options === null || options === void 0 ? void 0 : options.maxPBES2Count) || 10000; if (joseHeader.p2c > p2cLimit) throw new errors_js_1$r.JWEInvalid(`JOSE Header "p2c" (PBES2 Count) out is of acceptable bounds`); if (typeof joseHeader.p2s !== 'string') throw new errors_js_1$r.JWEInvalid(`JOSE Header "p2s" (PBES2 Salt) missing or invalid`); let p2s; try { p2s = (0, base64url_js_1$9.decode)(joseHeader.p2s); } catch { throw new errors_js_1$r.JWEInvalid('Failed to base64url decode the p2s'); } return (0, pbes2kw_js_1$1.decrypt)(alg, key, encryptedKey, joseHeader.p2c, p2s); } case 'A128KW': case 'A192KW': case 'A256KW': { if (encryptedKey === undefined) throw new errors_js_1$r.JWEInvalid('JWE Encrypted Key missing'); return (0, aeskw_js_1$1.unwrap)(alg, key, encryptedKey); } case 'A128GCMKW': case 'A192GCMKW': case 'A256GCMKW': { if (encryptedKey === undefined) throw new errors_js_1$r.JWEInvalid('JWE Encrypted Key missing'); if (typeof joseHeader.iv !== 'string') throw new errors_js_1$r.JWEInvalid(`JOSE Header "iv" (Initialization Vector) missing or invalid`); if (typeof joseHeader.tag !== 'string') throw new errors_js_1$r.JWEInvalid(`JOSE Header "tag" (Authentication Tag) missing or invalid`); let iv; try { iv = (0, base64url_js_1$9.decode)(joseHeader.iv); } catch { throw new errors_js_1$r.JWEInvalid('Failed to base64url decode the iv'); } let tag; try { tag = (0, base64url_js_1$9.decode)(joseHeader.tag); } catch { throw new errors_js_1$r.JWEInvalid('Failed to base64url decode the tag'); } return (0, aesgcmkw_js_1$1.unwrap)(alg, key, encryptedKey, iv, tag); } default: { throw new errors_js_1$r.JOSENotSupported('Invalid or unsupported "alg" (JWE Algorithm) header value'); } } } decrypt_key_management.default = decryptKeyManagement; var validate_crit = {}; Object.defineProperty(validate_crit, "__esModule", { value: true }); const errors_js_1$q = errors$5; function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) { if (joseHeader.crit !== undefined && protectedHeader.crit === undefined) { throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected'); } if (!protectedHeader || protectedHeader.crit === undefined) { return new Set(); } if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== 'string' || input.length === 0)) { throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present'); } let recognized; if (recognizedOption !== undefined) { recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]); } else { recognized = recognizedDefault; } for (const parameter of protectedHeader.crit) { if (!recognized.has(parameter)) { throw new errors_js_1$q.JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`); } if (joseHeader[parameter] === undefined) { throw new Err(`Extension Header Parameter "${parameter}" is missing`); } else if (recognized.get(parameter) && protectedHeader[parameter] === undefined) { throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`); } } return new Set(protectedHeader.crit); } validate_crit.default = validateCrit; var validate_algorithms = {}; Object.defineProperty(validate_algorithms, "__esModule", { value: true }); const validateAlgorithms = (option, algorithms) => { if (algorithms !== undefined && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== 'string'))) { throw new TypeError(`"${option}" option must be an array of strings`); } if (!algorithms) { return undefined; } return new Set(algorithms); }; validate_algorithms.default = validateAlgorithms; Object.defineProperty(decrypt$7, "__esModule", { value: true }); decrypt$7.flattenedDecrypt = void 0; const base64url_js_1$8 = base64url$9; const decrypt_js_1$3 = decrypt$6; const zlib_js_1 = zlib; const errors_js_1$p = errors$5; const is_disjoint_js_1$3 = is_disjoint; const is_object_js_1$a = is_object; const decrypt_key_management_js_1 = decrypt_key_management; const buffer_utils_js_1$c = buffer_utils; const cek_js_1$2 = cek; const validate_crit_js_1$3 = validate_crit; const validate_algorithms_js_1$1 = validate_algorithms; async function flattenedDecrypt(jwe, key, options) { var _a; if (!(0, is_object_js_1$a.default)(jwe)) { throw new errors_js_1$p.JWEInvalid('Flattened JWE must be an object'); } if (jwe.protected === undefined && jwe.header === undefined && jwe.unprotected === undefined) { throw new errors_js_1$p.JWEInvalid('JOSE Header missing'); } if (typeof jwe.iv !== 'string') { throw new errors_js_1$p.JWEInvalid('JWE Initialization Vector missing or incorrect type'); } if (typeof jwe.ciphertext !== 'string') { throw new errors_js_1$p.JWEInvalid('JWE Ciphertext missing or incorrect type'); } if (typeof jwe.tag !== 'string') { throw new errors_js_1$p.JWEInvalid('JWE Authentication Tag missing or incorrect type'); } if (jwe.protected !== undefined && typeof jwe.protected !== 'string') { throw new errors_js_1$p.JWEInvalid('JWE Protected Header incorrect type'); } if (jwe.encrypted_key !== undefined && typeof jwe.encrypted_key !== 'string') { throw new errors_js_1$p.JWEInvalid('JWE Encrypted Key incorrect type'); } if (jwe.aad !== undefined && typeof jwe.aad !== 'string') { throw new errors_js_1$p.JWEInvalid('JWE AAD incorrect type'); } if (jwe.header !== undefined && !(0, is_object_js_1$a.default)(jwe.header)) { throw new errors_js_1$p.JWEInvalid('JWE Shared Unprotected Header incorrect type'); } if (jwe.unprotected !== undefined && !(0, is_object_js_1$a.default)(jwe.unprotected)) { throw new errors_js_1$p.JWEInvalid('JWE Per-Recipient Unprotected Header incorrect type'); } let parsedProt; if (jwe.protected) { try { const protectedHeader = (0, base64url_js_1$8.decode)(jwe.protected); parsedProt = JSON.parse(buffer_utils_js_1$c.decoder.decode(protectedHeader)); } catch { throw new errors_js_1$p.JWEInvalid('JWE Protected Header is invalid'); } } if (!(0, is_disjoint_js_1$3.default)(parsedProt, jwe.header, jwe.unprotected)) { throw new errors_js_1$p.JWEInvalid('JWE Protected, JWE Unprotected Header, and JWE Per-Recipient Unprotected Header Parameter names must be disjoint'); } const joseHeader = { ...parsedProt, ...jwe.header, ...jwe.unprotected, }; (0, validate_crit_js_1$3.default)(errors_js_1$p.JWEInvalid, new Map(), options === null || options === void 0 ? void 0 : options.crit, parsedProt, joseHeader); if (joseHeader.zip !== undefined) { if (!parsedProt || !parsedProt.zip) { throw new errors_js_1$p.JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected'); } if (joseHeader.zip !== 'DEF') { throw new errors_js_1$p.JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value'); } } const { alg, enc } = joseHeader; if (typeof alg !== 'string' || !alg) { throw new errors_js_1$p.JWEInvalid('missing JWE Algorithm (alg) in JWE Header'); } if (typeof enc !== 'string' || !enc) { throw new errors_js_1$p.JWEInvalid('missing JWE Encryption Algorithm (enc) in JWE Header'); } const keyManagementAlgorithms = options && (0, validate_algorithms_js_1$1.default)('keyManagementAlgorithms', options.keyManagementAlgorithms); const contentEncryptionAlgorithms = options && (0, validate_algorithms_js_1$1.default)('contentEncryptionAlgorithms', options.contentEncryptionAlgorithms); if (keyManagementAlgorithms && !keyManagementAlgorithms.has(alg)) { throw new errors_js_1$p.JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter not allowed'); } if (contentEncryptionAlgorithms && !contentEncryptionAlgorithms.has(enc)) { throw new errors_js_1$p.JOSEAlgNotAllowed('"enc" (Encryption Algorithm) Header Parameter not allowed'); } let encryptedKey; if (jwe.encrypted_key !== undefined) { try { encryptedKey = (0, base64url_js_1$8.decode)(jwe.encrypted_key); } catch { throw new errors_js_1$p.JWEInvalid('Failed to base64url decode the encrypted_key'); } } let resolvedKey = false; if (typeof key === 'function') { key = await key(parsedProt, jwe); resolvedKey = true; } let cek; try { cek = await (0, decrypt_key_management_js_1.default)(alg, key, encryptedKey, joseHeader, options); } catch (err) { if (err instanceof TypeError || err instanceof errors_js_1$p.JWEInvalid || err instanceof errors_js_1$p.JOSENotSupported) { throw err; } cek = (0, cek_js_1$2.default)(enc); } let iv; let tag; try { iv = (0, base64url_js_1$8.decode)(jwe.iv); } catch { throw new errors_js_1$p.JWEInvalid('Failed to base64url decode the iv'); } try { tag = (0, base64url_js_1$8.decode)(jwe.tag); } catch { throw new errors_js_1$p.JWEInvalid('Failed to base64url decode the tag'); } const protectedHeader = buffer_utils_js_1$c.encoder.encode((_a = jwe.protected) !== null && _a !== void 0 ? _a : ''); let additionalData; if (jwe.aad !== undefined) { additionalData = (0, buffer_utils_js_1$c.concat)(protectedHeader, buffer_utils_js_1$c.encoder.encode('.'), buffer_utils_js_1$c.encoder.encode(jwe.aad)); } else { additionalData = protectedHeader; } let ciphertext; try { ciphertext = (0, base64url_js_1$8.decode)(jwe.ciphertext); } catch { throw new errors_js_1$p.JWEInvalid('Failed to base64url decode the ciphertext'); } let plaintext = await (0, decrypt_js_1$3.default)(enc, cek, ciphertext, iv, tag, additionalData); if (joseHeader.zip === 'DEF') { plaintext = await ((options === null || options === void 0 ? void 0 : options.inflateRaw) || zlib_js_1.inflate)(plaintext); } const result = { plaintext }; if (jwe.protected !== undefined) { result.protectedHeader = parsedProt; } if (jwe.aad !== undefined) { try { result.additionalAuthenticatedData = (0, base64url_js_1$8.decode)(jwe.aad); } catch { throw new errors_js_1$p.JWEInvalid('Failed to base64url decode the aad'); } } if (jwe.unprotected !== undefined) { result.sharedUnprotectedHeader = jwe.unprotected; } if (jwe.header !== undefined) { result.unprotectedHeader = jwe.header; } if (resolvedKey) { return { ...result, key }; } return result; } decrypt$7.flattenedDecrypt = flattenedDecrypt; Object.defineProperty(decrypt$8, "__esModule", { value: true }); decrypt$8.compactDecrypt = void 0; const decrypt_js_1$2 = decrypt$7; const errors_js_1$o = errors$5; const buffer_utils_js_1$b = buffer_utils; async function compactDecrypt(jwe, key, options) { if (jwe instanceof Uint8Array) { jwe = buffer_utils_js_1$b.decoder.decode(jwe); } if (typeof jwe !== 'string') { throw new errors_js_1$o.JWEInvalid('Compact JWE must be a string or Uint8Array'); } const { 0: protectedHeader, 1: encryptedKey, 2: iv, 3: ciphertext, 4: tag, length, } = jwe.split('.'); if (length !== 5) { throw new errors_js_1$o.JWEInvalid('Invalid Compact JWE'); } const decrypted = await (0, decrypt_js_1$2.flattenedDecrypt)({ ciphertext, iv: (iv || undefined), protected: protectedHeader || undefined, tag: (tag || undefined), encrypted_key: encryptedKey || undefined, }, key, options); const result = { plaintext: decrypted.plaintext, protectedHeader: decrypted.protectedHeader }; if (typeof key === 'function') { return { ...result, key: decrypted.key }; } return result; } decrypt$8.compactDecrypt = compactDecrypt; var decrypt$2 = {}; Object.defineProperty(decrypt$2, "__esModule", { value: true }); decrypt$2.generalDecrypt = void 0; const decrypt_js_1$1 = decrypt$7; const errors_js_1$n = errors$5; const is_object_js_1$9 = is_object; async function generalDecrypt(jwe, key, options) { if (!(0, is_object_js_1$9.default)(jwe)) { throw new errors_js_1$n.JWEInvalid('General JWE must be an object'); } if (!Array.isArray(jwe.recipients) || !jwe.recipients.every(is_object_js_1$9.default)) { throw new errors_js_1$n.JWEInvalid('JWE Recipients missing or incorrect type'); } if (!jwe.recipients.length) { throw new errors_js_1$n.JWEInvalid('JWE Recipients has no members'); } for (const recipient of jwe.recipients) { try { return await (0, decrypt_js_1$1.flattenedDecrypt)({ aad: jwe.aad, ciphertext: jwe.ciphertext, encrypted_key: recipient.encrypted_key, header: recipient.header, iv: jwe.iv, protected: jwe.protected, tag: jwe.tag, unprotected: jwe.unprotected, }, key, options); } catch { } } throw new errors_js_1$n.JWEDecryptionFailed(); } decrypt$2.generalDecrypt = generalDecrypt; var encrypt$3 = {}; var encrypt$2 = {}; var encrypt_key_management = {}; var _export = {}; var key_to_jwk = {}; var asn1_sequence_decoder = {}; Object.defineProperty(asn1_sequence_decoder, "__esModule", { value: true }); const tagInteger = 0x02; const tagSequence = 0x30; class Asn1SequenceDecoder { constructor(buffer) { if (buffer[0] !== tagSequence) { throw new TypeError(); } this.buffer = buffer; this.offset = 1; const len = this.decodeLength(); if (len !== buffer.length - this.offset) { throw new TypeError(); } } decodeLength() { let length = this.buffer[this.offset++]; if (length & 0x80) { const nBytes = length & ~0x80; length = 0; for (let i = 0; i < nBytes; i++) length = (length << 8) | this.buffer[this.offset + i]; this.offset += nBytes; } return length; } unsignedInteger() { if (this.buffer[this.offset++] !== tagInteger) { throw new TypeError(); } let length = this.decodeLength(); if (this.buffer[this.offset] === 0) { this.offset++; length--; } const result = this.buffer.slice(this.offset, this.offset + length); this.offset += length; return result; } end() { if (this.offset !== this.buffer.length) { throw new TypeError(); } } } asn1_sequence_decoder.default = Asn1SequenceDecoder; Object.defineProperty(key_to_jwk, "__esModule", { value: true }); const crypto_1$4 = require$$0$3; const base64url_js_1$7 = base64url$9; const asn1_sequence_decoder_js_1 = asn1_sequence_decoder; const errors_js_1$m = errors$5; const get_named_curve_js_1$1 = get_named_curve; const webcrypto_js_1$1 = webcrypto$1; const is_key_object_js_1 = is_key_object$1; const invalid_key_input_js_1$1 = invalid_key_input; const is_key_like_js_1$1 = is_key_like; const flags_js_1$2 = flags; const keyToJWK = (key) => { let keyObject; if ((0, webcrypto_js_1$1.isCryptoKey)(key)) { if (!key.extractable) { throw new TypeError('CryptoKey is not extractable'); } keyObject = crypto_1$4.KeyObject.from(key); } else if ((0, is_key_object_js_1.default)(key)) { keyObject = key; } else if (key instanceof Uint8Array) { return { kty: 'oct', k: (0, base64url_js_1$7.encode)(key), }; } else { throw new TypeError((0, invalid_key_input_js_1$1.default)(key, ...is_key_like_js_1$1.types, 'Uint8Array')); } if (flags_js_1$2.jwkExport) { if (keyObject.type !== 'secret' && !['rsa', 'ec', 'ed25519', 'x25519', 'ed448', 'x448'].includes(keyObject.asymmetricKeyType)) { throw new errors_js_1$m.JOSENotSupported('Unsupported key asymmetricKeyType'); } return keyObject.export({ format: 'jwk' }); } switch (keyObject.type) { case 'secret': return { kty: 'oct', k: (0, base64url_js_1$7.encode)(keyObject.export()), }; case 'private': case 'public': { switch (keyObject.asymmetricKeyType) { case 'rsa': { const der = keyObject.export({ format: 'der', type: 'pkcs1' }); const dec = new asn1_sequence_decoder_js_1.default(der); if (keyObject.type === 'private') { dec.unsignedInteger(); } const n = (0, base64url_js_1$7.encode)(dec.unsignedInteger()); const e = (0, base64url_js_1$7.encode)(dec.unsignedInteger()); let jwk; if (keyObject.type === 'private') { jwk = { d: (0, base64url_js_1$7.encode)(dec.unsignedInteger()), p: (0, base64url_js_1$7.encode)(dec.unsignedInteger()), q: (0, base64url_js_1$7.encode)(dec.unsignedInteger()), dp: (0, base64url_js_1$7.encode)(dec.unsignedInteger()), dq: (0, base64url_js_1$7.encode)(dec.unsignedInteger()), qi: (0, base64url_js_1$7.encode)(dec.unsignedInteger()), }; } dec.end(); return { kty: 'RSA', n, e, ...jwk }; } case 'ec': { const crv = (0, get_named_curve_js_1$1.default)(keyObject); let len; let offset; let correction; switch (crv) { case 'secp256k1': len = 64; offset = 31 + 2; correction = -1; break; case 'P-256': len = 64; offset = 34 + 2; correction = -1; break; case 'P-384': len = 96; offset = 33 + 2; correction = -3; break; case 'P-521': len = 132; offset = 33 + 2; correction = -3; break; default: throw new errors_js_1$m.JOSENotSupported('Unsupported curve'); } if (keyObject.type === 'public') { const der = keyObject.export({ type: 'spki', format: 'der' }); return { kty: 'EC', crv, x: (0, base64url_js_1$7.encode)(der.subarray(-len, -len / 2)), y: (0, base64url_js_1$7.encode)(der.subarray(-len / 2)), }; } const der = keyObject.export({ type: 'pkcs8', format: 'der' }); if (der.length < 100) { offset += correction; } return { ...keyToJWK((0, crypto_1$4.createPublicKey)(keyObject)), d: (0, base64url_js_1$7.encode)(der.subarray(offset, offset + len / 2)), }; } case 'ed25519': case 'x25519': { const crv = (0, get_named_curve_js_1$1.default)(keyObject); if (keyObject.type === 'public') { const der = keyObject.export({ type: 'spki', format: 'der' }); return { kty: 'OKP', crv, x: (0, base64url_js_1$7.encode)(der.subarray(-32)), }; } const der = keyObject.export({ type: 'pkcs8', format: 'der' }); return { ...keyToJWK((0, crypto_1$4.createPublicKey)(keyObject)), d: (0, base64url_js_1$7.encode)(der.subarray(-32)), }; } case 'ed448': case 'x448': { const crv = (0, get_named_curve_js_1$1.default)(keyObject); if (keyObject.type === 'public') { const der = keyObject.export({ type: 'spki', format: 'der' }); return { kty: 'OKP', crv, x: (0, base64url_js_1$7.encode)(der.subarray(crv === 'Ed448' ? -57 : -56)), }; } const der = keyObject.export({ type: 'pkcs8', format: 'der' }); return { ...keyToJWK((0, crypto_1$4.createPublicKey)(keyObject)), d: (0, base64url_js_1$7.encode)(der.subarray(crv === 'Ed448' ? -57 : -56)), }; } default: throw new errors_js_1$m.JOSENotSupported('Unsupported key asymmetricKeyType'); } } default: throw new errors_js_1$m.JOSENotSupported('Unsupported key type'); } }; key_to_jwk.default = keyToJWK; Object.defineProperty(_export, "__esModule", { value: true }); _export.exportJWK = _export.exportPKCS8 = _export.exportSPKI = void 0; const asn1_js_1 = asn1; const asn1_js_2 = asn1; const key_to_jwk_js_1 = key_to_jwk; async function exportSPKI(key) { return (0, asn1_js_1.toSPKI)(key); } _export.exportSPKI = exportSPKI; async function exportPKCS8(key) { return (0, asn1_js_2.toPKCS8)(key); } _export.exportPKCS8 = exportPKCS8; async function exportJWK(key) { return (0, key_to_jwk_js_1.default)(key); } _export.exportJWK = exportJWK; Object.defineProperty(encrypt_key_management, "__esModule", { value: true }); const aeskw_js_1 = aeskw; const ECDH = ecdhes; const pbes2kw_js_1 = pbes2kw; const rsaes_js_1 = rsaes; const base64url_js_1$6 = base64url$9; const cek_js_1$1 = cek; const errors_js_1$l = errors$5; const export_js_1 = _export; const check_key_type_js_1$2 = check_key_type; const aesgcmkw_js_1 = aesgcmkw; async function encryptKeyManagement(alg, enc, key, providedCek, providedParameters = {}) { let encryptedKey; let parameters; let cek; (0, check_key_type_js_1$2.default)(alg, key, 'encrypt'); switch (alg) { case 'dir': { cek = key; break; } case 'ECDH-ES': case 'ECDH-ES+A128KW': case 'ECDH-ES+A192KW': case 'ECDH-ES+A256KW': { if (!ECDH.ecdhAllowed(key)) { throw new errors_js_1$l.JOSENotSupported('ECDH with the provided key is not allowed or not supported by your javascript runtime'); } const { apu, apv } = providedParameters; let { epk: ephemeralKey } = providedParameters; ephemeralKey || (ephemeralKey = (await ECDH.generateEpk(key)).privateKey); const { x, y, crv, kty } = await (0, export_js_1.exportJWK)(ephemeralKey); const sharedSecret = await ECDH.deriveKey(key, ephemeralKey, alg === 'ECDH-ES' ? enc : alg, alg === 'ECDH-ES' ? (0, cek_js_1$1.bitLength)(enc) : parseInt(alg.slice(-5, -2), 10), apu, apv); parameters = { epk: { x, crv, kty } }; if (kty === 'EC') parameters.epk.y = y; if (apu) parameters.apu = (0, base64url_js_1$6.encode)(apu); if (apv) parameters.apv = (0, base64url_js_1$6.encode)(apv); if (alg === 'ECDH-ES') { cek = sharedSecret; break; } cek = providedCek || (0, cek_js_1$1.default)(enc); const kwAlg = alg.slice(-6); encryptedKey = await (0, aeskw_js_1.wrap)(kwAlg, sharedSecret, cek); break; } case 'RSA1_5': case 'RSA-OAEP': case 'RSA-OAEP-256': case 'RSA-OAEP-384': case 'RSA-OAEP-512': { cek = providedCek || (0, cek_js_1$1.default)(enc); encryptedKey = await (0, rsaes_js_1.encrypt)(alg, key, cek); break; } case 'PBES2-HS256+A128KW': case 'PBES2-HS384+A192KW': case 'PBES2-HS512+A256KW': { cek = providedCek || (0, cek_js_1$1.default)(enc); const { p2c, p2s } = providedParameters; ({ encryptedKey, ...parameters } = await (0, pbes2kw_js_1.encrypt)(alg, key, cek, p2c, p2s)); break; } case 'A128KW': case 'A192KW': case 'A256KW': { cek = providedCek || (0, cek_js_1$1.default)(enc); encryptedKey = await (0, aeskw_js_1.wrap)(alg, key, cek); break; } case 'A128GCMKW': case 'A192GCMKW': case 'A256GCMKW': { cek = providedCek || (0, cek_js_1$1.default)(enc); const { iv } = providedParameters; ({ encryptedKey, ...parameters } = await (0, aesgcmkw_js_1.wrap)(alg, key, cek, iv)); break; } default: { throw new errors_js_1$l.JOSENotSupported('Invalid or unsupported "alg" (JWE Algorithm) header value'); } } return { cek, encryptedKey, parameters }; } encrypt_key_management.default = encryptKeyManagement; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.FlattenedEncrypt = exports.unprotected = void 0; const base64url_js_1 = base64url$9; const encrypt_js_1 = encrypt$5; const zlib_js_1 = zlib; const iv_js_1 = iv; const encrypt_key_management_js_1 = encrypt_key_management; const errors_js_1 = errors$5; const is_disjoint_js_1 = is_disjoint; const buffer_utils_js_1 = buffer_utils; const validate_crit_js_1 = validate_crit; exports.unprotected = Symbol(); class FlattenedEncrypt { constructor(plaintext) { if (!(plaintext instanceof Uint8Array)) { throw new TypeError('plaintext must be an instance of Uint8Array'); } this._plaintext = plaintext; } setKeyManagementParameters(parameters) { if (this._keyManagementParameters) { throw new TypeError('setKeyManagementParameters can only be called once'); } this._keyManagementParameters = parameters; return this; } setProtectedHeader(protectedHeader) { if (this._protectedHeader) { throw new TypeError('setProtectedHeader can only be called once'); } this._protectedHeader = protectedHeader; return this; } setSharedUnprotectedHeader(sharedUnprotectedHeader) { if (this._sharedUnprotectedHeader) { throw new TypeError('setSharedUnprotectedHeader can only be called once'); } this._sharedUnprotectedHeader = sharedUnprotectedHeader; return this; } setUnprotectedHeader(unprotectedHeader) { if (this._unprotectedHeader) { throw new TypeError('setUnprotectedHeader can only be called once'); } this._unprotectedHeader = unprotectedHeader; return this; } setAdditionalAuthenticatedData(aad) { this._aad = aad; return this; } setContentEncryptionKey(cek) { if (this._cek) { throw new TypeError('setContentEncryptionKey can only be called once'); } this._cek = cek; return this; } setInitializationVector(iv) { if (this._iv) { throw new TypeError('setInitializationVector can only be called once'); } this._iv = iv; return this; } async encrypt(key, options) { if (!this._protectedHeader && !this._unprotectedHeader && !this._sharedUnprotectedHeader) { throw new errors_js_1.JWEInvalid('either setProtectedHeader, setUnprotectedHeader, or sharedUnprotectedHeader must be called before #encrypt()'); } if (!(0, is_disjoint_js_1.default)(this._protectedHeader, this._unprotectedHeader, this._sharedUnprotectedHeader)) { throw new errors_js_1.JWEInvalid('JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint'); } const joseHeader = { ...this._protectedHeader, ...this._unprotectedHeader, ...this._sharedUnprotectedHeader, }; (0, validate_crit_js_1.default)(errors_js_1.JWEInvalid, new Map(), options === null || options === void 0 ? void 0 : options.crit, this._protectedHeader, joseHeader); if (joseHeader.zip !== undefined) { if (!this._protectedHeader || !this._protectedHeader.zip) { throw new errors_js_1.JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected'); } if (joseHeader.zip !== 'DEF') { throw new errors_js_1.JOSENotSupported('Unsupported JWE "zip" (Compression Algorithm) Header Parameter value'); } } const { alg, enc } = joseHeader; if (typeof alg !== 'string' || !alg) { throw new errors_js_1.JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid'); } if (typeof enc !== 'string' || !enc) { throw new errors_js_1.JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid'); } let encryptedKey; if (alg === 'dir') { if (this._cek) { throw new TypeError('setContentEncryptionKey cannot be called when using Direct Encryption'); } } else if (alg === 'ECDH-ES') { if (this._cek) { throw new TypeError('setContentEncryptionKey cannot be called when using Direct Key Agreement'); } } let cek; { let parameters; ({ cek, encryptedKey, parameters } = await (0, encrypt_key_management_js_1.default)(alg, enc, key, this._cek, this._keyManagementParameters)); if (parameters) { if (options && exports.unprotected in options) { if (!this._unprotectedHeader) { this.setUnprotectedHeader(parameters); } else { this._unprotectedHeader = { ...this._unprotectedHeader, ...parameters }; } } else { if (!this._protectedHeader) { this.setProtectedHeader(parameters); } else { this._protectedHeader = { ...this._protectedHeader, ...parameters }; } } } } this._iv || (this._iv = (0, iv_js_1.default)(enc)); let additionalData; let protectedHeader; let aadMember; if (this._protectedHeader) { protectedHeader = buffer_utils_js_1.encoder.encode((0, base64url_js_1.encode)(JSON.stringify(this._protectedHeader))); } else { protectedHeader = buffer_utils_js_1.encoder.encode(''); } if (this._aad) { aadMember = (0, base64url_js_1.encode)(this._aad); additionalData = (0, buffer_utils_js_1.concat)(protectedHeader, buffer_utils_js_1.encoder.encode('.'), buffer_utils_js_1.encoder.encode(aadMember)); } else { additionalData = protectedHeader; } let ciphertext; let tag; if (joseHeader.zip === 'DEF') { const deflated = await ((options === null || options === void 0 ? void 0 : options.deflateRaw) || zlib_js_1.deflate)(this._plaintext); ({ ciphertext, tag } = await (0, encrypt_js_1.default)(enc, deflated, cek, this._iv, additionalData)); } else { ({ ciphertext, tag } = await (0, encrypt_js_1.default)(enc, this._plaintext, cek, this._iv, additionalData)); } const jwe = { ciphertext: (0, base64url_js_1.encode)(ciphertext), iv: (0, base64url_js_1.encode)(this._iv), tag: (0, base64url_js_1.encode)(tag), }; if (encryptedKey) { jwe.encrypted_key = (0, base64url_js_1.encode)(encryptedKey); } if (aadMember) { jwe.aad = aadMember; } if (this._protectedHeader) { jwe.protected = buffer_utils_js_1.decoder.decode(protectedHeader); } if (this._sharedUnprotectedHeader) { jwe.unprotected = this._sharedUnprotectedHeader; } if (this._unprotectedHeader) { jwe.header = this._unprotectedHeader; } return jwe; } } exports.FlattenedEncrypt = FlattenedEncrypt; } (encrypt$2)); Object.defineProperty(encrypt$3, "__esModule", { value: true }); encrypt$3.GeneralEncrypt = void 0; const encrypt_js_1$2 = encrypt$2; const errors_js_1$k = errors$5; const cek_js_1 = cek; const is_disjoint_js_1$2 = is_disjoint; const encrypt_key_management_js_1 = encrypt_key_management; const base64url_js_1$5 = base64url$9; const validate_crit_js_1$2 = validate_crit; class IndividualRecipient { constructor(enc, key, options) { this.parent = enc; this.key = key; this.options = options; } setUnprotectedHeader(unprotectedHeader) { if (this.unprotectedHeader) { throw new TypeError('setUnprotectedHeader can only be called once'); } this.unprotectedHeader = unprotectedHeader; return this; } addRecipient(...args) { return this.parent.addRecipient(...args); } encrypt(...args) { return this.parent.encrypt(...args); } done() { return this.parent; } } class GeneralEncrypt { constructor(plaintext) { this._recipients = []; this._plaintext = plaintext; } addRecipient(key, options) { const recipient = new IndividualRecipient(this, key, { crit: options === null || options === void 0 ? void 0 : options.crit }); this._recipients.push(recipient); return recipient; } setProtectedHeader(protectedHeader) { if (this._protectedHeader) { throw new TypeError('setProtectedHeader can only be called once'); } this._protectedHeader = protectedHeader; return this; } setSharedUnprotectedHeader(sharedUnprotectedHeader) { if (this._unprotectedHeader) { throw new TypeError('setSharedUnprotectedHeader can only be called once'); } this._unprotectedHeader = sharedUnprotectedHeader; return this; } setAdditionalAuthenticatedData(aad) { this._aad = aad; return this; } async encrypt(options) { var _a, _b, _c; if (!this._recipients.length) { throw new errors_js_1$k.JWEInvalid('at least one recipient must be added'); } options = { deflateRaw: options === null || options === void 0 ? void 0 : options.deflateRaw }; if (this._recipients.length === 1) { const [recipient] = this._recipients; const flattened = await new encrypt_js_1$2.FlattenedEncrypt(this._plaintext) .setAdditionalAuthenticatedData(this._aad) .setProtectedHeader(this._protectedHeader) .setSharedUnprotectedHeader(this._unprotectedHeader) .setUnprotectedHeader(recipient.unprotectedHeader) .encrypt(recipient.key, { ...recipient.options, ...options }); let jwe = { ciphertext: flattened.ciphertext, iv: flattened.iv, recipients: [{}], tag: flattened.tag, }; if (flattened.aad) jwe.aad = flattened.aad; if (flattened.protected) jwe.protected = flattened.protected; if (flattened.unprotected) jwe.unprotected = flattened.unprotected; if (flattened.encrypted_key) jwe.recipients[0].encrypted_key = flattened.encrypted_key; if (flattened.header) jwe.recipients[0].header = flattened.header; return jwe; } let enc; for (let i = 0; i < this._recipients.length; i++) { const recipient = this._recipients[i]; if (!(0, is_disjoint_js_1$2.default)(this._protectedHeader, this._unprotectedHeader, recipient.unprotectedHeader)) { throw new errors_js_1$k.JWEInvalid('JWE Protected, JWE Shared Unprotected and JWE Per-Recipient Header Parameter names must be disjoint'); } const joseHeader = { ...this._protectedHeader, ...this._unprotectedHeader, ...recipient.unprotectedHeader, }; const { alg } = joseHeader; if (typeof alg !== 'string' || !alg) { throw new errors_js_1$k.JWEInvalid('JWE "alg" (Algorithm) Header Parameter missing or invalid'); } if (alg === 'dir' || alg === 'ECDH-ES') { throw new errors_js_1$k.JWEInvalid('"dir" and "ECDH-ES" alg may only be used with a single recipient'); } if (typeof joseHeader.enc !== 'string' || !joseHeader.enc) { throw new errors_js_1$k.JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter missing or invalid'); } if (!enc) { enc = joseHeader.enc; } else if (enc !== joseHeader.enc) { throw new errors_js_1$k.JWEInvalid('JWE "enc" (Encryption Algorithm) Header Parameter must be the same for all recipients'); } (0, validate_crit_js_1$2.default)(errors_js_1$k.JWEInvalid, new Map(), recipient.options.crit, this._protectedHeader, joseHeader); if (joseHeader.zip !== undefined) { if (!this._protectedHeader || !this._protectedHeader.zip) { throw new errors_js_1$k.JWEInvalid('JWE "zip" (Compression Algorithm) Header MUST be integrity protected'); } } } const cek = (0, cek_js_1.default)(enc); let jwe = { ciphertext: '', iv: '', recipients: [], tag: '', }; for (let i = 0; i < this._recipients.length; i++) { const recipient = this._recipients[i]; const target = {}; jwe.recipients.push(target); const joseHeader = { ...this._protectedHeader, ...this._unprotectedHeader, ...recipient.unprotectedHeader, }; const p2c = joseHeader.alg.startsWith('PBES2') ? 2048 + i : undefined; if (i === 0) { const flattened = await new encrypt_js_1$2.FlattenedEncrypt(this._plaintext) .setAdditionalAuthenticatedData(this._aad) .setContentEncryptionKey(cek) .setProtectedHeader(this._protectedHeader) .setSharedUnprotectedHeader(this._unprotectedHeader) .setUnprotectedHeader(recipient.unprotectedHeader) .setKeyManagementParameters({ p2c }) .encrypt(recipient.key, { ...recipient.options, ...options, [encrypt_js_1$2.unprotected]: true, }); jwe.ciphertext = flattened.ciphertext; jwe.iv = flattened.iv; jwe.tag = flattened.tag; if (flattened.aad) jwe.aad = flattened.aad; if (flattened.protected) jwe.protected = flattened.protected; if (flattened.unprotected) jwe.unprotected = flattened.unprotected; target.encrypted_key = flattened.encrypted_key; if (flattened.header) target.header = flattened.header; continue; } const { encryptedKey, parameters } = await (0, encrypt_key_management_js_1.default)(((_a = recipient.unprotectedHeader) === null || _a === void 0 ? void 0 : _a.alg) || ((_b = this._protectedHeader) === null || _b === void 0 ? void 0 : _b.alg) || ((_c = this._unprotectedHeader) === null || _c === void 0 ? void 0 : _c.alg), enc, recipient.key, cek, { p2c }); target.encrypted_key = (0, base64url_js_1$5.encode)(encryptedKey); if (recipient.unprotectedHeader || parameters) target.header = { ...recipient.unprotectedHeader, ...parameters }; } return jwe; } } encrypt$3.GeneralEncrypt = GeneralEncrypt; var verify$6 = {}; var verify$5 = {}; var verify$4 = {}; var dsa_digest = {}; Object.defineProperty(dsa_digest, "__esModule", { value: true }); const errors_js_1$j = errors$5; function dsaDigest(alg) { switch (alg) { case 'PS256': case 'RS256': case 'ES256': case 'ES256K': return 'sha256'; case 'PS384': case 'RS384': case 'ES384': return 'sha384'; case 'PS512': case 'RS512': case 'ES512': return 'sha512'; case 'EdDSA': return undefined; default: throw new errors_js_1$j.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`); } } dsa_digest.default = dsaDigest; var node_key = {}; Object.defineProperty(node_key, "__esModule", { value: true }); const crypto_1$3 = require$$0$3; const get_named_curve_js_1 = get_named_curve; const errors_js_1$i = errors$5; const check_modulus_length_js_1$1 = check_modulus_length; const flags_js_1$1 = flags; const PSS = { padding: crypto_1$3.constants.RSA_PKCS1_PSS_PADDING, saltLength: crypto_1$3.constants.RSA_PSS_SALTLEN_DIGEST, }; const ecCurveAlgMap = new Map([ ['ES256', 'P-256'], ['ES256K', 'secp256k1'], ['ES384', 'P-384'], ['ES512', 'P-521'], ]); function keyForCrypto(alg, key) { switch (alg) { case 'EdDSA': if (!['ed25519', 'ed448'].includes(key.asymmetricKeyType)) { throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be ed25519 or ed448'); } return key; case 'RS256': case 'RS384': case 'RS512': if (key.asymmetricKeyType !== 'rsa') { throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be rsa'); } (0, check_modulus_length_js_1$1.default)(key, alg); return key; case flags_js_1$1.rsaPssParams && 'PS256': case flags_js_1$1.rsaPssParams && 'PS384': case flags_js_1$1.rsaPssParams && 'PS512': if (key.asymmetricKeyType === 'rsa-pss') { const { hashAlgorithm, mgf1HashAlgorithm, saltLength } = key.asymmetricKeyDetails; const length = parseInt(alg.slice(-3), 10); if (hashAlgorithm !== undefined && (hashAlgorithm !== `sha${length}` || mgf1HashAlgorithm !== hashAlgorithm)) { throw new TypeError(`Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" ${alg}`); } if (saltLength !== undefined && saltLength > length >> 3) { throw new TypeError(`Invalid key for this operation, its RSA-PSS parameter saltLength does not meet the requirements of "alg" ${alg}`); } } else if (key.asymmetricKeyType !== 'rsa') { throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be rsa or rsa-pss'); } (0, check_modulus_length_js_1$1.default)(key, alg); return { key, ...PSS }; case !flags_js_1$1.rsaPssParams && 'PS256': case !flags_js_1$1.rsaPssParams && 'PS384': case !flags_js_1$1.rsaPssParams && 'PS512': if (key.asymmetricKeyType !== 'rsa') { throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be rsa'); } (0, check_modulus_length_js_1$1.default)(key, alg); return { key, ...PSS }; case 'ES256': case 'ES256K': case 'ES384': case 'ES512': { if (key.asymmetricKeyType !== 'ec') { throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be ec'); } const actual = (0, get_named_curve_js_1.default)(key); const expected = ecCurveAlgMap.get(alg); if (actual !== expected) { throw new TypeError(`Invalid key curve for the algorithm, its curve must be ${expected}, got ${actual}`); } return { dsaEncoding: 'ieee-p1363', key }; } default: throw new errors_js_1$i.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`); } } node_key.default = keyForCrypto; var sign$6 = {}; var hmac_digest = {}; Object.defineProperty(hmac_digest, "__esModule", { value: true }); const errors_js_1$h = errors$5; function hmacDigest(alg) { switch (alg) { case 'HS256': return 'sha256'; case 'HS384': return 'sha384'; case 'HS512': return 'sha512'; default: throw new errors_js_1$h.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`); } } hmac_digest.default = hmacDigest; var get_sign_verify_key = {}; Object.defineProperty(get_sign_verify_key, "__esModule", { value: true }); const crypto_1$2 = require$$0$3; const webcrypto_js_1 = webcrypto$1; const crypto_key_js_1 = crypto_key; const invalid_key_input_js_1 = invalid_key_input; const is_key_like_js_1 = is_key_like; function getSignVerifyKey(alg, key, usage) { if (key instanceof Uint8Array) { if (!alg.startsWith('HS')) { throw new TypeError((0, invalid_key_input_js_1.default)(key, ...is_key_like_js_1.types)); } return (0, crypto_1$2.createSecretKey)(key); } if (key instanceof crypto_1$2.KeyObject) { return key; } if ((0, webcrypto_js_1.isCryptoKey)(key)) { (0, crypto_key_js_1.checkSigCryptoKey)(key, alg, usage); return crypto_1$2.KeyObject.from(key); } throw new TypeError((0, invalid_key_input_js_1.default)(key, ...is_key_like_js_1.types, 'Uint8Array')); } get_sign_verify_key.default = getSignVerifyKey; Object.defineProperty(sign$6, "__esModule", { value: true }); const crypto$6 = require$$0$3; const util_1$3 = require$$1; const dsa_digest_js_1$1 = dsa_digest; const hmac_digest_js_1 = hmac_digest; const node_key_js_1$1 = node_key; const get_sign_verify_key_js_1$1 = get_sign_verify_key; let oneShotSign; if (crypto$6.sign.length > 3) { oneShotSign = (0, util_1$3.promisify)(crypto$6.sign); } else { oneShotSign = crypto$6.sign; } const sign$5 = async (alg, key, data) => { const keyObject = (0, get_sign_verify_key_js_1$1.default)(alg, key, 'sign'); if (alg.startsWith('HS')) { const hmac = crypto$6.createHmac((0, hmac_digest_js_1.default)(alg), keyObject); hmac.update(data); return hmac.digest(); } return oneShotSign((0, dsa_digest_js_1$1.default)(alg), data, (0, node_key_js_1$1.default)(alg, keyObject)); }; sign$6.default = sign$5; Object.defineProperty(verify$4, "__esModule", { value: true }); const crypto$5 = require$$0$3; const util_1$2 = require$$1; const dsa_digest_js_1 = dsa_digest; const node_key_js_1 = node_key; const sign_js_1$4 = sign$6; const get_sign_verify_key_js_1 = get_sign_verify_key; const flags_js_1 = flags; let oneShotVerify; if (crypto$5.verify.length > 4 && flags_js_1.oneShotCallback) { oneShotVerify = (0, util_1$2.promisify)(crypto$5.verify); } else { oneShotVerify = crypto$5.verify; } const verify$3 = async (alg, key, signature, data) => { const keyObject = (0, get_sign_verify_key_js_1.default)(alg, key, 'verify'); if (alg.startsWith('HS')) { const expected = await (0, sign_js_1$4.default)(alg, keyObject, data); const actual = signature; try { return crypto$5.timingSafeEqual(actual, expected); } catch { return false; } } const algorithm = (0, dsa_digest_js_1.default)(alg); const keyInput = (0, node_key_js_1.default)(alg, keyObject); try { return await oneShotVerify(algorithm, data, keyInput, signature); } catch { return false; } }; verify$4.default = verify$3; Object.defineProperty(verify$5, "__esModule", { value: true }); verify$5.flattenedVerify = void 0; const base64url_js_1$4 = base64url$9; const verify_js_1$3 = verify$4; const errors_js_1$g = errors$5; const buffer_utils_js_1$a = buffer_utils; const is_disjoint_js_1$1 = is_disjoint; const is_object_js_1$8 = is_object; const check_key_type_js_1$1 = check_key_type; const validate_crit_js_1$1 = validate_crit; const validate_algorithms_js_1 = validate_algorithms; async function flattenedVerify(jws, key, options) { var _a; if (!(0, is_object_js_1$8.default)(jws)) { throw new errors_js_1$g.JWSInvalid('Flattened JWS must be an object'); } if (jws.protected === undefined && jws.header === undefined) { throw new errors_js_1$g.JWSInvalid('Flattened JWS must have either of the "protected" or "header" members'); } if (jws.protected !== undefined && typeof jws.protected !== 'string') { throw new errors_js_1$g.JWSInvalid('JWS Protected Header incorrect type'); } if (jws.payload === undefined) { throw new errors_js_1$g.JWSInvalid('JWS Payload missing'); } if (typeof jws.signature !== 'string') { throw new errors_js_1$g.JWSInvalid('JWS Signature missing or incorrect type'); } if (jws.header !== undefined && !(0, is_object_js_1$8.default)(jws.header)) { throw new errors_js_1$g.JWSInvalid('JWS Unprotected Header incorrect type'); } let parsedProt = {}; if (jws.protected) { try { const protectedHeader = (0, base64url_js_1$4.decode)(jws.protected); parsedProt = JSON.parse(buffer_utils_js_1$a.decoder.decode(protectedHeader)); } catch { throw new errors_js_1$g.JWSInvalid('JWS Protected Header is invalid'); } } if (!(0, is_disjoint_js_1$1.default)(parsedProt, jws.header)) { throw new errors_js_1$g.JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint'); } const joseHeader = { ...parsedProt, ...jws.header, }; const extensions = (0, validate_crit_js_1$1.default)(errors_js_1$g.JWSInvalid, new Map([['b64', true]]), options === null || options === void 0 ? void 0 : options.crit, parsedProt, joseHeader); let b64 = true; if (extensions.has('b64')) { b64 = parsedProt.b64; if (typeof b64 !== 'boolean') { throw new errors_js_1$g.JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean'); } } const { alg } = joseHeader; if (typeof alg !== 'string' || !alg) { throw new errors_js_1$g.JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid'); } const algorithms = options && (0, validate_algorithms_js_1.default)('algorithms', options.algorithms); if (algorithms && !algorithms.has(alg)) { throw new errors_js_1$g.JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter not allowed'); } if (b64) { if (typeof jws.payload !== 'string') { throw new errors_js_1$g.JWSInvalid('JWS Payload must be a string'); } } else if (typeof jws.payload !== 'string' && !(jws.payload instanceof Uint8Array)) { throw new errors_js_1$g.JWSInvalid('JWS Payload must be a string or an Uint8Array instance'); } let resolvedKey = false; if (typeof key === 'function') { key = await key(parsedProt, jws); resolvedKey = true; } (0, check_key_type_js_1$1.default)(alg, key, 'verify'); const data = (0, buffer_utils_js_1$a.concat)(buffer_utils_js_1$a.encoder.encode((_a = jws.protected) !== null && _a !== void 0 ? _a : ''), buffer_utils_js_1$a.encoder.encode('.'), typeof jws.payload === 'string' ? buffer_utils_js_1$a.encoder.encode(jws.payload) : jws.payload); let signature; try { signature = (0, base64url_js_1$4.decode)(jws.signature); } catch { throw new errors_js_1$g.JWSInvalid('Failed to base64url decode the signature'); } const verified = await (0, verify_js_1$3.default)(alg, key, signature, data); if (!verified) { throw new errors_js_1$g.JWSSignatureVerificationFailed(); } let payload; if (b64) { try { payload = (0, base64url_js_1$4.decode)(jws.payload); } catch { throw new errors_js_1$g.JWSInvalid('Failed to base64url decode the payload'); } } else if (typeof jws.payload === 'string') { payload = buffer_utils_js_1$a.encoder.encode(jws.payload); } else { payload = jws.payload; } const result = { payload }; if (jws.protected !== undefined) { result.protectedHeader = parsedProt; } if (jws.header !== undefined) { result.unprotectedHeader = jws.header; } if (resolvedKey) { return { ...result, key }; } return result; } verify$5.flattenedVerify = flattenedVerify; Object.defineProperty(verify$6, "__esModule", { value: true }); verify$6.compactVerify = void 0; const verify_js_1$2 = verify$5; const errors_js_1$f = errors$5; const buffer_utils_js_1$9 = buffer_utils; async function compactVerify(jws, key, options) { if (jws instanceof Uint8Array) { jws = buffer_utils_js_1$9.decoder.decode(jws); } if (typeof jws !== 'string') { throw new errors_js_1$f.JWSInvalid('Compact JWS must be a string or Uint8Array'); } const { 0: protectedHeader, 1: payload, 2: signature, length } = jws.split('.'); if (length !== 3) { throw new errors_js_1$f.JWSInvalid('Invalid Compact JWS'); } const verified = await (0, verify_js_1$2.flattenedVerify)({ payload, protected: protectedHeader, signature }, key, options); const result = { payload: verified.payload, protectedHeader: verified.protectedHeader }; if (typeof key === 'function') { return { ...result, key: verified.key }; } return result; } verify$6.compactVerify = compactVerify; var verify$2 = {}; Object.defineProperty(verify$2, "__esModule", { value: true }); verify$2.generalVerify = void 0; const verify_js_1$1 = verify$5; const errors_js_1$e = errors$5; const is_object_js_1$7 = is_object; async function generalVerify(jws, key, options) { if (!(0, is_object_js_1$7.default)(jws)) { throw new errors_js_1$e.JWSInvalid('General JWS must be an object'); } if (!Array.isArray(jws.signatures) || !jws.signatures.every(is_object_js_1$7.default)) { throw new errors_js_1$e.JWSInvalid('JWS Signatures missing or incorrect type'); } for (const signature of jws.signatures) { try { return await (0, verify_js_1$1.flattenedVerify)({ header: signature.header, payload: jws.payload, protected: signature.protected, signature: signature.signature, }, key, options); } catch { } } throw new errors_js_1$e.JWSSignatureVerificationFailed(); } verify$2.generalVerify = generalVerify; var verify$1 = {}; var jwt_claims_set = {}; var epoch = {}; Object.defineProperty(epoch, "__esModule", { value: true }); epoch.default = (date) => Math.floor(date.getTime() / 1000); var secs = {}; Object.defineProperty(secs, "__esModule", { value: true }); const minute = 60; const hour = minute * 60; const day = hour * 24; const week = day * 7; const year = day * 365.25; const REGEX = /^(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)$/i; secs.default = (str) => { const matched = REGEX.exec(str); if (!matched) { throw new TypeError('Invalid time period format'); } const value = parseFloat(matched[1]); const unit = matched[2].toLowerCase(); switch (unit) { case 'sec': case 'secs': case 'second': case 'seconds': case 's': return Math.round(value); case 'minute': case 'minutes': case 'min': case 'mins': case 'm': return Math.round(value * minute); case 'hour': case 'hours': case 'hr': case 'hrs': case 'h': return Math.round(value * hour); case 'day': case 'days': case 'd': return Math.round(value * day); case 'week': case 'weeks': case 'w': return Math.round(value * week); default: return Math.round(value * year); } }; Object.defineProperty(jwt_claims_set, "__esModule", { value: true }); const errors_js_1$d = errors$5; const buffer_utils_js_1$8 = buffer_utils; const epoch_js_1$1 = epoch; const secs_js_1$1 = secs; const is_object_js_1$6 = is_object; const normalizeTyp = (value) => value.toLowerCase().replace(/^application\//, ''); const checkAudiencePresence = (audPayload, audOption) => { if (typeof audPayload === 'string') { return audOption.includes(audPayload); } if (Array.isArray(audPayload)) { return audOption.some(Set.prototype.has.bind(new Set(audPayload))); } return false; }; jwt_claims_set.default = (protectedHeader, encodedPayload, options = {}) => { const { typ } = options; if (typ && (typeof protectedHeader.typ !== 'string' || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) { throw new errors_js_1$d.JWTClaimValidationFailed('unexpected "typ" JWT header value', 'typ', 'check_failed'); } let payload; try { payload = JSON.parse(buffer_utils_js_1$8.decoder.decode(encodedPayload)); } catch { } if (!(0, is_object_js_1$6.default)(payload)) { throw new errors_js_1$d.JWTInvalid('JWT Claims Set must be a top-level JSON object'); } const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options; if (maxTokenAge !== undefined) requiredClaims.push('iat'); if (audience !== undefined) requiredClaims.push('aud'); if (subject !== undefined) requiredClaims.push('sub'); if (issuer !== undefined) requiredClaims.push('iss'); for (const claim of new Set(requiredClaims.reverse())) { if (!(claim in payload)) { throw new errors_js_1$d.JWTClaimValidationFailed(`missing required "${claim}" claim`, claim, 'missing'); } } if (issuer && !(Array.isArray(issuer) ? issuer : [issuer]).includes(payload.iss)) { throw new errors_js_1$d.JWTClaimValidationFailed('unexpected "iss" claim value', 'iss', 'check_failed'); } if (subject && payload.sub !== subject) { throw new errors_js_1$d.JWTClaimValidationFailed('unexpected "sub" claim value', 'sub', 'check_failed'); } if (audience && !checkAudiencePresence(payload.aud, typeof audience === 'string' ? [audience] : audience)) { throw new errors_js_1$d.JWTClaimValidationFailed('unexpected "aud" claim value', 'aud', 'check_failed'); } let tolerance; switch (typeof options.clockTolerance) { case 'string': tolerance = (0, secs_js_1$1.default)(options.clockTolerance); break; case 'number': tolerance = options.clockTolerance; break; case 'undefined': tolerance = 0; break; default: throw new TypeError('Invalid clockTolerance option type'); } const { currentDate } = options; const now = (0, epoch_js_1$1.default)(currentDate || new Date()); if ((payload.iat !== undefined || maxTokenAge) && typeof payload.iat !== 'number') { throw new errors_js_1$d.JWTClaimValidationFailed('"iat" claim must be a number', 'iat', 'invalid'); } if (payload.nbf !== undefined) { if (typeof payload.nbf !== 'number') { throw new errors_js_1$d.JWTClaimValidationFailed('"nbf" claim must be a number', 'nbf', 'invalid'); } if (payload.nbf > now + tolerance) { throw new errors_js_1$d.JWTClaimValidationFailed('"nbf" claim timestamp check failed', 'nbf', 'check_failed'); } } if (payload.exp !== undefined) { if (typeof payload.exp !== 'number') { throw new errors_js_1$d.JWTClaimValidationFailed('"exp" claim must be a number', 'exp', 'invalid'); } if (payload.exp <= now - tolerance) { throw new errors_js_1$d.JWTExpired('"exp" claim timestamp check failed', 'exp', 'check_failed'); } } if (maxTokenAge) { const age = now - payload.iat; const max = typeof maxTokenAge === 'number' ? maxTokenAge : (0, secs_js_1$1.default)(maxTokenAge); if (age - tolerance > max) { throw new errors_js_1$d.JWTExpired('"iat" claim timestamp check failed (too far in the past)', 'iat', 'check_failed'); } if (age < 0 - tolerance) { throw new errors_js_1$d.JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed'); } } return payload; }; Object.defineProperty(verify$1, "__esModule", { value: true }); verify$1.jwtVerify = void 0; const verify_js_1 = verify$6; const jwt_claims_set_js_1$2 = jwt_claims_set; const errors_js_1$c = errors$5; async function jwtVerify(jwt, key, options) { var _a; const verified = await (0, verify_js_1.compactVerify)(jwt, key, options); if (((_a = verified.protectedHeader.crit) === null || _a === void 0 ? void 0 : _a.includes('b64')) && verified.protectedHeader.b64 === false) { throw new errors_js_1$c.JWTInvalid('JWTs MUST NOT use unencoded payload'); } const payload = (0, jwt_claims_set_js_1$2.default)(verified.protectedHeader, verified.payload, options); const result = { payload, protectedHeader: verified.protectedHeader }; if (typeof key === 'function') { return { ...result, key: verified.key }; } return result; } verify$1.jwtVerify = jwtVerify; var decrypt$1 = {}; Object.defineProperty(decrypt$1, "__esModule", { value: true }); decrypt$1.jwtDecrypt = void 0; const decrypt_js_1 = decrypt$8; const jwt_claims_set_js_1$1 = jwt_claims_set; const errors_js_1$b = errors$5; async function jwtDecrypt(jwt, key, options) { const decrypted = await (0, decrypt_js_1.compactDecrypt)(jwt, key, options); const payload = (0, jwt_claims_set_js_1$1.default)(decrypted.protectedHeader, decrypted.plaintext, options); const { protectedHeader } = decrypted; if (protectedHeader.iss !== undefined && protectedHeader.iss !== payload.iss) { throw new errors_js_1$b.JWTClaimValidationFailed('replicated "iss" claim header parameter mismatch', 'iss', 'mismatch'); } if (protectedHeader.sub !== undefined && protectedHeader.sub !== payload.sub) { throw new errors_js_1$b.JWTClaimValidationFailed('replicated "sub" claim header parameter mismatch', 'sub', 'mismatch'); } if (protectedHeader.aud !== undefined && JSON.stringify(protectedHeader.aud) !== JSON.stringify(payload.aud)) { throw new errors_js_1$b.JWTClaimValidationFailed('replicated "aud" claim header parameter mismatch', 'aud', 'mismatch'); } const result = { payload, protectedHeader }; if (typeof key === 'function') { return { ...result, key: decrypted.key }; } return result; } decrypt$1.jwtDecrypt = jwtDecrypt; var encrypt$1 = {}; Object.defineProperty(encrypt$1, "__esModule", { value: true }); encrypt$1.CompactEncrypt = void 0; const encrypt_js_1$1 = encrypt$2; class CompactEncrypt { constructor(plaintext) { this._flattened = new encrypt_js_1$1.FlattenedEncrypt(plaintext); } setContentEncryptionKey(cek) { this._flattened.setContentEncryptionKey(cek); return this; } setInitializationVector(iv) { this._flattened.setInitializationVector(iv); return this; } setProtectedHeader(protectedHeader) { this._flattened.setProtectedHeader(protectedHeader); return this; } setKeyManagementParameters(parameters) { this._flattened.setKeyManagementParameters(parameters); return this; } async encrypt(key, options) { const jwe = await this._flattened.encrypt(key, options); return [jwe.protected, jwe.encrypted_key, jwe.iv, jwe.ciphertext, jwe.tag].join('.'); } } encrypt$1.CompactEncrypt = CompactEncrypt; var sign$4 = {}; var sign$3 = {}; Object.defineProperty(sign$3, "__esModule", { value: true }); sign$3.FlattenedSign = void 0; const base64url_js_1$3 = base64url$9; const sign_js_1$3 = sign$6; const is_disjoint_js_1 = is_disjoint; const errors_js_1$a = errors$5; const buffer_utils_js_1$7 = buffer_utils; const check_key_type_js_1 = check_key_type; const validate_crit_js_1 = validate_crit; class FlattenedSign { constructor(payload) { if (!(payload instanceof Uint8Array)) { throw new TypeError('payload must be an instance of Uint8Array'); } this._payload = payload; } setProtectedHeader(protectedHeader) { if (this._protectedHeader) { throw new TypeError('setProtectedHeader can only be called once'); } this._protectedHeader = protectedHeader; return this; } setUnprotectedHeader(unprotectedHeader) { if (this._unprotectedHeader) { throw new TypeError('setUnprotectedHeader can only be called once'); } this._unprotectedHeader = unprotectedHeader; return this; } async sign(key, options) { if (!this._protectedHeader && !this._unprotectedHeader) { throw new errors_js_1$a.JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()'); } if (!(0, is_disjoint_js_1.default)(this._protectedHeader, this._unprotectedHeader)) { throw new errors_js_1$a.JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint'); } const joseHeader = { ...this._protectedHeader, ...this._unprotectedHeader, }; const extensions = (0, validate_crit_js_1.default)(errors_js_1$a.JWSInvalid, new Map([['b64', true]]), options === null || options === void 0 ? void 0 : options.crit, this._protectedHeader, joseHeader); let b64 = true; if (extensions.has('b64')) { b64 = this._protectedHeader.b64; if (typeof b64 !== 'boolean') { throw new errors_js_1$a.JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean'); } } const { alg } = joseHeader; if (typeof alg !== 'string' || !alg) { throw new errors_js_1$a.JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid'); } (0, check_key_type_js_1.default)(alg, key, 'sign'); let payload = this._payload; if (b64) { payload = buffer_utils_js_1$7.encoder.encode((0, base64url_js_1$3.encode)(payload)); } let protectedHeader; if (this._protectedHeader) { protectedHeader = buffer_utils_js_1$7.encoder.encode((0, base64url_js_1$3.encode)(JSON.stringify(this._protectedHeader))); } else { protectedHeader = buffer_utils_js_1$7.encoder.encode(''); } const data = (0, buffer_utils_js_1$7.concat)(protectedHeader, buffer_utils_js_1$7.encoder.encode('.'), payload); const signature = await (0, sign_js_1$3.default)(alg, key, data); const jws = { signature: (0, base64url_js_1$3.encode)(signature), payload: '', }; if (b64) { jws.payload = buffer_utils_js_1$7.decoder.decode(payload); } if (this._unprotectedHeader) { jws.header = this._unprotectedHeader; } if (this._protectedHeader) { jws.protected = buffer_utils_js_1$7.decoder.decode(protectedHeader); } return jws; } } sign$3.FlattenedSign = FlattenedSign; Object.defineProperty(sign$4, "__esModule", { value: true }); sign$4.CompactSign = void 0; const sign_js_1$2 = sign$3; class CompactSign { constructor(payload) { this._flattened = new sign_js_1$2.FlattenedSign(payload); } setProtectedHeader(protectedHeader) { this._flattened.setProtectedHeader(protectedHeader); return this; } async sign(key, options) { const jws = await this._flattened.sign(key, options); if (jws.payload === undefined) { throw new TypeError('use the flattened module for creating JWS with b64: false'); } return `${jws.protected}.${jws.payload}.${jws.signature}`; } } sign$4.CompactSign = CompactSign; var sign$2 = {}; Object.defineProperty(sign$2, "__esModule", { value: true }); sign$2.GeneralSign = void 0; const sign_js_1$1 = sign$3; const errors_js_1$9 = errors$5; class IndividualSignature { constructor(sig, key, options) { this.parent = sig; this.key = key; this.options = options; } setProtectedHeader(protectedHeader) { if (this.protectedHeader) { throw new TypeError('setProtectedHeader can only be called once'); } this.protectedHeader = protectedHeader; return this; } setUnprotectedHeader(unprotectedHeader) { if (this.unprotectedHeader) { throw new TypeError('setUnprotectedHeader can only be called once'); } this.unprotectedHeader = unprotectedHeader; return this; } addSignature(...args) { return this.parent.addSignature(...args); } sign(...args) { return this.parent.sign(...args); } done() { return this.parent; } } class GeneralSign { constructor(payload) { this._signatures = []; this._payload = payload; } addSignature(key, options) { const signature = new IndividualSignature(this, key, options); this._signatures.push(signature); return signature; } async sign() { if (!this._signatures.length) { throw new errors_js_1$9.JWSInvalid('at least one signature must be added'); } const jws = { signatures: [], payload: '', }; for (let i = 0; i < this._signatures.length; i++) { const signature = this._signatures[i]; const flattened = new sign_js_1$1.FlattenedSign(this._payload); flattened.setProtectedHeader(signature.protectedHeader); flattened.setUnprotectedHeader(signature.unprotectedHeader); const { payload, ...rest } = await flattened.sign(signature.key, signature.options); if (i === 0) { jws.payload = payload; } else if (jws.payload !== payload) { throw new errors_js_1$9.JWSInvalid('inconsistent use of JWS Unencoded Payload (RFC7797)'); } jws.signatures.push(rest); } return jws; } } sign$2.GeneralSign = GeneralSign; var sign$1 = {}; var produce = {}; Object.defineProperty(produce, "__esModule", { value: true }); produce.ProduceJWT = void 0; const epoch_js_1 = epoch; const is_object_js_1$5 = is_object; const secs_js_1 = secs; class ProduceJWT { constructor(payload) { if (!(0, is_object_js_1$5.default)(payload)) { throw new TypeError('JWT Claims Set MUST be an object'); } this._payload = payload; } setIssuer(issuer) { this._payload = { ...this._payload, iss: issuer }; return this; } setSubject(subject) { this._payload = { ...this._payload, sub: subject }; return this; } setAudience(audience) { this._payload = { ...this._payload, aud: audience }; return this; } setJti(jwtId) { this._payload = { ...this._payload, jti: jwtId }; return this; } setNotBefore(input) { if (typeof input === 'number') { this._payload = { ...this._payload, nbf: input }; } else { this._payload = { ...this._payload, nbf: (0, epoch_js_1.default)(new Date()) + (0, secs_js_1.default)(input) }; } return this; } setExpirationTime(input) { if (typeof input === 'number') { this._payload = { ...this._payload, exp: input }; } else { this._payload = { ...this._payload, exp: (0, epoch_js_1.default)(new Date()) + (0, secs_js_1.default)(input) }; } return this; } setIssuedAt(input) { if (typeof input === 'undefined') { this._payload = { ...this._payload, iat: (0, epoch_js_1.default)(new Date()) }; } else { this._payload = { ...this._payload, iat: input }; } return this; } } produce.ProduceJWT = ProduceJWT; Object.defineProperty(sign$1, "__esModule", { value: true }); sign$1.SignJWT = void 0; const sign_js_1 = sign$4; const errors_js_1$8 = errors$5; const buffer_utils_js_1$6 = buffer_utils; const produce_js_1$2 = produce; class SignJWT extends produce_js_1$2.ProduceJWT { setProtectedHeader(protectedHeader) { this._protectedHeader = protectedHeader; return this; } async sign(key, options) { var _a; const sig = new sign_js_1.CompactSign(buffer_utils_js_1$6.encoder.encode(JSON.stringify(this._payload))); sig.setProtectedHeader(this._protectedHeader); if (Array.isArray((_a = this._protectedHeader) === null || _a === void 0 ? void 0 : _a.crit) && this._protectedHeader.crit.includes('b64') && this._protectedHeader.b64 === false) { throw new errors_js_1$8.JWTInvalid('JWTs MUST NOT use unencoded payload'); } return sig.sign(key, options); } } sign$1.SignJWT = SignJWT; var encrypt = {}; Object.defineProperty(encrypt, "__esModule", { value: true }); encrypt.EncryptJWT = void 0; const encrypt_js_1 = encrypt$1; const buffer_utils_js_1$5 = buffer_utils; const produce_js_1$1 = produce; class EncryptJWT extends produce_js_1$1.ProduceJWT { setProtectedHeader(protectedHeader) { if (this._protectedHeader) { throw new TypeError('setProtectedHeader can only be called once'); } this._protectedHeader = protectedHeader; return this; } setKeyManagementParameters(parameters) { if (this._keyManagementParameters) { throw new TypeError('setKeyManagementParameters can only be called once'); } this._keyManagementParameters = parameters; return this; } setContentEncryptionKey(cek) { if (this._cek) { throw new TypeError('setContentEncryptionKey can only be called once'); } this._cek = cek; return this; } setInitializationVector(iv) { if (this._iv) { throw new TypeError('setInitializationVector can only be called once'); } this._iv = iv; return this; } replicateIssuerAsHeader() { this._replicateIssuerAsHeader = true; return this; } replicateSubjectAsHeader() { this._replicateSubjectAsHeader = true; return this; } replicateAudienceAsHeader() { this._replicateAudienceAsHeader = true; return this; } async encrypt(key, options) { const enc = new encrypt_js_1.CompactEncrypt(buffer_utils_js_1$5.encoder.encode(JSON.stringify(this._payload))); if (this._replicateIssuerAsHeader) { this._protectedHeader = { ...this._protectedHeader, iss: this._payload.iss }; } if (this._replicateSubjectAsHeader) { this._protectedHeader = { ...this._protectedHeader, sub: this._payload.sub }; } if (this._replicateAudienceAsHeader) { this._protectedHeader = { ...this._protectedHeader, aud: this._payload.aud }; } enc.setProtectedHeader(this._protectedHeader); if (this._iv) { enc.setInitializationVector(this._iv); } if (this._cek) { enc.setContentEncryptionKey(this._cek); } if (this._keyManagementParameters) { enc.setKeyManagementParameters(this._keyManagementParameters); } return enc.encrypt(key, options); } } encrypt.EncryptJWT = EncryptJWT; var thumbprint = {}; Object.defineProperty(thumbprint, "__esModule", { value: true }); thumbprint.calculateJwkThumbprintUri = thumbprint.calculateJwkThumbprint = void 0; const digest_js_1 = digest$1; const base64url_js_1$2 = base64url$9; const errors_js_1$7 = errors$5; const buffer_utils_js_1$4 = buffer_utils; const is_object_js_1$4 = is_object; const check = (value, description) => { if (typeof value !== 'string' || !value) { throw new errors_js_1$7.JWKInvalid(`${description} missing or invalid`); } }; async function calculateJwkThumbprint(jwk, digestAlgorithm) { if (!(0, is_object_js_1$4.default)(jwk)) { throw new TypeError('JWK must be an object'); } digestAlgorithm !== null && digestAlgorithm !== void 0 ? digestAlgorithm : (digestAlgorithm = 'sha256'); if (digestAlgorithm !== 'sha256' && digestAlgorithm !== 'sha384' && digestAlgorithm !== 'sha512') { throw new TypeError('digestAlgorithm must one of "sha256", "sha384", or "sha512"'); } let components; switch (jwk.kty) { case 'EC': check(jwk.crv, '"crv" (Curve) Parameter'); check(jwk.x, '"x" (X Coordinate) Parameter'); check(jwk.y, '"y" (Y Coordinate) Parameter'); components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }; break; case 'OKP': check(jwk.crv, '"crv" (Subtype of Key Pair) Parameter'); check(jwk.x, '"x" (Public Key) Parameter'); components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x }; break; case 'RSA': check(jwk.e, '"e" (Exponent) Parameter'); check(jwk.n, '"n" (Modulus) Parameter'); components = { e: jwk.e, kty: jwk.kty, n: jwk.n }; break; case 'oct': check(jwk.k, '"k" (Key Value) Parameter'); components = { k: jwk.k, kty: jwk.kty }; break; default: throw new errors_js_1$7.JOSENotSupported('"kty" (Key Type) Parameter missing or unsupported'); } const data = buffer_utils_js_1$4.encoder.encode(JSON.stringify(components)); return (0, base64url_js_1$2.encode)(await (0, digest_js_1.default)(digestAlgorithm, data)); } thumbprint.calculateJwkThumbprint = calculateJwkThumbprint; async function calculateJwkThumbprintUri(jwk, digestAlgorithm) { digestAlgorithm !== null && digestAlgorithm !== void 0 ? digestAlgorithm : (digestAlgorithm = 'sha256'); const thumbprint = await calculateJwkThumbprint(jwk, digestAlgorithm); return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`; } thumbprint.calculateJwkThumbprintUri = calculateJwkThumbprintUri; var embedded = {}; Object.defineProperty(embedded, "__esModule", { value: true }); embedded.EmbeddedJWK = void 0; const import_js_1$1 = _import; const is_object_js_1$3 = is_object; const errors_js_1$6 = errors$5; async function EmbeddedJWK(protectedHeader, token) { const joseHeader = { ...protectedHeader, ...token === null || token === void 0 ? void 0 : token.header, }; if (!(0, is_object_js_1$3.default)(joseHeader.jwk)) { throw new errors_js_1$6.JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a JSON object'); } const key = await (0, import_js_1$1.importJWK)({ ...joseHeader.jwk, ext: true }, joseHeader.alg, true); if (key instanceof Uint8Array || key.type !== 'public') { throw new errors_js_1$6.JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a public key'); } return key; } embedded.EmbeddedJWK = EmbeddedJWK; var local = {}; Object.defineProperty(local, "__esModule", { value: true }); local.createLocalJWKSet = local.LocalJWKSet = local.isJWKSLike = void 0; const import_js_1 = _import; const errors_js_1$5 = errors$5; const is_object_js_1$2 = is_object; function getKtyFromAlg$1(alg) { switch (typeof alg === 'string' && alg.slice(0, 2)) { case 'RS': case 'PS': return 'RSA'; case 'ES': return 'EC'; case 'Ed': return 'OKP'; default: throw new errors_js_1$5.JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set'); } } function isJWKSLike(jwks) { return (jwks && typeof jwks === 'object' && Array.isArray(jwks.keys) && jwks.keys.every(isJWKLike)); } local.isJWKSLike = isJWKSLike; function isJWKLike(key) { return (0, is_object_js_1$2.default)(key); } function clone$5(obj) { if (typeof structuredClone === 'function') { return structuredClone(obj); } return JSON.parse(JSON.stringify(obj)); } class LocalJWKSet { constructor(jwks) { this._cached = new WeakMap(); if (!isJWKSLike(jwks)) { throw new errors_js_1$5.JWKSInvalid('JSON Web Key Set malformed'); } this._jwks = clone$5(jwks); } async getKey(protectedHeader, token) { const { alg, kid } = { ...protectedHeader, ...token === null || token === void 0 ? void 0 : token.header }; const kty = getKtyFromAlg$1(alg); const candidates = this._jwks.keys.filter((jwk) => { let candidate = kty === jwk.kty; if (candidate && typeof kid === 'string') { candidate = kid === jwk.kid; } if (candidate && typeof jwk.alg === 'string') { candidate = alg === jwk.alg; } if (candidate && typeof jwk.use === 'string') { candidate = jwk.use === 'sig'; } if (candidate && Array.isArray(jwk.key_ops)) { candidate = jwk.key_ops.includes('verify'); } if (candidate && alg === 'EdDSA') { candidate = jwk.crv === 'Ed25519' || jwk.crv === 'Ed448'; } if (candidate) { switch (alg) { case 'ES256': candidate = jwk.crv === 'P-256'; break; case 'ES256K': candidate = jwk.crv === 'secp256k1'; break; case 'ES384': candidate = jwk.crv === 'P-384'; break; case 'ES512': candidate = jwk.crv === 'P-521'; break; } } return candidate; }); const { 0: jwk, length } = candidates; if (length === 0) { throw new errors_js_1$5.JWKSNoMatchingKey(); } else if (length !== 1) { const error = new errors_js_1$5.JWKSMultipleMatchingKeys(); const { _cached } = this; error[Symbol.asyncIterator] = async function* () { for (const jwk of candidates) { try { yield await importWithAlgCache(_cached, jwk, alg); } catch { continue; } } }; throw error; } return importWithAlgCache(this._cached, jwk, alg); } } local.LocalJWKSet = LocalJWKSet; async function importWithAlgCache(cache, jwk, alg) { const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk); if (cached[alg] === undefined) { const key = await (0, import_js_1.importJWK)({ ...jwk, ext: true }, alg); if (key instanceof Uint8Array || key.type !== 'public') { throw new errors_js_1$5.JWKSInvalid('JSON Web Key Set members must be public keys'); } cached[alg] = key; } return cached[alg]; } function createLocalJWKSet(jwks) { const set = new LocalJWKSet(jwks); return async function (protectedHeader, token) { return set.getKey(protectedHeader, token); }; } local.createLocalJWKSet = createLocalJWKSet; var remote = {}; var fetch_jwks = {}; Object.defineProperty(fetch_jwks, "__esModule", { value: true }); const http$2 = require$$0$5; const https$2 = require$$1$2; const events_1$3 = require$$1$3; const errors_js_1$4 = errors$5; const buffer_utils_js_1$3 = buffer_utils; const fetchJwks = async (url, timeout, options) => { let get; switch (url.protocol) { case 'https:': get = https$2.get; break; case 'http:': get = http$2.get; break; default: throw new TypeError('Unsupported URL protocol.'); } const { agent, headers } = options; const req = get(url.href, { agent, timeout, headers, }); const [response] = (await Promise.race([(0, events_1$3.once)(req, 'response'), (0, events_1$3.once)(req, 'timeout')])); if (!response) { req.destroy(); throw new errors_js_1$4.JWKSTimeout(); } if (response.statusCode !== 200) { throw new errors_js_1$4.JOSEError('Expected 200 OK from the JSON Web Key Set HTTP response'); } const parts = []; for await (const part of response) { parts.push(part); } try { return JSON.parse(buffer_utils_js_1$3.decoder.decode((0, buffer_utils_js_1$3.concat)(...parts))); } catch { throw new errors_js_1$4.JOSEError('Failed to parse the JSON Web Key Set HTTP response as JSON'); } }; fetch_jwks.default = fetchJwks; Object.defineProperty(remote, "__esModule", { value: true }); remote.createRemoteJWKSet = void 0; const fetch_jwks_js_1 = fetch_jwks; const errors_js_1$3 = errors$5; const local_js_1 = local; function isCloudflareWorkers() { return (typeof WebSocketPair !== 'undefined' || (typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers') || (typeof EdgeRuntime !== 'undefined' && EdgeRuntime === 'vercel')); } class RemoteJWKSet extends local_js_1.LocalJWKSet { constructor(url, options) { super({ keys: [] }); this._jwks = undefined; if (!(url instanceof URL)) { throw new TypeError('url must be an instance of URL'); } this._url = new URL(url.href); this._options = { agent: options === null || options === void 0 ? void 0 : options.agent, headers: options === null || options === void 0 ? void 0 : options.headers }; this._timeoutDuration = typeof (options === null || options === void 0 ? void 0 : options.timeoutDuration) === 'number' ? options === null || options === void 0 ? void 0 : options.timeoutDuration : 5000; this._cooldownDuration = typeof (options === null || options === void 0 ? void 0 : options.cooldownDuration) === 'number' ? options === null || options === void 0 ? void 0 : options.cooldownDuration : 30000; this._cacheMaxAge = typeof (options === null || options === void 0 ? void 0 : options.cacheMaxAge) === 'number' ? options === null || options === void 0 ? void 0 : options.cacheMaxAge : 600000; } coolingDown() { return typeof this._jwksTimestamp === 'number' ? Date.now() < this._jwksTimestamp + this._cooldownDuration : false; } fresh() { return typeof this._jwksTimestamp === 'number' ? Date.now() < this._jwksTimestamp + this._cacheMaxAge : false; } async getKey(protectedHeader, token) { if (!this._jwks || !this.fresh()) { await this.reload(); } try { return await super.getKey(protectedHeader, token); } catch (err) { if (err instanceof errors_js_1$3.JWKSNoMatchingKey) { if (this.coolingDown() === false) { await this.reload(); return super.getKey(protectedHeader, token); } } throw err; } } async reload() { if (this._pendingFetch && isCloudflareWorkers()) { this._pendingFetch = undefined; } this._pendingFetch || (this._pendingFetch = (0, fetch_jwks_js_1.default)(this._url, this._timeoutDuration, this._options) .then((json) => { if (!(0, local_js_1.isJWKSLike)(json)) { throw new errors_js_1$3.JWKSInvalid('JSON Web Key Set malformed'); } this._jwks = { keys: json.keys }; this._jwksTimestamp = Date.now(); this._pendingFetch = undefined; }) .catch((err) => { this._pendingFetch = undefined; throw err; })); await this._pendingFetch; } } function createRemoteJWKSet(url, options) { const set = new RemoteJWKSet(url, options); return async function (protectedHeader, token) { return set.getKey(protectedHeader, token); }; } remote.createRemoteJWKSet = createRemoteJWKSet; var unsecured = {}; Object.defineProperty(unsecured, "__esModule", { value: true }); unsecured.UnsecuredJWT = void 0; const base64url$8 = base64url$9; const buffer_utils_js_1$2 = buffer_utils; const errors_js_1$2 = errors$5; const jwt_claims_set_js_1 = jwt_claims_set; const produce_js_1 = produce; class UnsecuredJWT extends produce_js_1.ProduceJWT { encode() { const header = base64url$8.encode(JSON.stringify({ alg: 'none' })); const payload = base64url$8.encode(JSON.stringify(this._payload)); return `${header}.${payload}.`; } static decode(jwt, options) { if (typeof jwt !== 'string') { throw new errors_js_1$2.JWTInvalid('Unsecured JWT must be a string'); } const { 0: encodedHeader, 1: encodedPayload, 2: signature, length } = jwt.split('.'); if (length !== 3 || signature !== '') { throw new errors_js_1$2.JWTInvalid('Invalid Unsecured JWT'); } let header; try { header = JSON.parse(buffer_utils_js_1$2.decoder.decode(base64url$8.decode(encodedHeader))); if (header.alg !== 'none') throw new Error(); } catch { throw new errors_js_1$2.JWTInvalid('Invalid Unsecured JWT'); } const payload = (0, jwt_claims_set_js_1.default)(header, base64url$8.decode(encodedPayload), options); return { payload, header }; } } unsecured.UnsecuredJWT = UnsecuredJWT; var decode_protected_header = {}; var base64url$7 = {}; Object.defineProperty(base64url$7, "__esModule", { value: true }); base64url$7.decode = base64url$7.encode = void 0; const base64url$6 = base64url$9; base64url$7.encode = base64url$6.encode; base64url$7.decode = base64url$6.decode; Object.defineProperty(decode_protected_header, "__esModule", { value: true }); decode_protected_header.decodeProtectedHeader = void 0; const base64url_js_1$1 = base64url$7; const buffer_utils_js_1$1 = buffer_utils; const is_object_js_1$1 = is_object; function decodeProtectedHeader(token) { let protectedB64u; if (typeof token === 'string') { const parts = token.split('.'); if (parts.length === 3 || parts.length === 5) { [protectedB64u] = parts; } } else if (typeof token === 'object' && token) { if ('protected' in token) { protectedB64u = token.protected; } else { throw new TypeError('Token does not contain a Protected Header'); } } try { if (typeof protectedB64u !== 'string' || !protectedB64u) { throw new Error(); } const result = JSON.parse(buffer_utils_js_1$1.decoder.decode((0, base64url_js_1$1.decode)(protectedB64u))); if (!(0, is_object_js_1$1.default)(result)) { throw new Error(); } return result; } catch { throw new TypeError('Invalid Token or Protected Header formatting'); } } decode_protected_header.decodeProtectedHeader = decodeProtectedHeader; var decode_jwt$1 = {}; Object.defineProperty(decode_jwt$1, "__esModule", { value: true }); decode_jwt$1.decodeJwt = void 0; const base64url_js_1 = base64url$7; const buffer_utils_js_1 = buffer_utils; const is_object_js_1 = is_object; const errors_js_1$1 = errors$5; function decodeJwt(jwt) { if (typeof jwt !== 'string') throw new errors_js_1$1.JWTInvalid('JWTs must use Compact JWS serialization, JWT must be a string'); const { 1: payload, length } = jwt.split('.'); if (length === 5) throw new errors_js_1$1.JWTInvalid('Only JWTs using Compact JWS serialization can be decoded'); if (length !== 3) throw new errors_js_1$1.JWTInvalid('Invalid JWT'); if (!payload) throw new errors_js_1$1.JWTInvalid('JWTs must contain a payload'); let decoded; try { decoded = (0, base64url_js_1.decode)(payload); } catch { throw new errors_js_1$1.JWTInvalid('Failed to base64url decode the payload'); } let result; try { result = JSON.parse(buffer_utils_js_1.decoder.decode(decoded)); } catch { throw new errors_js_1$1.JWTInvalid('Failed to parse the decoded payload as JSON'); } if (!(0, is_object_js_1.default)(result)) throw new errors_js_1$1.JWTInvalid('Invalid JWT Claims Set'); return result; } decode_jwt$1.decodeJwt = decodeJwt; var generate_key_pair = {}; var generate$3 = {}; Object.defineProperty(generate$3, "__esModule", { value: true }); generate$3.generateKeyPair = generate$3.generateSecret = void 0; const crypto_1$1 = require$$0$3; const util_1$1 = require$$1; const random_js_1 = random$4; const check_modulus_length_js_1 = check_modulus_length; const errors_js_1 = errors$5; const generate$2 = (0, util_1$1.promisify)(crypto_1$1.generateKeyPair); async function generateSecret$1(alg, options) { let length; switch (alg) { case 'HS256': case 'HS384': case 'HS512': case 'A128CBC-HS256': case 'A192CBC-HS384': case 'A256CBC-HS512': length = parseInt(alg.slice(-3), 10); break; case 'A128KW': case 'A192KW': case 'A256KW': case 'A128GCMKW': case 'A192GCMKW': case 'A256GCMKW': case 'A128GCM': case 'A192GCM': case 'A256GCM': length = parseInt(alg.slice(1, 4), 10); break; default: throw new errors_js_1.JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value'); } return (0, crypto_1$1.createSecretKey)((0, random_js_1.default)(new Uint8Array(length >> 3))); } generate$3.generateSecret = generateSecret$1; async function generateKeyPair$1(alg, options) { var _a, _b; switch (alg) { case 'RS256': case 'RS384': case 'RS512': case 'PS256': case 'PS384': case 'PS512': case 'RSA-OAEP': case 'RSA-OAEP-256': case 'RSA-OAEP-384': case 'RSA-OAEP-512': case 'RSA1_5': { const modulusLength = (_a = options === null || options === void 0 ? void 0 : options.modulusLength) !== null && _a !== void 0 ? _a : 2048; if (typeof modulusLength !== 'number' || modulusLength < 2048) { throw new errors_js_1.JOSENotSupported('Invalid or unsupported modulusLength option provided, 2048 bits or larger keys must be used'); } const keypair = await generate$2('rsa', { modulusLength, publicExponent: 0x10001, }); (0, check_modulus_length_js_1.setModulusLength)(keypair.privateKey, modulusLength); (0, check_modulus_length_js_1.setModulusLength)(keypair.publicKey, modulusLength); return keypair; } case 'ES256': return generate$2('ec', { namedCurve: 'P-256' }); case 'ES256K': return generate$2('ec', { namedCurve: 'secp256k1' }); case 'ES384': return generate$2('ec', { namedCurve: 'P-384' }); case 'ES512': return generate$2('ec', { namedCurve: 'P-521' }); case 'EdDSA': { switch (options === null || options === void 0 ? void 0 : options.crv) { case undefined: case 'Ed25519': return generate$2('ed25519'); case 'Ed448': return generate$2('ed448'); default: throw new errors_js_1.JOSENotSupported('Invalid or unsupported crv option provided, supported values are Ed25519 and Ed448'); } } case 'ECDH-ES': case 'ECDH-ES+A128KW': case 'ECDH-ES+A192KW': case 'ECDH-ES+A256KW': const crv = (_b = options === null || options === void 0 ? void 0 : options.crv) !== null && _b !== void 0 ? _b : 'P-256'; switch (crv) { case undefined: case 'P-256': case 'P-384': case 'P-521': return generate$2('ec', { namedCurve: crv }); case 'X25519': return generate$2('x25519'); case 'X448': return generate$2('x448'); default: throw new errors_js_1.JOSENotSupported('Invalid or unsupported crv option provided, supported values are P-256, P-384, P-521, X25519, and X448'); } default: throw new errors_js_1.JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value'); } } generate$3.generateKeyPair = generateKeyPair$1; Object.defineProperty(generate_key_pair, "__esModule", { value: true }); generate_key_pair.generateKeyPair = void 0; const generate_js_1$1 = generate$3; async function generateKeyPair(alg, options) { return (0, generate_js_1$1.generateKeyPair)(alg, options); } generate_key_pair.generateKeyPair = generateKeyPair; var generate_secret = {}; Object.defineProperty(generate_secret, "__esModule", { value: true }); generate_secret.generateSecret = void 0; const generate_js_1 = generate$3; async function generateSecret(alg, options) { return (0, generate_js_1.generateSecret)(alg, options); } generate_secret.generateSecret = generateSecret; var runtime$1 = {}; var runtime = {}; Object.defineProperty(runtime, "__esModule", { value: true }); runtime.default = 'node:crypto'; Object.defineProperty(runtime$1, "__esModule", { value: true }); const runtime_js_1 = runtime; runtime$1.default = runtime_js_1.default; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.cryptoRuntime = exports.base64url = exports.generateSecret = exports.generateKeyPair = exports.errors = exports.decodeJwt = exports.decodeProtectedHeader = exports.importJWK = exports.importX509 = exports.importPKCS8 = exports.importSPKI = exports.exportJWK = exports.exportSPKI = exports.exportPKCS8 = exports.UnsecuredJWT = exports.createRemoteJWKSet = exports.createLocalJWKSet = exports.EmbeddedJWK = exports.calculateJwkThumbprintUri = exports.calculateJwkThumbprint = exports.EncryptJWT = exports.SignJWT = exports.GeneralSign = exports.FlattenedSign = exports.CompactSign = exports.FlattenedEncrypt = exports.CompactEncrypt = exports.jwtDecrypt = exports.jwtVerify = exports.generalVerify = exports.flattenedVerify = exports.compactVerify = exports.GeneralEncrypt = exports.generalDecrypt = exports.flattenedDecrypt = exports.compactDecrypt = void 0; var decrypt_js_1 = decrypt$8; Object.defineProperty(exports, "compactDecrypt", { enumerable: true, get: function () { return decrypt_js_1.compactDecrypt; } }); var decrypt_js_2 = decrypt$7; Object.defineProperty(exports, "flattenedDecrypt", { enumerable: true, get: function () { return decrypt_js_2.flattenedDecrypt; } }); var decrypt_js_3 = decrypt$2; Object.defineProperty(exports, "generalDecrypt", { enumerable: true, get: function () { return decrypt_js_3.generalDecrypt; } }); var encrypt_js_1 = encrypt$3; Object.defineProperty(exports, "GeneralEncrypt", { enumerable: true, get: function () { return encrypt_js_1.GeneralEncrypt; } }); var verify_js_1 = verify$6; Object.defineProperty(exports, "compactVerify", { enumerable: true, get: function () { return verify_js_1.compactVerify; } }); var verify_js_2 = verify$5; Object.defineProperty(exports, "flattenedVerify", { enumerable: true, get: function () { return verify_js_2.flattenedVerify; } }); var verify_js_3 = verify$2; Object.defineProperty(exports, "generalVerify", { enumerable: true, get: function () { return verify_js_3.generalVerify; } }); var verify_js_4 = verify$1; Object.defineProperty(exports, "jwtVerify", { enumerable: true, get: function () { return verify_js_4.jwtVerify; } }); var decrypt_js_4 = decrypt$1; Object.defineProperty(exports, "jwtDecrypt", { enumerable: true, get: function () { return decrypt_js_4.jwtDecrypt; } }); var encrypt_js_2 = encrypt$1; Object.defineProperty(exports, "CompactEncrypt", { enumerable: true, get: function () { return encrypt_js_2.CompactEncrypt; } }); var encrypt_js_3 = encrypt$2; Object.defineProperty(exports, "FlattenedEncrypt", { enumerable: true, get: function () { return encrypt_js_3.FlattenedEncrypt; } }); var sign_js_1 = sign$4; Object.defineProperty(exports, "CompactSign", { enumerable: true, get: function () { return sign_js_1.CompactSign; } }); var sign_js_2 = sign$3; Object.defineProperty(exports, "FlattenedSign", { enumerable: true, get: function () { return sign_js_2.FlattenedSign; } }); var sign_js_3 = sign$2; Object.defineProperty(exports, "GeneralSign", { enumerable: true, get: function () { return sign_js_3.GeneralSign; } }); var sign_js_4 = sign$1; Object.defineProperty(exports, "SignJWT", { enumerable: true, get: function () { return sign_js_4.SignJWT; } }); var encrypt_js_4 = encrypt; Object.defineProperty(exports, "EncryptJWT", { enumerable: true, get: function () { return encrypt_js_4.EncryptJWT; } }); var thumbprint_js_1 = thumbprint; Object.defineProperty(exports, "calculateJwkThumbprint", { enumerable: true, get: function () { return thumbprint_js_1.calculateJwkThumbprint; } }); Object.defineProperty(exports, "calculateJwkThumbprintUri", { enumerable: true, get: function () { return thumbprint_js_1.calculateJwkThumbprintUri; } }); var embedded_js_1 = embedded; Object.defineProperty(exports, "EmbeddedJWK", { enumerable: true, get: function () { return embedded_js_1.EmbeddedJWK; } }); var local_js_1 = local; Object.defineProperty(exports, "createLocalJWKSet", { enumerable: true, get: function () { return local_js_1.createLocalJWKSet; } }); var remote_js_1 = remote; Object.defineProperty(exports, "createRemoteJWKSet", { enumerable: true, get: function () { return remote_js_1.createRemoteJWKSet; } }); var unsecured_js_1 = unsecured; Object.defineProperty(exports, "UnsecuredJWT", { enumerable: true, get: function () { return unsecured_js_1.UnsecuredJWT; } }); var export_js_1 = _export; Object.defineProperty(exports, "exportPKCS8", { enumerable: true, get: function () { return export_js_1.exportPKCS8; } }); Object.defineProperty(exports, "exportSPKI", { enumerable: true, get: function () { return export_js_1.exportSPKI; } }); Object.defineProperty(exports, "exportJWK", { enumerable: true, get: function () { return export_js_1.exportJWK; } }); var import_js_1 = _import; Object.defineProperty(exports, "importSPKI", { enumerable: true, get: function () { return import_js_1.importSPKI; } }); Object.defineProperty(exports, "importPKCS8", { enumerable: true, get: function () { return import_js_1.importPKCS8; } }); Object.defineProperty(exports, "importX509", { enumerable: true, get: function () { return import_js_1.importX509; } }); Object.defineProperty(exports, "importJWK", { enumerable: true, get: function () { return import_js_1.importJWK; } }); var decode_protected_header_js_1 = decode_protected_header; Object.defineProperty(exports, "decodeProtectedHeader", { enumerable: true, get: function () { return decode_protected_header_js_1.decodeProtectedHeader; } }); var decode_jwt_js_1 = decode_jwt$1; Object.defineProperty(exports, "decodeJwt", { enumerable: true, get: function () { return decode_jwt_js_1.decodeJwt; } }); exports.errors = errors$5; var generate_key_pair_js_1 = generate_key_pair; Object.defineProperty(exports, "generateKeyPair", { enumerable: true, get: function () { return generate_key_pair_js_1.generateKeyPair; } }); var generate_secret_js_1 = generate_secret; Object.defineProperty(exports, "generateSecret", { enumerable: true, get: function () { return generate_secret_js_1.generateSecret; } }); exports.base64url = base64url$7; var runtime_js_1 = runtime$1; Object.defineProperty(exports, "cryptoRuntime", { enumerable: true, get: function () { return runtime_js_1.default; } }); } (cjs)); function JwksError$2(message) { Error.call(this, message); Error.captureStackTrace(this, this.constructor); this.name = 'JwksError'; this.message = message; } JwksError$2.prototype = Object.create(Error.prototype); JwksError$2.prototype.constructor = JwksError$2; var JwksError_1 = JwksError$2; const jose$4 = cjs; const JwksError$1 = JwksError_1; function resolveAlg(jwk) { if (jwk.alg) { return jwk.alg; } if (jwk.kty === 'RSA') { return 'RS256'; } if (jwk.kty === 'EC') { switch (jwk.crv) { case 'P-256': return 'ES256'; case 'secp256k1': return 'ES256K'; case 'P-384': return 'ES384'; case 'P-521': return 'ES512'; } } if (jwk.kty === 'OKP') { switch (jwk.crv) { case 'Ed25519': case 'Ed448': return 'EdDSA'; } } throw new JwksError$1('Unsupported JWK'); } async function retrieveSigningKeys$2(jwks) { const results = []; jwks = jwks .filter(({ use }) => use === 'sig' || use === undefined) .filter(({ kty }) => kty === 'RSA' || kty === 'EC' || kty === 'OKP'); for (const jwk of jwks) { try { const key = await jose$4.importJWK(jwk, resolveAlg(jwk)); if (key.type !== 'public') { continue; } let getSpki; switch (key[Symbol.toStringTag]) { case 'CryptoKey': { const spki = await jose$4.exportSPKI(key); getSpki = () => spki; break; } case 'KeyObject': // Assume legacy Node.js version without the Symbol.toStringTag backported // Fall through default: getSpki = () => key.export({ format: 'pem', type: 'spki' }); } results.push({ get publicKey() { return getSpki(); }, get rsaPublicKey() { return getSpki(); }, getPublicKey() { return getSpki(); }, ...(typeof jwk.kid === 'string' && jwk.kid ? { kid: jwk.kid } : undefined), ...(typeof jwk.alg === 'string' && jwk.alg ? { alg: jwk.alg } : undefined) }); } catch (err) { continue; } } return results; } var utils$4 = { retrieveSigningKeys: retrieveSigningKeys$2 }; var request$6 = {}; const http$1 = require$$0$5; const https$1 = require$$1$2; const urlUtil = require$$0$1; request$6.default = (options) => { if (options.fetcher) { return options.fetcher(options.uri); } return new Promise((resolve, reject) => { const { hostname, path, port, protocol } = urlUtil.parse(options.uri); const requestOptions = { hostname, path, port, method: 'GET', ...(options.headers && { headers: { ...options.headers } }), ...(options.timeout && { timeout: options.timeout }), ...(options.agent && { agent: options.agent }) }; const httpRequestLib = protocol === 'https:' ? https$1 : http$1; const httpRequest = httpRequestLib.request(requestOptions, (res) => { let rawData = ''; res.setEncoding('utf8'); res.on('data', (chunk) => { rawData += chunk; }); res.on('end', () => { if (res.statusCode < 200 || res.statusCode >= 300) { const errorMsg = res.body && (res.body.message || res.body) || res.statusMessage || `Http Error ${res.statusCode}`; reject({ errorMsg }); } else { try { resolve(rawData && JSON.parse(rawData)); } catch (error) { reject(error); } } }); }); httpRequest .on('timeout', () => httpRequest.destroy()) .on('error', (e) => reject(e)) .end(); }); }; var cache$1 = {}; var async = {}; var iterator; var hasRequiredIterator; function requireIterator () { if (hasRequiredIterator) return iterator; hasRequiredIterator = 1; iterator = function (Yallist) { Yallist.prototype[Symbol.iterator] = function* () { for (let walker = this.head; walker; walker = walker.next) { yield walker.value; } }; }; return iterator; } var yallist = Yallist$1; Yallist$1.Node = Node; Yallist$1.create = Yallist$1; function Yallist$1 (list) { var self = this; if (!(self instanceof Yallist$1)) { self = new Yallist$1(); } self.tail = null; self.head = null; self.length = 0; if (list && typeof list.forEach === 'function') { list.forEach(function (item) { self.push(item); }); } else if (arguments.length > 0) { for (var i = 0, l = arguments.length; i < l; i++) { self.push(arguments[i]); } } return self } Yallist$1.prototype.removeNode = function (node) { if (node.list !== this) { throw new Error('removing node which does not belong to this list') } var next = node.next; var prev = node.prev; if (next) { next.prev = prev; } if (prev) { prev.next = next; } if (node === this.head) { this.head = next; } if (node === this.tail) { this.tail = prev; } node.list.length--; node.next = null; node.prev = null; node.list = null; return next }; Yallist$1.prototype.unshiftNode = function (node) { if (node === this.head) { return } if (node.list) { node.list.removeNode(node); } var head = this.head; node.list = this; node.next = head; if (head) { head.prev = node; } this.head = node; if (!this.tail) { this.tail = node; } this.length++; }; Yallist$1.prototype.pushNode = function (node) { if (node === this.tail) { return } if (node.list) { node.list.removeNode(node); } var tail = this.tail; node.list = this; node.prev = tail; if (tail) { tail.next = node; } this.tail = node; if (!this.head) { this.head = node; } this.length++; }; Yallist$1.prototype.push = function () { for (var i = 0, l = arguments.length; i < l; i++) { push(this, arguments[i]); } return this.length }; Yallist$1.prototype.unshift = function () { for (var i = 0, l = arguments.length; i < l; i++) { unshift(this, arguments[i]); } return this.length }; Yallist$1.prototype.pop = function () { if (!this.tail) { return undefined } var res = this.tail.value; this.tail = this.tail.prev; if (this.tail) { this.tail.next = null; } else { this.head = null; } this.length--; return res }; Yallist$1.prototype.shift = function () { if (!this.head) { return undefined } var res = this.head.value; this.head = this.head.next; if (this.head) { this.head.prev = null; } else { this.tail = null; } this.length--; return res }; Yallist$1.prototype.forEach = function (fn, thisp) { thisp = thisp || this; for (var walker = this.head, i = 0; walker !== null; i++) { fn.call(thisp, walker.value, i, this); walker = walker.next; } }; Yallist$1.prototype.forEachReverse = function (fn, thisp) { thisp = thisp || this; for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { fn.call(thisp, walker.value, i, this); walker = walker.prev; } }; Yallist$1.prototype.get = function (n) { for (var i = 0, walker = this.head; walker !== null && i < n; i++) { // abort out of the list early if we hit a cycle walker = walker.next; } if (i === n && walker !== null) { return walker.value } }; Yallist$1.prototype.getReverse = function (n) { for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { // abort out of the list early if we hit a cycle walker = walker.prev; } if (i === n && walker !== null) { return walker.value } }; Yallist$1.prototype.map = function (fn, thisp) { thisp = thisp || this; var res = new Yallist$1(); for (var walker = this.head; walker !== null;) { res.push(fn.call(thisp, walker.value, this)); walker = walker.next; } return res }; Yallist$1.prototype.mapReverse = function (fn, thisp) { thisp = thisp || this; var res = new Yallist$1(); for (var walker = this.tail; walker !== null;) { res.push(fn.call(thisp, walker.value, this)); walker = walker.prev; } return res }; Yallist$1.prototype.reduce = function (fn, initial) { var acc; var walker = this.head; if (arguments.length > 1) { acc = initial; } else if (this.head) { walker = this.head.next; acc = this.head.value; } else { throw new TypeError('Reduce of empty list with no initial value') } for (var i = 0; walker !== null; i++) { acc = fn(acc, walker.value, i); walker = walker.next; } return acc }; Yallist$1.prototype.reduceReverse = function (fn, initial) { var acc; var walker = this.tail; if (arguments.length > 1) { acc = initial; } else if (this.tail) { walker = this.tail.prev; acc = this.tail.value; } else { throw new TypeError('Reduce of empty list with no initial value') } for (var i = this.length - 1; walker !== null; i--) { acc = fn(acc, walker.value, i); walker = walker.prev; } return acc }; Yallist$1.prototype.toArray = function () { var arr = new Array(this.length); for (var i = 0, walker = this.head; walker !== null; i++) { arr[i] = walker.value; walker = walker.next; } return arr }; Yallist$1.prototype.toArrayReverse = function () { var arr = new Array(this.length); for (var i = 0, walker = this.tail; walker !== null; i++) { arr[i] = walker.value; walker = walker.prev; } return arr }; Yallist$1.prototype.slice = function (from, to) { to = to || this.length; if (to < 0) { to += this.length; } from = from || 0; if (from < 0) { from += this.length; } var ret = new Yallist$1(); if (to < from || to < 0) { return ret } if (from < 0) { from = 0; } if (to > this.length) { to = this.length; } for (var i = 0, walker = this.head; walker !== null && i < from; i++) { walker = walker.next; } for (; walker !== null && i < to; i++, walker = walker.next) { ret.push(walker.value); } return ret }; Yallist$1.prototype.sliceReverse = function (from, to) { to = to || this.length; if (to < 0) { to += this.length; } from = from || 0; if (from < 0) { from += this.length; } var ret = new Yallist$1(); if (to < from || to < 0) { return ret } if (from < 0) { from = 0; } if (to > this.length) { to = this.length; } for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { walker = walker.prev; } for (; walker !== null && i > from; i--, walker = walker.prev) { ret.push(walker.value); } return ret }; Yallist$1.prototype.splice = function (start, deleteCount, ...nodes) { if (start > this.length) { start = this.length - 1; } if (start < 0) { start = this.length + start; } for (var i = 0, walker = this.head; walker !== null && i < start; i++) { walker = walker.next; } var ret = []; for (var i = 0; walker && i < deleteCount; i++) { ret.push(walker.value); walker = this.removeNode(walker); } if (walker === null) { walker = this.tail; } if (walker !== this.head && walker !== this.tail) { walker = walker.prev; } for (var i = 0; i < nodes.length; i++) { walker = insert(this, walker, nodes[i]); } return ret; }; Yallist$1.prototype.reverse = function () { var head = this.head; var tail = this.tail; for (var walker = head; walker !== null; walker = walker.prev) { var p = walker.prev; walker.prev = walker.next; walker.next = p; } this.head = tail; this.tail = head; return this }; function insert (self, node, value) { var inserted = node === self.head ? new Node(value, null, node, self) : new Node(value, node, node.next, self); if (inserted.next === null) { self.tail = inserted; } if (inserted.prev === null) { self.head = inserted; } self.length++; return inserted } function push (self, item) { self.tail = new Node(item, self.tail, null, self); if (!self.head) { self.head = self.tail; } self.length++; } function unshift (self, item) { self.head = new Node(item, null, self.head, self); if (!self.tail) { self.tail = self.head; } self.length++; } function Node (value, prev, next, list) { if (!(this instanceof Node)) { return new Node(value, prev, next, list) } this.list = list; this.value = value; if (prev) { prev.next = this; this.prev = prev; } else { this.prev = null; } if (next) { next.prev = this; this.next = next; } else { this.next = null; } } try { // add if support for Symbol.iterator is present requireIterator()(Yallist$1); } catch (er) {} // A linked list to keep track of recently-used-ness const Yallist = yallist; const MAX = Symbol('max'); const LENGTH = Symbol('length'); const LENGTH_CALCULATOR = Symbol('lengthCalculator'); const ALLOW_STALE = Symbol('allowStale'); const MAX_AGE = Symbol('maxAge'); const DISPOSE = Symbol('dispose'); const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet'); const LRU_LIST = Symbol('lruList'); const CACHE = Symbol('cache'); const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet'); const naiveLength = () => 1; // lruList is a yallist where the head is the youngest // item, and the tail is the oldest. the list contains the Hit // objects as the entries. // Each Hit object has a reference to its Yallist.Node. This // never changes. // // cache is a Map (or PseudoMap) that matches the keys to // the Yallist.Node object. let LRUCache$1 = class LRUCache { constructor (options) { if (typeof options === 'number') options = { max: options }; if (!options) options = {}; if (options.max && (typeof options.max !== 'number' || options.max < 0)) throw new TypeError('max must be a non-negative number') // Kind of weird to have a default max of Infinity, but oh well. this[MAX] = options.max || Infinity; const lc = options.length || naiveLength; this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc; this[ALLOW_STALE] = options.stale || false; if (options.maxAge && typeof options.maxAge !== 'number') throw new TypeError('maxAge must be a number') this[MAX_AGE] = options.maxAge || 0; this[DISPOSE] = options.dispose; this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false; this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false; this.reset(); } // resize the cache when the max changes. set max (mL) { if (typeof mL !== 'number' || mL < 0) throw new TypeError('max must be a non-negative number') this[MAX] = mL || Infinity; trim(this); } get max () { return this[MAX] } set allowStale (allowStale) { this[ALLOW_STALE] = !!allowStale; } get allowStale () { return this[ALLOW_STALE] } set maxAge (mA) { if (typeof mA !== 'number') throw new TypeError('maxAge must be a non-negative number') this[MAX_AGE] = mA; trim(this); } get maxAge () { return this[MAX_AGE] } // resize the cache when the lengthCalculator changes. set lengthCalculator (lC) { if (typeof lC !== 'function') lC = naiveLength; if (lC !== this[LENGTH_CALCULATOR]) { this[LENGTH_CALCULATOR] = lC; this[LENGTH] = 0; this[LRU_LIST].forEach(hit => { hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key); this[LENGTH] += hit.length; }); } trim(this); } get lengthCalculator () { return this[LENGTH_CALCULATOR] } get length () { return this[LENGTH] } get itemCount () { return this[LRU_LIST].length } rforEach (fn, thisp) { thisp = thisp || this; for (let walker = this[LRU_LIST].tail; walker !== null;) { const prev = walker.prev; forEachStep(this, fn, walker, thisp); walker = prev; } } forEach (fn, thisp) { thisp = thisp || this; for (let walker = this[LRU_LIST].head; walker !== null;) { const next = walker.next; forEachStep(this, fn, walker, thisp); walker = next; } } keys () { return this[LRU_LIST].toArray().map(k => k.key) } values () { return this[LRU_LIST].toArray().map(k => k.value) } reset () { if (this[DISPOSE] && this[LRU_LIST] && this[LRU_LIST].length) { this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)); } this[CACHE] = new Map(); // hash of items by key this[LRU_LIST] = new Yallist(); // list of items in order of use recency this[LENGTH] = 0; // length of items in the list } dump () { return this[LRU_LIST].map(hit => isStale(this, hit) ? false : { k: hit.key, v: hit.value, e: hit.now + (hit.maxAge || 0) }).toArray().filter(h => h) } dumpLru () { return this[LRU_LIST] } set (key, value, maxAge) { maxAge = maxAge || this[MAX_AGE]; if (maxAge && typeof maxAge !== 'number') throw new TypeError('maxAge must be a number') const now = maxAge ? Date.now() : 0; const len = this[LENGTH_CALCULATOR](value, key); if (this[CACHE].has(key)) { if (len > this[MAX]) { del$1(this, this[CACHE].get(key)); return false } const node = this[CACHE].get(key); const item = node.value; // dispose of the old one before overwriting // split out into 2 ifs for better coverage tracking if (this[DISPOSE]) { if (!this[NO_DISPOSE_ON_SET]) this[DISPOSE](key, item.value); } item.now = now; item.maxAge = maxAge; item.value = value; this[LENGTH] += len - item.length; item.length = len; this.get(key); trim(this); return true } const hit = new Entry(key, value, len, now, maxAge); // oversized objects fall out of cache automatically. if (hit.length > this[MAX]) { if (this[DISPOSE]) this[DISPOSE](key, value); return false } this[LENGTH] += hit.length; this[LRU_LIST].unshift(hit); this[CACHE].set(key, this[LRU_LIST].head); trim(this); return true } has (key) { if (!this[CACHE].has(key)) return false const hit = this[CACHE].get(key).value; return !isStale(this, hit) } get (key) { return get$1(this, key, true) } peek (key) { return get$1(this, key, false) } pop () { const node = this[LRU_LIST].tail; if (!node) return null del$1(this, node); return node.value } del (key) { del$1(this, this[CACHE].get(key)); } load (arr) { // reset the cache this.reset(); const now = Date.now(); // A previous serialized cache has the most recent items first for (let l = arr.length - 1; l >= 0; l--) { const hit = arr[l]; const expiresAt = hit.e || 0; if (expiresAt === 0) // the item was created without expiration in a non aged cache this.set(hit.k, hit.v); else { const maxAge = expiresAt - now; // dont add already expired items if (maxAge > 0) { this.set(hit.k, hit.v, maxAge); } } } } prune () { this[CACHE].forEach((value, key) => get$1(this, key, false)); } }; const get$1 = (self, key, doUse) => { const node = self[CACHE].get(key); if (node) { const hit = node.value; if (isStale(self, hit)) { del$1(self, node); if (!self[ALLOW_STALE]) return undefined } else { if (doUse) { if (self[UPDATE_AGE_ON_GET]) node.value.now = Date.now(); self[LRU_LIST].unshiftNode(node); } } return hit.value } }; const isStale = (self, hit) => { if (!hit || (!hit.maxAge && !self[MAX_AGE])) return false const diff = Date.now() - hit.now; return hit.maxAge ? diff > hit.maxAge : self[MAX_AGE] && (diff > self[MAX_AGE]) }; const trim = self => { if (self[LENGTH] > self[MAX]) { for (let walker = self[LRU_LIST].tail; self[LENGTH] > self[MAX] && walker !== null;) { // We know that we're about to delete this one, and also // what the next least recently used key will be, so just // go ahead and set it now. const prev = walker.prev; del$1(self, walker); walker = prev; } } }; const del$1 = (self, node) => { if (node) { const hit = node.value; if (self[DISPOSE]) self[DISPOSE](hit.key, hit.value); self[LENGTH] -= hit.length; self[CACHE].delete(hit.key); self[LRU_LIST].removeNode(node); } }; class Entry { constructor (key, value, length, now, maxAge) { this.key = key; this.value = value; this.length = length; this.now = now; this.maxAge = maxAge || 0; } } const forEachStep = (self, fn, node, thisp) => { let hit = node.value; if (isStale(self, hit)) { del$1(self, node); if (!self[ALLOW_STALE]) hit = undefined; } if (hit) fn.call(thisp, hit.value, hit.key, self); }; var lruCache = LRUCache$1; var lodash_clonedeep = {exports: {}}; /** * lodash (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ lodash_clonedeep.exports; (function (module, exports) { /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED = '__lodash_hash_undefined__'; /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER = 9007199254740991; /** `Object#toString` result references. */ var argsTag = '[object Arguments]', arrayTag = '[object Array]', boolTag = '[object Boolean]', dateTag = '[object Date]', errorTag = '[object Error]', funcTag = '[object Function]', genTag = '[object GeneratorFunction]', mapTag = '[object Map]', numberTag = '[object Number]', objectTag = '[object Object]', promiseTag = '[object Promise]', regexpTag = '[object RegExp]', setTag = '[object Set]', stringTag = '[object String]', symbolTag = '[object Symbol]', weakMapTag = '[object WeakMap]'; var arrayBufferTag = '[object ArrayBuffer]', dataViewTag = '[object DataView]', float32Tag = '[object Float32Array]', float64Tag = '[object Float64Array]', int8Tag = '[object Int8Array]', int16Tag = '[object Int16Array]', int32Tag = '[object Int32Array]', uint8Tag = '[object Uint8Array]', uint8ClampedTag = '[object Uint8ClampedArray]', uint16Tag = '[object Uint16Array]', uint32Tag = '[object Uint32Array]'; /** * Used to match `RegExp` * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). */ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; /** Used to match `RegExp` flags from their coerced string values. */ var reFlags = /\w*$/; /** Used to detect host constructors (Safari). */ var reIsHostCtor = /^\[object .+?Constructor\]$/; /** Used to detect unsigned integer values. */ var reIsUint = /^(?:0|[1-9]\d*)$/; /** Used to identify `toStringTag` values supported by `_.clone`. */ var cloneableTags = {}; cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[regexpTag] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[symbolTag] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false; /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); /** Detect free variable `exports`. */ var freeExports = exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule && freeModule.exports === freeExports; /** * Adds the key-value `pair` to `map`. * * @private * @param {Object} map The map to modify. * @param {Array} pair The key-value pair to add. * @returns {Object} Returns `map`. */ function addMapEntry(map, pair) { // Don't return `map.set` because it's not chainable in IE 11. map.set(pair[0], pair[1]); return map; } /** * Adds `value` to `set`. * * @private * @param {Object} set The set to modify. * @param {*} value The value to add. * @returns {Object} Returns `set`. */ function addSetEntry(set, value) { // Don't return `set.add` because it's not chainable in IE 11. set.add(value); return set; } /** * A specialized version of `_.forEach` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEach(array, iteratee) { var index = -1, length = array ? array.length : 0; while (++index < length) { if (iteratee(array[index], index, array) === false) { break; } } return array; } /** * Appends the elements of `values` to `array`. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to append. * @returns {Array} Returns `array`. */ function arrayPush(array, values) { var index = -1, length = values.length, offset = array.length; while (++index < length) { array[offset + index] = values[index]; } return array; } /** * A specialized version of `_.reduce` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {*} [accumulator] The initial value. * @param {boolean} [initAccum] Specify using the first element of `array` as * the initial value. * @returns {*} Returns the accumulated value. */ function arrayReduce(array, iteratee, accumulator, initAccum) { var index = -1, length = array ? array.length : 0; if (initAccum && length) { accumulator = array[++index]; } while (++index < length) { accumulator = iteratee(accumulator, array[index], index, array); } return accumulator; } /** * The base implementation of `_.times` without support for iteratee shorthands * or max array length checks. * * @private * @param {number} n The number of times to invoke `iteratee`. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the array of results. */ function baseTimes(n, iteratee) { var index = -1, result = Array(n); while (++index < n) { result[index] = iteratee(index); } return result; } /** * Gets the value at `key` of `object`. * * @private * @param {Object} [object] The object to query. * @param {string} key The key of the property to get. * @returns {*} Returns the property value. */ function getValue(object, key) { return object == null ? undefined : object[key]; } /** * Checks if `value` is a host object in IE < 9. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a host object, else `false`. */ function isHostObject(value) { // Many host objects are `Object` objects that can coerce to strings // despite having improperly defined `toString` methods. var result = false; if (value != null && typeof value.toString != 'function') { try { result = !!(value + ''); } catch (e) {} } return result; } /** * Converts `map` to its key-value pairs. * * @private * @param {Object} map The map to convert. * @returns {Array} Returns the key-value pairs. */ function mapToArray(map) { var index = -1, result = Array(map.size); map.forEach(function(value, key) { result[++index] = [key, value]; }); return result; } /** * Creates a unary function that invokes `func` with its argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg(func, transform) { return function(arg) { return func(transform(arg)); }; } /** * Converts `set` to an array of its values. * * @private * @param {Object} set The set to convert. * @returns {Array} Returns the values. */ function setToArray(set) { var index = -1, result = Array(set.size); set.forEach(function(value) { result[++index] = value; }); return result; } /** Used for built-in method references. */ var arrayProto = Array.prototype, funcProto = Function.prototype, objectProto = Object.prototype; /** Used to detect overreaching core-js shims. */ var coreJsData = root['__core-js_shared__']; /** Used to detect methods masquerading as native. */ var maskSrcKey = (function() { var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); return uid ? ('Symbol(src)_1.' + uid) : ''; }()); /** Used to resolve the decompiled source of functions. */ var funcToString = funcProto.toString; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString = objectProto.toString; /** Used to detect if a method is native. */ var reIsNative = RegExp('^' + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); /** Built-in value references. */ var Buffer = moduleExports ? root.Buffer : undefined, Symbol = root.Symbol, Uint8Array = root.Uint8Array, getPrototype = overArg(Object.getPrototypeOf, Object), objectCreate = Object.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, splice = arrayProto.splice; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeGetSymbols = Object.getOwnPropertySymbols, nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, nativeKeys = overArg(Object.keys, Object); /* Built-in method references that are verified to be native. */ var DataView = getNative(root, 'DataView'), Map = getNative(root, 'Map'), Promise = getNative(root, 'Promise'), Set = getNative(root, 'Set'), WeakMap = getNative(root, 'WeakMap'), nativeCreate = getNative(Object, 'create'); /** Used to detect maps, sets, and weakmaps. */ var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map), promiseCtorString = toSource(Promise), setCtorString = toSource(Set), weakMapCtorString = toSource(WeakMap); /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; /** * Creates a hash object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Hash(entries) { var index = -1, length = entries ? entries.length : 0; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } /** * Removes all key-value entries from the hash. * * @private * @name clear * @memberOf Hash */ function hashClear() { this.__data__ = nativeCreate ? nativeCreate(null) : {}; } /** * Removes `key` and its value from the hash. * * @private * @name delete * @memberOf Hash * @param {Object} hash The hash to modify. * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function hashDelete(key) { return this.has(key) && delete this.__data__[key]; } /** * Gets the hash value for `key`. * * @private * @name get * @memberOf Hash * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function hashGet(key) { var data = this.__data__; if (nativeCreate) { var result = data[key]; return result === HASH_UNDEFINED ? undefined : result; } return hasOwnProperty.call(data, key) ? data[key] : undefined; } /** * Checks if a hash value for `key` exists. * * @private * @name has * @memberOf Hash * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function hashHas(key) { var data = this.__data__; return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); } /** * Sets the hash `key` to `value`. * * @private * @name set * @memberOf Hash * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the hash instance. */ function hashSet(key, value) { var data = this.__data__; data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; return this; } // Add methods to `Hash`. Hash.prototype.clear = hashClear; Hash.prototype['delete'] = hashDelete; Hash.prototype.get = hashGet; Hash.prototype.has = hashHas; Hash.prototype.set = hashSet; /** * Creates an list cache object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function ListCache(entries) { var index = -1, length = entries ? entries.length : 0; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } /** * Removes all key-value entries from the list cache. * * @private * @name clear * @memberOf ListCache */ function listCacheClear() { this.__data__ = []; } /** * Removes `key` and its value from the list cache. * * @private * @name delete * @memberOf ListCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function listCacheDelete(key) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { return false; } var lastIndex = data.length - 1; if (index == lastIndex) { data.pop(); } else { splice.call(data, index, 1); } return true; } /** * Gets the list cache value for `key`. * * @private * @name get * @memberOf ListCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function listCacheGet(key) { var data = this.__data__, index = assocIndexOf(data, key); return index < 0 ? undefined : data[index][1]; } /** * Checks if a list cache value for `key` exists. * * @private * @name has * @memberOf ListCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function listCacheHas(key) { return assocIndexOf(this.__data__, key) > -1; } /** * Sets the list cache `key` to `value`. * * @private * @name set * @memberOf ListCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the list cache instance. */ function listCacheSet(key, value) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { data.push([key, value]); } else { data[index][1] = value; } return this; } // Add methods to `ListCache`. ListCache.prototype.clear = listCacheClear; ListCache.prototype['delete'] = listCacheDelete; ListCache.prototype.get = listCacheGet; ListCache.prototype.has = listCacheHas; ListCache.prototype.set = listCacheSet; /** * Creates a map cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function MapCache(entries) { var index = -1, length = entries ? entries.length : 0; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } /** * Removes all key-value entries from the map. * * @private * @name clear * @memberOf MapCache */ function mapCacheClear() { this.__data__ = { 'hash': new Hash, 'map': new (Map || ListCache), 'string': new Hash }; } /** * Removes `key` and its value from the map. * * @private * @name delete * @memberOf MapCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function mapCacheDelete(key) { return getMapData(this, key)['delete'](key); } /** * Gets the map value for `key`. * * @private * @name get * @memberOf MapCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function mapCacheGet(key) { return getMapData(this, key).get(key); } /** * Checks if a map value for `key` exists. * * @private * @name has * @memberOf MapCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function mapCacheHas(key) { return getMapData(this, key).has(key); } /** * Sets the map `key` to `value`. * * @private * @name set * @memberOf MapCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the map cache instance. */ function mapCacheSet(key, value) { getMapData(this, key).set(key, value); return this; } // Add methods to `MapCache`. MapCache.prototype.clear = mapCacheClear; MapCache.prototype['delete'] = mapCacheDelete; MapCache.prototype.get = mapCacheGet; MapCache.prototype.has = mapCacheHas; MapCache.prototype.set = mapCacheSet; /** * Creates a stack cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Stack(entries) { this.__data__ = new ListCache(entries); } /** * Removes all key-value entries from the stack. * * @private * @name clear * @memberOf Stack */ function stackClear() { this.__data__ = new ListCache; } /** * Removes `key` and its value from the stack. * * @private * @name delete * @memberOf Stack * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function stackDelete(key) { return this.__data__['delete'](key); } /** * Gets the stack value for `key`. * * @private * @name get * @memberOf Stack * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function stackGet(key) { return this.__data__.get(key); } /** * Checks if a stack value for `key` exists. * * @private * @name has * @memberOf Stack * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function stackHas(key) { return this.__data__.has(key); } /** * Sets the stack `key` to `value`. * * @private * @name set * @memberOf Stack * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the stack cache instance. */ function stackSet(key, value) { var cache = this.__data__; if (cache instanceof ListCache) { var pairs = cache.__data__; if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { pairs.push([key, value]); return this; } cache = this.__data__ = new MapCache(pairs); } cache.set(key, value); return this; } // Add methods to `Stack`. Stack.prototype.clear = stackClear; Stack.prototype['delete'] = stackDelete; Stack.prototype.get = stackGet; Stack.prototype.has = stackHas; Stack.prototype.set = stackSet; /** * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. * @param {boolean} inherited Specify returning inherited property names. * @returns {Array} Returns the array of property names. */ function arrayLikeKeys(value, inherited) { // Safari 8.1 makes `arguments.callee` enumerable in strict mode. // Safari 9 makes `arguments.length` enumerable in strict mode. var result = (isArray(value) || isArguments(value)) ? baseTimes(value.length, String) : []; var length = result.length, skipIndexes = !!length; for (var key in value) { if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && (key == 'length' || isIndex(key, length)))) { result.push(key); } } return result; } /** * Assigns `value` to `key` of `object` if the existing value is not equivalent * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignValue(object, key, value) { var objValue = object[key]; if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || (value === undefined && !(key in object))) { object[key] = value; } } /** * Gets the index at which the `key` is found in `array` of key-value pairs. * * @private * @param {Array} array The array to inspect. * @param {*} key The key to search for. * @returns {number} Returns the index of the matched value, else `-1`. */ function assocIndexOf(array, key) { var length = array.length; while (length--) { if (eq(array[length][0], key)) { return length; } } return -1; } /** * The base implementation of `_.assign` without support for multiple sources * or `customizer` functions. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @returns {Object} Returns `object`. */ function baseAssign(object, source) { return object && copyObject(source, keys(source), object); } /** * The base implementation of `_.clone` and `_.cloneDeep` which tracks * traversed objects. * * @private * @param {*} value The value to clone. * @param {boolean} [isDeep] Specify a deep clone. * @param {boolean} [isFull] Specify a clone including symbols. * @param {Function} [customizer] The function to customize cloning. * @param {string} [key] The key of `value`. * @param {Object} [object] The parent object of `value`. * @param {Object} [stack] Tracks traversed objects and their clone counterparts. * @returns {*} Returns the cloned value. */ function baseClone(value, isDeep, isFull, customizer, key, object, stack) { var result; if (customizer) { result = object ? customizer(value, key, object, stack) : customizer(value); } if (result !== undefined) { return result; } if (!isObject(value)) { return value; } var isArr = isArray(value); if (isArr) { result = initCloneArray(value); if (!isDeep) { return copyArray(value, result); } } else { var tag = getTag(value), isFunc = tag == funcTag || tag == genTag; if (isBuffer(value)) { return cloneBuffer(value, isDeep); } if (tag == objectTag || tag == argsTag || (isFunc && !object)) { if (isHostObject(value)) { return object ? value : {}; } result = initCloneObject(isFunc ? {} : value); if (!isDeep) { return copySymbols(value, baseAssign(result, value)); } } else { if (!cloneableTags[tag]) { return object ? value : {}; } result = initCloneByTag(value, tag, baseClone, isDeep); } } // Check for circular references and return its corresponding clone. stack || (stack = new Stack); var stacked = stack.get(value); if (stacked) { return stacked; } stack.set(value, result); if (!isArr) { var props = isFull ? getAllKeys(value) : keys(value); } arrayEach(props || value, function(subValue, key) { if (props) { key = subValue; subValue = value[key]; } // Recursively populate clone (susceptible to call stack limits). assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); }); return result; } /** * The base implementation of `_.create` without support for assigning * properties to the created object. * * @private * @param {Object} prototype The object to inherit from. * @returns {Object} Returns the new object. */ function baseCreate(proto) { return isObject(proto) ? objectCreate(proto) : {}; } /** * The base implementation of `getAllKeys` and `getAllKeysIn` which uses * `keysFunc` and `symbolsFunc` to get the enumerable property names and * symbols of `object`. * * @private * @param {Object} object The object to query. * @param {Function} keysFunc The function to get the keys of `object`. * @param {Function} symbolsFunc The function to get the symbols of `object`. * @returns {Array} Returns the array of property names and symbols. */ function baseGetAllKeys(object, keysFunc, symbolsFunc) { var result = keysFunc(object); return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); } /** * The base implementation of `getTag`. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { return objectToString.call(value); } /** * The base implementation of `_.isNative` without bad shim checks. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a native function, * else `false`. */ function baseIsNative(value) { if (!isObject(value) || isMasked(value)) { return false; } var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; return pattern.test(toSource(value)); } /** * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeys(object) { if (!isPrototype(object)) { return nativeKeys(object); } var result = []; for (var key in Object(object)) { if (hasOwnProperty.call(object, key) && key != 'constructor') { result.push(key); } } return result; } /** * Creates a clone of `buffer`. * * @private * @param {Buffer} buffer The buffer to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Buffer} Returns the cloned buffer. */ function cloneBuffer(buffer, isDeep) { if (isDeep) { return buffer.slice(); } var result = new buffer.constructor(buffer.length); buffer.copy(result); return result; } /** * Creates a clone of `arrayBuffer`. * * @private * @param {ArrayBuffer} arrayBuffer The array buffer to clone. * @returns {ArrayBuffer} Returns the cloned array buffer. */ function cloneArrayBuffer(arrayBuffer) { var result = new arrayBuffer.constructor(arrayBuffer.byteLength); new Uint8Array(result).set(new Uint8Array(arrayBuffer)); return result; } /** * Creates a clone of `dataView`. * * @private * @param {Object} dataView The data view to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned data view. */ function cloneDataView(dataView, isDeep) { var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); } /** * Creates a clone of `map`. * * @private * @param {Object} map The map to clone. * @param {Function} cloneFunc The function to clone values. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned map. */ function cloneMap(map, isDeep, cloneFunc) { var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); return arrayReduce(array, addMapEntry, new map.constructor); } /** * Creates a clone of `regexp`. * * @private * @param {Object} regexp The regexp to clone. * @returns {Object} Returns the cloned regexp. */ function cloneRegExp(regexp) { var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); result.lastIndex = regexp.lastIndex; return result; } /** * Creates a clone of `set`. * * @private * @param {Object} set The set to clone. * @param {Function} cloneFunc The function to clone values. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned set. */ function cloneSet(set, isDeep, cloneFunc) { var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); return arrayReduce(array, addSetEntry, new set.constructor); } /** * Creates a clone of the `symbol` object. * * @private * @param {Object} symbol The symbol object to clone. * @returns {Object} Returns the cloned symbol object. */ function cloneSymbol(symbol) { return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; } /** * Creates a clone of `typedArray`. * * @private * @param {Object} typedArray The typed array to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned typed array. */ function cloneTypedArray(typedArray, isDeep) { var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); } /** * Copies the values of `source` to `array`. * * @private * @param {Array} source The array to copy values from. * @param {Array} [array=[]] The array to copy values to. * @returns {Array} Returns `array`. */ function copyArray(source, array) { var index = -1, length = source.length; array || (array = Array(length)); while (++index < length) { array[index] = source[index]; } return array; } /** * Copies properties of `source` to `object`. * * @private * @param {Object} source The object to copy properties from. * @param {Array} props The property identifiers to copy. * @param {Object} [object={}] The object to copy properties to. * @param {Function} [customizer] The function to customize copied values. * @returns {Object} Returns `object`. */ function copyObject(source, props, object, customizer) { object || (object = {}); var index = -1, length = props.length; while (++index < length) { var key = props[index]; var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined; assignValue(object, key, newValue === undefined ? source[key] : newValue); } return object; } /** * Copies own symbol properties of `source` to `object`. * * @private * @param {Object} source The object to copy symbols from. * @param {Object} [object={}] The object to copy symbols to. * @returns {Object} Returns `object`. */ function copySymbols(source, object) { return copyObject(source, getSymbols(source), object); } /** * Creates an array of own enumerable property names and symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names and symbols. */ function getAllKeys(object) { return baseGetAllKeys(object, keys, getSymbols); } /** * Gets the data for `map`. * * @private * @param {Object} map The map to query. * @param {string} key The reference key. * @returns {*} Returns the map data. */ function getMapData(map, key) { var data = map.__data__; return isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map; } /** * Gets the native function at `key` of `object`. * * @private * @param {Object} object The object to query. * @param {string} key The key of the method to get. * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { var value = getValue(object, key); return baseIsNative(value) ? value : undefined; } /** * Creates an array of the own enumerable symbol properties of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of symbols. */ var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; /** * Gets the `toStringTag` of `value`. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ var getTag = baseGetTag; // Fallback for data views, maps, sets, and weak maps in IE 11, // for data views in Edge < 14, and promises in Node.js. if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || (Map && getTag(new Map) != mapTag) || (Promise && getTag(Promise.resolve()) != promiseTag) || (Set && getTag(new Set) != setTag) || (WeakMap && getTag(new WeakMap) != weakMapTag)) { getTag = function(value) { var result = objectToString.call(value), Ctor = result == objectTag ? value.constructor : undefined, ctorString = Ctor ? toSource(Ctor) : undefined; if (ctorString) { switch (ctorString) { case dataViewCtorString: return dataViewTag; case mapCtorString: return mapTag; case promiseCtorString: return promiseTag; case setCtorString: return setTag; case weakMapCtorString: return weakMapTag; } } return result; }; } /** * Initializes an array clone. * * @private * @param {Array} array The array to clone. * @returns {Array} Returns the initialized clone. */ function initCloneArray(array) { var length = array.length, result = array.constructor(length); // Add properties assigned by `RegExp#exec`. if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { result.index = array.index; result.input = array.input; } return result; } /** * Initializes an object clone. * * @private * @param {Object} object The object to clone. * @returns {Object} Returns the initialized clone. */ function initCloneObject(object) { return (typeof object.constructor == 'function' && !isPrototype(object)) ? baseCreate(getPrototype(object)) : {}; } /** * Initializes an object clone based on its `toStringTag`. * * **Note:** This function only supports cloning values with tags of * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * * @private * @param {Object} object The object to clone. * @param {string} tag The `toStringTag` of the object to clone. * @param {Function} cloneFunc The function to clone values. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the initialized clone. */ function initCloneByTag(object, tag, cloneFunc, isDeep) { var Ctor = object.constructor; switch (tag) { case arrayBufferTag: return cloneArrayBuffer(object); case boolTag: case dateTag: return new Ctor(+object); case dataViewTag: return cloneDataView(object, isDeep); case float32Tag: case float64Tag: case int8Tag: case int16Tag: case int32Tag: case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: return cloneTypedArray(object, isDeep); case mapTag: return cloneMap(object, isDeep, cloneFunc); case numberTag: case stringTag: return new Ctor(object); case regexpTag: return cloneRegExp(object); case setTag: return cloneSet(object, isDeep, cloneFunc); case symbolTag: return cloneSymbol(object); } } /** * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex(value, length) { length = length == null ? MAX_SAFE_INTEGER : length; return !!length && (typeof value == 'number' || reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length); } /** * Checks if `value` is suitable for use as unique object key. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is suitable, else `false`. */ function isKeyable(value) { var type = typeof value; return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') ? (value !== '__proto__') : (value === null); } /** * Checks if `func` has its source masked. * * @private * @param {Function} func The function to check. * @returns {boolean} Returns `true` if `func` is masked, else `false`. */ function isMasked(func) { return !!maskSrcKey && (maskSrcKey in func); } /** * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype(value) { var Ctor = value && value.constructor, proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; return value === proto; } /** * Converts `func` to its source code. * * @private * @param {Function} func The function to process. * @returns {string} Returns the source code. */ function toSource(func) { if (func != null) { try { return funcToString.call(func); } catch (e) {} try { return (func + ''); } catch (e) {} } return ''; } /** * This method is like `_.clone` except that it recursively clones `value`. * * @static * @memberOf _ * @since 1.0.0 * @category Lang * @param {*} value The value to recursively clone. * @returns {*} Returns the deep cloned value. * @see _.clone * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; * * var deep = _.cloneDeep(objects); * console.log(deep[0] === objects[0]); * // => false */ function cloneDeep(value) { return baseClone(value, true, true); } /** * Performs a * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * comparison between two values to determine if they are equivalent. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.eq(object, object); * // => true * * _.eq(object, other); * // => false * * _.eq('a', 'a'); * // => true * * _.eq('a', Object('a')); * // => false * * _.eq(NaN, NaN); * // => true */ function eq(value, other) { return value === other || (value !== value && other !== other); } /** * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, * else `false`. * @example * * _.isArguments(function() { return arguments; }()); * // => true * * _.isArguments([1, 2, 3]); * // => false */ function isArguments(value) { // Safari 8.1 makes `arguments.callee` enumerable in strict mode. return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); } /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray = Array.isArray; /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike(value) { return value != null && isLength(value.length) && !isFunction(value); } /** * This method is like `_.isArrayLike` except that it also checks if `value` * is an object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, * else `false`. * @example * * _.isArrayLikeObject([1, 2, 3]); * // => true * * _.isArrayLikeObject(document.body.children); * // => true * * _.isArrayLikeObject('abc'); * // => false * * _.isArrayLikeObject(_.noop); * // => false */ function isArrayLikeObject(value) { return isObjectLike(value) && isArrayLike(value); } /** * Checks if `value` is a buffer. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. * @example * * _.isBuffer(new Buffer(2)); * // => true * * _.isBuffer(new Uint8Array(2)); * // => false */ var isBuffer = nativeIsBuffer || stubFalse; /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction(value) { // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 8-9 which returns 'object' for typed array and other constructors. var tag = isObject(value) ? objectToString.call(value) : ''; return tag == funcTag || tag == genTag; } /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return !!value && typeof value == 'object'; } /** * Creates an array of the own enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. See the * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * for more details. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keys(new Foo); * // => ['a', 'b'] (iteration order is not guaranteed) * * _.keys('hi'); * // => ['0', '1'] */ function keys(object) { return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); } /** * This method returns a new empty array. * * @static * @memberOf _ * @since 4.13.0 * @category Util * @returns {Array} Returns the new empty array. * @example * * var arrays = _.times(2, _.stubArray); * * console.log(arrays); * // => [[], []] * * console.log(arrays[0] === arrays[1]); * // => false */ function stubArray() { return []; } /** * This method returns `false`. * * @static * @memberOf _ * @since 4.13.0 * @category Util * @returns {boolean} Returns `false`. * @example * * _.times(2, _.stubFalse); * // => [false, false] */ function stubFalse() { return false; } module.exports = cloneDeep; } (lodash_clonedeep, lodash_clonedeep.exports)); var lodash_clonedeepExports = lodash_clonedeep.exports; var freeze = {}; // From https://raw.githubusercontent.com/nikoskalogridis/deep-freeze/fb921b32064dce1645197be2bf975fe0385450b0/index.js // which is sadly, no longer maintained Object.defineProperty(freeze, "__esModule", { value: true }); freeze.deepFreeze = void 0; function deepFreeze(o) { if (o) { Object.freeze(o); Object.getOwnPropertyNames(o).forEach(function (prop) { if (o.hasOwnProperty(prop) && o[prop] !== null && (typeof o[prop] === 'object' || typeof o[prop] === 'function') && (o[prop].constructor !== Buffer) && !Object.isFrozen(o[prop])) { deepFreeze(o[prop]); } }); } return o; } freeze.deepFreeze = deepFreeze; var sync$1 = {}; var __read$1 = (commonjsGlobal && commonjsGlobal.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spread$1 = (commonjsGlobal && commonjsGlobal.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read$1(arguments[i])); return ar; }; var __importDefault$2 = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(sync$1, "__esModule", { value: true }); sync$1.syncMemoizer = void 0; var lru_cache_1$1 = __importDefault$2(lruCache); var events_1$2 = require$$1$3; var lodash_clonedeep_1$1 = __importDefault$2(lodash_clonedeepExports); var freeze_1$1 = freeze; function syncMemoizer(options) { var cache = new lru_cache_1$1.default(options); var load = options.load; var hash = options.hash; var bypass = options.bypass; var itemMaxAge = options.itemMaxAge; var freeze = options.freeze; var clone = options.clone; var emitter = new events_1$2.EventEmitter(); var defaultResult = Object.assign({ del: del, reset: function () { return cache.reset(); }, keys: cache.keys.bind(cache), on: emitter.on.bind(emitter), once: emitter.once.bind(emitter), }, options); if (options.disable) { return Object.assign(load, defaultResult); } function del() { var key = hash.apply(void 0, __spread$1(arguments)); cache.del(key); } function emit(event) { var parameters = []; for (var _i = 1; _i < arguments.length; _i++) { parameters[_i - 1] = arguments[_i]; } emitter.emit.apply(emitter, __spread$1([event], parameters)); } function isPromise(result) { // detect native, bluebird, A+ promises return result && result.then && typeof result.then === 'function'; } function processResult(result) { var res = result; if (clone) { if (isPromise(res)) { res = res.then(lodash_clonedeep_1$1.default); } else { res = lodash_clonedeep_1$1.default(res); } } if (freeze) { if (isPromise(res)) { res = res.then(freeze_1$1.deepFreeze); } else { freeze_1$1.deepFreeze(res); } } return res; } var result = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (bypass && bypass.apply(void 0, __spread$1(args))) { emit.apply(void 0, __spread$1(['miss'], args)); return load.apply(void 0, __spread$1(args)); } var key = hash.apply(void 0, __spread$1(args)); var fromCache = cache.get(key); if (fromCache) { emit.apply(void 0, __spread$1(['hit'], args)); return processResult(fromCache); } emit.apply(void 0, __spread$1(['miss'], args)); var result = load.apply(void 0, __spread$1(args)); if (itemMaxAge) { // @ts-ignore cache.set(key, result, itemMaxAge.apply(void 0, __spread$1(args.concat([result])))); } else { cache.set(key, result); } return processResult(result); }; return Object.assign(result, defaultResult); } sync$1.syncMemoizer = syncMemoizer; var __read = (commonjsGlobal && commonjsGlobal.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spread = (commonjsGlobal && commonjsGlobal.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; var __values = (commonjsGlobal && commonjsGlobal.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; var __importDefault$1 = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(async, "__esModule", { value: true }); async.asyncMemoizer = void 0; var lru_cache_1 = __importDefault$1(lruCache); var events_1$1 = require$$1$3; var lodash_clonedeep_1 = __importDefault$1(lodash_clonedeepExports); var freeze_1 = freeze; var sync_1 = sync$1; function asyncMemoizer(options) { var cache = new lru_cache_1.default(options); var load = options.load; var hash = options.hash; var bypass = options.bypass; var itemMaxAge = options.itemMaxAge; var freeze = options.freeze; var clone = options.clone; var queueMaxAge = options.queueMaxAge || 1000; var loading = new Map(); var emitter = new events_1$1.EventEmitter(); var memoizerMethods = Object.assign({ del: del, reset: function () { return cache.reset(); }, keys: cache.keys.bind(cache), on: emitter.on.bind(emitter), once: emitter.once.bind(emitter) }, options); if (options.disable) { return Object.assign(load, memoizerMethods); } function del() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var key = hash.apply(void 0, __spread(args)); cache.del(key); } function add(key, parameters, result) { if (freeze) { result.forEach(freeze_1.deepFreeze); } if (itemMaxAge) { cache.set(key, result, itemMaxAge.apply(void 0, __spread(parameters.concat(result)))); } else { cache.set(key, result); } } function runCallbacks(callbacks, args) { var e_1, _a; try { for (var callbacks_1 = __values(callbacks), callbacks_1_1 = callbacks_1.next(); !callbacks_1_1.done; callbacks_1_1 = callbacks_1.next()) { var callback = callbacks_1_1.value; // Simulate async call when returning from cache // and yield between callback resolution if (clone) { setImmediate.apply(void 0, __spread([callback], args.map(lodash_clonedeep_1.default))); } else { setImmediate.apply(void 0, __spread([callback], args)); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (callbacks_1_1 && !callbacks_1_1.done && (_a = callbacks_1.return)) _a.call(callbacks_1); } finally { if (e_1) throw e_1.error; } } } function emit(event) { var parameters = []; for (var _i = 1; _i < arguments.length; _i++) { parameters[_i - 1] = arguments[_i]; } emitter.emit.apply(emitter, __spread([event], parameters)); } function memoizedFunction() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var parameters = args.slice(0, -1); var callback = args.slice(-1).pop(); var key; if (bypass && bypass.apply(void 0, __spread(parameters))) { emit.apply(void 0, __spread(['miss'], parameters)); return load.apply(void 0, __spread(args)); } if (parameters.length === 0 && !hash) { //the load function only receives callback. key = '_'; } else { key = hash.apply(void 0, __spread(parameters)); } var fromCache = cache.get(key); if (fromCache) { emit.apply(void 0, __spread(['hit'], parameters)); // found, invoke callback return runCallbacks([callback], [null].concat(fromCache)); } var pendingLoad = loading.get(key); if (pendingLoad && pendingLoad.expiresAt > Date.now()) { // request already in progress, queue and return pendingLoad.queue.push(callback); emit.apply(void 0, __spread(['queue'], parameters)); return; } emit.apply(void 0, __spread(['miss'], parameters)); var started = Date.now(); // no pending request or not resolved before expiration // create a new queue and invoke load var queue = [callback]; loading.set(key, { queue: queue, expiresAt: started + queueMaxAge }); var loadHandler = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var err = args[0]; if (!err) { add(key, parameters, args.slice(1)); } // this can potentially delete a different queue than `queue` if // this callback was called after expiration. // that will only cause a new call to be performed and a new queue to be // created loading.delete(key); emit.apply(void 0, __spread(['loaded', Date.now() - started], parameters)); runCallbacks(queue, args); }; load.apply(void 0, __spread(parameters, [loadHandler])); } return Object.assign(memoizedFunction, memoizerMethods); } async.asyncMemoizer = asyncMemoizer; asyncMemoizer.sync = sync_1.syncMemoizer; var async_1 = async; var lib$4 = async_1.asyncMemoizer; const logger$2 = srcExports('jwks'); const memoizer = lib$4; const { promisify, callbackify: callbackify$1 } = require$$1; function cacheWrapper(client, { cacheMaxEntries = 5, cacheMaxAge = 600000 }) { logger$2(`Configured caching of signing keys. Max: ${cacheMaxEntries} / Age: ${cacheMaxAge}`); return promisify(memoizer({ hash: (kid) => kid, load: callbackify$1(client.getSigningKey.bind(client)), maxAge: cacheMaxAge, max: cacheMaxEntries })); } cache$1.default = cacheWrapper; var rateLimit = {}; var limiter = {}; /** * A hierarchical token bucket for rate limiting. See * http://en.wikipedia.org/wiki/Token_bucket for more information. * @author John Hurliman * * @param {Number} bucketSize Maximum number of tokens to hold in the bucket. * Also known as the burst rate. * @param {Number} tokensPerInterval Number of tokens to drip into the bucket * over the course of one interval. * @param {String|Number} interval The interval length in milliseconds, or as * one of the following strings: 'second', 'minute', 'hour', day'. * @param {TokenBucket} parentBucket Optional. A token bucket that will act as * the parent of this bucket. */ var TokenBucket$1 = function(bucketSize, tokensPerInterval, interval, parentBucket) { this.bucketSize = bucketSize; this.tokensPerInterval = tokensPerInterval; if (typeof interval === 'string') { switch (interval) { case 'sec': case 'second': this.interval = 1000; break; case 'min': case 'minute': this.interval = 1000 * 60; break; case 'hr': case 'hour': this.interval = 1000 * 60 * 60; break; case 'day': this.interval = 1000 * 60 * 60 * 24; break; default: throw new Error('Invaid interval ' + interval); } } else { this.interval = interval; } this.parentBucket = parentBucket; this.content = 0; this.lastDrip = +new Date(); }; TokenBucket$1.prototype = { bucketSize: 1, tokensPerInterval: 1, interval: 1000, parentBucket: null, content: 0, lastDrip: 0, /** * Remove the requested number of tokens and fire the given callback. If the * bucket (and any parent buckets) contains enough tokens this will happen * immediately. Otherwise, the removal and callback will happen when enough * tokens become available. * @param {Number} count The number of tokens to remove. * @param {Function} callback(err, remainingTokens) * @returns {Boolean} True if the callback was fired immediately, otherwise * false. */ removeTokens: function(count, callback) { var self = this; // Is this an infinite size bucket? if (!this.bucketSize) { process.nextTick(callback.bind(null, null, count, Number.POSITIVE_INFINITY)); return true; } // Make sure the bucket can hold the requested number of tokens if (count > this.bucketSize) { process.nextTick(callback.bind(null, 'Requested tokens ' + count + ' exceeds bucket size ' + this.bucketSize, null)); return false; } // Drip new tokens into this bucket this.drip(); // If we don't have enough tokens in this bucket, come back later if (count > this.content) return comeBackLater(); if (this.parentBucket) { // Remove the requested from the parent bucket first return this.parentBucket.removeTokens(count, function(err, remainingTokens) { if (err) return callback(err, null); // Check that we still have enough tokens in this bucket if (count > self.content) return comeBackLater(); // Tokens were removed from the parent bucket, now remove them from // this bucket and fire the callback. Note that we look at the current // bucket and parent bucket's remaining tokens and return the smaller // of the two values self.content -= count; callback(null, Math.min(remainingTokens, self.content)); }); } else { // Remove the requested tokens from this bucket and fire the callback this.content -= count; process.nextTick(callback.bind(null, null, this.content)); return true; } function comeBackLater() { // How long do we need to wait to make up the difference in tokens? var waitInterval = Math.ceil( (count - self.content) * (self.interval / self.tokensPerInterval)); setTimeout(function() { self.removeTokens(count, callback); }, waitInterval); return false; } }, /** * Attempt to remove the requested number of tokens and return immediately. * If the bucket (and any parent buckets) contains enough tokens this will * return true, otherwise false is returned. * @param {Number} count The number of tokens to remove. * @param {Boolean} True if the tokens were successfully removed, otherwise * false. */ tryRemoveTokens: function(count) { // Is this an infinite size bucket? if (!this.bucketSize) return true; // Make sure the bucket can hold the requested number of tokens if (count > this.bucketSize) return false; // Drip new tokens into this bucket this.drip(); // If we don't have enough tokens in this bucket, return false if (count > this.content) return false; // Try to remove the requested tokens from the parent bucket if (this.parentBucket && !this.parentBucket.tryRemoveTokens(count)) return false; // Remove the requested tokens from this bucket and return this.content -= count; return true; }, /** * Add any new tokens to the bucket since the last drip. * @returns {Boolean} True if new tokens were added, otherwise false. */ drip: function() { if (!this.tokensPerInterval) { this.content = this.bucketSize; return; } var now = +new Date(); var deltaMS = Math.max(now - this.lastDrip, 0); this.lastDrip = now; var dripAmount = deltaMS * (this.tokensPerInterval / this.interval); this.content = Math.min(this.content + dripAmount, this.bucketSize); } }; var tokenBucket = TokenBucket$1; var getMilliseconds$1 = function() { if (typeof process !== 'undefined' && process.hrtime) { var hrtime = process.hrtime(); var seconds = hrtime[0]; var nanoseconds = hrtime[1]; return seconds * 1e3 + Math.floor(nanoseconds / 1e6); } return new Date().getTime(); }; var clock = getMilliseconds$1; var TokenBucket = tokenBucket; var getMilliseconds = clock; /** * A generic rate limiter. Underneath the hood, this uses a token bucket plus * an additional check to limit how many tokens we can remove each interval. * @author John Hurliman * * @param {Number} tokensPerInterval Maximum number of tokens that can be * removed at any given moment and over the course of one interval. * @param {String|Number} interval The interval length in milliseconds, or as * one of the following strings: 'second', 'minute', 'hour', day'. * @param {Boolean} fireImmediately Optional. Whether or not the callback * will fire immediately when rate limiting is in effect (default is false). */ var RateLimiter$1 = function(tokensPerInterval, interval, fireImmediately) { this.tokenBucket = new TokenBucket(tokensPerInterval, tokensPerInterval, interval, null); // Fill the token bucket to start this.tokenBucket.content = tokensPerInterval; this.curIntervalStart = getMilliseconds(); this.tokensThisInterval = 0; this.fireImmediately = fireImmediately; }; RateLimiter$1.prototype = { tokenBucket: null, curIntervalStart: 0, tokensThisInterval: 0, fireImmediately: false, /** * Remove the requested number of tokens and fire the given callback. If the * rate limiter contains enough tokens and we haven't spent too many tokens * in this interval already, this will happen immediately. Otherwise, the * removal and callback will happen when enough tokens become available. * @param {Number} count The number of tokens to remove. * @param {Function} callback(err, remainingTokens) * @returns {Boolean} True if the callback was fired immediately, otherwise * false. */ removeTokens: function(count, callback) { // Make sure the request isn't for more than we can handle if (count > this.tokenBucket.bucketSize) { process.nextTick(callback.bind(null, 'Requested tokens ' + count + ' exceeds maximum tokens per interval ' + this.tokenBucket.bucketSize, null)); return false; } var self = this; var now = getMilliseconds(); // Advance the current interval and reset the current interval token count // if needed if (now < this.curIntervalStart || now - this.curIntervalStart >= this.tokenBucket.interval) { this.curIntervalStart = now; this.tokensThisInterval = 0; } // If we don't have enough tokens left in this interval, wait until the // next interval if (count > this.tokenBucket.tokensPerInterval - this.tokensThisInterval) { if (this.fireImmediately) { process.nextTick(callback.bind(null, null, -1)); } else { var waitInterval = Math.ceil( this.curIntervalStart + this.tokenBucket.interval - now); setTimeout(function() { self.tokenBucket.removeTokens(count, afterTokensRemoved); }, waitInterval); } return false; } // Remove the requested number of tokens from the token bucket return this.tokenBucket.removeTokens(count, afterTokensRemoved); function afterTokensRemoved(err, tokensRemaining) { if (err) return callback(err, null); self.tokensThisInterval += count; callback(null, tokensRemaining); } }, /** * Attempt to remove the requested number of tokens and return immediately. * If the bucket (and any parent buckets) contains enough tokens and we * haven't spent too many tokens in this interval already, this will return * true. Otherwise, false is returned. * @param {Number} count The number of tokens to remove. * @param {Boolean} True if the tokens were successfully removed, otherwise * false. */ tryRemoveTokens: function(count) { // Make sure the request isn't for more than we can handle if (count > this.tokenBucket.bucketSize) return false; var now = getMilliseconds(); // Advance the current interval and reset the current interval token count // if needed if (now < this.curIntervalStart || now - this.curIntervalStart >= this.tokenBucket.interval) { this.curIntervalStart = now; this.tokensThisInterval = 0; } // If we don't have enough tokens left in this interval, return false if (count > this.tokenBucket.tokensPerInterval - this.tokensThisInterval) return false; // Try to remove the requested number of tokens from the token bucket var removed = this.tokenBucket.tryRemoveTokens(count); if (removed) { this.tokensThisInterval += count; } return removed; }, /** * Returns the number of tokens remaining in the TokenBucket. * @returns {Number} The number of tokens remaining. */ getTokensRemaining: function () { this.tokenBucket.drip(); return this.tokenBucket.content; } }; var rateLimiter = RateLimiter$1; limiter.RateLimiter = rateLimiter; limiter.TokenBucket = tokenBucket; function JwksRateLimitError$1(message) { Error.call(this, message); Error.captureStackTrace(this, this.constructor); this.name = 'JwksRateLimitError'; this.message = message; } JwksRateLimitError$1.prototype = Object.create(Error.prototype); JwksRateLimitError$1.prototype.constructor = JwksRateLimitError$1; var JwksRateLimitError_1 = JwksRateLimitError$1; const logger$1 = srcExports('jwks'); const { RateLimiter } = limiter; const JwksRateLimitError = JwksRateLimitError_1; function rateLimitWrapper(client, { jwksRequestsPerMinute = 10 }) { const getSigningKey = client.getSigningKey.bind(client); const limiter = new RateLimiter(jwksRequestsPerMinute, 'minute', true); logger$1(`Configured rate limiting to JWKS endpoint at ${jwksRequestsPerMinute}/minute`); return async (kid) => await new Promise((resolve, reject) => { limiter.removeTokens(1, async (err, remaining) => { if (err) { reject(err); } logger$1('Requests to the JWKS endpoint available for the next minute:', remaining); if (remaining < 0) { logger$1('Too many requests to the JWKS endpoint'); reject(new JwksRateLimitError('Too many requests to the JWKS endpoint')); } else { try { const key = await getSigningKey(kid); resolve(key); } catch (error) { reject(error); } } }); }); } rateLimit.default = rateLimitWrapper; var interceptor = {}; const retrieveSigningKeys$1 = utils$4.retrieveSigningKeys; /** * Uses getKeysInterceptor to allow users to retrieve keys from a file, * external cache, or provided object before falling back to the jwksUri endpoint */ function getKeysInterceptor$1(client, { getKeysInterceptor }) { const getSigningKey = client.getSigningKey.bind(client); return async (kid) => { const keys = await getKeysInterceptor(); let signingKeys; if (keys && keys.length) { signingKeys = await retrieveSigningKeys$1(keys); } if (signingKeys && signingKeys.length) { const key = signingKeys.find(k => !kid || k.kid === kid); if (key) { return key; } } return getSigningKey(kid); }; } interceptor.default = getKeysInterceptor$1; var callbackSupport$2 = {}; const { callbackify } = require$$1; const callbackSupport$1 = (client) => { const getSigningKey = client.getSigningKey.bind(client); return (kid, cb) => { if (cb) { const callbackFunc = callbackify(getSigningKey); return callbackFunc(kid, cb); } return getSigningKey(kid); }; }; callbackSupport$2.default = callbackSupport$1; var wrappers = { request: request$6.default, cacheSigningKey: cache$1.default, rateLimitSigningKey: rateLimit.default, getKeysInterceptor: interceptor.default, callbackSupport: callbackSupport$2.default }; function SigningKeyNotFoundError$1(message) { Error.call(this, message); Error.captureStackTrace(this, this.constructor); this.name = 'SigningKeyNotFoundError'; this.message = message; } SigningKeyNotFoundError$1.prototype = Object.create(Error.prototype); SigningKeyNotFoundError$1.prototype.constructor = SigningKeyNotFoundError$1; var SigningKeyNotFoundError_1 = SigningKeyNotFoundError$1; const logger = srcExports('jwks'); const { retrieveSigningKeys } = utils$4 ; const { request: request$5, cacheSigningKey, rateLimitSigningKey, getKeysInterceptor, callbackSupport } = wrappers; const JwksError = JwksError_1; const SigningKeyNotFoundError = SigningKeyNotFoundError_1; let JwksClient$4 = class JwksClient { constructor(options) { this.options = { rateLimit: false, cache: true, timeout: 30000, ...options }; // Initialize wrappers. if (this.options.getKeysInterceptor) { this.getSigningKey = getKeysInterceptor(this, options); } if (this.options.rateLimit) { this.getSigningKey = rateLimitSigningKey(this, options); } if (this.options.cache) { this.getSigningKey = cacheSigningKey(this, options); } this.getSigningKey = callbackSupport(this, options); } async getKeys() { logger(`Fetching keys from '${this.options.jwksUri}'`); try { const res = await request$5({ uri: this.options.jwksUri, headers: this.options.requestHeaders, agent: this.options.requestAgent, timeout: this.options.timeout, fetcher: this.options.fetcher }); logger('Keys:', res.keys); return res.keys; } catch (err) { const { errorMsg } = err; logger('Failure:', errorMsg || err); throw (errorMsg ? new JwksError(errorMsg) : err); } } async getSigningKeys() { const keys = await this.getKeys(); if (!keys || !keys.length) { throw new JwksError('The JWKS endpoint did not contain any keys'); } const signingKeys = await retrieveSigningKeys(keys); if (!signingKeys.length) { throw new JwksError('The JWKS endpoint did not contain any signing keys'); } logger('Signing Keys:', signingKeys); return signingKeys; } async getSigningKey (kid) { logger(`Fetching signing key for '${kid}'`); const keys = await this.getSigningKeys(); const kidDefined = kid !== undefined && kid !== null; if (!kidDefined && keys.length > 1) { logger('No KID specified and JWKS endpoint returned more than 1 key'); throw new SigningKeyNotFoundError('No KID specified and JWKS endpoint returned more than 1 key'); } const key = keys.find(k => !kidDefined || k.kid === kid); if (key) { return key; } else { logger(`Unable to find a signing key that matches '${kid}'`); throw new SigningKeyNotFoundError(`Unable to find a signing key that matches '${kid}'`); } } }; var JwksClient_1$1 = { JwksClient: JwksClient$4 }; function ArgumentError$3(message) { Error.call(this, message); Error.captureStackTrace(this, this.constructor); this.name = 'ArgumentError'; this.message = message; } ArgumentError$3.prototype = Object.create(Error.prototype); ArgumentError$3.prototype.constructor = ArgumentError$3; var ArgumentError_1 = ArgumentError$3; var errors$4 = { ArgumentError: ArgumentError_1, JwksError: JwksError_1, JwksRateLimitError: JwksRateLimitError_1, SigningKeyNotFoundError: SigningKeyNotFoundError_1 }; var hapi = {exports: {}}; const allowedSignatureAlg = [ 'RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512', 'ES256', 'ES256K', 'ES384', 'ES512', 'EdDSA' ]; var config$2 = allowedSignatureAlg; (function (module) { const { ArgumentError } = errors$4; const { JwksClient } = JwksClient_1$1; const supportedAlg = config$2; const handleSigningKeyError = (err, cb) => { // If we didn't find a match, can't provide a key. if (err && err.name === 'SigningKeyNotFoundError') { return cb(err, null, null); } // If an error occured like rate limiting or HTTP issue, we'll bubble up the error. if (err) { return cb(err, null, null); } }; /** * Call hapiJwt2Key as a Promise * @param {object} options * @returns {Promise} */ module.exports.hapiJwt2KeyAsync = (options) => { const secretProvider = module.exports.hapiJwt2Key(options); return function(decoded) { return new Promise((resolve, reject) => { const cb = (err, key) => { (!key || err) ? reject(err) : resolve({ key }); }; secretProvider(decoded, cb); }); }; }; module.exports.hapiJwt2Key = function (options) { if (options === null || options === undefined) { throw new ArgumentError('An options object must be provided when initializing hapiJwt2Key'); } const client = new JwksClient(options); const onError = options.handleSigningKeyError || handleSigningKeyError; return function secretProvider(decoded, cb) { // We cannot find a signing certificate if there is no header (no kid). if (!decoded || !decoded.header) { return cb(new Error('Cannot find a signing certificate if there is no header'), null, null); } if (!supportedAlg.includes(decoded.header.alg)) { return cb(new Error('Unsupported algorithm ' + decoded.header.alg + ' supplied.'), null, null); } client.getSigningKey(decoded.header.kid) .then(key => { return cb(null, key.publicKey || key.rsaPublicKey, key); }).catch(err => { return onError(err, (newError) => cb(newError, null, null)); }); }; }; } (hapi)); var hapiExports = hapi.exports; var express = {}; const { ArgumentError: ArgumentError$2 } = errors$4; const { JwksClient: JwksClient$3 } = JwksClient_1$1; const supportedAlg$2 = config$2; const handleSigningKeyError$1 = (err, cb) => { // If we didn't find a match, can't provide a key. if (err && err.name === 'SigningKeyNotFoundError') { return cb(null); } // If an error occured like rate limiting or HTTP issue, we'll bubble up the error. if (err) { return cb(err); } }; express.expressJwtSecret = function (options) { if (options === null || options === undefined) { throw new ArgumentError$2('An options object must be provided when initializing expressJwtSecret'); } const client = new JwksClient$3(options); const onError = options.handleSigningKeyError || handleSigningKeyError$1; const expressJwt7Provider = async (req, token) => { if (!token) { return; } const header = token.header; if (!header || !supportedAlg$2.includes(header.alg)) { return; } try { const key = await client.getSigningKey(header.kid); return key.publicKey || key.rsaPublicKey; } catch (err) { return new Promise((resolve, reject) => { onError(err, (newError) => { if (!newError) { return resolve(); } reject(newError); }); }); } }; return function secretProvider(req, header, payload, cb) { //This function has 4 parameters to make it work with express-jwt@6 //but it also supports express-jwt@7 which only has 2. if (arguments.length === 4) { expressJwt7Provider(req, { header }) .then(key => { setImmediate(cb, null, key); }).catch(err => { setImmediate(cb, err); }); return; } return expressJwt7Provider(req, arguments[1]); }; }; var koa = {}; const { ArgumentError: ArgumentError$1 } = errors$4; const { JwksClient: JwksClient$2 } = JwksClient_1$1; const supportedAlg$1 = config$2; koa.koaJwtSecret = function (options = {}) { if (!options.jwksUri) { throw new ArgumentError$1('No JWKS provided. Please provide a jwksUri'); } const client = new JwksClient$2(options); return function secretProvider({ alg, kid } = {}) { return new Promise((resolve, reject) => { if (!supportedAlg$1.includes(alg)) { return reject(new Error('Missing / invalid token algorithm')); } client.getSigningKey(kid) .then(key => { resolve(key.publicKey || key.rsaPublicKey); }).catch(err => { if (options.handleSigningKeyError) { return options.handleSigningKeyError(err).then(reject); } return reject(err); }); }); }; }; var passport = {}; const jose$3 = cjs; const { ArgumentError } = errors$4; const { JwksClient: JwksClient$1 } = JwksClient_1$1; const supportedAlg = config$2; const handleSigningKeyError = (err, cb) => { // If we didn't find a match, can't provide a key. if (err && err.name === 'SigningKeyNotFoundError') { return cb(null); } // If an error occured like rate limiting or HTTP issue, we'll bubble up the error. if (err) { return cb(err); } }; passport.passportJwtSecret = function (options) { if (options === null || options === undefined) { throw new ArgumentError('An options object must be provided when initializing passportJwtSecret'); } if (!options.jwksUri) { throw new ArgumentError('No JWKS provided. Please provide a jwksUri'); } const client = new JwksClient$1(options); const onError = options.handleSigningKeyError || handleSigningKeyError; return function secretProvider(req, rawJwtToken, cb) { let decoded; try { decoded = { payload: jose$3.decodeJwt(rawJwtToken), header: jose$3.decodeProtectedHeader(rawJwtToken) }; } catch (err) { decoded = null; } if (!decoded || !supportedAlg.includes(decoded.header.alg)) { return cb(null, null); } client.getSigningKey(decoded.header.kid) .then(key => { cb(null, key.publicKey || key.rsaPublicKey); }).catch(err => { onError(err, (newError) => cb(newError, null)); }); }; }; const { JwksClient } = JwksClient_1$1; const errors$3 = errors$4; const { hapiJwt2Key, hapiJwt2KeyAsync } = hapiExports; const { expressJwtSecret } = express; const { koaJwtSecret } = koa; const { passportJwtSecret } = passport; src$1.exports = (options) => { return new JwksClient(options); }; var JwksClient_1 = src$1.exports.JwksClient = JwksClient; src$1.exports.ArgumentError = errors$3.ArgumentError; src$1.exports.JwksError = errors$3.JwksError; src$1.exports.JwksRateLimitError = errors$3.JwksRateLimitError; src$1.exports.SigningKeyNotFoundError = errors$3.SigningKeyNotFoundError; src$1.exports.expressJwtSecret = expressJwtSecret; src$1.exports.hapiJwt2Key = hapiJwt2Key; src$1.exports.hapiJwt2KeyAsync = hapiJwt2KeyAsync; src$1.exports.koaJwtSecret = koaJwtSecret; src$1.exports.passportJwtSecret = passportJwtSecret; const { format: format$3 } = require$$1; let OPError$5 = class OPError extends Error { constructor({ error_description, error, error_uri, session_state, state, scope }, response) { super(!error_description ? error : `${error} (${error_description})`); Object.assign( this, { error }, error_description && { error_description }, error_uri && { error_uri }, state && { state }, scope && { scope }, session_state && { session_state }, ); if (response) { Object.defineProperty(this, 'response', { value: response, }); } this.name = this.constructor.name; Error.captureStackTrace(this, this.constructor); } }; let RPError$8 = class RPError extends Error { constructor(...args) { if (typeof args[0] === 'string') { super(format$3(...args)); } else { const { message, printf, response, ...rest } = args[0]; if (printf) { super(format$3(...printf)); } else { super(message); } Object.assign(this, rest); if (response) { Object.defineProperty(this, 'response', { value: response, }); } } this.name = this.constructor.name; Error.captureStackTrace(this, this.constructor); } }; var errors$2 = { OPError: OPError$5, RPError: RPError$8, }; var client$2 = {exports: {}}; const crypto$4 = require$$0$3; const [major$3, minor$3] = process.version.substring(1).split('.').map((x) => parseInt(x, 10)); const xofOutputLength = major$3 > 12 || (major$3 === 12 && minor$3 >= 8); const shake256$1 = xofOutputLength && crypto$4.getHashes().includes('shake256'); var shake256_1 = shake256$1; const { strict: assert$3 } = require$$0$6; const { createHash: createHash$1 } = require$$0$3; const { format: format$2 } = require$$1; const shake256 = shake256_1; let encode$1; if (Buffer.isEncoding('base64url')) { encode$1 = (input) => input.toString('base64url'); } else { const fromBase64 = (base64) => base64.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); encode$1 = (input) => fromBase64(input.toString('base64')); } /** SPECIFICATION * Its (_hash) value is the base64url encoding of the left-most half of the hash of the octets of * the ASCII representation of the token value, where the hash algorithm used is the hash algorithm * used in the alg Header Parameter of the ID Token's JOSE Header. For instance, if the alg is * RS256, hash the token value with SHA-256, then take the left-most 128 bits and base64url encode * them. The _hash value is a case sensitive string. */ /** * @name getHash * @api private * * returns the sha length based off the JOSE alg heade value, defaults to sha256 * * @param token {String} token value to generate the hash from * @param alg {String} ID Token JOSE header alg value (i.e. RS256, HS384, ES512, PS256) * @param [crv] {String} For EdDSA the curve decides what hash algorithm is used. Required for EdDSA */ function getHash(alg, crv) { switch (alg) { case 'HS256': case 'RS256': case 'PS256': case 'ES256': case 'ES256K': return createHash$1('sha256'); case 'HS384': case 'RS384': case 'PS384': case 'ES384': return createHash$1('sha384'); case 'HS512': case 'RS512': case 'PS512': case 'ES512': return createHash$1('sha512'); case 'EdDSA': switch (crv) { case 'Ed25519': return createHash$1('sha512'); case 'Ed448': if (!shake256) { throw new TypeError('Ed448 *_hash calculation is not supported in your Node.js runtime version'); } return createHash$1('shake256', { outputLength: 114 }); default: throw new TypeError('unrecognized or invalid EdDSA curve provided'); } default: throw new TypeError('unrecognized or invalid JWS algorithm provided'); } } function generate$1(token, alg, crv) { const digest = getHash(alg, crv).update(token).digest(); return encode$1(digest.slice(0, digest.length / 2)); } function validate$1(names, actual, source, alg, crv) { if (typeof names.claim !== 'string' || !names.claim) { throw new TypeError('names.claim must be a non-empty string'); } if (typeof names.source !== 'string' || !names.source) { throw new TypeError('names.source must be a non-empty string'); } assert$3(typeof actual === 'string' && actual, `${names.claim} must be a non-empty string`); assert$3(typeof source === 'string' && source, `${names.source} must be a non-empty string`); let expected; let msg; try { expected = generate$1(source, alg, crv); } catch (err) { msg = format$2('%s could not be validated (%s)', names.claim, err.message); } msg = msg || format$2('%s mismatch, expected %s, got: %s', names.claim, expected, actual); assert$3.equal(expected, actual, msg); } var lib$3 = { validate: validate$1, generate: generate$1, }; const util$6 = require$$1; const crypto$3 = require$$0$3; var is_key_object = util$6.types.isKeyObject || ((obj) => obj && obj instanceof crypto$3.KeyObject); var base64url$5 = {}; let encode; if (Buffer.isEncoding('base64url')) { encode = (input, encoding = 'utf8') => Buffer.from(input, encoding).toString('base64url'); } else { const fromBase64 = (base64) => base64.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); encode = (input, encoding = 'utf8') => fromBase64(Buffer.from(input, encoding).toString('base64')); } const decode$2 = (input) => Buffer.from(input, 'base64'); base64url$5.decode = decode$2; base64url$5.encode = encode; const base64url$4 = base64url$5; var decode_jwt = (token) => { if (typeof token !== 'string' || !token) { throw new TypeError('JWT must be a string'); } const { 0: header, 1: payload, 2: signature, length } = token.split('.'); if (length === 5) { throw new TypeError('encrypted JWTs cannot be decoded'); } if (length !== 3) { throw new Error('JWTs must have three components'); } try { return { header: JSON.parse(base64url$4.decode(header)), payload: JSON.parse(base64url$4.decode(payload)), signature, }; } catch (err) { throw new Error('JWT is malformed'); } }; var defaults$5 = {exports: {}}; var is_plain_object = (a) => !!a && a.constructor === Object; const isPlainObject$5 = is_plain_object; function defaults$4(deep, target, ...sources) { for (const source of sources) { if (!isPlainObject$5(source)) { continue; } for (const [key, value] of Object.entries(source)) { /* istanbul ignore if */ if (key === '__proto__' || key === 'constructor') { continue; } if (typeof target[key] === 'undefined' && typeof value !== 'undefined') { target[key] = value; } if (deep && isPlainObject$5(target[key]) && isPlainObject$5(value)) { defaults$4(true, target[key], value); } } } return target; } defaults$5.exports = defaults$4.bind(undefined, false); defaults$5.exports.deep = defaults$4.bind(undefined, true); var defaultsExports = defaults$5.exports; const REGEXP = /(\w+)=("[^"]*")/g; var www_authenticate_parser = (wwwAuthenticate) => { const params = {}; try { while (REGEXP.exec(wwwAuthenticate) !== null) { if (RegExp.$1 && RegExp.$2) { params[RegExp.$1] = RegExp.$2.slice(1, -1); } } } catch (err) {} return params; }; function assertSigningAlgValuesSupport$1(endpoint, issuer, properties) { if (!issuer[`${endpoint}_endpoint`]) return; const eam = `${endpoint}_endpoint_auth_method`; const easa = `${endpoint}_endpoint_auth_signing_alg`; const easavs = `${endpoint}_endpoint_auth_signing_alg_values_supported`; if (properties[eam] && properties[eam].endsWith('_jwt') && !properties[easa] && !issuer[easavs]) { throw new TypeError( `${easavs} must be configured on the issuer if ${easa} is not defined on a client`, ); } } function assertIssuerConfiguration$3(issuer, endpoint) { if (!issuer[endpoint]) { throw new TypeError(`${endpoint} must be configured on the issuer`); } } var assert$2 = { assertSigningAlgValuesSupport: assertSigningAlgValuesSupport$1, assertIssuerConfiguration: assertIssuerConfiguration$3, }; var pick$3 = function pick(object, ...paths) { const obj = {}; for (const path of paths) { if (object[path] !== undefined) { obj[path] = object[path]; } } return obj; }; const { STATUS_CODES } = require$$0$5; const { format: format$1 } = require$$1; const { OPError: OPError$4 } = errors$2; const parseWwwAuthenticate$1 = www_authenticate_parser; const throwAuthenticateErrors = (response) => { const params = parseWwwAuthenticate$1(response.headers['www-authenticate']); if (params.error) { throw new OPError$4(params, response); } }; const isStandardBodyError = (response) => { let result = false; try { let jsonbody; if (typeof response.body !== 'object' || Buffer.isBuffer(response.body)) { jsonbody = JSON.parse(response.body); } else { jsonbody = response.body; } result = typeof jsonbody.error === 'string' && jsonbody.error.length; if (result) Object.defineProperty(response, 'body', { value: jsonbody, configurable: true }); } catch (err) {} return result; }; function processResponse$3(response, { statusCode = 200, body = true, bearer = false } = {}) { if (response.statusCode !== statusCode) { if (bearer) { throwAuthenticateErrors(response); } if (isStandardBodyError(response)) { throw new OPError$4(response.body, response); } throw new OPError$4( { error: format$1( 'expected %i %s, got: %i %s', statusCode, STATUS_CODES[statusCode], response.statusCode, STATUS_CODES[response.statusCode], ), }, response, ); } if (body && !response.body) { throw new OPError$4( { error: format$1( 'expected %i %s with body but no body was returned', statusCode, STATUS_CODES[statusCode], ), }, response, ); } return response.body; } var process_response = processResponse$3; var unix_timestamp = () => Math.floor(Date.now() / 1000); const base64url$3 = base64url$5; const now$3 = unix_timestamp; let TokenSet$2 = class TokenSet { constructor(values) { Object.assign(this, values); const { constructor, ...properties } = Object.getOwnPropertyDescriptors( this.constructor.prototype, ); Object.defineProperties(this, properties); } set expires_in(value) { this.expires_at = now$3() + Number(value); } get expires_in() { return Math.max.apply(null, [this.expires_at - now$3(), 0]); } expired() { return this.expires_in === 0; } claims() { if (!this.id_token) { throw new TypeError('id_token not present in TokenSet'); } return JSON.parse(base64url$3.decode(this.id_token.split('.')[1])); } }; var token_set = TokenSet$2; const { createHash, randomBytes } = require$$0$3; const base64url$2 = base64url$5; const random$3 = (bytes = 32) => base64url$2.encode(randomBytes(bytes)); var generators$1 = { random: random$3, state: random$3, nonce: random$3, codeVerifier: random$3, codeChallenge: (codeVerifier) => base64url$2.encode(createHash('sha256').update(codeVerifier).digest()), }; var request$4 = {exports: {}}; var name$1 = "openid-client"; var version$2 = "5.6.5"; var description$1 = "OpenID Connect Relying Party (RP, Client) implementation for Node.js runtime, supports passportjs"; var keywords$1 = [ "auth", "authentication", "basic", "certified", "client", "connect", "dynamic", "electron", "hybrid", "identity", "implicit", "oauth", "oauth2", "oidc", "openid", "passport", "relying party", "strategy" ]; var homepage = "https://github.com/panva/node-openid-client"; var repository$1 = "panva/node-openid-client"; var funding$1 = { url: "https://github.com/sponsors/panva" }; var license$1 = "MIT"; var author = "Filip Skokan "; var exports$2 = { types: "./types/index.d.ts", "import": "./lib/index.mjs", require: "./lib/index.js" }; var main$2 = "./lib/index.js"; var types$2 = "./types/index.d.ts"; var files = [ "lib", "types/index.d.ts" ]; var scripts$1 = { format: "npx prettier --loglevel silent --write ./lib ./test ./certification ./types", test: "mocha test/**/*.test.js" }; var dependencies = { jose: "^4.15.5", "lru-cache": "^6.0.0", "object-hash": "^2.2.0", "oidc-token-hash": "^5.0.3" }; var devDependencies$1 = { "@types/node": "^16.18.87", "@types/passport": "^1.0.16", base64url: "^3.0.1", chai: "^4.4.1", mocha: "^10.3.0", nock: "^13.5.4", prettier: "^2.8.8", "readable-mock-req": "^0.2.2", sinon: "^9.2.4", timekeeper: "^2.3.1" }; var require$$7 = { name: name$1, version: version$2, description: description$1, keywords: keywords$1, homepage: homepage, repository: repository$1, funding: funding$1, license: license$1, author: author, exports: exports$2, main: main$2, types: types$2, files: files, scripts: scripts$1, dependencies: dependencies, devDependencies: devDependencies$1, "standard-version": { scripts: { postchangelog: "sed -i '' -e 's/### \\[/## [/g' CHANGELOG.md" }, types: [ { type: "feat", section: "Features" }, { type: "fix", section: "Fixes" }, { type: "chore", hidden: true }, { type: "docs", hidden: true }, { type: "style", hidden: true }, { type: "refactor", section: "Refactor", hidden: false }, { type: "perf", section: "Performance", hidden: false }, { type: "test", hidden: true } ] } }; const HTTP_OPTIONS$2 = Symbol(); const CLOCK_TOLERANCE$2 = Symbol(); var consts = { CLOCK_TOLERANCE: CLOCK_TOLERANCE$2, HTTP_OPTIONS: HTTP_OPTIONS$2, }; const assert$1 = require$$0$6; const querystring$1 = require$$1$4; const http = require$$0$5; const https = require$$1$2; const { once: once$2 } = require$$1$3; const { URL: URL$2 } = require$$0$1; const LRU$2 = lruCache; const pkg = require$$7; const { RPError: RPError$7 } = errors$2; const pick$2 = pick$3; const { deep: defaultsDeep } = defaultsExports; const { HTTP_OPTIONS: HTTP_OPTIONS$1 } = consts; let DEFAULT_HTTP_OPTIONS; const NQCHAR = /^[\x21\x23-\x5B\x5D-\x7E]+$/; const allowed = [ 'agent', 'ca', 'cert', 'crl', 'headers', 'key', 'lookup', 'passphrase', 'pfx', 'timeout', ]; const setDefaults$1 = (props, options) => { DEFAULT_HTTP_OPTIONS = defaultsDeep( {}, props.length ? pick$2(options, ...props) : options, DEFAULT_HTTP_OPTIONS, ); }; setDefaults$1([], { headers: { 'User-Agent': `${pkg.name}/${pkg.version} (${pkg.homepage})`, 'Accept-Encoding': 'identity', }, timeout: 3500, }); function send(req, body, contentType) { if (contentType) { req.removeHeader('content-type'); req.setHeader('content-type', contentType); } if (body) { req.removeHeader('content-length'); req.setHeader('content-length', Buffer.byteLength(body)); req.write(body); } req.end(); } const nonces = new LRU$2({ max: 100 }); request$4.exports = async function request(options, { accessToken, mTLS = false, DPoP } = {}) { let url; try { url = new URL$2(options.url); delete options.url; assert$1(/^(https?:)$/.test(url.protocol)); } catch (err) { throw new TypeError('only valid absolute URLs can be requested'); } const optsFn = this[HTTP_OPTIONS$1]; let opts = options; const nonceKey = `${url.origin}${url.pathname}`; if (DPoP && 'dpopProof' in this) { opts.headers = opts.headers || {}; opts.headers.DPoP = await this.dpopProof( { htu: `${url.origin}${url.pathname}`, htm: options.method, nonce: nonces.get(nonceKey), }, DPoP, accessToken, ); } let userOptions; if (optsFn) { userOptions = pick$2( optsFn.call(this, url, defaultsDeep({}, opts, DEFAULT_HTTP_OPTIONS)), ...allowed, ); } opts = defaultsDeep({}, userOptions, opts, DEFAULT_HTTP_OPTIONS); if (mTLS && !opts.pfx && !(opts.key && opts.cert)) { throw new TypeError('mutual-TLS certificate and key not set'); } if (opts.searchParams) { for (const [key, value] of Object.entries(opts.searchParams)) { url.searchParams.delete(key); url.searchParams.set(key, value); } } let responseType; let form; let json; let body; ({ form, responseType, json, body, ...opts } = opts); for (const [key, value] of Object.entries(opts.headers || {})) { if (value === undefined) { delete opts.headers[key]; } } let response; const req = (url.protocol === 'https:' ? https.request : http.request)(url.href, opts); return (async () => { if (json) { send(req, JSON.stringify(json), 'application/json'); } else if (form) { send(req, querystring$1.stringify(form), 'application/x-www-form-urlencoded'); } else if (body) { send(req, body); } else { send(req); } [response] = await Promise.race([once$2(req, 'response'), once$2(req, 'timeout')]); // timeout reached if (!response) { req.destroy(); throw new RPError$7(`outgoing request timed out after ${opts.timeout}ms`); } const parts = []; for await (const part of response) { parts.push(part); } if (parts.length) { switch (responseType) { case 'json': { Object.defineProperty(response, 'body', { get() { let value = Buffer.concat(parts); try { value = JSON.parse(value); } catch (err) { Object.defineProperty(err, 'response', { value: response }); throw err; } finally { Object.defineProperty(response, 'body', { value, configurable: true }); } return value; }, configurable: true, }); break; } case undefined: case 'buffer': { Object.defineProperty(response, 'body', { get() { const value = Buffer.concat(parts); Object.defineProperty(response, 'body', { value, configurable: true }); return value; }, configurable: true, }); break; } default: throw new TypeError('unsupported responseType request option'); } } return response; })() .catch((err) => { if (response) Object.defineProperty(err, 'response', { value: response }); throw err; }) .finally(() => { const dpopNonce = response && response.headers['dpop-nonce']; if (dpopNonce && NQCHAR.test(dpopNonce)) { nonces.set(nonceKey, dpopNonce); } }); }; request$4.exports.setDefaults = setDefaults$1.bind(undefined, allowed); var requestExports = request$4.exports; var weak_cache = {}; weak_cache.keystores = new WeakMap(); var deep_clone = globalThis.structuredClone || ((obj) => JSON.parse(JSON.stringify(obj))); const jose$2 = cjs; const clone$4 = deep_clone; const isPlainObject$4 = is_plain_object; const internal = Symbol(); const keyscore = (key, { alg, use }) => { let score = 0; if (alg && key.alg) { score++; } if (use && key.use) { score++; } return score; }; function getKtyFromAlg(alg) { switch (typeof alg === 'string' && alg.slice(0, 2)) { case 'RS': case 'PS': return 'RSA'; case 'ES': return 'EC'; case 'Ed': return 'OKP'; default: return undefined; } } function getAlgorithms(use, alg, kty, crv) { // Ed25519, Ed448, and secp256k1 always have "alg" // OKP always has "use" if (alg) { return new Set([alg]); } switch (kty) { case 'EC': { let algs = []; if (use === 'enc' || use === undefined) { algs = algs.concat(['ECDH-ES', 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW']); } if (use === 'sig' || use === undefined) { switch (crv) { case 'P-256': case 'P-384': algs = algs.concat([`ES${crv.slice(-3)}`]); break; case 'P-521': algs = algs.concat(['ES512']); break; case 'secp256k1': if (jose$2.cryptoRuntime === 'node:crypto') { algs = algs.concat(['ES256K']); } break; } } return new Set(algs); } case 'OKP': { return new Set(['ECDH-ES', 'ECDH-ES+A128KW', 'ECDH-ES+A192KW', 'ECDH-ES+A256KW']); } case 'RSA': { let algs = []; if (use === 'enc' || use === undefined) { algs = algs.concat(['RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512']); if (jose$2.cryptoRuntime === 'node:crypto') { algs = algs.concat(['RSA1_5']); } } if (use === 'sig' || use === undefined) { algs = algs.concat(['PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512']); } return new Set(algs); } default: throw new Error('unreachable'); } } var keystore$1 = class KeyStore { #keys; constructor(i, keys) { if (i !== internal) throw new Error('invalid constructor call'); this.#keys = keys; } toJWKS() { return { keys: this.map(({ jwk: { d, p, q, dp, dq, qi, ...jwk } }) => jwk), }; } all({ alg, kid, use } = {}) { if (!use || !alg) { throw new Error(); } const kty = getKtyFromAlg(alg); const search = { alg, use }; return this.filter((key) => { let candidate = true; if (candidate && kty !== undefined && key.jwk.kty !== kty) { candidate = false; } if (candidate && kid !== undefined && key.jwk.kid !== kid) { candidate = false; } if (candidate && use !== undefined && key.jwk.use !== undefined && key.jwk.use !== use) { candidate = false; } if (candidate && key.jwk.alg && key.jwk.alg !== alg) { candidate = false; } else if (!key.algorithms.has(alg)) { candidate = false; } return candidate; }).sort((first, second) => keyscore(second, search) - keyscore(first, search)); } get(...args) { return this.all(...args)[0]; } static async fromJWKS(jwks, { onlyPublic = false, onlyPrivate = false } = {}) { if ( !isPlainObject$4(jwks) || !Array.isArray(jwks.keys) || jwks.keys.some((k) => !isPlainObject$4(k) || !('kty' in k)) ) { throw new TypeError('jwks must be a JSON Web Key Set formatted object'); } const keys = []; for (let jwk of jwks.keys) { jwk = clone$4(jwk); const { kty, kid, crv } = jwk; let { alg, use } = jwk; if (typeof kty !== 'string' || !kty) { continue; } if (use !== undefined && use !== 'sig' && use !== 'enc') { continue; } if (typeof alg !== 'string' && alg !== undefined) { continue; } if (typeof kid !== 'string' && kid !== undefined) { continue; } if (kty === 'EC' && use === 'sig') { switch (crv) { case 'P-256': alg = 'ES256'; break; case 'P-384': alg = 'ES384'; break; case 'P-521': alg = 'ES512'; break; } } if (crv === 'secp256k1') { use = 'sig'; alg = 'ES256K'; } if (kty === 'OKP') { switch (crv) { case 'Ed25519': case 'Ed448': use = 'sig'; alg = 'EdDSA'; break; case 'X25519': case 'X448': use = 'enc'; break; } } if (alg && !use) { switch (true) { case alg.startsWith('ECDH'): use = 'enc'; break; case alg.startsWith('RSA'): use = 'enc'; break; } } if (onlyPrivate && (jwk.kty === 'oct' || !jwk.d)) { throw new Error('jwks must only contain private keys'); } if (onlyPublic && (jwk.d || jwk.k)) { continue; } keys.push({ jwk: { ...jwk, alg, use }, async keyObject(alg) { if (this[alg]) { return this[alg]; } const keyObject = await jose$2.importJWK(this.jwk, alg); this[alg] = keyObject; return keyObject; }, get algorithms() { Object.defineProperty(this, 'algorithms', { value: getAlgorithms(this.jwk.use, this.jwk.alg, this.jwk.kty, this.jwk.crv), enumerable: true, configurable: false, }); return this.algorithms; }, }); } return new this(internal, keys); } filter(...args) { return this.#keys.filter(...args); } find(...args) { return this.#keys.find(...args); } every(...args) { return this.#keys.every(...args); } some(...args) { return this.#keys.some(...args); } map(...args) { return this.#keys.map(...args); } forEach(...args) { return this.#keys.forEach(...args); } reduce(...args) { return this.#keys.reduce(...args); } sort(...args) { return this.#keys.sort(...args); } *[Symbol.iterator]() { for (const key of this.#keys) { yield key; } } }; const isPlainObject$3 = is_plain_object; function merge$2(target, ...sources) { for (const source of sources) { if (!isPlainObject$3(source)) { continue; } for (const [key, value] of Object.entries(source)) { /* istanbul ignore if */ if (key === '__proto__' || key === 'constructor') { continue; } if (isPlainObject$3(target[key]) && isPlainObject$3(value)) { target[key] = merge$2(target[key], value); } else if (typeof value !== 'undefined') { target[key] = value; } } } return target; } var merge_1 = merge$2; const jose$1 = cjs; const { RPError: RPError$6 } = errors$2; const { assertIssuerConfiguration: assertIssuerConfiguration$2 } = assert$2; const { random: random$2 } = generators$1; const now$2 = unix_timestamp; const request$3 = requestExports; const { keystores: keystores$2 } = weak_cache; const merge$1 = merge_1; // TODO: in v6.x additionally encode the `- _ . ! ~ * ' ( )` characters // https://github.com/panva/node-openid-client/commit/5a2ea80ef5e59ec0c03dbd97d82f551e24a9d348 const formUrlEncode = (value) => encodeURIComponent(value).replace(/%20/g, '+'); async function clientAssertion(endpoint, payload) { let alg = this[`${endpoint}_endpoint_auth_signing_alg`]; if (!alg) { assertIssuerConfiguration$2( this.issuer, `${endpoint}_endpoint_auth_signing_alg_values_supported`, ); } if (this[`${endpoint}_endpoint_auth_method`] === 'client_secret_jwt') { if (!alg) { const supported = this.issuer[`${endpoint}_endpoint_auth_signing_alg_values_supported`]; alg = Array.isArray(supported) && supported.find((signAlg) => /^HS(?:256|384|512)/.test(signAlg)); } if (!alg) { throw new RPError$6( `failed to determine a JWS Algorithm to use for ${ this[`${endpoint}_endpoint_auth_method`] } Client Assertion`, ); } return new jose$1.CompactSign(Buffer.from(JSON.stringify(payload))) .setProtectedHeader({ alg }) .sign(this.secretForAlg(alg)); } const keystore = await keystores$2.get(this); if (!keystore) { throw new TypeError('no client jwks provided for signing a client assertion with'); } if (!alg) { const supported = this.issuer[`${endpoint}_endpoint_auth_signing_alg_values_supported`]; alg = Array.isArray(supported) && supported.find((signAlg) => keystore.get({ alg: signAlg, use: 'sig' })); } if (!alg) { throw new RPError$6( `failed to determine a JWS Algorithm to use for ${ this[`${endpoint}_endpoint_auth_method`] } Client Assertion`, ); } const key = keystore.get({ alg, use: 'sig' }); if (!key) { throw new RPError$6( `no key found in client jwks to sign a client assertion with using alg ${alg}`, ); } return new jose$1.CompactSign(Buffer.from(JSON.stringify(payload))) .setProtectedHeader({ alg, kid: key.jwk && key.jwk.kid }) .sign(await key.keyObject(alg)); } async function authFor(endpoint, { clientAssertionPayload } = {}) { const authMethod = this[`${endpoint}_endpoint_auth_method`]; switch (authMethod) { case 'self_signed_tls_client_auth': case 'tls_client_auth': case 'none': return { form: { client_id: this.client_id } }; case 'client_secret_post': if (typeof this.client_secret !== 'string') { throw new TypeError( 'client_secret_post client authentication method requires a client_secret', ); } return { form: { client_id: this.client_id, client_secret: this.client_secret } }; case 'private_key_jwt': case 'client_secret_jwt': { const timestamp = now$2(); const audience = [ ...new Set([this.issuer.issuer, this.issuer.token_endpoint].filter(Boolean)), ]; const assertion = await clientAssertion.call(this, endpoint, { iat: timestamp, exp: timestamp + 60, jti: random$2(), iss: this.client_id, sub: this.client_id, aud: audience, ...clientAssertionPayload, }); return { form: { client_id: this.client_id, client_assertion: assertion, client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer', }, }; } case 'client_secret_basic': { // This is correct behaviour, see https://tools.ietf.org/html/rfc6749#section-2.3.1 and the // related appendix. (also https://github.com/panva/node-openid-client/pull/91) // > The client identifier is encoded using the // > "application/x-www-form-urlencoded" encoding algorithm per // > Appendix B, and the encoded value is used as the username; the client // > password is encoded using the same algorithm and used as the // > password. if (typeof this.client_secret !== 'string') { throw new TypeError( 'client_secret_basic client authentication method requires a client_secret', ); } const encoded = `${formUrlEncode(this.client_id)}:${formUrlEncode(this.client_secret)}`; const value = Buffer.from(encoded).toString('base64'); return { headers: { Authorization: `Basic ${value}` } }; } default: { throw new TypeError(`missing, or unsupported, ${endpoint}_endpoint_auth_method`); } } } function resolveResponseType$2() { const { length, 0: value } = this.response_types; if (length === 1) { return value; } return undefined; } function resolveRedirectUri$2() { const { length, 0: value } = this.redirect_uris || []; if (length === 1) { return value; } return undefined; } async function authenticatedPost$1( endpoint, opts, { clientAssertionPayload, endpointAuthMethod = endpoint, DPoP } = {}, ) { const auth = await authFor.call(this, endpointAuthMethod, { clientAssertionPayload }); const requestOpts = merge$1(opts, auth); const mTLS = this[`${endpointAuthMethod}_endpoint_auth_method`].includes('tls_client_auth') || (endpoint === 'token' && this.tls_client_certificate_bound_access_tokens); let targetUrl; if (mTLS && this.issuer.mtls_endpoint_aliases) { targetUrl = this.issuer.mtls_endpoint_aliases[`${endpoint}_endpoint`]; } targetUrl = targetUrl || this.issuer[`${endpoint}_endpoint`]; if ('form' in requestOpts) { for (const [key, value] of Object.entries(requestOpts.form)) { if (typeof value === 'undefined') { delete requestOpts.form[key]; } } } return request$3.call( this, { ...requestOpts, method: 'POST', url: targetUrl, headers: { ...(endpoint !== 'revocation' ? { Accept: 'application/json', } : undefined), ...requestOpts.headers, }, }, { mTLS, DPoP }, ); } var client$1 = { resolveResponseType: resolveResponseType$2, resolveRedirectUri: resolveRedirectUri$2, authFor, authenticatedPost: authenticatedPost$1, }; var issuer$1 = {}; var objectHash$1 = {exports: {}}; (function (module, exports) { var crypto = require$$0$3; /** * Exported function * * Options: * * - `algorithm` hash algo to be used by this instance: *'sha1', 'md5' * - `excludeValues` {true|*false} hash object keys, values ignored * - `encoding` hash encoding, supports 'buffer', '*hex', 'binary', 'base64' * - `ignoreUnknown` {true|*false} ignore unknown object types * - `replacer` optional function that replaces values before hashing * - `respectFunctionProperties` {*true|false} consider function properties when hashing * - `respectFunctionNames` {*true|false} consider 'name' property of functions for hashing * - `respectType` {*true|false} Respect special properties (prototype, constructor) * when hashing to distinguish between types * - `unorderedArrays` {true|*false} Sort all arrays before hashing * - `unorderedSets` {*true|false} Sort `Set` and `Map` instances before hashing * * = default * * @param {object} object value to hash * @param {object} options hashing options * @return {string} hash value * @api public */ exports = module.exports = objectHash; function objectHash(object, options){ options = applyDefaults(object, options); return hash(object, options); } /** * Exported sugar methods * * @param {object} object value to hash * @return {string} hash value * @api public */ exports.sha1 = function(object){ return objectHash(object); }; exports.keys = function(object){ return objectHash(object, {excludeValues: true, algorithm: 'sha1', encoding: 'hex'}); }; exports.MD5 = function(object){ return objectHash(object, {algorithm: 'md5', encoding: 'hex'}); }; exports.keysMD5 = function(object){ return objectHash(object, {algorithm: 'md5', encoding: 'hex', excludeValues: true}); }; // Internals var hashes = crypto.getHashes ? crypto.getHashes().slice() : ['sha1', 'md5']; hashes.push('passthrough'); var encodings = ['buffer', 'hex', 'binary', 'base64']; function applyDefaults(object, sourceOptions){ sourceOptions = sourceOptions || {}; // create a copy rather than mutating var options = {}; options.algorithm = sourceOptions.algorithm || 'sha1'; options.encoding = sourceOptions.encoding || 'hex'; options.excludeValues = sourceOptions.excludeValues ? true : false; options.algorithm = options.algorithm.toLowerCase(); options.encoding = options.encoding.toLowerCase(); options.ignoreUnknown = sourceOptions.ignoreUnknown !== true ? false : true; // default to false options.respectType = sourceOptions.respectType === false ? false : true; // default to true options.respectFunctionNames = sourceOptions.respectFunctionNames === false ? false : true; options.respectFunctionProperties = sourceOptions.respectFunctionProperties === false ? false : true; options.unorderedArrays = sourceOptions.unorderedArrays !== true ? false : true; // default to false options.unorderedSets = sourceOptions.unorderedSets === false ? false : true; // default to false options.unorderedObjects = sourceOptions.unorderedObjects === false ? false : true; // default to true options.replacer = sourceOptions.replacer || undefined; options.excludeKeys = sourceOptions.excludeKeys || undefined; if(typeof object === 'undefined') { throw new Error('Object argument required.'); } // if there is a case-insensitive match in the hashes list, accept it // (i.e. SHA256 for sha256) for (var i = 0; i < hashes.length; ++i) { if (hashes[i].toLowerCase() === options.algorithm.toLowerCase()) { options.algorithm = hashes[i]; } } if(hashes.indexOf(options.algorithm) === -1){ throw new Error('Algorithm "' + options.algorithm + '" not supported. ' + 'supported values: ' + hashes.join(', ')); } if(encodings.indexOf(options.encoding) === -1 && options.algorithm !== 'passthrough'){ throw new Error('Encoding "' + options.encoding + '" not supported. ' + 'supported values: ' + encodings.join(', ')); } return options; } /** Check if the given function is a native function */ function isNativeFunction(f) { if ((typeof f) !== 'function') { return false; } var exp = /^function\s+\w*\s*\(\s*\)\s*{\s+\[native code\]\s+}$/i; return exp.exec(Function.prototype.toString.call(f)) != null; } function hash(object, options) { var hashingStream; if (options.algorithm !== 'passthrough') { hashingStream = crypto.createHash(options.algorithm); } else { hashingStream = new PassThrough(); } if (typeof hashingStream.write === 'undefined') { hashingStream.write = hashingStream.update; hashingStream.end = hashingStream.update; } var hasher = typeHasher(options, hashingStream); hasher.dispatch(object); if (!hashingStream.update) { hashingStream.end(''); } if (hashingStream.digest) { return hashingStream.digest(options.encoding === 'buffer' ? undefined : options.encoding); } var buf = hashingStream.read(); if (options.encoding === 'buffer') { return buf; } return buf.toString(options.encoding); } /** * Expose streaming API * * @param {object} object Value to serialize * @param {object} options Options, as for hash() * @param {object} stream A stream to write the serializiation to * @api public */ exports.writeToStream = function(object, options, stream) { if (typeof stream === 'undefined') { stream = options; options = {}; } options = applyDefaults(object, options); return typeHasher(options, stream).dispatch(object); }; function typeHasher(options, writeTo, context){ context = context || []; var write = function(str) { if (writeTo.update) { return writeTo.update(str, 'utf8'); } else { return writeTo.write(str, 'utf8'); } }; return { dispatch: function(value){ if (options.replacer) { value = options.replacer(value); } var type = typeof value; if (value === null) { type = 'null'; } //console.log("[DEBUG] Dispatch: ", value, "->", type, " -> ", "_" + type); return this['_' + type](value); }, _object: function(object) { var pattern = (/\[object (.*)\]/i); var objString = Object.prototype.toString.call(object); var objType = pattern.exec(objString); if (!objType) { // object type did not match [object ...] objType = 'unknown:[' + objString + ']'; } else { objType = objType[1]; // take only the class name } objType = objType.toLowerCase(); var objectNumber = null; if ((objectNumber = context.indexOf(object)) >= 0) { return this.dispatch('[CIRCULAR:' + objectNumber + ']'); } else { context.push(object); } if (typeof Buffer !== 'undefined' && Buffer.isBuffer && Buffer.isBuffer(object)) { write('buffer:'); return write(object); } if(objType !== 'object' && objType !== 'function' && objType !== 'asyncfunction') { if(this['_' + objType]) { this['_' + objType](object); } else if (options.ignoreUnknown) { return write('[' + objType + ']'); } else { throw new Error('Unknown object type "' + objType + '"'); } }else { var keys = Object.keys(object); if (options.unorderedObjects) { keys = keys.sort(); } // Make sure to incorporate special properties, so // Types with different prototypes will produce // a different hash and objects derived from // different functions (`new Foo`, `new Bar`) will // produce different hashes. // We never do this for native functions since some // seem to break because of that. if (options.respectType !== false && !isNativeFunction(object)) { keys.splice(0, 0, 'prototype', '__proto__', 'constructor'); } if (options.excludeKeys) { keys = keys.filter(function(key) { return !options.excludeKeys(key); }); } write('object:' + keys.length + ':'); var self = this; return keys.forEach(function(key){ self.dispatch(key); write(':'); if(!options.excludeValues) { self.dispatch(object[key]); } write(','); }); } }, _array: function(arr, unordered){ unordered = typeof unordered !== 'undefined' ? unordered : options.unorderedArrays !== false; // default to options.unorderedArrays var self = this; write('array:' + arr.length + ':'); if (!unordered || arr.length <= 1) { return arr.forEach(function(entry) { return self.dispatch(entry); }); } // the unordered case is a little more complicated: // since there is no canonical ordering on objects, // i.e. {a:1} < {a:2} and {a:1} > {a:2} are both false, // we first serialize each entry using a PassThrough stream // before sorting. // also: we can’t use the same context array for all entries // since the order of hashing should *not* matter. instead, // we keep track of the additions to a copy of the context array // and add all of them to the global context array when we’re done var contextAdditions = []; var entries = arr.map(function(entry) { var strm = new PassThrough(); var localContext = context.slice(); // make copy var hasher = typeHasher(options, strm, localContext); hasher.dispatch(entry); // take only what was added to localContext and append it to contextAdditions contextAdditions = contextAdditions.concat(localContext.slice(context.length)); return strm.read().toString(); }); context = context.concat(contextAdditions); entries.sort(); return this._array(entries, false); }, _date: function(date){ return write('date:' + date.toJSON()); }, _symbol: function(sym){ return write('symbol:' + sym.toString()); }, _error: function(err){ return write('error:' + err.toString()); }, _boolean: function(bool){ return write('bool:' + bool.toString()); }, _string: function(string){ write('string:' + string.length + ':'); write(string.toString()); }, _function: function(fn){ write('fn:'); if (isNativeFunction(fn)) { this.dispatch('[native]'); } else { this.dispatch(fn.toString()); } if (options.respectFunctionNames !== false) { // Make sure we can still distinguish native functions // by their name, otherwise String and Function will // have the same hash this.dispatch("function-name:" + String(fn.name)); } if (options.respectFunctionProperties) { this._object(fn); } }, _number: function(number){ return write('number:' + number.toString()); }, _xml: function(xml){ return write('xml:' + xml.toString()); }, _null: function() { return write('Null'); }, _undefined: function() { return write('Undefined'); }, _regexp: function(regex){ return write('regex:' + regex.toString()); }, _uint8array: function(arr){ write('uint8array:'); return this.dispatch(Array.prototype.slice.call(arr)); }, _uint8clampedarray: function(arr){ write('uint8clampedarray:'); return this.dispatch(Array.prototype.slice.call(arr)); }, _int8array: function(arr){ write('uint8array:'); return this.dispatch(Array.prototype.slice.call(arr)); }, _uint16array: function(arr){ write('uint16array:'); return this.dispatch(Array.prototype.slice.call(arr)); }, _int16array: function(arr){ write('uint16array:'); return this.dispatch(Array.prototype.slice.call(arr)); }, _uint32array: function(arr){ write('uint32array:'); return this.dispatch(Array.prototype.slice.call(arr)); }, _int32array: function(arr){ write('uint32array:'); return this.dispatch(Array.prototype.slice.call(arr)); }, _float32array: function(arr){ write('float32array:'); return this.dispatch(Array.prototype.slice.call(arr)); }, _float64array: function(arr){ write('float64array:'); return this.dispatch(Array.prototype.slice.call(arr)); }, _arraybuffer: function(arr){ write('arraybuffer:'); return this.dispatch(new Uint8Array(arr)); }, _url: function(url) { return write('url:' + url.toString()); }, _map: function(map) { write('map:'); var arr = Array.from(map); return this._array(arr, options.unorderedSets !== false); }, _set: function(set) { write('set:'); var arr = Array.from(set); return this._array(arr, options.unorderedSets !== false); }, _file: function(file) { write('file:'); return this.dispatch([file.name, file.size, file.type, file.lastModfied]); }, _blob: function() { if (options.ignoreUnknown) { return write('[blob]'); } throw Error('Hashing Blob objects is currently not supported\n' + '(see https://github.com/puleos/object-hash/issues/26)\n' + 'Use "options.replacer" or "options.ignoreUnknown"\n'); }, _domwindow: function() { return write('domwindow'); }, _bigint: function(number){ return write('bigint:' + number.toString()); }, /* Node.js standard native objects */ _process: function() { return write('process'); }, _timer: function() { return write('timer'); }, _pipe: function() { return write('pipe'); }, _tcp: function() { return write('tcp'); }, _udp: function() { return write('udp'); }, _tty: function() { return write('tty'); }, _statwatcher: function() { return write('statwatcher'); }, _securecontext: function() { return write('securecontext'); }, _connection: function() { return write('connection'); }, _zlib: function() { return write('zlib'); }, _context: function() { return write('context'); }, _nodescript: function() { return write('nodescript'); }, _httpparser: function() { return write('httpparser'); }, _dataview: function() { return write('dataview'); }, _signal: function() { return write('signal'); }, _fsevent: function() { return write('fsevent'); }, _tlswrap: function() { return write('tlswrap'); }, }; } // Mini-implementation of stream.PassThrough // We are far from having need for the full implementation, and we can // make assumptions like "many writes, then only one final read" // and we can ignore encoding specifics function PassThrough() { return { buf: '', write: function(b) { this.buf += b; }, end: function(b) { this.buf += b; }, read: function() { return this.buf; } }; } } (objectHash$1, objectHash$1.exports)); var objectHashExports = objectHash$1.exports; const objectHash = objectHashExports; const LRU$1 = lruCache; const { RPError: RPError$5 } = errors$2; const { assertIssuerConfiguration: assertIssuerConfiguration$1 } = assert$2; const KeyStore$1 = keystore$1; const { keystores: keystores$1 } = weak_cache; const processResponse$2 = process_response; const request$2 = requestExports; const inFlight = new WeakMap(); const caches = new WeakMap(); const lrus = (ctx) => { if (!caches.has(ctx)) { caches.set(ctx, new LRU$1({ max: 100 })); } return caches.get(ctx); }; async function getKeyStore(reload = false) { assertIssuerConfiguration$1(this, 'jwks_uri'); const keystore = keystores$1.get(this); const cache = lrus(this); if (reload || !keystore) { if (inFlight.has(this)) { return inFlight.get(this); } cache.reset(); inFlight.set( this, (async () => { const response = await request$2 .call(this, { method: 'GET', responseType: 'json', url: this.jwks_uri, headers: { Accept: 'application/json, application/jwk-set+json', }, }) .finally(() => { inFlight.delete(this); }); const jwks = processResponse$2(response); const joseKeyStore = KeyStore$1.fromJWKS(jwks, { onlyPublic: true }); cache.set('throttle', true, 60 * 1000); keystores$1.set(this, joseKeyStore); return joseKeyStore; })(), ); return inFlight.get(this); } return keystore; } async function queryKeyStore$1({ kid, kty, alg, use }, { allowMulti = false } = {}) { const cache = lrus(this); const def = { kid, kty, alg, use, }; const defHash = objectHash(def, { algorithm: 'sha256', ignoreUnknown: true, unorderedArrays: true, unorderedSets: true, respectType: false, }); // refresh keystore on every unknown key but also only upto once every minute const freshJwksUri = cache.get(defHash) || cache.get('throttle'); const keystore = await getKeyStore.call(this, !freshJwksUri); const keys = keystore.all(def); delete def.use; if (keys.length === 0) { throw new RPError$5({ printf: ["no valid key found in issuer's jwks_uri for key parameters %j", def], jwks: keystore, }); } if (!allowMulti && keys.length > 1 && !kid) { throw new RPError$5({ printf: [ "multiple matching keys found in issuer's jwks_uri for key parameters %j, kid must be provided in this case", def, ], jwks: keystore, }); } cache.set(defHash, true); return keys; } issuer$1.queryKeyStore = queryKeyStore$1; issuer$1.keystore = getKeyStore; const { inspect: inspect$2 } = require$$1; const { RPError: RPError$4, OPError: OPError$3 } = errors$2; const now$1 = unix_timestamp; let DeviceFlowHandle$1 = class DeviceFlowHandle { #aborted; #client; #clientAssertionPayload; #DPoP; #exchangeBody; #expires_at; #interval; #maxAge; #response; constructor({ client, exchangeBody, clientAssertionPayload, response, maxAge, DPoP }) { ['verification_uri', 'user_code', 'device_code'].forEach((prop) => { if (typeof response[prop] !== 'string' || !response[prop]) { throw new RPError$4( `expected ${prop} string to be returned by Device Authorization Response, got %j`, response[prop], ); } }); if (!Number.isSafeInteger(response.expires_in)) { throw new RPError$4( 'expected expires_in number to be returned by Device Authorization Response, got %j', response.expires_in, ); } this.#expires_at = now$1() + response.expires_in; this.#client = client; this.#DPoP = DPoP; this.#maxAge = maxAge; this.#exchangeBody = exchangeBody; this.#clientAssertionPayload = clientAssertionPayload; this.#response = response; this.#interval = response.interval * 1000 || 5000; } abort() { this.#aborted = true; } async poll({ signal } = {}) { if ((signal && signal.aborted) || this.#aborted) { throw new RPError$4('polling aborted'); } if (this.expired()) { throw new RPError$4( 'the device code %j has expired and the device authorization session has concluded', this.device_code, ); } await new Promise((resolve) => setTimeout(resolve, this.#interval)); let tokenset; try { tokenset = await this.#client.grant( { ...this.#exchangeBody, grant_type: 'urn:ietf:params:oauth:grant-type:device_code', device_code: this.device_code, }, { clientAssertionPayload: this.#clientAssertionPayload, DPoP: this.#DPoP }, ); } catch (err) { switch (err instanceof OPError$3 && err.error) { case 'slow_down': this.#interval += 5000; case 'authorization_pending': return this.poll({ signal }); default: throw err; } } if ('id_token' in tokenset) { await this.#client.decryptIdToken(tokenset); await this.#client.validateIdToken(tokenset, undefined, 'token', this.#maxAge); } return tokenset; } get device_code() { return this.#response.device_code; } get user_code() { return this.#response.user_code; } get verification_uri() { return this.#response.verification_uri; } get verification_uri_complete() { return this.#response.verification_uri_complete; } get expires_in() { return Math.max.apply(null, [this.#expires_at - now$1(), 0]); } expired() { return this.expires_in === 0; } /* istanbul ignore next */ [inspect$2.custom]() { return `${this.constructor.name} ${inspect$2(this.#response, { depth: Infinity, colors: process.stdout.isTTY, compact: false, sorted: true, })}`; } }; var device_flow_handle = DeviceFlowHandle$1; const { inspect: inspect$1 } = require$$1; const stdhttp = require$$0$5; const crypto$2 = require$$0$3; const { strict: assert } = require$$0$6; const querystring = require$$1$4; const url$2 = require$$0$1; const { URL: URL$1, URLSearchParams } = require$$0$1; const jose = cjs; const tokenHash = lib$3; const isKeyObject = is_key_object; const decodeJWT = decode_jwt; const base64url$1 = base64url$5; const defaults$3 = defaultsExports; const parseWwwAuthenticate = www_authenticate_parser; const { assertSigningAlgValuesSupport, assertIssuerConfiguration } = assert$2; const pick$1 = pick$3; const isPlainObject$2 = is_plain_object; const processResponse$1 = process_response; const TokenSet$1 = token_set; const { OPError: OPError$2, RPError: RPError$3 } = errors$2; const now = unix_timestamp; const { random: random$1 } = generators$1; const request$1 = requestExports; const { CLOCK_TOLERANCE: CLOCK_TOLERANCE$1 } = consts; const { keystores } = weak_cache; const KeyStore = keystore$1; const clone$3 = deep_clone; const { authenticatedPost, resolveResponseType: resolveResponseType$1, resolveRedirectUri: resolveRedirectUri$1 } = client$1; const { queryKeyStore } = issuer$1; const DeviceFlowHandle = device_flow_handle; const [major$2, minor$2] = process.version .slice(1) .split('.') .map((str) => parseInt(str, 10)); const rsaPssParams = major$2 >= 17 || (major$2 === 16 && minor$2 >= 9); const retryAttempt = Symbol(); const skipNonceCheck = Symbol(); const skipMaxAgeCheck = Symbol(); function pickCb(input) { return pick$1( input, 'access_token', // OAuth 2.0 'code', // OAuth 2.0 'error_description', // OAuth 2.0 'error_uri', // OAuth 2.0 'error', // OAuth 2.0 'expires_in', // OAuth 2.0 'id_token', // OIDC Core 1.0 'iss', // draft-ietf-oauth-iss-auth-resp 'response', // FAPI JARM 'session_state', // OIDC Session Management 'state', // OAuth 2.0 'token_type', // OAuth 2.0 ); } function authorizationHeaderValue(token, tokenType = 'Bearer') { return `${tokenType} ${token}`; } function getSearchParams(input) { const parsed = url$2.parse(input); if (!parsed.search) return {}; return querystring.parse(parsed.search.substring(1)); } function verifyPresence(payload, jwt, prop) { if (payload[prop] === undefined) { throw new RPError$3({ message: `missing required JWT property ${prop}`, jwt, }); } } function authorizationParams(params) { const authParams = { client_id: this.client_id, scope: 'openid', response_type: resolveResponseType$1.call(this), redirect_uri: resolveRedirectUri$1.call(this), ...params, }; Object.entries(authParams).forEach(([key, value]) => { if (value === null || value === undefined) { delete authParams[key]; } else if (key === 'claims' && typeof value === 'object') { authParams[key] = JSON.stringify(value); } else if (key === 'resource' && Array.isArray(value)) { authParams[key] = value; } else if (typeof value !== 'string') { authParams[key] = String(value); } }); return authParams; } function getKeystore(jwks) { if ( !isPlainObject$2(jwks) || !Array.isArray(jwks.keys) || jwks.keys.some((k) => !isPlainObject$2(k) || !('kty' in k)) ) { throw new TypeError('jwks must be a JSON Web Key Set formatted object'); } return KeyStore.fromJWKS(jwks, { onlyPrivate: true }); } // if an OP doesnt support client_secret_basic but supports client_secret_post, use it instead // this is in place to take care of most common pitfalls when first using discovered Issuers without // the support for default values defined by Discovery 1.0 function checkBasicSupport(client, properties) { try { const supported = client.issuer.token_endpoint_auth_methods_supported; if (!supported.includes(properties.token_endpoint_auth_method)) { if (supported.includes('client_secret_post')) { properties.token_endpoint_auth_method = 'client_secret_post'; } } } catch (err) {} } function handleCommonMistakes(client, metadata, properties) { if (!metadata.token_endpoint_auth_method) { // if no explicit value was provided checkBasicSupport(client, properties); } // :fp: c'mon people... RTFM if (metadata.redirect_uri) { if (metadata.redirect_uris) { throw new TypeError('provide a redirect_uri or redirect_uris, not both'); } properties.redirect_uris = [metadata.redirect_uri]; delete properties.redirect_uri; } if (metadata.response_type) { if (metadata.response_types) { throw new TypeError('provide a response_type or response_types, not both'); } properties.response_types = [metadata.response_type]; delete properties.response_type; } } function getDefaultsForEndpoint(endpoint, issuer, properties) { if (!issuer[`${endpoint}_endpoint`]) return; const tokenEndpointAuthMethod = properties.token_endpoint_auth_method; const tokenEndpointAuthSigningAlg = properties.token_endpoint_auth_signing_alg; const eam = `${endpoint}_endpoint_auth_method`; const easa = `${endpoint}_endpoint_auth_signing_alg`; if (properties[eam] === undefined && properties[easa] === undefined) { if (tokenEndpointAuthMethod !== undefined) { properties[eam] = tokenEndpointAuthMethod; } if (tokenEndpointAuthSigningAlg !== undefined) { properties[easa] = tokenEndpointAuthSigningAlg; } } } let BaseClient$1 = class BaseClient { #metadata; #issuer; #aadIssValidation; #additionalAuthorizedParties; constructor(issuer, aadIssValidation, metadata = {}, jwks, options) { this.#metadata = new Map(); this.#issuer = issuer; this.#aadIssValidation = aadIssValidation; if (typeof metadata.client_id !== 'string' || !metadata.client_id) { throw new TypeError('client_id is required'); } const properties = { grant_types: ['authorization_code'], id_token_signed_response_alg: 'RS256', authorization_signed_response_alg: 'RS256', response_types: ['code'], token_endpoint_auth_method: 'client_secret_basic', ...(this.fapi() ? { grant_types: ['authorization_code', 'implicit'], id_token_signed_response_alg: 'PS256', authorization_signed_response_alg: 'PS256', response_types: ['code id_token'], tls_client_certificate_bound_access_tokens: true, token_endpoint_auth_method: undefined, } : undefined), ...metadata, }; if (this.fapi()) { switch (properties.token_endpoint_auth_method) { case 'self_signed_tls_client_auth': case 'tls_client_auth': break; case 'private_key_jwt': if (!jwks) { throw new TypeError('jwks is required'); } break; case undefined: throw new TypeError('token_endpoint_auth_method is required'); default: throw new TypeError('invalid or unsupported token_endpoint_auth_method'); } } handleCommonMistakes(this, metadata, properties); assertSigningAlgValuesSupport('token', this.issuer, properties); ['introspection', 'revocation'].forEach((endpoint) => { getDefaultsForEndpoint(endpoint, this.issuer, properties); assertSigningAlgValuesSupport(endpoint, this.issuer, properties); }); Object.entries(properties).forEach(([key, value]) => { this.#metadata.set(key, value); if (!this[key]) { Object.defineProperty(this, key, { get() { return this.#metadata.get(key); }, enumerable: true, }); } }); if (jwks !== undefined) { const keystore = getKeystore.call(this, jwks); keystores.set(this, keystore); } if (options != null && options.additionalAuthorizedParties) { this.#additionalAuthorizedParties = clone$3(options.additionalAuthorizedParties); } this[CLOCK_TOLERANCE$1] = 0; } authorizationUrl(params = {}) { if (!isPlainObject$2(params)) { throw new TypeError('params must be a plain object'); } assertIssuerConfiguration(this.issuer, 'authorization_endpoint'); const target = new URL$1(this.issuer.authorization_endpoint); for (const [name, value] of Object.entries(authorizationParams.call(this, params))) { if (Array.isArray(value)) { target.searchParams.delete(name); for (const member of value) { target.searchParams.append(name, member); } } else { target.searchParams.set(name, value); } } // TODO: is the replace needed? return target.href.replace(/\+/g, '%20'); } authorizationPost(params = {}) { if (!isPlainObject$2(params)) { throw new TypeError('params must be a plain object'); } const inputs = authorizationParams.call(this, params); const formInputs = Object.keys(inputs) .map((name) => ``) .join('\n'); return ` Requesting Authorization
${formInputs}
`; } endSessionUrl(params = {}) { assertIssuerConfiguration(this.issuer, 'end_session_endpoint'); const { 0: postLogout, length } = this.post_logout_redirect_uris || []; const { post_logout_redirect_uri = length === 1 ? postLogout : undefined } = params; let id_token_hint; ({ id_token_hint, ...params } = params); if (id_token_hint instanceof TokenSet$1) { if (!id_token_hint.id_token) { throw new TypeError('id_token not present in TokenSet'); } id_token_hint = id_token_hint.id_token; } const target = url$2.parse(this.issuer.end_session_endpoint); const query = defaults$3( getSearchParams(this.issuer.end_session_endpoint), params, { post_logout_redirect_uri, client_id: this.client_id, }, { id_token_hint }, ); Object.entries(query).forEach(([key, value]) => { if (value === null || value === undefined) { delete query[key]; } }); target.search = null; target.query = query; return url$2.format(target); } callbackParams(input) { const isIncomingMessage = input instanceof stdhttp.IncomingMessage || (input && input.method && input.url); const isString = typeof input === 'string'; if (!isString && !isIncomingMessage) { throw new TypeError( '#callbackParams only accepts string urls, http.IncomingMessage or a lookalike', ); } if (isIncomingMessage) { switch (input.method) { case 'GET': return pickCb(getSearchParams(input.url)); case 'POST': if (input.body === undefined) { throw new TypeError( 'incoming message body missing, include a body parser prior to this method call', ); } switch (typeof input.body) { case 'object': case 'string': if (Buffer.isBuffer(input.body)) { return pickCb(querystring.parse(input.body.toString('utf-8'))); } if (typeof input.body === 'string') { return pickCb(querystring.parse(input.body)); } return pickCb(input.body); default: throw new TypeError('invalid IncomingMessage body object'); } default: throw new TypeError('invalid IncomingMessage method'); } } else { return pickCb(getSearchParams(input)); } } async callback( redirectUri, parameters, checks = {}, { exchangeBody, clientAssertionPayload, DPoP } = {}, ) { let params = pickCb(parameters); if (checks.jarm && !('response' in parameters)) { throw new RPError$3({ message: 'expected a JARM response', checks, params, }); } else if ('response' in parameters) { const decrypted = await this.decryptJARM(params.response); params = await this.validateJARM(decrypted); } if (this.default_max_age && !checks.max_age) { checks.max_age = this.default_max_age; } if (params.state && !checks.state) { throw new TypeError('checks.state argument is missing'); } if (!params.state && checks.state) { throw new RPError$3({ message: 'state missing from the response', checks, params, }); } if (checks.state !== params.state) { throw new RPError$3({ printf: ['state mismatch, expected %s, got: %s', checks.state, params.state], checks, params, }); } if ('iss' in params) { assertIssuerConfiguration(this.issuer, 'issuer'); if (params.iss !== this.issuer.issuer) { throw new RPError$3({ printf: ['iss mismatch, expected %s, got: %s', this.issuer.issuer, params.iss], params, }); } } else if ( this.issuer.authorization_response_iss_parameter_supported && !('id_token' in params) && !('response' in parameters) ) { throw new RPError$3({ message: 'iss missing from the response', params, }); } if (params.error) { throw new OPError$2(params); } const RESPONSE_TYPE_REQUIRED_PARAMS = { code: ['code'], id_token: ['id_token'], token: ['access_token', 'token_type'], }; if (checks.response_type) { for (const type of checks.response_type.split(' ')) { if (type === 'none') { if (params.code || params.id_token || params.access_token) { throw new RPError$3({ message: 'unexpected params encountered for "none" response', checks, params, }); } } else { for (const param of RESPONSE_TYPE_REQUIRED_PARAMS[type]) { if (!params[param]) { throw new RPError$3({ message: `${param} missing from response`, checks, params, }); } } } } } if (params.id_token) { const tokenset = new TokenSet$1(params); await this.decryptIdToken(tokenset); await this.validateIdToken( tokenset, checks.nonce, 'authorization', checks.max_age, checks.state, ); if (!params.code) { return tokenset; } } if (params.code) { const tokenset = await this.grant( { ...exchangeBody, grant_type: 'authorization_code', code: params.code, redirect_uri: redirectUri, code_verifier: checks.code_verifier, }, { clientAssertionPayload, DPoP }, ); await this.decryptIdToken(tokenset); await this.validateIdToken(tokenset, checks.nonce, 'token', checks.max_age); if (params.session_state) { tokenset.session_state = params.session_state; } return tokenset; } return new TokenSet$1(params); } async oauthCallback( redirectUri, parameters, checks = {}, { exchangeBody, clientAssertionPayload, DPoP } = {}, ) { let params = pickCb(parameters); if (checks.jarm && !('response' in parameters)) { throw new RPError$3({ message: 'expected a JARM response', checks, params, }); } else if ('response' in parameters) { const decrypted = await this.decryptJARM(params.response); params = await this.validateJARM(decrypted); } if (params.state && !checks.state) { throw new TypeError('checks.state argument is missing'); } if (!params.state && checks.state) { throw new RPError$3({ message: 'state missing from the response', checks, params, }); } if (checks.state !== params.state) { throw new RPError$3({ printf: ['state mismatch, expected %s, got: %s', checks.state, params.state], checks, params, }); } if ('iss' in params) { assertIssuerConfiguration(this.issuer, 'issuer'); if (params.iss !== this.issuer.issuer) { throw new RPError$3({ printf: ['iss mismatch, expected %s, got: %s', this.issuer.issuer, params.iss], params, }); } } else if ( this.issuer.authorization_response_iss_parameter_supported && !('id_token' in params) && !('response' in parameters) ) { throw new RPError$3({ message: 'iss missing from the response', params, }); } if (params.error) { throw new OPError$2(params); } if (typeof params.id_token === 'string' && params.id_token.length) { throw new RPError$3({ message: 'id_token detected in the response, you must use client.callback() instead of client.oauthCallback()', params, }); } delete params.id_token; const RESPONSE_TYPE_REQUIRED_PARAMS = { code: ['code'], token: ['access_token', 'token_type'], }; if (checks.response_type) { for (const type of checks.response_type.split(' ')) { if (type === 'none') { if (params.code || params.id_token || params.access_token) { throw new RPError$3({ message: 'unexpected params encountered for "none" response', checks, params, }); } } if (RESPONSE_TYPE_REQUIRED_PARAMS[type]) { for (const param of RESPONSE_TYPE_REQUIRED_PARAMS[type]) { if (!params[param]) { throw new RPError$3({ message: `${param} missing from response`, checks, params, }); } } } } } if (params.code) { const tokenset = await this.grant( { ...exchangeBody, grant_type: 'authorization_code', code: params.code, redirect_uri: redirectUri, code_verifier: checks.code_verifier, }, { clientAssertionPayload, DPoP }, ); if (typeof tokenset.id_token === 'string' && tokenset.id_token.length) { throw new RPError$3({ message: 'id_token detected in the response, you must use client.callback() instead of client.oauthCallback()', params, }); } delete tokenset.id_token; return tokenset; } return new TokenSet$1(params); } async decryptIdToken(token) { if (!this.id_token_encrypted_response_alg) { return token; } let idToken = token; if (idToken instanceof TokenSet$1) { if (!idToken.id_token) { throw new TypeError('id_token not present in TokenSet'); } idToken = idToken.id_token; } const expectedAlg = this.id_token_encrypted_response_alg; const expectedEnc = this.id_token_encrypted_response_enc; const result = await this.decryptJWE(idToken, expectedAlg, expectedEnc); if (token instanceof TokenSet$1) { token.id_token = result; return token; } return result; } async validateJWTUserinfo(body) { const expectedAlg = this.userinfo_signed_response_alg; return this.validateJWT(body, expectedAlg, []); } async decryptJARM(response) { if (!this.authorization_encrypted_response_alg) { return response; } const expectedAlg = this.authorization_encrypted_response_alg; const expectedEnc = this.authorization_encrypted_response_enc; return this.decryptJWE(response, expectedAlg, expectedEnc); } async decryptJWTUserinfo(body) { if (!this.userinfo_encrypted_response_alg) { return body; } const expectedAlg = this.userinfo_encrypted_response_alg; const expectedEnc = this.userinfo_encrypted_response_enc; return this.decryptJWE(body, expectedAlg, expectedEnc); } async decryptJWE(jwe, expectedAlg, expectedEnc = 'A128CBC-HS256') { const header = JSON.parse(base64url$1.decode(jwe.split('.')[0])); if (header.alg !== expectedAlg) { throw new RPError$3({ printf: ['unexpected JWE alg received, expected %s, got: %s', expectedAlg, header.alg], jwt: jwe, }); } if (header.enc !== expectedEnc) { throw new RPError$3({ printf: ['unexpected JWE enc received, expected %s, got: %s', expectedEnc, header.enc], jwt: jwe, }); } const getPlaintext = (result) => new TextDecoder().decode(result.plaintext); let plaintext; if (expectedAlg.match(/^(?:RSA|ECDH)/)) { const keystore = await keystores.get(this); const protectedHeader = jose.decodeProtectedHeader(jwe); for (const key of keystore.all({ ...protectedHeader, use: 'enc', })) { plaintext = await jose .compactDecrypt(jwe, await key.keyObject(protectedHeader.alg)) .then(getPlaintext, () => {}); if (plaintext) break; } } else { plaintext = await jose .compactDecrypt(jwe, this.secretForAlg(expectedAlg === 'dir' ? expectedEnc : expectedAlg)) .then(getPlaintext, () => {}); } if (!plaintext) { throw new RPError$3({ message: 'failed to decrypt JWE', jwt: jwe, }); } return plaintext; } async validateIdToken(tokenSet, nonce, returnedBy, maxAge, state) { let idToken = tokenSet; const expectedAlg = this.id_token_signed_response_alg; const isTokenSet = idToken instanceof TokenSet$1; if (isTokenSet) { if (!idToken.id_token) { throw new TypeError('id_token not present in TokenSet'); } idToken = idToken.id_token; } idToken = String(idToken); const timestamp = now(); const { protected: header, payload, key } = await this.validateJWT(idToken, expectedAlg); if (typeof maxAge === 'number' || (maxAge !== skipMaxAgeCheck && this.require_auth_time)) { if (!payload.auth_time) { throw new RPError$3({ message: 'missing required JWT property auth_time', jwt: idToken, }); } if (typeof payload.auth_time !== 'number') { throw new RPError$3({ message: 'JWT auth_time claim must be a JSON numeric value', jwt: idToken, }); } } if ( typeof maxAge === 'number' && payload.auth_time + maxAge < timestamp - this[CLOCK_TOLERANCE$1] ) { throw new RPError$3({ printf: [ 'too much time has elapsed since the last End-User authentication, max_age %i, auth_time: %i, now %i', maxAge, payload.auth_time, timestamp - this[CLOCK_TOLERANCE$1], ], now: timestamp, tolerance: this[CLOCK_TOLERANCE$1], auth_time: payload.auth_time, jwt: idToken, }); } if ( nonce !== skipNonceCheck && (payload.nonce || nonce !== undefined) && payload.nonce !== nonce ) { throw new RPError$3({ printf: ['nonce mismatch, expected %s, got: %s', nonce, payload.nonce], jwt: idToken, }); } if (returnedBy === 'authorization') { if (!payload.at_hash && tokenSet.access_token) { throw new RPError$3({ message: 'missing required property at_hash', jwt: idToken, }); } if (!payload.c_hash && tokenSet.code) { throw new RPError$3({ message: 'missing required property c_hash', jwt: idToken, }); } if (this.fapi()) { if (!payload.s_hash && (tokenSet.state || state)) { throw new RPError$3({ message: 'missing required property s_hash', jwt: idToken, }); } } if (payload.s_hash) { if (!state) { throw new TypeError('cannot verify s_hash, "checks.state" property not provided'); } try { tokenHash.validate( { claim: 's_hash', source: 'state' }, payload.s_hash, state, header.alg, key.jwk && key.jwk.crv, ); } catch (err) { throw new RPError$3({ message: err.message, jwt: idToken }); } } } if (this.fapi() && payload.iat < timestamp - 3600) { throw new RPError$3({ printf: ['JWT issued too far in the past, now %i, iat %i', timestamp, payload.iat], now: timestamp, tolerance: this[CLOCK_TOLERANCE$1], iat: payload.iat, jwt: idToken, }); } if (tokenSet.access_token && payload.at_hash !== undefined) { try { tokenHash.validate( { claim: 'at_hash', source: 'access_token' }, payload.at_hash, tokenSet.access_token, header.alg, key.jwk && key.jwk.crv, ); } catch (err) { throw new RPError$3({ message: err.message, jwt: idToken }); } } if (tokenSet.code && payload.c_hash !== undefined) { try { tokenHash.validate( { claim: 'c_hash', source: 'code' }, payload.c_hash, tokenSet.code, header.alg, key.jwk && key.jwk.crv, ); } catch (err) { throw new RPError$3({ message: err.message, jwt: idToken }); } } return tokenSet; } async validateJWT(jwt, expectedAlg, required = ['iss', 'sub', 'aud', 'exp', 'iat']) { const isSelfIssued = this.issuer.issuer === 'https://self-issued.me'; const timestamp = now(); let header; let payload; try { ({ header, payload } = decodeJWT(jwt, { complete: true })); } catch (err) { throw new RPError$3({ printf: ['failed to decode JWT (%s: %s)', err.name, err.message], jwt, }); } if (header.alg !== expectedAlg) { throw new RPError$3({ printf: ['unexpected JWT alg received, expected %s, got: %s', expectedAlg, header.alg], jwt, }); } if (isSelfIssued) { required = [...required, 'sub_jwk']; } required.forEach(verifyPresence.bind(undefined, payload, jwt)); if (payload.iss !== undefined) { let expectedIss = this.issuer.issuer; if (this.#aadIssValidation) { expectedIss = this.issuer.issuer.replace('{tenantid}', payload.tid); } if (payload.iss !== expectedIss) { throw new RPError$3({ printf: ['unexpected iss value, expected %s, got: %s', expectedIss, payload.iss], jwt, }); } } if (payload.iat !== undefined) { if (typeof payload.iat !== 'number') { throw new RPError$3({ message: 'JWT iat claim must be a JSON numeric value', jwt, }); } } if (payload.nbf !== undefined) { if (typeof payload.nbf !== 'number') { throw new RPError$3({ message: 'JWT nbf claim must be a JSON numeric value', jwt, }); } if (payload.nbf > timestamp + this[CLOCK_TOLERANCE$1]) { throw new RPError$3({ printf: [ 'JWT not active yet, now %i, nbf %i', timestamp + this[CLOCK_TOLERANCE$1], payload.nbf, ], now: timestamp, tolerance: this[CLOCK_TOLERANCE$1], nbf: payload.nbf, jwt, }); } } if (payload.exp !== undefined) { if (typeof payload.exp !== 'number') { throw new RPError$3({ message: 'JWT exp claim must be a JSON numeric value', jwt, }); } if (timestamp - this[CLOCK_TOLERANCE$1] >= payload.exp) { throw new RPError$3({ printf: ['JWT expired, now %i, exp %i', timestamp - this[CLOCK_TOLERANCE$1], payload.exp], now: timestamp, tolerance: this[CLOCK_TOLERANCE$1], exp: payload.exp, jwt, }); } } if (payload.aud !== undefined) { if (Array.isArray(payload.aud)) { if (payload.aud.length > 1 && !payload.azp) { throw new RPError$3({ message: 'missing required JWT property azp', jwt, }); } if (!payload.aud.includes(this.client_id)) { throw new RPError$3({ printf: [ 'aud is missing the client_id, expected %s to be included in %j', this.client_id, payload.aud, ], jwt, }); } } else if (payload.aud !== this.client_id) { throw new RPError$3({ printf: ['aud mismatch, expected %s, got: %s', this.client_id, payload.aud], jwt, }); } } if (payload.azp !== undefined) { let additionalAuthorizedParties = this.#additionalAuthorizedParties; if (typeof additionalAuthorizedParties === 'string') { additionalAuthorizedParties = [this.client_id, additionalAuthorizedParties]; } else if (Array.isArray(additionalAuthorizedParties)) { additionalAuthorizedParties = [this.client_id, ...additionalAuthorizedParties]; } else { additionalAuthorizedParties = [this.client_id]; } if (!additionalAuthorizedParties.includes(payload.azp)) { throw new RPError$3({ printf: ['azp mismatch, got: %s', payload.azp], jwt, }); } } let keys; if (isSelfIssued) { try { assert(isPlainObject$2(payload.sub_jwk)); const key = await jose.importJWK(payload.sub_jwk, header.alg); assert.equal(key.type, 'public'); keys = [ { keyObject() { return key; }, }, ]; } catch (err) { throw new RPError$3({ message: 'failed to use sub_jwk claim as an asymmetric JSON Web Key', jwt, }); } if ((await jose.calculateJwkThumbprint(payload.sub_jwk)) !== payload.sub) { throw new RPError$3({ message: 'failed to match the subject with sub_jwk', jwt, }); } } else if (header.alg.startsWith('HS')) { keys = [this.secretForAlg(header.alg)]; } else if (header.alg !== 'none') { keys = await queryKeyStore.call(this.issuer, { ...header, use: 'sig' }); } if (!keys && header.alg === 'none') { return { protected: header, payload }; } for (const key of keys) { const verified = await jose .compactVerify(jwt, key instanceof Uint8Array ? key : await key.keyObject(header.alg)) .catch(() => {}); if (verified) { return { payload, protected: verified.protectedHeader, key, }; } } throw new RPError$3({ message: 'failed to validate JWT signature', jwt, }); } async refresh(refreshToken, { exchangeBody, clientAssertionPayload, DPoP } = {}) { let token = refreshToken; if (token instanceof TokenSet$1) { if (!token.refresh_token) { throw new TypeError('refresh_token not present in TokenSet'); } token = token.refresh_token; } const tokenset = await this.grant( { ...exchangeBody, grant_type: 'refresh_token', refresh_token: String(token), }, { clientAssertionPayload, DPoP }, ); if (tokenset.id_token) { await this.decryptIdToken(tokenset); await this.validateIdToken(tokenset, skipNonceCheck, 'token', skipMaxAgeCheck); if (refreshToken instanceof TokenSet$1 && refreshToken.id_token) { const expectedSub = refreshToken.claims().sub; const actualSub = tokenset.claims().sub; if (actualSub !== expectedSub) { throw new RPError$3({ printf: ['sub mismatch, expected %s, got: %s', expectedSub, actualSub], jwt: tokenset.id_token, }); } } } return tokenset; } async requestResource( resourceUrl, accessToken, { method, headers, body, DPoP, tokenType = DPoP ? 'DPoP' : accessToken instanceof TokenSet$1 ? accessToken.token_type : 'Bearer', } = {}, retry, ) { if (accessToken instanceof TokenSet$1) { if (!accessToken.access_token) { throw new TypeError('access_token not present in TokenSet'); } accessToken = accessToken.access_token; } if (!accessToken) { throw new TypeError('no access token provided'); } else if (typeof accessToken !== 'string') { throw new TypeError('invalid access token provided'); } const requestOpts = { headers: { Authorization: authorizationHeaderValue(accessToken, tokenType), ...headers, }, body, }; const mTLS = !!this.tls_client_certificate_bound_access_tokens; const response = await request$1.call( this, { ...requestOpts, responseType: 'buffer', method, url: resourceUrl, }, { accessToken, mTLS, DPoP }, ); const wwwAuthenticate = response.headers['www-authenticate']; if ( retry !== retryAttempt && wwwAuthenticate && wwwAuthenticate.toLowerCase().startsWith('dpop ') && parseWwwAuthenticate(wwwAuthenticate).error === 'use_dpop_nonce' ) { return this.requestResource(resourceUrl, accessToken, { method, headers, body, DPoP, tokenType, }); } return response; } async userinfo(accessToken, { method = 'GET', via = 'header', tokenType, params, DPoP } = {}) { assertIssuerConfiguration(this.issuer, 'userinfo_endpoint'); const options = { tokenType, method: String(method).toUpperCase(), DPoP, }; if (options.method !== 'GET' && options.method !== 'POST') { throw new TypeError('#userinfo() method can only be POST or a GET'); } if (via === 'body' && options.method !== 'POST') { throw new TypeError('can only send body on POST'); } const jwt = !!(this.userinfo_signed_response_alg || this.userinfo_encrypted_response_alg); if (jwt) { options.headers = { Accept: 'application/jwt' }; } else { options.headers = { Accept: 'application/json' }; } const mTLS = !!this.tls_client_certificate_bound_access_tokens; let targetUrl; if (mTLS && this.issuer.mtls_endpoint_aliases) { targetUrl = this.issuer.mtls_endpoint_aliases.userinfo_endpoint; } targetUrl = new URL$1(targetUrl || this.issuer.userinfo_endpoint); if (via === 'body') { options.headers.Authorization = undefined; options.headers['Content-Type'] = 'application/x-www-form-urlencoded'; options.body = new URLSearchParams(); options.body.append( 'access_token', accessToken instanceof TokenSet$1 ? accessToken.access_token : accessToken, ); } // handle additional parameters, GET via querystring, POST via urlencoded body if (params) { if (options.method === 'GET') { Object.entries(params).forEach(([key, value]) => { targetUrl.searchParams.append(key, value); }); } else if (options.body) { // POST && via body Object.entries(params).forEach(([key, value]) => { options.body.append(key, value); }); } else { // POST && via header options.body = new URLSearchParams(); options.headers['Content-Type'] = 'application/x-www-form-urlencoded'; Object.entries(params).forEach(([key, value]) => { options.body.append(key, value); }); } } if (options.body) { options.body = options.body.toString(); } const response = await this.requestResource(targetUrl, accessToken, options); let parsed = processResponse$1(response, { bearer: true }); if (jwt) { if (!/^application\/jwt/.test(response.headers['content-type'])) { throw new RPError$3({ message: 'expected application/jwt response from the userinfo_endpoint', response, }); } const body = response.body.toString(); const userinfo = await this.decryptJWTUserinfo(body); if (!this.userinfo_signed_response_alg) { try { parsed = JSON.parse(userinfo); assert(isPlainObject$2(parsed)); } catch (err) { throw new RPError$3({ message: 'failed to parse userinfo JWE payload as JSON', jwt: userinfo, }); } } else { ({ payload: parsed } = await this.validateJWTUserinfo(userinfo)); } } else { try { parsed = JSON.parse(response.body); } catch (err) { Object.defineProperty(err, 'response', { value: response }); throw err; } } if (accessToken instanceof TokenSet$1 && accessToken.id_token) { const expectedSub = accessToken.claims().sub; if (parsed.sub !== expectedSub) { throw new RPError$3({ printf: ['userinfo sub mismatch, expected %s, got: %s', expectedSub, parsed.sub], body: parsed, jwt: accessToken.id_token, }); } } return parsed; } encryptionSecret(len) { const hash = len <= 256 ? 'sha256' : len <= 384 ? 'sha384' : len <= 512 ? 'sha512' : false; if (!hash) { throw new Error('unsupported symmetric encryption key derivation'); } return crypto$2 .createHash(hash) .update(this.client_secret) .digest() .slice(0, len / 8); } secretForAlg(alg) { if (!this.client_secret) { throw new TypeError('client_secret is required'); } if (/^A(\d{3})(?:GCM)?KW$/.test(alg)) { return this.encryptionSecret(parseInt(RegExp.$1, 10)); } if (/^A(\d{3})(?:GCM|CBC-HS(\d{3}))$/.test(alg)) { return this.encryptionSecret(parseInt(RegExp.$2 || RegExp.$1, 10)); } return new TextEncoder().encode(this.client_secret); } async grant(body, { clientAssertionPayload, DPoP } = {}, retry) { assertIssuerConfiguration(this.issuer, 'token_endpoint'); const response = await authenticatedPost.call( this, 'token', { form: body, responseType: 'json', }, { clientAssertionPayload, DPoP }, ); let responseBody; try { responseBody = processResponse$1(response); } catch (err) { if (retry !== retryAttempt && err instanceof OPError$2 && err.error === 'use_dpop_nonce') { return this.grant(body, { clientAssertionPayload, DPoP }, retryAttempt); } throw err; } return new TokenSet$1(responseBody); } async deviceAuthorization(params = {}, { exchangeBody, clientAssertionPayload, DPoP } = {}) { assertIssuerConfiguration(this.issuer, 'device_authorization_endpoint'); assertIssuerConfiguration(this.issuer, 'token_endpoint'); const body = authorizationParams.call(this, { client_id: this.client_id, redirect_uri: null, response_type: null, ...params, }); const response = await authenticatedPost.call( this, 'device_authorization', { responseType: 'json', form: body, }, { clientAssertionPayload, endpointAuthMethod: 'token' }, ); const responseBody = processResponse$1(response); return new DeviceFlowHandle({ client: this, exchangeBody, clientAssertionPayload, response: responseBody, maxAge: params.max_age, DPoP, }); } async revoke(token, hint, { revokeBody, clientAssertionPayload } = {}) { assertIssuerConfiguration(this.issuer, 'revocation_endpoint'); if (hint !== undefined && typeof hint !== 'string') { throw new TypeError('hint must be a string'); } const form = { ...revokeBody, token }; if (hint) { form.token_type_hint = hint; } const response = await authenticatedPost.call( this, 'revocation', { form, }, { clientAssertionPayload }, ); processResponse$1(response, { body: false }); } async introspect(token, hint, { introspectBody, clientAssertionPayload } = {}) { assertIssuerConfiguration(this.issuer, 'introspection_endpoint'); if (hint !== undefined && typeof hint !== 'string') { throw new TypeError('hint must be a string'); } const form = { ...introspectBody, token }; if (hint) { form.token_type_hint = hint; } const response = await authenticatedPost.call( this, 'introspection', { form, responseType: 'json' }, { clientAssertionPayload }, ); const responseBody = processResponse$1(response); return responseBody; } static async register(metadata, options = {}) { const { initialAccessToken, jwks, ...clientOptions } = options; assertIssuerConfiguration(this.issuer, 'registration_endpoint'); if (jwks !== undefined && !(metadata.jwks || metadata.jwks_uri)) { const keystore = await getKeystore.call(this, jwks); metadata.jwks = keystore.toJWKS(); } const response = await request$1.call(this, { headers: { Accept: 'application/json', ...(initialAccessToken ? { Authorization: authorizationHeaderValue(initialAccessToken), } : undefined), }, responseType: 'json', json: metadata, url: this.issuer.registration_endpoint, method: 'POST', }); const responseBody = processResponse$1(response, { statusCode: 201, bearer: true }); return new this(responseBody, jwks, clientOptions); } get metadata() { return clone$3(Object.fromEntries(this.#metadata.entries())); } static async fromUri(registrationClientUri, registrationAccessToken, jwks, clientOptions) { const response = await request$1.call(this, { method: 'GET', url: registrationClientUri, responseType: 'json', headers: { Authorization: authorizationHeaderValue(registrationAccessToken), Accept: 'application/json', }, }); const responseBody = processResponse$1(response, { bearer: true }); return new this(responseBody, jwks, clientOptions); } async requestObject( requestObject = {}, { sign: signingAlgorithm = this.request_object_signing_alg || 'none', encrypt: { alg: eKeyManagement = this.request_object_encryption_alg, enc: eContentEncryption = this.request_object_encryption_enc || 'A128CBC-HS256', } = {}, } = {}, ) { if (!isPlainObject$2(requestObject)) { throw new TypeError('requestObject must be a plain object'); } let signed; let key; const unix = now(); const header = { alg: signingAlgorithm, typ: 'oauth-authz-req+jwt' }; const payload = JSON.stringify( defaults$3({}, requestObject, { iss: this.client_id, aud: this.issuer.issuer, client_id: this.client_id, jti: random$1(), iat: unix, exp: unix + 300, ...(this.fapi() ? { nbf: unix } : undefined), }), ); if (signingAlgorithm === 'none') { signed = [base64url$1.encode(JSON.stringify(header)), base64url$1.encode(payload), ''].join('.'); } else { const symmetric = signingAlgorithm.startsWith('HS'); if (symmetric) { key = this.secretForAlg(signingAlgorithm); } else { const keystore = await keystores.get(this); if (!keystore) { throw new TypeError( `no keystore present for client, cannot sign using alg ${signingAlgorithm}`, ); } key = keystore.get({ alg: signingAlgorithm, use: 'sig' }); if (!key) { throw new TypeError(`no key to sign with found for alg ${signingAlgorithm}`); } } signed = await new jose.CompactSign(new TextEncoder().encode(payload)) .setProtectedHeader({ ...header, kid: symmetric ? undefined : key.jwk.kid, }) .sign(symmetric ? key : await key.keyObject(signingAlgorithm)); } if (!eKeyManagement) { return signed; } const fields = { alg: eKeyManagement, enc: eContentEncryption, cty: 'oauth-authz-req+jwt' }; if (fields.alg.match(/^(RSA|ECDH)/)) { [key] = await queryKeyStore.call( this.issuer, { alg: fields.alg, use: 'enc' }, { allowMulti: true }, ); } else { key = this.secretForAlg(fields.alg === 'dir' ? fields.enc : fields.alg); } return new jose.CompactEncrypt(new TextEncoder().encode(signed)) .setProtectedHeader({ ...fields, kid: key instanceof Uint8Array ? undefined : key.jwk.kid, }) .encrypt(key instanceof Uint8Array ? key : await key.keyObject(fields.alg)); } async pushedAuthorizationRequest(params = {}, { clientAssertionPayload } = {}) { assertIssuerConfiguration(this.issuer, 'pushed_authorization_request_endpoint'); const body = { ...('request' in params ? params : authorizationParams.call(this, params)), client_id: this.client_id, }; const response = await authenticatedPost.call( this, 'pushed_authorization_request', { responseType: 'json', form: body, }, { clientAssertionPayload, endpointAuthMethod: 'token' }, ); const responseBody = processResponse$1(response, { statusCode: 201 }); if (!('expires_in' in responseBody)) { throw new RPError$3({ message: 'expected expires_in in Pushed Authorization Successful Response', response, }); } if (typeof responseBody.expires_in !== 'number') { throw new RPError$3({ message: 'invalid expires_in value in Pushed Authorization Successful Response', response, }); } if (!('request_uri' in responseBody)) { throw new RPError$3({ message: 'expected request_uri in Pushed Authorization Successful Response', response, }); } if (typeof responseBody.request_uri !== 'string') { throw new RPError$3({ message: 'invalid request_uri value in Pushed Authorization Successful Response', response, }); } return responseBody; } get issuer() { return this.#issuer; } /* istanbul ignore next */ [inspect$1.custom]() { return `${this.constructor.name} ${inspect$1(this.metadata, { depth: Infinity, colors: process.stdout.isTTY, compact: false, sorted: true, })}`; } fapi() { return this.constructor.name === 'FAPI1Client'; } async validateJARM(response) { const expectedAlg = this.authorization_signed_response_alg; const { payload } = await this.validateJWT(response, expectedAlg, ['iss', 'exp', 'aud']); return pickCb(payload); } /** * @name dpopProof * @api private */ async dpopProof(payload, privateKeyInput, accessToken) { if (!isPlainObject$2(payload)) { throw new TypeError('payload must be a plain object'); } let privateKey; if (isKeyObject(privateKeyInput)) { privateKey = privateKeyInput; } else if (privateKeyInput[Symbol.toStringTag] === 'CryptoKey') { privateKey = privateKeyInput; } else if (jose.cryptoRuntime === 'node:crypto') { privateKey = crypto$2.createPrivateKey(privateKeyInput); } else { throw new TypeError('unrecognized crypto runtime'); } if (privateKey.type !== 'private') { throw new TypeError('"DPoP" option must be a private key'); } let alg = determineDPoPAlgorithm.call(this, privateKey, privateKeyInput); if (!alg) { throw new TypeError('could not determine DPoP JWS Algorithm'); } return new jose.SignJWT({ ath: accessToken ? base64url$1.encode(crypto$2.createHash('sha256').update(accessToken).digest()) : undefined, ...payload, }) .setProtectedHeader({ alg, typ: 'dpop+jwt', jwk: await getJwk(privateKey, privateKeyInput), }) .setIssuedAt() .setJti(random$1()) .sign(privateKey); } }; function determineDPoPAlgorithmFromCryptoKey(cryptoKey) { switch (cryptoKey.algorithm.name) { case 'Ed25519': case 'Ed448': return 'EdDSA'; case 'ECDSA': { switch (cryptoKey.algorithm.namedCurve) { case 'P-256': return 'ES256'; case 'P-384': return 'ES384'; case 'P-521': return 'ES512'; } break; } case 'RSASSA-PKCS1-v1_5': return `RS${cryptoKey.algorithm.hash.name.slice(4)}`; case 'RSA-PSS': return `PS${cryptoKey.algorithm.hash.name.slice(4)}`; default: throw new TypeError('unsupported DPoP private key'); } } let determineDPoPAlgorithm; if (jose.cryptoRuntime === 'node:crypto') { determineDPoPAlgorithm = function (privateKey, privateKeyInput) { if (privateKeyInput[Symbol.toStringTag] === 'CryptoKey') { return determineDPoPAlgorithmFromCryptoKey(privateKey); } switch (privateKey.asymmetricKeyType) { case 'ed25519': case 'ed448': return 'EdDSA'; case 'ec': return determineEcAlgorithm(privateKey, privateKeyInput); case 'rsa': case rsaPssParams && 'rsa-pss': return determineRsaAlgorithm( privateKey, privateKeyInput, this.issuer.dpop_signing_alg_values_supported, ); default: throw new TypeError('unsupported DPoP private key'); } }; const RSPS = /^(?:RS|PS)(?:256|384|512)$/; function determineRsaAlgorithm(privateKey, privateKeyInput, valuesSupported) { if ( typeof privateKeyInput === 'object' && privateKeyInput.format === 'jwk' && privateKeyInput.key && privateKeyInput.key.alg ) { return privateKeyInput.key.alg; } if (Array.isArray(valuesSupported)) { let candidates = valuesSupported.filter(RegExp.prototype.test.bind(RSPS)); if (privateKey.asymmetricKeyType === 'rsa-pss') { candidates = candidates.filter((value) => value.startsWith('PS')); } return ['PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS384'].find((preferred) => candidates.includes(preferred), ); } return 'PS256'; } const p256 = Buffer.from([42, 134, 72, 206, 61, 3, 1, 7]); const p384 = Buffer.from([43, 129, 4, 0, 34]); const p521 = Buffer.from([43, 129, 4, 0, 35]); const secp256k1 = Buffer.from([43, 129, 4, 0, 10]); function determineEcAlgorithm(privateKey, privateKeyInput) { // If input was a JWK switch ( typeof privateKeyInput === 'object' && typeof privateKeyInput.key === 'object' && privateKeyInput.key.crv ) { case 'P-256': return 'ES256'; case 'secp256k1': return 'ES256K'; case 'P-384': return 'ES384'; case 'P-512': return 'ES512'; } const buf = privateKey.export({ format: 'der', type: 'pkcs8' }); const i = buf[1] < 128 ? 17 : 18; const len = buf[i]; const curveOid = buf.slice(i + 1, i + 1 + len); if (curveOid.equals(p256)) { return 'ES256'; } if (curveOid.equals(p384)) { return 'ES384'; } if (curveOid.equals(p521)) { return 'ES512'; } if (curveOid.equals(secp256k1)) { return 'ES256K'; } throw new TypeError('unsupported DPoP private key curve'); } } else { determineDPoPAlgorithm = determineDPoPAlgorithmFromCryptoKey; } const jwkCache = new WeakMap(); async function getJwk(keyObject, privateKeyInput) { if ( jose.cryptoRuntime === 'node:crypto' && typeof privateKeyInput === 'object' && typeof privateKeyInput.key === 'object' && privateKeyInput.format === 'jwk' ) { return pick$1(privateKeyInput.key, 'kty', 'crv', 'x', 'y', 'e', 'n'); } if (jwkCache.has(privateKeyInput)) { return jwkCache.get(privateKeyInput); } const jwk = pick$1(await jose.exportJWK(keyObject), 'kty', 'crv', 'x', 'y', 'e', 'n'); if (isKeyObject(privateKeyInput) || jose.cryptoRuntime === 'WebCryptoAPI') { jwkCache.set(privateKeyInput, jwk); } return jwk; } client$2.exports = (issuer, aadIssValidation = false) => class Client extends BaseClient$1 { constructor(...args) { super(issuer, aadIssValidation, ...args); } static get issuer() { return issuer; } }; client$2.exports.BaseClient = BaseClient$1; var clientExports = client$2.exports; const LRU = lruCache; var issuer_registry = new LRU({ max: 100 }); // Credit: https://github.com/rohe/pyoidc/blob/master/src/oic/utils/webfinger.py // -- Normalization -- // A string of any other type is interpreted as a URI either the form of scheme // "://" authority path-abempty [ "?" query ] [ "#" fragment ] or authority // path-abempty [ "?" query ] [ "#" fragment ] per RFC 3986 [RFC3986] and is // normalized according to the following rules: // // If the user input Identifier does not have an RFC 3986 [RFC3986] scheme // portion, the string is interpreted as [userinfo "@"] host [":" port] // path-abempty [ "?" query ] [ "#" fragment ] per RFC 3986 [RFC3986]. // If the userinfo component is present and all of the path component, query // component, and port component are empty, the acct scheme is assumed. In this // case, the normalized URI is formed by prefixing acct: to the string as the // scheme. Per the 'acct' URI Scheme [I‑D.ietf‑appsawg‑acct‑uri], if there is an // at-sign character ('@') in the userinfo component, it needs to be // percent-encoded as described in RFC 3986 [RFC3986]. // For all other inputs without a scheme portion, the https scheme is assumed, // and the normalized URI is formed by prefixing https:// to the string as the // scheme. // If the resulting URI contains a fragment portion, it MUST be stripped off // together with the fragment delimiter character "#". // The WebFinger [I‑D.ietf‑appsawg‑webfinger] Resource in this case is the // resulting URI, and the WebFinger Host is the authority component. // // Note: Since the definition of authority in RFC 3986 [RFC3986] is // [ userinfo "@" ] host [ ":" port ], it is legal to have a user input // identifier like userinfo@host:port, e.g., alice@example.com:8080. const PORT = /^\d+$/; function hasScheme(input) { if (input.includes('://')) return true; const authority = input.replace(/(\/|\?)/g, '#').split('#')[0]; if (authority.includes(':')) { const index = authority.indexOf(':'); const hostOrPort = authority.slice(index + 1); if (!PORT.test(hostOrPort)) { return true; } } return false; } function acctSchemeAssumed(input) { if (!input.includes('@')) return false; const parts = input.split('@'); const host = parts[parts.length - 1]; return !(host.includes(':') || host.includes('/') || host.includes('?')); } function normalize(input) { if (typeof input !== 'string') { throw new TypeError('input must be a string'); } let output; if (hasScheme(input)) { output = input; } else if (acctSchemeAssumed(input)) { output = `acct:${input}`; } else { output = `https://${input}`; } return output.split('#')[0]; } var webfinger_normalize = normalize; const { inspect } = require$$1; const url$1 = require$$0$1; const { RPError: RPError$2 } = errors$2; const getClient = clientExports; const registry = issuer_registry; const processResponse = process_response; const webfingerNormalize = webfinger_normalize; const request = requestExports; const clone$2 = deep_clone; const { keystore } = issuer$1; const AAD_MULTITENANT_DISCOVERY = [ 'https://login.microsoftonline.com/common/.well-known/openid-configuration', 'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration', 'https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration', 'https://login.microsoftonline.com/consumers/v2.0/.well-known/openid-configuration', ]; const AAD_MULTITENANT = Symbol(); const ISSUER_DEFAULTS = { claim_types_supported: ['normal'], claims_parameter_supported: false, grant_types_supported: ['authorization_code', 'implicit'], request_parameter_supported: false, request_uri_parameter_supported: true, require_request_uri_registration: false, response_modes_supported: ['query', 'fragment'], token_endpoint_auth_methods_supported: ['client_secret_basic'], }; let Issuer$2 = class Issuer { #metadata; constructor(meta = {}) { const aadIssValidation = meta[AAD_MULTITENANT]; delete meta[AAD_MULTITENANT]; ['introspection', 'revocation'].forEach((endpoint) => { // if intro/revocation endpoint auth specific meta is missing use the token ones if they // are defined if ( meta[`${endpoint}_endpoint`] && meta[`${endpoint}_endpoint_auth_methods_supported`] === undefined && meta[`${endpoint}_endpoint_auth_signing_alg_values_supported`] === undefined ) { if (meta.token_endpoint_auth_methods_supported) { meta[`${endpoint}_endpoint_auth_methods_supported`] = meta.token_endpoint_auth_methods_supported; } if (meta.token_endpoint_auth_signing_alg_values_supported) { meta[`${endpoint}_endpoint_auth_signing_alg_values_supported`] = meta.token_endpoint_auth_signing_alg_values_supported; } } }); this.#metadata = new Map(); Object.entries(meta).forEach(([key, value]) => { this.#metadata.set(key, value); if (!this[key]) { Object.defineProperty(this, key, { get() { return this.#metadata.get(key); }, enumerable: true, }); } }); registry.set(this.issuer, this); const Client = getClient(this, aadIssValidation); Object.defineProperties(this, { Client: { value: Client, enumerable: true }, FAPI1Client: { value: class FAPI1Client extends Client {}, enumerable: true }, }); } get metadata() { return clone$2(Object.fromEntries(this.#metadata.entries())); } static async webfinger(input) { const resource = webfingerNormalize(input); const { host } = url$1.parse(resource); const webfingerUrl = `https://${host}/.well-known/webfinger`; const response = await request.call(this, { method: 'GET', url: webfingerUrl, responseType: 'json', searchParams: { resource, rel: 'http://openid.net/specs/connect/1.0/issuer' }, headers: { Accept: 'application/json', }, }); const body = processResponse(response); const location = Array.isArray(body.links) && body.links.find( (link) => typeof link === 'object' && link.rel === 'http://openid.net/specs/connect/1.0/issuer' && link.href, ); if (!location) { throw new RPError$2({ message: 'no issuer found in webfinger response', body, }); } if (typeof location.href !== 'string' || !location.href.startsWith('https://')) { throw new RPError$2({ printf: ['invalid issuer location %s', location.href], body, }); } const expectedIssuer = location.href; if (registry.has(expectedIssuer)) { return registry.get(expectedIssuer); } const issuer = await this.discover(expectedIssuer); if (issuer.issuer !== expectedIssuer) { registry.del(issuer.issuer); throw new RPError$2( 'discovered issuer mismatch, expected %s, got: %s', expectedIssuer, issuer.issuer, ); } return issuer; } static async discover(uri) { const wellKnownUri = resolveWellKnownUri(uri); const response = await request.call(this, { method: 'GET', responseType: 'json', url: wellKnownUri, headers: { Accept: 'application/json', }, }); const body = processResponse(response); return new Issuer({ ...ISSUER_DEFAULTS, ...body, [AAD_MULTITENANT]: !!AAD_MULTITENANT_DISCOVERY.find((discoveryURL) => wellKnownUri.startsWith(discoveryURL), ), }); } async reloadJwksUri() { await keystore.call(this, true); } /* istanbul ignore next */ [inspect.custom]() { return `${this.constructor.name} ${inspect(this.metadata, { depth: Infinity, colors: process.stdout.isTTY, compact: false, sorted: true, })}`; } }; function resolveWellKnownUri(uri) { const parsed = url$1.parse(uri); if (parsed.pathname.includes('/.well-known/')) { return uri; } else { let pathname; if (parsed.pathname.endsWith('/')) { pathname = `${parsed.pathname}.well-known/openid-configuration`; } else { pathname = `${parsed.pathname}/.well-known/openid-configuration`; } return url$1.format({ ...parsed, pathname }); } } var issuer = Issuer$2; const url = require$$0$1; const { format } = require$$1; const cloneDeep = deep_clone; const { RPError: RPError$1, OPError: OPError$1 } = errors$2; const { BaseClient } = clientExports; const { random, codeChallenge } = generators$1; const pick = pick$3; const { resolveResponseType, resolveRedirectUri } = client$1; function verified(err, user, info = {}) { if (err) { this.error(err); } else if (!user) { this.fail(info); } else { this.success(user, info); } } function OpenIDConnectStrategy( { client, params = {}, passReqToCallback = false, sessionKey, usePKCE = true, extras = {} } = {}, verify, ) { if (!(client instanceof BaseClient)) { throw new TypeError('client must be an instance of openid-client Client'); } if (typeof verify !== 'function') { throw new TypeError('verify callback must be a function'); } if (!client.issuer || !client.issuer.issuer) { throw new TypeError('client must have an issuer with an identifier'); } this._client = client; this._issuer = client.issuer; this._verify = verify; this._passReqToCallback = passReqToCallback; this._usePKCE = usePKCE; this._key = sessionKey || `oidc:${url.parse(this._issuer.issuer).hostname}`; this._params = cloneDeep(params); // state and nonce are handled in authenticate() delete this._params.state; delete this._params.nonce; this._extras = cloneDeep(extras); if (!this._params.response_type) this._params.response_type = resolveResponseType.call(client); if (!this._params.redirect_uri) this._params.redirect_uri = resolveRedirectUri.call(client); if (!this._params.scope) this._params.scope = 'openid'; if (this._usePKCE === true) { const supportedMethods = Array.isArray(this._issuer.code_challenge_methods_supported) ? this._issuer.code_challenge_methods_supported : false; if (supportedMethods && supportedMethods.includes('S256')) { this._usePKCE = 'S256'; } else if (supportedMethods && supportedMethods.includes('plain')) { this._usePKCE = 'plain'; } else if (supportedMethods) { throw new TypeError( 'neither code_challenge_method supported by the client is supported by the issuer', ); } else { this._usePKCE = 'S256'; } } else if (typeof this._usePKCE === 'string' && !['plain', 'S256'].includes(this._usePKCE)) { throw new TypeError(`${this._usePKCE} is not valid/implemented PKCE code_challenge_method`); } this.name = url.parse(client.issuer.issuer).hostname; } OpenIDConnectStrategy.prototype.authenticate = function authenticate(req, options) { (async () => { const client = this._client; if (!req.session) { throw new TypeError('authentication requires session support'); } const reqParams = client.callbackParams(req); const sessionKey = this._key; const { 0: parameter, length } = Object.keys(reqParams); /** * Start authentication request if this has no authorization response parameters or * this might a login initiated from a third party as per * https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin. */ if (length === 0 || (length === 1 && parameter === 'iss')) { // provide options object with extra authentication parameters const params = { state: random(), ...this._params, ...options, }; if (!params.nonce && params.response_type.includes('id_token')) { params.nonce = random(); } req.session[sessionKey] = pick(params, 'nonce', 'state', 'max_age', 'response_type'); if (this._usePKCE && params.response_type.includes('code')) { const verifier = random(); req.session[sessionKey].code_verifier = verifier; switch (this._usePKCE) { case 'S256': params.code_challenge = codeChallenge(verifier); params.code_challenge_method = 'S256'; break; case 'plain': params.code_challenge = verifier; break; } } this.redirect(client.authorizationUrl(params)); return; } /* end authentication request */ /* start authentication response */ const session = req.session[sessionKey]; if (Object.keys(session || {}).length === 0) { throw new Error( format( 'did not find expected authorization request details in session, req.session["%s"] is %j', sessionKey, session, ), ); } const { state, nonce, max_age: maxAge, code_verifier: codeVerifier, response_type: responseType, } = session; try { delete req.session[sessionKey]; } catch (err) {} const opts = { redirect_uri: this._params.redirect_uri, ...options, }; const checks = { state, nonce, max_age: maxAge, code_verifier: codeVerifier, response_type: responseType, }; const tokenset = await client.callback(opts.redirect_uri, reqParams, checks, this._extras); const passReq = this._passReqToCallback; const loadUserinfo = this._verify.length > (passReq ? 3 : 2) && client.issuer.userinfo_endpoint; const args = [tokenset, verified.bind(this)]; if (loadUserinfo) { if (!tokenset.access_token) { throw new RPError$1({ message: 'expected access_token to be returned when asking for userinfo in verify callback', tokenset, }); } const userinfo = await client.userinfo(tokenset); args.splice(1, 0, userinfo); } if (passReq) { args.unshift(req); } this._verify(...args); /* end authentication response */ })().catch((error) => { if ( (error instanceof OPError$1 && error.error !== 'server_error' && !error.error.startsWith('invalid')) || error instanceof RPError$1 ) { this.fail(error); } else { this.error(error); } }); }; var passport_strategy = OpenIDConnectStrategy; const Issuer$1 = issuer; const { OPError, RPError } = errors$2; const Strategy = passport_strategy; const TokenSet = token_set; const { CLOCK_TOLERANCE, HTTP_OPTIONS } = consts; const generators = generators$1; const { setDefaults } = requestExports; var lib$2 = { Issuer: Issuer$1, Strategy, TokenSet, errors: { OPError, RPError, }, custom: { setHttpOptionsDefaults: setDefaults, http_options: HTTP_OPTIONS, clock_tolerance: CLOCK_TOLERANCE, }, generators, }; var mod = /*@__PURE__*/getDefaultExportFromCjs(lib$2); const Issuer = mod.Issuer; mod.Strategy; mod.TokenSet; mod.errors; mod.custom; mod.generators; var main$1 = {exports: {}}; var name = "dotenv"; var version$1 = "16.4.5"; var description = "Loads environment variables from .env file"; var main = "lib/main.js"; var types$1 = "lib/main.d.ts"; var exports$1 = { ".": { types: "./lib/main.d.ts", require: "./lib/main.js", "default": "./lib/main.js" }, "./config": "./config.js", "./config.js": "./config.js", "./lib/env-options": "./lib/env-options.js", "./lib/env-options.js": "./lib/env-options.js", "./lib/cli-options": "./lib/cli-options.js", "./lib/cli-options.js": "./lib/cli-options.js", "./package.json": "./package.json" }; var scripts = { "dts-check": "tsc --project tests/types/tsconfig.json", lint: "standard", "lint-readme": "standard-markdown", pretest: "npm run lint && npm run dts-check", test: "tap tests/*.js --100 -Rspec", "test:coverage": "tap --coverage-report=lcov", prerelease: "npm test", release: "standard-version" }; var repository = { type: "git", url: "git://github.com/motdotla/dotenv.git" }; var funding = "https://dotenvx.com"; var keywords = [ "dotenv", "env", ".env", "environment", "variables", "config", "settings" ]; var readmeFilename = "README.md"; var license = "BSD-2-Clause"; var devDependencies = { "@definitelytyped/dtslint": "^0.0.133", "@types/node": "^18.11.3", decache: "^4.6.1", sinon: "^14.0.1", standard: "^17.0.0", "standard-markdown": "^7.1.0", "standard-version": "^9.5.0", tap: "^16.3.0", tar: "^6.1.11", typescript: "^4.8.4" }; var engines = { node: ">=12" }; var browser = { fs: false }; var require$$4 = { name: name, version: version$1, description: description, main: main, types: types$1, exports: exports$1, scripts: scripts, repository: repository, funding: funding, keywords: keywords, readmeFilename: readmeFilename, license: license, devDependencies: devDependencies, engines: engines, browser: browser }; const fs$i = fs$j; const path$c = require$$1$5; const os = require$$0$2; const crypto$1 = require$$0$3; const packageJson = require$$4; const version = packageJson.version; const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg; // Parse src into an Object function parse$8 (src) { const obj = {}; // Convert buffer to string let lines = src.toString(); // Convert line breaks to same format lines = lines.replace(/\r\n?/mg, '\n'); let match; while ((match = LINE.exec(lines)) != null) { const key = match[1]; // Default undefined or null to empty string let value = (match[2] || ''); // Remove whitespace value = value.trim(); // Check if double quoted const maybeQuote = value[0]; // Remove surrounding quotes value = value.replace(/^(['"`])([\s\S]*)\1$/mg, '$2'); // Expand newlines if double quoted if (maybeQuote === '"') { value = value.replace(/\\n/g, '\n'); value = value.replace(/\\r/g, '\r'); } // Add to object obj[key] = value; } return obj } function _parseVault (options) { const vaultPath = _vaultPath(options); // Parse .env.vault const result = DotenvModule.configDotenv({ path: vaultPath }); if (!result.parsed) { const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`); err.code = 'MISSING_DATA'; throw err } // handle scenario for comma separated keys - for use with key rotation // example: DOTENV_KEY="dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod" const keys = _dotenvKey(options).split(','); const length = keys.length; let decrypted; for (let i = 0; i < length; i++) { try { // Get full key const key = keys[i].trim(); // Get instructions for decrypt const attrs = _instructions(result, key); // Decrypt decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key); break } catch (error) { // last key if (i + 1 >= length) { throw error } // try next key } } // Parse decrypted .env string return DotenvModule.parse(decrypted) } function _log (message) { console.log(`[dotenv@${version}][INFO] ${message}`); } function _warn (message) { console.log(`[dotenv@${version}][WARN] ${message}`); } function _debug (message) { console.log(`[dotenv@${version}][DEBUG] ${message}`); } function _dotenvKey (options) { // prioritize developer directly setting options.DOTENV_KEY if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) { return options.DOTENV_KEY } // secondary infra already contains a DOTENV_KEY environment variable if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) { return process.env.DOTENV_KEY } // fallback to empty string return '' } function _instructions (result, dotenvKey) { // Parse DOTENV_KEY. Format is a URI let uri; try { uri = new URL(dotenvKey); } catch (error) { if (error.code === 'ERR_INVALID_URL') { const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development'); err.code = 'INVALID_DOTENV_KEY'; throw err } throw error } // Get decrypt key const key = uri.password; if (!key) { const err = new Error('INVALID_DOTENV_KEY: Missing key part'); err.code = 'INVALID_DOTENV_KEY'; throw err } // Get environment const environment = uri.searchParams.get('environment'); if (!environment) { const err = new Error('INVALID_DOTENV_KEY: Missing environment part'); err.code = 'INVALID_DOTENV_KEY'; throw err } // Get ciphertext payload const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`; const ciphertext = result.parsed[environmentKey]; // DOTENV_VAULT_PRODUCTION if (!ciphertext) { const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`); err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'; throw err } return { ciphertext, key } } function _vaultPath (options) { let possibleVaultPath = null; if (options && options.path && options.path.length > 0) { if (Array.isArray(options.path)) { for (const filepath of options.path) { if (fs$i.existsSync(filepath)) { possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`; } } } else { possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`; } } else { possibleVaultPath = path$c.resolve(process.cwd(), '.env.vault'); } if (fs$i.existsSync(possibleVaultPath)) { return possibleVaultPath } return null } function _resolveHome (envPath) { return envPath[0] === '~' ? path$c.join(os.homedir(), envPath.slice(1)) : envPath } function _configVault (options) { _log('Loading env from encrypted .env.vault'); const parsed = DotenvModule._parseVault(options); let processEnv = process.env; if (options && options.processEnv != null) { processEnv = options.processEnv; } DotenvModule.populate(processEnv, parsed, options); return { parsed } } function configDotenv (options) { const dotenvPath = path$c.resolve(process.cwd(), '.env'); let encoding = 'utf8'; const debug = Boolean(options && options.debug); if (options && options.encoding) { encoding = options.encoding; } else { if (debug) { _debug('No encoding is specified. UTF-8 is used by default'); } } let optionPaths = [dotenvPath]; // default, look for .env if (options && options.path) { if (!Array.isArray(options.path)) { optionPaths = [_resolveHome(options.path)]; } else { optionPaths = []; // reset default for (const filepath of options.path) { optionPaths.push(_resolveHome(filepath)); } } } // Build the parsed data in a temporary object (because we need to return it). Once we have the final // parsed data, we will combine it with process.env (or options.processEnv if provided). let lastError; const parsedAll = {}; for (const path of optionPaths) { try { // Specifying an encoding returns a string instead of a buffer const parsed = DotenvModule.parse(fs$i.readFileSync(path, { encoding })); DotenvModule.populate(parsedAll, parsed, options); } catch (e) { if (debug) { _debug(`Failed to load ${path} ${e.message}`); } lastError = e; } } let processEnv = process.env; if (options && options.processEnv != null) { processEnv = options.processEnv; } DotenvModule.populate(processEnv, parsedAll, options); if (lastError) { return { parsed: parsedAll, error: lastError } } else { return { parsed: parsedAll } } } // Populates process.env from .env file function config$1 (options) { // fallback to original dotenv if DOTENV_KEY is not set if (_dotenvKey(options).length === 0) { return DotenvModule.configDotenv(options) } const vaultPath = _vaultPath(options); // dotenvKey exists but .env.vault file does not exist if (!vaultPath) { _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`); return DotenvModule.configDotenv(options) } return DotenvModule._configVault(options) } function decrypt (encrypted, keyStr) { const key = Buffer.from(keyStr.slice(-64), 'hex'); let ciphertext = Buffer.from(encrypted, 'base64'); const nonce = ciphertext.subarray(0, 12); const authTag = ciphertext.subarray(-16); ciphertext = ciphertext.subarray(12, -16); try { const aesgcm = crypto$1.createDecipheriv('aes-256-gcm', key, nonce); aesgcm.setAuthTag(authTag); return `${aesgcm.update(ciphertext)}${aesgcm.final()}` } catch (error) { const isRange = error instanceof RangeError; const invalidKeyLength = error.message === 'Invalid key length'; const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'; if (isRange || invalidKeyLength) { const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)'); err.code = 'INVALID_DOTENV_KEY'; throw err } else if (decryptionFailed) { const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY'); err.code = 'DECRYPTION_FAILED'; throw err } else { throw error } } } // Populate process.env with parsed values function populate (processEnv, parsed, options = {}) { const debug = Boolean(options && options.debug); const override = Boolean(options && options.override); if (typeof parsed !== 'object') { const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate'); err.code = 'OBJECT_REQUIRED'; throw err } // Set process.env for (const key of Object.keys(parsed)) { if (Object.prototype.hasOwnProperty.call(processEnv, key)) { if (override === true) { processEnv[key] = parsed[key]; } if (debug) { if (override === true) { _debug(`"${key}" is already defined and WAS overwritten`); } else { _debug(`"${key}" is already defined and was NOT overwritten`); } } } else { processEnv[key] = parsed[key]; } } } const DotenvModule = { configDotenv, _configVault, _parseVault, config: config$1, decrypt, parse: parse$8, populate }; main$1.exports.configDotenv = DotenvModule.configDotenv; main$1.exports._configVault = DotenvModule._configVault; main$1.exports._parseVault = DotenvModule._parseVault; main$1.exports.config = DotenvModule.config; main$1.exports.decrypt = DotenvModule.decrypt; main$1.exports.parse = DotenvModule.parse; main$1.exports.populate = DotenvModule.populate; main$1.exports = DotenvModule; var mainExports = main$1.exports; var dotenv = /*@__PURE__*/getDefaultExportFromCjs(mainExports); var fs$h = {}; var universalify$1 = {}; universalify$1.fromCallback = function (fn) { return Object.defineProperty(function (...args) { if (typeof args[args.length - 1] === 'function') fn.apply(this, args); else { return new Promise((resolve, reject) => { args.push((err, res) => (err != null) ? reject(err) : resolve(res)); fn.apply(this, args); }) } }, 'name', { value: fn.name }) }; universalify$1.fromPromise = function (fn) { return Object.defineProperty(function (...args) { const cb = args[args.length - 1]; if (typeof cb !== 'function') return fn.apply(this, args) else { args.pop(); fn.apply(this, args).then(r => cb(null, r), cb); } }, 'name', { value: fn.name }) }; var constants$2 = require$$0$7; var origCwd = process.cwd; var cwd = null; var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform; process.cwd = function() { if (!cwd) cwd = origCwd.call(process); return cwd }; try { process.cwd(); } catch (er) {} // This check is needed until node.js 12 is required if (typeof process.chdir === 'function') { var chdir = process.chdir; process.chdir = function (d) { cwd = null; chdir.call(process, d); }; if (Object.setPrototypeOf) Object.setPrototypeOf(process.chdir, chdir); } var polyfills$1 = patch$3; function patch$3 (fs) { // (re-)implement some things that are known busted or missing. // lchmod, broken prior to 0.6.2 // back-port the fix here. if (constants$2.hasOwnProperty('O_SYMLINK') && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { patchLchmod(fs); } // lutimes implementation, or no-op if (!fs.lutimes) { patchLutimes(fs); } // https://github.com/isaacs/node-graceful-fs/issues/4 // Chown should not fail on einval or eperm if non-root. // It should not fail on enosys ever, as this just indicates // that a fs doesn't support the intended operation. fs.chown = chownFix(fs.chown); fs.fchown = chownFix(fs.fchown); fs.lchown = chownFix(fs.lchown); fs.chmod = chmodFix(fs.chmod); fs.fchmod = chmodFix(fs.fchmod); fs.lchmod = chmodFix(fs.lchmod); fs.chownSync = chownFixSync(fs.chownSync); fs.fchownSync = chownFixSync(fs.fchownSync); fs.lchownSync = chownFixSync(fs.lchownSync); fs.chmodSync = chmodFixSync(fs.chmodSync); fs.fchmodSync = chmodFixSync(fs.fchmodSync); fs.lchmodSync = chmodFixSync(fs.lchmodSync); fs.stat = statFix(fs.stat); fs.fstat = statFix(fs.fstat); fs.lstat = statFix(fs.lstat); fs.statSync = statFixSync(fs.statSync); fs.fstatSync = statFixSync(fs.fstatSync); fs.lstatSync = statFixSync(fs.lstatSync); // if lchmod/lchown do not exist, then make them no-ops if (fs.chmod && !fs.lchmod) { fs.lchmod = function (path, mode, cb) { if (cb) process.nextTick(cb); }; fs.lchmodSync = function () {}; } if (fs.chown && !fs.lchown) { fs.lchown = function (path, uid, gid, cb) { if (cb) process.nextTick(cb); }; fs.lchownSync = function () {}; } // on Windows, A/V software can lock the directory, causing this // to fail with an EACCES or EPERM if the directory contains newly // created files. Try again on failure, for up to 60 seconds. // Set the timeout this long because some Windows Anti-Virus, such as Parity // bit9, may lock files for up to a minute, causing npm package install // failures. Also, take care to yield the scheduler. Windows scheduling gives // CPU to a busy looping process, which can cause the program causing the lock // contention to be starved of CPU by node, so the contention doesn't resolve. if (platform === "win32") { fs.rename = typeof fs.rename !== 'function' ? fs.rename : (function (fs$rename) { function rename (from, to, cb) { var start = Date.now(); var backoff = 0; fs$rename(from, to, function CB (er) { if (er && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") && Date.now() - start < 60000) { setTimeout(function() { fs.stat(to, function (stater, st) { if (stater && stater.code === "ENOENT") fs$rename(from, to, CB); else cb(er); }); }, backoff); if (backoff < 100) backoff += 10; return; } if (cb) cb(er); }); } if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename); return rename })(fs.rename); } // if read() returns EAGAIN, then just try it again. fs.read = typeof fs.read !== 'function' ? fs.read : (function (fs$read) { function read (fd, buffer, offset, length, position, callback_) { var callback; if (callback_ && typeof callback_ === 'function') { var eagCounter = 0; callback = function (er, _, __) { if (er && er.code === 'EAGAIN' && eagCounter < 10) { eagCounter ++; return fs$read.call(fs, fd, buffer, offset, length, position, callback) } callback_.apply(this, arguments); }; } return fs$read.call(fs, fd, buffer, offset, length, position, callback) } // This ensures `util.promisify` works as it does for native `fs.read`. if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read); return read })(fs.read); fs.readSync = typeof fs.readSync !== 'function' ? fs.readSync : (function (fs$readSync) { return function (fd, buffer, offset, length, position) { var eagCounter = 0; while (true) { try { return fs$readSync.call(fs, fd, buffer, offset, length, position) } catch (er) { if (er.code === 'EAGAIN' && eagCounter < 10) { eagCounter ++; continue } throw er } } }})(fs.readSync); function patchLchmod (fs) { fs.lchmod = function (path, mode, callback) { fs.open( path , constants$2.O_WRONLY | constants$2.O_SYMLINK , mode , function (err, fd) { if (err) { if (callback) callback(err); return } // prefer to return the chmod error, if one occurs, // but still try to close, and report closing errors if they occur. fs.fchmod(fd, mode, function (err) { fs.close(fd, function(err2) { if (callback) callback(err || err2); }); }); }); }; fs.lchmodSync = function (path, mode) { var fd = fs.openSync(path, constants$2.O_WRONLY | constants$2.O_SYMLINK, mode); // prefer to return the chmod error, if one occurs, // but still try to close, and report closing errors if they occur. var threw = true; var ret; try { ret = fs.fchmodSync(fd, mode); threw = false; } finally { if (threw) { try { fs.closeSync(fd); } catch (er) {} } else { fs.closeSync(fd); } } return ret }; } function patchLutimes (fs) { if (constants$2.hasOwnProperty("O_SYMLINK") && fs.futimes) { fs.lutimes = function (path, at, mt, cb) { fs.open(path, constants$2.O_SYMLINK, function (er, fd) { if (er) { if (cb) cb(er); return } fs.futimes(fd, at, mt, function (er) { fs.close(fd, function (er2) { if (cb) cb(er || er2); }); }); }); }; fs.lutimesSync = function (path, at, mt) { var fd = fs.openSync(path, constants$2.O_SYMLINK); var ret; var threw = true; try { ret = fs.futimesSync(fd, at, mt); threw = false; } finally { if (threw) { try { fs.closeSync(fd); } catch (er) {} } else { fs.closeSync(fd); } } return ret }; } else if (fs.futimes) { fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb); }; fs.lutimesSync = function () {}; } } function chmodFix (orig) { if (!orig) return orig return function (target, mode, cb) { return orig.call(fs, target, mode, function (er) { if (chownErOk(er)) er = null; if (cb) cb.apply(this, arguments); }) } } function chmodFixSync (orig) { if (!orig) return orig return function (target, mode) { try { return orig.call(fs, target, mode) } catch (er) { if (!chownErOk(er)) throw er } } } function chownFix (orig) { if (!orig) return orig return function (target, uid, gid, cb) { return orig.call(fs, target, uid, gid, function (er) { if (chownErOk(er)) er = null; if (cb) cb.apply(this, arguments); }) } } function chownFixSync (orig) { if (!orig) return orig return function (target, uid, gid) { try { return orig.call(fs, target, uid, gid) } catch (er) { if (!chownErOk(er)) throw er } } } function statFix (orig) { if (!orig) return orig // Older versions of Node erroneously returned signed integers for // uid + gid. return function (target, options, cb) { if (typeof options === 'function') { cb = options; options = null; } function callback (er, stats) { if (stats) { if (stats.uid < 0) stats.uid += 0x100000000; if (stats.gid < 0) stats.gid += 0x100000000; } if (cb) cb.apply(this, arguments); } return options ? orig.call(fs, target, options, callback) : orig.call(fs, target, callback) } } function statFixSync (orig) { if (!orig) return orig // Older versions of Node erroneously returned signed integers for // uid + gid. return function (target, options) { var stats = options ? orig.call(fs, target, options) : orig.call(fs, target); if (stats) { if (stats.uid < 0) stats.uid += 0x100000000; if (stats.gid < 0) stats.gid += 0x100000000; } return stats; } } // ENOSYS means that the fs doesn't support the op. Just ignore // that, because it doesn't matter. // // if there's no getuid, or if getuid() is something other // than 0, and the error is EINVAL or EPERM, then just ignore // it. // // This specific case is a silent failure in cp, install, tar, // and most other unix tools that manage permissions. // // When running as root, or if other types of errors are // encountered, then it's strict. function chownErOk (er) { if (!er) return true if (er.code === "ENOSYS") return true var nonroot = !process.getuid || process.getuid() !== 0; if (nonroot) { if (er.code === "EINVAL" || er.code === "EPERM") return true } return false } } var Stream$3 = stream.Stream; var legacyStreams = legacy$1; function legacy$1 (fs) { return { ReadStream: ReadStream, WriteStream: WriteStream } function ReadStream (path, options) { if (!(this instanceof ReadStream)) return new ReadStream(path, options); Stream$3.call(this); var self = this; this.path = path; this.fd = null; this.readable = true; this.paused = false; this.flags = 'r'; this.mode = 438; /*=0666*/ this.bufferSize = 64 * 1024; options = options || {}; // Mixin options into this var keys = Object.keys(options); for (var index = 0, length = keys.length; index < length; index++) { var key = keys[index]; this[key] = options[key]; } if (this.encoding) this.setEncoding(this.encoding); if (this.start !== undefined) { if ('number' !== typeof this.start) { throw TypeError('start must be a Number'); } if (this.end === undefined) { this.end = Infinity; } else if ('number' !== typeof this.end) { throw TypeError('end must be a Number'); } if (this.start > this.end) { throw new Error('start must be <= end'); } this.pos = this.start; } if (this.fd !== null) { process.nextTick(function() { self._read(); }); return; } fs.open(this.path, this.flags, this.mode, function (err, fd) { if (err) { self.emit('error', err); self.readable = false; return; } self.fd = fd; self.emit('open', fd); self._read(); }); } function WriteStream (path, options) { if (!(this instanceof WriteStream)) return new WriteStream(path, options); Stream$3.call(this); this.path = path; this.fd = null; this.writable = true; this.flags = 'w'; this.encoding = 'binary'; this.mode = 438; /*=0666*/ this.bytesWritten = 0; options = options || {}; // Mixin options into this var keys = Object.keys(options); for (var index = 0, length = keys.length; index < length; index++) { var key = keys[index]; this[key] = options[key]; } if (this.start !== undefined) { if ('number' !== typeof this.start) { throw TypeError('start must be a Number'); } if (this.start < 0) { throw new Error('start must be >= zero'); } this.pos = this.start; } this.busy = false; this._queue = []; if (this.fd === null) { this._open = fs.open; this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); this.flush(); } } } var clone_1 = clone$1; var getPrototypeOf = Object.getPrototypeOf || function (obj) { return obj.__proto__ }; function clone$1 (obj) { if (obj === null || typeof obj !== 'object') return obj if (obj instanceof Object) var copy = { __proto__: getPrototypeOf(obj) }; else var copy = Object.create(null); Object.getOwnPropertyNames(obj).forEach(function (key) { Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)); }); return copy } var fs$g = fs$j; var polyfills = polyfills$1; var legacy = legacyStreams; var clone = clone_1; var util$5 = require$$1; /* istanbul ignore next - node 0.x polyfill */ var gracefulQueue; var previousSymbol; /* istanbul ignore else - node 0.x polyfill */ if (typeof Symbol === 'function' && typeof Symbol.for === 'function') { gracefulQueue = Symbol.for('graceful-fs.queue'); // This is used in testing by future versions previousSymbol = Symbol.for('graceful-fs.previous'); } else { gracefulQueue = '___graceful-fs.queue'; previousSymbol = '___graceful-fs.previous'; } function noop$1 () {} function publishQueue(context, queue) { Object.defineProperty(context, gracefulQueue, { get: function() { return queue } }); } var debug$8 = noop$1; if (util$5.debuglog) debug$8 = util$5.debuglog('gfs4'); else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) debug$8 = function() { var m = util$5.format.apply(util$5, arguments); m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: '); console.error(m); }; // Once time initialization if (!fs$g[gracefulQueue]) { // This queue can be shared by multiple loaded instances var queue = commonjsGlobal[gracefulQueue] || []; publishQueue(fs$g, queue); // Patch fs.close/closeSync to shared queue version, because we need // to retry() whenever a close happens *anywhere* in the program. // This is essential when multiple graceful-fs instances are // in play at the same time. fs$g.close = (function (fs$close) { function close (fd, cb) { return fs$close.call(fs$g, fd, function (err) { // This function uses the graceful-fs shared queue if (!err) { resetQueue(); } if (typeof cb === 'function') cb.apply(this, arguments); }) } Object.defineProperty(close, previousSymbol, { value: fs$close }); return close })(fs$g.close); fs$g.closeSync = (function (fs$closeSync) { function closeSync (fd) { // This function uses the graceful-fs shared queue fs$closeSync.apply(fs$g, arguments); resetQueue(); } Object.defineProperty(closeSync, previousSymbol, { value: fs$closeSync }); return closeSync })(fs$g.closeSync); if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { process.on('exit', function() { debug$8(fs$g[gracefulQueue]); require$$0$6.equal(fs$g[gracefulQueue].length, 0); }); } } if (!commonjsGlobal[gracefulQueue]) { publishQueue(commonjsGlobal, fs$g[gracefulQueue]); } var gracefulFs = patch$2(clone(fs$g)); if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$g.__patched) { gracefulFs = patch$2(fs$g); fs$g.__patched = true; } function patch$2 (fs) { // Everything that references the open() function needs to be in here polyfills(fs); fs.gracefulify = patch$2; fs.createReadStream = createReadStream; fs.createWriteStream = createWriteStream; var fs$readFile = fs.readFile; fs.readFile = readFile; function readFile (path, options, cb) { if (typeof options === 'function') cb = options, options = null; return go$readFile(path, options, cb) function go$readFile (path, options, cb, startTime) { return fs$readFile(path, options, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$readFile, [path, options, cb], err, startTime || Date.now(), Date.now()]); else { if (typeof cb === 'function') cb.apply(this, arguments); } }) } } var fs$writeFile = fs.writeFile; fs.writeFile = writeFile; function writeFile (path, data, options, cb) { if (typeof options === 'function') cb = options, options = null; return go$writeFile(path, data, options, cb) function go$writeFile (path, data, options, cb, startTime) { return fs$writeFile(path, data, options, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$writeFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]); else { if (typeof cb === 'function') cb.apply(this, arguments); } }) } } var fs$appendFile = fs.appendFile; if (fs$appendFile) fs.appendFile = appendFile; function appendFile (path, data, options, cb) { if (typeof options === 'function') cb = options, options = null; return go$appendFile(path, data, options, cb) function go$appendFile (path, data, options, cb, startTime) { return fs$appendFile(path, data, options, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$appendFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()]); else { if (typeof cb === 'function') cb.apply(this, arguments); } }) } } var fs$copyFile = fs.copyFile; if (fs$copyFile) fs.copyFile = copyFile; function copyFile (src, dest, flags, cb) { if (typeof flags === 'function') { cb = flags; flags = 0; } return go$copyFile(src, dest, flags, cb) function go$copyFile (src, dest, flags, cb, startTime) { return fs$copyFile(src, dest, flags, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$copyFile, [src, dest, flags, cb], err, startTime || Date.now(), Date.now()]); else { if (typeof cb === 'function') cb.apply(this, arguments); } }) } } var fs$readdir = fs.readdir; fs.readdir = readdir; var noReaddirOptionVersions = /^v[0-5]\./; function readdir (path, options, cb) { if (typeof options === 'function') cb = options, options = null; var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir (path, options, cb, startTime) { return fs$readdir(path, fs$readdirCallback( path, options, cb, startTime )) } : function go$readdir (path, options, cb, startTime) { return fs$readdir(path, options, fs$readdirCallback( path, options, cb, startTime )) }; return go$readdir(path, options, cb) function fs$readdirCallback (path, options, cb, startTime) { return function (err, files) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([ go$readdir, [path, options, cb], err, startTime || Date.now(), Date.now() ]); else { if (files && files.sort) files.sort(); if (typeof cb === 'function') cb.call(this, err, files); } } } } if (process.version.substr(0, 4) === 'v0.8') { var legStreams = legacy(fs); ReadStream = legStreams.ReadStream; WriteStream = legStreams.WriteStream; } var fs$ReadStream = fs.ReadStream; if (fs$ReadStream) { ReadStream.prototype = Object.create(fs$ReadStream.prototype); ReadStream.prototype.open = ReadStream$open; } var fs$WriteStream = fs.WriteStream; if (fs$WriteStream) { WriteStream.prototype = Object.create(fs$WriteStream.prototype); WriteStream.prototype.open = WriteStream$open; } Object.defineProperty(fs, 'ReadStream', { get: function () { return ReadStream }, set: function (val) { ReadStream = val; }, enumerable: true, configurable: true }); Object.defineProperty(fs, 'WriteStream', { get: function () { return WriteStream }, set: function (val) { WriteStream = val; }, enumerable: true, configurable: true }); // legacy names var FileReadStream = ReadStream; Object.defineProperty(fs, 'FileReadStream', { get: function () { return FileReadStream }, set: function (val) { FileReadStream = val; }, enumerable: true, configurable: true }); var FileWriteStream = WriteStream; Object.defineProperty(fs, 'FileWriteStream', { get: function () { return FileWriteStream }, set: function (val) { FileWriteStream = val; }, enumerable: true, configurable: true }); function ReadStream (path, options) { if (this instanceof ReadStream) return fs$ReadStream.apply(this, arguments), this else return ReadStream.apply(Object.create(ReadStream.prototype), arguments) } function ReadStream$open () { var that = this; open(that.path, that.flags, that.mode, function (err, fd) { if (err) { if (that.autoClose) that.destroy(); that.emit('error', err); } else { that.fd = fd; that.emit('open', fd); that.read(); } }); } function WriteStream (path, options) { if (this instanceof WriteStream) return fs$WriteStream.apply(this, arguments), this else return WriteStream.apply(Object.create(WriteStream.prototype), arguments) } function WriteStream$open () { var that = this; open(that.path, that.flags, that.mode, function (err, fd) { if (err) { that.destroy(); that.emit('error', err); } else { that.fd = fd; that.emit('open', fd); } }); } function createReadStream (path, options) { return new fs.ReadStream(path, options) } function createWriteStream (path, options) { return new fs.WriteStream(path, options) } var fs$open = fs.open; fs.open = open; function open (path, flags, mode, cb) { if (typeof mode === 'function') cb = mode, mode = null; return go$open(path, flags, mode, cb) function go$open (path, flags, mode, cb, startTime) { return fs$open(path, flags, mode, function (err, fd) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$open, [path, flags, mode, cb], err, startTime || Date.now(), Date.now()]); else { if (typeof cb === 'function') cb.apply(this, arguments); } }) } } return fs } function enqueue (elem) { debug$8('ENQUEUE', elem[0].name, elem[1]); fs$g[gracefulQueue].push(elem); retry(); } // keep track of the timeout between retry() calls var retryTimer; // reset the startTime and lastTime to now // this resets the start of the 60 second overall timeout as well as the // delay between attempts so that we'll retry these jobs sooner function resetQueue () { var now = Date.now(); for (var i = 0; i < fs$g[gracefulQueue].length; ++i) { // entries that are only a length of 2 are from an older version, don't // bother modifying those since they'll be retried anyway. if (fs$g[gracefulQueue][i].length > 2) { fs$g[gracefulQueue][i][3] = now; // startTime fs$g[gracefulQueue][i][4] = now; // lastTime } } // call retry to make sure we're actively processing the queue retry(); } function retry () { // clear the timer and remove it to help prevent unintended concurrency clearTimeout(retryTimer); retryTimer = undefined; if (fs$g[gracefulQueue].length === 0) return var elem = fs$g[gracefulQueue].shift(); var fn = elem[0]; var args = elem[1]; // these items may be unset if they were added by an older graceful-fs var err = elem[2]; var startTime = elem[3]; var lastTime = elem[4]; // if we don't have a startTime we have no way of knowing if we've waited // long enough, so go ahead and retry this item now if (startTime === undefined) { debug$8('RETRY', fn.name, args); fn.apply(null, args); } else if (Date.now() - startTime >= 60000) { // it's been more than 60 seconds total, bail now debug$8('TIMEOUT', fn.name, args); var cb = args.pop(); if (typeof cb === 'function') cb.call(null, err); } else { // the amount of time between the last attempt and right now var sinceAttempt = Date.now() - lastTime; // the amount of time between when we first tried, and when we last tried // rounded up to at least 1 var sinceStart = Math.max(lastTime - startTime, 1); // backoff. wait longer than the total time we've been retrying, but only // up to a maximum of 100ms var desiredDelay = Math.min(sinceStart * 1.2, 100); // it's been long enough since the last retry, do it again if (sinceAttempt >= desiredDelay) { debug$8('RETRY', fn.name, args); fn.apply(null, args.concat([startTime])); } else { // if we can't do this job yet, push it to the end of the queue // and let the next iteration check again fs$g[gracefulQueue].push(elem); } } // schedule our next run if one isn't already scheduled if (retryTimer === undefined) { retryTimer = setTimeout(retry, 0); } } (function (exports) { // This is adapted from https://github.com/normalize/mz // Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com and Contributors const u = universalify$1.fromCallback; const fs = gracefulFs; const api = [ 'access', 'appendFile', 'chmod', 'chown', 'close', 'copyFile', 'fchmod', 'fchown', 'fdatasync', 'fstat', 'fsync', 'ftruncate', 'futimes', 'lchmod', 'lchown', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'opendir', 'readdir', 'readFile', 'readlink', 'realpath', 'rename', 'rm', 'rmdir', 'stat', 'symlink', 'truncate', 'unlink', 'utimes', 'writeFile' ].filter(key => { // Some commands are not available on some systems. Ex: // fs.cp was added in Node.js v16.7.0 // fs.lchown is not available on at least some Linux return typeof fs[key] === 'function' }); // Export cloned fs: Object.assign(exports, fs); // Universalify async methods: api.forEach(method => { exports[method] = u(fs[method]); }); // We differ from mz/fs in that we still ship the old, broken, fs.exists() // since we are a drop-in replacement for the native module exports.exists = function (filename, callback) { if (typeof callback === 'function') { return fs.exists(filename, callback) } return new Promise(resolve => { return fs.exists(filename, resolve) }) }; // fs.read(), fs.write(), fs.readv(), & fs.writev() need special treatment due to multiple callback args exports.read = function (fd, buffer, offset, length, position, callback) { if (typeof callback === 'function') { return fs.read(fd, buffer, offset, length, position, callback) } return new Promise((resolve, reject) => { fs.read(fd, buffer, offset, length, position, (err, bytesRead, buffer) => { if (err) return reject(err) resolve({ bytesRead, buffer }); }); }) }; // Function signature can be // fs.write(fd, buffer[, offset[, length[, position]]], callback) // OR // fs.write(fd, string[, position[, encoding]], callback) // We need to handle both cases, so we use ...args exports.write = function (fd, buffer, ...args) { if (typeof args[args.length - 1] === 'function') { return fs.write(fd, buffer, ...args) } return new Promise((resolve, reject) => { fs.write(fd, buffer, ...args, (err, bytesWritten, buffer) => { if (err) return reject(err) resolve({ bytesWritten, buffer }); }); }) }; // Function signature is // s.readv(fd, buffers[, position], callback) // We need to handle the optional arg, so we use ...args exports.readv = function (fd, buffers, ...args) { if (typeof args[args.length - 1] === 'function') { return fs.readv(fd, buffers, ...args) } return new Promise((resolve, reject) => { fs.readv(fd, buffers, ...args, (err, bytesRead, buffers) => { if (err) return reject(err) resolve({ bytesRead, buffers }); }); }) }; // Function signature is // s.writev(fd, buffers[, position], callback) // We need to handle the optional arg, so we use ...args exports.writev = function (fd, buffers, ...args) { if (typeof args[args.length - 1] === 'function') { return fs.writev(fd, buffers, ...args) } return new Promise((resolve, reject) => { fs.writev(fd, buffers, ...args, (err, bytesWritten, buffers) => { if (err) return reject(err) resolve({ bytesWritten, buffers }); }); }) }; // fs.realpath.native sometimes not available if fs is monkey-patched if (typeof fs.realpath.native === 'function') { exports.realpath.native = u(fs.realpath.native); } else { process.emitWarning( 'fs.realpath.native is not a function. Is fs being monkey-patched?', 'Warning', 'fs-extra-WARN0003' ); } } (fs$h)); var makeDir$1 = {}; var utils$3 = {}; const path$b = require$$1$5; // https://github.com/nodejs/node/issues/8987 // https://github.com/libuv/libuv/pull/1088 utils$3.checkPath = function checkPath (pth) { if (process.platform === 'win32') { const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path$b.parse(pth).root, '')); if (pathHasInvalidWinCharacters) { const error = new Error(`Path contains invalid characters: ${pth}`); error.code = 'EINVAL'; throw error } } }; const fs$f = fs$h; const { checkPath } = utils$3; const getMode = options => { const defaults = { mode: 0o777 }; if (typeof options === 'number') return options return ({ ...defaults, ...options }).mode }; makeDir$1.makeDir = async (dir, options) => { checkPath(dir); return fs$f.mkdir(dir, { mode: getMode(options), recursive: true }) }; makeDir$1.makeDirSync = (dir, options) => { checkPath(dir); return fs$f.mkdirSync(dir, { mode: getMode(options), recursive: true }) }; const u$e = universalify$1.fromPromise; const { makeDir: _makeDir, makeDirSync } = makeDir$1; const makeDir = u$e(_makeDir); var mkdirs$2 = { mkdirs: makeDir, mkdirsSync: makeDirSync, // alias mkdirp: makeDir, mkdirpSync: makeDirSync, ensureDir: makeDir, ensureDirSync: makeDirSync }; const u$d = universalify$1.fromPromise; const fs$e = fs$h; function pathExists$6 (path) { return fs$e.access(path).then(() => true).catch(() => false) } var pathExists_1 = { pathExists: u$d(pathExists$6), pathExistsSync: fs$e.existsSync }; const fs$d = fs$h; const u$c = universalify$1.fromPromise; async function utimesMillis$1 (path, atime, mtime) { // if (!HAS_MILLIS_RES) return fs.utimes(path, atime, mtime, callback) const fd = await fs$d.open(path, 'r+'); let closeErr = null; try { await fs$d.futimes(fd, atime, mtime); } finally { try { await fs$d.close(fd); } catch (e) { closeErr = e; } } if (closeErr) { throw closeErr } } function utimesMillisSync$1 (path, atime, mtime) { const fd = fs$d.openSync(path, 'r+'); fs$d.futimesSync(fd, atime, mtime); return fs$d.closeSync(fd) } var utimes = { utimesMillis: u$c(utimesMillis$1), utimesMillisSync: utimesMillisSync$1 }; const fs$c = fs$h; const path$a = require$$1$5; const u$b = universalify$1.fromPromise; function getStats$1 (src, dest, opts) { const statFunc = opts.dereference ? (file) => fs$c.stat(file, { bigint: true }) : (file) => fs$c.lstat(file, { bigint: true }); return Promise.all([ statFunc(src), statFunc(dest).catch(err => { if (err.code === 'ENOENT') return null throw err }) ]).then(([srcStat, destStat]) => ({ srcStat, destStat })) } function getStatsSync (src, dest, opts) { let destStat; const statFunc = opts.dereference ? (file) => fs$c.statSync(file, { bigint: true }) : (file) => fs$c.lstatSync(file, { bigint: true }); const srcStat = statFunc(src); try { destStat = statFunc(dest); } catch (err) { if (err.code === 'ENOENT') return { srcStat, destStat: null } throw err } return { srcStat, destStat } } async function checkPaths (src, dest, funcName, opts) { const { srcStat, destStat } = await getStats$1(src, dest, opts); if (destStat) { if (areIdentical$2(srcStat, destStat)) { const srcBaseName = path$a.basename(src); const destBaseName = path$a.basename(dest); if (funcName === 'move' && srcBaseName !== destBaseName && srcBaseName.toLowerCase() === destBaseName.toLowerCase()) { return { srcStat, destStat, isChangingCase: true } } throw new Error('Source and destination must not be the same.') } if (srcStat.isDirectory() && !destStat.isDirectory()) { throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`) } if (!srcStat.isDirectory() && destStat.isDirectory()) { throw new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`) } } if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { throw new Error(errMsg(src, dest, funcName)) } return { srcStat, destStat } } function checkPathsSync (src, dest, funcName, opts) { const { srcStat, destStat } = getStatsSync(src, dest, opts); if (destStat) { if (areIdentical$2(srcStat, destStat)) { const srcBaseName = path$a.basename(src); const destBaseName = path$a.basename(dest); if (funcName === 'move' && srcBaseName !== destBaseName && srcBaseName.toLowerCase() === destBaseName.toLowerCase()) { return { srcStat, destStat, isChangingCase: true } } throw new Error('Source and destination must not be the same.') } if (srcStat.isDirectory() && !destStat.isDirectory()) { throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`) } if (!srcStat.isDirectory() && destStat.isDirectory()) { throw new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`) } } if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { throw new Error(errMsg(src, dest, funcName)) } return { srcStat, destStat } } // recursively check if dest parent is a subdirectory of src. // It works for all file types including symlinks since it // checks the src and dest inodes. It starts from the deepest // parent and stops once it reaches the src parent or the root path. async function checkParentPaths (src, srcStat, dest, funcName) { const srcParent = path$a.resolve(path$a.dirname(src)); const destParent = path$a.resolve(path$a.dirname(dest)); if (destParent === srcParent || destParent === path$a.parse(destParent).root) return let destStat; try { destStat = await fs$c.stat(destParent, { bigint: true }); } catch (err) { if (err.code === 'ENOENT') return throw err } if (areIdentical$2(srcStat, destStat)) { throw new Error(errMsg(src, dest, funcName)) } return checkParentPaths(src, srcStat, destParent, funcName) } function checkParentPathsSync (src, srcStat, dest, funcName) { const srcParent = path$a.resolve(path$a.dirname(src)); const destParent = path$a.resolve(path$a.dirname(dest)); if (destParent === srcParent || destParent === path$a.parse(destParent).root) return let destStat; try { destStat = fs$c.statSync(destParent, { bigint: true }); } catch (err) { if (err.code === 'ENOENT') return throw err } if (areIdentical$2(srcStat, destStat)) { throw new Error(errMsg(src, dest, funcName)) } return checkParentPathsSync(src, srcStat, destParent, funcName) } function areIdentical$2 (srcStat, destStat) { return destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev } // return true if dest is a subdir of src, otherwise false. // It only checks the path strings. function isSrcSubdir (src, dest) { const srcArr = path$a.resolve(src).split(path$a.sep).filter(i => i); const destArr = path$a.resolve(dest).split(path$a.sep).filter(i => i); return srcArr.every((cur, i) => destArr[i] === cur) } function errMsg (src, dest, funcName) { return `Cannot ${funcName} '${src}' to a subdirectory of itself, '${dest}'.` } var stat$4 = { // checkPaths checkPaths: u$b(checkPaths), checkPathsSync, // checkParent checkParentPaths: u$b(checkParentPaths), checkParentPathsSync, // Misc isSrcSubdir, areIdentical: areIdentical$2 }; const fs$b = fs$h; const path$9 = require$$1$5; const { mkdirs: mkdirs$1 } = mkdirs$2; const { pathExists: pathExists$5 } = pathExists_1; const { utimesMillis } = utimes; const stat$3 = stat$4; async function copy$3 (src, dest, opts = {}) { if (typeof opts === 'function') { opts = { filter: opts }; } opts.clobber = 'clobber' in opts ? !!opts.clobber : true; // default to true for now opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber; // overwrite falls back to clobber // Warn about using preserveTimestamps on 32-bit node if (opts.preserveTimestamps && process.arch === 'ia32') { process.emitWarning( 'Using the preserveTimestamps option in 32-bit node is not recommended;\n\n' + '\tsee https://github.com/jprichardson/node-fs-extra/issues/269', 'Warning', 'fs-extra-WARN0001' ); } const { srcStat, destStat } = await stat$3.checkPaths(src, dest, 'copy', opts); await stat$3.checkParentPaths(src, srcStat, dest, 'copy'); const include = await runFilter(src, dest, opts); if (!include) return // check if the parent of dest exists, and create it if it doesn't exist const destParent = path$9.dirname(dest); const dirExists = await pathExists$5(destParent); if (!dirExists) { await mkdirs$1(destParent); } await getStatsAndPerformCopy(destStat, src, dest, opts); } async function runFilter (src, dest, opts) { if (!opts.filter) return true return opts.filter(src, dest) } async function getStatsAndPerformCopy (destStat, src, dest, opts) { const statFn = opts.dereference ? fs$b.stat : fs$b.lstat; const srcStat = await statFn(src); if (srcStat.isDirectory()) return onDir$1(srcStat, destStat, src, dest, opts) if ( srcStat.isFile() || srcStat.isCharacterDevice() || srcStat.isBlockDevice() ) return onFile$1(srcStat, destStat, src, dest, opts) if (srcStat.isSymbolicLink()) return onLink$1(destStat, src, dest, opts) if (srcStat.isSocket()) throw new Error(`Cannot copy a socket file: ${src}`) if (srcStat.isFIFO()) throw new Error(`Cannot copy a FIFO pipe: ${src}`) throw new Error(`Unknown file: ${src}`) } async function onFile$1 (srcStat, destStat, src, dest, opts) { if (!destStat) return copyFile$1(srcStat, src, dest, opts) if (opts.overwrite) { await fs$b.unlink(dest); return copyFile$1(srcStat, src, dest, opts) } if (opts.errorOnExist) { throw new Error(`'${dest}' already exists`) } } async function copyFile$1 (srcStat, src, dest, opts) { await fs$b.copyFile(src, dest); if (opts.preserveTimestamps) { // Make sure the file is writable before setting the timestamp // otherwise open fails with EPERM when invoked with 'r+' // (through utimes call) if (fileIsNotWritable$1(srcStat.mode)) { await makeFileWritable$1(dest, srcStat.mode); } // Set timestamps and mode correspondingly // Note that The initial srcStat.atime cannot be trusted // because it is modified by the read(2) system call // (See https://nodejs.org/api/fs.html#fs_stat_time_values) const updatedSrcStat = await fs$b.stat(src); await utimesMillis(dest, updatedSrcStat.atime, updatedSrcStat.mtime); } return fs$b.chmod(dest, srcStat.mode) } function fileIsNotWritable$1 (srcMode) { return (srcMode & 0o200) === 0 } function makeFileWritable$1 (dest, srcMode) { return fs$b.chmod(dest, srcMode | 0o200) } async function onDir$1 (srcStat, destStat, src, dest, opts) { // the dest directory might not exist, create it if (!destStat) { await fs$b.mkdir(dest); } const items = await fs$b.readdir(src); // loop through the files in the current directory to copy everything await Promise.all(items.map(async item => { const srcItem = path$9.join(src, item); const destItem = path$9.join(dest, item); // skip the item if it is matches by the filter function const include = await runFilter(srcItem, destItem, opts); if (!include) return const { destStat } = await stat$3.checkPaths(srcItem, destItem, 'copy', opts); // If the item is a copyable file, `getStatsAndPerformCopy` will copy it // If the item is a directory, `getStatsAndPerformCopy` will call `onDir` recursively return getStatsAndPerformCopy(destStat, srcItem, destItem, opts) })); if (!destStat) { await fs$b.chmod(dest, srcStat.mode); } } async function onLink$1 (destStat, src, dest, opts) { let resolvedSrc = await fs$b.readlink(src); if (opts.dereference) { resolvedSrc = path$9.resolve(process.cwd(), resolvedSrc); } if (!destStat) { return fs$b.symlink(resolvedSrc, dest) } let resolvedDest = null; try { resolvedDest = await fs$b.readlink(dest); } catch (e) { // dest exists and is a regular file or directory, // Windows may throw UNKNOWN error. If dest already exists, // fs throws error anyway, so no need to guard against it here. if (e.code === 'EINVAL' || e.code === 'UNKNOWN') return fs$b.symlink(resolvedSrc, dest) throw e } if (opts.dereference) { resolvedDest = path$9.resolve(process.cwd(), resolvedDest); } if (stat$3.isSrcSubdir(resolvedSrc, resolvedDest)) { throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`) } // do not copy if src is a subdir of dest since unlinking // dest in this case would result in removing src contents // and therefore a broken symlink would be created. if (stat$3.isSrcSubdir(resolvedDest, resolvedSrc)) { throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`) } // copy the link await fs$b.unlink(dest); return fs$b.symlink(resolvedSrc, dest) } var copy_1 = copy$3; const fs$a = gracefulFs; const path$8 = require$$1$5; const mkdirsSync$1 = mkdirs$2.mkdirsSync; const utimesMillisSync = utimes.utimesMillisSync; const stat$2 = stat$4; function copySync$1 (src, dest, opts) { if (typeof opts === 'function') { opts = { filter: opts }; } opts = opts || {}; opts.clobber = 'clobber' in opts ? !!opts.clobber : true; // default to true for now opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber; // overwrite falls back to clobber // Warn about using preserveTimestamps on 32-bit node if (opts.preserveTimestamps && process.arch === 'ia32') { process.emitWarning( 'Using the preserveTimestamps option in 32-bit node is not recommended;\n\n' + '\tsee https://github.com/jprichardson/node-fs-extra/issues/269', 'Warning', 'fs-extra-WARN0002' ); } const { srcStat, destStat } = stat$2.checkPathsSync(src, dest, 'copy', opts); stat$2.checkParentPathsSync(src, srcStat, dest, 'copy'); if (opts.filter && !opts.filter(src, dest)) return const destParent = path$8.dirname(dest); if (!fs$a.existsSync(destParent)) mkdirsSync$1(destParent); return getStats(destStat, src, dest, opts) } function getStats (destStat, src, dest, opts) { const statSync = opts.dereference ? fs$a.statSync : fs$a.lstatSync; const srcStat = statSync(src); if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts) else if (srcStat.isFile() || srcStat.isCharacterDevice() || srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts) else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts) else if (srcStat.isSocket()) throw new Error(`Cannot copy a socket file: ${src}`) else if (srcStat.isFIFO()) throw new Error(`Cannot copy a FIFO pipe: ${src}`) throw new Error(`Unknown file: ${src}`) } function onFile (srcStat, destStat, src, dest, opts) { if (!destStat) return copyFile(srcStat, src, dest, opts) return mayCopyFile(srcStat, src, dest, opts) } function mayCopyFile (srcStat, src, dest, opts) { if (opts.overwrite) { fs$a.unlinkSync(dest); return copyFile(srcStat, src, dest, opts) } else if (opts.errorOnExist) { throw new Error(`'${dest}' already exists`) } } function copyFile (srcStat, src, dest, opts) { fs$a.copyFileSync(src, dest); if (opts.preserveTimestamps) handleTimestamps(srcStat.mode, src, dest); return setDestMode(dest, srcStat.mode) } function handleTimestamps (srcMode, src, dest) { // Make sure the file is writable before setting the timestamp // otherwise open fails with EPERM when invoked with 'r+' // (through utimes call) if (fileIsNotWritable(srcMode)) makeFileWritable(dest, srcMode); return setDestTimestamps(src, dest) } function fileIsNotWritable (srcMode) { return (srcMode & 0o200) === 0 } function makeFileWritable (dest, srcMode) { return setDestMode(dest, srcMode | 0o200) } function setDestMode (dest, srcMode) { return fs$a.chmodSync(dest, srcMode) } function setDestTimestamps (src, dest) { // The initial srcStat.atime cannot be trusted // because it is modified by the read(2) system call // (See https://nodejs.org/api/fs.html#fs_stat_time_values) const updatedSrcStat = fs$a.statSync(src); return utimesMillisSync(dest, updatedSrcStat.atime, updatedSrcStat.mtime) } function onDir (srcStat, destStat, src, dest, opts) { if (!destStat) return mkDirAndCopy(srcStat.mode, src, dest, opts) return copyDir(src, dest, opts) } function mkDirAndCopy (srcMode, src, dest, opts) { fs$a.mkdirSync(dest); copyDir(src, dest, opts); return setDestMode(dest, srcMode) } function copyDir (src, dest, opts) { fs$a.readdirSync(src).forEach(item => copyDirItem(item, src, dest, opts)); } function copyDirItem (item, src, dest, opts) { const srcItem = path$8.join(src, item); const destItem = path$8.join(dest, item); if (opts.filter && !opts.filter(srcItem, destItem)) return const { destStat } = stat$2.checkPathsSync(srcItem, destItem, 'copy', opts); return getStats(destStat, srcItem, destItem, opts) } function onLink (destStat, src, dest, opts) { let resolvedSrc = fs$a.readlinkSync(src); if (opts.dereference) { resolvedSrc = path$8.resolve(process.cwd(), resolvedSrc); } if (!destStat) { return fs$a.symlinkSync(resolvedSrc, dest) } else { let resolvedDest; try { resolvedDest = fs$a.readlinkSync(dest); } catch (err) { // dest exists and is a regular file or directory, // Windows may throw UNKNOWN error. If dest already exists, // fs throws error anyway, so no need to guard against it here. if (err.code === 'EINVAL' || err.code === 'UNKNOWN') return fs$a.symlinkSync(resolvedSrc, dest) throw err } if (opts.dereference) { resolvedDest = path$8.resolve(process.cwd(), resolvedDest); } if (stat$2.isSrcSubdir(resolvedSrc, resolvedDest)) { throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`) } // prevent copy if src is a subdir of dest since unlinking // dest in this case would result in removing src contents // and therefore a broken symlink would be created. if (stat$2.isSrcSubdir(resolvedDest, resolvedSrc)) { throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`) } return copyLink(resolvedSrc, dest) } } function copyLink (resolvedSrc, dest) { fs$a.unlinkSync(dest); return fs$a.symlinkSync(resolvedSrc, dest) } var copySync_1 = copySync$1; const u$a = universalify$1.fromPromise; var copy$2 = { copy: u$a(copy_1), copySync: copySync_1 }; const fs$9 = gracefulFs; const u$9 = universalify$1.fromCallback; function remove$2 (path, callback) { fs$9.rm(path, { recursive: true, force: true }, callback); } function removeSync$1 (path) { fs$9.rmSync(path, { recursive: true, force: true }); } var remove_1 = { remove: u$9(remove$2), removeSync: removeSync$1 }; const u$8 = universalify$1.fromPromise; const fs$8 = fs$h; const path$7 = require$$1$5; const mkdir$3 = mkdirs$2; const remove$1 = remove_1; const emptyDir = u$8(async function emptyDir (dir) { let items; try { items = await fs$8.readdir(dir); } catch { return mkdir$3.mkdirs(dir) } return Promise.all(items.map(item => remove$1.remove(path$7.join(dir, item)))) }); function emptyDirSync (dir) { let items; try { items = fs$8.readdirSync(dir); } catch { return mkdir$3.mkdirsSync(dir) } items.forEach(item => { item = path$7.join(dir, item); remove$1.removeSync(item); }); } var empty = { emptyDirSync, emptydirSync: emptyDirSync, emptyDir, emptydir: emptyDir }; const u$7 = universalify$1.fromPromise; const path$6 = require$$1$5; const fs$7 = fs$h; const mkdir$2 = mkdirs$2; async function createFile$1 (file) { let stats; try { stats = await fs$7.stat(file); } catch { } if (stats && stats.isFile()) return const dir = path$6.dirname(file); let dirStats = null; try { dirStats = await fs$7.stat(dir); } catch (err) { // if the directory doesn't exist, make it if (err.code === 'ENOENT') { await mkdir$2.mkdirs(dir); await fs$7.writeFile(file, ''); return } else { throw err } } if (dirStats.isDirectory()) { await fs$7.writeFile(file, ''); } else { // parent is not a directory // This is just to cause an internal ENOTDIR error to be thrown await fs$7.readdir(dir); } } function createFileSync$1 (file) { let stats; try { stats = fs$7.statSync(file); } catch { } if (stats && stats.isFile()) return const dir = path$6.dirname(file); try { if (!fs$7.statSync(dir).isDirectory()) { // parent is not a directory // This is just to cause an internal ENOTDIR error to be thrown fs$7.readdirSync(dir); } } catch (err) { // If the stat call above failed because the directory doesn't exist, create it if (err && err.code === 'ENOENT') mkdir$2.mkdirsSync(dir); else throw err } fs$7.writeFileSync(file, ''); } var file = { createFile: u$7(createFile$1), createFileSync: createFileSync$1 }; const u$6 = universalify$1.fromPromise; const path$5 = require$$1$5; const fs$6 = fs$h; const mkdir$1 = mkdirs$2; const { pathExists: pathExists$4 } = pathExists_1; const { areIdentical: areIdentical$1 } = stat$4; async function createLink$1 (srcpath, dstpath) { let dstStat; try { dstStat = await fs$6.lstat(dstpath); } catch { // ignore error } let srcStat; try { srcStat = await fs$6.lstat(srcpath); } catch (err) { err.message = err.message.replace('lstat', 'ensureLink'); throw err } if (dstStat && areIdentical$1(srcStat, dstStat)) return const dir = path$5.dirname(dstpath); const dirExists = await pathExists$4(dir); if (!dirExists) { await mkdir$1.mkdirs(dir); } await fs$6.link(srcpath, dstpath); } function createLinkSync$1 (srcpath, dstpath) { let dstStat; try { dstStat = fs$6.lstatSync(dstpath); } catch {} try { const srcStat = fs$6.lstatSync(srcpath); if (dstStat && areIdentical$1(srcStat, dstStat)) return } catch (err) { err.message = err.message.replace('lstat', 'ensureLink'); throw err } const dir = path$5.dirname(dstpath); const dirExists = fs$6.existsSync(dir); if (dirExists) return fs$6.linkSync(srcpath, dstpath) mkdir$1.mkdirsSync(dir); return fs$6.linkSync(srcpath, dstpath) } var link = { createLink: u$6(createLink$1), createLinkSync: createLinkSync$1 }; const path$4 = require$$1$5; const fs$5 = fs$h; const { pathExists: pathExists$3 } = pathExists_1; const u$5 = universalify$1.fromPromise; /** * Function that returns two types of paths, one relative to symlink, and one * relative to the current working directory. Checks if path is absolute or * relative. If the path is relative, this function checks if the path is * relative to symlink or relative to current working directory. This is an * initiative to find a smarter `srcpath` to supply when building symlinks. * This allows you to determine which path to use out of one of three possible * types of source paths. The first is an absolute path. This is detected by * `path.isAbsolute()`. When an absolute path is provided, it is checked to * see if it exists. If it does it's used, if not an error is returned * (callback)/ thrown (sync). The other two options for `srcpath` are a * relative url. By default Node's `fs.symlink` works by creating a symlink * using `dstpath` and expects the `srcpath` to be relative to the newly * created symlink. If you provide a `srcpath` that does not exist on the file * system it results in a broken symlink. To minimize this, the function * checks to see if the 'relative to symlink' source file exists, and if it * does it will use it. If it does not, it checks if there's a file that * exists that is relative to the current working directory, if does its used. * This preserves the expectations of the original fs.symlink spec and adds * the ability to pass in `relative to current working direcotry` paths. */ async function symlinkPaths$1 (srcpath, dstpath) { if (path$4.isAbsolute(srcpath)) { try { await fs$5.lstat(srcpath); } catch (err) { err.message = err.message.replace('lstat', 'ensureSymlink'); throw err } return { toCwd: srcpath, toDst: srcpath } } const dstdir = path$4.dirname(dstpath); const relativeToDst = path$4.join(dstdir, srcpath); const exists = await pathExists$3(relativeToDst); if (exists) { return { toCwd: relativeToDst, toDst: srcpath } } try { await fs$5.lstat(srcpath); } catch (err) { err.message = err.message.replace('lstat', 'ensureSymlink'); throw err } return { toCwd: srcpath, toDst: path$4.relative(dstdir, srcpath) } } function symlinkPathsSync$1 (srcpath, dstpath) { if (path$4.isAbsolute(srcpath)) { const exists = fs$5.existsSync(srcpath); if (!exists) throw new Error('absolute srcpath does not exist') return { toCwd: srcpath, toDst: srcpath } } const dstdir = path$4.dirname(dstpath); const relativeToDst = path$4.join(dstdir, srcpath); const exists = fs$5.existsSync(relativeToDst); if (exists) { return { toCwd: relativeToDst, toDst: srcpath } } const srcExists = fs$5.existsSync(srcpath); if (!srcExists) throw new Error('relative srcpath does not exist') return { toCwd: srcpath, toDst: path$4.relative(dstdir, srcpath) } } var symlinkPaths_1 = { symlinkPaths: u$5(symlinkPaths$1), symlinkPathsSync: symlinkPathsSync$1 }; const fs$4 = fs$h; const u$4 = universalify$1.fromPromise; async function symlinkType$1 (srcpath, type) { if (type) return type let stats; try { stats = await fs$4.lstat(srcpath); } catch { return 'file' } return (stats && stats.isDirectory()) ? 'dir' : 'file' } function symlinkTypeSync$1 (srcpath, type) { if (type) return type let stats; try { stats = fs$4.lstatSync(srcpath); } catch { return 'file' } return (stats && stats.isDirectory()) ? 'dir' : 'file' } var symlinkType_1 = { symlinkType: u$4(symlinkType$1), symlinkTypeSync: symlinkTypeSync$1 }; const u$3 = universalify$1.fromPromise; const path$3 = require$$1$5; const fs$3 = fs$h; const { mkdirs, mkdirsSync } = mkdirs$2; const { symlinkPaths, symlinkPathsSync } = symlinkPaths_1; const { symlinkType, symlinkTypeSync } = symlinkType_1; const { pathExists: pathExists$2 } = pathExists_1; const { areIdentical } = stat$4; async function createSymlink$1 (srcpath, dstpath, type) { let stats; try { stats = await fs$3.lstat(dstpath); } catch { } if (stats && stats.isSymbolicLink()) { const [srcStat, dstStat] = await Promise.all([ fs$3.stat(srcpath), fs$3.stat(dstpath) ]); if (areIdentical(srcStat, dstStat)) return } const relative = await symlinkPaths(srcpath, dstpath); srcpath = relative.toDst; const toType = await symlinkType(relative.toCwd, type); const dir = path$3.dirname(dstpath); if (!(await pathExists$2(dir))) { await mkdirs(dir); } return fs$3.symlink(srcpath, dstpath, toType) } function createSymlinkSync$1 (srcpath, dstpath, type) { let stats; try { stats = fs$3.lstatSync(dstpath); } catch { } if (stats && stats.isSymbolicLink()) { const srcStat = fs$3.statSync(srcpath); const dstStat = fs$3.statSync(dstpath); if (areIdentical(srcStat, dstStat)) return } const relative = symlinkPathsSync(srcpath, dstpath); srcpath = relative.toDst; type = symlinkTypeSync(relative.toCwd, type); const dir = path$3.dirname(dstpath); const exists = fs$3.existsSync(dir); if (exists) return fs$3.symlinkSync(srcpath, dstpath, type) mkdirsSync(dir); return fs$3.symlinkSync(srcpath, dstpath, type) } var symlink = { createSymlink: u$3(createSymlink$1), createSymlinkSync: createSymlinkSync$1 }; const { createFile, createFileSync } = file; const { createLink, createLinkSync } = link; const { createSymlink, createSymlinkSync } = symlink; var ensure = { // file createFile, createFileSync, ensureFile: createFile, ensureFileSync: createFileSync, // link createLink, createLinkSync, ensureLink: createLink, ensureLinkSync: createLinkSync, // symlink createSymlink, createSymlinkSync, ensureSymlink: createSymlink, ensureSymlinkSync: createSymlinkSync }; function stringify$3 (obj, { EOL = '\n', finalEOL = true, replacer = null, spaces } = {}) { const EOF = finalEOL ? EOL : ''; const str = JSON.stringify(obj, replacer, spaces); return str.replace(/\n/g, EOL) + EOF } function stripBom$1 (content) { // we do this because JSON.parse would convert it to a utf8 string if encoding wasn't specified if (Buffer.isBuffer(content)) content = content.toString('utf8'); return content.replace(/^\uFEFF/, '') } var utils$2 = { stringify: stringify$3, stripBom: stripBom$1 }; let _fs; try { _fs = gracefulFs; } catch (_) { _fs = fs$j; } const universalify = universalify$1; const { stringify: stringify$2, stripBom } = utils$2; async function _readFile (file, options = {}) { if (typeof options === 'string') { options = { encoding: options }; } const fs = options.fs || _fs; const shouldThrow = 'throws' in options ? options.throws : true; let data = await universalify.fromCallback(fs.readFile)(file, options); data = stripBom(data); let obj; try { obj = JSON.parse(data, options ? options.reviver : null); } catch (err) { if (shouldThrow) { err.message = `${file}: ${err.message}`; throw err } else { return null } } return obj } const readFile = universalify.fromPromise(_readFile); function readFileSync (file, options = {}) { if (typeof options === 'string') { options = { encoding: options }; } const fs = options.fs || _fs; const shouldThrow = 'throws' in options ? options.throws : true; try { let content = fs.readFileSync(file, options); content = stripBom(content); return JSON.parse(content, options.reviver) } catch (err) { if (shouldThrow) { err.message = `${file}: ${err.message}`; throw err } else { return null } } } async function _writeFile (file, obj, options = {}) { const fs = options.fs || _fs; const str = stringify$2(obj, options); await universalify.fromCallback(fs.writeFile)(file, str, options); } const writeFile = universalify.fromPromise(_writeFile); function writeFileSync (file, obj, options = {}) { const fs = options.fs || _fs; const str = stringify$2(obj, options); // not sure if fs.writeFileSync returns anything, but just in case return fs.writeFileSync(file, str, options) } const jsonfile$1 = { readFile, readFileSync, writeFile, writeFileSync }; var jsonfile_1 = jsonfile$1; const jsonFile$1 = jsonfile_1; var jsonfile = { // jsonfile exports readJson: jsonFile$1.readFile, readJsonSync: jsonFile$1.readFileSync, writeJson: jsonFile$1.writeFile, writeJsonSync: jsonFile$1.writeFileSync }; const u$2 = universalify$1.fromPromise; const fs$2 = fs$h; const path$2 = require$$1$5; const mkdir = mkdirs$2; const pathExists$1 = pathExists_1.pathExists; async function outputFile$1 (file, data, encoding = 'utf-8') { const dir = path$2.dirname(file); if (!(await pathExists$1(dir))) { await mkdir.mkdirs(dir); } return fs$2.writeFile(file, data, encoding) } function outputFileSync$1 (file, ...args) { const dir = path$2.dirname(file); if (!fs$2.existsSync(dir)) { mkdir.mkdirsSync(dir); } fs$2.writeFileSync(file, ...args); } var outputFile_1 = { outputFile: u$2(outputFile$1), outputFileSync: outputFileSync$1 }; const { stringify: stringify$1 } = utils$2; const { outputFile } = outputFile_1; async function outputJson (file, data, options = {}) { const str = stringify$1(data, options); await outputFile(file, str, options); } var outputJson_1 = outputJson; const { stringify } = utils$2; const { outputFileSync } = outputFile_1; function outputJsonSync (file, data, options) { const str = stringify(data, options); outputFileSync(file, str, options); } var outputJsonSync_1 = outputJsonSync; const u$1 = universalify$1.fromPromise; const jsonFile = jsonfile; jsonFile.outputJson = u$1(outputJson_1); jsonFile.outputJsonSync = outputJsonSync_1; // aliases jsonFile.outputJSON = jsonFile.outputJson; jsonFile.outputJSONSync = jsonFile.outputJsonSync; jsonFile.writeJSON = jsonFile.writeJson; jsonFile.writeJSONSync = jsonFile.writeJsonSync; jsonFile.readJSON = jsonFile.readJson; jsonFile.readJSONSync = jsonFile.readJsonSync; var json$1 = jsonFile; const fs$1 = fs$h; const path$1 = require$$1$5; const { copy: copy$1 } = copy$2; const { remove } = remove_1; const { mkdirp } = mkdirs$2; const { pathExists } = pathExists_1; const stat$1 = stat$4; async function move$2 (src, dest, opts = {}) { const overwrite = opts.overwrite || opts.clobber || false; const { srcStat, isChangingCase = false } = await stat$1.checkPaths(src, dest, 'move', opts); await stat$1.checkParentPaths(src, srcStat, dest, 'move'); // If the parent of dest is not root, make sure it exists before proceeding const destParent = path$1.dirname(dest); const parsedParentPath = path$1.parse(destParent); if (parsedParentPath.root !== destParent) { await mkdirp(destParent); } return doRename$1(src, dest, overwrite, isChangingCase) } async function doRename$1 (src, dest, overwrite, isChangingCase) { if (!isChangingCase) { if (overwrite) { await remove(dest); } else if (await pathExists(dest)) { throw new Error('dest already exists.') } } try { // Try w/ rename first, and try copy + remove if EXDEV await fs$1.rename(src, dest); } catch (err) { if (err.code !== 'EXDEV') { throw err } await moveAcrossDevice$1(src, dest, overwrite); } } async function moveAcrossDevice$1 (src, dest, overwrite) { const opts = { overwrite, errorOnExist: true, preserveTimestamps: true }; await copy$1(src, dest, opts); return remove(src) } var move_1 = move$2; const fs = gracefulFs; const path = require$$1$5; const copySync = copy$2.copySync; const removeSync = remove_1.removeSync; const mkdirpSync = mkdirs$2.mkdirpSync; const stat = stat$4; function moveSync (src, dest, opts) { opts = opts || {}; const overwrite = opts.overwrite || opts.clobber || false; const { srcStat, isChangingCase = false } = stat.checkPathsSync(src, dest, 'move', opts); stat.checkParentPathsSync(src, srcStat, dest, 'move'); if (!isParentRoot(dest)) mkdirpSync(path.dirname(dest)); return doRename(src, dest, overwrite, isChangingCase) } function isParentRoot (dest) { const parent = path.dirname(dest); const parsedPath = path.parse(parent); return parsedPath.root === parent } function doRename (src, dest, overwrite, isChangingCase) { if (isChangingCase) return rename$1(src, dest, overwrite) if (overwrite) { removeSync(dest); return rename$1(src, dest, overwrite) } if (fs.existsSync(dest)) throw new Error('dest already exists.') return rename$1(src, dest, overwrite) } function rename$1 (src, dest, overwrite) { try { fs.renameSync(src, dest); } catch (err) { if (err.code !== 'EXDEV') throw err return moveAcrossDevice(src, dest, overwrite) } } function moveAcrossDevice (src, dest, overwrite) { const opts = { overwrite, errorOnExist: true, preserveTimestamps: true }; copySync(src, dest, opts); return removeSync(src) } var moveSync_1 = moveSync; const u = universalify$1.fromPromise; var move$1 = { move: u(move_1), moveSync: moveSync_1 }; var lib$1 = { // Export promiseified graceful-fs: ...fs$h, // Export extra methods: ...copy$2, ...empty, ...ensure, ...json$1, ...mkdirs$2, ...move$1, ...outputFile_1, ...pathExists_1, ...remove_1 }; var fse = /*@__PURE__*/getDefaultExportFromCjs(lib$1); /*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ function isNothing(subject) { return (typeof subject === 'undefined') || (subject === null); } function isObject$6(subject) { return (typeof subject === 'object') && (subject !== null); } function toArray(sequence) { if (Array.isArray(sequence)) return sequence; else if (isNothing(sequence)) return []; return [ sequence ]; } function extend(target, source) { var index, length, key, sourceKeys; if (source) { sourceKeys = Object.keys(source); for (index = 0, length = sourceKeys.length; index < length; index += 1) { key = sourceKeys[index]; target[key] = source[key]; } } return target; } function repeat(string, count) { var result = '', cycle; for (cycle = 0; cycle < count; cycle += 1) { result += string; } return result; } function isNegativeZero(number) { return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); } var isNothing_1 = isNothing; var isObject_1 = isObject$6; var toArray_1 = toArray; var repeat_1 = repeat; var isNegativeZero_1 = isNegativeZero; var extend_1 = extend; var common = { isNothing: isNothing_1, isObject: isObject_1, toArray: toArray_1, repeat: repeat_1, isNegativeZero: isNegativeZero_1, extend: extend_1 }; // YAML error class. http://stackoverflow.com/questions/8458984 function formatError(exception, compact) { var where = '', message = exception.reason || '(unknown reason)'; if (!exception.mark) return message; if (exception.mark.name) { where += 'in "' + exception.mark.name + '" '; } where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')'; if (!compact && exception.mark.snippet) { where += '\n\n' + exception.mark.snippet; } return message + ' ' + where; } function YAMLException$1(reason, mark) { // Super constructor Error.call(this); this.name = 'YAMLException'; this.reason = reason; this.mark = mark; this.message = formatError(this, false); // Include stack trace in error object if (Error.captureStackTrace) { // Chrome and NodeJS Error.captureStackTrace(this, this.constructor); } else { // FF, IE 10+ and Safari 6+. Fallback for others this.stack = (new Error()).stack || ''; } } // Inherit from Error YAMLException$1.prototype = Object.create(Error.prototype); YAMLException$1.prototype.constructor = YAMLException$1; YAMLException$1.prototype.toString = function toString(compact) { return this.name + ': ' + formatError(this, compact); }; var exception = YAMLException$1; // get snippet for a single line, respecting maxLength function getLine(buffer, lineStart, lineEnd, position, maxLineLength) { var head = ''; var tail = ''; var maxHalfLength = Math.floor(maxLineLength / 2) - 1; if (position - lineStart > maxHalfLength) { head = ' ... '; lineStart = position - maxHalfLength + head.length; } if (lineEnd - position > maxHalfLength) { tail = ' ...'; lineEnd = position + maxHalfLength - tail.length; } return { str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail, pos: position - lineStart + head.length // relative position }; } function padStart(string, max) { return common.repeat(' ', max - string.length) + string; } function makeSnippet(mark, options) { options = Object.create(options || null); if (!mark.buffer) return null; if (!options.maxLength) options.maxLength = 79; if (typeof options.indent !== 'number') options.indent = 1; if (typeof options.linesBefore !== 'number') options.linesBefore = 3; if (typeof options.linesAfter !== 'number') options.linesAfter = 2; var re = /\r?\n|\r|\0/g; var lineStarts = [ 0 ]; var lineEnds = []; var match; var foundLineNo = -1; while ((match = re.exec(mark.buffer))) { lineEnds.push(match.index); lineStarts.push(match.index + match[0].length); if (mark.position <= match.index && foundLineNo < 0) { foundLineNo = lineStarts.length - 2; } } if (foundLineNo < 0) foundLineNo = lineStarts.length - 1; var result = '', i, line; var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length; var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3); for (i = 1; i <= options.linesBefore; i++) { if (foundLineNo - i < 0) break; line = getLine( mark.buffer, lineStarts[foundLineNo - i], lineEnds[foundLineNo - i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), maxLineLength ); result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + ' | ' + line.str + '\n' + result; } line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength); result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + ' | ' + line.str + '\n'; result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n'; for (i = 1; i <= options.linesAfter; i++) { if (foundLineNo + i >= lineEnds.length) break; line = getLine( mark.buffer, lineStarts[foundLineNo + i], lineEnds[foundLineNo + i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), maxLineLength ); result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + ' | ' + line.str + '\n'; } return result.replace(/\n$/, ''); } var snippet = makeSnippet; var TYPE_CONSTRUCTOR_OPTIONS = [ 'kind', 'multi', 'resolve', 'construct', 'instanceOf', 'predicate', 'represent', 'representName', 'defaultStyle', 'styleAliases' ]; var YAML_NODE_KINDS = [ 'scalar', 'sequence', 'mapping' ]; function compileStyleAliases(map) { var result = {}; if (map !== null) { Object.keys(map).forEach(function (style) { map[style].forEach(function (alias) { result[String(alias)] = style; }); }); } return result; } function Type$1(tag, options) { options = options || {}; Object.keys(options).forEach(function (name) { if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { throw new exception('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); } }); // TODO: Add tag format check. this.options = options; // keep original options in case user wants to extend this type later this.tag = tag; this.kind = options['kind'] || null; this.resolve = options['resolve'] || function () { return true; }; this.construct = options['construct'] || function (data) { return data; }; this.instanceOf = options['instanceOf'] || null; this.predicate = options['predicate'] || null; this.represent = options['represent'] || null; this.representName = options['representName'] || null; this.defaultStyle = options['defaultStyle'] || null; this.multi = options['multi'] || false; this.styleAliases = compileStyleAliases(options['styleAliases'] || null); if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { throw new exception('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); } } var type$1 = Type$1; /*eslint-disable max-len*/ function compileList(schema, name) { var result = []; schema[name].forEach(function (currentType) { var newIndex = result.length; result.forEach(function (previousType, previousIndex) { if (previousType.tag === currentType.tag && previousType.kind === currentType.kind && previousType.multi === currentType.multi) { newIndex = previousIndex; } }); result[newIndex] = currentType; }); return result; } function compileMap(/* lists... */) { var result = { scalar: {}, sequence: {}, mapping: {}, fallback: {}, multi: { scalar: [], sequence: [], mapping: [], fallback: [] } }, index, length; function collectType(type) { if (type.multi) { result.multi[type.kind].push(type); result.multi['fallback'].push(type); } else { result[type.kind][type.tag] = result['fallback'][type.tag] = type; } } for (index = 0, length = arguments.length; index < length; index += 1) { arguments[index].forEach(collectType); } return result; } function Schema$1(definition) { return this.extend(definition); } Schema$1.prototype.extend = function extend(definition) { var implicit = []; var explicit = []; if (definition instanceof type$1) { // Schema.extend(type) explicit.push(definition); } else if (Array.isArray(definition)) { // Schema.extend([ type1, type2, ... ]) explicit = explicit.concat(definition); } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) { // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] }) if (definition.implicit) implicit = implicit.concat(definition.implicit); if (definition.explicit) explicit = explicit.concat(definition.explicit); } else { throw new exception('Schema.extend argument should be a Type, [ Type ], ' + 'or a schema definition ({ implicit: [...], explicit: [...] })'); } implicit.forEach(function (type$1$1) { if (!(type$1$1 instanceof type$1)) { throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); } if (type$1$1.loadKind && type$1$1.loadKind !== 'scalar') { throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); } if (type$1$1.multi) { throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.'); } }); explicit.forEach(function (type$1$1) { if (!(type$1$1 instanceof type$1)) { throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); } }); var result = Object.create(Schema$1.prototype); result.implicit = (this.implicit || []).concat(implicit); result.explicit = (this.explicit || []).concat(explicit); result.compiledImplicit = compileList(result, 'implicit'); result.compiledExplicit = compileList(result, 'explicit'); result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit); return result; }; var schema = Schema$1; var str = new type$1('tag:yaml.org,2002:str', { kind: 'scalar', construct: function (data) { return data !== null ? data : ''; } }); var seq = new type$1('tag:yaml.org,2002:seq', { kind: 'sequence', construct: function (data) { return data !== null ? data : []; } }); var map = new type$1('tag:yaml.org,2002:map', { kind: 'mapping', construct: function (data) { return data !== null ? data : {}; } }); var failsafe = new schema({ explicit: [ str, seq, map ] }); function resolveYamlNull(data) { if (data === null) return true; var max = data.length; return (max === 1 && data === '~') || (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); } function constructYamlNull() { return null; } function isNull(object) { return object === null; } var _null = new type$1('tag:yaml.org,2002:null', { kind: 'scalar', resolve: resolveYamlNull, construct: constructYamlNull, predicate: isNull, represent: { canonical: function () { return '~'; }, lowercase: function () { return 'null'; }, uppercase: function () { return 'NULL'; }, camelcase: function () { return 'Null'; }, empty: function () { return ''; } }, defaultStyle: 'lowercase' }); function resolveYamlBoolean(data) { if (data === null) return false; var max = data.length; return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); } function constructYamlBoolean(data) { return data === 'true' || data === 'True' || data === 'TRUE'; } function isBoolean$2(object) { return Object.prototype.toString.call(object) === '[object Boolean]'; } var bool = new type$1('tag:yaml.org,2002:bool', { kind: 'scalar', resolve: resolveYamlBoolean, construct: constructYamlBoolean, predicate: isBoolean$2, represent: { lowercase: function (object) { return object ? 'true' : 'false'; }, uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, camelcase: function (object) { return object ? 'True' : 'False'; } }, defaultStyle: 'lowercase' }); function isHexCode(c) { return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || ((0x61/* a */ <= c) && (c <= 0x66/* f */)); } function isOctCode(c) { return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); } function isDecCode(c) { return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); } function resolveYamlInteger(data) { if (data === null) return false; var max = data.length, index = 0, hasDigits = false, ch; if (!max) return false; ch = data[index]; // sign if (ch === '-' || ch === '+') { ch = data[++index]; } if (ch === '0') { // 0 if (index + 1 === max) return true; ch = data[++index]; // base 2, base 8, base 16 if (ch === 'b') { // base 2 index++; for (; index < max; index++) { ch = data[index]; if (ch === '_') continue; if (ch !== '0' && ch !== '1') return false; hasDigits = true; } return hasDigits && ch !== '_'; } if (ch === 'x') { // base 16 index++; for (; index < max; index++) { ch = data[index]; if (ch === '_') continue; if (!isHexCode(data.charCodeAt(index))) return false; hasDigits = true; } return hasDigits && ch !== '_'; } if (ch === 'o') { // base 8 index++; for (; index < max; index++) { ch = data[index]; if (ch === '_') continue; if (!isOctCode(data.charCodeAt(index))) return false; hasDigits = true; } return hasDigits && ch !== '_'; } } // base 10 (except 0) // value should not start with `_`; if (ch === '_') return false; for (; index < max; index++) { ch = data[index]; if (ch === '_') continue; if (!isDecCode(data.charCodeAt(index))) { return false; } hasDigits = true; } // Should have digits and should not end with `_` if (!hasDigits || ch === '_') return false; return true; } function constructYamlInteger(data) { var value = data, sign = 1, ch; if (value.indexOf('_') !== -1) { value = value.replace(/_/g, ''); } ch = value[0]; if (ch === '-' || ch === '+') { if (ch === '-') sign = -1; value = value.slice(1); ch = value[0]; } if (value === '0') return 0; if (ch === '0') { if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); if (value[1] === 'x') return sign * parseInt(value.slice(2), 16); if (value[1] === 'o') return sign * parseInt(value.slice(2), 8); } return sign * parseInt(value, 10); } function isInteger$2(object) { return (Object.prototype.toString.call(object)) === '[object Number]' && (object % 1 === 0 && !common.isNegativeZero(object)); } var int = new type$1('tag:yaml.org,2002:int', { kind: 'scalar', resolve: resolveYamlInteger, construct: constructYamlInteger, predicate: isInteger$2, represent: { binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); }, octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); }, decimal: function (obj) { return obj.toString(10); }, /* eslint-disable max-len */ hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); } }, defaultStyle: 'decimal', styleAliases: { binary: [ 2, 'bin' ], octal: [ 8, 'oct' ], decimal: [ 10, 'dec' ], hexadecimal: [ 16, 'hex' ] } }); var YAML_FLOAT_PATTERN = new RegExp( // 2.5e4, 2.5 and integers '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' + // .2e4, .2 // special case, seems not from spec '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' + // .inf '|[-+]?\\.(?:inf|Inf|INF)' + // .nan '|\\.(?:nan|NaN|NAN))$'); function resolveYamlFloat(data) { if (data === null) return false; if (!YAML_FLOAT_PATTERN.test(data) || // Quick hack to not allow integers end with `_` // Probably should update regexp & check speed data[data.length - 1] === '_') { return false; } return true; } function constructYamlFloat(data) { var value, sign; value = data.replace(/_/g, '').toLowerCase(); sign = value[0] === '-' ? -1 : 1; if ('+-'.indexOf(value[0]) >= 0) { value = value.slice(1); } if (value === '.inf') { return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; } else if (value === '.nan') { return NaN; } return sign * parseFloat(value, 10); } var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; function representYamlFloat(object, style) { var res; if (isNaN(object)) { switch (style) { case 'lowercase': return '.nan'; case 'uppercase': return '.NAN'; case 'camelcase': return '.NaN'; } } else if (Number.POSITIVE_INFINITY === object) { switch (style) { case 'lowercase': return '.inf'; case 'uppercase': return '.INF'; case 'camelcase': return '.Inf'; } } else if (Number.NEGATIVE_INFINITY === object) { switch (style) { case 'lowercase': return '-.inf'; case 'uppercase': return '-.INF'; case 'camelcase': return '-.Inf'; } } else if (common.isNegativeZero(object)) { return '-0.0'; } res = object.toString(10); // JS stringifier can build scientific format without dots: 5e-100, // while YAML requres dot: 5.e-100. Fix it with simple hack return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; } function isFloat(object) { return (Object.prototype.toString.call(object) === '[object Number]') && (object % 1 !== 0 || common.isNegativeZero(object)); } var float = new type$1('tag:yaml.org,2002:float', { kind: 'scalar', resolve: resolveYamlFloat, construct: constructYamlFloat, predicate: isFloat, represent: representYamlFloat, defaultStyle: 'lowercase' }); var json = failsafe.extend({ implicit: [ _null, bool, int, float ] }); var core = json; var YAML_DATE_REGEXP = new RegExp( '^([0-9][0-9][0-9][0-9])' + // [1] year '-([0-9][0-9])' + // [2] month '-([0-9][0-9])$'); // [3] day var YAML_TIMESTAMP_REGEXP = new RegExp( '^([0-9][0-9][0-9][0-9])' + // [1] year '-([0-9][0-9]?)' + // [2] month '-([0-9][0-9]?)' + // [3] day '(?:[Tt]|[ \\t]+)' + // ... '([0-9][0-9]?)' + // [4] hour ':([0-9][0-9])' + // [5] minute ':([0-9][0-9])' + // [6] second '(?:\\.([0-9]*))?' + // [7] fraction '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour '(?::([0-9][0-9]))?))?$'); // [11] tz_minute function resolveYamlTimestamp(data) { if (data === null) return false; if (YAML_DATE_REGEXP.exec(data) !== null) return true; if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; return false; } function constructYamlTimestamp(data) { var match, year, month, day, hour, minute, second, fraction = 0, delta = null, tz_hour, tz_minute, date; match = YAML_DATE_REGEXP.exec(data); if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); if (match === null) throw new Error('Date resolve error'); // match: [1] year [2] month [3] day year = +(match[1]); month = +(match[2]) - 1; // JS month starts with 0 day = +(match[3]); if (!match[4]) { // no hour return new Date(Date.UTC(year, month, day)); } // match: [4] hour [5] minute [6] second [7] fraction hour = +(match[4]); minute = +(match[5]); second = +(match[6]); if (match[7]) { fraction = match[7].slice(0, 3); while (fraction.length < 3) { // milli-seconds fraction += '0'; } fraction = +fraction; } // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute if (match[9]) { tz_hour = +(match[10]); tz_minute = +(match[11] || 0); delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds if (match[9] === '-') delta = -delta; } date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); if (delta) date.setTime(date.getTime() - delta); return date; } function representYamlTimestamp(object /*, style*/) { return object.toISOString(); } var timestamp = new type$1('tag:yaml.org,2002:timestamp', { kind: 'scalar', resolve: resolveYamlTimestamp, construct: constructYamlTimestamp, instanceOf: Date, represent: representYamlTimestamp }); function resolveYamlMerge(data) { return data === '<<' || data === null; } var merge = new type$1('tag:yaml.org,2002:merge', { kind: 'scalar', resolve: resolveYamlMerge }); /*eslint-disable no-bitwise*/ // [ 64, 65, 66 ] -> [ padding, CR, LF ] var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; function resolveYamlBinary(data) { if (data === null) return false; var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; // Convert one by one. for (idx = 0; idx < max; idx++) { code = map.indexOf(data.charAt(idx)); // Skip CR/LF if (code > 64) continue; // Fail on illegal characters if (code < 0) return false; bitlen += 6; } // If there are any bits left, source was corrupted return (bitlen % 8) === 0; } function constructYamlBinary(data) { var idx, tailbits, input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan max = input.length, map = BASE64_MAP, bits = 0, result = []; // Collect by 6*4 bits (3 bytes) for (idx = 0; idx < max; idx++) { if ((idx % 4 === 0) && idx) { result.push((bits >> 16) & 0xFF); result.push((bits >> 8) & 0xFF); result.push(bits & 0xFF); } bits = (bits << 6) | map.indexOf(input.charAt(idx)); } // Dump tail tailbits = (max % 4) * 6; if (tailbits === 0) { result.push((bits >> 16) & 0xFF); result.push((bits >> 8) & 0xFF); result.push(bits & 0xFF); } else if (tailbits === 18) { result.push((bits >> 10) & 0xFF); result.push((bits >> 2) & 0xFF); } else if (tailbits === 12) { result.push((bits >> 4) & 0xFF); } return new Uint8Array(result); } function representYamlBinary(object /*, style*/) { var result = '', bits = 0, idx, tail, max = object.length, map = BASE64_MAP; // Convert every three bytes to 4 ASCII characters. for (idx = 0; idx < max; idx++) { if ((idx % 3 === 0) && idx) { result += map[(bits >> 18) & 0x3F]; result += map[(bits >> 12) & 0x3F]; result += map[(bits >> 6) & 0x3F]; result += map[bits & 0x3F]; } bits = (bits << 8) + object[idx]; } // Dump tail tail = max % 3; if (tail === 0) { result += map[(bits >> 18) & 0x3F]; result += map[(bits >> 12) & 0x3F]; result += map[(bits >> 6) & 0x3F]; result += map[bits & 0x3F]; } else if (tail === 2) { result += map[(bits >> 10) & 0x3F]; result += map[(bits >> 4) & 0x3F]; result += map[(bits << 2) & 0x3F]; result += map[64]; } else if (tail === 1) { result += map[(bits >> 2) & 0x3F]; result += map[(bits << 4) & 0x3F]; result += map[64]; result += map[64]; } return result; } function isBinary(obj) { return Object.prototype.toString.call(obj) === '[object Uint8Array]'; } var binary = new type$1('tag:yaml.org,2002:binary', { kind: 'scalar', resolve: resolveYamlBinary, construct: constructYamlBinary, predicate: isBinary, represent: representYamlBinary }); var _hasOwnProperty$3 = Object.prototype.hasOwnProperty; var _toString$2 = Object.prototype.toString; function resolveYamlOmap(data) { if (data === null) return true; var objectKeys = [], index, length, pair, pairKey, pairHasKey, object = data; for (index = 0, length = object.length; index < length; index += 1) { pair = object[index]; pairHasKey = false; if (_toString$2.call(pair) !== '[object Object]') return false; for (pairKey in pair) { if (_hasOwnProperty$3.call(pair, pairKey)) { if (!pairHasKey) pairHasKey = true; else return false; } } if (!pairHasKey) return false; if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); else return false; } return true; } function constructYamlOmap(data) { return data !== null ? data : []; } var omap = new type$1('tag:yaml.org,2002:omap', { kind: 'sequence', resolve: resolveYamlOmap, construct: constructYamlOmap }); var _toString$1 = Object.prototype.toString; function resolveYamlPairs(data) { if (data === null) return true; var index, length, pair, keys, result, object = data; result = new Array(object.length); for (index = 0, length = object.length; index < length; index += 1) { pair = object[index]; if (_toString$1.call(pair) !== '[object Object]') return false; keys = Object.keys(pair); if (keys.length !== 1) return false; result[index] = [ keys[0], pair[keys[0]] ]; } return true; } function constructYamlPairs(data) { if (data === null) return []; var index, length, pair, keys, result, object = data; result = new Array(object.length); for (index = 0, length = object.length; index < length; index += 1) { pair = object[index]; keys = Object.keys(pair); result[index] = [ keys[0], pair[keys[0]] ]; } return result; } var pairs = new type$1('tag:yaml.org,2002:pairs', { kind: 'sequence', resolve: resolveYamlPairs, construct: constructYamlPairs }); var _hasOwnProperty$2 = Object.prototype.hasOwnProperty; function resolveYamlSet(data) { if (data === null) return true; var key, object = data; for (key in object) { if (_hasOwnProperty$2.call(object, key)) { if (object[key] !== null) return false; } } return true; } function constructYamlSet(data) { return data !== null ? data : {}; } var set$1 = new type$1('tag:yaml.org,2002:set', { kind: 'mapping', resolve: resolveYamlSet, construct: constructYamlSet }); var _default = core.extend({ implicit: [ timestamp, merge ], explicit: [ binary, omap, pairs, set$1 ] }); /*eslint-disable max-len,no-use-before-define*/ var _hasOwnProperty$1 = Object.prototype.hasOwnProperty; var CONTEXT_FLOW_IN = 1; var CONTEXT_FLOW_OUT = 2; var CONTEXT_BLOCK_IN = 3; var CONTEXT_BLOCK_OUT = 4; var CHOMPING_CLIP = 1; var CHOMPING_STRIP = 2; var CHOMPING_KEEP = 3; var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; function _class(obj) { return Object.prototype.toString.call(obj); } function is_EOL(c) { return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); } function is_WHITE_SPACE(c) { return (c === 0x09/* Tab */) || (c === 0x20/* Space */); } function is_WS_OR_EOL(c) { return (c === 0x09/* Tab */) || (c === 0x20/* Space */) || (c === 0x0A/* LF */) || (c === 0x0D/* CR */); } function is_FLOW_INDICATOR(c) { return c === 0x2C/* , */ || c === 0x5B/* [ */ || c === 0x5D/* ] */ || c === 0x7B/* { */ || c === 0x7D/* } */; } function fromHexCode(c) { var lc; if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { return c - 0x30; } /*eslint-disable no-bitwise*/ lc = c | 0x20; if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { return lc - 0x61 + 10; } return -1; } function escapedHexLen(c) { if (c === 0x78/* x */) { return 2; } if (c === 0x75/* u */) { return 4; } if (c === 0x55/* U */) { return 8; } return 0; } function fromDecimalCode(c) { if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { return c - 0x30; } return -1; } function simpleEscapeSequence(c) { /* eslint-disable indent */ return (c === 0x30/* 0 */) ? '\x00' : (c === 0x61/* a */) ? '\x07' : (c === 0x62/* b */) ? '\x08' : (c === 0x74/* t */) ? '\x09' : (c === 0x09/* Tab */) ? '\x09' : (c === 0x6E/* n */) ? '\x0A' : (c === 0x76/* v */) ? '\x0B' : (c === 0x66/* f */) ? '\x0C' : (c === 0x72/* r */) ? '\x0D' : (c === 0x65/* e */) ? '\x1B' : (c === 0x20/* Space */) ? ' ' : (c === 0x22/* " */) ? '\x22' : (c === 0x2F/* / */) ? '/' : (c === 0x5C/* \ */) ? '\x5C' : (c === 0x4E/* N */) ? '\x85' : (c === 0x5F/* _ */) ? '\xA0' : (c === 0x4C/* L */) ? '\u2028' : (c === 0x50/* P */) ? '\u2029' : ''; } function charFromCodepoint(c) { if (c <= 0xFFFF) { return String.fromCharCode(c); } // Encode UTF-16 surrogate pair // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF return String.fromCharCode( ((c - 0x010000) >> 10) + 0xD800, ((c - 0x010000) & 0x03FF) + 0xDC00 ); } var simpleEscapeCheck = new Array(256); // integer, for fast access var simpleEscapeMap = new Array(256); for (var i = 0; i < 256; i++) { simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; simpleEscapeMap[i] = simpleEscapeSequence(i); } function State$1(input, options) { this.input = input; this.filename = options['filename'] || null; this.schema = options['schema'] || _default; this.onWarning = options['onWarning'] || null; // (Hidden) Remove? makes the loader to expect YAML 1.1 documents // if such documents have no explicit %YAML directive this.legacy = options['legacy'] || false; this.json = options['json'] || false; this.listener = options['listener'] || null; this.implicitTypes = this.schema.compiledImplicit; this.typeMap = this.schema.compiledTypeMap; this.length = input.length; this.position = 0; this.line = 0; this.lineStart = 0; this.lineIndent = 0; // position of first leading tab in the current line, // used to make sure there are no tabs in the indentation this.firstTabInLine = -1; this.documents = []; /* this.version; this.checkLineBreaks; this.tagMap; this.anchorMap; this.tag; this.anchor; this.kind; this.result;*/ } function generateError(state, message) { var mark = { name: state.filename, buffer: state.input.slice(0, -1), // omit trailing \0 position: state.position, line: state.line, column: state.position - state.lineStart }; mark.snippet = snippet(mark); return new exception(message, mark); } function throwError(state, message) { throw generateError(state, message); } function throwWarning(state, message) { if (state.onWarning) { state.onWarning.call(null, generateError(state, message)); } } var directiveHandlers = { YAML: function handleYamlDirective(state, name, args) { var match, major, minor; if (state.version !== null) { throwError(state, 'duplication of %YAML directive'); } if (args.length !== 1) { throwError(state, 'YAML directive accepts exactly one argument'); } match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); if (match === null) { throwError(state, 'ill-formed argument of the YAML directive'); } major = parseInt(match[1], 10); minor = parseInt(match[2], 10); if (major !== 1) { throwError(state, 'unacceptable YAML version of the document'); } state.version = args[0]; state.checkLineBreaks = (minor < 2); if (minor !== 1 && minor !== 2) { throwWarning(state, 'unsupported YAML version of the document'); } }, TAG: function handleTagDirective(state, name, args) { var handle, prefix; if (args.length !== 2) { throwError(state, 'TAG directive accepts exactly two arguments'); } handle = args[0]; prefix = args[1]; if (!PATTERN_TAG_HANDLE.test(handle)) { throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); } if (_hasOwnProperty$1.call(state.tagMap, handle)) { throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); } if (!PATTERN_TAG_URI.test(prefix)) { throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); } try { prefix = decodeURIComponent(prefix); } catch (err) { throwError(state, 'tag prefix is malformed: ' + prefix); } state.tagMap[handle] = prefix; } }; function captureSegment(state, start, end, checkJson) { var _position, _length, _character, _result; if (start < end) { _result = state.input.slice(start, end); if (checkJson) { for (_position = 0, _length = _result.length; _position < _length; _position += 1) { _character = _result.charCodeAt(_position); if (!(_character === 0x09 || (0x20 <= _character && _character <= 0x10FFFF))) { throwError(state, 'expected valid JSON character'); } } } else if (PATTERN_NON_PRINTABLE.test(_result)) { throwError(state, 'the stream contains non-printable characters'); } state.result += _result; } } function mergeMappings(state, destination, source, overridableKeys) { var sourceKeys, key, index, quantity; if (!common.isObject(source)) { throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); } sourceKeys = Object.keys(source); for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { key = sourceKeys[index]; if (!_hasOwnProperty$1.call(destination, key)) { destination[key] = source[key]; overridableKeys[key] = true; } } } function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, startLine, startLineStart, startPos) { var index, quantity; // The output is a plain object here, so keys can only be strings. // We need to convert keyNode to a string, but doing so can hang the process // (deeply nested arrays that explode exponentially using aliases). if (Array.isArray(keyNode)) { keyNode = Array.prototype.slice.call(keyNode); for (index = 0, quantity = keyNode.length; index < quantity; index += 1) { if (Array.isArray(keyNode[index])) { throwError(state, 'nested arrays are not supported inside keys'); } if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') { keyNode[index] = '[object Object]'; } } } // Avoid code execution in load() via toString property // (still use its own toString for arrays, timestamps, // and whatever user schema extensions happen to have @@toStringTag) if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') { keyNode = '[object Object]'; } keyNode = String(keyNode); if (_result === null) { _result = {}; } if (keyTag === 'tag:yaml.org,2002:merge') { if (Array.isArray(valueNode)) { for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { mergeMappings(state, _result, valueNode[index], overridableKeys); } } else { mergeMappings(state, _result, valueNode, overridableKeys); } } else { if (!state.json && !_hasOwnProperty$1.call(overridableKeys, keyNode) && _hasOwnProperty$1.call(_result, keyNode)) { state.line = startLine || state.line; state.lineStart = startLineStart || state.lineStart; state.position = startPos || state.position; throwError(state, 'duplicated mapping key'); } // used for this specific key only because Object.defineProperty is slow if (keyNode === '__proto__') { Object.defineProperty(_result, keyNode, { configurable: true, enumerable: true, writable: true, value: valueNode }); } else { _result[keyNode] = valueNode; } delete overridableKeys[keyNode]; } return _result; } function readLineBreak(state) { var ch; ch = state.input.charCodeAt(state.position); if (ch === 0x0A/* LF */) { state.position++; } else if (ch === 0x0D/* CR */) { state.position++; if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { state.position++; } } else { throwError(state, 'a line break is expected'); } state.line += 1; state.lineStart = state.position; state.firstTabInLine = -1; } function skipSeparationSpace(state, allowComments, checkIndent) { var lineBreaks = 0, ch = state.input.charCodeAt(state.position); while (ch !== 0) { while (is_WHITE_SPACE(ch)) { if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) { state.firstTabInLine = state.position; } ch = state.input.charCodeAt(++state.position); } if (allowComments && ch === 0x23/* # */) { do { ch = state.input.charCodeAt(++state.position); } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); } if (is_EOL(ch)) { readLineBreak(state); ch = state.input.charCodeAt(state.position); lineBreaks++; state.lineIndent = 0; while (ch === 0x20/* Space */) { state.lineIndent++; ch = state.input.charCodeAt(++state.position); } } else { break; } } if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { throwWarning(state, 'deficient indentation'); } return lineBreaks; } function testDocumentSeparator(state) { var _position = state.position, ch; ch = state.input.charCodeAt(_position); // Condition state.position === state.lineStart is tested // in parent on each call, for efficiency. No needs to test here again. if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && ch === state.input.charCodeAt(_position + 1) && ch === state.input.charCodeAt(_position + 2)) { _position += 3; ch = state.input.charCodeAt(_position); if (ch === 0 || is_WS_OR_EOL(ch)) { return true; } } return false; } function writeFoldedLines(state, count) { if (count === 1) { state.result += ' '; } else if (count > 1) { state.result += common.repeat('\n', count - 1); } } function readPlainScalar(state, nodeIndent, withinFlowCollection) { var preceding, following, captureStart, captureEnd, hasPendingContent, _line, _lineStart, _lineIndent, _kind = state.kind, _result = state.result, ch; ch = state.input.charCodeAt(state.position); if (is_WS_OR_EOL(ch) || is_FLOW_INDICATOR(ch) || ch === 0x23/* # */ || ch === 0x26/* & */ || ch === 0x2A/* * */ || ch === 0x21/* ! */ || ch === 0x7C/* | */ || ch === 0x3E/* > */ || ch === 0x27/* ' */ || ch === 0x22/* " */ || ch === 0x25/* % */ || ch === 0x40/* @ */ || ch === 0x60/* ` */) { return false; } if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { following = state.input.charCodeAt(state.position + 1); if (is_WS_OR_EOL(following) || withinFlowCollection && is_FLOW_INDICATOR(following)) { return false; } } state.kind = 'scalar'; state.result = ''; captureStart = captureEnd = state.position; hasPendingContent = false; while (ch !== 0) { if (ch === 0x3A/* : */) { following = state.input.charCodeAt(state.position + 1); if (is_WS_OR_EOL(following) || withinFlowCollection && is_FLOW_INDICATOR(following)) { break; } } else if (ch === 0x23/* # */) { preceding = state.input.charCodeAt(state.position - 1); if (is_WS_OR_EOL(preceding)) { break; } } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || withinFlowCollection && is_FLOW_INDICATOR(ch)) { break; } else if (is_EOL(ch)) { _line = state.line; _lineStart = state.lineStart; _lineIndent = state.lineIndent; skipSeparationSpace(state, false, -1); if (state.lineIndent >= nodeIndent) { hasPendingContent = true; ch = state.input.charCodeAt(state.position); continue; } else { state.position = captureEnd; state.line = _line; state.lineStart = _lineStart; state.lineIndent = _lineIndent; break; } } if (hasPendingContent) { captureSegment(state, captureStart, captureEnd, false); writeFoldedLines(state, state.line - _line); captureStart = captureEnd = state.position; hasPendingContent = false; } if (!is_WHITE_SPACE(ch)) { captureEnd = state.position + 1; } ch = state.input.charCodeAt(++state.position); } captureSegment(state, captureStart, captureEnd, false); if (state.result) { return true; } state.kind = _kind; state.result = _result; return false; } function readSingleQuotedScalar(state, nodeIndent) { var ch, captureStart, captureEnd; ch = state.input.charCodeAt(state.position); if (ch !== 0x27/* ' */) { return false; } state.kind = 'scalar'; state.result = ''; state.position++; captureStart = captureEnd = state.position; while ((ch = state.input.charCodeAt(state.position)) !== 0) { if (ch === 0x27/* ' */) { captureSegment(state, captureStart, state.position, true); ch = state.input.charCodeAt(++state.position); if (ch === 0x27/* ' */) { captureStart = state.position; state.position++; captureEnd = state.position; } else { return true; } } else if (is_EOL(ch)) { captureSegment(state, captureStart, captureEnd, true); writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); captureStart = captureEnd = state.position; } else if (state.position === state.lineStart && testDocumentSeparator(state)) { throwError(state, 'unexpected end of the document within a single quoted scalar'); } else { state.position++; captureEnd = state.position; } } throwError(state, 'unexpected end of the stream within a single quoted scalar'); } function readDoubleQuotedScalar(state, nodeIndent) { var captureStart, captureEnd, hexLength, hexResult, tmp, ch; ch = state.input.charCodeAt(state.position); if (ch !== 0x22/* " */) { return false; } state.kind = 'scalar'; state.result = ''; state.position++; captureStart = captureEnd = state.position; while ((ch = state.input.charCodeAt(state.position)) !== 0) { if (ch === 0x22/* " */) { captureSegment(state, captureStart, state.position, true); state.position++; return true; } else if (ch === 0x5C/* \ */) { captureSegment(state, captureStart, state.position, true); ch = state.input.charCodeAt(++state.position); if (is_EOL(ch)) { skipSeparationSpace(state, false, nodeIndent); // TODO: rework to inline fn with no type cast? } else if (ch < 256 && simpleEscapeCheck[ch]) { state.result += simpleEscapeMap[ch]; state.position++; } else if ((tmp = escapedHexLen(ch)) > 0) { hexLength = tmp; hexResult = 0; for (; hexLength > 0; hexLength--) { ch = state.input.charCodeAt(++state.position); if ((tmp = fromHexCode(ch)) >= 0) { hexResult = (hexResult << 4) + tmp; } else { throwError(state, 'expected hexadecimal character'); } } state.result += charFromCodepoint(hexResult); state.position++; } else { throwError(state, 'unknown escape sequence'); } captureStart = captureEnd = state.position; } else if (is_EOL(ch)) { captureSegment(state, captureStart, captureEnd, true); writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); captureStart = captureEnd = state.position; } else if (state.position === state.lineStart && testDocumentSeparator(state)) { throwError(state, 'unexpected end of the document within a double quoted scalar'); } else { state.position++; captureEnd = state.position; } } throwError(state, 'unexpected end of the stream within a double quoted scalar'); } function readFlowCollection(state, nodeIndent) { var readNext = true, _line, _lineStart, _pos, _tag = state.tag, _result, _anchor = state.anchor, following, terminator, isPair, isExplicitPair, isMapping, overridableKeys = Object.create(null), keyNode, keyTag, valueNode, ch; ch = state.input.charCodeAt(state.position); if (ch === 0x5B/* [ */) { terminator = 0x5D;/* ] */ isMapping = false; _result = []; } else if (ch === 0x7B/* { */) { terminator = 0x7D;/* } */ isMapping = true; _result = {}; } else { return false; } if (state.anchor !== null) { state.anchorMap[state.anchor] = _result; } ch = state.input.charCodeAt(++state.position); while (ch !== 0) { skipSeparationSpace(state, true, nodeIndent); ch = state.input.charCodeAt(state.position); if (ch === terminator) { state.position++; state.tag = _tag; state.anchor = _anchor; state.kind = isMapping ? 'mapping' : 'sequence'; state.result = _result; return true; } else if (!readNext) { throwError(state, 'missed comma between flow collection entries'); } else if (ch === 0x2C/* , */) { // "flow collection entries can never be completely empty", as per YAML 1.2, section 7.4 throwError(state, "expected the node content, but found ','"); } keyTag = keyNode = valueNode = null; isPair = isExplicitPair = false; if (ch === 0x3F/* ? */) { following = state.input.charCodeAt(state.position + 1); if (is_WS_OR_EOL(following)) { isPair = isExplicitPair = true; state.position++; skipSeparationSpace(state, true, nodeIndent); } } _line = state.line; // Save the current line. _lineStart = state.lineStart; _pos = state.position; composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); keyTag = state.tag; keyNode = state.result; skipSeparationSpace(state, true, nodeIndent); ch = state.input.charCodeAt(state.position); if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { isPair = true; ch = state.input.charCodeAt(++state.position); skipSeparationSpace(state, true, nodeIndent); composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); valueNode = state.result; } if (isMapping) { storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos); } else if (isPair) { _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos)); } else { _result.push(keyNode); } skipSeparationSpace(state, true, nodeIndent); ch = state.input.charCodeAt(state.position); if (ch === 0x2C/* , */) { readNext = true; ch = state.input.charCodeAt(++state.position); } else { readNext = false; } } throwError(state, 'unexpected end of the stream within a flow collection'); } function readBlockScalar(state, nodeIndent) { var captureStart, folding, chomping = CHOMPING_CLIP, didReadContent = false, detectedIndent = false, textIndent = nodeIndent, emptyLines = 0, atMoreIndented = false, tmp, ch; ch = state.input.charCodeAt(state.position); if (ch === 0x7C/* | */) { folding = false; } else if (ch === 0x3E/* > */) { folding = true; } else { return false; } state.kind = 'scalar'; state.result = ''; while (ch !== 0) { ch = state.input.charCodeAt(++state.position); if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { if (CHOMPING_CLIP === chomping) { chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; } else { throwError(state, 'repeat of a chomping mode identifier'); } } else if ((tmp = fromDecimalCode(ch)) >= 0) { if (tmp === 0) { throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); } else if (!detectedIndent) { textIndent = nodeIndent + tmp - 1; detectedIndent = true; } else { throwError(state, 'repeat of an indentation width identifier'); } } else { break; } } if (is_WHITE_SPACE(ch)) { do { ch = state.input.charCodeAt(++state.position); } while (is_WHITE_SPACE(ch)); if (ch === 0x23/* # */) { do { ch = state.input.charCodeAt(++state.position); } while (!is_EOL(ch) && (ch !== 0)); } } while (ch !== 0) { readLineBreak(state); state.lineIndent = 0; ch = state.input.charCodeAt(state.position); while ((!detectedIndent || state.lineIndent < textIndent) && (ch === 0x20/* Space */)) { state.lineIndent++; ch = state.input.charCodeAt(++state.position); } if (!detectedIndent && state.lineIndent > textIndent) { textIndent = state.lineIndent; } if (is_EOL(ch)) { emptyLines++; continue; } // End of the scalar. if (state.lineIndent < textIndent) { // Perform the chomping. if (chomping === CHOMPING_KEEP) { state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); } else if (chomping === CHOMPING_CLIP) { if (didReadContent) { // i.e. only if the scalar is not empty. state.result += '\n'; } } // Break this `while` cycle and go to the funciton's epilogue. break; } // Folded style: use fancy rules to handle line breaks. if (folding) { // Lines starting with white space characters (more-indented lines) are not folded. if (is_WHITE_SPACE(ch)) { atMoreIndented = true; // except for the first content line (cf. Example 8.1) state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); // End of more-indented block. } else if (atMoreIndented) { atMoreIndented = false; state.result += common.repeat('\n', emptyLines + 1); // Just one line break - perceive as the same line. } else if (emptyLines === 0) { if (didReadContent) { // i.e. only if we have already read some scalar content. state.result += ' '; } // Several line breaks - perceive as different lines. } else { state.result += common.repeat('\n', emptyLines); } // Literal style: just add exact number of line breaks between content lines. } else { // Keep all line breaks except the header line break. state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); } didReadContent = true; detectedIndent = true; emptyLines = 0; captureStart = state.position; while (!is_EOL(ch) && (ch !== 0)) { ch = state.input.charCodeAt(++state.position); } captureSegment(state, captureStart, state.position, false); } return true; } function readBlockSequence(state, nodeIndent) { var _line, _tag = state.tag, _anchor = state.anchor, _result = [], following, detected = false, ch; // there is a leading tab before this token, so it can't be a block sequence/mapping; // it can still be flow sequence/mapping or a scalar if (state.firstTabInLine !== -1) return false; if (state.anchor !== null) { state.anchorMap[state.anchor] = _result; } ch = state.input.charCodeAt(state.position); while (ch !== 0) { if (state.firstTabInLine !== -1) { state.position = state.firstTabInLine; throwError(state, 'tab characters must not be used in indentation'); } if (ch !== 0x2D/* - */) { break; } following = state.input.charCodeAt(state.position + 1); if (!is_WS_OR_EOL(following)) { break; } detected = true; state.position++; if (skipSeparationSpace(state, true, -1)) { if (state.lineIndent <= nodeIndent) { _result.push(null); ch = state.input.charCodeAt(state.position); continue; } } _line = state.line; composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); _result.push(state.result); skipSeparationSpace(state, true, -1); ch = state.input.charCodeAt(state.position); if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { throwError(state, 'bad indentation of a sequence entry'); } else if (state.lineIndent < nodeIndent) { break; } } if (detected) { state.tag = _tag; state.anchor = _anchor; state.kind = 'sequence'; state.result = _result; return true; } return false; } function readBlockMapping(state, nodeIndent, flowIndent) { var following, allowCompact, _line, _keyLine, _keyLineStart, _keyPos, _tag = state.tag, _anchor = state.anchor, _result = {}, overridableKeys = Object.create(null), keyTag = null, keyNode = null, valueNode = null, atExplicitKey = false, detected = false, ch; // there is a leading tab before this token, so it can't be a block sequence/mapping; // it can still be flow sequence/mapping or a scalar if (state.firstTabInLine !== -1) return false; if (state.anchor !== null) { state.anchorMap[state.anchor] = _result; } ch = state.input.charCodeAt(state.position); while (ch !== 0) { if (!atExplicitKey && state.firstTabInLine !== -1) { state.position = state.firstTabInLine; throwError(state, 'tab characters must not be used in indentation'); } following = state.input.charCodeAt(state.position + 1); _line = state.line; // Save the current line. // // Explicit notation case. There are two separate blocks: // first for the key (denoted by "?") and second for the value (denoted by ":") // if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { if (ch === 0x3F/* ? */) { if (atExplicitKey) { storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); keyTag = keyNode = valueNode = null; } detected = true; atExplicitKey = true; allowCompact = true; } else if (atExplicitKey) { // i.e. 0x3A/* : */ === character after the explicit key. atExplicitKey = false; allowCompact = true; } else { throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line'); } state.position += 1; ch = following; // // Implicit notation case. Flow-style node as the key first, then ":", and the value. // } else { _keyLine = state.line; _keyLineStart = state.lineStart; _keyPos = state.position; if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { // Neither implicit nor explicit notation. // Reading is done. Go to the epilogue. break; } if (state.line === _line) { ch = state.input.charCodeAt(state.position); while (is_WHITE_SPACE(ch)) { ch = state.input.charCodeAt(++state.position); } if (ch === 0x3A/* : */) { ch = state.input.charCodeAt(++state.position); if (!is_WS_OR_EOL(ch)) { throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); } if (atExplicitKey) { storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); keyTag = keyNode = valueNode = null; } detected = true; atExplicitKey = false; allowCompact = false; keyTag = state.tag; keyNode = state.result; } else if (detected) { throwError(state, 'can not read an implicit mapping pair; a colon is missed'); } else { state.tag = _tag; state.anchor = _anchor; return true; // Keep the result of `composeNode`. } } else if (detected) { throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); } else { state.tag = _tag; state.anchor = _anchor; return true; // Keep the result of `composeNode`. } } // // Common reading code for both explicit and implicit notations. // if (state.line === _line || state.lineIndent > nodeIndent) { if (atExplicitKey) { _keyLine = state.line; _keyLineStart = state.lineStart; _keyPos = state.position; } if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { if (atExplicitKey) { keyNode = state.result; } else { valueNode = state.result; } } if (!atExplicitKey) { storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos); keyTag = keyNode = valueNode = null; } skipSeparationSpace(state, true, -1); ch = state.input.charCodeAt(state.position); } if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { throwError(state, 'bad indentation of a mapping entry'); } else if (state.lineIndent < nodeIndent) { break; } } // // Epilogue. // // Special case: last mapping's node contains only the key in explicit notation. if (atExplicitKey) { storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); } // Expose the resulting mapping. if (detected) { state.tag = _tag; state.anchor = _anchor; state.kind = 'mapping'; state.result = _result; } return detected; } function readTagProperty(state) { var _position, isVerbatim = false, isNamed = false, tagHandle, tagName, ch; ch = state.input.charCodeAt(state.position); if (ch !== 0x21/* ! */) return false; if (state.tag !== null) { throwError(state, 'duplication of a tag property'); } ch = state.input.charCodeAt(++state.position); if (ch === 0x3C/* < */) { isVerbatim = true; ch = state.input.charCodeAt(++state.position); } else if (ch === 0x21/* ! */) { isNamed = true; tagHandle = '!!'; ch = state.input.charCodeAt(++state.position); } else { tagHandle = '!'; } _position = state.position; if (isVerbatim) { do { ch = state.input.charCodeAt(++state.position); } while (ch !== 0 && ch !== 0x3E/* > */); if (state.position < state.length) { tagName = state.input.slice(_position, state.position); ch = state.input.charCodeAt(++state.position); } else { throwError(state, 'unexpected end of the stream within a verbatim tag'); } } else { while (ch !== 0 && !is_WS_OR_EOL(ch)) { if (ch === 0x21/* ! */) { if (!isNamed) { tagHandle = state.input.slice(_position - 1, state.position + 1); if (!PATTERN_TAG_HANDLE.test(tagHandle)) { throwError(state, 'named tag handle cannot contain such characters'); } isNamed = true; _position = state.position + 1; } else { throwError(state, 'tag suffix cannot contain exclamation marks'); } } ch = state.input.charCodeAt(++state.position); } tagName = state.input.slice(_position, state.position); if (PATTERN_FLOW_INDICATORS.test(tagName)) { throwError(state, 'tag suffix cannot contain flow indicator characters'); } } if (tagName && !PATTERN_TAG_URI.test(tagName)) { throwError(state, 'tag name cannot contain such characters: ' + tagName); } try { tagName = decodeURIComponent(tagName); } catch (err) { throwError(state, 'tag name is malformed: ' + tagName); } if (isVerbatim) { state.tag = tagName; } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) { state.tag = state.tagMap[tagHandle] + tagName; } else if (tagHandle === '!') { state.tag = '!' + tagName; } else if (tagHandle === '!!') { state.tag = 'tag:yaml.org,2002:' + tagName; } else { throwError(state, 'undeclared tag handle "' + tagHandle + '"'); } return true; } function readAnchorProperty(state) { var _position, ch; ch = state.input.charCodeAt(state.position); if (ch !== 0x26/* & */) return false; if (state.anchor !== null) { throwError(state, 'duplication of an anchor property'); } ch = state.input.charCodeAt(++state.position); _position = state.position; while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { ch = state.input.charCodeAt(++state.position); } if (state.position === _position) { throwError(state, 'name of an anchor node must contain at least one character'); } state.anchor = state.input.slice(_position, state.position); return true; } function readAlias(state) { var _position, alias, ch; ch = state.input.charCodeAt(state.position); if (ch !== 0x2A/* * */) return false; ch = state.input.charCodeAt(++state.position); _position = state.position; while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { ch = state.input.charCodeAt(++state.position); } if (state.position === _position) { throwError(state, 'name of an alias node must contain at least one character'); } alias = state.input.slice(_position, state.position); if (!_hasOwnProperty$1.call(state.anchorMap, alias)) { throwError(state, 'unidentified alias "' + alias + '"'); } state.result = state.anchorMap[alias]; skipSeparationSpace(state, true, -1); return true; } function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { var allowBlockStyles, allowBlockScalars, allowBlockCollections, indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { indentStatus = 1; } else if (state.lineIndent === parentIndent) { indentStatus = 0; } else if (state.lineIndent < parentIndent) { indentStatus = -1; } } } if (indentStatus === 1) { while (readTagProperty(state) || readAnchorProperty(state)) { if (skipSeparationSpace(state, true, -1)) { atNewLine = true; allowBlockCollections = allowBlockStyles; if (state.lineIndent > parentIndent) { indentStatus = 1; } else if (state.lineIndent === parentIndent) { indentStatus = 0; } else if (state.lineIndent < parentIndent) { indentStatus = -1; } } else { allowBlockCollections = false; } } } if (allowBlockCollections) { allowBlockCollections = atNewLine || allowCompact; } if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { flowIndent = parentIndent; } else { flowIndent = parentIndent + 1; } blockIndent = state.position - state.lineStart; if (indentStatus === 1) { if (allowBlockCollections && (readBlockSequence(state, blockIndent) || readBlockMapping(state, blockIndent, flowIndent)) || readFlowCollection(state, flowIndent)) { hasContent = true; } else { if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || readSingleQuotedScalar(state, flowIndent) || readDoubleQuotedScalar(state, flowIndent)) { hasContent = true; } else if (readAlias(state)) { hasContent = true; if (state.tag !== null || state.anchor !== null) { throwError(state, 'alias node should not have any properties'); } } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { hasContent = true; if (state.tag === null) { state.tag = '?'; } } if (state.anchor !== null) { state.anchorMap[state.anchor] = state.result; } } } else if (indentStatus === 0) { // Special case: block sequences are allowed to have same indentation level as the parent. // http://www.yaml.org/spec/1.2/spec.html#id2799784 hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); } } if (state.tag === null) { if (state.anchor !== null) { state.anchorMap[state.anchor] = state.result; } } else if (state.tag === '?') { // Implicit resolving is not allowed for non-scalar types, and '?' // non-specific tag is only automatically assigned to plain scalars. // // We only need to check kind conformity in case user explicitly assigns '?' // tag, for example like this: "! [0]" // if (state.result !== null && state.kind !== 'scalar') { throwError(state, 'unacceptable node kind for ! tag; it should be "scalar", not "' + state.kind + '"'); } for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) { type = state.implicitTypes[typeIndex]; if (type.resolve(state.result)) { // `state.result` updated in resolver if matched state.result = type.construct(state.result); state.tag = type.tag; if (state.anchor !== null) { state.anchorMap[state.anchor] = state.result; } break; } } } else if (state.tag !== '!') { if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) { type = state.typeMap[state.kind || 'fallback'][state.tag]; } else { // looking for multi type type = null; typeList = state.typeMap.multi[state.kind || 'fallback']; for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) { if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) { type = typeList[typeIndex]; break; } } } if (!type) { throwError(state, 'unknown tag !<' + state.tag + '>'); } if (state.result !== null && type.kind !== state.kind) { throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); } if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); } else { state.result = type.construct(state.result, state.tag); if (state.anchor !== null) { state.anchorMap[state.anchor] = state.result; } } } if (state.listener !== null) { state.listener('close', state); } return state.tag !== null || state.anchor !== null || hasContent; } function readDocument(state) { var documentStart = state.position, _position, directiveName, directiveArgs, hasDirectives = false, ch; state.version = null; state.checkLineBreaks = state.legacy; state.tagMap = Object.create(null); state.anchorMap = Object.create(null); while ((ch = state.input.charCodeAt(state.position)) !== 0) { skipSeparationSpace(state, true, -1); ch = state.input.charCodeAt(state.position); if (state.lineIndent > 0 || ch !== 0x25/* % */) { break; } hasDirectives = true; ch = state.input.charCodeAt(++state.position); _position = state.position; while (ch !== 0 && !is_WS_OR_EOL(ch)) { ch = state.input.charCodeAt(++state.position); } directiveName = state.input.slice(_position, state.position); directiveArgs = []; if (directiveName.length < 1) { throwError(state, 'directive name must not be less than one character in length'); } while (ch !== 0) { while (is_WHITE_SPACE(ch)) { ch = state.input.charCodeAt(++state.position); } if (ch === 0x23/* # */) { do { ch = state.input.charCodeAt(++state.position); } while (ch !== 0 && !is_EOL(ch)); break; } if (is_EOL(ch)) break; _position = state.position; while (ch !== 0 && !is_WS_OR_EOL(ch)) { ch = state.input.charCodeAt(++state.position); } directiveArgs.push(state.input.slice(_position, state.position)); } if (ch !== 0) readLineBreak(state); if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) { directiveHandlers[directiveName](state, directiveName, directiveArgs); } else { throwWarning(state, 'unknown document directive "' + directiveName + '"'); } } skipSeparationSpace(state, true, -1); if (state.lineIndent === 0 && state.input.charCodeAt(state.position) === 0x2D/* - */ && state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { state.position += 3; skipSeparationSpace(state, true, -1); } else if (hasDirectives) { throwError(state, 'directives end mark is expected'); } composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); skipSeparationSpace(state, true, -1); if (state.checkLineBreaks && PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { throwWarning(state, 'non-ASCII line breaks are interpreted as content'); } state.documents.push(state.result); if (state.position === state.lineStart && testDocumentSeparator(state)) { if (state.input.charCodeAt(state.position) === 0x2E/* . */) { state.position += 3; skipSeparationSpace(state, true, -1); } return; } if (state.position < (state.length - 1)) { throwError(state, 'end of the stream or a document separator is expected'); } else { return; } } function loadDocuments(input, options) { input = String(input); options = options || {}; if (input.length !== 0) { // Add tailing `\n` if not exists if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { input += '\n'; } // Strip BOM if (input.charCodeAt(0) === 0xFEFF) { input = input.slice(1); } } var state = new State$1(input, options); var nullpos = input.indexOf('\0'); if (nullpos !== -1) { state.position = nullpos; throwError(state, 'null byte is not allowed in input'); } // Use 0 as string terminator. That significantly simplifies bounds check. state.input += '\0'; while (state.input.charCodeAt(state.position) === 0x20/* Space */) { state.lineIndent += 1; state.position += 1; } while (state.position < (state.length - 1)) { readDocument(state); } return state.documents; } function loadAll$1(input, iterator, options) { if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') { options = iterator; iterator = null; } var documents = loadDocuments(input, options); if (typeof iterator !== 'function') { return documents; } for (var index = 0, length = documents.length; index < length; index += 1) { iterator(documents[index]); } } function load$1(input, options) { var documents = loadDocuments(input, options); if (documents.length === 0) { /*eslint-disable no-undefined*/ return undefined; } else if (documents.length === 1) { return documents[0]; } throw new exception('expected a single document in the stream, but found more'); } var loadAll_1 = loadAll$1; var load_1 = load$1; var loader = { loadAll: loadAll_1, load: load_1 }; /*eslint-disable no-use-before-define*/ var _toString = Object.prototype.toString; var _hasOwnProperty = Object.prototype.hasOwnProperty; var CHAR_BOM = 0xFEFF; var CHAR_TAB = 0x09; /* Tab */ var CHAR_LINE_FEED = 0x0A; /* LF */ var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ var CHAR_SPACE = 0x20; /* Space */ var CHAR_EXCLAMATION = 0x21; /* ! */ var CHAR_DOUBLE_QUOTE = 0x22; /* " */ var CHAR_SHARP = 0x23; /* # */ var CHAR_PERCENT = 0x25; /* % */ var CHAR_AMPERSAND = 0x26; /* & */ var CHAR_SINGLE_QUOTE = 0x27; /* ' */ var CHAR_ASTERISK = 0x2A; /* * */ var CHAR_COMMA = 0x2C; /* , */ var CHAR_MINUS = 0x2D; /* - */ var CHAR_COLON = 0x3A; /* : */ var CHAR_EQUALS = 0x3D; /* = */ var CHAR_GREATER_THAN = 0x3E; /* > */ var CHAR_QUESTION = 0x3F; /* ? */ var CHAR_COMMERCIAL_AT = 0x40; /* @ */ var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ var CHAR_GRAVE_ACCENT = 0x60; /* ` */ var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ var CHAR_VERTICAL_LINE = 0x7C; /* | */ var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ var ESCAPE_SEQUENCES = {}; ESCAPE_SEQUENCES[0x00] = '\\0'; ESCAPE_SEQUENCES[0x07] = '\\a'; ESCAPE_SEQUENCES[0x08] = '\\b'; ESCAPE_SEQUENCES[0x09] = '\\t'; ESCAPE_SEQUENCES[0x0A] = '\\n'; ESCAPE_SEQUENCES[0x0B] = '\\v'; ESCAPE_SEQUENCES[0x0C] = '\\f'; ESCAPE_SEQUENCES[0x0D] = '\\r'; ESCAPE_SEQUENCES[0x1B] = '\\e'; ESCAPE_SEQUENCES[0x22] = '\\"'; ESCAPE_SEQUENCES[0x5C] = '\\\\'; ESCAPE_SEQUENCES[0x85] = '\\N'; ESCAPE_SEQUENCES[0xA0] = '\\_'; ESCAPE_SEQUENCES[0x2028] = '\\L'; ESCAPE_SEQUENCES[0x2029] = '\\P'; var DEPRECATED_BOOLEANS_SYNTAX = [ 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' ]; var DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/; function compileStyleMap(schema, map) { var result, keys, index, length, tag, style, type; if (map === null) return {}; result = {}; keys = Object.keys(map); for (index = 0, length = keys.length; index < length; index += 1) { tag = keys[index]; style = String(map[tag]); if (tag.slice(0, 2) === '!!') { tag = 'tag:yaml.org,2002:' + tag.slice(2); } type = schema.compiledTypeMap['fallback'][tag]; if (type && _hasOwnProperty.call(type.styleAliases, style)) { style = type.styleAliases[style]; } result[tag] = style; } return result; } function encodeHex(character) { var string, handle, length; string = character.toString(16).toUpperCase(); if (character <= 0xFF) { handle = 'x'; length = 2; } else if (character <= 0xFFFF) { handle = 'u'; length = 4; } else if (character <= 0xFFFFFFFF) { handle = 'U'; length = 8; } else { throw new exception('code point within a string may not be greater than 0xFFFFFFFF'); } return '\\' + handle + common.repeat('0', length - string.length) + string; } var QUOTING_TYPE_SINGLE = 1, QUOTING_TYPE_DOUBLE = 2; function State(options) { this.schema = options['schema'] || _default; this.indent = Math.max(1, (options['indent'] || 2)); this.noArrayIndent = options['noArrayIndent'] || false; this.skipInvalid = options['skipInvalid'] || false; this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); this.styleMap = compileStyleMap(this.schema, options['styles'] || null); this.sortKeys = options['sortKeys'] || false; this.lineWidth = options['lineWidth'] || 80; this.noRefs = options['noRefs'] || false; this.noCompatMode = options['noCompatMode'] || false; this.condenseFlow = options['condenseFlow'] || false; this.quotingType = options['quotingType'] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE; this.forceQuotes = options['forceQuotes'] || false; this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null; this.implicitTypes = this.schema.compiledImplicit; this.explicitTypes = this.schema.compiledExplicit; this.tag = null; this.result = ''; this.duplicates = []; this.usedDuplicates = null; } // Indents every line in a string. Empty lines (\n only) are not indented. function indentString(string, spaces) { var ind = common.repeat(' ', spaces), position = 0, next = -1, result = '', line, length = string.length; while (position < length) { next = string.indexOf('\n', position); if (next === -1) { line = string.slice(position); position = length; } else { line = string.slice(position, next + 1); position = next + 1; } if (line.length && line !== '\n') result += ind; result += line; } return result; } function generateNextLine(state, level) { return '\n' + common.repeat(' ', state.indent * level); } function testImplicitResolving(state, str) { var index, length, type; for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { type = state.implicitTypes[index]; if (type.resolve(str)) { return true; } } return false; } // [33] s-white ::= s-space | s-tab function isWhitespace(c) { return c === CHAR_SPACE || c === CHAR_TAB; } // Returns true if the character can be printed without escaping. // From YAML 1.2: "any allowed characters known to be non-printable // should also be escaped. [However,] This isn’t mandatory" // Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. function isPrintable(c) { return (0x00020 <= c && c <= 0x00007E) || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM) || (0x10000 <= c && c <= 0x10FFFF); } // [34] ns-char ::= nb-char - s-white // [27] nb-char ::= c-printable - b-char - c-byte-order-mark // [26] b-char ::= b-line-feed | b-carriage-return // Including s-white (for some reason, examples doesn't match specs in this aspect) // ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark function isNsCharOrWhitespace(c) { return isPrintable(c) && c !== CHAR_BOM // - b-char && c !== CHAR_CARRIAGE_RETURN && c !== CHAR_LINE_FEED; } // [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out // c = flow-in ⇒ ns-plain-safe-in // c = block-key ⇒ ns-plain-safe-out // c = flow-key ⇒ ns-plain-safe-in // [128] ns-plain-safe-out ::= ns-char // [129] ns-plain-safe-in ::= ns-char - c-flow-indicator // [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” ) // | ( /* An ns-char preceding */ “#” ) // | ( “:” /* Followed by an ns-plain-safe(c) */ ) function isPlainSafe(c, prev, inblock) { var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c); var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c); return ( // ns-plain-safe inblock ? // c = flow-in cIsNsCharOrWhitespace : cIsNsCharOrWhitespace // - c-flow-indicator && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET ) // ns-plain-char && c !== CHAR_SHARP // false on '#' && !(prev === CHAR_COLON && !cIsNsChar) // false on ': ' || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#' || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]' } // Simplified test for values allowed as the first character in plain style. function isPlainSafeFirst(c) { // Uses a subset of ns-char - c-indicator // where ns-char = nb-char - s-white. // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part return isPrintable(c) && c !== CHAR_BOM && !isWhitespace(c) // - s-white // - (c-indicator ::= // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” && c !== CHAR_MINUS && c !== CHAR_QUESTION && c !== CHAR_COLON && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “"” && c !== CHAR_SHARP && c !== CHAR_AMPERSAND && c !== CHAR_ASTERISK && c !== CHAR_EXCLAMATION && c !== CHAR_VERTICAL_LINE && c !== CHAR_EQUALS && c !== CHAR_GREATER_THAN && c !== CHAR_SINGLE_QUOTE && c !== CHAR_DOUBLE_QUOTE // | “%” | “@” | “`”) && c !== CHAR_PERCENT && c !== CHAR_COMMERCIAL_AT && c !== CHAR_GRAVE_ACCENT; } // Simplified test for values allowed as the last character in plain style. function isPlainSafeLast(c) { // just not whitespace or colon, it will be checked to be plain character later return !isWhitespace(c) && c !== CHAR_COLON; } // Same as 'string'.codePointAt(pos), but works in older browsers. function codePointAt(string, pos) { var first = string.charCodeAt(pos), second; if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) { second = string.charCodeAt(pos + 1); if (second >= 0xDC00 && second <= 0xDFFF) { // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; } } return first; } // Determines whether block indentation indicator is required. function needIndentIndicator(string) { var leadingSpaceRe = /^\n* /; return leadingSpaceRe.test(string); } var STYLE_PLAIN = 1, STYLE_SINGLE = 2, STYLE_LITERAL = 3, STYLE_FOLDED = 4, STYLE_DOUBLE = 5; // Determines which scalar styles are possible and returns the preferred style. // lineWidth = -1 => no limit. // Pre-conditions: str.length > 0. // Post-conditions: // STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. // STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). // STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType, quotingType, forceQuotes, inblock) { var i; var char = 0; var prevChar = null; var hasLineBreak = false; var hasFoldableLine = false; // only checked if shouldTrackWidth var shouldTrackWidth = lineWidth !== -1; var previousLineBreak = -1; // count the first line correctly var plain = isPlainSafeFirst(codePointAt(string, 0)) && isPlainSafeLast(codePointAt(string, string.length - 1)); if (singleLineOnly || forceQuotes) { // Case: no block styles. // Check for disallowed characters to rule out plain and single. for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { char = codePointAt(string, i); if (!isPrintable(char)) { return STYLE_DOUBLE; } plain = plain && isPlainSafe(char, prevChar, inblock); prevChar = char; } } else { // Case: block styles permitted. for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { char = codePointAt(string, i); if (char === CHAR_LINE_FEED) { hasLineBreak = true; // Check if any line can be folded. if (shouldTrackWidth) { hasFoldableLine = hasFoldableLine || // Foldable line = too long, and not more-indented. (i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1] !== ' '); previousLineBreak = i; } } else if (!isPrintable(char)) { return STYLE_DOUBLE; } plain = plain && isPlainSafe(char, prevChar, inblock); prevChar = char; } // in case the end is missing a \n hasFoldableLine = hasFoldableLine || (shouldTrackWidth && (i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1] !== ' ')); } // Although every style can represent \n without escaping, prefer block styles // for multiline, since they're more readable and they don't add empty lines. // Also prefer folding a super-long line. if (!hasLineBreak && !hasFoldableLine) { // Strings interpretable as another type have to be quoted; // e.g. the string 'true' vs. the boolean true. if (plain && !forceQuotes && !testAmbiguousType(string)) { return STYLE_PLAIN; } return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; } // Edge case: block indentation indicator can only have one digit. if (indentPerLevel > 9 && needIndentIndicator(string)) { return STYLE_DOUBLE; } // At this point we know block styles are valid. // Prefer literal style unless we want to fold. if (!forceQuotes) { return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; } return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; } // Note: line breaking/folding is implemented for only the folded style. // NB. We drop the last trailing newline (if any) of a returned block scalar // since the dumper adds its own newline. This always works: // • No ending newline => unaffected; already using strip "-" chomping. // • Ending newline => removed then restored. // Importantly, this keeps the "+" chomp indicator from gaining an extra line. function writeScalar(state, string, level, iskey, inblock) { state.dump = (function () { if (string.length === 0) { return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''"; } if (!state.noCompatMode) { if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) { return state.quotingType === QUOTING_TYPE_DOUBLE ? ('"' + string + '"') : ("'" + string + "'"); } } var indent = state.indent * Math.max(1, level); // no 0-indent scalars // As indentation gets deeper, let the width decrease monotonically // to the lower bound min(state.lineWidth, 40). // Note that this implies // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. // state.lineWidth > 40 + state.indent: width decreases until the lower bound. // This behaves better than a constant minimum width which disallows narrower options, // or an indent threshold which causes the width to suddenly increase. var lineWidth = state.lineWidth === -1 ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); // Without knowing if keys are implicit/explicit, assume implicit for safety. var singleLineOnly = iskey // No block styles in flow mode. || (state.flowLevel > -1 && level >= state.flowLevel); function testAmbiguity(string) { return testImplicitResolving(state, string); } switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) { case STYLE_PLAIN: return string; case STYLE_SINGLE: return "'" + string.replace(/'/g, "''") + "'"; case STYLE_LITERAL: return '|' + blockHeader(string, state.indent) + dropEndingNewline(indentString(string, indent)); case STYLE_FOLDED: return '>' + blockHeader(string, state.indent) + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); case STYLE_DOUBLE: return '"' + escapeString(string) + '"'; default: throw new exception('impossible error: invalid scalar style'); } }()); } // Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. function blockHeader(string, indentPerLevel) { var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ''; // note the special case: the string '\n' counts as a "trailing" empty line. var clip = string[string.length - 1] === '\n'; var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); var chomp = keep ? '+' : (clip ? '' : '-'); return indentIndicator + chomp + '\n'; } // (See the note for writeScalar.) function dropEndingNewline(string) { return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; } // Note: a long line without a suitable break point will exceed the width limit. // Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. function foldString(string, width) { // In folded style, $k$ consecutive newlines output as $k+1$ newlines— // unless they're before or after a more-indented line, or at the very // beginning or end, in which case $k$ maps to $k$. // Therefore, parse each chunk as newline(s) followed by a content line. var lineRe = /(\n+)([^\n]*)/g; // first line (possibly an empty line) var result = (function () { var nextLF = string.indexOf('\n'); nextLF = nextLF !== -1 ? nextLF : string.length; lineRe.lastIndex = nextLF; return foldLine(string.slice(0, nextLF), width); }()); // If we haven't reached the first content line yet, don't add an extra \n. var prevMoreIndented = string[0] === '\n' || string[0] === ' '; var moreIndented; // rest of the lines var match; while ((match = lineRe.exec(string))) { var prefix = match[1], line = match[2]; moreIndented = (line[0] === ' '); result += prefix + (!prevMoreIndented && !moreIndented && line !== '' ? '\n' : '') + foldLine(line, width); prevMoreIndented = moreIndented; } return result; } // Greedy line breaking. // Picks the longest line under the limit each time, // otherwise settles for the shortest line over the limit. // NB. More-indented lines *cannot* be folded, as that would add an extra \n. function foldLine(line, width) { if (line === '' || line[0] === ' ') return line; // Since a more-indented line adds a \n, breaks can't be followed by a space. var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. var match; // start is an inclusive index. end, curr, and next are exclusive. var start = 0, end, curr = 0, next = 0; var result = ''; // Invariants: 0 <= start <= length-1. // 0 <= curr <= next <= max(0, length-2). curr - start <= width. // Inside the loop: // A match implies length >= 2, so curr and next are <= length-2. while ((match = breakRe.exec(line))) { next = match.index; // maintain invariant: curr - start <= width if (next - start > width) { end = (curr > start) ? curr : next; // derive end <= length-2 result += '\n' + line.slice(start, end); // skip the space that was output as \n start = end + 1; // derive start <= length-1 } curr = next; } // By the invariants, start <= length-1, so there is something left over. // It is either the whole string or a part starting from non-whitespace. result += '\n'; // Insert a break if the remainder is too long and there is a break available. if (line.length - start > width && curr > start) { result += line.slice(start, curr) + '\n' + line.slice(curr + 1); } else { result += line.slice(start); } return result.slice(1); // drop extra \n joiner } // Escapes a double-quoted string. function escapeString(string) { var result = ''; var char = 0; var escapeSeq; for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { char = codePointAt(string, i); escapeSeq = ESCAPE_SEQUENCES[char]; if (!escapeSeq && isPrintable(char)) { result += string[i]; if (char >= 0x10000) result += string[i + 1]; } else { result += escapeSeq || encodeHex(char); } } return result; } function writeFlowSequence(state, level, object) { var _result = '', _tag = state.tag, index, length, value; for (index = 0, length = object.length; index < length; index += 1) { value = object[index]; if (state.replacer) { value = state.replacer.call(object, String(index), value); } // Write only valid elements, put null instead of invalid elements. if (writeNode(state, level, value, false, false) || (typeof value === 'undefined' && writeNode(state, level, null, false, false))) { if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : ''); _result += state.dump; } } state.tag = _tag; state.dump = '[' + _result + ']'; } function writeBlockSequence(state, level, object, compact) { var _result = '', _tag = state.tag, index, length, value; for (index = 0, length = object.length; index < length; index += 1) { value = object[index]; if (state.replacer) { value = state.replacer.call(object, String(index), value); } // Write only valid elements, put null instead of invalid elements. if (writeNode(state, level + 1, value, true, true, false, true) || (typeof value === 'undefined' && writeNode(state, level + 1, null, true, true, false, true))) { if (!compact || _result !== '') { _result += generateNextLine(state, level); } if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { _result += '-'; } else { _result += '- '; } _result += state.dump; } } state.tag = _tag; state.dump = _result || '[]'; // Empty sequence if no valid values. } function writeFlowMapping(state, level, object) { var _result = '', _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, pairBuffer; for (index = 0, length = objectKeyList.length; index < length; index += 1) { pairBuffer = ''; if (_result !== '') pairBuffer += ', '; if (state.condenseFlow) pairBuffer += '"'; objectKey = objectKeyList[index]; objectValue = object[objectKey]; if (state.replacer) { objectValue = state.replacer.call(object, objectKey, objectValue); } if (!writeNode(state, level, objectKey, false, false)) { continue; // Skip this pair because of invalid key; } if (state.dump.length > 1024) pairBuffer += '? '; pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' '); if (!writeNode(state, level, objectValue, false, false)) { continue; // Skip this pair because of invalid value. } pairBuffer += state.dump; // Both key and value are valid. _result += pairBuffer; } state.tag = _tag; state.dump = '{' + _result + '}'; } function writeBlockMapping(state, level, object, compact) { var _result = '', _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, explicitPair, pairBuffer; // Allow sorting keys so that the output file is deterministic if (state.sortKeys === true) { // Default sorting objectKeyList.sort(); } else if (typeof state.sortKeys === 'function') { // Custom sort function objectKeyList.sort(state.sortKeys); } else if (state.sortKeys) { // Something is wrong throw new exception('sortKeys must be a boolean or a function'); } for (index = 0, length = objectKeyList.length; index < length; index += 1) { pairBuffer = ''; if (!compact || _result !== '') { pairBuffer += generateNextLine(state, level); } objectKey = objectKeyList[index]; objectValue = object[objectKey]; if (state.replacer) { objectValue = state.replacer.call(object, objectKey, objectValue); } if (!writeNode(state, level + 1, objectKey, true, true, true)) { continue; // Skip this pair because of invalid key. } explicitPair = (state.tag !== null && state.tag !== '?') || (state.dump && state.dump.length > 1024); if (explicitPair) { if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { pairBuffer += '?'; } else { pairBuffer += '? '; } } pairBuffer += state.dump; if (explicitPair) { pairBuffer += generateNextLine(state, level); } if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { continue; // Skip this pair because of invalid value. } if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { pairBuffer += ':'; } else { pairBuffer += ': '; } pairBuffer += state.dump; // Both key and value are valid. _result += pairBuffer; } state.tag = _tag; state.dump = _result || '{}'; // Empty mapping if no valid pairs. } function detectType(state, object, explicit) { var _result, typeList, index, length, type, style; typeList = explicit ? state.explicitTypes : state.implicitTypes; for (index = 0, length = typeList.length; index < length; index += 1) { type = typeList[index]; if ((type.instanceOf || type.predicate) && (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && (!type.predicate || type.predicate(object))) { if (explicit) { if (type.multi && type.representName) { state.tag = type.representName(object); } else { state.tag = type.tag; } } else { state.tag = '?'; } if (type.represent) { style = state.styleMap[type.tag] || type.defaultStyle; if (_toString.call(type.represent) === '[object Function]') { _result = type.represent(object, style); } else if (_hasOwnProperty.call(type.represent, style)) { _result = type.represent[style](object, style); } else { throw new exception('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); } state.dump = _result; } return true; } } return false; } // Serializes `object` and writes it to global `result`. // Returns true on success, or false on invalid object. // function writeNode(state, level, object, block, compact, iskey, isblockseq) { state.tag = null; state.dump = object; if (!detectType(state, object, false)) { detectType(state, object, true); } var type = _toString.call(state.dump); var inblock = block; var tagStr; if (block) { block = (state.flowLevel < 0 || state.flowLevel > level); } var objectOrArray = type === '[object Object]' || type === '[object Array]', duplicateIndex, duplicate; if (objectOrArray) { duplicateIndex = state.duplicates.indexOf(object); duplicate = duplicateIndex !== -1; } if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { compact = false; } if (duplicate && state.usedDuplicates[duplicateIndex]) { state.dump = '*ref_' + duplicateIndex; } else { if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { state.usedDuplicates[duplicateIndex] = true; } if (type === '[object Object]') { if (block && (Object.keys(state.dump).length !== 0)) { writeBlockMapping(state, level, state.dump, compact); if (duplicate) { state.dump = '&ref_' + duplicateIndex + state.dump; } } else { writeFlowMapping(state, level, state.dump); if (duplicate) { state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; } } } else if (type === '[object Array]') { if (block && (state.dump.length !== 0)) { if (state.noArrayIndent && !isblockseq && level > 0) { writeBlockSequence(state, level - 1, state.dump, compact); } else { writeBlockSequence(state, level, state.dump, compact); } if (duplicate) { state.dump = '&ref_' + duplicateIndex + state.dump; } } else { writeFlowSequence(state, level, state.dump); if (duplicate) { state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; } } } else if (type === '[object String]') { if (state.tag !== '?') { writeScalar(state, state.dump, level, iskey, inblock); } } else if (type === '[object Undefined]') { return false; } else { if (state.skipInvalid) return false; throw new exception('unacceptable kind of an object to dump ' + type); } if (state.tag !== null && state.tag !== '?') { // Need to encode all characters except those allowed by the spec: // // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */ // [36] ns-hex-digit ::= ns-dec-digit // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */ // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */ // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-” // [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#” // | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,” // | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]” // // Also need to encode '!' because it has special meaning (end of tag prefix). // tagStr = encodeURI( state.tag[0] === '!' ? state.tag.slice(1) : state.tag ).replace(/!/g, '%21'); if (state.tag[0] === '!') { tagStr = '!' + tagStr; } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') { tagStr = '!!' + tagStr.slice(18); } else { tagStr = '!<' + tagStr + '>'; } state.dump = tagStr + ' ' + state.dump; } } return true; } function getDuplicateReferences(object, state) { var objects = [], duplicatesIndexes = [], index, length; inspectNode(object, objects, duplicatesIndexes); for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { state.duplicates.push(objects[duplicatesIndexes[index]]); } state.usedDuplicates = new Array(length); } function inspectNode(object, objects, duplicatesIndexes) { var objectKeyList, index, length; if (object !== null && typeof object === 'object') { index = objects.indexOf(object); if (index !== -1) { if (duplicatesIndexes.indexOf(index) === -1) { duplicatesIndexes.push(index); } } else { objects.push(object); if (Array.isArray(object)) { for (index = 0, length = object.length; index < length; index += 1) { inspectNode(object[index], objects, duplicatesIndexes); } } else { objectKeyList = Object.keys(object); for (index = 0, length = objectKeyList.length; index < length; index += 1) { inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); } } } } } function dump$1(input, options) { options = options || {}; var state = new State(options); if (!state.noRefs) getDuplicateReferences(input, state); var value = input; if (state.replacer) { value = state.replacer.call({ '': value }, '', value); } if (writeNode(state, 0, value, true, true)) return state.dump + '\n'; return ''; } var dump_1 = dump$1; var dumper = { dump: dump_1 }; function renamed(from, to) { return function () { throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' + 'Use yaml.' + to + ' instead, which is now safe by default.'); }; } var Type = type$1; var Schema = schema; var FAILSAFE_SCHEMA = failsafe; var JSON_SCHEMA = json; var CORE_SCHEMA = core; var DEFAULT_SCHEMA = _default; var load = loader.load; var loadAll = loader.loadAll; var dump$2 = dumper.dump; var YAMLException = exception; // Re-export all types in case user wants to create custom schema var types = { binary: binary, float: float, map: map, null: _null, pairs: pairs, set: set$1, timestamp: timestamp, bool: bool, int: int, merge: merge, omap: omap, seq: seq, str: str }; // Removed functions from JS-YAML 3.0.x var safeLoad = renamed('safeLoad', 'load'); var safeLoadAll = renamed('safeLoadAll', 'loadAll'); var safeDump = renamed('safeDump', 'dump'); var jsYaml = { Type: Type, Schema: Schema, FAILSAFE_SCHEMA: FAILSAFE_SCHEMA, JSON_SCHEMA: JSON_SCHEMA, CORE_SCHEMA: CORE_SCHEMA, DEFAULT_SCHEMA: DEFAULT_SCHEMA, load: load, loadAll: loadAll, dump: dump$2, YAMLException: YAMLException, types: types, safeLoad: safeLoad, safeLoadAll: safeLoadAll, safeDump: safeDump }; function requireYAML(filepath) { const yamlRaw = fse.readFileSync(filepath, "utf8"); return jsYaml.load(yamlRaw); } const allowedEnvironmentVars = [ // general "CONFIG_PATH", // cache "CACHE_ENABLED", "CACHE_TTL", "CACHE_CONTROL_S_MAXAGE", "CACHE_AUTO_PURGE", "CACHE_AUTO_PURGE_IGNORE_LIST", "CACHE_SYSTEM_TTL", "CACHE_SCHEMA", "CACHE_PERMISSIONS", "CACHE_NAMESPACE", "CACHE_STORE", "CACHE_STATUS_HEADER", "CACHE_VALUE_MAX_SIZE", "CACHE_SKIP_ALLOWED", "CACHE_HEALTHCHECK_THRESHOLD", // Externl JWT Cache "CACHE_JWT_NAMESPACE", // redis "REDIS", "REDIS_HOST", "REDIS_PORT", "REDIS_USERNAME", "REDIS_PASSWORD", "REDIS_PASSWORD_FILE", "REDIS_JWT_DB", // auth "AUTH_PROVIDERS", "AUTH_.+_DRIVER", "AUTH_.+_CLIENT_ID", "AUTH_.+_CLIENT_SECRET", "AUTH_.+_SCOPE", "AUTH_.+_AUTHORIZE_URL", "AUTH_.+_ACCESS_URL", "AUTH_.+_PROFILE_URL", "AUTH_.+_IDENTIFIER_KEY", "AUTH_.+_EMAIL_KEY", "AUTH_.+_FIRST_NAME_KEY", "AUTH_.+_LAST_NAME_KEY", "AUTH_.+_ALLOW_PUBLIC_REGISTRATION", "AUTH_.+_DEFAULT_ROLE_ID", "AUTH_.+_ICON", "AUTH_.+_LABEL", "AUTH_.+_PARAMS", "AUTH_.+_ISSUER_URL", "AUTH_.+_CLIENT_URL", "AUTH_.+_TRUSTED", "AUTH_.+_JWKS_URL", "AUTH_.+_JWKS_KEYS", "AUTH_.+_JWT_ROLE_KEY", "AUTH_.+_JWT_ADMIN_KEY", "AUTH_.+_JWT_APP_KEY", "AUTH_.+_JWT_USEDB" ].map((name) => new RegExp(`^${name}$`)); const acceptedEnvTypes = ["string", "number", "regex", "array", "json"]; const typeMap = {}; const defaults$2 = { CONFIG_PATH: require$$1$5.resolve(process.cwd(), ".env") }; let env = { ...defaults$2, ...process.env, ...processConfiguration() }; process.env = env; env = processValues(env); var env$1 = env; function toBoolean(value) { return value === "true" || value === true || value === "1" || value === 1; } function processConfiguration() { const configPath = require$$1$5.resolve(process.env["CONFIG_PATH"] || defaults$2["CONFIG_PATH"]); if (fs$j.existsSync(configPath) === false) return {}; const fileExt = require$$1$5.extname(configPath).toLowerCase(); if (fileExt === ".js") { const module = require(configPath); const exported = module.default || module; if (typeof exported === "function") { return exported(process.env); } else if (typeof exported === "object") { return exported; } throw new Error( `Invalid JS configuration file export type. Requires one of "function", "object", received: "${typeof exported}"` ); } if (fileExt === ".json") { return require(configPath); } if (fileExt === ".yaml" || fileExt === ".yml") { const data = requireYAML(configPath); if (typeof data === "object") { return data; } throw new Error("Invalid YAML configuration. Root has to be an object."); } return dotenv.parse(fs$j.readFileSync(configPath, { encoding: "utf8" })); } function getVariableType(variable) { return variable.split(":").slice(0, -1)[0]; } function getEnvVariableValue(variableValue, variableType) { return variableValue.split(`${variableType}:`)[1]; } function getEnvironmentValueWithPrefix(envArray) { return envArray.map((item) => { if (isEnvSyntaxPrefixPresent(item)) { return getEnvironmentValueByType(item); } return item; }); } function getEnvironmentValueByType(envVariableString) { const variableType = getVariableType(envVariableString) ?? false; const envVariableValue = getEnvVariableValue(envVariableString, variableType) ?? false; switch (variableType) { case "number": return toNumber$3(envVariableValue); case "array": return getEnvironmentValueWithPrefix(toArray$1(envVariableValue)); case "regex": return new RegExp(envVariableValue); case "string": return envVariableValue; case "json": return tryJSON(envVariableValue); } } function isEnvSyntaxPrefixPresent(value) { return acceptedEnvTypes.some((envType) => value.includes(`${envType}:`)); } function processValues(env2) { env2 = clone$7(env2); for (let [key, value] of Object.entries(env2)) { let newKey; if (key.length > 5 && key.endsWith("_FILE")) { newKey = key.slice(0, -5); if (allowedEnvironmentVars.some((pattern) => pattern.test(newKey))) { if (newKey in env2 && !(newKey in defaults$2 && env2[newKey] === defaults$2[newKey])) { throw new Error( `Duplicate environment variable encountered: you can't use "${newKey}" and "${key}" simultaneously.` ); } try { value = fs$j.readFileSync(value, { encoding: "utf8" }); key = newKey; } catch { throw new Error(`Failed to read value from file "${value}", defined in environment variable "${key}".`); } } } if (typeof value === "string" && isEnvSyntaxPrefixPresent(value)) { env2[key] = getEnvironmentValueByType(value); continue; } if (typeMap[key]) { switch (typeMap[key]) { case "number": env2[key] = toNumber$3(value); break; case "string": env2[key] = toString$2(value); break; case "array": env2[key] = toArray$1(value); break; case "json": env2[key] = tryJSON(value); break; case "boolean": env2[key] = toBoolean(value); } continue; } if (value === "true") { env2[key] = true; continue; } if (value === "false") { env2[key] = false; continue; } if (value === "null") { env2[key] = null; continue; } if (String(value).startsWith("0") === false && isNaN(value) === false && value.length > 0 && value <= Number.MAX_SAFE_INTEGER) { env2[key] = Number(value); continue; } if (String(value).includes(",")) { env2[key] = toArray$1(value); continue; } env2[key] = tryJSON(value); if (newKey) { env2[key] = value; } } return env2; } function tryJSON(value) { try { return parseJSON(value); } catch { return value; } } /** * Helpers. */ var s = 1000; var m = s * 60; var h = m * 60; var d = h * 24; var w = d * 7; var y = d * 365.25; /** * Parse or format the given `val`. * * Options: * * - `long` verbose formatting [false] * * @param {String|Number} val * @param {Object} [options] * @throws {Error} throw an error if val is not a non-empty string or a number * @return {String|Number} * @api public */ var ms$1 = function (val, options) { options = options || {}; var type = typeof val; if (type === 'string' && val.length > 0) { return parse$7(val); } else if (type === 'number' && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } throw new Error( 'val is not a non-empty string or a valid number. val=' + JSON.stringify(val) ); }; /** * Parse the given `str` and return milliseconds. * * @param {String} str * @return {Number} * @api private */ function parse$7(str) { str = String(str); if (str.length > 100) { return; } var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( str ); if (!match) { return; } var n = parseFloat(match[1]); var type = (match[2] || 'ms').toLowerCase(); switch (type) { case 'years': case 'year': case 'yrs': case 'yr': case 'y': return n * y; case 'weeks': case 'week': case 'w': return n * w; case 'days': case 'day': case 'd': return n * d; case 'hours': case 'hour': case 'hrs': case 'hr': case 'h': return n * h; case 'minutes': case 'minute': case 'mins': case 'min': case 'm': return n * m; case 'seconds': case 'second': case 'secs': case 'sec': case 's': return n * s; case 'milliseconds': case 'millisecond': case 'msecs': case 'msec': case 'ms': return n; default: return undefined; } } /** * Short format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtShort(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return Math.round(ms / d) + 'd'; } if (msAbs >= h) { return Math.round(ms / h) + 'h'; } if (msAbs >= m) { return Math.round(ms / m) + 'm'; } if (msAbs >= s) { return Math.round(ms / s) + 's'; } return ms + 'ms'; } /** * Long format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtLong(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return plural(ms, msAbs, d, 'day'); } if (msAbs >= h) { return plural(ms, msAbs, h, 'hour'); } if (msAbs >= m) { return plural(ms, msAbs, m, 'minute'); } if (msAbs >= s) { return plural(ms, msAbs, s, 'second'); } return ms + ' ms'; } /** * Pluralization helper. */ function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); } // src/create-error.ts var createError = (code, message, status = 500) => { return class extends Error { name = "DirectusError"; extensions; code = code.toUpperCase(); status = status; constructor(extensions, options) { const msg = typeof message === "string" ? message : message(extensions); super(msg, options); this.extensions = extensions; } toString() { return `${this.name} [${this.code}]: ${this.message}`; } }; }; const InvalidJWKIssuerMetadata = createError("INVALID_JWKS_ISSUER_ERROR", "No JWKS_URL or JWKS_KEYS and could not discover JWKS_URL from openid metadata", 500); const InvalidJWKSUrl = createError("INVALID_JWKS_ISSUER_ERROR", "Could not retrieve any valid keys from JWKS_URL", 500); const InvalidJWKKeys = createError("INVALID_JWKS_ISSUER_ERROR", "No signing keys in response from provider"); async function getAuthProviders() { console.log("calling auth providers"); return new Promise((resolve, reject) => { const authProviders = toArray$1(env$1["AUTH_PROVIDERS"]).filter((provider) => provider && env$1[`AUTH_${provider.toUpperCase()}_DRIVER`] === "openid").map((provider) => ({ name: provider, label: env$1[`AUTH_${provider.toUpperCase()}_LABEL`], driver: env$1[`AUTH_${provider.toUpperCase()}_DRIVER`], icon: env$1[`AUTH_${provider.toUpperCase()}_ICON`], trusted: env$1[`AUTH_${provider.toUpperCase()}_TRUSTED`], jwks_url: env$1[`AUTH_${provider.toUpperCase()}_JWKS_URL`], jwks_keys: env$1[`AUTH_${provider.toUpperCase()}_JWKS_KEYS`], issuer_url: env$1[`AUTH_${provider.toUpperCase()}_ISSUER_URL`], admin_key: env$1[`AUTH_${provider.toUpperCase()}_JWT_ADMIN_KEY`], app_key: env$1[`AUTH_${provider.toUpperCase()}_JWT_APP_KEY`], role_key: env$1[`AUTH_${provider.toUpperCase()}_JWT_ROLE_KEY`], client_id: env$1[`AUTH_${provider.toUpperCase()}_CLIENT_ID`], client_secret: env$1[`AUTH_${provider.toUpperCase()}_CLIENT_SECRET`], use_database: env$1[`AUTH_${provider.toUpperCase()}_JWT_USEDB`] })); if (authProviders.length === 0) return resolve([]); const promises = []; for (const authProvider of authProviders) { switch (authProvider.driver) { case "openid": if (!authProvider.trusted || authProvider.issuer_url == null && authProvider.jwks_url == null && authProvider.jwks_keys == null) break; promises.push(getJWKS(authProvider)); break; case "oauth2": if (!authProvider.trusted || authProvider.issuer_url == null && authProvider.jwks_url == null && authProvider.jwks_keys == null) break; promises.push(getJWKS(authProvider)); break; } } Promise.all(promises).then((values) => { resolve(values); }).catch((error) => { reject(error); }); }); } async function getJWKS(provider) { if (provider.jwks_keys !== void 0 && provider.issuer_url == null && provider.jwks_url == null) { const jwks_keys = JSON.parse(provider.jwks_keys); const jwksClient2 = new JwksClient_1({ getKeysInterceptor: () => { return jwks_keys; }, jwksUri: "" }); provider.JWKSClient = jwksClient2; } if (provider.issuer_url && !provider.jwks_url) { const issuer = await Issuer.discover(provider.issuer_url); if (issuer.metadata.jwks_uri != null) { provider.jwks_url = issuer.metadata.jwks_uri; } } if (provider.jwks_url == null) throw new InvalidJWKIssuerMetadata(); const jwksClient = await getJWKSClient(provider.jwks_url); provider.JWKSClient = jwksClient; return provider; } async function getJWKSClient(url) { const jwksClient = new JwksClient_1({ jwksUri: url, cache: true, cacheMaxAge: 36e6, // 10 hours cacheMaxEntries: 10, timeout: 3e4 // 30 seconds }); try { const keys = await jwksClient.getSigningKeys(); if (keys.length == 0) { throw new InvalidJWKKeys(); } } catch (error) { throw new InvalidJWKSUrl(); } return jwksClient; } var jws$3 = {}; var safeBuffer = {exports: {}}; /*! safe-buffer. MIT License. Feross Aboukhadijeh */ (function (module, exports) { /* eslint-disable node/no-deprecated-api */ var buffer = require$$0$4; var Buffer = buffer.Buffer; // alternative to using Object.keys for old browsers function copyProps (src, dst) { for (var key in src) { dst[key] = src[key]; } } if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { module.exports = buffer; } else { // Copy properties from require('buffer') copyProps(buffer, exports); exports.Buffer = SafeBuffer; } function SafeBuffer (arg, encodingOrOffset, length) { return Buffer(arg, encodingOrOffset, length) } SafeBuffer.prototype = Object.create(Buffer.prototype); // Copy static methods from Buffer copyProps(Buffer, SafeBuffer); SafeBuffer.from = function (arg, encodingOrOffset, length) { if (typeof arg === 'number') { throw new TypeError('Argument must not be a number') } return Buffer(arg, encodingOrOffset, length) }; SafeBuffer.alloc = function (size, fill, encoding) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number') } var buf = Buffer(size); if (fill !== undefined) { if (typeof encoding === 'string') { buf.fill(fill, encoding); } else { buf.fill(fill); } } else { buf.fill(0); } return buf }; SafeBuffer.allocUnsafe = function (size) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number') } return Buffer(size) }; SafeBuffer.allocUnsafeSlow = function (size) { if (typeof size !== 'number') { throw new TypeError('Argument must be a number') } return buffer.SlowBuffer(size) }; } (safeBuffer, safeBuffer.exports)); var safeBufferExports = safeBuffer.exports; /*global module, process*/ var Buffer$8 = safeBufferExports.Buffer; var Stream$2 = stream; var util$4 = require$$1; function DataStream$2(data) { this.buffer = null; this.writable = true; this.readable = true; // No input if (!data) { this.buffer = Buffer$8.alloc(0); return this; } // Stream if (typeof data.pipe === 'function') { this.buffer = Buffer$8.alloc(0); data.pipe(this); return this; } // Buffer or String // or Object (assumedly a passworded key) if (data.length || typeof data === 'object') { this.buffer = data; this.writable = false; process.nextTick(function () { this.emit('end', data); this.readable = false; this.emit('close'); }.bind(this)); return this; } throw new TypeError('Unexpected data type ('+ typeof data + ')'); } util$4.inherits(DataStream$2, Stream$2); DataStream$2.prototype.write = function write(data) { this.buffer = Buffer$8.concat([this.buffer, Buffer$8.from(data)]); this.emit('data', data); }; DataStream$2.prototype.end = function end(data) { if (data) this.write(data); this.emit('end', data); this.emit('close'); this.writable = false; this.readable = false; }; var dataStream = DataStream$2; /*jshint node:true */ var Buffer$7 = require$$0$4.Buffer; // browserify var SlowBuffer = require$$0$4.SlowBuffer; var bufferEqualConstantTime = bufferEq; function bufferEq(a, b) { // shortcutting on type is necessary for correctness if (!Buffer$7.isBuffer(a) || !Buffer$7.isBuffer(b)) { return false; } // buffer sizes should be well-known information, so despite this // shortcutting, it doesn't leak any information about the *contents* of the // buffers. if (a.length !== b.length) { return false; } var c = 0; for (var i = 0; i < a.length; i++) { /*jshint bitwise:false */ c |= a[i] ^ b[i]; // XOR } return c === 0; } bufferEq.install = function() { Buffer$7.prototype.equal = SlowBuffer.prototype.equal = function equal(that) { return bufferEq(this, that); }; }; var origBufEqual = Buffer$7.prototype.equal; var origSlowBufEqual = SlowBuffer.prototype.equal; bufferEq.restore = function() { Buffer$7.prototype.equal = origBufEqual; SlowBuffer.prototype.equal = origSlowBufEqual; }; function getParamSize(keySize) { var result = ((keySize / 8) | 0) + (keySize % 8 === 0 ? 0 : 1); return result; } var paramBytesForAlg = { ES256: getParamSize(256), ES384: getParamSize(384), ES512: getParamSize(521) }; function getParamBytesForAlg$1(alg) { var paramBytes = paramBytesForAlg[alg]; if (paramBytes) { return paramBytes; } throw new Error('Unknown algorithm "' + alg + '"'); } var paramBytesForAlg_1 = getParamBytesForAlg$1; var Buffer$6 = safeBufferExports.Buffer; var getParamBytesForAlg = paramBytesForAlg_1; var MAX_OCTET = 0x80, CLASS_UNIVERSAL = 0, PRIMITIVE_BIT = 0x20, TAG_SEQ = 0x10, TAG_INT = 0x02, ENCODED_TAG_SEQ = (TAG_SEQ | PRIMITIVE_BIT) | (CLASS_UNIVERSAL << 6), ENCODED_TAG_INT = TAG_INT | (CLASS_UNIVERSAL << 6); function base64Url(base64) { return base64 .replace(/=/g, '') .replace(/\+/g, '-') .replace(/\//g, '_'); } function signatureAsBuffer(signature) { if (Buffer$6.isBuffer(signature)) { return signature; } else if ('string' === typeof signature) { return Buffer$6.from(signature, 'base64'); } throw new TypeError('ECDSA signature must be a Base64 string or a Buffer'); } function derToJose(signature, alg) { signature = signatureAsBuffer(signature); var paramBytes = getParamBytesForAlg(alg); // the DER encoded param should at most be the param size, plus a padding // zero, since due to being a signed integer var maxEncodedParamLength = paramBytes + 1; var inputLength = signature.length; var offset = 0; if (signature[offset++] !== ENCODED_TAG_SEQ) { throw new Error('Could not find expected "seq"'); } var seqLength = signature[offset++]; if (seqLength === (MAX_OCTET | 1)) { seqLength = signature[offset++]; } if (inputLength - offset < seqLength) { throw new Error('"seq" specified length of "' + seqLength + '", only "' + (inputLength - offset) + '" remaining'); } if (signature[offset++] !== ENCODED_TAG_INT) { throw new Error('Could not find expected "int" for "r"'); } var rLength = signature[offset++]; if (inputLength - offset - 2 < rLength) { throw new Error('"r" specified length of "' + rLength + '", only "' + (inputLength - offset - 2) + '" available'); } if (maxEncodedParamLength < rLength) { throw new Error('"r" specified length of "' + rLength + '", max of "' + maxEncodedParamLength + '" is acceptable'); } var rOffset = offset; offset += rLength; if (signature[offset++] !== ENCODED_TAG_INT) { throw new Error('Could not find expected "int" for "s"'); } var sLength = signature[offset++]; if (inputLength - offset !== sLength) { throw new Error('"s" specified length of "' + sLength + '", expected "' + (inputLength - offset) + '"'); } if (maxEncodedParamLength < sLength) { throw new Error('"s" specified length of "' + sLength + '", max of "' + maxEncodedParamLength + '" is acceptable'); } var sOffset = offset; offset += sLength; if (offset !== inputLength) { throw new Error('Expected to consume entire buffer, but "' + (inputLength - offset) + '" bytes remain'); } var rPadding = paramBytes - rLength, sPadding = paramBytes - sLength; var dst = Buffer$6.allocUnsafe(rPadding + rLength + sPadding + sLength); for (offset = 0; offset < rPadding; ++offset) { dst[offset] = 0; } signature.copy(dst, offset, rOffset + Math.max(-rPadding, 0), rOffset + rLength); offset = paramBytes; for (var o = offset; offset < o + sPadding; ++offset) { dst[offset] = 0; } signature.copy(dst, offset, sOffset + Math.max(-sPadding, 0), sOffset + sLength); dst = dst.toString('base64'); dst = base64Url(dst); return dst; } function countPadding(buf, start, stop) { var padding = 0; while (start + padding < stop && buf[start + padding] === 0) { ++padding; } var needsSign = buf[start + padding] >= MAX_OCTET; if (needsSign) { --padding; } return padding; } function joseToDer(signature, alg) { signature = signatureAsBuffer(signature); var paramBytes = getParamBytesForAlg(alg); var signatureBytes = signature.length; if (signatureBytes !== paramBytes * 2) { throw new TypeError('"' + alg + '" signatures must be "' + paramBytes * 2 + '" bytes, saw "' + signatureBytes + '"'); } var rPadding = countPadding(signature, 0, paramBytes); var sPadding = countPadding(signature, paramBytes, signature.length); var rLength = paramBytes - rPadding; var sLength = paramBytes - sPadding; var rsBytes = 1 + 1 + rLength + 1 + 1 + sLength; var shortLength = rsBytes < MAX_OCTET; var dst = Buffer$6.allocUnsafe((shortLength ? 2 : 3) + rsBytes); var offset = 0; dst[offset++] = ENCODED_TAG_SEQ; if (shortLength) { // Bit 8 has value "0" // bits 7-1 give the length. dst[offset++] = rsBytes; } else { // Bit 8 of first octet has value "1" // bits 7-1 give the number of additional length octets. dst[offset++] = MAX_OCTET | 1; // length, base 256 dst[offset++] = rsBytes & 0xff; } dst[offset++] = ENCODED_TAG_INT; dst[offset++] = rLength; if (rPadding < 0) { dst[offset++] = 0; offset += signature.copy(dst, offset, 0, paramBytes); } else { offset += signature.copy(dst, offset, rPadding, paramBytes); } dst[offset++] = ENCODED_TAG_INT; dst[offset++] = sLength; if (sPadding < 0) { dst[offset++] = 0; signature.copy(dst, offset, paramBytes); } else { signature.copy(dst, offset, paramBytes + sPadding); } return dst; } var ecdsaSigFormatter = { derToJose: derToJose, joseToDer: joseToDer }; var bufferEqual = bufferEqualConstantTime; var Buffer$5 = safeBufferExports.Buffer; var crypto = require$$0$3; var formatEcdsa = ecdsaSigFormatter; var util$3 = require$$1; var MSG_INVALID_ALGORITHM = '"%s" is not a valid algorithm.\n Supported algorithms are:\n "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" and "none".'; var MSG_INVALID_SECRET = 'secret must be a string or buffer'; var MSG_INVALID_VERIFIER_KEY = 'key must be a string or a buffer'; var MSG_INVALID_SIGNER_KEY = 'key must be a string, a buffer or an object'; var supportsKeyObjects = typeof crypto.createPublicKey === 'function'; if (supportsKeyObjects) { MSG_INVALID_VERIFIER_KEY += ' or a KeyObject'; MSG_INVALID_SECRET += 'or a KeyObject'; } function checkIsPublicKey(key) { if (Buffer$5.isBuffer(key)) { return; } if (typeof key === 'string') { return; } if (!supportsKeyObjects) { throw typeError(MSG_INVALID_VERIFIER_KEY); } if (typeof key !== 'object') { throw typeError(MSG_INVALID_VERIFIER_KEY); } if (typeof key.type !== 'string') { throw typeError(MSG_INVALID_VERIFIER_KEY); } if (typeof key.asymmetricKeyType !== 'string') { throw typeError(MSG_INVALID_VERIFIER_KEY); } if (typeof key.export !== 'function') { throw typeError(MSG_INVALID_VERIFIER_KEY); } } function checkIsPrivateKey(key) { if (Buffer$5.isBuffer(key)) { return; } if (typeof key === 'string') { return; } if (typeof key === 'object') { return; } throw typeError(MSG_INVALID_SIGNER_KEY); } function checkIsSecretKey(key) { if (Buffer$5.isBuffer(key)) { return; } if (typeof key === 'string') { return key; } if (!supportsKeyObjects) { throw typeError(MSG_INVALID_SECRET); } if (typeof key !== 'object') { throw typeError(MSG_INVALID_SECRET); } if (key.type !== 'secret') { throw typeError(MSG_INVALID_SECRET); } if (typeof key.export !== 'function') { throw typeError(MSG_INVALID_SECRET); } } function fromBase64(base64) { return base64 .replace(/=/g, '') .replace(/\+/g, '-') .replace(/\//g, '_'); } function toBase64(base64url) { base64url = base64url.toString(); var padding = 4 - base64url.length % 4; if (padding !== 4) { for (var i = 0; i < padding; ++i) { base64url += '='; } } return base64url .replace(/\-/g, '+') .replace(/_/g, '/'); } function typeError(template) { var args = [].slice.call(arguments, 1); var errMsg = util$3.format.bind(util$3, template).apply(null, args); return new TypeError(errMsg); } function bufferOrString(obj) { return Buffer$5.isBuffer(obj) || typeof obj === 'string'; } function normalizeInput(thing) { if (!bufferOrString(thing)) thing = JSON.stringify(thing); return thing; } function createHmacSigner(bits) { return function sign(thing, secret) { checkIsSecretKey(secret); thing = normalizeInput(thing); var hmac = crypto.createHmac('sha' + bits, secret); var sig = (hmac.update(thing), hmac.digest('base64')); return fromBase64(sig); } } function createHmacVerifier(bits) { return function verify(thing, signature, secret) { var computedSig = createHmacSigner(bits)(thing, secret); return bufferEqual(Buffer$5.from(signature), Buffer$5.from(computedSig)); } } function createKeySigner(bits) { return function sign(thing, privateKey) { checkIsPrivateKey(privateKey); thing = normalizeInput(thing); // Even though we are specifying "RSA" here, this works with ECDSA // keys as well. var signer = crypto.createSign('RSA-SHA' + bits); var sig = (signer.update(thing), signer.sign(privateKey, 'base64')); return fromBase64(sig); } } function createKeyVerifier(bits) { return function verify(thing, signature, publicKey) { checkIsPublicKey(publicKey); thing = normalizeInput(thing); signature = toBase64(signature); var verifier = crypto.createVerify('RSA-SHA' + bits); verifier.update(thing); return verifier.verify(publicKey, signature, 'base64'); } } function createPSSKeySigner(bits) { return function sign(thing, privateKey) { checkIsPrivateKey(privateKey); thing = normalizeInput(thing); var signer = crypto.createSign('RSA-SHA' + bits); var sig = (signer.update(thing), signer.sign({ key: privateKey, padding: crypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST }, 'base64')); return fromBase64(sig); } } function createPSSKeyVerifier(bits) { return function verify(thing, signature, publicKey) { checkIsPublicKey(publicKey); thing = normalizeInput(thing); signature = toBase64(signature); var verifier = crypto.createVerify('RSA-SHA' + bits); verifier.update(thing); return verifier.verify({ key: publicKey, padding: crypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST }, signature, 'base64'); } } function createECDSASigner(bits) { var inner = createKeySigner(bits); return function sign() { var signature = inner.apply(null, arguments); signature = formatEcdsa.derToJose(signature, 'ES' + bits); return signature; }; } function createECDSAVerifer(bits) { var inner = createKeyVerifier(bits); return function verify(thing, signature, publicKey) { signature = formatEcdsa.joseToDer(signature, 'ES' + bits).toString('base64'); var result = inner(thing, signature, publicKey); return result; }; } function createNoneSigner() { return function sign() { return ''; } } function createNoneVerifier() { return function verify(thing, signature) { return signature === ''; } } var jwa$2 = function jwa(algorithm) { var signerFactories = { hs: createHmacSigner, rs: createKeySigner, ps: createPSSKeySigner, es: createECDSASigner, none: createNoneSigner, }; var verifierFactories = { hs: createHmacVerifier, rs: createKeyVerifier, ps: createPSSKeyVerifier, es: createECDSAVerifer, none: createNoneVerifier, }; var match = algorithm.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/i); if (!match) throw typeError(MSG_INVALID_ALGORITHM, algorithm); var algo = (match[1] || match[3]).toLowerCase(); var bits = match[2]; return { sign: signerFactories[algo](bits), verify: verifierFactories[algo](bits), } }; /*global module*/ var Buffer$4 = require$$0$4.Buffer; var tostring = function toString(obj) { if (typeof obj === 'string') return obj; if (typeof obj === 'number' || Buffer$4.isBuffer(obj)) return obj.toString(); return JSON.stringify(obj); }; /*global module*/ var Buffer$3 = safeBufferExports.Buffer; var DataStream$1 = dataStream; var jwa$1 = jwa$2; var Stream$1 = stream; var toString$1 = tostring; var util$2 = require$$1; function base64url(string, encoding) { return Buffer$3 .from(string, encoding) .toString('base64') .replace(/=/g, '') .replace(/\+/g, '-') .replace(/\//g, '_'); } function jwsSecuredInput(header, payload, encoding) { encoding = encoding || 'utf8'; var encodedHeader = base64url(toString$1(header), 'binary'); var encodedPayload = base64url(toString$1(payload), encoding); return util$2.format('%s.%s', encodedHeader, encodedPayload); } function jwsSign(opts) { var header = opts.header; var payload = opts.payload; var secretOrKey = opts.secret || opts.privateKey; var encoding = opts.encoding; var algo = jwa$1(header.alg); var securedInput = jwsSecuredInput(header, payload, encoding); var signature = algo.sign(securedInput, secretOrKey); return util$2.format('%s.%s', securedInput, signature); } function SignStream$1(opts) { var secret = opts.secret||opts.privateKey||opts.key; var secretStream = new DataStream$1(secret); this.readable = true; this.header = opts.header; this.encoding = opts.encoding; this.secret = this.privateKey = this.key = secretStream; this.payload = new DataStream$1(opts.payload); this.secret.once('close', function () { if (!this.payload.writable && this.readable) this.sign(); }.bind(this)); this.payload.once('close', function () { if (!this.secret.writable && this.readable) this.sign(); }.bind(this)); } util$2.inherits(SignStream$1, Stream$1); SignStream$1.prototype.sign = function sign() { try { var signature = jwsSign({ header: this.header, payload: this.payload.buffer, secret: this.secret.buffer, encoding: this.encoding }); this.emit('done', signature); this.emit('data', signature); this.emit('end'); this.readable = false; return signature; } catch (e) { this.readable = false; this.emit('error', e); this.emit('close'); } }; SignStream$1.sign = jwsSign; var signStream = SignStream$1; /*global module*/ var Buffer$2 = safeBufferExports.Buffer; var DataStream = dataStream; var jwa = jwa$2; var Stream = stream; var toString = tostring; var util$1 = require$$1; var JWS_REGEX = /^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.([a-zA-Z0-9\-_]+)?$/; function isObject$5(thing) { return Object.prototype.toString.call(thing) === '[object Object]'; } function safeJsonParse(thing) { if (isObject$5(thing)) return thing; try { return JSON.parse(thing); } catch (e) { return undefined; } } function headerFromJWS(jwsSig) { var encodedHeader = jwsSig.split('.', 1)[0]; return safeJsonParse(Buffer$2.from(encodedHeader, 'base64').toString('binary')); } function securedInputFromJWS(jwsSig) { return jwsSig.split('.', 2).join('.'); } function signatureFromJWS(jwsSig) { return jwsSig.split('.')[2]; } function payloadFromJWS(jwsSig, encoding) { encoding = encoding || 'utf8'; var payload = jwsSig.split('.')[1]; return Buffer$2.from(payload, 'base64').toString(encoding); } function isValidJws(string) { return JWS_REGEX.test(string) && !!headerFromJWS(string); } function jwsVerify(jwsSig, algorithm, secretOrKey) { if (!algorithm) { var err = new Error("Missing algorithm parameter for jws.verify"); err.code = "MISSING_ALGORITHM"; throw err; } jwsSig = toString(jwsSig); var signature = signatureFromJWS(jwsSig); var securedInput = securedInputFromJWS(jwsSig); var algo = jwa(algorithm); return algo.verify(securedInput, signature, secretOrKey); } function jwsDecode(jwsSig, opts) { opts = opts || {}; jwsSig = toString(jwsSig); if (!isValidJws(jwsSig)) return null; var header = headerFromJWS(jwsSig); if (!header) return null; var payload = payloadFromJWS(jwsSig); if (header.typ === 'JWT' || opts.json) payload = JSON.parse(payload, opts.encoding); return { header: header, payload: payload, signature: signatureFromJWS(jwsSig) }; } function VerifyStream$1(opts) { opts = opts || {}; var secretOrKey = opts.secret||opts.publicKey||opts.key; var secretStream = new DataStream(secretOrKey); this.readable = true; this.algorithm = opts.algorithm; this.encoding = opts.encoding; this.secret = this.publicKey = this.key = secretStream; this.signature = new DataStream(opts.signature); this.secret.once('close', function () { if (!this.signature.writable && this.readable) this.verify(); }.bind(this)); this.signature.once('close', function () { if (!this.secret.writable && this.readable) this.verify(); }.bind(this)); } util$1.inherits(VerifyStream$1, Stream); VerifyStream$1.prototype.verify = function verify() { try { var valid = jwsVerify(this.signature.buffer, this.algorithm, this.key.buffer); var obj = jwsDecode(this.signature.buffer, this.encoding); this.emit('done', valid, obj); this.emit('data', valid); this.emit('end'); this.readable = false; return valid; } catch (e) { this.readable = false; this.emit('error', e); this.emit('close'); } }; VerifyStream$1.decode = jwsDecode; VerifyStream$1.isValid = isValidJws; VerifyStream$1.verify = jwsVerify; var verifyStream = VerifyStream$1; /*global exports*/ var SignStream = signStream; var VerifyStream = verifyStream; var ALGORITHMS = [ 'HS256', 'HS384', 'HS512', 'RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512', 'ES256', 'ES384', 'ES512' ]; jws$3.ALGORITHMS = ALGORITHMS; jws$3.sign = SignStream.sign; jws$3.verify = VerifyStream.verify; jws$3.decode = VerifyStream.decode; jws$3.isValid = VerifyStream.isValid; jws$3.createSign = function createSign(opts) { return new SignStream(opts); }; jws$3.createVerify = function createVerify(opts) { return new VerifyStream(opts); }; var jws$2 = jws$3; var decode$1 = function (jwt, options) { options = options || {}; var decoded = jws$2.decode(jwt, options); if (!decoded) { return null; } var payload = decoded.payload; //try parse the payload if(typeof payload === 'string') { try { var obj = JSON.parse(payload); if(obj !== null && typeof obj === 'object') { payload = obj; } } catch (e) { } } //return header if `complete` option is enabled. header includes claims //such as `kid` and `alg` used to select the key within a JWKS needed to //verify the signature if (options.complete === true) { return { header: decoded.header, payload: payload, signature: decoded.signature }; } return payload; }; var JsonWebTokenError$3 = function (message, error) { Error.call(this, message); if(Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } this.name = 'JsonWebTokenError'; this.message = message; if (error) this.inner = error; }; JsonWebTokenError$3.prototype = Object.create(Error.prototype); JsonWebTokenError$3.prototype.constructor = JsonWebTokenError$3; var JsonWebTokenError_1 = JsonWebTokenError$3; var JsonWebTokenError$2 = JsonWebTokenError_1; var NotBeforeError$1 = function (message, date) { JsonWebTokenError$2.call(this, message); this.name = 'NotBeforeError'; this.date = date; }; NotBeforeError$1.prototype = Object.create(JsonWebTokenError$2.prototype); NotBeforeError$1.prototype.constructor = NotBeforeError$1; var NotBeforeError_1 = NotBeforeError$1; var JsonWebTokenError$1 = JsonWebTokenError_1; var TokenExpiredError$1 = function (message, expiredAt) { JsonWebTokenError$1.call(this, message); this.name = 'TokenExpiredError'; this.expiredAt = expiredAt; }; TokenExpiredError$1.prototype = Object.create(JsonWebTokenError$1.prototype); TokenExpiredError$1.prototype.constructor = TokenExpiredError$1; var TokenExpiredError_1 = TokenExpiredError$1; var ms = ms$1; var timespan$2 = function (time, iat) { var timestamp = iat || Math.floor(Date.now() / 1000); if (typeof time === 'string') { var milliseconds = ms(time); if (typeof milliseconds === 'undefined') { return; } return Math.floor(timestamp + milliseconds / 1000); } else if (typeof time === 'number') { return timestamp + time; } else { return; } }; var re$2 = {exports: {}}; // Note: this is the semver.org version of the spec that it implements // Not necessarily the package version of this code. const SEMVER_SPEC_VERSION = '2.0.0'; const MAX_LENGTH$1 = 256; const MAX_SAFE_INTEGER$4 = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */ 9007199254740991; // Max safe segment length for coercion. const MAX_SAFE_COMPONENT_LENGTH = 16; // Max safe length for a build identifier. The max length minus 6 characters for // the shortest version with a build 0.0.0+BUILD. const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH$1 - 6; const RELEASE_TYPES = [ 'major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease', ]; var constants$1 = { MAX_LENGTH: MAX_LENGTH$1, MAX_SAFE_COMPONENT_LENGTH, MAX_SAFE_BUILD_LENGTH, MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$4, RELEASE_TYPES, SEMVER_SPEC_VERSION, FLAG_INCLUDE_PRERELEASE: 0b001, FLAG_LOOSE: 0b010, }; const debug$7 = ( typeof process === 'object' && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ) ? (...args) => console.error('SEMVER', ...args) : () => {}; var debug_1$1 = debug$7; (function (module, exports) { const { MAX_SAFE_COMPONENT_LENGTH, MAX_SAFE_BUILD_LENGTH, MAX_LENGTH, } = constants$1; const debug = debug_1$1; exports = module.exports = {}; // The actual regexps go on exports.re const re = exports.re = []; const safeRe = exports.safeRe = []; const src = exports.src = []; const t = exports.t = {}; let R = 0; const LETTERDASHNUMBER = '[a-zA-Z0-9-]'; // Replace some greedy regex tokens to prevent regex dos issues. These regex are // used internally via the safeRe object since all inputs in this library get // normalized first to trim and collapse all extra whitespace. The original // regexes are exported for userland consumption and lower level usage. A // future breaking change could export the safer regex only with a note that // all input should have extra whitespace removed. const safeRegexReplacements = [ ['\\s', 1], ['\\d', MAX_LENGTH], [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], ]; const makeSafeRegex = (value) => { for (const [token, max] of safeRegexReplacements) { value = value .split(`${token}*`).join(`${token}{0,${max}}`) .split(`${token}+`).join(`${token}{1,${max}}`); } return value }; const createToken = (name, value, isGlobal) => { const safe = makeSafeRegex(value); const index = R++; debug(name, index, value); t[name] = index; src[index] = value; re[index] = new RegExp(value, isGlobal ? 'g' : undefined); safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined); }; // The following Regular Expressions can be used for tokenizing, // validating, and parsing SemVer version strings. // ## Numeric Identifier // A single `0`, or a non-zero digit followed by zero or more digits. createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*'); createToken('NUMERICIDENTIFIERLOOSE', '\\d+'); // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`); // ## Main Version // Three dot-separated numeric identifiers. createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` + `(${src[t.NUMERICIDENTIFIER]})\\.` + `(${src[t.NUMERICIDENTIFIER]})`); createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + `(${src[t.NUMERICIDENTIFIERLOOSE]})`); // ## Pre-release Version Identifier // A numeric identifier, or a non-numeric identifier. createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER] }|${src[t.NONNUMERICIDENTIFIER]})`); createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE] }|${src[t.NONNUMERICIDENTIFIER]})`); // ## Pre-release Version // Hyphen, followed by one or more dot-separated pre-release version // identifiers. createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER] }(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`); createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] }(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`); // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`); // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata // identifiers. createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER] }(?:\\.${src[t.BUILDIDENTIFIER]})*))`); // ## Full Version String // A main version, followed optionally by a pre-release version and // build metadata. // Note that the only major, minor, patch, and pre-release sections of // the version string are capturing groups. The build metadata is not a // capturing group, because it should not ever be used in version // comparison. createToken('FULLPLAIN', `v?${src[t.MAINVERSION] }${src[t.PRERELEASE]}?${ src[t.BUILD]}?`); createToken('FULL', `^${src[t.FULLPLAIN]}$`); // like full, but allows v1.2.3 and =1.2.3, which people do sometimes. // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty // common in the npm registry. createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE] }${src[t.PRERELEASELOOSE]}?${ src[t.BUILD]}?`); createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`); createToken('GTLT', '((?:<|>)?=?)'); // Something like "2.*" or "1.2.x". // Note that "x.x" is a valid xRange identifer, meaning "any version" // Only the first item is strictly required. createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`); createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`); createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + `(?:${src[t.PRERELEASE]})?${ src[t.BUILD]}?` + `)?)?`); createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + `(?:${src[t.PRERELEASELOOSE]})?${ src[t.BUILD]}?` + `)?)?`); createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`); createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`); // Coercion. // Extract anything that could conceivably be a part of a valid semver createToken('COERCEPLAIN', `${'(^|[^\\d])' + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`); createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`); createToken('COERCEFULL', src[t.COERCEPLAIN] + `(?:${src[t.PRERELEASE]})?` + `(?:${src[t.BUILD]})?` + `(?:$|[^\\d])`); createToken('COERCERTL', src[t.COERCE], true); createToken('COERCERTLFULL', src[t.COERCEFULL], true); // Tilde ranges. // Meaning is "reasonably at or greater than" createToken('LONETILDE', '(?:~>?)'); createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true); exports.tildeTrimReplace = '$1~'; createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`); createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`); // Caret ranges. // Meaning is "at least and backwards compatible with" createToken('LONECARET', '(?:\\^)'); createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true); exports.caretTrimReplace = '$1^'; createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`); createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`); // A simple gt/lt/eq thing, or just "" to indicate "any version" createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`); createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`); // An expression to strip any whitespace between the gtlt and the thing // it modifies, so that `> 1.2.3` ==> `>1.2.3` createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT] }\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true); exports.comparatorTrimReplace = '$1$2$3'; // Something like `1.2.3 - 1.2.4` // Note that these all use the loose form, because they'll be // checked against either the strict or loose comparator form // later. createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` + `\\s+-\\s+` + `(${src[t.XRANGEPLAIN]})` + `\\s*$`); createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + `\\s+-\\s+` + `(${src[t.XRANGEPLAINLOOSE]})` + `\\s*$`); // Star ranges basically just allow anything at all. createToken('STAR', '(<|>)?=?\\s*\\*'); // >=0.0.0 is like a star createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$'); createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$'); } (re$2, re$2.exports)); var reExports = re$2.exports; // parse out just the options we care about const looseOption = Object.freeze({ loose: true }); const emptyOpts = Object.freeze({ }); const parseOptions$1 = options => { if (!options) { return emptyOpts } if (typeof options !== 'object') { return looseOption } return options }; var parseOptions_1 = parseOptions$1; const numeric = /^[0-9]+$/; const compareIdentifiers$1 = (a, b) => { const anum = numeric.test(a); const bnum = numeric.test(b); if (anum && bnum) { a = +a; b = +b; } return a === b ? 0 : (anum && !bnum) ? -1 : (bnum && !anum) ? 1 : a < b ? -1 : 1 }; const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a); var identifiers$1 = { compareIdentifiers: compareIdentifiers$1, rcompareIdentifiers, }; const debug$6 = debug_1$1; const { MAX_LENGTH, MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$3 } = constants$1; const { safeRe: re$1, t: t$1 } = reExports; const parseOptions = parseOptions_1; const { compareIdentifiers } = identifiers$1; let SemVer$d = class SemVer { constructor (version, options) { options = parseOptions(options); if (version instanceof SemVer) { if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) { return version } else { version = version.version; } } else if (typeof version !== 'string') { throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) } if (version.length > MAX_LENGTH) { throw new TypeError( `version is longer than ${MAX_LENGTH} characters` ) } debug$6('SemVer', version, options); this.options = options; this.loose = !!options.loose; // this isn't actually relevant for versions, but keep it so that we // don't run into trouble passing this.options around. this.includePrerelease = !!options.includePrerelease; const m = version.trim().match(options.loose ? re$1[t$1.LOOSE] : re$1[t$1.FULL]); if (!m) { throw new TypeError(`Invalid Version: ${version}`) } this.raw = version; // these are actually numbers this.major = +m[1]; this.minor = +m[2]; this.patch = +m[3]; if (this.major > MAX_SAFE_INTEGER$3 || this.major < 0) { throw new TypeError('Invalid major version') } if (this.minor > MAX_SAFE_INTEGER$3 || this.minor < 0) { throw new TypeError('Invalid minor version') } if (this.patch > MAX_SAFE_INTEGER$3 || this.patch < 0) { throw new TypeError('Invalid patch version') } // numberify any prerelease numeric ids if (!m[4]) { this.prerelease = []; } else { this.prerelease = m[4].split('.').map((id) => { if (/^[0-9]+$/.test(id)) { const num = +id; if (num >= 0 && num < MAX_SAFE_INTEGER$3) { return num } } return id }); } this.build = m[5] ? m[5].split('.') : []; this.format(); } format () { this.version = `${this.major}.${this.minor}.${this.patch}`; if (this.prerelease.length) { this.version += `-${this.prerelease.join('.')}`; } return this.version } toString () { return this.version } compare (other) { debug$6('SemVer.compare', this.version, this.options, other); if (!(other instanceof SemVer)) { if (typeof other === 'string' && other === this.version) { return 0 } other = new SemVer(other, this.options); } if (other.version === this.version) { return 0 } return this.compareMain(other) || this.comparePre(other) } compareMain (other) { if (!(other instanceof SemVer)) { other = new SemVer(other, this.options); } return ( compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch) ) } comparePre (other) { if (!(other instanceof SemVer)) { other = new SemVer(other, this.options); } // NOT having a prerelease is > having one if (this.prerelease.length && !other.prerelease.length) { return -1 } else if (!this.prerelease.length && other.prerelease.length) { return 1 } else if (!this.prerelease.length && !other.prerelease.length) { return 0 } let i = 0; do { const a = this.prerelease[i]; const b = other.prerelease[i]; debug$6('prerelease compare', i, a, b); if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { return 1 } else if (a === undefined) { return -1 } else if (a === b) { continue } else { return compareIdentifiers(a, b) } } while (++i) } compareBuild (other) { if (!(other instanceof SemVer)) { other = new SemVer(other, this.options); } let i = 0; do { const a = this.build[i]; const b = other.build[i]; debug$6('build compare', i, a, b); if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { return 1 } else if (a === undefined) { return -1 } else if (a === b) { continue } else { return compareIdentifiers(a, b) } } while (++i) } // preminor will bump the version up to the next minor release, and immediately // down to pre-release. premajor and prepatch work the same way. inc (release, identifier, identifierBase) { switch (release) { case 'premajor': this.prerelease.length = 0; this.patch = 0; this.minor = 0; this.major++; this.inc('pre', identifier, identifierBase); break case 'preminor': this.prerelease.length = 0; this.patch = 0; this.minor++; this.inc('pre', identifier, identifierBase); break case 'prepatch': // If this is already a prerelease, it will bump to the next version // drop any prereleases that might already exist, since they are not // relevant at this point. this.prerelease.length = 0; this.inc('patch', identifier, identifierBase); this.inc('pre', identifier, identifierBase); break // If the input is a non-prerelease version, this acts the same as // prepatch. case 'prerelease': if (this.prerelease.length === 0) { this.inc('patch', identifier, identifierBase); } this.inc('pre', identifier, identifierBase); break case 'major': // If this is a pre-major version, bump up to the same major version. // Otherwise increment major. // 1.0.0-5 bumps to 1.0.0 // 1.1.0 bumps to 2.0.0 if ( this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0 ) { this.major++; } this.minor = 0; this.patch = 0; this.prerelease = []; break case 'minor': // If this is a pre-minor version, bump up to the same minor version. // Otherwise increment minor. // 1.2.0-5 bumps to 1.2.0 // 1.2.1 bumps to 1.3.0 if (this.patch !== 0 || this.prerelease.length === 0) { this.minor++; } this.patch = 0; this.prerelease = []; break case 'patch': // If this is not a pre-release version, it will increment the patch. // If it is a pre-release it will bump up to the same patch version. // 1.2.0-5 patches to 1.2.0 // 1.2.0 patches to 1.2.1 if (this.prerelease.length === 0) { this.patch++; } this.prerelease = []; break // This probably shouldn't be used publicly. // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. case 'pre': { const base = Number(identifierBase) ? 1 : 0; if (!identifier && identifierBase === false) { throw new Error('invalid increment argument: identifier is empty') } if (this.prerelease.length === 0) { this.prerelease = [base]; } else { let i = this.prerelease.length; while (--i >= 0) { if (typeof this.prerelease[i] === 'number') { this.prerelease[i]++; i = -2; } } if (i === -1) { // didn't increment anything if (identifier === this.prerelease.join('.') && identifierBase === false) { throw new Error('invalid increment argument: identifier already exists') } this.prerelease.push(base); } } if (identifier) { // 1.2.0-beta.1 bumps to 1.2.0-beta.2, // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 let prerelease = [identifier, base]; if (identifierBase === false) { prerelease = [identifier]; } if (compareIdentifiers(this.prerelease[0], identifier) === 0) { if (isNaN(this.prerelease[1])) { this.prerelease = prerelease; } } else { this.prerelease = prerelease; } } break } default: throw new Error(`invalid increment argument: ${release}`) } this.raw = this.format(); if (this.build.length) { this.raw += `+${this.build.join('.')}`; } return this } }; var semver$4 = SemVer$d; const SemVer$c = semver$4; const parse$6 = (version, options, throwErrors = false) => { if (version instanceof SemVer$c) { return version } try { return new SemVer$c(version, options) } catch (er) { if (!throwErrors) { return null } throw er } }; var parse_1 = parse$6; const parse$5 = parse_1; const valid$2 = (version, options) => { const v = parse$5(version, options); return v ? v.version : null }; var valid_1 = valid$2; const parse$4 = parse_1; const clean$1 = (version, options) => { const s = parse$4(version.trim().replace(/^[=v]+/, ''), options); return s ? s.version : null }; var clean_1 = clean$1; const SemVer$b = semver$4; const inc$1 = (version, release, options, identifier, identifierBase) => { if (typeof (options) === 'string') { identifierBase = identifier; identifier = options; options = undefined; } try { return new SemVer$b( version instanceof SemVer$b ? version.version : version, options ).inc(release, identifier, identifierBase).version } catch (er) { return null } }; var inc_1 = inc$1; const parse$3 = parse_1; const diff$1 = (version1, version2) => { const v1 = parse$3(version1, null, true); const v2 = parse$3(version2, null, true); const comparison = v1.compare(v2); if (comparison === 0) { return null } const v1Higher = comparison > 0; const highVersion = v1Higher ? v1 : v2; const lowVersion = v1Higher ? v2 : v1; const highHasPre = !!highVersion.prerelease.length; const lowHasPre = !!lowVersion.prerelease.length; if (lowHasPre && !highHasPre) { // Going from prerelease -> no prerelease requires some special casing // If the low version has only a major, then it will always be a major // Some examples: // 1.0.0-1 -> 1.0.0 // 1.0.0-1 -> 1.1.1 // 1.0.0-1 -> 2.0.0 if (!lowVersion.patch && !lowVersion.minor) { return 'major' } // Otherwise it can be determined by checking the high version if (highVersion.patch) { // anything higher than a patch bump would result in the wrong version return 'patch' } if (highVersion.minor) { // anything higher than a minor bump would result in the wrong version return 'minor' } // bumping major/minor/patch all have same result return 'major' } // add the `pre` prefix if we are going to a prerelease version const prefix = highHasPre ? 'pre' : ''; if (v1.major !== v2.major) { return prefix + 'major' } if (v1.minor !== v2.minor) { return prefix + 'minor' } if (v1.patch !== v2.patch) { return prefix + 'patch' } // high and low are preleases return 'prerelease' }; var diff_1 = diff$1; const SemVer$a = semver$4; const major$1 = (a, loose) => new SemVer$a(a, loose).major; var major_1 = major$1; const SemVer$9 = semver$4; const minor$1 = (a, loose) => new SemVer$9(a, loose).minor; var minor_1 = minor$1; const SemVer$8 = semver$4; const patch$1 = (a, loose) => new SemVer$8(a, loose).patch; var patch_1 = patch$1; const parse$2 = parse_1; const prerelease$1 = (version, options) => { const parsed = parse$2(version, options); return (parsed && parsed.prerelease.length) ? parsed.prerelease : null }; var prerelease_1 = prerelease$1; const SemVer$7 = semver$4; const compare$b = (a, b, loose) => new SemVer$7(a, loose).compare(new SemVer$7(b, loose)); var compare_1 = compare$b; const compare$a = compare_1; const rcompare$1 = (a, b, loose) => compare$a(b, a, loose); var rcompare_1 = rcompare$1; const compare$9 = compare_1; const compareLoose$1 = (a, b) => compare$9(a, b, true); var compareLoose_1 = compareLoose$1; const SemVer$6 = semver$4; const compareBuild$3 = (a, b, loose) => { const versionA = new SemVer$6(a, loose); const versionB = new SemVer$6(b, loose); return versionA.compare(versionB) || versionA.compareBuild(versionB) }; var compareBuild_1 = compareBuild$3; const compareBuild$2 = compareBuild_1; const sort$2 = (list, loose) => list.sort((a, b) => compareBuild$2(a, b, loose)); var sort_1 = sort$2; const compareBuild$1 = compareBuild_1; const rsort$1 = (list, loose) => list.sort((a, b) => compareBuild$1(b, a, loose)); var rsort_1 = rsort$1; const compare$8 = compare_1; const gt$4 = (a, b, loose) => compare$8(a, b, loose) > 0; var gt_1 = gt$4; const compare$7 = compare_1; const lt$3 = (a, b, loose) => compare$7(a, b, loose) < 0; var lt_1 = lt$3; const compare$6 = compare_1; const eq$3 = (a, b, loose) => compare$6(a, b, loose) === 0; var eq_1 = eq$3; const compare$5 = compare_1; const neq$2 = (a, b, loose) => compare$5(a, b, loose) !== 0; var neq_1 = neq$2; const compare$4 = compare_1; const gte$3 = (a, b, loose) => compare$4(a, b, loose) >= 0; var gte_1 = gte$3; const compare$3 = compare_1; const lte$3 = (a, b, loose) => compare$3(a, b, loose) <= 0; var lte_1 = lte$3; const eq$2 = eq_1; const neq$1 = neq_1; const gt$3 = gt_1; const gte$2 = gte_1; const lt$2 = lt_1; const lte$2 = lte_1; const cmp$1 = (a, op, b, loose) => { switch (op) { case '===': if (typeof a === 'object') { a = a.version; } if (typeof b === 'object') { b = b.version; } return a === b case '!==': if (typeof a === 'object') { a = a.version; } if (typeof b === 'object') { b = b.version; } return a !== b case '': case '=': case '==': return eq$2(a, b, loose) case '!=': return neq$1(a, b, loose) case '>': return gt$3(a, b, loose) case '>=': return gte$2(a, b, loose) case '<': return lt$2(a, b, loose) case '<=': return lte$2(a, b, loose) default: throw new TypeError(`Invalid operator: ${op}`) } }; var cmp_1 = cmp$1; const SemVer$5 = semver$4; const parse$1 = parse_1; const { safeRe: re, t } = reExports; const coerce$1 = (version, options) => { if (version instanceof SemVer$5) { return version } if (typeof version === 'number') { version = String(version); } if (typeof version !== 'string') { return null } options = options || {}; let match = null; if (!options.rtl) { match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]); } else { // Find the right-most coercible string that does not share // a terminus with a more left-ward coercible string. // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' // With includePrerelease option set, '1.2.3.4-rc' wants to coerce '2.3.4-rc', not '2.3.4' // // Walk through the string checking with a /g regexp // Manually set the index so as to pick up overlapping matches. // Stop when we get a match that ends at the string end, since no // coercible string can be more right-ward without the same terminus. const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL]; let next; while ((next = coerceRtlRegex.exec(version)) && (!match || match.index + match[0].length !== version.length) ) { if (!match || next.index + next[0].length !== match.index + match[0].length) { match = next; } coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length; } // leave it in a clean state coerceRtlRegex.lastIndex = -1; } if (match === null) { return null } const major = match[2]; const minor = match[3] || '0'; const patch = match[4] || '0'; const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : ''; const build = options.includePrerelease && match[6] ? `+${match[6]}` : ''; return parse$1(`${major}.${minor}.${patch}${prerelease}${build}`, options) }; var coerce_1 = coerce$1; class LRUCache { constructor () { this.max = 1000; this.map = new Map(); } get (key) { const value = this.map.get(key); if (value === undefined) { return undefined } else { // Remove the key from the map and add it to the end this.map.delete(key); this.map.set(key, value); return value } } delete (key) { return this.map.delete(key) } set (key, value) { const deleted = this.delete(key); if (!deleted && value !== undefined) { // If cache is full, delete the least recently used item if (this.map.size >= this.max) { const firstKey = this.map.keys().next().value; this.delete(firstKey); } this.map.set(key, value); } return this } } var lrucache = LRUCache; var range; var hasRequiredRange; function requireRange () { if (hasRequiredRange) return range; hasRequiredRange = 1; // hoisted class for cyclic dependency class Range { constructor (range, options) { options = parseOptions(options); if (range instanceof Range) { if ( range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease ) { return range } else { return new Range(range.raw, options) } } if (range instanceof Comparator) { // just put it in the set and return this.raw = range.value; this.set = [[range]]; this.format(); return this } this.options = options; this.loose = !!options.loose; this.includePrerelease = !!options.includePrerelease; // First reduce all whitespace as much as possible so we do not have to rely // on potentially slow regexes like \s*. This is then stored and used for // future error messages as well. this.raw = range .trim() .split(/\s+/) .join(' '); // First, split on || this.set = this.raw .split('||') // map the range to a 2d array of comparators .map(r => this.parseRange(r.trim())) // throw out any comparator lists that are empty // this generally means that it was not a valid range, which is allowed // in loose mode, but will still throw if the WHOLE range is invalid. .filter(c => c.length); if (!this.set.length) { throw new TypeError(`Invalid SemVer Range: ${this.raw}`) } // if we have any that are not the null set, throw out null sets. if (this.set.length > 1) { // keep the first one, in case they're all null sets const first = this.set[0]; this.set = this.set.filter(c => !isNullSet(c[0])); if (this.set.length === 0) { this.set = [first]; } else if (this.set.length > 1) { // if we have any that are *, then the range is just * for (const c of this.set) { if (c.length === 1 && isAny(c[0])) { this.set = [c]; break } } } } this.format(); } format () { this.range = this.set .map((comps) => comps.join(' ').trim()) .join('||') .trim(); return this.range } toString () { return this.range } parseRange (range) { // memoize range parsing for performance. // this is a very hot path, and fully deterministic. const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE); const memoKey = memoOpts + ':' + range; const cached = cache.get(memoKey); if (cached) { return cached } const loose = this.options.loose; // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]; range = range.replace(hr, hyphenReplace(this.options.includePrerelease)); debug('hyphen replace', range); // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace); debug('comparator trim', range); // `~ 1.2.3` => `~1.2.3` range = range.replace(re[t.TILDETRIM], tildeTrimReplace); debug('tilde trim', range); // `^ 1.2.3` => `^1.2.3` range = range.replace(re[t.CARETTRIM], caretTrimReplace); debug('caret trim', range); // At this point, the range is completely trimmed and // ready to be split into comparators. let rangeList = range .split(' ') .map(comp => parseComparator(comp, this.options)) .join(' ') .split(/\s+/) // >=0.0.0 is equivalent to * .map(comp => replaceGTE0(comp, this.options)); if (loose) { // in loose mode, throw out any that are not valid comparators rangeList = rangeList.filter(comp => { debug('loose invalid filter', comp, this.options); return !!comp.match(re[t.COMPARATORLOOSE]) }); } debug('range list', rangeList); // if any comparators are the null set, then replace with JUST null set // if more than one comparator, remove any * comparators // also, don't include the same comparator more than once const rangeMap = new Map(); const comparators = rangeList.map(comp => new Comparator(comp, this.options)); for (const comp of comparators) { if (isNullSet(comp)) { return [comp] } rangeMap.set(comp.value, comp); } if (rangeMap.size > 1 && rangeMap.has('')) { rangeMap.delete(''); } const result = [...rangeMap.values()]; cache.set(memoKey, result); return result } intersects (range, options) { if (!(range instanceof Range)) { throw new TypeError('a Range is required') } return this.set.some((thisComparators) => { return ( isSatisfiable(thisComparators, options) && range.set.some((rangeComparators) => { return ( isSatisfiable(rangeComparators, options) && thisComparators.every((thisComparator) => { return rangeComparators.every((rangeComparator) => { return thisComparator.intersects(rangeComparator, options) }) }) ) }) ) }) } // if ANY of the sets match ALL of its comparators, then pass test (version) { if (!version) { return false } if (typeof version === 'string') { try { version = new SemVer(version, this.options); } catch (er) { return false } } for (let i = 0; i < this.set.length; i++) { if (testSet(this.set[i], version, this.options)) { return true } } return false } } range = Range; const LRU = lrucache; const cache = new LRU(); const parseOptions = parseOptions_1; const Comparator = requireComparator(); const debug = debug_1$1; const SemVer = semver$4; const { safeRe: re, t, comparatorTrimReplace, tildeTrimReplace, caretTrimReplace, } = reExports; const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = constants$1; const isNullSet = c => c.value === '<0.0.0-0'; const isAny = c => c.value === ''; // take a set of comparators and determine whether there // exists a version which can satisfy it const isSatisfiable = (comparators, options) => { let result = true; const remainingComparators = comparators.slice(); let testComparator = remainingComparators.pop(); while (result && remainingComparators.length) { result = remainingComparators.every((otherComparator) => { return testComparator.intersects(otherComparator, options) }); testComparator = remainingComparators.pop(); } return result }; // comprised of xranges, tildes, stars, and gtlt's at this point. // already replaced the hyphen ranges // turn into a set of JUST comparators. const parseComparator = (comp, options) => { debug('comp', comp, options); comp = replaceCarets(comp, options); debug('caret', comp); comp = replaceTildes(comp, options); debug('tildes', comp); comp = replaceXRanges(comp, options); debug('xrange', comp); comp = replaceStars(comp, options); debug('stars', comp); return comp }; const isX = id => !id || id.toLowerCase() === 'x' || id === '*'; // ~, ~> --> * (any, kinda silly) // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0 // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0 // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 // ~0.0.1 --> >=0.0.1 <0.1.0-0 const replaceTildes = (comp, options) => { return comp .trim() .split(/\s+/) .map((c) => replaceTilde(c, options)) .join(' ') }; const replaceTilde = (comp, options) => { const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]; return comp.replace(r, (_, M, m, p, pr) => { debug('tilde', comp, _, M, m, p, pr); let ret; if (isX(M)) { ret = ''; } else if (isX(m)) { ret = `>=${M}.0.0 <${+M + 1}.0.0-0`; } else if (isX(p)) { // ~1.2 == >=1.2.0 <1.3.0-0 ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`; } else if (pr) { debug('replaceTilde pr', pr); ret = `>=${M}.${m}.${p}-${pr } <${M}.${+m + 1}.0-0`; } else { // ~1.2.3 == >=1.2.3 <1.3.0-0 ret = `>=${M}.${m}.${p } <${M}.${+m + 1}.0-0`; } debug('tilde return', ret); return ret }) }; // ^ --> * (any, kinda silly) // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0 // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0 // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0 // ^1.2.3 --> >=1.2.3 <2.0.0-0 // ^1.2.0 --> >=1.2.0 <2.0.0-0 // ^0.0.1 --> >=0.0.1 <0.0.2-0 // ^0.1.0 --> >=0.1.0 <0.2.0-0 const replaceCarets = (comp, options) => { return comp .trim() .split(/\s+/) .map((c) => replaceCaret(c, options)) .join(' ') }; const replaceCaret = (comp, options) => { debug('caret', comp, options); const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET]; const z = options.includePrerelease ? '-0' : ''; return comp.replace(r, (_, M, m, p, pr) => { debug('caret', comp, _, M, m, p, pr); let ret; if (isX(M)) { ret = ''; } else if (isX(m)) { ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`; } else if (isX(p)) { if (M === '0') { ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`; } else { ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`; } } else if (pr) { debug('replaceCaret pr', pr); if (M === '0') { if (m === '0') { ret = `>=${M}.${m}.${p}-${pr } <${M}.${m}.${+p + 1}-0`; } else { ret = `>=${M}.${m}.${p}-${pr } <${M}.${+m + 1}.0-0`; } } else { ret = `>=${M}.${m}.${p}-${pr } <${+M + 1}.0.0-0`; } } else { debug('no pr'); if (M === '0') { if (m === '0') { ret = `>=${M}.${m}.${p }${z} <${M}.${m}.${+p + 1}-0`; } else { ret = `>=${M}.${m}.${p }${z} <${M}.${+m + 1}.0-0`; } } else { ret = `>=${M}.${m}.${p } <${+M + 1}.0.0-0`; } } debug('caret return', ret); return ret }) }; const replaceXRanges = (comp, options) => { debug('replaceXRanges', comp, options); return comp .split(/\s+/) .map((c) => replaceXRange(c, options)) .join(' ') }; const replaceXRange = (comp, options) => { comp = comp.trim(); const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE]; return comp.replace(r, (ret, gtlt, M, m, p, pr) => { debug('xRange', comp, ret, gtlt, M, m, p, pr); const xM = isX(M); const xm = xM || isX(m); const xp = xm || isX(p); const anyX = xp; if (gtlt === '=' && anyX) { gtlt = ''; } // if we're including prereleases in the match, then we need // to fix this to -0, the lowest possible prerelease value pr = options.includePrerelease ? '-0' : ''; if (xM) { if (gtlt === '>' || gtlt === '<') { // nothing is allowed ret = '<0.0.0-0'; } else { // nothing is forbidden ret = '*'; } } else if (gtlt && anyX) { // we know patch is an x, because we have any x at all. // replace X with 0 if (xm) { m = 0; } p = 0; if (gtlt === '>') { // >1 => >=2.0.0 // >1.2 => >=1.3.0 gtlt = '>='; if (xm) { M = +M + 1; m = 0; p = 0; } else { m = +m + 1; p = 0; } } else if (gtlt === '<=') { // <=0.7.x is actually <0.8.0, since any 0.7.x should // pass. Similarly, <=7.x is actually <8.0.0, etc. gtlt = '<'; if (xm) { M = +M + 1; } else { m = +m + 1; } } if (gtlt === '<') { pr = '-0'; } ret = `${gtlt + M}.${m}.${p}${pr}`; } else if (xm) { ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`; } else if (xp) { ret = `>=${M}.${m}.0${pr } <${M}.${+m + 1}.0-0`; } debug('xRange return', ret); return ret }) }; // Because * is AND-ed with everything else in the comparator, // and '' means "any version", just remove the *s entirely. const replaceStars = (comp, options) => { debug('replaceStars', comp, options); // Looseness is ignored here. star is always as loose as it gets! return comp .trim() .replace(re[t.STAR], '') }; const replaceGTE0 = (comp, options) => { debug('replaceGTE0', comp, options); return comp .trim() .replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '') }; // This function is passed to string.replace(re[t.HYPHENRANGE]) // M, m, patch, prerelease, build // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 // 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do // 1.2 - 3.4 => >=1.2.0 <3.5.0-0 // TODO build? const hyphenReplace = incPr => ($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr) => { if (isX(fM)) { from = ''; } else if (isX(fm)) { from = `>=${fM}.0.0${incPr ? '-0' : ''}`; } else if (isX(fp)) { from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}`; } else if (fpr) { from = `>=${from}`; } else { from = `>=${from}${incPr ? '-0' : ''}`; } if (isX(tM)) { to = ''; } else if (isX(tm)) { to = `<${+tM + 1}.0.0-0`; } else if (isX(tp)) { to = `<${tM}.${+tm + 1}.0-0`; } else if (tpr) { to = `<=${tM}.${tm}.${tp}-${tpr}`; } else if (incPr) { to = `<${tM}.${tm}.${+tp + 1}-0`; } else { to = `<=${to}`; } return `${from} ${to}`.trim() }; const testSet = (set, version, options) => { for (let i = 0; i < set.length; i++) { if (!set[i].test(version)) { return false } } if (version.prerelease.length && !options.includePrerelease) { // Find the set of versions that are allowed to have prereleases // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 // That should allow `1.2.3-pr.2` to pass. // However, `1.2.4-alpha.notready` should NOT be allowed, // even though it's within the range set by the comparators. for (let i = 0; i < set.length; i++) { debug(set[i].semver); if (set[i].semver === Comparator.ANY) { continue } if (set[i].semver.prerelease.length > 0) { const allowed = set[i].semver; if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) { return true } } } // Version has a -pre, but it's not one of the ones we like. return false } return true }; return range; } var comparator; var hasRequiredComparator; function requireComparator () { if (hasRequiredComparator) return comparator; hasRequiredComparator = 1; const ANY = Symbol('SemVer ANY'); // hoisted class for cyclic dependency class Comparator { static get ANY () { return ANY } constructor (comp, options) { options = parseOptions(options); if (comp instanceof Comparator) { if (comp.loose === !!options.loose) { return comp } else { comp = comp.value; } } comp = comp.trim().split(/\s+/).join(' '); debug('comparator', comp, options); this.options = options; this.loose = !!options.loose; this.parse(comp); if (this.semver === ANY) { this.value = ''; } else { this.value = this.operator + this.semver.version; } debug('comp', this); } parse (comp) { const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]; const m = comp.match(r); if (!m) { throw new TypeError(`Invalid comparator: ${comp}`) } this.operator = m[1] !== undefined ? m[1] : ''; if (this.operator === '=') { this.operator = ''; } // if it literally is just '>' or '' then allow anything. if (!m[2]) { this.semver = ANY; } else { this.semver = new SemVer(m[2], this.options.loose); } } toString () { return this.value } test (version) { debug('Comparator.test', version, this.options.loose); if (this.semver === ANY || version === ANY) { return true } if (typeof version === 'string') { try { version = new SemVer(version, this.options); } catch (er) { return false } } return cmp(version, this.operator, this.semver, this.options) } intersects (comp, options) { if (!(comp instanceof Comparator)) { throw new TypeError('a Comparator is required') } if (this.operator === '') { if (this.value === '') { return true } return new Range(comp.value, options).test(this.value) } else if (comp.operator === '') { if (comp.value === '') { return true } return new Range(this.value, options).test(comp.semver) } options = parseOptions(options); // Special cases where nothing can possibly be lower if (options.includePrerelease && (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { return false } if (!options.includePrerelease && (this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) { return false } // Same direction increasing (> or >=) if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { return true } // Same direction decreasing (< or <=) if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { return true } // same SemVer and both sides are inclusive (<= or >=) if ( (this.semver.version === comp.semver.version) && this.operator.includes('=') && comp.operator.includes('=')) { return true } // opposite directions less than if (cmp(this.semver, '<', comp.semver, options) && this.operator.startsWith('>') && comp.operator.startsWith('<')) { return true } // opposite directions greater than if (cmp(this.semver, '>', comp.semver, options) && this.operator.startsWith('<') && comp.operator.startsWith('>')) { return true } return false } } comparator = Comparator; const parseOptions = parseOptions_1; const { safeRe: re, t } = reExports; const cmp = cmp_1; const debug = debug_1$1; const SemVer = semver$4; const Range = requireRange(); return comparator; } const Range$9 = requireRange(); const satisfies$4 = (version, range, options) => { try { range = new Range$9(range, options); } catch (er) { return false } return range.test(version) }; var satisfies_1 = satisfies$4; const Range$8 = requireRange(); // Mostly just for testing and legacy API reasons const toComparators$1 = (range, options) => new Range$8(range, options).set .map(comp => comp.map(c => c.value).join(' ').trim().split(' ')); var toComparators_1 = toComparators$1; const SemVer$4 = semver$4; const Range$7 = requireRange(); const maxSatisfying$1 = (versions, range, options) => { let max = null; let maxSV = null; let rangeObj = null; try { rangeObj = new Range$7(range, options); } catch (er) { return null } versions.forEach((v) => { if (rangeObj.test(v)) { // satisfies(v, range, options) if (!max || maxSV.compare(v) === -1) { // compare(max, v, true) max = v; maxSV = new SemVer$4(max, options); } } }); return max }; var maxSatisfying_1 = maxSatisfying$1; const SemVer$3 = semver$4; const Range$6 = requireRange(); const minSatisfying$1 = (versions, range, options) => { let min = null; let minSV = null; let rangeObj = null; try { rangeObj = new Range$6(range, options); } catch (er) { return null } versions.forEach((v) => { if (rangeObj.test(v)) { // satisfies(v, range, options) if (!min || minSV.compare(v) === 1) { // compare(min, v, true) min = v; minSV = new SemVer$3(min, options); } } }); return min }; var minSatisfying_1 = minSatisfying$1; const SemVer$2 = semver$4; const Range$5 = requireRange(); const gt$2 = gt_1; const minVersion$1 = (range, loose) => { range = new Range$5(range, loose); let minver = new SemVer$2('0.0.0'); if (range.test(minver)) { return minver } minver = new SemVer$2('0.0.0-0'); if (range.test(minver)) { return minver } minver = null; for (let i = 0; i < range.set.length; ++i) { const comparators = range.set[i]; let setMin = null; comparators.forEach((comparator) => { // Clone to avoid manipulating the comparator's semver object. const compver = new SemVer$2(comparator.semver.version); switch (comparator.operator) { case '>': if (compver.prerelease.length === 0) { compver.patch++; } else { compver.prerelease.push(0); } compver.raw = compver.format(); /* fallthrough */ case '': case '>=': if (!setMin || gt$2(compver, setMin)) { setMin = compver; } break case '<': case '<=': /* Ignore maximum versions */ break /* istanbul ignore next */ default: throw new Error(`Unexpected operation: ${comparator.operator}`) } }); if (setMin && (!minver || gt$2(minver, setMin))) { minver = setMin; } } if (minver && range.test(minver)) { return minver } return null }; var minVersion_1 = minVersion$1; const Range$4 = requireRange(); const validRange$1 = (range, options) => { try { // Return '*' instead of '' so that truthiness works. // This will throw if it's invalid anyway return new Range$4(range, options).range || '*' } catch (er) { return null } }; var valid$1 = validRange$1; const SemVer$1 = semver$4; const Comparator$2 = requireComparator(); const { ANY: ANY$1 } = Comparator$2; const Range$3 = requireRange(); const satisfies$3 = satisfies_1; const gt$1 = gt_1; const lt$1 = lt_1; const lte$1 = lte_1; const gte$1 = gte_1; const outside$3 = (version, range, hilo, options) => { version = new SemVer$1(version, options); range = new Range$3(range, options); let gtfn, ltefn, ltfn, comp, ecomp; switch (hilo) { case '>': gtfn = gt$1; ltefn = lte$1; ltfn = lt$1; comp = '>'; ecomp = '>='; break case '<': gtfn = lt$1; ltefn = gte$1; ltfn = gt$1; comp = '<'; ecomp = '<='; break default: throw new TypeError('Must provide a hilo val of "<" or ">"') } // If it satisfies the range it is not outside if (satisfies$3(version, range, options)) { return false } // From now on, variable terms are as if we're in "gtr" mode. // but note that everything is flipped for the "ltr" function. for (let i = 0; i < range.set.length; ++i) { const comparators = range.set[i]; let high = null; let low = null; comparators.forEach((comparator) => { if (comparator.semver === ANY$1) { comparator = new Comparator$2('>=0.0.0'); } high = high || comparator; low = low || comparator; if (gtfn(comparator.semver, high.semver, options)) { high = comparator; } else if (ltfn(comparator.semver, low.semver, options)) { low = comparator; } }); // If the edge version comparator has a operator then our version // isn't outside it if (high.operator === comp || high.operator === ecomp) { return false } // If the lowest version comparator has an operator and our version // is less than it then it isn't higher than the range if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) { return false } else if (low.operator === ecomp && ltfn(version, low.semver)) { return false } } return true }; var outside_1 = outside$3; // Determine if version is greater than all the versions possible in the range. const outside$2 = outside_1; const gtr$1 = (version, range, options) => outside$2(version, range, '>', options); var gtr_1 = gtr$1; const outside$1 = outside_1; // Determine if version is less than all the versions possible in the range const ltr$1 = (version, range, options) => outside$1(version, range, '<', options); var ltr_1 = ltr$1; const Range$2 = requireRange(); const intersects$1 = (r1, r2, options) => { r1 = new Range$2(r1, options); r2 = new Range$2(r2, options); return r1.intersects(r2, options) }; var intersects_1 = intersects$1; // given a set of versions and a range, create a "simplified" range // that includes the same versions that the original range does // If the original range is shorter than the simplified one, return that. const satisfies$2 = satisfies_1; const compare$2 = compare_1; var simplify = (versions, range, options) => { const set = []; let first = null; let prev = null; const v = versions.sort((a, b) => compare$2(a, b, options)); for (const version of v) { const included = satisfies$2(version, range, options); if (included) { prev = version; if (!first) { first = version; } } else { if (prev) { set.push([first, prev]); } prev = null; first = null; } } if (first) { set.push([first, null]); } const ranges = []; for (const [min, max] of set) { if (min === max) { ranges.push(min); } else if (!max && min === v[0]) { ranges.push('*'); } else if (!max) { ranges.push(`>=${min}`); } else if (min === v[0]) { ranges.push(`<=${max}`); } else { ranges.push(`${min} - ${max}`); } } const simplified = ranges.join(' || '); const original = typeof range.raw === 'string' ? range.raw : String(range); return simplified.length < original.length ? simplified : range }; const Range$1 = requireRange(); const Comparator$1 = requireComparator(); const { ANY } = Comparator$1; const satisfies$1 = satisfies_1; const compare$1 = compare_1; // Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff: // - Every simple range `r1, r2, ...` is a null set, OR // - Every simple range `r1, r2, ...` which is not a null set is a subset of // some `R1, R2, ...` // // Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff: // - If c is only the ANY comparator // - If C is only the ANY comparator, return true // - Else if in prerelease mode, return false // - else replace c with `[>=0.0.0]` // - If C is only the ANY comparator // - if in prerelease mode, return true // - else replace C with `[>=0.0.0]` // - Let EQ be the set of = comparators in c // - If EQ is more than one, return true (null set) // - Let GT be the highest > or >= comparator in c // - Let LT be the lowest < or <= comparator in c // - If GT and LT, and GT.semver > LT.semver, return true (null set) // - If any C is a = range, and GT or LT are set, return false // - If EQ // - If GT, and EQ does not satisfy GT, return true (null set) // - If LT, and EQ does not satisfy LT, return true (null set) // - If EQ satisfies every C, return true // - Else return false // - If GT // - If GT.semver is lower than any > or >= comp in C, return false // - If GT is >=, and GT.semver does not satisfy every C, return false // - If GT.semver has a prerelease, and not in prerelease mode // - If no C has a prerelease and the GT.semver tuple, return false // - If LT // - If LT.semver is greater than any < or <= comp in C, return false // - If LT is <=, and LT.semver does not satisfy every C, return false // - If GT.semver has a prerelease, and not in prerelease mode // - If no C has a prerelease and the LT.semver tuple, return false // - Else return true const subset$1 = (sub, dom, options = {}) => { if (sub === dom) { return true } sub = new Range$1(sub, options); dom = new Range$1(dom, options); let sawNonNull = false; OUTER: for (const simpleSub of sub.set) { for (const simpleDom of dom.set) { const isSub = simpleSubset(simpleSub, simpleDom, options); sawNonNull = sawNonNull || isSub !== null; if (isSub) { continue OUTER } } // the null set is a subset of everything, but null simple ranges in // a complex range should be ignored. so if we saw a non-null range, // then we know this isn't a subset, but if EVERY simple range was null, // then it is a subset. if (sawNonNull) { return false } } return true }; const minimumVersionWithPreRelease = [new Comparator$1('>=0.0.0-0')]; const minimumVersion = [new Comparator$1('>=0.0.0')]; const simpleSubset = (sub, dom, options) => { if (sub === dom) { return true } if (sub.length === 1 && sub[0].semver === ANY) { if (dom.length === 1 && dom[0].semver === ANY) { return true } else if (options.includePrerelease) { sub = minimumVersionWithPreRelease; } else { sub = minimumVersion; } } if (dom.length === 1 && dom[0].semver === ANY) { if (options.includePrerelease) { return true } else { dom = minimumVersion; } } const eqSet = new Set(); let gt, lt; for (const c of sub) { if (c.operator === '>' || c.operator === '>=') { gt = higherGT(gt, c, options); } else if (c.operator === '<' || c.operator === '<=') { lt = lowerLT(lt, c, options); } else { eqSet.add(c.semver); } } if (eqSet.size > 1) { return null } let gtltComp; if (gt && lt) { gtltComp = compare$1(gt.semver, lt.semver, options); if (gtltComp > 0) { return null } else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) { return null } } // will iterate one or zero times for (const eq of eqSet) { if (gt && !satisfies$1(eq, String(gt), options)) { return null } if (lt && !satisfies$1(eq, String(lt), options)) { return null } for (const c of dom) { if (!satisfies$1(eq, String(c), options)) { return false } } return true } let higher, lower; let hasDomLT, hasDomGT; // if the subset has a prerelease, we need a comparator in the superset // with the same tuple and a prerelease, or it's not a subset let needDomLTPre = lt && !options.includePrerelease && lt.semver.prerelease.length ? lt.semver : false; let needDomGTPre = gt && !options.includePrerelease && gt.semver.prerelease.length ? gt.semver : false; // exception: <1.2.3-0 is the same as <1.2.3 if (needDomLTPre && needDomLTPre.prerelease.length === 1 && lt.operator === '<' && needDomLTPre.prerelease[0] === 0) { needDomLTPre = false; } for (const c of dom) { hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>='; hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<='; if (gt) { if (needDomGTPre) { if (c.semver.prerelease && c.semver.prerelease.length && c.semver.major === needDomGTPre.major && c.semver.minor === needDomGTPre.minor && c.semver.patch === needDomGTPre.patch) { needDomGTPre = false; } } if (c.operator === '>' || c.operator === '>=') { higher = higherGT(gt, c, options); if (higher === c && higher !== gt) { return false } } else if (gt.operator === '>=' && !satisfies$1(gt.semver, String(c), options)) { return false } } if (lt) { if (needDomLTPre) { if (c.semver.prerelease && c.semver.prerelease.length && c.semver.major === needDomLTPre.major && c.semver.minor === needDomLTPre.minor && c.semver.patch === needDomLTPre.patch) { needDomLTPre = false; } } if (c.operator === '<' || c.operator === '<=') { lower = lowerLT(lt, c, options); if (lower === c && lower !== lt) { return false } } else if (lt.operator === '<=' && !satisfies$1(lt.semver, String(c), options)) { return false } } if (!c.operator && (lt || gt) && gtltComp !== 0) { return false } } // if there was a < or >, and nothing in the dom, then must be false // UNLESS it was limited by another range in the other direction. // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 if (gt && hasDomLT && !lt && gtltComp !== 0) { return false } if (lt && hasDomGT && !gt && gtltComp !== 0) { return false } // we needed a prerelease range in a specific tuple, but didn't get one // then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0, // because it includes prereleases in the 1.2.3 tuple if (needDomGTPre || needDomLTPre) { return false } return true }; // >=1.2.3 is lower than >1.2.3 const higherGT = (a, b, options) => { if (!a) { return b } const comp = compare$1(a.semver, b.semver, options); return comp > 0 ? a : comp < 0 ? b : b.operator === '>' && a.operator === '>=' ? b : a }; // <=1.2.3 is higher than <1.2.3 const lowerLT = (a, b, options) => { if (!a) { return b } const comp = compare$1(a.semver, b.semver, options); return comp < 0 ? a : comp > 0 ? b : b.operator === '<' && a.operator === '<=' ? b : a }; var subset_1 = subset$1; // just pre-load all the stuff that index.js lazily exports const internalRe = reExports; const constants = constants$1; const SemVer = semver$4; const identifiers = identifiers$1; const parse = parse_1; const valid = valid_1; const clean = clean_1; const inc = inc_1; const diff = diff_1; const major = major_1; const minor = minor_1; const patch = patch_1; const prerelease = prerelease_1; const compare = compare_1; const rcompare = rcompare_1; const compareLoose = compareLoose_1; const compareBuild = compareBuild_1; const sort$1 = sort_1; const rsort = rsort_1; const gt = gt_1; const lt = lt_1; const eq$1 = eq_1; const neq = neq_1; const gte = gte_1; const lte = lte_1; const cmp = cmp_1; const coerce = coerce_1; const Comparator = requireComparator(); const Range = requireRange(); const satisfies = satisfies_1; const toComparators = toComparators_1; const maxSatisfying = maxSatisfying_1; const minSatisfying = minSatisfying_1; const minVersion = minVersion_1; const validRange = valid$1; const outside = outside_1; const gtr = gtr_1; const ltr = ltr_1; const intersects = intersects_1; const simplifyRange = simplify; const subset = subset_1; var semver$3 = { parse, valid, clean, inc, diff, major, minor, patch, prerelease, compare, rcompare, compareLoose, compareBuild, sort: sort$1, rsort, gt, lt, eq: eq$1, neq, gte, lte, cmp, coerce, Comparator, Range, satisfies, toComparators, maxSatisfying, minSatisfying, minVersion, validRange, outside, gtr, ltr, intersects, simplifyRange, subset, SemVer, re: internalRe.re, src: internalRe.src, tokens: internalRe.t, SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, RELEASE_TYPES: constants.RELEASE_TYPES, compareIdentifiers: identifiers.compareIdentifiers, rcompareIdentifiers: identifiers.rcompareIdentifiers, }; const semver$2 = semver$3; var asymmetricKeyDetailsSupported = semver$2.satisfies(process.version, '>=15.7.0'); const semver$1 = semver$3; var rsaPssKeyDetailsSupported = semver$1.satisfies(process.version, '>=16.9.0'); const ASYMMETRIC_KEY_DETAILS_SUPPORTED = asymmetricKeyDetailsSupported; const RSA_PSS_KEY_DETAILS_SUPPORTED = rsaPssKeyDetailsSupported; const allowedAlgorithmsForKeys = { 'ec': ['ES256', 'ES384', 'ES512'], 'rsa': ['RS256', 'PS256', 'RS384', 'PS384', 'RS512', 'PS512'], 'rsa-pss': ['PS256', 'PS384', 'PS512'] }; const allowedCurves = { ES256: 'prime256v1', ES384: 'secp384r1', ES512: 'secp521r1', }; var validateAsymmetricKey$2 = function(algorithm, key) { if (!algorithm || !key) return; const keyType = key.asymmetricKeyType; if (!keyType) return; const allowedAlgorithms = allowedAlgorithmsForKeys[keyType]; if (!allowedAlgorithms) { throw new Error(`Unknown key type "${keyType}".`); } if (!allowedAlgorithms.includes(algorithm)) { throw new Error(`"alg" parameter for "${keyType}" key type must be one of: ${allowedAlgorithms.join(', ')}.`) } /* * Ignore the next block from test coverage because it gets executed * conditionally depending on the Node version. Not ignoring it would * prevent us from reaching the target % of coverage for versions of * Node under 15.7.0. */ /* istanbul ignore next */ if (ASYMMETRIC_KEY_DETAILS_SUPPORTED) { switch (keyType) { case 'ec': const keyCurve = key.asymmetricKeyDetails.namedCurve; const allowedCurve = allowedCurves[algorithm]; if (keyCurve !== allowedCurve) { throw new Error(`"alg" parameter "${algorithm}" requires curve "${allowedCurve}".`); } break; case 'rsa-pss': if (RSA_PSS_KEY_DETAILS_SUPPORTED) { const length = parseInt(algorithm.slice(-3), 10); const { hashAlgorithm, mgf1HashAlgorithm, saltLength } = key.asymmetricKeyDetails; if (hashAlgorithm !== `sha${length}` || mgf1HashAlgorithm !== hashAlgorithm) { throw new Error(`Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" ${algorithm}.`); } if (saltLength !== undefined && saltLength > length >> 3) { throw new Error(`Invalid key for this operation, its RSA-PSS parameter saltLength does not meet the requirements of "alg" ${algorithm}.`) } } break; } } }; var semver = semver$3; var psSupported = semver.satisfies(process.version, '^6.12.0 || >=8.0.0'); const JsonWebTokenError = JsonWebTokenError_1; const NotBeforeError = NotBeforeError_1; const TokenExpiredError = TokenExpiredError_1; const decode = decode$1; const timespan$1 = timespan$2; const validateAsymmetricKey$1 = validateAsymmetricKey$2; const PS_SUPPORTED$1 = psSupported; const jws$1 = jws$3; const {KeyObject: KeyObject$1, createSecretKey: createSecretKey$1, createPublicKey} = require$$0$3; const PUB_KEY_ALGS = ['RS256', 'RS384', 'RS512']; const EC_KEY_ALGS = ['ES256', 'ES384', 'ES512']; const RSA_KEY_ALGS = ['RS256', 'RS384', 'RS512']; const HS_ALGS = ['HS256', 'HS384', 'HS512']; if (PS_SUPPORTED$1) { PUB_KEY_ALGS.splice(PUB_KEY_ALGS.length, 0, 'PS256', 'PS384', 'PS512'); RSA_KEY_ALGS.splice(RSA_KEY_ALGS.length, 0, 'PS256', 'PS384', 'PS512'); } var verify = function (jwtString, secretOrPublicKey, options, callback) { if ((typeof options === 'function') && !callback) { callback = options; options = {}; } if (!options) { options = {}; } //clone this object since we are going to mutate it. options = Object.assign({}, options); let done; if (callback) { done = callback; } else { done = function(err, data) { if (err) throw err; return data; }; } if (options.clockTimestamp && typeof options.clockTimestamp !== 'number') { return done(new JsonWebTokenError('clockTimestamp must be a number')); } if (options.nonce !== undefined && (typeof options.nonce !== 'string' || options.nonce.trim() === '')) { return done(new JsonWebTokenError('nonce must be a non-empty string')); } if (options.allowInvalidAsymmetricKeyTypes !== undefined && typeof options.allowInvalidAsymmetricKeyTypes !== 'boolean') { return done(new JsonWebTokenError('allowInvalidAsymmetricKeyTypes must be a boolean')); } const clockTimestamp = options.clockTimestamp || Math.floor(Date.now() / 1000); if (!jwtString){ return done(new JsonWebTokenError('jwt must be provided')); } if (typeof jwtString !== 'string') { return done(new JsonWebTokenError('jwt must be a string')); } const parts = jwtString.split('.'); if (parts.length !== 3){ return done(new JsonWebTokenError('jwt malformed')); } let decodedToken; try { decodedToken = decode(jwtString, { complete: true }); } catch(err) { return done(err); } if (!decodedToken) { return done(new JsonWebTokenError('invalid token')); } const header = decodedToken.header; let getSecret; if(typeof secretOrPublicKey === 'function') { if(!callback) { return done(new JsonWebTokenError('verify must be called asynchronous if secret or public key is provided as a callback')); } getSecret = secretOrPublicKey; } else { getSecret = function(header, secretCallback) { return secretCallback(null, secretOrPublicKey); }; } return getSecret(header, function(err, secretOrPublicKey) { if(err) { return done(new JsonWebTokenError('error in secret or public key callback: ' + err.message)); } const hasSignature = parts[2].trim() !== ''; if (!hasSignature && secretOrPublicKey){ return done(new JsonWebTokenError('jwt signature is required')); } if (hasSignature && !secretOrPublicKey) { return done(new JsonWebTokenError('secret or public key must be provided')); } if (!hasSignature && !options.algorithms) { return done(new JsonWebTokenError('please specify "none" in "algorithms" to verify unsigned tokens')); } if (secretOrPublicKey != null && !(secretOrPublicKey instanceof KeyObject$1)) { try { secretOrPublicKey = createPublicKey(secretOrPublicKey); } catch (_) { try { secretOrPublicKey = createSecretKey$1(typeof secretOrPublicKey === 'string' ? Buffer.from(secretOrPublicKey) : secretOrPublicKey); } catch (_) { return done(new JsonWebTokenError('secretOrPublicKey is not valid key material')) } } } if (!options.algorithms) { if (secretOrPublicKey.type === 'secret') { options.algorithms = HS_ALGS; } else if (['rsa', 'rsa-pss'].includes(secretOrPublicKey.asymmetricKeyType)) { options.algorithms = RSA_KEY_ALGS; } else if (secretOrPublicKey.asymmetricKeyType === 'ec') { options.algorithms = EC_KEY_ALGS; } else { options.algorithms = PUB_KEY_ALGS; } } if (options.algorithms.indexOf(decodedToken.header.alg) === -1) { return done(new JsonWebTokenError('invalid algorithm')); } if (header.alg.startsWith('HS') && secretOrPublicKey.type !== 'secret') { return done(new JsonWebTokenError((`secretOrPublicKey must be a symmetric key when using ${header.alg}`))) } else if (/^(?:RS|PS|ES)/.test(header.alg) && secretOrPublicKey.type !== 'public') { return done(new JsonWebTokenError((`secretOrPublicKey must be an asymmetric key when using ${header.alg}`))) } if (!options.allowInvalidAsymmetricKeyTypes) { try { validateAsymmetricKey$1(header.alg, secretOrPublicKey); } catch (e) { return done(e); } } let valid; try { valid = jws$1.verify(jwtString, decodedToken.header.alg, secretOrPublicKey); } catch (e) { return done(e); } if (!valid) { return done(new JsonWebTokenError('invalid signature')); } const payload = decodedToken.payload; if (typeof payload.nbf !== 'undefined' && !options.ignoreNotBefore) { if (typeof payload.nbf !== 'number') { return done(new JsonWebTokenError('invalid nbf value')); } if (payload.nbf > clockTimestamp + (options.clockTolerance || 0)) { return done(new NotBeforeError('jwt not active', new Date(payload.nbf * 1000))); } } if (typeof payload.exp !== 'undefined' && !options.ignoreExpiration) { if (typeof payload.exp !== 'number') { return done(new JsonWebTokenError('invalid exp value')); } if (clockTimestamp >= payload.exp + (options.clockTolerance || 0)) { return done(new TokenExpiredError('jwt expired', new Date(payload.exp * 1000))); } } if (options.audience) { const audiences = Array.isArray(options.audience) ? options.audience : [options.audience]; const target = Array.isArray(payload.aud) ? payload.aud : [payload.aud]; const match = target.some(function (targetAudience) { return audiences.some(function (audience) { return audience instanceof RegExp ? audience.test(targetAudience) : audience === targetAudience; }); }); if (!match) { return done(new JsonWebTokenError('jwt audience invalid. expected: ' + audiences.join(' or '))); } } if (options.issuer) { const invalid_issuer = (typeof options.issuer === 'string' && payload.iss !== options.issuer) || (Array.isArray(options.issuer) && options.issuer.indexOf(payload.iss) === -1); if (invalid_issuer) { return done(new JsonWebTokenError('jwt issuer invalid. expected: ' + options.issuer)); } } if (options.subject) { if (payload.sub !== options.subject) { return done(new JsonWebTokenError('jwt subject invalid. expected: ' + options.subject)); } } if (options.jwtid) { if (payload.jti !== options.jwtid) { return done(new JsonWebTokenError('jwt jwtid invalid. expected: ' + options.jwtid)); } } if (options.nonce) { if (payload.nonce !== options.nonce) { return done(new JsonWebTokenError('jwt nonce invalid. expected: ' + options.nonce)); } } if (options.maxAge) { if (typeof payload.iat !== 'number') { return done(new JsonWebTokenError('iat required when maxAge is specified')); } const maxAgeTimestamp = timespan$1(options.maxAge, payload.iat); if (typeof maxAgeTimestamp === 'undefined') { return done(new JsonWebTokenError('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60')); } if (clockTimestamp >= maxAgeTimestamp + (options.clockTolerance || 0)) { return done(new TokenExpiredError('maxAge exceeded', new Date(maxAgeTimestamp * 1000))); } } if (options.complete === true) { const signature = decodedToken.signature; return done(null, { header: header, payload: payload, signature: signature }); } return done(null, payload); }); }; /** * lodash (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /** Used as references for various `Number` constants. */ var INFINITY$2 = 1 / 0, MAX_SAFE_INTEGER$2 = 9007199254740991, MAX_INTEGER$2 = 1.7976931348623157e+308, NAN$2 = 0 / 0; /** `Object#toString` result references. */ var argsTag$2 = '[object Arguments]', funcTag$2 = '[object Function]', genTag$2 = '[object GeneratorFunction]', stringTag$1 = '[object String]', symbolTag$2 = '[object Symbol]'; /** Used to match leading and trailing whitespace. */ var reTrim$2 = /^\s+|\s+$/g; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex$2 = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary$2 = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal$2 = /^0o[0-7]+$/i; /** Used to detect unsigned integer values. */ var reIsUint$1 = /^(?:0|[1-9]\d*)$/; /** Built-in method references without a dependency on `root`. */ var freeParseInt$2 = parseInt; /** * A specialized version of `_.map` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function arrayMap(array, iteratee) { var index = -1, length = array ? array.length : 0, result = Array(length); while (++index < length) { result[index] = iteratee(array[index], index, array); } return result; } /** * The base implementation of `_.findIndex` and `_.findLastIndex` without * support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Function} predicate The function invoked per iteration. * @param {number} fromIndex The index to search from. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseFindIndex(array, predicate, fromIndex, fromRight) { var length = array.length, index = fromIndex + (fromRight ? 1 : -1); while ((fromRight ? index-- : ++index < length)) { if (predicate(array[index], index, array)) { return index; } } return -1; } /** * The base implementation of `_.indexOf` without `fromIndex` bounds checks. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseIndexOf(array, value, fromIndex) { if (value !== value) { return baseFindIndex(array, baseIsNaN, fromIndex); } var index = fromIndex - 1, length = array.length; while (++index < length) { if (array[index] === value) { return index; } } return -1; } /** * The base implementation of `_.isNaN` without support for number objects. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. */ function baseIsNaN(value) { return value !== value; } /** * The base implementation of `_.times` without support for iteratee shorthands * or max array length checks. * * @private * @param {number} n The number of times to invoke `iteratee`. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the array of results. */ function baseTimes$1(n, iteratee) { var index = -1, result = Array(n); while (++index < n) { result[index] = iteratee(index); } return result; } /** * The base implementation of `_.values` and `_.valuesIn` which creates an * array of `object` property values corresponding to the property names * of `props`. * * @private * @param {Object} object The object to query. * @param {Array} props The property names to get values for. * @returns {Object} Returns the array of property values. */ function baseValues(object, props) { return arrayMap(props, function(key) { return object[key]; }); } /** * Creates a unary function that invokes `func` with its argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg$1(func, transform) { return function(arg) { return func(transform(arg)); }; } /** Used for built-in method references. */ var objectProto$8 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$3 = objectProto$8.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString$8 = objectProto$8.toString; /** Built-in value references. */ var propertyIsEnumerable$2 = objectProto$8.propertyIsEnumerable; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeKeys = overArg$1(Object.keys, Object), nativeMax$1 = Math.max; /** * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. * @param {boolean} inherited Specify returning inherited property names. * @returns {Array} Returns the array of property names. */ function arrayLikeKeys$1(value, inherited) { // Safari 8.1 makes `arguments.callee` enumerable in strict mode. // Safari 9 makes `arguments.length` enumerable in strict mode. var result = (isArray$2(value) || isArguments$3(value)) ? baseTimes$1(value.length, String) : []; var length = result.length, skipIndexes = !!length; for (var key in value) { if ((inherited || hasOwnProperty$3.call(value, key)) && !(skipIndexes && (key == 'length' || isIndex$1(key, length)))) { result.push(key); } } return result; } /** * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeys(object) { if (!isPrototype$1(object)) { return nativeKeys(object); } var result = []; for (var key in Object(object)) { if (hasOwnProperty$3.call(object, key) && key != 'constructor') { result.push(key); } } return result; } /** * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex$1(value, length) { length = length == null ? MAX_SAFE_INTEGER$2 : length; return !!length && (typeof value == 'number' || reIsUint$1.test(value)) && (value > -1 && value % 1 == 0 && value < length); } /** * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype$1(value) { var Ctor = value && value.constructor, proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$8; return value === proto; } /** * Checks if `value` is in `collection`. If `collection` is a string, it's * checked for a substring of `value`, otherwise * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * is used for equality comparisons. If `fromIndex` is negative, it's used as * the offset from the end of `collection`. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object|string} collection The collection to inspect. * @param {*} value The value to search for. * @param {number} [fromIndex=0] The index to search from. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. * @returns {boolean} Returns `true` if `value` is found, else `false`. * @example * * _.includes([1, 2, 3], 1); * // => true * * _.includes([1, 2, 3], 1, 2); * // => false * * _.includes({ 'a': 1, 'b': 2 }, 1); * // => true * * _.includes('abcd', 'bc'); * // => true */ function includes$1(collection, value, fromIndex, guard) { collection = isArrayLike$2(collection) ? collection : values(collection); fromIndex = (fromIndex && !guard) ? toInteger$2(fromIndex) : 0; var length = collection.length; if (fromIndex < 0) { fromIndex = nativeMax$1(length + fromIndex, 0); } return isString$2(collection) ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) : (!!length && baseIndexOf(collection, value, fromIndex) > -1); } /** * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, * else `false`. * @example * * _.isArguments(function() { return arguments; }()); * // => true * * _.isArguments([1, 2, 3]); * // => false */ function isArguments$3(value) { // Safari 8.1 makes `arguments.callee` enumerable in strict mode. return isArrayLikeObject$2(value) && hasOwnProperty$3.call(value, 'callee') && (!propertyIsEnumerable$2.call(value, 'callee') || objectToString$8.call(value) == argsTag$2); } /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray$2 = Array.isArray; /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike$2(value) { return value != null && isLength$2(value.length) && !isFunction$2(value); } /** * This method is like `_.isArrayLike` except that it also checks if `value` * is an object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, * else `false`. * @example * * _.isArrayLikeObject([1, 2, 3]); * // => true * * _.isArrayLikeObject(document.body.children); * // => true * * _.isArrayLikeObject('abc'); * // => false * * _.isArrayLikeObject(_.noop); * // => false */ function isArrayLikeObject$2(value) { return isObjectLike$8(value) && isArrayLike$2(value); } /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction$2(value) { // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 8-9 which returns 'object' for typed array and other constructors. var tag = isObject$4(value) ? objectToString$8.call(value) : ''; return tag == funcTag$2 || tag == genTag$2; } /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength$2(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$2; } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject$4(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike$8(value) { return !!value && typeof value == 'object'; } /** * Checks if `value` is classified as a `String` primitive or object. * * @static * @since 0.1.0 * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a string, else `false`. * @example * * _.isString('abc'); * // => true * * _.isString(1); * // => false */ function isString$2(value) { return typeof value == 'string' || (!isArray$2(value) && isObjectLike$8(value) && objectToString$8.call(value) == stringTag$1); } /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol$2(value) { return typeof value == 'symbol' || (isObjectLike$8(value) && objectToString$8.call(value) == symbolTag$2); } /** * Converts `value` to a finite number. * * @static * @memberOf _ * @since 4.12.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted number. * @example * * _.toFinite(3.2); * // => 3.2 * * _.toFinite(Number.MIN_VALUE); * // => 5e-324 * * _.toFinite(Infinity); * // => 1.7976931348623157e+308 * * _.toFinite('3.2'); * // => 3.2 */ function toFinite$2(value) { if (!value) { return value === 0 ? value : 0; } value = toNumber$2(value); if (value === INFINITY$2 || value === -INFINITY$2) { var sign = (value < 0 ? -1 : 1); return sign * MAX_INTEGER$2; } return value === value ? value : 0; } /** * Converts `value` to an integer. * * **Note:** This method is loosely based on * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toInteger(3.2); * // => 3 * * _.toInteger(Number.MIN_VALUE); * // => 0 * * _.toInteger(Infinity); * // => 1.7976931348623157e+308 * * _.toInteger('3.2'); * // => 3 */ function toInteger$2(value) { var result = toFinite$2(value), remainder = result % 1; return result === result ? (remainder ? result - remainder : result) : 0; } /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber$2(value) { if (typeof value == 'number') { return value; } if (isSymbol$2(value)) { return NAN$2; } if (isObject$4(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject$4(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim$2, ''); var isBinary = reIsBinary$2.test(value); return (isBinary || reIsOctal$2.test(value)) ? freeParseInt$2(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex$2.test(value) ? NAN$2 : +value); } /** * Creates an array of the own enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. See the * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * for more details. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keys(new Foo); * // => ['a', 'b'] (iteration order is not guaranteed) * * _.keys('hi'); * // => ['0', '1'] */ function keys$1(object) { return isArrayLike$2(object) ? arrayLikeKeys$1(object) : baseKeys(object); } /** * Creates an array of the own enumerable string keyed property values of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property values. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.values(new Foo); * // => [1, 2] (iteration order is not guaranteed) * * _.values('hi'); * // => ['h', 'i'] */ function values(object) { return object ? baseValues(object, keys$1(object)) : []; } var lodash_includes = includes$1; /** * lodash 3.0.3 (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright 2012-2016 The Dojo Foundation * Based on Underscore.js 1.8.3 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ /** `Object#toString` result references. */ var boolTag = '[object Boolean]'; /** Used for built-in method references. */ var objectProto$7 = Object.prototype; /** * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) * of values. */ var objectToString$7 = objectProto$7.toString; /** * Checks if `value` is classified as a boolean primitive or object. * * @static * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * * _.isBoolean(false); * // => true * * _.isBoolean(null); * // => false */ function isBoolean$1(value) { return value === true || value === false || (isObjectLike$7(value) && objectToString$7.call(value) == boolTag); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike$7(value) { return !!value && typeof value == 'object'; } var lodash_isboolean = isBoolean$1; /** * lodash (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /** Used as references for various `Number` constants. */ var INFINITY$1 = 1 / 0, MAX_INTEGER$1 = 1.7976931348623157e+308, NAN$1 = 0 / 0; /** `Object#toString` result references. */ var symbolTag$1 = '[object Symbol]'; /** Used to match leading and trailing whitespace. */ var reTrim$1 = /^\s+|\s+$/g; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex$1 = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary$1 = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal$1 = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt$1 = parseInt; /** Used for built-in method references. */ var objectProto$6 = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString$6 = objectProto$6.toString; /** * Checks if `value` is an integer. * * **Note:** This method is based on * [`Number.isInteger`](https://mdn.io/Number/isInteger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an integer, else `false`. * @example * * _.isInteger(3); * // => true * * _.isInteger(Number.MIN_VALUE); * // => false * * _.isInteger(Infinity); * // => false * * _.isInteger('3'); * // => false */ function isInteger$1(value) { return typeof value == 'number' && value == toInteger$1(value); } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject$3(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike$6(value) { return !!value && typeof value == 'object'; } /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol$1(value) { return typeof value == 'symbol' || (isObjectLike$6(value) && objectToString$6.call(value) == symbolTag$1); } /** * Converts `value` to a finite number. * * @static * @memberOf _ * @since 4.12.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted number. * @example * * _.toFinite(3.2); * // => 3.2 * * _.toFinite(Number.MIN_VALUE); * // => 5e-324 * * _.toFinite(Infinity); * // => 1.7976931348623157e+308 * * _.toFinite('3.2'); * // => 3.2 */ function toFinite$1(value) { if (!value) { return value === 0 ? value : 0; } value = toNumber$1(value); if (value === INFINITY$1 || value === -INFINITY$1) { var sign = (value < 0 ? -1 : 1); return sign * MAX_INTEGER$1; } return value === value ? value : 0; } /** * Converts `value` to an integer. * * **Note:** This method is loosely based on * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toInteger(3.2); * // => 3 * * _.toInteger(Number.MIN_VALUE); * // => 0 * * _.toInteger(Infinity); * // => 1.7976931348623157e+308 * * _.toInteger('3.2'); * // => 3 */ function toInteger$1(value) { var result = toFinite$1(value), remainder = result % 1; return result === result ? (remainder ? result - remainder : result) : 0; } /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber$1(value) { if (typeof value == 'number') { return value; } if (isSymbol$1(value)) { return NAN$1; } if (isObject$3(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject$3(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim$1, ''); var isBinary = reIsBinary$1.test(value); return (isBinary || reIsOctal$1.test(value)) ? freeParseInt$1(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex$1.test(value) ? NAN$1 : +value); } var lodash_isinteger = isInteger$1; /** * lodash 3.0.3 (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright 2012-2016 The Dojo Foundation * Based on Underscore.js 1.8.3 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ /** `Object#toString` result references. */ var numberTag = '[object Number]'; /** Used for built-in method references. */ var objectProto$5 = Object.prototype; /** * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) * of values. */ var objectToString$5 = objectProto$5.toString; /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike$5(value) { return !!value && typeof value == 'object'; } /** * Checks if `value` is classified as a `Number` primitive or object. * * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified * as numbers, use the `_.isFinite` method. * * @static * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * * _.isNumber(3); * // => true * * _.isNumber(Number.MIN_VALUE); * // => true * * _.isNumber(Infinity); * // => true * * _.isNumber('3'); * // => false */ function isNumber$1(value) { return typeof value == 'number' || (isObjectLike$5(value) && objectToString$5.call(value) == numberTag); } var lodash_isnumber = isNumber$1; /** * lodash (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /** `Object#toString` result references. */ var objectTag = '[object Object]'; /** * Checks if `value` is a host object in IE < 9. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a host object, else `false`. */ function isHostObject(value) { // Many host objects are `Object` objects that can coerce to strings // despite having improperly defined `toString` methods. var result = false; if (value != null && typeof value.toString != 'function') { try { result = !!(value + ''); } catch (e) {} } return result; } /** * Creates a unary function that invokes `func` with its argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg(func, transform) { return function(arg) { return func(transform(arg)); }; } /** Used for built-in method references. */ var funcProto = Function.prototype, objectProto$4 = Object.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString = funcProto.toString; /** Used to check objects for own properties. */ var hasOwnProperty$2 = objectProto$4.hasOwnProperty; /** Used to infer the `Object` constructor. */ var objectCtorString = funcToString.call(Object); /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString$4 = objectProto$4.toString; /** Built-in value references. */ var getPrototype = overArg(Object.getPrototypeOf, Object); /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike$4(value) { return !!value && typeof value == 'object'; } /** * Checks if `value` is a plain object, that is, an object created by the * `Object` constructor or one with a `[[Prototype]]` of `null`. * * @static * @memberOf _ * @since 0.8.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. * @example * * function Foo() { * this.a = 1; * } * * _.isPlainObject(new Foo); * // => false * * _.isPlainObject([1, 2, 3]); * // => false * * _.isPlainObject({ 'x': 0, 'y': 0 }); * // => true * * _.isPlainObject(Object.create(null)); * // => true */ function isPlainObject$1(value) { if (!isObjectLike$4(value) || objectToString$4.call(value) != objectTag || isHostObject(value)) { return false; } var proto = getPrototype(value); if (proto === null) { return true; } var Ctor = hasOwnProperty$2.call(proto, 'constructor') && proto.constructor; return (typeof Ctor == 'function' && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); } var lodash_isplainobject = isPlainObject$1; /** * lodash 4.0.1 (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright 2012-2016 The Dojo Foundation * Based on Underscore.js 1.8.3 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ /** `Object#toString` result references. */ var stringTag = '[object String]'; /** Used for built-in method references. */ var objectProto$3 = Object.prototype; /** * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) * of values. */ var objectToString$3 = objectProto$3.toString; /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @type Function * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray$1 = Array.isArray; /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike$3(value) { return !!value && typeof value == 'object'; } /** * Checks if `value` is classified as a `String` primitive or object. * * @static * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * * _.isString('abc'); * // => true * * _.isString(1); * // => false */ function isString$1(value) { return typeof value == 'string' || (!isArray$1(value) && isObjectLike$3(value) && objectToString$3.call(value) == stringTag); } var lodash_isstring = isString$1; /** * lodash (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0, MAX_INTEGER = 1.7976931348623157e+308, NAN = 0 / 0; /** `Object#toString` result references. */ var symbolTag = '[object Symbol]'; /** Used to match leading and trailing whitespace. */ var reTrim = /^\s+|\s+$/g; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt; /** Used for built-in method references. */ var objectProto$2 = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString$2 = objectProto$2.toString; /** * Creates a function that invokes `func`, with the `this` binding and arguments * of the created function, while it's called less than `n` times. Subsequent * calls to the created function return the result of the last `func` invocation. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {number} n The number of calls at which `func` is no longer invoked. * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * jQuery(element).on('click', _.before(5, addContactToList)); * // => Allows adding up to 4 contacts to the list. */ function before(n, func) { var result; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } n = toInteger(n); return function() { if (--n > 0) { result = func.apply(this, arguments); } if (n <= 1) { func = undefined; } return result; }; } /** * Creates a function that is restricted to invoking `func` once. Repeat calls * to the function return the value of the first invocation. The `func` is * invoked with the `this` binding and arguments of the created function. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * var initialize = _.once(createApplication); * initialize(); * initialize(); * // => `createApplication` is invoked once */ function once$1(func) { return before(2, func); } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject$2(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike$2(value) { return !!value && typeof value == 'object'; } /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike$2(value) && objectToString$2.call(value) == symbolTag); } /** * Converts `value` to a finite number. * * @static * @memberOf _ * @since 4.12.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted number. * @example * * _.toFinite(3.2); * // => 3.2 * * _.toFinite(Number.MIN_VALUE); * // => 5e-324 * * _.toFinite(Infinity); * // => 1.7976931348623157e+308 * * _.toFinite('3.2'); * // => 3.2 */ function toFinite(value) { if (!value) { return value === 0 ? value : 0; } value = toNumber(value); if (value === INFINITY || value === -INFINITY) { var sign = (value < 0 ? -1 : 1); return sign * MAX_INTEGER; } return value === value ? value : 0; } /** * Converts `value` to an integer. * * **Note:** This method is loosely based on * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toInteger(3.2); * // => 3 * * _.toInteger(Number.MIN_VALUE); * // => 0 * * _.toInteger(Infinity); * // => 1.7976931348623157e+308 * * _.toInteger('3.2'); * // => 3 */ function toInteger(value) { var result = toFinite(value), remainder = result % 1; return result === result ? (remainder ? result - remainder : result) : 0; } /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { return value; } if (isSymbol(value)) { return NAN; } if (isObject$2(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject$2(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim, ''); var isBinary = reIsBinary.test(value); return (isBinary || reIsOctal.test(value)) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex.test(value) ? NAN : +value); } var lodash_once = once$1; const timespan = timespan$2; const PS_SUPPORTED = psSupported; const validateAsymmetricKey = validateAsymmetricKey$2; const jws = jws$3; const includes = lodash_includes; const isBoolean = lodash_isboolean; const isInteger = lodash_isinteger; const isNumber = lodash_isnumber; const isPlainObject = lodash_isplainobject; const isString = lodash_isstring; const once = lodash_once; const { KeyObject, createSecretKey, createPrivateKey } = require$$0$3; const SUPPORTED_ALGS = ['RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512', 'HS256', 'HS384', 'HS512', 'none']; if (PS_SUPPORTED) { SUPPORTED_ALGS.splice(3, 0, 'PS256', 'PS384', 'PS512'); } const sign_options_schema = { expiresIn: { isValid: function(value) { return isInteger(value) || (isString(value) && value); }, message: '"expiresIn" should be a number of seconds or string representing a timespan' }, notBefore: { isValid: function(value) { return isInteger(value) || (isString(value) && value); }, message: '"notBefore" should be a number of seconds or string representing a timespan' }, audience: { isValid: function(value) { return isString(value) || Array.isArray(value); }, message: '"audience" must be a string or array' }, algorithm: { isValid: includes.bind(null, SUPPORTED_ALGS), message: '"algorithm" must be a valid string enum value' }, header: { isValid: isPlainObject, message: '"header" must be an object' }, encoding: { isValid: isString, message: '"encoding" must be a string' }, issuer: { isValid: isString, message: '"issuer" must be a string' }, subject: { isValid: isString, message: '"subject" must be a string' }, jwtid: { isValid: isString, message: '"jwtid" must be a string' }, noTimestamp: { isValid: isBoolean, message: '"noTimestamp" must be a boolean' }, keyid: { isValid: isString, message: '"keyid" must be a string' }, mutatePayload: { isValid: isBoolean, message: '"mutatePayload" must be a boolean' }, allowInsecureKeySizes: { isValid: isBoolean, message: '"allowInsecureKeySizes" must be a boolean'}, allowInvalidAsymmetricKeyTypes: { isValid: isBoolean, message: '"allowInvalidAsymmetricKeyTypes" must be a boolean'} }; const registered_claims_schema = { iat: { isValid: isNumber, message: '"iat" should be a number of seconds' }, exp: { isValid: isNumber, message: '"exp" should be a number of seconds' }, nbf: { isValid: isNumber, message: '"nbf" should be a number of seconds' } }; function validate(schema, allowUnknown, object, parameterName) { if (!isPlainObject(object)) { throw new Error('Expected "' + parameterName + '" to be a plain object.'); } Object.keys(object) .forEach(function(key) { const validator = schema[key]; if (!validator) { if (!allowUnknown) { throw new Error('"' + key + '" is not allowed in "' + parameterName + '"'); } return; } if (!validator.isValid(object[key])) { throw new Error(validator.message); } }); } function validateOptions(options) { return validate(sign_options_schema, false, options, 'options'); } function validatePayload(payload) { return validate(registered_claims_schema, true, payload, 'payload'); } const options_to_payload = { 'audience': 'aud', 'issuer': 'iss', 'subject': 'sub', 'jwtid': 'jti' }; const options_for_objects = [ 'expiresIn', 'notBefore', 'noTimestamp', 'audience', 'issuer', 'subject', 'jwtid', ]; var sign = function (payload, secretOrPrivateKey, options, callback) { if (typeof options === 'function') { callback = options; options = {}; } else { options = options || {}; } const isObjectPayload = typeof payload === 'object' && !Buffer.isBuffer(payload); const header = Object.assign({ alg: options.algorithm || 'HS256', typ: isObjectPayload ? 'JWT' : undefined, kid: options.keyid }, options.header); function failure(err) { if (callback) { return callback(err); } throw err; } if (!secretOrPrivateKey && options.algorithm !== 'none') { return failure(new Error('secretOrPrivateKey must have a value')); } if (secretOrPrivateKey != null && !(secretOrPrivateKey instanceof KeyObject)) { try { secretOrPrivateKey = createPrivateKey(secretOrPrivateKey); } catch (_) { try { secretOrPrivateKey = createSecretKey(typeof secretOrPrivateKey === 'string' ? Buffer.from(secretOrPrivateKey) : secretOrPrivateKey); } catch (_) { return failure(new Error('secretOrPrivateKey is not valid key material')); } } } if (header.alg.startsWith('HS') && secretOrPrivateKey.type !== 'secret') { return failure(new Error((`secretOrPrivateKey must be a symmetric key when using ${header.alg}`))) } else if (/^(?:RS|PS|ES)/.test(header.alg)) { if (secretOrPrivateKey.type !== 'private') { return failure(new Error((`secretOrPrivateKey must be an asymmetric key when using ${header.alg}`))) } if (!options.allowInsecureKeySizes && !header.alg.startsWith('ES') && secretOrPrivateKey.asymmetricKeyDetails !== undefined && //KeyObject.asymmetricKeyDetails is supported in Node 15+ secretOrPrivateKey.asymmetricKeyDetails.modulusLength < 2048) { return failure(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`)); } } if (typeof payload === 'undefined') { return failure(new Error('payload is required')); } else if (isObjectPayload) { try { validatePayload(payload); } catch (error) { return failure(error); } if (!options.mutatePayload) { payload = Object.assign({},payload); } } else { const invalid_options = options_for_objects.filter(function (opt) { return typeof options[opt] !== 'undefined'; }); if (invalid_options.length > 0) { return failure(new Error('invalid ' + invalid_options.join(',') + ' option for ' + (typeof payload ) + ' payload')); } } if (typeof payload.exp !== 'undefined' && typeof options.expiresIn !== 'undefined') { return failure(new Error('Bad "options.expiresIn" option the payload already has an "exp" property.')); } if (typeof payload.nbf !== 'undefined' && typeof options.notBefore !== 'undefined') { return failure(new Error('Bad "options.notBefore" option the payload already has an "nbf" property.')); } try { validateOptions(options); } catch (error) { return failure(error); } if (!options.allowInvalidAsymmetricKeyTypes) { try { validateAsymmetricKey(header.alg, secretOrPrivateKey); } catch (error) { return failure(error); } } const timestamp = payload.iat || Math.floor(Date.now() / 1000); if (options.noTimestamp) { delete payload.iat; } else if (isObjectPayload) { payload.iat = timestamp; } if (typeof options.notBefore !== 'undefined') { try { payload.nbf = timespan(options.notBefore, timestamp); } catch (err) { return failure(err); } if (typeof payload.nbf === 'undefined') { return failure(new Error('"notBefore" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60')); } } if (typeof options.expiresIn !== 'undefined' && typeof payload === 'object') { try { payload.exp = timespan(options.expiresIn, timestamp); } catch (err) { return failure(err); } if (typeof payload.exp === 'undefined') { return failure(new Error('"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60')); } } Object.keys(options_to_payload).forEach(function (key) { const claim = options_to_payload[key]; if (typeof options[key] !== 'undefined') { if (typeof payload[claim] !== 'undefined') { return failure(new Error('Bad "options.' + key + '" option. The payload already has an "' + claim + '" property.')); } payload[claim] = options[key]; } }); const encoding = options.encoding || 'utf8'; if (typeof callback === 'function') { callback = callback && once(callback); jws.createSign({ header: header, privateKey: secretOrPrivateKey, payload: payload, encoding: encoding }).once('error', callback) .once('done', function (signature) { // TODO: Remove in favor of the modulus length check before signing once node 15+ is the minimum supported version if(!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) { return callback(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`)) } callback(null, signature); }); } else { let signature = jws.sign({header: header, payload: payload, secret: secretOrPrivateKey, encoding: encoding}); // TODO: Remove in favor of the modulus length check before signing once node 15+ is the minimum supported version if(!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) { throw new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`) } return signature } }; var jsonwebtoken = { decode: decode$1, verify: verify, sign: sign, JsonWebTokenError: JsonWebTokenError_1, NotBeforeError: NotBeforeError_1, TokenExpiredError: TokenExpiredError_1, }; var jwt = /*@__PURE__*/getDefaultExportFromCjs(jsonwebtoken); function verify_token(provider, token) { return new Promise((resolve, reject) => { if (provider.JWKSClient === void 0) { return reject("JWKSClient not initialized"); } jwt.verify( token, (header, callback) => { provider.JWKSClient?.getSigningKey(header.kid, (err, key) => { const signingKey = key?.getPublicKey(); callback(err, signingKey); }); }, { complete: false }, (err, decoded) => { if (err || decoded === void 0 || typeof decoded === "string") { return reject(err); } return resolve(decoded); } ); }); } function commonjsRequire(path) { throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); } var jsonBuffer = {}; //TODO: handle reviver/dehydrate function like normal //and handle indentation, like normal. //if anyone needs this... please send pull request. jsonBuffer.stringify = function stringify (o) { if('undefined' == typeof o) return o if(o && Buffer.isBuffer(o)) return JSON.stringify(':base64:' + o.toString('base64')) if(o && o.toJSON) o = o.toJSON(); if(o && 'object' === typeof o) { var s = ''; var array = Array.isArray(o); s = array ? '[' : '{'; var first = true; for(var k in o) { var ignore = 'function' == typeof o[k] || (!array && 'undefined' === typeof o[k]); if(Object.hasOwnProperty.call(o, k) && !ignore) { if(!first) s += ','; first = false; if (array) { if(o[k] == undefined) s += 'null'; else s += stringify(o[k]); } else if (o[k] !== void(0)) { s += stringify(k) + ':' + stringify(o[k]); } } } s += array ? ']' : '}'; return s } else if ('string' === typeof o) { return JSON.stringify(/^:/.test(o) ? ':' + o : o) } else if ('undefined' === typeof o) { return 'null'; } else return JSON.stringify(o) }; jsonBuffer.parse = function (s) { return JSON.parse(s, function (key, value) { if('string' === typeof value) { if(/^:base64:/.test(value)) return Buffer.from(value.substring(8), 'base64') else return /^:/.test(value) ? value.substring(1) : value } return value }) }; const EventEmitter = require$$1$3; const JSONB = jsonBuffer; const loadStore = options => { const adapters = { redis: '@keyv/redis', rediss: '@keyv/redis', mongodb: '@keyv/mongo', mongo: '@keyv/mongo', sqlite: '@keyv/sqlite', postgresql: '@keyv/postgres', postgres: '@keyv/postgres', mysql: '@keyv/mysql', etcd: '@keyv/etcd', offline: '@keyv/offline', tiered: '@keyv/tiered', }; if (options.adapter || options.uri) { const adapter = options.adapter || /^[^:+]*/.exec(options.uri)[0]; return new (commonjsRequire(adapters[adapter]))(options); } return new Map(); }; const iterableAdapters = [ 'sqlite', 'postgres', 'mysql', 'mongo', 'redis', 'tiered', ]; class Keyv extends EventEmitter { constructor(uri, {emitErrors = true, ...options} = {}) { super(); this.opts = { namespace: 'keyv', serialize: JSONB.stringify, deserialize: JSONB.parse, ...((typeof uri === 'string') ? {uri} : uri), ...options, }; if (!this.opts.store) { const adapterOptions = {...this.opts}; this.opts.store = loadStore(adapterOptions); } if (this.opts.compression) { const compression = this.opts.compression; this.opts.serialize = compression.serialize.bind(compression); this.opts.deserialize = compression.deserialize.bind(compression); } if (typeof this.opts.store.on === 'function' && emitErrors) { this.opts.store.on('error', error => this.emit('error', error)); } this.opts.store.namespace = this.opts.namespace; const generateIterator = iterator => async function * () { for await (const [key, raw] of typeof iterator === 'function' ? iterator(this.opts.store.namespace) : iterator) { const data = await this.opts.deserialize(raw); if (this.opts.store.namespace && !key.includes(this.opts.store.namespace)) { continue; } if (typeof data.expires === 'number' && Date.now() > data.expires) { this.delete(key); continue; } yield [this._getKeyUnprefix(key), data.value]; } }; // Attach iterators if (typeof this.opts.store[Symbol.iterator] === 'function' && this.opts.store instanceof Map) { this.iterator = generateIterator(this.opts.store); } else if (typeof this.opts.store.iterator === 'function' && this.opts.store.opts && this._checkIterableAdaptar()) { this.iterator = generateIterator(this.opts.store.iterator.bind(this.opts.store)); } } _checkIterableAdaptar() { return iterableAdapters.includes(this.opts.store.opts.dialect) || iterableAdapters.findIndex(element => this.opts.store.opts.url.includes(element)) >= 0; } _getKeyPrefix(key) { return `${this.opts.namespace}:${key}`; } _getKeyPrefixArray(keys) { return keys.map(key => `${this.opts.namespace}:${key}`); } _getKeyUnprefix(key) { return key .split(':') .splice(1) .join(':'); } get(key, options) { const {store} = this.opts; const isArray = Array.isArray(key); const keyPrefixed = isArray ? this._getKeyPrefixArray(key) : this._getKeyPrefix(key); if (isArray && store.getMany === undefined) { const promises = []; for (const key of keyPrefixed) { promises.push(Promise.resolve() .then(() => store.get(key)) .then(data => (typeof data === 'string') ? this.opts.deserialize(data) : (this.opts.compression ? this.opts.deserialize(data) : data)) .then(data => { if (data === undefined || data === null) { return undefined; } if (typeof data.expires === 'number' && Date.now() > data.expires) { return this.delete(key).then(() => undefined); } return (options && options.raw) ? data : data.value; }), ); } return Promise.allSettled(promises) .then(values => { const data = []; for (const value of values) { data.push(value.value); } return data; }); } return Promise.resolve() .then(() => isArray ? store.getMany(keyPrefixed) : store.get(keyPrefixed)) .then(data => (typeof data === 'string') ? this.opts.deserialize(data) : (this.opts.compression ? this.opts.deserialize(data) : data)) .then(data => { if (data === undefined || data === null) { return undefined; } if (isArray) { return data.map((row, index) => { if ((typeof row === 'string')) { row = this.opts.deserialize(row); } if (row === undefined || row === null) { return undefined; } if (typeof row.expires === 'number' && Date.now() > row.expires) { this.delete(key[index]).then(() => undefined); return undefined; } return (options && options.raw) ? row : row.value; }); } if (typeof data.expires === 'number' && Date.now() > data.expires) { return this.delete(key).then(() => undefined); } return (options && options.raw) ? data : data.value; }); } set(key, value, ttl) { const keyPrefixed = this._getKeyPrefix(key); if (typeof ttl === 'undefined') { ttl = this.opts.ttl; } if (ttl === 0) { ttl = undefined; } const {store} = this.opts; return Promise.resolve() .then(() => { const expires = (typeof ttl === 'number') ? (Date.now() + ttl) : null; if (typeof value === 'symbol') { this.emit('error', 'symbol cannot be serialized'); } value = {value, expires}; return this.opts.serialize(value); }) .then(value => store.set(keyPrefixed, value, ttl)) .then(() => true); } delete(key) { const {store} = this.opts; if (Array.isArray(key)) { const keyPrefixed = this._getKeyPrefixArray(key); if (store.deleteMany === undefined) { const promises = []; for (const key of keyPrefixed) { promises.push(store.delete(key)); } return Promise.allSettled(promises) .then(values => values.every(x => x.value === true)); } return Promise.resolve() .then(() => store.deleteMany(keyPrefixed)); } const keyPrefixed = this._getKeyPrefix(key); return Promise.resolve() .then(() => store.delete(keyPrefixed)); } clear() { const {store} = this.opts; return Promise.resolve() .then(() => store.clear()); } has(key) { const keyPrefixed = this._getKeyPrefix(key); const {store} = this.opts; return Promise.resolve() .then(async () => { if (typeof store.has === 'function') { return store.has(keyPrefixed); } const value = await store.get(keyPrefixed); return value !== undefined; }); } disconnect() { const {store} = this.opts; if (typeof store.disconnect === 'function') { return store.disconnect(); } } } var src = Keyv; var Keyv$1 = /*@__PURE__*/getDefaultExportFromCjs(src); var built$2 = {exports: {}}; var Redis = {}; var built$1 = {}; var acl = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var append = { arity: 3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var asking = { arity: 1, flags: [ "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var auth = { arity: -2, flags: [ "noscript", "loading", "stale", "fast", "no_auth", "allow_busy" ], keyStart: 0, keyStop: 0, step: 0 }; var bgrewriteaof = { arity: 1, flags: [ "admin", "noscript", "no_async_loading" ], keyStart: 0, keyStop: 0, step: 0 }; var bgsave = { arity: -1, flags: [ "admin", "noscript", "no_async_loading" ], keyStart: 0, keyStop: 0, step: 0 }; var bitcount = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var bitfield = { arity: -2, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var bitfield_ro = { arity: -2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var bitop = { arity: -4, flags: [ "write", "denyoom" ], keyStart: 2, keyStop: -1, step: 1 }; var bitpos = { arity: -3, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var blmove = { arity: 6, flags: [ "write", "denyoom", "noscript", "blocking" ], keyStart: 1, keyStop: 2, step: 1 }; var blmpop = { arity: -5, flags: [ "write", "blocking", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var blpop = { arity: -3, flags: [ "write", "noscript", "blocking" ], keyStart: 1, keyStop: -2, step: 1 }; var brpop = { arity: -3, flags: [ "write", "noscript", "blocking" ], keyStart: 1, keyStop: -2, step: 1 }; var brpoplpush = { arity: 4, flags: [ "write", "denyoom", "noscript", "blocking" ], keyStart: 1, keyStop: 2, step: 1 }; var bzmpop = { arity: -5, flags: [ "write", "blocking", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var bzpopmax = { arity: -3, flags: [ "write", "noscript", "blocking", "fast" ], keyStart: 1, keyStop: -2, step: 1 }; var bzpopmin = { arity: -3, flags: [ "write", "noscript", "blocking", "fast" ], keyStart: 1, keyStop: -2, step: 1 }; var client = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var cluster$1 = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var command = { arity: -1, flags: [ "loading", "stale" ], keyStart: 0, keyStop: 0, step: 0 }; var config = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var copy = { arity: -3, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 2, step: 1 }; var dbsize = { arity: 1, flags: [ "readonly", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var debug$5 = { arity: -2, flags: [ "admin", "noscript", "loading", "stale" ], keyStart: 0, keyStop: 0, step: 0 }; var decr = { arity: 2, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var decrby = { arity: 3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var del = { arity: -2, flags: [ "write" ], keyStart: 1, keyStop: -1, step: 1 }; var discard = { arity: 1, flags: [ "noscript", "loading", "stale", "fast", "allow_busy" ], keyStart: 0, keyStop: 0, step: 0 }; var dump = { arity: 2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var echo = { arity: 2, flags: [ "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var eval_ro = { arity: -3, flags: [ "readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var evalsha = { arity: -3, flags: [ "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var evalsha_ro = { arity: -3, flags: [ "readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var exec = { arity: 1, flags: [ "noscript", "loading", "stale", "skip_slowlog" ], keyStart: 0, keyStop: 0, step: 0 }; var exists = { arity: -2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: -1, step: 1 }; var expire = { arity: -3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var expireat = { arity: -3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var expiretime = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var failover = { arity: -1, flags: [ "admin", "noscript", "stale" ], keyStart: 0, keyStop: 0, step: 0 }; var fcall = { arity: -3, flags: [ "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var fcall_ro = { arity: -3, flags: [ "readonly", "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var flushall = { arity: -1, flags: [ "write" ], keyStart: 0, keyStop: 0, step: 0 }; var flushdb = { arity: -1, flags: [ "write" ], keyStart: 0, keyStop: 0, step: 0 }; var geoadd = { arity: -5, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var geodist = { arity: -4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var geohash = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var geopos = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var georadius = { arity: -6, flags: [ "write", "denyoom", "movablekeys" ], keyStart: 1, keyStop: 1, step: 1 }; var georadius_ro = { arity: -6, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var georadiusbymember = { arity: -5, flags: [ "write", "denyoom", "movablekeys" ], keyStart: 1, keyStop: 1, step: 1 }; var georadiusbymember_ro = { arity: -5, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var geosearch = { arity: -7, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var geosearchstore = { arity: -8, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 2, step: 1 }; var get = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var getbit = { arity: 3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var getdel = { arity: 2, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var getex = { arity: -2, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var getrange = { arity: 4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var getset = { arity: 3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hdel = { arity: -3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hello = { arity: -1, flags: [ "noscript", "loading", "stale", "fast", "no_auth", "allow_busy" ], keyStart: 0, keyStop: 0, step: 0 }; var hexists = { arity: 3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hget = { arity: 3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hgetall = { arity: 2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var hincrby = { arity: 4, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hincrbyfloat = { arity: 4, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hkeys = { arity: 2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var hlen = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hmget = { arity: -3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hmset = { arity: -4, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hrandfield = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var hscan = { arity: -3, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var hset = { arity: -4, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hsetnx = { arity: 4, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hstrlen = { arity: 3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var hvals = { arity: 2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var incr = { arity: 2, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var incrby = { arity: 3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var incrbyfloat = { arity: 3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var info = { arity: -1, flags: [ "loading", "stale" ], keyStart: 0, keyStop: 0, step: 0 }; var keys = { arity: 2, flags: [ "readonly" ], keyStart: 0, keyStop: 0, step: 0 }; var lastsave = { arity: 1, flags: [ "loading", "stale", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var latency = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var lcs = { arity: -3, flags: [ "readonly" ], keyStart: 1, keyStop: 2, step: 1 }; var lindex = { arity: 3, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var linsert = { arity: 5, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var llen = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var lmove = { arity: 5, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 2, step: 1 }; var lmpop = { arity: -4, flags: [ "write", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var lolwut = { arity: -1, flags: [ "readonly", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var lpop = { arity: -2, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var lpos = { arity: -3, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var lpush = { arity: -3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var lpushx = { arity: -3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var lrange = { arity: 4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var lrem = { arity: 4, flags: [ "write" ], keyStart: 1, keyStop: 1, step: 1 }; var lset = { arity: 4, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var ltrim = { arity: 4, flags: [ "write" ], keyStart: 1, keyStop: 1, step: 1 }; var memory = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var mget = { arity: -2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: -1, step: 1 }; var migrate = { arity: -6, flags: [ "write", "movablekeys" ], keyStart: 3, keyStop: 3, step: 1 }; var module$1 = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var monitor = { arity: 1, flags: [ "admin", "noscript", "loading", "stale" ], keyStart: 0, keyStop: 0, step: 0 }; var move = { arity: 3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var mset = { arity: -3, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: -1, step: 2 }; var msetnx = { arity: -3, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: -1, step: 2 }; var multi$1 = { arity: 1, flags: [ "noscript", "loading", "stale", "fast", "allow_busy" ], keyStart: 0, keyStop: 0, step: 0 }; var object = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var persist = { arity: 2, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var pexpire = { arity: -3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var pexpireat = { arity: -3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var pexpiretime = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var pfadd = { arity: -2, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var pfcount = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: -1, step: 1 }; var pfdebug = { arity: 3, flags: [ "write", "denyoom", "admin" ], keyStart: 2, keyStop: 2, step: 1 }; var pfmerge = { arity: -2, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: -1, step: 1 }; var pfselftest = { arity: 1, flags: [ "admin" ], keyStart: 0, keyStop: 0, step: 0 }; var ping = { arity: -1, flags: [ "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var psetex = { arity: 4, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var psubscribe = { arity: -2, flags: [ "pubsub", "noscript", "loading", "stale" ], keyStart: 0, keyStop: 0, step: 0 }; var psync = { arity: -3, flags: [ "admin", "noscript", "no_async_loading", "no_multi" ], keyStart: 0, keyStop: 0, step: 0 }; var pttl = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var publish = { arity: 3, flags: [ "pubsub", "loading", "stale", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var pubsub = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var punsubscribe = { arity: -1, flags: [ "pubsub", "noscript", "loading", "stale" ], keyStart: 0, keyStop: 0, step: 0 }; var quit = { arity: -1, flags: [ "noscript", "loading", "stale", "fast", "no_auth", "allow_busy" ], keyStart: 0, keyStop: 0, step: 0 }; var randomkey = { arity: 1, flags: [ "readonly" ], keyStart: 0, keyStop: 0, step: 0 }; var readonly = { arity: 1, flags: [ "loading", "stale", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var readwrite = { arity: 1, flags: [ "loading", "stale", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var rename = { arity: 3, flags: [ "write" ], keyStart: 1, keyStop: 2, step: 1 }; var renamenx = { arity: 3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 2, step: 1 }; var replconf = { arity: -1, flags: [ "admin", "noscript", "loading", "stale", "allow_busy" ], keyStart: 0, keyStop: 0, step: 0 }; var replicaof = { arity: 3, flags: [ "admin", "noscript", "stale", "no_async_loading" ], keyStart: 0, keyStop: 0, step: 0 }; var reset = { arity: 1, flags: [ "noscript", "loading", "stale", "fast", "no_auth", "allow_busy" ], keyStart: 0, keyStop: 0, step: 0 }; var restore = { arity: -4, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var role = { arity: 1, flags: [ "noscript", "loading", "stale", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var rpop = { arity: -2, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var rpoplpush = { arity: 3, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 2, step: 1 }; var rpush = { arity: -3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var rpushx = { arity: -3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var sadd = { arity: -3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var save = { arity: 1, flags: [ "admin", "noscript", "no_async_loading", "no_multi" ], keyStart: 0, keyStop: 0, step: 0 }; var scan = { arity: -2, flags: [ "readonly" ], keyStart: 0, keyStop: 0, step: 0 }; var scard = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var script = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var sdiff = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: -1, step: 1 }; var sdiffstore = { arity: -3, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: -1, step: 1 }; var select = { arity: 2, flags: [ "loading", "stale", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var set = { arity: -3, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var setbit = { arity: 4, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var setex = { arity: 4, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var setnx = { arity: 3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var setrange = { arity: 4, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 1, step: 1 }; var shutdown = { arity: -1, flags: [ "admin", "noscript", "loading", "stale", "no_multi", "allow_busy" ], keyStart: 0, keyStop: 0, step: 0 }; var sinter = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: -1, step: 1 }; var sintercard = { arity: -3, flags: [ "readonly", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var sinterstore = { arity: -3, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: -1, step: 1 }; var sismember = { arity: 3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var slaveof = { arity: 3, flags: [ "admin", "noscript", "stale", "no_async_loading" ], keyStart: 0, keyStop: 0, step: 0 }; var slowlog = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var smembers = { arity: 2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var smismember = { arity: -3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var smove = { arity: 4, flags: [ "write", "fast" ], keyStart: 1, keyStop: 2, step: 1 }; var sort = { arity: -2, flags: [ "write", "denyoom", "movablekeys" ], keyStart: 1, keyStop: 1, step: 1 }; var sort_ro = { arity: -2, flags: [ "readonly", "movablekeys" ], keyStart: 1, keyStop: 1, step: 1 }; var spop = { arity: -2, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var spublish = { arity: 3, flags: [ "pubsub", "loading", "stale", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var srandmember = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var srem = { arity: -3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var sscan = { arity: -3, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var ssubscribe = { arity: -2, flags: [ "pubsub", "noscript", "loading", "stale" ], keyStart: 1, keyStop: -1, step: 1 }; var strlen = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var subscribe = { arity: -2, flags: [ "pubsub", "noscript", "loading", "stale" ], keyStart: 0, keyStop: 0, step: 0 }; var substr = { arity: 4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var sunion = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: -1, step: 1 }; var sunionstore = { arity: -3, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: -1, step: 1 }; var sunsubscribe = { arity: -1, flags: [ "pubsub", "noscript", "loading", "stale" ], keyStart: 1, keyStop: -1, step: 1 }; var swapdb = { arity: 3, flags: [ "write", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var sync = { arity: 1, flags: [ "admin", "noscript", "no_async_loading", "no_multi" ], keyStart: 0, keyStop: 0, step: 0 }; var time = { arity: 1, flags: [ "loading", "stale", "fast" ], keyStart: 0, keyStop: 0, step: 0 }; var touch = { arity: -2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: -1, step: 1 }; var ttl = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var type = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var unlink = { arity: -2, flags: [ "write", "fast" ], keyStart: 1, keyStop: -1, step: 1 }; var unsubscribe = { arity: -1, flags: [ "pubsub", "noscript", "loading", "stale" ], keyStart: 0, keyStop: 0, step: 0 }; var unwatch = { arity: 1, flags: [ "noscript", "loading", "stale", "fast", "allow_busy" ], keyStart: 0, keyStop: 0, step: 0 }; var wait = { arity: 3, flags: [ "noscript" ], keyStart: 0, keyStop: 0, step: 0 }; var watch = { arity: -2, flags: [ "noscript", "loading", "stale", "fast", "allow_busy" ], keyStart: 1, keyStop: -1, step: 1 }; var xack = { arity: -4, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var xadd = { arity: -5, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var xautoclaim = { arity: -6, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var xclaim = { arity: -6, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var xdel = { arity: -3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var xgroup = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var xinfo = { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }; var xlen = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var xpending = { arity: -3, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var xrange = { arity: -4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var xread = { arity: -4, flags: [ "readonly", "blocking", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var xreadgroup = { arity: -7, flags: [ "write", "blocking", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var xrevrange = { arity: -4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var xsetid = { arity: -3, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var xtrim = { arity: -4, flags: [ "write" ], keyStart: 1, keyStop: 1, step: 1 }; var zadd = { arity: -4, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zcard = { arity: 2, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zcount = { arity: 4, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zdiff = { arity: -3, flags: [ "readonly", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var zdiffstore = { arity: -4, flags: [ "write", "denyoom", "movablekeys" ], keyStart: 1, keyStop: 1, step: 1 }; var zincrby = { arity: 4, flags: [ "write", "denyoom", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zinter = { arity: -3, flags: [ "readonly", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var zintercard = { arity: -3, flags: [ "readonly", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var zinterstore = { arity: -4, flags: [ "write", "denyoom", "movablekeys" ], keyStart: 1, keyStop: 1, step: 1 }; var zlexcount = { arity: 4, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zmpop = { arity: -4, flags: [ "write", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var zmscore = { arity: -3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zpopmax = { arity: -2, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zpopmin = { arity: -2, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zrandmember = { arity: -2, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var zrange = { arity: -4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var zrangebylex = { arity: -4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var zrangebyscore = { arity: -4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var zrangestore = { arity: -5, flags: [ "write", "denyoom" ], keyStart: 1, keyStop: 2, step: 1 }; var zrank = { arity: 3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zrem = { arity: -3, flags: [ "write", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zremrangebylex = { arity: 4, flags: [ "write" ], keyStart: 1, keyStop: 1, step: 1 }; var zremrangebyrank = { arity: 4, flags: [ "write" ], keyStart: 1, keyStop: 1, step: 1 }; var zremrangebyscore = { arity: 4, flags: [ "write" ], keyStart: 1, keyStop: 1, step: 1 }; var zrevrange = { arity: -4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var zrevrangebylex = { arity: -4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var zrevrangebyscore = { arity: -4, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var zrevrank = { arity: 3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zscan = { arity: -3, flags: [ "readonly" ], keyStart: 1, keyStop: 1, step: 1 }; var zscore = { arity: 3, flags: [ "readonly", "fast" ], keyStart: 1, keyStop: 1, step: 1 }; var zunion = { arity: -3, flags: [ "readonly", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }; var zunionstore = { arity: -4, flags: [ "write", "denyoom", "movablekeys" ], keyStart: 1, keyStop: 1, step: 1 }; var require$$0 = { acl: acl, append: append, asking: asking, auth: auth, bgrewriteaof: bgrewriteaof, bgsave: bgsave, bitcount: bitcount, bitfield: bitfield, bitfield_ro: bitfield_ro, bitop: bitop, bitpos: bitpos, blmove: blmove, blmpop: blmpop, blpop: blpop, brpop: brpop, brpoplpush: brpoplpush, bzmpop: bzmpop, bzpopmax: bzpopmax, bzpopmin: bzpopmin, client: client, cluster: cluster$1, command: command, config: config, copy: copy, dbsize: dbsize, debug: debug$5, decr: decr, decrby: decrby, del: del, discard: discard, dump: dump, echo: echo, "eval": { arity: -3, flags: [ "noscript", "stale", "skip_monitor", "no_mandatory_keys", "movablekeys" ], keyStart: 0, keyStop: 0, step: 0 }, eval_ro: eval_ro, evalsha: evalsha, evalsha_ro: evalsha_ro, exec: exec, exists: exists, expire: expire, expireat: expireat, expiretime: expiretime, failover: failover, fcall: fcall, fcall_ro: fcall_ro, flushall: flushall, flushdb: flushdb, "function": { arity: -2, flags: [ ], keyStart: 0, keyStop: 0, step: 0 }, geoadd: geoadd, geodist: geodist, geohash: geohash, geopos: geopos, georadius: georadius, georadius_ro: georadius_ro, georadiusbymember: georadiusbymember, georadiusbymember_ro: georadiusbymember_ro, geosearch: geosearch, geosearchstore: geosearchstore, get: get, getbit: getbit, getdel: getdel, getex: getex, getrange: getrange, getset: getset, hdel: hdel, hello: hello, hexists: hexists, hget: hget, hgetall: hgetall, hincrby: hincrby, hincrbyfloat: hincrbyfloat, hkeys: hkeys, hlen: hlen, hmget: hmget, hmset: hmset, hrandfield: hrandfield, hscan: hscan, hset: hset, hsetnx: hsetnx, hstrlen: hstrlen, hvals: hvals, incr: incr, incrby: incrby, incrbyfloat: incrbyfloat, info: info, keys: keys, lastsave: lastsave, latency: latency, lcs: lcs, lindex: lindex, linsert: linsert, llen: llen, lmove: lmove, lmpop: lmpop, lolwut: lolwut, lpop: lpop, lpos: lpos, lpush: lpush, lpushx: lpushx, lrange: lrange, lrem: lrem, lset: lset, ltrim: ltrim, memory: memory, mget: mget, migrate: migrate, module: module$1, monitor: monitor, move: move, mset: mset, msetnx: msetnx, multi: multi$1, object: object, persist: persist, pexpire: pexpire, pexpireat: pexpireat, pexpiretime: pexpiretime, pfadd: pfadd, pfcount: pfcount, pfdebug: pfdebug, pfmerge: pfmerge, pfselftest: pfselftest, ping: ping, psetex: psetex, psubscribe: psubscribe, psync: psync, pttl: pttl, publish: publish, pubsub: pubsub, punsubscribe: punsubscribe, quit: quit, randomkey: randomkey, readonly: readonly, readwrite: readwrite, rename: rename, renamenx: renamenx, replconf: replconf, replicaof: replicaof, reset: reset, restore: restore, "restore-asking": { arity: -4, flags: [ "write", "denyoom", "asking" ], keyStart: 1, keyStop: 1, step: 1 }, role: role, rpop: rpop, rpoplpush: rpoplpush, rpush: rpush, rpushx: rpushx, sadd: sadd, save: save, scan: scan, scard: scard, script: script, sdiff: sdiff, sdiffstore: sdiffstore, select: select, set: set, setbit: setbit, setex: setex, setnx: setnx, setrange: setrange, shutdown: shutdown, sinter: sinter, sintercard: sintercard, sinterstore: sinterstore, sismember: sismember, slaveof: slaveof, slowlog: slowlog, smembers: smembers, smismember: smismember, smove: smove, sort: sort, sort_ro: sort_ro, spop: spop, spublish: spublish, srandmember: srandmember, srem: srem, sscan: sscan, ssubscribe: ssubscribe, strlen: strlen, subscribe: subscribe, substr: substr, sunion: sunion, sunionstore: sunionstore, sunsubscribe: sunsubscribe, swapdb: swapdb, sync: sync, time: time, touch: touch, ttl: ttl, type: type, unlink: unlink, unsubscribe: unsubscribe, unwatch: unwatch, wait: wait, watch: watch, xack: xack, xadd: xadd, xautoclaim: xautoclaim, xclaim: xclaim, xdel: xdel, xgroup: xgroup, xinfo: xinfo, xlen: xlen, xpending: xpending, xrange: xrange, xread: xread, xreadgroup: xreadgroup, xrevrange: xrevrange, xsetid: xsetid, xtrim: xtrim, zadd: zadd, zcard: zcard, zcount: zcount, zdiff: zdiff, zdiffstore: zdiffstore, zincrby: zincrby, zinter: zinter, zintercard: zintercard, zinterstore: zinterstore, zlexcount: zlexcount, zmpop: zmpop, zmscore: zmscore, zpopmax: zpopmax, zpopmin: zpopmin, zrandmember: zrandmember, zrange: zrange, zrangebylex: zrangebylex, zrangebyscore: zrangebyscore, zrangestore: zrangestore, zrank: zrank, zrem: zrem, zremrangebylex: zremrangebylex, zremrangebyrank: zremrangebyrank, zremrangebyscore: zremrangebyscore, zrevrange: zrevrange, zrevrangebylex: zrevrangebylex, zrevrangebyscore: zrevrangebyscore, zrevrank: zrevrank, zscan: zscan, zscore: zscore, zunion: zunion, zunionstore: zunionstore }; (function (exports) { var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getKeyIndexes = exports.hasFlag = exports.exists = exports.list = void 0; const commands_json_1 = __importDefault(require$$0); /** * Redis command list * * All commands are lowercased. */ exports.list = Object.keys(commands_json_1.default); const flags = {}; exports.list.forEach((commandName) => { flags[commandName] = commands_json_1.default[commandName].flags.reduce(function (flags, flag) { flags[flag] = true; return flags; }, {}); }); /** * Check if the command exists */ function exists(commandName) { return Boolean(commands_json_1.default[commandName]); } exports.exists = exists; /** * Check if the command has the flag * * Some of possible flags: readonly, noscript, loading */ function hasFlag(commandName, flag) { if (!flags[commandName]) { throw new Error("Unknown command " + commandName); } return Boolean(flags[commandName][flag]); } exports.hasFlag = hasFlag; /** * Get indexes of keys in the command arguments * * @example * ```javascript * getKeyIndexes('set', ['key', 'value']) // [0] * getKeyIndexes('mget', ['key1', 'key2']) // [0, 1] * ``` */ function getKeyIndexes(commandName, args, options) { const command = commands_json_1.default[commandName]; if (!command) { throw new Error("Unknown command " + commandName); } if (!Array.isArray(args)) { throw new Error("Expect args to be an array"); } const keys = []; const parseExternalKey = Boolean(options && options.parseExternalKey); const takeDynamicKeys = (args, startIndex) => { const keys = []; const keyStop = Number(args[startIndex]); for (let i = 0; i < keyStop; i++) { keys.push(i + startIndex + 1); } return keys; }; const takeKeyAfterToken = (args, startIndex, token) => { for (let i = startIndex; i < args.length - 1; i += 1) { if (String(args[i]).toLowerCase() === token.toLowerCase()) { return i + 1; } } return null; }; switch (commandName) { case "zunionstore": case "zinterstore": case "zdiffstore": keys.push(0, ...takeDynamicKeys(args, 1)); break; case "eval": case "evalsha": case "eval_ro": case "evalsha_ro": case "fcall": case "fcall_ro": case "blmpop": case "bzmpop": keys.push(...takeDynamicKeys(args, 1)); break; case "sintercard": case "lmpop": case "zunion": case "zinter": case "zmpop": case "zintercard": case "zdiff": { keys.push(...takeDynamicKeys(args, 0)); break; } case "georadius": { keys.push(0); const storeKey = takeKeyAfterToken(args, 5, "STORE"); if (storeKey) keys.push(storeKey); const distKey = takeKeyAfterToken(args, 5, "STOREDIST"); if (distKey) keys.push(distKey); break; } case "georadiusbymember": { keys.push(0); const storeKey = takeKeyAfterToken(args, 4, "STORE"); if (storeKey) keys.push(storeKey); const distKey = takeKeyAfterToken(args, 4, "STOREDIST"); if (distKey) keys.push(distKey); break; } case "sort": case "sort_ro": keys.push(0); for (let i = 1; i < args.length - 1; i++) { let arg = args[i]; if (typeof arg !== "string") { continue; } const directive = arg.toUpperCase(); if (directive === "GET") { i += 1; arg = args[i]; if (arg !== "#") { if (parseExternalKey) { keys.push([i, getExternalKeyNameLength(arg)]); } else { keys.push(i); } } } else if (directive === "BY") { i += 1; if (parseExternalKey) { keys.push([i, getExternalKeyNameLength(args[i])]); } else { keys.push(i); } } else if (directive === "STORE") { i += 1; keys.push(i); } } break; case "migrate": if (args[2] === "") { for (let i = 5; i < args.length - 1; i++) { const arg = args[i]; if (typeof arg === "string" && arg.toUpperCase() === "KEYS") { for (let j = i + 1; j < args.length; j++) { keys.push(j); } break; } } } else { keys.push(2); } break; case "xreadgroup": case "xread": // Keys are 1st half of the args after STREAMS argument. for (let i = commandName === "xread" ? 0 : 3; i < args.length - 1; i++) { if (String(args[i]).toUpperCase() === "STREAMS") { for (let j = i + 1; j <= i + (args.length - 1 - i) / 2; j++) { keys.push(j); } break; } } break; default: // Step has to be at least one in this case, otherwise the command does // not contain a key. if (command.step > 0) { const keyStart = command.keyStart - 1; const keyStop = command.keyStop > 0 ? command.keyStop : args.length + command.keyStop + 1; for (let i = keyStart; i < keyStop; i += command.step) { keys.push(i); } } break; } return keys; } exports.getKeyIndexes = getKeyIndexes; function getExternalKeyNameLength(key) { if (typeof key !== "string") { key = String(key); } const hashPos = key.indexOf("->"); return hashPos === -1 ? key.length : hashPos; } } (built$1)); var built = {}; var utils$1 = {}; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.tryCatch = exports.errorObj = void 0; //Try catch is not supported in optimizing //compiler, so it is isolated exports.errorObj = { e: {} }; let tryCatchTarget; function tryCatcher(err, val) { try { const target = tryCatchTarget; tryCatchTarget = null; return target.apply(this, arguments); } catch (e) { exports.errorObj.e = e; return exports.errorObj; } } function tryCatch(fn) { tryCatchTarget = fn; return tryCatcher; } exports.tryCatch = tryCatch; } (utils$1)); Object.defineProperty(built, "__esModule", { value: true }); const utils_1$9 = utils$1; function throwLater(e) { setTimeout(function () { throw e; }, 0); } function asCallback(promise, nodeback, options) { if (typeof nodeback === "function") { promise.then((val) => { let ret; if (options !== undefined && Object(options).spread && Array.isArray(val)) { ret = utils_1$9.tryCatch(nodeback).apply(undefined, [null].concat(val)); } else { ret = val === undefined ? utils_1$9.tryCatch(nodeback)(null) : utils_1$9.tryCatch(nodeback)(null, val); } if (ret === utils_1$9.errorObj) { throwLater(ret.e); } }, (cause) => { if (!cause) { const newReason = new Error(cause + ""); Object.assign(newReason, { cause }); cause = newReason; } const ret = utils_1$9.tryCatch(nodeback)(cause); if (ret === utils_1$9.errorObj) { throwLater(ret.e); } }); } return promise; } built.default = asCallback; var cluster = {}; var old; var hasRequiredOld; function requireOld () { if (hasRequiredOld) return old; hasRequiredOld = 1; const assert = require$$0$6; const util = require$$1; // RedisError function RedisError (message) { Object.defineProperty(this, 'message', { value: message || '', configurable: true, writable: true }); Error.captureStackTrace(this, this.constructor); } util.inherits(RedisError, Error); Object.defineProperty(RedisError.prototype, 'name', { value: 'RedisError', configurable: true, writable: true }); // ParserError function ParserError (message, buffer, offset) { assert(buffer); assert.strictEqual(typeof offset, 'number'); Object.defineProperty(this, 'message', { value: message || '', configurable: true, writable: true }); const tmp = Error.stackTraceLimit; Error.stackTraceLimit = 2; Error.captureStackTrace(this, this.constructor); Error.stackTraceLimit = tmp; this.offset = offset; this.buffer = buffer; } util.inherits(ParserError, RedisError); Object.defineProperty(ParserError.prototype, 'name', { value: 'ParserError', configurable: true, writable: true }); // ReplyError function ReplyError (message) { Object.defineProperty(this, 'message', { value: message || '', configurable: true, writable: true }); const tmp = Error.stackTraceLimit; Error.stackTraceLimit = 2; Error.captureStackTrace(this, this.constructor); Error.stackTraceLimit = tmp; } util.inherits(ReplyError, RedisError); Object.defineProperty(ReplyError.prototype, 'name', { value: 'ReplyError', configurable: true, writable: true }); // AbortError function AbortError (message) { Object.defineProperty(this, 'message', { value: message || '', configurable: true, writable: true }); Error.captureStackTrace(this, this.constructor); } util.inherits(AbortError, RedisError); Object.defineProperty(AbortError.prototype, 'name', { value: 'AbortError', configurable: true, writable: true }); // InterruptError function InterruptError (message) { Object.defineProperty(this, 'message', { value: message || '', configurable: true, writable: true }); Error.captureStackTrace(this, this.constructor); } util.inherits(InterruptError, AbortError); Object.defineProperty(InterruptError.prototype, 'name', { value: 'InterruptError', configurable: true, writable: true }); old = { RedisError, ParserError, ReplyError, AbortError, InterruptError }; return old; } var modern; var hasRequiredModern; function requireModern () { if (hasRequiredModern) return modern; hasRequiredModern = 1; const assert = require$$0$6; class RedisError extends Error { get name () { return this.constructor.name } } class ParserError extends RedisError { constructor (message, buffer, offset) { assert(buffer); assert.strictEqual(typeof offset, 'number'); const tmp = Error.stackTraceLimit; Error.stackTraceLimit = 2; super(message); Error.stackTraceLimit = tmp; this.offset = offset; this.buffer = buffer; } get name () { return this.constructor.name } } class ReplyError extends RedisError { constructor (message) { const tmp = Error.stackTraceLimit; Error.stackTraceLimit = 2; super(message); Error.stackTraceLimit = tmp; } get name () { return this.constructor.name } } class AbortError extends RedisError { get name () { return this.constructor.name } } class InterruptError extends AbortError { get name () { return this.constructor.name } } modern = { RedisError, ParserError, ReplyError, AbortError, InterruptError }; return modern; } const Errors = process.version.charCodeAt(1) < 55 && process.version.charCodeAt(2) === 46 ? requireOld() // Node.js < 7 : requireModern(); var redisErrors = Errors; var Command$1 = {}; var lib = {exports: {}}; /* * Copyright 2001-2010 Georges Menie (www.menie.org) * Copyright 2010 Salvatore Sanfilippo (adapted to Redis coding style) * Copyright 2015 Zihua Li (http://zihua.li) (ported to JavaScript) * Copyright 2016 Mike Diarmid (http://github.com/salakar) (re-write for performance, ~700% perf inc) * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the University of California, Berkeley nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* CRC16 implementation according to CCITT standards. * * Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the * following parameters: * * Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN" * Width : 16 bit * Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1) * Initialization : 0000 * Reflect Input byte : False * Reflect Output CRC : False * Xor constant to output CRC : 0000 * Output for "123456789" : 31C3 */ var lookup = [ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 ]; /** * Convert a string to a UTF8 array - faster than via buffer * @param str * @returns {Array} */ var toUTF8Array = function toUTF8Array(str) { var char; var i = 0; var p = 0; var utf8 = []; var len = str.length; for (; i < len; i++) { char = str.charCodeAt(i); if (char < 128) { utf8[p++] = char; } else if (char < 2048) { utf8[p++] = (char >> 6) | 192; utf8[p++] = (char & 63) | 128; } else if ( ((char & 0xFC00) === 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) === 0xDC00)) { char = 0x10000 + ((char & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF); utf8[p++] = (char >> 18) | 240; utf8[p++] = ((char >> 12) & 63) | 128; utf8[p++] = ((char >> 6) & 63) | 128; utf8[p++] = (char & 63) | 128; } else { utf8[p++] = (char >> 12) | 224; utf8[p++] = ((char >> 6) & 63) | 128; utf8[p++] = (char & 63) | 128; } } return utf8; }; /** * Convert a string into a redis slot hash. * @param str * @returns {number} */ var generate = lib.exports = function generate(str) { var char; var i = 0; var start = -1; var result = 0; var resultHash = 0; var utf8 = typeof str === 'string' ? toUTF8Array(str) : str; var len = utf8.length; while (i < len) { char = utf8[i++]; if (start === -1) { if (char === 0x7B) { start = i; } } else if (char !== 0x7D) { resultHash = lookup[(char ^ (resultHash >> 8)) & 0xFF] ^ (resultHash << 8); } else if (i - 1 !== start) { return resultHash & 0x3FFF; } result = lookup[(char ^ (result >> 8)) & 0xFF] ^ (result << 8); } return result & 0x3FFF; }; /** * Convert an array of multiple strings into a redis slot hash. * Returns -1 if one of the keys is not for the same slot as the others * @param keys * @returns {number} */ lib.exports.generateMulti = function generateMulti(keys) { var i = 1; var len = keys.length; var base = generate(keys[0]); while (i < len) { if (generate(keys[i++]) !== base) return -1; } return base; }; var libExports = lib.exports; var utils = {}; var lodash = {}; /** * lodash (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER$1 = 9007199254740991; /** `Object#toString` result references. */ var argsTag$1 = '[object Arguments]', funcTag$1 = '[object Function]', genTag$1 = '[object GeneratorFunction]'; /** Used to detect unsigned integer values. */ var reIsUint = /^(?:0|[1-9]\d*)$/; /** * A faster alternative to `Function#apply`, this function invokes `func` * with the `this` binding of `thisArg` and the arguments of `args`. * * @private * @param {Function} func The function to invoke. * @param {*} thisArg The `this` binding of `func`. * @param {Array} args The arguments to invoke `func` with. * @returns {*} Returns the result of `func`. */ function apply(func, thisArg, args) { switch (args.length) { case 0: return func.call(thisArg); case 1: return func.call(thisArg, args[0]); case 2: return func.call(thisArg, args[0], args[1]); case 3: return func.call(thisArg, args[0], args[1], args[2]); } return func.apply(thisArg, args); } /** * The base implementation of `_.times` without support for iteratee shorthands * or max array length checks. * * @private * @param {number} n The number of times to invoke `iteratee`. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the array of results. */ function baseTimes(n, iteratee) { var index = -1, result = Array(n); while (++index < n) { result[index] = iteratee(index); } return result; } /** Used for built-in method references. */ var objectProto$1 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$1 = objectProto$1.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString$1 = objectProto$1.toString; /** Built-in value references. */ var propertyIsEnumerable$1 = objectProto$1.propertyIsEnumerable; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max; /** * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. * @param {boolean} inherited Specify returning inherited property names. * @returns {Array} Returns the array of property names. */ function arrayLikeKeys(value, inherited) { // Safari 8.1 makes `arguments.callee` enumerable in strict mode. // Safari 9 makes `arguments.length` enumerable in strict mode. var result = (isArray(value) || isArguments$2(value)) ? baseTimes(value.length, String) : []; var length = result.length, skipIndexes = !!length; for (var key in value) { if ((inherited || hasOwnProperty$1.call(value, key)) && !(skipIndexes && (key == 'length' || isIndex(key, length)))) { result.push(key); } } return result; } /** * Used by `_.defaults` to customize its `_.assignIn` use. * * @private * @param {*} objValue The destination value. * @param {*} srcValue The source value. * @param {string} key The key of the property to assign. * @param {Object} object The parent object of `objValue`. * @returns {*} Returns the value to assign. */ function assignInDefaults(objValue, srcValue, key, object) { if (objValue === undefined || (eq(objValue, objectProto$1[key]) && !hasOwnProperty$1.call(object, key))) { return srcValue; } return objValue; } /** * Assigns `value` to `key` of `object` if the existing value is not equivalent * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignValue(object, key, value) { var objValue = object[key]; if (!(hasOwnProperty$1.call(object, key) && eq(objValue, value)) || (value === undefined && !(key in object))) { object[key] = value; } } /** * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeysIn(object) { if (!isObject$1(object)) { return nativeKeysIn(object); } var isProto = isPrototype(object), result = []; for (var key in object) { if (!(key == 'constructor' && (isProto || !hasOwnProperty$1.call(object, key)))) { result.push(key); } } return result; } /** * The base implementation of `_.rest` which doesn't validate or coerce arguments. * * @private * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @returns {Function} Returns the new function. */ function baseRest(func, start) { start = nativeMax(start === undefined ? (func.length - 1) : start, 0); return function() { var args = arguments, index = -1, length = nativeMax(args.length - start, 0), array = Array(length); while (++index < length) { array[index] = args[start + index]; } index = -1; var otherArgs = Array(start + 1); while (++index < start) { otherArgs[index] = args[index]; } otherArgs[start] = array; return apply(func, this, otherArgs); }; } /** * Copies properties of `source` to `object`. * * @private * @param {Object} source The object to copy properties from. * @param {Array} props The property identifiers to copy. * @param {Object} [object={}] The object to copy properties to. * @param {Function} [customizer] The function to customize copied values. * @returns {Object} Returns `object`. */ function copyObject(source, props, object, customizer) { object || (object = {}); var index = -1, length = props.length; while (++index < length) { var key = props[index]; var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined; assignValue(object, key, newValue === undefined ? source[key] : newValue); } return object; } /** * Creates a function like `_.assign`. * * @private * @param {Function} assigner The function to assign values. * @returns {Function} Returns the new assigner function. */ function createAssigner(assigner) { return baseRest(function(object, sources) { var index = -1, length = sources.length, customizer = length > 1 ? sources[length - 1] : undefined, guard = length > 2 ? sources[2] : undefined; customizer = (assigner.length > 3 && typeof customizer == 'function') ? (length--, customizer) : undefined; if (guard && isIterateeCall(sources[0], sources[1], guard)) { customizer = length < 3 ? undefined : customizer; length = 1; } object = Object(object); while (++index < length) { var source = sources[index]; if (source) { assigner(object, source, index, customizer); } } return object; }); } /** * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex(value, length) { length = length == null ? MAX_SAFE_INTEGER$1 : length; return !!length && (typeof value == 'number' || reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length); } /** * Checks if the given arguments are from an iteratee call. * * @private * @param {*} value The potential iteratee value argument. * @param {*} index The potential iteratee index or key argument. * @param {*} object The potential iteratee object argument. * @returns {boolean} Returns `true` if the arguments are from an iteratee call, * else `false`. */ function isIterateeCall(value, index, object) { if (!isObject$1(object)) { return false; } var type = typeof index; if (type == 'number' ? (isArrayLike$1(object) && isIndex(index, object.length)) : (type == 'string' && index in object) ) { return eq(object[index], value); } return false; } /** * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype(value) { var Ctor = value && value.constructor, proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$1; return value === proto; } /** * This function is like * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * except that it includes inherited enumerable properties. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function nativeKeysIn(object) { var result = []; if (object != null) { for (var key in Object(object)) { result.push(key); } } return result; } /** * Performs a * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * comparison between two values to determine if they are equivalent. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.eq(object, object); * // => true * * _.eq(object, other); * // => false * * _.eq('a', 'a'); * // => true * * _.eq('a', Object('a')); * // => false * * _.eq(NaN, NaN); * // => true */ function eq(value, other) { return value === other || (value !== value && other !== other); } /** * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, * else `false`. * @example * * _.isArguments(function() { return arguments; }()); * // => true * * _.isArguments([1, 2, 3]); * // => false */ function isArguments$2(value) { // Safari 8.1 makes `arguments.callee` enumerable in strict mode. return isArrayLikeObject$1(value) && hasOwnProperty$1.call(value, 'callee') && (!propertyIsEnumerable$1.call(value, 'callee') || objectToString$1.call(value) == argsTag$1); } /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray = Array.isArray; /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike$1(value) { return value != null && isLength$1(value.length) && !isFunction$1(value); } /** * This method is like `_.isArrayLike` except that it also checks if `value` * is an object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, * else `false`. * @example * * _.isArrayLikeObject([1, 2, 3]); * // => true * * _.isArrayLikeObject(document.body.children); * // => true * * _.isArrayLikeObject('abc'); * // => false * * _.isArrayLikeObject(_.noop); * // => false */ function isArrayLikeObject$1(value) { return isObjectLike$1(value) && isArrayLike$1(value); } /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction$1(value) { // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 8-9 which returns 'object' for typed array and other constructors. var tag = isObject$1(value) ? objectToString$1.call(value) : ''; return tag == funcTag$1 || tag == genTag$1; } /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength$1(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject$1(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike$1(value) { return !!value && typeof value == 'object'; } /** * This method is like `_.assignIn` except that it accepts `customizer` * which is invoked to produce the assigned values. If `customizer` returns * `undefined`, assignment is handled by the method instead. The `customizer` * is invoked with five arguments: (objValue, srcValue, key, object, source). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @alias extendWith * @category Object * @param {Object} object The destination object. * @param {...Object} sources The source objects. * @param {Function} [customizer] The function to customize assigned values. * @returns {Object} Returns `object`. * @see _.assignWith * @example * * function customizer(objValue, srcValue) { * return _.isUndefined(objValue) ? srcValue : objValue; * } * * var defaults = _.partialRight(_.assignInWith, customizer); * * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); * // => { 'a': 1, 'b': 2 } */ var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { copyObject(source, keysIn(source), object, customizer); }); /** * Assigns own and inherited enumerable string keyed properties of source * objects to the destination object for all destination properties that * resolve to `undefined`. Source objects are applied from left to right. * Once a property is set, additional values of the same property are ignored. * * **Note:** This method mutates `object`. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.defaultsDeep * @example * * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); * // => { 'a': 1, 'b': 2 } */ var defaults$1 = baseRest(function(args) { args.push(undefined, assignInDefaults); return apply(assignInWith, undefined, args); }); /** * Creates an array of the own and inherited enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ * @since 3.0.0 * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keysIn(new Foo); * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ function keysIn(object) { return isArrayLike$1(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); } var lodash_defaults = defaults$1; /** * lodash (Custom Build) * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER = 9007199254740991; /** `Object#toString` result references. */ var argsTag = '[object Arguments]', funcTag = '[object Function]', genTag = '[object GeneratorFunction]'; /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString = objectProto.toString; /** Built-in value references. */ var propertyIsEnumerable = objectProto.propertyIsEnumerable; /** * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, * else `false`. * @example * * _.isArguments(function() { return arguments; }()); * // => true * * _.isArguments([1, 2, 3]); * // => false */ function isArguments$1(value) { // Safari 8.1 makes `arguments.callee` enumerable in strict mode. return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); } /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike(value) { return value != null && isLength(value.length) && !isFunction(value); } /** * This method is like `_.isArrayLike` except that it also checks if `value` * is an object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, * else `false`. * @example * * _.isArrayLikeObject([1, 2, 3]); * // => true * * _.isArrayLikeObject(document.body.children); * // => true * * _.isArrayLikeObject('abc'); * // => false * * _.isArrayLikeObject(_.noop); * // => false */ function isArrayLikeObject(value) { return isObjectLike(value) && isArrayLike(value); } /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction(value) { // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 8-9 which returns 'object' for typed array and other constructors. var tag = isObject(value) ? objectToString.call(value) : ''; return tag == funcTag || tag == genTag; } /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return !!value && typeof value == 'object'; } var lodash_isarguments = isArguments$1; Object.defineProperty(lodash, "__esModule", { value: true }); lodash.isArguments = lodash.defaults = lodash.noop = void 0; const defaults = lodash_defaults; lodash.defaults = defaults; const isArguments = lodash_isarguments; lodash.isArguments = isArguments; function noop() { } lodash.noop = noop; var debug$4 = {}; Object.defineProperty(debug$4, "__esModule", { value: true }); debug$4.genRedactedString = debug$4.getStringValue = debug$4.MAX_ARGUMENT_LENGTH = void 0; const debug_1 = srcExports; const MAX_ARGUMENT_LENGTH = 200; debug$4.MAX_ARGUMENT_LENGTH = MAX_ARGUMENT_LENGTH; const NAMESPACE_PREFIX = "ioredis"; /** * helper function that tried to get a string value for * arbitrary "debug" arg */ function getStringValue(v) { if (v === null) { return; } switch (typeof v) { case "boolean": return; case "number": return; case "object": if (Buffer.isBuffer(v)) { return v.toString("hex"); } if (Array.isArray(v)) { return v.join(","); } try { return JSON.stringify(v); } catch (e) { return; } case "string": return v; } } debug$4.getStringValue = getStringValue; /** * helper function that redacts a string representation of a "debug" arg */ function genRedactedString(str, maxLen) { const { length } = str; return length <= maxLen ? str : str.slice(0, maxLen) + ' ... '; } debug$4.genRedactedString = genRedactedString; /** * a wrapper for the `debug` module, used to generate * "debug functions" that trim the values in their output */ function genDebugFunction(namespace) { const fn = (0, debug_1.default)(`${NAMESPACE_PREFIX}:${namespace}`); function wrappedDebug(...args) { if (!fn.enabled) { return; // no-op } // we skip the first arg because that is the message for (let i = 1; i < args.length; i++) { const str = getStringValue(args[i]); if (typeof str === "string" && str.length > MAX_ARGUMENT_LENGTH) { args[i] = genRedactedString(str, MAX_ARGUMENT_LENGTH); } } return fn.apply(null, args); } Object.defineProperties(wrappedDebug, { namespace: { get() { return fn.namespace; }, }, enabled: { get() { return fn.enabled; }, }, destroy: { get() { return fn.destroy; }, }, log: { get() { return fn.log; }, set(l) { fn.log = l; }, }, }); return wrappedDebug; } debug$4.default = genDebugFunction; var TLSProfiles$1 = {}; Object.defineProperty(TLSProfiles$1, "__esModule", { value: true }); /** * TLS settings for Redis Cloud. Updated on 2022-08-19. */ const RedisCloudCA = `-----BEGIN CERTIFICATE----- MIIDTzCCAjegAwIBAgIJAKSVpiDswLcwMA0GCSqGSIb3DQEBBQUAMD4xFjAUBgNV BAoMDUdhcmFudGlhIERhdGExJDAiBgNVBAMMG1NTTCBDZXJ0aWZpY2F0aW9uIEF1 dGhvcml0eTAeFw0xMzEwMDExMjE0NTVaFw0yMzA5MjkxMjE0NTVaMD4xFjAUBgNV BAoMDUdhcmFudGlhIERhdGExJDAiBgNVBAMMG1NTTCBDZXJ0aWZpY2F0aW9uIEF1 dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALZqkh/DczWP JnxnHLQ7QL0T4B4CDKWBKCcisriGbA6ZePWVNo4hfKQC6JrzfR+081NeD6VcWUiz rmd+jtPhIY4c+WVQYm5PKaN6DT1imYdxQw7aqO5j2KUCEh/cznpLxeSHoTxlR34E QwF28Wl3eg2vc5ct8LjU3eozWVk3gb7alx9mSA2SgmuX5lEQawl++rSjsBStemY2 BDwOpAMXIrdEyP/cVn8mkvi/BDs5M5G+09j0gfhyCzRWMQ7Hn71u1eolRxwVxgi3 TMn+/vTaFSqxKjgck6zuAYjBRPaHe7qLxHNr1So/Mc9nPy+3wHebFwbIcnUojwbp 4nctkWbjb2cCAwEAAaNQME4wHQYDVR0OBBYEFP1whtcrydmW3ZJeuSoKZIKjze3w MB8GA1UdIwQYMBaAFP1whtcrydmW3ZJeuSoKZIKjze3wMAwGA1UdEwQFMAMBAf8w DQYJKoZIhvcNAQEFBQADggEBAG2erXhwRAa7+ZOBs0B6X57Hwyd1R4kfmXcs0rta lbPpvgULSiB+TCbf3EbhJnHGyvdCY1tvlffLjdA7HJ0PCOn+YYLBA0pTU/dyvrN6 Su8NuS5yubnt9mb13nDGYo1rnt0YRfxN+8DM3fXIVr038A30UlPX2Ou1ExFJT0MZ uFKY6ZvLdI6/1cbgmguMlAhM+DhKyV6Sr5699LM3zqeI816pZmlREETYkGr91q7k BpXJu/dtHaGxg1ZGu6w/PCsYGUcECWENYD4VQPd8N32JjOfu6vEgoEAwfPP+3oGp Z4m3ewACcWOAenqflb+cQYC4PsF7qbXDmRaWrbKntOlZ3n0= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGMTCCBBmgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwajELMAkGA1UEBhMCVVMx CzAJBgNVBAgMAkNBMQswCQYDVQQHDAJDQTESMBAGA1UECgwJUmVkaXNMYWJzMS0w KwYDVQQDDCRSZWRpc0xhYnMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN MTgwMjI1MTUzNzM3WhcNMjgwMjIzMTUzNzM3WjBfMQswCQYDVQQGEwJVUzELMAkG A1UECAwCQ0ExEjAQBgNVBAoMCVJlZGlzTGFiczEvMC0GA1UEAwwmUkNQIEludGVy bWVkaWF0ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQDf9dqbxc8Bq7Ctq9rWcxrGNKKHivqLAFpPq02yLPx6fsOv Tq7GsDChAYBBc4v7Y2Ap9RD5Vs3dIhEANcnolf27QwrG9RMnnvzk8pCvp1o6zSU4 VuOE1W66/O1/7e2rVxyrnTcP7UgK43zNIXu7+tiAqWsO92uSnuMoGPGpeaUm1jym hjWKtkAwDFSqvHY+XL5qDVBEjeUe+WHkYUg40cAXjusAqgm2hZt29c2wnVrxW25W P0meNlzHGFdA2AC5z54iRiqj57dTfBTkHoBczQxcyw6hhzxZQ4e5I5zOKjXXEhZN r0tA3YC14CTabKRus/JmZieyZzRgEy2oti64tmLYTqSlAD78pRL40VNoaSYetXLw hhNsXCHgWaY6d5bLOc/aIQMAV5oLvZQKvuXAF1IDmhPA+bZbpWipp0zagf1P1H3s UzsMdn2KM0ejzgotbtNlj5TcrVwpmvE3ktvUAuA+hi3FkVx1US+2Gsp5x4YOzJ7u P1WPk6ShF0JgnJH2ILdj6kttTWwFzH17keSFICWDfH/+kM+k7Y1v3EXMQXE7y0T9 MjvJskz6d/nv+sQhY04xt64xFMGTnZjlJMzfQNi7zWFLTZnDD0lPowq7l3YiPoTT t5Xky83lu0KZsZBo0WlWaDG00gLVdtRgVbcuSWxpi5BdLb1kRab66JptWjxwXQID AQABo4HrMIHoMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHBzOi8vcmwtY2Etc2VydmVy LnJlZGlzbGFicy5jb20vdjEvY3JsMEYGCCsGAQUFBwEBBDowODA2BggrBgEFBQcw AYYqaHR0cHM6Ly9ybC1jYS1zZXJ2ZXIucmVkaXNsYWJzLmNvbS92MS9vY3NwMB0G A1UdDgQWBBQHar5OKvQUpP2qWt6mckzToeCOHDAfBgNVHSMEGDAWgBQi42wH6hM4 L2sujEvLM0/u8lRXTzASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIB hjANBgkqhkiG9w0BAQsFAAOCAgEAirEn/iTsAKyhd+pu2W3Z5NjCko4NPU0EYUbr AP7+POK2rzjIrJO3nFYQ/LLuC7KCXG+2qwan2SAOGmqWst13Y+WHp44Kae0kaChW vcYLXXSoGQGC8QuFSNUdaeg3RbMDYFT04dOkqufeWVccoHVxyTSg9eD8LZuHn5jw 7QDLiEECBmIJHk5Eeo2TAZrx4Yx6ufSUX5HeVjlAzqwtAqdt99uCJ/EL8bgpWbe+ XoSpvUv0SEC1I1dCAhCKAvRlIOA6VBcmzg5Am12KzkqTul12/VEFIgzqu0Zy2Jbc AUPrYVu/+tOGXQaijy7YgwH8P8n3s7ZeUa1VABJHcxrxYduDDJBLZi+MjheUDaZ1 jQRHYevI2tlqeSBqdPKG4zBY5lS0GiAlmuze5oENt0P3XboHoZPHiqcK3VECgTVh /BkJcuudETSJcZDmQ8YfoKfBzRQNg2sv/hwvUv73Ss51Sco8GEt2lD8uEdib1Q6z zDT5lXJowSzOD5ZA9OGDjnSRL+2riNtKWKEqvtEG3VBJoBzu9GoxbAc7wIZLxmli iF5a/Zf5X+UXD3s4TMmy6C4QZJpAA2egsSQCnraWO2ULhh7iXMysSkF/nzVfZn43 iqpaB8++9a37hWq14ZmOv0TJIDz//b2+KC4VFXWQ5W5QC6whsjT+OlG4p5ZYG0jo 616pxqo= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFujCCA6KgAwIBAgIJAJ1aTT1lu2ScMA0GCSqGSIb3DQEBCwUAMGoxCzAJBgNV BAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCQ0ExEjAQBgNVBAoMCVJlZGlz TGFiczEtMCsGA1UEAwwkUmVkaXNMYWJzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9y aXR5MB4XDTE4MDIyNTE1MjA0MloXDTM4MDIyMDE1MjA0MlowajELMAkGA1UEBhMC VVMxCzAJBgNVBAgMAkNBMQswCQYDVQQHDAJDQTESMBAGA1UECgwJUmVkaXNMYWJz MS0wKwYDVQQDDCRSZWRpc0xhYnMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLEjXy7YrbN5Waau5cd6g1 G5C2tMmeTpZ0duFAPxNU4oE3RHS5gGiok346fUXuUxbZ6QkuzeN2/2Z+RmRcJhQY Dm0ZgdG4x59An1TJfnzKKoWj8ISmoHS/TGNBdFzXV7FYNLBuqZouqePI6ReC6Qhl pp45huV32Q3a6IDrrvx7Wo5ZczEQeFNbCeCOQYNDdTmCyEkHqc2AGo8eoIlSTutT ULOC7R5gzJVTS0e1hesQ7jmqHjbO+VQS1NAL4/5K6cuTEqUl+XhVhPdLWBXJQ5ag 54qhX4v+ojLzeU1R/Vc6NjMvVtptWY6JihpgplprN0Yh2556ewcXMeturcKgXfGJ xeYzsjzXerEjrVocX5V8BNrg64NlifzTMKNOOv4fVZszq1SIHR8F9ROrqiOdh8iC JpUbLpXH9hWCSEO6VRMB2xJoKu3cgl63kF30s77x7wLFMEHiwsQRKxooE1UhgS9K 2sO4TlQ1eWUvFvHSTVDQDlGQ6zu4qjbOpb3Q8bQwoK+ai2alkXVR4Ltxe9QlgYK3 StsnPhruzZGA0wbXdpw0bnM+YdlEm5ffSTpNIfgHeaa7Dtb801FtA71ZlH7A6TaI SIQuUST9EKmv7xrJyx0W1pGoPOLw5T029aTjnICSLdtV9bLwysrLhIYG5bnPq78B cS+jZHFGzD7PUVGQD01nOQIDAQABo2MwYTAdBgNVHQ4EFgQUIuNsB+oTOC9rLoxL yzNP7vJUV08wHwYDVR0jBBgwFoAUIuNsB+oTOC9rLoxLyzNP7vJUV08wDwYDVR0T AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAHfg z5pMNUAKdMzK1aS1EDdK9yKz4qicILz5czSLj1mC7HKDRy8cVADUxEICis++CsCu rYOvyCVergHQLREcxPq4rc5Nq1uj6J6649NEeh4WazOOjL4ZfQ1jVznMbGy+fJm3 3Hoelv6jWRG9iqeJZja7/1s6YC6bWymI/OY1e4wUKeNHAo+Vger7MlHV+RuabaX+ hSJ8bJAM59NCM7AgMTQpJCncrcdLeceYniGy5Q/qt2b5mJkQVkIdy4TPGGB+AXDJ D0q3I/JDRkDUFNFdeW0js7fHdsvCR7O3tJy5zIgEV/o/BCkmJVtuwPYOrw/yOlKj TY/U7ATAx9VFF6/vYEOMYSmrZlFX+98L6nJtwDqfLB5VTltqZ4H/KBxGE3IRSt9l FXy40U+LnXzhhW+7VBAvyYX8GEXhHkKU8Gqk1xitrqfBXY74xKgyUSTolFSfFVgj mcM/X4K45bka+qpkj7Kfv/8D4j6aZekwhN2ly6hhC1SmQ8qjMjpG/mrWOSSHZFmf ybu9iD2AYHeIOkshIl6xYIa++Q/00/vs46IzAbQyriOi0XxlSMMVtPx0Q3isp+ji n8Mq9eOuxYOEQ4of8twUkUDd528iwGtEdwf0Q01UyT84S62N8AySl1ZBKXJz6W4F UhWfa/HQYOAPDdEjNgnVwLI23b8t0TozyCWw7q8h -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEjzCCA3egAwIBAgIQe55B/ALCKJDZtdNT8kD6hTANBgkqhkiG9w0BAQsFADBM MSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xv YmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0yMjAxMjYxMjAwMDBaFw0y NTAxMjYwMDAwMDBaMFgxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWdu IG52LXNhMS4wLAYDVQQDEyVHbG9iYWxTaWduIEF0bGFzIFIzIE9WIFRMUyBDQSAy MDIyIFEyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmGmg1LW9b7Lf 8zDD83yBDTEkt+FOxKJZqF4veWc5KZsQj9HfnUS2e5nj/E+JImlGPsQuoiosLuXD BVBNAMcUFa11buFMGMeEMwiTmCXoXRrXQmH0qjpOfKgYc5gHG3BsRGaRrf7VR4eg ofNMG9wUBw4/g/TT7+bQJdA4NfE7Y4d5gEryZiBGB/swaX6Jp/8MF4TgUmOWmalK dZCKyb4sPGQFRTtElk67F7vU+wdGcrcOx1tDcIB0ncjLPMnaFicagl+daWGsKqTh counQb6QJtYHa91KvCfKWocMxQ7OIbB5UARLPmC4CJ1/f8YFm35ebfzAeULYdGXu jE9CLor0OwIDAQABo4IBXzCCAVswDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQG CCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW BBSH5Zq7a7B/t95GfJWkDBpA8HHqdjAfBgNVHSMEGDAWgBSP8Et/qC5FJK5NUPpj move4t0bvDB7BggrBgEFBQcBAQRvMG0wLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3Nw Mi5nbG9iYWxzaWduLmNvbS9yb290cjMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9zZWN1 cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L3Jvb3QtcjMuY3J0MDYGA1UdHwQvMC0w K6ApoCeGJWh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vcm9vdC1yMy5jcmwwIQYD VR0gBBowGDAIBgZngQwBAgIwDAYKKwYBBAGgMgoBAjANBgkqhkiG9w0BAQsFAAOC AQEAKRic9/f+nmhQU/wz04APZLjgG5OgsuUOyUEZjKVhNGDwxGTvKhyXGGAMW2B/ 3bRi+aElpXwoxu3pL6fkElbX3B0BeS5LoDtxkyiVEBMZ8m+sXbocwlPyxrPbX6mY 0rVIvnuUeBH8X0L5IwfpNVvKnBIilTbcebfHyXkPezGwz7E1yhUULjJFm2bt0SdX y+4X/WeiiYIv+fTVgZZgl+/2MKIsu/qdBJc3f3TvJ8nz+Eax1zgZmww+RSQWeOj3 15Iw6Z5FX+NwzY/Ab+9PosR5UosSeq+9HhtaxZttXG1nVh+avYPGYddWmiMT90J5 ZgKnO/Fx2hBgTxhOTMYaD312kg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK 6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----END CERTIFICATE-----`; const TLSProfiles = { RedisCloudFixed: { ca: RedisCloudCA }, RedisCloudFlexible: { ca: RedisCloudCA }, }; TLSProfiles$1.default = TLSProfiles; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.noop = exports.defaults = exports.Debug = exports.zipMap = exports.CONNECTION_CLOSED_ERROR_MSG = exports.shuffle = exports.sample = exports.resolveTLSProfile = exports.parseURL = exports.optimizeErrorStack = exports.toArg = exports.convertMapToArray = exports.convertObjectToArray = exports.timeout = exports.packObject = exports.isInt = exports.wrapMultiResult = exports.convertBufferToString = void 0; const url_1 = require$$0$1; const lodash_1 = lodash; Object.defineProperty(exports, "defaults", { enumerable: true, get: function () { return lodash_1.defaults; } }); Object.defineProperty(exports, "noop", { enumerable: true, get: function () { return lodash_1.noop; } }); const debug_1 = debug$4; exports.Debug = debug_1.default; const TLSProfiles_1 = TLSProfiles$1; /** * Convert a buffer to string, supports buffer array * * @example * ```js * const input = [Buffer.from('foo'), [Buffer.from('bar')]] * const res = convertBufferToString(input, 'utf8') * expect(res).to.eql(['foo', ['bar']]) * ``` */ function convertBufferToString(value, encoding) { if (value instanceof Buffer) { return value.toString(encoding); } if (Array.isArray(value)) { const length = value.length; const res = Array(length); for (let i = 0; i < length; ++i) { res[i] = value[i] instanceof Buffer && encoding === "utf8" ? value[i].toString() : convertBufferToString(value[i], encoding); } return res; } return value; } exports.convertBufferToString = convertBufferToString; /** * Convert a list of results to node-style * * @example * ```js * const input = ['a', 'b', new Error('c'), 'd'] * const output = exports.wrapMultiResult(input) * expect(output).to.eql([[null, 'a'], [null, 'b'], [new Error('c')], [null, 'd']) * ``` */ function wrapMultiResult(arr) { // When using WATCH/EXEC transactions, the EXEC will return // a null instead of an array if (!arr) { return null; } const result = []; const length = arr.length; for (let i = 0; i < length; ++i) { const item = arr[i]; if (item instanceof Error) { result.push([item]); } else { result.push([null, item]); } } return result; } exports.wrapMultiResult = wrapMultiResult; /** * Detect if the argument is a int * @example * ```js * > isInt('123') * true * > isInt('123.3') * false * > isInt('1x') * false * > isInt(123) * true * > isInt(true) * false * ``` */ function isInt(value) { const x = parseFloat(value); return !isNaN(value) && (x | 0) === x; } exports.isInt = isInt; /** * Pack an array to an Object * * @example * ```js * > packObject(['a', 'b', 'c', 'd']) * { a: 'b', c: 'd' } * ``` */ function packObject(array) { const result = {}; const length = array.length; for (let i = 1; i < length; i += 2) { result[array[i - 1]] = array[i]; } return result; } exports.packObject = packObject; /** * Return a callback with timeout */ function timeout(callback, timeout) { let timer = null; const run = function () { if (timer) { clearTimeout(timer); timer = null; callback.apply(this, arguments); } }; timer = setTimeout(run, timeout, new Error("timeout")); return run; } exports.timeout = timeout; /** * Convert an object to an array * @example * ```js * > convertObjectToArray({ a: '1' }) * ['a', '1'] * ``` */ function convertObjectToArray(obj) { const result = []; const keys = Object.keys(obj); // Object.entries requires node 7+ for (let i = 0, l = keys.length; i < l; i++) { result.push(keys[i], obj[keys[i]]); } return result; } exports.convertObjectToArray = convertObjectToArray; /** * Convert a map to an array * @example * ```js * > convertMapToArray(new Map([[1, '2']])) * [1, '2'] * ``` */ function convertMapToArray(map) { const result = []; let pos = 0; map.forEach(function (value, key) { result[pos] = key; result[pos + 1] = value; pos += 2; }); return result; } exports.convertMapToArray = convertMapToArray; /** * Convert a non-string arg to a string */ function toArg(arg) { if (arg === null || typeof arg === "undefined") { return ""; } return String(arg); } exports.toArg = toArg; /** * Optimize error stack * * @param error actually error * @param friendlyStack the stack that more meaningful * @param filterPath only show stacks with the specified path */ function optimizeErrorStack(error, friendlyStack, filterPath) { const stacks = friendlyStack.split("\n"); let lines = ""; let i; for (i = 1; i < stacks.length; ++i) { if (stacks[i].indexOf(filterPath) === -1) { break; } } for (let j = i; j < stacks.length; ++j) { lines += "\n" + stacks[j]; } if (error.stack) { const pos = error.stack.indexOf("\n"); error.stack = error.stack.slice(0, pos) + lines; } return error; } exports.optimizeErrorStack = optimizeErrorStack; /** * Parse the redis protocol url */ function parseURL(url) { if (isInt(url)) { return { port: url }; } let parsed = (0, url_1.parse)(url, true, true); if (!parsed.slashes && url[0] !== "/") { url = "//" + url; parsed = (0, url_1.parse)(url, true, true); } const options = parsed.query || {}; const result = {}; if (parsed.auth) { const index = parsed.auth.indexOf(":"); result.username = index === -1 ? parsed.auth : parsed.auth.slice(0, index); result.password = index === -1 ? "" : parsed.auth.slice(index + 1); } if (parsed.pathname) { if (parsed.protocol === "redis:" || parsed.protocol === "rediss:") { if (parsed.pathname.length > 1) { result.db = parsed.pathname.slice(1); } } else { result.path = parsed.pathname; } } if (parsed.host) { result.host = parsed.hostname; } if (parsed.port) { result.port = parsed.port; } if (typeof options.family === "string") { const intFamily = Number.parseInt(options.family, 10); if (!Number.isNaN(intFamily)) { result.family = intFamily; } } (0, lodash_1.defaults)(result, options); return result; } exports.parseURL = parseURL; /** * Resolve TLS profile shortcut in connection options */ function resolveTLSProfile(options) { let tls = options === null || options === void 0 ? void 0 : options.tls; if (typeof tls === "string") tls = { profile: tls }; const profile = TLSProfiles_1.default[tls === null || tls === void 0 ? void 0 : tls.profile]; if (profile) { tls = Object.assign({}, profile, tls); delete tls.profile; options = Object.assign({}, options, { tls }); } return options; } exports.resolveTLSProfile = resolveTLSProfile; /** * Get a random element from `array` */ function sample(array, from = 0) { const length = array.length; if (from >= length) { return null; } return array[from + Math.floor(Math.random() * (length - from))]; } exports.sample = sample; /** * Shuffle the array using the Fisher-Yates Shuffle. * This method will mutate the original array. */ function shuffle(array) { let counter = array.length; // While there are elements in the array while (counter > 0) { // Pick a random index const index = Math.floor(Math.random() * counter); // Decrease counter by 1 counter--; // And swap the last element with it [array[counter], array[index]] = [array[index], array[counter]]; } return array; } exports.shuffle = shuffle; /** * Error message for connection being disconnected */ exports.CONNECTION_CLOSED_ERROR_MSG = "Connection is closed."; function zipMap(keys, values) { const map = new Map(); keys.forEach((key, index) => { map.set(key, values[index]); }); return map; } exports.zipMap = zipMap; } (utils)); Object.defineProperty(Command$1, "__esModule", { value: true }); const commands_1$2 = built$1; const calculateSlot$1 = libExports; const standard_as_callback_1$3 = built; const utils_1$8 = utils; /** * Command instance * * It's rare that you need to create a Command instance yourself. * * ```js * var infoCommand = new Command('info', null, function (err, result) { * console.log('result', result); * }); * * redis.sendCommand(infoCommand); * * // When no callback provided, Command instance will have a `promise` property, * // which will resolve/reject with the result of the command. * var getCommand = new Command('get', ['foo']); * getCommand.promise.then(function (result) { * console.log('result', result); * }); * ``` */ class Command { /** * Creates an instance of Command. * @param name Command name * @param args An array of command arguments * @param options * @param callback The callback that handles the response. * If omit, the response will be handled via Promise */ constructor(name, args = [], options = {}, callback) { this.name = name; this.inTransaction = false; this.isResolved = false; this.transformed = false; this.replyEncoding = options.replyEncoding; this.errorStack = options.errorStack; this.args = args.flat(); this.callback = callback; this.initPromise(); if (options.keyPrefix) { // @ts-expect-error const isBufferKeyPrefix = options.keyPrefix instanceof Buffer; // @ts-expect-error let keyPrefixBuffer = isBufferKeyPrefix ? options.keyPrefix : null; this._iterateKeys((key) => { if (key instanceof Buffer) { if (keyPrefixBuffer === null) { keyPrefixBuffer = Buffer.from(options.keyPrefix); } return Buffer.concat([keyPrefixBuffer, key]); } else if (isBufferKeyPrefix) { // @ts-expect-error return Buffer.concat([options.keyPrefix, Buffer.from(String(key))]); } return options.keyPrefix + key; }); } if (options.readOnly) { this.isReadOnly = true; } } /** * Check whether the command has the flag */ static checkFlag(flagName, commandName) { return !!this.getFlagMap()[flagName][commandName]; } static setArgumentTransformer(name, func) { this._transformer.argument[name] = func; } static setReplyTransformer(name, func) { this._transformer.reply[name] = func; } static getFlagMap() { if (!this.flagMap) { this.flagMap = Object.keys(Command.FLAGS).reduce((map, flagName) => { map[flagName] = {}; Command.FLAGS[flagName].forEach((commandName) => { map[flagName][commandName] = true; }); return map; }, {}); } return this.flagMap; } getSlot() { if (typeof this.slot === "undefined") { const key = this.getKeys()[0]; this.slot = key == null ? null : calculateSlot$1(key); } return this.slot; } getKeys() { return this._iterateKeys(); } /** * Convert command to writable buffer or string */ toWritable(_socket) { let result; const commandStr = "*" + (this.args.length + 1) + "\r\n$" + Buffer.byteLength(this.name) + "\r\n" + this.name + "\r\n"; if (this.bufferMode) { const buffers = new MixedBuffers(); buffers.push(commandStr); for (let i = 0; i < this.args.length; ++i) { const arg = this.args[i]; if (arg instanceof Buffer) { if (arg.length === 0) { buffers.push("$0\r\n\r\n"); } else { buffers.push("$" + arg.length + "\r\n"); buffers.push(arg); buffers.push("\r\n"); } } else { buffers.push("$" + Buffer.byteLength(arg) + "\r\n" + arg + "\r\n"); } } result = buffers.toBuffer(); } else { result = commandStr; for (let i = 0; i < this.args.length; ++i) { const arg = this.args[i]; result += "$" + Buffer.byteLength(arg) + "\r\n" + arg + "\r\n"; } } return result; } stringifyArguments() { for (let i = 0; i < this.args.length; ++i) { const arg = this.args[i]; if (typeof arg === "string") ; else if (arg instanceof Buffer) { this.bufferMode = true; } else { this.args[i] = (0, utils_1$8.toArg)(arg); } } } /** * Convert buffer/buffer[] to string/string[], * and apply reply transformer. */ transformReply(result) { if (this.replyEncoding) { result = (0, utils_1$8.convertBufferToString)(result, this.replyEncoding); } const transformer = Command._transformer.reply[this.name]; if (transformer) { result = transformer(result); } return result; } /** * Set the wait time before terminating the attempt to execute a command * and generating an error. */ setTimeout(ms) { if (!this._commandTimeoutTimer) { this._commandTimeoutTimer = setTimeout(() => { if (!this.isResolved) { this.reject(new Error("Command timed out")); } }, ms); } } initPromise() { const promise = new Promise((resolve, reject) => { if (!this.transformed) { this.transformed = true; const transformer = Command._transformer.argument[this.name]; if (transformer) { this.args = transformer(this.args); } this.stringifyArguments(); } this.resolve = this._convertValue(resolve); if (this.errorStack) { this.reject = (err) => { reject((0, utils_1$8.optimizeErrorStack)(err, this.errorStack.stack, __dirname)); }; } else { this.reject = reject; } }); this.promise = (0, standard_as_callback_1$3.default)(promise, this.callback); } /** * Iterate through the command arguments that are considered keys. */ _iterateKeys(transform = (key) => key) { if (typeof this.keys === "undefined") { this.keys = []; if ((0, commands_1$2.exists)(this.name)) { // @ts-expect-error const keyIndexes = (0, commands_1$2.getKeyIndexes)(this.name, this.args); for (const index of keyIndexes) { this.args[index] = transform(this.args[index]); this.keys.push(this.args[index]); } } } return this.keys; } /** * Convert the value from buffer to the target encoding. */ _convertValue(resolve) { return (value) => { try { const existingTimer = this._commandTimeoutTimer; if (existingTimer) { clearTimeout(existingTimer); delete this._commandTimeoutTimer; } resolve(this.transformReply(value)); this.isResolved = true; } catch (err) { this.reject(err); } return this.promise; }; } } Command$1.default = Command; Command.FLAGS = { VALID_IN_SUBSCRIBER_MODE: [ "subscribe", "psubscribe", "unsubscribe", "punsubscribe", "ssubscribe", "sunsubscribe", "ping", "quit", ], VALID_IN_MONITOR_MODE: ["monitor", "auth"], ENTER_SUBSCRIBER_MODE: ["subscribe", "psubscribe", "ssubscribe"], EXIT_SUBSCRIBER_MODE: ["unsubscribe", "punsubscribe", "sunsubscribe"], WILL_DISCONNECT: ["quit"], }; Command._transformer = { argument: {}, reply: {}, }; const msetArgumentTransformer = function (args) { if (args.length === 1) { if (args[0] instanceof Map) { return (0, utils_1$8.convertMapToArray)(args[0]); } if (typeof args[0] === "object" && args[0] !== null) { return (0, utils_1$8.convertObjectToArray)(args[0]); } } return args; }; const hsetArgumentTransformer = function (args) { if (args.length === 2) { if (args[1] instanceof Map) { return [args[0]].concat((0, utils_1$8.convertMapToArray)(args[1])); } if (typeof args[1] === "object" && args[1] !== null) { return [args[0]].concat((0, utils_1$8.convertObjectToArray)(args[1])); } } return args; }; Command.setArgumentTransformer("mset", msetArgumentTransformer); Command.setArgumentTransformer("msetnx", msetArgumentTransformer); Command.setArgumentTransformer("hset", hsetArgumentTransformer); Command.setArgumentTransformer("hmset", hsetArgumentTransformer); Command.setReplyTransformer("hgetall", function (result) { if (Array.isArray(result)) { const obj = {}; for (let i = 0; i < result.length; i += 2) { const key = result[i]; const value = result[i + 1]; if (key in obj) { // can only be truthy if the property is special somehow, like '__proto__' or 'constructor' // https://github.com/luin/ioredis/issues/1267 Object.defineProperty(obj, key, { value, configurable: true, enumerable: true, writable: true, }); } else { obj[key] = value; } } return obj; } return result; }); class MixedBuffers { constructor() { this.length = 0; this.items = []; } push(x) { this.length += Buffer.byteLength(x); this.items.push(x); } toBuffer() { const result = Buffer.allocUnsafe(this.length); let offset = 0; for (const item of this.items) { const length = Buffer.byteLength(item); Buffer.isBuffer(item) ? item.copy(result, offset) : result.write(item, offset, length); offset += length; } return result; } } var ClusterAllFailedError$1 = {}; Object.defineProperty(ClusterAllFailedError$1, "__esModule", { value: true }); const redis_errors_1$1 = redisErrors; class ClusterAllFailedError extends redis_errors_1$1.RedisError { constructor(message, lastNodeError) { super(message); this.lastNodeError = lastNodeError; Error.captureStackTrace(this, this.constructor); } get name() { return this.constructor.name; } } ClusterAllFailedError$1.default = ClusterAllFailedError; ClusterAllFailedError.defaultMessage = "Failed to refresh slots cache."; var ScanStream$1 = {}; Object.defineProperty(ScanStream$1, "__esModule", { value: true }); const stream_1 = stream; /** * Convenient class to convert the process of scanning keys to a readable stream. */ class ScanStream extends stream_1.Readable { constructor(opt) { super(opt); this.opt = opt; this._redisCursor = "0"; this._redisDrained = false; } _read() { if (this._redisDrained) { this.push(null); return; } const args = [this._redisCursor]; if (this.opt.key) { args.unshift(this.opt.key); } if (this.opt.match) { args.push("MATCH", this.opt.match); } if (this.opt.type) { args.push("TYPE", this.opt.type); } if (this.opt.count) { args.push("COUNT", String(this.opt.count)); } this.opt.redis[this.opt.command](args, (err, res) => { if (err) { this.emit("error", err); return; } this._redisCursor = res[0] instanceof Buffer ? res[0].toString() : res[0]; if (this._redisCursor === "0") { this._redisDrained = true; } this.push(res[1]); }); } close() { this._redisDrained = true; } } ScanStream$1.default = ScanStream; var transaction = {}; var Pipeline$1 = {}; var Commander$1 = {}; var autoPipelining = {}; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.executeWithAutoPipelining = exports.getFirstValueInFlattenedArray = exports.shouldUseAutoPipelining = exports.notAllowedAutoPipelineCommands = exports.kCallbacks = exports.kExec = void 0; const lodash_1 = lodash; const calculateSlot = libExports; const standard_as_callback_1 = built; exports.kExec = Symbol("exec"); exports.kCallbacks = Symbol("callbacks"); exports.notAllowedAutoPipelineCommands = [ "auth", "info", "script", "quit", "cluster", "pipeline", "multi", "subscribe", "psubscribe", "unsubscribe", "unpsubscribe", "select", ]; function executeAutoPipeline(client, slotKey) { /* If a pipeline is already executing, keep queueing up commands since ioredis won't serve two pipelines at the same time */ if (client._runningAutoPipelines.has(slotKey)) { return; } if (!client._autoPipelines.has(slotKey)) { /* Rare edge case. Somehow, something has deleted this running autopipeline in an immediate call to executeAutoPipeline. Maybe the callback in the pipeline.exec is sometimes called in the same tick, e.g. if redis is disconnected? */ return; } client._runningAutoPipelines.add(slotKey); // Get the pipeline and immediately delete it so that new commands are queued on a new pipeline const pipeline = client._autoPipelines.get(slotKey); client._autoPipelines.delete(slotKey); const callbacks = pipeline[exports.kCallbacks]; // Stop keeping a reference to callbacks immediately after the callbacks stop being used. // This allows the GC to reclaim objects referenced by callbacks, especially with 16384 slots // in Redis.Cluster pipeline[exports.kCallbacks] = null; // Perform the call pipeline.exec(function (err, results) { client._runningAutoPipelines.delete(slotKey); /* Invoke all callback in nextTick so the stack is cleared and callbacks can throw errors without affecting other callbacks. */ if (err) { for (let i = 0; i < callbacks.length; i++) { process.nextTick(callbacks[i], err); } } else { for (let i = 0; i < callbacks.length; i++) { process.nextTick(callbacks[i], ...results[i]); } } // If there is another pipeline on the same node, immediately execute it without waiting for nextTick if (client._autoPipelines.has(slotKey)) { executeAutoPipeline(client, slotKey); } }); } function shouldUseAutoPipelining(client, functionName, commandName) { return (functionName && client.options.enableAutoPipelining && !client.isPipeline && !exports.notAllowedAutoPipelineCommands.includes(commandName) && !client.options.autoPipeliningIgnoredCommands.includes(commandName)); } exports.shouldUseAutoPipelining = shouldUseAutoPipelining; function getFirstValueInFlattenedArray(args) { for (let i = 0; i < args.length; i++) { const arg = args[i]; if (typeof arg === "string") { return arg; } else if (Array.isArray(arg) || (0, lodash_1.isArguments)(arg)) { if (arg.length === 0) { continue; } return arg[0]; } const flattened = [arg].flat(); if (flattened.length > 0) { return flattened[0]; } } return undefined; } exports.getFirstValueInFlattenedArray = getFirstValueInFlattenedArray; function executeWithAutoPipelining(client, functionName, commandName, args, callback) { // On cluster mode let's wait for slots to be available if (client.isCluster && !client.slots.length) { if (client.status === "wait") client.connect().catch(lodash_1.noop); return (0, standard_as_callback_1.default)(new Promise(function (resolve, reject) { client.delayUntilReady((err) => { if (err) { reject(err); return; } executeWithAutoPipelining(client, functionName, commandName, args, null).then(resolve, reject); }); }), callback); } // If we have slot information, we can improve routing by grouping slots served by the same subset of nodes // Note that the first value in args may be a (possibly empty) array. // ioredis will only flatten one level of the array, in the Command constructor. const prefix = client.options.keyPrefix || ""; const slotKey = client.isCluster ? client.slots[calculateSlot(`${prefix}${getFirstValueInFlattenedArray(args)}`)].join(",") : "main"; if (!client._autoPipelines.has(slotKey)) { const pipeline = client.pipeline(); pipeline[exports.kExec] = false; pipeline[exports.kCallbacks] = []; client._autoPipelines.set(slotKey, pipeline); } const pipeline = client._autoPipelines.get(slotKey); /* Mark the pipeline as scheduled. The symbol will make sure that the pipeline is only scheduled once per tick. New commands are appended to an already scheduled pipeline. */ if (!pipeline[exports.kExec]) { pipeline[exports.kExec] = true; /* Deferring with setImmediate so we have a chance to capture multiple commands that can be scheduled by I/O events already in the event loop queue. */ setImmediate(executeAutoPipeline, client, slotKey); } // Create the promise which will execute the command in the pipeline. const autoPipelinePromise = new Promise(function (resolve, reject) { pipeline[exports.kCallbacks].push(function (err, value) { if (err) { reject(err); return; } resolve(value); }); if (functionName === "call") { args.unshift(commandName); } pipeline[functionName](...args); }); return (0, standard_as_callback_1.default)(autoPipelinePromise, callback); } exports.executeWithAutoPipelining = executeWithAutoPipelining; } (autoPipelining)); var Script$1 = {}; Object.defineProperty(Script$1, "__esModule", { value: true }); const crypto_1 = require$$0$3; const Command_1$3 = Command$1; const standard_as_callback_1$2 = built; class Script { constructor(lua, numberOfKeys = null, keyPrefix = "", readOnly = false) { this.lua = lua; this.numberOfKeys = numberOfKeys; this.keyPrefix = keyPrefix; this.readOnly = readOnly; this.sha = (0, crypto_1.createHash)("sha1").update(lua).digest("hex"); const sha = this.sha; const socketHasScriptLoaded = new WeakSet(); this.Command = class CustomScriptCommand extends Command_1$3.default { toWritable(socket) { const origReject = this.reject; this.reject = (err) => { if (err.message.indexOf("NOSCRIPT") !== -1) { socketHasScriptLoaded.delete(socket); } origReject.call(this, err); }; if (!socketHasScriptLoaded.has(socket)) { socketHasScriptLoaded.add(socket); this.name = "eval"; this.args[0] = lua; } else if (this.name === "eval") { this.name = "evalsha"; this.args[0] = sha; } return super.toWritable(socket); } }; } execute(container, args, options, callback) { if (typeof this.numberOfKeys === "number") { args.unshift(this.numberOfKeys); } if (this.keyPrefix) { options.keyPrefix = this.keyPrefix; } if (this.readOnly) { options.readOnly = true; } const evalsha = new this.Command("evalsha", [this.sha, ...args], options); evalsha.promise = evalsha.promise.catch((err) => { if (err.message.indexOf("NOSCRIPT") === -1) { throw err; } // Resend the same custom evalsha command that gets transformed // to an eval in case it's not loaded yet on the connection. const resend = new this.Command("evalsha", [this.sha, ...args], options); const client = container.isPipeline ? container.redis : container; return client.sendCommand(resend); }); (0, standard_as_callback_1$2.default)(evalsha.promise, callback); return container.sendCommand(evalsha); } } Script$1.default = Script; Object.defineProperty(Commander$1, "__esModule", { value: true }); const commands_1$1 = built$1; const autoPipelining_1 = autoPipelining; const Command_1$2 = Command$1; const Script_1 = Script$1; // eslint-disable-next-line @typescript-eslint/no-unused-vars class Commander { constructor() { this.options = {}; /** * @ignore */ this.scriptsSet = {}; /** * @ignore */ this.addedBuiltinSet = new Set(); } /** * Return supported builtin commands */ getBuiltinCommands() { return commands.slice(0); } /** * Create a builtin command */ createBuiltinCommand(commandName) { return { string: generateFunction(null, commandName, "utf8"), buffer: generateFunction(null, commandName, null), }; } /** * Create add builtin command */ addBuiltinCommand(commandName) { this.addedBuiltinSet.add(commandName); this[commandName] = generateFunction(commandName, commandName, "utf8"); this[commandName + "Buffer"] = generateFunction(commandName + "Buffer", commandName, null); } /** * Define a custom command using lua script */ defineCommand(name, definition) { const script = new Script_1.default(definition.lua, definition.numberOfKeys, this.options.keyPrefix, definition.readOnly); this.scriptsSet[name] = script; this[name] = generateScriptingFunction(name, name, script, "utf8"); this[name + "Buffer"] = generateScriptingFunction(name + "Buffer", name, script, null); } /** * @ignore */ sendCommand(command, stream, node) { throw new Error('"sendCommand" is not implemented'); } } const commands = commands_1$1.list.filter((command) => command !== "monitor"); commands.push("sentinel"); commands.forEach(function (commandName) { Commander.prototype[commandName] = generateFunction(commandName, commandName, "utf8"); Commander.prototype[commandName + "Buffer"] = generateFunction(commandName + "Buffer", commandName, null); }); Commander.prototype.call = generateFunction("call", "utf8"); Commander.prototype.callBuffer = generateFunction("callBuffer", null); // @ts-expect-error Commander.prototype.send_command = Commander.prototype.call; function generateFunction(functionName, _commandName, _encoding) { if (typeof _encoding === "undefined") { _encoding = _commandName; _commandName = null; } return function (...args) { const commandName = (_commandName || args.shift()); let callback = args[args.length - 1]; if (typeof callback === "function") { args.pop(); } else { callback = undefined; } const options = { errorStack: this.options.showFriendlyErrorStack ? new Error() : undefined, keyPrefix: this.options.keyPrefix, replyEncoding: _encoding, }; // No auto pipeline, use regular command sending if (!(0, autoPipelining_1.shouldUseAutoPipelining)(this, functionName, commandName)) { return this.sendCommand( // @ts-expect-error new Command_1$2.default(commandName, args, options, callback)); } // Create a new pipeline and make sure it's scheduled return (0, autoPipelining_1.executeWithAutoPipelining)(this, functionName, commandName, // @ts-expect-error args, callback); }; } function generateScriptingFunction(functionName, commandName, script, encoding) { return function (...args) { const callback = typeof args[args.length - 1] === "function" ? args.pop() : undefined; const options = { replyEncoding: encoding, }; if (this.options.showFriendlyErrorStack) { options.errorStack = new Error(); } // No auto pipeline, use regular command sending if (!(0, autoPipelining_1.shouldUseAutoPipelining)(this, functionName, commandName)) { return script.execute(this, args, options, callback); } // Create a new pipeline and make sure it's scheduled return (0, autoPipelining_1.executeWithAutoPipelining)(this, functionName, commandName, args, callback); }; } Commander$1.default = Commander; Object.defineProperty(Pipeline$1, "__esModule", { value: true }); const calculateSlot = libExports; const commands_1 = built$1; const standard_as_callback_1$1 = built; const util_1 = require$$1; const Command_1$1 = Command$1; const utils_1$7 = utils; const Commander_1 = Commander$1; /* This function derives from the cluster-key-slot implementation. Instead of checking that all keys have the same slot, it checks that all slots are served by the same set of nodes. If this is satisfied, it returns the first key's slot. */ function generateMultiWithNodes(redis, keys) { const slot = calculateSlot(keys[0]); const target = redis._groupsBySlot[slot]; for (let i = 1; i < keys.length; i++) { if (redis._groupsBySlot[calculateSlot(keys[i])] !== target) { return -1; } } return slot; } class Pipeline extends Commander_1.default { constructor(redis) { super(); this.redis = redis; this.isPipeline = true; this.replyPending = 0; this._queue = []; this._result = []; this._transactions = 0; this._shaToScript = {}; this.isCluster = this.redis.constructor.name === "Cluster" || this.redis.isCluster; this.options = redis.options; Object.keys(redis.scriptsSet).forEach((name) => { const script = redis.scriptsSet[name]; this._shaToScript[script.sha] = script; this[name] = redis[name]; this[name + "Buffer"] = redis[name + "Buffer"]; }); redis.addedBuiltinSet.forEach((name) => { this[name] = redis[name]; this[name + "Buffer"] = redis[name + "Buffer"]; }); this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; }); const _this = this; Object.defineProperty(this, "length", { get: function () { return _this._queue.length; }, }); } fillResult(value, position) { if (this._queue[position].name === "exec" && Array.isArray(value[1])) { const execLength = value[1].length; for (let i = 0; i < execLength; i++) { if (value[1][i] instanceof Error) { continue; } const cmd = this._queue[position - (execLength - i)]; try { value[1][i] = cmd.transformReply(value[1][i]); } catch (err) { value[1][i] = err; } } } this._result[position] = value; if (--this.replyPending) { return; } if (this.isCluster) { let retriable = true; let commonError; for (let i = 0; i < this._result.length; ++i) { const error = this._result[i][0]; const command = this._queue[i]; if (error) { if (command.name === "exec" && error.message === "EXECABORT Transaction discarded because of previous errors.") { continue; } if (!commonError) { commonError = { name: error.name, message: error.message, }; } else if (commonError.name !== error.name || commonError.message !== error.message) { retriable = false; break; } } else if (!command.inTransaction) { const isReadOnly = (0, commands_1.exists)(command.name) && (0, commands_1.hasFlag)(command.name, "readonly"); if (!isReadOnly) { retriable = false; break; } } } if (commonError && retriable) { const _this = this; const errv = commonError.message.split(" "); const queue = this._queue; let inTransaction = false; this._queue = []; for (let i = 0; i < queue.length; ++i) { if (errv[0] === "ASK" && !inTransaction && queue[i].name !== "asking" && (!queue[i - 1] || queue[i - 1].name !== "asking")) { const asking = new Command_1$1.default("asking"); asking.ignore = true; this.sendCommand(asking); } queue[i].initPromise(); this.sendCommand(queue[i]); inTransaction = queue[i].inTransaction; } let matched = true; if (typeof this.leftRedirections === "undefined") { this.leftRedirections = {}; } const exec = function () { _this.exec(); }; const cluster = this.redis; cluster.handleError(commonError, this.leftRedirections, { moved: function (_slot, key) { _this.preferKey = key; cluster.slots[errv[1]] = [key]; cluster._groupsBySlot[errv[1]] = cluster._groupsIds[cluster.slots[errv[1]].join(";")]; cluster.refreshSlotsCache(); _this.exec(); }, ask: function (_slot, key) { _this.preferKey = key; _this.exec(); }, tryagain: exec, clusterDown: exec, connectionClosed: exec, maxRedirections: () => { matched = false; }, defaults: () => { matched = false; }, }); if (matched) { return; } } } let ignoredCount = 0; for (let i = 0; i < this._queue.length - ignoredCount; ++i) { if (this._queue[i + ignoredCount].ignore) { ignoredCount += 1; } this._result[i] = this._result[i + ignoredCount]; } this.resolve(this._result.slice(0, this._result.length - ignoredCount)); } sendCommand(command) { if (this._transactions > 0) { command.inTransaction = true; } const position = this._queue.length; command.pipelineIndex = position; command.promise .then((result) => { this.fillResult([null, result], position); }) .catch((error) => { this.fillResult([error], position); }); this._queue.push(command); return this; } addBatch(commands) { let command, commandName, args; for (let i = 0; i < commands.length; ++i) { command = commands[i]; commandName = command[0]; args = command.slice(1); this[commandName].apply(this, args); } return this; } } Pipeline$1.default = Pipeline; // @ts-expect-error const multi = Pipeline.prototype.multi; // @ts-expect-error Pipeline.prototype.multi = function () { this._transactions += 1; return multi.apply(this, arguments); }; // @ts-expect-error const execBuffer = Pipeline.prototype.execBuffer; // @ts-expect-error Pipeline.prototype.execBuffer = (0, util_1.deprecate)(function () { if (this._transactions > 0) { this._transactions -= 1; } return execBuffer.apply(this, arguments); }, "Pipeline#execBuffer: Use Pipeline#exec instead"); // NOTE: To avoid an unhandled promise rejection, this will unconditionally always return this.promise, // which always has the rejection handled by standard-as-callback // adding the provided rejection callback. // // If a different promise instance were returned, that promise would cause its own unhandled promise rejection // errors, even if that promise unconditionally resolved to **the resolved value of** this.promise. Pipeline.prototype.exec = function (callback) { // Wait for the cluster to be connected, since we need nodes information before continuing if (this.isCluster && !this.redis.slots.length) { if (this.redis.status === "wait") this.redis.connect().catch(utils_1$7.noop); if (callback && !this.nodeifiedPromise) { this.nodeifiedPromise = true; (0, standard_as_callback_1$1.default)(this.promise, callback); } this.redis.delayUntilReady((err) => { if (err) { this.reject(err); return; } this.exec(callback); }); return this.promise; } if (this._transactions > 0) { this._transactions -= 1; return execBuffer.apply(this, arguments); } if (!this.nodeifiedPromise) { this.nodeifiedPromise = true; (0, standard_as_callback_1$1.default)(this.promise, callback); } if (!this._queue.length) { this.resolve([]); } let pipelineSlot; if (this.isCluster) { // List of the first key for each command const sampleKeys = []; for (let i = 0; i < this._queue.length; i++) { const keys = this._queue[i].getKeys(); if (keys.length) { sampleKeys.push(keys[0]); } // For each command, check that the keys belong to the same slot if (keys.length && calculateSlot.generateMulti(keys) < 0) { this.reject(new Error("All the keys in a pipeline command should belong to the same slot")); return this.promise; } } if (sampleKeys.length) { pipelineSlot = generateMultiWithNodes(this.redis, sampleKeys); if (pipelineSlot < 0) { this.reject(new Error("All keys in the pipeline should belong to the same slots allocation group")); return this.promise; } } else { // Send the pipeline to a random node pipelineSlot = (Math.random() * 16384) | 0; } } const _this = this; execPipeline(); return this.promise; function execPipeline() { let writePending = (_this.replyPending = _this._queue.length); let node; if (_this.isCluster) { node = { slot: pipelineSlot, redis: _this.redis.connectionPool.nodes.all[_this.preferKey], }; } let data = ""; let buffers; const stream = { isPipeline: true, destination: _this.isCluster ? node : { redis: _this.redis }, write(writable) { if (typeof writable !== "string") { if (!buffers) { buffers = []; } if (data) { buffers.push(Buffer.from(data, "utf8")); data = ""; } buffers.push(writable); } else { data += writable; } if (!--writePending) { if (buffers) { if (data) { buffers.push(Buffer.from(data, "utf8")); } stream.destination.redis.stream.write(Buffer.concat(buffers)); } else { stream.destination.redis.stream.write(data); } // Reset writePending for resending writePending = _this._queue.length; data = ""; buffers = undefined; } }, }; for (let i = 0; i < _this._queue.length; ++i) { _this.redis.sendCommand(_this._queue[i], stream, node); } return _this.promise; } }; Object.defineProperty(transaction, "__esModule", { value: true }); transaction.addTransactionSupport = void 0; const utils_1$6 = utils; const standard_as_callback_1 = built; const Pipeline_1 = Pipeline$1; function addTransactionSupport(redis) { redis.pipeline = function (commands) { const pipeline = new Pipeline_1.default(this); if (Array.isArray(commands)) { pipeline.addBatch(commands); } return pipeline; }; const { multi } = redis; redis.multi = function (commands, options) { if (typeof options === "undefined" && !Array.isArray(commands)) { options = commands; commands = null; } if (options && options.pipeline === false) { return multi.call(this); } const pipeline = new Pipeline_1.default(this); // @ts-expect-error pipeline.multi(); if (Array.isArray(commands)) { pipeline.addBatch(commands); } const exec = pipeline.exec; pipeline.exec = function (callback) { // Wait for the cluster to be connected, since we need nodes information before continuing if (this.isCluster && !this.redis.slots.length) { if (this.redis.status === "wait") this.redis.connect().catch(utils_1$6.noop); return (0, standard_as_callback_1.default)(new Promise((resolve, reject) => { this.redis.delayUntilReady((err) => { if (err) { reject(err); return; } this.exec(pipeline).then(resolve, reject); }); }), callback); } if (this._transactions > 0) { exec.call(pipeline); } // Returns directly when the pipeline // has been called multiple times (retries). if (this.nodeifiedPromise) { return exec.call(pipeline); } const promise = exec.call(pipeline); return (0, standard_as_callback_1.default)(promise.then(function (result) { const execResult = result[result.length - 1]; if (typeof execResult === "undefined") { throw new Error("Pipeline cannot be used to send any commands when the `exec()` has been called on it."); } if (execResult[0]) { execResult[0].previousErrors = []; for (let i = 0; i < result.length - 1; ++i) { if (result[i][0]) { execResult[0].previousErrors.push(result[i][0]); } } throw execResult[0]; } return (0, utils_1$6.wrapMultiResult)(execResult[1]); }), callback); }; // @ts-expect-error const { execBuffer } = pipeline; // @ts-expect-error pipeline.execBuffer = function (callback) { if (this._transactions > 0) { execBuffer.call(pipeline); } return pipeline.exec(callback); }; return pipeline; }; const { exec } = redis; redis.exec = function (callback) { return (0, standard_as_callback_1.default)(exec.call(this).then(function (results) { if (Array.isArray(results)) { results = (0, utils_1$6.wrapMultiResult)(results); } return results; }), callback); }; } transaction.addTransactionSupport = addTransactionSupport; var applyMixin$1 = {}; Object.defineProperty(applyMixin$1, "__esModule", { value: true }); function applyMixin(derivedConstructor, mixinConstructor) { Object.getOwnPropertyNames(mixinConstructor.prototype).forEach((name) => { Object.defineProperty(derivedConstructor.prototype, name, Object.getOwnPropertyDescriptor(mixinConstructor.prototype, name)); }); } applyMixin$1.default = applyMixin; var ClusterOptions = {}; Object.defineProperty(ClusterOptions, "__esModule", { value: true }); ClusterOptions.DEFAULT_CLUSTER_OPTIONS = void 0; const dns_1 = require$$0$8; ClusterOptions.DEFAULT_CLUSTER_OPTIONS = { clusterRetryStrategy: (times) => Math.min(100 + times * 2, 2000), enableOfflineQueue: true, enableReadyCheck: true, scaleReads: "master", maxRedirections: 16, retryDelayOnMoved: 0, retryDelayOnFailover: 100, retryDelayOnClusterDown: 100, retryDelayOnTryAgain: 100, slotsRefreshTimeout: 1000, useSRVRecords: false, resolveSrv: dns_1.resolveSrv, dnsLookup: dns_1.lookup, enableAutoPipelining: false, autoPipeliningIgnoredCommands: [], }; var ClusterSubscriber = {}; var util = {}; Object.defineProperty(util, "__esModule", { value: true }); util.getConnectionName = util.weightSrvRecords = util.groupSrvRecords = util.getUniqueHostnamesFromOptions = util.normalizeNodeOptions = util.nodeKeyToRedisOptions = util.getNodeKey = void 0; const utils_1$5 = utils; const net_1$1 = require$$0$9; function getNodeKey(node) { node.port = node.port || 6379; node.host = node.host || "127.0.0.1"; return node.host + ":" + node.port; } util.getNodeKey = getNodeKey; function nodeKeyToRedisOptions(nodeKey) { const portIndex = nodeKey.lastIndexOf(":"); if (portIndex === -1) { throw new Error(`Invalid node key ${nodeKey}`); } return { host: nodeKey.slice(0, portIndex), port: Number(nodeKey.slice(portIndex + 1)), }; } util.nodeKeyToRedisOptions = nodeKeyToRedisOptions; function normalizeNodeOptions(nodes) { return nodes.map((node) => { const options = {}; if (typeof node === "object") { Object.assign(options, node); } else if (typeof node === "string") { Object.assign(options, (0, utils_1$5.parseURL)(node)); } else if (typeof node === "number") { options.port = node; } else { throw new Error("Invalid argument " + node); } if (typeof options.port === "string") { options.port = parseInt(options.port, 10); } // Cluster mode only support db 0 delete options.db; if (!options.port) { options.port = 6379; } if (!options.host) { options.host = "127.0.0.1"; } return (0, utils_1$5.resolveTLSProfile)(options); }); } util.normalizeNodeOptions = normalizeNodeOptions; function getUniqueHostnamesFromOptions(nodes) { const uniqueHostsMap = {}; nodes.forEach((node) => { uniqueHostsMap[node.host] = true; }); return Object.keys(uniqueHostsMap).filter((host) => !(0, net_1$1.isIP)(host)); } util.getUniqueHostnamesFromOptions = getUniqueHostnamesFromOptions; function groupSrvRecords(records) { const recordsByPriority = {}; for (const record of records) { if (!recordsByPriority.hasOwnProperty(record.priority)) { recordsByPriority[record.priority] = { totalWeight: record.weight, records: [record], }; } else { recordsByPriority[record.priority].totalWeight += record.weight; recordsByPriority[record.priority].records.push(record); } } return recordsByPriority; } util.groupSrvRecords = groupSrvRecords; function weightSrvRecords(recordsGroup) { if (recordsGroup.records.length === 1) { recordsGroup.totalWeight = 0; return recordsGroup.records.shift(); } // + `recordsGroup.records.length` to support `weight` 0 const random = Math.floor(Math.random() * (recordsGroup.totalWeight + recordsGroup.records.length)); let total = 0; for (const [i, record] of recordsGroup.records.entries()) { total += 1 + record.weight; if (total > random) { recordsGroup.totalWeight -= record.weight; recordsGroup.records.splice(i, 1); return record; } } } util.weightSrvRecords = weightSrvRecords; function getConnectionName(component, nodeConnectionName) { const prefix = `ioredis-cluster(${component})`; return nodeConnectionName ? `${prefix}:${nodeConnectionName}` : prefix; } util.getConnectionName = getConnectionName; var hasRequiredClusterSubscriber; function requireClusterSubscriber () { if (hasRequiredClusterSubscriber) return ClusterSubscriber; hasRequiredClusterSubscriber = 1; Object.defineProperty(ClusterSubscriber, "__esModule", { value: true }); const util_1 = util; const utils_1 = utils; const Redis_1 = requireRedis(); const debug = (0, utils_1.Debug)("cluster:subscriber"); let ClusterSubscriber$1 = class ClusterSubscriber { constructor(connectionPool, emitter) { this.connectionPool = connectionPool; this.emitter = emitter; this.started = false; this.subscriber = null; this.onSubscriberEnd = () => { if (!this.started) { debug("subscriber has disconnected, but ClusterSubscriber is not started, so not reconnecting."); return; } // If the subscriber closes whilst it's still the active connection, // we might as well try to connecting to a new node if possible to // minimise the number of missed publishes. debug("subscriber has disconnected, selecting a new one..."); this.selectSubscriber(); }; // If the current node we're using as the subscriber disappears // from the node pool for some reason, we will select a new one // to connect to. // Note that this event is only triggered if the connection to // the node has been used; cluster subscriptions are setup with // lazyConnect = true. It's possible for the subscriber node to // disappear without this method being called! // See https://github.com/luin/ioredis/pull/1589 this.connectionPool.on("-node", (_, key) => { if (!this.started || !this.subscriber) { return; } if ((0, util_1.getNodeKey)(this.subscriber.options) === key) { debug("subscriber has left, selecting a new one..."); this.selectSubscriber(); } }); this.connectionPool.on("+node", () => { if (!this.started || this.subscriber) { return; } debug("a new node is discovered and there is no subscriber, selecting a new one..."); this.selectSubscriber(); }); } getInstance() { return this.subscriber; } start() { this.started = true; this.selectSubscriber(); debug("started"); } stop() { this.started = false; if (this.subscriber) { this.subscriber.disconnect(); this.subscriber = null; } debug("stopped"); } selectSubscriber() { const lastActiveSubscriber = this.lastActiveSubscriber; // Disconnect the previous subscriber even if there // will not be a new one. if (lastActiveSubscriber) { lastActiveSubscriber.off("end", this.onSubscriberEnd); lastActiveSubscriber.disconnect(); } if (this.subscriber) { this.subscriber.off("end", this.onSubscriberEnd); this.subscriber.disconnect(); } const sampleNode = (0, utils_1.sample)(this.connectionPool.getNodes()); if (!sampleNode) { debug("selecting subscriber failed since there is no node discovered in the cluster yet"); this.subscriber = null; return; } const { options } = sampleNode; debug("selected a subscriber %s:%s", options.host, options.port); /* * Create a specialized Redis connection for the subscription. * Note that auto reconnection is enabled here. * * `enableReadyCheck` is also enabled because although subscription is allowed * while redis is loading data from the disk, we can check if the password * provided for the subscriber is correct, and if not, the current subscriber * will be disconnected and a new subscriber will be selected. */ this.subscriber = new Redis_1.default({ port: options.port, host: options.host, username: options.username, password: options.password, enableReadyCheck: true, connectionName: (0, util_1.getConnectionName)("subscriber", options.connectionName), lazyConnect: true, tls: options.tls, // Don't try to reconnect the subscriber connection. If the connection fails // we will get an end event (handled below), at which point we'll pick a new // node from the pool and try to connect to that as the subscriber connection. retryStrategy: null, }); // Ignore the errors since they're handled in the connection pool. this.subscriber.on("error", utils_1.noop); // The node we lost connection to may not come back up in a // reasonable amount of time (e.g. a slave that's taken down // for maintainence), we could potentially miss many published // messages so we should reconnect as quickly as possible, to // a different node if needed. this.subscriber.once("end", this.onSubscriberEnd); // Re-subscribe previous channels const previousChannels = { subscribe: [], psubscribe: [], ssubscribe: [] }; if (lastActiveSubscriber) { const condition = lastActiveSubscriber.condition || lastActiveSubscriber.prevCondition; if (condition && condition.subscriber) { previousChannels.subscribe = condition.subscriber.channels("subscribe"); previousChannels.psubscribe = condition.subscriber.channels("psubscribe"); previousChannels.ssubscribe = condition.subscriber.channels("ssubscribe"); } } if (previousChannels.subscribe.length || previousChannels.psubscribe.length || previousChannels.ssubscribe.length) { let pending = 0; for (const type of ["subscribe", "psubscribe", "ssubscribe"]) { const channels = previousChannels[type]; if (channels.length) { pending += 1; debug("%s %d channels", type, channels.length); this.subscriber[type](channels) .then(() => { if (!--pending) { this.lastActiveSubscriber = this.subscriber; } }) .catch(() => { // TODO: should probably disconnect the subscriber and try again. debug("failed to %s %d channels", type, channels.length); }); } } } else { this.lastActiveSubscriber = this.subscriber; } for (const event of [ "message", "messageBuffer", "smessage", "smessageBuffer", ]) { this.subscriber.on(event, (arg1, arg2) => { this.emitter.emit(event, arg1, arg2); }); } for (const event of ["pmessage", "pmessageBuffer"]) { this.subscriber.on(event, (arg1, arg2, arg3) => { this.emitter.emit(event, arg1, arg2, arg3); }); } } }; ClusterSubscriber.default = ClusterSubscriber$1; return ClusterSubscriber; } var ConnectionPool = {}; var hasRequiredConnectionPool; function requireConnectionPool () { if (hasRequiredConnectionPool) return ConnectionPool; hasRequiredConnectionPool = 1; Object.defineProperty(ConnectionPool, "__esModule", { value: true }); const events_1 = require$$1$3; const utils_1 = utils; const util_1 = util; const Redis_1 = requireRedis(); const debug = (0, utils_1.Debug)("cluster:connectionPool"); let ConnectionPool$1 = class ConnectionPool extends events_1.EventEmitter { constructor(redisOptions) { super(); this.redisOptions = redisOptions; // master + slave = all this.nodes = { all: {}, master: {}, slave: {}, }; this.specifiedOptions = {}; } getNodes(role = "all") { const nodes = this.nodes[role]; return Object.keys(nodes).map((key) => nodes[key]); } getInstanceByKey(key) { return this.nodes.all[key]; } getSampleInstance(role) { const keys = Object.keys(this.nodes[role]); const sampleKey = (0, utils_1.sample)(keys); return this.nodes[role][sampleKey]; } /** * Find or create a connection to the node */ findOrCreate(node, readOnly = false) { const key = (0, util_1.getNodeKey)(node); readOnly = Boolean(readOnly); if (this.specifiedOptions[key]) { Object.assign(node, this.specifiedOptions[key]); } else { this.specifiedOptions[key] = node; } let redis; if (this.nodes.all[key]) { redis = this.nodes.all[key]; if (redis.options.readOnly !== readOnly) { redis.options.readOnly = readOnly; debug("Change role of %s to %s", key, readOnly ? "slave" : "master"); redis[readOnly ? "readonly" : "readwrite"]().catch(utils_1.noop); if (readOnly) { delete this.nodes.master[key]; this.nodes.slave[key] = redis; } else { delete this.nodes.slave[key]; this.nodes.master[key] = redis; } } } else { debug("Connecting to %s as %s", key, readOnly ? "slave" : "master"); redis = new Redis_1.default((0, utils_1.defaults)({ // Never try to reconnect when a node is lose, // instead, waiting for a `MOVED` error and // fetch the slots again. retryStrategy: null, // Offline queue should be enabled so that // we don't need to wait for the `ready` event // before sending commands to the node. enableOfflineQueue: true, readOnly: readOnly, }, node, this.redisOptions, { lazyConnect: true })); this.nodes.all[key] = redis; this.nodes[readOnly ? "slave" : "master"][key] = redis; redis.once("end", () => { this.removeNode(key); this.emit("-node", redis, key); if (!Object.keys(this.nodes.all).length) { this.emit("drain"); } }); this.emit("+node", redis, key); redis.on("error", function (error) { this.emit("nodeError", error, key); }); } return redis; } /** * Reset the pool with a set of nodes. * The old node will be removed. */ reset(nodes) { debug("Reset with %O", nodes); const newNodes = {}; nodes.forEach((node) => { const key = (0, util_1.getNodeKey)(node); // Don't override the existing (master) node // when the current one is slave. if (!(node.readOnly && newNodes[key])) { newNodes[key] = node; } }); Object.keys(this.nodes.all).forEach((key) => { if (!newNodes[key]) { debug("Disconnect %s because the node does not hold any slot", key); this.nodes.all[key].disconnect(); this.removeNode(key); } }); Object.keys(newNodes).forEach((key) => { const node = newNodes[key]; this.findOrCreate(node, node.readOnly); }); } /** * Remove a node from the pool. */ removeNode(key) { const { nodes } = this; if (nodes.all[key]) { debug("Remove %s from the pool", key); delete nodes.all[key]; } delete nodes.master[key]; delete nodes.slave[key]; } }; ConnectionPool.default = ConnectionPool$1; return ConnectionPool; } var DelayQueue$1 = {}; /** * Custom implementation of a double ended queue. */ function Denque(array, options) { var options = options || {}; this._capacity = options.capacity; this._head = 0; this._tail = 0; if (Array.isArray(array)) { this._fromArray(array); } else { this._capacityMask = 0x3; this._list = new Array(4); } } /** * -------------- * PUBLIC API * ------------- */ /** * Returns the item at the specified index from the list. * 0 is the first element, 1 is the second, and so on... * Elements at negative values are that many from the end: -1 is one before the end * (the last element), -2 is two before the end (one before last), etc. * @param index * @returns {*} */ Denque.prototype.peekAt = function peekAt(index) { var i = index; // expect a number or return undefined if ((i !== (i | 0))) { return void 0; } var len = this.size(); if (i >= len || i < -len) return undefined; if (i < 0) i += len; i = (this._head + i) & this._capacityMask; return this._list[i]; }; /** * Alias for peekAt() * @param i * @returns {*} */ Denque.prototype.get = function get(i) { return this.peekAt(i); }; /** * Returns the first item in the list without removing it. * @returns {*} */ Denque.prototype.peek = function peek() { if (this._head === this._tail) return undefined; return this._list[this._head]; }; /** * Alias for peek() * @returns {*} */ Denque.prototype.peekFront = function peekFront() { return this.peek(); }; /** * Returns the item that is at the back of the queue without removing it. * Uses peekAt(-1) */ Denque.prototype.peekBack = function peekBack() { return this.peekAt(-1); }; /** * Returns the current length of the queue * @return {Number} */ Object.defineProperty(Denque.prototype, 'length', { get: function length() { return this.size(); } }); /** * Return the number of items on the list, or 0 if empty. * @returns {number} */ Denque.prototype.size = function size() { if (this._head === this._tail) return 0; if (this._head < this._tail) return this._tail - this._head; else return this._capacityMask + 1 - (this._head - this._tail); }; /** * Add an item at the beginning of the list. * @param item */ Denque.prototype.unshift = function unshift(item) { if (arguments.length === 0) return this.size(); var len = this._list.length; this._head = (this._head - 1 + len) & this._capacityMask; this._list[this._head] = item; if (this._tail === this._head) this._growArray(); if (this._capacity && this.size() > this._capacity) this.pop(); if (this._head < this._tail) return this._tail - this._head; else return this._capacityMask + 1 - (this._head - this._tail); }; /** * Remove and return the first item on the list, * Returns undefined if the list is empty. * @returns {*} */ Denque.prototype.shift = function shift() { var head = this._head; if (head === this._tail) return undefined; var item = this._list[head]; this._list[head] = undefined; this._head = (head + 1) & this._capacityMask; if (head < 2 && this._tail > 10000 && this._tail <= this._list.length >>> 2) this._shrinkArray(); return item; }; /** * Add an item to the bottom of the list. * @param item */ Denque.prototype.push = function push(item) { if (arguments.length === 0) return this.size(); var tail = this._tail; this._list[tail] = item; this._tail = (tail + 1) & this._capacityMask; if (this._tail === this._head) { this._growArray(); } if (this._capacity && this.size() > this._capacity) { this.shift(); } if (this._head < this._tail) return this._tail - this._head; else return this._capacityMask + 1 - (this._head - this._tail); }; /** * Remove and return the last item on the list. * Returns undefined if the list is empty. * @returns {*} */ Denque.prototype.pop = function pop() { var tail = this._tail; if (tail === this._head) return undefined; var len = this._list.length; this._tail = (tail - 1 + len) & this._capacityMask; var item = this._list[this._tail]; this._list[this._tail] = undefined; if (this._head < 2 && tail > 10000 && tail <= len >>> 2) this._shrinkArray(); return item; }; /** * Remove and return the item at the specified index from the list. * Returns undefined if the list is empty. * @param index * @returns {*} */ Denque.prototype.removeOne = function removeOne(index) { var i = index; // expect a number or return undefined if ((i !== (i | 0))) { return void 0; } if (this._head === this._tail) return void 0; var size = this.size(); var len = this._list.length; if (i >= size || i < -size) return void 0; if (i < 0) i += size; i = (this._head + i) & this._capacityMask; var item = this._list[i]; var k; if (index < size / 2) { for (k = index; k > 0; k--) { this._list[i] = this._list[i = (i - 1 + len) & this._capacityMask]; } this._list[i] = void 0; this._head = (this._head + 1 + len) & this._capacityMask; } else { for (k = size - 1 - index; k > 0; k--) { this._list[i] = this._list[i = (i + 1 + len) & this._capacityMask]; } this._list[i] = void 0; this._tail = (this._tail - 1 + len) & this._capacityMask; } return item; }; /** * Remove number of items from the specified index from the list. * Returns array of removed items. * Returns undefined if the list is empty. * @param index * @param count * @returns {array} */ Denque.prototype.remove = function remove(index, count) { var i = index; var removed; var del_count = count; // expect a number or return undefined if ((i !== (i | 0))) { return void 0; } if (this._head === this._tail) return void 0; var size = this.size(); var len = this._list.length; if (i >= size || i < -size || count < 1) return void 0; if (i < 0) i += size; if (count === 1 || !count) { removed = new Array(1); removed[0] = this.removeOne(i); return removed; } if (i === 0 && i + count >= size) { removed = this.toArray(); this.clear(); return removed; } if (i + count > size) count = size - i; var k; removed = new Array(count); for (k = 0; k < count; k++) { removed[k] = this._list[(this._head + i + k) & this._capacityMask]; } i = (this._head + i) & this._capacityMask; if (index + count === size) { this._tail = (this._tail - count + len) & this._capacityMask; for (k = count; k > 0; k--) { this._list[i = (i + 1 + len) & this._capacityMask] = void 0; } return removed; } if (index === 0) { this._head = (this._head + count + len) & this._capacityMask; for (k = count - 1; k > 0; k--) { this._list[i = (i + 1 + len) & this._capacityMask] = void 0; } return removed; } if (i < size / 2) { this._head = (this._head + index + count + len) & this._capacityMask; for (k = index; k > 0; k--) { this.unshift(this._list[i = (i - 1 + len) & this._capacityMask]); } i = (this._head - 1 + len) & this._capacityMask; while (del_count > 0) { this._list[i = (i - 1 + len) & this._capacityMask] = void 0; del_count--; } if (index < 0) this._tail = i; } else { this._tail = i; i = (i + count + len) & this._capacityMask; for (k = size - (count + index); k > 0; k--) { this.push(this._list[i++]); } i = this._tail; while (del_count > 0) { this._list[i = (i + 1 + len) & this._capacityMask] = void 0; del_count--; } } if (this._head < 2 && this._tail > 10000 && this._tail <= len >>> 2) this._shrinkArray(); return removed; }; /** * Native splice implementation. * Remove number of items from the specified index from the list and/or add new elements. * Returns array of removed items or empty array if count == 0. * Returns undefined if the list is empty. * * @param index * @param count * @param {...*} [elements] * @returns {array} */ Denque.prototype.splice = function splice(index, count) { var i = index; // expect a number or return undefined if ((i !== (i | 0))) { return void 0; } var size = this.size(); if (i < 0) i += size; if (i > size) return void 0; if (arguments.length > 2) { var k; var temp; var removed; var arg_len = arguments.length; var len = this._list.length; var arguments_index = 2; if (!size || i < size / 2) { temp = new Array(i); for (k = 0; k < i; k++) { temp[k] = this._list[(this._head + k) & this._capacityMask]; } if (count === 0) { removed = []; if (i > 0) { this._head = (this._head + i + len) & this._capacityMask; } } else { removed = this.remove(i, count); this._head = (this._head + i + len) & this._capacityMask; } while (arg_len > arguments_index) { this.unshift(arguments[--arg_len]); } for (k = i; k > 0; k--) { this.unshift(temp[k - 1]); } } else { temp = new Array(size - (i + count)); var leng = temp.length; for (k = 0; k < leng; k++) { temp[k] = this._list[(this._head + i + count + k) & this._capacityMask]; } if (count === 0) { removed = []; if (i != size) { this._tail = (this._head + i + len) & this._capacityMask; } } else { removed = this.remove(i, count); this._tail = (this._tail - leng + len) & this._capacityMask; } while (arguments_index < arg_len) { this.push(arguments[arguments_index++]); } for (k = 0; k < leng; k++) { this.push(temp[k]); } } return removed; } else { return this.remove(i, count); } }; /** * Soft clear - does not reset capacity. */ Denque.prototype.clear = function clear() { this._list = new Array(this._list.length); this._head = 0; this._tail = 0; }; /** * Returns true or false whether the list is empty. * @returns {boolean} */ Denque.prototype.isEmpty = function isEmpty() { return this._head === this._tail; }; /** * Returns an array of all queue items. * @returns {Array} */ Denque.prototype.toArray = function toArray() { return this._copyArray(false); }; /** * ------------- * INTERNALS * ------------- */ /** * Fills the queue with items from an array * For use in the constructor * @param array * @private */ Denque.prototype._fromArray = function _fromArray(array) { var length = array.length; var capacity = this._nextPowerOf2(length); this._list = new Array(capacity); this._capacityMask = capacity - 1; this._tail = length; for (var i = 0; i < length; i++) this._list[i] = array[i]; }; /** * * @param fullCopy * @param size Initialize the array with a specific size. Will default to the current list size * @returns {Array} * @private */ Denque.prototype._copyArray = function _copyArray(fullCopy, size) { var src = this._list; var capacity = src.length; var length = this.length; size = size | length; // No prealloc requested and the buffer is contiguous if (size == length && this._head < this._tail) { // Simply do a fast slice copy return this._list.slice(this._head, this._tail); } var dest = new Array(size); var k = 0; var i; if (fullCopy || this._head > this._tail) { for (i = this._head; i < capacity; i++) dest[k++] = src[i]; for (i = 0; i < this._tail; i++) dest[k++] = src[i]; } else { for (i = this._head; i < this._tail; i++) dest[k++] = src[i]; } return dest; }; /** * Grows the internal list array. * @private */ Denque.prototype._growArray = function _growArray() { if (this._head != 0) { // double array size and copy existing data, head to end, then beginning to tail. var newList = this._copyArray(true, this._list.length << 1); this._tail = this._list.length; this._head = 0; this._list = newList; } else { this._tail = this._list.length; this._list.length <<= 1; } this._capacityMask = (this._capacityMask << 1) | 1; }; /** * Shrinks the internal list array. * @private */ Denque.prototype._shrinkArray = function _shrinkArray() { this._list.length >>>= 1; this._capacityMask >>>= 1; }; /** * Find the next power of 2, at least 4 * @private * @param {number} num * @returns {number} */ Denque.prototype._nextPowerOf2 = function _nextPowerOf2(num) { var log2 = Math.log(num) / Math.log(2); var nextPow2 = 1 << (log2 + 1); return Math.max(nextPow2, 4); }; var denque = Denque; Object.defineProperty(DelayQueue$1, "__esModule", { value: true }); const utils_1$4 = utils; const Deque = denque; const debug$3 = (0, utils_1$4.Debug)("delayqueue"); /** * Queue that runs items after specified duration */ class DelayQueue { constructor() { this.queues = {}; this.timeouts = {}; } /** * Add a new item to the queue * * @param bucket bucket name * @param item function that will run later * @param options */ push(bucket, item, options) { const callback = options.callback || process.nextTick; if (!this.queues[bucket]) { this.queues[bucket] = new Deque(); } const queue = this.queues[bucket]; queue.push(item); if (!this.timeouts[bucket]) { this.timeouts[bucket] = setTimeout(() => { callback(() => { this.timeouts[bucket] = null; this.execute(bucket); }); }, options.timeout); } } execute(bucket) { const queue = this.queues[bucket]; if (!queue) { return; } const { length } = queue; if (!length) { return; } debug$3("send %d commands in %s queue", length, bucket); this.queues[bucket] = null; while (queue.length > 0) { queue.shift()(); } } } DelayQueue$1.default = DelayQueue; var hasRequiredCluster; function requireCluster () { if (hasRequiredCluster) return cluster; hasRequiredCluster = 1; Object.defineProperty(cluster, "__esModule", { value: true }); const commands_1 = built$1; const events_1 = require$$1$3; const redis_errors_1 = redisErrors; const standard_as_callback_1 = built; const Command_1 = Command$1; const ClusterAllFailedError_1 = ClusterAllFailedError$1; const Redis_1 = requireRedis(); const ScanStream_1 = ScanStream$1; const transaction_1 = transaction; const utils_1 = utils; const applyMixin_1 = applyMixin$1; const Commander_1 = Commander$1; const ClusterOptions_1 = ClusterOptions; const ClusterSubscriber_1 = requireClusterSubscriber(); const ConnectionPool_1 = requireConnectionPool(); const DelayQueue_1 = DelayQueue$1; const util_1 = util; const Deque = denque; const debug = (0, utils_1.Debug)("cluster"); const REJECT_OVERWRITTEN_COMMANDS = new WeakSet(); /** * Client for the official Redis Cluster */ class Cluster extends Commander_1.default { /** * Creates an instance of Cluster. */ constructor(startupNodes, options = {}) { super(); this.slots = []; /** * @ignore */ this._groupsIds = {}; /** * @ignore */ this._groupsBySlot = Array(16384); /** * @ignore */ this.isCluster = true; this.retryAttempts = 0; this.delayQueue = new DelayQueue_1.default(); this.offlineQueue = new Deque(); this.isRefreshing = false; this._refreshSlotsCacheCallbacks = []; this._autoPipelines = new Map(); this._runningAutoPipelines = new Set(); this._readyDelayedCallbacks = []; /** * Every time Cluster#connect() is called, this value will be * auto-incrementing. The purpose of this value is used for * discarding previous connect attampts when creating a new * connection. */ this.connectionEpoch = 0; events_1.EventEmitter.call(this); this.startupNodes = startupNodes; this.options = (0, utils_1.defaults)({}, options, ClusterOptions_1.DEFAULT_CLUSTER_OPTIONS, this.options); if (this.options.redisOptions && this.options.redisOptions.keyPrefix && !this.options.keyPrefix) { this.options.keyPrefix = this.options.redisOptions.keyPrefix; } // validate options if (typeof this.options.scaleReads !== "function" && ["all", "master", "slave"].indexOf(this.options.scaleReads) === -1) { throw new Error('Invalid option scaleReads "' + this.options.scaleReads + '". Expected "all", "master", "slave" or a custom function'); } this.connectionPool = new ConnectionPool_1.default(this.options.redisOptions); this.connectionPool.on("-node", (redis, key) => { this.emit("-node", redis); }); this.connectionPool.on("+node", (redis) => { this.emit("+node", redis); }); this.connectionPool.on("drain", () => { this.setStatus("close"); }); this.connectionPool.on("nodeError", (error, key) => { this.emit("node error", error, key); }); this.subscriber = new ClusterSubscriber_1.default(this.connectionPool, this); if (this.options.scripts) { Object.entries(this.options.scripts).forEach(([name, definition]) => { this.defineCommand(name, definition); }); } if (this.options.lazyConnect) { this.setStatus("wait"); } else { this.connect().catch((err) => { debug("connecting failed: %s", err); }); } } /** * Connect to a cluster */ connect() { return new Promise((resolve, reject) => { if (this.status === "connecting" || this.status === "connect" || this.status === "ready") { reject(new Error("Redis is already connecting/connected")); return; } const epoch = ++this.connectionEpoch; this.setStatus("connecting"); this.resolveStartupNodeHostnames() .then((nodes) => { if (this.connectionEpoch !== epoch) { debug("discard connecting after resolving startup nodes because epoch not match: %d != %d", epoch, this.connectionEpoch); reject(new redis_errors_1.RedisError("Connection is discarded because a new connection is made")); return; } if (this.status !== "connecting") { debug("discard connecting after resolving startup nodes because the status changed to %s", this.status); reject(new redis_errors_1.RedisError("Connection is aborted")); return; } this.connectionPool.reset(nodes); const readyHandler = () => { this.setStatus("ready"); this.retryAttempts = 0; this.executeOfflineCommands(); this.resetNodesRefreshInterval(); resolve(); }; let closeListener = undefined; const refreshListener = () => { this.invokeReadyDelayedCallbacks(undefined); this.removeListener("close", closeListener); this.manuallyClosing = false; this.setStatus("connect"); if (this.options.enableReadyCheck) { this.readyCheck((err, fail) => { if (err || fail) { debug("Ready check failed (%s). Reconnecting...", err || fail); if (this.status === "connect") { this.disconnect(true); } } else { readyHandler(); } }); } else { readyHandler(); } }; closeListener = () => { const error = new Error("None of startup nodes is available"); this.removeListener("refresh", refreshListener); this.invokeReadyDelayedCallbacks(error); reject(error); }; this.once("refresh", refreshListener); this.once("close", closeListener); this.once("close", this.handleCloseEvent.bind(this)); this.refreshSlotsCache((err) => { if (err && err.message === ClusterAllFailedError_1.default.defaultMessage) { Redis_1.default.prototype.silentEmit.call(this, "error", err); this.connectionPool.reset([]); } }); this.subscriber.start(); }) .catch((err) => { this.setStatus("close"); this.handleCloseEvent(err); this.invokeReadyDelayedCallbacks(err); reject(err); }); }); } /** * Disconnect from every node in the cluster. */ disconnect(reconnect = false) { const status = this.status; this.setStatus("disconnecting"); if (!reconnect) { this.manuallyClosing = true; } if (this.reconnectTimeout && !reconnect) { clearTimeout(this.reconnectTimeout); this.reconnectTimeout = null; debug("Canceled reconnecting attempts"); } this.clearNodesRefreshInterval(); this.subscriber.stop(); if (status === "wait") { this.setStatus("close"); this.handleCloseEvent(); } else { this.connectionPool.reset([]); } } /** * Quit the cluster gracefully. */ quit(callback) { const status = this.status; this.setStatus("disconnecting"); this.manuallyClosing = true; if (this.reconnectTimeout) { clearTimeout(this.reconnectTimeout); this.reconnectTimeout = null; } this.clearNodesRefreshInterval(); this.subscriber.stop(); if (status === "wait") { const ret = (0, standard_as_callback_1.default)(Promise.resolve("OK"), callback); // use setImmediate to make sure "close" event // being emitted after quit() is returned setImmediate(function () { this.setStatus("close"); this.handleCloseEvent(); }.bind(this)); return ret; } return (0, standard_as_callback_1.default)(Promise.all(this.nodes().map((node) => node.quit().catch((err) => { // Ignore the error caused by disconnecting since // we're disconnecting... if (err.message === utils_1.CONNECTION_CLOSED_ERROR_MSG) { return "OK"; } throw err; }))).then(() => "OK"), callback); } /** * Create a new instance with the same startup nodes and options as the current one. * * @example * ```js * var cluster = new Redis.Cluster([{ host: "127.0.0.1", port: "30001" }]); * var anotherCluster = cluster.duplicate(); * ``` */ duplicate(overrideStartupNodes = [], overrideOptions = {}) { const startupNodes = overrideStartupNodes.length > 0 ? overrideStartupNodes : this.startupNodes.slice(0); const options = Object.assign({}, this.options, overrideOptions); return new Cluster(startupNodes, options); } /** * Get nodes with the specified role */ nodes(role = "all") { if (role !== "all" && role !== "master" && role !== "slave") { throw new Error('Invalid role "' + role + '". Expected "all", "master" or "slave"'); } return this.connectionPool.getNodes(role); } /** * This is needed in order not to install a listener for each auto pipeline * * @ignore */ delayUntilReady(callback) { this._readyDelayedCallbacks.push(callback); } /** * Get the number of commands queued in automatic pipelines. * * This is not available (and returns 0) until the cluster is connected and slots information have been received. */ get autoPipelineQueueSize() { let queued = 0; for (const pipeline of this._autoPipelines.values()) { queued += pipeline.length; } return queued; } /** * Refresh the slot cache * * @ignore */ refreshSlotsCache(callback) { if (callback) { this._refreshSlotsCacheCallbacks.push(callback); } if (this.isRefreshing) { return; } this.isRefreshing = true; const _this = this; const wrapper = (error) => { this.isRefreshing = false; for (const callback of this._refreshSlotsCacheCallbacks) { callback(error); } this._refreshSlotsCacheCallbacks = []; }; const nodes = (0, utils_1.shuffle)(this.connectionPool.getNodes()); let lastNodeError = null; function tryNode(index) { if (index === nodes.length) { const error = new ClusterAllFailedError_1.default(ClusterAllFailedError_1.default.defaultMessage, lastNodeError); return wrapper(error); } const node = nodes[index]; const key = `${node.options.host}:${node.options.port}`; debug("getting slot cache from %s", key); _this.getInfoFromNode(node, function (err) { switch (_this.status) { case "close": case "end": return wrapper(new Error("Cluster is disconnected.")); case "disconnecting": return wrapper(new Error("Cluster is disconnecting.")); } if (err) { _this.emit("node error", err, key); lastNodeError = err; tryNode(index + 1); } else { _this.emit("refresh"); wrapper(); } }); } tryNode(0); } /** * @ignore */ sendCommand(command, stream, node) { if (this.status === "wait") { this.connect().catch(utils_1.noop); } if (this.status === "end") { command.reject(new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG)); return command.promise; } let to = this.options.scaleReads; if (to !== "master") { const isCommandReadOnly = command.isReadOnly || ((0, commands_1.exists)(command.name) && (0, commands_1.hasFlag)(command.name, "readonly")); if (!isCommandReadOnly) { to = "master"; } } let targetSlot = node ? node.slot : command.getSlot(); const ttl = {}; const _this = this; if (!node && !REJECT_OVERWRITTEN_COMMANDS.has(command)) { REJECT_OVERWRITTEN_COMMANDS.add(command); const reject = command.reject; command.reject = function (err) { const partialTry = tryConnection.bind(null, true); _this.handleError(err, ttl, { moved: function (slot, key) { debug("command %s is moved to %s", command.name, key); targetSlot = Number(slot); if (_this.slots[slot]) { _this.slots[slot][0] = key; } else { _this.slots[slot] = [key]; } _this._groupsBySlot[slot] = _this._groupsIds[_this.slots[slot].join(";")]; _this.connectionPool.findOrCreate(_this.natMapper(key)); tryConnection(); debug("refreshing slot caches... (triggered by MOVED error)"); _this.refreshSlotsCache(); }, ask: function (slot, key) { debug("command %s is required to ask %s:%s", command.name, key); const mapped = _this.natMapper(key); _this.connectionPool.findOrCreate(mapped); tryConnection(false, `${mapped.host}:${mapped.port}`); }, tryagain: partialTry, clusterDown: partialTry, connectionClosed: partialTry, maxRedirections: function (redirectionError) { reject.call(command, redirectionError); }, defaults: function () { reject.call(command, err); }, }); }; } tryConnection(); function tryConnection(random, asking) { if (_this.status === "end") { command.reject(new redis_errors_1.AbortError("Cluster is ended.")); return; } let redis; if (_this.status === "ready" || command.name === "cluster") { if (node && node.redis) { redis = node.redis; } else if (Command_1.default.checkFlag("ENTER_SUBSCRIBER_MODE", command.name) || Command_1.default.checkFlag("EXIT_SUBSCRIBER_MODE", command.name)) { redis = _this.subscriber.getInstance(); if (!redis) { command.reject(new redis_errors_1.AbortError("No subscriber for the cluster")); return; } } else { if (!random) { if (typeof targetSlot === "number" && _this.slots[targetSlot]) { const nodeKeys = _this.slots[targetSlot]; if (typeof to === "function") { const nodes = nodeKeys.map(function (key) { return _this.connectionPool.getInstanceByKey(key); }); redis = to(nodes, command); if (Array.isArray(redis)) { redis = (0, utils_1.sample)(redis); } if (!redis) { redis = nodes[0]; } } else { let key; if (to === "all") { key = (0, utils_1.sample)(nodeKeys); } else if (to === "slave" && nodeKeys.length > 1) { key = (0, utils_1.sample)(nodeKeys, 1); } else { key = nodeKeys[0]; } redis = _this.connectionPool.getInstanceByKey(key); } } if (asking) { redis = _this.connectionPool.getInstanceByKey(asking); redis.asking(); } } if (!redis) { redis = (typeof to === "function" ? null : _this.connectionPool.getSampleInstance(to)) || _this.connectionPool.getSampleInstance("all"); } } if (node && !node.redis) { node.redis = redis; } } if (redis) { redis.sendCommand(command, stream); } else if (_this.options.enableOfflineQueue) { _this.offlineQueue.push({ command: command, stream: stream, node: node, }); } else { command.reject(new Error("Cluster isn't ready and enableOfflineQueue options is false")); } } return command.promise; } sscanStream(key, options) { return this.createScanStream("sscan", { key, options }); } sscanBufferStream(key, options) { return this.createScanStream("sscanBuffer", { key, options }); } hscanStream(key, options) { return this.createScanStream("hscan", { key, options }); } hscanBufferStream(key, options) { return this.createScanStream("hscanBuffer", { key, options }); } zscanStream(key, options) { return this.createScanStream("zscan", { key, options }); } zscanBufferStream(key, options) { return this.createScanStream("zscanBuffer", { key, options }); } /** * @ignore */ handleError(error, ttl, handlers) { if (typeof ttl.value === "undefined") { ttl.value = this.options.maxRedirections; } else { ttl.value -= 1; } if (ttl.value <= 0) { handlers.maxRedirections(new Error("Too many Cluster redirections. Last error: " + error)); return; } const errv = error.message.split(" "); if (errv[0] === "MOVED") { const timeout = this.options.retryDelayOnMoved; if (timeout && typeof timeout === "number") { this.delayQueue.push("moved", handlers.moved.bind(null, errv[1], errv[2]), { timeout }); } else { handlers.moved(errv[1], errv[2]); } } else if (errv[0] === "ASK") { handlers.ask(errv[1], errv[2]); } else if (errv[0] === "TRYAGAIN") { this.delayQueue.push("tryagain", handlers.tryagain, { timeout: this.options.retryDelayOnTryAgain, }); } else if (errv[0] === "CLUSTERDOWN" && this.options.retryDelayOnClusterDown > 0) { this.delayQueue.push("clusterdown", handlers.connectionClosed, { timeout: this.options.retryDelayOnClusterDown, callback: this.refreshSlotsCache.bind(this), }); } else if (error.message === utils_1.CONNECTION_CLOSED_ERROR_MSG && this.options.retryDelayOnFailover > 0 && this.status === "ready") { this.delayQueue.push("failover", handlers.connectionClosed, { timeout: this.options.retryDelayOnFailover, callback: this.refreshSlotsCache.bind(this), }); } else { handlers.defaults(); } } resetOfflineQueue() { this.offlineQueue = new Deque(); } clearNodesRefreshInterval() { if (this.slotsTimer) { clearTimeout(this.slotsTimer); this.slotsTimer = null; } } resetNodesRefreshInterval() { if (this.slotsTimer || !this.options.slotsRefreshInterval) { return; } const nextRound = () => { this.slotsTimer = setTimeout(() => { debug('refreshing slot caches... (triggered by "slotsRefreshInterval" option)'); this.refreshSlotsCache(() => { nextRound(); }); }, this.options.slotsRefreshInterval); }; nextRound(); } /** * Change cluster instance's status */ setStatus(status) { debug("status: %s -> %s", this.status || "[empty]", status); this.status = status; process.nextTick(() => { this.emit(status); }); } /** * Called when closed to check whether a reconnection should be made */ handleCloseEvent(reason) { if (reason) { debug("closed because %s", reason); } let retryDelay; if (!this.manuallyClosing && typeof this.options.clusterRetryStrategy === "function") { retryDelay = this.options.clusterRetryStrategy.call(this, ++this.retryAttempts, reason); } if (typeof retryDelay === "number") { this.setStatus("reconnecting"); this.reconnectTimeout = setTimeout(() => { this.reconnectTimeout = null; debug("Cluster is disconnected. Retrying after %dms", retryDelay); this.connect().catch(function (err) { debug("Got error %s when reconnecting. Ignoring...", err); }); }, retryDelay); } else { this.setStatus("end"); this.flushQueue(new Error("None of startup nodes is available")); } } /** * Flush offline queue with error. */ flushQueue(error) { let item; while ((item = this.offlineQueue.shift())) { item.command.reject(error); } } executeOfflineCommands() { if (this.offlineQueue.length) { debug("send %d commands in offline queue", this.offlineQueue.length); const offlineQueue = this.offlineQueue; this.resetOfflineQueue(); let item; while ((item = offlineQueue.shift())) { this.sendCommand(item.command, item.stream, item.node); } } } natMapper(nodeKey) { if (this.options.natMap && typeof this.options.natMap === "object") { const key = typeof nodeKey === "string" ? nodeKey : `${nodeKey.host}:${nodeKey.port}`; const mapped = this.options.natMap[key]; if (mapped) { debug("NAT mapping %s -> %O", key, mapped); return Object.assign({}, mapped); } } return typeof nodeKey === "string" ? (0, util_1.nodeKeyToRedisOptions)(nodeKey) : nodeKey; } getInfoFromNode(redis, callback) { if (!redis) { return callback(new Error("Node is disconnected")); } // Use a duplication of the connection to avoid // timeouts when the connection is in the blocking // mode (e.g. waiting for BLPOP). const duplicatedConnection = redis.duplicate({ enableOfflineQueue: true, enableReadyCheck: false, retryStrategy: null, connectionName: (0, util_1.getConnectionName)("refresher", this.options.redisOptions && this.options.redisOptions.connectionName), }); // Ignore error events since we will handle // exceptions for the CLUSTER SLOTS command. duplicatedConnection.on("error", utils_1.noop); duplicatedConnection.cluster("SLOTS", (0, utils_1.timeout)((err, result) => { duplicatedConnection.disconnect(); if (err) { return callback(err); } if (this.status === "disconnecting" || this.status === "close" || this.status === "end") { debug("ignore CLUSTER.SLOTS results (count: %d) since cluster status is %s", result.length, this.status); callback(); return; } const nodes = []; debug("cluster slots result count: %d", result.length); for (let i = 0; i < result.length; ++i) { const items = result[i]; const slotRangeStart = items[0]; const slotRangeEnd = items[1]; const keys = []; for (let j = 2; j < items.length; j++) { if (!items[j][0]) { continue; } const node = this.natMapper({ host: items[j][0], port: items[j][1], }); node.readOnly = j !== 2; nodes.push(node); keys.push(node.host + ":" + node.port); } debug("cluster slots result [%d]: slots %d~%d served by %s", i, slotRangeStart, slotRangeEnd, keys); for (let slot = slotRangeStart; slot <= slotRangeEnd; slot++) { this.slots[slot] = keys; } } // Assign to each node keys a numeric value to make autopipeline comparison faster. this._groupsIds = Object.create(null); let j = 0; for (let i = 0; i < 16384; i++) { const target = (this.slots[i] || []).join(";"); if (!target.length) { this._groupsBySlot[i] = undefined; continue; } if (!this._groupsIds[target]) { this._groupsIds[target] = ++j; } this._groupsBySlot[i] = this._groupsIds[target]; } this.connectionPool.reset(nodes); callback(); }, this.options.slotsRefreshTimeout)); } invokeReadyDelayedCallbacks(err) { for (const c of this._readyDelayedCallbacks) { process.nextTick(c, err); } this._readyDelayedCallbacks = []; } /** * Check whether Cluster is able to process commands */ readyCheck(callback) { this.cluster("INFO", (err, res) => { if (err) { return callback(err); } if (typeof res !== "string") { return callback(); } let state; const lines = res.split("\r\n"); for (let i = 0; i < lines.length; ++i) { const parts = lines[i].split(":"); if (parts[0] === "cluster_state") { state = parts[1]; break; } } if (state === "fail") { debug("cluster state not ok (%s)", state); callback(null, state); } else { callback(); } }); } resolveSrv(hostname) { return new Promise((resolve, reject) => { this.options.resolveSrv(hostname, (err, records) => { if (err) { return reject(err); } const self = this, groupedRecords = (0, util_1.groupSrvRecords)(records), sortedKeys = Object.keys(groupedRecords).sort((a, b) => parseInt(a) - parseInt(b)); function tryFirstOne(err) { if (!sortedKeys.length) { return reject(err); } const key = sortedKeys[0], group = groupedRecords[key], record = (0, util_1.weightSrvRecords)(group); if (!group.records.length) { sortedKeys.shift(); } self.dnsLookup(record.name).then((host) => resolve({ host, port: record.port, }), tryFirstOne); } tryFirstOne(); }); }); } dnsLookup(hostname) { return new Promise((resolve, reject) => { this.options.dnsLookup(hostname, (err, address) => { if (err) { debug("failed to resolve hostname %s to IP: %s", hostname, err.message); reject(err); } else { debug("resolved hostname %s to IP %s", hostname, address); resolve(address); } }); }); } /** * Normalize startup nodes, and resolving hostnames to IPs. * * This process happens every time when #connect() is called since * #startupNodes and DNS records may chanage. */ async resolveStartupNodeHostnames() { if (!Array.isArray(this.startupNodes) || this.startupNodes.length === 0) { throw new Error("`startupNodes` should contain at least one node."); } const startupNodes = (0, util_1.normalizeNodeOptions)(this.startupNodes); const hostnames = (0, util_1.getUniqueHostnamesFromOptions)(startupNodes); if (hostnames.length === 0) { return startupNodes; } const configs = await Promise.all(hostnames.map((this.options.useSRVRecords ? this.resolveSrv : this.dnsLookup).bind(this))); const hostnameToConfig = (0, utils_1.zipMap)(hostnames, configs); return startupNodes.map((node) => { const config = hostnameToConfig.get(node.host); if (!config) { return node; } if (this.options.useSRVRecords) { return Object.assign({}, node, config); } return Object.assign({}, node, { host: config }); }); } createScanStream(command, { key, options = {} }) { return new ScanStream_1.default({ objectMode: true, key: key, redis: this, command: command, ...options, }); } } (0, applyMixin_1.default)(Cluster, events_1.EventEmitter); (0, transaction_1.addTransactionSupport)(Cluster.prototype); cluster.default = Cluster; return cluster; } var connectors = {}; var StandaloneConnector$1 = {}; var AbstractConnector$1 = {}; Object.defineProperty(AbstractConnector$1, "__esModule", { value: true }); const utils_1$3 = utils; const debug$2 = (0, utils_1$3.Debug)("AbstractConnector"); class AbstractConnector { constructor(disconnectTimeout) { this.connecting = false; this.disconnectTimeout = disconnectTimeout; } check(info) { return true; } disconnect() { this.connecting = false; if (this.stream) { const stream = this.stream; // Make sure callbacks refer to the same instance const timeout = setTimeout(() => { debug$2("stream %s:%s still open, destroying it", stream.remoteAddress, stream.remotePort); stream.destroy(); }, this.disconnectTimeout); stream.on("close", () => clearTimeout(timeout)); stream.end(); } } } AbstractConnector$1.default = AbstractConnector; Object.defineProperty(StandaloneConnector$1, "__esModule", { value: true }); const net_1 = require$$0$9; const tls_1 = require$$1$6; const utils_1$2 = utils; const AbstractConnector_1 = AbstractConnector$1; class StandaloneConnector extends AbstractConnector_1.default { constructor(options) { super(options.disconnectTimeout); this.options = options; } connect(_) { const { options } = this; this.connecting = true; let connectionOptions; if ("path" in options && options.path) { connectionOptions = { path: options.path, }; } else { connectionOptions = {}; if ("port" in options && options.port != null) { connectionOptions.port = options.port; } if ("host" in options && options.host != null) { connectionOptions.host = options.host; } if ("family" in options && options.family != null) { connectionOptions.family = options.family; } } if (options.tls) { Object.assign(connectionOptions, options.tls); } // TODO: // We use native Promise here since other Promise // implementation may use different schedulers that // cause issue when the stream is resolved in the // next tick. // Should use the provided promise in the next major // version and do not connect before resolved. return new Promise((resolve, reject) => { process.nextTick(() => { if (!this.connecting) { reject(new Error(utils_1$2.CONNECTION_CLOSED_ERROR_MSG)); return; } try { if (options.tls) { this.stream = (0, tls_1.connect)(connectionOptions); } else { this.stream = (0, net_1.createConnection)(connectionOptions); } } catch (err) { reject(err); return; } this.stream.once("error", (err) => { this.firstError = err; }); resolve(this.stream); }); }); } } StandaloneConnector$1.default = StandaloneConnector; var SentinelConnector = {}; var SentinelIterator$1 = {}; Object.defineProperty(SentinelIterator$1, "__esModule", { value: true }); function isSentinelEql(a, b) { return ((a.host || "127.0.0.1") === (b.host || "127.0.0.1") && (a.port || 26379) === (b.port || 26379)); } class SentinelIterator { constructor(sentinels) { this.cursor = 0; this.sentinels = sentinels.slice(0); } next() { const done = this.cursor >= this.sentinels.length; return { done, value: done ? undefined : this.sentinels[this.cursor++] }; } reset(moveCurrentEndpointToFirst) { if (moveCurrentEndpointToFirst && this.sentinels.length > 1 && this.cursor !== 1) { this.sentinels.unshift(...this.sentinels.splice(this.cursor - 1)); } this.cursor = 0; } add(sentinel) { for (let i = 0; i < this.sentinels.length; i++) { if (isSentinelEql(sentinel, this.sentinels[i])) { return false; } } this.sentinels.push(sentinel); return true; } toString() { return `${JSON.stringify(this.sentinels)} @${this.cursor}`; } } SentinelIterator$1.default = SentinelIterator; var FailoverDetector$1 = {}; Object.defineProperty(FailoverDetector$1, "__esModule", { value: true }); FailoverDetector$1.FailoverDetector = void 0; const utils_1$1 = utils; const debug$1 = (0, utils_1$1.Debug)("FailoverDetector"); const CHANNEL_NAME = "+switch-master"; class FailoverDetector { // sentinels can't be used for regular commands after this constructor(connector, sentinels) { this.isDisconnected = false; this.connector = connector; this.sentinels = sentinels; } cleanup() { this.isDisconnected = true; for (const sentinel of this.sentinels) { sentinel.client.disconnect(); } } async subscribe() { debug$1("Starting FailoverDetector"); const promises = []; for (const sentinel of this.sentinels) { const promise = sentinel.client.subscribe(CHANNEL_NAME).catch((err) => { debug$1("Failed to subscribe to failover messages on sentinel %s:%s (%s)", sentinel.address.host || "127.0.0.1", sentinel.address.port || 26739, err.message); }); promises.push(promise); sentinel.client.on("message", (channel) => { if (!this.isDisconnected && channel === CHANNEL_NAME) { this.disconnect(); } }); } await Promise.all(promises); } disconnect() { // Avoid disconnecting more than once per failover. // A new FailoverDetector will be created after reconnecting. this.isDisconnected = true; debug$1("Failover detected, disconnecting"); // Will call this.cleanup() this.connector.disconnect(); } } FailoverDetector$1.FailoverDetector = FailoverDetector; var hasRequiredSentinelConnector; function requireSentinelConnector () { if (hasRequiredSentinelConnector) return SentinelConnector; hasRequiredSentinelConnector = 1; Object.defineProperty(SentinelConnector, "__esModule", { value: true }); SentinelConnector.SentinelIterator = void 0; const net_1 = require$$0$9; const utils_1 = utils; const tls_1 = require$$1$6; const SentinelIterator_1 = SentinelIterator$1; SentinelConnector.SentinelIterator = SentinelIterator_1.default; const AbstractConnector_1 = AbstractConnector$1; const Redis_1 = requireRedis(); const FailoverDetector_1 = FailoverDetector$1; const debug = (0, utils_1.Debug)("SentinelConnector"); let SentinelConnector$1 = class SentinelConnector extends AbstractConnector_1.default { constructor(options) { super(options.disconnectTimeout); this.options = options; this.emitter = null; this.failoverDetector = null; if (!this.options.sentinels.length) { throw new Error("Requires at least one sentinel to connect to."); } if (!this.options.name) { throw new Error("Requires the name of master."); } this.sentinelIterator = new SentinelIterator_1.default(this.options.sentinels); } check(info) { const roleMatches = !info.role || this.options.role === info.role; if (!roleMatches) { debug("role invalid, expected %s, but got %s", this.options.role, info.role); // Start from the next item. // Note that `reset` will move the cursor to the previous element, // so we advance two steps here. this.sentinelIterator.next(); this.sentinelIterator.next(); this.sentinelIterator.reset(true); } return roleMatches; } disconnect() { super.disconnect(); if (this.failoverDetector) { this.failoverDetector.cleanup(); } } connect(eventEmitter) { this.connecting = true; this.retryAttempts = 0; let lastError; const connectToNext = async () => { const endpoint = this.sentinelIterator.next(); if (endpoint.done) { this.sentinelIterator.reset(false); const retryDelay = typeof this.options.sentinelRetryStrategy === "function" ? this.options.sentinelRetryStrategy(++this.retryAttempts) : null; let errorMsg = typeof retryDelay !== "number" ? "All sentinels are unreachable and retry is disabled." : `All sentinels are unreachable. Retrying from scratch after ${retryDelay}ms.`; if (lastError) { errorMsg += ` Last error: ${lastError.message}`; } debug(errorMsg); const error = new Error(errorMsg); if (typeof retryDelay === "number") { eventEmitter("error", error); await new Promise((resolve) => setTimeout(resolve, retryDelay)); return connectToNext(); } else { throw error; } } let resolved = null; let err = null; try { resolved = await this.resolve(endpoint.value); } catch (error) { err = error; } if (!this.connecting) { throw new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG); } const endpointAddress = endpoint.value.host + ":" + endpoint.value.port; if (resolved) { debug("resolved: %s:%s from sentinel %s", resolved.host, resolved.port, endpointAddress); if (this.options.enableTLSForSentinelMode && this.options.tls) { Object.assign(resolved, this.options.tls); this.stream = (0, tls_1.connect)(resolved); this.stream.once("secureConnect", this.initFailoverDetector.bind(this)); } else { this.stream = (0, net_1.createConnection)(resolved); this.stream.once("connect", this.initFailoverDetector.bind(this)); } this.stream.once("error", (err) => { this.firstError = err; }); return this.stream; } else { const errorMsg = err ? "failed to connect to sentinel " + endpointAddress + " because " + err.message : "connected to sentinel " + endpointAddress + " successfully, but got an invalid reply: " + resolved; debug(errorMsg); eventEmitter("sentinelError", new Error(errorMsg)); if (err) { lastError = err; } return connectToNext(); } }; return connectToNext(); } async updateSentinels(client) { if (!this.options.updateSentinels) { return; } const result = await client.sentinel("sentinels", this.options.name); if (!Array.isArray(result)) { return; } result .map(utils_1.packObject) .forEach((sentinel) => { const flags = sentinel.flags ? sentinel.flags.split(",") : []; if (flags.indexOf("disconnected") === -1 && sentinel.ip && sentinel.port) { const endpoint = this.sentinelNatResolve(addressResponseToAddress(sentinel)); if (this.sentinelIterator.add(endpoint)) { debug("adding sentinel %s:%s", endpoint.host, endpoint.port); } } }); debug("Updated internal sentinels: %s", this.sentinelIterator); } async resolveMaster(client) { const result = await client.sentinel("get-master-addr-by-name", this.options.name); await this.updateSentinels(client); return this.sentinelNatResolve(Array.isArray(result) ? { host: result[0], port: Number(result[1]) } : null); } async resolveSlave(client) { const result = await client.sentinel("slaves", this.options.name); if (!Array.isArray(result)) { return null; } const availableSlaves = result .map(utils_1.packObject) .filter((slave) => slave.flags && !slave.flags.match(/(disconnected|s_down|o_down)/)); return this.sentinelNatResolve(selectPreferredSentinel(availableSlaves, this.options.preferredSlaves)); } sentinelNatResolve(item) { if (!item || !this.options.natMap) return item; return this.options.natMap[`${item.host}:${item.port}`] || item; } connectToSentinel(endpoint, options) { const redis = new Redis_1.default({ port: endpoint.port || 26379, host: endpoint.host, username: this.options.sentinelUsername || null, password: this.options.sentinelPassword || null, family: endpoint.family || // @ts-expect-error ("path" in this.options && this.options.path ? undefined : // @ts-expect-error this.options.family), tls: this.options.sentinelTLS, retryStrategy: null, enableReadyCheck: false, connectTimeout: this.options.connectTimeout, commandTimeout: this.options.sentinelCommandTimeout, ...options, }); // @ts-expect-error return redis; } async resolve(endpoint) { const client = this.connectToSentinel(endpoint); // ignore the errors since resolve* methods will handle them client.on("error", noop); try { if (this.options.role === "slave") { return await this.resolveSlave(client); } else { return await this.resolveMaster(client); } } finally { client.disconnect(); } } async initFailoverDetector() { var _a; if (!this.options.failoverDetector) { return; } // Move the current sentinel to the first position this.sentinelIterator.reset(true); const sentinels = []; // In case of a large amount of sentinels, limit the number of concurrent connections while (sentinels.length < this.options.sentinelMaxConnections) { const { done, value } = this.sentinelIterator.next(); if (done) { break; } const client = this.connectToSentinel(value, { lazyConnect: true, retryStrategy: this.options.sentinelReconnectStrategy, }); client.on("reconnecting", () => { var _a; // Tests listen to this event (_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit("sentinelReconnecting"); }); sentinels.push({ address: value, client }); } this.sentinelIterator.reset(false); if (this.failoverDetector) { // Clean up previous detector this.failoverDetector.cleanup(); } this.failoverDetector = new FailoverDetector_1.FailoverDetector(this, sentinels); await this.failoverDetector.subscribe(); // Tests listen to this event (_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit("failoverSubscribed"); } }; SentinelConnector.default = SentinelConnector$1; function selectPreferredSentinel(availableSlaves, preferredSlaves) { if (availableSlaves.length === 0) { return null; } let selectedSlave; if (typeof preferredSlaves === "function") { selectedSlave = preferredSlaves(availableSlaves); } else if (preferredSlaves !== null && typeof preferredSlaves === "object") { const preferredSlavesArray = Array.isArray(preferredSlaves) ? preferredSlaves : [preferredSlaves]; // sort by priority preferredSlavesArray.sort((a, b) => { // default the priority to 1 if (!a.prio) { a.prio = 1; } if (!b.prio) { b.prio = 1; } // lowest priority first if (a.prio < b.prio) { return -1; } if (a.prio > b.prio) { return 1; } return 0; }); // loop over preferred slaves and return the first match for (let p = 0; p < preferredSlavesArray.length; p++) { for (let a = 0; a < availableSlaves.length; a++) { const slave = availableSlaves[a]; if (slave.ip === preferredSlavesArray[p].ip) { if (slave.port === preferredSlavesArray[p].port) { selectedSlave = slave; break; } } } if (selectedSlave) { break; } } } // if none of the preferred slaves are available, a random available slave is returned if (!selectedSlave) { selectedSlave = (0, utils_1.sample)(availableSlaves); } return addressResponseToAddress(selectedSlave); } function addressResponseToAddress(input) { return { host: input.ip, port: Number(input.port) }; } function noop() { } return SentinelConnector; } var hasRequiredConnectors; function requireConnectors () { if (hasRequiredConnectors) return connectors; hasRequiredConnectors = 1; Object.defineProperty(connectors, "__esModule", { value: true }); connectors.SentinelConnector = connectors.StandaloneConnector = void 0; const StandaloneConnector_1 = StandaloneConnector$1; connectors.StandaloneConnector = StandaloneConnector_1.default; const SentinelConnector_1 = requireSentinelConnector(); connectors.SentinelConnector = SentinelConnector_1.default; return connectors; } var event_handler = {}; var errors$1 = {}; var MaxRetriesPerRequestError$1 = {}; Object.defineProperty(MaxRetriesPerRequestError$1, "__esModule", { value: true }); const redis_errors_1 = redisErrors; class MaxRetriesPerRequestError extends redis_errors_1.AbortError { constructor(maxRetriesPerRequest) { const message = `Reached the max retries per request limit (which is ${maxRetriesPerRequest}). Refer to "maxRetriesPerRequest" option for details.`; super(message); Error.captureStackTrace(this, this.constructor); } get name() { return this.constructor.name; } } MaxRetriesPerRequestError$1.default = MaxRetriesPerRequestError; Object.defineProperty(errors$1, "__esModule", { value: true }); errors$1.MaxRetriesPerRequestError = void 0; const MaxRetriesPerRequestError_1 = MaxRetriesPerRequestError$1; errors$1.MaxRetriesPerRequestError = MaxRetriesPerRequestError_1.default; var DataHandler$1 = {}; const Buffer$1 = require$$0$4.Buffer; const StringDecoder = require$$1$7.StringDecoder; const decoder = new StringDecoder(); const errors = redisErrors; const ReplyError = errors.ReplyError; const ParserError = errors.ParserError; var bufferPool = Buffer$1.allocUnsafe(32 * 1024); var bufferOffset = 0; var interval = null; var counter = 0; var notDecreased = 0; /** * Used for integer numbers only * @param {JavascriptRedisParser} parser * @returns {undefined|number} */ function parseSimpleNumbers (parser) { const length = parser.buffer.length - 1; var offset = parser.offset; var number = 0; var sign = 1; if (parser.buffer[offset] === 45) { sign = -1; offset++; } while (offset < length) { const c1 = parser.buffer[offset++]; if (c1 === 13) { // \r\n parser.offset = offset + 1; return sign * number } number = (number * 10) + (c1 - 48); } } /** * Used for integer numbers in case of the returnNumbers option * * Reading the string as parts of n SMI is more efficient than * using a string directly. * * @param {JavascriptRedisParser} parser * @returns {undefined|string} */ function parseStringNumbers (parser) { const length = parser.buffer.length - 1; var offset = parser.offset; var number = 0; var res = ''; if (parser.buffer[offset] === 45) { res += '-'; offset++; } while (offset < length) { var c1 = parser.buffer[offset++]; if (c1 === 13) { // \r\n parser.offset = offset + 1; if (number !== 0) { res += number; } return res } else if (number > 429496728) { res += (number * 10) + (c1 - 48); number = 0; } else if (c1 === 48 && number === 0) { res += 0; } else { number = (number * 10) + (c1 - 48); } } } /** * Parse a '+' redis simple string response but forward the offsets * onto convertBufferRange to generate a string. * @param {JavascriptRedisParser} parser * @returns {undefined|string|Buffer} */ function parseSimpleString (parser) { const start = parser.offset; const buffer = parser.buffer; const length = buffer.length - 1; var offset = start; while (offset < length) { if (buffer[offset++] === 13) { // \r\n parser.offset = offset + 1; if (parser.optionReturnBuffers === true) { return parser.buffer.slice(start, offset - 1) } return parser.buffer.toString('utf8', start, offset - 1) } } } /** * Returns the read length * @param {JavascriptRedisParser} parser * @returns {undefined|number} */ function parseLength (parser) { const length = parser.buffer.length - 1; var offset = parser.offset; var number = 0; while (offset < length) { const c1 = parser.buffer[offset++]; if (c1 === 13) { parser.offset = offset + 1; return number } number = (number * 10) + (c1 - 48); } } /** * Parse a ':' redis integer response * * If stringNumbers is activated the parser always returns numbers as string * This is important for big numbers (number > Math.pow(2, 53)) as js numbers * are 64bit floating point numbers with reduced precision * * @param {JavascriptRedisParser} parser * @returns {undefined|number|string} */ function parseInteger (parser) { if (parser.optionStringNumbers === true) { return parseStringNumbers(parser) } return parseSimpleNumbers(parser) } /** * Parse a '$' redis bulk string response * @param {JavascriptRedisParser} parser * @returns {undefined|null|string} */ function parseBulkString (parser) { const length = parseLength(parser); if (length === undefined) { return } if (length < 0) { return null } const offset = parser.offset + length; if (offset + 2 > parser.buffer.length) { parser.bigStrSize = offset + 2; parser.totalChunkSize = parser.buffer.length; parser.bufferCache.push(parser.buffer); return } const start = parser.offset; parser.offset = offset + 2; if (parser.optionReturnBuffers === true) { return parser.buffer.slice(start, offset) } return parser.buffer.toString('utf8', start, offset) } /** * Parse a '-' redis error response * @param {JavascriptRedisParser} parser * @returns {ReplyError} */ function parseError (parser) { var string = parseSimpleString(parser); if (string !== undefined) { if (parser.optionReturnBuffers === true) { string = string.toString(); } return new ReplyError(string) } } /** * Parsing error handler, resets parser buffer * @param {JavascriptRedisParser} parser * @param {number} type * @returns {undefined} */ function handleError (parser, type) { const err = new ParserError( 'Protocol error, got ' + JSON.stringify(String.fromCharCode(type)) + ' as reply type byte', JSON.stringify(parser.buffer), parser.offset ); parser.buffer = null; parser.returnFatalError(err); } /** * Parse a '*' redis array response * @param {JavascriptRedisParser} parser * @returns {undefined|null|any[]} */ function parseArray (parser) { const length = parseLength(parser); if (length === undefined) { return } if (length < 0) { return null } const responses = new Array(length); return parseArrayElements(parser, responses, 0) } /** * Push a partly parsed array to the stack * * @param {JavascriptRedisParser} parser * @param {any[]} array * @param {number} pos * @returns {undefined} */ function pushArrayCache (parser, array, pos) { parser.arrayCache.push(array); parser.arrayPos.push(pos); } /** * Parse chunked redis array response * @param {JavascriptRedisParser} parser * @returns {undefined|any[]} */ function parseArrayChunks (parser) { const tmp = parser.arrayCache.pop(); var pos = parser.arrayPos.pop(); if (parser.arrayCache.length) { const res = parseArrayChunks(parser); if (res === undefined) { pushArrayCache(parser, tmp, pos); return } tmp[pos++] = res; } return parseArrayElements(parser, tmp, pos) } /** * Parse redis array response elements * @param {JavascriptRedisParser} parser * @param {Array} responses * @param {number} i * @returns {undefined|null|any[]} */ function parseArrayElements (parser, responses, i) { const bufferLength = parser.buffer.length; while (i < responses.length) { const offset = parser.offset; if (parser.offset >= bufferLength) { pushArrayCache(parser, responses, i); return } const response = parseType(parser, parser.buffer[parser.offset++]); if (response === undefined) { if (!(parser.arrayCache.length || parser.bufferCache.length)) { parser.offset = offset; } pushArrayCache(parser, responses, i); return } responses[i] = response; i++; } return responses } /** * Called the appropriate parser for the specified type. * * 36: $ * 43: + * 42: * * 58: : * 45: - * * @param {JavascriptRedisParser} parser * @param {number} type * @returns {*} */ function parseType (parser, type) { switch (type) { case 36: return parseBulkString(parser) case 43: return parseSimpleString(parser) case 42: return parseArray(parser) case 58: return parseInteger(parser) case 45: return parseError(parser) default: return handleError(parser, type) } } /** * Decrease the bufferPool size over time * * Balance between increasing and decreasing the bufferPool. * Decrease the bufferPool by 10% by removing the first 10% of the current pool. * @returns {undefined} */ function decreaseBufferPool () { if (bufferPool.length > 50 * 1024) { if (counter === 1 || notDecreased > counter * 2) { const minSliceLen = Math.floor(bufferPool.length / 10); const sliceLength = minSliceLen < bufferOffset ? bufferOffset : minSliceLen; bufferOffset = 0; bufferPool = bufferPool.slice(sliceLength, bufferPool.length); } else { notDecreased++; counter--; } } else { clearInterval(interval); counter = 0; notDecreased = 0; interval = null; } } /** * Check if the requested size fits in the current bufferPool. * If it does not, reset and increase the bufferPool accordingly. * * @param {number} length * @returns {undefined} */ function resizeBuffer (length) { if (bufferPool.length < length + bufferOffset) { const multiplier = length > 1024 * 1024 * 75 ? 2 : 3; if (bufferOffset > 1024 * 1024 * 111) { bufferOffset = 1024 * 1024 * 50; } bufferPool = Buffer$1.allocUnsafe(length * multiplier + bufferOffset); bufferOffset = 0; counter++; if (interval === null) { interval = setInterval(decreaseBufferPool, 50); } } } /** * Concat a bulk string containing multiple chunks * * Notes: * 1) The first chunk might contain the whole bulk string including the \r * 2) We are only safe to fully add up elements that are neither the first nor any of the last two elements * * @param {JavascriptRedisParser} parser * @returns {String} */ function concatBulkString (parser) { const list = parser.bufferCache; const oldOffset = parser.offset; var chunks = list.length; var offset = parser.bigStrSize - parser.totalChunkSize; parser.offset = offset; if (offset <= 2) { if (chunks === 2) { return list[0].toString('utf8', oldOffset, list[0].length + offset - 2) } chunks--; offset = list[list.length - 2].length + offset; } var res = decoder.write(list[0].slice(oldOffset)); for (var i = 1; i < chunks - 1; i++) { res += decoder.write(list[i]); } res += decoder.end(list[i].slice(0, offset - 2)); return res } /** * Concat the collected chunks from parser.bufferCache. * * Increases the bufferPool size beforehand if necessary. * * @param {JavascriptRedisParser} parser * @returns {Buffer} */ function concatBulkBuffer (parser) { const list = parser.bufferCache; const oldOffset = parser.offset; const length = parser.bigStrSize - oldOffset - 2; var chunks = list.length; var offset = parser.bigStrSize - parser.totalChunkSize; parser.offset = offset; if (offset <= 2) { if (chunks === 2) { return list[0].slice(oldOffset, list[0].length + offset - 2) } chunks--; offset = list[list.length - 2].length + offset; } resizeBuffer(length); const start = bufferOffset; list[0].copy(bufferPool, start, oldOffset, list[0].length); bufferOffset += list[0].length - oldOffset; for (var i = 1; i < chunks - 1; i++) { list[i].copy(bufferPool, bufferOffset); bufferOffset += list[i].length; } list[i].copy(bufferPool, bufferOffset, 0, offset - 2); bufferOffset += offset - 2; return bufferPool.slice(start, bufferOffset) } class JavascriptRedisParser { /** * Javascript Redis Parser constructor * @param {{returnError: Function, returnReply: Function, returnFatalError?: Function, returnBuffers: boolean, stringNumbers: boolean }} options * @constructor */ constructor (options) { if (!options) { throw new TypeError('Options are mandatory.') } if (typeof options.returnError !== 'function' || typeof options.returnReply !== 'function') { throw new TypeError('The returnReply and returnError options have to be functions.') } this.setReturnBuffers(!!options.returnBuffers); this.setStringNumbers(!!options.stringNumbers); this.returnError = options.returnError; this.returnFatalError = options.returnFatalError || options.returnError; this.returnReply = options.returnReply; this.reset(); } /** * Reset the parser values to the initial state * * @returns {undefined} */ reset () { this.offset = 0; this.buffer = null; this.bigStrSize = 0; this.totalChunkSize = 0; this.bufferCache = []; this.arrayCache = []; this.arrayPos = []; } /** * Set the returnBuffers option * * @param {boolean} returnBuffers * @returns {undefined} */ setReturnBuffers (returnBuffers) { if (typeof returnBuffers !== 'boolean') { throw new TypeError('The returnBuffers argument has to be a boolean') } this.optionReturnBuffers = returnBuffers; } /** * Set the stringNumbers option * * @param {boolean} stringNumbers * @returns {undefined} */ setStringNumbers (stringNumbers) { if (typeof stringNumbers !== 'boolean') { throw new TypeError('The stringNumbers argument has to be a boolean') } this.optionStringNumbers = stringNumbers; } /** * Parse the redis buffer * @param {Buffer} buffer * @returns {undefined} */ execute (buffer) { if (this.buffer === null) { this.buffer = buffer; this.offset = 0; } else if (this.bigStrSize === 0) { const oldLength = this.buffer.length; const remainingLength = oldLength - this.offset; const newBuffer = Buffer$1.allocUnsafe(remainingLength + buffer.length); this.buffer.copy(newBuffer, 0, this.offset, oldLength); buffer.copy(newBuffer, remainingLength, 0, buffer.length); this.buffer = newBuffer; this.offset = 0; if (this.arrayCache.length) { const arr = parseArrayChunks(this); if (arr === undefined) { return } this.returnReply(arr); } } else if (this.totalChunkSize + buffer.length >= this.bigStrSize) { this.bufferCache.push(buffer); var tmp = this.optionReturnBuffers ? concatBulkBuffer(this) : concatBulkString(this); this.bigStrSize = 0; this.bufferCache = []; this.buffer = buffer; if (this.arrayCache.length) { this.arrayCache[0][this.arrayPos[0]++] = tmp; tmp = parseArrayChunks(this); if (tmp === undefined) { return } } this.returnReply(tmp); } else { this.bufferCache.push(buffer); this.totalChunkSize += buffer.length; return } while (this.offset < this.buffer.length) { const offset = this.offset; const type = this.buffer[this.offset++]; const response = parseType(this, type); if (response === undefined) { if (!(this.arrayCache.length || this.bufferCache.length)) { this.offset = offset; } return } if (type === 45) { this.returnError(response); } else { this.returnReply(response); } } this.buffer = null; } } var parser = JavascriptRedisParser; var redisParser = parser; var SubscriptionSet$1 = {}; Object.defineProperty(SubscriptionSet$1, "__esModule", { value: true }); /** * Tiny class to simplify dealing with subscription set */ class SubscriptionSet { constructor() { this.set = { subscribe: {}, psubscribe: {}, ssubscribe: {}, }; } add(set, channel) { this.set[mapSet(set)][channel] = true; } del(set, channel) { delete this.set[mapSet(set)][channel]; } channels(set) { return Object.keys(this.set[mapSet(set)]); } isEmpty() { return (this.channels("subscribe").length === 0 && this.channels("psubscribe").length === 0 && this.channels("ssubscribe").length === 0); } } SubscriptionSet$1.default = SubscriptionSet; function mapSet(set) { if (set === "unsubscribe") { return "subscribe"; } if (set === "punsubscribe") { return "psubscribe"; } if (set === "sunsubscribe") { return "ssubscribe"; } return set; } Object.defineProperty(DataHandler$1, "__esModule", { value: true }); const Command_1 = Command$1; const utils_1 = utils; const RedisParser = redisParser; const SubscriptionSet_1 = SubscriptionSet$1; const debug = (0, utils_1.Debug)("dataHandler"); class DataHandler { constructor(redis, parserOptions) { this.redis = redis; const parser = new RedisParser({ stringNumbers: parserOptions.stringNumbers, returnBuffers: true, returnError: (err) => { this.returnError(err); }, returnFatalError: (err) => { this.returnFatalError(err); }, returnReply: (reply) => { this.returnReply(reply); }, }); redis.stream.on("data", (data) => { parser.execute(data); }); } returnFatalError(err) { err.message += ". Please report this."; this.redis.recoverFromFatalError(err, err, { offlineQueue: false }); } returnError(err) { const item = this.shiftCommand(err); if (!item) { return; } err.command = { name: item.command.name, args: item.command.args, }; this.redis.handleReconnection(err, item); } returnReply(reply) { if (this.handleMonitorReply(reply)) { return; } if (this.handleSubscriberReply(reply)) { return; } const item = this.shiftCommand(reply); if (!item) { return; } if (Command_1.default.checkFlag("ENTER_SUBSCRIBER_MODE", item.command.name)) { this.redis.condition.subscriber = new SubscriptionSet_1.default(); this.redis.condition.subscriber.add(item.command.name, reply[1].toString()); if (!fillSubCommand(item.command, reply[2])) { this.redis.commandQueue.unshift(item); } } else if (Command_1.default.checkFlag("EXIT_SUBSCRIBER_MODE", item.command.name)) { if (!fillUnsubCommand(item.command, reply[2])) { this.redis.commandQueue.unshift(item); } } else { item.command.resolve(reply); } } handleSubscriberReply(reply) { if (!this.redis.condition.subscriber) { return false; } const replyType = Array.isArray(reply) ? reply[0].toString() : null; debug('receive reply "%s" in subscriber mode', replyType); switch (replyType) { case "message": if (this.redis.listeners("message").length > 0) { // Check if there're listeners to avoid unnecessary `toString()`. this.redis.emit("message", reply[1].toString(), reply[2] ? reply[2].toString() : ""); } this.redis.emit("messageBuffer", reply[1], reply[2]); break; case "pmessage": { const pattern = reply[1].toString(); if (this.redis.listeners("pmessage").length > 0) { this.redis.emit("pmessage", pattern, reply[2].toString(), reply[3].toString()); } this.redis.emit("pmessageBuffer", pattern, reply[2], reply[3]); break; } case "smessage": { if (this.redis.listeners("smessage").length > 0) { this.redis.emit("smessage", reply[1].toString(), reply[2] ? reply[2].toString() : ""); } this.redis.emit("smessageBuffer", reply[1], reply[2]); break; } case "ssubscribe": case "subscribe": case "psubscribe": { const channel = reply[1].toString(); this.redis.condition.subscriber.add(replyType, channel); const item = this.shiftCommand(reply); if (!item) { return; } if (!fillSubCommand(item.command, reply[2])) { this.redis.commandQueue.unshift(item); } break; } case "sunsubscribe": case "unsubscribe": case "punsubscribe": { const channel = reply[1] ? reply[1].toString() : null; if (channel) { this.redis.condition.subscriber.del(replyType, channel); } const count = reply[2]; if (Number(count) === 0) { this.redis.condition.subscriber = false; } const item = this.shiftCommand(reply); if (!item) { return; } if (!fillUnsubCommand(item.command, count)) { this.redis.commandQueue.unshift(item); } break; } default: { const item = this.shiftCommand(reply); if (!item) { return; } item.command.resolve(reply); } } return true; } handleMonitorReply(reply) { if (this.redis.status !== "monitoring") { return false; } const replyStr = reply.toString(); if (replyStr === "OK") { // Valid commands in the monitoring mode are AUTH and MONITOR, // both of which always reply with 'OK'. // So if we got an 'OK', we can make certain that // the reply is made to AUTH & MONITOR. return false; } // Since commands sent in the monitoring mode will trigger an exception, // any replies we received in the monitoring mode should consider to be // realtime monitor data instead of result of commands. const len = replyStr.indexOf(" "); const timestamp = replyStr.slice(0, len); const argIndex = replyStr.indexOf('"'); const args = replyStr .slice(argIndex + 1, -1) .split('" "') .map((elem) => elem.replace(/\\"/g, '"')); const dbAndSource = replyStr.slice(len + 2, argIndex - 2).split(" "); this.redis.emit("monitor", timestamp, args, dbAndSource[1], dbAndSource[0]); return true; } shiftCommand(reply) { const item = this.redis.commandQueue.shift(); if (!item) { const message = "Command queue state error. If you can reproduce this, please report it."; const error = new Error(message + (reply instanceof Error ? ` Last error: ${reply.message}` : ` Last reply: ${reply.toString()}`)); this.redis.emit("error", error); return null; } return item; } } DataHandler$1.default = DataHandler; const remainingRepliesMap = new WeakMap(); function fillSubCommand(command, count) { let remainingReplies = remainingRepliesMap.has(command) ? remainingRepliesMap.get(command) : command.args.length; remainingReplies -= 1; if (remainingReplies <= 0) { command.resolve(count); remainingRepliesMap.delete(command); return true; } remainingRepliesMap.set(command, remainingReplies); return false; } function fillUnsubCommand(command, count) { let remainingReplies = remainingRepliesMap.has(command) ? remainingRepliesMap.get(command) : command.args.length; if (remainingReplies === 0) { if (Number(count) === 0) { remainingRepliesMap.delete(command); command.resolve(count); return true; } return false; } remainingReplies -= 1; if (remainingReplies <= 0) { command.resolve(count); return true; } remainingRepliesMap.set(command, remainingReplies); return false; } (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.readyHandler = exports.errorHandler = exports.closeHandler = exports.connectHandler = void 0; const redis_errors_1 = redisErrors; const Command_1 = Command$1; const errors_1 = errors$1; const utils_1 = utils; const DataHandler_1 = DataHandler$1; const debug = (0, utils_1.Debug)("connection"); function connectHandler(self) { return function () { self.setStatus("connect"); self.resetCommandQueue(); // AUTH command should be processed before any other commands let flushed = false; const { connectionEpoch } = self; if (self.condition.auth) { self.auth(self.condition.auth, function (err) { if (connectionEpoch !== self.connectionEpoch) { return; } if (err) { if (err.message.indexOf("no password is set") !== -1) { console.warn("[WARN] Redis server does not require a password, but a password was supplied."); } else if (err.message.indexOf("without any password configured for the default user") !== -1) { console.warn("[WARN] This Redis server's `default` user does not require a password, but a password was supplied"); } else if (err.message.indexOf("wrong number of arguments for 'auth' command") !== -1) { console.warn(`[ERROR] The server returned "wrong number of arguments for 'auth' command". You are probably passing both username and password to Redis version 5 or below. You should only pass the 'password' option for Redis version 5 and under.`); } else { flushed = true; self.recoverFromFatalError(err, err); } } }); } if (self.condition.select) { self.select(self.condition.select).catch((err) => { // If the node is in cluster mode, select is disallowed. // In this case, reconnect won't help. self.silentEmit("error", err); }); } if (!self.options.enableReadyCheck) { exports.readyHandler(self)(); } /* No need to keep the reference of DataHandler here because we don't need to do the cleanup. `Stream#end()` will remove all listeners for us. */ new DataHandler_1.default(self, { stringNumbers: self.options.stringNumbers, }); if (self.options.enableReadyCheck) { self._readyCheck(function (err, info) { if (connectionEpoch !== self.connectionEpoch) { return; } if (err) { if (!flushed) { self.recoverFromFatalError(new Error("Ready check failed: " + err.message), err); } } else { if (self.connector.check(info)) { exports.readyHandler(self)(); } else { self.disconnect(true); } } }); } }; } exports.connectHandler = connectHandler; function abortError(command) { const err = new redis_errors_1.AbortError("Command aborted due to connection close"); err.command = { name: command.name, args: command.args, }; return err; } // If a contiguous set of pipeline commands starts from index zero then they // can be safely reattempted. If however we have a chain of pipelined commands // starting at index 1 or more it means we received a partial response before // the connection close and those pipelined commands must be aborted. For // example, if the queue looks like this: [2, 3, 4, 0, 1, 2] then after // aborting and purging we'll have a queue that looks like this: [0, 1, 2] function abortIncompletePipelines(commandQueue) { var _a; let expectedIndex = 0; for (let i = 0; i < commandQueue.length;) { const command = (_a = commandQueue.peekAt(i)) === null || _a === void 0 ? void 0 : _a.command; const pipelineIndex = command.pipelineIndex; if (pipelineIndex === undefined || pipelineIndex === 0) { expectedIndex = 0; } if (pipelineIndex !== undefined && pipelineIndex !== expectedIndex++) { commandQueue.remove(i, 1); command.reject(abortError(command)); continue; } i++; } } // If only a partial transaction result was received before connection close, // we have to abort any transaction fragments that may have ended up in the // offline queue function abortTransactionFragments(commandQueue) { var _a; for (let i = 0; i < commandQueue.length;) { const command = (_a = commandQueue.peekAt(i)) === null || _a === void 0 ? void 0 : _a.command; if (command.name === "multi") { break; } if (command.name === "exec") { commandQueue.remove(i, 1); command.reject(abortError(command)); break; } if (command.inTransaction) { commandQueue.remove(i, 1); command.reject(abortError(command)); } else { i++; } } } function closeHandler(self) { return function () { const prevStatus = self.status; self.setStatus("close"); if (self.commandQueue.length) { abortIncompletePipelines(self.commandQueue); } if (self.offlineQueue.length) { abortTransactionFragments(self.offlineQueue); } if (prevStatus === "ready") { if (!self.prevCondition) { self.prevCondition = self.condition; } if (self.commandQueue.length) { self.prevCommandQueue = self.commandQueue; } } if (self.manuallyClosing) { self.manuallyClosing = false; debug("skip reconnecting since the connection is manually closed."); return close(); } if (typeof self.options.retryStrategy !== "function") { debug("skip reconnecting because `retryStrategy` is not a function"); return close(); } const retryDelay = self.options.retryStrategy(++self.retryAttempts); if (typeof retryDelay !== "number") { debug("skip reconnecting because `retryStrategy` doesn't return a number"); return close(); } debug("reconnect in %sms", retryDelay); self.setStatus("reconnecting", retryDelay); self.reconnectTimeout = setTimeout(function () { self.reconnectTimeout = null; self.connect().catch(utils_1.noop); }, retryDelay); const { maxRetriesPerRequest } = self.options; if (typeof maxRetriesPerRequest === "number") { if (maxRetriesPerRequest < 0) { debug("maxRetriesPerRequest is negative, ignoring..."); } else { const remainder = self.retryAttempts % (maxRetriesPerRequest + 1); if (remainder === 0) { debug("reach maxRetriesPerRequest limitation, flushing command queue..."); self.flushQueue(new errors_1.MaxRetriesPerRequestError(maxRetriesPerRequest)); } } } }; function close() { self.setStatus("end"); self.flushQueue(new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG)); } } exports.closeHandler = closeHandler; function errorHandler(self) { return function (error) { debug("error: %s", error); self.silentEmit("error", error); }; } exports.errorHandler = errorHandler; function readyHandler(self) { return function () { self.setStatus("ready"); self.retryAttempts = 0; if (self.options.monitor) { self.call("monitor").then(() => self.setStatus("monitoring"), (error) => self.emit("error", error)); const { sendCommand } = self; self.sendCommand = function (command) { if (Command_1.default.checkFlag("VALID_IN_MONITOR_MODE", command.name)) { return sendCommand.call(self, command); } command.reject(new Error("Connection is in monitoring mode, can't process commands.")); return command.promise; }; self.once("close", function () { delete self.sendCommand; }); return; } const finalSelect = self.prevCondition ? self.prevCondition.select : self.condition.select; if (self.options.connectionName) { debug("set the connection name [%s]", self.options.connectionName); self.client("setname", self.options.connectionName).catch(utils_1.noop); } if (self.options.readOnly) { debug("set the connection to readonly mode"); self.readonly().catch(utils_1.noop); } if (self.prevCondition) { const condition = self.prevCondition; self.prevCondition = null; if (condition.subscriber && self.options.autoResubscribe) { // We re-select the previous db first since // `SELECT` command is not valid in sub mode. if (self.condition.select !== finalSelect) { debug("connect to db [%d]", finalSelect); self.select(finalSelect); } const subscribeChannels = condition.subscriber.channels("subscribe"); if (subscribeChannels.length) { debug("subscribe %d channels", subscribeChannels.length); self.subscribe(subscribeChannels); } const psubscribeChannels = condition.subscriber.channels("psubscribe"); if (psubscribeChannels.length) { debug("psubscribe %d channels", psubscribeChannels.length); self.psubscribe(psubscribeChannels); } const ssubscribeChannels = condition.subscriber.channels("ssubscribe"); if (ssubscribeChannels.length) { debug("ssubscribe %d channels", ssubscribeChannels.length); self.ssubscribe(ssubscribeChannels); } } } if (self.prevCommandQueue) { if (self.options.autoResendUnfulfilledCommands) { debug("resend %d unfulfilled commands", self.prevCommandQueue.length); while (self.prevCommandQueue.length > 0) { const item = self.prevCommandQueue.shift(); if (item.select !== self.condition.select && item.command.name !== "select") { self.select(item.select); } self.sendCommand(item.command, item.stream); } } else { self.prevCommandQueue = null; } } if (self.offlineQueue.length) { debug("send %d commands in offline queue", self.offlineQueue.length); const offlineQueue = self.offlineQueue; self.resetOfflineQueue(); while (offlineQueue.length > 0) { const item = offlineQueue.shift(); if (item.select !== self.condition.select && item.command.name !== "select") { self.select(item.select); } self.sendCommand(item.command, item.stream); } } if (self.condition.select !== finalSelect) { debug("connect to db [%d]", finalSelect); self.select(finalSelect); } }; } exports.readyHandler = readyHandler; } (event_handler)); var RedisOptions = {}; Object.defineProperty(RedisOptions, "__esModule", { value: true }); RedisOptions.DEFAULT_REDIS_OPTIONS = void 0; RedisOptions.DEFAULT_REDIS_OPTIONS = { // Connection port: 6379, host: "localhost", family: 4, connectTimeout: 10000, disconnectTimeout: 2000, retryStrategy: function (times) { return Math.min(times * 50, 2000); }, keepAlive: 0, noDelay: true, connectionName: null, // Sentinel sentinels: null, name: null, role: "master", sentinelRetryStrategy: function (times) { return Math.min(times * 10, 1000); }, sentinelReconnectStrategy: function () { // This strategy only applies when sentinels are used for detecting // a failover, not during initial master resolution. // The deployment can still function when some of the sentinels are down // for a long period of time, so we may not want to attempt reconnection // very often. Therefore the default interval is fairly long (1 minute). return 60000; }, natMap: null, enableTLSForSentinelMode: false, updateSentinels: true, failoverDetector: false, // Status username: null, password: null, db: 0, // Others enableOfflineQueue: true, enableReadyCheck: true, autoResubscribe: true, autoResendUnfulfilledCommands: true, lazyConnect: false, keyPrefix: "", reconnectOnError: null, readOnly: false, stringNumbers: false, maxRetriesPerRequest: 20, maxLoadingRetryTime: 10000, enableAutoPipelining: false, autoPipeliningIgnoredCommands: [], sentinelMaxConnections: 10, }; var hasRequiredRedis; function requireRedis () { if (hasRequiredRedis) return Redis; hasRequiredRedis = 1; Object.defineProperty(Redis, "__esModule", { value: true }); const commands_1 = built$1; const events_1 = require$$1$3; const standard_as_callback_1 = built; const cluster_1 = requireCluster(); const Command_1 = Command$1; const connectors_1 = requireConnectors(); const SentinelConnector_1 = requireSentinelConnector(); const eventHandler = event_handler; const RedisOptions_1 = RedisOptions; const ScanStream_1 = ScanStream$1; const transaction_1 = transaction; const utils_1 = utils; const applyMixin_1 = applyMixin$1; const Commander_1 = Commander$1; const lodash_1 = lodash; const Deque = denque; const debug = (0, utils_1.Debug)("redis"); /** * This is the major component of ioredis. * Use it to connect to a standalone Redis server or Sentinels. * * ```typescript * const redis = new Redis(); // Default port is 6379 * async function main() { * redis.set("foo", "bar"); * redis.get("foo", (err, result) => { * // `result` should be "bar" * console.log(err, result); * }); * // Or use Promise * const result = await redis.get("foo"); * } * ``` */ let Redis$1 = class Redis extends Commander_1.default { constructor(arg1, arg2, arg3) { super(); this.status = "wait"; /** * @ignore */ this.isCluster = false; this.reconnectTimeout = null; this.connectionEpoch = 0; this.retryAttempts = 0; this.manuallyClosing = false; // Prepare autopipelines structures this._autoPipelines = new Map(); this._runningAutoPipelines = new Set(); this.parseOptions(arg1, arg2, arg3); events_1.EventEmitter.call(this); this.resetCommandQueue(); this.resetOfflineQueue(); if (this.options.Connector) { this.connector = new this.options.Connector(this.options); } else if (this.options.sentinels) { const sentinelConnector = new SentinelConnector_1.default(this.options); sentinelConnector.emitter = this; this.connector = sentinelConnector; } else { this.connector = new connectors_1.StandaloneConnector(this.options); } if (this.options.scripts) { Object.entries(this.options.scripts).forEach(([name, definition]) => { this.defineCommand(name, definition); }); } // end(or wait) -> connecting -> connect -> ready -> end if (this.options.lazyConnect) { this.setStatus("wait"); } else { this.connect().catch(lodash_1.noop); } } /** * Create a Redis instance. * This is the same as `new Redis()` but is included for compatibility with node-redis. */ static createClient(...args) { return new Redis(...args); } get autoPipelineQueueSize() { let queued = 0; for (const pipeline of this._autoPipelines.values()) { queued += pipeline.length; } return queued; } /** * Create a connection to Redis. * This method will be invoked automatically when creating a new Redis instance * unless `lazyConnect: true` is passed. * * When calling this method manually, a Promise is returned, which will * be resolved when the connection status is ready. */ connect(callback) { const promise = new Promise((resolve, reject) => { if (this.status === "connecting" || this.status === "connect" || this.status === "ready") { reject(new Error("Redis is already connecting/connected")); return; } this.connectionEpoch += 1; this.setStatus("connecting"); const { options } = this; this.condition = { select: options.db, auth: options.username ? [options.username, options.password] : options.password, subscriber: false, }; const _this = this; (0, standard_as_callback_1.default)(this.connector.connect(function (type, err) { _this.silentEmit(type, err); }), function (err, stream) { if (err) { _this.flushQueue(err); _this.silentEmit("error", err); reject(err); _this.setStatus("end"); return; } let CONNECT_EVENT = options.tls ? "secureConnect" : "connect"; if ("sentinels" in options && options.sentinels && !options.enableTLSForSentinelMode) { CONNECT_EVENT = "connect"; } _this.stream = stream; if (options.noDelay) { stream.setNoDelay(true); } // Node ignores setKeepAlive before connect, therefore we wait for the event: // https://github.com/nodejs/node/issues/31663 if (typeof options.keepAlive === "number") { if (stream.connecting) { stream.once(CONNECT_EVENT, () => { stream.setKeepAlive(true, options.keepAlive); }); } else { stream.setKeepAlive(true, options.keepAlive); } } if (stream.connecting) { stream.once(CONNECT_EVENT, eventHandler.connectHandler(_this)); if (options.connectTimeout) { /* * Typically, Socket#setTimeout(0) will clear the timer * set before. However, in some platforms (Electron 3.x~4.x), * the timer will not be cleared. So we introduce a variable here. * * See https://github.com/electron/electron/issues/14915 */ let connectTimeoutCleared = false; stream.setTimeout(options.connectTimeout, function () { if (connectTimeoutCleared) { return; } stream.setTimeout(0); stream.destroy(); const err = new Error("connect ETIMEDOUT"); // @ts-expect-error err.errorno = "ETIMEDOUT"; // @ts-expect-error err.code = "ETIMEDOUT"; // @ts-expect-error err.syscall = "connect"; eventHandler.errorHandler(_this)(err); }); stream.once(CONNECT_EVENT, function () { connectTimeoutCleared = true; stream.setTimeout(0); }); } } else if (stream.destroyed) { const firstError = _this.connector.firstError; if (firstError) { process.nextTick(() => { eventHandler.errorHandler(_this)(firstError); }); } process.nextTick(eventHandler.closeHandler(_this)); } else { process.nextTick(eventHandler.connectHandler(_this)); } if (!stream.destroyed) { stream.once("error", eventHandler.errorHandler(_this)); stream.once("close", eventHandler.closeHandler(_this)); } const connectionReadyHandler = function () { _this.removeListener("close", connectionCloseHandler); resolve(); }; var connectionCloseHandler = function () { _this.removeListener("ready", connectionReadyHandler); reject(new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG)); }; _this.once("ready", connectionReadyHandler); _this.once("close", connectionCloseHandler); }); }); return (0, standard_as_callback_1.default)(promise, callback); } /** * Disconnect from Redis. * * This method closes the connection immediately, * and may lose some pending replies that haven't written to client. * If you want to wait for the pending replies, use Redis#quit instead. */ disconnect(reconnect = false) { if (!reconnect) { this.manuallyClosing = true; } if (this.reconnectTimeout && !reconnect) { clearTimeout(this.reconnectTimeout); this.reconnectTimeout = null; } if (this.status === "wait") { eventHandler.closeHandler(this)(); } else { this.connector.disconnect(); } } /** * Disconnect from Redis. * * @deprecated */ end() { this.disconnect(); } /** * Create a new instance with the same options as the current one. * * @example * ```js * var redis = new Redis(6380); * var anotherRedis = redis.duplicate(); * ``` */ duplicate(override) { return new Redis({ ...this.options, ...override }); } /** * Mode of the connection. * * One of `"normal"`, `"subscriber"`, or `"monitor"`. When the connection is * not in `"normal"` mode, certain commands are not allowed. */ get mode() { var _a; return this.options.monitor ? "monitor" : ((_a = this.condition) === null || _a === void 0 ? void 0 : _a.subscriber) ? "subscriber" : "normal"; } /** * Listen for all requests received by the server in real time. * * This command will create a new connection to Redis and send a * MONITOR command via the new connection in order to avoid disturbing * the current connection. * * @param callback The callback function. If omit, a promise will be returned. * @example * ```js * var redis = new Redis(); * redis.monitor(function (err, monitor) { * // Entering monitoring mode. * monitor.on('monitor', function (time, args, source, database) { * console.log(time + ": " + util.inspect(args)); * }); * }); * * // supports promise as well as other commands * redis.monitor().then(function (monitor) { * monitor.on('monitor', function (time, args, source, database) { * console.log(time + ": " + util.inspect(args)); * }); * }); * ``` */ monitor(callback) { const monitorInstance = this.duplicate({ monitor: true, lazyConnect: false, }); return (0, standard_as_callback_1.default)(new Promise(function (resolve, reject) { monitorInstance.once("error", reject); monitorInstance.once("monitoring", function () { resolve(monitorInstance); }); }), callback); } /** * Send a command to Redis * * This method is used internally and in most cases you should not * use it directly. If you need to send a command that is not supported * by the library, you can use the `call` method: * * ```js * const redis = new Redis(); * * redis.call('set', 'foo', 'bar'); * // or * redis.call(['set', 'foo', 'bar']); * ``` * * @ignore */ sendCommand(command, stream) { var _a, _b; if (this.status === "wait") { this.connect().catch(lodash_1.noop); } if (this.status === "end") { command.reject(new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG)); return command.promise; } if (((_a = this.condition) === null || _a === void 0 ? void 0 : _a.subscriber) && !Command_1.default.checkFlag("VALID_IN_SUBSCRIBER_MODE", command.name)) { command.reject(new Error("Connection in subscriber mode, only subscriber commands may be used")); return command.promise; } if (typeof this.options.commandTimeout === "number") { command.setTimeout(this.options.commandTimeout); } let writable = this.status === "ready" || (!stream && this.status === "connect" && (0, commands_1.exists)(command.name) && (0, commands_1.hasFlag)(command.name, "loading")); if (!this.stream) { writable = false; } else if (!this.stream.writable) { writable = false; // @ts-expect-error } else if (this.stream._writableState && this.stream._writableState.ended) { // TODO: We should be able to remove this as the PR has already been merged. // https://github.com/iojs/io.js/pull/1217 writable = false; } if (!writable) { if (!this.options.enableOfflineQueue) { command.reject(new Error("Stream isn't writeable and enableOfflineQueue options is false")); return command.promise; } if (command.name === "quit" && this.offlineQueue.length === 0) { this.disconnect(); command.resolve(Buffer.from("OK")); return command.promise; } // @ts-expect-error if (debug.enabled) { debug("queue command[%s]: %d -> %s(%o)", this._getDescription(), this.condition.select, command.name, command.args); } this.offlineQueue.push({ command: command, stream: stream, select: this.condition.select, }); } else { // @ts-expect-error if (debug.enabled) { debug("write command[%s]: %d -> %s(%o)", this._getDescription(), (_b = this.condition) === null || _b === void 0 ? void 0 : _b.select, command.name, command.args); } if (stream) { if ("isPipeline" in stream && stream.isPipeline) { stream.write(command.toWritable(stream.destination.redis.stream)); } else { stream.write(command.toWritable(stream)); } } else { this.stream.write(command.toWritable(this.stream)); } this.commandQueue.push({ command: command, stream: stream, select: this.condition.select, }); if (Command_1.default.checkFlag("WILL_DISCONNECT", command.name)) { this.manuallyClosing = true; } if (this.options.socketTimeout !== undefined && this.socketTimeoutTimer === undefined) { this.setSocketTimeout(); } } if (command.name === "select" && (0, utils_1.isInt)(command.args[0])) { const db = parseInt(command.args[0], 10); if (this.condition.select !== db) { this.condition.select = db; this.emit("select", db); debug("switch to db [%d]", this.condition.select); } } return command.promise; } setSocketTimeout() { this.socketTimeoutTimer = setTimeout(() => { this.stream.destroy(new Error(`Socket timeout. Expecting data, but didn't receive any in ${this.options.socketTimeout}ms.`)); this.socketTimeoutTimer = undefined; }, this.options.socketTimeout); // this handler must run after the "data" handler in "DataHandler" // so that `this.commandQueue.length` will be updated this.stream.once("data", () => { clearTimeout(this.socketTimeoutTimer); this.socketTimeoutTimer = undefined; if (this.commandQueue.length === 0) return; this.setSocketTimeout(); }); } scanStream(options) { return this.createScanStream("scan", { options }); } scanBufferStream(options) { return this.createScanStream("scanBuffer", { options }); } sscanStream(key, options) { return this.createScanStream("sscan", { key, options }); } sscanBufferStream(key, options) { return this.createScanStream("sscanBuffer", { key, options }); } hscanStream(key, options) { return this.createScanStream("hscan", { key, options }); } hscanBufferStream(key, options) { return this.createScanStream("hscanBuffer", { key, options }); } zscanStream(key, options) { return this.createScanStream("zscan", { key, options }); } zscanBufferStream(key, options) { return this.createScanStream("zscanBuffer", { key, options }); } /** * Emit only when there's at least one listener. * * @ignore */ silentEmit(eventName, arg) { let error; if (eventName === "error") { error = arg; if (this.status === "end") { return; } if (this.manuallyClosing) { // ignore connection related errors when manually disconnecting if (error instanceof Error && (error.message === utils_1.CONNECTION_CLOSED_ERROR_MSG || // @ts-expect-error error.syscall === "connect" || // @ts-expect-error error.syscall === "read")) { return; } } } if (this.listeners(eventName).length > 0) { return this.emit.apply(this, arguments); } if (error && error instanceof Error) { console.error("[ioredis] Unhandled error event:", error.stack); } return false; } /** * @ignore */ recoverFromFatalError(_commandError, err, options) { this.flushQueue(err, options); this.silentEmit("error", err); this.disconnect(true); } /** * @ignore */ handleReconnection(err, item) { var _a; let needReconnect = false; if (this.options.reconnectOnError) { needReconnect = this.options.reconnectOnError(err); } switch (needReconnect) { case 1: case true: if (this.status !== "reconnecting") { this.disconnect(true); } item.command.reject(err); break; case 2: if (this.status !== "reconnecting") { this.disconnect(true); } if (((_a = this.condition) === null || _a === void 0 ? void 0 : _a.select) !== item.select && item.command.name !== "select") { this.select(item.select); } // TODO // @ts-expect-error this.sendCommand(item.command); break; default: item.command.reject(err); } } /** * Get description of the connection. Used for debugging. */ _getDescription() { let description; if ("path" in this.options && this.options.path) { description = this.options.path; } else if (this.stream && this.stream.remoteAddress && this.stream.remotePort) { description = this.stream.remoteAddress + ":" + this.stream.remotePort; } else if ("host" in this.options && this.options.host) { description = this.options.host + ":" + this.options.port; } else { // Unexpected description = ""; } if (this.options.connectionName) { description += ` (${this.options.connectionName})`; } return description; } resetCommandQueue() { this.commandQueue = new Deque(); } resetOfflineQueue() { this.offlineQueue = new Deque(); } parseOptions(...args) { const options = {}; let isTls = false; for (let i = 0; i < args.length; ++i) { const arg = args[i]; if (arg === null || typeof arg === "undefined") { continue; } if (typeof arg === "object") { (0, lodash_1.defaults)(options, arg); } else if (typeof arg === "string") { (0, lodash_1.defaults)(options, (0, utils_1.parseURL)(arg)); if (arg.startsWith("rediss://")) { isTls = true; } } else if (typeof arg === "number") { options.port = arg; } else { throw new Error("Invalid argument " + arg); } } if (isTls) { (0, lodash_1.defaults)(options, { tls: true }); } (0, lodash_1.defaults)(options, Redis.defaultOptions); if (typeof options.port === "string") { options.port = parseInt(options.port, 10); } if (typeof options.db === "string") { options.db = parseInt(options.db, 10); } // @ts-expect-error this.options = (0, utils_1.resolveTLSProfile)(options); } /** * Change instance's status */ setStatus(status, arg) { // @ts-expect-error if (debug.enabled) { debug("status[%s]: %s -> %s", this._getDescription(), this.status || "[empty]", status); } this.status = status; process.nextTick(this.emit.bind(this, status, arg)); } createScanStream(command, { key, options = {} }) { return new ScanStream_1.default({ objectMode: true, key: key, redis: this, command: command, ...options, }); } /** * Flush offline queue and command queue with error. * * @param error The error object to send to the commands * @param options options */ flushQueue(error, options) { options = (0, lodash_1.defaults)({}, options, { offlineQueue: true, commandQueue: true, }); let item; if (options.offlineQueue) { while ((item = this.offlineQueue.shift())) { item.command.reject(error); } } if (options.commandQueue) { if (this.commandQueue.length > 0) { if (this.stream) { this.stream.removeAllListeners("data"); } while ((item = this.commandQueue.shift())) { item.command.reject(error); } } } } /** * Check whether Redis has finished loading the persistent data and is able to * process commands. */ _readyCheck(callback) { const _this = this; this.info(function (err, res) { if (err) { if (err.message && err.message.includes("NOPERM")) { console.warn(`Skipping the ready check because INFO command fails: "${err.message}". You can disable ready check with "enableReadyCheck". More: https://github.com/luin/ioredis/wiki/Disable-ready-check.`); return callback(null, {}); } return callback(err); } if (typeof res !== "string") { return callback(null, res); } const info = {}; const lines = res.split("\r\n"); for (let i = 0; i < lines.length; ++i) { const [fieldName, ...fieldValueParts] = lines[i].split(":"); const fieldValue = fieldValueParts.join(":"); if (fieldValue) { info[fieldName] = fieldValue; } } if (!info.loading || info.loading === "0") { callback(null, info); } else { const loadingEtaMs = (info.loading_eta_seconds || 1) * 1000; const retryTime = _this.options.maxLoadingRetryTime && _this.options.maxLoadingRetryTime < loadingEtaMs ? _this.options.maxLoadingRetryTime : loadingEtaMs; debug("Redis server still loading, trying again in " + retryTime + "ms"); setTimeout(function () { _this._readyCheck(callback); }, retryTime); } }).catch(lodash_1.noop); } }; Redis$1.Cluster = cluster_1.default; Redis$1.Command = Command_1.default; /** * Default options */ Redis$1.defaultOptions = RedisOptions_1.DEFAULT_REDIS_OPTIONS; (0, applyMixin_1.default)(Redis$1, events_1.EventEmitter); (0, transaction_1.addTransactionSupport)(Redis$1.prototype); Redis.default = Redis$1; return Redis; } (function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.print = exports.ReplyError = exports.SentinelIterator = exports.SentinelConnector = exports.AbstractConnector = exports.Pipeline = exports.ScanStream = exports.Command = exports.Cluster = exports.Redis = exports.default = void 0; exports = module.exports = requireRedis().default; var Redis_1 = requireRedis(); Object.defineProperty(exports, "default", { enumerable: true, get: function () { return Redis_1.default; } }); var Redis_2 = requireRedis(); Object.defineProperty(exports, "Redis", { enumerable: true, get: function () { return Redis_2.default; } }); var cluster_1 = requireCluster(); Object.defineProperty(exports, "Cluster", { enumerable: true, get: function () { return cluster_1.default; } }); /** * @ignore */ var Command_1 = Command$1; Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return Command_1.default; } }); /** * @ignore */ var ScanStream_1 = ScanStream$1; Object.defineProperty(exports, "ScanStream", { enumerable: true, get: function () { return ScanStream_1.default; } }); /** * @ignore */ var Pipeline_1 = Pipeline$1; Object.defineProperty(exports, "Pipeline", { enumerable: true, get: function () { return Pipeline_1.default; } }); /** * @ignore */ var AbstractConnector_1 = AbstractConnector$1; Object.defineProperty(exports, "AbstractConnector", { enumerable: true, get: function () { return AbstractConnector_1.default; } }); /** * @ignore */ var SentinelConnector_1 = requireSentinelConnector(); Object.defineProperty(exports, "SentinelConnector", { enumerable: true, get: function () { return SentinelConnector_1.default; } }); Object.defineProperty(exports, "SentinelIterator", { enumerable: true, get: function () { return SentinelConnector_1.SentinelIterator; } }); // No TS typings exports.ReplyError = redisErrors.ReplyError; /** * @ignore */ Object.defineProperty(exports, "Promise", { get() { console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used."); return Promise; }, set(_lib) { console.warn("ioredis v5 does not support plugging third-party Promise library anymore. Native Promise will be used."); }, }); /** * @ignore */ function print(err, reply) { if (err) { console.log("Error: " + err); } else { console.log("Reply: " + reply); } } exports.print = print; } (built$2, built$2.exports)); var builtExports = built$2.exports; var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; const events_1 = __importDefault(require$$1$3); const ioredis_1 = __importDefault(builtExports); class KeyvRedis extends events_1.default { constructor(uri, options) { super(); this.ttlSupport = true; this._getKeyName = (key) => { if (!this.opts.useRedisSets) { return `sets:${this._getNamespace()}:${key}`; } return key; }; this.opts = {}; this.opts.useRedisSets = true; this.opts.dialect = 'redis'; if (typeof uri !== 'string' && uri.options && ('family' in uri.options || uri.isCluster)) { this.redis = uri; } else { options = { ...(typeof uri === 'string' ? { uri } : uri), ...options }; // @ts-expect-error - uri is a string or RedisOptions this.redis = new ioredis_1.default(options.uri, options); } if (options !== undefined && options.useRedisSets === false) { this.opts.useRedisSets = false; } this.redis.on('error', (error) => this.emit('error', error)); } _getNamespace() { return `namespace:${this.namespace}`; } async get(key) { key = this._getKeyName(key); const value = await this.redis.get(key); if (value === null) { return undefined; } return value; } async getMany(keys) { keys = keys.map(this._getKeyName); return this.redis.mget(keys); } async set(key, value, ttl) { if (value === undefined) { return undefined; } key = this._getKeyName(key); const set = async (redis) => { if (typeof ttl === 'number') { await redis.set(key, value, 'PX', ttl); } else { await redis.set(key, value); } }; if (this.opts.useRedisSets) { const trx = await this.redis.multi(); await set(trx); await trx.sadd(this._getNamespace(), key); await trx.exec(); } else { await set(this.redis); } } async delete(key) { key = this._getKeyName(key); let items = 0; const unlink = async (redis) => redis.unlink(key); if (this.opts.useRedisSets) { const trx = this.redis.multi(); await unlink(trx); await trx.srem(this._getNamespace(), key); const r = await trx.exec(); items = r[0][1]; } else { items = await unlink(this.redis); } return items > 0; } async deleteMany(keys) { const deletePromises = keys.map(async (key) => this.delete(key)); const results = await Promise.allSettled(deletePromises); // @ts-expect-error - results is an array of objects with status and value return results.every(result => result.value); } async clear() { if (this.opts.useRedisSets) { const keys = await this.redis.smembers(this._getNamespace()); if (keys.length > 0) { await Promise.all([ this.redis.unlink([...keys]), this.redis.srem(this._getNamespace(), [...keys]), ]); } } else { const pattern = `sets:${this._getNamespace()}:*`; const keys = await this.redis.keys(pattern); if (keys.length > 0) { await this.redis.unlink(keys); } } } async *iterator(namespace) { const scan = this.redis.scan.bind(this.redis); const get = this.redis.mget.bind(this.redis); let cursor = '0'; do { // eslint-disable-next-line no-await-in-loop const [curs, keys] = await scan(cursor, 'MATCH', `${namespace}:*`); cursor = curs; if (keys.length > 0) { // eslint-disable-next-line no-await-in-loop const values = await get(keys); for (const [i] of keys.entries()) { const key = keys[i]; const value = values[i]; yield [key, value]; } } } while (cursor !== '0'); } async has(key) { const value = await this.redis.exists(key); return value !== 0; } async disconnect() { return this.redis.disconnect(); } } var dist = KeyvRedis; var KeyvRedis$1 = /*@__PURE__*/getDefaultExportFromCjs(dist); const cache = getCache(); function getCache() { if (env$1["CACHE_ENABLED"] !== true) return null; let namespace = env$1["CACHE_JWT_NAMESPACE"]; if (namespace == null || namespace === "") { namespace = "exjwt"; } let ttl = env$1["CACHE_JWT_TTL"]; if (ttl == null || ttl === "") { ttl = 5e3; } let uri = ""; let store = void 0; if (env$1["CACHE_STORE"] === "redis") { uri = env$1["REDIS"]; if (uri == null || uri === "") { uri = `redis://${env$1["REDIS_USERNAME"] || ""}:${env$1["REDIS_PASSWORD"] || ""}@${env$1["REDIS_HOST"]}:${env$1["REDIS_PORT"] || "6379"} /${env$1["REDIS_JWT_DB"] || "2"}`; } try { store = new KeyvRedis$1(uri); } catch (e) { throw new Error("CACHE: could not connect to database: " + e); } } try { const keyv = new Keyv$1(uri, { namespace, ttl, store }); keyv.on("error", (err) => { throw new Error("CACHE: could not connect: " + err); }); return keyv; } catch (e) { throw new Error("CACHE: could not connect to database: " + e); } } function CacheEnabled() { return cache !== null; } async function CacheSet(key, value) { if (cache === null) return false; return cache.set(key, value); } async function CacheGet(key) { if (cache === null) return null; return cache.get(key); } const authProviders = await getAuthProviders(); async function getAccountabilityForToken(token, iss, accountability, database) { if (accountability == null) { accountability = { user: null, role: null, admin: false, app: false }; } if (token == null || iss == null) { return accountability; } const providers = authProviders.filter((provider2) => provider2.issuer_url && iss.includes(provider2.issuer_url)); if (providers.length === 0) return accountability; if (providers.length > 1) { return accountability; } const provider = providers[0]; try { const result = await verify_token(provider, token); if (provider.use_database) { if (CacheEnabled() && result.sub) { const cachedAccountability = await CacheGet(result.sub); if (cachedAccountability) { return cachedAccountability; } } const user = await database.select("directus_users.id", "directus_users.role", "directus_roles.admin_access", "directus_roles.app_access").from("directus_users").leftJoin("directus_roles", "directus_users.role", "directus_roles.id").where({ "directus_users.external_identifier": result.sub, "directus_users.provider": provider.name }).first(); if (!user) { return accountability; } accountability.user = user.id; accountability.role = user.role; accountability.admin = user.admin_access === true || user.admin_access == 1; accountability.app = user.app_access === true || user.app_access == 1; if (CacheEnabled() && result.sub) { CacheSet(result.sub, accountability); } return accountability; } if (provider.role_key != null) { if (typeof result[provider.role_key] === "string") { accountability.role = result[provider.role_key]; } if (typeof result[provider.role_key] === "object") { accountability.role = ""; } if (result[provider.role_key].instanceOf(Array)) { accountability.role = result[provider.role_key][0]; } } if (provider.admin_key != null) { accountability.admin = result[provider.admin_key]; } if (provider.app_key != null) { accountability.app = result[provider.app_key]; } accountability.user = result.sub; } catch (error) { return accountability; } return accountability; } var index = defineHook(({ filter }) => { filter("authenticate", (defaultAccountability, event, context) => { const req = event["req"]; if (!req.token) return defaultAccountability; if (!context.database) { return defaultAccountability; } const decodedToken = jwt.decode(req.token); if (typeof decodedToken === "string" || decodedToken == null) return defaultAccountability; if (decodedToken?.iss == "directus") return defaultAccountability; return getAccountabilityForToken(req.token, decodedToken?.iss, context.accountability, context.database); }); }); export { index as default };