file-type

repository·main·Indexed 26 days ago

https://github.com/sindresorhus/file-type

An ESM library for detecting the file type of a file, stream, or data by checking its magic number (binary signature). Version 22.0.1 provides methods to detect types from file paths (via node:fs), buffers (Uint8Array/ArrayBuffer), web ReadableStreams, Blobs, and tokenizers. It includes the FileTypeParser class for managing custom detectors and supports an AbortSignal for cancelling asynchronous operations.

Tokens
5K
Snippets
19
Records
30
Agent score
88%

What's inside file-type

  1. Add custom detectors to FileTypeParser

    main

    You can extend file-type detection capabilities by providing custom detectors via the customDetectors option in the FileTypeParser constructor. Detectors provided through the constructor are executed before the default ones. This is useful for supporting uncommon file types or non-binary formats.

    Available third-party detectors include:

    • @file-type/av: Audio and video differentiation.
    • @file-type/cfbf: Compound File Binary Format (e.g., Office 97–2003, .msi).
    • @file-type/pdf: PDF-based types (e.g., Adobe Illustrator).
    • @file-type/xml: Common XML types (e.g., GLM, KML, MusicXML, RSS, SVG, XHTML).
    import {FileTypeParser} from 'file-type';
    import {detectXml} from '@file-type/xml';
    
    const parser = new FileTypeParser({customDetectors: [detectXml]});
    const fileType = await parser.fromFile('sample.kml');
    console.log(fileType);
  2. Configure custom detectors and MPEG tolerance

    main

    When calling detection functions, you can pass an options object to customize behavior.

    Options:

    • customDetectors (Array): An array of custom file type detectors to run before the default detectors.
    • mpegOffsetTolerance (number, default: 0): Specifies the byte tolerance for locating the first MPEG audio frame (e.g. .mp1, .mp2, .mp3, .aac). A tolerance of 10 bytes covers most cases of slight sync offsets.
    import {fileTypeFromFile} from 'file-type';
    import {detectXml} from '@file-type/xml';
    
    const fileType = await fileTypeFromFile('sample.kml', {customDetectors: [detectXml]});
    console.log(fileType);
  3. Example: Writing a custom detector

    main

    This example demonstrates how to create a detector for a hypothetical 'unicorn' file type that checks for a specific ASCII header (UNICORN).

    import {FileTypeParser} from 'file-type';
    
    const unicornDetector = {
    	id: 'unicorn', // May be used to recognize the detector in the detector list
    	async detect(tokenizer) {
    		const unicornHeader = [85, 78, 73, 67, 79, 82, 78]; // "UNICORN" in ASCII decimal
    
    		const buffer = new Uint8Array(unicornHeader.length);
    		await tokenizer.peekBuffer(buffer, {length: unicornHeader.length, mayBeLess: true});
    		if (unicornHeader.every((value, index) => value === buffer[index])) {
    			return {ext: 'unicorn', mime: 'application/unicorn'};
    		}
    
    		return undefined;
    	}
    }
    
    const buffer = new Uint8Array([85, 78, 73, 67, 79, 82, 78]);
    const parser = new FileTypeParser({customDetectors: [unicornDetector]});
    const fileType = await parser.fromBuffer(buffer);
    console.log(fileType); // {ext: 'unicorn', mime: 'application/unicorn'}
  4. Detect file type from a Blob with fileTypeFromBlob()

    main

    Use fileTypeFromBlob() to detect the file type of a Blob. A File object is a Blob and can be passed here. This method streams the underlying Blob.

    Returns a Promise that resolves to an object containing ext and mime, or undefined if no match is found.

    import {fileTypeFromBlob} from 'file-type';
    
    const blob = new Blob(['<?xml version="1.0" encoding="ISO-8859-1" ?>'], {
    	type: 'text/plain',
    	endings: 'native'
    });
    
    console.log(await fileTypeFromBlob(blob));
    //=> {ext: 'txt', mime: 'text/plain'}
  5. Detect file type from a tokenizer with fileTypeFromTokenizer()

    main

    Use fileTypeFromTokenizer() to detect the file type from an ITokenizer source. This allows for efficient detection by reading only the minimum amount of data required (e.g., using HTTP range requests or S3 chunked reads).

    Returns a Promise that resolves to an object containing ext and mime, or undefined if no match is found.

    import {makeTokenizer} from '@tokenizer/http';
    import {fileTypeFromTokenizer} from 'file-type';
    
    const audioTrackUrl = 'https://test-audio.netlify.com/Various%20Artists%20-%202009%20-%20netBloc%20Vol%2024_%20tiuqottigeloot%20%5BMP3-V2%5D/01%20-%20Diablo%20Swing%20Orchestra%20-%20Heroines.mp3';
    
    const httpTokenizer = await makeTokenizer(audioTrackUrl);
    const fileType = await fileTypeFromTokenizer(httpTokenizer);
    
    console.log(fileType);
    //=> {ext: 'mp3', mime: 'audio/mpeg'}
  6. Get supported extensions and MIME types

    main

    Use supportedExtensions and supportedMimeTypes to retrieve the sets of file types currently supported by the library.

    • supportedExtensions: Returns a Set<string> of supported file extensions.
    • supportedMimeTypes: Returns a Set<string> of supported MIME types.
  7. Enhance a web stream with fileTypeStream()

    main

    fileTypeStream(webStream, options?) returns a Promise that resolves to the original ReadableStream, but with an added fileType property. This is useful for stream pipelines.

    Internally, it builds a buffer of sampleSize bytes to determine the type. A smaller sample size may reduce detection accuracy.

    Options:

    • sampleSize (number, default: 4100): The sample size in bytes.
    import {fileTypeStream} from 'file-type';
    
    const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';
    
    const response = await fetch(url);
    const stream = await fileTypeStream(response.body, {sampleSize: 1024});
    
    if (stream.fileType?.mime === 'image/jpeg') {
    	// stream can be used to stream the JPEG image (from the very beginning of the stream)
    }
  8. Detect file type from a web stream with fileTypeFromStream()

    main

    Use fileTypeFromStream() to detect the file type of a Web ReadableStream. If you are using a Node.js stream.Readable, convert it using Readable.toWeb() first.

    Returns a Promise that resolves to an object containing ext and mime, or undefined if no match is found.

    import {fileTypeFromStream} from 'file-type';
    
    const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';
    
    const response = await fetch(url);
    const fileType = await fileTypeFromStream(response.body);
    
    console.log(fileType);
    //=> {ext: 'jpg', mime: 'image/jpeg'}
  9. Detect file type from a file path with fileTypeFromFile()

    main

    Use fileTypeFromFile() to determine the file type of a file at a given path. This method is only available in environments where node:fs is available (e.g., Node.js).

    Returns a Promise that resolves to an object containing ext (extension) and mime (MIME type), or undefined if no match is found.

    import {fileTypeFromFile} from 'file-type';
    
    console.log(await fileTypeFromFile('Unicorn.png'));
    //=> {ext: 'png', mime: 'image/png'}
  10. Implement a custom Detector

    main

    A Detector is an object used to extend detection logic. It must include an id and an asynchronous detect method. The detect method receives a tokenizer to read file content and an optional fileType representing results from previous detectors.

    Detector Execution Rules:

    • If a detector returns undefined and does not modify the tokenizer's position, the next detector in the sequence is executed.
    • If a detector returns undefined but does modify the tokenizer's position (tokenizer.position is advanced), no further detectors are executed, and the file type remains undefined.
    /**
    @param tokenizer - The [tokenizer](https://github.com/Borewit/strtok3#tokenizer) used to read file content.
    @param fileType - The file type detected by standard or previous custom detectors, or `undefined` if no match is found.
    @returns The detected file type, or `undefined` if no match is found.
    */
    export type Detector = {
    	id: string;
    	detect: (tokenizer: ITokenizer, fileType?: FileTypeResult) => Promise<FileTypeResult | undefined>;
    };
  11. Detect file type from a buffer with fileTypeFromBuffer()

    main

    Use fileTypeFromBuffer() to detect the file type of a Uint8Array or ArrayBuffer. This is useful when you have a portion of the beginning of a file in memory. If file access is available, fileTypeFromFile() is recommended instead.

    Returns a Promise that resolves to an object containing ext and mime, or undefined if no match is found.

    import {fileTypeFromBuffer} from 'file-type';
    import {readChunk} from 'read-chunk';
    
    const buffer = await readChunk('Unicorn.png', {length: 4100});
    
    console.log(await fileTypeFromBuffer(buffer));
    //=> {ext: 'png', mime: 'image/png'}