# All files utils.js

87.09% Statements 81/93
76.19% Branches 16/21
77.77% Functions 7/9
87.09% Lines 81/93

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    941x
    1x
    1x
    1x
    1x
    1x
    1x
    1x

    1x
    1x

    1x
    1x
    15x
    15x
    15x
    15x
    15x
    1x
    1x
    9x
    9x
    9x
    9x
    9x
    1x
    1x
    87x
    87x
    87x
    87x
    1x
    1x
    117x
    117x
    117x
    9x
    9x
    9x
    117x
    1x
    1x
    5x
    5x
    5x
    5x
    25x
    25x
    25x
    25x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x
    5x

    5x
    5x
    5x

    5x
    5x
    1x
    1x
    1x
    8x
    8x
    8x
    1x
    1x
    5x
    5x
    5x

    5x
    5x
    5x
    1x
     import errors from '@feathersjs/errors'

    const { Unavailable, NotFound } = errors

    export const DEFAULT_EVENTS = ['created', 'updated', 'patched', 'removed']
    export const DEFAULT_METHODS = ['find', 'get', 'create', 'update', 'patch', 'remove']

    export function isKoaApp (app) {
      return typeof app.request === 'object' && typeof app.request.query === 'object'
    }

    export function isExpressApp (app) {
      return typeof app.request === 'object' && typeof app.request.app === 'function'
    }

    export function isInternalService (app, serviceDescriptor) {
      // Default is to expose all services
      if (!app.distributionOptions.services) return false
      if (typeof app.distributionOptions.services === 'function') return !app.distributionOptions.services(serviceDescriptor)
      else return !app.distributionOptions.services.includes(serviceDescriptor.path)
    }

    export function isDiscoveredService (app, serviceDescriptor) {
      // Default is to discover all services
      if (!app.distributionOptions.remoteServices) return true
      if (typeof app.distributionOptions.remoteServices === 'function') return app.distributionOptions.remoteServices(serviceDescriptor)
      else return app.distributionOptions.remoteServices.includes(serviceDescriptor.path)
    }

    export function getServicePath (app, serviceDescriptor) {
      // Default is to same as remote path
      if (!app.distributionOptions.remoteServicePath) return serviceDescriptor.path
      else return app.distributionOptions.remoteServicePath(serviceDescriptor)
    }

    export function getService (app, path) {
      try {
        return app.service(path)
      } catch {
        // We return a false-y value in case the service wasn't found
        return null
      }
    }

    export async function healthcheck (app, key) {
      // List all available services
      let services = Object.getOwnPropertyNames(app.services)
      // Filter non-remote ones and not matching key
      services = services.filter(path => {
        const service = getService(app, path)
        if (!service || !service.remote) return false
        // In this case we'd like all services
        return (key === app.distributionKey ? true : (service.key === key))
      })

      const response = {}
      const errors = []
      // Perform all operations in // so that it will speed-up in case of eg timeouts
      await Promise.all(services.map(async path => {
        const service = getService(app, path)
        try {
          await service.healthcheck()
          // For more detail we store the list of failed/successful services
          Object.assign(response, { [service.path]: true })
        } catch (error) {
          errors.push(error)
          // For more detail we store the list of failed/successful services
          Object.assign(response, { [service.path]: false })
        }
      }))

      if (errors.length > 0) {
        throw new Unavailable('Unavailable distributed service(s) for app with key ' + key, Object.assign(response, { errors }))
      }
      return response
    }

    export class HealthcheckService {
      constructor (app) {
        // Keep track of app
        this.app = app
      }

      async find (params) {
        const key = params.route.key || this.app.distributionKey
        // Not yet registered
        if ((key !== this.app.distributionKey) && !this.app.serviceRequesters[key]) {
          throw new NotFound(`No app registered with key ${key}`)
        }

        return healthcheck(this.app, key)
      }
    }