Skip to content

Commit 4856594

Browse files
committed
Add support for reading from a WebStreams
- Stream Blob via a WebStreams, instead of buffering the full content - Update strtok3 to v7.0.0
1 parent 37233b1 commit 4856594

10 files changed

+43
-73
lines changed

.github/workflows/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
node-version:
13+
- 22
1314
- 20
14-
- 18
1515
steps:
1616
- uses: actions/checkout@v4
1717
- uses: actions/setup-node@v4

browser.d.ts

-29
This file was deleted.

browser.js

-15
This file was deleted.

core.d.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import type {Readable as ReadableStream} from 'node:stream';
1+
/**
2+
* Typings for primary entry point, Node.js specific typings can be found in index.d.ts
3+
*/
4+
5+
import type {Readable as NodeReadableStream} from 'node:stream';
6+
import type {ReadableStream as WebReadableStream} from 'node:stream/web';
27
import type {ITokenizer} from 'strtok3';
38

49
export type FileExtension =
@@ -318,7 +323,7 @@ export type FileTypeResult = {
318323
readonly mime: MimeType;
319324
};
320325

321-
export type ReadableStreamWithFileType = ReadableStream & {
326+
export type ReadableStreamWithFileType = NodeReadableStream & {
322327
readonly fileType?: FileTypeResult;
323328
};
324329

@@ -339,10 +344,10 @@ Detect the file type of a Node.js [readable stream](https://nodejs.org/api/strea
339344
340345
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.
341346
342-
@param stream - A readable stream representing file data.
347+
@param stream - A Node.js Readable stream or Web API Readable Stream representing file data.
343348
@returns The detected file type, or `undefined` when there is no match.
344349
*/
345-
export function fileTypeFromStream(stream: ReadableStream): Promise<FileTypeResult | undefined>;
350+
export function fileTypeFromStream(stream: NodeReadableStream | WebReadableStream): Promise<FileTypeResult | undefined>;
346351

347352
/**
348353
Detect the file type from an [`ITokenizer`](https://github.com/Borewit/strtok3#tokenizer) source.
@@ -420,7 +425,7 @@ if (stream2.fileType?.mime === 'image/jpeg') {
420425
}
421426
```
422427
*/
423-
export function fileTypeStream(readableStream: ReadableStream, options?: StreamOptions): Promise<ReadableStreamWithFileType>;
428+
export function fileTypeStream(readableStream: NodeReadableStream, options?: StreamOptions): Promise<ReadableStreamWithFileType>;
424429

425430
/**
426431
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).
@@ -511,7 +516,7 @@ export declare class FileTypeParser {
511516
/**
512517
Works the same way as {@link fileTypeFromStream}, additionally taking into account custom detectors (if any were provided to the constructor).
513518
*/
514-
fromStream(stream: ReadableStream): Promise<FileTypeResult | undefined>;
519+
fromStream(stream: NodeReadableStream): Promise<FileTypeResult | undefined>;
515520

516521
/**
517522
Works the same way as {@link fileTypeFromTokenizer}, additionally taking into account custom detectors (if any were provided to the constructor).
@@ -526,5 +531,5 @@ export declare class FileTypeParser {
526531
/**
527532
Works the same way as {@link fileTypeStream}, additionally taking into account custom detectors (if any were provided to the constructor).
528533
*/
529-
toDetectionStream(readableStream: ReadableStream, options?: StreamOptions): Promise<FileTypeResult | undefined>;
534+
toDetectionStream(readableStream: NodeReadableStream, options?: StreamOptions): Promise<FileTypeResult | undefined>;
530535
}

core.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
/**
2+
* Primary entry point, Node.js specific entry point is index.js
3+
*/
4+
15
import {Buffer} from 'node:buffer';
6+
import {ReadableStream as WebReadableStream} from 'node:stream/web';
27
import * as Token from 'token-types';
38
import * as strtok3 from 'strtok3/core';
49
import {
@@ -88,12 +93,11 @@ export class FileTypeParser {
8893
}
8994

9095
async fromBlob(blob) {
91-
const buffer = await blob.arrayBuffer();
92-
return this.fromBuffer(new Uint8Array(buffer));
96+
return this.fromStream(blob.stream());
9397
}
9498

9599
async fromStream(stream) {
96-
const tokenizer = await strtok3.fromStream(stream);
100+
const tokenizer = await (stream instanceof WebReadableStream ? strtok3.fromWebStream(stream) : strtok3.fromStream(stream));
97101
try {
98102
return await this.fromTokenizer(tokenizer);
99103
} finally {
@@ -576,7 +580,7 @@ export class FileTypeParser {
576580
) {
577581
// They all can have MIME `video/mp4` except `application/mp4` special-case which is hard to detect.
578582
// For some cases, we're specific, everything else falls to `video/mp4` with `mp4` extension.
579-
const brandMajor = this.buffer.toString('binary', 8, 12).replace('\0', ' ').trim();
583+
const brandMajor = this.buffer.toString('latin1', 8, 12).replace('\0', ' ').trim();
580584
switch (brandMajor) {
581585
case 'avif':
582586
case 'avis':
@@ -1059,7 +1063,7 @@ export class FileTypeParser {
10591063
}
10601064

10611065
if (this.checkString('AC')) {
1062-
const version = this.buffer.toString('binary', 2, 6);
1066+
const version = this.buffer.toString('latin1', 2, 6);
10631067
if (version.match('^d*') && version >= 1000 && version <= 1050) {
10641068
return {
10651069
ext: 'dwg',
@@ -1126,7 +1130,7 @@ export class FileTypeParser {
11261130
async function readChunkHeader() {
11271131
return {
11281132
length: await tokenizer.readToken(Token.INT32_BE),
1129-
type: await tokenizer.readToken(new Token.StringType(4, 'binary')),
1133+
type: await tokenizer.readToken(new Token.StringType(4, 'latin1')),
11301134
};
11311135
}
11321136

index.d.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
import type {FileTypeResult} from './core.js';
2-
31
/**
4-
Detect the file type of a file path.
2+
* Typings for Node.js specific entry point
3+
*/
54

6-
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.
5+
import type {FileTypeResult} from './core.js';
76

8-
@param path - The file path to parse.
9-
@returns The detected file type and MIME type or `undefined` when there is no match.
10-
*/
7+
/**
8+
* Detect the file type of a file path.
9+
*
10+
* 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.
11+
*
12+
* @param path
13+
* @returns The detected file type and MIME type or `undefined` when there is no match.
14+
*/
1115
export function fileTypeFromFile(path: string): Promise<FileTypeResult | undefined>;
1216

1317
export * from './core.js';

index.js

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* Node.js specific entry point
3+
*/
4+
15
import * as strtok3 from 'strtok3';
26
import {FileTypeParser} from './core.js';
37

index.test-d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {createReadStream} from 'node:fs';
33
import {expectType} from 'tsd';
44
import {
55
type FileTypeResult as FileTypeResultBrowser,
6-
} from './browser.js';
6+
} from './core.js';
77
import {
88
fileTypeFromBlob,
99
fileTypeFromBuffer,

package.json

+3-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"exports": {
1515
".": {
1616
"node": "./index.js",
17-
"default": "./browser.js"
17+
"default": "./core.js"
1818
},
1919
"./core": "./core.js"
2020
},
@@ -28,8 +28,6 @@
2828
"files": [
2929
"index.js",
3030
"index.d.ts",
31-
"browser.js",
32-
"browser.d.ts",
3331
"core.js",
3432
"core.d.ts",
3533
"supported.js",
@@ -210,9 +208,8 @@
210208
"fbx"
211209
],
212210
"dependencies": {
213-
"readable-web-to-node-stream": "^3.0.2",
214-
"strtok3": "^7.0.0",
215-
"token-types": "^5.0.1"
211+
"strtok3": "^7.1.0",
212+
"token-types": "^6.0.0"
216213
},
217214
"devDependencies": {
218215
"@tokenizer/token": "^0.3.0",

readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ The file path to parse.
147147

148148
### fileTypeFromStream(stream)
149149

150-
Detect the file type of a Node.js [readable stream](https://nodejs.org/api/stream.html#stream_class_stream_readable).
150+
Detect the file type of a [Node.js readable stream](https://nodejs.org/api/stream.html#stream_class_stream_readable) or a [Web API ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream).
151151

152152
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.
153153

0 commit comments

Comments
 (0)