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

silvermine / lambda-express / 19483117235

18 Nov 2025 10:48PM UTC coverage: 98.389% (-0.3%) from 98.663%
19483117235

push

github

onebytegone
fix: add support for promise-based handlers

208 of 214 branches covered (97.2%)

Branch coverage included in aggregate %.

7 of 8 new or added lines in 2 files covered. (87.5%)

464 of 469 relevant lines covered (98.93%)

2000.51 hits per line

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

95.56
/src/Application.ts
1
import { Callback, Context } from 'aws-lambda';
2
import Router from './Router';
4✔
3
import { RequestEvent, HandlerContext, ResponseResult } from './request-response-types';
4
import { isUndefined, StringUnknownMap, Writable } from '@silvermine/toolbox';
4✔
5
import { Request, Response } from '.';
4✔
6
import { isErrorWithStatusCode } from './interfaces';
4✔
7

8
export default class Application extends Router {
4✔
9

10
   private _settings: StringUnknownMap = {};
1,412✔
11

12
   /**
13
    * Assigns setting `name` to `value`. You may store any value that you want, but
14
    * certain names can be used to configure the behavior of the server. These special
15
    * names are listed in the app settings table.
16
    *
17
    * Calling `app.setSetting('foo', true)` for a `Boolean` property is the same as
18
    * calling `app.enable('foo')`. Similarly, calling `app.setSetting('foo', false)` for a
19
    * `Boolean` property is the same as calling `app.disable('foo')`.
20
    *
21
    * Retrieve the value of a setting with `app.getSetting()`.
22
    *
23
    * ```
24
    * app.setSetting('title', 'My Site');
25
    * app.getSetting('title'); // "My Site"
26
    * ```
27
    *
28
    * ## App Settings Used By Lambda Express:
29
    *
30
    *  * `trust proxy` (default `false`): Determines whether `X-Forwarded-*` headers are
31
    *    trusted or not. Be careful when enabling this setting because these headers are
32
    *    easily spoofed.
33
    *  * `case sensitive routing` (default `false`): Determines whether routing is
34
    *    case-sensitive. When enabled, "/Foo" and "/foo" are different routes. When
35
    *    disabled, "/Foo" and "/foo" are treated the same. NOTE: Sub-apps (routers mounted
36
    *    by calling `addSubRouter`, or those created implicitly by calling `.route(path)`)
37
    *    will inherit the value of this setting.
38
    *
39
    * @param name The name of the setting
40
    * @param val The value to assign to the setting
41
    */
42
   public setSetting(name: string, val: unknown): Application {
43
      this._settings[name] = val;
264✔
44

45
      if (name === 'case sensitive routing') {
264✔
46
         this.routerOptions.caseSensitive = !!val;
16✔
47
      }
48
      return this;
264✔
49
   }
50

51
   /**
52
    * See `app.setSetting(name, val)`.
53
    */
54
   public getSetting(name: string): unknown {
55
      return this._settings[name];
6,904✔
56
   }
57

58
   /**
59
    * See `app.enable(name)` and `app.disable(name)`.
60
    * @param name the name of the setting to test
61
    */
62
   public isEnabled(name: string): boolean {
63
      return !!this.getSetting(name);
6,796✔
64
   }
65

66
   /**
67
    * Enable a setting with `name`, e.g. `app.enable('trust proxy')`.
68
    * @param name setting name
69
    */
70
   public enable(name: string): Application {
71
      return this.setSetting(name, true);
132✔
72
   }
73

74
   /**
75
    * Disable a setting with `key`, e.g. `app.disable('trust proxy')`.
76
    * @param name setting key
77
    */
78
   public disable(name: string): Application {
79
      return this.setSetting(name, false);
120✔
80
   }
81

82
   /**
83
    * Run the app for a Lambda invocation.
84
    *
85
    * @param evt The event provided to the Lambda handler
86
    * @param context The context provided to the Lambda handler
87
    * @param cb The callback provided to the Lambda handler
88
    *
89
    * @deprecated Use `runAsync()` instead. Callback-style handlers are deprecated in
90
    *             Node.js 24.
91
    */
92
   public run(evt: RequestEvent, context: Context, cb: Callback): void {
93
      const req = new Request(this, evt, this._createHandlerContext(context)),
612✔
94
            resp = new Response(this, req, cb);
612✔
95

96
      this.handle(undefined, req, resp, (err: unknown): void => {
612✔
97
         // handler of last resort:
98
         if (err) {
56✔
99
            resp.sendStatus(isErrorWithStatusCode(err) && err.statusCode ? err.statusCode : 500);
24✔
100
         } else {
101
            resp.sendStatus(404);
32✔
102
         }
103
      });
104
   }
105

106
   /**
107
    * Run the app for a Lambda invocation using async/await pattern.
108
    *
109
    * @param evt The event provided to the Lambda handler
110
    * @param context The context provided to the Lambda handler
111
    * @returns A Promise that resolves with the response result or rejects with an error
112
    */
113
   public runAsync(evt: RequestEvent, context: Context): Promise<ResponseResult> {
114
      return new Promise((resolve, reject) => {
36✔
115
         this.run(evt, context, (error, result) => {
36✔
116
            if (error) {
36!
NEW
117
               reject(error);
×
118
            } else {
119
               resolve(result as ResponseResult);
36✔
120
            }
121
         });
122
      });
123
   }
124

125
   private _createHandlerContext(context: Context): HandlerContext {
126
      const newContext: Writable<HandlerContext> = {
612✔
127
         functionName: context.functionName,
128
         functionVersion: context.functionVersion,
129
         invokedFunctionArn: context.invokedFunctionArn,
130
         memoryLimitInMB: context.memoryLimitInMB,
131
         awsRequestId: context.awsRequestId,
132
         logGroupName: context.logGroupName,
133
         logStreamName: context.logStreamName,
134
         getRemainingTimeInMillis: context.getRemainingTimeInMillis,
135
      };
136

137
      if (!isUndefined(context.identity)) {
612✔
138
         newContext.identity = Object.freeze({ ...context.identity });
4✔
139
      }
140

141
      if (!isUndefined(context.clientContext)) {
612✔
142
         newContext.clientContext = Object.freeze({ ...context.clientContext });
4✔
143
      }
144

145
      return Object.freeze(newContext);
612✔
146
   }
147

148
}
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