@cj-tech-master/excelts 4.2.1-canary.20260111102127.f808a37 → 4.2.1

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 (232) hide show
  1. package/THIRD_PARTY_NOTICES.md +31 -0
  2. package/dist/browser/index.browser.d.ts +0 -1
  3. package/dist/browser/index.browser.js +0 -12
  4. package/dist/browser/modules/archive/byte-queue.d.ts +18 -0
  5. package/dist/browser/modules/archive/byte-queue.js +125 -0
  6. package/dist/browser/modules/archive/{compression/compress.base.js → compress.base.js} +1 -1
  7. package/dist/browser/modules/archive/{compression/compress.browser.d.ts → compress.browser.d.ts} +8 -2
  8. package/dist/{esm/modules/archive/compression → browser/modules/archive}/compress.browser.js +11 -3
  9. package/dist/browser/modules/archive/{compression/compress.d.ts → compress.d.ts} +2 -2
  10. package/dist/{esm/modules/archive/compression → browser/modules/archive}/compress.js +1 -1
  11. package/dist/browser/modules/archive/{compression/crc32.browser.d.ts → crc32.browser.d.ts} +1 -1
  12. package/dist/browser/modules/archive/{compression/crc32.d.ts → crc32.d.ts} +1 -1
  13. package/dist/browser/modules/archive/{compression/crc32.js → crc32.js} +1 -1
  14. package/dist/browser/modules/archive/defaults.d.ts +0 -1
  15. package/dist/browser/modules/archive/defaults.js +3 -6
  16. package/dist/browser/modules/archive/{compression/deflate-fallback.js → deflate-fallback.js} +1 -1
  17. package/dist/browser/modules/archive/{unzip/extract.d.ts → extract.d.ts} +2 -2
  18. package/dist/browser/modules/archive/index.base.d.ts +4 -4
  19. package/dist/browser/modules/archive/index.base.js +6 -3
  20. package/dist/browser/modules/archive/index.browser.d.ts +4 -3
  21. package/dist/browser/modules/archive/index.browser.js +7 -3
  22. package/dist/browser/modules/archive/index.d.ts +4 -3
  23. package/dist/browser/modules/archive/index.js +5 -3
  24. package/dist/browser/modules/archive/{unzip/stream.base.d.ts → parse.base.d.ts} +2 -36
  25. package/dist/browser/modules/archive/parse.base.js +644 -0
  26. package/dist/browser/modules/archive/{unzip/stream.browser.d.ts → parse.browser.d.ts} +1 -1
  27. package/dist/{esm/modules/archive/unzip/stream.browser.js → browser/modules/archive/parse.browser.js} +110 -371
  28. package/dist/browser/modules/archive/{unzip/stream.d.ts → parse.d.ts} +2 -2
  29. package/dist/{esm/modules/archive/unzip/stream.js → browser/modules/archive/parse.js} +5 -6
  30. package/dist/browser/modules/archive/{compression/streaming-compress.browser.d.ts → streaming-compress.browser.d.ts} +2 -2
  31. package/dist/browser/modules/archive/{compression/streaming-compress.browser.js → streaming-compress.browser.js} +3 -3
  32. package/dist/browser/modules/archive/{compression/streaming-compress.d.ts → streaming-compress.d.ts} +2 -2
  33. package/dist/browser/modules/archive/{compression/streaming-compress.js → streaming-compress.js} +2 -2
  34. package/dist/browser/modules/archive/{zip/stream.d.ts → streaming-zip.d.ts} +5 -28
  35. package/dist/{esm/modules/archive/zip/stream.js → browser/modules/archive/streaming-zip.js} +48 -192
  36. package/dist/browser/modules/archive/utils/bytes.js +16 -16
  37. package/dist/browser/modules/archive/utils/parse-buffer.js +23 -21
  38. package/dist/browser/modules/archive/utils/timestamps.js +1 -62
  39. package/dist/browser/modules/archive/utils/zip-extra-fields.d.ts +1 -1
  40. package/dist/browser/modules/archive/utils/zip-extra-fields.js +14 -26
  41. package/dist/browser/modules/archive/utils/zip-extra.d.ts +18 -0
  42. package/dist/browser/modules/archive/utils/zip-extra.js +68 -0
  43. package/dist/browser/modules/archive/zip-builder.d.ts +117 -0
  44. package/dist/browser/modules/archive/zip-builder.js +292 -0
  45. package/dist/browser/modules/archive/zip-constants.d.ts +18 -0
  46. package/dist/browser/modules/archive/zip-constants.js +23 -0
  47. package/dist/{esm/modules/archive/zip → browser/modules/archive}/zip-entry-metadata.js +3 -3
  48. package/dist/{types/modules/archive/unzip → browser/modules/archive}/zip-parser.d.ts +1 -1
  49. package/dist/{esm/modules/archive/unzip → browser/modules/archive}/zip-parser.js +24 -38
  50. package/dist/browser/modules/archive/{zip-spec/zip-records.d.ts → zip-records.d.ts} +0 -20
  51. package/dist/browser/modules/archive/zip-records.js +84 -0
  52. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +1 -1
  53. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
  54. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +1 -1
  55. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +6 -3
  56. package/dist/browser/modules/excel/xlsx/xlsx.js +1 -1
  57. package/dist/browser/modules/stream/streams.browser.d.ts +30 -28
  58. package/dist/browser/modules/stream/streams.browser.js +710 -830
  59. package/dist/browser/modules/stream/streams.js +58 -140
  60. package/dist/cjs/modules/archive/byte-queue.js +129 -0
  61. package/dist/cjs/modules/archive/{compression/compress.base.js → compress.base.js} +1 -1
  62. package/dist/cjs/modules/archive/{compression/compress.browser.js → compress.browser.js} +11 -3
  63. package/dist/cjs/modules/archive/{compression/compress.js → compress.js} +1 -1
  64. package/dist/cjs/modules/archive/{compression/crc32.js → crc32.js} +1 -1
  65. package/dist/cjs/modules/archive/defaults.js +4 -7
  66. package/dist/cjs/modules/archive/{compression/deflate-fallback.js → deflate-fallback.js} +1 -1
  67. package/dist/cjs/modules/archive/index.base.js +19 -9
  68. package/dist/cjs/modules/archive/index.browser.js +10 -4
  69. package/dist/cjs/modules/archive/index.js +8 -4
  70. package/dist/cjs/modules/archive/parse.base.js +666 -0
  71. package/dist/cjs/modules/archive/{unzip/stream.browser.js → parse.browser.js} +111 -372
  72. package/dist/cjs/modules/archive/{unzip/stream.js → parse.js} +8 -9
  73. package/dist/cjs/modules/archive/{compression/streaming-compress.browser.js → streaming-compress.browser.js} +3 -3
  74. package/dist/cjs/modules/archive/{compression/streaming-compress.js → streaming-compress.js} +2 -2
  75. package/dist/cjs/modules/archive/{zip/stream.js → streaming-zip.js} +50 -194
  76. package/dist/cjs/modules/archive/utils/bytes.js +16 -16
  77. package/dist/cjs/modules/archive/utils/parse-buffer.js +23 -21
  78. package/dist/cjs/modules/archive/utils/timestamps.js +3 -64
  79. package/dist/cjs/modules/archive/utils/zip-extra-fields.js +14 -26
  80. package/dist/cjs/modules/archive/utils/zip-extra.js +74 -0
  81. package/dist/cjs/modules/archive/zip-builder.js +297 -0
  82. package/dist/cjs/modules/archive/zip-constants.js +26 -0
  83. package/dist/cjs/modules/archive/{zip/zip-entry-metadata.js → zip-entry-metadata.js} +5 -5
  84. package/dist/cjs/modules/archive/{unzip/zip-parser.js → zip-parser.js} +33 -47
  85. package/dist/cjs/modules/archive/zip-records.js +90 -0
  86. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +2 -2
  87. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +4 -4
  88. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +9 -6
  89. package/dist/cjs/modules/excel/xlsx/xlsx.js +2 -2
  90. package/dist/cjs/modules/stream/streams.browser.js +710 -830
  91. package/dist/cjs/modules/stream/streams.js +58 -140
  92. package/dist/esm/index.browser.js +0 -12
  93. package/dist/esm/modules/archive/byte-queue.js +125 -0
  94. package/dist/esm/modules/archive/{compression/compress.base.js → compress.base.js} +1 -1
  95. package/dist/{browser/modules/archive/compression → esm/modules/archive}/compress.browser.js +11 -3
  96. package/dist/{browser/modules/archive/compression → esm/modules/archive}/compress.js +1 -1
  97. package/dist/esm/modules/archive/{compression/crc32.js → crc32.js} +1 -1
  98. package/dist/esm/modules/archive/defaults.js +3 -6
  99. package/dist/esm/modules/archive/{compression/deflate-fallback.js → deflate-fallback.js} +1 -1
  100. package/dist/esm/modules/archive/index.base.js +6 -3
  101. package/dist/esm/modules/archive/index.browser.js +7 -3
  102. package/dist/esm/modules/archive/index.js +5 -3
  103. package/dist/esm/modules/archive/parse.base.js +644 -0
  104. package/dist/{browser/modules/archive/unzip/stream.browser.js → esm/modules/archive/parse.browser.js} +110 -371
  105. package/dist/{browser/modules/archive/unzip/stream.js → esm/modules/archive/parse.js} +5 -6
  106. package/dist/esm/modules/archive/{compression/streaming-compress.browser.js → streaming-compress.browser.js} +3 -3
  107. package/dist/esm/modules/archive/{compression/streaming-compress.js → streaming-compress.js} +2 -2
  108. package/dist/{browser/modules/archive/zip/stream.js → esm/modules/archive/streaming-zip.js} +48 -192
  109. package/dist/esm/modules/archive/utils/bytes.js +16 -16
  110. package/dist/esm/modules/archive/utils/parse-buffer.js +23 -21
  111. package/dist/esm/modules/archive/utils/timestamps.js +1 -62
  112. package/dist/esm/modules/archive/utils/zip-extra-fields.js +14 -26
  113. package/dist/esm/modules/archive/utils/zip-extra.js +68 -0
  114. package/dist/esm/modules/archive/zip-builder.js +292 -0
  115. package/dist/esm/modules/archive/zip-constants.js +23 -0
  116. package/dist/{browser/modules/archive/zip → esm/modules/archive}/zip-entry-metadata.js +3 -3
  117. package/dist/{browser/modules/archive/unzip → esm/modules/archive}/zip-parser.js +24 -38
  118. package/dist/esm/modules/archive/zip-records.js +84 -0
  119. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +1 -1
  120. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +1 -1
  121. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +6 -3
  122. package/dist/esm/modules/excel/xlsx/xlsx.js +1 -1
  123. package/dist/esm/modules/stream/streams.browser.js +710 -830
  124. package/dist/esm/modules/stream/streams.js +58 -140
  125. package/dist/iife/THIRD_PARTY_NOTICES.md +31 -0
  126. package/dist/iife/excelts.iife.js +4425 -6215
  127. package/dist/iife/excelts.iife.js.map +1 -1
  128. package/dist/iife/excelts.iife.min.js +31 -103
  129. package/dist/types/index.browser.d.ts +0 -1
  130. package/dist/types/modules/archive/byte-queue.d.ts +18 -0
  131. package/dist/types/modules/archive/{compression/compress.browser.d.ts → compress.browser.d.ts} +8 -2
  132. package/dist/types/modules/archive/defaults.d.ts +0 -1
  133. package/dist/types/modules/archive/index.base.d.ts +4 -4
  134. package/dist/types/modules/archive/index.browser.d.ts +4 -3
  135. package/dist/types/modules/archive/index.d.ts +4 -3
  136. package/dist/types/modules/archive/{unzip/stream.base.d.ts → parse.base.d.ts} +4 -38
  137. package/dist/types/modules/archive/{unzip/stream.browser.d.ts → parse.browser.d.ts} +2 -2
  138. package/dist/types/modules/archive/{unzip/stream.d.ts → parse.d.ts} +3 -3
  139. package/dist/types/modules/archive/{compression/streaming-compress.browser.d.ts → streaming-compress.browser.d.ts} +1 -1
  140. package/dist/types/modules/archive/{zip/stream.d.ts → streaming-zip.d.ts} +6 -29
  141. package/dist/types/modules/archive/utils/zip-extra-fields.d.ts +1 -1
  142. package/dist/types/modules/archive/utils/zip-extra.d.ts +18 -0
  143. package/dist/types/modules/archive/zip-builder.d.ts +117 -0
  144. package/dist/types/modules/archive/zip-constants.d.ts +18 -0
  145. package/dist/types/modules/archive/{zip/zip-entry-metadata.d.ts → zip-entry-metadata.d.ts} +1 -1
  146. package/dist/{browser/modules/archive/unzip → types/modules/archive}/zip-parser.d.ts +1 -1
  147. package/dist/types/modules/archive/{zip-spec/zip-records.d.ts → zip-records.d.ts} +0 -20
  148. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
  149. package/dist/types/modules/stream/streams.browser.d.ts +30 -28
  150. package/package.json +1 -5
  151. package/dist/browser/modules/archive/internal/byte-queue.d.ts +0 -33
  152. package/dist/browser/modules/archive/internal/byte-queue.js +0 -407
  153. package/dist/browser/modules/archive/io/archive-sink.d.ts +0 -9
  154. package/dist/browser/modules/archive/io/archive-sink.js +0 -77
  155. package/dist/browser/modules/archive/io/archive-source.d.ts +0 -8
  156. package/dist/browser/modules/archive/io/archive-source.js +0 -107
  157. package/dist/browser/modules/archive/unzip/index.d.ts +0 -40
  158. package/dist/browser/modules/archive/unzip/index.js +0 -164
  159. package/dist/browser/modules/archive/unzip/stream.base.js +0 -1022
  160. package/dist/browser/modules/archive/utils/async-queue.d.ts +0 -7
  161. package/dist/browser/modules/archive/utils/async-queue.js +0 -103
  162. package/dist/browser/modules/archive/utils/compressibility.d.ts +0 -10
  163. package/dist/browser/modules/archive/utils/compressibility.js +0 -57
  164. package/dist/browser/modules/archive/utils/pattern-scanner.d.ts +0 -21
  165. package/dist/browser/modules/archive/utils/pattern-scanner.js +0 -27
  166. package/dist/browser/modules/archive/zip/index.d.ts +0 -42
  167. package/dist/browser/modules/archive/zip/index.js +0 -157
  168. package/dist/browser/modules/archive/zip/zip-bytes.d.ts +0 -73
  169. package/dist/browser/modules/archive/zip/zip-bytes.js +0 -239
  170. package/dist/browser/modules/archive/zip-spec/zip-records.js +0 -126
  171. package/dist/cjs/modules/archive/internal/byte-queue.js +0 -411
  172. package/dist/cjs/modules/archive/io/archive-sink.js +0 -82
  173. package/dist/cjs/modules/archive/io/archive-source.js +0 -114
  174. package/dist/cjs/modules/archive/unzip/index.js +0 -170
  175. package/dist/cjs/modules/archive/unzip/stream.base.js +0 -1044
  176. package/dist/cjs/modules/archive/utils/async-queue.js +0 -106
  177. package/dist/cjs/modules/archive/utils/compressibility.js +0 -60
  178. package/dist/cjs/modules/archive/utils/pattern-scanner.js +0 -31
  179. package/dist/cjs/modules/archive/zip/index.js +0 -162
  180. package/dist/cjs/modules/archive/zip/zip-bytes.js +0 -242
  181. package/dist/cjs/modules/archive/zip-spec/zip-records.js +0 -136
  182. package/dist/esm/modules/archive/internal/byte-queue.js +0 -407
  183. package/dist/esm/modules/archive/io/archive-sink.js +0 -77
  184. package/dist/esm/modules/archive/io/archive-source.js +0 -107
  185. package/dist/esm/modules/archive/unzip/index.js +0 -164
  186. package/dist/esm/modules/archive/unzip/stream.base.js +0 -1022
  187. package/dist/esm/modules/archive/utils/async-queue.js +0 -103
  188. package/dist/esm/modules/archive/utils/compressibility.js +0 -57
  189. package/dist/esm/modules/archive/utils/pattern-scanner.js +0 -27
  190. package/dist/esm/modules/archive/zip/index.js +0 -157
  191. package/dist/esm/modules/archive/zip/zip-bytes.js +0 -239
  192. package/dist/esm/modules/archive/zip-spec/zip-records.js +0 -126
  193. package/dist/types/modules/archive/internal/byte-queue.d.ts +0 -33
  194. package/dist/types/modules/archive/io/archive-sink.d.ts +0 -9
  195. package/dist/types/modules/archive/io/archive-source.d.ts +0 -8
  196. package/dist/types/modules/archive/unzip/index.d.ts +0 -40
  197. package/dist/types/modules/archive/utils/async-queue.d.ts +0 -7
  198. package/dist/types/modules/archive/utils/compressibility.d.ts +0 -10
  199. package/dist/types/modules/archive/utils/pattern-scanner.d.ts +0 -21
  200. package/dist/types/modules/archive/zip/index.d.ts +0 -42
  201. package/dist/types/modules/archive/zip/zip-bytes.d.ts +0 -73
  202. /package/dist/browser/modules/archive/{compression/compress.base.d.ts → compress.base.d.ts} +0 -0
  203. /package/dist/browser/modules/archive/{compression/crc32.base.d.ts → crc32.base.d.ts} +0 -0
  204. /package/dist/browser/modules/archive/{compression/crc32.base.js → crc32.base.js} +0 -0
  205. /package/dist/browser/modules/archive/{compression/crc32.browser.js → crc32.browser.js} +0 -0
  206. /package/dist/browser/modules/archive/{compression/deflate-fallback.d.ts → deflate-fallback.d.ts} +0 -0
  207. /package/dist/browser/modules/archive/{unzip/extract.js → extract.js} +0 -0
  208. /package/dist/browser/modules/archive/{compression/streaming-compress.base.d.ts → streaming-compress.base.d.ts} +0 -0
  209. /package/dist/browser/modules/archive/{compression/streaming-compress.base.js → streaming-compress.base.js} +0 -0
  210. /package/dist/browser/modules/archive/{zip-spec/zip-entry-info.d.ts → zip-entry-info.d.ts} +0 -0
  211. /package/dist/browser/modules/archive/{zip-spec/zip-entry-info.js → zip-entry-info.js} +0 -0
  212. /package/dist/browser/modules/archive/{zip/zip-entry-metadata.d.ts → zip-entry-metadata.d.ts} +0 -0
  213. /package/dist/cjs/modules/archive/{compression/crc32.base.js → crc32.base.js} +0 -0
  214. /package/dist/cjs/modules/archive/{compression/crc32.browser.js → crc32.browser.js} +0 -0
  215. /package/dist/cjs/modules/archive/{unzip/extract.js → extract.js} +0 -0
  216. /package/dist/cjs/modules/archive/{compression/streaming-compress.base.js → streaming-compress.base.js} +0 -0
  217. /package/dist/cjs/modules/archive/{zip-spec/zip-entry-info.js → zip-entry-info.js} +0 -0
  218. /package/dist/esm/modules/archive/{compression/crc32.base.js → crc32.base.js} +0 -0
  219. /package/dist/esm/modules/archive/{compression/crc32.browser.js → crc32.browser.js} +0 -0
  220. /package/dist/esm/modules/archive/{unzip/extract.js → extract.js} +0 -0
  221. /package/dist/esm/modules/archive/{compression/streaming-compress.base.js → streaming-compress.base.js} +0 -0
  222. /package/dist/esm/modules/archive/{zip-spec/zip-entry-info.js → zip-entry-info.js} +0 -0
  223. /package/dist/types/modules/archive/{compression/compress.base.d.ts → compress.base.d.ts} +0 -0
  224. /package/dist/types/modules/archive/{compression/compress.d.ts → compress.d.ts} +0 -0
  225. /package/dist/types/modules/archive/{compression/crc32.base.d.ts → crc32.base.d.ts} +0 -0
  226. /package/dist/types/modules/archive/{compression/crc32.browser.d.ts → crc32.browser.d.ts} +0 -0
  227. /package/dist/types/modules/archive/{compression/crc32.d.ts → crc32.d.ts} +0 -0
  228. /package/dist/types/modules/archive/{compression/deflate-fallback.d.ts → deflate-fallback.d.ts} +0 -0
  229. /package/dist/types/modules/archive/{unzip/extract.d.ts → extract.d.ts} +0 -0
  230. /package/dist/types/modules/archive/{compression/streaming-compress.base.d.ts → streaming-compress.base.d.ts} +0 -0
  231. /package/dist/types/modules/archive/{compression/streaming-compress.d.ts → streaming-compress.d.ts} +0 -0
  232. /package/dist/types/modules/archive/{zip-spec/zip-entry-info.d.ts → zip-entry-info.d.ts} +0 -0
@@ -6,68 +6,7 @@ exports.resolveZipLastModifiedDateFromUnixSeconds = resolveZipLastModifiedDateFr
6
6
  exports.resolveZipLastModifiedDateFromExtraField = resolveZipLastModifiedDateFromExtraField;
7
7
  exports.buildZipTimestampExtraField = buildZipTimestampExtraField;
8
8
  exports.dateToZipDos = dateToZipDos;
9
- const EXTENDED_TIMESTAMP_ID = 0x5455;
10
- function clampUint32(value) {
11
- if (!Number.isFinite(value)) {
12
- return 0;
13
- }
14
- if (value <= 0) {
15
- return 0;
16
- }
17
- // 0xFFFFFFFF fits JS safe integer.
18
- if (value >= 0xffffffff) {
19
- return 0xffffffff;
20
- }
21
- return value >>> 0;
22
- }
23
- function unixSecondsFromDate(date) {
24
- return clampUint32(Math.floor(date.getTime() / 1000));
25
- }
26
- /**
27
- * Parse Info-ZIP "Extended Timestamp" extra field (0x5455) and return mtime.
28
- * Returns Unix seconds (UTC) if present.
29
- */
30
- function parseExtendedTimestampMtimeUnixSeconds(extraField) {
31
- const view = new DataView(extraField.buffer, extraField.byteOffset, extraField.byteLength);
32
- let offset = 0;
33
- while (offset + 4 <= extraField.length) {
34
- const headerId = view.getUint16(offset, true);
35
- const dataSize = view.getUint16(offset + 2, true);
36
- const dataStart = offset + 4;
37
- const dataEnd = dataStart + dataSize;
38
- if (dataEnd > extraField.length) {
39
- break;
40
- }
41
- if (headerId === EXTENDED_TIMESTAMP_ID && dataSize >= 1) {
42
- const flags = extraField[dataStart];
43
- if ((flags & 0x01) !== 0 && dataSize >= 5) {
44
- // mtime is 4 bytes right after flags.
45
- return view.getUint32(dataStart + 1, true) >>> 0;
46
- }
47
- }
48
- offset = dataEnd;
49
- }
50
- return undefined;
51
- }
52
- /**
53
- * Build Info-ZIP "Extended Timestamp" extra field (0x5455).
54
- * We write only mtime (UTC, Unix seconds) to minimize size.
55
- */
56
- function buildExtendedTimestampExtraFieldFromUnixSeconds(unixSeconds) {
57
- const ts = clampUint32(unixSeconds);
58
- // flags(1) + mtime(4)
59
- const payloadSize = 5;
60
- const out = new Uint8Array(4 + payloadSize);
61
- const view = new DataView(out.buffer);
62
- view.setUint16(0, EXTENDED_TIMESTAMP_ID, true);
63
- view.setUint16(2, payloadSize, true);
64
- out[4] = 0x01; // mtime present
65
- view.setUint32(5, ts, true);
66
- return out;
67
- }
68
- function buildExtendedTimestampExtraFieldFromDate(date) {
69
- return buildExtendedTimestampExtraFieldFromUnixSeconds(unixSecondsFromDate(date));
70
- }
9
+ const zip_extra_1 = require("./zip-extra.js");
71
10
  /**
72
11
  * DOS date/time helpers for ZIP files.
73
12
  */
@@ -105,11 +44,11 @@ function resolveZipLastModifiedDateFromUnixSeconds(dosDate, dosTime, mtimeUnixSe
105
44
  return new Date(mtimeUnixSeconds * 1000);
106
45
  }
107
46
  function resolveZipLastModifiedDateFromExtraField(dosDate, dosTime, extraField) {
108
- const unixSeconds = parseExtendedTimestampMtimeUnixSeconds(extraField);
47
+ const unixSeconds = (0, zip_extra_1.parseExtendedTimestampMtimeUnixSeconds)(extraField);
109
48
  return resolveZipLastModifiedDateFromUnixSeconds(dosDate, dosTime, unixSeconds);
110
49
  }
111
50
  function buildZipTimestampExtraField(modTime, mode) {
112
- return mode === "dos+utc" ? buildExtendedTimestampExtraFieldFromDate(modTime) : new Uint8Array(0);
51
+ return mode === "dos+utc" ? (0, zip_extra_1.buildExtendedTimestampExtraFieldFromDate)(modTime) : new Uint8Array(0);
113
52
  }
114
53
  function dateToZipDos(modTime) {
115
54
  const [dosTime, dosDate] = dateToDos(modTime);
@@ -2,33 +2,12 @@
2
2
  /**
3
3
  * ZIP extra field parsing helpers.
4
4
  *
5
- * Kept standalone so both streaming parser (`stream.base.ts`) and buffer parser
5
+ * Kept standalone so both streaming parser (`parse.base.ts`) and buffer parser
6
6
  * (`zip-parser.ts`) can share ZIP64 + Info-ZIP timestamp handling.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.parseZipExtraFields = parseZipExtraFields;
10
- const EXTENDED_TIMESTAMP_ID = 0x5455;
11
- function parseExtendedTimestampMtimeUnixSeconds(extraField) {
12
- const view = new DataView(extraField.buffer, extraField.byteOffset, extraField.byteLength);
13
- let offset = 0;
14
- while (offset + 4 <= extraField.length) {
15
- const headerId = view.getUint16(offset, true);
16
- const dataSize = view.getUint16(offset + 2, true);
17
- const dataStart = offset + 4;
18
- const dataEnd = dataStart + dataSize;
19
- if (dataEnd > extraField.length) {
20
- break;
21
- }
22
- if (headerId === EXTENDED_TIMESTAMP_ID && dataSize >= 1) {
23
- const flags = extraField[dataStart];
24
- if ((flags & 0x01) !== 0 && dataSize >= 5) {
25
- return view.getUint32(dataStart + 1, true) >>> 0;
26
- }
27
- }
28
- offset = dataEnd;
29
- }
30
- return undefined;
31
- }
10
+ const zip_extra_1 = require("./zip-extra.js");
32
11
  function readUint64LE(view, offset) {
33
12
  // Convert to Number via 2x Uint32 to avoid BigInt requirements.
34
13
  const low = view.getUint32(offset, true);
@@ -67,9 +46,18 @@ function parseZipExtraFields(extraField, vars) {
67
46
  }
68
47
  }
69
48
  else if (signature === 0x5455) {
70
- const unixSeconds = parseExtendedTimestampMtimeUnixSeconds(extraField.subarray(offset, dataEnd));
71
- if (unixSeconds !== undefined) {
72
- extra.mtimeUnixSeconds = unixSeconds;
49
+ // Fast-path parse for Info-ZIP extended timestamp (mtime only).
50
+ if (partSize >= 1) {
51
+ const flags = extraField[dataStart];
52
+ if ((flags & 0x01) !== 0 && partSize >= 5) {
53
+ extra.mtimeUnixSeconds = view.getUint32(dataStart + 1, true) >>> 0;
54
+ }
55
+ else {
56
+ const unixSeconds = (0, zip_extra_1.parseExtendedTimestampMtimeUnixSeconds)(extraField.subarray(offset, dataEnd));
57
+ if (unixSeconds !== undefined) {
58
+ extra.mtimeUnixSeconds = unixSeconds;
59
+ }
60
+ }
73
61
  }
74
62
  }
75
63
  offset = dataEnd;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unixSecondsFromDate = unixSecondsFromDate;
4
+ exports.buildExtendedTimestampExtraFieldFromUnixSeconds = buildExtendedTimestampExtraFieldFromUnixSeconds;
5
+ exports.buildExtendedTimestampExtraFieldFromDate = buildExtendedTimestampExtraFieldFromDate;
6
+ exports.parseExtendedTimestampMtimeUnixSeconds = parseExtendedTimestampMtimeUnixSeconds;
7
+ const EXTENDED_TIMESTAMP_ID = 0x5455;
8
+ function clampUint32(value) {
9
+ if (!Number.isFinite(value)) {
10
+ return 0;
11
+ }
12
+ if (value <= 0) {
13
+ return 0;
14
+ }
15
+ // 0xFFFFFFFF fits JS safe integer.
16
+ if (value >= 0xffffffff) {
17
+ return 0xffffffff;
18
+ }
19
+ return value >>> 0;
20
+ }
21
+ function unixSecondsFromDate(date) {
22
+ return clampUint32(Math.floor(date.getTime() / 1000));
23
+ }
24
+ /**
25
+ * Build Info-ZIP "Extended Timestamp" extra field (0x5455).
26
+ * We write only mtime (UTC, Unix seconds) to minimize size.
27
+ *
28
+ * Layout:
29
+ * - Header ID: 2 bytes (0x5455)
30
+ * - Data size: 2 bytes
31
+ * - Flags: 1 byte (bit0 = mtime)
32
+ * - mtime: 4 bytes (Unix seconds)
33
+ */
34
+ function buildExtendedTimestampExtraFieldFromUnixSeconds(unixSeconds) {
35
+ const ts = clampUint32(unixSeconds);
36
+ // flags(1) + mtime(4)
37
+ const payloadSize = 5;
38
+ const out = new Uint8Array(4 + payloadSize);
39
+ const view = new DataView(out.buffer);
40
+ view.setUint16(0, EXTENDED_TIMESTAMP_ID, true);
41
+ view.setUint16(2, payloadSize, true);
42
+ out[4] = 0x01; // mtime present
43
+ view.setUint32(5, ts, true);
44
+ return out;
45
+ }
46
+ function buildExtendedTimestampExtraFieldFromDate(date) {
47
+ return buildExtendedTimestampExtraFieldFromUnixSeconds(unixSecondsFromDate(date));
48
+ }
49
+ /**
50
+ * Parse Info-ZIP "Extended Timestamp" extra field (0x5455) and return mtime.
51
+ * Returns Unix seconds (UTC) if present.
52
+ */
53
+ function parseExtendedTimestampMtimeUnixSeconds(extraField) {
54
+ const view = new DataView(extraField.buffer, extraField.byteOffset, extraField.byteLength);
55
+ let offset = 0;
56
+ while (offset + 4 <= extraField.length) {
57
+ const headerId = view.getUint16(offset, true);
58
+ const dataSize = view.getUint16(offset + 2, true);
59
+ const dataStart = offset + 4;
60
+ const dataEnd = dataStart + dataSize;
61
+ if (dataEnd > extraField.length) {
62
+ break;
63
+ }
64
+ if (headerId === EXTENDED_TIMESTAMP_ID && dataSize >= 1) {
65
+ const flags = extraField[dataStart];
66
+ if ((flags & 0x01) !== 0 && dataSize >= 5) {
67
+ // mtime is 4 bytes right after flags.
68
+ return view.getUint32(dataStart + 1, true) >>> 0;
69
+ }
70
+ }
71
+ offset = dataEnd;
72
+ }
73
+ return undefined;
74
+ }
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ /**
3
+ * ZIP file format builder
4
+ *
5
+ * Implements ZIP file structure according to PKWARE's APPNOTE.TXT specification
6
+ * https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
7
+ *
8
+ * ZIP file structure:
9
+ * ┌──────────────────────────┐
10
+ * │ Local File Header 1 │
11
+ * │ File Data 1 │
12
+ * ├──────────────────────────┤
13
+ * │ Local File Header 2 │
14
+ * │ File Data 2 │
15
+ * ├──────────────────────────┤
16
+ * │ ... │
17
+ * ├──────────────────────────┤
18
+ * │ Central Directory 1 │
19
+ * │ Central Directory 2 │
20
+ * │ ... │
21
+ * ├──────────────────────────┤
22
+ * │ End of Central Directory │
23
+ * └──────────────────────────┘
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.ZipBuilder = void 0;
27
+ exports.createZip = createZip;
28
+ exports.createZipSync = createZipSync;
29
+ const compress_1 = require("./compress.js");
30
+ const crc32_1 = require("./crc32.js");
31
+ const bytes_1 = require("./utils/bytes.js");
32
+ const zip_entry_metadata_1 = require("./zip-entry-metadata.js");
33
+ const defaults_1 = require("./defaults.js");
34
+ const zip_records_1 = require("./zip-records.js");
35
+ const zip_constants_1 = require("./zip-constants.js");
36
+ const LOCAL_FILE_HEADER_FIXED_SIZE = 30;
37
+ function encodeZipComment(comment) {
38
+ // Keep empty comment as empty bytes (no encoding surprises).
39
+ return comment ? new TextEncoder().encode(comment) : new Uint8Array(0);
40
+ }
41
+ function shouldDeflate(level, data) {
42
+ return level > 0 && data.length > 0;
43
+ }
44
+ function computeLocalRecordSize(entry) {
45
+ return (LOCAL_FILE_HEADER_FIXED_SIZE +
46
+ entry.name.length +
47
+ entry.extraField.length +
48
+ entry.compressedData.length);
49
+ }
50
+ function buildProcessedEntry(entry, offset, settings, compressedData) {
51
+ const modDate = entry.modTime ?? settings.defaultModTime;
52
+ const isCompressed = shouldDeflate(settings.level, entry.data);
53
+ const metadata = (0, zip_entry_metadata_1.buildZipEntryMetadata)({
54
+ name: entry.name,
55
+ comment: entry.comment,
56
+ modTime: modDate,
57
+ timestamps: settings.timestamps,
58
+ useDataDescriptor: false,
59
+ deflate: isCompressed
60
+ });
61
+ return {
62
+ name: metadata.nameBytes,
63
+ data: entry.data,
64
+ compressedData,
65
+ crc: (0, crc32_1.crc32)(entry.data),
66
+ compressionMethod: (0, zip_entry_metadata_1.resolveZipCompressionMethod)(isCompressed),
67
+ modTime: metadata.dosTime,
68
+ modDate: metadata.dosDate,
69
+ extraField: metadata.extraField,
70
+ comment: metadata.commentBytes,
71
+ offset
72
+ };
73
+ }
74
+ function appendProcessedEntry(processedEntries, entry, compressedData, currentOffset, settings) {
75
+ const processedEntry = buildProcessedEntry(entry, currentOffset, settings, compressedData);
76
+ processedEntries.push(processedEntry);
77
+ return {
78
+ processedEntry,
79
+ nextOffset: currentOffset + computeLocalRecordSize(processedEntry)
80
+ };
81
+ }
82
+ function finalizeZip(processedEntries, zipComment, centralDirOffset) {
83
+ // Build ZIP structure
84
+ const chunks = [];
85
+ // Local file headers and data
86
+ for (const entry of processedEntries) {
87
+ chunks.push(buildLocalFileHeaderChunk(entry));
88
+ chunks.push(entry.compressedData);
89
+ }
90
+ chunks.push(...buildCentralDirectorySection(processedEntries, centralDirOffset, zipComment));
91
+ return (0, bytes_1.concatUint8Arrays)(chunks);
92
+ }
93
+ function buildLocalFileHeaderChunk(entry) {
94
+ return (0, zip_records_1.buildLocalFileHeader)({
95
+ fileName: entry.name,
96
+ extraField: entry.extraField,
97
+ flags: zip_constants_1.FLAG_UTF8,
98
+ compressionMethod: entry.compressionMethod,
99
+ dosTime: entry.modTime,
100
+ dosDate: entry.modDate,
101
+ crc32: entry.crc,
102
+ compressedSize: entry.compressedData.length,
103
+ uncompressedSize: entry.data.length,
104
+ versionNeeded: zip_constants_1.VERSION_NEEDED
105
+ });
106
+ }
107
+ function buildCentralDirHeaderChunk(entry) {
108
+ return (0, zip_records_1.buildCentralDirectoryHeader)({
109
+ fileName: entry.name,
110
+ extraField: entry.extraField,
111
+ comment: entry.comment,
112
+ flags: zip_constants_1.FLAG_UTF8,
113
+ compressionMethod: entry.compressionMethod,
114
+ dosTime: entry.modTime,
115
+ dosDate: entry.modDate,
116
+ crc32: entry.crc,
117
+ compressedSize: entry.compressedData.length,
118
+ uncompressedSize: entry.data.length,
119
+ localHeaderOffset: entry.offset,
120
+ versionMadeBy: zip_constants_1.VERSION_MADE_BY,
121
+ versionNeeded: zip_constants_1.VERSION_NEEDED
122
+ });
123
+ }
124
+ function buildCentralDirectorySection(processedEntries, centralDirOffset, zipComment) {
125
+ const chunks = [];
126
+ for (const entry of processedEntries) {
127
+ chunks.push(buildCentralDirHeaderChunk(entry));
128
+ }
129
+ const centralDirSize = (0, bytes_1.sumUint8ArrayLengths)(chunks);
130
+ chunks.push((0, zip_records_1.buildEndOfCentralDirectory)({
131
+ entryCount: processedEntries.length,
132
+ centralDirSize,
133
+ centralDirOffset,
134
+ comment: zipComment
135
+ }));
136
+ return chunks;
137
+ }
138
+ /**
139
+ * Create a ZIP file from entries (async)
140
+ *
141
+ * @param entries - Files to include in ZIP
142
+ * @param options - ZIP options
143
+ * @returns ZIP file as Uint8Array
144
+ *
145
+ * @example
146
+ * ```ts
147
+ * const zip = await createZip([
148
+ * { name: "hello.txt", data: new TextEncoder().encode("Hello!") },
149
+ * { name: "folder/file.txt", data: new TextEncoder().encode("Nested!") }
150
+ * ], { level: 6 });
151
+ * ```
152
+ */
153
+ async function createZip(entries, options = {}) {
154
+ const level = options.level ?? defaults_1.DEFAULT_ZIP_LEVEL;
155
+ const timestamps = options.timestamps ?? defaults_1.DEFAULT_ZIP_TIMESTAMPS;
156
+ const zipComment = encodeZipComment(options.comment);
157
+ const defaultModTime = new Date();
158
+ const settings = {
159
+ level,
160
+ timestamps,
161
+ defaultModTime
162
+ };
163
+ const compressOptions = {
164
+ level,
165
+ thresholdBytes: options.thresholdBytes
166
+ };
167
+ const compressedDatas = await Promise.all(entries.map(async (entry) => {
168
+ return shouldDeflate(level, entry.data) ? (0, compress_1.compress)(entry.data, compressOptions) : entry.data;
169
+ }));
170
+ // Process entries
171
+ const processedEntries = [];
172
+ let currentOffset = 0;
173
+ for (let i = 0; i < entries.length; i++) {
174
+ const entry = entries[i];
175
+ const compressedData = compressedDatas[i];
176
+ const result = appendProcessedEntry(processedEntries, entry, compressedData, currentOffset, settings);
177
+ currentOffset = result.nextOffset;
178
+ }
179
+ return finalizeZip(processedEntries, zipComment, currentOffset);
180
+ }
181
+ /**
182
+ * Create a ZIP file from entries (sync)
183
+ *
184
+ * This is supported in both Node.js and browser builds.
185
+ */
186
+ function createZipSync(entries, options = {}) {
187
+ const level = options.level ?? defaults_1.DEFAULT_ZIP_LEVEL;
188
+ const timestamps = options.timestamps ?? defaults_1.DEFAULT_ZIP_TIMESTAMPS;
189
+ const zipComment = encodeZipComment(options.comment);
190
+ const defaultModTime = new Date();
191
+ const settings = {
192
+ level,
193
+ timestamps,
194
+ defaultModTime
195
+ };
196
+ const compressOptions = {
197
+ level,
198
+ thresholdBytes: options.thresholdBytes
199
+ };
200
+ // Process entries
201
+ const processedEntries = [];
202
+ let currentOffset = 0;
203
+ for (const entry of entries) {
204
+ // Compress data
205
+ const compressedData = shouldDeflate(level, entry.data)
206
+ ? (0, compress_1.compressSync)(entry.data, compressOptions)
207
+ : entry.data;
208
+ const result = appendProcessedEntry(processedEntries, entry, compressedData, currentOffset, settings);
209
+ currentOffset = result.nextOffset;
210
+ }
211
+ return finalizeZip(processedEntries, zipComment, currentOffset);
212
+ }
213
+ /**
214
+ * Streaming ZIP builder for large files
215
+ * Writes chunks to a callback as they are generated
216
+ */
217
+ class ZipBuilder {
218
+ /**
219
+ * Create a new ZIP builder
220
+ * @param options - ZIP options
221
+ */
222
+ constructor(options = {}) {
223
+ this.entries = [];
224
+ this.currentOffset = 0;
225
+ this.finalized = false;
226
+ this.level = options.level ?? defaults_1.DEFAULT_ZIP_LEVEL;
227
+ this.zipComment = encodeZipComment(options.comment);
228
+ this.timestamps = options.timestamps ?? defaults_1.DEFAULT_ZIP_TIMESTAMPS;
229
+ this.compressOptions = {
230
+ level: this.level,
231
+ thresholdBytes: options.thresholdBytes
232
+ };
233
+ this.settings = {
234
+ level: this.level,
235
+ timestamps: this.timestamps,
236
+ defaultModTime: new Date()
237
+ };
238
+ }
239
+ /**
240
+ * Add a file to the ZIP (async)
241
+ * @param entry - File entry
242
+ * @returns Local file header and compressed data chunks
243
+ */
244
+ async addFile(entry) {
245
+ if (this.finalized) {
246
+ throw new Error("Cannot add files after finalizing");
247
+ }
248
+ // Compress data
249
+ const compressedData = shouldDeflate(this.level, entry.data)
250
+ ? await (0, compress_1.compress)(entry.data, this.compressOptions)
251
+ : entry.data;
252
+ const result = appendProcessedEntry(this.entries, entry, compressedData, this.currentOffset, this.settings);
253
+ this.currentOffset = result.nextOffset;
254
+ return [buildLocalFileHeaderChunk(result.processedEntry), compressedData];
255
+ }
256
+ /**
257
+ * Add a file to the ZIP (sync)
258
+ * @param entry - File entry
259
+ * @returns Local file header and compressed data chunks
260
+ */
261
+ addFileSync(entry) {
262
+ if (this.finalized) {
263
+ throw new Error("Cannot add files after finalizing");
264
+ }
265
+ // Compress data
266
+ const compressedData = shouldDeflate(this.level, entry.data)
267
+ ? (0, compress_1.compressSync)(entry.data, this.compressOptions)
268
+ : entry.data;
269
+ const result = appendProcessedEntry(this.entries, entry, compressedData, this.currentOffset, this.settings);
270
+ this.currentOffset = result.nextOffset;
271
+ return [buildLocalFileHeaderChunk(result.processedEntry), compressedData];
272
+ }
273
+ /**
274
+ * Finalize the ZIP and return central directory + end record
275
+ * @returns Central directory and end of central directory chunks
276
+ */
277
+ finalize() {
278
+ if (this.finalized) {
279
+ throw new Error("ZIP already finalized");
280
+ }
281
+ this.finalized = true;
282
+ return buildCentralDirectorySection(this.entries, this.currentOffset, this.zipComment);
283
+ }
284
+ /**
285
+ * Get current number of entries
286
+ */
287
+ get entryCount() {
288
+ return this.entries.length;
289
+ }
290
+ /**
291
+ * Get current ZIP data size (without central directory)
292
+ */
293
+ get dataSize() {
294
+ return this.currentOffset;
295
+ }
296
+ }
297
+ exports.ZipBuilder = ZipBuilder;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * ZIP format constants (PKWARE APPNOTE)
4
+ * Shared by ZIP writer and parser implementations.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.UINT32_MAX = exports.UINT16_MAX = exports.FLAG_DATA_DESCRIPTOR = exports.FLAG_UTF8 = exports.COMPRESSION_DEFLATE = exports.COMPRESSION_STORE = exports.VERSION_MADE_BY = exports.VERSION_NEEDED = exports.ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = exports.ZIP64_END_OF_CENTRAL_DIR_SIG = exports.DATA_DESCRIPTOR_SIG = exports.END_OF_CENTRAL_DIR_SIG = exports.CENTRAL_DIR_HEADER_SIG = exports.LOCAL_FILE_HEADER_SIG = void 0;
8
+ // Signatures
9
+ exports.LOCAL_FILE_HEADER_SIG = 0x04034b50;
10
+ exports.CENTRAL_DIR_HEADER_SIG = 0x02014b50;
11
+ exports.END_OF_CENTRAL_DIR_SIG = 0x06054b50;
12
+ exports.DATA_DESCRIPTOR_SIG = 0x08074b50;
13
+ exports.ZIP64_END_OF_CENTRAL_DIR_SIG = 0x06064b50;
14
+ exports.ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50;
15
+ // Versions
16
+ exports.VERSION_NEEDED = 20; // 2.0 - supports DEFLATE
17
+ exports.VERSION_MADE_BY = 20; // 2.0
18
+ // Compression methods
19
+ exports.COMPRESSION_STORE = 0;
20
+ exports.COMPRESSION_DEFLATE = 8;
21
+ // General purpose bit flags
22
+ exports.FLAG_UTF8 = 0x0800;
23
+ exports.FLAG_DATA_DESCRIPTOR = 0x0008;
24
+ // ZIP64 / sentinel sizes
25
+ exports.UINT16_MAX = 0xffff;
26
+ exports.UINT32_MAX = 0xffffffff;
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveZipCompressionMethod = resolveZipCompressionMethod;
4
4
  exports.resolveZipFlags = resolveZipFlags;
5
5
  exports.buildZipEntryMetadata = buildZipEntryMetadata;
6
- const text_1 = require("../utils/text.js");
7
- const timestamps_1 = require("../utils/timestamps.js");
8
- const zip_records_1 = require("../zip-spec/zip-records.js");
6
+ const text_1 = require("./utils/text.js");
7
+ const timestamps_1 = require("./utils/timestamps.js");
8
+ const zip_constants_1 = require("./zip-constants.js");
9
9
  function resolveZipCompressionMethod(deflate) {
10
- return deflate ? zip_records_1.COMPRESSION_DEFLATE : zip_records_1.COMPRESSION_STORE;
10
+ return deflate ? zip_constants_1.COMPRESSION_DEFLATE : zip_constants_1.COMPRESSION_STORE;
11
11
  }
12
12
  function resolveZipFlags(useDataDescriptor) {
13
- return useDataDescriptor ? zip_records_1.FLAG_UTF8 | zip_records_1.FLAG_DATA_DESCRIPTOR : zip_records_1.FLAG_UTF8;
13
+ return useDataDescriptor ? zip_constants_1.FLAG_UTF8 | zip_constants_1.FLAG_DATA_DESCRIPTOR : zip_constants_1.FLAG_UTF8;
14
14
  }
15
15
  function buildZipEntryMetadata(input) {
16
16
  const nameBytes = (0, text_1.encodeUtf8)(input.name);