@@ -12,10 +12,12 @@ import { SimplifyDeep } from '../types'
12
12
*/
13
13
export type ParseQuery < Query extends string > = string extends Query
14
14
? GenericStringError
15
- : ParseNodes < EatWhitespace < Query > > extends [ infer Nodes extends Ast . Node [ ] , `${infer Remainder } `]
16
- ? EatWhitespace < Remainder > extends ''
17
- ? SimplifyDeep < Nodes >
18
- : ParserError < `Unexpected input: ${Remainder } `>
15
+ : ParseNodes < EatWhitespace < Query > > extends [ infer Nodes , `${infer Remainder } `]
16
+ ? Nodes extends Ast . Node [ ]
17
+ ? EatWhitespace < Remainder > extends ''
18
+ ? SimplifyDeep < Nodes >
19
+ : ParserError < `Unexpected input: ${Remainder } `>
20
+ : ParserError < 'Invalid nodes array structure' >
19
21
: ParseNodes < EatWhitespace < Query > >
20
22
21
23
/**
@@ -34,14 +36,15 @@ type ParseNodes<Input extends string> = string extends Input
34
36
: ParseNodesHelper < Input , [ ] >
35
37
36
38
type ParseNodesHelper < Input extends string , Nodes extends Ast . Node [ ] > = ParseNode < Input > extends [
37
- infer Node extends Ast . Node ,
39
+ infer Node ,
38
40
`${infer Remainder } `
39
41
]
40
- ? EatWhitespace < Remainder > extends `,${infer Remainder } `
41
- ? ParseNodesHelper < EatWhitespace < Remainder > , [ ...Nodes , Node ] >
42
- : [ [ ...Nodes , Node ] , EatWhitespace < Remainder > ]
42
+ ? Node extends Ast . Node
43
+ ? EatWhitespace < Remainder > extends `,${infer Remainder } `
44
+ ? ParseNodesHelper < EatWhitespace < Remainder > , [ ...Nodes , Node ] >
45
+ : [ [ ...Nodes , Node ] , EatWhitespace < Remainder > ]
46
+ : ParserError < 'Invalid node type in nodes helper' >
43
47
: ParseNode < Input >
44
-
45
48
/**
46
49
* Parses a node.
47
50
* A node is one of the following:
@@ -57,23 +60,21 @@ type ParseNode<Input extends string> = Input extends ''
57
60
? [ Ast . StarNode , EatWhitespace < Remainder > ]
58
61
: // `...field`
59
62
Input extends `...${infer Remainder } `
60
- ? ParseField < EatWhitespace < Remainder > > extends [
61
- infer TargetField extends Ast . FieldNode ,
62
- `${infer Remainder } `
63
- ]
64
- ? [ { type : 'spread' ; target : TargetField } , EatWhitespace < Remainder > ]
63
+ ? ParseField < EatWhitespace < Remainder > > extends [ infer TargetField , `${infer Remainder } `]
64
+ ? TargetField extends Ast . FieldNode
65
+ ? [ { type : 'spread' ; target : TargetField } , EatWhitespace < Remainder > ]
66
+ : ParserError < 'Invalid target field type in spread' >
65
67
: ParserError < `Unable to parse spread resource at \`${Input } \``>
66
68
: ParseIdentifier < Input > extends [ infer NameOrAlias , `${infer Remainder } `]
67
69
? EatWhitespace < Remainder > extends `::${infer _ } `
68
70
? // It's a type cast and not an alias, so treat it as part of the field.
69
71
ParseField < Input >
70
72
: EatWhitespace < Remainder > extends `:${infer Remainder } `
71
73
? // `alias:`
72
- ParseField < EatWhitespace < Remainder > > extends [
73
- infer Field extends Ast . FieldNode ,
74
- `${infer Remainder } `
75
- ]
76
- ? [ Omit < Field , 'alias' > & { alias : NameOrAlias } , EatWhitespace < Remainder > ]
74
+ ParseField < EatWhitespace < Remainder > > extends [ infer Field , `${infer Remainder } `]
75
+ ? Field extends Ast . FieldNode
76
+ ? [ Omit < Field , 'alias' > & { alias : NameOrAlias } , EatWhitespace < Remainder > ]
77
+ : ParserError < 'Invalid field type in alias parsing' >
77
78
: ParserError < `Unable to parse renamed field at \`${Input } \``>
78
79
: // Otherwise, just parse it as a field without alias.
79
80
ParseField < Input >
@@ -98,24 +99,22 @@ type ParseField<Input extends string> = Input extends ''
98
99
? Name extends 'count'
99
100
? ParseCountField < Input >
100
101
: Remainder extends `!inner${infer Remainder } `
101
- ? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
102
- infer Children extends Ast . Node [ ] ,
103
- `${infer Remainder } `
104
- ]
105
- ? // `field!inner(nodes)`
106
- [ { type : 'field' ; name : Name ; innerJoin : true ; children : Children } , Remainder ]
102
+ ? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [ infer Children , `${infer Remainder } `]
103
+ ? Children extends Ast . Node [ ]
104
+ ? // `field!inner(nodes)`
105
+ [ { type : 'field' ; name : Name ; innerJoin : true ; children : Children } , Remainder ]
106
+ : ParserError < 'Invalid children array in inner join' >
107
107
: CreateParserErrorIfRequired <
108
108
ParseEmbeddedResource < EatWhitespace < Remainder > > ,
109
109
`Expected embedded resource after "!inner" at \`${Remainder } \``
110
110
>
111
111
: EatWhitespace < Remainder > extends `!left${infer Remainder } `
112
- ? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
113
- infer Children extends Ast . Node [ ] ,
114
- `${infer Remainder } `
115
- ]
116
- ? // `field!left(nodes)`
117
- // !left is a noise word - treat it the same way as a non-`!inner`.
118
- [ { type : 'field' ; name : Name ; children : Children } , EatWhitespace < Remainder > ]
112
+ ? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [ infer Children , `${infer Remainder } `]
113
+ ? Children extends Ast . Node [ ]
114
+ ? // `field!left(nodes)`
115
+ // !left is a noise word - treat it the same way as a non-`!inner`.
116
+ [ { type : 'field' ; name : Name ; children : Children } , EatWhitespace < Remainder > ]
117
+ : ParserError < 'Invalid children array in left join' >
119
118
: CreateParserErrorIfRequired <
120
119
ParseEmbeddedResource < EatWhitespace < Remainder > > ,
121
120
`Expected embedded resource after "!left" at \`${EatWhitespace < Remainder > } \``
@@ -124,30 +123,36 @@ type ParseField<Input extends string> = Input extends ''
124
123
? ParseIdentifier < EatWhitespace < Remainder > > extends [ infer Hint , `${infer Remainder } `]
125
124
? EatWhitespace < Remainder > extends `!inner${infer Remainder } `
126
125
? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
127
- infer Children extends Ast . Node [ ] ,
126
+ infer Children ,
128
127
`${infer Remainder } `
129
128
]
130
- ? // `field!hint!inner(nodes)`
131
- [
132
- { type : 'field' ; name : Name ; hint : Hint ; innerJoin : true ; children : Children } ,
133
- EatWhitespace < Remainder >
134
- ]
129
+ ? Children extends Ast . Node [ ]
130
+ ? // `field!hint!inner(nodes)`
131
+ [
132
+ { type : 'field' ; name : Name ; hint : Hint ; innerJoin : true ; children : Children } ,
133
+ EatWhitespace < Remainder >
134
+ ]
135
+ : ParserError < 'Invalid children array in hint inner join' >
135
136
: ParseEmbeddedResource < EatWhitespace < Remainder > >
136
137
: ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
137
- infer Children extends Ast . Node [ ] ,
138
+ infer Children ,
138
139
`${infer Remainder } `
139
140
]
140
- ? // `field!hint(nodes)`
141
- [ { type : 'field' ; name : Name ; hint : Hint ; children : Children } , EatWhitespace < Remainder > ]
141
+ ? Children extends Ast . Node [ ]
142
+ ? // `field!hint(nodes)`
143
+ [
144
+ { type : 'field' ; name : Name ; hint : Hint ; children : Children } ,
145
+ EatWhitespace < Remainder >
146
+ ]
147
+ : ParserError < 'Invalid children array in hint' >
142
148
: ParseEmbeddedResource < EatWhitespace < Remainder > >
143
149
: ParserError < `Expected identifier after "!" at \`${EatWhitespace < Remainder > } \``>
144
150
: EatWhitespace < Remainder > extends `(${infer _ } `
145
- ? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
146
- infer Children extends Ast . Node [ ] ,
147
- `${infer Remainder } `
148
- ]
149
- ? // `field(nodes)`
150
- [ { type : 'field' ; name : Name ; children : Children } , EatWhitespace < Remainder > ]
151
+ ? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [ infer Children , `${infer Remainder } `]
152
+ ? Children extends Ast . Node [ ]
153
+ ? // `field(nodes)`
154
+ [ { type : 'field' ; name : Name ; children : Children } , EatWhitespace < Remainder > ]
155
+ : ParserError < 'Invalid children array in field' >
151
156
: // Return error if start of embedded resource was detected but not found.
152
157
ParseEmbeddedResource < EatWhitespace < Remainder > >
153
158
: // Otherwise it's a non-embedded resource field.
@@ -184,13 +189,12 @@ type ParseCountField<Input extends string> = ParseIdentifier<Input> extends [
184
189
type ParseEmbeddedResource < Input extends string > = Input extends `(${infer Remainder } `
185
190
? EatWhitespace < Remainder > extends `)${infer Remainder } `
186
191
? [ [ ] , EatWhitespace < Remainder > ]
187
- : ParseNodes < EatWhitespace < Remainder > > extends [
188
- infer Nodes extends Ast . Node [ ] ,
189
- `${infer Remainder } `
190
- ]
191
- ? EatWhitespace < Remainder > extends `)${infer Remainder } `
192
- ? [ Nodes , EatWhitespace < Remainder > ]
193
- : ParserError < `Expected ")" at \`${EatWhitespace < Remainder > } \``>
192
+ : ParseNodes < EatWhitespace < Remainder > > extends [ infer Nodes , `${infer Remainder } `]
193
+ ? Nodes extends Ast . Node [ ]
194
+ ? EatWhitespace < Remainder > extends `)${infer Remainder } `
195
+ ? [ Nodes , EatWhitespace < Remainder > ]
196
+ : ParserError < `Expected ")" at \`${EatWhitespace < Remainder > } \``>
197
+ : ParserError < 'Invalid nodes array in embedded resource' >
194
198
: ParseNodes < EatWhitespace < Remainder > >
195
199
: ParserError < `Expected "(" at \`${Input } \``>
196
200
0 commit comments