@neo4j/graphql
Version:
A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations
136 lines • 6.59 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.generateSubscriptionTypes = generateSubscriptionTypes;
const graphql_1 = require("graphql");
const EventType_1 = require("../../graphql/enums/EventType");
const ConcreteEntityAdapter_1 = require("../../schema-model/entity/model-adapters/ConcreteEntityAdapter");
const where_input_1 = require("../generation/where-input");
const subscribe_1 = require("../resolvers/subscriptions/subscribe");
const to_compose_1 = require("../to-compose");
function generateSubscriptionTypes({ schemaComposer, schemaModel, userDefinedFieldDirectivesForNode, features, }) {
const subscriptionComposer = schemaComposer.Subscription;
const eventTypeEnum = schemaComposer.createEnumTC(EventType_1.EventType);
const allNodes = schemaModel.concreteEntities.map((e) => new ConcreteEntityAdapter_1.ConcreteEntityAdapter(e));
const nodeNameToEventPayloadTypes = allNodes.reduce((acc, entityAdapter) => {
const userDefinedFieldDirectives = userDefinedFieldDirectivesForNode.get(entityAdapter.name);
if (!userDefinedFieldDirectives) {
throw new Error("fix user directives for object types in subscriptions.");
}
acc[entityAdapter.name] = schemaComposer.createObjectTC({
name: entityAdapter.operations.subscriptionEventPayloadTypeName,
fields: (0, to_compose_1.attributeAdapterToComposeFields)(entityAdapter.subscriptionEventPayloadFields, userDefinedFieldDirectives),
});
return acc;
}, {});
function generateSubscriptionWhere(entityAdapter) {
return (0, where_input_1.withWhereInputType)({
entityAdapter,
composer: schemaComposer,
typeName: entityAdapter.operations.subscriptionWhereInputTypeName,
features,
userDefinedFieldDirectives: userDefinedFieldDirectivesForNode[entityAdapter.name],
returnUndefinedIfEmpty: true,
alwaysAllowNesting: true,
ignoreCypherFieldFilters: true,
});
}
allNodes.forEach((entityAdapter) => generateSubscriptionWhere(entityAdapter));
const nodesWithSubscriptionOperation = allNodes.filter((e) => e.isSubscribable(schemaModel));
nodesWithSubscriptionOperation.forEach((entityAdapter) => {
const eventPayload = nodeNameToEventPayloadTypes[entityAdapter.name];
const where = generateSubscriptionWhere(entityAdapter);
const createField = (type) => schemaComposer.createObjectTC({
name: entityAdapter.operations.subscriptionEventTypeNames[type],
fields: {
event: {
type: eventTypeEnum.NonNull,
resolve: () => EventType_1.EventType.getValue(type.toUpperCase())?.value,
},
timestamp: {
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLFloat),
resolve: (source) => source.timestamp,
},
},
});
const nodeCreatedEvent = createField("create");
const nodeUpdatedEvent = createField("update");
const nodeDeletedEvent = createField("delete");
if (hasProperties(eventPayload)) {
nodeCreatedEvent.addFields({
[entityAdapter.operations.subscriptionEventPayloadFieldNames.create]: {
type: eventPayload.NonNull,
resolve: (source) => source.properties.new,
},
});
nodeUpdatedEvent.addFields({
previousState: {
type: eventPayload.NonNull,
resolve: (source) => source.properties.old,
},
[entityAdapter.operations.subscriptionEventPayloadFieldNames.update]: {
type: eventPayload.NonNull,
resolve: (source) => source.properties.new,
},
});
nodeDeletedEvent.addFields({
[entityAdapter.operations.subscriptionEventPayloadFieldNames.delete]: {
type: eventPayload.NonNull,
resolve: (source) => source.properties.old,
},
});
}
const whereArgument = where && { args: { where } };
if (entityAdapter.isSubscribableOnCreate(schemaModel)) {
subscriptionComposer.addFields({
[entityAdapter.operations.rootTypeFieldNames.subscribe.created]: {
...whereArgument,
type: nodeCreatedEvent.NonNull,
subscribe: (0, subscribe_1.generateSubscribeMethod)({ entityAdapter, type: "create" }),
resolve: subscribe_1.subscriptionResolve,
},
});
}
if (entityAdapter.isSubscribableOnUpdate(schemaModel)) {
subscriptionComposer.addFields({
[entityAdapter.operations.rootTypeFieldNames.subscribe.updated]: {
...whereArgument,
type: nodeUpdatedEvent.NonNull,
subscribe: (0, subscribe_1.generateSubscribeMethod)({ entityAdapter, type: "update" }),
resolve: subscribe_1.subscriptionResolve,
},
});
}
if (entityAdapter.isSubscribableOnDelete(schemaModel)) {
subscriptionComposer.addFields({
[entityAdapter.operations.rootTypeFieldNames.subscribe.deleted]: {
...whereArgument,
type: nodeDeletedEvent.NonNull,
subscribe: (0, subscribe_1.generateSubscribeMethod)({ entityAdapter, type: "delete" }),
resolve: subscribe_1.subscriptionResolve,
},
});
}
});
}
function hasProperties(x) {
return !!Object.keys(x.getFields()).length;
}
//# sourceMappingURL=generate-subscription-types.js.map