@depup/graphql-codegen__plugin-helpers 6.2.0-depup.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.
Files changed (40) hide show
  1. package/README.md +33 -0
  2. package/changes.json +18 -0
  3. package/cjs/federation.js +436 -0
  4. package/cjs/getCachedDocumentNodeFromSchema.js +5 -0
  5. package/cjs/helpers.js +178 -0
  6. package/cjs/index.js +13 -0
  7. package/cjs/oldVisit.js +19 -0
  8. package/cjs/package.json +1 -0
  9. package/cjs/profiler.js +49 -0
  10. package/cjs/resolve-external-module-and-fn.js +31 -0
  11. package/cjs/types.js +6 -0
  12. package/cjs/utils.js +35 -0
  13. package/esm/federation.js +430 -0
  14. package/esm/getCachedDocumentNodeFromSchema.js +2 -0
  15. package/esm/helpers.js +168 -0
  16. package/esm/index.js +8 -0
  17. package/esm/oldVisit.js +16 -0
  18. package/esm/profiler.js +45 -0
  19. package/esm/resolve-external-module-and-fn.js +27 -0
  20. package/esm/types.js +3 -0
  21. package/esm/utils.js +29 -0
  22. package/package.json +76 -0
  23. package/typings/federation.d.cts +102 -0
  24. package/typings/federation.d.ts +102 -0
  25. package/typings/getCachedDocumentNodeFromSchema.d.cts +2 -0
  26. package/typings/getCachedDocumentNodeFromSchema.d.ts +2 -0
  27. package/typings/helpers.d.cts +13 -0
  28. package/typings/helpers.d.ts +13 -0
  29. package/typings/index.d.cts +9 -0
  30. package/typings/index.d.ts +9 -0
  31. package/typings/oldVisit.d.cts +9 -0
  32. package/typings/oldVisit.d.ts +9 -0
  33. package/typings/profiler.d.cts +28 -0
  34. package/typings/profiler.d.ts +28 -0
  35. package/typings/resolve-external-module-and-fn.d.cts +1 -0
  36. package/typings/resolve-external-module-and-fn.d.ts +1 -0
  37. package/typings/types.d.cts +635 -0
  38. package/typings/types.d.ts +635 -0
  39. package/typings/utils.d.cts +6 -0
  40. package/typings/utils.d.ts +6 -0
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oldVisit = oldVisit;
4
+ const graphql_1 = require("graphql");
5
+ function oldVisit(root, { enter: enterVisitors, leave: leaveVisitors, ...newVisitor }) {
6
+ if (typeof enterVisitors === 'object') {
7
+ for (const key in enterVisitors) {
8
+ newVisitor[key] ||= {};
9
+ newVisitor[key].enter = enterVisitors[key];
10
+ }
11
+ }
12
+ if (typeof leaveVisitors === 'object') {
13
+ for (const key in leaveVisitors) {
14
+ newVisitor[key] ||= {};
15
+ newVisitor[key].leave = leaveVisitors[key];
16
+ }
17
+ }
18
+ return (0, graphql_1.visit)(root, newVisitor);
19
+ }
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNoopProfiler = createNoopProfiler;
4
+ exports.createProfiler = createProfiler;
5
+ function createNoopProfiler() {
6
+ return {
7
+ run(fn) {
8
+ return Promise.resolve().then(() => fn());
9
+ },
10
+ collect() {
11
+ return [];
12
+ },
13
+ };
14
+ }
15
+ function createProfiler() {
16
+ const events = [];
17
+ return {
18
+ collect() {
19
+ return events;
20
+ },
21
+ run(fn, name, cat) {
22
+ let startTime;
23
+ return Promise.resolve()
24
+ .then(() => {
25
+ startTime = process.hrtime();
26
+ })
27
+ .then(() => fn())
28
+ .then(value => {
29
+ const duration = process.hrtime(startTime);
30
+ // Trace Event Format documentation:
31
+ // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
32
+ const event = {
33
+ name,
34
+ cat,
35
+ ph: 'X',
36
+ ts: hrtimeToMicroseconds(startTime),
37
+ pid: 1,
38
+ tid: 0,
39
+ dur: hrtimeToMicroseconds(duration),
40
+ };
41
+ events.push(event);
42
+ return value;
43
+ });
44
+ },
45
+ };
46
+ }
47
+ function hrtimeToMicroseconds(hrtime) {
48
+ return (hrtime[0] * 1e9 + hrtime[1]) / 1000;
49
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveExternalModuleAndFn = resolveExternalModuleAndFn;
4
+ const tslib_1 = require("tslib");
5
+ const module_1 = require("module");
6
+ const process_1 = require("process");
7
+ const changeCaseAll = tslib_1.__importStar(require("change-case-all"));
8
+ function resolveExternalModuleAndFn(pointer) {
9
+ if (typeof pointer === 'function') {
10
+ return pointer;
11
+ }
12
+ let [moduleName, functionName] = pointer.split('#');
13
+ // Temp workaround until v2
14
+ if (moduleName === 'change-case') {
15
+ moduleName = 'change-case-all';
16
+ }
17
+ let loadedModule;
18
+ if (moduleName === 'change-case-all') {
19
+ loadedModule = changeCaseAll;
20
+ }
21
+ else {
22
+ // we have to use a path to a filename here (it does not need to exist.)
23
+ // https://github.com/dotansimha/graphql-code-generator/issues/6553
24
+ const cwdRequire = (0, module_1.createRequire)((0, process_1.cwd)() + '/index.js');
25
+ loadedModule = cwdRequire(moduleName);
26
+ if (!(functionName in loadedModule) && typeof loadedModule !== 'function') {
27
+ throw new Error(`${functionName} couldn't be found in module ${moduleName}!`);
28
+ }
29
+ }
30
+ return loadedModule[functionName] || loadedModule;
31
+ }
package/cjs/types.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isComplexPluginOutput = isComplexPluginOutput;
4
+ function isComplexPluginOutput(obj) {
5
+ return typeof obj === 'object' && Object.prototype.hasOwnProperty.call(obj, 'content');
6
+ }
package/cjs/utils.js ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeOutputs = mergeOutputs;
4
+ exports.isWrapperType = isWrapperType;
5
+ exports.getBaseType = getBaseType;
6
+ exports.removeNonNullWrapper = removeNonNullWrapper;
7
+ const graphql_1 = require("graphql");
8
+ function mergeOutputs(content) {
9
+ const result = { content: '', prepend: [], append: [] };
10
+ if (Array.isArray(content)) {
11
+ for (const item of content) {
12
+ if (typeof item === 'string') {
13
+ result.content += item;
14
+ }
15
+ else {
16
+ result.content += item.content;
17
+ result.prepend.push(...(item.prepend || []));
18
+ result.append.push(...(item.append || []));
19
+ }
20
+ }
21
+ }
22
+ return [...result.prepend, result.content, ...result.append].join('\n');
23
+ }
24
+ function isWrapperType(t) {
25
+ return (0, graphql_1.isListType)(t) || (0, graphql_1.isNonNullType)(t);
26
+ }
27
+ function getBaseType(type) {
28
+ if (isWrapperType(type)) {
29
+ return getBaseType(type.ofType);
30
+ }
31
+ return type;
32
+ }
33
+ function removeNonNullWrapper(type) {
34
+ return (0, graphql_1.isNonNullType)(type) ? type.ofType : type;
35
+ }
@@ -0,0 +1,430 @@
1
+ import { astFromInterfaceType, astFromObjectType, getRootTypeNames, MapperKind, mapSchema } from '@graphql-tools/utils';
2
+ import { GraphQLInterfaceType, GraphQLObjectType, isObjectType, parse, } from 'graphql';
3
+ import { oldVisit } from './index.js';
4
+ import { getBaseType } from './utils.js';
5
+ /**
6
+ * Federation Spec
7
+ */
8
+ export const federationSpec = parse(/* GraphQL */ `
9
+ scalar _FieldSet
10
+
11
+ directive @external on FIELD_DEFINITION
12
+ directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
13
+ directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
14
+ directive @key(fields: _FieldSet!) on OBJECT | INTERFACE
15
+ `);
16
+ /**
17
+ * Adds `__resolveReference` in each ObjectType and InterfaceType involved in Federation.
18
+ * We do this to utilise the existing FieldDefinition logic of the plugin, which includes many logic:
19
+ * - mapper
20
+ * - return type
21
+ * @param schema
22
+ */
23
+ export function addFederationReferencesToSchema(schema) {
24
+ const setFederationMeta = ({ meta, typeName, update, }) => {
25
+ meta[typeName] = {
26
+ ...(meta[typeName] ||
27
+ {
28
+ hasResolveReference: false,
29
+ resolvableKeyDirectives: [],
30
+ referenceSelectionSets: [],
31
+ referenceSelectionSetsString: '',
32
+ }),
33
+ ...update,
34
+ };
35
+ };
36
+ const getReferenceSelectionSets = ({ resolvableKeyDirectives, fields, }) => {
37
+ const referenceSelectionSets = [];
38
+ // @key() @key() - "primary keys" in Federation
39
+ // A reference may receive one primary key combination at a time, so they will be combined with `|`
40
+ const primaryKeys = resolvableKeyDirectives.map(extractReferenceSelectionSet);
41
+ referenceSelectionSets.push({ directive: '@key', selectionSets: [...primaryKeys] });
42
+ const requiresPossibleTypes = [];
43
+ for (const fieldNode of Object.values(fields)) {
44
+ // Look for @requires and see what the service needs and gets
45
+ const directives = getDirectivesByName('requires', fieldNode.astNode);
46
+ for (const directive of directives) {
47
+ const requires = extractReferenceSelectionSet(directive);
48
+ requiresPossibleTypes.push(requires);
49
+ }
50
+ }
51
+ referenceSelectionSets.push({ directive: '@requires', selectionSets: requiresPossibleTypes });
52
+ return referenceSelectionSets;
53
+ };
54
+ /**
55
+ * Function to find all combinations of selection sets and push them into the `result`
56
+ * This is used for `@requires` directive because depending on the operation selection set, different
57
+ * combination of fields are sent from the router.
58
+ *
59
+ * @example
60
+ * Input: [
61
+ * { a: true },
62
+ * { b: true },
63
+ * { c: true },
64
+ * { d: true},
65
+ * ]
66
+ * Output: [
67
+ * { a: true },
68
+ * { a: true, b: true },
69
+ * { a: true, c: true },
70
+ * { a: true, d: true },
71
+ * { a: true, b: true, c: true },
72
+ * { a: true, b: true, d: true },
73
+ * { a: true, c: true, d: true },
74
+ * { a: true, b: true, c: true, d: true }
75
+ *
76
+ * { b: true },
77
+ * { b: true, c: true },
78
+ * { b: true, d: true },
79
+ * { b: true, c: true, d: true }
80
+ *
81
+ * { c: true },
82
+ * { c: true, d: true },
83
+ *
84
+ * { d: true },
85
+ * ]
86
+ * ```
87
+ */
88
+ function findAllSelectionSetCombinations(selectionSets, result) {
89
+ if (selectionSets.length === 0) {
90
+ return;
91
+ }
92
+ for (let baseIndex = 0; baseIndex < selectionSets.length; baseIndex++) {
93
+ const base = selectionSets.slice(0, baseIndex + 1);
94
+ const rest = selectionSets.slice(baseIndex + 1, selectionSets.length);
95
+ const currentSelectionSet = base.reduce((acc, selectionSet) => {
96
+ acc = { ...acc, ...selectionSet };
97
+ return acc;
98
+ }, {});
99
+ if (baseIndex === 0) {
100
+ result.push(currentSelectionSet);
101
+ }
102
+ for (const selectionSet of rest) {
103
+ result.push({ ...currentSelectionSet, ...selectionSet });
104
+ }
105
+ }
106
+ const next = selectionSets.slice(1, selectionSets.length);
107
+ if (next.length > 0) {
108
+ findAllSelectionSetCombinations(next, result);
109
+ }
110
+ }
111
+ const printReferenceSelectionSets = ({ typeName, baseFederationType, referenceSelectionSets, }) => {
112
+ const referenceSelectionSetStrings = referenceSelectionSets.reduce((acc, { directive, selectionSets: originalSelectionSets }) => {
113
+ const result = [];
114
+ let selectionSets = originalSelectionSets;
115
+ if (directive === '@requires') {
116
+ selectionSets = [];
117
+ findAllSelectionSetCombinations(originalSelectionSets, selectionSets);
118
+ if (selectionSets.length > 0) {
119
+ result.push('Record<PropertyKey, never>');
120
+ }
121
+ }
122
+ for (const referenceSelectionSet of selectionSets) {
123
+ result.push(`GraphQLRecursivePick<${baseFederationType}, ${JSON.stringify(referenceSelectionSet)}>`);
124
+ }
125
+ if (result.length === 0) {
126
+ return acc;
127
+ }
128
+ if (result.length === 1) {
129
+ acc.push(result.join(' | '));
130
+ return acc;
131
+ }
132
+ acc.push(`( ${result.join('\n | ')} )`);
133
+ return acc;
134
+ }, []);
135
+ return `\n ( { __typename: '${typeName}' }\n & ${referenceSelectionSetStrings.join('\n & ')} )`;
136
+ };
137
+ const federationMeta = {};
138
+ const transformedSchema = mapSchema(schema, {
139
+ [MapperKind.INTERFACE_TYPE]: type => {
140
+ const node = astFromInterfaceType(type, schema);
141
+ const federationDetails = checkTypeFederationDetails(node, schema);
142
+ if (federationDetails && federationDetails.resolvableKeyDirectives.length > 0) {
143
+ const typeConfig = type.toConfig();
144
+ typeConfig.fields = {
145
+ [resolveReferenceFieldName]: {
146
+ type,
147
+ },
148
+ ...typeConfig.fields,
149
+ };
150
+ const referenceSelectionSets = getReferenceSelectionSets({
151
+ resolvableKeyDirectives: federationDetails.resolvableKeyDirectives,
152
+ fields: typeConfig.fields,
153
+ });
154
+ const referenceSelectionSetsString = printReferenceSelectionSets({
155
+ typeName: type.name,
156
+ baseFederationType: `FederationTypes['${type.name}']`, // FIXME: run convertName on FederationTypes
157
+ referenceSelectionSets,
158
+ });
159
+ setFederationMeta({
160
+ meta: federationMeta,
161
+ typeName: type.name,
162
+ update: {
163
+ hasResolveReference: true,
164
+ resolvableKeyDirectives: federationDetails.resolvableKeyDirectives,
165
+ referenceSelectionSets,
166
+ referenceSelectionSetsString,
167
+ },
168
+ });
169
+ return new GraphQLInterfaceType(typeConfig);
170
+ }
171
+ return type;
172
+ },
173
+ [MapperKind.OBJECT_TYPE]: type => {
174
+ const node = astFromObjectType(type, schema);
175
+ const federationDetails = checkTypeFederationDetails(node, schema);
176
+ if (federationDetails && federationDetails.resolvableKeyDirectives.length > 0) {
177
+ const typeConfig = type.toConfig();
178
+ const referenceSelectionSets = getReferenceSelectionSets({
179
+ resolvableKeyDirectives: federationDetails.resolvableKeyDirectives,
180
+ fields: typeConfig.fields,
181
+ });
182
+ typeConfig.fields = {
183
+ [resolveReferenceFieldName]: {
184
+ type,
185
+ },
186
+ ...typeConfig.fields,
187
+ };
188
+ const referenceSelectionSetsString = printReferenceSelectionSets({
189
+ typeName: type.name,
190
+ baseFederationType: `FederationTypes['${type.name}']`, // FIXME: run convertName on FederationTypes
191
+ referenceSelectionSets,
192
+ });
193
+ setFederationMeta({
194
+ meta: federationMeta,
195
+ typeName: type.name,
196
+ update: {
197
+ hasResolveReference: true,
198
+ resolvableKeyDirectives: federationDetails.resolvableKeyDirectives,
199
+ referenceSelectionSets,
200
+ referenceSelectionSetsString,
201
+ },
202
+ });
203
+ return new GraphQLObjectType(typeConfig);
204
+ }
205
+ return type;
206
+ },
207
+ });
208
+ return {
209
+ transformedSchema,
210
+ federationMeta,
211
+ };
212
+ }
213
+ /**
214
+ * Removes Federation Spec from GraphQL Schema
215
+ * @param schema
216
+ * @param config
217
+ */
218
+ export function removeFederation(schema) {
219
+ return mapSchema(schema, {
220
+ [MapperKind.QUERY]: queryType => {
221
+ const queryTypeConfig = queryType.toConfig();
222
+ delete queryTypeConfig.fields._entities;
223
+ delete queryTypeConfig.fields._service;
224
+ return new GraphQLObjectType(queryTypeConfig);
225
+ },
226
+ [MapperKind.UNION_TYPE]: unionType => {
227
+ const unionTypeName = unionType.name;
228
+ if (unionTypeName === '_Entity' || unionTypeName === '_Any') {
229
+ return null;
230
+ }
231
+ return unionType;
232
+ },
233
+ [MapperKind.OBJECT_TYPE]: objectType => {
234
+ if (objectType.name === '_Service') {
235
+ return null;
236
+ }
237
+ return objectType;
238
+ },
239
+ });
240
+ }
241
+ const resolveReferenceFieldName = '__resolveReference';
242
+ export class ApolloFederation {
243
+ enabled = false;
244
+ schema;
245
+ providesMap;
246
+ /**
247
+ * `fieldsToGenerate` is a meta object where the keys are object type names
248
+ * and the values are fields that must be generated for that object.
249
+ */
250
+ fieldsToGenerate;
251
+ meta = {};
252
+ constructor({ enabled, schema, meta }) {
253
+ this.enabled = enabled;
254
+ this.schema = schema;
255
+ this.providesMap = this.createMapOfProvides();
256
+ this.fieldsToGenerate = {};
257
+ this.meta = meta;
258
+ }
259
+ /**
260
+ * Excludes types definde by Federation
261
+ * @param typeNames List of type names
262
+ */
263
+ filterTypeNames(typeNames) {
264
+ return this.enabled ? typeNames.filter(t => t !== '_FieldSet') : typeNames;
265
+ }
266
+ /**
267
+ * Excludes `__resolveReference` fields
268
+ * @param fieldNames List of field names
269
+ */
270
+ filterFieldNames(fieldNames) {
271
+ return this.enabled ? fieldNames.filter(t => t !== resolveReferenceFieldName) : fieldNames;
272
+ }
273
+ /**
274
+ * Decides if directive should not be generated
275
+ * @param name directive's name
276
+ */
277
+ skipDirective(name) {
278
+ return this.enabled && ['external', 'requires', 'provides', 'key'].includes(name);
279
+ }
280
+ /**
281
+ * Decides if scalar should not be generated
282
+ * @param name directive's name
283
+ */
284
+ skipScalar(name) {
285
+ return this.enabled && name === '_FieldSet';
286
+ }
287
+ /**
288
+ * findFieldNodesToGenerate
289
+ * @description Function to find field nodes to generate.
290
+ * In a normal setup, all fields must be generated.
291
+ * However, in a Federatin setup, a field should not be generated if:
292
+ * - The field is marked as `@external` and there is no `@provides` path to the field
293
+ * - The parent object is marked as `@external` and there is no `@provides` path to the field
294
+ */
295
+ findFieldNodesToGenerate({ node, }) {
296
+ const nodeName = node.name.value;
297
+ if (this.fieldsToGenerate[nodeName]) {
298
+ return this.fieldsToGenerate[nodeName];
299
+ }
300
+ const fieldNodes = (node.fields || []).map(field => field.node);
301
+ if (!this.enabled) {
302
+ return fieldNodes;
303
+ }
304
+ // If the object is marked with `@external`, fields to generate are those with `@provides`
305
+ if (this.isExternal(node)) {
306
+ const fieldNodesWithProvides = fieldNodes.reduce((acc, fieldNode) => {
307
+ if (this.hasProvides(node, fieldNode.name.value)) {
308
+ acc.push(fieldNode);
309
+ return acc;
310
+ }
311
+ return acc;
312
+ }, []);
313
+ this.fieldsToGenerate[nodeName] = fieldNodesWithProvides;
314
+ return fieldNodesWithProvides;
315
+ }
316
+ // If the object is not marked with `@external`, fields to generate are:
317
+ // - the fields without `@external`
318
+ // - the `@external` fields with `@provides`
319
+ const fieldNodesWithoutExternalOrHasProvides = fieldNodes.reduce((acc, fieldNode) => {
320
+ if (!this.isExternal(fieldNode)) {
321
+ acc.push(fieldNode);
322
+ return acc;
323
+ }
324
+ if (this.isExternal(fieldNode) && this.hasProvides(node, fieldNode.name.value)) {
325
+ acc.push(fieldNode);
326
+ return acc;
327
+ }
328
+ return acc;
329
+ }, []);
330
+ this.fieldsToGenerate[nodeName] = fieldNodesWithoutExternalOrHasProvides;
331
+ return fieldNodesWithoutExternalOrHasProvides;
332
+ }
333
+ isResolveReferenceField(fieldNode) {
334
+ const name = typeof fieldNode.name === 'string' ? fieldNode.name : fieldNode.name.value;
335
+ return this.enabled && name === resolveReferenceFieldName;
336
+ }
337
+ addFederationTypeGenericIfApplicable({ genericTypes, typeName, federationTypesType, }) {
338
+ if (!this.getMeta()[typeName]) {
339
+ return;
340
+ }
341
+ const typeRef = `${federationTypesType}['${typeName}']`;
342
+ genericTypes.push(`FederationReferenceType extends ${typeRef} = ${typeRef}`);
343
+ }
344
+ getMeta() {
345
+ return this.meta;
346
+ }
347
+ isExternal(node) {
348
+ return getDirectivesByName('external', node).length > 0;
349
+ }
350
+ hasProvides(node, fieldName) {
351
+ const fields = this.providesMap[node.name.value];
352
+ if (fields?.length) {
353
+ return fields.includes(fieldName);
354
+ }
355
+ return false;
356
+ }
357
+ createMapOfProvides() {
358
+ const providesMap = {};
359
+ for (const typename of Object.keys(this.schema.getTypeMap())) {
360
+ const objectType = this.schema.getType(typename);
361
+ if (isObjectType(objectType)) {
362
+ for (const field of Object.values(objectType.getFields())) {
363
+ const provides = getDirectivesByName('provides', field.astNode)
364
+ .map(extractReferenceSelectionSet)
365
+ .reduce((prev, curr) => [...prev, ...Object.keys(curr)], []); // FIXME: this is not taking into account nested selection sets e.g. `company { taxCode }`
366
+ const ofType = getBaseType(field.type);
367
+ providesMap[ofType.name] ||= [];
368
+ providesMap[ofType.name].push(...provides);
369
+ }
370
+ }
371
+ }
372
+ return providesMap;
373
+ }
374
+ }
375
+ /**
376
+ * Checks if Object Type is involved in Federation. Based on `@key` directive
377
+ * @param node Type
378
+ */
379
+ function checkTypeFederationDetails(node, schema) {
380
+ const name = node.name.value;
381
+ const directives = node.directives;
382
+ const rootTypeNames = getRootTypeNames(schema);
383
+ const isNotRoot = !rootTypeNames.has(name);
384
+ const isNotIntrospection = !name.startsWith('__');
385
+ const keyDirectives = directives.filter(d => d.name.value === 'key');
386
+ const check = isNotRoot && isNotIntrospection && keyDirectives.length > 0;
387
+ if (!check) {
388
+ return false;
389
+ }
390
+ const resolvableKeyDirectives = keyDirectives.filter(d => {
391
+ for (const arg of d.arguments) {
392
+ if (arg.name.value === 'resolvable' && arg.value.kind === 'BooleanValue' && arg.value.value === false) {
393
+ return false;
394
+ }
395
+ }
396
+ return true;
397
+ });
398
+ return { resolvableKeyDirectives };
399
+ }
400
+ /**
401
+ * Extracts directives from a node based on directive's name
402
+ * @param name directive name
403
+ * @param node ObjectType or Field
404
+ */
405
+ function getDirectivesByName(name, node) {
406
+ return node?.directives?.filter(d => d.name.value === name) || [];
407
+ }
408
+ function extractReferenceSelectionSet(directive) {
409
+ const arg = directive.arguments.find(arg => arg.name.value === 'fields');
410
+ const { value } = arg.value;
411
+ return oldVisit(parse(`{${value}}`), {
412
+ leave: {
413
+ SelectionSet(node) {
414
+ return node.selections.reduce((accum, field) => {
415
+ accum[field.name] = field.selection;
416
+ return accum;
417
+ }, {});
418
+ },
419
+ Field(node) {
420
+ return {
421
+ name: node.name.value,
422
+ selection: node.selectionSet || true,
423
+ };
424
+ },
425
+ Document(node) {
426
+ return node.definitions.find((def) => def.kind === 'OperationDefinition' && def.operation === 'query').selectionSet;
427
+ },
428
+ },
429
+ });
430
+ }
@@ -0,0 +1,2 @@
1
+ import { getDocumentNodeFromSchema, memoize1 } from '@graphql-tools/utils';
2
+ export const getCachedDocumentNodeFromSchema = memoize1(getDocumentNodeFromSchema);