UNPKG

typia

Version:

Superfast runtime validators with only one line

1,855 lines (1,654 loc) • 98.7 kB
function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var lib$1 = {exports: {}}; var util$1 = {}; var types$4 = { ROOT : 0, GROUP : 1, POSITION : 2, SET : 3, RANGE : 4, REPETITION : 5, REFERENCE : 6, CHAR : 7, }; var sets$1 = {}; const types$3 = types$4; const INTS = () => [{ type: types$3.RANGE , from: 48, to: 57 }]; const WORDS = () => { return [ { type: types$3.CHAR, value: 95 }, { type: types$3.RANGE, from: 97, to: 122 }, { type: types$3.RANGE, from: 65, to: 90 } ].concat(INTS()); }; const WHITESPACE = () => { return [ { type: types$3.CHAR, value: 9 }, { type: types$3.CHAR, value: 10 }, { type: types$3.CHAR, value: 11 }, { type: types$3.CHAR, value: 12 }, { type: types$3.CHAR, value: 13 }, { type: types$3.CHAR, value: 32 }, { type: types$3.CHAR, value: 160 }, { type: types$3.CHAR, value: 5760 }, { type: types$3.RANGE, from: 8192, to: 8202 }, { type: types$3.CHAR, value: 8232 }, { type: types$3.CHAR, value: 8233 }, { type: types$3.CHAR, value: 8239 }, { type: types$3.CHAR, value: 8287 }, { type: types$3.CHAR, value: 12288 }, { type: types$3.CHAR, value: 65279 } ]; }; const NOTANYCHAR = () => { return [ { type: types$3.CHAR, value: 10 }, { type: types$3.CHAR, value: 13 }, { type: types$3.CHAR, value: 8232 }, { type: types$3.CHAR, value: 8233 }, ]; }; // Predefined class objects. sets$1.words = () => ({ type: types$3.SET, set: WORDS(), not: false }); sets$1.notWords = () => ({ type: types$3.SET, set: WORDS(), not: true }); sets$1.ints = () => ({ type: types$3.SET, set: INTS(), not: false }); sets$1.notInts = () => ({ type: types$3.SET, set: INTS(), not: true }); sets$1.whitespace = () => ({ type: types$3.SET, set: WHITESPACE(), not: false }); sets$1.notWhitespace = () => ({ type: types$3.SET, set: WHITESPACE(), not: true }); sets$1.anyChar = () => ({ type: types$3.SET, set: NOTANYCHAR(), not: true }); (function (exports) { const types = types$4; const sets = sets$1; const CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?'; const SLSH = { '0': 0, 't': 9, 'n': 10, 'v': 11, 'f': 12, 'r': 13 }; /** * Finds character representations in str and convert all to * their respective characters * * @param {String} str * @return {String} */ exports.strToChars = function(str) { /* jshint maxlen: false */ var chars_regex = /(\[\\b\])|(\\)?\\(?:u([A-F0-9]{4})|x([A-F0-9]{2})|(0?[0-7]{2})|c([@A-Z[\\\]^?])|([0tnvfr]))/g; str = str.replace(chars_regex, function(s, b, lbs, a16, b16, c8, dctrl, eslsh) { if (lbs) { return s; } var code = b ? 8 : a16 ? parseInt(a16, 16) : b16 ? parseInt(b16, 16) : c8 ? parseInt(c8, 8) : dctrl ? CTRL.indexOf(dctrl) : SLSH[eslsh]; var c = String.fromCharCode(code); // Escape special regex characters. if (/[[\]{}^$.|?*+()]/.test(c)) { c = '\\' + c; } return c; }); return str; }; /** * turns class into tokens * reads str until it encounters a ] not preceeded by a \ * * @param {String} str * @param {String} regexpStr * @return {Array.<Array.<Object>, Number>} */ exports.tokenizeClass = (str, regexpStr) => { /* jshint maxlen: false */ var tokens = []; var regexp = /\\(?:(w)|(d)|(s)|(W)|(D)|(S))|((?:(?:\\)(.)|([^\]\\]))-(?:\\)?([^\]]))|(\])|(?:\\)?([^])/g; var rs, c; while ((rs = regexp.exec(str)) != null) { if (rs[1]) { tokens.push(sets.words()); } else if (rs[2]) { tokens.push(sets.ints()); } else if (rs[3]) { tokens.push(sets.whitespace()); } else if (rs[4]) { tokens.push(sets.notWords()); } else if (rs[5]) { tokens.push(sets.notInts()); } else if (rs[6]) { tokens.push(sets.notWhitespace()); } else if (rs[7]) { tokens.push({ type: types.RANGE, from: (rs[8] || rs[9]).charCodeAt(0), to: rs[10].charCodeAt(0), }); } else if ((c = rs[12])) { tokens.push({ type: types.CHAR, value: c.charCodeAt(0), }); } else { return [tokens, regexp.lastIndex]; } } exports.error(regexpStr, 'Unterminated character class'); }; /** * Shortcut to throw errors. * * @param {String} regexp * @param {String} msg */ exports.error = (regexp, msg) => { throw new SyntaxError('Invalid regular expression: /' + regexp + '/: ' + msg); }; } (util$1)); var positions$1 = {}; const types$2 = types$4; positions$1.wordBoundary = () => ({ type: types$2.POSITION, value: 'b' }); positions$1.nonWordBoundary = () => ({ type: types$2.POSITION, value: 'B' }); positions$1.begin = () => ({ type: types$2.POSITION, value: '^' }); positions$1.end = () => ({ type: types$2.POSITION, value: '$' }); const util = util$1; const types$1 = types$4; const sets = sets$1; const positions = positions$1; lib$1.exports = (regexpStr) => { var i = 0, l, c, start = { type: types$1.ROOT, stack: []}, // Keep track of last clause/group and stack. lastGroup = start, last = start.stack, groupStack = []; var repeatErr = (i) => { util.error(regexpStr, `Nothing to repeat at column ${i - 1}`); }; // Decode a few escaped characters. var str = util.strToChars(regexpStr); l = str.length; // Iterate through each character in string. while (i < l) { c = str[i++]; switch (c) { // Handle escaped characters, inclues a few sets. case '\\': c = str[i++]; switch (c) { case 'b': last.push(positions.wordBoundary()); break; case 'B': last.push(positions.nonWordBoundary()); break; case 'w': last.push(sets.words()); break; case 'W': last.push(sets.notWords()); break; case 'd': last.push(sets.ints()); break; case 'D': last.push(sets.notInts()); break; case 's': last.push(sets.whitespace()); break; case 'S': last.push(sets.notWhitespace()); break; default: // Check if c is integer. // In which case it's a reference. if (/\d/.test(c)) { last.push({ type: types$1.REFERENCE, value: parseInt(c, 10) }); // Escaped character. } else { last.push({ type: types$1.CHAR, value: c.charCodeAt(0) }); } } break; // Positionals. case '^': last.push(positions.begin()); break; case '$': last.push(positions.end()); break; // Handle custom sets. case '[': // Check if this class is 'anti' i.e. [^abc]. var not; if (str[i] === '^') { not = true; i++; } else { not = false; } // Get all the characters in class. var classTokens = util.tokenizeClass(str.slice(i), regexpStr); // Increase index by length of class. i += classTokens[1]; last.push({ type: types$1.SET, set: classTokens[0], not, }); break; // Class of any character except \n. case '.': last.push(sets.anyChar()); break; // Push group onto stack. case '(': // Create group. var group = { type: types$1.GROUP, stack: [], remember: true, }; c = str[i]; // If if this is a special kind of group. if (c === '?') { c = str[i + 1]; i += 2; // Match if followed by. if (c === '=') { group.followedBy = true; // Match if not followed by. } else if (c === '!') { group.notFollowedBy = true; } else if (c !== ':') { util.error(regexpStr, `Invalid group, character '${c}'` + ` after '?' at column ${i - 1}`); } group.remember = false; } // Insert subgroup into current group stack. last.push(group); // Remember the current group for when the group closes. groupStack.push(lastGroup); // Make this new group the current group. lastGroup = group; last = group.stack; break; // Pop group out of stack. case ')': if (groupStack.length === 0) { util.error(regexpStr, `Unmatched ) at column ${i - 1}`); } lastGroup = groupStack.pop(); // Check if this group has a PIPE. // To get back the correct last stack. last = lastGroup.options ? lastGroup.options[lastGroup.options.length - 1] : lastGroup.stack; break; // Use pipe character to give more choices. case '|': // Create array where options are if this is the first PIPE // in this clause. if (!lastGroup.options) { lastGroup.options = [lastGroup.stack]; delete lastGroup.stack; } // Create a new stack and add to options for rest of clause. var stack = []; lastGroup.options.push(stack); last = stack; break; // Repetition. // For every repetition, remove last element from last stack // then insert back a RANGE object. // This design is chosen because there could be more than // one repetition symbols in a regex i.e. `a?+{2,3}`. case '{': var rs = /^(\d+)(,(\d+)?)?\}/.exec(str.slice(i)), min, max; if (rs !== null) { if (last.length === 0) { repeatErr(i); } min = parseInt(rs[1], 10); max = rs[2] ? rs[3] ? parseInt(rs[3], 10) : Infinity : min; i += rs[0].length; last.push({ type: types$1.REPETITION, min, max, value: last.pop(), }); } else { last.push({ type: types$1.CHAR, value: 123, }); } break; case '?': if (last.length === 0) { repeatErr(i); } last.push({ type: types$1.REPETITION, min: 0, max: 1, value: last.pop(), }); break; case '+': if (last.length === 0) { repeatErr(i); } last.push({ type: types$1.REPETITION, min: 1, max: Infinity, value: last.pop(), }); break; case '*': if (last.length === 0) { repeatErr(i); } last.push({ type: types$1.REPETITION, min: 0, max: Infinity, value: last.pop(), }); break; // Default is a character that is not `\[](){}?+*^$`. default: last.push({ type: types$1.CHAR, value: c.charCodeAt(0), }); } } // Check if any groups have not been closed. if (groupStack.length !== 0) { util.error(regexpStr, 'Unterminated group'); } return start; }; lib$1.exports.types = types$1; var libExports = lib$1.exports; /* eslint indent: 4 */ // Private helper class class SubRange { constructor(low, high) { this.low = low; this.high = high; this.length = 1 + high - low; } overlaps(range) { return !(this.high < range.low || this.low > range.high); } touches(range) { return !(this.high + 1 < range.low || this.low - 1 > range.high); } // Returns inclusive combination of SubRanges as a SubRange. add(range) { return new SubRange( Math.min(this.low, range.low), Math.max(this.high, range.high) ); } // Returns subtraction of SubRanges as an array of SubRanges. // (There's a case where subtraction divides it in 2) subtract(range) { if (range.low <= this.low && range.high >= this.high) { return []; } else if (range.low > this.low && range.high < this.high) { return [ new SubRange(this.low, range.low - 1), new SubRange(range.high + 1, this.high) ]; } else if (range.low <= this.low) { return [new SubRange(range.high + 1, this.high)]; } else { return [new SubRange(this.low, range.low - 1)]; } } toString() { return this.low == this.high ? this.low.toString() : this.low + '-' + this.high; } } let DRange$1 = class DRange { constructor(a, b) { this.ranges = []; this.length = 0; if (a != null) this.add(a, b); } _update_length() { this.length = this.ranges.reduce((previous, range) => { return previous + range.length; }, 0); } add(a, b) { var _add = (subrange) => { var i = 0; while (i < this.ranges.length && !subrange.touches(this.ranges[i])) { i++; } var newRanges = this.ranges.slice(0, i); while (i < this.ranges.length && subrange.touches(this.ranges[i])) { subrange = subrange.add(this.ranges[i]); i++; } newRanges.push(subrange); this.ranges = newRanges.concat(this.ranges.slice(i)); this._update_length(); }; if (a instanceof DRange) { a.ranges.forEach(_add); } else { if (b == null) b = a; _add(new SubRange(a, b)); } return this; } subtract(a, b) { var _subtract = (subrange) => { var i = 0; while (i < this.ranges.length && !subrange.overlaps(this.ranges[i])) { i++; } var newRanges = this.ranges.slice(0, i); while (i < this.ranges.length && subrange.overlaps(this.ranges[i])) { newRanges = newRanges.concat(this.ranges[i].subtract(subrange)); i++; } this.ranges = newRanges.concat(this.ranges.slice(i)); this._update_length(); }; if (a instanceof DRange) { a.ranges.forEach(_subtract); } else { if (b == null) b = a; _subtract(new SubRange(a, b)); } return this; } intersect(a, b) { var newRanges = []; var _intersect = (subrange) => { var i = 0; while (i < this.ranges.length && !subrange.overlaps(this.ranges[i])) { i++; } while (i < this.ranges.length && subrange.overlaps(this.ranges[i])) { var low = Math.max(this.ranges[i].low, subrange.low); var high = Math.min(this.ranges[i].high, subrange.high); newRanges.push(new SubRange(low, high)); i++; } }; if (a instanceof DRange) { a.ranges.forEach(_intersect); } else { if (b == null) b = a; _intersect(new SubRange(a, b)); } this.ranges = newRanges; this._update_length(); return this; } index(index) { var i = 0; while (i < this.ranges.length && this.ranges[i].length <= index) { index -= this.ranges[i].length; i++; } return this.ranges[i].low + index; } toString() { return '[ ' + this.ranges.join(', ') + ' ]'; } clone() { return new DRange(this); } numbers() { return this.ranges.reduce((result, subrange) => { var i = subrange.low; while (i <= subrange.high) { result.push(i); i++; } return result; }, []); } subranges() { return this.ranges.map((subrange) => ({ low: subrange.low, high: subrange.high, length: 1 + subrange.high - subrange.low })); } }; var lib = DRange$1; const ret = libExports; const DRange = lib; const types = ret.types; var randexp = class RandExp { /** * @constructor * @param {RegExp|String} regexp * @param {String} m */ constructor(regexp, m) { this._setDefaults(regexp); if (regexp instanceof RegExp) { this.ignoreCase = regexp.ignoreCase; this.multiline = regexp.multiline; regexp = regexp.source; } else if (typeof regexp === 'string') { this.ignoreCase = m && m.indexOf('i') !== -1; this.multiline = m && m.indexOf('m') !== -1; } else { throw new Error('Expected a regexp or string'); } this.tokens = ret(regexp); } /** * Checks if some custom properties have been set for this regexp. * * @param {RandExp} randexp * @param {RegExp} regexp */ _setDefaults(regexp) { // When a repetitional token has its max set to Infinite, // randexp won't actually generate a random amount between min and Infinite // instead it will see Infinite as min + 100. this.max = regexp.max != null ? regexp.max : RandExp.prototype.max != null ? RandExp.prototype.max : 100; // This allows expanding to include additional characters // for instance: RandExp.defaultRange.add(0, 65535); this.defaultRange = regexp.defaultRange ? regexp.defaultRange : this.defaultRange.clone(); if (regexp.randInt) { this.randInt = regexp.randInt; } } /** * Generates the random string. * * @return {String} */ gen() { return this._gen(this.tokens, []); } /** * Generate random string modeled after given tokens. * * @param {Object} token * @param {Array.<String>} groups * @return {String} */ _gen(token, groups) { var stack, str, n, i, l; switch (token.type) { case types.ROOT: case types.GROUP: // Ignore lookaheads for now. if (token.followedBy || token.notFollowedBy) { return ''; } // Insert placeholder until group string is generated. if (token.remember && token.groupNumber === undefined) { token.groupNumber = groups.push(null) - 1; } stack = token.options ? this._randSelect(token.options) : token.stack; str = ''; for (i = 0, l = stack.length; i < l; i++) { str += this._gen(stack[i], groups); } if (token.remember) { groups[token.groupNumber] = str; } return str; case types.POSITION: // Do nothing for now. return ''; case types.SET: var expandedSet = this._expand(token); if (!expandedSet.length) { return ''; } return String.fromCharCode(this._randSelect(expandedSet)); case types.REPETITION: // Randomly generate number between min and max. n = this.randInt(token.min, token.max === Infinity ? token.min + this.max : token.max); str = ''; for (i = 0; i < n; i++) { str += this._gen(token.value, groups); } return str; case types.REFERENCE: return groups[token.value - 1] || ''; case types.CHAR: var code = this.ignoreCase && this._randBool() ? this._toOtherCase(token.value) : token.value; return String.fromCharCode(code); } } /** * If code is alphabetic, converts to other case. * If not alphabetic, returns back code. * * @param {Number} code * @return {Number} */ _toOtherCase(code) { return code + (97 <= code && code <= 122 ? -32 : 65 <= code && code <= 90 ? 32 : 0); } /** * Randomly returns a true or false value. * * @return {Boolean} */ _randBool() { return !this.randInt(0, 1); } /** * Randomly selects and returns a value from the array. * * @param {Array.<Object>} arr * @return {Object} */ _randSelect(arr) { if (arr instanceof DRange) { return arr.index(this.randInt(0, arr.length - 1)); } return arr[this.randInt(0, arr.length - 1)]; } /** * expands a token to a DiscontinuousRange of characters which has a * length and an index function (for random selecting) * * @param {Object} token * @return {DiscontinuousRange} */ _expand(token) { if (token.type === ret.types.CHAR) { return new DRange(token.value); } else if (token.type === ret.types.RANGE) { return new DRange(token.from, token.to); } else { let drange = new DRange(); for (let i = 0; i < token.set.length; i++) { let subrange = this._expand(token.set[i]); drange.add(subrange); if (this.ignoreCase) { for (let j = 0; j < subrange.length; j++) { let code = subrange.index(j); let otherCaseCode = this._toOtherCase(code); if (code !== otherCaseCode) { drange.add(otherCaseCode); } } } } if (token.not) { return this.defaultRange.clone().subtract(drange); } else { return this.defaultRange.clone().intersect(drange); } } } /** * Randomly generates and returns a number between a and b (inclusive). * * @param {Number} a * @param {Number} b * @return {Number} */ randInt(a, b) { return a + Math.floor(Math.random() * (1 + b - a)); } /** * Default range of characters to generate from. */ get defaultRange() { return this._range = this._range || new DRange(32, 126); } set defaultRange(range) { this._range = range; } /** * * Enables use of randexp with a shorter call. * * @param {RegExp|String| regexp} * @param {String} m * @return {String} */ static randexp(regexp, m) { var randexp; if(typeof regexp === 'string') { regexp = new RegExp(regexp, m); } if (regexp._randexp === undefined) { randexp = new RandExp(regexp, m); regexp._randexp = randexp; } else { randexp = regexp._randexp; randexp._setDefaults(regexp); } return randexp.gen(); } /** * Enables sugary /regexp/.gen syntax. */ static sugar() { /* eshint freeze:false */ RegExp.prototype.gen = function() { return RandExp.randexp(this); }; } }; var RandExp = /*@__PURE__*/getDefaultExportFromCjs(randexp); const ALPHABETS = "abcdefghijklmnopqrstuvwxyz"; /* ----------------------------------------------------------- REGULAR ----------------------------------------------------------- */ const boolean$4 = () => Math.random() < 0.5; const integer = (min, max) => { min ??= 0; max ??= 100; return Math.floor(Math.random() * (max - min + 1)) + min; }; const bigint$4 = (min, max) => BigInt(integer(Number(min ?? BigInt(0)), Number(max ?? BigInt(100)))); const number$4 = (min, max) => { min ??= 0; max ??= 100; return Math.random() * (max - min) + min; }; const string$4 = (length) => new Array(length ?? integer(5, 10)) .fill(0) .map(() => ALPHABETS[integer(0, ALPHABETS.length - 1)]) .join(""); const array$2 = (closure, count, unique) => { count ??= length(); unique ??= false; if (unique === false) return new Array(count ?? length()) .fill(0) .map((_e, index) => closure(index)); else { const set = new Set(); while (set.size < count) set.add(closure(set.size)); return Array.from(set); } }; const pick = (array) => array[integer(0, array.length - 1)]; const length = () => integer(0, 3); const pattern = (regex) => { const r = new RandExp(regex); for (let i = 0; i < 10; ++i) { const str = r.gen(); if (regex.test(str)) return str; } return r.gen(); }; /* ----------------------------------------------------------- SECIAL FORMATS ----------------------------------------------------------- */ // SPECIAL CHARACTERS const byte = () => "vt7ekz4lIoNTTS9sDQYdWKharxIFAR54+z/umIxSgUM="; const password = () => string$4(integer(4, 16)); const regex = () => "/^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/"; const uuid = () => "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { const r = (Math.random() * 16) | 0; const v = c === "x" ? r : (r & 0x3) | 0x8; return v.toString(16); }); // ADDRESSES const email = () => `${string$4(10)}@${string$4(10)}.${string$4(3)}`; const hostname = () => `${string$4(10)}.${string$4(3)}`; const idnEmail = () => email(); const idnHostname = () => hostname(); const iri = () => url(); const iriReference = () => url(); const ipv4 = () => array$2(() => integer(0, 255), 4).join("."); const ipv6 = () => array$2(() => integer(0, 65535).toString(16), 8).join(":"); const uri = () => url(); const uriReference = () => url(); const uriTemplate = () => url(); const url = () => `https://${string$4(10)}.${string$4(3)}`; // TIMESTAMPS const datetime = (min, max) => new Date(number$4(min ?? Date.now() - 30 * DAY, max ?? Date.now() + 7 * DAY)).toISOString(); const date = (min, max) => new Date(number$4(min ?? 0, max ?? Date.now() * 2)) .toISOString() .substring(0, 10); const time = () => new Date(number$4(0, DAY)).toISOString().substring(11); const duration = () => { const period = durate([ ["Y", integer(0, 100)], ["M", integer(0, 12)], ["D", integer(0, 31)], ]); const time = durate([ ["H", integer(0, 24)], ["M", integer(0, 60)], ["S", integer(0, 60)], ]); if (period.length + time.length === 0) return "PT0S"; return `P${period}${time.length ? "T" : ""}${time}`; }; // POINTERS const jsonPointer = () => `/components/schemas/${string$4(10)}`; const relativeJsonPointer = () => `${integer(0, 10)}#`; const DAY = 86400000; const durate = (elements) => elements .filter(([_unit, value]) => value !== 0) .map(([unit, value]) => `${value}${unit}`) .join(""); var RandomGenerator = /*#__PURE__*/Object.freeze({ __proto__: null, array: array$2, bigint: bigint$4, boolean: boolean$4, byte: byte, date: date, datetime: datetime, duration: duration, email: email, hostname: hostname, idnEmail: idnEmail, idnHostname: idnHostname, integer: integer, ipv4: ipv4, ipv6: ipv6, iri: iri, iriReference: iriReference, jsonPointer: jsonPointer, length: length, number: number$4, password: password, pattern: pattern, pick: pick, regex: regex, relativeJsonPointer: relativeJsonPointer, string: string$4, time: time, uri: uri, uriReference: uriReference, uriTemplate: uriTemplate, url: url, uuid: uuid }); const $every = (array, pred) => { let error = null; for (let i = 0; i < array.length; ++i) if (null !== (error = pred(array[i], i))) return error; return null; }; class TypeGuardError extends Error { method; path; expected; value; fake_expected_typed_value_; constructor(props) { // MESSAGE CONSTRUCTION super(props.message || `Error on ${props.method}(): invalid type${props.path ? ` on ${props.path}` : ""}, expect to be ${props.expected}`); // INHERITANCE POLYFILL const proto = new.target.prototype; if (Object.setPrototypeOf) Object.setPrototypeOf(this, proto); else this.__proto__ = proto; // ASSIGN MEMBERS this.method = props.method; this.path = props.path; this.expected = props.expected; this.value = props.value; } } /** * @internal */ const $guard = (method) => (exceptionable, props, factory) => { if (exceptionable === true) throw (factory ?? ((props) => new TypeGuardError(props)))({ method, path: props.path, expected: props.expected, value: props.value, }); return false; }; const $join = (str) => variable(str) ? `.${str}` : `[${JSON.stringify(str)}]`; const variable = (str) => reserved(str) === false && /^[a-zA-Z_$][a-zA-Z_$0-9]*$/g.test(str); const reserved = (str) => RESERVED.has(str); const RESERVED = new Set([ "break", "case", "catch", "class", "const", "continue", "debugger", "default", "delete", "do", "else", "enum", "export", "extends", "false", "finally", "for", "function", "if", "import", "in", "instanceof", "new", "null", "return", "super", "switch", "this", "throw", "true", "try", "typeof", "var", "void", "while", "with", ]); const $report = (array) => { const reportable = (path) => { if (array.length === 0) return true; const last = array[array.length - 1].path; return path.length > last.length || last.substring(0, path.length) !== path; }; return (exceptable, error) => { if (exceptable && reportable(error.path)) array.push(error); return false; }; }; const $is_between = (value, minimum, maximum) => minimum <= value && value <= maximum; const $is_bigint_string = (str) => { try { BigInt(str); return true; } catch { return false; } }; /** * @internal */ const is$1 = () => ({ is_between: $is_between, is_bigint_string: $is_bigint_string, }); const functionalAssert = () => ({ errorFactory: (p) => new TypeGuardError(p), }); const $number = (value) => { if (isFinite(value) === false) throw new TypeGuardError({ method: "typia.json.stringify", expected: "number", value, message: "Error on typia.json.stringify(): infinite or not a number.", }); return value; }; const $rest = (str) => { return str.length === 2 ? "" : "," + str.substring(1, str.length - 1); }; /** * In the past, name of `typia` was `typescript-json`, and supported * JSON serialization by wrapping `fast-json-stringify. `typescript-json` was * a helper library of `fast-json-stringify`, which can skip manual JSON schema * definition just by putting pure TypeScript type. * * This `$string` function is a part of `fast-json-stringify` at that time, and * still being used in `typia` for the string serialization. * * @internal * @reference https://github.com/fastify/fast-json-stringify/blob/master/lib/serializer.js * @blog https://dev.to/samchon/good-bye-typescript-is-ancestor-of-typia-20000x-faster-validator-49fi */ const $string = (str) => { const len = str.length; let result = ""; let last = -1; let point = 255; // eslint-disable-next-line for (var i = 0; i < len; i++) { point = str.charCodeAt(i); if (point < 32) { return JSON.stringify(str); } if (point >= 0xd800 && point <= 0xdfff) { // The current character is a surrogate. return JSON.stringify(str); } if (point === 0x22 || // '"' point === 0x5c // '\' ) { last === -1 && (last = 0); result += str.slice(last, i) + "\\"; last = i; } } return ((last === -1 && '"' + str + '"') || '"' + result + str.slice(last) + '"'); }; /** * @internal */ const $tail = (str) => str[str.length - 1] === "," ? str.substring(0, str.length - 1) : str; const $throws = (method) => (props) => { throw new TypeGuardError({ ...props, method: `typia.${method}`, }); }; const stringify$1 = (method) => ({ ...is$1(), number: $number, string: $string, tail: $tail, rest: $rest, throws: $throws(`json.${method}`), }); const boolean$3 = (input) => input instanceof File ? input : input === null ? undefined : input === "null" ? null : input.length === 0 ? true : input === "true" || input === "1" ? true : input === "false" || input === "0" ? false : input; // wrong type const number$3 = (input) => input instanceof File ? input : !!input?.length ? input === "null" ? null : toNumber$3(input) : undefined; const bigint$3 = (input) => input instanceof File ? input : !!input?.length ? input === "null" ? null : toBigint$3(input) : undefined; const string$3 = (input) => input instanceof File ? input : input === null ? undefined : input === "null" ? null : input; const array$1 = (input, alternative) => input.length ? input : alternative; const blob = (input) => input instanceof Blob ? input : input === null ? undefined : input === "null" ? null : input; const file = (input) => input instanceof File ? input : input === null ? undefined : input === "null" ? null : input; const toNumber$3 = (str) => { const value = Number(str); return isNaN(value) ? str : value; }; const toBigint$3 = (str) => { try { return BigInt(str); } catch { return str; } }; var $FormDataReader = /*#__PURE__*/Object.freeze({ __proto__: null, array: array$1, bigint: bigint$3, blob: blob, boolean: boolean$3, file: file, number: number$3, string: string$3 }); const boolean$2 = (value) => value !== undefined ? value === "true" ? true : value === "false" ? false : value : undefined; const bigint$2 = (value) => value !== undefined ? toBigint$2(value) : undefined; const number$2 = (value) => value !== undefined ? toNumber$2(value) : undefined; const string$2 = (value) => value; const toBigint$2 = (str) => { try { return BigInt(str); } catch { return str; } }; const toNumber$2 = (str) => { const value = Number(str); return isNaN(value) ? str : value; }; var $HeadersReader = /*#__PURE__*/Object.freeze({ __proto__: null, bigint: bigint$2, boolean: boolean$2, number: number$2, string: string$2 }); const boolean$1 = (value) => value !== "null" ? value === "true" || value === "1" ? true : value === "false" || value === "0" ? false : value : null; const bigint$1 = (value) => value !== "null" ? toBigint$1(value) : null; const number$1 = (value) => value !== "null" ? toNumber$1(value) : null; const string$1 = (value) => (value !== "null" ? value : null); const toNumber$1 = (str) => { const value = Number(str); return isNaN(value) ? str : value; }; const toBigint$1 = (str) => { try { return BigInt(str); } catch { return str; } }; var $ParameterReader = /*#__PURE__*/Object.freeze({ __proto__: null, bigint: bigint$1, boolean: boolean$1, number: number$1, string: string$1 }); const boolean = (str) => str === null ? undefined : str === "null" ? null : str.length === 0 ? true : str === "true" || str === "1" ? true : str === "false" || str === "0" ? false : str; // wrong type const number = (str) => !!str?.length ? (str === "null" ? null : toNumber(str)) : undefined; const bigint = (str) => !!str?.length ? (str === "null" ? null : toBigint(str)) : undefined; const string = (str) => str === null ? undefined : str === "null" ? null : str; const params = (input) => { if (typeof input === "string") { const index = input.indexOf("?"); input = index === -1 ? "" : input.substring(index + 1); return new URLSearchParams(input); } return input; }; const array = (input, alternative) => input.length ? input : alternative; const toNumber = (str) => { const value = Number(str); return isNaN(value) ? str : value; }; const toBigint = (str) => { try { return BigInt(str); } catch { return str; } }; var $QueryReader = /*#__PURE__*/Object.freeze({ __proto__: null, array: array, bigint: bigint, boolean: boolean, number: number, params: params, string: string }); const formData$1 = () => $FormDataReader; const headers$1 = () => $HeadersReader; const parameter$1 = () => $ParameterReader; const query$1 = () => $QueryReader; const capitalize = (str) => str.length ? str[0].toUpperCase() + str.slice(1).toLowerCase() : str; function snake$2(str) { if (str.length === 0) return str; // PREFIX // eslint-disable-next-line @typescript-eslint/no-unused-vars let prefix = ""; for (let i = 0; i < str.length; i++) { if (str[i] === "_") prefix += "_"; else break; } if (prefix.length !== 0) str = str.substring(prefix.length); const out = (s) => `${prefix}${s}`; // SNAKE CASE const items = str.split("_"); if (items.length > 1) return out(items.map((s) => s.toLowerCase()).join("_")); // CAMEL OR PASCAL CASE const indexes = []; for (let i = 0; i < str.length; i++) { const code = str.charCodeAt(i); if (65 <= code && code <= 90) indexes.push(i); } for (let i = indexes.length - 1; i > 0; --i) { const now = indexes[i]; const prev = indexes[i - 1]; if (now - prev === 1) indexes.splice(i, 1); } if (indexes.length !== 0 && indexes[0] === 0) indexes.splice(0, 1); if (indexes.length === 0) return str.toLowerCase(); let ret = ""; for (let i = 0; i < indexes.length; i++) { const first = i === 0 ? 0 : indexes[i - 1]; const last = indexes[i]; ret += str.substring(first, last).toLowerCase(); ret += "_"; } ret += str.substring(indexes[indexes.length - 1]).toLowerCase(); return out(ret); } const camel$2 = (str) => unsnake({ plain: (str) => str.length ? str === str.toUpperCase() ? str.toLocaleLowerCase() : `${str[0].toLowerCase()}${str.substring(1)}` : str, snake: (str, i) => i === 0 ? str.toLowerCase() : capitalize(str.toLowerCase()), })(str); const pascal$2 = (str) => unsnake({ plain: (str) => str.length ? `${str[0].toUpperCase()}${str.substring(1)}` : str, snake: capitalize, })(str); const unsnake = (props) => (str) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars let prefix = ""; for (let i = 0; i < str.length; i++) { if (str[i] === "_") prefix += "_"; else break; } if (prefix.length !== 0) str = str.substring(prefix.length); const out = (s) => `${prefix}${s}`; if (str.length === 0) return out(""); const items = str.split("_").filter((s) => s.length !== 0); return items.length === 0 ? out("") : items.length === 1 ? out(props.plain(items[0])) : out(items.map(props.snake).join("")); }; const $convention = (rename) => { const main = (input) => { if (typeof input === "object") if (input === null) return null; else if (Array.isArray(input)) return input.map(main); else if (input instanceof Boolean || input instanceof BigInt || input instanceof Number || input instanceof String) return input.valueOf(); else if (input instanceof Date) return new Date(input); else if (input instanceof Uint8Array || input instanceof Uint8ClampedArray || input instanceof Uint16Array || input instanceof Uint32Array || input instanceof BigUint64Array || input instanceof Int8Array || input instanceof Int16Array || input instanceof Int32Array || input instanceof BigInt64Array || input instanceof Float32Array || input instanceof Float64Array || input instanceof DataView) return input; else return object(input); return input; }; const object = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [rename(key), main(value)])); return main; }; const camel$1 = (method) => ({ ...base(method), any: $convention(camel$2), }); const pascal$1 = (method) => ({ ...base(method), any: $convention(pascal$2), }); const snake$1 = (method) => ({ ...base(method), any: $convention(snake$2), }); const base = (method) => ({ ...is$1(), throws: $throws(`notations.${method}`), }); const $clone = (value) => $cloneMain(value); const $cloneMain = (value) => { if (value === undefined) return undefined; else if (typeof value === "object") if (value === null) return null; else if (Array.isArray(value)) return value.map($cloneMain); else if (value instanceof Date) return new Date(value); else if (value instanceof Uint8Array) return new Uint8Array(value); else if (value instanceof Uint8ClampedArray) return new Uint8ClampedArray(value); else if (value instanceof Uint16Array) return new Uint16Array(value); else if (value instanceof Uint32Array) return new Uint32Array(value); else if (value instanceof BigUint64Array) return new BigUint64Array(value); else if (value instanceof Int8Array) return new Int8Array(value); else if (value instanceof Int16Array) return new Int16Array(value); else if (value instanceof Int32Array) return new Int32Array(value); else if (value instanceof BigInt64Array) return new BigInt64Array(value); else if (value instanceof Float32Array) return new Float32Array(value); else if (value instanceof Float64Array) return new Float64Array(value); else if (value instanceof ArrayBuffer) return value.slice(0); else if (value instanceof SharedArrayBuffer) return value.slice(0); else if (value instanceof DataView) return new DataView(value.buffer.slice(0)); else if (typeof File !== "undefined" && value instanceof File) return new File([value], value.name, { type: value.type }); else if (typeof Blob !== "undefined" && value instanceof Blob) return new Blob([value], { type: value.type }); else if (value instanceof Set) return new Set([...value].map($cloneMain)); else if (value instanceof Map) return new Map([...value].map(([k, v]) => [$cloneMain(k), $cloneMain(v)])); else if (value instanceof WeakSet || value instanceof WeakMap) throw new Error("WeakSet and WeakMap are not supported"); else if (value.valueOf() !== value) return $cloneMain(value.valueOf()); else return Object.fromEntries(Object.entries(value) .map(([k, v]) => [k, $cloneMain(v)]) .filter(([, v]) => v !== undefined)); else if (typeof value === "function") return undefined; return value; }; const $any = (val) => $clone(val); const clone$1 = (method) => ({ ...is$1(), throws: $throws(`misc.${method}`), any: $any, }); const prune$1 = (method) => ({ ...is$1(), throws: $throws(`misc.${method}`), }); class Singleton { closure_; value_; constructor(closure) { this.closure_ = closure; this.value_ = NOT_MOUNTED_YET; } get(...args) { if (this.value_ === NOT_MOUNTED_YET) this.value_ = this.closure_(...args); return this.value_; } } const NOT_MOUNTED_YET = {}; /// @reference https://github.com/piotr-oles/as-proto/blob/main/packages/as-proto/assembly/internal/FixedReader.ts class $ProtobufReader { /** * Read buffer */ buf; /** * Read buffer pointer. */ ptr; /** * DataView for buffer. */ view; constructor(buf) { this.buf = buf; this.ptr = 0; this.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); } index() { return this.ptr; } size() { return this.buf.length; } uint32() { return this.varint32(); } int32() { return this.varint32(); } sint32() { const value = this.varint32(); return (value >>> 1) ^ -(value & 1); } uint64() { return this.varint64(); } int64() { return this.varint64(); } sint64() { const value = this.varint64(); return (value >> BigInt(0x01)) ^ -(value & BigInt(0x01)); } bool() { return this.varint32() !== 0; } float() { const value = this.view.getFloat32(this.ptr, true); this.ptr += 4; return value; } double() { const value = this.view.getFloat64(this.ptr, true); this.ptr += 8; return value; } bytes() { const length = this.uint32(); const from = this.ptr; this.ptr += length; return this.buf.subarray(from, from + length); } string() { return utf8$1.get().decode(this.bytes()); } skip(length) { if (length === 0) while (this.u8() & 0x80) ; else { if (this.index() + length > this.size()) throw new Error("Error on typia.protobuf.decode(): buffer overflow."); this.ptr += length; } } skipType(wireType) { switch (wireType) { case 0 /* ProtobufWire.VARIANT */: this.skip(0); break; case 1 /* ProtobufWire.I64 */: this.skip(8); break; case 2 /* ProtobufWire.LEN */: this.skip(this.uint32()); break; case 3 /* ProtobufWire.START_GROUP */: while ((wireType = this.uint32() & 0x07) !== 4 /* ProtobufWire.END_GROUP */) this.skipType(wireType); break; case 5 /* ProtobufWire.I32 */: this.skip(4); break; default: throw new Error(`Invalid wire type ${wireType} at offset ${this.ptr}.`); } } varint32() { let loaded; let value; value = (loaded = this.u8()) & 0x7f; if (loaded < 0x80) return value; value |= ((loaded = this.u8()) & 0x7f) << 7; if (loaded < 0x80) return value; value |= ((loaded = this.u8()) & 0x7f) << 14; if (loaded < 0x80) return value; value |= ((loaded = this.u8()) & 0x7f) << 21; if (loaded < 0x80) return value; value |= ((loaded = this.u8()) & 0xf) << 28; if (loaded < 0x80) return value; // increment position until there is no continuation bit or until we read 10 bytes if (this.u8() < 0x80) return value; if (this.u8() < 0x80) return value; if (this.u8() < 0x80) return value; if (this.u8() < 0x80) return value; if (this.u8() < 0x80) return value; return value; } varint64() { let loaded; let value; value = (loaded = this.u8n()) & BigInt(0x7f); if (loaded < BigInt(0x80)) return value; value |= ((loaded = this.u8n()) & BigInt(0x7f)) << BigInt(7); if (loaded < BigInt(0x80)) return value; value |= ((loaded = this.u8n()) & BigInt(0x7f)) << BigInt(14); if (loaded < BigInt(0x80)) return value; value |= ((loaded = this.u8n()) & BigInt(0x7f)) << BigInt(21); if (loaded < BigInt(0x80)) return value; value |= ((loaded = this.u8n()) & BigInt(0x7f)) << BigInt(28); if (loaded < BigInt(0x80)) return value; value |= ((loaded = this.u8n()) & BigInt(0x7f)) << BigInt(35); if (loaded < BigInt(0x80)) return value; value |= ((loaded = this.u8n()) & BigInt(0x7f)) << BigInt(42); if (loaded < BigInt(0x80)) return value; value |= ((loaded = this.u8n()) & BigInt(0x7f)) << BigInt(49); if (loaded < BigInt(0x80)) return value; value |= ((loaded = this.u8n()) & BigInt(0x7f)) << BigInt(56); if (loaded < BigInt(0x80)) return value; value |= (this.u8n() & BigInt(0x01)) << BigInt(63); return BigInt.asIntN(64, value); } u8() { return this.view.getUint8(this.ptr++); } u8n() { return BigInt(this.u8()); } } const utf8$1 = /** @__PURE__ */ new Singleton(() => new TextDecoder("utf-8")); const $strlen = (s) => { let b; let i; let c; for (b = i = 0; (c = s.charCodeAt(i++)); b += c >> 11 ? 3 : c >> 7 ? 2 : 1) ; return b; }; /// @reference https://github.com/piotr-oles/as-proto/blob/main/packages/as-proto/assembly/internal/FixedSizer.ts class $ProtobufSizer { /** * Total length. */ len; /** * Position stack. */ pos; /** * Variable length list. */