UNPKG

@relay-graphql-js/validation-rules

Version:
153 lines (152 loc) 7.03 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.RelayCompatRequiredPageInfoFields = exports.connectionSelectionSetPaginationInfo = void 0; var graphql_1 = require("graphql"); var utils_1 = require("./utils"); function hasFirstArgument(fieldNode) { return !!(fieldNode.arguments && fieldNode.arguments.find(function (arg) { return arg.name.value === "first"; })); } function hasLastArgument(fieldNode) { return !!(fieldNode.arguments && fieldNode.arguments.find(function (arg) { return arg.name.value === "last"; })); } function hasAfterArgument(fieldNode) { return !!(fieldNode.arguments && fieldNode.arguments.find(function (arg) { return arg.name.value === "after"; })); } function hasBeforeArgument(fieldNode) { return !!(fieldNode.arguments && fieldNode.arguments.find(function (arg) { return arg.name.value === "before"; })); } function rollupFieldsInfo(fieldsInfo) { return fieldsInfo.reduce(function (carry, el) { carry.hasNextPage = carry.hasNextPage || el.hasNextPage; carry.hasPreviousPage = carry.hasPreviousPage || el.hasPreviousPage; carry.endCursor = carry.endCursor || el.endCursor; carry.startCursor = carry.startCursor || el.startCursor; return carry; }, { hasNextPage: false, hasPreviousPage: false, endCursor: false, startCursor: false }); } function connectionSelectionSetPaginationInfo(getFragment, selectionSetNode) { var fieldsInfo = []; graphql_1.visit(selectionSetNode, { SelectionSet: function (selectionSet) { if (selectionSet !== selectionSetNode) { // Don't recurse into other selection sets return false; } }, InlineFragment: function (inlineFragment) { fieldsInfo.push(connectionSelectionSetPaginationInfo(getFragment, inlineFragment.selectionSet)); return false; }, Field: function (fieldNode) { if (fieldNode.name.value === "pageInfo" && fieldNode.selectionSet) { fieldsInfo.push(pageInfoSelectionSetPaginationInfo(getFragment, fieldNode.selectionSet)); return false; } }, FragmentSpread: function (fragmentSpread) { var fragmentDefinitionNode = getFragment(fragmentSpread.name.value); if (fragmentDefinitionNode) { fieldsInfo.push(connectionSelectionSetPaginationInfo(getFragment, fragmentDefinitionNode.selectionSet)); } return false; } }); return rollupFieldsInfo(fieldsInfo); } exports.connectionSelectionSetPaginationInfo = connectionSelectionSetPaginationInfo; function pageInfoSelectionSetPaginationInfo(getFragment, selectionSetNode) { var fields = { hasNextPage: false, hasPreviousPage: false, startCursor: false, endCursor: false }; var nestedFieldsInfo = []; graphql_1.visit(selectionSetNode, { SelectionSet: function (selectionSet) { if (selectionSet !== selectionSetNode) { // Don't recurse into other selection sets return false; } }, InlineFragment: function (inlineFragment) { nestedFieldsInfo.push(pageInfoSelectionSetPaginationInfo(getFragment, inlineFragment.selectionSet)); return false; }, Field: function (fieldNode) { if (fieldNode.name.value === "startCursor") { fields.startCursor = true; } if (fieldNode.name.value === "endCursor") { fields.endCursor = true; } if (fieldNode.name.value === "hasPreviousPage") { fields.hasPreviousPage = true; } if (fieldNode.name.value === "hasNextPage") { fields.hasNextPage = true; } }, FragmentSpread: function (fragmentSpread) { var fragmentDefinitionNode = getFragment(fragmentSpread.name.value); if (fragmentDefinitionNode) { nestedFieldsInfo.push(pageInfoSelectionSetPaginationInfo(getFragment, fragmentDefinitionNode.selectionSet)); } return false; } }); return rollupFieldsInfo(__spreadArrays([fields], nestedFieldsInfo)); } // tslint:disable-next-line: no-shadowed-variable exports.RelayCompatRequiredPageInfoFields = function RelayCompatRequiredPageInfoFields(context) { return { Field: { enter: function (fieldNode) { if (!fieldNode.selectionSet) { return; } var type = context.getType(); if (!type || !utils_1.isConnectionType(type)) { return; } var connectionDirective = utils_1.getConnectionDirective(fieldNode); if (!connectionDirective) { return; } var isForwardConnection = hasFirstArgument(fieldNode) && hasAfterArgument(fieldNode); var isBackwardConnection = hasLastArgument(fieldNode) && hasBeforeArgument(fieldNode); var selectionName = fieldNode.alias || fieldNode.name; var paginationFields = connectionSelectionSetPaginationInfo(function (name) { return context.getFragment(name); }, fieldNode.selectionSet); var connectionName = connectionDirective.key || selectionName; if (isForwardConnection) { if (!paginationFields.hasNextPage) { context.reportError(new graphql_1.GraphQLError("Missing pageInfo.hasNextPage field on connection \"" + connectionName + "\".", connectionDirective.directive)); } if (!paginationFields.endCursor) { context.reportError(new graphql_1.GraphQLError("Missing pageInfo.endCursor field on connection \"" + connectionName + "\".", connectionDirective.directive)); } } if (isBackwardConnection) { if (!paginationFields.hasPreviousPage) { context.reportError(new graphql_1.GraphQLError("Missing pageInfo.hasPreviousPage field on connection \"" + connectionName + "\".", connectionDirective.directive)); } if (!paginationFields.startCursor) { context.reportError(new graphql_1.GraphQLError("Missing pageInfo.startCursor field on connection \"" + connectionName + "\".", connectionDirective.directive)); } } } } }; };