# detection/detect ## Purpose The unified MIME detection entry point for `@suaveplan/mime`. Merges evidence from three independent sources — magic bytes, file extension, and a declared `Content-Type` header — using a confidence-scoring model. When sources agree, the confidence is boosted above any single-source threshold. When they disagree, magic bytes win over extension, which wins over declared headers, reflecting real-world reliability. ## Features - Multi-source detection: bytes, extension/filename, Content-Type header - Confidence scores: magic-bytes=0.95, extension=0.7, content-type=0.6 - Agreement boost: +0.05 per additional agreeing source (capped at 1.0) - Falls back to `application/octet-stream` with confidence=0 when no sources available - Accepts `filename` as an alias for `extension` (strips path components automatically) - Swallows malformed Content-Type headers gracefully (no throws) - Re-exports `detectFromMagicBytes` and `detectAllFromMagicBytes` for convenience ## Usage: Basic Example ```typescript import { detect } from "@suaveplan/mime/detection/detect"; const result = detect({ bytes: fileBuffer, filename: "photo.jpg", }); console.log(result.mime); // "image/jpeg" console.log(result.confidence); // 0.95 (magic bytes match) console.log(result.source); // "magic-bytes" ``` ## Usage: Advanced Example ```typescript import { detect } from "@suaveplan/mime/detection/detect"; // All three sources provided — if they agree, confidence is boosted const result = detect({ bytes: buffer, filename: "report.pdf", contentType: "application/pdf", }); if (result.confidence > 0.9) { console.log("High confidence:", result.mime); console.log("Sources:", result.candidates.map(c => c.source)); } // Only extension provided const byExtension = detect({ extension: "svg" }); console.log(byExtension.mime); // "image/svg+xml" console.log(byExtension.confidence); // 0.7 // No sources — safe fallback const fallback = detect({}); console.log(fallback.mime); // "application/octet-stream" console.log(fallback.confidence); // 0 ``` ## API Reference ### `detect(input: DetectInput): DetectResult` | Parameter | Type | Description | |-----------|------|-------------| | `input` | `DetectInput` | Detection inputs — at least one field should be set. | **Returns:** `DetectResult` with `mime`, `confidence`, `source`, and `candidates` array. **Throws:** Never — malformed Content-Type headers are silently ignored. ### `DetectInput` | Field | Type | Description | |-------|------|-------------| | `bytes?` | `Uint8Array` | Raw file bytes for magic-byte detection | | `extension?` | `string` | File extension (with or without dot) | | `filename?` | `string` | Full filename or path (extension extracted automatically) | | `contentType?` | `string` | Raw `Content-Type` header value | ### `DetectResult` | Field | Type | Description | |-------|------|-------------| | `mime` | `string` | Best MIME type guess | | `confidence` | `number` | 0.0–1.0 confidence score | | `source` | `DetectSource` | Primary detection source | | `candidates` | `Candidate[]` | All candidate MIME types with their sources | ## Implementation Notes Candidates are collected in descending confidence order: magic-bytes first, then extension, then content-type. Because this order is fixed and confidence values are monotonically decreasing, the first candidate in the array is always the best. The confidence boost formula `min(1, bestScore + (agreeing - 1) * 0.05)` adds 5% for each additional source that agrees with the winner, reflecting that corroborating evidence raises overall certainty.