dir-archiver 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/cli.js +4 -1
- package/index.js +77 -37
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -10,6 +10,8 @@ Compress a whole directory (including subdirectories) into a zip file, with opt
|
|
|
10
10
|
$ npm install dir-archiver
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
Requires Node.js >=14.
|
|
14
|
+
|
|
13
15
|
# Usage
|
|
14
16
|
|
|
15
17
|
## API
|
|
@@ -35,7 +37,14 @@ const excludes = ['directory_name', 'file.extension'];
|
|
|
35
37
|
var archive = new DirArchiver('path/to/directory', 'path/to/desination/zipfile.zip', true, excludes);
|
|
36
38
|
|
|
37
39
|
// Create the zip file.
|
|
38
|
-
archive.createZip()
|
|
40
|
+
archive.createZip().then(() => {
|
|
41
|
+
console.log('Archive ready');
|
|
42
|
+
}).catch((err) => {
|
|
43
|
+
console.error(err);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Or with async/await:
|
|
47
|
+
// await archive.createZip();
|
|
39
48
|
```
|
|
40
49
|
## Command Line Interface
|
|
41
50
|
|
|
@@ -54,6 +63,12 @@ Options:
|
|
|
54
63
|
--exclude A list with the names of the files and folders to exclude. [array]
|
|
55
64
|
```
|
|
56
65
|
|
|
66
|
+
# Testing
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
$ npm test
|
|
70
|
+
```
|
|
71
|
+
|
|
57
72
|
|
|
58
73
|
|
|
59
74
|
[changelog-image]: https://img.shields.io/badge/changelog-md-blue.svg?style=flat-square
|
package/cli.js
CHANGED
|
@@ -25,4 +25,7 @@ if ( directoryPath === false || zipPath === false ) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const archive = new DirArchiver( directoryPath, zipPath, includeBaseDirectory, excludes );
|
|
28
|
-
archive.createZip()
|
|
28
|
+
archive.createZip().catch( ( err ) => {
|
|
29
|
+
console.error( err );
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
} );
|
package/index.js
CHANGED
|
@@ -15,7 +15,8 @@ class DirArchiver {
|
|
|
15
15
|
constructor( directoryPath, zipPath, includeBaseDirectory, excludes ) {
|
|
16
16
|
|
|
17
17
|
// Contains the excluded files and folders.
|
|
18
|
-
|
|
18
|
+
const safeExcludes = Array.isArray( excludes ) ? excludes : [];
|
|
19
|
+
this.excludes = safeExcludes.map( ( element ) => {
|
|
19
20
|
return path.normalize( element );
|
|
20
21
|
} );
|
|
21
22
|
|
|
@@ -26,6 +27,15 @@ class DirArchiver {
|
|
|
26
27
|
this.includeBaseDirectory = includeBaseDirectory;
|
|
27
28
|
|
|
28
29
|
this.baseDirectory = path.basename( this.directoryPath );
|
|
30
|
+
|
|
31
|
+
const relativeZipPath = path.relative( this.directoryPath, this.zipPath );
|
|
32
|
+
const isZipInsideSource = relativeZipPath && ! relativeZipPath.startsWith( '..' ) && ! path.isAbsolute( relativeZipPath );
|
|
33
|
+
if ( isZipInsideSource ) {
|
|
34
|
+
const normalizedZipPath = path.normalize( relativeZipPath );
|
|
35
|
+
if ( ! this.excludes.includes( normalizedZipPath ) ) {
|
|
36
|
+
this.excludes.push( normalizedZipPath );
|
|
37
|
+
}
|
|
38
|
+
}
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
/**
|
|
@@ -34,8 +44,11 @@ class DirArchiver {
|
|
|
34
44
|
*/
|
|
35
45
|
traverseDirectoryTree( directoryPath ) {
|
|
36
46
|
const files = fs.readdirSync( directoryPath );
|
|
37
|
-
for ( const
|
|
38
|
-
const currentPath = path.join( path.resolve( directoryPath ),
|
|
47
|
+
for ( const file of files ) {
|
|
48
|
+
const currentPath = path.join( path.resolve( directoryPath ), file );
|
|
49
|
+
if ( path.resolve( currentPath ) === this.zipPath ) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
39
52
|
const stats = fs.statSync( currentPath );
|
|
40
53
|
let relativePath = path.relative( this.directoryPath, currentPath );
|
|
41
54
|
if ( stats.isFile() && ! this.excludes.includes( relativePath ) ) {
|
|
@@ -68,46 +81,73 @@ class DirArchiver {
|
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
createZip () {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
return new Promise( ( resolve, reject ) => {
|
|
85
|
+
let settled = false;
|
|
86
|
+
const safeResolve = ( value ) => {
|
|
87
|
+
if ( settled ) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
settled = true;
|
|
91
|
+
resolve( value );
|
|
92
|
+
};
|
|
93
|
+
const safeReject = ( err ) => {
|
|
94
|
+
if ( settled ) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
settled = true;
|
|
98
|
+
reject( err );
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Remove the destination zip if it exists.
|
|
102
|
+
// see : https://github.com/Ismail-elkorchi/dir-archiver/issues/5
|
|
103
|
+
try {
|
|
104
|
+
if ( fs.existsSync( this.zipPath ) ) {
|
|
105
|
+
fs.unlinkSync( this.zipPath );
|
|
106
|
+
}
|
|
107
|
+
} catch ( err ) {
|
|
108
|
+
safeReject( err );
|
|
109
|
+
return;
|
|
90
110
|
}
|
|
91
|
-
} );
|
|
92
111
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
112
|
+
// Create a file to stream archive data to.
|
|
113
|
+
this.output = fs.createWriteStream( this.zipPath );
|
|
114
|
+
this.archive = archiver( 'zip', {
|
|
115
|
+
zlib: { level: 9 }
|
|
116
|
+
} );
|
|
117
|
+
|
|
118
|
+
// Catch warnings during archiving.
|
|
119
|
+
this.archive.on( 'warning', ( err ) => {
|
|
120
|
+
if ( err.code === 'ENOENT' ) {
|
|
121
|
+
// log warning
|
|
122
|
+
console.log( err );
|
|
123
|
+
} else {
|
|
124
|
+
safeReject( err );
|
|
125
|
+
}
|
|
126
|
+
} );
|
|
127
|
+
|
|
128
|
+
// Catch errors during archiving.
|
|
129
|
+
this.archive.on( 'error', ( err ) => {
|
|
130
|
+
safeReject( err );
|
|
131
|
+
} );
|
|
132
|
+
|
|
133
|
+
this.output.on( 'error', ( err ) => {
|
|
134
|
+
safeReject( err );
|
|
135
|
+
} );
|
|
97
136
|
|
|
98
|
-
|
|
99
|
-
|
|
137
|
+
// Listen for all archive data to be written.
|
|
138
|
+
this.output.on( 'close', () => {
|
|
139
|
+
console.log( `Created ${this.zipPath} of ${this.prettyBytes( this.archive.pointer() )}` );
|
|
140
|
+
safeResolve( this.zipPath );
|
|
141
|
+
} );
|
|
100
142
|
|
|
101
|
-
|
|
102
|
-
|
|
143
|
+
// Pipe archive data to the file.
|
|
144
|
+
this.archive.pipe( this.output );
|
|
103
145
|
|
|
104
|
-
|
|
105
|
-
|
|
146
|
+
// Recursively traverse the directory tree and append the files to the archive.
|
|
147
|
+
this.traverseDirectoryTree( this.directoryPath );
|
|
106
148
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
this.output.on( 'close', function () {
|
|
110
|
-
console.log( `Created ${self.zipPath} of ${self.prettyBytes( self.archive.pointer() )}` );
|
|
149
|
+
// Finalize the archive.
|
|
150
|
+
this.archive.finalize();
|
|
111
151
|
} );
|
|
112
152
|
}
|
|
113
153
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dir-archiver",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Compress a whole directory (including subdirectories) into a zip file, with options to exclude specific files, or directories.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "index.js",
|
|
@@ -34,14 +34,19 @@
|
|
|
34
34
|
"homepage": "https://github.com/Ismail-elkorchi/dir-archiver",
|
|
35
35
|
"scripts": {
|
|
36
36
|
"lint": "eslint cli.js index.js",
|
|
37
|
-
"lint:fix": "eslint --fix cli.js index.js"
|
|
37
|
+
"lint:fix": "eslint --fix cli.js index.js",
|
|
38
|
+
"test": "node test/smoke.js"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=14"
|
|
38
42
|
},
|
|
39
43
|
"dependencies": {
|
|
40
|
-
"archiver": "^
|
|
44
|
+
"archiver": "^7.0.1",
|
|
41
45
|
"argv-flags": "^0.1.1"
|
|
42
46
|
},
|
|
43
47
|
"devDependencies": {
|
|
44
48
|
"eslint": "^8.24.0",
|
|
45
|
-
"eslint-plugin-n": "^15.3.0"
|
|
49
|
+
"eslint-plugin-n": "^15.3.0",
|
|
50
|
+
"yauzl": "^3.2.0"
|
|
46
51
|
}
|
|
47
52
|
}
|