Skip to content

Commit cc9344a

Browse files
avalletesoedirgo
andauthored
fix(types): make types retrocompatible to typescript 4.5.5 (#571)
* fix(types): spread and embeding combination issues * chore: remove debug test case * chore: reproduce invalid node type error * chore: using type fix the test * fix(types): types result with schema as any * wip: make parser logic retrocompatible * wip: almost there * chore(types): make GetResult compatible with typescript 4.5.5 * chore: fix merge * chore: finish merge * chore: revert non essential changes * chore: add TODO --------- Co-authored-by: Bobbie Soedirgo <[email protected]> Co-authored-by: Bobbie Soedirgo <[email protected]>
1 parent f22849b commit cc9344a

File tree

9 files changed

+337
-273
lines changed

9 files changed

+337
-273
lines changed

package-lock.json

Lines changed: 8 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"ts-jest": "^28.0.3",
6161
"tsd": "^0.31.2",
6262
"typedoc": "^0.22.16",
63-
"typescript": "~4.7",
63+
"typescript": "4.5.5",
6464
"wait-for-localhost-cli": "^3.0.0"
6565
}
6666
}

src/select-query-parser/parser.ts

Lines changed: 58 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ import { SimplifyDeep } from '../types'
1212
*/
1313
export type ParseQuery<Query extends string> = string extends Query
1414
? 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'>
1921
: ParseNodes<EatWhitespace<Query>>
2022

2123
/**
@@ -34,14 +36,15 @@ type ParseNodes<Input extends string> = string extends Input
3436
: ParseNodesHelper<Input, []>
3537

3638
type ParseNodesHelper<Input extends string, Nodes extends Ast.Node[]> = ParseNode<Input> extends [
37-
infer Node extends Ast.Node,
39+
infer Node,
3840
`${infer Remainder}`
3941
]
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'>
4347
: ParseNode<Input>
44-
4548
/**
4649
* Parses a node.
4750
* A node is one of the following:
@@ -57,23 +60,21 @@ type ParseNode<Input extends string> = Input extends ''
5760
? [Ast.StarNode, EatWhitespace<Remainder>]
5861
: // `...field`
5962
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'>
6567
: ParserError<`Unable to parse spread resource at \`${Input}\``>
6668
: ParseIdentifier<Input> extends [infer NameOrAlias, `${infer Remainder}`]
6769
? EatWhitespace<Remainder> extends `::${infer _}`
6870
? // It's a type cast and not an alias, so treat it as part of the field.
6971
ParseField<Input>
7072
: EatWhitespace<Remainder> extends `:${infer Remainder}`
7173
? // `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'>
7778
: ParserError<`Unable to parse renamed field at \`${Input}\``>
7879
: // Otherwise, just parse it as a field without alias.
7980
ParseField<Input>
@@ -98,24 +99,22 @@ type ParseField<Input extends string> = Input extends ''
9899
? Name extends 'count'
99100
? ParseCountField<Input>
100101
: 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'>
107107
: CreateParserErrorIfRequired<
108108
ParseEmbeddedResource<EatWhitespace<Remainder>>,
109109
`Expected embedded resource after "!inner" at \`${Remainder}\``
110110
>
111111
: 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'>
119118
: CreateParserErrorIfRequired<
120119
ParseEmbeddedResource<EatWhitespace<Remainder>>,
121120
`Expected embedded resource after "!left" at \`${EatWhitespace<Remainder>}\``
@@ -124,30 +123,36 @@ type ParseField<Input extends string> = Input extends ''
124123
? ParseIdentifier<EatWhitespace<Remainder>> extends [infer Hint, `${infer Remainder}`]
125124
? EatWhitespace<Remainder> extends `!inner${infer Remainder}`
126125
? ParseEmbeddedResource<EatWhitespace<Remainder>> extends [
127-
infer Children extends Ast.Node[],
126+
infer Children,
128127
`${infer Remainder}`
129128
]
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'>
135136
: ParseEmbeddedResource<EatWhitespace<Remainder>>
136137
: ParseEmbeddedResource<EatWhitespace<Remainder>> extends [
137-
infer Children extends Ast.Node[],
138+
infer Children,
138139
`${infer Remainder}`
139140
]
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'>
142148
: ParseEmbeddedResource<EatWhitespace<Remainder>>
143149
: ParserError<`Expected identifier after "!" at \`${EatWhitespace<Remainder>}\``>
144150
: 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'>
151156
: // Return error if start of embedded resource was detected but not found.
152157
ParseEmbeddedResource<EatWhitespace<Remainder>>
153158
: // Otherwise it's a non-embedded resource field.
@@ -184,13 +189,12 @@ type ParseCountField<Input extends string> = ParseIdentifier<Input> extends [
184189
type ParseEmbeddedResource<Input extends string> = Input extends `(${infer Remainder}`
185190
? EatWhitespace<Remainder> extends `)${infer Remainder}`
186191
? [[], 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'>
194198
: ParseNodes<EatWhitespace<Remainder>>
195199
: ParserError<`Expected "(" at \`${Input}\``>
196200

src/select-query-parser/result.ts

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,18 @@ export type GetResult<
3535
Relationships,
3636
Query extends string
3737
> = IsAny<Schema> extends true
38-
? ParseQuery<Query> extends infer ParsedQuery extends Ast.Node[]
39-
? RelationName extends string
40-
? ProcessNodesWithoutSchema<ParsedQuery>
41-
: any
38+
? ParseQuery<Query> extends infer ParsedQuery
39+
? ParsedQuery extends Ast.Node[]
40+
? RelationName extends string
41+
? ProcessNodesWithoutSchema<ParsedQuery>
42+
: any
43+
: ParsedQuery
4244
: any
4345
: Relationships extends null // For .rpc calls the passed relationships will be null in that case, the result will always be the function return type
44-
? ParseQuery<Query> extends infer ParsedQuery extends Ast.Node[]
45-
? RPCCallNodes<ParsedQuery, RelationName extends string ? RelationName : 'rpc_call', Row>
46+
? ParseQuery<Query> extends infer ParsedQuery
47+
? ParsedQuery extends Ast.Node[]
48+
? RPCCallNodes<ParsedQuery, RelationName extends string ? RelationName : 'rpc_call', Row>
49+
: ParsedQuery
4650
: Row
4751
: ParseQuery<Query> extends infer ParsedQuery
4852
? ParsedQuery extends Ast.Node[]
@@ -111,11 +115,15 @@ type ProcessNodeWithoutSchema<Node extends Ast.Node> = Node extends Ast.StarNode
111115
type ProcessNodesWithoutSchema<
112116
Nodes extends Ast.Node[],
113117
Acc extends Record<string, unknown> = {}
114-
> = Nodes extends [infer FirstNode extends Ast.Node, ...infer RestNodes extends Ast.Node[]]
115-
? ProcessNodeWithoutSchema<FirstNode> extends infer FieldResult
116-
? FieldResult extends Record<string, unknown>
117-
? ProcessNodesWithoutSchema<RestNodes, Acc & FieldResult>
118-
: FieldResult
118+
> = Nodes extends [infer FirstNode, ...infer RestNodes]
119+
? FirstNode extends Ast.Node
120+
? RestNodes extends Ast.Node[]
121+
? ProcessNodeWithoutSchema<FirstNode> extends infer FieldResult
122+
? FieldResult extends Record<string, unknown>
123+
? ProcessNodesWithoutSchema<RestNodes, Acc & FieldResult>
124+
: FieldResult
125+
: any
126+
: any
119127
: any
120128
: Prettify<Acc>
121129

@@ -144,14 +152,18 @@ export type RPCCallNodes<
144152
RelationName extends string,
145153
Row extends Record<string, unknown>,
146154
Acc extends Record<string, unknown> = {} // Acc is now an object
147-
> = Nodes extends [infer FirstNode extends Ast.Node, ...infer RestNodes extends Ast.Node[]]
148-
? ProcessRPCNode<Row, RelationName, FirstNode> extends infer FieldResult
149-
? FieldResult extends Record<string, unknown>
150-
? RPCCallNodes<RestNodes, RelationName, Row, Acc & FieldResult>
151-
: FieldResult extends SelectQueryError<infer E>
152-
? SelectQueryError<E>
153-
: SelectQueryError<'Could not retrieve a valid record or error value'>
154-
: SelectQueryError<'Processing node failed.'>
155+
> = Nodes extends [infer FirstNode, ...infer RestNodes]
156+
? FirstNode extends Ast.Node
157+
? RestNodes extends Ast.Node[]
158+
? ProcessRPCNode<Row, RelationName, FirstNode> extends infer FieldResult
159+
? FieldResult extends Record<string, unknown>
160+
? RPCCallNodes<RestNodes, RelationName, Row, Acc & FieldResult>
161+
: FieldResult extends SelectQueryError<infer E>
162+
? SelectQueryError<E>
163+
: SelectQueryError<'Could not retrieve a valid record or error value'>
164+
: SelectQueryError<'Processing node failed.'>
165+
: SelectQueryError<'Invalid rest nodes array in RPC call'>
166+
: SelectQueryError<'Invalid first node in RPC call'>
155167
: Prettify<Acc>
156168

157169
/**
@@ -172,14 +184,18 @@ export type ProcessNodes<
172184
Nodes extends Ast.Node[],
173185
Acc extends Record<string, unknown> = {} // Acc is now an object
174186
> = CheckDuplicateEmbededReference<Schema, RelationName, Relationships, Nodes> extends false
175-
? Nodes extends [infer FirstNode extends Ast.Node, ...infer RestNodes extends Ast.Node[]]
176-
? ProcessNode<Schema, Row, RelationName, Relationships, FirstNode> extends infer FieldResult
177-
? FieldResult extends Record<string, unknown>
178-
? ProcessNodes<Schema, Row, RelationName, Relationships, RestNodes, Acc & FieldResult>
179-
: FieldResult extends SelectQueryError<infer E>
180-
? SelectQueryError<E>
181-
: SelectQueryError<'Could not retrieve a valid record or error value'>
182-
: SelectQueryError<'Processing node failed.'>
187+
? Nodes extends [infer FirstNode, ...infer RestNodes]
188+
? FirstNode extends Ast.Node
189+
? RestNodes extends Ast.Node[]
190+
? ProcessNode<Schema, Row, RelationName, Relationships, FirstNode> extends infer FieldResult
191+
? FieldResult extends Record<string, unknown>
192+
? ProcessNodes<Schema, Row, RelationName, Relationships, RestNodes, Acc & FieldResult>
193+
: FieldResult extends SelectQueryError<infer E>
194+
? SelectQueryError<E>
195+
: SelectQueryError<'Could not retrieve a valid record or error value'>
196+
: SelectQueryError<'Processing node failed.'>
197+
: SelectQueryError<'Invalid rest nodes array type in ProcessNodes'>
198+
: SelectQueryError<'Invalid first node type in ProcessNodes'>
183199
: Prettify<Acc>
184200
: Prettify<CheckDuplicateEmbededReference<Schema, RelationName, Relationships, Nodes>>
185201

0 commit comments

Comments
 (0)