Remove archiver dependency

This commit is contained in:
advplyr 2022-07-06 20:12:14 -05:00
parent 415e0a7b5a
commit ab08d83c04
35 changed files with 4046 additions and 194 deletions

221
package-lock.json generated
View File

@ -33,20 +33,6 @@
"negotiator": "0.6.3"
}
},
"archiver": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz",
"integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==",
"requires": {
"archiver-utils": "^2.1.0",
"async": "^3.2.3",
"buffer-crc32": "^0.2.1",
"readable-stream": "^3.6.0",
"readdir-glob": "^1.0.0",
"tar-stream": "^2.2.0",
"zip-stream": "^4.1.0"
}
},
"archiver-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
@ -62,35 +48,6 @@
"lodash.union": "^4.6.0",
"normalize-path": "^3.0.0",
"readable-stream": "^2.0.0"
},
"dependencies": {
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"array-flatten": {
@ -98,11 +55,6 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"async": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
},
"axios": {
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
@ -116,26 +68,11 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
},
"bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"requires": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"body-parser": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
@ -164,20 +101,6 @@
"concat-map": "0.0.1"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="
},
"bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -197,17 +120,6 @@
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
},
"compress-commons": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz",
"integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==",
"requires": {
"buffer-crc32": "^0.2.13",
"crc32-stream": "^4.0.2",
"normalize-path": "^3.0.0",
"readable-stream": "^3.6.0"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -250,20 +162,6 @@
"vary": "^1"
}
},
"crc-32": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
},
"crc32-stream": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz",
"integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==",
"requires": {
"crc-32": "^1.2.0",
"readable-stream": "^3.4.0"
}
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -325,14 +223,6 @@
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"requires": {
"once": "^1.4.0"
}
},
"engine.io": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz",
@ -457,11 +347,6 @@
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
},
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -544,11 +429,6 @@
"safer-buffer": ">= 2.1.2 < 3"
}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -579,35 +459,6 @@
"integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
"requires": {
"readable-stream": "^2.0.5"
},
"dependencies": {
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"lodash.defaults": {
@ -771,21 +622,24 @@
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"readdir-glob": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz",
"integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==",
"requires": {
"minimatch": "^3.0.4"
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
},
"safe-buffer": {
@ -920,23 +774,18 @@
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
},
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.2.0"
}
},
"tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"requires": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
"safe-buffer": "~5.1.0"
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
},
"toidentifier": {
@ -961,7 +810,7 @@
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"utils-merge": {
"version": "1.0.1",
@ -976,7 +825,7 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"ws": {
"version": "8.2.3",
@ -996,16 +845,6 @@
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
},
"zip-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz",
"integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==",
"requires": {
"archiver-utils": "^2.1.0",
"compress-commons": "^4.1.0",
"readable-stream": "^3.6.0"
}
}
}
}

View File

@ -30,7 +30,7 @@
"author": "advplyr",
"license": "GPL-3.0",
"dependencies": {
"archiver": "^5.3.0",
"archiver-utils": "^2.1.0",
"axios": "^0.26.1",
"express": "^4.17.1",
"htmlparser2": "^8.0.1",

View File

@ -0,0 +1,22 @@
Copyright (c) 2012-2014 Chris Talkington, contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,19 @@
The MIT License
Copyright (c) 2013 Brian J. Brennan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,122 @@
//
// used in archiver
// Source: https://github.com/brianloveswords/buffer-crc32
//
var Buffer = require('buffer').Buffer;
var CRC_TABLE = [
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
0x2d02ef8d
];
if (typeof Int32Array !== 'undefined') {
CRC_TABLE = new Int32Array(CRC_TABLE);
}
function newEmptyBuffer(length) {
var buffer = new Buffer(length);
buffer.fill(0x00);
return buffer;
}
function ensureBuffer(input) {
if (Buffer.isBuffer(input)) {
return input;
}
var hasNewBufferAPI =
typeof Buffer.alloc === "function" &&
typeof Buffer.from === "function";
if (typeof input === "number") {
return hasNewBufferAPI ? Buffer.alloc(input) : newEmptyBuffer(input);
}
else if (typeof input === "string") {
return hasNewBufferAPI ? Buffer.from(input) : new Buffer(input);
}
else {
throw new Error("input must be buffer, number, or string, received " +
typeof input);
}
}
function bufferizeInt(num) {
var tmp = ensureBuffer(4);
tmp.writeInt32BE(num, 0);
return tmp;
}
function _crc32(buf, previous) {
buf = ensureBuffer(buf);
if (Buffer.isBuffer(previous)) {
previous = previous.readUInt32BE(0);
}
var crc = ~~previous ^ -1;
for (var n = 0; n < buf.length; n++) {
crc = CRC_TABLE[(crc ^ buf[n]) & 0xff] ^ (crc >>> 8);
}
return (crc ^ -1);
}
function crc32() {
return bufferizeInt(_crc32.apply(null, arguments));
}
crc32.signed = function () {
return _crc32.apply(null, arguments);
};
crc32.unsigned = function () {
return _crc32.apply(null, arguments) >>> 0;
};
module.exports = crc32;

View File

@ -0,0 +1,22 @@
Copyright (c) 2014 Chris Talkington, contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,16 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
var ArchiveEntry = module.exports = function() {};
ArchiveEntry.prototype.getName = function() {};
ArchiveEntry.prototype.getSize = function() {};
ArchiveEntry.prototype.getLastModifiedDate = function() {};
ArchiveEntry.prototype.isDirectory = function() {};

View File

@ -0,0 +1,117 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
var inherits = require('util').inherits;
var Transform = require('readable-stream').Transform;
var ArchiveEntry = require('./archive-entry');
var util = require('../util');
var ArchiveOutputStream = module.exports = function(options) {
if (!(this instanceof ArchiveOutputStream)) {
return new ArchiveOutputStream(options);
}
Transform.call(this, options);
this.offset = 0;
this._archive = {
finish: false,
finished: false,
processing: false
};
};
inherits(ArchiveOutputStream, Transform);
ArchiveOutputStream.prototype._appendBuffer = function(zae, source, callback) {
// scaffold only
};
ArchiveOutputStream.prototype._appendStream = function(zae, source, callback) {
// scaffold only
};
ArchiveOutputStream.prototype._emitErrorCallback = function(err) {
if (err) {
this.emit('error', err);
}
};
ArchiveOutputStream.prototype._finish = function(ae) {
// scaffold only
};
ArchiveOutputStream.prototype._normalizeEntry = function(ae) {
// scaffold only
};
ArchiveOutputStream.prototype._transform = function(chunk, encoding, callback) {
callback(null, chunk);
};
ArchiveOutputStream.prototype.entry = function(ae, source, callback) {
source = source || null;
if (typeof callback !== 'function') {
callback = this._emitErrorCallback.bind(this);
}
if (!(ae instanceof ArchiveEntry)) {
callback(new Error('not a valid instance of ArchiveEntry'));
return;
}
if (this._archive.finish || this._archive.finished) {
callback(new Error('unacceptable entry after finish'));
return;
}
if (this._archive.processing) {
callback(new Error('already processing an entry'));
return;
}
this._archive.processing = true;
this._normalizeEntry(ae);
this._entry = ae;
source = util.normalizeInputSource(source);
if (Buffer.isBuffer(source)) {
this._appendBuffer(ae, source, callback);
} else if (util.isStream(source)) {
this._appendStream(ae, source, callback);
} else {
this._archive.processing = false;
callback(new Error('input source must be valid Stream or Buffer instance'));
return;
}
return this;
};
ArchiveOutputStream.prototype.finish = function() {
if (this._archive.processing) {
this._archive.finish = true;
return;
}
this._finish();
};
ArchiveOutputStream.prototype.getBytesWritten = function() {
return this.offset;
};
ArchiveOutputStream.prototype.write = function(chunk, cb) {
if (chunk) {
this.offset += chunk.length;
}
return Transform.prototype.write.call(this, chunk, cb);
};

View File

@ -0,0 +1,71 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
module.exports = {
WORD: 4,
DWORD: 8,
EMPTY: Buffer.alloc(0),
SHORT: 2,
SHORT_MASK: 0xffff,
SHORT_SHIFT: 16,
SHORT_ZERO: Buffer.from(Array(2)),
LONG: 4,
LONG_ZERO: Buffer.from(Array(4)),
MIN_VERSION_INITIAL: 10,
MIN_VERSION_DATA_DESCRIPTOR: 20,
MIN_VERSION_ZIP64: 45,
VERSION_MADEBY: 45,
METHOD_STORED: 0,
METHOD_DEFLATED: 8,
PLATFORM_UNIX: 3,
PLATFORM_FAT: 0,
SIG_LFH: 0x04034b50,
SIG_DD: 0x08074b50,
SIG_CFH: 0x02014b50,
SIG_EOCD: 0x06054b50,
SIG_ZIP64_EOCD: 0x06064B50,
SIG_ZIP64_EOCD_LOC: 0x07064B50,
ZIP64_MAGIC_SHORT: 0xffff,
ZIP64_MAGIC: 0xffffffff,
ZIP64_EXTRA_ID: 0x0001,
ZLIB_NO_COMPRESSION: 0,
ZLIB_BEST_SPEED: 1,
ZLIB_BEST_COMPRESSION: 9,
ZLIB_DEFAULT_COMPRESSION: -1,
MODE_MASK: 0xFFF,
DEFAULT_FILE_MODE: 33188, // 010644 = -rw-r--r-- = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
DEFAULT_DIR_MODE: 16877, // 040755 = drwxr-xr-x = S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
EXT_FILE_ATTR_DIR: 1106051088, // 010173200020 = drwxr-xr-x = (((S_IFDIR | 0755) << 16) | S_DOS_D)
EXT_FILE_ATTR_FILE: 2175008800, // 020151000040 = -rw-r--r-- = (((S_IFREG | 0644) << 16) | S_DOS_A) >>> 0
// Unix file types
S_IFMT: 61440, // 0170000 type of file mask
S_IFIFO: 4096, // 010000 named pipe (fifo)
S_IFCHR: 8192, // 020000 character special
S_IFDIR: 16384, // 040000 directory
S_IFBLK: 24576, // 060000 block special
S_IFREG: 32768, // 0100000 regular
S_IFLNK: 40960, // 0120000 symbolic link
S_IFSOCK: 49152, // 0140000 socket
// DOS file type flags
S_DOS_A: 32, // 040 Archive
S_DOS_D: 16, // 020 Directory
S_DOS_V: 8, // 010 Volume
S_DOS_S: 4, // 04 System
S_DOS_H: 2, // 02 Hidden
S_DOS_R: 1 // 01 Read Only
};

View File

@ -0,0 +1,101 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
var zipUtil = require('./util');
var DATA_DESCRIPTOR_FLAG = 1 << 3;
var ENCRYPTION_FLAG = 1 << 0;
var NUMBER_OF_SHANNON_FANO_TREES_FLAG = 1 << 2;
var SLIDING_DICTIONARY_SIZE_FLAG = 1 << 1;
var STRONG_ENCRYPTION_FLAG = 1 << 6;
var UFT8_NAMES_FLAG = 1 << 11;
var GeneralPurposeBit = module.exports = function() {
if (!(this instanceof GeneralPurposeBit)) {
return new GeneralPurposeBit();
}
this.descriptor = false;
this.encryption = false;
this.utf8 = false;
this.numberOfShannonFanoTrees = 0;
this.strongEncryption = false;
this.slidingDictionarySize = 0;
return this;
};
GeneralPurposeBit.prototype.encode = function() {
return zipUtil.getShortBytes(
(this.descriptor ? DATA_DESCRIPTOR_FLAG : 0) |
(this.utf8 ? UFT8_NAMES_FLAG : 0) |
(this.encryption ? ENCRYPTION_FLAG : 0) |
(this.strongEncryption ? STRONG_ENCRYPTION_FLAG : 0)
);
};
GeneralPurposeBit.prototype.parse = function(buf, offset) {
var flag = zipUtil.getShortBytesValue(buf, offset);
var gbp = new GeneralPurposeBit();
gbp.useDataDescriptor((flag & DATA_DESCRIPTOR_FLAG) !== 0);
gbp.useUTF8ForNames((flag & UFT8_NAMES_FLAG) !== 0);
gbp.useStrongEncryption((flag & STRONG_ENCRYPTION_FLAG) !== 0);
gbp.useEncryption((flag & ENCRYPTION_FLAG) !== 0);
gbp.setSlidingDictionarySize((flag & SLIDING_DICTIONARY_SIZE_FLAG) !== 0 ? 8192 : 4096);
gbp.setNumberOfShannonFanoTrees((flag & NUMBER_OF_SHANNON_FANO_TREES_FLAG) !== 0 ? 3 : 2);
return gbp;
};
GeneralPurposeBit.prototype.setNumberOfShannonFanoTrees = function(n) {
this.numberOfShannonFanoTrees = n;
};
GeneralPurposeBit.prototype.getNumberOfShannonFanoTrees = function() {
return this.numberOfShannonFanoTrees;
};
GeneralPurposeBit.prototype.setSlidingDictionarySize = function(n) {
this.slidingDictionarySize = n;
};
GeneralPurposeBit.prototype.getSlidingDictionarySize = function() {
return this.slidingDictionarySize;
};
GeneralPurposeBit.prototype.useDataDescriptor = function(b) {
this.descriptor = b;
};
GeneralPurposeBit.prototype.usesDataDescriptor = function() {
return this.descriptor;
};
GeneralPurposeBit.prototype.useEncryption = function(b) {
this.encryption = b;
};
GeneralPurposeBit.prototype.usesEncryption = function() {
return this.encryption;
};
GeneralPurposeBit.prototype.useStrongEncryption = function(b) {
this.strongEncryption = b;
};
GeneralPurposeBit.prototype.usesStrongEncryption = function() {
return this.strongEncryption;
};
GeneralPurposeBit.prototype.useUTF8ForNames = function(b) {
this.utf8 = b;
};
GeneralPurposeBit.prototype.usesUTF8ForNames = function() {
return this.utf8;
};

View File

@ -0,0 +1,53 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
module.exports = {
/**
* Bits used for permissions (and sticky bit)
*/
PERM_MASK: 4095, // 07777
/**
* Bits used to indicate the filesystem object type.
*/
FILE_TYPE_FLAG: 61440, // 0170000
/**
* Indicates symbolic links.
*/
LINK_FLAG: 40960, // 0120000
/**
* Indicates plain files.
*/
FILE_FLAG: 32768, // 0100000
/**
* Indicates directories.
*/
DIR_FLAG: 16384, // 040000
// ----------------------------------------------------------
// somewhat arbitrary choices that are quite common for shared
// installations
// -----------------------------------------------------------
/**
* Default permissions for symbolic links.
*/
DEFAULT_LINK_PERM: 511, // 0777
/**
* Default permissions for directories.
*/
DEFAULT_DIR_PERM: 493, // 0755
/**
* Default permissions for plain files.
*/
DEFAULT_FILE_PERM: 420 // 0644
};

View File

@ -0,0 +1,74 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
var util = module.exports = {};
util.dateToDos = function(d, forceLocalTime) {
forceLocalTime = forceLocalTime || false;
var year = forceLocalTime ? d.getFullYear() : d.getUTCFullYear();
if (year < 1980) {
return 2162688; // 1980-1-1 00:00:00
} else if (year >= 2044) {
return 2141175677; // 2043-12-31 23:59:58
}
var val = {
year: year,
month: forceLocalTime ? d.getMonth() : d.getUTCMonth(),
date: forceLocalTime ? d.getDate() : d.getUTCDate(),
hours: forceLocalTime ? d.getHours() : d.getUTCHours(),
minutes: forceLocalTime ? d.getMinutes() : d.getUTCMinutes(),
seconds: forceLocalTime ? d.getSeconds() : d.getUTCSeconds()
};
return ((val.year - 1980) << 25) | ((val.month + 1) << 21) | (val.date << 16) |
(val.hours << 11) | (val.minutes << 5) | (val.seconds / 2);
};
util.dosToDate = function(dos) {
return new Date(((dos >> 25) & 0x7f) + 1980, ((dos >> 21) & 0x0f) - 1, (dos >> 16) & 0x1f, (dos >> 11) & 0x1f, (dos >> 5) & 0x3f, (dos & 0x1f) << 1);
};
util.fromDosTime = function(buf) {
return util.dosToDate(buf.readUInt32LE(0));
};
util.getEightBytes = function(v) {
var buf = Buffer.alloc(8);
buf.writeUInt32LE(v % 0x0100000000, 0);
buf.writeUInt32LE((v / 0x0100000000) | 0, 4);
return buf;
};
util.getShortBytes = function(v) {
var buf = Buffer.alloc(2);
buf.writeUInt16LE((v & 0xFFFF) >>> 0, 0);
return buf;
};
util.getShortBytesValue = function(buf, offset) {
return buf.readUInt16LE(offset);
};
util.getLongBytes = function(v) {
var buf = Buffer.alloc(4);
buf.writeUInt32LE((v & 0xFFFFFFFF) >>> 0, 0);
return buf;
};
util.getLongBytesValue = function(buf, offset) {
return buf.readUInt32LE(offset);
};
util.toDosTime = function(d) {
return util.getLongBytes(util.dateToDos(d));
};

View File

@ -0,0 +1,413 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
var inherits = require('util').inherits;
var normalizePath = require('../../../normalize-path');
var ArchiveEntry = require('../archive-entry');
var GeneralPurposeBit = require('./general-purpose-bit');
var UnixStat = require('./unix-stat');
var constants = require('./constants');
var zipUtil = require('./util');
var ZipArchiveEntry = module.exports = function (name) {
if (!(this instanceof ZipArchiveEntry)) {
return new ZipArchiveEntry(name);
}
ArchiveEntry.call(this);
this.platform = constants.PLATFORM_FAT;
this.method = -1;
this.name = null;
this.size = 0;
this.csize = 0;
this.gpb = new GeneralPurposeBit();
this.crc = 0;
this.time = -1;
this.minver = constants.MIN_VERSION_INITIAL;
this.mode = -1;
this.extra = null;
this.exattr = 0;
this.inattr = 0;
this.comment = null;
if (name) {
this.setName(name);
}
};
inherits(ZipArchiveEntry, ArchiveEntry);
/**
* Returns the extra fields related to the entry.
*
* @returns {Buffer}
*/
ZipArchiveEntry.prototype.getCentralDirectoryExtra = function () {
return this.getExtra();
};
/**
* Returns the comment set for the entry.
*
* @returns {string}
*/
ZipArchiveEntry.prototype.getComment = function () {
return this.comment !== null ? this.comment : '';
};
/**
* Returns the compressed size of the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getCompressedSize = function () {
return this.csize;
};
/**
* Returns the CRC32 digest for the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getCrc = function () {
return this.crc;
};
/**
* Returns the external file attributes for the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getExternalAttributes = function () {
return this.exattr;
};
/**
* Returns the extra fields related to the entry.
*
* @returns {Buffer}
*/
ZipArchiveEntry.prototype.getExtra = function () {
return this.extra !== null ? this.extra : constants.EMPTY;
};
/**
* Returns the general purpose bits related to the entry.
*
* @returns {GeneralPurposeBit}
*/
ZipArchiveEntry.prototype.getGeneralPurposeBit = function () {
return this.gpb;
};
/**
* Returns the internal file attributes for the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getInternalAttributes = function () {
return this.inattr;
};
/**
* Returns the last modified date of the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getLastModifiedDate = function () {
return this.getTime();
};
/**
* Returns the extra fields related to the entry.
*
* @returns {Buffer}
*/
ZipArchiveEntry.prototype.getLocalFileDataExtra = function () {
return this.getExtra();
};
/**
* Returns the compression method used on the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getMethod = function () {
return this.method;
};
/**
* Returns the filename of the entry.
*
* @returns {string}
*/
ZipArchiveEntry.prototype.getName = function () {
return this.name;
};
/**
* Returns the platform on which the entry was made.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getPlatform = function () {
return this.platform;
};
/**
* Returns the size of the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getSize = function () {
return this.size;
};
/**
* Returns a date object representing the last modified date of the entry.
*
* @returns {number|Date}
*/
ZipArchiveEntry.prototype.getTime = function () {
return this.time !== -1 ? zipUtil.dosToDate(this.time) : -1;
};
/**
* Returns the DOS timestamp for the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getTimeDos = function () {
return this.time !== -1 ? this.time : 0;
};
/**
* Returns the UNIX file permissions for the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getUnixMode = function () {
return this.platform !== constants.PLATFORM_UNIX ? 0 : ((this.getExternalAttributes() >> constants.SHORT_SHIFT) & constants.SHORT_MASK);
};
/**
* Returns the version of ZIP needed to extract the entry.
*
* @returns {number}
*/
ZipArchiveEntry.prototype.getVersionNeededToExtract = function () {
return this.minver;
};
/**
* Sets the comment of the entry.
*
* @param comment
*/
ZipArchiveEntry.prototype.setComment = function (comment) {
if (Buffer.byteLength(comment) !== comment.length) {
this.getGeneralPurposeBit().useUTF8ForNames(true);
}
this.comment = comment;
};
/**
* Sets the compressed size of the entry.
*
* @param size
*/
ZipArchiveEntry.prototype.setCompressedSize = function (size) {
if (size < 0) {
throw new Error('invalid entry compressed size');
}
this.csize = size;
};
/**
* Sets the checksum of the entry.
*
* @param crc
*/
ZipArchiveEntry.prototype.setCrc = function (crc) {
if (crc < 0) {
throw new Error('invalid entry crc32');
}
this.crc = crc;
};
/**
* Sets the external file attributes of the entry.
*
* @param attr
*/
ZipArchiveEntry.prototype.setExternalAttributes = function (attr) {
this.exattr = attr >>> 0;
};
/**
* Sets the extra fields related to the entry.
*
* @param extra
*/
ZipArchiveEntry.prototype.setExtra = function (extra) {
this.extra = extra;
};
/**
* Sets the general purpose bits related to the entry.
*
* @param gpb
*/
ZipArchiveEntry.prototype.setGeneralPurposeBit = function (gpb) {
if (!(gpb instanceof GeneralPurposeBit)) {
throw new Error('invalid entry GeneralPurposeBit');
}
this.gpb = gpb;
};
/**
* Sets the internal file attributes of the entry.
*
* @param attr
*/
ZipArchiveEntry.prototype.setInternalAttributes = function (attr) {
this.inattr = attr;
};
/**
* Sets the compression method of the entry.
*
* @param method
*/
ZipArchiveEntry.prototype.setMethod = function (method) {
if (method < 0) {
throw new Error('invalid entry compression method');
}
this.method = method;
};
/**
* Sets the name of the entry.
*
* @param name
* @param prependSlash
*/
ZipArchiveEntry.prototype.setName = function (name, prependSlash = false) {
name = normalizePath(name, false)
.replace(/^\w+:/, '')
.replace(/^(\.\.\/|\/)+/, '');
if (prependSlash) {
name = `/${name}`;
}
if (Buffer.byteLength(name) !== name.length) {
this.getGeneralPurposeBit().useUTF8ForNames(true);
}
this.name = name;
};
/**
* Sets the platform on which the entry was made.
*
* @param platform
*/
ZipArchiveEntry.prototype.setPlatform = function (platform) {
this.platform = platform;
};
/**
* Sets the size of the entry.
*
* @param size
*/
ZipArchiveEntry.prototype.setSize = function (size) {
if (size < 0) {
throw new Error('invalid entry size');
}
this.size = size;
};
/**
* Sets the time of the entry.
*
* @param time
* @param forceLocalTime
*/
ZipArchiveEntry.prototype.setTime = function (time, forceLocalTime) {
if (!(time instanceof Date)) {
throw new Error('invalid entry time');
}
this.time = zipUtil.dateToDos(time, forceLocalTime);
};
/**
* Sets the UNIX file permissions for the entry.
*
* @param mode
*/
ZipArchiveEntry.prototype.setUnixMode = function (mode) {
mode |= this.isDirectory() ? constants.S_IFDIR : constants.S_IFREG;
var extattr = 0;
extattr |= (mode << constants.SHORT_SHIFT) | (this.isDirectory() ? constants.S_DOS_D : constants.S_DOS_A);
this.setExternalAttributes(extattr);
this.mode = mode & constants.MODE_MASK;
this.platform = constants.PLATFORM_UNIX;
};
/**
* Sets the version of ZIP needed to extract this entry.
*
* @param minver
*/
ZipArchiveEntry.prototype.setVersionNeededToExtract = function (minver) {
this.minver = minver;
};
/**
* Returns true if this entry represents a directory.
*
* @returns {boolean}
*/
ZipArchiveEntry.prototype.isDirectory = function () {
return this.getName().slice(-1) === '/';
};
/**
* Returns true if this entry represents a unix symlink,
* in which case the entry's content contains the target path
* for the symlink.
*
* @returns {boolean}
*/
ZipArchiveEntry.prototype.isUnixSymlink = function () {
return (this.getUnixMode() & UnixStat.FILE_TYPE_FLAG) === UnixStat.LINK_FLAG;
};
/**
* Returns true if this entry is using the ZIP64 extension of ZIP.
*
* @returns {boolean}
*/
ZipArchiveEntry.prototype.isZip64 = function () {
return this.csize > constants.ZIP64_MAGIC || this.size > constants.ZIP64_MAGIC;
};

View File

@ -0,0 +1,437 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
var inherits = require('util').inherits;
var crc32 = require('../../../buffer-crc32');
var { CRC32Stream } = require('../../../crc32-stream');
var { DeflateCRC32Stream } = require('../../../crc32-stream');
var ArchiveOutputStream = require('../archive-output-stream');
var constants = require('./constants');
var zipUtil = require('./util');
var ZipArchiveOutputStream = module.exports = function (options) {
if (!(this instanceof ZipArchiveOutputStream)) {
return new ZipArchiveOutputStream(options);
}
options = this.options = this._defaults(options);
ArchiveOutputStream.call(this, options);
this._entry = null;
this._entries = [];
this._archive = {
centralLength: 0,
centralOffset: 0,
comment: '',
finish: false,
finished: false,
processing: false,
forceZip64: options.forceZip64,
forceLocalTime: options.forceLocalTime
};
};
inherits(ZipArchiveOutputStream, ArchiveOutputStream);
ZipArchiveOutputStream.prototype._afterAppend = function (ae) {
this._entries.push(ae);
if (ae.getGeneralPurposeBit().usesDataDescriptor()) {
this._writeDataDescriptor(ae);
}
this._archive.processing = false;
this._entry = null;
if (this._archive.finish && !this._archive.finished) {
this._finish();
}
};
ZipArchiveOutputStream.prototype._appendBuffer = function (ae, source, callback) {
if (source.length === 0) {
ae.setMethod(constants.METHOD_STORED);
}
var method = ae.getMethod();
if (method === constants.METHOD_STORED) {
ae.setSize(source.length);
ae.setCompressedSize(source.length);
ae.setCrc(crc32.unsigned(source));
}
this._writeLocalFileHeader(ae);
if (method === constants.METHOD_STORED) {
this.write(source);
this._afterAppend(ae);
callback(null, ae);
return;
} else if (method === constants.METHOD_DEFLATED) {
this._smartStream(ae, callback).end(source);
return;
} else {
callback(new Error('compression method ' + method + ' not implemented'));
return;
}
};
ZipArchiveOutputStream.prototype._appendStream = function (ae, source, callback) {
ae.getGeneralPurposeBit().useDataDescriptor(true);
ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
this._writeLocalFileHeader(ae);
var smart = this._smartStream(ae, callback);
source.once('error', function (err) {
smart.emit('error', err);
smart.end();
})
source.pipe(smart);
};
ZipArchiveOutputStream.prototype._defaults = function (o) {
if (typeof o !== 'object') {
o = {};
}
if (typeof o.zlib !== 'object') {
o.zlib = {};
}
if (typeof o.zlib.level !== 'number') {
o.zlib.level = constants.ZLIB_BEST_SPEED;
}
o.forceZip64 = !!o.forceZip64;
o.forceLocalTime = !!o.forceLocalTime;
return o;
};
ZipArchiveOutputStream.prototype._finish = function () {
this._archive.centralOffset = this.offset;
this._entries.forEach(function (ae) {
this._writeCentralFileHeader(ae);
}.bind(this));
this._archive.centralLength = this.offset - this._archive.centralOffset;
if (this.isZip64()) {
this._writeCentralDirectoryZip64();
}
this._writeCentralDirectoryEnd();
this._archive.processing = false;
this._archive.finish = true;
this._archive.finished = true;
this.end();
};
ZipArchiveOutputStream.prototype._normalizeEntry = function (ae) {
if (ae.getMethod() === -1) {
ae.setMethod(constants.METHOD_DEFLATED);
}
if (ae.getMethod() === constants.METHOD_DEFLATED) {
ae.getGeneralPurposeBit().useDataDescriptor(true);
ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
}
if (ae.getTime() === -1) {
ae.setTime(new Date(), this._archive.forceLocalTime);
}
ae._offsets = {
file: 0,
data: 0,
contents: 0,
};
};
ZipArchiveOutputStream.prototype._smartStream = function (ae, callback) {
var deflate = ae.getMethod() === constants.METHOD_DEFLATED;
var process = deflate ? new DeflateCRC32Stream(this.options.zlib) : new CRC32Stream();
var error = null;
function handleStuff() {
var digest = process.digest().readUInt32BE(0);
ae.setCrc(digest);
ae.setSize(process.size());
ae.setCompressedSize(process.size(true));
this._afterAppend(ae);
callback(error, ae);
}
process.once('end', handleStuff.bind(this));
process.once('error', function (err) {
error = err;
});
process.pipe(this, { end: false });
return process;
};
ZipArchiveOutputStream.prototype._writeCentralDirectoryEnd = function () {
var records = this._entries.length;
var size = this._archive.centralLength;
var offset = this._archive.centralOffset;
if (this.isZip64()) {
records = constants.ZIP64_MAGIC_SHORT;
size = constants.ZIP64_MAGIC;
offset = constants.ZIP64_MAGIC;
}
// signature
this.write(zipUtil.getLongBytes(constants.SIG_EOCD));
// disk numbers
this.write(constants.SHORT_ZERO);
this.write(constants.SHORT_ZERO);
// number of entries
this.write(zipUtil.getShortBytes(records));
this.write(zipUtil.getShortBytes(records));
// length and location of CD
this.write(zipUtil.getLongBytes(size));
this.write(zipUtil.getLongBytes(offset));
// archive comment
var comment = this.getComment();
var commentLength = Buffer.byteLength(comment);
this.write(zipUtil.getShortBytes(commentLength));
this.write(comment);
};
ZipArchiveOutputStream.prototype._writeCentralDirectoryZip64 = function () {
// signature
this.write(zipUtil.getLongBytes(constants.SIG_ZIP64_EOCD));
// size of the ZIP64 EOCD record
this.write(zipUtil.getEightBytes(44));
// version made by
this.write(zipUtil.getShortBytes(constants.MIN_VERSION_ZIP64));
// version to extract
this.write(zipUtil.getShortBytes(constants.MIN_VERSION_ZIP64));
// disk numbers
this.write(constants.LONG_ZERO);
this.write(constants.LONG_ZERO);
// number of entries
this.write(zipUtil.getEightBytes(this._entries.length));
this.write(zipUtil.getEightBytes(this._entries.length));
// length and location of CD
this.write(zipUtil.getEightBytes(this._archive.centralLength));
this.write(zipUtil.getEightBytes(this._archive.centralOffset));
// extensible data sector
// not implemented at this time
// end of central directory locator
this.write(zipUtil.getLongBytes(constants.SIG_ZIP64_EOCD_LOC));
// disk number holding the ZIP64 EOCD record
this.write(constants.LONG_ZERO);
// relative offset of the ZIP64 EOCD record
this.write(zipUtil.getEightBytes(this._archive.centralOffset + this._archive.centralLength));
// total number of disks
this.write(zipUtil.getLongBytes(1));
};
ZipArchiveOutputStream.prototype._writeCentralFileHeader = function (ae) {
var gpb = ae.getGeneralPurposeBit();
var method = ae.getMethod();
var offsets = ae._offsets;
var size = ae.getSize();
var compressedSize = ae.getCompressedSize();
if (ae.isZip64() || offsets.file > constants.ZIP64_MAGIC) {
size = constants.ZIP64_MAGIC;
compressedSize = constants.ZIP64_MAGIC;
ae.setVersionNeededToExtract(constants.MIN_VERSION_ZIP64);
var extraBuf = Buffer.concat([
zipUtil.getShortBytes(constants.ZIP64_EXTRA_ID),
zipUtil.getShortBytes(24),
zipUtil.getEightBytes(ae.getSize()),
zipUtil.getEightBytes(ae.getCompressedSize()),
zipUtil.getEightBytes(offsets.file)
], 28);
ae.setExtra(extraBuf);
}
// signature
this.write(zipUtil.getLongBytes(constants.SIG_CFH));
// version made by
this.write(zipUtil.getShortBytes((ae.getPlatform() << 8) | constants.VERSION_MADEBY));
// version to extract and general bit flag
this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
this.write(gpb.encode());
// compression method
this.write(zipUtil.getShortBytes(method));
// datetime
this.write(zipUtil.getLongBytes(ae.getTimeDos()));
// crc32 checksum
this.write(zipUtil.getLongBytes(ae.getCrc()));
// sizes
this.write(zipUtil.getLongBytes(compressedSize));
this.write(zipUtil.getLongBytes(size));
var name = ae.getName();
var comment = ae.getComment();
var extra = ae.getCentralDirectoryExtra();
if (gpb.usesUTF8ForNames()) {
name = Buffer.from(name);
comment = Buffer.from(comment);
}
// name length
this.write(zipUtil.getShortBytes(name.length));
// extra length
this.write(zipUtil.getShortBytes(extra.length));
// comments length
this.write(zipUtil.getShortBytes(comment.length));
// disk number start
this.write(constants.SHORT_ZERO);
// internal attributes
this.write(zipUtil.getShortBytes(ae.getInternalAttributes()));
// external attributes
this.write(zipUtil.getLongBytes(ae.getExternalAttributes()));
// relative offset of LFH
if (offsets.file > constants.ZIP64_MAGIC) {
this.write(zipUtil.getLongBytes(constants.ZIP64_MAGIC));
} else {
this.write(zipUtil.getLongBytes(offsets.file));
}
// name
this.write(name);
// extra
this.write(extra);
// comment
this.write(comment);
};
ZipArchiveOutputStream.prototype._writeDataDescriptor = function (ae) {
// signature
this.write(zipUtil.getLongBytes(constants.SIG_DD));
// crc32 checksum
this.write(zipUtil.getLongBytes(ae.getCrc()));
// sizes
if (ae.isZip64()) {
this.write(zipUtil.getEightBytes(ae.getCompressedSize()));
this.write(zipUtil.getEightBytes(ae.getSize()));
} else {
this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
this.write(zipUtil.getLongBytes(ae.getSize()));
}
};
ZipArchiveOutputStream.prototype._writeLocalFileHeader = function (ae) {
var gpb = ae.getGeneralPurposeBit();
var method = ae.getMethod();
var name = ae.getName();
var extra = ae.getLocalFileDataExtra();
if (ae.isZip64()) {
gpb.useDataDescriptor(true);
ae.setVersionNeededToExtract(constants.MIN_VERSION_ZIP64);
}
if (gpb.usesUTF8ForNames()) {
name = Buffer.from(name);
}
ae._offsets.file = this.offset;
// signature
this.write(zipUtil.getLongBytes(constants.SIG_LFH));
// version to extract and general bit flag
this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
this.write(gpb.encode());
// compression method
this.write(zipUtil.getShortBytes(method));
// datetime
this.write(zipUtil.getLongBytes(ae.getTimeDos()));
ae._offsets.data = this.offset;
// crc32 checksum and sizes
if (gpb.usesDataDescriptor()) {
this.write(constants.LONG_ZERO);
this.write(constants.LONG_ZERO);
this.write(constants.LONG_ZERO);
} else {
this.write(zipUtil.getLongBytes(ae.getCrc()));
this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
this.write(zipUtil.getLongBytes(ae.getSize()));
}
// name length
this.write(zipUtil.getShortBytes(name.length));
// extra length
this.write(zipUtil.getShortBytes(extra.length));
// name
this.write(name);
// extra
this.write(extra);
ae._offsets.contents = this.offset;
};
ZipArchiveOutputStream.prototype.getComment = function (comment) {
return this._archive.comment !== null ? this._archive.comment : '';
};
ZipArchiveOutputStream.prototype.isZip64 = function () {
return this._archive.forceZip64 || this._entries.length > constants.ZIP64_MAGIC_SHORT || this._archive.centralLength > constants.ZIP64_MAGIC || this._archive.centralOffset > constants.ZIP64_MAGIC;
};
ZipArchiveOutputStream.prototype.setComment = function (comment) {
this._archive.comment = comment;
};

View File

@ -0,0 +1,13 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
module.exports = {
ArchiveEntry: require('./archivers/archive-entry'),
ZipArchiveEntry: require('./archivers/zip/zip-archive-entry'),
ArchiveOutputStream: require('./archivers/archive-output-stream'),
ZipArchiveOutputStream: require('./archivers/zip/zip-archive-output-stream')
};

View File

@ -0,0 +1,30 @@
/**
* node-compress-commons
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
*/
var Stream = require('stream').Stream;
var PassThrough = require('readable-stream').PassThrough;
var util = module.exports = {};
util.isStream = function(source) {
return source instanceof Stream;
};
util.normalizeInputSource = function(source) {
if (source === null) {
return Buffer.alloc(0);
} else if (typeof source === 'string') {
return Buffer.from(source);
} else if (util.isStream(source) && !source._readableState) {
var normalized = new PassThrough();
source.pipe(normalized);
return normalized;
}
return source;
};

View File

@ -0,0 +1,22 @@
Copyright (c) 2014 Chris Talkington, contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,48 @@
/**
* node-crc32-stream
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-crc32-stream/blob/master/LICENSE-MIT
*/
'use strict';
const { Transform } = require('readable-stream');
const crc32 = require('../crc32');
class CRC32Stream extends Transform {
constructor(options) {
super(options);
this.checksum = Buffer.allocUnsafe(4);
this.checksum.writeInt32BE(0, 0);
this.rawSize = 0;
}
_transform(chunk, encoding, callback) {
if (chunk) {
this.checksum = crc32.buf(chunk, this.checksum) >>> 0;
this.rawSize += chunk.length;
}
callback(null, chunk);
}
digest(encoding) {
const checksum = Buffer.allocUnsafe(4);
checksum.writeUInt32BE(this.checksum >>> 0, 0);
return encoding ? checksum.toString(encoding) : checksum;
}
hex() {
return this.digest('hex').toUpperCase();
}
size() {
return this.rawSize;
}
}
module.exports = CRC32Stream;

View File

@ -0,0 +1,62 @@
/**
* node-crc32-stream
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-crc32-stream/blob/master/LICENSE-MIT
*/
'use strict';
const { DeflateRaw } = require('zlib');
const crc32 = require('../crc32');
class DeflateCRC32Stream extends DeflateRaw {
constructor(options) {
super(options);
this.checksum = Buffer.allocUnsafe(4);
this.checksum.writeInt32BE(0, 0);
this.rawSize = 0;
this.compressedSize = 0;
}
push(chunk, encoding) {
if (chunk) {
this.compressedSize += chunk.length;
}
return super.push(chunk, encoding);
}
_transform(chunk, encoding, callback) {
if (chunk) {
this.checksum = crc32.buf(chunk, this.checksum) >>> 0;
this.rawSize += chunk.length;
}
super._transform(chunk, encoding, callback)
}
digest(encoding) {
const checksum = Buffer.allocUnsafe(4);
checksum.writeUInt32BE(this.checksum >>> 0, 0);
return encoding ? checksum.toString(encoding) : checksum;
}
hex() {
return this.digest('hex').toUpperCase();
}
size(compressed = false) {
if (compressed) {
return this.compressedSize;
} else {
return this.rawSize;
}
}
}
module.exports = DeflateCRC32Stream;

View File

@ -0,0 +1,14 @@
/**
* node-crc32-stream
*
* Copyright (c) 2014 Chris Talkington, contributors.
* Licensed under the MIT license.
* https://github.com/archiverjs/node-crc32-stream/blob/master/LICENSE-MIT
*/
'use strict';
module.exports = {
CRC32Stream: require('./crc32-stream'),
DeflateCRC32Stream: require('./deflate-crc32-stream')
}

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (C) 2014-present SheetJS LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,115 @@
/*! crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
/*exported CRC32 */
var CRC32;
(function (factory) {
/*jshint ignore:start */
/*eslint-disable */
if(typeof DO_NOT_EXPORT_CRC === 'undefined') {
if('object' === typeof exports) {
factory(exports);
} else if ('function' === typeof define && define.amd) {
define(function () {
var module = {};
factory(module);
return module;
});
} else {
factory(CRC32 = {});
}
} else {
factory(CRC32 = {});
}
/*eslint-enable */
/*jshint ignore:end */
}(function(CRC32) {
CRC32.version = '1.2.2';
/*global Int32Array */
function signed_crc_table() {
var c = 0, table = new Array(256);
for(var n =0; n != 256; ++n){
c = n;
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
table[n] = c;
}
return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table;
}
var T0 = signed_crc_table();
function slice_by_16_tables(T) {
var c = 0, v = 0, n = 0, table = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ;
for(n = 0; n != 256; ++n) table[n] = T[n];
for(n = 0; n != 256; ++n) {
v = T[n];
for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF];
}
var out = [];
for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256);
return out;
}
var TT = slice_by_16_tables(T0);
var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4];
var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9];
var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14];
function crc32_bstr(bstr, seed) {
var C = seed ^ -1;
for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF];
return ~C;
}
function crc32_buf(B, seed) {
var C = seed ^ -1, L = B.length - 15, i = 0;
for(; i < L;) C =
Tf[B[i++] ^ (C & 255)] ^
Te[B[i++] ^ ((C >> 8) & 255)] ^
Td[B[i++] ^ ((C >> 16) & 255)] ^
Tc[B[i++] ^ (C >>> 24)] ^
Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^
T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^
T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]];
L += 15;
while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF];
return ~C;
}
function crc32_str(str, seed) {
var C = seed ^ -1;
for(var i = 0, L = str.length, c = 0, d = 0; i < L;) {
c = str.charCodeAt(i++);
if(c < 0x80) {
C = (C>>>8) ^ T0[(C^c)&0xFF];
} else if(c < 0x800) {
C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF];
C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF];
} else if(c >= 0xD800 && c < 0xE000) {
c = (c&1023)+64; d = str.charCodeAt(i++)&1023;
C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF];
C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF];
C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF];
C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF];
} else {
C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF];
C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF];
C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF];
}
}
return ~C;
}
CRC32.table = T0;
// $FlowIgnore
CRC32.bstr = crc32_bstr;
// $FlowIgnore
CRC32.buf = crc32_buf;
// $FlowIgnore
CRC32.str = crc32_str;
}));

View File

@ -0,0 +1,83 @@
/**
* Archiver Vending
*
* @ignore
* @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
* @copyright (c) 2012-2014 Chris Talkington, contributors.
*/
var Archiver = require('./lib/core');
var formats = {};
/**
* Dispenses a new Archiver instance.
*
* @constructor
* @param {String} format The archive format to use.
* @param {Object} options See [Archiver]{@link Archiver}
* @return {Archiver}
*/
var vending = function (format, options) {
return vending.create(format, options);
};
/**
* Creates a new Archiver instance.
*
* @param {String} format The archive format to use.
* @param {Object} options See [Archiver]{@link Archiver}
* @return {Archiver}
*/
vending.create = function (format, options) {
if (formats[format]) {
var instance = new Archiver(format, options);
instance.setFormat(format);
instance.setModule(new formats[format](options));
return instance;
} else {
throw new Error('create(' + format + '): format not registered');
}
};
/**
* Registers a format for use with archiver.
*
* @param {String} format The name of the format.
* @param {Function} module The function for archiver to interact with.
* @return void
*/
vending.registerFormat = function (format, module) {
if (formats[format]) {
throw new Error('register(' + format + '): format already registered');
}
if (typeof module !== 'function') {
throw new Error('register(' + format + '): format module invalid');
}
if (typeof module.prototype.append !== 'function' || typeof module.prototype.finalize !== 'function') {
throw new Error('register(' + format + '): format module missing methods');
}
formats[format] = module;
};
/**
* Check if the format is already registered.
*
* @param {String} format the name of the format.
* @return boolean
*/
vending.isRegisteredFormat = function (format) {
if (formats[format]) {
return true;
}
return false;
};
vending.registerFormat('zip', require('./lib/plugins/zip'));
vending.registerFormat('json', require('./lib/plugins/json'));
module.exports = vending;

View File

@ -0,0 +1,974 @@
/**
* Archiver Core
*
* @ignore
* @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
* @copyright (c) 2012-2014 Chris Talkington, contributors.
*/
var fs = require('fs');
var glob = require('../readdir-glob');
var async = require('../../async');
var path = require('path');
var util = require('archiver-utils');
var inherits = require('util').inherits;
var ArchiverError = require('./error');
var Transform = require('readable-stream').Transform;
var win32 = process.platform === 'win32';
/**
* @constructor
* @param {String} format The archive format to use.
* @param {(CoreOptions|TransformOptions)} options See also {@link ZipOptions} and {@link TarOptions}.
*/
var Archiver = function (format, options) {
if (!(this instanceof Archiver)) {
return new Archiver(format, options);
}
if (typeof format !== 'string') {
options = format;
format = 'zip';
}
options = this.options = util.defaults(options, {
highWaterMark: 1024 * 1024,
statConcurrency: 4
});
Transform.call(this, options);
this._format = false;
this._module = false;
this._pending = 0;
this._pointer = 0;
this._entriesCount = 0;
this._entriesProcessedCount = 0;
this._fsEntriesTotalBytes = 0;
this._fsEntriesProcessedBytes = 0;
this._queue = async.queue(this._onQueueTask.bind(this), 1);
this._queue.drain(this._onQueueDrain.bind(this));
this._statQueue = async.queue(this._onStatQueueTask.bind(this), options.statConcurrency);
this._statQueue.drain(this._onQueueDrain.bind(this));
this._state = {
aborted: false,
finalize: false,
finalizing: false,
finalized: false,
modulePiped: false
};
this._streams = [];
};
inherits(Archiver, Transform);
/**
* Internal logic for `abort`.
*
* @private
* @return void
*/
Archiver.prototype._abort = function () {
this._state.aborted = true;
this._queue.kill();
this._statQueue.kill();
if (this._queue.idle()) {
this._shutdown();
}
};
/**
* Internal helper for appending files.
*
* @private
* @param {String} filepath The source filepath.
* @param {EntryData} data The entry data.
* @return void
*/
Archiver.prototype._append = function (filepath, data) {
data = data || {};
var task = {
source: null,
filepath: filepath
};
if (!data.name) {
data.name = filepath;
}
data.sourcePath = filepath;
task.data = data;
this._entriesCount++;
if (data.stats && data.stats instanceof fs.Stats) {
task = this._updateQueueTaskWithStats(task, data.stats);
if (task) {
if (data.stats.size) {
this._fsEntriesTotalBytes += data.stats.size;
}
this._queue.push(task);
}
} else {
this._statQueue.push(task);
}
};
/**
* Internal logic for `finalize`.
*
* @private
* @return void
*/
Archiver.prototype._finalize = function () {
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
return;
}
this._state.finalizing = true;
this._moduleFinalize();
this._state.finalizing = false;
this._state.finalized = true;
};
/**
* Checks the various state variables to determine if we can `finalize`.
*
* @private
* @return {Boolean}
*/
Archiver.prototype._maybeFinalize = function () {
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
return false;
}
if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
this._finalize();
return true;
}
return false;
};
/**
* Appends an entry to the module.
*
* @private
* @fires Archiver#entry
* @param {(Buffer|Stream)} source
* @param {EntryData} data
* @param {Function} callback
* @return void
*/
Archiver.prototype._moduleAppend = function (source, data, callback) {
if (this._state.aborted) {
callback();
return;
}
this._module.append(source, data, function (err) {
this._task = null;
if (this._state.aborted) {
this._shutdown();
return;
}
if (err) {
this.emit('error', err);
setImmediate(callback);
return;
}
/**
* Fires when the entry's input has been processed and appended to the archive.
*
* @event Archiver#entry
* @type {EntryData}
*/
this.emit('entry', data);
this._entriesProcessedCount++;
if (data.stats && data.stats.size) {
this._fsEntriesProcessedBytes += data.stats.size;
}
/**
* @event Archiver#progress
* @type {ProgressData}
*/
this.emit('progress', {
entries: {
total: this._entriesCount,
processed: this._entriesProcessedCount
},
fs: {
totalBytes: this._fsEntriesTotalBytes,
processedBytes: this._fsEntriesProcessedBytes
}
});
setImmediate(callback);
}.bind(this));
};
/**
* Finalizes the module.
*
* @private
* @return void
*/
Archiver.prototype._moduleFinalize = function () {
if (typeof this._module.finalize === 'function') {
this._module.finalize();
} else if (typeof this._module.end === 'function') {
this._module.end();
} else {
this.emit('error', new ArchiverError('NOENDMETHOD'));
}
};
/**
* Pipes the module to our internal stream with error bubbling.
*
* @private
* @return void
*/
Archiver.prototype._modulePipe = function () {
this._module.on('error', this._onModuleError.bind(this));
this._module.pipe(this);
this._state.modulePiped = true;
};
/**
* Determines if the current module supports a defined feature.
*
* @private
* @param {String} key
* @return {Boolean}
*/
Archiver.prototype._moduleSupports = function (key) {
if (!this._module.supports || !this._module.supports[key]) {
return false;
}
return this._module.supports[key];
};
/**
* Unpipes the module from our internal stream.
*
* @private
* @return void
*/
Archiver.prototype._moduleUnpipe = function () {
this._module.unpipe(this);
this._state.modulePiped = false;
};
/**
* Normalizes entry data with fallbacks for key properties.
*
* @private
* @param {Object} data
* @param {fs.Stats} stats
* @return {Object}
*/
Archiver.prototype._normalizeEntryData = function (data, stats) {
data = util.defaults(data, {
type: 'file',
name: null,
date: null,
mode: null,
prefix: null,
sourcePath: null,
stats: false
});
if (stats && data.stats === false) {
data.stats = stats;
}
var isDir = data.type === 'directory';
if (data.name) {
if (typeof data.prefix === 'string' && '' !== data.prefix) {
data.name = data.prefix + '/' + data.name;
data.prefix = null;
}
data.name = util.sanitizePath(data.name);
if (data.type !== 'symlink' && data.name.slice(-1) === '/') {
isDir = true;
data.type = 'directory';
} else if (isDir) {
data.name += '/';
}
}
// 511 === 0777; 493 === 0755; 438 === 0666; 420 === 0644
if (typeof data.mode === 'number') {
if (win32) {
data.mode &= 511;
} else {
data.mode &= 4095
}
} else if (data.stats && data.mode === null) {
if (win32) {
data.mode = data.stats.mode & 511;
} else {
data.mode = data.stats.mode & 4095;
}
// stat isn't reliable on windows; force 0755 for dir
if (win32 && isDir) {
data.mode = 493;
}
} else if (data.mode === null) {
data.mode = isDir ? 493 : 420;
}
if (data.stats && data.date === null) {
data.date = data.stats.mtime;
} else {
data.date = util.dateify(data.date);
}
return data;
};
/**
* Error listener that re-emits error on to our internal stream.
*
* @private
* @param {Error} err
* @return void
*/
Archiver.prototype._onModuleError = function (err) {
/**
* @event Archiver#error
* @type {ErrorData}
*/
this.emit('error', err);
};
/**
* Checks the various state variables after queue has drained to determine if
* we need to `finalize`.
*
* @private
* @return void
*/
Archiver.prototype._onQueueDrain = function () {
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
return;
}
if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
this._finalize();
}
};
/**
* Appends each queue task to the module.
*
* @private
* @param {Object} task
* @param {Function} callback
* @return void
*/
Archiver.prototype._onQueueTask = function (task, callback) {
var fullCallback = () => {
if (task.data.callback) {
task.data.callback();
}
callback();
}
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
fullCallback();
return;
}
this._task = task;
this._moduleAppend(task.source, task.data, fullCallback);
};
/**
* Performs a file stat and reinjects the task back into the queue.
*
* @private
* @param {Object} task
* @param {Function} callback
* @return void
*/
Archiver.prototype._onStatQueueTask = function (task, callback) {
if (this._state.finalizing || this._state.finalized || this._state.aborted) {
callback();
return;
}
fs.lstat(task.filepath, function (err, stats) {
if (this._state.aborted) {
setImmediate(callback);
return;
}
if (err) {
this._entriesCount--;
/**
* @event Archiver#warning
* @type {ErrorData}
*/
this.emit('warning', err);
setImmediate(callback);
return;
}
task = this._updateQueueTaskWithStats(task, stats);
if (task) {
if (stats.size) {
this._fsEntriesTotalBytes += stats.size;
}
this._queue.push(task);
}
setImmediate(callback);
}.bind(this));
};
/**
* Unpipes the module and ends our internal stream.
*
* @private
* @return void
*/
Archiver.prototype._shutdown = function () {
this._moduleUnpipe();
this.end();
};
/**
* Tracks the bytes emitted by our internal stream.
*
* @private
* @param {Buffer} chunk
* @param {String} encoding
* @param {Function} callback
* @return void
*/
Archiver.prototype._transform = function (chunk, encoding, callback) {
if (chunk) {
this._pointer += chunk.length;
}
callback(null, chunk);
};
/**
* Updates and normalizes a queue task using stats data.
*
* @private
* @param {Object} task
* @param {fs.Stats} stats
* @return {Object}
*/
Archiver.prototype._updateQueueTaskWithStats = function (task, stats) {
if (stats.isFile()) {
task.data.type = 'file';
task.data.sourceType = 'stream';
task.source = util.lazyReadStream(task.filepath);
} else if (stats.isDirectory() && this._moduleSupports('directory')) {
task.data.name = util.trailingSlashIt(task.data.name);
task.data.type = 'directory';
task.data.sourcePath = util.trailingSlashIt(task.filepath);
task.data.sourceType = 'buffer';
task.source = Buffer.concat([]);
} else if (stats.isSymbolicLink() && this._moduleSupports('symlink')) {
var linkPath = fs.readlinkSync(task.filepath);
var dirName = path.dirname(task.filepath);
task.data.type = 'symlink';
task.data.linkname = path.relative(dirName, path.resolve(dirName, linkPath));
task.data.sourceType = 'buffer';
task.source = Buffer.concat([]);
} else {
if (stats.isDirectory()) {
this.emit('warning', new ArchiverError('DIRECTORYNOTSUPPORTED', task.data));
} else if (stats.isSymbolicLink()) {
this.emit('warning', new ArchiverError('SYMLINKNOTSUPPORTED', task.data));
} else {
this.emit('warning', new ArchiverError('ENTRYNOTSUPPORTED', task.data));
}
return null;
}
task.data = this._normalizeEntryData(task.data, stats);
return task;
};
/**
* Aborts the archiving process, taking a best-effort approach, by:
*
* - removing any pending queue tasks
* - allowing any active queue workers to finish
* - detaching internal module pipes
* - ending both sides of the Transform stream
*
* It will NOT drain any remaining sources.
*
* @return {this}
*/
Archiver.prototype.abort = function () {
if (this._state.aborted || this._state.finalized) {
return this;
}
this._abort();
return this;
};
/**
* Appends an input source (text string, buffer, or stream) to the instance.
*
* When the instance has received, processed, and emitted the input, the `entry`
* event is fired.
*
* @fires Archiver#entry
* @param {(Buffer|Stream|String)} source The input source.
* @param {EntryData} data See also {@link ZipEntryData} and {@link TarEntryData}.
* @return {this}
*/
Archiver.prototype.append = function (source, data) {
if (this._state.finalize || this._state.aborted) {
this.emit('error', new ArchiverError('QUEUECLOSED'));
return this;
}
data = this._normalizeEntryData(data);
if (typeof data.name !== 'string' || data.name.length === 0) {
this.emit('error', new ArchiverError('ENTRYNAMEREQUIRED'));
return this;
}
if (data.type === 'directory' && !this._moduleSupports('directory')) {
this.emit('error', new ArchiverError('DIRECTORYNOTSUPPORTED', { name: data.name }));
return this;
}
source = util.normalizeInputSource(source);
if (Buffer.isBuffer(source)) {
data.sourceType = 'buffer';
} else if (util.isStream(source)) {
data.sourceType = 'stream';
} else {
this.emit('error', new ArchiverError('INPUTSTEAMBUFFERREQUIRED', { name: data.name }));
return this;
}
this._entriesCount++;
this._queue.push({
data: data,
source: source
});
return this;
};
/**
* Appends a directory and its files, recursively, given its dirpath.
*
* @param {String} dirpath The source directory path.
* @param {String} destpath The destination path within the archive.
* @param {(EntryData|Function)} data See also [ZipEntryData]{@link ZipEntryData} and
* [TarEntryData]{@link TarEntryData}.
* @return {this}
*/
Archiver.prototype.directory = function (dirpath, destpath, data) {
if (this._state.finalize || this._state.aborted) {
this.emit('error', new ArchiverError('QUEUECLOSED'));
return this;
}
if (typeof dirpath !== 'string' || dirpath.length === 0) {
this.emit('error', new ArchiverError('DIRECTORYDIRPATHREQUIRED'));
return this;
}
this._pending++;
if (destpath === false) {
destpath = '';
} else if (typeof destpath !== 'string') {
destpath = dirpath;
}
var dataFunction = false;
if (typeof data === 'function') {
dataFunction = data;
data = {};
} else if (typeof data !== 'object') {
data = {};
}
var globOptions = {
stat: true,
dot: true
};
function onGlobEnd() {
this._pending--;
this._maybeFinalize();
}
function onGlobError(err) {
this.emit('error', err);
}
function onGlobMatch(match) {
globber.pause();
var ignoreMatch = false;
var entryData = Object.assign({}, data);
entryData.name = match.relative;
entryData.prefix = destpath;
entryData.stats = match.stat;
entryData.callback = globber.resume.bind(globber);
try {
if (dataFunction) {
entryData = dataFunction(entryData);
if (entryData === false) {
ignoreMatch = true;
} else if (typeof entryData !== 'object') {
throw new ArchiverError('DIRECTORYFUNCTIONINVALIDDATA', { dirpath: dirpath });
}
}
} catch (e) {
this.emit('error', e);
return;
}
if (ignoreMatch) {
globber.resume();
return;
}
this._append(match.absolute, entryData);
}
var globber = glob(dirpath, globOptions);
globber.on('error', onGlobError.bind(this));
globber.on('match', onGlobMatch.bind(this));
globber.on('end', onGlobEnd.bind(this));
return this;
};
/**
* Appends a file given its filepath using a
* [lazystream]{@link https://github.com/jpommerening/node-lazystream} wrapper to
* prevent issues with open file limits.
*
* When the instance has received, processed, and emitted the file, the `entry`
* event is fired.
*
* @param {String} filepath The source filepath.
* @param {EntryData} data See also [ZipEntryData]{@link ZipEntryData} and
* [TarEntryData]{@link TarEntryData}.
* @return {this}
*/
Archiver.prototype.file = function (filepath, data) {
if (this._state.finalize || this._state.aborted) {
this.emit('error', new ArchiverError('QUEUECLOSED'));
return this;
}
if (typeof filepath !== 'string' || filepath.length === 0) {
this.emit('error', new ArchiverError('FILEFILEPATHREQUIRED'));
return this;
}
this._append(filepath, data);
return this;
};
/**
* Appends multiple files that match a glob pattern.
*
* @param {String} pattern The [glob pattern]{@link https://github.com/isaacs/minimatch} to match.
* @param {Object} options See [node-readdir-glob]{@link https://github.com/yqnn/node-readdir-glob#options}.
* @param {EntryData} data See also [ZipEntryData]{@link ZipEntryData} and
* [TarEntryData]{@link TarEntryData}.
* @return {this}
*/
Archiver.prototype.glob = function (pattern, options, data) {
this._pending++;
options = util.defaults(options, {
stat: true,
pattern: pattern
});
function onGlobEnd() {
this._pending--;
this._maybeFinalize();
}
function onGlobError(err) {
this.emit('error', err);
}
function onGlobMatch(match) {
globber.pause();
var entryData = Object.assign({}, data);
entryData.callback = globber.resume.bind(globber);
entryData.stats = match.stat;
entryData.name = match.relative;
this._append(match.absolute, entryData);
}
var globber = glob(options.cwd || '.', options);
globber.on('error', onGlobError.bind(this));
globber.on('match', onGlobMatch.bind(this));
globber.on('end', onGlobEnd.bind(this));
return this;
};
/**
* Finalizes the instance and prevents further appending to the archive
* structure (queue will continue til drained).
*
* The `end`, `close` or `finish` events on the destination stream may fire
* right after calling this method so you should set listeners beforehand to
* properly detect stream completion.
*
* @return {Promise}
*/
Archiver.prototype.finalize = function () {
if (this._state.aborted) {
var abortedError = new ArchiverError('ABORTED');
this.emit('error', abortedError);
return Promise.reject(abortedError);
}
if (this._state.finalize) {
var finalizingError = new ArchiverError('FINALIZING');
this.emit('error', finalizingError);
return Promise.reject(finalizingError);
}
this._state.finalize = true;
if (this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
this._finalize();
}
var self = this;
return new Promise(function (resolve, reject) {
var errored;
self._module.on('end', function () {
if (!errored) {
resolve();
}
})
self._module.on('error', function (err) {
errored = true;
reject(err);
})
})
};
/**
* Sets the module format name used for archiving.
*
* @param {String} format The name of the format.
* @return {this}
*/
Archiver.prototype.setFormat = function (format) {
if (this._format) {
this.emit('error', new ArchiverError('FORMATSET'));
return this;
}
this._format = format;
return this;
};
/**
* Sets the module used for archiving.
*
* @param {Function} module The function for archiver to interact with.
* @return {this}
*/
Archiver.prototype.setModule = function (module) {
if (this._state.aborted) {
this.emit('error', new ArchiverError('ABORTED'));
return this;
}
if (this._state.module) {
this.emit('error', new ArchiverError('MODULESET'));
return this;
}
this._module = module;
this._modulePipe();
return this;
};
/**
* Appends a symlink to the instance.
*
* This does NOT interact with filesystem and is used for programmatically creating symlinks.
*
* @param {String} filepath The symlink path (within archive).
* @param {String} target The target path (within archive).
* @param {Number} mode Sets the entry permissions.
* @return {this}
*/
Archiver.prototype.symlink = function (filepath, target, mode) {
if (this._state.finalize || this._state.aborted) {
this.emit('error', new ArchiverError('QUEUECLOSED'));
return this;
}
if (typeof filepath !== 'string' || filepath.length === 0) {
this.emit('error', new ArchiverError('SYMLINKFILEPATHREQUIRED'));
return this;
}
if (typeof target !== 'string' || target.length === 0) {
this.emit('error', new ArchiverError('SYMLINKTARGETREQUIRED', { filepath: filepath }));
return this;
}
if (!this._moduleSupports('symlink')) {
this.emit('error', new ArchiverError('SYMLINKNOTSUPPORTED', { filepath: filepath }));
return this;
}
var data = {};
data.type = 'symlink';
data.name = filepath.replace(/\\/g, '/');
data.linkname = target.replace(/\\/g, '/');
data.sourceType = 'buffer';
if (typeof mode === "number") {
data.mode = mode;
}
this._entriesCount++;
this._queue.push({
data: data,
source: Buffer.concat([])
});
return this;
};
/**
* Returns the current length (in bytes) that has been emitted.
*
* @return {Number}
*/
Archiver.prototype.pointer = function () {
return this._pointer;
};
/**
* Middleware-like helper that has yet to be fully implemented.
*
* @private
* @param {Function} plugin
* @return {this}
*/
Archiver.prototype.use = function (plugin) {
this._streams.push(plugin);
return this;
};
module.exports = Archiver;
/**
* @typedef {Object} CoreOptions
* @global
* @property {Number} [statConcurrency=4] Sets the number of workers used to
* process the internal fs stat queue.
*/
/**
* @typedef {Object} TransformOptions
* @property {Boolean} [allowHalfOpen=true] If set to false, then the stream
* will automatically end the readable side when the writable side ends and vice
* versa.
* @property {Boolean} [readableObjectMode=false] Sets objectMode for readable
* side of the stream. Has no effect if objectMode is true.
* @property {Boolean} [writableObjectMode=false] Sets objectMode for writable
* side of the stream. Has no effect if objectMode is true.
* @property {Boolean} [decodeStrings=true] Whether or not to decode strings
* into Buffers before passing them to _write(). `Writable`
* @property {String} [encoding=NULL] If specified, then buffers will be decoded
* to strings using the specified encoding. `Readable`
* @property {Number} [highWaterMark=16kb] The maximum number of bytes to store
* in the internal buffer before ceasing to read from the underlying resource.
* `Readable` `Writable`
* @property {Boolean} [objectMode=false] Whether this stream should behave as a
* stream of objects. Meaning that stream.read(n) returns a single value instead
* of a Buffer of size n. `Readable` `Writable`
*/
/**
* @typedef {Object} EntryData
* @property {String} name Sets the entry name including internal path.
* @property {(String|Date)} [date=NOW()] Sets the entry date.
* @property {Number} [mode=D:0755/F:0644] Sets the entry permissions.
* @property {String} [prefix] Sets a path prefix for the entry name. Useful
* when working with methods like `directory` or `glob`.
* @property {fs.Stats} [stats] Sets the fs stat data for this entry allowing
* for reduction of fs stat calls when stat data is already known.
*/
/**
* @typedef {Object} ErrorData
* @property {String} message The message of the error.
* @property {String} code The error code assigned to this error.
* @property {String} data Additional data provided for reporting or debugging (where available).
*/
/**
* @typedef {Object} ProgressData
* @property {Object} entries
* @property {Number} entries.total Number of entries that have been appended.
* @property {Number} entries.processed Number of entries that have been processed.
* @property {Object} fs
* @property {Number} fs.totalBytes Number of bytes that have been appended. Calculated asynchronously and might not be accurate: it growth while entries are added. (based on fs.Stats)
* @property {Number} fs.processedBytes Number of bytes that have been processed. (based on fs.Stats)
*/

View File

@ -0,0 +1,40 @@
/**
* Archiver Core
*
* @ignore
* @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
* @copyright (c) 2012-2014 Chris Talkington, contributors.
*/
var util = require('util');
const ERROR_CODES = {
'ABORTED': 'archive was aborted',
'DIRECTORYDIRPATHREQUIRED': 'diretory dirpath argument must be a non-empty string value',
'DIRECTORYFUNCTIONINVALIDDATA': 'invalid data returned by directory custom data function',
'ENTRYNAMEREQUIRED': 'entry name must be a non-empty string value',
'FILEFILEPATHREQUIRED': 'file filepath argument must be a non-empty string value',
'FINALIZING': 'archive already finalizing',
'QUEUECLOSED': 'queue closed',
'NOENDMETHOD': 'no suitable finalize/end method defined by module',
'DIRECTORYNOTSUPPORTED': 'support for directory entries not defined by module',
'FORMATSET': 'archive format already set',
'INPUTSTEAMBUFFERREQUIRED': 'input source must be valid Stream or Buffer instance',
'MODULESET': 'module already set',
'SYMLINKNOTSUPPORTED': 'support for symlink entries not defined by module',
'SYMLINKFILEPATHREQUIRED': 'symlink filepath argument must be a non-empty string value',
'SYMLINKTARGETREQUIRED': 'symlink target argument must be a non-empty string value',
'ENTRYNOTSUPPORTED': 'entry not supported'
};
function ArchiverError(code, data) {
Error.captureStackTrace(this, this.constructor);
//this.name = this.constructor.name;
this.message = ERROR_CODES[code] || code;
this.code = code;
this.data = data;
}
util.inherits(ArchiverError, Error);
exports = module.exports = ArchiverError;

View File

@ -0,0 +1,110 @@
/**
* JSON Format Plugin
*
* @module plugins/json
* @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
* @copyright (c) 2012-2014 Chris Talkington, contributors.
*/
var inherits = require('util').inherits;
var Transform = require('readable-stream').Transform;
var crc32 = require('../../buffer-crc32');
var util = require('archiver-utils');
/**
* @constructor
* @param {(JsonOptions|TransformOptions)} options
*/
var Json = function (options) {
if (!(this instanceof Json)) {
return new Json(options);
}
options = this.options = util.defaults(options, {});
Transform.call(this, options);
this.supports = {
directory: true,
symlink: true
};
this.files = [];
};
inherits(Json, Transform);
/**
* [_transform description]
*
* @private
* @param {Buffer} chunk
* @param {String} encoding
* @param {Function} callback
* @return void
*/
Json.prototype._transform = function (chunk, encoding, callback) {
callback(null, chunk);
};
/**
* [_writeStringified description]
*
* @private
* @return void
*/
Json.prototype._writeStringified = function () {
var fileString = JSON.stringify(this.files);
this.write(fileString);
};
/**
* [append description]
*
* @param {(Buffer|Stream)} source
* @param {EntryData} data
* @param {Function} callback
* @return void
*/
Json.prototype.append = function (source, data, callback) {
var self = this;
data.crc32 = 0;
function onend(err, sourceBuffer) {
if (err) {
callback(err);
return;
}
data.size = sourceBuffer.length || 0;
data.crc32 = crc32.unsigned(sourceBuffer);
self.files.push(data);
callback(null, data);
}
if (data.sourceType === 'buffer') {
onend(null, source);
} else if (data.sourceType === 'stream') {
util.collectStream(source, onend);
}
};
/**
* [finalize description]
*
* @return void
*/
Json.prototype.finalize = function () {
this._writeStringified();
this.end();
};
module.exports = Json;
/**
* @typedef {Object} JsonOptions
* @global
*/

View File

@ -0,0 +1,120 @@
/**
* ZIP Format Plugin
*
* @module plugins/zip
* @license [MIT]{@link https://github.com/archiverjs/node-archiver/blob/master/LICENSE}
* @copyright (c) 2012-2014 Chris Talkington, contributors.
*/
var engine = require('../../zip-stream');
var util = require('archiver-utils');
/**
* @constructor
* @param {ZipOptions} [options]
* @param {String} [options.comment] Sets the zip archive comment.
* @param {Boolean} [options.forceLocalTime=false] Forces the archive to contain local file times instead of UTC.
* @param {Boolean} [options.forceZip64=false] Forces the archive to contain ZIP64 headers.
* @param {Boolean} [options.namePrependSlash=false] Prepends a forward slash to archive file paths.
* @param {Boolean} [options.store=false] Sets the compression method to STORE.
* @param {Object} [options.zlib] Passed to [zlib]{@link https://nodejs.org/api/zlib.html#zlib_class_options}
*/
var Zip = function (options) {
if (!(this instanceof Zip)) {
return new Zip(options);
}
options = this.options = util.defaults(options, {
comment: '',
forceUTC: false,
namePrependSlash: false,
store: false
});
this.supports = {
directory: true,
symlink: true
};
this.engine = new engine(options);
};
/**
* @param {(Buffer|Stream)} source
* @param {ZipEntryData} data
* @param {String} data.name Sets the entry name including internal path.
* @param {(String|Date)} [data.date=NOW()] Sets the entry date.
* @param {Number} [data.mode=D:0755/F:0644] Sets the entry permissions.
* @param {String} [data.prefix] Sets a path prefix for the entry name. Useful
* when working with methods like `directory` or `glob`.
* @param {fs.Stats} [data.stats] Sets the fs stat data for this entry allowing
* for reduction of fs stat calls when stat data is already known.
* @param {Boolean} [data.store=ZipOptions.store] Sets the compression method to STORE.
* @param {Function} callback
* @return void
*/
Zip.prototype.append = function (source, data, callback) {
this.engine.entry(source, data, callback);
};
/**
* @return void
*/
Zip.prototype.finalize = function () {
this.engine.finalize();
};
/**
* @return this.engine
*/
Zip.prototype.on = function () {
return this.engine.on.apply(this.engine, arguments);
};
/**
* @return this.engine
*/
Zip.prototype.pipe = function () {
return this.engine.pipe.apply(this.engine, arguments);
};
/**
* @return this.engine
*/
Zip.prototype.unpipe = function () {
return this.engine.unpipe.apply(this.engine, arguments);
};
module.exports = Zip;
/**
* @typedef {Object} ZipOptions
* @global
* @property {String} [comment] Sets the zip archive comment.
* @property {Boolean} [forceLocalTime=false] Forces the archive to contain local file times instead of UTC.
* @property {Boolean} [forceZip64=false] Forces the archive to contain ZIP64 headers.
* @prpperty {Boolean} [namePrependSlash=false] Prepends a forward slash to archive file paths.
* @property {Boolean} [store=false] Sets the compression method to STORE.
* @property {Object} [zlib] Passed to [zlib]{@link https://nodejs.org/api/zlib.html#zlib_class_options}
* to control compression.
* @property {*} [*] See [zip-stream]{@link https://archiverjs.com/zip-stream/ZipStream.html} documentation for current list of properties.
*/
/**
* @typedef {Object} ZipEntryData
* @global
* @property {String} name Sets the entry name including internal path.
* @property {(String|Date)} [date=NOW()] Sets the entry date.
* @property {Number} [mode=D:0755/F:0644] Sets the entry permissions.
* @property {Boolean} [namePrependSlash=ZipOptions.namePrependSlash] Prepends a forward slash to archive file paths.
* @property {String} [prefix] Sets a path prefix for the entry name. Useful
* when working with methods like `directory` or `glob`.
* @property {fs.Stats} [stats] Sets the fs stat data for this entry allowing
* for reduction of fs stat calls when stat data is already known.
* @property {Boolean} [store=ZipOptions.store] Sets the compression method to STORE.
*/
/**
* ZipStream Module
* @external ZipStream
* @see {@link https://www.archiverjs.com/zip-stream/ZipStream.html}
*/

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2018, Jon Schlinkert.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,35 @@
/*!
* normalize-path <https://github.com/jonschlinkert/normalize-path>
*
* Copyright (c) 2014-2018, Jon Schlinkert.
* Released under the MIT License.
*/
module.exports = function (path, stripTrailing) {
if (typeof path !== 'string') {
throw new TypeError('expected path to be a string');
}
if (path === '\\' || path === '/') return '/';
var len = path.length;
if (len <= 1) return path;
// ensure that win32 namespaces has two leading slashes, so that the path is
// handled properly by the win32 version of path.parse() after being normalized
// https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
var prefix = '';
if (len > 4 && path[3] === '\\') {
var ch = path[2];
if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') {
path = path.slice(2);
prefix = '//';
}
}
var segs = path.split(/[/\\]+/);
if (stripTrailing !== false && segs[segs.length - 1] === '') {
segs.pop();
}
return prefix + segs.join('/');
};

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2020 Yann Armelin
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,248 @@
//
// used by archiver
// Source: https://github.com/Yqnn/node-readdir-glob
//
module.exports = readdirGlob;
const fs = require('fs');
const { EventEmitter } = require('events');
const { Minimatch } = require('minimatch');
const { resolve } = require('path');
function readdir(dir, strict) {
return new Promise((resolve, reject) => {
fs.readdir(dir, { withFileTypes: true }, (err, files) => {
if (err) {
switch (err.code) {
case 'ENOTDIR': // Not a directory
if (strict) {
reject(err);
} else {
resolve([]);
}
break;
case 'ENOTSUP': // Operation not supported
case 'ENOENT': // No such file or directory
case 'ENAMETOOLONG': // Filename too long
case 'UNKNOWN':
resolve([]);
break;
case 'ELOOP': // Too many levels of symbolic links
default:
reject(err);
break;
}
} else {
resolve(files);
}
});
});
}
function stat(file, followSymlinks) {
return new Promise((resolve, reject) => {
const statFunc = followSymlinks ? fs.stat : fs.lstat;
statFunc(file, (err, stats) => {
if (err) {
switch (err.code) {
case 'ENOENT':
if (followSymlinks) {
// Fallback to lstat to handle broken links as files
resolve(stat(file, false));
} else {
resolve(null);
}
break;
default:
resolve(null);
break;
}
} else {
resolve(stats);
}
});
});
}
async function* exploreWalkAsync(dir, path, followSymlinks, useStat, shouldSkip, strict) {
let files = await readdir(path + dir, strict);
for (const file of files) {
let name = file.name;
if (name === undefined) {
// undefined file.name means the `withFileTypes` options is not supported by node
// we have to call the stat function to know if file is directory or not.
name = file;
useStat = true;
}
const filename = dir + '/' + name;
const relative = filename.slice(1); // Remove the leading /
const absolute = path + '/' + relative;
let stats = null;
if (useStat || followSymlinks) {
stats = await stat(absolute, followSymlinks);
}
if (!stats && file.name !== undefined) {
stats = file;
}
if (stats === null) {
stats = { isDirectory: () => false };
}
if (stats.isDirectory()) {
if (!shouldSkip(relative)) {
yield { relative, absolute, stats };
yield* exploreWalkAsync(filename, path, followSymlinks, useStat, shouldSkip, false);
}
} else {
yield { relative, absolute, stats };
}
}
}
async function* explore(path, followSymlinks, useStat, shouldSkip) {
yield* exploreWalkAsync('', path, followSymlinks, useStat, shouldSkip, true);
}
function readOptions(options) {
return {
pattern: options.pattern,
dot: !!options.dot,
noglobstar: !!options.noglobstar,
matchBase: !!options.matchBase,
nocase: !!options.nocase,
ignore: options.ignore,
skip: options.skip,
follow: !!options.follow,
stat: !!options.stat,
nodir: !!options.nodir,
mark: !!options.mark,
silent: !!options.silent,
absolute: !!options.absolute
};
}
class ReaddirGlob extends EventEmitter {
constructor(cwd, options, cb) {
super();
if (typeof options === 'function') {
cb = options;
options = null;
}
this.options = readOptions(options || {});
this.matchers = [];
if (this.options.pattern) {
const matchers = Array.isArray(this.options.pattern) ? this.options.pattern : [this.options.pattern];
this.matchers = matchers.map(m =>
new Minimatch(m, {
dot: this.options.dot,
noglobstar: this.options.noglobstar,
matchBase: this.options.matchBase,
nocase: this.options.nocase
})
);
}
this.ignoreMatchers = [];
if (this.options.ignore) {
const ignorePatterns = Array.isArray(this.options.ignore) ? this.options.ignore : [this.options.ignore];
this.ignoreMatchers = ignorePatterns.map(ignore =>
new Minimatch(ignore, { dot: true })
);
}
this.skipMatchers = [];
if (this.options.skip) {
const skipPatterns = Array.isArray(this.options.skip) ? this.options.skip : [this.options.skip];
this.skipMatchers = skipPatterns.map(skip =>
new Minimatch(skip, { dot: true })
);
}
this.iterator = explore(resolve(cwd || '.'), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
this.paused = false;
this.inactive = false;
this.aborted = false;
if (cb) {
this._matches = [];
this.on('match', match => this._matches.push(this.options.absolute ? match.absolute : match.relative));
this.on('error', err => cb(err));
this.on('end', () => cb(null, this._matches));
}
setTimeout(() => this._next(), 0);
}
_shouldSkipDirectory(relative) {
//console.log(relative, this.skipMatchers.some(m => m.match(relative)));
return this.skipMatchers.some(m => m.match(relative));
}
_fileMatches(relative, isDirectory) {
const file = relative + (isDirectory ? '/' : '');
return (this.matchers.length === 0 || this.matchers.some(m => m.match(file)))
&& !this.ignoreMatchers.some(m => m.match(file))
&& (!this.options.nodir || !isDirectory);
}
_next() {
if (!this.paused && !this.aborted) {
this.iterator.next()
.then((obj) => {
if (!obj.done) {
const isDirectory = obj.value.stats.isDirectory();
if (this._fileMatches(obj.value.relative, isDirectory)) {
let relative = obj.value.relative;
let absolute = obj.value.absolute;
if (this.options.mark && isDirectory) {
relative += '/';
absolute += '/';
}
if (this.options.stat) {
this.emit('match', { relative, absolute, stat: obj.value.stats });
} else {
this.emit('match', { relative, absolute });
}
}
this._next(this.iterator);
} else {
this.emit('end');
}
})
.catch((err) => {
this.abort();
this.emit('error', err);
if (!err.code && !this.options.silent) {
console.error(err);
}
});
} else {
this.inactive = true;
}
}
abort() {
this.aborted = true;
}
pause() {
this.paused = true;
}
resume() {
this.paused = false;
if (this.inactive) {
this.inactive = false;
this._next();
}
}
}
function readdirGlob(pattern, options, cb) {
return new ReaddirGlob(pattern, options, cb);
}
readdirGlob.ReaddirGlob = ReaddirGlob;

View File

@ -0,0 +1,22 @@
Copyright (c) 2014 Chris Talkington, contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,187 @@
/**
* ZipStream
*
* @ignore
* @license [MIT]{@link https://github.com/archiverjs/node-zip-stream/blob/master/LICENSE}
* @copyright (c) 2014 Chris Talkington, contributors.
*/
var inherits = require('util').inherits;
var ZipArchiveOutputStream = require('../compress-commons').ZipArchiveOutputStream;
var ZipArchiveEntry = require('../compress-commons').ZipArchiveEntry;
var util = require('archiver-utils');
/**
* @constructor
* @extends external:ZipArchiveOutputStream
* @param {Object} [options]
* @param {String} [options.comment] Sets the zip archive comment.
* @param {Boolean} [options.forceLocalTime=false] Forces the archive to contain local file times instead of UTC.
* @param {Boolean} [options.forceZip64=false] Forces the archive to contain ZIP64 headers.
* @param {Boolean} [options.store=false] Sets the compression method to STORE.
* @param {Object} [options.zlib] Passed to [zlib]{@link https://nodejs.org/api/zlib.html#zlib_class_options}
* to control compression.
*/
var ZipStream = module.exports = function (options) {
if (!(this instanceof ZipStream)) {
return new ZipStream(options);
}
options = this.options = options || {};
options.zlib = options.zlib || {};
ZipArchiveOutputStream.call(this, options);
if (typeof options.level === 'number' && options.level >= 0) {
options.zlib.level = options.level;
delete options.level;
}
if (!options.forceZip64 && typeof options.zlib.level === 'number' && options.zlib.level === 0) {
options.store = true;
}
options.namePrependSlash = options.namePrependSlash || false;
if (options.comment && options.comment.length > 0) {
this.setComment(options.comment);
}
};
inherits(ZipStream, ZipArchiveOutputStream);
/**
* Normalizes entry data with fallbacks for key properties.
*
* @private
* @param {Object} data
* @return {Object}
*/
ZipStream.prototype._normalizeFileData = function (data) {
data = util.defaults(data, {
type: 'file',
name: null,
namePrependSlash: this.options.namePrependSlash,
linkname: null,
date: null,
mode: null,
store: this.options.store,
comment: ''
});
var isDir = data.type === 'directory';
var isSymlink = data.type === 'symlink';
if (data.name) {
data.name = util.sanitizePath(data.name);
if (!isSymlink && data.name.slice(-1) === '/') {
isDir = true;
data.type = 'directory';
} else if (isDir) {
data.name += '/';
}
}
if (isDir || isSymlink) {
data.store = true;
}
data.date = util.dateify(data.date);
return data;
};
/**
* Appends an entry given an input source (text string, buffer, or stream).
*
* @param {(Buffer|Stream|String)} source The input source.
* @param {Object} data
* @param {String} data.name Sets the entry name including internal path.
* @param {String} [data.comment] Sets the entry comment.
* @param {(String|Date)} [data.date=NOW()] Sets the entry date.
* @param {Number} [data.mode=D:0755/F:0644] Sets the entry permissions.
* @param {Boolean} [data.store=options.store] Sets the compression method to STORE.
* @param {String} [data.type=file] Sets the entry type. Defaults to `directory`
* if name ends with trailing slash.
* @param {Function} callback
* @return this
*/
ZipStream.prototype.entry = function (source, data, callback) {
if (typeof callback !== 'function') {
callback = this._emitErrorCallback.bind(this);
}
data = this._normalizeFileData(data);
if (data.type !== 'file' && data.type !== 'directory' && data.type !== 'symlink') {
callback(new Error(data.type + ' entries not currently supported'));
return;
}
if (typeof data.name !== 'string' || data.name.length === 0) {
callback(new Error('entry name must be a non-empty string value'));
return;
}
if (data.type === 'symlink' && typeof data.linkname !== 'string') {
callback(new Error('entry linkname must be a non-empty string value when type equals symlink'));
return;
}
var entry = new ZipArchiveEntry(data.name);
entry.setTime(data.date, this.options.forceLocalTime);
if (data.namePrependSlash) {
entry.setName(data.name, true);
}
if (data.store) {
entry.setMethod(0);
}
if (data.comment.length > 0) {
entry.setComment(data.comment);
}
if (data.type === 'symlink' && typeof data.mode !== 'number') {
data.mode = 40960; // 0120000
}
if (typeof data.mode === 'number') {
if (data.type === 'symlink') {
data.mode |= 40960;
}
entry.setUnixMode(data.mode);
}
if (data.type === 'symlink' && typeof data.linkname === 'string') {
source = Buffer.from(data.linkname);
}
return ZipArchiveOutputStream.prototype.entry.call(this, entry, source, callback);
};
/**
* Finalizes the instance and prevents further appending to the archive
* structure (queue will continue til drained).
*
* @return void
*/
ZipStream.prototype.finalize = function () {
this.finish();
};
/**
* Returns the current number of bytes written to this stream.
* @function ZipStream#getBytesWritten
* @returns {Number}
*/
/**
* Compress Commons ZipArchiveOutputStream
* @external ZipArchiveOutputStream
* @see {@link https://github.com/archiverjs/node-compress-commons}
*/

View File

@ -2,7 +2,7 @@ const Path = require('path')
const cron = require('../libs/nodeCron')
const fs = require('../libs/fsExtra')
const archiver = require('archiver')
const archiver = require('../libs/archiver')
const StreamZip = require('../libs/nodeStreamZip')
// Utils

View File

@ -1,6 +1,6 @@
const Path = require('path')
const fs = require('../libs/fsExtra')
const archiver = require('archiver')
const archiver = require('../libs/archiver')
const workerThreads = require('worker_threads')
const Logger = require('../Logger')