UNPKG

koa-omnibus

Version:
88 lines (78 loc) 2.8 kB
const Application = require('koa') const defaults = require('./defaults.js') const debug = require('debug')('koa-omnibus') const createOptions = (...args) => { //const options = _.defaultsDeep({}, defaults, ...args) // < this doesn't work const options = Object.assign({}, defaults, ...args) // < however, this works fine options.headers = Object.freeze(Object.assign({}, defaults.headers, options.headers)) options.limits = Object.freeze(Object.assign({}, defaults.limits, options.limits)) options.namespace = options.namespace || 'state' // whenever namespace is false-y return Object.freeze(options) // XXX: should Options be a class? } const createMiddleware = (options) => { const { timing, tracing } = options.headers const limitRate = options.limitRate(options) const limitTime = options.limitTime(options) return async function omnibus(context, next) { const tracer = options.targetTracer(options, context, tracing) const log = options.targetLogger(options, context, { tracing: tracer }) const source = { log, timing: {}, tracing: tracer } // wrapped into: const target = options.targetObject(options, context, source) const start = (target.timing.start = process.hrtime()) try { await limitRate(context, next) await limitTime(context, next) target.error = null // no throw } catch (error) { target.error = options.targetError(options, context, error) } finally { const [s, ns] = process.hrtime(start) const ms = Number(s * 1e3 + ns / 1e6).toFixed(6) tracer[timing] = `${ms} millisecond(s)` // header const err = options.redactedError(options, context) const req = options.redactedRequest(options, context) const res = options.redactedResponse(options, context) if (!err) log.trace({ req, res }, 'request') else log.debug({ err, req, res }, 'request') } } } const omnibus = (...args) => { const options = createOptions(...args) debug('create with options: %j', options) return createMiddleware(options) } const createApplication = (options = createOptions()) => { let application = new Application() for (const key of ['before', 'hooks']) { const all = Array.isArray(options[key]) ? options[key] : [] for (const one of all) { switch (key) { case 'hooks': application = one(application) break default: application.use(one) } } } application.use(omnibus(options)) for (const key of ['after', 'routers']) { const all = Array.isArray(options[key]) ? options[key] : [] for (const one of all) { switch (key) { case 'routers': application.use(one.allowedMethods()) application.use(one.routes()) break default: application.use(one) } } } return application } module.exports = Object.assign(omnibus, { createApplication, default: omnibus, })