@juspay/neurolink
Version:
The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002
107 lines (106 loc) • 5.64 kB
TypeScript
/**
* Canonical file-format registry — the single source of truth for
* extension ↔ MIME ↔ FileType ↔ modality.
*
* ## Why this exists
*
* The same knowledge used to live in five hand-maintained tables that had no
* way of agreeing with each other:
*
* 1. `EXTENSION_MIME_MAP` (config/mimeConstants.ts)
* 2. the `*_EXTENSIONS` category arrays (config/fileExtensions.ts)
* 3. `ExtensionStrategy.typeMap` + `.mimeMap` (utils/fileDetector.ts)
* 4. `EXTENSION_TYPE_MAP` (utils/messageBuilder.ts)
* 5. each processor's `supportedExtensions` / `supportedMimeTypes`
*
* They drifted, and the drift was not cosmetic — a format that a processor
* declared it supported was routinely invisible to the detector standing in
* front of it, so the file never reached the processor at all. Measured on real
* ffmpeg-generated media before this registry existed:
*
* .aiff .m2ts .mts .vob .3g2 .3gp → "unknown" (downgraded to metadata text)
* .mpg .mpeg → "csv" (binary parsed as a spreadsheet)
* .ts → "text" (MPEG-TS inlined as source code)
*
* Deriving all five consumers from one table makes that class of drift
* structurally impossible rather than merely fixed once.
*
* ## Invariants
*
* - `extensions[0]` is canonical for the format; the rest are accepted aliases.
* - `mimeTypes[0]` is canonical; the rest are aliases seen in the wild
* (`audio/x-wav`, `image/x-icon`, vendor prefixes, …).
* - Every extension and every MIME type appears in exactly one entry. The
* `assertRegistryIsUnambiguous()` check below is executed at module load, so
* a duplicate is a startup failure rather than a silent last-write-wins.
* - `fileType` is the *routing* type the detector emits (what processor to
* use); `modality` is the *category* a human means. They deliberately differ:
* an .odt is `fileType: "docx"` (the Word processor handles it) but
* `modality: "document"`, and .svg is `fileType: "svg"` (sanitised as markup,
* never sent to a vision API) but `modality: "image"`.
*
* @module processors/config/fileTypeRegistry
*/
import type { FileFormatEntry, FileModality, FileType } from "../../types/index.js";
/**
* Every file format NeuroLink can identify, grouped by modality.
*
* Adding a format here is all that is required — the extension map, the MIME
* map, the detector's lookup tables, the category arrays and the media
* processors' supported-format lists are all derived from this array.
*/
export declare const FILE_TYPE_REGISTRY: readonly FileFormatEntry[];
/**
* Extensions that must NOT be treated as belonging to their registry entry's
* modality when only a filename is available.
*
* Derived from {@link EXTENSION_OVERRIDES}: `extensionsForModality("video")`
* feeds both `VIDEO_EXTENSIONS` and `VideoProcessor`'s supported list, and
* `BaseFileProcessor.isFileSupported` accepts a file when the *extension*
* matches even if the supplied mimetype says otherwise. Leaving `.ts` in that
* list made `isVideoFile("text/plain", "app.ts")` return true.
*/
/**
* Extension → MIME for the overridden extensions only.
*
* Exported so `EXTENSION_MIME_MAP` can apply the override as its FINAL layer.
* That map is built by spreading the registry over the text map, so without
* this the registry's `.ts → video/mp2t` won again and `getMimeTypeForExtension`
* disagreed with `mimeTypeForExtension` about the very same file.
*/
export declare const EXTENSION_MIME_OVERRIDES: Readonly<Record<string, string>>;
/**
* Normalize an extension to the registry's key form: lowercased, with a leading
* dot. Accepts `"png"`, `".PNG"`, `"image.png"` and `"/tmp/a.png"` alike.
*
* Compound extensions (`.tar.gz`) are matched before the single-segment form so
* a `.tar.gz` resolves to the gzip entry rather than to `.gz` by accident —
* they happen to agree today, but the lookup should not depend on that.
*/
export declare function normalizeExtension(raw: string): string;
/** Look up the registry entry for a file extension, or undefined. */
export declare function lookupByExtension(ext: string): FileFormatEntry | undefined;
/**
* Look up the registry entry for a MIME type, or undefined. Any `;charset=…`
* parameter is stripped, matching how Content-Type headers arrive.
*/
export declare function lookupByMimeType(mime: string): FileFormatEntry | undefined;
/**
* Routing {@link FileType} for an extension, honouring {@link EXTENSION_OVERRIDES}.
* Returns undefined when the extension is not in the registry.
*/
export declare function fileTypeForExtension(ext: string): FileType | undefined;
/** Canonical MIME type for an extension, or undefined when unknown. */
export declare function mimeTypeForExtension(ext: string): string | undefined;
/** Canonical extension (with leading dot) for a MIME type, or undefined. */
export declare function extensionForMimeType(mime: string): string | undefined;
/** Every extension registered for a modality, in registry order. */
export declare function extensionsForModality(modality: FileModality): readonly string[];
/** Every MIME type registered for a modality, in registry order. */
export declare function mimeTypesForModality(modality: FileModality): readonly string[];
/**
* True when the extension belongs to the given modality. Uses the entry's
* modality, not its routing `fileType`, so `.svg` counts as an image and `.odt`
* counts as a document.
*/
export declare function isModalityExtension(ext: string, modality: FileModality): boolean;