Skip to content

Commit aa361e3

Browse files
committed
Initial commit
0 parents  commit aa361e3

File tree

11 files changed

+415
-0
lines changed

11 files changed

+415
-0
lines changed

.eslintrc.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module.exports = {
2+
env: {
3+
browser: false,
4+
commonjs: true,
5+
es2021: true,
6+
node: true,
7+
},
8+
extends: 'eslint:recommended',
9+
parserOptions: {
10+
ecmaVersion: 'latest',
11+
},
12+
rules: {
13+
'indent': [
14+
'error',
15+
2
16+
],
17+
'linebreak-style': [
18+
'error',
19+
'unix'
20+
],
21+
'quotes': [
22+
'error',
23+
'single'
24+
],
25+
'semi': [
26+
'error',
27+
'always'
28+
],
29+
'no-unused-vars': 'warn'
30+
},
31+
};

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
package-lock.json
3+
yarn.lock
4+
dist
5+
*.zip

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 NZIP Contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# [NZIP](https://nzip.dev)
2+
3+
A fast & low-memory consuming archiver built on [fflate](https://github.com/101arrowz/fflate) and [Node.js](https://nodejs.org/en)
4+
5+
## Highlights
6+
7+
- Fast: Built on top of [fflate](https://github.com/101arrowz/fflate) which supports streaming and multi-threads.
8+
- Modern: Written in 100% modern ES6 javascript with non-blocking asynchronous programming techniques.
9+
- Low-memory: Using node.js stream API to consume lower memory resources as much as possible.
10+
- Cross-platform: Runs on any machine where node.js is supported.
11+
12+
## Requirements
13+
14+
- Running from binary release
15+
16+
None (Binary from the [last release](https://github.com/ifconfigla/nzip/releases/latest) is the only requirement)
17+
18+
- Running from npx or npm install
19+
20+
Node.js LTS version (See the [official node.js download page](https://nodejs.org/en/download))
21+
22+
## Quickstart
23+
24+
### Installation & Running
25+
26+
- Running via [binary release](https://github.com/ifconfigla/nzip/releases/latest)
27+
28+
```bash
29+
$ nzip "fileToInclude1, fileToInclude2, folderToInclude1" "fileToExclude1"
30+
```
31+
32+
- Running via npx (Without installation)
33+
34+
```bash
35+
$ npx nzip "fileToInclude1, fileToInclude2, folderToInclude1" "fileToExclude1"
36+
```
37+
38+
- Running via npm global install
39+
40+
```bash
41+
$ npm i -g nzip
42+
$ nzip "fileToInclude1, fileToInclude2, folderToInclude1" "fileToExclude1"
43+
```
44+
45+
## Donations
46+
47+
- BTC:
48+
49+
```
50+
15BrvbeHtNp5PuoUBdo95j7G2wWmpmq7Dg
51+
```
52+
53+
- LTC:
54+
55+
```
56+
LgK6hSbeyhE8UpsWM86z4rrCoKf38SWYH8
57+
```
58+
59+
- DOGE:
60+
61+
```
62+
DKjBYVArMGKXAJae1y3V9nvjZX9TVehSRL
63+
```
64+
65+
- ETH:
66+
67+
```
68+
0x34E3B113EBb270F2acbF312815c538EC1E12aec1
69+
```
70+
71+
- XMR:
72+
73+
```
74+
47qyY7CYdsDWsfpLoSUZP2Q5Hnnf3LteM9w2ZJ878XHAjAsd3ZHB6AUNb2BErfgsYA4Ne2SPLM5AzboABx4n9USJAYU5ZNZ
75+
```
76+

_config.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
titles_from_headings:
2+
enabled: true
3+
strip_title: true
4+
collections: true

files.example.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
"file1",
3+
"file2",
4+
"folder1",
5+
"folder2"
6+
]

ifconfig-dev.pub

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
-----BEGIN PGP PUBLIC KEY BLOCK-----
2+
3+
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
50+
sRcslvNI
51+
=C1G/
52+
-----END PGP PUBLIC KEY BLOCK-----

index.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
const { Zip, AsyncZipDeflate } = require('fflate');
2+
const fs = require('fs');
3+
const path = require('path');
4+
5+
/**
6+
* Getting files recursively
7+
* https://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search
8+
* @param {string} dir
9+
* @returns {String[]} list of files
10+
*/
11+
const getFiles = (dir) => {
12+
const dirents = fs.readdirSync(dir, { withFileTypes: true });
13+
14+
const files = dirents.map((dirent) => {
15+
const res = path.join(dir, dirent.name);
16+
return dirent.isDirectory() ? getFiles(res) : res;
17+
});
18+
19+
// Return posix path
20+
return files.flat().map(f => f.split(path.sep).join(path.posix.sep));
21+
};
22+
23+
const resolveFiles = (dirOrFile) => {
24+
const stat = fs.statSync(dirOrFile);
25+
if (stat && stat.isDirectory()) {
26+
return getFiles(dirOrFile);
27+
}
28+
return [dirOrFile];
29+
};
30+
31+
/**
32+
* Read recursive list of files and archive them into single zip file.
33+
* https://github.com/101arrowz/fflate/issues/48#issuecomment-804430295
34+
* @param {Object} inputParams
35+
* @param {String[]} inputParams.files
36+
* @param {string} inputParams.zipName
37+
*/
38+
const createZip = async ({
39+
files,
40+
filteredFiles = [],
41+
zipName = `nzip_${parseInt(new Date().getTime() / 1000)}.zip`
42+
}) => {
43+
// Scan files
44+
const filesRes = files.map(f => resolveFiles(f)).flat().filter(f => !filteredFiles.includes(f));
45+
46+
// Initialize writeStream to dir.zip
47+
const writeStream = fs.createWriteStream(zipName);
48+
49+
// Initialize zip stream and define chunk output to writeStream
50+
const zip = new Zip((err, dat, final) => {
51+
writeStream.write(dat);
52+
if (final) {
53+
writeStream.end();
54+
}
55+
});
56+
57+
for await (const file of filesRes) {
58+
const fileZip = new AsyncZipDeflate(file);
59+
zip.add(fileZip);
60+
61+
await new Promise((res, rej) => {
62+
const readStream = fs.createReadStream(file);
63+
64+
readStream.on('data', chunk => fileZip.push(chunk));
65+
readStream.on('end', () => {
66+
fileZip.push(new Uint8Array(0), true);
67+
res();
68+
});
69+
readStream.on('error', rej);
70+
});
71+
72+
console.log(`[NZIP] Processing ${file}`);
73+
}
74+
75+
zip.end();
76+
console.log(`[NZIP] Completed writing ${zipName}`);
77+
};
78+
79+
module.exports = createZip;

package.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "nzip",
3+
"version": "1.0.0",
4+
"description": "A fast & low-memory consuming archiver built on fflate and Node.js",
5+
"main": "index.js",
6+
"bin": {
7+
"nzip": "./start.js"
8+
},
9+
"scripts": {
10+
"lint": "eslint ./*.{js,jsx}",
11+
"lint:fix": "eslint ./*.{js,jsx} --fix",
12+
"build": "pkg -d --no-native-build --no-signature --no-bytecode -c ./package.json ./start.js",
13+
"dist": "npm run build && ./scripts/pack.sh",
14+
"start": "node ./start.js",
15+
"test": "echo \"Error: no test specified\" && exit 1"
16+
},
17+
"author": "NZIP Contributors",
18+
"license": "MIT",
19+
"files": [
20+
".eslintrc.js",
21+
".gitignore",
22+
"scripts",
23+
"ifconfig-dev.pub",
24+
"files.example.json",
25+
"index.js",
26+
"LICENSE",
27+
"README.md",
28+
"start.js"
29+
],
30+
"target": "node18",
31+
"pkg": {
32+
"scripts": [
33+
"*.js",
34+
"node_modules/fflate/**/*.{js,cjs}"
35+
],
36+
"targets": [
37+
"node18-linux-x64",
38+
"node18-macos-x64",
39+
"node18-win-x64"
40+
],
41+
"outputPath": "dist"
42+
},
43+
"dependencies": {
44+
"commander": "^11.0.0",
45+
"fflate": "^0.8.0"
46+
},
47+
"devDependencies": {
48+
"eslint": "^8.46.0",
49+
"pkg": "^5.8.1"
50+
}
51+
}

scripts/pack.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
PACKAGE_NAME=($(jq -r '.name' package.json))
4+
PACKAGE_VERSION=($(jq -r '.version' package.json))
5+
6+
nzip -p && mv ${PACKAGE_NAME}.zip dist/${PACKAGE_NAME}-${PACKAGE_VERSION}-src.zip
7+
cp ifconfig-dev.pub dist
8+
cd dist
9+
rm SHA256SUMS SHA256SUMS.asc
10+
chmod +x ${PACKAGE_NAME}-linux
11+
chmod +x ${PACKAGE_NAME}-macos
12+
mv ${PACKAGE_NAME}-linux ${PACKAGE_NAME} && tar -czvf ${PACKAGE_NAME}-${PACKAGE_VERSION}-x86_64-linux.tar.gz ${PACKAGE_NAME} && rm ${PACKAGE_NAME}
13+
mv ${PACKAGE_NAME}-macos ${PACKAGE_NAME} && tar -czvf ${PACKAGE_NAME}-${PACKAGE_VERSION}-x86_64-darwin.tar.gz ${PACKAGE_NAME} && rm ${PACKAGE_NAME}
14+
mv ${PACKAGE_NAME}-win.exe ${PACKAGE_NAME}.exe && zip ${PACKAGE_NAME}-${PACKAGE_VERSION}-x86_64-win.zip ${PACKAGE_NAME}.exe && rm ${PACKAGE_NAME}.exe
15+
sha256sum * > SHA256SUMS
16+
gpg --clear-sign SHA256SUMS
17+
cd -;
18+
zip -r ${PACKAGE_NAME}-${PACKAGE_VERSION}-dist.zip dist

0 commit comments

Comments
 (0)