Skip to content

Commit 14910bf

Browse files
bnjmnt4nsteve-chavez
authored andcommitted
feat: query parser: handle empty embedded resources ()
Closes #445.
1 parent e6a64c6 commit 14910bf

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

src/select-query-parser.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ type ConstructFieldDefinition<
202202
Field['children'],
203203
unknown
204204
>
205+
: Field extends { children: [] }
206+
? {}
205207
: Field extends { name: string; original: string; hint: string; children: unknown[] }
206208
? {
207209
[_ in Field['name']]: GetResultHelper<
@@ -460,19 +462,22 @@ type ParseJsonAccessor<Input extends string> = Input extends `->${infer Remainde
460462

461463
/**
462464
* Parses an embedded resource, which is an opening `(`, followed by a sequence of
463-
* nodes, separated by `,`, then a closing `)`.
465+
* 0 or more nodes separated by `,`, then a closing `)`.
464466
*
465467
* Returns a tuple of ["Parsed fields", "Remainder of text"], an error,
466468
* or the original string input indicating that no opening `(` was found.
467469
*/
468470
type ParseEmbeddedResource<Input extends string> = Input extends `(${infer Remainder}`
469471
? ParseNodes<EatWhitespace<Remainder>> extends [infer Fields, `${infer Remainder}`]
470472
? EatWhitespace<Remainder> extends `)${infer Remainder}`
471-
? Fields extends []
472-
? ParserError<'Expected fields after `(`'>
473-
: [Fields, EatWhitespace<Remainder>]
473+
? [Fields, EatWhitespace<Remainder>]
474474
: ParserError<`Expected ")"`>
475-
: ParseNodes<EatWhitespace<Remainder>>
475+
: // If no nodes were detected, check for `)` for empty embedded resources `()`.
476+
ParseNodes<EatWhitespace<Remainder>> extends ParserError<string>
477+
? EatWhitespace<Remainder> extends `)${infer Remainder}`
478+
? [[], EatWhitespace<Remainder>]
479+
: ParseNodes<EatWhitespace<Remainder>>
480+
: ParserError<'Expected embedded resource fields or `)`'>
476481
: Input
477482

478483
/**

test/index.test-d.ts

+9
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ const postgrest = new PostgrestClient<Database>(REST_URL)
7979
)
8080
}
8181

82+
// embedded resource with no fields
83+
{
84+
const { data, error } = await postgrest.from('messages').select('message, users()').single()
85+
if (error) {
86+
throw new Error(error.message)
87+
}
88+
expectType<{ message: string | null }>(data)
89+
}
90+
8291
// json accessor in select query
8392
{
8493
const { data, error } = await postgrest

0 commit comments

Comments
 (0)