| 12 | * Handler for API blocks that make external HTTP requests. |
| 13 | */ |
| 14 | export class ApiBlockHandler implements BlockHandler { |
| 15 | canHandle(block: SerializedBlock): boolean { |
| 16 | return block.metadata?.id === BlockType.API |
| 17 | } |
| 18 | |
| 19 | async execute( |
| 20 | ctx: ExecutionContext, |
| 21 | block: SerializedBlock, |
| 22 | inputs: Record<string, any> |
| 23 | ): Promise<any> { |
| 24 | const tool = getTool(block.config.tool) |
| 25 | if (!tool) { |
| 26 | throw new Error(`Tool not found: ${block.config.tool}`) |
| 27 | } |
| 28 | |
| 29 | if (tool.name?.includes('HTTP') && (!inputs.url || inputs.url.trim() === '')) { |
| 30 | return { data: null, status: HTTP.STATUS.OK, headers: {} } |
| 31 | } |
| 32 | |
| 33 | if (tool.name?.includes('HTTP') && inputs.url) { |
| 34 | let urlToValidate = inputs.url |
| 35 | if (typeof urlToValidate === 'string') { |
| 36 | if ( |
| 37 | (urlToValidate.startsWith('"') && urlToValidate.endsWith('"')) || |
| 38 | (urlToValidate.startsWith("'") && urlToValidate.endsWith("'")) |
| 39 | ) { |
| 40 | urlToValidate = urlToValidate.slice(1, -1) |
| 41 | inputs.url = urlToValidate |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | const urlValidation = await validateUrlWithDNS(urlToValidate, 'url') |
| 46 | if (!urlValidation.isValid) { |
| 47 | throw new Error(urlValidation.error) |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | try { |
| 52 | const processedInputs = { ...inputs } |
| 53 | |
| 54 | if (processedInputs.body !== undefined) { |
| 55 | if (typeof processedInputs.body === 'string') { |
| 56 | try { |
| 57 | const trimmedBody = processedInputs.body.trim() |
| 58 | if (trimmedBody.startsWith('{') || trimmedBody.startsWith('[')) { |
| 59 | processedInputs.body = JSON.parse(trimmedBody) |
| 60 | } |
| 61 | } catch (e) {} |
| 62 | } else if (processedInputs.body === null) { |
| 63 | processedInputs.body = undefined |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | const result = await executeTool( |
| 68 | block.config.tool, |
| 69 | { |
| 70 | ...processedInputs, |
| 71 | _context: { |
nothing calls this directly
no outgoing calls
no test coverage detected