@@ -249,12 +249,12 @@ type ConstructFieldDefinition<
249
249
: Child [ ]
250
250
: never
251
251
}
252
+ : Field extends { name : string ; type : infer T }
253
+ ? { [ K in Field [ 'name' ] ] : T }
252
254
: Field extends { name : string ; original : string }
253
255
? Field [ 'original' ] extends keyof Row
254
256
? { [ K in Field [ 'name' ] ] : Row [ Field [ 'original' ] ] }
255
257
: SelectQueryError < `Referencing missing column \`${Field [ 'original' ] } \``>
256
- : Field extends { name : string ; type : infer T }
257
- ? { [ K in Field [ 'name' ] ] : T }
258
258
: Record < string , unknown >
259
259
260
260
/**
@@ -318,40 +318,22 @@ type ParseIdentifier<Input extends string> = ReadLetters<Input> extends [
318
318
: ParserError < `No (possibly double-quoted) identifier at \`${Input } \``>
319
319
320
320
/**
321
- * Parses a node.
322
- * A node is one of the following:
323
- * - `*`
321
+ * Parses a field without preceding field renaming.
322
+ * A field is one of the following:
324
323
* - `field`
325
324
* - `field::type`
326
325
* - `field->json...`
327
326
* - `field(nodes)`
328
327
* - `field!hint(nodes)`
329
328
* - `field!inner(nodes)`
330
329
* - `field!hint!inner(nodes)`
331
- * - `renamed_field:field`
332
- * - `renamed_field:field::type`
333
- * - `renamed_field:field->json...`
334
- * - `renamed_field:field(nodes)`
335
- * - `renamed_field:field!hint(nodes)`
336
- * - `renamed_field:field!inner(nodes)`
337
- * - `renamed_field:field!hint!inner(nodes)`
338
330
*
339
- * TODO: more support for JSON operators `-> `, `->>`.
331
+ * TODO: support type casting of JSON operators `a->b::type `, `a ->>b::type `.
340
332
*/
341
- type ParseNode < Input extends string > = Input extends ''
333
+ type ParseField < Input extends string > = Input extends ''
342
334
? ParserError < 'Empty string' >
343
- : // `*`
344
- Input extends `*${infer Remainder } `
345
- ? [ { star : true } , EatWhitespace < Remainder > ]
346
335
: ParseIdentifier < Input > extends [ infer Name , `${infer Remainder } `]
347
- ? EatWhitespace < Remainder > extends `::${infer Remainder } `
348
- ? ParseIdentifier < Remainder > extends [ infer CastType , `${infer Remainder } `]
349
- ? // `field::type`
350
- CastType extends PostgreSQLTypes
351
- ? [ { name : Name ; type : TypeScriptTypes < CastType > } , EatWhitespace < Remainder > ]
352
- : never
353
- : ParserError < `Unexpected type cast at \`${Input } \``>
354
- : EatWhitespace < Remainder > extends `!inner${infer Remainder } `
336
+ ? EatWhitespace < Remainder > extends `!inner${infer Remainder } `
355
337
? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [ infer Fields , `${infer Remainder } `]
356
338
? // `field!inner(nodes)`
357
339
[ { name : Name ; original : Name ; children : Fields } , EatWhitespace < Remainder > ]
@@ -383,79 +365,6 @@ type ParseNode<Input extends string> = Input extends ''
383
365
'Expected embedded resource after `!hint`'
384
366
>
385
367
: ParserError < 'Expected identifier after `!`' >
386
- : EatWhitespace < Remainder > extends `:${infer Remainder } `
387
- ? ParseIdentifier < EatWhitespace < Remainder > > extends [ infer OriginalName , `${infer Remainder } `]
388
- ? EatWhitespace < Remainder > extends `::${infer Remainder } `
389
- ? ParseIdentifier < Remainder > extends [ infer CastType , `${infer Remainder } `]
390
- ? // `renamed_field:field::type`
391
- CastType extends PostgreSQLTypes
392
- ? [ { name : Name ; type : TypeScriptTypes < CastType > } , EatWhitespace < Remainder > ]
393
- : never
394
- : ParserError < `Unexpected type cast at \`${Input } \``>
395
- : EatWhitespace < Remainder > extends `!inner${infer Remainder } `
396
- ? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
397
- infer Fields ,
398
- `${infer Remainder } `
399
- ]
400
- ? // `renamed_field:field!inner(nodes)`
401
- [ { name : Name ; original : OriginalName ; children : Fields } , EatWhitespace < Remainder > ]
402
- : CreateParserErrorIfRequired <
403
- ParseEmbeddedResource < EatWhitespace < Remainder > > ,
404
- 'Expected embedded resource after `!inner`'
405
- >
406
- : EatWhitespace < Remainder > extends `!${infer Remainder } `
407
- ? ParseIdentifier < EatWhitespace < Remainder > > extends [ infer Hint , `${infer Remainder } `]
408
- ? EatWhitespace < Remainder > extends `!inner${infer Remainder } `
409
- ? ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
410
- infer Fields ,
411
- `${infer Remainder } `
412
- ]
413
- ? // `renamed_field:field!hint!inner(nodes)`
414
- [
415
- { name : Name ; original : OriginalName ; hint : Hint ; children : Fields } ,
416
- EatWhitespace < Remainder >
417
- ]
418
- : CreateParserErrorIfRequired <
419
- ParseEmbeddedResource < EatWhitespace < Remainder > > ,
420
- 'Expected embedded resource after `!inner`'
421
- >
422
- : ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
423
- infer Fields ,
424
- `${infer Remainder } `
425
- ]
426
- ? // `renamed_field:field!hint(nodes)`
427
- [
428
- {
429
- name : Name
430
- original : OriginalName
431
- hint : Hint
432
- children : Fields
433
- } ,
434
- EatWhitespace < Remainder >
435
- ]
436
- : CreateParserErrorIfRequired <
437
- ParseEmbeddedResource < EatWhitespace < Remainder > > ,
438
- 'Expected embedded resource after `!hint`'
439
- >
440
- : ParserError < 'Expected identifier after `!`' >
441
- : ParseEmbeddedResource < EatWhitespace < Remainder > > extends [
442
- infer Fields ,
443
- `${infer Remainder } `
444
- ]
445
- ? // `renamed_field:field(nodes)`
446
- [ { name : Name ; original : OriginalName ; children : Fields } , EatWhitespace < Remainder > ]
447
- : ParseJsonAccessor < EatWhitespace < Remainder > > extends [
448
- infer _PropertyName ,
449
- infer PropertyType ,
450
- `${infer Remainder } `
451
- ]
452
- ? // `renamed_field:field->json...`
453
- [ { name : Name ; type : PropertyType } , EatWhitespace < Remainder > ]
454
- : ParseEmbeddedResource < EatWhitespace < Remainder > > extends ParserError < string >
455
- ? ParseEmbeddedResource < EatWhitespace < Remainder > >
456
- : // `renamed_field:field`
457
- [ { name : Name ; original : OriginalName } , EatWhitespace < Remainder > ]
458
- : ParseIdentifier < EatWhitespace < Remainder > >
459
368
: ParseEmbeddedResource < EatWhitespace < Remainder > > extends [ infer Fields , `${infer Remainder } `]
460
369
? // `field(nodes)`
461
370
[ { name : Name ; original : Name ; children : Fields } , EatWhitespace < Remainder > ]
@@ -465,13 +374,48 @@ type ParseNode<Input extends string> = Input extends ''
465
374
`${infer Remainder } `
466
375
]
467
376
? // `field->json...`
468
- [ { name : PropertyName ; type : PropertyType } , EatWhitespace < Remainder > ]
377
+ [ { name : PropertyName ; original : PropertyName ; type : PropertyType } , EatWhitespace < Remainder > ]
469
378
: ParseEmbeddedResource < EatWhitespace < Remainder > > extends ParserError < string >
470
379
? ParseEmbeddedResource < EatWhitespace < Remainder > >
380
+ : EatWhitespace < Remainder > extends `::${infer Remainder } `
381
+ ? ParseIdentifier < Remainder > extends [ `${infer CastType } `, `${infer Remainder } `]
382
+ ? // `field::type`
383
+ CastType extends PostgreSQLTypes
384
+ ? [ { name : Name ; type : TypeScriptTypes < CastType > } , EatWhitespace < Remainder > ]
385
+ : ParserError < `Invalid type for \`::\` operator \`$ { CastType } \``>
386
+ : ParserError < `Invalid type for \`::\` operator at \`$ { Remainder } \``>
471
387
: // `field`
472
388
[ { name : Name ; original : Name } , EatWhitespace < Remainder > ]
473
389
: ParserError < `Expected identifier at \`${Input } \``>
474
390
391
+ /**
392
+ * Parses a node.
393
+ * A node is one of the following:
394
+ * - `*`
395
+ * - a field, as defined above
396
+ * - a renamed field, `renamed_field:field`
397
+ */
398
+ type ParseNode < Input extends string > = Input extends ''
399
+ ? ParserError < 'Empty string' >
400
+ : // `*`
401
+ Input extends `*${infer Remainder } `
402
+ ? [ { star : true } , EatWhitespace < Remainder > ]
403
+ : ParseIdentifier < Input > extends [ infer Name , `${infer Remainder } `]
404
+ ? EatWhitespace < Remainder > extends `::${infer _Remainder } `
405
+ ? // `field::`
406
+ // Special case to detect type-casting before renaming.
407
+ ParseField < Input >
408
+ : EatWhitespace < Remainder > extends `:${infer Remainder } `
409
+ ? // `renamed_field:`
410
+ ParseField < EatWhitespace < Remainder > > extends [ infer Field , `${infer Remainder } `]
411
+ ? Field extends { name : string }
412
+ ? [ Prettify < Omit < Field , 'name' > & { name : Name } > , EatWhitespace < Remainder > ]
413
+ : ParserError < `Unable to parse renamed field`>
414
+ : ParserError < `Unable to parse renamed field`>
415
+ : // Otherwise, just parse it as a field without renaming.
416
+ ParseField < Input >
417
+ : ParserError < `Expected identifier at \`${Input } \``>
418
+
475
419
/**
476
420
* Parses a JSON property accessor of the shape `->a->b->c`. The last accessor in
477
421
* the series may convert to text by using the ->> operator instead of ->.
0 commit comments