@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
package/src/jsonParser.ts CHANGED
@@ -13,28 +13,27 @@ import { createArrayParser } from './arrayParser.js';
13
13
  import { createParserAccessorParser } from './parserAccessorParser.js';
14
14
  import { createElementParser } from './elementParser.js';
15
15
  import { parserCreatorCompose } from './parserCreatorCompose.js';
16
+ import { createSeparatedArrayParser } from './separatedArrayParser.js';
16
17
 
17
- const whitespaceParser: Parser<unknown, string> = createArrayParser(
18
- createUnionParser([
19
- createExactSequenceParser(' '),
20
- createExactSequenceParser('\t'),
21
- createExactSequenceParser('\r'),
22
- createExactSequenceParser('\n'),
23
- ]),
24
- );
18
+ const whitespaceParser: Parser<unknown, string> = createArrayParser(createUnionParser([
19
+ createExactSequenceParser(' '),
20
+ createExactSequenceParser('\t'),
21
+ createExactSequenceParser('\r'),
22
+ createExactSequenceParser('\n'),
23
+ ]));
25
24
 
26
- const jsonQuoteEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\"'), () => '"');
25
+ const jsonQuoteEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(String.raw`\"`), () => '"');
27
26
  const jsonBackslashEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\\\'), () => '\\');
28
- const jsonSlashEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\/'), () => '/');
29
- const jsonBackspaceEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\b'), () => '\b');
30
- const jsonFormFeedEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\f'), () => '\f');
31
- const jsonNewLineEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\n'), () => '\n');
32
- const jsonCarriageReturnEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\r'), () => '\r');
33
- const jsonTabEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\t'), () => '\t');
27
+ const jsonSlashEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(String.raw`\/`), () => '/');
28
+ const jsonBackspaceEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(String.raw`\b`), () => '\b');
29
+ const jsonFormFeedEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(String.raw`\f`), () => '\f');
30
+ const jsonNewLineEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(String.raw`\n`), () => '\n');
31
+ const jsonCarriageReturnEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(String.raw`\r`), () => '\r');
32
+ const jsonTabEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(String.raw`\t`), () => '\t');
34
33
 
35
34
  const jsonUnicodeEscapeSequenceParser: Parser<string, string> = promiseCompose(
36
35
  createTupleParser([
37
- createExactSequenceParser('\\u'),
36
+ createExactSequenceParser(String.raw`\u`),
38
37
  createFixedLengthSequenceParser<string>(4),
39
38
  ]),
40
39
  ([ , hexCode ]) => String.fromCharCode(Number.parseInt(hexCode, 16)),
@@ -65,7 +64,7 @@ const jsonStringCharacterParser: Parser<string, string> = createDisjunctionParse
65
64
  )(),
66
65
  ]);
67
66
 
68
- const jsonStringParser: Parser<string, string> = promiseCompose(
67
+ export const jsonStringParser: Parser<string, string> = promiseCompose(
69
68
  createTupleParser([
70
69
  createExactSequenceParser('"'),
71
70
  promiseCompose(
@@ -79,28 +78,26 @@ const jsonStringParser: Parser<string, string> = promiseCompose(
79
78
  ([ , string ]) => string,
80
79
  );
81
80
 
82
- const jsonNumberParser: Parser<number, string> = parserCreatorCompose(
83
- () => createArrayParser(
84
- parserCreatorCompose(
85
- () => elementParser,
86
- character => async parserContext => {
87
- parserContext.invariant(
88
- (
89
- character === '-'
90
- || (character >= '0' && character <= '9')
91
- || character === '.'
92
- || character === 'e'
93
- || character === 'E'
94
- || character === '+'
95
- ),
96
- 'Expected "-", "0" to "9", ".", "e", "E", "+", got "%s"',
97
- character,
98
- );
99
-
100
- return character;
101
- },
102
- )(),
103
- ),
81
+ export const jsonNumberParser: Parser<number, string> = parserCreatorCompose(
82
+ () => createArrayParser(parserCreatorCompose(
83
+ () => elementParser,
84
+ character => async parserContext => {
85
+ parserContext.invariant(
86
+ (
87
+ character === '-'
88
+ || (character >= '0' && character <= '9')
89
+ || character === '.'
90
+ || character === 'e'
91
+ || character === 'E'
92
+ || character === '+'
93
+ ),
94
+ 'Expected "-", "0" to "9", ".", "e", "E", "+", got "%s"',
95
+ character,
96
+ );
97
+
98
+ return character;
99
+ },
100
+ )()),
104
101
  characters => async parserContext => {
105
102
  parserContext.invariant(characters.length > 0, 'Expected at least one character');
106
103
 
@@ -189,30 +186,17 @@ const jsonArrayParser: Parser<JsonArray, string> = promiseCompose(
189
186
  createTupleParser([
190
187
  createExactSequenceParser('['),
191
188
  whitespaceParser,
192
- promiseCompose(
193
- createTerminatedArrayParser(
194
- createDisjunctionParser<JsonValue, string>([
195
- promiseCompose(
196
- createTupleParser([
197
- createParserAccessorParser(() => jsonValueParser),
198
- whitespaceParser,
199
- createExactSequenceParser(','),
200
- whitespaceParser,
201
- ]),
202
- ([ value ]) => value,
203
- ),
204
- promiseCompose(
205
- createTupleParser([
206
- createParserAccessorParser(() => jsonValueParser),
207
- whitespaceParser,
208
- ]),
209
- ([ value ]) => value,
210
- ),
211
- ]),
212
- createExactSequenceParser(']'),
213
- ),
214
- ([ values ]) => values,
189
+ createSeparatedArrayParser(
190
+ createParserAccessorParser(() => jsonValueParser),
191
+ createTupleParser([
192
+ whitespaceParser,
193
+ createExactSequenceParser(','),
194
+ whitespaceParser,
195
+ ]),
215
196
  ),
197
+ whitespaceParser,
198
+ createExactSequenceParser(']'),
199
+ whitespaceParser,
216
200
  ]),
217
201
  ([ _bracket, _whitespace, values ]) => values,
218
202
  );
@@ -0,0 +1,21 @@
1
+ import test from 'ava';
2
+ import { NormalLazyMessageError } from './lazyMessageError.js';
3
+
4
+ test('LazyMessageError works', t => {
5
+ const error = new NormalLazyMessageError([
6
+ () => [
7
+ 'Line 1: %s',
8
+ 'Line 2: %s and %s.',
9
+ ],
10
+ 42,
11
+ () => 'foo',
12
+ true,
13
+ ]);
14
+
15
+ error.computeMessage();
16
+
17
+ t.is(
18
+ error.message,
19
+ 'Line 1: 42\nLine 2: foo and true.',
20
+ );
21
+ });
@@ -0,0 +1,88 @@
1
+ import { NoStackCaptureOverheadError } from "./noStackCaptureOverheadError.js";
2
+
3
+ type ValueOrAccessor<T> = T | (() => T);
4
+
5
+ export type LazyMessage =
6
+ | ValueOrAccessor<string | string[]>
7
+ | [ ValueOrAccessor<string | string[]>, ...Array<ValueOrAccessor<unknown>> ]
8
+ ;
9
+
10
+ function formatLazyMessageFormat(
11
+ format: ValueOrAccessor<string | string[]>,
12
+ ): string {
13
+ if (typeof format === 'function') {
14
+ format = format();
15
+ }
16
+
17
+ if (Array.isArray(format)) {
18
+ return format.join('\n');
19
+ }
20
+
21
+ return format;
22
+ }
23
+
24
+ function formatLazyMessageSubstitutions(
25
+ format: string,
26
+ formatArguments: Array<ValueOrAccessor<unknown>>,
27
+ ): string {
28
+ return format.replaceAll('%s', () => {
29
+ const argumentOrAccessor = formatArguments.shift();
30
+ return typeof argumentOrAccessor === 'function' ? argumentOrAccessor() : argumentOrAccessor;
31
+ });
32
+ }
33
+
34
+ export function formatLazyMessage(lazyMessage: LazyMessage): string {
35
+ if (Array.isArray(lazyMessage)) {
36
+ const [ format, ...formatArguments ] = lazyMessage;
37
+ const formattedFormat = formatLazyMessageFormat(format);
38
+ return formatLazyMessageSubstitutions(formattedFormat, formatArguments);
39
+ } else {
40
+ return formatLazyMessageFormat(lazyMessage);
41
+ }
42
+ }
43
+
44
+ export interface LazyMessageError extends Error {
45
+ computeMessage(): void;
46
+ }
47
+
48
+ export function createLazyMessageErrorClass(
49
+ BaseError: typeof NoStackCaptureOverheadError | typeof Error,
50
+ ) {
51
+ return class LazyMessageError extends (BaseError as typeof Error) implements LazyMessageError {
52
+ name = 'LazyMessageError';
53
+
54
+ _lazyMessage: undefined | LazyMessage;
55
+
56
+ constructor(
57
+ lazyMessage: LazyMessage,
58
+ ) {
59
+ super('LAZY_MESSAGE');
60
+ this._lazyMessage = lazyMessage;
61
+ }
62
+
63
+ computeMessage(): void {
64
+ if (this._lazyMessage === undefined) {
65
+ return;
66
+ }
67
+
68
+ this.message = formatLazyMessage(this._lazyMessage);
69
+ this.stack = this.stack?.replace('LAZY_MESSAGE', this.message);
70
+ delete this._lazyMessage;
71
+ }
72
+ }
73
+ }
74
+
75
+ export const NormalLazyMessageError = createLazyMessageErrorClass(Error);
76
+ export const NoStackCaptureOverheadLazyMessageError = createLazyMessageErrorClass(NoStackCaptureOverheadError);
77
+
78
+ export function isLazyMessageError(
79
+ value: unknown,
80
+ ): value is LazyMessageError {
81
+ return (
82
+ typeof value === 'object'
83
+ && value !== null
84
+ && value instanceof Error
85
+ && '_lazyMessage' in value
86
+ && typeof (value as Record<string, unknown>).computeMessage === 'function'
87
+ );
88
+ }
@@ -0,0 +1,173 @@
1
+ import { testProp, fc } from '@fast-check/ava';
2
+ import test from 'ava';
3
+ // @ts-expect-error
4
+ import leb128 from 'leb128';
5
+ import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
6
+ import { runParser } from './parser.js';
7
+ import {
8
+ uleb128Parser, sleb128Parser, uleb128NumberParser, sleb128NumberParser,
9
+ } from './leb128Parser.js';
10
+
11
+ test('sleb128, uleb128, uleb128p1', async t => {
12
+ for (const [
13
+ input, expectedSleb128, expectedUleb128,
14
+ ] of [
15
+ [ Buffer.from('00', 'hex'), 0n, 0n ],
16
+ [ Buffer.from('01', 'hex'), 1n, 1n ],
17
+ [ Buffer.from('7f', 'hex'), -1n, 127n ],
18
+ [ Buffer.from('807f', 'hex'), -128n, 16_256n ],
19
+ ] as const) {
20
+ const actualSleb128 = await runParser(sleb128Parser, input, uint8ArrayParserInputCompanion);
21
+ const actualUleb128 = await runParser(uleb128Parser, input, uint8ArrayParserInputCompanion);
22
+
23
+ t.is(actualSleb128, expectedSleb128, 'sleb128');
24
+ t.is(actualUleb128, expectedUleb128, 'uleb128');
25
+ }
26
+
27
+ for (const [
28
+ input, expectedUleb128,
29
+ ] of [
30
+ [ new Uint8Array([ 2 ]), 2n ],
31
+ [ new Uint8Array([ 127 ]), 127n ],
32
+ [ new Uint8Array([ 0 + 0x80, 1 ]), 128n ],
33
+ [ new Uint8Array([ 1 + 0x80, 1 ]), 129n ],
34
+ [ new Uint8Array([ 57 + 0x80, 100 ]), 12_857n ],
35
+ ] as const) {
36
+ const actualUleb128 = await runParser(uleb128Parser, input, uint8ArrayParserInputCompanion);
37
+
38
+ t.is(actualUleb128, expectedUleb128, 'uleb128');
39
+ }
40
+
41
+ for (const [
42
+ input, expectedSleb128,
43
+ ] of [
44
+ [ new Uint8Array([ 2 ]), 2n ],
45
+ [ new Uint8Array([ 0x7E ]), -2n ],
46
+ [ new Uint8Array([ 127 + 0x80, 0 ]), 127n ],
47
+ [ new Uint8Array([ 1 + 0x80, 0x7F ]), -127n ],
48
+ [ new Uint8Array([ 0 + 0x80, 1 ]), 128n ],
49
+ [ new Uint8Array([ 0 + 0x80, 0x7F ]), -128n ],
50
+ [ new Uint8Array([ 1 + 0x80, 1 ]), 129n ],
51
+ [ new Uint8Array([ 0x7F + 0x80, 0x7E ]), -129n ],
52
+ ] as const) {
53
+ const actualSleb128 = await runParser(sleb128Parser, input, uint8ArrayParserInputCompanion);
54
+
55
+ t.is(actualSleb128, expectedSleb128, 'sleb128');
56
+ }
57
+ });
58
+
59
+ testProp(
60
+ 'uleb128NumberParser on small number',
61
+ [
62
+ fc.nat(),
63
+ ],
64
+ async (t, natural) => {
65
+ const uleb128 = leb128.unsigned.encode(natural);
66
+
67
+ const actualUleb128 = await runParser(uleb128NumberParser, uleb128, uint8ArrayParserInputCompanion);
68
+
69
+ t.is(actualUleb128, natural, 'uleb128');
70
+ },
71
+ {
72
+ verbose: true,
73
+ },
74
+ );
75
+
76
+ testProp(
77
+ 'sleb128NumberParser on small number',
78
+ [
79
+ fc.integer(),
80
+ ],
81
+ async (t, integer) => {
82
+ const sleb128 = leb128.signed.encode(integer);
83
+
84
+ const actualSleb128 = await runParser(sleb128NumberParser, sleb128, uint8ArrayParserInputCompanion);
85
+
86
+ t.is(actualSleb128, integer, 'sleb128');
87
+ },
88
+ {
89
+ verbose: true,
90
+ },
91
+ );
92
+
93
+ // TODO?
94
+ testProp.skip(
95
+ 'uleb128NumberParser on large number',
96
+ [
97
+ fc.maxSafeNat(),
98
+ ],
99
+ async (t, natural) => {
100
+ const uleb128 = leb128.unsigned.encode(natural);
101
+
102
+ if (natural > (2 ** 32) - 1) {
103
+ await t.throwsAsync(async () => runParser(uleb128NumberParser, uleb128, uint8ArrayParserInputCompanion));
104
+
105
+ return;
106
+ }
107
+
108
+ const actualUleb128 = await runParser(uleb128NumberParser, uleb128, uint8ArrayParserInputCompanion);
109
+
110
+ t.is(actualUleb128, natural, 'uleb128');
111
+ },
112
+ {
113
+ verbose: true,
114
+ },
115
+ );
116
+
117
+ // TODO?
118
+ testProp.skip(
119
+ 'sleb128NumberParser on large number',
120
+ [
121
+ fc.maxSafeInteger(),
122
+ ],
123
+ async (t, integer) => {
124
+ const sleb128 = leb128.signed.encode(integer);
125
+
126
+ if (integer > (2 ** 32) - 1 || integer < -(2 ** 32)) {
127
+ await t.throwsAsync(async () => runParser(sleb128NumberParser, sleb128, uint8ArrayParserInputCompanion));
128
+
129
+ return;
130
+ }
131
+
132
+ const actualSleb128 = await runParser(sleb128NumberParser, sleb128, uint8ArrayParserInputCompanion);
133
+
134
+ t.is(actualSleb128, integer, 'sleb128');
135
+ },
136
+ {
137
+ verbose: true,
138
+ },
139
+ );
140
+
141
+ testProp(
142
+ 'uleb128Parser on bigint',
143
+ [
144
+ fc.bigInt({ min: 0n }),
145
+ ],
146
+ async (t, bigInt) => {
147
+ const uleb128 = leb128.unsigned.encode(bigInt);
148
+
149
+ const actualUleb128 = await runParser(uleb128Parser, uleb128, uint8ArrayParserInputCompanion);
150
+
151
+ t.is(actualUleb128, bigInt, 'uleb128');
152
+ },
153
+ {
154
+ verbose: true,
155
+ },
156
+ );
157
+
158
+ testProp(
159
+ 'sleb128Parser on bigint',
160
+ [
161
+ fc.bigInt(),
162
+ ],
163
+ async (t, bigInt) => {
164
+ const sleb128 = leb128.signed.encode(bigInt);
165
+
166
+ const actualSleb128 = await runParser(sleb128Parser, sleb128, uint8ArrayParserInputCompanion);
167
+
168
+ t.is(actualSleb128, bigInt, 'sleb128');
169
+ },
170
+ {
171
+ verbose: true,
172
+ },
173
+ );
@@ -0,0 +1,125 @@
1
+ import { type Parser } from './parser.js';
2
+
3
+ export const uleb128Parser: Parser<bigint, Uint8Array> = async parserContext => {
4
+ let leastSignificantValueBitIndex = 0n;
5
+ let value = 0n;
6
+
7
+ while (true) {
8
+ const byte = await parserContext.read(0);
9
+ const byteValue = BigInt(byte & 0b0111_1111);
10
+ const byteNotLast = BigInt(byte & 0b1000_0000);
11
+
12
+ value |= byteValue << leastSignificantValueBitIndex;
13
+
14
+ if (byteNotLast) {
15
+ leastSignificantValueBitIndex += 7n;
16
+ continue;
17
+ }
18
+
19
+ break;
20
+ }
21
+
22
+ return value;
23
+ };
24
+
25
+ export const sleb128Parser: Parser<bigint, Uint8Array> = async parserContext => {
26
+ let value = 0n;
27
+ let leastSignificantValueBitIndex = 0n;
28
+
29
+ while (true) {
30
+ const byte = await parserContext.read(0);
31
+ const byteValue = BigInt(byte & 0b0111_1111);
32
+ const byteNotLast = BigInt(byte & 0b1000_0000);
33
+
34
+ value |= byteValue << leastSignificantValueBitIndex;
35
+ leastSignificantValueBitIndex += 7n;
36
+
37
+ if (byteNotLast) {
38
+ continue;
39
+ }
40
+
41
+ const mostSignificantInputBit = byte & 0b0100_0000;
42
+
43
+ if (mostSignificantInputBit) {
44
+ value |= (~0n << leastSignificantValueBitIndex);
45
+ }
46
+
47
+ break;
48
+ }
49
+
50
+ return value;
51
+ };
52
+
53
+ export const uleb128NumberParser: Parser<number, Uint8Array> = async parserContext => {
54
+ const value = await uleb128Parser(parserContext);
55
+
56
+ parserContext.invariant(
57
+ Number(value) <= Number.MAX_SAFE_INTEGER,
58
+ 'Value is too large to be represented as a number: %s',
59
+ value,
60
+ );
61
+
62
+ return Number(value);
63
+ };
64
+
65
+ export const sleb128NumberParser: Parser<number, Uint8Array> = async parserContext => {
66
+ const value = await sleb128Parser(parserContext);
67
+
68
+ parserContext.invariant(
69
+ Number(value) >= Number.MIN_SAFE_INTEGER && Number(value) <= Number.MAX_SAFE_INTEGER,
70
+ 'Value is too large to be represented as a number: %s',
71
+ value,
72
+ );
73
+
74
+ return Number(value);
75
+ };
76
+
77
+ export const uleb128UnsafeNumberParser: Parser<number, Uint8Array> = async parserContext => {
78
+ let leastSignificantValueBitIndex = 0;
79
+ let value = 0;
80
+
81
+ while (true) {
82
+ const byte = await parserContext.read(0);
83
+ const byteValue = byte & 0b0111_1111;
84
+ const byteNotLast = byte & 0b1000_0000;
85
+
86
+ value |= byteValue << leastSignificantValueBitIndex;
87
+
88
+ if (byteNotLast) {
89
+ leastSignificantValueBitIndex += 7;
90
+ continue;
91
+ }
92
+
93
+ break;
94
+ }
95
+
96
+ return value;
97
+ };
98
+
99
+ export const sleb128UnsafeNumberParser: Parser<number, Uint8Array> = async parserContext => {
100
+ let value = 0;
101
+ let leastSignificantValueBitIndex = 0;
102
+
103
+ while (true) {
104
+ const byte = await parserContext.read(0);
105
+ const byteValue = byte & 0b0111_1111;
106
+ const byteNotLast = byte & 0b1000_0000;
107
+
108
+ value |= byteValue << leastSignificantValueBitIndex;
109
+ leastSignificantValueBitIndex += 7;
110
+
111
+ if (byteNotLast) {
112
+ continue;
113
+ }
114
+
115
+ const mostSignificantInputBit = byte & 0b0100_0000;
116
+
117
+ if (leastSignificantValueBitIndex < 32 && mostSignificantInputBit) {
118
+ value |= (~0 << leastSignificantValueBitIndex);
119
+ }
120
+
121
+ break;
122
+ }
123
+
124
+ return value;
125
+ };
@@ -0,0 +1,19 @@
1
+ import { getParserName, setParserName, type Parser } from './parser.js';
2
+
3
+ export const createLookaheadParser = <Output, Sequence>(
4
+ childParser: Parser<Output, Sequence>,
5
+ ): Parser<Output, Sequence> => {
6
+ const lookaheadParser: Parser<Output, Sequence> = async parserContext => {
7
+ const childParserContext = parserContext.lookahead();
8
+
9
+ try {
10
+ return await childParser(childParserContext);
11
+ } finally {
12
+ childParserContext.dispose();
13
+ }
14
+ };
15
+
16
+ setParserName(lookaheadParser, `(?=${getParserName(childParser)})`);
17
+
18
+ return lookaheadParser;
19
+ };
@@ -0,0 +1,49 @@
1
+ import * as fc from 'fast-check';
2
+ import { testProp } from '@fast-check/ava';
3
+ import { createNegativeLookaheadParser } from './negativeLookaheadParser.js';
4
+ import { createExactSequenceParser } from './exactSequenceParser.js';
5
+ import { runParser } from './parser.js';
6
+ import { stringParserInputCompanion } from './parserInputCompanion.js';
7
+ import { createTupleParser } from './tupleParser.js';
8
+
9
+ testProp(
10
+ 'negativeLookaheadParser',
11
+ [
12
+ fc.tuple(
13
+ fc.string({
14
+ minLength: 1,
15
+ }),
16
+ fc.string({
17
+ minLength: 1,
18
+ }),
19
+ ).filter(([ a, b ]) => !a.startsWith(b)),
20
+ ],
21
+ async (t, [ stringA, stringB ]) => {
22
+ const result = await runParser(
23
+ createTupleParser([
24
+ createNegativeLookaheadParser(createExactSequenceParser(stringB)),
25
+ createExactSequenceParser(stringA + stringB),
26
+ ]),
27
+ stringA + stringB,
28
+ stringParserInputCompanion,
29
+ );
30
+
31
+ t.deepEqual(result, [ undefined, stringA + stringB ]);
32
+
33
+ await t.throwsAsync(async () => runParser(
34
+ createTupleParser([
35
+ createNegativeLookaheadParser(createExactSequenceParser(stringA)),
36
+ createExactSequenceParser(stringA + stringB),
37
+ ]),
38
+ stringA + stringB,
39
+ stringParserInputCompanion,
40
+ ), {
41
+ any: true,
42
+ name: 'ParserParsingInvariantError',
43
+ message: /lookahead/,
44
+ });
45
+ },
46
+ {
47
+ verbose: true,
48
+ },
49
+ );
@@ -1,24 +1,36 @@
1
- import { getParserName, type Parser } from './parser.js';
2
- import { ParserParsingFailedError } from './parserError.js';
1
+ import { getParserName, setParserName, type Parser } from './parser.js';
2
+ import { isParserParsingFailedError, ParserParsingFailedError } from './parserError.js';
3
3
 
4
4
  export const createNegativeLookaheadParser = <Sequence>(
5
5
  childParser: Parser<unknown, Sequence>,
6
- ): Parser<void, Sequence> => async parserContext => {
7
- const childParserContext = parserContext.lookahead();
8
- try {
9
- await childParser(childParserContext);
6
+ ): Parser<void, Sequence> => {
7
+ const negativeLookaheadParser: Parser<void, Sequence> = async parserContext => {
8
+ const childParserContext = parserContext.lookahead();
9
+
10
+ let childParserSuccess: boolean;
11
+
12
+ try {
13
+ await childParser(childParserContext);
14
+
15
+ childParserSuccess = true;
16
+ } catch (error) {
17
+ if (!isParserParsingFailedError(error)) {
18
+ throw error;
19
+ }
20
+
21
+ childParserSuccess = false;
22
+ } finally {
23
+ childParserContext.dispose();
24
+ }
25
+
10
26
  parserContext.invariant(
11
- false,
27
+ !childParserSuccess,
12
28
  'Negative lookahead assertion failed for child parser %s.',
13
29
  getParserName(childParser),
14
30
  );
15
- } catch (error) {
16
- if (error instanceof ParserParsingFailedError) {
17
- return;
18
- }
31
+ };
32
+
33
+ setParserName(negativeLookaheadParser, `(?!${getParserName(childParser)})`);
19
34
 
20
- throw error;
21
- } finally {
22
- childParserContext.dispose();
23
- }
35
+ return negativeLookaheadParser;
24
36
  };
@@ -0,0 +1,17 @@
1
+ import test from 'ava';
2
+ import util from 'util';
3
+ import { NoStackCaptureOverheadError } from './noStackCaptureOverheadError.js';
4
+
5
+ test('NoStackCaptureOverheadError works', t => {
6
+ const error = new NoStackCaptureOverheadError('Test message');
7
+
8
+ t.is(error.name, 'NoStackCaptureOverheadError');
9
+ t.is(error.message, 'Test message');
10
+ t.true(error instanceof Error, 'error is instance of Error');
11
+ t.true(error instanceof NoStackCaptureOverheadError, 'error is instance of NoStackCaptureOverheadError');
12
+ t.false(new Error() instanceof NoStackCaptureOverheadError, 'regular Error is not instance of NoStackCaptureOverheadError');
13
+ if (typeof (Error as any).isError === 'function') {
14
+ t.false((Error as any).isError(error), 'Error.isError does not identify error as Error');
15
+ }
16
+ t.false(util.types.isNativeError(error), 'util.types.isNativeError does not identify error as native Error');
17
+ });