import type { APIRoute } from 'astro'; /** * Spintax Pattern Validator * Check syntax before running 10k generations */ function validateGodToken(request: Request): boolean { const token = request.headers.get('X-God-Token') || request.headers.get('Authorization')?.replace('Bearer ', '') || new URL(request.url).searchParams.get('token'); const godToken = process.env.GOD_MODE_TOKEN || import.meta.env.GOD_MODE_TOKEN; if (!godToken) return true; return token === godToken; } interface ValidationError { type: string; position: number; message: string; } /** * Validate spintax pattern syntax */ function validateSpintax(pattern: string): { valid: boolean; errors: ValidationError[] } { const errors: ValidationError[] = []; let braceStack: number[] = []; let inBraces = false; let currentDepth = 0; const maxDepth = 3; for (let i = 0; i < pattern.length; i++) { const char = pattern[i]; const prevChar = i > 0 ? pattern[i - 1] : ''; // Check for opening brace if (char === '{' && prevChar !== '\\') { braceStack.push(i); currentDepth++; inBraces = true; if (currentDepth > maxDepth) { errors.push({ type: 'max_depth', position: i, message: `Nested too deep (max ${maxDepth} levels)` }); } } // Check for closing brace if (char === '}' && prevChar !== '\\') { if (braceStack.length === 0) { errors.push({ type: 'unmatched_closing', position: i, message: 'Closing brace without opening brace' }); } else { const openPos = braceStack.pop(); const content = pattern.substring(openPos! + 1, i); // Check for empty braces if (content.trim() === '') { errors.push({ type: 'empty_braces', position: openPos!, message: 'Empty option set {}' }); } // Check for missing pipes if (!content.includes('|')) { errors.push({ type: 'no_alternatives', position: openPos!, message: 'Option set must contain at least one pipe |' }); } // Check for empty options const options = content.split('|'); for (let j = 0; j < options.length; j++) { if (options[j].trim() === '') { errors.push({ type: 'empty_option', position: openPos! + content.indexOf('||'), message: 'Empty option between pipes' }); } } currentDepth--; } inBraces = braceStack.length > 0; } } // Check for unclosed braces if (braceStack.length > 0) { for (const pos of braceStack) { errors.push({ type: 'unclosed_brace', position: pos, message: 'Opening brace not closed' }); } } return { valid: errors.length === 0, errors }; } /** * Generate a few sample variations */ function generateSamples(pattern: string, count: number = 3): string[] { const samples: string[] = []; for (let i = 0; i < count; i++) { let result = pattern; const regex = /\{([^{}]+)\}/g; result = result.replace(regex, (match, content) => { const options = content.split('|').map((s: string) => s.trim()); return options[Math.floor(Math.random() * options.length)]; }); samples.push(result); } return samples; } export const POST: APIRoute = async ({ request }) => { if (!validateGodToken(request)) { return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401, headers: { 'Content-Type': 'application/json' } }); } try { const { pattern, max_depth = 3 } = await request.json(); if (!pattern) { return new Response(JSON.stringify({ error: 'Missing pattern' }), { status: 400, headers: { 'Content-Type': 'application/json' } }); } const validation = validateSpintax(pattern); const samples = validation.valid ? generateSamples(pattern, 5) : []; return new Response(JSON.stringify({ pattern, valid: validation.valid, errors: validation.errors, samples: validation.valid ? samples : null, stats: { length: pattern.length, braces: (pattern.match(/\{/g) || []).length, pipes: (pattern.match(/\|/g) || []).length }, recommendation: validation.valid ? '✅ Pattern is valid - safe to use in batch generation' : '❌ Fix errors before using in production', timestamp: new Date().toISOString() }), { status: 200, headers: { 'Content-Type': 'application/json' } }); } catch (error: any) { return new Response(JSON.stringify({ error: 'Validation failed', details: error.message }), { status: 500, headers: { 'Content-Type': 'application/json' } }); } }; export const GET: APIRoute = async ({ request }) => { if (!validateGodToken(request)) { return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401, headers: { 'Content-Type': 'application/json' } }); } return new Response(JSON.stringify({ endpoint: 'POST /api/intelligence/spintax/validate', description: 'Validate spintax patterns before batch generation', examples: { valid: '{Hello|Hi|Hey} {world|there|friend}!', invalid: '{Hello|Hi} {world', nested: '{The {best|top} {solution|answer}}', empty: '{|option} // Error: empty option' }, errors_detected: [ 'unmatched_braces', 'empty_option_sets', 'no_alternatives', 'max_depth_exceeded' ] }, null, 2), { status: 200, headers: { 'Content-Type': 'application/json' } }); };