@rushstack/zipsync 0.2.13 → 0.3.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.
Files changed (100) hide show
  1. package/CHANGELOG.json +41 -0
  2. package/CHANGELOG.md +13 -1
  3. package/bin/zipsync +1 -1
  4. package/lib-esm/cli/ZipSyncCommandLineParser.js +93 -0
  5. package/lib-esm/cli/ZipSyncCommandLineParser.js.map +1 -0
  6. package/lib-esm/compress.js +115 -0
  7. package/lib-esm/compress.js.map +1 -0
  8. package/lib-esm/crc32.js +32 -0
  9. package/lib-esm/crc32.js.map +1 -0
  10. package/lib-esm/fs.js +48 -0
  11. package/lib-esm/fs.js.map +1 -0
  12. package/lib-esm/hash.js +39 -0
  13. package/lib-esm/hash.js.map +1 -0
  14. package/lib-esm/index.js +5 -0
  15. package/lib-esm/index.js.map +1 -0
  16. package/lib-esm/pack.js +379 -0
  17. package/lib-esm/pack.js.map +1 -0
  18. package/lib-esm/packWorker.js +58 -0
  19. package/lib-esm/packWorker.js.map +1 -0
  20. package/lib-esm/packWorkerAsync.js +43 -0
  21. package/lib-esm/packWorkerAsync.js.map +1 -0
  22. package/lib-esm/perf.js +49 -0
  23. package/lib-esm/perf.js.map +1 -0
  24. package/lib-esm/start.js +17 -0
  25. package/lib-esm/start.js.map +1 -0
  26. package/lib-esm/unpack.js +334 -0
  27. package/lib-esm/unpack.js.map +1 -0
  28. package/lib-esm/unpackWorker.js +54 -0
  29. package/lib-esm/unpackWorker.js.map +1 -0
  30. package/lib-esm/unpackWorkerAsync.js +43 -0
  31. package/lib-esm/unpackWorkerAsync.js.map +1 -0
  32. package/lib-esm/zipSyncUtils.js +6 -0
  33. package/lib-esm/zipSyncUtils.js.map +1 -0
  34. package/lib-esm/zipUtils.js +292 -0
  35. package/lib-esm/zipUtils.js.map +1 -0
  36. package/package.json +33 -6
  37. /package/{lib → lib-commonjs}/cli/ZipSyncCommandLineParser.js +0 -0
  38. /package/{lib → lib-commonjs}/cli/ZipSyncCommandLineParser.js.map +0 -0
  39. /package/{lib → lib-commonjs}/compress.js +0 -0
  40. /package/{lib → lib-commonjs}/compress.js.map +0 -0
  41. /package/{lib → lib-commonjs}/crc32.js +0 -0
  42. /package/{lib → lib-commonjs}/crc32.js.map +0 -0
  43. /package/{lib → lib-commonjs}/fs.js +0 -0
  44. /package/{lib → lib-commonjs}/fs.js.map +0 -0
  45. /package/{lib → lib-commonjs}/hash.js +0 -0
  46. /package/{lib → lib-commonjs}/hash.js.map +0 -0
  47. /package/{lib → lib-commonjs}/index.js +0 -0
  48. /package/{lib → lib-commonjs}/index.js.map +0 -0
  49. /package/{lib → lib-commonjs}/pack.js +0 -0
  50. /package/{lib → lib-commonjs}/pack.js.map +0 -0
  51. /package/{lib → lib-commonjs}/packWorker.js +0 -0
  52. /package/{lib → lib-commonjs}/packWorker.js.map +0 -0
  53. /package/{lib → lib-commonjs}/packWorkerAsync.js +0 -0
  54. /package/{lib → lib-commonjs}/packWorkerAsync.js.map +0 -0
  55. /package/{lib → lib-commonjs}/perf.js +0 -0
  56. /package/{lib → lib-commonjs}/perf.js.map +0 -0
  57. /package/{lib → lib-commonjs}/start.js +0 -0
  58. /package/{lib → lib-commonjs}/start.js.map +0 -0
  59. /package/{lib → lib-commonjs}/unpack.js +0 -0
  60. /package/{lib → lib-commonjs}/unpack.js.map +0 -0
  61. /package/{lib → lib-commonjs}/unpackWorker.js +0 -0
  62. /package/{lib → lib-commonjs}/unpackWorker.js.map +0 -0
  63. /package/{lib → lib-commonjs}/unpackWorkerAsync.js +0 -0
  64. /package/{lib → lib-commonjs}/unpackWorkerAsync.js.map +0 -0
  65. /package/{lib → lib-commonjs}/zipSyncUtils.js +0 -0
  66. /package/{lib → lib-commonjs}/zipSyncUtils.js.map +0 -0
  67. /package/{lib → lib-commonjs}/zipUtils.js +0 -0
  68. /package/{lib → lib-commonjs}/zipUtils.js.map +0 -0
  69. /package/{lib → lib-dts}/cli/ZipSyncCommandLineParser.d.ts +0 -0
  70. /package/{lib → lib-dts}/cli/ZipSyncCommandLineParser.d.ts.map +0 -0
  71. /package/{lib → lib-dts}/compress.d.ts +0 -0
  72. /package/{lib → lib-dts}/compress.d.ts.map +0 -0
  73. /package/{lib → lib-dts}/crc32.d.ts +0 -0
  74. /package/{lib → lib-dts}/crc32.d.ts.map +0 -0
  75. /package/{lib → lib-dts}/fs.d.ts +0 -0
  76. /package/{lib → lib-dts}/fs.d.ts.map +0 -0
  77. /package/{lib → lib-dts}/hash.d.ts +0 -0
  78. /package/{lib → lib-dts}/hash.d.ts.map +0 -0
  79. /package/{lib → lib-dts}/index.d.ts +0 -0
  80. /package/{lib → lib-dts}/index.d.ts.map +0 -0
  81. /package/{lib → lib-dts}/pack.d.ts +0 -0
  82. /package/{lib → lib-dts}/pack.d.ts.map +0 -0
  83. /package/{lib → lib-dts}/packWorker.d.ts +0 -0
  84. /package/{lib → lib-dts}/packWorker.d.ts.map +0 -0
  85. /package/{lib → lib-dts}/packWorkerAsync.d.ts +0 -0
  86. /package/{lib → lib-dts}/packWorkerAsync.d.ts.map +0 -0
  87. /package/{lib → lib-dts}/perf.d.ts +0 -0
  88. /package/{lib → lib-dts}/perf.d.ts.map +0 -0
  89. /package/{lib → lib-dts}/start.d.ts +0 -0
  90. /package/{lib → lib-dts}/start.d.ts.map +0 -0
  91. /package/{lib → lib-dts}/unpack.d.ts +0 -0
  92. /package/{lib → lib-dts}/unpack.d.ts.map +0 -0
  93. /package/{lib → lib-dts}/unpackWorker.d.ts +0 -0
  94. /package/{lib → lib-dts}/unpackWorker.d.ts.map +0 -0
  95. /package/{lib → lib-dts}/unpackWorkerAsync.d.ts +0 -0
  96. /package/{lib → lib-dts}/unpackWorkerAsync.d.ts.map +0 -0
  97. /package/{lib → lib-dts}/zipSyncUtils.d.ts +0 -0
  98. /package/{lib → lib-dts}/zipSyncUtils.d.ts.map +0 -0
  99. /package/{lib → lib-dts}/zipUtils.d.ts +0 -0
  100. /package/{lib → lib-dts}/zipUtils.d.ts.map +0 -0
@@ -0,0 +1,292 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+ /**
4
+ * Low-level ZIP structure helpers used by the zipsync pack/unpack pipeline.
5
+ *
6
+ * Spec reference: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
7
+ */
8
+ /**
9
+ * Local file header signature PK\x03\x04
10
+ */
11
+ const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50; // PK\x03\x04
12
+ /**
13
+ * Central directory file header signature PK\x01\x02
14
+ */
15
+ const CENTRAL_DIR_HEADER_SIGNATURE = 0x02014b50; // PK\x01\x02
16
+ /**
17
+ * End of central directory signature PK\x05\x06
18
+ */
19
+ const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50; // PK\x05\x06
20
+ /**
21
+ * Data descriptor signature PK\x07\x08
22
+ */
23
+ const DATA_DESCRIPTOR_SIGNATURE = 0x08074b50; // PK\x07\x08
24
+ export const STORE_COMPRESSION = 0;
25
+ export const DEFLATE_COMPRESSION = 8;
26
+ export const ZSTD_COMPRESSION = 93;
27
+ function writeUInt32LE(buffer, value, offset) {
28
+ buffer.writeUInt32LE(value, offset);
29
+ }
30
+ function writeUInt16LE(buffer, value, offset) {
31
+ buffer.writeUInt16LE(value, offset);
32
+ }
33
+ function readUInt32LE(buffer, offset) {
34
+ return buffer.readUInt32LE(offset);
35
+ }
36
+ function readUInt16LE(buffer, offset) {
37
+ return buffer.readUInt16LE(offset);
38
+ }
39
+ /**
40
+ * Convert a JS Date into packed DOS time/date fields used by classic ZIP.
41
+ * Seconds are stored /2 (range 0-29 => 0-58s). Years are offset from 1980.
42
+ */
43
+ export function dosDateTime(date) {
44
+ /* eslint-disable no-bitwise */
45
+ const time = ((date.getHours() & 0x1f) << 11) | ((date.getMinutes() & 0x3f) << 5) | ((date.getSeconds() / 2) & 0x1f);
46
+ const dateVal = (((date.getFullYear() - 1980) & 0x7f) << 9) |
47
+ (((date.getMonth() + 1) & 0xf) << 5) |
48
+ (date.getDate() & 0x1f);
49
+ /* eslint-enable no-bitwise */
50
+ return { time, date: dateVal };
51
+ }
52
+ /**
53
+ * Reusable scratch buffer for the fixed-length local file header (30 bytes).
54
+ * Using a single Buffer avoids per-file allocations; callers must copy/use synchronously.
55
+ */
56
+ const localFileHeaderBuffer = Buffer.allocUnsafe(30);
57
+ /**
58
+ * Write the fixed portion of a local file header for an entry (with data descriptor flag set) and
59
+ * return the header buffer plus the variable-length filename buffer.
60
+ *
61
+ * Layout (little-endian):
62
+ * signature(4) versionNeeded(2) flags(2) method(2) modTime(2) modDate(2)
63
+ * crc32(4) compSize(4) uncompSize(4) nameLen(2) extraLen(2)
64
+ *
65
+ * Because we set bit 3 of the general purpose flag, crc32/compSize/uncompSize are zero here and the
66
+ * actual values appear later in a trailing data descriptor record. This enables streaming without
67
+ * buffering entire file contents beforehand.
68
+ */
69
+ export function writeLocalFileHeader(entry) {
70
+ const filenameBuffer = Buffer.from(entry.filename, 'utf8');
71
+ const { time, date } = entry.dosDateTime;
72
+ let offset = 0;
73
+ writeUInt32LE(localFileHeaderBuffer, LOCAL_FILE_HEADER_SIGNATURE, offset);
74
+ offset += 4;
75
+ writeUInt16LE(localFileHeaderBuffer, 20, offset); // version needed
76
+ offset += 2;
77
+ // General purpose bit flag: set bit 3 (0x0008) to indicate presence of data descriptor
78
+ // Per APPNOTE: when bit 3 is set, CRC-32 and sizes in local header are set to zero and
79
+ // the actual values are stored in the data descriptor that follows the file data.
80
+ writeUInt16LE(localFileHeaderBuffer, 0x0008, offset); // flags (data descriptor)
81
+ offset += 2;
82
+ writeUInt16LE(localFileHeaderBuffer, entry.compressionMethod, offset); // compression method (0=store,8=deflate)
83
+ offset += 2;
84
+ writeUInt16LE(localFileHeaderBuffer, time, offset); // last mod time
85
+ offset += 2;
86
+ writeUInt16LE(localFileHeaderBuffer, date, offset); // last mod date
87
+ offset += 2;
88
+ // With bit 3 set, these three fields MUST be zero in the local header
89
+ writeUInt32LE(localFileHeaderBuffer, 0, offset); // crc32 (placeholder, real value in data descriptor)
90
+ offset += 4;
91
+ writeUInt32LE(localFileHeaderBuffer, 0, offset); // compressed size (placeholder)
92
+ offset += 4;
93
+ writeUInt32LE(localFileHeaderBuffer, 0, offset); // uncompressed size (placeholder)
94
+ offset += 4;
95
+ writeUInt16LE(localFileHeaderBuffer, filenameBuffer.length, offset); // filename length
96
+ offset += 2;
97
+ writeUInt16LE(localFileHeaderBuffer, 0, offset); // extra field length
98
+ offset += 2;
99
+ return [localFileHeaderBuffer, filenameBuffer];
100
+ }
101
+ /**
102
+ * Reusable scratch buffer for central directory entries (fixed-length 46 bytes before filename)
103
+ */
104
+ const centralDirHeaderBuffer = Buffer.allocUnsafe(46);
105
+ /**
106
+ * Write a central directory header referencing an already written local file entry.
107
+ * Central directory consolidates the final CRC + sizes (always present here) and provides a table
108
+ * for fast enumeration without scanning the archive sequentially.
109
+ */
110
+ export function writeCentralDirectoryHeader(entry) {
111
+ const filenameBuffer = Buffer.from(entry.filename, 'utf8');
112
+ const now = new Date();
113
+ const { time, date } = dosDateTime(now);
114
+ let offset = 0;
115
+ writeUInt32LE(centralDirHeaderBuffer, CENTRAL_DIR_HEADER_SIGNATURE, offset);
116
+ offset += 4;
117
+ writeUInt16LE(centralDirHeaderBuffer, 20, offset); // version made by
118
+ offset += 2;
119
+ writeUInt16LE(centralDirHeaderBuffer, 20, offset); // version needed
120
+ offset += 2;
121
+ // Mirror flags used in local header (bit 3 set to indicate data descriptor was used)
122
+ writeUInt16LE(centralDirHeaderBuffer, 0x0008, offset); // flags
123
+ offset += 2;
124
+ writeUInt16LE(centralDirHeaderBuffer, entry.compressionMethod, offset); // compression method
125
+ offset += 2;
126
+ writeUInt16LE(centralDirHeaderBuffer, time, offset); // last mod time
127
+ offset += 2;
128
+ writeUInt16LE(centralDirHeaderBuffer, date, offset); // last mod date
129
+ offset += 2;
130
+ writeUInt32LE(centralDirHeaderBuffer, entry.crc32, offset); // crc32
131
+ offset += 4;
132
+ writeUInt32LE(centralDirHeaderBuffer, entry.compressedSize, offset); // compressed size
133
+ offset += 4;
134
+ writeUInt32LE(centralDirHeaderBuffer, entry.size, offset); // uncompressed size
135
+ offset += 4;
136
+ writeUInt16LE(centralDirHeaderBuffer, filenameBuffer.length, offset); // filename length
137
+ offset += 2;
138
+ writeUInt16LE(centralDirHeaderBuffer, 0, offset); // extra field length
139
+ offset += 2;
140
+ writeUInt16LE(centralDirHeaderBuffer, 0, offset); // comment length
141
+ offset += 2;
142
+ writeUInt16LE(centralDirHeaderBuffer, 0, offset); // disk number start
143
+ offset += 2;
144
+ writeUInt16LE(centralDirHeaderBuffer, 0, offset); // internal file attributes
145
+ offset += 2;
146
+ writeUInt32LE(centralDirHeaderBuffer, 0, offset); // external file attributes
147
+ offset += 4;
148
+ writeUInt32LE(centralDirHeaderBuffer, entry.localHeaderOffset, offset); // local header offset
149
+ offset += 4;
150
+ return [centralDirHeaderBuffer, filenameBuffer];
151
+ }
152
+ /**
153
+ * Data descriptor: signature(4) crc32(4) compSize(4) uncompSize(4)
154
+ */
155
+ const dataDescriptorBuffer = Buffer.allocUnsafe(16);
156
+ /**
157
+ * Write the trailing data descriptor for an entry. Only used because we set flag bit 3 in the
158
+ * local file header allowing deferred CRC/size calculation.
159
+ */
160
+ export function writeDataDescriptor(entry) {
161
+ let offset = 0;
162
+ writeUInt32LE(dataDescriptorBuffer, DATA_DESCRIPTOR_SIGNATURE, offset); // signature PK\x07\x08
163
+ offset += 4;
164
+ writeUInt32LE(dataDescriptorBuffer, entry.crc32, offset); // crc32
165
+ offset += 4;
166
+ writeUInt32LE(dataDescriptorBuffer, entry.compressedSize, offset); // compressed size
167
+ offset += 4;
168
+ writeUInt32LE(dataDescriptorBuffer, entry.size, offset); // uncompressed size
169
+ return dataDescriptorBuffer;
170
+ }
171
+ /**
172
+ * End of central directory (EOCD) record (22 bytes when comment length = 0)
173
+ */
174
+ const endOfCentralDirBuffer = Buffer.allocUnsafe(22);
175
+ /**
176
+ * Write the EOCD record referencing the accumulated central directory. We omit archive comments
177
+ * and do not support ZIP64 (sufficient for build cache archive sizes today).
178
+ */
179
+ export function writeEndOfCentralDirectory(centralDirOffset, centralDirSize, entryCount) {
180
+ let offset = 0;
181
+ writeUInt32LE(endOfCentralDirBuffer, END_OF_CENTRAL_DIR_SIGNATURE, offset);
182
+ offset += 4;
183
+ writeUInt16LE(endOfCentralDirBuffer, 0, offset); // disk number
184
+ offset += 2;
185
+ writeUInt16LE(endOfCentralDirBuffer, 0, offset); // central dir start disk
186
+ offset += 2;
187
+ writeUInt16LE(endOfCentralDirBuffer, entryCount, offset); // central dir records on disk
188
+ offset += 2;
189
+ writeUInt16LE(endOfCentralDirBuffer, entryCount, offset); // total central dir records
190
+ offset += 2;
191
+ writeUInt32LE(endOfCentralDirBuffer, centralDirSize, offset); // central dir size
192
+ offset += 4;
193
+ writeUInt32LE(endOfCentralDirBuffer, centralDirOffset, offset); // central dir offset
194
+ offset += 4;
195
+ writeUInt16LE(endOfCentralDirBuffer, 0, offset); // comment length
196
+ return endOfCentralDirBuffer;
197
+ }
198
+ /**
199
+ * Parse a local file header at the provided offset. Minimal validation: signature check only.
200
+ * Returns header plus the offset pointing just past the variable-length name+extra field.
201
+ */
202
+ export function parseLocalFileHeader(buffer, offset) {
203
+ const signature = readUInt32LE(buffer, offset);
204
+ if (signature !== LOCAL_FILE_HEADER_SIGNATURE) {
205
+ throw new Error(`Unexpected local file header signature at offset ${offset.toString(16)}: ${signature.toString(16)}`);
206
+ }
207
+ const header = {
208
+ signature,
209
+ versionNeeded: readUInt16LE(buffer, offset + 4),
210
+ flags: readUInt16LE(buffer, offset + 6),
211
+ compressionMethod: readUInt16LE(buffer, offset + 8),
212
+ lastModTime: readUInt16LE(buffer, offset + 10),
213
+ lastModDate: readUInt16LE(buffer, offset + 12),
214
+ crc32: readUInt32LE(buffer, offset + 14),
215
+ compressedSize: readUInt32LE(buffer, offset + 18),
216
+ uncompressedSize: readUInt32LE(buffer, offset + 22),
217
+ filenameLength: readUInt16LE(buffer, offset + 26),
218
+ extraFieldLength: readUInt16LE(buffer, offset + 28)
219
+ };
220
+ return {
221
+ header,
222
+ nextOffset: offset + 30 + header.filenameLength + header.extraFieldLength
223
+ };
224
+ }
225
+ /**
226
+ * Parse a central directory header at the given offset (within a sliced central directory buffer).
227
+ * Returns header, filename string, and nextOffset pointing to the next structure.
228
+ */
229
+ export function parseCentralDirectoryHeader(buffer, offset) {
230
+ const signature = readUInt32LE(buffer, offset);
231
+ if (signature !== CENTRAL_DIR_HEADER_SIGNATURE) {
232
+ throw new Error(`Unexpected central directory signature at offset ${offset.toString(16)}: ${signature.toString(16)}`);
233
+ }
234
+ const header = {
235
+ signature,
236
+ versionMadeBy: readUInt16LE(buffer, offset + 4),
237
+ versionNeeded: readUInt16LE(buffer, offset + 6),
238
+ flags: readUInt16LE(buffer, offset + 8),
239
+ compressionMethod: readUInt16LE(buffer, offset + 10),
240
+ lastModTime: readUInt16LE(buffer, offset + 12),
241
+ lastModDate: readUInt16LE(buffer, offset + 14),
242
+ crc32: readUInt32LE(buffer, offset + 16),
243
+ compressedSize: readUInt32LE(buffer, offset + 20),
244
+ uncompressedSize: readUInt32LE(buffer, offset + 24),
245
+ filenameLength: readUInt16LE(buffer, offset + 28),
246
+ extraFieldLength: readUInt16LE(buffer, offset + 30),
247
+ commentLength: readUInt16LE(buffer, offset + 32),
248
+ diskNumberStart: readUInt16LE(buffer, offset + 34),
249
+ internalFileAttributes: readUInt16LE(buffer, offset + 36),
250
+ externalFileAttributes: readUInt32LE(buffer, offset + 38),
251
+ localHeaderOffset: readUInt32LE(buffer, offset + 42)
252
+ };
253
+ offset += 46;
254
+ const filename = buffer.toString('utf8', offset, offset + header.filenameLength);
255
+ return {
256
+ header,
257
+ filename,
258
+ nextOffset: offset + header.filenameLength + header.extraFieldLength + header.commentLength
259
+ };
260
+ }
261
+ /**
262
+ * Locate the EOCD record by reverse scanning. Since we never write a comment the EOCD will be the
263
+ * first matching signature encountered scanning backwards from the end.
264
+ */
265
+ export function findEndOfCentralDirectory(buffer) {
266
+ for (let i = buffer.length - 22; i >= 0; i--) {
267
+ if (readUInt32LE(buffer, i) === END_OF_CENTRAL_DIR_SIGNATURE) {
268
+ return {
269
+ signature: readUInt32LE(buffer, i),
270
+ diskNumber: readUInt16LE(buffer, i + 4),
271
+ centralDirStartDisk: readUInt16LE(buffer, i + 6),
272
+ centralDirRecordsOnDisk: readUInt16LE(buffer, i + 8),
273
+ totalCentralDirRecords: readUInt16LE(buffer, i + 10),
274
+ centralDirSize: readUInt32LE(buffer, i + 12),
275
+ centralDirOffset: readUInt32LE(buffer, i + 16),
276
+ commentLength: readUInt16LE(buffer, i + 20)
277
+ };
278
+ }
279
+ }
280
+ throw new Error('End of central directory not found');
281
+ }
282
+ /**
283
+ * Slice out the (possibly compressed) file data bytes for a central directory entry.
284
+ * Caller will decompress if needed based on entry.header.compressionMethod.
285
+ */
286
+ export function getFileFromZip(zipBuffer, entry) {
287
+ const { header: localFileHeader } = parseLocalFileHeader(zipBuffer, entry.header.localHeaderOffset);
288
+ const localDataOffset = entry.header.localHeaderOffset + 30 + localFileHeader.filenameLength + localFileHeader.extraFieldLength;
289
+ const fileZipBuffer = zipBuffer.subarray(localDataOffset, localDataOffset + entry.header.compressedSize);
290
+ return fileZipBuffer;
291
+ }
292
+ //# sourceMappingURL=zipUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zipUtils.js","sourceRoot":"","sources":["../src/zipUtils.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Low-level ZIP structure helpers used by the zipsync pack/unpack pipeline.\n *\n * Spec reference: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT\n */\n\n/**\n * Local file header signature PK\\x03\\x04\n */\nconst LOCAL_FILE_HEADER_SIGNATURE: number = 0x04034b50; // PK\\x03\\x04\n/**\n * Central directory file header signature PK\\x01\\x02\n */\nconst CENTRAL_DIR_HEADER_SIGNATURE: number = 0x02014b50; // PK\\x01\\x02\n/**\n * End of central directory signature PK\\x05\\x06\n */\nconst END_OF_CENTRAL_DIR_SIGNATURE: number = 0x06054b50; // PK\\x05\\x06\n/**\n * Data descriptor signature PK\\x07\\x08\n */\nconst DATA_DESCRIPTOR_SIGNATURE: number = 0x08074b50; // PK\\x07\\x08\n\nexport const STORE_COMPRESSION: 0 = 0;\nexport const DEFLATE_COMPRESSION: 8 = 8;\nexport const ZSTD_COMPRESSION: 93 = 93;\nexport type ZipMetaCompressionMethod =\n | typeof STORE_COMPRESSION\n | typeof DEFLATE_COMPRESSION\n | typeof ZSTD_COMPRESSION;\n\nexport interface IFileEntry {\n filename: string;\n size: number;\n compressedSize: number;\n crc32: number;\n sha1Hash: string;\n localHeaderOffset: number;\n compressionMethod: ZipMetaCompressionMethod;\n dosDateTime: { time: number; date: number };\n}\n\nexport interface ILocalFileHeader {\n signature: number;\n versionNeeded: number;\n flags: number;\n compressionMethod: number;\n lastModTime: number;\n lastModDate: number;\n crc32: number;\n compressedSize: number;\n uncompressedSize: number;\n filenameLength: number;\n extraFieldLength: number;\n}\n\nexport interface ICentralDirectoryHeader {\n signature: number;\n versionMadeBy: number;\n versionNeeded: number;\n flags: number;\n compressionMethod: number;\n lastModTime: number;\n lastModDate: number;\n crc32: number;\n compressedSize: number;\n uncompressedSize: number;\n filenameLength: number;\n extraFieldLength: number;\n commentLength: number;\n diskNumberStart: number;\n internalFileAttributes: number;\n externalFileAttributes: number;\n localHeaderOffset: number;\n}\n\nexport interface IEndOfCentralDirectory {\n signature: number;\n diskNumber: number;\n centralDirStartDisk: number;\n centralDirRecordsOnDisk: number;\n totalCentralDirRecords: number;\n centralDirSize: number;\n centralDirOffset: number;\n commentLength: number;\n}\n\nfunction writeUInt32LE(buffer: Buffer, value: number, offset: number): void {\n buffer.writeUInt32LE(value, offset);\n}\n\nfunction writeUInt16LE(buffer: Buffer, value: number, offset: number): void {\n buffer.writeUInt16LE(value, offset);\n}\n\nfunction readUInt32LE(buffer: Buffer, offset: number): number {\n return buffer.readUInt32LE(offset);\n}\n\nfunction readUInt16LE(buffer: Buffer, offset: number): number {\n return buffer.readUInt16LE(offset);\n}\n\n/**\n * Convert a JS Date into packed DOS time/date fields used by classic ZIP.\n * Seconds are stored /2 (range 0-29 => 0-58s). Years are offset from 1980.\n */\nexport function dosDateTime(date: Date): { time: number; date: number } {\n /* eslint-disable no-bitwise */\n const time: number =\n ((date.getHours() & 0x1f) << 11) | ((date.getMinutes() & 0x3f) << 5) | ((date.getSeconds() / 2) & 0x1f);\n\n const dateVal: number =\n (((date.getFullYear() - 1980) & 0x7f) << 9) |\n (((date.getMonth() + 1) & 0xf) << 5) |\n (date.getDate() & 0x1f);\n /* eslint-enable no-bitwise */\n\n return { time, date: dateVal };\n}\n\n/**\n * Reusable scratch buffer for the fixed-length local file header (30 bytes).\n * Using a single Buffer avoids per-file allocations; callers must copy/use synchronously.\n */\nconst localFileHeaderBuffer: Buffer = Buffer.allocUnsafe(30);\n/**\n * Write the fixed portion of a local file header for an entry (with data descriptor flag set) and\n * return the header buffer plus the variable-length filename buffer.\n *\n * Layout (little-endian):\n * signature(4) versionNeeded(2) flags(2) method(2) modTime(2) modDate(2)\n * crc32(4) compSize(4) uncompSize(4) nameLen(2) extraLen(2)\n *\n * Because we set bit 3 of the general purpose flag, crc32/compSize/uncompSize are zero here and the\n * actual values appear later in a trailing data descriptor record. This enables streaming without\n * buffering entire file contents beforehand.\n */\nexport function writeLocalFileHeader(\n entry: IFileEntry\n): [fileHeaderWithoutVariableLengthData: Buffer, fileHeaderVariableLengthData: Buffer] {\n const filenameBuffer: Buffer = Buffer.from(entry.filename, 'utf8');\n\n const { time, date } = entry.dosDateTime;\n\n let offset: number = 0;\n writeUInt32LE(localFileHeaderBuffer, LOCAL_FILE_HEADER_SIGNATURE, offset);\n offset += 4;\n writeUInt16LE(localFileHeaderBuffer, 20, offset); // version needed\n offset += 2;\n // General purpose bit flag: set bit 3 (0x0008) to indicate presence of data descriptor\n // Per APPNOTE: when bit 3 is set, CRC-32 and sizes in local header are set to zero and\n // the actual values are stored in the data descriptor that follows the file data.\n writeUInt16LE(localFileHeaderBuffer, 0x0008, offset); // flags (data descriptor)\n offset += 2;\n writeUInt16LE(localFileHeaderBuffer, entry.compressionMethod, offset); // compression method (0=store,8=deflate)\n offset += 2;\n writeUInt16LE(localFileHeaderBuffer, time, offset); // last mod time\n offset += 2;\n writeUInt16LE(localFileHeaderBuffer, date, offset); // last mod date\n offset += 2;\n // With bit 3 set, these three fields MUST be zero in the local header\n writeUInt32LE(localFileHeaderBuffer, 0, offset); // crc32 (placeholder, real value in data descriptor)\n offset += 4;\n writeUInt32LE(localFileHeaderBuffer, 0, offset); // compressed size (placeholder)\n offset += 4;\n writeUInt32LE(localFileHeaderBuffer, 0, offset); // uncompressed size (placeholder)\n offset += 4;\n writeUInt16LE(localFileHeaderBuffer, filenameBuffer.length, offset); // filename length\n offset += 2;\n writeUInt16LE(localFileHeaderBuffer, 0, offset); // extra field length\n offset += 2;\n\n return [localFileHeaderBuffer, filenameBuffer];\n}\n\n/**\n * Reusable scratch buffer for central directory entries (fixed-length 46 bytes before filename)\n */\nconst centralDirHeaderBuffer: Buffer = Buffer.allocUnsafe(46);\n/**\n * Write a central directory header referencing an already written local file entry.\n * Central directory consolidates the final CRC + sizes (always present here) and provides a table\n * for fast enumeration without scanning the archive sequentially.\n */\nexport function writeCentralDirectoryHeader(entry: IFileEntry): Buffer[] {\n const filenameBuffer: Buffer = Buffer.from(entry.filename, 'utf8');\n\n const now: Date = new Date();\n const { time, date } = dosDateTime(now);\n\n let offset: number = 0;\n writeUInt32LE(centralDirHeaderBuffer, CENTRAL_DIR_HEADER_SIGNATURE, offset);\n offset += 4;\n writeUInt16LE(centralDirHeaderBuffer, 20, offset); // version made by\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 20, offset); // version needed\n offset += 2;\n // Mirror flags used in local header (bit 3 set to indicate data descriptor was used)\n writeUInt16LE(centralDirHeaderBuffer, 0x0008, offset); // flags\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, entry.compressionMethod, offset); // compression method\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, time, offset); // last mod time\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, date, offset); // last mod date\n offset += 2;\n writeUInt32LE(centralDirHeaderBuffer, entry.crc32, offset); // crc32\n offset += 4;\n writeUInt32LE(centralDirHeaderBuffer, entry.compressedSize, offset); // compressed size\n offset += 4;\n writeUInt32LE(centralDirHeaderBuffer, entry.size, offset); // uncompressed size\n offset += 4;\n writeUInt16LE(centralDirHeaderBuffer, filenameBuffer.length, offset); // filename length\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 0, offset); // extra field length\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 0, offset); // comment length\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 0, offset); // disk number start\n offset += 2;\n writeUInt16LE(centralDirHeaderBuffer, 0, offset); // internal file attributes\n offset += 2;\n writeUInt32LE(centralDirHeaderBuffer, 0, offset); // external file attributes\n offset += 4;\n writeUInt32LE(centralDirHeaderBuffer, entry.localHeaderOffset, offset); // local header offset\n offset += 4;\n\n return [centralDirHeaderBuffer, filenameBuffer];\n}\n\n/**\n * Data descriptor: signature(4) crc32(4) compSize(4) uncompSize(4)\n */\nconst dataDescriptorBuffer: Buffer = Buffer.allocUnsafe(16);\n/**\n * Write the trailing data descriptor for an entry. Only used because we set flag bit 3 in the\n * local file header allowing deferred CRC/size calculation.\n */\nexport function writeDataDescriptor(entry: IFileEntry): Buffer {\n let offset: number = 0;\n writeUInt32LE(dataDescriptorBuffer, DATA_DESCRIPTOR_SIGNATURE, offset); // signature PK\\x07\\x08\n offset += 4;\n writeUInt32LE(dataDescriptorBuffer, entry.crc32, offset); // crc32\n offset += 4;\n writeUInt32LE(dataDescriptorBuffer, entry.compressedSize, offset); // compressed size\n offset += 4;\n writeUInt32LE(dataDescriptorBuffer, entry.size, offset); // uncompressed size\n return dataDescriptorBuffer;\n}\n\n/**\n * End of central directory (EOCD) record (22 bytes when comment length = 0)\n */\nconst endOfCentralDirBuffer: Buffer = Buffer.allocUnsafe(22);\n/**\n * Write the EOCD record referencing the accumulated central directory. We omit archive comments\n * and do not support ZIP64 (sufficient for build cache archive sizes today).\n */\nexport function writeEndOfCentralDirectory(\n centralDirOffset: number,\n centralDirSize: number,\n entryCount: number\n): Buffer {\n let offset: number = 0;\n writeUInt32LE(endOfCentralDirBuffer, END_OF_CENTRAL_DIR_SIGNATURE, offset);\n offset += 4;\n writeUInt16LE(endOfCentralDirBuffer, 0, offset); // disk number\n offset += 2;\n writeUInt16LE(endOfCentralDirBuffer, 0, offset); // central dir start disk\n offset += 2;\n writeUInt16LE(endOfCentralDirBuffer, entryCount, offset); // central dir records on disk\n offset += 2;\n writeUInt16LE(endOfCentralDirBuffer, entryCount, offset); // total central dir records\n offset += 2;\n writeUInt32LE(endOfCentralDirBuffer, centralDirSize, offset); // central dir size\n offset += 4;\n writeUInt32LE(endOfCentralDirBuffer, centralDirOffset, offset); // central dir offset\n offset += 4;\n writeUInt16LE(endOfCentralDirBuffer, 0, offset); // comment length\n\n return endOfCentralDirBuffer;\n}\n\ninterface ILocalFileHeaderParseResult {\n header: ILocalFileHeader;\n nextOffset: number;\n}\n\n/**\n * Parse a local file header at the provided offset. Minimal validation: signature check only.\n * Returns header plus the offset pointing just past the variable-length name+extra field.\n */\nexport function parseLocalFileHeader(buffer: Buffer, offset: number): ILocalFileHeaderParseResult {\n const signature: number = readUInt32LE(buffer, offset);\n if (signature !== LOCAL_FILE_HEADER_SIGNATURE) {\n throw new Error(\n `Unexpected local file header signature at offset ${offset.toString(16)}: ${signature.toString(16)}`\n );\n }\n const header: ILocalFileHeader = {\n signature,\n versionNeeded: readUInt16LE(buffer, offset + 4),\n flags: readUInt16LE(buffer, offset + 6),\n compressionMethod: readUInt16LE(buffer, offset + 8),\n lastModTime: readUInt16LE(buffer, offset + 10),\n lastModDate: readUInt16LE(buffer, offset + 12),\n crc32: readUInt32LE(buffer, offset + 14),\n compressedSize: readUInt32LE(buffer, offset + 18),\n uncompressedSize: readUInt32LE(buffer, offset + 22),\n filenameLength: readUInt16LE(buffer, offset + 26),\n extraFieldLength: readUInt16LE(buffer, offset + 28)\n };\n\n return {\n header,\n nextOffset: offset + 30 + header.filenameLength + header.extraFieldLength\n };\n}\n\nexport interface ICentralDirectoryHeaderParseResult {\n header: ICentralDirectoryHeader;\n filename: string;\n nextOffset: number;\n}\n\n/**\n * Parse a central directory header at the given offset (within a sliced central directory buffer).\n * Returns header, filename string, and nextOffset pointing to the next structure.\n */\nexport function parseCentralDirectoryHeader(\n buffer: Buffer,\n offset: number\n): ICentralDirectoryHeaderParseResult {\n const signature: number = readUInt32LE(buffer, offset);\n if (signature !== CENTRAL_DIR_HEADER_SIGNATURE) {\n throw new Error(\n `Unexpected central directory signature at offset ${offset.toString(16)}: ${signature.toString(16)}`\n );\n }\n const header: ICentralDirectoryHeader = {\n signature,\n versionMadeBy: readUInt16LE(buffer, offset + 4),\n versionNeeded: readUInt16LE(buffer, offset + 6),\n flags: readUInt16LE(buffer, offset + 8),\n compressionMethod: readUInt16LE(buffer, offset + 10),\n lastModTime: readUInt16LE(buffer, offset + 12),\n lastModDate: readUInt16LE(buffer, offset + 14),\n crc32: readUInt32LE(buffer, offset + 16),\n compressedSize: readUInt32LE(buffer, offset + 20),\n uncompressedSize: readUInt32LE(buffer, offset + 24),\n filenameLength: readUInt16LE(buffer, offset + 28),\n extraFieldLength: readUInt16LE(buffer, offset + 30),\n commentLength: readUInt16LE(buffer, offset + 32),\n diskNumberStart: readUInt16LE(buffer, offset + 34),\n internalFileAttributes: readUInt16LE(buffer, offset + 36),\n externalFileAttributes: readUInt32LE(buffer, offset + 38),\n localHeaderOffset: readUInt32LE(buffer, offset + 42)\n };\n\n offset += 46;\n\n const filename: string = buffer.toString('utf8', offset, offset + header.filenameLength);\n\n return {\n header,\n filename,\n nextOffset: offset + header.filenameLength + header.extraFieldLength + header.commentLength\n };\n}\n\n/**\n * Locate the EOCD record by reverse scanning. Since we never write a comment the EOCD will be the\n * first matching signature encountered scanning backwards from the end.\n */\nexport function findEndOfCentralDirectory(buffer: Buffer): IEndOfCentralDirectory {\n for (let i: number = buffer.length - 22; i >= 0; i--) {\n if (readUInt32LE(buffer, i) === END_OF_CENTRAL_DIR_SIGNATURE) {\n return {\n signature: readUInt32LE(buffer, i),\n diskNumber: readUInt16LE(buffer, i + 4),\n centralDirStartDisk: readUInt16LE(buffer, i + 6),\n centralDirRecordsOnDisk: readUInt16LE(buffer, i + 8),\n totalCentralDirRecords: readUInt16LE(buffer, i + 10),\n centralDirSize: readUInt32LE(buffer, i + 12),\n centralDirOffset: readUInt32LE(buffer, i + 16),\n commentLength: readUInt16LE(buffer, i + 20)\n };\n }\n }\n\n throw new Error('End of central directory not found');\n}\n\n/**\n * Slice out the (possibly compressed) file data bytes for a central directory entry.\n * Caller will decompress if needed based on entry.header.compressionMethod.\n */\nexport function getFileFromZip(zipBuffer: Buffer, entry: ICentralDirectoryHeaderParseResult): Buffer {\n const { header: localFileHeader } = parseLocalFileHeader(zipBuffer, entry.header.localHeaderOffset);\n const localDataOffset: number =\n entry.header.localHeaderOffset + 30 + localFileHeader.filenameLength + localFileHeader.extraFieldLength;\n const fileZipBuffer: Buffer = zipBuffer.subarray(\n localDataOffset,\n localDataOffset + entry.header.compressedSize\n );\n return fileZipBuffer;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/zipsync",
3
- "version": "0.2.13",
3
+ "version": "0.3.0",
4
4
  "description": "CLI tool for creating and extracting ZIP archives with intelligent filesystem synchronization",
5
5
  "repository": {
6
6
  "type": "git",
@@ -13,15 +13,42 @@
13
13
  "license": "MIT",
14
14
  "dependencies": {
15
15
  "typescript": "~5.8.2",
16
- "@rushstack/terminal": "0.21.0",
17
- "@rushstack/lookup-by-path": "0.8.15",
18
- "@rushstack/ts-command-line": "5.2.0"
16
+ "@rushstack/terminal": "0.22.0",
17
+ "@rushstack/ts-command-line": "5.3.0",
18
+ "@rushstack/lookup-by-path": "0.9.0"
19
19
  },
20
20
  "devDependencies": {
21
21
  "eslint": "~9.37.0",
22
- "@rushstack/heft": "1.1.13",
23
- "local-node-rig": "1.0.0"
22
+ "local-node-rig": "1.0.0",
23
+ "@rushstack/heft": "1.2.0"
24
24
  },
25
+ "main": "./lib-commonjs/index.js",
26
+ "module": "./lib-esm/index.js",
27
+ "types": "./lib-dts/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./lib-dts/index.d.ts",
31
+ "import": "./lib-esm/index.js",
32
+ "require": "./lib-commonjs/index.js"
33
+ },
34
+ "./lib/*": {
35
+ "types": "./lib-dts/*.d.ts",
36
+ "import": "./lib-esm/*.js",
37
+ "require": "./lib-commonjs/*.js"
38
+ },
39
+ "./package.json": "./package.json"
40
+ },
41
+ "typesVersions": {
42
+ "*": {
43
+ "lib/*": [
44
+ "lib-dts/*"
45
+ ]
46
+ }
47
+ },
48
+ "sideEffects": [
49
+ "lib-commonjs/start.js",
50
+ "lib-esm/start.js"
51
+ ],
25
52
  "scripts": {
26
53
  "start": "node lib/start",
27
54
  "build": "heft build --clean",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes