;
+ }
+}
+
+type PointersToObjectType = ObjectType;
+
+export type SelectModifiers = {
+ filter?: TypeSet, Cardinality>;
+ order_by?: any;
+ offset?: any | number;
+ limit?: any | number;
+};
+
+// ---
+
+// object types -> pointers
+// pointers -> links
+// links -> target object type
+// links -> link properties
+export type extractObjectShapeToSelectShape = Partial<{
+ [k in keyof TObject['__pointers__']]: TObject['__pointers__'][k] extends PropertyDesc
+ ?
+ | boolean
+ | TypeSet<
+ TObject['__pointers__'][k]['target'],
+ CardinalityAssignable
+ >
+ : TObject['__pointers__'][k] extends LinkDesc
+ ? {} // as link, currently no type
+ : any;
+}> & { [key: string]: unknown };
+
+type extractLinksToPartial = Shape extends infer T
+ ? T extends object
+ ? {
+ [Key in keyof Shape]: Shape[Key] extends infer Link
+ ? Link extends BaseObject | Array
+ ? boolean
+ : never
+ : never;
+ }
+ : never
+ : never;
+
+type extractMultiLinksToPartial = Shape extends infer T
+ ? T extends object
+ ? {
+ [Key in keyof Shape]: Shape[Key] extends infer Link
+ ? Link extends Array
+ ? boolean
+ : never
+ : never;
+ }
+ : never
+ : never;
+
+// Filter out links from model type
+export type extractLinks<
+ Model extends object,
+ PartialLinks extends extractLinksToPartial = extractLinksToPartial,
+> = PartialLinks extends infer Links
+ ? {
+ [K in keyof Links]: [boolean] extends [Links[K]] ? K : never;
+ }[keyof Links]
+ : null;
+export type extractMultiLinks<
+ Model extends object,
+ PartialLinks extends extractMultiLinksToPartial = extractMultiLinksToPartial,
+> = PartialLinks extends infer Links
+ ? {
+ [K in keyof Links]: [boolean] extends [Links[K]] ? K : never;
+ }[keyof Links]
+ : null;
+
+type Split = S extends `${infer T}${D}${infer U}`
+ ? never
+ : [S][0];
+
+// For removing backlinks from `link` fields
+// eg. SplitLT<"posts" | "comments" | " -> "posts" | "comments"
+export type SplitLT = Split;
+// Only way to get models name is to split it on its BaseObject __name__
+// eg. SplitDefault<"default::Post"> -> "Post"
+export type SplitDefault = Split;
+
+export type EdgeDBObjectFieldOptions<
+ Types extends SchemaTypes,
+ ParentShape,
+ Type extends TypeParam,
+ Nullable extends FieldNullability,
+ Args extends InputFieldMap,
+ Select,
+ ResolveReturnShape,
+> = PothosSchemaTypes.ObjectFieldOptions<
+ Types,
+ ParentShape,
+ Type,
+ Nullable,
+ Args,
+ ResolveReturnShape
+>;
+
+type EdgeDBObjectFieldsShape<
+ Types extends SchemaTypes,
+ Model extends EdgeDBModelTypes,
+ Shape extends object,
+> = (t: EdgeDBObjectFieldBuilder) => FieldMap;
+
+export type EdgeDBObjectTypeOptions<
+ Types extends SchemaTypes,
+ Interfaces extends InterfaceParam[],
+ Model extends EdgeDBModelTypes,
+ Shape extends object,
+> = Omit<
+ | PothosSchemaTypes.ObjectTypeOptions
+ | PothosSchemaTypes.ObjectTypeWithInterfaceOptions,
+ 'fields' | 'description'
+> & {
+ description?: string | false;
+ fields?: EdgeDBObjectFieldsShape;
+};
+
+type RefForLink<
+ Model extends EdgeDBModelTypes,
+ Field extends keyof Model['Links'],
+> = Model['Links'][Field] extends unknown[]
+ ? [ObjectRef]
+ : ObjectRef;
+
+export type RelatedFieldOptions<
+ Types extends SchemaTypes,
+ Model extends EdgeDBModelTypes,
+ Field extends keyof Model['Links'],
+ Nullable extends boolean,
+ Args extends InputFieldMap,
+ ResolveReturnShape,
+ Shape,
+> = Omit<
+ PothosSchemaTypes.ObjectFieldOptions<
+ Types,
+ Shape,
+ RefForLink,
+ Nullable,
+ Args,
+ ResolveReturnShape
+ >,
+ 'resolve' | 'type' | 'description'
+> & {
+ resolve?: (
+ query: never,
+ parent: Shape,
+ args: InputShapeFromFields,
+ context: Types['Context'],
+ info: GraphQLResolveInfo,
+ ) => MaybePromise> & {
+ type?: EdgeDBObjectRef;
+ };
+};
+
+export type EdgeDBFieldResolver<
+ Types extends SchemaTypes,
+ Model extends EdgeDBModelTypes,
+ Parent,
+ Param extends TypeParam,
+ Args extends InputFieldMap,
+ Nullable extends FieldNullability,
+ ResolveReturnShape,
+> = (
+ query: {},
+ parent: Parent,
+ args: InputShapeFromFields,
+ context: Types['Context'],
+ info: GraphQLResolveInfo,
+) => ShapeFromTypeParam extends infer Shape
+ ? [Shape] extends [[readonly (infer Item)[] | null | undefined]]
+ ? ListResolveValue
+ : MaybePromise
+ : never;
+
+export type EdgeDBFieldOptions<
+ Types extends SchemaTypes,
+ ParentShape,
+ Type extends
+ | EdgeDBObjectRef
+ | keyof Types['EdgeDBTypes']['default']
+ | [keyof Types['EdgeDBTypes']['default']]
+ | [EdgeDBObjectRef],
+ Model extends EdgeDBModelTypes,
+ Param extends TypeParam,
+ Args extends InputFieldMap,
+ Nullable extends FieldNullability,
+ ResolveShape,
+ ResolveReturnShape,
+ Kind extends FieldKind = FieldKind,
+> = FieldOptionsFromKind<
+ Types,
+ ParentShape,
+ Param,
+ Nullable,
+ Args,
+ Kind,
+ ResolveShape,
+ ResolveReturnShape
+> extends infer FieldOptions
+ ? Omit & {
+ type: Type;
+ resolve: FieldOptions extends { resolve?: (parent: infer Parent, ...args: any[]) => unknown }
+ ? EdgeDBFieldResolver
+ : EdgeDBFieldResolver;
+ }
+ : never;
diff --git a/packages/plugin-edgedb/src/util/datamodel.ts b/packages/plugin-edgedb/src/util/datamodel.ts
new file mode 100644
index 000000000..0c6bd2ec9
--- /dev/null
+++ b/packages/plugin-edgedb/src/util/datamodel.ts
@@ -0,0 +1,65 @@
+import { SchemaTypes } from '@pothos/core';
+import { EdgeDBObjectRef } from '../object-ref';
+import { EdgeDBModelTypes } from '../types';
+import { getObjectsTypes } from './get-client';
+
+export const refMap = new WeakMap