@jsonjoy.com/json-random
Version:
Random JSON generation, structured JSON by schema generation, no dependencies.
156 lines • 5.64 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TemplateJson = void 0;
const tslib_1 = require("tslib");
const number_1 = require("../number");
const string_1 = require("../string");
const util_1 = require("../util");
const templates = tslib_1.__importStar(require("./templates"));
class TemplateJson {
constructor(template = templates.nil, opts = {}) {
this.template = template;
this.opts = opts;
this.nodes = 0;
this.maxNodes = opts.maxNodes ?? 100;
}
gen() {
return this.generate(this.template);
}
generate(tpl) {
this.nodes++;
while (typeof tpl === 'function')
tpl = tpl();
const template = typeof tpl === 'string' ? [tpl] : tpl;
const type = template[0];
switch (type) {
case 'arr':
return this.generateArray(template);
case 'obj':
return this.generateObject(template);
case 'map':
return this.generateMap(template);
case 'str':
return this.generateString(template);
case 'num':
return this.generateNumber(template);
case 'int':
return this.generateInteger(template);
case 'int64':
return this.generateInt64(template);
case 'float':
return this.generateFloat(template);
case 'bool':
return this.generateBoolean(template);
case 'bin':
return this.generateBin(template);
case 'nil':
return null;
case 'lit':
return this.generateLiteral(template);
case 'or':
return this.generateOr(template);
default:
throw new Error(`Unknown template type: ${type}`);
}
}
minmax(min, max) {
if (this.nodes > this.maxNodes)
return min;
if (this.nodes + max > this.maxNodes)
max = this.maxNodes - this.nodes;
if (max < min)
max = min;
return (0, number_1.int)(min, max);
}
generateArray(template) {
const [, min = 0, max = 5, itemTemplate = 'nil', head = [], tail = []] = template;
const length = this.minmax(min, max);
const result = [];
for (const tpl of head)
result.push(this.generate(tpl));
for (let i = 0; i < length; i++)
result.push(this.generate(itemTemplate));
for (const tpl of tail)
result.push(this.generate(tpl));
return result;
}
generateObject(template) {
const [, fields = []] = template;
const result = {};
for (const field of fields) {
const [keyToken, valueTemplate = 'nil', optionality = 0] = field;
if (optionality) {
if (this.nodes > this.maxNodes)
continue;
if (Math.random() < optionality)
continue;
}
const key = (0, string_1.randomString)(keyToken ?? templates.tokensObjectKey);
const value = this.generate(valueTemplate);
result[key] = value;
}
return result;
}
generateMap(template) {
const [, keyToken, valueTemplate = 'nil', min = 0, max = 5] = template;
const length = this.minmax(min, max);
const result = {};
const token = keyToken ?? templates.tokensObjectKey;
for (let i = 0; i < length; i++) {
const key = (0, string_1.randomString)(token);
const value = this.generate(valueTemplate);
result[key] = value;
}
return result;
}
generateString(template) {
return (0, string_1.randomString)(template[1] ?? templates.tokensHelloWorld);
}
generateNumber([, min, max]) {
if (Math.random() > 0.5)
return this.generateInteger(['int', min, max]);
else
return this.generateFloat(['float', min, max]);
}
generateInteger(template) {
const [, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER] = template;
return (0, number_1.int)(min, max);
}
generateInt64(template) {
const [, min = BigInt('-9223372036854775808'), max = BigInt('9223372036854775807')] = template;
return (0, number_1.int64)(min, max);
}
generateFloat(template) {
const [, min = -Number.MAX_VALUE, max = Number.MAX_VALUE] = template;
let float = Math.random() * (max - min) + min;
float = Math.max(min, Math.min(max, float));
return float;
}
generateBoolean(template) {
const value = template[1];
return value !== undefined ? value : Math.random() < 0.5;
}
generateBin(template) {
const [, min = 0, max = 5, omin = 0, omax = 255] = template;
const length = this.minmax(min, max);
const result = new Uint8Array(length);
for (let i = 0; i < length; i++) {
result[i] = (0, number_1.int)(omin, omax);
}
return result;
}
generateLiteral(template) {
return (0, util_1.clone)(template[1]);
}
generateOr(template) {
const [, ...options] = template;
const index = (0, number_1.int)(0, options.length - 1);
return this.generate(options[index]);
}
}
exports.TemplateJson = TemplateJson;
TemplateJson.gen = (template, opts) => {
const generator = new TemplateJson(template, opts);
return generator.gen();
};
//# sourceMappingURL=TemplateJson.js.map