backendium 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/handler.d.ts +16 -0
- package/dist/handler.js +104 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +87 -0
- package/dist/logger.d.ts +42 -0
- package/dist/logger.js +221 -0
- package/dist/request.d.ts +34 -0
- package/dist/request.js +78 -0
- package/dist/response.d.ts +11 -0
- package/dist/response.js +17 -0
- package/dist/router.d.ts +60 -0
- package/dist/router.js +138 -0
- package/dist/ws.d.ts +101 -0
- package/dist/ws.js +338 -0
- package/package.json +26 -0
- package/readme.md +11 -0
- package/src/handler.ts +85 -0
- package/src/index.ts +109 -0
- package/src/logger.ts +273 -0
- package/src/request.ts +91 -0
- package/src/response.ts +22 -0
- package/src/router.ts +228 -0
- package/src/ws.ts +371 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import BackendiumResponse from "./response.js";
|
|
2
|
+
import Backendium from "./index.js";
|
|
3
|
+
import { NextFunction, Request, RequestHandler } from "express";
|
|
4
|
+
import { BackendiumRequestOptionsType, BackendiumRequestType } from "./request.js";
|
|
5
|
+
import { BackendiumRouter } from "./router";
|
|
6
|
+
import { ValidationError } from "checkeasy";
|
|
7
|
+
export type BackendiumHandlerReturnType = void | undefined | {
|
|
8
|
+
code?: number;
|
|
9
|
+
next?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type BackendiumHandlerType<BodyType, ParamsType, QueryType, AuthType, HeadersType, GlobalAuthType> = (request: BackendiumRequestType<BodyType, ParamsType, QueryType, AuthType, HeadersType, GlobalAuthType>, response: BackendiumResponse, app: Backendium, next: NextFunction) => BackendiumHandlerReturnType | Promise<BackendiumHandlerReturnType>;
|
|
12
|
+
export type RawHandlerType<DefaultAuthType> = (router: BackendiumRouter<DefaultAuthType>) => (app: Backendium) => RequestHandler;
|
|
13
|
+
export declare function defaultAuthFailedHandler(request: Request, response: BackendiumResponse, app: Backendium): void;
|
|
14
|
+
export declare function defaultErrorHandler(request: Request, response: BackendiumResponse, data: any, app: Backendium, error: any, message: string): void;
|
|
15
|
+
export declare function defaultValidationErrorHandler(request: Request, response: BackendiumResponse, app: Backendium, data: Buffer, error: ValidationError, message: string): void;
|
|
16
|
+
export default function backendiumHandler<BodyType, ParamsType, QueryType, AuthType, HeadersType, GlobalAuthType>(handler: BackendiumHandlerType<BodyType, ParamsType, QueryType, AuthType, HeadersType, GlobalAuthType>, { auth, authChecker, authFailed, errorHandler, errorMessage, validationErrorHandler, validationErrorMessage, ...options }: BackendiumRequestOptionsType<BodyType, ParamsType, QueryType, AuthType, HeadersType>): RawHandlerType<GlobalAuthType>;
|
package/dist/handler.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
11
|
+
var t = {};
|
|
12
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
13
|
+
t[p] = s[p];
|
|
14
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
15
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
16
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
17
|
+
t[p[i]] = s[p[i]];
|
|
18
|
+
}
|
|
19
|
+
return t;
|
|
20
|
+
};
|
|
21
|
+
import BackendiumResponse from "./response.js";
|
|
22
|
+
import parseRequest from "./request.js";
|
|
23
|
+
export function defaultAuthFailedHandler(request, response, app) {
|
|
24
|
+
response.status(209);
|
|
25
|
+
response.end();
|
|
26
|
+
}
|
|
27
|
+
export function defaultErrorHandler(request, response, data, app, error, message) {
|
|
28
|
+
response.status(500);
|
|
29
|
+
response.end(message !== null && message !== void 0 ? message : "Internal Server Error");
|
|
30
|
+
app.logger.requestError(request.url, data, error);
|
|
31
|
+
}
|
|
32
|
+
export function defaultValidationErrorHandler(request, response, app, data, error, message) {
|
|
33
|
+
response.status(400);
|
|
34
|
+
response.end(message !== null && message !== void 0 ? message : "Validation failed");
|
|
35
|
+
}
|
|
36
|
+
export default function backendiumHandler(handler, _a) {
|
|
37
|
+
var { auth, authChecker, authFailed, errorHandler, errorMessage, validationErrorHandler, validationErrorMessage } = _a, options = __rest(_a, ["auth", "authChecker", "authFailed", "errorHandler", "errorMessage", "validationErrorHandler", "validationErrorMessage"]);
|
|
38
|
+
return (router) => (app) => ((request, response, next) => __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
40
|
+
let body;
|
|
41
|
+
try {
|
|
42
|
+
let req = yield parseRequest(request, app, Object.assign(Object.assign({}, options), { auth, authChecker, authFailed, errorHandler, validationErrorHandler, errorMessage, validationErrorMessage }));
|
|
43
|
+
let res = new BackendiumResponse(response, app);
|
|
44
|
+
if (Array.isArray(req)) {
|
|
45
|
+
let [data, error] = req;
|
|
46
|
+
((_a = validationErrorHandler !== null && validationErrorHandler !== void 0 ? validationErrorHandler : app.config.validationErrorHandler) !== null && _a !== void 0 ? _a : defaultValidationErrorHandler)(request, res, app, data, error, validationErrorMessage !== null && validationErrorMessage !== void 0 ? validationErrorMessage : app.config.validationErrorMessage);
|
|
47
|
+
if ((_b = app.config.logging) === null || _b === void 0 ? void 0 : _b.fullRequest)
|
|
48
|
+
app.logger.requestFull(request.url, res.lastStatus, data, res.lastResponse);
|
|
49
|
+
else
|
|
50
|
+
app.logger.request(request.url, res.lastStatus);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
body = req.body;
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
let authData = undefined;
|
|
56
|
+
if (authChecker) {
|
|
57
|
+
let ret = authChecker(request, res, app);
|
|
58
|
+
if (ret instanceof Promise)
|
|
59
|
+
ret = yield ret;
|
|
60
|
+
if (ret === null) {
|
|
61
|
+
((_d = (_c = authFailed !== null && authFailed !== void 0 ? authFailed : router.authFailed) !== null && _c !== void 0 ? _c : app.authFailed) !== null && _d !== void 0 ? _d : defaultAuthFailedHandler)(request, res, app);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
authData = ret;
|
|
65
|
+
}
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
let globalAuthData = undefined;
|
|
68
|
+
if (!authChecker && auth && router.authChecker) {
|
|
69
|
+
let ret = router.authChecker(request, res, app);
|
|
70
|
+
if (ret instanceof Promise)
|
|
71
|
+
ret = yield ret;
|
|
72
|
+
if (ret === null) {
|
|
73
|
+
((_f = (_e = authFailed !== null && authFailed !== void 0 ? authFailed : router.authFailed) !== null && _e !== void 0 ? _e : app.authFailed) !== null && _f !== void 0 ? _f : defaultAuthFailedHandler)(request, res, app);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
globalAuthData = ret;
|
|
77
|
+
}
|
|
78
|
+
let ret = handler(Object.assign(Object.assign({}, req), { auth: authData, globalAuth: globalAuthData }), res, app, next);
|
|
79
|
+
if (ret instanceof Promise)
|
|
80
|
+
ret = yield ret;
|
|
81
|
+
if (!ret)
|
|
82
|
+
return;
|
|
83
|
+
let { code = 200, next: isNext = false } = ret;
|
|
84
|
+
response.status(code);
|
|
85
|
+
if (isNext) {
|
|
86
|
+
next();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
response.end();
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if ((_g = app.config.logging) === null || _g === void 0 ? void 0 : _g.fullRequest)
|
|
96
|
+
app.logger.requestFull(request.url, res.lastStatus, req.body, res.lastResponse);
|
|
97
|
+
else
|
|
98
|
+
app.logger.request(request.url, res.lastStatus);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
((_h = errorHandler !== null && errorHandler !== void 0 ? errorHandler : app.config.errorHandler) !== null && _h !== void 0 ? _h : defaultErrorHandler)(request, new BackendiumResponse(response, app), body, app, error, errorMessage !== null && errorMessage !== void 0 ? errorMessage : app.config.errorMessage);
|
|
102
|
+
}
|
|
103
|
+
}));
|
|
104
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Request, RequestHandler } from "express";
|
|
2
|
+
import { Server } from "node:http";
|
|
3
|
+
import { BackendiumRouter, MethodType } from "./router.js";
|
|
4
|
+
import { EventEmitter, EventKey } from "event-emitter-typescript";
|
|
5
|
+
import { WebSocketExpress, WSRequestHandler } from "websocket-express";
|
|
6
|
+
import { BackendiumWebSocket } from "./ws.js";
|
|
7
|
+
import Logger from "./logger";
|
|
8
|
+
import BackendiumResponse from "./response";
|
|
9
|
+
import { ValidationError } from "checkeasy";
|
|
10
|
+
export type BackendiumConfigType = {
|
|
11
|
+
port: number;
|
|
12
|
+
host: string;
|
|
13
|
+
name: string;
|
|
14
|
+
version: string | number;
|
|
15
|
+
logging: {
|
|
16
|
+
path?: string;
|
|
17
|
+
fullRequest?: boolean;
|
|
18
|
+
fullWs?: boolean;
|
|
19
|
+
replaceConsoleLog?: boolean;
|
|
20
|
+
};
|
|
21
|
+
autoLogFull: boolean;
|
|
22
|
+
autoLog: boolean;
|
|
23
|
+
autoLogWsFull: boolean;
|
|
24
|
+
autoLogWs: boolean;
|
|
25
|
+
errorMessage: string;
|
|
26
|
+
errorHandler(request: Request, response: BackendiumResponse, data: any, app: Backendium, error: any, message?: string): void;
|
|
27
|
+
validationErrorMessage: string;
|
|
28
|
+
validationErrorHandler(request: Request, response: BackendiumResponse, app: Backendium, data: Buffer, error: ValidationError, message?: string): void;
|
|
29
|
+
wsErrorMessage: string;
|
|
30
|
+
wsErrorHandler(data: Buffer, connection: BackendiumWebSocket<any>, app: Backendium, error: any): void;
|
|
31
|
+
};
|
|
32
|
+
export type BackendiumEvents = {
|
|
33
|
+
starting: [];
|
|
34
|
+
start: [Server];
|
|
35
|
+
};
|
|
36
|
+
export default class Backendium<GlobalAuthType = any> extends BackendiumRouter<GlobalAuthType> {
|
|
37
|
+
express: WebSocketExpress;
|
|
38
|
+
protected eventEmitter: EventEmitter<BackendiumEvents>;
|
|
39
|
+
logger: Logger;
|
|
40
|
+
protected config_: Partial<BackendiumConfigType>;
|
|
41
|
+
constructor(config?: Partial<BackendiumConfigType>);
|
|
42
|
+
get config(): Partial<BackendiumConfigType>;
|
|
43
|
+
set config(config: Partial<BackendiumConfigType>);
|
|
44
|
+
protected addAnyRouteHandler(method: MethodType, handlers: Array<RequestHandler>): void;
|
|
45
|
+
protected addRoutedHandler(method: MethodType, route: string, handlers: Array<RequestHandler>): void;
|
|
46
|
+
protected addWSHandler(route: string, handlers: Array<WSRequestHandler>): void;
|
|
47
|
+
on<E extends EventKey<BackendiumEvents>>(event: E, subscriber: (...args: BackendiumEvents[E]) => void): () => void;
|
|
48
|
+
once<E extends EventKey<BackendiumEvents>>(event: E, subscriber: (...args: BackendiumEvents[E]) => void): () => void;
|
|
49
|
+
off<E extends EventKey<BackendiumEvents>>(event: E, subscriber: (...args: BackendiumEvents[E]) => void): void;
|
|
50
|
+
start(callback?: (server: Server) => void): Server;
|
|
51
|
+
startAsync(): Promise<Server>;
|
|
52
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { BackendiumRouter } from "./router.js";
|
|
11
|
+
import { EventEmitter } from "event-emitter-typescript";
|
|
12
|
+
import { WebSocketExpress } from "websocket-express";
|
|
13
|
+
import Logger from "./logger";
|
|
14
|
+
export default class Backendium extends BackendiumRouter {
|
|
15
|
+
constructor(config = {}) {
|
|
16
|
+
super();
|
|
17
|
+
this.express = new WebSocketExpress;
|
|
18
|
+
this.eventEmitter = new EventEmitter;
|
|
19
|
+
this.logger = new Logger(console.log.bind(console));
|
|
20
|
+
this.config_ = {};
|
|
21
|
+
this.config = config;
|
|
22
|
+
}
|
|
23
|
+
get config() { return this.config_; }
|
|
24
|
+
set config(config) {
|
|
25
|
+
var _a, _b, _c, _d;
|
|
26
|
+
this.config_ = Object.assign(Object.assign(Object.assign({}, this.config_), config), { logging: Object.assign(Object.assign({}, this.config_.logging), config.logging) });
|
|
27
|
+
if ((_a = this.config_.logging) === null || _a === void 0 ? void 0 : _a.path)
|
|
28
|
+
this.logger.path = (_b = this.config_.logging) === null || _b === void 0 ? void 0 : _b.path;
|
|
29
|
+
if ((_d = (_c = this.config_.logging) === null || _c === void 0 ? void 0 : _c.replaceConsoleLog) !== null && _d !== void 0 ? _d : true) {
|
|
30
|
+
console.log = this.logger.message.bind(this.logger);
|
|
31
|
+
console.error = this.logger.error.bind(this.logger);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
addAnyRouteHandler(method, handlers) {
|
|
35
|
+
this.express[method]("*", ...handlers);
|
|
36
|
+
}
|
|
37
|
+
addRoutedHandler(method, route, handlers) {
|
|
38
|
+
this.express[method](route, ...handlers);
|
|
39
|
+
}
|
|
40
|
+
addWSHandler(route, handlers) {
|
|
41
|
+
this.express.ws(route, ...handlers);
|
|
42
|
+
}
|
|
43
|
+
on(event, subscriber) {
|
|
44
|
+
return this.eventEmitter.on(event, (args) => subscriber(...args));
|
|
45
|
+
}
|
|
46
|
+
;
|
|
47
|
+
once(event, subscriber) {
|
|
48
|
+
return this.eventEmitter.once(event, (args) => subscriber(...args));
|
|
49
|
+
}
|
|
50
|
+
;
|
|
51
|
+
off(event, subscriber) {
|
|
52
|
+
this.eventEmitter.off(event, (args) => subscriber(...args));
|
|
53
|
+
}
|
|
54
|
+
;
|
|
55
|
+
start(callback) {
|
|
56
|
+
var _a, _b;
|
|
57
|
+
this.handlers.forEach(([method, route, handlers]) => {
|
|
58
|
+
if (method == "ws")
|
|
59
|
+
this.addWSHandler(route, handlers.map(handler => handler(this)));
|
|
60
|
+
else if (route)
|
|
61
|
+
this.addRoutedHandler(method, route, handlers.map(handler => handler(this)));
|
|
62
|
+
else
|
|
63
|
+
this.addAnyRouteHandler(method, handlers.map(handler => handler(this)));
|
|
64
|
+
});
|
|
65
|
+
this.eventEmitter.emit("starting", []);
|
|
66
|
+
// const server = this.express.createServer();
|
|
67
|
+
// server.listen(this.config.port ?? 8080, this.config.host ?? "localhost", () => {
|
|
68
|
+
// if (callback) callback(server);
|
|
69
|
+
// this.eventEmitter.emit("start", [server]);
|
|
70
|
+
// });
|
|
71
|
+
const server = this.express.listen((_a = this.config_.port) !== null && _a !== void 0 ? _a : 8080, (_b = this.config_.host) !== null && _b !== void 0 ? _b : "localhost", () => {
|
|
72
|
+
var _a, _b, _c, _d;
|
|
73
|
+
this.logger.initMessage((_a = this.config_.name) !== null && _a !== void 0 ? _a : "app", (_b = this.config_.version) !== null && _b !== void 0 ? _b : "0.0.0", (_c = this.config.port) !== null && _c !== void 0 ? _c : 8080, (_d = this.config_.host) !== null && _d !== void 0 ? _d : "localhost");
|
|
74
|
+
if (callback)
|
|
75
|
+
callback(server);
|
|
76
|
+
this.eventEmitter.emit("start", [server]);
|
|
77
|
+
});
|
|
78
|
+
return server;
|
|
79
|
+
}
|
|
80
|
+
startAsync() {
|
|
81
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
return new Promise(resolve => {
|
|
83
|
+
this.start(resolve);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export declare function getDate(): string;
|
|
2
|
+
export default class Logger {
|
|
3
|
+
log: (...data: Array<string>) => void;
|
|
4
|
+
protected path_?: string | undefined;
|
|
5
|
+
protected logData: string;
|
|
6
|
+
constructor(log: (...data: Array<string>) => void, path_?: string | undefined);
|
|
7
|
+
get path(): string | undefined;
|
|
8
|
+
set path(path: string);
|
|
9
|
+
clear(): void;
|
|
10
|
+
logSeparately(consoleData: Array<any>, fileData: Array<string>): void;
|
|
11
|
+
getPrefix(tag: string): string;
|
|
12
|
+
Log(tag: string, func?: import("chalk").ChalkInstance, ...data: Array<any>): void;
|
|
13
|
+
message(...data: Array<any>): void;
|
|
14
|
+
info(...data: Array<any>): void;
|
|
15
|
+
success(...data: Array<any>): void;
|
|
16
|
+
warning(...data: Array<any>): void;
|
|
17
|
+
error(...data: Array<any>): void;
|
|
18
|
+
fatal(...data: Array<any>): void;
|
|
19
|
+
initMessage(name: string, version: string | number, port: number, host: string): void;
|
|
20
|
+
protected formatData(data: any): any;
|
|
21
|
+
protected formatDataColors(data: any, color?: import("chalk").ChalkInstance, defaultColor?: import("chalk").ChalkInstance): any;
|
|
22
|
+
requestFull(url: string, code: number, request: any, response: any): void;
|
|
23
|
+
request(url: string, code: number): void;
|
|
24
|
+
requestError(url: string, request: any, stackTrace: any): void;
|
|
25
|
+
wsConnected(url: string): void;
|
|
26
|
+
wsRejected(url: string): void;
|
|
27
|
+
wsInitFull(url: string, data: any): void;
|
|
28
|
+
wsInitFailedFull(url: string, data: any): void;
|
|
29
|
+
wsInit(url: string): void;
|
|
30
|
+
wsInitFailed(url: string): void;
|
|
31
|
+
wsIncomingEventFull(url: string, event: string, data: any): void;
|
|
32
|
+
wsIncomingEvent(url: string, event: string): void;
|
|
33
|
+
wsOutgoingEventFull(url: string, event: string, data: any): void;
|
|
34
|
+
wsOutgoingEvent(url: string, event: string): void;
|
|
35
|
+
wsInputFull(url: string, data: any): void;
|
|
36
|
+
wsInput(url: string): void;
|
|
37
|
+
wsOutputFull(url: string, data: any): void;
|
|
38
|
+
wsOutput(url: string): void;
|
|
39
|
+
wsError(url: string, data: any, stackTrace: any): void;
|
|
40
|
+
wsClose(url: any): void;
|
|
41
|
+
wsTerminate(url: any): void;
|
|
42
|
+
}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as util from "node:util";
|
|
4
|
+
export function getDate() {
|
|
5
|
+
let date = new Date();
|
|
6
|
+
return `${date.getFullYear()}.${date.getMonth() + 1}.${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
|
|
7
|
+
}
|
|
8
|
+
export default class Logger {
|
|
9
|
+
constructor(log, path_) {
|
|
10
|
+
this.log = log;
|
|
11
|
+
this.path_ = path_;
|
|
12
|
+
this.logData = "";
|
|
13
|
+
}
|
|
14
|
+
get path() { return this.path_; }
|
|
15
|
+
set path(path) {
|
|
16
|
+
this.path_ = path;
|
|
17
|
+
if (this.path_)
|
|
18
|
+
fs.writeFileSync(this.path_, this.logData);
|
|
19
|
+
}
|
|
20
|
+
clear() {
|
|
21
|
+
if (this.path_)
|
|
22
|
+
fs.writeFileSync(this.path_, "");
|
|
23
|
+
}
|
|
24
|
+
logSeparately(consoleData, fileData) {
|
|
25
|
+
this.log(...consoleData);
|
|
26
|
+
this.logData += (this.logData.length ? '\n' : "") + fileData.join(' ');
|
|
27
|
+
if (this.path_)
|
|
28
|
+
fs.writeFileSync(this.path_, this.logData);
|
|
29
|
+
}
|
|
30
|
+
getPrefix(tag) {
|
|
31
|
+
return `[${getDate()}] ${tag}:`;
|
|
32
|
+
}
|
|
33
|
+
Log(tag, func = chalk.white, ...data) {
|
|
34
|
+
let prefix = this.getPrefix(tag);
|
|
35
|
+
this.logSeparately([func(prefix), ...data.map((elem) => typeof elem !== "string" ? elem : func(elem))], [prefix, ...data.map(elem => util.inspect(elem))]);
|
|
36
|
+
}
|
|
37
|
+
message(...data) {
|
|
38
|
+
return this.Log("info", chalk.white, ...data);
|
|
39
|
+
}
|
|
40
|
+
info(...data) {
|
|
41
|
+
return this.Log("info", chalk.white, ...data);
|
|
42
|
+
}
|
|
43
|
+
success(...data) {
|
|
44
|
+
return this.Log("success", chalk.green, ...data);
|
|
45
|
+
}
|
|
46
|
+
warning(...data) {
|
|
47
|
+
return this.Log("warn", chalk.yellow, ...data);
|
|
48
|
+
}
|
|
49
|
+
error(...data) {
|
|
50
|
+
return this.Log("error", chalk.redBright, ...data);
|
|
51
|
+
}
|
|
52
|
+
fatal(...data) {
|
|
53
|
+
return this.Log("fatal", chalk.red, ...data);
|
|
54
|
+
}
|
|
55
|
+
initMessage(name, version, port, host) {
|
|
56
|
+
this.logSeparately([chalk.greenBright(`--++== ${chalk.green(name)} ${chalk.cyan('v' + version)}; ${chalk.cyan(`${host}:${port}`)} ==++--`)], [`--++== ${name} v${version}; port: ${port} ==++--`]);
|
|
57
|
+
}
|
|
58
|
+
formatData(data) {
|
|
59
|
+
return Buffer.isBuffer(data) ? `"${data.toString()}"` : typeof data === "string" ? `"${data}"` : data;
|
|
60
|
+
}
|
|
61
|
+
formatDataColors(data, color = chalk.cyan, defaultColor = chalk.green) {
|
|
62
|
+
return Buffer.isBuffer(data) ? defaultColor(`"${color(data.toString())}"`) : typeof data === "string" ? defaultColor(`"${color(data)}"`) : data;
|
|
63
|
+
}
|
|
64
|
+
requestFull(url, code, request, response) {
|
|
65
|
+
request = typeof request === "string" ? request.replaceAll("\n", "\\n") : request;
|
|
66
|
+
response = typeof response === "string" ? response.replaceAll("\n", "\\n") : response;
|
|
67
|
+
let toLog = [this.getPrefix("request"), `Handled request to`];
|
|
68
|
+
let toLogColours = [...toLog, chalk.cyan(url)];
|
|
69
|
+
// toLog[0] = '\n' + toLog[0];
|
|
70
|
+
toLog.push(url);
|
|
71
|
+
if (code !== undefined) {
|
|
72
|
+
toLog.push(". Code:", code);
|
|
73
|
+
toLogColours.push(". Code:", code);
|
|
74
|
+
}
|
|
75
|
+
if (request !== undefined) {
|
|
76
|
+
toLog.push(". Request:", this.formatData(request));
|
|
77
|
+
toLogColours.push(". Request:", this.formatDataColors(request));
|
|
78
|
+
}
|
|
79
|
+
if (response !== undefined) {
|
|
80
|
+
toLog.push(". Response:", this.formatData(response));
|
|
81
|
+
toLogColours.push(". Response:", this.formatDataColors(response));
|
|
82
|
+
}
|
|
83
|
+
this.logSeparately(toLogColours.map(elem => typeof elem === "string" ? chalk.green(elem) : elem), toLog);
|
|
84
|
+
}
|
|
85
|
+
request(url, code) {
|
|
86
|
+
let toLog = [this.getPrefix("request"), `Handled request to`];
|
|
87
|
+
let toLogColours = [...toLog, chalk.cyan(url)];
|
|
88
|
+
// toLog[0] = '\n' + toLog[0];
|
|
89
|
+
toLog.push(url);
|
|
90
|
+
if (code !== undefined) {
|
|
91
|
+
toLog.push(". Code:", code);
|
|
92
|
+
toLogColours.push(". Code:", code);
|
|
93
|
+
}
|
|
94
|
+
this.logSeparately(toLogColours.map(elem => typeof elem === "string" ? chalk.green(elem) : elem), toLog);
|
|
95
|
+
}
|
|
96
|
+
requestError(url, request, stackTrace) {
|
|
97
|
+
request = typeof request === "string" ? request.replaceAll("\n", "\\n") : request;
|
|
98
|
+
let toLog = [this.getPrefix("request"), `Error during handling request to`];
|
|
99
|
+
let toLogColours = [...toLog, chalk.cyan(url)];
|
|
100
|
+
// toLog[0] = '\n' + toLog[0];
|
|
101
|
+
toLog.push(url);
|
|
102
|
+
if (request !== undefined) {
|
|
103
|
+
toLog.push(". Request:", this.formatData(request));
|
|
104
|
+
toLogColours.push(`. Request:`, this.formatDataColors(request));
|
|
105
|
+
}
|
|
106
|
+
toLog.push(`\n${stackTrace}`);
|
|
107
|
+
toLogColours.push(`\n${stackTrace}`);
|
|
108
|
+
this.logSeparately(toLogColours.map(elem => typeof elem === "string" ? chalk.redBright(elem) : elem), toLog);
|
|
109
|
+
}
|
|
110
|
+
wsConnected(url) {
|
|
111
|
+
let prefix = this.getPrefix("wsConnected");
|
|
112
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Websocket connected on url"), chalk.cyan(url)], [prefix, "Websocket connected on url", url]);
|
|
113
|
+
}
|
|
114
|
+
wsRejected(url) {
|
|
115
|
+
let prefix = this.getPrefix("wsRejected");
|
|
116
|
+
this.logSeparately([chalk.red(prefix), chalk.red("Websocket rejected on url"), chalk.cyan(url)], [prefix, "Websocket rejected on url", url]);
|
|
117
|
+
}
|
|
118
|
+
wsInitFull(url, data) {
|
|
119
|
+
let prefix = this.getPrefix("wsInit");
|
|
120
|
+
this.logSeparately([
|
|
121
|
+
chalk.green(prefix), chalk.green("Websocket init on url"), chalk.cyan(url), chalk.green("done"),
|
|
122
|
+
...(data !== null && data !== undefined ? [chalk.green("Data:"), this.formatDataColors(data)] : [])
|
|
123
|
+
], [
|
|
124
|
+
prefix, "Websocket init on url", url, "done",
|
|
125
|
+
...(data !== null && data !== undefined ? ["Data:", this.formatData(data)] : [])
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
wsInitFailedFull(url, data) {
|
|
129
|
+
let prefix = this.getPrefix("wsInitFailed");
|
|
130
|
+
this.logSeparately([
|
|
131
|
+
chalk.green(prefix), chalk.green("Websocket init on url"), chalk.cyan(url), chalk.red("failed"),
|
|
132
|
+
...(data !== null && data !== undefined ? [chalk.green("Data:"), this.formatDataColors(data)] : [])
|
|
133
|
+
], [
|
|
134
|
+
prefix, "Websocket init on url", url, "failed",
|
|
135
|
+
...(data !== null && data !== undefined ? ["Data:", this.formatData(data)] : [])
|
|
136
|
+
]);
|
|
137
|
+
}
|
|
138
|
+
wsInit(url) {
|
|
139
|
+
let prefix = this.getPrefix("wsInit");
|
|
140
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Websocket init on url"), chalk.cyan(url), chalk.red("done")], [prefix, "Websocket init on url", url, "done"]);
|
|
141
|
+
}
|
|
142
|
+
wsInitFailed(url) {
|
|
143
|
+
let prefix = this.getPrefix("wsInitFailed");
|
|
144
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Websocket init on url"), chalk.cyan(url), chalk.red("failed")], [prefix, "Websocket init on url", url, "failed"]);
|
|
145
|
+
}
|
|
146
|
+
wsIncomingEventFull(url, event, data) {
|
|
147
|
+
let prefix = this.getPrefix("wsIncomingEvent");
|
|
148
|
+
this.logSeparately([
|
|
149
|
+
chalk.green(prefix), chalk.green("Client, connected on url"), chalk.cyan(url) + chalk.green(','), chalk.green("has emitted event"), chalk.green(`"${chalk.cyan(event)}"`),
|
|
150
|
+
...(data !== null && data !== undefined ? [chalk.green("with data:"), this.formatDataColors(data)] : [])
|
|
151
|
+
], [
|
|
152
|
+
prefix, "Client, connected on url", url + ',', "has emitted event", `"${event}"`,
|
|
153
|
+
...(data !== null && data !== undefined ? ["with data:", this.formatData(data)] : [])
|
|
154
|
+
]);
|
|
155
|
+
}
|
|
156
|
+
wsIncomingEvent(url, event) {
|
|
157
|
+
let prefix = this.getPrefix("wsIncomingEvent");
|
|
158
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Client, connected on url"),
|
|
159
|
+
chalk.cyan(url) + chalk.green(','), chalk.green("has emitted event"), chalk.green(`${chalk.cyan(event)}`)], [prefix, "Client, connected on url", url + ',', "has emitted event", `"${event}"`]);
|
|
160
|
+
}
|
|
161
|
+
wsOutgoingEventFull(url, event, data) {
|
|
162
|
+
let prefix = this.getPrefix("wsOutgoingEvent");
|
|
163
|
+
this.logSeparately([
|
|
164
|
+
chalk.green(prefix), chalk.green("Server has emitted event"), chalk.green(`"${chalk.cyan(event)}"`), chalk.green("to websocket connection on url"), chalk.cyan(url),
|
|
165
|
+
...(data !== null && data !== undefined ? [chalk.green("with data:"), this.formatDataColors(data)] : [])
|
|
166
|
+
], [
|
|
167
|
+
prefix, "Server has emitted event", `"${event}"`, "to websocket connection on url", url,
|
|
168
|
+
...(data !== null && data !== undefined ? ["with data:", this.formatData(data)] : [])
|
|
169
|
+
]);
|
|
170
|
+
}
|
|
171
|
+
wsOutgoingEvent(url, event) {
|
|
172
|
+
let prefix = this.getPrefix("wsOutgoingEvent");
|
|
173
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Server has emitted event"), chalk.green(`${chalk.cyan(event)}`), chalk.green("to websocket connection on url"), chalk.cyan(url)], [prefix, "Server has emitted event", event, "to websocket connection on url", url]);
|
|
174
|
+
}
|
|
175
|
+
wsInputFull(url, data) {
|
|
176
|
+
let prefix = this.getPrefix("wsInput");
|
|
177
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Client, connected on url"),
|
|
178
|
+
chalk.cyan(url) + chalk.green(','), chalk.green("has sent message"), this.formatDataColors(data)], [prefix, "Client, connected on url", url + ',', "has sent message", this.formatData(data)]);
|
|
179
|
+
}
|
|
180
|
+
wsInput(url) {
|
|
181
|
+
let prefix = this.getPrefix("wsInput");
|
|
182
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Client, connected on url"),
|
|
183
|
+
chalk.cyan(url) + chalk.green(','), chalk.green("has sent message")], [prefix, "Client, connected on url", url + ',', "has sent message"]);
|
|
184
|
+
}
|
|
185
|
+
wsOutputFull(url, data) {
|
|
186
|
+
let prefix = this.getPrefix("wsOutput");
|
|
187
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Server has sent message"), this.formatDataColors(data),
|
|
188
|
+
chalk.green("to websocket connection on url"),
|
|
189
|
+
chalk.cyan(url)], [prefix, "Server has sent message", this.formatData(data),
|
|
190
|
+
"to websocket connection on url", url]);
|
|
191
|
+
}
|
|
192
|
+
wsOutput(url) {
|
|
193
|
+
let prefix = this.getPrefix("wsOutput");
|
|
194
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Server has sent message"),
|
|
195
|
+
chalk.green("to websocket connection on url"), chalk.cyan(url)], [prefix, "Server has sent message", "to websocket connection on url", url]);
|
|
196
|
+
}
|
|
197
|
+
wsError(url, data, stackTrace) {
|
|
198
|
+
data = typeof data === "string" ? data.replaceAll("\n", "\\n") : data;
|
|
199
|
+
let toLog = [this.getPrefix("error"), `Error during handling websocket input to`];
|
|
200
|
+
let toLogColours = [...toLog, chalk.cyan(url)];
|
|
201
|
+
// toLog[0] = '\n' + toLog[0];
|
|
202
|
+
toLog.push(url);
|
|
203
|
+
if (data !== undefined) {
|
|
204
|
+
toLog.push(". Data:", this.formatData(data));
|
|
205
|
+
toLogColours.push(`. Data:`, this.formatDataColors(data));
|
|
206
|
+
}
|
|
207
|
+
toLog.push(`\n${stackTrace}`);
|
|
208
|
+
toLogColours.push(`\n${stackTrace}`);
|
|
209
|
+
this.logSeparately(toLogColours.map(elem => typeof elem === "string" ? chalk.redBright(elem) : elem), toLog);
|
|
210
|
+
}
|
|
211
|
+
wsClose(url) {
|
|
212
|
+
let prefix = this.getPrefix("wsClose");
|
|
213
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Websocket connection on url"), chalk.cyan(url),
|
|
214
|
+
chalk.green("closed")], [prefix, "Websocket connection on url", url, "closed"]);
|
|
215
|
+
}
|
|
216
|
+
wsTerminate(url) {
|
|
217
|
+
let prefix = this.getPrefix("wsTerminate");
|
|
218
|
+
this.logSeparately([chalk.green(prefix), chalk.green("Websocket connection on url"), chalk.cyan(url),
|
|
219
|
+
chalk.red("terminated")], [prefix, "Websocket connection on url", url, "terminated"]);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Request } from "express";
|
|
2
|
+
import Backendium from "./index.js";
|
|
3
|
+
import { ValidationError, Validator } from "checkeasy";
|
|
4
|
+
import BackendiumResponse from "./response";
|
|
5
|
+
export type ValidatorsType<BodyType, ParamsType, QueryType, HeadersType> = {
|
|
6
|
+
bodyValidator?: Validator<BodyType>;
|
|
7
|
+
paramsValidator?: Validator<ParamsType>;
|
|
8
|
+
queryValidator?: Validator<QueryType>;
|
|
9
|
+
headersValidator?: Validator<HeadersType>;
|
|
10
|
+
};
|
|
11
|
+
export type AuthCheckerType<AuthType> = (request: Request, response: BackendiumResponse, app: Backendium) => AuthType | null | Promise<AuthType | null>;
|
|
12
|
+
export type AuthFailedType = (request: Request, response: BackendiumResponse, app: Backendium) => void;
|
|
13
|
+
export type BackendiumRequestOptionsType<BodyType, ParamsType, QueryType, AuthType, HeadersType> = ValidatorsType<BodyType, ParamsType, QueryType, HeadersType> & {
|
|
14
|
+
auth?: boolean;
|
|
15
|
+
authChecker?: AuthCheckerType<AuthType>;
|
|
16
|
+
authFailed?: AuthFailedType;
|
|
17
|
+
errorMessage?: string;
|
|
18
|
+
errorHandler?(request: Request, response: BackendiumResponse, data: any, app: Backendium, error: any): void;
|
|
19
|
+
validationErrorMessage?: string;
|
|
20
|
+
validationErrorHandler?(request: Request, response: BackendiumResponse, app: Backendium, data: Buffer, error: ValidationError, message?: string): void;
|
|
21
|
+
};
|
|
22
|
+
export type BackendiumRequestType<BodyType, ParamsType, QueryType, AuthType, HeadersType, DefaultAuthType> = {
|
|
23
|
+
expressRequest: Request;
|
|
24
|
+
body: BodyType;
|
|
25
|
+
params: ParamsType;
|
|
26
|
+
query: QueryType;
|
|
27
|
+
headers: HeadersType;
|
|
28
|
+
bodyBuffer: Buffer;
|
|
29
|
+
options: BackendiumRequestOptionsType<BodyType, ParamsType, QueryType, AuthType, HeadersType>;
|
|
30
|
+
app: Backendium;
|
|
31
|
+
auth: AuthType;
|
|
32
|
+
globalAuth: DefaultAuthType;
|
|
33
|
+
};
|
|
34
|
+
export default function parseRequest<BodyType, ParamsType, QueryType, AuthType, HeadersType>(request: Request, app: Backendium, { bodyValidator, paramsValidator, queryValidator, headersValidator, ...other }: BackendiumRequestOptionsType<BodyType, ParamsType, QueryType, AuthType, HeadersType>): Promise<Omit<Omit<BackendiumRequestType<BodyType, ParamsType, QueryType, AuthType, HeadersType, any>, "auth">, "globalAuth"> | [Buffer, ValidationError]>;
|
package/dist/request.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
11
|
+
var t = {};
|
|
12
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
13
|
+
t[p] = s[p];
|
|
14
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
15
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
16
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
17
|
+
t[p[i]] = s[p[i]];
|
|
18
|
+
}
|
|
19
|
+
return t;
|
|
20
|
+
};
|
|
21
|
+
import { ValidationError } from "checkeasy";
|
|
22
|
+
function parse(data, validator, root = "") {
|
|
23
|
+
if (!validator) {
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
return validator(data, root);
|
|
29
|
+
}
|
|
30
|
+
catch (error0) {
|
|
31
|
+
if (Buffer.isBuffer(data)) {
|
|
32
|
+
try {
|
|
33
|
+
return validator(JSON.parse(data.toString()), root);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (error instanceof ValidationError)
|
|
37
|
+
throw error;
|
|
38
|
+
throw error0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
throw error0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function getBody(request) {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
if (request.body)
|
|
47
|
+
return request.body;
|
|
48
|
+
return new Promise(resolve => {
|
|
49
|
+
let buffer = Buffer.alloc(0);
|
|
50
|
+
request.on("data", chunk => buffer = Buffer.concat([buffer, chunk]));
|
|
51
|
+
request.on("end", () => {
|
|
52
|
+
request.body = buffer;
|
|
53
|
+
resolve(buffer);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export default function parseRequest(request, app, _a) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
var { bodyValidator, paramsValidator, queryValidator, headersValidator } = _a, other = __rest(_a, ["bodyValidator", "paramsValidator", "queryValidator", "headersValidator"]);
|
|
61
|
+
let bodyBuffer = yield getBody(request);
|
|
62
|
+
try {
|
|
63
|
+
let body = parse(bodyBuffer, bodyValidator);
|
|
64
|
+
let params = parse(request.params, paramsValidator);
|
|
65
|
+
let query = parse(request.query, queryValidator);
|
|
66
|
+
let headers = parse(request.headers, headersValidator);
|
|
67
|
+
return {
|
|
68
|
+
expressRequest: request, body, params, query, headers, bodyBuffer, app,
|
|
69
|
+
options: Object.assign({ bodyValidator, paramsValidator, queryValidator, headersValidator }, other)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (error instanceof ValidationError)
|
|
74
|
+
return [bodyBuffer, error];
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Response } from "express";
|
|
2
|
+
import Backendium from "./index.js";
|
|
3
|
+
export default class BackendiumResponse {
|
|
4
|
+
expressResponse: Response;
|
|
5
|
+
app: Backendium;
|
|
6
|
+
lastStatus: number;
|
|
7
|
+
lastResponse: any;
|
|
8
|
+
constructor(expressResponse: Response, app: Backendium);
|
|
9
|
+
status(status: number): void;
|
|
10
|
+
end(data?: any, status?: number): void;
|
|
11
|
+
}
|