Skip to content

Commit 451eb84

Browse files
authored
Merge pull request #1597 from hayes/feat/drizzle-path-info
feat(plugin-drizzle): add pathInfo to query callbacks for path-based …
2 parents 96db4c3 + ac51bb2 commit 451eb84

File tree

12 files changed

+523
-27
lines changed

12 files changed

+523
-27
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
"@pothos/plugin-drizzle": minor
3+
---
4+
5+
Add pathInfo parameter to t.relation() and t.relatedConnection() query callbacks for path-based filtering.
6+
7+
PathInfo includes:
8+
- `path`: Array of "ParentType.fieldName" strings (e.g., `['Query.user', 'User.posts']`)
9+
- `segments`: Detailed info for each path segment including field, alias, parentType, and isList
10+
11+
Example usage:
12+
```typescript
13+
posts: t.relation('posts', {
14+
query: (args, ctx, pathInfo) => {
15+
// Check if accessed via viewer (own profile) vs user (public)
16+
const isViewerContext = pathInfo?.path?.at(-2) === 'Query.viewer';
17+
return {
18+
where: { published: isViewerContext ? false : true },
19+
};
20+
},
21+
})
22+
```

packages/plugin-drizzle/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ builder.drizzleObject('users', {
228228
limit: t.arg.int(),
229229
offset: t.arg.int(),
230230
},
231+
// query callback receives (args, ctx, pathInfo)
231232
query: (args) => ({
232233
limit: args.limit ?? 10,
233234
offset: args.offset ?? 0,
@@ -251,8 +252,9 @@ builder.drizzleObject('users', {
251252
```
252253

253254
The query API enables you to define args and convert them into parameters that will be passed into
254-
the relational query builder. You can read more about the relation query builder api
255-
[here](https://orm.drizzle.team/docs/rqb#querying)
255+
the relational query builder. The `query` callback receives `(args, ctx, pathInfo)` where `pathInfo`
256+
contains the GraphQL query path information (`path` and `segments`). You can read more about the
257+
relation query builder api [here](https://orm.drizzle.team/docs/rqb#querying)
256258

257259
## Drizzle Fields
258260

packages/plugin-drizzle/src/drizzle-field-builder.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import type { DrizzleRef } from './interface-ref';
4141
import type {
4242
DrizzleConnectionShape,
4343
ListRelation,
44+
PathInfo,
4445
RelatedConnectionOptions,
4546
RelatedCountOptions,
4647
RelatedFieldOptions,
@@ -219,9 +220,23 @@ export class DrizzleObjectFieldBuilder<
219220
)!;
220221
};
221222

222-
const getQuery = (args: PothosSchemaTypes.DefaultConnectionArguments, ctx: {}) => {
223-
const { limit, orderBy, where, ...fieldQuery } =
224-
(typeof query === 'function' ? query(args, ctx) : query) ?? {};
223+
const getQuery = (
224+
args: PothosSchemaTypes.DefaultConnectionArguments,
225+
ctx: {},
226+
pathInfo?: import('./types').PathInfo,
227+
) => {
228+
const { limit, orderBy, where, ...fieldQuery } = ((typeof query === 'function'
229+
? (query as (args: {}, ctx: {}, pathInfo?: import('./types').PathInfo) => {})(
230+
args,
231+
ctx,
232+
pathInfo,
233+
)
234+
: query) ?? {}) as {
235+
limit?: number;
236+
orderBy?: unknown;
237+
where?: SQL;
238+
columns?: Record<string, boolean>;
239+
};
225240

226241
const { cursorColumns, columns, ...connectionQuery } = drizzleCursorConnectionQuery({
227242
ctx,
@@ -255,6 +270,7 @@ export class DrizzleObjectFieldBuilder<
255270
context: object,
256271
nestedQuery: (query: unknown, path?: unknown) => { select?: object },
257272
getSelection: (path: string[]) => FieldNode | null,
273+
pathInfo: import('./types').PathInfo,
258274
) => {
259275
typeName ??= this.builder.configStore.getTypeConfig(ref).name;
260276

@@ -279,7 +295,7 @@ export class DrizzleObjectFieldBuilder<
279295
};
280296
}
281297

282-
const nested = nestedQuery(getQuery(args, context).select, {
298+
const nested = nestedQuery(getQuery(args, context, pathInfo).select, {
283299
getType: () => typeName!,
284300
paths: [[{ name: 'nodes' }], [{ name: 'edges' }, { name: 'node' }]],
285301
}) as SelectionMap;
@@ -500,14 +516,24 @@ export class DrizzleObjectFieldBuilder<
500516

501517
const { query = {}, extensions, ...rest } = options;
502518

503-
const relationSelect = (args: object, context: object, nestedQuery: (query: unknown) => {}) => {
519+
const relationSelect = (
520+
args: object,
521+
context: object,
522+
nestedQuery: (query: unknown) => {},
523+
_resolveSelection: unknown,
524+
pathInfo: PathInfo,
525+
) => {
504526
const relQuery = {
505527
columns: {},
506528
with: {
507529
[name]: {
508530
...nestedQuery(query),
509531
...((typeof query === 'function'
510-
? (query as (args: {}, context: {}) => {})(args, context)
532+
? (query as (args: {}, context: {}, pathInfo: PathInfo) => {})(
533+
args,
534+
context,
535+
pathInfo,
536+
)
511537
: query) as {}),
512538
},
513539
},

packages/plugin-drizzle/src/index.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,23 @@ export class PothosDrizzlePlugin<Types extends SchemaTypes> extends BasePlugin<T
121121
args: {},
122122
ctx: Types['Context'],
123123
nestedQuery: (query: unknown, path?: string[]) => never,
124-
) => ({
125-
columns: {},
126-
...(select as (args: unknown, ctx: unknown, nestedQuery: unknown) => {})(
127-
args,
128-
ctx,
129-
nestedQuery,
130-
),
131-
})
124+
_resolveSelection: unknown,
125+
pathInfo: import('./types').PathInfo,
126+
) => {
127+
// Attach PathInfo properties to nestedQuery for t.field select callbacks
128+
const nestedQueryWithPath = Object.assign(nestedQuery, {
129+
path: pathInfo.path,
130+
segments: pathInfo.segments,
131+
});
132+
return {
133+
columns: {},
134+
...(select as (args: unknown, ctx: unknown, nestedQuery: unknown) => {})(
135+
args,
136+
ctx,
137+
nestedQueryWithPath,
138+
),
139+
};
140+
}
132141
: {
133142
columns: {},
134143
...select,

packages/plugin-drizzle/src/types.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ import type { DrizzleRef } from './interface-ref';
4444
import type { IndirectInclude } from './utils/map-query';
4545
import type { SelectionMap } from './utils/selections';
4646

47+
export interface FieldPathInfo {
48+
field: string;
49+
alias: string;
50+
parentType: string;
51+
isList: boolean;
52+
}
53+
54+
export interface PathInfo {
55+
path: string[];
56+
segments: FieldPathInfo[];
57+
}
58+
4759
export type DrizzleClient<TCountSource = Table | SQL | SQLWrapper> = {
4860
readonly _: {
4961
readonly schema: unknown;
@@ -323,10 +335,11 @@ export type DrizzleObjectFieldOptions<
323335
| ((
324336
args: InputShapeFromFields<Args>,
325337
ctx: Types['Context'],
326-
nestedSelection: <Selection extends boolean | {}>(
338+
nestedSelection: (<Selection extends boolean | {}>(
327339
selection?: Selection,
328340
path?: string[],
329-
) => Selection,
341+
) => Selection) &
342+
PathInfo,
330343
) => DBQueryConfig<'one', Types['DrizzleRelations'], ExtractTable<Types, ParentShape>>)
331344
);
332345
};
@@ -345,6 +358,7 @@ export type DrizzleFieldSelection =
345358
type?: string,
346359
) => DBQueryConfig<'one'> | boolean,
347360
resolveSelection: (path: string[]) => FieldNode | null,
361+
pathInfo: PathInfo,
348362
) => SelectionMap);
349363

350364
export type ExtractTable<Types extends SchemaTypes, Shape> = Shape extends {
@@ -480,7 +494,13 @@ export type QueryForField<
480494
'columns' | 'extra' | 'with'
481495
>
482496
) extends infer QueryConfig
483-
? QueryConfig | ((args: InputShapeFromFields<Args>, context: Types['Context']) => QueryConfig)
497+
?
498+
| QueryConfig
499+
| ((
500+
args: InputShapeFromFields<Args>,
501+
context: Types['Context'],
502+
pathInfo: PathInfo,
503+
) => QueryConfig)
484504
: never;
485505

486506
export type QueryForDrizzleField<
@@ -503,7 +523,7 @@ export type QueryForRelatedConnection<
503523
> & {
504524
orderBy?: ConnectionOrderBy<Table> | ((table: Table) => ConnectionOrderBy<Table>);
505525
} extends infer QueryConfig
506-
? QueryConfig | ((args: Args, context: Types['Context']) => QueryConfig)
526+
? QueryConfig | ((args: Args, context: Types['Context'], pathInfo: PathInfo) => QueryConfig)
507527
: never;
508528

509529
export type QueryForDrizzleConnection<

0 commit comments

Comments
 (0)