archiver-node 8.0.5 → 8.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,78 @@
1
+ ---
2
+ - name: "breaking-change"
3
+ color: ee0701
4
+ description: "A breaking change for existing users."
5
+ - name: "bugfix"
6
+ color: ee0701
7
+ description: "Inconsistencies or issues which will cause a problem for users or implementors."
8
+ - name: "documentation"
9
+ color: 0052cc
10
+ description: "Solely about the documentation of the project."
11
+ - name: "enhancement"
12
+ color: 1d76db
13
+ description: "Enhancement of the code, not introducing new features."
14
+ - name: "refactor"
15
+ color: 1d76db
16
+ description: "Improvement of existing code, not introducing new features."
17
+ - name: "performance"
18
+ color: 1d76db
19
+ description: "Improving performance, not introducing new features."
20
+ - name: "new-feature"
21
+ color: 0e8a16
22
+ description: "New features or options."
23
+ - name: "maintenance"
24
+ color: 2af79e
25
+ description: "Generic maintenance tasks."
26
+ - name: "ci"
27
+ color: 1d76db
28
+ description: "Work that improves the continue integration."
29
+ - name: "dependencies"
30
+ color: 1d76db
31
+ description: "Upgrade or downgrade of project dependencies."
32
+
33
+ - name: "in-progress"
34
+ color: fbca04
35
+ description: "Issue is currently being resolved by a developer."
36
+ - name: "stale"
37
+ color: fef2c0
38
+ description: "There has not been activity on this issue or PR for quite some time."
39
+ - name: "no-stale"
40
+ color: fef2c0
41
+ description: "This issue or PR is exempted from the stable bot."
42
+
43
+ - name: "security"
44
+ color: ee0701
45
+ description: "Marks a security issue that needs to be resolved asap."
46
+ - name: "incomplete"
47
+ color: fef2c0
48
+ description: "Marks a PR or issue that is missing information."
49
+ - name: "invalid"
50
+ color: fef2c0
51
+ description: "Marks a PR or issue that is missing information."
52
+
53
+ - name: "beginner-friendly"
54
+ color: 0e8a16
55
+ description: "Good first issue for people wanting to contribute to the project."
56
+ - name: "help-wanted"
57
+ color: 0e8a16
58
+ description: "We need some extra helping hands or expertise in order to resolve this."
59
+
60
+ - name: "priority-critical"
61
+ color: ee0701
62
+ description: "This should be dealt with ASAP. Not fixing this issue would be a serious error."
63
+ - name: "priority-high"
64
+ color: b60205
65
+ description: "After critical issues are fixed, these should be dealt with before any further issues."
66
+ - name: "priority-medium"
67
+ color: 0e8a16
68
+ description: "This issue may be useful, and needs some attention."
69
+ - name: "priority-low"
70
+ color: e4ea8a
71
+ description: "Nice addition, maybe... someday..."
72
+
73
+ - name: "major"
74
+ color: b60205
75
+ description: "This PR causes a major version bump in the version number."
76
+ - name: "minor"
77
+ color: 0e8a16
78
+ description: "This PR causes a minor version bump in the version number."
@@ -0,0 +1,57 @@
1
+ ---
2
+ name-template: "$RESOLVED_VERSION"
3
+ tag-template: "$RESOLVED_VERSION"
4
+ change-template: "- $TITLE @$AUTHOR (#$NUMBER)"
5
+ sort-direction: ascending
6
+
7
+ categories:
8
+ - title: "Breaking changes"
9
+ labels:
10
+ - "breaking-change"
11
+ - title: "New features"
12
+ labels:
13
+ - "new-feature"
14
+ - title: "Bug fixes"
15
+ labels:
16
+ - "bugfix"
17
+ - title: "Enhancements"
18
+ labels:
19
+ - "enhancement"
20
+ - "refactor"
21
+ - "performance"
22
+ - title: "Maintenance"
23
+ labels:
24
+ - "maintenance"
25
+ - "ci"
26
+ - title: "Documentation"
27
+ labels:
28
+ - "documentation"
29
+ - title: "Dependency updates"
30
+ labels:
31
+ - "dependencies"
32
+
33
+ version-resolver:
34
+ major:
35
+ labels:
36
+ - "major"
37
+ - "breaking-change"
38
+ minor:
39
+ labels:
40
+ - "minor"
41
+ - "new-feature"
42
+ patch:
43
+ labels:
44
+ - "bugfix"
45
+ - "chore"
46
+ - "ci"
47
+ - "dependencies"
48
+ - "documentation"
49
+ - "enhancement"
50
+ - "performance"
51
+ - "refactor"
52
+ default: patch
53
+
54
+ template: |
55
+ ## What’s changed
56
+
57
+ $CHANGES
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: Sync labels
3
+
4
+ # yamllint disable-line rule:truthy
5
+ on:
6
+ push:
7
+ branches:
8
+ - main
9
+ paths:
10
+ - .github/labels.yml
11
+ workflow_dispatch:
12
+
13
+ jobs:
14
+ labels:
15
+ name: Sync labels
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: Check out code from GitHub
19
+ uses: actions/checkout@v4
20
+ - name: Run Label Syncer
21
+ uses: micnncim/action-label-syncer@v1.3.0
22
+ env:
23
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,30 @@
1
+ name: Node CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ branches:
9
+ - master
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+
15
+ strategy:
16
+ matrix:
17
+ node-version: [18.x, 20.x]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4.2.2
21
+ - name: Use Node.js ${{ matrix.node-version }}
22
+ uses: actions/setup-node@v4.4.0
23
+ with:
24
+ node-version: ${{ matrix.node-version }}
25
+ - name: npm install and test
26
+ run: |
27
+ npm ci
28
+ npm test
29
+ env:
30
+ CI: true
@@ -0,0 +1,30 @@
1
+ name: Node Publish Package
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4.2.2
12
+ - uses: actions/setup-node@v4.4.0
13
+ with:
14
+ node-version: 20
15
+ - run: npm ci
16
+ - run: npm test
17
+
18
+ publish-npm:
19
+ needs: build
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v4.2.2
23
+ - uses: actions/setup-node@v4.4.0
24
+ with:
25
+ node-version: 20
26
+ registry-url: https://registry.npmjs.org/
27
+ - run: npm ci
28
+ - run: npm publish
29
+ env:
30
+ NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: Release Drafter
3
+
4
+ # yamllint disable-line rule:truthy
5
+ on:
6
+ push:
7
+ branches:
8
+ - master
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ update_release_draft:
13
+ name: Update Release Draft
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Run Release Drafter
17
+ uses: release-drafter/release-drafter@v6.1.0
18
+ env:
19
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
package/CHANGELOG.md ADDED
@@ -0,0 +1,41 @@
1
+ ## `8.0.1` // 23.02.2026
2
+
3
+ * Forked the `master` branch of the [original repo](https://github.com/archiverjs/node-archiver/) in response to an [npm security vulnerability issue](https://github.com/archiverjs/node-archiver/issues/819) not having been fixed for more than a year due to the original package apparently having been abandoned for an unknown reason. The fork is branched off the same code that was released as the latest known version `7.0.1` with a single additional commit by the original author called ["`esm` refactoring"](https://github.com/archiverjs/node-archiver/pull/790/changes).
4
+
5
+ * The changes in the aforementioned "`esm` refactoring" commit:
6
+ * Added `prettier` to automatically format the code during build. Replaced single quotes with double quotes after introducing `prettier`.
7
+ * The CommonJS code was rewritten as ESM. Because the package has no `build` script, it means that this package can only be `import`ed now and cannot be `require()`d.
8
+ * Added named exports: `ZipArchive`, `TarArchive`, `JsonArchive`. Use them instead of the default export.
9
+ * Old approach: `import archiver from 'archiver'` and `const zipArchive = archiver('zip', options)`.
10
+ * New approach: `import { ZipArchive } from 'archiver'` and `new ZipArchive(options)`.
11
+ * Added named export `Archiver`. It could be used to add new types of archives. Use it instead of the default export (which has been removed).
12
+ * Old approach: `import archiver from 'archiver'` and `const zipArchive = archiver('zip', options)`.
13
+ * New approach: `import { Archiver } from 'archiver'` and `class ZipArchive extends Archiver { ... see index.js ... }` and `new ZipArchive(options)`.
14
+ * Removed exported functions: `registerFormat`, `isRegisteredFormat`, `create`.
15
+ * Updated `zip-stream` dependency from `6.x` to `7.x`.
16
+ * (breaking change) Node.js 18+ is now required.
17
+ * Downgraded `readdir-glob` dependency from `2.x` to `1.x` for an unknown reason.
18
+ * Perhaps it was because `readdir-glob@2.x` updated `minimatch` dependency to `10.x` which [broke](https://github.com/Yqnn/node-readdir-glob/issues/24) Node.js 16+ support and introduced a Node.js 20+ requirement.
19
+
20
+ * Updated `is-stream` dependency from `3.x` to `4.x`
21
+ * (breaking change) Node.js 18+ is now required.
22
+ * (breaking change) The `isStream()` method now also ensures that the stream is not closed. One can pass [`{canOpen: false}`](https://github.com/sindresorhus/is-stream/pull/20) to bring back the old behavior.
23
+ * Added the `{canOpen: false}` option mentioned above in `./lib/utils.js` in the `archiver` code in order for this to not be a breaking change or something.
24
+
25
+ * Reverted the downgrade of `readdir-glob` dependency which was for unspecified reason. Now it's at version `2.x` again.
26
+ * (breaking change) Node.js 18+ is now required.
27
+ * Updated `./lib/core.js` [accordingly](https://github.com/Yqnn/node-readdir-glob/issues/28)
28
+
29
+ * Removed `lazystream` dependency because that package doesn't seem to be [maintained](https://github.com/archiverjs/archiver-utils/issues/191) anymore and [depends](https://github.com/jpommerening/node-lazystream/issues/7) on an old version of `readable-stream`.
30
+ * Replaced it with a simple function.
31
+
32
+ * Added `esbuild` development dependency and added a `build` step that creates a CommonJS version of the package that can be `require()`d and not only `import`ed.
33
+
34
+ * Added TypeScript definition file.
35
+ * Copied it from [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/archiver).
36
+
37
+ * Fixed `website/docs/quickstart.md` and `website/docs/archiver_api.md`.
38
+
39
+ ## Older versions
40
+
41
+ See [CHANGELOG.md](https://github.com/archiverjs/node-archiver/blob/master/CHANGELOG.md) of the original package for more info on the older versions.
package/README.md CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  Creates `.zip` or `.tar` archives using Node.js Streams (supports Node.js 18+).
4
4
 
5
- Forked from [`archiver`](https://www.npmjs.com/package/archiver) package at its unreleased version `8.0.0`.
6
-
7
- Visit the [API documentation](https://www.archiverjs.com/) for a list of all methods available.
5
+ [Forked](https://github.com/archiverjs/node-archiver/issues/819#issuecomment-3945988393) from [`archiver`](https://www.npmjs.com/package/archiver) package at its unreleased version `8.0.0`.
8
6
 
9
7
  ## Install
10
8
 
@@ -14,178 +12,125 @@ npm install archiver-node --save
14
12
 
15
13
  ## Use
16
14
 
17
- Create a utility class called `ZipArchive`.
15
+ For simplified use, consider `archiver-node/zip` subpackage.
18
16
 
19
17
  ```js
20
- import { ZipArchive as ZipArchiver } from 'archiver-node'
21
-
22
- // `WritableStream` doesn't work well with `archiver`.
23
- // It breaks in certain cases. Use `PassThrough` stream instead.
24
- // https://github.com/archiverjs/node-archiver/issues/336
25
- // https://github.com/catamphetamine/archiver-bug
26
- // import { WritableStream } from 'memory-streams'
27
-
28
- import Stream, { PassThrough } from 'stream'
29
-
30
- class ZipArchive {
31
- constructor() {
32
- this.outputStream = new PassThrough()
33
-
34
- const archive = new ZipArchiver({
35
- // Sets the compression level.
36
- // zlib: { level: 9 }
37
- })
38
-
39
- this.archive = archive
40
-
41
- this.promise = new Promise((resolve, reject) => {
42
- // Listens for all archive data to be written.
43
- // 'close' event is fired when all data has been written.
44
- this.outputStream.on('close', () => {
45
- this.size = archive.pointer()
46
- resolve()
47
- })
48
-
49
- // // Listens for all archive data to be written.
50
- // // `end` event is fired when all archive data has been consumed by a consumer stream.
51
- // // @see: https://nodejs.org/api/stream.html#stream_event_end
52
- // archive.on('end', function() {
53
- // this.size = archive.pointer()
54
- // resolve()
55
- // })
56
-
57
- // Catch "warnings", whatever those're.
58
- archive.on('warning', function(error) {
59
- reject(error)
60
- // The following code sample is from `archiver` README:
61
- // if (error.code === 'ENOENT') {
62
- // // `ENOENT` errors happen when a file or folder doesn't exist.
63
- // // It's not clear what are the cases when it could happen.
64
- // // And it's not clear why they're dismissed as unimportant here.
65
- // console.warn(error)
66
- // } else {
67
- // reject(error)
68
- // }
69
- })
70
-
71
- // Catch errors.
72
- archive.on('error', reject)
73
-
74
- // Pipe archive data to the output stream.
75
- archive.pipe(this.outputStream)
76
- })
77
- }
18
+ import ZipArchive from 'archiver-node/zip'
78
19
 
79
- /**
80
- * @param {(stream.Readable|Buffer|string)} content
81
- * @param {string} internalPath — Path inside the archive
82
- */
83
- add(content, internalPath) {
84
- if (content instanceof Stream) {
85
- // `Stream` is allowed.
86
- } else if (content instanceof Buffer) {
87
- // `Buffer` is allowed.
88
- } else if (typeof content === 'string') {
89
- // `string` is allowed.
90
- } else {
91
- const message = 'Unsupported type of content attempted to be added to a .zip archive'
92
- console.log(message + ':')
93
- console.log(content)
94
- throw new Error(message)
95
- }
96
- this.archive.append(content, { name: internalPath })
97
- }
20
+ const archive = new ZipArchive()
98
21
 
99
- /**
100
- * @param {string} filePath — Path to file in the filesystem
101
- * @param {string} internalPath — Path inside the archive
102
- */
103
- includeFile(filePath, internalPath) {
104
- this.archive.file(filePath, { name: internalPath })
105
- }
22
+ // Add a file from stream.
23
+ archive.add(fs.createReadStream("/path/to/file1.txt"), "file1.txt")
106
24
 
107
- /**
108
- * @param {string} directoryPath — Path to directory in the filesystem.
109
- * @param {string} filePathPattern — File path "glob" pattern. Example: "file*.txt".
110
- */
111
- includeFilesByMatch(directoryPath, filePathPattern) {
112
- this.archive.glob(filePathPattern, { cwd: directoryPath })
113
- }
25
+ // Add a file from string.
26
+ archive.add("some text", "file2.txt")
114
27
 
115
- /**
116
- * @param {string} directoryPath — Path to directory in the filesystem
117
- * @param {string} [internalPath] — Path inside the archive. Omitting this argument will put the contents of the directory to the root of the archive.
118
- */
119
- includeDirectory(directoryPath, internalPath) {
120
- this.archive.directory(directoryPath, internalPath || false);
121
- }
28
+ // Add a file from buffer.
29
+ archive.add(Buffer.from(...), "file3.txt")
122
30
 
123
- /**
124
- * Starts the process of writing the archive file data.
125
- * @returns {stream.Readable}
126
- */
127
- write() {
128
- // `.finalize()` starts the process of writing the archive file.
129
- //
130
- // `.finalize()` also returns some kind of `Promise` but it's some kind of a weird one
131
- // and is not meant to be `await`ed or anything like that.
132
- // https://github.com/archiverjs/node-archiver/issues/772
133
- //
134
- // "close", "end" or "finish" events may be fired on `this.archive`
135
- // right after calling this method, so any required event handlers
136
- // should have been added beforehand.
137
- //
138
- this.archive.finalize()
139
-
140
- // Returns a readable `Stream` with the `.zip` archive data.
141
- return this.outputStream
142
- }
31
+ // Add a file from disk.
32
+ archive.includeFile("/path/to/file4.txt", "file4.txt")
143
33
 
144
- /**
145
- * Returns the size of the resulting archive.
146
- * Returns `undefined` until the archive has been written.
147
- * @returns {number | undefined}
148
- */
149
- getSize() {
150
- return this.size
151
- }
152
- }
34
+ // Add a directory from disk.
35
+ archive.includeDirectory("/path/to/directory", "directory")
36
+
37
+ // Add a directory from disk, putting its contents at the root of archive.
38
+ archive.includeDirectory("/path/to/directory")
39
+
40
+ // Add all files matching a "glob" pattern.
41
+ archive.includeFilesByMatch("/path/to/directory", "file*.txt")
42
+
43
+ // Finalize the archive, i.e. we are done adding files to it.
44
+ const archiveDataStream = archive.write()
45
+
46
+ // Pipe the archive data to an output stream.
47
+ archiveDataStream.pipe(fs.createWriteStream("/path/to/archive.zip"))
48
+
49
+ // (optional)
50
+ // When the archive has been written.
51
+ archive.promise.then(() => {
52
+ // Print the size of the archive (in bytes).
53
+ console.log(archive.size)
54
+ })
153
55
  ```
154
56
 
155
- Use the utility class `ZipArchive`.
57
+ For classic use, see the [API documentation](https://www.archiverjs.com/) of the original `archiver` package.
156
58
 
157
59
  ```js
158
- const archive = new ZipArchive()
60
+ import { ZipArchive, TarArchive, JsonArchive } from 'archiver-node'
61
+
62
+ const archive = new ZipArchive({
63
+ // (optional)
64
+ // Node.js `zlib` options such as compression level.
65
+ // https://nodejs.org/api/zlib
66
+ zlib: { level: 9 }
67
+ })
68
+
69
+ // catch "non-critical" errors
70
+ archive.on("warning", (error) => {
71
+ if (error.code === "ENOENT") {
72
+ console.warn(error)
73
+ } else {
74
+ throw error
75
+ }
76
+ })
77
+
78
+ // catch errors
79
+ archive.on("error", (error) => {
80
+ throw error
81
+ })
82
+
83
+ // pipe archive data to the file
84
+ archive.pipe(fs.createWriteStream("/path/to/archive.zip"))
159
85
 
160
86
  // append a file from stream
161
- const file1 = __dirname + "/file1.txt";
162
- archive.add(fs.createReadStream(file1), "file1.txt");
87
+ archive.append(fs.createReadStream("/path/to/file1.txt"), { name: "file1.txt" })
163
88
 
164
89
  // append a file from string
165
- archive.add("string cheese!", "file2.txt");
90
+ archive.append("some text", { name: "file2.txt" })
166
91
 
167
92
  // append a file from buffer
168
- const buffer3 = Buffer.from("buff it!");
169
- archive.add(buffer3, "file3.txt");
93
+ archive.append(Buffer.from(...);, { name: "file3.txt" })
170
94
 
171
95
  // append a file
172
- archive.includeFile("/path/to/file1.txt", "file4.txt");
96
+ archive.file("/path/to/file4.txt", { name: "file4.txt" })
173
97
 
174
- // append files from a sub-directory and naming it `new-sub-directory` within the archive
175
- archive.includeDirectory("/path/to/sub-directory/", "new-sub-directory");
98
+ // append files from a sub-directory and naming it `new-subdir` within the archive
99
+ archive.directory("/path/to/directory", "directory")
176
100
 
177
101
  // append files from a sub-directory, putting its contents at the root of archive
178
- archive.includeDirectory("/path/to/sub-directory/");
102
+ archive.directory("/path/to/directory", false)
179
103
 
180
104
  // append files from a glob pattern
181
- archive.includeFilesByMatch("/path/to/some/directory/", "file*.txt");
105
+ archive.glob("file*.txt", { cwd: "/path/to/directory" })
182
106
 
183
- // finalize the archive (i.e. we are done appending files).
184
- const archiveDataStream = archive.write();
185
-
186
- archiveDataStream.pipe(...);
107
+ // finalize the archive (ie we are done appending files but streams have to finish yet)
108
+ // 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand
109
+ archive.finalize()
187
110
  ```
188
111
 
189
- ## Formats
112
+ For implementing a new type of archive, extend the exported `Archiver` class.
113
+
114
+ ```js
115
+ import { Archiver } from 'archiver-node'
116
+
117
+ class NewTypeOfArchive extends Archiver {
118
+ constructor(options) {
119
+ super(options)
120
+ this._format = "new-type-of-archive"
121
+ this._module = new NewTypeOfArchiveImplementation(options)
122
+ this._supportsDirectory = true
123
+ this._supportsSymlink = true
124
+ this._modulePipe()
125
+ }
126
+ }
190
127
 
191
- Archiver ships with out of the box support for TAR and ZIP archives.
128
+ class NewTypeOfArchiveImplementation {
129
+ constructor(options) { ... }
130
+ append(source, data, callback) { ... }
131
+ finalize() { ... }
132
+ on() { ... }
133
+ pipe() { ... }
134
+ unpipe() { ... }
135
+ }
136
+ ```
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _ZipArchive = _interopRequireDefault(require("../archivers/ZipArchive.js"));
8
+ var _stream = _interopRequireWildcard(require("stream"));
9
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
11
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
12
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
13
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
14
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
15
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
16
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // `WritableStream` doesn't work well with `archiver`.
17
+ // It breaks in certain cases. Use `PassThrough` stream instead.
18
+ // https://github.com/archiverjs/node-archiver/issues/336
19
+ // https://github.com/catamphetamine/archiver-bug
20
+ // import { WritableStream } from 'memory-streams'
21
+ var ZipArchive = exports["default"] = /*#__PURE__*/function () {
22
+ /**
23
+ * @param {object} [options] — Node.js `zlib` options such as compression level. https://nodejs.org/api/zlib. Example: `{ zlib: { level: 9 } }`.
24
+ */
25
+ function ZipArchive(options) {
26
+ var _this = this;
27
+ _classCallCheck(this, ZipArchive);
28
+ // this._outputStream = new WritableStream()
29
+ this._outputStream = new _stream.PassThrough();
30
+ var archive = new _ZipArchive["default"](options);
31
+ this._archive = archive;
32
+
33
+ // `archive` has a `.pipe()` method which kinda makes it usable as a readable stream.
34
+ // Although it's still not a "proper" implementation of a `Readable` stream.
35
+ // https://github.com/archiverjs/node-archiver/issues/765
36
+ // To get a "proper" implementation of a `Readable` stream, people use a workaround:
37
+ // `const passThroughStream = new PassThrough()` and then `archive.pipe(passThroughStream)`.
38
+
39
+ // An alternative way of how to create a `ReadableStream` from an `archive`.
40
+ // https://github.com/archiverjs/node-archiver/issues/759
41
+ //
42
+ // const readableStream = new ReadableStream({
43
+ // start(controller) {
44
+ // archive.on('data', chunk => controller.enqueue(chunk));
45
+ // archive.on('end', () => controller.close());
46
+ // archive.on('error', error => controller.error(error));
47
+ //
48
+ // archive.append(...);
49
+ // archive.append(...);
50
+ // archive.finalize();
51
+ // }
52
+ // });
53
+
54
+ // The size of the resulting archive (in bytes).
55
+ // Is `undefined` until the archive has been written.
56
+ this.size = undefined;
57
+
58
+ // A `Promise<void>` that resolves when the archive has been written.
59
+ this.promise = new Promise(function (resolve, reject) {
60
+ // Listens for all archive data to be written.
61
+ // 'close' event is fired when all data has been written.
62
+ _this._outputStream.on('close', function () {
63
+ _this.size = archive.pointer();
64
+ resolve();
65
+ });
66
+
67
+ // // Listens for all archive data to be written.
68
+ // // `end` event is fired when all archive data has been consumed by a consumer stream.
69
+ // // @see: https://nodejs.org/api/stream.html#stream_event_end
70
+ // archive.on('end', function() {
71
+ // this.size = archive.pointer()
72
+ // resolve()
73
+ // })
74
+
75
+ // Catch "warnings", whatever those're.
76
+ archive.on('warning', function (error) {
77
+ reject(error);
78
+ // The following code sample is from `archiver` README:
79
+ // if (error.code === 'ENOENT') {
80
+ // // `ENOENT` errors happen when a file or folder doesn't exist.
81
+ // // It's not clear what are the cases when it could happen.
82
+ // // And it's not clear why they're dismissed as unimportant here.
83
+ // console.warn(error)
84
+ // } else {
85
+ // reject(error)
86
+ // }
87
+ });
88
+
89
+ // Catch errors.
90
+ archive.on('error', reject);
91
+
92
+ // Pipe archive data to the output stream.
93
+ archive.pipe(_this._outputStream);
94
+ });
95
+ }
96
+
97
+ /**
98
+ * @param {(stream.Readable|Buffer|string)} content
99
+ * @param {string} internalPath — Path inside the archive
100
+ */
101
+ return _createClass(ZipArchive, [{
102
+ key: "add",
103
+ value: function add(content, internalPath) {
104
+ if (content instanceof _stream["default"]) {
105
+ // `Stream` is allowed.
106
+ } else if (content instanceof Buffer) {
107
+ // `Buffer` is allowed.
108
+ } else if (typeof content === 'string') {
109
+ // `string` is allowed.
110
+ } else {
111
+ var message = 'Unsupported type of content attempted to be added to a .zip archive';
112
+ console.log(message + ':');
113
+ console.log(content);
114
+ throw new Error(message);
115
+ }
116
+ this._archive.append(content, {
117
+ name: internalPath
118
+ });
119
+ }
120
+
121
+ /**
122
+ * @param {string} pathToFile — Path to file in the filesystem
123
+ * @param {string} internalPath — Path inside the archive
124
+ */
125
+ }, {
126
+ key: "includeFile",
127
+ value: function includeFile(pathToFile, internalPath) {
128
+ this._archive.file(pathToFile, {
129
+ name: internalPath
130
+ });
131
+ }
132
+
133
+ /**
134
+ * @param {string} pathToDirectory — Path to directory in the filesystem.
135
+ * @param {string} filePathPattern — File path "glob" pattern. Example: "file*.txt".
136
+ */
137
+ }, {
138
+ key: "includeFilesByMatch",
139
+ value: function includeFilesByMatch(pathToDirectory, filePathPattern) {
140
+ this._archive.glob(filePathPattern, {
141
+ cwd: pathToDirectory
142
+ });
143
+ }
144
+
145
+ /**
146
+ * @param {string} pathToDirectory — Path to directory in the filesystem
147
+ * @param {string} [internalPath] — Path inside the archive. Omitting this argument will put the contents of the directory to the root of the archive.
148
+ */
149
+ }, {
150
+ key: "includeDirectory",
151
+ value: function includeDirectory(pathToDirectory, internalPath) {
152
+ this._archive.directory(pathToDirectory, internalPath || false);
153
+ }
154
+
155
+ /**
156
+ * Starts the process of writing the archive file data.
157
+ * @returns {stream.Readable}
158
+ */
159
+ }, {
160
+ key: "write",
161
+ value: function write() {
162
+ // `.finalize()` starts the process of writing the archive file.
163
+ //
164
+ // `.finalize()` also returns some kind of `Promise` but it's some kind of a weird one
165
+ // and is not meant to be `await`ed or anything like that.
166
+ // https://github.com/archiverjs/node-archiver/issues/772
167
+ //
168
+ // "close", "end" or "finish" events may be fired on `this._archive`
169
+ // right after calling this method, so any required event handlers
170
+ // should have been added beforehand.
171
+ //
172
+ this._archive.finalize();
173
+
174
+ // Returns a readable `Stream` with the `.zip` archive data.
175
+ return this._outputStream;
176
+ }
177
+ }]);
178
+ }();
package/index.d.ts CHANGED
@@ -73,7 +73,7 @@ interface TransformOptions {
73
73
  objectmode?: boolean | undefined;
74
74
  }
75
75
 
76
- interface ZipOptions {
76
+ export interface ZipOptions {
77
77
  comment?: string | undefined;
78
78
  forceLocalTime?: boolean | undefined;
79
79
  forceZip64?: boolean | undefined;
@@ -2,12 +2,12 @@ import Archiver from "../Archiver.js";
2
2
  import Tar from "../plugins/tar.js";
3
3
 
4
4
  export default class TarArchive extends Archiver {
5
- constructor(options) {
6
- super(options);
7
- this._format = "tar";
8
- this._module = new Tar(options);
9
- this._supportsDirectory = true;
10
- this._supportsSymlink = true;
11
- this._modulePipe();
12
- }
5
+ constructor(options) {
6
+ super(options);
7
+ this._format = "tar";
8
+ this._module = new Tar(options);
9
+ this._supportsDirectory = true;
10
+ this._supportsSymlink = true;
11
+ this._modulePipe();
12
+ }
13
13
  }
@@ -2,12 +2,12 @@ import Archiver from "../Archiver.js";
2
2
  import Zip from "../plugins/zip.js";
3
3
 
4
4
  export default class ZipArchive extends Archiver {
5
- constructor(options) {
6
- super(options);
7
- this._format = "zip";
8
- this._module = new Zip(options);
9
- this._supportsDirectory = true;
10
- this._supportsSymlink = true;
11
- this._modulePipe();
12
- }
5
+ constructor(options) {
6
+ super(options);
7
+ this._format = "zip";
8
+ this._module = new Zip(options);
9
+ this._supportsDirectory = true;
10
+ this._supportsSymlink = true;
11
+ this._modulePipe();
12
+ }
13
13
  }
@@ -0,0 +1,151 @@
1
+ import ZipArchive_ from '../archivers/ZipArchive.js'
2
+
3
+ // `WritableStream` doesn't work well with `archiver`.
4
+ // It breaks in certain cases. Use `PassThrough` stream instead.
5
+ // https://github.com/archiverjs/node-archiver/issues/336
6
+ // https://github.com/catamphetamine/archiver-bug
7
+ // import { WritableStream } from 'memory-streams'
8
+
9
+ import Stream, { PassThrough } from 'stream'
10
+
11
+ export default class ZipArchive {
12
+ /**
13
+ * @param {object} [options] — Node.js `zlib` options such as compression level. https://nodejs.org/api/zlib. Example: `{ zlib: { level: 9 } }`.
14
+ */
15
+ constructor(options) {
16
+ // this._outputStream = new WritableStream()
17
+ this._outputStream = new PassThrough()
18
+
19
+ const archive = new ZipArchive_(options)
20
+
21
+ this._archive = archive
22
+
23
+ // `archive` has a `.pipe()` method which kinda makes it usable as a readable stream.
24
+ // Although it's still not a "proper" implementation of a `Readable` stream.
25
+ // https://github.com/archiverjs/node-archiver/issues/765
26
+ // To get a "proper" implementation of a `Readable` stream, people use a workaround:
27
+ // `const passThroughStream = new PassThrough()` and then `archive.pipe(passThroughStream)`.
28
+
29
+ // An alternative way of how to create a `ReadableStream` from an `archive`.
30
+ // https://github.com/archiverjs/node-archiver/issues/759
31
+ //
32
+ // const readableStream = new ReadableStream({
33
+ // start(controller) {
34
+ // archive.on('data', chunk => controller.enqueue(chunk));
35
+ // archive.on('end', () => controller.close());
36
+ // archive.on('error', error => controller.error(error));
37
+ //
38
+ // archive.append(...);
39
+ // archive.append(...);
40
+ // archive.finalize();
41
+ // }
42
+ // });
43
+
44
+ // The size of the resulting archive (in bytes).
45
+ // Is `undefined` until the archive has been written.
46
+ this.size = undefined
47
+
48
+ // A `Promise<void>` that resolves when the archive has been written.
49
+ this.promise = new Promise((resolve, reject) => {
50
+ // Listens for all archive data to be written.
51
+ // 'close' event is fired when all data has been written.
52
+ this._outputStream.on('close', () => {
53
+ this.size = archive.pointer()
54
+ resolve()
55
+ })
56
+
57
+ // // Listens for all archive data to be written.
58
+ // // `end` event is fired when all archive data has been consumed by a consumer stream.
59
+ // // @see: https://nodejs.org/api/stream.html#stream_event_end
60
+ // archive.on('end', function() {
61
+ // this.size = archive.pointer()
62
+ // resolve()
63
+ // })
64
+
65
+ // Catch "warnings", whatever those're.
66
+ archive.on('warning', function(error) {
67
+ reject(error)
68
+ // The following code sample is from `archiver` README:
69
+ // if (error.code === 'ENOENT') {
70
+ // // `ENOENT` errors happen when a file or folder doesn't exist.
71
+ // // It's not clear what are the cases when it could happen.
72
+ // // And it's not clear why they're dismissed as unimportant here.
73
+ // console.warn(error)
74
+ // } else {
75
+ // reject(error)
76
+ // }
77
+ })
78
+
79
+ // Catch errors.
80
+ archive.on('error', reject)
81
+
82
+ // Pipe archive data to the output stream.
83
+ archive.pipe(this._outputStream)
84
+ })
85
+ }
86
+
87
+ /**
88
+ * @param {(stream.Readable|Buffer|string)} content
89
+ * @param {string} internalPath — Path inside the archive
90
+ */
91
+ add(content, internalPath) {
92
+ if (content instanceof Stream) {
93
+ // `Stream` is allowed.
94
+ } else if (content instanceof Buffer) {
95
+ // `Buffer` is allowed.
96
+ } else if (typeof content === 'string') {
97
+ // `string` is allowed.
98
+ } else {
99
+ const message = 'Unsupported type of content attempted to be added to a .zip archive'
100
+ console.log(message + ':')
101
+ console.log(content)
102
+ throw new Error(message)
103
+ }
104
+ this._archive.append(content, { name: internalPath })
105
+ }
106
+
107
+ /**
108
+ * @param {string} pathToFile — Path to file in the filesystem
109
+ * @param {string} internalPath — Path inside the archive
110
+ */
111
+ includeFile(pathToFile, internalPath) {
112
+ this._archive.file(pathToFile, { name: internalPath })
113
+ }
114
+
115
+ /**
116
+ * @param {string} pathToDirectory — Path to directory in the filesystem.
117
+ * @param {string} filePathPattern — File path "glob" pattern. Example: "file*.txt".
118
+ */
119
+ includeFilesByMatch(pathToDirectory, filePathPattern) {
120
+ this._archive.glob(filePathPattern, { cwd: pathToDirectory })
121
+ }
122
+
123
+ /**
124
+ * @param {string} pathToDirectory — Path to directory in the filesystem
125
+ * @param {string} [internalPath] — Path inside the archive. Omitting this argument will put the contents of the directory to the root of the archive.
126
+ */
127
+ includeDirectory(pathToDirectory, internalPath) {
128
+ this._archive.directory(pathToDirectory, internalPath || false);
129
+ }
130
+
131
+ /**
132
+ * Starts the process of writing the archive file data.
133
+ * @returns {stream.Readable}
134
+ */
135
+ write() {
136
+ // `.finalize()` starts the process of writing the archive file.
137
+ //
138
+ // `.finalize()` also returns some kind of `Promise` but it's some kind of a weird one
139
+ // and is not meant to be `await`ed or anything like that.
140
+ // https://github.com/archiverjs/node-archiver/issues/772
141
+ //
142
+ // "close", "end" or "finish" events may be fired on `this._archive`
143
+ // right after calling this method, so any required event handlers
144
+ // should have been added beforehand.
145
+ //
146
+ this._archive.finalize()
147
+
148
+ // Returns a readable `Stream` with the `.zip` archive data.
149
+ return this._outputStream
150
+ }
151
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archiver-node",
3
- "version": "8.0.5",
3
+ "version": "8.0.7",
4
4
  "description": "a streaming interface for archive generation",
5
5
  "homepage": "https://github.com/catamphetamine/node-archiver",
6
6
  "author": {
@@ -22,15 +22,13 @@
22
22
  "import": "./index.js",
23
23
  "require": "./index.cjs"
24
24
  },
25
+ "./zip": {
26
+ "types": "./zip/index.d.ts",
27
+ "import": "./zip/index.js",
28
+ "require": "./zip/index.cjs"
29
+ },
25
30
  "./package.json": "./package.json"
26
31
  },
27
- "files": [
28
- "index.js",
29
- "index.cjs",
30
- "index.d.ts",
31
- "lib",
32
- "cjs"
33
- ],
34
32
  "engines": {
35
33
  "node": ">=18"
36
34
  },
package/zip/index.cjs ADDED
@@ -0,0 +1 @@
1
+ module.exports = require("../cjs/exports/zip.js").default;
package/zip/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import * as stream from 'stream'
2
+
3
+ import { ZipOptions } from '../index.d.js';
4
+
5
+ export default class ZipArchive {
6
+ constructor(options?: ZipOptions);
7
+ add(content: stream.Readable | Buffer | string, internalPath: string): void;
8
+ includeFile(pathToFile: string, internalPath: string): void;
9
+ includeFilesByMatch(pathToDirectory: string, filePathPattern: string): void;
10
+ includeDirectory(pathToDirectory: string, internalPath?: string): void;
11
+ write(): stream.Readable;
12
+ promise: Promise<void>;
13
+ size?: number;
14
+ }
package/zip/index.js ADDED
@@ -0,0 +1 @@
1
+ export { default } from "../lib/exports/zip.js";
@@ -0,0 +1,14 @@
1
+ {
2
+ "private": true,
3
+ "name": "archiver-node/zip",
4
+ "version": "1.0.0",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./index.d.ts",
9
+ "import": "./index.js",
10
+ "require": "./index.cjs"
11
+ }
12
+ },
13
+ "sideEffects": false
14
+ }