@graphql-mesh/neo4j
Version:
126 lines (125 loc) • 5.09 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const graphql_scalars_1 = require("graphql-scalars");
const neo4j_driver_1 = tslib_1.__importDefault(require("neo4j-driver"));
const cross_helpers_1 = require("@graphql-mesh/cross-helpers");
const store_1 = require("@graphql-mesh/store");
const utils_1 = require("@graphql-mesh/utils");
const delegate_1 = require("@graphql-tools/delegate");
const graphql_1 = require("@neo4j/graphql");
const introspector_1 = require("@neo4j/introspector");
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, logger, importFn, }) {
this.config = config;
this.baseDir = baseDir;
this.pubsub = pubsub;
this.typeDefs = store.proxy('typeDefs', store_1.PredefinedProxyOptions.StringWithoutValidation);
this.logger = logger;
this.importFn = importFn;
}
getCachedTypeDefs(driver) {
return this.typeDefs.getWithSet(async () => {
if (this.config.source) {
return (0, utils_1.readFileOrUrl)(this.config.source, {
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'}"`);
let replaceAllPolyfilled = false;
if (!String.prototype.replaceAll) {
replaceAllPolyfilled = true;
// eslint-disable-next-line no-extend-native
String.prototype.replaceAll = function (str, newStr) {
if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
return this.replace(str, newStr);
}
return this.replace(new RegExp(str, 'g'), newStr);
};
}
const typeDefs = await (0, introspector_1.toGraphQLTypeDefs)(() => driver.session({ database: this.config.database, defaultAccessMode: neo4j_driver_1.default.session.READ }));
if (replaceAllPolyfilled) {
// eslint-disable-next-line no-extend-native
delete String.prototype.replaceAll;
}
return typeDefs;
}
});
}
async getMeshSource({ fetchFn }) {
this.fetchFn = fetchFn;
const driver = neo4j_driver_1.default.driver(this.config.endpoint, neo4j_driver_1.default.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_1.Neo4jGraphQL({
typeDefs,
driver,
validate: false,
debug: !!cross_helpers_1.process.env.DEBUG,
resolvers: {
BigInt: graphql_scalars_1.GraphQLBigInt,
},
features: {
subscriptions: {
events,
publish: eventMeta => this.pubsub.publish(eventMeta.event, eventMeta),
},
},
});
const schema = await neo4jGraphQL.getSchema();
const defaultExecutor = (0, delegate_1.createDefaultExecutor)(schema);
const sessionConfig = {
database: this.config.database,
};
return {
schema: await neo4jGraphQL.getSchema(),
executor(executionRequest) {
executionRequest.context = executionRequest.context || {};
executionRequest.context.sessionConfig = sessionConfig;
return defaultExecutor(executionRequest);
},
};
}
}
exports.default = Neo4JHandler;