UNPKG

@neo4j/graphql

Version:

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

117 lines 5.98 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. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CompositeConnectionPartial = void 0; const cypher_builder_1 = __importDefault(require("@neo4j/cypher-builder")); const wrap_subquery_in_calls_1 = require("../../../utils/wrap-subquery-in-calls"); const ConnectionReadOperation_1 = require("../ConnectionReadOperation"); class CompositeConnectionPartial extends ConnectionReadOperation_1.ConnectionReadOperation { /** Prints the name of the Node */ print() { return `${super.print()} <${this.target.name}>`; } transpile(context) { // eslint-disable-next-line prefer-const let { selection: clause, nestedContext } = this.selection.apply(context); let extraMatches = this.getChildren().flatMap((f) => { return f.getSelection(nestedContext); }); const filterSubqueries = (0, wrap_subquery_in_calls_1.wrapSubqueriesInCypherCalls)(nestedContext, this.filters, [nestedContext.target]); if (extraMatches.length > 0 || filterSubqueries.length > 0) { extraMatches = [clause, ...extraMatches]; clause = new cypher_builder_1.default.With("*"); } const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); const authPredicate = this.getAuthFilterPredicate(nestedContext); const validations = this.getValidations(nestedContext); const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext); const filters = cypher_builder_1.default.and(...predicates, ...authPredicate); const nodeProjectionSubqueries = (0, wrap_subquery_in_calls_1.wrapSubqueriesInCypherCalls)(nestedContext, this.nodeFields, [ nestedContext.target, ]); const nodeProjectionMap = new cypher_builder_1.default.Map(); // This bit is different than normal connection ops const targetNodeName = this.target.name; nodeProjectionMap.set({ __resolveType: new cypher_builder_1.default.Literal(targetNodeName), __id: cypher_builder_1.default.id(nestedContext.target), }); const nodeProjectionFields = this.nodeFields.map((f) => f.getProjectionField(nestedContext.target)); const nodeSortProjectionFields = this.sortFields.flatMap((f) => f.node.map((ef) => ef.getProjectionField(nestedContext))); const uniqueNodeProjectionFields = Array.from(new Set([...nodeProjectionFields, ...nodeSortProjectionFields])); uniqueNodeProjectionFields.forEach((p) => { if (typeof p === "string") { nodeProjectionMap.set(p, nestedContext.target.property(p)); } else { nodeProjectionMap.set(p); } }); const edgeVar = new cypher_builder_1.default.NamedVariable("edge"); const edgeProjectionMap = new cypher_builder_1.default.Map(); const edgeProjectionFields = this.edgeFields.map((f) => f.getProjectionField(nestedContext.relationship)); const edgeSortProjectionFields = this.sortFields.flatMap((f) => f.edge.map((ef) => ef.getProjectionField(nestedContext))); const uniqueEdgeProjectionFields = Array.from(new Set([...edgeProjectionFields, ...edgeSortProjectionFields])); const propertiesProjectionMap = new cypher_builder_1.default.Map(); uniqueEdgeProjectionFields.forEach((p) => { if (typeof p === "string") { propertiesProjectionMap.set(p, nestedContext.relationship.property(p)); } else { propertiesProjectionMap.set(p); } }); if (propertiesProjectionMap.size) { if (this.relationship?.propertiesTypeName) { // should be true if getting here but just in case.. propertiesProjectionMap.set("__resolveType", new cypher_builder_1.default.Literal(this.relationship.propertiesTypeName)); } edgeProjectionMap.set("properties", propertiesProjectionMap); } edgeProjectionMap.set("node", nodeProjectionMap); let withWhere; if (filters) { if (authFilterSubqueries.length > 0) { // This is to avoid unnecessary With * withWhere = new cypher_builder_1.default.With("*").where(filters); } else { clause.where(filters); } } const projectionClauses = new cypher_builder_1.default.With([edgeProjectionMap, edgeVar]).return(context.returnVariable); const subClause = cypher_builder_1.default.utils.concat( // ...preSelection, ...extraMatches, ...filterSubqueries, clause, ...authFilterSubqueries, withWhere, ...validations, ...nodeProjectionSubqueries, projectionClauses); return { clauses: [subClause], projectionExpr: context.returnVariable, }; } // Pagination is handled by CompositeConnectionReadOperation addPagination(_pagination) { return undefined; } } exports.CompositeConnectionPartial = CompositeConnectionPartial; //# sourceMappingURL=CompositeConnectionPartial.js.map