|
1 | 1 | // Credits to @bnjmnt4n (https://www.npmjs.com/package/postgrest-query)
|
| 2 | +// See https://github.com/PostgREST/postgrest/blob/2f91853cb1de18944a4556df09e52450b881cfb3/src/PostgREST/ApiRequest/QueryParams.hs#L282-L284 |
2 | 3 |
|
3 | 4 | import { GenericSchema, Prettify } from './types'
|
4 | 5 |
|
@@ -335,15 +336,12 @@ type ParseIdentifier<Input extends string> = ReadLetters<Input> extends [
|
335 | 336 | /**
|
336 | 337 | * Parses a field without preceding field renaming.
|
337 | 338 | * A field is one of the following:
|
338 |
| - * - `field` |
339 |
| - * - `field::type` |
340 |
| - * - `field->json...` |
341 |
| - * - `field(nodes)` |
342 |
| - * - `field!hint(nodes)` |
343 |
| - * - `field!inner(nodes)` |
344 |
| - * - `field!hint!inner(nodes)` |
345 |
| - * |
346 |
| - * TODO: support type casting of JSON operators `a->b::type`, `a->>b::type`. |
| 339 | + * - a field with an embedded resource |
| 340 | + * - `field(nodes)` |
| 341 | + * - `field!hint(nodes)` |
| 342 | + * - `field!inner(nodes)` |
| 343 | + * - `field!hint!inner(nodes)` |
| 344 | + * - a field without an embedded resource (see {@link ParseFieldWithoutEmbeddedResource}) |
347 | 345 | */
|
348 | 346 | type ParseField<Input extends string> = Input extends ''
|
349 | 347 | ? ParserError<'Empty string'>
|
@@ -383,15 +381,32 @@ type ParseField<Input extends string> = Input extends ''
|
383 | 381 | : ParseEmbeddedResource<EatWhitespace<Remainder>> extends [infer Fields, `${infer Remainder}`]
|
384 | 382 | ? // `field(nodes)`
|
385 | 383 | [{ name: Name; original: Name; children: Fields }, EatWhitespace<Remainder>]
|
386 |
| - : ParseJsonAccessor<EatWhitespace<Remainder>> extends [ |
387 |
| - infer PropertyName, |
388 |
| - infer PropertyType, |
389 |
| - `${infer Remainder}` |
390 |
| - ] |
| 384 | + : ParseEmbeddedResource<EatWhitespace<Remainder>> extends ParserError<string> |
| 385 | + ? // Return error if start of embedded resource was detected but not found. |
| 386 | + ParseEmbeddedResource<EatWhitespace<Remainder>> |
| 387 | + : // Otherwise try to match a field without embedded resource. |
| 388 | + ParseFieldWithoutEmbeddedResource<Input> |
| 389 | + : ParserError<`Expected identifier at \`${Input}\``> |
| 390 | + |
| 391 | +/** |
| 392 | + * Parses a field excluding embedded resources, without preceding field renaming. |
| 393 | + * This is one of the following: |
| 394 | + * - `field` |
| 395 | + * - `field::type` |
| 396 | + * - `field->json...` |
| 397 | + * |
| 398 | + * TODO: support type casting of JSON operators `a->b::type`, `a->>b::type`. |
| 399 | + */ |
| 400 | +type ParseFieldWithoutEmbeddedResource<Input extends string> = Input extends '' |
| 401 | + ? 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 | + ] |
391 | 408 | ? // `field->json...`
|
392 | 409 | [{ name: PropertyName; original: PropertyName; type: PropertyType }, EatWhitespace<Remainder>]
|
393 |
| - : ParseEmbeddedResource<EatWhitespace<Remainder>> extends ParserError<string> |
394 |
| - ? ParseEmbeddedResource<EatWhitespace<Remainder>> |
395 | 410 | : EatWhitespace<Remainder> extends `::${infer Remainder}`
|
396 | 411 | ? ParseIdentifier<Remainder> extends [`${infer CastType}`, `${infer Remainder}`]
|
397 | 412 | ? // `field::type`
|
|
0 commit comments