| 214 | return { inputs: inputs(inputShape) }; |
| 215 | }, |
| 216 | async execute({ inputs, params }, context) { |
| 217 | const { method, contentType, timeout, failOnError, authType } = params; |
| 218 | const { url, body, headers = {} } = inputs; |
| 219 | const dynamicInputs = inputs as Record<string, unknown>; |
| 220 | const authHeaderNameValue = |
| 221 | typeof dynamicInputs.authHeaderName === 'string' ? dynamicInputs.authHeaderName : undefined; |
| 222 | const authHeaderValueValue = |
| 223 | typeof dynamicInputs.authHeaderValue === 'string' ? dynamicInputs.authHeaderValue : undefined; |
| 224 | |
| 225 | context.logger.info(`[HTTP] ${method} ${url}`); |
| 226 | |
| 227 | // Merge headers |
| 228 | const finalHeaders = new Headers(headers); |
| 229 | if (contentType !== 'custom' && !finalHeaders.has('Content-Type')) { |
| 230 | finalHeaders.set('Content-Type', contentType); |
| 231 | } |
| 232 | |
| 233 | // Handle Auth |
| 234 | if (authType === 'bearer' && dynamicInputs.bearerToken) { |
| 235 | finalHeaders.set('Authorization', `Bearer ${dynamicInputs.bearerToken}`); |
| 236 | } else if (authType === 'basic' && dynamicInputs.username && dynamicInputs.password) { |
| 237 | const b64 = btoa(`${dynamicInputs.username}:${dynamicInputs.password}`); |
| 238 | finalHeaders.set('Authorization', `Basic ${b64}`); |
| 239 | } else if (authType === 'custom' && authHeaderNameValue && authHeaderValueValue) { |
| 240 | finalHeaders.set(authHeaderNameValue, authHeaderValueValue); |
| 241 | } |
| 242 | |
| 243 | const controller = new AbortController(); |
| 244 | const timeoutId = setTimeout(() => controller.abort(), timeout); |
| 245 | |
| 246 | try { |
| 247 | context.emitProgress(`Requesting ${method} ${url}...`); |
| 248 | |
| 249 | const sensitiveHeaders = authHeaderNameValue |
| 250 | ? Array.from(new Set([...DEFAULT_SENSITIVE_HEADERS, authHeaderNameValue])) |
| 251 | : DEFAULT_SENSITIVE_HEADERS; |
| 252 | |
| 253 | const response = await context.http.fetch( |
| 254 | url, |
| 255 | { |
| 256 | method: method, |
| 257 | headers: finalHeaders, |
| 258 | body: method !== 'GET' && method !== 'HEAD' ? body : undefined, |
| 259 | signal: controller.signal, |
| 260 | }, |
| 261 | { sensitiveHeaders }, |
| 262 | ); |
| 263 | |
| 264 | clearTimeout(timeoutId); |
| 265 | |
| 266 | const rawText = await response.text(); |
| 267 | let parsedData: unknown = rawText; |
| 268 | |
| 269 | // Try parsing JSON |
| 270 | try { |
| 271 | if ( |
| 272 | rawText && |
| 273 | (response.headers.get('content-type')?.includes('application/json') || |