(rawMessage = '', depth = 0)
| 277 | } |
| 278 | |
| 279 | function extractTextFromMime(rawMessage = '', depth = 0) { |
| 280 | const { headerText, bodyText } = splitRawMessage(rawMessage); |
| 281 | const headers = parseRawHeaders(headerText); |
| 282 | const contentType = String(headers['content-type'] || ''); |
| 283 | const boundary = getBoundaryFromContentType(contentType); |
| 284 | |
| 285 | if (/multipart\//i.test(contentType) && boundary && depth < 6) { |
| 286 | const marker = `--${boundary}`; |
| 287 | const sections = String(bodyText || '') |
| 288 | .split(marker) |
| 289 | .map((part) => part.trim()) |
| 290 | .filter((part) => part && part !== '--'); |
| 291 | |
| 292 | const extractedParts = sections |
| 293 | .map((part) => part.replace(/--\s*$/, '').trim()) |
| 294 | .map((part) => extractTextFromMime(part, depth + 1)?.text || '') |
| 295 | .filter(Boolean); |
| 296 | |
| 297 | const plainText = extractedParts.join(' ').replace(/\s+/g, ' ').trim(); |
| 298 | return { |
| 299 | headers, |
| 300 | text: plainText, |
| 301 | }; |
| 302 | } |
| 303 | |
| 304 | return { |
| 305 | headers, |
| 306 | text: decodeMimeBody(bodyText, headers), |
| 307 | }; |
| 308 | } |
| 309 | |
| 310 | function normalizeReceivedDateTime(value) { |
| 311 | if (!value && value !== 0) return ''; |
no test coverage detected