Skip to content

Commit 959e749

Browse files
committed
feat: query parser: handle empty embedded resources ()
Closes #445.
1 parent 22e0003 commit 959e749

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
@@ -191,6 +191,8 @@ type ConstructFieldDefinition<
191191
Field
192192
> = Field extends { star: true }
193193
? Row
194+
: Field extends { children: [] }
195+
? {}
194196
: Field extends { name: string; original: string; hint: string; children: unknown[] }
195197
? {
196198
[_ in Field['name']]: GetResultHelper<
@@ -441,19 +443,22 @@ type ParseJsonAccessor<Input extends string> = Input extends `->${infer Remainde
441443

442444
/**
443445
* Parses an embedded resource, which is an opening `(`, followed by a sequence of
444-
* nodes, separated by `,`, then a closing `)`.
446+
* 0 or more nodes separated by `,`, then a closing `)`.
445447
*
446448
* Returns a tuple of ["Parsed fields", "Remainder of text"], an error,
447449
* or the original string input indicating that no opening `(` was found.
448450
*/
449451
type ParseEmbeddedResource<Input extends string> = Input extends `(${infer Remainder}`
450452
? ParseNodes<EatWhitespace<Remainder>> extends [infer Fields, `${infer Remainder}`]
451453
? EatWhitespace<Remainder> extends `)${infer Remainder}`
452-
? Fields extends []
453-
? ParserError<'Expected fields after `(`'>
454-
: [Fields, EatWhitespace<Remainder>]
454+
? [Fields, EatWhitespace<Remainder>]
455455
: ParserError<`Expected ")"`>
456-
: ParseNodes<EatWhitespace<Remainder>>
456+
: // If no nodes were detected, check for `)` for empty embedded resources `()`.
457+
ParseNodes<EatWhitespace<Remainder>> extends ParserError<string>
458+
? EatWhitespace<Remainder> extends `)${infer Remainder}`
459+
? [[], EatWhitespace<Remainder>]
460+
: ParseNodes<EatWhitespace<Remainder>>
461+
: ParserError<'Expected embedded resource fields or `)`'>
457462
: Input
458463

459464
/**

test/index.test-d.ts

+9
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ const postgrest = new PostgrestClient<Database>(REST_URL)
5353
expectError(postgrest.from('updatable_view').update({ non_updatable_column: 0 }))
5454
}
5555

56+
// embedded resource with no fields
57+
{
58+
const { data, error } = await postgrest.from('messages').select('message, users()').single()
59+
if (error) {
60+
throw new Error(error.message)
61+
}
62+
expectType<{ message: string | null }>(data)
63+
}
64+
5665
// json accessor in select query
5766
{
5867
const { data, error } = await postgrest

0 commit comments

Comments
 (0)