backendium 0.0.15 → 0.0.17
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 +2 -2
- package/dist/handler.js +24 -47
- package/dist/index.d.ts +2 -2
- package/dist/index.js +13 -27
- package/dist/logger.js +3 -1
- package/dist/request.d.ts +8 -9
- package/dist/request.js +31 -53
- package/dist/response.js +4 -1
- package/dist/router.js +7 -8
- package/dist/ws.js +53 -64
- package/package.json +4 -3
- package/readme.md +1 -1
- package/src/handler.ts +11 -12
- package/src/index.ts +2 -2
- package/src/request.ts +23 -20
- package/src/ws.ts +1 -0
- package/tsconfig.json +1 -1
package/dist/handler.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import Backendium from "./index.js";
|
|
|
3
3
|
import { NextFunction, Request, RequestHandler } from "express";
|
|
4
4
|
import { BackendiumRequestOptionsType, BackendiumRequestType } from "./request.js";
|
|
5
5
|
import { BackendiumRouter } from "./router.js";
|
|
6
|
-
import {
|
|
6
|
+
import { ParsingError } from "parsium";
|
|
7
7
|
export type BackendiumHandlerReturnType = void | undefined | {
|
|
8
8
|
code?: number;
|
|
9
9
|
next?: boolean;
|
|
@@ -12,5 +12,5 @@ export type BackendiumHandlerType<BodyType, ParamsType, QueryType, AuthType, Hea
|
|
|
12
12
|
export type RawHandlerType<DefaultAuthType> = (router: BackendiumRouter<DefaultAuthType>) => (app: Backendium) => RequestHandler;
|
|
13
13
|
export declare function defaultAuthFailedHandler(request: Request, response: BackendiumResponse, app: Backendium): void;
|
|
14
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,
|
|
15
|
+
export declare function defaultValidationErrorHandler(request: Request, response: BackendiumResponse, app: Backendium, error: ParsingError, message: string): void;
|
|
16
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
CHANGED
|
@@ -1,65 +1,42 @@
|
|
|
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
1
|
import BackendiumResponse from "./response.js";
|
|
22
2
|
import parseRequest from "./request.js";
|
|
3
|
+
import { ParsingError } from "parsium";
|
|
23
4
|
export function defaultAuthFailedHandler(request, response, app) {
|
|
24
5
|
response.status(209);
|
|
25
6
|
response.end();
|
|
26
7
|
}
|
|
27
8
|
export function defaultErrorHandler(request, response, data, app, error, message) {
|
|
28
9
|
response.status(500);
|
|
29
|
-
response.end(message
|
|
10
|
+
response.end(message ?? "Internal Server Error");
|
|
30
11
|
app.logger.requestError(request.url, data, error);
|
|
31
12
|
}
|
|
32
|
-
export function defaultValidationErrorHandler(request, response, app,
|
|
13
|
+
export function defaultValidationErrorHandler(request, response, app, error, message) {
|
|
33
14
|
response.status(400);
|
|
34
|
-
response.end(message
|
|
15
|
+
response.end(message ?? "Validation failed: " + error.message);
|
|
35
16
|
}
|
|
36
|
-
export default function backendiumHandler(handler,
|
|
37
|
-
|
|
38
|
-
return (router) => (app) => ((request, response, next) => __awaiter(this, void 0, void 0, function* () {
|
|
39
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
17
|
+
export default function backendiumHandler(handler, { auth, authChecker, authFailed, errorHandler, errorMessage, validationErrorHandler, validationErrorMessage, ...options }) {
|
|
18
|
+
return (router) => (app) => (async (request, response, next) => {
|
|
40
19
|
let body;
|
|
41
20
|
try {
|
|
42
|
-
let req =
|
|
21
|
+
let req = await parseRequest(request, app, { ...options, auth, authChecker, authFailed, errorHandler, validationErrorHandler, errorMessage, validationErrorMessage });
|
|
43
22
|
let res = new BackendiumResponse(response, app);
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
app.logger.requestFull(request.url, res.lastStatus, data, res.lastResponse);
|
|
23
|
+
if (req instanceof ParsingError) {
|
|
24
|
+
(validationErrorHandler ?? app.config.validationErrorHandler ?? defaultValidationErrorHandler)(request, res, app, req, validationErrorMessage ?? app.config.validationErrorMessage);
|
|
25
|
+
if (app.config.logging?.fullRequest)
|
|
26
|
+
app.logger.requestFull(request.url, res.lastStatus, '"<invalid>"', res.lastResponse);
|
|
49
27
|
else
|
|
50
28
|
app.logger.request(request.url, res.lastStatus);
|
|
51
29
|
return;
|
|
52
30
|
}
|
|
53
31
|
body = req.body;
|
|
54
|
-
// @ts-ignore
|
|
55
32
|
let authData = undefined;
|
|
56
33
|
if (authChecker) {
|
|
57
34
|
let ret = authChecker(request, res, app);
|
|
58
35
|
if (ret instanceof Promise)
|
|
59
|
-
ret =
|
|
36
|
+
ret = await ret;
|
|
60
37
|
if (ret === null) {
|
|
61
|
-
(
|
|
62
|
-
if (
|
|
38
|
+
(authFailed ?? router.authFailed ?? app.authFailed ?? defaultAuthFailedHandler)(request, res, app);
|
|
39
|
+
if (app.config.logging?.fullRequest)
|
|
63
40
|
app.logger.requestFull(request.url, res.lastStatus, req.body, res.lastResponse);
|
|
64
41
|
else
|
|
65
42
|
app.logger.request(request.url, res.lastStatus);
|
|
@@ -67,15 +44,14 @@ export default function backendiumHandler(handler, _a) {
|
|
|
67
44
|
}
|
|
68
45
|
authData = ret;
|
|
69
46
|
}
|
|
70
|
-
// @ts-ignore
|
|
71
47
|
let globalAuthData = undefined;
|
|
72
48
|
if (!authChecker && auth && router.authChecker) {
|
|
73
49
|
let ret = router.authChecker(request, res, app);
|
|
74
50
|
if (ret instanceof Promise)
|
|
75
|
-
ret =
|
|
51
|
+
ret = await ret;
|
|
76
52
|
if (ret === null) {
|
|
77
|
-
(
|
|
78
|
-
if (
|
|
53
|
+
(authFailed ?? router.authFailed ?? app.authFailed ?? defaultAuthFailedHandler)(request, res, app);
|
|
54
|
+
if (app.config.logging?.fullRequest)
|
|
79
55
|
app.logger.requestFull(request.url, res.lastStatus, req.body, res.lastResponse);
|
|
80
56
|
else
|
|
81
57
|
app.logger.request(request.url, res.lastStatus);
|
|
@@ -83,11 +59,11 @@ export default function backendiumHandler(handler, _a) {
|
|
|
83
59
|
}
|
|
84
60
|
globalAuthData = ret;
|
|
85
61
|
}
|
|
86
|
-
let ret = handler(
|
|
62
|
+
let ret = handler({ ...req, auth: authData, globalAuth: globalAuthData }, res, app, next);
|
|
87
63
|
if (ret instanceof Promise)
|
|
88
|
-
ret =
|
|
64
|
+
ret = await ret;
|
|
89
65
|
if (!ret) {
|
|
90
|
-
if (
|
|
66
|
+
if (app.config.logging?.fullRequest)
|
|
91
67
|
app.logger.requestFull(request.url, res.lastStatus, req.body, res.lastResponse);
|
|
92
68
|
else
|
|
93
69
|
app.logger.request(request.url, res.lastStatus);
|
|
@@ -103,13 +79,14 @@ export default function backendiumHandler(handler, _a) {
|
|
|
103
79
|
response.end();
|
|
104
80
|
}
|
|
105
81
|
catch (error) { }
|
|
106
|
-
if (
|
|
82
|
+
if (app.config.logging?.fullRequest)
|
|
107
83
|
app.logger.requestFull(request.url, res.lastStatus, req.body, res.lastResponse);
|
|
108
84
|
else
|
|
109
85
|
app.logger.request(request.url, res.lastStatus);
|
|
110
86
|
}
|
|
111
87
|
catch (error) {
|
|
112
|
-
(
|
|
88
|
+
(errorHandler ?? app.config.errorHandler ?? defaultErrorHandler)(request, new BackendiumResponse(response, app), body, app, error, errorMessage ?? app.config.errorMessage);
|
|
113
89
|
}
|
|
114
|
-
})
|
|
90
|
+
});
|
|
115
91
|
}
|
|
92
|
+
// @TODO save some body chunks from parsium for logging
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { EventEmitter, EventKey } from "event-emitter-typescript";
|
|
|
5
5
|
import { WebSocketExpress, WSRequestHandler } from "websocket-express";
|
|
6
6
|
import { BackendiumWebSocket } from "./ws.js";
|
|
7
7
|
import Logger from "./logger.js";
|
|
8
|
-
import BackendiumResponse from "./response
|
|
8
|
+
import BackendiumResponse from "./response";
|
|
9
9
|
import { ValidationError } from "checkeasy";
|
|
10
10
|
import type { MethodType } from "./httpRouter.js";
|
|
11
11
|
export type BackendiumConfigType = {
|
|
@@ -26,7 +26,7 @@ export type BackendiumConfigType = {
|
|
|
26
26
|
errorMessage: string;
|
|
27
27
|
errorHandler(request: Request, response: BackendiumResponse, data: any, app: Backendium, error: any, message?: string): void;
|
|
28
28
|
validationErrorMessage: string;
|
|
29
|
-
validationErrorHandler(request: Request, response: BackendiumResponse, app: Backendium,
|
|
29
|
+
validationErrorHandler(request: Request, response: BackendiumResponse, app: Backendium, error: ValidationError, message?: string): void;
|
|
30
30
|
wsErrorMessage: string;
|
|
31
31
|
wsErrorHandler(data: Buffer, connection: BackendiumWebSocket<any>, app: Backendium, error: any): void;
|
|
32
32
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,32 +1,22 @@
|
|
|
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
1
|
import { BackendiumRouter } from "./router.js";
|
|
11
2
|
import { EventEmitter } from "event-emitter-typescript";
|
|
12
3
|
import { WebSocketExpress } from "websocket-express";
|
|
13
4
|
import Logger from "./logger.js";
|
|
14
5
|
export default class Backendium extends BackendiumRouter {
|
|
6
|
+
express = new WebSocketExpress;
|
|
7
|
+
eventEmitter = new EventEmitter;
|
|
8
|
+
logger = new Logger(console.log.bind(console));
|
|
9
|
+
config_ = {};
|
|
15
10
|
constructor(config = {}) {
|
|
16
11
|
super();
|
|
17
|
-
this.express = new WebSocketExpress;
|
|
18
|
-
this.eventEmitter = new EventEmitter;
|
|
19
|
-
this.logger = new Logger(console.log.bind(console));
|
|
20
|
-
this.config_ = {};
|
|
21
12
|
this.config = config;
|
|
22
13
|
}
|
|
23
14
|
get config() { return this.config_; }
|
|
24
15
|
set config(config) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if ((_d = (_c = this.config_.logging) === null || _c === void 0 ? void 0 : _c.replaceConsoleLog) !== null && _d !== void 0 ? _d : true) {
|
|
16
|
+
this.config_ = { ...this.config_, ...config, logging: { ...this.config_.logging, ...config.logging } };
|
|
17
|
+
if (this.config_.logging?.path)
|
|
18
|
+
this.logger.path = this.config_.logging?.path;
|
|
19
|
+
if (this.config_.logging?.replaceConsoleLog ?? true) {
|
|
30
20
|
console.log = this.logger.message.bind(this.logger);
|
|
31
21
|
console.error = this.logger.error.bind(this.logger);
|
|
32
22
|
}
|
|
@@ -53,7 +43,6 @@ export default class Backendium extends BackendiumRouter {
|
|
|
53
43
|
}
|
|
54
44
|
;
|
|
55
45
|
start(callback) {
|
|
56
|
-
var _a, _b;
|
|
57
46
|
this.handlers.forEach(([method, route, handlers]) => {
|
|
58
47
|
if (method == "ws")
|
|
59
48
|
this.addWSHandler(route, handlers.map(handler => handler(this)));
|
|
@@ -68,20 +57,17 @@ export default class Backendium extends BackendiumRouter {
|
|
|
68
57
|
// if (callback) callback(server);
|
|
69
58
|
// this.eventEmitter.emit("start", [server]);
|
|
70
59
|
// });
|
|
71
|
-
const server = this.express.listen(
|
|
72
|
-
|
|
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");
|
|
60
|
+
const server = this.express.listen(this.config_.port ?? 8080, this.config_.host ?? "localhost", () => {
|
|
61
|
+
this.logger.initMessage(this.config_.name ?? "app", this.config_.version ?? "0.0.0", this.config.port ?? 8080, this.config_.host ?? "localhost");
|
|
74
62
|
if (callback)
|
|
75
63
|
callback(server);
|
|
76
64
|
this.eventEmitter.emit("start", [server]);
|
|
77
65
|
});
|
|
78
66
|
return server;
|
|
79
67
|
}
|
|
80
|
-
startAsync() {
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
this.start(resolve);
|
|
84
|
-
});
|
|
68
|
+
async startAsync() {
|
|
69
|
+
return new Promise(resolve => {
|
|
70
|
+
this.start(resolve);
|
|
85
71
|
});
|
|
86
72
|
}
|
|
87
73
|
}
|
package/dist/logger.js
CHANGED
|
@@ -6,10 +6,12 @@ export function getDate() {
|
|
|
6
6
|
return `${date.getFullYear()}.${date.getMonth() + 1}.${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
|
|
7
7
|
}
|
|
8
8
|
export default class Logger {
|
|
9
|
+
log;
|
|
10
|
+
path_;
|
|
11
|
+
logData = "";
|
|
9
12
|
constructor(log, path_) {
|
|
10
13
|
this.log = log;
|
|
11
14
|
this.path_ = path_;
|
|
12
|
-
this.logData = "";
|
|
13
15
|
}
|
|
14
16
|
get path() { return this.path_; }
|
|
15
17
|
set path(path) {
|
package/dist/request.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Request } from "express";
|
|
2
2
|
import Backendium from "./index.js";
|
|
3
|
-
import {
|
|
4
|
-
import BackendiumResponse from "./response";
|
|
3
|
+
import { Parser, ParsingError } from "parsium";
|
|
4
|
+
import BackendiumResponse from "./response.js";
|
|
5
5
|
export type ValidatorsType<BodyType, ParamsType, QueryType, HeadersType> = {
|
|
6
|
-
bodyValidator?:
|
|
7
|
-
paramsValidator?:
|
|
8
|
-
queryValidator?:
|
|
9
|
-
headersValidator?:
|
|
6
|
+
bodyValidator?: Parser<BodyType>;
|
|
7
|
+
paramsValidator?: Parser<ParamsType>;
|
|
8
|
+
queryValidator?: Parser<QueryType>;
|
|
9
|
+
headersValidator?: Parser<HeadersType>;
|
|
10
10
|
};
|
|
11
11
|
export type AuthCheckerType<AuthType> = (request: Request, response: BackendiumResponse, app: Backendium) => AuthType | null | Promise<AuthType | null>;
|
|
12
12
|
export type AuthFailedType = (request: Request, response: BackendiumResponse, app: Backendium) => void;
|
|
@@ -17,7 +17,7 @@ export type BackendiumRequestOptionsType<BodyType, ParamsType, QueryType, AuthTy
|
|
|
17
17
|
errorMessage?: string;
|
|
18
18
|
errorHandler?(request: Request, response: BackendiumResponse, data: any, app: Backendium, error: any): void;
|
|
19
19
|
validationErrorMessage?: string;
|
|
20
|
-
validationErrorHandler?(request: Request, response: BackendiumResponse, app: Backendium,
|
|
20
|
+
validationErrorHandler?(request: Request, response: BackendiumResponse, app: Backendium, error: ParsingError, message?: string): void;
|
|
21
21
|
};
|
|
22
22
|
export type BackendiumRequestType<BodyType, ParamsType, QueryType, AuthType, HeadersType, DefaultAuthType> = {
|
|
23
23
|
expressRequest: Request;
|
|
@@ -25,10 +25,9 @@ export type BackendiumRequestType<BodyType, ParamsType, QueryType, AuthType, Hea
|
|
|
25
25
|
params: ParamsType;
|
|
26
26
|
query: QueryType;
|
|
27
27
|
headers: HeadersType;
|
|
28
|
-
bodyBuffer: Buffer;
|
|
29
28
|
options: BackendiumRequestOptionsType<BodyType, ParamsType, QueryType, AuthType, HeadersType>;
|
|
30
29
|
app: Backendium;
|
|
31
30
|
auth: AuthType;
|
|
32
31
|
globalAuth: DefaultAuthType;
|
|
33
32
|
};
|
|
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"> |
|
|
33
|
+
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"> | ParsingError>;
|
package/dist/request.js
CHANGED
|
@@ -1,24 +1,4 @@
|
|
|
1
|
-
|
|
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";
|
|
1
|
+
import { any, ParsingError } from "parsium";
|
|
22
2
|
function parse(data, validator, root = "") {
|
|
23
3
|
if (!validator) {
|
|
24
4
|
// @ts-ignore
|
|
@@ -33,7 +13,7 @@ function parse(data, validator, root = "") {
|
|
|
33
13
|
return validator(JSON.parse(data.toString()), root);
|
|
34
14
|
}
|
|
35
15
|
catch (error) {
|
|
36
|
-
if (error instanceof
|
|
16
|
+
if (error instanceof ParsingError)
|
|
37
17
|
throw error;
|
|
38
18
|
throw error0;
|
|
39
19
|
}
|
|
@@ -41,38 +21,36 @@ function parse(data, validator, root = "") {
|
|
|
41
21
|
throw error0;
|
|
42
22
|
}
|
|
43
23
|
}
|
|
44
|
-
function getBody(request) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
request.
|
|
52
|
-
|
|
53
|
-
resolve(buffer);
|
|
54
|
-
});
|
|
24
|
+
async function getBody(request) {
|
|
25
|
+
if (request.body)
|
|
26
|
+
return request.body;
|
|
27
|
+
return new Promise(resolve => {
|
|
28
|
+
let buffer = Buffer.alloc(0);
|
|
29
|
+
request.on("data", chunk => buffer = Buffer.concat([buffer, chunk]));
|
|
30
|
+
request.on("end", () => {
|
|
31
|
+
request.body = buffer;
|
|
32
|
+
resolve(buffer);
|
|
55
33
|
});
|
|
56
34
|
});
|
|
57
35
|
}
|
|
58
|
-
export default function parseRequest(request, app,
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
let
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
36
|
+
export default async function parseRequest(request, app, { bodyValidator, paramsValidator, queryValidator, headersValidator, ...other }) {
|
|
37
|
+
// let bodyBuffer = await getBody(request);
|
|
38
|
+
try {
|
|
39
|
+
// let body = parse(bodyBuffer, bodyValidator, "body");
|
|
40
|
+
// let params = parse(request.params, paramsValidator, "params");
|
|
41
|
+
// let query = parse(request.query, queryValidator, "query");
|
|
42
|
+
// let headers = parse(request.headers, headersValidator, "headers");
|
|
43
|
+
let body = await (bodyValidator ?? any()).stream(request, "body");
|
|
44
|
+
let params = (paramsValidator ?? any())(request.params, "params");
|
|
45
|
+
let query = (queryValidator ?? any())(request.query, "query");
|
|
46
|
+
let headers = (headersValidator ?? any())(request.headers, "headers");
|
|
47
|
+
return {
|
|
48
|
+
expressRequest: request, body, params, query, headers, app,
|
|
49
|
+
options: { bodyValidator, paramsValidator, queryValidator, headersValidator, ...other }
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
//if (error instanceof ParsingError) return error;
|
|
54
|
+
return error;
|
|
55
|
+
}
|
|
78
56
|
}
|
package/dist/response.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export default class BackendiumResponse {
|
|
2
|
+
expressResponse;
|
|
3
|
+
app;
|
|
4
|
+
lastStatus = 200;
|
|
5
|
+
lastResponse;
|
|
2
6
|
constructor(expressResponse, app) {
|
|
3
7
|
this.expressResponse = expressResponse;
|
|
4
8
|
this.app = app;
|
|
5
|
-
this.lastStatus = 200;
|
|
6
9
|
}
|
|
7
10
|
status(status) {
|
|
8
11
|
this.lastStatus = status;
|
package/dist/router.js
CHANGED
|
@@ -2,12 +2,11 @@ import backendiumHandler from "./handler.js";
|
|
|
2
2
|
import { WebSocketRouteConstructor } from "./ws.js";
|
|
3
3
|
import { BackendiumHttpRouter } from "./httpRouter.js";
|
|
4
4
|
export class BackendiumRouter extends BackendiumHttpRouter {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
5
|
+
_handlers = [];
|
|
6
|
+
authChecker;
|
|
7
|
+
authFailed;
|
|
9
8
|
pushHandlers(method, path, options, handlers) {
|
|
10
|
-
this._handlers.push([method, path, handlers.map(handler => backendiumHandler(handler, options
|
|
9
|
+
this._handlers.push([method, path, handlers.map(handler => backendiumHandler(handler, options ?? { auth: false })(this))]);
|
|
11
10
|
}
|
|
12
11
|
get handlers() { return this._handlers; }
|
|
13
12
|
ws(route) {
|
|
@@ -18,7 +17,7 @@ export class BackendiumRouter extends BackendiumHttpRouter {
|
|
|
18
17
|
return constructor;
|
|
19
18
|
}
|
|
20
19
|
static addPrefix([method, route, handler], prefix) {
|
|
21
|
-
return [method, route || !
|
|
20
|
+
return [method, route || !route?.startsWith("/") ? prefix + (route ?? "") : prefix + (route ?? ""), handler];
|
|
22
21
|
}
|
|
23
22
|
router(router, routePrefix = "") {
|
|
24
23
|
this._handlers.push(...router._handlers.map((handler) => {
|
|
@@ -27,7 +26,7 @@ export class BackendiumRouter extends BackendiumHttpRouter {
|
|
|
27
26
|
}));
|
|
28
27
|
}
|
|
29
28
|
setAuth(checker, failHandler) {
|
|
30
|
-
this.authChecker = checker
|
|
31
|
-
this.authFailed = failHandler
|
|
29
|
+
this.authChecker = checker ?? this.authChecker;
|
|
30
|
+
this.authFailed = failHandler ?? this.authFailed;
|
|
32
31
|
}
|
|
33
32
|
}
|
package/dist/ws.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
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
1
|
import { EventEmitter } from "event-emitter-typescript";
|
|
11
2
|
import { ValidationError } from "checkeasy";
|
|
12
3
|
export class BackendiumWebSocket {
|
|
4
|
+
socket;
|
|
5
|
+
wsConstructor;
|
|
6
|
+
app;
|
|
7
|
+
initData;
|
|
8
|
+
url;
|
|
9
|
+
eventEmitter = new EventEmitter;
|
|
10
|
+
wsEventEmitter = new EventEmitter;
|
|
11
|
+
events = new Set;
|
|
12
|
+
operations = new EventEmitter;
|
|
13
|
+
useEvents = false;
|
|
13
14
|
static rawDataParse(data) {
|
|
15
|
+
// @ts-ignore
|
|
14
16
|
return data instanceof Buffer ? data : data instanceof ArrayBuffer ? Buffer.from(data) : data.reduce((prev, cur) => Buffer.concat([prev, cur]), Buffer.alloc(0));
|
|
15
17
|
}
|
|
16
18
|
parseEventHead(head, message, socket, app) {
|
|
@@ -37,11 +39,10 @@ export class BackendiumWebSocket {
|
|
|
37
39
|
this.operations.emit(operation, [payload, operationConfig, socket, app]);
|
|
38
40
|
}
|
|
39
41
|
parseEventMessage(message, socket, app, isBinary) {
|
|
40
|
-
var _a, _b, _c, _d;
|
|
41
42
|
if (isBinary) {
|
|
42
43
|
this.eventEmitter.emit("notEventMessage", [message, socket, app, isBinary]);
|
|
43
44
|
this.wsConstructor.eventEmitter.emit("notEventMessage", [message, socket, app, isBinary]);
|
|
44
|
-
if (
|
|
45
|
+
if (app.config.logging?.fullWs)
|
|
45
46
|
app.logger.wsInputFull(this.url, message);
|
|
46
47
|
else
|
|
47
48
|
app.logger.wsInput(this.url);
|
|
@@ -51,7 +52,7 @@ export class BackendiumWebSocket {
|
|
|
51
52
|
let [head_, ...data] = message.toString().split("\n");
|
|
52
53
|
let payload = Buffer.from(data.join("\n")), head = this.parseEventHead(head_, message, socket, app);
|
|
53
54
|
if (!head) {
|
|
54
|
-
if (
|
|
55
|
+
if (app.config.logging?.fullWs)
|
|
55
56
|
app.logger.wsInputFull(this.url, message);
|
|
56
57
|
else
|
|
57
58
|
app.logger.wsInput(this.url);
|
|
@@ -59,7 +60,7 @@ export class BackendiumWebSocket {
|
|
|
59
60
|
}
|
|
60
61
|
if ("event" in head) {
|
|
61
62
|
this.emitIncomingEvent(head.event, payload, socket, app, head);
|
|
62
|
-
if (
|
|
63
|
+
if (app.config.logging?.fullWs)
|
|
63
64
|
app.logger.wsIncomingEventFull(this.url, head.event, payload.length ? payload : null);
|
|
64
65
|
else
|
|
65
66
|
app.logger.wsIncomingEvent(this.url, head.event);
|
|
@@ -70,7 +71,7 @@ export class BackendiumWebSocket {
|
|
|
70
71
|
catch (error) {
|
|
71
72
|
this.eventEmitter.emit("notEventMessage", [message, socket, app, isBinary]);
|
|
72
73
|
this.wsConstructor.eventEmitter.emit("notEventMessage", [message, socket, app, isBinary]);
|
|
73
|
-
if (
|
|
74
|
+
if (app.config.logging?.fullWs)
|
|
74
75
|
app.logger.wsInputFull(this.url, message);
|
|
75
76
|
else
|
|
76
77
|
app.logger.wsInput(this.url);
|
|
@@ -83,15 +84,9 @@ export class BackendiumWebSocket {
|
|
|
83
84
|
this.app = app;
|
|
84
85
|
this.initData = initData;
|
|
85
86
|
this.url = url;
|
|
86
|
-
this.eventEmitter = new EventEmitter;
|
|
87
|
-
this.wsEventEmitter = new EventEmitter;
|
|
88
|
-
this.events = new Set;
|
|
89
|
-
this.operations = new EventEmitter;
|
|
90
|
-
this.useEvents = false;
|
|
91
87
|
this.eventEmitter.emit("accept", [this, this.wsConstructor, app]);
|
|
92
88
|
this.wsConstructor.eventEmitter.emit("accept", [this, this.wsConstructor, app]);
|
|
93
89
|
socket.on("message", (data, isBinary) => {
|
|
94
|
-
var _a;
|
|
95
90
|
let buffer = BackendiumWebSocket.rawDataParse(data);
|
|
96
91
|
if (this.useEvents) {
|
|
97
92
|
this.eventEmitter.emit("messageBeforeEvents", [buffer, this, app, isBinary]);
|
|
@@ -101,7 +96,7 @@ export class BackendiumWebSocket {
|
|
|
101
96
|
else {
|
|
102
97
|
this.eventEmitter.emit("notEventMessage", [buffer, this, app, isBinary]);
|
|
103
98
|
this.wsConstructor.eventEmitter.emit("notEventMessage", [buffer, this, app, isBinary]);
|
|
104
|
-
if (
|
|
99
|
+
if (app.config.logging?.fullWs)
|
|
105
100
|
app.logger.wsInputFull(url, data);
|
|
106
101
|
else
|
|
107
102
|
app.logger.wsInput(url);
|
|
@@ -152,7 +147,7 @@ export class BackendiumWebSocket {
|
|
|
152
147
|
return;
|
|
153
148
|
}
|
|
154
149
|
// @ts-ignore
|
|
155
|
-
callback(mainData, socket, app, validator
|
|
150
|
+
callback(mainData, socket, app, validator ?? bufferValidator);
|
|
156
151
|
});
|
|
157
152
|
}
|
|
158
153
|
operation(event, subscriber) {
|
|
@@ -178,9 +173,8 @@ export class BackendiumWebSocket {
|
|
|
178
173
|
this.socket.send(data);
|
|
179
174
|
}
|
|
180
175
|
send(data) {
|
|
181
|
-
var _a;
|
|
182
176
|
this._send(data);
|
|
183
|
-
if (
|
|
177
|
+
if (this.app.config.logging?.fullWs)
|
|
184
178
|
this.app.logger.wsOutputFull(this.url, data);
|
|
185
179
|
else
|
|
186
180
|
this.app.logger.wsOutput(this.url);
|
|
@@ -189,10 +183,9 @@ export class BackendiumWebSocket {
|
|
|
189
183
|
return typeof data === "string" ? data : data instanceof Buffer ? data.toString() : data === undefined ? "undefined" : (typeof data === "number" && isNaN(data)) ? "NaN" : JSON.stringify(data);
|
|
190
184
|
}
|
|
191
185
|
emit(event, payload) {
|
|
192
|
-
var _a;
|
|
193
186
|
BackendiumWebSocket.eventNameCheck(event);
|
|
194
187
|
this._send(`$${event}\n${BackendiumWebSocket.AnyToString(payload)}`);
|
|
195
|
-
if (
|
|
188
|
+
if (this.app.config.logging?.fullWs)
|
|
196
189
|
this.app.logger.wsOutgoingEventFull(this.url, event, payload);
|
|
197
190
|
else
|
|
198
191
|
this.app.logger.wsOutgoingEvent(this.url, event);
|
|
@@ -226,50 +219,47 @@ function parse(data, validator) {
|
|
|
226
219
|
}
|
|
227
220
|
}
|
|
228
221
|
export class WebSocketRouteConstructor {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
222
|
+
sockets = [];
|
|
223
|
+
eventEmitter = new EventEmitter;
|
|
224
|
+
acceptRejectFn;
|
|
225
|
+
eventHandlers = [];
|
|
226
|
+
operations = new EventEmitter;
|
|
227
|
+
initRequired = false;
|
|
236
228
|
_backendiumWebsocket(socket, app, initData, url) {
|
|
237
229
|
let backendiumSocket = new BackendiumWebSocket(socket, this, app, initData, url);
|
|
238
230
|
// @ts-ignore
|
|
239
231
|
this.eventHandlers.forEach(([event, socket, validator]) => backendiumSocket.event(event, socket, validator));
|
|
240
232
|
}
|
|
241
|
-
_handle(request, response, next, app) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
let socket = yield response.accept();
|
|
253
|
-
app.logger.wsConnected(request.originalUrl);
|
|
254
|
-
if (this.initRequired) {
|
|
255
|
-
socket.once("message", (data) => {
|
|
256
|
-
this.eventEmitter.emit("init", [socket, BackendiumWebSocket.rawDataParse(data), app, request.originalUrl]);
|
|
257
|
-
});
|
|
233
|
+
async _handle(request, response, next, app) {
|
|
234
|
+
if (this.acceptRejectFn) {
|
|
235
|
+
let [flag, code, message] = await this.acceptRejectFn(request, response, app);
|
|
236
|
+
if (!flag) {
|
|
237
|
+
response.reject(code, message);
|
|
238
|
+
app.logger.wsRejected(request.originalUrl);
|
|
239
|
+
this.eventEmitter.emit("reject", [request, response, app, code, message]);
|
|
240
|
+
return;
|
|
258
241
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
242
|
+
}
|
|
243
|
+
let socket = await response.accept();
|
|
244
|
+
app.logger.wsConnected(request.originalUrl);
|
|
245
|
+
if (this.initRequired) {
|
|
246
|
+
socket.once("message", (data) => {
|
|
247
|
+
this.eventEmitter.emit("init", [socket, BackendiumWebSocket.rawDataParse(data), app, request.originalUrl]);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
else
|
|
252
|
+
this._backendiumWebsocket(socket, app, undefined, request.originalUrl);
|
|
263
253
|
}
|
|
264
254
|
acceptReject(callback) {
|
|
265
|
-
this.acceptRejectFn = (request, response, app) =>
|
|
255
|
+
this.acceptRejectFn = async (request, response, app) => {
|
|
266
256
|
let ans = callback(request, response, app), data;
|
|
267
257
|
if (ans instanceof Promise)
|
|
268
|
-
data =
|
|
258
|
+
data = await ans;
|
|
269
259
|
else
|
|
270
260
|
data = ans;
|
|
271
261
|
return typeof data === "boolean" ? [data, undefined, undefined] : [false, data[0], data[1]];
|
|
272
|
-
}
|
|
262
|
+
};
|
|
273
263
|
return this;
|
|
274
264
|
}
|
|
275
265
|
event(event, callback, validator) {
|
|
@@ -303,12 +293,11 @@ export class WebSocketRouteConstructor {
|
|
|
303
293
|
}
|
|
304
294
|
requireInit(callback, validator) {
|
|
305
295
|
this.initRequired = true;
|
|
306
|
-
this.on("init", (socket, data, app, url) =>
|
|
307
|
-
var _a, _b, _c;
|
|
296
|
+
this.on("init", async (socket, data, app, url) => {
|
|
308
297
|
let [mainData, parsed] = validator ? parse(data, validator) : [data, true];
|
|
309
298
|
if (!parsed || !mainData) {
|
|
310
299
|
this.eventEmitter.emit("initParsingFailed", [data, socket, app, validator]);
|
|
311
|
-
if (
|
|
300
|
+
if (app.config.logging?.fullWs)
|
|
312
301
|
app.logger.wsInitFailedFull(url, data);
|
|
313
302
|
else
|
|
314
303
|
app.logger.wsInitFailed(url);
|
|
@@ -317,9 +306,9 @@ export class WebSocketRouteConstructor {
|
|
|
317
306
|
// @ts-ignore
|
|
318
307
|
let ret = callback(socket, mainData, app);
|
|
319
308
|
if (ret instanceof Promise)
|
|
320
|
-
ret =
|
|
309
|
+
ret = await ret;
|
|
321
310
|
if (ret !== null) {
|
|
322
|
-
if (
|
|
311
|
+
if (app.config.logging?.fullWs)
|
|
323
312
|
app.logger.wsInitFull(url, mainData);
|
|
324
313
|
else
|
|
325
314
|
app.logger.wsInit(url);
|
|
@@ -327,12 +316,12 @@ export class WebSocketRouteConstructor {
|
|
|
327
316
|
}
|
|
328
317
|
else {
|
|
329
318
|
this.eventEmitter.emit("initFailed", [data, socket, app]);
|
|
330
|
-
if (
|
|
319
|
+
if (app.config.logging?.fullWs)
|
|
331
320
|
app.logger.wsInitFailedFull(url, mainData);
|
|
332
321
|
else
|
|
333
322
|
app.logger.wsInitFailed(url);
|
|
334
323
|
}
|
|
335
|
-
})
|
|
324
|
+
});
|
|
336
325
|
return this;
|
|
337
326
|
}
|
|
338
327
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backendium",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Express-based javascript backend framework with websocket support
|
|
3
|
+
"version": "0.0.17",
|
|
4
|
+
"description": "Express-based javascript backend framework with websocket support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"chalk": "^5.3.0",
|
|
13
13
|
"event-emitter-typescript": "^2.1.1",
|
|
14
14
|
"express": "^4.21.0",
|
|
15
|
+
"parsium": "^0.0.3",
|
|
15
16
|
"websocket-express": "^3.1.1",
|
|
16
17
|
"ws": "^8.18.0"
|
|
17
18
|
},
|
|
@@ -25,4 +26,4 @@
|
|
|
25
26
|
},
|
|
26
27
|
"files": ["src", "dist", "package.json", "readme.md", "tsconfig.json"],
|
|
27
28
|
"type": "module"
|
|
28
|
-
}
|
|
29
|
+
}
|
package/readme.md
CHANGED
|
@@ -149,7 +149,7 @@ router.setAuth((request, response) => {
|
|
|
149
149
|
});
|
|
150
150
|
|
|
151
151
|
router.post("/auth", (request, response) => {
|
|
152
|
-
console.log(request.globalAuth); // type of request.
|
|
152
|
+
console.log(request.globalAuth); // type of request.globalAuth is string
|
|
153
153
|
response.end();
|
|
154
154
|
}, {
|
|
155
155
|
auth: true
|
package/src/handler.ts
CHANGED
|
@@ -3,7 +3,7 @@ import Backendium from "./index.js";
|
|
|
3
3
|
import {NextFunction, Request, RequestHandler, Response} from "express";
|
|
4
4
|
import parseRequest, {BackendiumRequestOptionsType, BackendiumRequestType} from "./request.js";
|
|
5
5
|
import {BackendiumRouter} from "./router.js";
|
|
6
|
-
import {
|
|
6
|
+
import {ParsingError} from "parsium";
|
|
7
7
|
|
|
8
8
|
export type BackendiumHandlerReturnType = void | undefined | {code?: number, next?: boolean};
|
|
9
9
|
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>;
|
|
@@ -21,7 +21,7 @@ export function defaultErrorHandler(request: Request, response: BackendiumRespon
|
|
|
21
21
|
app.logger.requestError(request.url, data, error);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export function defaultValidationErrorHandler(request: Request, response: BackendiumResponse, app: Backendium,
|
|
24
|
+
export function defaultValidationErrorHandler(request: Request, response: BackendiumResponse, app: Backendium, error: ParsingError, message: string) {
|
|
25
25
|
response.status(400);
|
|
26
26
|
response.end(message ?? "Validation failed: " + error.message);
|
|
27
27
|
}
|
|
@@ -34,16 +34,14 @@ export default function backendiumHandler<BodyType, ParamsType, QueryType, AuthT
|
|
|
34
34
|
try {
|
|
35
35
|
let req = await parseRequest(request, app, {...options, auth, authChecker, authFailed, errorHandler, validationErrorHandler, errorMessage, validationErrorMessage});
|
|
36
36
|
let res = new BackendiumResponse(response, app);
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
(
|
|
40
|
-
if (app.config.logging?.fullRequest) app.logger.requestFull(request.url, res.lastStatus, data, res.lastResponse);
|
|
37
|
+
if (req instanceof ParsingError) {
|
|
38
|
+
(validationErrorHandler ?? app.config.validationErrorHandler ?? defaultValidationErrorHandler)(request, res, app, req, validationErrorMessage ?? app.config.validationErrorMessage);
|
|
39
|
+
if (app.config.logging?.fullRequest) app.logger.requestFull(request.url, res.lastStatus, '"<invalid>"', res.lastResponse);
|
|
41
40
|
else app.logger.request(request.url, res.lastStatus);
|
|
42
41
|
return;
|
|
43
42
|
}
|
|
44
43
|
body = req.body;
|
|
45
|
-
|
|
46
|
-
let authData: AuthType = undefined;
|
|
44
|
+
let authData: AuthType = undefined as unknown as AuthType;
|
|
47
45
|
if (authChecker) {
|
|
48
46
|
let ret = authChecker(request, res, app);
|
|
49
47
|
if (ret instanceof Promise) ret = await ret;
|
|
@@ -55,8 +53,7 @@ export default function backendiumHandler<BodyType, ParamsType, QueryType, AuthT
|
|
|
55
53
|
}
|
|
56
54
|
authData = ret;
|
|
57
55
|
}
|
|
58
|
-
|
|
59
|
-
let globalAuthData: GlobalAuthType = undefined;
|
|
56
|
+
let globalAuthData: GlobalAuthType = undefined as unknown as GlobalAuthType;
|
|
60
57
|
if (!authChecker && auth && router.authChecker) {
|
|
61
58
|
let ret = router.authChecker(request, res, app);
|
|
62
59
|
if (ret instanceof Promise) ret = await ret;
|
|
@@ -87,7 +84,9 @@ export default function backendiumHandler<BodyType, ParamsType, QueryType, AuthT
|
|
|
87
84
|
else app.logger.request(request.url, res.lastStatus);
|
|
88
85
|
}
|
|
89
86
|
catch (error) {
|
|
90
|
-
(errorHandler ?? app.config.errorHandler ?? defaultErrorHandler)(request, new BackendiumResponse(response, app), body, app,
|
|
87
|
+
(errorHandler ?? app.config.errorHandler ?? defaultErrorHandler)(request, new BackendiumResponse(response, app), body, app, error, errorMessage ?? app.config.errorMessage);
|
|
91
88
|
}
|
|
92
89
|
});
|
|
93
|
-
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// @TODO save some body chunks from parsium for logging
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {EventEmitter, EventKey} from "event-emitter-typescript";
|
|
|
5
5
|
import {WebSocketExpress, WSRequestHandler} from "websocket-express";
|
|
6
6
|
import {BackendiumWebSocket} from "./ws.js";
|
|
7
7
|
import Logger from "./logger.js";
|
|
8
|
-
import BackendiumResponse from "./response
|
|
8
|
+
import BackendiumResponse from "./response";
|
|
9
9
|
import {ValidationError} from "checkeasy";
|
|
10
10
|
import type {MethodType} from "./httpRouter.js";
|
|
11
11
|
|
|
@@ -27,7 +27,7 @@ export type BackendiumConfigType = {
|
|
|
27
27
|
errorMessage: string,
|
|
28
28
|
errorHandler(request: Request, response: BackendiumResponse, data: any, app: Backendium, error: any, message?: string): void,
|
|
29
29
|
validationErrorMessage: string,
|
|
30
|
-
validationErrorHandler(request: Request, response: BackendiumResponse, app: Backendium,
|
|
30
|
+
validationErrorHandler(request: Request, response: BackendiumResponse, app: Backendium, error: ValidationError, message?: string): void,
|
|
31
31
|
wsErrorMessage: string,
|
|
32
32
|
wsErrorHandler(data: Buffer, connection: BackendiumWebSocket<any>, app: Backendium, error: any): void
|
|
33
33
|
}
|
package/src/request.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {Request} from "express";
|
|
2
2
|
import Backendium from "./index.js";
|
|
3
|
-
import {
|
|
4
|
-
import BackendiumResponse from "./response";
|
|
3
|
+
import {any, Parser, ParsingError} from "parsium";
|
|
4
|
+
import BackendiumResponse from "./response.js";
|
|
5
5
|
|
|
6
6
|
export type ValidatorsType<BodyType, ParamsType, QueryType, HeadersType> = {
|
|
7
|
-
bodyValidator?:
|
|
8
|
-
paramsValidator?:
|
|
9
|
-
queryValidator?:
|
|
10
|
-
headersValidator?:
|
|
7
|
+
bodyValidator?: Parser<BodyType>,
|
|
8
|
+
paramsValidator?: Parser<ParamsType>,
|
|
9
|
+
queryValidator?: Parser<QueryType>,
|
|
10
|
+
headersValidator?: Parser<HeadersType>
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export type AuthCheckerType<AuthType> = (request: Request, response: BackendiumResponse, app: Backendium) => AuthType | null | Promise<AuthType | null>;
|
|
@@ -20,7 +20,7 @@ export type BackendiumRequestOptionsType<BodyType, ParamsType, QueryType, AuthTy
|
|
|
20
20
|
errorMessage?: string,
|
|
21
21
|
errorHandler?(request: Request, response: BackendiumResponse, data: any, app: Backendium, error: any): void,
|
|
22
22
|
validationErrorMessage?: string,
|
|
23
|
-
validationErrorHandler?(request: Request, response: BackendiumResponse, app: Backendium,
|
|
23
|
+
validationErrorHandler?(request: Request, response: BackendiumResponse, app: Backendium, error: ParsingError, message?: string): void
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export type BackendiumRequestType<BodyType, ParamsType, QueryType, AuthType, HeadersType, DefaultAuthType> = {
|
|
@@ -29,14 +29,13 @@ export type BackendiumRequestType<BodyType, ParamsType, QueryType, AuthType, Hea
|
|
|
29
29
|
params: ParamsType,
|
|
30
30
|
query: QueryType,
|
|
31
31
|
headers: HeadersType,
|
|
32
|
-
bodyBuffer: Buffer,
|
|
33
32
|
options: BackendiumRequestOptionsType<BodyType, ParamsType, QueryType, AuthType, HeadersType>,
|
|
34
33
|
app: Backendium,
|
|
35
34
|
auth: AuthType,
|
|
36
35
|
globalAuth: DefaultAuthType
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
function parse<Type>(data: Buffer | object, validator?:
|
|
38
|
+
function parse<Type>(data: Buffer | object, validator?: Parser<Type>, root: string = ""): Type {
|
|
40
39
|
if (!validator) {
|
|
41
40
|
// @ts-ignore
|
|
42
41
|
return data;
|
|
@@ -50,7 +49,7 @@ function parse<Type>(data: Buffer | object, validator?: Validator<Type>, root: s
|
|
|
50
49
|
return validator(JSON.parse(data.toString()), root);
|
|
51
50
|
}
|
|
52
51
|
catch (error) {
|
|
53
|
-
if (error instanceof
|
|
52
|
+
if (error instanceof ParsingError) throw error;
|
|
54
53
|
throw error0;
|
|
55
54
|
}
|
|
56
55
|
}
|
|
@@ -72,20 +71,24 @@ async function getBody(request: Request): Promise<Buffer> {
|
|
|
72
71
|
|
|
73
72
|
export default async function parseRequest<BodyType, ParamsType, QueryType, AuthType, HeadersType>(request: Request, app: Backendium,
|
|
74
73
|
{bodyValidator, paramsValidator, queryValidator, headersValidator, ...other}: BackendiumRequestOptionsType<BodyType, ParamsType, QueryType, AuthType, HeadersType>
|
|
75
|
-
): Promise<Omit<Omit<BackendiumRequestType<BodyType, ParamsType, QueryType, AuthType, HeadersType, any>, "auth">, "globalAuth"> |
|
|
76
|
-
let bodyBuffer = await getBody(request);
|
|
74
|
+
): Promise<Omit<Omit<BackendiumRequestType<BodyType, ParamsType, QueryType, AuthType, HeadersType, any>, "auth">, "globalAuth"> | ParsingError> {
|
|
75
|
+
// let bodyBuffer = await getBody(request);
|
|
77
76
|
try {
|
|
78
|
-
let body = parse(bodyBuffer, bodyValidator, "body");
|
|
79
|
-
let params = parse(request.params, paramsValidator, "params");
|
|
80
|
-
let query = parse(request.query, queryValidator, "query");
|
|
81
|
-
let headers = parse(request.headers, headersValidator, "headers");
|
|
77
|
+
// let body = parse(bodyBuffer, bodyValidator, "body");
|
|
78
|
+
// let params = parse(request.params, paramsValidator, "params");
|
|
79
|
+
// let query = parse(request.query, queryValidator, "query");
|
|
80
|
+
// let headers = parse(request.headers, headersValidator, "headers");
|
|
81
|
+
let body = await (bodyValidator ?? any<BodyType>()).stream(request, "body");
|
|
82
|
+
let params = (paramsValidator ?? any<ParamsType>())(request.params, "params");
|
|
83
|
+
let query = (queryValidator ?? any<QueryType>())(request.query, "query");
|
|
84
|
+
let headers = (headersValidator ?? any<HeadersType>())(request.headers, "headers");
|
|
82
85
|
return {
|
|
83
|
-
expressRequest: request, body, params, query, headers,
|
|
86
|
+
expressRequest: request, body, params, query, headers, app,
|
|
84
87
|
options: {bodyValidator, paramsValidator, queryValidator, headersValidator, ...other}
|
|
85
88
|
};
|
|
86
89
|
}
|
|
87
90
|
catch (error) {
|
|
88
|
-
if (error instanceof
|
|
89
|
-
|
|
91
|
+
//if (error instanceof ParsingError) return error;
|
|
92
|
+
return error as ParsingError;
|
|
90
93
|
}
|
|
91
|
-
}
|
|
94
|
+
}
|
package/src/ws.ts
CHANGED
|
@@ -50,6 +50,7 @@ export class BackendiumWebSocket<InitDataType> {
|
|
|
50
50
|
protected useEvents = false;
|
|
51
51
|
|
|
52
52
|
public static rawDataParse(data: WebSocket.RawData): Buffer {
|
|
53
|
+
// @ts-ignore
|
|
53
54
|
return data instanceof Buffer ? data : data instanceof ArrayBuffer ? Buffer.from(data) : data.reduce((prev, cur) => Buffer.concat([prev, cur]), Buffer.alloc(0));
|
|
54
55
|
}
|
|
55
56
|
|