import type { Type } from './schema' import { isEmpty } from '../data' import { objectMap } from '../data/object' const _mapJsonSchemaType: Record = { string: 'string', number: 'number', boolean: 'boolean', int: 'integer', } export function schemaExportJsonSchema(schema: Type): Record { // assert(isSchemaObjectFlat(schema), 'schema should be a flat object') function transformSchema(schema: Type): any { const type = _mapJsonSchemaType[schema.type] ?? schema.type ?? 'object' const properties: Record = {} const required: string[] = [] objectMap(schema._object!, (key, schema: any) => { const type = _mapJsonSchemaType[schema.type] ?? schema.type properties[key] = { type } const enumValues = (schema as any)._enumValues if (enumValues) { properties[key].enum = enumValues } if (schema._default !== undefined) { properties[key].default = schema._default } if (schema._meta?.desc) { properties[key].description = schema._meta.desc } if (schema._optional !== true) { required.push(key) } if (schema.type === 'array' && schema._type) { properties[key].items = transformSchema(schema._type) } else if (schema.type === 'object' && schema._object) { Object.assign(properties[key], transformSchema(schema)) properties[key].additionalProperties = false } else if (schema.type === 'record' && schema._type) { properties[key].type = 'object' properties[key].additionalProperties = transformSchema(schema._type) } // Handle union types (e.g., z.union) else if (schema.type === 'union' && Array.isArray(schema._union)) { properties[key].type = schema._union.map((s: any) => _mapJsonSchemaType[s.type] ?? s.type) // todo complex types } }) if (!isEmpty(properties)) { return { type, properties, additionalProperties: false, ...(required.length > 0 ? { required } : {}), } } return { type, } } return { $schema: 'http://json-schema.org/draft-07/schema#', additionalProperties: false, ...transformSchema(schema), } } export function schemaExportJsonSchemaString(schema: Type): string { const jsonSchema = schemaExportJsonSchema(schema) return JSON.stringify(jsonSchema, null, 2) }