equipped 5.0.0-beta.9 → 5.0.0-rc.2
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 +156 -0
- package/lib/bull/index.js +33 -44
- package/lib/cache/cache.d.ts +1 -0
- package/lib/cache/types/redis-cache.d.ts +1 -0
- package/lib/cache/types/redis-cache.js +8 -0
- package/lib/db/_instance.d.ts +2 -2
- package/lib/db/_instance.js +9 -25
- package/lib/db/mongoose/changes.d.ts +1 -26
- package/lib/db/mongoose/changes.js +7 -20
- package/lib/db/mongoose/index.d.ts +2 -27
- package/lib/db/mongoose/index.js +8 -24
- package/lib/db/mongoose/query.d.ts +0 -25
- package/lib/errors/customError.js +2 -0
- package/lib/errors/types/accessTokenExpired.js +1 -1
- package/lib/errors/types/badRequestError.js +1 -1
- package/lib/errors/types/notAuthenticatedError.js +1 -1
- package/lib/errors/types/notAuthorizedError.js +1 -1
- package/lib/errors/types/notFoundError.js +1 -1
- package/lib/errors/types/refreshTokenMisusedError.js +1 -1
- package/lib/errors/types/validationError.js +1 -1
- package/lib/events/index.js +1 -3
- package/lib/events/kafka.d.ts +1 -1
- package/lib/events/kafka.js +19 -25
- package/lib/events/rabbit.d.ts +1 -1
- package/lib/events/rabbit.js +9 -22
- package/lib/instance/index.d.ts +2 -1
- package/lib/instance/index.js +28 -41
- package/lib/instance/settings.d.ts +2 -2
- package/lib/instance/settings.js +4 -4
- package/lib/listeners/emitter.d.ts +6 -3
- package/lib/listeners/emitter.js +97 -109
- package/lib/scripts/json-schema.d.ts +2 -1
- package/lib/scripts/json-schema.js +29 -22
- package/lib/server/impls/base.d.ts +18 -7
- package/lib/server/impls/base.js +177 -80
- package/lib/server/impls/express.d.ts +0 -1
- package/lib/server/impls/express.js +16 -34
- package/lib/server/impls/fastify.d.ts +2 -4
- package/lib/server/impls/fastify.js +21 -39
- package/lib/server/middlewares/errorHandler.d.ts +2 -2
- package/lib/server/middlewares/notFoundHandler.d.ts +2 -2
- package/lib/server/middlewares/parseAuthUser.d.ts +2 -2
- package/lib/server/middlewares/requireAuthUser.d.ts +2 -2
- package/lib/server/middlewares/requireAuthUser.js +2 -2
- package/lib/server/middlewares/requireRefreshUser.d.ts +2 -2
- package/lib/server/middlewares/requireRefreshUser.js +2 -2
- package/lib/server/requests.d.ts +10 -7
- package/lib/server/requests.js +27 -21
- package/lib/server/routes.d.ts +4 -2
- package/lib/server/routes.js +33 -33
- package/lib/server/types.d.ts +19 -9
- package/lib/server/types.js +3 -0
- package/lib/storage/index.d.ts +0 -1
- package/lib/structure/baseEntity.js +7 -9
- package/lib/types/index.d.ts +2 -2
- package/lib/utils/auth.d.ts +5 -5
- package/lib/utils/authUser.d.ts +3 -2
- package/lib/utils/media.d.ts +0 -1
- package/lib/utils/utils.d.ts +1 -0
- package/lib/utils/utils.js +9 -0
- package/lib/validations/index.d.ts +79 -85
- package/lib/validations/index.js +4 -4
- package/package.json +24 -25
package/lib/server/impls/base.js
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
-
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");
|
|
5
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
-
};
|
|
7
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
8
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
10
|
-
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");
|
|
11
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
|
-
};
|
|
13
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
4
|
};
|
|
16
|
-
var _Server_instances, _Server_schemas, _Server_listener, _Server_regRoute;
|
|
17
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
6
|
exports.Server = void 0;
|
|
19
7
|
const socket_io_1 = __importDefault(require("socket.io"));
|
|
@@ -22,73 +10,162 @@ const path_1 = __importDefault(require("path"));
|
|
|
22
10
|
const instance_1 = require("../../instance");
|
|
23
11
|
const listeners_1 = require("../../listeners");
|
|
24
12
|
const middlewares_1 = require("../middlewares");
|
|
13
|
+
const requests_1 = require("../requests");
|
|
25
14
|
const routes_1 = require("../routes");
|
|
15
|
+
const types_1 = require("../types");
|
|
26
16
|
class Server {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
17
|
+
#routesByPath = new Map();
|
|
18
|
+
#routesByKey = new Map();
|
|
19
|
+
#schemas = {};
|
|
20
|
+
#listener = null;
|
|
21
|
+
#registeredTags = {};
|
|
22
|
+
#registeredTagGroups = {};
|
|
23
|
+
server;
|
|
24
|
+
staticPath = path_1.default.join(process.cwd(), 'public');
|
|
25
|
+
settings = instance_1.Instance.get().settings;
|
|
26
|
+
openapiJsonUrl = `${this.settings.openapiDocsPath}/openapi.json`;
|
|
27
|
+
baseOpenapiDoc = {
|
|
28
|
+
openapi: '3.0.0',
|
|
29
|
+
info: { title: this.settings.appId, version: this.settings.openapiDocsVersion },
|
|
30
|
+
servers: this.settings.openapiDocsBaseUrl.map((url) => ({ url })),
|
|
31
|
+
paths: {},
|
|
32
|
+
components: {
|
|
33
|
+
schemas: {},
|
|
34
|
+
securitySchemes: {
|
|
35
|
+
AccessToken: {
|
|
36
|
+
type: 'apiKey',
|
|
37
|
+
name: 'Access-Token',
|
|
38
|
+
in: 'header',
|
|
50
39
|
},
|
|
51
|
-
|
|
52
|
-
|
|
40
|
+
RefreshToken: {
|
|
41
|
+
type: 'apiKey',
|
|
42
|
+
name: 'Refresh-Token',
|
|
43
|
+
in: 'header',
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
tags: [],
|
|
48
|
+
'x-tagGroups': [],
|
|
49
|
+
};
|
|
50
|
+
constructor(server) {
|
|
53
51
|
this.server = server;
|
|
54
52
|
}
|
|
55
53
|
get listener() {
|
|
56
|
-
if (!
|
|
54
|
+
if (!this.#listener) {
|
|
57
55
|
const socket = new socket_io_1.default.Server(this.server, { cors: { origin: '*' } });
|
|
58
|
-
|
|
56
|
+
this.#listener = new listeners_1.Listener(socket, {
|
|
59
57
|
onConnect: async () => { },
|
|
60
58
|
onDisconnect: async () => { }
|
|
61
|
-
})
|
|
59
|
+
});
|
|
62
60
|
}
|
|
63
|
-
return
|
|
61
|
+
return this.#listener;
|
|
62
|
+
}
|
|
63
|
+
addRouter(...routers) {
|
|
64
|
+
routers.map((router) => router.routes).forEach((routes) => this.addRoute(...routes));
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
-
routes.forEach((route) =>
|
|
66
|
+
addRoute(...routes) {
|
|
67
|
+
routes.forEach((route) => this.#regRoute(route));
|
|
67
68
|
}
|
|
68
|
-
addSchema(schemas) {
|
|
69
|
-
Object.assign(
|
|
69
|
+
addSchema(...schemas) {
|
|
70
|
+
schemas.forEach((schema) => Object.assign(this.#schemas, schema));
|
|
70
71
|
}
|
|
71
72
|
async load() {
|
|
72
73
|
await this.onLoad();
|
|
73
74
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
#buildTag(groups) {
|
|
76
|
+
if (!groups.length)
|
|
77
|
+
return undefined;
|
|
78
|
+
const parsed = groups.map((g) => typeof g === 'string' ? { name: g } : g);
|
|
79
|
+
const name = parsed.map((g) => g.name).join(' > ');
|
|
80
|
+
const displayName = parsed.at(-1)?.name ?? '';
|
|
81
|
+
const description = parsed.map((g) => g.description?.trim() ?? '').filter(Boolean).join('\n\n\n\n');
|
|
82
|
+
if (!this.#registeredTags[name]) {
|
|
83
|
+
this.#registeredTags[name] = true;
|
|
84
|
+
this.baseOpenapiDoc.tags.push({ name, 'x-displayName': displayName, description });
|
|
85
|
+
const tagGroups = parsed.slice(0, -1);
|
|
86
|
+
const groupName = tagGroups.map((g) => g.name).join(' > ') || 'default';
|
|
87
|
+
if (!this.#registeredTagGroups[groupName]) {
|
|
88
|
+
const group = { name: groupName, tags: [] };
|
|
89
|
+
this.baseOpenapiDoc['x-tagGroups'].push(group);
|
|
90
|
+
this.#registeredTagGroups[groupName] = group;
|
|
91
|
+
}
|
|
92
|
+
this.#registeredTagGroups[groupName].tags = [...new Set([...this.#registeredTagGroups[groupName].tags, name])];
|
|
93
|
+
}
|
|
94
|
+
return name;
|
|
95
|
+
}
|
|
96
|
+
#regRoute(route) {
|
|
97
|
+
const middlewares = [middlewares_1.parseAuthUser, ...(route.middlewares ?? [])];
|
|
98
|
+
route.onSetupHandler?.(route);
|
|
99
|
+
middlewares.forEach((m) => m.onSetup?.(route));
|
|
100
|
+
route.onError?.onSetup?.(route);
|
|
101
|
+
const { method, path, handler, schema, security, onError, hideSchema = false } = route;
|
|
102
|
+
const pathKey = `(${method.toUpperCase()}) ${path}`;
|
|
103
|
+
const { key = pathKey } = route;
|
|
104
|
+
const tag = this.#buildTag(route.groups ?? []);
|
|
105
|
+
const scheme = Object.assign({}, schema, this.#schemas[key]);
|
|
106
|
+
const fullRoute = {
|
|
107
|
+
method, middlewares, handler, key,
|
|
108
|
+
path: (0, routes_1.cleanPath)(path),
|
|
109
|
+
onError,
|
|
110
|
+
schema: {
|
|
111
|
+
...scheme,
|
|
112
|
+
...(scheme.title ? { summary: scheme.title } : {}),
|
|
113
|
+
summary: scheme.title ?? scheme.summary ?? (0, routes_1.cleanPath)(path),
|
|
114
|
+
hide: hideSchema,
|
|
115
|
+
tags: tag ? [tag] : undefined,
|
|
116
|
+
description: route.descriptions?.join('\n\n'),
|
|
117
|
+
security,
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
if (this.#routesByPath.get(pathKey))
|
|
121
|
+
throw new Error(`Route path ${pathKey} already registered. All route paths and methods combinations must be unique`);
|
|
122
|
+
if (this.#routesByKey.get(key))
|
|
123
|
+
throw new Error(`Route key ${fullRoute.key} already registered. All route keys must be unique`);
|
|
124
|
+
this.#routesByPath.set(pathKey, fullRoute);
|
|
125
|
+
this.#routesByKey.set(key, fullRoute);
|
|
126
|
+
this.registerRoute(fullRoute);
|
|
77
127
|
}
|
|
78
128
|
test() {
|
|
79
129
|
return (0, supertest_1.default)(this.server);
|
|
80
130
|
}
|
|
81
131
|
async start(port) {
|
|
82
|
-
|
|
83
|
-
|
|
132
|
+
this.addRoute({
|
|
133
|
+
method: 'get',
|
|
134
|
+
path: `${this.settings.openapiDocsPath}/`,
|
|
135
|
+
handler: () => new requests_1.Response({
|
|
136
|
+
status: types_1.StatusCodes.Found,
|
|
137
|
+
headers: { 'Location': './index.html' },
|
|
138
|
+
}),
|
|
139
|
+
hideSchema: true,
|
|
140
|
+
});
|
|
141
|
+
this.addRoute({
|
|
142
|
+
method: 'get',
|
|
143
|
+
path: `${this.settings.openapiDocsPath}/index.html`,
|
|
144
|
+
handler: () => new requests_1.Response({
|
|
145
|
+
body: scalarHtml
|
|
146
|
+
.replaceAll('__API_TITLE__', this.settings.appId)
|
|
147
|
+
.replaceAll('__OPENAPI_JSON_URL__', './openapi.json'),
|
|
148
|
+
headers: { 'Content-Type': 'text/html' },
|
|
149
|
+
}),
|
|
150
|
+
hideSchema: true,
|
|
151
|
+
});
|
|
152
|
+
this.addRoute({
|
|
153
|
+
method: 'get',
|
|
154
|
+
path: `${this.settings.openapiDocsPath}/redoc.html`,
|
|
155
|
+
handler: () => new requests_1.Response({
|
|
156
|
+
body: redocHtml
|
|
157
|
+
.replaceAll('__API_TITLE__', this.settings.appId)
|
|
158
|
+
.replaceAll('__OPENAPI_JSON_URL__', './openapi.json'),
|
|
159
|
+
headers: { 'Content-Type': 'text/html' },
|
|
160
|
+
}),
|
|
161
|
+
hideSchema: true,
|
|
162
|
+
});
|
|
163
|
+
this.addRoute({
|
|
164
|
+
method: 'get',
|
|
84
165
|
path: '__health',
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
})(async () => `${this.settings.appId} service running`);
|
|
91
|
-
this.register(postRoutesRouter);
|
|
166
|
+
handler: async () => `${this.settings.appId} service running`,
|
|
167
|
+
hideSchema: true,
|
|
168
|
+
});
|
|
92
169
|
const started = await this.startServer(port);
|
|
93
170
|
if (started)
|
|
94
171
|
await instance_1.Instance.get().logger.info(`${this.settings.appId} service listening on port ${port}`);
|
|
@@ -96,26 +173,46 @@ class Server {
|
|
|
96
173
|
}
|
|
97
174
|
}
|
|
98
175
|
exports.Server = Server;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
176
|
+
const scalarHtml = `
|
|
177
|
+
<!doctype html>
|
|
178
|
+
<html>
|
|
179
|
+
<head>
|
|
180
|
+
<title>__API_TITLE__</title>
|
|
181
|
+
<meta charset="utf-8" />
|
|
182
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
183
|
+
<style>
|
|
184
|
+
.darklight-reference {
|
|
185
|
+
display: none;
|
|
186
|
+
}
|
|
187
|
+
</style>
|
|
188
|
+
</head>
|
|
189
|
+
<body>
|
|
190
|
+
<script id="api-reference" data-url="__OPENAPI_JSON_URL__"></script>
|
|
191
|
+
<script>
|
|
192
|
+
const configuration = { theme: 'purple' };
|
|
193
|
+
document.getElementById('api-reference').dataset.configuration = JSON.stringify(configuration);
|
|
194
|
+
</script>
|
|
195
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.24.36"></script>
|
|
196
|
+
</body>
|
|
197
|
+
</html>
|
|
198
|
+
`;
|
|
199
|
+
const redocHtml = `
|
|
200
|
+
<!doctype html>
|
|
201
|
+
<html>
|
|
202
|
+
<head>
|
|
203
|
+
<title>__API_TITLE__</title>
|
|
204
|
+
<meta charset="utf-8" />
|
|
205
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
206
|
+
<style>
|
|
207
|
+
body {
|
|
208
|
+
margin: 0;
|
|
209
|
+
padding: 0;
|
|
210
|
+
}
|
|
211
|
+
</style>
|
|
212
|
+
</head>
|
|
213
|
+
<body>
|
|
214
|
+
<redoc spec-url="__OPENAPI_JSON_URL__"></redoc>
|
|
215
|
+
<script src="https://cdn.redoc.ly/redoc/v2.1.5/bundles/redoc.standalone.js"> </script>
|
|
216
|
+
</body>
|
|
217
|
+
</html>
|
|
218
|
+
`;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import { Defined } from '../../types';
|
|
3
|
-
import { Request, Response } from '../requests';
|
|
4
3
|
import { Route } from '../types';
|
|
5
4
|
import { FullRoute, Server } from './base';
|
|
6
5
|
export declare class ExpressServer extends Server<express.Request, express.Response> {
|
|
@@ -1,19 +1,7 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
4
|
};
|
|
16
|
-
var _ExpressServer_expressApp, _ExpressServer_oapi, _ExpressServer_ref;
|
|
17
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
6
|
exports.ExpressServer = void 0;
|
|
19
7
|
const utils_1 = require("@fastify/swagger/lib/spec/openapi/utils");
|
|
@@ -23,7 +11,6 @@ const cors_1 = __importDefault(require("cors"));
|
|
|
23
11
|
const express_1 = __importDefault(require("express"));
|
|
24
12
|
const express_fileupload_1 = __importDefault(require("express-fileupload"));
|
|
25
13
|
const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
|
|
26
|
-
const express_slow_down_1 = __importDefault(require("express-slow-down"));
|
|
27
14
|
const helmet_1 = __importDefault(require("helmet"));
|
|
28
15
|
const http_1 = __importDefault(require("http"));
|
|
29
16
|
const json_schema_resolver_1 = __importDefault(require("json-schema-resolver"));
|
|
@@ -37,25 +24,27 @@ const requests_1 = require("../requests");
|
|
|
37
24
|
const types_1 = require("../types");
|
|
38
25
|
const base_1 = require("./base");
|
|
39
26
|
class ExpressServer extends base_1.Server {
|
|
27
|
+
#expressApp;
|
|
28
|
+
#oapi = (0, openapi_1.default)(this.openapiJsonUrl.replace('.json', ''), this.baseOpenapiDoc, { coerce: false });
|
|
29
|
+
#ref = (0, json_schema_resolver_1.default)({ clone: true });
|
|
40
30
|
constructor() {
|
|
41
31
|
const app = (0, express_1.default)();
|
|
42
32
|
super(http_1.default.createServer(app));
|
|
43
|
-
|
|
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");
|
|
33
|
+
this.#expressApp = app;
|
|
47
34
|
app.disable('x-powered-by');
|
|
48
35
|
if (this.settings.logRequests)
|
|
49
36
|
app.use((0, pino_http_1.pinoHttp)({ logger: instance_1.Instance.get().logger }));
|
|
50
37
|
app.use(express_1.default.json());
|
|
51
38
|
app.use(express_1.default.text());
|
|
52
39
|
app.use((0, cookie_parser_1.default)());
|
|
53
|
-
app.use(helmet_1.default
|
|
40
|
+
app.use((0, helmet_1.default)({
|
|
41
|
+
crossOriginResourcePolicy: { policy: 'cross-origin' },
|
|
42
|
+
contentSecurityPolicy: false
|
|
43
|
+
}));
|
|
54
44
|
app.use((0, cors_1.default)({ origin: '*' }));
|
|
55
45
|
app.use(express_1.default.urlencoded({ extended: false }));
|
|
56
46
|
app.use(express_1.default.static(this.staticPath));
|
|
57
|
-
app.use(
|
|
58
|
-
app.use(this.settings.openapiDocsUrl, __classPrivateFieldGet(this, _ExpressServer_oapi, "f").swaggerui());
|
|
47
|
+
app.use(this.#oapi);
|
|
59
48
|
app.use((0, express_fileupload_1.default)({
|
|
60
49
|
limits: { fileSize: this.settings.maxFileUploadSizeInMb * 1024 * 1024 },
|
|
61
50
|
useTempFiles: false
|
|
@@ -66,21 +55,15 @@ class ExpressServer extends base_1.Server {
|
|
|
66
55
|
limit: this.settings.rateLimit,
|
|
67
56
|
handler: (_, res) => res.status(types_1.StatusCodes.TooManyRequests).json([{ message: 'Too Many Requests' }])
|
|
68
57
|
}));
|
|
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
58
|
}
|
|
76
59
|
registerRoute(route) {
|
|
77
|
-
const openapi = (0, utils_1.prepareOpenapiMethod)(route.schema,
|
|
60
|
+
const openapi = (0, utils_1.prepareOpenapiMethod)(route.schema, this.#ref, this.baseOpenapiDoc, route.path);
|
|
78
61
|
const controllers = [
|
|
79
62
|
...route.middlewares.map((m) => this.makeMiddleware(m.cb)),
|
|
80
63
|
this.makeController(route.handler)
|
|
81
64
|
];
|
|
82
65
|
if (!route.schema.hide)
|
|
83
|
-
controllers.unshift(
|
|
66
|
+
controllers.unshift(this.#oapi[this.settings.requestSchemaValidation ? 'validPath' : 'path'](openapi), (error, _, __, next) => {
|
|
84
67
|
if ('validationErrors' in error) {
|
|
85
68
|
const validationErrors = error.validationErrors;
|
|
86
69
|
throw new errors_1.ValidationError(validationErrors.map((error) => ({
|
|
@@ -92,11 +75,11 @@ class ExpressServer extends base_1.Server {
|
|
|
92
75
|
});
|
|
93
76
|
if (route.onError)
|
|
94
77
|
controllers.push(this.makeErrorMiddleware(route.onError.cb));
|
|
95
|
-
|
|
78
|
+
this.#expressApp[route.method]?.(route.path, ...controllers);
|
|
96
79
|
}
|
|
97
80
|
async startServer(port) {
|
|
98
|
-
|
|
99
|
-
|
|
81
|
+
this.#expressApp.use(this.makeMiddleware(middlewares_1.notFoundHandler.cb));
|
|
82
|
+
this.#expressApp.use(this.makeErrorMiddleware(middlewares_1.errorHandler.cb));
|
|
100
83
|
return await new Promise((resolve, reject) => {
|
|
101
84
|
try {
|
|
102
85
|
const app = this.server.listen({ host: '0.0.0.0', port }, async () => resolve(true));
|
|
@@ -130,7 +113,7 @@ class ExpressServer extends base_1.Server {
|
|
|
130
113
|
})));
|
|
131
114
|
return [key, fileArray];
|
|
132
115
|
})));
|
|
133
|
-
return req.savedReq
|
|
116
|
+
return req.savedReq ||= new requests_1.Request({
|
|
134
117
|
ip: req.ip,
|
|
135
118
|
body: req.body ?? {},
|
|
136
119
|
cookies: req.cookies ?? {},
|
|
@@ -139,7 +122,7 @@ class ExpressServer extends base_1.Server {
|
|
|
139
122
|
method: req.method,
|
|
140
123
|
path: req.path,
|
|
141
124
|
headers, files,
|
|
142
|
-
}, res)
|
|
125
|
+
}, res);
|
|
143
126
|
}
|
|
144
127
|
makeController(cb) {
|
|
145
128
|
return async (req, res, next) => {
|
|
@@ -180,4 +163,3 @@ class ExpressServer extends base_1.Server {
|
|
|
180
163
|
}
|
|
181
164
|
}
|
|
182
165
|
exports.ExpressServer = ExpressServer;
|
|
183
|
-
_ExpressServer_expressApp = new WeakMap(), _ExpressServer_oapi = new WeakMap(), _ExpressServer_ref = new WeakMap();
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/// <reference types="node/http" />
|
|
2
|
-
/// <reference types="pino-http" />
|
|
3
1
|
import { FastifyReply, FastifyRequest, preHandlerHookHandler, RouteHandlerMethod } from 'fastify';
|
|
4
2
|
import { Defined } from '../../types';
|
|
5
3
|
import { Request } from '../requests';
|
|
@@ -11,10 +9,10 @@ export declare class FastifyServer extends Server<FastifyRequest, FastifyReply>
|
|
|
11
9
|
protected onLoad(): Promise<void>;
|
|
12
10
|
protected registerRoute(route: FullRoute): void;
|
|
13
11
|
protected startServer(port: number): Promise<boolean>;
|
|
14
|
-
protected parse(req: FastifyRequest, res: FastifyReply): Promise<Request<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string,
|
|
12
|
+
protected parse(req: FastifyRequest, res: FastifyReply): Promise<Request<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string, string>, Record<string, any>, Record<string, string | string[]>, Record<string, string | string[]>, import("../types").SupportedStatusCodes>>>;
|
|
15
13
|
makeController(cb: Defined<Route['handler']>): RouteHandlerMethod;
|
|
16
14
|
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
|
|
15
|
+
makeErrorMiddleware(cb: Defined<Route['onError']>['cb']): (error: import("fastify").FastifyError, request: FastifyRequest, reply: FastifyReply) => void;
|
|
18
16
|
}
|
|
19
17
|
declare module 'fastify' {
|
|
20
18
|
interface FastifyRequest {
|
|
@@ -1,19 +1,7 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
4
|
};
|
|
16
|
-
var _FastifyServer_fastifyApp;
|
|
17
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
6
|
exports.FastifyServer = void 0;
|
|
19
7
|
const cookie_1 = __importDefault(require("@fastify/cookie"));
|
|
@@ -24,9 +12,7 @@ const multipart_1 = __importDefault(require("@fastify/multipart"));
|
|
|
24
12
|
const rate_limit_1 = __importDefault(require("@fastify/rate-limit"));
|
|
25
13
|
const static_1 = __importDefault(require("@fastify/static"));
|
|
26
14
|
const swagger_1 = __importDefault(require("@fastify/swagger"));
|
|
27
|
-
const swagger_ui_1 = __importDefault(require("@fastify/swagger-ui"));
|
|
28
15
|
const fastify_1 = __importDefault(require("fastify"));
|
|
29
|
-
const fastify_slow_down_1 = __importDefault(require("fastify-slow-down"));
|
|
30
16
|
const qs_1 = __importDefault(require("qs"));
|
|
31
17
|
const errors_1 = require("../../errors");
|
|
32
18
|
const exit_1 = require("../../exit");
|
|
@@ -39,25 +25,29 @@ const base_1 = require("./base");
|
|
|
39
25
|
function getFastifyApp() {
|
|
40
26
|
const instance = instance_1.Instance.get();
|
|
41
27
|
return (0, fastify_1.default)({
|
|
28
|
+
ignoreTrailingSlash: true,
|
|
29
|
+
caseSensitive: false,
|
|
42
30
|
logger: instance.settings.logRequests ? instance.logger : false,
|
|
43
31
|
ajv: { customOptions: { coerceTypes: false } },
|
|
44
32
|
schemaErrorFormatter: (errors, data) => new errors_1.ValidationError(errors.map((error) => ({ messages: [error.message ?? ''], field: `${data}${error.instancePath}`.replaceAll('/', '.') })))
|
|
45
33
|
});
|
|
46
34
|
}
|
|
47
35
|
class FastifyServer extends base_1.Server {
|
|
36
|
+
#fastifyApp;
|
|
48
37
|
constructor() {
|
|
49
38
|
const app = getFastifyApp();
|
|
50
39
|
super(app.server);
|
|
51
|
-
|
|
52
|
-
__classPrivateFieldSet(this, _FastifyServer_fastifyApp, app, "f");
|
|
40
|
+
this.#fastifyApp = app;
|
|
53
41
|
app.decorateRequest('savedReq', null);
|
|
54
42
|
app.register(static_1.default, { root: this.staticPath });
|
|
55
43
|
app.register(cookie_1.default, {});
|
|
56
44
|
app.register(cors_1.default, { origin: '*' });
|
|
57
45
|
app.register(swagger_1.default, { openapi: this.baseOpenapiDoc });
|
|
58
|
-
app.
|
|
46
|
+
app.get(this.openapiJsonUrl, (_, res) => {
|
|
47
|
+
res.code(200).send(app.swagger({}));
|
|
48
|
+
});
|
|
59
49
|
app.register(formbody_1.default, { parser: (str) => qs_1.default.parse(str) });
|
|
60
|
-
app.register(helmet_1.default, { crossOriginResourcePolicy: { policy: 'cross-origin' } });
|
|
50
|
+
app.register(helmet_1.default, { crossOriginResourcePolicy: { policy: 'cross-origin' }, contentSecurityPolicy: false });
|
|
61
51
|
app.register(multipart_1.default, {
|
|
62
52
|
attachFieldsToBody: 'keyValues',
|
|
63
53
|
throwFileSizeLimit: false,
|
|
@@ -75,12 +65,6 @@ class FastifyServer extends base_1.Server {
|
|
|
75
65
|
f.value = parsed;
|
|
76
66
|
}
|
|
77
67
|
});
|
|
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
68
|
if (this.settings.useRateLimit)
|
|
85
69
|
app.register(rate_limit_1.default, {
|
|
86
70
|
max: this.settings.rateLimit,
|
|
@@ -96,10 +80,10 @@ class FastifyServer extends base_1.Server {
|
|
|
96
80
|
}
|
|
97
81
|
}
|
|
98
82
|
async onLoad() {
|
|
99
|
-
await
|
|
83
|
+
await this.#fastifyApp.ready();
|
|
100
84
|
}
|
|
101
85
|
registerRoute(route) {
|
|
102
|
-
|
|
86
|
+
this.#fastifyApp.register(async (inst) => {
|
|
103
87
|
inst.route({
|
|
104
88
|
url: route.path,
|
|
105
89
|
method: route.method,
|
|
@@ -111,24 +95,24 @@ class FastifyServer extends base_1.Server {
|
|
|
111
95
|
});
|
|
112
96
|
}
|
|
113
97
|
async startServer(port) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
await
|
|
117
|
-
(0, exit_1.addWaitBeforeExit)(
|
|
98
|
+
this.#fastifyApp.setNotFoundHandler(this.makeController(middlewares_1.notFoundHandler.cb));
|
|
99
|
+
this.#fastifyApp.setErrorHandler(this.makeErrorMiddleware(middlewares_1.errorHandler.cb));
|
|
100
|
+
await this.#fastifyApp.listen({ port, host: '0.0.0.0' });
|
|
101
|
+
(0, exit_1.addWaitBeforeExit)(this.#fastifyApp.close);
|
|
118
102
|
return true;
|
|
119
103
|
}
|
|
120
104
|
async parse(req, res) {
|
|
121
105
|
const allHeaders = Object.fromEntries(Object.entries(req.headers).map(([key, val]) => [key, val ?? null]));
|
|
122
106
|
const headers = {
|
|
123
107
|
...allHeaders,
|
|
124
|
-
AccessToken: req.headers['
|
|
125
|
-
RefreshToken: req.headers['
|
|
126
|
-
ContentType: req.headers['
|
|
108
|
+
AccessToken: req.headers['access-token']?.toString() ?? null,
|
|
109
|
+
RefreshToken: req.headers['refresh-token']?.toString() ?? null,
|
|
110
|
+
ContentType: req.headers['content-type']?.toString() ?? null,
|
|
127
111
|
Referer: req.headers['referer']?.toString() ?? null,
|
|
128
|
-
UserAgent: req.headers['
|
|
112
|
+
UserAgent: req.headers['user-agent']?.toString() ?? null
|
|
129
113
|
};
|
|
130
114
|
const { body, files } = excludeBufferKeys(req.body ?? {});
|
|
131
|
-
return req.savedReq
|
|
115
|
+
return req.savedReq ||= new requests_1.Request({
|
|
132
116
|
ip: req.ip,
|
|
133
117
|
body,
|
|
134
118
|
cookies: req.cookies ?? {},
|
|
@@ -138,15 +122,14 @@ class FastifyServer extends base_1.Server {
|
|
|
138
122
|
path: req.url,
|
|
139
123
|
headers,
|
|
140
124
|
files,
|
|
141
|
-
}, res.raw)
|
|
125
|
+
}, res.raw);
|
|
142
126
|
}
|
|
143
127
|
makeController(cb) {
|
|
144
128
|
const handler = async (req, reply) => {
|
|
145
129
|
const rawResponse = await cb(await this.parse(req, reply));
|
|
146
130
|
const response = rawResponse instanceof requests_1.Response ? rawResponse : new requests_1.Response({ body: rawResponse });
|
|
147
|
-
const type = response.shouldJSONify ? 'json' : 'send';
|
|
148
131
|
if (!response.piped)
|
|
149
|
-
reply.status(response.status).headers(response.headers)
|
|
132
|
+
reply.status(response.status).headers(response.headers).send(response.body);
|
|
150
133
|
};
|
|
151
134
|
return handler;
|
|
152
135
|
}
|
|
@@ -167,7 +150,6 @@ class FastifyServer extends base_1.Server {
|
|
|
167
150
|
}
|
|
168
151
|
}
|
|
169
152
|
exports.FastifyServer = FastifyServer;
|
|
170
|
-
_FastifyServer_fastifyApp = new WeakMap();
|
|
171
153
|
function excludeBufferKeys(body) {
|
|
172
154
|
if (typeof body !== 'object')
|
|
173
155
|
return { body: body, files: {} };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const errorHandler: {
|
|
2
|
-
cb: import("../types").ErrorHandler<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string,
|
|
3
|
-
onSetup?: import("../types").HandlerSetup
|
|
2
|
+
cb: import("../types").ErrorHandler<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string, string>, Record<string, any>, Record<string, string | string[]>, Record<string, string | string[]>, import("../types").SupportedStatusCodes>>;
|
|
3
|
+
onSetup?: import("../types").HandlerSetup;
|
|
4
4
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const notFoundHandler: {
|
|
2
|
-
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string,
|
|
3
|
-
onSetup?: import("../types").HandlerSetup
|
|
2
|
+
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string, string>, Record<string, any>, Record<string, string | string[]>, Record<string, string | string[]>, import("../types").SupportedStatusCodes>>;
|
|
3
|
+
onSetup?: import("../types").HandlerSetup;
|
|
4
4
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const parseAuthUser: {
|
|
2
|
-
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string,
|
|
3
|
-
onSetup?: import("../types").HandlerSetup
|
|
2
|
+
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string, string>, Record<string, any>, Record<string, string | string[]>, Record<string, string | string[]>, import("../types").SupportedStatusCodes>>;
|
|
3
|
+
onSetup?: import("../types").HandlerSetup;
|
|
4
4
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const requireAuthUser: {
|
|
2
|
-
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string,
|
|
3
|
-
onSetup?: import("../types").HandlerSetup
|
|
2
|
+
cb: import("../types").RouteMiddlewareHandler<import("../types").Api<any, string, import("../types").MethodTypes, any, Record<string, string>, Record<string, any>, Record<string, string | string[]>, Record<string, string | string[]>, import("../types").SupportedStatusCodes>>;
|
|
3
|
+
onSetup?: import("../types").HandlerSetup;
|
|
4
4
|
};
|