@bool-ts/core 1.1.1 → 1.2.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/LICENSE +21 -21
- package/__test/controller.ts +64 -63
- package/__test/index.ts +11 -11
- package/__test/interfaces.ts +7 -7
- package/__test/module.ts +17 -17
- package/__test/repository.ts +16 -16
- package/__test/service.ts +20 -20
- package/bun.lockb +0 -0
- package/dist/decorators/controller.js +10 -6
- package/dist/decorators/http.js +34 -25
- package/dist/decorators/index.js +23 -5
- package/dist/decorators/inject.js +9 -5
- package/dist/decorators/injectable.js +8 -4
- package/dist/decorators/module.d.ts +1 -0
- package/dist/decorators/module.js +8 -4
- package/dist/hooks/factory.d.ts +1 -0
- package/dist/hooks/factory.js +66 -35
- package/dist/hooks/index.js +7 -2
- package/dist/hooks/injector.js +10 -7
- package/dist/http/clientError.js +7 -3
- package/dist/http/index.js +25 -7
- package/dist/http/serverError.js +7 -3
- package/dist/index.js +21 -5
- package/dist/interfaces/index.js +3 -1
- package/package.json +2 -2
- package/src/decorators/controller.ts +18 -18
- package/src/decorators/http.ts +185 -185
- package/src/decorators/index.ts +5 -5
- package/src/decorators/inject.ts +19 -19
- package/src/decorators/injectable.ts +12 -12
- package/src/decorators/module.ts +22 -21
- package/src/hooks/factory.ts +199 -193
- package/src/hooks/index.ts +2 -2
- package/src/hooks/injector.ts +43 -43
- package/src/http/clientError.ts +57 -57
- package/src/http/index.ts +68 -68
- package/src/http/serverError.ts +39 -39
- package/src/index.ts +6 -6
- package/src/interfaces/index.ts +3 -3
- package/test.http +28 -28
- package/tsconfig.json +108 -108
package/src/hooks/factory.ts
CHANGED
|
@@ -1,193 +1,199 @@
|
|
|
1
|
-
import "reflect-metadata";
|
|
2
|
-
import "colors";
|
|
3
|
-
|
|
4
|
-
import * as Qs from "qs";
|
|
5
|
-
import * as ResponseTime from "response-time";
|
|
6
|
-
|
|
7
|
-
import { type IControllerRoute, type TModuleOptions, controllerKey, controllerRoutesKey, moduleKey } from "../decorators";
|
|
8
|
-
import { default as ExpressApp, Router, json, urlencoded, Request, Response, NextFunction, Errback } from "express";
|
|
9
|
-
import { Injector } from "./injector";
|
|
10
|
-
import { errorInfer } from "../http";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export type TBoolFactoryOptions = Partial<{
|
|
14
|
-
debug: boolean;
|
|
15
|
-
log: Partial<{
|
|
16
|
-
methods: Array<"GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS">;
|
|
17
|
-
}>;
|
|
18
|
-
queryParser: Partial<{
|
|
19
|
-
depth: 10,
|
|
20
|
-
arrayLimit: 50
|
|
21
|
-
}>;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
*
|
|
28
|
-
* @param
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import "colors";
|
|
3
|
+
|
|
4
|
+
import * as Qs from "qs";
|
|
5
|
+
import * as ResponseTime from "response-time";
|
|
6
|
+
|
|
7
|
+
import { type IControllerRoute, type TModuleOptions, controllerKey, controllerRoutesKey, moduleKey } from "../decorators";
|
|
8
|
+
import { default as ExpressApp, Router, json, urlencoded, Request, Response, NextFunction, Errback } from "express";
|
|
9
|
+
import { Injector } from "./injector";
|
|
10
|
+
import { errorInfer } from "../http";
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export type TBoolFactoryOptions = Partial<{
|
|
14
|
+
debug: boolean;
|
|
15
|
+
log: Partial<{
|
|
16
|
+
methods: Array<"GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS">;
|
|
17
|
+
}>;
|
|
18
|
+
queryParser: Partial<{
|
|
19
|
+
depth: 10,
|
|
20
|
+
arrayLimit: 50
|
|
21
|
+
}>;
|
|
22
|
+
prefix: string;
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* @param target
|
|
29
|
+
* @param router
|
|
30
|
+
*/
|
|
31
|
+
const controllerCreator = (
|
|
32
|
+
controllerConstructor: new (...args: any[]) => unknown,
|
|
33
|
+
parentRouter: Router = Router()
|
|
34
|
+
) => {
|
|
35
|
+
if (!Reflect.getOwnMetadataKeys(controllerConstructor).includes(controllerKey)) {
|
|
36
|
+
throw Error(`${controllerConstructor.name} is not a controller.`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const controller = Injector.get(controllerConstructor);
|
|
40
|
+
|
|
41
|
+
if (!controller) {
|
|
42
|
+
throw Error("Can not initialize controller.");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const controllerMetadata = Reflect.getOwnMetadata(controllerKey, controllerConstructor) || "/";
|
|
46
|
+
const routesMetadata = (Reflect.getOwnMetadata(controllerRoutesKey, controllerConstructor) || []) as Array<IControllerRoute>;
|
|
47
|
+
const router = Router();
|
|
48
|
+
|
|
49
|
+
routesMetadata.forEach(routeMetadata => {
|
|
50
|
+
if (typeof routeMetadata.descriptor.value !== "function") {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const route = router.route(routeMetadata.path);
|
|
55
|
+
|
|
56
|
+
switch (routeMetadata.httpMethod) {
|
|
57
|
+
case "GET":
|
|
58
|
+
return route.get(routeMetadata.descriptor.value.bind(controller));
|
|
59
|
+
case "POST":
|
|
60
|
+
return route.post(routeMetadata.descriptor.value.bind(controller));
|
|
61
|
+
case "PUT":
|
|
62
|
+
return route.put(routeMetadata.descriptor.value.bind(controller));
|
|
63
|
+
case "PATCH":
|
|
64
|
+
return route.patch(routeMetadata.descriptor.value.bind(controller));
|
|
65
|
+
case "DELETE":
|
|
66
|
+
return route.delete(routeMetadata.descriptor.value.bind(controller));
|
|
67
|
+
case "OPTIONS":
|
|
68
|
+
return route.options(routeMetadata.descriptor.value.bind(controller));
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return parentRouter.use(controllerMetadata, router);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @param target
|
|
79
|
+
*/
|
|
80
|
+
export const BoolFactory = (
|
|
81
|
+
target: new (...args: any[]) => unknown,
|
|
82
|
+
options?: TBoolFactoryOptions
|
|
83
|
+
) => {
|
|
84
|
+
if (!Reflect.getOwnMetadataKeys(target).includes(moduleKey)) {
|
|
85
|
+
throw Error(`${target.name} is not a module.`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const metadata = Reflect.getOwnMetadata(moduleKey, target) as TModuleOptions;
|
|
89
|
+
const allowOrigins = !metadata?.allowOrigins ?
|
|
90
|
+
["*"] : typeof metadata.allowOrigins !== "string" ?
|
|
91
|
+
metadata.allowOrigins : [metadata.allowOrigins];
|
|
92
|
+
const allowMethods = !metadata?.allowMethods ?
|
|
93
|
+
["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] : metadata.allowMethods;
|
|
94
|
+
const app = ExpressApp();
|
|
95
|
+
const factoryOptions = Object.freeze({
|
|
96
|
+
allowLogsMethods: !options?.log?.methods ? ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] : options.log.methods
|
|
97
|
+
});
|
|
98
|
+
const routers = !metadata?.controllers ?
|
|
99
|
+
[] : metadata.controllers.map(controllerConstructor => controllerCreator(controllerConstructor));
|
|
100
|
+
|
|
101
|
+
app.set("etag", "strong");
|
|
102
|
+
app.set("query parser", (query: string) => Qs.parse(query, {
|
|
103
|
+
depth: !options?.queryParser?.depth || options.queryParser.depth < 0 ? 10 : options.queryParser.depth,
|
|
104
|
+
arrayLimit: !options?.queryParser?.arrayLimit || options.queryParser.arrayLimit < 0 ? 50 : options.queryParser.arrayLimit
|
|
105
|
+
}));
|
|
106
|
+
|
|
107
|
+
app.use(
|
|
108
|
+
urlencoded({
|
|
109
|
+
extended: true,
|
|
110
|
+
inflate: true,
|
|
111
|
+
limit: "1mb",
|
|
112
|
+
parameterLimit: 20,
|
|
113
|
+
type: "application/x-www-form-urlencoded",
|
|
114
|
+
verify: undefined
|
|
115
|
+
}),
|
|
116
|
+
json({
|
|
117
|
+
inflate: true,
|
|
118
|
+
limit: "5mb",
|
|
119
|
+
reviver: undefined,
|
|
120
|
+
strict: true,
|
|
121
|
+
type: "application/json",
|
|
122
|
+
verify: undefined
|
|
123
|
+
}),
|
|
124
|
+
// Headers parser
|
|
125
|
+
(req: Request, res: Response, next: NextFunction) => {
|
|
126
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
127
|
+
req.headers[key] = typeof value !== "string" ? value : decodeURI(value)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
next();
|
|
131
|
+
},
|
|
132
|
+
// Body parser
|
|
133
|
+
(req: Request, res: Response, next: NextFunction) => {
|
|
134
|
+
if (typeof req.body !== "object" || !req.body) {
|
|
135
|
+
req.body = Object.freeze({});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
next();
|
|
139
|
+
},
|
|
140
|
+
// Error catcher
|
|
141
|
+
(err: Errback, req: Request, res: Response, next: NextFunction) => {
|
|
142
|
+
errorInfer(res, err);
|
|
143
|
+
|
|
144
|
+
if (!options?.debug) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
console.error("Headers:", JSON.stringify(req.headers), "\nBody:", JSON.stringify(req.body), "\nError:", JSON.stringify(err));
|
|
149
|
+
},
|
|
150
|
+
// Response time log
|
|
151
|
+
ResponseTime.default((req: Request, res: Response, time: number) => {
|
|
152
|
+
const requestMethod = req.method.toUpperCase();
|
|
153
|
+
|
|
154
|
+
if (!factoryOptions.allowLogsMethods.includes(requestMethod)) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const convertedMethod = `${requestMethod.yellow}`.bgBlue;
|
|
159
|
+
const convertedPID = `${process.pid}`.yellow;
|
|
160
|
+
const convertedReqIp = `${req.headers["x-forwarded-for"] || req.headers["x-real-ip"] || req.ip || "<Unknown>"}`.yellow;
|
|
161
|
+
const convertedTime = `${Math.round((time + Number.EPSILON) * 10 ** 2) / 10 ** 2}ms`.yellow;
|
|
162
|
+
|
|
163
|
+
console.info(`PID: ${convertedPID} - Method: ${convertedMethod} - IP: ${convertedReqIp} - ${req.originalUrl.blue} - Time: ${convertedTime}`);
|
|
164
|
+
})
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
app.use((req: Request, res: Response, next: NextFunction) => {
|
|
168
|
+
if (!allowOrigins.includes("*")) {
|
|
169
|
+
if (!allowOrigins.includes(req.headers.origin || "*")) {
|
|
170
|
+
return res.status(403).json({
|
|
171
|
+
httpCode: 403,
|
|
172
|
+
data: {
|
|
173
|
+
origin: {
|
|
174
|
+
code: "origin:invalid:0x00001",
|
|
175
|
+
message: "Invalid origin."
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
res.header("Access-Control-Allow-Origin", req.headers.origin || "*");
|
|
183
|
+
res.header("Access-Control-Allow-Headers", "*");
|
|
184
|
+
res.header("Access-Control-Allow-Credentials", "true");
|
|
185
|
+
res.header("Access-Control-Allow-Methods", allowMethods.join(", "));
|
|
186
|
+
|
|
187
|
+
next();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
if (routers.length > 0) {
|
|
191
|
+
!metadata?.prefix ?
|
|
192
|
+
app.use(routers) : app.use(!metadata.prefix.startsWith("/") ?
|
|
193
|
+
`/${metadata.prefix}` : metadata.prefix, routers);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return app;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export default BoolFactory;
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { BoolFactory } from "./factory";
|
|
2
|
-
export { Injector } from "./injector";
|
|
1
|
+
export { BoolFactory } from "./factory";
|
|
2
|
+
export { Injector } from "./injector";
|
package/src/hooks/injector.ts
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
import "reflect-metadata";
|
|
2
|
-
|
|
3
|
-
import { injectableKey, injectKey } from "../decorators";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
interface IInjector {
|
|
7
|
-
get<T>(classDefinition: { new(...args: any[]): T }): T
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const Injector: IInjector = new class {
|
|
11
|
-
|
|
12
|
-
private readonly _mapper: Map<Function, any> = new Map();
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
16
|
-
* @param constructor
|
|
17
|
-
*/
|
|
18
|
-
get<T>(
|
|
19
|
-
classDefinition: { new(...args: any[]): T }
|
|
20
|
-
) {
|
|
21
|
-
if (this._mapper.has(classDefinition)) {
|
|
22
|
-
return this._mapper.get(classDefinition) as T;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const ownMetadataKeys = Reflect.getMetadataKeys(classDefinition);
|
|
26
|
-
|
|
27
|
-
if (!ownMetadataKeys.includes(injectableKey)) {
|
|
28
|
-
throw Error("Missing dependency declaration, please check @Injectable() used on dependency(ies).");
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Initialize dependencies injection
|
|
32
|
-
const dependencies: any[] = Reflect.getOwnMetadata(injectKey, classDefinition) || [];
|
|
33
|
-
const injections: any[] = dependencies.map(dependency => Injector.get(dependency));
|
|
34
|
-
const instance = new classDefinition(...injections);
|
|
35
|
-
|
|
36
|
-
this._mapper.set(classDefinition, instance);
|
|
37
|
-
|
|
38
|
-
return instance;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default Injector;
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
|
|
3
|
+
import { injectableKey, injectKey } from "../decorators";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
interface IInjector {
|
|
7
|
+
get<T>(classDefinition: { new(...args: any[]): T }): T
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const Injector: IInjector = new class {
|
|
11
|
+
|
|
12
|
+
private readonly _mapper: Map<Function, any> = new Map();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param constructor
|
|
17
|
+
*/
|
|
18
|
+
get<T>(
|
|
19
|
+
classDefinition: { new(...args: any[]): T }
|
|
20
|
+
) {
|
|
21
|
+
if (this._mapper.has(classDefinition)) {
|
|
22
|
+
return this._mapper.get(classDefinition) as T;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const ownMetadataKeys = Reflect.getMetadataKeys(classDefinition);
|
|
26
|
+
|
|
27
|
+
if (!ownMetadataKeys.includes(injectableKey)) {
|
|
28
|
+
throw Error("Missing dependency declaration, please check @Injectable() used on dependency(ies).");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Initialize dependencies injection
|
|
32
|
+
const dependencies: any[] = Reflect.getOwnMetadata(injectKey, classDefinition) || [];
|
|
33
|
+
const injections: any[] = dependencies.map(dependency => Injector.get(dependency));
|
|
34
|
+
const instance = new classDefinition(...injections);
|
|
35
|
+
|
|
36
|
+
this._mapper.set(classDefinition, instance);
|
|
37
|
+
|
|
38
|
+
return instance;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default Injector;
|
package/src/http/clientError.ts
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
import * as ExpressJS from "express";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const httpClientErrors = Object.freeze({
|
|
5
|
-
400: "BAD_REQUEST",
|
|
6
|
-
401: "UNAUTHORIZED",
|
|
7
|
-
402: "PAYMENT_REQUIRED",
|
|
8
|
-
403: "FORBIDDEN",
|
|
9
|
-
404: "NOT_FOUND",
|
|
10
|
-
405: "METHOD_NOT_ALLOWED",
|
|
11
|
-
406: "NOT_ACCEPTABLE",
|
|
12
|
-
407: "PROXY_AUTHENCATION_REQUIRED",
|
|
13
|
-
408: "REQUEST_TIMEOUT",
|
|
14
|
-
409: "CONFLICT",
|
|
15
|
-
410: "GONE",
|
|
16
|
-
411: "LENGTH_REQUIRED",
|
|
17
|
-
412: "PRECONDITION_FAILED",
|
|
18
|
-
413: "PAYLOAD_TOO_LARGE",
|
|
19
|
-
414: "URI_TOO_LONG",
|
|
20
|
-
415: "UNSUPPORTED_MEDIA_TYPE",
|
|
21
|
-
416: "RANGE_NOT_SATISFIABLE",
|
|
22
|
-
417: "EXPECTATION_FAILED",
|
|
23
|
-
418: "IM_A_TEAPOT",
|
|
24
|
-
421: "MISDIRECTED_REQUEST",
|
|
25
|
-
422: "UNPROCESSABLE_ENTITY",
|
|
26
|
-
423: "LOCKED",
|
|
27
|
-
424: "FAILED_DEPENDENCY",
|
|
28
|
-
425: "TOO_EARLY_",
|
|
29
|
-
426: "UPGRAGE_REQUIRED",
|
|
30
|
-
428: "PRECONDITION_REQUIRED",
|
|
31
|
-
429: "TOO_MANY_REQUESTS",
|
|
32
|
-
431: "REQUEST_HEADER_FIELDS_TOO_LARGE",
|
|
33
|
-
451: "UNAVAILABLE_FOR_LEGAL_REASONS"
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
export class HttpClientError<
|
|
37
|
-
T extends keyof typeof httpClientErrors = keyof typeof httpClientErrors,
|
|
38
|
-
K = any
|
|
39
|
-
> extends Error {
|
|
40
|
-
public readonly httpCode: T;
|
|
41
|
-
public readonly message: typeof httpClientErrors[T];
|
|
42
|
-
public readonly data: K;
|
|
43
|
-
|
|
44
|
-
constructor({
|
|
45
|
-
httpCode,
|
|
46
|
-
data
|
|
47
|
-
}: {
|
|
48
|
-
["httpCode"]: T;
|
|
49
|
-
["data"]: K;
|
|
50
|
-
}) {
|
|
51
|
-
super();
|
|
52
|
-
|
|
53
|
-
this.httpCode = httpCode;
|
|
54
|
-
this.message = httpClientErrors[httpCode];
|
|
55
|
-
this.data = data;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
1
|
+
import * as ExpressJS from "express";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export const httpClientErrors = Object.freeze({
|
|
5
|
+
400: "BAD_REQUEST",
|
|
6
|
+
401: "UNAUTHORIZED",
|
|
7
|
+
402: "PAYMENT_REQUIRED",
|
|
8
|
+
403: "FORBIDDEN",
|
|
9
|
+
404: "NOT_FOUND",
|
|
10
|
+
405: "METHOD_NOT_ALLOWED",
|
|
11
|
+
406: "NOT_ACCEPTABLE",
|
|
12
|
+
407: "PROXY_AUTHENCATION_REQUIRED",
|
|
13
|
+
408: "REQUEST_TIMEOUT",
|
|
14
|
+
409: "CONFLICT",
|
|
15
|
+
410: "GONE",
|
|
16
|
+
411: "LENGTH_REQUIRED",
|
|
17
|
+
412: "PRECONDITION_FAILED",
|
|
18
|
+
413: "PAYLOAD_TOO_LARGE",
|
|
19
|
+
414: "URI_TOO_LONG",
|
|
20
|
+
415: "UNSUPPORTED_MEDIA_TYPE",
|
|
21
|
+
416: "RANGE_NOT_SATISFIABLE",
|
|
22
|
+
417: "EXPECTATION_FAILED",
|
|
23
|
+
418: "IM_A_TEAPOT",
|
|
24
|
+
421: "MISDIRECTED_REQUEST",
|
|
25
|
+
422: "UNPROCESSABLE_ENTITY",
|
|
26
|
+
423: "LOCKED",
|
|
27
|
+
424: "FAILED_DEPENDENCY",
|
|
28
|
+
425: "TOO_EARLY_",
|
|
29
|
+
426: "UPGRAGE_REQUIRED",
|
|
30
|
+
428: "PRECONDITION_REQUIRED",
|
|
31
|
+
429: "TOO_MANY_REQUESTS",
|
|
32
|
+
431: "REQUEST_HEADER_FIELDS_TOO_LARGE",
|
|
33
|
+
451: "UNAVAILABLE_FOR_LEGAL_REASONS"
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export class HttpClientError<
|
|
37
|
+
T extends keyof typeof httpClientErrors = keyof typeof httpClientErrors,
|
|
38
|
+
K = any
|
|
39
|
+
> extends Error {
|
|
40
|
+
public readonly httpCode: T;
|
|
41
|
+
public readonly message: typeof httpClientErrors[T];
|
|
42
|
+
public readonly data: K;
|
|
43
|
+
|
|
44
|
+
constructor({
|
|
45
|
+
httpCode,
|
|
46
|
+
data
|
|
47
|
+
}: {
|
|
48
|
+
["httpCode"]: T;
|
|
49
|
+
["data"]: K;
|
|
50
|
+
}) {
|
|
51
|
+
super();
|
|
52
|
+
|
|
53
|
+
this.httpCode = httpCode;
|
|
54
|
+
this.message = httpClientErrors[httpCode];
|
|
55
|
+
this.data = data;
|
|
56
|
+
}
|
|
57
|
+
}
|