@mionjs/platform-vercel 0.8.0-alpha.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.
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const src_vercelHandler = require("./src/vercelHandler.cjs");
4
+ const src_constants = require("./src/constants.cjs");
5
+ exports.createVercelHandler = src_vercelHandler.createVercelHandler;
6
+ exports.resetVercelHandlerOpts = src_vercelHandler.resetVercelHandlerOpts;
7
+ exports.setVercelHandlerOpts = src_vercelHandler.setVercelHandlerOpts;
8
+ exports.DEFAULT_VERCEL_OPTIONS = src_constants.DEFAULT_VERCEL_OPTIONS;
9
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,3 @@
1
+ export * from './src/types.ts';
2
+ export * from './src/vercelHandler.ts';
3
+ export * from './src/constants.ts';
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const DEFAULT_VERCEL_OPTIONS = {
4
+ defaultResponseHeaders: {}
5
+ };
6
+ exports.DEFAULT_VERCEL_OPTIONS = DEFAULT_VERCEL_OPTIONS;
7
+ //# sourceMappingURL=constants.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.cjs","sources":["../../../src/constants.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {VercelHandlerOptions} from './types.ts';\n\nexport const DEFAULT_VERCEL_OPTIONS: VercelHandlerOptions = {\n defaultResponseHeaders: {},\n};\n"],"names":[],"mappings":";;AASO,MAAM,yBAA+C;AAAA,EACxD,wBAAwB,CAAA;AAC5B;;"}
@@ -0,0 +1,2 @@
1
+ import { VercelHandlerOptions } from './types.ts';
2
+ export declare const DEFAULT_VERCEL_OPTIONS: VercelHandlerOptions;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const http = require("http");
4
+ const https = require("https");
5
+ const src_vercelHandler = require("./vercelHandler.cjs");
6
+ const DEFAULT_DEV_SERVER_OPTIONS = {
7
+ port: 3e3,
8
+ protocol: "http"
9
+ };
10
+ async function nodeIncomingToRequest(req) {
11
+ const chunks = [];
12
+ for await (const chunk of req) {
13
+ chunks.push(chunk);
14
+ }
15
+ const body = Buffer.concat(chunks);
16
+ const host = req.headers.host || "localhost";
17
+ const protocol = "http";
18
+ const url = `${protocol}://${host}${req.url || "/"}`;
19
+ const headers = new Headers();
20
+ for (const [key, value] of Object.entries(req.headers)) {
21
+ if (value === void 0) continue;
22
+ if (Array.isArray(value)) {
23
+ for (const v of value) headers.append(key, v);
24
+ } else {
25
+ headers.set(key, value);
26
+ }
27
+ }
28
+ return new Request(url, {
29
+ method: req.method || "GET",
30
+ headers,
31
+ body: body.length > 0 ? body : void 0
32
+ });
33
+ }
34
+ async function writeWebResponseToNode(webResponse, res) {
35
+ res.statusCode = webResponse.status;
36
+ webResponse.headers.forEach((value, key) => {
37
+ res.setHeader(key, value);
38
+ });
39
+ const buffer = Buffer.from(await webResponse.arrayBuffer());
40
+ res.end(buffer);
41
+ }
42
+ function startBunDevServer(handler, options) {
43
+ const url = `${options.protocol}://localhost:${options.port}`;
44
+ const server = globalThis.Bun.serve({
45
+ port: options.port,
46
+ fetch: handler.POST
47
+ });
48
+ console.log(`mion vercel dev server (bun) running on ${url}`);
49
+ const shutdownHandler = () => {
50
+ console.log(`Shutting down mion vercel dev server on ${url}`);
51
+ server.stop(true);
52
+ process.exit(0);
53
+ };
54
+ process.on("SIGINT", shutdownHandler);
55
+ process.on("SIGTERM", shutdownHandler);
56
+ return server;
57
+ }
58
+ function startNodeDevServer(handler, options) {
59
+ return new Promise((resolve, reject) => {
60
+ const requestListener = async (req, res) => {
61
+ try {
62
+ const webRequest = await nodeIncomingToRequest(req);
63
+ const webResponse = await handler.POST(webRequest);
64
+ await writeWebResponseToNode(webResponse, res);
65
+ } catch (err) {
66
+ if (!res.writableEnded) {
67
+ res.statusCode = 500;
68
+ res.end("Internal Server Error");
69
+ } else {
70
+ console.error("Error handling request:", err);
71
+ }
72
+ }
73
+ };
74
+ const server = options.protocol === "https" ? https.createServer(requestListener) : http.createServer(requestListener);
75
+ server.on("error", reject);
76
+ server.listen(options.port, () => {
77
+ console.log(`mion vercel dev server (node) running on ${options.protocol}://localhost:${options.port}`);
78
+ resolve(server);
79
+ });
80
+ const shutdownHandler = () => {
81
+ console.log(`Shutting down mion vercel dev server on ${options.protocol}://localhost:${options.port}`);
82
+ server.close(() => process.exit(0));
83
+ };
84
+ process.on("SIGINT", shutdownHandler);
85
+ process.on("SIGTERM", shutdownHandler);
86
+ });
87
+ }
88
+ async function startVercelDevServer(options) {
89
+ const opts = { ...DEFAULT_DEV_SERVER_OPTIONS, ...options };
90
+ const handler = src_vercelHandler.createVercelHandler();
91
+ if (typeof globalThis?.Bun !== "undefined") return startBunDevServer(handler, opts);
92
+ return startNodeDevServer(handler, opts);
93
+ }
94
+ exports.startVercelDevServer = startVercelDevServer;
95
+ //# sourceMappingURL=devServer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devServer.cjs","sources":["../../../src/devServer.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {createServer as createHttp} from 'http';\nimport {createServer as createHttps} from 'https';\nimport {createVercelHandler} from './vercelHandler.ts';\nimport type {DevServerOptions} from './types.ts';\nimport type {IncomingMessage, Server as HttpServer, ServerResponse} from 'http';\nimport type {Server as HttpsServer} from 'https';\n\nconst DEFAULT_DEV_SERVER_OPTIONS: DevServerOptions = {\n port: 3000,\n protocol: 'http',\n};\n\n/** Converts Node's IncomingMessage to a Web standard Request */\nasync function nodeIncomingToRequest(req: IncomingMessage): Promise<Request> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk as Buffer);\n }\n const body = Buffer.concat(chunks);\n const host = req.headers.host || 'localhost';\n const protocol = 'http';\n const url = `${protocol}://${host}${req.url || '/'}`;\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const v of value) headers.append(key, v);\n } else {\n headers.set(key, value);\n }\n }\n return new Request(url, {\n method: req.method || 'GET',\n headers,\n body: body.length > 0 ? body : undefined,\n });\n}\n\n/** Writes a Web standard Response to Node's ServerResponse */\nasync function writeWebResponseToNode(webResponse: Response, res: ServerResponse): Promise<void> {\n res.statusCode = webResponse.status;\n webResponse.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n const buffer = Buffer.from(await webResponse.arrayBuffer());\n res.end(buffer);\n}\n\n/** Starts a dev server using Bun's native Request/Response support */\nfunction startBunDevServer(handler: ReturnType<typeof createVercelHandler>, options: DevServerOptions): any {\n const url = `${options.protocol}://localhost:${options.port}`;\n const server = (globalThis as any).Bun.serve({\n port: options.port,\n fetch: handler.POST,\n });\n console.log(`mion vercel dev server (bun) running on ${url}`);\n\n const shutdownHandler = () => {\n console.log(`Shutting down mion vercel dev server on ${url}`);\n server.stop(true);\n process.exit(0);\n };\n process.on('SIGINT', shutdownHandler);\n process.on('SIGTERM', shutdownHandler);\n\n return server;\n}\n\n/** Starts a dev server using Node's http/https module with Request/Response adapters */\nfunction startNodeDevServer(\n handler: ReturnType<typeof createVercelHandler>,\n options: DevServerOptions\n): Promise<HttpServer | HttpsServer> {\n return new Promise((resolve, reject) => {\n const requestListener = async (req: IncomingMessage, res: ServerResponse) => {\n try {\n const webRequest = await nodeIncomingToRequest(req);\n const webResponse = await handler.POST(webRequest);\n await writeWebResponseToNode(webResponse, res);\n } catch (err) {\n if (!res.writableEnded) {\n res.statusCode = 500;\n res.end('Internal Server Error');\n } else {\n console.error('Error handling request:', err);\n }\n }\n };\n\n const server = options.protocol === 'https' ? createHttps(requestListener) : createHttp(requestListener);\n\n server.on('error', reject);\n\n server.listen(options.port, () => {\n console.log(`mion vercel dev server (node) running on ${options.protocol}://localhost:${options.port}`);\n resolve(server);\n });\n\n const shutdownHandler = () => {\n console.log(`Shutting down mion vercel dev server on ${options.protocol}://localhost:${options.port}`);\n server.close(() => process.exit(0));\n };\n process.on('SIGINT', shutdownHandler);\n process.on('SIGTERM', shutdownHandler);\n });\n}\n\n/** Starts a local dev server for the Vercel handler. Auto-detects Bun or Node runtime. */\nexport async function startVercelDevServer(options?: Partial<DevServerOptions>): Promise<HttpServer | HttpsServer | any> {\n const opts: DevServerOptions = {...DEFAULT_DEV_SERVER_OPTIONS, ...options};\n const handler = createVercelHandler();\n if (typeof (globalThis as any)?.Bun !== 'undefined') return startBunDevServer(handler, opts);\n return startNodeDevServer(handler, opts);\n}\n"],"names":["createHttps","createHttp","createVercelHandler"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { DevServerOptions } from './types.ts';
2
+ import { Server as HttpServer } from 'http';
3
+ import { Server as HttpsServer } from 'https';
4
+ export declare function startVercelDevServer(options?: Partial<DevServerOptions>): Promise<HttpServer | HttpsServer | any>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ export interface VercelHandlerOptions {
2
+ defaultResponseHeaders: Record<string, string>;
3
+ }
4
+ export interface DevServerOptions {
5
+ port: number;
6
+ protocol: 'http' | 'https';
7
+ }
8
+ export declare type __ΩVercelHandlerOptions = any[];
9
+ export declare type __ΩDevServerOptions = any[];
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const router = require("@mionjs/router");
4
+ const src_constants = require("./constants.cjs");
5
+ const core = require("@mionjs/core");
6
+ let vercelOptions = { ...src_constants.DEFAULT_VERCEL_OPTIONS };
7
+ let defaultHeaders = [["server", "@mionjs"]];
8
+ function resetVercelHandlerOpts() {
9
+ vercelOptions = { ...src_constants.DEFAULT_VERCEL_OPTIONS };
10
+ defaultHeaders = [["server", "@mionjs"]];
11
+ router.resetRouter();
12
+ }
13
+ function setVercelHandlerOpts(options) {
14
+ vercelOptions = {
15
+ ...vercelOptions,
16
+ ...options
17
+ };
18
+ defaultHeaders = [["server", "@mionjs"], ...Object.entries(vercelOptions.defaultResponseHeaders)];
19
+ return vercelOptions;
20
+ }
21
+ async function handleRequest(req) {
22
+ const reqUrl = req.url;
23
+ const urlObj = new URL(reqUrl);
24
+ const path = urlObj.pathname;
25
+ const urlQuery = urlObj.search ? urlObj.search.slice(1) : void 0;
26
+ const contentType = req.headers.get("content-type") || "";
27
+ const isBinary = contentType.startsWith("application/octet-stream");
28
+ let rawBody = req.body ? isBinary ? await req.arrayBuffer() : await req.json() : void 0;
29
+ let reqBodyType = isBinary ? core.SerializerModes.binary : core.SerializerModes.json;
30
+ const queryBody = router.decodeQueryBody(urlQuery, rawBody);
31
+ if (queryBody) {
32
+ rawBody = queryBody.rawBody;
33
+ reqBodyType = queryBody.bodyType;
34
+ }
35
+ const responseHeaders = new Headers(defaultHeaders);
36
+ try {
37
+ const platformResp = await router.dispatchRoute(
38
+ path,
39
+ rawBody,
40
+ req.headers,
41
+ responseHeaders,
42
+ req,
43
+ void 0,
44
+ reqBodyType,
45
+ urlQuery
46
+ );
47
+ return reply(platformResp, responseHeaders);
48
+ } catch (e) {
49
+ const error = e instanceof core.RpcError ? e : new core.RpcError({
50
+ publicMessage: "Unknown Error",
51
+ type: "unknown-error",
52
+ originalError: e
53
+ });
54
+ return fatalFail(error, responseHeaders);
55
+ }
56
+ }
57
+ function createVercelHandler() {
58
+ return {
59
+ GET: handleRequest,
60
+ POST: handleRequest,
61
+ PUT: handleRequest,
62
+ DELETE: handleRequest,
63
+ PATCH: handleRequest
64
+ };
65
+ }
66
+ function fatalFail(err, responseHeaders) {
67
+ const routeResponse = router.getRouterFatalErrorResponse(err, responseHeaders);
68
+ return reply(routeResponse, responseHeaders);
69
+ }
70
+ function reply(mionResp, responseHeaders) {
71
+ const bodyType = mionResp.serializer;
72
+ switch (bodyType) {
73
+ case core.SerializerModes.stringifyJson: {
74
+ return new Response(mionResp.rawBody, {
75
+ status: mionResp.statusCode,
76
+ headers: responseHeaders
77
+ });
78
+ }
79
+ case core.SerializerModes.json: {
80
+ return Response.json(mionResp.body, {
81
+ status: mionResp.statusCode,
82
+ headers: responseHeaders
83
+ });
84
+ }
85
+ case core.SerializerModes.binary: {
86
+ const serializer = mionResp.binSerializer;
87
+ responseHeaders.set("content-length", String(serializer.getLength()));
88
+ const response = new Response(serializer.getBufferView(), {
89
+ status: mionResp.statusCode,
90
+ headers: responseHeaders
91
+ });
92
+ serializer.markAsEnded();
93
+ return response;
94
+ }
95
+ default: {
96
+ const error = new core.RpcError({
97
+ publicMessage: "unknown-mion-response-format",
98
+ type: "unknown-error",
99
+ errorData: { bodyType }
100
+ });
101
+ return fatalFail(error, responseHeaders);
102
+ }
103
+ }
104
+ }
105
+ exports.createVercelHandler = createVercelHandler;
106
+ exports.resetVercelHandlerOpts = resetVercelHandlerOpts;
107
+ exports.setVercelHandlerOpts = setVercelHandlerOpts;
108
+ //# sourceMappingURL=vercelHandler.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercelHandler.cjs","sources":["../../../src/vercelHandler.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {dispatchRoute, getRouterFatalErrorResponse, resetRouter, decodeQueryBody, MionResponse} from '@mionjs/router';\nimport {DEFAULT_VERCEL_OPTIONS} from './constants.ts';\nimport type {VercelHandlerOptions} from './types.ts';\nimport {SerializerModes} from '@mionjs/core';\nimport type {SerializerCode} from '@mionjs/core';\nimport {RpcError} from '@mionjs/core';\n\n// ############# PRIVATE STATE #############\n\nlet vercelOptions: Readonly<VercelHandlerOptions> = {...DEFAULT_VERCEL_OPTIONS};\nlet defaultHeaders: [string, string][] = [['server', '@mionjs']];\n\nexport function resetVercelHandlerOpts() {\n vercelOptions = {...DEFAULT_VERCEL_OPTIONS};\n defaultHeaders = [['server', '@mionjs']];\n resetRouter();\n}\n\nexport function setVercelHandlerOpts(options?: Partial<VercelHandlerOptions>) {\n vercelOptions = {\n ...vercelOptions,\n ...options,\n };\n defaultHeaders = [['server', '@mionjs'], ...Object.entries(vercelOptions.defaultResponseHeaders)];\n return vercelOptions;\n}\n\n/** Main handler for Web standard Request -> Response */\nasync function handleRequest(req: Request): Promise<Response> {\n const reqUrl = req.url;\n const urlObj = new URL(reqUrl);\n const path = urlObj.pathname;\n const urlQuery = urlObj.search ? urlObj.search.slice(1) : undefined;\n const contentType = req.headers.get('content-type') || '';\n const isBinary = contentType.startsWith('application/octet-stream');\n let rawBody: any = req.body\n ? isBinary\n ? await req.arrayBuffer()\n : ((await req.json()) as Record<string, unknown>)\n : undefined;\n let reqBodyType: SerializerCode = isBinary ? SerializerModes.binary : SerializerModes.json;\n const queryBody = decodeQueryBody(urlQuery, rawBody);\n if (queryBody) {\n rawBody = queryBody.rawBody;\n reqBodyType = queryBody.bodyType;\n }\n const responseHeaders = new Headers(defaultHeaders);\n\n try {\n const platformResp = await dispatchRoute(\n path,\n rawBody,\n req.headers,\n responseHeaders,\n req,\n undefined,\n reqBodyType,\n urlQuery\n );\n return reply(platformResp, responseHeaders);\n } catch (e) {\n const error =\n e instanceof RpcError\n ? e\n : new RpcError({\n publicMessage: 'Unknown Error',\n type: 'unknown-error',\n originalError: e as Error,\n });\n return fatalFail(error, responseHeaders);\n }\n}\n\n/** Creates Next.js App Router / Vercel serverless route handlers */\nexport function createVercelHandler() {\n return {\n GET: handleRequest,\n POST: handleRequest,\n PUT: handleRequest,\n DELETE: handleRequest,\n PATCH: handleRequest,\n };\n}\n\nfunction fatalFail(err: RpcError<string>, responseHeaders: any): Response {\n const routeResponse = getRouterFatalErrorResponse(err, responseHeaders);\n return reply(routeResponse, responseHeaders);\n}\n\nfunction reply(mionResp: MionResponse, responseHeaders: any): Response {\n const bodyType = mionResp.serializer;\n switch (bodyType) {\n case SerializerModes.stringifyJson: {\n return new Response(mionResp.rawBody as string, {\n status: mionResp.statusCode,\n headers: responseHeaders,\n });\n }\n case SerializerModes.json: {\n return Response.json(mionResp.body, {\n status: mionResp.statusCode,\n headers: responseHeaders,\n });\n }\n case SerializerModes.binary: {\n const serializer = mionResp.binSerializer!;\n responseHeaders.set('content-length', String(serializer.getLength()));\n const response = new Response(serializer.getBufferView(), {\n status: mionResp.statusCode,\n headers: responseHeaders,\n });\n serializer.markAsEnded();\n return response;\n }\n default: {\n const error = new RpcError({\n publicMessage: 'unknown-mion-response-format',\n type: 'unknown-error',\n errorData: {bodyType},\n });\n return fatalFail(error, responseHeaders);\n }\n }\n}\n"],"names":["DEFAULT_VERCEL_OPTIONS","resetRouter","SerializerModes","decodeQueryBody","dispatchRoute","RpcError","getRouterFatalErrorResponse"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { VercelHandlerOptions } from './types.ts';
2
+ export declare function resetVercelHandlerOpts(): void;
3
+ export declare function setVercelHandlerOpts(options?: Partial<VercelHandlerOptions>): Readonly<VercelHandlerOptions>;
4
+ declare function handleRequest(req: Request): Promise<Response>;
5
+ export declare function createVercelHandler(): {
6
+ GET: typeof handleRequest;
7
+ POST: typeof handleRequest;
8
+ PUT: typeof handleRequest;
9
+ DELETE: typeof handleRequest;
10
+ PATCH: typeof handleRequest;
11
+ };
12
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './src/types.ts';
2
+ export * from './src/vercelHandler.ts';
3
+ export * from './src/constants.ts';
@@ -0,0 +1,9 @@
1
+ import { createVercelHandler, resetVercelHandlerOpts, setVercelHandlerOpts } from "./src/vercelHandler.js";
2
+ import { DEFAULT_VERCEL_OPTIONS } from "./src/constants.js";
3
+ export {
4
+ DEFAULT_VERCEL_OPTIONS,
5
+ createVercelHandler,
6
+ resetVercelHandlerOpts,
7
+ setVercelHandlerOpts
8
+ };
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -0,0 +1,2 @@
1
+ import { VercelHandlerOptions } from './types.ts';
2
+ export declare const DEFAULT_VERCEL_OPTIONS: VercelHandlerOptions;
@@ -0,0 +1,7 @@
1
+ const DEFAULT_VERCEL_OPTIONS = {
2
+ defaultResponseHeaders: {}
3
+ };
4
+ export {
5
+ DEFAULT_VERCEL_OPTIONS
6
+ };
7
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../../src/constants.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {VercelHandlerOptions} from './types.ts';\n\nexport const DEFAULT_VERCEL_OPTIONS: VercelHandlerOptions = {\n defaultResponseHeaders: {},\n};\n"],"names":[],"mappings":"AASO,MAAM,yBAA+C;AAAA,EACxD,wBAAwB,CAAA;AAC5B;"}
@@ -0,0 +1,4 @@
1
+ import { DevServerOptions } from './types.ts';
2
+ import { Server as HttpServer } from 'http';
3
+ import { Server as HttpsServer } from 'https';
4
+ export declare function startVercelDevServer(options?: Partial<DevServerOptions>): Promise<HttpServer | HttpsServer | any>;
@@ -0,0 +1,95 @@
1
+ import { createServer as createServer$1 } from "http";
2
+ import { createServer } from "https";
3
+ import { createVercelHandler } from "./vercelHandler.js";
4
+ const DEFAULT_DEV_SERVER_OPTIONS = {
5
+ port: 3e3,
6
+ protocol: "http"
7
+ };
8
+ async function nodeIncomingToRequest(req) {
9
+ const chunks = [];
10
+ for await (const chunk of req) {
11
+ chunks.push(chunk);
12
+ }
13
+ const body = Buffer.concat(chunks);
14
+ const host = req.headers.host || "localhost";
15
+ const protocol = "http";
16
+ const url = `${protocol}://${host}${req.url || "/"}`;
17
+ const headers = new Headers();
18
+ for (const [key, value] of Object.entries(req.headers)) {
19
+ if (value === void 0) continue;
20
+ if (Array.isArray(value)) {
21
+ for (const v of value) headers.append(key, v);
22
+ } else {
23
+ headers.set(key, value);
24
+ }
25
+ }
26
+ return new Request(url, {
27
+ method: req.method || "GET",
28
+ headers,
29
+ body: body.length > 0 ? body : void 0
30
+ });
31
+ }
32
+ async function writeWebResponseToNode(webResponse, res) {
33
+ res.statusCode = webResponse.status;
34
+ webResponse.headers.forEach((value, key) => {
35
+ res.setHeader(key, value);
36
+ });
37
+ const buffer = Buffer.from(await webResponse.arrayBuffer());
38
+ res.end(buffer);
39
+ }
40
+ function startBunDevServer(handler, options) {
41
+ const url = `${options.protocol}://localhost:${options.port}`;
42
+ const server = globalThis.Bun.serve({
43
+ port: options.port,
44
+ fetch: handler.POST
45
+ });
46
+ console.log(`mion vercel dev server (bun) running on ${url}`);
47
+ const shutdownHandler = () => {
48
+ console.log(`Shutting down mion vercel dev server on ${url}`);
49
+ server.stop(true);
50
+ process.exit(0);
51
+ };
52
+ process.on("SIGINT", shutdownHandler);
53
+ process.on("SIGTERM", shutdownHandler);
54
+ return server;
55
+ }
56
+ function startNodeDevServer(handler, options) {
57
+ return new Promise((resolve, reject) => {
58
+ const requestListener = async (req, res) => {
59
+ try {
60
+ const webRequest = await nodeIncomingToRequest(req);
61
+ const webResponse = await handler.POST(webRequest);
62
+ await writeWebResponseToNode(webResponse, res);
63
+ } catch (err) {
64
+ if (!res.writableEnded) {
65
+ res.statusCode = 500;
66
+ res.end("Internal Server Error");
67
+ } else {
68
+ console.error("Error handling request:", err);
69
+ }
70
+ }
71
+ };
72
+ const server = options.protocol === "https" ? createServer(requestListener) : createServer$1(requestListener);
73
+ server.on("error", reject);
74
+ server.listen(options.port, () => {
75
+ console.log(`mion vercel dev server (node) running on ${options.protocol}://localhost:${options.port}`);
76
+ resolve(server);
77
+ });
78
+ const shutdownHandler = () => {
79
+ console.log(`Shutting down mion vercel dev server on ${options.protocol}://localhost:${options.port}`);
80
+ server.close(() => process.exit(0));
81
+ };
82
+ process.on("SIGINT", shutdownHandler);
83
+ process.on("SIGTERM", shutdownHandler);
84
+ });
85
+ }
86
+ async function startVercelDevServer(options) {
87
+ const opts = { ...DEFAULT_DEV_SERVER_OPTIONS, ...options };
88
+ const handler = createVercelHandler();
89
+ if (typeof globalThis?.Bun !== "undefined") return startBunDevServer(handler, opts);
90
+ return startNodeDevServer(handler, opts);
91
+ }
92
+ export {
93
+ startVercelDevServer
94
+ };
95
+ //# sourceMappingURL=devServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devServer.js","sources":["../../../src/devServer.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {createServer as createHttp} from 'http';\nimport {createServer as createHttps} from 'https';\nimport {createVercelHandler} from './vercelHandler.ts';\nimport type {DevServerOptions} from './types.ts';\nimport type {IncomingMessage, Server as HttpServer, ServerResponse} from 'http';\nimport type {Server as HttpsServer} from 'https';\n\nconst DEFAULT_DEV_SERVER_OPTIONS: DevServerOptions = {\n port: 3000,\n protocol: 'http',\n};\n\n/** Converts Node's IncomingMessage to a Web standard Request */\nasync function nodeIncomingToRequest(req: IncomingMessage): Promise<Request> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk as Buffer);\n }\n const body = Buffer.concat(chunks);\n const host = req.headers.host || 'localhost';\n const protocol = 'http';\n const url = `${protocol}://${host}${req.url || '/'}`;\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const v of value) headers.append(key, v);\n } else {\n headers.set(key, value);\n }\n }\n return new Request(url, {\n method: req.method || 'GET',\n headers,\n body: body.length > 0 ? body : undefined,\n });\n}\n\n/** Writes a Web standard Response to Node's ServerResponse */\nasync function writeWebResponseToNode(webResponse: Response, res: ServerResponse): Promise<void> {\n res.statusCode = webResponse.status;\n webResponse.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n const buffer = Buffer.from(await webResponse.arrayBuffer());\n res.end(buffer);\n}\n\n/** Starts a dev server using Bun's native Request/Response support */\nfunction startBunDevServer(handler: ReturnType<typeof createVercelHandler>, options: DevServerOptions): any {\n const url = `${options.protocol}://localhost:${options.port}`;\n const server = (globalThis as any).Bun.serve({\n port: options.port,\n fetch: handler.POST,\n });\n console.log(`mion vercel dev server (bun) running on ${url}`);\n\n const shutdownHandler = () => {\n console.log(`Shutting down mion vercel dev server on ${url}`);\n server.stop(true);\n process.exit(0);\n };\n process.on('SIGINT', shutdownHandler);\n process.on('SIGTERM', shutdownHandler);\n\n return server;\n}\n\n/** Starts a dev server using Node's http/https module with Request/Response adapters */\nfunction startNodeDevServer(\n handler: ReturnType<typeof createVercelHandler>,\n options: DevServerOptions\n): Promise<HttpServer | HttpsServer> {\n return new Promise((resolve, reject) => {\n const requestListener = async (req: IncomingMessage, res: ServerResponse) => {\n try {\n const webRequest = await nodeIncomingToRequest(req);\n const webResponse = await handler.POST(webRequest);\n await writeWebResponseToNode(webResponse, res);\n } catch (err) {\n if (!res.writableEnded) {\n res.statusCode = 500;\n res.end('Internal Server Error');\n } else {\n console.error('Error handling request:', err);\n }\n }\n };\n\n const server = options.protocol === 'https' ? createHttps(requestListener) : createHttp(requestListener);\n\n server.on('error', reject);\n\n server.listen(options.port, () => {\n console.log(`mion vercel dev server (node) running on ${options.protocol}://localhost:${options.port}`);\n resolve(server);\n });\n\n const shutdownHandler = () => {\n console.log(`Shutting down mion vercel dev server on ${options.protocol}://localhost:${options.port}`);\n server.close(() => process.exit(0));\n };\n process.on('SIGINT', shutdownHandler);\n process.on('SIGTERM', shutdownHandler);\n });\n}\n\n/** Starts a local dev server for the Vercel handler. Auto-detects Bun or Node runtime. */\nexport async function startVercelDevServer(options?: Partial<DevServerOptions>): Promise<HttpServer | HttpsServer | any> {\n const opts: DevServerOptions = {...DEFAULT_DEV_SERVER_OPTIONS, ...options};\n const handler = createVercelHandler();\n if (typeof (globalThis as any)?.Bun !== 'undefined') return startBunDevServer(handler, opts);\n return startNodeDevServer(handler, opts);\n}\n"],"names":["createHttps","createHttp"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface VercelHandlerOptions {
2
+ defaultResponseHeaders: Record<string, string>;
3
+ }
4
+ export interface DevServerOptions {
5
+ port: number;
6
+ protocol: 'http' | 'https';
7
+ }
8
+ export declare type __ΩVercelHandlerOptions = any[];
9
+ export declare type __ΩDevServerOptions = any[];
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { VercelHandlerOptions } from './types.ts';
2
+ export declare function resetVercelHandlerOpts(): void;
3
+ export declare function setVercelHandlerOpts(options?: Partial<VercelHandlerOptions>): Readonly<VercelHandlerOptions>;
4
+ declare function handleRequest(req: Request): Promise<Response>;
5
+ export declare function createVercelHandler(): {
6
+ GET: typeof handleRequest;
7
+ POST: typeof handleRequest;
8
+ PUT: typeof handleRequest;
9
+ DELETE: typeof handleRequest;
10
+ PATCH: typeof handleRequest;
11
+ };
12
+ export {};
@@ -0,0 +1,108 @@
1
+ import { resetRouter, decodeQueryBody, dispatchRoute, getRouterFatalErrorResponse } from "@mionjs/router";
2
+ import { DEFAULT_VERCEL_OPTIONS } from "./constants.js";
3
+ import { SerializerModes, RpcError } from "@mionjs/core";
4
+ let vercelOptions = { ...DEFAULT_VERCEL_OPTIONS };
5
+ let defaultHeaders = [["server", "@mionjs"]];
6
+ function resetVercelHandlerOpts() {
7
+ vercelOptions = { ...DEFAULT_VERCEL_OPTIONS };
8
+ defaultHeaders = [["server", "@mionjs"]];
9
+ resetRouter();
10
+ }
11
+ function setVercelHandlerOpts(options) {
12
+ vercelOptions = {
13
+ ...vercelOptions,
14
+ ...options
15
+ };
16
+ defaultHeaders = [["server", "@mionjs"], ...Object.entries(vercelOptions.defaultResponseHeaders)];
17
+ return vercelOptions;
18
+ }
19
+ async function handleRequest(req) {
20
+ const reqUrl = req.url;
21
+ const urlObj = new URL(reqUrl);
22
+ const path = urlObj.pathname;
23
+ const urlQuery = urlObj.search ? urlObj.search.slice(1) : void 0;
24
+ const contentType = req.headers.get("content-type") || "";
25
+ const isBinary = contentType.startsWith("application/octet-stream");
26
+ let rawBody = req.body ? isBinary ? await req.arrayBuffer() : await req.json() : void 0;
27
+ let reqBodyType = isBinary ? SerializerModes.binary : SerializerModes.json;
28
+ const queryBody = decodeQueryBody(urlQuery, rawBody);
29
+ if (queryBody) {
30
+ rawBody = queryBody.rawBody;
31
+ reqBodyType = queryBody.bodyType;
32
+ }
33
+ const responseHeaders = new Headers(defaultHeaders);
34
+ try {
35
+ const platformResp = await dispatchRoute(
36
+ path,
37
+ rawBody,
38
+ req.headers,
39
+ responseHeaders,
40
+ req,
41
+ void 0,
42
+ reqBodyType,
43
+ urlQuery
44
+ );
45
+ return reply(platformResp, responseHeaders);
46
+ } catch (e) {
47
+ const error = e instanceof RpcError ? e : new RpcError({
48
+ publicMessage: "Unknown Error",
49
+ type: "unknown-error",
50
+ originalError: e
51
+ });
52
+ return fatalFail(error, responseHeaders);
53
+ }
54
+ }
55
+ function createVercelHandler() {
56
+ return {
57
+ GET: handleRequest,
58
+ POST: handleRequest,
59
+ PUT: handleRequest,
60
+ DELETE: handleRequest,
61
+ PATCH: handleRequest
62
+ };
63
+ }
64
+ function fatalFail(err, responseHeaders) {
65
+ const routeResponse = getRouterFatalErrorResponse(err, responseHeaders);
66
+ return reply(routeResponse, responseHeaders);
67
+ }
68
+ function reply(mionResp, responseHeaders) {
69
+ const bodyType = mionResp.serializer;
70
+ switch (bodyType) {
71
+ case SerializerModes.stringifyJson: {
72
+ return new Response(mionResp.rawBody, {
73
+ status: mionResp.statusCode,
74
+ headers: responseHeaders
75
+ });
76
+ }
77
+ case SerializerModes.json: {
78
+ return Response.json(mionResp.body, {
79
+ status: mionResp.statusCode,
80
+ headers: responseHeaders
81
+ });
82
+ }
83
+ case SerializerModes.binary: {
84
+ const serializer = mionResp.binSerializer;
85
+ responseHeaders.set("content-length", String(serializer.getLength()));
86
+ const response = new Response(serializer.getBufferView(), {
87
+ status: mionResp.statusCode,
88
+ headers: responseHeaders
89
+ });
90
+ serializer.markAsEnded();
91
+ return response;
92
+ }
93
+ default: {
94
+ const error = new RpcError({
95
+ publicMessage: "unknown-mion-response-format",
96
+ type: "unknown-error",
97
+ errorData: { bodyType }
98
+ });
99
+ return fatalFail(error, responseHeaders);
100
+ }
101
+ }
102
+ }
103
+ export {
104
+ createVercelHandler,
105
+ resetVercelHandlerOpts,
106
+ setVercelHandlerOpts
107
+ };
108
+ //# sourceMappingURL=vercelHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercelHandler.js","sources":["../../../src/vercelHandler.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {dispatchRoute, getRouterFatalErrorResponse, resetRouter, decodeQueryBody, MionResponse} from '@mionjs/router';\nimport {DEFAULT_VERCEL_OPTIONS} from './constants.ts';\nimport type {VercelHandlerOptions} from './types.ts';\nimport {SerializerModes} from '@mionjs/core';\nimport type {SerializerCode} from '@mionjs/core';\nimport {RpcError} from '@mionjs/core';\n\n// ############# PRIVATE STATE #############\n\nlet vercelOptions: Readonly<VercelHandlerOptions> = {...DEFAULT_VERCEL_OPTIONS};\nlet defaultHeaders: [string, string][] = [['server', '@mionjs']];\n\nexport function resetVercelHandlerOpts() {\n vercelOptions = {...DEFAULT_VERCEL_OPTIONS};\n defaultHeaders = [['server', '@mionjs']];\n resetRouter();\n}\n\nexport function setVercelHandlerOpts(options?: Partial<VercelHandlerOptions>) {\n vercelOptions = {\n ...vercelOptions,\n ...options,\n };\n defaultHeaders = [['server', '@mionjs'], ...Object.entries(vercelOptions.defaultResponseHeaders)];\n return vercelOptions;\n}\n\n/** Main handler for Web standard Request -> Response */\nasync function handleRequest(req: Request): Promise<Response> {\n const reqUrl = req.url;\n const urlObj = new URL(reqUrl);\n const path = urlObj.pathname;\n const urlQuery = urlObj.search ? urlObj.search.slice(1) : undefined;\n const contentType = req.headers.get('content-type') || '';\n const isBinary = contentType.startsWith('application/octet-stream');\n let rawBody: any = req.body\n ? isBinary\n ? await req.arrayBuffer()\n : ((await req.json()) as Record<string, unknown>)\n : undefined;\n let reqBodyType: SerializerCode = isBinary ? SerializerModes.binary : SerializerModes.json;\n const queryBody = decodeQueryBody(urlQuery, rawBody);\n if (queryBody) {\n rawBody = queryBody.rawBody;\n reqBodyType = queryBody.bodyType;\n }\n const responseHeaders = new Headers(defaultHeaders);\n\n try {\n const platformResp = await dispatchRoute(\n path,\n rawBody,\n req.headers,\n responseHeaders,\n req,\n undefined,\n reqBodyType,\n urlQuery\n );\n return reply(platformResp, responseHeaders);\n } catch (e) {\n const error =\n e instanceof RpcError\n ? e\n : new RpcError({\n publicMessage: 'Unknown Error',\n type: 'unknown-error',\n originalError: e as Error,\n });\n return fatalFail(error, responseHeaders);\n }\n}\n\n/** Creates Next.js App Router / Vercel serverless route handlers */\nexport function createVercelHandler() {\n return {\n GET: handleRequest,\n POST: handleRequest,\n PUT: handleRequest,\n DELETE: handleRequest,\n PATCH: handleRequest,\n };\n}\n\nfunction fatalFail(err: RpcError<string>, responseHeaders: any): Response {\n const routeResponse = getRouterFatalErrorResponse(err, responseHeaders);\n return reply(routeResponse, responseHeaders);\n}\n\nfunction reply(mionResp: MionResponse, responseHeaders: any): Response {\n const bodyType = mionResp.serializer;\n switch (bodyType) {\n case SerializerModes.stringifyJson: {\n return new Response(mionResp.rawBody as string, {\n status: mionResp.statusCode,\n headers: responseHeaders,\n });\n }\n case SerializerModes.json: {\n return Response.json(mionResp.body, {\n status: mionResp.statusCode,\n headers: responseHeaders,\n });\n }\n case SerializerModes.binary: {\n const serializer = mionResp.binSerializer!;\n responseHeaders.set('content-length', String(serializer.getLength()));\n const response = new Response(serializer.getBufferView(), {\n status: mionResp.statusCode,\n headers: responseHeaders,\n });\n serializer.markAsEnded();\n return response;\n }\n default: {\n const error = new RpcError({\n publicMessage: 'unknown-mion-response-format',\n type: 'unknown-error',\n errorData: {bodyType},\n });\n return fatalFail(error, responseHeaders);\n }\n }\n}\n"],"names":[],"mappings":"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"}
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Mion
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/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@mionjs/platform-vercel",
3
+ "version": "0.8.0-alpha.0",
4
+ "type": "module",
5
+ "description": "mion adapter for Vercel serverless functions",
6
+ "keywords": [
7
+ "typescript",
8
+ "API",
9
+ "RPC",
10
+ "json",
11
+ "server",
12
+ "serverless",
13
+ "framework",
14
+ "vercel"
15
+ ],
16
+ "author": "ma jerez",
17
+ "homepage": "https://mion.io/",
18
+ "license": "MIT",
19
+ "exports": {
20
+ ".": {
21
+ "source": "./index.ts",
22
+ "types": "./.dist/esm/index.d.ts",
23
+ "require": "./.dist/cjs/index.cjs",
24
+ "default": "./.dist/esm/index.js"
25
+ },
26
+ "./dev-server": {
27
+ "source": "./src/devServer.ts",
28
+ "types": "./.dist/esm/src/devServer.d.ts",
29
+ "require": "./.dist/cjs/src/devServer.cjs",
30
+ "default": "./.dist/esm/src/devServer.js"
31
+ }
32
+ },
33
+ "directories": {
34
+ "lib": ".dist"
35
+ },
36
+ "files": [
37
+ ".dist"
38
+ ],
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/MionKit/mion.git"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "scripts": {
47
+ "test": "vitest run",
48
+ "dev": "vite build --watch",
49
+ "dev:test": "vitest watch",
50
+ "lint": "npx eslint src",
51
+ "format": "prettier --write src/**/*.ts",
52
+ "build": "vite build",
53
+ "clean": "rimraf .dist & rimraf .coverage",
54
+ "fresh-start": "npm run clean && rimraf node_modules"
55
+ },
56
+ "bugs": {
57
+ "url": "https://github.com/MionKit/mion/issues"
58
+ },
59
+ "dependencies": {
60
+ "@mionjs/core": "^0.8.0-alpha.0",
61
+ "@mionjs/router": "^0.8.0-alpha.0"
62
+ },
63
+ "gitHead": "5d2ec524ba39d040338ce8946d8edf78aa7291a3"
64
+ }