@mionjs/platform-cloudflare 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_cloudflareHandler = require("./src/cloudflareHandler.cjs");
4
+ const src_constants = require("./src/constants.cjs");
5
+ exports.createCloudflareHandler = src_cloudflareHandler.createCloudflareHandler;
6
+ exports.resetCloudflareHandlerOpts = src_cloudflareHandler.resetCloudflareHandlerOpts;
7
+ exports.setCloudflareHandlerOpts = src_cloudflareHandler.setCloudflareHandlerOpts;
8
+ exports.DEFAULT_CLOUDFLARE_OPTIONS = src_constants.DEFAULT_CLOUDFLARE_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/cloudflareHandler.ts';
3
+ export * from './src/constants.ts';
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -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 cloudflareOptions = { ...src_constants.DEFAULT_CLOUDFLARE_OPTIONS };
7
+ let defaultHeaders = [["server", "@mionjs"]];
8
+ function resetCloudflareHandlerOpts() {
9
+ cloudflareOptions = { ...src_constants.DEFAULT_CLOUDFLARE_OPTIONS };
10
+ defaultHeaders = [["server", "@mionjs"]];
11
+ router.resetRouter();
12
+ }
13
+ function setCloudflareHandlerOpts(options) {
14
+ cloudflareOptions = {
15
+ ...cloudflareOptions,
16
+ ...options
17
+ };
18
+ defaultHeaders = [["server", "@mionjs"], ...Object.entries(cloudflareOptions.defaultResponseHeaders)];
19
+ return cloudflareOptions;
20
+ }
21
+ async function handleRequest(req, env, ctx) {
22
+ const reqUrl = req.url;
23
+ const urlObj = new URL(reqUrl);
24
+ let path = urlObj.pathname;
25
+ if (cloudflareOptions.basePath && path.startsWith(cloudflareOptions.basePath)) {
26
+ path = path.slice(cloudflareOptions.basePath.length) || "/";
27
+ }
28
+ const urlQuery = urlObj.search ? urlObj.search.slice(1) : void 0;
29
+ const contentType = req.headers.get("content-type") || "";
30
+ const isBinary = contentType.startsWith("application/octet-stream");
31
+ let rawBody = req.body ? isBinary ? await req.arrayBuffer() : await req.json() : void 0;
32
+ let reqBodyType = isBinary ? core.SerializerModes.binary : core.SerializerModes.json;
33
+ const queryBody = router.decodeQueryBody(urlQuery, rawBody);
34
+ if (queryBody) {
35
+ rawBody = queryBody.rawBody;
36
+ reqBodyType = queryBody.bodyType;
37
+ }
38
+ const responseHeaders = new Headers(defaultHeaders);
39
+ const platformContext = env !== void 0 || ctx !== void 0 ? { env, ctx } : void 0;
40
+ try {
41
+ const platformResp = await router.dispatchRoute(
42
+ path,
43
+ rawBody,
44
+ req.headers,
45
+ responseHeaders,
46
+ req,
47
+ platformContext,
48
+ reqBodyType,
49
+ urlQuery
50
+ );
51
+ return reply(platformResp, responseHeaders);
52
+ } catch (e) {
53
+ const error = e instanceof core.RpcError ? e : new core.RpcError({
54
+ publicMessage: "Unknown Error",
55
+ type: "unknown-error",
56
+ originalError: e
57
+ });
58
+ return fatalFail(error, responseHeaders);
59
+ }
60
+ }
61
+ function createCloudflareHandler() {
62
+ return {
63
+ fetch: (req, env, ctx) => handleRequest(req, env, ctx)
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.createCloudflareHandler = createCloudflareHandler;
106
+ exports.resetCloudflareHandlerOpts = resetCloudflareHandlerOpts;
107
+ exports.setCloudflareHandlerOpts = setCloudflareHandlerOpts;
108
+ //# sourceMappingURL=cloudflareHandler.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflareHandler.cjs","sources":["../../../src/cloudflareHandler.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_CLOUDFLARE_OPTIONS} from './constants.ts';\nimport type {CloudflareHandlerOptions, CloudflareExecutionContext, CloudflarePlatformContext} 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 cloudflareOptions: Readonly<CloudflareHandlerOptions> = {...DEFAULT_CLOUDFLARE_OPTIONS};\nlet defaultHeaders: [string, string][] = [['server', '@mionjs']];\n\nexport function resetCloudflareHandlerOpts() {\n cloudflareOptions = {...DEFAULT_CLOUDFLARE_OPTIONS};\n defaultHeaders = [['server', '@mionjs']];\n resetRouter();\n}\n\nexport function setCloudflareHandlerOpts(options?: Partial<CloudflareHandlerOptions>) {\n cloudflareOptions = {\n ...cloudflareOptions,\n ...options,\n };\n defaultHeaders = [['server', '@mionjs'], ...Object.entries(cloudflareOptions.defaultResponseHeaders)];\n return cloudflareOptions;\n}\n\n/** Main handler for Web standard Request -> Response */\nasync function handleRequest<Env = unknown>(req: Request, env?: Env, ctx?: CloudflareExecutionContext): Promise<Response> {\n const reqUrl = req.url;\n const urlObj = new URL(reqUrl);\n let path = urlObj.pathname;\n // Strip basePath prefix to get the mion route path\n if (cloudflareOptions.basePath && path.startsWith(cloudflareOptions.basePath)) {\n path = path.slice(cloudflareOptions.basePath.length) || '/';\n }\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 // Build platform context for route handlers to access env/ctx\n const platformContext: CloudflarePlatformContext<Env> | undefined =\n env !== undefined || ctx !== undefined ? {env: env as Env, ctx: ctx as CloudflareExecutionContext} : undefined;\n\n try {\n const platformResp = await dispatchRoute(\n path,\n rawBody,\n req.headers,\n responseHeaders,\n req,\n platformContext,\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 a Cloudflare Workers fetch handler */\nexport function createCloudflareHandler<Env = unknown>() {\n return {\n fetch: (req: Request, env?: Env, ctx?: CloudflareExecutionContext) => handleRequest<Env>(req, env, ctx),\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_CLOUDFLARE_OPTIONS","resetRouter","SerializerModes","decodeQueryBody","dispatchRoute","RpcError","getRouterFatalErrorResponse"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { CloudflareHandlerOptions, CloudflareExecutionContext } from './types.ts';
2
+ export declare function resetCloudflareHandlerOpts(): void;
3
+ export declare function setCloudflareHandlerOpts(options?: Partial<CloudflareHandlerOptions>): Readonly<CloudflareHandlerOptions>;
4
+ export declare function createCloudflareHandler<Env = unknown>(): {
5
+ fetch: (req: Request, env?: Env, ctx?: CloudflareExecutionContext) => Promise<Response>;
6
+ };
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const DEFAULT_CLOUDFLARE_OPTIONS = {
4
+ defaultResponseHeaders: {},
5
+ basePath: ""
6
+ };
7
+ exports.DEFAULT_CLOUDFLARE_OPTIONS = DEFAULT_CLOUDFLARE_OPTIONS;
8
+ //# 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 {CloudflareHandlerOptions} from './types.ts';\n\nexport const DEFAULT_CLOUDFLARE_OPTIONS: CloudflareHandlerOptions = {\n defaultResponseHeaders: {},\n basePath: '',\n};\n"],"names":[],"mappings":";;AASO,MAAM,6BAAuD;AAAA,EAChE,wBAAwB,CAAA;AAAA,EACxB,UAAU;AACd;;"}
@@ -0,0 +1,2 @@
1
+ import { CloudflareHandlerOptions } from './types.ts';
2
+ export declare const DEFAULT_CLOUDFLARE_OPTIONS: CloudflareHandlerOptions;
@@ -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,15 @@
1
+ export interface CloudflareHandlerOptions {
2
+ defaultResponseHeaders: Record<string, string>;
3
+ basePath: string;
4
+ }
5
+ export interface CloudflareExecutionContext {
6
+ waitUntil(promise: Promise<any>): void;
7
+ passThroughOnException(): void;
8
+ }
9
+ export interface CloudflarePlatformContext<Env = unknown> {
10
+ env: Env;
11
+ ctx: CloudflareExecutionContext;
12
+ }
13
+ export declare type __ΩCloudflareHandlerOptions = any[];
14
+ export declare type __ΩCloudflareExecutionContext = any[];
15
+ export declare type __ΩCloudflarePlatformContext = any[];
@@ -0,0 +1,3 @@
1
+ export * from './src/types.ts';
2
+ export * from './src/cloudflareHandler.ts';
3
+ export * from './src/constants.ts';
@@ -0,0 +1,9 @@
1
+ import { createCloudflareHandler, resetCloudflareHandlerOpts, setCloudflareHandlerOpts } from "./src/cloudflareHandler.js";
2
+ import { DEFAULT_CLOUDFLARE_OPTIONS } from "./src/constants.js";
3
+ export {
4
+ DEFAULT_CLOUDFLARE_OPTIONS,
5
+ createCloudflareHandler,
6
+ resetCloudflareHandlerOpts,
7
+ setCloudflareHandlerOpts
8
+ };
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -0,0 +1,6 @@
1
+ import { CloudflareHandlerOptions, CloudflareExecutionContext } from './types.ts';
2
+ export declare function resetCloudflareHandlerOpts(): void;
3
+ export declare function setCloudflareHandlerOpts(options?: Partial<CloudflareHandlerOptions>): Readonly<CloudflareHandlerOptions>;
4
+ export declare function createCloudflareHandler<Env = unknown>(): {
5
+ fetch: (req: Request, env?: Env, ctx?: CloudflareExecutionContext) => Promise<Response>;
6
+ };
@@ -0,0 +1,108 @@
1
+ import { resetRouter, decodeQueryBody, dispatchRoute, getRouterFatalErrorResponse } from "@mionjs/router";
2
+ import { DEFAULT_CLOUDFLARE_OPTIONS } from "./constants.js";
3
+ import { SerializerModes, RpcError } from "@mionjs/core";
4
+ let cloudflareOptions = { ...DEFAULT_CLOUDFLARE_OPTIONS };
5
+ let defaultHeaders = [["server", "@mionjs"]];
6
+ function resetCloudflareHandlerOpts() {
7
+ cloudflareOptions = { ...DEFAULT_CLOUDFLARE_OPTIONS };
8
+ defaultHeaders = [["server", "@mionjs"]];
9
+ resetRouter();
10
+ }
11
+ function setCloudflareHandlerOpts(options) {
12
+ cloudflareOptions = {
13
+ ...cloudflareOptions,
14
+ ...options
15
+ };
16
+ defaultHeaders = [["server", "@mionjs"], ...Object.entries(cloudflareOptions.defaultResponseHeaders)];
17
+ return cloudflareOptions;
18
+ }
19
+ async function handleRequest(req, env, ctx) {
20
+ const reqUrl = req.url;
21
+ const urlObj = new URL(reqUrl);
22
+ let path = urlObj.pathname;
23
+ if (cloudflareOptions.basePath && path.startsWith(cloudflareOptions.basePath)) {
24
+ path = path.slice(cloudflareOptions.basePath.length) || "/";
25
+ }
26
+ const urlQuery = urlObj.search ? urlObj.search.slice(1) : void 0;
27
+ const contentType = req.headers.get("content-type") || "";
28
+ const isBinary = contentType.startsWith("application/octet-stream");
29
+ let rawBody = req.body ? isBinary ? await req.arrayBuffer() : await req.json() : void 0;
30
+ let reqBodyType = isBinary ? SerializerModes.binary : SerializerModes.json;
31
+ const queryBody = decodeQueryBody(urlQuery, rawBody);
32
+ if (queryBody) {
33
+ rawBody = queryBody.rawBody;
34
+ reqBodyType = queryBody.bodyType;
35
+ }
36
+ const responseHeaders = new Headers(defaultHeaders);
37
+ const platformContext = env !== void 0 || ctx !== void 0 ? { env, ctx } : void 0;
38
+ try {
39
+ const platformResp = await dispatchRoute(
40
+ path,
41
+ rawBody,
42
+ req.headers,
43
+ responseHeaders,
44
+ req,
45
+ platformContext,
46
+ reqBodyType,
47
+ urlQuery
48
+ );
49
+ return reply(platformResp, responseHeaders);
50
+ } catch (e) {
51
+ const error = e instanceof RpcError ? e : new RpcError({
52
+ publicMessage: "Unknown Error",
53
+ type: "unknown-error",
54
+ originalError: e
55
+ });
56
+ return fatalFail(error, responseHeaders);
57
+ }
58
+ }
59
+ function createCloudflareHandler() {
60
+ return {
61
+ fetch: (req, env, ctx) => handleRequest(req, env, ctx)
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
+ createCloudflareHandler,
105
+ resetCloudflareHandlerOpts,
106
+ setCloudflareHandlerOpts
107
+ };
108
+ //# sourceMappingURL=cloudflareHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflareHandler.js","sources":["../../../src/cloudflareHandler.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_CLOUDFLARE_OPTIONS} from './constants.ts';\nimport type {CloudflareHandlerOptions, CloudflareExecutionContext, CloudflarePlatformContext} 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 cloudflareOptions: Readonly<CloudflareHandlerOptions> = {...DEFAULT_CLOUDFLARE_OPTIONS};\nlet defaultHeaders: [string, string][] = [['server', '@mionjs']];\n\nexport function resetCloudflareHandlerOpts() {\n cloudflareOptions = {...DEFAULT_CLOUDFLARE_OPTIONS};\n defaultHeaders = [['server', '@mionjs']];\n resetRouter();\n}\n\nexport function setCloudflareHandlerOpts(options?: Partial<CloudflareHandlerOptions>) {\n cloudflareOptions = {\n ...cloudflareOptions,\n ...options,\n };\n defaultHeaders = [['server', '@mionjs'], ...Object.entries(cloudflareOptions.defaultResponseHeaders)];\n return cloudflareOptions;\n}\n\n/** Main handler for Web standard Request -> Response */\nasync function handleRequest<Env = unknown>(req: Request, env?: Env, ctx?: CloudflareExecutionContext): Promise<Response> {\n const reqUrl = req.url;\n const urlObj = new URL(reqUrl);\n let path = urlObj.pathname;\n // Strip basePath prefix to get the mion route path\n if (cloudflareOptions.basePath && path.startsWith(cloudflareOptions.basePath)) {\n path = path.slice(cloudflareOptions.basePath.length) || '/';\n }\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 // Build platform context for route handlers to access env/ctx\n const platformContext: CloudflarePlatformContext<Env> | undefined =\n env !== undefined || ctx !== undefined ? {env: env as Env, ctx: ctx as CloudflareExecutionContext} : undefined;\n\n try {\n const platformResp = await dispatchRoute(\n path,\n rawBody,\n req.headers,\n responseHeaders,\n req,\n platformContext,\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 a Cloudflare Workers fetch handler */\nexport function createCloudflareHandler<Env = unknown>() {\n return {\n fetch: (req: Request, env?: Env, ctx?: CloudflareExecutionContext) => handleRequest<Env>(req, env, ctx),\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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"}
@@ -0,0 +1,2 @@
1
+ import { CloudflareHandlerOptions } from './types.ts';
2
+ export declare const DEFAULT_CLOUDFLARE_OPTIONS: CloudflareHandlerOptions;
@@ -0,0 +1,8 @@
1
+ const DEFAULT_CLOUDFLARE_OPTIONS = {
2
+ defaultResponseHeaders: {},
3
+ basePath: ""
4
+ };
5
+ export {
6
+ DEFAULT_CLOUDFLARE_OPTIONS
7
+ };
8
+ //# 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 {CloudflareHandlerOptions} from './types.ts';\n\nexport const DEFAULT_CLOUDFLARE_OPTIONS: CloudflareHandlerOptions = {\n defaultResponseHeaders: {},\n basePath: '',\n};\n"],"names":[],"mappings":"AASO,MAAM,6BAAuD;AAAA,EAChE,wBAAwB,CAAA;AAAA,EACxB,UAAU;AACd;"}
@@ -0,0 +1,15 @@
1
+ export interface CloudflareHandlerOptions {
2
+ defaultResponseHeaders: Record<string, string>;
3
+ basePath: string;
4
+ }
5
+ export interface CloudflareExecutionContext {
6
+ waitUntil(promise: Promise<any>): void;
7
+ passThroughOnException(): void;
8
+ }
9
+ export interface CloudflarePlatformContext<Env = unknown> {
10
+ env: Env;
11
+ ctx: CloudflareExecutionContext;
12
+ }
13
+ export declare type __ΩCloudflareHandlerOptions = any[];
14
+ export declare type __ΩCloudflareExecutionContext = any[];
15
+ export declare type __ΩCloudflarePlatformContext = any[];
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
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,59 @@
1
+ {
2
+ "name": "@mionjs/platform-cloudflare",
3
+ "version": "0.8.0-alpha.0",
4
+ "type": "module",
5
+ "description": "mion adapter for Cloudflare Workers",
6
+ "keywords": [
7
+ "typescript",
8
+ "API",
9
+ "RPC",
10
+ "json",
11
+ "server",
12
+ "serverless",
13
+ "framework",
14
+ "cloudflare",
15
+ "workers"
16
+ ],
17
+ "author": "ma jerez",
18
+ "homepage": "https://mion.io/",
19
+ "license": "MIT",
20
+ "exports": {
21
+ ".": {
22
+ "source": "./index.ts",
23
+ "types": "./.dist/esm/index.d.ts",
24
+ "require": "./.dist/cjs/index.cjs",
25
+ "default": "./.dist/esm/index.js"
26
+ }
27
+ },
28
+ "directories": {
29
+ "lib": ".dist"
30
+ },
31
+ "files": [
32
+ ".dist"
33
+ ],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/MionKit/mion.git"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "scripts": {
42
+ "test": "vitest run",
43
+ "dev": "vite build --watch",
44
+ "dev:test": "vitest watch",
45
+ "lint": "npx eslint src",
46
+ "format": "prettier --write src/**/*.ts",
47
+ "build": "vite build",
48
+ "clean": "rimraf .dist & rimraf .coverage",
49
+ "fresh-start": "npm run clean && rimraf node_modules"
50
+ },
51
+ "bugs": {
52
+ "url": "https://github.com/MionKit/mion/issues"
53
+ },
54
+ "dependencies": {
55
+ "@mionjs/core": "^0.8.0-alpha.0",
56
+ "@mionjs/router": "^0.8.0-alpha.0"
57
+ },
58
+ "gitHead": "5d2ec524ba39d040338ce8946d8edf78aa7291a3"
59
+ }