@middy/http-router 6.1.6 → 6.2.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/index.d.ts +44 -43
- package/index.js +137 -133
- package/package.json +69 -72
package/index.d.ts
CHANGED
|
@@ -1,53 +1,54 @@
|
|
|
1
|
-
import middy
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import type middy from "@middy/core";
|
|
2
|
+
import type { MiddyfiedHandler } from "@middy/core";
|
|
3
|
+
import type {
|
|
4
|
+
ALBEvent,
|
|
5
|
+
ALBResult,
|
|
6
|
+
APIGatewayProxyEvent,
|
|
7
|
+
APIGatewayProxyEventV2,
|
|
8
|
+
APIGatewayProxyResult,
|
|
9
|
+
APIGatewayProxyResultV2,
|
|
10
|
+
Handler as LambdaHandler,
|
|
11
|
+
} from "aws-lambda";
|
|
11
12
|
|
|
12
13
|
export type Method =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
| "GET"
|
|
15
|
+
| "POST"
|
|
16
|
+
| "PUT"
|
|
17
|
+
| "PATCH"
|
|
18
|
+
| "DELETE"
|
|
19
|
+
| "OPTIONS"
|
|
20
|
+
| "HEAD"
|
|
21
|
+
| "ANY";
|
|
21
22
|
|
|
22
23
|
export interface Route<TEvent, TResult> {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
method: Method;
|
|
25
|
+
path: string;
|
|
26
|
+
handler:
|
|
27
|
+
| LambdaHandler<TEvent, TResult>
|
|
28
|
+
| MiddyfiedHandler<TEvent, TResult, any, any>;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export type RouteNotFoundResponseFn = (input: {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}) => never
|
|
32
|
+
method: string;
|
|
33
|
+
path: string;
|
|
34
|
+
}) => never;
|
|
34
35
|
|
|
35
36
|
declare function httpRouterHandler<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
): middy.MiddyfiedHandler<TEvent, TResult
|
|
37
|
+
TEvent extends
|
|
38
|
+
| ALBEvent
|
|
39
|
+
| APIGatewayProxyEvent
|
|
40
|
+
| APIGatewayProxyEventV2 = APIGatewayProxyEvent,
|
|
41
|
+
TResult extends
|
|
42
|
+
| ALBResult
|
|
43
|
+
| APIGatewayProxyResult
|
|
44
|
+
| APIGatewayProxyResultV2 = APIGatewayProxyResult,
|
|
45
|
+
>(
|
|
46
|
+
routes:
|
|
47
|
+
| Array<Route<TEvent, TResult>>
|
|
48
|
+
| {
|
|
49
|
+
routes: Array<Route<TEvent, TResult>>;
|
|
50
|
+
notFoundResponse: RouteNotFoundResponseFn;
|
|
51
|
+
},
|
|
52
|
+
): middy.MiddyfiedHandler<TEvent, TResult>;
|
|
52
53
|
|
|
53
|
-
export default httpRouterHandler
|
|
54
|
+
export default httpRouterHandler;
|
package/index.js
CHANGED
|
@@ -1,144 +1,148 @@
|
|
|
1
|
-
import { createError } from
|
|
1
|
+
import { createError } from "@middy/util";
|
|
2
2
|
|
|
3
3
|
const defaults = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
4
|
+
routes: [],
|
|
5
|
+
notFoundResponse: ({ method, path }) => {
|
|
6
|
+
const err = createError(404, "Route does not exist", {
|
|
7
|
+
cause: { package: "@middy/http-router", data: { method, path } },
|
|
8
|
+
});
|
|
9
|
+
throw err;
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
12
|
const httpRouteHandler = (opts = {}) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
13
|
+
let options;
|
|
14
|
+
if (Array.isArray(opts)) {
|
|
15
|
+
options = { routes: opts };
|
|
16
|
+
}
|
|
17
|
+
options ??= opts;
|
|
18
|
+
const { routes, notFoundResponse } = { ...defaults, ...options };
|
|
19
|
+
|
|
20
|
+
const routesStatic = {};
|
|
21
|
+
const routesDynamic = {};
|
|
22
|
+
const enumMethods = methods.concat("ANY");
|
|
23
|
+
for (const route of routes) {
|
|
24
|
+
let { method, path, handler } = route;
|
|
25
|
+
|
|
26
|
+
// Prevents `routesType[method][path] = handler` from flagging: This assignment may alter Object.prototype if a malicious '__proto__' string is injected from library input.
|
|
27
|
+
if (!enumMethods.includes(method)) {
|
|
28
|
+
throw new Error("Method not allowed", {
|
|
29
|
+
cause: { package: "@middy/http-router", data: { method } },
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// remove trailing slash, but not if it's the first one
|
|
34
|
+
if (path.endsWith("/") && path !== "/") {
|
|
35
|
+
path = path.substr(0, path.length - 1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Static
|
|
39
|
+
if (path.indexOf("{") < 0) {
|
|
40
|
+
attachStaticRoute(method, path, handler, routesStatic);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Dynamic
|
|
45
|
+
attachDynamicRoute(method, path, handler, routesDynamic);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return (event, context, abort) => {
|
|
49
|
+
const { method, path } = getVersionRoute[pickVersion(event)](event);
|
|
50
|
+
|
|
51
|
+
if (!method) {
|
|
52
|
+
throw new Error("Unknown http event format", {
|
|
53
|
+
cause: { package: "@middy/http-router", data: { method } },
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (!path) {
|
|
57
|
+
throw new Error("Unknown http event format", {
|
|
58
|
+
cause: { package: "@middy/http-router", data: { path } },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Static
|
|
63
|
+
if (
|
|
64
|
+
Object.hasOwnProperty.call(routesStatic, method) &&
|
|
65
|
+
Object.hasOwnProperty.call(routesStatic[method], path)
|
|
66
|
+
) {
|
|
67
|
+
const handler = routesStatic[method][path];
|
|
68
|
+
return handler(event, context, abort);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Dynamic
|
|
72
|
+
if (Object.hasOwnProperty.call(routesDynamic, method)) {
|
|
73
|
+
for (const route of routesDynamic[method] ?? []) {
|
|
74
|
+
const match = path.match(route.path);
|
|
75
|
+
if (match) {
|
|
76
|
+
event.pathParameters = {
|
|
77
|
+
...match.groups,
|
|
78
|
+
...event.pathParameters,
|
|
79
|
+
};
|
|
80
|
+
return route.handler(event, context, abort);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Not Found
|
|
86
|
+
return notFoundResponse({ method, path });
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const regexpDynamicWildcards = /\/\{(proxy)\+\}$/;
|
|
91
|
+
const regexpDynamicParameters = /\/\{([^/]+)\}/g;
|
|
92
|
+
|
|
93
|
+
const methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]; // ANY excluded by design
|
|
92
94
|
|
|
93
95
|
const attachStaticRoute = (method, path, handler, routesType) => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
96
|
+
if (method === "ANY") {
|
|
97
|
+
for (const method of methods) {
|
|
98
|
+
attachStaticRoute(method, path, handler, routesType);
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (!routesType[method]) {
|
|
103
|
+
routesType[method] = {};
|
|
104
|
+
}
|
|
105
|
+
routesType[method][path] = handler;
|
|
106
|
+
routesType[method][`${path}/`] = handler; // Optional `/`
|
|
107
|
+
};
|
|
106
108
|
|
|
107
109
|
const attachDynamicRoute = (method, path, handler, routesType) => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
110
|
+
if (method === "ANY") {
|
|
111
|
+
for (const method of methods) {
|
|
112
|
+
attachDynamicRoute(method, path, handler, routesType);
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (!routesType[method]) {
|
|
117
|
+
routesType[method] = [];
|
|
118
|
+
}
|
|
119
|
+
const pathPartialRegExp = path
|
|
120
|
+
.replace(regexpDynamicWildcards, "/?(?<$1>.*)")
|
|
121
|
+
.replace(regexpDynamicParameters, "/(?<$1>[^/]+)");
|
|
122
|
+
// SAST Skipped: Not accessible by users
|
|
123
|
+
// nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp
|
|
124
|
+
const pathRegExp = new RegExp(`^${pathPartialRegExp}/?$`); // Adds in optional `/`
|
|
125
|
+
routesType[method].push({ path: pathRegExp, handler });
|
|
126
|
+
};
|
|
123
127
|
|
|
124
128
|
const pickVersion = (event) => {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
129
|
+
// '1.0' is a safer default
|
|
130
|
+
return event.version ?? (event.method ? "vpc" : "1.0");
|
|
131
|
+
};
|
|
128
132
|
|
|
129
133
|
const getVersionRoute = {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export default httpRouteHandler
|
|
134
|
+
"1.0": (event) => ({
|
|
135
|
+
method: event.httpMethod,
|
|
136
|
+
path: event.path,
|
|
137
|
+
}),
|
|
138
|
+
"2.0": (event) => ({
|
|
139
|
+
method: event.requestContext.http.method,
|
|
140
|
+
path: event.requestContext.http.path,
|
|
141
|
+
}),
|
|
142
|
+
vpc: (event) => ({
|
|
143
|
+
method: event.method,
|
|
144
|
+
path: event.raw_path.split("?")[0],
|
|
145
|
+
}),
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export default httpRouteHandler;
|
package/package.json
CHANGED
|
@@ -1,74 +1,71 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"@types/aws-lambda": "^8.10.97"
|
|
72
|
-
},
|
|
73
|
-
"gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431"
|
|
2
|
+
"name": "@middy/http-router",
|
|
3
|
+
"version": "6.2.0",
|
|
4
|
+
"description": "HTTP event router for the middy framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=20"
|
|
8
|
+
},
|
|
9
|
+
"engineStrict": true,
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"module": "./index.js",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": {
|
|
17
|
+
"types": "./index.d.ts",
|
|
18
|
+
"default": "./index.js"
|
|
19
|
+
},
|
|
20
|
+
"require": {
|
|
21
|
+
"default": "./index.js"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"types": "index.d.ts",
|
|
26
|
+
"files": ["index.js", "index.d.ts"],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"test": "npm run test:unit && npm run test:fuzz",
|
|
29
|
+
"test:unit": "node --test",
|
|
30
|
+
"test:fuzz": "node --test index.fuzz.js",
|
|
31
|
+
"test:perf": "node --test index.perf.js"
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"keywords": [
|
|
35
|
+
"Lambda",
|
|
36
|
+
"Middleware",
|
|
37
|
+
"Serverless",
|
|
38
|
+
"Framework",
|
|
39
|
+
"AWS",
|
|
40
|
+
"AWS Lambda",
|
|
41
|
+
"Middy",
|
|
42
|
+
"HTTP",
|
|
43
|
+
"API",
|
|
44
|
+
"router"
|
|
45
|
+
],
|
|
46
|
+
"author": {
|
|
47
|
+
"name": "Middy contributors",
|
|
48
|
+
"url": "https://github.com/middyjs/middy/graphs/contributors"
|
|
49
|
+
},
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/middyjs/middy.git",
|
|
53
|
+
"directory": "packages/http-router"
|
|
54
|
+
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/middyjs/middy/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://middy.js.org",
|
|
59
|
+
"funding": {
|
|
60
|
+
"type": "github",
|
|
61
|
+
"url": "https://github.com/sponsors/willfarrell"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@middy/util": "6.2.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@middy/core": "6.2.0",
|
|
68
|
+
"@types/aws-lambda": "^8.10.97"
|
|
69
|
+
},
|
|
70
|
+
"gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431"
|
|
74
71
|
}
|