json-schema-faker
Version:
JSON-Schema + fake data generators
1,653 lines (1,632 loc) • 212 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/lib/vendor.mjs
var DEPENDENCIES, getDependencies, setDependencies;
var init_vendor = __esm({
"src/lib/vendor.mjs"() {
DEPENDENCIES = {};
getDependencies = () => {
return DEPENDENCIES;
};
setDependencies = (value) => {
Object.assign(DEPENDENCIES, value);
};
}
});
// src/lib/class/Registry.mjs
var Registry, Registry_default;
var init_Registry = __esm({
"src/lib/class/Registry.mjs"() {
Registry = class {
constructor() {
this.data = {};
}
/**
* Unregisters custom format(s)
* @param name
*/
unregister(name) {
if (!name) {
this.data = {};
} else {
delete this.data[name];
}
}
/**
* Registers custom format
*/
register(name, callback) {
this.data[name] = callback;
}
/**
* Register many formats at one shot
*/
registerMany(formats) {
Object.keys(formats).forEach((name) => {
this.data[name] = formats[name];
});
}
/**
* Returns element by registry key
*/
get(name) {
const format = this.data[name];
return format;
}
/**
* Returns the whole registry content
*/
list() {
return this.data;
}
};
Registry_default = Registry;
}
});
// src/lib/api/defaults.mjs
var defaults, defaults_default;
var init_defaults = __esm({
"src/lib/api/defaults.mjs"() {
defaults = {};
defaults_default = defaults;
defaults.defaultInvalidTypeProduct = void 0;
defaults.defaultRandExpMax = 10;
defaults.maxRegexRetry = 100;
defaults.pruneProperties = [];
defaults.ignoreProperties = [];
defaults.ignoreMissingRefs = false;
defaults.failOnInvalidTypes = true;
defaults.failOnInvalidFormat = true;
defaults.alwaysFakeOptionals = false;
defaults.optionalsProbability = null;
defaults.fixedProbabilities = false;
defaults.useExamplesValue = false;
defaults.useDefaultValue = false;
defaults.requiredOnly = false;
defaults.omitNulls = false;
defaults.minItems = 0;
defaults.maxItems = null;
defaults.minLength = 0;
defaults.maxLength = null;
defaults.resolveJsonPath = false;
defaults.reuseProperties = false;
defaults.fillProperties = true;
defaults.sortProperties = false;
defaults.replaceEmptyByRandomValue = false;
defaults.random = Math.random;
defaults.minDateTime = /* @__PURE__ */ new Date("1889-12-31T00:00:00.000Z");
defaults.maxDateTime = /* @__PURE__ */ new Date("1970-01-01T00:00:01.000Z");
defaults.renderTitle = true;
defaults.renderDescription = true;
defaults.renderComment = false;
}
});
// src/lib/class/OptionRegistry.mjs
var OptionRegistry, OptionRegistry_default;
var init_OptionRegistry = __esm({
"src/lib/class/OptionRegistry.mjs"() {
init_Registry();
init_defaults();
OptionRegistry = class extends Registry_default {
constructor() {
super();
this.data = { ...defaults_default };
this._defaults = defaults_default;
}
get defaults() {
return { ...this._defaults };
}
};
OptionRegistry_default = OptionRegistry;
}
});
// src/lib/api/option.mjs
function optionAPI(nameOrOptionMap, optionalValue) {
if (typeof nameOrOptionMap === "string") {
if (typeof optionalValue !== "undefined") {
return registry.register(nameOrOptionMap, optionalValue);
}
return registry.get(nameOrOptionMap);
}
return registry.registerMany(nameOrOptionMap);
}
var registry, option_default;
var init_option = __esm({
"src/lib/api/option.mjs"() {
init_OptionRegistry();
registry = new OptionRegistry_default();
optionAPI.getDefaults = () => registry.defaults;
option_default = optionAPI;
}
});
// src/lib/core/constants.mjs
var ALLOWED_TYPES, SCALAR_TYPES, ALL_TYPES, MOST_NEAR_DATETIME, MIN_INTEGER, MAX_INTEGER, MIN_NUMBER, MAX_NUMBER, constants_default;
var init_constants = __esm({
"src/lib/core/constants.mjs"() {
ALLOWED_TYPES = ["integer", "number", "string", "boolean"];
SCALAR_TYPES = ALLOWED_TYPES.concat(["null"]);
ALL_TYPES = ["array", "object"].concat(SCALAR_TYPES);
MOST_NEAR_DATETIME = 2524608e6;
MIN_INTEGER = -1e8;
MAX_INTEGER = 1e8;
MIN_NUMBER = -100;
MAX_NUMBER = 100;
constants_default = {
ALLOWED_TYPES,
SCALAR_TYPES,
ALL_TYPES,
MIN_NUMBER,
MAX_NUMBER,
MIN_INTEGER,
MAX_INTEGER,
MOST_NEAR_DATETIME
};
}
});
// node_modules/ret/lib/types.js
var require_types = __commonJS({
"node_modules/ret/lib/types.js"(exports2, module2) {
module2.exports = {
ROOT: 0,
GROUP: 1,
POSITION: 2,
SET: 3,
RANGE: 4,
REPETITION: 5,
REFERENCE: 6,
CHAR: 7
};
}
});
// node_modules/ret/lib/sets.js
var require_sets = __commonJS({
"node_modules/ret/lib/sets.js"(exports2) {
var types2 = require_types();
var INTS = () => [{ type: types2.RANGE, from: 48, to: 57 }];
var WORDS = () => {
return [
{ type: types2.CHAR, value: 95 },
{ type: types2.RANGE, from: 97, to: 122 },
{ type: types2.RANGE, from: 65, to: 90 }
].concat(INTS());
};
var WHITESPACE = () => {
return [
{ type: types2.CHAR, value: 9 },
{ type: types2.CHAR, value: 10 },
{ type: types2.CHAR, value: 11 },
{ type: types2.CHAR, value: 12 },
{ type: types2.CHAR, value: 13 },
{ type: types2.CHAR, value: 32 },
{ type: types2.CHAR, value: 160 },
{ type: types2.CHAR, value: 5760 },
{ type: types2.RANGE, from: 8192, to: 8202 },
{ type: types2.CHAR, value: 8232 },
{ type: types2.CHAR, value: 8233 },
{ type: types2.CHAR, value: 8239 },
{ type: types2.CHAR, value: 8287 },
{ type: types2.CHAR, value: 12288 },
{ type: types2.CHAR, value: 65279 }
];
};
var NOTANYCHAR = () => {
return [
{ type: types2.CHAR, value: 10 },
{ type: types2.CHAR, value: 13 },
{ type: types2.CHAR, value: 8232 },
{ type: types2.CHAR, value: 8233 }
];
};
exports2.words = () => ({ type: types2.SET, set: WORDS(), not: false });
exports2.notWords = () => ({ type: types2.SET, set: WORDS(), not: true });
exports2.ints = () => ({ type: types2.SET, set: INTS(), not: false });
exports2.notInts = () => ({ type: types2.SET, set: INTS(), not: true });
exports2.whitespace = () => ({ type: types2.SET, set: WHITESPACE(), not: false });
exports2.notWhitespace = () => ({ type: types2.SET, set: WHITESPACE(), not: true });
exports2.anyChar = () => ({ type: types2.SET, set: NOTANYCHAR(), not: true });
}
});
// node_modules/ret/lib/util.js
var require_util = __commonJS({
"node_modules/ret/lib/util.js"(exports2) {
var types2 = require_types();
var sets = require_sets();
var CTRL = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?";
var SLSH = { "0": 0, "t": 9, "n": 10, "v": 11, "f": 12, "r": 13 };
exports2.strToChars = function(str) {
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);
if (/[[\]{}^$.|?*+()]/.test(c)) {
c = "\\" + c;
}
return c;
});
return str;
};
exports2.tokenizeClass = (str, regexpStr) => {
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: types2.RANGE,
from: (rs[8] || rs[9]).charCodeAt(0),
to: rs[10].charCodeAt(0)
});
} else if (c = rs[12]) {
tokens.push({
type: types2.CHAR,
value: c.charCodeAt(0)
});
} else {
return [tokens, regexp.lastIndex];
}
}
exports2.error(regexpStr, "Unterminated character class");
};
exports2.error = (regexp, msg) => {
throw new SyntaxError("Invalid regular expression: /" + regexp + "/: " + msg);
};
}
});
// node_modules/ret/lib/positions.js
var require_positions = __commonJS({
"node_modules/ret/lib/positions.js"(exports2) {
var types2 = require_types();
exports2.wordBoundary = () => ({ type: types2.POSITION, value: "b" });
exports2.nonWordBoundary = () => ({ type: types2.POSITION, value: "B" });
exports2.begin = () => ({ type: types2.POSITION, value: "^" });
exports2.end = () => ({ type: types2.POSITION, value: "$" });
}
});
// node_modules/ret/lib/index.js
var require_lib = __commonJS({
"node_modules/ret/lib/index.js"(exports2, module2) {
var util = require_util();
var types2 = require_types();
var sets = require_sets();
var positions = require_positions();
module2.exports = (regexpStr) => {
var i = 0, l, c, start = { type: types2.ROOT, stack: [] }, lastGroup = start, last = start.stack, groupStack = [];
var repeatErr = (i2) => {
util.error(regexpStr, `Nothing to repeat at column ${i2 - 1}`);
};
var str = util.strToChars(regexpStr);
l = str.length;
while (i < l) {
c = str[i++];
switch (c) {
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:
if (/\d/.test(c)) {
last.push({ type: types2.REFERENCE, value: parseInt(c, 10) });
} else {
last.push({ type: types2.CHAR, value: c.charCodeAt(0) });
}
}
break;
case "^":
last.push(positions.begin());
break;
case "$":
last.push(positions.end());
break;
case "[":
var not;
if (str[i] === "^") {
not = true;
i++;
} else {
not = false;
}
var classTokens = util.tokenizeClass(str.slice(i), regexpStr);
i += classTokens[1];
last.push({
type: types2.SET,
set: classTokens[0],
not
});
break;
case ".":
last.push(sets.anyChar());
break;
case "(":
var group = {
type: types2.GROUP,
stack: [],
remember: true
};
c = str[i];
if (c === "?") {
c = str[i + 1];
i += 2;
if (c === "=") {
group.followedBy = true;
} else if (c === "!") {
group.notFollowedBy = true;
} else if (c !== ":") {
util.error(
regexpStr,
`Invalid group, character '${c}' after '?' at column ${i - 1}`
);
}
group.remember = false;
}
last.push(group);
groupStack.push(lastGroup);
lastGroup = group;
last = group.stack;
break;
case ")":
if (groupStack.length === 0) {
util.error(regexpStr, `Unmatched ) at column ${i - 1}`);
}
lastGroup = groupStack.pop();
last = lastGroup.options ? lastGroup.options[lastGroup.options.length - 1] : lastGroup.stack;
break;
case "|":
if (!lastGroup.options) {
lastGroup.options = [lastGroup.stack];
delete lastGroup.stack;
}
var stack = [];
lastGroup.options.push(stack);
last = stack;
break;
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: types2.REPETITION,
min,
max,
value: last.pop()
});
} else {
last.push({
type: types2.CHAR,
value: 123
});
}
break;
case "?":
if (last.length === 0) {
repeatErr(i);
}
last.push({
type: types2.REPETITION,
min: 0,
max: 1,
value: last.pop()
});
break;
case "+":
if (last.length === 0) {
repeatErr(i);
}
last.push({
type: types2.REPETITION,
min: 1,
max: Infinity,
value: last.pop()
});
break;
case "*":
if (last.length === 0) {
repeatErr(i);
}
last.push({
type: types2.REPETITION,
min: 0,
max: Infinity,
value: last.pop()
});
break;
default:
last.push({
type: types2.CHAR,
value: c.charCodeAt(0)
});
}
}
if (groupStack.length !== 0) {
util.error(regexpStr, "Unterminated group");
}
return start;
};
module2.exports.types = types2;
}
});
// node_modules/drange/lib/index.js
var require_lib2 = __commonJS({
"node_modules/drange/lib/index.js"(exports2, module2) {
"use strict";
var SubRange = 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;
}
};
var DRange = 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
}));
}
};
module2.exports = DRange;
}
});
// node_modules/randexp/lib/randexp.js
var require_randexp = __commonJS({
"node_modules/randexp/lib/randexp.js"(exports2, module2) {
var ret = require_lib();
var DRange = require_lib2();
var types2 = ret.types;
module2.exports = class RandExp2 {
/**
* @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) {
this.max = regexp.max != null ? regexp.max : RandExp2.prototype.max != null ? RandExp2.prototype.max : 100;
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 types2.ROOT:
case types2.GROUP:
if (token.followedBy || token.notFollowedBy) {
return "";
}
if (token.remember && token.groupNumber === void 0) {
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 types2.POSITION:
return "";
case types2.SET:
var expandedSet = this._expand(token);
if (!expandedSet.length) {
return "";
}
return String.fromCharCode(this._randSelect(expandedSet));
case types2.REPETITION:
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 types2.REFERENCE:
return groups[token.value - 1] || "";
case types2.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 === void 0) {
randexp = new RandExp2(regexp, m);
regexp._randexp = randexp;
} else {
randexp = regexp._randexp;
randexp._setDefaults(regexp);
}
return randexp.gen();
}
/**
* Enables sugary /regexp/.gen syntax.
*/
static sugar() {
RegExp.prototype.gen = function() {
return RandExp2.randexp(this);
};
}
};
}
});
// src/lib/core/random.mjs
function getRandomInteger(min, max) {
min = typeof min === "undefined" ? constants_default.MIN_INTEGER : min;
max = typeof max === "undefined" ? constants_default.MAX_INTEGER : max;
return Math.floor(option_default("random")() * (max - min + 1)) + min;
}
function _randexp(value) {
import_randexp.default.prototype.max = option_default("defaultRandExpMax");
import_randexp.default.prototype.randInt = (a, b) => a + Math.floor(option_default("random")() * (1 + (b - a)));
const re = new import_randexp.default(value);
return re.gen();
}
function pick(collection) {
return collection[Math.floor(option_default("random")() * collection.length)];
}
function shuffle(collection) {
let tmp;
let key;
let length = collection.length;
const copy = collection.slice();
for (; length > 0; ) {
key = Math.floor(option_default("random")() * length);
length -= 1;
tmp = copy[length];
copy[length] = copy[key];
copy[key] = tmp;
}
return copy;
}
function getRandom(min, max) {
return option_default("random")() * (max - min) + min;
}
function number(min, max, defMin, defMax, hasPrecision = false) {
defMin = typeof defMin === "undefined" ? constants_default.MIN_NUMBER : defMin;
defMax = typeof defMax === "undefined" ? constants_default.MAX_NUMBER : defMax;
min = typeof min === "undefined" ? defMin : min;
max = typeof max === "undefined" ? defMax : max;
if (max < min) {
max += min;
}
if (hasPrecision) {
return getRandom(min, max);
}
return getRandomInteger(min, max);
}
function by(type) {
switch (type) {
case "seconds":
return number(0, 60) * 60;
case "minutes":
return number(15, 50) * 612;
case "hours":
return number(12, 72) * 36123;
case "days":
return number(7, 30) * 86412345;
case "weeks":
return number(4, 52) * 604812345;
case "months":
return number(2, 13) * 2592012345;
case "years":
return number(1, 20) * 31104012345;
default:
break;
}
}
function date(step) {
if (step) {
return by(step);
}
let earliest = option_default("minDateTime");
let latest = option_default("maxDateTime");
if (typeof earliest === "string") {
earliest = new Date(earliest);
}
if (typeof latest === "string") {
latest = new Date(latest);
}
const now = (/* @__PURE__ */ new Date()).getTime();
if (typeof earliest === "number") {
earliest = new Date(now + earliest);
}
if (typeof latest === "number") {
latest = new Date(now + latest);
}
return new Date(getRandom(earliest.getTime(), latest.getTime()));
}
var import_randexp, random_default;
var init_random = __esm({
"src/lib/core/random.mjs"() {
import_randexp = __toESM(require_randexp(), 1);
init_option();
init_constants();
random_default = {
pick,
date,
shuffle,
number,
randexp: _randexp
};
}
});
// src/lib/core/utils.mjs
function getLocalRef(obj, path, refs) {
path = decodeURIComponent(path);
if (refs && refs[path])
return clone(refs[path]);
const keyElements = path.replace("#/", "/").split("/");
let schema = obj.$ref && refs && refs[obj.$ref] || obj;
if (!schema && !keyElements[0]) {
keyElements[0] = obj.$ref.split("#/")[0];
}
if (refs && path.includes("#/") && refs[keyElements[0]]) {
schema = refs[keyElements.shift()];
}
if (!keyElements[0])
keyElements.shift();
while (schema && keyElements.length > 0) {
const prop = keyElements.shift();
if (!schema[prop]) {
throw new Error(`Prop not found: ${prop} (${path})`);
}
schema = schema[prop];
}
return schema;
}
function isNumeric(value) {
return typeof value === "string" && RE_NUMERIC.test(value);
}
function isScalar(value) {
return ["number", "boolean"].includes(typeof value);
}
function hasProperties(obj, ...properties) {
return properties.filter((key) => {
return typeof obj[key] !== "undefined";
}).length > 0;
}
function clampDate(value) {
if (value.includes(" ")) {
return new Date(value).toISOString().substr(0, 10);
}
let [year, month, day] = value.split("T")[0].split("-");
month = `0${Math.max(1, Math.min(12, month))}`.slice(-2);
day = `0${Math.max(1, Math.min(31, day))}`.slice(-2);
return `${year}-${month}-${day}`;
}
function clampDateTime(value) {
if (value.includes(" ")) {
return new Date(value).toISOString().substr(0, 10);
}
const [datePart, timePart] = value.split("T");
let [year, month, day] = datePart.split("-");
let [hour, minute, second] = timePart.substr(0, 8).split(":");
month = `0${Math.max(1, Math.min(12, month))}`.slice(-2);
day = `0${Math.max(1, Math.min(31, day))}`.slice(-2);
hour = `0${Math.max(1, Math.min(23, hour))}`.slice(-2);
minute = `0${Math.max(1, Math.min(59, minute))}`.slice(-2);
second = `0${Math.max(1, Math.min(59, second))}`.slice(-2);
return `${year}-${month}-${day}T${hour}:${minute}:${second}.000Z`;
}
function typecast(type, schema, callback) {
const params = {};
switch (type || schema.type) {
case "integer":
case "number":
if (typeof schema.minimum !== "undefined") {
params.minimum = schema.minimum;
}
if (typeof schema.maximum !== "undefined") {
params.maximum = schema.maximum;
}
if (schema.enum) {
let min = Math.max(params.minimum || 0, 0);
let max = Math.min(params.maximum || Infinity, Infinity);
if (schema.exclusiveMinimum && min === schema.minimum) {
min += schema.multipleOf || 1;
}
if (schema.exclusiveMaximum && max === schema.maximum) {
max -= schema.multipleOf || 1;
}
if (min || max !== Infinity) {
schema.enum = schema.enum.filter((x) => {
if (x >= min && x <= max) {
return true;
}
return false;
});
}
}
break;
case "string": {
params.minLength = option_default("minLength") || 0;
params.maxLength = option_default("maxLength") || Number.MAX_SAFE_INTEGER;
if (typeof schema.minLength !== "undefined") {
params.minLength = Math.max(params.minLength, schema.minLength);
}
if (typeof schema.maxLength !== "undefined") {
params.maxLength = Math.min(params.maxLength, schema.maxLength);
}
break;
}
default:
break;
}
let value = callback(params);
if (value === null || value === void 0) {
return null;
}
switch (type || schema.type) {
case "number":
value = isNumeric(value) ? parseFloat(value) : value;
break;
case "integer":
value = isNumeric(value) ? parseInt(value, 10) : value;
break;
case "boolean":
value = !!value;
break;
case "string": {
if (isScalar(value)) {
return value;
}
value = String(value);
const min = Math.max(params.minLength || 0, 0);
const max = Math.min(params.maxLength || Infinity, Infinity);
let prev;
let noChangeCount = 0;
while (value.length < min) {
prev = value;
if (!schema.pattern) {
value += `${random_default.pick([" ", "/", "_", "-", "+", "=", "@", "^"])}${value}`;
} else {
value += random_default.randexp(schema.pattern);
}
if (value === prev) {
noChangeCount += 1;
if (noChangeCount === 3) {
break;
}
} else {
noChangeCount = 0;
}
}
if (value.length > max) {
value = value.substr(0, max);
const pattern = schema.pattern ? new RegExp(schema.pattern) : null;
if (pattern && !pattern.test(value)) {
let temp = value;
const maxRetries = option_default("maxRegexRetry");
const minLength = Math.max(value.length - maxRetries, min);
while (temp.length > minLength && !pattern.test(temp)) {
temp = temp.slice(0, -1);
if (pattern.test(temp)) {
value = temp;
}
}
}
}
switch (schema.format) {
case "date-time":
case "datetime":
value = new Date(clampDateTime(value)).toISOString().replace(/([0-9])0+Z$/, "$1Z");
break;
case "full-date":
case "date":
value = new Date(clampDate(value)).toISOString().substr(0, 10);
break;
case "time":
value = (/* @__PURE__ */ new Date(`1969-01-01 ${value}`)).toISOString().substr(11);
break;
default:
break;
}
break;
}
default:
break;
}
return value;
}
function merge(a, b) {
Object.keys(b).forEach((key) => {
if (typeof b[key] !== "object" || b[key] === null) {
a[key] = b[key];
} else if (Array.isArray(b[key])) {
a[key] = a[key] || [];
b[key].forEach((value, i) => {
if (a.type === "array" && b.type === "array") {
a[key][i] = merge(a[key][i] || {}, value, true);
} else if (Array.isArray(a[key]) && a[key].indexOf(value) === -1) {
a[key].push(value);
}
});
} else if (typeof a[key] !== "object" || a[key] === null || Array.isArray(a[key])) {
a[key] = merge({}, b[key]);
} else {
a[key] = merge(a[key], b[key]);
}
});
return a;
}
function clone(obj, cache = /* @__PURE__ */ new Map()) {
if (!obj || typeof obj !== "object") {
return obj;
}
if (cache.has(obj)) {
return cache.get(obj);
}
if (Array.isArray(obj)) {
const arr = [];
cache.set(obj, arr);
arr.push(...obj.map((x) => clone(x, cache)));
return arr;
}
const clonedObj = {};
cache.set(obj, clonedObj);
return Object.keys(obj).reduce((prev, cur) => {
prev[cur] = clone(obj[cur], cache);
return prev;
}, clonedObj);
}
function short(schema) {
const s = JSON.stringify(schema);
const l = JSON.stringify(schema, null, 2);
return s.length > 400 ? `${l.substr(0, 400)}...` : l;
}
function anyValue() {
return random_default.pick([
false,
true,
null,
-1,
NaN,
Math.PI,
Infinity,
void 0,
[],
{},
// FIXME: use built-in random?
Math.random(),
Math.random().toString(36).substr(2)
]);
}
function hasValue(schema, value) {
if (schema.enum)
return schema.enum.includes(value);
if (schema.const)
return schema.const === value;
}
function notValue(schema, parent) {
const copy = merge({}, parent);
if (typeof schema.minimum !== "undefined") {
copy.maximum = schema.minimum;
copy.exclusiveMaximum = true;
}
if (typeof schema.maximum !== "undefined") {
copy.minimum = schema.maximum > copy.maximum ? 0 : schema.maximum;
copy.exclusiveMinimum = true;
}
if (typeof schema.minLength !== "undefined") {
copy.maxLength = schema.minLength;
}
if (typeof schema.maxLength !== "undefined") {
copy.minLength = schema.maxLength > copy.maxLength ? 0 : schema.maxLength;
}
if (schema.type) {
copy.type = random_default.pick(constants_default.SCALAR_TYPES.filter((x) => {
const types2 = Array.isArray(schema.type) ? schema.type : [schema.type];
return types2.every((type) => {
if (x === "number" || x === "integer") {
return type !== "number" && type !== "integer";
}
return x !== type;
});
}));
} else if (schema.enum) {
let value;
do {
value = anyValue();
} while (schema.enum.indexOf(value) !== -1);
copy.enum = [value];
}
if (schema.required && copy.properties) {
schema.required.forEach((prop) => {
delete copy.properties[prop];
});
}
return copy;
}
function validateValueForSchema(value, schema) {
const schemaHasMin = schema.minimum !== void 0;
const schemaHasMax = schema.maximum !== void 0;
return (schemaHasMin || schemaHasMax) && (!schemaHasMin || value >= schema.minimum) && (!schemaHasMax || value <= schema.maximum);
}
function validate(value, schemas) {
return !schemas.every((schema) => validateValueForSchema(value, schema));
}
function validateValueForOneOf(value, oneOf) {
const validCount = oneOf.reduce((count, schema) => count + (validateValueForSchema(value, schema) ? 1 : 0), 0);
return validCount === 1;
}
function isKey(prop) {
return ["enum", "const", "default", "examples", "required", "definitions", "items", "properties"].includes(prop);
}
function omitProps(obj, props) {
return Object.keys(obj).filter((key) => !props.includes(key)).reduce((copy, k) => {
if (Array.isArray(obj[k])) {
copy[k] = obj[k].slice();
} else {
copy[k] = obj[k] instanceof Object ? merge({}, obj[k]) : obj[k];
}
return copy;
}, {});
}
function template(value, schema) {
if (Array.isArray(value)) {
return value.map((x) => template(x, schema));
}
if (typeof value === "string") {
value = value.replace(/#\{([\w.-]+)\}/g, (_, $1) => schema[$1]);
}
return value;
}
function isEmpty(value) {
return Object.prototype.toString.call(value) === "[object Object]" && !Object.keys(value).length;
}
function shouldClean(key, schema) {
schema = schema.items || schema;
const alwaysFakeOptionals = option_default("alwaysFakeOptionals");
const isRequired = Array.isArray(schema.required) && schema.required.includes(key) || alwaysFakeOptionals;
const wasCleaned = typeof schema.thunk === "function" || schema.additionalProperties && typeof schema.additionalProperties.thunk === "function";
return !isRequired && !wasCleaned;
}
function clean(obj, schema, isArray = false) {
if (!obj || typeof obj !== "object") {
return obj;
}
if (Array.isArray(obj)) {
return obj.map((value) => clean(value, schema == null ? void 0 : schema.items, true)).filter((value) => typeof value !== "undefined");
}
Object.keys(obj).forEach((k) => {
if (isEmpty(obj[k])) {
if (shouldClean(k, schema)) {
delete obj[k];
}
} else {
let subSchema = schema;
if (schema && schema.properties && schema.properties[k]) {
subSchema = schema.properties[k];
}
const value = clean(obj[k], subSchema);
if (!isEmpty(value)) {
obj[k] = value;
}
}
if (typeof obj[k] === "undefined") {
delete obj[k];
}
});
if (!Object.keys(obj).length && isArray) {
return void 0;
}
return obj;
}
var RE_NUMERIC, utils_default;
var init_utils = __esm({
"src/lib/core/utils.mjs"() {
init_option();
init_constants();
init_random();
RE_NUMERIC = /^(0|[1-9][0-9]*)$/;
utils_default = {
hasProperties,
getLocalRef,
omitProps,
typecast,
merge,
clone,
short,
hasValue,
notValue,
anyValue,
validate,
validateValueForSchema,
validateValueForOneOf,
isKey,
template,
shouldClean,
clean,
isEmpty,
clampDate
};
}
});
// src/lib/class/Container.mjs
function proxy(gen) {
return (value, schema, property, rootSchema) => {
let fn = value;
let args = [];
if (typeof value === "object") {
fn = Object.keys(value)[0];
if (Array.isArray(value[fn])) {
args = value[fn];
} else {
args.push(value[fn]);
}
}
const props = fn.split(".");
let ctx = gen();
while (props.length > 1) {
ctx = ctx[props.shift()];
}
value = typeof ctx === "object" ? ctx[props[0]] : ctx;
if (typeof value === "function") {
value = value.apply(ctx, args.map((x) => utils_default.template(x, rootSchema)));
}
if (Object.prototype.toString.call(value) === "[object Object]") {
Object.keys(value).forEach((key) => {
if (typeof value[key] === "function") {
throw new Error(`Cannot resolve value for '${property}: ${fn}', given: ${value}`);
}
});
}
return value;
};
}
var Container, Container_default;
var init_Container = __esm({
"src/lib/class/Container.mjs"() {
init_utils();
Container = class {
constructor() {
this.registry = {};
this.support = {};
}
/**
* Unregister extensions
* @param name
*/
reset(name) {
if (!name) {
this.registry = {};
this.support = {};
} else {
delete this.registry[name];
delete this.support[name];
}
}
/**
* Override dependency given by name
* @param name
* @param callback
*/
extend(name, callback) {
this.registry[name] = callback(this.registry[name]);
if (!this.support[name]) {
this.support[name] = proxy(() => this.registry[name]);
}
}
/**
* Set keyword support by name
* @param name
* @param callback
*/
define(name, callback) {
this.support[name] = callback;
}
/**
* Returns dependency given by name
* @param name
* @returns {Dependency}
*/
get(name) {
if (typeof this.registry[name] === "undefined") {
throw new ReferenceError(`'${name}' dependency doesn't exist.`);
}
return this.registry[name];
}
/**
* Apply a custom keyword
* @param schema
*/
wrap(schema) {
if (!("generate" in schema)) {
const keys = Object.keys(schema);
const context = {};
let length = keys.length;
while (length--) {
const fn = keys[length].replace(/^x-/, "");
const gen = this.support[fn];
if (typeof gen === "function") {
Object.defineProperty(schema, "generate", {
configurable: false,
enumerable: false,
writable: false,
value: (rootSchema, key) => gen.call(context, schema[keys[length]], schema, keys[length], rootSchema, key.slice())
// eslint-disable-line
});
break;
}
}
}
return schema;
}
};
Container_default = Container;
}
});
// src/lib/api/format.mjs
function formatAPI(nameOrFormatMap, callback) {
if (typeof nameOrFormatMap === "undefined") {
return registry2.list();
}
if (typeof nameOrFormatMap === "string") {
if (typeof callback === "function") {
registry2.register(nameOrFormatMap, callback);
} else if (callback === null || callback === false) {
registry2.unregister(nameOrFormatMap);
} else {
return registry2.get(nameOrFormatMap);
}
} else {
registry2.registerMany(nameOrFormatMap);
}
}
var registry2, format_default;
var init_format = __esm({
"src/lib/api/format.mjs"() {
init_Registry();
registry2 = new Registry_default();
format_default = formatAPI;
}
});
// src/lib/core/error.mjs
var ParseError, error_default;
var init_error = __esm({
"src/lib/core/error.mjs"() {
ParseError = class extends Error {
constructor(message, path) {
super();
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
this.name = "ParseError";
this.message = message;
this.path = path;
}
};
error_default = ParseError;
}
});
// src/lib/core/infer.mjs
function matchesType(obj, lastElementInPath, inferredTypeProperties) {
return Object.keys(obj).filter((prop) => {
const isSubschema = subschemaProperties.indexOf(lastElementInPath) > -1;
const inferredPropertyFound = inferredTypeProperties.indexOf(prop) > -1;
if (inferredPropertyFound && !isSubschema) {
return true;
}
return false;
}).length > 0;
}
function inferType(obj, schemaPath) {
const keys = Object.keys(inferredProperties);
for (let i = 0; i < keys.length; i += 1) {
const typeName = keys[i];
const lastElementInPath = schemaPath[schemaPath.length - 1];
if (matchesType(obj, lastElementInPath, inferredProperties[typeName])) {
return typeName;
}
}
}
var inferredProperties, subschemaProperties, infer_default;
var init_infer = __esm({
"src/lib/core/infer.mjs"() {
inferredProperties = {
array: [
"additionalItems",
"items",
"maxItems",
"minItems",
"uniqueItems"
],
integer: [
"exclusiveMaximum",
"exclusiveMinimum",
"maximum",
"minimum",
"multipleOf"
],
object: [
"additionalProperties",
"dependencies",
"maxProperties",
"minProperties",
"patternProperties",
"properties",
"required"
],
string: [
"maxLength",
"minLength",
"pattern",
"format"
]
};
inferredProperties.number = inferredProperties.integer;
subschemaProperties = [
"additionalItems",
"items",
"additionalProperties",
"dependencies",
"patternProperties",
"properties"
];
infer_default = inferType;
}
});
// src/lib/generators/boolean.mjs
function booleanGenerator() {
return option_default("random")() > 0.5;
}
var boolean_default;
var init_boolean = __esm({
"src/lib/generators/boolean.mjs"() {
init_option();
boolean_default = booleanGenerator;
}
});
// src/lib/types/boolean.mjs
var booleanType, boolean_default2;
var init_boolean2 = __esm({
"src/lib/types/boolean.mjs"() {
init_boolean();
booleanType = boolean_default;
boolean_default2 = boolean