@@ -208,23 +208,30 @@ module.exports = function (/**String*/input) {
208208 * @param zipPath Optional path inside the zip
209209 * @param zipName Optional name for the file
210210 */
211- addLocalFile : function ( /**String*/ localPath , /**String=*/ zipPath , /**String=*/ zipName ) {
211+ addLocalFile : function ( /**String*/ localPath , /**String=*/ zipPath , /**String=*/ zipName , /**String*/ comment ) {
212212 if ( fs . existsSync ( localPath ) ) {
213+ // prepare zippath
213214 if ( zipPath ) {
215+ // convert windows file separators
214216 zipPath = zipPath . split ( "\\" ) . join ( "/" ) ;
217+ // add separator if it wasnt given
215218 if ( zipPath . charAt ( zipPath . length - 1 ) !== "/" ) {
216219 zipPath += "/" ;
217220 }
218221 } else {
219222 zipPath = "" ;
220223 }
224+ // p - local file name
221225 var p = localPath . split ( "\\" ) . join ( "/" ) . split ( "/" ) . pop ( ) ;
222226
223- if ( zipName ) {
224- this . addFile ( zipPath + zipName , fs . readFileSync ( localPath ) , "" , 0 )
225- } else {
226- this . addFile ( zipPath + p , fs . readFileSync ( localPath ) , "" , 0 )
227- }
227+ // add file name into zippath
228+ zipPath += ( zipName ) ? zipPath : p ;
229+
230+ // read file attributes
231+ const _attr = fs . statSync ( localPath ) ;
232+
233+ // add file into zip file
234+ this . addFile ( zipPath , fs . readFileSync ( localPath ) , comment , _attr )
228235 } else {
229236 throw new Error ( Utils . Errors . FILE_NOT_FOUND . replace ( "%s" , localPath ) ) ;
230237 }
@@ -376,19 +383,38 @@ module.exports = function (/**String*/input) {
376383 * @param attr
377384 */
378385 addFile : function ( /**String*/ entryName , /**Buffer*/ content , /**String*/ comment , /**Number*/ attr ) {
386+ // prepare new entry
379387 var entry = new ZipEntry ( ) ;
380388 entry . entryName = entryName ;
381389 entry . comment = comment || "" ;
382390
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--
391+ var isStat = ( 'object' === typeof attr ) && ( attr instanceof fs . Stats ) ;
392+
393+ // last modification time from file stats
394+ if ( isStat ) {
395+ entry . header . time = attr . mtime ;
396+ }
397+
398+ // Set file attribute
399+ var fileattr = ( entry . isDirectory ) ? 0x10 : 0 ; // (MS-DOS directory flag)
400+
401+ // extended attributes field for Unix
402+ if ( 'win32' !== process . platform ) {
403+ // set file type either S_IFDIR / S_IFREG
404+ var unix = ( entry . isDirectory ) ? 0x4000 : 0x8000 ;
405+
406+ if ( isStat ) { // File attributes from file stats
407+ unix |= ( 0xfff & attr . mode )
408+ } else if ( 'number' === typeof attr ) { // attr from given attr values
409+ unix |= ( 0xfff & attr ) ;
410+ } else { // Default values:
411+ unix |= ( entry . isDirectory ) ? 0o755 : 0o644 ; // permissions (drwxr-xr-x) or (-r-wr--r--)
388412 }
413+
414+ fileattr = ( fileattr | ( unix << 16 ) ) >>> 0 ; // add attributes
389415 }
390416
391- entry . attr = attr ;
417+ entry . attr = fileattr ;
392418
393419 entry . setData ( content ) ;
394420 _zip . setEntry ( entry ) ;
0 commit comments