1.15.0 • Published 3 years ago

node-stream-zip v1.15.0

Weekly downloads
564,064
License
MIT
Repository
github
Last release
3 years ago

node-stream-zip CI Checks

node.js library for reading and extraction of ZIP archives.
Features:

  • it never loads entire archive into memory, everything is read by chunks
  • large archives support
  • all operations are non-blocking, no sync i/o
  • fast initialization
  • no dependencies, no binary addons
  • decompression with built-in zlib module
  • deflate, sfx, macosx/windows built-in archives
  • ZIP64 support

Installation

npm i node-stream-zip

Usage

There are two APIs provided: 1. promise-based / async 2. callbacks

It's recommended to use the new, promise API, however the legacy callback API may be more flexible for certain operations.

Async API

Open a zip file

const StreamZip = require('node-stream-zip');
const zip = new StreamZip.async({ file: 'archive.zip' });

Stream one entry to stdout

const stm = await zip.stream('path/inside/zip.txt');
stm.pipe(process.stdout);
stm.on('end', () => zip.close());

Read a file as buffer

const data = await zip.entryData('path/inside/zip.txt');
await zip.close();

Extract one file to disk

await zip.extract('path/inside/zip.txt', './extracted.txt');
await zip.close();

List entries

const entriesCount = await zip.entriesCount;
console.log(`Entries read: ${entriesCount}`);

const entries = await zip.entries();
for (const entry of Object.values(entries)) {
    const desc = entry.isDirectory ? 'directory' : `${entry.size} bytes`;
    console.log(`Entry ${entry.name}: ${desc}`);
}

// Do not forget to close the file once you're done
await zip.close();

Extract a folder from archive to disk

fs.mkdirSync('extracted');
await zip.extract('path/inside/zip/', './extracted');
await zip.close();

Extract everything

fs.mkdirSync('extracted');
const count = await zip.extract(null, './extracted');
console.log(`Extracted ${count} entries`);
await zip.close();

When extracting a folder, you can listen to extract event

zip.on('extract', (entry, file) => {
    console.log(`Extracted ${entry.name} to ${file}`);
});

entry event is generated for every entry during loading

zip.on('entry', entry => {
    // you can already stream this entry,
    // without waiting until all entry descriptions are read (suitable for very large archives)
    console.log(`Read entry ${entry.name}`);
});

Callback API

Open a zip file

const StreamZip = require('node-stream-zip');
const zip = new StreamZip({ file: 'archive.zip' });

// Handle errors
zip.on('error', err => { /*...*/ });

List entries

zip.on('ready', () => {
    console.log('Entries read: ' + zip.entriesCount);
    for (const entry of Object.values(zip.entries())) {
        const desc = entry.isDirectory ? 'directory' : `${entry.size} bytes`;
        console.log(`Entry ${entry.name}: ${desc}`);
    }
    // Do not forget to close the file once you're done
    zip.close();
});

Stream one entry to stdout

zip.on('ready', () => {
    zip.stream('path/inside/zip.txt', (err, stm) => {
        stm.pipe(process.stdout);
        stm.on('end', () => zip.close());
    });
});

Extract one file to disk

zip.on('ready', () => {
    zip.extract('path/inside/zip.txt', './extracted.txt', err => {
        console.log(err ? 'Extract error' : 'Extracted');
        zip.close();
    });
});

Extract a folder from archive to disk

zip.on('ready', () => {
    fs.mkdirSync('extracted');
    zip.extract('path/inside/zip/', './extracted', err => {
        console.log(err ? 'Extract error' : 'Extracted');
        zip.close();
    });
});

Extract everything

zip.on('ready', () => {
    fs.mkdirSync('extracted');
    zip.extract(null, './extracted', (err, count) => {
        console.log(err ? 'Extract error' : `Extracted ${count} entries`);
        zip.close();
    });
});

Read a file as buffer in sync way

zip.on('ready', () => {
    const data = zip.entryDataSync('path/inside/zip.txt');
    zip.close();
});

When extracting a folder, you can listen to extract event

zip.on('extract', (entry, file) => {
    console.log(`Extracted ${entry.name} to ${file}`);
});

entry event is generated for every entry during loading

zip.on('entry', entry => {
    // you can already stream this entry,
    // without waiting until all entry descriptions are read (suitable for very large archives)
    console.log(`Read entry ${entry.name}`);
});

Options

You can pass these options to the constructor

  • storeEntries: true - you will be able to work with entries inside zip archive, otherwise the only way to access them is entry event
  • skipEntryNameValidation: true - by default, entry name is checked for malicious characters, like ../ or c:\123, pass this flag to disable validation errors

Methods

  • zip.entries() - get all entries description
  • zip.entry(name) - get entry description by name
  • zip.stream(entry, function(err, stm) { }) - get entry data reader stream
  • zip.entryDataSync(entry) - get entry data in sync way
  • zip.close() - cleanup after all entries have been read, streamed, extracted, and you don't need the archive

Building

The project doesn't require building. To run unit tests with nodeunit:

npm test

Known issues

Out of scope

  • AES encrypted files: the library will throw an error if you try to open it

Contributors

ZIP parsing code has been partially forked from cthackers/adm-zip (MIT license).

dos.zczc.cz_vueeasy-select-rnreact-native-bluetooth2xlstream_copyreact-native-template-rfbasecalendar_indexercalendar-indexerairscanairscan-examplereact-native-esc-pos-sahaab@borisovart/atol-kkt-moduledeneme323112url-xi@ntt_app/react-native-custom-notificationreact-native-custom-text-hwjamesreact-native-covid-sdk@stmp/stamp-clicreate-tactech-appreact-native-printer-brothers@h2security/cdxgenreact-native-shekhar-bridge-testwilscanner@oiti/documentoscopy-react-nativereciple-module-managerquoc-testreact-native-slider-kf@infinitebrahmanuniverse/nolb-node-stgear-vpn-cronaxis-module-utilityegg-zipluminos-ui-corevisionr-binaryvisionr-corevisionr-server@everything-registry/sub-chunk-2317jawwy-sdkjawwy_gamification_releasereact-native-sphereuisphereuijawwy_libraryreact-native-credit-card-pkgreact-native-jawwy_sample@zoolanders/cli@autifyhq/autify-cli@cord-tools/cord-cli@continuousjr/xlstream@corelmax/react-native-my2c2p-sdk@danielcalle/sfdx-scanner@damruravihara/react-native-testing-package@damian.lnc/core@daisy/epub-utils@baloochat/react-native-svg-uri@cyclonedx/cdxgen@cpdevtools/development-host@coti-cvi/dappeteer@aysea/react-native-ui-library@azalpacir/react-native-dhp-printer@create-anchor-app/cli@axe-web/create-blockbbreplaybiometric-stbirken-react-native-community-image-editor@cs6/react-native-test-native-view-library@con-test/react-native-concent-common@assystant/firebase@idas1/ui-component-libetl-monitor-update@ibmgaragecloud/cloud-native-toolkit-cli@inspirelectronics/win-pvm@instana/synthetic-api-scriptextract-word-docsexplorer-desktop-launchercdk-bundle-analyzer@harvard-lil/scoopcapgo@guoyunhe/downloader@brantalikp/rn-resizeany-text@ailnaf/xlsx2csv@bygd/gd-upload-adaptor@bygd/gd-upload-google@akromio/registry@apica-io/url-xi@apardellass/react-native-audio-stream@digital-go-jp/abr-geocoder@gluestack/boltvmezone-cli@jalzae/any-textfawaterak-online-paymentfawatrak-online-payment@iokfine/dappeteerdnvgitsolgolang-migrate-clidatastore-zipcargenerator-wpsitegenz-native-elementsdetcraycreate-hyperapp-starter
1.15.0

3 years ago

1.14.0

3 years ago

1.13.6

3 years ago

1.13.5

3 years ago

1.13.4

3 years ago

1.13.3

3 years ago

1.13.2

3 years ago

1.13.1

3 years ago

1.13.0

3 years ago

1.12.0

3 years ago

1.11.7

3 years ago

1.11.6

3 years ago

1.11.5

3 years ago

1.11.4

3 years ago

1.11.3

4 years ago

1.11.2

4 years ago

1.11.1

4 years ago

1.11.0

4 years ago

1.10.1

4 years ago

1.10.0

4 years ago

1.9.2

4 years ago

1.9.1

4 years ago

1.9.0

4 years ago

1.8.2

5 years ago

1.8.1

5 years ago

1.8.0

5 years ago

1.7.0

6 years ago

1.6.0

6 years ago

1.5.0

6 years ago

1.4.2

6 years ago

1.4.1

6 years ago

1.4.0

6 years ago

1.3.8

6 years ago

1.3.7

7 years ago

1.3.6

7 years ago

1.3.5

7 years ago

1.3.4

8 years ago

1.3.3

8 years ago

1.3.2

8 years ago

1.3.1

8 years ago

1.3.0

8 years ago

1.2.2

8 years ago

1.2.1

9 years ago

1.2.0

9 years ago

1.1.1

9 years ago

1.1.0

9 years ago

1.0.0

9 years ago

0.2.0

9 years ago

0.1.0

9 years ago