UNPKG

@neo4j/graphql

Version:

A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations

185 lines 8.65 kB
"use strict"; /* * Copyright (c) "Neo4j" * Neo4j Sweden AB [http://neo4j.com] * * This file is part of Neo4j. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.DisconnectFactory = void 0; const utils_1 = require("../../../../utils/utils"); const MutationOperationField_1 = require("../../ast/input-fields/MutationOperationField"); const ParamInputField_1 = require("../../ast/input-fields/ParamInputField"); const DisconnectOperation_1 = require("../../ast/operations/DisconnectOperation"); const CompositeDisconnectOperation_1 = require("../../ast/operations/composite/CompositeDisconnectOperation"); const CompositeDisconnectPartial_1 = require("../../ast/operations/composite/CompositeDisconnectPartial"); const RelationshipSelectionPattern_1 = require("../../ast/selection/SelectionPattern/RelationshipSelectionPattern"); const is_concrete_entity_1 = require("../../utils/is-concrete-entity"); const is_interface_entity_1 = require("../../utils/is-interface-entity"); const is_union_entity_1 = require("../../utils/is-union-entity"); const raise_attribute_ambiguity_1 = require("../../utils/raise-attribute-ambiguity"); class DisconnectFactory { constructor(queryASTFactory) { this.queryASTFactory = queryASTFactory; } createDisconnectOperation(entity, relationship, input, context, callbackBucket) { const disconnectOP = new DisconnectOperation_1.DisconnectOperation({ target: entity, selectionPattern: new RelationshipSelectionPattern_1.RelationshipSelectionPattern({ relationship, targetOverride: entity, }), relationship, }); this.hydrateDisconnectOperation({ target: entity, relationship, input, disconnect: disconnectOP, context, callbackBucket, }); return disconnectOP; } createCompositeDisconnectOperation(entity, relationship, input, context, callbackBucket) { const partials = []; for (const concreteEntity of entity.concreteEntities) { const partial = this.createCompositeDisconnectPartial(concreteEntity, relationship, input, context, callbackBucket); partials.push(partial); } return new CompositeDisconnectOperation_1.CompositeDisconnectOperation({ partials, target: entity, }); } createCompositeDisconnectPartial(entity, relationship, input, context, callbackBucket) { const disconnectOp = new CompositeDisconnectPartial_1.CompositeDisconnectPartial({ target: entity, selectionPattern: new RelationshipSelectionPattern_1.RelationshipSelectionPattern({ relationship, targetOverride: entity, }), relationship, }); this.hydrateDisconnectOperation({ target: entity, relationship, input, disconnect: disconnectOp, context, callbackBucket, }); return disconnectOp; } hydrateDisconnectOperation({ target, relationship, input, disconnect, context, callbackBucket, }) { this.addEntityAuthorization({ entity: target, context, operation: disconnect, }); if ((0, is_concrete_entity_1.isConcreteEntity)(relationship.source)) { this.addSourceEntityAuthorization({ entity: relationship.source, context, operation: disconnect, }); } (0, utils_1.asArray)(input).forEach((inputItem) => { const { whereArg, disconnectArg } = this.parseDisconnectArgs(inputItem); const nodeFilters = []; const edgeFilters = []; if (whereArg.node) { if ((0, is_concrete_entity_1.isConcreteEntity)(relationship.target) || (0, is_union_entity_1.isUnionEntity)(relationship.target)) { nodeFilters.push(...this.queryASTFactory.filterFactory.createNodeFilters(target, whereArg.node)); } else if ((0, is_interface_entity_1.isInterfaceEntity)(relationship.target)) { nodeFilters.push(...this.queryASTFactory.filterFactory.createInterfaceNodeFilters({ entity: relationship.target, targetEntity: target, whereFields: whereArg.node, relationship, })); } } if (whereArg.edge) { edgeFilters.push(...this.queryASTFactory.filterFactory.createEdgeFilters(relationship, whereArg.edge)); } disconnect.addFilters(...nodeFilters, ...edgeFilters); (0, utils_1.asArray)(disconnectArg).forEach((nestedDisconnectInputFields) => { Object.entries(nestedDisconnectInputFields).forEach(([key, value]) => { const nestedRelationship = target.relationships.get(key); if (!nestedRelationship) { throw new Error("Expected relationship on connect operation. Please contact support"); } const nestedEntity = nestedRelationship.target; (0, utils_1.asArray)(value).forEach((nestedDisconnectInputItem) => { const nestedDisconnectOperation = this.queryASTFactory.operationsFactory.createDisconnectOperation(nestedEntity, nestedRelationship, nestedDisconnectInputItem, context, callbackBucket); const mutationOperationField = new MutationOperationField_1.MutationOperationField(nestedDisconnectOperation, key); disconnect.addField(mutationOperationField, "node"); }); }); }); const targetInputEdge = this.getInputEdge(inputItem, relationship); /* Create the attributes for the edge */ (0, raise_attribute_ambiguity_1.raiseAttributeAmbiguity)(Object.keys(targetInputEdge), relationship); for (const key of Object.keys(targetInputEdge)) { const attribute = relationship.attributes.get(key); if (attribute) { const attachedTo = "relationship"; const paramInputField = new ParamInputField_1.ParamInputField({ attachedTo, attribute, inputValue: targetInputEdge[key], }); disconnect.addField(paramInputField, attachedTo); } } }); } addEntityAuthorization({ entity, context, operation, }) { const authFilters = this.queryASTFactory.authorizationFactory.getAuthFilters({ entity, operations: ["DELETE_RELATIONSHIP"], context, afterValidation: true, }); operation.addAuthFilters(...authFilters); } addSourceEntityAuthorization({ entity, context, operation, }) { const authFilters = this.queryASTFactory.authorizationFactory.getAuthFilters({ entity, operations: ["DELETE_RELATIONSHIP"], context, afterValidation: true, }); operation.addSourceAuthFilters(...authFilters); } getInputEdge(inputItem, relationship) { const edge = inputItem.edge ?? {}; // Deals with composite relationships if (relationship.propertiesTypeName && edge[relationship.propertiesTypeName]) { return edge[relationship.propertiesTypeName]; } return edge; } parseDisconnectArgs(args) { const rawWhere = args.where ?? {}; const whereArg = { node: rawWhere.node, edge: rawWhere.edge }; const disconnectArg = args.disconnect ?? {}; return { whereArg, disconnectArg }; } } exports.DisconnectFactory = DisconnectFactory; //# sourceMappingURL=DisconnectFactory.js.map