• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jeffijoe / awilix-koa / 12956685791

24 Jan 2025 08:00PM UTC coverage: 90.278%. Remained the same
12956685791

Pull #72

github

web-flow
Merge 4cc41df34 into 8f92495cd
Pull Request #72: Add type parameters to Router definitions

21 of 28 branches covered (75.0%)

6 of 7 new or added lines in 2 files covered. (85.71%)

2 existing lines in 1 file now uncovered.

65 of 72 relevant lines covered (90.28%)

10.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.5
/src/invokers.ts
1
import {
8✔
2
  asFunction,
3
  Resolver,
4
  AwilixContainer,
5
  ResolverOptions,
6
  Constructor,
7
  asClass,
8
  ClassOrFunctionReturning,
9
  FunctionReturning,
10
} from 'awilix'
11
import { isClass } from 'awilix/lib/utils'
8✔
12
import { MethodName } from 'awilix-router-core'
13
import assert from 'assert'
8✔
14

15
/**
16
 * Creates either a function invoker or a class invoker, based on whether
17
 * the argument can be classified as a class or not. Uses Awilix' `isClass` utility.
18
 *
19
 * @param functionOrClass
20
 * The function or class to invoke.
21
 *
22
 * @param opts
23
 * Resolver options for the class/function.
24
 */
25
export function makeInvoker<T>(
8✔
26
  functionOrClass: ClassOrFunctionReturning<T>,
27
  opts?: ResolverOptions<T>,
28
) {
29
  return isClass(functionOrClass)
12✔
30
    ? makeClassInvoker(functionOrClass as Constructor<T>, opts)
31
    : makeFunctionInvoker(functionOrClass as FunctionReturning<T>, opts)
32
}
33

34
/**
35
 * Returns a function that when called with a name,
36
 * returns another function to be used as Koa middleware.
37
 * That function will run `fn` with the container cradle as the
38
 * only parameter, and then call the `methodToInvoke` on
39
 * the result.
40
 *
41
 * @param {Function} fn
42
 * @param opts
43
 * @return {(methodToInvoke: string) => (ctx) => void}
44
 */
45
export function makeFunctionInvoker<T>(
8✔
46
  fn: FunctionReturning<T>,
47
  opts?: ResolverOptions<T>,
48
) {
49
  return makeResolverInvoker(asFunction(fn, opts))
8✔
50
}
51

52
/**
53
 * Same as `makeInvoker` but for classes.
54
 *
55
 * @param {Class} Class
56
 * @param opts
57
 * @return {(methodToInvoke: string) => (ctx) => void}
58
 */
59
export function makeClassInvoker<T>(
8✔
60
  Class: Constructor<T>,
61
  opts?: ResolverOptions<T>,
62
) {
63
  return makeResolverInvoker(asClass(Class, opts))
12✔
64
}
65

66
/**
67
 * Returns a function that when called with a method name,
68
 * returns another function to be used as Koa middleware.
69
 * That function will run `container.build(resolver)`, and
70
 * then call the method on the result, passing in the Koa context
71
 * and `next()`.
72
 *
73
 * @param {Resolver} resolver
74
 * @return {(methodToInvoke: string) => (ctx) => void}
75
 */
76
export function makeResolverInvoker<T>(resolver: Resolver<T>) {
8✔
77
  const singleton = resolver.lifetime === 'SINGLETON'
20✔
78
  let _resolved: any
79

80
  /**
81
   * 2nd step is to create a method to invoke on the result
82
   * of the resolver.
83
   *
84
   * @param  {MethodName} methodToInvoke
85
   * @return {(ctx) => void}
86
   */
87
  return function makeMemberInvoker(methodToInvoke: MethodName) {
20✔
88
    /**
89
     * The invoker middleware.
90
     *
91
     * @param  {Koa.Context} ctx
92
     * @param  {...*} rest
93
     * @return {*}
94
     */
95
    return function memberInvoker(ctx: any, ...rest: any[]) {
86✔
96
      const container: AwilixContainer = ctx.state.container
30✔
97
      if (!container) {
30!
NEW
98
        throw new Error(
×
99
          'Awilix container not found on Koa state object. Please ensure you use either scopePerRequest or attachContainer',
100
        )
101
      }
102

103
      let resolved: any
104
      if (singleton) {
30!
UNCOV
105
        if (!_resolved) {
×
UNCOV
106
          _resolved = container.build(resolver)
×
107
        }
108
        resolved = _resolved
×
109
      } else {
110
        resolved = container.build(resolver)
30✔
111
      }
112

113
      assert(
30✔
114
        methodToInvoke,
115
        `methodToInvoke must be a valid method type, such as string, number or symbol, but was ${String(
116
          methodToInvoke,
117
        )}`,
118
      )
119
      return resolved[methodToInvoke](ctx, ...rest)
30✔
120
    }
121
  }
122
}
123

124
/**
125
 * Injects dependencies into the middleware factory when the middleware is invoked.
126
 *
127
 * @param factory
128
 */
129
export function inject(factory: ClassOrFunctionReturning<any> | Resolver<any>) {
8✔
130
  const resolver = getResolver(factory)
4✔
131
  /**
132
   * The invoker middleware.
133
   */
134
  return function middlewareFactoryHandler(ctx: any, ...rest: any[]) {
24✔
135
    const container: AwilixContainer = ctx.state.container
8✔
136
    const resolved: any = container.build(resolver)
8✔
137
    return resolved(ctx, ...rest)
8✔
138
  }
139
}
140

141
/**
142
 * Wraps or returns a resolver.
143
 */
144
function getResolver<T>(
145
  arg: ClassOrFunctionReturning<T> | Resolver<T>,
146
): Resolver<T> {
147
  if (typeof arg === 'function') {
4✔
148
    return asFunction(arg as any)
2✔
149
  }
150

151
  return arg
2✔
152
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc