hono-adapter-aws-lambda 1.3.4 → 1.4.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 +0 -2
- package/dist/index.d.mts +75 -34
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +360 -367
- package/dist/index.mjs.map +1 -0
- package/package.json +29 -26
package/README.md
CHANGED
|
@@ -58,8 +58,6 @@ See some more examples in the test file: [test/index.test.ts](test/index.test.ts
|
|
|
58
58
|
[npm-downloads-href]: https://npmjs.com/package/hono-adapter-aws-lambda
|
|
59
59
|
[codecov-src]: https://img.shields.io/codecov/c/gh/namesmt/hono-adapter-aws-lambda/main?labelColor=18181B&color=F0DB4F
|
|
60
60
|
[codecov-href]: https://codecov.io/gh/namesmt/hono-adapter-aws-lambda
|
|
61
|
-
[license-src]: https://img.shields.io/github/license/namesmt/hono-adapter-aws-lambda.svg?labelColor=18181B&color=F0DB4F
|
|
62
|
-
[license-href]: https://github.com/namesmt/hono-adapter-aws-lambda/blob/main/LICENSE
|
|
63
61
|
[bundlejs-src]: https://img.shields.io/bundlejs/size/hono-adapter-aws-lambda?labelColor=18181B&color=F0DB4F
|
|
64
62
|
[bundlejs-href]: https://bundlejs.com/?q=hono-adapter-aws-lambda
|
|
65
63
|
[jsDocs-src]: https://img.shields.io/badge/Check_out-jsDocs.io---?labelColor=18181B&color=F0DB4F
|
package/dist/index.d.mts
CHANGED
|
@@ -1,42 +1,83 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { Env, Hono, Schema } from "hono";
|
|
2
|
+
import { LambdaEvent, LambdaRequestEvent, LambdaTriggerEvent, LambdaTriggerEvent as LambdaTriggerEvent$1 } from "@namesmt/utils-lambda";
|
|
3
|
+
import { APIGatewayProxyResult, APIGatewayProxyStructuredResultV2, Context as LambdaContext, Handler } from "aws-lambda";
|
|
4
|
+
import { H } from "hono/types";
|
|
5
|
+
//#region src/types.d.ts
|
|
6
|
+
export type LambdaHandler<TEvent = any, TResult = any> = Handler<TEvent, TResult>;
|
|
7
|
+
export type LambdaHandlerResult = APIGatewayProxyResult | APIGatewayProxyStructuredResultV2;
|
|
8
|
+
/**
|
|
9
|
+
* Amazon VPC Lattice v2 event.
|
|
10
|
+
* Not yet available in `@types/aws-lambda`, so defined locally.
|
|
11
|
+
*/
|
|
12
|
+
export interface LatticeRequestContextV2 {
|
|
13
|
+
serviceNetworkArn: string;
|
|
14
|
+
serviceArn: string;
|
|
15
|
+
targetGroupArn: string;
|
|
16
|
+
region: string;
|
|
17
|
+
timeEpoch: string;
|
|
18
|
+
identity: {
|
|
19
|
+
sourceVpcArn?: string;
|
|
20
|
+
type?: string;
|
|
21
|
+
principal?: string;
|
|
22
|
+
principalOrgID?: string;
|
|
23
|
+
sessionName?: string;
|
|
24
|
+
x509IssuerOu?: string;
|
|
25
|
+
x509SanDns?: string;
|
|
26
|
+
x509SanNameCn?: string;
|
|
27
|
+
x509SanUri?: string;
|
|
28
|
+
x509SubjectCn?: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface LatticeProxyEventV2 {
|
|
32
|
+
version: string;
|
|
33
|
+
path: string;
|
|
34
|
+
method: string;
|
|
35
|
+
headers: Record<string, string[] | undefined>;
|
|
36
|
+
queryStringParameters: Record<string, string[] | undefined>;
|
|
37
|
+
body: string | null;
|
|
38
|
+
isBase64Encoded: boolean;
|
|
39
|
+
requestContext: LatticeRequestContextV2;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* All events the adapter handles: request, trigger, and VPC Lattice.
|
|
43
|
+
*/
|
|
44
|
+
export type AdapterEvent = LambdaEvent | LatticeProxyEventV2;
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/handler.d.ts
|
|
12
47
|
interface HandleConfigOptions {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
48
|
+
/**
|
|
49
|
+
* This allows you to easier invoke HTTP routes manually by parsing `event.routeKey` for method and path.
|
|
50
|
+
*/
|
|
51
|
+
easyRouteKey?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Overrides the default binary content-type detection.
|
|
54
|
+
* Defaults to `defaultIsContentTypeBinary`.
|
|
55
|
+
*/
|
|
56
|
+
isContentTypeBinary?: (contentType: string) => boolean;
|
|
17
57
|
}
|
|
18
|
-
declare function streamHandle<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'>(app: Hono<E, S, BasePath>, handleConfig?: HandleConfigOptions): LambdaHandler<
|
|
58
|
+
export declare function streamHandle<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'>(app: Hono<E, S, BasePath>, handleConfig?: HandleConfigOptions): LambdaHandler<AdapterEvent>;
|
|
19
59
|
/**
|
|
20
60
|
* Accepts events from API Gateway/ELB(`APIGatewayProxyEvent`) and directly through Function Url(`APIGatewayProxyEventV2`)
|
|
21
61
|
*/
|
|
22
|
-
declare function handle<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'>(app: Hono<E, S, BasePath>, handleConfig?: HandleConfigOptions): LambdaHandler<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
62
|
+
export declare function handle<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'>(app: Hono<E, S, BasePath>, handleConfig?: HandleConfigOptions): LambdaHandler<AdapterEvent, LambdaHandlerResult>;
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/trigger.d.ts
|
|
65
|
+
export declare class TriggerFactory<IE extends Env, HE extends Env> {
|
|
66
|
+
private simpleRouter;
|
|
67
|
+
honoApp: Hono<HE>;
|
|
68
|
+
internalApp: Hono<IE, import("hono/types").BlankSchema, "/">;
|
|
69
|
+
constructor(app: Hono<HE>);
|
|
70
|
+
on: (eventSource: string, id: string, ...handlers: H<IE>[]) => this;
|
|
30
71
|
}
|
|
31
72
|
type ExtractHonoEnv<A extends Hono> = A extends Hono<infer E> ? E : never;
|
|
32
|
-
declare function createTriggerFactory<E extends Env, A extends Hono<any, any, '/'>>(app: A): TriggerFactory<E extends unknown ? {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
73
|
+
export declare function createTriggerFactory<E extends Env, A extends Hono<any, any, '/'>>(app: A): TriggerFactory<E extends unknown ? {
|
|
74
|
+
Bindings: {
|
|
75
|
+
event: LambdaTriggerEvent$1;
|
|
76
|
+
};
|
|
77
|
+
Variables: Record<string, unknown>;
|
|
37
78
|
} : E, ExtractHonoEnv<A>>;
|
|
38
|
-
declare const triggerPathUUID: string;
|
|
39
|
-
declare function getTriggerPath(path: string): string;
|
|
40
|
-
|
|
41
|
-
export {
|
|
42
|
-
|
|
79
|
+
export declare const triggerPathUUID: string;
|
|
80
|
+
export declare function getTriggerPath(path: string): string;
|
|
81
|
+
//#endregion
|
|
82
|
+
export type { LambdaContext, LambdaEvent, LambdaRequestEvent, LambdaTriggerEvent };
|
|
83
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/handler.ts","../src/trigger.ts"],"mappings":";;;;;YAMY,cAAc,cAAc,iBAAiB,QAAQ,QAAQ;YAC7D,sBAAsB,wBAAwB;;;;;iBAMzC;EACf;EACA;EACA;EACA;EACA;EACA;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;iBAIa;EACf;EACA;EACA;EACA,SAAS;EACT,uBAAuB;EACvB;EACA;EACA,gBAAgB;;;;;YAMN,eAAe,cAAc;;;UCGxB;;;;EAIf;;;;;EAKA,uBAAuB;;wBAGT,aACd,UAAU,MAAM,KAChB,UAAU,aACV,+BACA,KAAK,KAAK,GAAG,GAAG,WAAW,eAAe,sBAAsB,cAAc;;;;wBAmDhE,OAAO,UAAU,MAAM,KAAK,UAAU,aAAa,+BAA+B,KAAK,KAAK,GAAG,GAAG,WAAW,eAAe,sBAAsB,cAAc,cAAc;;;qBCvGjL,eAAe,WAAW,KAAK,WAAW;UAC7C;EAER,SAAS,KAAK;EACd,aAAW,KAAA,yBAAA;EAEC,YAAA,KAAK,KAAK;EAItB,KAAM,qBAAqB,eAAe,UAAU,EAAE;;KAyCnD,eAAe,UAAU,QAAQ,UAAU,WAAW,KAAK;wBAEhD,qBAAqB,UAAU,KAAK,UAAU,qBAAqB,KAAK,IAAC,eAAA;EAGvE;IAAE,OAAO;;EACR,WAAA;IAGlB,GAAA,eAAA;qBAoCY;wBAEG,eAAe"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,411 +1,404 @@
|
|
|
1
|
-
import { Readable } from
|
|
2
|
-
import { pipeline } from
|
|
3
|
-
import { decodeBase64, encodeBase64 } from
|
|
4
|
-
import { Hono } from
|
|
5
|
-
import { mergePath } from
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const path = this.getPath(event);
|
|
12
|
-
const urlPath = `https://${domainName}${path}`;
|
|
13
|
-
const url = queryString ? `${urlPath}?${queryString}` : urlPath;
|
|
14
|
-
const headers = this.getHeaders(event);
|
|
15
|
-
const method = this.getMethod(event);
|
|
16
|
-
const requestInit = {
|
|
17
|
-
headers,
|
|
18
|
-
method
|
|
19
|
-
};
|
|
20
|
-
if (event.body) {
|
|
21
|
-
requestInit.body = event.isBase64Encoded ? decodeBase64(event.body) : event.body;
|
|
22
|
-
}
|
|
23
|
-
return new Request(url, requestInit);
|
|
24
|
-
}
|
|
25
|
-
async createResult(event, res) {
|
|
26
|
-
const contentType = res.headers.get("content-type");
|
|
27
|
-
let isBase64Encoded = !!(contentType && isContentTypeBinary(contentType));
|
|
28
|
-
if (!isBase64Encoded) {
|
|
29
|
-
const contentEncoding = res.headers.get("content-encoding");
|
|
30
|
-
isBase64Encoded = isContentEncodingBinary(contentEncoding);
|
|
31
|
-
}
|
|
32
|
-
const body = isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text();
|
|
33
|
-
const result = {
|
|
34
|
-
body,
|
|
35
|
-
headers: {},
|
|
36
|
-
multiValueHeaders: void 0,
|
|
37
|
-
statusCode: res.status,
|
|
38
|
-
isBase64Encoded
|
|
39
|
-
};
|
|
40
|
-
if ("multiValueHeaders" in event) {
|
|
41
|
-
result.multiValueHeaders = {};
|
|
42
|
-
}
|
|
43
|
-
this.setCookies(event, res, result);
|
|
44
|
-
res.headers.forEach((value, key) => {
|
|
45
|
-
result.headers[key] = value;
|
|
46
|
-
if ("multiValueHeaders" in event) {
|
|
47
|
-
result.multiValueHeaders[key] = [value];
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
return result;
|
|
51
|
-
}
|
|
52
|
-
setCookies(event, res, result) {
|
|
53
|
-
if (res.headers.has("set-cookie")) {
|
|
54
|
-
const cookies = res.headers.getSetCookie ? res.headers.getSetCookie() : Array.from(res.headers.entries()).filter(([k]) => k === "set-cookie").map(([, v]) => v);
|
|
55
|
-
if (Array.isArray(cookies)) {
|
|
56
|
-
this.setCookiesToResult(event, result, cookies);
|
|
57
|
-
res.headers.delete("set-cookie");
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
class EventV2Processor extends RequestEventProcessor {
|
|
63
|
-
getPath(event) {
|
|
64
|
-
return event.rawPath;
|
|
65
|
-
}
|
|
66
|
-
getMethod(event) {
|
|
67
|
-
return event.requestContext.http.method;
|
|
68
|
-
}
|
|
69
|
-
getQueryString(event) {
|
|
70
|
-
return event.rawQueryString;
|
|
71
|
-
}
|
|
72
|
-
getCookies(event, headers) {
|
|
73
|
-
if (Array.isArray(event.cookies)) {
|
|
74
|
-
headers.set("Cookie", event.cookies.join("; "));
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
setCookiesToResult(_, result, cookies) {
|
|
78
|
-
result.cookies = cookies;
|
|
79
|
-
}
|
|
80
|
-
getHeaders(event) {
|
|
81
|
-
const headers = new Headers();
|
|
82
|
-
this.getCookies(event, headers);
|
|
83
|
-
if (event.headers) {
|
|
84
|
-
for (const [k, v] of Object.entries(event.headers)) {
|
|
85
|
-
if (v) {
|
|
86
|
-
headers.set(k, v);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return headers;
|
|
91
|
-
}
|
|
1
|
+
import { Readable } from "stream";
|
|
2
|
+
import { pipeline } from "stream/promises";
|
|
3
|
+
import { decodeBase64, encodeBase64 } from "hono/utils/encode";
|
|
4
|
+
import { Hono } from "hono";
|
|
5
|
+
import { mergePath } from "hono/utils/url";
|
|
6
|
+
//#region src/request.ts
|
|
7
|
+
const NON_ASCII_REGEX = /[^\x00-\x7F]/;
|
|
8
|
+
function sanitizeHeaderValue(value) {
|
|
9
|
+
if (!NON_ASCII_REGEX.test(value)) return value;
|
|
10
|
+
return encodeURIComponent(value);
|
|
92
11
|
}
|
|
12
|
+
var RequestEventProcessor = class {
|
|
13
|
+
createRequest(event) {
|
|
14
|
+
const queryString = this.getQueryString(event);
|
|
15
|
+
const urlPath = `https://${event.requestContext && "domainName" in event.requestContext ? event.requestContext.domainName : event.headers?.host ?? event.multiValueHeaders?.host?.[0]}${this.getPath(event)}`;
|
|
16
|
+
const url = queryString ? `${urlPath}?${queryString}` : urlPath;
|
|
17
|
+
const headers = this.getHeaders(event);
|
|
18
|
+
const requestInit = {
|
|
19
|
+
headers,
|
|
20
|
+
method: this.getMethod(event)
|
|
21
|
+
};
|
|
22
|
+
if (event.body) {
|
|
23
|
+
const body = event.isBase64Encoded ? decodeBase64(event.body) : new TextEncoder().encode(event.body);
|
|
24
|
+
requestInit.body = body;
|
|
25
|
+
headers.set("content-length", body.length.toString());
|
|
26
|
+
}
|
|
27
|
+
return new Request(url, requestInit);
|
|
28
|
+
}
|
|
29
|
+
async createResult(event, res, options) {
|
|
30
|
+
const contentType = res.headers.get("content-type");
|
|
31
|
+
const isContentTypeBinaryFn = options?.isContentTypeBinary ?? defaultIsContentTypeBinary;
|
|
32
|
+
let isBase64Encoded = !!(contentType && isContentTypeBinaryFn(contentType));
|
|
33
|
+
if (!isBase64Encoded) isBase64Encoded = isContentEncodingBinary(res.headers.get("content-encoding"));
|
|
34
|
+
const result = {
|
|
35
|
+
body: isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text(),
|
|
36
|
+
headers: {},
|
|
37
|
+
multiValueHeaders: void 0,
|
|
38
|
+
statusCode: res.status,
|
|
39
|
+
isBase64Encoded
|
|
40
|
+
};
|
|
41
|
+
if ("multiValueHeaders" in event) result.multiValueHeaders = {};
|
|
42
|
+
this.setCookies(event, res, result);
|
|
43
|
+
res.headers.forEach((value, key) => {
|
|
44
|
+
result.headers[key] = value;
|
|
45
|
+
if ("multiValueHeaders" in event) result.multiValueHeaders[key] = [value];
|
|
46
|
+
});
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
setCookies(event, res, result) {
|
|
50
|
+
if (res.headers.has("set-cookie")) {
|
|
51
|
+
const cookies = res.headers.getSetCookie ? res.headers.getSetCookie() : Array.from(res.headers.entries()).filter(([k]) => k === "set-cookie").map(([, v]) => v);
|
|
52
|
+
if (Array.isArray(cookies)) {
|
|
53
|
+
this.setCookiesToResult(event, result, cookies);
|
|
54
|
+
res.headers.delete("set-cookie");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var EventV2Processor = class extends RequestEventProcessor {
|
|
60
|
+
getPath(event) {
|
|
61
|
+
return event.rawPath;
|
|
62
|
+
}
|
|
63
|
+
getMethod(event) {
|
|
64
|
+
return event.requestContext.http.method;
|
|
65
|
+
}
|
|
66
|
+
getQueryString(event) {
|
|
67
|
+
return event.rawQueryString;
|
|
68
|
+
}
|
|
69
|
+
getCookies(event, headers) {
|
|
70
|
+
if (Array.isArray(event.cookies)) headers.set("Cookie", event.cookies.join("; "));
|
|
71
|
+
}
|
|
72
|
+
setCookiesToResult(_, result, cookies) {
|
|
73
|
+
result.cookies = cookies;
|
|
74
|
+
}
|
|
75
|
+
getHeaders(event) {
|
|
76
|
+
const headers = new Headers();
|
|
77
|
+
this.getCookies(event, headers);
|
|
78
|
+
if (event.headers) {
|
|
79
|
+
for (const [k, v] of Object.entries(event.headers)) if (v) headers.set(k, v);
|
|
80
|
+
}
|
|
81
|
+
return headers;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
93
84
|
const v2Processor = new EventV2Processor();
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return headers;
|
|
125
|
-
}
|
|
126
|
-
setCookiesToResult(_, result, cookies) {
|
|
127
|
-
result.multiValueHeaders = {
|
|
128
|
-
"set-cookie": cookies
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
}
|
|
85
|
+
var EventV1Processor = class extends RequestEventProcessor {
|
|
86
|
+
getPath(event) {
|
|
87
|
+
return event.path;
|
|
88
|
+
}
|
|
89
|
+
getMethod(event) {
|
|
90
|
+
return event.httpMethod;
|
|
91
|
+
}
|
|
92
|
+
getQueryString(event) {
|
|
93
|
+
if (event.multiValueQueryStringParameters) return Object.entries(event.multiValueQueryStringParameters || {}).filter(([, value]) => value).map(([key, values]) => values.map((value) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&")).join("&");
|
|
94
|
+
else return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value || "")}`).join("&");
|
|
95
|
+
}
|
|
96
|
+
getCookies(event, headers) {}
|
|
97
|
+
getHeaders(event) {
|
|
98
|
+
const headers = new Headers();
|
|
99
|
+
this.getCookies(event, headers);
|
|
100
|
+
if (event.multiValueHeaders) {
|
|
101
|
+
for (const [k, values] of Object.entries(event.multiValueHeaders)) if (values) values.forEach((v) => headers.append(k, sanitizeHeaderValue(v)));
|
|
102
|
+
}
|
|
103
|
+
if (event.headers) {
|
|
104
|
+
for (const [k, v] of Object.entries(event.headers)) if (v && !headers.has(k)) headers.set(k, sanitizeHeaderValue(v));
|
|
105
|
+
}
|
|
106
|
+
return headers;
|
|
107
|
+
}
|
|
108
|
+
setCookiesToResult(_, result, cookies) {
|
|
109
|
+
result.multiValueHeaders = { "set-cookie": cookies };
|
|
110
|
+
}
|
|
111
|
+
};
|
|
132
112
|
const v1Processor = new EventV1Processor();
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
getCookies(event, headers) {
|
|
165
|
-
let cookie;
|
|
166
|
-
if (event.multiValueHeaders) {
|
|
167
|
-
cookie = event.multiValueHeaders.cookie?.join("; ");
|
|
168
|
-
} else {
|
|
169
|
-
cookie = event.headers ? event.headers.cookie : void 0;
|
|
170
|
-
}
|
|
171
|
-
if (cookie) {
|
|
172
|
-
headers.append("Cookie", cookie);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
setCookiesToResult(event, result, cookies) {
|
|
176
|
-
if (event.multiValueHeaders && result.multiValueHeaders) {
|
|
177
|
-
result.multiValueHeaders["set-cookie"] = cookies;
|
|
178
|
-
} else {
|
|
179
|
-
result.headers["set-cookie"] = cookies.join(", ");
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
113
|
+
var ALBProcessor = class extends RequestEventProcessor {
|
|
114
|
+
getHeaders(event) {
|
|
115
|
+
const headers = new Headers();
|
|
116
|
+
if (event.multiValueHeaders) {
|
|
117
|
+
for (const [key, values] of Object.entries(event.multiValueHeaders)) if (values && Array.isArray(values)) headers.set(key, sanitizeHeaderValue(values.join("; ")));
|
|
118
|
+
} else for (const [key, value] of Object.entries(event.headers ?? {})) if (value) headers.set(key, sanitizeHeaderValue(value));
|
|
119
|
+
return headers;
|
|
120
|
+
}
|
|
121
|
+
getPath(event) {
|
|
122
|
+
return event.path;
|
|
123
|
+
}
|
|
124
|
+
getMethod(event) {
|
|
125
|
+
return event.httpMethod;
|
|
126
|
+
}
|
|
127
|
+
getQueryString(event) {
|
|
128
|
+
if (event.multiValueQueryStringParameters) return Object.entries(event.multiValueQueryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value?.join(`&${key}=`)}`).join("&");
|
|
129
|
+
else return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
|
|
130
|
+
}
|
|
131
|
+
getCookies(event, headers) {
|
|
132
|
+
let cookie;
|
|
133
|
+
if (event.multiValueHeaders) cookie = event.multiValueHeaders.cookie?.join("; ");
|
|
134
|
+
else cookie = event.headers ? event.headers.cookie : void 0;
|
|
135
|
+
if (cookie) headers.append("Cookie", cookie);
|
|
136
|
+
}
|
|
137
|
+
setCookiesToResult(event, result, cookies) {
|
|
138
|
+
if (event.multiValueHeaders && result.multiValueHeaders) result.multiValueHeaders["set-cookie"] = cookies;
|
|
139
|
+
else result.headers["set-cookie"] = cookies[0];
|
|
140
|
+
}
|
|
141
|
+
};
|
|
183
142
|
const albProcessor = new ALBProcessor();
|
|
143
|
+
var LatticeV2Processor = class extends RequestEventProcessor {
|
|
144
|
+
getPath(event) {
|
|
145
|
+
return event.path;
|
|
146
|
+
}
|
|
147
|
+
getMethod(event) {
|
|
148
|
+
return event.method;
|
|
149
|
+
}
|
|
150
|
+
getQueryString() {
|
|
151
|
+
return "";
|
|
152
|
+
}
|
|
153
|
+
getHeaders(event) {
|
|
154
|
+
const headers = new Headers();
|
|
155
|
+
if (event.headers) {
|
|
156
|
+
for (const [k, values] of Object.entries(event.headers)) if (values) values.forEach((v) => headers.append(k, sanitizeHeaderValue(v)));
|
|
157
|
+
}
|
|
158
|
+
return headers;
|
|
159
|
+
}
|
|
160
|
+
getCookies() {}
|
|
161
|
+
setCookiesToResult(_, result, cookies) {
|
|
162
|
+
result.headers = {
|
|
163
|
+
...result.headers,
|
|
164
|
+
"set-cookie": cookies[0]
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const latticeV2Processor = new LatticeV2Processor();
|
|
184
169
|
function isProxyEventALB(event) {
|
|
185
|
-
|
|
170
|
+
return Object.hasOwn(event, "requestContext") && Object.hasOwn(event.requestContext, "elb");
|
|
186
171
|
}
|
|
187
172
|
function isProxyEventV2(event) {
|
|
188
|
-
|
|
173
|
+
return Object.hasOwn(event, "rawPath") && Object.hasOwn(event.requestContext ?? {}, "http");
|
|
189
174
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
class TriggerFactory {
|
|
193
|
-
simpleRouter = {};
|
|
194
|
-
honoApp;
|
|
195
|
-
internalApp = new Hono();
|
|
196
|
-
constructor(app) {
|
|
197
|
-
this.honoApp = app;
|
|
198
|
-
}
|
|
199
|
-
on = (eventSource, id, ...handlers) => {
|
|
200
|
-
let thisEventSource = this.simpleRouter[eventSource];
|
|
201
|
-
if (!thisEventSource) {
|
|
202
|
-
this.simpleRouter[eventSource] = thisEventSource = {};
|
|
203
|
-
this.honoApp.on(METHOD, getTriggerPath(eventSource), async (c) => {
|
|
204
|
-
if (thisEventSource["$!"]) {
|
|
205
|
-
return this.internalApp.fetch(makeLocalRequest(METHOD, `/${eventSource}/$!`), c.env);
|
|
206
|
-
}
|
|
207
|
-
const resObj = {};
|
|
208
|
-
for (const route in thisEventSource) {
|
|
209
|
-
if (route[0] === "$")
|
|
210
|
-
continue;
|
|
211
|
-
const res = await this.internalApp.fetch(makeLocalRequest(METHOD, `/${eventSource}/${route}`), c.env);
|
|
212
|
-
resObj[route] = /^application\/json/.test(res.headers.get("content-type") || "") ? await res.json() : await res.text();
|
|
213
|
-
}
|
|
214
|
-
if (thisEventSource["$="]) {
|
|
215
|
-
return this.internalApp.fetch(makeLocalRequest(METHOD, `/${eventSource}/$=`), c.env);
|
|
216
|
-
}
|
|
217
|
-
return c.json(resObj);
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
if (thisEventSource[id])
|
|
221
|
-
throw new Error(`Route ID "${id}" already exists for event source "${eventSource}"`);
|
|
222
|
-
this.internalApp.on(METHOD, `/${eventSource}/${id}`, ...handlers);
|
|
223
|
-
thisEventSource[id] = true;
|
|
224
|
-
return this;
|
|
225
|
-
};
|
|
175
|
+
function isLatticeEventV2(event) {
|
|
176
|
+
return Object.hasOwn(event, "requestContext") && Object.hasOwn(event.requestContext ?? {}, "serviceArn");
|
|
226
177
|
}
|
|
178
|
+
//#endregion
|
|
179
|
+
//#region src/trigger.ts
|
|
180
|
+
const METHOD = "TRIGGER";
|
|
181
|
+
const JSON_CONTENT_TYPE_REGEX = /^application\/json/;
|
|
182
|
+
var TriggerFactory = class {
|
|
183
|
+
simpleRouter = {};
|
|
184
|
+
honoApp;
|
|
185
|
+
internalApp = new Hono();
|
|
186
|
+
constructor(app) {
|
|
187
|
+
this.honoApp = app;
|
|
188
|
+
}
|
|
189
|
+
on = (eventSource, id, ...handlers) => {
|
|
190
|
+
let thisEventSource = this.simpleRouter[eventSource];
|
|
191
|
+
if (!thisEventSource) {
|
|
192
|
+
this.simpleRouter[eventSource] = thisEventSource = {};
|
|
193
|
+
this.honoApp.on(METHOD, getTriggerPath(eventSource), async (c) => {
|
|
194
|
+
if (thisEventSource["$!"]) return this.internalApp.fetch(makeLocalRequest(METHOD, `/${eventSource}/$!`), c.env);
|
|
195
|
+
const resObj = {};
|
|
196
|
+
for (const route in thisEventSource) {
|
|
197
|
+
if (route[0] === "$") continue;
|
|
198
|
+
const res = await this.internalApp.fetch(makeLocalRequest(METHOD, `/${eventSource}/${route}`), c.env);
|
|
199
|
+
resObj[route] = JSON_CONTENT_TYPE_REGEX.test(res.headers.get("content-type") || "") ? await res.json() : await res.text();
|
|
200
|
+
}
|
|
201
|
+
if (thisEventSource["$="]) return this.internalApp.fetch(makeLocalRequest(METHOD, `/${eventSource}/$=`), c.env);
|
|
202
|
+
return c.json(resObj);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
if (thisEventSource[id]) throw new Error(`Route ID "${id}" already exists for event source "${eventSource}"`);
|
|
206
|
+
this.internalApp.on(METHOD, `/${eventSource}/${id}`, ...handlers);
|
|
207
|
+
thisEventSource[id] = true;
|
|
208
|
+
return this;
|
|
209
|
+
};
|
|
210
|
+
};
|
|
227
211
|
function createTriggerFactory(app) {
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
class TriggerEventProcessor {
|
|
231
|
-
createRequest(event) {
|
|
232
|
-
const path = getTriggerPath(getEventSource(event));
|
|
233
|
-
return makeLocalRequest(METHOD, path);
|
|
234
|
-
}
|
|
235
|
-
async createResult(event, res) {
|
|
236
|
-
const contentType = res.headers.get("content-type");
|
|
237
|
-
let isBase64Encoded = !!(contentType && isContentTypeBinary(contentType));
|
|
238
|
-
if (!isBase64Encoded) {
|
|
239
|
-
const contentEncoding = res.headers.get("content-encoding");
|
|
240
|
-
isBase64Encoded = isContentEncodingBinary(contentEncoding);
|
|
241
|
-
}
|
|
242
|
-
const body = isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text();
|
|
243
|
-
const result = {
|
|
244
|
-
body,
|
|
245
|
-
headers: {},
|
|
246
|
-
statusCode: res.status,
|
|
247
|
-
isBase64Encoded
|
|
248
|
-
};
|
|
249
|
-
res.headers.forEach((value, key) => {
|
|
250
|
-
result.headers[key] = value;
|
|
251
|
-
});
|
|
252
|
-
return result;
|
|
253
|
-
}
|
|
212
|
+
return new TriggerFactory(app);
|
|
254
213
|
}
|
|
214
|
+
var TriggerEventProcessor = class {
|
|
215
|
+
createRequest(event) {
|
|
216
|
+
const path = getTriggerPath(getEventSource(event));
|
|
217
|
+
return makeLocalRequest(METHOD, path);
|
|
218
|
+
}
|
|
219
|
+
async createResult(event, res) {
|
|
220
|
+
const contentType = res.headers.get("content-type");
|
|
221
|
+
let isBase64Encoded = !!(contentType && isContentTypeBinary(contentType));
|
|
222
|
+
if (!isBase64Encoded) isBase64Encoded = isContentEncodingBinary(res.headers.get("content-encoding"));
|
|
223
|
+
const result = {
|
|
224
|
+
body: isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text(),
|
|
225
|
+
headers: {},
|
|
226
|
+
statusCode: res.status,
|
|
227
|
+
isBase64Encoded
|
|
228
|
+
};
|
|
229
|
+
res.headers.forEach((value, key) => {
|
|
230
|
+
result.headers[key] = value;
|
|
231
|
+
});
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
};
|
|
255
235
|
const triggerProcessor = new TriggerEventProcessor();
|
|
256
236
|
const triggerPathUUID = `${process.env.HONO_TRIGGER_SALT}-${Date.now()}-${Math.random()}`;
|
|
257
237
|
function getTriggerPath(path) {
|
|
258
|
-
|
|
238
|
+
return mergePath(triggerPathUUID, path);
|
|
259
239
|
}
|
|
260
240
|
function getEventSource(event) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return eventSource;
|
|
241
|
+
const eventSource = event?.eventSource || event?.Name || event?.Records?.[0]?.eventSource || event?.Records?.[0]?.EventSource || event?.source || event?.triggerSource;
|
|
242
|
+
if (!eventSource) throw new Error("Invalid `event`: not LambdaTriggerEvent");
|
|
243
|
+
return eventSource;
|
|
265
244
|
}
|
|
266
245
|
function isTriggerEvent(event) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
246
|
+
try {
|
|
247
|
+
return Boolean(getEventSource(event));
|
|
248
|
+
} catch {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
272
251
|
}
|
|
273
252
|
function makeLocalRequest(method, path) {
|
|
274
|
-
|
|
253
|
+
return new Request(`http://127.0.0.1${path}`, { method });
|
|
254
|
+
}
|
|
255
|
+
//#endregion
|
|
256
|
+
//#region src/common.ts
|
|
257
|
+
const CONTENT_TYPE_TEXT_REGEX = /^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/;
|
|
258
|
+
const CONTENT_ENCODING_IDENTITY_REGEX = /^identity$/i;
|
|
259
|
+
/**
|
|
260
|
+
* Check if the given content type is binary.
|
|
261
|
+
* This is the default used by `handle`/`streamHandle` and may be overridden via the
|
|
262
|
+
* `isContentTypeBinary` option.
|
|
263
|
+
*/
|
|
264
|
+
function defaultIsContentTypeBinary(contentType) {
|
|
265
|
+
return !CONTENT_TYPE_TEXT_REGEX.test(contentType);
|
|
275
266
|
}
|
|
276
|
-
|
|
277
267
|
function isContentTypeBinary(contentType) {
|
|
278
|
-
|
|
279
|
-
contentType
|
|
280
|
-
);
|
|
268
|
+
return defaultIsContentTypeBinary(contentType);
|
|
281
269
|
}
|
|
282
270
|
function isContentEncodingBinary(contentEncoding) {
|
|
283
|
-
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
return /^(?:gzip|deflate|compress|br)/.test(contentEncoding);
|
|
271
|
+
return !!contentEncoding && !CONTENT_ENCODING_IDENTITY_REGEX.test(contentEncoding);
|
|
287
272
|
}
|
|
288
273
|
function getProcessor(event) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
return v2Processor;
|
|
295
|
-
return v1Processor;
|
|
274
|
+
if (isTriggerEvent(event)) return triggerProcessor;
|
|
275
|
+
if (isProxyEventALB(event)) return albProcessor;
|
|
276
|
+
if (isProxyEventV2(event)) return v2Processor;
|
|
277
|
+
if (isLatticeEventV2(event)) return latticeV2Processor;
|
|
278
|
+
return v1Processor;
|
|
296
279
|
}
|
|
297
|
-
|
|
280
|
+
//#endregion
|
|
281
|
+
//#region src/utils/event.ts
|
|
282
|
+
/**
|
|
283
|
+
* Creates/populates a minimal event with path & method for routing usage purpose.
|
|
284
|
+
*
|
|
285
|
+
* Will also set `Content-Type` header and stringify body if method is not GET/HEAD
|
|
286
|
+
*/
|
|
298
287
|
function minimalEvent(method, path, baseEvent) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
return event;
|
|
288
|
+
const event = baseEvent ?? {};
|
|
289
|
+
event.requestContext ??= {
|
|
290
|
+
http: {
|
|
291
|
+
method: "",
|
|
292
|
+
path: ""
|
|
293
|
+
},
|
|
294
|
+
routeKey: ""
|
|
295
|
+
};
|
|
296
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
297
|
+
event.headers ??= {};
|
|
298
|
+
event.headers["content-type"] ??= "application/json";
|
|
299
|
+
if (typeof event.body !== "string") event.body = JSON.stringify(event.body);
|
|
300
|
+
}
|
|
301
|
+
event.routeKey = event.requestContext.routeKey = `${method} ${path}`;
|
|
302
|
+
event.requestContext.http.method = method;
|
|
303
|
+
event.rawPath = event.requestContext.http.path = path;
|
|
304
|
+
return event;
|
|
317
305
|
}
|
|
318
|
-
|
|
306
|
+
//#endregion
|
|
307
|
+
//#region src/handler.ts
|
|
319
308
|
async function writableWriteReadable(writer, reader) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
309
|
+
let readResult = await reader.read();
|
|
310
|
+
while (!readResult.done) {
|
|
311
|
+
writer.write(readResult.value);
|
|
312
|
+
readResult = await reader.read();
|
|
313
|
+
}
|
|
314
|
+
writer.end();
|
|
326
315
|
}
|
|
327
316
|
function stringToReadable(str) {
|
|
328
|
-
|
|
317
|
+
return Readable.from(Buffer.from(str));
|
|
329
318
|
}
|
|
330
319
|
function resultToStreamMetadata(result) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
320
|
+
return {
|
|
321
|
+
statusCode: result.statusCode,
|
|
322
|
+
headers: result.headers,
|
|
323
|
+
cookies: result.cookies
|
|
324
|
+
};
|
|
336
325
|
}
|
|
337
326
|
function responseToStreamMetadata(res) {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
cookies
|
|
350
|
-
};
|
|
327
|
+
const headers = {};
|
|
328
|
+
const cookies = [];
|
|
329
|
+
res.headers.forEach((value, name) => {
|
|
330
|
+
if (name === "set-cookie") cookies.push(value);
|
|
331
|
+
else headers[name] = value;
|
|
332
|
+
});
|
|
333
|
+
return {
|
|
334
|
+
statusCode: res.status,
|
|
335
|
+
headers,
|
|
336
|
+
cookies
|
|
337
|
+
};
|
|
351
338
|
}
|
|
352
339
|
function streamHandle(app, handleConfig) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
} finally {
|
|
380
|
-
responseStream.end();
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
);
|
|
340
|
+
return awslambda.streamifyResponse(async (event, responseStream, context) => {
|
|
341
|
+
await processConfig(event, context, handleConfig);
|
|
342
|
+
const processor = getProcessor(event);
|
|
343
|
+
try {
|
|
344
|
+
const req = processor.createRequest(event);
|
|
345
|
+
const res = await app.fetch(req, {
|
|
346
|
+
event,
|
|
347
|
+
context
|
|
348
|
+
});
|
|
349
|
+
if (res.headers.get("$HAAL-returnBody")) {
|
|
350
|
+
const result = await res.json();
|
|
351
|
+
responseStream = awslambda.HttpResponseStream.from(responseStream, resultToStreamMetadata(result));
|
|
352
|
+
const bodyStream = stringToReadable(result.body || "");
|
|
353
|
+
await pipeline(bodyStream, responseStream);
|
|
354
|
+
} else {
|
|
355
|
+
responseStream = awslambda.HttpResponseStream.from(responseStream, responseToStreamMetadata(res));
|
|
356
|
+
if (res.body) await writableWriteReadable(responseStream, res.body.getReader());
|
|
357
|
+
else responseStream.write("");
|
|
358
|
+
}
|
|
359
|
+
} catch (error) {
|
|
360
|
+
console.error("Error processing request:", error);
|
|
361
|
+
responseStream.write("Internal Server Error");
|
|
362
|
+
} finally {
|
|
363
|
+
responseStream.end();
|
|
364
|
+
}
|
|
365
|
+
});
|
|
384
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Accepts events from API Gateway/ELB(`APIGatewayProxyEvent`) and directly through Function Url(`APIGatewayProxyEventV2`)
|
|
369
|
+
*/
|
|
385
370
|
function handle(app, handleConfig) {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
371
|
+
return async (event, context) => {
|
|
372
|
+
await processConfig(event, context, handleConfig);
|
|
373
|
+
const processor = getProcessor(event);
|
|
374
|
+
const resultOptions = handleConfig?.isContentTypeBinary ? { isContentTypeBinary: handleConfig.isContentTypeBinary } : void 0;
|
|
375
|
+
let req;
|
|
376
|
+
try {
|
|
377
|
+
req = processor.createRequest(event);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
console.error("Error processing request:", error);
|
|
380
|
+
const errorResponse = error instanceof TypeError ? new Response("Invalid request", { status: 400 }) : new Response("Internal Server Error", { status: 500 });
|
|
381
|
+
return processor.createResult(event, errorResponse, resultOptions);
|
|
382
|
+
}
|
|
383
|
+
const res = await app.fetch(req, {
|
|
384
|
+
event,
|
|
385
|
+
context
|
|
386
|
+
});
|
|
387
|
+
if (res.headers.get("$HAAL-returnBody")) return await res.json();
|
|
388
|
+
return processor.createResult(event, res, resultOptions);
|
|
389
|
+
};
|
|
398
390
|
}
|
|
399
391
|
async function processConfig(event, context, handleConfig) {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
}
|
|
392
|
+
const _eventCastV2 = event;
|
|
393
|
+
if (handleConfig?.easyRouteKey) {
|
|
394
|
+
if (!_eventCastV2.routeKey) return;
|
|
395
|
+
if (!_eventCastV2.requestContext?.http?.path && !_eventCastV2.requestContext?.http?.method) {
|
|
396
|
+
const [method, path] = _eventCastV2.routeKey.split(" ");
|
|
397
|
+
minimalEvent(method, path, _eventCastV2);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
409
400
|
}
|
|
410
|
-
|
|
401
|
+
//#endregion
|
|
411
402
|
export { TriggerFactory, createTriggerFactory, getTriggerPath, handle, streamHandle, triggerPathUUID };
|
|
403
|
+
|
|
404
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/request.ts","../src/trigger.ts","../src/common.ts","../src/utils/event.ts","../src/handler.ts"],"sourcesContent":["import type { LambdaRequestEvent } from '@namesmt/utils-lambda'\nimport type { ALBEvent, APIGatewayProxyEvent, APIGatewayProxyEventV2, APIGatewayProxyResult, APIGatewayProxyStructuredResultV2 } from 'aws-lambda'\nimport type { EventProcessor, ResultOptions } from './common'\n\nimport type { AdapterEvent, LambdaHandlerResult, LatticeProxyEventV2 } from './types'\nimport { decodeBase64, encodeBase64 } from 'hono/utils/encode'\nimport { defaultIsContentTypeBinary, isContentEncodingBinary } from './common'\n\n// eslint-disable-next-line no-control-regex\nconst NON_ASCII_REGEX = /[^\\x00-\\x7F]/\n\nfunction sanitizeHeaderValue(value: string): string {\n // Check if the value contains non-ASCII characters (char codes > 127)\n if (!NON_ASCII_REGEX.test(value))\n return value\n return encodeURIComponent(value)\n}\n\nabstract class RequestEventProcessor<E extends LambdaRequestEvent | LatticeProxyEventV2> implements EventProcessor<E> {\n protected abstract getPath(event: E): string\n\n protected abstract getMethod(event: E): string\n\n protected abstract getQueryString(event: E): string\n\n protected abstract getHeaders(event: E): Headers\n\n protected abstract getCookies(event: E, headers: Headers): void\n\n protected abstract setCookiesToResult(\n event: E,\n result: LambdaHandlerResult,\n cookies: string[]\n ): void\n\n createRequest(event: E): Request {\n const queryString = this.getQueryString(event)\n const domainName\n = event.requestContext && 'domainName' in event.requestContext\n ? event.requestContext.domainName\n : (event as unknown as APIGatewayProxyEventV2).headers?.host ?? (event as unknown as APIGatewayProxyEvent).multiValueHeaders?.host?.[0]\n const path = this.getPath(event)\n const urlPath = `https://${domainName}${path}`\n const url = queryString ? `${urlPath}?${queryString}` : urlPath\n\n const headers = this.getHeaders(event)\n\n const method = this.getMethod(event)\n const requestInit: RequestInit = {\n headers,\n method,\n }\n\n if (event.body) {\n const body = event.isBase64Encoded ? decodeBase64(event.body) : new TextEncoder().encode(event.body)\n requestInit.body = body\n headers.set('content-length', body.length.toString())\n }\n\n return new Request(url, requestInit)\n }\n\n async createResult(event: E, res: Response, options?: ResultOptions): Promise<LambdaHandlerResult> {\n const contentType = res.headers.get('content-type')\n const isContentTypeBinaryFn = options?.isContentTypeBinary ?? defaultIsContentTypeBinary\n let isBase64Encoded = !!(contentType && isContentTypeBinaryFn(contentType))\n\n if (!isBase64Encoded) {\n const contentEncoding = res.headers.get('content-encoding')\n isBase64Encoded = isContentEncodingBinary(contentEncoding)\n }\n\n const body = isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text()\n\n const result = {\n body,\n headers: {} as NonNullable<APIGatewayProxyStructuredResultV2['headers']>,\n multiValueHeaders: undefined as APIGatewayProxyResult['multiValueHeaders'],\n statusCode: res.status,\n isBase64Encoded,\n } satisfies APIGatewayProxyResult & APIGatewayProxyStructuredResultV2\n\n if ('multiValueHeaders' in event) {\n result.multiValueHeaders = {}\n }\n\n this.setCookies(event, res, result)\n res.headers.forEach((value, key) => {\n result.headers[key] = value\n if ('multiValueHeaders' in event) {\n result.multiValueHeaders![key] = [value]\n }\n })\n\n return result\n }\n\n setCookies(event: E, res: Response, result: LambdaHandlerResult) {\n if (res.headers.has('set-cookie')) {\n const cookies = res.headers.getSetCookie\n ? res.headers.getSetCookie()\n : Array.from(res.headers.entries()).filter(([k]) => k === 'set-cookie').map(([, v]) => v)\n\n if (Array.isArray(cookies)) {\n this.setCookiesToResult(event, result, cookies)\n res.headers.delete('set-cookie')\n }\n }\n }\n}\n\nclass EventV2Processor extends RequestEventProcessor<APIGatewayProxyEventV2> {\n protected getPath(event: APIGatewayProxyEventV2): string {\n return event.rawPath\n }\n\n protected getMethod(event: APIGatewayProxyEventV2): string {\n return event.requestContext.http.method\n }\n\n protected getQueryString(event: APIGatewayProxyEventV2): string {\n return event.rawQueryString\n }\n\n protected getCookies(event: APIGatewayProxyEventV2, headers: Headers): void {\n if (Array.isArray(event.cookies)) {\n headers.set('Cookie', event.cookies.join('; '))\n }\n }\n\n protected setCookiesToResult(\n _: APIGatewayProxyEventV2,\n result: APIGatewayProxyStructuredResultV2,\n cookies: string[],\n ): void {\n result.cookies = cookies\n }\n\n protected getHeaders(event: APIGatewayProxyEventV2): Headers {\n const headers = new Headers()\n this.getCookies(event, headers)\n if (event.headers) {\n for (const [k, v] of Object.entries(event.headers)) {\n if (v) {\n headers.set(k, v)\n }\n }\n }\n return headers\n }\n}\n\nexport const v2Processor: EventV2Processor = new EventV2Processor()\n\nclass EventV1Processor extends RequestEventProcessor<Exclude<LambdaRequestEvent, APIGatewayProxyEventV2>> {\n protected getPath(event: Exclude<LambdaRequestEvent, APIGatewayProxyEventV2>): string {\n return event.path\n }\n\n protected getMethod(event: Exclude<LambdaRequestEvent, APIGatewayProxyEventV2>): string {\n return event.httpMethod\n }\n\n protected getQueryString(event: Exclude<LambdaRequestEvent, APIGatewayProxyEventV2>): string {\n // API Gateway passes decoded values, so we need to re-encode them to preserve the original URL\n if ((event as APIGatewayProxyEvent).multiValueQueryStringParameters) {\n return Object.entries((event as APIGatewayProxyEvent).multiValueQueryStringParameters || {})\n .filter(([, value]) => value)\n .map(([key, values]) => values!.map(value => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join('&'))\n .join('&')\n }\n else {\n return Object.entries(event.queryStringParameters || {})\n .filter(([, value]) => value)\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value || '')}`)\n .join('&')\n }\n }\n\n protected getCookies(\n // eslint-disable-next-line unused-imports/no-unused-vars\n event: Exclude<LambdaRequestEvent, APIGatewayProxyEventV2>,\n // eslint-disable-next-line unused-imports/no-unused-vars\n headers: Headers,\n ): void {\n // nop\n }\n\n protected getHeaders(event: APIGatewayProxyEvent): Headers {\n const headers = new Headers()\n this.getCookies(event, headers)\n if (event.multiValueHeaders) {\n for (const [k, values] of Object.entries(event.multiValueHeaders)) {\n if (values) {\n values.forEach(v => headers.append(k, sanitizeHeaderValue(v)))\n }\n }\n }\n if (event.headers) {\n for (const [k, v] of Object.entries(event.headers)) {\n if (v && !headers.has(k)) {\n headers.set(k, sanitizeHeaderValue(v))\n }\n }\n }\n return headers\n }\n\n protected setCookiesToResult(\n _: APIGatewayProxyEvent,\n result: APIGatewayProxyResult,\n cookies: string[],\n ): void {\n result.multiValueHeaders = {\n 'set-cookie': cookies,\n }\n }\n}\n\nexport const v1Processor: EventV1Processor = new EventV1Processor()\n\nclass ALBProcessor extends RequestEventProcessor<ALBEvent> {\n protected getHeaders(event: ALBEvent): Headers {\n const headers = new Headers()\n // if multiValueHeaders is present the ALB will use it instead of the headers field\n // https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers\n if (event.multiValueHeaders) {\n for (const [key, values] of Object.entries(event.multiValueHeaders)) {\n if (values && Array.isArray(values)) {\n // https://www.rfc-editor.org/rfc/rfc9110.html#name-common-rules-for-defining-f\n headers.set(key, sanitizeHeaderValue(values.join('; ')))\n }\n }\n }\n else {\n for (const [key, value] of Object.entries(event.headers ?? {})) {\n if (value) {\n headers.set(key, sanitizeHeaderValue(value))\n }\n }\n }\n return headers\n }\n\n protected getPath(event: ALBEvent): string {\n return event.path\n }\n\n protected getMethod(event: ALBEvent): string {\n return event.httpMethod\n }\n\n protected getQueryString(event: ALBEvent): string {\n // In the case of ALB Integration either queryStringParameters or multiValueQueryStringParameters can be present not both\n /* \n In other cases like when using the serverless framework, the event object does contain both queryStringParameters and multiValueQueryStringParameters:\n Below is an example event object for this URL: /payment/b8c55e69?select=amount&select=currency\n {\n ...\n queryStringParameters: { select: 'currency' },\n multiValueQueryStringParameters: { select: [ 'amount', 'currency' ] },\n }\n The expected results is for select to be an array with two items. However the pre-fix code is only returning one item ('currency') in the array.\n A simple fix would be to invert the if statement and check the multiValueQueryStringParameters first.\n */\n if (event.multiValueQueryStringParameters) {\n return Object.entries(event.multiValueQueryStringParameters || {})\n .filter(([, value]) => value)\n .map(([key, value]) => `${key}=${value?.join(`&${key}=`)}`)\n .join('&')\n }\n else {\n return Object.entries(event.queryStringParameters || {})\n .filter(([, value]) => value)\n .map(([key, value]) => `${key}=${value}`)\n .join('&')\n }\n }\n\n protected getCookies(event: ALBEvent, headers: Headers): void {\n let cookie\n if (event.multiValueHeaders) {\n cookie = event.multiValueHeaders.cookie?.join('; ')\n }\n else {\n cookie = event.headers ? event.headers.cookie : undefined\n }\n if (cookie) {\n headers.append('Cookie', cookie)\n }\n }\n\n protected setCookiesToResult(\n event: ALBEvent,\n result: APIGatewayProxyResult,\n cookies: string[],\n ): void {\n // when multi value headers is enabled\n if (event.multiValueHeaders && result.multiValueHeaders) {\n result.multiValueHeaders['set-cookie'] = cookies\n }\n else {\n // otherwise serialize the set-cookie\n result.headers!['set-cookie'] = cookies[0]\n }\n }\n}\n\nexport const albProcessor: ALBProcessor = new ALBProcessor()\n\nclass LatticeV2Processor extends RequestEventProcessor<LatticeProxyEventV2> {\n protected getPath(event: LatticeProxyEventV2): string {\n return event.path\n }\n\n protected getMethod(event: LatticeProxyEventV2): string {\n return event.method\n }\n\n protected getQueryString(): string {\n return ''\n }\n\n protected getHeaders(event: LatticeProxyEventV2): Headers {\n const headers = new Headers()\n if (event.headers) {\n for (const [k, values] of Object.entries(event.headers)) {\n if (values) {\n values.forEach(v => headers.append(k, sanitizeHeaderValue(v)))\n }\n }\n }\n return headers\n }\n\n protected getCookies(): void {\n // nop\n }\n\n protected setCookiesToResult(\n _: LatticeProxyEventV2,\n result: APIGatewayProxyResult,\n cookies: string[],\n ): void {\n result.headers = {\n ...result.headers,\n 'set-cookie': cookies[0],\n }\n }\n}\n\nexport const latticeV2Processor: LatticeV2Processor = new LatticeV2Processor()\n\nexport function isProxyEventALB(event: AdapterEvent): event is ALBEvent {\n return Object.hasOwn(event, 'requestContext') && Object.hasOwn((event as LambdaRequestEvent).requestContext, 'elb')\n}\n\nexport function isProxyEventV2(event: AdapterEvent): event is APIGatewayProxyEventV2 {\n // A V1 (REST API) event behind a custom domain base path mapping also carries a\n // `rawPath`, so `rawPath` alone is not enough to identify a V2 event. Every V2\n // (HTTP API / function URL) event has an `http` object on its request context.\n return Object.hasOwn(event, 'rawPath') && Object.hasOwn((event as LambdaRequestEvent).requestContext ?? {}, 'http')\n}\n\nexport function isLatticeEventV2(event: AdapterEvent): event is LatticeProxyEventV2 {\n return Object.hasOwn(event, 'requestContext') && Object.hasOwn((event as LatticeProxyEventV2).requestContext ?? {}, 'serviceArn')\n}\n","import type { CommonTriggerEventsMap, LambdaTriggerEvent } from '@namesmt/utils-lambda'\nimport type { APIGatewayProxyStructuredResultV2 } from 'aws-lambda'\nimport type { Env } from 'hono'\nimport type { H } from 'hono/types'\nimport type { EventProcessor } from './common'\nimport type { AdapterEvent } from './types'\nimport { Hono } from 'hono'\nimport { encodeBase64 } from 'hono/utils/encode'\nimport { mergePath } from 'hono/utils/url'\nimport { isContentEncodingBinary, isContentTypeBinary } from './common'\n\nconst METHOD = 'TRIGGER'\nconst JSON_CONTENT_TYPE_REGEX = /^application\\/json/\n\nexport class TriggerFactory<IE extends Env, HE extends Env> {\n private simpleRouter: Record<string, Record<string, true>> = {}\n\n honoApp: Hono<HE>\n internalApp = new Hono<IE>()\n\n constructor(app: Hono<HE>) {\n this.honoApp = app\n }\n\n on = (eventSource: string, id: string, ...handlers: H<IE>[]) => {\n let thisEventSource = this.simpleRouter[eventSource]\n if (!thisEventSource) {\n this.simpleRouter[eventSource] = thisEventSource = {}\n\n this.honoApp.on(METHOD, getTriggerPath(eventSource), async (c) => {\n // $!: rootTakeover, this is a special id that will return itself, bypass the execute of the rest of the ids\n if (thisEventSource['$!']) {\n return this.internalApp.fetch(makeLocalRequest(METHOD, `/${eventSource}/$!`), c.env)\n }\n\n const resObj: Record<string, any> = {}\n for (const route in thisEventSource) {\n // Bypass special ids in normal process loop\n if (route[0] === '$')\n continue\n\n const res = await this.internalApp.fetch(makeLocalRequest(METHOD, `/${eventSource}/${route}`), c.env)\n resObj[route] = JSON_CONTENT_TYPE_REGEX.test(res.headers.get('content-type') || '') ? await res.json() : await res.text()\n }\n\n // $: rootReturn, this is a special id that will always be processed last and return itself instead of an object of all ids result.\n if (thisEventSource['$=']) {\n return this.internalApp.fetch(makeLocalRequest(METHOD, `/${eventSource}/$=`), c.env)\n }\n\n return c.json(resObj)\n })\n }\n\n if (thisEventSource[id])\n throw new Error(`Route ID \"${id}\" already exists for event source \"${eventSource}\"`)\n\n // @ts-expect-error upstream Hono type bug\n this.internalApp.on(METHOD, `/${eventSource}/${id}`, ...handlers)\n thisEventSource[id] = true\n\n return this\n }\n}\n\ntype ExtractHonoEnv<A extends Hono> = A extends Hono<infer E> ? E : never\n\nexport function createTriggerFactory<E extends Env, A extends Hono<any, any, '/'>>(app: A) {\n return new TriggerFactory<E extends unknown\n ? {\n Bindings: { event: LambdaTriggerEvent }\n Variables: Record<string, unknown>\n }\n : E, ExtractHonoEnv<A>>(app)\n}\n\nclass TriggerEventProcessor implements EventProcessor<LambdaTriggerEvent> {\n createRequest(event: LambdaTriggerEvent): Request {\n const path = getTriggerPath(getEventSource(event))\n return makeLocalRequest(METHOD, path)\n }\n\n async createResult(event: LambdaTriggerEvent, res: Response): Promise<any> {\n const contentType = res.headers.get('content-type')\n let isBase64Encoded = !!(contentType && isContentTypeBinary(contentType))\n\n if (!isBase64Encoded) {\n const contentEncoding = res.headers.get('content-encoding')\n isBase64Encoded = isContentEncodingBinary(contentEncoding)\n }\n\n const body = isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text()\n\n const result = {\n body,\n headers: {} as NonNullable<APIGatewayProxyStructuredResultV2['headers']>,\n statusCode: res.status,\n isBase64Encoded,\n } satisfies APIGatewayProxyStructuredResultV2\n\n res.headers.forEach((value, key) => {\n result.headers[key] = value\n })\n\n return result\n }\n}\nexport const triggerProcessor: TriggerEventProcessor = new TriggerEventProcessor()\n\n// eslint-disable-next-line node/prefer-global/process\nexport const triggerPathUUID = `${process.env.HONO_TRIGGER_SALT}-${Date.now()}-${Math.random()}`\n\nexport function getTriggerPath(path: string) {\n return mergePath(triggerPathUUID, path)\n}\n\nexport function getEventSource(event: LambdaTriggerEvent): string {\n const eventSource = (false\n || (event as CommonTriggerEventsMap['eventSource'])?.eventSource\n || (event as CommonTriggerEventsMap['Name'])?.Name\n || (event as CommonTriggerEventsMap['Records.eventSource'])?.Records?.[0]?.eventSource\n || (event as CommonTriggerEventsMap['Records.EventSource'])?.Records?.[0]?.EventSource\n || (event as CommonTriggerEventsMap['source'])?.source\n || (event as CommonTriggerEventsMap['triggerSource'])?.triggerSource\n )\n\n if (!eventSource)\n throw new Error('Invalid `event`: not LambdaTriggerEvent')\n\n return eventSource\n}\n\nexport function isTriggerEvent(event: AdapterEvent): event is LambdaTriggerEvent {\n try {\n return Boolean(getEventSource(event as LambdaTriggerEvent))\n }\n catch {\n return false\n }\n}\n\nexport function makeLocalRequest(method: string, path: string): Request {\n return new Request(`http://127.0.0.1${path}`, { method })\n}\n","import type { AdapterEvent } from './types'\n\nimport { albProcessor, isLatticeEventV2, isProxyEventALB, isProxyEventV2, latticeV2Processor, v1Processor, v2Processor } from './request'\nimport { isTriggerEvent, triggerProcessor } from './trigger'\n\nconst CONTENT_TYPE_TEXT_REGEX = /^text\\/(?:plain|html|css|javascript|csv)|(?:\\/|\\+)(?:json|xml)\\s*(?:;|$)/\nconst CONTENT_ENCODING_IDENTITY_REGEX = /^identity$/i\n\n/**\n * Check if the given content type is binary.\n * This is the default used by `handle`/`streamHandle` and may be overridden via the\n * `isContentTypeBinary` option.\n */\nexport function defaultIsContentTypeBinary(contentType: string): boolean {\n return !CONTENT_TYPE_TEXT_REGEX.test(contentType)\n}\n\nexport function isContentTypeBinary(contentType: string) {\n return defaultIsContentTypeBinary(contentType)\n}\n\nexport function isContentEncodingBinary(contentEncoding: string | null) {\n return !!contentEncoding && !CONTENT_ENCODING_IDENTITY_REGEX.test(contentEncoding)\n}\n\nexport interface ResultOptions {\n isContentTypeBinary?: (contentType: string) => boolean\n}\n\nexport abstract class EventProcessor<E extends AdapterEvent> {\n abstract createRequest(event: E): Request\n\n abstract createResult(event: E, res: Response, options?: ResultOptions): Promise<any>\n}\n\nexport function getProcessor(event: AdapterEvent): EventProcessor<AdapterEvent> {\n if (isTriggerEvent(event))\n return triggerProcessor\n if (isProxyEventALB(event))\n return albProcessor\n\n if (isProxyEventV2(event))\n return v2Processor\n\n if (isLatticeEventV2(event))\n return latticeV2Processor\n\n return v1Processor\n}\n","import type { APIGatewayProxyEventV2 } from 'aws-lambda'\n\n/**\n * Creates/populates a minimal event with path & method for routing usage purpose.\n * \n * Will also set `Content-Type` header and stringify body if method is not GET/HEAD \n */\nexport function minimalEvent(method: string, path: string, baseEvent?: APIGatewayProxyEventV2): APIGatewayProxyEventV2 {\n const event = baseEvent ?? {} as any\n\n event.requestContext ??= {\n http: {\n method: '',\n path: '',\n },\n routeKey: '',\n }\n\n if (method !== 'GET' && method !== 'HEAD') {\n event.headers ??= {}\n event.headers['content-type'] ??= 'application/json'\n\n if (typeof event.body !== 'string')\n event.body = JSON.stringify(event.body)\n }\n\n event.routeKey = event.requestContext.routeKey = `${method} ${path}`\n event.requestContext.http.method = method\n event.rawPath = event.requestContext.http.path = path\n\n return event as APIGatewayProxyEventV2\n}\n","import type { APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2 } from 'aws-lambda'\nimport type { Env, Hono, Schema } from 'hono'\nimport type { ReadableStreamDefaultReader } from 'stream/web'\nimport type { ResultOptions } from './common'\nimport type { AdapterEvent, LambdaContext, LambdaHandler, LambdaHandlerResult } from './types'\nimport { Readable } from 'stream'\nimport { pipeline } from 'stream/promises'\nimport { getProcessor } from './common'\nimport { minimalEvent } from './utils/event'\n\nasync function writableWriteReadable(writer: NodeJS.WritableStream, reader: ReadableStreamDefaultReader<Uint8Array>): Promise<void> {\n let readResult = await reader.read()\n while (!readResult.done) {\n writer.write(readResult.value)\n readResult = await reader.read()\n }\n writer.end()\n}\n\nfunction stringToReadable(str: string): Readable {\n // eslint-disable-next-line node/prefer-global/buffer\n return Readable.from(Buffer.from(str))\n}\n\nfunction resultToStreamMetadata(result: APIGatewayProxyStructuredResultV2) {\n return {\n statusCode: result.statusCode,\n headers: result.headers,\n cookies: result.cookies,\n }\n}\n\nfunction responseToStreamMetadata(res: Response) {\n const headers: Record<string, string> = {}\n const cookies: string[] = []\n\n res.headers.forEach((value, name) => {\n if (name === 'set-cookie')\n cookies.push(value)\n else\n headers[name] = value\n })\n\n return {\n statusCode: res.status,\n headers,\n cookies,\n }\n}\n\nexport interface HandleConfigOptions {\n /**\n * This allows you to easier invoke HTTP routes manually by parsing `event.routeKey` for method and path.\n */\n easyRouteKey?: boolean\n /**\n * Overrides the default binary content-type detection.\n * Defaults to `defaultIsContentTypeBinary`.\n */\n isContentTypeBinary?: (contentType: string) => boolean\n}\n\nexport function streamHandle<\n E extends Env = Env,\n S extends Schema = {},\n BasePath extends string = '/',\n>(app: Hono<E, S, BasePath>, handleConfig?: HandleConfigOptions): LambdaHandler<AdapterEvent> {\n // @ts-expect-error awslambda is not a standard API\n return awslambda.streamifyResponse(\n async (event, responseStream, context) => {\n await processConfig(event, context, handleConfig)\n\n const processor = getProcessor(event)\n try {\n const req = processor.createRequest(event)\n\n const res = await app.fetch(req, {\n event,\n context,\n })\n\n if (res.headers.get('$HAAL-returnBody')) {\n const result = (await res.json()) as APIGatewayProxyStructuredResultV2\n\n // Update response stream metadata\n responseStream = awslambda.HttpResponseStream.from(responseStream, resultToStreamMetadata(result))\n\n const bodyStream = stringToReadable(result.body || '')\n\n await pipeline(bodyStream, responseStream)\n }\n else {\n // Update response stream metadata\n responseStream = awslambda.HttpResponseStream.from(responseStream, responseToStreamMetadata(res))\n\n if (res.body) {\n await writableWriteReadable(responseStream, res.body.getReader())\n }\n else {\n responseStream.write('')\n }\n }\n }\n catch (error) {\n console.error('Error processing request:', error)\n responseStream.write('Internal Server Error')\n }\n finally {\n responseStream.end()\n }\n },\n )\n}\n\n/**\n * Accepts events from API Gateway/ELB(`APIGatewayProxyEvent`) and directly through Function Url(`APIGatewayProxyEventV2`)\n */\nexport function handle<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'>(app: Hono<E, S, BasePath>, handleConfig?: HandleConfigOptions): LambdaHandler<AdapterEvent, LambdaHandlerResult> {\n return async (event, context?) => {\n await processConfig(event, context, handleConfig)\n\n const processor = getProcessor(event)\n\n const resultOptions: ResultOptions | undefined = handleConfig?.isContentTypeBinary\n ? { isContentTypeBinary: handleConfig.isContentTypeBinary }\n : undefined\n\n let req: Request\n try {\n req = processor.createRequest(event)\n }\n catch (error) {\n console.error('Error processing request:', error)\n const errorResponse = error instanceof TypeError\n ? new Response('Invalid request', { status: 400 })\n : new Response('Internal Server Error', { status: 500 })\n return processor.createResult(event, errorResponse, resultOptions)\n }\n\n const res = await app.fetch(req, {\n event,\n context,\n })\n\n if (res.headers.get('$HAAL-returnBody'))\n return (await res.json()) as LambdaHandlerResult\n\n return processor.createResult(event, res, resultOptions)\n }\n}\n\nasync function processConfig(event: AdapterEvent, context?: LambdaContext, handleConfig?: HandleConfigOptions) {\n const _eventCastV2 = event as APIGatewayProxyEventV2\n if (handleConfig?.easyRouteKey) {\n if (!_eventCastV2.routeKey)\n return\n\n if (!_eventCastV2.requestContext?.http?.path && !_eventCastV2.requestContext?.http?.method) {\n const [method, path] = _eventCastV2.routeKey.split(' ')\n minimalEvent(method, path, _eventCastV2)\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono-adapter-aws-lambda",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
|
+
"packageManager": "pnpm@12.4.1",
|
|
5
6
|
"description": "",
|
|
6
7
|
"author": "NamesMT <dangquoctrung123@gmail.com>",
|
|
7
8
|
"license": "MIT",
|
|
@@ -19,6 +20,9 @@
|
|
|
19
20
|
"lambda"
|
|
20
21
|
],
|
|
21
22
|
"sideEffects": false,
|
|
23
|
+
"imports": {
|
|
24
|
+
"#src/*": "./src/*"
|
|
25
|
+
},
|
|
22
26
|
"exports": {
|
|
23
27
|
".": {
|
|
24
28
|
"types": "./dist/index.d.mts",
|
|
@@ -33,7 +37,20 @@
|
|
|
33
37
|
"dist"
|
|
34
38
|
],
|
|
35
39
|
"engines": {
|
|
36
|
-
"node": ">=
|
|
40
|
+
"node": ">=22.0.0"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"start": "NODE_ENV=dev tsx src/index.ts",
|
|
44
|
+
"watch": "NODE_ENV=dev tsx watch src/index.ts",
|
|
45
|
+
"dev": "pnpm run watch",
|
|
46
|
+
"lint": "eslint .",
|
|
47
|
+
"test": "vitest",
|
|
48
|
+
"test:types": "tsc --noEmit --skipLibCheck",
|
|
49
|
+
"check": "pnpm lint && pnpm test:types && vitest run --coverage",
|
|
50
|
+
"build": "tsdown",
|
|
51
|
+
"release": "pnpm dlx changelogen@latest --release --push --publish",
|
|
52
|
+
"prepare": "simple-git-hooks",
|
|
53
|
+
"prepublishOnly": "pnpm run build"
|
|
37
54
|
},
|
|
38
55
|
"peerDependencies": {
|
|
39
56
|
"hono": ">=4.7.11"
|
|
@@ -45,39 +62,25 @@
|
|
|
45
62
|
},
|
|
46
63
|
"dependencies": {
|
|
47
64
|
"@namesmt/utils-lambda": "^0.1.4",
|
|
48
|
-
"@types/aws-lambda": "^8.10.
|
|
65
|
+
"@types/aws-lambda": "^8.10.163"
|
|
49
66
|
},
|
|
50
67
|
"devDependencies": {
|
|
51
|
-
"@antfu/eslint-config": "^7.
|
|
52
|
-
"@types/node": "^24.
|
|
53
|
-
"@vitest/coverage-v8": "^3.2.
|
|
68
|
+
"@antfu/eslint-config": "^7.7.3",
|
|
69
|
+
"@types/node": "^24.13.4",
|
|
70
|
+
"@vitest/coverage-v8": "^3.2.7",
|
|
54
71
|
"eslint": "^9.39.2",
|
|
55
72
|
"klona": "^2.0.6",
|
|
56
|
-
"lint-staged": "^16.
|
|
57
|
-
"simple-git-hooks": "^2.
|
|
58
|
-
"
|
|
73
|
+
"lint-staged": "^16.4.0",
|
|
74
|
+
"simple-git-hooks": "^2.14.0",
|
|
75
|
+
"tsdown": "^0.23.0",
|
|
76
|
+
"tsx": "^4.23.13",
|
|
59
77
|
"typescript": "^5.9.3",
|
|
60
|
-
"
|
|
61
|
-
"vitest": "^3.2.4"
|
|
78
|
+
"vitest": "^3.2.7"
|
|
62
79
|
},
|
|
63
80
|
"simple-git-hooks": {
|
|
64
81
|
"pre-commit": "pnpm lint-staged"
|
|
65
82
|
},
|
|
66
83
|
"lint-staged": {
|
|
67
84
|
"*": "eslint --fix"
|
|
68
|
-
},
|
|
69
|
-
"scripts": {
|
|
70
|
-
"start": "NODE_ENV=dev tsx src/index.ts",
|
|
71
|
-
"watch": "NODE_ENV=dev tsx watch src/index.ts",
|
|
72
|
-
"stub": "unbuild --stub",
|
|
73
|
-
"dev": "pnpm run watch",
|
|
74
|
-
"play": "pnpm run stub && pnpm run --filter playground dev",
|
|
75
|
-
"play:useBuild": "pnpm run build && pnpm run --filter playground dev",
|
|
76
|
-
"lint": "eslint .",
|
|
77
|
-
"test": "vitest",
|
|
78
|
-
"test:types": "tsc --noEmit --skipLibCheck",
|
|
79
|
-
"check": "pnpm lint && pnpm test:types && vitest run --coverage",
|
|
80
|
-
"build": "unbuild",
|
|
81
|
-
"release": "pnpm dlx changelogen@latest --release --push --publish"
|
|
82
85
|
}
|
|
83
|
-
}
|
|
86
|
+
}
|