1 | type _If<Test, Then, Else> = Test extends true ? Then : Else;
|
2 |
|
3 | export type Features = {
|
4 | lookbehind?: boolean;
|
5 | namedGroups?: boolean;
|
6 | unicodePropertyEscape?: boolean;
|
7 | unicodeSet?: boolean;
|
8 | modifiers?: boolean;
|
9 | };
|
10 |
|
11 | export type AstNodeType =
|
12 | | "alternative"
|
13 | | "anchor"
|
14 | | "characterClass"
|
15 | | "characterClassEscape"
|
16 | | "characterClassRange"
|
17 | | "disjunction"
|
18 | | "dot"
|
19 | | "group"
|
20 | | "quantifier"
|
21 | | "reference"
|
22 | | "unicodePropertyEscape"
|
23 | | "value";
|
24 |
|
25 | export type Base<T extends AstNodeType> = {
|
26 | range: [number, number];
|
27 | raw: string;
|
28 | type: T;
|
29 | };
|
30 |
|
31 | export type AstNode<F extends Features = {}> =
|
32 | | Alternative<F>
|
33 | | Anchor
|
34 | | CharacterClass<F>
|
35 | | CharacterClassEscape
|
36 | | CharacterClassRange
|
37 | | Disjunction<F>
|
38 | | Dot
|
39 | | Group<F>
|
40 | | Quantifier<F>
|
41 | | Reference<F>
|
42 | | _If<F["unicodePropertyEscape"], UnicodePropertyEscape, never>
|
43 | | Value;
|
44 |
|
45 | export type RootNode<F extends Features = {}> = Exclude<
|
46 | AstNode<F>,
|
47 | CharacterClassRange
|
48 | >;
|
49 |
|
50 | export type Anchor = Base<"anchor"> & {
|
51 | kind: "boundary" | "end" | "not-boundary" | "start";
|
52 | };
|
53 |
|
54 | export type CharacterClassEscape = Base<"characterClassEscape"> & {
|
55 | value: 'd' | 'D' | 'w' | 'W' | 's' | 'S';
|
56 | };
|
57 |
|
58 | export type Value = Base<"value"> & {
|
59 | codePoint: number;
|
60 | kind:
|
61 | | "controlLetter"
|
62 | | "hexadecimalEscape"
|
63 | | "identifier"
|
64 | | "null"
|
65 | | "octal"
|
66 | | "singleEscape"
|
67 | | "symbol"
|
68 | | "unicodeCodePointEscape"
|
69 | | "unicodeEscape";
|
70 | };
|
71 |
|
72 | export type Identifier = Base<"value"> & {
|
73 | value: string;
|
74 | };
|
75 |
|
76 | export type Alternative<F extends Features = {}> = Base<"alternative"> & {
|
77 | body: RootNode<F>[];
|
78 | };
|
79 |
|
80 | export type CharacterClassRange = Base<"characterClassRange"> & {
|
81 | max: Value;
|
82 | min: Value;
|
83 | };
|
84 |
|
85 | export type UnicodePropertyEscape = Base<"unicodePropertyEscape"> & {
|
86 | negative: boolean;
|
87 | value: string;
|
88 | };
|
89 |
|
90 | export type CharacterClassBody =
|
91 | | CharacterClassEscape
|
92 | | CharacterClassRange
|
93 | | UnicodePropertyEscape
|
94 | | Value;
|
95 |
|
96 | export type CharacterClass<F extends Features = {}> = Base<"characterClass"> & {
|
97 | body: CharacterClassBody[];
|
98 | negative: boolean;
|
99 | kind: "union" | _If<F["unicodeSet"], "intersection" | "subtraction", never>;
|
100 | };
|
101 |
|
102 | export type ModifierFlags = {
|
103 | enabling: string;
|
104 | disabling: string;
|
105 | };
|
106 |
|
107 | export type NonCapturingGroup<F extends Features = {}> = Base<"group"> &
|
108 | (
|
109 | | {
|
110 | behavior:
|
111 | | "lookahead"
|
112 | | "lookbehind"
|
113 | | "negativeLookahead"
|
114 | | "negativeLookbehind";
|
115 | body: RootNode<F>[];
|
116 | }
|
117 | | ({
|
118 | behavior: "ignore";
|
119 | body: RootNode<F>[];
|
120 | } & _If<
|
121 | F["modifiers"],
|
122 | {
|
123 | modifierFlags?: ModifierFlags;
|
124 | },
|
125 | {
|
126 | modifierFlags: undefined;
|
127 | }
|
128 | >)
|
129 | );
|
130 |
|
131 | export type CapturingGroup<F extends Features = {}> = Base<"group"> & {
|
132 | behavior: "normal";
|
133 | body: RootNode<F>[];
|
134 | } & _If<
|
135 | F["namedGroups"],
|
136 | {
|
137 | name?: Identifier;
|
138 | },
|
139 | {
|
140 | name: undefined;
|
141 | }
|
142 | >;
|
143 |
|
144 | export type Group<F extends Features = {}> =
|
145 | | CapturingGroup<F>
|
146 | | NonCapturingGroup<F>;
|
147 |
|
148 | export type Quantifier<F extends Features = {}> = Base<"quantifier"> & {
|
149 | body: [RootNode<F>];
|
150 | greedy: boolean;
|
151 | max?: number;
|
152 | min: number;
|
153 | symbol?: "?" | "*" | "+";
|
154 | };
|
155 |
|
156 | export type Disjunction<F extends Features = {}> = Base<"disjunction"> & {
|
157 | body: [RootNode<F>, RootNode<F>, ...RootNode<F>[]];
|
158 | };
|
159 |
|
160 | export type Dot = Base<"dot">;
|
161 |
|
162 | export type NamedReference = Base<"reference"> & {
|
163 | matchIndex: undefined;
|
164 | name: Identifier;
|
165 | };
|
166 |
|
167 | export type IndexReference = Base<"reference"> & {
|
168 | matchIndex: number;
|
169 | name: undefined;
|
170 | };
|
171 |
|
172 | export type Reference<F extends Features = {}> = _If<
|
173 | F["namedGroups"],
|
174 | IndexReference | NamedReference,
|
175 | IndexReference
|
176 | >;
|
177 |
|
178 | export function parse<F extends Features = {}>(
|
179 | str: string,
|
180 | flags: string,
|
181 | features?: F
|
182 | ): RootNode<F>;
|