@neo4j/graphql
Version:
A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations
172 lines • 7.22 kB
JavaScript
;
/*
* 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