@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,310 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ======================================
|
|
3
|
+
// ZipCopy.ts - Efficient ZIP Entry Copying (Buffer-based)
|
|
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
|
+
// Buffer-based implementation for in-memory ZIP operations.
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ZipCopy = void 0;
|
|
16
|
+
const ZipEntry_1 = __importDefault(require("./ZipEntry"));
|
|
17
|
+
const Headers_1 = require("./constants/Headers");
|
|
18
|
+
/**
|
|
19
|
+
* Efficient ZIP file copying class (Buffer-based)
|
|
20
|
+
*
|
|
21
|
+
* Uses ZipEntry instances directly to copy entries without decompression/recompression.
|
|
22
|
+
* Supports filtering and reordering entries while maintaining ZIP file validity.
|
|
23
|
+
* Works entirely with buffers for in-memory operations.
|
|
24
|
+
*
|
|
25
|
+
* Entry data and the central directory / EOCD are separated so you can append
|
|
26
|
+
* more entry data before finalizing: use copyZipEntriesOnly, append new entry
|
|
27
|
+
* data to the buffer, then call writeCentralDirectoryAndEOCD with all entries
|
|
28
|
+
* and concatenate to form the final ZIP buffer.
|
|
29
|
+
*
|
|
30
|
+
* @example Full copy (one shot)
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const zipCopy = new ZipCopy(zipkit);
|
|
33
|
+
* const result = await zipCopy.copyZipBuffer(sourceZipBuffer, {
|
|
34
|
+
* entryFilter: (entry) => !entry.filename.startsWith('.'),
|
|
35
|
+
* entrySorter: (a, b) => a.filename.localeCompare(b.filename)
|
|
36
|
+
* });
|
|
37
|
+
* // result.zipBuffer contains the complete copied ZIP file
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @example Copy then append entries before finalizing
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const { entryDataBuffer, dataEndOffset, copiedEntries } = await zipCopy.copyZipEntriesOnly(sourceZipBuffer);
|
|
43
|
+
* // ... append new entry data (local header + data), collect new ZipEntry[] with localHdrOffset set ...
|
|
44
|
+
* const allEntryData = Buffer.concat([entryDataBuffer, newEntryDataBuffer]);
|
|
45
|
+
* const allEntries = [...copiedEntries, ...newEntries];
|
|
46
|
+
* const centralAndEocd = zipCopy.writeCentralDirectoryAndEOCD(allEntries, {
|
|
47
|
+
* zipComment: '',
|
|
48
|
+
* centralDirOffset: allEntryData.length
|
|
49
|
+
* });
|
|
50
|
+
* const zipBuffer = Buffer.concat([allEntryData, centralAndEocd]);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
class ZipCopy {
|
|
54
|
+
/**
|
|
55
|
+
* Creates a new ZipCopy instance
|
|
56
|
+
* @param zipkit - Zipkit instance to use for ZIP operations
|
|
57
|
+
*/
|
|
58
|
+
constructor(zipkit) {
|
|
59
|
+
this.zipkit = zipkit;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Calculate local header size by reading from buffer
|
|
63
|
+
*
|
|
64
|
+
* Reads the first 30 bytes of the local header to get the exact
|
|
65
|
+
* filename and extra field lengths, ensuring accuracy even when
|
|
66
|
+
* local header differs from central directory.
|
|
67
|
+
*
|
|
68
|
+
* @param sourceBuffer - Buffer containing the source ZIP file
|
|
69
|
+
* @param entry - ZipEntry with localHdrOffset
|
|
70
|
+
* @returns Size of the local header in bytes
|
|
71
|
+
*/
|
|
72
|
+
calculateLocalHeaderSize(sourceBuffer, entry) {
|
|
73
|
+
// Verify offset is within buffer bounds
|
|
74
|
+
if (entry.localHdrOffset + Headers_1.LOCAL_HDR.SIZE > sourceBuffer.length) {
|
|
75
|
+
throw new Error(`Local header offset ${entry.localHdrOffset} is beyond buffer size ${sourceBuffer.length} for entry ${entry.filename}`);
|
|
76
|
+
}
|
|
77
|
+
// Read the fixed 30-byte local header
|
|
78
|
+
const headerBuffer = sourceBuffer.subarray(entry.localHdrOffset, entry.localHdrOffset + Headers_1.LOCAL_HDR.SIZE);
|
|
79
|
+
// Verify signature
|
|
80
|
+
if (headerBuffer.readUInt32LE(0) !== Headers_1.LOCAL_HDR.SIGNATURE) {
|
|
81
|
+
throw new Error(`Invalid local file header signature for entry ${entry.filename} at offset ${entry.localHdrOffset}`);
|
|
82
|
+
}
|
|
83
|
+
// Read filename and extra field lengths from the actual header
|
|
84
|
+
const filenameLength = headerBuffer.readUInt16LE(Headers_1.LOCAL_HDR.FNAME_LEN);
|
|
85
|
+
const extraFieldLength = headerBuffer.readUInt16LE(Headers_1.LOCAL_HDR.EXTRA_LEN);
|
|
86
|
+
// Calculate total local header size
|
|
87
|
+
return Headers_1.LOCAL_HDR.SIZE + filenameLength + extraFieldLength;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Copy entry bytes directly from source buffer
|
|
91
|
+
*
|
|
92
|
+
* Copies the local header and compressed data as a single operation.
|
|
93
|
+
*
|
|
94
|
+
* Handles various entry types:
|
|
95
|
+
* - Normal entries: [local header][filename][extra][compressed data]
|
|
96
|
+
* - Encrypted entries: compressedSize includes 12-byte encryption header
|
|
97
|
+
* - Data descriptor entries: [local header][filename][extra][data][data descriptor (16 bytes)]
|
|
98
|
+
*
|
|
99
|
+
* For data descriptor entries, the local header has compressed size = 0,
|
|
100
|
+
* but the actual size is in the central directory (entry.compressedSize).
|
|
101
|
+
*
|
|
102
|
+
* @param sourceBuffer - Buffer containing the source ZIP file
|
|
103
|
+
* @param entry - ZipEntry with source offset information
|
|
104
|
+
* @returns Buffer containing the copied entry (local header + compressed data + data descriptor if present)
|
|
105
|
+
*/
|
|
106
|
+
copyEntryBytes(sourceBuffer, entry) {
|
|
107
|
+
// Calculate local header size by reading from buffer
|
|
108
|
+
const localHeaderSize = this.calculateLocalHeaderSize(sourceBuffer, entry);
|
|
109
|
+
// Determine total entry size
|
|
110
|
+
// For data descriptor entries, add 16 bytes for the data descriptor
|
|
111
|
+
const hasDataDescriptor = (entry.bitFlags & Headers_1.GP_FLAG.DATA_DESC) !== 0;
|
|
112
|
+
const totalEntrySize = localHeaderSize + entry.compressedSize + (hasDataDescriptor ? 16 : 0);
|
|
113
|
+
// Verify we have enough data in the buffer
|
|
114
|
+
if (entry.localHdrOffset + totalEntrySize > sourceBuffer.length) {
|
|
115
|
+
throw new Error(`Entry ${entry.filename} extends beyond buffer size: ` +
|
|
116
|
+
`offset ${entry.localHdrOffset} + size ${totalEntrySize} > buffer length ${sourceBuffer.length}`);
|
|
117
|
+
}
|
|
118
|
+
// Extract the entire entry (local header + compressed data + data descriptor if present) from source
|
|
119
|
+
const entryBuffer = sourceBuffer.subarray(entry.localHdrOffset, entry.localHdrOffset + totalEntrySize);
|
|
120
|
+
// Verify data descriptor signature if present
|
|
121
|
+
if (hasDataDescriptor) {
|
|
122
|
+
const dataDescOffset = localHeaderSize + entry.compressedSize;
|
|
123
|
+
const dataDescSig = entryBuffer.readUInt32LE(dataDescOffset);
|
|
124
|
+
if (dataDescSig !== 0x08074b50) { // DATA_DESCRIPTOR signature
|
|
125
|
+
throw new Error(`Invalid data descriptor signature for entry ${entry.filename} ` +
|
|
126
|
+
`(expected 0x08074b50, got 0x${dataDescSig.toString(16)})`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Return a copy of the buffer slice (so modifications don't affect source)
|
|
130
|
+
return Buffer.from(entryBuffer);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Clone a ZipEntry with a new local header offset
|
|
134
|
+
*
|
|
135
|
+
* Creates a new ZipEntry instance with all properties copied from the source,
|
|
136
|
+
* but with an updated localHdrOffset for the destination buffer.
|
|
137
|
+
*
|
|
138
|
+
* @param entry - Source ZipEntry to clone
|
|
139
|
+
* @param newLocalHdrOffset - New local header offset for the destination
|
|
140
|
+
* @returns New ZipEntry instance with updated offset
|
|
141
|
+
*/
|
|
142
|
+
cloneEntryWithOffset(entry, newLocalHdrOffset) {
|
|
143
|
+
// Create a new ZipEntry with the same filename and comment
|
|
144
|
+
const cloned = new ZipEntry_1.default(entry.filename, entry.comment || null, entry.debug);
|
|
145
|
+
// Copy all properties
|
|
146
|
+
cloned.verMadeBy = entry.verMadeBy;
|
|
147
|
+
cloned.verExtract = entry.verExtract;
|
|
148
|
+
cloned.bitFlags = entry.bitFlags;
|
|
149
|
+
cloned.cmpMethod = entry.cmpMethod;
|
|
150
|
+
cloned.timeDateDOS = entry.timeDateDOS;
|
|
151
|
+
cloned.crc = entry.crc;
|
|
152
|
+
cloned.compressedSize = entry.compressedSize;
|
|
153
|
+
cloned.uncompressedSize = entry.uncompressedSize;
|
|
154
|
+
cloned.volNumber = entry.volNumber;
|
|
155
|
+
cloned.intFileAttr = entry.intFileAttr;
|
|
156
|
+
cloned.extFileAttr = entry.extFileAttr;
|
|
157
|
+
cloned.localHdrOffset = newLocalHdrOffset; // Update offset
|
|
158
|
+
// Copy extra field if present
|
|
159
|
+
if (entry.extraField) {
|
|
160
|
+
cloned.extraField = Buffer.from(entry.extraField);
|
|
161
|
+
}
|
|
162
|
+
// Copy metadata
|
|
163
|
+
cloned.isEncrypted = entry.isEncrypted;
|
|
164
|
+
cloned.isStrongEncrypt = entry.isStrongEncrypt;
|
|
165
|
+
cloned.isDirectory = entry.isDirectory;
|
|
166
|
+
cloned.isMetaData = entry.isMetaData;
|
|
167
|
+
cloned.isUpdated = entry.isUpdated;
|
|
168
|
+
// Copy platform-specific data
|
|
169
|
+
cloned.platform = entry.platform;
|
|
170
|
+
cloned.universalTime = entry.universalTime;
|
|
171
|
+
cloned.uid = entry.uid;
|
|
172
|
+
cloned.gid = entry.gid;
|
|
173
|
+
cloned.sha256 = entry.sha256;
|
|
174
|
+
// Copy symlink data
|
|
175
|
+
cloned.isSymlink = entry.isSymlink;
|
|
176
|
+
cloned.linkTarget = entry.linkTarget;
|
|
177
|
+
// Copy hardlink data
|
|
178
|
+
cloned.isHardLink = entry.isHardLink;
|
|
179
|
+
cloned.originalEntry = entry.originalEntry;
|
|
180
|
+
cloned.inode = entry.inode;
|
|
181
|
+
return cloned;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Build central directory and End of Central Directory buffer.
|
|
185
|
+
* Used internally by copyZipBuffer and by writeCentralDirectoryAndEOCD.
|
|
186
|
+
*/
|
|
187
|
+
buildCentralDirectoryAndEOCDBuffer(entries, zipComment, centralDirOffset) {
|
|
188
|
+
const centralDirChunks = [];
|
|
189
|
+
for (const entry of entries) {
|
|
190
|
+
centralDirChunks.push(entry.centralDirEntry());
|
|
191
|
+
}
|
|
192
|
+
const centralDirBuffer = Buffer.concat(centralDirChunks);
|
|
193
|
+
const centralDirSize = centralDirBuffer.length;
|
|
194
|
+
const commentBytes = Buffer.from(zipComment, 'utf8');
|
|
195
|
+
const commentLength = Math.min(commentBytes.length, 0xffff);
|
|
196
|
+
const eocdBuffer = Buffer.alloc(22 + commentLength);
|
|
197
|
+
let pos = 0;
|
|
198
|
+
eocdBuffer.writeUInt32LE(Headers_1.CENTRAL_END.SIGNATURE, pos);
|
|
199
|
+
pos += 4;
|
|
200
|
+
eocdBuffer.writeUInt16LE(0, pos);
|
|
201
|
+
pos += 2;
|
|
202
|
+
eocdBuffer.writeUInt16LE(0, pos);
|
|
203
|
+
pos += 2;
|
|
204
|
+
eocdBuffer.writeUInt16LE(entries.length, pos);
|
|
205
|
+
pos += 2;
|
|
206
|
+
eocdBuffer.writeUInt16LE(entries.length, pos);
|
|
207
|
+
pos += 2;
|
|
208
|
+
eocdBuffer.writeUInt32LE(centralDirSize, pos);
|
|
209
|
+
pos += 4;
|
|
210
|
+
eocdBuffer.writeUInt32LE(centralDirOffset, pos);
|
|
211
|
+
pos += 4;
|
|
212
|
+
eocdBuffer.writeUInt16LE(commentLength, pos);
|
|
213
|
+
pos += 2;
|
|
214
|
+
if (commentLength > 0) {
|
|
215
|
+
commentBytes.copy(eocdBuffer, pos, 0, commentLength);
|
|
216
|
+
}
|
|
217
|
+
return Buffer.concat([centralDirBuffer, eocdBuffer]);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Copy only ZIP entry data from the source buffer (no central directory or EOCD).
|
|
221
|
+
* Use when you want to append more entry data before finalizing. Then call
|
|
222
|
+
* writeCentralDirectoryAndEOCD with all entries (copied + new) and concatenate
|
|
223
|
+
* to form the final ZIP buffer.
|
|
224
|
+
*
|
|
225
|
+
* @param sourceZipBuffer - Buffer containing the source ZIP file
|
|
226
|
+
* @param options - Optional copy options (filtering, sorting)
|
|
227
|
+
* @returns Result with entryDataBuffer and copiedEntries for use when appending and finalizing
|
|
228
|
+
*/
|
|
229
|
+
async copyZipEntriesOnly(sourceZipBuffer, options) {
|
|
230
|
+
const sourceEntries = this.zipkit.loadZip(sourceZipBuffer);
|
|
231
|
+
let entriesToCopy = options?.entryFilter
|
|
232
|
+
? sourceEntries.filter(options.entryFilter)
|
|
233
|
+
: sourceEntries;
|
|
234
|
+
if (options?.entrySorter) {
|
|
235
|
+
entriesToCopy = [...entriesToCopy].sort(options.entrySorter);
|
|
236
|
+
}
|
|
237
|
+
if (entriesToCopy.length === 0) {
|
|
238
|
+
throw new Error('No entries to copy after filtering');
|
|
239
|
+
}
|
|
240
|
+
const outputChunks = [];
|
|
241
|
+
let destOffset = 0;
|
|
242
|
+
const copiedEntries = [];
|
|
243
|
+
for (const sourceEntry of entriesToCopy) {
|
|
244
|
+
const newLocalHdrOffset = destOffset;
|
|
245
|
+
const entryBuffer = this.copyEntryBytes(sourceZipBuffer, sourceEntry);
|
|
246
|
+
outputChunks.push(entryBuffer);
|
|
247
|
+
destOffset += entryBuffer.length;
|
|
248
|
+
const clonedEntry = this.cloneEntryWithOffset(sourceEntry, newLocalHdrOffset);
|
|
249
|
+
copiedEntries.push(clonedEntry);
|
|
250
|
+
}
|
|
251
|
+
const entryDataBuffer = Buffer.concat(outputChunks);
|
|
252
|
+
return {
|
|
253
|
+
entryDataBuffer,
|
|
254
|
+
dataEndOffset: entryDataBuffer.length,
|
|
255
|
+
copiedEntries,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Build central directory and End of Central Directory buffer for the given entries.
|
|
260
|
+
* Concatenate this with entry data (e.g. from copyZipEntriesOnly + any appended entries)
|
|
261
|
+
* to form a valid ZIP buffer. When concatenating, pass centralDirOffset equal to the
|
|
262
|
+
* length of the entry data buffer that will precede this (so EOCD has the correct offset).
|
|
263
|
+
*
|
|
264
|
+
* @param entries - All entries in order (copied + any new), each with localHdrOffset set
|
|
265
|
+
* @param options - Optional finalize options (zipComment; centralDirOffset for correct EOCD when concatenating)
|
|
266
|
+
* @returns Buffer containing central directory + EOCD
|
|
267
|
+
*/
|
|
268
|
+
writeCentralDirectoryAndEOCD(entries, options) {
|
|
269
|
+
if (entries.length === 0) {
|
|
270
|
+
throw new Error('At least one entry is required to finalize');
|
|
271
|
+
}
|
|
272
|
+
const zipComment = options?.zipComment ?? '';
|
|
273
|
+
const centralDirOffset = options?.centralDirOffset ?? 0;
|
|
274
|
+
const result = this.buildCentralDirectoryAndEOCDBuffer(entries, zipComment, centralDirOffset);
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Copy ZIP file entries efficiently from buffer to buffer
|
|
279
|
+
*
|
|
280
|
+
* Main method that copies entries from source ZIP buffer to destination ZIP buffer.
|
|
281
|
+
* Uses ZipEntry instances directly to avoid unnecessary parsing.
|
|
282
|
+
*
|
|
283
|
+
* @param sourceZipBuffer - Buffer containing the source ZIP file
|
|
284
|
+
* @param options - Optional copy options (filtering, sorting, etc.)
|
|
285
|
+
* @returns Copy result with entry information and the complete ZIP buffer
|
|
286
|
+
*/
|
|
287
|
+
async copyZipBuffer(sourceZipBuffer, options) {
|
|
288
|
+
const { entryDataBuffer, dataEndOffset, copiedEntries } = await this.copyZipEntriesOnly(sourceZipBuffer, options);
|
|
289
|
+
const zipComment = options?.preserveComments !== false && this.zipkit.getZipComment()
|
|
290
|
+
? this.zipkit.getZipComment()
|
|
291
|
+
: '';
|
|
292
|
+
const centralAndEocd = this.writeCentralDirectoryAndEOCD(copiedEntries, {
|
|
293
|
+
zipComment,
|
|
294
|
+
centralDirOffset: dataEndOffset,
|
|
295
|
+
});
|
|
296
|
+
const zipBuffer = Buffer.concat([entryDataBuffer, centralAndEocd]);
|
|
297
|
+
return {
|
|
298
|
+
entries: copiedEntries.map(entry => ({
|
|
299
|
+
filename: entry.filename,
|
|
300
|
+
localHeaderOffset: entry.localHdrOffset,
|
|
301
|
+
compressedSize: entry.compressedSize,
|
|
302
|
+
})),
|
|
303
|
+
centralDirOffset: dataEndOffset,
|
|
304
|
+
totalEntries: copiedEntries.length,
|
|
305
|
+
zipBuffer,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
exports.ZipCopy = ZipCopy;
|
|
310
|
+
//# sourceMappingURL=ZipCopy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZipCopy.js","sourceRoot":"","sources":["../../src/core/ZipCopy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import Zipkit from './Zipkit';
|
|
2
|
+
import ZipEntry from './ZipEntry';
|
|
3
|
+
export interface DecompressionResult {
|
|
4
|
+
success: boolean;
|
|
5
|
+
data?: Buffer;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DecompressionOptions {
|
|
9
|
+
method: number;
|
|
10
|
+
debug?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* ZipDecompress - Unified Decompression Module (Internal to Zipkit)
|
|
14
|
+
* Consolidates decompression functionality from ZipCompress
|
|
15
|
+
* Supports deflate, zstd, and stored compression methods with chunked processing
|
|
16
|
+
*
|
|
17
|
+
* This class is internal to Zipkit and should not be used directly.
|
|
18
|
+
* Use Zipkit methods instead.
|
|
19
|
+
*/
|
|
20
|
+
declare class ZipDecompress {
|
|
21
|
+
private zipkit;
|
|
22
|
+
private debug;
|
|
23
|
+
private static loggingEnabled;
|
|
24
|
+
/**
|
|
25
|
+
* Internal logging method - only logs if class logging is enabled
|
|
26
|
+
*/
|
|
27
|
+
private log;
|
|
28
|
+
constructor(zipkit: Zipkit);
|
|
29
|
+
/**
|
|
30
|
+
* Extract file data (Buffer-based ZIP only)
|
|
31
|
+
* Public method that validates buffer mode and extracts entry
|
|
32
|
+
*
|
|
33
|
+
* @param entry ZIP entry to extract
|
|
34
|
+
* @param skipHashCheck Skip hash verification (CRC-32 or SHA-256)
|
|
35
|
+
* @returns Promise resolving to extracted data as Buffer, or null if failed
|
|
36
|
+
* @throws Error if not a Buffer-based ZIP
|
|
37
|
+
*/
|
|
38
|
+
extract(entry: ZipEntry, skipHashCheck?: boolean): Promise<Buffer | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Inflate data using pako (internal use only)
|
|
41
|
+
*/
|
|
42
|
+
private inflate;
|
|
43
|
+
/**
|
|
44
|
+
* Synchronous zstd decompress method for in-memory mode
|
|
45
|
+
* ZSTD codec is guaranteed to be initialized via factory method
|
|
46
|
+
* Internal method only
|
|
47
|
+
*/
|
|
48
|
+
private zstdDecompressSync;
|
|
49
|
+
/**
|
|
50
|
+
* Uncompress compressed data buffer (synchronous for in-memory mode)
|
|
51
|
+
* Handles decompression and hash verification
|
|
52
|
+
* Internal method only
|
|
53
|
+
*/
|
|
54
|
+
private unCompress;
|
|
55
|
+
}
|
|
56
|
+
export default ZipDecompress;
|
|
57
|
+
//# sourceMappingURL=ZipDecompress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZipDecompress.d.ts","sourceRoot":"","sources":["../../src/core/ZipDecompress.ts"],"names":[],"mappings":"AAiBA,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,OAAO,QAAQ,MAAM,YAAY,CAAC;AAKlC,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAU;IAGvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAkB;IAE/C;;OAEG;IACH,OAAO,CAAC,GAAG;gBAMC,MAAM,EAAE,MAAM;IAU1B;;;;;;;;OAQG;IACG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAiC/E;;OAEG;IACH,OAAO,CAAC,OAAO;IAOf;;;;OAIG;YACW,kBAAkB;IAchC;;;;OAIG;YACW,UAAU;CA0CzB;AAGD,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ======================================
|
|
3
|
+
// ZipDecompress.ts - Decompression Module
|
|
4
|
+
// Copyright (c) 2025 NeoWare, Inc. All rights reserved.
|
|
5
|
+
// ======================================
|
|
6
|
+
//
|
|
7
|
+
// LOGGING INSTRUCTIONS:
|
|
8
|
+
// ---------------------
|
|
9
|
+
// To enable/disable logging, set loggingEnabled to true/false in the class:
|
|
10
|
+
// private static loggingEnabled: boolean = true; // Enable logging
|
|
11
|
+
// private static loggingEnabled: boolean = false; // Disable logging
|
|
12
|
+
//
|
|
13
|
+
// Logging respects the global Logger level (debug, info, warn, error, silent).
|
|
14
|
+
// Logger level is automatically set to 'debug' when loggingEnabled is true.
|
|
15
|
+
//
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
const pako = require('pako');
|
|
21
|
+
const ZstdManager_1 = require("./ZstdManager");
|
|
22
|
+
const Logger_1 = require("./components/Logger");
|
|
23
|
+
const Errors_1 = __importDefault(require("./constants/Errors"));
|
|
24
|
+
const Headers_1 = require("./constants/Headers");
|
|
25
|
+
const ZipCrypto_1 = require("./encryption/ZipCrypto");
|
|
26
|
+
/**
|
|
27
|
+
* ZipDecompress - Unified Decompression Module (Internal to Zipkit)
|
|
28
|
+
* Consolidates decompression functionality from ZipCompress
|
|
29
|
+
* Supports deflate, zstd, and stored compression methods with chunked processing
|
|
30
|
+
*
|
|
31
|
+
* This class is internal to Zipkit and should not be used directly.
|
|
32
|
+
* Use Zipkit methods instead.
|
|
33
|
+
*/
|
|
34
|
+
class ZipDecompress {
|
|
35
|
+
/**
|
|
36
|
+
* Internal logging method - only logs if class logging is enabled
|
|
37
|
+
*/
|
|
38
|
+
log(...args) {
|
|
39
|
+
if (ZipDecompress.loggingEnabled) {
|
|
40
|
+
Logger_1.Logger.debug(`[ZipDecompress]`, ...args);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
constructor(zipkit) {
|
|
44
|
+
this.zipkit = zipkit;
|
|
45
|
+
// Debug disabled by default
|
|
46
|
+
this.debug = false;
|
|
47
|
+
// If logging is enabled, ensure Logger level is set to debug
|
|
48
|
+
if (ZipDecompress.loggingEnabled) {
|
|
49
|
+
Logger_1.Logger.setLevel('debug');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract file data (Buffer-based ZIP only)
|
|
54
|
+
* Public method that validates buffer mode and extracts entry
|
|
55
|
+
*
|
|
56
|
+
* @param entry ZIP entry to extract
|
|
57
|
+
* @param skipHashCheck Skip hash verification (CRC-32 or SHA-256)
|
|
58
|
+
* @returns Promise resolving to extracted data as Buffer, or null if failed
|
|
59
|
+
* @throws Error if not a Buffer-based ZIP
|
|
60
|
+
*/
|
|
61
|
+
async extract(entry, skipHashCheck) {
|
|
62
|
+
if (!this.zipkit.hasInBuffer()) {
|
|
63
|
+
throw new Error('extract() requires Buffer-based ZIP. Use ZipkitNode.extractToFile() for file-based ZIP or call loadZip() first.');
|
|
64
|
+
}
|
|
65
|
+
this.log(`extract() called for entry: ${entry.filename}, method: ${entry.cmpMethod}, skipHashCheck: ${skipHashCheck}`);
|
|
66
|
+
const buffer = this.zipkit.ensureBuffer();
|
|
67
|
+
// Decrypt if needed using password on zipkit instance
|
|
68
|
+
let fdata = this.zipkit.parseLocalHeader(entry, buffer);
|
|
69
|
+
if (entry.isEncrypted && this.zipkit?.password) {
|
|
70
|
+
this.log(`Starting in-memory decryption for entry: ${entry.filename}`);
|
|
71
|
+
// Use ZipCrypto's decryptBuffer method which handles all the header parsing and decryption
|
|
72
|
+
const zipCrypto = new ZipCrypto_1.ZipCrypto();
|
|
73
|
+
fdata = zipCrypto.decryptBuffer(entry, buffer, fdata, this.zipkit.password);
|
|
74
|
+
this.log(`Decryption successful, decrypted compressed data length: ${fdata.length}`);
|
|
75
|
+
}
|
|
76
|
+
if (fdata.length === 0) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// Use the unCompress method
|
|
80
|
+
return this.unCompress(fdata, entry, skipHashCheck);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Inflate data using pako (internal use only)
|
|
84
|
+
*/
|
|
85
|
+
inflate(data) {
|
|
86
|
+
this.log(`inflate() called with ${data.length} bytes`);
|
|
87
|
+
const result = pako.inflateRaw(data);
|
|
88
|
+
return Buffer.from(result.buffer, result.byteOffset, result.byteLength);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Synchronous zstd decompress method for in-memory mode
|
|
92
|
+
* ZSTD codec is guaranteed to be initialized via factory method
|
|
93
|
+
* Internal method only
|
|
94
|
+
*/
|
|
95
|
+
async zstdDecompressSync(data) {
|
|
96
|
+
this.log(`zstdDecompressSync() called with ${data.length} bytes`);
|
|
97
|
+
try {
|
|
98
|
+
// Use global ZstdManager for decompression (handles queuing and initialization)
|
|
99
|
+
const decompressed = await ZstdManager_1.ZstdManager.decompress(data);
|
|
100
|
+
this.log(`ZSTD decompression successful: ${data.length} bytes -> ${decompressed.length} bytes`);
|
|
101
|
+
return Buffer.from(decompressed);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
this.log(`ZSTD decompression failed: ${error}`);
|
|
105
|
+
throw new Error(`ZSTD decompression failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Uncompress compressed data buffer (synchronous for in-memory mode)
|
|
110
|
+
* Handles decompression and hash verification
|
|
111
|
+
* Internal method only
|
|
112
|
+
*/
|
|
113
|
+
async unCompress(compressedData, entry, skipHashCheck) {
|
|
114
|
+
this.log(`unCompress() called for entry: ${entry.filename}, method: ${entry.cmpMethod}, data length: ${compressedData.length}`);
|
|
115
|
+
if (compressedData.length === 0) {
|
|
116
|
+
return Buffer.alloc(0);
|
|
117
|
+
}
|
|
118
|
+
let outBuf;
|
|
119
|
+
if (entry.cmpMethod === Headers_1.CMP_METHOD.STORED) {
|
|
120
|
+
outBuf = compressedData;
|
|
121
|
+
}
|
|
122
|
+
else if (entry.cmpMethod === Headers_1.CMP_METHOD.DEFLATED) {
|
|
123
|
+
// Use synchronous inflate for deflate
|
|
124
|
+
outBuf = this.inflate(compressedData);
|
|
125
|
+
}
|
|
126
|
+
else if (entry.cmpMethod === Headers_1.CMP_METHOD.ZSTD) {
|
|
127
|
+
// Use ZSTD decompression (now async with ZstdManager)
|
|
128
|
+
outBuf = await this.zstdDecompressSync(compressedData);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
throw new Error(`Unsupported compression method: ${entry.cmpMethod}`);
|
|
132
|
+
}
|
|
133
|
+
// Verify hash
|
|
134
|
+
if (!skipHashCheck) {
|
|
135
|
+
if (entry.sha256) {
|
|
136
|
+
const isValid = this.zipkit.testSHA256(entry, outBuf);
|
|
137
|
+
if (!isValid) {
|
|
138
|
+
throw new Error(Errors_1.default.INVALID_SHA256);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
const isValid = this.zipkit.testCRC32(entry, outBuf);
|
|
143
|
+
if (!isValid) {
|
|
144
|
+
throw new Error(Errors_1.default.INVALID_CRC);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return outBuf;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Class-level logging control - set to true to enable logging
|
|
152
|
+
ZipDecompress.loggingEnabled = false;
|
|
153
|
+
// Default export for internal use by Zipkit only
|
|
154
|
+
exports.default = ZipDecompress;
|
|
155
|
+
//# sourceMappingURL=ZipDecompress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZipDecompress.js","sourceRoot":"","sources":["../../src/core/ZipDecompress.ts"],"names":[],"mappings":"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"}
|