@futpib/parser 1.0.4 → 1.0.6

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 (250) hide show
  1. package/.claude/settings.local.json +24 -0
  2. package/.github/workflows/main.yml +1 -0
  3. package/build/androidPackageParser.js +30 -32
  4. package/build/arbitraryDalvikBytecode.d.ts +3 -3
  5. package/build/arbitraryDalvikBytecode.js +33 -27
  6. package/build/arbitraryDalvikExecutable.js +55 -17
  7. package/build/arbitraryJava.d.ts +31 -0
  8. package/build/arbitraryJava.js +532 -0
  9. package/build/arbitraryJavaScript.d.ts +3 -0
  10. package/build/arbitraryJavaScript.js +263 -0
  11. package/build/arbitraryJavascript.d.ts +3 -0
  12. package/build/arbitraryJavascript.js +263 -0
  13. package/build/arbitraryZig.d.ts +3 -0
  14. package/build/arbitraryZig.js +240 -0
  15. package/build/arbitraryZipStream.d.ts +1 -1
  16. package/build/arrayParser.js +72 -13
  17. package/build/backsmali.d.ts +4 -3
  18. package/build/backsmali.js +26 -6
  19. package/build/bash.d.ts +6 -1
  20. package/build/bashParser.js +131 -90
  21. package/build/bashParser.test.js +162 -0
  22. package/build/bashParserEdgeCases.test.d.ts +1 -0
  23. package/build/bashParserEdgeCases.test.js +117 -0
  24. package/build/dalvikBytecodeParser/addressConversion.d.ts +110 -0
  25. package/build/dalvikBytecodeParser/addressConversion.js +334 -0
  26. package/build/dalvikBytecodeParser/formatParsers.d.ts +7 -6
  27. package/build/dalvikBytecodeParser/formatParsers.js +13 -14
  28. package/build/dalvikBytecodeParser.d.ts +60 -31
  29. package/build/dalvikBytecodeParser.js +92 -35
  30. package/build/dalvikBytecodeParser.test-d.d.ts +1 -0
  31. package/build/dalvikBytecodeParser.test-d.js +268 -0
  32. package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +9 -8
  33. package/build/dalvikBytecodeUnparser/formatUnparsers.js +13 -12
  34. package/build/dalvikBytecodeUnparser.d.ts +2 -2
  35. package/build/dalvikBytecodeUnparser.js +23 -23
  36. package/build/dalvikBytecodeUnparser.test.js +7 -7
  37. package/build/dalvikExecutable.d.ts +3 -3
  38. package/build/dalvikExecutable.test-d.d.ts +1 -0
  39. package/build/dalvikExecutable.test-d.js +59 -0
  40. package/build/dalvikExecutableParser/typedNumbers.d.ts +18 -0
  41. package/build/dalvikExecutableParser/typedNumbers.js +3 -0
  42. package/build/dalvikExecutableParser.d.ts +2 -1
  43. package/build/dalvikExecutableParser.js +96 -77
  44. package/build/dalvikExecutableParser.test.js +24 -3
  45. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +3 -0
  46. package/build/dalvikExecutableUnparser/poolScanners.d.ts +2 -2
  47. package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +3 -3
  48. package/build/dalvikExecutableUnparser/sectionUnparsers.js +26 -11
  49. package/build/dalvikExecutableUnparser.d.ts +2 -2
  50. package/build/dalvikExecutableUnparser.test.js +2 -1
  51. package/build/disjunctionParser.d.ts +5 -3
  52. package/build/disjunctionParser.js +79 -17
  53. package/build/disjunctionParser.test-d.d.ts +1 -0
  54. package/build/disjunctionParser.test-d.js +72 -0
  55. package/build/elementSwitchParser.d.ts +4 -0
  56. package/build/{exactElementSwitchParser.js → elementSwitchParser.js} +3 -4
  57. package/build/elementSwitchParser.test-d.d.ts +1 -0
  58. package/build/elementSwitchParser.test-d.js +44 -0
  59. package/build/exactSequenceParser.d.ts +4 -2
  60. package/build/exactSequenceParser.test-d.d.ts +1 -0
  61. package/build/exactSequenceParser.test-d.js +36 -0
  62. package/build/fetchCid.js +2 -66
  63. package/build/index.d.ts +3 -2
  64. package/build/index.js +2 -1
  65. package/build/index.test.js +16 -1
  66. package/build/inputReader.d.ts +10 -0
  67. package/build/inputReader.js +36 -0
  68. package/build/java.d.ts +502 -0
  69. package/build/java.js +2 -0
  70. package/build/javaKeyStoreParser.js +14 -17
  71. package/build/javaParser.d.ts +51 -0
  72. package/build/javaParser.js +1538 -0
  73. package/build/javaParser.test.d.ts +1 -0
  74. package/build/javaParser.test.js +1287 -0
  75. package/build/javaScript.d.ts +35 -0
  76. package/build/javaScript.js +1 -0
  77. package/build/javaScriptParser.d.ts +9 -0
  78. package/build/javaScriptParser.js +34 -0
  79. package/build/javaScriptUnparser.d.ts +3 -0
  80. package/build/javaScriptUnparser.js +4 -0
  81. package/build/javaScriptUnparser.test.d.ts +1 -0
  82. package/build/javaScriptUnparser.test.js +24 -0
  83. package/build/javaUnparser.d.ts +2 -0
  84. package/build/javaUnparser.js +519 -0
  85. package/build/javaUnparser.test.d.ts +1 -0
  86. package/build/javaUnparser.test.js +24 -0
  87. package/build/javascript.d.ts +35 -0
  88. package/build/javascript.js +1 -0
  89. package/build/javascriptParser.d.ts +9 -0
  90. package/build/javascriptParser.js +34 -0
  91. package/build/javascriptUnparser.d.ts +3 -0
  92. package/build/javascriptUnparser.js +4 -0
  93. package/build/javascriptUnparser.test.d.ts +1 -0
  94. package/build/javascriptUnparser.test.js +24 -0
  95. package/build/jsonParser.js +2 -12
  96. package/build/lazyMessageError.d.ts +3 -0
  97. package/build/lookaheadParser.js +60 -3
  98. package/build/negativeLookaheadParser.js +70 -11
  99. package/build/nonEmptyArrayParser.js +72 -13
  100. package/build/objectParser.d.ts +12 -0
  101. package/build/objectParser.js +31 -0
  102. package/build/objectParser.test-d.d.ts +1 -0
  103. package/build/objectParser.test-d.js +112 -0
  104. package/build/objectParser.test.d.ts +1 -0
  105. package/build/objectParser.test.js +55 -0
  106. package/build/optionalParser.js +69 -10
  107. package/build/parser.d.ts +4 -0
  108. package/build/parser.js +3 -1
  109. package/build/parser.test.js +114 -1
  110. package/build/parserConsumedSequenceParser.js +66 -7
  111. package/build/parserContext.d.ts +6 -0
  112. package/build/parserContext.js +20 -11
  113. package/build/parserError.d.ts +119 -27
  114. package/build/parserError.js +16 -8
  115. package/build/regexpParser.js +33 -3
  116. package/build/regexpParser.test.js +31 -0
  117. package/build/regularExpressionParser.js +35 -15
  118. package/build/separatedArrayParser.js +73 -14
  119. package/build/separatedNonEmptyArrayParser.js +73 -14
  120. package/build/sliceBoundedParser.js +62 -5
  121. package/build/smaliParser.d.ts +7 -7
  122. package/build/smaliParser.js +185 -268
  123. package/build/smaliParser.test.js +58 -0
  124. package/build/stringEscapes.d.ts +5 -0
  125. package/build/stringEscapes.js +244 -0
  126. package/build/symbolicExpression.d.ts +29 -0
  127. package/build/symbolicExpression.js +1 -0
  128. package/build/symbolicExpressionParser.d.ts +4 -0
  129. package/build/symbolicExpressionParser.js +123 -0
  130. package/build/symbolicExpressionParser.test.d.ts +1 -0
  131. package/build/symbolicExpressionParser.test.js +289 -0
  132. package/build/terminatedArrayParser.js +113 -38
  133. package/build/terminatedArrayParser.test.js +4 -2
  134. package/build/tupleParser.d.ts +7 -15
  135. package/build/tupleParser.js +1 -0
  136. package/build/unionParser.d.ts +5 -3
  137. package/build/unionParser.js +7 -2
  138. package/build/unionParser.test-d.d.ts +1 -0
  139. package/build/unionParser.test-d.js +72 -0
  140. package/build/unionParser.test.js +10 -11
  141. package/build/zig.d.ts +280 -0
  142. package/build/zig.js +2 -0
  143. package/build/zigParser.d.ts +3 -0
  144. package/build/zigParser.js +1119 -0
  145. package/build/zigParser.test.d.ts +1 -0
  146. package/build/zigParser.test.js +1590 -0
  147. package/build/zigUnparser.d.ts +2 -0
  148. package/build/zigUnparser.js +460 -0
  149. package/build/zigUnparser.test.d.ts +1 -0
  150. package/build/zigUnparser.test.js +24 -0
  151. package/build/zipParser.js +19 -32
  152. package/build/zipUnparser.js +19 -7
  153. package/build/zipUnparser.test.js +1 -1
  154. package/node_modules-@types/s-expression/index.d.ts +5 -0
  155. package/package.json +24 -6
  156. package/src/androidPackageParser.ts +33 -60
  157. package/src/arbitraryDalvikBytecode.ts +39 -31
  158. package/src/arbitraryDalvikExecutable.ts +65 -20
  159. package/src/arbitraryJava.ts +804 -0
  160. package/src/arbitraryJavaScript.ts +410 -0
  161. package/src/arbitraryZig.ts +380 -0
  162. package/src/arrayParser.ts +1 -3
  163. package/src/backsmali.ts +35 -4
  164. package/src/bash.ts +8 -1
  165. package/src/bashParser.test.ts +258 -0
  166. package/src/bashParser.ts +180 -143
  167. package/src/dalvikBytecodeParser/addressConversion.ts +496 -0
  168. package/src/dalvikBytecodeParser/formatParsers.ts +19 -29
  169. package/src/dalvikBytecodeParser.test-d.ts +310 -0
  170. package/src/dalvikBytecodeParser.ts +194 -69
  171. package/src/dalvikBytecodeUnparser/formatUnparsers.ts +27 -26
  172. package/src/dalvikBytecodeUnparser.test.ts +7 -7
  173. package/src/dalvikBytecodeUnparser.ts +31 -30
  174. package/src/dalvikExecutable.test-d.ts +132 -0
  175. package/src/dalvikExecutable.ts +3 -3
  176. package/src/dalvikExecutableParser/typedNumbers.ts +11 -0
  177. package/src/dalvikExecutableParser.test.ts +37 -3
  178. package/src/dalvikExecutableParser.test.ts.md +163 -2
  179. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  180. package/src/dalvikExecutableParser.ts +121 -139
  181. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +4 -0
  182. package/src/dalvikExecutableUnparser/poolScanners.ts +6 -6
  183. package/src/dalvikExecutableUnparser/sectionUnparsers.ts +38 -14
  184. package/src/dalvikExecutableUnparser.test.ts +3 -2
  185. package/src/dalvikExecutableUnparser.ts +4 -4
  186. package/src/disjunctionParser.test-d.ts +105 -0
  187. package/src/disjunctionParser.ts +18 -15
  188. package/src/elementSwitchParser.test-d.ts +74 -0
  189. package/src/elementSwitchParser.ts +51 -0
  190. package/src/exactSequenceParser.test-d.ts +43 -0
  191. package/src/exactSequenceParser.ts +13 -8
  192. package/src/fetchCid.ts +2 -76
  193. package/src/index.test.ts +22 -1
  194. package/src/index.ts +7 -1
  195. package/src/inputReader.ts +53 -0
  196. package/src/java.ts +708 -0
  197. package/src/javaKeyStoreParser.ts +18 -32
  198. package/src/javaParser.test.ts +1592 -0
  199. package/src/javaParser.ts +2640 -0
  200. package/src/javaScript.ts +36 -0
  201. package/src/javaScriptParser.ts +57 -0
  202. package/src/javaScriptUnparser.test.ts +37 -0
  203. package/src/javaScriptUnparser.ts +7 -0
  204. package/src/javaUnparser.test.ts +37 -0
  205. package/src/javaUnparser.ts +640 -0
  206. package/src/jsonParser.ts +6 -27
  207. package/src/lookaheadParser.ts +2 -6
  208. package/src/negativeLookaheadParser.ts +1 -3
  209. package/src/nonEmptyArrayParser.ts +1 -3
  210. package/src/objectParser.test-d.ts +152 -0
  211. package/src/objectParser.test.ts +71 -0
  212. package/src/objectParser.ts +69 -0
  213. package/src/optionalParser.ts +1 -3
  214. package/src/parser.test.ts +151 -4
  215. package/src/parser.ts +11 -1
  216. package/src/parserConsumedSequenceParser.ts +2 -4
  217. package/src/parserContext.ts +26 -11
  218. package/src/parserError.ts +17 -3
  219. package/src/regexpParser.test.ts +78 -0
  220. package/src/regexpParser.ts +35 -3
  221. package/src/regularExpressionParser.ts +36 -37
  222. package/src/separatedArrayParser.ts +1 -3
  223. package/src/separatedNonEmptyArrayParser.ts +1 -3
  224. package/src/sliceBoundedParser.test.ts +2 -2
  225. package/src/sliceBoundedParser.ts +15 -19
  226. package/src/smaliParser.test.ts +64 -0
  227. package/src/smaliParser.test.ts.md +12 -12
  228. package/src/smaliParser.test.ts.snap +0 -0
  229. package/src/smaliParser.ts +246 -534
  230. package/src/stringEscapes.ts +253 -0
  231. package/src/symbolicExpression.ts +17 -0
  232. package/src/symbolicExpressionParser.test.ts +466 -0
  233. package/src/symbolicExpressionParser.ts +190 -0
  234. package/src/terminatedArrayParser.test.ts +9 -6
  235. package/src/terminatedArrayParser.ts +25 -29
  236. package/src/tupleParser.ts +21 -18
  237. package/src/unionParser.test-d.ts +105 -0
  238. package/src/unionParser.test.ts +18 -17
  239. package/src/unionParser.ts +28 -16
  240. package/src/zig.ts +411 -0
  241. package/src/zigParser.test.ts +1693 -0
  242. package/src/zigParser.ts +1745 -0
  243. package/src/zigUnparser.test.ts +37 -0
  244. package/src/zigUnparser.ts +615 -0
  245. package/src/zipParser.ts +20 -56
  246. package/src/zipUnparser.test.ts +1 -1
  247. package/src/zipUnparser.ts +22 -7
  248. package/tsconfig.json +2 -2
  249. package/build/exactElementSwitchParser.d.ts +0 -3
  250. package/src/exactElementSwitchParser.ts +0 -41
@@ -19,7 +19,7 @@ export const createTerminatedArrayParserNaive = <ElementOutput, TerminatorOutput
19
19
  getParserName(terminatorParser, 'anonymousTerminator'),
20
20
  );
21
21
 
22
- const elementOrTerminatorParser = createUnionParser<ElementOutput | Terminated<TerminatorOutput>, Sequence>([
22
+ const elementOrTerminatorParser = createUnionParser([
23
23
  elementParser,
24
24
  promiseCompose(terminatorParser, terminatorValue => new Terminated(terminatorValue)),
25
25
  ]);
@@ -51,36 +51,36 @@ export const createTerminatedArrayParser = <ElementOutput, TerminatorOutput, Seq
51
51
  const elements: ElementOutput[] = [];
52
52
 
53
53
  while (true) {
54
- const terminatorParserContext = parserContext.lookahead({
54
+ using terminatorParserContext = parserContext.lookahead({
55
55
  debugName: getParserName(terminatorParser, 'anonymousTerminator'),
56
56
  });
57
57
 
58
58
  try {
59
59
  const terminatorValue = await terminatorParser(terminatorParserContext);
60
60
 
61
- const elementParserContext = parserContext.lookahead({
62
- debugName: getParserName(elementParser, 'anonymousElement'),
63
- });
64
-
65
- try {
66
- await elementParser(elementParserContext);
67
-
68
- parserImplementationInvariant(
69
- false,
70
- [
71
- 'Both element and terminator parsers matched.',
72
- 'Element parser: %s',
73
- 'Terminator parser: %s',
74
- ],
75
- getParserName(elementParser, 'anonymousElement'),
76
- getParserName(terminatorParser, 'anonymousTerminator'),
77
- );
78
- } catch (error) {
79
- if (!(isParserParsingFailedError(error))) {
80
- throw error;
61
+ {
62
+ using elementParserContext = parserContext.lookahead({
63
+ debugName: getParserName(elementParser, 'anonymousElement'),
64
+ });
65
+
66
+ try {
67
+ await elementParser(elementParserContext);
68
+
69
+ parserImplementationInvariant(
70
+ false,
71
+ [
72
+ 'Both element and terminator parsers matched.',
73
+ 'Element parser: %s',
74
+ 'Terminator parser: %s',
75
+ ],
76
+ getParserName(elementParser, 'anonymousElement'),
77
+ getParserName(terminatorParser, 'anonymousTerminator'),
78
+ );
79
+ } catch (error) {
80
+ if (!(isParserParsingFailedError(error))) {
81
+ throw error;
82
+ }
81
83
  }
82
- } finally {
83
- elementParserContext.dispose();
84
84
  }
85
85
 
86
86
  terminatorParserContext.unlookahead();
@@ -90,8 +90,6 @@ export const createTerminatedArrayParser = <ElementOutput, TerminatorOutput, Seq
90
90
  if (!(isParserParsingFailedError(error))) {
91
91
  throw error;
92
92
  }
93
- } finally {
94
- terminatorParserContext.dispose();
95
93
  }
96
94
 
97
95
  const element = await elementParser(parserContext);
@@ -113,7 +111,7 @@ export const createTerminatedArrayParserUnsafe = <ElementOutput, TerminatorOutpu
113
111
  const elements: ElementOutput[] = [];
114
112
 
115
113
  while (true) {
116
- const terminatorParserContext = parserContext.lookahead({
114
+ using terminatorParserContext = parserContext.lookahead({
117
115
  debugName: getParserName(terminatorParser, 'anonymousTerminator'),
118
116
  });
119
117
 
@@ -127,8 +125,6 @@ export const createTerminatedArrayParserUnsafe = <ElementOutput, TerminatorOutpu
127
125
  if (!(isParserParsingFailedError(error))) {
128
126
  throw error;
129
127
  }
130
- } finally {
131
- terminatorParserContext.dispose();
132
128
  }
133
129
 
134
130
  const element = await elementParser(parserContext);
@@ -1,21 +1,24 @@
1
- import { getParserName, setParserName, type Parser } from './parser.js';
2
-
3
- export function createTupleParser<A, B, Sequence>([ parserA, parserB ]: [Parser<A, Sequence>, Parser<B, Sequence>]): Parser<[A, B], Sequence>;
4
- export function createTupleParser<A, B, C, Sequence>([ parserA, parserB, parserC ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>]): Parser<[A, B, C], Sequence>;
5
- export function createTupleParser<A, B, C, D, Sequence>([ parserA, parserB, parserC, parserD ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>]): Parser<[A, B, C, D], Sequence>;
6
- export function createTupleParser<A, B, C, D, E, Sequence>([ parserA, parserB, parserC, parserD, parserE ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>]): Parser<[A, B, C, D, E], Sequence>;
7
- export function createTupleParser<A, B, C, D, E, F, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>]): Parser<[A, B, C, D, E, F], Sequence>;
8
- export function createTupleParser<A, B, C, D, E, F, G, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF, parserG ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>]): Parser<[A, B, C, D, E, F, G], Sequence>;
9
- export function createTupleParser<A, B, C, D, E, F, G, H, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>]): Parser<[A, B, C, D, E, F, G, H], Sequence>;
10
- export function createTupleParser<A, B, C, D, E, F, G, H, I, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I], Sequence>;
11
- export function createTupleParser<A, B, C, D, E, F, G, H, I, J, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J], Sequence>;
12
- export function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K], Sequence>;
13
- export function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, L, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK, parserL ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>, Parser<L, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K, L], Sequence>;
14
- export function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, L, M, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK, parserL, parserM ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>, Parser<L, Sequence>, Parser<M, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K, L, M], Sequence>;
15
- export function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, L, M, N, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK, parserL, parserM, parserN ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>, Parser<L, Sequence>, Parser<M, Sequence>, Parser<N, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K, L, M, N], Sequence>;
16
- export function createTupleParser<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, Sequence>([ parserA, parserB, parserC, parserD, parserE, parserF, parserG, parserH, parserI, parserJ, parserK, parserL, parserM, parserN, parserO ]: [Parser<A, Sequence>, Parser<B, Sequence>, Parser<C, Sequence>, Parser<D, Sequence>, Parser<E, Sequence>, Parser<F, Sequence>, Parser<G, Sequence>, Parser<H, Sequence>, Parser<I, Sequence>, Parser<J, Sequence>, Parser<K, Sequence>, Parser<L, Sequence>, Parser<M, Sequence>, Parser<N, Sequence>, Parser<O, Sequence>]): Parser<[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O], Sequence>;
17
- export function createTupleParser<Sequence>(parsers: Array<Parser<unknown, Sequence>>): Parser<unknown[], Sequence> {
18
- const tupleParser: Parser<unknown[], Sequence> = async parserContext => {
1
+ import { getParserName, setParserName, type Parser, type ParserOutput, type ParserSequence } from './parser.js';
2
+
3
+ // Map tuple of parsers to tuple of their outputs
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ type TupleParserOutput<Parsers extends readonly Parser<any, any, any>[]> = {
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ [K in keyof Parsers]: Parsers[K] extends Parser<any, any, any> ? ParserOutput<Parsers[K]> : never
8
+ };
9
+
10
+ // Infer Sequence from parser array
11
+ type InferSequenceFromParserArray<T extends readonly unknown[]> = ParserSequence<T[number]>;
12
+
13
+ export function createTupleParser<
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ const Parsers extends readonly Parser<any, any, any>[],
16
+ >(
17
+ parsers: Parsers,
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ ): Parser<TupleParserOutput<Parsers>, InferSequenceFromParserArray<Parsers>, any> {
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ const tupleParser: Parser<any, any, any> = async parserContext => {
19
22
  const values: unknown[] = [];
20
23
 
21
24
  for (const parser of parsers) {
@@ -0,0 +1,105 @@
1
+ import { expectAssignable, expectType } from 'tsd';
2
+ import { createUnionParser } from './unionParser.js';
3
+ import { type Parser, type ParserOutput } from './parser.js';
4
+ import { createExactSequenceParser } from './exactSequenceParser.js';
5
+ import { createExactElementParser } from './exactElementParser.js';
6
+ import { createFixedLengthSequenceParser } from './fixedLengthSequenceParser.js';
7
+
8
+ // Test: basic union of string parsers - output inferred as string
9
+ {
10
+ const parser = createUnionParser([
11
+ createExactElementParser('a'),
12
+ createExactElementParser('b'),
13
+ ]);
14
+
15
+ type Output = ParserOutput<typeof parser>;
16
+
17
+ expectAssignable<string>(null! as Output);
18
+ expectAssignable<Output>(null! as string);
19
+ }
20
+
21
+ // Test: union preserves literal types when parsers have explicit literal output types
22
+ {
23
+ const parserA: Parser<'a', string> = async () => 'a' as const;
24
+ const parserB: Parser<'b', string> = async () => 'b' as const;
25
+
26
+ const parser = createUnionParser([parserA, parserB]);
27
+
28
+ type Output = ParserOutput<typeof parser>;
29
+
30
+ // Output should be 'a' | 'b', not string
31
+ expectAssignable<'a' | 'b'>(null! as Output);
32
+ expectAssignable<Output>(null! as 'a' | 'b');
33
+ }
34
+
35
+ // Test: union of parsers with different output types
36
+ {
37
+ const stringParser: Parser<string, string> = createFixedLengthSequenceParser(3);
38
+ const numberParser: Parser<number, string> = () => 42;
39
+
40
+ const parser = createUnionParser([
41
+ stringParser,
42
+ numberParser,
43
+ ]);
44
+
45
+ type Output = ParserOutput<typeof parser>;
46
+
47
+ // Output should be string | number
48
+ expectAssignable<string | number>(null! as Output);
49
+ expectAssignable<Output>(null! as string | number);
50
+ }
51
+
52
+ // Test: nested unions
53
+ {
54
+ const inner = createUnionParser([
55
+ createExactElementParser('a'),
56
+ createExactElementParser('b'),
57
+ ]);
58
+
59
+ const parser = createUnionParser([
60
+ inner,
61
+ createExactElementParser('c'),
62
+ ]);
63
+
64
+ type Output = ParserOutput<typeof parser>;
65
+
66
+ expectAssignable<string>(null! as Output);
67
+ expectAssignable<Output>(null! as string);
68
+ }
69
+
70
+ // Test: sequence type inferred from child parsers
71
+ {
72
+ const parser = createUnionParser([
73
+ createExactSequenceParser('hello'),
74
+ createExactSequenceParser('world'),
75
+ ]);
76
+
77
+ type Output = ParserOutput<typeof parser>;
78
+
79
+ // Parser should be for string sequences, output is string (widened from literals)
80
+ expectAssignable<string>(null! as Output);
81
+ }
82
+
83
+ // Test: single parser in union
84
+ {
85
+ const parser = createUnionParser([
86
+ createExactSequenceParser('only'),
87
+ ]);
88
+
89
+ type Output = ParserOutput<typeof parser>;
90
+
91
+ // Output is string (widened from literal 'only')
92
+ expectAssignable<string>(null! as Output);
93
+ }
94
+
95
+ // Test: union of object-producing parsers
96
+ {
97
+ const parser1: Parser<{ type: 'a'; value: number }, string> = async () => ({ type: 'a', value: 1 });
98
+ const parser2: Parser<{ type: 'b'; name: string }, string> = async () => ({ type: 'b', name: 'test' });
99
+
100
+ const parser = createUnionParser([parser1, parser2]);
101
+
102
+ type Output = ParserOutput<typeof parser>;
103
+
104
+ expectAssignable<{ type: 'a'; value: number } | { type: 'b'; name: string }>(null! as Output);
105
+ }
@@ -31,26 +31,27 @@ test('union of union of union', async t => {
31
31
  });
32
32
 
33
33
  test('sync and async child parsers', async t => {
34
- const parser = createArrayParser(createUnionParser<string, string>([
35
- async parserContext => {
36
- parserContext.invariant(
37
- parserContext.position % 2 === 0,
38
- 'Expected an even position.',
39
- );
34
+ const evenParser: Parser<string, string> = async parserContext => {
35
+ parserContext.invariant(
36
+ parserContext.position % 2 === 0,
37
+ 'Expected an even position.',
38
+ );
40
39
 
41
- return parserContext.read(0);
42
- },
43
- parserContext => {
44
- parserContext.invariant(
45
- parserContext.position % 2 === 1,
46
- 'Expected an odd position.',
47
- );
40
+ return parserContext.read(0);
41
+ };
48
42
 
49
- parserContext.skip(1);
43
+ const oddParser: Parser<string, string> = parserContext => {
44
+ parserContext.invariant(
45
+ parserContext.position % 2 === 1,
46
+ 'Expected an odd position.',
47
+ );
50
48
 
51
- return String.fromCodePoint('A'.codePointAt(0)! + parserContext.position - 1);
52
- },
53
- ]));
49
+ parserContext.skip(1);
50
+
51
+ return String.fromCodePoint('A'.codePointAt(0)! + parserContext.position - 1);
52
+ };
53
+
54
+ const parser = createArrayParser(createUnionParser([evenParser, oddParser]));
54
55
 
55
56
  const result = await runParser(parser, 'a?c?', stringParserInputCompanion, {
56
57
  errorJoinMode: 'all',
@@ -1,9 +1,14 @@
1
1
  import { allSettledStream } from './allSettledStream.js';
2
- import { getParserName, setParserName, type Parser } from './parser.js';
2
+ import { getParserName, setParserName, type Parser, type ParserOutput, type ParserSequence } from './parser.js';
3
3
  import { type ParserContext } from './parserContext.js';
4
4
  import { isParserParsingFailedError, ParserParsingFailedError } from './parserError.js';
5
5
  import { parserImplementationInvariant } from './parserImplementationInvariant.js';
6
- import { type DeriveSequenceElement } from './sequence.js';
6
+
7
+ // Union all output types from an array of parsers
8
+ type UnionParserOutput<Parsers extends readonly unknown[]> = ParserOutput<Parsers[number]>;
9
+
10
+ // Infer Sequence from parser array
11
+ type InferSequenceFromParserArray<T extends readonly unknown[]> = ParserSequence<T[number]>;
7
12
 
8
13
  const bigintReplacer = (_key: string, value: unknown) => {
9
14
  if (typeof value === 'bigint') {
@@ -13,24 +18,28 @@ const bigintReplacer = (_key: string, value: unknown) => {
13
18
  return value;
14
19
  };
15
20
 
16
- export const createUnionParser = <
17
- Output,
18
- Sequence,
19
- Element = DeriveSequenceElement<Sequence>,
21
+ export function createUnionParser<
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ const Parsers extends readonly Parser<any, any, any>[],
20
24
  >(
21
- childParsers: Array<Parser<unknown, Sequence, Element>>,
22
- ): Parser<Output, Sequence, Element> => {
25
+ childParsers: Parsers,
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
+ ): Parser<UnionParserOutput<Parsers>, InferSequenceFromParserArray<Parsers>> {
23
28
  parserImplementationInvariant(childParsers.length > 0, 'Union parser must have at least one child parser.');
24
29
 
25
30
  type TaskContext = {
26
- childParser: Parser<unknown, Sequence, Element>;
27
- childParserContext: ParserContext<Sequence, Element>;
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ childParser: Parser<any, any, any>;
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ childParserContext: ParserContext<any, any>;
28
35
  };
29
36
 
30
- const unionParser: Parser<Output, Sequence, Element> = async parserContext => {
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ const unionParser: Parser<any, any, any> = async parserContext => {
31
39
  let runningChildParserContexts: TaskContext[] = [];
32
40
 
33
- const createChildParserTask = (childParser: Parser<unknown, Sequence, Element>) => {
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ const createChildParserTask = (childParser: Parser<any, any, any>) => {
34
43
  const childParserContext = parserContext.lookahead({
35
44
  debugName: getParserName(childParser, 'anonymousUnionChild'),
36
45
  });
@@ -42,7 +51,8 @@ export const createUnionParser = <
42
51
 
43
52
  runningChildParserContexts.push(context);
44
53
 
45
- const getChildParserPromise = (async () => childParser(childParserContext) as Promise<Output>);
54
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+ const getChildParserPromise = (async () => childParser(childParserContext) as Promise<any>);
46
56
 
47
57
  const promise = getChildParserPromise();
48
58
 
@@ -52,10 +62,12 @@ export const createUnionParser = <
52
62
  };
53
63
  };
54
64
 
55
- const childParserResults = allSettledStream<Output, TaskContext>(childParsers.map(createChildParserTask));
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ const childParserResults = allSettledStream<any, TaskContext>(childParsers.map(createChildParserTask));
56
67
 
57
68
  const parserParsingFailedErrors: ParserParsingFailedError[] = [];
58
- const successfulParserOutputs: Output[] = [];
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ const successfulParserOutputs: any[] = [];
59
71
  const successfulTaskContexts: TaskContext[] = [];
60
72
  let didUnlookahead = false;
61
73
 
@@ -127,4 +139,4 @@ export const createUnionParser = <
127
139
  ].join('');
128
140
 
129
141
  return setParserName(unionParser, name);
130
- };
142
+ }