Skip to content

Commit

Permalink
Add ReturnShape to Model Types ++ Fix edgeDBFields resolve return typ…
Browse files Browse the repository at this point in the history
…e on array types
  • Loading branch information
baristikir committed Aug 22, 2022
1 parent eb18ba4 commit f853b76
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 40 deletions.
21 changes: 6 additions & 15 deletions packages/plugin-edgedb/src/global-types.ts
Expand Up @@ -100,30 +100,21 @@ declare global {
ResolveShape,
ResolveReturnShape,
Type extends TypeParam extends [unknown]
? [ObjectRef<Model['Shape']>]
: ObjectRef<Model['Shape']>,
? [ObjectRef<Model['ReturnShape']>]
: ObjectRef<Model['ReturnShape']>,
Model extends EdgeDBModelTypes = EdgeDBModelShape<
Types,
// @ts-expect-error -> string | number | symbol not assignable to ..
TypeParam extends [keyof Types['EdgeDBTypes']['default']]
? keyof Types['EdgeDBTypes']['default'][TypeParam[0]]
? TypeParam[0]
: TypeParam extends [EdgeDBObjectRef<EdgeDBModelTypes>]
? TypeParam[0][typeof edgeDBModelKey]
? TypeParam[0][typeof edgeDBModelKey]['Name']
: TypeParam extends EdgeDBObjectRef<EdgeDBModelTypes>
? TypeParam[typeof edgeDBModelKey]
? TypeParam[typeof edgeDBModelKey]['Name']
: TypeParam extends keyof Types['EdgeDBTypes']['default']
? TypeParam
: never
> &
(TypeParam extends [keyof Types['EdgeDBTypes']['default']]
? Types['EdgeDBTypes']['default'][TypeParam[0]]
: TypeParam extends [EdgeDBObjectRef<EdgeDBModelTypes>]
? TypeParam[0][typeof edgeDBModelKey]
: TypeParam extends EdgeDBObjectRef<EdgeDBModelTypes>
? TypeParam[typeof edgeDBModelKey]
: TypeParam extends keyof Types['EdgeDBTypes']['default']
? Types['EdgeDBTypes']['default'][TypeParam]
: never),
>,
>(
options: EdgeDBFieldOptions<
Types,
Expand Down
85 changes: 63 additions & 22 deletions packages/plugin-edgedb/src/types.ts
Expand Up @@ -57,7 +57,8 @@ export type EdgeDBSchemaTypes<Types extends SchemaTypes> =
export interface EdgeDBModelTypes {
Name: string;
Shape: {};
MultiLinks: string;
ReturnShape: {};
MultiLink: string;
LinkName: string;
Links: Record<
string,
Expand All @@ -71,29 +72,57 @@ export interface EdgeDBModelTypes {
export type EdgeDBModelShape<
Types extends SchemaTypes,
Name extends EdgeDBSchemaTypeKeys<Types>,
> = EdgeDBSchemaTypes<Types>[Name] extends infer Property
? Property extends BaseObject
> = EdgeDBSchemaTypes<Types>[Name] extends infer ModelProperties
? ModelProperties extends BaseObject
? {
Name: Name;
Shape: Property;
MultiLinks: '';
LinkName: extractLinks<Property> extends infer Link
Shape: ModelProperties;
ReturnShape: {
[K in keyof ModelProperties]?: ModelProperties[K] extends ObjectType
? ModelProperties[K] extends infer Link
? { [K in keyof Link]?: Link[K] }
: ModelProperties[K]
: ModelProperties[K];
};
MultiLink: extractMultiLinks<ModelProperties> extends infer Link
? Link extends string
? SplitLT<Link>
: never
: never;
LinkName: extractLinks<ModelProperties> extends infer Link
? Link extends string
? SplitLT<Link>
: never
: never;
} extends infer ModelTypesWithoutLinks
? ModelTypesWithoutLinks extends { LinkName: string; Shape: Record<string, unknown> }
? ModelTypesWithoutLinks extends {
LinkName: string;
Shape: Record<string, unknown>;
}
? ModelTypesWithoutLinks & {
Links: {
[Key in ModelTypesWithoutLinks['LinkName']]: {
Shape: ModelTypesWithoutLinks['Shape'][Key] extends infer Shape
? Shape extends BaseObject
? Shape
? { [K in keyof Shape]?: Shape[K] }
: Shape extends Array<BaseObject>
? Shape[0]
? { [K in keyof Shape[0]]?: Shape[0][K] }
: never
: never;
Types: EdgeDBModelShape<
Types,
ModelTypesWithoutLinks['Shape'][Key] extends infer Base
? Base extends TypeSet<ObjectType>
? Base['__element__']['__name__'] extends infer ModelName
? ModelName extends string
? SplitDefault<ModelName> extends EdgeDBSchemaTypeKeys<Types>
? SplitDefault<ModelName>
: never
: never
: never
: never
: never
>;
};
};
}
Expand Down Expand Up @@ -275,16 +304,17 @@ type extractLinksToPartial<Shape extends { [key: string]: any }> = Shape extends
: never
: never;

// Extract links from queryBuilder object, not from type
// Shape extends infer T
// ? T extends TypeSet<ObjectType>
// ? {
// [K in keyof T['__element__']['__pointers__']]: T['__element__']['__pointers__'][K] extends LinkDesc
// ? boolean
// : never;
// }
// : never
// : never;
type extractMultiLinksToPartial<Shape extends { [key: string]: any }> = Shape extends infer T
? T extends object
? {
[Key in keyof Shape]: Shape[Key] extends infer Link
? Link extends Array<BaseObject>
? boolean
: never
: never;
}
: never
: never;

// Filter out links from model type
export type extractLinks<
Expand All @@ -295,14 +325,25 @@ export type extractLinks<
[K in keyof Links]: [boolean] extends [Links[K]] ? K : never;
}[keyof Links]
: null;
export type extractMultiLinks<
Model extends object,
PartialLinks extends extractMultiLinksToPartial<Model> = extractMultiLinksToPartial<Model>,
> = PartialLinks extends infer Links
? {
[K in keyof Links]: [boolean] extends [Links[K]] ? K : never;
}[keyof Links]
: null;

type Split<S extends string, D extends string> = S extends `${infer T}${D}${infer U}`
? never
: [S][0];

// For removing backlinks from `link` fields
// eg. fields: "posts" | "comments" | "<author" -> fields: "posts" | "comments"
// eg. SplitLT<"posts" | "comments" | "<author"> -> "posts" | "comments"
export type SplitLT<LinkOptions extends string> = Split<LinkOptions, '<'>;
// Only way to get models name is to split it on its BaseObject __name__
// eg. SplitDefault<"default::Post"> -> "Post"
export type SplitDefault<LinkOptions extends string> = Split<LinkOptions, 'default::'>;

export type EdgeDBObjectFieldOptions<
Types extends SchemaTypes,
Expand Down Expand Up @@ -394,8 +435,8 @@ export type EdgeDBFieldResolver<
info: GraphQLResolveInfo,
) => ShapeFromTypeParam<Types, Param, Nullable> extends infer Shape
? [Shape] extends [[readonly (infer Item)[] | null | undefined]]
? ListResolveValue<Partial<Shape>, Item, ResolveReturnShape>
: MaybePromise<Partial<Shape>>
? ListResolveValue<Shape, Item, ResolveReturnShape>
: MaybePromise<Shape>
: never;

export type EdgeDBFieldOptions<
Expand Down
20 changes: 17 additions & 3 deletions packages/plugin-edgedb/tests/example/schema/index.ts
Expand Up @@ -62,20 +62,34 @@ builder.queryType({
return user;
},
}),
users: t.edgeDBField({
user: t.edgeDBField({
type: 'User',
nullable: true,
resolve: async (_query, _parent, _args, ctx) => {
const user = await e
.select(e.User, (user) => ({
...e.User['*'],
filter: e.op(user.id, '=', e.uuid(ctx.user.id)),
}))
.run(db);
return user;
// ^?
},
}),
users: t.edgeDBField({
type: ['User'],
nullable: true,
resolve: async (_query, _parent, _args, ctx) => {
const users = await e
.select(e.User, (user) => ({
id: true,
email: true,
name: true,
filter: e.op(user.id, '=', e.uuid(ctx.user.id)),
}))
.run(db);

return user;
return users;
// ^?
},
}),
}),
Expand Down

0 comments on commit f853b76

Please sign in to comment.