@graphql-mesh/transport-neo4j
Version:
100 lines (99 loc) • 3.41 kB
JavaScript
import { parse, visit } from 'graphql';
import { GraphQLBigInt } from 'graphql-scalars';
import { createDefaultExecutor } from '@graphql-tools/delegate';
import { getDirective, getDocumentNodeFromSchema } from '@graphql-tools/utils';
import { Neo4jGraphQL } from '@neo4j/graphql';
import { getDriverFromOpts } from './driver.js';
import { getEventEmitterFromPubSub } from './eventEmitterForPubSub.js';
function filterIntrospectionDefinitions(node) {
if (!node.directives?.some(directive => directive.name.value === 'introspection')) {
return null;
}
return node;
}
export async function getNeo4JExecutor(opts) {
const transportDirectives = getDirective(opts.schema, opts.schema, 'transport');
if (!transportDirectives?.length) {
throw new Error('No transport directive found on the schema!');
}
const { location: endpoint, options: { database, auth }, } = transportDirectives[0];
let driver = opts.driver;
if (!driver) {
driver = getDriverFromOpts({
endpoint,
auth,
logger: opts.logger,
});
}
let typeDefs = getDocumentNodeFromSchema(opts.schema);
const astVisitor = {
enter: filterIntrospectionDefinitions,
};
typeDefs = visit(typeDefs, {
EnumTypeDefinition: astVisitor,
ObjectTypeDefinition: astVisitor,
InterfaceTypeDefinition: astVisitor,
UnionTypeDefinition: astVisitor,
InputObjectTypeDefinition: astVisitor,
FieldDefinition: astVisitor,
// DirectiveDefinition: astVisitor,
ScalarTypeDefinition: astVisitor,
EnumValueDefinition: astVisitor,
InputValueDefinition: astVisitor,
});
typeDefs.definitions.push(...parse(/* GraphQL */ `
directive @source(
subgraph: String
name: String
type: String
) on ENUM | OBJECT | INTERFACE | UNION | INPUT_OBJECT | FIELD_DEFINITION | SCALAR | ENUM_VALUE | INPUT_FIELD_DEFINITION
`).definitions);
const executableSchema = await getExecutableSchemaFromTypeDefsAndDriver({
driver,
logger: opts.logger,
pubsub: opts.pubsub,
typeDefs,
});
const defaultExecutor = createDefaultExecutor(executableSchema);
const sessionConfig = {
database,
};
return function neo4JExecutor(args) {
return defaultExecutor({
...args,
context: {
...args.context,
sessionConfig,
},
});
};
}
export function getExecutableSchemaFromTypeDefsAndDriver({ driver, logger, pubsub, typeDefs, }) {
let features;
if (pubsub) {
features = {
subscriptions: {
events: getEventEmitterFromPubSub(pubsub),
publish: eventMeta => pubsub.publish(eventMeta.event, eventMeta),
close: () => { },
},
};
const id = pubsub.subscribe('destroy', async () => {
pubsub.unsubscribe(id);
logger?.debug('Closing Neo4j');
await driver.close();
logger?.debug('Neo4j closed');
});
}
const neo4jGraphQL = new Neo4jGraphQL({
typeDefs,
driver,
validate: false,
debug: !!process.env.DEBUG,
resolvers: {
BigInt: GraphQLBigInt,
},
features,
});
return neo4jGraphQL.getSchema();
}