@jsonjoy.com/json-type
Version:
High-performance JSON Pointer implementation
205 lines • 7.07 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Random = void 0;
const json_random_1 = require("@jsonjoy.com/json-random");
const json_clone_1 = require("@jsonjoy.com/util/lib/json-clone");
const rxjs_1 = require("rxjs");
const ObjType_1 = require("../type/classes/ObjType");
class Random {
gen(type) {
const kind = type.kind();
switch (kind) {
case 'any':
return this.any(type);
case 'arr':
return this.arr(type);
case 'bin':
return this.bin(type);
case 'bool':
return this.bool(type);
case 'con':
return this.con(type);
case 'fn':
return this.fn(type);
case 'fn$':
return this.fn$(type);
case 'map':
return this.map(type);
case 'num':
return this.num(type);
case 'obj':
return this.obj(type);
case 'or':
return this.or(type);
case 'ref':
return this.ref(type);
case 'str':
return this.str(type);
default:
throw new Error(`Unsupported type kind: ${kind}`);
}
}
any(type) {
return json_random_1.RandomJson.generate({ nodeCount: 5 });
}
arr(type) {
let length = Math.round(Math.random() * 10);
const schema = type.getSchema();
const { min, max } = schema;
if (min !== undefined && length < min)
length = min + length;
if (max !== undefined && length > max)
length = max;
const result = [];
if (type._head)
for (const childType of type._head)
result.push(this.gen(childType));
const elementType = type._type;
if (elementType)
for (let i = 0; i < length; i++)
result.push(this.gen(elementType));
if (type._tail)
for (const childType of type._tail)
result.push(this.gen(childType));
return result;
}
bin(type) {
const octets = json_random_1.RandomJson.genString()
.split('')
.map((c) => c.charCodeAt(0));
return new Uint8Array(octets);
}
bool(type) {
return json_random_1.RandomJson.genBoolean();
}
con(type) {
return (0, json_clone_1.cloneBinary)(type.getSchema().value);
}
fn(type) {
return async () => this.gen(type.res);
}
fn$(type) {
return (0, rxjs_1.of)(this.gen(type.res));
}
map(type) {
const length = Math.round(Math.random() * 10);
const res = {};
for (let i = 0; i < length; i++)
res[json_random_1.RandomJson.genString(length)] = this.gen(type._value);
return res;
}
num(type) {
let num = Math.random();
let min = Number.MIN_SAFE_INTEGER;
let max = Number.MAX_SAFE_INTEGER;
const schema = type.getSchema();
const { lt, lte, gt, gte } = schema;
const isIntegerFormat = schema.format && ['i8', 'i16', 'i32', 'i64', 'i', 'u8', 'u16', 'u32', 'u64', 'u'].includes(schema.format);
if (gt !== undefined)
min = gt;
if (gte !== undefined)
if (gte === lte)
return gte;
else
min = isIntegerFormat ? gte : gte + 0.000000000000001;
if (lt !== undefined)
max = lt;
if (lte !== undefined)
max = isIntegerFormat ? lte : lte - 0.000000000000001;
if (min >= max)
return max;
if (schema.format) {
switch (schema.format) {
case 'i8':
min = Math.max(min, -0x80);
max = Math.min(max, 0x7f);
break;
case 'i16':
min = Math.max(min, -0x8000);
max = Math.min(max, 0x7fff);
break;
case 'i32':
min = Math.max(min, -0x80000000);
max = Math.min(max, 0x7fffffff);
break;
case 'i64':
case 'i':
min = Math.max(min, -0x8000000000);
max = Math.min(max, 0x7fffffffff);
break;
case 'u8':
min = Math.max(min, 0);
max = Math.min(max, 0xff);
break;
case 'u16':
min = Math.max(min, 0);
max = Math.min(max, 0xffff);
break;
case 'u32':
min = Math.max(min, 0);
max = Math.min(max, 0xffffffff);
break;
case 'u64':
case 'u':
min = Math.max(min, 0);
max = Math.min(max, 0xffffffffffff);
break;
}
return Math.round(num * (max - min)) + min;
}
num = num * (max - min) + min;
if (Math.random() > 0.7)
num = Math.round(num);
if (num === 0)
return 0;
return num;
}
obj(type) {
const schema = type.getSchema();
const obj = schema.decodeUnknownKeys
? json_random_1.RandomJson.genObject()
: {};
for (const f of type.keys) {
const field = f;
const isOptional = field instanceof ObjType_1.KeyOptType;
if (isOptional && Math.random() > 0.5)
continue;
obj[field.key] = this.gen(field.val);
}
return obj;
}
or(type) {
const types = type.types;
const index = Math.floor(Math.random() * types.length);
return this.gen(types[index]);
}
ref(type) {
if (!type.system)
throw new Error('NO_SYSTEM');
const alias = type.system.resolve(type.getSchema().ref);
return this.gen(alias.type);
}
str(type) {
const schema = type.getSchema();
const isAscii = schema.format === 'ascii' || schema.ascii;
const { min, max } = schema;
let targetLength = Math.round(Math.random() * 10);
if (min !== undefined && targetLength < min)
targetLength = min + targetLength;
if (max !== undefined && targetLength > max)
targetLength = max;
let str = isAscii ? (0, json_random_1.randomString)(['char', 32, 126, targetLength]) : json_random_1.RandomJson.genString(targetLength);
const length = str.length;
if (min !== undefined && length < min)
str = str.padEnd(min, '.');
if (max !== undefined && length > max)
str = str.slice(0, max);
return str;
}
}
exports.Random = Random;
Random.gen = (type) => {
const generator = new Random();
return generator.gen(type);
};
//# sourceMappingURL=Random.js.map