UNPKG

zon-format

Version:

ZON: The most token-efficient serialization format for LLMs - beats CSV, TOON, JSON, and all competitors

554 lines (553 loc) 19.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.zon = exports.ZonSchema = void 0; exports.validate = validate; const decoder_1 = require("../core/decoder"); /** * Abstract base class for ZON schemas. * Defines the contract for parsing validation and prompt generation. */ class ZonSchema { describe(description) { this.description = description; return this; } example(value) { this.exampleValue = value; return this; } optional() { return new ZonOptional(this); } nullable() { return new ZonNullable(this); } default(value) { return new ZonDefault(this, value); } refine(validator, message) { return new ZonRefinement(this, validator, message); } } exports.ZonSchema = ZonSchema; class ZonNullable extends ZonSchema { constructor(schema) { super(); this.schema = schema; } parse(data, path = []) { if (data === null) { return { success: true, data: null }; } return this.schema.parse(data, path); } toPrompt(indent = 0) { return `${this.schema.toPrompt(indent)} (nullable)`; } } class ZonOptional extends ZonSchema { constructor(schema) { super(); this.schema = schema; } parse(data, path = []) { if (data === undefined || data === null) { return { success: true, data: undefined }; } return this.schema.parse(data, path); } toPrompt(indent = 0) { return `${this.schema.toPrompt(indent)} (optional)`; } } class ZonString extends ZonSchema { constructor() { super(...arguments); this.emailValidation = false; this.urlValidation = false; this.uuidValidation = false; this.datetimeValidation = false; this.dateValidation = false; this.timeValidation = false; } min(length) { this.minLength = length; return this; } max(length) { this.maxLength = length; return this; } email() { this.emailValidation = true; return this; } url() { this.urlValidation = true; return this; } regex(pattern, message) { this.regexPattern = pattern; this.regexMessage = message; return this; } uuid(version = 'any') { this.uuidValidation = version; return this; } datetime() { this.datetimeValidation = true; return this; } date() { this.dateValidation = true; return this; } time() { this.timeValidation = true; return this; } parse(data, path = []) { if (typeof data !== 'string') { return { success: false, error: `Expected string at ${path.join('.') || 'root'}, got ${typeof data}`, issues: [{ path, message: `Expected string, got ${typeof data}`, code: 'invalid_type' }], }; } if (this.minLength !== undefined && data.length < this.minLength) { return { success: false, error: `String too short at ${path.join('.') || 'root'}: minimum ${this.minLength} characters`, issues: [{ path, message: `String too short: minimum ${this.minLength} characters`, code: 'custom' }], }; } if (this.maxLength !== undefined && data.length > this.maxLength) { return { success: false, error: `String too long at ${path.join('.') || 'root'}: maximum ${this.maxLength} characters`, issues: [{ path, message: `String too long: maximum ${this.maxLength} characters`, code: 'custom' }], }; } if (this.emailValidation && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data)) { return { success: false, error: `Invalid email at ${path.join('.') || 'root'}`, issues: [{ path, message: 'Invalid email format', code: 'custom' }], }; } if (this.urlValidation) { try { new URL(data); } catch (_a) { return { success: false, error: `Invalid URL at ${path.join('.') || 'root'}`, issues: [{ path, message: 'Invalid URL format', code: 'custom' }], }; } } if (this.regexPattern && !this.regexPattern.test(data)) { return { success: false, error: this.regexMessage || `Pattern mismatch at ${path.join('.') || 'root'}`, issues: [{ path, message: this.regexMessage || 'Does not match required pattern', code: 'custom' }], }; } if (this.uuidValidation) { const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; const uuidAnyRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; const pattern = this.uuidValidation === 'v4' ? uuidV4Regex : uuidAnyRegex; const versionStr = this.uuidValidation === 'v4' ? ' v4' : ''; if (!pattern.test(data)) { return { success: false, error: `Invalid UUID${versionStr} at ${path.join('.') || 'root'}`, issues: [{ path, message: `Invalid UUID${versionStr} format`, code: 'custom' }], }; } } if (this.datetimeValidation && !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$/.test(data)) { return { success: false, error: `Invalid datetime at ${path.join('.') || 'root'}`, issues: [{ path, message: 'Invalid ISO 8601 datetime format', code: 'custom' }], }; } if (this.dateValidation && !/^\d{4}-\d{2}-\d{2}$/.test(data)) { return { success: false, error: `Invalid date at ${path.join('.') || 'root'}`, issues: [{ path, message: 'Invalid date format (expected YYYY-MM-DD)', code: 'custom' }], }; } if (this.timeValidation && !/^\d{2}:\d{2}:\d{2}$/.test(data)) { return { success: false, error: `Invalid time at ${path.join('.') || 'root'}`, issues: [{ path, message: 'Invalid time format (expected HH:MM:SS)', code: 'custom' }], }; } return { success: true, data }; } toPrompt(indent = 0) { const constraints = []; if (this.minLength !== undefined) constraints.push(`min: ${this.minLength}`); if (this.maxLength !== undefined) constraints.push(`max: ${this.maxLength}`); if (this.emailValidation) constraints.push('email'); if (this.urlValidation) constraints.push('url'); if (this.regexPattern) constraints.push('pattern'); if (this.uuidValidation) constraints.push(`uuid${this.uuidValidation === 'v4' ? '-v4' : ''}`); if (this.datetimeValidation) constraints.push('datetime'); if (this.dateValidation) constraints.push('date'); if (this.timeValidation) constraints.push('time'); const constraintStr = constraints.length > 0 ? ` (${constraints.join(', ')})` : ''; const desc = this.description ? ` - ${this.description}` : ''; return `string${constraintStr}${desc}`; } } class ZonNumber extends ZonSchema { constructor() { super(...arguments); this.isPositive = false; this.isNegative = false; this.isInteger = false; } min(value) { this.minValue = value; return this; } max(value) { this.maxValue = value; return this; } positive() { this.isPositive = true; return this; } negative() { this.isNegative = true; return this; } int() { this.isInteger = true; return this; } parse(data, path = []) { if (typeof data !== 'number' || isNaN(data)) { return { success: false, error: `Expected number at ${path.join('.') || 'root'}, got ${typeof data}`, issues: [{ path, message: `Expected number, got ${typeof data}`, code: 'invalid_type' }], }; } if (this.isInteger && !Number.isInteger(data)) { return { success: false, error: `Expected integer at ${path.join('.') || 'root'}, got ${data}`, issues: [{ path, message: `Expected integer, got ${data}`, code: 'custom' }], }; } if (this.isPositive && data <= 0) { return { success: false, error: `Expected positive number at ${path.join('.') || 'root'}, got ${data}`, issues: [{ path, message: `Expected positive number, got ${data}`, code: 'custom' }], }; } if (this.isNegative && data >= 0) { return { success: false, error: `Expected negative number at ${path.join('.') || 'root'}, got ${data}`, issues: [{ path, message: `Expected negative number, got ${data}`, code: 'custom' }], }; } if (this.minValue !== undefined && data < this.minValue) { return { success: false, error: `Number too small at ${path.join('.') || 'root'}: minimum ${this.minValue}`, issues: [{ path, message: `Number too small: minimum ${this.minValue}`, code: 'custom' }], }; } if (this.maxValue !== undefined && data > this.maxValue) { return { success: false, error: `Number too large at ${path.join('.') || 'root'}: maximum ${this.maxValue}`, issues: [{ path, message: `Number too large: maximum ${this.maxValue}`, code: 'custom' }], }; } return { success: true, data }; } toPrompt(indent = 0) { const constraints = []; if (this.isInteger) constraints.push('integer'); if (this.isPositive) constraints.push('positive'); if (this.isNegative) constraints.push('negative'); if (this.minValue !== undefined) constraints.push(`min: ${this.minValue}`); if (this.maxValue !== undefined) constraints.push(`max: ${this.maxValue}`); const constraintStr = constraints.length > 0 ? ` (${constraints.join(', ')})` : ''; const desc = this.description ? ` - ${this.description}` : ''; return `number${constraintStr}${desc}`; } } class ZonBoolean extends ZonSchema { parse(data, path = []) { if (typeof data !== 'boolean') { return { success: false, error: `Expected boolean at ${path.join('.') || 'root'}, got ${typeof data}`, issues: [{ path, message: `Expected boolean, got ${typeof data}`, code: 'invalid_type' }], }; } return { success: true, data }; } toPrompt(indent = 0) { const desc = this.description ? ` - ${this.description}` : ''; return `boolean${desc}`; } } class ZonEnum extends ZonSchema { constructor(values) { super(); this.values = values; } parse(data, path = []) { if (!this.values.includes(data)) { return { success: false, error: `Expected one of [${this.values.join(', ')}] at ${path.join('.') || 'root'}, got '${data}'`, issues: [{ path, message: `Invalid enum value. Expected: ${this.values.join(', ')}`, code: 'invalid_enum' }], }; } return { success: true, data }; } toPrompt(indent = 0) { const desc = this.description ? ` - ${this.description}` : ''; return `enum(${this.values.join(', ')})${desc}`; } } class ZonArray extends ZonSchema { constructor(elementSchema) { super(); this.elementSchema = elementSchema; } min(length) { this.minLength = length; return this; } max(length) { this.maxLength = length; return this; } parse(data, path = []) { if (!Array.isArray(data)) { return { success: false, error: `Expected array at ${path.join('.') || 'root'}, got ${typeof data}`, issues: [{ path, message: `Expected array, got ${typeof data}`, code: 'invalid_type' }], }; } if (this.minLength !== undefined && data.length < this.minLength) { return { success: false, error: `Array too short at ${path.join('.') || 'root'}: minimum ${this.minLength} items`, issues: [{ path, message: `Array too short: minimum ${this.minLength} items`, code: 'custom' }], }; } if (this.maxLength !== undefined && data.length > this.maxLength) { return { success: false, error: `Array too long at ${path.join('.') || 'root'}: maximum ${this.maxLength} items`, issues: [{ path, message: `Array too long: maximum ${this.maxLength} items`, code: 'custom' }], }; } const result = []; for (let i = 0; i < data.length; i++) { const itemResult = this.elementSchema.parse(data[i], [...path, i]); if (!itemResult.success) { return itemResult; } result.push(itemResult.data); } return { success: true, data: result }; } toPrompt(indent = 0) { const constraints = []; if (this.minLength !== undefined) constraints.push(`min: ${this.minLength}`); if (this.maxLength !== undefined) constraints.push(`max: ${this.maxLength}`); const constraintStr = constraints.length > 0 ? ` (${constraints.join(', ')})` : ''; const desc = this.description ? ` - ${this.description}` : ''; return `array of [${this.elementSchema.toPrompt(indent)}]${constraintStr}${desc}`; } } class ZonObject extends ZonSchema { constructor(shape) { super(); this.shape = shape; } parse(data, path = []) { if (typeof data !== 'object' || data === null || Array.isArray(data)) { return { success: false, error: `Expected object at ${path.join('.') || 'root'}, got ${data === null ? 'null' : typeof data}`, issues: [{ path, message: `Expected object, got ${data === null ? 'null' : typeof data}`, code: 'invalid_type' }], }; } const result = {}; for (const key in this.shape) { const fieldSchema = this.shape[key]; const fieldResult = fieldSchema.parse(data[key], [...path, key]); if (!fieldResult.success) { return fieldResult; } result[key] = fieldResult.data; } return { success: true, data: result }; } toPrompt(indent = 0) { const spaces = ' '.repeat(indent); const lines = [`object:`]; if (this.description) { lines[0] += ` (${this.description})`; } for (const key in this.shape) { const fieldSchema = this.shape[key]; const fieldPrompt = fieldSchema.toPrompt(indent + 2); lines.push(`${spaces} - ${key}: ${fieldPrompt}`); } return lines.join('\n'); } } class ZonLiteral extends ZonSchema { constructor(value) { super(); this.value = value; } parse(data, path = []) { if (data !== this.value) { return { success: false, error: `Expected literal '${this.value}' at ${path.join('.') || 'root'}, got '${data}'`, issues: [{ path, message: `Must be exactly '${this.value}'`, code: 'invalid_type' }], }; } return { success: true, data: this.value }; } toPrompt(indent = 0) { const desc = this.description ? ` - ${this.description}` : ''; return `literal(${JSON.stringify(this.value)})${desc}`; } } class ZonUnion extends ZonSchema { constructor(schemas) { super(); this.schemas = schemas; } parse(data, path = []) { const errors = []; for (const schema of this.schemas) { const result = schema.parse(data, path); if (result.success) { return result; } errors.push(result.error); } return { success: false, error: `No union member matched at ${path.join('.') || 'root'}`, issues: [{ path, message: 'Value does not match any union member', code: 'invalid_type' }], }; } toPrompt(indent = 0) { const desc = this.description ? ` - ${this.description}` : ''; return `oneOf(${this.schemas.map(s => s.toPrompt()).join(' | ')})${desc}`; } } class ZonDefault extends ZonSchema { constructor(schema, defaultValue) { super(); this.schema = schema; this.defaultValue = defaultValue; } parse(data, path = []) { if (data === undefined || data === null) { return { success: true, data: this.defaultValue }; } return this.schema.parse(data, path); } toPrompt(indent = 0) { return `${this.schema.toPrompt(indent)} (default: ${JSON.stringify(this.defaultValue)})`; } } class ZonRefinement extends ZonSchema { constructor(schema, validator, message) { super(); this.schema = schema; this.validator = validator; this.message = message; } parse(data, path = []) { const result = this.schema.parse(data, path); if (!result.success) return result; if (!this.validator(result.data)) { return { success: false, error: `${this.message} at ${path.join('.') || 'root'}`, issues: [{ path, message: this.message, code: 'custom' }], }; } return result; } toPrompt(indent = 0) { return `${this.schema.toPrompt(indent)} (custom validation)`; } } exports.zon = { string: () => new ZonString(), number: () => new ZonNumber(), boolean: () => new ZonBoolean(), enum: (values) => new ZonEnum(values), array: (schema) => new ZonArray(schema), object: (shape) => new ZonObject(shape), literal: (value) => new ZonLiteral(value), union: (...schemas) => new ZonUnion(schemas), }; /** * Validates a ZON string or decoded object against a schema. * @param input ZON string or decoded object * @param schema ZON Schema */ function validate(input, schema) { let data = input; if (typeof input === 'string') { try { data = (0, decoder_1.decode)(input); } catch (e) { return { success: false, error: `ZON Parse Error: ${e.message}`, issues: [{ path: [], message: e.message, code: 'custom' }], }; } } return schema.parse(data); }