All files / src/schemas helpers.ts

88.88% Statements 16/18
83.33% Branches 10/12
100% Functions 3/3
88.88% Lines 16/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60      4x   210x 13x       197x 11x             186x 12x       174x       174x       4x   33x               33x       33x             24x 24x     24x      
import { z } from 'zod';
 
// Helper to validate JavaScript code
export const validateJavaScriptCode = (code: string): boolean => {
  // Check for common HTML entities that shouldn't be in JS
  if (/"|&|<|>|&#\d+;|&\w+;/.test(code)) {
    return false;
  }
 
  // Basic check to ensure it's not HTML
  if (/<(!DOCTYPE|html|body|head|script|style)\b/i.test(code)) {
    return false;
  }
 
  // Check for literal \n, \t, \r outside of strings (common LLM mistake)
  // This is tricky - we'll check if the code has these patterns in a way that suggests
  // they're meant to be actual newlines/tabs rather than escape sequences in strings
  // Look for patterns like: ;\n or }\n or )\n which suggest literal newlines
  if (/[;})]\s*\\n|\\n\s*[{(/]/.test(code)) {
    return false;
  }
 
  // Check for obvious cases of literal \n between statements
  Iif (/[;})]\s*\\n\s*\w/.test(code)) {
    return false;
  }
 
  return true;
};
 
// Helper to create schema that rejects session_id
export const createStatelessSchema = <T extends z.ZodObject<z.ZodRawShape>>(schema: T, toolName: string) => {
  // Tool-specific guidance for common scenarios
  const toolGuidance: Record<string, string> = {
    capture_screenshot: 'To capture screenshots with sessions, use crawl(session_id, screenshot: true)',
    generate_pdf: 'To generate PDFs with sessions, use crawl(session_id, pdf: true)',
    execute_js: 'To run JavaScript with sessions, use crawl(session_id, js_code: [...])',
    get_html: 'To get HTML with sessions, use crawl(session_id)',
    extract_with_llm: 'To extract data with sessions, first use crawl(session_id) then extract from the response',
  };
 
  const message = `${toolName} does not support session_id. This tool is stateless - each call creates a new browser. ${
    toolGuidance[toolName] || 'For persistent operations, use crawl with session_id.'
  }`;
 
  return z
    .object({
      session_id: z.never({ message }).optional(),
    })
    .passthrough()
    .and(schema)
    .transform((data) => {
      const { session_id, ...rest } = data;
      Iif (session_id !== undefined) {
        throw new Error(message);
      }
      return rest as z.infer<T>;
    });
};