Skip to content

Commit f30fcc2

Browse files
bnjmnt4nsteve-chavez
authored andcommitted
Parser: Split parsing of type casts into separate helper
1 parent e525751 commit f30fcc2

File tree

1 file changed

+43
-18
lines changed

1 file changed

+43
-18
lines changed

src/select-query-parser.ts

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -394,30 +394,55 @@ type ParseField<Input extends string> = Input extends ''
394394
* - `field`
395395
* - `field::type`
396396
* - `field->json...`
397-
*
398-
* TODO: support type casting of JSON operators `a->b::type`, `a->>b::type`.
397+
* - `field->json...::type`
399398
*/
400399
type ParseFieldWithoutEmbeddedResource<Input extends string> = Input extends ''
401400
? ParserError<'Empty string'>
402-
: ParseIdentifier<Input> extends [infer Name, `${infer Remainder}`]
403-
? ParseJsonAccessor<EatWhitespace<Remainder>> extends [
404-
infer PropertyName,
405-
infer PropertyType,
406-
`${infer Remainder}`
407-
]
408-
? // `field->json...`
409-
[{ name: PropertyName; original: PropertyName; type: PropertyType }, EatWhitespace<Remainder>]
410-
: EatWhitespace<Remainder> extends `::${infer Remainder}`
411-
? ParseIdentifier<Remainder> extends [`${infer CastType}`, `${infer Remainder}`]
412-
? // `field::type`
413-
CastType extends PostgreSQLTypes
414-
? [{ name: Name; type: TypeScriptTypes<CastType> }, EatWhitespace<Remainder>]
415-
: ParserError<`Invalid type for \`::\` operator \`${CastType}\``>
416-
: ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``>
401+
: ParseFieldWithoutEmbeddedResourceAndTypeCast<Input> extends [infer Field, `${infer Remainder}`]
402+
? ParseFieldTypeCast<EatWhitespace<Remainder>> extends [infer Type, `${infer Remainder}`]
403+
? // `field::type`
404+
[Field & { type: Type }, EatWhitespace<Remainder>]
405+
: ParseFieldTypeCast<EatWhitespace<Remainder>> extends ParserError<string>
406+
? ParseFieldTypeCast<EatWhitespace<Remainder>>
417407
: // `field`
418-
[{ name: Name; original: Name }, EatWhitespace<Remainder>]
408+
[Field, EatWhitespace<Remainder>]
419409
: ParserError<`Expected identifier at \`${Input}\``>
420410

411+
/**
412+
* Parses a field excluding embedded resources or typecasting, without preceding field renaming.
413+
* This is one of the following:
414+
* - `field`
415+
* - `field->json...`
416+
*/
417+
type ParseFieldWithoutEmbeddedResourceAndTypeCast<Input extends string> =
418+
ParseIdentifier<Input> extends [infer Name, `${infer Remainder}`]
419+
? ParseJsonAccessor<EatWhitespace<Remainder>> extends [
420+
infer PropertyName,
421+
infer PropertyType,
422+
`${infer Remainder}`
423+
]
424+
? // `field->json...`
425+
[
426+
{ name: PropertyName; original: PropertyName; type: PropertyType },
427+
EatWhitespace<Remainder>
428+
]
429+
: // `field`
430+
[{ name: Name; original: Name }, EatWhitespace<Remainder>]
431+
: ParserError<`Expected field at \`${Input}\``>
432+
433+
/**
434+
* Parses a field typecast (`::type`), returning a tuple of ["Type", "Remainder of text"]
435+
* or the original string input indicating that no typecast was found.
436+
*/
437+
type ParseFieldTypeCast<Input extends string> = EatWhitespace<Input> extends `::${infer Remainder}`
438+
? ParseIdentifier<EatWhitespace<Remainder>> extends [`${infer CastType}`, `${infer Remainder}`]
439+
? // Ensure that `CastType` is a valid type.
440+
CastType extends PostgreSQLTypes
441+
? [TypeScriptTypes<CastType>, EatWhitespace<Remainder>]
442+
: ParserError<`Invalid type for \`::\` operator \`${CastType}\``>
443+
: ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``>
444+
: Input
445+
421446
/**
422447
* Parses a node.
423448
* A node is one of the following:

0 commit comments

Comments
 (0)