@graphql-inspector/action 3.1.0 → 3.2.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 (3) hide show
  1. package/index.js +4531 -84
  2. package/index.mjs +4531 -84
  3. package/package.json +1 -1
package/index.mjs CHANGED
@@ -1969,6 +1969,18 @@ function readName(lexer, start) {
1969
1969
  );
1970
1970
  }
1971
1971
 
1972
+ /**
1973
+ * Configuration options to control parser behavior
1974
+ */
1975
+
1976
+ /**
1977
+ * Given a GraphQL source, parses it into a Document.
1978
+ * Throws GraphQLError if a syntax error is encountered.
1979
+ */
1980
+ function parse(source, options) {
1981
+ const parser = new Parser(source, options);
1982
+ return parser.parseDocument();
1983
+ }
1972
1984
  /**
1973
1985
  * Given a string containing a GraphQL value (ex. `[42]`), parse the AST for
1974
1986
  * that value.
@@ -3688,6 +3700,85 @@ function visit(root, visitor, visitorKeys = QueryDocumentKeys) {
3688
3700
 
3689
3701
  return newRoot;
3690
3702
  }
3703
+ /**
3704
+ * Creates a new visitor instance which delegates to many visitors to run in
3705
+ * parallel. Each visitor will be visited for each node before moving on.
3706
+ *
3707
+ * If a prior visitor edits a node, no following visitors will see that node.
3708
+ */
3709
+
3710
+ function visitInParallel(visitors) {
3711
+ const skipping = new Array(visitors.length).fill(null);
3712
+ const mergedVisitor = Object.create(null);
3713
+
3714
+ for (const kind of Object.values(Kind)) {
3715
+ let hasVisitor = false;
3716
+ const enterList = new Array(visitors.length).fill(undefined);
3717
+ const leaveList = new Array(visitors.length).fill(undefined);
3718
+
3719
+ for (let i = 0; i < visitors.length; ++i) {
3720
+ const { enter, leave } = getEnterLeaveForKind(visitors[i], kind);
3721
+ hasVisitor || (hasVisitor = enter != null || leave != null);
3722
+ enterList[i] = enter;
3723
+ leaveList[i] = leave;
3724
+ }
3725
+
3726
+ if (!hasVisitor) {
3727
+ continue;
3728
+ }
3729
+
3730
+ const mergedEnterLeave = {
3731
+ enter(...args) {
3732
+ const node = args[0];
3733
+
3734
+ for (let i = 0; i < visitors.length; i++) {
3735
+ if (skipping[i] === null) {
3736
+ var _enterList$i;
3737
+
3738
+ const result =
3739
+ (_enterList$i = enterList[i]) === null || _enterList$i === void 0
3740
+ ? void 0
3741
+ : _enterList$i.apply(visitors[i], args);
3742
+
3743
+ if (result === false) {
3744
+ skipping[i] = node;
3745
+ } else if (result === BREAK) {
3746
+ skipping[i] = BREAK;
3747
+ } else if (result !== undefined) {
3748
+ return result;
3749
+ }
3750
+ }
3751
+ }
3752
+ },
3753
+
3754
+ leave(...args) {
3755
+ const node = args[0];
3756
+
3757
+ for (let i = 0; i < visitors.length; i++) {
3758
+ if (skipping[i] === null) {
3759
+ var _leaveList$i;
3760
+
3761
+ const result =
3762
+ (_leaveList$i = leaveList[i]) === null || _leaveList$i === void 0
3763
+ ? void 0
3764
+ : _leaveList$i.apply(visitors[i], args);
3765
+
3766
+ if (result === BREAK) {
3767
+ skipping[i] = BREAK;
3768
+ } else if (result !== undefined && result !== false) {
3769
+ return result;
3770
+ }
3771
+ } else if (skipping[i] === node) {
3772
+ skipping[i] = null;
3773
+ }
3774
+ }
3775
+ },
3776
+ };
3777
+ mergedVisitor[kind] = mergedEnterLeave;
3778
+ }
3779
+
3780
+ return mergedVisitor;
3781
+ }
3691
3782
  /**
3692
3783
  * Given a visitor instance and a node kind, return EnterLeaveVisitor for that kind.
3693
3784
  */
@@ -4744,6 +4835,13 @@ function isLeafType(type) {
4744
4835
  * These types may describe the parent context of a selection set.
4745
4836
  */
4746
4837
 
4838
+ function isCompositeType(type) {
4839
+ return isObjectType(type) || isInterfaceType(type) || isUnionType(type);
4840
+ }
4841
+ /**
4842
+ * These types may describe the parent context of a selection set.
4843
+ */
4844
+
4747
4845
  function isAbstractType(type) {
4748
4846
  return isInterfaceType(type) || isUnionType(type);
4749
4847
  }
@@ -4851,6 +4949,11 @@ function assertNullableType(type) {
4851
4949
 
4852
4950
  return type;
4853
4951
  }
4952
+ function getNullableType(type) {
4953
+ if (type) {
4954
+ return isNonNullType(type) ? type.ofType : type;
4955
+ }
4956
+ }
4854
4957
  function getNamedType(type) {
4855
4958
  if (type) {
4856
4959
  let unwrappedType = type;
@@ -5212,6 +5315,9 @@ function argsToArgsConfig(args) {
5212
5315
  }),
5213
5316
  );
5214
5317
  }
5318
+ function isRequiredArgument(arg) {
5319
+ return isNonNullType(arg.type) && arg.defaultValue === undefined;
5320
+ }
5215
5321
 
5216
5322
  /**
5217
5323
  * Interface Type Definition
@@ -5669,6 +5775,90 @@ function defineInputFieldMap(config) {
5669
5775
  });
5670
5776
  }
5671
5777
 
5778
+ function isRequiredInputField(field) {
5779
+ return isNonNullType(field.type) && field.defaultValue === undefined;
5780
+ }
5781
+
5782
+ /**
5783
+ * Provided a type and a super type, return true if the first type is either
5784
+ * equal or a subset of the second super type (covariant).
5785
+ */
5786
+
5787
+ function isTypeSubTypeOf(schema, maybeSubType, superType) {
5788
+ // Equivalent type is a valid subtype
5789
+ if (maybeSubType === superType) {
5790
+ return true;
5791
+ } // If superType is non-null, maybeSubType must also be non-null.
5792
+
5793
+ if (isNonNullType(superType)) {
5794
+ if (isNonNullType(maybeSubType)) {
5795
+ return isTypeSubTypeOf(schema, maybeSubType.ofType, superType.ofType);
5796
+ }
5797
+
5798
+ return false;
5799
+ }
5800
+
5801
+ if (isNonNullType(maybeSubType)) {
5802
+ // If superType is nullable, maybeSubType may be non-null or nullable.
5803
+ return isTypeSubTypeOf(schema, maybeSubType.ofType, superType);
5804
+ } // If superType type is a list, maybeSubType type must also be a list.
5805
+
5806
+ if (isListType(superType)) {
5807
+ if (isListType(maybeSubType)) {
5808
+ return isTypeSubTypeOf(schema, maybeSubType.ofType, superType.ofType);
5809
+ }
5810
+
5811
+ return false;
5812
+ }
5813
+
5814
+ if (isListType(maybeSubType)) {
5815
+ // If superType is not a list, maybeSubType must also be not a list.
5816
+ return false;
5817
+ } // If superType type is an abstract type, check if it is super type of maybeSubType.
5818
+ // Otherwise, the child type is not a valid subtype of the parent type.
5819
+
5820
+ return (
5821
+ isAbstractType(superType) &&
5822
+ (isInterfaceType(maybeSubType) || isObjectType(maybeSubType)) &&
5823
+ schema.isSubType(superType, maybeSubType)
5824
+ );
5825
+ }
5826
+ /**
5827
+ * Provided two composite types, determine if they "overlap". Two composite
5828
+ * types overlap when the Sets of possible concrete types for each intersect.
5829
+ *
5830
+ * This is often used to determine if a fragment of a given type could possibly
5831
+ * be visited in a context of another type.
5832
+ *
5833
+ * This function is commutative.
5834
+ */
5835
+
5836
+ function doTypesOverlap(schema, typeA, typeB) {
5837
+ // Equivalent types overlap
5838
+ if (typeA === typeB) {
5839
+ return true;
5840
+ }
5841
+
5842
+ if (isAbstractType(typeA)) {
5843
+ if (isAbstractType(typeB)) {
5844
+ // If both types are abstract, then determine if there is any intersection
5845
+ // between possible concrete types of each.
5846
+ return schema
5847
+ .getPossibleTypes(typeA)
5848
+ .some((type) => schema.isSubType(typeB, type));
5849
+ } // Determine if the latter type is a possible concrete type of the former.
5850
+
5851
+ return schema.isSubType(typeA, typeB);
5852
+ }
5853
+
5854
+ if (isAbstractType(typeB)) {
5855
+ // Determine if the former type is a possible concrete type of the latter.
5856
+ return schema.isSubType(typeB, typeA);
5857
+ } // Otherwise the types do not overlap.
5858
+
5859
+ return false;
5860
+ }
5861
+
5672
5862
  /**
5673
5863
  * Returns true if the provided object is an Object (i.e. not a string literal)
5674
5864
  * and implements the Iterator protocol.
@@ -7195,6 +7385,166 @@ function collectReferencedTypes(type, typeSet) {
7195
7385
  return typeSet;
7196
7386
  }
7197
7387
 
7388
+ /**
7389
+ * Given a Schema and an AST node describing a type, return a GraphQLType
7390
+ * definition which applies to that type. For example, if provided the parsed
7391
+ * AST node for `[User]`, a GraphQLList instance will be returned, containing
7392
+ * the type called "User" found in the schema. If a type called "User" is not
7393
+ * found in the schema, then undefined will be returned.
7394
+ */
7395
+
7396
+ function typeFromAST(schema, typeNode) {
7397
+ let innerType;
7398
+
7399
+ if (typeNode.kind === Kind.LIST_TYPE) {
7400
+ innerType = typeFromAST(schema, typeNode.type);
7401
+ return innerType && new GraphQLList(innerType);
7402
+ }
7403
+
7404
+ if (typeNode.kind === Kind.NON_NULL_TYPE) {
7405
+ innerType = typeFromAST(schema, typeNode.type);
7406
+ return innerType && new GraphQLNonNull(innerType);
7407
+ } // istanbul ignore else (See: 'https://github.com/graphql/graphql-js/issues/2618')
7408
+
7409
+ if (typeNode.kind === Kind.NAMED_TYPE) {
7410
+ return schema.getType(typeNode.name.value);
7411
+ } // istanbul ignore next (Not reachable. All possible type nodes have been considered)
7412
+
7413
+ invariant(false, 'Unexpected type node: ' + inspect(typeNode));
7414
+ }
7415
+
7416
+ function isExecutableDefinitionNode(node) {
7417
+ return (
7418
+ node.kind === Kind.OPERATION_DEFINITION ||
7419
+ node.kind === Kind.FRAGMENT_DEFINITION
7420
+ );
7421
+ }
7422
+ function isTypeSystemDefinitionNode(node) {
7423
+ return (
7424
+ node.kind === Kind.SCHEMA_DEFINITION ||
7425
+ isTypeDefinitionNode(node) ||
7426
+ node.kind === Kind.DIRECTIVE_DEFINITION
7427
+ );
7428
+ }
7429
+ function isTypeDefinitionNode(node) {
7430
+ return (
7431
+ node.kind === Kind.SCALAR_TYPE_DEFINITION ||
7432
+ node.kind === Kind.OBJECT_TYPE_DEFINITION ||
7433
+ node.kind === Kind.INTERFACE_TYPE_DEFINITION ||
7434
+ node.kind === Kind.UNION_TYPE_DEFINITION ||
7435
+ node.kind === Kind.ENUM_TYPE_DEFINITION ||
7436
+ node.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION
7437
+ );
7438
+ }
7439
+ function isTypeSystemExtensionNode(node) {
7440
+ return node.kind === Kind.SCHEMA_EXTENSION || isTypeExtensionNode(node);
7441
+ }
7442
+ function isTypeExtensionNode(node) {
7443
+ return (
7444
+ node.kind === Kind.SCALAR_TYPE_EXTENSION ||
7445
+ node.kind === Kind.OBJECT_TYPE_EXTENSION ||
7446
+ node.kind === Kind.INTERFACE_TYPE_EXTENSION ||
7447
+ node.kind === Kind.UNION_TYPE_EXTENSION ||
7448
+ node.kind === Kind.ENUM_TYPE_EXTENSION ||
7449
+ node.kind === Kind.INPUT_OBJECT_TYPE_EXTENSION
7450
+ );
7451
+ }
7452
+
7453
+ /**
7454
+ * Executable definitions
7455
+ *
7456
+ * A GraphQL document is only valid for execution if all definitions are either
7457
+ * operation or fragment definitions.
7458
+ *
7459
+ * See https://spec.graphql.org/draft/#sec-Executable-Definitions
7460
+ */
7461
+ function ExecutableDefinitionsRule(context) {
7462
+ return {
7463
+ Document(node) {
7464
+ for (const definition of node.definitions) {
7465
+ if (!isExecutableDefinitionNode(definition)) {
7466
+ const defName =
7467
+ definition.kind === Kind.SCHEMA_DEFINITION ||
7468
+ definition.kind === Kind.SCHEMA_EXTENSION
7469
+ ? 'schema'
7470
+ : '"' + definition.name.value + '"';
7471
+ context.reportError(
7472
+ new GraphQLError(
7473
+ `The ${defName} definition is not executable.`,
7474
+ definition,
7475
+ ),
7476
+ );
7477
+ }
7478
+ }
7479
+
7480
+ return false;
7481
+ },
7482
+ };
7483
+ }
7484
+
7485
+ /**
7486
+ * Unique operation names
7487
+ *
7488
+ * A GraphQL document is only valid if all defined operations have unique names.
7489
+ *
7490
+ * See https://spec.graphql.org/draft/#sec-Operation-Name-Uniqueness
7491
+ */
7492
+ function UniqueOperationNamesRule(context) {
7493
+ const knownOperationNames = Object.create(null);
7494
+ return {
7495
+ OperationDefinition(node) {
7496
+ const operationName = node.name;
7497
+
7498
+ if (operationName) {
7499
+ if (knownOperationNames[operationName.value]) {
7500
+ context.reportError(
7501
+ new GraphQLError(
7502
+ `There can be only one operation named "${operationName.value}".`,
7503
+ [knownOperationNames[operationName.value], operationName],
7504
+ ),
7505
+ );
7506
+ } else {
7507
+ knownOperationNames[operationName.value] = operationName;
7508
+ }
7509
+ }
7510
+
7511
+ return false;
7512
+ },
7513
+
7514
+ FragmentDefinition: () => false,
7515
+ };
7516
+ }
7517
+
7518
+ /**
7519
+ * Lone anonymous operation
7520
+ *
7521
+ * A GraphQL document is only valid if when it contains an anonymous operation
7522
+ * (the query short-hand) that it contains only that one operation definition.
7523
+ *
7524
+ * See https://spec.graphql.org/draft/#sec-Lone-Anonymous-Operation
7525
+ */
7526
+ function LoneAnonymousOperationRule(context) {
7527
+ let operationCount = 0;
7528
+ return {
7529
+ Document(node) {
7530
+ operationCount = node.definitions.filter(
7531
+ (definition) => definition.kind === Kind.OPERATION_DEFINITION,
7532
+ ).length;
7533
+ },
7534
+
7535
+ OperationDefinition(node) {
7536
+ if (!node.name && operationCount > 1) {
7537
+ context.reportError(
7538
+ new GraphQLError(
7539
+ 'This anonymous operation must be the only defined operation.',
7540
+ node,
7541
+ ),
7542
+ );
7543
+ }
7544
+ },
7545
+ };
7546
+ }
7547
+
7198
7548
  /**
7199
7549
  * Produces a JavaScript value given a GraphQL Value AST.
7200
7550
  *
@@ -7356,109 +7706,3397 @@ function isMissingVariable(valueNode, variables) {
7356
7706
  }
7357
7707
 
7358
7708
  /**
7359
- * Build a GraphQLSchema for use by client tools.
7709
+ * Prepares an object map of argument values given a list of argument
7710
+ * definitions and list of argument AST nodes.
7360
7711
  *
7361
- * Given the result of a client running the introspection query, creates and
7362
- * returns a GraphQLSchema instance which can be then used with all graphql-js
7363
- * tools, but cannot be used to execute a query, as introspection does not
7364
- * represent the "resolver", "parse" or "serialize" functions or any other
7365
- * server-internal mechanisms.
7712
+ * Note: The returned value is a plain Object with a prototype, since it is
7713
+ * exposed to user code. Care should be taken to not pull values from the
7714
+ * Object prototype.
7366
7715
  *
7367
- * This function expects a complete introspection result. Don't forget to check
7368
- * the "errors" field of a server response before calling this function.
7716
+ * @internal
7369
7717
  */
7370
7718
 
7371
- function buildClientSchema(introspection, options) {
7372
- (isObjectLike(introspection) && isObjectLike(introspection.__schema)) ||
7373
- devAssert(
7374
- false,
7375
- `Invalid or incomplete introspection result. Ensure that you are passing "data" property of introspection response and no "errors" was returned alongside: ${inspect(
7376
- introspection,
7377
- )}.`,
7378
- ); // Get the schema from the introspection result.
7719
+ function getArgumentValues(def, node, variableValues) {
7720
+ var _node$arguments;
7379
7721
 
7380
- const schemaIntrospection = introspection.__schema; // Iterate through all types, getting the type definition for each.
7722
+ const coercedValues = {}; // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
7381
7723
 
7382
- const typeMap = keyValMap(
7383
- schemaIntrospection.types,
7384
- (typeIntrospection) => typeIntrospection.name,
7385
- (typeIntrospection) => buildType(typeIntrospection),
7386
- ); // Include standard types only if they are used.
7724
+ const argumentNodes =
7725
+ (_node$arguments = node.arguments) !== null && _node$arguments !== void 0
7726
+ ? _node$arguments
7727
+ : [];
7728
+ const argNodeMap = keyMap(argumentNodes, (arg) => arg.name.value);
7729
+
7730
+ for (const argDef of def.args) {
7731
+ const name = argDef.name;
7732
+ const argType = argDef.type;
7733
+ const argumentNode = argNodeMap[name];
7734
+
7735
+ if (!argumentNode) {
7736
+ if (argDef.defaultValue !== undefined) {
7737
+ coercedValues[name] = argDef.defaultValue;
7738
+ } else if (isNonNullType(argType)) {
7739
+ throw new GraphQLError(
7740
+ `Argument "${name}" of required type "${inspect(argType)}" ` +
7741
+ 'was not provided.',
7742
+ node,
7743
+ );
7744
+ }
7387
7745
 
7388
- for (const stdType of [...specifiedScalarTypes, ...introspectionTypes]) {
7389
- if (typeMap[stdType.name]) {
7390
- typeMap[stdType.name] = stdType;
7746
+ continue;
7391
7747
  }
7392
- } // Get the root Query, Mutation, and Subscription types.
7393
-
7394
- const queryType = schemaIntrospection.queryType
7395
- ? getObjectType(schemaIntrospection.queryType)
7396
- : null;
7397
- const mutationType = schemaIntrospection.mutationType
7398
- ? getObjectType(schemaIntrospection.mutationType)
7399
- : null;
7400
- const subscriptionType = schemaIntrospection.subscriptionType
7401
- ? getObjectType(schemaIntrospection.subscriptionType)
7402
- : null; // Get the directives supported by Introspection, assuming empty-set if
7403
- // directives were not queried for.
7404
7748
 
7405
- const directives = schemaIntrospection.directives
7406
- ? schemaIntrospection.directives.map(buildDirective)
7407
- : []; // Then produce and return a Schema with these types.
7749
+ const valueNode = argumentNode.value;
7750
+ let isNull = valueNode.kind === Kind.NULL;
7408
7751
 
7409
- return new GraphQLSchema({
7410
- description: schemaIntrospection.description,
7411
- query: queryType,
7412
- mutation: mutationType,
7413
- subscription: subscriptionType,
7414
- types: Object.values(typeMap),
7415
- directives,
7416
- assumeValid:
7417
- options === null || options === void 0 ? void 0 : options.assumeValid,
7418
- }); // Given a type reference in introspection, return the GraphQLType instance.
7419
- // preferring cached instances before building new instances.
7752
+ if (valueNode.kind === Kind.VARIABLE) {
7753
+ const variableName = valueNode.name.value;
7420
7754
 
7421
- function getType(typeRef) {
7422
- if (typeRef.kind === TypeKind.LIST) {
7423
- const itemRef = typeRef.ofType;
7755
+ if (
7756
+ variableValues == null ||
7757
+ !hasOwnProperty(variableValues, variableName)
7758
+ ) {
7759
+ if (argDef.defaultValue !== undefined) {
7760
+ coercedValues[name] = argDef.defaultValue;
7761
+ } else if (isNonNullType(argType)) {
7762
+ throw new GraphQLError(
7763
+ `Argument "${name}" of required type "${inspect(argType)}" ` +
7764
+ `was provided the variable "$${variableName}" which was not provided a runtime value.`,
7765
+ valueNode,
7766
+ );
7767
+ }
7424
7768
 
7425
- if (!itemRef) {
7426
- throw new Error('Decorated type deeper than introspection query.');
7769
+ continue;
7427
7770
  }
7428
7771
 
7429
- return new GraphQLList(getType(itemRef));
7772
+ isNull = variableValues[variableName] == null;
7430
7773
  }
7431
7774
 
7432
- if (typeRef.kind === TypeKind.NON_NULL) {
7433
- const nullableRef = typeRef.ofType;
7775
+ if (isNull && isNonNullType(argType)) {
7776
+ throw new GraphQLError(
7777
+ `Argument "${name}" of non-null type "${inspect(argType)}" ` +
7778
+ 'must not be null.',
7779
+ valueNode,
7780
+ );
7781
+ }
7434
7782
 
7435
- if (!nullableRef) {
7436
- throw new Error('Decorated type deeper than introspection query.');
7437
- }
7783
+ const coercedValue = valueFromAST(valueNode, argType, variableValues);
7438
7784
 
7439
- const nullableType = getType(nullableRef);
7440
- return new GraphQLNonNull(assertNullableType(nullableType));
7785
+ if (coercedValue === undefined) {
7786
+ // Note: ValuesOfCorrectTypeRule validation should catch this before
7787
+ // execution. This is a runtime check to ensure execution does not
7788
+ // continue with an invalid argument value.
7789
+ throw new GraphQLError(
7790
+ `Argument "${name}" has invalid value ${print(valueNode)}.`,
7791
+ valueNode,
7792
+ );
7441
7793
  }
7442
7794
 
7443
- return getNamedType(typeRef);
7795
+ coercedValues[name] = coercedValue;
7444
7796
  }
7445
7797
 
7446
- function getNamedType(typeRef) {
7447
- const typeName = typeRef.name;
7448
-
7449
- if (!typeName) {
7450
- throw new Error(`Unknown type reference: ${inspect(typeRef)}.`);
7451
- }
7798
+ return coercedValues;
7799
+ }
7800
+ /**
7801
+ * Prepares an object map of argument values given a directive definition
7802
+ * and a AST node which may contain directives. Optionally also accepts a map
7803
+ * of variable values.
7804
+ *
7805
+ * If the directive does not exist on the node, returns undefined.
7806
+ *
7807
+ * Note: The returned value is a plain Object with a prototype, since it is
7808
+ * exposed to user code. Care should be taken to not pull values from the
7809
+ * Object prototype.
7810
+ */
7452
7811
 
7453
- const type = typeMap[typeName];
7812
+ function getDirectiveValues(directiveDef, node, variableValues) {
7813
+ var _node$directives;
7454
7814
 
7455
- if (!type) {
7456
- throw new Error(
7457
- `Invalid or incomplete schema, unknown type: ${typeName}. Ensure that a full introspection query is used in order to build a client schema.`,
7458
- );
7459
- }
7815
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
7816
+ const directiveNode =
7817
+ (_node$directives = node.directives) === null || _node$directives === void 0
7818
+ ? void 0
7819
+ : _node$directives.find(
7820
+ (directive) => directive.name.value === directiveDef.name,
7821
+ );
7460
7822
 
7461
- return type;
7823
+ if (directiveNode) {
7824
+ return getArgumentValues(directiveDef, directiveNode, variableValues);
7825
+ }
7826
+ }
7827
+
7828
+ function hasOwnProperty(obj, prop) {
7829
+ return Object.prototype.hasOwnProperty.call(obj, prop);
7830
+ }
7831
+
7832
+ /**
7833
+ * Given a selectionSet, collect all of the fields and returns it at the end.
7834
+ *
7835
+ * CollectFields requires the "runtime type" of an object. For a field which
7836
+ * returns an Interface or Union type, the "runtime type" will be the actual
7837
+ * Object type returned by that field.
7838
+ *
7839
+ * @internal
7840
+ */
7841
+
7842
+ function collectFields(
7843
+ schema,
7844
+ fragments,
7845
+ variableValues,
7846
+ runtimeType,
7847
+ selectionSet,
7848
+ ) {
7849
+ const fields = new Map();
7850
+ collectFieldsImpl(
7851
+ schema,
7852
+ fragments,
7853
+ variableValues,
7854
+ runtimeType,
7855
+ selectionSet,
7856
+ fields,
7857
+ new Set(),
7858
+ );
7859
+ return fields;
7860
+ }
7861
+
7862
+ function collectFieldsImpl(
7863
+ schema,
7864
+ fragments,
7865
+ variableValues,
7866
+ runtimeType,
7867
+ selectionSet,
7868
+ fields,
7869
+ visitedFragmentNames,
7870
+ ) {
7871
+ for (const selection of selectionSet.selections) {
7872
+ switch (selection.kind) {
7873
+ case Kind.FIELD: {
7874
+ if (!shouldIncludeNode(variableValues, selection)) {
7875
+ continue;
7876
+ }
7877
+
7878
+ const name = getFieldEntryKey(selection);
7879
+ const fieldList = fields.get(name);
7880
+
7881
+ if (fieldList !== undefined) {
7882
+ fieldList.push(selection);
7883
+ } else {
7884
+ fields.set(name, [selection]);
7885
+ }
7886
+
7887
+ break;
7888
+ }
7889
+
7890
+ case Kind.INLINE_FRAGMENT: {
7891
+ if (
7892
+ !shouldIncludeNode(variableValues, selection) ||
7893
+ !doesFragmentConditionMatch(schema, selection, runtimeType)
7894
+ ) {
7895
+ continue;
7896
+ }
7897
+
7898
+ collectFieldsImpl(
7899
+ schema,
7900
+ fragments,
7901
+ variableValues,
7902
+ runtimeType,
7903
+ selection.selectionSet,
7904
+ fields,
7905
+ visitedFragmentNames,
7906
+ );
7907
+ break;
7908
+ }
7909
+
7910
+ case Kind.FRAGMENT_SPREAD: {
7911
+ const fragName = selection.name.value;
7912
+
7913
+ if (
7914
+ visitedFragmentNames.has(fragName) ||
7915
+ !shouldIncludeNode(variableValues, selection)
7916
+ ) {
7917
+ continue;
7918
+ }
7919
+
7920
+ visitedFragmentNames.add(fragName);
7921
+ const fragment = fragments[fragName];
7922
+
7923
+ if (
7924
+ !fragment ||
7925
+ !doesFragmentConditionMatch(schema, fragment, runtimeType)
7926
+ ) {
7927
+ continue;
7928
+ }
7929
+
7930
+ collectFieldsImpl(
7931
+ schema,
7932
+ fragments,
7933
+ variableValues,
7934
+ runtimeType,
7935
+ fragment.selectionSet,
7936
+ fields,
7937
+ visitedFragmentNames,
7938
+ );
7939
+ break;
7940
+ }
7941
+ }
7942
+ }
7943
+ }
7944
+ /**
7945
+ * Determines if a field should be included based on the `@include` and `@skip`
7946
+ * directives, where `@skip` has higher precedence than `@include`.
7947
+ */
7948
+
7949
+ function shouldIncludeNode(variableValues, node) {
7950
+ const skip = getDirectiveValues(GraphQLSkipDirective, node, variableValues);
7951
+
7952
+ if ((skip === null || skip === void 0 ? void 0 : skip.if) === true) {
7953
+ return false;
7954
+ }
7955
+
7956
+ const include = getDirectiveValues(
7957
+ GraphQLIncludeDirective,
7958
+ node,
7959
+ variableValues,
7960
+ );
7961
+
7962
+ if (
7963
+ (include === null || include === void 0 ? void 0 : include.if) === false
7964
+ ) {
7965
+ return false;
7966
+ }
7967
+
7968
+ return true;
7969
+ }
7970
+ /**
7971
+ * Determines if a fragment is applicable to the given type.
7972
+ */
7973
+
7974
+ function doesFragmentConditionMatch(schema, fragment, type) {
7975
+ const typeConditionNode = fragment.typeCondition;
7976
+
7977
+ if (!typeConditionNode) {
7978
+ return true;
7979
+ }
7980
+
7981
+ const conditionalType = typeFromAST(schema, typeConditionNode);
7982
+
7983
+ if (conditionalType === type) {
7984
+ return true;
7985
+ }
7986
+
7987
+ if (isAbstractType(conditionalType)) {
7988
+ return schema.isSubType(conditionalType, type);
7989
+ }
7990
+
7991
+ return false;
7992
+ }
7993
+ /**
7994
+ * Implements the logic to compute the key of a given field's entry
7995
+ */
7996
+
7997
+ function getFieldEntryKey(node) {
7998
+ return node.alias ? node.alias.value : node.name.value;
7999
+ }
8000
+
8001
+ /**
8002
+ * Subscriptions must only include a non-introspection field.
8003
+ *
8004
+ * A GraphQL subscription is valid only if it contains a single root field and
8005
+ * that root field is not an introspection field.
8006
+ *
8007
+ * See https://spec.graphql.org/draft/#sec-Single-root-field
8008
+ */
8009
+ function SingleFieldSubscriptionsRule(context) {
8010
+ return {
8011
+ OperationDefinition(node) {
8012
+ if (node.operation === 'subscription') {
8013
+ const schema = context.getSchema();
8014
+ const subscriptionType = schema.getSubscriptionType();
8015
+
8016
+ if (subscriptionType) {
8017
+ const operationName = node.name ? node.name.value : null;
8018
+ const variableValues = Object.create(null);
8019
+ const document = context.getDocument();
8020
+ const fragments = Object.create(null);
8021
+
8022
+ for (const definition of document.definitions) {
8023
+ if (definition.kind === Kind.FRAGMENT_DEFINITION) {
8024
+ fragments[definition.name.value] = definition;
8025
+ }
8026
+ }
8027
+
8028
+ const fields = collectFields(
8029
+ schema,
8030
+ fragments,
8031
+ variableValues,
8032
+ subscriptionType,
8033
+ node.selectionSet,
8034
+ );
8035
+
8036
+ if (fields.size > 1) {
8037
+ const fieldSelectionLists = [...fields.values()];
8038
+ const extraFieldSelectionLists = fieldSelectionLists.slice(1);
8039
+ const extraFieldSelections = extraFieldSelectionLists.flat();
8040
+ context.reportError(
8041
+ new GraphQLError(
8042
+ operationName != null
8043
+ ? `Subscription "${operationName}" must select only one top level field.`
8044
+ : 'Anonymous Subscription must select only one top level field.',
8045
+ extraFieldSelections,
8046
+ ),
8047
+ );
8048
+ }
8049
+
8050
+ for (const fieldNodes of fields.values()) {
8051
+ const field = fieldNodes[0];
8052
+ const fieldName = field.name.value;
8053
+
8054
+ if (fieldName.startsWith('__')) {
8055
+ context.reportError(
8056
+ new GraphQLError(
8057
+ operationName != null
8058
+ ? `Subscription "${operationName}" must not select an introspection top level field.`
8059
+ : 'Anonymous Subscription must not select an introspection top level field.',
8060
+ fieldNodes,
8061
+ ),
8062
+ );
8063
+ }
8064
+ }
8065
+ }
8066
+ }
8067
+ },
8068
+ };
8069
+ }
8070
+
8071
+ /**
8072
+ * Known type names
8073
+ *
8074
+ * A GraphQL document is only valid if referenced types (specifically
8075
+ * variable definitions and fragment conditions) are defined by the type schema.
8076
+ *
8077
+ * See https://spec.graphql.org/draft/#sec-Fragment-Spread-Type-Existence
8078
+ */
8079
+ function KnownTypeNamesRule(context) {
8080
+ const schema = context.getSchema();
8081
+ const existingTypesMap = schema ? schema.getTypeMap() : Object.create(null);
8082
+ const definedTypes = Object.create(null);
8083
+
8084
+ for (const def of context.getDocument().definitions) {
8085
+ if (isTypeDefinitionNode(def)) {
8086
+ definedTypes[def.name.value] = true;
8087
+ }
8088
+ }
8089
+
8090
+ const typeNames = [
8091
+ ...Object.keys(existingTypesMap),
8092
+ ...Object.keys(definedTypes),
8093
+ ];
8094
+ return {
8095
+ NamedType(node, _1, parent, _2, ancestors) {
8096
+ const typeName = node.name.value;
8097
+
8098
+ if (!existingTypesMap[typeName] && !definedTypes[typeName]) {
8099
+ var _ancestors$;
8100
+
8101
+ const definitionNode =
8102
+ (_ancestors$ = ancestors[2]) !== null && _ancestors$ !== void 0
8103
+ ? _ancestors$
8104
+ : parent;
8105
+ const isSDL = definitionNode != null && isSDLNode(definitionNode);
8106
+
8107
+ if (isSDL && standardTypeNames.includes(typeName)) {
8108
+ return;
8109
+ }
8110
+
8111
+ const suggestedTypes = suggestionList(
8112
+ typeName,
8113
+ isSDL ? standardTypeNames.concat(typeNames) : typeNames,
8114
+ );
8115
+ context.reportError(
8116
+ new GraphQLError(
8117
+ `Unknown type "${typeName}".` + didYouMean(suggestedTypes),
8118
+ node,
8119
+ ),
8120
+ );
8121
+ }
8122
+ },
8123
+ };
8124
+ }
8125
+ const standardTypeNames = [...specifiedScalarTypes, ...introspectionTypes].map(
8126
+ (type) => type.name,
8127
+ );
8128
+
8129
+ function isSDLNode(value) {
8130
+ return (
8131
+ 'kind' in value &&
8132
+ (isTypeSystemDefinitionNode(value) || isTypeSystemExtensionNode(value))
8133
+ );
8134
+ }
8135
+
8136
+ /**
8137
+ * Fragments on composite type
8138
+ *
8139
+ * Fragments use a type condition to determine if they apply, since fragments
8140
+ * can only be spread into a composite type (object, interface, or union), the
8141
+ * type condition must also be a composite type.
8142
+ *
8143
+ * See https://spec.graphql.org/draft/#sec-Fragments-On-Composite-Types
8144
+ */
8145
+ function FragmentsOnCompositeTypesRule(context) {
8146
+ return {
8147
+ InlineFragment(node) {
8148
+ const typeCondition = node.typeCondition;
8149
+
8150
+ if (typeCondition) {
8151
+ const type = typeFromAST(context.getSchema(), typeCondition);
8152
+
8153
+ if (type && !isCompositeType(type)) {
8154
+ const typeStr = print(typeCondition);
8155
+ context.reportError(
8156
+ new GraphQLError(
8157
+ `Fragment cannot condition on non composite type "${typeStr}".`,
8158
+ typeCondition,
8159
+ ),
8160
+ );
8161
+ }
8162
+ }
8163
+ },
8164
+
8165
+ FragmentDefinition(node) {
8166
+ const type = typeFromAST(context.getSchema(), node.typeCondition);
8167
+
8168
+ if (type && !isCompositeType(type)) {
8169
+ const typeStr = print(node.typeCondition);
8170
+ context.reportError(
8171
+ new GraphQLError(
8172
+ `Fragment "${node.name.value}" cannot condition on non composite type "${typeStr}".`,
8173
+ node.typeCondition,
8174
+ ),
8175
+ );
8176
+ }
8177
+ },
8178
+ };
8179
+ }
8180
+
8181
+ /**
8182
+ * Variables are input types
8183
+ *
8184
+ * A GraphQL operation is only valid if all the variables it defines are of
8185
+ * input types (scalar, enum, or input object).
8186
+ *
8187
+ * See https://spec.graphql.org/draft/#sec-Variables-Are-Input-Types
8188
+ */
8189
+ function VariablesAreInputTypesRule(context) {
8190
+ return {
8191
+ VariableDefinition(node) {
8192
+ const type = typeFromAST(context.getSchema(), node.type);
8193
+
8194
+ if (type !== undefined && !isInputType(type)) {
8195
+ const variableName = node.variable.name.value;
8196
+ const typeName = print(node.type);
8197
+ context.reportError(
8198
+ new GraphQLError(
8199
+ `Variable "$${variableName}" cannot be non-input type "${typeName}".`,
8200
+ node.type,
8201
+ ),
8202
+ );
8203
+ }
8204
+ },
8205
+ };
8206
+ }
8207
+
8208
+ /**
8209
+ * Scalar leafs
8210
+ *
8211
+ * A GraphQL document is valid only if all leaf fields (fields without
8212
+ * sub selections) are of scalar or enum types.
8213
+ */
8214
+ function ScalarLeafsRule(context) {
8215
+ return {
8216
+ Field(node) {
8217
+ const type = context.getType();
8218
+ const selectionSet = node.selectionSet;
8219
+
8220
+ if (type) {
8221
+ if (isLeafType(getNamedType(type))) {
8222
+ if (selectionSet) {
8223
+ const fieldName = node.name.value;
8224
+ const typeStr = inspect(type);
8225
+ context.reportError(
8226
+ new GraphQLError(
8227
+ `Field "${fieldName}" must not have a selection since type "${typeStr}" has no subfields.`,
8228
+ selectionSet,
8229
+ ),
8230
+ );
8231
+ }
8232
+ } else if (!selectionSet) {
8233
+ const fieldName = node.name.value;
8234
+ const typeStr = inspect(type);
8235
+ context.reportError(
8236
+ new GraphQLError(
8237
+ `Field "${fieldName}" of type "${typeStr}" must have a selection of subfields. Did you mean "${fieldName} { ... }"?`,
8238
+ node,
8239
+ ),
8240
+ );
8241
+ }
8242
+ }
8243
+ },
8244
+ };
8245
+ }
8246
+
8247
+ /**
8248
+ * Fields on correct type
8249
+ *
8250
+ * A GraphQL document is only valid if all fields selected are defined by the
8251
+ * parent type, or are an allowed meta field such as __typename.
8252
+ *
8253
+ * See https://spec.graphql.org/draft/#sec-Field-Selections
8254
+ */
8255
+ function FieldsOnCorrectTypeRule(context) {
8256
+ return {
8257
+ Field(node) {
8258
+ const type = context.getParentType();
8259
+
8260
+ if (type) {
8261
+ const fieldDef = context.getFieldDef();
8262
+
8263
+ if (!fieldDef) {
8264
+ // This field doesn't exist, lets look for suggestions.
8265
+ const schema = context.getSchema();
8266
+ const fieldName = node.name.value; // First determine if there are any suggested types to condition on.
8267
+
8268
+ let suggestion = didYouMean(
8269
+ 'to use an inline fragment on',
8270
+ getSuggestedTypeNames(schema, type, fieldName),
8271
+ ); // If there are no suggested types, then perhaps this was a typo?
8272
+
8273
+ if (suggestion === '') {
8274
+ suggestion = didYouMean(getSuggestedFieldNames(type, fieldName));
8275
+ } // Report an error, including helpful suggestions.
8276
+
8277
+ context.reportError(
8278
+ new GraphQLError(
8279
+ `Cannot query field "${fieldName}" on type "${type.name}".` +
8280
+ suggestion,
8281
+ node,
8282
+ ),
8283
+ );
8284
+ }
8285
+ }
8286
+ },
8287
+ };
8288
+ }
8289
+ /**
8290
+ * Go through all of the implementations of type, as well as the interfaces that
8291
+ * they implement. If any of those types include the provided field, suggest them,
8292
+ * sorted by how often the type is referenced.
8293
+ */
8294
+
8295
+ function getSuggestedTypeNames(schema, type, fieldName) {
8296
+ if (!isAbstractType(type)) {
8297
+ // Must be an Object type, which does not have possible fields.
8298
+ return [];
8299
+ }
8300
+
8301
+ const suggestedTypes = new Set();
8302
+ const usageCount = Object.create(null);
8303
+
8304
+ for (const possibleType of schema.getPossibleTypes(type)) {
8305
+ if (!possibleType.getFields()[fieldName]) {
8306
+ continue;
8307
+ } // This object type defines this field.
8308
+
8309
+ suggestedTypes.add(possibleType);
8310
+ usageCount[possibleType.name] = 1;
8311
+
8312
+ for (const possibleInterface of possibleType.getInterfaces()) {
8313
+ var _usageCount$possibleI;
8314
+
8315
+ if (!possibleInterface.getFields()[fieldName]) {
8316
+ continue;
8317
+ } // This interface type defines this field.
8318
+
8319
+ suggestedTypes.add(possibleInterface);
8320
+ usageCount[possibleInterface.name] =
8321
+ ((_usageCount$possibleI = usageCount[possibleInterface.name]) !==
8322
+ null && _usageCount$possibleI !== void 0
8323
+ ? _usageCount$possibleI
8324
+ : 0) + 1;
8325
+ }
8326
+ }
8327
+
8328
+ return [...suggestedTypes]
8329
+ .sort((typeA, typeB) => {
8330
+ // Suggest both interface and object types based on how common they are.
8331
+ const usageCountDiff = usageCount[typeB.name] - usageCount[typeA.name];
8332
+
8333
+ if (usageCountDiff !== 0) {
8334
+ return usageCountDiff;
8335
+ } // Suggest super types first followed by subtypes
8336
+
8337
+ if (isInterfaceType(typeA) && schema.isSubType(typeA, typeB)) {
8338
+ return -1;
8339
+ }
8340
+
8341
+ if (isInterfaceType(typeB) && schema.isSubType(typeB, typeA)) {
8342
+ return 1;
8343
+ }
8344
+
8345
+ return naturalCompare(typeA.name, typeB.name);
8346
+ })
8347
+ .map((x) => x.name);
8348
+ }
8349
+ /**
8350
+ * For the field name provided, determine if there are any similar field names
8351
+ * that may be the result of a typo.
8352
+ */
8353
+
8354
+ function getSuggestedFieldNames(type, fieldName) {
8355
+ if (isObjectType(type) || isInterfaceType(type)) {
8356
+ const possibleFieldNames = Object.keys(type.getFields());
8357
+ return suggestionList(fieldName, possibleFieldNames);
8358
+ } // Otherwise, must be a Union type, which does not define fields.
8359
+
8360
+ return [];
8361
+ }
8362
+
8363
+ /**
8364
+ * Unique fragment names
8365
+ *
8366
+ * A GraphQL document is only valid if all defined fragments have unique names.
8367
+ *
8368
+ * See https://spec.graphql.org/draft/#sec-Fragment-Name-Uniqueness
8369
+ */
8370
+ function UniqueFragmentNamesRule(context) {
8371
+ const knownFragmentNames = Object.create(null);
8372
+ return {
8373
+ OperationDefinition: () => false,
8374
+
8375
+ FragmentDefinition(node) {
8376
+ const fragmentName = node.name.value;
8377
+
8378
+ if (knownFragmentNames[fragmentName]) {
8379
+ context.reportError(
8380
+ new GraphQLError(
8381
+ `There can be only one fragment named "${fragmentName}".`,
8382
+ [knownFragmentNames[fragmentName], node.name],
8383
+ ),
8384
+ );
8385
+ } else {
8386
+ knownFragmentNames[fragmentName] = node.name;
8387
+ }
8388
+
8389
+ return false;
8390
+ },
8391
+ };
8392
+ }
8393
+
8394
+ /**
8395
+ * Known fragment names
8396
+ *
8397
+ * A GraphQL document is only valid if all `...Fragment` fragment spreads refer
8398
+ * to fragments defined in the same document.
8399
+ *
8400
+ * See https://spec.graphql.org/draft/#sec-Fragment-spread-target-defined
8401
+ */
8402
+ function KnownFragmentNamesRule(context) {
8403
+ return {
8404
+ FragmentSpread(node) {
8405
+ const fragmentName = node.name.value;
8406
+ const fragment = context.getFragment(fragmentName);
8407
+
8408
+ if (!fragment) {
8409
+ context.reportError(
8410
+ new GraphQLError(`Unknown fragment "${fragmentName}".`, node.name),
8411
+ );
8412
+ }
8413
+ },
8414
+ };
8415
+ }
8416
+
8417
+ /**
8418
+ * No unused fragments
8419
+ *
8420
+ * A GraphQL document is only valid if all fragment definitions are spread
8421
+ * within operations, or spread within other fragments spread within operations.
8422
+ *
8423
+ * See https://spec.graphql.org/draft/#sec-Fragments-Must-Be-Used
8424
+ */
8425
+ function NoUnusedFragmentsRule(context) {
8426
+ const operationDefs = [];
8427
+ const fragmentDefs = [];
8428
+ return {
8429
+ OperationDefinition(node) {
8430
+ operationDefs.push(node);
8431
+ return false;
8432
+ },
8433
+
8434
+ FragmentDefinition(node) {
8435
+ fragmentDefs.push(node);
8436
+ return false;
8437
+ },
8438
+
8439
+ Document: {
8440
+ leave() {
8441
+ const fragmentNameUsed = Object.create(null);
8442
+
8443
+ for (const operation of operationDefs) {
8444
+ for (const fragment of context.getRecursivelyReferencedFragments(
8445
+ operation,
8446
+ )) {
8447
+ fragmentNameUsed[fragment.name.value] = true;
8448
+ }
8449
+ }
8450
+
8451
+ for (const fragmentDef of fragmentDefs) {
8452
+ const fragName = fragmentDef.name.value;
8453
+
8454
+ if (fragmentNameUsed[fragName] !== true) {
8455
+ context.reportError(
8456
+ new GraphQLError(
8457
+ `Fragment "${fragName}" is never used.`,
8458
+ fragmentDef,
8459
+ ),
8460
+ );
8461
+ }
8462
+ }
8463
+ },
8464
+ },
8465
+ };
8466
+ }
8467
+
8468
+ /**
8469
+ * Possible fragment spread
8470
+ *
8471
+ * A fragment spread is only valid if the type condition could ever possibly
8472
+ * be true: if there is a non-empty intersection of the possible parent types,
8473
+ * and possible types which pass the type condition.
8474
+ */
8475
+ function PossibleFragmentSpreadsRule(context) {
8476
+ return {
8477
+ InlineFragment(node) {
8478
+ const fragType = context.getType();
8479
+ const parentType = context.getParentType();
8480
+
8481
+ if (
8482
+ isCompositeType(fragType) &&
8483
+ isCompositeType(parentType) &&
8484
+ !doTypesOverlap(context.getSchema(), fragType, parentType)
8485
+ ) {
8486
+ const parentTypeStr = inspect(parentType);
8487
+ const fragTypeStr = inspect(fragType);
8488
+ context.reportError(
8489
+ new GraphQLError(
8490
+ `Fragment cannot be spread here as objects of type "${parentTypeStr}" can never be of type "${fragTypeStr}".`,
8491
+ node,
8492
+ ),
8493
+ );
8494
+ }
8495
+ },
8496
+
8497
+ FragmentSpread(node) {
8498
+ const fragName = node.name.value;
8499
+ const fragType = getFragmentType(context, fragName);
8500
+ const parentType = context.getParentType();
8501
+
8502
+ if (
8503
+ fragType &&
8504
+ parentType &&
8505
+ !doTypesOverlap(context.getSchema(), fragType, parentType)
8506
+ ) {
8507
+ const parentTypeStr = inspect(parentType);
8508
+ const fragTypeStr = inspect(fragType);
8509
+ context.reportError(
8510
+ new GraphQLError(
8511
+ `Fragment "${fragName}" cannot be spread here as objects of type "${parentTypeStr}" can never be of type "${fragTypeStr}".`,
8512
+ node,
8513
+ ),
8514
+ );
8515
+ }
8516
+ },
8517
+ };
8518
+ }
8519
+
8520
+ function getFragmentType(context, name) {
8521
+ const frag = context.getFragment(name);
8522
+
8523
+ if (frag) {
8524
+ const type = typeFromAST(context.getSchema(), frag.typeCondition);
8525
+
8526
+ if (isCompositeType(type)) {
8527
+ return type;
8528
+ }
8529
+ }
8530
+ }
8531
+
8532
+ /**
8533
+ * No fragment cycles
8534
+ *
8535
+ * The graph of fragment spreads must not form any cycles including spreading itself.
8536
+ * Otherwise an operation could infinitely spread or infinitely execute on cycles in the underlying data.
8537
+ *
8538
+ * See https://spec.graphql.org/draft/#sec-Fragment-spreads-must-not-form-cycles
8539
+ */
8540
+ function NoFragmentCyclesRule(context) {
8541
+ // Tracks already visited fragments to maintain O(N) and to ensure that cycles
8542
+ // are not redundantly reported.
8543
+ const visitedFrags = Object.create(null); // Array of AST nodes used to produce meaningful errors
8544
+
8545
+ const spreadPath = []; // Position in the spread path
8546
+
8547
+ const spreadPathIndexByName = Object.create(null);
8548
+ return {
8549
+ OperationDefinition: () => false,
8550
+
8551
+ FragmentDefinition(node) {
8552
+ detectCycleRecursive(node);
8553
+ return false;
8554
+ },
8555
+ }; // This does a straight-forward DFS to find cycles.
8556
+ // It does not terminate when a cycle was found but continues to explore
8557
+ // the graph to find all possible cycles.
8558
+
8559
+ function detectCycleRecursive(fragment) {
8560
+ if (visitedFrags[fragment.name.value]) {
8561
+ return;
8562
+ }
8563
+
8564
+ const fragmentName = fragment.name.value;
8565
+ visitedFrags[fragmentName] = true;
8566
+ const spreadNodes = context.getFragmentSpreads(fragment.selectionSet);
8567
+
8568
+ if (spreadNodes.length === 0) {
8569
+ return;
8570
+ }
8571
+
8572
+ spreadPathIndexByName[fragmentName] = spreadPath.length;
8573
+
8574
+ for (const spreadNode of spreadNodes) {
8575
+ const spreadName = spreadNode.name.value;
8576
+ const cycleIndex = spreadPathIndexByName[spreadName];
8577
+ spreadPath.push(spreadNode);
8578
+
8579
+ if (cycleIndex === undefined) {
8580
+ const spreadFragment = context.getFragment(spreadName);
8581
+
8582
+ if (spreadFragment) {
8583
+ detectCycleRecursive(spreadFragment);
8584
+ }
8585
+ } else {
8586
+ const cyclePath = spreadPath.slice(cycleIndex);
8587
+ const viaPath = cyclePath
8588
+ .slice(0, -1)
8589
+ .map((s) => '"' + s.name.value + '"')
8590
+ .join(', ');
8591
+ context.reportError(
8592
+ new GraphQLError(
8593
+ `Cannot spread fragment "${spreadName}" within itself` +
8594
+ (viaPath !== '' ? ` via ${viaPath}.` : '.'),
8595
+ cyclePath,
8596
+ ),
8597
+ );
8598
+ }
8599
+
8600
+ spreadPath.pop();
8601
+ }
8602
+
8603
+ spreadPathIndexByName[fragmentName] = undefined;
8604
+ }
8605
+ }
8606
+
8607
+ /**
8608
+ * Groups array items into a Map, given a function to produce grouping key.
8609
+ */
8610
+ function groupBy(list, keyFn) {
8611
+ const result = new Map();
8612
+
8613
+ for (const item of list) {
8614
+ const key = keyFn(item);
8615
+ const group = result.get(key);
8616
+
8617
+ if (group === undefined) {
8618
+ result.set(key, [item]);
8619
+ } else {
8620
+ group.push(item);
8621
+ }
8622
+ }
8623
+
8624
+ return result;
8625
+ }
8626
+
8627
+ /**
8628
+ * Unique variable names
8629
+ *
8630
+ * A GraphQL operation is only valid if all its variables are uniquely named.
8631
+ */
8632
+ function UniqueVariableNamesRule(context) {
8633
+ return {
8634
+ OperationDefinition(operationNode) {
8635
+ var _operationNode$variab;
8636
+
8637
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
8638
+ const variableDefinitions =
8639
+ (_operationNode$variab = operationNode.variableDefinitions) !== null &&
8640
+ _operationNode$variab !== void 0
8641
+ ? _operationNode$variab
8642
+ : [];
8643
+ const seenVariableDefinitions = groupBy(
8644
+ variableDefinitions,
8645
+ (node) => node.variable.name.value,
8646
+ );
8647
+
8648
+ for (const [variableName, variableNodes] of seenVariableDefinitions) {
8649
+ if (variableNodes.length > 1) {
8650
+ context.reportError(
8651
+ new GraphQLError(
8652
+ `There can be only one variable named "$${variableName}".`,
8653
+ variableNodes.map((node) => node.variable.name),
8654
+ ),
8655
+ );
8656
+ }
8657
+ }
8658
+ },
8659
+ };
8660
+ }
8661
+
8662
+ /**
8663
+ * No undefined variables
8664
+ *
8665
+ * A GraphQL operation is only valid if all variables encountered, both directly
8666
+ * and via fragment spreads, are defined by that operation.
8667
+ *
8668
+ * See https://spec.graphql.org/draft/#sec-All-Variable-Uses-Defined
8669
+ */
8670
+ function NoUndefinedVariablesRule(context) {
8671
+ let variableNameDefined = Object.create(null);
8672
+ return {
8673
+ OperationDefinition: {
8674
+ enter() {
8675
+ variableNameDefined = Object.create(null);
8676
+ },
8677
+
8678
+ leave(operation) {
8679
+ const usages = context.getRecursiveVariableUsages(operation);
8680
+
8681
+ for (const { node } of usages) {
8682
+ const varName = node.name.value;
8683
+
8684
+ if (variableNameDefined[varName] !== true) {
8685
+ context.reportError(
8686
+ new GraphQLError(
8687
+ operation.name
8688
+ ? `Variable "$${varName}" is not defined by operation "${operation.name.value}".`
8689
+ : `Variable "$${varName}" is not defined.`,
8690
+ [node, operation],
8691
+ ),
8692
+ );
8693
+ }
8694
+ }
8695
+ },
8696
+ },
8697
+
8698
+ VariableDefinition(node) {
8699
+ variableNameDefined[node.variable.name.value] = true;
8700
+ },
8701
+ };
8702
+ }
8703
+
8704
+ /**
8705
+ * No unused variables
8706
+ *
8707
+ * A GraphQL operation is only valid if all variables defined by an operation
8708
+ * are used, either directly or within a spread fragment.
8709
+ *
8710
+ * See https://spec.graphql.org/draft/#sec-All-Variables-Used
8711
+ */
8712
+ function NoUnusedVariablesRule(context) {
8713
+ let variableDefs = [];
8714
+ return {
8715
+ OperationDefinition: {
8716
+ enter() {
8717
+ variableDefs = [];
8718
+ },
8719
+
8720
+ leave(operation) {
8721
+ const variableNameUsed = Object.create(null);
8722
+ const usages = context.getRecursiveVariableUsages(operation);
8723
+
8724
+ for (const { node } of usages) {
8725
+ variableNameUsed[node.name.value] = true;
8726
+ }
8727
+
8728
+ for (const variableDef of variableDefs) {
8729
+ const variableName = variableDef.variable.name.value;
8730
+
8731
+ if (variableNameUsed[variableName] !== true) {
8732
+ context.reportError(
8733
+ new GraphQLError(
8734
+ operation.name
8735
+ ? `Variable "$${variableName}" is never used in operation "${operation.name.value}".`
8736
+ : `Variable "$${variableName}" is never used.`,
8737
+ variableDef,
8738
+ ),
8739
+ );
8740
+ }
8741
+ }
8742
+ },
8743
+ },
8744
+
8745
+ VariableDefinition(def) {
8746
+ variableDefs.push(def);
8747
+ },
8748
+ };
8749
+ }
8750
+
8751
+ /**
8752
+ * Known directives
8753
+ *
8754
+ * A GraphQL document is only valid if all `@directives` are known by the
8755
+ * schema and legally positioned.
8756
+ *
8757
+ * See https://spec.graphql.org/draft/#sec-Directives-Are-Defined
8758
+ */
8759
+ function KnownDirectivesRule(context) {
8760
+ const locationsMap = Object.create(null);
8761
+ const schema = context.getSchema();
8762
+ const definedDirectives = schema
8763
+ ? schema.getDirectives()
8764
+ : specifiedDirectives;
8765
+
8766
+ for (const directive of definedDirectives) {
8767
+ locationsMap[directive.name] = directive.locations;
8768
+ }
8769
+
8770
+ const astDefinitions = context.getDocument().definitions;
8771
+
8772
+ for (const def of astDefinitions) {
8773
+ if (def.kind === Kind.DIRECTIVE_DEFINITION) {
8774
+ locationsMap[def.name.value] = def.locations.map((name) => name.value);
8775
+ }
8776
+ }
8777
+
8778
+ return {
8779
+ Directive(node, _key, _parent, _path, ancestors) {
8780
+ const name = node.name.value;
8781
+ const locations = locationsMap[name];
8782
+
8783
+ if (!locations) {
8784
+ context.reportError(
8785
+ new GraphQLError(`Unknown directive "@${name}".`, node),
8786
+ );
8787
+ return;
8788
+ }
8789
+
8790
+ const candidateLocation = getDirectiveLocationForASTPath(ancestors);
8791
+
8792
+ if (candidateLocation && !locations.includes(candidateLocation)) {
8793
+ context.reportError(
8794
+ new GraphQLError(
8795
+ `Directive "@${name}" may not be used on ${candidateLocation}.`,
8796
+ node,
8797
+ ),
8798
+ );
8799
+ }
8800
+ },
8801
+ };
8802
+ }
8803
+
8804
+ function getDirectiveLocationForASTPath(ancestors) {
8805
+ const appliedTo = ancestors[ancestors.length - 1];
8806
+ 'kind' in appliedTo || invariant(false);
8807
+
8808
+ switch (appliedTo.kind) {
8809
+ case Kind.OPERATION_DEFINITION:
8810
+ return getDirectiveLocationForOperation(appliedTo.operation);
8811
+
8812
+ case Kind.FIELD:
8813
+ return DirectiveLocation.FIELD;
8814
+
8815
+ case Kind.FRAGMENT_SPREAD:
8816
+ return DirectiveLocation.FRAGMENT_SPREAD;
8817
+
8818
+ case Kind.INLINE_FRAGMENT:
8819
+ return DirectiveLocation.INLINE_FRAGMENT;
8820
+
8821
+ case Kind.FRAGMENT_DEFINITION:
8822
+ return DirectiveLocation.FRAGMENT_DEFINITION;
8823
+
8824
+ case Kind.VARIABLE_DEFINITION:
8825
+ return DirectiveLocation.VARIABLE_DEFINITION;
8826
+
8827
+ case Kind.SCHEMA_DEFINITION:
8828
+ case Kind.SCHEMA_EXTENSION:
8829
+ return DirectiveLocation.SCHEMA;
8830
+
8831
+ case Kind.SCALAR_TYPE_DEFINITION:
8832
+ case Kind.SCALAR_TYPE_EXTENSION:
8833
+ return DirectiveLocation.SCALAR;
8834
+
8835
+ case Kind.OBJECT_TYPE_DEFINITION:
8836
+ case Kind.OBJECT_TYPE_EXTENSION:
8837
+ return DirectiveLocation.OBJECT;
8838
+
8839
+ case Kind.FIELD_DEFINITION:
8840
+ return DirectiveLocation.FIELD_DEFINITION;
8841
+
8842
+ case Kind.INTERFACE_TYPE_DEFINITION:
8843
+ case Kind.INTERFACE_TYPE_EXTENSION:
8844
+ return DirectiveLocation.INTERFACE;
8845
+
8846
+ case Kind.UNION_TYPE_DEFINITION:
8847
+ case Kind.UNION_TYPE_EXTENSION:
8848
+ return DirectiveLocation.UNION;
8849
+
8850
+ case Kind.ENUM_TYPE_DEFINITION:
8851
+ case Kind.ENUM_TYPE_EXTENSION:
8852
+ return DirectiveLocation.ENUM;
8853
+
8854
+ case Kind.ENUM_VALUE_DEFINITION:
8855
+ return DirectiveLocation.ENUM_VALUE;
8856
+
8857
+ case Kind.INPUT_OBJECT_TYPE_DEFINITION:
8858
+ case Kind.INPUT_OBJECT_TYPE_EXTENSION:
8859
+ return DirectiveLocation.INPUT_OBJECT;
8860
+
8861
+ case Kind.INPUT_VALUE_DEFINITION: {
8862
+ const parentNode = ancestors[ancestors.length - 3];
8863
+ 'kind' in parentNode || invariant(false);
8864
+ return parentNode.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION
8865
+ ? DirectiveLocation.INPUT_FIELD_DEFINITION
8866
+ : DirectiveLocation.ARGUMENT_DEFINITION;
8867
+ }
8868
+ }
8869
+ }
8870
+
8871
+ function getDirectiveLocationForOperation(operation) {
8872
+ switch (operation) {
8873
+ case OperationTypeNode.QUERY:
8874
+ return DirectiveLocation.QUERY;
8875
+
8876
+ case OperationTypeNode.MUTATION:
8877
+ return DirectiveLocation.MUTATION;
8878
+
8879
+ case OperationTypeNode.SUBSCRIPTION:
8880
+ return DirectiveLocation.SUBSCRIPTION;
8881
+ } // istanbul ignore next (Not reachable. All possible types have been considered)
8882
+
8883
+ invariant(false, 'Unexpected operation: ' + inspect(operation));
8884
+ }
8885
+
8886
+ /**
8887
+ * Unique directive names per location
8888
+ *
8889
+ * A GraphQL document is only valid if all non-repeatable directives at
8890
+ * a given location are uniquely named.
8891
+ *
8892
+ * See https://spec.graphql.org/draft/#sec-Directives-Are-Unique-Per-Location
8893
+ */
8894
+ function UniqueDirectivesPerLocationRule(context) {
8895
+ const uniqueDirectiveMap = Object.create(null);
8896
+ const schema = context.getSchema();
8897
+ const definedDirectives = schema
8898
+ ? schema.getDirectives()
8899
+ : specifiedDirectives;
8900
+
8901
+ for (const directive of definedDirectives) {
8902
+ uniqueDirectiveMap[directive.name] = !directive.isRepeatable;
8903
+ }
8904
+
8905
+ const astDefinitions = context.getDocument().definitions;
8906
+
8907
+ for (const def of astDefinitions) {
8908
+ if (def.kind === Kind.DIRECTIVE_DEFINITION) {
8909
+ uniqueDirectiveMap[def.name.value] = !def.repeatable;
8910
+ }
8911
+ }
8912
+
8913
+ const schemaDirectives = Object.create(null);
8914
+ const typeDirectivesMap = Object.create(null);
8915
+ return {
8916
+ // Many different AST nodes may contain directives. Rather than listing
8917
+ // them all, just listen for entering any node, and check to see if it
8918
+ // defines any directives.
8919
+ enter(node) {
8920
+ if (!('directives' in node) || !node.directives) {
8921
+ return;
8922
+ }
8923
+
8924
+ let seenDirectives;
8925
+
8926
+ if (
8927
+ node.kind === Kind.SCHEMA_DEFINITION ||
8928
+ node.kind === Kind.SCHEMA_EXTENSION
8929
+ ) {
8930
+ seenDirectives = schemaDirectives;
8931
+ } else if (isTypeDefinitionNode(node) || isTypeExtensionNode(node)) {
8932
+ const typeName = node.name.value;
8933
+ seenDirectives = typeDirectivesMap[typeName];
8934
+
8935
+ if (seenDirectives === undefined) {
8936
+ typeDirectivesMap[typeName] = seenDirectives = Object.create(null);
8937
+ }
8938
+ } else {
8939
+ seenDirectives = Object.create(null);
8940
+ }
8941
+
8942
+ for (const directive of node.directives) {
8943
+ const directiveName = directive.name.value;
8944
+
8945
+ if (uniqueDirectiveMap[directiveName]) {
8946
+ if (seenDirectives[directiveName]) {
8947
+ context.reportError(
8948
+ new GraphQLError(
8949
+ `The directive "@${directiveName}" can only be used once at this location.`,
8950
+ [seenDirectives[directiveName], directive],
8951
+ ),
8952
+ );
8953
+ } else {
8954
+ seenDirectives[directiveName] = directive;
8955
+ }
8956
+ }
8957
+ }
8958
+ },
8959
+ };
8960
+ }
8961
+
8962
+ /**
8963
+ * Known argument names
8964
+ *
8965
+ * A GraphQL field is only valid if all supplied arguments are defined by
8966
+ * that field.
8967
+ *
8968
+ * See https://spec.graphql.org/draft/#sec-Argument-Names
8969
+ * See https://spec.graphql.org/draft/#sec-Directives-Are-In-Valid-Locations
8970
+ */
8971
+ function KnownArgumentNamesRule(context) {
8972
+ return {
8973
+ // eslint-disable-next-line new-cap
8974
+ ...KnownArgumentNamesOnDirectivesRule(context),
8975
+
8976
+ Argument(argNode) {
8977
+ const argDef = context.getArgument();
8978
+ const fieldDef = context.getFieldDef();
8979
+ const parentType = context.getParentType();
8980
+
8981
+ if (!argDef && fieldDef && parentType) {
8982
+ const argName = argNode.name.value;
8983
+ const knownArgsNames = fieldDef.args.map((arg) => arg.name);
8984
+ const suggestions = suggestionList(argName, knownArgsNames);
8985
+ context.reportError(
8986
+ new GraphQLError(
8987
+ `Unknown argument "${argName}" on field "${parentType.name}.${fieldDef.name}".` +
8988
+ didYouMean(suggestions),
8989
+ argNode,
8990
+ ),
8991
+ );
8992
+ }
8993
+ },
8994
+ };
8995
+ }
8996
+ /**
8997
+ * @internal
8998
+ */
8999
+
9000
+ function KnownArgumentNamesOnDirectivesRule(context) {
9001
+ const directiveArgs = Object.create(null);
9002
+ const schema = context.getSchema();
9003
+ const definedDirectives = schema
9004
+ ? schema.getDirectives()
9005
+ : specifiedDirectives;
9006
+
9007
+ for (const directive of definedDirectives) {
9008
+ directiveArgs[directive.name] = directive.args.map((arg) => arg.name);
9009
+ }
9010
+
9011
+ const astDefinitions = context.getDocument().definitions;
9012
+
9013
+ for (const def of astDefinitions) {
9014
+ if (def.kind === Kind.DIRECTIVE_DEFINITION) {
9015
+ var _def$arguments;
9016
+
9017
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
9018
+ const argsNodes =
9019
+ (_def$arguments = def.arguments) !== null && _def$arguments !== void 0
9020
+ ? _def$arguments
9021
+ : [];
9022
+ directiveArgs[def.name.value] = argsNodes.map((arg) => arg.name.value);
9023
+ }
9024
+ }
9025
+
9026
+ return {
9027
+ Directive(directiveNode) {
9028
+ const directiveName = directiveNode.name.value;
9029
+ const knownArgs = directiveArgs[directiveName];
9030
+
9031
+ if (directiveNode.arguments && knownArgs) {
9032
+ for (const argNode of directiveNode.arguments) {
9033
+ const argName = argNode.name.value;
9034
+
9035
+ if (!knownArgs.includes(argName)) {
9036
+ const suggestions = suggestionList(argName, knownArgs);
9037
+ context.reportError(
9038
+ new GraphQLError(
9039
+ `Unknown argument "${argName}" on directive "@${directiveName}".` +
9040
+ didYouMean(suggestions),
9041
+ argNode,
9042
+ ),
9043
+ );
9044
+ }
9045
+ }
9046
+ }
9047
+
9048
+ return false;
9049
+ },
9050
+ };
9051
+ }
9052
+
9053
+ /**
9054
+ * Unique argument names
9055
+ *
9056
+ * A GraphQL field or directive is only valid if all supplied arguments are
9057
+ * uniquely named.
9058
+ *
9059
+ * See https://spec.graphql.org/draft/#sec-Argument-Names
9060
+ */
9061
+ function UniqueArgumentNamesRule(context) {
9062
+ return {
9063
+ Field: checkArgUniqueness,
9064
+ Directive: checkArgUniqueness,
9065
+ };
9066
+
9067
+ function checkArgUniqueness(parentNode) {
9068
+ var _parentNode$arguments;
9069
+
9070
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
9071
+ const argumentNodes =
9072
+ (_parentNode$arguments = parentNode.arguments) !== null &&
9073
+ _parentNode$arguments !== void 0
9074
+ ? _parentNode$arguments
9075
+ : [];
9076
+ const seenArgs = groupBy(argumentNodes, (arg) => arg.name.value);
9077
+
9078
+ for (const [argName, argNodes] of seenArgs) {
9079
+ if (argNodes.length > 1) {
9080
+ context.reportError(
9081
+ new GraphQLError(
9082
+ `There can be only one argument named "${argName}".`,
9083
+ argNodes.map((node) => node.name),
9084
+ ),
9085
+ );
9086
+ }
9087
+ }
9088
+ }
9089
+ }
9090
+
9091
+ /**
9092
+ * Value literals of correct type
9093
+ *
9094
+ * A GraphQL document is only valid if all value literals are of the type
9095
+ * expected at their position.
9096
+ *
9097
+ * See https://spec.graphql.org/draft/#sec-Values-of-Correct-Type
9098
+ */
9099
+ function ValuesOfCorrectTypeRule(context) {
9100
+ return {
9101
+ ListValue(node) {
9102
+ // Note: TypeInfo will traverse into a list's item type, so look to the
9103
+ // parent input type to check if it is a list.
9104
+ const type = getNullableType(context.getParentInputType());
9105
+
9106
+ if (!isListType(type)) {
9107
+ isValidValueNode(context, node);
9108
+ return false; // Don't traverse further.
9109
+ }
9110
+ },
9111
+
9112
+ ObjectValue(node) {
9113
+ const type = getNamedType(context.getInputType());
9114
+
9115
+ if (!isInputObjectType(type)) {
9116
+ isValidValueNode(context, node);
9117
+ return false; // Don't traverse further.
9118
+ } // Ensure every required field exists.
9119
+
9120
+ const fieldNodeMap = keyMap(node.fields, (field) => field.name.value);
9121
+
9122
+ for (const fieldDef of Object.values(type.getFields())) {
9123
+ const fieldNode = fieldNodeMap[fieldDef.name];
9124
+
9125
+ if (!fieldNode && isRequiredInputField(fieldDef)) {
9126
+ const typeStr = inspect(fieldDef.type);
9127
+ context.reportError(
9128
+ new GraphQLError(
9129
+ `Field "${type.name}.${fieldDef.name}" of required type "${typeStr}" was not provided.`,
9130
+ node,
9131
+ ),
9132
+ );
9133
+ }
9134
+ }
9135
+ },
9136
+
9137
+ ObjectField(node) {
9138
+ const parentType = getNamedType(context.getParentInputType());
9139
+ const fieldType = context.getInputType();
9140
+
9141
+ if (!fieldType && isInputObjectType(parentType)) {
9142
+ const suggestions = suggestionList(
9143
+ node.name.value,
9144
+ Object.keys(parentType.getFields()),
9145
+ );
9146
+ context.reportError(
9147
+ new GraphQLError(
9148
+ `Field "${node.name.value}" is not defined by type "${parentType.name}".` +
9149
+ didYouMean(suggestions),
9150
+ node,
9151
+ ),
9152
+ );
9153
+ }
9154
+ },
9155
+
9156
+ NullValue(node) {
9157
+ const type = context.getInputType();
9158
+
9159
+ if (isNonNullType(type)) {
9160
+ context.reportError(
9161
+ new GraphQLError(
9162
+ `Expected value of type "${inspect(type)}", found ${print(node)}.`,
9163
+ node,
9164
+ ),
9165
+ );
9166
+ }
9167
+ },
9168
+
9169
+ EnumValue: (node) => isValidValueNode(context, node),
9170
+ IntValue: (node) => isValidValueNode(context, node),
9171
+ FloatValue: (node) => isValidValueNode(context, node),
9172
+ StringValue: (node) => isValidValueNode(context, node),
9173
+ BooleanValue: (node) => isValidValueNode(context, node),
9174
+ };
9175
+ }
9176
+ /**
9177
+ * Any value literal may be a valid representation of a Scalar, depending on
9178
+ * that scalar type.
9179
+ */
9180
+
9181
+ function isValidValueNode(context, node) {
9182
+ // Report any error at the full type expected by the location.
9183
+ const locationType = context.getInputType();
9184
+
9185
+ if (!locationType) {
9186
+ return;
9187
+ }
9188
+
9189
+ const type = getNamedType(locationType);
9190
+
9191
+ if (!isLeafType(type)) {
9192
+ const typeStr = inspect(locationType);
9193
+ context.reportError(
9194
+ new GraphQLError(
9195
+ `Expected value of type "${typeStr}", found ${print(node)}.`,
9196
+ node,
9197
+ ),
9198
+ );
9199
+ return;
9200
+ } // Scalars and Enums determine if a literal value is valid via parseLiteral(),
9201
+ // which may throw or return an invalid value to indicate failure.
9202
+
9203
+ try {
9204
+ const parseResult = type.parseLiteral(
9205
+ node,
9206
+ undefined,
9207
+ /* variables */
9208
+ );
9209
+
9210
+ if (parseResult === undefined) {
9211
+ const typeStr = inspect(locationType);
9212
+ context.reportError(
9213
+ new GraphQLError(
9214
+ `Expected value of type "${typeStr}", found ${print(node)}.`,
9215
+ node,
9216
+ ),
9217
+ );
9218
+ }
9219
+ } catch (error) {
9220
+ const typeStr = inspect(locationType);
9221
+
9222
+ if (error instanceof GraphQLError) {
9223
+ context.reportError(error);
9224
+ } else {
9225
+ context.reportError(
9226
+ new GraphQLError(
9227
+ `Expected value of type "${typeStr}", found ${print(node)}; ` +
9228
+ error.message,
9229
+ node,
9230
+ undefined,
9231
+ undefined,
9232
+ undefined,
9233
+ error,
9234
+ ),
9235
+ );
9236
+ }
9237
+ }
9238
+ }
9239
+
9240
+ /**
9241
+ * Provided required arguments
9242
+ *
9243
+ * A field or directive is only valid if all required (non-null without a
9244
+ * default value) field arguments have been provided.
9245
+ */
9246
+ function ProvidedRequiredArgumentsRule(context) {
9247
+ return {
9248
+ // eslint-disable-next-line new-cap
9249
+ ...ProvidedRequiredArgumentsOnDirectivesRule(context),
9250
+ Field: {
9251
+ // Validate on leave to allow for deeper errors to appear first.
9252
+ leave(fieldNode) {
9253
+ var _fieldNode$arguments;
9254
+
9255
+ const fieldDef = context.getFieldDef();
9256
+
9257
+ if (!fieldDef) {
9258
+ return false;
9259
+ }
9260
+
9261
+ const providedArgs = new Set( // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
9262
+ (_fieldNode$arguments = fieldNode.arguments) === null ||
9263
+ _fieldNode$arguments === void 0
9264
+ ? void 0
9265
+ : _fieldNode$arguments.map((arg) => arg.name.value),
9266
+ );
9267
+
9268
+ for (const argDef of fieldDef.args) {
9269
+ if (!providedArgs.has(argDef.name) && isRequiredArgument(argDef)) {
9270
+ const argTypeStr = inspect(argDef.type);
9271
+ context.reportError(
9272
+ new GraphQLError(
9273
+ `Field "${fieldDef.name}" argument "${argDef.name}" of type "${argTypeStr}" is required, but it was not provided.`,
9274
+ fieldNode,
9275
+ ),
9276
+ );
9277
+ }
9278
+ }
9279
+ },
9280
+ },
9281
+ };
9282
+ }
9283
+ /**
9284
+ * @internal
9285
+ */
9286
+
9287
+ function ProvidedRequiredArgumentsOnDirectivesRule(context) {
9288
+ var _schema$getDirectives;
9289
+
9290
+ const requiredArgsMap = Object.create(null);
9291
+ const schema = context.getSchema();
9292
+ const definedDirectives =
9293
+ (_schema$getDirectives =
9294
+ schema === null || schema === void 0
9295
+ ? void 0
9296
+ : schema.getDirectives()) !== null && _schema$getDirectives !== void 0
9297
+ ? _schema$getDirectives
9298
+ : specifiedDirectives;
9299
+
9300
+ for (const directive of definedDirectives) {
9301
+ requiredArgsMap[directive.name] = keyMap(
9302
+ directive.args.filter(isRequiredArgument),
9303
+ (arg) => arg.name,
9304
+ );
9305
+ }
9306
+
9307
+ const astDefinitions = context.getDocument().definitions;
9308
+
9309
+ for (const def of astDefinitions) {
9310
+ if (def.kind === Kind.DIRECTIVE_DEFINITION) {
9311
+ var _def$arguments;
9312
+
9313
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
9314
+ const argNodes =
9315
+ (_def$arguments = def.arguments) !== null && _def$arguments !== void 0
9316
+ ? _def$arguments
9317
+ : [];
9318
+ requiredArgsMap[def.name.value] = keyMap(
9319
+ argNodes.filter(isRequiredArgumentNode),
9320
+ (arg) => arg.name.value,
9321
+ );
9322
+ }
9323
+ }
9324
+
9325
+ return {
9326
+ Directive: {
9327
+ // Validate on leave to allow for deeper errors to appear first.
9328
+ leave(directiveNode) {
9329
+ const directiveName = directiveNode.name.value;
9330
+ const requiredArgs = requiredArgsMap[directiveName];
9331
+
9332
+ if (requiredArgs) {
9333
+ var _directiveNode$argume;
9334
+
9335
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
9336
+ const argNodes =
9337
+ (_directiveNode$argume = directiveNode.arguments) !== null &&
9338
+ _directiveNode$argume !== void 0
9339
+ ? _directiveNode$argume
9340
+ : [];
9341
+ const argNodeMap = new Set(argNodes.map((arg) => arg.name.value));
9342
+
9343
+ for (const [argName, argDef] of Object.entries(requiredArgs)) {
9344
+ if (!argNodeMap.has(argName)) {
9345
+ const argType = isType(argDef.type)
9346
+ ? inspect(argDef.type)
9347
+ : print(argDef.type);
9348
+ context.reportError(
9349
+ new GraphQLError(
9350
+ `Directive "@${directiveName}" argument "${argName}" of type "${argType}" is required, but it was not provided.`,
9351
+ directiveNode,
9352
+ ),
9353
+ );
9354
+ }
9355
+ }
9356
+ }
9357
+ },
9358
+ },
9359
+ };
9360
+ }
9361
+
9362
+ function isRequiredArgumentNode(arg) {
9363
+ return arg.type.kind === Kind.NON_NULL_TYPE && arg.defaultValue == null;
9364
+ }
9365
+
9366
+ /**
9367
+ * Variables in allowed position
9368
+ *
9369
+ * Variable usages must be compatible with the arguments they are passed to.
9370
+ *
9371
+ * See https://spec.graphql.org/draft/#sec-All-Variable-Usages-are-Allowed
9372
+ */
9373
+ function VariablesInAllowedPositionRule(context) {
9374
+ let varDefMap = Object.create(null);
9375
+ return {
9376
+ OperationDefinition: {
9377
+ enter() {
9378
+ varDefMap = Object.create(null);
9379
+ },
9380
+
9381
+ leave(operation) {
9382
+ const usages = context.getRecursiveVariableUsages(operation);
9383
+
9384
+ for (const { node, type, defaultValue } of usages) {
9385
+ const varName = node.name.value;
9386
+ const varDef = varDefMap[varName];
9387
+
9388
+ if (varDef && type) {
9389
+ // A var type is allowed if it is the same or more strict (e.g. is
9390
+ // a subtype of) than the expected type. It can be more strict if
9391
+ // the variable type is non-null when the expected type is nullable.
9392
+ // If both are list types, the variable item type can be more strict
9393
+ // than the expected item type (contravariant).
9394
+ const schema = context.getSchema();
9395
+ const varType = typeFromAST(schema, varDef.type);
9396
+
9397
+ if (
9398
+ varType &&
9399
+ !allowedVariableUsage(
9400
+ schema,
9401
+ varType,
9402
+ varDef.defaultValue,
9403
+ type,
9404
+ defaultValue,
9405
+ )
9406
+ ) {
9407
+ const varTypeStr = inspect(varType);
9408
+ const typeStr = inspect(type);
9409
+ context.reportError(
9410
+ new GraphQLError(
9411
+ `Variable "$${varName}" of type "${varTypeStr}" used in position expecting type "${typeStr}".`,
9412
+ [varDef, node],
9413
+ ),
9414
+ );
9415
+ }
9416
+ }
9417
+ }
9418
+ },
9419
+ },
9420
+
9421
+ VariableDefinition(node) {
9422
+ varDefMap[node.variable.name.value] = node;
9423
+ },
9424
+ };
9425
+ }
9426
+ /**
9427
+ * Returns true if the variable is allowed in the location it was found,
9428
+ * which includes considering if default values exist for either the variable
9429
+ * or the location at which it is located.
9430
+ */
9431
+
9432
+ function allowedVariableUsage(
9433
+ schema,
9434
+ varType,
9435
+ varDefaultValue,
9436
+ locationType,
9437
+ locationDefaultValue,
9438
+ ) {
9439
+ if (isNonNullType(locationType) && !isNonNullType(varType)) {
9440
+ const hasNonNullVariableDefaultValue =
9441
+ varDefaultValue != null && varDefaultValue.kind !== Kind.NULL;
9442
+ const hasLocationDefaultValue = locationDefaultValue !== undefined;
9443
+
9444
+ if (!hasNonNullVariableDefaultValue && !hasLocationDefaultValue) {
9445
+ return false;
9446
+ }
9447
+
9448
+ const nullableLocationType = locationType.ofType;
9449
+ return isTypeSubTypeOf(schema, varType, nullableLocationType);
9450
+ }
9451
+
9452
+ return isTypeSubTypeOf(schema, varType, locationType);
9453
+ }
9454
+
9455
+ function reasonMessage(reason) {
9456
+ if (Array.isArray(reason)) {
9457
+ return reason
9458
+ .map(
9459
+ ([responseName, subReason]) =>
9460
+ `subfields "${responseName}" conflict because ` +
9461
+ reasonMessage(subReason),
9462
+ )
9463
+ .join(' and ');
9464
+ }
9465
+
9466
+ return reason;
9467
+ }
9468
+ /**
9469
+ * Overlapping fields can be merged
9470
+ *
9471
+ * A selection set is only valid if all fields (including spreading any
9472
+ * fragments) either correspond to distinct response names or can be merged
9473
+ * without ambiguity.
9474
+ *
9475
+ * See https://spec.graphql.org/draft/#sec-Field-Selection-Merging
9476
+ */
9477
+
9478
+ function OverlappingFieldsCanBeMergedRule(context) {
9479
+ // A memoization for when two fragments are compared "between" each other for
9480
+ // conflicts. Two fragments may be compared many times, so memoizing this can
9481
+ // dramatically improve the performance of this validator.
9482
+ const comparedFragmentPairs = new PairSet(); // A cache for the "field map" and list of fragment names found in any given
9483
+ // selection set. Selection sets may be asked for this information multiple
9484
+ // times, so this improves the performance of this validator.
9485
+
9486
+ const cachedFieldsAndFragmentNames = new Map();
9487
+ return {
9488
+ SelectionSet(selectionSet) {
9489
+ const conflicts = findConflictsWithinSelectionSet(
9490
+ context,
9491
+ cachedFieldsAndFragmentNames,
9492
+ comparedFragmentPairs,
9493
+ context.getParentType(),
9494
+ selectionSet,
9495
+ );
9496
+
9497
+ for (const [[responseName, reason], fields1, fields2] of conflicts) {
9498
+ const reasonMsg = reasonMessage(reason);
9499
+ context.reportError(
9500
+ new GraphQLError(
9501
+ `Fields "${responseName}" conflict because ${reasonMsg}. Use different aliases on the fields to fetch both if this was intentional.`,
9502
+ fields1.concat(fields2),
9503
+ ),
9504
+ );
9505
+ }
9506
+ },
9507
+ };
9508
+ }
9509
+
9510
+ /**
9511
+ * Algorithm:
9512
+ *
9513
+ * Conflicts occur when two fields exist in a query which will produce the same
9514
+ * response name, but represent differing values, thus creating a conflict.
9515
+ * The algorithm below finds all conflicts via making a series of comparisons
9516
+ * between fields. In order to compare as few fields as possible, this makes
9517
+ * a series of comparisons "within" sets of fields and "between" sets of fields.
9518
+ *
9519
+ * Given any selection set, a collection produces both a set of fields by
9520
+ * also including all inline fragments, as well as a list of fragments
9521
+ * referenced by fragment spreads.
9522
+ *
9523
+ * A) Each selection set represented in the document first compares "within" its
9524
+ * collected set of fields, finding any conflicts between every pair of
9525
+ * overlapping fields.
9526
+ * Note: This is the *only time* that a the fields "within" a set are compared
9527
+ * to each other. After this only fields "between" sets are compared.
9528
+ *
9529
+ * B) Also, if any fragment is referenced in a selection set, then a
9530
+ * comparison is made "between" the original set of fields and the
9531
+ * referenced fragment.
9532
+ *
9533
+ * C) Also, if multiple fragments are referenced, then comparisons
9534
+ * are made "between" each referenced fragment.
9535
+ *
9536
+ * D) When comparing "between" a set of fields and a referenced fragment, first
9537
+ * a comparison is made between each field in the original set of fields and
9538
+ * each field in the the referenced set of fields.
9539
+ *
9540
+ * E) Also, if any fragment is referenced in the referenced selection set,
9541
+ * then a comparison is made "between" the original set of fields and the
9542
+ * referenced fragment (recursively referring to step D).
9543
+ *
9544
+ * F) When comparing "between" two fragments, first a comparison is made between
9545
+ * each field in the first referenced set of fields and each field in the the
9546
+ * second referenced set of fields.
9547
+ *
9548
+ * G) Also, any fragments referenced by the first must be compared to the
9549
+ * second, and any fragments referenced by the second must be compared to the
9550
+ * first (recursively referring to step F).
9551
+ *
9552
+ * H) When comparing two fields, if both have selection sets, then a comparison
9553
+ * is made "between" both selection sets, first comparing the set of fields in
9554
+ * the first selection set with the set of fields in the second.
9555
+ *
9556
+ * I) Also, if any fragment is referenced in either selection set, then a
9557
+ * comparison is made "between" the other set of fields and the
9558
+ * referenced fragment.
9559
+ *
9560
+ * J) Also, if two fragments are referenced in both selection sets, then a
9561
+ * comparison is made "between" the two fragments.
9562
+ *
9563
+ */
9564
+ // Find all conflicts found "within" a selection set, including those found
9565
+ // via spreading in fragments. Called when visiting each SelectionSet in the
9566
+ // GraphQL Document.
9567
+ function findConflictsWithinSelectionSet(
9568
+ context,
9569
+ cachedFieldsAndFragmentNames,
9570
+ comparedFragmentPairs,
9571
+ parentType,
9572
+ selectionSet,
9573
+ ) {
9574
+ const conflicts = [];
9575
+ const [fieldMap, fragmentNames] = getFieldsAndFragmentNames(
9576
+ context,
9577
+ cachedFieldsAndFragmentNames,
9578
+ parentType,
9579
+ selectionSet,
9580
+ ); // (A) Find find all conflicts "within" the fields of this selection set.
9581
+ // Note: this is the *only place* `collectConflictsWithin` is called.
9582
+
9583
+ collectConflictsWithin(
9584
+ context,
9585
+ conflicts,
9586
+ cachedFieldsAndFragmentNames,
9587
+ comparedFragmentPairs,
9588
+ fieldMap,
9589
+ );
9590
+
9591
+ if (fragmentNames.length !== 0) {
9592
+ // (B) Then collect conflicts between these fields and those represented by
9593
+ // each spread fragment name found.
9594
+ for (let i = 0; i < fragmentNames.length; i++) {
9595
+ collectConflictsBetweenFieldsAndFragment(
9596
+ context,
9597
+ conflicts,
9598
+ cachedFieldsAndFragmentNames,
9599
+ comparedFragmentPairs,
9600
+ false,
9601
+ fieldMap,
9602
+ fragmentNames[i],
9603
+ ); // (C) Then compare this fragment with all other fragments found in this
9604
+ // selection set to collect conflicts between fragments spread together.
9605
+ // This compares each item in the list of fragment names to every other
9606
+ // item in that same list (except for itself).
9607
+
9608
+ for (let j = i + 1; j < fragmentNames.length; j++) {
9609
+ collectConflictsBetweenFragments(
9610
+ context,
9611
+ conflicts,
9612
+ cachedFieldsAndFragmentNames,
9613
+ comparedFragmentPairs,
9614
+ false,
9615
+ fragmentNames[i],
9616
+ fragmentNames[j],
9617
+ );
9618
+ }
9619
+ }
9620
+ }
9621
+
9622
+ return conflicts;
9623
+ } // Collect all conflicts found between a set of fields and a fragment reference
9624
+ // including via spreading in any nested fragments.
9625
+
9626
+ function collectConflictsBetweenFieldsAndFragment(
9627
+ context,
9628
+ conflicts,
9629
+ cachedFieldsAndFragmentNames,
9630
+ comparedFragmentPairs,
9631
+ areMutuallyExclusive,
9632
+ fieldMap,
9633
+ fragmentName,
9634
+ ) {
9635
+ const fragment = context.getFragment(fragmentName);
9636
+
9637
+ if (!fragment) {
9638
+ return;
9639
+ }
9640
+
9641
+ const [fieldMap2, referencedFragmentNames] =
9642
+ getReferencedFieldsAndFragmentNames(
9643
+ context,
9644
+ cachedFieldsAndFragmentNames,
9645
+ fragment,
9646
+ ); // Do not compare a fragment's fieldMap to itself.
9647
+
9648
+ if (fieldMap === fieldMap2) {
9649
+ return;
9650
+ } // (D) First collect any conflicts between the provided collection of fields
9651
+ // and the collection of fields represented by the given fragment.
9652
+
9653
+ collectConflictsBetween(
9654
+ context,
9655
+ conflicts,
9656
+ cachedFieldsAndFragmentNames,
9657
+ comparedFragmentPairs,
9658
+ areMutuallyExclusive,
9659
+ fieldMap,
9660
+ fieldMap2,
9661
+ ); // (E) Then collect any conflicts between the provided collection of fields
9662
+ // and any fragment names found in the given fragment.
9663
+
9664
+ for (const referencedFragmentName of referencedFragmentNames) {
9665
+ collectConflictsBetweenFieldsAndFragment(
9666
+ context,
9667
+ conflicts,
9668
+ cachedFieldsAndFragmentNames,
9669
+ comparedFragmentPairs,
9670
+ areMutuallyExclusive,
9671
+ fieldMap,
9672
+ referencedFragmentName,
9673
+ );
9674
+ }
9675
+ } // Collect all conflicts found between two fragments, including via spreading in
9676
+ // any nested fragments.
9677
+
9678
+ function collectConflictsBetweenFragments(
9679
+ context,
9680
+ conflicts,
9681
+ cachedFieldsAndFragmentNames,
9682
+ comparedFragmentPairs,
9683
+ areMutuallyExclusive,
9684
+ fragmentName1,
9685
+ fragmentName2,
9686
+ ) {
9687
+ // No need to compare a fragment to itself.
9688
+ if (fragmentName1 === fragmentName2) {
9689
+ return;
9690
+ } // Memoize so two fragments are not compared for conflicts more than once.
9691
+
9692
+ if (
9693
+ comparedFragmentPairs.has(
9694
+ fragmentName1,
9695
+ fragmentName2,
9696
+ areMutuallyExclusive,
9697
+ )
9698
+ ) {
9699
+ return;
9700
+ }
9701
+
9702
+ comparedFragmentPairs.add(fragmentName1, fragmentName2, areMutuallyExclusive);
9703
+ const fragment1 = context.getFragment(fragmentName1);
9704
+ const fragment2 = context.getFragment(fragmentName2);
9705
+
9706
+ if (!fragment1 || !fragment2) {
9707
+ return;
9708
+ }
9709
+
9710
+ const [fieldMap1, referencedFragmentNames1] =
9711
+ getReferencedFieldsAndFragmentNames(
9712
+ context,
9713
+ cachedFieldsAndFragmentNames,
9714
+ fragment1,
9715
+ );
9716
+ const [fieldMap2, referencedFragmentNames2] =
9717
+ getReferencedFieldsAndFragmentNames(
9718
+ context,
9719
+ cachedFieldsAndFragmentNames,
9720
+ fragment2,
9721
+ ); // (F) First, collect all conflicts between these two collections of fields
9722
+ // (not including any nested fragments).
9723
+
9724
+ collectConflictsBetween(
9725
+ context,
9726
+ conflicts,
9727
+ cachedFieldsAndFragmentNames,
9728
+ comparedFragmentPairs,
9729
+ areMutuallyExclusive,
9730
+ fieldMap1,
9731
+ fieldMap2,
9732
+ ); // (G) Then collect conflicts between the first fragment and any nested
9733
+ // fragments spread in the second fragment.
9734
+
9735
+ for (const referencedFragmentName2 of referencedFragmentNames2) {
9736
+ collectConflictsBetweenFragments(
9737
+ context,
9738
+ conflicts,
9739
+ cachedFieldsAndFragmentNames,
9740
+ comparedFragmentPairs,
9741
+ areMutuallyExclusive,
9742
+ fragmentName1,
9743
+ referencedFragmentName2,
9744
+ );
9745
+ } // (G) Then collect conflicts between the second fragment and any nested
9746
+ // fragments spread in the first fragment.
9747
+
9748
+ for (const referencedFragmentName1 of referencedFragmentNames1) {
9749
+ collectConflictsBetweenFragments(
9750
+ context,
9751
+ conflicts,
9752
+ cachedFieldsAndFragmentNames,
9753
+ comparedFragmentPairs,
9754
+ areMutuallyExclusive,
9755
+ referencedFragmentName1,
9756
+ fragmentName2,
9757
+ );
9758
+ }
9759
+ } // Find all conflicts found between two selection sets, including those found
9760
+ // via spreading in fragments. Called when determining if conflicts exist
9761
+ // between the sub-fields of two overlapping fields.
9762
+
9763
+ function findConflictsBetweenSubSelectionSets(
9764
+ context,
9765
+ cachedFieldsAndFragmentNames,
9766
+ comparedFragmentPairs,
9767
+ areMutuallyExclusive,
9768
+ parentType1,
9769
+ selectionSet1,
9770
+ parentType2,
9771
+ selectionSet2,
9772
+ ) {
9773
+ const conflicts = [];
9774
+ const [fieldMap1, fragmentNames1] = getFieldsAndFragmentNames(
9775
+ context,
9776
+ cachedFieldsAndFragmentNames,
9777
+ parentType1,
9778
+ selectionSet1,
9779
+ );
9780
+ const [fieldMap2, fragmentNames2] = getFieldsAndFragmentNames(
9781
+ context,
9782
+ cachedFieldsAndFragmentNames,
9783
+ parentType2,
9784
+ selectionSet2,
9785
+ ); // (H) First, collect all conflicts between these two collections of field.
9786
+
9787
+ collectConflictsBetween(
9788
+ context,
9789
+ conflicts,
9790
+ cachedFieldsAndFragmentNames,
9791
+ comparedFragmentPairs,
9792
+ areMutuallyExclusive,
9793
+ fieldMap1,
9794
+ fieldMap2,
9795
+ ); // (I) Then collect conflicts between the first collection of fields and
9796
+ // those referenced by each fragment name associated with the second.
9797
+
9798
+ for (const fragmentName2 of fragmentNames2) {
9799
+ collectConflictsBetweenFieldsAndFragment(
9800
+ context,
9801
+ conflicts,
9802
+ cachedFieldsAndFragmentNames,
9803
+ comparedFragmentPairs,
9804
+ areMutuallyExclusive,
9805
+ fieldMap1,
9806
+ fragmentName2,
9807
+ );
9808
+ } // (I) Then collect conflicts between the second collection of fields and
9809
+ // those referenced by each fragment name associated with the first.
9810
+
9811
+ for (const fragmentName1 of fragmentNames1) {
9812
+ collectConflictsBetweenFieldsAndFragment(
9813
+ context,
9814
+ conflicts,
9815
+ cachedFieldsAndFragmentNames,
9816
+ comparedFragmentPairs,
9817
+ areMutuallyExclusive,
9818
+ fieldMap2,
9819
+ fragmentName1,
9820
+ );
9821
+ } // (J) Also collect conflicts between any fragment names by the first and
9822
+ // fragment names by the second. This compares each item in the first set of
9823
+ // names to each item in the second set of names.
9824
+
9825
+ for (const fragmentName1 of fragmentNames1) {
9826
+ for (const fragmentName2 of fragmentNames2) {
9827
+ collectConflictsBetweenFragments(
9828
+ context,
9829
+ conflicts,
9830
+ cachedFieldsAndFragmentNames,
9831
+ comparedFragmentPairs,
9832
+ areMutuallyExclusive,
9833
+ fragmentName1,
9834
+ fragmentName2,
9835
+ );
9836
+ }
9837
+ }
9838
+
9839
+ return conflicts;
9840
+ } // Collect all Conflicts "within" one collection of fields.
9841
+
9842
+ function collectConflictsWithin(
9843
+ context,
9844
+ conflicts,
9845
+ cachedFieldsAndFragmentNames,
9846
+ comparedFragmentPairs,
9847
+ fieldMap,
9848
+ ) {
9849
+ // A field map is a keyed collection, where each key represents a response
9850
+ // name and the value at that key is a list of all fields which provide that
9851
+ // response name. For every response name, if there are multiple fields, they
9852
+ // must be compared to find a potential conflict.
9853
+ for (const [responseName, fields] of Object.entries(fieldMap)) {
9854
+ // This compares every field in the list to every other field in this list
9855
+ // (except to itself). If the list only has one item, nothing needs to
9856
+ // be compared.
9857
+ if (fields.length > 1) {
9858
+ for (let i = 0; i < fields.length; i++) {
9859
+ for (let j = i + 1; j < fields.length; j++) {
9860
+ const conflict = findConflict(
9861
+ context,
9862
+ cachedFieldsAndFragmentNames,
9863
+ comparedFragmentPairs,
9864
+ false, // within one collection is never mutually exclusive
9865
+ responseName,
9866
+ fields[i],
9867
+ fields[j],
9868
+ );
9869
+
9870
+ if (conflict) {
9871
+ conflicts.push(conflict);
9872
+ }
9873
+ }
9874
+ }
9875
+ }
9876
+ }
9877
+ } // Collect all Conflicts between two collections of fields. This is similar to,
9878
+ // but different from the `collectConflictsWithin` function above. This check
9879
+ // assumes that `collectConflictsWithin` has already been called on each
9880
+ // provided collection of fields. This is true because this validator traverses
9881
+ // each individual selection set.
9882
+
9883
+ function collectConflictsBetween(
9884
+ context,
9885
+ conflicts,
9886
+ cachedFieldsAndFragmentNames,
9887
+ comparedFragmentPairs,
9888
+ parentFieldsAreMutuallyExclusive,
9889
+ fieldMap1,
9890
+ fieldMap2,
9891
+ ) {
9892
+ // A field map is a keyed collection, where each key represents a response
9893
+ // name and the value at that key is a list of all fields which provide that
9894
+ // response name. For any response name which appears in both provided field
9895
+ // maps, each field from the first field map must be compared to every field
9896
+ // in the second field map to find potential conflicts.
9897
+ for (const [responseName, fields1] of Object.entries(fieldMap1)) {
9898
+ const fields2 = fieldMap2[responseName];
9899
+
9900
+ if (fields2) {
9901
+ for (const field1 of fields1) {
9902
+ for (const field2 of fields2) {
9903
+ const conflict = findConflict(
9904
+ context,
9905
+ cachedFieldsAndFragmentNames,
9906
+ comparedFragmentPairs,
9907
+ parentFieldsAreMutuallyExclusive,
9908
+ responseName,
9909
+ field1,
9910
+ field2,
9911
+ );
9912
+
9913
+ if (conflict) {
9914
+ conflicts.push(conflict);
9915
+ }
9916
+ }
9917
+ }
9918
+ }
9919
+ }
9920
+ } // Determines if there is a conflict between two particular fields, including
9921
+ // comparing their sub-fields.
9922
+
9923
+ function findConflict(
9924
+ context,
9925
+ cachedFieldsAndFragmentNames,
9926
+ comparedFragmentPairs,
9927
+ parentFieldsAreMutuallyExclusive,
9928
+ responseName,
9929
+ field1,
9930
+ field2,
9931
+ ) {
9932
+ const [parentType1, node1, def1] = field1;
9933
+ const [parentType2, node2, def2] = field2; // If it is known that two fields could not possibly apply at the same
9934
+ // time, due to the parent types, then it is safe to permit them to diverge
9935
+ // in aliased field or arguments used as they will not present any ambiguity
9936
+ // by differing.
9937
+ // It is known that two parent types could never overlap if they are
9938
+ // different Object types. Interface or Union types might overlap - if not
9939
+ // in the current state of the schema, then perhaps in some future version,
9940
+ // thus may not safely diverge.
9941
+
9942
+ const areMutuallyExclusive =
9943
+ parentFieldsAreMutuallyExclusive ||
9944
+ (parentType1 !== parentType2 &&
9945
+ isObjectType(parentType1) &&
9946
+ isObjectType(parentType2));
9947
+
9948
+ if (!areMutuallyExclusive) {
9949
+ var _node1$arguments, _node2$arguments;
9950
+
9951
+ // Two aliases must refer to the same field.
9952
+ const name1 = node1.name.value;
9953
+ const name2 = node2.name.value;
9954
+
9955
+ if (name1 !== name2) {
9956
+ return [
9957
+ [responseName, `"${name1}" and "${name2}" are different fields`],
9958
+ [node1],
9959
+ [node2],
9960
+ ];
9961
+ } // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
9962
+
9963
+ const args1 =
9964
+ (_node1$arguments = node1.arguments) !== null &&
9965
+ _node1$arguments !== void 0
9966
+ ? _node1$arguments
9967
+ : []; // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
9968
+
9969
+ const args2 =
9970
+ (_node2$arguments = node2.arguments) !== null &&
9971
+ _node2$arguments !== void 0
9972
+ ? _node2$arguments
9973
+ : []; // Two field calls must have the same arguments.
9974
+
9975
+ if (!sameArguments(args1, args2)) {
9976
+ return [
9977
+ [responseName, 'they have differing arguments'],
9978
+ [node1],
9979
+ [node2],
9980
+ ];
9981
+ }
9982
+ } // The return type for each field.
9983
+
9984
+ const type1 = def1 === null || def1 === void 0 ? void 0 : def1.type;
9985
+ const type2 = def2 === null || def2 === void 0 ? void 0 : def2.type;
9986
+
9987
+ if (type1 && type2 && doTypesConflict(type1, type2)) {
9988
+ return [
9989
+ [
9990
+ responseName,
9991
+ `they return conflicting types "${inspect(type1)}" and "${inspect(
9992
+ type2,
9993
+ )}"`,
9994
+ ],
9995
+ [node1],
9996
+ [node2],
9997
+ ];
9998
+ } // Collect and compare sub-fields. Use the same "visited fragment names" list
9999
+ // for both collections so fields in a fragment reference are never
10000
+ // compared to themselves.
10001
+
10002
+ const selectionSet1 = node1.selectionSet;
10003
+ const selectionSet2 = node2.selectionSet;
10004
+
10005
+ if (selectionSet1 && selectionSet2) {
10006
+ const conflicts = findConflictsBetweenSubSelectionSets(
10007
+ context,
10008
+ cachedFieldsAndFragmentNames,
10009
+ comparedFragmentPairs,
10010
+ areMutuallyExclusive,
10011
+ getNamedType(type1),
10012
+ selectionSet1,
10013
+ getNamedType(type2),
10014
+ selectionSet2,
10015
+ );
10016
+ return subfieldConflicts(conflicts, responseName, node1, node2);
10017
+ }
10018
+ }
10019
+
10020
+ function sameArguments(arguments1, arguments2) {
10021
+ if (arguments1.length !== arguments2.length) {
10022
+ return false;
10023
+ }
10024
+
10025
+ return arguments1.every((argument1) => {
10026
+ const argument2 = arguments2.find(
10027
+ (argument) => argument.name.value === argument1.name.value,
10028
+ );
10029
+
10030
+ if (!argument2) {
10031
+ return false;
10032
+ }
10033
+
10034
+ return sameValue(argument1.value, argument2.value);
10035
+ });
10036
+ }
10037
+
10038
+ function sameValue(value1, value2) {
10039
+ return print(value1) === print(value2);
10040
+ } // Two types conflict if both types could not apply to a value simultaneously.
10041
+ // Composite types are ignored as their individual field types will be compared
10042
+ // later recursively. However List and Non-Null types must match.
10043
+
10044
+ function doTypesConflict(type1, type2) {
10045
+ if (isListType(type1)) {
10046
+ return isListType(type2)
10047
+ ? doTypesConflict(type1.ofType, type2.ofType)
10048
+ : true;
10049
+ }
10050
+
10051
+ if (isListType(type2)) {
10052
+ return true;
10053
+ }
10054
+
10055
+ if (isNonNullType(type1)) {
10056
+ return isNonNullType(type2)
10057
+ ? doTypesConflict(type1.ofType, type2.ofType)
10058
+ : true;
10059
+ }
10060
+
10061
+ if (isNonNullType(type2)) {
10062
+ return true;
10063
+ }
10064
+
10065
+ if (isLeafType(type1) || isLeafType(type2)) {
10066
+ return type1 !== type2;
10067
+ }
10068
+
10069
+ return false;
10070
+ } // Given a selection set, return the collection of fields (a mapping of response
10071
+ // name to field nodes and definitions) as well as a list of fragment names
10072
+ // referenced via fragment spreads.
10073
+
10074
+ function getFieldsAndFragmentNames(
10075
+ context,
10076
+ cachedFieldsAndFragmentNames,
10077
+ parentType,
10078
+ selectionSet,
10079
+ ) {
10080
+ const cached = cachedFieldsAndFragmentNames.get(selectionSet);
10081
+
10082
+ if (cached) {
10083
+ return cached;
10084
+ }
10085
+
10086
+ const nodeAndDefs = Object.create(null);
10087
+ const fragmentNames = Object.create(null);
10088
+
10089
+ _collectFieldsAndFragmentNames(
10090
+ context,
10091
+ parentType,
10092
+ selectionSet,
10093
+ nodeAndDefs,
10094
+ fragmentNames,
10095
+ );
10096
+
10097
+ const result = [nodeAndDefs, Object.keys(fragmentNames)];
10098
+ cachedFieldsAndFragmentNames.set(selectionSet, result);
10099
+ return result;
10100
+ } // Given a reference to a fragment, return the represented collection of fields
10101
+ // as well as a list of nested fragment names referenced via fragment spreads.
10102
+
10103
+ function getReferencedFieldsAndFragmentNames(
10104
+ context,
10105
+ cachedFieldsAndFragmentNames,
10106
+ fragment,
10107
+ ) {
10108
+ // Short-circuit building a type from the node if possible.
10109
+ const cached = cachedFieldsAndFragmentNames.get(fragment.selectionSet);
10110
+
10111
+ if (cached) {
10112
+ return cached;
10113
+ }
10114
+
10115
+ const fragmentType = typeFromAST(context.getSchema(), fragment.typeCondition);
10116
+ return getFieldsAndFragmentNames(
10117
+ context,
10118
+ cachedFieldsAndFragmentNames,
10119
+ fragmentType,
10120
+ fragment.selectionSet,
10121
+ );
10122
+ }
10123
+
10124
+ function _collectFieldsAndFragmentNames(
10125
+ context,
10126
+ parentType,
10127
+ selectionSet,
10128
+ nodeAndDefs,
10129
+ fragmentNames,
10130
+ ) {
10131
+ for (const selection of selectionSet.selections) {
10132
+ switch (selection.kind) {
10133
+ case Kind.FIELD: {
10134
+ const fieldName = selection.name.value;
10135
+ let fieldDef;
10136
+
10137
+ if (isObjectType(parentType) || isInterfaceType(parentType)) {
10138
+ fieldDef = parentType.getFields()[fieldName];
10139
+ }
10140
+
10141
+ const responseName = selection.alias
10142
+ ? selection.alias.value
10143
+ : fieldName;
10144
+
10145
+ if (!nodeAndDefs[responseName]) {
10146
+ nodeAndDefs[responseName] = [];
10147
+ }
10148
+
10149
+ nodeAndDefs[responseName].push([parentType, selection, fieldDef]);
10150
+ break;
10151
+ }
10152
+
10153
+ case Kind.FRAGMENT_SPREAD:
10154
+ fragmentNames[selection.name.value] = true;
10155
+ break;
10156
+
10157
+ case Kind.INLINE_FRAGMENT: {
10158
+ const typeCondition = selection.typeCondition;
10159
+ const inlineFragmentType = typeCondition
10160
+ ? typeFromAST(context.getSchema(), typeCondition)
10161
+ : parentType;
10162
+
10163
+ _collectFieldsAndFragmentNames(
10164
+ context,
10165
+ inlineFragmentType,
10166
+ selection.selectionSet,
10167
+ nodeAndDefs,
10168
+ fragmentNames,
10169
+ );
10170
+
10171
+ break;
10172
+ }
10173
+ }
10174
+ }
10175
+ } // Given a series of Conflicts which occurred between two sub-fields, generate
10176
+ // a single Conflict.
10177
+
10178
+ function subfieldConflicts(conflicts, responseName, node1, node2) {
10179
+ if (conflicts.length > 0) {
10180
+ return [
10181
+ [responseName, conflicts.map(([reason]) => reason)],
10182
+ [node1, ...conflicts.map(([, fields1]) => fields1).flat()],
10183
+ [node2, ...conflicts.map(([, , fields2]) => fields2).flat()],
10184
+ ];
10185
+ }
10186
+ }
10187
+ /**
10188
+ * A way to keep track of pairs of things when the ordering of the pair does not matter.
10189
+ */
10190
+
10191
+ class PairSet {
10192
+ constructor() {
10193
+ this._data = new Map();
10194
+ }
10195
+
10196
+ has(a, b, areMutuallyExclusive) {
10197
+ var _this$_data$get;
10198
+
10199
+ const [key1, key2] = a < b ? [a, b] : [b, a];
10200
+ const result =
10201
+ (_this$_data$get = this._data.get(key1)) === null ||
10202
+ _this$_data$get === void 0
10203
+ ? void 0
10204
+ : _this$_data$get.get(key2);
10205
+
10206
+ if (result === undefined) {
10207
+ return false;
10208
+ } // areMutuallyExclusive being false is a superset of being true, hence if
10209
+ // we want to know if this PairSet "has" these two with no exclusivity,
10210
+ // we have to ensure it was added as such.
10211
+
10212
+ return areMutuallyExclusive ? true : areMutuallyExclusive === result;
10213
+ }
10214
+
10215
+ add(a, b, areMutuallyExclusive) {
10216
+ const [key1, key2] = a < b ? [a, b] : [b, a];
10217
+
10218
+ const map = this._data.get(key1);
10219
+
10220
+ if (map === undefined) {
10221
+ this._data.set(key1, new Map([[key2, areMutuallyExclusive]]));
10222
+ } else {
10223
+ map.set(key2, areMutuallyExclusive);
10224
+ }
10225
+ }
10226
+ }
10227
+
10228
+ /**
10229
+ * Unique input field names
10230
+ *
10231
+ * A GraphQL input object value is only valid if all supplied fields are
10232
+ * uniquely named.
10233
+ *
10234
+ * See https://spec.graphql.org/draft/#sec-Input-Object-Field-Uniqueness
10235
+ */
10236
+ function UniqueInputFieldNamesRule(context) {
10237
+ const knownNameStack = [];
10238
+ let knownNames = Object.create(null);
10239
+ return {
10240
+ ObjectValue: {
10241
+ enter() {
10242
+ knownNameStack.push(knownNames);
10243
+ knownNames = Object.create(null);
10244
+ },
10245
+
10246
+ leave() {
10247
+ const prevKnownNames = knownNameStack.pop();
10248
+ prevKnownNames || invariant(false);
10249
+ knownNames = prevKnownNames;
10250
+ },
10251
+ },
10252
+
10253
+ ObjectField(node) {
10254
+ const fieldName = node.name.value;
10255
+
10256
+ if (knownNames[fieldName]) {
10257
+ context.reportError(
10258
+ new GraphQLError(
10259
+ `There can be only one input field named "${fieldName}".`,
10260
+ [knownNames[fieldName], node.name],
10261
+ ),
10262
+ );
10263
+ } else {
10264
+ knownNames[fieldName] = node.name;
10265
+ }
10266
+ },
10267
+ };
10268
+ }
10269
+
10270
+ /**
10271
+ * Lone Schema definition
10272
+ *
10273
+ * A GraphQL document is only valid if it contains only one schema definition.
10274
+ */
10275
+ function LoneSchemaDefinitionRule(context) {
10276
+ var _ref, _ref2, _oldSchema$astNode;
10277
+
10278
+ const oldSchema = context.getSchema();
10279
+ const alreadyDefined =
10280
+ (_ref =
10281
+ (_ref2 =
10282
+ (_oldSchema$astNode =
10283
+ oldSchema === null || oldSchema === void 0
10284
+ ? void 0
10285
+ : oldSchema.astNode) !== null && _oldSchema$astNode !== void 0
10286
+ ? _oldSchema$astNode
10287
+ : oldSchema === null || oldSchema === void 0
10288
+ ? void 0
10289
+ : oldSchema.getQueryType()) !== null && _ref2 !== void 0
10290
+ ? _ref2
10291
+ : oldSchema === null || oldSchema === void 0
10292
+ ? void 0
10293
+ : oldSchema.getMutationType()) !== null && _ref !== void 0
10294
+ ? _ref
10295
+ : oldSchema === null || oldSchema === void 0
10296
+ ? void 0
10297
+ : oldSchema.getSubscriptionType();
10298
+ let schemaDefinitionsCount = 0;
10299
+ return {
10300
+ SchemaDefinition(node) {
10301
+ if (alreadyDefined) {
10302
+ context.reportError(
10303
+ new GraphQLError(
10304
+ 'Cannot define a new schema within a schema extension.',
10305
+ node,
10306
+ ),
10307
+ );
10308
+ return;
10309
+ }
10310
+
10311
+ if (schemaDefinitionsCount > 0) {
10312
+ context.reportError(
10313
+ new GraphQLError('Must provide only one schema definition.', node),
10314
+ );
10315
+ }
10316
+
10317
+ ++schemaDefinitionsCount;
10318
+ },
10319
+ };
10320
+ }
10321
+
10322
+ /**
10323
+ * Unique operation types
10324
+ *
10325
+ * A GraphQL document is only valid if it has only one type per operation.
10326
+ */
10327
+ function UniqueOperationTypesRule(context) {
10328
+ const schema = context.getSchema();
10329
+ const definedOperationTypes = Object.create(null);
10330
+ const existingOperationTypes = schema
10331
+ ? {
10332
+ query: schema.getQueryType(),
10333
+ mutation: schema.getMutationType(),
10334
+ subscription: schema.getSubscriptionType(),
10335
+ }
10336
+ : {};
10337
+ return {
10338
+ SchemaDefinition: checkOperationTypes,
10339
+ SchemaExtension: checkOperationTypes,
10340
+ };
10341
+
10342
+ function checkOperationTypes(node) {
10343
+ var _node$operationTypes;
10344
+
10345
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
10346
+ const operationTypesNodes =
10347
+ (_node$operationTypes = node.operationTypes) !== null &&
10348
+ _node$operationTypes !== void 0
10349
+ ? _node$operationTypes
10350
+ : [];
10351
+
10352
+ for (const operationType of operationTypesNodes) {
10353
+ const operation = operationType.operation;
10354
+ const alreadyDefinedOperationType = definedOperationTypes[operation];
10355
+
10356
+ if (existingOperationTypes[operation]) {
10357
+ context.reportError(
10358
+ new GraphQLError(
10359
+ `Type for ${operation} already defined in the schema. It cannot be redefined.`,
10360
+ operationType,
10361
+ ),
10362
+ );
10363
+ } else if (alreadyDefinedOperationType) {
10364
+ context.reportError(
10365
+ new GraphQLError(
10366
+ `There can be only one ${operation} type in schema.`,
10367
+ [alreadyDefinedOperationType, operationType],
10368
+ ),
10369
+ );
10370
+ } else {
10371
+ definedOperationTypes[operation] = operationType;
10372
+ }
10373
+ }
10374
+
10375
+ return false;
10376
+ }
10377
+ }
10378
+
10379
+ /**
10380
+ * Unique type names
10381
+ *
10382
+ * A GraphQL document is only valid if all defined types have unique names.
10383
+ */
10384
+ function UniqueTypeNamesRule(context) {
10385
+ const knownTypeNames = Object.create(null);
10386
+ const schema = context.getSchema();
10387
+ return {
10388
+ ScalarTypeDefinition: checkTypeName,
10389
+ ObjectTypeDefinition: checkTypeName,
10390
+ InterfaceTypeDefinition: checkTypeName,
10391
+ UnionTypeDefinition: checkTypeName,
10392
+ EnumTypeDefinition: checkTypeName,
10393
+ InputObjectTypeDefinition: checkTypeName,
10394
+ };
10395
+
10396
+ function checkTypeName(node) {
10397
+ const typeName = node.name.value;
10398
+
10399
+ if (schema !== null && schema !== void 0 && schema.getType(typeName)) {
10400
+ context.reportError(
10401
+ new GraphQLError(
10402
+ `Type "${typeName}" already exists in the schema. It cannot also be defined in this type definition.`,
10403
+ node.name,
10404
+ ),
10405
+ );
10406
+ return;
10407
+ }
10408
+
10409
+ if (knownTypeNames[typeName]) {
10410
+ context.reportError(
10411
+ new GraphQLError(`There can be only one type named "${typeName}".`, [
10412
+ knownTypeNames[typeName],
10413
+ node.name,
10414
+ ]),
10415
+ );
10416
+ } else {
10417
+ knownTypeNames[typeName] = node.name;
10418
+ }
10419
+
10420
+ return false;
10421
+ }
10422
+ }
10423
+
10424
+ /**
10425
+ * Unique enum value names
10426
+ *
10427
+ * A GraphQL enum type is only valid if all its values are uniquely named.
10428
+ */
10429
+ function UniqueEnumValueNamesRule(context) {
10430
+ const schema = context.getSchema();
10431
+ const existingTypeMap = schema ? schema.getTypeMap() : Object.create(null);
10432
+ const knownValueNames = Object.create(null);
10433
+ return {
10434
+ EnumTypeDefinition: checkValueUniqueness,
10435
+ EnumTypeExtension: checkValueUniqueness,
10436
+ };
10437
+
10438
+ function checkValueUniqueness(node) {
10439
+ var _node$values;
10440
+
10441
+ const typeName = node.name.value;
10442
+
10443
+ if (!knownValueNames[typeName]) {
10444
+ knownValueNames[typeName] = Object.create(null);
10445
+ } // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
10446
+
10447
+ const valueNodes =
10448
+ (_node$values = node.values) !== null && _node$values !== void 0
10449
+ ? _node$values
10450
+ : [];
10451
+ const valueNames = knownValueNames[typeName];
10452
+
10453
+ for (const valueDef of valueNodes) {
10454
+ const valueName = valueDef.name.value;
10455
+ const existingType = existingTypeMap[typeName];
10456
+
10457
+ if (isEnumType(existingType) && existingType.getValue(valueName)) {
10458
+ context.reportError(
10459
+ new GraphQLError(
10460
+ `Enum value "${typeName}.${valueName}" already exists in the schema. It cannot also be defined in this type extension.`,
10461
+ valueDef.name,
10462
+ ),
10463
+ );
10464
+ } else if (valueNames[valueName]) {
10465
+ context.reportError(
10466
+ new GraphQLError(
10467
+ `Enum value "${typeName}.${valueName}" can only be defined once.`,
10468
+ [valueNames[valueName], valueDef.name],
10469
+ ),
10470
+ );
10471
+ } else {
10472
+ valueNames[valueName] = valueDef.name;
10473
+ }
10474
+ }
10475
+
10476
+ return false;
10477
+ }
10478
+ }
10479
+
10480
+ /**
10481
+ * Unique field definition names
10482
+ *
10483
+ * A GraphQL complex type is only valid if all its fields are uniquely named.
10484
+ */
10485
+ function UniqueFieldDefinitionNamesRule(context) {
10486
+ const schema = context.getSchema();
10487
+ const existingTypeMap = schema ? schema.getTypeMap() : Object.create(null);
10488
+ const knownFieldNames = Object.create(null);
10489
+ return {
10490
+ InputObjectTypeDefinition: checkFieldUniqueness,
10491
+ InputObjectTypeExtension: checkFieldUniqueness,
10492
+ InterfaceTypeDefinition: checkFieldUniqueness,
10493
+ InterfaceTypeExtension: checkFieldUniqueness,
10494
+ ObjectTypeDefinition: checkFieldUniqueness,
10495
+ ObjectTypeExtension: checkFieldUniqueness,
10496
+ };
10497
+
10498
+ function checkFieldUniqueness(node) {
10499
+ var _node$fields;
10500
+
10501
+ const typeName = node.name.value;
10502
+
10503
+ if (!knownFieldNames[typeName]) {
10504
+ knownFieldNames[typeName] = Object.create(null);
10505
+ } // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
10506
+
10507
+ const fieldNodes =
10508
+ (_node$fields = node.fields) !== null && _node$fields !== void 0
10509
+ ? _node$fields
10510
+ : [];
10511
+ const fieldNames = knownFieldNames[typeName];
10512
+
10513
+ for (const fieldDef of fieldNodes) {
10514
+ const fieldName = fieldDef.name.value;
10515
+
10516
+ if (hasField(existingTypeMap[typeName], fieldName)) {
10517
+ context.reportError(
10518
+ new GraphQLError(
10519
+ `Field "${typeName}.${fieldName}" already exists in the schema. It cannot also be defined in this type extension.`,
10520
+ fieldDef.name,
10521
+ ),
10522
+ );
10523
+ } else if (fieldNames[fieldName]) {
10524
+ context.reportError(
10525
+ new GraphQLError(
10526
+ `Field "${typeName}.${fieldName}" can only be defined once.`,
10527
+ [fieldNames[fieldName], fieldDef.name],
10528
+ ),
10529
+ );
10530
+ } else {
10531
+ fieldNames[fieldName] = fieldDef.name;
10532
+ }
10533
+ }
10534
+
10535
+ return false;
10536
+ }
10537
+ }
10538
+
10539
+ function hasField(type, fieldName) {
10540
+ if (isObjectType(type) || isInterfaceType(type) || isInputObjectType(type)) {
10541
+ return type.getFields()[fieldName] != null;
10542
+ }
10543
+
10544
+ return false;
10545
+ }
10546
+
10547
+ /**
10548
+ * Unique argument definition names
10549
+ *
10550
+ * A GraphQL Object or Interface type is only valid if all its fields have uniquely named arguments.
10551
+ * A GraphQL Directive is only valid if all its arguments are uniquely named.
10552
+ */
10553
+ function UniqueArgumentDefinitionNamesRule(context) {
10554
+ return {
10555
+ DirectiveDefinition(directiveNode) {
10556
+ var _directiveNode$argume;
10557
+
10558
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
10559
+ const argumentNodes =
10560
+ (_directiveNode$argume = directiveNode.arguments) !== null &&
10561
+ _directiveNode$argume !== void 0
10562
+ ? _directiveNode$argume
10563
+ : [];
10564
+ return checkArgUniqueness(`@${directiveNode.name.value}`, argumentNodes);
10565
+ },
10566
+
10567
+ InterfaceTypeDefinition: checkArgUniquenessPerField,
10568
+ InterfaceTypeExtension: checkArgUniquenessPerField,
10569
+ ObjectTypeDefinition: checkArgUniquenessPerField,
10570
+ ObjectTypeExtension: checkArgUniquenessPerField,
10571
+ };
10572
+
10573
+ function checkArgUniquenessPerField(typeNode) {
10574
+ var _typeNode$fields;
10575
+
10576
+ const typeName = typeNode.name.value; // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
10577
+
10578
+ const fieldNodes =
10579
+ (_typeNode$fields = typeNode.fields) !== null &&
10580
+ _typeNode$fields !== void 0
10581
+ ? _typeNode$fields
10582
+ : [];
10583
+
10584
+ for (const fieldDef of fieldNodes) {
10585
+ var _fieldDef$arguments;
10586
+
10587
+ const fieldName = fieldDef.name.value; // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
10588
+
10589
+ const argumentNodes =
10590
+ (_fieldDef$arguments = fieldDef.arguments) !== null &&
10591
+ _fieldDef$arguments !== void 0
10592
+ ? _fieldDef$arguments
10593
+ : [];
10594
+ checkArgUniqueness(`${typeName}.${fieldName}`, argumentNodes);
10595
+ }
10596
+
10597
+ return false;
10598
+ }
10599
+
10600
+ function checkArgUniqueness(parentName, argumentNodes) {
10601
+ const seenArgs = groupBy(argumentNodes, (arg) => arg.name.value);
10602
+
10603
+ for (const [argName, argNodes] of seenArgs) {
10604
+ if (argNodes.length > 1) {
10605
+ context.reportError(
10606
+ new GraphQLError(
10607
+ `Argument "${parentName}(${argName}:)" can only be defined once.`,
10608
+ argNodes.map((node) => node.name),
10609
+ ),
10610
+ );
10611
+ }
10612
+ }
10613
+
10614
+ return false;
10615
+ }
10616
+ }
10617
+
10618
+ /**
10619
+ * Unique directive names
10620
+ *
10621
+ * A GraphQL document is only valid if all defined directives have unique names.
10622
+ */
10623
+ function UniqueDirectiveNamesRule(context) {
10624
+ const knownDirectiveNames = Object.create(null);
10625
+ const schema = context.getSchema();
10626
+ return {
10627
+ DirectiveDefinition(node) {
10628
+ const directiveName = node.name.value;
10629
+
10630
+ if (
10631
+ schema !== null &&
10632
+ schema !== void 0 &&
10633
+ schema.getDirective(directiveName)
10634
+ ) {
10635
+ context.reportError(
10636
+ new GraphQLError(
10637
+ `Directive "@${directiveName}" already exists in the schema. It cannot be redefined.`,
10638
+ node.name,
10639
+ ),
10640
+ );
10641
+ return;
10642
+ }
10643
+
10644
+ if (knownDirectiveNames[directiveName]) {
10645
+ context.reportError(
10646
+ new GraphQLError(
10647
+ `There can be only one directive named "@${directiveName}".`,
10648
+ [knownDirectiveNames[directiveName], node.name],
10649
+ ),
10650
+ );
10651
+ } else {
10652
+ knownDirectiveNames[directiveName] = node.name;
10653
+ }
10654
+
10655
+ return false;
10656
+ },
10657
+ };
10658
+ }
10659
+
10660
+ /**
10661
+ * Possible type extension
10662
+ *
10663
+ * A type extension is only valid if the type is defined and has the same kind.
10664
+ */
10665
+ function PossibleTypeExtensionsRule(context) {
10666
+ const schema = context.getSchema();
10667
+ const definedTypes = Object.create(null);
10668
+
10669
+ for (const def of context.getDocument().definitions) {
10670
+ if (isTypeDefinitionNode(def)) {
10671
+ definedTypes[def.name.value] = def;
10672
+ }
10673
+ }
10674
+
10675
+ return {
10676
+ ScalarTypeExtension: checkExtension,
10677
+ ObjectTypeExtension: checkExtension,
10678
+ InterfaceTypeExtension: checkExtension,
10679
+ UnionTypeExtension: checkExtension,
10680
+ EnumTypeExtension: checkExtension,
10681
+ InputObjectTypeExtension: checkExtension,
10682
+ };
10683
+
10684
+ function checkExtension(node) {
10685
+ const typeName = node.name.value;
10686
+ const defNode = definedTypes[typeName];
10687
+ const existingType =
10688
+ schema === null || schema === void 0 ? void 0 : schema.getType(typeName);
10689
+ let expectedKind;
10690
+
10691
+ if (defNode) {
10692
+ expectedKind = defKindToExtKind[defNode.kind];
10693
+ } else if (existingType) {
10694
+ expectedKind = typeToExtKind(existingType);
10695
+ }
10696
+
10697
+ if (expectedKind) {
10698
+ if (expectedKind !== node.kind) {
10699
+ const kindStr = extensionKindToTypeName(node.kind);
10700
+ context.reportError(
10701
+ new GraphQLError(
10702
+ `Cannot extend non-${kindStr} type "${typeName}".`,
10703
+ defNode ? [defNode, node] : node,
10704
+ ),
10705
+ );
10706
+ }
10707
+ } else {
10708
+ const allTypeNames = Object.keys({
10709
+ ...definedTypes,
10710
+ ...(schema === null || schema === void 0
10711
+ ? void 0
10712
+ : schema.getTypeMap()),
10713
+ });
10714
+ const suggestedTypes = suggestionList(typeName, allTypeNames);
10715
+ context.reportError(
10716
+ new GraphQLError(
10717
+ `Cannot extend type "${typeName}" because it is not defined.` +
10718
+ didYouMean(suggestedTypes),
10719
+ node.name,
10720
+ ),
10721
+ );
10722
+ }
10723
+ }
10724
+ }
10725
+ const defKindToExtKind = {
10726
+ [Kind.SCALAR_TYPE_DEFINITION]: Kind.SCALAR_TYPE_EXTENSION,
10727
+ [Kind.OBJECT_TYPE_DEFINITION]: Kind.OBJECT_TYPE_EXTENSION,
10728
+ [Kind.INTERFACE_TYPE_DEFINITION]: Kind.INTERFACE_TYPE_EXTENSION,
10729
+ [Kind.UNION_TYPE_DEFINITION]: Kind.UNION_TYPE_EXTENSION,
10730
+ [Kind.ENUM_TYPE_DEFINITION]: Kind.ENUM_TYPE_EXTENSION,
10731
+ [Kind.INPUT_OBJECT_TYPE_DEFINITION]: Kind.INPUT_OBJECT_TYPE_EXTENSION,
10732
+ };
10733
+
10734
+ function typeToExtKind(type) {
10735
+ if (isScalarType(type)) {
10736
+ return Kind.SCALAR_TYPE_EXTENSION;
10737
+ }
10738
+
10739
+ if (isObjectType(type)) {
10740
+ return Kind.OBJECT_TYPE_EXTENSION;
10741
+ }
10742
+
10743
+ if (isInterfaceType(type)) {
10744
+ return Kind.INTERFACE_TYPE_EXTENSION;
10745
+ }
10746
+
10747
+ if (isUnionType(type)) {
10748
+ return Kind.UNION_TYPE_EXTENSION;
10749
+ }
10750
+
10751
+ if (isEnumType(type)) {
10752
+ return Kind.ENUM_TYPE_EXTENSION;
10753
+ } // istanbul ignore else (See: 'https://github.com/graphql/graphql-js/issues/2618')
10754
+
10755
+ if (isInputObjectType(type)) {
10756
+ return Kind.INPUT_OBJECT_TYPE_EXTENSION;
10757
+ } // istanbul ignore next (Not reachable. All possible types have been considered)
10758
+
10759
+ invariant(false, 'Unexpected type: ' + inspect(type));
10760
+ }
10761
+
10762
+ function extensionKindToTypeName(kind) {
10763
+ switch (kind) {
10764
+ case Kind.SCALAR_TYPE_EXTENSION:
10765
+ return 'scalar';
10766
+
10767
+ case Kind.OBJECT_TYPE_EXTENSION:
10768
+ return 'object';
10769
+
10770
+ case Kind.INTERFACE_TYPE_EXTENSION:
10771
+ return 'interface';
10772
+
10773
+ case Kind.UNION_TYPE_EXTENSION:
10774
+ return 'union';
10775
+
10776
+ case Kind.ENUM_TYPE_EXTENSION:
10777
+ return 'enum';
10778
+
10779
+ case Kind.INPUT_OBJECT_TYPE_EXTENSION:
10780
+ return 'input object';
10781
+ } // istanbul ignore next (Not reachable. All possible types have been considered)
10782
+
10783
+ invariant(false, 'Unexpected kind: ' + inspect(kind));
10784
+ }
10785
+
10786
+ // Spec Section: "Executable Definitions"
10787
+ /**
10788
+ * This set includes all validation rules defined by the GraphQL spec.
10789
+ *
10790
+ * The order of the rules in this list has been adjusted to lead to the
10791
+ * most clear output when encountering multiple validation errors.
10792
+ */
10793
+
10794
+ const specifiedRules = Object.freeze([
10795
+ ExecutableDefinitionsRule,
10796
+ UniqueOperationNamesRule,
10797
+ LoneAnonymousOperationRule,
10798
+ SingleFieldSubscriptionsRule,
10799
+ KnownTypeNamesRule,
10800
+ FragmentsOnCompositeTypesRule,
10801
+ VariablesAreInputTypesRule,
10802
+ ScalarLeafsRule,
10803
+ FieldsOnCorrectTypeRule,
10804
+ UniqueFragmentNamesRule,
10805
+ KnownFragmentNamesRule,
10806
+ NoUnusedFragmentsRule,
10807
+ PossibleFragmentSpreadsRule,
10808
+ NoFragmentCyclesRule,
10809
+ UniqueVariableNamesRule,
10810
+ NoUndefinedVariablesRule,
10811
+ NoUnusedVariablesRule,
10812
+ KnownDirectivesRule,
10813
+ UniqueDirectivesPerLocationRule,
10814
+ KnownArgumentNamesRule,
10815
+ UniqueArgumentNamesRule,
10816
+ ValuesOfCorrectTypeRule,
10817
+ ProvidedRequiredArgumentsRule,
10818
+ VariablesInAllowedPositionRule,
10819
+ OverlappingFieldsCanBeMergedRule,
10820
+ UniqueInputFieldNamesRule,
10821
+ ]);
10822
+ /**
10823
+ * @internal
10824
+ */
10825
+
10826
+ const specifiedSDLRules = Object.freeze([
10827
+ LoneSchemaDefinitionRule,
10828
+ UniqueOperationTypesRule,
10829
+ UniqueTypeNamesRule,
10830
+ UniqueEnumValueNamesRule,
10831
+ UniqueFieldDefinitionNamesRule,
10832
+ UniqueArgumentDefinitionNamesRule,
10833
+ UniqueDirectiveNamesRule,
10834
+ KnownTypeNamesRule,
10835
+ KnownDirectivesRule,
10836
+ UniqueDirectivesPerLocationRule,
10837
+ PossibleTypeExtensionsRule,
10838
+ KnownArgumentNamesOnDirectivesRule,
10839
+ UniqueArgumentNamesRule,
10840
+ UniqueInputFieldNamesRule,
10841
+ ProvidedRequiredArgumentsOnDirectivesRule,
10842
+ ]);
10843
+
10844
+ /**
10845
+ * An instance of this class is passed as the "this" context to all validators,
10846
+ * allowing access to commonly useful contextual information from within a
10847
+ * validation rule.
10848
+ */
10849
+ class ASTValidationContext {
10850
+ constructor(ast, onError) {
10851
+ this._ast = ast;
10852
+ this._fragments = undefined;
10853
+ this._fragmentSpreads = new Map();
10854
+ this._recursivelyReferencedFragments = new Map();
10855
+ this._onError = onError;
10856
+ }
10857
+
10858
+ get [Symbol.toStringTag]() {
10859
+ return 'ASTValidationContext';
10860
+ }
10861
+
10862
+ reportError(error) {
10863
+ this._onError(error);
10864
+ }
10865
+
10866
+ getDocument() {
10867
+ return this._ast;
10868
+ }
10869
+
10870
+ getFragment(name) {
10871
+ let fragments;
10872
+
10873
+ if (this._fragments) {
10874
+ fragments = this._fragments;
10875
+ } else {
10876
+ fragments = Object.create(null);
10877
+
10878
+ for (const defNode of this.getDocument().definitions) {
10879
+ if (defNode.kind === Kind.FRAGMENT_DEFINITION) {
10880
+ fragments[defNode.name.value] = defNode;
10881
+ }
10882
+ }
10883
+
10884
+ this._fragments = fragments;
10885
+ }
10886
+
10887
+ return fragments[name];
10888
+ }
10889
+
10890
+ getFragmentSpreads(node) {
10891
+ let spreads = this._fragmentSpreads.get(node);
10892
+
10893
+ if (!spreads) {
10894
+ spreads = [];
10895
+ const setsToVisit = [node];
10896
+ let set;
10897
+
10898
+ while ((set = setsToVisit.pop())) {
10899
+ for (const selection of set.selections) {
10900
+ if (selection.kind === Kind.FRAGMENT_SPREAD) {
10901
+ spreads.push(selection);
10902
+ } else if (selection.selectionSet) {
10903
+ setsToVisit.push(selection.selectionSet);
10904
+ }
10905
+ }
10906
+ }
10907
+
10908
+ this._fragmentSpreads.set(node, spreads);
10909
+ }
10910
+
10911
+ return spreads;
10912
+ }
10913
+
10914
+ getRecursivelyReferencedFragments(operation) {
10915
+ let fragments = this._recursivelyReferencedFragments.get(operation);
10916
+
10917
+ if (!fragments) {
10918
+ fragments = [];
10919
+ const collectedNames = Object.create(null);
10920
+ const nodesToVisit = [operation.selectionSet];
10921
+ let node;
10922
+
10923
+ while ((node = nodesToVisit.pop())) {
10924
+ for (const spread of this.getFragmentSpreads(node)) {
10925
+ const fragName = spread.name.value;
10926
+
10927
+ if (collectedNames[fragName] !== true) {
10928
+ collectedNames[fragName] = true;
10929
+ const fragment = this.getFragment(fragName);
10930
+
10931
+ if (fragment) {
10932
+ fragments.push(fragment);
10933
+ nodesToVisit.push(fragment.selectionSet);
10934
+ }
10935
+ }
10936
+ }
10937
+ }
10938
+
10939
+ this._recursivelyReferencedFragments.set(operation, fragments);
10940
+ }
10941
+
10942
+ return fragments;
10943
+ }
10944
+ }
10945
+ class SDLValidationContext extends ASTValidationContext {
10946
+ constructor(ast, schema, onError) {
10947
+ super(ast, onError);
10948
+ this._schema = schema;
10949
+ }
10950
+
10951
+ get [Symbol.toStringTag]() {
10952
+ return 'SDLValidationContext';
10953
+ }
10954
+
10955
+ getSchema() {
10956
+ return this._schema;
10957
+ }
10958
+ }
10959
+
10960
+ /**
10961
+ * @internal
10962
+ */
10963
+
10964
+ function validateSDL(
10965
+ documentAST,
10966
+ schemaToExtend,
10967
+ rules = specifiedSDLRules,
10968
+ ) {
10969
+ const errors = [];
10970
+ const context = new SDLValidationContext(
10971
+ documentAST,
10972
+ schemaToExtend,
10973
+ (error) => {
10974
+ errors.push(error);
10975
+ },
10976
+ );
10977
+ const visitors = rules.map((rule) => rule(context));
10978
+ visit(documentAST, visitInParallel(visitors));
10979
+ return errors;
10980
+ }
10981
+ /**
10982
+ * Utility function which asserts a SDL document is valid by throwing an error
10983
+ * if it is invalid.
10984
+ *
10985
+ * @internal
10986
+ */
10987
+
10988
+ function assertValidSDL(documentAST) {
10989
+ const errors = validateSDL(documentAST);
10990
+
10991
+ if (errors.length !== 0) {
10992
+ throw new Error(errors.map((error) => error.message).join('\n\n'));
10993
+ }
10994
+ }
10995
+
10996
+ /**
10997
+ * Build a GraphQLSchema for use by client tools.
10998
+ *
10999
+ * Given the result of a client running the introspection query, creates and
11000
+ * returns a GraphQLSchema instance which can be then used with all graphql-js
11001
+ * tools, but cannot be used to execute a query, as introspection does not
11002
+ * represent the "resolver", "parse" or "serialize" functions or any other
11003
+ * server-internal mechanisms.
11004
+ *
11005
+ * This function expects a complete introspection result. Don't forget to check
11006
+ * the "errors" field of a server response before calling this function.
11007
+ */
11008
+
11009
+ function buildClientSchema(introspection, options) {
11010
+ (isObjectLike(introspection) && isObjectLike(introspection.__schema)) ||
11011
+ devAssert(
11012
+ false,
11013
+ `Invalid or incomplete introspection result. Ensure that you are passing "data" property of introspection response and no "errors" was returned alongside: ${inspect(
11014
+ introspection,
11015
+ )}.`,
11016
+ ); // Get the schema from the introspection result.
11017
+
11018
+ const schemaIntrospection = introspection.__schema; // Iterate through all types, getting the type definition for each.
11019
+
11020
+ const typeMap = keyValMap(
11021
+ schemaIntrospection.types,
11022
+ (typeIntrospection) => typeIntrospection.name,
11023
+ (typeIntrospection) => buildType(typeIntrospection),
11024
+ ); // Include standard types only if they are used.
11025
+
11026
+ for (const stdType of [...specifiedScalarTypes, ...introspectionTypes]) {
11027
+ if (typeMap[stdType.name]) {
11028
+ typeMap[stdType.name] = stdType;
11029
+ }
11030
+ } // Get the root Query, Mutation, and Subscription types.
11031
+
11032
+ const queryType = schemaIntrospection.queryType
11033
+ ? getObjectType(schemaIntrospection.queryType)
11034
+ : null;
11035
+ const mutationType = schemaIntrospection.mutationType
11036
+ ? getObjectType(schemaIntrospection.mutationType)
11037
+ : null;
11038
+ const subscriptionType = schemaIntrospection.subscriptionType
11039
+ ? getObjectType(schemaIntrospection.subscriptionType)
11040
+ : null; // Get the directives supported by Introspection, assuming empty-set if
11041
+ // directives were not queried for.
11042
+
11043
+ const directives = schemaIntrospection.directives
11044
+ ? schemaIntrospection.directives.map(buildDirective)
11045
+ : []; // Then produce and return a Schema with these types.
11046
+
11047
+ return new GraphQLSchema({
11048
+ description: schemaIntrospection.description,
11049
+ query: queryType,
11050
+ mutation: mutationType,
11051
+ subscription: subscriptionType,
11052
+ types: Object.values(typeMap),
11053
+ directives,
11054
+ assumeValid:
11055
+ options === null || options === void 0 ? void 0 : options.assumeValid,
11056
+ }); // Given a type reference in introspection, return the GraphQLType instance.
11057
+ // preferring cached instances before building new instances.
11058
+
11059
+ function getType(typeRef) {
11060
+ if (typeRef.kind === TypeKind.LIST) {
11061
+ const itemRef = typeRef.ofType;
11062
+
11063
+ if (!itemRef) {
11064
+ throw new Error('Decorated type deeper than introspection query.');
11065
+ }
11066
+
11067
+ return new GraphQLList(getType(itemRef));
11068
+ }
11069
+
11070
+ if (typeRef.kind === TypeKind.NON_NULL) {
11071
+ const nullableRef = typeRef.ofType;
11072
+
11073
+ if (!nullableRef) {
11074
+ throw new Error('Decorated type deeper than introspection query.');
11075
+ }
11076
+
11077
+ const nullableType = getType(nullableRef);
11078
+ return new GraphQLNonNull(assertNullableType(nullableType));
11079
+ }
11080
+
11081
+ return getNamedType(typeRef);
11082
+ }
11083
+
11084
+ function getNamedType(typeRef) {
11085
+ const typeName = typeRef.name;
11086
+
11087
+ if (!typeName) {
11088
+ throw new Error(`Unknown type reference: ${inspect(typeRef)}.`);
11089
+ }
11090
+
11091
+ const type = typeMap[typeName];
11092
+
11093
+ if (!type) {
11094
+ throw new Error(
11095
+ `Invalid or incomplete schema, unknown type: ${typeName}. Ensure that a full introspection query is used in order to build a client schema.`,
11096
+ );
11097
+ }
11098
+
11099
+ return type;
7462
11100
  }
7463
11101
 
7464
11102
  function getObjectType(typeRef) {
@@ -7692,6 +11330,796 @@ function buildClientSchema(introspection, options) {
7692
11330
  }
7693
11331
  }
7694
11332
 
11333
+ /**
11334
+ * @internal
11335
+ */
11336
+
11337
+ function extendSchemaImpl(schemaConfig, documentAST, options) {
11338
+ var _schemaDef, _schemaDef$descriptio, _schemaDef2, _options$assumeValid;
11339
+
11340
+ // Collect the type definitions and extensions found in the document.
11341
+ const typeDefs = [];
11342
+ const typeExtensionsMap = Object.create(null); // New directives and types are separate because a directives and types can
11343
+ // have the same name. For example, a type named "skip".
11344
+
11345
+ const directiveDefs = [];
11346
+ let schemaDef; // Schema extensions are collected which may add additional operation types.
11347
+
11348
+ const schemaExtensions = [];
11349
+
11350
+ for (const def of documentAST.definitions) {
11351
+ if (def.kind === Kind.SCHEMA_DEFINITION) {
11352
+ schemaDef = def;
11353
+ } else if (def.kind === Kind.SCHEMA_EXTENSION) {
11354
+ schemaExtensions.push(def);
11355
+ } else if (isTypeDefinitionNode(def)) {
11356
+ typeDefs.push(def);
11357
+ } else if (isTypeExtensionNode(def)) {
11358
+ const extendedTypeName = def.name.value;
11359
+ const existingTypeExtensions = typeExtensionsMap[extendedTypeName];
11360
+ typeExtensionsMap[extendedTypeName] = existingTypeExtensions
11361
+ ? existingTypeExtensions.concat([def])
11362
+ : [def];
11363
+ } else if (def.kind === Kind.DIRECTIVE_DEFINITION) {
11364
+ directiveDefs.push(def);
11365
+ }
11366
+ } // If this document contains no new types, extensions, or directives then
11367
+ // return the same unmodified GraphQLSchema instance.
11368
+
11369
+ if (
11370
+ Object.keys(typeExtensionsMap).length === 0 &&
11371
+ typeDefs.length === 0 &&
11372
+ directiveDefs.length === 0 &&
11373
+ schemaExtensions.length === 0 &&
11374
+ schemaDef == null
11375
+ ) {
11376
+ return schemaConfig;
11377
+ }
11378
+
11379
+ const typeMap = Object.create(null);
11380
+
11381
+ for (const existingType of schemaConfig.types) {
11382
+ typeMap[existingType.name] = extendNamedType(existingType);
11383
+ }
11384
+
11385
+ for (const typeNode of typeDefs) {
11386
+ var _stdTypeMap$name;
11387
+
11388
+ const name = typeNode.name.value;
11389
+ typeMap[name] =
11390
+ (_stdTypeMap$name = stdTypeMap[name]) !== null &&
11391
+ _stdTypeMap$name !== void 0
11392
+ ? _stdTypeMap$name
11393
+ : buildType(typeNode);
11394
+ }
11395
+
11396
+ const operationTypes = {
11397
+ // Get the extended root operation types.
11398
+ query: schemaConfig.query && replaceNamedType(schemaConfig.query),
11399
+ mutation: schemaConfig.mutation && replaceNamedType(schemaConfig.mutation),
11400
+ subscription:
11401
+ schemaConfig.subscription && replaceNamedType(schemaConfig.subscription),
11402
+ // Then, incorporate schema definition and all schema extensions.
11403
+ ...(schemaDef && getOperationTypes([schemaDef])),
11404
+ ...getOperationTypes(schemaExtensions),
11405
+ }; // Then produce and return a Schema config with these types.
11406
+
11407
+ return {
11408
+ description:
11409
+ (_schemaDef = schemaDef) === null || _schemaDef === void 0
11410
+ ? void 0
11411
+ : (_schemaDef$descriptio = _schemaDef.description) === null ||
11412
+ _schemaDef$descriptio === void 0
11413
+ ? void 0
11414
+ : _schemaDef$descriptio.value,
11415
+ ...operationTypes,
11416
+ types: Object.values(typeMap),
11417
+ directives: [
11418
+ ...schemaConfig.directives.map(replaceDirective),
11419
+ ...directiveDefs.map(buildDirective),
11420
+ ],
11421
+ extensions: Object.create(null),
11422
+ astNode:
11423
+ (_schemaDef2 = schemaDef) !== null && _schemaDef2 !== void 0
11424
+ ? _schemaDef2
11425
+ : schemaConfig.astNode,
11426
+ extensionASTNodes: schemaConfig.extensionASTNodes.concat(schemaExtensions),
11427
+ assumeValid:
11428
+ (_options$assumeValid =
11429
+ options === null || options === void 0
11430
+ ? void 0
11431
+ : options.assumeValid) !== null && _options$assumeValid !== void 0
11432
+ ? _options$assumeValid
11433
+ : false,
11434
+ }; // Below are functions used for producing this schema that have closed over
11435
+ // this scope and have access to the schema, cache, and newly defined types.
11436
+
11437
+ function replaceType(type) {
11438
+ if (isListType(type)) {
11439
+ // @ts-expect-error
11440
+ return new GraphQLList(replaceType(type.ofType));
11441
+ }
11442
+
11443
+ if (isNonNullType(type)) {
11444
+ // @ts-expect-error
11445
+ return new GraphQLNonNull(replaceType(type.ofType));
11446
+ } // @ts-expect-error FIXME
11447
+
11448
+ return replaceNamedType(type);
11449
+ }
11450
+
11451
+ function replaceNamedType(type) {
11452
+ // Note: While this could make early assertions to get the correctly
11453
+ // typed values, that would throw immediately while type system
11454
+ // validation with validateSchema() will produce more actionable results.
11455
+ return typeMap[type.name];
11456
+ }
11457
+
11458
+ function replaceDirective(directive) {
11459
+ const config = directive.toConfig();
11460
+ return new GraphQLDirective({
11461
+ ...config,
11462
+ args: mapValue(config.args, extendArg),
11463
+ });
11464
+ }
11465
+
11466
+ function extendNamedType(type) {
11467
+ if (isIntrospectionType(type) || isSpecifiedScalarType(type)) {
11468
+ // Builtin types are not extended.
11469
+ return type;
11470
+ }
11471
+
11472
+ if (isScalarType(type)) {
11473
+ return extendScalarType(type);
11474
+ }
11475
+
11476
+ if (isObjectType(type)) {
11477
+ return extendObjectType(type);
11478
+ }
11479
+
11480
+ if (isInterfaceType(type)) {
11481
+ return extendInterfaceType(type);
11482
+ }
11483
+
11484
+ if (isUnionType(type)) {
11485
+ return extendUnionType(type);
11486
+ }
11487
+
11488
+ if (isEnumType(type)) {
11489
+ return extendEnumType(type);
11490
+ } // istanbul ignore else (See: 'https://github.com/graphql/graphql-js/issues/2618')
11491
+
11492
+ if (isInputObjectType(type)) {
11493
+ return extendInputObjectType(type);
11494
+ } // istanbul ignore next (Not reachable. All possible types have been considered)
11495
+
11496
+ invariant(false, 'Unexpected type: ' + inspect(type));
11497
+ }
11498
+
11499
+ function extendInputObjectType(type) {
11500
+ var _typeExtensionsMap$co;
11501
+
11502
+ const config = type.toConfig();
11503
+ const extensions =
11504
+ (_typeExtensionsMap$co = typeExtensionsMap[config.name]) !== null &&
11505
+ _typeExtensionsMap$co !== void 0
11506
+ ? _typeExtensionsMap$co
11507
+ : [];
11508
+ return new GraphQLInputObjectType({
11509
+ ...config,
11510
+ fields: () => ({
11511
+ ...mapValue(config.fields, (field) => ({
11512
+ ...field,
11513
+ type: replaceType(field.type),
11514
+ })),
11515
+ ...buildInputFieldMap(extensions),
11516
+ }),
11517
+ extensionASTNodes: config.extensionASTNodes.concat(extensions),
11518
+ });
11519
+ }
11520
+
11521
+ function extendEnumType(type) {
11522
+ var _typeExtensionsMap$ty;
11523
+
11524
+ const config = type.toConfig();
11525
+ const extensions =
11526
+ (_typeExtensionsMap$ty = typeExtensionsMap[type.name]) !== null &&
11527
+ _typeExtensionsMap$ty !== void 0
11528
+ ? _typeExtensionsMap$ty
11529
+ : [];
11530
+ return new GraphQLEnumType({
11531
+ ...config,
11532
+ values: { ...config.values, ...buildEnumValueMap(extensions) },
11533
+ extensionASTNodes: config.extensionASTNodes.concat(extensions),
11534
+ });
11535
+ }
11536
+
11537
+ function extendScalarType(type) {
11538
+ var _typeExtensionsMap$co2;
11539
+
11540
+ const config = type.toConfig();
11541
+ const extensions =
11542
+ (_typeExtensionsMap$co2 = typeExtensionsMap[config.name]) !== null &&
11543
+ _typeExtensionsMap$co2 !== void 0
11544
+ ? _typeExtensionsMap$co2
11545
+ : [];
11546
+ let specifiedByURL = config.specifiedByURL;
11547
+
11548
+ for (const extensionNode of extensions) {
11549
+ var _getSpecifiedByURL;
11550
+
11551
+ specifiedByURL =
11552
+ (_getSpecifiedByURL = getSpecifiedByURL(extensionNode)) !== null &&
11553
+ _getSpecifiedByURL !== void 0
11554
+ ? _getSpecifiedByURL
11555
+ : specifiedByURL;
11556
+ }
11557
+
11558
+ return new GraphQLScalarType({
11559
+ ...config,
11560
+ specifiedByURL,
11561
+ extensionASTNodes: config.extensionASTNodes.concat(extensions),
11562
+ });
11563
+ }
11564
+
11565
+ function extendObjectType(type) {
11566
+ var _typeExtensionsMap$co3;
11567
+
11568
+ const config = type.toConfig();
11569
+ const extensions =
11570
+ (_typeExtensionsMap$co3 = typeExtensionsMap[config.name]) !== null &&
11571
+ _typeExtensionsMap$co3 !== void 0
11572
+ ? _typeExtensionsMap$co3
11573
+ : [];
11574
+ return new GraphQLObjectType({
11575
+ ...config,
11576
+ interfaces: () => [
11577
+ ...type.getInterfaces().map(replaceNamedType),
11578
+ ...buildInterfaces(extensions),
11579
+ ],
11580
+ fields: () => ({
11581
+ ...mapValue(config.fields, extendField),
11582
+ ...buildFieldMap(extensions),
11583
+ }),
11584
+ extensionASTNodes: config.extensionASTNodes.concat(extensions),
11585
+ });
11586
+ }
11587
+
11588
+ function extendInterfaceType(type) {
11589
+ var _typeExtensionsMap$co4;
11590
+
11591
+ const config = type.toConfig();
11592
+ const extensions =
11593
+ (_typeExtensionsMap$co4 = typeExtensionsMap[config.name]) !== null &&
11594
+ _typeExtensionsMap$co4 !== void 0
11595
+ ? _typeExtensionsMap$co4
11596
+ : [];
11597
+ return new GraphQLInterfaceType({
11598
+ ...config,
11599
+ interfaces: () => [
11600
+ ...type.getInterfaces().map(replaceNamedType),
11601
+ ...buildInterfaces(extensions),
11602
+ ],
11603
+ fields: () => ({
11604
+ ...mapValue(config.fields, extendField),
11605
+ ...buildFieldMap(extensions),
11606
+ }),
11607
+ extensionASTNodes: config.extensionASTNodes.concat(extensions),
11608
+ });
11609
+ }
11610
+
11611
+ function extendUnionType(type) {
11612
+ var _typeExtensionsMap$co5;
11613
+
11614
+ const config = type.toConfig();
11615
+ const extensions =
11616
+ (_typeExtensionsMap$co5 = typeExtensionsMap[config.name]) !== null &&
11617
+ _typeExtensionsMap$co5 !== void 0
11618
+ ? _typeExtensionsMap$co5
11619
+ : [];
11620
+ return new GraphQLUnionType({
11621
+ ...config,
11622
+ types: () => [
11623
+ ...type.getTypes().map(replaceNamedType),
11624
+ ...buildUnionTypes(extensions),
11625
+ ],
11626
+ extensionASTNodes: config.extensionASTNodes.concat(extensions),
11627
+ });
11628
+ }
11629
+
11630
+ function extendField(field) {
11631
+ return {
11632
+ ...field,
11633
+ type: replaceType(field.type),
11634
+ args: field.args && mapValue(field.args, extendArg),
11635
+ };
11636
+ }
11637
+
11638
+ function extendArg(arg) {
11639
+ return { ...arg, type: replaceType(arg.type) };
11640
+ }
11641
+
11642
+ function getOperationTypes(nodes) {
11643
+ const opTypes = {};
11644
+
11645
+ for (const node of nodes) {
11646
+ var _node$operationTypes;
11647
+
11648
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
11649
+ const operationTypesNodes =
11650
+ (_node$operationTypes = node.operationTypes) !== null &&
11651
+ _node$operationTypes !== void 0
11652
+ ? _node$operationTypes
11653
+ : [];
11654
+
11655
+ for (const operationType of operationTypesNodes) {
11656
+ // Note: While this could make early assertions to get the correctly
11657
+ // typed values below, that would throw immediately while type system
11658
+ // validation with validateSchema() will produce more actionable results.
11659
+ // @ts-expect-error
11660
+ opTypes[operationType.operation] = getNamedType(operationType.type);
11661
+ }
11662
+ }
11663
+
11664
+ return opTypes;
11665
+ }
11666
+
11667
+ function getNamedType(node) {
11668
+ var _stdTypeMap$name2;
11669
+
11670
+ const name = node.name.value;
11671
+ const type =
11672
+ (_stdTypeMap$name2 = stdTypeMap[name]) !== null &&
11673
+ _stdTypeMap$name2 !== void 0
11674
+ ? _stdTypeMap$name2
11675
+ : typeMap[name];
11676
+
11677
+ if (type === undefined) {
11678
+ throw new Error(`Unknown type: "${name}".`);
11679
+ }
11680
+
11681
+ return type;
11682
+ }
11683
+
11684
+ function getWrappedType(node) {
11685
+ if (node.kind === Kind.LIST_TYPE) {
11686
+ return new GraphQLList(getWrappedType(node.type));
11687
+ }
11688
+
11689
+ if (node.kind === Kind.NON_NULL_TYPE) {
11690
+ return new GraphQLNonNull(getWrappedType(node.type));
11691
+ }
11692
+
11693
+ return getNamedType(node);
11694
+ }
11695
+
11696
+ function buildDirective(node) {
11697
+ var _node$description;
11698
+
11699
+ return new GraphQLDirective({
11700
+ name: node.name.value,
11701
+ description:
11702
+ (_node$description = node.description) === null ||
11703
+ _node$description === void 0
11704
+ ? void 0
11705
+ : _node$description.value,
11706
+ // @ts-expect-error
11707
+ locations: node.locations.map(({ value }) => value),
11708
+ isRepeatable: node.repeatable,
11709
+ args: buildArgumentMap(node.arguments),
11710
+ astNode: node,
11711
+ });
11712
+ }
11713
+
11714
+ function buildFieldMap(nodes) {
11715
+ const fieldConfigMap = Object.create(null);
11716
+
11717
+ for (const node of nodes) {
11718
+ var _node$fields;
11719
+
11720
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
11721
+ const nodeFields =
11722
+ (_node$fields = node.fields) !== null && _node$fields !== void 0
11723
+ ? _node$fields
11724
+ : [];
11725
+
11726
+ for (const field of nodeFields) {
11727
+ var _field$description;
11728
+
11729
+ fieldConfigMap[field.name.value] = {
11730
+ // Note: While this could make assertions to get the correctly typed
11731
+ // value, that would throw immediately while type system validation
11732
+ // with validateSchema() will produce more actionable results.
11733
+ type: getWrappedType(field.type),
11734
+ description:
11735
+ (_field$description = field.description) === null ||
11736
+ _field$description === void 0
11737
+ ? void 0
11738
+ : _field$description.value,
11739
+ args: buildArgumentMap(field.arguments),
11740
+ deprecationReason: getDeprecationReason(field),
11741
+ astNode: field,
11742
+ };
11743
+ }
11744
+ }
11745
+
11746
+ return fieldConfigMap;
11747
+ }
11748
+
11749
+ function buildArgumentMap(args) {
11750
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
11751
+ const argsNodes = args !== null && args !== void 0 ? args : [];
11752
+ const argConfigMap = Object.create(null);
11753
+
11754
+ for (const arg of argsNodes) {
11755
+ var _arg$description;
11756
+
11757
+ // Note: While this could make assertions to get the correctly typed
11758
+ // value, that would throw immediately while type system validation
11759
+ // with validateSchema() will produce more actionable results.
11760
+ const type = getWrappedType(arg.type);
11761
+ argConfigMap[arg.name.value] = {
11762
+ type,
11763
+ description:
11764
+ (_arg$description = arg.description) === null ||
11765
+ _arg$description === void 0
11766
+ ? void 0
11767
+ : _arg$description.value,
11768
+ defaultValue: valueFromAST(arg.defaultValue, type),
11769
+ deprecationReason: getDeprecationReason(arg),
11770
+ astNode: arg,
11771
+ };
11772
+ }
11773
+
11774
+ return argConfigMap;
11775
+ }
11776
+
11777
+ function buildInputFieldMap(nodes) {
11778
+ const inputFieldMap = Object.create(null);
11779
+
11780
+ for (const node of nodes) {
11781
+ var _node$fields2;
11782
+
11783
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
11784
+ const fieldsNodes =
11785
+ (_node$fields2 = node.fields) !== null && _node$fields2 !== void 0
11786
+ ? _node$fields2
11787
+ : [];
11788
+
11789
+ for (const field of fieldsNodes) {
11790
+ var _field$description2;
11791
+
11792
+ // Note: While this could make assertions to get the correctly typed
11793
+ // value, that would throw immediately while type system validation
11794
+ // with validateSchema() will produce more actionable results.
11795
+ const type = getWrappedType(field.type);
11796
+ inputFieldMap[field.name.value] = {
11797
+ type,
11798
+ description:
11799
+ (_field$description2 = field.description) === null ||
11800
+ _field$description2 === void 0
11801
+ ? void 0
11802
+ : _field$description2.value,
11803
+ defaultValue: valueFromAST(field.defaultValue, type),
11804
+ deprecationReason: getDeprecationReason(field),
11805
+ astNode: field,
11806
+ };
11807
+ }
11808
+ }
11809
+
11810
+ return inputFieldMap;
11811
+ }
11812
+
11813
+ function buildEnumValueMap(nodes) {
11814
+ const enumValueMap = Object.create(null);
11815
+
11816
+ for (const node of nodes) {
11817
+ var _node$values;
11818
+
11819
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
11820
+ const valuesNodes =
11821
+ (_node$values = node.values) !== null && _node$values !== void 0
11822
+ ? _node$values
11823
+ : [];
11824
+
11825
+ for (const value of valuesNodes) {
11826
+ var _value$description;
11827
+
11828
+ enumValueMap[value.name.value] = {
11829
+ description:
11830
+ (_value$description = value.description) === null ||
11831
+ _value$description === void 0
11832
+ ? void 0
11833
+ : _value$description.value,
11834
+ deprecationReason: getDeprecationReason(value),
11835
+ astNode: value,
11836
+ };
11837
+ }
11838
+ }
11839
+
11840
+ return enumValueMap;
11841
+ }
11842
+
11843
+ function buildInterfaces(nodes) {
11844
+ // Note: While this could make assertions to get the correctly typed
11845
+ // values below, that would throw immediately while type system
11846
+ // validation with validateSchema() will produce more actionable results.
11847
+ // @ts-expect-error
11848
+ return nodes.flatMap(
11849
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
11850
+ (node) => {
11851
+ var _node$interfaces$map, _node$interfaces;
11852
+
11853
+ return (_node$interfaces$map =
11854
+ (_node$interfaces = node.interfaces) === null ||
11855
+ _node$interfaces === void 0
11856
+ ? void 0
11857
+ : _node$interfaces.map(getNamedType)) !== null &&
11858
+ _node$interfaces$map !== void 0
11859
+ ? _node$interfaces$map
11860
+ : [];
11861
+ },
11862
+ );
11863
+ }
11864
+
11865
+ function buildUnionTypes(nodes) {
11866
+ // Note: While this could make assertions to get the correctly typed
11867
+ // values below, that would throw immediately while type system
11868
+ // validation with validateSchema() will produce more actionable results.
11869
+ // @ts-expect-error
11870
+ return nodes.flatMap(
11871
+ // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2203')
11872
+ (node) => {
11873
+ var _node$types$map, _node$types;
11874
+
11875
+ return (_node$types$map =
11876
+ (_node$types = node.types) === null || _node$types === void 0
11877
+ ? void 0
11878
+ : _node$types.map(getNamedType)) !== null &&
11879
+ _node$types$map !== void 0
11880
+ ? _node$types$map
11881
+ : [];
11882
+ },
11883
+ );
11884
+ }
11885
+
11886
+ function buildType(astNode) {
11887
+ var _typeExtensionsMap$na;
11888
+
11889
+ const name = astNode.name.value;
11890
+ const extensionASTNodes =
11891
+ (_typeExtensionsMap$na = typeExtensionsMap[name]) !== null &&
11892
+ _typeExtensionsMap$na !== void 0
11893
+ ? _typeExtensionsMap$na
11894
+ : [];
11895
+
11896
+ switch (astNode.kind) {
11897
+ case Kind.OBJECT_TYPE_DEFINITION: {
11898
+ var _astNode$description;
11899
+
11900
+ const allNodes = [astNode, ...extensionASTNodes];
11901
+ return new GraphQLObjectType({
11902
+ name,
11903
+ description:
11904
+ (_astNode$description = astNode.description) === null ||
11905
+ _astNode$description === void 0
11906
+ ? void 0
11907
+ : _astNode$description.value,
11908
+ interfaces: () => buildInterfaces(allNodes),
11909
+ fields: () => buildFieldMap(allNodes),
11910
+ astNode,
11911
+ extensionASTNodes,
11912
+ });
11913
+ }
11914
+
11915
+ case Kind.INTERFACE_TYPE_DEFINITION: {
11916
+ var _astNode$description2;
11917
+
11918
+ const allNodes = [astNode, ...extensionASTNodes];
11919
+ return new GraphQLInterfaceType({
11920
+ name,
11921
+ description:
11922
+ (_astNode$description2 = astNode.description) === null ||
11923
+ _astNode$description2 === void 0
11924
+ ? void 0
11925
+ : _astNode$description2.value,
11926
+ interfaces: () => buildInterfaces(allNodes),
11927
+ fields: () => buildFieldMap(allNodes),
11928
+ astNode,
11929
+ extensionASTNodes,
11930
+ });
11931
+ }
11932
+
11933
+ case Kind.ENUM_TYPE_DEFINITION: {
11934
+ var _astNode$description3;
11935
+
11936
+ const allNodes = [astNode, ...extensionASTNodes];
11937
+ return new GraphQLEnumType({
11938
+ name,
11939
+ description:
11940
+ (_astNode$description3 = astNode.description) === null ||
11941
+ _astNode$description3 === void 0
11942
+ ? void 0
11943
+ : _astNode$description3.value,
11944
+ values: buildEnumValueMap(allNodes),
11945
+ astNode,
11946
+ extensionASTNodes,
11947
+ });
11948
+ }
11949
+
11950
+ case Kind.UNION_TYPE_DEFINITION: {
11951
+ var _astNode$description4;
11952
+
11953
+ const allNodes = [astNode, ...extensionASTNodes];
11954
+ return new GraphQLUnionType({
11955
+ name,
11956
+ description:
11957
+ (_astNode$description4 = astNode.description) === null ||
11958
+ _astNode$description4 === void 0
11959
+ ? void 0
11960
+ : _astNode$description4.value,
11961
+ types: () => buildUnionTypes(allNodes),
11962
+ astNode,
11963
+ extensionASTNodes,
11964
+ });
11965
+ }
11966
+
11967
+ case Kind.SCALAR_TYPE_DEFINITION: {
11968
+ var _astNode$description5;
11969
+
11970
+ return new GraphQLScalarType({
11971
+ name,
11972
+ description:
11973
+ (_astNode$description5 = astNode.description) === null ||
11974
+ _astNode$description5 === void 0
11975
+ ? void 0
11976
+ : _astNode$description5.value,
11977
+ specifiedByURL: getSpecifiedByURL(astNode),
11978
+ astNode,
11979
+ extensionASTNodes,
11980
+ });
11981
+ }
11982
+
11983
+ case Kind.INPUT_OBJECT_TYPE_DEFINITION: {
11984
+ var _astNode$description6;
11985
+
11986
+ const allNodes = [astNode, ...extensionASTNodes];
11987
+ return new GraphQLInputObjectType({
11988
+ name,
11989
+ description:
11990
+ (_astNode$description6 = astNode.description) === null ||
11991
+ _astNode$description6 === void 0
11992
+ ? void 0
11993
+ : _astNode$description6.value,
11994
+ fields: () => buildInputFieldMap(allNodes),
11995
+ astNode,
11996
+ extensionASTNodes,
11997
+ });
11998
+ }
11999
+ } // istanbul ignore next (Not reachable. All possible type definition nodes have been considered)
12000
+
12001
+
12002
+ invariant(false, 'Unexpected type definition node: ' + inspect(astNode));
12003
+ }
12004
+ }
12005
+ const stdTypeMap = keyMap(
12006
+ [...specifiedScalarTypes, ...introspectionTypes],
12007
+ (type) => type.name,
12008
+ );
12009
+ /**
12010
+ * Given a field or enum value node, returns the string value for the
12011
+ * deprecation reason.
12012
+ */
12013
+
12014
+ function getDeprecationReason(node) {
12015
+ const deprecated = getDirectiveValues(GraphQLDeprecatedDirective, node); // @ts-expect-error validated by `getDirectiveValues`
12016
+
12017
+ return deprecated === null || deprecated === void 0
12018
+ ? void 0
12019
+ : deprecated.reason;
12020
+ }
12021
+ /**
12022
+ * Given a scalar node, returns the string value for the specifiedByURL.
12023
+ */
12024
+
12025
+ function getSpecifiedByURL(node) {
12026
+ const specifiedBy = getDirectiveValues(GraphQLSpecifiedByDirective, node); // @ts-expect-error validated by `getDirectiveValues`
12027
+
12028
+ return specifiedBy === null || specifiedBy === void 0
12029
+ ? void 0
12030
+ : specifiedBy.url;
12031
+ }
12032
+
12033
+ /**
12034
+ * This takes the ast of a schema document produced by the parse function in
12035
+ * src/language/parser.js.
12036
+ *
12037
+ * If no schema definition is provided, then it will look for types named Query,
12038
+ * Mutation and Subscription.
12039
+ *
12040
+ * Given that AST it constructs a GraphQLSchema. The resulting schema
12041
+ * has no resolve methods, so execution will use default resolvers.
12042
+ */
12043
+ function buildASTSchema(documentAST, options) {
12044
+ (documentAST != null && documentAST.kind === Kind.DOCUMENT) ||
12045
+ devAssert(false, 'Must provide valid Document AST.');
12046
+
12047
+ if (
12048
+ (options === null || options === void 0 ? void 0 : options.assumeValid) !==
12049
+ true &&
12050
+ (options === null || options === void 0
12051
+ ? void 0
12052
+ : options.assumeValidSDL) !== true
12053
+ ) {
12054
+ assertValidSDL(documentAST);
12055
+ }
12056
+
12057
+ const emptySchemaConfig = {
12058
+ description: undefined,
12059
+ types: [],
12060
+ directives: [],
12061
+ extensions: Object.create(null),
12062
+ extensionASTNodes: [],
12063
+ assumeValid: false,
12064
+ };
12065
+ const config = extendSchemaImpl(emptySchemaConfig, documentAST, options);
12066
+
12067
+ if (config.astNode == null) {
12068
+ for (const type of config.types) {
12069
+ switch (type.name) {
12070
+ // Note: While this could make early assertions to get the correctly
12071
+ // typed values below, that would throw immediately while type system
12072
+ // validation with validateSchema() will produce more actionable results.
12073
+ case 'Query':
12074
+ // @ts-expect-error validated in `validateSchema`
12075
+ config.query = type;
12076
+ break;
12077
+
12078
+ case 'Mutation':
12079
+ // @ts-expect-error validated in `validateSchema`
12080
+ config.mutation = type;
12081
+ break;
12082
+
12083
+ case 'Subscription':
12084
+ // @ts-expect-error validated in `validateSchema`
12085
+ config.subscription = type;
12086
+ break;
12087
+ }
12088
+ }
12089
+ }
12090
+
12091
+ const directives = [
12092
+ ...config.directives, // If specified directives were not explicitly declared, add them.
12093
+ ...specifiedDirectives.filter((stdDirective) =>
12094
+ config.directives.every(
12095
+ (directive) => directive.name !== stdDirective.name,
12096
+ ),
12097
+ ),
12098
+ ];
12099
+ return new GraphQLSchema({ ...config, directives });
12100
+ }
12101
+ /**
12102
+ * A helper function to build a GraphQLSchema directly from a source
12103
+ * document.
12104
+ */
12105
+
12106
+ function buildSchema(source, options) {
12107
+ const document = parse(source, {
12108
+ noLocation:
12109
+ options === null || options === void 0 ? void 0 : options.noLocation,
12110
+ allowLegacyFragmentVariables:
12111
+ options === null || options === void 0
12112
+ ? void 0
12113
+ : options.allowLegacyFragmentVariables,
12114
+ });
12115
+ return buildASTSchema(document, {
12116
+ assumeValidSDL:
12117
+ options === null || options === void 0 ? void 0 : options.assumeValidSDL,
12118
+ assumeValid:
12119
+ options === null || options === void 0 ? void 0 : options.assumeValid,
12120
+ });
12121
+ }
12122
+
7695
12123
  function printSchema(schema) {
7696
12124
  return printFilteredSchema(
7697
12125
  schema,
@@ -8085,7 +12513,7 @@ function run() {
8085
12513
  let newSchema;
8086
12514
  let sources;
8087
12515
  if (extname(schemaPath.toLowerCase()) === ".json") {
8088
- oldSchema = buildClientSchema(JSON.parse(oldFile));
12516
+ oldSchema = endpoint ? buildSchema(oldFile) : buildClientSchema(JSON.parse(oldFile));
8089
12517
  newSchema = buildClientSchema(JSON.parse(newFile));
8090
12518
  sources = {
8091
12519
  old: new Source(printSchema(oldSchema), endpoint || `${schemaRef}:${schemaPath}`),
@@ -8120,7 +12548,8 @@ function run() {
8120
12548
  ? (_c = context.payload.pull_request.labels) === null || _c === void 0 ? void 0 : _c.some((label) => label.name === approveLabel)
8121
12549
  : false;
8122
12550
  // Force Success when failOnBreaking is disabled
8123
- if ((failOnBreaking === false || hasApprovedBreakingChangeLabel) && conclusion === CheckConclusion.Failure) {
12551
+ if ((failOnBreaking === false || hasApprovedBreakingChangeLabel) &&
12552
+ conclusion === CheckConclusion.Failure) {
8124
12553
  info('FailOnBreaking disabled. Forcing SUCCESS');
8125
12554
  conclusion = CheckConclusion.Success;
8126
12555
  }
@@ -8157,6 +12586,8 @@ function fileLoader({ octokit, owner, repo, }) {
8157
12586
  repository(name: $repo, owner: $owner) {
8158
12587
  object(expression: $expression) {
8159
12588
  ... on Blob {
12589
+ isTruncated
12590
+ oid
8160
12591
  text
8161
12592
  }
8162
12593
  }
@@ -8164,7 +12595,7 @@ function fileLoader({ octokit, owner, repo, }) {
8164
12595
  }
8165
12596
  `;
8166
12597
  return function loadFile(file) {
8167
- var _a, _b;
12598
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
8168
12599
  return __awaiter(this, void 0, void 0, function* () {
8169
12600
  if (file.workspace) {
8170
12601
  return readFileSync(resolve(file.workspace, file.path), {
@@ -8178,8 +12609,23 @@ function fileLoader({ octokit, owner, repo, }) {
8178
12609
  });
8179
12610
  info(`Query ${file.ref}:${file.path} from ${owner}/${repo}`);
8180
12611
  try {
8181
- if ((_b = (_a = result === null || result === void 0 ? void 0 : result.repository) === null || _a === void 0 ? void 0 : _a.object) === null || _b === void 0 ? void 0 : _b.text) {
8182
- return result.repository.object.text;
12612
+ if (((_b = (_a = result === null || result === void 0 ? void 0 : result.repository) === null || _a === void 0 ? void 0 : _a.object) === null || _b === void 0 ? void 0 : _b.oid) && ((_d = (_c = result === null || result === void 0 ? void 0 : result.repository) === null || _c === void 0 ? void 0 : _c.object) === null || _d === void 0 ? void 0 : _d.isTruncated)) {
12613
+ const oid = (_f = (_e = result === null || result === void 0 ? void 0 : result.repository) === null || _e === void 0 ? void 0 : _e.object) === null || _f === void 0 ? void 0 : _f.oid;
12614
+ const getBlobResponse = yield octokit.git.getBlob({
12615
+ owner,
12616
+ repo,
12617
+ file_sha: oid,
12618
+ });
12619
+ if ((_g = getBlobResponse === null || getBlobResponse === void 0 ? void 0 : getBlobResponse.data) === null || _g === void 0 ? void 0 : _g.content) {
12620
+ return Buffer.from((_h = getBlobResponse === null || getBlobResponse === void 0 ? void 0 : getBlobResponse.data) === null || _h === void 0 ? void 0 : _h.content, 'base64').toString('utf-8');
12621
+ }
12622
+ throw new Error('getBlobResponse.data.content is null');
12623
+ }
12624
+ if ((_k = (_j = result === null || result === void 0 ? void 0 : result.repository) === null || _j === void 0 ? void 0 : _j.object) === null || _k === void 0 ? void 0 : _k.text) {
12625
+ if (((_m = (_l = result === null || result === void 0 ? void 0 : result.repository) === null || _l === void 0 ? void 0 : _l.object) === null || _m === void 0 ? void 0 : _m.isTruncated) === false) {
12626
+ return result.repository.object.text;
12627
+ }
12628
+ throw new Error('result.repository.object.text is truncated and oid is null');
8183
12629
  }
8184
12630
  throw new Error('result.repository.object.text is null');
8185
12631
  }
@@ -8198,7 +12644,8 @@ function updateCheckRun(octokit, checkId, { conclusion, output }) {
8198
12644
  const batches = batch(annotations, 50);
8199
12645
  info(`annotations to be sent: ${annotations.length}`);
8200
12646
  yield octokit.checks.update(Object.assign(Object.assign({ check_run_id: checkId, completed_at: new Date().toISOString(), status: 'completed' }, context.repo), { conclusion, output: {
8201
- title, summary
12647
+ title,
12648
+ summary,
8202
12649
  } }));
8203
12650
  try {
8204
12651
  yield Promise.all(batches.map((chunk) => __awaiter(this, void 0, void 0, function* () {