@@ -56,16 +56,26 @@ module.exports = function (/**String*/input) {
56
56
return null ;
57
57
}
58
58
59
+ function fixPath ( zipPath ) {
60
+ // convert windows file separators
61
+ zipPath = zipPath . split ( "\\" ) . join ( "/" ) ;
62
+ // add separator if it wasnt given
63
+ if ( zipPath . charAt ( zipPath . length - 1 ) !== "/" ) {
64
+ zipPath += "/" ;
65
+ }
66
+ return zipPath ;
67
+ }
68
+
59
69
return {
60
70
/**
61
71
* Extracts the given entry from the archive and returns the content as a Buffer object
62
72
* @param entry ZipEntry object or String with the full path of the entry
63
73
*
64
74
* @return Buffer or Null in case of error
65
75
*/
66
- readFile : function ( /**Object*/ entry ) {
76
+ readFile : function ( /**Object*/ entry , /*String, Buffer*/ pass ) {
67
77
var item = getEntry ( entry ) ;
68
- return item && item . getData ( ) || null ;
78
+ return item && item . getData ( pass ) || null ;
69
79
} ,
70
80
71
81
/**
@@ -208,23 +218,22 @@ module.exports = function (/**String*/input) {
208
218
* @param zipPath Optional path inside the zip
209
219
* @param zipName Optional name for the file
210
220
*/
211
- addLocalFile : function ( /**String*/ localPath , /**String=*/ zipPath , /**String=*/ zipName ) {
221
+ addLocalFile : function ( /**String*/ localPath , /**String=*/ zipPath , /**String=*/ zipName , /**String*/ comment ) {
212
222
if ( fs . existsSync ( localPath ) ) {
213
- if ( zipPath ) {
214
- zipPath = zipPath . split ( "\\" ) . join ( "/" ) ;
215
- if ( zipPath . charAt ( zipPath . length - 1 ) !== "/" ) {
216
- zipPath += "/" ;
217
- }
218
- } else {
219
- zipPath = "" ;
220
- }
223
+ // fix ZipPath
224
+ zipPath = ( zipPath ) ? fixPath ( zipPath ) : "" ;
225
+
226
+ // p - local file name
221
227
var p = localPath . split ( "\\" ) . join ( "/" ) . split ( "/" ) . pop ( ) ;
222
228
223
- if ( zipName ) {
224
- this . addFile ( zipPath + zipName , fs . readFileSync ( localPath ) , "" , 0 )
225
- } else {
226
- this . addFile ( zipPath + p , fs . readFileSync ( localPath ) , "" , 0 )
227
- }
229
+ // add file name into zippath
230
+ zipPath += ( zipName ) ? zipName : p ;
231
+
232
+ // read file attributes
233
+ const _attr = fs . statSync ( localPath ) ;
234
+
235
+ // add file into zip file
236
+ this . addFile ( zipPath , fs . readFileSync ( localPath ) , comment , _attr )
228
237
} else {
229
238
throw new Error ( Utils . Errors . FILE_NOT_FOUND . replace ( "%s" , localPath ) ) ;
230
239
}
@@ -238,54 +247,47 @@ module.exports = function (/**String*/input) {
238
247
* @param filter optional RegExp or Function if files match will
239
248
* be included.
240
249
*/
241
- addLocalFolder : function ( /**String*/ localPath , /**String=*/ zipPath , /**=RegExp|Function*/ filter ) {
242
- if ( filter === undefined ) {
243
- filter = function ( ) {
244
- return true ;
245
- } ;
246
- } else if ( filter instanceof RegExp ) {
247
- filter = function ( filter ) {
248
- return function ( filename ) {
249
- return filter . test ( filename ) ;
250
- }
251
- } ( filter ) ;
252
- }
253
-
254
- if ( zipPath ) {
255
- zipPath = zipPath . split ( "\\" ) . join ( "/" ) ;
256
- if ( zipPath . charAt ( zipPath . length - 1 ) !== "/" ) {
257
- zipPath += "/" ;
258
- }
259
- } else {
260
- zipPath = "" ;
261
- }
262
- // normalize the path first
263
- localPath = pth . normalize ( localPath ) ;
264
- localPath = localPath . split ( "\\" ) . join ( "/" ) ; //windows fix
265
- if ( localPath . charAt ( localPath . length - 1 ) !== "/" )
266
- localPath += "/" ;
267
-
268
- if ( fs . existsSync ( localPath ) ) {
269
-
270
- var items = Utils . findFiles ( localPath ) ,
271
- self = this ;
272
-
273
- if ( items . length ) {
274
- items . forEach ( function ( path ) {
275
- var p = path . split ( "\\" ) . join ( "/" ) . replace ( new RegExp ( localPath . replace ( / ( \( | \) | \$ ) / g, '\\$1' ) , 'i' ) , "" ) ; //windows fix
276
- if ( filter ( p ) ) {
277
- if ( p . charAt ( p . length - 1 ) !== "/" ) {
278
- self . addFile ( zipPath + p , fs . readFileSync ( path ) , "" , 0 )
279
- } else {
280
- self . addFile ( zipPath + p , Buffer . alloc ( 0 ) , "" , 0 )
281
- }
282
- }
283
- } ) ;
284
- }
285
- } else {
286
- throw new Error ( Utils . Errors . FILE_NOT_FOUND . replace ( "%s" , localPath ) ) ;
287
- }
288
- } ,
250
+ addLocalFolder : function ( /**String*/ localPath , /**String=*/ zipPath , /**=RegExp|Function*/ filter ) {
251
+ // Prepare filter
252
+ if ( filter instanceof RegExp ) { // if filter is RegExp wrap it
253
+ filter = ( function ( rx ) {
254
+ return function ( filename ) {
255
+ return rx . test ( filename ) ;
256
+ }
257
+ } ) ( filter ) ;
258
+ } else if ( 'function' !== typeof filter ) { // if filter is not function we will replace it
259
+ filter = function ( ) {
260
+ return true ;
261
+ } ;
262
+ }
263
+
264
+ // fix ZipPath
265
+ zipPath = ( zipPath ) ? fixPath ( zipPath ) : "" ;
266
+
267
+ // normalize the path first
268
+ localPath = pth . normalize ( localPath ) ;
269
+
270
+ if ( fs . existsSync ( localPath ) ) {
271
+
272
+ var items = Utils . findFiles ( localPath ) ,
273
+ self = this ;
274
+
275
+ if ( items . length ) {
276
+ items . forEach ( function ( filepath ) {
277
+ var p = pth . relative ( localPath , filepath ) . split ( "\\" ) . join ( "/" ) ; //windows fix
278
+ if ( filter ( p ) ) {
279
+ if ( filepath . charAt ( filepath . length - 1 ) !== pth . sep ) {
280
+ self . addFile ( zipPath + p , fs . readFileSync ( filepath ) , "" , fs . statSync ( filepath ) ) ;
281
+ } else {
282
+ self . addFile ( zipPath + p + '/' , Buffer . alloc ( 0 ) , "" , 0 ) ;
283
+ }
284
+ }
285
+ } ) ;
286
+ }
287
+ } else {
288
+ throw new Error ( Utils . Errors . FILE_NOT_FOUND . replace ( "%s" , localPath ) ) ;
289
+ }
290
+ } ,
289
291
290
292
/**
291
293
* Asynchronous addLocalFile
@@ -376,19 +378,38 @@ module.exports = function (/**String*/input) {
376
378
* @param attr
377
379
*/
378
380
addFile : function ( /**String*/ entryName , /**Buffer*/ content , /**String*/ comment , /**Number*/ attr ) {
381
+ // prepare new entry
379
382
var entry = new ZipEntry ( ) ;
380
383
entry . entryName = entryName ;
381
384
entry . comment = comment || "" ;
382
385
383
- if ( ! attr ) {
384
- if ( entry . isDirectory ) {
385
- attr = ( 0o40755 << 16 ) | 0x10 ; // (permissions drwxr-xr-x) + (MS-DOS directory flag)
386
- } else {
387
- attr = 0o644 << 16 ; // permissions -r-wr--r--
386
+ var isStat = ( 'object' === typeof attr ) && ( attr instanceof fs . Stats ) ;
387
+
388
+ // last modification time from file stats
389
+ if ( isStat ) {
390
+ entry . header . time = attr . mtime ;
391
+ }
392
+
393
+ // Set file attribute
394
+ var fileattr = ( entry . isDirectory ) ? 0x10 : 0 ; // (MS-DOS directory flag)
395
+
396
+ // extended attributes field for Unix
397
+ if ( 'win32' !== process . platform ) {
398
+ // set file type either S_IFDIR / S_IFREG
399
+ var unix = ( entry . isDirectory ) ? 0x4000 : 0x8000 ;
400
+
401
+ if ( isStat ) { // File attributes from file stats
402
+ unix |= ( 0xfff & attr . mode )
403
+ } else if ( 'number' === typeof attr ) { // attr from given attr values
404
+ unix |= ( 0xfff & attr ) ;
405
+ } else { // Default values:
406
+ unix |= ( entry . isDirectory ) ? 0o755 : 0o644 ; // permissions (drwxr-xr-x) or (-r-wr--r--)
388
407
}
408
+
409
+ fileattr = ( fileattr | ( unix << 16 ) ) >>> 0 ; // add attributes
389
410
}
390
411
391
- entry . attr = attr ;
412
+ entry . attr = fileattr ;
392
413
393
414
entry . setData ( content ) ;
394
415
_zip . setEntry ( entry ) ;
@@ -482,7 +503,7 @@ module.exports = function (/**String*/input) {
482
503
* Test the archive
483
504
*
484
505
*/
485
- test : function ( ) {
506
+ test : function ( pass ) {
486
507
if ( ! _zip ) {
487
508
return false ;
488
509
}
@@ -492,7 +513,7 @@ module.exports = function (/**String*/input) {
492
513
if ( entry . isDirectory ) {
493
514
continue ;
494
515
}
495
- var content = _zip . entries [ entry ] . getData ( ) ;
516
+ var content = _zip . entries [ entry ] . getData ( pass ) ;
496
517
if ( ! content ) {
497
518
return false ;
498
519
}
@@ -510,7 +531,7 @@ module.exports = function (/**String*/input) {
510
531
* @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
511
532
* Default is FALSE
512
533
*/
513
- extractAllTo : function ( /**String*/ targetPath , /**Boolean*/ overwrite ) {
534
+ extractAllTo : function ( /**String*/ targetPath , /**Boolean*/ overwrite , /*String, Buffer*/ pass ) {
514
535
overwrite = overwrite || false ;
515
536
if ( ! _zip ) {
516
537
throw new Error ( Utils . Errors . NO_ZIP ) ;
@@ -521,7 +542,7 @@ module.exports = function (/**String*/input) {
521
542
Utils . makeDir ( entryName ) ;
522
543
return ;
523
544
}
524
- var content = entry . getData ( ) ;
545
+ var content = entry . getData ( pass ) ;
525
546
if ( ! content ) {
526
547
throw new Error ( Utils . Errors . CANT_EXTRACT_FILE ) ;
527
548
}
0 commit comments