UNPKG

@jsonjoy.com/json-random

Version:

Random JSON generation, structured JSON by schema generation, no dependencies.

156 lines 5.64 kB
"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