Skip to content

Commit e898896

Browse files
committed
fix: add dist folder to repo as a workaround for an npm bug
1 parent 44f3391 commit e898896

14 files changed

+1313
-3
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,5 @@ typings/
6060
# next.js build output
6161
.next
6262

63-
# dist
64-
dist
63+
# dist - don't ignore it as there is a bug in npm which messes up installation of git modules with npm ci
64+
#dist

dist/lambda-wrapper.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Request } from './request';
2+
import { Response } from './response';
3+
import { APIGatewayProxyResult } from 'aws-lambda';
4+
export interface Middleware {
5+
(request: Request, response: Response, next: (param?: unknown) => void): void;
6+
}
7+
export interface OnFinishedHandler {
8+
(out: unknown, req: Request, res: Response): Promise<APIGatewayProxyResult>;
9+
}
10+
declare const _default: {
11+
ApiGatewayHandler: (router: Middleware, onFinished: OnFinishedHandler) => import("aws-lambda").Handler<import("aws-lambda").APIGatewayProxyEvent, APIGatewayProxyResult>;
12+
};
13+
export default _default;

dist/lambda-wrapper.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
const request_1 = require("./request");
4+
const response_1 = require("./response");
5+
/**
6+
* API Gateway handler generator for Lambda
7+
*
8+
* @param router Express compatible router instance
9+
* @param onFinished Last callback before output gets send. Function params: out, req, res
10+
* @return Lambda handler for API gateway events
11+
* @public
12+
*/
13+
const ApiGatewayHandler = (router, onFinished) => {
14+
/**
15+
* Lambda Handler for API Gateway invocations
16+
*
17+
* @param {object} event API Gateway event object
18+
* @param {object} context API Gateway context object
19+
* @return {promise} Returns undefined if callback param is set. Return a promise if callback param is undefined.
20+
*/
21+
const handleApiGatewayEvent = function (event, context) {
22+
return new Promise(resolve => {
23+
const req = new request_1.Request(event);
24+
const res = (req.res = new response_1.Response(req, async (err, out) => {
25+
if (err) {
26+
console.error(err);
27+
}
28+
// run and wait for onFinished callback
29+
if (onFinished)
30+
try {
31+
out = await onFinished(err || out, req, res);
32+
}
33+
catch (err) {
34+
console.error('Error in onFinished callback: ', err);
35+
}
36+
// resolve promise even if onFinished callback errors out
37+
resolve(out);
38+
}));
39+
router(req, res, err => {
40+
// handle generic routing errors
41+
// use error handling middleware for more granular control
42+
if (err) {
43+
console.error('ERROR: ', err);
44+
res.status(500).send('Server error');
45+
}
46+
else {
47+
res.status(404).send('Not found');
48+
}
49+
});
50+
});
51+
};
52+
return handleApiGatewayEvent;
53+
};
54+
exports.default = { ApiGatewayHandler };
55+
module.exports = { ApiGatewayHandler };

dist/lambda-wrapper.spec.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {};

dist/lambda-wrapper.spec.js

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
"use strict";
2+
const { ApiGatewayHandler } = require('./lambda-wrapper');
3+
const Router = require('router');
4+
const bodyParser = require('body-parser');
5+
describe('Lambda Wrapper', () => {
6+
const proxyRequest = {
7+
body: null,
8+
headers: {},
9+
multiValueHeaders: {},
10+
httpMethod: 'POST',
11+
isBase64Encoded: false,
12+
path: '/path',
13+
pathParameters: {},
14+
queryStringParameters: {},
15+
multiValueQueryStringParameters: {},
16+
stageVariables: {},
17+
requestContext: {},
18+
resource: ''
19+
};
20+
it('should send json output properly', async () => {
21+
const router = Router();
22+
router.use((req, res) => {
23+
res.json({ a: 1 });
24+
});
25+
const lambdaHandler = ApiGatewayHandler(router);
26+
const proxyRequest = {
27+
body: '',
28+
headers: {},
29+
multiValueHeaders: {},
30+
httpMethod: 'GET',
31+
isBase64Encoded: false,
32+
path: '/path',
33+
pathParameters: {},
34+
queryStringParameters: {},
35+
multiValueQueryStringParameters: {},
36+
stageVariables: {},
37+
requestContext: {},
38+
resource: ''
39+
};
40+
const result = await lambdaHandler(proxyRequest, {});
41+
expect(result).toEqual({
42+
statusCode: 200,
43+
headers: {
44+
'content-type': 'application/json'
45+
},
46+
body: '{"a":1}'
47+
});
48+
});
49+
it('should handle json body on a post request', async () => {
50+
const router = Router();
51+
router.use(bodyParser.json());
52+
router.use((req, res) => {
53+
res.json(req.body);
54+
});
55+
const lambdaHandler = ApiGatewayHandler(router);
56+
const requestObject = JSON.stringify({ a: 1 });
57+
const proxyRequest = {
58+
body: requestObject,
59+
headers: {
60+
'Content-Type': 'application/json',
61+
'Content-Length': requestObject.length
62+
},
63+
multiValueHeaders: {
64+
'Content-Type': ['application/json'],
65+
'Content-Length': [requestObject.length]
66+
},
67+
httpMethod: 'POST',
68+
isBase64Encoded: false,
69+
path: '/path',
70+
pathParameters: {},
71+
queryStringParameters: {},
72+
multiValueQueryStringParameters: {},
73+
stageVariables: {},
74+
requestContext: {},
75+
resource: ''
76+
};
77+
const result = await lambdaHandler(proxyRequest, {});
78+
expect(result).toEqual({
79+
statusCode: 200,
80+
headers: {
81+
'content-type': 'application/json'
82+
},
83+
body: requestObject
84+
});
85+
});
86+
it('should run multiple middlewares', async () => {
87+
expect.assertions(1);
88+
const router = Router();
89+
router.use((req, res, next) => {
90+
req.fromFirstEndpoint = '1';
91+
next();
92+
});
93+
router.use((req, res) => {
94+
res.json({ b: req.fromFirstEndpoint });
95+
});
96+
const lambdaHandler = ApiGatewayHandler(router);
97+
const result = await lambdaHandler(proxyRequest, {});
98+
expect(result).toEqual({
99+
statusCode: 200,
100+
headers: {
101+
'content-type': 'application/json'
102+
},
103+
body: JSON.stringify({ "b": "1" })
104+
});
105+
});
106+
it('should handle errors', async () => {
107+
expect.assertions(1);
108+
const router = Router();
109+
router.use((req, res, next) => {
110+
throw Error('test');
111+
});
112+
router.use((err, req, res, next) => {
113+
expect(err).toEqual(Error('test'));
114+
next();
115+
});
116+
const lambdaHandler = ApiGatewayHandler(router);
117+
const out = await lambdaHandler(proxyRequest, {});
118+
});
119+
it('should handle next(error)', async () => {
120+
expect.assertions(1);
121+
const router = Router();
122+
router.use((req, res, next) => {
123+
next('test');
124+
});
125+
router.use((err, req, res, next) => {
126+
expect(err).toEqual('test');
127+
next();
128+
});
129+
const lambdaHandler = ApiGatewayHandler(router);
130+
await lambdaHandler(proxyRequest, {});
131+
});
132+
it('GET with path', async () => {
133+
expect.assertions(1);
134+
const router = Router();
135+
router.get('/*', (req, res, next) => {
136+
req.fromFirstEndpoint = 1;
137+
next();
138+
});
139+
router.get('/path', (req, res) => {
140+
res.json({ a: req.fromFirstEndpoint, b: 2 });
141+
});
142+
const lambdaHandler = ApiGatewayHandler(router);
143+
const proxyRequest = {
144+
body: '',
145+
headers: {},
146+
multiValueHeaders: {},
147+
httpMethod: 'GET',
148+
isBase64Encoded: false,
149+
path: '/path',
150+
pathParameters: {},
151+
queryStringParameters: {},
152+
multiValueQueryStringParameters: {},
153+
stageVariables: {},
154+
requestContext: {},
155+
resource: ''
156+
};
157+
const result = await lambdaHandler(proxyRequest, {});
158+
expect(result).toEqual({
159+
statusCode: 200,
160+
headers: {
161+
'content-type': 'application/json'
162+
},
163+
body: '{"a":1,"b":2}'
164+
});
165+
});
166+
it('POST matching only post handler', async () => {
167+
expect.assertions(1);
168+
const router = Router();
169+
router.get('/path', (req, res, next) => {
170+
req.foo = 1;
171+
next();
172+
});
173+
router.post('/path', (req, res) => {
174+
res.json({ a: req.foo, b: 2 });
175+
});
176+
const lambdaHandler = ApiGatewayHandler(router);
177+
const result = await lambdaHandler(proxyRequest, {});
178+
expect(result).toEqual({
179+
statusCode: 200,
180+
headers: {
181+
'content-type': 'application/json'
182+
},
183+
body: '{"b":2}'
184+
});
185+
});
186+
it('Router cascade', async () => {
187+
expect.assertions(1);
188+
const subRouter = Router();
189+
subRouter.post('/path', (req, res) => {
190+
res.json({ b: 2 });
191+
});
192+
const router = Router();
193+
router.use('/testing', subRouter);
194+
const lambdaHandler = ApiGatewayHandler(router);
195+
let request = {};
196+
Object.assign(request, proxyRequest);
197+
request.path = '/testing/path';
198+
const result = await lambdaHandler(request, {});
199+
expect(result).toEqual({
200+
statusCode: 200,
201+
headers: {
202+
'content-type': 'application/json'
203+
},
204+
body: '{"b":2}'
205+
});
206+
});
207+
});

0 commit comments

Comments
 (0)