├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.yml │ └── issue.yml ├── funding.yml ├── pull_request_template.md ├── security.md └── workflows │ └── main.yml ├── .gitignore ├── .npmrc ├── contributing.md ├── core.d.ts ├── core.js ├── fixture ├── fixture-0x20001.eot ├── fixture-2.doc.cfb ├── fixture-2.m4v ├── fixture-Leica-M10.dng ├── fixture-adobe-illustrator.pdf ├── fixture-adts-mpeg2.aac ├── fixture-adts-mpeg4-2.aac ├── fixture-adts-mpeg4.aac ├── fixture-ascii.cpio ├── fixture-babys-songbook.m4b.m4a ├── fixture-bad-offset-10.mp3 ├── fixture-bad-offset.mp3 ├── fixture-bali.tif ├── fixture-bdav.mts ├── fixture-big-endian.mie ├── fixture-big-endian.pcap ├── fixture-big-endian.tif ├── fixture-bin.cpio ├── fixture-corrupt.mkv ├── fixture-corrupt.png ├── fixture-crlf.epub ├── fixture-cube_pc.drc ├── fixture-dash.mp4 ├── fixture-fast-web.pdf ├── fixture-ffe3.mp3 ├── fixture-heic.heic ├── fixture-hp1.jls ├── fixture-hp2.jls ├── fixture-hp3.jls ├── fixture-id3v2.aac ├── fixture-id3v2.flac ├── fixture-imovie.mp4 ├── fixture-isom.mp4 ├── fixture-isomv2.mp4 ├── fixture-itxt.png ├── fixture-json.webp ├── fixture-line-weights.dwg ├── fixture-little-endian.mie ├── fixture-little-endian.pcap ├── fixture-little-endian.tif ├── fixture-mif1.heic ├── fixture-minimal.pdf ├── fixture-mjpeg.mov ├── fixture-monkeysaudio.ape ├── fixture-moov.mov ├── fixture-mp2l3.mp3 ├── fixture-mp4v2.mp4 ├── fixture-mpa.mp2 ├── fixture-msf1.heic ├── fixture-normal.jls ├── fixture-null.webm ├── fixture-office365.docx ├── fixture-office365.pptx ├── fixture-office365.xlsx ├── fixture-otto.woff ├── fixture-otto.woff2 ├── fixture-password-protected.xls ├── fixture-pax.tar ├── fixture-printed.pdf ├── fixture-raw.mts ├── fixture-realmedia-audio.rm ├── fixture-realmedia-video.rm ├── fixture-sample.pst ├── fixture-sequence.avif ├── fixture-smallest.pdf ├── fixture-sony-zv-e10.arw ├── fixture-spaces.tar ├── fixture-sv7.mpc ├── fixture-sv8.mpc ├── fixture-unknown-ogg.ogx ├── fixture-utf16-be-bom.xml ├── fixture-utf16-le-bom.xml ├── fixture-utf8-bom.xml ├── fixture-v7.tar ├── fixture-vsdx.vsdx ├── fixture-vstx.vsdx ├── fixture-vtt-eof.vtt ├── fixture-vtt-linebreak.vtt ├── fixture-vtt-space.vtt ├── fixture-vtt-tab.vtt ├── fixture-yuv420-8bit.avif ├── fixture.3g2 ├── fixture.3gp ├── fixture.3mf ├── fixture.7z ├── fixture.ac3 ├── fixture.ace ├── fixture.aif ├── fixture.alias ├── fixture.amr ├── fixture.apk ├── fixture.apng ├── fixture.ar ├── fixture.arj ├── fixture.arrow ├── fixture.asar ├── fixture.asf ├── fixture.avi ├── fixture.avro ├── fixture.blend ├── fixture.bmp ├── fixture.bpg ├── fixture.bz2 ├── fixture.cab ├── fixture.chm ├── fixture.class ├── fixture.cr2 ├── fixture.cr3 ├── fixture.crx ├── fixture.cur ├── fixture.dcm ├── fixture.deb ├── fixture.dmg ├── fixture.doc.cfb ├── fixture.docm ├── fixture.docx ├── fixture.dotm ├── fixture.dotx ├── fixture.dsf ├── fixture.elf ├── fixture.eot ├── fixture.eps ├── fixture.epub ├── fixture.exe ├── fixture.f4a ├── fixture.f4b ├── fixture.f4p ├── fixture.f4v ├── fixture.fbx ├── fixture.flac ├── fixture.flif ├── fixture.flv ├── fixture.gif ├── fixture.glb ├── fixture.icc ├── fixture.icns ├── fixture.ico ├── fixture.ics ├── fixture.indd ├── fixture.it ├── fixture.j2c ├── fixture.jar ├── fixture.jp2 ├── fixture.jpg ├── fixture.jpm ├── fixture.jpx ├── fixture.jxl ├── fixture.jxr ├── fixture.ktx ├── fixture.lnk ├── fixture.lz4 ├── fixture.lzh ├── fixture.m4a ├── fixture.m4b ├── fixture.m4p ├── fixture.m4v ├── fixture.macho ├── fixture.mid ├── fixture.mj2 ├── fixture.mkv ├── fixture.mobi ├── fixture.mov ├── fixture.mp1 ├── fixture.mp2 ├── fixture.mp3 ├── fixture.mpg ├── fixture.msi.cfb ├── fixture.mxf ├── fixture.nef ├── fixture.nes ├── fixture.odg ├── fixture.odp ├── fixture.ods ├── fixture.odt ├── fixture.oga ├── fixture.ogg ├── fixture.ogm ├── fixture.ogv ├── fixture.opus ├── fixture.orf ├── fixture.otf ├── fixture.otg ├── fixture.otp ├── fixture.ots ├── fixture.ott ├── fixture.parquet ├── fixture.pdf ├── fixture.pgp ├── fixture.png ├── fixture.potm ├── fixture.potx ├── fixture.ppsm ├── fixture.ppsx ├── fixture.ppt.cfb ├── fixture.pptm ├── fixture.pptx ├── fixture.ps ├── fixture.ps.mpg ├── fixture.psd ├── fixture.qcp ├── fixture.raf ├── fixture.rar ├── fixture.rpm ├── fixture.rtf ├── fixture.rw2 ├── fixture.s3m ├── fixture.shp ├── fixture.skp ├── fixture.spx ├── fixture.sqlite ├── fixture.stl ├── fixture.sub.mpg ├── fixture.swf ├── fixture.tar ├── fixture.tar.Z ├── fixture.tar.gz ├── fixture.tar.lz ├── fixture.tar.xz ├── fixture.tar.zst ├── fixture.ttc ├── fixture.ttf ├── fixture.unicorn ├── fixture.vcf ├── fixture.voc ├── fixture.wasm ├── fixture.wav ├── fixture.webm ├── fixture.webp ├── fixture.wma.asf ├── fixture.wmv.asf ├── fixture.woff ├── fixture.woff2 ├── fixture.wv ├── fixture.xcf ├── fixture.xls.cfb ├── fixture.xlsm ├── fixture.xlsx ├── fixture.xltm ├── fixture.xltx ├── fixture.xm ├── fixture.xml ├── fixture.xpi ├── fixture.zip ├── fixture2.3gp ├── fixture2.asar ├── fixture2.docx ├── fixture2.eps ├── fixture2.jxl ├── fixture2.mkv ├── fixture2.mpg ├── fixture2.nef ├── fixture2.pptx ├── fixture2.xlsx ├── fixture3.nef └── fixture4.nef ├── index.d.ts ├── index.js ├── index.test-d.ts ├── license ├── media └── logo.jpg ├── package.json ├── readme.md ├── supported.js ├── test.js ├── type.js └── util.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.yml] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Suggest an improvement or new feature 2 | description: ——— 3 | labels: enhancement 4 | body: 5 | - type: textarea 6 | attributes: 7 | label: Description 8 | validations: 9 | required: true 10 | - type: checkboxes 11 | attributes: 12 | label: Existing Issue Check 13 | description: Please search for existing issues to avoid duplicates. 14 | options: 15 | - label: 'I have searched the existing issues and could not find any related to my problem.' 16 | required: true 17 | - type: checkboxes 18 | attributes: 19 | label: File-Type Scope Acknowledgment 20 | description: This package is designed to detect well-known **binary**-based file types only. 21 | options: 22 | - label: 'I understand that file-type detects binary file types and not text or other formats.' 23 | required: true 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/issue.yml: -------------------------------------------------------------------------------- 1 | name: Report a bug 2 | description: ——— 3 | labels: bug 4 | body: 5 | - type: textarea 6 | attributes: 7 | label: Description 8 | validations: 9 | required: true 10 | - type: checkboxes 11 | attributes: 12 | label: Existing Issue Check 13 | description: Please search for existing issues to avoid duplicates. 14 | options: 15 | - label: 'I have searched the existing issues and could not find any related to my problem.' 16 | required: true 17 | - type: checkboxes 18 | attributes: 19 | label: ESM (ECMAScript Module) Requirement Acknowledgment 20 | description: This package is an ECMAScript Module (ESM) only. CommonJS is **not** supported. 21 | options: 22 | - label: 'My project is an [ESM project](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) and my `package.json` contains the following entry: `"type": "module"`.' 23 | required: true 24 | - type: checkboxes 25 | attributes: 26 | label: File-Type Scope Acknowledgment 27 | description: This package is designed to detect well-known **binary**-based file types only. 28 | options: 29 | - label: 'I understand that file-type detects binary file types and not text or other formats.' 30 | required: true 31 | -------------------------------------------------------------------------------- /.github/funding.yml: -------------------------------------------------------------------------------- 1 | github: [sindresorhus, Borewit] 2 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | If you're adding support for a new file type, please follow the below steps: 2 | 3 | - **One PR per file type.** 4 | - Add a fixture file named `fixture.` to the `fixture` directory. 5 | - Add the file extension to the `extensions` array in `supported.js`. 6 | - Add the file's MIME type to the `types` array in `supported.js`. 7 | - Add the file type detection logic to the `core.js` file. 8 | - Determine the appropriate detection confidence category: 9 | - `detectConfident()`: Detections with a high degree of certainty in identifying the correct file type. 10 | - `detectImprecise()`: Detections with limited supporting data, resulting in a higher likelihood of false positives. 11 | - Respect the sequence: 12 | - Signature with shorter sample size (counted from offset 0 until the last required byte position) will be executed first. 13 | - Only the initial determination for the file type counts for the sequence. 14 | - Existing signatures requiring same sample length (same *signature group*) will be tested prior to your new detections. Yours will be last. (rational: common formats first). 15 | - Add the file extension to the `Supported file types` section of the readme in alphabetical order, in the format ```- [``](URL) - Format name```, for example, ```- [`png`](https://en.wikipedia.org/wiki/Portable_Network_Graphics) - Portable Network Graphics``` 16 | - Add the file extension to the `keywords` array in the `package.json` file. 17 | - Run `$ npm test` to ensure the tests pass. 18 | - Open a pull request with a title like `Add support for Format`, for example, `Add support for PNG`. 19 | - The pull request description should include a link to the official page of the file format or some other source. Also include a link to where you found the file type detection / magic bytes and the MIME type. 20 | -------------------------------------------------------------------------------- /.github/security.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. 4 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | - push 4 | - pull_request 5 | jobs: 6 | test: 7 | name: Node.js ${{ matrix.node-version }} 8 | runs-on: ubuntu-latest 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | node-version: 13 | - 24 14 | - 22 15 | - 20 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: actions/setup-node@v4 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | - run: npm install 22 | - run: npm test 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn.lock 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | If you're adding support for a new file type, [please follow these steps](.github/pull_request_template.md). 4 | -------------------------------------------------------------------------------- /core.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Typings for primary entry point, Node.js specific typings can be found in index.d.ts 3 | */ 4 | 5 | import type {ReadableStream as WebReadableStream} from 'node:stream/web'; 6 | import type {ITokenizer, AnyWebByteStream} from 'strtok3'; 7 | 8 | /** 9 | Either the Node.js ReadableStream or the `lib.dom.d.ts` ReadableStream. 10 | Related issue: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/60377 11 | */ 12 | export type AnyWebReadableStream = WebReadableStream | ReadableStream; 13 | 14 | export type FileTypeResult = { 15 | /** 16 | One of the supported [file types](https://github.com/sindresorhus/file-type#supported-file-types). 17 | */ 18 | readonly ext: string; 19 | 20 | /** 21 | The detected [MIME type](https://en.wikipedia.org/wiki/Internet_media_type). 22 | */ 23 | readonly mime: string; 24 | }; 25 | 26 | /** 27 | Detect the file type of a `Uint8Array` or `ArrayBuffer`. 28 | 29 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the buffer. 30 | 31 | If file access is available, it is recommended to use `.fromFile()` instead. 32 | 33 | @param buffer - An Uint8Array or ArrayBuffer representing file data. It works best if the buffer contains the entire file. It may work with a smaller portion as well. 34 | @param options - Options to override default behavior. 35 | @returns The detected file type, or `undefined` when there is no match. 36 | */ 37 | export function fileTypeFromBuffer(buffer: Uint8Array | ArrayBuffer, options?: FileTypeOptions): Promise; 38 | 39 | /** 40 | Detect the file type of a [web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream). 41 | 42 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the buffer. 43 | 44 | @param stream - A [web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) streaming a file to examine. 45 | @param options - Options to override default behavior. 46 | @returns A `Promise` for an object with the detected file type, or `undefined` when there is no match. 47 | */ 48 | export function fileTypeFromStream(stream: AnyWebByteStream, options?: FileTypeOptions): Promise; 49 | 50 | /** 51 | Detect the file type from an [`ITokenizer`](https://github.com/Borewit/strtok3#tokenizer) source. 52 | 53 | This method is used internally, but can also be used for a special "tokenizer" reader. 54 | 55 | A tokenizer propagates the internal read functions, allowing alternative transport mechanisms, to access files, to be implemented and used. 56 | 57 | @param tokenizer - File source implementing the tokenizer interface. 58 | @param options - Options to override default behavior. 59 | @returns The detected file type, or `undefined` when there is no match. 60 | 61 | An example is [`@tokenizer/http`](https://github.com/Borewit/tokenizer-http), which requests data using [HTTP-range-requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests). A difference with a conventional stream and the [*tokenizer*](https://github.com/Borewit/strtok3#tokenizer), is that it is able to *ignore* (seek, fast-forward) in the stream. For example, you may only need and read the first 6 bytes, and the last 128 bytes, which may be an advantage in case reading the entire file would take longer. 62 | 63 | @example 64 | ``` 65 | import {makeTokenizer} from '@tokenizer/http'; 66 | import {fileTypeFromTokenizer} from 'file-type'; 67 | 68 | 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'; 69 | 70 | const httpTokenizer = await makeTokenizer(audioTrackUrl); 71 | const fileType = await fileTypeFromTokenizer(httpTokenizer); 72 | 73 | console.log(fileType); 74 | //=> {ext: 'mp3', mime: 'audio/mpeg'} 75 | ``` 76 | */ 77 | export function fileTypeFromTokenizer(tokenizer: ITokenizer, options?: FileTypeOptions): Promise; 78 | 79 | /** 80 | Supported file extensions. 81 | */ 82 | export const supportedExtensions: ReadonlySet; 83 | 84 | /** 85 | Supported MIME types. 86 | */ 87 | export const supportedMimeTypes: ReadonlySet; 88 | 89 | export type StreamOptions = { 90 | /** 91 | The default sample size in bytes. 92 | 93 | @default 4100 94 | */ 95 | readonly sampleSize?: number; 96 | }; 97 | 98 | /** 99 | Detect the file type of a [`Blob`](https://nodejs.org/api/buffer.html#class-blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). 100 | 101 | @param blob - The [`Blob`](https://nodejs.org/api/buffer.html#class-blob) used for file detection. 102 | @param options - Options to override default behavior. 103 | @returns The detected file type, or `undefined` when there is no match. 104 | 105 | @example 106 | ``` 107 | import {fileTypeFromBlob} from 'file-type'; 108 | 109 | const blob = new Blob([''], { 110 | type: 'text/plain', 111 | endings: 'native' 112 | }); 113 | 114 | console.log(await fileTypeFromBlob(blob)); 115 | //=> {ext: 'txt', mime: 'text/plain'} 116 | ``` 117 | */ 118 | export declare function fileTypeFromBlob(blob: Blob, options?: FileTypeOptions): Promise; 119 | 120 | /** 121 | A custom file type detector. 122 | 123 | Custom file type detectors are plugins designed to extend the default detection capabilities. 124 | They allow support for uncommon file types, non-binary formats, or customized detection behavior. 125 | 126 | Detectors can be added via the constructor options or by modifying `FileTypeParser#detectors` directly. 127 | Detectors provided through the constructor are executed before the default ones. 128 | 129 | Detectors can be added via the constructor options or by directly modifying `FileTypeParser#detectors`. 130 | 131 | ### Example adding a detector 132 | 133 | ```js 134 | import {FileTypeParser} from 'file-type'; 135 | import {detectXml} from '@file-type/xml'; 136 | 137 | const parser = new FileTypeParser({customDetectors: [detectXml]}); 138 | const fileType = await parser.fromFile('sample.kml'); 139 | console.log(fileType); 140 | ``` 141 | 142 | ### Available-third party file-type detectors 143 | 144 | - [@file-type/xml](https://github.com/Borewit/file-type-xml): Detects common XML file types, such as GLM, KML, MusicXML, RSS, SVG, and XHTML 145 | 146 | ### Detector execution flow 147 | 148 | If a detector returns `undefined`, the following rules apply: 149 | 150 | 1. **No Tokenizer Interaction**: If the detector does not modify the tokenizer's position, the next detector in the sequence is executed. 151 | 2. **Tokenizer Interaction**: If the detector modifies the tokenizer's position (`tokenizer.position` is advanced), no further detectors are executed. In this case, the file type remains `undefined`, as subsequent detectors cannot evaluate the content. This is an exceptional scenario, as it prevents any other detectors from determining the file type. 152 | 153 | ### Example writing a custom detector 154 | 155 | Below is an example of a custom detector array. This can be passed to the `FileTypeParser` via the `fileTypeOptions` argument. 156 | 157 | ``` 158 | import {FileTypeParser} from 'file-type'; 159 | 160 | const customDetectors = [ 161 | async tokenizer => { 162 | const unicornHeader = [85, 78, 73, 67, 79, 82, 78]; // "UNICORN" in ASCII decimal 163 | 164 | const buffer = new Uint8Array(unicornHeader.length); 165 | await tokenizer.peekBuffer(buffer, {length: unicornHeader.length, mayBeLess: true}); 166 | if (unicornHeader.every((value, index) => value === buffer[index])) { 167 | return {ext: 'unicorn', mime: 'application/unicorn'}; 168 | } 169 | 170 | return undefined; 171 | }, 172 | ]; 173 | 174 | const buffer = new Uint8Array([85, 78, 73, 67, 79, 82, 78]); 175 | const parser = new FileTypeParser({customDetectors}); 176 | const fileType = await parser.fromBuffer(buffer); 177 | console.log(fileType); // {ext: 'unicorn', mime: 'application/unicorn'} 178 | ``` 179 | 180 | @param tokenizer - The [tokenizer](https://github.com/Borewit/strtok3#tokenizer) used to read file content. 181 | @param fileType - The file type detected by standard or previous custom detectors, or `undefined` if no match is found. 182 | @returns The detected file type, or `undefined` if no match is found. 183 | */ 184 | export type Detector = { 185 | id: string; 186 | detect: (tokenizer: ITokenizer, fileType?: FileTypeResult) => Promise; 187 | }; 188 | 189 | export type FileTypeOptions = { 190 | customDetectors?: Iterable; 191 | 192 | /** 193 | Specifies the byte tolerance for locating the first MPEG audio frame (e.g. `.mp1`, `.mp2`, `.mp3`, `.aac`). 194 | 195 | Allows detection to handle slight sync offsets between the expected and actual frame start. Common in malformed or incorrectly muxed files, which, while technically invalid, do occur in the wild. 196 | 197 | A tolerance of 10 bytes covers most cases. 198 | 199 | @default 0 200 | */ 201 | mpegOffsetTolerance?: number; 202 | }; 203 | 204 | export declare class TokenizerPositionError extends Error { 205 | constructor(message?: string); 206 | } 207 | 208 | export type AnyWebReadableByteStreamWithFileType = AnyWebReadableStream & { 209 | readonly fileType?: FileTypeResult; 210 | }; 211 | 212 | /** 213 | Workaround for using `bundler` as the module-resolution in TypeScript. 214 | */ 215 | export function fileTypeFromFile(filePath: string, options?: {customDetectors?: Iterable}): Promise; 216 | 217 | /** 218 | Returns a `Promise` which resolves to the original readable stream argument, but with an added `fileType` property, which is an object like the one returned from `fileTypeFromFile()`. 219 | 220 | This method can be handy to put in a stream pipeline, but it comes with a price. Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample, to determine the file type. The sample size impacts the file detection resolution. A smaller sample size will result in lower probability of the best file type detection. 221 | */ 222 | export function fileTypeStream(webStream: AnyWebReadableStream, options?: StreamOptions): Promise; 223 | 224 | export declare class FileTypeParser { 225 | /** 226 | File type detectors. 227 | 228 | Initialized with a single entry holding the built-in detector function. 229 | */ 230 | detectors: Detector[]; 231 | 232 | constructor(options?: {customDetectors?: Iterable; signal?: AbortSignal}); 233 | 234 | /** 235 | Works the same way as {@link fileTypeFromBuffer}, additionally taking into account custom detectors (if any were provided to the constructor). 236 | */ 237 | fromBuffer(buffer: Uint8Array | ArrayBuffer): Promise; 238 | 239 | /** 240 | Works the same way as {@link fileTypeFromTokenizer}, additionally taking into account custom detectors (if any were provided to the constructor). 241 | */ 242 | fromTokenizer(tokenizer: ITokenizer): Promise; 243 | 244 | /** 245 | Works the same way as {@link fileTypeFromBlob}, additionally taking into account custom detectors (if any were provided to the constructor). 246 | */ 247 | fromBlob(blob: Blob): Promise; 248 | 249 | /** 250 | Works the same way as {@link fileTypeStream}, additionally taking into account custom detectors (if any were provided to the constructor). 251 | */ 252 | toDetectionStream(webStream: AnyWebReadableStream, options?: StreamOptions): Promise; 253 | } 254 | -------------------------------------------------------------------------------- /fixture/fixture-0x20001.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-0x20001.eot -------------------------------------------------------------------------------- /fixture/fixture-2.doc.cfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-2.doc.cfb -------------------------------------------------------------------------------- /fixture/fixture-2.m4v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-2.m4v -------------------------------------------------------------------------------- /fixture/fixture-Leica-M10.dng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-Leica-M10.dng -------------------------------------------------------------------------------- /fixture/fixture-adobe-illustrator.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-adobe-illustrator.pdf -------------------------------------------------------------------------------- /fixture/fixture-adts-mpeg2.aac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-adts-mpeg2.aac -------------------------------------------------------------------------------- /fixture/fixture-adts-mpeg4-2.aac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-adts-mpeg4-2.aac -------------------------------------------------------------------------------- /fixture/fixture-adts-mpeg4.aac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-adts-mpeg4.aac -------------------------------------------------------------------------------- /fixture/fixture-ascii.cpio: -------------------------------------------------------------------------------- 1 | 0707070000475347511006440017500017500000010000001441141455100000600000000006smallsmall 2 | 0707070000000000000000000000000000000000010000000000000000000001300000000000TRAILER!!! -------------------------------------------------------------------------------- /fixture/fixture-babys-songbook.m4b.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-babys-songbook.m4b.m4a -------------------------------------------------------------------------------- /fixture/fixture-bad-offset-10.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-bad-offset-10.mp3 -------------------------------------------------------------------------------- /fixture/fixture-bad-offset.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-bad-offset.mp3 -------------------------------------------------------------------------------- /fixture/fixture-bali.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-bali.tif -------------------------------------------------------------------------------- /fixture/fixture-bdav.mts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-bdav.mts -------------------------------------------------------------------------------- /fixture/fixture-big-endian.mie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-big-endian.mie -------------------------------------------------------------------------------- /fixture/fixture-big-endian.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-big-endian.pcap -------------------------------------------------------------------------------- /fixture/fixture-big-endian.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-big-endian.tif -------------------------------------------------------------------------------- /fixture/fixture-bin.cpio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-bin.cpio -------------------------------------------------------------------------------- /fixture/fixture-corrupt.mkv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-corrupt.mkv -------------------------------------------------------------------------------- /fixture/fixture-corrupt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-corrupt.png -------------------------------------------------------------------------------- /fixture/fixture-crlf.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-crlf.epub -------------------------------------------------------------------------------- /fixture/fixture-cube_pc.drc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-cube_pc.drc -------------------------------------------------------------------------------- /fixture/fixture-dash.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-dash.mp4 -------------------------------------------------------------------------------- /fixture/fixture-fast-web.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-fast-web.pdf -------------------------------------------------------------------------------- /fixture/fixture-ffe3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-ffe3.mp3 -------------------------------------------------------------------------------- /fixture/fixture-heic.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-heic.heic -------------------------------------------------------------------------------- /fixture/fixture-hp1.jls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-hp1.jls -------------------------------------------------------------------------------- /fixture/fixture-hp2.jls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-hp2.jls -------------------------------------------------------------------------------- /fixture/fixture-hp3.jls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-hp3.jls -------------------------------------------------------------------------------- /fixture/fixture-id3v2.aac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-id3v2.aac -------------------------------------------------------------------------------- /fixture/fixture-id3v2.flac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-id3v2.flac -------------------------------------------------------------------------------- /fixture/fixture-imovie.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-imovie.mp4 -------------------------------------------------------------------------------- /fixture/fixture-isom.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-isom.mp4 -------------------------------------------------------------------------------- /fixture/fixture-isomv2.mp4: -------------------------------------------------------------------------------- 1 | ftypmp42 -------------------------------------------------------------------------------- /fixture/fixture-itxt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-itxt.png -------------------------------------------------------------------------------- /fixture/fixture-json.webp: -------------------------------------------------------------------------------- 1 | { "WEBP": {}} 2 | -------------------------------------------------------------------------------- /fixture/fixture-line-weights.dwg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-line-weights.dwg -------------------------------------------------------------------------------- /fixture/fixture-little-endian.mie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-little-endian.mie -------------------------------------------------------------------------------- /fixture/fixture-little-endian.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-little-endian.pcap -------------------------------------------------------------------------------- /fixture/fixture-little-endian.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-little-endian.tif -------------------------------------------------------------------------------- /fixture/fixture-mif1.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-mif1.heic -------------------------------------------------------------------------------- /fixture/fixture-minimal.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.1 2 | %¥±ë 3 | 4 | 1 0 obj 5 | << /Type /Catalog 6 | /Pages 2 0 R 7 | >> 8 | endobj 9 | 10 | 2 0 obj 11 | << /Type /Pages 12 | /Kids [3 0 R] 13 | /Count 1 14 | /MediaBox [0 0 300 144] 15 | >> 16 | endobj 17 | 18 | 3 0 obj 19 | << /Type /Page 20 | /Parent 2 0 R 21 | /Resources 22 | << /Font 23 | << /F1 24 | << /Type /Font 25 | /Subtype /Type1 26 | /BaseFont /Times-Roman 27 | >> 28 | >> 29 | >> 30 | /Contents 4 0 R 31 | >> 32 | endobj 33 | 34 | 4 0 obj 35 | << /Length 55 >> 36 | stream 37 | BT 38 | /F1 18 Tf 39 | 0 0 Td 40 | (Hello World) Tj 41 | ET 42 | endstream 43 | endobj 44 | 45 | xref 46 | 0 5 47 | 0000000000 65535 f 48 | 0000000018 00000 n 49 | 0000000077 00000 n 50 | 0000000178 00000 n 51 | 0000000457 00000 n 52 | trailer 53 | << /Root 1 0 R 54 | /Size 5 55 | >> 56 | startxref 57 | 565 58 | %%EOF 59 | -------------------------------------------------------------------------------- /fixture/fixture-mjpeg.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-mjpeg.mov -------------------------------------------------------------------------------- /fixture/fixture-monkeysaudio.ape: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-monkeysaudio.ape -------------------------------------------------------------------------------- /fixture/fixture-moov.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-moov.mov -------------------------------------------------------------------------------- /fixture/fixture-mp2l3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-mp2l3.mp3 -------------------------------------------------------------------------------- /fixture/fixture-mp4v2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-mp4v2.mp4 -------------------------------------------------------------------------------- /fixture/fixture-mpa.mp2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-mpa.mp2 -------------------------------------------------------------------------------- /fixture/fixture-msf1.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-msf1.heic -------------------------------------------------------------------------------- /fixture/fixture-normal.jls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-normal.jls -------------------------------------------------------------------------------- /fixture/fixture-null.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-null.webm -------------------------------------------------------------------------------- /fixture/fixture-office365.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-office365.docx -------------------------------------------------------------------------------- /fixture/fixture-office365.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-office365.pptx -------------------------------------------------------------------------------- /fixture/fixture-office365.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-office365.xlsx -------------------------------------------------------------------------------- /fixture/fixture-otto.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-otto.woff -------------------------------------------------------------------------------- /fixture/fixture-otto.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-otto.woff2 -------------------------------------------------------------------------------- /fixture/fixture-password-protected.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-password-protected.xls -------------------------------------------------------------------------------- /fixture/fixture-pax.tar: -------------------------------------------------------------------------------- 1 | pax_global_header00006660000000000000000000000064146032526370014522gustar00rootroot0000000000000052 comment=dacf7e83da42bd9d3978560e41869a784c24d912 2 | linux-6.7.12/000077500000000000000000000000001460325263700127565ustar00rootroot00000000000000linux-6.7.12/.clang-format000066400000000000000000000501211460325263700153300ustar00rootroot00000000000000 -------------------------------------------------------------------------------- /fixture/fixture-printed.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-printed.pdf -------------------------------------------------------------------------------- /fixture/fixture-raw.mts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-raw.mts -------------------------------------------------------------------------------- /fixture/fixture-realmedia-audio.rm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-realmedia-audio.rm -------------------------------------------------------------------------------- /fixture/fixture-realmedia-video.rm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-realmedia-video.rm -------------------------------------------------------------------------------- /fixture/fixture-sample.pst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-sample.pst -------------------------------------------------------------------------------- /fixture/fixture-sequence.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-sequence.avif -------------------------------------------------------------------------------- /fixture/fixture-smallest.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-smallest.pdf -------------------------------------------------------------------------------- /fixture/fixture-sony-zv-e10.arw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-sony-zv-e10.arw -------------------------------------------------------------------------------- /fixture/fixture-spaces.tar: -------------------------------------------------------------------------------- 1 | proc_module.xml100600 0 0 140433073 13706574161 12410 0ustar00rootroot -------------------------------------------------------------------------------- /fixture/fixture-sv7.mpc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-sv7.mpc -------------------------------------------------------------------------------- /fixture/fixture-sv8.mpc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-sv8.mpc -------------------------------------------------------------------------------- /fixture/fixture-unknown-ogg.ogx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-unknown-ogg.ogx -------------------------------------------------------------------------------- /fixture/fixture-utf16-be-bom.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-utf16-be-bom.xml -------------------------------------------------------------------------------- /fixture/fixture-utf16-le-bom.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-utf16-le-bom.xml -------------------------------------------------------------------------------- /fixture/fixture-utf8-bom.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | UTF-8 with BOM 4 | 5 | -------------------------------------------------------------------------------- /fixture/fixture-v7.tar: -------------------------------------------------------------------------------- 1 | test0000644000175000017500000000000013454610422006670 00000000000000 -------------------------------------------------------------------------------- /fixture/fixture-vsdx.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-vsdx.vsdx -------------------------------------------------------------------------------- /fixture/fixture-vstx.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-vstx.vsdx -------------------------------------------------------------------------------- /fixture/fixture-vtt-eof.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT -------------------------------------------------------------------------------- /fixture/fixture-vtt-linebreak.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | 00:11.000 --> 00:13.000 4 | Test WEBVTT prefix followed by a line break -------------------------------------------------------------------------------- /fixture/fixture-vtt-space.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 00:11.000 --> 00:13.000 2 | Test WEBVTT prefix followed by a space -------------------------------------------------------------------------------- /fixture/fixture-vtt-tab.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 00:11.000 --> 00:13.000 2 | Test WEBVTT prefix followed by a tab -------------------------------------------------------------------------------- /fixture/fixture-yuv420-8bit.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture-yuv420-8bit.avif -------------------------------------------------------------------------------- /fixture/fixture.3g2: -------------------------------------------------------------------------------- 1 | ftyp3g2a -------------------------------------------------------------------------------- /fixture/fixture.3gp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.3gp -------------------------------------------------------------------------------- /fixture/fixture.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.3mf -------------------------------------------------------------------------------- /fixture/fixture.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.7z -------------------------------------------------------------------------------- /fixture/fixture.ac3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ac3 -------------------------------------------------------------------------------- /fixture/fixture.ace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ace -------------------------------------------------------------------------------- /fixture/fixture.aif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.aif -------------------------------------------------------------------------------- /fixture/fixture.alias: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.alias -------------------------------------------------------------------------------- /fixture/fixture.amr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.amr -------------------------------------------------------------------------------- /fixture/fixture.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.apk -------------------------------------------------------------------------------- /fixture/fixture.apng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.apng -------------------------------------------------------------------------------- /fixture/fixture.ar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ar -------------------------------------------------------------------------------- /fixture/fixture.arj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.arj -------------------------------------------------------------------------------- /fixture/fixture.arrow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.arrow -------------------------------------------------------------------------------- /fixture/fixture.asar: -------------------------------------------------------------------------------- 1 | <81{"files":{"sample.txt":{"size":11,"offset":"0"}}}helloworld 2 | -------------------------------------------------------------------------------- /fixture/fixture.asf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.asf -------------------------------------------------------------------------------- /fixture/fixture.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.avi -------------------------------------------------------------------------------- /fixture/fixture.avro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.avro -------------------------------------------------------------------------------- /fixture/fixture.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.blend -------------------------------------------------------------------------------- /fixture/fixture.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.bmp -------------------------------------------------------------------------------- /fixture/fixture.bpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.bpg -------------------------------------------------------------------------------- /fixture/fixture.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.bz2 -------------------------------------------------------------------------------- /fixture/fixture.cab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.cab -------------------------------------------------------------------------------- /fixture/fixture.chm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.chm -------------------------------------------------------------------------------- /fixture/fixture.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.class -------------------------------------------------------------------------------- /fixture/fixture.cr2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.cr2 -------------------------------------------------------------------------------- /fixture/fixture.cr3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.cr3 -------------------------------------------------------------------------------- /fixture/fixture.crx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.crx -------------------------------------------------------------------------------- /fixture/fixture.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.cur -------------------------------------------------------------------------------- /fixture/fixture.dcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.dcm -------------------------------------------------------------------------------- /fixture/fixture.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.deb -------------------------------------------------------------------------------- /fixture/fixture.dmg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.dmg -------------------------------------------------------------------------------- /fixture/fixture.doc.cfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.doc.cfb -------------------------------------------------------------------------------- /fixture/fixture.docm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.docm -------------------------------------------------------------------------------- /fixture/fixture.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.docx -------------------------------------------------------------------------------- /fixture/fixture.dotm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.dotm -------------------------------------------------------------------------------- /fixture/fixture.dotx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.dotx -------------------------------------------------------------------------------- /fixture/fixture.dsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.dsf -------------------------------------------------------------------------------- /fixture/fixture.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.elf -------------------------------------------------------------------------------- /fixture/fixture.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.eot -------------------------------------------------------------------------------- /fixture/fixture.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.eps -------------------------------------------------------------------------------- /fixture/fixture.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.epub -------------------------------------------------------------------------------- /fixture/fixture.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.exe -------------------------------------------------------------------------------- /fixture/fixture.f4a: -------------------------------------------------------------------------------- 1 | ftypF4A -------------------------------------------------------------------------------- /fixture/fixture.f4b: -------------------------------------------------------------------------------- 1 | ftypF4B -------------------------------------------------------------------------------- /fixture/fixture.f4p: -------------------------------------------------------------------------------- 1 | ftypF4P -------------------------------------------------------------------------------- /fixture/fixture.f4v: -------------------------------------------------------------------------------- 1 | ftypF4V -------------------------------------------------------------------------------- /fixture/fixture.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.fbx -------------------------------------------------------------------------------- /fixture/fixture.flac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.flac -------------------------------------------------------------------------------- /fixture/fixture.flif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.flif -------------------------------------------------------------------------------- /fixture/fixture.flv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.flv -------------------------------------------------------------------------------- /fixture/fixture.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.gif -------------------------------------------------------------------------------- /fixture/fixture.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.glb -------------------------------------------------------------------------------- /fixture/fixture.icc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.icc -------------------------------------------------------------------------------- /fixture/fixture.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.icns -------------------------------------------------------------------------------- /fixture/fixture.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ico -------------------------------------------------------------------------------- /fixture/fixture.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | VERSION:2.0 3 | PRODID:-//hacksw/handcal//NONSGML v1.0//EN 4 | BEGIN:VEVENT 5 | UID:19970610T172345Z-AF23B2@example.com 6 | DTSTAMP:19970610T172345Z 7 | DTSTART:19970714T170000Z 8 | DTEND:19970715T040000Z 9 | SUMMARY:Bastille Day Party 10 | END:VEVENT 11 | END:VCALENDAR -------------------------------------------------------------------------------- /fixture/fixture.indd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.indd -------------------------------------------------------------------------------- /fixture/fixture.it: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.it -------------------------------------------------------------------------------- /fixture/fixture.j2c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.j2c -------------------------------------------------------------------------------- /fixture/fixture.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.jar -------------------------------------------------------------------------------- /fixture/fixture.jp2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.jp2 -------------------------------------------------------------------------------- /fixture/fixture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.jpg -------------------------------------------------------------------------------- /fixture/fixture.jpm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.jpm -------------------------------------------------------------------------------- /fixture/fixture.jpx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.jpx -------------------------------------------------------------------------------- /fixture/fixture.jxl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.jxl -------------------------------------------------------------------------------- /fixture/fixture.jxr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.jxr -------------------------------------------------------------------------------- /fixture/fixture.ktx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ktx -------------------------------------------------------------------------------- /fixture/fixture.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.lnk -------------------------------------------------------------------------------- /fixture/fixture.lz4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.lz4 -------------------------------------------------------------------------------- /fixture/fixture.lzh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.lzh -------------------------------------------------------------------------------- /fixture/fixture.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.m4a -------------------------------------------------------------------------------- /fixture/fixture.m4b: -------------------------------------------------------------------------------- 1 | ftypM4B -------------------------------------------------------------------------------- /fixture/fixture.m4p: -------------------------------------------------------------------------------- 1 | ftypM4P -------------------------------------------------------------------------------- /fixture/fixture.m4v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.m4v -------------------------------------------------------------------------------- /fixture/fixture.macho: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.macho -------------------------------------------------------------------------------- /fixture/fixture.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mid -------------------------------------------------------------------------------- /fixture/fixture.mj2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mj2 -------------------------------------------------------------------------------- /fixture/fixture.mkv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mkv -------------------------------------------------------------------------------- /fixture/fixture.mobi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mobi -------------------------------------------------------------------------------- /fixture/fixture.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mov -------------------------------------------------------------------------------- /fixture/fixture.mp1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mp1 -------------------------------------------------------------------------------- /fixture/fixture.mp2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mp2 -------------------------------------------------------------------------------- /fixture/fixture.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mp3 -------------------------------------------------------------------------------- /fixture/fixture.mpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mpg -------------------------------------------------------------------------------- /fixture/fixture.msi.cfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.msi.cfb -------------------------------------------------------------------------------- /fixture/fixture.mxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.mxf -------------------------------------------------------------------------------- /fixture/fixture.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.nef -------------------------------------------------------------------------------- /fixture/fixture.nes: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.nes -------------------------------------------------------------------------------- /fixture/fixture.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.odg -------------------------------------------------------------------------------- /fixture/fixture.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.odp -------------------------------------------------------------------------------- /fixture/fixture.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ods -------------------------------------------------------------------------------- /fixture/fixture.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.odt -------------------------------------------------------------------------------- /fixture/fixture.oga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.oga -------------------------------------------------------------------------------- /fixture/fixture.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ogg -------------------------------------------------------------------------------- /fixture/fixture.ogm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ogm -------------------------------------------------------------------------------- /fixture/fixture.ogv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ogv -------------------------------------------------------------------------------- /fixture/fixture.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.opus -------------------------------------------------------------------------------- /fixture/fixture.orf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.orf -------------------------------------------------------------------------------- /fixture/fixture.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.otf -------------------------------------------------------------------------------- /fixture/fixture.otg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.otg -------------------------------------------------------------------------------- /fixture/fixture.otp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.otp -------------------------------------------------------------------------------- /fixture/fixture.ots: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ots -------------------------------------------------------------------------------- /fixture/fixture.ott: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ott -------------------------------------------------------------------------------- /fixture/fixture.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.parquet -------------------------------------------------------------------------------- /fixture/fixture.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.pdf -------------------------------------------------------------------------------- /fixture/fixture.pgp: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP MESSAGE----- 2 | Version: OpenPGP.js v3.0.9 3 | Comment: https://openpgpjs.org 4 | 5 | wcBMA5C5XtMJioU5AQf/VlCbKDYaUD2UaAVVM4jJqktfYkNjxfGAzzJps+0e 6 | mfkkG4Ax5GJWHC0q5I3PKXlqSESpqooARa5bYZ1wt5iqEYPbUkt1csbsnXlZ 7 | X1EHwZb9YYmQBEJSjOyA49jwpeetaEt//VvIlFPHp4a7QnYePSa3gH1DsKkM 8 | NG/cZjZoh/ik5yAPD56w1/Ym+RP0y11lwpWxbpfq0iyu5RbUekD9cgXAnCvP 9 | G29Sqt8H3C299v2dbp3utRSf+bS/ERra6XVipWjjxfkD2tgrruFIERSAGQX1 10 | FPvS6ztH0301hUEXeA7cA4OuGK5sgbBeiRoSHE/DdbTeLiRIxbW01rqIXxzz 11 | ItJRAby+866YRBJnl/vvauszUFNz9JpV2ZS5c+weELrkPBlUuaV0CieLkwIn 12 | T318njOQ+cnW1cpxWPaiK/qSCBaIc6sOiVhLL4wRePu2FRe47mC4 13 | =Gp87 14 | -----END PGP MESSAGE----- 15 | -------------------------------------------------------------------------------- /fixture/fixture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.png -------------------------------------------------------------------------------- /fixture/fixture.potm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.potm -------------------------------------------------------------------------------- /fixture/fixture.potx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.potx -------------------------------------------------------------------------------- /fixture/fixture.ppsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ppsm -------------------------------------------------------------------------------- /fixture/fixture.ppsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ppsx -------------------------------------------------------------------------------- /fixture/fixture.ppt.cfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ppt.cfb -------------------------------------------------------------------------------- /fixture/fixture.pptm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.pptm -------------------------------------------------------------------------------- /fixture/fixture.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.pptx -------------------------------------------------------------------------------- /fixture/fixture.ps: -------------------------------------------------------------------------------- 1 | %!PS 2 | 3 | /Courier % name the desired font 4 | 20 selectfont % choose the size in points and establish 5 | % the font as the current one 6 | 72 500 moveto % position the current point at 7 | % coordinates 72, 500 (the origin is at the 8 | % lower-left corner of the page) 9 | (Hello world!) show % stroke the text in parentheses 10 | showpage % print all on the page 11 | -------------------------------------------------------------------------------- /fixture/fixture.ps.mpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ps.mpg -------------------------------------------------------------------------------- /fixture/fixture.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.psd -------------------------------------------------------------------------------- /fixture/fixture.qcp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.qcp -------------------------------------------------------------------------------- /fixture/fixture.raf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.raf -------------------------------------------------------------------------------- /fixture/fixture.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.rar -------------------------------------------------------------------------------- /fixture/fixture.rpm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.rpm -------------------------------------------------------------------------------- /fixture/fixture.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0 5 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural 6 | 7 | \f0\fs24 \cf0 Test RTF file} -------------------------------------------------------------------------------- /fixture/fixture.rw2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.rw2 -------------------------------------------------------------------------------- /fixture/fixture.s3m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.s3m -------------------------------------------------------------------------------- /fixture/fixture.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.shp -------------------------------------------------------------------------------- /fixture/fixture.skp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.skp -------------------------------------------------------------------------------- /fixture/fixture.spx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.spx -------------------------------------------------------------------------------- /fixture/fixture.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.sqlite -------------------------------------------------------------------------------- /fixture/fixture.stl: -------------------------------------------------------------------------------- 1 | solid SQUARE 2 | facet normal 0.0 0.0 1.0 3 | outer loop 4 | vertex 1.0 0.0 0.0 5 | vertex 0.5 0.5 0.0 6 | vertex 0.0 0.0 0.0 7 | endloop 8 | endfacet 9 | facet normal 0.0 0.0 1.0 10 | outer loop 11 | vertex 0.0 0.0 0.0 12 | vertex 0.5 0.5 0.0 13 | vertex 0.0 1.0 0.0 14 | endloop 15 | endfacet 16 | facet normal 0.0 0.0 1.0 17 | outer loop 18 | vertex 1.0 0.0 0.0 19 | vertex 1.0 1.0 0.0 20 | vertex 0.0 1.0 0.0 21 | endloop 22 | endfacet 23 | endsolid SQUARE 24 | -------------------------------------------------------------------------------- /fixture/fixture.sub.mpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.sub.mpg -------------------------------------------------------------------------------- /fixture/fixture.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.swf -------------------------------------------------------------------------------- /fixture/fixture.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.tar -------------------------------------------------------------------------------- /fixture/fixture.tar.Z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.tar.Z -------------------------------------------------------------------------------- /fixture/fixture.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.tar.gz -------------------------------------------------------------------------------- /fixture/fixture.tar.lz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.tar.lz -------------------------------------------------------------------------------- /fixture/fixture.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.tar.xz -------------------------------------------------------------------------------- /fixture/fixture.tar.zst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.tar.zst -------------------------------------------------------------------------------- /fixture/fixture.ttc: -------------------------------------------------------------------------------- 1 | ttcf -------------------------------------------------------------------------------- /fixture/fixture.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.ttf -------------------------------------------------------------------------------- /fixture/fixture.unicorn: -------------------------------------------------------------------------------- 1 | UNICORN FILE CONTENT 2 | -------------------------------------------------------------------------------- /fixture/fixture.vcf: -------------------------------------------------------------------------------- 1 | BEGIN:VCARD 2 | VERSION:3.0 3 | N:Gump;Forrest;;Mr.,; 4 | FN:Forrest Gump 5 | ORG:Bubba Gump Shrimp Co. 6 | TITLE:Shrimp Man 7 | PHOTO;VALUE=URI;TYPE=GIF:http://www.example.com/dir_photos/my_photo.gif 8 | TEL;TYPE=WORK,VOICE:(111) 555-1212 9 | TEL;TYPE=HOME,VOICE:(404) 555-1212 10 | ADR;TYPE=WORK,PREF:;;100 Waters Edge;Baytown;LA;30314;United States of America 11 | LABEL;TYPE=WORK,PREF:100 Waters Edge\nBaytown\, LA 30314\nUnited States of America 12 | ADR;TYPE=HOME:;;42 Plantation St.;Baytown;LA;30314;United States of America 13 | LABEL;TYPE=HOME:42 Plantation St.\nBaytown\, LA 30314\nUnited States of America 14 | EMAIL:forrestgump@example.com 15 | REV:2008-04-24T19:52:43Z 16 | END:VCARD 17 | -------------------------------------------------------------------------------- /fixture/fixture.voc: -------------------------------------------------------------------------------- 1 | Creative Voice File 2 | ) -------------------------------------------------------------------------------- /fixture/fixture.wasm: -------------------------------------------------------------------------------- 1 | asm ` 2 | addTwo 3 |  j -------------------------------------------------------------------------------- /fixture/fixture.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.wav -------------------------------------------------------------------------------- /fixture/fixture.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.webm -------------------------------------------------------------------------------- /fixture/fixture.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.webp -------------------------------------------------------------------------------- /fixture/fixture.wma.asf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.wma.asf -------------------------------------------------------------------------------- /fixture/fixture.wmv.asf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.wmv.asf -------------------------------------------------------------------------------- /fixture/fixture.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.woff -------------------------------------------------------------------------------- /fixture/fixture.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.woff2 -------------------------------------------------------------------------------- /fixture/fixture.wv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.wv -------------------------------------------------------------------------------- /fixture/fixture.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.xcf -------------------------------------------------------------------------------- /fixture/fixture.xls.cfb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.xls.cfb -------------------------------------------------------------------------------- /fixture/fixture.xlsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.xlsm -------------------------------------------------------------------------------- /fixture/fixture.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.xlsx -------------------------------------------------------------------------------- /fixture/fixture.xltm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.xltm -------------------------------------------------------------------------------- /fixture/fixture.xltx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.xltx -------------------------------------------------------------------------------- /fixture/fixture.xm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.xm -------------------------------------------------------------------------------- /fixture/fixture.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fixture/fixture.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.xpi -------------------------------------------------------------------------------- /fixture/fixture.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture.zip -------------------------------------------------------------------------------- /fixture/fixture2.3gp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture2.3gp -------------------------------------------------------------------------------- /fixture/fixture2.asar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture2.asar -------------------------------------------------------------------------------- /fixture/fixture2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture2.docx -------------------------------------------------------------------------------- /fixture/fixture2.eps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe-2.0 EPSF-1.2 %%Creator: Adobe Illustrator 88(TM) 1.6 %%For: (Timothy A. Tedder) () %%Title: (earth) %%CreationDate: (10/19/88) (2:29 PM) %%DocumentProcSets: Adobe_packedarray 0 0 %%DocumentSuppliedProcSets: Adobe_packedarray 0 0 %%DocumentProcSets: Adobe_cmykcolor 0 0 %%DocumentSuppliedProcSets: Adobe_cmykcolor 0 0 %%DocumentProcSets: Adobe_cshow 0 0 %%DocumentSuppliedProcSets: Adobe_cshow 0 0 %%DocumentProcSets: Adobe_customcolor 0 0 %%DocumentSuppliedProcSets: Adobe_customcolor 0 0 %%DocumentProcSets: Adobe_Illustrator_881 0 0 %%DocumentSuppliedProcSets: Adobe_Illustrator_881 0 0 %%ColorUsage: Black&White %%DocumentProcessColors: Black %%BoundingBox:119 246 394 521 %%TemplateBox:288 360 288 360 %%TileBox:-552 730 0 1460 %%EndComments %%BeginProcSet: Adobe_packedarray 0 0 % packedarray Operators % Version 1.0 5/9/1988 % Copyright (C) 1987, 1988 % Adobe Systems Incorporated % All Rights Reserved userdict /Adobe_packedarray 5 dict dup begin put /initialize % - initialize - { /packedarray where { pop } { Adobe_packedarray begin Adobe_packedarray { dup xcheck { bind } if userdict 3 1 roll put } forall end } ifelse } def /terminate % - terminate - { } def /packedarray % arguments count packedarray array { array astore readonly } def /setpacking % boolean setpacking - { pop } def /currentpacking % - setpacking boolean { false } def currentdict readonly pop end %%EndProcSet Adobe_packedarray /initialize get exec %%BeginProcSet:Adobe_cmykcolor 0 0 % cmykcolor Operators % Version 1.0 5/9/1988 % Copyright (C) 1987, 1988 % Adobe Systems Incorporated % All Rights Reserved currentpacking true setpacking userdict /Adobe_cmykcolor 4 dict dup begin put /initialize % - initialize - { /setcmykcolor where { pop } { userdict /Adobe_cmykcolor_vars 2 dict dup begin put /_setrgbcolor /setrgbcolor load def /_currentrgbcolor /currentrgbcolor load def Adobe_cmykcolor begin Adobe_cmykcolor { dup xcheck { bind } if pop pop } forall end end Adobe_cmykcolor begin } ifelse } def /terminate % - terminate - { currentdict Adobe_cmykcolor eq { end } if } def /setcmykcolor % cyan magenta yellow black setcmykcolor - { 1 sub 4 1 roll 3 { 3 index add neg dup 0 lt { pop 0 } if 3 1 roll } repeat Adobe_cmykcolor_vars /_setrgbcolor get exec pop } def /currentcmykcolor % - currentcmykcolor cyan magenta yellow black { Adobe_cmykcolor_vars /_currentrgbcolor get exec 3 { 1 sub neg 3 1 roll } repeat 0 } def currentdict readonly pop end setpacking %%EndProcSet %%BeginProcSet: Adobe_cshow 0 0 % cshow Operator % Version 1.0 5/9/1988 % Copyright (C) 1987, 1988 % Adobe Systems Incorporated % All Rights Reserved currentpacking true setpacking userdict /Adobe_cshow 3 dict dup begin put /initialize % - initialize - { /cshow where { pop } { userdict /Adobe_cshow_vars 1 dict dup begin put /_cshow % - _cshow proc {} def Adobe_cshow begin Adobe_cshow { dup xcheck { bind } if userdict 3 1 roll put } forall end end } ifelse } def /terminate % - terminate - { } def /cshow % string proc cshow - { Adobe_cshow_vars exch /_cshow exch put { 0 0 Adobe_cshow_vars /_cshow get exec } forall } def currentdict readonly pop end setpacking %%EndProcSet %%BeginProcSet: Adobe_customcolor 0 0 % Custom Color Operators % Version 1.0 5/9/1988 % Copyright (C) 1987, 1988 % Adobe Systems Incorporated % All Rights Reserved currentpacking true setpacking userdict /Adobe_customcolor 5 dict dup begin put /initialize % - initialize - { /setcustomcolor where { pop } { Adobe_customcolor begin Adobe_customcolor { dup xcheck { bind } if pop pop } forall end Adobe_customcolor begin } ifelse } def /terminate % - terminate - { currentdict Adobe_customcolor eq { end } if } def /findcmykcustomcolor % cyan magenta yellow black name findcmykcustomcolor object { 5 packedarray } def /setcustomcolor % object tint setcustomcolor - { exch aload pop pop 4 { 4 index mul 4 1 roll } repeat 5 -1 roll pop setcmykcolor } def /setoverprint % boolean setoverprint - { pop } def currentdict readonly pop end setpacking %%EndProcSet %%BeginProcSet: Adobe_Illustrator881 0 0 % Adobe Illustrator (TM) Prolog % Version 1.0 5/9/1988 % Copyright (C) 1987, 1988 % Adobe Systems Incorporated % All Rights Reserved currentpacking true setpacking userdict /Adobe_Illustrator881 72 dict dup begin put % initialization /initialize % - initialize - { userdict /Adobe_Illustrator881_vars 29 dict dup begin put % paint operands /_lp /none def /_pf {} def /_ps {} def /_psf {} def /_pss {} def % text operands /_a null def /_as null def /_tt 2 array def /_tl 2 array def /_tm matrix def /t {} def % color operands /_gf null def /_cf 4 array def /_if null def /_of false def /_fc {} def /_gs null def /_cs 4 array def /_is null def /_os false def /_sc {} def /_i null def Adobe_Illustrator881 begin Adobe_Illustrator881 { dup xcheck { bind } if pop pop } forall end end Adobe_Illustrator881 begin Adobe_Illustrator881_vars begin newpath } def /terminate % - terminate - { end end } def % definition operators /_ % - _ null null def /ddef % key value ddef - { Adobe_Illustrator881_vars 3 1 roll put } def /xput % key value literal xput - { dup load dup length exch maxlength eq { dup dup load dup length 2 mul dict copy def } if load begin def end } def /npop % integer npop - { { pop } repeat } def % marking operators /sw % ax ay length string sw x y { stringwidth exch 5 -1 roll 3 index 1 sub mul add 4 1 roll 3 1 roll 1 sub mul add } def /ss % ax ay length string matrix ss - { 3 -1 roll pop 4 1 roll { 2 npop (0) exch 2 copy 0 exch put pop gsave false charpath currentpoint 4 index setmatrix stroke grestore moveto 2 copy rmoveto } cshow 3 npop } def % path operators /sp % ax ay length string sp - { exch pop { 2 npop (0) exch 2 copy 0 exch put pop false charpath 2 copy rmoveto } cshow 2 npop } def % path construction operators /pl % x y pl x y { transform 0.25 sub round 0.25 add exch 0.25 sub round 0.25 add exch itransform } def /setstrokeadjust where { pop true setstrokeadjust /c % x1 y1 x2 y2 x3 y3 c - { curveto } def /C /c load def /v % x2 y2 x3 y3 v - { currentpoint 6 2 roll curveto } def /V /v load def /y % x1 y1 x2 y2 y - { 2 copy curveto } def /Y /y load def /l % x y l - { lineto } def /L /l load def /m % x y m - { moveto } def } { /c { pl curveto } def /C /c load def /v { currentpoint 6 2 roll pl curveto } def /V /v load def /y { pl 2 copy curveto } def /Y /y load def /l { pl lineto } def /L /l load def /m { pl moveto } def } ifelse % graphic state operators /d % array phase d - { setdash } def /cf % - cf flatness currentflat def /i % flatness i - { dup 0 eq { pop cf } if setflat } def /j % linejoin j - { setlinejoin } def /J % linecap J - { setlinecap } def /M % miterlimit M - { setmiterlimit } def /w % linewidth w - { setlinewidth } def % path painting operators /H % - H - {} def /h % - h - { closepath } def /N % - N - { newpath } def /n % - n - /N load def /F % - F - { _pf } def /f % - f - { closepath F } def /S % - S - { _ps } def /s % - s - { closepath S } def /B % - B - { gsave F grestore S } def /b % - b - { closepath B } def /W % - W - { clip } def % text painting operators /ta % length string ta ax ay length string { _as moveto _tt aload pop 4 -2 roll } def /tl % - tl - { _tl aload pop translate } def /as % - as array { { 0 0 } { 2 copy _tt aload pop 4 -2 roll sw exch neg 2 div exch neg 2 div } { 2 copy _tt aload pop 4 -2 roll sw exch neg exch neg } { 0 0 } } cvlit def /z % literal size leading tracking align z - { /_a exch ddef /_as as _a get ddef _a 2 le { 0 _tt astore pop 0 exch neg _tl astore pop } { 0 exch neg _tt astore pop neg 0 _tl astore pop } ifelse exch findfont exch scalefont setfont } def /tm % matrix tm - { _tm currentmatrix pop concat } def /I % matrix I - { tm /t { ta sp tl } ddef } def /o % matrix o - { tm /t { ta 4 npop tl newpath } ddef } def /e % matrix e - { tm /t { ta _psf tl newpath } ddef } def /r % matrix r - { tm /t { ta _tm _pss tl newpath } ddef } def /a % matrix a - { tm /t { 2 copy ta _psf newpath ta _tm _pss tl newpath } ddef } def /T % - T - { _tm setmatrix } def % font operators /Z % array literal literal direction Z - { pop findfont begin currentdict dup length 1 add dict begin { 1 index /FID ne { def } { 2 npop } ifelse } forall /FontName exch def dup length 0 ne { /Encoding Encoding 256 array copy def 0 exch { dup type /nametype eq { Encoding 2 index 2 index put pop 1 add } { exch pop } ifelse } forall } if pop currentdict dup end end /FontName get exch definefont pop } def % group operators /u % - u - {} def /U % - U - {} def /q % - q - { gsave } def /Q % - Q - { grestore } def % place operators /` % matrix llx lly urx ury string ` - { /_i save ddef 6 1 roll 4 npop concat userdict begin /showpage {} def false setoverprint pop } def /~ % - ~ - { end _i restore } def % color operators /O % flag O - { 0 ne /_of exch ddef /_lp /none ddef } def /R % flag R - { 0 ne /_os exch ddef /_lp /none ddef } def /g % gray g - { /_gf exch ddef /_fc { _lp /fill ne { _of setoverprint _gf setgray /_lp /fill ddef } if } ddef /_pf { _fc fill } ddef /_psf { _fc exch pop ashow } ddef /_lp /none ddef } def /G % gray G - { /_gs exch ddef /_sc { _lp /stroke ne { _os setoverprint _gs setgray /_lp /stroke ddef } if } ddef /_ps { _sc stroke } ddef /_pss { _sc ss } ddef /_lp /none ddef } def /k % cyan magenta yellow black k - { _cf astore pop /_fc { _lp /fill ne { _of setoverprint _cf aload pop setcmykcolor /_lp /fill ddef } if } ddef /_pf { _fc fill } ddef /_psf { _fc exch pop ashow } ddef /_lp /none ddef } def /K % cyan magenta yellow black K - { _cs astore pop /_sc { _lp /stroke ne { _os setoverprint _cs aload pop setcmykcolor /_lp /stroke ddef } if } ddef /_ps { _sc stroke } ddef /_pss { _sc ss } ddef /_lp /none ddef } def /x % cyan magenta yellow black name gray x - { /_gf exch ddef findcmykcustomcolor /_if exch ddef /_fc { _lp /fill ne { _of setoverprint _if _gf 1 exch sub setcustomcolor /_lp /fill ddef } if } ddef /_pf { _fc fill } ddef /_psf { _fc exch pop ashow } ddef /_lp /none ddef } def /X % cyan magenta yellow black name gray X - { /_gs exch ddef findcmykcustomcolor /_is exch ddef /_sc { _lp /stroke ne { _os setoverprint _is _gs 1 exch sub setcustomcolor /_lp /stroke ddef } if } ddef /_ps { _sc stroke } ddef /_pss { _sc ss } ddef /_lp /none ddef } def % locked object operators /A % value A - { pop } def currentdict readonly pop end setpacking %%EndProcSet %%EndProlog %%BeginSetup Adobe_cmykcolor /initialize get exec Adobe_cshow /initialize get exec Adobe_customcolor /initialize get exec Adobe_Illustrator881 /initialize get exec %%EndSetup 0 A u q 0 O 0 g 0 R 0 G 0 i 0 J 0 j 1 w 4 M []0 d %%Note: 289.7483 499.934 m 323.3996 489.1332 350.8221 464.5488 364.8541 432.0545 c 390.3671 372.9737 360.4601 299.753 300.8926 274.7434 c 241.5687 249.836 167.9347 279.1117 143.7827 339.0235 c 134.3854 362.3347 131.6141 386.862 137.3373 411.8925 c 145.5155 447.6591 157.8251 467.6706 191.9297 487.7602 c 222.0044 505.476 256.5007 510.6053 289.7483 499.934 c h W n 0.2 g 120.6329 385.5208 m 120.6329 459.3289 180.4681 519.164 254.2761 519.164 c 328.0841 519.164 387.9193 459.3289 387.9193 385.5208 c 387.9193 311.7128 328.0841 251.8777 254.2761 251.8777 c 180.4681 251.8777 120.6329 311.7128 120.6329 385.5208 c f u 0.2227 g 132.0236 388.6477 m 132.0236 457.0886 187.5077 512.5727 255.9486 512.5727 c 324.3895 512.5727 379.8736 457.0886 379.8736 388.6477 c 379.8736 320.2068 324.3895 264.7227 255.9486 264.7227 c 187.5077 264.7227 132.0236 320.2068 132.0236 388.6477 c f 0.2454 g 143.4163 391.7751 m 143.4163 454.8479 194.5486 505.9802 257.6214 505.9802 c 320.6943 505.9802 371.8265 454.8479 371.8265 391.7751 c 371.8265 328.7022 320.6943 277.5699 257.6214 277.5699 c 194.5486 277.5699 143.4163 328.7022 143.4163 391.7751 c f 0.2682 g 154.8089 394.9025 m 154.8089 452.6072 201.5894 499.3878 259.2942 499.3878 c 316.999 499.3878 363.7795 452.6072 363.7795 394.9025 c 363.7795 337.1977 316.999 290.4172 259.2942 290.4172 c 201.5894 290.4172 154.8089 337.1977 154.8089 394.9025 c f 0.2909 g 166.2015 398.0298 m 166.2015 450.3666 208.6302 492.7953 260.967 492.7953 c 313.3037 492.7953 355.7324 450.3666 355.7324 398.0298 c 355.7324 345.6931 313.3037 303.2644 260.967 303.2644 c 208.6302 303.2644 166.2015 345.6931 166.2015 398.0298 c f 0.3136 g 177.5941 401.1572 m 177.5941 448.1259 215.671 486.2028 262.6398 486.2028 c 309.6085 486.2028 347.6854 448.1259 347.6854 401.1572 c 347.6854 354.1885 309.6085 316.1116 262.6398 316.1116 c 215.671 316.1116 177.5941 354.1885 177.5941 401.1572 c f 0.3364 g 188.9868 404.2846 m 188.9868 445.8853 222.7119 479.6104 264.3125 479.6104 c 305.9132 479.6104 339.6383 445.8853 339.6383 404.2846 c 339.6383 362.6839 305.9132 328.9588 264.3125 328.9588 c 222.7119 328.9588 188.9868 362.6839 188.9868 404.2846 c f 0.3591 g 200.3794 407.412 m 200.3794 443.6446 229.7527 473.0179 265.9853 473.0179 c 302.218 473.0179 331.5913 443.6446 331.5913 407.412 c 331.5913 371.1793 302.218 341.806 265.9853 341.806 c 229.7527 341.806 200.3794 371.1793 200.3794 407.412 c f 0.3818 g 211.772 410.5393 m 211.772 441.404 236.7935 466.4255 267.6581 466.4255 c 298.5227 466.4255 323.5442 441.404 323.5442 410.5393 c 323.5442 379.6748 298.5227 354.6532 267.6581 354.6532 c 236.7935 354.6532 211.772 379.6748 211.772 410.5393 c f 0.4045 g 223.1646 413.6667 m 223.1646 439.1633 243.8343 459.833 269.3309 459.833 c 294.8274 459.833 315.4972 439.1633 315.4972 413.6667 c 315.4972 388.1702 294.8274 367.5005 269.3309 367.5005 c 243.8343 367.5005 223.1646 388.1702 223.1646 413.6667 c f 0.4273 g 234.5573 416.7941 m 234.5573 436.9226 250.8752 453.2405 271.0037 453.2405 c 291.1322 453.2405 307.4501 436.9226 307.4501 416.7941 c 307.4501 396.6656 291.1322 380.3477 271.0037 380.3477 c 250.8752 380.3477 234.5573 396.6656 234.5573 416.7941 c f U 0.45 g 245.948 419.921 m 245.948 434.6824 257.9148 446.6492 272.6762 446.6492 c 287.4376 446.6492 299.4044 434.6824 299.4044 419.921 c 299.4044 405.1596 287.4376 393.1927 272.6762 393.1927 c 257.9148 393.1927 245.948 405.1596 245.948 419.921 c f Q 0 O 0 g 0 R 0 G 0 i 0 J 0 j 1 w 4 M []0 d %%Note: 289.7483 499.934 m 323.3996 489.1332 350.8221 464.5488 364.8541 432.0545 c 390.3671 372.9737 360.4601 299.753 300.8926 274.7434 c 241.5687 249.836 167.9347 279.1117 143.7827 339.0235 c 134.3854 362.3347 131.6141 386.862 137.3373 411.8925 c 145.5155 447.6591 157.8251 467.6706 191.9297 487.7602 c 222.0044 505.476 256.5007 510.6053 289.7483 499.934 c s 1 g 0.5 w 262.9362 494.878 m 263.9038 495.9616 264.029 497.0776 263.6135 497.9427 c 262.428 500.4107 259.8451 498.5589 258.7761 497.0208 C 258.1363 498.4351 256.8504 498.1583 255.8006 497.9151 c 255.004 497.7306 254.317 496.9224 254.8631 496.077 c 255.6469 494.8637 256.6282 493.6156 257.8426 493.2309 c 259.3329 492.7589 260.7498 492.4297 262.9362 494.878 c b 246.261 490.0954 m 247.0191 495.3287 247.1764 499.5381 251.6501 503.1758 c 252.3093 503.7118 251.5041 504.8194 250.7648 504.878 c 246.1479 505.2436 237.1615 504.8332 235.8237 502.4362 c 233.7228 498.6722 235.8776 491.4663 241.0037 488.4015 c 242.3837 487.5763 245.7645 486.6679 246.261 490.0954 c b 221.7933 487.0311 m 222.2423 486.2785 222.8567 485.611 223.7408 486.0865 c 226.5326 487.588 222.6996 489.3542 223.7761 491.0208 C 225.1099 489.6871 226.4425 488.3545 227.7761 487.0208 C 231.1632 492.2806 223.8779 497.3235 220.359 499.2646 c 216.5141 501.3856 212.9676 494.4472 210.7761 492.0208 C 214.6938 490.2114 219.1382 491.4814 221.7933 487.0311 c b 219.4496 475.1803 m 217.2548 480.8589 214.9571 485.8608 209.5444 487.2241 c 208.3401 487.5274 205.9487 484.81 204.9404 482.783 c 202.4377 477.752 209.3265 475.0647 207.878 471.2099 c 206.695 468.0619 206.5051 464.2489 204.3433 461.1545 c 203.4441 459.8674 201.5381 461.562 200.8447 462.9608 c 200.1052 464.4525 201.7189 466.7855 199.6509 467.7631 c 195.4009 469.7723 187.4771 470.989 188.3149 476.8093 c 188.9238 481.0387 195.1368 482.9055 195.5333 487.9101 c 195.5857 488.5717 194.6187 489.3568 193.776 488.8036 c 182.5886 481.4583 171.3027 475.5423 163.0261 465.3958 c 147.0595 445.8222 132.091 418.4364 140.7136 391.8958 C 144.2369 398.2317 136.3142 404.56 140.7136 410.8958 C 143.3919 402.1176 145.3569 393.5363 152.2552 386.4497 c 152.8715 385.8166 150.907 382.7934 151.947 381.0338 c 155.1274 375.6534 161.797 374.5592 167.7136 374.8958 C 167.2928 371.7261 170.0157 369.9832 171.8688 369.3494 c 180.6928 366.3307 187.049 360.8411 194.8662 356.1501 c 196.9756 354.8843 196.2676 358.8141 197.6913 358.672 c 205.2502 357.9173 205.856 350.0908 207.0701 343.9665 c 207.3868 342.3684 210.0023 341.4284 210.3812 339.8177 c 211.3784 335.5789 209.4697 330.6396 211.3356 327.2369 c 216.4342 317.9387 231.7717 315.7572 234.4636 306.6458 c 237.7136 295.6458 237.5532 281.9055 241.9621 269.9878 c 242.5616 268.3672 244.1946 266.5581 245.7822 266.2557 c 248.9949 265.6439 260.1357 265.6306 262.4584 266.5446 c 268.1426 268.7815 275.9636 274.3958 276.6494 278.1308 c 279.1081 291.5213 288.3125 290.4866 292.0735 297.2517 c 293.3588 299.5637 293.0046 303.4012 292.2678 307.009 c 291.3356 311.5736 296.06 314.2964 298.3463 318.1157 c 299.4239 319.916 301.023 323.1725 299.3826 324.4808 c 291.6107 330.6793 282.2473 333.5366 272.7136 329.8958 C 271.679 333.3266 275.1378 336.3038 273.0433 340.0788 c 272.4035 341.232 273.1099 343.5575 273.085 344.8841 c 272.927 353.3242 268.3777 361.9687 257.7574 362.615 c 254.4437 362.8166 254.3365 368.8336 250.6923 370.8573 c 242.0101 375.6786 234.0391 370.1833 225.7136 367.8958 C 225.6417 368.9832 226.1112 370.7205 224.7233 370.6631 c 217.2654 370.354 208.1444 366.1258 207.7136 357.8958 C 205.0878 359.1552 203.941 362.5496 200.7082 362.8338 c 198.3213 363.0437 196.072 360.9694 193.7825 362.0426 c 192.5648 362.6134 191.3771 363.7481 190.8861 364.9654 c 189.7628 367.7501 192.5051 371.6355 189.5049 373.5725 c 187.0301 375.1703 182.2637 372.1887 181.3511 375.0959 c 180.5628 377.607 186.6741 382.6222 183.457 384.4423 c 180.6287 386.0426 177.4147 384.1035 174.3916 382.5047 c 167.5434 378.883 161.5311 387.4385 160.3434 394.0097 c 159.1788 400.4532 161.181 408.6551 167.8732 411.5235 c 171.8335 413.221 176.6781 409.4493 180.5016 411.3275 c 182.4996 412.309 184.905 413.7755 186.4141 412.5323 c 189.4681 410.016 193.6844 409.3116 195.5327 405.8006 c 196.6171 403.7409 194.2784 400.8098 196.8082 399.0303 c 196.8784 398.9809 197.3786 399.5608 197.7136 399.8958 C 197.1685 396.2387 199.6003 393.3354 200.7136 389.8958 C 201.7147 390.8969 203.155 391.7468 203.481 392.9585 c 205.4984 400.456 199.5463 408.4574 202.7416 414.3372 c 206.2251 420.7472 209.5076 426.8985 213.018 433.7397 c 214.4742 436.5776 217.1338 438.6911 219.7963 440.791 c 220.5525 441.3875 221.0831 440.4498 221.7747 439.987 c 222.6111 439.4272 223.6213 440.2459 223.5098 440.8587 c 223.3982 441.4718 222.2018 442.341 222.8303 442.6783 c 226.2465 444.5119 228.1605 447.4301 230.7136 449.8958 C 226.2239 453.2582 220.035 448.8928 216.7136 444.8958 C 222.8849 449.8136 225.1703 460.8635 234.7136 456.8958 C 235.8882 460.7527 241.8715 459.8852 241.7252 461.8211 c 241.1125 469.9232 231.998 474.5171 226.7136 480.8958 C 225.5663 479.0559 225.4812 476.7725 224.4154 475.0841 c 223.5966 473.7867 221.5572 469.7268 219.4496 475.1803 c b 249.7922 448.0593 m 250.7217 447.6692 251.505 448.2479 251.6604 449.0434 c 252.5609 453.653 247.2679 453.2509 245.7761 456.0208 C 245.4394 455.6842 245.1038 455.1253 244.78 455.1363 c 243.1977 455.1898 244.2984 458.0949 242.829 457.7765 c 239.4154 457.037 241.9164 452.8662 239.7761 451.0208 C 243.0007 449.6536 246.5276 449.4293 249.7922 448.0593 c b 298.6886 481.156 m 301.8026 483.1714 298.3354 486.4673 296.7543 486.539 c 294.9557 486.6204 295.7592 483.6663 295.958 482.0431 c 296.1208 480.7135 297.7139 480.5252 298.6886 481.156 c b 304.3822 481.1275 m 304.1183 480.1533 303.6413 479.0982 303.8806 478.0446 c 304.229 476.5104 306.2117 476.7436 306.4942 477.1966 c 308.2003 479.9326 310.5241 479.3387 311.3297 482.1488 c 312.842 487.4244 305.5648 486.3447 302.9461 489.1779 c 302.4362 489.7297 302.9557 491.0518 302.6863 491.9952 c 302.4607 492.7855 301.5234 493.5389 300.8982 492.9012 c 296.0264 487.9319 305.7106 486.0319 304.3822 481.1275 c b 315.7649 478.9803 m 313.119 479.7079 312.3219 477.2227 310.7761 476.0208 C 311.4426 475.3543 312.0104 474.3835 312.8164 474.182 c 314.7507 473.6985 316.9925 474.5319 318.6585 473.7653 c 322.1959 472.1373 323.7502 467.5142 323.1033 464.1502 c 321.9755 458.2864 315.0336 460.6195 309.8228 459.7433 c 308.6534 459.5467 307.5293 458.1711 306.9075 456.9537 c 306.0205 455.2169 308.1732 454.2713 308.4612 452.9521 c 309.2362 449.4015 308.3715 443.9141 311.8068 443.7742 c 315.7832 443.6122 318.925 447.4477 323.7822 447.3605 c 324.7653 447.3429 326.4761 449.0554 326.4241 450.0014 c 326.1186 455.55 325.1462 461.5031 330.0952 464.4926 c 333.6101 466.6157 339.2649 466.0933 342.948 463.2429 c 343.1583 463.0802 344.2775 464.2138 343.6656 464.9259 c 336.0389 473.8014 327.6993 480.4107 317.7184 486.9325 c 316.8765 487.4826 315.8357 486.6016 315.9922 486.0865 c 316.3608 484.8728 318.0582 484.1698 318.6295 482.9521 c 319.4335 481.2381 318.7872 478.1492 315.7649 478.9803 c b 335.8932 456.9075 m 335.2636 456.2568 336.0755 455.1817 336.7759 455.1825 c 337.4766 455.1833 338.2894 456.2566 337.6589 456.9072 c 337.3285 457.2481 336.2223 457.2475 335.8932 456.9075 c b 345.6561 451.1443 m 346.2943 451.7646 345.4771 452.5368 344.7761 453.0208 C 344.3766 451.4521 341.669 452.4946 342.0344 451.0879 c 342.6272 448.8055 344.6541 450.1703 345.6561 451.1443 c b 345.6136 457.008 m 345.744 455.354 347.2075 455.0874 347.7761 454.0208 C 350.6015 457.253 347.6156 462.2134 344.7464 462.3383 c 342.1785 462.45 345.4673 458.8636 345.6136 457.008 c b 339.8964 387.445 m 345.2477 385.9283 353.2441 390.7796 354.3547 382.961 c 355.0814 377.8452 356.0482 373.4821 358.2538 368.776 c 360.6779 363.604 357.6652 357.669 356.2543 352.1543 c 355.3741 348.714 352.6667 345.7619 350.041 342.7871 c 348.0474 340.5285 348.6645 336.9477 348.2582 333.9554 c 347.6854 329.7359 351.5231 321.3322 353.7612 323.2225 c 364.6913 332.4542 372.0321 360.5778 373.424 375.0547 c 375.4573 396.2029 372.3386 420.5833 360.2041 439.6551 c 357.2261 444.3356 350.7969 441.895 345.8619 443.3183 c 344.246 443.7844 343.3053 446.2304 341.6876 446.74 c 335.3839 448.7257 329.5215 444.5618 324.3494 440.5743 c 322.3254 439.0138 320.0442 443.219 316.7913 441.9809 c 314.5552 441.1297 314.6569 438.6022 314.1122 436.9125 c 313.0832 433.7205 314.2317 430.3247 315.3881 426.8902 c 316.3586 424.0074 313.5326 421.4991 312.2302 418.8016 c 308.5155 411.1074 311.2912 402.3222 311.2242 394.0172 c 311.2136 392.6942 313.2467 390.9395 314.8687 390.2336 c 319.5544 388.1944 324.6825 388.2089 329.8298 387.3384 c 333.0988 386.7855 336.136 388.5107 339.8964 387.445 c b U %%Trailer Adobe_Illustrator881 /terminate get exec Adobe_customcolor /terminate get exec Adobe_cshow /terminate get exec Adobe_cmykcolor /terminate get exec -------------------------------------------------------------------------------- /fixture/fixture2.jxl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture2.jxl -------------------------------------------------------------------------------- /fixture/fixture2.mkv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture2.mkv -------------------------------------------------------------------------------- /fixture/fixture2.mpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture2.mpg -------------------------------------------------------------------------------- /fixture/fixture2.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture2.nef -------------------------------------------------------------------------------- /fixture/fixture2.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture2.pptx -------------------------------------------------------------------------------- /fixture/fixture2.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture2.xlsx -------------------------------------------------------------------------------- /fixture/fixture3.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture3.nef -------------------------------------------------------------------------------- /fixture/fixture4.nef: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/fixture/fixture4.nef -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Typings for Node.js specific entry point. 3 | */ 4 | 5 | import type {Readable as NodeReadableStream} from 'node:stream'; 6 | import type {AnyWebByteStream} from 'strtok3'; 7 | import { 8 | type FileTypeResult, 9 | type StreamOptions, 10 | type AnyWebReadableStream, 11 | type AnyWebReadableByteStreamWithFileType, 12 | type FileTypeOptions, 13 | FileTypeParser as DefaultFileTypeParser, 14 | } from './core.js'; 15 | 16 | export type ReadableStreamWithFileType = NodeReadableStream & { 17 | readonly fileType?: FileTypeResult; 18 | }; 19 | 20 | /** 21 | Extending `FileTypeParser` with Node.js engine specific functions. 22 | */ 23 | export declare class FileTypeParser extends DefaultFileTypeParser { 24 | /** 25 | @param stream - Node.js `stream.Readable` or web `ReadableStream`. 26 | */ 27 | fromStream(stream: AnyWebReadableStream | NodeReadableStream): Promise; 28 | 29 | fromFile(filePath: string): Promise; 30 | 31 | /** 32 | Works the same way as {@link fileTypeStream}, additionally taking into account custom detectors (if any were provided to the constructor). 33 | */ 34 | toDetectionStream(readableStream: NodeReadableStream, options?: FileTypeOptions & StreamOptions): Promise; 35 | toDetectionStream(webStream: AnyWebReadableStream, options?: FileTypeOptions & StreamOptions): Promise; 36 | } 37 | 38 | /** 39 | Detect the file type of a file path. 40 | 41 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the file. 42 | 43 | This is for Node.js only. 44 | 45 | To read from a [`File`](https://developer.mozilla.org/docs/Web/API/File), see `fileTypeFromBlob()`. 46 | 47 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the buffer. 48 | 49 | @returns The detected file type and MIME type or `undefined` when there is no match. 50 | */ 51 | export function fileTypeFromFile(filePath: string, options?: FileTypeOptions): Promise; 52 | 53 | /** 54 | Detect the file type of a [web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream). 55 | 56 | If the engine is Node.js, this may also be a [Node.js `stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable). 57 | 58 | Direct support for Node.js streams will be dropped in the future, when Node.js streams can be converted to Web streams (see [`toWeb()`](https://nodejs.org/api/stream.html#streamreadabletowebstreamreadable-options)). 59 | 60 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the buffer. 61 | 62 | @param stream - A [web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) or [Node.js `stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable) streaming a file to examine. 63 | @param options - Options to override default behaviour. 64 | @returns A `Promise` for an object with the detected file type, or `undefined` when there is no match. 65 | */ 66 | export function fileTypeFromStream(stream: AnyWebReadableStream | NodeReadableStream, options?: FileTypeOptions): Promise; 67 | 68 | /** 69 | Returns a `Promise` which resolves to the original readable stream argument, but with an added `fileType` property, which is an object like the one returned from `fileTypeFromFile()`. 70 | 71 | This method can be handy to put in between a stream, but it comes with a price. 72 | Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample, to determine the file type. 73 | The sample size impacts the file detection resolution. 74 | A smaller sample size will result in lower probability of the best file type detection. 75 | 76 | @param readableStream - A [web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) or [Node.js `stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable), streaming a file to examine. 77 | @param options - May be used to override the default sample size. 78 | @returns A `Promise` which resolves to the original readable stream argument, but with an added `fileType` property, which is an object like the one returned from `fileTypeFromFile()`. 79 | 80 | @example 81 | ``` 82 | import got from 'got'; 83 | import {fileTypeStream} from 'file-type'; 84 | 85 | const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg'; 86 | 87 | const stream1 = got.stream(url); 88 | const stream2 = await fileTypeStream(stream1, {sampleSize: 1024}); 89 | 90 | if (stream2.fileType?.mime === 'image/jpeg') { 91 | // stream2 can be used to stream the JPEG image (from the very beginning of the stream) 92 | } 93 | ``` 94 | */ 95 | export function fileTypeStream(readableStream: NodeReadableStream, options?: FileTypeOptions & StreamOptions): Promise; 96 | export function fileTypeStream(webStream: AnyWebByteStream, options?: FileTypeOptions & StreamOptions): Promise; 97 | 98 | export * from './core.js'; 99 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | Node.js specific entry point. 3 | */ 4 | 5 | import {ReadableStream as WebReadableStream} from 'node:stream/web'; 6 | import {pipeline, PassThrough, Readable} from 'node:stream'; 7 | import * as strtok3 from 'strtok3'; 8 | import {FileTypeParser as DefaultFileTypeParser, reasonableDetectionSizeInBytes} from './core.js'; 9 | 10 | export class FileTypeParser extends DefaultFileTypeParser { 11 | async fromStream(stream) { 12 | const tokenizer = await (stream instanceof WebReadableStream ? strtok3.fromWebStream(stream, this.tokenizerOptions) : strtok3.fromStream(stream, this.tokenizerOptions)); 13 | try { 14 | return await super.fromTokenizer(tokenizer); 15 | } finally { 16 | await tokenizer.close(); 17 | } 18 | } 19 | 20 | async fromFile(path) { 21 | const tokenizer = await strtok3.fromFile(path); 22 | try { 23 | return await super.fromTokenizer(tokenizer); 24 | } finally { 25 | await tokenizer.close(); 26 | } 27 | } 28 | 29 | async toDetectionStream(readableStream, options = {}) { 30 | if (!(readableStream instanceof Readable)) { 31 | return super.toDetectionStream(readableStream, options); 32 | } 33 | 34 | const {sampleSize = reasonableDetectionSizeInBytes} = options; 35 | 36 | return new Promise((resolve, reject) => { 37 | readableStream.on('error', reject); 38 | 39 | readableStream.once('readable', () => { 40 | (async () => { 41 | try { 42 | // Set up output stream 43 | const pass = new PassThrough(); 44 | const outputStream = pipeline ? pipeline(readableStream, pass, () => {}) : readableStream.pipe(pass); 45 | 46 | // Read the input stream and detect the filetype 47 | const chunk = readableStream.read(sampleSize) ?? readableStream.read() ?? new Uint8Array(0); 48 | try { 49 | pass.fileType = await this.fromBuffer(chunk); 50 | } catch (error) { 51 | if (error instanceof strtok3.EndOfStreamError) { 52 | pass.fileType = undefined; 53 | } else { 54 | reject(error); 55 | } 56 | } 57 | 58 | resolve(outputStream); 59 | } catch (error) { 60 | reject(error); 61 | } 62 | })(); 63 | }); 64 | }); 65 | } 66 | } 67 | 68 | export async function fileTypeFromFile(path, options) { 69 | return (new FileTypeParser(options)).fromFile(path, options); 70 | } 71 | 72 | export async function fileTypeFromStream(stream, options) { 73 | return (new FileTypeParser(options)).fromStream(stream); 74 | } 75 | 76 | export async function fileTypeStream(readableStream, options = {}) { 77 | return new FileTypeParser(options).toDetectionStream(readableStream, options); 78 | } 79 | 80 | export { 81 | fileTypeFromTokenizer, 82 | fileTypeFromBuffer, 83 | fileTypeFromBlob, 84 | supportedMimeTypes, 85 | supportedExtensions, 86 | } from './core.js'; 87 | -------------------------------------------------------------------------------- /index.test-d.ts: -------------------------------------------------------------------------------- 1 | import {createReadStream} from 'node:fs'; 2 | import {Readable} from 'node:stream'; 3 | import {ReadableStream as NodeReadableStream} from 'node:stream/web'; 4 | import {expectType} from 'tsd'; 5 | import {fromFile} from 'strtok3'; 6 | import { 7 | type FileTypeResult as FileTypeResultBrowser, 8 | } from './core.js'; 9 | import { 10 | fileTypeFromBlob, 11 | fileTypeFromBuffer, 12 | fileTypeFromFile, 13 | fileTypeFromStream, 14 | fileTypeStream, 15 | type FileTypeResult, 16 | type ReadableStreamWithFileType, 17 | FileTypeParser, 18 | } from './index.js'; 19 | 20 | // `fileTypeStream`: accepts options merged from StreamOptions & FileTypeOptions 21 | (async () => { 22 | const stream = createReadStream('myFile'); 23 | expectType(await fileTypeStream(stream, {sampleSize: 256, customDetectors: []})); 24 | })(); 25 | 26 | // `FileTypeParser`: tests generic input types and mixed options 27 | (async () => { 28 | const fileTypeParser = new FileTypeParser({customDetectors: []}); 29 | const nodeStream = new Readable(); 30 | const webStream = new ReadableStream(); 31 | const nodeWebStream = new NodeReadableStream(); 32 | 33 | expectType(await fileTypeParser.fromStream(nodeStream)); 34 | expectType(await fileTypeParser.fromStream(webStream)); 35 | expectType(await fileTypeParser.fromStream(nodeWebStream)); 36 | 37 | expectType(await fileTypeParser.toDetectionStream(nodeStream, {sampleSize: 256, customDetectors: []})); 38 | })(); 39 | 40 | // Test that Blob overload returns browser-specific result 41 | expectType>(fileTypeFromBlob(new Blob([]))); 42 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Sindre Sorhus (https://sindresorhus.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /media/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sindresorhus/file-type/c54c7444ba5445a360cc40787fd1f26bb2765cec/media/logo.jpg -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-type", 3 | "version": "21.0.0", 4 | "description": "Detect the file type of a file, stream, or data", 5 | "license": "MIT", 6 | "repository": "sindresorhus/file-type", 7 | "funding": "https://github.com/sindresorhus/file-type?sponsor=1", 8 | "author": { 9 | "name": "Sindre Sorhus", 10 | "email": "sindresorhus@gmail.com", 11 | "url": "https://sindresorhus.com" 12 | }, 13 | "type": "module", 14 | "exports": { 15 | ".": { 16 | "node": { 17 | "types": "./index.d.ts", 18 | "import": "./index.js", 19 | "module-sync": "./index.js" 20 | }, 21 | "default": { 22 | "types": "./core.d.ts", 23 | "import": "./core.js", 24 | "module-sync": "./core.js" 25 | } 26 | }, 27 | "./core": { 28 | "types": "./core.d.ts", 29 | "default": "./core.js" 30 | }, 31 | "./node": { 32 | "types": "./index.d.ts", 33 | "default": "./index.js" 34 | } 35 | }, 36 | "sideEffects": false, 37 | "engines": { 38 | "node": ">=20" 39 | }, 40 | "scripts": { 41 | "test": "xo && ava && tsd" 42 | }, 43 | "files": [ 44 | "index.js", 45 | "index.d.ts", 46 | "core.js", 47 | "core.d.ts", 48 | "supported.js", 49 | "util.js" 50 | ], 51 | "keywords": [ 52 | "mime", 53 | "file", 54 | "type", 55 | "magic", 56 | "archive", 57 | "image", 58 | "img", 59 | "pic", 60 | "picture", 61 | "flash", 62 | "photo", 63 | "video", 64 | "detect", 65 | "check", 66 | "is", 67 | "exif", 68 | "elf", 69 | "macho", 70 | "exe", 71 | "binary", 72 | "buffer", 73 | "uint8array", 74 | "jpg", 75 | "png", 76 | "apng", 77 | "gif", 78 | "webp", 79 | "flif", 80 | "xcf", 81 | "cr2", 82 | "cr3", 83 | "orf", 84 | "arw", 85 | "dng", 86 | "nef", 87 | "rw2", 88 | "raf", 89 | "tif", 90 | "bmp", 91 | "icns", 92 | "jxr", 93 | "psd", 94 | "indd", 95 | "zip", 96 | "tar", 97 | "rar", 98 | "gz", 99 | "bz2", 100 | "7z", 101 | "dmg", 102 | "mp4", 103 | "mid", 104 | "mkv", 105 | "webm", 106 | "mov", 107 | "avi", 108 | "mpg", 109 | "mp2", 110 | "mp3", 111 | "m4a", 112 | "ogg", 113 | "opus", 114 | "flac", 115 | "wav", 116 | "amr", 117 | "pdf", 118 | "epub", 119 | "mobi", 120 | "swf", 121 | "rtf", 122 | "woff", 123 | "woff2", 124 | "eot", 125 | "ttf", 126 | "otf", 127 | "ttc", 128 | "ico", 129 | "flv", 130 | "ps", 131 | "xz", 132 | "sqlite", 133 | "xpi", 134 | "cab", 135 | "deb", 136 | "ar", 137 | "rpm", 138 | "Z", 139 | "lz", 140 | "cfb", 141 | "mxf", 142 | "mts", 143 | "wasm", 144 | "webassembly", 145 | "blend", 146 | "bpg", 147 | "docx", 148 | "pptx", 149 | "xlsx", 150 | "3gp", 151 | "j2c", 152 | "jp2", 153 | "jpm", 154 | "jpx", 155 | "mj2", 156 | "aif", 157 | "odt", 158 | "ods", 159 | "odp", 160 | "xml", 161 | "heic", 162 | "ics", 163 | "glb", 164 | "pcap", 165 | "dsf", 166 | "lnk", 167 | "alias", 168 | "voc", 169 | "ac3", 170 | "3g2", 171 | "m4b", 172 | "m4p", 173 | "m4v", 174 | "f4a", 175 | "f4b", 176 | "f4p", 177 | "f4v", 178 | "mie", 179 | "qcp", 180 | "asf", 181 | "ogv", 182 | "ogm", 183 | "oga", 184 | "spx", 185 | "ogx", 186 | "ape", 187 | "wv", 188 | "cur", 189 | "nes", 190 | "crx", 191 | "ktx", 192 | "dcm", 193 | "mpc", 194 | "arrow", 195 | "shp", 196 | "aac", 197 | "mp1", 198 | "it", 199 | "s3m", 200 | "xm", 201 | "skp", 202 | "avif", 203 | "eps", 204 | "lzh", 205 | "pgp", 206 | "asar", 207 | "stl", 208 | "chm", 209 | "3mf", 210 | "zst", 211 | "jxl", 212 | "vcf", 213 | "jls", 214 | "pst", 215 | "dwg", 216 | "parquet", 217 | "class", 218 | "arj", 219 | "cpio", 220 | "ace", 221 | "avro", 222 | "icc", 223 | "fbx", 224 | "vsdx", 225 | "vtt", 226 | "apk", 227 | "drc", 228 | "lz4", 229 | "potx", 230 | "xltx", 231 | "dotx", 232 | "xltm", 233 | "ots", 234 | "odg", 235 | "otg", 236 | "otp", 237 | "ott", 238 | "xlsm", 239 | "docm", 240 | "dotm", 241 | "potm", 242 | "pptm", 243 | "jar", 244 | "rm", 245 | "ppsm", 246 | "ppsx" 247 | ], 248 | "dependencies": { 249 | "@tokenizer/inflate": "^0.2.7", 250 | "strtok3": "^10.2.2", 251 | "token-types": "^6.0.0", 252 | "uint8array-extras": "^1.4.0" 253 | }, 254 | "devDependencies": { 255 | "@tokenizer/token": "^0.3.0", 256 | "@types/node": "^22.15.21", 257 | "ava": "^6.3.0", 258 | "commonmark": "^0.31.2", 259 | "get-stream": "^9.0.1", 260 | "noop-stream": "^1.0.0", 261 | "tsd": "^0.32.0", 262 | "xo": "^0.60.0" 263 | }, 264 | "xo": { 265 | "envs": [ 266 | "node", 267 | "browser" 268 | ], 269 | "ignores": [ 270 | "fixture" 271 | ], 272 | "rules": { 273 | "no-inner-declarations": "warn", 274 | "no-await-in-loop": "warn", 275 | "no-bitwise": "off", 276 | "@typescript-eslint/no-unsafe-assignment": "off", 277 | "unicorn/text-encoding-identifier-case": "off", 278 | "unicorn/switch-case-braces": "off", 279 | "unicorn/prefer-top-level-await": "off" 280 | } 281 | }, 282 | "ava": { 283 | "serial": true 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |

2 | file-type logo 3 |

4 | 5 | > Detect the file type of a file, stream, or data 6 | 7 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the buffer. 8 | 9 | This package is for detecting binary-based file formats, not text-based formats like `.txt`, `.csv`, `.svg`, etc. 10 | 11 | We accept contributions for commonly used modern file formats, not historical or obscure ones. Open an issue first for discussion. 12 | 13 | ## Install 14 | 15 | ```sh 16 | npm install file-type 17 | ``` 18 | 19 | **This package is an ESM package. Your project needs to be ESM too. [Read more](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c). For TypeScript + CommonJS, see [`load-esm`](https://github.com/Borewit/load-esm).** 20 | 21 | If you use it with Webpack, you need the latest Webpack version and ensure you configure it correctly for ESM. 22 | 23 | File type detection is based on binary signatures (magic numbers) and should be treated as a best-effort hint, not a guarantee. 24 | 25 | ## Usage 26 | 27 | ### Node.js 28 | 29 | Determine file type from a file: 30 | 31 | ```js 32 | import {fileTypeFromFile} from 'file-type'; 33 | 34 | console.log(await fileTypeFromFile('Unicorn.png')); 35 | //=> {ext: 'png', mime: 'image/png'} 36 | ``` 37 | 38 | Determine file type from a Uint8Array/ArrayBuffer, which may be a portion of the beginning of a file: 39 | 40 | ```js 41 | import {fileTypeFromBuffer} from 'file-type'; 42 | import {readChunk} from 'read-chunk'; 43 | 44 | const buffer = await readChunk('Unicorn.png', {length: 4100}); 45 | 46 | console.log(await fileTypeFromBuffer(buffer)); 47 | //=> {ext: 'png', mime: 'image/png'} 48 | ``` 49 | 50 | Determine file type from a stream: 51 | 52 | ```js 53 | import fs from 'node:fs'; 54 | import {fileTypeFromStream} from 'file-type'; 55 | 56 | const stream = fs.createReadStream('Unicorn.mp4'); 57 | 58 | console.log(await fileTypeFromStream(stream)); 59 | //=> {ext: 'mp4', mime: 'video/mp4'} 60 | ``` 61 | 62 | The stream method can also be used to read from a remote location: 63 | 64 | ```js 65 | import got from 'got'; 66 | import {fileTypeFromStream} from 'file-type'; 67 | 68 | const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg'; 69 | 70 | const stream = got.stream(url); 71 | 72 | console.log(await fileTypeFromStream(stream)); 73 | //=> {ext: 'jpg', mime: 'image/jpeg'} 74 | ``` 75 | 76 | Another stream example: 77 | 78 | ```js 79 | import stream from 'node:stream'; 80 | import fs from 'node:fs'; 81 | import crypto from 'node:crypto'; 82 | import {fileTypeStream} from 'file-type'; 83 | 84 | const read = fs.createReadStream('encrypted.enc'); 85 | const decipher = crypto.createDecipheriv(alg, key, iv); 86 | 87 | const streamWithFileType = await fileTypeStream(stream.pipeline(read, decipher)); 88 | 89 | console.log(streamWithFileType.fileType); 90 | //=> {ext: 'mov', mime: 'video/quicktime'} 91 | 92 | const write = fs.createWriteStream(`decrypted.${streamWithFileType.fileType.ext}`); 93 | streamWithFileType.pipe(write); 94 | ``` 95 | 96 | ### Browser 97 | 98 | ```js 99 | import {fileTypeFromStream} from 'file-type'; 100 | 101 | const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg'; 102 | 103 | const response = await fetch(url); 104 | const fileType = await fileTypeFromStream(response.body); 105 | 106 | console.log(fileType); 107 | //=> {ext: 'jpg', mime: 'image/jpeg'} 108 | ``` 109 | 110 | ## API 111 | 112 | ### fileTypeFromBuffer(buffer, options) 113 | 114 | Detect the file type of a `Uint8Array`, or `ArrayBuffer`. 115 | 116 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the buffer. 117 | 118 | If file access is available, it is recommended to use `fileTypeFromFile()` instead. 119 | 120 | Returns a `Promise` for an object with the detected file type: 121 | 122 | - `ext` - One of the [supported file types](#supported-file-types) 123 | - `mime` - The [MIME type](https://en.wikipedia.org/wiki/Internet_media_type) 124 | 125 | Or `undefined` when there is no match. 126 | 127 | #### buffer 128 | 129 | Type: `Uint8Array | ArrayBuffer` 130 | 131 | A buffer representing file data. It works best if the buffer contains the entire file. It may work with a smaller portion as well. 132 | 133 | ### fileTypeFromFile(filePath, options) 134 | 135 | Detect the file type of a file path. 136 | 137 | This is for Node.js only. 138 | 139 | To read from a [`File`](https://developer.mozilla.org/docs/Web/API/File), see [`fileTypeFromBlob()`](#filetypefromblobblob-options). 140 | 141 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the buffer. 142 | 143 | Returns a `Promise` for an object with the detected file type: 144 | 145 | - `ext` - One of the [supported file types](#supported-file-types) 146 | - `mime` - The [MIME type](https://en.wikipedia.org/wiki/Internet_media_type) 147 | 148 | Or `undefined` when there is no match. 149 | 150 | #### filePath 151 | 152 | Type: `string` 153 | 154 | The file path to parse. 155 | 156 | ### fileTypeFromStream(stream) 157 | 158 | Detect the file type of a [web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream). 159 | 160 | If the engine is Node.js, this may also be a [Node.js `stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable). 161 | 162 | Direct support for Node.js streams will be dropped in the future, when Node.js streams can be converted to Web streams (see [`toWeb()`](https://nodejs.org/api/stream.html#streamreadabletowebstreamreadable-options)). 163 | 164 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the buffer. 165 | 166 | Returns a `Promise` for an object with the detected file type: 167 | 168 | - `ext` - One of the [supported file types](#supported-file-types) 169 | - `mime` - The [MIME type](https://en.wikipedia.org/wiki/Internet_media_type) 170 | 171 | Or `undefined` when there is no match. 172 | 173 | #### stream 174 | 175 | Type: [Web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) or [Node.js `stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable) 176 | 177 | A readable stream representing file data. 178 | 179 | ### fileTypeFromBlob(blob, options) 180 | 181 | Detect the file type of a [`Blob`](https://developer.mozilla.org/docs/Web/API/Blob), 182 | 183 | > [!TIP] 184 | > A [`File` object](https://developer.mozilla.org/docs/Web/API/File) is a `Blob` and can be passed in here. 185 | 186 | It will **stream** the underlying Blob. 187 | 188 | The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the blob. 189 | 190 | Returns a `Promise` for an object with the detected file type: 191 | 192 | - `ext` - One of the [supported file types](#supported-file-types) 193 | - `mime` - The [MIME type](https://en.wikipedia.org/wiki/Internet_media_type) 194 | 195 | Or `undefined` when there is no match. 196 | 197 | ```js 198 | import {fileTypeFromBlob} from 'file-type'; 199 | 200 | const blob = new Blob([''], { 201 | type: 'text/plain', 202 | endings: 'native' 203 | }); 204 | 205 | console.log(await fileTypeFromBlob(blob)); 206 | //=> {ext: 'txt', mime: 'text/plain'} 207 | ``` 208 | 209 | > [!WARNING] 210 | > This method depends on [ReadableStreamBYOBReader](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader) which **requires Node.js ≥ 20** 211 | > and [may not be available in all modern browsers](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamBYOBReader#browser_compatibility). 212 | 213 | To work around this limitation, you can use an alternative approach to read and process the `Blob` without relying on streaming: 214 | 215 | ```js 216 | import {fileTypeFromBuffer} from 'file-type'; 217 | 218 | async function readFromBlobWithoutStreaming(blob) { 219 | const buffer = await blob.arrayBuffer(); 220 | return fileTypeFromBuffer(buffer); 221 | } 222 | ``` 223 | 224 | #### blob 225 | 226 | Type: [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) 227 | 228 | ### fileTypeFromTokenizer(tokenizer, options) 229 | 230 | Detect the file type from an `ITokenizer` source. 231 | 232 | This method is used internally, but can also be used for a special "tokenizer" reader. 233 | 234 | A tokenizer propagates the internal read functions, allowing alternative transport mechanisms, to access files, to be implemented and used. 235 | 236 | Returns a `Promise` for an object with the detected file type: 237 | 238 | - `ext` - One of the [supported file types](#supported-file-types) 239 | - `mime` - The [MIME type](https://en.wikipedia.org/wiki/Internet_media_type) 240 | 241 | Or `undefined` when there is no match. 242 | 243 | An example is [`@tokenizer/http`](https://github.com/Borewit/tokenizer-http), which requests data using [HTTP-range-requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests). A difference with a conventional stream and the [*tokenizer*](https://github.com/Borewit/strtok3#tokenizer), is that it can *ignore* (seek, fast-forward) in the stream. For example, you may only need and read the first 6 bytes, and the last 128 bytes, which may be an advantage in case reading the entire file would take longer. 244 | 245 | ```js 246 | import {makeTokenizer} from '@tokenizer/http'; 247 | import {fileTypeFromTokenizer} from 'file-type'; 248 | 249 | 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'; 250 | 251 | const httpTokenizer = await makeTokenizer(audioTrackUrl); 252 | const fileType = await fileTypeFromTokenizer(httpTokenizer); 253 | 254 | console.log(fileType); 255 | //=> {ext: 'mp3', mime: 'audio/mpeg'} 256 | ``` 257 | 258 | Or use [`@tokenizer/s3`](https://github.com/Borewit/tokenizer-s3) to determine the file type of a file stored on [Amazon S3](https://aws.amazon.com/s3): 259 | 260 | ```js 261 | import {S3Client} from '@aws-sdk/client-s3'; 262 | import {makeChunkedTokenizerFromS3} from '@tokenizer/s3'; 263 | import {fileTypeFromTokenizer} from 'file-type'; 264 | 265 | // Initialize the S3 client 266 | // Initialize S3 client 267 | const s3 = new S3Client(); 268 | 269 | // Initialize the S3 tokenizer. 270 | const s3Tokenizer = await makeChunkedTokenizerFromS3(s3, { 271 | Bucket: 'affectlab', 272 | Key: '1min_35sec.mp4' 273 | }); 274 | 275 | // Figure out what kind of file it is. 276 | const fileType = await fileTypeFromTokenizer(s3Tokenizer); 277 | console.log(fileType); 278 | ``` 279 | 280 | Note that only the minimum amount of data required to determine the file type is read (okay, just a bit extra to prevent too many fragmented reads). 281 | 282 | #### tokenizer 283 | 284 | Type: [`ITokenizer`](https://github.com/Borewit/strtok3#tokenizer) 285 | 286 | A file source implementing the [tokenizer interface](https://github.com/Borewit/strtok3#tokenizer). 287 | 288 | ### fileTypeStream(webStream, options?) 289 | 290 | Returns a `Promise` which resolves to the original readable stream argument, but with an added `fileType` property, which is an object like the one returned from `fileTypeFromFile()`. 291 | 292 | This method can be handy to put in between a stream, but it comes with a price. 293 | Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample, to determine the file type. 294 | The sample size impacts the file detection resolution. 295 | A smaller sample size will result in lower probability of the best file type detection. 296 | 297 | **Note:** When using Node.js, a `stream.Readable` may be provided as well. 298 | 299 | #### readableStream 300 | 301 | Type: [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable) 302 | 303 | #### options 304 | 305 | Type: `object` 306 | 307 | Supports the following options in addition to the [general options](#options): 308 | 309 | ##### sampleSize 310 | 311 | Type: `number`\ 312 | Default: `4100` 313 | 314 | The sample size in bytes. 315 | 316 | #### Example 317 | 318 | ```js 319 | import got from 'got'; 320 | import {fileTypeStream} from 'file-type'; 321 | 322 | const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg'; 323 | 324 | const stream1 = got.stream(url); 325 | const stream2 = await fileTypeStream(stream1, {sampleSize: 1024}); 326 | 327 | if (stream2.fileType?.mime === 'image/jpeg') { 328 | // stream2 can be used to stream the JPEG image (from the very beginning of the stream) 329 | } 330 | ``` 331 | 332 | #### readableStream 333 | 334 | Type: [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable) 335 | 336 | The input stream. 337 | 338 | ### supportedExtensions 339 | 340 | Returns a `Set` of supported file extensions. 341 | 342 | ### supportedMimeTypes 343 | 344 | Returns a `Set` of supported MIME types. 345 | 346 | ### Options 347 | 348 | #### customDetectors 349 | 350 | Array of custom file type detectors to run before default detectors. 351 | 352 | For example: 353 | 354 | ```js 355 | import {fileTypeFromFile} from 'file-type'; 356 | import {detectXml} from '@file-type/xml'; 357 | 358 | const fileType = await fileTypeFromFile('sample.kml', {customDetectors: [detectXml]}); 359 | console.log(fileType); 360 | ``` 361 | 362 | #### mpegOffsetTolerance 363 | 364 | Default: `0` 365 | 366 | Specifies the byte tolerance for locating the first MPEG audio frame (e.g. `.mp1`, `.mp2`, `.mp3`, `.aac`). 367 | 368 | Allows detection to handle slight sync offsets between the expected and actual frame start. Common in malformed or incorrectly muxed files, which, while technically invalid, do occur in the wild. 369 | 370 | A tolerance of 10 bytes covers most cases. 371 | 372 | ## Custom detectors 373 | 374 | Custom file type detectors are plugins designed to extend the default detection capabilities. 375 | They allow support for uncommon file types, non-binary formats, or customized detection behavior. 376 | 377 | Detectors can be added via the constructor options or by modifying `FileTypeParser#detectors` directly. 378 | Detectors provided through the constructor are executed before the default ones. 379 | 380 | Detectors can be added via the constructor options or by directly modifying `FileTypeParser#detectors`. 381 | 382 | ### Example adding a detector 383 | 384 | For example: 385 | 386 | ```js 387 | import {FileTypeParser} from 'file-type'; 388 | import {detectXml} from '@file-type/xml'; 389 | 390 | const parser = new FileTypeParser({customDetectors: [detectXml]}); 391 | const fileType = await parser.fromFile('sample.kml'); 392 | console.log(fileType); 393 | ``` 394 | 395 | ### Available third-party file-type detectors 396 | 397 | - [@file-type/xml](https://github.com/Borewit/file-type-xml): Detects common XML file types, such as GLM, KML, MusicXML, RSS, SVG, and XHTML 398 | 399 | ### Detector execution flow 400 | 401 | If a detector returns `undefined`, the following rules apply: 402 | 403 | 1. **No Tokenizer Interaction**: If the detector does not modify the tokenizer's position, the next detector in the sequence is executed. 404 | 2. **Tokenizer Interaction**: If the detector modifies the tokenizer's position (`tokenizer.position` is advanced), no further detectors are executed. In this case, the file type remains `undefined`, as subsequent detectors cannot evaluate the content. This is an exceptional scenario, as it prevents any other detectors from determining the file type. 405 | 406 | ### Writing your own custom detector 407 | 408 | Below is an example of a custom detector array. This can be passed to the `FileTypeParser` via the `fileTypeOptions` argument. 409 | 410 | ```js 411 | import {FileTypeParser} from 'file-type'; 412 | 413 | const unicornDetector = { 414 | id: 'unicorn', // May be used to recognize the detector in the detector list 415 | async detect(tokenizer) { 416 | const unicornHeader = [85, 78, 73, 67, 79, 82, 78]; // "UNICORN" in ASCII decimal 417 | 418 | const buffer = new Uint8Array(unicornHeader.length); 419 | await tokenizer.peekBuffer(buffer, {length: unicornHeader.length, mayBeLess: true}); 420 | if (unicornHeader.every((value, index) => value === buffer[index])) { 421 | return {ext: 'unicorn', mime: 'application/unicorn'}; 422 | } 423 | 424 | return undefined; 425 | } 426 | } 427 | 428 | const buffer = new Uint8Array([85, 78, 73, 67, 79, 82, 78]); 429 | const parser = new FileTypeParser({customDetectors: [unicornDetector]}); 430 | const fileType = await parser.fromBuffer(buffer); 431 | console.log(fileType); // {ext: 'unicorn', mime: 'application/unicorn'} 432 | ``` 433 | 434 | ```ts 435 | /** 436 | @param tokenizer - The [tokenizer](https://github.com/Borewit/strtok3#tokenizer) used to read file content. 437 | @param fileType - The file type detected by standard or previous custom detectors, or `undefined` if no match is found. 438 | @returns The detected file type, or `undefined` if no match is found. 439 | */ 440 | export type Detector = (tokenizer: ITokenizer, fileType?: FileTypeResult) => Promise; 441 | ``` 442 | 443 | ## Abort signal 444 | 445 | Some async operations can be aborted by passing an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) to the `FileTypeParser` constructor. 446 | 447 | ```js 448 | import {FileTypeParser} from 'file-type'; 449 | 450 | const abortController = new AbortController() 451 | 452 | const parser = new FileTypeParser({abortSignal: abortController.signal}); 453 | 454 | const promise = parser.fromStream(blob.stream()); 455 | 456 | abortController.abort(); // Abort file-type reading from the Blob stream. 457 | ``` 458 | 459 | ## Supported file types 460 | 461 | - [`3g2`](https://en.wikipedia.org/wiki/3GP_and_3G2#3G2) - Multimedia container format defined by the 3GPP2 for 3G CDMA2000 multimedia services 462 | - [`3gp`](https://en.wikipedia.org/wiki/3GP_and_3G2#3GP) - Multimedia container format defined by the Third Generation Partnership Project (3GPP) for 3G UMTS multimedia services 463 | - [`3mf`](https://en.wikipedia.org/wiki/3D_Manufacturing_Format) - 3D Manufacturing Format 464 | - [`7z`](https://en.wikipedia.org/wiki/7z) - 7-Zip archive 465 | - [`Z`](https://fileinfo.com/extension/z) - Unix Compressed File 466 | - [`aac`](https://en.wikipedia.org/wiki/Advanced_Audio_Coding) - Advanced Audio Coding 467 | - [`ac3`](https://www.atsc.org/standard/a522012-digital-audio-compression-ac-3-e-ac-3-standard-12172012/) - ATSC A/52 Audio File 468 | - [`ace`](https://en.wikipedia.org/wiki/ACE_(compressed_file_format)) - ACE archive 469 | - [`aif`](https://en.wikipedia.org/wiki/Audio_Interchange_File_Format) - Audio Interchange file 470 | - [`alias`](https://en.wikipedia.org/wiki/Alias_%28Mac_OS%29) - macOS Alias file 471 | - [`amr`](https://en.wikipedia.org/wiki/Adaptive_Multi-Rate_audio_codec) - Adaptive Multi-Rate audio codec 472 | - [`ape`](https://en.wikipedia.org/wiki/Monkey%27s_Audio) - Monkey's Audio 473 | - [`apk`](https://en.wikipedia.org/wiki/Apk_(file_format)) - Android package format 474 | - [`apng`](https://en.wikipedia.org/wiki/APNG) - Animated Portable Network Graphics 475 | - [`ar`](https://en.wikipedia.org/wiki/Ar_(Unix)) - Archive file 476 | - [`arj`](https://en.wikipedia.org/wiki/ARJ) - Archive file 477 | - [`arrow`](https://arrow.apache.org) - Columnar format for tables of data 478 | - [`arw`](https://en.wikipedia.org/wiki/Raw_image_format#ARW) - Sony Alpha Raw image file 479 | - [`asar`](https://github.com/electron/asar#format) - Archive format primarily used to enclose Electron applications 480 | - [`asf`](https://en.wikipedia.org/wiki/Advanced_Systems_Format) - Advanced Systems Format 481 | - [`avi`](https://en.wikipedia.org/wiki/Audio_Video_Interleave) - Audio Video Interleave file 482 | - [`avif`](https://en.wikipedia.org/wiki/AV1#AV1_Image_File_Format_(AVIF)) - AV1 Image File Format 483 | - [`avro`](https://en.wikipedia.org/wiki/Apache_Avro#Avro_Object_Container_File) - Object container file developed by Apache Avro 484 | - [`blend`](https://wiki.blender.org/index.php/Dev:Source/Architecture/File_Format) - Blender project 485 | - [`bmp`](https://en.wikipedia.org/wiki/BMP_file_format) - Bitmap image file 486 | - [`bpg`](https://bellard.org/bpg/) - Better Portable Graphics file 487 | - [`bz2`](https://en.wikipedia.org/wiki/Bzip2) - Archive file 488 | - [`cab`](https://en.wikipedia.org/wiki/Cabinet_(file_format)) - Cabinet file 489 | - [`cfb`](https://en.wikipedia.org/wiki/Compound_File_Binary_Format) - Compound File Binary Format 490 | - [`chm`](https://en.wikipedia.org/wiki/Microsoft_Compiled_HTML_Help) - Microsoft Compiled HTML Help 491 | - [`class`](https://en.wikipedia.org/wiki/Java_class_file) - Java class file 492 | - [`cpio`](https://en.wikipedia.org/wiki/Cpio) - Cpio archive 493 | - [`cr2`](https://fileinfo.com/extension/cr2) - Canon Raw image file (v2) 494 | - [`cr3`](https://fileinfo.com/extension/cr3) - Canon Raw image file (v3) 495 | - [`crx`](https://developer.chrome.com/extensions/crx) - Google Chrome extension 496 | - [`cur`](https://en.wikipedia.org/wiki/ICO_(file_format)) - Icon file 497 | - [`dcm`](https://en.wikipedia.org/wiki/DICOM#Data_format) - DICOM Image File 498 | - [`deb`](https://en.wikipedia.org/wiki/Deb_(file_format)) - Debian package 499 | - [`dmg`](https://en.wikipedia.org/wiki/Apple_Disk_Image) - Apple Disk Image 500 | - [`dng`](https://en.wikipedia.org/wiki/Digital_Negative) - Adobe Digital Negative image file 501 | - [`docm`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions) - Microsoft Word macro-enabled document 502 | - [`docx`](https://en.wikipedia.org/wiki/Office_Open_XML) - Microsoft Word document 503 | - [`dotm`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions) - Microsoft Word macro-enabled template 504 | - [`dotx`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions) - Microsoft Word template 505 | - [`drc`](https://en.wikipedia.org/wiki/Zstandard) - Google's Draco 3D Data Compression 506 | - [`dsf`](https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf) - Sony DSD Stream File (DSF) 507 | - [`dwg`](https://en.wikipedia.org/wiki/.dwg) - Autodesk CAD file 508 | - [`elf`](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) - Unix Executable and Linkable Format 509 | - [`eot`](https://en.wikipedia.org/wiki/Embedded_OpenType) - Embedded OpenType font 510 | - [`eps`](https://en.wikipedia.org/wiki/Encapsulated_PostScript) - Encapsulated PostScript 511 | - [`epub`](https://en.wikipedia.org/wiki/EPUB) - E-book file 512 | - [`exe`](https://en.wikipedia.org/wiki/.exe) - Executable file 513 | - [`f4a`](https://en.wikipedia.org/wiki/Flash_Video) - Audio-only ISO base media file format used by Adobe Flash Player 514 | - [`f4b`](https://en.wikipedia.org/wiki/Flash_Video) - Audiobook and podcast ISO base media file format used by Adobe Flash Player 515 | - [`f4p`](https://en.wikipedia.org/wiki/Flash_Video) - ISO base media file format protected by Adobe Access DRM used by Adobe Flash Player 516 | - [`f4v`](https://en.wikipedia.org/wiki/Flash_Video) - ISO base media file format used by Adobe Flash Player 517 | - [`fbx`](https://en.wikipedia.org/wiki/FBX) - Filmbox is a proprietary file format used to provide interoperability between digital content creation apps. 518 | - [`flac`](https://en.wikipedia.org/wiki/FLAC) - Free Lossless Audio Codec 519 | - [`flif`](https://en.wikipedia.org/wiki/Free_Lossless_Image_Format) - Free Lossless Image Format 520 | - [`flv`](https://en.wikipedia.org/wiki/Flash_Video) - Flash video 521 | - [`gif`](https://en.wikipedia.org/wiki/GIF) - Graphics Interchange Format 522 | - [`glb`](https://github.com/KhronosGroup/glTF) - GL Transmission Format 523 | - [`gz`](https://en.wikipedia.org/wiki/Gzip) - Archive file 524 | - [`heic`](https://nokiatech.github.io/heif/technical.html) - High Efficiency Image File Format 525 | - [`icc`](https://en.wikipedia.org/wiki/ICC_profile) - ICC Profile 526 | - [`icns`](https://en.wikipedia.org/wiki/Apple_Icon_Image_format) - Apple Icon image 527 | - [`ico`](https://en.wikipedia.org/wiki/ICO_(file_format)) - Windows icon file 528 | - [`ics`](https://en.wikipedia.org/wiki/ICalendar#Data_format) - iCalendar 529 | - [`indd`](https://en.wikipedia.org/wiki/Adobe_InDesign#File_format) - Adobe InDesign document 530 | - [`it`](https://wiki.openmpt.org/Manual:_Module_formats#The_Impulse_Tracker_format_.28.it.29) - Audio module format: Impulse Tracker 531 | - [`j2c`](https://en.wikipedia.org/wiki/JPEG_2000) - JPEG 2000 532 | - [`jar`](https://en.wikipedia.org/wiki/JAR_(file_format)) - Java archive 533 | - [`jls`](https://en.wikipedia.org/wiki/Lossless_JPEG#JPEG-LS) - Lossless/near-lossless compression standard for continuous-tone images 534 | - [`jp2`](https://en.wikipedia.org/wiki/JPEG_2000) - JPEG 2000 535 | - [`jpg`](https://en.wikipedia.org/wiki/JPEG) - Joint Photographic Experts Group image 536 | - [`jpm`](https://en.wikipedia.org/wiki/JPEG_2000) - JPEG 2000 537 | - [`jpx`](https://en.wikipedia.org/wiki/JPEG_2000) - JPEG 2000 538 | - [`jxl`](https://en.wikipedia.org/wiki/JPEG_XL) - JPEG XL image format 539 | - [`jxr`](https://en.wikipedia.org/wiki/JPEG_XR) - Joint Photographic Experts Group extended range 540 | - [`ktx`](https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/) - OpenGL and OpenGL ES textures 541 | - [`lnk`](https://en.wikipedia.org/wiki/Shortcut_%28computing%29#Microsoft_Windows) - Microsoft Windows file shortcut 542 | - [`lz`](https://en.wikipedia.org/wiki/Lzip) - Archive file 543 | - [`lz4`](https://en.wikipedia.org/wiki/LZ4_(compression_algorithm)) - Compressed archive created by one of a variety of LZ4 compression utilities 544 | - [`lzh`](https://en.wikipedia.org/wiki/LHA_(file_format)) - LZH archive 545 | - [`m4a`](https://en.wikipedia.org/wiki/M4A) - Audio-only MPEG-4 files 546 | - [`m4b`](https://en.wikipedia.org/wiki/M4B) - Audiobook and podcast MPEG-4 files, which also contain metadata including chapter markers, images, and hyperlinks 547 | - [`m4p`](https://en.wikipedia.org/wiki/MPEG-4_Part_14#Filename_extensions) - MPEG-4 files with audio streams encrypted by FairPlay Digital Rights Management as were sold through the iTunes Store 548 | - [`m4v`](https://en.wikipedia.org/wiki/M4V) - Video container format developed by Apple, which is very similar to the MP4 format 549 | - [`macho`](https://en.wikipedia.org/wiki/Mach-O) - Mach-O binary format 550 | - [`mid`](https://en.wikipedia.org/wiki/MIDI) - Musical Instrument Digital Interface file 551 | - [`mie`](https://en.wikipedia.org/wiki/Sidecar_file) - Dedicated meta information format which supports storage of binary as well as textual meta information 552 | - [`mj2`](https://en.wikipedia.org/wiki/Motion_JPEG_2000) - Motion JPEG 2000 553 | - [`mkv`](https://en.wikipedia.org/wiki/Matroska) - Matroska video file 554 | - [`mobi`](https://en.wikipedia.org/wiki/Mobipocket) - Mobipocket 555 | - [`mov`](https://en.wikipedia.org/wiki/QuickTime_File_Format) - QuickTime video file 556 | - [`mp1`](https://en.wikipedia.org/wiki/MPEG-1_Audio_Layer_I) - MPEG-1 Audio Layer I 557 | - [`mp2`](https://en.wikipedia.org/wiki/MPEG-1_Audio_Layer_II) - MPEG-1 Audio Layer II 558 | - [`mp3`](https://en.wikipedia.org/wiki/MP3) - Audio file 559 | - [`mp4`](https://en.wikipedia.org/wiki/MPEG-4_Part_14#Filename_extensions) - MPEG-4 Part 14 video file 560 | - [`mpc`](https://en.wikipedia.org/wiki/Musepack) - Musepack (SV7 & SV8) 561 | - [`mpg`](https://en.wikipedia.org/wiki/MPEG-1) - MPEG-1 file 562 | - [`mts`](https://en.wikipedia.org/wiki/.m2ts) - MPEG-2 Transport Stream, both raw and Blu-ray Disc Audio-Video (BDAV) versions 563 | - [`mxf`](https://en.wikipedia.org/wiki/Material_Exchange_Format) - Material Exchange Format 564 | - [`nef`](https://www.nikonusa.com/en/learn-and-explore/a/products-and-innovation/nikon-electronic-format-nef.html) - Nikon Electronic Format image file 565 | - [`nes`](https://fileinfo.com/extension/nes) - Nintendo NES ROM 566 | - [`odg`](https://en.wikipedia.org/wiki/OpenDocument) - OpenDocument for drawing 567 | - [`odp`](https://en.wikipedia.org/wiki/OpenDocument) - OpenDocument for presentations 568 | - [`ods`](https://en.wikipedia.org/wiki/OpenDocument) - OpenDocument for spreadsheets 569 | - [`odt`](https://en.wikipedia.org/wiki/OpenDocument) - OpenDocument for word processing 570 | - [`oga`](https://en.wikipedia.org/wiki/Ogg) - Audio file 571 | - [`ogg`](https://en.wikipedia.org/wiki/Ogg) - Audio file 572 | - [`ogm`](https://en.wikipedia.org/wiki/Ogg) - Audio file 573 | - [`ogv`](https://en.wikipedia.org/wiki/Ogg) - Audio file 574 | - [`ogx`](https://en.wikipedia.org/wiki/Ogg) - Audio file 575 | - [`opus`](https://en.wikipedia.org/wiki/Opus_(audio_format)) - Audio file 576 | - [`orf`](https://en.wikipedia.org/wiki/ORF_format) - Olympus Raw image file 577 | - [`otf`](https://en.wikipedia.org/wiki/OpenType) - OpenType font 578 | - [`otg`](https://en.wikipedia.org/wiki/OpenDocument_technical_specification#Templates) - OpenDocument template for drawing 579 | - [`otp`](https://en.wikipedia.org/wiki/OpenDocument_technical_specification#Templates) - OpenDocument template for presentations 580 | - [`ots`](https://en.wikipedia.org/wiki/OpenDocument_technical_specification#Templates) - OpenDocument template for spreadsheets 581 | - [`ott`](https://en.wikipedia.org/wiki/OpenDocument_technical_specification#Templates) - OpenDocument template for word processing 582 | - [`parquet`](https://en.wikipedia.org/wiki/Apache_Parquet) - Apache Parquet 583 | - [`pcap`](https://wiki.wireshark.org/Development/LibpcapFileFormat) - Libpcap File Format 584 | - [`pdf`](https://en.wikipedia.org/wiki/Portable_Document_Format) - Portable Document Format 585 | - [`pgp`](https://en.wikipedia.org/wiki/Pretty_Good_Privacy) - Pretty Good Privacy 586 | - [`png`](https://en.wikipedia.org/wiki/Portable_Network_Graphics) - Portable Network Graphics 587 | - [`potm`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions) - Microsoft PowerPoint macro-enabled template 588 | - [`potx`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions) - Microsoft PowerPoint template 589 | - [`ppsm`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions#PowerPoint) - Office PowerPoint 2007 macro-enabled slide show 590 | - [`ppsx`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions#PowerPoint) - Office PowerPoint 2007 slide show 591 | - [`pptm`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions) - Microsoft PowerPoint macro-enabled document 592 | - [`pptx`](https://en.wikipedia.org/wiki/Office_Open_XML) - Microsoft PowerPoint document 593 | - [`ps`](https://en.wikipedia.org/wiki/Postscript) - Postscript 594 | - [`psd`](https://en.wikipedia.org/wiki/Adobe_Photoshop#File_format) - Adobe Photoshop document 595 | - [`pst`](https://en.wikipedia.org/wiki/Personal_Storage_Table) - Personal Storage Table file 596 | - [`qcp`](https://en.wikipedia.org/wiki/QCP) - Tagged and chunked data 597 | - [`raf`](https://en.wikipedia.org/wiki/Raw_image_format) - Fujifilm RAW image file 598 | - [`rar`](https://en.wikipedia.org/wiki/RAR_(file_format)) - Archive file 599 | - [`rm`](https://en.wikipedia.org/wiki/RealMedia) - RealMedia 600 | - [`rpm`](https://fileinfo.com/extension/rpm) - Red Hat Package Manager file 601 | - [`rtf`](https://en.wikipedia.org/wiki/Rich_Text_Format) - Rich Text Format 602 | - [`rw2`](https://en.wikipedia.org/wiki/Raw_image_format) - Panasonic RAW image file 603 | - [`s3m`](https://wiki.openmpt.org/Manual:_Module_formats#The_ScreamTracker_3_format_.28.s3m.29) - Audio module format: ScreamTracker 3 604 | - [`shp`](https://en.wikipedia.org/wiki/Shapefile) - Geospatial vector data format 605 | - [`skp`](https://en.wikipedia.org/wiki/SketchUp) - SketchUp 606 | - [`spx`](https://en.wikipedia.org/wiki/Ogg) - Audio file 607 | - [`sqlite`](https://www.sqlite.org/fileformat2.html) - SQLite file 608 | - [`stl`](https://en.wikipedia.org/wiki/STL_(file_format)) - Standard Tesselated Geometry File Format (ASCII only) 609 | - [`swf`](https://en.wikipedia.org/wiki/SWF) - Adobe Flash Player file 610 | - [`tar`](https://en.wikipedia.org/wiki/Tar_(computing)#File_format) - Tarball archive file 611 | - [`tif`](https://en.wikipedia.org/wiki/Tagged_Image_File_Format) - Tagged Image file 612 | - [`ttc`](https://en.wikipedia.org/wiki/TrueType#TrueType_Collection) - TrueType Collection font 613 | - [`ttf`](https://en.wikipedia.org/wiki/TrueType) - TrueType font 614 | - [`vcf`](https://en.wikipedia.org/wiki/VCard) - vCard 615 | - [`voc`](https://wiki.multimedia.cx/index.php/Creative_Voice) - Creative Voice File 616 | - [`vsdx`](https://en.wikipedia.org/wiki/Microsoft_Visio) - Microsoft Visio File 617 | - [`vtt`](https://en.wikipedia.org/wiki/WebVTT) - WebVTT File (for video captions) 618 | - [`wasm`](https://en.wikipedia.org/wiki/WebAssembly) - WebAssembly intermediate compiled format 619 | - [`wav`](https://en.wikipedia.org/wiki/WAV) - Waveform Audio file 620 | - [`webm`](https://en.wikipedia.org/wiki/WebM) - Web video file 621 | - [`webp`](https://en.wikipedia.org/wiki/WebP) - Web Picture format 622 | - [`woff`](https://en.wikipedia.org/wiki/Web_Open_Font_Format) - Web Open Font Format 623 | - [`woff2`](https://en.wikipedia.org/wiki/Web_Open_Font_Format) - Web Open Font Format 624 | - [`wv`](https://en.wikipedia.org/wiki/WavPack) - WavPack 625 | - [`xcf`](https://en.wikipedia.org/wiki/XCF_(file_format)) - eXperimental Computing Facility 626 | - [`xlsm`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions) - Microsoft Excel macro-enabled document 627 | - [`xlsx`](https://en.wikipedia.org/wiki/Office_Open_XML) - Microsoft Excel document 628 | - [`xltm`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions) - Microsoft Excel macro-enabled template 629 | - [`xltx`](https://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions) - Microsoft Excel template 630 | - [`xm`](https://wiki.openmpt.org/Manual:_Module_formats#The_FastTracker_2_format_.28.xm.29) - Audio module format: FastTracker 2 631 | - [`xml`](https://en.wikipedia.org/wiki/XML) - eXtensible Markup Language 632 | - [`xpi`](https://en.wikipedia.org/wiki/XPInstall) - XPInstall file 633 | - [`xz`](https://en.wikipedia.org/wiki/Xz) - Compressed file 634 | - [`zip`](https://en.wikipedia.org/wiki/Zip_(file_format)) - Archive file 635 | - [`zst`](https://en.wikipedia.org/wiki/Zstandard) - Archive file 636 | 637 | *[Pull requests](.github/pull_request_template.md) are welcome for additional commonly used file types.* 638 | 639 | The following file types will not be accepted: 640 | - [MS-CFB: Microsoft Compound File Binary File Format based formats](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cfb/53989ce4-7b05-4f8d-829b-d08d6148375b), too old and difficult to parse: 641 | - `.doc` - Microsoft Word 97-2003 Document 642 | - `.xls` - Microsoft Excel 97-2003 Document 643 | - `.ppt` - Microsoft PowerPoint97-2003 Document 644 | - `.msi` - Microsoft Windows Installer 645 | - `.csv` - [Reason.](https://github.com/sindresorhus/file-type/issues/264#issuecomment-568439196) 646 | - `.svg` - Supported by [third-party detector](#available-third-party-file-type-detectors). 647 | 648 | #### tokenizer 649 | 650 | Type: [`ITokenizer`](https://github.com/Borewit/strtok3#tokenizer) 651 | 652 | Usable as source of the examined file. 653 | 654 | #### fileType 655 | 656 | Type: `FileTypeResult` 657 | 658 | An object having an `ext` (extension) and `mime` (mime type) property. 659 | 660 | Detected by the standard detections or a previous custom detection. Undefined if no matching fileTypeResult could be found. 661 | 662 | ## Related 663 | 664 | - [file-type-cli](https://github.com/sindresorhus/file-type-cli) - CLI for this module 665 | - [image-dimensions](https://github.com/sindresorhus/image-dimensions) - Get the dimensions of an image 666 | 667 | ## Maintainers 668 | 669 | - [Sindre Sorhus](https://github.com/sindresorhus) 670 | - [Borewit](https://github.com/Borewit) 671 | -------------------------------------------------------------------------------- /supported.js: -------------------------------------------------------------------------------- 1 | export const extensions = [ 2 | 'jpg', 3 | 'png', 4 | 'apng', 5 | 'gif', 6 | 'webp', 7 | 'flif', 8 | 'xcf', 9 | 'cr2', 10 | 'cr3', 11 | 'orf', 12 | 'arw', 13 | 'dng', 14 | 'nef', 15 | 'rw2', 16 | 'raf', 17 | 'tif', 18 | 'bmp', 19 | 'icns', 20 | 'jxr', 21 | 'psd', 22 | 'indd', 23 | 'zip', 24 | 'tar', 25 | 'rar', 26 | 'gz', 27 | 'bz2', 28 | '7z', 29 | 'dmg', 30 | 'mp4', 31 | 'mid', 32 | 'mkv', 33 | 'webm', 34 | 'mov', 35 | 'avi', 36 | 'mpg', 37 | 'mp2', 38 | 'mp3', 39 | 'm4a', 40 | 'oga', 41 | 'ogg', 42 | 'ogv', 43 | 'opus', 44 | 'flac', 45 | 'wav', 46 | 'spx', 47 | 'amr', 48 | 'pdf', 49 | 'epub', 50 | 'elf', 51 | 'macho', 52 | 'exe', 53 | 'swf', 54 | 'rtf', 55 | 'wasm', 56 | 'woff', 57 | 'woff2', 58 | 'eot', 59 | 'ttf', 60 | 'otf', 61 | 'ttc', 62 | 'ico', 63 | 'flv', 64 | 'ps', 65 | 'xz', 66 | 'sqlite', 67 | 'nes', 68 | 'crx', 69 | 'xpi', 70 | 'cab', 71 | 'deb', 72 | 'ar', 73 | 'rpm', 74 | 'Z', 75 | 'lz', 76 | 'cfb', 77 | 'mxf', 78 | 'mts', 79 | 'blend', 80 | 'bpg', 81 | 'docx', 82 | 'pptx', 83 | 'xlsx', 84 | '3gp', 85 | '3g2', 86 | 'j2c', 87 | 'jp2', 88 | 'jpm', 89 | 'jpx', 90 | 'mj2', 91 | 'aif', 92 | 'qcp', 93 | 'odt', 94 | 'ods', 95 | 'odp', 96 | 'xml', 97 | 'mobi', 98 | 'heic', 99 | 'cur', 100 | 'ktx', 101 | 'ape', 102 | 'wv', 103 | 'dcm', 104 | 'ics', 105 | 'glb', 106 | 'pcap', 107 | 'dsf', 108 | 'lnk', 109 | 'alias', 110 | 'voc', 111 | 'ac3', 112 | 'm4v', 113 | 'm4p', 114 | 'm4b', 115 | 'f4v', 116 | 'f4p', 117 | 'f4b', 118 | 'f4a', 119 | 'mie', 120 | 'asf', 121 | 'ogm', 122 | 'ogx', 123 | 'mpc', 124 | 'arrow', 125 | 'shp', 126 | 'aac', 127 | 'mp1', 128 | 'it', 129 | 's3m', 130 | 'xm', 131 | 'skp', 132 | 'avif', 133 | 'eps', 134 | 'lzh', 135 | 'pgp', 136 | 'asar', 137 | 'stl', 138 | 'chm', 139 | '3mf', 140 | 'zst', 141 | 'jxl', 142 | 'vcf', 143 | 'jls', 144 | 'pst', 145 | 'dwg', 146 | 'parquet', 147 | 'class', 148 | 'arj', 149 | 'cpio', 150 | 'ace', 151 | 'avro', 152 | 'icc', 153 | 'fbx', 154 | 'vsdx', 155 | 'vtt', 156 | 'apk', 157 | 'drc', 158 | 'lz4', 159 | 'potx', 160 | 'xltx', 161 | 'dotx', 162 | 'xltm', 163 | 'ott', 164 | 'ots', 165 | 'otp', 166 | 'odg', 167 | 'otg', 168 | 'xlsm', 169 | 'docm', 170 | 'dotm', 171 | 'potm', 172 | 'pptm', 173 | 'jar', 174 | 'rm', 175 | 'ppsm', 176 | 'ppsx', 177 | ]; 178 | 179 | export const mimeTypes = [ 180 | 'image/jpeg', 181 | 'image/png', 182 | 'image/gif', 183 | 'image/webp', 184 | 'image/flif', 185 | 'image/x-xcf', 186 | 'image/x-canon-cr2', 187 | 'image/x-canon-cr3', 188 | 'image/tiff', 189 | 'image/bmp', 190 | 'image/vnd.ms-photo', 191 | 'image/vnd.adobe.photoshop', 192 | 'application/x-indesign', 193 | 'application/epub+zip', 194 | 'application/x-xpinstall', 195 | 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', 196 | 'application/vnd.oasis.opendocument.text', 197 | 'application/vnd.oasis.opendocument.spreadsheet', 198 | 'application/vnd.oasis.opendocument.presentation', 199 | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 200 | 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 201 | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 202 | 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 203 | 'application/zip', 204 | 'application/x-tar', 205 | 'application/x-rar-compressed', 206 | 'application/gzip', 207 | 'application/x-bzip2', 208 | 'application/x-7z-compressed', 209 | 'application/x-apple-diskimage', 210 | 'application/vnd.apache.arrow.file', 211 | 'video/mp4', 212 | 'audio/midi', 213 | 'video/matroska', 214 | 'video/webm', 215 | 'video/quicktime', 216 | 'video/vnd.avi', 217 | 'audio/wav', 218 | 'audio/qcelp', 219 | 'audio/x-ms-asf', 220 | 'video/x-ms-asf', 221 | 'application/vnd.ms-asf', 222 | 'video/mpeg', 223 | 'video/3gpp', 224 | 'audio/mpeg', 225 | 'audio/mp4', // RFC 4337 226 | 'video/ogg', 227 | 'audio/ogg', 228 | 'audio/ogg; codecs=opus', 229 | 'application/ogg', 230 | 'audio/flac', 231 | 'audio/ape', 232 | 'audio/wavpack', 233 | 'audio/amr', 234 | 'application/pdf', 235 | 'application/x-elf', 236 | 'application/x-mach-binary', 237 | 'application/x-msdownload', 238 | 'application/x-shockwave-flash', 239 | 'application/rtf', 240 | 'application/wasm', 241 | 'font/woff', 242 | 'font/woff2', 243 | 'application/vnd.ms-fontobject', 244 | 'font/ttf', 245 | 'font/otf', 246 | 'font/collection', 247 | 'image/x-icon', 248 | 'video/x-flv', 249 | 'application/postscript', 250 | 'application/eps', 251 | 'application/x-xz', 252 | 'application/x-sqlite3', 253 | 'application/x-nintendo-nes-rom', 254 | 'application/x-google-chrome-extension', 255 | 'application/vnd.ms-cab-compressed', 256 | 'application/x-deb', 257 | 'application/x-unix-archive', 258 | 'application/x-rpm', 259 | 'application/x-compress', 260 | 'application/x-lzip', 261 | 'application/x-cfb', 262 | 'application/x-mie', 263 | 'application/mxf', 264 | 'video/mp2t', 265 | 'application/x-blender', 266 | 'image/bpg', 267 | 'image/j2c', 268 | 'image/jp2', 269 | 'image/jpx', 270 | 'image/jpm', 271 | 'image/mj2', 272 | 'audio/aiff', 273 | 'application/xml', 274 | 'application/x-mobipocket-ebook', 275 | 'image/heif', 276 | 'image/heif-sequence', 277 | 'image/heic', 278 | 'image/heic-sequence', 279 | 'image/icns', 280 | 'image/ktx', 281 | 'application/dicom', 282 | 'audio/x-musepack', 283 | 'text/calendar', 284 | 'text/vcard', 285 | 'text/vtt', 286 | 'model/gltf-binary', 287 | 'application/vnd.tcpdump.pcap', 288 | 'audio/x-dsf', // Non-standard 289 | 'application/x.ms.shortcut', // Invented by us 290 | 'application/x.apple.alias', // Invented by us 291 | 'audio/x-voc', 292 | 'audio/vnd.dolby.dd-raw', 293 | 'audio/x-m4a', 294 | 'image/apng', 295 | 'image/x-olympus-orf', 296 | 'image/x-sony-arw', 297 | 'image/x-adobe-dng', 298 | 'image/x-nikon-nef', 299 | 'image/x-panasonic-rw2', 300 | 'image/x-fujifilm-raf', 301 | 'video/x-m4v', 302 | 'video/3gpp2', 303 | 'application/x-esri-shape', 304 | 'audio/aac', 305 | 'audio/x-it', 306 | 'audio/x-s3m', 307 | 'audio/x-xm', 308 | 'video/MP1S', 309 | 'video/MP2P', 310 | 'application/vnd.sketchup.skp', 311 | 'image/avif', 312 | 'application/x-lzh-compressed', 313 | 'application/pgp-encrypted', 314 | 'application/x-asar', 315 | 'model/stl', 316 | 'application/vnd.ms-htmlhelp', 317 | 'model/3mf', 318 | 'image/jxl', 319 | 'application/zstd', 320 | 'image/jls', 321 | 'application/vnd.ms-outlook', 322 | 'image/vnd.dwg', 323 | 'application/vnd.apache.parquet', 324 | 'application/java-vm', 325 | 'application/x-arj', 326 | 'application/x-cpio', 327 | 'application/x-ace-compressed', 328 | 'application/avro', 329 | 'application/vnd.iccprofile', 330 | 'application/x.autodesk.fbx', // Invented by us 331 | 'application/vnd.visio', 332 | 'application/vnd.android.package-archive', 333 | 'application/vnd.google.draco', // Invented by us 334 | 'application/x-lz4', // Invented by us 335 | 'application/vnd.openxmlformats-officedocument.presentationml.template', 336 | 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 337 | 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 338 | 'application/vnd.ms-excel.template.macroenabled.12', 339 | 'application/vnd.oasis.opendocument.text-template', 340 | 'application/vnd.oasis.opendocument.spreadsheet-template', 341 | 'application/vnd.oasis.opendocument.presentation-template', 342 | 'application/vnd.oasis.opendocument.graphics', 343 | 'application/vnd.oasis.opendocument.graphics-template', 344 | 'application/vnd.ms-excel.sheet.macroenabled.12', 345 | 'application/vnd.ms-word.document.macroenabled.12', 346 | 'application/vnd.ms-word.template.macroenabled.12', 347 | 'application/vnd.ms-powerpoint.template.macroenabled.12', 348 | 'application/vnd.ms-powerpoint.presentation.macroenabled.12', 349 | 'application/java-archive', 350 | 'application/vnd.rn-realmedia', 351 | ]; 352 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | import process from 'node:process'; 2 | import path from 'node:path'; 3 | import {fileURLToPath} from 'node:url'; 4 | import fs from 'node:fs'; 5 | import {readFile} from 'node:fs/promises'; 6 | import stream from 'node:stream'; 7 | import test from 'ava'; 8 | import {readableNoopStream} from 'noop-stream'; 9 | import {Parser as ReadmeParser} from 'commonmark'; 10 | import * as strtok3 from 'strtok3/core'; 11 | import {areUint8ArraysEqual} from 'uint8array-extras'; 12 | import {getStreamAsArrayBuffer} from 'get-stream'; 13 | import { 14 | fileTypeFromBuffer, 15 | fileTypeFromStream as fileTypeNodeFromStream, 16 | fileTypeFromFile, 17 | fileTypeFromBlob, 18 | fileTypeStream, 19 | supportedExtensions, 20 | supportedMimeTypes, 21 | FileTypeParser, 22 | } from './index.js'; 23 | 24 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); 25 | 26 | const missingTests = new Set([ 27 | ]); 28 | 29 | const [nodeMajorVersion] = process.versions.node.split('.').map(Number); 30 | const nodeVersionSupportingByteBlobStream = 20; 31 | 32 | const types = [...supportedExtensions].filter(extension => !missingTests.has(extension)); 33 | 34 | // Define an entry here only if the fixture has a different 35 | // name than `fixture` or if you want multiple fixtures 36 | const names = { 37 | aac: [ 38 | 'fixture-adts-mpeg2', 39 | 'fixture-adts-mpeg4', 40 | 'fixture-adts-mpeg4-2', 41 | 'fixture-id3v2', 42 | ], 43 | asar: [ 44 | 'fixture', 45 | 'fixture2', 46 | ], 47 | arw: [ 48 | 'fixture-sony-zv-e10', 49 | ], 50 | cr3: [ 51 | 'fixture', 52 | ], 53 | dng: [ 54 | 'fixture-Leica-M10', 55 | ], 56 | drc: [ 57 | 'fixture-cube_pc', 58 | ], 59 | epub: [ 60 | 'fixture', 61 | 'fixture-crlf', 62 | ], 63 | nef: [ 64 | 'fixture', 65 | 'fixture2', 66 | 'fixture3', 67 | 'fixture4', 68 | ], 69 | '3gp': [ 70 | 'fixture', 71 | 'fixture2', 72 | ], 73 | woff2: [ 74 | 'fixture', 75 | 'fixture-otto', 76 | ], 77 | woff: [ 78 | 'fixture', 79 | 'fixture-otto', 80 | ], 81 | eot: [ 82 | 'fixture', 83 | 'fixture-0x20001', 84 | ], 85 | mov: [ 86 | 'fixture', 87 | 'fixture-mjpeg', 88 | 'fixture-moov', 89 | ], 90 | mp2: [ 91 | 'fixture', 92 | 'fixture-mpa', 93 | ], 94 | mp3: [ 95 | 'fixture', 96 | 'fixture-mp2l3', 97 | 'fixture-ffe3', 98 | ], 99 | mp4: [ 100 | 'fixture-imovie', 101 | 'fixture-isom', 102 | 'fixture-isomv2', 103 | 'fixture-mp4v2', 104 | 'fixture-dash', 105 | ], 106 | mts: [ 107 | 'fixture-raw', 108 | 'fixture-bdav', 109 | ], 110 | tif: [ 111 | 'fixture-big-endian', 112 | 'fixture-little-endian', 113 | 'fixture-bali', 114 | ], 115 | gz: [ 116 | 'fixture.tar', 117 | ], 118 | xz: [ 119 | 'fixture.tar', 120 | ], 121 | lz: [ 122 | 'fixture.tar', 123 | ], 124 | Z: [ 125 | 'fixture.tar', 126 | ], 127 | zst: [ 128 | 'fixture.tar', 129 | ], 130 | mkv: [ 131 | 'fixture', 132 | 'fixture2', 133 | ], 134 | mpg: [ 135 | 'fixture', 136 | 'fixture2', 137 | 'fixture.ps', 138 | 'fixture.sub', 139 | ], 140 | heic: [ 141 | 'fixture-mif1', 142 | 'fixture-msf1', 143 | 'fixture-heic', 144 | ], 145 | ape: [ 146 | 'fixture-monkeysaudio', 147 | ], 148 | mpc: [ 149 | 'fixture-sv7', 150 | 'fixture-sv8', 151 | ], 152 | pcap: [ 153 | 'fixture-big-endian', 154 | 'fixture-little-endian', 155 | ], 156 | png: [ 157 | 'fixture', 158 | 'fixture-itxt', 159 | ], 160 | tar: [ 161 | 'fixture', 162 | 'fixture-v7', 163 | 'fixture-spaces', 164 | 'fixture-pax', 165 | ], 166 | mie: [ 167 | 'fixture-big-endian', 168 | 'fixture-little-endian', 169 | ], 170 | m4a: [ 171 | 'fixture-babys-songbook.m4b', // Actually it's an `.m4b` 172 | ], 173 | m4v: [ 174 | 'fixture', 175 | 'fixture-2', // Previously named as `fixture.mp4` 176 | ], 177 | flac: [ 178 | 'fixture', 179 | 'fixture-id3v2', // FLAC prefixed with ID3v2 header 180 | ], 181 | docx: [ 182 | 'fixture', 183 | 'fixture2', 184 | 'fixture-office365', 185 | ], 186 | pptx: [ 187 | 'fixture', 188 | 'fixture2', 189 | 'fixture-office365', 190 | ], 191 | xlsx: [ 192 | 'fixture', 193 | 'fixture2', 194 | 'fixture-office365', 195 | ], 196 | ogx: [ 197 | 'fixture-unknown-ogg', // Manipulated fixture to unrecognized Ogg based file 198 | ], 199 | avif: [ 200 | 'fixture-yuv420-8bit', // Multiple bit-depths and/or subsamplings 201 | 'fixture-sequence', 202 | ], 203 | eps: [ 204 | 'fixture', 205 | 'fixture2', 206 | ], 207 | cfb: [ 208 | 'fixture.msi', 209 | 'fixture.xls', 210 | 'fixture.doc', 211 | 'fixture.ppt', 212 | 'fixture-2.doc', 213 | ], 214 | asf: [ 215 | 'fixture', 216 | 'fixture.wma', 217 | 'fixture.wmv', 218 | ], 219 | jxl: [ 220 | 'fixture', // Image data stored within JXL container 221 | 'fixture2', // Bare image data with no container 222 | ], 223 | pdf: [ 224 | 'fixture', 225 | 'fixture-adobe-illustrator', // PDF saved from Adobe Illustrator, using the default "[Illustrator Default]" preset 226 | 'fixture-smallest', // PDF saved from Adobe Illustrator, using the preset "smallest PDF" 227 | 'fixture-fast-web', // PDF saved from Adobe Illustrator, using the default "[Illustrator Default"] preset, but enabling "Optimize for Fast Web View" 228 | 'fixture-printed', // PDF printed from Adobe Illustrator, but with a PDF printer. 229 | 'fixture-minimal', // PDF written to be as small as the spec allows 230 | ], 231 | webm: [ 232 | 'fixture-null', // EBML DocType with trailing null character 233 | ], 234 | xml: [ 235 | 'fixture', 236 | 'fixture-utf8-bom', // UTF-8 with BOM 237 | 'fixture-utf16-be-bom', // UTF-16 little endian encoded XML, with BOM 238 | 'fixture-utf16-le-bom', // UTF-16 big endian encoded XML, with BOM 239 | ], 240 | jls: [ 241 | 'fixture-normal', 242 | 'fixture-hp1', 243 | 'fixture-hp2', 244 | 'fixture-hp3', 245 | ], 246 | pst: [ 247 | 'fixture-sample', 248 | ], 249 | dwg: [ 250 | 'fixture-line-weights', 251 | ], 252 | j2c: [ 253 | 'fixture', 254 | ], 255 | cpio: [ 256 | 'fixture-bin', 257 | 'fixture-ascii', 258 | ], 259 | vsdx: [ 260 | 'fixture-vsdx', 261 | 'fixture-vstx', 262 | ], 263 | vtt: [ 264 | 'fixture-vtt-linebreak', 265 | 'fixture-vtt-space', 266 | 'fixture-vtt-tab', 267 | 'fixture-vtt-eof', 268 | ], 269 | lz4: [ 270 | 'fixture', 271 | ], 272 | rm: [ 273 | 'fixture-realmedia-audio', 274 | 'fixture-realmedia-video', 275 | ], 276 | ppsx: [ 277 | 'fixture', 278 | ], 279 | ppsm: [ 280 | 'fixture', 281 | ], 282 | }; 283 | 284 | // Define an entry here only if the file type has potential 285 | // for false-positives 286 | const falsePositives = { 287 | png: [ 288 | 'fixture-corrupt', 289 | ], 290 | webp: [ 291 | 'fixture-json', 292 | ], 293 | }; 294 | 295 | // Known failing fixture 296 | const failingFixture = new Set([ 297 | 'fixture-password-protected.xls', // Excel / MS-OSHARED / Compound-File-Binary-Format 298 | ]); 299 | 300 | /** 301 | @returns {Array} An array of fixture objects. 302 | Each object contains the following properties: 303 | - `path` {string}: The full path to the fixture file. 304 | - `filename` {string}: The name of the fixture file. 305 | - `type` {string}: The type/extension of the fixture. 306 | */ 307 | function getFixtures() { 308 | const paths = []; 309 | for (const type of types) { 310 | if (Object.hasOwn(names, type)) { 311 | for (const suffix of names[type]) { 312 | const filename = `${(suffix ?? 'fixture')}.${type}`; 313 | paths.push({ 314 | path: path.join(__dirname, 'fixture', filename), 315 | filename, 316 | type, 317 | }); 318 | } 319 | } else { 320 | const filename = `fixture.${type}`; 321 | paths.push({ 322 | path: path.join(__dirname, 'fixture', filename), 323 | filename, 324 | type, 325 | }); 326 | } 327 | } 328 | 329 | return paths; 330 | } 331 | 332 | async function checkBufferLike(t, expectedExtension, bufferLike) { 333 | const {ext, mime} = await fileTypeFromBuffer(bufferLike) ?? {}; 334 | t.is(ext, expectedExtension); 335 | t.is(typeof mime, 'string'); 336 | } 337 | 338 | async function checkBlobLike(t, expectedExtension, bufferLike) { 339 | const blob = new Blob([bufferLike]); 340 | const {ext, mime} = await fileTypeFromBlob(blob) ?? {}; 341 | t.is(ext, expectedExtension); 342 | t.is(typeof mime, 'string'); 343 | } 344 | 345 | async function testFromFile(t, expectedExtension, filePath) { 346 | const {ext, mime} = await fileTypeFromFile(filePath) ?? {}; 347 | t.is(ext, expectedExtension); 348 | t.is(typeof mime, 'string'); 349 | } 350 | 351 | async function testFromBuffer(t, expectedExtension, path) { 352 | const chunk = fs.readFileSync(path); 353 | await checkBufferLike(t, expectedExtension, chunk); 354 | await checkBufferLike(t, expectedExtension, new Uint8Array(chunk)); 355 | await checkBufferLike(t, expectedExtension, chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength)); 356 | } 357 | 358 | async function testFromBlob(t, expectedExtension, path) { 359 | const chunk = fs.readFileSync(path); 360 | await checkBlobLike(t, expectedExtension, chunk); 361 | } 362 | 363 | async function testFalsePositive(t, filePath) { 364 | await t.is(await fileTypeFromFile(filePath), undefined); 365 | 366 | const chunk = fs.readFileSync(filePath); 367 | t.is(await fileTypeFromBuffer(chunk), undefined); 368 | t.is(await fileTypeFromBuffer(new Uint8Array(chunk)), undefined); 369 | t.is(await fileTypeFromBuffer(chunk.buffer), undefined); 370 | } 371 | 372 | async function testFileNodeFromStream(t, expectedExtension, filePath, filename) { 373 | const fileType = await fileTypeNodeFromStream(fs.createReadStream(filePath)); 374 | 375 | t.truthy(fileType, `identify ${filename}`); 376 | t.is(fileType.ext, expectedExtension, 'fileType.ext'); 377 | t.is(typeof fileType.mime, 'string', 'fileType.mime'); 378 | } 379 | 380 | async function getStreamAsUint8Array(stream) { 381 | return new Uint8Array(await getStreamAsArrayBuffer(stream)); 382 | } 383 | 384 | async function testStreamWithNodeStream(t, expectedExtension, filePath) { 385 | const readableStream = await fileTypeStream(fs.createReadStream(filePath)); 386 | try { 387 | const fileStream = fs.createReadStream(filePath); 388 | try { 389 | const [bufferA, bufferB] = await Promise.all([getStreamAsUint8Array(readableStream), getStreamAsUint8Array(fileStream)]); 390 | t.true(areUint8ArraysEqual(bufferA, bufferB)); 391 | } finally { 392 | fileStream.destroy(); 393 | } 394 | } finally { 395 | readableStream.destroy(); 396 | } 397 | } 398 | 399 | async function testStreamWithWebStream(t, expectedExtension, path) { 400 | // Read the file into a buffer 401 | const fileBuffer = await readFile(path); 402 | // Create a Blob from the buffer 403 | const blob = new Blob([fileBuffer]); 404 | const webStream = await fileTypeStream(blob.stream()); 405 | t.false(webStream.locked); 406 | const webStreamResult = await getStreamAsUint8Array(webStream); 407 | t.false(webStream.locked, 'Ensure web-stream is released'); 408 | t.true(areUint8ArraysEqual(fileBuffer, webStreamResult)); 409 | } 410 | 411 | test('Test suite must be able to detect Node.js major version', t => { 412 | t.is(typeof nodeMajorVersion, 'number', 'Detected Node.js major version should be a number'); 413 | }); 414 | 415 | let i = 0; 416 | for (const fixture of getFixtures()) { 417 | const _test = failingFixture.has(fixture.filename) ? test.failing : test; 418 | 419 | _test(`${fixture.filename} ${i++} .fileTypeFromFile() method - same fileType`, testFromFile, fixture.type, fixture.path); 420 | _test(`${fixture.filename} ${i++} .fileTypeFromBuffer() method - same fileType`, testFromBuffer, fixture.type, fixture.path); 421 | if (nodeMajorVersion >= nodeVersionSupportingByteBlobStream) { 422 | // Blob requires to stream to BYOB ReadableStream, requiring Node.js ≥ 20 423 | _test(`${fixture.filename} ${i++} .fileTypeFromBlob() method - same fileType`, testFromBlob, fixture.type, fixture.path); 424 | test(`${fixture.filename} ${i++} .fileTypeStream() - identical Web Streams`, testStreamWithWebStream, fixture.type, fixture.path); 425 | } 426 | 427 | _test(`${fixture.filename} ${i++} .fileTypeFromStream() Node.js method - same fileType`, testFileNodeFromStream, fixture.type, fixture.path, fixture.filename); 428 | _test(`${fixture.filename} ${i++} .fileTypeStream() - identical Node.js Readable streams`, testStreamWithNodeStream, fixture.type, fixture.path); 429 | 430 | if (Object.hasOwn(falsePositives, fixture.filename)) { 431 | for (const falsePositiveFile of falsePositives[fixture.filename]) { 432 | test(`false positive - ${fixture.filename} ${i++}`, testFalsePositive, fixture.filename, falsePositiveFile); 433 | } 434 | } 435 | } 436 | 437 | test('.fileTypeStream() method - empty stream', async t => { 438 | const newStream = await fileTypeStream(readableNoopStream()); 439 | t.is(newStream.fileType, undefined); 440 | }); 441 | 442 | test('.fileTypeStream() method - short stream', async t => { 443 | const bufferA = new Uint8Array([0, 1, 0, 1]); 444 | class MyStream extends stream.Readable { 445 | _read() { 446 | this.push(bufferA); 447 | this.push(null); 448 | } 449 | } 450 | 451 | // Test filetype detection 452 | const shortStream = new MyStream(); 453 | const newStream = await fileTypeStream(shortStream); 454 | t.is(newStream.fileType, undefined); 455 | 456 | // Test usability of returned stream 457 | const bufferB = await getStreamAsUint8Array(newStream); 458 | t.deepEqual(bufferA, bufferB); 459 | }); 460 | 461 | test('.fileTypeStream() method - no end-of-stream errors', async t => { 462 | const file = path.join(__dirname, 'fixture', 'fixture.ogm'); 463 | const stream = await fileTypeStream(fs.createReadStream(file), {sampleSize: 30}); 464 | t.is(stream.fileType, undefined); 465 | }); 466 | 467 | test('.fileTypeStream() method - error event', async t => { 468 | const errorMessage = 'Fixture'; 469 | 470 | const readableStream = new stream.Readable({ 471 | read() { 472 | process.nextTick(() => { 473 | this.emit('error', new Error(errorMessage)); 474 | }); 475 | }, 476 | }); 477 | 478 | await t.throwsAsync(fileTypeStream(readableStream), {message: errorMessage}); 479 | }); 480 | 481 | test('.fileTypeStream() method - sampleSize option', async t => { 482 | const file = path.join(__dirname, 'fixture', 'fixture.ogm'); 483 | let stream = await fileTypeStream(fs.createReadStream(file), {sampleSize: 30}); 484 | t.is(typeof (stream.fileType), 'undefined', 'file-type cannot be determined with a sampleSize of 30'); 485 | 486 | stream = await fileTypeStream(fs.createReadStream(file), {sampleSize: 4100}); 487 | t.is(typeof (stream.fileType), 'object', 'file-type can be determined with a sampleSize of 4100'); 488 | t.is(stream.fileType.mime, 'video/ogg'); 489 | }); 490 | 491 | test('.fileTypeFromStream() method - be able to abort operation', async t => { 492 | const bufferA = new Uint8Array([0, 1, 0, 1]); 493 | class MyStream extends stream.Readable { 494 | _read() { 495 | setTimeout(() => { 496 | this.push(bufferA); 497 | this.push(null); 498 | }, 500); 499 | } 500 | } 501 | 502 | const shortStream = new MyStream(); 503 | const abortController = new AbortController(); 504 | const parser = new FileTypeParser({signal: abortController.signal}); 505 | const promiseFileType = parser.fromStream(shortStream); 506 | abortController.abort(); // Abort asynchronous operation: reading from shortStream 507 | const error = await t.throwsAsync(promiseFileType); 508 | t.true(error instanceof strtok3.AbortError, 'Expect error te be an instanceof AbortError'); 509 | }); 510 | 511 | test('supportedExtensions.has', t => { 512 | t.true(supportedExtensions.has('jpg')); 513 | t.false(supportedExtensions.has('blah')); 514 | }); 515 | 516 | test('supportedMimeTypes.has', t => { 517 | t.true(supportedMimeTypes.has('video/mpeg')); 518 | t.false(supportedMimeTypes.has('video/blah')); 519 | }); 520 | 521 | test('validate the input argument type', async t => { 522 | await t.throwsAsync(fileTypeFromBuffer('x'), { 523 | message: /Expected the `input` argument to be of type `Uint8Array`/, 524 | }); 525 | 526 | await t.notThrowsAsync(fileTypeFromBuffer(new Uint8Array())); 527 | 528 | await t.notThrowsAsync(fileTypeFromBuffer(new ArrayBuffer())); 529 | }); 530 | 531 | test('validate the repo has all extensions and mimes in sync', t => { 532 | // File: core.js (base truth) 533 | function readIndexJS() { 534 | const core = fs.readFileSync('core.js', {encoding: 'utf8'}); 535 | const extensionArray = core.match(/(?<=ext:\s')(.*)(?=',)/g); 536 | const mimeArray = core.match(/(?<=mime:\s')(.*)(?=')/g); 537 | const extensions = new Set(extensionArray); 538 | const mimes = new Set(mimeArray); 539 | 540 | return { 541 | exts: extensions, 542 | mimes, 543 | }; 544 | } 545 | 546 | // File: package.json 547 | function readPackageJSON() { 548 | const packageJson = fs.readFileSync('package.json', {encoding: 'utf8'}); 549 | const {keywords} = JSON.parse(packageJson); 550 | 551 | const allowedExtras = new Set([ 552 | 'mime', 553 | 'file', 554 | 'type', 555 | 'magic', 556 | 'archive', 557 | 'image', 558 | 'img', 559 | 'pic', 560 | 'picture', 561 | 'flash', 562 | 'photo', 563 | 'video', 564 | 'detect', 565 | 'check', 566 | 'is', 567 | 'exif', 568 | 'binary', 569 | 'buffer', 570 | 'uint8array', 571 | 'webassembly', 572 | ]); 573 | 574 | const extensionArray = keywords.filter(keyword => !allowedExtras.has(keyword)); 575 | return extensionArray; 576 | } 577 | 578 | // File: readme.md 579 | function readReadmeMD() { 580 | const index = fs.readFileSync('readme.md', {encoding: 'utf8'}); 581 | const extensionArray = index.match(/(?<=-\s\[`)(.*)(?=`)/g); 582 | return extensionArray; 583 | } 584 | 585 | // Helpers 586 | // Find extensions/mimes that are defined twice in a file 587 | function findDuplicates(input) { 588 | // TODO: Fix this. 589 | // eslint-disable-next-line unicorn/no-array-reduce 590 | return input.reduce((accumulator, element, index, array) => { 591 | if (array.indexOf(element) !== index && !accumulator.includes(element)) { 592 | accumulator.push(element); 593 | } 594 | 595 | return accumulator; 596 | }, []); 597 | } 598 | 599 | // Find extensions/mimes that are in another file but not in `core.js` 600 | function findExtras(array, set) { 601 | return array.filter(element => !set.has(element)); 602 | } 603 | 604 | // Find extensions/mimes that are in `core.js` but missing from another file 605 | function findMissing(array, set) { 606 | const missing = []; 607 | const other = new Set(array); 608 | for (const elemenet of set) { 609 | if (!other.has(elemenet)) { 610 | missing.push(elemenet); 611 | } 612 | } 613 | 614 | return missing; 615 | } 616 | 617 | // Test runner 618 | function validate(found, baseTruth, filename, extensionOrMime) { 619 | const duplicates = findDuplicates(found); 620 | const extras = findExtras(found, baseTruth); 621 | const missing = findMissing(found, baseTruth); 622 | t.is(duplicates.length, 0, `Found duplicate ${extensionOrMime}: ${duplicates} in ${filename}.`); 623 | t.is(extras.length, 0, `Extra ${extensionOrMime}: ${extras} in ${filename}.`); 624 | t.is(missing.length, 0, `Missing ${extensionOrMime}: ${missing} in ${filename}.`); 625 | } 626 | 627 | // Get the base truth of extensions and mimes supported from core.js 628 | const {exts} = readIndexJS(); 629 | 630 | // Validate all extensions 631 | const filesWithExtensions = { 632 | 'supported.js': [...supportedExtensions], 633 | 'package.json': readPackageJSON(), 634 | 'readme.md': readReadmeMD(), 635 | }; 636 | 637 | for (const filename in filesWithExtensions) { 638 | if (filesWithExtensions[filename]) { 639 | const foundExtensions = filesWithExtensions[filename]; 640 | validate(foundExtensions, exts, filename, 'extensions'); 641 | } 642 | } 643 | }); 644 | 645 | class BufferedStream extends stream.Readable { 646 | constructor(buffer) { 647 | super(); 648 | this.push(buffer); 649 | this.push(null); 650 | } 651 | 652 | _read() {} 653 | } 654 | 655 | test('odd file sizes', async t => { 656 | const oddFileSizes = [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 255, 256, 257, 511, 512, 513]; 657 | 658 | for (const size of oddFileSizes) { 659 | const buffer = new Uint8Array(size); 660 | await t.notThrowsAsync(fileTypeFromBuffer(buffer), `fromBuffer: File size: ${size} bytes`); 661 | } 662 | 663 | for (const size of oddFileSizes) { 664 | const buffer = new Uint8Array(size); 665 | const stream = new BufferedStream(buffer); 666 | await t.notThrowsAsync(fileTypeNodeFromStream(stream), `fromStream: File size: ${size} bytes`); 667 | } 668 | }); 669 | 670 | test('supported files types are listed alphabetically', async t => { 671 | const readme = await fs.promises.readFile('readme.md', {encoding: 'utf8'}); 672 | let currentNode = new ReadmeParser().parse(readme).firstChild; 673 | 674 | while (currentNode) { 675 | if (currentNode.type === 'heading' && currentNode.firstChild.literal === 'Supported file types') { 676 | // Header → List → First list item 677 | currentNode = currentNode.next.firstChild; 678 | break; 679 | } 680 | 681 | currentNode = currentNode.next; 682 | } 683 | 684 | let previousFileType; 685 | 686 | while (currentNode) { 687 | // List item → Paragraph → Link → Inline code → Text 688 | const currentFileType = currentNode.firstChild.firstChild.firstChild.literal; 689 | 690 | if (previousFileType) { 691 | t.true(currentFileType > previousFileType, `${currentFileType} should be listed before ${previousFileType}`); 692 | } 693 | 694 | previousFileType = currentFileType; 695 | currentNode = currentNode.next; 696 | } 697 | }); 698 | 699 | // TODO: Replace with `Set.symmetricDifference` when targeting Node.js 22. 700 | function symmetricDifference(setA, setB) { 701 | const diff = new Set(); 702 | for (const item of setA) { 703 | if (!setB.has(item)) { 704 | diff.add(item); 705 | } 706 | } 707 | 708 | for (const item of setB) { 709 | if (!setA.has(item)) { 710 | diff.add(item); 711 | } 712 | } 713 | 714 | return diff; 715 | } 716 | 717 | test('implemented MIME types and extensions match the list of supported ones', async t => { 718 | const mimeTypesWithoutUnitTest = [ 719 | 'application/vnd.ms-asf', 720 | 'image/heic-sequence', 721 | ]; 722 | 723 | const implementedMimeTypes = new Set(mimeTypesWithoutUnitTest); 724 | const implementedExtensions = new Set(); 725 | 726 | for (const {path} of getFixtures()) { 727 | const fileType = await fileTypeFromFile(path); 728 | if (fileType) { 729 | implementedMimeTypes.add(fileType.mime); 730 | implementedExtensions.add(fileType.ext); 731 | } 732 | } 733 | 734 | const differencesInMimeTypes = symmetricDifference(supportedMimeTypes, implementedMimeTypes); 735 | 736 | for (const difference of differencesInMimeTypes) { 737 | if (implementedMimeTypes.has(difference)) { 738 | t.fail(`MIME-type ${difference} is implemented, but not declared as a supported MIME-type`); 739 | } else { 740 | t.fail(`MIME-type ${difference} declared as a supported MIME-type, but not found as an implemented MIME-type`); 741 | } 742 | } 743 | 744 | t.is(differencesInMimeTypes.size, 0); 745 | 746 | const differencesInExtensions = symmetricDifference(supportedExtensions, implementedExtensions); 747 | for (const difference of differencesInExtensions) { 748 | if (implementedMimeTypes.has(difference)) { 749 | t.fail(`Extension ${difference} is implemented, but not declared as a supported extension`); 750 | } else { 751 | t.fail(`Extension ${difference} declared as a supported extension, but not found as an implemented extension`); 752 | } 753 | } 754 | 755 | t.is(differencesInExtensions.size, 0); 756 | }); 757 | 758 | test('corrupt MKV throws', async t => { 759 | const filePath = path.join(__dirname, 'fixture/fixture-corrupt.mkv'); 760 | await t.throwsAsync(fileTypeFromFile(filePath), {message: /End-Of-Stream/}); 761 | }); 762 | 763 | // Create a custom detector for the just made up "unicorn" file type 764 | const unicornDetector = { 765 | id: 'mock.unicorn', 766 | async detect(tokenizer) { 767 | const unicornHeader = [85, 78, 73, 67, 79, 82, 78]; // "UNICORN" as decimal string 768 | const buffer = new Uint8Array(7); 769 | await tokenizer.peekBuffer(buffer, {length: unicornHeader.length, mayBeLess: true}); 770 | if (unicornHeader.every((value, index) => value === buffer[index])) { 771 | return {ext: 'unicorn', mime: 'application/unicorn'}; 772 | } 773 | 774 | return undefined; 775 | }, 776 | }; 777 | 778 | const mockPngDetector = { 779 | id: 'mock.png', 780 | detect: () => ({ext: 'mockPng', mime: 'image/mockPng'}), 781 | }; 782 | 783 | const tokenizerPositionChanger = { 784 | id: 'mock.dirtyTokenizer', 785 | detect(tokenizer) { 786 | const buffer = new Uint8Array(1); 787 | tokenizer.readBuffer(buffer, {length: 1, mayBeLess: true}); 788 | }, 789 | }; 790 | 791 | if (nodeMajorVersion >= nodeVersionSupportingByteBlobStream) { 792 | // Blob requires to stream to BYOB ReadableStream, requiring Node.js ≥ 20 793 | 794 | test('fileTypeFromBlob should detect custom file type "unicorn" using custom detectors', async t => { 795 | // Set up the "unicorn" file content 796 | const header = 'UNICORN FILE\n'; 797 | const blob = new Blob([header]); 798 | 799 | const customDetectors = [unicornDetector]; 800 | const parser = new FileTypeParser({customDetectors}); 801 | 802 | const result = await parser.fromBlob(blob); 803 | t.deepEqual(result, {ext: 'unicorn', mime: 'application/unicorn'}); 804 | }); 805 | 806 | test('fileTypeFromBlob should keep detecting default file types when no custom detector matches', async t => { 807 | const file = path.join(__dirname, 'fixture', 'fixture.png'); 808 | const chunk = fs.readFileSync(file); 809 | const blob = new Blob([chunk]); 810 | 811 | const customDetectors = [unicornDetector]; 812 | const parser = new FileTypeParser({customDetectors}); 813 | 814 | const result = await parser.fromBlob(blob); 815 | t.deepEqual(result, {ext: 'png', mime: 'image/png'}); 816 | }); 817 | 818 | test('fileTypeFromBlob should allow overriding default file type detectors', async t => { 819 | const file = path.join(__dirname, 'fixture', 'fixture.png'); 820 | const chunk = fs.readFileSync(file); 821 | const blob = new Blob([chunk]); 822 | 823 | const customDetectors = [mockPngDetector]; 824 | const parser = new FileTypeParser({customDetectors}); 825 | 826 | const result = await parser.fromBlob(blob); 827 | t.deepEqual(result, {ext: 'mockPng', mime: 'image/mockPng'}); 828 | }); 829 | } 830 | 831 | test('fileTypeFromBuffer should detect custom file type "unicorn" using custom detectors', async t => { 832 | const header = 'UNICORN FILE\n'; 833 | const uint8ArrayContent = new TextEncoder().encode(header); 834 | 835 | const customDetectors = [unicornDetector]; 836 | const parser = new FileTypeParser({customDetectors}); 837 | 838 | const result = await parser.fromBuffer(uint8ArrayContent); 839 | t.deepEqual(result, {ext: 'unicorn', mime: 'application/unicorn'}); 840 | }); 841 | 842 | test('fileTypeFromBuffer should keep detecting default file types when no custom detector matches', async t => { 843 | const file = path.join(__dirname, 'fixture', 'fixture.png'); 844 | const uint8ArrayContent = fs.readFileSync(file); 845 | 846 | const customDetectors = [unicornDetector]; 847 | const parser = new FileTypeParser({customDetectors}); 848 | 849 | const result = await parser.fromBuffer(uint8ArrayContent); 850 | t.deepEqual(result, {ext: 'png', mime: 'image/png'}); 851 | }); 852 | 853 | test('fileTypeFromBuffer should allow overriding default file type detectors', async t => { 854 | const file = path.join(__dirname, 'fixture', 'fixture.png'); 855 | const uint8ArrayContent = fs.readFileSync(file); 856 | 857 | const customDetectors = [mockPngDetector]; 858 | const parser = new FileTypeParser({customDetectors}); 859 | 860 | const result = await parser.fromBuffer(uint8ArrayContent); 861 | t.deepEqual(result, {ext: 'mockPng', mime: 'image/mockPng'}); 862 | }); 863 | 864 | class CustomReadableStream extends stream.Readable { 865 | _read(_size) { 866 | this.push('UNICORN'); 867 | } 868 | } 869 | test('fileTypeFromStream should detect custom file type "unicorn" using custom detectors', async t => { 870 | const readableStream = new CustomReadableStream(); 871 | 872 | const customDetectors = [unicornDetector]; 873 | const parser = new FileTypeParser({customDetectors}); 874 | 875 | const result = await parser.fromStream(readableStream); 876 | t.deepEqual(result, {ext: 'unicorn', mime: 'application/unicorn'}); 877 | }); 878 | 879 | test('fileTypeFromStream should keep detecting default file types when no custom detector matches', async t => { 880 | const file = path.join(__dirname, 'fixture', 'fixture.png'); 881 | const readableStream = fs.createReadStream(file); 882 | 883 | const customDetectors = [unicornDetector]; 884 | const parser = new FileTypeParser({customDetectors}); 885 | 886 | const result = await parser.fromStream(readableStream); 887 | t.deepEqual(result, {ext: 'png', mime: 'image/png'}); 888 | }); 889 | 890 | test('fileTypeFromStream should allow overriding default file type detectors', async t => { 891 | const file = path.join(__dirname, 'fixture', 'fixture.png'); 892 | const readableStream = fs.createReadStream(file); 893 | 894 | const customDetectors = [mockPngDetector]; 895 | const parser = new FileTypeParser({customDetectors}); 896 | 897 | const result = await parser.fromStream(readableStream); 898 | t.deepEqual(result, {ext: 'mockPng', mime: 'image/mockPng'}); 899 | }); 900 | 901 | test('fileTypeFromFile should detect custom file type "unicorn" using custom detectors', async t => { 902 | const file = path.join(__dirname, 'fixture', 'fixture.unicorn'); 903 | 904 | const customDetectors = [unicornDetector]; 905 | 906 | const result = await fileTypeFromFile(file, {customDetectors}); 907 | t.deepEqual(result, {ext: 'unicorn', mime: 'application/unicorn'}); 908 | }); 909 | 910 | test('fileTypeFromFile should keep detecting default file types when no custom detector matches', async t => { 911 | const file = path.join(__dirname, 'fixture', 'fixture.png'); 912 | 913 | const customDetectors = [unicornDetector]; 914 | 915 | const result = await fileTypeFromFile(file, {customDetectors}); 916 | t.deepEqual(result, {ext: 'png', mime: 'image/png'}); 917 | }); 918 | 919 | test('fileTypeFromFile should allow overriding default file type detectors', async t => { 920 | const file = path.join(__dirname, 'fixture', 'fixture.png'); 921 | 922 | const customDetectors = [mockPngDetector]; 923 | 924 | const result = await fileTypeFromFile(file, {customDetectors}); 925 | t.deepEqual(result, {ext: 'mockPng', mime: 'image/mockPng'}); 926 | }); 927 | 928 | test('fileTypeFromTokenizer should return undefined when a custom detector changes the tokenizer position and does not return a file type', async t => { 929 | const header = 'UNICORN FILE\n'; 930 | const uint8ArrayContent = new TextEncoder().encode(header); 931 | 932 | // Include the unicornDetector here to verify it's not used after the tokenizer.position changed 933 | const customDetectors = [tokenizerPositionChanger, unicornDetector]; 934 | const parser = new FileTypeParser({customDetectors}); 935 | 936 | const result = await parser.fromTokenizer(strtok3.fromBuffer(uint8ArrayContent)); 937 | t.is(result, undefined); 938 | }); 939 | 940 | test('should detect MPEG frame which is out of sync with the mpegOffsetTolerance option', async t => { 941 | const badOffset1Path = path.join(__dirname, 'fixture', 'fixture-bad-offset.mp3'); 942 | const badOffset10Path = path.join(__dirname, 'fixture', 'fixture-bad-offset-10.mp3'); 943 | 944 | let result = await fileTypeFromFile(badOffset1Path); 945 | t.is(result, undefined, 'does not detect an MP3 which 1 byte out-sync, with default value mpegOffsetTolerance=0'); 946 | 947 | result = await fileTypeFromFile(badOffset1Path, {mpegOffsetTolerance: 1}); 948 | t.deepEqual(result, {ext: 'mp3', mime: 'audio/mpeg'}, 'detect an MP3 which 1 byte out of sync'); 949 | 950 | result = await fileTypeFromFile(badOffset10Path); 951 | t.is(result, undefined, 'does not detect an MP3 which 10 bytes out of sync, with default value mpegOffsetTolerance=0'); 952 | 953 | result = await fileTypeFromFile(badOffset10Path, {mpegOffsetTolerance: 10}); 954 | t.deepEqual(result, {ext: 'mp3', mime: 'audio/mpeg'}, 'detect an MP3 which 1 byte out of sync'); 955 | }); 956 | -------------------------------------------------------------------------------- /type.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/node 2 | import process from 'node:process'; 3 | import {fileTypeFromFile} from './index.js'; 4 | 5 | const [file] = process.argv.slice(2); 6 | 7 | if (!file) { 8 | console.error('Expected path of the file to examine'); 9 | process.exit(); 10 | } 11 | 12 | const fileType = await fileTypeFromFile(file); 13 | 14 | if (fileType) { 15 | console.log(`MIME-type: ${fileType.mime}`); 16 | console.log(`Extension: ${fileType.ext}`); 17 | } else { 18 | console.log('Could not determine file type'); 19 | } 20 | -------------------------------------------------------------------------------- /util.js: -------------------------------------------------------------------------------- 1 | import {StringType} from 'token-types'; 2 | 3 | export function stringToBytes(string) { 4 | return [...string].map(character => character.charCodeAt(0)); // eslint-disable-line unicorn/prefer-code-point 5 | } 6 | 7 | /** 8 | Checks whether the TAR checksum is valid. 9 | 10 | @param {Uint8Array} arrayBuffer - The TAR header `[offset ... offset + 512]`. 11 | @param {number} offset - TAR header offset. 12 | @returns {boolean} `true` if the TAR checksum is valid, otherwise `false`. 13 | */ 14 | export function tarHeaderChecksumMatches(arrayBuffer, offset = 0) { 15 | const readSum = Number.parseInt(new StringType(6).get(arrayBuffer, 148).replace(/\0.*$/, '').trim(), 8); // Read sum in header 16 | if (Number.isNaN(readSum)) { 17 | return false; 18 | } 19 | 20 | let sum = 8 * 0x20; // Initialize signed bit sum 21 | 22 | for (let index = offset; index < offset + 148; index++) { 23 | sum += arrayBuffer[index]; 24 | } 25 | 26 | for (let index = offset + 156; index < offset + 512; index++) { 27 | sum += arrayBuffer[index]; 28 | } 29 | 30 | return readSum === sum; 31 | } 32 | 33 | /** 34 | ID3 UINT32 sync-safe tokenizer token. 35 | 28 bits (representing up to 256MB) integer, the msb is 0 to avoid "false syncsignals". 36 | */ 37 | export const uint32SyncSafeToken = { 38 | get: (buffer, offset) => (buffer[offset + 3] & 0x7F) | ((buffer[offset + 2]) << 7) | ((buffer[offset + 1]) << 14) | ((buffer[offset]) << 21), 39 | len: 4, 40 | }; 41 | --------------------------------------------------------------------------------