Authenticated raw-binary GET (no envelope). Used for file downloads that * must carry the Bearer token — e.g. / src, which the browser * fetches natively and cannot authorize on its own. Returns the body as a * Blob on 2xx; otherwise parses the daemon envelope and throws.
(path: string)
| 103 | * fetches natively and cannot authorize on its own. Returns the body as a |
| 104 | * Blob on 2xx; otherwise parses the daemon envelope and throws. */ |
| 105 | async getBlob(path: string): Promise<Blob> { |
| 106 | const url = buildRestUrl(this.origin, path); |
| 107 | const requestId = createRequestId(); |
| 108 | const headers: Record<string, string> = { 'X-Request-Id': requestId }; |
| 109 | this.addClientHeaders(headers); |
| 110 | const startedAt = Date.now(); |
| 111 | traceRestRequest({ method: 'GET', path, url, requestId }); |
| 112 | let response: Response; |
| 113 | try { |
| 114 | response = await fetch(url, { method: 'GET', headers, signal: timeoutSignal() }); |
| 115 | } catch (err) { |
| 116 | traceRestFailure({ |
| 117 | method: 'GET', |
| 118 | path, |
| 119 | requestId, |
| 120 | phase: 'fetch', |
| 121 | durationMs: Date.now() - startedAt, |
| 122 | error: err, |
| 123 | }); |
| 124 | throw new DaemonNetworkError({ |
| 125 | message: `Network error calling GET ${path}`, |
| 126 | cause: err, |
| 127 | method: 'GET', |
| 128 | path, |
| 129 | url, |
| 130 | requestId, |
| 131 | phase: 'fetch', |
| 132 | timeoutMs: REQUEST_TIMEOUT_MS, |
| 133 | timestamp: Date.now(), |
| 134 | durationMs: Date.now() - startedAt, |
| 135 | }); |
| 136 | } |
| 137 | if (response.ok) { |
| 138 | traceRestResponse({ |
| 139 | method: 'GET', |
| 140 | path, |
| 141 | requestId, |
| 142 | status: response.status, |
| 143 | durationMs: Date.now() - startedAt, |
| 144 | code: 0, |
| 145 | msg: '', |
| 146 | }); |
| 147 | return response.blob(); |
| 148 | } |
| 149 | // Error path: the daemon sends a JSON envelope (401/404/413…). |
| 150 | let envelope: WireEnvelope<unknown> | undefined; |
| 151 | try { |
| 152 | envelope = (await response.clone().json()) as WireEnvelope<unknown>; |
| 153 | } catch { |
| 154 | // not JSON — fall back to the HTTP status below |
| 155 | } |
| 156 | this.checkAuthRequired(response, envelope?.code ?? 0); |
| 157 | traceRestResponse({ |
| 158 | method: 'GET', |
| 159 | path, |
| 160 | requestId, |
| 161 | status: response.status, |
| 162 | durationMs: Date.now() - startedAt, |
no test coverage detected