1
- 'use strict' ;
2
- const path = require ( 'path' ) ;
3
- const fs = require ( 'graceful-fs' ) ;
4
- const decompressTar = require ( 'decompress-tar' ) ;
5
- const decompressTarbz2 = require ( 'decompress-tarbz2' ) ;
6
- const decompressTargz = require ( 'decompress-targz' ) ;
7
- const decompressUnzip = require ( 'decompress-unzip' ) ;
8
- const makeDir = require ( 'make-dir' ) ;
9
- const pify = require ( 'pify' ) ;
10
- const stripDirs = require ( 'strip-dirs' ) ;
1
+ import { Buffer } from 'node:buffer' ;
2
+ import path from 'node:path' ;
3
+ import process from 'node:process' ;
4
+ import decompressTar from 'decompress-tar' ;
5
+ import decompressTarbz2 from 'decompress-tarbz2' ;
6
+ import decompressTargz from 'decompress-targz' ;
7
+ import decompressUnzip from 'decompress-unzip' ;
8
+ import fs from 'graceful-fs' ;
9
+ import makeDir from 'make-dir' ;
10
+ import pify from 'pify' ;
11
+ import stripDirs from 'strip-dirs' ;
11
12
12
13
const fsP = pify ( fs ) ;
13
14
14
- const runPlugins = ( input , opts ) => {
15
- if ( opts . plugins . length === 0 ) {
15
+ const runPlugins = ( input , options ) => {
16
+ if ( options . plugins . length === 0 ) {
16
17
return Promise . resolve ( [ ] ) ;
17
18
}
18
19
19
- return Promise . all ( opts . plugins . map ( x => x ( input , opts ) ) ) . then ( files => files . reduce ( ( a , b ) => a . concat ( b ) ) ) ;
20
+ return Promise . all ( options . plugins . map ( x => x ( input , options ) ) )
21
+ // eslint-disable-next-line unicorn/no-array-reduce, unicorn/prefer-spread
22
+ . then ( files => files . reduce ( ( a , b ) => a . concat ( b ) ) ) ;
20
23
} ;
21
24
22
- const safeMakeDir = ( dir , realOutputPath ) => {
23
- return fsP . realpath ( dir )
24
- . catch ( _ => {
25
- const parent = path . dirname ( dir ) ;
26
- return safeMakeDir ( parent , realOutputPath ) ;
27
- } )
28
- . then ( realParentPath => {
29
- if ( realParentPath . indexOf ( realOutputPath ) !== 0 ) {
30
- throw ( new Error ( 'Refusing to create a directory outside the output path.' ) ) ;
31
- }
32
-
33
- return makeDir ( dir ) . then ( fsP . realpath ) ;
34
- } ) ;
35
- } ;
25
+ const safeMakeDir = ( dir , realOutputPath ) => fsP . realpath ( dir )
26
+ . catch ( _ => {
27
+ const parent = path . dirname ( dir ) ;
28
+ return safeMakeDir ( parent , realOutputPath ) ;
29
+ } )
30
+ . then ( realParentPath => {
31
+ if ( realParentPath . indexOf ( realOutputPath ) !== 0 ) {
32
+ throw new Error ( 'Refusing to create a directory outside the output path.' ) ;
33
+ }
36
34
37
- const preventWritingThroughSymlink = ( destination , realOutputPath ) => {
38
- return fsP . readlink ( destination )
39
- . catch ( _ => {
40
- // Either no file exists, or it's not a symlink. In either case, this is
41
- // not an escape we need to worry about in this phase.
42
- return null ;
43
- } )
44
- . then ( symlinkPointsTo => {
45
- if ( symlinkPointsTo ) {
46
- throw new Error ( 'Refusing to write into a symlink' ) ;
47
- }
48
-
49
- // No symlink exists at `destination`, so we can continue
50
- return realOutputPath ;
51
- } ) ;
52
- } ;
35
+ return makeDir ( dir ) . then ( fsP . realpath ) ;
36
+ } ) ;
37
+
38
+ const preventWritingThroughSymlink = ( destination , realOutputPath ) => fsP . readlink ( destination )
39
+ // Either no file exists, or it's not a symlink. In either case, this is
40
+ // not an escape we need to worry about in this phase.
41
+ . catch ( _ => null )
42
+ . then ( symlinkPointsTo => {
43
+ if ( symlinkPointsTo ) {
44
+ throw new Error ( 'Refusing to write into a symlink' ) ;
45
+ }
46
+
47
+ // No symlink exists at `destination`, so we can continue
48
+ return realOutputPath ;
49
+ } ) ;
53
50
54
- const extractFile = ( input , output , opts ) => runPlugins ( input , opts ) . then ( files => {
55
- if ( opts . strip > 0 ) {
51
+ const extractFile = ( input , output , options ) => runPlugins ( input , options ) . then ( files => {
52
+ if ( options . strip > 0 ) {
56
53
files = files
57
54
. map ( x => {
58
- x . path = stripDirs ( x . path , opts . strip ) ;
55
+ x . path = stripDirs ( x . path , options . strip ) ;
59
56
return x ;
60
57
} )
61
58
. filter ( x => x . path !== '.' ) ;
62
59
}
63
60
64
- if ( typeof opts . filter === 'function' ) {
65
- files = files . filter ( opts . filter ) ;
61
+ if ( typeof options . filter === 'function' ) {
62
+ // eslint-disable-next-line unicorn/no-array-callback-reference
63
+ files = files . filter ( options . filter ) ;
66
64
}
67
65
68
- if ( typeof opts . map === 'function' ) {
69
- files = files . map ( opts . map ) ;
66
+ if ( typeof options . map === 'function' ) {
67
+ // eslint-disable-next-line unicorn/no-array-callback-reference
68
+ files = files . map ( options . map ) ;
70
69
}
71
70
72
71
if ( ! output ) {
@@ -75,7 +74,7 @@ const extractFile = (input, output, opts) => runPlugins(input, opts).then(files
75
74
76
75
return Promise . all ( files . map ( x => {
77
76
const dest = path . join ( output , x . path ) ;
78
- const mode = x . mode & ~ process . umask ( ) ;
77
+ const mode = x . mode & ~ process . umask ( ) ; // eslint-disable-line no-bitwise
79
78
const now = new Date ( ) ;
80
79
81
80
if ( x . type === 'directory' ) {
@@ -88,26 +87,23 @@ const extractFile = (input, output, opts) => runPlugins(input, opts).then(files
88
87
89
88
return makeDir ( output )
90
89
. then ( outputPath => fsP . realpath ( outputPath ) )
91
- . then ( realOutputPath => {
90
+ . then ( realOutputPath =>
92
91
// Attempt to ensure parent directory exists (failing if it's outside the output dir)
93
- return safeMakeDir ( path . dirname ( dest ) , realOutputPath )
94
- . then ( ( ) => realOutputPath ) ;
95
- } )
92
+ safeMakeDir ( path . dirname ( dest ) , realOutputPath ) . then ( ( ) => realOutputPath ) ,
93
+ )
96
94
. then ( realOutputPath => {
97
95
if ( x . type === 'file' ) {
98
96
return preventWritingThroughSymlink ( dest , realOutputPath ) ;
99
97
}
100
98
101
99
return realOutputPath ;
102
100
} )
103
- . then ( realOutputPath => {
104
- return fsP . realpath ( path . dirname ( dest ) )
105
- . then ( realDestinationDir => {
106
- if ( realDestinationDir . indexOf ( realOutputPath ) !== 0 ) {
107
- throw ( new Error ( 'Refusing to write outside output directory: ' + realDestinationDir ) ) ;
108
- }
109
- } ) ;
110
- } )
101
+ . then ( realOutputPath => fsP . realpath ( path . dirname ( dest ) )
102
+ . then ( realDestinationDir => {
103
+ if ( realDestinationDir . indexOf ( realOutputPath ) !== 0 ) {
104
+ throw new Error ( `Refusing to write outside output directory: ${ realDestinationDir } ` ) ;
105
+ }
106
+ } ) )
111
107
. then ( ( ) => {
112
108
if ( x . type === 'link' ) {
113
109
return fsP . link ( x . linkname , dest ) ;
@@ -128,24 +124,29 @@ const extractFile = (input, output, opts) => runPlugins(input, opts).then(files
128
124
} ) ) ;
129
125
} ) ;
130
126
131
- module . exports = ( input , output , opts ) => {
127
+ const decompress = ( input , output , options ) => {
132
128
if ( typeof input !== 'string' && ! Buffer . isBuffer ( input ) ) {
133
129
return Promise . reject ( new TypeError ( 'Input file required' ) ) ;
134
130
}
135
131
136
132
if ( typeof output === 'object' ) {
137
- opts = output ;
133
+ options = output ;
138
134
output = null ;
139
135
}
140
136
141
- opts = Object . assign ( { plugins : [
142
- decompressTar ( ) ,
143
- decompressTarbz2 ( ) ,
144
- decompressTargz ( ) ,
145
- decompressUnzip ( )
146
- ] } , opts ) ;
137
+ options = {
138
+ plugins : [
139
+ decompressTar ( ) ,
140
+ decompressTarbz2 ( ) ,
141
+ decompressTargz ( ) ,
142
+ decompressUnzip ( ) ,
143
+ ] ,
144
+ ...options ,
145
+ } ;
147
146
148
147
const read = typeof input === 'string' ? fsP . readFile ( input ) : Promise . resolve ( input ) ;
149
148
150
- return read . then ( buf => extractFile ( buf , output , opts ) ) ;
149
+ return read . then ( buf => extractFile ( buf , output , options ) ) ;
151
150
} ;
151
+
152
+ export default decompress ;
0 commit comments