@pothos/plugin-drizzle 0.16.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,11 +15,12 @@ import {
15
15
  getNamedType,
16
16
  type InlineFragmentNode,
17
17
  isInterfaceType,
18
+ isListType,
18
19
  isObjectType,
19
20
  Kind,
20
21
  type SelectionSetNode,
21
22
  } from 'graphql';
22
- import type { DrizzleFieldSelection } from '../types';
23
+ import type { DrizzleFieldSelection, FieldPathInfo, PathInfo } from '../types';
23
24
  import type { PothosDrizzleSchemaConfig } from './config';
24
25
  import { type LoaderMappings, setLoaderMappings } from './loader-map';
25
26
  import {
@@ -47,6 +48,7 @@ function addTypeSelectionsForField(
47
48
  selection: FieldNode,
48
49
  indirectPath: string[],
49
50
  deferred?: boolean,
51
+ segments: FieldPathInfo[] = [],
50
52
  ) {
51
53
  if (selection.name.value.startsWith('__')) {
52
54
  return;
@@ -78,6 +80,7 @@ function addTypeSelectionsForField(
78
80
  field,
79
81
  path,
80
82
  deferred,
83
+ segments,
81
84
  );
82
85
  },
83
86
  deferred,
@@ -92,6 +95,7 @@ function addTypeSelectionsForField(
92
95
  selection,
93
96
  indirectPath,
94
97
  deferred,
98
+ segments,
95
99
  );
96
100
  return;
97
101
  }
@@ -105,7 +109,16 @@ function addTypeSelectionsForField(
105
109
  }
106
110
 
107
111
  if (selection.selectionSet && (!deferred || !state.skipDeferredFragments)) {
108
- addNestedSelections(config, type, context, info, state, selection.selectionSet, indirectPath);
112
+ addNestedSelections(
113
+ config,
114
+ type,
115
+ context,
116
+ info,
117
+ state,
118
+ selection.selectionSet,
119
+ indirectPath,
120
+ segments,
121
+ );
109
122
  }
110
123
  }
111
124
 
@@ -225,12 +238,13 @@ function addNestedSelections(
225
238
  state: SelectionState,
226
239
  selections: SelectionSetNode,
227
240
  indirectPath: string[],
241
+ segments: FieldPathInfo[] = [],
228
242
  ) {
229
243
  let parentType = type;
230
244
  for (const selection of selections.selections) {
231
245
  switch (selection.kind) {
232
246
  case Kind.FIELD:
233
- addFieldSelection(config, type, context, info, state, selection, indirectPath);
247
+ addFieldSelection(config, type, context, info, state, selection, indirectPath, segments);
234
248
 
235
249
  continue;
236
250
  case Kind.FRAGMENT_SPREAD:
@@ -257,6 +271,7 @@ function addNestedSelections(
257
271
  state,
258
272
  info.fragments[selection.name.value].selectionSet,
259
273
  indirectPath,
274
+ segments,
260
275
  );
261
276
 
262
277
  continue;
@@ -285,6 +300,7 @@ function addNestedSelections(
285
300
  state,
286
301
  selection.selectionSet,
287
302
  indirectPath,
303
+ segments,
288
304
  );
289
305
 
290
306
  continue;
@@ -305,6 +321,7 @@ function addFieldSelection(
305
321
  state: SelectionState,
306
322
  selection: FieldNode,
307
323
  indirectPath: string[],
324
+ segments: FieldPathInfo[] = [],
308
325
  ) {
309
326
  if (selection.name.value.startsWith('__') || fieldSkipped(info, selection)) {
310
327
  return;
@@ -314,11 +331,26 @@ function addFieldSelection(
314
331
  throw new PothosValidationError(`Unknown field ${selection.name.value} on ${type.name}`);
315
332
  }
316
333
 
334
+ const allSegments = [
335
+ ...segments,
336
+ {
337
+ field: selection.name.value,
338
+ alias: selection.alias?.value ?? selection.name.value,
339
+ parentType: type.name,
340
+ isList: isListType(field.type) || isListType(getNamedType(field.type)),
341
+ },
342
+ ];
343
+
317
344
  const fieldSelect = field.extensions?.pothosDrizzleSelect as DrizzleFieldSelection | undefined;
318
345
 
319
346
  let fieldSelectionMap: DBQueryConfig<'one'> | undefined;
320
347
  let mappings: LoaderMappings = {};
321
348
  if (typeof fieldSelect === 'function') {
349
+ const pathInfo: PathInfo = {
350
+ path: allSegments.map((s) => `${s.parentType}.${s.field}`),
351
+ segments: allSegments,
352
+ };
353
+
322
354
  const args = getMappedArgumentValues(field, selection, context, info) as Record<
323
355
  string,
324
356
  unknown
@@ -369,11 +401,22 @@ function addFieldSelection(
369
401
  resolvedField,
370
402
  path,
371
403
  deferred,
404
+ allSegments,
372
405
  );
373
406
  },
374
407
  );
375
408
  }
376
- addTypeSelectionsForField(config, returnType, context, info, fieldState, selection, []);
409
+ addTypeSelectionsForField(
410
+ config,
411
+ returnType,
412
+ context,
413
+ info,
414
+ fieldState,
415
+ selection,
416
+ [],
417
+ undefined,
418
+ allSegments,
419
+ );
377
420
  mappings = fieldState.mappings;
378
421
  return selectionToQuery(config, fieldState);
379
422
  },
@@ -394,6 +437,7 @@ function addFieldSelection(
394
437
  );
395
438
  return node;
396
439
  },
440
+ pathInfo,
397
441
  );
398
442
  } else {
399
443
  fieldSelectionMap = fieldSelect!;
@@ -522,7 +566,31 @@ export function stateFromInfo<T extends SelectionMap>({
522
566
  } else {
523
567
  state = createStateForSelection(config, info, type, undefined, initialSelection);
524
568
 
525
- addTypeSelectionsForField(config, type, context, info, state, info.fieldNodes[0], []);
569
+ // Create initial segment for the root query field
570
+ const rootFieldNode = info.fieldNodes[0];
571
+ const rootField = info.parentType.getFields()[rootFieldNode.name.value];
572
+ const initialSegments: FieldPathInfo[] = rootField
573
+ ? [
574
+ {
575
+ field: rootFieldNode.name.value,
576
+ alias: rootFieldNode.alias?.value ?? rootFieldNode.name.value,
577
+ parentType: info.parentType.name,
578
+ isList: isListType(rootField.type) || isListType(getNamedType(rootField.type)),
579
+ },
580
+ ]
581
+ : [];
582
+
583
+ addTypeSelectionsForField(
584
+ config,
585
+ type,
586
+ context,
587
+ info,
588
+ state,
589
+ info.fieldNodes[0],
590
+ [],
591
+ undefined,
592
+ initialSegments,
593
+ );
526
594
  }
527
595
 
528
596
  if (!state) {