UNPKG

@neo4j/graphql

Version:

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

329 lines 11.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.AttributeAdapter = void 0; const AttributeType_1 = require("../AttributeType"); const AttributeTypeHelper_1 = require("../AttributeTypeHelper"); const AggregationAdapter_1 = require("./AggregationAdapter"); const ListAdapter_1 = require("./ListAdapter"); const MathAdapter_1 = require("./MathAdapter"); class AttributeAdapter { constructor(attribute) { this.name = attribute.name; this.type = attribute.type; this.args = attribute.args; this.annotations = attribute.annotations; this.databaseName = attribute.databaseName; this.description = attribute.description; this.typeHelper = new AttributeTypeHelper_1.AttributeTypeHelper(attribute.type); } get listModel() { if (!this._listModel) { if (!this.isArrayMethodField()) { return; } this._listModel = new ListAdapter_1.ListAdapter(this); } return this._listModel; } get mathModel() { if (!this._mathModel) { if (!this.typeHelper.isNumeric() || this.typeHelper.isList()) { return; } this._mathModel = new MathAdapter_1.MathAdapter(this); } return this._mathModel; } get aggregationModel() { if (!this._aggregationModel) { this._aggregationModel = new AggregationAdapter_1.AggregationAdapter(this); } return this._aggregationModel; } /** * Categories Filters * each Attribute has the knowledge of whether it is part of a category * */ isMutable() { return ((this.typeHelper.isEnum() || this.typeHelper.isAbstract() || this.typeHelper.isSpatial() || this.typeHelper.isScalar() || this.typeHelper.isObject()) && !this.isCypher()); } isCypher() { return !!this.annotations.cypher; } isObjectField() { return (this.typeHelper.isScalar() || this.typeHelper.isEnum() || this.typeHelper.isAbstract() || this.typeHelper.isObject() || this.typeHelper.isSpatial()); } isSortableField() { return (this.isSortable() && !this.typeHelper.isList() && !this.isCustomResolvable() && (this.typeHelper.isScalar() || this.typeHelper.isEnum() || this.typeHelper.isSpatial()) && (!this.isCypher() || !this.args.some((arg) => arg.type.isRequired))); } isCypherRelationshipField() { return this.isCypher() && Boolean(this.annotations.cypher?.targetEntity); } isWhereField() { return ((this.typeHelper.isEnum() || this.typeHelper.isSpatial() || this.typeHelper.isScalar() || this.isCypherRelationshipField()) && this.isFilterable() && !this.isCustomResolvable()); } isEventPayloadField() { return ((this.typeHelper.isEnum() || this.typeHelper.isSpatial() || this.typeHelper.isScalar()) && !this.isCustomResolvable()); } isSubscriptionConnectedRelationshipField() { return ((this.typeHelper.isEnum() || this.typeHelper.isSpatial() || this.typeHelper.isScalar()) && !this.isCypher()); } isOnCreateField() { if (!this.isNonGeneratedField()) { return false; } if (this.annotations.settable?.onCreate === false) { return false; } if (this.timestampCreateIsGenerated() || this.populatedByCreateIsGenerated()) { return false; } return (this.typeHelper.isScalar() || this.typeHelper.isSpatial() || this.typeHelper.isEnum() || this.typeHelper.isAbstract()); } isNumericalOrTemporal() { return (this.typeHelper.isFloat() || this.typeHelper.isInt() || this.typeHelper.isBigInt() || this.typeHelper.isTemporal()); } isAggregableField() { return (!this.typeHelper.isList() && !this.typeHelper.isID() && (this.typeHelper.isScalar() || this.typeHelper.isEnum()) && this.isAggregable()); } isAggregationWhereField() { if (this.typeHelper.isList() || this.typeHelper.isID() || this.typeHelper.isBoolean() || this.typeHelper.isDate()) { return false; } return ((this.typeHelper.isGraphQLBuiltInScalar() || this.typeHelper.isTemporal() || this.typeHelper.isBigInt()) && this.isAggregationFilterable()); } isCreateInputField() { return (this.isNonGeneratedField() && this.annotations.settable?.onCreate !== false && !this.timestampCreateIsGenerated() && !this.populatedByCreateIsGenerated()); } isUpdateInputField() { return (this.isNonGeneratedField() && this.annotations.settable?.onUpdate !== false && !this.timestampUpdateIsGenerated() && !this.populatedByUpdateIsGenerated()); } timestampCreateIsGenerated() { if (!this.annotations.timestamp) { // The timestamp directive is not set on the field return false; } if (this.annotations.timestamp.operations.includes("CREATE")) { // The timestamp directive is set to generate on create return true; } // The timestamp directive is not set to generate on create return false; } populatedByCreateIsGenerated() { if (!this.annotations.populatedBy) { // The populatedBy directive is not set on the field return false; } if (this.annotations.populatedBy.operations.includes("CREATE")) { // The populatedBy directive is set to generate on create return true; } // The populatedBy directive is not set to generate on create return false; } isNonGeneratedField() { if (this.isCypher() || this.isCustomResolvable()) { return false; } if (this.annotations.id) { return false; } if (this.typeHelper.isEnum() || this.typeHelper.isScalar() || this.typeHelper.isSpatial()) { return true; } return false; } timestampUpdateIsGenerated() { if (!this.annotations.timestamp) { // The timestamp directive is not set on the field return false; } if (this.annotations.timestamp.operations.includes("UPDATE")) { // The timestamp directive is set to generate on update return true; } // The timestamp directive is not set to generate on update return false; } populatedByUpdateIsGenerated() { if (!this.annotations.populatedBy) { // The populatedBy directive is not set on the field return false; } if (this.annotations.populatedBy.operations.includes("UPDATE")) { // The populatedBy directive is set to generate on update return true; } // The populatedBy directive is not set to generate on update return false; } isArrayMethodField() { return (this.typeHelper.isList() && !this.typeHelper.isUserScalar() && (this.typeHelper.isScalar() || this.typeHelper.isSpatial())); } /** * Category Helpers * */ getDefaultValue() { return this.annotations.default?.value; } isReadable() { return this.annotations.selectable?.onRead !== false; } isAggregable() { return (this.annotations.selectable?.onAggregate !== false && this.isCustomResolvable() === false && this.isCypher() === false); } isAggregationFilterable() { return (this.annotations.filterable?.byAggregate !== false && this.isCustomResolvable() === false && this.isCypher() === false); } isFilterable() { return this.annotations.filterable?.byValue !== false; } isSortable() { return this.annotations.sortable?.byValue !== false; } isCustomResolvable() { return !!this.annotations.customResolver; } isGlobalIDAttribute() { return !!this.annotations.relayId; } /** * Type names * used to create different types for the Attribute or Entity that contains the Attributes */ getTypePrettyName() { if (!this.typeHelper.isList()) { return `${this.getTypeName()}${this.typeHelper.isRequired() ? "!" : ""}`; } const listType = this.type; if (listType.ofType instanceof AttributeType_1.ListType) { // matrix case return `[[${this.getTypeName()}${this.typeHelper.isListElementRequired() ? "!" : ""}]]${this.typeHelper.isRequired() ? "!" : ""}`; } return `[${this.getTypeName()}${this.typeHelper.isListElementRequired() ? "!" : ""}]${this.typeHelper.isRequired() ? "!" : ""}`; } getTypeName() { if (!this.typeHelper.isList()) { return this.type.name; } const listType = this.type; if (listType.ofType instanceof AttributeType_1.ListType) { // matrix case return listType.ofType.ofType.name; } return listType.ofType.name; // return this.isList() ? this.type.ofType.name : this.type.name; } getFieldTypeName() { if (!this.typeHelper.isList()) { return this.getTypeName(); } const listType = this.type; if (listType.ofType instanceof AttributeType_1.ListType) { // matrix case return `[[${this.getTypeName()}]]`; } return `[${this.getTypeName()}]`; } getInputTypeName() { if (this.typeHelper.isSpatial()) { if (this.getTypeName() === "Point") { return "PointInput"; } else { return "CartesianPointInput"; } } return this.getTypeName(); } // TODO: We should probably have this live in a different, more specific adapter getFilterableInputTypeName() { return `[${this.getInputTypeName()}${this.typeHelper.isRequired() ? "!" : ""}]`; } getInputTypeNames() { const pretty = this.typeHelper.isList() ? `[${this.getInputTypeName()}${this.typeHelper.isListElementRequired() ? "!" : ""}]` : this.getInputTypeName(); return { where: { type: this.getInputTypeName(), pretty }, create: { type: this.getTypeName(), pretty: `${pretty}${this.typeHelper.isRequired() ? "!" : ""}`, }, update: { type: this.getTypeName(), pretty, }, }; } getAggregateSelectionTypeName() { return `${this.getFieldTypeName()}AggregateSelection`; } } exports.AttributeAdapter = AttributeAdapter; //# sourceMappingURL=AttributeAdapter.js.map