meld
Version:
Meld: A template language for LLM prompts
102 lines (92 loc) • 3.04 kB
text/typescript
import { DirectiveNode } from 'meld-spec';
import { MeldDirectiveError } from '@core/errors/MeldDirectiveError.js';
import { DirectiveErrorCode } from '@services/pipeline/DirectiveService/errors/DirectiveError.js';
/**
* Validates @define directives
*/
export function validateDefineDirective(node: DirectiveNode): void {
const directive = node.directive;
// Validate name
if (!directive.name || typeof directive.name !== 'string') {
throw new MeldDirectiveError(
'Define directive requires a "name" property (string)',
'define',
{
location: node.location?.start,
code: DirectiveErrorCode.VALIDATION_FAILED
}
);
}
// Check if it's a basic name or a name with risk annotation
const nameParts = directive.name.split('.');
// The AST has already validated the function name format
// If there are extensions (like risk annotations), validate them
if (nameParts.length > 1) {
// First extension must be 'risk' or 'about'
if (nameParts[1] !== 'risk' && nameParts[1] !== 'about') {
throw new MeldDirectiveError(
'Define directive name extension must be "risk" or "about"',
'define',
{
location: node.location?.start,
code: DirectiveErrorCode.VALIDATION_FAILED
}
);
}
// If there's a third part (risk level), it must be high, med, or low
if (nameParts.length > 2 && !['high', 'med', 'low'].includes(nameParts[2])) {
throw new MeldDirectiveError(
'Risk level must be "high", "med", or "low"',
'define',
{
location: node.location?.start,
code: DirectiveErrorCode.VALIDATION_FAILED
}
);
}
// No more than 3 parts allowed
if (nameParts.length > 3) {
throw new MeldDirectiveError(
'Define directive name cannot have more than 3 parts',
'define',
{
location: node.location?.start,
code: DirectiveErrorCode.VALIDATION_FAILED
}
);
}
}
// Validate command exists
if (!directive.command || typeof directive.command !== 'object') {
throw new MeldDirectiveError(
'Define directive requires a "command" property (object)',
'define',
{
location: node.location?.start,
code: DirectiveErrorCode.VALIDATION_FAILED
}
);
}
// Validate command structure
if (directive.command.kind !== 'run' || typeof directive.command.command !== 'string') {
throw new MeldDirectiveError(
'Define directive command must have a kind="run" and a command string',
'define',
{
location: node.location?.start,
code: DirectiveErrorCode.VALIDATION_FAILED
}
);
}
// Validate command is not empty
if (!directive.command.command.trim()) {
throw new MeldDirectiveError(
'Command cannot be empty',
'define',
{
location: node.location?.start,
code: DirectiveErrorCode.VALIDATION_FAILED
}
);
}
}