@pothos/plugin-drizzle 0.7.2 → 0.8.1

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dts/model-loader.d.ts.map +1 -1
  3. package/dts/types.d.ts +1 -0
  4. package/dts/types.d.ts.map +1 -1
  5. package/dts/utils/config.d.ts +1 -0
  6. package/dts/utils/config.d.ts.map +1 -1
  7. package/dts/utils/map-query.d.ts.map +1 -1
  8. package/dts/utils/selections.d.ts +2 -1
  9. package/dts/utils/selections.d.ts.map +1 -1
  10. package/esm/field-builder.js.map +1 -1
  11. package/esm/model-loader.d.ts.map +1 -1
  12. package/esm/model-loader.js +1 -0
  13. package/esm/model-loader.js.map +1 -1
  14. package/esm/types.d.ts +1 -0
  15. package/esm/types.d.ts.map +1 -1
  16. package/esm/types.js.map +1 -1
  17. package/esm/utils/config.d.ts +1 -0
  18. package/esm/utils/config.d.ts.map +1 -1
  19. package/esm/utils/config.js +2 -0
  20. package/esm/utils/config.js.map +1 -1
  21. package/esm/utils/map-query.d.ts.map +1 -1
  22. package/esm/utils/map-query.js +35 -20
  23. package/esm/utils/map-query.js.map +1 -1
  24. package/esm/utils/selections.d.ts +2 -1
  25. package/esm/utils/selections.d.ts.map +1 -1
  26. package/esm/utils/selections.js +3 -2
  27. package/esm/utils/selections.js.map +1 -1
  28. package/lib/field-builder.js.map +1 -1
  29. package/lib/model-loader.js +1 -0
  30. package/lib/model-loader.js.map +1 -1
  31. package/lib/types.js.map +1 -1
  32. package/lib/utils/config.js +2 -0
  33. package/lib/utils/config.js.map +1 -1
  34. package/lib/utils/map-query.js +35 -20
  35. package/lib/utils/map-query.js.map +1 -1
  36. package/lib/utils/selections.js +3 -2
  37. package/lib/utils/selections.js.map +1 -1
  38. package/package.json +2 -2
  39. package/src/field-builder.ts +0 -1
  40. package/src/model-loader.ts +1 -0
  41. package/src/types.ts +1 -0
  42. package/src/utils/config.ts +2 -0
  43. package/src/utils/map-query.ts +65 -11
  44. package/src/utils/selections.ts +8 -4
@@ -3,6 +3,7 @@ import type { DBQueryConfig, TableRelationalConfig } from 'drizzle-orm';
3
3
  import {
4
4
  type FieldNode,
5
5
  type FragmentDefinitionNode,
6
+ type FragmentSpreadNode,
6
7
  type GraphQLField,
7
8
  GraphQLIncludeDirective,
8
9
  type GraphQLInterfaceType,
@@ -45,6 +46,7 @@ function addTypeSelectionsForField(
45
46
  state: SelectionState,
46
47
  selection: FieldNode,
47
48
  indirectPath: string[],
49
+ deferred?: boolean,
48
50
  ) {
49
51
  if (selection.name.value.startsWith('__')) {
50
52
  return;
@@ -67,8 +69,18 @@ function addTypeSelectionsForField(
67
69
  pothosIndirectInclude.paths ?? [pothosIndirectInclude.path!],
68
70
  indirectPath,
69
71
  (resolvedType, field, path) => {
70
- addTypeSelectionsForField(config, resolvedType, context, info, state, field, path);
72
+ addTypeSelectionsForField(
73
+ config,
74
+ resolvedType,
75
+ context,
76
+ info,
77
+ state,
78
+ field,
79
+ path,
80
+ deferred,
81
+ );
71
82
  },
83
+ deferred,
72
84
  );
73
85
  } else if (pothosIndirectInclude) {
74
86
  addTypeSelectionsForField(
@@ -79,6 +91,7 @@ function addTypeSelectionsForField(
79
91
  state,
80
92
  selection,
81
93
  indirectPath,
94
+ deferred,
82
95
  );
83
96
  return;
84
97
  }
@@ -91,7 +104,7 @@ function addTypeSelectionsForField(
91
104
  mergeSelection(config, state, { ...pothosDrizzleSelect });
92
105
  }
93
106
 
94
- if (selection.selectionSet) {
107
+ if (selection.selectionSet && (!deferred || !state.skipDeferredFragments)) {
95
108
  addNestedSelections(config, type, context, info, state, selection.selectionSet, indirectPath);
96
109
  }
97
110
  }
@@ -103,13 +116,22 @@ function resolveIndirectIncludePaths(
103
116
  pathPrefix: { type?: string; name: string }[],
104
117
  includePaths: { type?: string; name: string }[][],
105
118
  path: string[],
106
- resolve: (type: GraphQLNamedType, field: FieldNode, path: string[]) => void,
119
+ resolve: (type: GraphQLNamedType, field: FieldNode, path: string[], deferred: boolean) => void,
120
+ deferred?: boolean,
107
121
  ) {
108
122
  for (const includePath of includePaths) {
109
123
  if (pathPrefix.length > 0) {
110
- resolveIndirectInclude(type, info, selection, [...pathPrefix, ...includePath], path, resolve);
124
+ resolveIndirectInclude(
125
+ type,
126
+ info,
127
+ selection,
128
+ [...pathPrefix, ...includePath],
129
+ path,
130
+ resolve,
131
+ deferred,
132
+ );
111
133
  } else {
112
- resolveIndirectInclude(type, info, selection, includePath, path, resolve);
134
+ resolveIndirectInclude(type, info, selection, includePath, path, resolve, deferred);
113
135
  }
114
136
  }
115
137
  }
@@ -120,10 +142,11 @@ function resolveIndirectInclude(
120
142
  selection: FieldNode | FragmentDefinitionNode | InlineFragmentNode,
121
143
  includePath: { type?: string; name: string }[],
122
144
  path: string[],
123
- resolve: (type: GraphQLNamedType, field: FieldNode, path: string[]) => void,
145
+ resolve: (type: GraphQLNamedType, field: FieldNode, path: string[], deferred: boolean) => void,
146
+ deferred = false,
124
147
  ) {
125
148
  if (includePath.length === 0) {
126
- resolve(type, selection as FieldNode, path);
149
+ resolve(type, selection as FieldNode, path, deferred);
127
150
  return;
128
151
  }
129
152
 
@@ -149,6 +172,7 @@ function resolveIndirectInclude(
149
172
  rest,
150
173
  [...path, sel.alias?.value ?? sel.name.value],
151
174
  resolve,
175
+ deferred,
152
176
  );
153
177
  }
154
178
  continue;
@@ -164,6 +188,7 @@ function resolveIndirectInclude(
164
188
  includePath,
165
189
  path,
166
190
  resolve,
191
+ deferred || isDeferredFragment(sel, info),
167
192
  );
168
193
  }
169
194
 
@@ -178,6 +203,7 @@ function resolveIndirectInclude(
178
203
  includePath,
179
204
  path,
180
205
  resolve,
206
+ deferred || isDeferredFragment(sel, info),
181
207
  );
182
208
  }
183
209
 
@@ -208,6 +234,10 @@ function addNestedSelections(
208
234
 
209
235
  continue;
210
236
  case Kind.FRAGMENT_SPREAD:
237
+ if (state.skipDeferredFragments && isDeferredFragment(selection, info)) {
238
+ continue;
239
+ }
240
+
211
241
  parentType = info.schema.getType(
212
242
  info.fragments[selection.name.value].typeCondition.name.value,
213
243
  )! as GraphQLObjectType;
@@ -232,6 +262,10 @@ function addNestedSelections(
232
262
  continue;
233
263
 
234
264
  case Kind.INLINE_FRAGMENT:
265
+ if (state.skipDeferredFragments && isDeferredFragment(selection, info)) {
266
+ continue;
267
+ }
268
+
235
269
  parentType = selection.typeCondition
236
270
  ? (info.schema.getType(selection.typeCondition.name.value) as GraphQLObjectType)
237
271
  : type;
@@ -325,7 +359,7 @@ function addFieldSelection(
325
359
  (returnType.extensions?.pothosIndirectInclude as { path: [] })?.path ?? [],
326
360
  normalizedIndirectInclude.paths ?? [normalizedIndirectInclude.path!],
327
361
  [],
328
- (resolvedType, resolvedField, path) => {
362
+ (resolvedType, resolvedField, path, deferred) => {
329
363
  addTypeSelectionsForField(
330
364
  config,
331
365
  resolvedType,
@@ -334,6 +368,7 @@ function addFieldSelection(
334
368
  fieldState,
335
369
  resolvedField,
336
370
  path,
371
+ deferred,
337
372
  );
338
373
  },
339
374
  );
@@ -424,7 +459,7 @@ export function stateFromInfo<T extends SelectionMap>({
424
459
  info.fieldNodes[0],
425
460
  pothosIndirectInclude?.path ?? [],
426
461
  [],
427
- (indirectType, indirectField, subPath) => {
462
+ (indirectType, indirectField, subPath, deferred) => {
428
463
  resolveIndirectIncludePaths(
429
464
  indirectType,
430
465
  info,
@@ -434,7 +469,7 @@ export function stateFromInfo<T extends SelectionMap>({
434
469
  ? paths.map((p) => p.map((n) => (typeof n === 'string' ? { name: n } : n)))
435
470
  : [path.map((n) => (typeof n === 'string' ? { name: n } : n))],
436
471
  subPath,
437
- (resolvedType, resolvedField, nested) => {
472
+ (resolvedType, resolvedField, nested, deferred) => {
438
473
  state = createStateForSelection(config, info, resolvedType, undefined, select);
439
474
 
440
475
  addTypeSelectionsForField(
@@ -445,8 +480,10 @@ export function stateFromInfo<T extends SelectionMap>({
445
480
  state,
446
481
  resolvedField,
447
482
  nested,
483
+ deferred,
448
484
  );
449
485
  },
486
+ deferred,
450
487
  );
451
488
  },
452
489
  );
@@ -500,7 +537,11 @@ function createStateForSelection(
500
537
  throw new PothosValidationError(`Expected ${targetType.name} to have a table config`);
501
538
  }
502
539
 
503
- const state = createState(pothosDrizzleTable, parent);
540
+ const state = createState(
541
+ pothosDrizzleTable,
542
+ parent?.skipDeferredFragments ?? config.skipDeferredFragments,
543
+ parent,
544
+ );
504
545
 
505
546
  if (initialSelections) {
506
547
  mergeSelection(config, state, initialSelections);
@@ -571,3 +612,16 @@ function fieldSkipped(info: GraphQLResolveInfo, selection: FieldNode) {
571
612
 
572
613
  return false;
573
614
  }
615
+
616
+ function isDeferredFragment(
617
+ node: FragmentSpreadNode | InlineFragmentNode,
618
+ info: GraphQLResolveInfo,
619
+ ) {
620
+ const deferDirective = info.schema.getDirective('defer');
621
+ if (!deferDirective) {
622
+ return false;
623
+ }
624
+
625
+ const defer = getDirectiveValues(deferDirective, node, info.variableValues);
626
+ return !!defer && defer.if !== false;
627
+ }
@@ -1,10 +1,8 @@
1
1
  import { PothosValidationError } from '@pothos/core';
2
2
  import {
3
3
  type DBQueryConfig,
4
- RelationalSchemaConfig,
5
4
  type SQL,
6
5
  type TableRelationalConfig,
7
- TablesRelationalConfig,
8
6
  getOperators,
9
7
  } from 'drizzle-orm';
10
8
  import type { PothosDrizzleSchemaConfig } from './config';
@@ -21,6 +19,7 @@ export interface SelectionState {
21
19
  mappings: LoaderMappings;
22
20
  parent?: SelectionState;
23
21
  depth: number;
22
+ skipDeferredFragments: boolean;
24
23
  }
25
24
 
26
25
  export type SelectionMap = DBQueryConfig<'one', false>;
@@ -102,9 +101,14 @@ export function mergeState(state: SelectionState, newState: SelectionState) {
102
101
  }
103
102
  }
104
103
 
105
- export function createState(table: TableRelationalConfig, parent?: SelectionState): SelectionState {
104
+ export function createState(
105
+ table: TableRelationalConfig,
106
+ skipDeferredFragments: boolean,
107
+ parent?: SelectionState,
108
+ ): SelectionState {
106
109
  return {
107
110
  table,
111
+ skipDeferredFragments,
108
112
  parent,
109
113
  query: {},
110
114
  columns: new Set(),
@@ -168,7 +172,7 @@ export function mergeSelection(
168
172
  if (state.with.has(key)) {
169
173
  mergeSelection(config, state.with.get(key)!, selection);
170
174
  } else {
171
- const relatedState = createState(table, state);
175
+ const relatedState = createState(table, state.skipDeferredFragments, state);
172
176
  mergeSelection(config, relatedState, selection);
173
177
  state.with.set(key, relatedState);
174
178
  }