Skip to content

Commit 2dd0966

Browse files
committed
clean up handling of missing brotli/zstd in old node versions
1 parent a6c9c3f commit 2dd0966

4 files changed

Lines changed: 51 additions & 24 deletions

File tree

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
3434
"license": "MIT",
3535
"devDependencies": {
36-
"@types/node": "^22.15.29",
36+
"@types/node": "^24.5.2",
3737
"tap": "^21.1.0",
3838
"tshy": "^3.0.2",
3939
"typedoc": "^0.28.1"

src/index.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ const _superWrite = Symbol('_superWrite')
2020
export class ZlibError extends Error {
2121
code?: string
2222
errno?: number
23-
constructor(err: NodeJS.ErrnoException | Error) {
24-
super('zlib: ' + err.message)
23+
constructor(err: NodeJS.ErrnoException | Error, origin?: Function) {
24+
super('zlib: ' + err.message, { cause: err })
2525
this.code = (err as NodeJS.ErrnoException).code
2626
this.errno = (err as NodeJS.ErrnoException).errno
2727
/* c8 ignore next */
2828
if (!this.code) this.code = 'ZLIB_ERROR'
2929

3030
this.message = 'zlib: ' + err.message
31-
Error.captureStackTrace(this, this.constructor)
31+
Error.captureStackTrace(this, origin ?? this.constructor)
3232
}
3333

3434
get name() {
@@ -51,6 +51,18 @@ export type ZlibBaseOptions = Minipass.Options<Minipass.ContiguousData> & {
5151
finishFlush?: number
5252
fullFlushFlag?: number
5353
}
54+
55+
export type ZlibHandle =
56+
| realZlib.Gzip
57+
| realZlib.Gunzip
58+
| realZlib.Deflate
59+
| realZlib.Inflate
60+
| realZlib.DeflateRaw
61+
| realZlib.InflateRaw
62+
| realZlib.BrotliCompress
63+
| realZlib.BrotliDecompress
64+
| realZlib.ZstdCompress
65+
| realZlib.ZstdDecompress
5466
export type ZlibMode =
5567
| 'Gzip'
5668
| 'Gunzip'
@@ -59,13 +71,6 @@ export type ZlibMode =
5971
| 'DeflateRaw'
6072
| 'InflateRaw'
6173
| 'Unzip'
62-
export type ZlibHandle =
63-
| realZlib.Gzip
64-
| realZlib.Gunzip
65-
| realZlib.Deflate
66-
| realZlib.Inflate
67-
| realZlib.DeflateRaw
68-
| realZlib.InflateRaw
6974
export type BrotliMode = 'BrotliCompress' | 'BrotliDecompress'
7075
export type ZstdMode = 'ZstdCompress' | 'ZstdDecompress'
7176

@@ -103,14 +108,19 @@ abstract class ZlibBase extends Minipass<Buffer, ChunkWithFlushFlag> {
103108
this.#fullFlushFlag = opts.fullFlushFlag ?? 0
104109
/* c8 ignore stop */
105110

111+
//@ts-ignore
112+
if (typeof realZlib[mode] !== 'function') {
113+
throw new TypeError('Compression method not supported: ' + mode)
114+
}
115+
106116
// this will throw if any options are invalid for the class selected
107117
try {
108118
// @types/node doesn't know that it exports the classes, but they're there
109119
//@ts-ignore
110120
this.#handle = new realZlib[mode](opts)
111121
} catch (er) {
112122
// make sure that all errors get decorated properly
113-
throw new ZlibError(er as NodeJS.ErrnoException)
123+
throw new ZlibError(er as NodeJS.ErrnoException, this.constructor)
114124
}
115125

116126
this.#onError = err => {
@@ -245,7 +255,7 @@ abstract class ZlibBase extends Minipass<Buffer, ChunkWithFlushFlag> {
245255
// or if we do, put Buffer.concat() back before we emit error
246256
// Error events call into user code, which may call Buffer.concat()
247257
passthroughBufferConcat(false)
248-
this.#onError(new ZlibError(err as NodeJS.ErrnoException))
258+
this.#onError(new ZlibError(err as NodeJS.ErrnoException, this.write))
249259
} finally {
250260
if (this.#handle) {
251261
// Core zlib resets `_handle` to null after attempting to close the
@@ -263,7 +273,7 @@ abstract class ZlibBase extends Minipass<Buffer, ChunkWithFlushFlag> {
263273
}
264274

265275
if (this.#handle)
266-
this.#handle.on('error', er => this.#onError(new ZlibError(er)))
276+
this.#handle.on('error', er => this.#onError(new ZlibError(er, this.write)))
267277

268278
let writeReturn
269279
if (result) {
@@ -417,7 +427,7 @@ export class Unzip extends Zlib {
417427
}
418428
}
419429

420-
export class Brotli extends ZlibBase {
430+
class Brotli extends ZlibBase {
421431
constructor(opts: ZlibOptions, mode: BrotliMode) {
422432
opts = opts || {}
423433

@@ -441,7 +451,7 @@ export class BrotliDecompress extends Brotli {
441451
}
442452
}
443453

444-
export class Zstd extends ZlibBase {
454+
class Zstd extends ZlibBase {
445455
constructor(opts: ZlibOptions, mode: ZstdMode) {
446456
opts = opts || {}
447457

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import t from 'tap'
2+
3+
t.test('pretend we do not have zstd', async t => {
4+
const miniz = await t.mockImport('../dist/esm/index.js', {
5+
'node:zlib': t.createMock(await import('node:zlib'), {
6+
BrotliCompress: undefined,
7+
BrotliDecompress: undefined,
8+
}),
9+
})
10+
11+
t.throws(() => {
12+
new miniz.BrotliCompress({})
13+
}, {
14+
name: 'TypeError',
15+
message: 'Compression method not supported: BrotliCompress',
16+
})
17+
})

0 commit comments

Comments
 (0)