graphql
Version:
A Query Language and Runtime which can target any service.
1 lines • 5.3 kB
Source Map (JSON)
{"version":3,"file":"PossibleFragmentSpreadsRule.js","sourceRoot":"","sources":["../../../src/validation/rules/PossibleFragmentSpreadsRule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,kCAAiC;AAGnD,OAAO,EAAE,YAAY,EAAE,qCAAoC;AAK3D,OAAO,EAAE,eAAe,EAAE,kCAAiC;AAE3D,OAAO,EAAE,cAAc,EAAE,4CAA2C;AACpE,OAAO,EAAE,WAAW,EAAE,wCAAuC;AAkD7D,MAAM,UAAU,2BAA2B,CACzC,OAA0B;IAE1B,OAAO;QACL,cAAc,CAAC,IAAI;YACjB,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;YAC3C,IACE,eAAe,CAAC,QAAQ,CAAC;gBACzB,eAAe,CAAC,UAAU,CAAC;gBAC3B,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,EAC1D,CAAC;gBACD,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;gBAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACtC,OAAO,CAAC,WAAW,CACjB,IAAI,YAAY,CACd,sDAAsD,aAAa,2BAA2B,WAAW,IAAI,EAC7G,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QACD,cAAc,CAAC,IAAI;YACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YACjC,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACpD,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;YAC3C,IACE,QAAQ;gBACR,UAAU;gBACV,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,EAC1D,CAAC;gBACD,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;gBAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACtC,OAAO,CAAC,WAAW,CACjB,IAAI,YAAY,CACd,aAAa,QAAQ,+CAA+C,aAAa,2BAA2B,WAAW,IAAI,EAC3H,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB,CACF,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,OAA0B,EAC1B,IAAY;IAEZ,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAClE,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["/** @category Validation Rules */\n\nimport { inspect } from '../../jsutils/inspect.ts';\nimport type { Maybe } from '../../jsutils/Maybe.ts';\n\nimport { GraphQLError } from '../../error/GraphQLError.ts';\n\nimport type { ASTVisitor } from '../../language/visitor.ts';\n\nimport type { GraphQLCompositeType } from '../../type/definition.ts';\nimport { isCompositeType } from '../../type/definition.ts';\n\nimport { doTypesOverlap } from '../../utilities/typeComparators.ts';\nimport { typeFromAST } from '../../utilities/typeFromAST.ts';\n\nimport type { ValidationContext } from '../ValidationContext.ts';\n\n/**\n * Possible fragment spread\n *\n * A fragment spread is only valid if the type condition could ever possibly\n * be true: if there is a non-empty intersection of the possible parent types,\n * and possible types which pass the type condition.\n * @param context - The validation context used while checking the document.\n * @returns A visitor that reports validation errors for this rule.\n * @example\n * ```ts\n * import { buildSchema, parse, validate } from 'graphql';\n * import { PossibleFragmentSpreadsRule } from 'graphql/validation';\n *\n * const schema = buildSchema(`\n * type Query {\n * dog: Dog\n * }\n *\n * type Dog {\n * barkVolume: Int\n * }\n *\n * type Cat {\n * meowVolume: Int\n * }\n * `);\n *\n * const invalidDocument = parse(`\n * { dog { ... on Cat { meowVolume } } }\n * `);\n * const invalidErrors = validate(schema, invalidDocument, [\n * PossibleFragmentSpreadsRule,\n * ]);\n *\n * invalidErrors.length; // => 1\n *\n * const validDocument = parse(`\n * { dog { ... on Dog { barkVolume } } }\n * `);\n * const validErrors = validate(schema, validDocument, [\n * PossibleFragmentSpreadsRule,\n * ]);\n *\n * validErrors; // => []\n * ```\n */\nexport function PossibleFragmentSpreadsRule(\n context: ValidationContext,\n): ASTVisitor {\n return {\n InlineFragment(node) {\n const fragType = context.getType();\n const parentType = context.getParentType();\n if (\n isCompositeType(fragType) &&\n isCompositeType(parentType) &&\n !doTypesOverlap(context.getSchema(), fragType, parentType)\n ) {\n const parentTypeStr = inspect(parentType);\n const fragTypeStr = inspect(fragType);\n context.reportError(\n new GraphQLError(\n `Fragment cannot be spread here as objects of type \"${parentTypeStr}\" can never be of type \"${fragTypeStr}\".`,\n { nodes: node },\n ),\n );\n }\n },\n FragmentSpread(node) {\n const fragName = node.name.value;\n const fragType = getFragmentType(context, fragName);\n const parentType = context.getParentType();\n if (\n fragType &&\n parentType &&\n !doTypesOverlap(context.getSchema(), fragType, parentType)\n ) {\n const parentTypeStr = inspect(parentType);\n const fragTypeStr = inspect(fragType);\n context.reportError(\n new GraphQLError(\n `Fragment \"${fragName}\" cannot be spread here as objects of type \"${parentTypeStr}\" can never be of type \"${fragTypeStr}\".`,\n { nodes: node },\n ),\n );\n }\n },\n };\n}\n\nfunction getFragmentType(\n context: ValidationContext,\n name: string,\n): Maybe<GraphQLCompositeType> {\n const frag = context.getFragment(name);\n if (frag) {\n const type = typeFromAST(context.getSchema(), frag.typeCondition);\n if (isCompositeType(type)) {\n return type;\n }\n }\n}\n"]}