(part: Extract<ReplayPart, { type: "file" }>)
| 188 | } |
| 189 | |
| 190 | function filePartToContentChunks(part: Extract<ReplayPart, { type: "file" }>): ContentChunk[] { |
| 191 | if (part.url.startsWith("file://")) { |
| 192 | return [ |
| 193 | { |
| 194 | content: { |
| 195 | type: "resource_link", |
| 196 | uri: part.url, |
| 197 | name: part.filename ?? "file", |
| 198 | mimeType: part.mime, |
| 199 | }, |
| 200 | }, |
| 201 | ] |
| 202 | } |
| 203 | if (!part.url.startsWith("data:")) return [] |
| 204 | |
| 205 | const data = decodeDataUrl(part.url) |
| 206 | if (!data) return [] |
| 207 | if (data.mime.startsWith("image/")) { |
| 208 | return [ |
| 209 | { |
| 210 | content: { |
| 211 | type: "image", |
| 212 | mimeType: data.mime, |
| 213 | data: data.base64, |
| 214 | uri: pathToFileURL(part.filename ?? "image").href, |
| 215 | }, |
| 216 | }, |
| 217 | ] |
| 218 | } |
| 219 | |
| 220 | return [ |
| 221 | { |
| 222 | content: { |
| 223 | type: "resource", |
| 224 | resource: |
| 225 | data.mime.startsWith("text/") || data.mime === "application/json" |
| 226 | ? { |
| 227 | uri: pathToFileURL(part.filename ?? "file").href, |
| 228 | mimeType: data.mime, |
| 229 | text: Buffer.from(data.base64, "base64").toString("utf8"), |
| 230 | } |
| 231 | : { |
| 232 | uri: pathToFileURL(part.filename ?? "file").href, |
| 233 | mimeType: data.mime, |
| 234 | blob: data.base64, |
| 235 | }, |
| 236 | }, |
| 237 | }, |
| 238 | ] |
| 239 | } |
| 240 | |
| 241 | function decodeDataUrl(url: string) { |
| 242 | const match = /^data:([^;]+);base64,(.*)$/.exec(url) |
no test coverage detected