@apollo/federation-internals 2.0.0-alpha.0 → 2.0.0-alpha.4

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 (86) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/buildSchema.d.ts.map +1 -1
  3. package/dist/buildSchema.js +3 -3
  4. package/dist/buildSchema.js.map +1 -1
  5. package/dist/coreSpec.d.ts +1 -1
  6. package/dist/coreSpec.d.ts.map +1 -1
  7. package/dist/coreSpec.js +2 -0
  8. package/dist/coreSpec.js.map +1 -1
  9. package/dist/debug.d.ts.map +1 -1
  10. package/dist/debug.js +7 -23
  11. package/dist/debug.js.map +1 -1
  12. package/dist/definitions.d.ts +28 -13
  13. package/dist/definitions.d.ts.map +1 -1
  14. package/dist/definitions.js +132 -71
  15. package/dist/definitions.js.map +1 -1
  16. package/dist/error.d.ts +87 -3
  17. package/dist/error.d.ts.map +1 -1
  18. package/dist/error.js +143 -5
  19. package/dist/error.js.map +1 -1
  20. package/dist/extractSubgraphsFromSupergraph.d.ts.map +1 -1
  21. package/dist/extractSubgraphsFromSupergraph.js +60 -8
  22. package/dist/extractSubgraphsFromSupergraph.js.map +1 -1
  23. package/dist/federation.d.ts +7 -6
  24. package/dist/federation.d.ts.map +1 -1
  25. package/dist/federation.js +227 -81
  26. package/dist/federation.js.map +1 -1
  27. package/dist/genErrorCodeDoc.d.ts +2 -0
  28. package/dist/genErrorCodeDoc.d.ts.map +1 -0
  29. package/dist/genErrorCodeDoc.js +55 -0
  30. package/dist/genErrorCodeDoc.js.map +1 -0
  31. package/dist/inaccessibleSpec.d.ts +1 -1
  32. package/dist/inaccessibleSpec.d.ts.map +1 -1
  33. package/dist/inaccessibleSpec.js +5 -5
  34. package/dist/inaccessibleSpec.js.map +1 -1
  35. package/dist/joinSpec.d.ts.map +1 -1
  36. package/dist/joinSpec.js +6 -5
  37. package/dist/joinSpec.js.map +1 -1
  38. package/dist/operations.d.ts.map +1 -1
  39. package/dist/operations.js +16 -16
  40. package/dist/operations.js.map +1 -1
  41. package/dist/print.d.ts +1 -1
  42. package/dist/print.d.ts.map +1 -1
  43. package/dist/print.js +4 -4
  44. package/dist/print.js.map +1 -1
  45. package/dist/suggestions.js +1 -1
  46. package/dist/suggestions.js.map +1 -1
  47. package/dist/tagSpec.d.ts +2 -2
  48. package/dist/tagSpec.d.ts.map +1 -1
  49. package/dist/tagSpec.js +10 -2
  50. package/dist/tagSpec.js.map +1 -1
  51. package/dist/utils.d.ts +16 -0
  52. package/dist/utils.d.ts.map +1 -1
  53. package/dist/utils.js +82 -1
  54. package/dist/utils.js.map +1 -1
  55. package/dist/validate.js.map +1 -1
  56. package/dist/values.d.ts +2 -1
  57. package/dist/values.d.ts.map +1 -1
  58. package/dist/values.js +29 -4
  59. package/dist/values.js.map +1 -1
  60. package/package.json +5 -6
  61. package/src/__tests__/definitions.test.ts +3 -3
  62. package/src/__tests__/extractSubgraphsFromSupergraph.test.ts +432 -0
  63. package/src/__tests__/matchers/toMatchString.ts +2 -2
  64. package/src/__tests__/removeInaccessibleElements.test.ts +8 -8
  65. package/src/__tests__/subgraphValidation.test.ts +452 -0
  66. package/src/__tests__/utils.test.ts +92 -0
  67. package/src/buildSchema.ts +12 -11
  68. package/src/coreSpec.ts +12 -10
  69. package/src/debug.ts +8 -25
  70. package/src/definitions.ts +249 -115
  71. package/src/error.ts +334 -7
  72. package/src/extractSubgraphsFromSupergraph.ts +80 -19
  73. package/src/federation.ts +299 -138
  74. package/src/genErrorCodeDoc.ts +69 -0
  75. package/src/inaccessibleSpec.ts +13 -8
  76. package/src/joinSpec.ts +11 -8
  77. package/src/operations.ts +40 -38
  78. package/src/print.ts +8 -8
  79. package/src/suggestions.ts +1 -1
  80. package/src/tagSpec.ts +12 -7
  81. package/src/types.ts +1 -1
  82. package/src/utils.ts +109 -0
  83. package/src/validate.ts +4 -4
  84. package/src/values.ts +51 -9
  85. package/tsconfig.test.tsbuildinfo +1 -1
  86. package/tsconfig.tsbuildinfo +1 -1
@@ -88,28 +88,23 @@ function isCustomScalarType(type) {
88
88
  }
89
89
  exports.isCustomScalarType = isCustomScalarType;
90
90
  function isIntType(type) {
91
- var _a;
92
- return type === ((_a = type.schema()) === null || _a === void 0 ? void 0 : _a.intType());
91
+ return type === type.schema().intType();
93
92
  }
94
93
  exports.isIntType = isIntType;
95
94
  function isStringType(type) {
96
- var _a;
97
- return type === ((_a = type.schema()) === null || _a === void 0 ? void 0 : _a.stringType());
95
+ return type === type.schema().stringType();
98
96
  }
99
97
  exports.isStringType = isStringType;
100
98
  function isFloatType(type) {
101
- var _a;
102
- return type === ((_a = type.schema()) === null || _a === void 0 ? void 0 : _a.floatType());
99
+ return type === type.schema().floatType();
103
100
  }
104
101
  exports.isFloatType = isFloatType;
105
102
  function isBooleanType(type) {
106
- var _a;
107
- return type === ((_a = type.schema()) === null || _a === void 0 ? void 0 : _a.booleanType());
103
+ return type === type.schema().booleanType();
108
104
  }
109
105
  exports.isBooleanType = isBooleanType;
110
106
  function isIDType(type) {
111
- var _a;
112
- return type === ((_a = type.schema()) === null || _a === void 0 ? void 0 : _a.idType());
107
+ return type === type.schema().idType();
113
108
  }
114
109
  exports.isIDType = isIDType;
115
110
  function isObjectType(type) {
@@ -192,40 +187,40 @@ function runtimeTypesIntersects(t1, t2) {
192
187
  }
193
188
  exports.runtimeTypesIntersects = runtimeTypesIntersects;
194
189
  exports.executableDirectiveLocations = [
195
- 'QUERY',
196
- 'MUTATION',
197
- 'SUBSCRIPTION',
198
- 'FIELD',
199
- 'FRAGMENT_DEFINITION',
200
- 'FRAGMENT_SPREAD',
201
- 'INLINE_FRAGMENT',
202
- 'VARIABLE_DEFINITION',
190
+ graphql_1.DirectiveLocation.QUERY,
191
+ graphql_1.DirectiveLocation.MUTATION,
192
+ graphql_1.DirectiveLocation.SUBSCRIPTION,
193
+ graphql_1.DirectiveLocation.FIELD,
194
+ graphql_1.DirectiveLocation.FRAGMENT_DEFINITION,
195
+ graphql_1.DirectiveLocation.FRAGMENT_SPREAD,
196
+ graphql_1.DirectiveLocation.INLINE_FRAGMENT,
197
+ graphql_1.DirectiveLocation.VARIABLE_DEFINITION,
203
198
  ];
204
199
  function typeToAST(type) {
205
200
  switch (type.kind) {
206
201
  case 'ListType':
207
202
  return {
208
- kind: 'ListType',
203
+ kind: graphql_1.Kind.LIST_TYPE,
209
204
  type: typeToAST(type.ofType)
210
205
  };
211
206
  case 'NonNullType':
212
207
  return {
213
- kind: 'NonNullType',
208
+ kind: graphql_1.Kind.NON_NULL_TYPE,
214
209
  type: typeToAST(type.ofType)
215
210
  };
216
211
  default:
217
212
  return {
218
- kind: 'NamedType',
219
- name: { kind: 'Name', value: type.name }
213
+ kind: graphql_1.Kind.NAMED_TYPE,
214
+ name: { kind: graphql_1.Kind.NAME, value: type.name }
220
215
  };
221
216
  }
222
217
  }
223
218
  exports.typeToAST = typeToAST;
224
219
  function typeFromAST(schema, node) {
225
220
  switch (node.kind) {
226
- case 'ListType':
221
+ case graphql_1.Kind.LIST_TYPE:
227
222
  return new ListType(typeFromAST(schema, node.type));
228
- case 'NonNullType':
223
+ case graphql_1.Kind.NON_NULL_TYPE:
229
224
  return new NonNullType(typeFromAST(schema, node.type));
230
225
  default:
231
226
  const type = schema.type(node.name.value);
@@ -259,7 +254,7 @@ class DirectiveTargetElement {
259
254
  applyDirective(defOrDirective, args) {
260
255
  let toAdd;
261
256
  if (defOrDirective instanceof Directive) {
262
- if (defOrDirective.schema() && defOrDirective.schema() != this.schema()) {
257
+ if (defOrDirective.schema() != this.schema()) {
263
258
  throw new Error(`Cannot add directive ${defOrDirective} to ${this} as it is attached to another schema`);
264
259
  }
265
260
  toAdd = defOrDirective;
@@ -280,7 +275,7 @@ class DirectiveTargetElement {
280
275
  }
281
276
  return this.appliedDirectives.map(directive => {
282
277
  return {
283
- kind: 'Directive',
278
+ kind: graphql_1.Kind.DIRECTIVE,
284
279
  name: {
285
280
  kind: graphql_1.Kind.NAME,
286
281
  value: directive.name,
@@ -305,19 +300,32 @@ function sourceASTs(...elts) {
305
300
  exports.sourceASTs = sourceASTs;
306
301
  class Element {
307
302
  schema() {
303
+ const schema = this.schemaInternal();
304
+ (0, utils_1.assert)(schema, 'requested schema does not exist. Probably because the element is unattached');
305
+ return schema;
306
+ }
307
+ schemaInternal() {
308
308
  if (!this._parent) {
309
309
  return undefined;
310
310
  }
311
311
  else if (this._parent instanceof Schema) {
312
312
  return this._parent;
313
313
  }
314
- else {
314
+ else if (this._parent instanceof SchemaElement) {
315
+ return this._parent.schemaInternal();
316
+ }
317
+ else if (this._parent instanceof DirectiveTargetElement) {
315
318
  return this._parent.schema();
316
319
  }
320
+ (0, utils_1.assert)(false, 'unreachable code. parent is of unknown type');
317
321
  }
318
322
  get parent() {
323
+ (0, utils_1.assert)(this._parent, 'trying to access non-existent parent');
319
324
  return this._parent;
320
325
  }
326
+ isAttached() {
327
+ return !!this._parent;
328
+ }
321
329
  setParent(parent) {
322
330
  (0, utils_1.assert)(!this._parent, "Cannot set parent of an already attached element");
323
331
  this._parent = parent;
@@ -326,7 +334,7 @@ class Element {
326
334
  onAttached() {
327
335
  }
328
336
  checkUpdate() {
329
- if (!this.schema()) {
337
+ if (!this.isAttached()) {
330
338
  throw error(`Cannot modify detached element ${this}`);
331
339
  }
332
340
  }
@@ -373,7 +381,7 @@ class SchemaElement extends Element {
373
381
  this.checkUpdate();
374
382
  const def = this.schema().directive(nameOrDefOrDirective);
375
383
  if (!def) {
376
- throw new graphql_1.GraphQLError(`Cannot apply unkown directive "@${nameOrDefOrDirective}"`);
384
+ throw new graphql_1.GraphQLError(`Cannot apply unknown directive "@${nameOrDefOrDirective}"`);
377
385
  }
378
386
  name = nameOrDefOrDirective;
379
387
  }
@@ -394,7 +402,7 @@ class SchemaElement extends Element {
394
402
  applied.forEach(d => d.remove());
395
403
  }
396
404
  onModification() {
397
- const schema = this.schema();
405
+ const schema = this.schemaInternal();
398
406
  if (schema) {
399
407
  Schema.prototype['onModification'].call(schema);
400
408
  }
@@ -421,7 +429,7 @@ class SchemaElement extends Element {
421
429
  thisElement = thisElement.parent;
422
430
  }
423
431
  }
424
- if (addedElement) {
432
+ if (addedElement && addedElement.isAttached()) {
425
433
  const thatSchema = addedElement.schema();
426
434
  if (thatSchema && thatSchema != this.schema()) {
427
435
  throw error(`Cannot add element ${addedElement} to ${this} as it is attached to another schema`);
@@ -514,6 +522,9 @@ class BaseNamedType extends NamedSchemaElement {
514
522
  this._parent = undefined;
515
523
  return toReturn;
516
524
  }
525
+ removeRecursive() {
526
+ this.remove().forEach(ref => this.removeReferenceRecursive(ref));
527
+ }
517
528
  referencers() {
518
529
  return (0, utils_1.setValues)(this._referencers);
519
530
  }
@@ -559,7 +570,7 @@ class BaseExtensionMember extends Element {
559
570
  setOfExtension(extension) {
560
571
  var _a;
561
572
  this.checkUpdate();
562
- if (extension && !((_a = this.parent) === null || _a === void 0 ? void 0 : _a.extensions().has(extension))) {
573
+ if (extension && !((_a = this._parent) === null || _a === void 0 ? void 0 : _a.extensions().has(extension))) {
563
574
  throw error(`Cannot set object as part of the provided extension: it is not an extension of parent ${this.parent}`);
564
575
  }
565
576
  this._extension = extension;
@@ -585,14 +596,13 @@ class BuiltIns {
585
596
  addBuiltInDirectives(schema) {
586
597
  for (const name of ['include', 'skip']) {
587
598
  this.addBuiltInDirective(schema, name)
588
- .addLocations('FIELD', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT')
599
+ .addLocations(graphql_1.DirectiveLocation.FIELD, graphql_1.DirectiveLocation.FRAGMENT_SPREAD, graphql_1.DirectiveLocation.INLINE_FRAGMENT)
589
600
  .addArgument('if', new NonNullType(schema.booleanType()));
590
601
  }
591
602
  this.addBuiltInDirective(schema, 'deprecated')
592
- .addLocations('FIELD_DEFINITION', 'ENUM_VALUE', 'ARGUMENT_DEFINITION', 'INPUT_FIELD_DEFINITION')
593
- .addArgument('reason', schema.stringType(), 'No longer supported');
603
+ .addLocations(graphql_1.DirectiveLocation.FIELD_DEFINITION, graphql_1.DirectiveLocation.ENUM_VALUE, graphql_1.DirectiveLocation.ARGUMENT_DEFINITION, graphql_1.DirectiveLocation.INPUT_FIELD_DEFINITION).addArgument('reason', schema.stringType(), 'No longer supported');
594
604
  this.addBuiltInDirective(schema, 'specifiedBy')
595
- .addLocations('SCALAR')
605
+ .addLocations(graphql_1.DirectiveLocation.SCALAR)
596
606
  .addArgument('url', new NonNullType(schema.stringType()));
597
607
  }
598
608
  isGraphQLBuiltIn(element) {
@@ -883,8 +893,12 @@ class Schema {
883
893
  }
884
894
  return this.apiSchema;
885
895
  }
886
- toGraphQLJSSchema() {
887
- return (0, graphql_1.buildASTSchema)(this.toAST());
896
+ toGraphQLJSSchema(isSubgraph = false) {
897
+ if (!isSubgraph) {
898
+ return (0, graphql_1.buildASTSchema)(this.toAST());
899
+ }
900
+ const ast = (0, graphql_1.parse)((0, print_1.printSchema)(this, { ...toASTPrintOptions, mergeTypesAndExtensions: true }), { noLocation: true });
901
+ return (0, graphql_1.buildASTSchema)(ast);
888
902
  }
889
903
  get schemaDefinition() {
890
904
  return this._schemaDefinition;
@@ -937,7 +951,7 @@ class Schema {
937
951
  if (existing && !existing.isBuiltIn) {
938
952
  throw error(`Type ${type} already exists in this schema`);
939
953
  }
940
- if (type.parent) {
954
+ if (type.isAttached()) {
941
955
  if (type.parent == this) {
942
956
  return type;
943
957
  }
@@ -1002,7 +1016,7 @@ class Schema {
1002
1016
  if (existing && !existing.isBuiltIn) {
1003
1017
  throw error(`Directive ${definition} already exists in this schema`);
1004
1018
  }
1005
- if (definition.parent) {
1019
+ if (definition.isAttached()) {
1006
1020
  if (definition.parent == this) {
1007
1021
  return definition;
1008
1022
  }
@@ -1183,6 +1197,9 @@ class ScalarType extends BaseNamedType {
1183
1197
  }
1184
1198
  removeInnerElements() {
1185
1199
  }
1200
+ removeReferenceRecursive(ref) {
1201
+ ref.remove();
1202
+ }
1186
1203
  }
1187
1204
  exports.ScalarType = ScalarType;
1188
1205
  class InterfaceImplementation extends BaseExtensionMember {
@@ -1237,7 +1254,7 @@ class FieldBasedType extends BaseNamedType {
1237
1254
  this.checkUpdate();
1238
1255
  const maybeItf = this.schema().type(nameOrItfOrItfImpl);
1239
1256
  if (!maybeItf) {
1240
- throw new graphql_1.GraphQLError(`Cannot implement unkown type ${nameOrItfOrItfImpl}`);
1257
+ throw new graphql_1.GraphQLError(`Cannot implement unknown type ${nameOrItfOrItfImpl}`);
1241
1258
  }
1242
1259
  else if (maybeItf.kind != 'InterfaceType') {
1243
1260
  throw new graphql_1.GraphQLError(`Cannot implement non-interface type ${nameOrItfOrItfImpl} (of type ${maybeItf.kind})`);
@@ -1348,19 +1365,25 @@ class ObjectType extends FieldBasedType {
1348
1365
  }
1349
1366
  isRootType() {
1350
1367
  const schema = this.schema();
1351
- if (!schema) {
1352
- return false;
1353
- }
1354
1368
  return schema.schemaDefinition.roots().some(rt => rt.type == this);
1355
1369
  }
1356
1370
  isQueryRootType() {
1357
1371
  var _a;
1358
1372
  const schema = this.schema();
1359
- if (!schema) {
1360
- return false;
1361
- }
1362
1373
  return ((_a = schema.schemaDefinition.root('query')) === null || _a === void 0 ? void 0 : _a.type) === this;
1363
1374
  }
1375
+ removeReferenceRecursive(ref) {
1376
+ switch (ref.kind) {
1377
+ case 'FieldDefinition':
1378
+ ref.removeRecursive();
1379
+ break;
1380
+ case 'UnionType':
1381
+ if (ref.membersCount() === 0) {
1382
+ ref.removeRecursive();
1383
+ }
1384
+ break;
1385
+ }
1386
+ }
1364
1387
  }
1365
1388
  exports.ObjectType = ObjectType;
1366
1389
  class InterfaceType extends FieldBasedType {
@@ -1378,6 +1401,11 @@ class InterfaceType extends FieldBasedType {
1378
1401
  const typeName = typeof type === 'string' ? type : type.name;
1379
1402
  return this.possibleRuntimeTypes().some(t => t.name == typeName);
1380
1403
  }
1404
+ removeReferenceRecursive(ref) {
1405
+ if (ref.kind === 'FieldDefinition') {
1406
+ ref.removeRecursive();
1407
+ }
1408
+ }
1381
1409
  }
1382
1410
  exports.InterfaceType = InterfaceType;
1383
1411
  class UnionMember extends BaseExtensionMember {
@@ -1427,7 +1455,7 @@ class UnionType extends BaseNamedType {
1427
1455
  this.checkUpdate();
1428
1456
  const maybeObj = this.schema().type(nameOrTypeOrMember);
1429
1457
  if (!maybeObj) {
1430
- throw new graphql_1.GraphQLError(`Cannot add unkown type ${nameOrTypeOrMember} as member of union type ${this.name}`);
1458
+ throw new graphql_1.GraphQLError(`Cannot add unknown type ${nameOrTypeOrMember} as member of union type ${this.name}`);
1431
1459
  }
1432
1460
  else if (maybeObj.kind != 'ObjectType') {
1433
1461
  throw new graphql_1.GraphQLError(`Cannot add non-object type ${nameOrTypeOrMember} (of type ${maybeObj.kind}) as member of union type ${this.name}`);
@@ -1482,6 +1510,9 @@ class UnionType extends BaseNamedType {
1482
1510
  hasNonExtensionInnerElements() {
1483
1511
  return this.members().some(m => m.ofExtension() === undefined);
1484
1512
  }
1513
+ removeReferenceRecursive(ref) {
1514
+ ref.removeRecursive();
1515
+ }
1485
1516
  }
1486
1517
  exports.UnionType = UnionType;
1487
1518
  class EnumType extends BaseNamedType {
@@ -1532,6 +1563,9 @@ class EnumType extends BaseNamedType {
1532
1563
  hasNonExtensionInnerElements() {
1533
1564
  return this._values.some(v => v.ofExtension() === undefined);
1534
1565
  }
1566
+ removeReferenceRecursive(ref) {
1567
+ ref.removeRecursive();
1568
+ }
1535
1569
  }
1536
1570
  exports.EnumType = EnumType;
1537
1571
  class InputObjectType extends BaseNamedType {
@@ -1556,7 +1590,7 @@ class InputObjectType extends BaseNamedType {
1556
1590
  throw error(`Field ${toAdd.name} already exists on ${this}`);
1557
1591
  }
1558
1592
  if (type && !isInputType(type)) {
1559
- throw error(`Invalid ouptut type ${type} for field ${toAdd.name}: input field types should be input types.`);
1593
+ throw error(`Invalid output type ${type} for field ${toAdd.name}: input field types should be input types.`);
1560
1594
  }
1561
1595
  this._fields.set(toAdd.name, toAdd);
1562
1596
  this._cachedFieldsArray = undefined;
@@ -1588,6 +1622,14 @@ class InputObjectType extends BaseNamedType {
1588
1622
  hasNonExtensionInnerElements() {
1589
1623
  return this.fields().some(f => f.ofExtension() === undefined);
1590
1624
  }
1625
+ removeReferenceRecursive(ref) {
1626
+ if (ref.kind === 'ArgumentDefinition') {
1627
+ ref.parent().removeRecursive();
1628
+ }
1629
+ else {
1630
+ ref.removeRecursive();
1631
+ }
1632
+ }
1591
1633
  }
1592
1634
  exports.InputObjectType = InputObjectType;
1593
1635
  class BaseWrapperType {
@@ -1598,6 +1640,9 @@ class BaseWrapperType {
1598
1640
  schema() {
1599
1641
  return this.baseType().schema();
1600
1642
  }
1643
+ isAttached() {
1644
+ return this.baseType().isAttached();
1645
+ }
1601
1646
  get ofType() {
1602
1647
  return this._type;
1603
1648
  }
@@ -1636,7 +1681,7 @@ class FieldDefinition extends NamedSchemaElementWithType {
1636
1681
  return this.isBuiltIn;
1637
1682
  }
1638
1683
  get coordinate() {
1639
- const parent = this.parent;
1684
+ const parent = this._parent;
1640
1685
  return `${parent == undefined ? '<detached>' : parent.coordinate}.${this.name}`;
1641
1686
  }
1642
1687
  hasArguments() {
@@ -1670,7 +1715,7 @@ class FieldDefinition extends NamedSchemaElementWithType {
1670
1715
  return existing;
1671
1716
  }
1672
1717
  if (type && !isInputType(type)) {
1673
- throw error(`Invalid ouptut type ${type} for argument ${toAdd.name} of ${this}: arguments should be input types.`);
1718
+ throw error(`Invalid output type ${type} for argument ${toAdd.name} of ${this}: arguments should be input types.`);
1674
1719
  }
1675
1720
  this._args.set(toAdd.name, toAdd);
1676
1721
  Element.prototype['setParent'].call(toAdd, this);
@@ -1686,7 +1731,7 @@ class FieldDefinition extends NamedSchemaElementWithType {
1686
1731
  setOfExtension(extension) {
1687
1732
  var _a;
1688
1733
  this.checkUpdate();
1689
- if (extension && !((_a = this.parent) === null || _a === void 0 ? void 0 : _a.extensions().has(extension))) {
1734
+ if (extension && !((_a = this._parent) === null || _a === void 0 ? void 0 : _a.extensions().has(extension))) {
1690
1735
  throw error(`Cannot mark field ${this.name} as part of the provided extension: it is not an extension of field parent type ${this.parent}`);
1691
1736
  }
1692
1737
  this._extension = extension;
@@ -1722,6 +1767,13 @@ class FieldDefinition extends NamedSchemaElementWithType {
1722
1767
  this._parent = undefined;
1723
1768
  return [];
1724
1769
  }
1770
+ removeRecursive() {
1771
+ const parent = this._parent;
1772
+ this.remove();
1773
+ if (parent && !isUnionType(parent) && parent.fields().length === 0) {
1774
+ parent.removeRecursive();
1775
+ }
1776
+ }
1725
1777
  toString() {
1726
1778
  const args = this._args.size == 0
1727
1779
  ? ""
@@ -1736,7 +1788,7 @@ class InputFieldDefinition extends NamedSchemaElementWithType {
1736
1788
  this.kind = 'InputFieldDefinition';
1737
1789
  }
1738
1790
  get coordinate() {
1739
- const parent = this.parent;
1791
+ const parent = this._parent;
1740
1792
  return `${parent == undefined ? '<detached>' : parent.coordinate}.${this.name}`;
1741
1793
  }
1742
1794
  isRequired() {
@@ -1748,7 +1800,7 @@ class InputFieldDefinition extends NamedSchemaElementWithType {
1748
1800
  setOfExtension(extension) {
1749
1801
  var _a;
1750
1802
  this.checkUpdate();
1751
- if (extension && !((_a = this.parent) === null || _a === void 0 ? void 0 : _a.extensions().has(extension))) {
1803
+ if (extension && !((_a = this._parent) === null || _a === void 0 ? void 0 : _a.extensions().has(extension))) {
1752
1804
  throw error(`Cannot mark field ${this.name} as part of the provided extension: it is not an extension of field parent type ${this.parent}`);
1753
1805
  }
1754
1806
  this._extension = extension;
@@ -1767,6 +1819,13 @@ class InputFieldDefinition extends NamedSchemaElementWithType {
1767
1819
  this.type = undefined;
1768
1820
  return [];
1769
1821
  }
1822
+ removeRecursive() {
1823
+ const parent = this._parent;
1824
+ this.remove();
1825
+ if (parent && parent.fields().length === 0) {
1826
+ parent.removeRecursive();
1827
+ }
1828
+ }
1770
1829
  toString() {
1771
1830
  const defaultStr = this.defaultValue === undefined ? "" : ` = ${(0, values_1.valueToString)(this.defaultValue, this.type)}`;
1772
1831
  return `${this.name}: ${this.type}${defaultStr}`;
@@ -1779,7 +1838,7 @@ class ArgumentDefinition extends NamedSchemaElementWithType {
1779
1838
  this.kind = 'ArgumentDefinition';
1780
1839
  }
1781
1840
  get coordinate() {
1782
- const parent = this.parent;
1841
+ const parent = this._parent;
1783
1842
  return `${parent == undefined ? '<detached>' : parent.coordinate}(${this.name}:)`;
1784
1843
  }
1785
1844
  isRequired() {
@@ -1816,7 +1875,7 @@ class EnumValue extends NamedSchemaElement {
1816
1875
  this.kind = 'EnumValue';
1817
1876
  }
1818
1877
  get coordinate() {
1819
- const parent = this.parent;
1878
+ const parent = this._parent;
1820
1879
  return `${parent == undefined ? '<detached>' : parent.coordinate}.${this.name}`;
1821
1880
  }
1822
1881
  ofExtension() {
@@ -1825,7 +1884,7 @@ class EnumValue extends NamedSchemaElement {
1825
1884
  setOfExtension(extension) {
1826
1885
  var _a;
1827
1886
  this.checkUpdate();
1828
- if (extension && !((_a = this.parent) === null || _a === void 0 ? void 0 : _a.extensions().has(extension))) {
1887
+ if (extension && !((_a = this._parent) === null || _a === void 0 ? void 0 : _a.extensions().has(extension))) {
1829
1888
  throw error(`Cannot mark field ${this.name} as part of the provided extension: it is not an extension of field parent type ${this.parent}`);
1830
1889
  }
1831
1890
  this._extension = extension;
@@ -1915,7 +1974,7 @@ class DirectiveDefinition extends NamedSchemaElement {
1915
1974
  return this.addLocations(...Object.values(graphql_1.DirectiveLocation));
1916
1975
  }
1917
1976
  addAllTypeLocations() {
1918
- return this.addLocations('SCALAR', 'OBJECT', 'INTERFACE', 'UNION', 'ENUM', 'INPUT_OBJECT');
1977
+ return this.addLocations(graphql_1.DirectiveLocation.SCALAR, graphql_1.DirectiveLocation.OBJECT, graphql_1.DirectiveLocation.INTERFACE, graphql_1.DirectiveLocation.UNION, graphql_1.DirectiveLocation.ENUM, graphql_1.DirectiveLocation.INPUT_OBJECT);
1919
1978
  }
1920
1979
  removeLocations(...locations) {
1921
1980
  let modified = false;
@@ -1959,6 +2018,9 @@ class DirectiveDefinition extends NamedSchemaElement {
1959
2018
  this._referencers.clear();
1960
2019
  return toReturn;
1961
2020
  }
2021
+ removeRecursive() {
2022
+ this.remove().forEach(ref => ref.remove());
2023
+ }
1962
2024
  toString() {
1963
2025
  return `@${this.name}`;
1964
2026
  }
@@ -1971,12 +2033,11 @@ class Directive extends Element {
1971
2033
  this._args = _args;
1972
2034
  }
1973
2035
  schema() {
1974
- var _a;
1975
- return (_a = this._parent) === null || _a === void 0 ? void 0 : _a.schema();
2036
+ return this.parent.schema();
1976
2037
  }
1977
2038
  get definition() {
1978
2039
  const doc = this.schema();
1979
- return doc === null || doc === void 0 ? void 0 : doc.directive(this.name);
2040
+ return doc.directive(this.name);
1980
2041
  }
1981
2042
  arguments(includeDefaultValues = false) {
1982
2043
  if (!includeDefaultValues) {
@@ -1998,7 +2059,7 @@ class Directive extends Element {
1998
2059
  }
1999
2060
  }
2000
2061
  isAttachedToSchemaElement() {
2001
- return this.parent !== undefined && this.parent instanceof SchemaElement;
2062
+ return this.isAttached();
2002
2063
  }
2003
2064
  setArguments(args) {
2004
2065
  this._args = args;
@@ -2013,7 +2074,7 @@ class Directive extends Element {
2013
2074
  if (entries.length !== Object.keys(expectedArgs).length) {
2014
2075
  return false;
2015
2076
  }
2016
- for (var [key, val] of entries) {
2077
+ for (const [key, val] of entries) {
2017
2078
  if (!(key in expectedArgs)) {
2018
2079
  return false;
2019
2080
  }
@@ -2052,19 +2113,18 @@ class Directive extends Element {
2052
2113
  (0, utils_1.assert)(definition, () => `Cannot convert arguments of detached directive ${this}`);
2053
2114
  return entries.map(([n, v]) => {
2054
2115
  return {
2055
- kind: 'Argument',
2116
+ kind: graphql_1.Kind.ARGUMENT,
2056
2117
  name: { kind: graphql_1.Kind.NAME, value: n },
2057
2118
  value: (0, values_1.valueToAST)(v, definition.argument(n).type),
2058
2119
  };
2059
2120
  });
2060
2121
  }
2061
2122
  remove() {
2062
- var _a;
2063
2123
  if (!this._parent) {
2064
2124
  return false;
2065
2125
  }
2066
2126
  this.onModification();
2067
- const coreFeatures = (_a = this.schema()) === null || _a === void 0 ? void 0 : _a.coreFeatures;
2127
+ const coreFeatures = this.schema().coreFeatures;
2068
2128
  if (coreFeatures && this.name === coreFeatures.coreItself.nameInSchema) {
2069
2129
  const url = coreSpec_1.FeatureUrl.parse(this._args['feature']);
2070
2130
  if (url.identity === coreFeatures.coreItself.url.identity) {
@@ -2109,8 +2169,8 @@ class Variable {
2109
2169
  }
2110
2170
  toVariableNode() {
2111
2171
  return {
2112
- kind: 'Variable',
2113
- name: { kind: 'Name', value: this.name },
2172
+ kind: graphql_1.Kind.VARIABLE,
2173
+ name: { kind: graphql_1.Kind.NAME, value: this.name },
2114
2174
  };
2115
2175
  }
2116
2176
  toString() {
@@ -2158,12 +2218,13 @@ class VariableDefinition extends DirectiveTargetElement {
2158
2218
  this.defaultValue = defaultValue;
2159
2219
  }
2160
2220
  toVariableDefinitionNode() {
2221
+ const ast = (0, values_1.valueToAST)(this.defaultValue, this.type);
2161
2222
  return {
2162
- kind: 'VariableDefinition',
2223
+ kind: graphql_1.Kind.VARIABLE_DEFINITION,
2163
2224
  variable: this.variable.toVariableNode(),
2164
2225
  type: typeToAST(this.type),
2165
- defaultValue: (0, values_1.valueToAST)(this.defaultValue, this.type),
2166
- directives: this.appliedDirectivesToDirectiveNodes()
2226
+ defaultValue: (ast !== undefined) ? (0, values_1.valueNodeToConstValueNode)(ast) : undefined,
2227
+ directives: this.appliedDirectivesToDirectiveNodes(),
2167
2228
  };
2168
2229
  }
2169
2230
  toString() {