( opts: GetPresignedOptions )
| 175 | * `{ presignedUrl, fileInfo, uploadHeaders?, directUploadSupported }` contract. |
| 176 | */ |
| 177 | export const getPresignedUploadInfo = async ( |
| 178 | opts: GetPresignedOptions |
| 179 | ): Promise<PresignedUploadInfo> => { |
| 180 | const { endpoint, file, body, signal } = opts |
| 181 | const response = await fetch(endpoint, { |
| 182 | method: 'POST', |
| 183 | headers: { 'Content-Type': 'application/json' }, |
| 184 | body: JSON.stringify({ |
| 185 | fileName: file.name, |
| 186 | contentType: getFileContentType(file), |
| 187 | fileSize: file.size, |
| 188 | ...body, |
| 189 | }), |
| 190 | signal, |
| 191 | }) |
| 192 | |
| 193 | if (!response.ok) { |
| 194 | let errorDetails: unknown = null |
| 195 | try { |
| 196 | errorDetails = await response.json() |
| 197 | } catch {} |
| 198 | const serverMessage = |
| 199 | errorDetails != null && |
| 200 | typeof errorDetails === 'object' && |
| 201 | typeof (errorDetails as Record<string, unknown>).error === 'string' |
| 202 | ? ((errorDetails as Record<string, unknown>).error as string) |
| 203 | : null |
| 204 | throw new DirectUploadError( |
| 205 | serverMessage || |
| 206 | `Failed to get presigned URL for ${file.name}: ${response.status} ${response.statusText}`, |
| 207 | 'PRESIGNED_URL_ERROR', |
| 208 | errorDetails |
| 209 | ) |
| 210 | } |
| 211 | |
| 212 | return normalizePresignedData(await response.json(), file.name) |
| 213 | } |
| 214 | |
| 215 | interface UploadViaPutOptions { |
| 216 | file: File |
no test coverage detected