Skip to content

Commit

Permalink
Fixed stream-file-type issue.
Browse files Browse the repository at this point in the history
For more info, see LinusU/stream-file-type#6
  • Loading branch information
KostyaTretyak committed Jul 30, 2024
1 parent 144d9ab commit 57268ac
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 66 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ts-stack/multer",
"version": "1.0.0-beta.2",
"version": "1.0.0-beta.3",
"type": "module",
"description": "Multer is a node.js parser for handling `multipart/form-data`, which is primarily used for uploading files.",
"license": "MIT",
Expand All @@ -26,7 +26,7 @@
"@ts-stack/type-is": "^1.0.1",
"append-field": "^2.0.0",
"bytes": "^3.1.2",
"stream-file-type": "^0.6.1",
"file-type": "^19.3.0",
"tempy": "^3.1.0"
},
"devDependencies": {
Expand Down
11 changes: 8 additions & 3 deletions src/read-body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { promisify } from 'node:util';
import { createWriteStream } from 'node:fs';
import { Busboy } from '@fastify/busboy';
import { temporaryFile } from 'tempy';
import FileType from 'stream-file-type';
import { IncomingHttpHeaders } from 'node:http';

import { FileType } from './stream-file-type.js';
import { MulterError } from './error.js';
import { MulterFile, LimitGuard, NormalizedLimits } from './types.js';
import { onFinished as preOnFinished } from './on-finished.js';
Expand Down Expand Up @@ -83,7 +83,7 @@ function collectFiles(busboy: Busboy, limits: NormalizedLimits, limitGuard: Limi
file.size = target.bytesWritten;

const fileType = await detector.fileTypePromise();
file.detectedMimeType = fileType ? fileType.mime : null;
file.detectedMimeType = fileType?.mime ?? null;
file.detectedFileExtension = fileType ? `.${fileType.ext}` : '';

return file;
Expand All @@ -97,7 +97,12 @@ function collectFiles(busboy: Busboy, limits: NormalizedLimits, limitGuard: Limi
});
}

export async function readBody(req: Readable, headers: IncomingHttpHeaders, limits: NormalizedLimits, limitGuard: LimitGuard) {
export async function readBody(
req: Readable,
headers: IncomingHttpHeaders,
limits: NormalizedLimits,
limitGuard: LimitGuard,
) {
const busboy = new Busboy({ headers: headers as any, limits: limits });

const promiseFields = collectFields(busboy, limits);
Expand Down
52 changes: 52 additions & 0 deletions src/stream-file-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { PassThrough, Transform } from 'node:stream';
import { fileTypeFromStream } from 'file-type';

import { AnyFn } from './types.js';

export class FileType extends Transform {
#stream: PassThrough | null;
#result: Promise<{ ext: string; mime: string } | null>;
#transformCalled: boolean;

constructor() {
super();
this.#stream = new PassThrough();

this.#result = fileTypeFromStream(this.#stream).then(
(value) => {
this.#stream = null;
return value || null;
},
(err) => {
this.#stream = null;
return null;
},
);
}

fileTypePromise() {
return this.#result;
}

override _transform(chunk: any, _: any, cb: AnyFn) {
this.#transformCalled = true;
if (this.#stream != null) {
this.#stream.write(chunk);
}

cb(null, chunk);
}

override _flush(cb: AnyFn) {
if (this.#transformCalled) {
this.#result.finally(() => this.finish(cb));
} else {
this.finish(cb);
}
}

protected finish(cb: AnyFn) {
cb(null);
this.#stream?.end();
}
}
87 changes: 26 additions & 61 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1518,14 +1518,14 @@ file-entry-cache@^8.0.0:
dependencies:
flat-cache "^4.0.0"

file-type@^16.0.0:
version "16.5.4"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.4.tgz#474fb4f704bee427681f98dd390058a172a6c2fd"
integrity sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==
file-type@^19.3.0:
version "19.3.0"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-19.3.0.tgz#7b5989c4af05e4b02c553f29a6acca0508e9ea9b"
integrity sha512-mROwiKLZf/Kwa/2Rol+OOZQn1eyTkPB3ZTwC0ExY6OLFCbgxHYZvBm7xI77NvfZFMKBsmuXfmLJnD4eEftEhrA==
dependencies:
readable-web-to-node-stream "^3.0.0"
strtok3 "^6.2.4"
token-types "^4.1.1"
strtok3 "^8.0.0"
token-types "^6.0.0"
uint8array-extras "^1.3.0"

fill-range@^7.1.1:
version "7.1.1"
Expand Down Expand Up @@ -1747,7 +1747,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"

inherits@2, inherits@^2.0.3:
inherits@2:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
Expand Down Expand Up @@ -2534,10 +2534,10 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==

peek-readable@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72"
integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==
peek-readable@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.1.3.tgz#08993b35dd87502ae5e6028498663abed2dcc009"
integrity sha512-kCsc9HwH5RgVA3H3VqkWFyGQwsxUxLdiSX1d5nqAm7hnMFjNFX1VhBLmJoUY0hZNc8gmDNgBkLjfhiWPsziXWA==

picocolors@^1.0.0, picocolors@^1.0.1:
version "1.0.1"
Expand Down Expand Up @@ -2608,22 +2608,6 @@ react-is@^18.0.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e"
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==

readable-stream@^3.6.0:
version "3.6.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
util-deprecate "^1.0.1"

readable-web-to-node-stream@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb"
integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==
dependencies:
readable-stream "^3.6.0"

require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
Expand Down Expand Up @@ -2672,11 +2656,6 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"

safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==

semver@^6.3.0, semver@^6.3.1:
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
Expand Down Expand Up @@ -2739,13 +2718,6 @@ stack-utils@^2.0.3:
dependencies:
escape-string-regexp "^2.0.0"

stream-file-type@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/stream-file-type/-/stream-file-type-0.6.1.tgz#d8b8ac8736a0f2df7ca3e5718e28b6e8187f78fe"
integrity sha512-//KIXMQan4ow4gD//dfPu15nhH/sFdt41PzAOpD9EBFUBy/MtFjocTPO8v1dTOJnyi47TlPo6Qj+67sSE1lJKA==
dependencies:
file-type "^16.0.0"

string-length@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
Expand All @@ -2763,13 +2735,6 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
Expand All @@ -2792,13 +2757,13 @@ strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==

strtok3@^6.2.4:
version "6.3.0"
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0"
integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==
strtok3@^8.0.0:
version "8.0.1"
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-8.0.1.tgz#74088e62b2ba43b2f12256600c0225adbed90641"
integrity sha512-HNkTAnNWQj2YBzfTtoC5OQyu1QwPsMwiB7VyQmNvQKCrmEDSvFB857Vh97UY9InGLNRAB91sdS1ztifRo/3hdA==
dependencies:
"@tokenizer/token" "^0.3.0"
peek-readable "^4.1.0"
peek-readable "^5.1.3"

supports-color@^5.3.0:
version "5.5.0"
Expand Down Expand Up @@ -2877,10 +2842,10 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"

token-types@^4.1.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.1.tgz#0f897f03665846982806e138977dbe72d44df753"
integrity sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==
token-types@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.0.0.tgz#1ab26be1ef9c434853500c071acfe5c8dd6544a3"
integrity sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==
dependencies:
"@tokenizer/token" "^0.3.0"
ieee754 "^1.2.1"
Expand Down Expand Up @@ -2946,6 +2911,11 @@ typescript@^5.5.4:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba"
integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==

uint8array-extras@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/uint8array-extras/-/uint8array-extras-1.4.0.tgz#e42a678a6dd335ec2d21661333ed42f44ae7cc74"
integrity sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==

undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
Expand Down Expand Up @@ -2973,11 +2943,6 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"

util-deprecate@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==

v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
Expand Down

0 comments on commit 57268ac

Please sign in to comment.