@neoware_inc/neozipkit 0.5.0
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 +134 -0
- package/dist/browser/ZipkitBrowser.d.ts +27 -0
- package/dist/browser/ZipkitBrowser.d.ts.map +1 -0
- package/dist/browser/ZipkitBrowser.js +303 -0
- package/dist/browser/ZipkitBrowser.js.map +1 -0
- package/dist/browser/index.d.ts +9 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.esm.d.ts +12 -0
- package/dist/browser/index.esm.d.ts.map +1 -0
- package/dist/browser/index.esm.js +46 -0
- package/dist/browser/index.esm.js.map +1 -0
- package/dist/browser/index.js +38 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser-esm/index.d.ts +9 -0
- package/dist/browser-esm/index.js +50211 -0
- package/dist/browser-esm/index.js.map +7 -0
- package/dist/browser-umd/index.d.ts +9 -0
- package/dist/browser-umd/index.js +50221 -0
- package/dist/browser-umd/index.js.map +7 -0
- package/dist/browser-umd/index.min.js +39 -0
- package/dist/browser.d.ts +9 -0
- package/dist/browser.js +38 -0
- package/dist/core/ZipCompress.d.ts +99 -0
- package/dist/core/ZipCompress.d.ts.map +1 -0
- package/dist/core/ZipCompress.js +287 -0
- package/dist/core/ZipCompress.js.map +1 -0
- package/dist/core/ZipCopy.d.ts +175 -0
- package/dist/core/ZipCopy.d.ts.map +1 -0
- package/dist/core/ZipCopy.js +310 -0
- package/dist/core/ZipCopy.js.map +1 -0
- package/dist/core/ZipDecompress.d.ts +57 -0
- package/dist/core/ZipDecompress.d.ts.map +1 -0
- package/dist/core/ZipDecompress.js +155 -0
- package/dist/core/ZipDecompress.js.map +1 -0
- package/dist/core/ZipEntry.d.ts +138 -0
- package/dist/core/ZipEntry.d.ts.map +1 -0
- package/dist/core/ZipEntry.js +829 -0
- package/dist/core/ZipEntry.js.map +1 -0
- package/dist/core/Zipkit.d.ts +315 -0
- package/dist/core/Zipkit.d.ts.map +1 -0
- package/dist/core/Zipkit.js +647 -0
- package/dist/core/Zipkit.js.map +1 -0
- package/dist/core/ZstdManager.d.ts +56 -0
- package/dist/core/ZstdManager.d.ts.map +1 -0
- package/dist/core/ZstdManager.js +144 -0
- package/dist/core/ZstdManager.js.map +1 -0
- package/dist/core/components/HashCalculator.d.ts +138 -0
- package/dist/core/components/HashCalculator.d.ts.map +1 -0
- package/dist/core/components/HashCalculator.js +360 -0
- package/dist/core/components/HashCalculator.js.map +1 -0
- package/dist/core/components/Logger.d.ts +73 -0
- package/dist/core/components/Logger.d.ts.map +1 -0
- package/dist/core/components/Logger.js +156 -0
- package/dist/core/components/Logger.js.map +1 -0
- package/dist/core/components/ProgressTracker.d.ts +43 -0
- package/dist/core/components/ProgressTracker.d.ts.map +1 -0
- package/dist/core/components/ProgressTracker.js +112 -0
- package/dist/core/components/ProgressTracker.js.map +1 -0
- package/dist/core/components/Support.d.ts +64 -0
- package/dist/core/components/Support.d.ts.map +1 -0
- package/dist/core/components/Support.js +71 -0
- package/dist/core/components/Support.js.map +1 -0
- package/dist/core/components/Util.d.ts +26 -0
- package/dist/core/components/Util.d.ts.map +1 -0
- package/dist/core/components/Util.js +95 -0
- package/dist/core/components/Util.js.map +1 -0
- package/dist/core/constants/Errors.d.ts +52 -0
- package/dist/core/constants/Errors.d.ts.map +1 -0
- package/dist/core/constants/Errors.js +67 -0
- package/dist/core/constants/Errors.js.map +1 -0
- package/dist/core/constants/Headers.d.ts +170 -0
- package/dist/core/constants/Headers.d.ts.map +1 -0
- package/dist/core/constants/Headers.js +194 -0
- package/dist/core/constants/Headers.js.map +1 -0
- package/dist/core/encryption/Manager.d.ts +58 -0
- package/dist/core/encryption/Manager.d.ts.map +1 -0
- package/dist/core/encryption/Manager.js +121 -0
- package/dist/core/encryption/Manager.js.map +1 -0
- package/dist/core/encryption/ZipCrypto.d.ts +172 -0
- package/dist/core/encryption/ZipCrypto.d.ts.map +1 -0
- package/dist/core/encryption/ZipCrypto.js +554 -0
- package/dist/core/encryption/ZipCrypto.js.map +1 -0
- package/dist/core/encryption/index.d.ts +9 -0
- package/dist/core/encryption/index.d.ts.map +1 -0
- package/dist/core/encryption/index.js +17 -0
- package/dist/core/encryption/index.js.map +1 -0
- package/dist/core/encryption/types.d.ts +29 -0
- package/dist/core/encryption/types.d.ts.map +1 -0
- package/dist/core/encryption/types.js +12 -0
- package/dist/core/encryption/types.js.map +1 -0
- package/dist/core/index.d.ts +27 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +59 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/version.d.ts +5 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +31 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/node/ZipCompressNode.d.ts +123 -0
- package/dist/node/ZipCompressNode.d.ts.map +1 -0
- package/dist/node/ZipCompressNode.js +565 -0
- package/dist/node/ZipCompressNode.js.map +1 -0
- package/dist/node/ZipCopyNode.d.ts +165 -0
- package/dist/node/ZipCopyNode.d.ts.map +1 -0
- package/dist/node/ZipCopyNode.js +347 -0
- package/dist/node/ZipCopyNode.js.map +1 -0
- package/dist/node/ZipDecompressNode.d.ts +197 -0
- package/dist/node/ZipDecompressNode.d.ts.map +1 -0
- package/dist/node/ZipDecompressNode.js +678 -0
- package/dist/node/ZipDecompressNode.js.map +1 -0
- package/dist/node/ZipkitNode.d.ts +466 -0
- package/dist/node/ZipkitNode.d.ts.map +1 -0
- package/dist/node/ZipkitNode.js +1426 -0
- package/dist/node/ZipkitNode.js.map +1 -0
- package/dist/node/index.d.ts +25 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +54 -0
- package/dist/node/index.js.map +1 -0
- package/dist/types/index.d.ts +45 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/examples/README.md +261 -0
- package/examples/append-data.json +44 -0
- package/examples/copy-zip-append.ts +139 -0
- package/examples/copy-zip.ts +152 -0
- package/examples/create-zip.ts +172 -0
- package/examples/extract-zip.ts +118 -0
- package/examples/list-zip.ts +161 -0
- package/examples/test-files/data.json +116 -0
- package/examples/test-files/document.md +80 -0
- package/examples/test-files/document.txt +6 -0
- package/examples/test-files/file1.txt +48 -0
- package/examples/test-files/file2.txt +80 -0
- package/examples/tsconfig.json +44 -0
- package/package.json +167 -0
- package/src/browser/ZipkitBrowser.ts +305 -0
- package/src/browser/index.esm.ts +32 -0
- package/src/browser/index.ts +19 -0
- package/src/core/ZipCompress.ts +370 -0
- package/src/core/ZipCopy.ts +434 -0
- package/src/core/ZipDecompress.ts +191 -0
- package/src/core/ZipEntry.ts +917 -0
- package/src/core/Zipkit.ts +794 -0
- package/src/core/ZstdManager.ts +165 -0
- package/src/core/components/HashCalculator.ts +384 -0
- package/src/core/components/Logger.ts +180 -0
- package/src/core/components/ProgressTracker.ts +134 -0
- package/src/core/components/Support.ts +77 -0
- package/src/core/components/Util.ts +91 -0
- package/src/core/constants/Errors.ts +78 -0
- package/src/core/constants/Headers.ts +205 -0
- package/src/core/encryption/Manager.ts +137 -0
- package/src/core/encryption/ZipCrypto.ts +650 -0
- package/src/core/encryption/index.ts +15 -0
- package/src/core/encryption/types.ts +33 -0
- package/src/core/index.ts +42 -0
- package/src/core/version.ts +33 -0
- package/src/index.ts +19 -0
- package/src/node/ZipCompressNode.ts +618 -0
- package/src/node/ZipCopyNode.ts +437 -0
- package/src/node/ZipDecompressNode.ts +793 -0
- package/src/node/ZipkitNode.ts +1706 -0
- package/src/node/index.ts +40 -0
- package/src/types/index.ts +68 -0
- package/src/types/modules.d.ts +22 -0
- package/src/types/opentimestamps.d.ts +1 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import ZipEntry from '../core/ZipEntry';
|
|
2
|
+
import ZipkitNode from './ZipkitNode';
|
|
3
|
+
/**
|
|
4
|
+
* Options for copying ZIP files
|
|
5
|
+
*/
|
|
6
|
+
export interface CopyOptions {
|
|
7
|
+
/** Filter function to determine which entries to copy */
|
|
8
|
+
entryFilter?: (entry: ZipEntry) => boolean;
|
|
9
|
+
/** Sort function to reorder entries before copying */
|
|
10
|
+
entrySorter?: (a: ZipEntry, b: ZipEntry) => number;
|
|
11
|
+
/** Whether to preserve the ZIP file comment (default: true) */
|
|
12
|
+
preserveComments?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Result of copying a ZIP file
|
|
16
|
+
*/
|
|
17
|
+
export interface CopyResult {
|
|
18
|
+
/** Information about copied entries */
|
|
19
|
+
entries: Array<{
|
|
20
|
+
filename: string;
|
|
21
|
+
localHeaderOffset: number;
|
|
22
|
+
compressedSize: number;
|
|
23
|
+
}>;
|
|
24
|
+
/** Offset to the start of the central directory */
|
|
25
|
+
centralDirOffset: number;
|
|
26
|
+
/** Total number of entries copied */
|
|
27
|
+
totalEntries: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Result of copying only ZIP entry data (no central directory or EOCD).
|
|
31
|
+
* Use with writeCentralDirectoryAndEOCD after optionally adding more entries
|
|
32
|
+
* to allow building a ZIP that includes both copied and new entries.
|
|
33
|
+
*/
|
|
34
|
+
export interface CopyEntriesOnlyResult {
|
|
35
|
+
/** Path to the destination file (entry data only; not yet a valid ZIP) */
|
|
36
|
+
destPath: string;
|
|
37
|
+
/** Offset at which entry data ends; central directory should start here after any new entries are appended */
|
|
38
|
+
dataEndOffset: number;
|
|
39
|
+
/** Copied entries with localHdrOffset set for the destination file */
|
|
40
|
+
copiedEntries: ZipEntry[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Options for finalizing a ZIP file (writing central directory and EOCD)
|
|
44
|
+
*/
|
|
45
|
+
export interface FinalizeZipOptions {
|
|
46
|
+
/** ZIP file comment (default: empty) */
|
|
47
|
+
zipComment?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Efficient ZIP file copying class
|
|
51
|
+
*
|
|
52
|
+
* Uses ZipEntry instances directly to copy entries without decompression/recompression.
|
|
53
|
+
* Supports filtering and reordering entries while maintaining ZIP file validity.
|
|
54
|
+
*
|
|
55
|
+
* Entry data and the central directory / EOCD are separated so you can add files
|
|
56
|
+
* to the copy before finalizing: use copyZipEntriesOnly, append new entries at
|
|
57
|
+
* dataEndOffset, then call writeCentralDirectoryAndEOCD with all entries.
|
|
58
|
+
*
|
|
59
|
+
* @example Full copy (one shot)
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const zipCopy = new ZipCopyNode(new ZipkitNode());
|
|
62
|
+
* const result = await zipCopy.copyZipFile('source.zip', 'dest.zip', {
|
|
63
|
+
* entryFilter: (entry) => !entry.filename.startsWith('.'),
|
|
64
|
+
* entrySorter: (a, b) => a.filename.localeCompare(b.filename)
|
|
65
|
+
* });
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @example Copy then add files before finalizing
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const zipCopy = new ZipCopyNode(new ZipkitNode());
|
|
71
|
+
* const { destPath, dataEndOffset, copiedEntries } = await zipCopy.copyZipEntriesOnly('source.zip', 'dest.zip');
|
|
72
|
+
* // ... append new entries to destPath at dataEndOffset, collect new ZipEntry[] with localHdrOffset set ...
|
|
73
|
+
* const allEntries = [...copiedEntries, ...newEntries];
|
|
74
|
+
* zipCopy.writeCentralDirectoryAndEOCD(destPath, allEntries, { zipComment: '' });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare class ZipCopyNode {
|
|
78
|
+
private zipkitNode;
|
|
79
|
+
/**
|
|
80
|
+
* Creates a new ZipCopyNode instance
|
|
81
|
+
* @param zipkitNode - Optional ZipkitNode instance. If not provided, creates a new one.
|
|
82
|
+
*/
|
|
83
|
+
constructor(zipkitNode?: ZipkitNode);
|
|
84
|
+
/**
|
|
85
|
+
* Calculate local header size by reading the actual local header
|
|
86
|
+
*
|
|
87
|
+
* Reads the first 30 bytes of the local header to get the exact
|
|
88
|
+
* filename and extra field lengths, ensuring accuracy even when
|
|
89
|
+
* local header differs from central directory.
|
|
90
|
+
*
|
|
91
|
+
* @param sourceFd - File descriptor for source ZIP file
|
|
92
|
+
* @param entry - ZipEntry with localHdrOffset
|
|
93
|
+
* @returns Size of the local header in bytes
|
|
94
|
+
*/
|
|
95
|
+
private calculateLocalHeaderSize;
|
|
96
|
+
/**
|
|
97
|
+
* Copy entry bytes directly from source to destination
|
|
98
|
+
*
|
|
99
|
+
* Copies the local header and compressed data as a single operation.
|
|
100
|
+
*
|
|
101
|
+
* Handles various entry types:
|
|
102
|
+
* - Normal entries: [local header][filename][extra][compressed data]
|
|
103
|
+
* - Encrypted entries: compressedSize includes 12-byte encryption header
|
|
104
|
+
* - Data descriptor entries: [local header][filename][extra][data][data descriptor (16 bytes)]
|
|
105
|
+
*
|
|
106
|
+
* For data descriptor entries, the local header has compressed size = 0,
|
|
107
|
+
* but the actual size is in the central directory (entry.compressedSize).
|
|
108
|
+
*
|
|
109
|
+
* @param sourceFd - File descriptor for source ZIP file
|
|
110
|
+
* @param destFd - File descriptor for destination ZIP file
|
|
111
|
+
* @param entry - ZipEntry with source offset information
|
|
112
|
+
* @returns Number of bytes written
|
|
113
|
+
*/
|
|
114
|
+
private copyEntryBytes;
|
|
115
|
+
/**
|
|
116
|
+
* Clone a ZipEntry with a new local header offset
|
|
117
|
+
*
|
|
118
|
+
* Creates a new ZipEntry instance with all properties copied from the source,
|
|
119
|
+
* but with an updated localHdrOffset for the destination file.
|
|
120
|
+
*
|
|
121
|
+
* @param entry - Source ZipEntry to clone
|
|
122
|
+
* @param newLocalHdrOffset - New local header offset for the destination
|
|
123
|
+
* @returns New ZipEntry instance with updated offset
|
|
124
|
+
*/
|
|
125
|
+
private cloneEntryWithOffset;
|
|
126
|
+
/**
|
|
127
|
+
* Write central directory and End of Central Directory record to an open file descriptor.
|
|
128
|
+
* Used internally by copyZipFile and by writeCentralDirectoryAndEOCD.
|
|
129
|
+
*/
|
|
130
|
+
private writeCentralDirectoryAndEOCDToFd;
|
|
131
|
+
/**
|
|
132
|
+
* Copy only ZIP entry data to the destination file (no central directory or EOCD).
|
|
133
|
+
* Use this when you want to add more entries before finalizing. Then call
|
|
134
|
+
* writeCentralDirectoryAndEOCD with all entries (copied + new) to produce a valid ZIP.
|
|
135
|
+
*
|
|
136
|
+
* @param sourceZipPath - Path to source ZIP file
|
|
137
|
+
* @param destZipPath - Path to destination file (will contain only entry data until finalized)
|
|
138
|
+
* @param options - Optional copy options (filtering, sorting)
|
|
139
|
+
* @returns Result with dataEndOffset and copiedEntries for use when adding files and finalizing
|
|
140
|
+
*/
|
|
141
|
+
copyZipEntriesOnly(sourceZipPath: string, destZipPath: string, options?: CopyOptions): Promise<CopyEntriesOnlyResult>;
|
|
142
|
+
/**
|
|
143
|
+
* Append central directory and End of Central Directory to a file that already
|
|
144
|
+
* contains ZIP entry data (e.g. from copyZipEntriesOnly plus any newly added entries).
|
|
145
|
+
* Call this after adding files to produce a valid ZIP.
|
|
146
|
+
*
|
|
147
|
+
* @param destZipPath - Path to the partial ZIP file (entry data only)
|
|
148
|
+
* @param entries - All entries in order (copied + any new), each with localHdrOffset set
|
|
149
|
+
* @param options - Optional finalize options (e.g. zipComment)
|
|
150
|
+
*/
|
|
151
|
+
writeCentralDirectoryAndEOCD(destZipPath: string, entries: ZipEntry[], options?: FinalizeZipOptions): void;
|
|
152
|
+
/**
|
|
153
|
+
* Copy ZIP file entries efficiently
|
|
154
|
+
*
|
|
155
|
+
* Main method that copies entries from source ZIP to destination ZIP.
|
|
156
|
+
* Uses ZipEntry instances directly to avoid unnecessary parsing.
|
|
157
|
+
*
|
|
158
|
+
* @param sourceZipPath - Path to source ZIP file
|
|
159
|
+
* @param destZipPath - Path to destination ZIP file
|
|
160
|
+
* @param options - Optional copy options (filtering, sorting, etc.)
|
|
161
|
+
* @returns Copy result with entry information
|
|
162
|
+
*/
|
|
163
|
+
copyZipFile(sourceZipPath: string, destZipPath: string, options?: CopyOptions): Promise<CopyResult>;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=ZipCopyNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZipCopyNode.d.ts","sourceRoot":"","sources":["../../src/node/ZipCopyNode.ts"],"names":[],"mappings":"AAUA,OAAO,QAAQ,MAAM,kBAAkB,CAAC;AACxC,OAAO,UAAU,MAAM,cAAc,CAAC;AAGtC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC;IAC3C,sDAAsD;IACtD,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,KAAK,MAAM,CAAC;IACnD,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,OAAO,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;IACH,mDAAmD;IACnD,gBAAgB,EAAE,MAAM,CAAC;IACzB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,8GAA8G;IAC9G,aAAa,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,aAAa,EAAE,QAAQ,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,CAAa;IAE/B;;;OAGG;gBACS,UAAU,CAAC,EAAE,UAAU;IAInC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,wBAAwB;IAoBhC;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,cAAc;IAiDtB;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAoD5B;;;OAGG;IACH,OAAO,CAAC,gCAAgC;IA8CxC;;;;;;;;;OASG;IACG,kBAAkB,CACtB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,qBAAqB,CAAC;IAyCjC;;;;;;;;OAQG;IACH,4BAA4B,CAC1B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,QAAQ,EAAE,EACnB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,IAAI;IAeP;;;;;;;;;;OAUG;IACG,WAAW,CACf,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,UAAU,CAAC;CAyBvB"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ======================================
|
|
3
|
+
// ZipCopyNode.ts - Efficient ZIP Entry Copying
|
|
4
|
+
// Copyright (c) 2025 NeoWare, Inc. All rights reserved.
|
|
5
|
+
// ======================================
|
|
6
|
+
//
|
|
7
|
+
// Efficient ZIP entry copying using ZipEntry instances directly.
|
|
8
|
+
// Leverages existing offsets and sizes to copy raw bytes without
|
|
9
|
+
// unnecessary parsing and reconstruction.
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
44
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
45
|
+
};
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.ZipCopyNode = void 0;
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const ZipEntry_1 = __importDefault(require("../core/ZipEntry"));
|
|
50
|
+
const ZipkitNode_1 = __importDefault(require("./ZipkitNode"));
|
|
51
|
+
const Headers_1 = require("../core/constants/Headers");
|
|
52
|
+
/**
|
|
53
|
+
* Efficient ZIP file copying class
|
|
54
|
+
*
|
|
55
|
+
* Uses ZipEntry instances directly to copy entries without decompression/recompression.
|
|
56
|
+
* Supports filtering and reordering entries while maintaining ZIP file validity.
|
|
57
|
+
*
|
|
58
|
+
* Entry data and the central directory / EOCD are separated so you can add files
|
|
59
|
+
* to the copy before finalizing: use copyZipEntriesOnly, append new entries at
|
|
60
|
+
* dataEndOffset, then call writeCentralDirectoryAndEOCD with all entries.
|
|
61
|
+
*
|
|
62
|
+
* @example Full copy (one shot)
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const zipCopy = new ZipCopyNode(new ZipkitNode());
|
|
65
|
+
* const result = await zipCopy.copyZipFile('source.zip', 'dest.zip', {
|
|
66
|
+
* entryFilter: (entry) => !entry.filename.startsWith('.'),
|
|
67
|
+
* entrySorter: (a, b) => a.filename.localeCompare(b.filename)
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example Copy then add files before finalizing
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const zipCopy = new ZipCopyNode(new ZipkitNode());
|
|
74
|
+
* const { destPath, dataEndOffset, copiedEntries } = await zipCopy.copyZipEntriesOnly('source.zip', 'dest.zip');
|
|
75
|
+
* // ... append new entries to destPath at dataEndOffset, collect new ZipEntry[] with localHdrOffset set ...
|
|
76
|
+
* const allEntries = [...copiedEntries, ...newEntries];
|
|
77
|
+
* zipCopy.writeCentralDirectoryAndEOCD(destPath, allEntries, { zipComment: '' });
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
class ZipCopyNode {
|
|
81
|
+
/**
|
|
82
|
+
* Creates a new ZipCopyNode instance
|
|
83
|
+
* @param zipkitNode - Optional ZipkitNode instance. If not provided, creates a new one.
|
|
84
|
+
*/
|
|
85
|
+
constructor(zipkitNode) {
|
|
86
|
+
this.zipkitNode = zipkitNode || new ZipkitNode_1.default();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Calculate local header size by reading the actual local header
|
|
90
|
+
*
|
|
91
|
+
* Reads the first 30 bytes of the local header to get the exact
|
|
92
|
+
* filename and extra field lengths, ensuring accuracy even when
|
|
93
|
+
* local header differs from central directory.
|
|
94
|
+
*
|
|
95
|
+
* @param sourceFd - File descriptor for source ZIP file
|
|
96
|
+
* @param entry - ZipEntry with localHdrOffset
|
|
97
|
+
* @returns Size of the local header in bytes
|
|
98
|
+
*/
|
|
99
|
+
calculateLocalHeaderSize(sourceFd, entry) {
|
|
100
|
+
// Read the fixed 30-byte local header
|
|
101
|
+
const headerBuffer = Buffer.alloc(Headers_1.LOCAL_HDR.SIZE);
|
|
102
|
+
fs.readSync(sourceFd, headerBuffer, 0, Headers_1.LOCAL_HDR.SIZE, entry.localHdrOffset);
|
|
103
|
+
// Verify signature
|
|
104
|
+
if (headerBuffer.readUInt32LE(0) !== Headers_1.LOCAL_HDR.SIGNATURE) {
|
|
105
|
+
throw new Error(`Invalid local file header signature for entry ${entry.filename} at offset ${entry.localHdrOffset}`);
|
|
106
|
+
}
|
|
107
|
+
// Read filename and extra field lengths from the actual header
|
|
108
|
+
const filenameLength = headerBuffer.readUInt16LE(Headers_1.LOCAL_HDR.FNAME_LEN);
|
|
109
|
+
const extraFieldLength = headerBuffer.readUInt16LE(Headers_1.LOCAL_HDR.EXTRA_LEN);
|
|
110
|
+
// Calculate total local header size
|
|
111
|
+
return Headers_1.LOCAL_HDR.SIZE + filenameLength + extraFieldLength;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Copy entry bytes directly from source to destination
|
|
115
|
+
*
|
|
116
|
+
* Copies the local header and compressed data as a single operation.
|
|
117
|
+
*
|
|
118
|
+
* Handles various entry types:
|
|
119
|
+
* - Normal entries: [local header][filename][extra][compressed data]
|
|
120
|
+
* - Encrypted entries: compressedSize includes 12-byte encryption header
|
|
121
|
+
* - Data descriptor entries: [local header][filename][extra][data][data descriptor (16 bytes)]
|
|
122
|
+
*
|
|
123
|
+
* For data descriptor entries, the local header has compressed size = 0,
|
|
124
|
+
* but the actual size is in the central directory (entry.compressedSize).
|
|
125
|
+
*
|
|
126
|
+
* @param sourceFd - File descriptor for source ZIP file
|
|
127
|
+
* @param destFd - File descriptor for destination ZIP file
|
|
128
|
+
* @param entry - ZipEntry with source offset information
|
|
129
|
+
* @returns Number of bytes written
|
|
130
|
+
*/
|
|
131
|
+
copyEntryBytes(sourceFd, destFd, entry) {
|
|
132
|
+
// Calculate local header size by reading the actual header
|
|
133
|
+
const localHeaderSize = this.calculateLocalHeaderSize(sourceFd, entry);
|
|
134
|
+
// Determine total entry size
|
|
135
|
+
// For data descriptor entries, add 16 bytes for the data descriptor
|
|
136
|
+
const hasDataDescriptor = (entry.bitFlags & Headers_1.GP_FLAG.DATA_DESC) !== 0;
|
|
137
|
+
const totalEntrySize = localHeaderSize + entry.compressedSize + (hasDataDescriptor ? 16 : 0);
|
|
138
|
+
// Read the entire entry (local header + compressed data + data descriptor if present) from source
|
|
139
|
+
const entryBuffer = Buffer.alloc(totalEntrySize);
|
|
140
|
+
const bytesRead = fs.readSync(sourceFd, entryBuffer, 0, totalEntrySize, entry.localHdrOffset);
|
|
141
|
+
if (bytesRead !== totalEntrySize) {
|
|
142
|
+
throw new Error(`Failed to read complete entry for ${entry.filename}: ` +
|
|
143
|
+
`expected ${totalEntrySize} bytes, got ${bytesRead}`);
|
|
144
|
+
}
|
|
145
|
+
// Verify data descriptor signature if present
|
|
146
|
+
if (hasDataDescriptor) {
|
|
147
|
+
const dataDescOffset = localHeaderSize + entry.compressedSize;
|
|
148
|
+
const dataDescSig = entryBuffer.readUInt32LE(dataDescOffset);
|
|
149
|
+
if (dataDescSig !== 0x08074b50) { // DATA_DESCRIPTOR signature
|
|
150
|
+
throw new Error(`Invalid data descriptor signature for entry ${entry.filename} ` +
|
|
151
|
+
`(expected 0x08074b50, got 0x${dataDescSig.toString(16)})`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Write to destination
|
|
155
|
+
const bytesWritten = fs.writeSync(destFd, entryBuffer, 0, totalEntrySize);
|
|
156
|
+
if (bytesWritten !== totalEntrySize) {
|
|
157
|
+
throw new Error(`Failed to write complete entry for ${entry.filename}: ` +
|
|
158
|
+
`expected ${totalEntrySize} bytes, wrote ${bytesWritten}`);
|
|
159
|
+
}
|
|
160
|
+
return bytesWritten;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Clone a ZipEntry with a new local header offset
|
|
164
|
+
*
|
|
165
|
+
* Creates a new ZipEntry instance with all properties copied from the source,
|
|
166
|
+
* but with an updated localHdrOffset for the destination file.
|
|
167
|
+
*
|
|
168
|
+
* @param entry - Source ZipEntry to clone
|
|
169
|
+
* @param newLocalHdrOffset - New local header offset for the destination
|
|
170
|
+
* @returns New ZipEntry instance with updated offset
|
|
171
|
+
*/
|
|
172
|
+
cloneEntryWithOffset(entry, newLocalHdrOffset) {
|
|
173
|
+
// Create a new ZipEntry with the same filename and comment
|
|
174
|
+
const cloned = new ZipEntry_1.default(entry.filename, entry.comment || null, entry.debug);
|
|
175
|
+
// Copy all properties
|
|
176
|
+
cloned.verMadeBy = entry.verMadeBy;
|
|
177
|
+
cloned.verExtract = entry.verExtract;
|
|
178
|
+
cloned.bitFlags = entry.bitFlags;
|
|
179
|
+
cloned.cmpMethod = entry.cmpMethod;
|
|
180
|
+
cloned.timeDateDOS = entry.timeDateDOS;
|
|
181
|
+
cloned.crc = entry.crc;
|
|
182
|
+
cloned.compressedSize = entry.compressedSize;
|
|
183
|
+
cloned.uncompressedSize = entry.uncompressedSize;
|
|
184
|
+
cloned.volNumber = entry.volNumber;
|
|
185
|
+
cloned.intFileAttr = entry.intFileAttr;
|
|
186
|
+
cloned.extFileAttr = entry.extFileAttr;
|
|
187
|
+
cloned.localHdrOffset = newLocalHdrOffset; // Update offset
|
|
188
|
+
// Copy extra field if present
|
|
189
|
+
if (entry.extraField) {
|
|
190
|
+
cloned.extraField = Buffer.from(entry.extraField);
|
|
191
|
+
}
|
|
192
|
+
// Copy metadata
|
|
193
|
+
cloned.isEncrypted = entry.isEncrypted;
|
|
194
|
+
cloned.isStrongEncrypt = entry.isStrongEncrypt;
|
|
195
|
+
cloned.isDirectory = entry.isDirectory;
|
|
196
|
+
cloned.isMetaData = entry.isMetaData;
|
|
197
|
+
cloned.isUpdated = entry.isUpdated;
|
|
198
|
+
// Copy platform-specific data
|
|
199
|
+
cloned.platform = entry.platform;
|
|
200
|
+
cloned.universalTime = entry.universalTime;
|
|
201
|
+
cloned.uid = entry.uid;
|
|
202
|
+
cloned.gid = entry.gid;
|
|
203
|
+
cloned.sha256 = entry.sha256;
|
|
204
|
+
// Copy symlink data
|
|
205
|
+
cloned.isSymlink = entry.isSymlink;
|
|
206
|
+
cloned.linkTarget = entry.linkTarget;
|
|
207
|
+
// Copy hardlink data
|
|
208
|
+
cloned.isHardLink = entry.isHardLink;
|
|
209
|
+
cloned.originalEntry = entry.originalEntry;
|
|
210
|
+
cloned.inode = entry.inode;
|
|
211
|
+
return cloned;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Write central directory and End of Central Directory record to an open file descriptor.
|
|
215
|
+
* Used internally by copyZipFile and by writeCentralDirectoryAndEOCD.
|
|
216
|
+
*/
|
|
217
|
+
writeCentralDirectoryAndEOCDToFd(destFd, entries, zipComment) {
|
|
218
|
+
const centralDirStartOffset = fs.fstatSync(destFd).size;
|
|
219
|
+
for (const entry of entries) {
|
|
220
|
+
const centralDirBuffer = entry.centralDirEntry();
|
|
221
|
+
fs.writeSync(destFd, centralDirBuffer, 0, centralDirBuffer.length);
|
|
222
|
+
}
|
|
223
|
+
const centralDirEndOffset = fs.fstatSync(destFd).size;
|
|
224
|
+
const centralDirSize = centralDirEndOffset - centralDirStartOffset;
|
|
225
|
+
const commentBytes = Buffer.from(zipComment, 'utf8');
|
|
226
|
+
const commentLength = Math.min(commentBytes.length, 0xFFFF);
|
|
227
|
+
const eocdBuffer = Buffer.alloc(22 + commentLength);
|
|
228
|
+
let pos = 0;
|
|
229
|
+
eocdBuffer.writeUInt32LE(Headers_1.CENTRAL_END.SIGNATURE, pos);
|
|
230
|
+
pos += 4;
|
|
231
|
+
eocdBuffer.writeUInt16LE(0, pos);
|
|
232
|
+
pos += 2;
|
|
233
|
+
eocdBuffer.writeUInt16LE(0, pos);
|
|
234
|
+
pos += 2;
|
|
235
|
+
eocdBuffer.writeUInt16LE(entries.length, pos);
|
|
236
|
+
pos += 2;
|
|
237
|
+
eocdBuffer.writeUInt16LE(entries.length, pos);
|
|
238
|
+
pos += 2;
|
|
239
|
+
eocdBuffer.writeUInt32LE(centralDirSize, pos);
|
|
240
|
+
pos += 4;
|
|
241
|
+
eocdBuffer.writeUInt32LE(centralDirStartOffset, pos);
|
|
242
|
+
pos += 4;
|
|
243
|
+
eocdBuffer.writeUInt16LE(commentLength, pos);
|
|
244
|
+
pos += 2;
|
|
245
|
+
if (commentLength > 0) {
|
|
246
|
+
commentBytes.copy(eocdBuffer, pos, 0, commentLength);
|
|
247
|
+
}
|
|
248
|
+
fs.writeSync(destFd, eocdBuffer, 0, eocdBuffer.length);
|
|
249
|
+
return { centralDirOffset: centralDirStartOffset, centralDirSize };
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Copy only ZIP entry data to the destination file (no central directory or EOCD).
|
|
253
|
+
* Use this when you want to add more entries before finalizing. Then call
|
|
254
|
+
* writeCentralDirectoryAndEOCD with all entries (copied + new) to produce a valid ZIP.
|
|
255
|
+
*
|
|
256
|
+
* @param sourceZipPath - Path to source ZIP file
|
|
257
|
+
* @param destZipPath - Path to destination file (will contain only entry data until finalized)
|
|
258
|
+
* @param options - Optional copy options (filtering, sorting)
|
|
259
|
+
* @returns Result with dataEndOffset and copiedEntries for use when adding files and finalizing
|
|
260
|
+
*/
|
|
261
|
+
async copyZipEntriesOnly(sourceZipPath, destZipPath, options) {
|
|
262
|
+
const sourceEntries = await this.zipkitNode.loadZipFile(sourceZipPath);
|
|
263
|
+
let entriesToCopy = options?.entryFilter
|
|
264
|
+
? sourceEntries.filter(options.entryFilter)
|
|
265
|
+
: sourceEntries;
|
|
266
|
+
if (options?.entrySorter) {
|
|
267
|
+
entriesToCopy = [...entriesToCopy].sort(options.entrySorter);
|
|
268
|
+
}
|
|
269
|
+
if (entriesToCopy.length === 0) {
|
|
270
|
+
throw new Error('No entries to copy after filtering');
|
|
271
|
+
}
|
|
272
|
+
const sourceFd = fs.openSync(sourceZipPath, 'r');
|
|
273
|
+
const destFd = fs.openSync(destZipPath, 'w');
|
|
274
|
+
try {
|
|
275
|
+
let destOffset = 0;
|
|
276
|
+
const copiedEntries = [];
|
|
277
|
+
for (const sourceEntry of entriesToCopy) {
|
|
278
|
+
const newLocalHdrOffset = destOffset;
|
|
279
|
+
const bytesWritten = this.copyEntryBytes(sourceFd, destFd, sourceEntry);
|
|
280
|
+
destOffset += bytesWritten;
|
|
281
|
+
const clonedEntry = this.cloneEntryWithOffset(sourceEntry, newLocalHdrOffset);
|
|
282
|
+
copiedEntries.push(clonedEntry);
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
destPath: destZipPath,
|
|
286
|
+
dataEndOffset: destOffset,
|
|
287
|
+
copiedEntries,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
finally {
|
|
291
|
+
fs.closeSync(sourceFd);
|
|
292
|
+
fs.closeSync(destFd);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Append central directory and End of Central Directory to a file that already
|
|
297
|
+
* contains ZIP entry data (e.g. from copyZipEntriesOnly plus any newly added entries).
|
|
298
|
+
* Call this after adding files to produce a valid ZIP.
|
|
299
|
+
*
|
|
300
|
+
* @param destZipPath - Path to the partial ZIP file (entry data only)
|
|
301
|
+
* @param entries - All entries in order (copied + any new), each with localHdrOffset set
|
|
302
|
+
* @param options - Optional finalize options (e.g. zipComment)
|
|
303
|
+
*/
|
|
304
|
+
writeCentralDirectoryAndEOCD(destZipPath, entries, options) {
|
|
305
|
+
if (entries.length === 0) {
|
|
306
|
+
throw new Error('At least one entry is required to finalize');
|
|
307
|
+
}
|
|
308
|
+
const zipComment = options?.zipComment ?? '';
|
|
309
|
+
const destFd = fs.openSync(destZipPath, 'a');
|
|
310
|
+
try {
|
|
311
|
+
this.writeCentralDirectoryAndEOCDToFd(destFd, entries, zipComment);
|
|
312
|
+
}
|
|
313
|
+
finally {
|
|
314
|
+
fs.closeSync(destFd);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Copy ZIP file entries efficiently
|
|
319
|
+
*
|
|
320
|
+
* Main method that copies entries from source ZIP to destination ZIP.
|
|
321
|
+
* Uses ZipEntry instances directly to avoid unnecessary parsing.
|
|
322
|
+
*
|
|
323
|
+
* @param sourceZipPath - Path to source ZIP file
|
|
324
|
+
* @param destZipPath - Path to destination ZIP file
|
|
325
|
+
* @param options - Optional copy options (filtering, sorting, etc.)
|
|
326
|
+
* @returns Copy result with entry information
|
|
327
|
+
*/
|
|
328
|
+
async copyZipFile(sourceZipPath, destZipPath, options) {
|
|
329
|
+
// Copy only entry data, then write central directory and EOCD (no added entries)
|
|
330
|
+
const { dataEndOffset, copiedEntries } = await this.copyZipEntriesOnly(sourceZipPath, destZipPath, options);
|
|
331
|
+
const zipComment = options?.preserveComments !== false && this.zipkitNode.getZipComment()
|
|
332
|
+
? this.zipkitNode.getZipComment()
|
|
333
|
+
: '';
|
|
334
|
+
this.writeCentralDirectoryAndEOCD(destZipPath, copiedEntries, { zipComment });
|
|
335
|
+
return {
|
|
336
|
+
entries: copiedEntries.map(entry => ({
|
|
337
|
+
filename: entry.filename,
|
|
338
|
+
localHeaderOffset: entry.localHdrOffset,
|
|
339
|
+
compressedSize: entry.compressedSize,
|
|
340
|
+
})),
|
|
341
|
+
centralDirOffset: dataEndOffset,
|
|
342
|
+
totalEntries: copiedEntries.length,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
exports.ZipCopyNode = ZipCopyNode;
|
|
347
|
+
//# sourceMappingURL=ZipCopyNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZipCopyNode.js","sourceRoot":"","sources":["../../src/node/ZipCopyNode.ts"],"names":[],"mappings":"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"}
|