( url: string, filePath: string, fetchImpl: FetchImpl, )
| 697 | * snapshots. |
| 698 | */ |
| 699 | export async function streamUrlToFile( |
| 700 | url: string, |
| 701 | filePath: string, |
| 702 | fetchImpl: FetchImpl, |
| 703 | ): Promise<void> { |
| 704 | let response: Response; |
| 705 | try { |
| 706 | response = await fetchImpl(url); |
| 707 | } catch (err) { |
| 708 | const message = err instanceof Error ? err.message : String(err); |
| 709 | throw new TransportError(`Failed to download presigned URL ${url}: ${message}`); |
| 710 | } |
| 711 | if (!response.ok) { |
| 712 | throw ApiError.fromEnvelope({ |
| 713 | error: { |
| 714 | code: 'UNAVAILABLE', |
| 715 | message: `Failed to download presigned URL (HTTP ${response.status}).`, |
| 716 | nextAction: |
| 717 | 'Re-run `testsprite test failure get`. Presigned URLs in the bundle expire after 15 minutes.', |
| 718 | requestId: 'local', |
| 719 | details: { status: response.status, url }, |
| 720 | }, |
| 721 | }); |
| 722 | } |
| 723 | if (!response.body) { |
| 724 | // Some test runtimes / fetch polyfills don't expose `body` as a |
| 725 | // ReadableStream. Fall back to a buffered write — same correctness, |
| 726 | // just no streaming benefit. The bundle is bounded by the |
| 727 | // backend's 15-min TTL, so even a multi-MB video buffers fully in |
| 728 | // a tolerable amount of memory. |
| 729 | const buffer = Buffer.from(await response.arrayBuffer()); |
| 730 | await writeFile(filePath, buffer); |
| 731 | return; |
| 732 | } |
| 733 | await mkdir(dirname(filePath), { recursive: true }); |
| 734 | // `response.body` is a Web ReadableStream. Node's `pipeline` accepts |
| 735 | // it via `Readable.fromWeb` (Node ≥ 18). Wrap in a try so any error |
| 736 | // from the stream propagates as a TransportError, preserving the |
| 737 | // exit-code contract. |
| 738 | const fileSink = createWriteStream(filePath); |
| 739 | try { |
| 740 | const webBody = response.body as unknown as NodeReadableStream<Uint8Array>; |
| 741 | const { Readable } = await import('node:stream'); |
| 742 | const nodeStream = Readable.fromWeb(webBody); |
| 743 | await pipeline(nodeStream, fileSink as unknown as Writable); |
| 744 | } catch (err) { |
| 745 | const message = err instanceof Error ? err.message : String(err); |
| 746 | throw new TransportError(`Failed mid-download of ${url}: ${message}`); |
| 747 | } |
| 748 | } |
| 749 | |
| 750 | function isPresignedUrl(value: string): boolean { |
| 751 | return value.startsWith('https://'); |
no test coverage detected