diff --git a/.changeset/shaggy-mugs-agree.md b/.changeset/shaggy-mugs-agree.md new file mode 100644 index 0000000000..fba6ebfeb0 --- /dev/null +++ b/.changeset/shaggy-mugs-agree.md @@ -0,0 +1,8 @@ +--- +"graphile-build-pg": patch +"postgraphile": patch +"@dataplan/pg": patch +--- + +Tweak some types to allow defining the types of the final PgRegistry via +declaration merging (requires codegen). diff --git a/grafast/dataplan-pg/src/codecs.ts b/grafast/dataplan-pg/src/codecs.ts index 26eb80ebe8..8cd4e495b8 100644 --- a/grafast/dataplan-pg/src/codecs.ts +++ b/grafast/dataplan-pg/src/codecs.ts @@ -961,8 +961,7 @@ export function rangeOfCodec< : null), fromPg: needsCast ? function (value) { - const json = JSON.parse(value); - const [lowerInc, lower, upper, upperInc, empty] = json; + const [lowerInc, lower, upper, upperInc, empty] = JSON.parse(value); return empty ? { empty: true } : { diff --git a/grafast/dataplan-pg/src/datasource.ts b/grafast/dataplan-pg/src/datasource.ts index 56709a5f7b..89c0d713aa 100644 --- a/grafast/dataplan-pg/src/datasource.ts +++ b/grafast/dataplan-pg/src/datasource.ts @@ -137,11 +137,14 @@ export interface PgResourceParameter< */ export interface PgResourceUnique< TAttributes extends PgCodecAttributes = PgCodecAttributes, + TUniqueAttributes extends ReadonlyArray< + keyof TAttributes & string + > = ReadonlyArray, > { /** * The attributes that are unique */ - attributes: ReadonlyArray; + attributes: TUniqueAttributes; /** * If this is true, this represents the "primary key" of the resource. */ diff --git a/grafast/dataplan-pg/src/index.ts b/grafast/dataplan-pg/src/index.ts index 429aee6172..fbf77fc20a 100644 --- a/grafast/dataplan-pg/src/index.ts +++ b/grafast/dataplan-pg/src/index.ts @@ -236,6 +236,8 @@ export type { PgCodecAttributeVia, PgCodecAttributeViaExplicit, PgCodecExtensions, + PgCodecFromJavaScriptType, + PgCodecFromPostgresType, PgCodecList, PgCodecPolymorphism, PgCodecPolymorphismRelational, @@ -281,6 +283,7 @@ export type { PgPath, PgPoint, PgPolygon, + PgRangeValue, PgRecordTypeCodecSpec, PgRefDefinition, PgRefDefinitionExtensions, @@ -318,11 +321,6 @@ export type { TuplePlanMap, WithPgClient, }; -export type { - PgCodecFromJavaScriptType, - PgCodecFromPostgresType, - PgRangeValue, -}; export { assertPgClassSingleStep, domainOfCodec, diff --git a/grafast/dataplan-pg/src/interfaces.ts b/grafast/dataplan-pg/src/interfaces.ts index b0281b5ac5..adc271affb 100644 --- a/grafast/dataplan-pg/src/interfaces.ts +++ b/grafast/dataplan-pg/src/interfaces.ts @@ -462,10 +462,7 @@ export type PlanByUniques< TAttributes extends PgCodecAttributes, TUniqueAttributes extends ReadonlyArray>, > = TAttributes extends PgCodecAttributes - ? TuplePlanMap< - TAttributes, - TUniqueAttributes[number]["attributes"] & string[] - >[number] + ? TuplePlanMap[number] : undefined; export type PgConditionLike = Modifier & { @@ -652,12 +649,7 @@ export interface PgRegistry< PgCodec >, TResourceOptions extends { - [name in string]: PgResourceOptions< - name, - PgCodec, // TCodecs[keyof TCodecs], - ReadonlyArray>, - readonly PgResourceParameter[] | undefined - >; + [name in string]: PgResourceOptions; } = Record< string, PgResourceOptions< @@ -670,18 +662,7 @@ export interface PgRegistry< >, TRelations extends { [codecName in keyof TCodecs]?: { - [relationName in string]: PgCodecRelationConfig< - // TCodecs[keyof TCodecs] & - PgCodec, - // TResourceOptions[keyof TResourceOptions] & - PgResourceOptions< - any, - // TCodecs[keyof TCodecs] & - PgCodecWithAttributes, - any, - any - > - >; + [relationName in string]: PgCodecRelationConfig; }; } = Record< string, diff --git a/graphile-build/graphile-build-pg/src/index.ts b/graphile-build/graphile-build-pg/src/index.ts index 4de5d97eb1..7877ecd759 100644 --- a/graphile-build/graphile-build-pg/src/index.ts +++ b/graphile-build/graphile-build-pg/src/index.ts @@ -108,8 +108,15 @@ declare global { [tagName: string]: null | true | string | (string | true)[]; } + /** Augment this interface to provide generated build-time types. */ + interface GeneratedTypes {} + interface BuildInput { - pgRegistry: PgRegistry; + pgRegistry: GeneratedTypes extends { + pgRegistry: infer TRegistry extends PgRegistry; + } + ? TRegistry + : PgRegistry; } interface SchemaOptions { diff --git a/graphile-build/graphile-build-pg/src/plugins/PgBasicsPlugin.ts b/graphile-build/graphile-build-pg/src/plugins/PgBasicsPlugin.ts index 78c318f759..a758e1df84 100644 --- a/graphile-build/graphile-build-pg/src/plugins/PgBasicsPlugin.ts +++ b/graphile-build/graphile-build-pg/src/plugins/PgBasicsPlugin.ts @@ -5,7 +5,6 @@ import type { PgCodec, PgCodecRelation, PgCodecWithAttributes, - PgExecutor, PgRefDefinition, PgResource, PgResourceUnique, @@ -142,8 +141,13 @@ declare global { /** * Shortcut to primary executor; equivalent for most users to `build.input.pgRegistry.pgExecutors.main`. * (strictly it's `build.input.pgRegistry.pgExecutors[Object.keys(build.input.pgRegistry.pgExecutors)[0]]`) + * + * Note: the TypeScript type for this is an approximation, because + * TypeScript doesn't have a concept of "first key". For most people + * there will be just a single executor anyway, and the type of the + * executor doesn't tend to matter much. */ - pgExecutor: PgExecutor; + pgExecutor: GraphileBuild.Build["input"]["pgRegistry"]["pgExecutors"][keyof GraphileBuild.Build["input"]["pgRegistry"]["pgExecutors"]]; /** Shortcut to the resources in the registry */ pgResources: GraphileBuild.Build["input"]["pgRegistry"]["pgResources"]; /** Shortcut to the codecs in the registry */