@bool-ts/core 2.1.2 → 2.2.0
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/README.md +1 -1
- package/dist/decorators/container.d.ts +1 -1
- package/dist/decorators/module.d.ts +1 -1
- package/dist/entities/application.d.ts +5 -4
- package/dist/entities/httpRoute.d.ts +46 -29
- package/dist/entities/httpRouter.d.ts +3 -1
- package/dist/entities/httpRouterGroup.d.ts +9 -5
- package/dist/http/clientError.d.ts +3 -3
- package/dist/http/index.d.ts +3 -11
- package/dist/http/serverError.d.ts +2 -2
- package/dist/index.js +6 -6
- package/dist/index.js.map +12 -12
- package/package.json +1 -1
- package/src/decorators/container.ts +1 -1
- package/src/decorators/module.ts +1 -1
- package/src/entities/application.ts +108 -70
- package/src/entities/httpRoute.ts +73 -166
- package/src/entities/httpRouter.ts +2 -4
- package/src/entities/httpRouterGroup.ts +16 -6
- package/src/http/clientError.ts +6 -3
- package/src/http/index.ts +26 -11
- package/src/http/serverError.ts +6 -3
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
1
|
import type { TArgumentsMetadataCollection } from "../decorators/arguments";
|
|
4
2
|
import type { THttpMethods } from "../http";
|
|
5
3
|
|
|
@@ -10,16 +8,25 @@ export type THttpRouteModel<T = unknown> = Readonly<{
|
|
|
10
8
|
argumentsMetadata: TArgumentsMetadataCollection;
|
|
11
9
|
}>;
|
|
12
10
|
|
|
11
|
+
const BASE_URL = "http://www.booljs.com";
|
|
12
|
+
|
|
13
13
|
export class HttpRoute {
|
|
14
14
|
public static rootPattern = ":([a-z0-9A-Z_-]{1,})";
|
|
15
15
|
public static innerRootPattern = "([a-z0-9A-Z_-]{1,})";
|
|
16
16
|
|
|
17
17
|
public readonly alias: string;
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
#map = new Map<THttpMethods, THttpRouteModel>();
|
|
20
|
+
#urlPattern: URLPattern;
|
|
21
|
+
|
|
22
|
+
constructor({ alias }: { alias: string }) {
|
|
23
|
+
const thinAlias = this._thinAlias(alias);
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
this
|
|
25
|
+
this.alias = thinAlias;
|
|
26
|
+
this.#urlPattern = new URLPattern({
|
|
27
|
+
pathname: thinAlias,
|
|
28
|
+
baseURL: BASE_URL
|
|
29
|
+
});
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
/**
|
|
@@ -28,162 +35,62 @@ export class HttpRoute {
|
|
|
28
35
|
* @param method
|
|
29
36
|
* @returns
|
|
30
37
|
*/
|
|
31
|
-
public test(
|
|
32
|
-
pathname: string,
|
|
33
|
-
method: keyof THttpMethods
|
|
34
|
-
):
|
|
35
|
-
| Readonly<{ parameters: Record<string, string>; model: THttpRouteModel }>
|
|
36
|
-
| false
|
|
37
|
-
| undefined {
|
|
38
|
+
public test({ pathname }: { pathname: string }): boolean {
|
|
38
39
|
try {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (!model) {
|
|
44
|
-
return undefined;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Compare splitted length
|
|
48
|
-
if (aliasSplitted.length !== currentPathNameSplitted.length) {
|
|
49
|
-
return undefined;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const parameters: Record<string, string> = Object();
|
|
53
|
-
const matchingRegex = this.alias.replace(
|
|
54
|
-
new RegExp(HttpRoute.rootPattern, "g"),
|
|
55
|
-
HttpRoute.innerRootPattern
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
if (!new RegExp(matchingRegex).test(this._thinAlias(pathname))) {
|
|
59
|
-
return undefined;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
for (let index = 0; index < aliasSplitted.length; index++) {
|
|
63
|
-
const aliasPart = aliasSplitted[index];
|
|
64
|
-
const pathnamePart = currentPathNameSplitted[index];
|
|
65
|
-
|
|
66
|
-
// Check pathmane path match a dynamic syntax, if no match => start compare equal or not
|
|
67
|
-
if (!new RegExp(HttpRoute.rootPattern, "g").test(aliasPart)) {
|
|
68
|
-
if (aliasPart !== pathnamePart) return undefined;
|
|
69
|
-
} else {
|
|
70
|
-
let isFailed = false;
|
|
71
|
-
|
|
72
|
-
aliasPart.replace(
|
|
73
|
-
new RegExp(HttpRoute.rootPattern, "g"),
|
|
74
|
-
(match, key, offset) => {
|
|
75
|
-
if (offset === 0) {
|
|
76
|
-
pathnamePart.replace(
|
|
77
|
-
new RegExp(HttpRoute.innerRootPattern, "g"),
|
|
78
|
-
(innerMatch, innerKey, innerOffset) => {
|
|
79
|
-
if (innerOffset === 0) {
|
|
80
|
-
Object.assign(parameters, {
|
|
81
|
-
[key]: innerMatch
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return innerMatch;
|
|
86
|
-
}
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return match;
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
if (isFailed) {
|
|
95
|
-
return undefined;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return Object.freeze({
|
|
103
|
-
parameters: parameters,
|
|
104
|
-
model: model
|
|
40
|
+
return this.#urlPattern.test({
|
|
41
|
+
pathname: this._thinAlias(pathname),
|
|
42
|
+
baseURL: BASE_URL
|
|
105
43
|
});
|
|
106
|
-
} catch (
|
|
107
|
-
console.error(
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error(error);
|
|
46
|
+
|
|
108
47
|
return false;
|
|
109
48
|
}
|
|
110
49
|
}
|
|
111
50
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
* @returns
|
|
117
|
-
*/
|
|
118
|
-
public isMatch(pathname: string, method: keyof THttpMethods) {
|
|
51
|
+
public exec({ pathname, method }: { pathname: string; method: THttpMethods }): Readonly<{
|
|
52
|
+
parameters: Record<string, string | undefined>;
|
|
53
|
+
model: THttpRouteModel;
|
|
54
|
+
}> | null {
|
|
119
55
|
try {
|
|
120
|
-
const
|
|
56
|
+
const model = this.#map.get(method);
|
|
121
57
|
|
|
122
|
-
if (!
|
|
123
|
-
return
|
|
58
|
+
if (!model) {
|
|
59
|
+
return null;
|
|
124
60
|
}
|
|
125
61
|
|
|
126
|
-
const
|
|
127
|
-
|
|
62
|
+
const inferResult = this.#urlPattern.exec({
|
|
63
|
+
pathname: this._thinAlias(pathname),
|
|
64
|
+
baseURL: BASE_URL
|
|
65
|
+
});
|
|
128
66
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return false;
|
|
67
|
+
if (!inferResult) {
|
|
68
|
+
return null;
|
|
132
69
|
}
|
|
133
70
|
|
|
134
|
-
const parameters =
|
|
135
|
-
|
|
136
|
-
for (let index = 0; index < aliasSplitted.length; index++) {
|
|
137
|
-
const aliasPart = aliasSplitted[index];
|
|
138
|
-
const pathnamePart = currentPathNameSplitted[index];
|
|
139
|
-
|
|
140
|
-
// Check pathmane path match a dynamic syntax, if no match => start compare equal or not
|
|
141
|
-
if (!new RegExp(HttpRoute.rootPattern, "g").test(aliasPart)) {
|
|
142
|
-
if (aliasPart !== pathnamePart) {
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
let isFailed = false;
|
|
147
|
-
|
|
148
|
-
aliasPart.replace(
|
|
149
|
-
new RegExp(HttpRoute.rootPattern, "g"),
|
|
150
|
-
(subString, key, value) => {
|
|
151
|
-
if (!new RegExp(value, "g").test(pathnamePart)) {
|
|
152
|
-
isFailed = true;
|
|
153
|
-
} else {
|
|
154
|
-
Object.assign(parameters, {
|
|
155
|
-
[key]: pathnamePart
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
return "";
|
|
159
|
-
}
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
if (isFailed) {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
71
|
+
const parameters = inferResult.pathname.groups;
|
|
166
72
|
|
|
167
|
-
|
|
168
|
-
|
|
73
|
+
return Object.freeze({
|
|
74
|
+
parameters: parameters,
|
|
75
|
+
model: model
|
|
76
|
+
});
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error(error);
|
|
169
79
|
|
|
170
|
-
return
|
|
171
|
-
} catch (err) {
|
|
172
|
-
console.error(err);
|
|
173
|
-
return undefined;
|
|
80
|
+
return null;
|
|
174
81
|
}
|
|
175
82
|
}
|
|
176
83
|
|
|
177
84
|
/**
|
|
178
85
|
*
|
|
179
|
-
* @param
|
|
86
|
+
* @param model
|
|
180
87
|
* @returns
|
|
181
88
|
*/
|
|
182
|
-
public get(
|
|
183
|
-
const currenTHttpRouteModel = this.
|
|
89
|
+
public get({ model }: { model: THttpRouteModel }) {
|
|
90
|
+
const currenTHttpRouteModel = this.#map.get("GET");
|
|
184
91
|
|
|
185
92
|
if (!currenTHttpRouteModel) {
|
|
186
|
-
this.
|
|
93
|
+
this.#map.set("GET", model);
|
|
187
94
|
}
|
|
188
95
|
|
|
189
96
|
return this;
|
|
@@ -191,14 +98,14 @@ export class HttpRoute {
|
|
|
191
98
|
|
|
192
99
|
/**
|
|
193
100
|
*
|
|
194
|
-
* @param
|
|
101
|
+
* @param model
|
|
195
102
|
* @returns
|
|
196
103
|
*/
|
|
197
|
-
public post(
|
|
198
|
-
const currenTHttpRouteModel = this.
|
|
104
|
+
public post({ model }: { model: THttpRouteModel }) {
|
|
105
|
+
const currenTHttpRouteModel = this.#map.get("POST");
|
|
199
106
|
|
|
200
107
|
if (!currenTHttpRouteModel) {
|
|
201
|
-
this.
|
|
108
|
+
this.#map.set("POST", model);
|
|
202
109
|
}
|
|
203
110
|
|
|
204
111
|
return this;
|
|
@@ -206,14 +113,14 @@ export class HttpRoute {
|
|
|
206
113
|
|
|
207
114
|
/**
|
|
208
115
|
*
|
|
209
|
-
* @param
|
|
116
|
+
* @param model
|
|
210
117
|
* @returns
|
|
211
118
|
*/
|
|
212
|
-
public put(
|
|
213
|
-
const currenTHttpRouteModel = this.
|
|
119
|
+
public put({ model }: { model: THttpRouteModel }) {
|
|
120
|
+
const currenTHttpRouteModel = this.#map.get("PUT");
|
|
214
121
|
|
|
215
122
|
if (!currenTHttpRouteModel) {
|
|
216
|
-
this.
|
|
123
|
+
this.#map.set("PUT", model);
|
|
217
124
|
}
|
|
218
125
|
|
|
219
126
|
return this;
|
|
@@ -221,14 +128,14 @@ export class HttpRoute {
|
|
|
221
128
|
|
|
222
129
|
/**
|
|
223
130
|
*
|
|
224
|
-
* @param
|
|
131
|
+
* @param model
|
|
225
132
|
* @returns
|
|
226
133
|
*/
|
|
227
|
-
public delete(
|
|
228
|
-
const currenTHttpRouteModel = this.
|
|
134
|
+
public delete({ model }: { model: THttpRouteModel }) {
|
|
135
|
+
const currenTHttpRouteModel = this.#map.get("DELETE");
|
|
229
136
|
|
|
230
137
|
if (!currenTHttpRouteModel) {
|
|
231
|
-
this.
|
|
138
|
+
this.#map.set("DELETE", model);
|
|
232
139
|
}
|
|
233
140
|
|
|
234
141
|
return this;
|
|
@@ -236,14 +143,14 @@ export class HttpRoute {
|
|
|
236
143
|
|
|
237
144
|
/**
|
|
238
145
|
*
|
|
239
|
-
* @param
|
|
146
|
+
* @param model
|
|
240
147
|
* @returns
|
|
241
148
|
*/
|
|
242
|
-
public connect(
|
|
243
|
-
const currenTHttpRouteModel = this.
|
|
149
|
+
public connect({ model }: { model: THttpRouteModel }) {
|
|
150
|
+
const currenTHttpRouteModel = this.#map.get("CONNECT");
|
|
244
151
|
|
|
245
152
|
if (!currenTHttpRouteModel) {
|
|
246
|
-
return this.
|
|
153
|
+
return this.#map.set("CONNECT", model);
|
|
247
154
|
}
|
|
248
155
|
|
|
249
156
|
return this;
|
|
@@ -251,14 +158,14 @@ export class HttpRoute {
|
|
|
251
158
|
|
|
252
159
|
/**
|
|
253
160
|
*
|
|
254
|
-
* @param
|
|
161
|
+
* @param model
|
|
255
162
|
* @returns
|
|
256
163
|
*/
|
|
257
|
-
public options(
|
|
258
|
-
const currenTHttpRouteModel = this.
|
|
164
|
+
public options({ model }: { model: THttpRouteModel }) {
|
|
165
|
+
const currenTHttpRouteModel = this.#map.get("OPTIONS");
|
|
259
166
|
|
|
260
167
|
if (!currenTHttpRouteModel) {
|
|
261
|
-
return this.
|
|
168
|
+
return this.#map.set("OPTIONS", model);
|
|
262
169
|
}
|
|
263
170
|
|
|
264
171
|
return this;
|
|
@@ -266,14 +173,14 @@ export class HttpRoute {
|
|
|
266
173
|
|
|
267
174
|
/**
|
|
268
175
|
*
|
|
269
|
-
* @param
|
|
176
|
+
* @param model
|
|
270
177
|
* @returns
|
|
271
178
|
*/
|
|
272
|
-
public trace(
|
|
273
|
-
const currenTHttpRouteModel = this.
|
|
179
|
+
public trace({ model }: { model: THttpRouteModel }) {
|
|
180
|
+
const currenTHttpRouteModel = this.#map.get("TRACE");
|
|
274
181
|
|
|
275
182
|
if (!currenTHttpRouteModel) {
|
|
276
|
-
return this.
|
|
183
|
+
return this.#map.set("TRACE", model);
|
|
277
184
|
}
|
|
278
185
|
|
|
279
186
|
return this;
|
|
@@ -281,14 +188,14 @@ export class HttpRoute {
|
|
|
281
188
|
|
|
282
189
|
/**
|
|
283
190
|
*
|
|
284
|
-
* @param
|
|
191
|
+
* @param model
|
|
285
192
|
* @returns
|
|
286
193
|
*/
|
|
287
|
-
public patch(
|
|
288
|
-
const currenTHttpRouteModel = this.
|
|
194
|
+
public patch({ model }: { model: THttpRouteModel }) {
|
|
195
|
+
const currenTHttpRouteModel = this.#map.get("PATCH");
|
|
289
196
|
|
|
290
197
|
if (!currenTHttpRouteModel) {
|
|
291
|
-
return this.
|
|
198
|
+
return this.#map.set("PATCH", model);
|
|
292
199
|
}
|
|
293
200
|
|
|
294
201
|
return this;
|
|
@@ -296,7 +203,7 @@ export class HttpRoute {
|
|
|
296
203
|
|
|
297
204
|
/**
|
|
298
205
|
*
|
|
299
|
-
* @param
|
|
206
|
+
* @param model
|
|
300
207
|
* @returns
|
|
301
208
|
*/
|
|
302
209
|
private _thinAlias(alias: string) {
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
1
|
import HttpRoute from "./httpRoute";
|
|
4
2
|
|
|
5
3
|
export class HttpRouter {
|
|
@@ -7,7 +5,7 @@ export class HttpRouter {
|
|
|
7
5
|
|
|
8
6
|
private _routes: Map<string, HttpRoute> = new Map();
|
|
9
7
|
|
|
10
|
-
constructor(alias: string) {
|
|
8
|
+
constructor({ alias }: { alias: string }) {
|
|
11
9
|
this.alias = this._thinAlias(alias);
|
|
12
10
|
}
|
|
13
11
|
|
|
@@ -19,7 +17,7 @@ export class HttpRouter {
|
|
|
19
17
|
public route(alias: string) {
|
|
20
18
|
const thinAlias = this._thinAlias(`${this.alias}/${alias}`);
|
|
21
19
|
const route = this._routes.get(thinAlias);
|
|
22
|
-
const newRoute = !route ? new HttpRoute(`${this.alias}/${alias}`) : route;
|
|
20
|
+
const newRoute = !route ? new HttpRoute({ alias: `${this.alias}/${alias}` }) : route;
|
|
23
21
|
|
|
24
22
|
if (!route) {
|
|
25
23
|
this._routes.set(thinAlias, newRoute);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { THttpMethods } from "../http";
|
|
2
|
+
import type { THttpRouteModel } from "./httpRoute";
|
|
2
3
|
import type { HttpRouter } from "./httpRouter";
|
|
3
4
|
|
|
4
5
|
export class HttpRouterGroup {
|
|
@@ -18,23 +19,32 @@ export class HttpRouterGroup {
|
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
*
|
|
21
|
-
* @param
|
|
22
|
+
* @param pathname
|
|
22
23
|
* @param method
|
|
23
24
|
* @returns
|
|
24
25
|
*/
|
|
25
|
-
public find(
|
|
26
|
+
public find({ pathname, method }: { pathname: string; method: THttpMethods }): Readonly<{
|
|
27
|
+
parameters: Record<string, string | undefined>;
|
|
28
|
+
model: THttpRouteModel;
|
|
29
|
+
}> | null {
|
|
26
30
|
for (const router of this._routers.values()) {
|
|
27
31
|
for (const route of router.routes.values()) {
|
|
28
|
-
const
|
|
32
|
+
const testResult = route.test({ pathname });
|
|
29
33
|
|
|
30
|
-
if (!
|
|
34
|
+
if (!testResult) {
|
|
31
35
|
continue;
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
const execResult = route.exec({ pathname, method });
|
|
39
|
+
|
|
40
|
+
if (!execResult) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return execResult;
|
|
35
45
|
}
|
|
36
46
|
}
|
|
37
47
|
|
|
38
|
-
return
|
|
48
|
+
return null;
|
|
39
49
|
}
|
|
40
50
|
}
|
package/src/http/clientError.ts
CHANGED
|
@@ -30,12 +30,15 @@ export const httpClientErrors = Object.freeze({
|
|
|
30
30
|
451: "UNAVAILABLE_FOR_LEGAL_REASONS"
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
export class HttpClientError<
|
|
33
|
+
export class HttpClientError<
|
|
34
|
+
T extends keyof typeof httpClientErrors = keyof typeof httpClientErrors,
|
|
35
|
+
K = unknown
|
|
36
|
+
> extends Error {
|
|
34
37
|
public readonly httpCode: T;
|
|
35
38
|
public readonly message: (typeof httpClientErrors)[T] | string;
|
|
36
|
-
public readonly data: K;
|
|
39
|
+
public readonly data: K | undefined;
|
|
37
40
|
|
|
38
|
-
constructor({ httpCode, data, message }: { httpCode: T; data
|
|
41
|
+
constructor({ httpCode, data, message }: { httpCode: T; data?: K; message?: string }) {
|
|
39
42
|
super();
|
|
40
43
|
|
|
41
44
|
this.httpCode = httpCode;
|
package/src/http/index.ts
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
import { HttpClientError } from "./clientError";
|
|
2
2
|
import { HttpServerError } from "./serverError";
|
|
3
3
|
|
|
4
|
-
export type THttpMethods =
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
export type THttpMethods =
|
|
5
|
+
| "GET"
|
|
6
|
+
| "HEAD"
|
|
7
|
+
| "POST"
|
|
8
|
+
| "PUT"
|
|
9
|
+
| "DELETE"
|
|
10
|
+
| "CONNECT"
|
|
11
|
+
| "OPTIONS"
|
|
12
|
+
| "TRACE"
|
|
13
|
+
| "PATCH";
|
|
14
|
+
|
|
15
|
+
export const httpMethods: Array<THttpMethods> = [
|
|
16
|
+
"GET",
|
|
17
|
+
"HEAD",
|
|
18
|
+
"POST",
|
|
19
|
+
"PUT",
|
|
20
|
+
"DELETE",
|
|
21
|
+
"CONNECT",
|
|
22
|
+
"OPTIONS",
|
|
23
|
+
"TRACE",
|
|
24
|
+
"PATCH"
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
export const httpMethodsStandardization = (method: string): method is THttpMethods =>
|
|
28
|
+
!!httpMethods.find((httpMethod) => httpMethod === method);
|
|
15
29
|
|
|
16
30
|
export const jsonErrorInfer = (data: any, headers: Headers = new Headers()) => {
|
|
17
31
|
headers.set("Content-Type", "application/json");
|
|
@@ -59,3 +73,4 @@ export const jsonErrorInfer = (data: any, headers: Headers = new Headers()) => {
|
|
|
59
73
|
|
|
60
74
|
export * from "./clientError";
|
|
61
75
|
export * from "./serverError";
|
|
76
|
+
|
package/src/http/serverError.ts
CHANGED
|
@@ -12,12 +12,15 @@ export const httpServerErrors = Object.freeze({
|
|
|
12
12
|
511: "NETWORK_AUTHENTICATION_REQUIRED"
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
export class HttpServerError<
|
|
15
|
+
export class HttpServerError<
|
|
16
|
+
T extends keyof typeof httpServerErrors = keyof typeof httpServerErrors,
|
|
17
|
+
K = any
|
|
18
|
+
> extends Error {
|
|
16
19
|
public readonly httpCode: T;
|
|
17
20
|
public readonly message: (typeof httpServerErrors)[T] | string;
|
|
18
|
-
public readonly data: K;
|
|
21
|
+
public readonly data: K | undefined;
|
|
19
22
|
|
|
20
|
-
constructor({ httpCode, data, message }: { httpCode: T; data
|
|
23
|
+
constructor({ httpCode, data, message }: { httpCode: T; data?: K; message?: string }) {
|
|
21
24
|
super();
|
|
22
25
|
|
|
23
26
|
this.httpCode = httpCode;
|