@mionjs/platform-node 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,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const src_mionHttp = require("./src/mionHttp.cjs");
4
+ const src_constants = require("./src/constants.cjs");
5
+ exports.httpRequestHandler = src_mionHttp.httpRequestHandler;
6
+ exports.resetNodeHttpOpts = src_mionHttp.resetNodeHttpOpts;
7
+ exports.setNodeHttpOpts = src_mionHttp.setNodeHttpOpts;
8
+ exports.startNodeServer = src_mionHttp.startNodeServer;
9
+ exports.ACCEPT_JSON = src_constants.ACCEPT_JSON;
10
+ exports.CONTENT_TYPE_HEADER_NAME = src_constants.CONTENT_TYPE_HEADER_NAME;
11
+ exports.DEFAULT_HTTP_OPTIONS = src_constants.DEFAULT_HTTP_OPTIONS;
12
+ exports.JSON_CONTENT_TYPE = src_constants.JSON_CONTENT_TYPE;
13
+ exports.JSON_TYPE_HEADER = src_constants.JSON_TYPE_HEADER;
14
+ //# 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/mionHttp.ts';
2
+ export * from './src/types.ts';
3
+ export * from './src/constants.ts';
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const CONTENT_TYPE_HEADER_NAME = "content-type";
4
+ const ACCEPT_JSON = "application/json";
5
+ const JSON_CONTENT_TYPE = "application/json; charset=utf-8";
6
+ const JSON_TYPE_HEADER = { CONTENT_TYPE_HEADER_NAME: JSON_CONTENT_TYPE };
7
+ const DEFAULT_HTTP_OPTIONS = {
8
+ protocol: "http",
9
+ port: 80,
10
+ options: {
11
+ /** @default 8KB same as default value in new node versions */
12
+ maxHeaderSize: 8192
13
+ },
14
+ defaultResponseHeaders: {},
15
+ /**
16
+ * 256KB by default, same as lambda payload
17
+ * @link https://docs.aws.amazon.com/lambda/latest/operatorguide/payload.html
18
+ * */
19
+ maxBodySize: 256e3
20
+ // 256KB
21
+ };
22
+ exports.ACCEPT_JSON = ACCEPT_JSON;
23
+ exports.CONTENT_TYPE_HEADER_NAME = CONTENT_TYPE_HEADER_NAME;
24
+ exports.DEFAULT_HTTP_OPTIONS = DEFAULT_HTTP_OPTIONS;
25
+ exports.JSON_CONTENT_TYPE = JSON_CONTENT_TYPE;
26
+ exports.JSON_TYPE_HEADER = JSON_TYPE_HEADER;
27
+ //# sourceMappingURL=constants.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.cjs","sources":["../../../src/constants.ts"],"sourcesContent":["/* ########\n * 2022 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {NodeHttpOptions} from './types.ts';\n\nexport const CONTENT_TYPE_HEADER_NAME = 'content-type';\nexport const ACCEPT_JSON = 'application/json';\nexport const JSON_CONTENT_TYPE = 'application/json; charset=utf-8';\nexport const JSON_TYPE_HEADER = {CONTENT_TYPE_HEADER_NAME: JSON_CONTENT_TYPE};\n\nexport const DEFAULT_HTTP_OPTIONS: NodeHttpOptions = {\n protocol: 'http',\n port: 80,\n options: {\n /** @default 8KB same as default value in new node versions */\n maxHeaderSize: 8192,\n },\n defaultResponseHeaders: {},\n /**\n * 256KB by default, same as lambda payload\n * @link https://docs.aws.amazon.com/lambda/latest/operatorguide/payload.html\n * */\n maxBodySize: 256000, // 256KB\n};\n"],"names":[],"mappings":";;AASO,MAAM,2BAA2B;AACjC,MAAM,cAAc;AACpB,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB,EAAC,0BAA0B,kBAAA;AAEpD,MAAM,uBAAwC;AAAA,EACjD,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA;AAAA,IAEL,eAAe;AAAA,EAAA;AAAA,EAEnB,wBAAwB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKxB,aAAa;AAAA;AACjB;;;;;;"}
@@ -0,0 +1,8 @@
1
+ import { NodeHttpOptions } from './types.ts';
2
+ export declare const CONTENT_TYPE_HEADER_NAME = "content-type";
3
+ export declare const ACCEPT_JSON = "application/json";
4
+ export declare const JSON_CONTENT_TYPE = "application/json; charset=utf-8";
5
+ export declare const JSON_TYPE_HEADER: {
6
+ CONTENT_TYPE_HEADER_NAME: string;
7
+ };
8
+ export declare const DEFAULT_HTTP_OPTIONS: NodeHttpOptions;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const router = require("@mionjs/router");
4
+ function headersFromIncomingMessage(rawRequest) {
5
+ return router.headersFromRecord(rawRequest.headers, true);
6
+ }
7
+ class ServerResponseHeadersImpl {
8
+ constructor(resp) {
9
+ this.resp = resp;
10
+ }
11
+ append(name, value) {
12
+ this.resp.appendHeader(name, value);
13
+ }
14
+ delete(name) {
15
+ this.resp.removeHeader(name);
16
+ }
17
+ get(name) {
18
+ return toSingleHeader(this.resp.getHeader(name));
19
+ }
20
+ has(name) {
21
+ return this.resp.hasHeader(name);
22
+ }
23
+ set(name, value) {
24
+ this.resp.setHeader(name, value);
25
+ }
26
+ entries() {
27
+ return getSingleHeadersObj(this.resp).entries();
28
+ }
29
+ keys() {
30
+ return getSingleHeadersObj(this.resp).values();
31
+ }
32
+ values() {
33
+ return getSingleHeadersObj(this.resp).values();
34
+ }
35
+ }
36
+ function headersFromServerResponse(resp, initialHeaders) {
37
+ if (initialHeaders) Object.entries(initialHeaders).forEach(([name, value]) => resp.setHeader(name, value));
38
+ return new ServerResponseHeadersImpl(resp);
39
+ }
40
+ function toSingleHeader(value) {
41
+ if (!value) return void 0;
42
+ if (Array.isArray(value)) return value.join(", ");
43
+ return value;
44
+ }
45
+ function getSingleHeadersObj(resp) {
46
+ const entries = Object.entries(resp.getHeaders()).map(([name, value]) => [name, toSingleHeader(value)]);
47
+ return Object.fromEntries(entries);
48
+ }
49
+ exports.headersFromIncomingMessage = headersFromIncomingMessage;
50
+ exports.headersFromServerResponse = headersFromServerResponse;
51
+ //# sourceMappingURL=headers.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.cjs","sources":["../../../src/headers.ts"],"sourcesContent":["/* ########\n * 2022 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {MionHeaders, headersFromRecord} from '@mionjs/router';\nimport {IncomingMessage, ServerResponse} from 'http';\n\nexport function headersFromIncomingMessage(rawRequest: IncomingMessage): MionHeaders {\n return headersFromRecord(rawRequest.headers as any, true);\n}\n\n/**\n * Reusable class for managing HTTP response headers with ServerResponse integration\n * Provides a MionHeaders interface that wraps Node.js ServerResponse header methods\n */\nclass ServerResponseHeadersImpl implements MionHeaders {\n constructor(private resp: ServerResponse) {}\n\n append(name: string, value: string): void {\n this.resp.appendHeader(name, value);\n }\n\n delete(name: string): void {\n this.resp.removeHeader(name);\n }\n get(name: string): string | undefined | null {\n return toSingleHeader(this.resp.getHeader(name));\n }\n has(name: string): boolean {\n return this.resp.hasHeader(name);\n }\n set(name: string, value: string): void {\n this.resp.setHeader(name, value);\n }\n\n entries(): IterableIterator<[string, string]> {\n return getSingleHeadersObj(this.resp).entries();\n }\n\n keys(): IterableIterator<string> {\n return getSingleHeadersObj(this.resp).values();\n }\n\n values(): IterableIterator<string> {\n return getSingleHeadersObj(this.resp).values();\n }\n}\n\nexport function headersFromServerResponse(resp: ServerResponse, initialHeaders: Record<string, string> | null): MionHeaders {\n if (initialHeaders) Object.entries(initialHeaders).forEach(([name, value]) => resp.setHeader(name, value));\n return new ServerResponseHeadersImpl(resp);\n}\n\nfunction toSingleHeader(value: string | number | string[] | undefined): string | undefined {\n if (!value) return undefined;\n if (Array.isArray(value)) return value.join(', ');\n return value as string;\n}\n\nfunction getSingleHeadersObj(resp: ServerResponse) {\n const entries = Object.entries(resp.getHeaders()).map(([name, value]) => [name, toSingleHeader(value)]);\n return Object.fromEntries(entries);\n}\n"],"names":["headersFromRecord"],"mappings":";;;AAUO,SAAS,2BAA2B,YAA0C;AACjF,SAAOA,yBAAkB,WAAW,SAAgB,IAAI;AAC5D;AAMA,MAAM,0BAAiD;AAAA,EACnD,YAAoB,MAAsB;AAAtB,SAAA,OAAA;AAAA,EAAuB;AAAA,EAE3C,OAAO,MAAc,OAAqB;AACtC,SAAK,KAAK,aAAa,MAAM,KAAK;AAAA,EACtC;AAAA,EAEA,OAAO,MAAoB;AACvB,SAAK,KAAK,aAAa,IAAI;AAAA,EAC/B;AAAA,EACA,IAAI,MAAyC;AACzC,WAAO,eAAe,KAAK,KAAK,UAAU,IAAI,CAAC;AAAA,EACnD;AAAA,EACA,IAAI,MAAuB;AACvB,WAAO,KAAK,KAAK,UAAU,IAAI;AAAA,EACnC;AAAA,EACA,IAAI,MAAc,OAAqB;AACnC,SAAK,KAAK,UAAU,MAAM,KAAK;AAAA,EACnC;AAAA,EAEA,UAA8C;AAC1C,WAAO,oBAAoB,KAAK,IAAI,EAAE,QAAA;AAAA,EAC1C;AAAA,EAEA,OAAiC;AAC7B,WAAO,oBAAoB,KAAK,IAAI,EAAE,OAAA;AAAA,EAC1C;AAAA,EAEA,SAAmC;AAC/B,WAAO,oBAAoB,KAAK,IAAI,EAAE,OAAA;AAAA,EAC1C;AACJ;AAEO,SAAS,0BAA0B,MAAsB,gBAA4D;AACxH,MAAI,eAAgB,QAAO,QAAQ,cAAc,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,UAAU,MAAM,KAAK,CAAC;AACzG,SAAO,IAAI,0BAA0B,IAAI;AAC7C;AAEA,SAAS,eAAe,OAAmE;AACvF,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,KAAK,IAAI;AAChD,SAAO;AACX;AAEA,SAAS,oBAAoB,MAAsB;AAC/C,QAAM,UAAU,OAAO,QAAQ,KAAK,WAAA,CAAY,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,eAAe,KAAK,CAAC,CAAC;AACtG,SAAO,OAAO,YAAY,OAAO;AACrC;;;"}
@@ -0,0 +1,4 @@
1
+ import { MionHeaders } from '@mionjs/router';
2
+ import { IncomingMessage, ServerResponse } from 'http';
3
+ export declare function headersFromIncomingMessage(rawRequest: IncomingMessage): MionHeaders;
4
+ export declare function headersFromServerResponse(resp: ServerResponse, initialHeaders: Record<string, string> | null): MionHeaders;
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const router = require("@mionjs/router");
4
+ const http = require("http");
5
+ const https = require("https");
6
+ const src_constants = require("./constants.cjs");
7
+ const core = require("@mionjs/core");
8
+ const src_headers = require("./headers.cjs");
9
+ let httpOptions = { ...src_constants.DEFAULT_HTTP_OPTIONS };
10
+ function resetNodeHttpOpts() {
11
+ httpOptions = { ...src_constants.DEFAULT_HTTP_OPTIONS };
12
+ router.resetRouter();
13
+ }
14
+ function setNodeHttpOpts(options) {
15
+ httpOptions = {
16
+ ...httpOptions,
17
+ ...options
18
+ };
19
+ return httpOptions;
20
+ }
21
+ async function startNodeServer(options) {
22
+ const isTest = core.getENV("NODE_ENV") === "test";
23
+ const isCompiling = core.isMionCompileMode();
24
+ if (options) setNodeHttpOpts(options);
25
+ const port = httpOptions.port !== 80 ? `:${httpOptions.port}` : "";
26
+ const url = `${httpOptions.protocol}://localhost${port}`;
27
+ if (!isTest && !isCompiling)
28
+ console.log(`mion node server running on ${url}`, {
29
+ port: httpOptions.port,
30
+ httpOptions
31
+ });
32
+ return new Promise((resolve, reject) => {
33
+ const server = httpOptions.protocol === "https" ? https.createServer(httpOptions.options, httpRequestHandler) : http.createServer(httpOptions.options, httpRequestHandler);
34
+ if (isCompiling) {
35
+ console.log("Compiling routes metadata and skipping mion server initialization...");
36
+ return resolve(server);
37
+ }
38
+ server.on("error", (e) => {
39
+ reject(e);
40
+ });
41
+ server.listen(httpOptions.port, () => {
42
+ resolve(server);
43
+ });
44
+ const shutdownHandler = function() {
45
+ if (!isTest) console.log(`Shutting down mion server on ${url}`);
46
+ server.close(() => {
47
+ process.exit(0);
48
+ });
49
+ };
50
+ process.on("SIGINT", shutdownHandler);
51
+ process.on("SIGTERM", shutdownHandler);
52
+ });
53
+ }
54
+ function httpRequestHandler(httpReq, httpResponse) {
55
+ let replied = false;
56
+ const nodeUrl = httpReq.url || "/";
57
+ const queryIndex = nodeUrl.indexOf("?");
58
+ const path = queryIndex === -1 ? nodeUrl : nodeUrl.substring(0, queryIndex);
59
+ const urlQuery = queryIndex === -1 ? void 0 : nodeUrl.substring(queryIndex + 1);
60
+ let size = 0;
61
+ const bodyChunks = [];
62
+ httpResponse.setHeader("server", "@mionjs");
63
+ const reqHeaders = src_headers.headersFromIncomingMessage(httpReq);
64
+ const respHeaders = src_headers.headersFromServerResponse(httpResponse, httpOptions.defaultResponseHeaders);
65
+ httpReq.on("data", (data) => {
66
+ bodyChunks.push(data);
67
+ const chunkLength = bodyChunks[bodyChunks.length - 1].length;
68
+ size += chunkLength;
69
+ if (size > httpOptions.maxBodySize && !replied) {
70
+ replied = true;
71
+ const error = new core.RpcError({
72
+ publicMessage: "Payload Too Large",
73
+ type: "request-payload-too-large"
74
+ });
75
+ fatalFail(httpResponse, respHeaders, error);
76
+ }
77
+ });
78
+ httpReq.on("error", (e) => {
79
+ if (replied) return;
80
+ replied = true;
81
+ const error = new core.RpcError({
82
+ publicMessage: "Connection Error",
83
+ type: "request-connection-error",
84
+ originalError: e
85
+ });
86
+ fatalFail(httpResponse, respHeaders, error);
87
+ });
88
+ httpReq.on("end", async () => {
89
+ if (replied) return;
90
+ const buffer = Buffer.concat(bodyChunks);
91
+ const contentType = httpReq.headers["content-type"] || "";
92
+ const isBinary = contentType.startsWith("application/octet-stream");
93
+ let reqRawBody = isBinary ? buffer : buffer.toString();
94
+ let reqBodyType = isBinary ? core.SerializerModes.binary : core.SerializerModes.stringifyJson;
95
+ const queryBody = router.decodeQueryBody(urlQuery, reqRawBody || void 0);
96
+ if (queryBody) {
97
+ reqRawBody = queryBody.rawBody;
98
+ reqBodyType = queryBody.bodyType;
99
+ }
100
+ try {
101
+ const mionResponse = await router.dispatchRoute(
102
+ path,
103
+ reqRawBody,
104
+ reqHeaders,
105
+ respHeaders,
106
+ httpReq,
107
+ httpResponse,
108
+ reqBodyType,
109
+ urlQuery
110
+ );
111
+ if (replied || httpResponse.writableEnded) return;
112
+ replied = true;
113
+ reply(httpResponse, mionResponse);
114
+ } catch (e) {
115
+ if (replied) return;
116
+ replied = true;
117
+ const error = new core.RpcError({
118
+ publicMessage: "Unknown Error",
119
+ type: "unknown-error",
120
+ originalError: e
121
+ });
122
+ fatalFail(httpResponse, respHeaders, error);
123
+ }
124
+ });
125
+ httpResponse.on("error", (e) => {
126
+ if (replied) return;
127
+ replied = true;
128
+ const error = new core.RpcError({
129
+ publicMessage: "Connection Error",
130
+ type: "response-connection-error",
131
+ originalError: e
132
+ });
133
+ fatalFail(httpResponse, respHeaders, error);
134
+ });
135
+ }
136
+ function fatalFail(httpResponse, respHeaders, error) {
137
+ if (httpResponse.writableEnded) return;
138
+ const routeResponse = router.getRouterFatalErrorResponse(error, respHeaders);
139
+ reply(httpResponse, routeResponse);
140
+ }
141
+ function reply(httpResp, mionResp) {
142
+ httpResp.statusCode = mionResp.statusCode;
143
+ const bodyType = mionResp.serializer;
144
+ switch (bodyType) {
145
+ case core.SerializerModes.stringifyJson: {
146
+ const buffer = Buffer.from(mionResp.rawBody, "utf8");
147
+ httpResp.setHeader("content-length", buffer.byteLength);
148
+ httpResp.end(buffer);
149
+ break;
150
+ }
151
+ case core.SerializerModes.json: {
152
+ const jsonString = JSON.stringify(mionResp.body);
153
+ const buffer = Buffer.from(jsonString, "utf8");
154
+ httpResp.setHeader("content-length", buffer.byteLength);
155
+ httpResp.end(buffer);
156
+ break;
157
+ }
158
+ case core.SerializerModes.binary: {
159
+ const serializer = mionResp.binSerializer;
160
+ httpResp.setHeader("content-length", serializer.getLength());
161
+ httpResp.end(serializer.getBufferView());
162
+ const onFinish = () => serializer.markAsEnded();
163
+ httpResp.on("finish", onFinish);
164
+ httpResp.on("close", onFinish);
165
+ break;
166
+ }
167
+ default: {
168
+ const error = new core.RpcError({
169
+ publicMessage: "unknown-mion-response-format",
170
+ type: "unknown-error",
171
+ errorData: { bodyType }
172
+ });
173
+ fatalFail(httpResp, mionResp.headers, error);
174
+ }
175
+ }
176
+ }
177
+ exports.httpRequestHandler = httpRequestHandler;
178
+ exports.resetNodeHttpOpts = resetNodeHttpOpts;
179
+ exports.setNodeHttpOpts = setNodeHttpOpts;
180
+ exports.startNodeServer = startNodeServer;
181
+ //# sourceMappingURL=mionHttp.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mionHttp.cjs","sources":["../../../src/mionHttp.ts"],"sourcesContent":["/* ########\n * 2022 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} from '@mionjs/router';\nimport {createServer as createHttp} from 'http';\nimport {createServer as createHttps} from 'https';\nimport {DEFAULT_HTTP_OPTIONS} from './constants.ts';\nimport type {NodeHttpOptions} from './types.ts';\nimport type {IncomingMessage, Server as HttpServer, ServerResponse} from 'http';\nimport type {Server as HttpsServer} from 'https';\nimport type {MionHeaders, MionResponse} from '@mionjs/router';\nimport {getENV, isMionCompileMode, SerializerModes} from '@mionjs/core';\nimport type {SerializerCode} from '@mionjs/core';\nimport {RpcError} from '@mionjs/core';\nimport {headersFromIncomingMessage, headersFromServerResponse} from './headers.ts';\n\n// ############# PRIVATE STATE #############\n\nlet httpOptions: Readonly<NodeHttpOptions> = {...DEFAULT_HTTP_OPTIONS};\n\n// ############# PUBLIC METHODS #############\n\nexport function resetNodeHttpOpts() {\n httpOptions = {...DEFAULT_HTTP_OPTIONS};\n resetRouter();\n}\n\nexport function setNodeHttpOpts(options?: Partial<NodeHttpOptions>) {\n httpOptions = {\n ...httpOptions,\n ...options,\n };\n\n return httpOptions;\n}\n\nexport async function startNodeServer(options?: Partial<NodeHttpOptions>): Promise<HttpServer | HttpsServer> {\n const isTest = getENV('NODE_ENV') === 'test';\n const isCompiling = isMionCompileMode();\n\n if (options) setNodeHttpOpts(options);\n const port = httpOptions.port !== 80 ? `:${httpOptions.port}` : '';\n const url = `${httpOptions.protocol}://localhost${port}`;\n if (!isTest && !isCompiling)\n console.log(`mion node server running on ${url}`, {\n port: httpOptions.port,\n httpOptions,\n });\n\n return new Promise<HttpServer | HttpsServer>((resolve, reject) => {\n const server =\n httpOptions.protocol === 'https'\n ? createHttps(httpOptions.options, httpRequestHandler)\n : createHttp(httpOptions.options, httpRequestHandler);\n\n if (isCompiling) {\n console.log('Compiling routes metadata and skipping mion server initialization...');\n return resolve(server);\n }\n\n server.on('error', (e) => {\n reject(e);\n });\n\n server.listen(httpOptions.port, () => {\n resolve(server);\n });\n\n const shutdownHandler = function () {\n if (!isTest) console.log(`Shutting down mion server on ${url}`);\n server.close(() => {\n process.exit(0);\n });\n };\n\n process.on('SIGINT', shutdownHandler);\n process.on('SIGTERM', shutdownHandler);\n });\n}\n\n// ############# PRIVATE METHODS #############\n\n// exported as can be used in some server to proxy node requests\nexport function httpRequestHandler(httpReq: IncomingMessage, httpResponse: ServerResponse): void {\n let replied = false;\n const nodeUrl = httpReq.url || '/';\n const queryIndex = nodeUrl.indexOf('?');\n const path = queryIndex === -1 ? nodeUrl : nodeUrl.substring(0, queryIndex);\n const urlQuery = queryIndex === -1 ? undefined : nodeUrl.substring(queryIndex + 1);\n let size = 0;\n const bodyChunks: any[] = [];\n\n httpResponse.setHeader('server', '@mionjs');\n const reqHeaders = headersFromIncomingMessage(httpReq);\n const respHeaders = headersFromServerResponse(httpResponse, httpOptions.defaultResponseHeaders);\n\n httpReq.on('data', (data) => {\n bodyChunks.push(data);\n const chunkLength = bodyChunks[bodyChunks.length - 1].length;\n size += chunkLength;\n if (size > httpOptions.maxBodySize && !replied) {\n replied = true;\n const error = new RpcError({\n publicMessage: 'Payload Too Large',\n type: 'request-payload-too-large',\n });\n fatalFail(httpResponse, respHeaders, error);\n }\n });\n\n httpReq.on('error', (e) => {\n if (replied) return;\n replied = true;\n const error = new RpcError({\n publicMessage: 'Connection Error',\n type: 'request-connection-error',\n originalError: e,\n });\n fatalFail(httpResponse, respHeaders, error);\n });\n\n httpReq.on('end', async () => {\n if (replied) return;\n const buffer = Buffer.concat(bodyChunks);\n const contentType = httpReq.headers['content-type'] || '';\n const isBinary = contentType.startsWith('application/octet-stream');\n let reqRawBody: any = isBinary ? buffer : buffer.toString();\n let reqBodyType: SerializerCode = isBinary ? SerializerModes.binary : SerializerModes.stringifyJson;\n const queryBody = decodeQueryBody(urlQuery, reqRawBody || undefined);\n if (queryBody) {\n reqRawBody = queryBody.rawBody;\n reqBodyType = queryBody.bodyType;\n }\n\n try {\n const mionResponse = await dispatchRoute(\n path,\n reqRawBody,\n reqHeaders,\n respHeaders,\n httpReq,\n httpResponse,\n reqBodyType,\n urlQuery\n );\n if (replied || httpResponse.writableEnded) return;\n replied = true;\n reply(httpResponse, mionResponse);\n } catch (e) {\n if (replied) return;\n replied = true;\n const error = new RpcError({\n publicMessage: 'Unknown Error',\n type: 'unknown-error',\n originalError: e as Error,\n });\n fatalFail(httpResponse, respHeaders, error);\n }\n });\n\n httpResponse.on('error', (e) => {\n if (replied) return;\n replied = true;\n const error = new RpcError({\n publicMessage: 'Connection Error',\n type: 'response-connection-error',\n originalError: e,\n });\n fatalFail(httpResponse, respHeaders, error);\n });\n}\n\n// only called when there is an http error or weird unhandled route errors\nfunction fatalFail(httpResponse: ServerResponse, respHeaders: MionHeaders, error: RpcError<string>) {\n if (httpResponse.writableEnded) return;\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(httpResponse, routeResponse);\n}\n\nfunction reply(httpResp: ServerResponse, mionResp: MionResponse) {\n httpResp.statusCode = mionResp.statusCode;\n const bodyType = mionResp.serializer;\n switch (bodyType) {\n case SerializerModes.stringifyJson: {\n const buffer = Buffer.from(mionResp.rawBody as string, 'utf8');\n httpResp.setHeader('content-length', buffer.byteLength);\n // content-type already set by serializer\n httpResp.end(buffer);\n break;\n }\n case SerializerModes.json: {\n // Platform adapter stringifies the prepared body object\n const jsonString = JSON.stringify(mionResp.body);\n const buffer = Buffer.from(jsonString, 'utf8');\n httpResp.setHeader('content-length', buffer.byteLength);\n httpResp.end(buffer);\n break;\n }\n case SerializerModes.binary: {\n const serializer = mionResp.binSerializer!;\n httpResp.setHeader('content-length', serializer.getLength());\n // content-type already set by serializer\n httpResp.end(serializer.getBufferView());\n // Release buffer when response is finished\n const onFinish = () => serializer.markAsEnded();\n httpResp.on('finish', onFinish);\n httpResp.on('close', onFinish); // Fallback for aborted connection\n break;\n }\n default: {\n const error = new RpcError({\n publicMessage: 'unknown-mion-response-format',\n type: 'unknown-error',\n errorData: {bodyType},\n });\n fatalFail(httpResp, mionResp.headers, error);\n }\n }\n}\n"],"names":["DEFAULT_HTTP_OPTIONS","resetRouter","getENV","isMionCompileMode","createHttps","createHttp","headersFromIncomingMessage","headersFromServerResponse","RpcError","SerializerModes","decodeQueryBody","dispatchRoute","getRouterFatalErrorResponse"],"mappings":";;;;;;;;AAsBA,IAAI,cAAyC,EAAC,GAAGA,mCAAA;AAI1C,SAAS,oBAAoB;AAChC,gBAAc,EAAC,GAAGA,mCAAA;AAClBC,qBAAA;AACJ;AAEO,SAAS,gBAAgB,SAAoC;AAChE,gBAAc;AAAA,IACV,GAAG;AAAA,IACH,GAAG;AAAA,EAAA;AAGP,SAAO;AACX;AAEA,eAAsB,gBAAgB,SAAuE;AACzG,QAAM,SAASC,KAAAA,OAAO,UAAU,MAAM;AACtC,QAAM,cAAcC,KAAAA,kBAAA;AAEpB,MAAI,yBAAyB,OAAO;AACpC,QAAM,OAAO,YAAY,SAAS,KAAK,IAAI,YAAY,IAAI,KAAK;AAChE,QAAM,MAAM,GAAG,YAAY,QAAQ,eAAe,IAAI;AACtD,MAAI,CAAC,UAAU,CAAC;AACZ,YAAQ,IAAI,+BAA+B,GAAG,IAAI;AAAA,MAC9C,MAAM,YAAY;AAAA,MAClB;AAAA,IAAA,CACH;AAEL,SAAO,IAAI,QAAkC,CAAC,SAAS,WAAW;AAC9D,UAAM,SACF,YAAY,aAAa,UACnBC,MAAAA,aAAY,YAAY,SAAS,kBAAkB,IACnDC,KAAAA,aAAW,YAAY,SAAS,kBAAkB;AAE5D,QAAI,aAAa;AACb,cAAQ,IAAI,sEAAsE;AAClF,aAAO,QAAQ,MAAM;AAAA,IACzB;AAEA,WAAO,GAAG,SAAS,CAAC,MAAM;AACtB,aAAO,CAAC;AAAA,IACZ,CAAC;AAED,WAAO,OAAO,YAAY,MAAM,MAAM;AAClC,cAAQ,MAAM;AAAA,IAClB,CAAC;AAED,UAAM,kBAAkB,WAAY;AAChC,UAAI,CAAC,OAAQ,SAAQ,IAAI,gCAAgC,GAAG,EAAE;AAC9D,aAAO,MAAM,MAAM;AACf,gBAAQ,KAAK,CAAC;AAAA,MAClB,CAAC;AAAA,IACL;AAEA,YAAQ,GAAG,UAAU,eAAe;AACpC,YAAQ,GAAG,WAAW,eAAe;AAAA,EACzC,CAAC;AACL;AAKO,SAAS,mBAAmB,SAA0B,cAAoC;AAC7F,MAAI,UAAU;AACd,QAAM,UAAU,QAAQ,OAAO;AAC/B,QAAM,aAAa,QAAQ,QAAQ,GAAG;AACtC,QAAM,OAAO,eAAe,KAAK,UAAU,QAAQ,UAAU,GAAG,UAAU;AAC1E,QAAM,WAAW,eAAe,KAAK,SAAY,QAAQ,UAAU,aAAa,CAAC;AACjF,MAAI,OAAO;AACX,QAAM,aAAoB,CAAA;AAE1B,eAAa,UAAU,UAAU,SAAS;AAC1C,QAAM,aAAaC,YAAAA,2BAA2B,OAAO;AACrD,QAAM,cAAcC,YAAAA,0BAA0B,cAAc,YAAY,sBAAsB;AAE9F,UAAQ,GAAG,QAAQ,CAAC,SAAS;AACzB,eAAW,KAAK,IAAI;AACpB,UAAM,cAAc,WAAW,WAAW,SAAS,CAAC,EAAE;AACtD,YAAQ;AACR,QAAI,OAAO,YAAY,eAAe,CAAC,SAAS;AAC5C,gBAAU;AACV,YAAM,QAAQ,IAAIC,cAAS;AAAA,QACvB,eAAe;AAAA,QACf,MAAM;AAAA,MAAA,CACT;AACD,gBAAU,cAAc,aAAa,KAAK;AAAA,IAC9C;AAAA,EACJ,CAAC;AAED,UAAQ,GAAG,SAAS,CAAC,MAAM;AACvB,QAAI,QAAS;AACb,cAAU;AACV,UAAM,QAAQ,IAAIA,cAAS;AAAA,MACvB,eAAe;AAAA,MACf,MAAM;AAAA,MACN,eAAe;AAAA,IAAA,CAClB;AACD,cAAU,cAAc,aAAa,KAAK;AAAA,EAC9C,CAAC;AAED,UAAQ,GAAG,OAAO,YAAY;AAC1B,QAAI,QAAS;AACb,UAAM,SAAS,OAAO,OAAO,UAAU;AACvC,UAAM,cAAc,QAAQ,QAAQ,cAAc,KAAK;AACvD,UAAM,WAAW,YAAY,WAAW,0BAA0B;AAClE,QAAI,aAAkB,WAAW,SAAS,OAAO,SAAA;AACjD,QAAI,cAA8B,WAAWC,KAAAA,gBAAgB,SAASA,KAAAA,gBAAgB;AACtF,UAAM,YAAYC,OAAAA,gBAAgB,UAAU,cAAc,MAAS;AACnE,QAAI,WAAW;AACX,mBAAa,UAAU;AACvB,oBAAc,UAAU;AAAA,IAC5B;AAEA,QAAI;AACA,YAAM,eAAe,MAAMC,OAAAA;AAAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAEJ,UAAI,WAAW,aAAa,cAAe;AAC3C,gBAAU;AACV,YAAM,cAAc,YAAY;AAAA,IACpC,SAAS,GAAG;AACR,UAAI,QAAS;AACb,gBAAU;AACV,YAAM,QAAQ,IAAIH,cAAS;AAAA,QACvB,eAAe;AAAA,QACf,MAAM;AAAA,QACN,eAAe;AAAA,MAAA,CAClB;AACD,gBAAU,cAAc,aAAa,KAAK;AAAA,IAC9C;AAAA,EACJ,CAAC;AAED,eAAa,GAAG,SAAS,CAAC,MAAM;AAC5B,QAAI,QAAS;AACb,cAAU;AACV,UAAM,QAAQ,IAAIA,cAAS;AAAA,MACvB,eAAe;AAAA,MACf,MAAM;AAAA,MACN,eAAe;AAAA,IAAA,CAClB;AACD,cAAU,cAAc,aAAa,KAAK;AAAA,EAC9C,CAAC;AACL;AAGA,SAAS,UAAU,cAA8B,aAA0B,OAAyB;AAChG,MAAI,aAAa,cAAe;AAChC,QAAM,gBAAgBI,OAAAA,4BAA4B,OAAO,WAAW;AACpE,QAAM,cAAc,aAAa;AACrC;AAEA,SAAS,MAAM,UAA0B,UAAwB;AAC7D,WAAS,aAAa,SAAS;AAC/B,QAAM,WAAW,SAAS;AAC1B,UAAQ,UAAA;AAAA,IACJ,KAAKH,KAAAA,gBAAgB,eAAe;AAChC,YAAM,SAAS,OAAO,KAAK,SAAS,SAAmB,MAAM;AAC7D,eAAS,UAAU,kBAAkB,OAAO,UAAU;AAEtD,eAAS,IAAI,MAAM;AACnB;AAAA,IACJ;AAAA,IACA,KAAKA,KAAAA,gBAAgB,MAAM;AAEvB,YAAM,aAAa,KAAK,UAAU,SAAS,IAAI;AAC/C,YAAM,SAAS,OAAO,KAAK,YAAY,MAAM;AAC7C,eAAS,UAAU,kBAAkB,OAAO,UAAU;AACtD,eAAS,IAAI,MAAM;AACnB;AAAA,IACJ;AAAA,IACA,KAAKA,KAAAA,gBAAgB,QAAQ;AACzB,YAAM,aAAa,SAAS;AAC5B,eAAS,UAAU,kBAAkB,WAAW,UAAA,CAAW;AAE3D,eAAS,IAAI,WAAW,eAAe;AAEvC,YAAM,WAAW,MAAM,WAAW,YAAA;AAClC,eAAS,GAAG,UAAU,QAAQ;AAC9B,eAAS,GAAG,SAAS,QAAQ;AAC7B;AAAA,IACJ;AAAA,IACA,SAAS;AACL,YAAM,QAAQ,IAAID,cAAS;AAAA,QACvB,eAAe;AAAA,QACf,MAAM;AAAA,QACN,WAAW,EAAC,SAAA;AAAA,MAAQ,CACvB;AACD,gBAAU,UAAU,SAAS,SAAS,KAAK;AAAA,IAC/C;AAAA,EAAA;AAER;;;;;"}
@@ -0,0 +1,7 @@
1
+ import { NodeHttpOptions } from './types.ts';
2
+ import { IncomingMessage, Server as HttpServer, ServerResponse } from 'http';
3
+ import { Server as HttpsServer } from 'https';
4
+ export declare function resetNodeHttpOpts(): void;
5
+ export declare function setNodeHttpOpts(options?: Partial<NodeHttpOptions>): Readonly<NodeHttpOptions>;
6
+ export declare function startNodeServer(options?: Partial<NodeHttpOptions>): Promise<HttpServer | HttpsServer>;
7
+ export declare function httpRequestHandler(httpReq: IncomingMessage, httpResponse: ServerResponse): void;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import { ServerOptions } from 'https';
2
+ export interface NodeHttpOptions {
3
+ protocol: 'http' | 'https';
4
+ port: number;
5
+ options: ServerOptions;
6
+ defaultResponseHeaders: Record<string, string>;
7
+ maxBodySize: number;
8
+ }
9
+ export declare type __ΩNodeHttpOptions = any[];
@@ -0,0 +1,3 @@
1
+ export * from './src/mionHttp.ts';
2
+ export * from './src/types.ts';
3
+ export * from './src/constants.ts';
@@ -0,0 +1,14 @@
1
+ import { httpRequestHandler, resetNodeHttpOpts, setNodeHttpOpts, startNodeServer } from "./src/mionHttp.js";
2
+ import { ACCEPT_JSON, CONTENT_TYPE_HEADER_NAME, DEFAULT_HTTP_OPTIONS, JSON_CONTENT_TYPE, JSON_TYPE_HEADER } from "./src/constants.js";
3
+ export {
4
+ ACCEPT_JSON,
5
+ CONTENT_TYPE_HEADER_NAME,
6
+ DEFAULT_HTTP_OPTIONS,
7
+ JSON_CONTENT_TYPE,
8
+ JSON_TYPE_HEADER,
9
+ httpRequestHandler,
10
+ resetNodeHttpOpts,
11
+ setNodeHttpOpts,
12
+ startNodeServer
13
+ };
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -0,0 +1,8 @@
1
+ import { NodeHttpOptions } from './types.ts';
2
+ export declare const CONTENT_TYPE_HEADER_NAME = "content-type";
3
+ export declare const ACCEPT_JSON = "application/json";
4
+ export declare const JSON_CONTENT_TYPE = "application/json; charset=utf-8";
5
+ export declare const JSON_TYPE_HEADER: {
6
+ CONTENT_TYPE_HEADER_NAME: string;
7
+ };
8
+ export declare const DEFAULT_HTTP_OPTIONS: NodeHttpOptions;
@@ -0,0 +1,27 @@
1
+ const CONTENT_TYPE_HEADER_NAME = "content-type";
2
+ const ACCEPT_JSON = "application/json";
3
+ const JSON_CONTENT_TYPE = "application/json; charset=utf-8";
4
+ const JSON_TYPE_HEADER = { CONTENT_TYPE_HEADER_NAME: JSON_CONTENT_TYPE };
5
+ const DEFAULT_HTTP_OPTIONS = {
6
+ protocol: "http",
7
+ port: 80,
8
+ options: {
9
+ /** @default 8KB same as default value in new node versions */
10
+ maxHeaderSize: 8192
11
+ },
12
+ defaultResponseHeaders: {},
13
+ /**
14
+ * 256KB by default, same as lambda payload
15
+ * @link https://docs.aws.amazon.com/lambda/latest/operatorguide/payload.html
16
+ * */
17
+ maxBodySize: 256e3
18
+ // 256KB
19
+ };
20
+ export {
21
+ ACCEPT_JSON,
22
+ CONTENT_TYPE_HEADER_NAME,
23
+ DEFAULT_HTTP_OPTIONS,
24
+ JSON_CONTENT_TYPE,
25
+ JSON_TYPE_HEADER
26
+ };
27
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../../src/constants.ts"],"sourcesContent":["/* ########\n * 2022 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {NodeHttpOptions} from './types.ts';\n\nexport const CONTENT_TYPE_HEADER_NAME = 'content-type';\nexport const ACCEPT_JSON = 'application/json';\nexport const JSON_CONTENT_TYPE = 'application/json; charset=utf-8';\nexport const JSON_TYPE_HEADER = {CONTENT_TYPE_HEADER_NAME: JSON_CONTENT_TYPE};\n\nexport const DEFAULT_HTTP_OPTIONS: NodeHttpOptions = {\n protocol: 'http',\n port: 80,\n options: {\n /** @default 8KB same as default value in new node versions */\n maxHeaderSize: 8192,\n },\n defaultResponseHeaders: {},\n /**\n * 256KB by default, same as lambda payload\n * @link https://docs.aws.amazon.com/lambda/latest/operatorguide/payload.html\n * */\n maxBodySize: 256000, // 256KB\n};\n"],"names":[],"mappings":"AASO,MAAM,2BAA2B;AACjC,MAAM,cAAc;AACpB,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB,EAAC,0BAA0B,kBAAA;AAEpD,MAAM,uBAAwC;AAAA,EACjD,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA;AAAA,IAEL,eAAe;AAAA,EAAA;AAAA,EAEnB,wBAAwB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKxB,aAAa;AAAA;AACjB;"}
@@ -0,0 +1,4 @@
1
+ import { MionHeaders } from '@mionjs/router';
2
+ import { IncomingMessage, ServerResponse } from 'http';
3
+ export declare function headersFromIncomingMessage(rawRequest: IncomingMessage): MionHeaders;
4
+ export declare function headersFromServerResponse(resp: ServerResponse, initialHeaders: Record<string, string> | null): MionHeaders;
@@ -0,0 +1,51 @@
1
+ import { headersFromRecord } from "@mionjs/router";
2
+ function headersFromIncomingMessage(rawRequest) {
3
+ return headersFromRecord(rawRequest.headers, true);
4
+ }
5
+ class ServerResponseHeadersImpl {
6
+ constructor(resp) {
7
+ this.resp = resp;
8
+ }
9
+ append(name, value) {
10
+ this.resp.appendHeader(name, value);
11
+ }
12
+ delete(name) {
13
+ this.resp.removeHeader(name);
14
+ }
15
+ get(name) {
16
+ return toSingleHeader(this.resp.getHeader(name));
17
+ }
18
+ has(name) {
19
+ return this.resp.hasHeader(name);
20
+ }
21
+ set(name, value) {
22
+ this.resp.setHeader(name, value);
23
+ }
24
+ entries() {
25
+ return getSingleHeadersObj(this.resp).entries();
26
+ }
27
+ keys() {
28
+ return getSingleHeadersObj(this.resp).values();
29
+ }
30
+ values() {
31
+ return getSingleHeadersObj(this.resp).values();
32
+ }
33
+ }
34
+ function headersFromServerResponse(resp, initialHeaders) {
35
+ if (initialHeaders) Object.entries(initialHeaders).forEach(([name, value]) => resp.setHeader(name, value));
36
+ return new ServerResponseHeadersImpl(resp);
37
+ }
38
+ function toSingleHeader(value) {
39
+ if (!value) return void 0;
40
+ if (Array.isArray(value)) return value.join(", ");
41
+ return value;
42
+ }
43
+ function getSingleHeadersObj(resp) {
44
+ const entries = Object.entries(resp.getHeaders()).map(([name, value]) => [name, toSingleHeader(value)]);
45
+ return Object.fromEntries(entries);
46
+ }
47
+ export {
48
+ headersFromIncomingMessage,
49
+ headersFromServerResponse
50
+ };
51
+ //# sourceMappingURL=headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.js","sources":["../../../src/headers.ts"],"sourcesContent":["/* ########\n * 2022 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {MionHeaders, headersFromRecord} from '@mionjs/router';\nimport {IncomingMessage, ServerResponse} from 'http';\n\nexport function headersFromIncomingMessage(rawRequest: IncomingMessage): MionHeaders {\n return headersFromRecord(rawRequest.headers as any, true);\n}\n\n/**\n * Reusable class for managing HTTP response headers with ServerResponse integration\n * Provides a MionHeaders interface that wraps Node.js ServerResponse header methods\n */\nclass ServerResponseHeadersImpl implements MionHeaders {\n constructor(private resp: ServerResponse) {}\n\n append(name: string, value: string): void {\n this.resp.appendHeader(name, value);\n }\n\n delete(name: string): void {\n this.resp.removeHeader(name);\n }\n get(name: string): string | undefined | null {\n return toSingleHeader(this.resp.getHeader(name));\n }\n has(name: string): boolean {\n return this.resp.hasHeader(name);\n }\n set(name: string, value: string): void {\n this.resp.setHeader(name, value);\n }\n\n entries(): IterableIterator<[string, string]> {\n return getSingleHeadersObj(this.resp).entries();\n }\n\n keys(): IterableIterator<string> {\n return getSingleHeadersObj(this.resp).values();\n }\n\n values(): IterableIterator<string> {\n return getSingleHeadersObj(this.resp).values();\n }\n}\n\nexport function headersFromServerResponse(resp: ServerResponse, initialHeaders: Record<string, string> | null): MionHeaders {\n if (initialHeaders) Object.entries(initialHeaders).forEach(([name, value]) => resp.setHeader(name, value));\n return new ServerResponseHeadersImpl(resp);\n}\n\nfunction toSingleHeader(value: string | number | string[] | undefined): string | undefined {\n if (!value) return undefined;\n if (Array.isArray(value)) return value.join(', ');\n return value as string;\n}\n\nfunction getSingleHeadersObj(resp: ServerResponse) {\n const entries = Object.entries(resp.getHeaders()).map(([name, value]) => [name, toSingleHeader(value)]);\n return Object.fromEntries(entries);\n}\n"],"names":[],"mappings":";AAUO,SAAS,2BAA2B,YAA0C;AACjF,SAAO,kBAAkB,WAAW,SAAgB,IAAI;AAC5D;AAMA,MAAM,0BAAiD;AAAA,EACnD,YAAoB,MAAsB;AAAtB,SAAA,OAAA;AAAA,EAAuB;AAAA,EAE3C,OAAO,MAAc,OAAqB;AACtC,SAAK,KAAK,aAAa,MAAM,KAAK;AAAA,EACtC;AAAA,EAEA,OAAO,MAAoB;AACvB,SAAK,KAAK,aAAa,IAAI;AAAA,EAC/B;AAAA,EACA,IAAI,MAAyC;AACzC,WAAO,eAAe,KAAK,KAAK,UAAU,IAAI,CAAC;AAAA,EACnD;AAAA,EACA,IAAI,MAAuB;AACvB,WAAO,KAAK,KAAK,UAAU,IAAI;AAAA,EACnC;AAAA,EACA,IAAI,MAAc,OAAqB;AACnC,SAAK,KAAK,UAAU,MAAM,KAAK;AAAA,EACnC;AAAA,EAEA,UAA8C;AAC1C,WAAO,oBAAoB,KAAK,IAAI,EAAE,QAAA;AAAA,EAC1C;AAAA,EAEA,OAAiC;AAC7B,WAAO,oBAAoB,KAAK,IAAI,EAAE,OAAA;AAAA,EAC1C;AAAA,EAEA,SAAmC;AAC/B,WAAO,oBAAoB,KAAK,IAAI,EAAE,OAAA;AAAA,EAC1C;AACJ;AAEO,SAAS,0BAA0B,MAAsB,gBAA4D;AACxH,MAAI,eAAgB,QAAO,QAAQ,cAAc,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,UAAU,MAAM,KAAK,CAAC;AACzG,SAAO,IAAI,0BAA0B,IAAI;AAC7C;AAEA,SAAS,eAAe,OAAmE;AACvF,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,KAAK,IAAI;AAChD,SAAO;AACX;AAEA,SAAS,oBAAoB,MAAsB;AAC/C,QAAM,UAAU,OAAO,QAAQ,KAAK,WAAA,CAAY,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,eAAe,KAAK,CAAC,CAAC;AACtG,SAAO,OAAO,YAAY,OAAO;AACrC;"}
@@ -0,0 +1,7 @@
1
+ import { NodeHttpOptions } from './types.ts';
2
+ import { IncomingMessage, Server as HttpServer, ServerResponse } from 'http';
3
+ import { Server as HttpsServer } from 'https';
4
+ export declare function resetNodeHttpOpts(): void;
5
+ export declare function setNodeHttpOpts(options?: Partial<NodeHttpOptions>): Readonly<NodeHttpOptions>;
6
+ export declare function startNodeServer(options?: Partial<NodeHttpOptions>): Promise<HttpServer | HttpsServer>;
7
+ export declare function httpRequestHandler(httpReq: IncomingMessage, httpResponse: ServerResponse): void;
@@ -0,0 +1,181 @@
1
+ import { decodeQueryBody, dispatchRoute, resetRouter, getRouterFatalErrorResponse } from "@mionjs/router";
2
+ import { createServer as createServer$1 } from "http";
3
+ import { createServer } from "https";
4
+ import { DEFAULT_HTTP_OPTIONS } from "./constants.js";
5
+ import { RpcError, SerializerModes, getENV, isMionCompileMode } from "@mionjs/core";
6
+ import { headersFromIncomingMessage, headersFromServerResponse } from "./headers.js";
7
+ let httpOptions = { ...DEFAULT_HTTP_OPTIONS };
8
+ function resetNodeHttpOpts() {
9
+ httpOptions = { ...DEFAULT_HTTP_OPTIONS };
10
+ resetRouter();
11
+ }
12
+ function setNodeHttpOpts(options) {
13
+ httpOptions = {
14
+ ...httpOptions,
15
+ ...options
16
+ };
17
+ return httpOptions;
18
+ }
19
+ async function startNodeServer(options) {
20
+ const isTest = getENV("NODE_ENV") === "test";
21
+ const isCompiling = isMionCompileMode();
22
+ if (options) setNodeHttpOpts(options);
23
+ const port = httpOptions.port !== 80 ? `:${httpOptions.port}` : "";
24
+ const url = `${httpOptions.protocol}://localhost${port}`;
25
+ if (!isTest && !isCompiling)
26
+ console.log(`mion node server running on ${url}`, {
27
+ port: httpOptions.port,
28
+ httpOptions
29
+ });
30
+ return new Promise((resolve, reject) => {
31
+ const server = httpOptions.protocol === "https" ? createServer(httpOptions.options, httpRequestHandler) : createServer$1(httpOptions.options, httpRequestHandler);
32
+ if (isCompiling) {
33
+ console.log("Compiling routes metadata and skipping mion server initialization...");
34
+ return resolve(server);
35
+ }
36
+ server.on("error", (e) => {
37
+ reject(e);
38
+ });
39
+ server.listen(httpOptions.port, () => {
40
+ resolve(server);
41
+ });
42
+ const shutdownHandler = function() {
43
+ if (!isTest) console.log(`Shutting down mion server on ${url}`);
44
+ server.close(() => {
45
+ process.exit(0);
46
+ });
47
+ };
48
+ process.on("SIGINT", shutdownHandler);
49
+ process.on("SIGTERM", shutdownHandler);
50
+ });
51
+ }
52
+ function httpRequestHandler(httpReq, httpResponse) {
53
+ let replied = false;
54
+ const nodeUrl = httpReq.url || "/";
55
+ const queryIndex = nodeUrl.indexOf("?");
56
+ const path = queryIndex === -1 ? nodeUrl : nodeUrl.substring(0, queryIndex);
57
+ const urlQuery = queryIndex === -1 ? void 0 : nodeUrl.substring(queryIndex + 1);
58
+ let size = 0;
59
+ const bodyChunks = [];
60
+ httpResponse.setHeader("server", "@mionjs");
61
+ const reqHeaders = headersFromIncomingMessage(httpReq);
62
+ const respHeaders = headersFromServerResponse(httpResponse, httpOptions.defaultResponseHeaders);
63
+ httpReq.on("data", (data) => {
64
+ bodyChunks.push(data);
65
+ const chunkLength = bodyChunks[bodyChunks.length - 1].length;
66
+ size += chunkLength;
67
+ if (size > httpOptions.maxBodySize && !replied) {
68
+ replied = true;
69
+ const error = new RpcError({
70
+ publicMessage: "Payload Too Large",
71
+ type: "request-payload-too-large"
72
+ });
73
+ fatalFail(httpResponse, respHeaders, error);
74
+ }
75
+ });
76
+ httpReq.on("error", (e) => {
77
+ if (replied) return;
78
+ replied = true;
79
+ const error = new RpcError({
80
+ publicMessage: "Connection Error",
81
+ type: "request-connection-error",
82
+ originalError: e
83
+ });
84
+ fatalFail(httpResponse, respHeaders, error);
85
+ });
86
+ httpReq.on("end", async () => {
87
+ if (replied) return;
88
+ const buffer = Buffer.concat(bodyChunks);
89
+ const contentType = httpReq.headers["content-type"] || "";
90
+ const isBinary = contentType.startsWith("application/octet-stream");
91
+ let reqRawBody = isBinary ? buffer : buffer.toString();
92
+ let reqBodyType = isBinary ? SerializerModes.binary : SerializerModes.stringifyJson;
93
+ const queryBody = decodeQueryBody(urlQuery, reqRawBody || void 0);
94
+ if (queryBody) {
95
+ reqRawBody = queryBody.rawBody;
96
+ reqBodyType = queryBody.bodyType;
97
+ }
98
+ try {
99
+ const mionResponse = await dispatchRoute(
100
+ path,
101
+ reqRawBody,
102
+ reqHeaders,
103
+ respHeaders,
104
+ httpReq,
105
+ httpResponse,
106
+ reqBodyType,
107
+ urlQuery
108
+ );
109
+ if (replied || httpResponse.writableEnded) return;
110
+ replied = true;
111
+ reply(httpResponse, mionResponse);
112
+ } catch (e) {
113
+ if (replied) return;
114
+ replied = true;
115
+ const error = new RpcError({
116
+ publicMessage: "Unknown Error",
117
+ type: "unknown-error",
118
+ originalError: e
119
+ });
120
+ fatalFail(httpResponse, respHeaders, error);
121
+ }
122
+ });
123
+ httpResponse.on("error", (e) => {
124
+ if (replied) return;
125
+ replied = true;
126
+ const error = new RpcError({
127
+ publicMessage: "Connection Error",
128
+ type: "response-connection-error",
129
+ originalError: e
130
+ });
131
+ fatalFail(httpResponse, respHeaders, error);
132
+ });
133
+ }
134
+ function fatalFail(httpResponse, respHeaders, error) {
135
+ if (httpResponse.writableEnded) return;
136
+ const routeResponse = getRouterFatalErrorResponse(error, respHeaders);
137
+ reply(httpResponse, routeResponse);
138
+ }
139
+ function reply(httpResp, mionResp) {
140
+ httpResp.statusCode = mionResp.statusCode;
141
+ const bodyType = mionResp.serializer;
142
+ switch (bodyType) {
143
+ case SerializerModes.stringifyJson: {
144
+ const buffer = Buffer.from(mionResp.rawBody, "utf8");
145
+ httpResp.setHeader("content-length", buffer.byteLength);
146
+ httpResp.end(buffer);
147
+ break;
148
+ }
149
+ case SerializerModes.json: {
150
+ const jsonString = JSON.stringify(mionResp.body);
151
+ const buffer = Buffer.from(jsonString, "utf8");
152
+ httpResp.setHeader("content-length", buffer.byteLength);
153
+ httpResp.end(buffer);
154
+ break;
155
+ }
156
+ case SerializerModes.binary: {
157
+ const serializer = mionResp.binSerializer;
158
+ httpResp.setHeader("content-length", serializer.getLength());
159
+ httpResp.end(serializer.getBufferView());
160
+ const onFinish = () => serializer.markAsEnded();
161
+ httpResp.on("finish", onFinish);
162
+ httpResp.on("close", onFinish);
163
+ break;
164
+ }
165
+ default: {
166
+ const error = new RpcError({
167
+ publicMessage: "unknown-mion-response-format",
168
+ type: "unknown-error",
169
+ errorData: { bodyType }
170
+ });
171
+ fatalFail(httpResp, mionResp.headers, error);
172
+ }
173
+ }
174
+ }
175
+ export {
176
+ httpRequestHandler,
177
+ resetNodeHttpOpts,
178
+ setNodeHttpOpts,
179
+ startNodeServer
180
+ };
181
+ //# sourceMappingURL=mionHttp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mionHttp.js","sources":["../../../src/mionHttp.ts"],"sourcesContent":["/* ########\n * 2022 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} from '@mionjs/router';\nimport {createServer as createHttp} from 'http';\nimport {createServer as createHttps} from 'https';\nimport {DEFAULT_HTTP_OPTIONS} from './constants.ts';\nimport type {NodeHttpOptions} from './types.ts';\nimport type {IncomingMessage, Server as HttpServer, ServerResponse} from 'http';\nimport type {Server as HttpsServer} from 'https';\nimport type {MionHeaders, MionResponse} from '@mionjs/router';\nimport {getENV, isMionCompileMode, SerializerModes} from '@mionjs/core';\nimport type {SerializerCode} from '@mionjs/core';\nimport {RpcError} from '@mionjs/core';\nimport {headersFromIncomingMessage, headersFromServerResponse} from './headers.ts';\n\n// ############# PRIVATE STATE #############\n\nlet httpOptions: Readonly<NodeHttpOptions> = {...DEFAULT_HTTP_OPTIONS};\n\n// ############# PUBLIC METHODS #############\n\nexport function resetNodeHttpOpts() {\n httpOptions = {...DEFAULT_HTTP_OPTIONS};\n resetRouter();\n}\n\nexport function setNodeHttpOpts(options?: Partial<NodeHttpOptions>) {\n httpOptions = {\n ...httpOptions,\n ...options,\n };\n\n return httpOptions;\n}\n\nexport async function startNodeServer(options?: Partial<NodeHttpOptions>): Promise<HttpServer | HttpsServer> {\n const isTest = getENV('NODE_ENV') === 'test';\n const isCompiling = isMionCompileMode();\n\n if (options) setNodeHttpOpts(options);\n const port = httpOptions.port !== 80 ? `:${httpOptions.port}` : '';\n const url = `${httpOptions.protocol}://localhost${port}`;\n if (!isTest && !isCompiling)\n console.log(`mion node server running on ${url}`, {\n port: httpOptions.port,\n httpOptions,\n });\n\n return new Promise<HttpServer | HttpsServer>((resolve, reject) => {\n const server =\n httpOptions.protocol === 'https'\n ? createHttps(httpOptions.options, httpRequestHandler)\n : createHttp(httpOptions.options, httpRequestHandler);\n\n if (isCompiling) {\n console.log('Compiling routes metadata and skipping mion server initialization...');\n return resolve(server);\n }\n\n server.on('error', (e) => {\n reject(e);\n });\n\n server.listen(httpOptions.port, () => {\n resolve(server);\n });\n\n const shutdownHandler = function () {\n if (!isTest) console.log(`Shutting down mion server on ${url}`);\n server.close(() => {\n process.exit(0);\n });\n };\n\n process.on('SIGINT', shutdownHandler);\n process.on('SIGTERM', shutdownHandler);\n });\n}\n\n// ############# PRIVATE METHODS #############\n\n// exported as can be used in some server to proxy node requests\nexport function httpRequestHandler(httpReq: IncomingMessage, httpResponse: ServerResponse): void {\n let replied = false;\n const nodeUrl = httpReq.url || '/';\n const queryIndex = nodeUrl.indexOf('?');\n const path = queryIndex === -1 ? nodeUrl : nodeUrl.substring(0, queryIndex);\n const urlQuery = queryIndex === -1 ? undefined : nodeUrl.substring(queryIndex + 1);\n let size = 0;\n const bodyChunks: any[] = [];\n\n httpResponse.setHeader('server', '@mionjs');\n const reqHeaders = headersFromIncomingMessage(httpReq);\n const respHeaders = headersFromServerResponse(httpResponse, httpOptions.defaultResponseHeaders);\n\n httpReq.on('data', (data) => {\n bodyChunks.push(data);\n const chunkLength = bodyChunks[bodyChunks.length - 1].length;\n size += chunkLength;\n if (size > httpOptions.maxBodySize && !replied) {\n replied = true;\n const error = new RpcError({\n publicMessage: 'Payload Too Large',\n type: 'request-payload-too-large',\n });\n fatalFail(httpResponse, respHeaders, error);\n }\n });\n\n httpReq.on('error', (e) => {\n if (replied) return;\n replied = true;\n const error = new RpcError({\n publicMessage: 'Connection Error',\n type: 'request-connection-error',\n originalError: e,\n });\n fatalFail(httpResponse, respHeaders, error);\n });\n\n httpReq.on('end', async () => {\n if (replied) return;\n const buffer = Buffer.concat(bodyChunks);\n const contentType = httpReq.headers['content-type'] || '';\n const isBinary = contentType.startsWith('application/octet-stream');\n let reqRawBody: any = isBinary ? buffer : buffer.toString();\n let reqBodyType: SerializerCode = isBinary ? SerializerModes.binary : SerializerModes.stringifyJson;\n const queryBody = decodeQueryBody(urlQuery, reqRawBody || undefined);\n if (queryBody) {\n reqRawBody = queryBody.rawBody;\n reqBodyType = queryBody.bodyType;\n }\n\n try {\n const mionResponse = await dispatchRoute(\n path,\n reqRawBody,\n reqHeaders,\n respHeaders,\n httpReq,\n httpResponse,\n reqBodyType,\n urlQuery\n );\n if (replied || httpResponse.writableEnded) return;\n replied = true;\n reply(httpResponse, mionResponse);\n } catch (e) {\n if (replied) return;\n replied = true;\n const error = new RpcError({\n publicMessage: 'Unknown Error',\n type: 'unknown-error',\n originalError: e as Error,\n });\n fatalFail(httpResponse, respHeaders, error);\n }\n });\n\n httpResponse.on('error', (e) => {\n if (replied) return;\n replied = true;\n const error = new RpcError({\n publicMessage: 'Connection Error',\n type: 'response-connection-error',\n originalError: e,\n });\n fatalFail(httpResponse, respHeaders, error);\n });\n}\n\n// only called when there is an http error or weird unhandled route errors\nfunction fatalFail(httpResponse: ServerResponse, respHeaders: MionHeaders, error: RpcError<string>) {\n if (httpResponse.writableEnded) return;\n const routeResponse = getRouterFatalErrorResponse(error, respHeaders);\n reply(httpResponse, routeResponse);\n}\n\nfunction reply(httpResp: ServerResponse, mionResp: MionResponse) {\n httpResp.statusCode = mionResp.statusCode;\n const bodyType = mionResp.serializer;\n switch (bodyType) {\n case SerializerModes.stringifyJson: {\n const buffer = Buffer.from(mionResp.rawBody as string, 'utf8');\n httpResp.setHeader('content-length', buffer.byteLength);\n // content-type already set by serializer\n httpResp.end(buffer);\n break;\n }\n case SerializerModes.json: {\n // Platform adapter stringifies the prepared body object\n const jsonString = JSON.stringify(mionResp.body);\n const buffer = Buffer.from(jsonString, 'utf8');\n httpResp.setHeader('content-length', buffer.byteLength);\n httpResp.end(buffer);\n break;\n }\n case SerializerModes.binary: {\n const serializer = mionResp.binSerializer!;\n httpResp.setHeader('content-length', serializer.getLength());\n // content-type already set by serializer\n httpResp.end(serializer.getBufferView());\n // Release buffer when response is finished\n const onFinish = () => serializer.markAsEnded();\n httpResp.on('finish', onFinish);\n httpResp.on('close', onFinish); // Fallback for aborted connection\n break;\n }\n default: {\n const error = new RpcError({\n publicMessage: 'unknown-mion-response-format',\n type: 'unknown-error',\n errorData: {bodyType},\n });\n fatalFail(httpResp, mionResp.headers, error);\n }\n }\n}\n"],"names":["createHttps","createHttp"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { ServerOptions } from 'https';
2
+ export interface NodeHttpOptions {
3
+ protocol: 'http' | 'https';
4
+ port: number;
5
+ options: ServerOptions;
6
+ defaultResponseHeaders: Record<string, string>;
7
+ maxBodySize: number;
8
+ }
9
+ export declare type __ΩNodeHttpOptions = 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/README.md ADDED
@@ -0,0 +1,27 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/MionKit/mion/master/assets/public/bannerx90-dark.png">
4
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/MionKit/mion/master/assets/public/bannerx90.png">
5
+ <img alt='mion, a mikro kit for Typescript Serverless APIs' src='https://raw.githubusercontent.com/MionKit/mion/master/assets/public/bannerx90.png'>
6
+ </picture>
7
+ </p>
8
+ <p align="center">
9
+ <strong>Full Stack APIs at the speed of light 🚀
10
+ </strong>
11
+ </p>
12
+ <p align=center>
13
+ <img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square&maxAge=99999999" alt="npm" style="max-width:100%;">
14
+ <img src="https://img.shields.io/badge/license-MIT-97ca00.svg?style=flat-square&maxAge=99999999" alt="npm" style="max-width:100%;">
15
+ </p>
16
+
17
+ # `@mionjs/platform-node`
18
+
19
+ This package contains a Node.js server to run mion APIs!
20
+
21
+ ## Check Out The [Website And Documentation](http://mion.io) 📚
22
+
23
+ [![mion-website-banner](https://raw.githubusercontent.com/MionKit/mion/master/assets/public/mion-website-banner.png)](http://mion.io)
24
+
25
+ ---
26
+
27
+ _[MIT](../../LICENSE) LICENSE_
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@mionjs/platform-node",
3
+ "version": "0.8.0-alpha.0",
4
+ "type": "module",
5
+ "description": "mion HTTP Server for quick Api development.",
6
+ "keywords": [
7
+ "typescript",
8
+ "API",
9
+ "RPC",
10
+ "json",
11
+ "schema",
12
+ "generate",
13
+ "server",
14
+ "serverless",
15
+ "framework",
16
+ "node"
17
+ ],
18
+ "author": "ma jerez",
19
+ "homepage": "https://mion.io/",
20
+ "license": "MIT",
21
+ "exports": {
22
+ ".": {
23
+ "source": "./index.ts",
24
+ "types": "./.dist/esm/index.d.ts",
25
+ "require": "./.dist/cjs/index.cjs",
26
+ "default": "./.dist/esm/index.js"
27
+ }
28
+ },
29
+ "directories": {
30
+ "lib": ".dist"
31
+ },
32
+ "files": [
33
+ ".dist"
34
+ ],
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/MionKit/mion.git"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "scripts": {
43
+ "test": "vitest run",
44
+ "dev": "vite build --watch",
45
+ "dev:test": "vitest watch",
46
+ "lint": "npx eslint src",
47
+ "format": "prettier --write src/**/*.ts",
48
+ "build": "vite build",
49
+ "clean": "rimraf .dist & rimraf .coverage",
50
+ "fresh-start": "npm run clean && rimraf node_modules"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/MionKit/mion/issues"
54
+ },
55
+ "dependencies": {
56
+ "@mionjs/core": "^0.8.0-alpha.0",
57
+ "@mionjs/router": "^0.8.0-alpha.0"
58
+ },
59
+ "gitHead": "5d2ec524ba39d040338ce8946d8edf78aa7291a3"
60
+ }