Skip to content

Commit

Permalink
support indirect paths in queryFromInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
hayes committed Aug 19, 2022
1 parent 72de623 commit 5e71c28
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-rocks-bathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@pothos/plugin-prisma': minor
---

update queryFromInfo to support indirect paths
20 changes: 12 additions & 8 deletions packages/plugin-prisma/src/field-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ fieldBuilderProto.prismaField = function prismaField({ type, resolve, ...options
return this.field({
...(options as {}),
type: typeParam,
resolve: (parent: never, args: unknown, ctx: {}, info: GraphQLResolveInfo) => {
const query = queryFromInfo(ctx, info);
resolve: (parent: never, args: unknown, context: {}, info: GraphQLResolveInfo) => {
const query = queryFromInfo({ context, info });

return resolve(query, parent, args as never, ctx, info) as never;
return resolve(query, parent, args as never, context, info) as never;
},
}) as never;
};
Expand Down Expand Up @@ -89,21 +89,25 @@ fieldBuilderProto.prismaConnection = function prismaConnection<
resolve: (
parent: unknown,
args: PothosSchemaTypes.DefaultConnectionArguments,
ctx: {},
context: {},
info: GraphQLResolveInfo,
) =>
resolvePrismaCursorConnection(
{
query: queryFromInfo(ctx, info, undefined, { select: cursorSelection as {} }),
ctx,
query: queryFromInfo({
context,
info,
select: cursorSelection as {},
}),
ctx: context,
parseCursor,
maxSize,
defaultSize,
args,
totalCount: totalCount && (() => totalCount(parent, args as never, ctx, info)),
totalCount: totalCount && (() => totalCount(parent, args as never, context, info)),
},
formatCursor,
(query) => resolve(query as never, parent, args as never, ctx, info),
(query) => resolve(query as never, parent, args as never, context, info),
),
},
{
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-prisma/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class PrismaPlugin<Types extends SchemaTypes> extends BasePlugin<Types> {
}

if (fallback) {
return fallback(queryFromInfo(context, info), parent, args, context, info);
return fallback(queryFromInfo({ context, info }), parent, args, context, info);
}

const selectionState = selectionStateFromInfo(context, info);
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-prisma/src/schema-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ schemaBuilderProto.prismaNode = function prismaNode(
context: SchemaTypes['Context'],
info: GraphQLResolveInfo,
) => {
const query = queryFromInfo(context, info, typeName);
const query = queryFromInfo({ context, info, typeName });
const delegate = getDelegateFromModel(getClient(this, context), type);

const record = await (delegate.findUniqueOrThrow
Expand Down
38 changes: 29 additions & 9 deletions packages/plugin-prisma/src/util/map-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,20 +306,40 @@ function addFieldSelection(
}
}

export function queryFromInfo(
context: object,
info: GraphQLResolveInfo,
typeName?: string,
initialSelection?: SelectionMap,
): {} {
export function queryFromInfo({
context,
info,
typeName,
select,
path = [],
}: {
context: object;
info: GraphQLResolveInfo;
typeName?: string;
select?: SelectionMap['select'];
path?: string[];
}): {} {
const type = typeName ? info.schema.getTypeMap()[typeName] : getNamedType(info.returnType);
const state = createStateForType(type, info);

if (initialSelection) {
mergeSelection(state, initialSelection);
if (select) {
mergeSelection(state, { select });
}

addTypeSelectionsForField(type, context, info, state, info.fieldNodes[0], []);
if (path.length > 0) {
resolveIndirectInclude(
getNamedType(info.returnType),
info,
info.fieldNodes[0],
path.map((n) => (typeof n === 'string' ? { name: n } : n)),
[],
(resolvedType, resolvedField, nested) => {
addTypeSelectionsForField(resolvedType, context, info, state, resolvedField, nested);
},
);
} else {
addTypeSelectionsForField(type, context, info, state, info.fieldNodes[0], []);
}

setLoaderMappings(context, info, state.mappings);

Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-prisma/tests/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ exports[`prisma generates schema 1`] = `
message: String!
}
type Blog {
pages: [Int!]!
posts: [Post!]!
}
type Comment {
author: User!
authorBio: String
Expand Down Expand Up @@ -109,6 +114,7 @@ type Profile {
type Query {
badUser: User!
blog: Blog!
findUniqueRelations: FindUniqueRelations!
findUniqueRelationsSelect: FindUniqueRelations!
manualConnection(after: ID, before: ID, first: Int, last: Int): QueryManualConnection!
Expand Down
24 changes: 24 additions & 0 deletions packages/plugin-prisma/tests/example/schema/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-underscore-dangle */
import { resolveCursorConnection, ResolveCursorConnectionArgs } from '@pothos/plugin-relay';
import { queryFromInfo } from '../../../src/util/map-query';
import { Post } from '../../client';
import builder, { prisma } from '../builder';

Expand Down Expand Up @@ -769,4 +770,27 @@ builder.queryField('manualConnection', (t) =>
}),
);

const Blog = builder.objectRef<{ posts: Post[]; pages: number[] }>('Blog').implement({
fields: (t) => ({
posts: t.prismaField({
type: ['Post'],
resolve: (_, blog) => blog.posts,
}),
pages: t.exposeIntList('pages'),
}),
});

builder.queryField('blog', (t) =>
t.field({
type: Blog,
resolve: async (_, args, context, info) => ({
posts: await prisma.post.findMany({
...queryFromInfo({ context, info, typeName: 'Post', path: ['posts'] }),
take: 3,
}),
pages: [1, 2, 3],
}),
}),
);

export default builder.toSchema({});
79 changes: 79 additions & 0 deletions packages/plugin-prisma/tests/nested-query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,83 @@ describe('nested query', () => {
]
`);
});

it('queryFromInfo with nested path', async () => {
const query = gql`
query {
blog {
posts {
id
author {
name
}
}
pages
}
}
`;

const result = await execute({
schema,
document: query,
contextValue: { user: { id: 1 } },
});

expect(result).toMatchInlineSnapshot(`
Object {
"data": Object {
"blog": Object {
"pages": Array [
1,
2,
3,
],
"posts": Array [
Object {
"author": Object {
"name": "Maurine Rath",
},
"id": "1",
},
Object {
"author": Object {
"name": "Maurine Rath",
},
"id": "2",
},
Object {
"author": Object {
"name": "Maurine Rath",
},
"id": "3",
},
],
},
},
}
`);

expect(queries).toMatchInlineSnapshot(`
Array [
Object {
"action": "findMany",
"args": Object {
"include": Object {
"author": true,
"comments": Object {
"include": Object {
"author": true,
},
"take": 3,
},
},
"take": 3,
},
"dataPath": Array [],
"model": "Post",
"runInTransaction": false,
},
]
`);
});
});

1 comment on commit 5e71c28

@vercel
Copy link

@vercel vercel bot commented on 5e71c28 Aug 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.