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

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 (241) hide show
  1. package/THIRD_PARTY_NOTICES.md +0 -31
  2. package/dist/browser/index.browser.d.ts +1 -0
  3. package/dist/browser/index.browser.js +12 -0
  4. package/dist/{types/modules/archive → browser/modules/archive/compression}/compress.base.d.ts +1 -0
  5. package/dist/browser/modules/archive/{compress.base.js → compression/compress.base.js} +2 -1
  6. package/dist/{types/modules/archive → browser/modules/archive/compression}/compress.browser.d.ts +10 -8
  7. package/dist/{esm/modules/archive → browser/modules/archive/compression}/compress.browser.js +18 -19
  8. package/dist/browser/modules/archive/{compress.d.ts → compression/compress.d.ts} +2 -2
  9. package/dist/browser/modules/archive/{compress.js → compression/compress.js} +1 -1
  10. package/dist/browser/modules/archive/{crc32.browser.d.ts → compression/crc32.browser.d.ts} +1 -1
  11. package/dist/browser/modules/archive/{crc32.d.ts → compression/crc32.d.ts} +1 -1
  12. package/dist/browser/modules/archive/{crc32.js → compression/crc32.js} +1 -1
  13. package/dist/browser/modules/archive/{deflate-fallback.js → compression/deflate-fallback.js} +1 -1
  14. package/dist/browser/modules/archive/{streaming-compress.browser.d.ts → compression/streaming-compress.browser.d.ts} +2 -2
  15. package/dist/browser/modules/archive/{streaming-compress.browser.js → compression/streaming-compress.browser.js} +3 -3
  16. package/dist/browser/modules/archive/{streaming-compress.d.ts → compression/streaming-compress.d.ts} +2 -2
  17. package/dist/browser/modules/archive/{streaming-compress.js → compression/streaming-compress.js} +2 -2
  18. package/dist/browser/modules/archive/defaults.d.ts +1 -0
  19. package/dist/browser/modules/archive/defaults.js +6 -3
  20. package/dist/browser/modules/archive/index.base.d.ts +4 -4
  21. package/dist/browser/modules/archive/index.base.js +3 -6
  22. package/dist/browser/modules/archive/index.browser.d.ts +3 -4
  23. package/dist/browser/modules/archive/index.browser.js +3 -7
  24. package/dist/browser/modules/archive/index.d.ts +3 -4
  25. package/dist/browser/modules/archive/index.js +3 -5
  26. package/dist/browser/modules/archive/internal/byte-queue.d.ts +33 -0
  27. package/dist/browser/modules/archive/internal/byte-queue.js +407 -0
  28. package/dist/browser/modules/archive/io/archive-sink.d.ts +9 -0
  29. package/dist/browser/modules/archive/io/archive-sink.js +77 -0
  30. package/dist/browser/modules/archive/io/archive-source.d.ts +8 -0
  31. package/dist/browser/modules/archive/io/archive-source.js +107 -0
  32. package/dist/browser/modules/archive/{extract.d.ts → unzip/extract.d.ts} +2 -2
  33. package/dist/browser/modules/archive/unzip/index.d.ts +40 -0
  34. package/dist/browser/modules/archive/unzip/index.js +164 -0
  35. package/dist/browser/modules/archive/{parse.base.d.ts → unzip/stream.base.d.ts} +58 -3
  36. package/dist/browser/modules/archive/unzip/stream.base.js +1022 -0
  37. package/dist/browser/modules/archive/{parse.browser.d.ts → unzip/stream.browser.d.ts} +1 -1
  38. package/dist/browser/modules/archive/{parse.browser.js → unzip/stream.browser.js} +376 -110
  39. package/dist/browser/modules/archive/{parse.d.ts → unzip/stream.d.ts} +2 -2
  40. package/dist/{esm/modules/archive/parse.js → browser/modules/archive/unzip/stream.js} +7 -6
  41. package/dist/{types/modules/archive → browser/modules/archive/unzip}/zip-parser.d.ts +1 -1
  42. package/dist/{esm/modules/archive → browser/modules/archive/unzip}/zip-parser.js +38 -24
  43. package/dist/browser/modules/archive/utils/async-queue.d.ts +7 -0
  44. package/dist/browser/modules/archive/utils/async-queue.js +103 -0
  45. package/dist/browser/modules/archive/utils/bytes.js +16 -16
  46. package/dist/browser/modules/archive/utils/compressibility.d.ts +10 -0
  47. package/dist/browser/modules/archive/utils/compressibility.js +57 -0
  48. package/dist/browser/modules/archive/utils/parse-buffer.js +21 -23
  49. package/dist/browser/modules/archive/utils/pattern-scanner.d.ts +21 -0
  50. package/dist/browser/modules/archive/utils/pattern-scanner.js +27 -0
  51. package/dist/browser/modules/archive/utils/timestamps.js +62 -1
  52. package/dist/browser/modules/archive/utils/zip-extra-fields.d.ts +1 -1
  53. package/dist/browser/modules/archive/utils/zip-extra-fields.js +26 -14
  54. package/dist/browser/modules/archive/zip/index.d.ts +42 -0
  55. package/dist/browser/modules/archive/zip/index.js +157 -0
  56. package/dist/browser/modules/archive/{streaming-zip.d.ts → zip/stream.d.ts} +28 -5
  57. package/dist/browser/modules/archive/{streaming-zip.js → zip/stream.js} +192 -48
  58. package/dist/browser/modules/archive/zip/zip-bytes.d.ts +73 -0
  59. package/dist/browser/modules/archive/zip/zip-bytes.js +239 -0
  60. package/dist/{esm/modules/archive → browser/modules/archive/zip}/zip-entry-metadata.js +3 -3
  61. package/dist/browser/modules/archive/{zip-records.d.ts → zip-spec/zip-records.d.ts} +20 -0
  62. package/dist/browser/modules/archive/zip-spec/zip-records.js +126 -0
  63. package/dist/browser/modules/excel/form-control.d.ts +2 -0
  64. package/dist/browser/modules/excel/form-control.js +54 -16
  65. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +1 -1
  66. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
  67. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +1 -1
  68. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +17 -3
  69. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +3 -6
  70. package/dist/browser/modules/excel/xlsx/xlsx.js +1 -1
  71. package/dist/browser/modules/stream/streams.browser.d.ts +28 -28
  72. package/dist/browser/modules/stream/streams.browser.js +850 -697
  73. package/dist/browser/modules/stream/streams.js +140 -58
  74. package/dist/cjs/modules/archive/{compress.base.js → compression/compress.base.js} +2 -1
  75. package/dist/cjs/modules/archive/{compress.browser.js → compression/compress.browser.js} +18 -19
  76. package/dist/cjs/modules/archive/{compress.js → compression/compress.js} +1 -1
  77. package/dist/cjs/modules/archive/{crc32.js → compression/crc32.js} +1 -1
  78. package/dist/cjs/modules/archive/{deflate-fallback.js → compression/deflate-fallback.js} +1 -1
  79. package/dist/cjs/modules/archive/{streaming-compress.browser.js → compression/streaming-compress.browser.js} +3 -3
  80. package/dist/cjs/modules/archive/{streaming-compress.js → compression/streaming-compress.js} +2 -2
  81. package/dist/cjs/modules/archive/defaults.js +7 -4
  82. package/dist/cjs/modules/archive/index.base.js +9 -19
  83. package/dist/cjs/modules/archive/index.browser.js +4 -10
  84. package/dist/cjs/modules/archive/index.js +4 -8
  85. package/dist/cjs/modules/archive/internal/byte-queue.js +411 -0
  86. package/dist/cjs/modules/archive/io/archive-sink.js +82 -0
  87. package/dist/cjs/modules/archive/io/archive-source.js +114 -0
  88. package/dist/cjs/modules/archive/unzip/index.js +170 -0
  89. package/dist/cjs/modules/archive/unzip/stream.base.js +1044 -0
  90. package/dist/cjs/modules/archive/{parse.browser.js → unzip/stream.browser.js} +377 -111
  91. package/dist/cjs/modules/archive/{parse.js → unzip/stream.js} +9 -8
  92. package/dist/cjs/modules/archive/{zip-parser.js → unzip/zip-parser.js} +47 -33
  93. package/dist/cjs/modules/archive/utils/async-queue.js +106 -0
  94. package/dist/cjs/modules/archive/utils/bytes.js +16 -16
  95. package/dist/cjs/modules/archive/utils/compressibility.js +60 -0
  96. package/dist/cjs/modules/archive/utils/parse-buffer.js +21 -23
  97. package/dist/cjs/modules/archive/utils/pattern-scanner.js +31 -0
  98. package/dist/cjs/modules/archive/utils/timestamps.js +64 -3
  99. package/dist/cjs/modules/archive/utils/zip-extra-fields.js +26 -14
  100. package/dist/cjs/modules/archive/zip/index.js +162 -0
  101. package/dist/cjs/modules/archive/{streaming-zip.js → zip/stream.js} +194 -50
  102. package/dist/cjs/modules/archive/zip/zip-bytes.js +242 -0
  103. package/dist/cjs/modules/archive/{zip-entry-metadata.js → zip/zip-entry-metadata.js} +5 -5
  104. package/dist/cjs/modules/archive/zip-spec/zip-records.js +136 -0
  105. package/dist/cjs/modules/excel/form-control.js +54 -16
  106. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +2 -2
  107. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +4 -4
  108. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +17 -3
  109. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +6 -9
  110. package/dist/cjs/modules/excel/xlsx/xlsx.js +2 -2
  111. package/dist/cjs/modules/stream/streams.browser.js +850 -697
  112. package/dist/cjs/modules/stream/streams.js +140 -58
  113. package/dist/esm/index.browser.js +12 -0
  114. package/dist/esm/modules/archive/{compress.base.js → compression/compress.base.js} +2 -1
  115. package/dist/{browser/modules/archive → esm/modules/archive/compression}/compress.browser.js +18 -19
  116. package/dist/esm/modules/archive/{compress.js → compression/compress.js} +1 -1
  117. package/dist/esm/modules/archive/{crc32.js → compression/crc32.js} +1 -1
  118. package/dist/esm/modules/archive/{deflate-fallback.js → compression/deflate-fallback.js} +1 -1
  119. package/dist/esm/modules/archive/{streaming-compress.browser.js → compression/streaming-compress.browser.js} +3 -3
  120. package/dist/esm/modules/archive/{streaming-compress.js → compression/streaming-compress.js} +2 -2
  121. package/dist/esm/modules/archive/defaults.js +6 -3
  122. package/dist/esm/modules/archive/index.base.js +3 -6
  123. package/dist/esm/modules/archive/index.browser.js +3 -7
  124. package/dist/esm/modules/archive/index.js +3 -5
  125. package/dist/esm/modules/archive/internal/byte-queue.js +407 -0
  126. package/dist/esm/modules/archive/io/archive-sink.js +77 -0
  127. package/dist/esm/modules/archive/io/archive-source.js +107 -0
  128. package/dist/esm/modules/archive/unzip/index.js +164 -0
  129. package/dist/esm/modules/archive/unzip/stream.base.js +1022 -0
  130. package/dist/esm/modules/archive/{parse.browser.js → unzip/stream.browser.js} +376 -110
  131. package/dist/{browser/modules/archive/parse.js → esm/modules/archive/unzip/stream.js} +7 -6
  132. package/dist/{browser/modules/archive → esm/modules/archive/unzip}/zip-parser.js +38 -24
  133. package/dist/esm/modules/archive/utils/async-queue.js +103 -0
  134. package/dist/esm/modules/archive/utils/bytes.js +16 -16
  135. package/dist/esm/modules/archive/utils/compressibility.js +57 -0
  136. package/dist/esm/modules/archive/utils/parse-buffer.js +21 -23
  137. package/dist/esm/modules/archive/utils/pattern-scanner.js +27 -0
  138. package/dist/esm/modules/archive/utils/timestamps.js +62 -1
  139. package/dist/esm/modules/archive/utils/zip-extra-fields.js +26 -14
  140. package/dist/esm/modules/archive/zip/index.js +157 -0
  141. package/dist/esm/modules/archive/{streaming-zip.js → zip/stream.js} +192 -48
  142. package/dist/esm/modules/archive/zip/zip-bytes.js +239 -0
  143. package/dist/{browser/modules/archive → esm/modules/archive/zip}/zip-entry-metadata.js +3 -3
  144. package/dist/esm/modules/archive/zip-spec/zip-records.js +126 -0
  145. package/dist/esm/modules/excel/form-control.js +54 -16
  146. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +1 -1
  147. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +1 -1
  148. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +17 -3
  149. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +3 -6
  150. package/dist/esm/modules/excel/xlsx/xlsx.js +1 -1
  151. package/dist/esm/modules/stream/streams.browser.js +850 -697
  152. package/dist/esm/modules/stream/streams.js +140 -58
  153. package/dist/iife/THIRD_PARTY_NOTICES.md +81 -0
  154. package/dist/iife/excelts.iife.js +4777 -2863
  155. package/dist/iife/excelts.iife.js.map +1 -1
  156. package/dist/iife/excelts.iife.min.js +103 -31
  157. package/dist/types/index.browser.d.ts +1 -0
  158. package/dist/{browser/modules/archive → types/modules/archive/compression}/compress.base.d.ts +1 -0
  159. package/dist/{browser/modules/archive → types/modules/archive/compression}/compress.browser.d.ts +10 -8
  160. package/dist/types/modules/archive/{streaming-compress.browser.d.ts → compression/streaming-compress.browser.d.ts} +1 -1
  161. package/dist/types/modules/archive/defaults.d.ts +1 -0
  162. package/dist/types/modules/archive/index.base.d.ts +4 -4
  163. package/dist/types/modules/archive/index.browser.d.ts +3 -4
  164. package/dist/types/modules/archive/index.d.ts +3 -4
  165. package/dist/types/modules/archive/internal/byte-queue.d.ts +33 -0
  166. package/dist/types/modules/archive/io/archive-sink.d.ts +9 -0
  167. package/dist/types/modules/archive/io/archive-source.d.ts +8 -0
  168. package/dist/types/modules/archive/unzip/index.d.ts +40 -0
  169. package/dist/types/modules/archive/{parse.base.d.ts → unzip/stream.base.d.ts} +60 -5
  170. package/dist/types/modules/archive/{parse.browser.d.ts → unzip/stream.browser.d.ts} +2 -2
  171. package/dist/types/modules/archive/{parse.d.ts → unzip/stream.d.ts} +3 -3
  172. package/dist/{browser/modules/archive → types/modules/archive/unzip}/zip-parser.d.ts +1 -1
  173. package/dist/types/modules/archive/utils/async-queue.d.ts +7 -0
  174. package/dist/types/modules/archive/utils/compressibility.d.ts +10 -0
  175. package/dist/types/modules/archive/utils/pattern-scanner.d.ts +21 -0
  176. package/dist/types/modules/archive/utils/zip-extra-fields.d.ts +1 -1
  177. package/dist/types/modules/archive/zip/index.d.ts +42 -0
  178. package/dist/types/modules/archive/{streaming-zip.d.ts → zip/stream.d.ts} +29 -6
  179. package/dist/types/modules/archive/zip/zip-bytes.d.ts +73 -0
  180. package/dist/types/modules/archive/{zip-entry-metadata.d.ts → zip/zip-entry-metadata.d.ts} +1 -1
  181. package/dist/types/modules/archive/{zip-records.d.ts → zip-spec/zip-records.d.ts} +20 -0
  182. package/dist/types/modules/excel/form-control.d.ts +2 -0
  183. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
  184. package/dist/types/modules/stream/streams.browser.d.ts +28 -28
  185. package/package.json +10 -6
  186. package/dist/browser/modules/archive/byte-queue.d.ts +0 -18
  187. package/dist/browser/modules/archive/byte-queue.js +0 -125
  188. package/dist/browser/modules/archive/parse.base.js +0 -610
  189. package/dist/browser/modules/archive/utils/zip-extra.d.ts +0 -18
  190. package/dist/browser/modules/archive/utils/zip-extra.js +0 -68
  191. package/dist/browser/modules/archive/zip-builder.d.ts +0 -117
  192. package/dist/browser/modules/archive/zip-builder.js +0 -292
  193. package/dist/browser/modules/archive/zip-constants.d.ts +0 -18
  194. package/dist/browser/modules/archive/zip-constants.js +0 -23
  195. package/dist/browser/modules/archive/zip-records.js +0 -84
  196. package/dist/cjs/modules/archive/byte-queue.js +0 -129
  197. package/dist/cjs/modules/archive/parse.base.js +0 -632
  198. package/dist/cjs/modules/archive/utils/zip-extra.js +0 -74
  199. package/dist/cjs/modules/archive/zip-builder.js +0 -297
  200. package/dist/cjs/modules/archive/zip-constants.js +0 -26
  201. package/dist/cjs/modules/archive/zip-records.js +0 -90
  202. package/dist/esm/modules/archive/byte-queue.js +0 -125
  203. package/dist/esm/modules/archive/parse.base.js +0 -610
  204. package/dist/esm/modules/archive/utils/zip-extra.js +0 -68
  205. package/dist/esm/modules/archive/zip-builder.js +0 -292
  206. package/dist/esm/modules/archive/zip-constants.js +0 -23
  207. package/dist/esm/modules/archive/zip-records.js +0 -84
  208. package/dist/types/modules/archive/byte-queue.d.ts +0 -18
  209. package/dist/types/modules/archive/utils/zip-extra.d.ts +0 -18
  210. package/dist/types/modules/archive/zip-builder.d.ts +0 -117
  211. package/dist/types/modules/archive/zip-constants.d.ts +0 -18
  212. /package/dist/browser/modules/archive/{crc32.base.d.ts → compression/crc32.base.d.ts} +0 -0
  213. /package/dist/browser/modules/archive/{crc32.base.js → compression/crc32.base.js} +0 -0
  214. /package/dist/browser/modules/archive/{crc32.browser.js → compression/crc32.browser.js} +0 -0
  215. /package/dist/browser/modules/archive/{deflate-fallback.d.ts → compression/deflate-fallback.d.ts} +0 -0
  216. /package/dist/browser/modules/archive/{streaming-compress.base.d.ts → compression/streaming-compress.base.d.ts} +0 -0
  217. /package/dist/browser/modules/archive/{streaming-compress.base.js → compression/streaming-compress.base.js} +0 -0
  218. /package/dist/browser/modules/archive/{extract.js → unzip/extract.js} +0 -0
  219. /package/dist/browser/modules/archive/{zip-entry-metadata.d.ts → zip/zip-entry-metadata.d.ts} +0 -0
  220. /package/dist/browser/modules/archive/{zip-entry-info.d.ts → zip-spec/zip-entry-info.d.ts} +0 -0
  221. /package/dist/browser/modules/archive/{zip-entry-info.js → zip-spec/zip-entry-info.js} +0 -0
  222. /package/dist/cjs/modules/archive/{crc32.base.js → compression/crc32.base.js} +0 -0
  223. /package/dist/cjs/modules/archive/{crc32.browser.js → compression/crc32.browser.js} +0 -0
  224. /package/dist/cjs/modules/archive/{streaming-compress.base.js → compression/streaming-compress.base.js} +0 -0
  225. /package/dist/cjs/modules/archive/{extract.js → unzip/extract.js} +0 -0
  226. /package/dist/cjs/modules/archive/{zip-entry-info.js → zip-spec/zip-entry-info.js} +0 -0
  227. /package/dist/esm/modules/archive/{crc32.base.js → compression/crc32.base.js} +0 -0
  228. /package/dist/esm/modules/archive/{crc32.browser.js → compression/crc32.browser.js} +0 -0
  229. /package/dist/esm/modules/archive/{streaming-compress.base.js → compression/streaming-compress.base.js} +0 -0
  230. /package/dist/esm/modules/archive/{extract.js → unzip/extract.js} +0 -0
  231. /package/dist/esm/modules/archive/{zip-entry-info.js → zip-spec/zip-entry-info.js} +0 -0
  232. /package/dist/{LICENSE → iife/LICENSE} +0 -0
  233. /package/dist/types/modules/archive/{compress.d.ts → compression/compress.d.ts} +0 -0
  234. /package/dist/types/modules/archive/{crc32.base.d.ts → compression/crc32.base.d.ts} +0 -0
  235. /package/dist/types/modules/archive/{crc32.browser.d.ts → compression/crc32.browser.d.ts} +0 -0
  236. /package/dist/types/modules/archive/{crc32.d.ts → compression/crc32.d.ts} +0 -0
  237. /package/dist/types/modules/archive/{deflate-fallback.d.ts → compression/deflate-fallback.d.ts} +0 -0
  238. /package/dist/types/modules/archive/{streaming-compress.base.d.ts → compression/streaming-compress.base.d.ts} +0 -0
  239. /package/dist/types/modules/archive/{streaming-compress.d.ts → compression/streaming-compress.d.ts} +0 -0
  240. /package/dist/types/modules/archive/{extract.d.ts → unzip/extract.d.ts} +0 -0
  241. /package/dist/types/modules/archive/{zip-entry-info.d.ts → zip-spec/zip-entry-info.d.ts} +0 -0
@@ -1,632 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PullStream = exports.parseExtraField = exports.END_OF_CENTRAL_DIRECTORY_FORMAT = exports.CENTRAL_DIRECTORY_FILE_HEADER_FORMAT = exports.DATA_DESCRIPTOR_FORMAT = exports.LOCAL_FILE_HEADER_FORMAT = exports.CRX_HEADER_FORMAT = void 0;
4
- exports.decodeZipEntryPath = decodeZipEntryPath;
5
- exports.isZipUnicodeFlag = isZipUnicodeFlag;
6
- exports.isZipDirectoryPath = isZipDirectoryPath;
7
- exports.getZipEntryType = getZipEntryType;
8
- exports.buildZipEntryProps = buildZipEntryProps;
9
- exports.resolveZipEntryLastModifiedDateTime = resolveZipEntryLastModifiedDateTime;
10
- exports.hasDataDescriptorFlag = hasDataDescriptorFlag;
11
- exports.isFileSizeKnown = isFileSizeKnown;
12
- exports.autodrain = autodrain;
13
- exports.bufferStream = bufferStream;
14
- exports.readCrxHeader = readCrxHeader;
15
- exports.readLocalFileHeader = readLocalFileHeader;
16
- exports.readDataDescriptor = readDataDescriptor;
17
- exports.consumeCentralDirectoryFileHeader = consumeCentralDirectoryFileHeader;
18
- exports.consumeEndOfCentralDirectoryRecord = consumeEndOfCentralDirectoryRecord;
19
- exports.scanValidatedDataDescriptor = scanValidatedDataDescriptor;
20
- exports.streamUntilValidatedDataDescriptor = streamUntilValidatedDataDescriptor;
21
- exports.runParseLoop = runParseLoop;
22
- const timestamps_1 = require("./utils/timestamps.js");
23
- const _stream_1 = require("../stream/index.js");
24
- const parse_buffer_1 = require("./utils/parse-buffer.js");
25
- const byte_queue_1 = require("./byte-queue.js");
26
- const bytes_1 = require("./utils/bytes.js");
27
- const binary_1 = require("./utils/binary.js");
28
- const zip_extra_fields_1 = require("./utils/zip-extra-fields.js");
29
- const zip_constants_1 = require("./zip-constants.js");
30
- // Shared parseBuffer() formats
31
- exports.CRX_HEADER_FORMAT = [
32
- ["version", 4],
33
- ["pubKeyLength", 4],
34
- ["signatureLength", 4]
35
- ];
36
- exports.LOCAL_FILE_HEADER_FORMAT = [
37
- ["versionsNeededToExtract", 2],
38
- ["flags", 2],
39
- ["compressionMethod", 2],
40
- ["lastModifiedTime", 2],
41
- ["lastModifiedDate", 2],
42
- ["crc32", 4],
43
- ["compressedSize", 4],
44
- ["uncompressedSize", 4],
45
- ["fileNameLength", 2],
46
- ["extraFieldLength", 2]
47
- ];
48
- exports.DATA_DESCRIPTOR_FORMAT = [
49
- ["dataDescriptorSignature", 4],
50
- ["crc32", 4],
51
- ["compressedSize", 4],
52
- ["uncompressedSize", 4]
53
- ];
54
- exports.CENTRAL_DIRECTORY_FILE_HEADER_FORMAT = [
55
- ["versionMadeBy", 2],
56
- ["versionsNeededToExtract", 2],
57
- ["flags", 2],
58
- ["compressionMethod", 2],
59
- ["lastModifiedTime", 2],
60
- ["lastModifiedDate", 2],
61
- ["crc32", 4],
62
- ["compressedSize", 4],
63
- ["uncompressedSize", 4],
64
- ["fileNameLength", 2],
65
- ["extraFieldLength", 2],
66
- ["fileCommentLength", 2],
67
- ["diskNumber", 2],
68
- ["internalFileAttributes", 2],
69
- ["externalFileAttributes", 4],
70
- ["offsetToLocalFileHeader", 4]
71
- ];
72
- exports.END_OF_CENTRAL_DIRECTORY_FORMAT = [
73
- ["diskNumber", 2],
74
- ["diskStart", 2],
75
- ["numberOfRecordsOnDisk", 2],
76
- ["numberOfRecords", 2],
77
- ["sizeOfCentralDirectory", 4],
78
- ["offsetToStartOfCentralDirectory", 4],
79
- ["commentLength", 2]
80
- ];
81
- const textDecoder = new TextDecoder();
82
- const textEncoder = new TextEncoder();
83
- function decodeZipEntryPath(pathBuffer) {
84
- return textDecoder.decode(pathBuffer);
85
- }
86
- function isZipUnicodeFlag(flags) {
87
- return ((flags || 0) & 0x800) !== 0;
88
- }
89
- function isZipDirectoryPath(path) {
90
- if (path.length === 0) {
91
- return false;
92
- }
93
- const last = path.charCodeAt(path.length - 1);
94
- return last === 47 || last === 92;
95
- }
96
- function getZipEntryType(path, uncompressedSize) {
97
- return uncompressedSize === 0 && isZipDirectoryPath(path) ? "Directory" : "File";
98
- }
99
- function buildZipEntryProps(path, pathBuffer, flags) {
100
- return {
101
- path,
102
- pathBuffer,
103
- flags: {
104
- isUnicode: isZipUnicodeFlag(flags)
105
- }
106
- };
107
- }
108
- function resolveZipEntryLastModifiedDateTime(vars, extraFields) {
109
- const dosDate = vars.lastModifiedDate || 0;
110
- const dosTime = vars.lastModifiedTime || 0;
111
- const dosDateTime = (0, timestamps_1.parseDosDateTimeUTC)(dosDate, dosTime);
112
- const unixSecondsMtime = extraFields.mtimeUnixSeconds;
113
- if (unixSecondsMtime === undefined) {
114
- return dosDateTime;
115
- }
116
- return (0, timestamps_1.resolveZipLastModifiedDateFromUnixSeconds)(dosDate, dosTime, unixSecondsMtime);
117
- }
118
- exports.parseExtraField = zip_extra_fields_1.parseZipExtraFields;
119
- function hasDataDescriptorFlag(flags) {
120
- return ((flags || 0) & 0x08) !== 0;
121
- }
122
- function isFileSizeKnown(flags, compressedSize) {
123
- return !hasDataDescriptorFlag(flags) || (compressedSize || 0) > 0;
124
- }
125
- function autodrain(stream) {
126
- const draining = stream.pipe(new _stream_1.Transform({
127
- transform(_chunk, _encoding, callback) {
128
- callback();
129
- }
130
- }));
131
- draining.promise = () => new Promise((resolve, reject) => {
132
- draining.on("finish", resolve);
133
- draining.on("error", reject);
134
- });
135
- return draining;
136
- }
137
- /**
138
- * Collects all data from a readable stream into a single Uint8Array.
139
- */
140
- function bufferStream(entry) {
141
- return new Promise((resolve, reject) => {
142
- const chunks = [];
143
- const stream = new _stream_1.Transform({
144
- transform(d, _encoding, callback) {
145
- chunks.push(d);
146
- callback();
147
- }
148
- });
149
- stream.on("finish", () => {
150
- resolve(chunks.length === 1 ? chunks[0] : (0, _stream_1.concatUint8Arrays)(chunks));
151
- });
152
- stream.on("error", reject);
153
- entry.on("error", reject).pipe(stream);
154
- });
155
- }
156
- const STR_FUNCTION = "function";
157
- class PullStream extends _stream_1.Duplex {
158
- get buffer() {
159
- return this._queue.view();
160
- }
161
- set buffer(value) {
162
- this._queue.reset(value);
163
- }
164
- constructor() {
165
- super({ decodeStrings: false, objectMode: true });
166
- this._queue = new byte_queue_1.ByteQueue();
167
- this.finished = false;
168
- this.on("finish", () => {
169
- this.finished = true;
170
- this.emit("chunk", false);
171
- });
172
- }
173
- _write(chunk, _encoding, callback) {
174
- const data = typeof chunk === "string" ? textEncoder.encode(chunk) : chunk;
175
- this._queue.append(data);
176
- this.cb = callback;
177
- this.emit("chunk");
178
- }
179
- _read() { }
180
- _maybeReleaseWriteCallback() {
181
- if (typeof this.cb === STR_FUNCTION) {
182
- const callback = this.cb;
183
- this.cb = undefined;
184
- callback();
185
- }
186
- }
187
- /**
188
- * The `eof` parameter is interpreted as `file_length` if the type is number
189
- * otherwise (i.e. Uint8Array) it is interpreted as a pattern signaling end of stream
190
- */
191
- stream(eof, includeEof) {
192
- const p = new _stream_1.PassThrough();
193
- let done = false;
194
- const cb = () => {
195
- this._maybeReleaseWriteCallback();
196
- };
197
- const pull = () => {
198
- let packet;
199
- const available = this._queue.length;
200
- if (available) {
201
- if (typeof eof === "number") {
202
- const toRead = Math.min(eof, available);
203
- if (toRead > 0) {
204
- packet = this._queue.read(toRead);
205
- eof -= toRead;
206
- }
207
- done = done || eof === 0;
208
- }
209
- else {
210
- const view = this._queue.view();
211
- let match = (0, bytes_1.indexOfUint8ArrayPattern)(view, eof);
212
- if (match !== -1) {
213
- // store signature match byte offset to allow us to reference
214
- // this for zip64 offset
215
- this.match = match;
216
- if (includeEof) {
217
- match = match + eof.length;
218
- }
219
- if (match > 0) {
220
- packet = this._queue.read(match);
221
- }
222
- done = true;
223
- }
224
- else {
225
- const len = view.length - eof.length;
226
- if (len <= 0) {
227
- cb();
228
- }
229
- else {
230
- packet = this._queue.read(len);
231
- }
232
- }
233
- }
234
- if (packet) {
235
- p.write(packet, () => {
236
- if (this._queue.length === 0 ||
237
- (typeof eof !== "number" && eof.length && this._queue.length <= eof.length)) {
238
- cb();
239
- }
240
- if (done) {
241
- cb();
242
- this.removeListener("chunk", pull);
243
- p.end();
244
- return;
245
- }
246
- // Continue draining regardless of downstream read timing.
247
- queueMicrotask(pull);
248
- });
249
- return;
250
- }
251
- }
252
- if (!done) {
253
- if (this.finished) {
254
- this.removeListener("chunk", pull);
255
- cb();
256
- p.destroy(new Error("FILE_ENDED"));
257
- return;
258
- }
259
- }
260
- else {
261
- this.removeListener("chunk", pull);
262
- cb();
263
- p.end();
264
- }
265
- };
266
- this.on("chunk", pull);
267
- pull();
268
- return p;
269
- }
270
- pull(eof, includeEof) {
271
- if (eof === 0) {
272
- return Promise.resolve(new Uint8Array(0));
273
- }
274
- // If we already have the required data in buffer
275
- // we can resolve the request immediately
276
- if (typeof eof === "number" && this._queue.length >= eof) {
277
- const data = this._queue.read(eof);
278
- // If we drained the internal buffer, allow the upstream writer to continue.
279
- if (this._queue.length === 0) {
280
- this._maybeReleaseWriteCallback();
281
- }
282
- return Promise.resolve(data);
283
- }
284
- // Otherwise we stream until we have it
285
- const chunks = [];
286
- const concatStream = new _stream_1.Transform({
287
- transform(d, _encoding, cb) {
288
- chunks.push(d);
289
- cb();
290
- }
291
- });
292
- let pullStreamRejectHandler;
293
- return new Promise((resolve, reject) => {
294
- pullStreamRejectHandler = (e) => {
295
- this.__emittedError = e;
296
- reject(e);
297
- };
298
- if (this.finished) {
299
- return reject(new Error("FILE_ENDED"));
300
- }
301
- this.once("error", pullStreamRejectHandler); // reject any errors from pullstream itself
302
- this.stream(eof, includeEof)
303
- .on("error", reject)
304
- .pipe(concatStream)
305
- .on("finish", () => {
306
- resolve(chunks.length === 1 ? chunks[0] : (0, _stream_1.concatUint8Arrays)(chunks));
307
- })
308
- .on("error", reject);
309
- }).finally(() => {
310
- this.removeListener("error", pullStreamRejectHandler);
311
- });
312
- }
313
- pullUntil(pattern, includeEof) {
314
- return this.pull(pattern, includeEof);
315
- }
316
- }
317
- exports.PullStream = PullStream;
318
- async function readCrxHeader(pull) {
319
- const data = await pull(12);
320
- const header = (0, parse_buffer_1.parseTyped)(data, exports.CRX_HEADER_FORMAT);
321
- const pubKeyLength = header.pubKeyLength || 0;
322
- const signatureLength = header.signatureLength || 0;
323
- const keyAndSig = await pull(pubKeyLength + signatureLength);
324
- header.publicKey = keyAndSig.subarray(0, pubKeyLength);
325
- header.signature = keyAndSig.subarray(pubKeyLength);
326
- return header;
327
- }
328
- async function readLocalFileHeader(pull) {
329
- const data = await pull(26);
330
- const vars = (0, parse_buffer_1.parseTyped)(data, exports.LOCAL_FILE_HEADER_FORMAT);
331
- const fileNameBuffer = await pull(vars.fileNameLength || 0);
332
- const extraFieldData = await pull(vars.extraFieldLength || 0);
333
- return { vars, fileNameBuffer, extraFieldData };
334
- }
335
- async function readDataDescriptor(pull) {
336
- const data = await pull(16);
337
- return (0, parse_buffer_1.parseTyped)(data, exports.DATA_DESCRIPTOR_FORMAT);
338
- }
339
- async function consumeCentralDirectoryFileHeader(pull) {
340
- const data = await pull(42);
341
- const vars = (0, parse_buffer_1.parseTyped)(data, exports.CENTRAL_DIRECTORY_FILE_HEADER_FORMAT);
342
- await pull(vars.fileNameLength || 0);
343
- await pull(vars.extraFieldLength || 0);
344
- await pull(vars.fileCommentLength || 0);
345
- }
346
- async function consumeEndOfCentralDirectoryRecord(pull) {
347
- const data = await pull(18);
348
- const vars = (0, parse_buffer_1.parseTyped)(data, exports.END_OF_CENTRAL_DIRECTORY_FORMAT);
349
- await pull(vars.commentLength || 0);
350
- }
351
- // =============================================================================
352
- // Validated Data Descriptor Scan (shared by Node + Browser)
353
- // =============================================================================
354
- function isValidZipRecordSignature(sig) {
355
- switch (sig) {
356
- case zip_constants_1.LOCAL_FILE_HEADER_SIG:
357
- case zip_constants_1.CENTRAL_DIR_HEADER_SIG:
358
- case zip_constants_1.END_OF_CENTRAL_DIR_SIG:
359
- case zip_constants_1.ZIP64_END_OF_CENTRAL_DIR_SIG:
360
- case zip_constants_1.ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG:
361
- return true;
362
- default:
363
- return false;
364
- }
365
- }
366
- function readUint32LEFromBytes(view, offset) {
367
- return ((view[offset] |
368
- 0 |
369
- ((view[offset + 1] | 0) << 8) |
370
- ((view[offset + 2] | 0) << 16) |
371
- ((view[offset + 3] | 0) << 24)) >>>
372
- 0);
373
- }
374
- function indexOf4BytesPattern(buffer, pattern, startIndex) {
375
- if (pattern.length !== 4) {
376
- return (0, bytes_1.indexOfUint8ArrayPattern)(buffer, pattern, startIndex);
377
- }
378
- const b0 = pattern[0];
379
- const b1 = pattern[1];
380
- const b2 = pattern[2];
381
- const b3 = pattern[3];
382
- const bufLen = buffer.length;
383
- let start = startIndex | 0;
384
- if (start < 0) {
385
- start = 0;
386
- }
387
- if (start > bufLen - 4) {
388
- return -1;
389
- }
390
- for (let i = start; i <= bufLen - 4; i++) {
391
- if (buffer[i] === b0 && buffer[i + 1] === b1 && buffer[i + 2] === b2 && buffer[i + 3] === b3) {
392
- return i;
393
- }
394
- }
395
- return -1;
396
- }
397
- function initScanResult(out) {
398
- if (out) {
399
- return out;
400
- }
401
- return { foundIndex: -1, nextSearchFrom: 0 };
402
- }
403
- /**
404
- * Scan for a validated DATA_DESCRIPTOR record boundary.
405
- *
406
- * Scanning for the 4-byte signature alone is unsafe because it can appear inside
407
- * compressed data. We validate a candidate by requiring:
408
- * - the next 4 bytes after the 16-byte descriptor form a known ZIP record signature, and
409
- * - the descriptor's compressedSize matches the number of compressed bytes emitted so far.
410
- */
411
- function scanValidatedDataDescriptor(view, dataDescriptorSignature, bytesEmitted, startIndex = 0, out) {
412
- const result = initScanResult(out);
413
- let searchFrom = startIndex | 0;
414
- if (searchFrom < 0) {
415
- searchFrom = 0;
416
- }
417
- if (searchFrom > view.length) {
418
- searchFrom = view.length;
419
- }
420
- // To avoid missing a signature split across chunk boundaries, we may need
421
- // to re-check the last (sigLen - 1) bytes on the next scan.
422
- const sigLen = dataDescriptorSignature.length | 0;
423
- const overlap = sigLen > 0 ? sigLen - 1 : 0;
424
- while (searchFrom < view.length) {
425
- const match = indexOf4BytesPattern(view, dataDescriptorSignature, searchFrom);
426
- if (match === -1) {
427
- result.foundIndex = -1;
428
- result.nextSearchFrom = Math.max(searchFrom, Math.max(0, view.length - overlap));
429
- return result;
430
- }
431
- const idx = match;
432
- // Need 16 bytes for descriptor + 4 bytes for next record signature.
433
- const nextSigOffset = idx + 16;
434
- if (nextSigOffset + 4 <= view.length) {
435
- const nextSig = readUint32LEFromBytes(view, nextSigOffset);
436
- const descriptorCompressedSize = readUint32LEFromBytes(view, idx + 8);
437
- const expectedCompressedSize = (bytesEmitted + idx) >>> 0;
438
- if (isValidZipRecordSignature(nextSig) &&
439
- descriptorCompressedSize === expectedCompressedSize) {
440
- result.foundIndex = idx;
441
- result.nextSearchFrom = idx;
442
- return result;
443
- }
444
- searchFrom = idx + 1;
445
- continue;
446
- }
447
- // Not enough bytes to validate yet. Re-check this candidate once more bytes arrive.
448
- result.foundIndex = -1;
449
- result.nextSearchFrom = idx;
450
- return result;
451
- }
452
- result.foundIndex = -1;
453
- result.nextSearchFrom = Math.max(searchFrom, Math.max(0, view.length - overlap));
454
- return result;
455
- }
456
- /**
457
- * Stream compressed file data until we reach a validated DATA_DESCRIPTOR boundary.
458
- *
459
- * This encapsulates the shared logic used by both Node and browser parsers.
460
- */
461
- function streamUntilValidatedDataDescriptor(options) {
462
- const { source, dataDescriptorSignature } = options;
463
- const keepTailBytes = options.keepTailBytes ?? 20;
464
- const errorMessage = options.errorMessage ?? "FILE_ENDED: Data descriptor not found";
465
- const output = new _stream_1.PassThrough();
466
- let done = false;
467
- // Total number of compressed bytes already emitted for this entry.
468
- let bytesEmitted = 0;
469
- let searchFrom = 0;
470
- const scanResult = { foundIndex: -1, nextSearchFrom: 0 };
471
- let unsubscribe;
472
- const cleanup = () => {
473
- if (unsubscribe) {
474
- unsubscribe();
475
- unsubscribe = undefined;
476
- }
477
- };
478
- const pull = () => {
479
- if (done) {
480
- return;
481
- }
482
- while (source.getLength() > 0) {
483
- const view = source.getView();
484
- scanValidatedDataDescriptor(view, dataDescriptorSignature, bytesEmitted, searchFrom, scanResult);
485
- const foundIndex = scanResult.foundIndex;
486
- searchFrom = scanResult.nextSearchFrom;
487
- if (foundIndex !== -1) {
488
- if (foundIndex > 0) {
489
- output.write(source.read(foundIndex));
490
- bytesEmitted += foundIndex;
491
- searchFrom = Math.max(0, searchFrom - foundIndex);
492
- }
493
- done = true;
494
- source.maybeReleaseWriteCallback?.();
495
- cleanup();
496
- output.end();
497
- return;
498
- }
499
- // Flush most of the buffered data but keep a tail so a potential signature
500
- // split across chunks can still be detected/validated.
501
- const flushLen = Math.max(0, view.length - keepTailBytes);
502
- if (flushLen > 0) {
503
- output.write(source.read(flushLen));
504
- bytesEmitted += flushLen;
505
- searchFrom = Math.max(0, searchFrom - flushLen);
506
- if (source.getLength() <= keepTailBytes) {
507
- source.maybeReleaseWriteCallback?.();
508
- }
509
- return;
510
- }
511
- // Need more data.
512
- break;
513
- }
514
- if (!done && source.isFinished()) {
515
- done = true;
516
- cleanup();
517
- output.destroy(new Error(errorMessage));
518
- }
519
- };
520
- unsubscribe = source.onDataAvailable(pull);
521
- queueMicrotask(pull);
522
- return output;
523
- }
524
- const endDirectorySignature = (0, binary_1.writeUint32LE)(zip_constants_1.END_OF_CENTRAL_DIR_SIG);
525
- async function runParseLoop(opts, io, emitter, inflateFactory, state) {
526
- while (true) {
527
- const sigBytes = await io.pull(4);
528
- if (sigBytes.length === 0) {
529
- emitter.emitClose();
530
- return;
531
- }
532
- const signature = (0, binary_1.readUint32LE)(sigBytes, 0);
533
- if (signature === 0x34327243) {
534
- state.crxHeader = await readCrxHeader(async (length) => io.pull(length));
535
- emitter.emitCrxHeader(state.crxHeader);
536
- continue;
537
- }
538
- if (signature === zip_constants_1.LOCAL_FILE_HEADER_SIG) {
539
- await readFileRecord(opts, io, emitter, inflateFactory, state);
540
- continue;
541
- }
542
- if (signature === zip_constants_1.CENTRAL_DIR_HEADER_SIG) {
543
- state.reachedCD = true;
544
- await consumeCentralDirectoryFileHeader(async (length) => io.pull(length));
545
- continue;
546
- }
547
- if (signature === zip_constants_1.END_OF_CENTRAL_DIR_SIG) {
548
- await consumeEndOfCentralDirectoryRecord(async (length) => io.pull(length));
549
- io.setDone();
550
- emitter.emitClose();
551
- return;
552
- }
553
- if (state.reachedCD) {
554
- // We are in central directory trailing data; resync by scanning for EOCD signature.
555
- // consumeEndOfCentralDirectoryRecord expects the EOCD signature to be consumed, so includeEof=true.
556
- const includeEof = true;
557
- await io.pullUntil(endDirectorySignature, includeEof);
558
- await consumeEndOfCentralDirectoryRecord(async (length) => io.pull(length));
559
- io.setDone();
560
- emitter.emitClose();
561
- return;
562
- }
563
- emitter.emitError(new Error("invalid signature: 0x" + signature.toString(16)));
564
- emitter.emitClose();
565
- return;
566
- }
567
- }
568
- async function readFileRecord(opts, io, emitter, inflateFactory, state) {
569
- const { vars: headerVars, fileNameBuffer, extraFieldData } = await readLocalFileHeader(async (l) => io.pull(l));
570
- const vars = headerVars;
571
- if (state.crxHeader) {
572
- vars.crxHeader = state.crxHeader;
573
- }
574
- const fileName = decodeZipEntryPath(fileNameBuffer);
575
- const entry = new _stream_1.PassThrough();
576
- let autodraining = false;
577
- entry.autodrain = function () {
578
- autodraining = true;
579
- entry.__autodraining = true;
580
- return autodrain(entry);
581
- };
582
- entry.buffer = function () {
583
- return bufferStream(entry);
584
- };
585
- entry.path = fileName;
586
- entry.props = buildZipEntryProps(fileName, fileNameBuffer, vars.flags);
587
- entry.type = getZipEntryType(fileName, vars.uncompressedSize || 0);
588
- if (opts.verbose) {
589
- if (entry.type === "Directory") {
590
- console.log(" creating:", fileName);
591
- }
592
- else if (entry.type === "File") {
593
- if (vars.compressionMethod === 0) {
594
- console.log(" extracting:", fileName);
595
- }
596
- else {
597
- console.log(" inflating:", fileName);
598
- }
599
- }
600
- }
601
- const extra = (0, exports.parseExtraField)(extraFieldData, vars);
602
- vars.lastModifiedDateTime = resolveZipEntryLastModifiedDateTime(vars, extra);
603
- entry.vars = vars;
604
- entry.extraFields = extra;
605
- entry.__autodraining = autodraining;
606
- const fileSizeKnown = isFileSizeKnown(vars.flags, vars.compressedSize);
607
- if (fileSizeKnown) {
608
- entry.size = vars.uncompressedSize || 0;
609
- }
610
- if (opts.forceStream) {
611
- emitter.pushEntry(entry);
612
- }
613
- else {
614
- emitter.emitEntry(entry);
615
- emitter.pushEntryIfPiped(entry);
616
- }
617
- if (opts.verbose) {
618
- console.log({
619
- filename: fileName,
620
- vars: vars,
621
- extraFields: entry.extraFields
622
- });
623
- }
624
- const inflater = vars.compressionMethod && !autodraining ? inflateFactory() : new _stream_1.PassThrough();
625
- if (fileSizeKnown) {
626
- await (0, _stream_1.pipeline)(io.stream(vars.compressedSize || 0), inflater, entry);
627
- return;
628
- }
629
- await (0, _stream_1.pipeline)(io.streamUntilDataDescriptor(), inflater, entry);
630
- const dd = await readDataDescriptor(async (l) => io.pull(l));
631
- entry.size = dd.uncompressedSize || 0;
632
- }
@@ -1,74 +0,0 @@
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
- }