UNPKG

graphql-modules

Version:

Create reusable, maintainable, testable and extendable GraphQL modules

72 lines (71 loc) 2.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.moduleFactory = moduleFactory; const metadata_1 = require("./metadata"); const resolvers_1 = require("./resolvers"); const type_defs_1 = require("./type-defs"); const tokens_1 = require("./tokens"); const di_1 = require("../di"); const resolution_1 = require("./../di/resolution"); function lazy(getter) { let called = false; let computedValue; return { get value() { if (!called) { called = true; computedValue = getter(); } return computedValue; }, }; } function moduleFactory(config) { const typeDefs = (0, type_defs_1.createTypeDefs)(config); const metadata = (0, metadata_1.metadataFactory)(typeDefs, config); const providers = lazy(() => typeof config.providers === 'function' ? config.providers() : config.providers); // Filter providers and keep them this way // so we don't do this filtering multiple times. // Providers don't change over time, so it's safe to do it. const operationProviders = lazy(() => di_1.ReflectiveInjector.resolve((0, di_1.onlyOperationProviders)(providers.value))); const singletonProviders = lazy(() => di_1.ReflectiveInjector.resolve((0, di_1.onlySingletonProviders)(providers.value))); const mod = { id: config.id, config, metadata, typeDefs, // Factory is called once on application creation, // before we even handle GraphQL Operation factory(app) { const resolvedModule = mod; resolvedModule.singletonProviders = singletonProviders.value; resolvedModule.operationProviders = operationProviders.value; // Create a module-level Singleton injector const injector = di_1.ReflectiveInjector.createFromResolved({ name: `Module "${config.id}" (Singleton Scope)`, providers: resolvedModule.singletonProviders.concat((0, resolution_1.resolveProviders)([ { // with module's id, useful in Logging and stuff provide: tokens_1.MODULE_ID, useValue: config.id, }, ])), parent: app.injector, }); // We attach injector property to existing `mod` object // because we want to keep references // that are later on used in testing utils resolvedModule.injector = injector; // Create resolvers object based on module's config // It involves wrapping a resolver with middlewares // and other things like validation resolvedModule.resolvers = (0, resolvers_1.createResolvers)(config, metadata, { middlewareMap: app.middlewares, }); return resolvedModule; }, }; return mod; }