@scloud/lambda-api 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/handler.d.ts +49 -0
- package/dist/handler.js +178 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +18 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.js +3 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Lambda API Gateway Proxy handler
|
|
2
|
+
|
|
3
|
+
A Lambda handler that routes API Gateway Proxy messages and returns an API Gateway Proxy Response.
|
|
4
|
+
|
|
5
|
+
This is a piece of useful boilerplate to handle the mechanics of routing, headers and cookies, catching any errors and handling 400, 405 and 500 errors (you can optionally handle 404 and 500 with your own handler functions).
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
Create your routes:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
import { types } from '@scloud/lambda-api';
|
|
13
|
+
|
|
14
|
+
const routes: types.Routes = {
|
|
15
|
+
'/ping': { GET: async (request: types.Request) => ({ statusCode: 200, body: {message: 'ok'} }) },
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Use `@scloud/lambda-api` in your Lambda handler:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
|
23
|
+
import { apiHandler, helpers } from '@scloud/lambda-api';
|
|
24
|
+
|
|
25
|
+
export async function handler(event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> {
|
|
26
|
+
const result = await apiHandler(event, context, routes);
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The `apiHandler` function will call your route functions according to the method and path of the request, catching any errors and returning 404/405 if a path/method isn't defined, or 500 if an error is thrown.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
|
2
|
+
import { Handler, Request, Routes } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Ensures the path is lowercased, always has a leading slash and never a trailing slash
|
|
5
|
+
* @param path APIGatewayProxyEvent.path
|
|
6
|
+
*/
|
|
7
|
+
export declare function standardPath(path: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Ensures a non-null object containing only query-string parameters that have a value.
|
|
10
|
+
* @param query APIGatewayProxyEvent.query
|
|
11
|
+
*/
|
|
12
|
+
export declare function standardQueryParameters(query: {
|
|
13
|
+
[name: string]: string | undefined;
|
|
14
|
+
} | null): {
|
|
15
|
+
[name: string]: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Ensures all header names are lowercased for ease of access.
|
|
19
|
+
* @param headers APIGatewayProxyEvent.headers
|
|
20
|
+
*/
|
|
21
|
+
export declare function standardHeaders(headers: {
|
|
22
|
+
[name: string]: string | undefined;
|
|
23
|
+
}): {
|
|
24
|
+
[name: string]: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Parses the body (if present) to a JSON string. Returns at mimimum an empty object.
|
|
28
|
+
* @param body APIGatewayProxyEvent.body
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseBody(body: string | null): {
|
|
31
|
+
[name: string]: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Parses the cookie, if any, returning at minimum an empty object.
|
|
35
|
+
* @param headers APIGatewayProxyEvent.headers
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseCookie(headers: {
|
|
38
|
+
[name: string]: string | undefined;
|
|
39
|
+
}): {
|
|
40
|
+
[name: string]: string;
|
|
41
|
+
};
|
|
42
|
+
export declare function buildCookie(values: {
|
|
43
|
+
[key: string]: string;
|
|
44
|
+
} | undefined): string[] | undefined;
|
|
45
|
+
export declare function parseRequest(event: APIGatewayProxyEvent): Request;
|
|
46
|
+
/**
|
|
47
|
+
* Generic routing handler
|
|
48
|
+
*/
|
|
49
|
+
export declare function apiHandler(event: APIGatewayProxyEvent, context: Context, routes?: Routes, errorHandler?: Handler, catchAll?: Handler): Promise<APIGatewayProxyResult>;
|
package/dist/handler.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.apiHandler = exports.parseRequest = exports.buildCookie = exports.parseCookie = exports.parseBody = exports.standardHeaders = exports.standardQueryParameters = exports.standardPath = void 0;
|
|
27
|
+
const cookie = __importStar(require("cookie"));
|
|
28
|
+
/**
|
|
29
|
+
* Ensures the path is lowercased, always has a leading slash and never a trailing slash
|
|
30
|
+
* @param path APIGatewayProxyEvent.path
|
|
31
|
+
*/
|
|
32
|
+
function standardPath(path) {
|
|
33
|
+
// Get path segments, filtering out any blanks
|
|
34
|
+
const segments = path.split('/').filter((segment) => segment);
|
|
35
|
+
// Return path
|
|
36
|
+
return `/${segments.join('/').toLowerCase()}`;
|
|
37
|
+
}
|
|
38
|
+
exports.standardPath = standardPath;
|
|
39
|
+
/**
|
|
40
|
+
* Ensures a non-null object containing only query-string parameters that have a value.
|
|
41
|
+
* @param query APIGatewayProxyEvent.query
|
|
42
|
+
*/
|
|
43
|
+
function standardQueryParameters(query) {
|
|
44
|
+
if (!query)
|
|
45
|
+
return {};
|
|
46
|
+
const result = {};
|
|
47
|
+
Object.keys(query).forEach((parameter) => {
|
|
48
|
+
const value = query[parameter];
|
|
49
|
+
if (value)
|
|
50
|
+
result[parameter] = value;
|
|
51
|
+
});
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
exports.standardQueryParameters = standardQueryParameters;
|
|
55
|
+
/**
|
|
56
|
+
* Ensures all header names are lowercased for ease of access.
|
|
57
|
+
* @param headers APIGatewayProxyEvent.headers
|
|
58
|
+
*/
|
|
59
|
+
function standardHeaders(headers) {
|
|
60
|
+
const result = {};
|
|
61
|
+
Object.keys(headers).forEach((name) => {
|
|
62
|
+
const value = headers[name];
|
|
63
|
+
if (value)
|
|
64
|
+
result[name.toLowerCase()] = value;
|
|
65
|
+
});
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
exports.standardHeaders = standardHeaders;
|
|
69
|
+
/**
|
|
70
|
+
* Parses the body (if present) to a JSON string. Returns at mimimum an empty object.
|
|
71
|
+
* @param body APIGatewayProxyEvent.body
|
|
72
|
+
*/
|
|
73
|
+
function parseBody(body) {
|
|
74
|
+
if (!body)
|
|
75
|
+
return {};
|
|
76
|
+
let result = {};
|
|
77
|
+
try {
|
|
78
|
+
result = JSON.parse(body);
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
console.error(`Error parsing request body: ${e}`);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
exports.parseBody = parseBody;
|
|
86
|
+
/**
|
|
87
|
+
* Parses the cookie, if any, returning at minimum an empty object.
|
|
88
|
+
* @param headers APIGatewayProxyEvent.headers
|
|
89
|
+
*/
|
|
90
|
+
function parseCookie(headers) {
|
|
91
|
+
const header = headers.cookie || headers.Cookie || '';
|
|
92
|
+
return cookie.parse(header);
|
|
93
|
+
}
|
|
94
|
+
exports.parseCookie = parseCookie;
|
|
95
|
+
function buildCookie(values) {
|
|
96
|
+
if (!values)
|
|
97
|
+
return undefined;
|
|
98
|
+
const header = [];
|
|
99
|
+
const oneYear = 60 * 60 * 24 * 365;
|
|
100
|
+
Object.keys(values).forEach((key) => {
|
|
101
|
+
const value = values[key];
|
|
102
|
+
if (value === '') {
|
|
103
|
+
// If explicitly unset, expire the cookie value
|
|
104
|
+
header.push(cookie.serialize(key, '', {
|
|
105
|
+
expires: new Date(), secure: true, httpOnly: true, sameSite: 'strict',
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
else if (value) {
|
|
109
|
+
// Otherwise, set it only if a value was given
|
|
110
|
+
header.push(cookie.serialize(key, value, {
|
|
111
|
+
maxAge: oneYear, secure: true, httpOnly: true, sameSite: 'strict',
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return header;
|
|
116
|
+
}
|
|
117
|
+
exports.buildCookie = buildCookie;
|
|
118
|
+
function parseRequest(event) {
|
|
119
|
+
return {
|
|
120
|
+
method: event.httpMethod,
|
|
121
|
+
path: standardPath(event.path),
|
|
122
|
+
query: standardQueryParameters(event.queryStringParameters),
|
|
123
|
+
headers: standardHeaders(event.headers),
|
|
124
|
+
body: parseBody(event.body),
|
|
125
|
+
cookies: parseCookie(event.headers),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
exports.parseRequest = parseRequest;
|
|
129
|
+
/**
|
|
130
|
+
* Generic routing handler
|
|
131
|
+
*/
|
|
132
|
+
async function apiHandler(event, context, routes = {
|
|
133
|
+
'/api/ping': { GET: async (request) => ({ statusCode: 200, body: request }) },
|
|
134
|
+
}, errorHandler = async (request) => ({ statusCode: 500, body: { error: `Internal server error: ${request.path}` } }), catchAll = async (request) => ({ statusCode: 404, body: { error: `Not found: ${request.path}` } })) {
|
|
135
|
+
console.log(`Executing ${context.functionName} version: ${process.env.COMMIT_HASH}`);
|
|
136
|
+
const request = parseRequest(event);
|
|
137
|
+
let response;
|
|
138
|
+
try {
|
|
139
|
+
const route = routes[request.path];
|
|
140
|
+
if (!route) {
|
|
141
|
+
// Catch-all / 404
|
|
142
|
+
response = await catchAll(request);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
const handlerFunction = route[request.method];
|
|
146
|
+
if (!handlerFunction)
|
|
147
|
+
return { statusCode: 405, body: JSON.stringify('Method not allowed') };
|
|
148
|
+
// Handle the request:
|
|
149
|
+
response = await handlerFunction(request);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch (e) {
|
|
153
|
+
console.error(`${e.message}\n${e.stack}`);
|
|
154
|
+
try {
|
|
155
|
+
// Error handling
|
|
156
|
+
response = await errorHandler(request);
|
|
157
|
+
}
|
|
158
|
+
catch (ee) {
|
|
159
|
+
response = { statusCode: 500, body: { error: `Internal server error: ${request.path}` } };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// QPI Gateway Proxy result
|
|
163
|
+
const result = {
|
|
164
|
+
statusCode: response.statusCode,
|
|
165
|
+
body: JSON.stringify(response.body),
|
|
166
|
+
headers: response.headers,
|
|
167
|
+
};
|
|
168
|
+
// Cookies (if set)
|
|
169
|
+
const cookieHeaders = buildCookie(response.cookies);
|
|
170
|
+
if (cookieHeaders) {
|
|
171
|
+
result.multiValueHeaders = {
|
|
172
|
+
Cookie: cookieHeaders,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
exports.apiHandler = apiHandler;
|
|
178
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBT0EsK0NBQWlDO0FBS2pDOzs7R0FHRztBQUNILFNBQWdCLFlBQVksQ0FBQyxJQUFZO0lBQ3ZDLDhDQUE4QztJQUM5QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDOUQsY0FBYztJQUNkLE9BQU8sSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7QUFDaEQsQ0FBQztBQUxELG9DQUtDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0IsdUJBQXVCLENBQUMsS0FBcUQ7SUFDM0YsSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN0QixNQUFNLE1BQU0sR0FBZ0MsRUFBRSxDQUFDO0lBQy9DLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUU7UUFDdkMsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQy9CLElBQUksS0FBSztZQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBUkQsMERBUUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixlQUFlLENBQUMsT0FBZ0Q7SUFDOUUsTUFBTSxNQUFNLEdBQWdDLEVBQUUsQ0FBQztJQUMvQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1FB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QUFvQixDQUFDLEVBQUUsQ0FBQztZQUU3RixzQkFBc0I7WUFDdEIsUUFBUSxHQUFHLE1BQU0sZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQzNDO0tBQ0Y7SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNWLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBSSxDQUFXLENBQUMsT0FBTyxLQUFNLENBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2hFLElBQUk7WUFDRixpQkFBaUI7WUFDakIsUUFBUSxHQUFHLE1BQU0sWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3hDO1FBQUMsT0FBTyxFQUFFLEVBQUU7WUFDWCxRQUFRLEdBQUcsRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSwwQkFBMEIsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQztTQUMzRjtLQUNGO0lBRUQsMkJBQTJCO0lBQzNCLE1BQU0sTUFBTSxHQUEwQjtRQUNwQyxVQUFVLEVBQUUsUUFBUSxDQUFDLFVBQVU7UUFDL0IsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztRQUNuQyxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87S0FDMUIsQ0FBQztJQUVGLG1CQUFtQjtJQUNuQixNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3BELElBQUksYUFBYSxFQUFFO1FBQ2pCLE1BQU0sQ0FBQyxpQkFBaUIsR0FBRztZQUN6QixNQUFNLEVBQUUsYUFBYTtTQUN0QixDQUFDO0tBQ0g7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBbkRELGdDQW1EQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9wcmVmZXItZGVmYXVsdC1leHBvcnQgKi9cbi8vIGh0dHBzOi8vYXdzLmFtYXpvbi5jb20vYmxvZ3MvbW9iaWxlL3VuZGVyc3RhbmRpbmctYW1hem9uLWNvZ25pdG8tdXNlci1wb29sLW9hdXRoLTItMC1ncmFudHMvXG5pbXBvcnQge1xuICBBUElHYXRld2F5UHJveHlFdmVudCxcbiAgQVBJR2F0ZXdheVByb3h5UmVzdWx0LFxuICBDb250ZXh0LFxufSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIGNvb2tpZSBmcm9tICdjb29raWUnO1xuaW1wb3J0IHtcbiAgSGFuZGxlciwgUmVxdWVzdCwgUmVzcG9uc2UsIFJvdXRlLCBSb3V0ZXMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIEVuc3VyZXMgdGhlIHBhdGggaXMgbG93ZXJjYXNlZCwgYWx3YXlzIGhhcyBhIGxlYWRpbmcgc2xhc2ggYW5kIG5ldmVyIGEgdHJhaWxpbmcgc2xhc2hcbiAqIEBwYXJhbSBwYXRoIEFQSUdhdGV3YXlQcm94eUV2ZW50LnBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YW5kYXJkUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBHZXQgcGF0aCBzZWdtZW50cywgZmlsdGVyaW5nIG91dCBhbnkgYmxhbmtzXG4gIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdCgnLycpLmZpbHRlcigoc2VnbWVudCkgPT4gc2VnbWVudCk7XG4gIC8vIFJldHVybiBwYXRoXG4gIHJldHVybiBgLyR7c2VnbWVudHMuam9pbignLycpLnRvTG93ZXJDYXNlKCl9YDtcbn1cblxuLyoqXG4gKiBFbnN1cmVzIGEgbm9uLW51bGwgb2JqZWN0IGNvbnRhaW5pbmcgb25seSBxdWVyeS1zdHJpbmcgcGFyYW1ldGVycyB0aGF0IGhhdmUgYSB2YWx1ZS5cbiAqIEBwYXJhbSBxdWVyeSBBUElHYXRld2F5UHJveHlFdmVudC5xdWVyeVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhbmRhcmRRdWVyeVBhcmFtZXRlcnMocXVlcnk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZDsgfSB8IG51bGwpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0ge1xuICBpZiAoIXF1ZXJ5KSByZXR1cm4ge307XG4gIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge307XG4gIE9iamVjdC5rZXlzKHF1ZXJ5KS5mb3JFYWNoKChwYXJhbWV0ZXIpID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IHF1ZXJ5W3BhcmFtZXRlcl07XG4gICAgaWYgKHZhbHVlKSByZXN1bHRbcGFyYW1ldGVyXSA9IHZhbHVlO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBFbnN1cmVzIGFsbCBoZWFkZXIgbmFtZXMgYXJlIGxvd2VyY2FzZWQgZm9yIGVhc2Ugb2YgYWNjZXNzLlxuICogQHBhcmFtIGhlYWRlcnMgQVBJR2F0ZXdheVByb3h5RXZlbnQuaGVhZGVyc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhbmRhcmRIZWFkZXJzKGhlYWRlcnM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZDsgfSk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfSB7XG4gIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge307XG4gIE9iamVjdC5rZXlzKGhlYWRlcnMpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IGhlYWRlcnNbbmFtZV07XG4gICAgaWYgKHZhbHVlKSByZXN1bHRbbmFtZS50b0xvd2VyQ2FzZSgpXSA9IHZhbHVlO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBQYXJzZXMgdGhlIGJvZHkgKGlmIHByZXNlbnQpIHRvIGEgSlNPTiBzdHJpbmcuIFJldHVybnMgYXQgbWltaW11bSBhbiBlbXB0eSBvYmplY3QuXG4gKiBAcGFyYW0gYm9keSBBUElHYXRld2F5UHJveHlFdmVudC5ib2R5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJvZHkoYm9keTogc3RyaW5nIHwgbnVsbCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfSB7XG4gIGlmICghYm9keSkgcmV0dXJuIHt9O1xuICBsZXQgcmVzdWx0ID0ge307XG4gIHRyeSB7XG4gICAgcmVzdWx0ID0gSlNPTi5wYXJzZShib2R5KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHBhcnNpbmcgcmVxdWVzdCBib2R5OiAke2V9YCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBQYXJzZXMgdGhlIGNvb2tpZSwgaWYgYW55LCByZXR1cm5pbmcgYXQgbWluaW11bSBhbiBlbXB0eSBvYmplY3QuXG4gKiBAcGFyYW0gaGVhZGVycyBBUElHYXRld2F5UHJveHlFdmVudC5oZWFkZXJzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUNvb2tpZShoZWFkZXJzOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQ7IH0pOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0ge1xuICBjb25zdCBoZWFkZXIgPSBoZWFkZXJzLmNvb2tpZSB8fCBoZWFkZXJzLkNvb2tpZSB8fCAnJztcbiAgcmV0dXJuIGNvb2tpZS5wYXJzZShoZWFkZXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDb29raWUodmFsdWVzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZzsgfSB8IHVuZGVmaW5lZCk6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCF2YWx1ZXMpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgaGVhZGVyOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBvbmVZZWFyID0gNjAgKiA2MCAqIDI0ICogMzY1O1xuXG4gIE9iamVjdC5rZXlzKHZhbHVlcykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSB2YWx1ZXNba2V5XTtcbiAgICBpZiAodmFsdWUgPT09ICcnKSB7XG4gICAgICAvLyBJZiBleHBsaWNpdGx5IHVuc2V0LCBleHBpcmUgdGhlIGNvb2tpZSB2YWx1ZVxuICAgICAgaGVhZGVyLnB1c2goY29va2llLnNlcmlhbGl6ZShrZXksICcnLCB7XG4gICAgICAgIGV4cGlyZXM6IG5ldyBEYXRlKCksIHNlY3VyZTogdHJ1ZSwgaHR0cE9ubHk6IHRydWUsIHNhbWVTaXRlOiAnc3RyaWN0JyxcbiAgICAgIH0pKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlKSB7XG4gICAgICAvLyBPdGhlcndpc2UsIHNldCBpdCBvbmx5IGlmIGEgdmFsdWUgd2FzIGdpdmVuXG4gICAgICBoZWFkZXIucHVzaChjb29raWUuc2VyaWFsaXplKGtleSwgdmFsdWUsIHtcbiAgICAgICAgbWF4QWdlOiBvbmVZZWFyLCBzZWN1cmU6IHRydWUsIGh0dHBPbmx5OiB0cnVlLCBzYW1lU2l0ZTogJ3N0cmljdCcsXG4gICAgICB9KSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gaGVhZGVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VSZXF1ZXN0KGV2ZW50OiBBUElHYXRld2F5UHJveHlFdmVudCk6IFJlcXVlc3Qge1xuICByZXR1cm4ge1xuICAgIG1ldGhvZDogZXZlbnQuaHR0cE1ldGhvZCxcbiAgICBwYXRoOiBzdGFuZGFyZFBhdGgoZXZlbnQucGF0aCksXG4gICAgcXVlcnk6IHN0YW5kYXJkUXVlcnlQYXJhbWV0ZXJzKGV2ZW50LnF1ZXJ5U3RyaW5nUGFyYW1ldGVycyksXG4gICAgaGVhZGVyczogc3RhbmRhcmRIZWFkZXJzKGV2ZW50LmhlYWRlcnMpLFxuICAgIGJvZHk6IHBhcnNlQm9keShldmVudC5ib2R5KSxcbiAgICBjb29raWVzOiBwYXJzZUNvb2tpZShldmVudC5oZWFkZXJzKSxcbiAgfTtcbn1cblxuLyoqXG4gKiBHZW5lcmljIHJvdXRpbmcgaGFuZGxlclxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXBpSGFuZGxlcihcbiAgZXZlbnQ6IEFQSUdhdGV3YXlQcm94eUV2ZW50LFxuICBjb250ZXh0OiBDb250ZXh0LFxuICByb3V0ZXM6IFJvdXRlcyA9IHtcbiAgICAnL2FwaS9waW5nJzogeyBHRVQ6IGFzeW5jIChyZXF1ZXN0OiBSZXF1ZXN0KSA9PiAoeyBzdGF0dXNDb2RlOiAyMDAsIGJvZHk6IHJlcXVlc3QgfSkgfSxcbiAgfSxcbiAgZXJyb3JIYW5kbGVyOiBIYW5kbGVyID0gYXN5bmMgKHJlcXVlc3Q6IFJlcXVlc3QpID0+ICh7IHN0YXR1c0NvZGU6IDUwMCwgYm9keTogeyBlcnJvcjogYEludGVybmFsIHNlcnZlciBlcnJvcjogJHtyZXF1ZXN0LnBhdGh9YCB9IH0pLFxuICBjYXRjaEFsbDogSGFuZGxlciA9IGFzeW5jIChyZXF1ZXN0OiBSZXF1ZXN0KSA9PiAoeyBzdGF0dXNDb2RlOiA0MDQsIGJvZHk6IHsgZXJyb3I6IGBOb3QgZm91bmQ6ICR7cmVxdWVzdC5wYXRofWAgfSB9KSxcbik6IFByb21pc2U8QVBJR2F0ZXdheVByb3h5UmVzdWx0PiB7XG4gIGNvbnNvbGUubG9nKGBFeGVjdXRpbmcgJHtjb250ZXh0LmZ1bmN0aW9uTmFtZX0gdmVyc2lvbjogJHtwcm9jZXNzLmVudi5DT01NSVRfSEFTSH1gKTtcbiAgY29uc3QgcmVxdWVzdCA9IHBhcnNlUmVxdWVzdChldmVudCk7XG5cbiAgbGV0IHJlc3BvbnNlOiBSZXNwb25zZTtcbiAgdHJ5IHtcbiAgICBjb25zdCByb3V0ZSA9IHJvdXRlc1tyZXF1ZXN0LnBhdGhdO1xuICAgIGlmICghcm91dGUpIHtcbiAgICAgIC8vIENhdGNoLWFsbCAvIDQwNFxuICAgICAgcmVzcG9uc2UgPSBhd2FpdCBjYXRjaEFsbChyZXF1ZXN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaGFuZGxlckZ1bmN0aW9uID0gcm91dGVbcmVxdWVzdC5tZXRob2QgYXMga2V5b2YgUm91dGVdO1xuICAgICAgaWYgKCFoYW5kbGVyRnVuY3Rpb24pIHJldHVybiB7IHN0YXR1c0NvZGU6IDQwNSwgYm9keTogSlNPTi5zdHJpbmdpZnkoJ01ldGhvZCBub3QgYWxsb3dlZCcpIH07XG5cbiAgICAgIC8vIEhhbmRsZSB0aGUgcmVxdWVzdDpcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgaGFuZGxlckZ1bmN0aW9uKHJlcXVlc3QpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYCR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9XFxuJHsoZSBhcyBFcnJvcikuc3RhY2t9YCk7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEVycm9yIGhhbmRsaW5nXG4gICAgICByZXNwb25zZSA9IGF3YWl0IGVycm9ySGFuZGxlcihyZXF1ZXN0KTtcbiAgICB9IGNhdGNoIChlZSkge1xuICAgICAgcmVzcG9uc2UgPSB7IHN0YXR1c0NvZGU6IDUwMCwgYm9keTogeyBlcnJvcjogYEludGVybmFsIHNlcnZlciBlcnJvcjogJHtyZXF1ZXN0LnBhdGh9YCB9IH07XG4gICAgfVxuICB9XG5cbiAgLy8gUVBJIEdhdGV3YXkgUHJveHkgcmVzdWx0XG4gIGNvbnN0IHJlc3VsdDogQVBJR2F0ZXdheVByb3h5UmVzdWx0ID0ge1xuICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1c0NvZGUsXG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UuYm9keSksXG4gICAgaGVhZGVyczogcmVzcG9uc2UuaGVhZGVycyxcbiAgfTtcblxuICAvLyBDb29raWVzIChpZiBzZXQpXG4gIGNvbnN0IGNvb2tpZUhlYWRlcnMgPSBidWlsZENvb2tpZShyZXNwb25zZS5jb29raWVzKTtcbiAgaWYgKGNvb2tpZUhlYWRlcnMpIHtcbiAgICByZXN1bHQubXVsdGlWYWx1ZUhlYWRlcnMgPSB7XG4gICAgICBDb29raWU6IGNvb2tpZUhlYWRlcnMsXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iXX0=
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './handler';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./handler"), exports);
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDRDQUEwQiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vaGFuZGxlcic7XG4iXX0=
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface Request {
|
|
2
|
+
method: string;
|
|
3
|
+
path: string;
|
|
4
|
+
query: {
|
|
5
|
+
[name: string]: string;
|
|
6
|
+
};
|
|
7
|
+
headers: {
|
|
8
|
+
[name: string]: string;
|
|
9
|
+
};
|
|
10
|
+
cookies: {
|
|
11
|
+
[name: string]: string;
|
|
12
|
+
};
|
|
13
|
+
body: {
|
|
14
|
+
[name: string]: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface Response {
|
|
18
|
+
statusCode: number;
|
|
19
|
+
headers?: {
|
|
20
|
+
[name: string]: string;
|
|
21
|
+
};
|
|
22
|
+
cookies?: {
|
|
23
|
+
[name: string]: string;
|
|
24
|
+
};
|
|
25
|
+
body?: {
|
|
26
|
+
[name: string]: any;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export type Handler = (request: Request) => Promise<Response>;
|
|
30
|
+
export interface Route {
|
|
31
|
+
GET?: Handler;
|
|
32
|
+
POST?: Handler;
|
|
33
|
+
PUT?: Handler;
|
|
34
|
+
DELETE?: Handler;
|
|
35
|
+
OPTIONS?: Handler;
|
|
36
|
+
}
|
|
37
|
+
export interface Routes {
|
|
38
|
+
[path: string]: Route;
|
|
39
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgUmVxdWVzdCB7XG4gIG1ldGhvZDogc3RyaW5nLFxuICBwYXRoOiBzdHJpbmcsXG4gIHF1ZXJ5OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0sXG4gIGhlYWRlcnM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfSxcbiAgY29va2llczogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9LFxuICBib2R5OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0sXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzcG9uc2Uge1xuICBzdGF0dXNDb2RlOiBudW1iZXIsXG4gIGhlYWRlcnM/OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0sXG4gIGNvb2tpZXM/OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0sXG4gIGJvZHk/OiB7IFtuYW1lOiBzdHJpbmddOiBhbnk7IH0sXG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuZXhwb3J0IHR5cGUgSGFuZGxlciA9IChyZXF1ZXN0OiBSZXF1ZXN0KSA9PiBQcm9taXNlPFJlc3BvbnNlPjtcbmV4cG9ydCBpbnRlcmZhY2UgUm91dGUge1xuICBHRVQ/OiBIYW5kbGVyLFxuICBQT1NUPzogSGFuZGxlcixcbiAgUFVUPzogSGFuZGxlcixcbiAgREVMRVRFPzogSGFuZGxlcixcbiAgT1BUSU9OUz86IEhhbmRsZXIsXG59XG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlcyB7IFtwYXRoOiBzdHJpbmddOiBSb3V0ZTsgfVxuIl19
|