UNPKG

@iyio/convo-lang

Version:

A conversational language.

284 lines 11.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.describeConvoScheme = exports.jsonSchemeToConvoTypeString = exports.zodSchemeToConvoTypeString = exports.schemeToConvoTypeString = exports.convoBaseTypeToZodType = exports.convoParamsToZodShape = exports.convoValueToZodType = exports.convoTypeToJsonScheme = void 0; const common_1 = require("@iyio/common"); const zod_1 = require("zod"); const ConvoError_1 = require("./ConvoError"); const convo_lib_1 = require("./convo-lib"); const convo_types_1 = require("./convo-types"); const typeCacheKey = Symbol('typeCacheKey'); const convoTypeToJsonScheme = (value, maxDepth = 100, cache = true) => { const zod = (0, exports.convoValueToZodType)(value, maxDepth, cache); return (0, common_1.zodTypeToJsonScheme)(zod, maxDepth, cache); }; exports.convoTypeToJsonScheme = convoTypeToJsonScheme; const convoValueToZodType = (value, maxDepth = 100, cache = true) => { if (cache && value && value[typeCacheKey]) { return value[typeCacheKey]; } const type = _convoValueToZodType(value, value?.[convo_lib_1.convoMetadataKey], maxDepth); if (cache && value) { value[typeCacheKey] = type; } return type; }; exports.convoValueToZodType = convoValueToZodType; const _convoValueToZodType = (value, metadata, maxDepth = 100) => { maxDepth--; if (maxDepth < 0) { return zod_1.z.any(); } let isOptional = false; let isArray = false; if ((0, convo_types_1.isOptionalConvoValue)(value)) { isOptional = true; value = value.value; } let zType; if (Array.isArray(value)) { isArray = true; if (value.length === 0) { zType = zod_1.z.any(); } else { zType = _convoValueToZodType(value[0], undefined, maxDepth); } } else if ((0, convo_types_1.isConvoType)(value)) { if ((0, convo_types_1.isConvoBaseType)(value.type)) { zType = (0, exports.convoBaseTypeToZodType)(value.type); } else if (value.enumValues) { if (value.enumValues.length === 0) { zType = zod_1.z.enum(['']); } else { let allStrings = true; for (let ei = 0; ei < value.enumValues.length; ei++) { if (!(typeof value.enumValues[ei] === 'string')) { allStrings = false; break; } } if (allStrings) { zType = zod_1.z.enum(value.enumValues); } else { zType = zod_1.z.union(value.enumValues.map(v => zod_1.z.literal(v))); } } } else { zType = zod_1.z.unknown(); } } else { switch (value) { case undefined: zType = zod_1.z.undefined(); break; case null: zType = zod_1.z.null(); break; default: if (typeof value === 'object') { const shape = _convoParamsToZodShape(value, metadata, maxDepth); zType = zod_1.z.object(shape); } else { zType = zod_1.z.literal(value); } } } if (isArray) { zType = zType.array(); } if (isOptional) { zType = zType.optional(); } if (metadata?.comment) { zType = zType.describe(metadata.comment); } return zType; }; const convoParamsToZodShape = (params, maxDepth = 100) => { return _convoParamsToZodShape(params, undefined, maxDepth); }; exports.convoParamsToZodShape = convoParamsToZodShape; const _convoParamsToZodShape = (params, metadata, maxDepth = 100) => { maxDepth--; const shape = {}; for (const e in params) { const v = params[e]; shape[e] = _convoValueToZodType(v, metadata?.properties?.[e] ?? v?.[convo_lib_1.convoMetadataKey], maxDepth); } return shape; }; const convoBaseTypeToZodType = (type) => { switch (type) { case 'string': return zod_1.z.string(); case 'boolean': return zod_1.z.boolean(); case 'number': return zod_1.z.number(); case 'time': return zod_1.z.number(); case 'void': return zod_1.z.void(); case 'int': return zod_1.z.number().int(); case 'array': return zod_1.z.any().array(); case 'map': return zod_1.z.record(zod_1.z.string()); case 'any': return zod_1.z.any(); default: throw new ConvoError_1.ConvoError('unexpected-base-type', { baseType: type }, `Unexpected ConvoBaseType - ${type}`); } }; exports.convoBaseTypeToZodType = convoBaseTypeToZodType; const schemeToConvoTypeString = (scheme, nameOverride) => { if (scheme instanceof zod_1.ZodType) { const json = (0, common_1.zodTypeToJsonScheme)(scheme); if (!json) { throw new ConvoError_1.ConvoError('invalid-scheme-type'); } return (0, exports.jsonSchemeToConvoTypeString)(json, nameOverride); } else { return (0, exports.jsonSchemeToConvoTypeString)(scheme, nameOverride); } }; exports.schemeToConvoTypeString = schemeToConvoTypeString; const zodSchemeToConvoTypeString = (scheme, nameOverride) => { const json = (0, common_1.zodTypeToJsonScheme)(scheme); if (!json) { throw new ConvoError_1.ConvoError('invalid-scheme-type'); } return (0, exports.jsonSchemeToConvoTypeString)(json, nameOverride); }; exports.zodSchemeToConvoTypeString = zodSchemeToConvoTypeString; const jsonSchemeToConvoTypeString = (scheme, nameOverride) => { const out = []; _jsonSchemeToConvoTypeString(scheme, out, '', null, nameOverride, false, 20); return out.join(''); }; exports.jsonSchemeToConvoTypeString = jsonSchemeToConvoTypeString; const tabSize = ' '; const _jsonSchemeToConvoTypeString = (scheme, out, tab, label, nameOverride, required, maxDepth) => { if (maxDepth < 0) { throw new ConvoError_1.ConvoError('max-type-conversion-depth-reached'); } maxDepth--; if (scheme.description) { (0, convo_lib_1.convoDescriptionToCommentOut)(scheme.description, tab, out); out.push('\n'); } const open = label ? `${tab}${label}${required ? '' : '?'}: ` : tab; if (scheme.enum) { out.push(open, 'enum(', scheme.enum.map(v => JSON.stringify(v)).join(' '), ')'); } else if (scheme.type) { switch (scheme.type) { case 'object': out.push(open, nameOverride ?? 'struct', '(\n'); if (scheme.properties) { for (const e in scheme.properties) { const prop = scheme.properties[e]; if (!prop) { continue; } _jsonSchemeToConvoTypeString(prop, out, tab + tabSize, e, undefined, scheme.required?.includes(e) ? true : false, maxDepth); out.push('\n'); } } out.push(tab, ')'); break; case 'array': out.push(open, 'array(\n'); if (scheme.items) { _jsonSchemeToConvoTypeString(scheme.items, out, tab + tabSize, null, undefined, false, maxDepth); out.push('\n'); } out.push(tab, ')'); break; case 'string': out.push(open, 'string'); break; case 'number': out.push(open, 'number'); break; case 'boolean': out.push(open, 'boolean'); break; case 'integer': out.push(open, 'int'); break; case 'null': out.push(open, 'null'); break; default: throw new ConvoError_1.ConvoError('unknown-json-scheme-type', undefined, `${scheme.type} is an unknown json scheme type to convo`); } } else { throw new ConvoError_1.ConvoError('unknown-json-scheme-type', undefined, `json scheme type did not define a type or enum values`); } }; const describeConvoScheme = (scheme, value, nameOverride) => { if (scheme instanceof zod_1.ZodType) { const json = (0, common_1.zodTypeToJsonScheme)(scheme); if (!json) { throw new ConvoError_1.ConvoError('invalid-scheme-type'); } scheme = json; } const out = []; _describeScheme('unset', scheme, out, '', null, nameOverride, false, 20, value); return out.join(''); }; exports.describeConvoScheme = describeConvoScheme; const descTabSize = ' '; const _describeScheme = (undefinedValue, scheme, out, tab, label, nameOverride, required, maxDepth, value) => { if (maxDepth < 0) { throw new ConvoError_1.ConvoError('max-type-conversion-depth-reached'); } maxDepth--; const open = label ? `${tab}- ${label}: ` : tab; if (scheme.type) { switch (scheme.type) { case 'object': if (label) { out.push(open, '- :\n'); } if (scheme.properties) { for (const e in scheme.properties) { const prop = scheme.properties[e]; if (!prop) { continue; } _describeScheme(undefinedValue, prop, out, tab + (label ? descTabSize : ''), e, undefined, scheme.required?.includes(e) ? true : false, maxDepth, value?.[e]); out.push('\n'); } } //out.push(tab,')'); break; case 'array': { const length = value?.length ?? 0; const n = label ?? 'items'; out.push(open, `${length} ${length === 1 ? (0, common_1.wordToSingular)(n) : n}\n`); if (scheme.items && Array.isArray(value)) { for (let i = 0; i < value.length; i++) { const item = value[i]; _describeScheme(undefinedValue, scheme.items, out, tab + (label ? descTabSize : ''), (i + 1).toString(), undefined, false, maxDepth, item); } _describeScheme(undefinedValue, scheme.items, out, tab + descTabSize, null, undefined, false, maxDepth, value); } break; } default: out.push(open, `${value === null ? 'null' : value === undefined ? undefinedValue : value}`); break; } } else if (scheme.enum) { out.push(open, `${value === null ? 'null' : value === undefined ? undefinedValue : value}`); } else { throw new ConvoError_1.ConvoError('unknown-json-scheme-type', undefined, `json scheme type did not define a type or enum values`); } }; //# sourceMappingURL=convo-zod.js.map