donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
176 lines • 6.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.jsonSchemaToZod = jsonSchemaToZod;
const v4_1 = require("zod/v4");
function jsonSchemaToZod(schema) {
// Handle anyOf
if (schema.anyOf) {
const unions = schema.anyOf.map((subSchema) => jsonSchemaToZod(subSchema));
if (unions.length === 0) {
throw new Error('anyOf must contain at least one valid schema object');
}
return v4_1.z.union(unions);
}
// Handle enum
if (schema.enum) {
if (schema.enum.length === 0) {
throw new Error('Enum must have at least one value');
}
return v4_1.z.enum(schema.enum);
}
// Handle type
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
switch (type) {
case 'string':
return buildStringSchema(schema);
case 'number':
return buildNumberSchema(schema);
case 'integer':
return buildIntegerSchema(schema);
case 'boolean':
return v4_1.z.boolean();
case 'object':
return buildObjectSchema(schema);
case 'array':
return buildArraySchema(schema);
default:
// If no type is specified, default to unknown
return v4_1.z.unknown();
}
}
function buildStringSchema(schema) {
let zodSchema = v4_1.z.string();
if (schema.format) {
switch (schema.format) {
case 'date-time':
zodSchema = v4_1.z.iso.datetime();
break;
case 'date':
zodSchema = v4_1.z.iso.date();
break;
case 'time':
zodSchema = v4_1.z.iso.time();
break;
case 'email':
zodSchema = v4_1.z.email();
break;
case 'uuid':
zodSchema = v4_1.z.uuid();
break;
case 'ipv4':
zodSchema = v4_1.z.ipv4();
break;
case 'ipv6':
zodSchema = v4_1.z.ipv6();
break;
case 'hostname':
// Zod doesn't have a built-in hostname validator, so we use a regex
zodSchema = zodSchema.regex(/^(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))*$/, 'Invalid hostname');
break;
case 'duration':
// ISO 8601 duration format
zodSchema = v4_1.z.iso.duration();
break;
}
}
// Apply pattern constraint
if (schema.pattern) {
zodSchema = zodSchema.regex(new RegExp(schema.pattern));
}
return zodSchema;
}
function buildNumberSchema(schema) {
let zodSchema = v4_1.z.number();
// Apply numeric constraints
if (schema.minimum !== undefined) {
zodSchema = zodSchema.min(schema.minimum);
}
if (schema.maximum !== undefined) {
zodSchema = zodSchema.max(schema.maximum);
}
if (typeof schema.exclusiveMinimum === 'number') {
zodSchema = zodSchema.gt(schema.exclusiveMinimum);
}
if (typeof schema.exclusiveMaximum === 'number') {
zodSchema = zodSchema.lt(schema.exclusiveMaximum);
}
if (schema.multipleOf !== undefined) {
zodSchema = zodSchema.multipleOf(schema.multipleOf);
}
return zodSchema;
}
function buildIntegerSchema(schema) {
let zodSchema = v4_1.z.number().int();
// Apply numeric constraints (same as number)
if (schema.minimum !== undefined) {
zodSchema = zodSchema.min(schema.minimum);
}
if (schema.maximum !== undefined) {
zodSchema = zodSchema.max(schema.maximum);
}
if (typeof schema.exclusiveMinimum === 'number') {
zodSchema = zodSchema.gt(schema.exclusiveMinimum);
}
if (typeof schema.exclusiveMaximum === 'number') {
zodSchema = zodSchema.lt(schema.exclusiveMaximum);
}
if (schema.multipleOf !== undefined) {
zodSchema = zodSchema.multipleOf(schema.multipleOf);
}
return zodSchema;
}
function buildObjectSchema(schema) {
// If no properties are defined, treat as a record/unknown object
if (!schema.properties || Object.keys(schema.properties).length === 0) {
return v4_1.z.record(v4_1.z.string(), v4_1.z.unknown());
}
const shape = {};
for (const [key, propSchema] of Object.entries(schema.properties)) {
// Handle JSONSchema7Definition - skip if boolean
if (typeof propSchema === 'boolean') {
continue;
}
let zodProp = jsonSchemaToZod(propSchema);
// Make property optional if it's not in the required array
if (!schema.required?.includes(key)) {
zodProp = zodProp.optional();
}
shape[key] = zodProp;
}
return v4_1.z.object(shape);
}
function buildArraySchema(schema) {
let itemSchema = v4_1.z.unknown();
if (schema.items) {
if (typeof schema.items === 'boolean') {
// Boolean schema: true allows anything, false allows nothing
itemSchema = schema.items ? v4_1.z.unknown() : v4_1.z.never();
}
else if (Array.isArray(schema.items)) {
// Tuple validation - for simplicity, we'll use a union of all item schemas
const itemSchemas = schema.items
.filter((item) => typeof item === 'object')
.map((item) => jsonSchemaToZod(item));
if (itemSchemas.length > 0) {
itemSchema =
itemSchemas.length === 1
? itemSchemas[0]
: v4_1.z.union(itemSchemas);
}
}
else {
// Single schema object
itemSchema = jsonSchemaToZod(schema.items);
}
}
let zodSchema = v4_1.z.array(itemSchema);
// Apply array constraints
if (schema.minItems !== undefined) {
zodSchema = zodSchema.min(schema.minItems);
}
if (schema.maxItems !== undefined) {
zodSchema = zodSchema.max(schema.maxItems);
}
return zodSchema;
}
//# sourceMappingURL=JsonSchemaUtils.js.map