UNPKG

@neo4j/graphql

Version:

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

172 lines 7.22 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.DeleteFactory = void 0; const utils_1 = require("../../../../utils/utils"); const check_authentication_1 = require("../../../authorization/check-authentication"); const DeleteOperation_1 = require("../../ast/operations/DeleteOperation"); const NodeSelection_1 = require("../../ast/selection/NodeSelection"); const RelationshipSelection_1 = require("../../ast/selection/RelationshipSelection"); const get_concrete_entities_1 = require("../../utils/get-concrete-entities"); const is_interface_entity_1 = require("../../utils/is-interface-entity"); const is_union_entity_1 = require("../../utils/is-union-entity"); class DeleteFactory { constructor(queryASTFactory) { this.queryASTFactory = queryASTFactory; } parseDeleteArgs(args, isTopLevel) { let whereArg; const rawWhere = (0, utils_1.isRecord)(args.where) ? args.where : {}; if (isTopLevel) { whereArg = { node: rawWhere.node ?? {}, edge: rawWhere.edge ?? {} }; } else { whereArg = { node: rawWhere, edge: {} }; } const deleteArg = (0, utils_1.isRecord)(args.delete) ? args.delete : {}; return { whereArg, deleteArg }; } createTopLevelDeleteOperation({ entity, resolveTree, context, varName, }) { (0, check_authentication_1.checkEntityAuthentication)({ entity: entity.entity, targetOperations: ["DELETE"], context, }); const { whereArg, deleteArg } = this.parseDeleteArgs(resolveTree.args, false); const selection = new NodeSelection_1.NodeSelection({ target: entity, alias: varName, }); const nodeFilters = this.queryASTFactory.filterFactory.createNodeFilters(entity, whereArg.node); const authFilters = this.queryASTFactory.authorizationFactory.getAuthFilters({ entity, operations: ["DELETE"], context, }); const nestedDeleteOperations = this.createNestedDeleteOperations(deleteArg, entity, context); return new DeleteOperation_1.DeleteOperation({ target: entity, selection, filters: nodeFilters, authFilters, nestedOperations: nestedDeleteOperations, }); } createNestedDeleteOperationsForInterface({ deleteArg, relationship, target, context, }) { return target.concreteEntities.flatMap((concreteEntity) => { return this.createNestedDeleteOperation({ relationship, target: concreteEntity, args: deleteArg, context, partialOf: target, }); }); } createNestedDeleteOperationsForUnion({ deleteArg, relationship, target, context, }) { const concreteEntities = (0, get_concrete_entities_1.getConcreteEntities)(target, deleteArg); return concreteEntities.flatMap((concreteEntity) => { return (0, utils_1.asArray)(deleteArg[concreteEntity.name]).flatMap((concreteArgs) => { return this.createNestedDeleteOperation({ relationship, target: concreteEntity, args: concreteArgs, context, }); }); }); } createNestedDeleteOperations(deleteArg, source, context) { return (0, utils_1.filterTruthy)(Object.entries(deleteArg).flatMap(([key, valueArr]) => { return (0, utils_1.asArray)(valueArr).flatMap((value) => { const relationship = source.findRelationship(key); if (!relationship) { throw new Error(`Failed to find relationship ${key}`); } const target = relationship.target; if ((0, is_interface_entity_1.isInterfaceEntity)(target)) { return this.createNestedDeleteOperationsForInterface({ deleteArg: value, relationship, target, context, }); } if ((0, is_union_entity_1.isUnionEntity)(target)) { return this.createNestedDeleteOperationsForUnion({ deleteArg: value, relationship, target, context, }); } return this.createNestedDeleteOperation({ relationship, target, args: value, context, }); }); })); } createNestedDeleteOperation({ relationship, target, args, context, partialOf, }) { const { whereArg, deleteArg } = this.parseDeleteArgs(args, true); (0, check_authentication_1.checkEntityAuthentication)({ entity: target.entity, targetOperations: ["DELETE"], context, }); const selection = new RelationshipSelection_1.RelationshipSelection({ relationship, optional: true, targetOverride: target, }); let nodeFilters; if (partialOf && (0, is_interface_entity_1.isInterfaceEntity)(partialOf)) { nodeFilters = this.queryASTFactory.filterFactory.createInterfaceNodeFilters({ entity: partialOf, targetEntity: target, whereFields: whereArg.node, }); } else { nodeFilters = this.queryASTFactory.filterFactory.createNodeFilters(target, whereArg.node); } const edgeFilters = this.queryASTFactory.filterFactory.createEdgeFilters(relationship, whereArg.edge); const filters = [...nodeFilters, ...edgeFilters]; const authFilters = this.queryASTFactory.authorizationFactory.getAuthFilters({ entity: target, operations: ["DELETE"], context, }); const nestedDeleteOperations = this.createNestedDeleteOperations(deleteArg, target, context); return [ new DeleteOperation_1.DeleteOperation({ target, selection, filters, authFilters, nestedOperations: nestedDeleteOperations, }), ]; } } exports.DeleteFactory = DeleteFactory; //# sourceMappingURL=DeleteFactory.js.map