@futpib/parser 1.0.2 → 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.
- package/.github/copilot-instructions.md +149 -0
- package/.github/workflows/copilot-setup-steps.yml +18 -0
- package/.github/workflows/main.yml +29 -8
- package/.yarn/releases/yarn-4.9.4.cjs +942 -0
- package/.yarnrc.yml +1 -1
- package/build/allSettledStream.js +1 -1
- package/build/allSettledStream.test.js +2 -2
- package/build/androidPackageParser.d.ts +1 -1
- package/build/androidPackageParser.js +5 -3
- package/build/androidPackageParser.test.js +7 -7
- package/build/androidPackageUnparser.d.ts +2 -2
- package/build/androidPackageUnparser.js +18 -14
- package/build/androidPackageUnparser.test.js +7 -7
- package/build/arbitrarilySlicedAsyncInterator.js +2 -1
- package/build/arbitraryDalvikBytecode.d.ts +4 -0
- package/build/arbitraryDalvikBytecode.js +640 -0
- package/build/arbitraryDalvikExecutable.d.ts +3 -0
- package/build/arbitraryDalvikExecutable.js +282 -0
- package/build/arbitraryDosDateTime.js +1 -0
- package/build/arbitraryZipStream.js +1 -1
- package/build/arrayParser.js +2 -2
- package/build/arrayUnparser.d.ts +1 -1
- package/build/backsmali.d.ts +3 -1
- package/build/backsmali.js +31 -3
- package/build/customInvariant.d.ts +2 -1
- package/build/customInvariant.js +4 -6
- package/build/dalvikBytecodeParser/formatParsers.d.ts +76 -2
- package/build/dalvikBytecodeParser/formatParsers.js +146 -11
- package/build/dalvikBytecodeParser/formatSizes.d.ts +34 -0
- package/build/dalvikBytecodeParser/formatSizes.js +34 -0
- package/build/dalvikBytecodeParser/operationFormats.d.ts +225 -0
- package/build/dalvikBytecodeParser/operationFormats.js +225 -0
- package/build/dalvikBytecodeParser.d.ts +1105 -5
- package/build/dalvikBytecodeParser.js +658 -205
- package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +152 -0
- package/build/dalvikBytecodeUnparser/formatUnparsers.js +225 -0
- package/build/dalvikBytecodeUnparser.d.ts +3 -0
- package/build/dalvikBytecodeUnparser.js +642 -0
- package/build/dalvikBytecodeUnparser.test.d.ts +1 -0
- package/build/dalvikBytecodeUnparser.test.js +25 -0
- package/build/dalvikExecutable.d.ts +65 -8
- package/build/dalvikExecutable.js +36 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +1 -1
- package/build/dalvikExecutableParser/stringSyntaxParser.js +17 -17
- package/build/dalvikExecutableParser/typeParsers.d.ts +2 -1
- package/build/dalvikExecutableParser/typeParsers.js +16 -11
- package/build/dalvikExecutableParser/typedNumbers.d.ts +85 -69
- package/build/dalvikExecutableParser/typedNumbers.js +0 -1
- package/build/dalvikExecutableParser.d.ts +2 -2
- package/build/dalvikExecutableParser.js +655 -337
- package/build/dalvikExecutableParser.test.js +24 -22
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +223 -246
- package/build/dalvikExecutableUnparser/annotationUnparsers.d.ts +14 -0
- package/build/dalvikExecutableUnparser/annotationUnparsers.js +97 -0
- package/build/dalvikExecutableUnparser/poolBuilders.d.ts +49 -0
- package/build/dalvikExecutableUnparser/poolBuilders.js +140 -0
- package/build/dalvikExecutableUnparser/poolScanners.d.ts +4 -0
- package/build/dalvikExecutableUnparser/poolScanners.js +220 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +25 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.js +581 -0
- package/build/dalvikExecutableUnparser/utils.d.ts +10 -0
- package/build/dalvikExecutableUnparser/utils.js +108 -0
- package/build/dalvikExecutableUnparser.d.ts +4 -0
- package/build/dalvikExecutableUnparser.js +406 -0
- package/build/dalvikExecutableUnparser.test.d.ts +1 -0
- package/build/dalvikExecutableUnparser.test.js +31 -0
- package/build/debugLogInputParser.js +1 -1
- package/build/disjunctionParser.d.ts +2 -2
- package/build/disjunctionParser.js +2 -2
- package/build/elementTerminatedArrayParser.d.ts +2 -2
- package/build/elementTerminatedArrayParser.js +1 -1
- package/build/elementTerminatedArrayParser.test.js +5 -5
- package/build/elementTerminatedSequenceArrayParser.d.ts +2 -2
- package/build/elementTerminatedSequenceArrayParser.js +1 -1
- package/build/elementTerminatedSequenceArrayParser.test.js +2 -2
- package/build/elementTerminatedSequenceParser.d.ts +2 -2
- package/build/elementTerminatedSequenceParser.js +1 -1
- package/build/elementTerminatedSequenceParser.test.js +2 -2
- package/build/endOfInputParser.d.ts +1 -1
- package/build/exactElementSwitchParser.d.ts +3 -0
- package/build/exactElementSwitchParser.js +22 -0
- package/build/fetchCid.js +2 -6
- package/build/fetchCid.test.d.ts +1 -0
- package/build/fetchCid.test.js +16 -0
- package/build/fixedLengthSequenceParser.test.js +2 -2
- package/build/hasExecutable.js +2 -2
- package/build/highResolutionTimer.js +1 -1
- package/build/inputReader.d.ts +1 -1
- package/build/inputReader.test.js +33 -45
- package/build/javaKeyStoreParser.test.js +6 -6
- package/build/jsonParser.js +8 -8
- package/build/lazyMessageError.d.ts +48 -0
- package/build/lazyMessageError.js +53 -0
- package/build/lazyMessageError.test.d.ts +1 -0
- package/build/lazyMessageError.test.js +15 -0
- package/build/leb128Parser.d.ts +1 -1
- package/build/leb128Parser.js +10 -10
- package/build/leb128Parser.test.js +7 -7
- package/build/negativeLookaheadParser.js +2 -2
- package/build/negativeLookaheadParser.test.js +4 -4
- package/build/noStackCaptureOverheadError.d.ts +4 -0
- package/build/noStackCaptureOverheadError.js +9 -0
- package/build/noStackCaptureOverheadError.test.d.ts +1 -0
- package/build/noStackCaptureOverheadError.test.js +15 -0
- package/build/nonEmptyArrayParser.js +2 -2
- package/build/nonEmptyArrayParser.test.js +2 -1
- package/build/optionalParser.js +2 -2
- package/build/parser.d.ts +2 -1
- package/build/parser.js +23 -8
- package/build/parser.test.js +78 -29
- package/build/parserConsumedSequenceParser.d.ts +1 -1
- package/build/parserConsumedSequenceParser.js +2 -2
- package/build/parserContext.d.ts +8 -6
- package/build/parserContext.js +60 -33
- package/build/parserContext.test.js +7 -3
- package/build/parserError.d.ts +603 -44
- package/build/parserError.js +98 -53
- package/build/parserImplementationInvariant.d.ts +1 -1
- package/build/parserImplementationInvariant.js +2 -2
- package/build/parserInputCompanion.js +2 -2
- package/build/promiseCompose.js +1 -2
- package/build/separatedArrayParser.js +2 -2
- package/build/separatedNonEmptyArrayParser.d.ts +2 -0
- package/build/separatedNonEmptyArrayParser.js +40 -0
- package/build/separatedNonEmptyArrayParser.test.d.ts +1 -0
- package/build/separatedNonEmptyArrayParser.test.js +66 -0
- package/build/sequenceBuffer.js +1 -1
- package/build/sequenceTerminatedSequenceParser.d.ts +2 -2
- package/build/sequenceTerminatedSequenceParser.js +3 -3
- package/build/sequenceTerminatedSequenceParser.test.js +1 -1
- package/build/sequenceUnparser.d.ts +1 -1
- package/build/skipToParser.d.ts +1 -1
- package/build/skipToParser.js +2 -2
- package/build/sliceBoundedParser.test.js +4 -9
- package/build/smali.d.ts +1 -1
- package/build/smali.js +6 -2
- package/build/smaliParser.d.ts +62 -6
- package/build/smaliParser.js +1721 -296
- package/build/smaliParser.test.js +338 -43
- package/build/stringFromAsyncIterable.d.ts +1 -0
- package/build/stringFromAsyncIterable.js +7 -0
- package/build/terminatedArrayParser.js +4 -4
- package/build/terminatedArrayParser.test.js +7 -7
- package/build/toAsyncIterator.js +4 -4
- package/build/unionParser.d.ts +1 -1
- package/build/unionParser.js +2 -2
- package/build/unionParser.test.js +3 -3
- package/build/unparser.d.ts +3 -3
- package/build/unparser.js +6 -4
- package/build/unparser.test.js +7 -19
- package/build/unparserContext.d.ts +2 -2
- package/build/unparserContext.js +2 -3
- package/build/unparserError.d.ts +2 -1
- package/build/unparserError.js +2 -1
- package/build/unparserImplementationInvariant.d.ts +1 -1
- package/build/unparserOutputCompanion.d.ts +1 -1
- package/build/unparserOutputCompanion.js +1 -1
- package/build/zipParser.js +1 -1
- package/build/zipUnparser.d.ts +3 -3
- package/build/zipUnparser.js +9 -19
- package/build/zipUnparser.test.js +1 -1
- package/package.json +19 -26
- package/src/allSettledStream.test.ts +2 -2
- package/src/allSettledStream.ts +3 -3
- package/src/androidPackageParser.test.ts +17 -19
- package/src/androidPackageParser.ts +129 -171
- package/src/androidPackageUnparser.test.ts +19 -21
- package/src/androidPackageUnparser.ts +23 -17
- package/src/arbitrarilySlicedAsyncInterable.ts +1 -1
- package/src/arbitrarilySlicedAsyncInterator.ts +4 -4
- package/src/arbitraryDalvikBytecode.ts +992 -0
- package/src/arbitraryDalvikExecutable.ts +434 -0
- package/src/arbitraryDosDateTime.ts +1 -0
- package/src/arbitraryZipStream.ts +1 -1
- package/src/arrayParser.ts +2 -2
- package/src/arrayUnparser.ts +2 -2
- package/src/backsmali.ts +48 -4
- package/src/bsonParser.test.ts +12 -14
- package/src/customInvariant.ts +8 -12
- package/src/dalvikBytecodeParser/formatParsers.ts +376 -17
- package/src/dalvikBytecodeParser/formatSizes.ts +35 -0
- package/src/dalvikBytecodeParser/operationFormats.ts +226 -0
- package/src/dalvikBytecodeParser.ts +1042 -243
- package/src/dalvikBytecodeUnparser/formatUnparsers.ts +442 -0
- package/src/dalvikBytecodeUnparser.test.ts +44 -0
- package/src/dalvikBytecodeUnparser.ts +758 -0
- package/src/dalvikExecutable.ts +110 -48
- package/src/dalvikExecutableParser/stringSyntaxParser.ts +33 -33
- package/src/dalvikExecutableParser/typeParsers.ts +23 -14
- package/src/dalvikExecutableParser/typedNumbers.ts +19 -19
- package/src/dalvikExecutableParser.test.ts +60 -60
- package/src/dalvikExecutableParser.test.ts.md +6 -6
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +911 -434
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +256 -239
- package/src/dalvikExecutableUnparser/annotationUnparsers.ts +135 -0
- package/src/dalvikExecutableUnparser/poolBuilders.ts +189 -0
- package/src/dalvikExecutableUnparser/poolScanners.ts +297 -0
- package/src/dalvikExecutableUnparser/sectionUnparsers.ts +683 -0
- package/src/dalvikExecutableUnparser/utils.ts +149 -0
- package/src/dalvikExecutableUnparser.test.ts +57 -0
- package/src/dalvikExecutableUnparser.ts +581 -0
- package/src/debugLogInputParser.ts +1 -1
- package/src/disjunctionParser.ts +5 -5
- package/src/elementTerminatedArrayParser.test.ts +8 -8
- package/src/elementTerminatedArrayParser.ts +2 -2
- package/src/elementTerminatedSequenceArrayParser.test.ts +4 -6
- package/src/elementTerminatedSequenceArrayParser.ts +2 -2
- package/src/elementTerminatedSequenceParser.test.ts +4 -6
- package/src/elementTerminatedSequenceParser.ts +2 -2
- package/src/endOfInputParser.ts +1 -1
- package/src/exactElementSwitchParser.ts +41 -0
- package/src/fetchCid.test.ts +20 -0
- package/src/fetchCid.ts +3 -7
- package/src/fixedLengthSequenceParser.test.ts +10 -12
- package/src/hasExecutable.ts +2 -2
- package/src/highResolutionTimer.ts +1 -1
- package/src/inputReader.test.ts +39 -52
- package/src/inputReader.ts +2 -4
- package/src/inputReaderState.ts +1 -1
- package/src/inspect.ts +1 -1
- package/src/javaKeyStoreParser.test.ts +12 -14
- package/src/javaKeyStoreParser.ts +2 -6
- package/src/jsonParser.test.ts +2 -4
- package/src/jsonParser.ts +34 -38
- package/src/lazyMessageError.test.ts +21 -0
- package/src/lazyMessageError.ts +88 -0
- package/src/leb128Parser.test.ts +25 -23
- package/src/leb128Parser.ts +19 -19
- package/src/negativeLookaheadParser.test.ts +7 -11
- package/src/negativeLookaheadParser.ts +2 -2
- package/src/noStackCaptureOverheadError.test.ts +17 -0
- package/src/noStackCaptureOverheadError.ts +12 -0
- package/src/nonEmptyArrayParser.test.ts +3 -2
- package/src/nonEmptyArrayParser.ts +2 -2
- package/src/optionalParser.ts +2 -2
- package/src/parser.test.ts +96 -43
- package/src/parser.test.ts.md +13 -6
- package/src/parser.test.ts.snap +0 -0
- package/src/parser.ts +35 -12
- package/src/parserAccessorParser.ts +1 -1
- package/src/parserConsumedSequenceParser.ts +3 -3
- package/src/parserContext.test.ts +7 -3
- package/src/parserContext.ts +82 -48
- package/src/parserError.ts +143 -63
- package/src/parserImplementationInvariant.ts +3 -3
- package/src/parserInputCompanion.ts +2 -2
- package/src/promiseCompose.ts +2 -2
- package/src/separatedArrayParser.ts +3 -3
- package/src/separatedNonEmptyArrayParser.test.ts +117 -0
- package/src/separatedNonEmptyArrayParser.ts +61 -0
- package/src/sequenceBuffer.test.ts +9 -9
- package/src/sequenceBuffer.ts +4 -4
- package/src/sequenceTerminatedSequenceParser.test.ts +3 -5
- package/src/sequenceTerminatedSequenceParser.ts +4 -4
- package/src/sequenceUnparser.ts +2 -2
- package/src/skipToParser.ts +2 -2
- package/src/sliceBoundedParser.test.ts +4 -12
- package/src/sliceBoundedParser.ts +2 -2
- package/src/smali.ts +8 -3
- package/src/smaliParser.test.ts +377 -66
- package/src/smaliParser.test.ts.md +1635 -48
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +2751 -569
- package/src/stringFromAsyncIterable.ts +9 -0
- package/src/terminatedArrayParser.test.ts +11 -11
- package/src/terminatedArrayParser.ts +5 -7
- package/src/toAsyncIterator.ts +8 -8
- package/src/uint8Array.ts +2 -3
- package/src/unionParser.test.ts +22 -23
- package/src/unionParser.ts +6 -8
- package/src/unparser.test.ts +18 -34
- package/src/unparser.ts +13 -9
- package/src/unparserContext.ts +9 -13
- package/src/unparserError.ts +2 -1
- package/src/unparserImplementationInvariant.ts +1 -1
- package/src/unparserOutputCompanion.ts +1 -1
- package/src/zip.ts +2 -6
- package/src/zipParser.ts +10 -18
- package/src/zipUnparser.test.ts +1 -1
- package/src/zipUnparser.ts +52 -64
- package/tsconfig.json +7 -1
- package/xo.config.ts +15 -0
- package/.yarn/releases/yarn-4.5.3.cjs +0 -934
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fc from 'fast-check';
|
|
2
2
|
import { testProp } from '@fast-check/ava';
|
|
3
|
-
import { Parser, runParser } from './parser.js';
|
|
3
|
+
import { type Parser, runParser } from './parser.js';
|
|
4
4
|
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
5
5
|
import { createElementTerminatedSequenceArrayParser } from './elementTerminatedSequenceArrayParser.js';
|
|
6
6
|
|
|
@@ -13,14 +13,12 @@ testProp.serial(
|
|
|
13
13
|
})
|
|
14
14
|
.map(string => ({
|
|
15
15
|
string,
|
|
16
|
-
terminator: string.slice(-1)
|
|
16
|
+
terminator: string.slice(-1),
|
|
17
17
|
}))
|
|
18
|
-
.filter(({ string, terminator }) => string.split(terminator).length === 2)
|
|
18
|
+
.filter(({ string, terminator }) => string.split(terminator).length === 2),
|
|
19
19
|
],
|
|
20
20
|
async (t, { string, terminator }) => {
|
|
21
|
-
const elementTerminatedSequenceArrayParser = createElementTerminatedSequenceArrayParser<string>(
|
|
22
|
-
terminator,
|
|
23
|
-
);
|
|
21
|
+
const elementTerminatedSequenceArrayParser = createElementTerminatedSequenceArrayParser<string>(terminator);
|
|
24
22
|
|
|
25
23
|
const createTestWrapperParser = (innerParser: typeof elementTerminatedSequenceArrayParser): Parser<{
|
|
26
24
|
strings: string[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Parser, setParserName } from
|
|
2
|
-
import { DeriveSequenceElement } from
|
|
1
|
+
import { type Parser, setParserName } from './parser.js';
|
|
2
|
+
import { type DeriveSequenceElement } from './sequence.js';
|
|
3
3
|
|
|
4
4
|
export const createElementTerminatedSequenceArrayParser = <Sequence, Element = DeriveSequenceElement<Sequence>>(
|
|
5
5
|
terminatorElement: Element,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fc from 'fast-check';
|
|
2
2
|
import { testProp } from '@fast-check/ava';
|
|
3
|
-
import { Parser, runParser } from './parser.js';
|
|
3
|
+
import { type Parser, runParser } from './parser.js';
|
|
4
4
|
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
5
5
|
import { createElementTerminatedSequenceParser } from './elementTerminatedSequenceParser.js';
|
|
6
6
|
|
|
@@ -13,14 +13,12 @@ testProp.serial(
|
|
|
13
13
|
})
|
|
14
14
|
.map(string => ({
|
|
15
15
|
string,
|
|
16
|
-
terminator: string.slice(-1)
|
|
16
|
+
terminator: string.slice(-1),
|
|
17
17
|
}))
|
|
18
|
-
.filter(({ string, terminator }) => string.split(terminator).length === 2)
|
|
18
|
+
.filter(({ string, terminator }) => string.split(terminator).length === 2),
|
|
19
19
|
],
|
|
20
20
|
async (t, { string, terminator }) => {
|
|
21
|
-
const elementTerminatedSequenceParser = createElementTerminatedSequenceParser<string>(
|
|
22
|
-
terminator,
|
|
23
|
-
);
|
|
21
|
+
const elementTerminatedSequenceParser = createElementTerminatedSequenceParser<string>(terminator);
|
|
24
22
|
|
|
25
23
|
const createTestWrapperParser = (innerParser: typeof elementTerminatedSequenceParser): Parser<{
|
|
26
24
|
string: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Parser, setParserName } from
|
|
2
|
-
import { DeriveSequenceElement } from
|
|
1
|
+
import { type Parser, setParserName } from './parser.js';
|
|
2
|
+
import { type DeriveSequenceElement } from './sequence.js';
|
|
3
3
|
|
|
4
4
|
export const createElementTerminatedSequenceParser = <Sequence, Element = DeriveSequenceElement<Sequence>>(
|
|
5
5
|
terminatorElement: Element,
|
package/src/endOfInputParser.ts
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import invariant from "invariant";
|
|
2
|
+
import { getParserName, Parser, setParserName } from "./parser.js";
|
|
3
|
+
import { parserImplementationInvariant } from "./parserImplementationInvariant.js";
|
|
4
|
+
import { DeriveSequenceElement } from "./sequence.js";
|
|
5
|
+
|
|
6
|
+
export const createElementSwitchParser = <
|
|
7
|
+
Output,
|
|
8
|
+
Sequence,
|
|
9
|
+
Element = DeriveSequenceElement<Sequence>,
|
|
10
|
+
>(
|
|
11
|
+
childParsers: Map<Element, Parser<unknown, Sequence, Element>>,
|
|
12
|
+
defaultParser?: Parser<unknown, Sequence, Element>,
|
|
13
|
+
): Parser<Output, Sequence, Element> => {
|
|
14
|
+
parserImplementationInvariant(childParsers.size > 0, 'Element switch parser must have at least one child parser.');
|
|
15
|
+
|
|
16
|
+
const elementSwitchParser: Parser<Output, Sequence, Element> = async parserContext => {
|
|
17
|
+
const currentElement = await parserContext.peek(0);
|
|
18
|
+
|
|
19
|
+
parserContext.invariant(currentElement !== undefined, 'Unexpected end of input.');
|
|
20
|
+
invariant(currentElement !== undefined, 'Unexpected end of input.');
|
|
21
|
+
|
|
22
|
+
const childParser = childParsers.get(currentElement) ?? defaultParser;
|
|
23
|
+
|
|
24
|
+
parserContext.invariant(childParser, `No child parser found for element: ${String(currentElement)}`);
|
|
25
|
+
|
|
26
|
+
const childParserOutput = await childParser!(parserContext) as Output;
|
|
27
|
+
|
|
28
|
+
return childParserOutput;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const name = [
|
|
32
|
+
'elementSwitch(',
|
|
33
|
+
...Array.from(childParsers.entries()).map(
|
|
34
|
+
([ element, childParser ]) => `${String(element)}=>${getParserName(childParser, 'anonymousElementSwitchChild')}`,
|
|
35
|
+
),
|
|
36
|
+
defaultParser ? `|default=>${getParserName(defaultParser, 'anonymousElementSwitchDefaultChild')}` : '',
|
|
37
|
+
')',
|
|
38
|
+
].join('');
|
|
39
|
+
|
|
40
|
+
return setParserName(elementSwitchParser, name);
|
|
41
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { fetchCid } from './fetchCid.js';
|
|
3
|
+
|
|
4
|
+
const cid = 'bafybeicb3qajmwy6li7hche2nkucvytaxcyxhwhphmi73tgydjzmyoqoda';
|
|
5
|
+
|
|
6
|
+
test('fetchCid', async t => {
|
|
7
|
+
await Promise.all([
|
|
8
|
+
fetchCid(cid),
|
|
9
|
+
fetchCid(cid),
|
|
10
|
+
fetchCid(cid),
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
await Promise.all([
|
|
14
|
+
fetchCid(cid),
|
|
15
|
+
fetchCid(cid),
|
|
16
|
+
fetchCid(cid),
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
t.pass();
|
|
20
|
+
});
|
package/src/fetchCid.ts
CHANGED
|
@@ -47,15 +47,13 @@ class FsCache {
|
|
|
47
47
|
try {
|
|
48
48
|
const file = await fsPromises.open(this._getKeyPath(key), 'r');
|
|
49
49
|
|
|
50
|
-
const stream = file.readableWebStream(
|
|
51
|
-
type: 'bytes',
|
|
52
|
-
}) as ReadableStream<Uint8Array>;
|
|
50
|
+
const stream = file.readableWebStream() as ReadableStream<Uint8Array>;
|
|
53
51
|
|
|
54
52
|
const streamWithClose = readableWebStreamOnFinish(stream, () => {
|
|
55
53
|
file.close();
|
|
56
54
|
});
|
|
57
55
|
|
|
58
|
-
return [ streamWithClose, undefined as
|
|
56
|
+
return [ streamWithClose, undefined as unknown as ReadableStream<Uint8Array> ];
|
|
59
57
|
} catch (error) {
|
|
60
58
|
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
61
59
|
return undefined;
|
|
@@ -108,9 +106,7 @@ export async function fetchCid(cidOrPath: string): Promise<AsyncIterable<Uint8Ar
|
|
|
108
106
|
if (cidOrPath.includes('/')) {
|
|
109
107
|
const file = await fsPromises.open(cidOrPath, 'r');
|
|
110
108
|
|
|
111
|
-
const stream = file.readableWebStream(
|
|
112
|
-
type: 'bytes',
|
|
113
|
-
}) as ReadableStream<Uint8Array>;
|
|
109
|
+
const stream = file.readableWebStream() as ReadableStream<Uint8Array>;
|
|
114
110
|
|
|
115
111
|
const streamWithClose = readableWebStreamOnFinish(stream, () => {
|
|
116
112
|
file.close();
|
|
@@ -2,7 +2,7 @@ import test from 'ava';
|
|
|
2
2
|
import * as fc from 'fast-check';
|
|
3
3
|
import { testProp } from '@fast-check/ava';
|
|
4
4
|
import { createFixedLengthSequenceParser, createFixedLengthSequenceParserNaive } from './fixedLengthSequenceParser.js';
|
|
5
|
-
import { Parser, runParserWithRemainingInput } from './parser.js';
|
|
5
|
+
import { type Parser, runParserWithRemainingInput } from './parser.js';
|
|
6
6
|
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
7
7
|
import { HighResolutionTotalTimer } from './highResolutionTimer.js';
|
|
8
8
|
import { arbitrarilySlicedAsyncIterable } from './arbitrarilySlicedAsyncInterable.js';
|
|
@@ -19,12 +19,10 @@ testProp.serial(
|
|
|
19
19
|
max: 2n ** 14n,
|
|
20
20
|
})
|
|
21
21
|
.chain(length => fc.tuple(
|
|
22
|
-
arbitrarilySlicedAsyncIterable(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}),
|
|
27
|
-
),
|
|
22
|
+
arbitrarilySlicedAsyncIterable(fc.string({
|
|
23
|
+
minLength: Number(length),
|
|
24
|
+
maxLength: Number(length) * 2,
|
|
25
|
+
})),
|
|
28
26
|
fc.constant(length),
|
|
29
27
|
)),
|
|
30
28
|
],
|
|
@@ -33,8 +31,8 @@ testProp.serial(
|
|
|
33
31
|
const fixedLengthSequenceParser = createFixedLengthSequenceParser<string>(length);
|
|
34
32
|
|
|
35
33
|
const createTestWrapperParser = (innerParser: typeof fixedLengthSequenceParser): Parser<{
|
|
36
|
-
result: string
|
|
37
|
-
position: number
|
|
34
|
+
result: string;
|
|
35
|
+
position: number;
|
|
38
36
|
}, string> => async parserContext => {
|
|
39
37
|
const result = await innerParser(parserContext);
|
|
40
38
|
|
|
@@ -45,7 +43,7 @@ testProp.serial(
|
|
|
45
43
|
};
|
|
46
44
|
};
|
|
47
45
|
|
|
48
|
-
const { output: actualNaive } = await naiveTotalTimer.measureAsync(() => runParserWithRemainingInput(
|
|
46
|
+
const { output: actualNaive } = await naiveTotalTimer.measureAsync(async () => runParserWithRemainingInput(
|
|
49
47
|
createTestWrapperParser(fixedLengthSequenceParserNaive),
|
|
50
48
|
sequence,
|
|
51
49
|
stringParserInputCompanion,
|
|
@@ -53,7 +51,7 @@ testProp.serial(
|
|
|
53
51
|
|
|
54
52
|
t.true(actualNaive.result.length === Number(length));
|
|
55
53
|
|
|
56
|
-
const { output: actual } = await totalTimer.measureAsync(() => runParserWithRemainingInput(
|
|
54
|
+
const { output: actual } = await totalTimer.measureAsync(async () => runParserWithRemainingInput(
|
|
57
55
|
createTestWrapperParser(fixedLengthSequenceParser),
|
|
58
56
|
sequence,
|
|
59
57
|
stringParserInputCompanion,
|
|
@@ -71,7 +69,7 @@ test.serial(
|
|
|
71
69
|
t => {
|
|
72
70
|
t.true(
|
|
73
71
|
totalTimer.time * 10n < naiveTotalTimer.time,
|
|
74
|
-
`Naive: ${naiveTotalTimer.time /
|
|
72
|
+
`Naive: ${naiveTotalTimer.time / 1_000_000n}ms, Optimized: ${totalTimer.time / 1_000_000n}ms`,
|
|
75
73
|
);
|
|
76
74
|
},
|
|
77
75
|
);
|
package/src/hasExecutable.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { execa } from 'execa';
|
|
2
2
|
|
|
3
3
|
export async function hasExecutable(executable: string) {
|
|
4
|
-
const hasExecutable = execa(executable).
|
|
4
|
+
const hasExecutable = execa(executable).catch(() => false).then(() => true);
|
|
5
5
|
|
|
6
6
|
if (!hasExecutable) {
|
|
7
|
-
console.warn(
|
|
7
|
+
console.warn('Executable %o not found', executable);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
return hasExecutable;
|
package/src/inputReader.test.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
2
|
import { InputReaderImplementation } from './inputReader.js';
|
|
3
3
|
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
4
|
-
import { ParserImplementationError } from './parserError.js';
|
|
5
4
|
import { toAsyncIterable } from './toAsyncIterable.js';
|
|
6
|
-
import { InputReaderState } from './inputReaderState.js';
|
|
5
|
+
import { type InputReaderState } from './inputReaderState.js';
|
|
7
6
|
|
|
8
7
|
test('inputReader', async t => {
|
|
9
8
|
const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function * () {
|
|
@@ -122,7 +121,7 @@ test('inputReader.peekSequence concurrent', async t => {
|
|
|
122
121
|
yield * 'abcdefgh';
|
|
123
122
|
})());
|
|
124
123
|
|
|
125
|
-
const peeks = await Promise.all([1, 2, 3].flatMap(length => [
|
|
124
|
+
const peeks = await Promise.all([ 1, 2, 3 ].flatMap(length => [
|
|
126
125
|
inputReader.peekSequence(0, 0 + length),
|
|
127
126
|
inputReader.peekSequence(0, 0 + length),
|
|
128
127
|
inputReader.peekSequence(0, 0 + length),
|
|
@@ -247,10 +246,16 @@ test('inputReader.lookahead', async t => {
|
|
|
247
246
|
inputReader.skip(1);
|
|
248
247
|
|
|
249
248
|
await t.throwsAsync(async () => lookahead0a.peek(0), {
|
|
250
|
-
|
|
249
|
+
any: true,
|
|
250
|
+
name: 'ParserImplementationInvariantError',
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
await t.throwsAsync(async () => lookahead0b.peek(0), {
|
|
254
|
+
any: true,
|
|
255
|
+
});
|
|
256
|
+
await t.throwsAsync(async () => lookahead0c.peek(0), {
|
|
257
|
+
any: true,
|
|
251
258
|
});
|
|
252
|
-
await t.throwsAsync(async () => lookahead0b.peek(0));
|
|
253
|
-
await t.throwsAsync(async () => lookahead0c.peek(0));
|
|
254
259
|
|
|
255
260
|
const lookahead1a = inputReader.lookahead();
|
|
256
261
|
const lookahead1b = inputReader.lookahead();
|
|
@@ -292,11 +297,19 @@ test('inputReader.lookahead', async t => {
|
|
|
292
297
|
|
|
293
298
|
t.is(inputReader.position, 2);
|
|
294
299
|
|
|
295
|
-
await t.throwsAsync(async () => lookahead0a.peek(0)
|
|
296
|
-
|
|
297
|
-
|
|
300
|
+
await t.throwsAsync(async () => lookahead0a.peek(0), {
|
|
301
|
+
any: true,
|
|
302
|
+
});
|
|
303
|
+
await t.throwsAsync(async () => lookahead0b.peek(0), {
|
|
304
|
+
any: true,
|
|
305
|
+
});
|
|
306
|
+
await t.throwsAsync(async () => lookahead0c.peek(0), {
|
|
307
|
+
any: true,
|
|
308
|
+
});
|
|
298
309
|
t.is(await lookahead1a.peek(0), 'c');
|
|
299
|
-
await t.throwsAsync(async () => lookahead1b.peek(0)
|
|
310
|
+
await t.throwsAsync(async () => lookahead1b.peek(0), {
|
|
311
|
+
any: true,
|
|
312
|
+
});
|
|
300
313
|
t.is(await lookahead2a.peek(0), 'd');
|
|
301
314
|
t.is(await lookahead2b.peek(0), 'c');
|
|
302
315
|
|
|
@@ -376,9 +389,9 @@ async function inputReaderStateToArray<Sequence>({
|
|
|
376
389
|
unconsumedBufferedSequences,
|
|
377
390
|
consumedBufferedSequences,
|
|
378
391
|
unbufferedSequences,
|
|
379
|
-
}: InputReaderState<Sequence>): Promise<
|
|
380
|
-
const unconsumedBufferedSequencesArray = unconsumedBufferedSequences
|
|
381
|
-
const consumedBufferedSequencesArray = consumedBufferedSequences
|
|
392
|
+
}: InputReaderState<Sequence>): Promise<Array<Sequence | typeof END_OF_CONSUMED_SEQUENCES | typeof END_OF_BUFFERED_SEQUENCES>> {
|
|
393
|
+
const unconsumedBufferedSequencesArray = [ ...unconsumedBufferedSequences ];
|
|
394
|
+
const consumedBufferedSequencesArray = [ ...consumedBufferedSequences ];
|
|
382
395
|
|
|
383
396
|
const unbufferedSequencesArray = [];
|
|
384
397
|
if (unbufferedSequences) {
|
|
@@ -396,43 +409,10 @@ async function inputReaderStateToArray<Sequence>({
|
|
|
396
409
|
];
|
|
397
410
|
}
|
|
398
411
|
|
|
399
|
-
|
|
400
|
-
input,
|
|
401
|
-
|
|
402
|
-
expected
|
|
403
|
-
] of [
|
|
404
|
-
[
|
|
405
|
-
[ '', 'abc', 'def', '', 'gh' ],
|
|
406
|
-
0,
|
|
407
|
-
[ END_OF_CONSUMED_SEQUENCES, 'abc', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh' ],
|
|
408
|
-
],
|
|
409
|
-
[
|
|
410
|
-
[ '', 'abc', 'def', '', 'gh' ],
|
|
411
|
-
1,
|
|
412
|
-
[ 'a', END_OF_CONSUMED_SEQUENCES, 'bc', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh' ],
|
|
413
|
-
],
|
|
414
|
-
[
|
|
415
|
-
[ '', 'abc', 'def', '', 'gh' ],
|
|
416
|
-
2,
|
|
417
|
-
[ 'ab', END_OF_CONSUMED_SEQUENCES, 'c', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh' ],
|
|
418
|
-
],
|
|
419
|
-
[
|
|
420
|
-
[ '', 'abc', 'def', '', 'gh' ],
|
|
421
|
-
3,
|
|
422
|
-
[ END_OF_CONSUMED_SEQUENCES, 'def', END_OF_BUFFERED_SEQUENCES, '', 'gh' ],
|
|
423
|
-
],
|
|
424
|
-
[
|
|
425
|
-
[ '', 'abc', 'def', '', 'gh' ],
|
|
426
|
-
4,
|
|
427
|
-
[ 'd', END_OF_CONSUMED_SEQUENCES, 'ef', END_OF_BUFFERED_SEQUENCES, '', 'gh' ],
|
|
428
|
-
],
|
|
429
|
-
[
|
|
430
|
-
[ '', 'abc', 'def', '', 'gh' ],
|
|
431
|
-
8,
|
|
432
|
-
[ END_OF_CONSUMED_SEQUENCES, END_OF_BUFFERED_SEQUENCES ],
|
|
433
|
-
],
|
|
434
|
-
] as const) {
|
|
435
|
-
test('inputReader.toInputReaderState ' + JSON.stringify({ input, position }), async t => {
|
|
412
|
+
const inputReaderStateMacro = test.macro({
|
|
413
|
+
title: (providedTitle, input: readonly string[], position: number) =>
|
|
414
|
+
providedTitle ?? `inputReader.toInputReaderState ${JSON.stringify({ input, position })}`,
|
|
415
|
+
async exec(t, input: readonly string[], position: number, expected: ReadonlyArray<string | symbol>) {
|
|
436
416
|
const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function * () {
|
|
437
417
|
yield * input;
|
|
438
418
|
})());
|
|
@@ -443,5 +423,12 @@ for (const [
|
|
|
443
423
|
const actual = await inputReaderStateToArray(inputReader.toInputReaderState());
|
|
444
424
|
|
|
445
425
|
t.deepEqual(actual, expected);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 0, [ END_OF_CONSUMED_SEQUENCES, 'abc', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh' ]);
|
|
430
|
+
test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 1, [ 'a', END_OF_CONSUMED_SEQUENCES, 'bc', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh' ]);
|
|
431
|
+
test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 2, [ 'ab', END_OF_CONSUMED_SEQUENCES, 'c', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh' ]);
|
|
432
|
+
test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 3, [ END_OF_CONSUMED_SEQUENCES, 'def', END_OF_BUFFERED_SEQUENCES, '', 'gh' ]);
|
|
433
|
+
test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 4, [ 'd', END_OF_CONSUMED_SEQUENCES, 'ef', END_OF_BUFFERED_SEQUENCES, '', 'gh' ]);
|
|
434
|
+
test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 8, [ END_OF_CONSUMED_SEQUENCES, END_OF_BUFFERED_SEQUENCES ]);
|
package/src/inputReader.ts
CHANGED
|
@@ -3,7 +3,7 @@ import invariant from 'invariant';
|
|
|
3
3
|
import { type SequenceBuffer, SequenceBufferImplementation } from './sequenceBuffer.js';
|
|
4
4
|
import { type ParserInputCompanion } from './parserInputCompanion.js';
|
|
5
5
|
import { parserImplementationInvariant } from './parserImplementationInvariant.js';
|
|
6
|
-
import { InputReaderState } from './inputReaderState.js';
|
|
6
|
+
import { type InputReaderState } from './inputReaderState.js';
|
|
7
7
|
|
|
8
8
|
export type InputReader<Sequence, Element> = {
|
|
9
9
|
get position(): number;
|
|
@@ -169,9 +169,7 @@ class InputReaderLookaheadImplementation<Sequence, Element> implements InputRead
|
|
|
169
169
|
private _initialInputReaderPosition = 0;
|
|
170
170
|
private _offset = 0;
|
|
171
171
|
|
|
172
|
-
constructor(
|
|
173
|
-
private readonly _inputReader: InputReaderImplementation<Sequence, Element>,
|
|
174
|
-
) {
|
|
172
|
+
constructor(private readonly _inputReader: InputReaderImplementation<Sequence, Element>) {
|
|
175
173
|
this._initialInputReaderPosition = this._inputReader.position;
|
|
176
174
|
}
|
|
177
175
|
|
package/src/inputReaderState.ts
CHANGED
package/src/inspect.ts
CHANGED
|
@@ -4,19 +4,17 @@ import { runParser } from './parser.js';
|
|
|
4
4
|
import { javaKeyStoreParser } from './javaKeyStoreParser.js';
|
|
5
5
|
import { fetchCid } from './fetchCid.js';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
'javaKeyStore ' + javaKeyStoreCid,
|
|
12
|
-
async t => {
|
|
13
|
-
const javaKeyStoreStream = await fetchCid(javaKeyStoreCid);
|
|
7
|
+
const javaKeyStoreMacro = test.macro({
|
|
8
|
+
title: (providedTitle, javaKeyStoreCid: string) => providedTitle ?? `javaKeyStore ${javaKeyStoreCid}`,
|
|
9
|
+
async exec(t, javaKeyStoreCid: string) {
|
|
10
|
+
const javaKeyStoreStream = await fetchCid(javaKeyStoreCid);
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
const actual = await runParser(javaKeyStoreParser, javaKeyStoreStream, uint8ArrayParserInputCompanion, {
|
|
13
|
+
errorJoinMode: 'all',
|
|
14
|
+
});
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
t.snapshot(actual);
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test(javaKeyStoreMacro, 'bafkreig6k53b6p7bdvfjxc5mcb4qv3mffqls5ymqerxkqd6ih2xy5cs3n4');
|
|
@@ -66,9 +66,7 @@ const javaKeyStorePrivateKeyEntryCertificateParser = promiseCompose(
|
|
|
66
66
|
([ type, certificate ]) => ({ type, certificate }),
|
|
67
67
|
);
|
|
68
68
|
|
|
69
|
-
const javaKeyStorePrivateKeyEntryCertificateChainParser = createUint32BECountPrefixedParser(
|
|
70
|
-
javaKeyStorePrivateKeyEntryCertificateParser,
|
|
71
|
-
);
|
|
69
|
+
const javaKeyStorePrivateKeyEntryCertificateChainParser = createUint32BECountPrefixedParser(javaKeyStorePrivateKeyEntryCertificateParser);
|
|
72
70
|
|
|
73
71
|
const javaKeyStorePrivateKeyEntryParser = promiseCompose(
|
|
74
72
|
createTupleParser([
|
|
@@ -109,9 +107,7 @@ const javaKeyStoreEntryParser = createUnionParser([
|
|
|
109
107
|
javaKeyStoreSecretKeyEntryParser,
|
|
110
108
|
]);
|
|
111
109
|
|
|
112
|
-
const javaKeyStoreEntriesParser = createUint32BECountPrefixedParser(
|
|
113
|
-
javaKeyStoreEntryParser,
|
|
114
|
-
);
|
|
110
|
+
const javaKeyStoreEntriesParser = createUint32BECountPrefixedParser(javaKeyStoreEntryParser);
|
|
115
111
|
|
|
116
112
|
const javaKeyStoreParser_ = createTupleParser([
|
|
117
113
|
javaKeyStoreImplementationParser,
|
package/src/jsonParser.test.ts
CHANGED
|
@@ -7,10 +7,8 @@ import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
|
7
7
|
testProp(
|
|
8
8
|
'json',
|
|
9
9
|
[
|
|
10
|
-
arbitrarilySlicedAsyncIterator(
|
|
11
|
-
|
|
12
|
-
.map(([ jsonString, indent ]) => JSON.stringify(JSON.parse(jsonString), null, indent)),
|
|
13
|
-
),
|
|
10
|
+
arbitrarilySlicedAsyncIterator(fc.tuple(fc.json(), fc.nat())
|
|
11
|
+
.map(([ jsonString, indent ]) => JSON.stringify(JSON.parse(jsonString), null, indent))),
|
|
14
12
|
],
|
|
15
13
|
async (t, [ jsonString, jsonStringChunkIterator ]) => {
|
|
16
14
|
const actual = await runParser(jsonValueParser, jsonStringChunkIterator, stringParserInputCompanion, {
|
package/src/jsonParser.ts
CHANGED
|
@@ -15,27 +15,25 @@ import { createElementParser } from './elementParser.js';
|
|
|
15
15
|
import { parserCreatorCompose } from './parserCreatorCompose.js';
|
|
16
16
|
import { createSeparatedArrayParser } from './separatedArrayParser.js';
|
|
17
17
|
|
|
18
|
-
const whitespaceParser: Parser<unknown, string> = createArrayParser(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
const jsonQuoteEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\"'), () => '"');
|
|
18
|
+
const whitespaceParser: Parser<unknown, string> = createArrayParser(createUnionParser([
|
|
19
|
+
createExactSequenceParser(' '),
|
|
20
|
+
createExactSequenceParser('\t'),
|
|
21
|
+
createExactSequenceParser('\r'),
|
|
22
|
+
createExactSequenceParser('\n'),
|
|
23
|
+
]));
|
|
24
|
+
|
|
25
|
+
const jsonQuoteEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(String.raw`\"`), () => '"');
|
|
28
26
|
const jsonBackslashEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser('\\\\'), () => '\\');
|
|
29
|
-
const jsonSlashEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(
|
|
30
|
-
const jsonBackspaceEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(
|
|
31
|
-
const jsonFormFeedEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(
|
|
32
|
-
const jsonNewLineEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(
|
|
33
|
-
const jsonCarriageReturnEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(
|
|
34
|
-
const jsonTabEscapeSequenceParser: Parser<string, string> = promiseCompose(createExactSequenceParser(
|
|
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');
|
|
35
33
|
|
|
36
34
|
const jsonUnicodeEscapeSequenceParser: Parser<string, string> = promiseCompose(
|
|
37
35
|
createTupleParser([
|
|
38
|
-
createExactSequenceParser(
|
|
36
|
+
createExactSequenceParser(String.raw`\u`),
|
|
39
37
|
createFixedLengthSequenceParser<string>(4),
|
|
40
38
|
]),
|
|
41
39
|
([ , hexCode ]) => String.fromCharCode(Number.parseInt(hexCode, 16)),
|
|
@@ -81,27 +79,25 @@ export const jsonStringParser: Parser<string, string> = promiseCompose(
|
|
|
81
79
|
);
|
|
82
80
|
|
|
83
81
|
export const jsonNumberParser: Parser<number, string> = parserCreatorCompose(
|
|
84
|
-
() => createArrayParser(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
)(),
|
|
104
|
-
),
|
|
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
|
+
)()),
|
|
105
101
|
characters => async parserContext => {
|
|
106
102
|
parserContext.invariant(characters.length > 0, 'Expected at least one character');
|
|
107
103
|
|
|
@@ -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
|
+
});
|