archiver-node 8.0.6 → 8.0.8

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.
package/README.md CHANGED
@@ -34,13 +34,15 @@ archive.includeFile("/path/to/file4.txt", "file4.txt")
34
34
  // Add a directory from disk.
35
35
  archive.includeDirectory("/path/to/directory", "directory")
36
36
 
37
- // Add a directory from disk, putting its contents at the root of archive.
37
+ // Add a directory from disk, putting its contents at the root of archive,
38
+ // i.e. without creating a sub-directory.
38
39
  archive.includeDirectory("/path/to/directory")
39
40
 
40
- // Add all files matching a "glob" pattern.
41
+ // Add all files that match a "glob" pattern relative to a certain directory.
41
42
  archive.includeFilesByMatch("/path/to/directory", "file*.txt")
42
43
 
43
- // Finalize the archive, i.e. we are done adding files to it.
44
+ // Finalize the archive, i.e. nothing else will be added to it.
45
+ // It will start writing the archive data from this point.
44
46
  const archiveDataStream = archive.write()
45
47
 
46
48
  // Pipe the archive data to an output stream.
@@ -66,7 +68,7 @@ const archive = new ZipArchive({
66
68
  zlib: { level: 9 }
67
69
  })
68
70
 
69
- // catch "non-critical" errors
71
+ // Catch "non-critical" errors.
70
72
  archive.on("warning", (error) => {
71
73
  if (error.code === "ENOENT") {
72
74
  console.warn(error)
@@ -75,37 +77,44 @@ archive.on("warning", (error) => {
75
77
  }
76
78
  })
77
79
 
78
- // catch errors
80
+ // Catch errors.
79
81
  archive.on("error", (error) => {
80
82
  throw error
81
83
  })
82
84
 
83
- // pipe archive data to the file
85
+ // Pipe the archive data to an output stream.
86
+ // The archive data will start being written as soon as `.finalize()` is called.
84
87
  archive.pipe(fs.createWriteStream("/path/to/archive.zip"))
85
88
 
86
- // append a file from stream
89
+ // Add a file from stream.
87
90
  archive.append(fs.createReadStream("/path/to/file1.txt"), { name: "file1.txt" })
88
91
 
89
- // append a file from string
92
+ // Add a file from string.
90
93
  archive.append("some text", { name: "file2.txt" })
91
94
 
92
- // append a file from buffer
95
+ // Add a file from buffer.
93
96
  archive.append(Buffer.from(...);, { name: "file3.txt" })
94
97
 
95
- // append a file
98
+ // Add a file from disk.
96
99
  archive.file("/path/to/file4.txt", { name: "file4.txt" })
97
100
 
98
- // append files from a sub-directory and naming it `new-subdir` within the archive
101
+ // Add a directory from disk.
99
102
  archive.directory("/path/to/directory", "directory")
100
103
 
101
- // append files from a sub-directory, putting its contents at the root of archive
104
+ // Add a directory from disk, putting its contents at the root of archive,
105
+ // i.e. without creating a sub-directory.
102
106
  archive.directory("/path/to/directory", false)
103
107
 
104
- // append files from a glob pattern
108
+ // Add all files that match a "glob" pattern relative to a certain directory.
105
109
  archive.glob("file*.txt", { cwd: "/path/to/directory" })
106
110
 
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
111
+ // Finalize the archive, i.e. nothing else will be added to it.
112
+ // It will start writing the archive data from this point.
113
+ //
114
+ // "close", "end" or "finish" events may start being emitted on the `archive` instance
115
+ // or the output stream right after calling this method, so add any required event listeners
116
+ // on any of those streams beforehand.
117
+ //
109
118
  archive.finalize()
110
119
  ```
111
120
 
@@ -118,14 +127,15 @@ class NewTypeOfArchive extends Archiver {
118
127
  constructor(options) {
119
128
  super(options)
120
129
  this._format = "new-type-of-archive"
121
- this._module = new NewTypeOfArchiveImplementation(options)
130
+ this._module = new NewTypeOfArchiveModule(options)
122
131
  this._supportsDirectory = true
123
132
  this._supportsSymlink = true
124
133
  this._modulePipe()
125
134
  }
126
135
  }
127
136
 
128
- class NewTypeOfArchiveImplementation {
137
+ // See TypeScript definition of `Module` class.
138
+ class NewTypeOfArchiveModule {
129
139
  constructor(options) { ... }
130
140
  append(source, data, callback) { ... }
131
141
  finalize() { ... }
package/index.d.ts CHANGED
@@ -28,12 +28,13 @@ interface EntryData {
28
28
  stats?: fs.Stats | undefined;
29
29
  }
30
30
 
31
- interface ZipEntryData extends EntryData {
31
+ interface ZipEntryData {
32
32
  /** Sets the compression method to STORE */
33
33
  store?: boolean | undefined;
34
34
  }
35
35
 
36
- type TarEntryData = EntryData;
36
+ interface TarEntryData {}
37
+ interface JsonEntryData {}
37
38
 
38
39
  interface ProgressData {
39
40
  entries: {
@@ -49,7 +50,7 @@ interface ProgressData {
49
50
  /** A function that lets you either opt out of including an entry (by returning false), or modify the contents of an entry as it is added (by returning an EntryData) */
50
51
  type EntryDataFunction = (entry: EntryData) => false | EntryData;
51
52
 
52
- class ArchiverError extends Error {
53
+ declare class ArchiverError extends Error {
53
54
  code: string; // Since archiver format support is modular, we cannot enumerate all possible error codes, as the modules can throw arbitrary ones.
54
55
  data: any;
55
56
  path?: any;
@@ -88,22 +89,48 @@ interface TarOptions {
88
89
  gzipOptions?: ZlibOptions | undefined;
89
90
  }
90
91
 
91
- export class Archiver extends stream.Transform {
92
+ interface JsonOptions {}
93
+
94
+ declare class Module<Options, AdditionalEntryData> {
95
+ constructor(options?: Options);
96
+
97
+ append(
98
+ source: Buffer | stream.Readable,
99
+ data: EntryData & AdditionalEntryData,
100
+ // If there's an `error` argument, it doesn't pass the `data` argument.
101
+ // Otherwise, when `error` argument is `null`, it does pass the `same `data` argument
102
+ // that was passed when calling the `append()` function, with potential modifications to it
103
+ // such as setting the values of some of its properties.
104
+ callback: (error: Error | null, data?: EntryData & AdditionalEntryData) => void
105
+ ): void;
106
+
107
+ on(event: "end", listener: () => void): void;
108
+ on(event: "error", listener: (error: Error) => void): void;
109
+
110
+ finalize(): void;
111
+ pipe(): void;
112
+ unpipe(): void;
113
+ }
114
+
115
+ export class Archiver<
116
+ ModuleOptions extends Record<string, any>,
117
+ AdditionalEntryData extends Record<string, any>
118
+ > extends stream.Transform {
92
119
  _format: string;
93
- _module: Module;
120
+ _module: Module<ModuleOptions, AdditionalEntryData>;
94
121
  _supportsDirectory: boolean;
95
122
  _supportsSymlink: boolean;
96
123
  _modulePipe: () => void;
97
124
 
98
- constructor(options?: ArchiverOptions);
125
+ constructor(options?: ArchiverOptions & ModuleOptions);
99
126
 
100
127
  abort(): this;
101
- append(source: stream.Readable | Buffer | string, data?: EntryData | ZipEntryData | TarEntryData): this;
128
+ append(source: stream.Readable | Buffer | string, data?: EntryData & AdditionalEntryData): this;
102
129
 
103
130
  /** if false is passed for destpath, the path of a chunk of data in the archive is set to the root */
104
- directory(dirpath: string, destpath: false | string, data?: Partial<EntryData> | EntryDataFunction): this;
105
- file(filename: string, data: EntryData): this;
106
- glob(pattern: string, options?: GlobOptions, data?: Partial<EntryData>): this;
131
+ directory(dirpath: string, destpath: false | string, data?: Partial<EntryData & AdditionalEntryData> | EntryDataFunction): this;
132
+ file(filename: string, data: EntryData & AdditionalEntryData): this;
133
+ glob(pattern: string, options?: GlobOptions, data?: Partial<EntryData & AdditionalEntryData>): this;
107
134
  finalize(): Promise<void>;
108
135
 
109
136
  setFormat(format: string): this;
@@ -121,18 +148,10 @@ export class Archiver extends stream.Transform {
121
148
  on(event: "progress", listener: (progress: ProgressData) => void): this;
122
149
  on(event: "close" | "drain" | "finish", listener: () => void): this;
123
150
  on(event: "pipe" | "unpipe", listener: (src: stream.Readable) => void): this;
124
- on(event: "entry", listener: (entry: EntryData) => void): this;
151
+ on(event: "entry", listener: (entry: EntryData & AdditionalEntryData) => void): this;
125
152
  on(event: string, listener: (...args: any[]) => void): this;
126
153
  }
127
154
 
128
- export class ZipArchive extends Archiver {
129
- constructor(options?: ArchiverOptions & ZipOptions);
130
- }
131
-
132
- export class TarArchive extends Archiver {
133
- constructor(options?: ArchiverOptions & TarOptions);
134
- }
135
-
136
- export class JsonArchive extends Archiver {
137
- constructor(options?: ArchiverOptions);
138
- }
155
+ export class ZipArchive extends Archiver<ZipOptions, ZipEntryData> {}
156
+ export class TarArchive extends Archiver<TarOptions, TarEntryData> {}
157
+ export class JsonArchive extends Archiver<JsonOptions, JsonEntryData> {}
@@ -48,21 +48,34 @@ export default class ZipArchive {
48
48
  // A `Promise<void>` that resolves when the archive has been written.
49
49
  this.promise = new Promise((resolve, reject) => {
50
50
  // Listens for all archive data to be written.
51
- // 'close' event is fired when all data has been written.
51
+ // "close" event is fired when all data has been written.
52
+ //
53
+ // P.S. Not all stream types are guaranteed to emit the "close" event.
54
+ // For example, a standard `process.stdout` stream may stay open
55
+ // for the life of the process and not output a "close" event,
56
+ // but an `fs.createWriteStream()` will typically emit a "close" event.
57
+ //
58
+ // In Node.js streams, the "finish" event signifies that all data has been
59
+ // successfully flushed to the underlying system, while the "close" event
60
+ // indicates that the stream's underlying resource (like a file descriptor)
61
+ // has been fully shut down. The "finish" event always occurs before the "close" event
62
+ // in a normal, successful operation.
63
+ //
64
+ // If you need to know when you can safely perform an action that requires
65
+ // all data to be persisted (like reading a file you just wrote), you should
66
+ // wait for the "close" event. If you only need to know when you can stop writing
67
+ // more data to the stream, the finish "event" is sufficient.
68
+ //
52
69
  this._outputStream.on('close', () => {
53
70
  this.size = archive.pointer()
54
71
  resolve()
55
72
  })
56
73
 
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.
74
+ // Catch "warnings":
75
+ // * `ArchiverError("DIRECTORYNOTSUPPORTED")` When the type of archive doesn't support creating directories inside of it.
76
+ // * `ArchiverError("SYMLINKNOTSUPPORTED")` — When the type of archive doesn't support creating symlinks inside of it.
77
+ // * `ArchiverError("ENTRYNOTSUPPORTED")` — When the type of archive doesn't support adding a particular "entry" to it: one that's neither a file, nor a directory, nor a symlink. This seems to be some kind of "future proofing".
78
+ // * `fs.lstat()` errors, such as `{ code: "ENOENT" }` when the file is not found. `Archiver` calls `fs.lstat()` on every `.append(filepath, object)` call in order to determine the file size. After the file size has been determined, it puts the file to the "main queue" for writing it inside the archive.
66
79
  archive.on('warning', function(error) {
67
80
  reject(error)
68
81
  // The following code sample is from `archiver` README:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archiver-node",
3
- "version": "8.0.6",
3
+ "version": "8.0.8",
4
4
  "description": "a streaming interface for archive generation",
5
5
  "homepage": "https://github.com/catamphetamine/node-archiver",
6
6
  "author": {
@@ -22,6 +22,11 @@
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
32
  "engines": {