UNPKG

@relay-graphql-js/validation-rules

Version:
153 lines (152 loc) 8.06 kB
"use strict"; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; exports.__esModule = true; exports.RelayKnownArgumentNames = void 0; var graphql_1 = require("graphql"); var argumentDefinitions_1 = require("./argumentDefinitions"); var utils_1 = require("./utils"); // tslint:disable-next-line: no-shadowed-variable exports.RelayKnownArgumentNames = function RelayKnownArgumentNames(context) { var originalRuleVisitor = graphql_1.KnownArgumentNamesRule(context); return { Argument: function (argumentNode) { /** * Always forward field arguments to the original rule. */ graphql_1.visit(argumentNode, originalRuleVisitor); return false; }, FragmentSpread: function (fragmentSpreadNode) { var fragmentDefinitionNode = context.getFragment(fragmentSpreadNode.name.value); if (fragmentDefinitionNode && (!fragmentSpreadNode.directives || fragmentSpreadNode.directives.findIndex(function (directive) { return directive.name.value === "arguments"; }) === -1) && argumentDefinitions_1.getArgumentDefinitions(fragmentDefinitionNode)) { validateFragmentArguments(context, fragmentDefinitionNode, fragmentSpreadNode); } }, Directive: function (directiveNode, _key, _parent, _nodePath, ancestors) { if (directiveNode.name.value === "argumentDefinitions") { validateFragmentArgumentDefinitions(context, directiveNode); return false; } if (directiveNode.name.value === "arguments") { var fragmentSpreadNode = ancestors[ancestors.length - 1]; var fragmentDefinitionNode = context.getFragment(fragmentSpreadNode.name.value); if (fragmentDefinitionNode) { validateFragmentArguments(context, fragmentDefinitionNode, fragmentSpreadNode, directiveNode); } return false; } /** * Forward any other directives to original rule. */ graphql_1.visit(directiveNode, originalRuleVisitor); return false; } }; }; function validateFragmentArgumentDefinitions(context, directiveNode) { if (!directiveNode.arguments || directiveNode.arguments.length === 0) { context.reportError(new graphql_1.GraphQLError("Missing required argument definitions.", directiveNode)); } else { directiveNode.arguments.forEach(function (argumentNode) { var metadataNode = argumentNode.value; if (metadataNode.kind !== "ObjectValue" || !metadataNode.fields.some(function (field) { return field.name.value === "type"; })) { context.reportError(new graphql_1.GraphQLError("Metadata of argument definition should be of type \"Object\" with a \"type\" and optional \"defaultValue\" key.", metadataNode)); } else { metadataNode.fields.forEach(function (fieldNode) { var name = fieldNode.name.value; if (name !== "type" && name !== "defaultValue") { context.reportError(new graphql_1.GraphQLError("Unknown key \"" + name + "\" in argument definition metadata.", fieldNode.name)); } var valueNode = fieldNode.value; if (name === "type") { if (valueNode.kind !== "StringValue") { context.reportError(new graphql_1.GraphQLError("Value for \"type\" in argument definition metadata must be specified as string literal.", valueNode)); } else { var typeNode = null; try { typeNode = graphql_1.parseType(valueNode.value); } catch (error) { context.reportError(new graphql_1.GraphQLError(error.message, valueNode)); } if (typeNode) { while (typeNode.kind === "NonNullType" || typeNode.kind === "ListType") { typeNode = typeNode.type; } if (!context.getSchema().getType(typeNode.name.value)) { context.reportError(new graphql_1.GraphQLError("Unknown type \"" + typeNode.name.value + "\" in argument definition metadata.", valueNode)); } } } } else if (name === "defaultValue") { if (utils_1.containsVariableNodes(fieldNode.value)) { context.reportError(new graphql_1.GraphQLError("defaultValue contains variables for argument " + argumentNode.name.value + " in argument definition metadata.", valueNode)); } } }); } }); } } function isNullableArgument(argumentDefinition) { var typeField = argumentDefinition.fields.find(function (f) { return f.name.value === "type"; }); if (typeField == null) { return false; } if (typeField.value.kind !== "StringValue") { return false; } try { var type = graphql_1.parseType(typeField.value.value); return type.kind !== "NonNullType"; } catch (e) { return false; } } function validateFragmentArguments(context, fragmentDefinitionNode, fragmentSpreadNode, directiveNode) { var argumentDefinitionNodes = argumentDefinitions_1.getArgumentDefinitions(fragmentDefinitionNode); var suggestionList = require("graphql/jsutils/suggestionList")["default"]; var didYouMean = require("graphql/jsutils/didYouMean")["default"]; if (!argumentDefinitionNodes) { context.reportError(new graphql_1.GraphQLError("No fragment argument definitions exist for fragment \"" + fragmentSpreadNode.name.value + "\".", fragmentSpreadNode)); } else { var argumentNodes_1 = __spreadArrays(((directiveNode && directiveNode.arguments) || [])); argumentDefinitionNodes.forEach(function (argumentDef) { var argumentIndex = argumentNodes_1.findIndex(function (a) { return a.name.value === argumentDef.name.value; }); if (argumentIndex >= 0) { argumentNodes_1.splice(argumentIndex, 1); } else { var value = argumentDef.value; if (value.kind === "ObjectValue") { if (value.fields.findIndex(function (field) { return field.name.value === "defaultValue"; }) === -1 && !isNullableArgument(value)) { context.reportError(new graphql_1.GraphQLError("Missing required fragment argument \"" + argumentDef.name.value + "\".", directiveNode || fragmentSpreadNode)); } } else { console.log("Unexpected fragment argument value kind \"" + value.kind + "\"."); } } }); argumentNodes_1.forEach(function (argumentNode) { var suggestions = suggestionList(argumentNode.name.value, argumentDefinitionNodes.map(function (argDef) { return argDef.name.value; })); context.reportError(new graphql_1.GraphQLError("Unknown fragment argument \"" + argumentNode.name.value + "\"." + didYouMean(suggestions.map(function (x) { return "\"" + x + "\""; })), directiveNode)); }); } }