Skip to content

Commit 096dc4d

Browse files
committed
fix: ensuring close event is emited after stream has ended
For node 18 combaitibility fixes isaacs#321
1 parent 9d71c56 commit 096dc4d

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

lib/parse.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const maxMetaEntrySize = 1024 * 1024
2828
const Entry = require('./read-entry.js')
2929
const Pax = require('./pax.js')
3030
const zlib = require('minizlib')
31+
const { nextTick } = require('process')
3132

3233
const gzipHeader = Buffer.from([0x1f, 0x8b])
3334
const STATE = Symbol('state')
@@ -59,6 +60,7 @@ const DONE = Symbol('onDone')
5960
const SAW_VALID_ENTRY = Symbol('sawValidEntry')
6061
const SAW_NULL_BLOCK = Symbol('sawNullBlock')
6162
const SAW_EOF = Symbol('sawEOF')
63+
const CLOSESTREAM = Symbol('closeStream')
6264

6365
const noop = _ => true
6466

@@ -89,7 +91,6 @@ module.exports = warner(class Parser extends EE {
8991
this.emit('prefinish')
9092
this.emit('finish')
9193
this.emit('end')
92-
this.emit('close')
9394
})
9495
}
9596

@@ -114,6 +115,9 @@ module.exports = warner(class Parser extends EE {
114115
this[ABORTED] = false
115116
this[SAW_NULL_BLOCK] = false
116117
this[SAW_EOF] = false
118+
119+
this.on('end', () => this[CLOSESTREAM]())
120+
117121
if (typeof opt.onwarn === 'function') {
118122
this.on('warn', opt.onwarn)
119123
}
@@ -217,6 +221,10 @@ module.exports = warner(class Parser extends EE {
217221
}
218222
}
219223

224+
[CLOSESTREAM] () {
225+
nextTick(() => this.emit('close'))
226+
}
227+
220228
[PROCESSENTRY] (entry) {
221229
let go = true
222230

lib/unpack.js

-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ class Unpack extends Parser {
234234
this.emit('prefinish')
235235
this.emit('finish')
236236
this.emit('end')
237-
this.emit('close')
238237
}
239238
}
240239

package.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@
3333
"events-to-array": "^1.1.2",
3434
"mutate-fs": "^2.1.1",
3535
"rimraf": "^3.0.2",
36-
"tap": "^16.0.1",
37-
"tar-fs": "^2.1.1",
38-
"tar-stream": "^2.2.0"
36+
"tap": "^16.0.1"
3937
},
4038
"license": "ISC",
4139
"engines": {

test/extract.js

+28
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const mkdirp = require('mkdirp')
1010
const { promisify } = require('util')
1111
const rimraf = promisify(require('rimraf'))
1212
const mutateFS = require('mutate-fs')
13+
const pipeline = promisify(require('stream').pipeline)
14+
const https = require('https')
1315

1416
t.teardown(_ => rimraf(extractdir))
1517

@@ -54,6 +56,32 @@ t.test('basic extracting', t => {
5456
t.end()
5557
})
5658

59+
t.test('ensure an open stream is not prematuraly closed', t => {
60+
const dir = path.resolve(extractdir, 'basic-with-stream')
61+
62+
t.beforeEach(async () => {
63+
await rimraf(dir)
64+
await mkdirp(dir)
65+
})
66+
67+
const check = async t => {
68+
fs.lstatSync(dir + '/node-tar-main/LICENSE')
69+
await rimraf(dir)
70+
t.end()
71+
}
72+
73+
t.test('async promisey', t => {
74+
https.get('https://codeload.github.com/npm/node-tar/tar.gz/main', (stream) => {
75+
return pipeline(
76+
stream,
77+
x({ cwd: dir }, ['node-tar-main/LICENSE'])
78+
).then(_ => check(t))
79+
})
80+
})
81+
82+
t.end()
83+
})
84+
5785
t.test('file list and filter', t => {
5886
const file = path.resolve(tars, 'utf8.tar')
5987
const dir = path.resolve(extractdir, 'filter')

0 commit comments

Comments
 (0)