@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.
- package/.dist/cjs/index.cjs +9 -0
- package/.dist/cjs/index.cjs.map +1 -0
- package/.dist/cjs/index.d.ts +3 -0
- package/.dist/cjs/package.json +1 -0
- package/.dist/cjs/src/constants.cjs +7 -0
- package/.dist/cjs/src/constants.cjs.map +1 -0
- package/.dist/cjs/src/constants.d.ts +2 -0
- package/.dist/cjs/src/devServer.cjs +95 -0
- package/.dist/cjs/src/devServer.cjs.map +1 -0
- package/.dist/cjs/src/devServer.d.ts +4 -0
- package/.dist/cjs/src/types.cjs +2 -0
- package/.dist/cjs/src/types.cjs.map +1 -0
- package/.dist/cjs/src/types.d.ts +9 -0
- package/.dist/cjs/src/vercelHandler.cjs +108 -0
- package/.dist/cjs/src/vercelHandler.cjs.map +1 -0
- package/.dist/cjs/src/vercelHandler.d.ts +12 -0
- package/.dist/esm/index.d.ts +3 -0
- package/.dist/esm/index.js +9 -0
- package/.dist/esm/index.js.map +1 -0
- package/.dist/esm/src/constants.d.ts +2 -0
- package/.dist/esm/src/constants.js +7 -0
- package/.dist/esm/src/constants.js.map +1 -0
- package/.dist/esm/src/devServer.d.ts +4 -0
- package/.dist/esm/src/devServer.js +95 -0
- package/.dist/esm/src/devServer.js.map +1 -0
- package/.dist/esm/src/types.d.ts +9 -0
- package/.dist/esm/src/types.js +2 -0
- package/.dist/esm/src/types.js.map +1 -0
- package/.dist/esm/src/vercelHandler.d.ts +12 -0
- package/.dist/esm/src/vercelHandler.js +108 -0
- package/.dist/esm/src/vercelHandler.js.map +1 -0
- package/LICENSE +21 -0
- package/package.json +64 -0
|
@@ -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 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -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,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 @@
|
|
|
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,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 @@
|
|
|
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,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 @@
|
|
|
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
|
+
}
|