@relay-graphql-js/validation-rules
Version:
shared relay validation rules for graphql-js parser
186 lines (185 loc) • 7.88 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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.getRecursiveVariableUsagesWithRelayInfo = exports.isFragmentDefinedVariable = exports.getFragmentArgumentDefinitions = exports.getArgumentDefinitions = void 0;
var graphql_1 = require("graphql");
var utils_1 = require("./utils");
function getArgumentDefinitions(fragmentDefinitionNode) {
var argumentDefinitionNodes;
graphql_1.visit(fragmentDefinitionNode, {
Directive: function (argumentDefinitionsDirectiveNode) {
if (argumentDefinitionsDirectiveNode.name.value === "argumentDefinitions") {
argumentDefinitionNodes = argumentDefinitionsDirectiveNode.arguments;
}
else {
return false;
}
}
});
return argumentDefinitionNodes;
}
exports.getArgumentDefinitions = getArgumentDefinitions;
function getFragmentArgumentDefinitions(context, fragmentDefinitionNode) {
var argDefs = getArgumentDefinitions(fragmentDefinitionNode);
if (argDefs == null) {
return {};
}
return argDefs.reduce(function (carry, argDef) {
var node = argDef.name;
var name = argDef.name.value;
var astTypeNode;
var defaultValue;
if (argDef.value.kind === "ObjectValue") {
var typeField = argDef.value.fields.find(function (f) { return f.name.value === "type"; });
var defaultValueField = argDef.value.fields.find(function (f) { return f.name.value === "defaultValue"; });
if (typeField != null && typeField.value.kind === "StringValue") {
try {
astTypeNode = graphql_1.parseType(typeField.value.value);
}
catch (_a) {
// ignore
}
}
if (defaultValueField != null) {
defaultValue = defaultValueField.value;
}
}
var schemaType;
if (astTypeNode != null) {
try {
var type = graphql_1.typeFromAST(context.getSchema(), astTypeNode);
if (graphql_1.isInputType(type)) {
schemaType = type;
}
}
catch (_b) {
// ignore
}
}
carry[name] = {
node: node,
schemaType: schemaType,
typeNode: astTypeNode,
defaultValue: defaultValue
};
return carry;
}, {});
}
exports.getFragmentArgumentDefinitions = getFragmentArgumentDefinitions;
function getVariableUsages(context, nodeWithSelection) {
var typeInfo = new graphql_1.TypeInfo(context.getSchema());
var newUsages = [];
graphql_1.visit(nodeWithSelection, graphql_1.visitWithTypeInfo(typeInfo, {
VariableDefinition: function () { return false; },
Directive: function (directive, _key, _parent, _hans, ancestors) {
if (directive.name.value !== "arguments" || !directive.arguments) {
return;
}
var fragmentSpreadParent = utils_1.findFragmentSpreadParent(ancestors);
if (!fragmentSpreadParent) {
return false;
}
var fragmentDefinition = context.getFragment(fragmentSpreadParent.name.value);
if (fragmentDefinition == null) {
return false;
}
var fragmentArguments = getFragmentArgumentDefinitions(context, fragmentDefinition);
directive.arguments.forEach(function (arg) {
var argumentName = arg.name.value;
var argumentValue = arg.value;
if (argumentValue.kind === "Variable") {
var definition = fragmentArguments[argumentName];
if (!definition) {
newUsages.push({
node: argumentValue,
type: undefined,
defaultValue: undefined
});
}
else {
newUsages.push({
node: argumentValue,
type: definition.schemaType,
defaultValue: definition.defaultValue
});
}
}
});
return false;
},
Variable: function (variable) {
newUsages.push({
node: variable,
type: typeInfo.getInputType(),
defaultValue: typeInfo.getDefaultValue()
});
}
}));
return newUsages;
}
function isFragmentDefinedVariable(variableOrArgumentDefinition) {
return variableOrArgumentDefinition.node.kind === "Name";
}
exports.isFragmentDefinedVariable = isFragmentDefinedVariable;
function getRecursiveVariableUsagesWithRelayInfo(context, nodeWithSelectionSet) {
var schema = context.getSchema();
var rootVariables = nodeWithSelectionSet.kind === "OperationDefinition"
? nodeWithSelectionSet.variableDefinitions == null
? {}
: nodeWithSelectionSet.variableDefinitions.reduce(function (carry, varDef) {
var variableName = varDef.variable.name.value;
carry[variableName] = {
node: varDef.variable,
defaultValue: varDef.defaultValue,
typeNode: varDef.type
};
try {
var schemaType = graphql_1.typeFromAST(schema, varDef.type);
if (graphql_1.isInputType(schemaType)) {
carry[variableName].schemaType = schemaType;
}
}
catch (_a) {
// ignore
}
return carry;
}, {})
: getFragmentArgumentDefinitions(context, nodeWithSelectionSet);
var fragments = nodeWithSelectionSet.kind === "OperationDefinition"
? context.getRecursivelyReferencedFragments(nodeWithSelectionSet)
: [];
var rootUsages = getVariableUsages(context, nodeWithSelectionSet).map(function (usage) {
var newUsage = __assign(__assign({}, usage), { usingFragmentName: null });
var varName = usage.node.name.value;
if (rootVariables[varName]) {
newUsage.variableDefinition = rootVariables[varName];
}
return newUsage;
});
var fragmentUsages = fragments.map(function (fragment) {
var argumentDefs = getFragmentArgumentDefinitions(context, fragment);
var framgentUsages = getVariableUsages(context, fragment);
return framgentUsages.map(function (usage) { return (__assign(__assign({}, usage), { variableDefinition: argumentDefs[usage.node.name.value]
? argumentDefs[usage.node.name.value]
: rootVariables[usage.node.name.value], usingFragmentName: fragment.name.value })); });
});
return __spreadArrays(rootUsages).concat(Array.prototype.concat.apply([], fragmentUsages));
}
exports.getRecursiveVariableUsagesWithRelayInfo = getRecursiveVariableUsagesWithRelayInfo;