Skip to content

Commit 166fe5f

Browse files
committed
rework types
1 parent d262f40 commit 166fe5f

File tree

5 files changed

+622
-523
lines changed

5 files changed

+622
-523
lines changed

grafast/dataplan-pg/src/codecs.ts

Lines changed: 84 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,12 @@ import {
3838
import type { PgExecutor } from "./executor.js";
3939
import { inspect } from "./inspect.js";
4040
import type {
41+
AnyPgCodec,
4142
PgCodec,
43+
PgCodecAttributes,
44+
PgCodecAttributesRecord,
4245
PgCodecExtensions,
46+
PgCodecFromPostgres,
4347
PgCodecPolymorphism,
4448
PgDecode,
4549
PgEncode,
@@ -59,10 +63,21 @@ export type PgCodecAttributeVia = string | PgCodecAttributeViaExplicit;
5963
/** @deprecated Use DataplanPg.PgCodecAttributeExtensions instead */
6064
export type PgCodecAttributeExtensions = DataplanPg.PgCodecAttributeExtensions;
6165

66+
export type AnyPgCodecAttribute = PgCodecAttribute<any, any, any>;
67+
export type PgCodecAttributeName<U> = U extends PgCodecAttribute<
68+
infer TName,
69+
any,
70+
any
71+
>
72+
? TName
73+
: never;
74+
6275
export interface PgCodecAttribute<
63-
TCodec extends PgCodec = PgCodec,
64-
TNotNull extends boolean = boolean,
76+
TName extends string,
77+
TCodec extends AnyPgCodec,
78+
TNotNull extends boolean,
6579
> {
80+
name: TName;
6681
/**
6782
* How to translate to/from PG and how to cast.
6883
*/
@@ -129,14 +144,6 @@ export interface PgCodecAttribute<
129144
extensions?: Partial<PgCodecAttributeExtensions>;
130145
}
131146

132-
export type PgCodecAttributes<
133-
TCodecMap extends {
134-
[attributeName in string]: PgCodecAttribute;
135-
} = {
136-
[attributeName in string]: PgCodecAttribute;
137-
},
138-
> = TCodecMap;
139-
140147
/**
141148
* Returns a PgCodec for the given builtin Postgres scalar type, optionally
142149
* pass the following config:
@@ -160,12 +167,12 @@ function t<TFromJavaScript = any, TFromPostgres = string>(): <
160167
options?: Cast<TFromJavaScript, TFromPostgres>,
161168
) => PgCodec<
162169
TName,
163-
undefined,
170+
never,
164171
TFromPostgres,
165172
TFromJavaScript,
166-
undefined,
167-
undefined,
168-
undefined
173+
never,
174+
never,
175+
never
169176
> {
170177
return (oid, type, options = {}) => {
171178
const { castFromPg, listCastFromPg, fromPg, toPg, isBinary } = options;
@@ -174,7 +181,6 @@ function t<TFromJavaScript = any, TFromPostgres = string>(): <
174181
sqlType: sql.identifier(...type.split(".")),
175182
fromPg: fromPg ?? (identity as any),
176183
toPg: toPg ?? (identity as any),
177-
attributes: undefined,
178184
extensions: { oid: oid },
179185
castFromPg,
180186
listCastFromPg,
@@ -318,11 +324,13 @@ function recordStringToTuple(value: string): Array<string | null> {
318324
return tuple;
319325
}
320326

321-
function realAttributeDefs<TAttributes extends PgCodecAttributes>(
322-
attributes: TAttributes,
323-
): Array<[string, TAttributes[keyof TAttributes]]> {
327+
function realAttributeDefs<
328+
TAttributes extends ReadonlyArray<AnyPgCodecAttribute>,
329+
>(
330+
attributes: PgCodecAttributesRecord<TAttributes>,
331+
): Array<[PgCodecAttributeName<TAttributes[number]>, TAttributes[number]]> {
324332
const attributeDefs = Object.entries(attributes) as Array<
325-
[string, TAttributes extends infer U ? U[keyof U] : never]
333+
[PgCodecAttributeName<TAttributes[number]>, TAttributes[number]]
326334
>;
327335
return attributeDefs.filter(
328336
([_attributeName, spec]) => !spec.expression && !spec.via,
@@ -336,8 +344,10 @@ function realAttributeDefs<TAttributes extends PgCodecAttributes>(
336344
*
337345
* @see {@link https://www.postgresql.org/docs/current/rowtypes.html#id-1.5.7.24.6}
338346
*/
339-
function makeRecordToSQLRawValue<TAttributes extends PgCodecAttributes>(
340-
attributes: TAttributes,
347+
function makeRecordToSQLRawValue<
348+
TAttributes extends ReadonlyArray<AnyPgCodecAttribute>,
349+
>(
350+
attributes: PgCodecAttributesRecord<TAttributes>,
341351
): PgEncode<ObjectFromPgCodecAttributes<TAttributes>> {
342352
const attributeDefs = realAttributeDefs(attributes);
343353
return (value) => {
@@ -350,19 +360,21 @@ function makeRecordToSQLRawValue<TAttributes extends PgCodecAttributes>(
350360
};
351361
}
352362

353-
export type ObjectFromPgCodecAttributes<TAttributes extends PgCodecAttributes> =
354-
{
355-
[attributeName in keyof TAttributes]: TAttributes[attributeName] extends PgCodecAttribute<
356-
infer UCodec,
357-
infer UNonNull
358-
>
359-
? UCodec extends PgCodec<any, any, any, infer UFromJs, any, any, any>
360-
? UNonNull extends true
361-
? Exclude<UFromJs, null | undefined>
362-
: UFromJs | null
363-
: never
364-
: never;
365-
};
363+
export type ObjectFromPgCodecAttributes<
364+
TAttributes extends ReadonlyArray<AnyPgCodecAttribute>,
365+
> = {
366+
[TCodecAttribute in TAttributes[number] as PgCodecAttributeName<TCodecAttribute>]: TCodecAttribute extends PgCodecAttribute<
367+
any,
368+
infer UCodec,
369+
infer UNonNull
370+
>
371+
? UCodec extends PgCodec<any, any, any, infer UFromJs, any, any, any>
372+
? UNonNull extends true
373+
? Exclude<UFromJs, null | undefined>
374+
: UFromJs | null
375+
: never
376+
: never;
377+
};
366378

367379
/**
368380
* Takes a list of attributes and returns a mapping function that takes a
@@ -371,8 +383,10 @@ export type ObjectFromPgCodecAttributes<TAttributes extends PgCodecAttributes> =
371383
*
372384
* @see {@link https://www.postgresql.org/docs/current/rowtypes.html#id-1.5.7.24.6}
373385
*/
374-
function makeSQLValueToRecord<TAttributes extends PgCodecAttributes>(
375-
attributes: TAttributes,
386+
function makeSQLValueToRecord<
387+
TAttributes extends ReadonlyArray<AnyPgCodecAttribute>,
388+
>(
389+
attributes: PgCodecAttributesRecord<TAttributes>,
376390
): (value: string) => ObjectFromPgCodecAttributes<TAttributes> {
377391
const attributeDefs = realAttributeDefs(attributes);
378392
const attributeCount = attributeDefs.length;
@@ -390,12 +404,12 @@ function makeSQLValueToRecord<TAttributes extends PgCodecAttributes>(
390404

391405
export type PgRecordTypeCodecSpec<
392406
TName extends string,
393-
TAttributes extends PgCodecAttributes,
407+
TAttributes extends ReadonlyArray<AnyPgCodecAttribute>,
394408
> = {
395409
name: TName;
396410
executor: PgExecutor;
397411
identifier: SQL;
398-
attributes: TAttributes;
412+
attributes: PgCodecAttributesRecord<TAttributes>;
399413
polymorphism?: PgCodecPolymorphism<any>;
400414
description?: string;
401415
extensions?: Partial<PgCodecExtensions>;
@@ -413,18 +427,18 @@ export type PgRecordTypeCodecSpec<
413427
* isAnonymous - if true, this represents an "anonymous" type, typically the return value of a function or something like that. If this is true, then name and identifier are ignored.
414428
*/
415429
export function recordCodec<
416-
const TName extends string,
417-
const TAttributes extends PgCodecAttributes,
430+
TName extends string,
431+
TAttributes extends ReadonlyArray<AnyPgCodecAttribute>,
418432
>(
419433
config: PgRecordTypeCodecSpec<TName, TAttributes>,
420434
): PgCodec<
421435
TName,
422436
TAttributes,
423437
string,
424438
ObjectFromPgCodecAttributes<TAttributes>,
425-
undefined,
426-
undefined,
427-
undefined
439+
never,
440+
never,
441+
never
428442
> {
429443
const {
430444
name,
@@ -504,14 +518,14 @@ type CodecWithListCodec<
504518
`${TCodec extends PgCodec<infer UName, any, any, any, any, any, any>
505519
? UName
506520
: never}[]`,
507-
undefined,
521+
never,
508522
string,
509-
TCodec extends PgCodec<any, any, any, infer UFromJs, undefined, any, any>
523+
TCodec extends PgCodec<any, any, any, infer UFromJs, never, any, any>
510524
? UFromJs[]
511525
: any[],
512526
TCodec,
513-
undefined,
514-
undefined
527+
never,
528+
never
515529
>;
516530
};
517531

@@ -529,7 +543,7 @@ type CodecWithListCodec<
529543
* @param identifier - a pg-sql2 fragment that represents the name of this type
530544
*/
531545
export function listOfCodec<
532-
TInnerCodec extends PgCodec<string, any, any, any, undefined, any, any>,
546+
TInnerCodec extends PgCodec<string, any, any, any, never, any, any>,
533547
>(
534548
listedCodec: TInnerCodec,
535549
config?: {
@@ -542,14 +556,14 @@ export function listOfCodec<
542556
`${TInnerCodec extends PgCodec<infer UName, any, any, any, any, any, any>
543557
? UName
544558
: never}[]`,
545-
undefined, // Array has no attributes
559+
never, // Array has no attributes
546560
string,
547-
TInnerCodec extends PgCodec<any, any, any, infer UFromJs, undefined, any, any>
561+
TInnerCodec extends PgCodec<any, any, any, infer UFromJs, never, any, any>
548562
? UFromJs[]
549563
: any[],
550564
TInnerCodec,
551-
undefined,
552-
undefined
565+
never,
566+
never
553567
> {
554568
const innerCodec: CodecWithListCodec<TInnerCodec> = listedCodec;
555569

@@ -568,22 +582,14 @@ export function listOfCodec<
568582
`${TInnerCodec extends PgCodec<infer UName, any, any, any, any, any, any>
569583
? UName
570584
: never}[]`,
571-
undefined, // Array has no attributes
585+
never, // Array has no attributes
572586
string,
573-
TInnerCodec extends PgCodec<
574-
any,
575-
any,
576-
any,
577-
infer UFromJs,
578-
undefined,
579-
any,
580-
any
581-
>
587+
TInnerCodec extends PgCodec<any, any, any, infer UFromJs, never, any, any>
582588
? UFromJs[]
583589
: any[],
584590
TInnerCodec,
585-
undefined,
586-
undefined
591+
never,
592+
never
587593
> = {
588594
name: `${
589595
innerCodec.name as TInnerCodec extends PgCodec<
@@ -661,7 +667,7 @@ exportAs("@dataplan/pg", listOfCodec, "listOfCodec");
661667
*/
662668
export function domainOfCodec<
663669
TName extends string,
664-
TInnerCodec extends PgCodec<any, any, any, any, any, any>,
670+
TInnerCodec extends AnyPgCodec,
665671
>(
666672
innerCodec: TInnerCodec,
667673
name: TName,
@@ -673,13 +679,15 @@ export function domainOfCodec<
673679
} = {},
674680
): PgCodec<
675681
TName,
676-
TInnerCodec extends PgCodec<any, infer U, any, any, any, any> ? U : any,
677-
TInnerCodec extends PgCodec<any, any, infer U, any, any, any> ? U : any,
678-
undefined,
682+
PgCodecAttributes<TInnerCodec>,
683+
PgCodecFromPostgres<TInnerCodec>,
684+
any,
679685
TInnerCodec,
680-
undefined
686+
never,
687+
any
681688
> {
682689
const { description, extensions, notNull } = config;
690+
683691
return {
684692
// Generally same as underlying type:
685693
...innerCodec,
@@ -689,7 +697,7 @@ export function domainOfCodec<
689697
sqlType: identifier,
690698
description,
691699
extensions,
692-
domainOfCodec: innerCodec.arrayOfCodec ? undefined : innerCodec,
700+
...(innerCodec.arrayOfCodec ? {} : { domainOfCodec: innerCodec }),
693701
notNull: Boolean(notNull),
694702
};
695703
}
@@ -701,7 +709,7 @@ exportAs("@dataplan/pg", domainOfCodec, "domainOfCodec");
701709
* @internal
702710
*/
703711
function escapeRangeValue<
704-
TInnerCodec extends PgCodec<any, undefined, any, any, undefined, any, any>,
712+
TInnerCodec extends PgCodec<any, never, any, any, never, any, any>,
705713
>(value: null | any, innerCodec: TInnerCodec): string {
706714
if (value == null) {
707715
return "";
@@ -727,15 +735,7 @@ interface PgRange<T> {
727735
*/
728736
export function rangeOfCodec<
729737
TName extends string,
730-
TInnerCodec extends PgCodec<
731-
any,
732-
undefined,
733-
any,
734-
any,
735-
undefined,
736-
any,
737-
undefined
738-
>,
738+
TInnerCodec extends PgCodec<any, never, any, any, never, any, never>,
739739
>(
740740
innerCodec: TInnerCodec,
741741
name: TName,
@@ -744,15 +744,7 @@ export function rangeOfCodec<
744744
description?: string;
745745
extensions?: Partial<PgCodecExtensions>;
746746
} = {},
747-
): PgCodec<
748-
TName,
749-
undefined,
750-
string,
751-
PgRange<unknown>,
752-
undefined,
753-
undefined,
754-
TInnerCodec
755-
> {
747+
): PgCodec<TName, never, string, PgRange<unknown>, never, never, TInnerCodec> {
756748
const { description, extensions } = config;
757749
const needsCast = innerCodec.castFromPg;
758750

@@ -1169,17 +1161,16 @@ export function getCodecByPgCatalogTypeName(pgCatalogTypeName: string) {
11691161
return null;
11701162
}
11711163

1172-
export function getInnerCodec<
1173-
TCodec extends PgCodec<any, any, any, any, any, any>,
1174-
>(
1164+
export function getInnerCodec<TCodec extends AnyPgCodec>(
11751165
codec: TCodec,
11761166
): TCodec extends PgCodec<
11771167
any,
11781168
any,
11791169
any,
11801170
infer UArray,
11811171
infer UDomain,
1182-
infer URange
1172+
infer URange,
1173+
any
11831174
>
11841175
? Exclude<UDomain | UArray | URange, undefined>
11851176
: TCodec {

0 commit comments

Comments
 (0)