typia
Version:
Superfast runtime validators with only one line
1,855 lines (1,654 loc) • 98.7 kB
JavaScript
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.
*/