equipped 4.4.6 → 5.0.0-beta-1
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/CHANGELOG.md +25 -0
- package/lib/db/_instance.d.ts +3 -6
- package/lib/db/mongoose/changes.d.ts +2 -1
- package/lib/db/mongoose/index.d.ts +2 -1
- package/lib/db/mongoose/index.js +3 -1
- package/lib/db/mongoose/query.d.ts +1 -0
- package/lib/db/query.d.ts +12 -11
- package/lib/errors/customError.d.ts +0 -1
- package/lib/errors/customError.js +0 -1
- package/lib/errors/index.d.ts +0 -2
- package/lib/errors/index.js +0 -2
- package/lib/errors/types/refreshTokenMisusedError.d.ts +1 -1
- package/lib/errors/types/refreshTokenMisusedError.js +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/instance/index.d.ts +5 -4
- package/lib/instance/index.js +17 -4
- package/lib/instance/settings.d.ts +8 -0
- package/lib/instance/settings.js +7 -1
- package/lib/listeners/emitter.d.ts +3 -3
- package/lib/scripts/index.d.ts +1 -0
- package/lib/scripts/index.js +17 -0
- package/lib/scripts/json-schema.d.ts +2 -0
- package/lib/scripts/json-schema.js +75 -0
- package/lib/server/impls/base.d.ts +37 -0
- package/lib/server/impls/base.js +120 -0
- package/lib/server/impls/express.d.ts +16 -0
- package/lib/server/impls/express.js +183 -0
- package/lib/server/impls/fastify.d.ts +23 -0
- package/lib/server/impls/fastify.js +182 -0
- package/lib/server/index.d.ts +7 -6
- package/lib/server/index.js +10 -8
- package/lib/server/middlewares/errorHandler.d.ts +4 -1
- package/lib/server/middlewares/errorHandler.js +10 -11
- package/lib/server/middlewares/index.d.ts +1 -0
- package/lib/server/middlewares/index.js +1 -0
- package/lib/server/middlewares/notFoundHandler.d.ts +4 -1
- package/lib/server/middlewares/notFoundHandler.js +3 -3
- package/lib/server/middlewares/parseAuthUser.d.ts +4 -1
- package/lib/server/middlewares/parseAuthUser.js +2 -2
- package/lib/server/middlewares/requireAuthUser.d.ts +4 -2
- package/lib/server/middlewares/requireAuthUser.js +8 -3
- package/lib/server/middlewares/requireRefreshUser.d.ts +4 -2
- package/lib/server/middlewares/requireRefreshUser.js +7 -4
- package/lib/server/requests.d.ts +50 -0
- package/lib/server/requests.js +60 -0
- package/lib/server/routes.d.ts +6 -23
- package/lib/server/routes.js +39 -49
- package/lib/server/types.d.ts +85 -0
- package/lib/server/types.js +33 -0
- package/lib/structure/baseEntity.d.ts +4 -5
- package/lib/structure/baseEntity.js +20 -12
- package/lib/types/index.d.ts +20 -0
- package/lib/types/index.js +2 -0
- package/package.json +36 -22
- package/lib/errors/types/accountNotVerifiedError.d.ts +0 -5
- package/lib/errors/types/accountNotVerifiedError.js +0 -12
- package/lib/errors/types/invalidToken.d.ts +0 -5
- package/lib/errors/types/invalidToken.js +0 -12
- package/lib/logger/index.d.ts +0 -13
- package/lib/logger/index.js +0 -41
- package/lib/server/app.d.ts +0 -12
- package/lib/server/app.js +0 -121
- package/lib/server/controllers/index.d.ts +0 -10
- package/lib/server/controllers/index.js +0 -46
- package/lib/server/controllers/request.d.ts +0 -40
- package/lib/server/controllers/request.js +0 -85
- package/lib/server/controllers/response.d.ts +0 -14
- package/lib/server/controllers/response.js +0 -16
- package/lib/server/statusCodes.d.ts +0 -16
- package/lib/server/statusCodes.js +0 -17
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { Defined } from '../../types';
|
|
3
|
+
import { Request, Response } from '../requests';
|
|
4
|
+
import { Route } from '../types';
|
|
5
|
+
import { FullRoute, Server } from './base';
|
|
6
|
+
export declare class ExpressServer extends Server<express.Request, express.Response> {
|
|
7
|
+
#private;
|
|
8
|
+
constructor();
|
|
9
|
+
protected registerRoute(route: FullRoute): void;
|
|
10
|
+
protected startServer(port: number): Promise<boolean>;
|
|
11
|
+
protected onLoad(): Promise<void>;
|
|
12
|
+
protected parse(req: express.Request, res: express.Response): Promise<any>;
|
|
13
|
+
makeController(cb: Defined<Route['handler']>): (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void>;
|
|
14
|
+
makeMiddleware(cb: Defined<Route['middlewares']>[number]['cb']): (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void>;
|
|
15
|
+
makeErrorMiddleware(cb: Defined<Route['onError']>['cb']): (err: Error, req: express.Request, res: express.Response, _next: express.NextFunction) => Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
var _ExpressServer_expressApp, _ExpressServer_oapi, _ExpressServer_ref;
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.ExpressServer = void 0;
|
|
19
|
+
const utils_1 = require("@fastify/swagger/lib/spec/openapi/utils");
|
|
20
|
+
const openapi_1 = __importDefault(require("@wesleytodd/openapi"));
|
|
21
|
+
const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
22
|
+
const cors_1 = __importDefault(require("cors"));
|
|
23
|
+
const express_1 = __importDefault(require("express"));
|
|
24
|
+
const express_fileupload_1 = __importDefault(require("express-fileupload"));
|
|
25
|
+
const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
|
|
26
|
+
const express_slow_down_1 = __importDefault(require("express-slow-down"));
|
|
27
|
+
const helmet_1 = __importDefault(require("helmet"));
|
|
28
|
+
const http_1 = __importDefault(require("http"));
|
|
29
|
+
const json_schema_resolver_1 = __importDefault(require("json-schema-resolver"));
|
|
30
|
+
const pino_http_1 = require("pino-http");
|
|
31
|
+
const errors_1 = require("../../errors");
|
|
32
|
+
const exit_1 = require("../../exit");
|
|
33
|
+
const instance_1 = require("../../instance");
|
|
34
|
+
const media_1 = require("../../utils/media");
|
|
35
|
+
const middlewares_1 = require("../middlewares");
|
|
36
|
+
const requests_1 = require("../requests");
|
|
37
|
+
const types_1 = require("../types");
|
|
38
|
+
const base_1 = require("./base");
|
|
39
|
+
class ExpressServer extends base_1.Server {
|
|
40
|
+
constructor() {
|
|
41
|
+
const app = (0, express_1.default)();
|
|
42
|
+
super(http_1.default.createServer(app));
|
|
43
|
+
_ExpressServer_expressApp.set(this, void 0);
|
|
44
|
+
_ExpressServer_oapi.set(this, (0, openapi_1.default)(`${this.settings.openapiDocsUrl}/json`, this.baseOpenapiDoc, { coerce: false }));
|
|
45
|
+
_ExpressServer_ref.set(this, (0, json_schema_resolver_1.default)({ clone: true }));
|
|
46
|
+
__classPrivateFieldSet(this, _ExpressServer_expressApp, app, "f");
|
|
47
|
+
app.disable('x-powered-by');
|
|
48
|
+
if (this.settings.logRequests)
|
|
49
|
+
app.use((0, pino_http_1.pinoHttp)({ logger: instance_1.Instance.get().logger }));
|
|
50
|
+
app.use(express_1.default.json());
|
|
51
|
+
app.use(express_1.default.text());
|
|
52
|
+
app.use((0, cookie_parser_1.default)());
|
|
53
|
+
app.use(helmet_1.default.crossOriginResourcePolicy({ policy: 'cross-origin' }));
|
|
54
|
+
app.use((0, cors_1.default)({ origin: '*' }));
|
|
55
|
+
app.use(express_1.default.urlencoded({ extended: false }));
|
|
56
|
+
app.use(express_1.default.static(this.staticPath));
|
|
57
|
+
app.use(__classPrivateFieldGet(this, _ExpressServer_oapi, "f"));
|
|
58
|
+
app.use(this.settings.openapiDocsUrl, __classPrivateFieldGet(this, _ExpressServer_oapi, "f").swaggerui());
|
|
59
|
+
app.use((0, express_fileupload_1.default)({
|
|
60
|
+
limits: { fileSize: this.settings.maxFileUploadSizeInMb * 1024 * 1024 },
|
|
61
|
+
useTempFiles: false
|
|
62
|
+
}));
|
|
63
|
+
if (this.settings.useRateLimit)
|
|
64
|
+
app.use((0, express_rate_limit_1.default)({
|
|
65
|
+
windowMs: this.settings.rateLimitPeriodInMs,
|
|
66
|
+
limit: this.settings.rateLimit,
|
|
67
|
+
handler: (_, res) => res.status(types_1.StatusCodes.TooManyRequests).json([{ message: 'Too Many Requests' }])
|
|
68
|
+
}));
|
|
69
|
+
if (this.settings.useSlowDown)
|
|
70
|
+
app.use((0, express_slow_down_1.default)({
|
|
71
|
+
windowMs: this.settings.slowDownPeriodInMs,
|
|
72
|
+
delayAfter: this.settings.slowDownAfter,
|
|
73
|
+
delayMs: this.settings.slowDownDelayInMs
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
registerRoute(route) {
|
|
77
|
+
const openapi = (0, utils_1.prepareOpenapiMethod)(route.schema, __classPrivateFieldGet(this, _ExpressServer_ref, "f"), this.baseOpenapiDoc, route.path);
|
|
78
|
+
const controllers = [
|
|
79
|
+
...route.middlewares.map((m) => this.makeMiddleware(m.cb)),
|
|
80
|
+
this.makeController(route.handler)
|
|
81
|
+
];
|
|
82
|
+
if (!route.schema.hide)
|
|
83
|
+
controllers.unshift(__classPrivateFieldGet(this, _ExpressServer_oapi, "f")[this.settings.requestSchemaValidation ? 'validPath' : 'path'](openapi), (error, _, __, next) => {
|
|
84
|
+
if ('validationErrors' in error) {
|
|
85
|
+
const validationErrors = error.validationErrors;
|
|
86
|
+
throw new errors_1.ValidationError(validationErrors.map((error) => ({
|
|
87
|
+
messages: [error.message ?? ''],
|
|
88
|
+
field: error.instancePath.replaceAll('/', '.').split('.').filter(Boolean).join('.')
|
|
89
|
+
})));
|
|
90
|
+
}
|
|
91
|
+
next();
|
|
92
|
+
});
|
|
93
|
+
if (route.onError)
|
|
94
|
+
controllers.push(this.makeErrorMiddleware(route.onError.cb));
|
|
95
|
+
__classPrivateFieldGet(this, _ExpressServer_expressApp, "f")[route.method]?.(route.path, ...controllers);
|
|
96
|
+
}
|
|
97
|
+
async startServer(port) {
|
|
98
|
+
__classPrivateFieldGet(this, _ExpressServer_expressApp, "f").use(this.makeMiddleware(middlewares_1.notFoundHandler.cb));
|
|
99
|
+
__classPrivateFieldGet(this, _ExpressServer_expressApp, "f").use(this.makeErrorMiddleware(middlewares_1.errorHandler.cb));
|
|
100
|
+
return await new Promise((resolve, reject) => {
|
|
101
|
+
try {
|
|
102
|
+
const app = this.server.listen(port, async () => resolve(true));
|
|
103
|
+
(0, exit_1.addWaitBeforeExit)(app.close);
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
reject(err);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async onLoad() { }
|
|
111
|
+
async parse(req, res) {
|
|
112
|
+
const allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]));
|
|
113
|
+
const headers = {
|
|
114
|
+
...allHeaders,
|
|
115
|
+
AccessToken: req.get('Access-Token') ?? null,
|
|
116
|
+
RefreshToken: req.get('Refresh-Token') ?? null,
|
|
117
|
+
ContentType: req.get('Content-Type') ?? null,
|
|
118
|
+
Referer: req.get('referer') ?? null,
|
|
119
|
+
UserAgent: req.get('User-Agent') ?? null
|
|
120
|
+
};
|
|
121
|
+
const files = Object.fromEntries(await Promise.all(Object.entries(req.files ?? {}).map(async ([key, file]) => {
|
|
122
|
+
const uploads = Array.isArray(file) ? file : [file];
|
|
123
|
+
const fileArray = await Promise.all(uploads.map(async (f) => ({
|
|
124
|
+
name: f.name,
|
|
125
|
+
type: f.mimetype,
|
|
126
|
+
size: f.size,
|
|
127
|
+
isTruncated: f.truncated,
|
|
128
|
+
data: f.data,
|
|
129
|
+
duration: await (0, media_1.getMediaDuration)(f.data),
|
|
130
|
+
})));
|
|
131
|
+
return [key, fileArray];
|
|
132
|
+
})));
|
|
133
|
+
return req.savedReq || (req.savedReq = new requests_1.Request({
|
|
134
|
+
ip: req.ip,
|
|
135
|
+
body: req.body ?? {},
|
|
136
|
+
cookies: req.cookies ?? {},
|
|
137
|
+
params: req.params ?? {},
|
|
138
|
+
query: req.query ?? {},
|
|
139
|
+
method: req.method,
|
|
140
|
+
path: req.path,
|
|
141
|
+
headers, files,
|
|
142
|
+
}, res));
|
|
143
|
+
}
|
|
144
|
+
makeController(cb) {
|
|
145
|
+
return async (req, res, next) => {
|
|
146
|
+
try {
|
|
147
|
+
const rawResponse = await cb(await this.parse(req, res));
|
|
148
|
+
const response = rawResponse instanceof requests_1.Response ? rawResponse : new requests_1.Response({ body: rawResponse });
|
|
149
|
+
if (!response.piped) {
|
|
150
|
+
Object.entries(response.headers).forEach(([key, value]) => res.header(key, value));
|
|
151
|
+
const type = response.shouldJSONify ? 'json' : 'send';
|
|
152
|
+
res.status(response.status)[type](response.body).end();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
next(e);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
makeMiddleware(cb) {
|
|
161
|
+
return async (req, res, next) => {
|
|
162
|
+
try {
|
|
163
|
+
await cb(await this.parse(req, res));
|
|
164
|
+
return next();
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
return next(e);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
makeErrorMiddleware(cb) {
|
|
172
|
+
return async (err, req, res, _next) => {
|
|
173
|
+
const rawResponse = await cb(await this.parse(req, res), err);
|
|
174
|
+
const response = rawResponse instanceof requests_1.Response ? rawResponse : new requests_1.Response({ body: rawResponse, status: types_1.StatusCodes.BadRequest });
|
|
175
|
+
if (!response.piped) {
|
|
176
|
+
Object.entries(response.headers).forEach(([key, value]) => res.header(key, value));
|
|
177
|
+
res.status(response.status).send(response.body).end();
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
exports.ExpressServer = ExpressServer;
|
|
183
|
+
_ExpressServer_expressApp = new WeakMap(), _ExpressServer_oapi = new WeakMap(), _ExpressServer_ref = new WeakMap();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="node/http" />
|
|
2
|
+
/// <reference types="pino-http" />
|
|
3
|
+
import { FastifyReply, FastifyRequest, preHandlerHookHandler, RouteHandlerMethod } from 'fastify';
|
|
4
|
+
import { Defined } from '../../types';
|
|
5
|
+
import { Request } from '../requests';
|
|
6
|
+
import { Route } from '../types';
|
|
7
|
+
import { FullRoute, Server } from './base';
|
|
8
|
+
export declare class FastifyServer extends Server<FastifyRequest, FastifyReply> {
|
|
9
|
+
#private;
|
|
10
|
+
constructor();
|
|
11
|
+
protected onLoad(): Promise<void>;
|
|
12
|
+
protected registerRoute(route: FullRoute): void;
|
|
13
|
+
protected startServer(port: number): Promise<boolean>;
|
|
14
|
+
protected parse(req: FastifyRequest, res: FastifyReply): Promise<Request<import("../types").Api>>;
|
|
15
|
+
makeController(cb: Defined<Route['handler']>): RouteHandlerMethod;
|
|
16
|
+
makeMiddleware(cb: Defined<Route['middlewares']>[number]['cb']): preHandlerHookHandler<import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").RouteGenericInterface, unknown, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, import("fastify").FastifyBaseLogger>;
|
|
17
|
+
makeErrorMiddleware(cb: Defined<Route['onError']>['cb']): (error: import("fastify").FastifyError, request: FastifyRequest<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown, import("fastify").FastifyBaseLogger, import("fastify/types/type-provider").ResolveFastifyRequestType<import("fastify").FastifyTypeProviderDefault, import("fastify").FastifySchema, import("fastify").RouteGenericInterface>>, reply: FastifyReply<import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").RouteGenericInterface, unknown, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown>) => void;
|
|
18
|
+
}
|
|
19
|
+
declare module 'fastify' {
|
|
20
|
+
interface FastifyRequest {
|
|
21
|
+
savedReq: Request | null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
var _FastifyServer_fastifyApp;
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.FastifyServer = void 0;
|
|
19
|
+
const cookie_1 = __importDefault(require("@fastify/cookie"));
|
|
20
|
+
const cors_1 = __importDefault(require("@fastify/cors"));
|
|
21
|
+
const formbody_1 = __importDefault(require("@fastify/formbody"));
|
|
22
|
+
const helmet_1 = __importDefault(require("@fastify/helmet"));
|
|
23
|
+
const multipart_1 = __importDefault(require("@fastify/multipart"));
|
|
24
|
+
const rate_limit_1 = __importDefault(require("@fastify/rate-limit"));
|
|
25
|
+
const static_1 = __importDefault(require("@fastify/static"));
|
|
26
|
+
const swagger_1 = __importDefault(require("@fastify/swagger"));
|
|
27
|
+
const swagger_ui_1 = __importDefault(require("@fastify/swagger-ui"));
|
|
28
|
+
const fastify_1 = __importDefault(require("fastify"));
|
|
29
|
+
const fastify_slow_down_1 = __importDefault(require("fastify-slow-down"));
|
|
30
|
+
const qs_1 = __importDefault(require("qs"));
|
|
31
|
+
const errors_1 = require("../../errors");
|
|
32
|
+
const exit_1 = require("../../exit");
|
|
33
|
+
const instance_1 = require("../../instance");
|
|
34
|
+
const media_1 = require("../../utils/media");
|
|
35
|
+
const middlewares_1 = require("../middlewares");
|
|
36
|
+
const requests_1 = require("../requests");
|
|
37
|
+
const types_1 = require("../types");
|
|
38
|
+
const base_1 = require("./base");
|
|
39
|
+
function getFastifyApp() {
|
|
40
|
+
const instance = instance_1.Instance.get();
|
|
41
|
+
return (0, fastify_1.default)({
|
|
42
|
+
logger: instance.settings.logRequests ? instance.logger : false,
|
|
43
|
+
ajv: { customOptions: { coerceTypes: false } },
|
|
44
|
+
schemaErrorFormatter: (errors, data) => new errors_1.ValidationError(errors.map((error) => ({ messages: [error.message ?? ''], field: `${data}${error.instancePath}`.replaceAll('/', '.') })))
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
class FastifyServer extends base_1.Server {
|
|
48
|
+
constructor() {
|
|
49
|
+
const app = getFastifyApp();
|
|
50
|
+
super(app.server);
|
|
51
|
+
_FastifyServer_fastifyApp.set(this, void 0);
|
|
52
|
+
__classPrivateFieldSet(this, _FastifyServer_fastifyApp, app, "f");
|
|
53
|
+
app.decorateRequest('savedReq', null);
|
|
54
|
+
app.register(static_1.default, { root: this.staticPath });
|
|
55
|
+
app.register(cookie_1.default, {});
|
|
56
|
+
app.register(cors_1.default, { origin: '*' });
|
|
57
|
+
app.register(swagger_1.default, { openapi: this.baseOpenapiDoc });
|
|
58
|
+
app.register(swagger_ui_1.default, { routePrefix: this.settings.openapiDocsUrl });
|
|
59
|
+
app.register(formbody_1.default, { parser: (str) => qs_1.default.parse(str) });
|
|
60
|
+
app.register(helmet_1.default, { crossOriginResourcePolicy: { policy: 'cross-origin' } });
|
|
61
|
+
app.register(multipart_1.default, {
|
|
62
|
+
attachFieldsToBody: 'keyValues',
|
|
63
|
+
throwFileSizeLimit: false,
|
|
64
|
+
limits: { fileSize: this.settings.maxFileUploadSizeInMb * 1024 * 1024 },
|
|
65
|
+
onFile: async (f) => {
|
|
66
|
+
const buffer = await f.toBuffer();
|
|
67
|
+
const parsed = {
|
|
68
|
+
name: f.filename,
|
|
69
|
+
type: f.mimetype,
|
|
70
|
+
size: buffer.byteLength,
|
|
71
|
+
isTruncated: f.file.truncated,
|
|
72
|
+
data: buffer,
|
|
73
|
+
duration: await (0, media_1.getMediaDuration)(buffer),
|
|
74
|
+
};
|
|
75
|
+
f.value = parsed;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
if (this.settings.useSlowDown)
|
|
79
|
+
app.register(fastify_slow_down_1.default, {
|
|
80
|
+
timeWindow: this.settings.slowDownPeriodInMs,
|
|
81
|
+
delayAfter: this.settings.slowDownAfter,
|
|
82
|
+
delay: this.settings.slowDownDelayInMs
|
|
83
|
+
});
|
|
84
|
+
if (this.settings.useRateLimit)
|
|
85
|
+
app.register(rate_limit_1.default, {
|
|
86
|
+
max: this.settings.rateLimit,
|
|
87
|
+
timeWindow: this.settings.rateLimitPeriodInMs,
|
|
88
|
+
errorResponseBuilder: (_, context) => ({
|
|
89
|
+
statusCode: types_1.StatusCodes.TooManyRequests,
|
|
90
|
+
message: JSON.stringify([{ message: `Too Many Requests. Retry in ${context.after}` }])
|
|
91
|
+
})
|
|
92
|
+
});
|
|
93
|
+
if (!this.settings.requestSchemaValidation) {
|
|
94
|
+
app.setValidatorCompiler(() => () => true);
|
|
95
|
+
app.setSerializerCompiler(() => (data) => JSON.stringify(data));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async onLoad() {
|
|
99
|
+
await __classPrivateFieldGet(this, _FastifyServer_fastifyApp, "f").ready();
|
|
100
|
+
}
|
|
101
|
+
registerRoute(route) {
|
|
102
|
+
__classPrivateFieldGet(this, _FastifyServer_fastifyApp, "f").register(async (inst) => {
|
|
103
|
+
inst.route({
|
|
104
|
+
url: route.path,
|
|
105
|
+
method: route.method,
|
|
106
|
+
handler: this.makeController(route.handler),
|
|
107
|
+
preHandler: route.middlewares.map((m) => this.makeMiddleware(m.cb)),
|
|
108
|
+
errorHandler: route.onError ? this.makeErrorMiddleware(route.onError.cb) : undefined,
|
|
109
|
+
schema: route.schema,
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
async startServer(port) {
|
|
114
|
+
__classPrivateFieldGet(this, _FastifyServer_fastifyApp, "f").setNotFoundHandler(this.makeController(middlewares_1.notFoundHandler.cb));
|
|
115
|
+
__classPrivateFieldGet(this, _FastifyServer_fastifyApp, "f").setErrorHandler(this.makeErrorMiddleware(middlewares_1.errorHandler.cb));
|
|
116
|
+
await __classPrivateFieldGet(this, _FastifyServer_fastifyApp, "f").listen({ port });
|
|
117
|
+
(0, exit_1.addWaitBeforeExit)(__classPrivateFieldGet(this, _FastifyServer_fastifyApp, "f").close);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
async parse(req, res) {
|
|
121
|
+
const allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]));
|
|
122
|
+
const headers = {
|
|
123
|
+
...allHeaders,
|
|
124
|
+
AccessToken: req.headers['Access-Token']?.toString() ?? null,
|
|
125
|
+
RefreshToken: req.headers['Refresh-Token']?.toString() ?? null,
|
|
126
|
+
ContentType: req.headers['Content-Type']?.toString() ?? null,
|
|
127
|
+
Referer: req.headers['referer']?.toString() ?? null,
|
|
128
|
+
UserAgent: req.headers['User-Agent']?.toString() ?? null
|
|
129
|
+
};
|
|
130
|
+
const { body, files } = excludeBufferKeys(req.body ?? {});
|
|
131
|
+
return req.savedReq || (req.savedReq = new requests_1.Request({
|
|
132
|
+
ip: req.ip,
|
|
133
|
+
body,
|
|
134
|
+
cookies: req.cookies ?? {},
|
|
135
|
+
params: req.params ?? {},
|
|
136
|
+
query: req.query ?? {},
|
|
137
|
+
method: req.method,
|
|
138
|
+
path: req.url,
|
|
139
|
+
headers,
|
|
140
|
+
files,
|
|
141
|
+
}, res.raw));
|
|
142
|
+
}
|
|
143
|
+
makeController(cb) {
|
|
144
|
+
const handler = async (req, reply) => {
|
|
145
|
+
const rawResponse = await cb(await this.parse(req, reply));
|
|
146
|
+
const response = rawResponse instanceof requests_1.Response ? rawResponse : new requests_1.Response({ body: rawResponse });
|
|
147
|
+
const type = response.shouldJSONify ? 'json' : 'send';
|
|
148
|
+
if (!response.piped)
|
|
149
|
+
reply.status(response.status).headers(response.headers)[type](response.body);
|
|
150
|
+
};
|
|
151
|
+
return handler;
|
|
152
|
+
}
|
|
153
|
+
makeMiddleware(cb) {
|
|
154
|
+
const handler = async (req, reply) => {
|
|
155
|
+
await cb(await this.parse(req, reply));
|
|
156
|
+
};
|
|
157
|
+
return handler;
|
|
158
|
+
}
|
|
159
|
+
makeErrorMiddleware(cb) {
|
|
160
|
+
const handler = async (error, req, reply) => {
|
|
161
|
+
const rawResponse = await cb(await this.parse(req, reply), error);
|
|
162
|
+
const response = rawResponse instanceof requests_1.Response ? rawResponse : new requests_1.Response({ body: rawResponse, status: types_1.StatusCodes.BadRequest });
|
|
163
|
+
if (!response.piped)
|
|
164
|
+
reply.status(response.status).headers(response.headers).send(response.body);
|
|
165
|
+
};
|
|
166
|
+
return handler;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.FastifyServer = FastifyServer;
|
|
170
|
+
_FastifyServer_fastifyApp = new WeakMap();
|
|
171
|
+
function excludeBufferKeys(body) {
|
|
172
|
+
if (typeof body !== 'object')
|
|
173
|
+
return { body: body, files: {} };
|
|
174
|
+
const entries = Object.entries(body ?? {});
|
|
175
|
+
const isFile = (val) => Array.isArray(val) ? isFile(val.at(0)) : Buffer.isBuffer(val?.data);
|
|
176
|
+
const fileEntries = entries.filter(([_, value]) => isFile(value)).map(([key, value]) => [key, Array.isArray(value) ? value : [value]]);
|
|
177
|
+
const nonFileEntries = entries.filter(([_, value]) => !isFile(value));
|
|
178
|
+
return {
|
|
179
|
+
body: Object.fromEntries(nonFileEntries),
|
|
180
|
+
files: Object.fromEntries(fileEntries)
|
|
181
|
+
};
|
|
182
|
+
}
|
package/lib/server/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export * from './controllers';
|
|
2
|
-
export * from './controllers/request';
|
|
3
|
-
export * from './controllers/response';
|
|
4
1
|
export * from './middlewares';
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export * from './
|
|
2
|
+
export * from './requests';
|
|
3
|
+
export * from './routes';
|
|
4
|
+
export * from './types';
|
|
5
|
+
import { Server } from './impls/base';
|
|
6
|
+
export type { Server };
|
|
7
|
+
export type ServerTypes = 'express' | 'fastify';
|
|
8
|
+
export declare const serverTypes: Record<ServerTypes, () => Server>;
|
package/lib/server/index.js
CHANGED
|
@@ -14,12 +14,14 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
18
|
-
__exportStar(require("./controllers"), exports);
|
|
19
|
-
__exportStar(require("./controllers/request"), exports);
|
|
20
|
-
__exportStar(require("./controllers/response"), exports);
|
|
17
|
+
exports.serverTypes = void 0;
|
|
21
18
|
__exportStar(require("./middlewares"), exports);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
__exportStar(require("./requests"), exports);
|
|
20
|
+
__exportStar(require("./routes"), exports);
|
|
21
|
+
__exportStar(require("./types"), exports);
|
|
22
|
+
const express_1 = require("./impls/express");
|
|
23
|
+
const fastify_1 = require("./impls/fastify");
|
|
24
|
+
exports.serverTypes = {
|
|
25
|
+
express: () => new express_1.ExpressServer(),
|
|
26
|
+
fastify: () => new fastify_1.FastifyServer(),
|
|
27
|
+
};
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export declare const errorHandler:
|
|
1
|
+
export declare const errorHandler: {
|
|
2
|
+
cb: import("../types").ErrorHandler<import("../types").Api<unknown, string, import("../types").MethodTypes, unknown, unknown, unknown, import("../types").SupportedStatusCodes>>;
|
|
3
|
+
onSetup?: import("../types").HandlerSetup | undefined;
|
|
4
|
+
};
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.errorHandler = void 0;
|
|
4
|
+
const errors_1 = require("../../errors");
|
|
4
5
|
const instance_1 = require("../../instance");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (error.isCustomError)
|
|
11
|
-
return new response_1.Response({
|
|
6
|
+
const requests_1 = require("../requests");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
exports.errorHandler = (0, types_1.makeErrorMiddleware)(async (_, error) => {
|
|
9
|
+
if (error instanceof errors_1.CustomError)
|
|
10
|
+
return new requests_1.Response({
|
|
12
11
|
body: error.serializedErrors,
|
|
13
12
|
status: error.statusCode
|
|
14
13
|
});
|
|
15
14
|
else {
|
|
16
|
-
await instance_1.Instance.get().logger.error(
|
|
17
|
-
return new
|
|
18
|
-
body: [{ message: 'Something went wrong', data:
|
|
19
|
-
status:
|
|
15
|
+
await instance_1.Instance.get().logger.error(error);
|
|
16
|
+
return new requests_1.Response({
|
|
17
|
+
body: [{ message: 'Something went wrong', data: error.message }],
|
|
18
|
+
status: types_1.StatusCodes.BadRequest
|
|
20
19
|
});
|
|
21
20
|
}
|
|
22
21
|
});
|
|
@@ -16,5 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./errorHandler"), exports);
|
|
18
18
|
__exportStar(require("./notFoundHandler"), exports);
|
|
19
|
+
__exportStar(require("./parseAuthUser"), exports);
|
|
19
20
|
__exportStar(require("./requireAuthUser"), exports);
|
|
20
21
|
__exportStar(require("./requireRefreshUser"), exports);
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export declare const notFoundHandler:
|
|
1
|
+
export declare const notFoundHandler: {
|
|
2
|
+
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<unknown, string, import("../types").MethodTypes, unknown, unknown, unknown, import("../types").SupportedStatusCodes>>;
|
|
3
|
+
onSetup?: import("../types").HandlerSetup | undefined;
|
|
4
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.notFoundHandler = void 0;
|
|
4
4
|
const errors_1 = require("../../errors");
|
|
5
|
-
const
|
|
6
|
-
exports.notFoundHandler = (0,
|
|
7
|
-
throw new errors_1.NotFoundError(
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
exports.notFoundHandler = (0, types_1.makeMiddleware)(async (req) => {
|
|
7
|
+
throw new errors_1.NotFoundError(`Route ${req.path} not found`);
|
|
8
8
|
});
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export declare const parseAuthUser:
|
|
1
|
+
export declare const parseAuthUser: {
|
|
2
|
+
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<unknown, string, import("../types").MethodTypes, unknown, unknown, unknown, import("../types").SupportedStatusCodes>>;
|
|
3
|
+
onSetup?: import("../types").HandlerSetup | undefined;
|
|
4
|
+
};
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseAuthUser = void 0;
|
|
4
4
|
const errors_1 = require("../../errors");
|
|
5
5
|
const tokens_1 = require("../../utils/tokens");
|
|
6
|
-
const
|
|
7
|
-
exports.parseAuthUser = (0,
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
exports.parseAuthUser = (0, types_1.makeMiddleware)(async (request) => {
|
|
8
8
|
const accessToken = request.headers.AccessToken;
|
|
9
9
|
if (accessToken)
|
|
10
10
|
request.authUser = await (0, tokens_1.verifyAccessToken)(accessToken).catch((err) => {
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export declare const requireAuthUser: {
|
|
2
|
+
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<unknown, string, import("../types").MethodTypes, unknown, unknown, unknown, import("../types").SupportedStatusCodes>>;
|
|
3
|
+
onSetup?: import("../types").HandlerSetup | undefined;
|
|
4
|
+
};
|
|
@@ -2,10 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.requireAuthUser = void 0;
|
|
4
4
|
const errors_1 = require("../../errors");
|
|
5
|
-
const
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
exports.requireAuthUser = (0, types_1.makeMiddleware)(async (request) => {
|
|
6
7
|
if (request.pendingError)
|
|
7
8
|
throw request.pendingError;
|
|
9
|
+
if (!request.headers.AccessToken)
|
|
10
|
+
throw new errors_1.NotAuthenticatedError('Access-Token header missing');
|
|
8
11
|
if (!request.authUser)
|
|
9
12
|
throw new errors_1.NotAuthenticatedError();
|
|
10
|
-
}
|
|
11
|
-
|
|
13
|
+
}, (route) => {
|
|
14
|
+
route.security ?? (route.security = []);
|
|
15
|
+
route.security.push({ AccessToken: [] });
|
|
16
|
+
});
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export declare const requireRefreshUser: {
|
|
2
|
+
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<unknown, string, import("../types").MethodTypes, unknown, unknown, unknown, import("../types").SupportedStatusCodes>>;
|
|
3
|
+
onSetup?: import("../types").HandlerSetup | undefined;
|
|
4
|
+
};
|
|
@@ -3,12 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.requireRefreshUser = void 0;
|
|
4
4
|
const errors_1 = require("../../errors");
|
|
5
5
|
const tokens_1 = require("../../utils/tokens");
|
|
6
|
-
const
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
exports.requireRefreshUser = (0, types_1.makeMiddleware)(async (request) => {
|
|
7
8
|
const refreshToken = request.headers.RefreshToken;
|
|
8
9
|
if (!refreshToken)
|
|
9
|
-
throw new errors_1.NotAuthorizedError();
|
|
10
|
+
throw new errors_1.NotAuthorizedError('Refresh-Token header missing');
|
|
10
11
|
request.refreshUser = await (0, tokens_1.verifyRefreshToken)(refreshToken);
|
|
11
12
|
if (!request.refreshUser)
|
|
12
13
|
throw new errors_1.NotAuthorizedError();
|
|
13
|
-
}
|
|
14
|
-
|
|
14
|
+
}, (route) => {
|
|
15
|
+
route.security ?? (route.security = []);
|
|
16
|
+
route.security.push({ RefreshToken: [] });
|
|
17
|
+
});
|