@bool-ts/core 1.3.0 → 1.3.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.
@@ -13,6 +13,13 @@ const getAbcSchema = Zod.object({
13
13
  })
14
14
  });
15
15
 
16
+ const stringSchema = Zod.object({}).refine(async (val) => {
17
+ const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
18
+ await delay(10000);
19
+
20
+ return val;
21
+ });
22
+
16
23
  @Controller("test")
17
24
  export class TestController {
18
25
  constructor(
@@ -56,8 +63,8 @@ export class TestController {
56
63
 
57
64
  @Delete()
58
65
  private _delete(
59
- @ZodSchema(getAbcSchema) req: Request,
60
- res: Response
66
+ req: Request,
67
+ @ZodSchema(stringSchema) res: Response
61
68
  ) {
62
69
  res.json({ test: "success" }).send();
63
70
  }
@@ -2,236 +2,140 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Options = exports.Delete = exports.Patch = exports.Put = exports.Post = exports.Get = exports.controllerRoutesKey = void 0;
4
4
  const http_1 = require("../http");
5
+ const ultils_1 = require("../ultils");
5
6
  const zodSchema_1 = require("./zodSchema");
6
7
  exports.controllerRoutesKey = "__bool:controller.routes__";
7
- /**
8
- *
9
- * @param path
10
- * @returns
11
- */
12
- const Get = (path = "/") => (target, methodName, descriptor) => {
13
- if (typeof descriptor.value !== "function") {
14
- throw Error("Get decorator only use for method.");
8
+ const defaultDecorator = (path, method) => (target, methodName, descriptor) => {
9
+ if (!(descriptor.value instanceof Function)) {
10
+ throw Error(`${method} decorator only use for method.`);
15
11
  }
16
12
  // Define controller metadata
17
13
  Reflect.defineMetadata(exports.controllerRoutesKey, [
18
14
  ...Reflect.getOwnMetadata(exports.controllerRoutesKey, target.constructor) || [],
19
15
  {
20
16
  path: !path.startsWith("/") ? `/${path}` : path,
21
- httpMethod: "GET",
17
+ httpMethod: method.toUpperCase(),
22
18
  methodName: methodName,
23
19
  descriptor: descriptor
24
20
  }
25
21
  ], target.constructor);
26
22
  // Define route parameters zod validation
27
23
  const currentMethod = descriptor.value;
28
- descriptor.value = function () {
29
- const zodSchemaMetadata = Reflect.getOwnMetadata(zodSchema_1.controllerRouteZodSchemaKey, target.constructor, methodName);
30
- if (zodSchemaMetadata) {
31
- for (const zodSchemaProp in zodSchemaMetadata) {
32
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
33
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
34
- if (!validation.success) {
35
- throw new http_1.HttpClientError({
36
- httpCode: 400,
37
- data: validation.error.issues
38
- });
24
+ const isAsync = descriptor.value instanceof ultils_1.AsyncFunction;
25
+ if (!isAsync) {
26
+ descriptor.value = function () {
27
+ const zodSchemaMetadata = Reflect.getOwnMetadata(zodSchema_1.controllerRouteZodSchemaKey, target.constructor, methodName);
28
+ if (zodSchemaMetadata) {
29
+ for (const zodSchemaProp in zodSchemaMetadata) {
30
+ const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
31
+ try {
32
+ const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
33
+ if (!validation.success) {
34
+ throw new http_1.HttpClientError({
35
+ httpCode: 400,
36
+ message: `Validation at the [${methodName}] method fails at positional argument [${tmpZodMetadata.index}].`,
37
+ data: validation.error.issues
38
+ });
39
+ }
40
+ arguments[tmpZodMetadata.index] = validation.data;
41
+ }
42
+ catch (error) {
43
+ if (error instanceof http_1.HttpClientError) {
44
+ throw error;
45
+ }
46
+ throw new http_1.HttpServerError({
47
+ httpCode: 500,
48
+ message: `Validation at the [${methodName}] method error at positional argument [${tmpZodMetadata.index}].`,
49
+ data: !(error instanceof Error) ? error : [{
50
+ message: error.message,
51
+ code: error.name,
52
+ cause: error.cause
53
+ }]
54
+ });
55
+ }
39
56
  }
40
57
  }
41
- }
42
- return currentMethod.apply(this, arguments);
43
- };
58
+ return currentMethod.apply(this, arguments);
59
+ };
60
+ }
61
+ else {
62
+ descriptor.value = async function () {
63
+ const zodSchemaMetadata = Reflect.getOwnMetadata(zodSchema_1.controllerRouteZodSchemaKey, target.constructor, methodName);
64
+ if (zodSchemaMetadata) {
65
+ for (const zodSchemaProp in zodSchemaMetadata) {
66
+ const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
67
+ try {
68
+ const validation = await tmpZodMetadata.schema.safeParseAsync(arguments[tmpZodMetadata.index]);
69
+ if (!validation.success) {
70
+ throw new http_1.HttpClientError({
71
+ httpCode: 400,
72
+ message: `Validation at the [${methodName}] method fails at positional argument [${tmpZodMetadata.index}].`,
73
+ data: validation.error.issues
74
+ });
75
+ }
76
+ arguments[tmpZodMetadata.index] = validation.data;
77
+ }
78
+ catch (error) {
79
+ if (error instanceof http_1.HttpClientError) {
80
+ throw error;
81
+ }
82
+ throw new http_1.HttpServerError({
83
+ httpCode: 500,
84
+ message: `Validation at the [${methodName}] method error at positional argument [${tmpZodMetadata.index}].`,
85
+ data: !(error instanceof Error) ? error : [{
86
+ message: error.message,
87
+ code: error.name,
88
+ cause: error.cause
89
+ }]
90
+ });
91
+ }
92
+ }
93
+ }
94
+ return currentMethod.apply(this, arguments);
95
+ };
96
+ }
44
97
  };
98
+ /**
99
+ *
100
+ * @param path
101
+ * @returns
102
+ */
103
+ const Get = (path = "/") => defaultDecorator(path, "Get");
45
104
  exports.Get = Get;
46
105
  /**
47
106
  *
48
107
  * @param path
49
108
  * @returns
50
109
  */
51
- const Post = (path = "/") => (target, methodName, descriptor) => {
52
- if (typeof descriptor.value !== "function") {
53
- throw Error("Post decorator only use for method.");
54
- }
55
- Reflect.defineMetadata(exports.controllerRoutesKey, [
56
- ...Reflect.getOwnMetadata(exports.controllerRoutesKey, target.constructor) || [],
57
- {
58
- path: !path.startsWith("/") ? `/${path}` : path,
59
- httpMethod: "POST",
60
- methodName: methodName,
61
- descriptor: descriptor
62
- }
63
- ], target.constructor);
64
- // Define route parameters zod validation
65
- const currentMethod = descriptor.value;
66
- descriptor.value = function () {
67
- const zodSchemaMetadata = Reflect.getOwnMetadata(zodSchema_1.controllerRouteZodSchemaKey, target.constructor, methodName);
68
- if (zodSchemaMetadata) {
69
- for (const zodSchemaProp in zodSchemaMetadata) {
70
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
71
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
72
- if (!validation.success) {
73
- throw new http_1.HttpClientError({
74
- httpCode: 400,
75
- data: validation.error.issues
76
- });
77
- }
78
- }
79
- }
80
- return currentMethod.apply(this, arguments);
81
- };
82
- };
110
+ const Post = (path = "/") => defaultDecorator(path, "Post");
83
111
  exports.Post = Post;
84
112
  /**
85
113
  *
86
114
  * @param path
87
115
  * @returns
88
116
  */
89
- const Put = (path = "/") => (target, methodName, descriptor) => {
90
- if (typeof descriptor.value !== "function") {
91
- throw Error("Put decorator only use for method.");
92
- }
93
- Reflect.defineMetadata(exports.controllerRoutesKey, [
94
- ...Reflect.getOwnMetadata(exports.controllerRoutesKey, target.constructor) || [],
95
- {
96
- path: !path.startsWith("/") ? `/${path}` : path,
97
- httpMethod: "PUT",
98
- methodName: methodName,
99
- descriptor: descriptor
100
- }
101
- ], target.constructor);
102
- // Define route parameters zod validation
103
- const currentMethod = descriptor.value;
104
- descriptor.value = function () {
105
- const zodSchemaMetadata = Reflect.getOwnMetadata(zodSchema_1.controllerRouteZodSchemaKey, target.constructor, methodName);
106
- if (zodSchemaMetadata) {
107
- for (const zodSchemaProp in zodSchemaMetadata) {
108
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
109
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
110
- if (!validation.success) {
111
- throw new http_1.HttpClientError({
112
- httpCode: 400,
113
- data: validation.error.issues
114
- });
115
- }
116
- }
117
- }
118
- return currentMethod.apply(this, arguments);
119
- };
120
- };
117
+ const Put = (path = "/") => defaultDecorator(path, "Put");
121
118
  exports.Put = Put;
122
119
  /**
123
120
  *
124
121
  * @param path
125
122
  * @returns
126
123
  */
127
- const Patch = (path = "/") => (target, methodName, descriptor) => {
128
- if (typeof descriptor.value !== "function") {
129
- throw Error("Patch decorator only use for method.");
130
- }
131
- Reflect.defineMetadata(exports.controllerRoutesKey, [
132
- ...Reflect.getOwnMetadata(exports.controllerRoutesKey, target.constructor) || [],
133
- {
134
- path: !path.startsWith("/") ? `/${path}` : path,
135
- httpMethod: "PATCH",
136
- methodName: methodName,
137
- descriptor: descriptor
138
- }
139
- ], target.constructor);
140
- // Define route parameters zod validation
141
- const currentMethod = descriptor.value;
142
- descriptor.value = function () {
143
- const zodSchemaMetadata = Reflect.getOwnMetadata(zodSchema_1.controllerRouteZodSchemaKey, target.constructor, methodName);
144
- if (zodSchemaMetadata) {
145
- for (const zodSchemaProp in zodSchemaMetadata) {
146
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
147
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
148
- if (!validation.success) {
149
- throw new http_1.HttpClientError({
150
- httpCode: 400,
151
- data: validation.error.issues
152
- });
153
- }
154
- }
155
- }
156
- return currentMethod.apply(this, arguments);
157
- };
158
- };
124
+ const Patch = (path = "/") => defaultDecorator(path, "Patch");
159
125
  exports.Patch = Patch;
160
126
  /**
161
127
  *
162
128
  * @param path
163
129
  * @returns
164
130
  */
165
- const Delete = (path = "/") => (target, methodName, descriptor) => {
166
- if (typeof descriptor.value !== "function") {
167
- throw Error("Delete decorator only use for method.");
168
- }
169
- Reflect.defineMetadata(exports.controllerRoutesKey, [
170
- ...Reflect.getOwnMetadata(exports.controllerRoutesKey, target.constructor) || [],
171
- {
172
- path: !path.startsWith("/") ? `/${path}` : path,
173
- httpMethod: "DELETE",
174
- methodName: methodName,
175
- descriptor: descriptor
176
- }
177
- ], target.constructor);
178
- // Define route parameters zod validation
179
- const currentMethod = descriptor.value;
180
- descriptor.value = function () {
181
- const zodSchemaMetadata = Reflect.getOwnMetadata(zodSchema_1.controllerRouteZodSchemaKey, target.constructor, methodName);
182
- if (zodSchemaMetadata) {
183
- for (const zodSchemaProp in zodSchemaMetadata) {
184
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
185
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
186
- if (!validation.success) {
187
- throw new http_1.HttpClientError({
188
- httpCode: 400,
189
- data: validation.error.issues
190
- });
191
- }
192
- }
193
- }
194
- return currentMethod.apply(this, arguments);
195
- };
196
- };
131
+ const Delete = (path = "/") => defaultDecorator(path, "Delete");
197
132
  exports.Delete = Delete;
198
133
  /**
199
134
  *
200
135
  * @param path
201
136
  * @returns
202
137
  */
203
- const Options = (path = "/") => (target, methodName, descriptor) => {
204
- if (typeof descriptor.value !== "function") {
205
- throw Error("Options decorator only use for method.");
206
- }
207
- Reflect.defineMetadata(exports.controllerRoutesKey, [
208
- ...Reflect.getOwnMetadata(exports.controllerRoutesKey, target.constructor) || [],
209
- {
210
- path: !path.startsWith("/") ? `/${path}` : path,
211
- httpMethod: "OPTIONS",
212
- methodName: methodName,
213
- descriptor: descriptor
214
- }
215
- ], target.constructor);
216
- // Define route parameters zod validation
217
- const currentMethod = descriptor.value;
218
- descriptor.value = function () {
219
- const zodSchemaMetadata = Reflect.getOwnMetadata(zodSchema_1.controllerRouteZodSchemaKey, target.constructor, methodName);
220
- if (zodSchemaMetadata) {
221
- for (const zodSchemaProp in zodSchemaMetadata) {
222
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
223
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
224
- if (!validation.success) {
225
- throw new http_1.HttpClientError({
226
- httpCode: 400,
227
- data: validation.error.issues
228
- });
229
- }
230
- }
231
- }
232
- return currentMethod.apply(this, arguments);
233
- };
234
- };
138
+ const Options = (path = "/") => defaultDecorator(path, "Options");
235
139
  exports.Options = Options;
236
140
  exports.default = {
237
141
  Get: exports.Get,
@@ -3,12 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZodSchema = exports.controllerRouteZodSchemaKey = void 0;
4
4
  exports.controllerRouteZodSchemaKey = "__bool:controller.route.zodSchema__";
5
5
  const ZodSchema = (schema) => {
6
- try {
7
- schema.safeParse(undefined);
8
- }
9
- catch (err) {
10
- throw Error("Zod schema parameter do not allow async.");
11
- }
12
6
  return (target, methodName, parameterIndex) => {
13
7
  if (!methodName) {
14
8
  return;
@@ -169,7 +169,9 @@ const BoolFactory = (target, options) => {
169
169
  if (!options?.debug) {
170
170
  return;
171
171
  }
172
- console.error("Headers:", JSON.stringify(req.headers), "\nBody:", JSON.stringify(req.body), "\nError:", JSON.stringify(err));
172
+ console.info("Headers:", JSON.stringify(req.headers, null, 4), "\nBody:", JSON.stringify(req.body, null, 4));
173
+ console.error("Error:");
174
+ console.error(err);
173
175
  });
174
176
  return app;
175
177
  };
@@ -31,10 +31,11 @@ export declare const httpClientErrors: Readonly<{
31
31
  }>;
32
32
  export declare class HttpClientError<T extends keyof typeof httpClientErrors = keyof typeof httpClientErrors, K = any> extends Error {
33
33
  readonly httpCode: T;
34
- readonly message: typeof httpClientErrors[T];
34
+ readonly message: typeof httpClientErrors[T] | string;
35
35
  readonly data: K;
36
- constructor({ httpCode, data }: {
37
- ["httpCode"]: T;
38
- ["data"]: K;
36
+ constructor({ httpCode, data, message }: {
37
+ httpCode: T;
38
+ data: K;
39
+ message?: string;
39
40
  });
40
41
  }
@@ -36,10 +36,10 @@ class HttpClientError extends Error {
36
36
  httpCode;
37
37
  message;
38
38
  data;
39
- constructor({ httpCode, data }) {
39
+ constructor({ httpCode, data, message }) {
40
40
  super();
41
41
  this.httpCode = httpCode;
42
- this.message = exports.httpClientErrors[httpCode];
42
+ this.message = !message?.trim() ? exports.httpClientErrors[httpCode] : message.trim();
43
43
  this.data = data;
44
44
  }
45
45
  }
@@ -34,7 +34,11 @@ const errorInfer = (res, data) => {
34
34
  res.status(500).json({
35
35
  httpCode: 500,
36
36
  message: "INTERNAL SERVER ERROR",
37
- data: data
37
+ data: !(data instanceof Error) ? data : {
38
+ message: data.message,
39
+ code: data.name,
40
+ cause: data.cause
41
+ }
38
42
  });
39
43
  return;
40
44
  }
@@ -13,10 +13,11 @@ export declare const httpServerErrors: Readonly<{
13
13
  }>;
14
14
  export declare class HttpServerError<T extends keyof typeof httpServerErrors = keyof typeof httpServerErrors, K = any> extends Error {
15
15
  readonly httpCode: T;
16
- readonly message: typeof httpServerErrors[T];
16
+ readonly message: typeof httpServerErrors[T] | string;
17
17
  readonly data: K;
18
- constructor({ httpCode, data }: {
19
- ["httpCode"]: T;
20
- ["data"]: K;
18
+ constructor({ httpCode, data, message }: {
19
+ httpCode: T;
20
+ data: K;
21
+ message?: string;
21
22
  });
22
23
  }
@@ -18,10 +18,10 @@ class HttpServerError extends Error {
18
18
  httpCode;
19
19
  message;
20
20
  data;
21
- constructor({ httpCode, data }) {
21
+ constructor({ httpCode, data, message }) {
22
22
  super();
23
23
  this.httpCode = httpCode;
24
- this.message = exports.httpServerErrors[httpCode];
24
+ this.message = !message?.trim() ? exports.httpServerErrors[httpCode] : message.trim();
25
25
  this.data = data;
26
26
  }
27
27
  }
@@ -0,0 +1 @@
1
+ export declare const AsyncFunction: Function;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AsyncFunction = void 0;
4
+ exports.AsyncFunction = async function () { }.constructor;
@@ -0,0 +1 @@
1
+ export * from "./asyncFunction";
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./asyncFunction"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bool-ts/core",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -1,4 +1,5 @@
1
- import { HttpClientError } from "../http";
1
+ import { HttpClientError, HttpServerError } from "../http";
2
+ import { AsyncFunction } from "../ultils";
2
3
  import { controllerRouteZodSchemaKey } from "./zodSchema";
3
4
 
4
5
  export interface IControllerRoute {
@@ -11,20 +12,17 @@ export interface IControllerRoute {
11
12
 
12
13
  export const controllerRoutesKey = "__bool:controller.routes__";
13
14
 
14
- /**
15
- *
16
- * @param path
17
- * @returns
18
- */
19
- export const Get = (
20
- path = "/"
15
+
16
+ const defaultDecorator = (
17
+ path: string,
18
+ method: "Get" | "Post" | "Put" | "Patch" | "Delete" | "Options"
21
19
  ) => (
22
20
  target: Object,
23
21
  methodName: string,
24
22
  descriptor: PropertyDescriptor
25
23
  ) => {
26
- if (typeof descriptor.value !== "function") {
27
- throw Error("Get decorator only use for method.");
24
+ if (!(descriptor.value instanceof Function)) {
25
+ throw Error(`${method} decorator only use for method.`);
28
26
  }
29
27
 
30
28
  // Define controller metadata
@@ -32,7 +30,7 @@ export const Get = (
32
30
  ...Reflect.getOwnMetadata(controllerRoutesKey, target.constructor) || [],
33
31
  {
34
32
  path: !path.startsWith("/") ? `/${path}` : path,
35
- httpMethod: "GET",
33
+ httpMethod: method.toUpperCase(),
36
34
  methodName: methodName,
37
35
  descriptor: descriptor
38
36
  }
@@ -40,80 +38,112 @@ export const Get = (
40
38
 
41
39
  // Define route parameters zod validation
42
40
  const currentMethod = descriptor.value;
43
-
44
- descriptor.value = function () {
45
- const zodSchemaMetadata = Reflect.getOwnMetadata(controllerRouteZodSchemaKey, target.constructor, methodName);
46
-
47
- if (zodSchemaMetadata) {
48
- for (const zodSchemaProp in zodSchemaMetadata) {
49
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
50
-
51
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
52
-
53
- if (!validation.success) {
54
- throw new HttpClientError({
55
- httpCode: 400,
56
- data: validation.error.issues
57
- })
41
+ const isAsync = descriptor.value instanceof AsyncFunction;
42
+
43
+ if (!isAsync) {
44
+ descriptor.value = function () {
45
+ const zodSchemaMetadata = Reflect.getOwnMetadata(controllerRouteZodSchemaKey, target.constructor, methodName);
46
+
47
+ if (zodSchemaMetadata) {
48
+ for (const zodSchemaProp in zodSchemaMetadata) {
49
+ const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
50
+
51
+ try {
52
+ const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
53
+
54
+ if (!validation.success) {
55
+ throw new HttpClientError({
56
+ httpCode: 400,
57
+ message: `Validation at the [${methodName}] method fails at positional argument [${tmpZodMetadata.index}].`,
58
+ data: validation.error.issues
59
+ });
60
+ }
61
+
62
+ arguments[tmpZodMetadata.index] = validation.data;
63
+ }
64
+ catch (error) {
65
+ if (error instanceof HttpClientError) {
66
+ throw error;
67
+ }
68
+
69
+ throw new HttpServerError({
70
+ httpCode: 500,
71
+ message: `Validation at the [${methodName}] method error at positional argument [${tmpZodMetadata.index}].`,
72
+ data: !(error instanceof Error) ? error : [{
73
+ message: error.message,
74
+ code: error.name,
75
+ cause: error.cause
76
+ }]
77
+ });
78
+ }
58
79
  }
59
80
  }
81
+
82
+ return currentMethod.apply(this, arguments);
60
83
  }
84
+ }
85
+ else {
86
+ descriptor.value = async function () {
87
+ const zodSchemaMetadata = Reflect.getOwnMetadata(controllerRouteZodSchemaKey, target.constructor, methodName);
88
+
89
+ if (zodSchemaMetadata) {
90
+ for (const zodSchemaProp in zodSchemaMetadata) {
91
+ const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
92
+
93
+ try {
94
+ const validation = await tmpZodMetadata.schema.safeParseAsync(arguments[tmpZodMetadata.index]);
95
+
96
+ if (!validation.success) {
97
+ throw new HttpClientError({
98
+ httpCode: 400,
99
+ message: `Validation at the [${methodName}] method fails at positional argument [${tmpZodMetadata.index}].`,
100
+ data: validation.error.issues
101
+ });
102
+ }
103
+
104
+ arguments[tmpZodMetadata.index] = validation.data;
105
+ }
106
+ catch (error) {
107
+ if (error instanceof HttpClientError) {
108
+ throw error;
109
+ }
110
+
111
+ throw new HttpServerError({
112
+ httpCode: 500,
113
+ message: `Validation at the [${methodName}] method error at positional argument [${tmpZodMetadata.index}].`,
114
+ data: !(error instanceof Error) ? error : [{
115
+ message: error.message,
116
+ code: error.name,
117
+ cause: error.cause
118
+ }]
119
+ });
120
+ }
121
+ }
122
+ }
61
123
 
62
- return currentMethod.apply(this, arguments);
124
+ return currentMethod.apply(this, arguments);
125
+ }
63
126
  }
64
127
  }
65
128
 
66
-
67
129
  /**
68
130
  *
69
131
  * @param path
70
132
  * @returns
71
133
  */
72
- export const Post = (
134
+ export const Get = (
73
135
  path = "/"
74
- ) => (
75
- target: Object,
76
- methodName: string,
77
- descriptor: PropertyDescriptor
78
- ) => {
79
- if (typeof descriptor.value !== "function") {
80
- throw Error("Post decorator only use for method.");
81
- }
136
+ ) => defaultDecorator(path, "Get");
82
137
 
83
- Reflect.defineMetadata(controllerRoutesKey, [
84
- ...Reflect.getOwnMetadata(controllerRoutesKey, target.constructor) || [],
85
- {
86
- path: !path.startsWith("/") ? `/${path}` : path,
87
- httpMethod: "POST",
88
- methodName: methodName,
89
- descriptor: descriptor
90
- }
91
- ], target.constructor);
92
-
93
- // Define route parameters zod validation
94
- const currentMethod = descriptor.value;
95
138
 
96
- descriptor.value = function () {
97
- const zodSchemaMetadata = Reflect.getOwnMetadata(controllerRouteZodSchemaKey, target.constructor, methodName);
98
-
99
- if (zodSchemaMetadata) {
100
- for (const zodSchemaProp in zodSchemaMetadata) {
101
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
102
-
103
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
104
-
105
- if (!validation.success) {
106
- throw new HttpClientError({
107
- httpCode: 400,
108
- data: validation.error.issues
109
- })
110
- }
111
- }
112
- }
113
-
114
- return currentMethod.apply(this, arguments);
115
- }
116
- }
139
+ /**
140
+ *
141
+ * @param path
142
+ * @returns
143
+ */
144
+ export const Post = (
145
+ path = "/"
146
+ ) => defaultDecorator(path, "Post");
117
147
 
118
148
 
119
149
  /**
@@ -123,49 +153,7 @@ export const Post = (
123
153
  */
124
154
  export const Put = (
125
155
  path = "/"
126
- ) => (
127
- target: Object,
128
- methodName: string,
129
- descriptor: PropertyDescriptor
130
- ) => {
131
- if (typeof descriptor.value !== "function") {
132
- throw Error("Put decorator only use for method.");
133
- }
134
-
135
- Reflect.defineMetadata(controllerRoutesKey, [
136
- ...Reflect.getOwnMetadata(controllerRoutesKey, target.constructor) || [],
137
- {
138
- path: !path.startsWith("/") ? `/${path}` : path,
139
- httpMethod: "PUT",
140
- methodName: methodName,
141
- descriptor: descriptor
142
- }
143
- ], target.constructor);
144
-
145
- // Define route parameters zod validation
146
- const currentMethod = descriptor.value;
147
-
148
- descriptor.value = function () {
149
- const zodSchemaMetadata = Reflect.getOwnMetadata(controllerRouteZodSchemaKey, target.constructor, methodName);
150
-
151
- if (zodSchemaMetadata) {
152
- for (const zodSchemaProp in zodSchemaMetadata) {
153
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
154
-
155
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
156
-
157
- if (!validation.success) {
158
- throw new HttpClientError({
159
- httpCode: 400,
160
- data: validation.error.issues
161
- })
162
- }
163
- }
164
- }
165
-
166
- return currentMethod.apply(this, arguments);
167
- }
168
- }
156
+ ) => defaultDecorator(path, "Put");
169
157
 
170
158
 
171
159
  /**
@@ -175,49 +163,7 @@ export const Put = (
175
163
  */
176
164
  export const Patch = (
177
165
  path = "/"
178
- ) => (
179
- target: Object,
180
- methodName: string,
181
- descriptor: PropertyDescriptor
182
- ) => {
183
- if (typeof descriptor.value !== "function") {
184
- throw Error("Patch decorator only use for method.");
185
- }
186
-
187
- Reflect.defineMetadata(controllerRoutesKey, [
188
- ...Reflect.getOwnMetadata(controllerRoutesKey, target.constructor) || [],
189
- {
190
- path: !path.startsWith("/") ? `/${path}` : path,
191
- httpMethod: "PATCH",
192
- methodName: methodName,
193
- descriptor: descriptor
194
- }
195
- ], target.constructor);
196
-
197
- // Define route parameters zod validation
198
- const currentMethod = descriptor.value;
199
-
200
- descriptor.value = function () {
201
- const zodSchemaMetadata = Reflect.getOwnMetadata(controllerRouteZodSchemaKey, target.constructor, methodName);
202
-
203
- if (zodSchemaMetadata) {
204
- for (const zodSchemaProp in zodSchemaMetadata) {
205
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
206
-
207
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
208
-
209
- if (!validation.success) {
210
- throw new HttpClientError({
211
- httpCode: 400,
212
- data: validation.error.issues
213
- })
214
- }
215
- }
216
- }
217
-
218
- return currentMethod.apply(this, arguments);
219
- }
220
- }
166
+ ) => defaultDecorator(path, "Patch");
221
167
 
222
168
 
223
169
  /**
@@ -227,49 +173,7 @@ export const Patch = (
227
173
  */
228
174
  export const Delete = (
229
175
  path = "/"
230
- ) => (
231
- target: Object,
232
- methodName: string,
233
- descriptor: PropertyDescriptor
234
- ) => {
235
- if (typeof descriptor.value !== "function") {
236
- throw Error("Delete decorator only use for method.");
237
- }
238
-
239
- Reflect.defineMetadata(controllerRoutesKey, [
240
- ...Reflect.getOwnMetadata(controllerRoutesKey, target.constructor) || [],
241
- {
242
- path: !path.startsWith("/") ? `/${path}` : path,
243
- httpMethod: "DELETE",
244
- methodName: methodName,
245
- descriptor: descriptor
246
- }
247
- ], target.constructor);
248
-
249
- // Define route parameters zod validation
250
- const currentMethod = descriptor.value;
251
-
252
- descriptor.value = function () {
253
- const zodSchemaMetadata = Reflect.getOwnMetadata(controllerRouteZodSchemaKey, target.constructor, methodName);
254
-
255
- if (zodSchemaMetadata) {
256
- for (const zodSchemaProp in zodSchemaMetadata) {
257
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
258
-
259
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
260
-
261
- if (!validation.success) {
262
- throw new HttpClientError({
263
- httpCode: 400,
264
- data: validation.error.issues
265
- })
266
- }
267
- }
268
- }
269
-
270
- return currentMethod.apply(this, arguments);
271
- }
272
- }
176
+ ) => defaultDecorator(path, "Delete");
273
177
 
274
178
 
275
179
  /**
@@ -279,49 +183,7 @@ export const Delete = (
279
183
  */
280
184
  export const Options = (
281
185
  path = "/"
282
- ) => (
283
- target: Object,
284
- methodName: string,
285
- descriptor: PropertyDescriptor
286
- ) => {
287
- if (typeof descriptor.value !== "function") {
288
- throw Error("Options decorator only use for method.");
289
- }
290
-
291
- Reflect.defineMetadata(controllerRoutesKey, [
292
- ...Reflect.getOwnMetadata(controllerRoutesKey, target.constructor) || [],
293
- {
294
- path: !path.startsWith("/") ? `/${path}` : path,
295
- httpMethod: "OPTIONS",
296
- methodName: methodName,
297
- descriptor: descriptor
298
- }
299
- ], target.constructor);
300
-
301
- // Define route parameters zod validation
302
- const currentMethod = descriptor.value;
303
-
304
- descriptor.value = function () {
305
- const zodSchemaMetadata = Reflect.getOwnMetadata(controllerRouteZodSchemaKey, target.constructor, methodName);
306
-
307
- if (zodSchemaMetadata) {
308
- for (const zodSchemaProp in zodSchemaMetadata) {
309
- const tmpZodMetadata = zodSchemaMetadata[zodSchemaProp];
310
-
311
- const validation = tmpZodMetadata.schema.safeParse(arguments[tmpZodMetadata.index]);
312
-
313
- if (!validation.success) {
314
- throw new HttpClientError({
315
- httpCode: 400,
316
- data: validation.error.issues
317
- })
318
- }
319
- }
320
- }
321
-
322
- return currentMethod.apply(this, arguments);
323
- }
324
- }
186
+ ) => defaultDecorator(path, "Options");
325
187
 
326
188
  export default {
327
189
  Get,
@@ -2,16 +2,10 @@ import * as Zod from "zod";
2
2
 
3
3
  export const controllerRouteZodSchemaKey = "__bool:controller.route.zodSchema__";
4
4
 
5
+
5
6
  export const ZodSchema = (
6
7
  schema: Zod.Schema
7
8
  ) => {
8
- try {
9
- schema.safeParse(undefined);
10
- }
11
- catch (err) {
12
- throw Error("Zod schema parameter do not allow async.");
13
- }
14
-
15
9
  return (
16
10
  target: Object,
17
11
  methodName: string | symbol | undefined,
@@ -193,7 +193,9 @@ export const BoolFactory = (
193
193
  return;
194
194
  }
195
195
 
196
- console.error("Headers:", JSON.stringify(req.headers), "\nBody:", JSON.stringify(req.body), "\nError:", JSON.stringify(err));
196
+ console.info("Headers:", JSON.stringify(req.headers, null, 4), "\nBody:", JSON.stringify(req.body, null, 4));
197
+ console.error("Error:");
198
+ console.error(err);
197
199
  }
198
200
  );
199
201
 
@@ -1,6 +1,3 @@
1
- import * as ExpressJS from "express";
2
-
3
-
4
1
  export const httpClientErrors = Object.freeze({
5
2
  400: "BAD_REQUEST",
6
3
  401: "UNAUTHORIZED",
@@ -38,20 +35,22 @@ export class HttpClientError<
38
35
  K = any
39
36
  > extends Error {
40
37
  public readonly httpCode: T;
41
- public readonly message: typeof httpClientErrors[T];
38
+ public readonly message: typeof httpClientErrors[T] | string;
42
39
  public readonly data: K;
43
40
 
44
41
  constructor({
45
42
  httpCode,
46
- data
43
+ data,
44
+ message
47
45
  }: {
48
- ["httpCode"]: T;
49
- ["data"]: K;
46
+ httpCode: T;
47
+ data: K;
48
+ message?: string;
50
49
  }) {
51
50
  super();
52
51
 
53
52
  this.httpCode = httpCode;
54
- this.message = httpClientErrors[httpCode];
53
+ this.message = !message?.trim() ? httpClientErrors[httpCode] : message.trim();
55
54
  this.data = data;
56
55
  }
57
56
  }
package/src/http/index.ts CHANGED
@@ -23,7 +23,11 @@ export const errorInfer = (res: Response, data: any) => {
23
23
  res.status(500).json({
24
24
  httpCode: 500,
25
25
  message: "INTERNAL SERVER ERROR",
26
- data: data
26
+ data: !(data instanceof Error) ? data : {
27
+ message: data.message,
28
+ code: data.name,
29
+ cause: data.cause
30
+ }
27
31
  });
28
32
  return;
29
33
  }
@@ -1,6 +1,3 @@
1
- import * as ExpressJS from "express";
2
-
3
-
4
1
  export const httpServerErrors = Object.freeze({
5
2
  500: "INTERNAL_SERVER_ERROR",
6
3
  501: "NOT_IMPLEMENTED",
@@ -20,20 +17,22 @@ export class HttpServerError<
20
17
  K = any
21
18
  > extends Error {
22
19
  public readonly httpCode: T;
23
- public readonly message: typeof httpServerErrors[T];
20
+ public readonly message: typeof httpServerErrors[T] | string;
24
21
  public readonly data: K;
25
22
 
26
23
  constructor({
27
24
  httpCode,
28
- data
25
+ data,
26
+ message
29
27
  }: {
30
- ["httpCode"]: T;
31
- ["data"]: K;
28
+ httpCode: T;
29
+ data: K;
30
+ message?: string;
32
31
  }) {
33
32
  super();
34
33
 
35
34
  this.httpCode = httpCode;
36
- this.message = httpServerErrors[httpCode];
35
+ this.message = !message?.trim() ? httpServerErrors[httpCode] : message.trim();
37
36
  this.data = data;
38
37
  }
39
38
  }
@@ -0,0 +1 @@
1
+ export const AsyncFunction = async function () { }.constructor;
@@ -0,0 +1 @@
1
+ export * from "./asyncFunction";