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/request / src / adapters / apollo.ts
Size: Mime:
import { RESTDataSource, RequestOptions } from 'apollo-datasource-rest'
import { fromMapToObj, isString } from 'exotic'
import {
  OneRequestStore,
  CacheOptions,
  OneRequest,
  OneRequestStoreAsObj,
} from '../typings'
import {
  fromHeadersToSerialized,
  fromParamsToSerializedUrlParams,
} from '../deps/fromOneRequestToSerialized'
import { encodeBody } from '../deps/encodeBody'
import { config } from '../config'

function fromStoreToCacheOptions(store: OneRequestStore) {
  if (store.has('cache') === false) {
    return config.get('defaultCache')
  } else if (store.get('cache') === false) {
    return undefined
  } else {
    return store.get('cache')
  }
}

/**
 * @todo may want to set this in `willSendRequest`?
 * @todo support if headers already has `Content-Type`?
 */
function setContentType(headers: Headers) {
  // @todo split
  // === compat: 7.5 ===
  if (config.get('shouldEncodeGetWithFormBody') === true) {
    headers.set('Content-Type', 'application/x-www-form-urlencoded')
  } else {
    headers.set('Content-Type', 'application/json')
  }
}

export class OneRequestApolloDataSource extends RESTDataSource {
  debugName?: string
  baseURL: string
  store: OneRequestStore
  // oneRequest: OneRequest

  cacheOptionsFor(response: Response, request: Request): CacheOptions {
    const cacheOption = fromStoreToCacheOptions(this.store)

    config
      .get('logger')
      .info('cache for: ' + request.url + JSON.stringify(cacheOption))

    return cacheOption
  }
  cacheKeyFor(request: Request) {
    const COOKIE_NAMESPACE_FIX_GET_FROM_ENV =
      process.env.GUEST_COOKIE_NAMESPACE || 'ckcjeu_'
    const COOKIE_NAMESPACE_REGISTERED_FIX_GET_FROM_ENV =
      process.env.REGISTERED_COOKIE_NAMESPACE || 'ckcjeustat_'
    const SESSION_ID_NAMESPACE =
      process.env.SESSION_ID_NAMESPACE || 'x-sk-session-id'
    const registered =
      request.headers.get(COOKIE_NAMESPACE_REGISTERED_FIX_GET_FROM_ENV) || ''
    const sessionId = request.headers.get(SESSION_ID_NAMESPACE) || ''

    const guest = request.headers.get(COOKIE_NAMESPACE_FIX_GET_FROM_ENV) || ''

    return guest + registered + sessionId + request.url
  }

  // @todo should add logging hook here.....
  // @note - this prevents errors from being thrown
  // which may have unintended side effects
  didReceiveResponse(response: Response, request: Request) {
    // console.debug('[1request]')
    // console.log({ response, request })
    // console.debug('=== \n\n')
    return response
  }

  // requestWillMount / requestWillCreate
  // just here for debugging
  // async willSendRequest(request: RequestOptions): Promise<void> {
  //   if (process.env.NODE_ENV === 'production') return
  //   const url = await this.resolveURL(request)
  //   for (const [name, value] of request.params)
  //     url.searchParams.append(name, value)
  //   console.info('[1request] willSendRequest: ')
  //   console.log({ request, url: url.href })
  // }

  setup(store: OneRequestStore) {
    this.store = store
    this.debugName = this.store.get('named')
    this.baseURL = this.store.get('baseUrl')

    return this
  }

  params(params: any) {
    console.warn('[apolloRestDataSource]:params', params)
    return this
  }
  path(path: string) {
    console.warn('[apolloRestDataSource]:path', path)
    return this
  }

  get headers() {
    return this.store.get('headers')
  }

  willSendRequest(request: RequestOptions) {
    const oneRequestAsObj = fromMapToObj(this.store) as OneRequestStoreAsObj
    const { params } = oneRequestAsObj
    if (params) {
      Object.keys(params).forEach(key => {
        request.params.set(
          key,
          isString(params[key]) ? params[key] : JSON.stringify(params[key])
        )
      })
    }
  }

  toDebug() {
    const oneRequestAsObj = fromMapToObj(this.store) as OneRequestStoreAsObj
    const { headers, params, method, body } = oneRequestAsObj

    setContentType(headers)
    const serializedHeaders = fromHeadersToSerialized(headers)
    const finalPath = fromParamsToSerializedUrlParams(params, this.store)

    const debugArgs = {
      headers: serializedHeaders,
      finalPath: finalPath.href,
      params,
      method,
      body,
    }

    return debugArgs
  }

  doRequest() {
    const oneRequestAsObj = fromMapToObj(this.store) as OneRequestStoreAsObj
    const { headers, urlObj, method, body } = oneRequestAsObj

    setContentType(headers)
    const serializedHeaders = fromHeadersToSerialized(headers)

    config
      .get('logger')
      .info('[1request] doRequest (apolloRestDataSource): ', this.toDebug())

    const args = {
      method,
      path: urlObj.href,
      body: undefined,
      headers: serializedHeaders,
    }

    if (method.toLowerCase() === 'post' || method.toLowerCase() === 'patch') {
      config.get('logger').debug('[1request] using patch / post')

      args.body = body
    }

    // this `as any` is because fetch is marked as private, so we bypass that
    return (this as any).fetch(args)

    // === when forking ===
    // return this._fetch(args)
    // === actual request ===
    // const secondArg = method === 'post' ? body : params
    // return this[method.toLowerCase()](path, secondArg, { headers })
    // === body on get ===
    // const args = { method, path, params, body, headers }
    // return (this as any).fetch(args)
  }
}

/**
 * @alias asRestDataSource
 */
export function apolloRestDataSource(store: OneRequestStore) {
  store
    .get('context')
    .log.debug('[1request] doRequest (adaptRequest - apolloRestDataSource): ')

  return new OneRequestApolloDataSource().setup(store)
}