diff --git a/grafast/dataplan-pg/src/adaptors/pg.ts b/grafast/dataplan-pg/src/adaptors/pg.ts index ca64331227..131803e785 100644 --- a/grafast/dataplan-pg/src/adaptors/pg.ts +++ b/grafast/dataplan-pg/src/adaptors/pg.ts @@ -417,7 +417,7 @@ export function createWithPgClient( } // This is here as a TypeScript assertion, to ensure we conform to PgAdaptor -const _testValidAdaptor: PgAdaptor["createWithPgClient"] = +const _testValidAdaptor: PgAdaptor<"@dataplan/pg/adaptors/pg">["createWithPgClient"] = createWithPgClient; const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); @@ -718,8 +718,8 @@ declare global { } export function makePgService( - options: MakePgServiceOptions & { pool?: pg.Pool }, -): GraphileConfig.PgServiceConfiguration { + options: MakePgServiceOptions & { pool?: pg.Pool }, +): GraphileConfig.PgServiceConfiguration { const { name = "main", connectionString, @@ -760,7 +760,7 @@ export function makePgService( pgSubscriber = new PgSubscriber(pool); releasers.push(() => pgSubscriber!.release?.()); } - const service: GraphileConfig.PgServiceConfiguration = { + const service: GraphileConfig.PgServiceConfiguration = { name, schemas: Array.isArray(schemas) ? schemas : [schemas ?? "public"], withPgClientKey: withPgClientKey as any, @@ -769,7 +769,7 @@ export function makePgService( pgSettings, pgSettingsForIntrospection, pgSubscriber, - adaptor: { createWithPgClient }, + adaptor: { createWithPgClient, makePgService }, adaptorSettings: { pool, superuserConnectionString, diff --git a/grafast/dataplan-pg/src/executor.ts b/grafast/dataplan-pg/src/executor.ts index d2d07061db..fe02914f70 100644 --- a/grafast/dataplan-pg/src/executor.ts +++ b/grafast/dataplan-pg/src/executor.ts @@ -76,7 +76,7 @@ export interface PgClient { withTransaction(callback: (client: this) => Promise): Promise; } -export interface WithPgClient { +export interface WithPgClient { ( pgSettings: { [key: string]: string } | null, callback: (client: TPgClient) => T | Promise, diff --git a/grafast/dataplan-pg/src/index.ts b/grafast/dataplan-pg/src/index.ts index 70f7c81bf4..359b993b9c 100644 --- a/grafast/dataplan-pg/src/index.ts +++ b/grafast/dataplan-pg/src/index.ts @@ -1,6 +1,7 @@ import type { GrafastSubscriber } from "grafast"; import { exportAsMany } from "grafast"; +import type {NodePostgresPgClient, PgAdaptorSettings} from "./adaptors/pg.js"; import { domainOfCodec, enumCodec, @@ -426,15 +427,15 @@ export { version } from "./version.js"; declare global { namespace GraphileConfig { - interface PgServiceConfiguration { + interface PgServiceConfiguration { name: string; schemas?: string[]; - adaptor: PgAdaptor; - adaptorSettings?: TAdaptorSettings; + adaptor: DataplanPg.PgClientByAdaptor[TAdaptor]["adaptor"]; + adaptorSettings?: DataplanPg.PgClientByAdaptor[TAdaptor]["adaptorSettings"]; /** The key on 'context' where the withPgClient function will be sourced */ - withPgClientKey: KeysOfType>; + withPgClientKey: KeysOfType>; /** Return settings to set in the session */ pgSettings?: ( @@ -467,7 +468,7 @@ declare global { } interface Preset { - pgServices?: ReadonlyArray>; + pgServices?: ReadonlyArray; } } namespace DataplanPg { @@ -504,5 +505,14 @@ declare global { interface PgCodecAttributeExtensions {} interface PgRefDefinitionExtensions {} interface PgCodecRelationExtensions {} + + interface PgClientByAdaptor { + "@dataplan/pg/adaptors/pg": { + adaptor: PgAdaptor; + adaptorSettings: PgAdaptorSettings, + client: NodePostgresPgClient; + }; + // Add more here via declaration merging + } } } diff --git a/grafast/dataplan-pg/src/interfaces.ts b/grafast/dataplan-pg/src/interfaces.ts index d323a5a8bb..4b7747cf12 100644 --- a/grafast/dataplan-pg/src/interfaces.ts +++ b/grafast/dataplan-pg/src/interfaces.ts @@ -9,7 +9,7 @@ import type { PgResourceParameter, PgResourceUnique, } from "./datasource.js"; -import type { PgClient, PgExecutor} from "./executor.js"; +import type { PgExecutor} from "./executor.js"; import type { PgDeleteSingleStep } from "./steps/pgDeleteSingle.js"; import type { PgInsertSingleStep } from "./steps/pgInsertSingle.js"; import type { PgSelectSingleStep } from "./steps/pgSelectSingle.js"; @@ -415,10 +415,10 @@ export type KeysOfType = { [key in keyof TObject]: TObject[key] extends TValueType ? key : never; }[keyof TObject]; -export interface MakePgServiceOptions +export interface MakePgServiceOptions extends Partial< Pick< - GraphileConfig.PgServiceConfiguration, + GraphileConfig.PgServiceConfiguration, | "name" | "pgSettings" | "pgSettingsForIntrospection" diff --git a/grafast/dataplan-pg/src/pgServices.ts b/grafast/dataplan-pg/src/pgServices.ts index 94d473c1ce..6f97f133d1 100644 --- a/grafast/dataplan-pg/src/pgServices.ts +++ b/grafast/dataplan-pg/src/pgServices.ts @@ -1,13 +1,19 @@ -import type { PgClient, WithPgClient } from "./executor.ts"; +import type * as pg from "pg"; + +import type { PgClient, WithPgClient } from "./executor"; +import type {MakePgServiceOptions} from "./interfaces"; type PromiseOrDirect = T | PromiseLike; /** @experimental */ -export interface PgAdaptor { +export interface PgAdaptor { createWithPgClient: ( - adaptorSettings: TAdaptorSettings | undefined, + adaptorSettings: DataplanPg.PgClientByAdaptor[TAdaptor]["adaptorSettings"] | undefined, variant?: "SUPERUSER" | null, - ) => PromiseOrDirect>; + ) => PromiseOrDirect>; + makePgService: ( + options: MakePgServiceOptions & { pool?: pg.Pool }, + ) => GraphileConfig.PgServiceConfiguration } /** @@ -27,7 +33,7 @@ interface PgClientBySourceCacheValue { } const withPgClientDetailsByConfigCache = new Map< - GraphileConfig.PgServiceConfiguration, + GraphileConfig.PgServiceConfiguration, PromiseOrDirect >(); @@ -35,8 +41,8 @@ const withPgClientDetailsByConfigCache = new Map< * Get or build the 'withPgClient' callback function for a given database * config, caching it to make future lookups faster. */ -export function getWithPgClientFromPgService( - config: GraphileConfig.PgServiceConfiguration, +export function getWithPgClientFromPgService( + config: GraphileConfig.PgServiceConfiguration, ): PromiseOrDirect> { const existing = withPgClientDetailsByConfigCache.get(config); if (existing) { @@ -60,7 +66,7 @@ export function getWithPgClientFromPgService - originalWithPgClient.apply(null, args)) as WithPgClient; + originalWithPgClient.apply(null, args)) as WithPgClient; const cachedValue: PgClientBySourceCacheValue = { withPgClient, retainers: 1, @@ -97,10 +103,10 @@ export function getWithPgClientFromPgService( - config: GraphileConfig.PgServiceConfiguration, +export async function withPgClientFromPgService( + config: GraphileConfig.PgServiceConfiguration, pgSettings: { [key: string]: string } | null, - callback: (client: TPgClient) => T | Promise, + callback: (client: PgClient) => T | Promise, ): Promise { const withPgClientFromPgService = getWithPgClientFromPgService(config); const withPgClient = isPromiseLike(withPgClientFromPgService) @@ -114,10 +120,10 @@ export async function withPgClientFromPgService( - config: GraphileConfig.PgServiceConfiguration, +export async function withSuperuserPgClientFromPgService( + config: GraphileConfig.PgServiceConfiguration, pgSettings: { [key: string]: string } | null, - callback: (client: TPgClient) => T | Promise, + callback: (client: PgClient) => T | Promise, ): Promise { const withPgClient = await config.adaptor.createWithPgClient( config.adaptorSettings, diff --git a/graphile-build/graphile-build-pg/src/plugins/PgIntrospectionPlugin.ts b/graphile-build/graphile-build-pg/src/plugins/PgIntrospectionPlugin.ts index 2d37f749b3..c07ae43167 100644 --- a/graphile-build/graphile-build-pg/src/plugins/PgIntrospectionPlugin.ts +++ b/graphile-build/graphile-build-pg/src/plugins/PgIntrospectionPlugin.ts @@ -1,4 +1,4 @@ -import type { KeysOfType, PgClient, WithPgClient } from "@dataplan/pg"; +import type { KeysOfType, WithPgClient } from "@dataplan/pg"; import { PgExecutor, withPgClientFromPgService, @@ -66,7 +66,7 @@ declare global { getIntrospection(): PromiseOrDirect; getService(serviceName: string): Promise<{ introspection: Introspection; - pgService: GraphileConfig.PgServiceConfiguration; + pgService: GraphileConfig.PgServiceConfiguration; }>; getExecutorForService(serviceName: string): PgExecutor; @@ -229,7 +229,7 @@ declare global { } type IntrospectionResults = Array<{ - pgService: GraphileConfig.PgServiceConfiguration; + pgService: GraphileConfig.PgServiceConfiguration; introspection: Introspection; }>; @@ -706,7 +706,7 @@ export const PgIntrospectionPlugin: GraphileConfig.Plugin = { function introspectPgServices( pgServices: - | ReadonlyArray> + | ReadonlyArray | undefined, ): Promise { if (!pgServices) {