UNPKG

@neo4j/graphql

Version:

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

249 lines 12.9 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.createRelationshipFields = createRelationshipFields; const graphql_1 = require("graphql"); const graphql_compose_1 = require("graphql-compose"); const constants_1 = require("../../constants"); const ConcreteEntityAdapter_1 = require("../../schema-model/entity/model-adapters/ConcreteEntityAdapter"); const InterfaceEntityAdapter_1 = require("../../schema-model/entity/model-adapters/InterfaceEntityAdapter"); const UnionEntityAdapter_1 = require("../../schema-model/entity/model-adapters/UnionEntityAdapter"); const RelationshipAdapter_1 = require("../../schema-model/relationship/model-adapters/RelationshipAdapter"); const RelationshipDeclarationAdapter_1 = require("../../schema-model/relationship/model-adapters/RelationshipDeclarationAdapter"); const field_aggregation_composer_1 = require("../aggregations/field-aggregation-composer"); const augment_object_or_interface_1 = require("../generation/augment-object-or-interface"); const connect_input_1 = require("../generation/connect-input"); const create_input_1 = require("../generation/create-input"); const delete_input_1 = require("../generation/delete-input"); const disconnect_input_1 = require("../generation/disconnect-input"); const edge_wrapper_type_1 = require("../generation/edge-wrapper-type"); const object_type_1 = require("../generation/object-type"); const relation_input_1 = require("../generation/relation-input"); const sort_and_options_input_1 = require("../generation/sort-and-options-input"); const update_input_1 = require("../generation/update-input"); const where_input_1 = require("../generation/where-input"); const to_compose_1 = require("../to-compose"); function doForRelationshipDeclaration({ relationshipDeclarationAdapter, composer, }) { // creates the type for the `edge` field that contains all possible implementations of a declared relationship // an implementation being a relationship directive with different `properties` value for (const relationshipAdapter of relationshipDeclarationAdapter.relationshipImplementations) { if (!relationshipAdapter.propertiesTypeName) { continue; } const propertiesType = composer .getOrCreateUTC(relationshipDeclarationAdapter.operations.relationshipPropertiesFieldTypename) .addType(relationshipAdapter.propertiesTypeName); composer.getOrCreateOTC(relationshipDeclarationAdapter.operations.relationshipFieldTypename, (tc) => tc.addFields({ cursor: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString), node: `${relationshipDeclarationAdapter.target.name}!`, properties: propertiesType.NonNull, })); (0, edge_wrapper_type_1.withEdgeWrapperType)({ edgeTypeName: relationshipDeclarationAdapter.operations.whereInputTypeName, edgeFieldTypeName: relationshipAdapter.operations.whereInputTypeName, edgeFieldAdapter: relationshipAdapter, composer, }); (0, edge_wrapper_type_1.withEdgeWrapperType)({ edgeTypeName: relationshipDeclarationAdapter.operations.sortInputTypeName, edgeFieldTypeName: relationshipAdapter.operations.sortInputTypeName, edgeFieldAdapter: relationshipAdapter, composer, }); if (relationshipAdapter.hasCreateInputFields) { (0, edge_wrapper_type_1.withEdgeWrapperType)({ edgeTypeName: relationshipDeclarationAdapter.operations.createInputTypeName, edgeFieldTypeName: relationshipAdapter.operations.edgeCreateInputTypeName, edgeFieldAdapter: relationshipAdapter, composer, }); } if (relationshipAdapter.hasUpdateInputFields) { (0, edge_wrapper_type_1.withEdgeWrapperType)({ edgeTypeName: relationshipDeclarationAdapter.operations.edgeUpdateInputTypeName, edgeFieldTypeName: relationshipAdapter.operations.edgeUpdateInputTypeName, edgeFieldAdapter: relationshipAdapter, composer, }); } if (relationshipAdapter.aggregationWhereFields) { (0, edge_wrapper_type_1.withEdgeWrapperType)({ edgeTypeName: relationshipDeclarationAdapter.operations.edgeAggregationWhereInputTypeName, edgeFieldTypeName: relationshipAdapter.operations.edgeAggregationWhereInputTypeName, edgeFieldAdapter: relationshipAdapter, composer, }); } } } function doForRelationshipPropertiesType({ composer, relationshipAdapter, userDefinedDirectivesForNode, userDefinedFieldDirectivesForNode, features, }) { if (!relationshipAdapter.propertiesTypeName) { return; } const userDefinedFieldDirectives = userDefinedFieldDirectivesForNode.get(relationshipAdapter.propertiesTypeName); const userDefinedInterfaceDirectives = userDefinedDirectivesForNode.get(relationshipAdapter.name) || []; (0, object_type_1.withObjectType)({ entityAdapter: relationshipAdapter, userDefinedFieldDirectives, userDefinedObjectDirectives: userDefinedInterfaceDirectives, composer, }); (0, sort_and_options_input_1.withSortInputType)({ relationshipAdapter, userDefinedFieldDirectives, composer }); (0, update_input_1.withUpdateInputType)({ entityAdapter: relationshipAdapter, userDefinedFieldDirectives, composer, features }); (0, where_input_1.withWhereInputType)({ entityAdapter: relationshipAdapter, userDefinedFieldDirectives, features, composer, }); (0, create_input_1.withCreateInputType)({ entityAdapter: relationshipAdapter, userDefinedFieldDirectives, composer }); } function createRelationshipFields({ entityAdapter, schemaComposer, // TODO: Ideally we come up with a solution where we don't have to pass the following into these kind of functions composeNode, subgraph, userDefinedFieldDirectives, seenRelationshipPropertiesTypes, userDefinedDirectivesForNode, userDefinedFieldDirectivesForNode, features, complexityEstimatorHelper, }) { const relationships = entityAdapter instanceof ConcreteEntityAdapter_1.ConcreteEntityAdapter ? entityAdapter.relationships : entityAdapter.relationshipDeclarations; if (!relationships.size) { return; } relationships.forEach((relationshipAdapter) => { if (!relationshipAdapter) { return; } if (!relationshipAdapter.isList) { throw new Error(`@relationship on non-list field [${relationshipAdapter.source.name}.${relationshipAdapter.name}] not supported`); } // TODO: find a way to merge these 2 into 1 RelationshipProperties generation function if (relationshipAdapter instanceof RelationshipDeclarationAdapter_1.RelationshipDeclarationAdapter) { doForRelationshipDeclaration({ relationshipDeclarationAdapter: relationshipAdapter, composer: schemaComposer, }); } if (relationshipAdapter instanceof RelationshipAdapter_1.RelationshipAdapter) { if (relationshipAdapter.propertiesTypeName) { if (seenRelationshipPropertiesTypes.has(relationshipAdapter.propertiesTypeName)) { // update description const propertiesObjectType = schemaComposer.getOTC(relationshipAdapter.propertiesTypeName); propertiesObjectType.setDescription((0, object_type_1.getRelationshipPropertiesTypeDescription)({ relationshipAdapter, propertiesObjectType })); } else { doForRelationshipPropertiesType({ composer: schemaComposer, relationshipAdapter, userDefinedDirectivesForNode, userDefinedFieldDirectivesForNode, features, }); seenRelationshipPropertiesTypes.add(relationshipAdapter.propertiesTypeName); } } } const relationshipTarget = relationshipAdapter.target; const userDefinedDirectivesOnField = userDefinedFieldDirectives.get(relationshipAdapter.name); const deprecatedDirectives = (0, to_compose_1.graphqlDirectivesToCompose)((userDefinedDirectivesOnField || []).filter((directive) => directive.name.value === constants_1.DEPRECATED)); const userDefinedDirectivesOnTargetFields = userDefinedFieldDirectivesForNode.get(relationshipAdapter.target.name); const relationshipFieldsOpts = { relationshipAdapter, composer: schemaComposer, composeNode, userDefinedFieldDirectives, deprecatedDirectives, userDefinedDirectivesOnTargetFields, features, complexityEstimatorHelper, }; if (relationshipTarget instanceof UnionEntityAdapter_1.UnionEntityAdapter) { createRelationshipFieldsForTarget(relationshipFieldsOpts); return; } if (composeNode instanceof graphql_compose_1.ObjectTypeComposer) { // make a new fn augmentObjectTypeWithAggregationField const fieldAggregationComposer = new field_aggregation_composer_1.FieldAggregationComposer(schemaComposer, subgraph); fieldAggregationComposer.createAggregationTypeObject(relationshipAdapter, features); } if (relationshipTarget instanceof ConcreteEntityAdapter_1.ConcreteEntityAdapter) { relationshipFieldsOpts.subgraph = subgraph; } createRelationshipFieldsForTarget(relationshipFieldsOpts); }); } function createRelationshipFieldsForTarget({ relationshipAdapter, composer, composeNode, userDefinedFieldDirectives, deprecatedDirectives, userDefinedDirectivesOnTargetFields, subgraph, // only for concrete targets features, complexityEstimatorHelper, }) { (0, where_input_1.withSourceWhereInputType)({ relationshipAdapter, composer, deprecatedDirectives, userDefinedDirectivesOnTargetFields, features, }); if (relationshipAdapter.target instanceof InterfaceEntityAdapter_1.InterfaceEntityAdapter) { (0, create_input_1.withFieldInputType)({ relationshipAdapter, composer, userDefinedFieldDirectives }); } complexityEstimatorHelper.registerField(composeNode.getTypeName(), relationshipAdapter.name); composeNode.addFields((0, augment_object_or_interface_1.augmentObjectOrInterfaceTypeWithRelationshipField)({ relationshipAdapter, userDefinedFieldDirectives, subgraph, composer, features, })); complexityEstimatorHelper.registerField(composeNode.getTypeName(), relationshipAdapter.operations.connectionFieldName); composeNode.addFields((0, augment_object_or_interface_1.augmentObjectOrInterfaceTypeWithConnectionField)(relationshipAdapter, userDefinedFieldDirectives, composer, features)); (0, relation_input_1.withRelationInputType)({ relationshipAdapter, composer, deprecatedDirectives, userDefinedFieldDirectives, }); (0, create_input_1.augmentCreateInputTypeWithRelationshipsInput)({ relationshipAdapter, composer, deprecatedDirectives, userDefinedFieldDirectives, features, }); (0, connect_input_1.augmentConnectInputTypeWithConnectFieldInput)({ relationshipAdapter, composer, deprecatedDirectives, }); (0, delete_input_1.augmentDeleteInputTypeWithDeleteFieldInput)({ relationshipAdapter, composer, deprecatedDirectives, features, }); (0, disconnect_input_1.augmentDisconnectInputTypeWithDisconnectFieldInput)({ relationshipAdapter, composer, deprecatedDirectives, features, }); (0, update_input_1.augmentUpdateInputTypeWithUpdateFieldInput)({ relationshipAdapter, composer, deprecatedDirectives, userDefinedFieldDirectives, features, }); } //# sourceMappingURL=create-relationship-fields.js.map