@vercube/serverless 0.0.22

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025-present - Vercube
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,192 @@
1
+ <div align="center">
2
+ <a href="https://vercube.dev/"><img src="https://github.com/OskarLebuda/vue-lazy-hydration/raw/main/.github/assets/logo.png?raw=true" alt="Vercube logo" width="200"></a>
3
+ <br>
4
+ <br>
5
+
6
+ # @vercube/serverless
7
+
8
+ Serverless deployment adapters for Vercube applications
9
+
10
+ <a href="https://www.npmjs.com/package/@vercube/serverless">
11
+ <img src="https://img.shields.io/npm/v/%40vercube%2Fserverless?style=for-the-badge&logo=npm&color=%23767eff" alt="npm"/>
12
+ </a>
13
+ <a href="https://www.npmjs.com/package/@vercube/serverless">
14
+ <img src="https://img.shields.io/npm/dm/%40vercube%2Fserverless?style=for-the-badge&logo=npm&color=%23767eff" alt="npm"/>
15
+ </a>
16
+ <a href="https://github.com/vercube/vercube/blob/main/LICENSE" target="_blank">
17
+ <img src="https://img.shields.io/npm/l/%40vercube%2Fserverless?style=for-the-badge&color=%23767eff" alt="License"/>
18
+ </a>
19
+ <br/>
20
+ <br/>
21
+ </div>
22
+
23
+ Deploy your Vercube applications to serverless platforms with zero configuration. This package provides seamless adapters for AWS Lambda, Vercel, and other serverless providers, allowing you to run your Vercube apps anywhere without code changes.
24
+
25
+ ---
26
+
27
+ ## 🧩 `@vercube/serverless` Module
28
+
29
+ The `@vercube/serverless` module provides unified, provider-agnostic adapters for deploying Vercube applications to serverless platforms. It abstracts the differences between various serverless providers into a consistent API, enabling easy deployment across different environments without modifying your application code.
30
+
31
+ ### ✅ Key Features
32
+
33
+ - **AWS Lambda Integration** - Full support for API Gateway v1 and v2
34
+ - **Zero Configuration** - Works out-of-the-box with existing Vercube apps
35
+ - **Type Safety** - Complete TypeScript support with proper type definitions
36
+ - **Binary Support** - Automatic handling of binary content with base64 encoding
37
+ - **Cookie Support** - Proper cookie handling for both API Gateway versions
38
+ - **Error Handling** - Robust error handling and validation
39
+ - **Performance Optimized** - Efficient request/response conversion
40
+
41
+ ---
42
+
43
+ ## 🚀 Installation
44
+
45
+ ```bash
46
+ pnpm install @vercube/serverless
47
+ ```
48
+
49
+ ---
50
+
51
+ ## ⚙️ Usage
52
+
53
+ ### AWS Lambda Integration
54
+
55
+ Deploy your Vercube application to AWS Lambda with API Gateway:
56
+
57
+ ```ts
58
+ // lambda.ts
59
+ import { createApp } from '@vercube/core';
60
+ import { toServerlessHandler } from '@vercube/serverless/aws-lambda';
61
+
62
+ const app = createApp();
63
+ export const handler = toServerlessHandler(app);
64
+ ```
65
+
66
+ ### Serverless Framework Configuration
67
+
68
+ ```yaml
69
+ # serverless.yml
70
+ service: vercube-app
71
+
72
+ provider:
73
+ name: aws
74
+ runtime: nodejs22.x
75
+ region: us-east-1
76
+
77
+ functions:
78
+ api:
79
+ handler: lambda.handler
80
+ events:
81
+ - http:
82
+ path: /{proxy+}
83
+ method: ANY
84
+ cors: true
85
+ ```
86
+
87
+ ---
88
+
89
+ ## 🔧 Supported Platforms
90
+
91
+ ### AWS Lambda
92
+
93
+ Full support for AWS Lambda with API Gateway integration:
94
+
95
+ - **API Gateway v1** - Complete compatibility with `APIGatewayProxyEvent`
96
+ - **API Gateway v2** - Full support for `APIGatewayProxyEventV2`
97
+ - **Binary Content** - Automatic base64 encoding for binary responses
98
+ - **Cookies** - Proper cookie handling for both API Gateway versions
99
+ - **Headers** - Complete header conversion and processing
100
+
101
+ ---
102
+
103
+ ## 📋 API Reference
104
+
105
+ ### `toServerlessHandler(app: App)`
106
+
107
+ Converts a Vercube App instance into a serverless handler function.
108
+
109
+ **Parameters:**
110
+ - `app` - The Vercube App instance that will handle requests
111
+
112
+ **Returns:**
113
+ - An async function that accepts serverless events and returns platform-specific responses
114
+
115
+ **Example:**
116
+ ```ts
117
+ import { createApp } from '@vercube/core';
118
+ import { toServerlessHandler } from '@vercube/serverless/aws-lambda';
119
+
120
+ const app = createApp();
121
+ export const handler = toServerlessHandler(app);
122
+ ```
123
+
124
+ ---
125
+
126
+ ## 🔄 Request/Response Conversion
127
+
128
+ The serverless adapters handle automatic conversion between platform-specific events and standard web requests:
129
+
130
+ ### Request Conversion
131
+ - **HTTP Method** - Extracted from event properties
132
+ - **URL Construction** - Built from path, query parameters, and headers
133
+ - **Headers** - Converted to standard Headers object
134
+ - **Body** - Properly decoded and converted to Request body
135
+
136
+ ### Response Conversion
137
+ - **Status Code** - Mapped from Response status
138
+ - **Headers** - Converted to platform-specific format
139
+ - **Body** - Encoded appropriately (text vs binary)
140
+ - **Cookies** - Handled for both API Gateway versions
141
+
142
+ ---
143
+
144
+ ## 🚀 Performance Considerations
145
+
146
+ - **Streaming Support** - Efficient handling of large request/response bodies
147
+ - **Memory Optimization** - Minimal memory footprint for serverless environments
148
+ - **Cold Start Optimization** - Fast initialization and request processing
149
+ - **Binary Content** - Optimized base64 encoding for binary responses
150
+
151
+ ---
152
+
153
+ ## 🔍 Debugging
154
+
155
+ Enable debug logging to troubleshoot serverless deployments:
156
+
157
+ ```ts
158
+ import { createApp } from '@vercube/core';
159
+ import { toServerlessHandler } from '@vercube/serverless/aws-lambda';
160
+
161
+ const app = createApp({
162
+ logger: {
163
+ level: 'debug'
164
+ }
165
+ });
166
+
167
+ export const handler = toServerlessHandler(app);
168
+ ```
169
+
170
+ ---
171
+
172
+ ## 📚 Documentation
173
+
174
+ Full documentation is available at [**vercube.dev**](https://vercube.dev).
175
+ Explore guides, API references, and best practices to master Vercube serverless deployment.
176
+
177
+ ---
178
+
179
+ ## 🙌 Credits
180
+
181
+ This module is inspired by:
182
+
183
+ * [Nitro AWS Lambda Preset](https://nitro.build/presets/aws-lambda)
184
+ * [Hono AWS Lambda Adapter](https://hono.dev/guides/aws-lambda)
185
+ * [Vercel Serverless Functions](https://vercel.com/docs/functions)
186
+
187
+ ---
188
+
189
+ ## 🪪 License
190
+
191
+ [MIT License](https://github.com/vercube/vercube/blob/main/LICENSE)
192
+
@@ -0,0 +1,34 @@
1
+ import { ServerlessHandler } from "../../ServerlessTypes-lXnSKHNA.mjs";
2
+ import { App } from "@vercube/core";
3
+ import { APIGatewayProxyEvent, APIGatewayProxyEventV2 } from "aws-lambda";
4
+
5
+ //#region src/Adapters/aws-lambda/index.d.ts
6
+
7
+ /**
8
+ * Converts a Vercube App instance into an AWS Lambda handler function for API Gateway integration.
9
+ *
10
+ * This function creates a serverless handler that bridges between AWS API Gateway events and
11
+ * the Vercube application framework. It handles the conversion of AWS Lambda events to standard
12
+ * web Request objects, processes them through the Vercube app, and converts the responses back
13
+ * to the format expected by AWS API Gateway.
14
+ *
15
+ * The handler supports both API Gateway v1 (APIGatewayProxyEvent) and v2 (APIGatewayProxyEventV2)
16
+ * event formats, automatically detecting and handling the appropriate format. It processes:
17
+ * - HTTP method, URL, headers, and body from the Lambda event
18
+ * - Converts them to a standard web Request object
19
+ * - Passes the request through the Vercube application
20
+ * - Converts the Response back to AWS API Gateway format
21
+ *
22
+ * The returned handler function can be directly used as an AWS Lambda function handler,
23
+ * providing seamless integration between AWS Lambda and Vercube applications.
24
+ *
25
+ * @param app - The Vercube App instance that will handle the requests
26
+ * @returns An async function that accepts AWS API Gateway events and returns API Gateway responses
27
+ *
28
+ * @see {@link convertEventToRequest} For details on event to request conversion
29
+ * @see {@link convertResponseToAWSResponse} For details on response header conversion
30
+ * @see {@link convertBodyToAWSResponse} For details on response body conversion
31
+ */
32
+ declare function toServerlessHandler(app: App): ServerlessHandler<APIGatewayProxyEvent | APIGatewayProxyEventV2>;
33
+ //#endregion
34
+ export { toServerlessHandler };
@@ -0,0 +1,353 @@
1
+ import { stringifyQuery } from "ufo";
2
+
3
+ //#region src/Adapters/aws-lambda/Utils/Request.ts
4
+ const DEFAULT_METHOD = "GET";
5
+ const DEFAULT_HOSTNAME = ".";
6
+ const HTTP_PROTOCOL = "http";
7
+ const HTTPS_PROTOCOL = "https";
8
+ const HEADER_KEYS = {
9
+ HOST: ["host", "Host"],
10
+ X_FORWARDED_PROTO: ["X-Forwarded-Proto", "x-forwarded-proto"],
11
+ COOKIE: "cookie"
12
+ };
13
+ /**
14
+ * Type guard to check if an event is APIGatewayProxyEventV2
15
+ */
16
+ function isV2Event(event) {
17
+ return "requestContext" in event && "http" in event.requestContext && "method" in event.requestContext.http;
18
+ }
19
+ /**
20
+ * Type guard to check if an event is APIGatewayProxyEvent
21
+ */
22
+ function isV1Event(event) {
23
+ return "httpMethod" in event;
24
+ }
25
+ /**
26
+ * Safely gets a header value with case-insensitive fallback
27
+ */
28
+ function getHeaderValue(headers, keys) {
29
+ if (!headers) return void 0;
30
+ for (const key of keys) {
31
+ const value = headers[key];
32
+ if (value !== void 0) return value;
33
+ }
34
+ return void 0;
35
+ }
36
+ /**
37
+ * Extracts the HTTP method from an API Gateway event.
38
+ *
39
+ * Handles both v1 and v2 event formats:
40
+ * - v1: Uses `httpMethod` property
41
+ * - v2: Uses `requestContext.http.method` property
42
+ *
43
+ * @param event - The AWS API Gateway event object (v1 or v2 format)
44
+ * @returns The HTTP method as a string, defaults to 'GET' if not found
45
+ */
46
+ function getEventMethod(event) {
47
+ if (isV1Event(event)) return event.httpMethod || DEFAULT_METHOD;
48
+ if (isV2Event(event)) return event.requestContext?.http?.method || DEFAULT_METHOD;
49
+ return DEFAULT_METHOD;
50
+ }
51
+ /**
52
+ * Constructs a complete URL from an API Gateway event.
53
+ *
54
+ * Builds the URL by combining:
55
+ * - Protocol (http/https based on X-Forwarded-Proto header)
56
+ * - Hostname (from headers or requestContext)
57
+ * - Path (from event path properties)
58
+ * - Query string (from query parameters)
59
+ *
60
+ * @param event - The AWS API Gateway event object (v1 or v2 format)
61
+ * @returns A complete URL object
62
+ */
63
+ function getEventUrl(event) {
64
+ const hostname = getEventHostname(event);
65
+ const path = getEventPath(event);
66
+ const query = getEventQuery(event);
67
+ const protocol = getEventProtocol(event);
68
+ const urlPath = query ? `${path}?${query}` : path;
69
+ return new URL(urlPath, `${protocol}://${hostname}`);
70
+ }
71
+ /**
72
+ * Extracts the hostname from the event
73
+ */
74
+ function getEventHostname(event) {
75
+ const hostHeader = getHeaderValue(event.headers, HEADER_KEYS.HOST);
76
+ if (hostHeader) return hostHeader;
77
+ return event.requestContext?.domainName || DEFAULT_HOSTNAME;
78
+ }
79
+ /**
80
+ * Extracts the path from the event
81
+ */
82
+ function getEventPath(event) {
83
+ if (isV1Event(event)) return event.path || "/";
84
+ if (isV2Event(event)) return event.rawPath || "/";
85
+ return "/";
86
+ }
87
+ /**
88
+ * Determines the protocol from the event headers
89
+ */
90
+ function getEventProtocol(event) {
91
+ const forwardedProto = getHeaderValue(event.headers, HEADER_KEYS.X_FORWARDED_PROTO);
92
+ return forwardedProto === HTTP_PROTOCOL ? HTTP_PROTOCOL : HTTPS_PROTOCOL;
93
+ }
94
+ /**
95
+ * Extracts and formats query parameters from an API Gateway event.
96
+ *
97
+ * Handles both v1 and v2 event formats:
98
+ * - v2: Uses `rawQueryString` if available
99
+ * - v1: Combines `queryStringParameters` and `multiValueQueryStringParameters`
100
+ *
101
+ * @param event - The AWS API Gateway event object (v1 or v2 format)
102
+ * @returns A formatted query string (without the leading '?')
103
+ */
104
+ function getEventQuery(event) {
105
+ if (isV2Event(event) && typeof event.rawQueryString === "string") return event.rawQueryString;
106
+ const queryParams = event.queryStringParameters || {};
107
+ const multiValueParams = isV1Event(event) ? event.multiValueQueryStringParameters || {} : {};
108
+ const combinedParams = {
109
+ ...queryParams,
110
+ ...multiValueParams
111
+ };
112
+ return stringifyQuery(combinedParams);
113
+ }
114
+ /**
115
+ * Converts API Gateway event headers to a standard Headers object.
116
+ *
117
+ * Processes all headers from the event and handles cookies specially:
118
+ * - Sets all event headers in the Headers object
119
+ * - Appends cookies from the event's cookies array (v2 format)
120
+ *
121
+ * @param event - The AWS API Gateway event object (v1 or v2 format)
122
+ * @returns A Headers object with all event headers and cookies
123
+ */
124
+ function getEventHeaders(event) {
125
+ const headers = new Headers();
126
+ if (event.headers) {
127
+ for (const [key, value] of Object.entries(event.headers)) if (value !== void 0 && value !== null) headers.set(key, value);
128
+ }
129
+ if (isV2Event(event) && event.cookies && Array.isArray(event.cookies)) {
130
+ for (const cookie of event.cookies) if (cookie) headers.append(HEADER_KEYS.COOKIE, cookie);
131
+ }
132
+ return headers;
133
+ }
134
+ /**
135
+ * Extracts the request body from an API Gateway event.
136
+ *
137
+ * Handles different body formats:
138
+ * - Returns undefined if no body is present
139
+ * - Decodes base64-encoded bodies when `isBase64Encoded` is true
140
+ * - Returns the raw body string for regular requests
141
+ *
142
+ * @param event - The AWS API Gateway event object (v1 or v2 format)
143
+ * @returns The request body as BodyInit (string, Buffer, or undefined)
144
+ */
145
+ function getEventBody(event) {
146
+ if (!event.body || event.body === null) return void 0;
147
+ if (event.isBase64Encoded) try {
148
+ return Buffer.from(event.body, "base64");
149
+ } catch {
150
+ return event.body;
151
+ }
152
+ return event.body;
153
+ }
154
+ /**
155
+ * Converts an AWS API Gateway event to a standard Request object.
156
+ *
157
+ * This function handles both APIGatewayProxyEvent (v1) and APIGatewayProxyEventV2 (v2) formats,
158
+ * extracting the HTTP method, URL, headers, and body to create a web-standard Request object.
159
+ *
160
+ * This file is highly inspired by the `awsRequest` from `nitro`
161
+ * @see https://github.com/nitrojs/nitro/blob/v3/src/presets/aws-lambda/runtime/_utils.ts
162
+ *
163
+ * @param event - The AWS API Gateway event object (v1 or v2 format)
164
+ * @returns A new Request object with the extracted event data
165
+ * @throws {Error} If the event is invalid or missing required properties
166
+ */
167
+ function convertEventToRequest(event) {
168
+ if (!event || typeof event !== "object") throw new Error("Invalid event: event must be a valid object");
169
+ const method = getEventMethod(event);
170
+ const url = getEventUrl(event);
171
+ const headers = getEventHeaders(event);
172
+ const body = getEventBody(event);
173
+ return new Request(url, {
174
+ method,
175
+ headers,
176
+ body
177
+ });
178
+ }
179
+
180
+ //#endregion
181
+ //#region src/Adapters/aws-lambda/Utils/Response.ts
182
+ const DEFAULT_BODY = "";
183
+ const DEFAULT_CONTENT_TYPE = "";
184
+ const UTF8_ENCODING = "utf8";
185
+ const BASE64_ENCODING = "base64";
186
+ const TEXT_CONTENT_TYPE_PATTERNS = [
187
+ /^text\//,
188
+ /^application\/(json|javascript|xml|xml\+text|x-www-form-urlencoded)$/,
189
+ /^application\/.*\+json$/,
190
+ /^application\/.*\+xml$/,
191
+ /utf-?8/
192
+ ];
193
+ /**
194
+ * Converts a standard web Response object to AWS API Gateway compatible response format.
195
+ *
196
+ * This function transforms the Response headers and cookies into the format expected by
197
+ * AWS API Gateway proxy integrations. It handles both v1 and v2 API Gateway formats:
198
+ * - v1: Uses `multiValueHeaders` for cookies
199
+ * - v2: Uses `cookies` array for cookies
200
+ *
201
+ * The function processes all response headers, converting them to the appropriate format
202
+ * for AWS Lambda integration. Headers with multiple values are joined with commas,
203
+ * and cookies are handled specially for both API Gateway versions.
204
+ *
205
+ * @param response - The standard web Response object to convert
206
+ * @returns An object containing headers and cookies in AWS API Gateway format
207
+ * @throws {Error} If the response object is invalid or headers cannot be processed
208
+ */
209
+ function convertResponseToAWSResponse(response) {
210
+ if (!response || !response.headers) throw new Error("Invalid response: response must be a valid Response object with headers");
211
+ const headers = Object.create(null);
212
+ response.headers.forEach((value, key) => {
213
+ if (value !== void 0 && value !== null) headers[key] = Array.isArray(value) ? value.join(",") : String(value);
214
+ else if (value === null) headers[key] = "null";
215
+ else if (value === void 0) headers[key] = "undefined";
216
+ });
217
+ const cookies = typeof response.headers.getSetCookie === "function" ? response.headers.getSetCookie() : [];
218
+ if (cookies.length > 0) return {
219
+ headers,
220
+ cookies,
221
+ multiValueHeaders: { "set-cookie": cookies }
222
+ };
223
+ return { headers };
224
+ }
225
+ /**
226
+ * Converts a Response body to AWS API Gateway compatible format with proper encoding.
227
+ *
228
+ * AWS Lambda proxy integrations require special handling for binary content:
229
+ * - Text content types are returned as UTF-8 strings
230
+ * - Binary content types are base64 encoded with the `isBase64Encoded` flag set
231
+ *
232
+ * This function determines the appropriate encoding based on the response's content-type
233
+ * header and converts the body accordingly. It supports both text and binary content
234
+ * types, ensuring compatibility with API Gateway's payload encoding requirements.
235
+ *
236
+ * Binary media types should be configured as * in API Gateway settings.
237
+ * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html
238
+ *
239
+ * This function is heavily inspired by the `awsResponseBody` from `nitro`
240
+ * @see https://github.com/nitrojs/nitro/blob/v3/src/presets/aws-lambda/runtime/_utils.ts
241
+ *
242
+ * @param response - The standard web Response object containing the body to convert
243
+ * @returns A promise that resolves to an object with the encoded body and encoding flag
244
+ * @throws {Error} If the response body cannot be read or converted
245
+ */
246
+ async function convertBodyToAWSResponse(response) {
247
+ if (!response) throw new Error("Invalid response: response must be a valid Response object");
248
+ if (!response.body) return { body: DEFAULT_BODY };
249
+ try {
250
+ const buffer = await toBuffer(response.body);
251
+ const contentType = response.headers.get("content-type") || DEFAULT_CONTENT_TYPE;
252
+ if (isTextType(contentType)) return { body: buffer.toString(UTF8_ENCODING) };
253
+ else return {
254
+ body: buffer.toString(BASE64_ENCODING),
255
+ isBase64Encoded: true
256
+ };
257
+ } catch (error) {
258
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
259
+ throw new Error(`Failed to convert response body: ${errorMessage}`);
260
+ }
261
+ }
262
+ /**
263
+ * Determines if a content type should be treated as text content.
264
+ *
265
+ * This function uses a set of patterns to identify text-based content types:
266
+ * - Content types starting with "text/" (e.g., text/plain, text/html)
267
+ * - JavaScript, JSON, or XML content types
268
+ * - Content types containing UTF-8 encoding specification
269
+ *
270
+ * The function performs case-insensitive matching to handle various content type
271
+ * formats and specifications.
272
+ *
273
+ * @param contentType - The content type string to evaluate (e.g., "text/plain", "application/json")
274
+ * @returns True if the content type should be treated as text, false otherwise
275
+ */
276
+ function isTextType(contentType = DEFAULT_CONTENT_TYPE) {
277
+ if (!contentType) return false;
278
+ return TEXT_CONTENT_TYPE_PATTERNS.some((pattern) => pattern.test(contentType));
279
+ }
280
+ /**
281
+ * Converts a ReadableStream to a Buffer using Web Streams API.
282
+ *
283
+ * This function reads all chunks from a ReadableStream and concatenates them
284
+ * into a single Buffer. It uses the modern Web Streams API with WritableStream
285
+ * to efficiently process the stream data without blocking.
286
+ *
287
+ * The function handles stream errors gracefully and provides proper cleanup
288
+ * of stream resources. It's designed to work with Response.body streams
289
+ * from fetch API responses.
290
+ *
291
+ * @param data - The ReadableStream to convert to a Buffer
292
+ * @returns A promise that resolves to a Buffer containing all stream data
293
+ * @throws {Error} If the stream cannot be read or an error occurs during processing
294
+ */
295
+ function toBuffer(data) {
296
+ return new Promise((resolve, reject) => {
297
+ const chunks = [];
298
+ const writableStream = new WritableStream({
299
+ write(chunk) {
300
+ chunks.push(chunk);
301
+ },
302
+ close() {
303
+ resolve(Buffer.concat(chunks));
304
+ },
305
+ abort(reason) {
306
+ reject(/* @__PURE__ */ new Error("Stream aborted: " + String(reason)));
307
+ }
308
+ });
309
+ data.pipeTo(writableStream).catch(reject);
310
+ });
311
+ }
312
+
313
+ //#endregion
314
+ //#region src/Adapters/aws-lambda/index.ts
315
+ /**
316
+ * Converts a Vercube App instance into an AWS Lambda handler function for API Gateway integration.
317
+ *
318
+ * This function creates a serverless handler that bridges between AWS API Gateway events and
319
+ * the Vercube application framework. It handles the conversion of AWS Lambda events to standard
320
+ * web Request objects, processes them through the Vercube app, and converts the responses back
321
+ * to the format expected by AWS API Gateway.
322
+ *
323
+ * The handler supports both API Gateway v1 (APIGatewayProxyEvent) and v2 (APIGatewayProxyEventV2)
324
+ * event formats, automatically detecting and handling the appropriate format. It processes:
325
+ * - HTTP method, URL, headers, and body from the Lambda event
326
+ * - Converts them to a standard web Request object
327
+ * - Passes the request through the Vercube application
328
+ * - Converts the Response back to AWS API Gateway format
329
+ *
330
+ * The returned handler function can be directly used as an AWS Lambda function handler,
331
+ * providing seamless integration between AWS Lambda and Vercube applications.
332
+ *
333
+ * @param app - The Vercube App instance that will handle the requests
334
+ * @returns An async function that accepts AWS API Gateway events and returns API Gateway responses
335
+ *
336
+ * @see {@link convertEventToRequest} For details on event to request conversion
337
+ * @see {@link convertResponseToAWSResponse} For details on response header conversion
338
+ * @see {@link convertBodyToAWSResponse} For details on response body conversion
339
+ */
340
+ function toServerlessHandler(app) {
341
+ return async (event) => {
342
+ const request = convertEventToRequest(event);
343
+ const response = await app.fetch(request);
344
+ return {
345
+ statusCode: response.status,
346
+ ...convertResponseToAWSResponse(response),
347
+ ...await convertBodyToAWSResponse(response)
348
+ };
349
+ };
350
+ }
351
+
352
+ //#endregion
353
+ export { toServerlessHandler };
@@ -0,0 +1,6 @@
1
+ import { MaybePromise } from "@vercube/core";
2
+
3
+ //#region src/Types/ServerlessTypes.d.ts
4
+ type ServerlessHandler<Event = unknown, HandlerResponse = unknown> = (event: Event) => MaybePromise<HandlerResponse>;
5
+ //#endregion
6
+ export { ServerlessHandler };
@@ -0,0 +1,2 @@
1
+ import { ServerlessHandler } from "./ServerlessTypes-lXnSKHNA.mjs";
2
+ export { ServerlessHandler };
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ export { };
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@vercube/serverless",
3
+ "version": "0.0.22",
4
+ "description": "Serverless module for Vercube framework",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/vercube/vercube.git",
8
+ "directory": "packages/serverless"
9
+ },
10
+ "license": "MIT",
11
+ "sideEffects": false,
12
+ "type": "module",
13
+ "main": "./dist/index.mjs",
14
+ "module": "./dist/index.mjs",
15
+ "exports": {
16
+ ".": "./dist/index.mjs",
17
+ "./package.json": "./package.json",
18
+ "./aws-lambda": "./dist/Adapters/aws-lambda/index.mjs"
19
+ },
20
+ "types": "./dist/index.d.mts",
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "keywords": [
26
+ "vercube",
27
+ "serverless",
28
+ "aws",
29
+ "lambda",
30
+ "aws-lambda",
31
+ "aws-serverless",
32
+ "aws-api-gateway",
33
+ "aws-apigw",
34
+ "aws-apigw-lambda"
35
+ ],
36
+ "dependencies": {
37
+ "ufo": "1.6.1",
38
+ "@vercube/core": "0.0.22",
39
+ "@vercube/di": "0.0.22"
40
+ },
41
+ "devDependencies": {
42
+ "@types/aws-lambda": "8.10.152",
43
+ "@azure/functions": "4.7.2-preview"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "scripts": {
49
+ "build": "tsdown --config tsdown.config.ts"
50
+ }
51
+ }