graphql 16.13.1 → 16.14.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 (51) hide show
  1. package/execution/values.js +4 -4
  2. package/execution/values.mjs +4 -4
  3. package/index.d.ts +1 -0
  4. package/language/ast.d.ts +10 -1
  5. package/language/ast.js +8 -1
  6. package/language/ast.mjs +8 -1
  7. package/language/directiveLocation.d.ts +1 -0
  8. package/language/directiveLocation.js +1 -0
  9. package/language/directiveLocation.mjs +1 -0
  10. package/language/index.d.ts +1 -0
  11. package/language/kinds.d.ts +1 -0
  12. package/language/kinds.js +1 -0
  13. package/language/kinds.mjs +1 -0
  14. package/language/parser.d.ts +14 -0
  15. package/language/parser.js +33 -0
  16. package/language/parser.mjs +33 -0
  17. package/language/predicates.js +3 -1
  18. package/language/predicates.mjs +5 -1
  19. package/language/printer.js +13 -1
  20. package/language/printer.mjs +13 -1
  21. package/package.json +1 -1
  22. package/type/directives.d.ts +9 -1
  23. package/type/directives.js +10 -1
  24. package/type/directives.mjs +10 -1
  25. package/type/introspection.js +24 -1
  26. package/type/introspection.mjs +24 -1
  27. package/utilities/buildASTSchema.js +4 -0
  28. package/utilities/buildASTSchema.mjs +4 -0
  29. package/utilities/buildClientSchema.js +1 -0
  30. package/utilities/buildClientSchema.mjs +1 -0
  31. package/utilities/coerceInputValue.js +2 -2
  32. package/utilities/coerceInputValue.mjs +2 -2
  33. package/utilities/extendSchema.js +58 -3
  34. package/utilities/extendSchema.mjs +58 -3
  35. package/utilities/getIntrospectionQuery.d.ts +16 -0
  36. package/utilities/getIntrospectionQuery.js +31 -38
  37. package/utilities/getIntrospectionQuery.mjs +31 -38
  38. package/utilities/introspectionFromSchema.js +1 -0
  39. package/utilities/introspectionFromSchema.mjs +1 -0
  40. package/utilities/printSchema.js +1 -0
  41. package/utilities/printSchema.mjs +1 -0
  42. package/utilities/valueFromAST.js +12 -2
  43. package/utilities/valueFromAST.mjs +12 -2
  44. package/validation/rules/KnownDirectivesRule.js +4 -0
  45. package/validation/rules/KnownDirectivesRule.mjs +4 -0
  46. package/validation/rules/UniqueDirectivesPerLocationRule.js +12 -0
  47. package/validation/rules/UniqueDirectivesPerLocationRule.mjs +12 -0
  48. package/validation/rules/ValuesOfCorrectTypeRule.js +0 -11
  49. package/validation/rules/ValuesOfCorrectTypeRule.mjs +0 -11
  50. package/version.js +3 -3
  51. package/version.mjs +3 -3
@@ -76,7 +76,18 @@ const __Schema = new _definition.GraphQLObjectType({
76
76
  new _definition.GraphQLNonNull(__Directive),
77
77
  ),
78
78
  ),
79
- resolve: (schema) => schema.getDirectives(),
79
+ args: {
80
+ includeDeprecated: {
81
+ type: new _definition.GraphQLNonNull(_scalars.GraphQLBoolean),
82
+ defaultValue: false,
83
+ },
84
+ },
85
+ resolve: (schema, { includeDeprecated }) =>
86
+ includeDeprecated
87
+ ? schema.getDirectives()
88
+ : schema
89
+ .getDirectives()
90
+ .filter((directive) => directive.deprecationReason == null),
80
91
  },
81
92
  }),
82
93
  });
@@ -127,6 +138,14 @@ const __Directive = new _definition.GraphQLObjectType({
127
138
  : field.args.filter((arg) => arg.deprecationReason == null);
128
139
  },
129
140
  },
141
+ isDeprecated: {
142
+ type: new _definition.GraphQLNonNull(_scalars.GraphQLBoolean),
143
+ resolve: (directive) => directive.deprecationReason != null,
144
+ },
145
+ deprecationReason: {
146
+ type: _scalars.GraphQLString,
147
+ resolve: (directive) => directive.deprecationReason,
148
+ },
130
149
  }),
131
150
  });
132
151
 
@@ -213,6 +232,10 @@ const __DirectiveLocation = new _definition.GraphQLEnumType({
213
232
  value: _directiveLocation.DirectiveLocation.INPUT_FIELD_DEFINITION,
214
233
  description: 'Location adjacent to an input object field definition.',
215
234
  },
235
+ DIRECTIVE_DEFINITION: {
236
+ value: _directiveLocation.DirectiveLocation.DIRECTIVE_DEFINITION,
237
+ description: 'Location adjacent to a directive definition.',
238
+ },
216
239
  },
217
240
  });
218
241
 
@@ -58,7 +58,18 @@ export const __Schema = new GraphQLObjectType({
58
58
  type: new GraphQLNonNull(
59
59
  new GraphQLList(new GraphQLNonNull(__Directive)),
60
60
  ),
61
- resolve: (schema) => schema.getDirectives(),
61
+ args: {
62
+ includeDeprecated: {
63
+ type: new GraphQLNonNull(GraphQLBoolean),
64
+ defaultValue: false,
65
+ },
66
+ },
67
+ resolve: (schema, { includeDeprecated }) =>
68
+ includeDeprecated
69
+ ? schema.getDirectives()
70
+ : schema
71
+ .getDirectives()
72
+ .filter((directive) => directive.deprecationReason == null),
62
73
  },
63
74
  }),
64
75
  });
@@ -102,6 +113,14 @@ export const __Directive = new GraphQLObjectType({
102
113
  : field.args.filter((arg) => arg.deprecationReason == null);
103
114
  },
104
115
  },
116
+ isDeprecated: {
117
+ type: new GraphQLNonNull(GraphQLBoolean),
118
+ resolve: (directive) => directive.deprecationReason != null,
119
+ },
120
+ deprecationReason: {
121
+ type: GraphQLString,
122
+ resolve: (directive) => directive.deprecationReason,
123
+ },
105
124
  }),
106
125
  });
107
126
  export const __DirectiveLocation = new GraphQLEnumType({
@@ -185,6 +204,10 @@ export const __DirectiveLocation = new GraphQLEnumType({
185
204
  value: DirectiveLocation.INPUT_FIELD_DEFINITION,
186
205
  description: 'Location adjacent to an input object field definition.',
187
206
  },
207
+ DIRECTIVE_DEFINITION: {
208
+ value: DirectiveLocation.DIRECTIVE_DEFINITION,
209
+ description: 'Location adjacent to a directive definition.',
210
+ },
188
211
  },
189
212
  });
190
213
  export const __Type = new GraphQLObjectType({
@@ -105,6 +105,10 @@ function buildSchema(source, options) {
105
105
  options === null || options === void 0
106
106
  ? void 0
107
107
  : options.allowLegacyFragmentVariables,
108
+ experimentalDirectivesOnDirectiveDefinitions:
109
+ options === null || options === void 0
110
+ ? void 0
111
+ : options.experimentalDirectivesOnDirectiveDefinitions,
108
112
  });
109
113
  return buildASTSchema(document, {
110
114
  assumeValidSDL:
@@ -87,6 +87,10 @@ export function buildSchema(source, options) {
87
87
  options === null || options === void 0
88
88
  ? void 0
89
89
  : options.allowLegacyFragmentVariables,
90
+ experimentalDirectivesOnDirectiveDefinitions:
91
+ options === null || options === void 0
92
+ ? void 0
93
+ : options.experimentalDirectivesOnDirectiveDefinitions,
90
94
  });
91
95
  return buildASTSchema(document, {
92
96
  assumeValidSDL:
@@ -380,6 +380,7 @@ function buildClientSchema(introspection, options) {
380
380
  name: directiveIntrospection.name,
381
381
  description: directiveIntrospection.description,
382
382
  isRepeatable: directiveIntrospection.isRepeatable,
383
+ deprecationReason: directiveIntrospection.deprecationReason,
383
384
  locations: directiveIntrospection.locations.slice(),
384
385
  args: buildInputValueDefMap(directiveIntrospection.args),
385
386
  });
@@ -357,6 +357,7 @@ export function buildClientSchema(introspection, options) {
357
357
  name: directiveIntrospection.name,
358
358
  description: directiveIntrospection.description,
359
359
  isRepeatable: directiveIntrospection.isRepeatable,
360
+ deprecationReason: directiveIntrospection.deprecationReason,
360
361
  locations: directiveIntrospection.locations.slice(),
361
362
  args: buildInputValueDefMap(directiveIntrospection.args),
362
363
  });
@@ -94,7 +94,7 @@ function coerceInputValueImpl(inputValue, type, onError, path) {
94
94
  return;
95
95
  }
96
96
 
97
- const coercedValue = {};
97
+ const coercedValue = Object.create(null);
98
98
  const fieldDefs = type.getFields();
99
99
 
100
100
  for (const field of Object.values(fieldDefs)) {
@@ -167,7 +167,7 @@ function coerceInputValueImpl(inputValue, type, onError, path) {
167
167
  }
168
168
  }
169
169
 
170
- return coercedValue;
170
+ return { ...coercedValue };
171
171
  }
172
172
 
173
173
  if ((0, _definition.isLeafType)(type)) {
@@ -76,7 +76,7 @@ function coerceInputValueImpl(inputValue, type, onError, path) {
76
76
  return;
77
77
  }
78
78
 
79
- const coercedValue = {};
79
+ const coercedValue = Object.create(null);
80
80
  const fieldDefs = type.getFields();
81
81
 
82
82
  for (const field of Object.values(fieldDefs)) {
@@ -149,7 +149,7 @@ function coerceInputValueImpl(inputValue, type, onError, path) {
149
149
  }
150
150
  }
151
151
 
152
- return coercedValue;
152
+ return { ...coercedValue };
153
153
  }
154
154
 
155
155
  if (isLeafType(type)) {
@@ -78,7 +78,8 @@ function extendSchemaImpl(schemaConfig, documentAST, options) {
78
78
 
79
79
  // Collect the type definitions and extensions found in the document.
80
80
  const typeDefs = [];
81
- const typeExtensionsMap = Object.create(null); // New directives and types are separate because a directives and types can
81
+ const typeExtensionsMap = Object.create(null);
82
+ const directiveExtensionsMap = Object.create(null); // New directives and types are separate because a directives and types can
82
83
  // have the same name. For example, a type named "skip".
83
84
 
84
85
  const directiveDefs = [];
@@ -101,6 +102,14 @@ function extendSchemaImpl(schemaConfig, documentAST, options) {
101
102
  : [def];
102
103
  } else if (def.kind === _kinds.Kind.DIRECTIVE_DEFINITION) {
103
104
  directiveDefs.push(def);
105
+ } else if (def.kind === _kinds.Kind.DIRECTIVE_EXTENSION) {
106
+ const extendedDirectiveName = def.name.value;
107
+ const existingDirectiveExtensions =
108
+ directiveExtensionsMap[extendedDirectiveName];
109
+ directiveExtensionsMap[extendedDirectiveName] =
110
+ existingDirectiveExtensions
111
+ ? existingDirectiveExtensions.concat([def])
112
+ : [def];
104
113
  }
105
114
  } // If this document contains no new types, extensions, or directives then
106
115
  // return the same unmodified GraphQLSchema instance.
@@ -108,6 +117,7 @@ function extendSchemaImpl(schemaConfig, documentAST, options) {
108
117
  if (
109
118
  Object.keys(typeExtensionsMap).length === 0 &&
110
119
  typeDefs.length === 0 &&
120
+ Object.keys(directiveExtensionsMap).length === 0 &&
111
121
  directiveDefs.length === 0 &&
112
122
  schemaExtensions.length === 0 &&
113
123
  schemaDef == null
@@ -132,6 +142,12 @@ function extendSchemaImpl(schemaConfig, documentAST, options) {
132
142
  : buildType(typeNode);
133
143
  }
134
144
 
145
+ const directiveMap = Object.create(null);
146
+
147
+ for (const existingDirective of schemaConfig.directives) {
148
+ directiveMap[existingDirective.name] = extendDirective(existingDirective);
149
+ }
150
+
135
151
  const operationTypes = {
136
152
  // Get the extended root operation types.
137
153
  query: schemaConfig.query && replaceNamedType(schemaConfig.query),
@@ -143,6 +159,8 @@ function extendSchemaImpl(schemaConfig, documentAST, options) {
143
159
  ...getOperationTypes(schemaExtensions),
144
160
  }; // Then produce and return a Schema config with these types.
145
161
 
162
+ const directives = Object.values(directiveMap); // will be `Array<GraphQLDirective>`
163
+
146
164
  return {
147
165
  description:
148
166
  (_schemaDef = schemaDef) === null || _schemaDef === void 0
@@ -154,7 +172,7 @@ function extendSchemaImpl(schemaConfig, documentAST, options) {
154
172
  ...operationTypes,
155
173
  types: Object.values(typeMap),
156
174
  directives: [
157
- ...schemaConfig.directives.map(replaceDirective),
175
+ ...directives.map(replaceDirective),
158
176
  ...directiveDefs.map(buildDirective),
159
177
  ],
160
178
  extensions: Object.create(null),
@@ -413,6 +431,29 @@ function extendSchemaImpl(schemaConfig, documentAST, options) {
413
431
  return opTypes;
414
432
  }
415
433
 
434
+ function extendDirective(directive) {
435
+ var _directiveExtensionsM, _config$deprecationRe;
436
+
437
+ const config = directive.toConfig();
438
+ const extensions =
439
+ (_directiveExtensionsM = directiveExtensionsMap[config.name]) !== null &&
440
+ _directiveExtensionsM !== void 0
441
+ ? _directiveExtensionsM
442
+ : [];
443
+ const deprecationReason =
444
+ (_config$deprecationRe = config.deprecationReason) !== null &&
445
+ _config$deprecationRe !== void 0
446
+ ? _config$deprecationRe
447
+ : extensions
448
+ .map((ext) => getDeprecationReason(ext))
449
+ .find((reason) => reason != null);
450
+ return new _directives.GraphQLDirective({
451
+ ...config,
452
+ deprecationReason,
453
+ extensionASTNodes: config.extensionASTNodes.concat(extensions),
454
+ });
455
+ }
456
+
416
457
  function getNamedType(node) {
417
458
  var _stdTypeMap$name2;
418
459
 
@@ -443,8 +484,20 @@ function extendSchemaImpl(schemaConfig, documentAST, options) {
443
484
  }
444
485
 
445
486
  function buildDirective(node) {
446
- var _node$description;
487
+ var _directiveExtensionsM2, _getDeprecationReason, _node$description;
447
488
 
489
+ const extensions =
490
+ (_directiveExtensionsM2 = directiveExtensionsMap[node.name.value]) !==
491
+ null && _directiveExtensionsM2 !== void 0
492
+ ? _directiveExtensionsM2
493
+ : [];
494
+ const deprecationReason =
495
+ (_getDeprecationReason = getDeprecationReason(node)) !== null &&
496
+ _getDeprecationReason !== void 0
497
+ ? _getDeprecationReason
498
+ : extensions
499
+ .map((ext) => getDeprecationReason(ext))
500
+ .find((reason) => reason != null);
448
501
  return new _directives.GraphQLDirective({
449
502
  name: node.name.value,
450
503
  description:
@@ -456,7 +509,9 @@ function extendSchemaImpl(schemaConfig, documentAST, options) {
456
509
  locations: node.locations.map(({ value }) => value),
457
510
  isRepeatable: node.repeatable,
458
511
  args: buildArgumentMap(node.arguments),
512
+ deprecationReason,
459
513
  astNode: node,
514
+ extensionASTNodes: extensions,
460
515
  });
461
516
  }
462
517
 
@@ -87,7 +87,8 @@ export function extendSchemaImpl(schemaConfig, documentAST, options) {
87
87
 
88
88
  // Collect the type definitions and extensions found in the document.
89
89
  const typeDefs = [];
90
- const typeExtensionsMap = Object.create(null); // New directives and types are separate because a directives and types can
90
+ const typeExtensionsMap = Object.create(null);
91
+ const directiveExtensionsMap = Object.create(null); // New directives and types are separate because a directives and types can
91
92
  // have the same name. For example, a type named "skip".
92
93
 
93
94
  const directiveDefs = [];
@@ -110,6 +111,14 @@ export function extendSchemaImpl(schemaConfig, documentAST, options) {
110
111
  : [def];
111
112
  } else if (def.kind === Kind.DIRECTIVE_DEFINITION) {
112
113
  directiveDefs.push(def);
114
+ } else if (def.kind === Kind.DIRECTIVE_EXTENSION) {
115
+ const extendedDirectiveName = def.name.value;
116
+ const existingDirectiveExtensions =
117
+ directiveExtensionsMap[extendedDirectiveName];
118
+ directiveExtensionsMap[extendedDirectiveName] =
119
+ existingDirectiveExtensions
120
+ ? existingDirectiveExtensions.concat([def])
121
+ : [def];
113
122
  }
114
123
  } // If this document contains no new types, extensions, or directives then
115
124
  // return the same unmodified GraphQLSchema instance.
@@ -117,6 +126,7 @@ export function extendSchemaImpl(schemaConfig, documentAST, options) {
117
126
  if (
118
127
  Object.keys(typeExtensionsMap).length === 0 &&
119
128
  typeDefs.length === 0 &&
129
+ Object.keys(directiveExtensionsMap).length === 0 &&
120
130
  directiveDefs.length === 0 &&
121
131
  schemaExtensions.length === 0 &&
122
132
  schemaDef == null
@@ -141,6 +151,12 @@ export function extendSchemaImpl(schemaConfig, documentAST, options) {
141
151
  : buildType(typeNode);
142
152
  }
143
153
 
154
+ const directiveMap = Object.create(null);
155
+
156
+ for (const existingDirective of schemaConfig.directives) {
157
+ directiveMap[existingDirective.name] = extendDirective(existingDirective);
158
+ }
159
+
144
160
  const operationTypes = {
145
161
  // Get the extended root operation types.
146
162
  query: schemaConfig.query && replaceNamedType(schemaConfig.query),
@@ -152,6 +168,8 @@ export function extendSchemaImpl(schemaConfig, documentAST, options) {
152
168
  ...getOperationTypes(schemaExtensions),
153
169
  }; // Then produce and return a Schema config with these types.
154
170
 
171
+ const directives = Object.values(directiveMap); // will be `Array<GraphQLDirective>`
172
+
155
173
  return {
156
174
  description:
157
175
  (_schemaDef = schemaDef) === null || _schemaDef === void 0
@@ -163,7 +181,7 @@ export function extendSchemaImpl(schemaConfig, documentAST, options) {
163
181
  ...operationTypes,
164
182
  types: Object.values(typeMap),
165
183
  directives: [
166
- ...schemaConfig.directives.map(replaceDirective),
184
+ ...directives.map(replaceDirective),
167
185
  ...directiveDefs.map(buildDirective),
168
186
  ],
169
187
  extensions: Object.create(null),
@@ -415,6 +433,29 @@ export function extendSchemaImpl(schemaConfig, documentAST, options) {
415
433
  return opTypes;
416
434
  }
417
435
 
436
+ function extendDirective(directive) {
437
+ var _directiveExtensionsM, _config$deprecationRe;
438
+
439
+ const config = directive.toConfig();
440
+ const extensions =
441
+ (_directiveExtensionsM = directiveExtensionsMap[config.name]) !== null &&
442
+ _directiveExtensionsM !== void 0
443
+ ? _directiveExtensionsM
444
+ : [];
445
+ const deprecationReason =
446
+ (_config$deprecationRe = config.deprecationReason) !== null &&
447
+ _config$deprecationRe !== void 0
448
+ ? _config$deprecationRe
449
+ : extensions
450
+ .map((ext) => getDeprecationReason(ext))
451
+ .find((reason) => reason != null);
452
+ return new GraphQLDirective({
453
+ ...config,
454
+ deprecationReason,
455
+ extensionASTNodes: config.extensionASTNodes.concat(extensions),
456
+ });
457
+ }
458
+
418
459
  function getNamedType(node) {
419
460
  var _stdTypeMap$name2;
420
461
 
@@ -445,8 +486,20 @@ export function extendSchemaImpl(schemaConfig, documentAST, options) {
445
486
  }
446
487
 
447
488
  function buildDirective(node) {
448
- var _node$description;
489
+ var _directiveExtensionsM2, _getDeprecationReason, _node$description;
449
490
 
491
+ const extensions =
492
+ (_directiveExtensionsM2 = directiveExtensionsMap[node.name.value]) !==
493
+ null && _directiveExtensionsM2 !== void 0
494
+ ? _directiveExtensionsM2
495
+ : [];
496
+ const deprecationReason =
497
+ (_getDeprecationReason = getDeprecationReason(node)) !== null &&
498
+ _getDeprecationReason !== void 0
499
+ ? _getDeprecationReason
500
+ : extensions
501
+ .map((ext) => getDeprecationReason(ext))
502
+ .find((reason) => reason != null);
450
503
  return new GraphQLDirective({
451
504
  name: node.name.value,
452
505
  description:
@@ -458,7 +511,9 @@ export function extendSchemaImpl(schemaConfig, documentAST, options) {
458
511
  locations: node.locations.map(({ value }) => value),
459
512
  isRepeatable: node.repeatable,
460
513
  args: buildArgumentMap(node.arguments),
514
+ deprecationReason,
461
515
  astNode: node,
516
+ extensionASTNodes: extensions,
462
517
  });
463
518
  }
464
519
 
@@ -26,11 +26,25 @@ export interface IntrospectionOptions {
26
26
  * Default: false
27
27
  */
28
28
  inputValueDeprecation?: boolean;
29
+ /**
30
+ * Whether target GraphQL server supports deprecation of directives.
31
+ * Default: false
32
+ */
33
+ experimentalDirectiveDeprecation?: boolean;
29
34
  /**
30
35
  * Whether target GraphQL server supports `@oneOf` input objects.
31
36
  * Default: false
32
37
  */
33
38
  oneOf?: boolean;
39
+ /**
40
+ * How deep to recurse into nested types, larger values will result in more
41
+ * accurate results, but have a higher load on the server.
42
+ * Some servers might restrict the maximum query depth or complexity.
43
+ * If that's the case, try decreasing this value.
44
+ *
45
+ * Default: 9
46
+ */
47
+ typeDepth?: number;
34
48
  }
35
49
  /**
36
50
  * Produce the GraphQL query recommended for a full schema introspection.
@@ -183,6 +197,8 @@ export interface IntrospectionDirective {
183
197
  readonly name: string;
184
198
  readonly description?: Maybe<string>;
185
199
  readonly isRepeatable?: boolean;
200
+ readonly isDeprecated?: boolean;
201
+ readonly deprecationReason?: Maybe<string>;
186
202
  readonly locations: ReadonlyArray<DirectiveLocation>;
187
203
  readonly args: ReadonlyArray<IntrospectionInputValue>;
188
204
  }
@@ -16,7 +16,9 @@ function getIntrospectionQuery(options) {
16
16
  directiveIsRepeatable: false,
17
17
  schemaDescription: false,
18
18
  inputValueDeprecation: false,
19
+ experimentalDirectiveDeprecation: false,
19
20
  oneOf: false,
21
+ typeDepth: 9,
20
22
  ...options,
21
23
  };
22
24
  const descriptions = optionsWithDefault.descriptions ? 'description' : '';
@@ -34,7 +36,30 @@ function getIntrospectionQuery(options) {
34
36
  return optionsWithDefault.inputValueDeprecation ? str : '';
35
37
  }
36
38
 
39
+ function experimentalDirectiveDeprecation(str) {
40
+ return optionsWithDefault.experimentalDirectiveDeprecation ? str : '';
41
+ }
42
+
37
43
  const oneOf = optionsWithDefault.oneOf ? 'isOneOf' : '';
44
+
45
+ function ofType(level, indent) {
46
+ if (level <= 0) {
47
+ return '';
48
+ }
49
+
50
+ if (level > 100) {
51
+ throw new Error(
52
+ 'Please set typeDepth to a reasonable value between 0 and 100; the default is 9.',
53
+ );
54
+ }
55
+
56
+ return `
57
+ ${indent}ofType {
58
+ ${indent} name
59
+ ${indent} kind${ofType(level - 1, indent + ' ')}
60
+ ${indent}}`;
61
+ }
62
+
38
63
  return `
39
64
  query IntrospectionQuery {
40
65
  __schema {
@@ -45,10 +70,14 @@ function getIntrospectionQuery(options) {
45
70
  types {
46
71
  ...FullType
47
72
  }
48
- directives {
73
+ directives${experimentalDirectiveDeprecation(
74
+ '(includeDeprecated: true)',
75
+ )} {
49
76
  name
50
77
  ${descriptions}
51
78
  ${directiveIsRepeatable}
79
+ ${experimentalDirectiveDeprecation('isDeprecated')}
80
+ ${experimentalDirectiveDeprecation('deprecationReason')}
52
81
  locations
53
82
  args${inputDeprecation('(includeDeprecated: true)')} {
54
83
  ...InputValue
@@ -103,43 +132,7 @@ function getIntrospectionQuery(options) {
103
132
 
104
133
  fragment TypeRef on __Type {
105
134
  kind
106
- name
107
- ofType {
108
- kind
109
- name
110
- ofType {
111
- kind
112
- name
113
- ofType {
114
- kind
115
- name
116
- ofType {
117
- kind
118
- name
119
- ofType {
120
- kind
121
- name
122
- ofType {
123
- kind
124
- name
125
- ofType {
126
- kind
127
- name
128
- ofType {
129
- kind
130
- name
131
- ofType {
132
- kind
133
- name
134
- }
135
- }
136
- }
137
- }
138
- }
139
- }
140
- }
141
- }
142
- }
135
+ name${ofType(optionsWithDefault.typeDepth, ' ')}
143
136
  }
144
137
  `;
145
138
  }
@@ -9,7 +9,9 @@ export function getIntrospectionQuery(options) {
9
9
  directiveIsRepeatable: false,
10
10
  schemaDescription: false,
11
11
  inputValueDeprecation: false,
12
+ experimentalDirectiveDeprecation: false,
12
13
  oneOf: false,
14
+ typeDepth: 9,
13
15
  ...options,
14
16
  };
15
17
  const descriptions = optionsWithDefault.descriptions ? 'description' : '';
@@ -27,7 +29,30 @@ export function getIntrospectionQuery(options) {
27
29
  return optionsWithDefault.inputValueDeprecation ? str : '';
28
30
  }
29
31
 
32
+ function experimentalDirectiveDeprecation(str) {
33
+ return optionsWithDefault.experimentalDirectiveDeprecation ? str : '';
34
+ }
35
+
30
36
  const oneOf = optionsWithDefault.oneOf ? 'isOneOf' : '';
37
+
38
+ function ofType(level, indent) {
39
+ if (level <= 0) {
40
+ return '';
41
+ }
42
+
43
+ if (level > 100) {
44
+ throw new Error(
45
+ 'Please set typeDepth to a reasonable value between 0 and 100; the default is 9.',
46
+ );
47
+ }
48
+
49
+ return `
50
+ ${indent}ofType {
51
+ ${indent} name
52
+ ${indent} kind${ofType(level - 1, indent + ' ')}
53
+ ${indent}}`;
54
+ }
55
+
31
56
  return `
32
57
  query IntrospectionQuery {
33
58
  __schema {
@@ -38,10 +63,14 @@ export function getIntrospectionQuery(options) {
38
63
  types {
39
64
  ...FullType
40
65
  }
41
- directives {
66
+ directives${experimentalDirectiveDeprecation(
67
+ '(includeDeprecated: true)',
68
+ )} {
42
69
  name
43
70
  ${descriptions}
44
71
  ${directiveIsRepeatable}
72
+ ${experimentalDirectiveDeprecation('isDeprecated')}
73
+ ${experimentalDirectiveDeprecation('deprecationReason')}
45
74
  locations
46
75
  args${inputDeprecation('(includeDeprecated: true)')} {
47
76
  ...InputValue
@@ -96,43 +125,7 @@ export function getIntrospectionQuery(options) {
96
125
 
97
126
  fragment TypeRef on __Type {
98
127
  kind
99
- name
100
- ofType {
101
- kind
102
- name
103
- ofType {
104
- kind
105
- name
106
- ofType {
107
- kind
108
- name
109
- ofType {
110
- kind
111
- name
112
- ofType {
113
- kind
114
- name
115
- ofType {
116
- kind
117
- name
118
- ofType {
119
- kind
120
- name
121
- ofType {
122
- kind
123
- name
124
- ofType {
125
- kind
126
- name
127
- }
128
- }
129
- }
130
- }
131
- }
132
- }
133
- }
134
- }
135
- }
128
+ name${ofType(optionsWithDefault.typeDepth, ' ')}
136
129
  }
137
130
  `;
138
131
  }
@@ -28,6 +28,7 @@ function introspectionFromSchema(schema, options) {
28
28
  directiveIsRepeatable: true,
29
29
  schemaDescription: true,
30
30
  inputValueDeprecation: true,
31
+ experimentalDirectiveDeprecation: true,
31
32
  oneOf: true,
32
33
  ...options,
33
34
  };
@@ -18,6 +18,7 @@ export function introspectionFromSchema(schema, options) {
18
18
  directiveIsRepeatable: true,
19
19
  schemaDescription: true,
20
20
  inputValueDeprecation: true,
21
+ experimentalDirectiveDeprecation: true,
21
22
  oneOf: true,
22
23
  ...options,
23
24
  };
@@ -286,6 +286,7 @@ function printDirective(directive) {
286
286
  'directive @' +
287
287
  directive.name +
288
288
  printArgs(directive.args) +
289
+ printDeprecated(directive.deprecationReason) +
289
290
  (directive.isRepeatable ? ' repeatable' : '') +
290
291
  ' on ' +
291
292
  directive.locations.join(' | ')
@@ -262,6 +262,7 @@ function printDirective(directive) {
262
262
  'directive @' +
263
263
  directive.name +
264
264
  printArgs(directive.args) +
265
+ printDeprecated(directive.deprecationReason) +
265
266
  (directive.isRepeatable ? ' repeatable' : '') +
266
267
  ' on ' +
267
268
  directive.locations.join(' | ')