graphql
Version:
A Query Language and Runtime which can target any service.
1 lines • 5.11 kB
Source Map (JSON)
{"version":3,"file":"KnownTypeNamesRule.js","sourceRoot":"","sources":["../../../src/validation/rules/KnownTypeNamesRule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,qCAAoC;AACzD,OAAO,EAAE,cAAc,EAAE,yCAAwC;AAEjE,OAAO,EAAE,YAAY,EAAE,qCAAoC;AAG3D,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,GAC1B,sCAAqC;AAGtC,OAAO,EAAE,kBAAkB,EAAE,qCAAoC;AACjE,OAAO,EAAE,oBAAoB,EAAE,+BAA8B;AA0C7D,MAAM,UAAU,kBAAkB,CAChC,OAAiD;IAEjD,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAC9C,MAAM,gBAAgB,GAAG,OAAO,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAEjE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;QACxB,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;QAChC,GAAG,WAAW,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;KACzE,CAAC,CAAC;IAEH,OAAO;QACL,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YACjC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,MAAM,cAAc,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;gBAC9C,MAAM,KAAK,GAAG,cAAc,IAAI,IAAI,IAAI,SAAS,CAAC,cAAc,CAAC,CAAC;gBAClE,IAAI,KAAK,IAAI,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC7C,OAAO;gBACT,CAAC;gBAED,MAAM,cAAc,GAAG,OAAO,CAAC,eAAe;oBAC5C,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,cAAc,CACZ,QAAQ,EACR,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,iBAAiB,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAC9D,CAAC;gBACN,OAAO,CAAC,WAAW,CACjB,IAAI,YAAY,CACd,iBAAiB,QAAQ,IAAI,GAAG,UAAU,CAAC,cAAc,CAAC,EAC1D,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB,CACF,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAC/B,CAAC,GAAG,oBAAoB,EAAE,GAAG,kBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAC1E,CAAC;AAEF,SAAS,SAAS,CAAC,KAAuC;IACxD,OAAO,CACL,MAAM,IAAI,KAAK;QACf,CAAC,0BAA0B,CAAC,KAAK,CAAC,IAAI,yBAAyB,CAAC,KAAK,CAAC,CAAC,CACxE,CAAC;AACJ,CAAC","sourcesContent":["/** @category Validation Rules */\n\nimport { didYouMean } from '../../jsutils/didYouMean.ts';\nimport { suggestionList } from '../../jsutils/suggestionList.ts';\n\nimport { GraphQLError } from '../../error/GraphQLError.ts';\n\nimport type { ASTNode } from '../../language/ast.ts';\nimport {\n isTypeDefinitionNode,\n isTypeSystemDefinitionNode,\n isTypeSystemExtensionNode,\n} from '../../language/predicates.ts';\nimport type { ASTVisitor } from '../../language/visitor.ts';\n\nimport { introspectionTypes } from '../../type/introspection.ts';\nimport { specifiedScalarTypes } from '../../type/scalars.ts';\n\nimport type {\n SDLValidationContext,\n ValidationContext,\n} from '../ValidationContext.ts';\n\n/**\n * Known type names\n *\n * A GraphQL document is only valid if referenced types (specifically\n * variable definitions and fragment conditions) are defined by the type schema.\n *\n * See https://spec.graphql.org/draft/#sec-Fragment-Spread-Type-Existence\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 { KnownTypeNamesRule } from 'graphql/validation';\n *\n * const schema = buildSchema(`\n * type Query {\n * name: String\n * }\n * `);\n *\n * const invalidDocument = parse(`\n * fragment Bad on Missing { name }\n * `);\n * const invalidErrors = validate(schema, invalidDocument, [KnownTypeNamesRule]);\n *\n * invalidErrors.length; // => 1\n *\n * const validDocument = parse(`\n * fragment Good on Query { name }\n * `);\n * const validErrors = validate(schema, validDocument, [KnownTypeNamesRule]);\n *\n * validErrors; // => []\n * ```\n */\nexport function KnownTypeNamesRule(\n context: ValidationContext | SDLValidationContext,\n): ASTVisitor {\n const { definitions } = context.getDocument();\n const existingTypesMap = context.getSchema()?.getTypeMap() ?? {};\n\n const typeNames = new Set([\n ...Object.keys(existingTypesMap),\n ...definitions.filter(isTypeDefinitionNode).map((def) => def.name.value),\n ]);\n\n return {\n NamedType(node, _1, parent, _2, ancestors) {\n const typeName = node.name.value;\n if (!typeNames.has(typeName)) {\n const definitionNode = ancestors[2] ?? parent;\n const isSDL = definitionNode != null && isSDLNode(definitionNode);\n if (isSDL && standardTypeNames.has(typeName)) {\n return;\n }\n\n const suggestedTypes = context.hideSuggestions\n ? []\n : suggestionList(\n typeName,\n isSDL ? [...standardTypeNames, ...typeNames] : [...typeNames],\n );\n context.reportError(\n new GraphQLError(\n `Unknown type \"${typeName}\".` + didYouMean(suggestedTypes),\n { nodes: node },\n ),\n );\n }\n },\n };\n}\n\nconst standardTypeNames = new Set<string>(\n [...specifiedScalarTypes, ...introspectionTypes].map((type) => type.name),\n);\n\nfunction isSDLNode(value: ASTNode | ReadonlyArray<ASTNode>): boolean {\n return (\n 'kind' in value &&\n (isTypeSystemDefinitionNode(value) || isTypeSystemExtensionNode(value))\n );\n}\n"]}