| 45 | // Build a fetcher that hits a local /api path then maps the success body |
| 46 | const fetchAndProcess = |
| 47 | (path: string, process: (raw: any) => any = (r) => r) => |
| 48 | async (ctx: JobContext) => { |
| 49 | const target = path.includes('${ip}') ? ctx.ipAddress || '' : ctx.address; |
| 50 | const url = path.replace(/\$\{(ip|url)\}/g, target); |
| 51 | const res = await fetch(`${ctx.api}/${url}`, { signal: ctx.signal }); |
| 52 | const raw = await parseJson(res); |
| 53 | return raw?.error ? raw : process(raw); |
| 54 | }; |
| 55 | |
| 56 | const card = ( |
| 57 | id: string, |