Skip to content

Commit 722e37b

Browse files
authored
fix: refactor use natives to drop md5-file and multistream (#888)
Signed-off-by: ferhat elmas <elmas.ferhat@gmail.com>
1 parent 52ed538 commit 722e37b

File tree

3 files changed

+30
-52
lines changed

3 files changed

+30
-52
lines changed

package-lock.json

Lines changed: 0 additions & 37 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@
7979
"json-bigint": "^1.0.0",
8080
"knex": "^3.1.0",
8181
"lru-cache": "^10.2.0",
82-
"md5-file": "^5.0.0",
83-
"multistream": "^4.1.0",
8482
"object-sizeof": "^2.6.4",
8583
"pg": "^8.12.0",
8684
"pg-boss": "github:supabase/pg-boss#feat/exactly_once",
@@ -102,7 +100,6 @@
102100
"@types/jest": "^29.2.1",
103101
"@types/js-yaml": "^4.0.5",
104102
"@types/json-bigint": "^1.0.4",
105-
"@types/multistream": "^4.1.3",
106103
"@types/mustache": "^4.2.2",
107104
"@types/node": "^22.18.8",
108105
"@types/pg": "^8.6.4",

src/storage/backend/file.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { ERRORS, StorageBackendError } from '@internal/errors'
2-
import { randomUUID } from 'crypto'
2+
import { createHash, randomUUID } from 'crypto'
33
import fs from 'fs-extra'
44
import fsExtra from 'fs-extra'
55
import * as xattr from 'fs-xattr'
6-
import fileChecksum from 'md5-file'
7-
import MultiStream from 'multistream'
86
import path from 'path'
97
import stream from 'stream'
108
import { promisify } from 'util'
@@ -384,7 +382,7 @@ export class FileBackend implements StorageBackendAdapter {
384382

385383
await pipeline(body, writeStream)
386384

387-
const etag = await fileChecksum(partPath)
385+
const etag = await this.computeMd5(partPath)
388386

389387
const platform = process.platform == 'darwin' ? 'darwin' : 'linux'
390388
await this.setMetadataAttr(partPath, METADATA_ATTR_KEYS[platform]['etag'], etag)
@@ -432,11 +430,7 @@ export class FileBackend implements StorageBackendAdapter {
432430
const finalParts = await Promise.all(partsByEtags)
433431
finalParts.sort((a, b) => parseInt(a.split('-')[1]) - parseInt(b.split('-')[1]))
434432

435-
const fileStreams = finalParts.map((partPath) => {
436-
return fs.createReadStream(partPath)
437-
})
438-
439-
const multistream = new MultiStream(fileStreams)
433+
const multipartStream = this.mergePartStreams(finalParts)
440434
const metadataContent = await fsExtra.readFile(
441435
this.resolveSecurePath(
442436
path.join(
@@ -456,7 +450,7 @@ export class FileBackend implements StorageBackendAdapter {
456450
bucketName,
457451
key,
458452
version,
459-
multistream,
453+
multipartStream,
460454
metadata.contentType,
461455
metadata.cacheControl
462456
)
@@ -524,7 +518,7 @@ export class FileBackend implements StorageBackendAdapter {
524518
const writePart = fs.createWriteStream(partFilePath)
525519
await pipeline(partStream, writePart)
526520

527-
const etag = await fileChecksum(partFilePath)
521+
const etag = await this.computeMd5(partFilePath)
528522
await this.setMetadataAttr(partFilePath, METADATA_ATTR_KEYS[platform]['etag'], etag)
529523

530524
const fileStat = await fs.lstat(partFilePath)
@@ -535,6 +529,30 @@ export class FileBackend implements StorageBackendAdapter {
535529
}
536530
}
537531

532+
private mergePartStreams(partPaths: string[]): stream.Readable {
533+
return stream.Readable.from(this.iteratePartChunks(partPaths))
534+
}
535+
536+
private async *iteratePartChunks(partPaths: string[]): AsyncGenerator<Buffer> {
537+
for (const partPath of partPaths) {
538+
const partStream = fs.createReadStream(partPath)
539+
for await (const chunk of partStream) {
540+
yield chunk as Buffer
541+
}
542+
}
543+
}
544+
545+
private async computeMd5(filePath: string): Promise<string> {
546+
const hash = createHash('md5')
547+
const readStream = fs.createReadStream(filePath)
548+
549+
for await (const chunk of readStream) {
550+
hash.update(chunk)
551+
}
552+
553+
return hash.digest('hex')
554+
}
555+
538556
/**
539557
* Returns a private url that can only be accessed internally by the system
540558
* @param bucket
@@ -676,7 +694,7 @@ export class FileBackend implements StorageBackendAdapter {
676694

677695
private async etag(file: string, stats: fs.Stats): Promise<string> {
678696
if (this.etagAlgorithm === 'md5') {
679-
const checksum = await fileChecksum(file)
697+
const checksum = await this.computeMd5(file)
680698
return `"${checksum}"`
681699
} else if (this.etagAlgorithm === 'mtime') {
682700
return `"${stats.mtimeMs.toString(16)}-${stats.size.toString(16)}"`

0 commit comments

Comments
 (0)