162 lines
5.3 KiB
JavaScript
162 lines
5.3 KiB
JavaScript
import { createServer } from 'http';
|
|
|
|
/*! *****************************************************************************
|
|
Copyright (c) Microsoft Corporation.
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|
***************************************************************************** */
|
|
|
|
function __classPrivateFieldGet(receiver, privateMap) {
|
|
if (!privateMap.has(receiver)) {
|
|
throw new TypeError("attempted to get private field on non-instance");
|
|
}
|
|
return privateMap.get(receiver);
|
|
}
|
|
|
|
function __classPrivateFieldSet(receiver, privateMap, value) {
|
|
if (!privateMap.has(receiver)) {
|
|
throw new TypeError("attempted to set private field on non-instance");
|
|
}
|
|
privateMap.set(receiver, value);
|
|
return value;
|
|
}
|
|
|
|
const pushMiddlewares = (arr, element) => {
|
|
if (Array.isArray(element))
|
|
element.forEach((el) => pushMiddlewares(arr, el));
|
|
else {
|
|
if (typeof element != "function")
|
|
throw new Error("Route callback must be a function");
|
|
arr.push(element);
|
|
}
|
|
};
|
|
const logger = (req, res, next) => {
|
|
console.log(`Accessed ${req.url} from ${req.headers["user-agent"]}`); // eslint-disable-line
|
|
next();
|
|
};
|
|
|
|
const useJson = (res) => (obj) => {
|
|
res.statusCode = 200;
|
|
res.setHeader("Content-Type", "application/json");
|
|
res.write(JSON.stringify(obj));
|
|
res.end();
|
|
};
|
|
const useSend = (res) => (content) => {
|
|
if (typeof content === "object" ||
|
|
typeof content === "undefined" ||
|
|
typeof content === "function")
|
|
throw new Error("Content must be displayable");
|
|
res.statusCode = 200;
|
|
res.setHeader("Content-Type", "text/plain");
|
|
switch (typeof content) {
|
|
case "boolean":
|
|
res.write(content ? "true" : "false");
|
|
break;
|
|
case "number":
|
|
case "bigint":
|
|
res.write(content.toString());
|
|
break;
|
|
default:
|
|
res.write(content);
|
|
}
|
|
res.end();
|
|
};
|
|
|
|
const processURL = (url) => {
|
|
const qPos = url.indexOf("?");
|
|
const path = url.substring(0, qPos > 0 ? qPos : undefined).toLowerCase();
|
|
const query = {};
|
|
if (qPos > 0)
|
|
url
|
|
.substring(qPos + 1)
|
|
.split("&")
|
|
.map((queryParam) => {
|
|
const tokens = queryParam.split("=");
|
|
query[decodeURI(tokens[0])] = decodeURI(tokens[1]);
|
|
});
|
|
return {
|
|
path,
|
|
query,
|
|
};
|
|
};
|
|
|
|
var _stack, _router;
|
|
class eServer {
|
|
constructor() {
|
|
_stack.set(this, void 0);
|
|
_router.set(this, void 0);
|
|
__classPrivateFieldSet(this, _stack, []);
|
|
__classPrivateFieldSet(this, _router, {});
|
|
}
|
|
handle(req, res, callback) {
|
|
let idx = 0;
|
|
// @ts-ignore
|
|
if (req.url)
|
|
req = Object.assign(Object.assign({}, req), processURL(req.url));
|
|
// @ts-ignore
|
|
res = Object.assign(Object.assign({}, res), { send: useSend(res), json: useJson(res) });
|
|
const stack = [
|
|
...__classPrivateFieldGet(this, _stack),
|
|
...(req.path && __classPrivateFieldGet(this, _router)[req.path] ? __classPrivateFieldGet(this, _router)[req.path] : []),
|
|
];
|
|
const next = (err) => {
|
|
if (err)
|
|
return setImmediate(() => callback(err));
|
|
if (idx === stack.length) {
|
|
return setImmediate(() => callback());
|
|
}
|
|
const layer = stack[idx++];
|
|
setImmediate(() => {
|
|
try {
|
|
layer(req, res, next);
|
|
}
|
|
catch (err) {
|
|
next(err);
|
|
}
|
|
});
|
|
};
|
|
next();
|
|
}
|
|
use(middleware) {
|
|
if (typeof middleware !== "function")
|
|
throw new Error("Middleware must be a function");
|
|
pushMiddlewares(__classPrivateFieldGet(this, _stack), middleware);
|
|
}
|
|
route(path, ...callbacks) {
|
|
if (typeof callbacks[0] !== "function")
|
|
throw new Error("Route callback must be a function");
|
|
path = path.toLowerCase();
|
|
if (!__classPrivateFieldGet(this, _router)[path])
|
|
__classPrivateFieldGet(this, _router)[path] = [];
|
|
pushMiddlewares(__classPrivateFieldGet(this, _router)[path], callbacks);
|
|
}
|
|
listen(port, callback) {
|
|
const handler = (req, res) => this.handle(req, res, (err) => {
|
|
if (err) {
|
|
console.log(err); // eslint-disable-line
|
|
res.statusCode = 500;
|
|
res.end();
|
|
}
|
|
else {
|
|
res.statusCode = 404;
|
|
res.write("Not found: 404");
|
|
res.end();
|
|
}
|
|
});
|
|
return createServer(handler).listen(port, callback);
|
|
}
|
|
}
|
|
_stack = new WeakMap(), _router = new WeakMap();
|
|
|
|
export default eServer;
|
|
export { logger };
|