Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/graphql-toolset / src / GraphQLModule.ts
Size: Mime:
/**
 * @file @alias library
 * @todo https://github.com/apollographql/apollo-server/issues/1075#issuecomment-440768737
 */
import { Request as OneRequest, OneRequestStore } from '@skava/request'
import { mergeGraphQLSchemas } from '@graphql-modules/epoxy'
import {
  GraphQLModule as GraphQLCoreModule,
  GraphQLModuleOptions,
} from '@graphql-modules/core'

export { mergeGraphQLSchemas } from '@graphql-modules/epoxy'
export {
  GraphQLModule as GraphQLCoreModule,
  GraphQLModuleOptions,
} from '@graphql-modules/core'

export class GraphQLModule<
  Config = any,
  Request = any,
  Context = any
> extends GraphQLCoreModule<Config, Request, Context> {
  public dataSources: () => OneRequest | any
  public mergedContextBuilder: (context: Context) => Context
  public syncContextBuilder: (context: Context) => Context

  constructor(
    _options?: GraphQLModuleOptions<Config, Request, Context> & {
      dataSources?: () => OneRequest
    },
    _moduleConfig?: Config
  ) {
    const { dataSources, typeDefs, ...remainingOptions } = _options as any

    const mergedTypeDefs = Array.isArray(typeDefs)
      ? mergeGraphQLSchemas(typeDefs)
      : typeDefs

    const superOptions = { ...remainingOptions, typeDefs: mergedTypeDefs }
    super(superOptions, _moduleConfig)

    if (dataSources) {
      this.dataSources = dataSources
    }
    if (remainingOptions.contextBuilder) {
      this.syncContextBuilder = remainingOptions.contextBuilder as any
    }

    if (Array.isArray(remainingOptions.imports)) {
      this.dataSources = (arg?: any) => {
        const merged = {}
        const imported = remainingOptions.imports as any[]
        imported.forEach(graphqlModule => {
          // isFunction @todo
          if (graphqlModule.dataSources) {
            const returned = graphqlModule.dataSources(arg)
            Object.assign(merged, returned)
          }
        })

        if (dataSources) {
          const computedDataSources = dataSources(arg)
          Object.assign(merged, computedDataSources)
        }

        return merged
      }
    }

    // @note the one built in is async and weird
    /**
     * @todo - this does not hoist mergedContextBuilder?
     */
    if (Array.isArray(remainingOptions.imports)) {
      const mergedContextBuilder = (context: Context) => {
        const merged = {}
        const imported = remainingOptions.imports as any[]
        imported.forEach(graphqlModule => {
          if (graphqlModule.contextBuilder) {
            const returned = graphqlModule.contextBuilder(context)
            Object.assign(merged, returned)
          }
          if (graphqlModule.syncContextBuilder) {
            const returned = graphqlModule.syncContextBuilder(context)
            Object.assign(merged, returned)
          }
        })

        return merged
      }

      this.mergedContextBuilder = mergedContextBuilder as any
    }
  }
}