@futpib/parser 1.0.1 → 1.0.3

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 (425) hide show
  1. package/.github/copilot-instructions.md +149 -0
  2. package/.github/workflows/copilot-setup-steps.yml +18 -0
  3. package/.github/workflows/main.yml +29 -8
  4. package/.yarn/releases/yarn-4.9.4.cjs +942 -0
  5. package/.yarnrc.yml +1 -1
  6. package/build/allSettledStream.js +32 -14
  7. package/build/allSettledStream.test.js +32 -0
  8. package/build/androidPackage.d.ts +39 -0
  9. package/build/androidPackageParser.d.ts +17 -0
  10. package/build/androidPackageParser.js +185 -0
  11. package/build/androidPackageParser.test.js +22 -0
  12. package/build/androidPackageUnparser.d.ts +4 -0
  13. package/build/androidPackageUnparser.js +94 -0
  14. package/build/androidPackageUnparser.test.js +26 -0
  15. package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
  16. package/build/arbitrarilySlicedAsyncInterable.js +3 -3
  17. package/build/arbitrarilySlicedAsyncInterator.js +2 -1
  18. package/build/arbitraryDalvikBytecode.d.ts +4 -0
  19. package/build/arbitraryDalvikBytecode.js +640 -0
  20. package/build/arbitraryDalvikExecutable.d.ts +3 -0
  21. package/build/arbitraryDalvikExecutable.js +282 -0
  22. package/build/arbitraryDosDateTime.js +1 -0
  23. package/build/arbitraryZipStream.js +1 -1
  24. package/build/arrayParser.js +2 -2
  25. package/build/arrayParser.test.js +3 -3
  26. package/build/arrayUnparser.d.ts +1 -1
  27. package/build/backsmali.d.ts +3 -0
  28. package/build/backsmali.js +50 -0
  29. package/build/bsonParser.js +6 -2
  30. package/build/customInvariant.d.ts +2 -1
  31. package/build/customInvariant.js +4 -6
  32. package/build/dalvikBytecodeParser/formatParsers.d.ts +171 -0
  33. package/build/dalvikBytecodeParser/formatParsers.js +304 -0
  34. package/build/dalvikBytecodeParser/formatSizes.d.ts +34 -0
  35. package/build/dalvikBytecodeParser/formatSizes.js +34 -0
  36. package/build/dalvikBytecodeParser/operationFormats.d.ts +225 -0
  37. package/build/dalvikBytecodeParser/operationFormats.js +225 -0
  38. package/build/dalvikBytecodeParser.d.ts +1207 -0
  39. package/build/dalvikBytecodeParser.js +1289 -0
  40. package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +152 -0
  41. package/build/dalvikBytecodeUnparser/formatUnparsers.js +225 -0
  42. package/build/dalvikBytecodeUnparser.d.ts +3 -0
  43. package/build/dalvikBytecodeUnparser.js +642 -0
  44. package/build/dalvikBytecodeUnparser.test.js +25 -0
  45. package/build/dalvikExecutable.d.ts +215 -0
  46. package/build/dalvikExecutable.js +56 -0
  47. package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
  48. package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
  49. package/build/dalvikExecutableParser/typeParsers.d.ts +11 -0
  50. package/build/dalvikExecutableParser/typeParsers.js +39 -0
  51. package/build/dalvikExecutableParser/typedNumbers.d.ts +106 -0
  52. package/build/dalvikExecutableParser/typedNumbers.js +18 -0
  53. package/build/dalvikExecutableParser.d.ts +5 -0
  54. package/build/dalvikExecutableParser.js +1757 -0
  55. package/build/dalvikExecutableParser.test.js +72 -0
  56. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +275 -0
  57. package/build/dalvikExecutableUnparser/annotationUnparsers.d.ts +14 -0
  58. package/build/dalvikExecutableUnparser/annotationUnparsers.js +97 -0
  59. package/build/dalvikExecutableUnparser/poolBuilders.d.ts +49 -0
  60. package/build/dalvikExecutableUnparser/poolBuilders.js +140 -0
  61. package/build/dalvikExecutableUnparser/poolScanners.d.ts +4 -0
  62. package/build/dalvikExecutableUnparser/poolScanners.js +220 -0
  63. package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +25 -0
  64. package/build/dalvikExecutableUnparser/sectionUnparsers.js +581 -0
  65. package/build/dalvikExecutableUnparser/utils.d.ts +10 -0
  66. package/build/dalvikExecutableUnparser/utils.js +108 -0
  67. package/build/dalvikExecutableUnparser.d.ts +4 -0
  68. package/build/dalvikExecutableUnparser.js +406 -0
  69. package/build/dalvikExecutableUnparser.test.js +31 -0
  70. package/build/debugLogInputParser.d.ts +4 -0
  71. package/build/debugLogInputParser.js +16 -0
  72. package/build/debugLogParser.js +14 -3
  73. package/build/disjunctionParser.d.ts +2 -1
  74. package/build/disjunctionParser.js +6 -4
  75. package/build/elementTerminatedArrayParser.d.ts +3 -0
  76. package/build/elementTerminatedArrayParser.js +18 -0
  77. package/build/elementTerminatedArrayParser.test.js +52 -0
  78. package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
  79. package/build/elementTerminatedSequenceArrayParser.js +32 -0
  80. package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
  81. package/build/elementTerminatedSequenceParser.d.ts +3 -0
  82. package/build/elementTerminatedSequenceParser.js +27 -0
  83. package/build/elementTerminatedSequenceParser.test.js +34 -0
  84. package/build/endOfInputParser.d.ts +1 -1
  85. package/build/exactElementParser.js +10 -5
  86. package/build/exactElementSwitchParser.d.ts +3 -0
  87. package/build/exactElementSwitchParser.js +22 -0
  88. package/build/exactSequenceParser.d.ts +2 -1
  89. package/build/exactSequenceParser.js +12 -2
  90. package/build/fetchCid.d.ts +1 -0
  91. package/build/fetchCid.js +103 -0
  92. package/build/fetchCid.test.js +16 -0
  93. package/build/fixedLengthSequenceParser.d.ts +1 -0
  94. package/build/fixedLengthSequenceParser.js +18 -1
  95. package/build/fixedLengthSequenceParser.test.js +41 -0
  96. package/build/hasExecutable.d.ts +1 -0
  97. package/build/hasExecutable.js +8 -0
  98. package/build/highResolutionTimer.d.ts +16 -0
  99. package/build/highResolutionTimer.js +42 -0
  100. package/build/inputReader.d.ts +11 -0
  101. package/build/inputReader.js +37 -0
  102. package/build/inputReader.test.js +161 -8
  103. package/build/inputReaderState.d.ts +10 -0
  104. package/build/inputReaderState.js +16 -0
  105. package/build/inspect.d.ts +1 -0
  106. package/build/inspect.js +7 -0
  107. package/build/javaKeyStoreParser.test.js +8 -8
  108. package/build/jsonParser.d.ts +2 -0
  109. package/build/jsonParser.js +19 -22
  110. package/build/lazyMessageError.d.ts +48 -0
  111. package/build/lazyMessageError.js +53 -0
  112. package/build/lazyMessageError.test.d.ts +1 -0
  113. package/build/lazyMessageError.test.js +15 -0
  114. package/build/leb128Parser.d.ts +7 -0
  115. package/build/leb128Parser.js +82 -0
  116. package/build/leb128Parser.test.d.ts +1 -0
  117. package/build/leb128Parser.test.js +107 -0
  118. package/build/lookaheadParser.d.ts +2 -0
  119. package/build/lookaheadParser.js +14 -0
  120. package/build/negativeLookaheadParser.js +22 -16
  121. package/build/negativeLookaheadParser.test.d.ts +1 -0
  122. package/build/negativeLookaheadParser.test.js +30 -0
  123. package/build/noStackCaptureOverheadError.d.ts +4 -0
  124. package/build/noStackCaptureOverheadError.js +9 -0
  125. package/build/noStackCaptureOverheadError.test.d.ts +1 -0
  126. package/build/noStackCaptureOverheadError.test.js +15 -0
  127. package/build/nonEmptyArrayParser.d.ts +2 -0
  128. package/build/nonEmptyArrayParser.js +32 -0
  129. package/build/nonEmptyArrayParser.test.d.ts +1 -0
  130. package/build/nonEmptyArrayParser.test.js +17 -0
  131. package/build/optionalParser.js +2 -2
  132. package/build/parser.d.ts +11 -1
  133. package/build/parser.js +82 -32
  134. package/build/parser.test.js +141 -25
  135. package/build/parserAccessorParser.js +9 -1
  136. package/build/parserConsumedSequenceParser.d.ts +1 -1
  137. package/build/parserConsumedSequenceParser.js +21 -16
  138. package/build/parserContext.d.ts +22 -6
  139. package/build/parserContext.js +113 -57
  140. package/build/parserContext.test.js +33 -2
  141. package/build/parserCreatorCompose.d.ts +1 -0
  142. package/build/parserCreatorCompose.js +8 -2
  143. package/build/parserError.d.ts +605 -40
  144. package/build/parserError.js +98 -53
  145. package/build/parserImplementationInvariant.d.ts +1 -1
  146. package/build/parserImplementationInvariant.js +2 -2
  147. package/build/parserInputCompanion.d.ts +15 -0
  148. package/build/parserInputCompanion.js +38 -0
  149. package/build/promiseCompose.d.ts +1 -1
  150. package/build/promiseCompose.js +11 -1
  151. package/build/promiseSettled.d.ts +1 -0
  152. package/build/promiseSettled.js +4 -0
  153. package/build/separatedArrayParser.d.ts +2 -0
  154. package/build/separatedArrayParser.js +39 -0
  155. package/build/separatedArrayParser.test.d.ts +1 -0
  156. package/build/separatedArrayParser.test.js +21 -0
  157. package/build/separatedNonEmptyArrayParser.d.ts +2 -0
  158. package/build/separatedNonEmptyArrayParser.js +40 -0
  159. package/build/separatedNonEmptyArrayParser.test.d.ts +1 -0
  160. package/build/separatedNonEmptyArrayParser.test.js +66 -0
  161. package/build/sequenceBuffer.d.ts +10 -0
  162. package/build/sequenceBuffer.js +54 -2
  163. package/build/sequenceBuffer.test.js +57 -0
  164. package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
  165. package/build/sequenceTerminatedSequenceParser.js +32 -0
  166. package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
  167. package/build/sequenceTerminatedSequenceParser.test.js +37 -0
  168. package/build/sequenceUnparser.d.ts +1 -1
  169. package/build/skipParser.d.ts +1 -1
  170. package/build/skipParser.js +4 -2
  171. package/build/skipToParser.d.ts +2 -0
  172. package/build/skipToParser.js +11 -0
  173. package/build/sliceBoundedParser.d.ts +1 -1
  174. package/build/sliceBoundedParser.js +7 -2
  175. package/build/sliceBoundedParser.test.js +30 -1
  176. package/build/smali.d.ts +1 -0
  177. package/build/smali.js +21 -0
  178. package/build/smaliParser.d.ts +68 -0
  179. package/build/smaliParser.js +2081 -0
  180. package/build/smaliParser.test.d.ts +1 -0
  181. package/build/smaliParser.test.js +410 -0
  182. package/build/stringFromAsyncIterable.d.ts +1 -0
  183. package/build/stringFromAsyncIterable.js +7 -0
  184. package/build/terminatedArrayParser.d.ts +3 -1
  185. package/build/terminatedArrayParser.js +79 -2
  186. package/build/terminatedArrayParser.test.d.ts +1 -0
  187. package/build/terminatedArrayParser.test.js +131 -0
  188. package/build/toAsyncIterable.d.ts +1 -0
  189. package/build/toAsyncIterable.js +7 -0
  190. package/build/toAsyncIterator.d.ts +1 -0
  191. package/build/toAsyncIterator.js +33 -0
  192. package/build/tupleParser.d.ts +4 -0
  193. package/build/tupleParser.js +1 -5
  194. package/build/unionParser.d.ts +2 -1
  195. package/build/unionParser.js +29 -14
  196. package/build/unionParser.test.d.ts +1 -0
  197. package/build/unionParser.test.js +60 -0
  198. package/build/unparser.d.ts +3 -3
  199. package/build/unparser.js +6 -4
  200. package/build/unparser.test.js +7 -19
  201. package/build/unparserContext.d.ts +2 -2
  202. package/build/unparserContext.js +2 -3
  203. package/build/unparserError.d.ts +2 -1
  204. package/build/unparserError.js +2 -1
  205. package/build/unparserImplementationInvariant.d.ts +1 -1
  206. package/build/unparserOutputCompanion.d.ts +1 -1
  207. package/build/unparserOutputCompanion.js +1 -1
  208. package/build/zipParser.d.ts +7 -2
  209. package/build/zipParser.js +36 -12
  210. package/build/zipUnparser.d.ts +7 -4
  211. package/build/zipUnparser.js +64 -45
  212. package/build/zipUnparser.test.js +15 -15
  213. package/package.json +33 -24
  214. package/src/allSettledStream.test.ts +40 -0
  215. package/src/allSettledStream.ts +47 -15
  216. package/src/androidPackage.ts +48 -0
  217. package/src/androidPackageParser.test.ts +27 -0
  218. package/src/{apkParser.test.ts.md → androidPackageParser.test.ts.md} +4 -4
  219. package/src/androidPackageParser.test.ts.snap +0 -0
  220. package/src/androidPackageParser.ts +398 -0
  221. package/src/androidPackageUnparser.test.ts +34 -0
  222. package/src/androidPackageUnparser.ts +126 -0
  223. package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
  224. package/src/arbitrarilySlicedAsyncInterator.ts +4 -4
  225. package/src/arbitraryDalvikBytecode.ts +992 -0
  226. package/src/arbitraryDalvikExecutable.ts +434 -0
  227. package/src/arbitraryDosDateTime.ts +1 -0
  228. package/src/arbitraryZipStream.ts +1 -1
  229. package/src/arrayParser.test.ts +3 -3
  230. package/src/arrayParser.ts +2 -2
  231. package/src/arrayUnparser.ts +2 -2
  232. package/src/backsmali.ts +74 -0
  233. package/src/bsonParser.test.ts +12 -14
  234. package/src/bsonParser.ts +13 -2
  235. package/src/customInvariant.ts +8 -12
  236. package/src/dalvikBytecodeParser/formatParsers.ts +780 -0
  237. package/src/dalvikBytecodeParser/formatSizes.ts +35 -0
  238. package/src/dalvikBytecodeParser/operationFormats.ts +226 -0
  239. package/src/dalvikBytecodeParser.ts +2873 -0
  240. package/src/dalvikBytecodeUnparser/formatUnparsers.ts +442 -0
  241. package/src/dalvikBytecodeUnparser.test.ts +44 -0
  242. package/src/dalvikBytecodeUnparser.ts +758 -0
  243. package/src/dalvikExecutable.ts +282 -0
  244. package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
  245. package/src/dalvikExecutableParser/typeParsers.ts +74 -0
  246. package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
  247. package/src/dalvikExecutableParser.test.ts +89 -0
  248. package/src/dalvikExecutableParser.test.ts.md +634 -0
  249. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  250. package/src/dalvikExecutableParser.ts +3245 -0
  251. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +363 -0
  252. package/src/dalvikExecutableUnparser/annotationUnparsers.ts +135 -0
  253. package/src/dalvikExecutableUnparser/poolBuilders.ts +189 -0
  254. package/src/dalvikExecutableUnparser/poolScanners.ts +297 -0
  255. package/src/dalvikExecutableUnparser/sectionUnparsers.ts +683 -0
  256. package/src/dalvikExecutableUnparser/utils.ts +149 -0
  257. package/src/dalvikExecutableUnparser.test.ts +57 -0
  258. package/src/dalvikExecutableUnparser.ts +581 -0
  259. package/src/debugLogInputParser.ts +28 -0
  260. package/src/debugLogParser.ts +19 -3
  261. package/src/disjunctionParser.ts +12 -7
  262. package/src/elementTerminatedArrayParser.test.ts +99 -0
  263. package/src/elementTerminatedArrayParser.ts +31 -0
  264. package/src/elementTerminatedSequenceArrayParser.test.ts +52 -0
  265. package/src/elementTerminatedSequenceArrayParser.ts +52 -0
  266. package/src/elementTerminatedSequenceParser.test.ts +52 -0
  267. package/src/elementTerminatedSequenceParser.ts +43 -0
  268. package/src/endOfInputParser.ts +1 -1
  269. package/src/exactElementParser.ts +17 -11
  270. package/src/exactElementSwitchParser.ts +41 -0
  271. package/src/exactSequenceParser.ts +23 -2
  272. package/src/fetchCid.test.ts +20 -0
  273. package/src/fetchCid.ts +121 -0
  274. package/src/fixedLengthSequenceParser.test.ts +75 -0
  275. package/src/fixedLengthSequenceParser.ts +28 -1
  276. package/src/hasExecutable.ts +11 -0
  277. package/src/highResolutionTimer.ts +49 -0
  278. package/src/inputReader.test.ts +204 -8
  279. package/src/inputReader.ts +76 -3
  280. package/src/inputReaderState.ts +33 -0
  281. package/src/inspect.ts +9 -0
  282. package/src/javaKeyStoreParser.test.ts +12 -15
  283. package/src/javaKeyStoreParser.ts +2 -6
  284. package/src/jsonParser.test.ts +2 -4
  285. package/src/jsonParser.ts +46 -62
  286. package/src/lazyMessageError.test.ts +21 -0
  287. package/src/lazyMessageError.ts +88 -0
  288. package/src/leb128Parser.test.ts +173 -0
  289. package/src/leb128Parser.ts +125 -0
  290. package/src/lookaheadParser.ts +19 -0
  291. package/src/negativeLookaheadParser.test.ts +49 -0
  292. package/src/negativeLookaheadParser.ts +27 -15
  293. package/src/noStackCaptureOverheadError.test.ts +17 -0
  294. package/src/noStackCaptureOverheadError.ts +12 -0
  295. package/src/nonEmptyArrayParser.test.ts +21 -0
  296. package/src/nonEmptyArrayParser.ts +44 -0
  297. package/src/optionalParser.ts +3 -2
  298. package/src/parser.test.ts +203 -31
  299. package/src/parser.test.ts.md +34 -27
  300. package/src/parser.test.ts.snap +0 -0
  301. package/src/parser.ts +172 -45
  302. package/src/parserAccessorParser.ts +12 -2
  303. package/src/parserConsumedSequenceParser.ts +26 -17
  304. package/src/parserContext.test.ts +37 -2
  305. package/src/parserContext.ts +185 -79
  306. package/src/parserCreatorCompose.ts +20 -2
  307. package/src/parserError.ts +144 -61
  308. package/src/parserImplementationInvariant.ts +3 -3
  309. package/src/parserInputCompanion.ts +55 -0
  310. package/src/promiseCompose.ts +17 -3
  311. package/src/promiseSettled.ts +6 -0
  312. package/src/separatedArrayParser.test.ts +34 -0
  313. package/src/separatedArrayParser.ts +55 -0
  314. package/src/separatedNonEmptyArrayParser.test.ts +117 -0
  315. package/src/separatedNonEmptyArrayParser.ts +61 -0
  316. package/src/sequenceBuffer.test.ts +70 -0
  317. package/src/sequenceBuffer.ts +88 -2
  318. package/src/sequenceTerminatedSequenceParser.test.ts +58 -0
  319. package/src/sequenceTerminatedSequenceParser.ts +62 -0
  320. package/src/sequenceUnparser.ts +2 -2
  321. package/src/skipParser.ts +7 -5
  322. package/src/skipToParser.ts +16 -0
  323. package/src/sliceBoundedParser.test.ts +35 -1
  324. package/src/sliceBoundedParser.ts +19 -1
  325. package/src/smali.ts +29 -0
  326. package/src/smaliParser.test.ts +443 -0
  327. package/src/smaliParser.test.ts.md +3907 -0
  328. package/src/smaliParser.test.ts.snap +0 -0
  329. package/src/smaliParser.ts +3348 -0
  330. package/src/stringFromAsyncIterable.ts +9 -0
  331. package/src/terminatedArrayParser.test.ts +258 -0
  332. package/src/terminatedArrayParser.ts +109 -6
  333. package/src/toAsyncIterable.ts +7 -0
  334. package/src/toAsyncIterator.ts +48 -0
  335. package/src/tupleParser.ts +8 -5
  336. package/src/uint8Array.ts +2 -3
  337. package/src/unionParser.test.ts +78 -0
  338. package/src/unionParser.ts +47 -21
  339. package/src/unparser.test.ts +18 -34
  340. package/src/unparser.ts +13 -9
  341. package/src/unparserContext.ts +9 -13
  342. package/src/unparserError.ts +2 -1
  343. package/src/unparserImplementationInvariant.ts +1 -1
  344. package/src/unparserOutputCompanion.ts +1 -1
  345. package/src/zip.ts +2 -6
  346. package/src/zipParser.ts +71 -20
  347. package/src/zipUnparser.test.ts +19 -19
  348. package/src/zipUnparser.ts +139 -90
  349. package/tsconfig.json +7 -1
  350. package/xo.config.ts +15 -0
  351. package/.yarn/releases/yarn-4.5.3.cjs +0 -934
  352. package/build/apk.d.ts +0 -39
  353. package/build/apkParser.d.ts +0 -16
  354. package/build/apkParser.js +0 -164
  355. package/build/apkParser.test.js +0 -22
  356. package/build/apkUnparser.d.ts +0 -4
  357. package/build/apkUnparser.js +0 -90
  358. package/build/apkUnparser.test.js +0 -26
  359. package/build/arbitraryDosDate.d.ts +0 -2
  360. package/build/arbitraryDosDate.js +0 -8
  361. package/build/arbitraryZipEntry.d.ts +0 -3
  362. package/build/arbitraryZipEntry.js +0 -26
  363. package/build/createDisjunctionParser.d.ts +0 -2
  364. package/build/createDisjunctionParser.js +0 -47
  365. package/build/createExactParser.d.ts +0 -2
  366. package/build/createExactParser.js +0 -12
  367. package/build/createSequentialUnionParser.d.ts +0 -2
  368. package/build/createSequentialUnionParser.js +0 -69
  369. package/build/fixedLengthChunkParser.d.ts +0 -2
  370. package/build/fixedLengthChunkParser.js +0 -12
  371. package/build/fixedLengthParser.d.ts +0 -2
  372. package/build/fixedLengthParser.js +0 -12
  373. package/build/inputChunkBuffer.d.ts +0 -15
  374. package/build/inputChunkBuffer.js +0 -40
  375. package/build/inputChunkBuffer.test.js +0 -34
  376. package/build/inputCompanion.d.ts +0 -18
  377. package/build/inputCompanion.js +0 -28
  378. package/build/invariantDefined.d.ts +0 -1
  379. package/build/invariantDefined.js +0 -5
  380. package/build/invariantIdentity.d.ts +0 -3
  381. package/build/invariantIdentity.js +0 -5
  382. package/build/javaKeystoreParser.d.ts +0 -2
  383. package/build/javaKeystoreParser.js +0 -7
  384. package/build/jsonParser2.d.ts +0 -3
  385. package/build/jsonParser2.js +0 -52
  386. package/build/jsonParser2.test.js +0 -22
  387. package/build/negativeLookahead.d.ts +0 -2
  388. package/build/negativeLookahead.js +0 -18
  389. package/build/parserCompose.d.ts +0 -3
  390. package/build/parserCompose.js +0 -7
  391. package/build/parserImplementationInvariantInvariant.d.ts +0 -3
  392. package/build/parserImplementationInvariantInvariant.js +0 -15
  393. package/build/parserInvariant.d.ts +0 -4
  394. package/build/parserInvariant.js +0 -11
  395. package/build/promiseFish.d.ts +0 -1
  396. package/build/promiseFish.js +0 -3
  397. package/build/sequenceParser.d.ts +0 -3
  398. package/build/sequenceParser.js +0 -10
  399. package/build/terminatedSequenceParser.d.ts +0 -2
  400. package/build/terminatedSequenceParser.js +0 -24
  401. package/build/unparserInputCompanion.d.ts +0 -15
  402. package/build/unparserInputCompanion.js +0 -13
  403. package/build/zipEntry.d.ts +0 -28
  404. package/build/zipFile.d.ts +0 -32
  405. package/build/zipFileEntry.d.ts +0 -6
  406. package/src/apk.ts +0 -48
  407. package/src/apkParser.test.ts +0 -30
  408. package/src/apkParser.test.ts.snap +0 -0
  409. package/src/apkParser.ts +0 -392
  410. package/src/apkUnparser.test.ts +0 -37
  411. package/src/apkUnparser.ts +0 -120
  412. package/src/invariantDefined.ts +0 -6
  413. package/src/invariantIdentity.ts +0 -8
  414. /package/build/{apk.js → androidPackage.js} +0 -0
  415. /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
  416. /package/build/{apkUnparser.test.d.ts → androidPackageUnparser.test.d.ts} +0 -0
  417. /package/build/{arbitraryDosPermissions.d.ts → dalvikBytecodeUnparser.test.d.ts} +0 -0
  418. /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
  419. /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
  420. /package/build/{jsonParser2.test.d.ts → dalvikExecutableUnparser.test.d.ts} +0 -0
  421. /package/build/{parserParsingInvariant.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
  422. /package/build/{parserParsingInvariant.js → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
  423. /package/build/{zipEntry.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
  424. /package/build/{zipFile.js → fetchCid.test.d.ts} +0 -0
  425. /package/build/{zipFileEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
@@ -1,85 +1,168 @@
1
+ import { type InputReaderState } from './inputReaderState.js';
2
+ import { LazyMessage, NormalLazyMessageError, NoStackCaptureOverheadLazyMessageError } from './lazyMessageError.js';
1
3
 
2
- export class ParserError extends Error {
3
- name = 'ParserError';
4
+ export interface ParserError extends Error {
5
+ position: undefined | number;
6
+ inputReaderSate: undefined | InputReaderState<unknown>;
4
7
  }
5
8
 
6
- export class ParserImplementationError extends ParserError {
7
- name = 'ParserImplementationError';
9
+ export function isParserError(value: unknown): value is ParserError {
10
+ return (
11
+ typeof value === 'object'
12
+ && value !== null
13
+ && value instanceof Error
14
+ && 'position' in value
15
+ && (typeof value.position === 'number' || value.position === undefined)
16
+ && 'inputReaderSate' in value
17
+ && (value.inputReaderSate === undefined || typeof value.inputReaderSate === 'object')
18
+ );
8
19
  }
9
- export class ParserImplementationInvariantError extends ParserImplementationError {
10
- name = 'ParserImplementationInvariantError';
20
+
21
+ type ParserErrorInterface = ParserError;
22
+
23
+ export interface ParserParsingFailedError extends ParserErrorInterface {
24
+ depth: number;
25
+ position: number;
11
26
  }
12
27
 
13
- export class ParserParsingFailedError extends ParserError {
14
- name = 'ParserParsingFailedError';
15
-
16
- constructor(
17
- message: string,
18
- public readonly depth: number,
19
- public readonly position: number,
20
- ) {
21
- super([
22
- '(position: ',
23
- position,
24
- ') ',
25
- message,
26
- ].join(''));
27
- }
28
+ export function isParserParsingFailedError(value: unknown): value is ParserParsingFailedError {
29
+ return (
30
+ typeof value === 'object'
31
+ && value !== null
32
+ && value instanceof Error
33
+ && 'depth' in value
34
+ && typeof value.depth === 'number'
35
+ && 'position' in value
36
+ && typeof value.position === 'number'
37
+ );
28
38
  }
29
39
 
30
- export class ParserParsingJoinError extends ParserParsingFailedError {
31
- name = 'ParserParsingJoinError';
40
+ type ParserParsingFailedErrorInterface = ParserParsingFailedError;
32
41
 
33
- public readonly childErrors: ParserParsingFailedError[] = [];
42
+ export interface ParserParsingJoinError extends ParserParsingFailedErrorInterface {
43
+ childErrors: ParserParsingFailedErrorInterface[];
34
44
  }
35
45
 
36
- export class ParserParsingJoinNoneError extends ParserParsingJoinError {
37
- name = 'ParserParsingJoinNoneError';
46
+ export function isParserParsingJoinError(value: unknown): value is ParserParsingJoinError {
47
+ return (
48
+ typeof value === 'object'
49
+ && value !== null
50
+ && value instanceof Error
51
+ && 'childErrors' in value
52
+ && Array.isArray(value.childErrors)
53
+ && value.childErrors.every((childError: unknown) => isParserParsingFailedError(childError))
54
+ );
38
55
  }
39
56
 
40
- export class ParserParsingJoinAllError extends ParserParsingJoinError {
41
- name = 'ParserParsingJoinAllError';
57
+ type ParserParsingJoinErrorInterface = ParserParsingJoinError;
58
+
59
+ function createParserErrorModule(
60
+ BaseLazyMessageError: typeof NormalLazyMessageError | typeof NoStackCaptureOverheadLazyMessageError,
61
+ ) {
62
+ class ParserError extends BaseLazyMessageError implements ParserErrorInterface {
63
+ name = 'ParserError';
42
64
 
43
- constructor(
44
- message: string,
45
- depth: number,
46
- position: number,
47
- public readonly childErrors: ParserParsingFailedError[],
48
- ) {
49
- super(message, depth, position);
65
+ public position: undefined | number = undefined;
66
+ public inputReaderSate: undefined | InputReaderState<unknown> = undefined;
67
+ }
68
+
69
+ class ParserImplementationError extends ParserError {
70
+ name = 'ParserImplementationError';
71
+ }
72
+ class ParserImplementationInvariantError extends ParserImplementationError {
73
+ name = 'ParserImplementationInvariantError';
50
74
  }
51
- }
52
75
 
53
- export class ParserParsingJoinDeepestError extends ParserParsingJoinError {
54
- name = 'ParserParsingJoinDeepestError';
76
+ class ParserParsingFailedError extends ParserError implements ParserParsingFailedErrorInterface {
77
+ name = 'ParserParsingFailedError';
55
78
 
56
- constructor(
57
- message: string,
58
- depth: number,
59
- position: number,
60
- public readonly childErrors: ParserParsingFailedError[],
61
- ) {
62
- super(message, depth, position);
79
+ constructor(
80
+ message: LazyMessage,
81
+ public readonly depth: number,
82
+ public readonly position: number,
83
+ ) {
84
+ super(message);
85
+ }
63
86
  }
64
- }
65
87
 
66
- export class ParserParsingJoinFurthestError extends ParserParsingJoinError {
67
- name = 'ParserParsingJoinFurthestError';
88
+ class ParserParsingJoinError extends ParserParsingFailedError implements ParserParsingJoinErrorInterface {
89
+ name = 'ParserParsingJoinError';
68
90
 
69
- constructor(
70
- message: string,
71
- depth: number,
72
- position: number,
73
- public readonly childErrors: ParserParsingFailedError[],
74
- ) {
75
- super(message, depth, position);
91
+ public readonly childErrors: ParserParsingFailedErrorInterface[] = [];
76
92
  }
77
- }
78
93
 
79
- export class ParserParsingInvariantError extends ParserParsingFailedError {
80
- name = 'ParserParsingInvariantError';
81
- }
94
+ class ParserParsingJoinNoneError extends ParserParsingJoinError {
95
+ name = 'ParserParsingJoinNoneError';
96
+ }
97
+
98
+ class ParserParsingJoinAllError extends ParserParsingJoinError {
99
+ name = 'ParserParsingJoinAllError';
100
+
101
+ constructor(
102
+ message: LazyMessage,
103
+ depth: number,
104
+ position: number,
105
+ public readonly childErrors: ParserParsingFailedErrorInterface[],
106
+ ) {
107
+ super(message, depth, position);
108
+ }
109
+ }
82
110
 
83
- export class ParserUnexpectedEndOfInputError extends ParserParsingFailedError {
84
- name = 'ParserUnexpectedEndOfInputError';
111
+ class ParserParsingJoinDeepestError extends ParserParsingJoinError {
112
+ name = 'ParserParsingJoinDeepestError';
113
+
114
+ constructor(
115
+ message: LazyMessage,
116
+ depth: number,
117
+ position: number,
118
+ public readonly childErrors: ParserParsingFailedErrorInterface[],
119
+ ) {
120
+ super(message, depth, position);
121
+ }
122
+ }
123
+
124
+ class ParserParsingJoinFurthestError extends ParserParsingJoinError {
125
+ name = 'ParserParsingJoinFurthestError';
126
+
127
+ constructor(
128
+ message: LazyMessage,
129
+ depth: number,
130
+ position: number,
131
+ public readonly childErrors: ParserParsingFailedErrorInterface[],
132
+ ) {
133
+ super(message, depth, position);
134
+ }
135
+ }
136
+
137
+ class ParserParsingInvariantError extends ParserParsingFailedError {
138
+ name = 'ParserParsingInvariantError';
139
+ }
140
+
141
+ class ParserUnexpectedEndOfInputError extends ParserParsingFailedError {
142
+ name = 'ParserUnexpectedEndOfInputError';
143
+ }
144
+
145
+ class ParserUnexpectedRemainingInputError extends ParserParsingFailedError {
146
+ name = 'ParserUnexpectedRemainingInputError';
147
+ }
148
+
149
+ return {
150
+ ParserError,
151
+ ParserImplementationError,
152
+ ParserImplementationInvariantError,
153
+ ParserParsingFailedError,
154
+ ParserParsingJoinError,
155
+ ParserParsingJoinNoneError,
156
+ ParserParsingJoinAllError,
157
+ ParserParsingJoinDeepestError,
158
+ ParserParsingJoinFurthestError,
159
+ ParserParsingInvariantError,
160
+ ParserUnexpectedEndOfInputError,
161
+ ParserUnexpectedRemainingInputError,
162
+ };
85
163
  }
164
+
165
+ export type ParserErrorModule = ReturnType<typeof createParserErrorModule>;
166
+
167
+ export const normalParserErrorModule = createParserErrorModule(NormalLazyMessageError);
168
+ export const noStackCaptureOverheadParserErrorModule = createParserErrorModule(NoStackCaptureOverheadLazyMessageError);
@@ -1,6 +1,6 @@
1
- import { ParserImplementationInvariantError } from './parserError.js';
2
1
  import { type Falsy, customInvariant, type ValueOrAccessor } from './customInvariant.js';
2
+ import { normalParserErrorModule } from './parserError.js';
3
3
 
4
- export function parserImplementationInvariant<T>(value: T, format: ValueOrAccessor<string | string[]>, ...formatArguments: any[]): Exclude<T, Falsy> {
5
- return customInvariant(ParserImplementationInvariantError, value, format, ...formatArguments);
4
+ export function parserImplementationInvariant<T>(value: T, format: ValueOrAccessor<string | string[]>, ...formatArguments: unknown[]): Exclude<T, Falsy> {
5
+ return customInvariant(normalParserErrorModule.ParserImplementationInvariantError, value, format, ...formatArguments);
6
6
  }
@@ -2,8 +2,13 @@
2
2
  export type ParserInputCompanion<Sequence, Element> = {
3
3
  is(value: unknown): value is Sequence;
4
4
  from(elements: Element[]): Sequence;
5
+ concat(sequences: Sequence[]): Sequence;
5
6
  length(sequence: Sequence): number;
6
7
  at(sequence: Sequence, index: number): Element | undefined;
8
+ subsequence(sequence: Sequence, start: number, end: number): Sequence;
9
+ indexOf(sequence: Sequence, element: Element, fromIndex?: number): number;
10
+ indexOfSubsequence(sequence: Sequence, subsequence: Sequence, fromIndex?: number): number;
11
+ equals(sequenceA: Sequence, sequenceB: Sequence): boolean;
7
12
  };
8
13
 
9
14
  export class StringParserInputCompanion implements ParserInputCompanion<string, string> {
@@ -15,6 +20,10 @@ export class StringParserInputCompanion implements ParserInputCompanion<string,
15
20
  return elements.join('');
16
21
  }
17
22
 
23
+ concat(sequences: string[]): string {
24
+ return sequences.join('');
25
+ }
26
+
18
27
  length(sequence: string): number {
19
28
  return sequence.length;
20
29
  }
@@ -22,6 +31,22 @@ export class StringParserInputCompanion implements ParserInputCompanion<string,
22
31
  at(sequence: string, index: number): string | undefined {
23
32
  return sequence.at(index);
24
33
  }
34
+
35
+ subsequence(sequence: string, start: number, end: number): string {
36
+ return sequence.slice(start, end);
37
+ }
38
+
39
+ indexOf(sequence: string, element: string, fromIndex?: number): number {
40
+ return sequence.indexOf(element, fromIndex);
41
+ }
42
+
43
+ indexOfSubsequence(sequence: string, subsequence: string, fromIndex?: number): number {
44
+ return sequence.indexOf(subsequence, fromIndex);
45
+ }
46
+
47
+ equals(sequenceA: string, sequenceB: string): boolean {
48
+ return sequenceA === sequenceB;
49
+ }
25
50
  }
26
51
 
27
52
  export const stringParserInputCompanion = new StringParserInputCompanion();
@@ -35,6 +60,10 @@ export class Uint8ArrayParserInputCompanion implements ParserInputCompanion<Uint
35
60
  return new Uint8Array(elements);
36
61
  }
37
62
 
63
+ concat(sequences: Uint8Array[]): Uint8Array {
64
+ return new Uint8Array(Buffer.concat(sequences));
65
+ }
66
+
38
67
  length(sequence: Uint8Array): number {
39
68
  return sequence.length;
40
69
  }
@@ -42,6 +71,32 @@ export class Uint8ArrayParserInputCompanion implements ParserInputCompanion<Uint
42
71
  at(sequence: Uint8Array, index: number): number | undefined {
43
72
  return sequence.at(index);
44
73
  }
74
+
75
+ subsequence(sequence: Uint8Array, start: number, end: number): Uint8Array {
76
+ return sequence.subarray(start, end);
77
+ }
78
+
79
+ indexOf(sequence: Uint8Array, element: number, fromIndex?: number): number {
80
+ return sequence.indexOf(element, fromIndex);
81
+ }
82
+
83
+ indexOfSubsequence(sequence: Uint8Array, subsequence: Uint8Array, fromIndex?: number): number {
84
+ return Buffer.from(sequence).indexOf(Buffer.from(subsequence), fromIndex);
85
+ }
86
+
87
+ equals(sequenceA: Uint8Array, sequenceB: Uint8Array): boolean {
88
+ if (sequenceA.length !== sequenceB.length) {
89
+ return false;
90
+ }
91
+
92
+ for (const [ index, element ] of sequenceA.entries()) {
93
+ if (element !== sequenceB[index]) {
94
+ return false;
95
+ }
96
+ }
97
+
98
+ return true;
99
+ }
45
100
  }
46
101
 
47
102
  export const uint8ArrayParserInputCompanion = new Uint8ArrayParserInputCompanion();
@@ -1,7 +1,21 @@
1
1
 
2
2
  export function promiseCompose<A, B, C>(
3
- f1: (a: A) => Promise<B>,
3
+ f1: (a: A) => B | Promise<B>,
4
4
  f2: (b: B) => C | Promise<C>,
5
- ): (a: A) => Promise<C> {
6
- return async a => f1(a).then(f2);
5
+ ): (a: A) => C | Promise<C> {
6
+ async function promiseComposed(a: A) {
7
+ const bOrBPromise = f1(a);
8
+
9
+ if (bOrBPromise instanceof Promise) {
10
+ return bOrBPromise.then(f2);
11
+ }
12
+
13
+ return f2(bOrBPromise);
14
+ }
15
+
16
+ Object.defineProperty(promiseComposed, 'name', {
17
+ value: `promiseCompose(${f1.name}, ${f2.name})`,
18
+ });
19
+
20
+ return promiseComposed;
7
21
  }
@@ -0,0 +1,6 @@
1
+
2
+ export async function promiseSettled<T>(promise: Promise<T>): Promise<PromiseSettledResult<T>> {
3
+ const [ promiseSettledResult ] = await Promise.allSettled([ promise ]);
4
+
5
+ return promiseSettledResult;
6
+ }
@@ -0,0 +1,34 @@
1
+ import test from 'ava';
2
+ import { testProp, fc } from '@fast-check/ava';
3
+ import { createSeparatedArrayParser } from './separatedArrayParser.js';
4
+ import { type Parser, runParser, runParserWithRemainingInput } from './parser.js';
5
+ import { stringParserInputCompanion } from './parserInputCompanion.js';
6
+ import { createExactSequenceParser } from './exactSequenceParser.js';
7
+
8
+ test('does not loop forever with a child parser that does not consume anything', async t => {
9
+ const parser: Parser<undefined[], string> = createSeparatedArrayParser(async () => undefined, () => undefined);
10
+ const { output } = await runParserWithRemainingInput(parser, 'foo', stringParserInputCompanion);
11
+
12
+ t.deepEqual(output, []);
13
+ });
14
+
15
+ testProp(
16
+ 'separatedArray',
17
+ [
18
+ fc.array(fc.constant('element')),
19
+ ],
20
+ async (t, elements) => {
21
+ const separatedArrayParser = createSeparatedArrayParser(
22
+ createExactSequenceParser('element'),
23
+ createExactSequenceParser('separator'),
24
+ );
25
+
26
+ const actual = await runParser(separatedArrayParser, elements.join('separator'), stringParserInputCompanion);
27
+ const expected = elements;
28
+
29
+ t.deepEqual(actual, expected);
30
+ },
31
+ {
32
+ verbose: true,
33
+ },
34
+ );
@@ -0,0 +1,55 @@
1
+ import { getParserName, type Parser, setParserName } from './parser.js';
2
+ import { isParserParsingFailedError } from './parserError.js';
3
+ import { promiseCompose } from './promiseCompose.js';
4
+ import { createTupleParser } from './tupleParser.js';
5
+
6
+ export const createSeparatedArrayParser = <ElementOutput, Sequence>(
7
+ elementParser: Parser<ElementOutput, Sequence>,
8
+ separatorParser: Parser<unknown, Sequence>,
9
+ ): Parser<ElementOutput[], Sequence> => {
10
+ const separatorThenElementParser: Parser<ElementOutput, Sequence> = promiseCompose(
11
+ createTupleParser([
12
+ separatorParser,
13
+ elementParser,
14
+ ]),
15
+ ([ , element ]) => element,
16
+ );
17
+
18
+ const separatedArrayParser: Parser<ElementOutput[], Sequence> = async parserContext => {
19
+ let parser = elementParser;
20
+
21
+ const elements: ElementOutput[] = [];
22
+
23
+ while (true) {
24
+ const elementParserContext = parserContext.lookahead();
25
+ const initialPosition = elementParserContext.position;
26
+
27
+ try {
28
+ const element = await parser(elementParserContext);
29
+
30
+ if (elementParserContext.position === initialPosition) {
31
+ break;
32
+ }
33
+
34
+ elements.push(element);
35
+ elementParserContext.unlookahead();
36
+ } catch (error) {
37
+ if (isParserParsingFailedError(error)) {
38
+ break;
39
+ }
40
+
41
+ throw error;
42
+ } finally {
43
+ elementParserContext.dispose();
44
+ }
45
+
46
+ parser = separatorThenElementParser;
47
+ }
48
+
49
+ return elements;
50
+ };
51
+
52
+ setParserName(separatedArrayParser, getParserName(elementParser, 'anonymousSeparatedArrayChild') + '*');
53
+
54
+ return separatedArrayParser;
55
+ };
@@ -0,0 +1,117 @@
1
+ import test from 'ava';
2
+ import { testProp, fc } from '@fast-check/ava';
3
+ import { createSeparatedNonEmptyArrayParser } from './separatedNonEmptyArrayParser.js';
4
+ import { type Parser, runParser, runParserWithRemainingInput } from './parser.js';
5
+ import { stringParserInputCompanion } from './parserInputCompanion.js';
6
+ import { createExactSequenceParser } from './exactSequenceParser.js';
7
+ import { stringFromAsyncIterable } from './stringFromAsyncIterable.js';
8
+
9
+ test('empty input throws error', async t => {
10
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
11
+ createExactSequenceParser('element'),
12
+ createExactSequenceParser(','),
13
+ );
14
+
15
+ await t.throwsAsync(async () => runParser(parser, '', stringParserInputCompanion), {
16
+ any: true,
17
+ message: /Expected .* to match at least once/,
18
+ });
19
+ });
20
+
21
+ test('single element without separator matches', async t => {
22
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
23
+ createExactSequenceParser('element'),
24
+ createExactSequenceParser(','),
25
+ );
26
+
27
+ const result = await runParser(parser, 'element', stringParserInputCompanion);
28
+ t.deepEqual(result, [ 'element' ]);
29
+ });
30
+
31
+ test('two elements with separator matches', async t => {
32
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
33
+ createExactSequenceParser('element'),
34
+ createExactSequenceParser(','),
35
+ );
36
+
37
+ const result = await runParser(parser, 'element,element', stringParserInputCompanion);
38
+ t.deepEqual(result, [ 'element', 'element' ]);
39
+ });
40
+
41
+ test('multiple elements with separator matches', async t => {
42
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
43
+ createExactSequenceParser('a'),
44
+ createExactSequenceParser(','),
45
+ );
46
+
47
+ const result = await runParser(parser, 'a,a,a,a', stringParserInputCompanion);
48
+ t.deepEqual(result, [ 'a', 'a', 'a', 'a' ]);
49
+ });
50
+
51
+ test('does not consume trailing separator', async t => {
52
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
53
+ createExactSequenceParser('element'),
54
+ createExactSequenceParser(','),
55
+ );
56
+
57
+ const { output, remainingInput } = await runParserWithRemainingInput(parser, 'element,element,', stringParserInputCompanion);
58
+ t.deepEqual(output, [ 'element', 'element' ]);
59
+ t.is(await stringFromAsyncIterable(remainingInput!), ',');
60
+ });
61
+
62
+ test('does not loop forever with a child parser that does not consume anything', async t => {
63
+ const parser: Parser<undefined[], string> = createSeparatedNonEmptyArrayParser(
64
+ async () => undefined,
65
+ () => undefined,
66
+ );
67
+
68
+ await t.throwsAsync(async () => runParser(parser, 'foo', stringParserInputCompanion), {
69
+ any: true,
70
+ message: /Expected .* to match at least once/,
71
+ });
72
+ });
73
+
74
+ test('partial match throws error', async t => {
75
+ const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
76
+ createExactSequenceParser('element'),
77
+ createExactSequenceParser(','),
78
+ );
79
+
80
+ await t.throwsAsync(async () => runParser(parser, 'elem', stringParserInputCompanion), {
81
+ any: true,
82
+ message: /Expected .* to match at least once/,
83
+ });
84
+ });
85
+
86
+ testProp(
87
+ 'separatedNonEmptyArray with at least one element',
88
+ [
89
+ fc.array(fc.constant('element'), { minLength: 1 }),
90
+ ],
91
+ async (t, elements) => {
92
+ const separatedNonEmptyArrayParser = createSeparatedNonEmptyArrayParser(
93
+ createExactSequenceParser('element'),
94
+ createExactSequenceParser('separator'),
95
+ );
96
+
97
+ const actual = await runParser(separatedNonEmptyArrayParser, elements.join('separator'), stringParserInputCompanion);
98
+ const expected = elements;
99
+
100
+ t.deepEqual(actual, expected);
101
+ },
102
+ {
103
+ verbose: true,
104
+ },
105
+ );
106
+
107
+ test('separatedNonEmptyArray throws on empty array', async t => {
108
+ const separatedNonEmptyArrayParser = createSeparatedNonEmptyArrayParser(
109
+ createExactSequenceParser('element'),
110
+ createExactSequenceParser('separator'),
111
+ );
112
+
113
+ await t.throwsAsync(async () => runParser(separatedNonEmptyArrayParser, '', stringParserInputCompanion), {
114
+ any: true,
115
+ message: /Expected .* to match at least once/,
116
+ });
117
+ });
@@ -0,0 +1,61 @@
1
+ import { getParserName, type Parser, setParserName } from './parser.js';
2
+ import { isParserParsingFailedError, ParserParsingFailedError } from './parserError.js';
3
+ import { promiseCompose } from './promiseCompose.js';
4
+ import { createTupleParser } from './tupleParser.js';
5
+
6
+ export const createSeparatedNonEmptyArrayParser = <ElementOutput, Sequence>(
7
+ elementParser: Parser<ElementOutput, Sequence>,
8
+ separatorParser: Parser<unknown, Sequence>,
9
+ ): Parser<ElementOutput[], Sequence> => {
10
+ const separatorThenElementParser: Parser<ElementOutput, Sequence> = promiseCompose(
11
+ createTupleParser([
12
+ separatorParser,
13
+ elementParser,
14
+ ]),
15
+ ([ , element ]) => element,
16
+ );
17
+
18
+ const separatedNonEmptyArrayParser: Parser<ElementOutput[], Sequence> = async parserContext => {
19
+ let parser = elementParser;
20
+
21
+ const elements: ElementOutput[] = [];
22
+
23
+ while (true) {
24
+ const elementParserContext = parserContext.lookahead();
25
+ const initialPosition = elementParserContext.position;
26
+
27
+ try {
28
+ const element = await parser(elementParserContext);
29
+
30
+ if (elementParserContext.position === initialPosition) {
31
+ break;
32
+ }
33
+
34
+ elements.push(element);
35
+ elementParserContext.unlookahead();
36
+ } catch (error) {
37
+ if (isParserParsingFailedError(error)) {
38
+ break;
39
+ }
40
+
41
+ throw error;
42
+ } finally {
43
+ elementParserContext.dispose();
44
+ }
45
+
46
+ parser = separatorThenElementParser;
47
+ }
48
+
49
+ parserContext.invariant(
50
+ elements.length > 0,
51
+ 'Expected elementParser (%s) to match at least once',
52
+ getParserName(elementParser, 'anonymousSeparatedNonEmptyArrayChild'),
53
+ );
54
+
55
+ return elements;
56
+ };
57
+
58
+ setParserName(separatedNonEmptyArrayParser, getParserName(elementParser, 'anonymousSeparatedNonEmptyArrayChild') + '+');
59
+
60
+ return separatedNonEmptyArrayParser;
61
+ };