zocker
Version:
Generate realistic test-data from your Zod-Schemas
1,388 lines (1,356 loc) • 120 kB
JavaScript
import * as z$2 from "zod/v4/core";
import { faker } from "@faker-js/faker";
import * as z4$1 from "zod/v4";
import z4, { z } from "zod/v4";
import Randexp from "randexp";
import { z as z$1 } from "zod/v3";
//#region src/lib/v4/exceptions.ts
var RecursionLimitReachedException$1 = class extends Error {};
var NoGeneratorException$1 = class extends Error {};
var InvalidSchemaException$1 = class extends Error {};
//#endregion
//#region src/lib/v4/generate.ts
/**
* Generate a random value that matches the given schema.
* This get's called recursively until schema generation is done.
*
* @param schema - The schema to generate a value for.
* @param ctx - The context and configuration for the generation process.
* @returns - A pseudo-random value that matches the given schema.
*/
function generate$1(schema, ctx) {
increment_recursion_count$1(schema, ctx);
try {
return generate_value$1(schema, ctx);
} finally {
decrement_recursion_count$1(schema, ctx);
}
}
const generate_value$1 = (schema, generation_context) => {
const reference_generator = generation_context.reference_generators.find((g) => g.schema === schema);
if (reference_generator) return reference_generator.generator(schema, generation_context);
const instanceof_generator = generation_context.instanceof_generators.find((g) => schema instanceof g.schema);
if (instanceof_generator) return instanceof_generator.generator(schema, generation_context);
throw new NoGeneratorException$1(`No generator for schema ${schema._zod.def.type} - You can provide a custom generator in the zocker options`);
};
function increment_recursion_count$1(schema, ctx) {
const previous_depth = ctx.parent_schemas.get(schema) ?? 0;
const current_depth = previous_depth + 1;
if (current_depth >= ctx.recursion_limit) throw new RecursionLimitReachedException$1("Recursion limit reached");
ctx.parent_schemas.set(schema, current_depth);
}
function decrement_recursion_count$1(schema, ctx) {
const previous_depth = ctx.parent_schemas.get(schema) ?? 0;
const current_depth = previous_depth - 1;
ctx.parent_schemas.set(schema, current_depth);
}
//#endregion
//#region src/lib/v4/utils/random.ts
/**
* @deprecated Use `faker.helpers.arrayElement` directly
*/
function pick$1(array) {
return faker.helpers.arrayElement(array);
}
/**
* @deprecated Use `faker.datatype.boolean({ probability })` directly
*/
function weighted_random_boolean$1(true_probability) {
return faker.datatype.boolean({ probability: true_probability });
}
//#endregion
//#region src/lib/v4/generators/default.ts
const generator$5 = (schema, ctx) => {
const should_use_default = weighted_random_boolean$1(ctx.default_options.default_chance);
const default_value = schema._zod.def.defaultValue;
return should_use_default ? default_value : generate$1(schema._zod.def.innerType, ctx);
};
const DefaultGenerator$1 = {
schema: z$2.$ZodDefault,
generator: generator$5,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/any.ts
const literalSchema$1 = z4$1.union([
z4$1.string(),
z4$1.number(),
z4$1.boolean(),
z4$1.null()
]);
const jsonSchema$1 = z4$1.lazy(() => z4$1.union([
literalSchema$1,
z4$1.array(jsonSchema$1),
z4$1.record(z4$1.string(), jsonSchema$1)
]));
const any$2 = z4$1.any();
const potential_schemas$1 = [
z4$1.undefined(),
z4$1.null(),
z4$1.boolean(),
z4$1.number(),
z4$1.string(),
z4$1.bigint(),
z4$1.date(),
z4$1.symbol(),
z4$1.unknown(),
z4$1.nan(),
z4$1.record(z4$1.union([
z4$1.string(),
z4$1.number(),
z4$1.symbol()
]), any$2),
z4$1.array(any$2),
z4$1.map(any$2, any$2),
z4$1.set(any$2),
z4$1.promise(any$2)
].map((schema) => schema.optional());
const generate_any$1 = (schema, ctx) => {
if (ctx.any_options.strategy === "fast") return void 0;
if (ctx.any_options.strategy === "json-compatible") {
const generated$1 = generate$1(jsonSchema$1, ctx);
return generated$1;
}
const schema_to_use = pick$1(potential_schemas$1);
const generated = generate$1(schema_to_use, ctx);
return generated;
};
const generate_unknown$1 = (schema, ctx) => {
if (ctx.unknown_options.strategy === "fast") return void 0;
if (ctx.unknown_options.strategy === "json-compatible") {
const generated$1 = generate$1(jsonSchema$1, ctx);
return generated$1;
}
const schema_to_use = pick$1(potential_schemas$1);
const generated = generate$1(schema_to_use, ctx);
return generated;
};
const AnyGenerator$1 = {
schema: z$2.$ZodAny,
generator: generate_any$1,
match: "instanceof"
};
const UnknownGenerator$1 = {
schema: z$2.$ZodUnknown,
generator: generate_unknown$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/utils/lcm.ts
/**
* Calculates the least common multiple (LCM) of two numbers.
* @param a
* @param b
* @returns
*/
function lcm$3(a, b) {
if (a === Number.MIN_VALUE || a == 0) return b;
if (b === Number.MIN_VALUE || b == 0) return a;
if (typeof a === "bigint") return bigintLCM(BigInt(a), BigInt(b));
return lcmNonIntegers(a.toString(), b.toString());
}
/**
* Calculates the greatest common divisor (GCD) of two numbers using the Euclidean algorithm.
*/
function bigintGCD(a, b) {
while (b !== 0n) [a, b] = [b, a % b];
return a;
}
/**
* Calculates the least common multiple (LCM) of two numbers.
*/
function bigintLCM(a, b) {
return a * b / bigintGCD(a, b);
}
/**
* Converts a decimal string to a fraction represented as a tuple of two bigints (numerator, denominator).
* @param decimalStr Eg "0.75" or "1.5"
* @returns A tuple where the first element is the numerator and the second element is the denominator.
*
* @example "0.75" -> [3n, 4n]
*/
function decimalToFraction(decimalStr) {
if (decimalStr.includes("e")) {
const [base, exponent] = decimalStr.split("e");
if (!base || !exponent) throw new Error(`Invalid number string: ${decimalStr}`);
const baseFraction = decimalToFraction(base);
const exponentValue = BigInt(exponent);
if (exponentValue < 0n) baseFraction[1] *= 10n ** -exponentValue;
else baseFraction[0] *= 10n ** exponentValue;
return baseFraction;
}
if (!decimalStr.includes(".")) return [BigInt(decimalStr), 1n];
const parts = decimalStr.split(".");
const intPart = parts[0];
const fracPart = parts[1] ?? "";
const scale = 10n ** BigInt(fracPart.length);
const numerator = BigInt(intPart + fracPart);
const denominator = scale;
const divisor = bigintGCD(numerator, denominator);
return [numerator / divisor, denominator / divisor];
}
/**
*
* @param aStr
* @param bStr
* @returns
*/
function lcmNonIntegers(aStr, bStr) {
const [numA, denA] = decimalToFraction(aStr);
const [numB, denB] = decimalToFraction(bStr);
const lcmDen = bigintLCM(denA, denB);
const A = numA * (lcmDen / denA);
const B = numB * (lcmDen / denB);
const lcmInt = bigintLCM(A, B);
const result = Number(lcmInt) / Number(lcmDen);
return Number(result.toString());
}
//#endregion
//#region src/lib/v4/generators/numbers.ts
const generate_number$1 = (number_schema, ctx) => {
try {
let proposed_number = NaN;
const semantic_generators = {
age: () => faker.number.int({
min: 0,
max: 120
}),
year: () => faker.number.int({
min: 1200,
max: 3e3
}),
month: () => faker.number.int({
min: 1,
max: 12
}),
"day-of-the-month": () => faker.number.int({
min: 1,
max: 31
}),
hour: () => faker.number.int({
min: 0,
max: 23
}),
minute: () => faker.number.int({
min: 0,
max: 59
}),
second: () => faker.number.int({
min: 0,
max: 59
}),
millisecond: () => faker.number.int({
min: 0,
max: 999
}),
weekday: () => faker.number.int({
min: 0,
max: 6
})
};
const generator$6 = semantic_generators[ctx.semantic_context];
if (!generator$6) throw new Error("No generator found for semantic context - Falling back to random number");
proposed_number = generator$6();
const result = number_schema["~standard"].validate(proposed_number);
if ("then" in result) throw new Error();
if (result.issues) throw new Error();
return result.value;
} catch (e) {}
let is_extreme_value = faker.datatype.boolean({ probability: ctx.number_options.extreme_value_chance });
const formatChecks = number_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckNumberFormat) ?? [];
if (Object.hasOwn(number_schema._zod.def, "format")) formatChecks.push(number_schema);
let is_int = formatChecks.reduce((acc, check) => acc || check._zod.def.format === "int32" || check._zod.def.format === "safeint" || check._zod.def.format === "uint32", false);
const is_finite = true;
const min_checks = number_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckGreaterThan) ?? [];
const max_checks = number_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckLessThan) ?? [];
const min_boundary = min_checks.reduce((prev, curr) => {
const proposedBoundary = [curr._zod.def.value, curr._zod.def.inclusive];
return proposedBoundary[0] > prev[0] ? proposedBoundary : prev;
}, [Number.MIN_SAFE_INTEGER / 2, true]);
const max_boundary = max_checks.reduce((prev, curr) => {
const proposedBoundary = [curr._zod.def.value, curr._zod.def.inclusive];
return proposedBoundary[0] < prev[0] ? proposedBoundary : prev;
}, [Number.MAX_SAFE_INTEGER / 2, true]);
let inclusive_min = min_boundary[1];
let inclusive_max = max_boundary[1];
let min = min_boundary[0];
let max = max_boundary[0];
if (!inclusive_min) {
const float_step = float_step_size$1(min);
min += is_int ? 1 : float_step;
}
if (!inclusive_max) {
const float_step = float_step_size$1(max);
max -= is_int ? 1 : float_step;
}
if (max < min) throw new InvalidSchemaException$1("max must be greater than min if specified");
let value;
if (is_int) value = faker.number.int({
min,
max
});
else {
if (is_extreme_value) {
const use_lower_extreme = faker.datatype.boolean({ probability: .5 });
if (use_lower_extreme) value = -Infinity;
else value = Infinity;
}
value = faker.number.float({
min,
max
});
}
if (value === void 0) throw new Error("Failed to generate Number. This is a bug in the built-in generator");
const multipleof_checks = number_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckMultipleOf) ?? [];
const multipleof = multipleof_checks.reduce((acc, check) => {
const multipleOf = check._zod.def.value;
return lcm$3(acc, multipleOf);
}, Number(multipleof_checks[0]?._zod.def.value ?? Number.MIN_VALUE));
if (multipleof !== Number.MIN_VALUE) {
value = is_int ? faker.number.int({
min,
max,
multipleOf: multipleof !== Number.MIN_VALUE ? multipleof : void 0
}) : faker.number.float({
min,
max,
multipleOf: multipleof !== Number.MIN_VALUE ? multipleof : void 0
});
const result = z.number().multipleOf(multipleof).safeParse(value);
if (!result.success) return generate_number$1(number_schema, ctx);
}
return value;
};
function float_step_size$1(n) {
return Math.max(Number.MIN_VALUE, 2 ** Math.floor(Math.log2(n)) * Number.EPSILON);
}
const NumberGenerator$1 = {
schema: z$2.$ZodNumber,
generator: generate_number$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/tuple.ts
const generate_tuple$1 = (schema, generation_context) => {
const tuple = schema._zod.def.items.map((item) => generate$1(item, generation_context));
return tuple;
};
const TupleGenerator$1 = {
schema: z$2.$ZodTuple,
generator: generate_tuple$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/union.ts
const generate_union$1 = (schema, ctx) => {
const schemas = schema._zod.def.options;
const possible_indexes = new Array(schemas.length).fill(0).map((_, i) => i);
const indexes = faker.helpers.shuffle(possible_indexes);
for (const index of indexes) try {
ctx.path.push(index);
const schema$1 = schemas[index];
return generate$1(schema$1, ctx);
} catch (e) {
if (e instanceof RecursionLimitReachedException$1) continue;
else throw e;
} finally {
ctx.path.pop();
}
throw new RecursionLimitReachedException$1();
};
const UnionGenerator$1 = {
schema: z$2.$ZodUnion,
generator: generate_union$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/semantics.ts
const paragraph_triggers$1 = [
"about",
"description",
"paragraph",
"text",
"body",
"content"
];
const sentence_triggers$1 = [
"sentence",
"line",
"headline",
"heading"
];
const jobtitle_triggers$1 = [
"job",
"title",
"position",
"role",
"occupation",
"profession",
"career"
];
const delimiters$1 = [
",",
";",
":",
"|",
"/",
"\\",
"-",
"_",
" "
];
function get_semantic_flag$1(str) {
str = str.toLowerCase().trim();
for (const delimiter of delimiters$1) str = str.split(delimiter).join(" ");
if (str.includes("name")) {
if (str.includes("first")) return "firstname";
if (str.includes("last")) return "lastname";
return "fullname";
}
if (str.includes("street")) return "street";
if (str.includes("city")) return "city";
if (str.includes("country")) return "country";
if (paragraph_triggers$1.some((t) => str.includes(t))) return "paragraph";
if (sentence_triggers$1.some((t) => str.includes(t))) return "sentence";
if (str.includes("word")) return "word";
if (jobtitle_triggers$1.some((t) => str.includes(t))) return "jobtitle";
if (str.includes("phone")) return "phoneNumber";
if (str.includes("age")) return "age";
if (str.includes("hex")) return "color-hex";
if (str.includes("color")) return "color";
if (str.includes("zip")) return "zip";
if (str.includes("week") && str.includes("day")) return "weekday";
if (str.includes("birthday")) return "birthday";
if (str.includes("year")) return "year";
if (str.includes("month")) return "month";
if (str.includes("day")) return "day-of-the-month";
if (str.includes("hour")) return "hour";
if (str.includes("minute")) return "minute";
if (str.includes("second")) return "second";
if (str.includes("millisecond")) return "millisecond";
if (str.includes("gender") || str.includes("sex")) return "gender";
if (str.includes("municipality") || str.includes("city") || str.includes("town") || str.includes("place") || str.includes("region") || str.includes("state")) return "municipality";
if (str.includes("id")) return "unique-id";
return "unspecified";
}
//#endregion
//#region src/lib/v4/generators/object.ts
const generate_object$1 = (object_schema, ctx) => {
const mock_entries = [];
Object.entries(object_schema._zod.def.shape).forEach((entry) => {
const key = entry[0];
const property_schema = entry[1];
const prev_semantic_context = ctx.semantic_context;
const semantic_flag = get_semantic_flag$1(String(key));
try {
ctx.path.push(key);
ctx.semantic_context = semantic_flag;
const generated_value = generate$1(property_schema, ctx);
mock_entries.push([key, generated_value]);
} finally {
ctx.path.pop();
ctx.semantic_context = prev_semantic_context;
}
});
return Object.fromEntries(mock_entries);
};
const ObjectGenerator$1 = {
schema: z$2.$ZodObject,
generator: generate_object$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/set.ts
const generate_set$1 = (schema, ctx) => {
const size = faker.number.int({
min: ctx.set_options.min,
max: ctx.set_options.max
});
const set = /* @__PURE__ */ new Set();
try {
for (let i = 0; i < size; i++) try {
ctx.path.push(i);
const value = generate$1(schema._zod.def.valueType, ctx);
set.add(value);
} finally {
ctx.path.pop();
}
} catch (error) {
if (error instanceof RecursionLimitReachedException$1) return set;
throw error;
}
return set;
};
const SetGenerator$1 = {
schema: z$2.$ZodSet,
generator: generate_set$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/map.ts
const generate_map$1 = (schema, ctx) => {
const size = faker.number.int({
min: ctx.map_options.min,
max: ctx.map_options.max
});
const map = /* @__PURE__ */ new Map();
try {
const keys = [];
for (let i = 0; i < size; i++) {
const key = generate$1(schema._zod.def.keyType, ctx);
keys.push(key);
}
for (const key of keys) {
let prev_semantic_context = ctx.semantic_context;
try {
ctx.path.push(key);
ctx.semantic_context = "key";
const value = generate$1(schema._zod.def.valueType, ctx);
map.set(key, value);
} finally {
ctx.path.pop();
ctx.semantic_context = prev_semantic_context;
}
}
} catch (error) {
if (error instanceof RecursionLimitReachedException$1) return map;
throw error;
}
return map;
};
const MapGenerator$1 = {
schema: z$2.$ZodMap,
generator: generate_map$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/dates.ts
const MIN_DATE = /* @__PURE__ */ new Date(-864e13);
const MAX_DATE = /* @__PURE__ */ new Date(864e13);
const generate_date$1 = (date_schema, ctx) => {
const min_checks = date_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckGreaterThan) ?? [];
const max_checks = date_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckLessThan) ?? [];
const min = min_checks.reduce((acc, check) => {
const value = check._zod.def.value;
return value > acc ? value : acc;
}, MIN_DATE);
const max = max_checks.reduce((acc, check) => {
const value = check._zod.def.value;
return value < acc ? value : acc;
}, MAX_DATE);
if (min && max && max < min) throw new InvalidSchemaException$1("max date is less than min date");
if (min === MIN_DATE && max === MAX_DATE) return faker.date.recent({ days: 100 });
if (min !== MIN_DATE && max === MAX_DATE) return faker.date.future({ refDate: min });
if (min === MIN_DATE && max !== MAX_DATE) return faker.date.past({ refDate: max });
return faker.date.between({
from: min,
to: max ?? Date.now() + 1e7
});
};
const DateGenerator$1 = {
schema: z$2.$ZodDate,
generator: generate_date$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/record.ts
const generate_record$1 = (schema, ctx) => {
const record = {};
try {
const keys = generateKeys(schema, ctx);
for (const key of keys) {
let value;
let prev_semantic_context = ctx.semantic_context;
try {
ctx.path.push(key);
ctx.semantic_context = "key";
value = generate$1(schema._zod.def.valueType, ctx);
} finally {
ctx.path.pop();
ctx.semantic_context = prev_semantic_context;
}
record[key] = value;
}
} catch (error) {
if (error instanceof RecursionLimitReachedException$1) return record;
throw error;
}
return record;
};
/**
* Geneartes keys for a record
* @param schema
* @param ctx
*/
function generateKeys(schema, ctx) {
const keySchema = schema._zod.def.keyType;
if (keySchema._zod.values) return [...keySchema._zod.values];
const numKeys = faker.number.int({
min: ctx.record_options.min,
max: ctx.record_options.max
});
const keys = [];
while (keys.length < numKeys) {
const key = generate$1(schema._zod.def.keyType, ctx);
if (key != void 0) keys.push(key);
}
return keys;
}
const RecordGenerator$1 = {
schema: z$2.$ZodRecord,
generator: generate_record$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/bigint.ts
const generate_bigint$1 = (bigint_schema, ctx) => {
const multiple_of_checks = bigint_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckMultipleOf) ?? [];
const min_checks = bigint_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckGreaterThan) ?? [];
const max_checks = bigint_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckLessThan) ?? [];
const min = min_checks.reduce((acc, check) => {
const min$1 = check._zod.def.value;
return min$1 > acc ? min$1 : acc;
}, BigInt(Number.MIN_SAFE_INTEGER));
const max = max_checks.reduce((acc, check) => {
const max$1 = check._zod.def.value;
return max$1 < acc ? max$1 : acc;
}, BigInt(Number.MAX_SAFE_INTEGER));
const multipleof = multiple_of_checks.reduce((acc, check) => {
const multipleOf = check._zod.def.value;
return lcm$2(acc, multipleOf);
}, 1n);
let value = faker.number.bigInt({
min,
max
});
const next_larger_multiple = value + (multipleof - value % multipleof);
const next_smaller_multiple = value - value % multipleof;
if (next_larger_multiple <= max) value = next_larger_multiple;
else if (next_smaller_multiple >= min) value = next_smaller_multiple;
else throw new InvalidSchemaException$1("Cannot generate a valid BigInt that satisfies the constraints");
return value;
};
function lcm$2(a, b) {
return a * b / gcd$2(a, b);
}
function gcd$2(a, b) {
if (b === 0n) return a;
return gcd$2(b, a % b);
}
const BigintGenerator$1 = {
schema: z$2.$ZodBigInt,
generator: generate_bigint$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/promise.ts
const generate_promise$1 = (schema, generation_context) => {
return generate$1(schema._zod.def.innerType, generation_context);
};
const PromiseGenerator$1 = {
schema: z$2.$ZodPromise,
generator: generate_promise$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/lazy.ts
const generate_lazy$1 = (schema, generation_context) => {
const getter = schema._zod.def.getter();
return generate$1(getter, generation_context);
};
const LazyGenerator$1 = {
schema: z$2.$ZodLazy,
generator: generate_lazy$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/symbol.ts
const generate_symbol$1 = () => {
const symbol_key = faker.string.alphanumeric();
return Symbol.for(symbol_key);
};
const SymbolGenerator$1 = {
schema: z$2.$ZodSymbol,
generator: generate_symbol$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/enum.ts
const generate_enum$1 = (schema, ctx) => {
const values = Object.values(schema._zod.def.entries);
const value = pick$1(values);
return value;
};
const EnumGenerator$1 = {
schema: z$2.$ZodEnum,
generator: generate_enum$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/boolean.ts
const generate_boolean$1 = () => {
return faker.datatype.boolean();
};
const BooleanGenerator$1 = {
schema: z$2.$ZodBoolean,
generator: generate_boolean$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/string/length-constraints.ts
/**
* Returns the length constraints that apply for a given schema. If multiple constraints
* are specified (eg. multiple min-lengths), the most restrictive is applied
*
* @param string_schema The schema to get length constraints for
* @returns The length constraints
* @throws InvalidSchemaException if the length constraints are impossible to satisfy (eg: min > max)
*/
function getLengthConstraints(string_schema) {
const min_length_checks = string_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckMinLength) ?? [];
const max_length_checks = string_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckMaxLength) ?? [];
const exact_length_checks = string_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckLengthEquals) ?? [];
const min_length = min_length_checks.reduce((acc, check) => {
const value = check._zod.def.minimum;
return value > acc ? value : acc;
}, 0);
const max_length = max_length_checks.reduce((acc, check) => {
const value = check._zod.def.maximum;
return value < acc ? value : acc;
}, Infinity);
if (min_length > max_length) throw new InvalidSchemaException$1("min length is greater than max length");
let exact_length = null;
for (const exact_length_check of exact_length_checks) {
const suggested_length = exact_length_check._zod.def.length;
if (exact_length == null) exact_length = suggested_length;
else if (suggested_length != exact_length) throw new InvalidSchemaException$1("Cannot generate a string with conflictung exact length constraints");
}
if (exact_length !== null) {
if (min_length > exact_length) throw new InvalidSchemaException$1("min length is greater than exact length");
if (max_length < exact_length) throw new InvalidSchemaException$1("max length is less than exact length");
}
return {
min: min_length,
max: max_length,
exact: exact_length
};
}
//#endregion
//#region src/lib/v4/generators/array.ts
const generate_array$1 = (array_schema, ctx) => {
const length_constraints$1 = getLengthConstraints(array_schema);
const min = Math.max(length_constraints$1.min, ctx.array_options.min);
const max = Math.min(length_constraints$1.max, ctx.array_options.max);
if (min > max) throw new InvalidSchemaException$1("min length is greater than max length");
const length = length_constraints$1.exact ?? faker.number.int({
min,
max
});
const generated_array = [];
try {
for (let i = 0; i < length; i++) {
let generated_value;
try {
ctx.path.push(i);
generated_value = generate$1(array_schema._zod.def.element, ctx);
} finally {
ctx.path.pop();
}
generated_array.push(generated_value);
}
return generated_array;
} catch (error) {
if (!(error instanceof RecursionLimitReachedException$1)) throw error;
if (min !== 0) throw error;
if (length_constraints$1.exact !== null && length_constraints$1.exact !== 0) throw error;
return [];
}
};
const ArrayGenerator$1 = {
schema: z$2.$ZodArray,
generator: generate_array$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/optional.ts
const generator$4 = (schema, ctx) => {
const should_be_undefined = weighted_random_boolean$1(ctx.optional_options.undefined_chance);
try {
return should_be_undefined ? void 0 : generate$1(schema._zod.def.innerType, ctx);
} catch (e) {
if (e instanceof RecursionLimitReachedException$1) return void 0;
else throw e;
}
};
const OptionalGenerator$1 = {
schema: z$2.$ZodOptional,
generator: generator$4,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/nullable.ts
const generator$3 = (schema, ctx) => {
const should_be_null = weighted_random_boolean$1(ctx.nullable_options.null_chance);
try {
return should_be_null ? null : generate$1(schema._zod.def.innerType, ctx);
} catch (e) {
if (e instanceof RecursionLimitReachedException$1) return null;
else throw e;
}
};
const NullableGenerator$1 = {
schema: z$2.$ZodNullable,
generator: generator$3,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/intersection/index.ts
const generate_intersection$1 = (schema, ctx) => {
const schema_1 = schema._zod.def.left;
const schema_2 = schema._zod.def.right;
const merged = merge_schema$1(schema_1, schema_2);
return generate$1(merged, ctx);
};
const merge_schema$1 = (schema_1, schema_2) => {
if (schema_1 instanceof z$2.$ZodNumber && schema_2 instanceof z$2.$ZodNumber) {
const combined = z.number();
combined._zod.def.checks = [...schema_1._zod.def.checks ?? [], ...schema_2._zod.def.checks ?? []];
return combined;
}
if (schema_1 instanceof z$2.$ZodString && schema_2 instanceof z$2.$ZodString) {
const combined = z.string();
combined._zod.def.checks = [...schema_1._zod.def.checks ?? [], ...schema_2._zod.def.checks ?? []];
return combined;
}
if (schema_1 instanceof z$2.$ZodBoolean && schema_2 instanceof z$2.$ZodBoolean) return z.boolean();
if (schema_1 instanceof z$2.$ZodLiteral && schema_2 instanceof z$2.$ZodLiteral) {
const common_values = setIntersection(new Set(schema_1._zod.def.values), new Set(schema_2._zod.def.values));
if (common_values.size === 0) throw new InvalidSchemaException$1("Cannot generate intersection of literal schemas with no common values");
return z.literal(Array.from(common_values));
}
if (schema_1 instanceof z$2.$ZodSymbol && schema_2 instanceof z$2.$ZodType) return z.symbol();
if (schema_1 instanceof z$2.$ZodUnion && schema_2 instanceof z$2.$ZodUnion) {
const combined = [];
for (const option1 of schema_1._zod.def.options) for (const option2 of schema_2._zod.def.options) try {
combined.push(merge_schema$1(option1, option2));
} catch (e) {
continue;
}
if (combined.length == 0) throw new NoGeneratorException$1("Could not generate intersection of unions");
return z.union(combined);
}
if (schema_1 instanceof z$2.$ZodEnum && schema_2 instanceof z$2.$ZodEnum) {
const shared = setIntersection(new Set(Object.values(schema_1._zod.def.entries)), new Set(Object.values(schema_2._zod.def.entries)));
return z.enum(Array.from(shared));
}
if (schema_1 instanceof z$2.$ZodArray && schema_2 instanceof z$2.$ZodArray) return z.array(merge_schema$1(schema_1._zod.def.element, schema_2._zod.def.element));
throw new NoGeneratorException$1("ZodIntersections only have very limited support at the moment.");
};
const IntersectionGenerator$1 = {
schema: z$2.$ZodIntersection,
generator: generate_intersection$1,
match: "instanceof"
};
function setIntersection(a, b) {
return new Set([...a].filter((x) => b.has(x)));
}
//#endregion
//#region src/lib/v4/generators/readonly.ts
const generate_readonly$1 = (readonly_schema, ctx) => {
const inner = generate$1(readonly_schema._zod.def.innerType, ctx);
if (typeof inner === "object") Object.freeze(inner);
return inner;
};
const ReadonlyGenerator$1 = {
schema: z$2.$ZodReadonly,
generator: generate_readonly$1,
match: "instanceof"
};
//#endregion
//#region src/lib/v4/generators/string/content-constraints.ts
/**
* Returns the constraints on the _content_ of a string. These include:
* - `starts_with`, `ends_with` and `includes`
*
* @param string_schema The string schema to get the Content Constarints for.
* @returns The constaraints on the content of the string.
*/
function getContentConstraints(string_schema) {
const starts_with_checks = string_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckStartsWith) ?? [];
const ends_with_checks = string_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckEndsWith) ?? [];
const includes_checks = string_schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckIncludes) ?? [];
const starts_with = starts_with_checks.reduce((acc, check) => {
const suggested_starts_with = check._zod.def.prefix;
if (acc.length == suggested_starts_with.length && acc != suggested_starts_with) throw new InvalidSchemaException$1("startsWith constraints are not compatible - The Schema cannot be satisfied");
const longer = suggested_starts_with.length > acc.length ? suggested_starts_with : acc;
const shorter = suggested_starts_with.length < acc.length ? suggested_starts_with : acc;
if (!longer.startsWith(shorter)) throw new InvalidSchemaException$1("startsWith constraints are not compatible - The Schema cannot be satisfied");
return longer;
}, "");
const ends_with = ends_with_checks.reduce((acc, check) => {
const suggested_ends_with = check._zod.def.suffix;
if (acc.length == suggested_ends_with.length && acc != suggested_ends_with) throw new InvalidSchemaException$1("endsWith constraints are not compatible - The Schema cannot be satisfied");
const longer = suggested_ends_with.length > acc.length ? suggested_ends_with : acc;
const shorter = suggested_ends_with.length < acc.length ? suggested_ends_with : acc;
if (!longer.endsWith(shorter)) throw new InvalidSchemaException$1("endsWith constraints are not compatible - The Schema cannot be satisfied");
return longer;
}, "");
const includes = includes_checks.map((c) => c._zod.def.includes).filter((include) => !starts_with.includes(include)).filter((include) => !ends_with.includes(include));
return {
starts_with,
ends_with,
includes
};
}
//#endregion
//#region src/lib/v4/generators/string/legacy.ts
/**
* If the schema has checks for a legacy format (eg `z.string().email()` instead of `z.string()`), this will
* call the apropriate generator.
*
* @returns The generated string, or `null` if no legacy format was used
*/
function legacyFormatString(schema, ctx) {
const checks = schema._zod.def.checks ?? [];
const format_checks = checks.filter((check) => check instanceof z4.ZodStringFormat);
const date_checks = format_checks.filter((check) => check instanceof z4.iso.ZodISODate);
if (date_checks.length > 0) {
const date_schema = z4.iso.date();
date_schema._zod.def.checks = checks;
return generate$1(date_schema, ctx);
}
const datetime_checks = format_checks.filter((check) => check instanceof z4.iso.ZodISODateTime);
if (datetime_checks.length > 0) {
const datetime_schema = z4.iso.datetime();
datetime_schema._zod.def.checks = checks;
return generate$1(datetime_schema, ctx);
}
const duration_checks = format_checks.filter((check) => check instanceof z4.iso.ZodISODuration);
if (duration_checks.length > 0) {
const duration_schema = z4.iso.duration();
duration_schema._zod.def.checks = checks;
return generate$1(duration_schema, ctx);
}
const time_checks = format_checks.filter((check) => check instanceof z4.iso.ZodISOTime);
if (time_checks.length > 0) {
const time_schema = z4.iso.time();
time_schema._zod.def.checks = checks;
return generate$1(time_schema, ctx);
}
const email_checks = format_checks.filter((check) => check instanceof z4.ZodEmail);
if (email_checks.length > 0) {
const email_schema = z4.email();
email_schema._zod.def.checks = checks;
return generate$1(email_schema, ctx);
}
const guid_checks = checks.filter((c) => c instanceof z4.ZodGUID);
if (guid_checks.length > 0) {
const guid_schema = z4.guid();
guid_schema._zod.def.checks = checks;
return generate$1(guid_schema, ctx);
}
const uuid_checks = checks.filter((c) => c instanceof z4.ZodUUID);
if (uuid_checks.length > 0) {
const check = uuid_checks[0];
const uuid_schema = z4.uuid({ version: check.def.version });
uuid_schema._zod.def.checks = checks;
return generate$1(uuid_schema, ctx);
}
const url_checks = checks.filter((c) => c instanceof z4.ZodURL);
if (url_checks.length > 0) {
const url_schema = z4.url();
url_schema._zod.def.checks = checks;
return generate$1(url_schema, ctx);
}
const cuid_checks = checks.filter((c) => c instanceof z4.ZodCUID);
if (cuid_checks.length > 0) {
const cuid_schema = z4.cuid();
cuid_schema._zod.def.checks = checks;
return generate$1(cuid_schema, ctx);
}
const cuid2_checks = checks.filter((c) => c instanceof z4.ZodCUID2);
if (cuid2_checks.length > 0) {
const cuid2_schema = z4.cuid2();
cuid2_schema._zod.def.checks = checks;
return generate$1(cuid2_schema, ctx);
}
const ulid_checks = checks.filter((c) => c instanceof z4.ZodULID);
if (ulid_checks.length > 0) {
const ulid_schema = z4.ulid();
ulid_schema._zod.def.checks = checks;
return generate$1(ulid_schema, ctx);
}
const emoji_checks = checks.filter((c) => c instanceof z4.ZodEmoji);
if (emoji_checks.length > 0) {
const emoji_schema = z4.emoji();
emoji_schema._zod.def.checks = checks;
return generate$1(emoji_schema, ctx);
}
const nanoid_checks = checks.filter((c) => c instanceof z4.ZodNanoID);
if (nanoid_checks.length > 0) {
const nanoid_schema = z4.nanoid();
nanoid_schema._zod.def.checks = checks;
return generate$1(nanoid_schema, ctx);
}
const ipv6_checks = checks.filter((c) => c instanceof z4.ZodIPv6);
if (ipv6_checks.length > 0) {
const ipv6_schema = z4.ipv6();
ipv6_schema._zod.def.checks = checks;
return generate$1(ipv6_schema, ctx);
}
const ipv4_checks = checks.filter((c) => c instanceof z4.ZodIPv4);
if (ipv4_checks.length > 0) {
const ipv4_schema = z4.ipv4();
ipv4_schema._zod.def.checks = checks;
return generate$1(ipv4_schema, ctx);
}
const e164_checks = checks.filter((c) => c instanceof z4.ZodE164);
if (e164_checks.length > 0) {
const e164_schema = z4.e164();
e164_schema._zod.def.checks = checks;
return generate$1(e164_schema, ctx);
}
const cidrv4_checks = checks.filter((c) => c instanceof z4.ZodCIDRv4);
if (cidrv4_checks.length > 0) {
const cidrv4_schema = z4.cidrv4();
cidrv4_schema._zod.def.checks = checks;
return generate$1(cidrv4_schema, ctx);
}
const cidrv6_checks = checks.filter((c) => c instanceof z4.ZodCIDRv6);
if (cidrv6_checks.length > 0) {
const cidrv6_schema = z4.cidrv6();
cidrv6_schema._zod.def.checks = checks;
return generate$1(cidrv6_schema, ctx);
}
const base64_url_checks = checks.filter((c) => c instanceof z4.ZodBase64URL);
if (base64_url_checks.length > 0) {
const base64_url_schema = z4.base64url();
base64_url_schema._zod.def.checks = checks;
return generate$1(base64_url_schema, ctx);
}
const base64_checks = checks.filter((c) => c instanceof z4.ZodBase64);
if (base64_checks.length > 0) {
const base64_schema = z4.base64();
base64_schema._zod.def.checks = checks;
return generate$1(base64_schema, ctx);
}
const jwt_checks = checks.filter((c) => c instanceof z4.ZodJWT);
if (jwt_checks.length > 0) {
const jwt_schema = z4.jwt();
jwt_schema._zod.def.checks = checks;
return generate$1(jwt_schema, ctx);
}
const ksuid_checks = checks.filter((c) => c instanceof z4.ZodKSUID);
if (ksuid_checks.length > 0) {
const ksuid_schema = z4.ksuid();
ksuid_schema._zod.def.checks = checks;
return generate$1(ksuid_schema, ctx);
}
const xid_checks = checks.filter((c) => c instanceof z4.ZodXID);
if (xid_checks.length > 0) {
const xid_schema = z4.xid();
xid_schema._zod.def.checks = checks;
return generate$1(xid_schema, ctx);
}
return null;
}
//#endregion
//#region src/lib/v4/generators/string/plain.ts
const generate_string$1 = (string_schema, ctx) => {
const legacy = legacyFormatString(string_schema, ctx);
if (legacy !== null) return legacy;
const lengthConstraints = getLengthConstraints(string_schema);
const contentConstraints = getContentConstraints(string_schema);
const regexConstraints = getRegexConstraints(string_schema);
if (regexConstraints.length > 0) {
if (regexConstraints.length > 1) throw new NoGeneratorException$1("Zocker's included regex generator currently does support multiple regex checks on the same string. Provide a custom generator instead.");
if (lengthConstraints.exact !== null) throw new NoGeneratorException$1("Zocker's included regex generator currently does not work together with length constraints (minLength, maxLength, length). Provide a custom generator instead.");
if (contentConstraints.starts_with != "" || contentConstraints.ends_with != "" || contentConstraints.includes.length > 0) throw new NoGeneratorException$1("Zocker's included regex generator currently does not work together with startWith, endsWith or includes constraints. Provide a custom generator instead.");
const regex$1 = regexConstraints[0];
const randexp = new Randexp(regex$1);
randexp.randInt = (min, max) => faker.number.int({
min,
max
});
return randexp.gen();
}
try {
const human_readable_string = generateStringWithoutFormat(ctx, lengthConstraints, contentConstraints);
if (stringMatchesConstraints(human_readable_string, lengthConstraints, contentConstraints)) return human_readable_string;
} catch (e) {}
lengthConstraints.min = Math.max(lengthConstraints.min, contentConstraints.starts_with.length, contentConstraints.ends_with.length, ...contentConstraints.includes.map((s) => s.length));
const length = lengthConstraints.exact ?? faker.number.int({
min: lengthConstraints.min,
max: lengthConstraints.max == Infinity ? lengthConstraints.min + 5e4 : lengthConstraints.max
});
const generated_length = length - contentConstraints.starts_with.length - contentConstraints.ends_with.length - contentConstraints.includes.reduce((a, b) => a + b.length, 0);
return contentConstraints.starts_with + faker.string.sample(generated_length) + contentConstraints.includes.join("") + contentConstraints.ends_with;
};
const StringGenerator$1 = {
schema: z$2.$ZodString,
generator: generate_string$1,
match: "instanceof"
};
/**
* Takes in a ZodType & Returns a list of 0 or more regexes it has to fulfill.
*
* @example `z.string().regex(/abc/) -> [/abc/]`
* @param schema
*/
function getRegexConstraints(schema) {
const regex_checks = schema._zod.def.checks?.filter((c) => c instanceof z$2.$ZodCheckRegex) ?? [];
return regex_checks.map((check) => check._zod.def.pattern);
}
function generateStringWithoutFormat(ctx, lc, cc) {
const semantic_generators = {
fullname: faker.person.fullName,
firstname: faker.person.firstName,
lastname: faker.person.lastName,
street: faker.location.street,
city: faker.location.city,
country: faker.location.country,
zip: faker.location.zipCode,
phoneNumber: faker.phone.number,
paragraph: faker.lorem.paragraph,
sentence: faker.lorem.sentence,
word: faker.lorem.word,
jobtitle: faker.person.jobTitle,
color: color$1,
gender: faker.person.gender,
municipality: faker.location.city,
"color-hex": () => faker.color.rgb({
prefix: "#",
casing: "lower"
}),
weekday: faker.date.weekday,
"unique-id": faker.string.uuid,
key: () => faker.lorem.word(),
unspecified: () => faker.lorem.paragraphs(faker.number.int({
min: 1,
max: 5
}))
};
const generator$6 = semantic_generators[ctx.semantic_context];
if (!generator$6) throw new Error("No semantic generator found for context - falling back to random string");
const proposed_string = generator$6();
return proposed_string;
}
function color$1() {
const generators = [faker.color.human, faker.color.rgb];
return pick$1(generators)();
}
function stringMatchesConstraints(str, lc, cc) {
if (lc.exact && str.length !== lc.exact) return false;
if (lc.min && str.length < lc.min) return false;
if (lc.max && str.length > lc.max) return false;
if (cc.starts_with && !str.startsWith(cc.starts_with)) return false;
if (cc.ends_with && !str.endsWith(cc.ends_with)) return false;
if (cc.includes.length > 0 && !cc.includes.every((i) => str.includes(i))) return false;
return true;
}
//#endregion
//#region src/lib/v4/generators/string/cuid.ts
const CUID_MIN_LENGTH = 9;
const CUID_COMMON_LENGHT = 25;
const CUID2_MIN_LENGTH = 2;
const CUID2_COMMON_LENGTH = 24;
/**
* Generates a valid CUID. The CUID format is as follows:
* 1. The char 'c'
* 2. 8 or more characters [a-zA-Z0-9]. Technically more are allowed, just not - or whitespace.
*
* @param schema A CUID Schema
* @param generation_context The relevant generation context
* @returns A CUID that conforms to the given schema
* @throws InvalidSchemaException if the Schema cannot be satisfied
*/
const generate_cuid = (schema, generation_context) => {
const length_constraints$1 = getLengthConstraints(schema);
const content_constraints$1 = getContentConstraints(schema);
const exact_length_too_short = length_constraints$1.exact != null && length_constraints$1.exact < CUID_MIN_LENGTH;
const max_length_too_short = length_constraints$1.max < CUID_MIN_LENGTH;
if (exact_length_too_short || max_length_too_short) throw new InvalidSchemaException$1("CUID cannot be less than 9 characters long");
if (content_constraints$1.starts_with != "" && !content_constraints$1.starts_with.startsWith("c")) throw new InvalidSchemaException$1("CUID must start with a 'c'");
const length = length_constraints$1.exact ?? faker.number.int({
min: Math.max(length_constraints$1.min, CUID_MIN_LENGTH),
max: length_constraints$1.max == Infinity ? length_constraints$1.min + CUID_COMMON_LENGHT : length_constraints$1.max
});
return generateCUIDofLength(length);
};
/**
* Generates a valid CUID2. The CUID2 format is as follows:
* - One alpha character
* - 1 or more alphanumeric characters
*
* @param schema A CUID2 Schema
* @param generation_context The relevant generation context
* @returns A CUID2 that conforms to the given schema
* @throws InvalidSchemaException if the Schema cannot be satisfied
*/
const generate_cuid2 = (schema, generation_context) => {
const length_constraints$1 = getLengthConstraints(schema);
const content_constraints$1 = getContentConstraints(schema);
const exact_length_too_short = length_constraints$1.exact != null && length_constraints$1.exact < CUID2_MIN_LENGTH;
const max_length_too_short = length_constraints$1.max < CUID2_MIN_LENGTH;
if (exact_length_too_short || max_length_too_short) throw new InvalidSchemaException$1("CUID2 cannot be less than 2 characters long");
const length = length_constraints$1.exact ?? faker.number.int({
min: Math.max(length_constraints$1.min, CUID2_MIN_LENGTH),
max: length_constraints$1.max == Infinity ? length_constraints$1.min + CUID2_COMMON_LENGTH : length_constraints$1.max
});
return generateCUID2ofLength(length);
};
const CUIDGenerator = {
schema: z$2.$ZodCUID,
generator: generate_cuid,
match: "instanceof"
};
const CUID2Generator = {
schema: z$2.$ZodCUID2,
generator: generate_cuid2,
match: "instanceof"
};
/**
* Generates a CUID of the given length
* @param len The length of the CUID. Must be at least 9
* @returns A CUID of the given length
* @throws If the length is too short
*/
function generateCUIDofLength(len) {
if (len < CUID_MIN_LENGTH) throw new TypeError("CUID must be at least 9 characters long");
let cuid$1 = "c" + faker.string.alphanumeric({ length: len - 1 });
return cuid$1;
}
/**
* Generates a CUID2 of the given length
* @param len The length of the CUID2. Must be at least 2
* @returns A CUID of the given length
* @throws If the length is too short
*/
function generateCUID2ofLength(len) {
if (len < CUID2_MIN_LENGTH) throw new TypeError("CUID2 must be at least 2 characters long");
let cuid2$1 = faker.string.alpha({ casing: "lower" }) + faker.string.alphanumeric({
length: len - 1,
casing: "lower"
});
return cuid2$1;
}
//#endregion
//#region src/lib/v4/generators/string/ip.ts
const IPV4_MIN_LENGTH = 7;
const IPV4_MAX_LENGTH = 15;
const IPV4_NUM_DOTS = 3;
const IPV6_MIN_LENGTH = 3;
const IPV6_MAX_LENGTH = 39;
const IPV6_MIN_LENGTH_WITHOUT_DOUBLE_COLON = 15;
const IPV6_MAX_LENGTH_WITH_DOUBLE_COLON = 36;
const ipv4_generator = (schema, ctx) => {
const length_constraints$1 = getLengthConstraints(schema);
const content_constraints$1 = getContentConstraints(schema);
const min_length_too_long = length_constraints$1.min > IPV4_MAX_LENGTH;
const max_length_too_short = length_constraints$1.max < IPV4_MIN_LENGTH;
const exact_length_too_long = length_constraints$1.exact != null && length_constraints$1.exact > IPV4_MAX_LENGTH;
const exact_length_too_short = length_constraints$1.exact != null && length_constraints$1.exact < IPV4_MIN_LENGTH;
if (min_length_too_long || max_length_too_short || exact_length_too_long || exact_length_too_short) throw new Error("Invalid length constraints for IPv4");
const length = length_constraints$1.exact ?? faker.number.int({
min: Math.max(length_constraints$1.min, IPV4_MIN_LENGTH),
max: Math.min(length_constraints$1.max, IPV4_MAX_LENGTH)
});
return generateIPv4OfLength(length);
};
const ipv6_generator = (schema, ctx) => {
const length_constraints$1 = getLengthConstraints(schema);
const content_constraints$1 = getContentConstraints(schema);
const min_length_too_long = length_constraints$1.min > IPV6_MAX_LENGTH;
const max_length_too_short = length_constraints$1.max < IPV6_MIN_LENGTH;
const exact_length_too_long = length_constraints$1.exact != null && length_constraints$1.exact > IPV6_MAX_LENGTH;
const exact_length_too_short = length_constraints$1.exact != null && length_constraints$1.exact < IPV6_MIN_LENGTH;
if (min_length_too_long || max_length_too_short || exact_length_too_long || exact_length_too_short) throw new Error("Invalid length constraints for IPv6");
const length = length_constraints$1.exact ?? faker.number.int({
min: Math.max(length_constraints$1.min, IPV6_MIN_LENGTH),
max: Math.min(length_constraints$1.max, IPV6_MAX_LENGTH)
});
return generateIPv6OfLength(length);
};
const IPv4Generator = {
schema: z$2.$ZodIPv4,
generator: ipv4_generator,
match: "instanceof"
};
const IPv6Generator = {
schema: z$2.$ZodIPv6,
generator: ipv6_generator,
match: "instanceof"
};
/**
* Generates an IPv4 Address of the given length. The length must be such that
* an IPv4 address can be made.
*
* @param length
*/
function generateIPv4OfLength(length) {
const num_numbers_in_ip = length - IPV4_NUM_DOTS;
const segment_lengths = partition(num_numbers_in_ip, 4, 1, 3);
const segments = segment_lengths.map((length$1) => generateIPv4Segment(length$1));
return segments.join(".");
}
/**
* Generates an IPv6 Address of the given length. The length must be such that
* an IPv6 address can be made.
*
* @param length
*/
function generateIPv6OfLength(length) {
const should_use_double_colon = ipv6ShouldUseDoubleColon(length);
const num_segments = choseNumberOfIPv6Segments(length, should_use_double_colon);
if (!should_use_double_colon) {
const lengthWithoutColons$1 = length - 7;
const segment_lengths$1 = partition(lengthWithoutColons$1, num_segments, 1, 4);
const segments$1 = segment_lengths$1.map((length$1) => generateIPv6Segment(length$1));
return segments$1.join(":");
}
const lengthWithoutColons = length - (num_segments - 1) - 2;
const segment_lengths = partition(lengthWithoutColons, num_segments, 1, 4);
const segments = segment_lengths.map((length$1) => generateIPv6Segment(length$1));
return "::" + segments.join(":");
}
/**
* Generates an IPv4 segment (0-255) of the given length
* @param length How many characters the segment should be. Between 1 and 3
* @returns An IPv4 segment
* @throws TypeError if the length is invalid
*/
function generateIPv4Segment(length) {
if (length < 1 || length > 3 || !Number.isInteger(length)) throw new TypeError("IPv4 segments must be between 1 and 3 characters long");
switch (length) {
case 1: return faker.number.int({
min: 0,
max: 9
}).toString();
case 2: return faker.number.int({
min: 10,
max: 99
}).toString();
case 3:
default: return faker.number.int({
min: 100,
max: 255
}).toString();
}
}
/**
* Generates a random IPv6 segment (0-ffff) of the given length
* @param length How many characters the segment should be. Between 1 and 4
* @returns An IPv6 segment
* @throws TypeError if the length is invalid
*/
function generateIPv6Segment(length) {
if (length < 1 || length > 4 || !Number.isInteger(length)) throw new TypeError("IPv6 segments must be between 1 and 4 characters long");
return faker.string.hexadecimal({
length,
prefix: "",
casing: "lower"
});
}
/**
* Returns true/false if the IPv6 of the given length should use double colons
* - If it'