@futpib/parser 1.0.0 → 1.0.2

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 (380) hide show
  1. package/build/allSettledStream.js +32 -14
  2. package/build/allSettledStream.test.js +32 -0
  3. package/build/androidPackage.d.ts +39 -0
  4. package/build/androidPackageParser.d.ts +17 -0
  5. package/build/androidPackageParser.js +183 -0
  6. package/build/{apkParser.test.js → androidPackageParser.test.js} +7 -7
  7. package/build/androidPackageUnparser.d.ts +4 -0
  8. package/build/androidPackageUnparser.js +90 -0
  9. package/build/androidPackageUnparser.test.js +26 -0
  10. package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
  11. package/build/arbitrarilySlicedAsyncInterable.js +3 -3
  12. package/build/arbitraryFileSystemEntry.js +1 -1
  13. package/build/arbitraryZip.d.ts +1 -1
  14. package/build/arbitraryZip.js +13 -19
  15. package/build/arbitraryZipPermissions.d.ts +1 -8
  16. package/build/arbitraryZipPermissions.js +1 -16
  17. package/build/arbitraryZipStream.d.ts +1 -1
  18. package/build/arbitraryZipStream.js +3 -3
  19. package/build/arrayParser.d.ts +1 -1
  20. package/build/arrayParser.js +2 -2
  21. package/build/arrayParser.test.js +4 -4
  22. package/build/arrayUnparser.d.ts +2 -0
  23. package/build/arrayUnparser.js +8 -0
  24. package/build/backsmali.d.ts +1 -0
  25. package/build/backsmali.js +22 -0
  26. package/build/bsonParser.js +6 -2
  27. package/build/bsonParser.test.js +2 -2
  28. package/build/{parserInvariant.d.ts → customInvariant.d.ts} +1 -1
  29. package/build/{parserInvariant.js → customInvariant.js} +1 -1
  30. package/build/dalvikBytecodeParser/formatParsers.d.ts +97 -0
  31. package/build/dalvikBytecodeParser/formatParsers.js +169 -0
  32. package/build/dalvikBytecodeParser.d.ts +107 -0
  33. package/build/dalvikBytecodeParser.js +836 -0
  34. package/build/dalvikExecutable.d.ts +158 -0
  35. package/build/dalvikExecutable.js +20 -0
  36. package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
  37. package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
  38. package/build/dalvikExecutableParser/typeParsers.d.ts +10 -0
  39. package/build/dalvikExecutableParser/typeParsers.js +34 -0
  40. package/build/dalvikExecutableParser/typedNumbers.d.ts +90 -0
  41. package/build/dalvikExecutableParser/typedNumbers.js +19 -0
  42. package/build/dalvikExecutableParser.d.ts +5 -0
  43. package/build/dalvikExecutableParser.js +1439 -0
  44. package/build/dalvikExecutableParser.test.js +70 -0
  45. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +298 -0
  46. package/build/debugLogInputParser.d.ts +4 -0
  47. package/build/debugLogInputParser.js +16 -0
  48. package/build/debugLogParser.d.ts +1 -1
  49. package/build/debugLogParser.js +15 -4
  50. package/build/disjunctionParser.d.ts +2 -1
  51. package/build/disjunctionParser.js +4 -2
  52. package/build/elementParser.d.ts +2 -2
  53. package/build/elementParser.js +1 -1
  54. package/build/elementTerminatedArrayParser.d.ts +3 -0
  55. package/build/elementTerminatedArrayParser.js +18 -0
  56. package/build/elementTerminatedArrayParser.test.js +52 -0
  57. package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
  58. package/build/elementTerminatedSequenceArrayParser.js +32 -0
  59. package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
  60. package/build/elementTerminatedSequenceParser.d.ts +3 -0
  61. package/build/elementTerminatedSequenceParser.js +27 -0
  62. package/build/elementTerminatedSequenceParser.test.js +34 -0
  63. package/build/endOfInputParser.d.ts +2 -2
  64. package/build/exactElementParser.d.ts +1 -1
  65. package/build/exactElementParser.js +10 -5
  66. package/build/exactSequenceParser.d.ts +2 -1
  67. package/build/exactSequenceParser.js +12 -2
  68. package/build/fetchCid.d.ts +1 -0
  69. package/build/fetchCid.js +107 -0
  70. package/build/fixedLengthSequenceParser.d.ts +1 -0
  71. package/build/fixedLengthSequenceParser.js +18 -1
  72. package/build/fixedLengthSequenceParser.test.js +41 -0
  73. package/build/hasExecutable.d.ts +1 -0
  74. package/build/hasExecutable.js +8 -0
  75. package/build/highResolutionTimer.d.ts +16 -0
  76. package/build/highResolutionTimer.js +42 -0
  77. package/build/index.d.ts +5 -2
  78. package/build/index.js +3 -0
  79. package/build/inputReader.d.ts +14 -3
  80. package/build/inputReader.js +43 -6
  81. package/build/inputReader.test.js +172 -7
  82. package/build/inputReaderState.d.ts +10 -0
  83. package/build/inputReaderState.js +16 -0
  84. package/build/inspect.d.ts +1 -0
  85. package/build/inspect.js +7 -0
  86. package/build/javaKeyStoreParser.d.ts +2 -0
  87. package/build/javaKeyStoreParser.js +67 -0
  88. package/build/javaKeyStoreParser.test.d.ts +1 -0
  89. package/build/javaKeyStoreParser.test.js +16 -0
  90. package/build/jsonParser.d.ts +2 -0
  91. package/build/jsonParser.js +13 -15
  92. package/build/jsonParser.test.js +2 -2
  93. package/build/leb128Parser.d.ts +7 -0
  94. package/build/leb128Parser.js +82 -0
  95. package/build/leb128Parser.test.d.ts +1 -0
  96. package/build/leb128Parser.test.js +107 -0
  97. package/build/listParser.d.ts +1 -1
  98. package/build/listParser.js +5 -5
  99. package/build/lookaheadParser.d.ts +2 -0
  100. package/build/lookaheadParser.js +14 -0
  101. package/build/{negativeLookahead.d.ts → negativeLookaheadParser.d.ts} +1 -1
  102. package/build/negativeLookaheadParser.js +24 -0
  103. package/build/negativeLookaheadParser.test.d.ts +1 -0
  104. package/build/negativeLookaheadParser.test.js +30 -0
  105. package/build/nonEmptyArrayParser.d.ts +2 -0
  106. package/build/nonEmptyArrayParser.js +32 -0
  107. package/build/nonEmptyArrayParser.test.d.ts +1 -0
  108. package/build/nonEmptyArrayParser.test.js +16 -0
  109. package/build/optionalParser.d.ts +1 -1
  110. package/build/optionalParser.js +2 -2
  111. package/build/parser.d.ts +13 -4
  112. package/build/parser.js +67 -32
  113. package/build/parser.test.js +94 -27
  114. package/build/parserAccessorParser.d.ts +1 -1
  115. package/build/parserAccessorParser.js +9 -1
  116. package/build/parserConsumedSequenceParser.d.ts +2 -0
  117. package/build/parserConsumedSequenceParser.js +22 -0
  118. package/build/parserContext.d.ts +20 -6
  119. package/build/parserContext.js +70 -40
  120. package/build/parserContext.test.js +34 -7
  121. package/build/parserCreatorCompose.d.ts +4 -3
  122. package/build/parserCreatorCompose.js +9 -3
  123. package/build/parserError.d.ts +6 -0
  124. package/build/parserError.js +6 -6
  125. package/build/parserImplementationInvariant.d.ts +1 -1
  126. package/build/parserImplementationInvariant.js +2 -2
  127. package/build/parserInputCompanion.d.ts +35 -0
  128. package/build/parserInputCompanion.js +68 -0
  129. package/build/promiseCompose.d.ts +1 -1
  130. package/build/promiseCompose.js +12 -1
  131. package/build/promiseSettled.d.ts +1 -0
  132. package/build/promiseSettled.js +4 -0
  133. package/build/quantifierParser.d.ts +2 -0
  134. package/build/quantifierParser.js +17 -0
  135. package/build/separatedArrayParser.d.ts +2 -0
  136. package/build/separatedArrayParser.js +39 -0
  137. package/build/separatedArrayParser.test.d.ts +1 -0
  138. package/build/separatedArrayParser.test.js +21 -0
  139. package/build/sequenceBuffer.d.ts +13 -3
  140. package/build/sequenceBuffer.js +60 -8
  141. package/build/sequenceBuffer.test.js +59 -2
  142. package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
  143. package/build/sequenceTerminatedSequenceParser.js +32 -0
  144. package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
  145. package/build/sequenceTerminatedSequenceParser.test.js +37 -0
  146. package/build/sequenceUnparser.d.ts +2 -0
  147. package/build/sequenceUnparser.js +6 -0
  148. package/build/skipParser.d.ts +1 -1
  149. package/build/skipParser.js +4 -2
  150. package/build/skipToParser.d.ts +2 -0
  151. package/build/skipToParser.js +11 -0
  152. package/build/sliceBoundedParser.d.ts +2 -2
  153. package/build/sliceBoundedParser.js +8 -3
  154. package/build/sliceBoundedParser.test.js +37 -3
  155. package/build/smali.d.ts +1 -0
  156. package/build/smali.js +17 -0
  157. package/build/smaliParser.d.ts +12 -0
  158. package/build/smaliParser.js +656 -0
  159. package/build/smaliParser.test.d.ts +1 -0
  160. package/build/smaliParser.test.js +115 -0
  161. package/build/terminatedArrayParser.d.ts +4 -2
  162. package/build/terminatedArrayParser.js +82 -5
  163. package/build/terminatedArrayParser.test.d.ts +1 -0
  164. package/build/terminatedArrayParser.test.js +131 -0
  165. package/build/toAsyncIterable.d.ts +1 -0
  166. package/build/toAsyncIterable.js +7 -0
  167. package/build/toAsyncIterator.d.ts +1 -0
  168. package/build/toAsyncIterator.js +33 -0
  169. package/build/tupleParser.d.ts +4 -0
  170. package/build/tupleParser.js +1 -5
  171. package/build/uint8Array.d.ts +1 -0
  172. package/build/uint8Array.js +7 -0
  173. package/build/unionParser.d.ts +2 -1
  174. package/build/unionParser.js +27 -12
  175. package/build/unionParser.test.d.ts +1 -0
  176. package/build/unionParser.test.js +60 -0
  177. package/build/unparser.d.ts +8 -0
  178. package/build/unparser.js +104 -0
  179. package/build/unparser.test.d.ts +1 -0
  180. package/build/unparser.test.js +150 -0
  181. package/build/unparserContext.d.ts +31 -0
  182. package/build/unparserContext.js +74 -0
  183. package/build/unparserError.d.ts +9 -0
  184. package/build/unparserError.js +9 -0
  185. package/build/unparserImplementationInvariant.d.ts +2 -0
  186. package/build/unparserImplementationInvariant.js +5 -0
  187. package/build/unparserOutputCompanion.d.ts +15 -0
  188. package/build/unparserOutputCompanion.js +13 -0
  189. package/build/zip.d.ts +9 -17
  190. package/build/zipParser.d.ts +20 -12
  191. package/build/zipParser.js +83 -71
  192. package/build/zipParser.test.js +2 -7
  193. package/build/zipUnparser.d.ts +8 -0
  194. package/build/zipUnparser.js +200 -0
  195. package/build/zipUnparser.test.d.ts +1 -0
  196. package/build/zipUnparser.test.js +80 -0
  197. package/package.json +26 -8
  198. package/src/allSettledStream.test.ts +40 -0
  199. package/src/allSettledStream.ts +47 -15
  200. package/src/androidPackage.ts +48 -0
  201. package/src/{apkParser.test.ts → androidPackageParser.test.ts} +7 -8
  202. package/src/androidPackageParser.test.ts.md +271 -0
  203. package/src/androidPackageParser.test.ts.snap +0 -0
  204. package/src/androidPackageParser.ts +440 -0
  205. package/src/androidPackageUnparser.test.ts +36 -0
  206. package/src/androidPackageUnparser.ts +120 -0
  207. package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
  208. package/src/arbitraryFileSystemEntry.ts +2 -4
  209. package/src/arbitraryZip.ts +20 -27
  210. package/src/arbitraryZipPermissions.ts +0 -25
  211. package/src/arbitraryZipStream.ts +4 -4
  212. package/src/arrayParser.test.ts +4 -4
  213. package/src/arrayParser.ts +3 -2
  214. package/src/arrayUnparser.ts +13 -0
  215. package/src/backsmali.ts +30 -0
  216. package/src/bsonParser.test.ts +2 -2
  217. package/src/bsonParser.ts +16 -5
  218. package/src/{parserInvariant.ts → customInvariant.ts} +2 -2
  219. package/src/dalvikBytecodeParser/formatParsers.ts +421 -0
  220. package/src/dalvikBytecodeParser.ts +2074 -0
  221. package/src/dalvikExecutable.ts +220 -0
  222. package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
  223. package/src/dalvikExecutableParser/typeParsers.ts +65 -0
  224. package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
  225. package/src/dalvikExecutableParser.test.ts +89 -0
  226. package/src/dalvikExecutableParser.test.ts.md +634 -0
  227. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  228. package/src/dalvikExecutableParser.ts +2768 -0
  229. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +346 -0
  230. package/src/debugLogInputParser.ts +28 -0
  231. package/src/debugLogParser.ts +20 -4
  232. package/src/disjunctionParser.ts +10 -5
  233. package/src/elementParser.ts +3 -3
  234. package/src/elementTerminatedArrayParser.test.ts +99 -0
  235. package/src/elementTerminatedArrayParser.ts +31 -0
  236. package/src/elementTerminatedSequenceArrayParser.test.ts +54 -0
  237. package/src/elementTerminatedSequenceArrayParser.ts +52 -0
  238. package/src/elementTerminatedSequenceParser.test.ts +54 -0
  239. package/src/elementTerminatedSequenceParser.ts +43 -0
  240. package/src/endOfInputParser.ts +4 -4
  241. package/src/exactElementParser.ts +18 -12
  242. package/src/exactSequenceParser.ts +24 -3
  243. package/src/fetchCid.ts +125 -0
  244. package/src/fixedLengthSequenceParser.test.ts +77 -0
  245. package/src/fixedLengthSequenceParser.ts +28 -1
  246. package/src/hasExecutable.ts +11 -0
  247. package/src/highResolutionTimer.ts +49 -0
  248. package/src/index.ts +15 -2
  249. package/src/inputReader.test.ts +216 -7
  250. package/src/inputReader.ts +80 -5
  251. package/src/inputReaderState.ts +33 -0
  252. package/src/inspect.ts +9 -0
  253. package/src/javaKeyStore.ts +0 -0
  254. package/src/javaKeyStoreParser.test.ts +22 -0
  255. package/src/javaKeyStoreParser.test.ts.md +103 -0
  256. package/src/javaKeyStoreParser.test.ts.snap +0 -0
  257. package/src/javaKeyStoreParser.ts +136 -0
  258. package/src/jsonParser.test.ts +2 -2
  259. package/src/jsonParser.ts +23 -34
  260. package/src/leb128Parser.test.ts +171 -0
  261. package/src/leb128Parser.ts +125 -0
  262. package/src/listParser.ts +6 -6
  263. package/src/lookaheadParser.ts +19 -0
  264. package/src/negativeLookaheadParser.test.ts +53 -0
  265. package/src/negativeLookaheadParser.ts +36 -0
  266. package/src/nonEmptyArrayParser.test.ts +20 -0
  267. package/src/nonEmptyArrayParser.ts +44 -0
  268. package/src/optionalParser.ts +4 -3
  269. package/src/parser.test.ts +148 -27
  270. package/src/parser.test.ts.md +21 -21
  271. package/src/parser.test.ts.snap +0 -0
  272. package/src/parser.ts +153 -49
  273. package/src/parserAccessorParser.ts +12 -2
  274. package/src/parserConsumedSequenceParser.ts +29 -0
  275. package/src/parserContext.test.ts +38 -7
  276. package/src/parserContext.ts +127 -51
  277. package/src/parserCreatorCompose.ts +25 -7
  278. package/src/parserError.ts +9 -6
  279. package/src/parserImplementationInvariant.ts +2 -2
  280. package/src/parserInputCompanion.ts +102 -0
  281. package/src/promiseCompose.ts +17 -3
  282. package/src/promiseSettled.ts +6 -0
  283. package/src/quantifierParser.ts +25 -0
  284. package/src/separatedArrayParser.test.ts +34 -0
  285. package/src/separatedArrayParser.ts +55 -0
  286. package/src/sequenceBuffer.test.ts +72 -2
  287. package/src/sequenceBuffer.ts +93 -7
  288. package/src/sequenceTerminatedSequenceParser.test.ts +60 -0
  289. package/src/sequenceTerminatedSequenceParser.ts +62 -0
  290. package/src/sequenceUnparser.ts +9 -0
  291. package/src/skipParser.ts +7 -5
  292. package/src/skipToParser.ts +16 -0
  293. package/src/sliceBoundedParser.test.ts +45 -3
  294. package/src/sliceBoundedParser.ts +21 -3
  295. package/src/smali.ts +24 -0
  296. package/src/smaliParser.test.ts +132 -0
  297. package/src/smaliParser.test.ts.md +2320 -0
  298. package/src/smaliParser.test.ts.snap +0 -0
  299. package/src/smaliParser.ts +1166 -0
  300. package/src/terminatedArrayParser.test.ts +258 -0
  301. package/src/terminatedArrayParser.ts +111 -6
  302. package/src/toAsyncIterable.ts +7 -0
  303. package/src/toAsyncIterator.ts +48 -0
  304. package/src/tupleParser.ts +8 -5
  305. package/src/uint8Array.ts +10 -0
  306. package/src/unionParser.test.ts +79 -0
  307. package/src/unionParser.ts +44 -16
  308. package/src/unparser.test.ts +221 -0
  309. package/src/unparser.ts +209 -0
  310. package/src/unparserContext.ts +127 -0
  311. package/src/unparserError.ts +12 -0
  312. package/src/unparserImplementationInvariant.ts +6 -0
  313. package/src/unparserOutputCompanion.ts +24 -0
  314. package/src/zip.ts +10 -22
  315. package/src/zipParser.test.ts +2 -8
  316. package/src/zipParser.ts +223 -146
  317. package/src/zipUnparser.test.ts +119 -0
  318. package/src/zipUnparser.ts +300 -0
  319. package/build/apk.d.ts +0 -13
  320. package/build/apkParser.d.ts +0 -3
  321. package/build/apkParser.js +0 -135
  322. package/build/arbitraryDosDate.d.ts +0 -2
  323. package/build/arbitraryDosDate.js +0 -8
  324. package/build/arbitraryZipEntry.d.ts +0 -3
  325. package/build/arbitraryZipEntry.js +0 -26
  326. package/build/createDisjunctionParser.d.ts +0 -2
  327. package/build/createDisjunctionParser.js +0 -47
  328. package/build/createExactParser.d.ts +0 -2
  329. package/build/createExactParser.js +0 -12
  330. package/build/createSequentialUnionParser.d.ts +0 -2
  331. package/build/createSequentialUnionParser.js +0 -69
  332. package/build/fixedLengthChunkParser.d.ts +0 -2
  333. package/build/fixedLengthChunkParser.js +0 -12
  334. package/build/fixedLengthParser.d.ts +0 -2
  335. package/build/fixedLengthParser.js +0 -12
  336. package/build/inputChunkBuffer.d.ts +0 -15
  337. package/build/inputChunkBuffer.js +0 -40
  338. package/build/inputChunkBuffer.test.js +0 -34
  339. package/build/inputCompanion.d.ts +0 -18
  340. package/build/inputCompanion.js +0 -28
  341. package/build/invariantDefined.d.ts +0 -1
  342. package/build/invariantDefined.js +0 -5
  343. package/build/invariantIdentity.d.ts +0 -3
  344. package/build/invariantIdentity.js +0 -5
  345. package/build/jsonParser2.d.ts +0 -3
  346. package/build/jsonParser2.js +0 -52
  347. package/build/jsonParser2.test.js +0 -22
  348. package/build/negativeLookahead.js +0 -20
  349. package/build/parserCompose.d.ts +0 -3
  350. package/build/parserCompose.js +0 -7
  351. package/build/parserImplementationInvariantInvariant.d.ts +0 -3
  352. package/build/parserImplementationInvariantInvariant.js +0 -15
  353. package/build/promiseFish.d.ts +0 -1
  354. package/build/promiseFish.js +0 -3
  355. package/build/sequenceParser.d.ts +0 -3
  356. package/build/sequenceParser.js +0 -10
  357. package/build/terminatedSequenceParser.d.ts +0 -2
  358. package/build/terminatedSequenceParser.js +0 -24
  359. package/build/zipEntry.d.ts +0 -28
  360. package/build/zipFile.d.ts +0 -32
  361. package/build/zipFileEntry.d.ts +0 -6
  362. package/src/apk.ts +0 -16
  363. package/src/apkParser.test.ts.md +0 -268
  364. package/src/apkParser.test.ts.snap +0 -0
  365. package/src/apkParser.ts +0 -327
  366. package/src/inputCompanion.ts +0 -43
  367. package/src/invariantDefined.ts +0 -6
  368. package/src/invariantIdentity.ts +0 -8
  369. package/src/negativeLookahead.ts +0 -26
  370. /package/build/{apk.js → androidPackage.js} +0 -0
  371. /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
  372. /package/build/{arbitraryDosPermissions.d.ts → androidPackageUnparser.test.d.ts} +0 -0
  373. /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
  374. /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
  375. /package/build/{jsonParser2.test.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
  376. /package/build/{parserParsingInvariant.d.ts → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
  377. /package/build/{parserParsingInvariant.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
  378. /package/build/{zipEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
  379. /package/build/{zipFile.js → javaKeyStore.d.ts} +0 -0
  380. /package/build/{zipFileEntry.js → javaKeyStore.js} +0 -0
package/src/zipParser.ts CHANGED
@@ -1,16 +1,25 @@
1
- import invariant from "invariant";
2
- import zlib from "node:zlib";
3
- import { createArrayParser } from "./arrayParser.js";
4
- import { createExactSequenceParser } from "./exactSequenceParser.js";
5
- import { Parser, setParserName } from "./parser.js";
6
- import { createTupleParser } from "./tupleParser.js";
7
- import { promiseCompose } from "./promiseCompose.js";
8
- import { createFixedLengthSequenceParser } from "./fixedLengthSequenceParser.js";
9
- import { createOptionalParser } from "./optionalParser.js";
10
- import { parserCreatorCompose } from "./parserCreatorCompose.js";
11
- import { Zip, ZipCompression, ZipDirectoryEntry, ZipEntry, ZipFileEntry, ZipPermissions } from "./zip.js";
12
- import { Readable } from "node:stream";
13
- import { pipeline } from "node:stream/promises";
1
+ import zlib from 'node:zlib';
2
+ import { Readable } from 'node:stream';
3
+ import { pipeline } from 'node:stream/promises';
4
+ import invariant from 'invariant';
5
+ import { createArrayParser } from './arrayParser.js';
6
+ import { createExactSequenceParser } from './exactSequenceParser.js';
7
+ import { type Parser, setParserName } from './parser.js';
8
+ import { createTupleParser } from './tupleParser.js';
9
+ import { promiseCompose } from './promiseCompose.js';
10
+ import { createFixedLengthSequenceParser } from './fixedLengthSequenceParser.js';
11
+ import { createOptionalParser } from './optionalParser.js';
12
+ import { parserCreatorCompose } from './parserCreatorCompose.js';
13
+ import {
14
+ type Zip,
15
+ type ZipCompression,
16
+ type ZipDirectoryEntry,
17
+ type ZipEntry,
18
+ type ZipFileEntry,
19
+ } from './zip.js';
20
+ import { uint8ArrayAsyncIterableToUint8Array } from './uint8Array.js';
21
+ import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
22
+ import { createSequenceTerminatedSequenceParser } from './sequenceTerminatedSequenceParser.js';
14
23
 
15
24
  // https://pkwaredownloads.blob.core.windows.net/pem/APPNOTE.txt
16
25
 
@@ -34,12 +43,12 @@ const dosDateTimeParser: Parser<Date, Uint8Array> = promiseCompose(
34
43
  uint16LEParser,
35
44
  ]),
36
45
  ([ time, date ]) => new Date(Date.UTC(
37
- 1980 + ((date >> 9) & 0x7f),
38
- ((date >> 5) & 0xf) - 1,
39
- date & 0x1f,
40
- (time >> 11) & 0x1f,
41
- (time >> 5) & 0x3f,
42
- (time & 0x1f) * 2,
46
+ 1980 + ((date >> 9) & 0x7F),
47
+ ((date >> 5) & 0xF) - 1,
48
+ date & 0x1F,
49
+ (time >> 11) & 0x1F,
50
+ (time >> 5) & 0x3F,
51
+ (time & 0x1F) * 2,
43
52
  )),
44
53
  );
45
54
 
@@ -58,21 +67,23 @@ const zipCompressionMethodParser: Parser<ZipCompression, Uint8Array> = promiseCo
58
67
  },
59
68
  );
60
69
 
61
- type ZipLocalFileHeader = {
70
+ export type ZipLocalFileHeader = {
62
71
  versionNeededToExtract: number;
63
72
  generalPurposeBitFlag: number;
64
73
  compressionMethod: ZipCompression;
65
- lastModFile: Date;
74
+ lastModifiedFile: Date;
66
75
  crc32: number;
67
76
  compressedSize: number;
68
77
  uncompressedSize: number;
69
78
 
70
- fileName: string;
79
+ filePath: string;
71
80
  extraField: Uint8Array;
72
81
  };
73
82
 
83
+ const zipLocalFileHeaderSignatureParser = createExactSequenceParser<Uint8Array>(Buffer.from('504b0304', 'hex'));
84
+
74
85
  const zipLocalFileHeaderParser_ = createTupleParser([
75
- createExactSequenceParser<Uint8Array>(Buffer.from('504b0304', 'hex')),
86
+ zipLocalFileHeaderSignatureParser,
76
87
  uint16LEParser,
77
88
  uint16LEParser,
78
89
  zipCompressionMethodParser,
@@ -86,10 +97,10 @@ const zipLocalFileHeaderParser_ = createTupleParser([
86
97
  uint16LEParser,
87
98
  ]),
88
99
  ([
89
- fileNameLength,
100
+ filePathLength,
90
101
  extraFieldLength,
91
102
  ]) => createTupleParser([
92
- createFixedLengthSequenceParser(fileNameLength),
103
+ createFixedLengthSequenceParser(filePathLength),
93
104
  createFixedLengthSequenceParser(extraFieldLength),
94
105
  ]),
95
106
  )(),
@@ -104,20 +115,20 @@ const zipLocalFileHeaderParser: Parser<ZipLocalFileHeader, Uint8Array> = promise
104
115
  versionNeededToExtract,
105
116
  generalPurposeBitFlag,
106
117
  compressionMethod,
107
- lastModFile,
118
+ lastModifiedFile,
108
119
  crc32,
109
120
  compressedSize,
110
121
  uncompressedSize,
111
- [ fileName, extraField ],
122
+ [ filePath, extraField ],
112
123
  ]) => ({
113
124
  versionNeededToExtract,
114
125
  generalPurposeBitFlag,
115
126
  compressionMethod,
116
- lastModFile,
127
+ lastModifiedFile,
117
128
  crc32,
118
129
  compressedSize,
119
130
  uncompressedSize,
120
- fileName: Buffer.from(fileName).toString('utf8'),
131
+ filePath: Buffer.from(filePath).toString('utf8'),
121
132
  extraField,
122
133
  }),
123
134
  );
@@ -126,31 +137,84 @@ const zipEncryptionHeaderParser: Parser<unknown, Uint8Array> = async parserConte
126
137
  parserContext.invariant(false, 'Not implemented');
127
138
  };
128
139
 
129
- const zipDataDescriptorParser: Parser<unknown, Uint8Array> = createTupleParser([
130
- // FIXME: optional in spec
131
- // createOptionalParser(createExactSequenceParser<Uint8Array>(Buffer.from('504b0708', 'hex'))),
132
- createExactSequenceParser<Uint8Array>(Buffer.from('504b0708', 'hex')),
133
- uint32LEParser,
134
- uint32LEParser,
135
- uint32LEParser,
136
- ]);
140
+ type ZipDataDescriptor = {
141
+ crc32: number;
142
+ compressedSize: number;
143
+ uncompressedSize: number;
144
+ };
145
+
146
+ const zipDataDescriptorSignature: Uint8Array = Buffer.from('504b0708', 'hex');
147
+ const zipDataDescriptorSignatureParser = createExactSequenceParser<Uint8Array>(
148
+ zipDataDescriptorSignature
149
+ );
150
+
151
+ const zipDataDescriptorParser: Parser<ZipDataDescriptor, Uint8Array> = promiseCompose(
152
+ createTupleParser([
153
+ createNegativeLookaheadParser(
154
+ zipLocalFileHeaderSignatureParser,
155
+ ),
156
+ // FIXME: optional in spec
157
+ //createOptionalParser(zipDataDescriptorSignatureParser),
158
+ zipDataDescriptorSignatureParser,
159
+ uint32LEParser,
160
+ uint32LEParser,
161
+ uint32LEParser,
162
+ ]),
163
+ ([
164
+ _notZipLocalFileHeaderSignature,
165
+ _zipDataDescriptorSignature,
166
+ crc32,
167
+ compressedSize,
168
+ uncompressedSize,
169
+ ]) => ({
170
+ crc32,
171
+ compressedSize,
172
+ uncompressedSize,
173
+ }),
174
+ );
137
175
 
138
- type ZipLocalFile = {
176
+ setParserName(zipDataDescriptorParser, 'zipDataDescriptorParser');
177
+
178
+ export type ZipLocalFile = {
139
179
  zipLocalFileHeader: ZipLocalFileHeader;
140
180
  zipEncryptionHeader: unknown;
141
181
  compressedData: Uint8Array;
142
- zipDataDescriptor: unknown;
182
+ zipDataDescriptor: undefined | ZipDataDescriptor;
143
183
  };
144
184
 
145
185
  export const zipLocalFileParser: Parser<ZipLocalFile, Uint8Array> = promiseCompose(
146
186
  parserCreatorCompose(
147
187
  () => zipLocalFileHeaderParser,
148
- (zipLocalFileHeader) => createTupleParser([
149
- async () => zipLocalFileHeader,
150
- createOptionalParser(zipEncryptionHeaderParser),
151
- createFixedLengthSequenceParser(zipLocalFileHeader.compressedSize),
152
- createOptionalParser(zipDataDescriptorParser),
153
- ]),
188
+ zipLocalFileHeader => {
189
+ const sizeInDataDescriptor = Boolean(
190
+ zipLocalFileHeader.generalPurposeBitFlag & 0b0000_0000_0000_1000
191
+ && zipLocalFileHeader.crc32 === 0
192
+ && zipLocalFileHeader.compressedSize === 0
193
+ && zipLocalFileHeader.uncompressedSize === 0
194
+ );
195
+
196
+ return createTupleParser([
197
+ async () => zipLocalFileHeader,
198
+ createOptionalParser(zipEncryptionHeaderParser),
199
+ (
200
+ sizeInDataDescriptor
201
+ ? createSequenceTerminatedSequenceParser(
202
+ zipDataDescriptorSignature,
203
+ {
204
+ consumeTerminator: false,
205
+ },
206
+ )
207
+ : createFixedLengthSequenceParser(zipLocalFileHeader.compressedSize)
208
+ ),
209
+ (
210
+ sizeInDataDescriptor
211
+ ? (<T>(parser: T): T => parser)
212
+ : createOptionalParser
213
+ )(
214
+ zipDataDescriptorParser
215
+ ),
216
+ ]);
217
+ },
154
218
  )(),
155
219
  ([
156
220
  zipLocalFileHeader,
@@ -191,83 +255,117 @@ const zipVersionMadeByParser: Parser<ZipVersionMadeBy, Uint8Array> = promiseComp
191
255
  }),
192
256
  );
193
257
 
194
- type ZipCentralDirectoryHeader = {
258
+ type ZipExternalFileAttributes = {
259
+ directory: boolean;
260
+ }
261
+
262
+ const dosExternalFileAttributesParser: Parser<ZipExternalFileAttributes, Uint8Array> = promiseCompose(
263
+ uint32LEParser,
264
+ externalFileAttributes => ({
265
+ directory: (externalFileAttributes & 0b0001_0000) !== 0,
266
+ }),
267
+ );
268
+
269
+ const unixExternalFileAttributesParser: Parser<ZipExternalFileAttributes, Uint8Array> = promiseCompose(
270
+ uint32LEParser,
271
+ externalFileAttributes => ({
272
+ directory: (externalFileAttributes & (0b0100_0000_0000_0000 << 16)) !== 0,
273
+ }),
274
+ );
275
+
276
+ const createExternalFileAttributesParser = (hostSystem: number) => promiseCompose(
277
+ hostSystem === 0 ? dosExternalFileAttributesParser : unixExternalFileAttributesParser,
278
+ externalFileAttributes => externalFileAttributes,
279
+ );
280
+
281
+ export type ZipCentralDirectoryHeader = {
195
282
  versionMadeBy: ZipVersionMadeBy;
196
283
  versionNeededToExtract: number;
197
284
  generalPurposeBitFlag: number;
198
285
  compressionMethod: ZipCompression;
199
- lastModFile: Date;
286
+ lastModifiedFile: Date;
200
287
  crc32: number;
201
288
  compressedSize: number;
202
289
  uncompressedSize: number;
203
290
  diskNumberStart: number;
204
291
  internalFileAttributes: number;
205
- externalFileAttributes: number;
292
+ externalFileAttributes: ZipExternalFileAttributes;
206
293
  relativeOffsetOfLocalHeader: number;
207
294
 
208
- fileName: string;
295
+ filePath: string;
209
296
  extraField: Uint8Array;
210
297
  fileComment: string;
211
298
  };
212
299
 
213
- const zipCentralDirectoryHeaderParser_ = createTupleParser([
214
- createExactSequenceParser<Uint8Array>(Buffer.from('504b0102', 'hex')),
215
- zipVersionMadeByParser,
216
- uint16LEParser,
217
- uint16LEParser,
218
- zipCompressionMethodParser,
219
- dosDateTimeParser,
220
- uint32LEParser,
221
- uint32LEParser,
222
- uint32LEParser,
223
- parserCreatorCompose(
224
- () => createTupleParser([
225
- uint16LEParser,
226
- uint16LEParser,
227
- uint16LEParser,
228
- uint16LEParser,
229
- uint16LEParser,
230
- uint32LEParser,
231
- uint32LEParser,
232
- ]),
233
- ([
234
- fileNameLength,
235
- extraFieldLength,
236
- fileCommentLength,
237
-
238
- diskNumberStart,
239
- internalFileAttributes,
240
- externalFileAttributes,
241
- relativeOffsetOfLocalHeader,
242
- ]) => createTupleParser([
243
- createFixedLengthSequenceParser(fileNameLength),
244
- createFixedLengthSequenceParser(extraFieldLength),
245
- createFixedLengthSequenceParser(fileCommentLength),
246
-
247
- async () => diskNumberStart,
248
- async () => internalFileAttributes,
249
- async () => externalFileAttributes,
250
- async () => relativeOffsetOfLocalHeader,
251
- ]),
252
- )(),
253
- ]);
300
+ const zipCentralDirectoryHeaderParser_ = parserCreatorCompose(
301
+ () => createTupleParser([
302
+ createExactSequenceParser<Uint8Array>(Buffer.from('504b0102', 'hex')),
303
+ zipVersionMadeByParser,
304
+ ]),
305
+ ([
306
+ _centralDirectoryHeaderSignature,
307
+ versionMadeBy,
308
+ ]) => createTupleParser([
309
+ async () => versionMadeBy,
310
+ uint16LEParser,
311
+ uint16LEParser,
312
+ zipCompressionMethodParser,
313
+ dosDateTimeParser,
314
+ uint32LEParser,
315
+ uint32LEParser,
316
+ uint32LEParser,
317
+ parserCreatorCompose(
318
+ () => createTupleParser([
319
+ uint16LEParser,
320
+ uint16LEParser,
321
+ uint16LEParser,
322
+
323
+ uint16LEParser,
324
+ uint16LEParser,
325
+
326
+ createExternalFileAttributesParser(versionMadeBy.hostSystem),
327
+ uint32LEParser,
328
+ ]),
329
+ ([
330
+ filePathLength,
331
+ extraFieldLength,
332
+ fileCommentLength,
333
+
334
+ diskNumberStart,
335
+ internalFileAttributes,
336
+
337
+ externalFileAttributes,
338
+ relativeOffsetOfLocalHeader,
339
+ ]) => createTupleParser([
340
+ createFixedLengthSequenceParser(filePathLength),
341
+ createFixedLengthSequenceParser(extraFieldLength),
342
+ createFixedLengthSequenceParser(fileCommentLength),
343
+
344
+ async () => diskNumberStart,
345
+ async () => internalFileAttributes,
346
+
347
+ async () => externalFileAttributes,
348
+ async () => relativeOffsetOfLocalHeader,
349
+ ]),
350
+ )(),
351
+ ]),
352
+ )();
254
353
 
255
354
  setParserName(zipCentralDirectoryHeaderParser_, 'centralDirectoryHeaderParser_');
256
355
 
257
356
  export const zipCentralDirectoryHeaderParser: Parser<ZipCentralDirectoryHeader, Uint8Array> = promiseCompose(
258
357
  zipCentralDirectoryHeaderParser_,
259
358
  ([
260
- _centralDirectoryHeaderSignature,
261
359
  versionMadeBy,
262
360
  versionNeededToExtract,
263
361
  generalPurposeBitFlag,
264
362
  compressionMethod,
265
- lastModFile,
363
+ lastModifiedFile,
266
364
  crc32,
267
365
  compressedSize,
268
366
  uncompressedSize,
269
367
  [
270
- fileName,
368
+ filePath,
271
369
  extraField,
272
370
  fileComment,
273
371
 
@@ -281,7 +379,7 @@ export const zipCentralDirectoryHeaderParser: Parser<ZipCentralDirectoryHeader,
281
379
  versionNeededToExtract,
282
380
  generalPurposeBitFlag,
283
381
  compressionMethod,
284
- lastModFile,
382
+ lastModifiedFile,
285
383
  crc32,
286
384
  compressedSize,
287
385
  uncompressedSize,
@@ -289,7 +387,7 @@ export const zipCentralDirectoryHeaderParser: Parser<ZipCentralDirectoryHeader,
289
387
  internalFileAttributes,
290
388
  externalFileAttributes,
291
389
  relativeOffsetOfLocalHeader,
292
- fileName: Buffer.from(fileName).toString('utf8'),
390
+ filePath: Buffer.from(filePath).toString('utf8'),
293
391
  extraField,
294
392
  fileComment: Buffer.from(fileComment).toString('utf8'),
295
393
  }),
@@ -311,14 +409,14 @@ const zipFileCommentParser: Parser<string, Uint8Array> = promiseCompose(
311
409
  uint8Array => Buffer.from(uint8Array).toString('utf8'),
312
410
  );
313
411
 
314
- type ZipEndOfCentralDirectoryRecord = {
315
- numberOfThisDisk: number,
316
- numberOfTheDiskWithTheStartOfTheCentralDirectory: number,
317
- totalNumberOfEntriesInTheCentralDirectoryOnThisDisk: number,
318
- totalNumberOfEntriesInTheCentralDirectory: number,
319
- sizeOfTheCentralDirectory: number,
320
- offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber: number,
321
- zipFileComment: string,
412
+ export type ZipEndOfCentralDirectoryRecord = {
413
+ numberOfThisDisk: number;
414
+ numberOfTheDiskWithTheStartOfTheCentralDirectory: number;
415
+ totalNumberOfEntriesInTheCentralDirectoryOnThisDisk: number;
416
+ totalNumberOfEntriesInTheCentralDirectory: number;
417
+ sizeOfTheCentralDirectory: number;
418
+ offsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber: number;
419
+ zipFileComment: string;
322
420
  };
323
421
 
324
422
  const zipEndOfCentralDirectoryRecordParser_ = createTupleParser([
@@ -332,7 +430,7 @@ const zipEndOfCentralDirectoryRecordParser_ = createTupleParser([
332
430
  zipFileCommentParser,
333
431
  ]);
334
432
 
335
- setParserName(zipEndOfCentralDirectoryRecordParser_, 'endOfCentralDirectoryRecordParser_');
433
+ setParserName(zipEndOfCentralDirectoryRecordParser_, 'zipEndOfCentralDirectoryRecordParser_');
336
434
 
337
435
  export const zipEndOfCentralDirectoryRecordParser: Parser<ZipEndOfCentralDirectoryRecord, Uint8Array> = promiseCompose(
338
436
  zipEndOfCentralDirectoryRecordParser_,
@@ -356,6 +454,8 @@ export const zipEndOfCentralDirectoryRecordParser: Parser<ZipEndOfCentralDirecto
356
454
  }),
357
455
  );
358
456
 
457
+ setParserName(zipEndOfCentralDirectoryRecordParser, 'zipEndOfCentralDirectoryRecordParser');
458
+
359
459
  const zipParser_ = createTupleParser([
360
460
  createArrayParser(zipLocalFileParser),
361
461
  createOptionalParser(zipArchiveDecryptionHeaderParser),
@@ -372,10 +472,10 @@ export async function zipEntriesFromZipSegments({
372
472
  zipLocalFiles,
373
473
  zipCentralDirectoryHeaders,
374
474
  }: {
375
- zipLocalFiles: ZipLocalFile[],
376
- zipCentralDirectoryHeaders: ZipCentralDirectoryHeader[],
475
+ zipLocalFiles: ZipLocalFile[];
476
+ zipCentralDirectoryHeaders: ZipCentralDirectoryHeader[];
377
477
  }) {
378
- const decompressPromises: Promise<void>[] = [];
478
+ const decompressPromises: Array<Promise<void>> = [];
379
479
 
380
480
  const entries: ZipEntry[] = await Promise.all(zipLocalFiles.map(async (zipLocalFile, index) => {
381
481
  const {
@@ -389,41 +489,24 @@ export async function zipEntriesFromZipSegments({
389
489
 
390
490
  invariant(centralDirectoryHeader, 'Central directory header not found for local file %s', index);
391
491
 
392
- let isDosDirectory = false;
393
- let permissions: ZipPermissions = {
394
- type: 'unix',
395
- unixPermissions: 0,
396
- };
397
-
398
- if (centralDirectoryHeader.versionMadeBy.hostSystem === 0) {
399
- isDosDirectory = (centralDirectoryHeader.externalFileAttributes & 0b00010000) !== 0;
400
- permissions = {
401
- type: 'dos',
402
- dosPermissions: centralDirectoryHeader.externalFileAttributes & 0b00111111,
403
- };
404
- }
405
-
406
- if (centralDirectoryHeader.versionMadeBy.hostSystem === 3) {
407
- permissions = {
408
- type: 'unix',
409
- unixPermissions: (centralDirectoryHeader.externalFileAttributes >> 16) & 0b111111111,
410
- };
411
- }
412
-
413
492
  const commonFields: Omit<ZipFileEntry | ZipDirectoryEntry, 'type'> = {
414
- path: zipLocalFileHeader.fileName,
493
+ path: zipLocalFileHeader.filePath,
415
494
  comment: centralDirectoryHeader.fileComment,
416
- date: zipLocalFileHeader.lastModFile,
417
- permissions,
495
+ date: zipLocalFileHeader.lastModifiedFile,
496
+ hostSystem: centralDirectoryHeader.versionMadeBy.hostSystem === 0 ? 'dos' : 'unix',
497
+ attributes: centralDirectoryHeader.externalFileAttributes,
418
498
  };
419
499
 
420
- const isDirectory = isDosDirectory || commonFields.path.endsWith('/');
500
+ const isDirectory = (
501
+ centralDirectoryHeader.externalFileAttributes.directory
502
+ || commonFields.path.endsWith('/')
503
+ );
421
504
 
422
505
  if (isDirectory) {
423
506
  return {
424
507
  ...commonFields,
425
508
  type: 'directory',
426
- path: commonFields.path.slice(0, -1),
509
+ path: commonFields.path.replace(/\/$/, ''),
427
510
  };
428
511
  }
429
512
 
@@ -434,18 +517,12 @@ export async function zipEntriesFromZipSegments({
434
517
  compression: zipLocalFileHeader.compressionMethod,
435
518
  };
436
519
 
437
- if (fileEntry.content.length && fileEntry.compression === 'deflate') {
438
- const deflate = zlib.createInflateRaw();
520
+ if (fileEntry.content.length > 0 && fileEntry.compression === 'deflate') {
521
+ const inflate = zlib.createInflateRaw();
439
522
  const input = Readable.from(Buffer.from(compressedData));
440
523
  const [ _, buffer ] = await Promise.all([
441
- pipeline(input, deflate),
442
- (async () => {
443
- const chunks: Buffer[] = [];
444
- for await (const chunk of deflate) {
445
- chunks.push(chunk);
446
- }
447
- return Buffer.concat(chunks);
448
- })(),
524
+ pipeline(input, inflate),
525
+ uint8ArrayAsyncIterableToUint8Array(inflate),
449
526
  ]);
450
527
 
451
528
  fileEntry.content = Uint8Array.from(buffer);
@@ -465,10 +542,10 @@ export async function zipFromZipSegments({
465
542
 
466
543
  zipEndOfCentralDirectoryRecord,
467
544
  }: {
468
- zipLocalFiles: ZipLocalFile[],
469
- zipCentralDirectoryHeaders: ZipCentralDirectoryHeader[],
545
+ zipLocalFiles: ZipLocalFile[];
546
+ zipCentralDirectoryHeaders: ZipCentralDirectoryHeader[];
470
547
 
471
- zipEndOfCentralDirectoryRecord: ZipEndOfCentralDirectoryRecord,
548
+ zipEndOfCentralDirectoryRecord: ZipEndOfCentralDirectoryRecord;
472
549
  }) {
473
550
  const entries = await zipEntriesFromZipSegments({
474
551
  zipLocalFiles,
@@ -0,0 +1,119 @@
1
+ import { fc, testProp } from '@fast-check/ava';
2
+ import { temporaryFile } from 'tempy';
3
+ import { execa } from 'execa';
4
+ import fsPromises from 'node:fs/promises';
5
+ import { runUnparser } from './unparser.js';
6
+ import { createZipUnparser } from './zipUnparser.js';
7
+ import { uint8ArrayUnparserOutputCompanion } from './unparserOutputCompanion.js';
8
+ import { runParser } from './parser.js';
9
+ import { zipParser } from './zipParser.js';
10
+ import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
11
+ import { arbitraryZip } from './arbitraryZip.js';
12
+ import { hasExecutable } from './hasExecutable.js';
13
+
14
+ const hasZipinfoPromise = hasExecutable('zipinfo');
15
+ const has7zPromise = hasExecutable('7z');
16
+
17
+ async function zipinfo(zipFilePath: string) {
18
+ const { stdout } = await execa('zipinfo', [
19
+ '-v',
20
+ zipFilePath,
21
+ ], {
22
+ reject: false,
23
+ });
24
+
25
+ return {
26
+ isEmptyZipfile: stdout.endsWith('Empty zipfile.'),
27
+ };
28
+ }
29
+
30
+ async function _7zList(zipFilePath: string) {
31
+ const { stdout } = await execa('7z', [
32
+ 'l',
33
+ zipFilePath,
34
+ ], {
35
+ reject: false,
36
+ });
37
+
38
+ if (/Errors: \d+$/.test(stdout)) {
39
+ throw new Error(`7z reports errors: ${stdout}`);
40
+ }
41
+
42
+ return {
43
+ isEmptyZipfile: false, // TODO
44
+ };
45
+ }
46
+
47
+ testProp(
48
+ 'zip',
49
+ [
50
+ arbitraryZip,
51
+ fc.record({
52
+ dataDescriptor: fc.boolean(),
53
+ }),
54
+ ],
55
+ async (t, zip, options) => {
56
+ const zipUnparser = createZipUnparser(options);
57
+
58
+ {
59
+ const zipStream = runUnparser(zipUnparser, zip, uint8ArrayUnparserOutputCompanion);
60
+
61
+ await fsPromises.writeFile('/tmp/zip.zip', zipStream);
62
+ }
63
+
64
+ const actualStream = runUnparser(zipUnparser, zip, uint8ArrayUnparserOutputCompanion);
65
+ const actual = await runParser(zipParser, actualStream, uint8ArrayParserInputCompanion);
66
+
67
+ t.deepEqual(actual, zip);
68
+
69
+ const hasZipinfo = await hasZipinfoPromise;
70
+ const has7z = await has7zPromise;
71
+
72
+ if (!hasZipinfo && !has7z) {
73
+ t.pass('no zipinfo or 7z, skipping zipfile check');
74
+
75
+ return;
76
+ }
77
+
78
+ const temporaryFilePath = temporaryFile({
79
+ extension: 'zip',
80
+ });
81
+
82
+ const zipStream = runUnparser(zipUnparser, zip, uint8ArrayUnparserOutputCompanion);
83
+
84
+ await fsPromises.writeFile(temporaryFilePath, zipStream);
85
+
86
+ if (has7z) {
87
+ const {
88
+ isEmptyZipfile,
89
+ } = await _7zList(temporaryFilePath);
90
+
91
+ if (isEmptyZipfile) {
92
+ t.deepEqual(
93
+ actual.entries,
94
+ [],
95
+ '7z reports the zipfile as empty, but it has entries',
96
+ );
97
+ }
98
+ }
99
+
100
+ if (hasZipinfo) {
101
+ const {
102
+ isEmptyZipfile,
103
+ } = await zipinfo(temporaryFilePath);
104
+
105
+ if (isEmptyZipfile) {
106
+ t.deepEqual(
107
+ actual.entries.filter(entry => entry.type === 'file'),
108
+ [],
109
+ 'zipinfo reports the zipfile as empty, but it has file entries',
110
+ );
111
+ }
112
+ }
113
+
114
+ await fsPromises.unlink(temporaryFilePath);
115
+ },
116
+ {
117
+ verbose: true,
118
+ },
119
+ );