@pawel-up/jexl
Version:
Javascript Expression Language: Powerful context-based expression parser and evaluator
193 lines • 7.29 kB
JavaScript
import { JSON_SCHEMA_VERSION, DEFAULT_BASE_URL, } from './types.js';
export function createLibrarySchema(functionSchemas, config) {
const baseUrl = config.baseUrl || DEFAULT_BASE_URL;
return {
$schema: JSON_SCHEMA_VERSION,
$id: `${baseUrl}/${config.category}.schema.json`,
title: config.title,
description: config.description,
version: config.version,
functions: functionSchemas,
};
}
export function createParameter(name, schema, required = true, options = {}) {
return {
name,
schema,
required,
...options,
};
}
export function createFunctionSchema(name, description, category, parameters, returns, options = {}) {
return {
name,
description,
category,
parameters,
returns,
...options,
};
}
export function getFunctionSchema(library, functionName) {
return library.functions[functionName];
}
export function getAllFunctionNames(library) {
return Object.keys(library.functions);
}
export function getFunctionsByCategory(library, category) {
return Object.fromEntries(Object.entries(library.functions).filter(([, schema]) => schema.category === category));
}
export function getFunctionsByTag(library, tag) {
return Object.fromEntries(Object.entries(library.functions).filter(([, schema]) => schema.tags?.includes(tag)));
}
export function searchFunctions(library, query) {
const lowerQuery = query.toLowerCase();
return Object.fromEntries(Object.entries(library.functions).filter(([name, schema]) => name.toLowerCase().includes(lowerQuery) || schema.description.toLowerCase().includes(lowerQuery)));
}
export function toJSON(library, pretty = true) {
return JSON.stringify(library, null, pretty ? 2 : 0);
}
export function mergeLibrarySchemas(libraries, config) {
const mergedFunctions = libraries.reduce((acc, lib) => ({ ...acc, ...lib.functions }), {});
return createLibrarySchema(mergedFunctions, config);
}
export function validateFunctionSchema(schema) {
const errors = [];
if (!schema.name)
errors.push('Function name is required');
if (!schema.description)
errors.push('Function description is required');
if (!schema.category)
errors.push('Function category is required');
if (!schema.parameters)
errors.push('Function parameters array is required');
if (!schema.returns)
errors.push('Function returns definition is required');
schema.parameters?.forEach((param, index) => {
if (!param.name)
errors.push(`Parameter ${index}: name is required`);
if (!param.schema) {
errors.push(`Parameter ${index} (${param.name}): schema is required`);
}
else {
if (getTypeStringFromSchema(param.schema) === 'unknown') {
errors.push(`Parameter ${index} (${param.name}): schema is missing a valid type definition (e.g., type, enum, anyOf)`);
}
if (!param.schema.description) {
errors.push(`Parameter ${index}: schema.description is required`);
}
}
if (param.required === undefined)
errors.push(`Parameter ${index}: required field is required`);
});
if (schema.returns && getTypeStringFromSchema(schema.returns) === 'unknown') {
errors.push('Return schema is missing a valid type definition (e.g., type, enum, anyOf)');
}
return errors;
}
export function getTypeStringFromSchema(schema) {
if (typeof schema === 'boolean') {
return schema ? 'any' : 'never';
}
if (schema.type) {
if (Array.isArray(schema.type)) {
return schema.type.join(' | ');
}
return schema.type;
}
if (schema.enum) {
return schema.enum.map((v) => (typeof v === 'string' ? `"${v}"` : String(v))).join(' | ');
}
if (schema.anyOf) {
return schema.anyOf
.map((s) => (typeof s === 'object' && s !== null && !Array.isArray(s) ? getTypeStringFromSchema(s) : 'unknown'))
.join(' | ');
}
if (schema.oneOf) {
return schema.oneOf
.map((s) => (typeof s === 'object' && s !== null && !Array.isArray(s) ? getTypeStringFromSchema(s) : 'unknown'))
.join(' | ');
}
return 'unknown';
}
export function generateSignature(schema) {
const params = schema.parameters
.map((p) => {
const optional = p.required ? '' : '?';
const variadic = p.variadic ? '...' : '';
const typeStr = getTypeStringFromSchema(p.schema);
return `${variadic}${p.name}${optional}: ${typeStr}`;
})
.join(', ');
const returnType = getTypeStringFromSchema(schema.returns);
return `${schema.name}(${params}) → ${returnType}`;
}
export function generateFunctionMarkdown(schema) {
const lines = [];
lines.push(`### ${schema.name}`);
lines.push('');
lines.push(schema.description);
lines.push('');
if (schema.deprecated) {
lines.push('> ⚠️ **Deprecated** - This function is deprecated and may be removed in future versions.');
lines.push('');
}
lines.push('**Signature:**');
lines.push(`\`${generateSignature(schema)}\``);
lines.push('');
if (schema.parameters.length > 0) {
lines.push('**Parameters:**');
lines.push('');
schema.parameters.forEach((param) => {
const required = param.required ? '' : ' (optional)';
const variadic = param.variadic ? ' (variadic)' : '';
const typeStr = getTypeStringFromSchema(param.schema);
lines.push(`- \`${param.name}\` (${typeStr}${required}${variadic}) - ${param.schema?.description || 'No description provided'}`);
});
lines.push('');
}
const returnType = getTypeStringFromSchema(schema.returns);
const returnDescription = schema.returns.description || 'Return value';
lines.push(`**Returns:** ${returnType} - ${returnDescription}`);
lines.push('');
if (schema.examples && schema.examples.length > 0) {
lines.push('**Examples:**');
lines.push('');
schema.examples.forEach((example) => {
lines.push(`\`\`\`typescript`);
lines.push(example);
lines.push(`\`\`\``);
lines.push('');
});
}
if (schema.since) {
lines.push(`*Since: ${schema.since}*`);
lines.push('');
}
return lines.join('\n');
}
export function generateLibraryMarkdown(library) {
const functions = Object.values(library.functions);
const lines = [];
lines.push(`# ${library.title}`);
lines.push('');
lines.push(library.description);
lines.push('');
lines.push(`**Version:** ${library.version}`);
lines.push('');
lines.push(`**Functions:** ${functions.length}`);
lines.push('');
lines.push('## Table of Contents');
lines.push('');
functions.forEach((func) => {
lines.push(`- [${func.name}](#${func.name.toLowerCase()})`);
});
lines.push('');
lines.push('## Functions');
lines.push('');
functions.forEach((func) => {
lines.push(generateFunctionMarkdown(func));
});
return lines.join('\n');
}
//# sourceMappingURL=utils.js.map