@morojs/moro 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/core/config/index.d.ts +5 -5
- package/dist/core/config/index.js +1 -1
- package/dist/core/config/index.js.map +1 -1
- package/dist/core/config/loader.d.ts +1 -1
- package/dist/core/config/loader.js +58 -82
- package/dist/core/config/loader.js.map +1 -1
- package/dist/core/config/schema.d.ts +1 -1
- package/dist/core/config/schema.js +52 -111
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/config/utils.d.ts +2 -2
- package/dist/core/config/utils.js +18 -18
- package/dist/core/config/utils.js.map +1 -1
- package/dist/core/database/adapters/drizzle.d.ts +1 -1
- package/dist/core/database/adapters/drizzle.js +39 -55
- package/dist/core/database/adapters/drizzle.js.map +1 -1
- package/dist/core/database/adapters/index.d.ts +7 -7
- package/dist/core/database/adapters/index.js +11 -11
- package/dist/core/database/adapters/index.js.map +1 -1
- package/dist/core/database/adapters/mongodb.d.ts +1 -1
- package/dist/core/database/adapters/mongodb.js +19 -23
- package/dist/core/database/adapters/mongodb.js.map +1 -1
- package/dist/core/database/adapters/mysql.d.ts +1 -1
- package/dist/core/database/adapters/mysql.js +31 -27
- package/dist/core/database/adapters/mysql.js.map +1 -1
- package/dist/core/database/adapters/postgresql.d.ts +1 -1
- package/dist/core/database/adapters/postgresql.js +27 -35
- package/dist/core/database/adapters/postgresql.js.map +1 -1
- package/dist/core/database/adapters/redis.d.ts +1 -1
- package/dist/core/database/adapters/redis.js +24 -24
- package/dist/core/database/adapters/redis.js.map +1 -1
- package/dist/core/database/adapters/sqlite.d.ts +1 -1
- package/dist/core/database/adapters/sqlite.js +36 -36
- package/dist/core/database/adapters/sqlite.js.map +1 -1
- package/dist/core/database/index.d.ts +2 -2
- package/dist/core/docs/index.d.ts +7 -7
- package/dist/core/docs/index.js +13 -15
- package/dist/core/docs/index.js.map +1 -1
- package/dist/core/docs/openapi-generator.d.ts +5 -5
- package/dist/core/docs/openapi-generator.js +93 -94
- package/dist/core/docs/openapi-generator.js.map +1 -1
- package/dist/core/docs/simple-docs.d.ts +1 -1
- package/dist/core/docs/simple-docs.js +25 -28
- package/dist/core/docs/simple-docs.js.map +1 -1
- package/dist/core/docs/swagger-ui.d.ts +2 -2
- package/dist/core/docs/swagger-ui.js +46 -51
- package/dist/core/docs/swagger-ui.js.map +1 -1
- package/dist/core/docs/zod-to-openapi.d.ts +1 -1
- package/dist/core/docs/zod-to-openapi.js +115 -125
- package/dist/core/docs/zod-to-openapi.js.map +1 -1
- package/dist/core/events/event-bus.d.ts +1 -1
- package/dist/core/events/event-bus.js +15 -21
- package/dist/core/events/event-bus.js.map +1 -1
- package/dist/core/events/index.d.ts +2 -2
- package/dist/core/framework.d.ts +5 -5
- package/dist/core/framework.js +55 -60
- package/dist/core/framework.js.map +1 -1
- package/dist/core/http/http-server.d.ts +2 -2
- package/dist/core/http/http-server.js +228 -261
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/index.d.ts +3 -3
- package/dist/core/http/router.d.ts +1 -1
- package/dist/core/http/router.js +15 -17
- package/dist/core/http/router.js.map +1 -1
- package/dist/core/logger/filters.d.ts +1 -1
- package/dist/core/logger/filters.js +16 -16
- package/dist/core/logger/filters.js.map +1 -1
- package/dist/core/logger/index.d.ts +3 -3
- package/dist/core/logger/logger.d.ts +1 -1
- package/dist/core/logger/logger.js +48 -59
- package/dist/core/logger/logger.js.map +1 -1
- package/dist/core/logger/outputs.d.ts +4 -4
- package/dist/core/logger/outputs.js +16 -20
- package/dist/core/logger/outputs.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/file.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cache/file.js +19 -19
- package/dist/core/middleware/built-in/adapters/cache/file.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/index.d.ts +4 -4
- package/dist/core/middleware/built-in/adapters/cache/index.js +3 -3
- package/dist/core/middleware/built-in/adapters/cache/index.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/memory.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cache/memory.js +5 -5
- package/dist/core/middleware/built-in/adapters/cache/memory.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cache/redis.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cache/redis.js +18 -18
- package/dist/core/middleware/built-in/adapters/cache/redis.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/azure.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/azure.js +8 -8
- package/dist/core/middleware/built-in/adapters/cdn/azure.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js +14 -14
- package/dist/core/middleware/built-in/adapters/cdn/cloudflare.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.d.ts +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js +13 -15
- package/dist/core/middleware/built-in/adapters/cdn/cloudfront.js.map +1 -1
- package/dist/core/middleware/built-in/adapters/cdn/index.d.ts +4 -4
- package/dist/core/middleware/built-in/adapters/cdn/index.js +3 -3
- package/dist/core/middleware/built-in/adapters/index.d.ts +4 -4
- package/dist/core/middleware/built-in/auth.d.ts +1 -1
- package/dist/core/middleware/built-in/auth.js +14 -14
- package/dist/core/middleware/built-in/cache.d.ts +2 -2
- package/dist/core/middleware/built-in/cache.js +43 -45
- package/dist/core/middleware/built-in/cache.js.map +1 -1
- package/dist/core/middleware/built-in/cdn.d.ts +2 -2
- package/dist/core/middleware/built-in/cdn.js +27 -29
- package/dist/core/middleware/built-in/cdn.js.map +1 -1
- package/dist/core/middleware/built-in/cookie.d.ts +2 -2
- package/dist/core/middleware/built-in/cookie.js +17 -17
- package/dist/core/middleware/built-in/cookie.js.map +1 -1
- package/dist/core/middleware/built-in/cors.d.ts +1 -1
- package/dist/core/middleware/built-in/cors.js +13 -13
- package/dist/core/middleware/built-in/csp.d.ts +1 -1
- package/dist/core/middleware/built-in/csp.js +22 -25
- package/dist/core/middleware/built-in/csp.js.map +1 -1
- package/dist/core/middleware/built-in/csrf.d.ts +1 -1
- package/dist/core/middleware/built-in/csrf.js +21 -24
- package/dist/core/middleware/built-in/csrf.js.map +1 -1
- package/dist/core/middleware/built-in/error-tracker.js +2 -2
- package/dist/core/middleware/built-in/index.d.ts +14 -14
- package/dist/core/middleware/built-in/performance-monitor.js +2 -2
- package/dist/core/middleware/built-in/rate-limit.d.ts +1 -1
- package/dist/core/middleware/built-in/rate-limit.js +12 -12
- package/dist/core/middleware/built-in/request-logger.js.map +1 -1
- package/dist/core/middleware/built-in/session.d.ts +5 -5
- package/dist/core/middleware/built-in/session.js +35 -38
- package/dist/core/middleware/built-in/session.js.map +1 -1
- package/dist/core/middleware/built-in/sse.d.ts +1 -1
- package/dist/core/middleware/built-in/sse.js +20 -22
- package/dist/core/middleware/built-in/sse.js.map +1 -1
- package/dist/core/middleware/built-in/validation.d.ts +1 -1
- package/dist/core/middleware/built-in/validation.js +13 -13
- package/dist/core/middleware/index.d.ts +5 -5
- package/dist/core/middleware/index.js +16 -16
- package/dist/core/middleware/index.js.map +1 -1
- package/dist/core/modules/auto-discovery.d.ts +2 -2
- package/dist/core/modules/auto-discovery.js +12 -13
- package/dist/core/modules/auto-discovery.js.map +1 -1
- package/dist/core/modules/index.d.ts +2 -2
- package/dist/core/modules/index.js.map +1 -1
- package/dist/core/modules/modules.d.ts +3 -3
- package/dist/core/modules/modules.js +3 -6
- package/dist/core/modules/modules.js.map +1 -1
- package/dist/core/networking/index.d.ts +2 -2
- package/dist/core/networking/index.js.map +1 -1
- package/dist/core/networking/service-discovery.d.ts +2 -2
- package/dist/core/networking/service-discovery.js +27 -27
- package/dist/core/networking/service-discovery.js.map +1 -1
- package/dist/core/networking/websocket-manager.d.ts +3 -3
- package/dist/core/networking/websocket-manager.js +15 -16
- package/dist/core/networking/websocket-manager.js.map +1 -1
- package/dist/core/routing/app-integration.d.ts +2 -2
- package/dist/core/routing/app-integration.js +13 -13
- package/dist/core/routing/app-integration.js.map +1 -1
- package/dist/core/routing/index.d.ts +3 -3
- package/dist/core/routing/index.js +43 -52
- package/dist/core/routing/index.js.map +1 -1
- package/dist/core/runtime/aws-lambda-adapter.d.ts +3 -3
- package/dist/core/runtime/aws-lambda-adapter.js +14 -16
- package/dist/core/runtime/aws-lambda-adapter.js.map +1 -1
- package/dist/core/runtime/base-adapter.d.ts +2 -2
- package/dist/core/runtime/base-adapter.js +11 -12
- package/dist/core/runtime/base-adapter.js.map +1 -1
- package/dist/core/runtime/cloudflare-workers-adapter.d.ts +3 -3
- package/dist/core/runtime/cloudflare-workers-adapter.js +20 -21
- package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
- package/dist/core/runtime/index.d.ts +9 -9
- package/dist/core/runtime/index.js +4 -4
- package/dist/core/runtime/index.js.map +1 -1
- package/dist/core/runtime/node-adapter.d.ts +5 -5
- package/dist/core/runtime/node-adapter.js +35 -35
- package/dist/core/runtime/node-adapter.js.map +1 -1
- package/dist/core/runtime/vercel-edge-adapter.d.ts +3 -3
- package/dist/core/runtime/vercel-edge-adapter.js +12 -15
- package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
- package/dist/core/utilities/circuit-breaker.js +6 -6
- package/dist/core/utilities/container.d.ts +1 -1
- package/dist/core/utilities/container.js +17 -22
- package/dist/core/utilities/container.js.map +1 -1
- package/dist/core/utilities/hooks.d.ts +3 -3
- package/dist/core/utilities/hooks.js +11 -11
- package/dist/core/utilities/hooks.js.map +1 -1
- package/dist/core/utilities/index.d.ts +4 -4
- package/dist/core/validation/index.d.ts +3 -3
- package/dist/core/validation/index.js +15 -15
- package/dist/core/validation/index.js.map +1 -1
- package/dist/index.d.ts +41 -30
- package/dist/index.js +50 -1
- package/dist/index.js.map +1 -1
- package/dist/moro.d.ts +14 -14
- package/dist/moro.js +79 -88
- package/dist/moro.js.map +1 -1
- package/dist/types/cache.d.ts +1 -1
- package/dist/types/core.d.ts +2 -2
- package/dist/types/events.d.ts +19 -19
- package/dist/types/hooks.d.ts +1 -1
- package/dist/types/http.d.ts +2 -2
- package/dist/types/logger.d.ts +3 -3
- package/dist/types/module.d.ts +2 -2
- package/dist/types/runtime.d.ts +2 -2
- package/dist/types/session.d.ts +4 -4
- package/package.json +183 -165
- package/src/core/config/index.ts +7 -9
- package/src/core/config/loader.ts +86 -158
- package/src/core/config/schema.ts +59 -122
- package/src/core/config/utils.ts +27 -45
- package/src/core/database/adapters/drizzle.ts +53 -75
- package/src/core/database/adapters/index.ts +26 -29
- package/src/core/database/adapters/mongodb.ts +31 -54
- package/src/core/database/adapters/mysql.ts +40 -50
- package/src/core/database/adapters/postgresql.ts +32 -42
- package/src/core/database/adapters/redis.ts +31 -36
- package/src/core/database/adapters/sqlite.ts +43 -51
- package/src/core/database/index.ts +2 -2
- package/src/core/docs/index.ts +25 -39
- package/src/core/docs/openapi-generator.ts +104 -117
- package/src/core/docs/simple-docs.ts +29 -39
- package/src/core/docs/swagger-ui.ts +57 -76
- package/src/core/docs/zod-to-openapi.ts +121 -153
- package/src/core/events/event-bus.ts +22 -45
- package/src/core/events/index.ts +2 -2
- package/src/core/framework.ts +119 -197
- package/src/core/http/http-server.ts +260 -360
- package/src/core/http/index.ts +3 -8
- package/src/core/http/router.ts +19 -31
- package/src/core/logger/filters.ts +19 -22
- package/src/core/logger/index.ts +3 -3
- package/src/core/logger/logger.ts +59 -100
- package/src/core/logger/outputs.ts +23 -27
- package/src/core/middleware/built-in/adapters/cache/file.ts +21 -23
- package/src/core/middleware/built-in/adapters/cache/index.ts +11 -14
- package/src/core/middleware/built-in/adapters/cache/memory.ts +7 -7
- package/src/core/middleware/built-in/adapters/cache/redis.ts +21 -24
- package/src/core/middleware/built-in/adapters/cdn/azure.ts +10 -18
- package/src/core/middleware/built-in/adapters/cdn/cloudflare.ts +19 -36
- package/src/core/middleware/built-in/adapters/cdn/cloudfront.ts +17 -26
- package/src/core/middleware/built-in/adapters/cdn/index.ts +10 -10
- package/src/core/middleware/built-in/adapters/index.ts +4 -4
- package/src/core/middleware/built-in/auth.ts +16 -16
- package/src/core/middleware/built-in/cache.ts +50 -67
- package/src/core/middleware/built-in/cdn.ts +34 -61
- package/src/core/middleware/built-in/cookie.ts +23 -28
- package/src/core/middleware/built-in/cors.ts +17 -17
- package/src/core/middleware/built-in/csp.ts +25 -31
- package/src/core/middleware/built-in/csrf.ts +24 -29
- package/src/core/middleware/built-in/error-tracker.ts +3 -3
- package/src/core/middleware/built-in/index.ts +28 -28
- package/src/core/middleware/built-in/performance-monitor.ts +4 -4
- package/src/core/middleware/built-in/rate-limit.ts +15 -15
- package/src/core/middleware/built-in/request-logger.ts +1 -3
- package/src/core/middleware/built-in/session.ts +47 -70
- package/src/core/middleware/built-in/sse.ts +23 -28
- package/src/core/middleware/built-in/validation.ts +15 -15
- package/src/core/middleware/index.ts +26 -37
- package/src/core/modules/auto-discovery.ts +21 -31
- package/src/core/modules/index.ts +2 -5
- package/src/core/modules/modules.ts +11 -20
- package/src/core/networking/index.ts +2 -6
- package/src/core/networking/service-discovery.ts +41 -61
- package/src/core/networking/websocket-manager.ts +27 -36
- package/src/core/routing/app-integration.ts +19 -32
- package/src/core/routing/index.ts +57 -88
- package/src/core/runtime/aws-lambda-adapter.ts +20 -30
- package/src/core/runtime/base-adapter.ts +17 -27
- package/src/core/runtime/cloudflare-workers-adapter.ts +28 -42
- package/src/core/runtime/index.ts +21 -33
- package/src/core/runtime/node-adapter.ts +59 -73
- package/src/core/runtime/vercel-edge-adapter.ts +18 -29
- package/src/core/utilities/circuit-breaker.ts +7 -7
- package/src/core/utilities/container.ts +52 -89
- package/src/core/utilities/hooks.ts +17 -23
- package/src/core/utilities/index.ts +4 -4
- package/src/core/validation/index.ts +25 -51
- package/src/index.ts +104 -60
- package/src/moro.ts +119 -191
- package/src/types/cache.ts +1 -1
- package/src/types/core.ts +2 -2
- package/src/types/database.ts +2 -10
- package/src/types/events.ts +23 -31
- package/src/types/hooks.ts +1 -1
- package/src/types/http.ts +5 -8
- package/src/types/logger.ts +7 -23
- package/src/types/module.ts +2 -2
- package/src/types/runtime.ts +6 -21
- package/src/types/session.ts +4 -4
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
// Base runtime adapter with common functionality
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
RuntimeHttpResponse,
|
|
6
|
-
} from "../../types/runtime";
|
|
7
|
-
import { HttpRequest, HttpResponse } from "../../types/http";
|
|
8
|
-
import { randomBytes } from "crypto";
|
|
2
|
+
import { RuntimeAdapter, RuntimeType, RuntimeHttpResponse } from '../../types/runtime';
|
|
3
|
+
import { HttpRequest, HttpResponse } from '../../types/http';
|
|
4
|
+
import { randomBytes } from 'crypto';
|
|
9
5
|
|
|
10
6
|
export abstract class BaseRuntimeAdapter implements RuntimeAdapter {
|
|
11
7
|
abstract readonly type: RuntimeType;
|
|
12
8
|
|
|
13
|
-
abstract adaptRequest(
|
|
14
|
-
runtimeRequest: any,
|
|
15
|
-
...args: any[]
|
|
16
|
-
): Promise<HttpRequest>;
|
|
9
|
+
abstract adaptRequest(runtimeRequest: any, ...args: any[]): Promise<HttpRequest>;
|
|
17
10
|
abstract adaptResponse(
|
|
18
11
|
moroResponse: HttpResponse | RuntimeHttpResponse,
|
|
19
|
-
runtimeRequest: any
|
|
12
|
+
runtimeRequest: any
|
|
20
13
|
): Promise<any>;
|
|
21
|
-
abstract createServer(
|
|
22
|
-
handler: (req: HttpRequest, res: HttpResponse) => Promise<void>,
|
|
23
|
-
): any;
|
|
14
|
+
abstract createServer(handler: (req: HttpRequest, res: HttpResponse) => Promise<void>): any;
|
|
24
15
|
|
|
25
16
|
// Generate UUID without external dependency
|
|
26
17
|
protected generateUUID(): string {
|
|
27
18
|
return randomBytes(16)
|
|
28
|
-
.toString(
|
|
29
|
-
.replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/,
|
|
19
|
+
.toString('hex')
|
|
20
|
+
.replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, '$1-$2-$3-$4-$5');
|
|
30
21
|
}
|
|
31
22
|
|
|
32
23
|
// Common request enhancement
|
|
@@ -35,7 +26,7 @@ export abstract class BaseRuntimeAdapter implements RuntimeAdapter {
|
|
|
35
26
|
|
|
36
27
|
// Add common properties
|
|
37
28
|
request.requestId = request.requestId || this.generateUUID();
|
|
38
|
-
request.ip = request.ip ||
|
|
29
|
+
request.ip = request.ip || 'unknown';
|
|
39
30
|
request.params = request.params || {};
|
|
40
31
|
request.query = request.query || {};
|
|
41
32
|
request.cookies = request.cookies || {};
|
|
@@ -58,7 +49,7 @@ export abstract class BaseRuntimeAdapter implements RuntimeAdapter {
|
|
|
58
49
|
},
|
|
59
50
|
|
|
60
51
|
json: function (data: any) {
|
|
61
|
-
this.headers[
|
|
52
|
+
this.headers['Content-Type'] = 'application/json';
|
|
62
53
|
this.body = JSON.stringify(data);
|
|
63
54
|
this.headersSent = true;
|
|
64
55
|
},
|
|
@@ -71,24 +62,23 @@ export abstract class BaseRuntimeAdapter implements RuntimeAdapter {
|
|
|
71
62
|
cookie: function (name: string, value: string, options?: any) {
|
|
72
63
|
// Simple cookie implementation
|
|
73
64
|
const cookieString = `${name}=${value}`;
|
|
74
|
-
this.headers[
|
|
65
|
+
this.headers['Set-Cookie'] = cookieString;
|
|
75
66
|
return this;
|
|
76
67
|
},
|
|
77
68
|
|
|
78
69
|
clearCookie: function (name: string, options?: any) {
|
|
79
|
-
this.headers[
|
|
80
|
-
`${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
|
|
70
|
+
this.headers['Set-Cookie'] = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
|
|
81
71
|
return this;
|
|
82
72
|
},
|
|
83
73
|
|
|
84
74
|
redirect: function (url: string, status?: number) {
|
|
85
75
|
this.statusCode = status || 302;
|
|
86
|
-
this.headers[
|
|
76
|
+
this.headers['Location'] = url;
|
|
87
77
|
this.headersSent = true;
|
|
88
78
|
},
|
|
89
79
|
|
|
90
80
|
sendFile: async function (filePath: string) {
|
|
91
|
-
throw new Error(
|
|
81
|
+
throw new Error('sendFile not implemented in this runtime');
|
|
92
82
|
},
|
|
93
83
|
};
|
|
94
84
|
|
|
@@ -101,7 +91,7 @@ export abstract class BaseRuntimeAdapter implements RuntimeAdapter {
|
|
|
101
91
|
query: Record<string, string>;
|
|
102
92
|
} {
|
|
103
93
|
try {
|
|
104
|
-
const urlObj = new URL(url,
|
|
94
|
+
const urlObj = new URL(url, 'http://localhost');
|
|
105
95
|
const query: Record<string, string> = {};
|
|
106
96
|
|
|
107
97
|
urlObj.searchParams.forEach((value, key) => {
|
|
@@ -124,8 +114,8 @@ export abstract class BaseRuntimeAdapter implements RuntimeAdapter {
|
|
|
124
114
|
protected async parseBody(body: any, contentType?: string): Promise<any> {
|
|
125
115
|
if (!body) return undefined;
|
|
126
116
|
|
|
127
|
-
if (typeof body ===
|
|
128
|
-
if (contentType?.includes(
|
|
117
|
+
if (typeof body === 'string') {
|
|
118
|
+
if (contentType?.includes('application/json')) {
|
|
129
119
|
try {
|
|
130
120
|
return JSON.parse(body);
|
|
131
121
|
} catch {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Cloudflare Workers runtime adapter
|
|
2
|
-
import { BaseRuntimeAdapter } from
|
|
3
|
-
import { HttpRequest, HttpResponse } from
|
|
4
|
-
import { RuntimeHttpResponse } from
|
|
2
|
+
import { BaseRuntimeAdapter } from './base-adapter';
|
|
3
|
+
import { HttpRequest, HttpResponse } from '../../types/http';
|
|
4
|
+
import { RuntimeHttpResponse } from '../../types/runtime';
|
|
5
5
|
|
|
6
6
|
export interface WorkersEnv {
|
|
7
7
|
[key: string]: any;
|
|
@@ -13,26 +13,22 @@ export interface WorkersContext {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export class CloudflareWorkersAdapter extends BaseRuntimeAdapter {
|
|
16
|
-
readonly type =
|
|
16
|
+
readonly type = 'cloudflare-workers' as const;
|
|
17
17
|
|
|
18
|
-
async adaptRequest(
|
|
19
|
-
request: Request,
|
|
20
|
-
env: WorkersEnv,
|
|
21
|
-
ctx: WorkersContext,
|
|
22
|
-
): Promise<HttpRequest> {
|
|
18
|
+
async adaptRequest(request: Request, env: WorkersEnv, ctx: WorkersContext): Promise<HttpRequest> {
|
|
23
19
|
const { pathname, query } = this.parseUrl(request.url);
|
|
24
20
|
|
|
25
21
|
// Parse body for POST/PUT/PATCH requests
|
|
26
22
|
let body: any;
|
|
27
|
-
if ([
|
|
28
|
-
const contentType = request.headers.get(
|
|
29
|
-
if (contentType.includes(
|
|
23
|
+
if (['POST', 'PUT', 'PATCH'].includes(request.method)) {
|
|
24
|
+
const contentType = request.headers.get('content-type') || '';
|
|
25
|
+
if (contentType.includes('application/json')) {
|
|
30
26
|
try {
|
|
31
27
|
body = await request.json();
|
|
32
28
|
} catch {
|
|
33
29
|
body = await request.text();
|
|
34
30
|
}
|
|
35
|
-
} else if (contentType.includes(
|
|
31
|
+
} else if (contentType.includes('application/x-www-form-urlencoded')) {
|
|
36
32
|
body = await request.formData();
|
|
37
33
|
// Convert FormData to object
|
|
38
34
|
const formObject: Record<string, any> = {};
|
|
@@ -60,8 +56,8 @@ export class CloudflareWorkersAdapter extends BaseRuntimeAdapter {
|
|
|
60
56
|
headers,
|
|
61
57
|
ip: this.getClientIP(headers, request),
|
|
62
58
|
params: {},
|
|
63
|
-
requestId:
|
|
64
|
-
cookies: this.parseCookies(headers.cookie ||
|
|
59
|
+
requestId: '',
|
|
60
|
+
cookies: this.parseCookies(headers.cookie || ''),
|
|
65
61
|
files: {},
|
|
66
62
|
// Add Workers-specific context
|
|
67
63
|
env,
|
|
@@ -71,9 +67,7 @@ export class CloudflareWorkersAdapter extends BaseRuntimeAdapter {
|
|
|
71
67
|
return this.enhanceRequest(baseRequest);
|
|
72
68
|
}
|
|
73
69
|
|
|
74
|
-
async adaptResponse(
|
|
75
|
-
moroResponse: HttpResponse | RuntimeHttpResponse,
|
|
76
|
-
): Promise<Response> {
|
|
70
|
+
async adaptResponse(moroResponse: HttpResponse | RuntimeHttpResponse): Promise<Response> {
|
|
77
71
|
const runtimeResponse = moroResponse as RuntimeHttpResponse;
|
|
78
72
|
|
|
79
73
|
// Handle different response states
|
|
@@ -82,10 +76,7 @@ export class CloudflareWorkersAdapter extends BaseRuntimeAdapter {
|
|
|
82
76
|
const headers = runtimeResponse.headers || {};
|
|
83
77
|
|
|
84
78
|
// If it's a real HttpResponse, we need to extract the data differently
|
|
85
|
-
if (
|
|
86
|
-
"statusCode" in moroResponse &&
|
|
87
|
-
typeof moroResponse.statusCode === "number"
|
|
88
|
-
) {
|
|
79
|
+
if ('statusCode' in moroResponse && typeof moroResponse.statusCode === 'number') {
|
|
89
80
|
status = moroResponse.statusCode;
|
|
90
81
|
}
|
|
91
82
|
|
|
@@ -96,9 +87,9 @@ export class CloudflareWorkersAdapter extends BaseRuntimeAdapter {
|
|
|
96
87
|
});
|
|
97
88
|
|
|
98
89
|
// Handle different body types
|
|
99
|
-
if (typeof body ===
|
|
90
|
+
if (typeof body === 'object' && body !== null) {
|
|
100
91
|
body = JSON.stringify(body);
|
|
101
|
-
responseHeaders.set(
|
|
92
|
+
responseHeaders.set('Content-Type', 'application/json');
|
|
102
93
|
}
|
|
103
94
|
|
|
104
95
|
return new Response(body, {
|
|
@@ -107,9 +98,7 @@ export class CloudflareWorkersAdapter extends BaseRuntimeAdapter {
|
|
|
107
98
|
});
|
|
108
99
|
}
|
|
109
100
|
|
|
110
|
-
createServer(
|
|
111
|
-
handler: (req: HttpRequest, res: HttpResponse) => Promise<void>,
|
|
112
|
-
) {
|
|
101
|
+
createServer(handler: (req: HttpRequest, res: HttpResponse) => Promise<void>) {
|
|
113
102
|
// Return a Cloudflare Workers-compatible handler function
|
|
114
103
|
return async (request: Request, env: WorkersEnv, ctx: WorkersContext) => {
|
|
115
104
|
try {
|
|
@@ -123,13 +112,13 @@ export class CloudflareWorkersAdapter extends BaseRuntimeAdapter {
|
|
|
123
112
|
return new Response(
|
|
124
113
|
JSON.stringify({
|
|
125
114
|
success: false,
|
|
126
|
-
error:
|
|
127
|
-
message: error instanceof Error ? error.message :
|
|
115
|
+
error: 'Internal server error',
|
|
116
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
128
117
|
}),
|
|
129
118
|
{
|
|
130
119
|
status: 500,
|
|
131
|
-
headers: {
|
|
132
|
-
}
|
|
120
|
+
headers: { 'Content-Type': 'application/json' },
|
|
121
|
+
}
|
|
133
122
|
);
|
|
134
123
|
}
|
|
135
124
|
};
|
|
@@ -138,26 +127,23 @@ export class CloudflareWorkersAdapter extends BaseRuntimeAdapter {
|
|
|
138
127
|
// Cloudflare Workers doesn't have a listen method - it's handled by the platform
|
|
139
128
|
// listen method is optional in the interface
|
|
140
129
|
|
|
141
|
-
private getClientIP(
|
|
142
|
-
headers: Record<string, string>,
|
|
143
|
-
request: Request,
|
|
144
|
-
): string {
|
|
130
|
+
private getClientIP(headers: Record<string, string>, request: Request): string {
|
|
145
131
|
// Cloudflare provides the real IP in CF-Connecting-IP header
|
|
146
132
|
return (
|
|
147
|
-
headers[
|
|
148
|
-
headers[
|
|
149
|
-
headers[
|
|
150
|
-
|
|
133
|
+
headers['cf-connecting-ip'] ||
|
|
134
|
+
headers['x-forwarded-for']?.split(',')[0]?.trim() ||
|
|
135
|
+
headers['x-real-ip'] ||
|
|
136
|
+
'unknown'
|
|
151
137
|
);
|
|
152
138
|
}
|
|
153
139
|
|
|
154
140
|
private parseCookies(cookieHeader: string): Record<string, string> {
|
|
155
141
|
const cookies: Record<string, string> = {};
|
|
156
142
|
if (cookieHeader) {
|
|
157
|
-
cookieHeader.split(
|
|
158
|
-
const [name, ...rest] = cookie.trim().split(
|
|
143
|
+
cookieHeader.split(';').forEach(cookie => {
|
|
144
|
+
const [name, ...rest] = cookie.trim().split('=');
|
|
159
145
|
if (name && rest.length > 0) {
|
|
160
|
-
cookies[name] = rest.join(
|
|
146
|
+
cookies[name] = rest.join('=');
|
|
161
147
|
}
|
|
162
148
|
});
|
|
163
149
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Runtime adapters export
|
|
2
|
-
export { BaseRuntimeAdapter } from
|
|
3
|
-
export { NodeRuntimeAdapter } from
|
|
4
|
-
export { VercelEdgeAdapter } from
|
|
5
|
-
export { AWSLambdaAdapter } from
|
|
6
|
-
export { CloudflareWorkersAdapter } from
|
|
2
|
+
export { BaseRuntimeAdapter } from './base-adapter';
|
|
3
|
+
export { NodeRuntimeAdapter } from './node-adapter';
|
|
4
|
+
export { VercelEdgeAdapter } from './vercel-edge-adapter';
|
|
5
|
+
export { AWSLambdaAdapter } from './aws-lambda-adapter';
|
|
6
|
+
export { CloudflareWorkersAdapter } from './cloudflare-workers-adapter';
|
|
7
7
|
|
|
8
8
|
// Re-export types
|
|
9
9
|
export type {
|
|
@@ -12,32 +12,28 @@ export type {
|
|
|
12
12
|
RuntimeConfig,
|
|
13
13
|
RuntimeMoroOptions,
|
|
14
14
|
RuntimeHttpResponse,
|
|
15
|
-
} from
|
|
15
|
+
} from '../../types/runtime';
|
|
16
16
|
|
|
17
17
|
// Re-export specific runtime types
|
|
18
|
-
export type {
|
|
19
|
-
|
|
20
|
-
LambdaContext,
|
|
21
|
-
LambdaResponse,
|
|
22
|
-
} from "./aws-lambda-adapter";
|
|
23
|
-
export type { WorkersEnv, WorkersContext } from "./cloudflare-workers-adapter";
|
|
18
|
+
export type { LambdaEvent, LambdaContext, LambdaResponse } from './aws-lambda-adapter';
|
|
19
|
+
export type { WorkersEnv, WorkersContext } from './cloudflare-workers-adapter';
|
|
24
20
|
|
|
25
21
|
// Runtime factory functions
|
|
26
|
-
import { NodeRuntimeAdapter } from
|
|
27
|
-
import { VercelEdgeAdapter } from
|
|
28
|
-
import { AWSLambdaAdapter } from
|
|
29
|
-
import { CloudflareWorkersAdapter } from
|
|
30
|
-
import { RuntimeType, RuntimeAdapter } from
|
|
22
|
+
import { NodeRuntimeAdapter } from './node-adapter';
|
|
23
|
+
import { VercelEdgeAdapter } from './vercel-edge-adapter';
|
|
24
|
+
import { AWSLambdaAdapter } from './aws-lambda-adapter';
|
|
25
|
+
import { CloudflareWorkersAdapter } from './cloudflare-workers-adapter';
|
|
26
|
+
import { RuntimeType, RuntimeAdapter } from '../../types/runtime';
|
|
31
27
|
|
|
32
28
|
export function createRuntimeAdapter(type: RuntimeType): RuntimeAdapter {
|
|
33
29
|
switch (type) {
|
|
34
|
-
case
|
|
30
|
+
case 'node':
|
|
35
31
|
return new NodeRuntimeAdapter();
|
|
36
|
-
case
|
|
32
|
+
case 'vercel-edge':
|
|
37
33
|
return new VercelEdgeAdapter();
|
|
38
|
-
case
|
|
34
|
+
case 'aws-lambda':
|
|
39
35
|
return new AWSLambdaAdapter();
|
|
40
|
-
case
|
|
36
|
+
case 'cloudflare-workers':
|
|
41
37
|
return new CloudflareWorkersAdapter();
|
|
42
38
|
default:
|
|
43
39
|
throw new Error(`Unsupported runtime type: ${type}`);
|
|
@@ -45,30 +41,22 @@ export function createRuntimeAdapter(type: RuntimeType): RuntimeAdapter {
|
|
|
45
41
|
}
|
|
46
42
|
|
|
47
43
|
// Convenience functions for creating runtime-specific handlers
|
|
48
|
-
export function createNodeHandler(
|
|
49
|
-
handler: (req: any, res: any) => Promise<void>,
|
|
50
|
-
) {
|
|
44
|
+
export function createNodeHandler(handler: (req: any, res: any) => Promise<void>) {
|
|
51
45
|
const adapter = new NodeRuntimeAdapter();
|
|
52
46
|
return adapter.createServer(handler);
|
|
53
47
|
}
|
|
54
48
|
|
|
55
|
-
export function createEdgeHandler(
|
|
56
|
-
handler: (req: any, res: any) => Promise<void>,
|
|
57
|
-
) {
|
|
49
|
+
export function createEdgeHandler(handler: (req: any, res: any) => Promise<void>) {
|
|
58
50
|
const adapter = new VercelEdgeAdapter();
|
|
59
51
|
return adapter.createServer(handler);
|
|
60
52
|
}
|
|
61
53
|
|
|
62
|
-
export function createLambdaHandler(
|
|
63
|
-
handler: (req: any, res: any) => Promise<void>,
|
|
64
|
-
) {
|
|
54
|
+
export function createLambdaHandler(handler: (req: any, res: any) => Promise<void>) {
|
|
65
55
|
const adapter = new AWSLambdaAdapter();
|
|
66
56
|
return adapter.createServer(handler);
|
|
67
57
|
}
|
|
68
58
|
|
|
69
|
-
export function createWorkerHandler(
|
|
70
|
-
handler: (req: any, res: any) => Promise<void>,
|
|
71
|
-
) {
|
|
59
|
+
export function createWorkerHandler(handler: (req: any, res: any) => Promise<void>) {
|
|
72
60
|
const adapter = new CloudflareWorkersAdapter();
|
|
73
61
|
return adapter.createServer(handler);
|
|
74
62
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
// Node.js runtime adapter
|
|
2
|
-
import { IncomingMessage, ServerResponse } from
|
|
3
|
-
import { BaseRuntimeAdapter } from
|
|
4
|
-
import { HttpRequest, HttpResponse } from
|
|
5
|
-
import { RuntimeHttpResponse } from
|
|
6
|
-
import { MoroHttpServer } from
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
import { BaseRuntimeAdapter } from './base-adapter';
|
|
4
|
+
import { HttpRequest, HttpResponse } from '../../types/http';
|
|
5
|
+
import { RuntimeHttpResponse } from '../../types/runtime';
|
|
6
|
+
import { MoroHttpServer } from '../http/http-server';
|
|
7
7
|
|
|
8
8
|
export class NodeRuntimeAdapter extends BaseRuntimeAdapter {
|
|
9
|
-
readonly type =
|
|
9
|
+
readonly type = 'node' as const;
|
|
10
10
|
|
|
11
11
|
async adaptRequest(req: IncomingMessage): Promise<HttpRequest> {
|
|
12
|
-
const { pathname, query } = this.parseUrl(req.url ||
|
|
12
|
+
const { pathname, query } = this.parseUrl(req.url || '/');
|
|
13
13
|
|
|
14
14
|
// Parse body for POST/PUT/PATCH requests
|
|
15
15
|
let body: any;
|
|
16
|
-
if ([
|
|
16
|
+
if (['POST', 'PUT', 'PATCH'].includes(req.method!)) {
|
|
17
17
|
body = await this.parseRequestBody(req);
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -33,7 +33,7 @@ export class NodeRuntimeAdapter extends BaseRuntimeAdapter {
|
|
|
33
33
|
body,
|
|
34
34
|
ip: this.getClientIP(req),
|
|
35
35
|
params: {},
|
|
36
|
-
requestId:
|
|
36
|
+
requestId: '',
|
|
37
37
|
cookies: {},
|
|
38
38
|
files: {},
|
|
39
39
|
} as Partial<HttpRequest>;
|
|
@@ -43,84 +43,73 @@ export class NodeRuntimeAdapter extends BaseRuntimeAdapter {
|
|
|
43
43
|
|
|
44
44
|
async adaptResponse(
|
|
45
45
|
moroResponse: HttpResponse | RuntimeHttpResponse,
|
|
46
|
-
req: IncomingMessage
|
|
46
|
+
req: IncomingMessage
|
|
47
47
|
): Promise<ServerResponse> {
|
|
48
48
|
// For Node.js, we typically work with the actual ServerResponse
|
|
49
49
|
// This method is mainly for converting mock responses back to real ones
|
|
50
50
|
return moroResponse as any;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
createServer(
|
|
54
|
-
handler: (req: HttpRequest, res: HttpResponse) => Promise<void>,
|
|
55
|
-
): MoroHttpServer {
|
|
53
|
+
createServer(handler: (req: HttpRequest, res: HttpResponse) => Promise<void>): MoroHttpServer {
|
|
56
54
|
const httpServer = new MoroHttpServer();
|
|
57
55
|
|
|
58
56
|
// Replace the default request handler with our runtime-aware handler
|
|
59
57
|
const originalServer = httpServer.getServer();
|
|
60
|
-
originalServer.removeAllListeners(
|
|
61
|
-
|
|
62
|
-
originalServer.on(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
error instanceof Error ? error.message : "Unknown error",
|
|
80
|
-
}),
|
|
81
|
-
);
|
|
82
|
-
}
|
|
58
|
+
originalServer.removeAllListeners('request');
|
|
59
|
+
|
|
60
|
+
originalServer.on('request', async (req: IncomingMessage, res: ServerResponse) => {
|
|
61
|
+
try {
|
|
62
|
+
const moroReq = await this.adaptRequest(req);
|
|
63
|
+
const moroRes = this.enhanceResponse(res);
|
|
64
|
+
|
|
65
|
+
await handler(moroReq, moroRes);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (!res.headersSent) {
|
|
68
|
+
res.statusCode = 500;
|
|
69
|
+
res.setHeader('Content-Type', 'application/json');
|
|
70
|
+
res.end(
|
|
71
|
+
JSON.stringify({
|
|
72
|
+
success: false,
|
|
73
|
+
error: 'Internal server error',
|
|
74
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
75
|
+
})
|
|
76
|
+
);
|
|
83
77
|
}
|
|
84
|
-
}
|
|
85
|
-
);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
86
80
|
|
|
87
81
|
return httpServer;
|
|
88
82
|
}
|
|
89
83
|
|
|
90
|
-
listen(
|
|
91
|
-
server: MoroHttpServer,
|
|
92
|
-
port: number,
|
|
93
|
-
host?: string,
|
|
94
|
-
callback?: () => void,
|
|
95
|
-
): void {
|
|
84
|
+
listen(server: MoroHttpServer, port: number, host?: string, callback?: () => void): void {
|
|
96
85
|
server.listen(port, host as any, callback);
|
|
97
86
|
}
|
|
98
87
|
|
|
99
88
|
// Helper methods
|
|
100
89
|
private async parseRequestBody(req: IncomingMessage): Promise<any> {
|
|
101
90
|
return new Promise((resolve, reject) => {
|
|
102
|
-
let body =
|
|
103
|
-
req.on(
|
|
91
|
+
let body = '';
|
|
92
|
+
req.on('data', chunk => {
|
|
104
93
|
body += chunk.toString();
|
|
105
94
|
});
|
|
106
|
-
req.on(
|
|
95
|
+
req.on('end', () => {
|
|
107
96
|
try {
|
|
108
|
-
const contentType = req.headers[
|
|
97
|
+
const contentType = req.headers['content-type'] || '';
|
|
109
98
|
resolve(this.parseBody(body, contentType));
|
|
110
99
|
} catch (error) {
|
|
111
100
|
reject(error);
|
|
112
101
|
}
|
|
113
102
|
});
|
|
114
|
-
req.on(
|
|
103
|
+
req.on('error', reject);
|
|
115
104
|
});
|
|
116
105
|
}
|
|
117
106
|
|
|
118
107
|
private getClientIP(req: IncomingMessage): string {
|
|
119
|
-
const forwarded = req.headers[
|
|
108
|
+
const forwarded = req.headers['x-forwarded-for'] as string;
|
|
120
109
|
if (forwarded) {
|
|
121
|
-
return forwarded.split(
|
|
110
|
+
return forwarded.split(',')[0].trim();
|
|
122
111
|
}
|
|
123
|
-
return req.socket.remoteAddress ||
|
|
112
|
+
return req.socket.remoteAddress || 'unknown';
|
|
124
113
|
}
|
|
125
114
|
|
|
126
115
|
private enhanceResponse(res: ServerResponse): HttpResponse {
|
|
@@ -129,7 +118,7 @@ export class NodeRuntimeAdapter extends BaseRuntimeAdapter {
|
|
|
129
118
|
// Add MoroJS response methods if they don't exist
|
|
130
119
|
if (!enhanced.json) {
|
|
131
120
|
enhanced.json = function (data: any) {
|
|
132
|
-
this.setHeader(
|
|
121
|
+
this.setHeader('Content-Type', 'application/json');
|
|
133
122
|
this.end(JSON.stringify(data));
|
|
134
123
|
};
|
|
135
124
|
}
|
|
@@ -150,17 +139,14 @@ export class NodeRuntimeAdapter extends BaseRuntimeAdapter {
|
|
|
150
139
|
if (!enhanced.cookie) {
|
|
151
140
|
enhanced.cookie = function (name: string, value: string, options?: any) {
|
|
152
141
|
const cookieString = `${name}=${value}`;
|
|
153
|
-
this.setHeader(
|
|
142
|
+
this.setHeader('Set-Cookie', cookieString);
|
|
154
143
|
return this;
|
|
155
144
|
};
|
|
156
145
|
}
|
|
157
146
|
|
|
158
147
|
if (!enhanced.clearCookie) {
|
|
159
148
|
enhanced.clearCookie = function (name: string, options?: any) {
|
|
160
|
-
this.setHeader(
|
|
161
|
-
"Set-Cookie",
|
|
162
|
-
`${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`,
|
|
163
|
-
);
|
|
149
|
+
this.setHeader('Set-Cookie', `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`);
|
|
164
150
|
return this;
|
|
165
151
|
};
|
|
166
152
|
}
|
|
@@ -168,15 +154,15 @@ export class NodeRuntimeAdapter extends BaseRuntimeAdapter {
|
|
|
168
154
|
if (!enhanced.redirect) {
|
|
169
155
|
enhanced.redirect = function (url: string, status?: number) {
|
|
170
156
|
this.statusCode = status || 302;
|
|
171
|
-
this.setHeader(
|
|
157
|
+
this.setHeader('Location', url);
|
|
172
158
|
this.end();
|
|
173
159
|
};
|
|
174
160
|
}
|
|
175
161
|
|
|
176
162
|
if (!enhanced.sendFile) {
|
|
177
163
|
enhanced.sendFile = async function (filePath: string) {
|
|
178
|
-
const fs = await import(
|
|
179
|
-
const path = await import(
|
|
164
|
+
const fs = await import('fs');
|
|
165
|
+
const path = await import('path');
|
|
180
166
|
|
|
181
167
|
try {
|
|
182
168
|
const data = await fs.promises.readFile(filePath);
|
|
@@ -184,23 +170,23 @@ export class NodeRuntimeAdapter extends BaseRuntimeAdapter {
|
|
|
184
170
|
|
|
185
171
|
// Basic content type detection
|
|
186
172
|
const contentTypes: Record<string, string> = {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
173
|
+
'.html': 'text/html',
|
|
174
|
+
'.js': 'application/javascript',
|
|
175
|
+
'.css': 'text/css',
|
|
176
|
+
'.json': 'application/json',
|
|
177
|
+
'.png': 'image/png',
|
|
178
|
+
'.jpg': 'image/jpeg',
|
|
179
|
+
'.jpeg': 'image/jpeg',
|
|
180
|
+
'.gif': 'image/gif',
|
|
181
|
+
'.svg': 'image/svg+xml',
|
|
196
182
|
};
|
|
197
183
|
|
|
198
|
-
const contentType = contentTypes[ext] ||
|
|
199
|
-
this.setHeader(
|
|
184
|
+
const contentType = contentTypes[ext] || 'application/octet-stream';
|
|
185
|
+
this.setHeader('Content-Type', contentType);
|
|
200
186
|
this.end(data);
|
|
201
187
|
} catch (error) {
|
|
202
188
|
this.statusCode = 404;
|
|
203
|
-
this.end(
|
|
189
|
+
this.end('File not found');
|
|
204
190
|
}
|
|
205
191
|
};
|
|
206
192
|
}
|