@iyio/convo-lang
Version:
A conversational language.
284 lines • 11.2 kB
JavaScript
;
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