backendium 0.0.15 → 0.0.16
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 +32 -53
- package/dist/response.js +4 -1
- package/dist/router.js +7 -8
- package/dist/ws.js +52 -64
- package/package.json +3 -2
- package/readme.md +1 -1
- package/src/handler.ts +11 -12
- package/src/index.ts +2 -2
- package/src/request.ts +21 -18
- 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,37 @@ 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)
|
|
54
|
+
return error;
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
78
57
|
}
|
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,15 +1,16 @@
|
|
|
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) {
|
|
14
15
|
return data instanceof Buffer ? data : data instanceof ArrayBuffer ? Buffer.from(data) : data.reduce((prev, cur) => Buffer.concat([prev, cur]), Buffer.alloc(0));
|
|
15
16
|
}
|
|
@@ -37,11 +38,10 @@ export class BackendiumWebSocket {
|
|
|
37
38
|
this.operations.emit(operation, [payload, operationConfig, socket, app]);
|
|
38
39
|
}
|
|
39
40
|
parseEventMessage(message, socket, app, isBinary) {
|
|
40
|
-
var _a, _b, _c, _d;
|
|
41
41
|
if (isBinary) {
|
|
42
42
|
this.eventEmitter.emit("notEventMessage", [message, socket, app, isBinary]);
|
|
43
43
|
this.wsConstructor.eventEmitter.emit("notEventMessage", [message, socket, app, isBinary]);
|
|
44
|
-
if (
|
|
44
|
+
if (app.config.logging?.fullWs)
|
|
45
45
|
app.logger.wsInputFull(this.url, message);
|
|
46
46
|
else
|
|
47
47
|
app.logger.wsInput(this.url);
|
|
@@ -51,7 +51,7 @@ export class BackendiumWebSocket {
|
|
|
51
51
|
let [head_, ...data] = message.toString().split("\n");
|
|
52
52
|
let payload = Buffer.from(data.join("\n")), head = this.parseEventHead(head_, message, socket, app);
|
|
53
53
|
if (!head) {
|
|
54
|
-
if (
|
|
54
|
+
if (app.config.logging?.fullWs)
|
|
55
55
|
app.logger.wsInputFull(this.url, message);
|
|
56
56
|
else
|
|
57
57
|
app.logger.wsInput(this.url);
|
|
@@ -59,7 +59,7 @@ export class BackendiumWebSocket {
|
|
|
59
59
|
}
|
|
60
60
|
if ("event" in head) {
|
|
61
61
|
this.emitIncomingEvent(head.event, payload, socket, app, head);
|
|
62
|
-
if (
|
|
62
|
+
if (app.config.logging?.fullWs)
|
|
63
63
|
app.logger.wsIncomingEventFull(this.url, head.event, payload.length ? payload : null);
|
|
64
64
|
else
|
|
65
65
|
app.logger.wsIncomingEvent(this.url, head.event);
|
|
@@ -70,7 +70,7 @@ export class BackendiumWebSocket {
|
|
|
70
70
|
catch (error) {
|
|
71
71
|
this.eventEmitter.emit("notEventMessage", [message, socket, app, isBinary]);
|
|
72
72
|
this.wsConstructor.eventEmitter.emit("notEventMessage", [message, socket, app, isBinary]);
|
|
73
|
-
if (
|
|
73
|
+
if (app.config.logging?.fullWs)
|
|
74
74
|
app.logger.wsInputFull(this.url, message);
|
|
75
75
|
else
|
|
76
76
|
app.logger.wsInput(this.url);
|
|
@@ -83,15 +83,9 @@ export class BackendiumWebSocket {
|
|
|
83
83
|
this.app = app;
|
|
84
84
|
this.initData = initData;
|
|
85
85
|
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
86
|
this.eventEmitter.emit("accept", [this, this.wsConstructor, app]);
|
|
92
87
|
this.wsConstructor.eventEmitter.emit("accept", [this, this.wsConstructor, app]);
|
|
93
88
|
socket.on("message", (data, isBinary) => {
|
|
94
|
-
var _a;
|
|
95
89
|
let buffer = BackendiumWebSocket.rawDataParse(data);
|
|
96
90
|
if (this.useEvents) {
|
|
97
91
|
this.eventEmitter.emit("messageBeforeEvents", [buffer, this, app, isBinary]);
|
|
@@ -101,7 +95,7 @@ export class BackendiumWebSocket {
|
|
|
101
95
|
else {
|
|
102
96
|
this.eventEmitter.emit("notEventMessage", [buffer, this, app, isBinary]);
|
|
103
97
|
this.wsConstructor.eventEmitter.emit("notEventMessage", [buffer, this, app, isBinary]);
|
|
104
|
-
if (
|
|
98
|
+
if (app.config.logging?.fullWs)
|
|
105
99
|
app.logger.wsInputFull(url, data);
|
|
106
100
|
else
|
|
107
101
|
app.logger.wsInput(url);
|
|
@@ -152,7 +146,7 @@ export class BackendiumWebSocket {
|
|
|
152
146
|
return;
|
|
153
147
|
}
|
|
154
148
|
// @ts-ignore
|
|
155
|
-
callback(mainData, socket, app, validator
|
|
149
|
+
callback(mainData, socket, app, validator ?? bufferValidator);
|
|
156
150
|
});
|
|
157
151
|
}
|
|
158
152
|
operation(event, subscriber) {
|
|
@@ -178,9 +172,8 @@ export class BackendiumWebSocket {
|
|
|
178
172
|
this.socket.send(data);
|
|
179
173
|
}
|
|
180
174
|
send(data) {
|
|
181
|
-
var _a;
|
|
182
175
|
this._send(data);
|
|
183
|
-
if (
|
|
176
|
+
if (this.app.config.logging?.fullWs)
|
|
184
177
|
this.app.logger.wsOutputFull(this.url, data);
|
|
185
178
|
else
|
|
186
179
|
this.app.logger.wsOutput(this.url);
|
|
@@ -189,10 +182,9 @@ export class BackendiumWebSocket {
|
|
|
189
182
|
return typeof data === "string" ? data : data instanceof Buffer ? data.toString() : data === undefined ? "undefined" : (typeof data === "number" && isNaN(data)) ? "NaN" : JSON.stringify(data);
|
|
190
183
|
}
|
|
191
184
|
emit(event, payload) {
|
|
192
|
-
var _a;
|
|
193
185
|
BackendiumWebSocket.eventNameCheck(event);
|
|
194
186
|
this._send(`$${event}\n${BackendiumWebSocket.AnyToString(payload)}`);
|
|
195
|
-
if (
|
|
187
|
+
if (this.app.config.logging?.fullWs)
|
|
196
188
|
this.app.logger.wsOutgoingEventFull(this.url, event, payload);
|
|
197
189
|
else
|
|
198
190
|
this.app.logger.wsOutgoingEvent(this.url, event);
|
|
@@ -226,50 +218,47 @@ function parse(data, validator) {
|
|
|
226
218
|
}
|
|
227
219
|
}
|
|
228
220
|
export class WebSocketRouteConstructor {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
221
|
+
sockets = [];
|
|
222
|
+
eventEmitter = new EventEmitter;
|
|
223
|
+
acceptRejectFn;
|
|
224
|
+
eventHandlers = [];
|
|
225
|
+
operations = new EventEmitter;
|
|
226
|
+
initRequired = false;
|
|
236
227
|
_backendiumWebsocket(socket, app, initData, url) {
|
|
237
228
|
let backendiumSocket = new BackendiumWebSocket(socket, this, app, initData, url);
|
|
238
229
|
// @ts-ignore
|
|
239
230
|
this.eventHandlers.forEach(([event, socket, validator]) => backendiumSocket.event(event, socket, validator));
|
|
240
231
|
}
|
|
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
|
-
});
|
|
232
|
+
async _handle(request, response, next, app) {
|
|
233
|
+
if (this.acceptRejectFn) {
|
|
234
|
+
let [flag, code, message] = await this.acceptRejectFn(request, response, app);
|
|
235
|
+
if (!flag) {
|
|
236
|
+
response.reject(code, message);
|
|
237
|
+
app.logger.wsRejected(request.originalUrl);
|
|
238
|
+
this.eventEmitter.emit("reject", [request, response, app, code, message]);
|
|
239
|
+
return;
|
|
258
240
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
241
|
+
}
|
|
242
|
+
let socket = await response.accept();
|
|
243
|
+
app.logger.wsConnected(request.originalUrl);
|
|
244
|
+
if (this.initRequired) {
|
|
245
|
+
socket.once("message", (data) => {
|
|
246
|
+
this.eventEmitter.emit("init", [socket, BackendiumWebSocket.rawDataParse(data), app, request.originalUrl]);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
// @ts-ignore
|
|
250
|
+
else
|
|
251
|
+
this._backendiumWebsocket(socket, app, undefined, request.originalUrl);
|
|
263
252
|
}
|
|
264
253
|
acceptReject(callback) {
|
|
265
|
-
this.acceptRejectFn = (request, response, app) =>
|
|
254
|
+
this.acceptRejectFn = async (request, response, app) => {
|
|
266
255
|
let ans = callback(request, response, app), data;
|
|
267
256
|
if (ans instanceof Promise)
|
|
268
|
-
data =
|
|
257
|
+
data = await ans;
|
|
269
258
|
else
|
|
270
259
|
data = ans;
|
|
271
260
|
return typeof data === "boolean" ? [data, undefined, undefined] : [false, data[0], data[1]];
|
|
272
|
-
}
|
|
261
|
+
};
|
|
273
262
|
return this;
|
|
274
263
|
}
|
|
275
264
|
event(event, callback, validator) {
|
|
@@ -303,12 +292,11 @@ export class WebSocketRouteConstructor {
|
|
|
303
292
|
}
|
|
304
293
|
requireInit(callback, validator) {
|
|
305
294
|
this.initRequired = true;
|
|
306
|
-
this.on("init", (socket, data, app, url) =>
|
|
307
|
-
var _a, _b, _c;
|
|
295
|
+
this.on("init", async (socket, data, app, url) => {
|
|
308
296
|
let [mainData, parsed] = validator ? parse(data, validator) : [data, true];
|
|
309
297
|
if (!parsed || !mainData) {
|
|
310
298
|
this.eventEmitter.emit("initParsingFailed", [data, socket, app, validator]);
|
|
311
|
-
if (
|
|
299
|
+
if (app.config.logging?.fullWs)
|
|
312
300
|
app.logger.wsInitFailedFull(url, data);
|
|
313
301
|
else
|
|
314
302
|
app.logger.wsInitFailed(url);
|
|
@@ -317,9 +305,9 @@ export class WebSocketRouteConstructor {
|
|
|
317
305
|
// @ts-ignore
|
|
318
306
|
let ret = callback(socket, mainData, app);
|
|
319
307
|
if (ret instanceof Promise)
|
|
320
|
-
ret =
|
|
308
|
+
ret = await ret;
|
|
321
309
|
if (ret !== null) {
|
|
322
|
-
if (
|
|
310
|
+
if (app.config.logging?.fullWs)
|
|
323
311
|
app.logger.wsInitFull(url, mainData);
|
|
324
312
|
else
|
|
325
313
|
app.logger.wsInit(url);
|
|
@@ -327,12 +315,12 @@ export class WebSocketRouteConstructor {
|
|
|
327
315
|
}
|
|
328
316
|
else {
|
|
329
317
|
this.eventEmitter.emit("initFailed", [data, socket, app]);
|
|
330
|
-
if (
|
|
318
|
+
if (app.config.logging?.fullWs)
|
|
331
319
|
app.logger.wsInitFailedFull(url, mainData);
|
|
332
320
|
else
|
|
333
321
|
app.logger.wsInitFailed(url);
|
|
334
322
|
}
|
|
335
|
-
})
|
|
323
|
+
});
|
|
336
324
|
return this;
|
|
337
325
|
}
|
|
338
326
|
}
|
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.16",
|
|
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.2",
|
|
15
16
|
"websocket-express": "^3.1.1",
|
|
16
17
|
"ws": "^8.18.0"
|
|
17
18
|
},
|
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
|
|
91
|
+
if (error instanceof ParsingError) return error;
|
|
89
92
|
throw error;
|
|
90
93
|
}
|
|
91
94
|
}
|