@pothos/plugin-dataloader
Version:
A Pothos plugin for attaching dataloader to object types
243 lines (229 loc) • 7.04 kB
text/typescript
import type {
FieldKind,
FieldNullability,
FieldOptionsFromKind,
InferredFieldOptionKeys,
InputFieldMap,
InputShapeFromFields,
InterfaceParam,
InterfaceRef,
InterfaceTypeOptions,
MaybePromise,
ObjectParam,
ObjectRef,
ObjectTypeOptions,
OutputRef,
OutputShape,
OutputType,
Resolver,
SchemaTypes,
ShapeFromTypeParam,
TypeParam,
} from '@pothos/core';
import type DataLoader from 'dataloader';
import type { GraphQLResolveInfo } from 'graphql';
export type DataloaderKey = bigint | number | string;
export type LoadableFieldOptions<
Types extends SchemaTypes,
ParentShape,
Type extends TypeParam<Types>,
Nullable extends FieldNullability<Type>,
Args extends InputFieldMap,
ResolveReturnShape,
Key,
CacheKey,
Kind extends FieldKind = FieldKind,
ByPath extends boolean = boolean,
> = Omit<
FieldOptionsFromKind<Types, ParentShape, Type, Nullable, Args, Kind, Key, ResolveReturnShape>,
InferredFieldOptionKeys
> & {
byPath?: ByPath;
load: (
keys: Key[],
context: Types['Context'],
args: false extends ByPath ? never : InputShapeFromFields<Args>,
info: false extends ByPath ? never : GraphQLResolveInfo,
) => Promise<readonly (Error | LoaderShapeFromType<Types, Type, Nullable>)[]>;
loaderOptions?: DataLoader.Options<Key, LoaderShapeFromType<Types, Type, Nullable>, CacheKey>;
sort?: (value: LoaderShapeFromType<Types, Type, false>) => Key;
resolve: Resolver<
ParentShape,
InputShapeFromFields<Args>,
Types['Context'],
(Type extends unknown[] ? [OutputRef<Key>] : OutputRef<Key>) extends infer KeyType
? KeyType extends OutputRef | [OutputRef]
? ShapeFromTypeParam<
Types,
KeyType,
Nullable extends FieldNullability<KeyType> ? Nullable : never
>
: never
: never,
ResolveReturnShape
>;
};
export type LoadableListFieldOptions<
Types extends SchemaTypes,
ParentShape,
Type extends OutputType<Types>,
Nullable extends FieldNullability<[Type]>,
Args extends InputFieldMap,
ResolveReturnShape,
Key,
CacheKey,
Kind extends FieldKind = FieldKind,
ByPath extends boolean = boolean,
> = Omit<
FieldOptionsFromKind<Types, ParentShape, [Type], Nullable, Args, Kind, Key, ResolveReturnShape>,
InferredFieldOptionKeys | 'type'
> & {
type: Type;
byPath?: ByPath;
load: (
keys: Key[],
context: Types['Context'],
args: false extends ByPath ? never : InputShapeFromFields<Args>,
info: false extends ByPath ? never : GraphQLResolveInfo,
) => Promise<readonly (Error | ShapeFromTypeParam<Types, [Type], Nullable>)[]>;
loaderOptions?: DataLoader.Options<Key, ShapeFromTypeParam<Types, [Type], Nullable>, CacheKey>;
sort?: (value: ShapeFromTypeParam<Types, [Type], false>) => Key;
resolve: Resolver<
ParentShape,
InputShapeFromFields<Args>,
Types['Context'],
Key,
ResolveReturnShape
>;
};
export type LoadableGroupFieldOptions<
Types extends SchemaTypes,
ParentShape,
Type extends OutputType<Types>,
Nullable extends FieldNullability<[Type]>,
Args extends InputFieldMap,
ResolveReturnShape,
Key,
CacheKey,
Kind extends FieldKind = FieldKind,
ByPath extends boolean = boolean,
> = Omit<
FieldOptionsFromKind<Types, ParentShape, [Type], Nullable, Args, Kind, Key, ResolveReturnShape>,
InferredFieldOptionKeys | 'type'
> & {
type: Type;
byPath?: ByPath;
load: (
keys: Key[],
context: Types['Context'],
args: false extends ByPath ? never : InputShapeFromFields<Args>,
info: false extends ByPath ? never : GraphQLResolveInfo,
) => Promise<readonly ShapeFromTypeParam<Types, Type, true>[]>;
loaderOptions?: DataLoader.Options<Key, ShapeFromTypeParam<Types, Type, true>[], CacheKey>;
group: (value: ShapeFromTypeParam<Types, Type, false>) => Key;
resolve: Resolver<
ParentShape,
InputShapeFromFields<Args>,
Types['Context'],
Key,
ResolveReturnShape
>;
};
export type DataLoaderOptions<
Types extends SchemaTypes,
LoadResult,
Key extends bigint | number | string,
CacheKey,
Shape = ShapeFromLoadResult<LoadResult>,
> = {
load: (keys: Key[], context: Types['Context']) => Promise<readonly LoadResult[]>;
loaderOptions?: DataLoader.Options<Key, Shape, CacheKey>;
} & (
| {
toKey: (value: Shape) => Key;
cacheResolved?: boolean;
sort?: boolean;
}
| {
toKey?: undefined;
cacheResolved?: (value: Shape) => Key;
sort?: (value: Shape) => Key;
}
);
export type DataloaderObjectTypeOptions<
Types extends SchemaTypes,
LoadResult,
Key extends bigint | number | string,
Interfaces extends InterfaceParam<Types>[],
NameOrRef extends ObjectParam<Types> | string,
CacheKey,
Shape,
> = DataLoaderOptions<Types, LoadResult, Key, CacheKey, Shape> &
ObjectTypeOptions<
Types,
NameOrRef extends ObjectParam<Types> ? NameOrRef : ObjectRef<Types, Shape>,
Shape,
Interfaces
>;
export type LoadableInterfaceOptions<
Types extends SchemaTypes,
LoadResult,
Key extends bigint | number | string,
Interfaces extends InterfaceParam<Types>[],
NameOrRef extends InterfaceParam<Types> | string,
CacheKey,
Shape = ShapeFromLoadResult<LoadResult>,
> = DataLoaderOptions<Types, LoadResult, Key, CacheKey, Shape> &
InterfaceTypeOptions<
Types,
NameOrRef extends InterfaceParam<Types> ? NameOrRef : InterfaceRef<Types, Shape>,
Shape,
Interfaces
>;
export type LoadableUnionOptions<
Types extends SchemaTypes,
Key extends bigint | number | string,
Member extends ObjectParam<Types>,
CacheKey,
Shape,
> = DataLoaderOptions<Types, Shape | Error, Key, CacheKey, Shape> &
PothosSchemaTypes.UnionTypeOptions<Types, Member>;
export type LoaderShapeFromType<
Types extends SchemaTypes,
Type extends TypeParam<Types>,
Nullable extends FieldNullability<Type>,
> = Type extends [TypeParam<Types>]
? ShapeFromTypeParam<Types, Type[0], Nullable extends { items: infer N } ? N : Nullable>
: ShapeFromTypeParam<Types, Type, Nullable>;
export interface LoadableRef<K, V, C> {
getDataloader: (context: C) => DataLoader<K, V>;
}
export interface LoadableNodeId<Types extends SchemaTypes, Shape, IDShape> {
id: Omit<
FieldOptionsFromKind<
Types,
Shape,
'ID',
false,
{},
'Object',
Shape,
MaybePromise<OutputShape<Types, 'ID'>>
>,
'args' | 'nullable' | 'type'
> & {
parse?: (id: string, ctx: Types['Context']) => IDShape;
};
}
export type LoadableNodeOptions<
Types extends SchemaTypes,
LoadResult,
Interfaces extends InterfaceParam<Types>[],
NameOrRef extends ObjectParam<Types> | string,
IDShape extends bigint | number | string = string,
Key extends bigint | number | string = IDShape,
CacheKey = Key,
Shape = ShapeFromLoadResult<LoadResult>,
> = DataloaderObjectTypeOptions<Types, LoadResult, Key, Interfaces, NameOrRef, CacheKey, Shape> &
LoadableNodeId<Types, Shape, IDShape>;
export type ShapeFromLoadResult<T> = Exclude<T, Error>;