@scloud/lambda-api 0.3.7 → 1.0.0

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 CHANGED
@@ -6,6 +6,7 @@ This is a piece of useful boilerplate to handle the mechanics of routing, header
6
6
 
7
7
  ## Releae notes
8
8
 
9
+ * `0.3.8`: Optinoal generic type on `Request`
9
10
  * `0.3.7`: Fix cookie setting to use `Set-Cookie`
10
11
  * `0.3.6`: Enable parsing body as `application/x-www-form-urlencoded` as well as JSON
11
12
  * `0.3.5`: `actions/setup-node@v4` and Node `lts`
package/dist/handler.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
2
- import { ContextBuilder, Handler, Request, Response, Routes } from './types';
2
+ import { Request, Response, Handler, Routes } from './types';
3
3
  /**
4
4
  * API route handler
5
5
  */
6
- export declare function apiHandler(event: APIGatewayProxyEvent, context: Context, routes?: Routes, errorHandler?: (request: Request, e: Error) => Promise<Response>, catchAll?: Handler, contextBuilder?: ContextBuilder): Promise<APIGatewayProxyResult>;
6
+ export declare function apiHandler(event: APIGatewayProxyEvent, context: Context, routes?: Routes, errorHandler?: ((request: Request, e: Error) => Promise<Response>) | undefined, catchAll?: Handler | undefined): Promise<APIGatewayProxyResult>;
package/dist/handler.js CHANGED
@@ -1,61 +1,86 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.apiHandler = apiHandler;
4
+ const types_1 = require("./types");
4
5
  const helpers_1 = require("./helpers");
5
- function textResponse(statusCode, body) {
6
+ function errorResponse(statusCode, body, e) {
7
+ if (e instanceof types_1.ApiError) {
8
+ return {
9
+ statusCode: e.statusCode,
10
+ body: e.body,
11
+ };
12
+ }
13
+ if (e)
14
+ console.error(`${e.stack}`);
6
15
  return {
7
- statusCode,
8
- headers: { 'Content-Type': 'text/plain' },
9
- body
16
+ statusCode: statusCode,
17
+ body: body,
10
18
  };
11
19
  }
12
20
  /**
13
21
  * API route handler
14
22
  */
15
23
  async function apiHandler(event, context, routes = {
16
- '/api/ping': { GET: async (request) => ({ statusCode: 200, body: request }) },
17
- }, errorHandler = async (request) => ({ statusCode: 500, body: { error: `Internal server error: ${request.path}` } }), catchAll = async (request) => textResponse(404, `Not found: ${request.path}`), contextBuilder) {
18
- console.log(`Executing ${context.functionName} version: ${process.env.COMMIT_HASH}`);
24
+ '/ping': { GET: { handler: async (request) => ({ statusCode: 200, body: request }) } },
25
+ }, errorHandler = undefined, catchAll = undefined) {
19
26
  const request = (0, helpers_1.parseRequest)(event);
20
27
  let response;
21
28
  try {
22
29
  const match = (0, helpers_1.matchRoute)(routes, request.path);
23
- if (!match.route) {
30
+ if (match.params)
31
+ request.pathParameters = match.params;
32
+ if (match.methods) {
33
+ const route = match.methods[request.method];
34
+ if (!route)
35
+ throw new types_1.ApiError(405, 'Method not allowed');
36
+ // Verify request body
37
+ if (route.request?.body) {
38
+ const parsed = route.request.body.safeParse(request.body);
39
+ if (!parsed.success) {
40
+ throw new types_1.ApiError(400, parsed.error);
41
+ }
42
+ request.body = parsed.data;
43
+ }
44
+ response = await route.handler(request);
45
+ // Verify response body
46
+ if (route.response?.body) {
47
+ const parsed = route.response.body.safeParse(response.body);
48
+ if (!parsed.success) {
49
+ console.error(JSON.stringify(parsed.error, null, 2));
50
+ throw new types_1.ApiError(500, 'Internal server error');
51
+ }
52
+ response.body = parsed.data;
53
+ }
54
+ }
55
+ else if (catchAll) {
24
56
  // Catch-all / 404
25
- response = await catchAll(request);
57
+ response = await catchAll.handler(request);
26
58
  }
27
59
  else {
28
- const handlerFunction = match.route[request.method];
29
- // Handle the request:
30
- if (handlerFunction) {
31
- if (contextBuilder)
32
- await contextBuilder(request);
33
- response = await handlerFunction({ ...request, pathParameters: match.params });
34
- }
35
- else {
36
- response = textResponse(405, 'Method not allowed');
37
- }
60
+ throw new types_1.ApiError(404, 'Not found');
38
61
  }
39
62
  }
40
63
  catch (e) {
41
- // Fallback error handling
42
- console.error(`${e.message}\n${e.stack}`);
43
- response = textResponse(500, `Internal server error: ${request.path}`);
44
- try {
45
- // Error handling
46
- if (errorHandler)
64
+ if (errorHandler) {
65
+ try {
47
66
  response = await errorHandler(request, e);
67
+ }
68
+ catch (ee) {
69
+ response = errorResponse(500, 'Internal server error', ee);
70
+ }
48
71
  }
49
- catch (ee) {
50
- console.error(`Error in error handler: ${ee.message}\n${ee.stack}`);
72
+ else {
73
+ response = errorResponse(500, 'Internal server error', e);
51
74
  }
52
75
  }
53
- // API Gateway Proxy result
54
- let body = '';
76
+ // Translate the response to an API Gateway Proxy result
77
+ let body;
78
+ const headers = response.headers || {};
55
79
  if (typeof response.body === 'string') {
56
80
  // Use the body as-is
57
- // Potentially add a text/plain content type header:
58
- response.headers = { 'Content-Type': 'text/plain', ...response.headers };
81
+ // Add text/plain if no Content-Type header is set:
82
+ if (!(0, helpers_1.getHeader)('Content-Type', headers))
83
+ (0, helpers_1.setHeader)('Content-Type', 'text/plain', headers);
59
84
  body = response.body;
60
85
  }
61
86
  else if (response.body) {
@@ -63,13 +88,14 @@ async function apiHandler(event, context, routes = {
63
88
  // API Gateway returns application/json by default
64
89
  body = JSON.stringify(response.body);
65
90
  }
91
+ // Prepare response
66
92
  const result = {
67
- statusCode: response.statusCode,
68
- body,
69
- headers: response.headers,
93
+ statusCode: response.statusCode ?? 200,
94
+ headers,
95
+ body: body || '',
70
96
  };
71
- // Cookies (if set)
72
- const cookieHeaders = (0, helpers_1.buildCookie)(response.cookies);
97
+ // Add cookie headers
98
+ const cookieHeaders = (0, helpers_1.buildCookie)(response);
73
99
  if (cookieHeaders) {
74
100
  result.multiValueHeaders = {
75
101
  'Set-Cookie': cookieHeaders,
@@ -77,4 +103,4 @@ async function apiHandler(event, context, routes = {
77
103
  }
78
104
  return result;
79
105
  }
80
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBc0JBLGdDQXFFQztBQWxGRCx1Q0FBa0U7QUFFbEUsU0FBUyxZQUFZLENBQUMsVUFBa0IsRUFBRSxJQUFZO0lBQ3BELE9BQU87UUFDTCxVQUFVO1FBQ1YsT0FBTyxFQUFFLEVBQUUsY0FBYyxFQUFFLFlBQVksRUFBRTtRQUN6QyxJQUFJO0tBQ0wsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNJLEtBQUssVUFBVSxVQUFVLENBQzlCLEtBQTJCLEVBQzNCLE9BQWdCLEVBQ2hCLFNBQWlCO0lBQ2YsV0FBVyxFQUFFLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxPQUFnQixFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRTtDQUN2RixFQUNELGVBQWtFLEtBQUssRUFBRSxPQUFnQixFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRSxLQUFLLEVBQUUsMEJBQTBCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFDOUssV0FBb0IsS0FBSyxFQUFFLE9BQWdCLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsY0FBYyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsRUFDL0YsY0FBK0I7SUFFL0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLE9BQU8sQ0FBQyxZQUFZLGFBQWEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ3JGLE1BQU0sT0FBTyxHQUFHLElBQUEsc0JBQVksRUFBQyxLQUFLLENBQUMsQ0FBQztJQUVwQyxJQUFJLFFBQWtCLENBQUM7SUFDdkIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcsSUFBQSxvQkFBVSxFQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNqQixrQkFBa0I7WUFDbEIsUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JDLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBcUIsQ0FBQyxDQUFDO1lBRW5FLHNCQUFzQjtZQUN0QixJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUNwQixJQUFJLGNBQWM7b0JBQUUsTUFBTSxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ2xELFFBQVEsR0FBRyxNQUFNLGVBQWUsQ0FBQyxFQUFFLEdBQUcsT0FBTyxFQUFFLGNBQWMsRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUNqRixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sUUFBUSxHQUFHLFlBQVksQ0FBQyxHQUFHLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztZQUNyRCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsMEJBQTBCO1FBQzFCLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBSSxDQUFXLENBQUMsT0FBTyxLQUFNLENBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2hFLFFBQVEsR0FBRyxZQUFZLENBQUMsR0FBRyxFQUFFLDBCQUEwQixPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUM7WUFDSCxpQkFBaUI7WUFDakIsSUFBSSxZQUFZO2dCQUFFLFFBQVEsR0FBRyxNQUFNLFlBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBVSxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDWixPQUFPLENBQUMsS0FBSyxDQUFDLDJCQUE0QixFQUFZLENBQUMsT0FBTyxLQUFNLEVBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzVGLENBQUM7SUFDSCxDQUFDO0lBRUQsMkJBQTJCO0lBQzNCLElBQUksSUFBSSxHQUFXLEVBQUUsQ0FBQztJQUN0QixJQUFJLE9BQU8sUUFBUSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUN0QyxxQkFBcUI7UUFDckIsb0RBQW9EO1FBQ3BELFFBQVEsQ0FBQyxPQUFPLEdBQUcsRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLEdBQUcsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3pFLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO0lBQ3ZCLENBQUM7U0FBTSxJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN6QixnQ0FBZ0M7UUFDaEMsa0RBQWtEO1FBQ2xELElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQTBCO1FBQ3BDLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVTtRQUMvQixJQUFJO1FBQ0osT0FBTyxFQUFFLFFBQVEsQ0FBQyxPQUFPO0tBQzFCLENBQUM7SUFFRixtQkFBbUI7SUFDbkIsTUFBTSxhQUFhLEdBQUcsSUFBQSxxQkFBVyxFQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNwRCxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sQ0FBQyxpQkFBaUIsR0FBRztZQUN6QixZQUFZLEVBQUUsYUFBYTtTQUM1QixDQUFDO0lBQ0osQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBUElHYXRld2F5UHJveHlFdmVudCxcbiAgQVBJR2F0ZXdheVByb3h5UmVzdWx0LFxuICBDb250ZXh0LFxufSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCB7XG4gIENvbnRleHRCdWlsZGVyLFxuICBIYW5kbGVyLCBSZXF1ZXN0LCBSZXNwb25zZSwgUm91dGUsIFJvdXRlcyxcbn0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBidWlsZENvb2tpZSwgbWF0Y2hSb3V0ZSwgcGFyc2VSZXF1ZXN0IH0gZnJvbSAnLi9oZWxwZXJzJztcblxuZnVuY3Rpb24gdGV4dFJlc3BvbnNlKHN0YXR1c0NvZGU6IG51bWJlciwgYm9keTogc3RyaW5nKTogUmVzcG9uc2Uge1xuICByZXR1cm4ge1xuICAgIHN0YXR1c0NvZGUsXG4gICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ3RleHQvcGxhaW4nIH0sXG4gICAgYm9keVxuICB9O1xufVxuXG4vKipcbiAqIEFQSSByb3V0ZSBoYW5kbGVyXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhcGlIYW5kbGVyKFxuICBldmVudDogQVBJR2F0ZXdheVByb3h5RXZlbnQsXG4gIGNvbnRleHQ6IENvbnRleHQsXG4gIHJvdXRlczogUm91dGVzID0ge1xuICAgICcvYXBpL3BpbmcnOiB7IEdFVDogYXN5bmMgKHJlcXVlc3Q6IFJlcXVlc3QpID0+ICh7IHN0YXR1c0NvZGU6IDIwMCwgYm9keTogcmVxdWVzdCB9KSB9LFxuICB9LFxuICBlcnJvckhhbmRsZXI6IChyZXF1ZXN0OiBSZXF1ZXN0LCBlOiBFcnJvcikgPT4gUHJvbWlzZTxSZXNwb25zZT4gPSBhc3luYyAocmVxdWVzdDogUmVxdWVzdCkgPT4gKHsgc3RhdHVzQ29kZTogNTAwLCBib2R5OiB7IGVycm9yOiBgSW50ZXJuYWwgc2VydmVyIGVycm9yOiAke3JlcXVlc3QucGF0aH1gIH0gfSksXG4gIGNhdGNoQWxsOiBIYW5kbGVyID0gYXN5bmMgKHJlcXVlc3Q6IFJlcXVlc3QpID0+IHRleHRSZXNwb25zZSg0MDQsIGBOb3QgZm91bmQ6ICR7cmVxdWVzdC5wYXRofWApLFxuICBjb250ZXh0QnVpbGRlcj86IENvbnRleHRCdWlsZGVyLFxuKTogUHJvbWlzZTxBUElHYXRld2F5UHJveHlSZXN1bHQ+IHtcbiAgY29uc29sZS5sb2coYEV4ZWN1dGluZyAke2NvbnRleHQuZnVuY3Rpb25OYW1lfSB2ZXJzaW9uOiAke3Byb2Nlc3MuZW52LkNPTU1JVF9IQVNIfWApO1xuICBjb25zdCByZXF1ZXN0ID0gcGFyc2VSZXF1ZXN0KGV2ZW50KTtcblxuICBsZXQgcmVzcG9uc2U6IFJlc3BvbnNlO1xuICB0cnkge1xuICAgIGNvbnN0IG1hdGNoID0gbWF0Y2hSb3V0ZShyb3V0ZXMsIHJlcXVlc3QucGF0aCk7XG4gICAgaWYgKCFtYXRjaC5yb3V0ZSkge1xuICAgICAgLy8gQ2F0Y2gtYWxsIC8gNDA0XG4gICAgICByZXNwb25zZSA9IGF3YWl0IGNhdGNoQWxsKHJlcXVlc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBoYW5kbGVyRnVuY3Rpb24gPSBtYXRjaC5yb3V0ZVtyZXF1ZXN0Lm1ldGhvZCBhcyBrZXlvZiBSb3V0ZV07XG5cbiAgICAgIC8vIEhhbmRsZSB0aGUgcmVxdWVzdDpcbiAgICAgIGlmIChoYW5kbGVyRnVuY3Rpb24pIHtcbiAgICAgICAgaWYgKGNvbnRleHRCdWlsZGVyKSBhd2FpdCBjb250ZXh0QnVpbGRlcihyZXF1ZXN0KTtcbiAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCBoYW5kbGVyRnVuY3Rpb24oeyAuLi5yZXF1ZXN0LCBwYXRoUGFyYW1ldGVyczogbWF0Y2gucGFyYW1zIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzcG9uc2UgPSB0ZXh0UmVzcG9uc2UoNDA1LCAnTWV0aG9kIG5vdCBhbGxvd2VkJyk7XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gRmFsbGJhY2sgZXJyb3IgaGFuZGxpbmdcbiAgICBjb25zb2xlLmVycm9yKGAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfVxcbiR7KGUgYXMgRXJyb3IpLnN0YWNrfWApO1xuICAgIHJlc3BvbnNlID0gdGV4dFJlc3BvbnNlKDUwMCwgYEludGVybmFsIHNlcnZlciBlcnJvcjogJHtyZXF1ZXN0LnBhdGh9YCk7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEVycm9yIGhhbmRsaW5nXG4gICAgICBpZiAoZXJyb3JIYW5kbGVyKSByZXNwb25zZSA9IGF3YWl0IGVycm9ySGFuZGxlcihyZXF1ZXN0LCBlIGFzIEVycm9yKTtcbiAgICB9IGNhdGNoIChlZSkge1xuICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgaW4gZXJyb3IgaGFuZGxlcjogJHsoZWUgYXMgRXJyb3IpLm1lc3NhZ2V9XFxuJHsoZWUgYXMgRXJyb3IpLnN0YWNrfWApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFQSSBHYXRld2F5IFByb3h5IHJlc3VsdFxuICBsZXQgYm9keTogc3RyaW5nID0gJyc7XG4gIGlmICh0eXBlb2YgcmVzcG9uc2UuYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBVc2UgdGhlIGJvZHkgYXMtaXNcbiAgICAvLyBQb3RlbnRpYWxseSBhZGQgYSB0ZXh0L3BsYWluIGNvbnRlbnQgdHlwZSBoZWFkZXI6XG4gICAgcmVzcG9uc2UuaGVhZGVycyA9IHsgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L3BsYWluJywgLi4ucmVzcG9uc2UuaGVhZGVycyB9O1xuICAgIGJvZHkgPSByZXNwb25zZS5ib2R5O1xuICB9IGVsc2UgaWYgKHJlc3BvbnNlLmJvZHkpIHtcbiAgICAvLyBTdHJpbmdpZnkgdGhlIHJlc3BvbnNlIG9iamVjdFxuICAgIC8vIEFQSSBHYXRld2F5IHJldHVybnMgYXBwbGljYXRpb24vanNvbiBieSBkZWZhdWx0XG4gICAgYm9keSA9IEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLmJvZHkpO1xuICB9XG4gIGNvbnN0IHJlc3VsdDogQVBJR2F0ZXdheVByb3h5UmVzdWx0ID0ge1xuICAgIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1c0NvZGUsXG4gICAgYm9keSxcbiAgICBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzLFxuICB9O1xuXG4gIC8vIENvb2tpZXMgKGlmIHNldClcbiAgY29uc3QgY29va2llSGVhZGVycyA9IGJ1aWxkQ29va2llKHJlc3BvbnNlLmNvb2tpZXMpO1xuICBpZiAoY29va2llSGVhZGVycykge1xuICAgIHJlc3VsdC5tdWx0aVZhbHVlSGVhZGVycyA9IHtcbiAgICAgICdTZXQtQ29va2llJzogY29va2llSGVhZGVycyxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiJdfQ==
106
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNEJBLGdDQXdGQztBQS9HRCxtQ0FHaUI7QUFDakIsdUNBQXdGO0FBRXhGLFNBQVMsYUFBYSxDQUFDLFVBQWtCLEVBQUUsSUFBYSxFQUFFLENBQVc7SUFDbkUsSUFBSSxDQUFDLFlBQVksZ0JBQVEsRUFBRSxDQUFDO1FBQzFCLE9BQU87WUFDTCxVQUFVLEVBQUUsQ0FBQyxDQUFDLFVBQVU7WUFDeEIsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJO1NBQ2IsQ0FBQztJQUNKLENBQUM7SUFDRCxJQUFJLENBQUM7UUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUksQ0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDOUMsT0FBTztRQUNMLFVBQVUsRUFBRSxVQUFVO1FBQ3RCLElBQUksRUFBRSxJQUFJO0tBQ1gsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNJLEtBQUssVUFBVSxVQUFVLENBQzlCLEtBQTJCLEVBQzNCLE9BQWdCLEVBQ2hCLFNBQWlCO0lBQ2YsT0FBTyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Q0FDdkYsRUFDRCxlQUFnRixTQUFTLEVBQ3pGLFdBQWdDLFNBQVM7SUFFekMsTUFBTSxPQUFPLEdBQUcsSUFBQSxzQkFBWSxFQUFDLEtBQUssQ0FBQyxDQUFDO0lBRXBDLElBQUksUUFBa0IsQ0FBQztJQUN2QixJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssR0FBRyxJQUFBLG9CQUFVLEVBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQyxJQUFJLEtBQUssQ0FBQyxN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QU8sQ0FBQyxDQUFDO1FBQzFGLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO0lBQ3ZCLENBQUM7U0FBTSxJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN6QixnQ0FBZ0M7UUFDaEMsa0RBQWtEO1FBQ2xELElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsbUJBQW1CO0lBQ25CLE1BQU0sTUFBTSxHQUEwQjtRQUNwQyxVQUFVLEVBQUUsUUFBUSxDQUFDLFVBQVUsSUFBSSxHQUFHO1FBQ3RDLE9BQU87UUFDUCxJQUFJLEVBQUUsSUFBSSxJQUFJLEVBQUU7S0FDakIsQ0FBQztJQUVGLHFCQUFxQjtJQUNyQixNQUFNLGFBQWEsR0FBRyxJQUFBLHFCQUFXLEVBQUMsUUFBUSxDQUFDLENBQUM7SUFDNUMsSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUNsQixNQUFNLENBQUMsaUJBQWlCLEdBQUc7WUFDekIsWUFBWSxFQUFFLGFBQWE7U0FDNUIsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQVBJR2F0ZXdheVByb3h5RXZlbnQsXG4gIEFQSUdhdGV3YXlQcm94eVJlc3VsdCxcbiAgQ29udGV4dCxcbn0gZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQge1xuICBSZXF1ZXN0LCBSZXNwb25zZSwgSGFuZGxlciwgUm91dGUsIFJvdXRlcyxcbiAgQXBpRXJyb3IsXG59IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgYnVpbGRDb29raWUsIGdldEhlYWRlciwgbWF0Y2hSb3V0ZSwgcGFyc2VSZXF1ZXN0LCBzZXRIZWFkZXIgfSBmcm9tICcuL2hlbHBlcnMnO1xuXG5mdW5jdGlvbiBlcnJvclJlc3BvbnNlKHN0YXR1c0NvZGU6IG51bWJlciwgYm9keTogdW5rbm93biwgZT86IHVua25vd24pOiBSZXNwb25zZSB7XG4gIGlmIChlIGluc3RhbmNlb2YgQXBpRXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzQ29kZTogZS5zdGF0dXNDb2RlLFxuICAgICAgYm9keTogZS5ib2R5LFxuICAgIH07XG4gIH1cbiAgaWYgKGUpIGNvbnNvbGUuZXJyb3IoYCR7KGUgYXMgRXJyb3IpLnN0YWNrfWApO1xuICByZXR1cm4ge1xuICAgIHN0YXR1c0NvZGU6IHN0YXR1c0NvZGUsXG4gICAgYm9keTogYm9keSxcbiAgfTtcbn1cblxuLyoqXG4gKiBBUEkgcm91dGUgaGFuZGxlclxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXBpSGFuZGxlcihcbiAgZXZlbnQ6IEFQSUdhdGV3YXlQcm94eUV2ZW50LFxuICBjb250ZXh0OiBDb250ZXh0LFxuICByb3V0ZXM6IFJvdXRlcyA9IHtcbiAgICAnL3BpbmcnOiB7IEdFVDogeyBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCkgPT4gKHsgc3RhdHVzQ29kZTogMjAwLCBib2R5OiByZXF1ZXN0IH0pIH0gfSxcbiAgfSxcbiAgZXJyb3JIYW5kbGVyOiAoKHJlcXVlc3Q6IFJlcXVlc3QsIGU6IEVycm9yKSA9PiBQcm9taXNlPFJlc3BvbnNlPikgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gIGNhdGNoQWxsOiBIYW5kbGVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLFxuKTogUHJvbWlzZTxBUElHYXRld2F5UHJveHlSZXN1bHQ+IHtcbiAgY29uc3QgcmVxdWVzdCA9IHBhcnNlUmVxdWVzdChldmVudCk7XG5cbiAgbGV0IHJlc3BvbnNlOiBSZXNwb25zZTtcbiAgdHJ5IHtcbiAgICBjb25zdCBtYXRjaCA9IG1hdGNoUm91dGUocm91dGVzLCByZXF1ZXN0LnBhdGgpO1xuICAgIGlmIChtYXRjaC5wYXJhbXMpIHJlcXVlc3QucGF0aFBhcmFtZXRlcnMgPSBtYXRjaC5wYXJhbXM7XG5cbiAgICBpZiAobWF0Y2gubWV0aG9kcykge1xuICAgICAgY29uc3Qgcm91dGUgPSBtYXRjaC5tZXRob2RzW3JlcXVlc3QubWV0aG9kIGFzIGtleW9mIFJvdXRlXTtcbiAgICAgIGlmICghcm91dGUpIHRocm93IG5ldyBBcGlFcnJvcig0MDUsICdNZXRob2Qgbm90IGFsbG93ZWQnKTtcblxuICAgICAgLy8gVmVyaWZ5IHJlcXVlc3QgYm9keVxuICAgICAgaWYgKHJvdXRlLnJlcXVlc3Q/LmJvZHkpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gcm91dGUucmVxdWVzdC5ib2R5LnNhZmVQYXJzZShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICBpZiAoIXBhcnNlZC5zdWNjZXNzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEFwaUVycm9yKDQwMCwgcGFyc2VkLmVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICByZXF1ZXN0LmJvZHkgPSBwYXJzZWQuZGF0YTtcbiAgICAgIH1cblxuICAgICAgcmVzcG9uc2UgPSBhd2FpdCByb3V0ZS5oYW5kbGVyKHJlcXVlc3QpO1xuXG4gICAgICAvLyBWZXJpZnkgcmVzcG9uc2UgYm9keVxuICAgICAgaWYgKHJvdXRlLnJlc3BvbnNlPy5ib2R5KSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IHJvdXRlLnJlc3BvbnNlLmJvZHkuc2FmZVBhcnNlKHJlc3BvbnNlLmJvZHkpO1xuICAgICAgICBpZiAoIXBhcnNlZC5zdWNjZXNzKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihKU09OLnN0cmluZ2lmeShwYXJzZWQuZXJyb3IsIG51bGwsIDIpKTtcbiAgICAgICAgICB0aHJvdyBuZXcgQXBpRXJyb3IoNTAwLCAnSW50ZXJuYWwgc2VydmVyIGVycm9yJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2UuYm9keSA9IHBhcnNlZC5kYXRhO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY2F0Y2hBbGwpIHtcbiAgICAgIC8vIENhdGNoLWFsbCAvIDQwNFxuICAgICAgcmVzcG9uc2UgPSBhd2FpdCBjYXRjaEFsbC5oYW5kbGVyKHJlcXVlc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgQXBpRXJyb3IoNDA0LCAnTm90IGZvdW5kJyk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGVycm9ySGFuZGxlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCBlcnJvckhhbmRsZXIocmVxdWVzdCwgZSBhcyBFcnJvcik7XG4gICAgICB9IGNhdGNoIChlZSkge1xuICAgICAgICByZXNwb25zZSA9IGVycm9yUmVzcG9uc2UoNTAwLCAnSW50ZXJuYWwgc2VydmVyIGVycm9yJywgZWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXNwb25zZSA9IGVycm9yUmVzcG9uc2UoNTAwLCAnSW50ZXJuYWwgc2VydmVyIGVycm9yJywgZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gVHJhbnNsYXRlIHRoZSByZXNwb25zZSB0byBhbiBBUEkgR2F0ZXdheSBQcm94eSByZXN1bHRcbiAgbGV0IGJvZHk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgY29uc3QgaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnMgfHwge307XG4gIGlmICh0eXBlb2YgcmVzcG9uc2UuYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBVc2UgdGhlIGJvZHkgYXMtaXNcbiAgICAvLyBBZGQgdGV4dC9wbGFpbiBpZiBubyBDb250ZW50LVR5cGUgaGVhZGVyIGlzIHNldDpcbiAgICBpZiAoIWdldEhlYWRlcignQ29udGVudC1UeXBlJywgaGVhZGVycykpIHNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvcGxhaW4nLCBoZWFkZXJzKTtcbiAgICBib2R5ID0gcmVzcG9uc2UuYm9keTtcbiAgfSBlbHNlIGlmIChyZXNwb25zZS5ib2R5KSB7XG4gICAgLy8gU3RyaW5naWZ5IHRoZSByZXNwb25zZSBvYmplY3RcbiAgICAvLyBBUEkgR2F0ZXdheSByZXR1cm5zIGFwcGxpY2F0aW9uL2pzb24gYnkgZGVmYXVsdFxuICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShyZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIC8vIFByZXBhcmUgcmVzcG9uc2VcbiAgY29uc3QgcmVzdWx0OiBBUElHYXRld2F5UHJveHlSZXN1bHQgPSB7XG4gICAgc3RhdHVzQ29kZTogcmVzcG9uc2Uuc3RhdHVzQ29kZSA/PyAyMDAsXG4gICAgaGVhZGVycyxcbiAgICBib2R5OiBib2R5IHx8ICcnLFxuICB9O1xuXG4gIC8vIEFkZCBjb29raWUgaGVhZGVyc1xuICBjb25zdCBjb29raWVIZWFkZXJzID0gYnVpbGRDb29raWUocmVzcG9uc2UpO1xuICBpZiAoY29va2llSGVhZGVycykge1xuICAgIHJlc3VsdC5tdWx0aVZhbHVlSGVhZGVycyA9IHtcbiAgICAgICdTZXQtQ29va2llJzogY29va2llSGVhZGVycyxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiJdfQ==
package/dist/helpers.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { APIGatewayProxyEvent } from 'aws-lambda';
2
- import { Request, Route, Routes } from './types';
2
+ import { Request, Response, Route, Routes } from './types';
3
3
  /**
4
4
  * Ensures the path is lowercased, always has a leading slash and never a trailing slash
5
5
  * @param path APIGatewayProxyEvent.path
@@ -15,7 +15,7 @@ export declare function standardQueryParameters(query: {
15
15
  [name: string]: string;
16
16
  };
17
17
  /**
18
- * Ensures all header names are lowercased for ease of access.
18
+ * Ensures all headers have a value.
19
19
  * @param headers APIGatewayProxyEvent.headers
20
20
  */
21
21
  export declare function standardHeaders(headers: {
@@ -38,12 +38,22 @@ export declare function parseCookie(headers: {
38
38
  }): {
39
39
  [name: string]: string;
40
40
  };
41
- export declare function buildCookie(values: {
42
- [key: string]: string;
43
- } | undefined): string[] | undefined;
41
+ export declare function buildCookie(response: Response, maxAge?: number | undefined, expires?: Date | undefined, secure?: boolean, httpOnly?: boolean, sameSite?: 'strict' | 'lax' | 'none'): string[] | undefined;
42
+ /**
43
+ * Case-insensitive header lookup
44
+ */
45
+ export declare function getHeader(name: string, headers: {
46
+ [key: string]: string | undefined;
47
+ } | undefined): string | undefined;
48
+ /**
49
+ * Case-insensitive header setting
50
+ */
51
+ export declare function setHeader(name: string, value: string, headers: {
52
+ [key: string]: string | undefined;
53
+ } | undefined): void;
44
54
  export declare function parseRequest(event: APIGatewayProxyEvent): Request;
45
55
  export declare function matchRoute(routes: Routes, path: string): {
46
- route: Route | undefined;
56
+ methods: Route | undefined;
47
57
  params: {
48
58
  [name: string]: string;
49
59
  };
package/dist/helpers.js CHANGED
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
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
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
36
  exports.standardPath = standardPath;
27
37
  exports.standardQueryParameters = standardQueryParameters;
@@ -29,6 +39,8 @@ exports.standardHeaders = standardHeaders;
29
39
  exports.parseBody = parseBody;
30
40
  exports.parseCookie = parseCookie;
31
41
  exports.buildCookie = buildCookie;
42
+ exports.getHeader = getHeader;
43
+ exports.setHeader = setHeader;
32
44
  exports.parseRequest = parseRequest;
33
45
  exports.matchRoute = matchRoute;
34
46
  const cookie = __importStar(require("cookie"));
@@ -58,19 +70,14 @@ function standardQueryParameters(query) {
58
70
  return result;
59
71
  }
60
72
  /**
61
- * Ensures all header names are lowercased for ease of access.
73
+ * Ensures all headers have a value.
62
74
  * @param headers APIGatewayProxyEvent.headers
63
75
  */
64
76
  function standardHeaders(headers) {
65
77
  const result = {};
66
- Object.keys(headers).forEach((name) => {
67
- const value = headers[name];
68
- if (value) {
69
- // Provide both original-case and lowercased (standardised) header names for ease of access:
70
- result[name] = value;
71
- result[name.toLowerCase()] = value;
72
- }
73
- });
78
+ for (const [name, value] of Object.entries(headers || {})) {
79
+ result[name] = value ?? '';
80
+ }
74
81
  return result;
75
82
  }
76
83
  /**
@@ -102,81 +109,121 @@ function parseBody(body, isBase64Encoded, contentType = 'application/json') {
102
109
  * @param headers APIGatewayProxyEvent.headers
103
110
  */
104
111
  function parseCookie(headers) {
105
- const header = headers.cookie || headers.Cookie || '';
106
- return cookie.parse(header);
112
+ const header = getHeader('Cookie', headers);
113
+ const values = header ? cookie.parse(header) : {};
114
+ // Ensure we don't return any undefined values
115
+ const result = {};
116
+ for (const [name, value] of Object.entries(values)) {
117
+ if (value)
118
+ result[name] = value;
119
+ }
120
+ return result;
107
121
  }
108
- function buildCookie(values) {
109
- if (!values)
122
+ function buildCookie(response, maxAge = 60 * 60 * 24 * 365, expires = undefined, secure = true, httpOnly = true, sameSite = 'lax') {
123
+ if (!response.cookies)
110
124
  return undefined;
125
+ const cookies = {};
126
+ for (const [key, value] of Object.entries(response.cookies)) {
127
+ cookies[key] = value;
128
+ }
111
129
  const header = [];
112
- const oneYear = 60 * 60 * 24 * 365;
113
- Object.keys(values).forEach((key) => {
114
- const value = values[key];
130
+ Object.keys(cookies).forEach((key) => {
131
+ const value = cookies[key];
115
132
  if (value === '') {
116
133
  // If explicitly unset, expire the cookie value
117
134
  header.push(cookie.serialize(key, '', {
118
- expires: new Date(), secure: true, httpOnly: true, sameSite: 'strict',
135
+ expires: new Date(), secure, httpOnly, sameSite,
119
136
  }));
120
137
  }
121
138
  else if (value) {
122
139
  // Otherwise, set it only if a value was given
123
140
  header.push(cookie.serialize(key, value, {
124
- maxAge: oneYear, secure: true, httpOnly: true, sameSite: 'strict',
141
+ maxAge, expires, secure, httpOnly, sameSite,
125
142
  }));
126
143
  }
127
144
  });
128
145
  return header;
129
146
  }
147
+ /**
148
+ * Case-insensitive header lookup
149
+ */
150
+ function getHeader(name, headers) {
151
+ if (!headers)
152
+ return undefined;
153
+ // Exact match
154
+ if (headers[name])
155
+ return headers[name];
156
+ // Case-insensitive match
157
+ const lowercased = {};
158
+ for (const [key, value] of Object.entries(headers)) {
159
+ lowercased[key.toLowerCase()] = value;
160
+ }
161
+ return lowercased[name.toLowerCase()];
162
+ }
163
+ /**
164
+ * Case-insensitive header setting
165
+ */
166
+ function setHeader(name, value, headers) {
167
+ if (!headers)
168
+ return;
169
+ let set = false;
170
+ for (const key of Object.keys(headers)) {
171
+ if (name.toLowerCase() === key.toLowerCase()) {
172
+ headers[key] = value;
173
+ set = true;
174
+ }
175
+ }
176
+ if (!set)
177
+ headers[name] = value;
178
+ }
130
179
  function parseRequest(event) {
131
180
  return {
132
181
  method: event.httpMethod,
133
182
  path: standardPath(event.path),
134
183
  query: standardQueryParameters(event.queryStringParameters),
135
184
  headers: standardHeaders(event.headers),
136
- body: parseBody(event.body, event.isBase64Encoded, event.headers['content-type']),
185
+ body: parseBody(event.body, event.isBase64Encoded, getHeader('Content-Type', event.headers)),
137
186
  cookies: parseCookie(event.headers),
138
187
  pathParameters: {}, // These need to be parsed as part of route matching
139
- context: {}, // You can add any custom values you need to the request via this context
188
+ context: { event }, // You can add any custom values you need to the request via this context
140
189
  };
141
190
  }
142
191
  function matchRoute(routes, path) {
143
- // Simple match
192
+ // Direct match
144
193
  if (routes[path])
145
- return { route: routes[path], params: {} };
194
+ return { methods: routes[path], params: {} };
146
195
  // List paths to check
147
196
  const paths = Object.keys(routes);
148
197
  // Case-insensitive match
149
- for (let p = 0; p < paths.length; p++) {
150
- const candidate = paths[p];
198
+ for (const candidate of paths) {
151
199
  if (candidate.toLowerCase() === path.toLowerCase())
152
- return { route: routes[candidate], params: {} };
200
+ return { methods: routes[candidate], params: {} };
153
201
  }
154
202
  // Path-parameter matching
155
203
  const pathSegments = path.split('/');
156
- for (let p = 0; p < paths.length; p++) {
157
- const candidate = paths[p];
204
+ for (const candidate of paths) {
158
205
  const candidateSegments = candidate.split('/');
159
206
  // First check: length match
160
207
  if (pathSegments.length !== candidateSegments.length)
161
208
  continue;
162
209
  for (let s = 0; s < pathSegments.length; s++) {
163
210
  const params = {};
164
- const pathSegment = pathSegments[s];
165
- const candidateSegment = candidateSegments[s];
211
+ const pathSegment = pathSegments[s] ?? '';
212
+ const candidateSegment = candidateSegments[s] ?? '';
166
213
  if (candidateSegment.startsWith('{') && candidateSegment.endsWith('}')) {
167
214
  // Path parameter
168
215
  const name = candidateSegment.slice(1, -1);
169
216
  params[name] = pathSegment;
170
217
  }
171
- else if (pathSegment !== candidateSegment) {
218
+ else if (pathSegment.toLowerCase() !== candidateSegment.toLowerCase()) {
172
219
  break;
173
220
  }
174
221
  if (s === pathSegments.length - 1) {
175
222
  // Matched all segments
176
- return { route: routes[candidate], params };
223
+ return { methods: routes[candidate], params };
177
224
  }
178
225
  }
179
226
  }
180
- return { route: undefined, params: {} };
227
+ return { methods: undefined, params: {} };
181
228
  }
182
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRQSxvQ0FLQztBQU1ELDBEQVFDO0FBTUQsMENBV0M7QUFPRCw4QkFrQkM7QUFNRCxrQ0FHQztBQUVELGtDQXNCQztBQUVELG9DQVdDO0FBRUQsZ0NBMkNDO0FBL0pELCtDQUFpQztBQUdqQzs7O0dBR0c7QUFDSCxTQUFnQixZQUFZLENBQUMsSUFBWTtJQUN2Qyw4Q0FBOEM7SUFDOUMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlELGNBQWM7SUFDZCxPQUFPLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDO0FBQ2hELENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQix1QkFBdUIsQ0FBQyxLQUFxRDtJQUMzRixJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3RCLE1BQU0sTUFBTSxHQUFnQyxFQUFFLENBQUM7SUFDL0MsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtRQUN2QyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0IsSUFBSSxLQUFLO1lBQUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEtBQUssQ0FBQztJQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixlQUFlLENBQUMsT0FBZ0Q7SUFDOUUsTUFBTSxNQUFNLEdBQWdDLEVBQUUsQ0FBQztJQUMv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QztZQUM3QixDQUFDO2lCQUFNLElBQUksV0FBVyxLQUFLLGdCQUFnQixFQUFFLENBQUM7Z0JBQzVDLE1BQU07WUFDUixDQUFDO1lBRUQsSUFBSSxDQUFDLEtBQUssWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDbEMsdUJBQXVCO2dCQUN2QixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUM5QyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUM7QUFDMUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFQSUdhdGV3YXlQcm94eUV2ZW50IH0gZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgKiBhcyBjb29raWUgZnJvbSAnY29va2llJztcbmltcG9ydCB7IFJlcXVlc3QsIFJvdXRlLCBSb3V0ZXMgfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiBFbnN1cmVzIHRoZSBwYXRoIGlzIGxvd2VyY2FzZWQsIGFsd2F5cyBoYXMgYSBsZWFkaW5nIHNsYXNoIGFuZCBuZXZlciBhIHRyYWlsaW5nIHNsYXNoXG4gKiBAcGFyYW0gcGF0aCBBUElHYXRld2F5UHJveHlFdmVudC5wYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFuZGFyZFBhdGgocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gR2V0IHBhdGggc2VnbWVudHMsIGZpbHRlcmluZyBvdXQgYW55IGJsYW5rc1xuICBjb25zdCBzZWdtZW50cyA9IHBhdGguc3BsaXQoJy8nKS5maWx0ZXIoKHNlZ21lbnQpID0+IHNlZ21lbnQpO1xuICAvLyBSZXR1cm4gcGF0aFxuICByZXR1cm4gYC8ke3NlZ21lbnRzLmpvaW4oJy8nKS50b0xvd2VyQ2FzZSgpfWA7XG59XG5cbi8qKlxuICogRW5zdXJlcyBhIG5vbi1udWxsIG9iamVjdCBjb250YWluaW5nIG9ubHkgcXVlcnktc3RyaW5nIHBhcmFtZXRlcnMgdGhhdCBoYXZlIGEgdmFsdWUuXG4gKiBAcGFyYW0gcXVlcnkgQVBJR2F0ZXdheVByb3h5RXZlbnQucXVlcnlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YW5kYXJkUXVlcnlQYXJhbWV0ZXJzKHF1ZXJ5OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQ7IH0gfCBudWxsKTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9IHtcbiAgaWYgKCFxdWVyeSkgcmV0dXJuIHt9O1xuICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfSA9IHt9O1xuICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaCgocGFyYW1ldGVyKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBxdWVyeVtwYXJhbWV0ZXJdO1xuICAgIGlmICh2YWx1ZSkgcmVzdWx0W3BhcmFtZXRlcl0gPSB2YWx1ZTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRW5zdXJlcyBhbGwgaGVhZGVyIG5hbWVzIGFyZSBsb3dlcmNhc2VkIGZvciBlYXNlIG9mIGFjY2Vzcy5cbiAqIEBwYXJhbSBoZWFkZXJzIEFQSUdhdGV3YXlQcm94eUV2ZW50LmhlYWRlcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YW5kYXJkSGVhZGVycyhoZWFkZXJzOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQ7IH0pOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0ge1xuICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfSA9IHt9O1xuICBPYmplY3Qua2V5cyhoZWFkZXJzKS5mb3JFYWNoKChuYW1lKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBoZWFkZXJzW25hbWVdO1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgLy8gUHJvdmlkZSBib3RoIG9yaWdpbmFsLWNhc2UgYW5kIGxvd2VyY2FzZWQgKHN0YW5kYXJkaXNlZCkgaGVhZGVyIG5hbWVzIGZvciBlYXNlIG9mIGFjY2VzczpcbiAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xuICAgICAgcmVzdWx0W25hbWUudG9Mb3dlckNhc2UoKV0gPSB2YWx1ZTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgYm9keSAoaWYgcHJlc2VudCkgZnJvbSBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQgb3IgSlNPTiBzdHJpbmcuXG4gKiBJZiB0aGUgYm9keSBmYWlscyB0byBwYXJzZSBhcyBKU09uLCB0aGUgcmF3IGJvZHkgaXMgcmV0dXJuZWQuXG4gKiBAcGFyYW0gYm9keSBBUElHYXRld2F5UHJveHlFdmVudC5ib2R5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJvZHkoYm9keTogc3RyaW5nIHwgbnVsbCwgaXNCYXNlNjRFbmNvZGVkOiBib29sZWFuLCBjb250ZW50VHlwZTogc3RyaW5nID0gJ2FwcGxpY2F0aW9uL2pzb24nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBzdHJpbmcge1xuICBpZiAoIWJvZHkpIHJldHVybiB7fTtcblxuICBjb25zdCBjb250ZW50ID0gaXNCYXNlNjRFbmNvZGVkID8gQnVmZmVyLmZyb20oYm9keSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCd1dGY4JykgOiBib2R5O1xuXG4gIHRyeSB7XG4gICAgaWYgKChjb250ZW50VHlwZSB8fCAnJykudG9Mb3dlckNhc2UoKSA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpIHtcbiAgICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMobmV3IFVSTFNlYXJjaFBhcmFtcyhjb250ZW50KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgdG8gcGFyc2luZyBhcyBKU09OOlxuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoY29udGVudCk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcihgRXJyb3IgcGFyc2luZyByZXF1ZXN0IGJvZHk6ICR7ZX1gKTtcbiAgfVxuXG4gIC8vIEZhbGxiYWNrIHRvIHJldHVybmluZyB0aGUgcmF3IGJvZHlcbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBjb29raWUsIGlmIGFueSwgcmV0dXJuaW5nIGF0IG1pbmltdW0gYW4gZW1wdHkgb2JqZWN0LlxuICogQHBhcmFtIGhlYWRlcnMgQVBJR2F0ZXdheVByb3h5RXZlbnQuaGVhZGVyc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDb29raWUoaGVhZGVyczogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkOyB9KTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9IHtcbiAgY29uc3QgaGVhZGVyID0gaGVhZGVycy5jb29raWUgfHwgaGVhZGVycy5Db29raWUgfHwgJyc7XG4gIHJldHVybiBjb29raWUucGFyc2UoaGVhZGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ29va2llKHZhbHVlczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmc7IH0gfCB1bmRlZmluZWQpOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCB7XG4gIGlmICghdmFsdWVzKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGhlYWRlcjogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgb25lWWVhciA9IDYwICogNjAgKiAyNCAqIDM2NTtcblxuICBPYmplY3Qua2V5cyh2YWx1ZXMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzW2tleV07XG4gICAgaWYgKHZhbHVlID09PSAnJykge1xuICAgICAgLy8gSWYgZXhwbGljaXRseSB1bnNldCwgZXhwaXJlIHRoZSBjb29raWUgdmFsdWVcbiAgICAgIGhlYWRlci5wdXNoKGNvb2tpZS5zZXJpYWxpemUoa2V5LCAnJywge1xuICAgICAgICBleHBpcmVzOiBuZXcgRGF0ZSgpLCBzZWN1cmU6IHRydWUsIGh0dHBPbmx5OiB0cnVlLCBzYW1lU2l0ZTogJ3N0cmljdCcsXG4gICAgICB9KSk7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSkge1xuICAgICAgLy8gT3RoZXJ3aXNlLCBzZXQgaXQgb25seSBpZiBhIHZhbHVlIHdhcyBnaXZlblxuICAgICAgaGVhZGVyLnB1c2goY29va2llLnNlcmlhbGl6ZShrZXksIHZhbHVlLCB7XG4gICAgICAgIG1heEFnZTogb25lWWVhciwgc2VjdXJlOiB0cnVlLCBodHRwT25seTogdHJ1ZSwgc2FtZVNpdGU6ICdzdHJpY3QnLFxuICAgICAgfSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGhlYWRlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUmVxdWVzdChldmVudDogQVBJR2F0ZXdheVByb3h5RXZlbnQpOiBSZXF1ZXN0IHtcbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IGV2ZW50Lmh0dHBNZXRob2QsXG4gICAgcGF0aDogc3RhbmRhcmRQYXRoKGV2ZW50LnBhdGgpLFxuICAgIHF1ZXJ5OiBzdGFuZGFyZFF1ZXJ5UGFyYW1ldGVycyhldmVudC5xdWVyeVN0cmluZ1BhcmFtZXRlcnMpLFxuICAgIGhlYWRlcnM6IHN0YW5kYXJkSGVhZGVycyhldmVudC5oZWFkZXJzKSxcbiAgICBib2R5OiBwYXJzZUJvZHkoZXZlbnQuYm9keSwgZXZlbnQuaXNCYXNlNjRFbmNvZGVkLCBldmVudC5oZWFkZXJzWydjb250ZW50LXR5cGUnXSksXG4gICAgY29va2llczogcGFyc2VDb29raWUoZXZlbnQuaGVhZGVycyksXG4gICAgcGF0aFBhcmFtZXRlcnM6IHt9LCAvLyBUaGVzZSBuZWVkIHRvIGJlIHBhcnNlZCBhcyBwYXJ0IG9mIHJvdXRlIG1hdGNoaW5nXG4gICAgY29udGV4dDoge30sIC8vIFlvdSBjYW4gYWRkIGFueSBjdXN0b20gdmFsdWVzIHlvdSBuZWVkIHRvIHRoZSByZXF1ZXN0IHZpYSB0aGlzIGNvbnRleHRcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoUm91dGUocm91dGVzOiBSb3V0ZXMsIHBhdGg6IHN0cmluZyk6IHsgcm91dGU6IFJvdXRlIHwgdW5kZWZpbmVkLCBwYXJhbXM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfTsgfSB7XG4gIC8vIFNpbXBsZSBtYXRjaFxuICBpZiAocm91dGVzW3BhdGhdKSByZXR1cm4geyByb3V0ZTogcm91dGVzW3BhdGhdLCBwYXJhbXM6IHt9IH07XG5cbiAgLy8gTGlzdCBwYXRocyB0byBjaGVja1xuICBjb25zdCBwYXRocyA9IE9iamVjdC5rZXlzKHJvdXRlcyk7XG5cbiAgLy8gQ2FzZS1pbnNlbnNpdGl2ZSBtYXRjaFxuICBmb3IgKGxldCBwID0gMDsgcCA8IHBhdGhzLmxlbmd0aDsgcCsrKSB7XG4gICAgY29uc3QgY2FuZGlkYXRlID0gcGF0aHNbcF07XG4gICAgaWYgKGNhbmRpZGF0ZS50b0xvd2VyQ2FzZSgpID09PSBwYXRoLnRvTG93ZXJDYXNlKCkpIHJldHVybiB7IHJvdXRlOiByb3V0ZXNbY2FuZGlkYXRlXSwgcGFyYW1zOiB7fSB9O1xuICB9XG5cbiAgLy8gUGF0aC1wYXJhbWV0ZXIgbWF0Y2hpbmdcbiAgY29uc3QgcGF0aFNlZ21lbnRzID0gcGF0aC5zcGxpdCgnLycpO1xuXG4gIGZvciAobGV0IHAgPSAwOyBwIDwgcGF0aHMubGVuZ3RoOyBwKyspIHtcbiAgICBjb25zdCBjYW5kaWRhdGUgPSBwYXRoc1twXTtcbiAgICBjb25zdCBjYW5kaWRhdGVTZWdtZW50cyA9IGNhbmRpZGF0ZS5zcGxpdCgnLycpO1xuXG4gICAgLy8gRmlyc3QgY2hlY2s6IGxlbmd0aCBtYXRjaFxuICAgIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoICE9PSBjYW5kaWRhdGVTZWdtZW50cy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgZm9yIChsZXQgcyA9IDA7IHMgPCBwYXRoU2VnbWVudHMubGVuZ3RoOyBzKyspIHtcbiAgICAgIGNvbnN0IHBhcmFtczogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge307XG4gICAgICBjb25zdCBwYXRoU2VnbWVudCA9IHBhdGhTZWdtZW50c1tzXTtcbiAgICAgIGNvbnN0IGNhbmRpZGF0ZVNlZ21lbnQgPSBjYW5kaWRhdGVTZWdtZW50c1tzXTtcbiAgICAgIGlmIChjYW5kaWRhdGVTZWdtZW50LnN0YXJ0c1dpdGgoJ3snKSAmJiBjYW5kaWRhdGVTZWdtZW50LmVuZHNXaXRoKCd9JykpIHtcbiAgICAgICAgLy8gUGF0aCBwYXJhbWV0ZXJcbiAgICAgICAgY29uc3QgbmFtZSA9IGNhbmRpZGF0ZVNlZ21lbnQuc2xpY2UoMSwgLTEpO1xuICAgICAgICBwYXJhbXNbbmFtZV0gPSBwYXRoU2VnbWVudDtcbiAgICAgIH0gZWxzZSBpZiAocGF0aFNlZ21lbnQgIT09IGNhbmRpZGF0ZVNlZ21lbnQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChzID09PSBwYXRoU2VnbWVudHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAvLyBNYXRjaGVkIGFsbCBzZWdtZW50c1xuICAgICAgICByZXR1cm4geyByb3V0ZTogcm91dGVzW2NhbmRpZGF0ZV0sIHBhcmFtcyB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IHJvdXRlOiB1bmRlZmluZWQsIHBhcmFtczoge30gfTtcbn1cbiJdfQ==
229
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBUUEsb0NBS0M7QUFNRCwwREFRQztBQU1ELDBDQU1DO0FBT0QsOEJBa0JDO0FBTUQsa0NBVUM7QUFFRCxrQ0FpQ0M7QUFLRCw4QkFZQztBQUtELDhCQVVDO0FBRUQsb0NBV0M7QUFFRCxnQ0F5Q0M7QUExTUQsK0NBQWlDO0FBR2pDOzs7R0FHRztBQUNILFNBQWdCLFlBQVksQ0FBQyxJQUFZO0lBQ3ZDLDhDQUE4QztJQUM5QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDOUQsY0FBYztJQUNkLE9BQU8sSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7QUFDaEQsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLHVCQUF1QixDQUFDLEtBQXFEO0lBQzNGLElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDdEIsTUFBTSxNQUFNLEdBQWdDLEVBQUUsQ0FBQztJQUMvQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO1FBQ3ZDLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMvQixJQUFJLEtBQUs7WUFBRSxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ3ZDLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxPQUFnRDtJQUM5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QUUsQ0FBQztnQkFDdkUsaUJBQWlCO2dCQUNqQixNQUFNLElBQUksR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxXQUFXLENBQUM7WUFDN0IsQ0FBQztpQkFBTSxJQUFJLFdBQVcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDO2dCQUN4RSxNQUFNO1lBQ1IsQ0FBQztZQUVELElBQUksQ0FBQyxLQUFLLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xDLHVCQUF1QjtnQkFDdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUM7WUFDaEQsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDO0FBQzVDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBUElHYXRld2F5UHJveHlFdmVudCB9IGZyb20gJ2F3cy1sYW1iZGEnO1xuaW1wb3J0ICogYXMgY29va2llIGZyb20gJ2Nvb2tpZSc7XG5pbXBvcnQgeyBSZXF1ZXN0LCBSZXNwb25zZSwgUm91dGUsIFJvdXRlcyB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIEVuc3VyZXMgdGhlIHBhdGggaXMgbG93ZXJjYXNlZCwgYWx3YXlzIGhhcyBhIGxlYWRpbmcgc2xhc2ggYW5kIG5ldmVyIGEgdHJhaWxpbmcgc2xhc2hcbiAqIEBwYXJhbSBwYXRoIEFQSUdhdGV3YXlQcm94eUV2ZW50LnBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YW5kYXJkUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBHZXQgcGF0aCBzZWdtZW50cywgZmlsdGVyaW5nIG91dCBhbnkgYmxhbmtzXG4gIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdCgnLycpLmZpbHRlcigoc2VnbWVudCkgPT4gc2VnbWVudCk7XG4gIC8vIFJldHVybiBwYXRoXG4gIHJldHVybiBgLyR7c2VnbWVudHMuam9pbignLycpLnRvTG93ZXJDYXNlKCl9YDtcbn1cblxuLyoqXG4gKiBFbnN1cmVzIGEgbm9uLW51bGwgb2JqZWN0IGNvbnRhaW5pbmcgb25seSBxdWVyeS1zdHJpbmcgcGFyYW1ldGVycyB0aGF0IGhhdmUgYSB2YWx1ZS5cbiAqIEBwYXJhbSBxdWVyeSBBUElHYXRld2F5UHJveHlFdmVudC5xdWVyeVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhbmRhcmRRdWVyeVBhcmFtZXRlcnMocXVlcnk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZDsgfSB8IG51bGwpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0ge1xuICBpZiAoIXF1ZXJ5KSByZXR1cm4ge307XG4gIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge307XG4gIE9iamVjdC5rZXlzKHF1ZXJ5KS5mb3JFYWNoKChwYXJhbWV0ZXIpID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IHF1ZXJ5W3BhcmFtZXRlcl07XG4gICAgaWYgKHZhbHVlKSByZXN1bHRbcGFyYW1ldGVyXSA9IHZhbHVlO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBFbnN1cmVzIGFsbCBoZWFkZXJzIGhhdmUgYSB2YWx1ZS5cbiAqIEBwYXJhbSBoZWFkZXJzIEFQSUdhdGV3YXlQcm94eUV2ZW50LmhlYWRlcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YW5kYXJkSGVhZGVycyhoZWFkZXJzOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQ7IH0pOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0ge1xuICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfSA9IHt9O1xuICBmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoaGVhZGVycyB8fCB7fSkpIHtcbiAgICByZXN1bHRbbmFtZV0gPSB2YWx1ZSA/PyAnJztcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgYm9keSAoaWYgcHJlc2VudCkgZnJvbSBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQgb3IgSlNPTiBzdHJpbmcuXG4gKiBJZiB0aGUgYm9keSBmYWlscyB0byBwYXJzZSBhcyBKU09uLCB0aGUgcmF3IGJvZHkgaXMgcmV0dXJuZWQuXG4gKiBAcGFyYW0gYm9keSBBUElHYXRld2F5UHJveHlFdmVudC5ib2R5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJvZHkoYm9keTogc3RyaW5nIHwgbnVsbCwgaXNCYXNlNjRFbmNvZGVkOiBib29sZWFuLCBjb250ZW50VHlwZTogc3RyaW5nID0gJ2FwcGxpY2F0aW9uL2pzb24nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBzdHJpbmcge1xuICBpZiAoIWJvZHkpIHJldHVybiB7fTtcblxuICBjb25zdCBjb250ZW50ID0gaXNCYXNlNjRFbmNvZGVkID8gQnVmZmVyLmZyb20oYm9keSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCd1dGY4JykgOiBib2R5O1xuXG4gIHRyeSB7XG4gICAgaWYgKChjb250ZW50VHlwZSB8fCAnJykudG9Mb3dlckNhc2UoKSA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpIHtcbiAgICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMobmV3IFVSTFNlYXJjaFBhcmFtcyhjb250ZW50KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgdG8gcGFyc2luZyBhcyBKU09OOlxuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoY29udGVudCk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcihgRXJyb3IgcGFyc2luZyByZXF1ZXN0IGJvZHk6ICR7ZX1gKTtcbiAgfVxuXG4gIC8vIEZhbGxiYWNrIHRvIHJldHVybmluZyB0aGUgcmF3IGJvZHlcbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBjb29raWUsIGlmIGFueSwgcmV0dXJuaW5nIGF0IG1pbmltdW0gYW4gZW1wdHkgb2JqZWN0LlxuICogQHBhcmFtIGhlYWRlcnMgQVBJR2F0ZXdheVByb3h5RXZlbnQuaGVhZGVyc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDb29raWUoaGVhZGVyczogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkOyB9KTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9IHtcbiAgY29uc3QgaGVhZGVyID0gZ2V0SGVhZGVyKCdDb29raWUnLCBoZWFkZXJzKTtcbiAgY29uc3QgdmFsdWVzID0gaGVhZGVyID8gY29va2llLnBhcnNlKGhlYWRlcikgOiB7fTtcblxuICAvLyBFbnN1cmUgd2UgZG9uJ3QgcmV0dXJuIGFueSB1bmRlZmluZWQgdmFsdWVzXG4gIGNvbnN0IHJlc3VsdDogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge307XG4gIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZXMpKSB7XG4gICAgaWYgKHZhbHVlKSByZXN1bHRbbmFtZV0gPSB2YWx1ZTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDb29raWUoXG4gIHJlc3BvbnNlOiBSZXNwb25zZSxcbiAgbWF4QWdlOiBudW1iZXIgfCB1bmRlZmluZWQgPSA2MCAqIDYwICogMjQgKiAzNjUsXG4gIGV4cGlyZXM6IERhdGUgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gIHNlY3VyZTogYm9vbGVhbiA9IHRydWUsXG4gIGh0dHBPbmx5OiBib29sZWFuID0gdHJ1ZSxcbiAgc2FtZVNpdGU6ICdzdHJpY3QnIHwgJ2xheCcgfCAnbm9uZScgPSAnbGF4Jyxcbik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFyZXNwb25zZS5jb29raWVzKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGNvb2tpZXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge307XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlLmNvb2tpZXMpKSB7XG4gICAgY29va2llc1trZXldID0gdmFsdWU7XG4gIH1cblxuICBjb25zdCBoZWFkZXI6IHN0cmluZ1tdID0gW107XG5cbiAgT2JqZWN0LmtleXMoY29va2llcykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBjb29raWVzW2tleV07XG4gICAgaWYgKHZhbHVlID09PSAnJykge1xuICAgICAgLy8gSWYgZXhwbGljaXRseSB1bnNldCwgZXhwaXJlIHRoZSBjb29raWUgdmFsdWVcbiAgICAgIGhlYWRlci5wdXNoKGNvb2tpZS5zZXJpYWxpemUoa2V5LCAnJywge1xuICAgICAgICBleHBpcmVzOiBuZXcgRGF0ZSgpLCBzZWN1cmUsIGh0dHBPbmx5LCBzYW1lU2l0ZSxcbiAgICAgIH0pKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlKSB7XG4gICAgICAvLyBPdGhlcndpc2UsIHNldCBpdCBvbmx5IGlmIGEgdmFsdWUgd2FzIGdpdmVuXG4gICAgICBoZWFkZXIucHVzaChjb29raWUuc2VyaWFsaXplKGtleSwgdmFsdWUsIHtcbiAgICAgICAgbWF4QWdlLCBleHBpcmVzLCBzZWN1cmUsIGh0dHBPbmx5LCBzYW1lU2l0ZSxcbiAgICAgIH0pKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBoZWFkZXI7XG59XG5cbi8qKlxuICogQ2FzZS1pbnNlbnNpdGl2ZSBoZWFkZXIgbG9va3VwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRIZWFkZXIobmFtZTogc3RyaW5nLCBoZWFkZXJzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZDsgfSB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghaGVhZGVycykgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAvLyBFeGFjdCBtYXRjaFxuICBpZiAoaGVhZGVyc1tuYW1lXSkgcmV0dXJuIGhlYWRlcnNbbmFtZV07XG5cbiAgLy8gQ2FzZS1pbnNlbnNpdGl2ZSBtYXRjaFxuICBjb25zdCBsb3dlcmNhc2VkOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZDsgfSA9IHt9O1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhoZWFkZXJzKSkge1xuICAgIGxvd2VyY2FzZWRba2V5LnRvTG93ZXJDYXNlKCldID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGxvd2VyY2FzZWRbbmFtZS50b0xvd2VyQ2FzZSgpXTtcbn1cblxuLyoqXG4gKiBDYXNlLWluc2Vuc2l0aXZlIGhlYWRlciBzZXR0aW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRIZWFkZXIobmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBoZWFkZXJzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZDsgfSB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBpZiAoIWhlYWRlcnMpIHJldHVybjtcbiAgbGV0IHNldCA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgIGlmIChuYW1lLnRvTG93ZXJDYXNlKCkgPT09IGtleS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBoZWFkZXJzW2tleV0gPSB2YWx1ZTtcbiAgICAgIHNldCA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmICghc2V0KSBoZWFkZXJzW25hbWVdID0gdmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVJlcXVlc3QoZXZlbnQ6IEFQSUdhdGV3YXlQcm94eUV2ZW50KTogUmVxdWVzdCB7XG4gIHJldHVybiB7XG4gICAgbWV0aG9kOiBldmVudC5odHRwTWV0aG9kLFxuICAgIHBhdGg6IHN0YW5kYXJkUGF0aChldmVudC5wYXRoKSxcbiAgICBxdWVyeTogc3RhbmRhcmRRdWVyeVBhcmFtZXRlcnMoZXZlbnQucXVlcnlTdHJpbmdQYXJhbWV0ZXJzKSxcbiAgICBoZWFkZXJzOiBzdGFuZGFyZEhlYWRlcnMoZXZlbnQuaGVhZGVycyksXG4gICAgYm9keTogcGFyc2VCb2R5KGV2ZW50LmJvZHksIGV2ZW50LmlzQmFzZTY0RW5jb2RlZCwgZ2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCBldmVudC5oZWFkZXJzKSksXG4gICAgY29va2llczogcGFyc2VDb29raWUoZXZlbnQuaGVhZGVycyksXG4gICAgcGF0aFBhcmFtZXRlcnM6IHt9LCAvLyBUaGVzZSBuZWVkIHRvIGJlIHBhcnNlZCBhcyBwYXJ0IG9mIHJvdXRlIG1hdGNoaW5nXG4gICAgY29udGV4dDogeyBldmVudCB9LCAvLyBZb3UgY2FuIGFkZCBhbnkgY3VzdG9tIHZhbHVlcyB5b3UgbmVlZCB0byB0aGUgcmVxdWVzdCB2aWEgdGhpcyBjb250ZXh0XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaFJvdXRlKHJvdXRlczogUm91dGVzLCBwYXRoOiBzdHJpbmcpOiB7IG1ldGhvZHM6IFJvdXRlIHwgdW5kZWZpbmVkLCBwYXJhbXM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfTsgfSB7XG4gIC8vIERpcmVjdCBtYXRjaFxuICBpZiAocm91dGVzW3BhdGhdKSByZXR1cm4geyBtZXRob2RzOiByb3V0ZXNbcGF0aF0sIHBhcmFtczoge30gfTtcblxuICAvLyBMaXN0IHBhdGhzIHRvIGNoZWNrXG4gIGNvbnN0IHBhdGhzID0gT2JqZWN0LmtleXMocm91dGVzKTtcblxuICAvLyBDYXNlLWluc2Vuc2l0aXZlIG1hdGNoXG4gIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIHBhdGhzKSB7XG4gICAgaWYgKGNhbmRpZGF0ZS50b0xvd2VyQ2FzZSgpID09PSBwYXRoLnRvTG93ZXJDYXNlKCkpIHJldHVybiB7IG1ldGhvZHM6IHJvdXRlc1tjYW5kaWRhdGVdLCBwYXJhbXM6IHt9IH07XG4gIH1cblxuICAvLyBQYXRoLXBhcmFtZXRlciBtYXRjaGluZ1xuICBjb25zdCBwYXRoU2VnbWVudHMgPSBwYXRoLnNwbGl0KCcvJyk7XG5cbiAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2YgcGF0aHMpIHtcbiAgICBjb25zdCBjYW5kaWRhdGVTZWdtZW50cyA9IGNhbmRpZGF0ZS5zcGxpdCgnLycpO1xuXG4gICAgLy8gRmlyc3QgY2hlY2s6IGxlbmd0aCBtYXRjaFxuICAgIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoICE9PSBjYW5kaWRhdGVTZWdtZW50cy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgZm9yIChsZXQgcyA9IDA7IHMgPCBwYXRoU2VnbWVudHMubGVuZ3RoOyBzKyspIHtcbiAgICAgIGNvbnN0IHBhcmFtczogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge307XG4gICAgICBjb25zdCBwYXRoU2VnbWVudCA9IHBhdGhTZWdtZW50c1tzXSA/PyAnJztcbiAgICAgIGNvbnN0IGNhbmRpZGF0ZVNlZ21lbnQgPSBjYW5kaWRhdGVTZWdtZW50c1tzXSA/PyAnJztcbiAgICAgIGlmIChjYW5kaWRhdGVTZWdtZW50LnN0YXJ0c1dpdGgoJ3snKSAmJiBjYW5kaWRhdGVTZWdtZW50LmVuZHNXaXRoKCd9JykpIHtcbiAgICAgICAgLy8gUGF0aCBwYXJhbWV0ZXJcbiAgICAgICAgY29uc3QgbmFtZSA9IGNhbmRpZGF0ZVNlZ21lbnQuc2xpY2UoMSwgLTEpO1xuICAgICAgICBwYXJhbXNbbmFtZV0gPSBwYXRoU2VnbWVudDtcbiAgICAgIH0gZWxzZSBpZiAocGF0aFNlZ21lbnQudG9Mb3dlckNhc2UoKSAhPT0gY2FuZGlkYXRlU2VnbWVudC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAocyA9PT0gcGF0aFNlZ21lbnRzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgLy8gTWF0Y2hlZCBhbGwgc2VnbWVudHNcbiAgICAgICAgcmV0dXJuIHsgbWV0aG9kczogcm91dGVzW2NhbmRpZGF0ZV0sIHBhcmFtcyB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IG1ldGhvZHM6IHVuZGVmaW5lZCwgcGFyYW1zOiB7fSB9O1xufVxuIl19
package/dist/index.js CHANGED
@@ -18,16 +18,26 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
18
18
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
19
19
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
20
20
  };
21
- var __importStar = (this && this.__importStar) || function (mod) {
22
- if (mod && mod.__esModule) return mod;
23
- var result = {};
24
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
25
- __setModuleDefault(result, mod);
26
- return result;
27
- };
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
28
38
  Object.defineProperty(exports, "__esModule", { value: true });
29
39
  exports.types = exports.helpers = void 0;
30
40
  __exportStar(require("./handler"), exports);
31
41
  exports.helpers = __importStar(require("./helpers"));
32
42
  exports.types = __importStar(require("./types"));
33
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw0Q0FBMEI7QUFDMUIscURBQXFDO0FBQ3JDLGlEQUFpQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vaGFuZGxlcic7XG5leHBvcnQgKiBhcyBoZWxwZXJzIGZyb20gJy4vaGVscGVycyc7XG5leHBvcnQgKiBhcyB0eXBlcyBmcm9tICcuL3R5cGVzJztcbiJdfQ==
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNENBQTBCO0FBQzFCLHFEQUFxQztBQUNyQyxpREFBaUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2hhbmRsZXInO1xuZXhwb3J0ICogYXMgaGVscGVycyBmcm9tICcuL2hlbHBlcnMnO1xuZXhwb3J0ICogYXMgdHlwZXMgZnJvbSAnLi90eXBlcyc7XG4iXX0=
package/dist/types.d.ts CHANGED
@@ -1,50 +1,55 @@
1
- /**
2
- * Simplified representation of the HTTP Request.
3
- * The implementation guarantees that you'll always have non-null objects for query, headers, cookies, and body.
4
- * The method will be the HTTP method from the API Gateway proxt event.
5
- * The path will be the path from the API Gateway proxy event, which starts with '/'.
6
- */
7
- export interface Request {
1
+ import { APIGatewayProxyEvent } from "aws-lambda";
2
+ import z from "zod";
3
+ export interface Request<B = any> {
8
4
  method: string;
9
5
  path: string;
10
- query: {
11
- [name: string]: string;
12
- };
13
- headers: {
14
- [name: string]: string;
15
- };
16
- cookies: {
17
- [name: string]: string;
18
- };
19
- /** Path parameters will be parsed from the route definitions you pass to apiHandler() */
20
- pathParameters: {
21
- [name: string]: string;
22
- };
23
- body: any;
24
- /** You can add any custom values you need to the request via this context */
6
+ query: Record<string, string>;
7
+ headers: Record<string, string>;
8
+ cookies: Record<string, string>;
9
+ pathParameters: Record<string, string>;
10
+ body: B;
25
11
  context: {
12
+ event: APIGatewayProxyEvent;
26
13
  [key: string]: any;
27
14
  };
28
15
  }
29
- export interface Response {
30
- statusCode: number;
31
- headers?: {
32
- [name: string]: string;
16
+ export interface Response<B = any> {
17
+ statusCode?: number;
18
+ headers?: Record<string, string>;
19
+ cookies?: Record<string, string>;
20
+ body?: B;
21
+ }
22
+ type AnySchema = z.ZodType<any, any, any>;
23
+ export interface Handler<SReq extends AnySchema = AnySchema, SRes extends AnySchema = AnySchema> {
24
+ request?: {
25
+ body?: SReq;
26
+ headers?: z.ZodObject<any>;
27
+ cookies?: z.ZodObject<any>;
28
+ pathParameters?: z.ZodObject<any>;
29
+ query?: z.ZodObject<any>;
33
30
  };
34
- cookies?: {
35
- [name: string]: string;
31
+ response?: {
32
+ body?: SRes;
33
+ headers?: z.ZodObject<any>;
34
+ cookies?: z.ZodObject<any>;
36
35
  };
37
- body?: object | string;
36
+ handler: (request: Request<z.infer<SReq>>) => Promise<Response<z.infer<SRes>>>;
38
37
  }
39
- export type Handler = (request: Request) => Promise<Response>;
40
38
  export interface Route {
41
39
  GET?: Handler;
42
40
  POST?: Handler;
43
41
  PUT?: Handler;
44
42
  DELETE?: Handler;
43
+ PATCH?: Handler;
45
44
  OPTIONS?: Handler;
45
+ HEAD?: Handler;
46
46
  }
47
47
  export interface Routes {
48
48
  [path: string]: Route;
49
49
  }
50
- export type ContextBuilder = (request: Request) => Promise<void>;
50
+ export declare class ApiError extends Error {
51
+ statusCode: number;
52
+ body: unknown;
53
+ constructor(statusCode: number, body: unknown);
54
+ }
55
+ export {};
package/dist/types.js CHANGED
@@ -1,3 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2ltcGxpZmllZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgSFRUUCBSZXF1ZXN0LlxuICogVGhlIGltcGxlbWVudGF0aW9uIGd1YXJhbnRlZXMgdGhhdCB5b3UnbGwgYWx3YXlzIGhhdmUgbm9uLW51bGwgb2JqZWN0cyBmb3IgcXVlcnksIGhlYWRlcnMsIGNvb2tpZXMsIGFuZCBib2R5LlxuICogVGhlIG1ldGhvZCB3aWxsIGJlIHRoZSBIVFRQIG1ldGhvZCBmcm9tIHRoZSBBUEkgR2F0ZXdheSBwcm94dCBldmVudC5cbiAqIFRoZSBwYXRoIHdpbGwgYmUgdGhlIHBhdGggZnJvbSB0aGUgQVBJIEdhdGV3YXkgcHJveHkgZXZlbnQsIHdoaWNoIHN0YXJ0cyB3aXRoICcvJy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXF1ZXN0IHtcbiAgbWV0aG9kOiBzdHJpbmcsXG4gIHBhdGg6IHN0cmluZyxcbiAgcXVlcnk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfSxcbiAgaGVhZGVyczogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9LFxuICBjb29raWVzOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0sXG4gIC8qKiBQYXRoIHBhcmFtZXRlcnMgd2lsbCBiZSBwYXJzZWQgZnJvbSB0aGUgcm91dGUgZGVmaW5pdGlvbnMgeW91IHBhc3MgdG8gYXBpSGFuZGxlcigpICovXG4gIHBhdGhQYXJhbWV0ZXJzOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0sXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIGJvZHk6IGFueSxcbiAgLyoqIFlvdSBjYW4gYWRkIGFueSBjdXN0b20gdmFsdWVzIHlvdSBuZWVkIHRvIHRoZSByZXF1ZXN0IHZpYSB0aGlzIGNvbnRleHQgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgY29udGV4dDogeyBba2V5OiBzdHJpbmddOiBhbnk7IH0sXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzcG9uc2Uge1xuICBzdGF0dXNDb2RlOiBudW1iZXIsXG4gIGhlYWRlcnM/OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0sXG4gIGNvb2tpZXM/OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0sXG4gIGJvZHk/OiBvYmplY3QgfCBzdHJpbmcsXG59XG5cbmV4cG9ydCB0eXBlIEhhbmRsZXIgPSAocmVxdWVzdDogUmVxdWVzdCkgPT4gUHJvbWlzZTxSZXNwb25zZT47XG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlIHtcbiAgR0VUPzogSGFuZGxlcixcbiAgUE9TVD86IEhhbmRsZXIsXG4gIFBVVD86IEhhbmRsZXIsXG4gIERFTEVURT86IEhhbmRsZXIsXG4gIE9QVElPTlM/OiBIYW5kbGVyLFxufVxuZXhwb3J0IGludGVyZmFjZSBSb3V0ZXMgeyBbcGF0aDogc3RyaW5nXTogUm91dGU7IH1cblxuXG5leHBvcnQgdHlwZSBDb250ZXh0QnVpbGRlciA9IChyZXF1ZXN0OiBSZXF1ZXN0KSA9PiBQcm9taXNlPHZvaWQ+OyJdfQ==
3
+ exports.ApiError = void 0;
4
+ class ApiError extends Error {
5
+ statusCode;
6
+ body;
7
+ constructor(statusCode, body) {
8
+ super(typeof body === 'string' ? body : JSON.stringify(body, null, 2));
9
+ this.statusCode = statusCode;
10
+ this.body = body;
11
+ // Required for instanceof to work properly
12
+ Object.setPrototypeOf(this, ApiError.prototype);
13
+ }
14
+ }
15
+ exports.ApiError = ApiError;
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBd0RBLE1BQWEsUUFBUyxTQUFRLEtBQUs7SUFDakMsVUFBVSxDQUFTO0lBQ25CLElBQUksQ0FBVTtJQUVkLFlBQVksVUFBa0IsRUFBRSxJQUFhO1FBQzNDLEtBQUssQ0FBQyxPQUFPLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFFakIsMkNBQTJDO1FBQzNDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNsRCxDQUFDO0NBQ0Y7QUFaRCw0QkFZQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IEFQSUdhdGV3YXlQcm94eUV2ZW50IH0gZnJvbSBcImF3cy1sYW1iZGFcIjtcbmltcG9ydCB6IGZyb20gXCJ6b2RcIjtcblxuZXhwb3J0IGludGVyZmFjZSBSZXF1ZXN0PEIgPSBhbnk+IHtcbiAgbWV0aG9kOiBzdHJpbmcsXG4gIHBhdGg6IHN0cmluZyxcbiAgcXVlcnk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGNvb2tpZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIHBhdGhQYXJhbWV0ZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICBib2R5OiBCO1xuICBjb250ZXh0OiB7XG4gICAgZXZlbnQ6IEFQSUdhdGV3YXlQcm94eUV2ZW50O1xuICAgIFtrZXk6IHN0cmluZ106IGFueTtcbiAgfSxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXNwb25zZTxCID0gYW55PiB7XG4gIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICBjb29raWVzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgYm9keT86IEI7XG59XG5cbnR5cGUgQW55U2NoZW1hID0gei5ab2RUeXBlPGFueSwgYW55LCBhbnk+O1xuZXhwb3J0IGludGVyZmFjZSBIYW5kbGVyPFNSZXEgZXh0ZW5kcyBBbnlTY2hlbWEgPSBBbnlTY2hlbWEsIFNSZXMgZXh0ZW5kcyBBbnlTY2hlbWEgPSBBbnlTY2hlbWE+IHtcbiAgcmVxdWVzdD86IHtcbiAgICBib2R5PzogU1JlcTtcbiAgICBoZWFkZXJzPzogei5ab2RPYmplY3Q8YW55PjtcbiAgICBjb29raWVzPzogei5ab2RPYmplY3Q8YW55PjtcbiAgICBwYXRoUGFyYW1ldGVycz86IHouWm9kT2JqZWN0PGFueT47XG4gICAgcXVlcnk/OiB6LlpvZE9iamVjdDxhbnk+O1xuICB9O1xuICByZXNwb25zZT86IHtcbiAgICBib2R5PzogU1JlcztcbiAgICBoZWFkZXJzPzogei5ab2RPYmplY3Q8YW55PjtcbiAgICBjb29raWVzPzogei5ab2RPYmplY3Q8YW55PjtcbiAgfTtcbiAgaGFuZGxlcjogKHJlcXVlc3Q6IFJlcXVlc3Q8ei5pbmZlcjxTUmVxPj4pID0+IFByb21pc2U8UmVzcG9uc2U8ei5pbmZlcjxTUmVzPj4+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlIHtcbiAgR0VUPzogSGFuZGxlcjtcbiAgUE9TVD86IEhhbmRsZXI7XG4gIFBVVD86IEhhbmRsZXI7XG4gIERFTEVURT86IEhhbmRsZXI7XG4gIFBBVENIPzogSGFuZGxlcjtcbiAgT1BUSU9OUz86IEhhbmRsZXI7XG4gIEhFQUQ/OiBIYW5kbGVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlcyB7XG4gIFtwYXRoOiBzdHJpbmddOiBSb3V0ZTtcbn1cblxuZXhwb3J0IGNsYXNzIEFwaUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gIGJvZHk6IHVua25vd247XG5cbiAgY29uc3RydWN0b3Ioc3RhdHVzQ29kZTogbnVtYmVyLCBib2R5OiB1bmtub3duKSB7XG4gICAgc3VwZXIodHlwZW9mIGJvZHkgPT09ICdzdHJpbmcnID8gYm9keSA6IEpTT04uc3RyaW5naWZ5KGJvZHksIG51bGwsIDIpKTtcbiAgICB0aGlzLnN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlO1xuICAgIHRoaXMuYm9keSA9IGJvZHk7XG5cbiAgICAvLyBSZXF1aXJlZCBmb3IgaW5zdGFuY2VvZiB0byB3b3JrIHByb3Blcmx5XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEFwaUVycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cbiJdfQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scloud/lambda-api",
3
- "version": "0.3.7",
3
+ "version": "1.0.0",
4
4
  "description": "Lambda handler for API Gateway proxy requests",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -34,6 +34,7 @@
34
34
  "homepage": "https://github.com/davidcarboni/scloud#readme",
35
35
  "devDependencies": {
36
36
  "@eslint/js": "*",
37
+ "@tsconfig/node22": "*",
37
38
  "@types/chai": "*",
38
39
  "@types/cookie": "*",
39
40
  "@types/mocha": "*",
@@ -51,6 +52,7 @@
51
52
  },
52
53
  "dependencies": {
53
54
  "@types/aws-lambda": "*",
54
- "cookie": "*"
55
+ "cookie": "*",
56
+ "zod": "*"
55
57
  }
56
58
  }