@graphql-mesh/neo4j
Version:
107 lines (102 loc) • 3.82 kB
JavaScript
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
const introspector = require('@neo4j/introspector');
const graphql = require('@neo4j/graphql');
const graphqlScalars = require('graphql-scalars');
const neo4j = _interopDefault(require('neo4j-driver'));
const store = require('@graphql-mesh/store');
const utils = require('@graphql-mesh/utils');
const crossHelpers = require('@graphql-mesh/cross-helpers');
function getEventEmitterFromPubSub(pubsub) {
return {
on(event, listener) {
pubsub.subscribe(event.toString(), listener);
return this;
},
once(event, listener) {
const id = pubsub.subscribe(event.toString(), data => {
listener(data);
pubsub.unsubscribe(id);
});
return this;
},
emit(event, ...args) {
pubsub.publish(event.toString(), args[0]);
return true;
},
addListener(event, listener) {
return this.on(event, listener);
},
setMaxListeners() {
return this;
},
};
}
class Neo4JHandler {
constructor({ config, baseDir, pubsub, store: store$1, logger, importFn }) {
this.config = config;
this.baseDir = baseDir;
this.pubsub = pubsub;
this.typeDefs = store$1.proxy('typeDefs.graphql', store.PredefinedProxyOptions.StringWithoutValidation);
this.logger = logger;
this.importFn = importFn;
}
getCachedTypeDefs(driver) {
return this.typeDefs.getWithSet(async () => {
if (this.config.typeDefs) {
return utils.readFileOrUrl(this.config.typeDefs, {
cwd: this.baseDir,
allowUnknownExtensions: true,
importFn: this.importFn,
fetch: this.fetchFn,
logger: this.logger,
});
}
else {
this.logger.info('Inferring the schema from the database: ', `"${this.config.database || 'neo4j'}"`);
return introspector.toGraphQLTypeDefs(() => driver.session({ database: this.config.database, defaultAccessMode: neo4j.session.READ }));
}
});
}
async getMeshSource({ fetchFn }) {
this.fetchFn = fetchFn;
const driver = neo4j.driver(this.config.url, neo4j.auth.basic(this.config.username, this.config.password), {
useBigInt: true,
logging: {
logger: (level, message) => this.logger[level](message),
},
});
const id = this.pubsub.subscribe('destroy', async () => {
this.pubsub.unsubscribe(id);
this.logger.debug('Closing Neo4j');
await driver.close();
this.logger.debug('Neo4j closed');
});
const typeDefs = await this.getCachedTypeDefs(driver);
const events = getEventEmitterFromPubSub(this.pubsub);
const neo4jGraphQL = new graphql.Neo4jGraphQL({
typeDefs,
config: {
driverConfig: {
database: this.config.database,
},
enableDebug: !!crossHelpers.process.env.DEBUG,
skipValidateTypeDefs: true,
},
resolvers: {
BigInt: graphqlScalars.GraphQLBigInt,
},
plugins: {
subscriptions: {
events,
publish: eventMeta => this.pubsub.publish(eventMeta.event, eventMeta),
},
},
driver,
});
return {
schema: await neo4jGraphQL.getSchema(),
};
}
}
module.exports = Neo4JHandler;