Skip to content

Commit f853b76

Browse files
committed
Add ReturnShape to Model Types ++ Fix edgeDBFields resolve return type on array types
1 parent eb18ba4 commit f853b76

File tree

3 files changed

+86
-40
lines changed

3 files changed

+86
-40
lines changed

packages/plugin-edgedb/src/global-types.ts

+6-15
Original file line numberDiff line numberDiff line change
@@ -100,30 +100,21 @@ declare global {
100100
ResolveShape,
101101
ResolveReturnShape,
102102
Type extends TypeParam extends [unknown]
103-
? [ObjectRef<Model['Shape']>]
104-
: ObjectRef<Model['Shape']>,
103+
? [ObjectRef<Model['ReturnShape']>]
104+
: ObjectRef<Model['ReturnShape']>,
105105
Model extends EdgeDBModelTypes = EdgeDBModelShape<
106106
Types,
107107
// @ts-expect-error -> string | number | symbol not assignable to ..
108108
TypeParam extends [keyof Types['EdgeDBTypes']['default']]
109-
? keyof Types['EdgeDBTypes']['default'][TypeParam[0]]
109+
? TypeParam[0]
110110
: TypeParam extends [EdgeDBObjectRef<EdgeDBModelTypes>]
111-
? TypeParam[0][typeof edgeDBModelKey]
111+
? TypeParam[0][typeof edgeDBModelKey]['Name']
112112
: TypeParam extends EdgeDBObjectRef<EdgeDBModelTypes>
113-
? TypeParam[typeof edgeDBModelKey]
113+
? TypeParam[typeof edgeDBModelKey]['Name']
114114
: TypeParam extends keyof Types['EdgeDBTypes']['default']
115115
? TypeParam
116116
: never
117-
> &
118-
(TypeParam extends [keyof Types['EdgeDBTypes']['default']]
119-
? Types['EdgeDBTypes']['default'][TypeParam[0]]
120-
: TypeParam extends [EdgeDBObjectRef<EdgeDBModelTypes>]
121-
? TypeParam[0][typeof edgeDBModelKey]
122-
: TypeParam extends EdgeDBObjectRef<EdgeDBModelTypes>
123-
? TypeParam[typeof edgeDBModelKey]
124-
: TypeParam extends keyof Types['EdgeDBTypes']['default']
125-
? Types['EdgeDBTypes']['default'][TypeParam]
126-
: never),
117+
>,
127118
>(
128119
options: EdgeDBFieldOptions<
129120
Types,

packages/plugin-edgedb/src/types.ts

+63-22
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ export type EdgeDBSchemaTypes<Types extends SchemaTypes> =
5757
export interface EdgeDBModelTypes {
5858
Name: string;
5959
Shape: {};
60-
MultiLinks: string;
60+
ReturnShape: {};
61+
MultiLink: string;
6162
LinkName: string;
6263
Links: Record<
6364
string,
@@ -71,29 +72,57 @@ export interface EdgeDBModelTypes {
7172
export type EdgeDBModelShape<
7273
Types extends SchemaTypes,
7374
Name extends EdgeDBSchemaTypeKeys<Types>,
74-
> = EdgeDBSchemaTypes<Types>[Name] extends infer Property
75-
? Property extends BaseObject
75+
> = EdgeDBSchemaTypes<Types>[Name] extends infer ModelProperties
76+
? ModelProperties extends BaseObject
7677
? {
7778
Name: Name;
78-
Shape: Property;
79-
MultiLinks: '';
80-
LinkName: extractLinks<Property> extends infer Link
79+
Shape: ModelProperties;
80+
ReturnShape: {
81+
[K in keyof ModelProperties]?: ModelProperties[K] extends ObjectType
82+
? ModelProperties[K] extends infer Link
83+
? { [K in keyof Link]?: Link[K] }
84+
: ModelProperties[K]
85+
: ModelProperties[K];
86+
};
87+
MultiLink: extractMultiLinks<ModelProperties> extends infer Link
88+
? Link extends string
89+
? SplitLT<Link>
90+
: never
91+
: never;
92+
LinkName: extractLinks<ModelProperties> extends infer Link
8193
? Link extends string
8294
? SplitLT<Link>
8395
: never
8496
: never;
8597
} extends infer ModelTypesWithoutLinks
86-
? ModelTypesWithoutLinks extends { LinkName: string; Shape: Record<string, unknown> }
98+
? ModelTypesWithoutLinks extends {
99+
LinkName: string;
100+
Shape: Record<string, unknown>;
101+
}
87102
? ModelTypesWithoutLinks & {
88103
Links: {
89104
[Key in ModelTypesWithoutLinks['LinkName']]: {
90105
Shape: ModelTypesWithoutLinks['Shape'][Key] extends infer Shape
91106
? Shape extends BaseObject
92-
? Shape
107+
? { [K in keyof Shape]?: Shape[K] }
93108
: Shape extends Array<BaseObject>
94-
? Shape[0]
109+
? { [K in keyof Shape[0]]?: Shape[0][K] }
95110
: never
96111
: never;
112+
Types: EdgeDBModelShape<
113+
Types,
114+
ModelTypesWithoutLinks['Shape'][Key] extends infer Base
115+
? Base extends TypeSet<ObjectType>
116+
? Base['__element__']['__name__'] extends infer ModelName
117+
? ModelName extends string
118+
? SplitDefault<ModelName> extends EdgeDBSchemaTypeKeys<Types>
119+
? SplitDefault<ModelName>
120+
: never
121+
: never
122+
: never
123+
: never
124+
: never
125+
>;
97126
};
98127
};
99128
}
@@ -275,16 +304,17 @@ type extractLinksToPartial<Shape extends { [key: string]: any }> = Shape extends
275304
: never
276305
: never;
277306

278-
// Extract links from queryBuilder object, not from type
279-
// Shape extends infer T
280-
// ? T extends TypeSet<ObjectType>
281-
// ? {
282-
// [K in keyof T['__element__']['__pointers__']]: T['__element__']['__pointers__'][K] extends LinkDesc
283-
// ? boolean
284-
// : never;
285-
// }
286-
// : never
287-
// : never;
307+
type extractMultiLinksToPartial<Shape extends { [key: string]: any }> = Shape extends infer T
308+
? T extends object
309+
? {
310+
[Key in keyof Shape]: Shape[Key] extends infer Link
311+
? Link extends Array<BaseObject>
312+
? boolean
313+
: never
314+
: never;
315+
}
316+
: never
317+
: never;
288318

289319
// Filter out links from model type
290320
export type extractLinks<
@@ -295,14 +325,25 @@ export type extractLinks<
295325
[K in keyof Links]: [boolean] extends [Links[K]] ? K : never;
296326
}[keyof Links]
297327
: null;
328+
export type extractMultiLinks<
329+
Model extends object,
330+
PartialLinks extends extractMultiLinksToPartial<Model> = extractMultiLinksToPartial<Model>,
331+
> = PartialLinks extends infer Links
332+
? {
333+
[K in keyof Links]: [boolean] extends [Links[K]] ? K : never;
334+
}[keyof Links]
335+
: null;
298336

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

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

307348
export type EdgeDBObjectFieldOptions<
308349
Types extends SchemaTypes,
@@ -394,8 +435,8 @@ export type EdgeDBFieldResolver<
394435
info: GraphQLResolveInfo,
395436
) => ShapeFromTypeParam<Types, Param, Nullable> extends infer Shape
396437
? [Shape] extends [[readonly (infer Item)[] | null | undefined]]
397-
? ListResolveValue<Partial<Shape>, Item, ResolveReturnShape>
398-
: MaybePromise<Partial<Shape>>
438+
? ListResolveValue<Shape, Item, ResolveReturnShape>
439+
: MaybePromise<Shape>
399440
: never;
400441

401442
export type EdgeDBFieldOptions<

packages/plugin-edgedb/tests/example/schema/index.ts

+17-3
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,34 @@ builder.queryType({
6262
return user;
6363
},
6464
}),
65-
users: t.edgeDBField({
65+
user: t.edgeDBField({
6666
type: 'User',
6767
nullable: true,
6868
resolve: async (_query, _parent, _args, ctx) => {
6969
const user = await e
70+
.select(e.User, (user) => ({
71+
...e.User['*'],
72+
filter: e.op(user.id, '=', e.uuid(ctx.user.id)),
73+
}))
74+
.run(db);
75+
return user;
76+
// ^?
77+
},
78+
}),
79+
users: t.edgeDBField({
80+
type: ['User'],
81+
nullable: true,
82+
resolve: async (_query, _parent, _args, ctx) => {
83+
const users = await e
7084
.select(e.User, (user) => ({
7185
id: true,
7286
email: true,
7387
name: true,
74-
filter: e.op(user.id, '=', e.uuid(ctx.user.id)),
7588
}))
7689
.run(db);
7790

78-
return user;
91+
return users;
92+
// ^?
7993
},
8094
}),
8195
}),

0 commit comments

Comments
 (0)