@omnigraph/neo4j
Version:
155 lines (154 loc) • 5.96 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getExecutableSchemaFromTypeDefsAndDriver = exports.loadGraphQLSchemaFromNeo4J = void 0;
const tslib_1 = require("tslib");
const graphql_1 = require("graphql");
const graphql_scalars_1 = require("graphql-scalars");
const neo4j_driver_1 = tslib_1.__importDefault(require("neo4j-driver"));
const schema_1 = require("@graphql-tools/schema");
const graphql_2 = require("@neo4j/graphql");
const introspector_1 = require("@neo4j/introspector");
const driver_js_1 = require("./driver.js");
const eventEmitterForPubSub_js_1 = require("./eventEmitterForPubSub.js");
const strReplaceAllPolyfill_js_1 = require("./strReplaceAllPolyfill.js");
function createAddIntrospectionDirective(subgraph) {
return function addIntrospectionDirective(node) {
if (!node.directives?.some(directive => directive.name.value === 'introspection')) {
return {
...node,
directives: [
...(node.directives || []),
{
kind: 'Directive',
name: {
kind: 'Name',
value: 'introspection',
arguments: [
{
kind: 'Argument',
name: {
kind: 'Name',
value: 'subgraph',
},
value: {
kind: 'StringValue',
value: subgraph,
},
},
],
},
},
],
};
}
};
}
async function loadGraphQLSchemaFromNeo4J(subgraphName, { endpoint, auth, logger, pubsub, database = 'neo4j', driver }) {
logger?.info('Inferring the schema from the database: ', `"${database}"`);
let closeDriverAfter = false;
if (!driver) {
closeDriverAfter = !pubsub;
driver = (0, driver_js_1.getDriverFromOpts)({
endpoint,
auth,
logger,
});
}
(0, strReplaceAllPolyfill_js_1.polyfillStrReplaceAll)();
const typeDefsStr = await (0, introspector_1.toGraphQLTypeDefs)(() => driver.session({
database,
defaultAccessMode: neo4j_driver_1.default.session.READ,
}));
let typeDefs = (0, graphql_1.parse)(typeDefsStr, { noLocation: true });
const addIntrospectionDirective = createAddIntrospectionDirective(subgraphName);
typeDefs = (0, graphql_1.visit)(typeDefs, {
EnumTypeDefinition: addIntrospectionDirective,
ObjectTypeDefinition: addIntrospectionDirective,
InterfaceTypeDefinition: addIntrospectionDirective,
UnionTypeDefinition: addIntrospectionDirective,
InputObjectTypeDefinition: addIntrospectionDirective,
FieldDefinition: addIntrospectionDirective,
// DirectiveDefinition: addIntrospectionDirective,
ScalarTypeDefinition: addIntrospectionDirective,
EnumValueDefinition: addIntrospectionDirective,
InputValueDefinition: addIntrospectionDirective,
});
typeDefs.definitions.push(...(0, graphql_1.parse)(
/* GraphQL */ `
directive @relationshipProperties on OBJECT
directive @relationship(type: String, direction: _RelationDirections) on FIELD_DEFINITION
enum _RelationDirections {
IN
OUT
}
directive @introspection(
subgraph: String
) on ENUM | OBJECT | INTERFACE | UNION | INPUT_OBJECT | FIELD_DEFINITION | SCALAR | ENUM_VALUE | INPUT_FIELD_DEFINITION
`, {
noLocation: true,
}).definitions);
(0, strReplaceAllPolyfill_js_1.revertStrReplaceAllPolyfill)();
const schema = await getExecutableSchemaFromTypeDefsAndDriver({
driver,
logger,
pubsub,
typeDefs,
});
if (closeDriverAfter) {
await driver.close();
}
const schemaExtensions = (schema.extensions ||= {});
schemaExtensions.directives = schemaExtensions.directives || {};
schemaExtensions.directives.transport = {
kind: 'neo4j',
subgraph: subgraphName,
location: endpoint,
options: {
database,
auth,
},
};
return (0, schema_1.mergeSchemas)({
schemas: [schema],
typeDefs: [
typeDefs,
`
scalar Any
directive @transport(kind: String, subgraph: String, location: String, options: Any) on SCHEMA
`,
],
assumeValid: true,
assumeValidSDL: true,
});
}
exports.loadGraphQLSchemaFromNeo4J = loadGraphQLSchemaFromNeo4J;
function getExecutableSchemaFromTypeDefsAndDriver({ driver, logger, pubsub, typeDefs, }) {
let features;
if (pubsub) {
features = {
subscriptions: {
events: (0, eventEmitterForPubSub_js_1.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 graphql_2.Neo4jGraphQL({
typeDefs,
driver,
validate: false,
debug: !!process.env.DEBUG,
resolvers: {
BigInt: graphql_scalars_1.GraphQLBigInt,
},
features,
});
return neo4jGraphQL.getSchema();
}
exports.getExecutableSchemaFromTypeDefsAndDriver = getExecutableSchemaFromTypeDefsAndDriver;
;