@arkyn/server 3.0.1-beta.4 → 3.0.1-beta.41
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 +368 -65
- package/dist/api/arkynLogRequest.d.ts +1 -1
- package/dist/api/arkynLogRequest.d.ts.map +1 -1
- package/dist/api/arkynLogRequest.js +7 -8
- package/dist/api/makeRequest.d.ts +1 -1
- package/dist/api/makeRequest.d.ts.map +1 -1
- package/dist/api/makeRequest.js +3 -5
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/mapper/arkynLogRequestMapper.js +2 -2
- package/dist/{config/apiInstance.d.ts → services/apiService.d.ts} +21 -21
- package/dist/{config/apiInstance.d.ts.map → services/apiService.d.ts.map} +1 -1
- package/dist/{config/apiInstance.js → services/apiService.js} +18 -18
- package/dist/{config/arkynLogInstance.d.ts → services/arkynLogService.d.ts} +5 -5
- package/dist/services/arkynLogService.d.ts.map +1 -0
- package/dist/{config/arkynLogInstance.js → services/arkynLogService.js} +4 -5
- package/dist/services/formParse.d.ts +3 -3
- package/dist/services/formParse.d.ts.map +1 -1
- package/dist/services/formParse.js +8 -5
- package/dist/services/getCaller.d.ts.map +1 -1
- package/dist/services/getCaller.js +9 -14
- package/dist/services/httpDebug.d.ts +40 -1
- package/dist/services/httpDebug.d.ts.map +1 -1
- package/dist/services/httpDebug.js +42 -1
- package/dist/services/measureRouteExecution.d.ts +3 -0
- package/dist/services/measureRouteExecution.d.ts.map +1 -0
- package/dist/services/measureRouteExecution.js +24 -0
- package/dist/services/schemaValidator.d.ts +3 -3
- package/dist/services/schemaValidator.d.ts.map +1 -1
- package/dist/services/schemaValidator.js +1 -1
- package/package.json +31 -20
- package/src/api/arkynLogRequest.ts +20 -14
- package/src/api/makeRequest.ts +3 -5
- package/src/index.ts +3 -5
- package/src/mapper/arkynLogRequestMapper.ts +2 -2
- package/src/{config/apiInstance.ts → services/apiService.ts} +20 -20
- package/src/{config/arkynLogInstance.ts → services/arkynLogService.ts} +4 -9
- package/src/services/formParse.ts +11 -8
- package/src/services/getCaller.ts +15 -16
- package/src/services/httpDebug.ts +44 -1
- package/src/services/measureRouteExecution.ts +31 -0
- package/src/services/schemaValidator.ts +4 -4
- package/dist/config/arkynLogInstance.d.ts.map +0 -1
- package/tsconfig.json +0 -21
- package/vitest.config.ts +0 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ArkynLogService } from "../services/arkynLogService";
|
|
2
2
|
import { httpDebug } from "../services/httpDebug";
|
|
3
3
|
|
|
4
4
|
type ConfigProps = {
|
|
@@ -30,7 +30,7 @@ type ConfigProps = {
|
|
|
30
30
|
* @param config.responseBody - The body of the response received.
|
|
31
31
|
*
|
|
32
32
|
* @remarks
|
|
33
|
-
* - This function retrieves the inbox flow configuration using `
|
|
33
|
+
* - This function retrieves the inbox flow configuration using `InboxFlowService.getInboxConfig()`.
|
|
34
34
|
* - If the configuration is not available, the function will return early without performing any action.
|
|
35
35
|
* - In a development environment (`NODE_ENV === "development"`), the function will also return early.
|
|
36
36
|
* - The request is sent as a POST request to the inbox API URL with the provided configuration details.
|
|
@@ -56,10 +56,10 @@ type ConfigProps = {
|
|
|
56
56
|
*/
|
|
57
57
|
|
|
58
58
|
async function arkynLogRequest(config: ConfigProps) {
|
|
59
|
-
const
|
|
60
|
-
if (!
|
|
59
|
+
const arkynService = ArkynLogService.getArkynConfig();
|
|
60
|
+
if (!arkynService) return;
|
|
61
61
|
|
|
62
|
-
const {
|
|
62
|
+
const { arkynUserToken, arkynApiUrl } = arkynService;
|
|
63
63
|
|
|
64
64
|
const {
|
|
65
65
|
elapsedTime,
|
|
@@ -74,7 +74,7 @@ async function arkynLogRequest(config: ConfigProps) {
|
|
|
74
74
|
rawUrl,
|
|
75
75
|
} = config;
|
|
76
76
|
|
|
77
|
-
if (process.env.NODE_ENV === "development") return;
|
|
77
|
+
// if (process.env.NODE_ENV === "development") return;
|
|
78
78
|
|
|
79
79
|
try {
|
|
80
80
|
const url = new URL(rawUrl);
|
|
@@ -96,14 +96,20 @@ async function arkynLogRequest(config: ConfigProps) {
|
|
|
96
96
|
responseBody,
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
await fetch(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
99
|
+
await fetch(
|
|
100
|
+
arkynApiUrl.replace(
|
|
101
|
+
":trafficSourceId",
|
|
102
|
+
arkynService.arkynTrafficSourceId
|
|
103
|
+
),
|
|
104
|
+
{
|
|
105
|
+
method: "POST",
|
|
106
|
+
body,
|
|
107
|
+
headers: {
|
|
108
|
+
"Content-Type": "application/json",
|
|
109
|
+
Authorization: `Bearer ${arkynUserToken}`,
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
);
|
|
107
113
|
} catch (err) {
|
|
108
114
|
httpDebug("arkyn log error", "Error sending request", err);
|
|
109
115
|
}
|
package/src/api/makeRequest.ts
CHANGED
|
@@ -41,7 +41,7 @@ import { arkynLogRequest } from "./arkynLogRequest";
|
|
|
41
41
|
async function makeRequest<T = any>(
|
|
42
42
|
method: "POST" | "PUT" | "DELETE" | "PATCH" | "GET",
|
|
43
43
|
url: string,
|
|
44
|
-
|
|
44
|
+
rawHeaders: HeadersInit = {},
|
|
45
45
|
body?: any
|
|
46
46
|
): Promise<ApiResponseDTO<T>> {
|
|
47
47
|
const successMessage = {
|
|
@@ -55,12 +55,10 @@ async function makeRequest<T = any>(
|
|
|
55
55
|
try {
|
|
56
56
|
const startTime = performance.now();
|
|
57
57
|
|
|
58
|
+
const headers = { ...rawHeaders, "Content-Type": "application/json" };
|
|
58
59
|
const response = await fetch(url, {
|
|
59
60
|
method,
|
|
60
|
-
headers
|
|
61
|
-
...headers,
|
|
62
|
-
"Content-Type": "application/json",
|
|
63
|
-
},
|
|
61
|
+
headers,
|
|
64
62
|
body: body ? JSON.stringify(body) : undefined,
|
|
65
63
|
});
|
|
66
64
|
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
// config
|
|
2
|
-
export { ApiInstance } from "./config/apiInstance";
|
|
3
|
-
export { ArkynLogInstance } from "./config/arkynLogInstance";
|
|
4
|
-
|
|
5
1
|
// http bad responses
|
|
6
2
|
export { BadGateway } from "./http/badResponses/badGateway";
|
|
7
3
|
export { BadRequest } from "./http/badResponses/badRequest";
|
|
@@ -21,11 +17,13 @@ export { Success } from "./http/successResponses/success";
|
|
|
21
17
|
export { Updated } from "./http/successResponses/updated";
|
|
22
18
|
|
|
23
19
|
// services
|
|
20
|
+
export { ApiService } from "./services/apiService";
|
|
21
|
+
export { ArkynLogService } from "./services/arkynLogService";
|
|
24
22
|
export { decodeErrorMessageFromRequest } from "./services/decodeErrorMessageFromRequest";
|
|
25
23
|
export { decodeRequestBody } from "./services/decodeRequestBody";
|
|
26
24
|
export { errorHandler } from "./services/errorHandler";
|
|
27
25
|
export { formParse } from "./services/formParse";
|
|
28
26
|
export { getCaller } from "./services/getCaller";
|
|
29
27
|
export { getScopedParams } from "./services/getScopedParams";
|
|
30
|
-
export { httpDebug } from "./services/httpDebug";
|
|
28
|
+
export { httpDebug, HttpDebugService } from "./services/httpDebug";
|
|
31
29
|
export { SchemaValidator } from "./services/schemaValidator";
|
|
@@ -62,10 +62,10 @@ class ArkynLogRequestMapper {
|
|
|
62
62
|
token: null,
|
|
63
63
|
elapsedTime: props.elapsedTime,
|
|
64
64
|
requestHeaders: this.mapHeaders(props.requestHeaders),
|
|
65
|
-
requestBody: props.requestBody,
|
|
65
|
+
requestBody: props.requestBody || null,
|
|
66
66
|
queryParams: this.mapQueryParams(props.queryParams),
|
|
67
67
|
responseHeaders: this.mapHeaders(props.responseHeaders),
|
|
68
|
-
responseBody: props.responseBody,
|
|
68
|
+
responseBody: props.responseBody || null,
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -4,7 +4,7 @@ import { patchRequest } from "../api/patchRequest";
|
|
|
4
4
|
import { postRequest } from "../api/postRequest";
|
|
5
5
|
import { putRequest } from "../api/putRequest";
|
|
6
6
|
|
|
7
|
-
type
|
|
7
|
+
type ApiServiceConstructorProps = {
|
|
8
8
|
baseUrl: string;
|
|
9
9
|
baseHeaders?: HeadersInit;
|
|
10
10
|
baseToken?: string | null;
|
|
@@ -25,20 +25,20 @@ type ApiRequestDataWithBodyProps = {
|
|
|
25
25
|
* Class representing an API instance to handle HTTP requests with base configurations.
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
class
|
|
28
|
+
class ApiService {
|
|
29
29
|
private baseUrl: string;
|
|
30
30
|
private baseHeaders?: HeadersInit;
|
|
31
31
|
private baseToken?: string;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Creates an instance of
|
|
34
|
+
* Creates an instance of ApiService.
|
|
35
35
|
* @param props - The configuration properties for the API instance.
|
|
36
36
|
* @param props.baseUrl - The base URL for the API.
|
|
37
37
|
* @param props.baseHeaders - Optional base headers to include in all requests.
|
|
38
38
|
* @param props.baseToken - Optional base token for authorization.
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
|
-
constructor(props:
|
|
41
|
+
constructor(props: ApiServiceConstructorProps) {
|
|
42
42
|
this.baseUrl = props.baseUrl;
|
|
43
43
|
this.baseHeaders = props.baseHeaders || undefined;
|
|
44
44
|
this.baseToken = props.baseToken || undefined;
|
|
@@ -76,26 +76,26 @@ class ApiInstance {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* Sends a
|
|
80
|
-
* @param route - The API route to send the
|
|
79
|
+
* Sends a get request to the specified route.
|
|
80
|
+
* @param route - The API route to send the get request to.
|
|
81
81
|
* @param data - The request data, including optional headers and token.
|
|
82
82
|
* @returns The API response data.
|
|
83
83
|
*/
|
|
84
84
|
|
|
85
|
-
async
|
|
85
|
+
async get(route: string, data?: ApiRequestDataWithoutBodyProps) {
|
|
86
86
|
const url = this.generateURL(route);
|
|
87
87
|
const headers = this.generateHeaders(data?.headers || {}, data?.token);
|
|
88
88
|
return await getRequest(url, headers);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
|
-
* Sends a
|
|
93
|
-
* @param route - The API route to send the
|
|
92
|
+
* Sends a post request to the specified route.
|
|
93
|
+
* @param route - The API route to send the post request to.
|
|
94
94
|
* @param data - The request data, including body, optional headers, and token.
|
|
95
95
|
* @returns The API response data.
|
|
96
96
|
*/
|
|
97
97
|
|
|
98
|
-
async
|
|
98
|
+
async post(route: string, data?: ApiRequestDataWithBodyProps) {
|
|
99
99
|
const url = this.generateURL(route);
|
|
100
100
|
const headers = this.generateHeaders(data?.headers || {}, data?.token);
|
|
101
101
|
const body = data?.body;
|
|
@@ -103,13 +103,13 @@ class ApiInstance {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
|
-
* Sends a
|
|
107
|
-
* @param route - The API route to send the
|
|
106
|
+
* Sends a put request to the specified route.
|
|
107
|
+
* @param route - The API route to send the put request to.
|
|
108
108
|
* @param data - The request data, including body, optional headers, and token.
|
|
109
109
|
* @returns The API response data.
|
|
110
110
|
*/
|
|
111
111
|
|
|
112
|
-
async
|
|
112
|
+
async put(route: string, data?: ApiRequestDataWithBodyProps) {
|
|
113
113
|
const url = this.generateURL(route);
|
|
114
114
|
const headers = this.generateHeaders(data?.headers || {}, data?.token);
|
|
115
115
|
const body = data?.body;
|
|
@@ -117,13 +117,13 @@ class ApiInstance {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
|
-
* Sends a
|
|
121
|
-
* @param route - The API route to send the
|
|
120
|
+
* Sends a patch request to the specified route.
|
|
121
|
+
* @param route - The API route to send the patch request to.
|
|
122
122
|
* @param data - The request data, including body, optional headers, and token.
|
|
123
123
|
* @returns The API response data.
|
|
124
124
|
*/
|
|
125
125
|
|
|
126
|
-
async
|
|
126
|
+
async patch(route: string, data?: ApiRequestDataWithBodyProps) {
|
|
127
127
|
const url = this.generateURL(route);
|
|
128
128
|
const headers = this.generateHeaders(data?.headers || {}, data?.token);
|
|
129
129
|
const body = data?.body;
|
|
@@ -131,13 +131,13 @@ class ApiInstance {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
|
-
* Sends a
|
|
135
|
-
* @param route - The API route to send the
|
|
134
|
+
* Sends a delete request to the specified route.
|
|
135
|
+
* @param route - The API route to send the delete request to.
|
|
136
136
|
* @param data - The request data, including body, optional headers, and token.
|
|
137
137
|
* @returns The API response data.
|
|
138
138
|
*/
|
|
139
139
|
|
|
140
|
-
async
|
|
140
|
+
async delete(route: string, data?: ApiRequestDataWithBodyProps) {
|
|
141
141
|
const url = this.generateURL(route);
|
|
142
142
|
const headers = this.generateHeaders(data?.headers || {}, data?.token);
|
|
143
143
|
const body = data?.body;
|
|
@@ -145,4 +145,4 @@ class ApiInstance {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
export {
|
|
148
|
+
export { ApiService };
|
|
@@ -11,12 +11,12 @@ type SetArkynConfigProps = {
|
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* The `
|
|
14
|
+
* The `ArkynLogService` class manages the configuration for the arkyn flow.
|
|
15
15
|
* It allows you to set and retrieve the arkyn configuration, including the traffic source ID,
|
|
16
16
|
* user token, and API URL.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
class
|
|
19
|
+
class ArkynLogService {
|
|
20
20
|
private static arkynConfig?: ArkynConfigProps;
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -40,11 +40,6 @@ class ArkynLogInstance {
|
|
|
40
40
|
arkynLogBaseApiUrl =
|
|
41
41
|
arkynLogBaseApiUrl + "/http-traffic-records/:trafficSourceId";
|
|
42
42
|
|
|
43
|
-
arkynLogBaseApiUrl.replace(
|
|
44
|
-
":trafficSourceId",
|
|
45
|
-
arkynConfig.arkynTrafficSourceId
|
|
46
|
-
);
|
|
47
|
-
|
|
48
43
|
this.arkynConfig = {
|
|
49
44
|
arkynTrafficSourceId: arkynConfig.arkynTrafficSourceId,
|
|
50
45
|
arkynUserToken: arkynConfig.arkynUserToken,
|
|
@@ -53,7 +48,7 @@ class ArkynLogInstance {
|
|
|
53
48
|
}
|
|
54
49
|
|
|
55
50
|
/**
|
|
56
|
-
* Retrieves the current arkyn configuration for the
|
|
51
|
+
* Retrieves the current arkyn configuration for the ArkynLogService.
|
|
57
52
|
*
|
|
58
53
|
* @returns {ArkynConfigProps | undefined} The current arkyn configuration if set,
|
|
59
54
|
* or `undefined` if no configuration has been initialized.
|
|
@@ -72,4 +67,4 @@ class ArkynLogInstance {
|
|
|
72
67
|
}
|
|
73
68
|
}
|
|
74
69
|
|
|
75
|
-
export {
|
|
70
|
+
export { ArkynLogService };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
2
|
|
|
3
3
|
type SuccessResponse<T extends FormParseProps> = {
|
|
4
4
|
success: true;
|
|
5
|
-
data: T[1] extends
|
|
5
|
+
data: T[1] extends ZodType<infer U> ? U : never;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
type ErrorResponse = {
|
|
@@ -11,7 +11,7 @@ type ErrorResponse = {
|
|
|
11
11
|
fieldErrors: { [x: string]: string };
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
type FormParseProps = [formData: { [k: string]: any }, schema:
|
|
14
|
+
type FormParseProps = [formData: { [k: string]: any }, schema: ZodType];
|
|
15
15
|
|
|
16
16
|
type FormParseReturnType<T extends FormParseProps> =
|
|
17
17
|
| SuccessResponse<T>
|
|
@@ -64,10 +64,10 @@ function formParse<T extends FormParseProps>([
|
|
|
64
64
|
|
|
65
65
|
if (zodResponse.success === false) {
|
|
66
66
|
const errorsObject = Object.fromEntries(
|
|
67
|
-
zodResponse.error.
|
|
68
|
-
|
|
69
|
-
item.message
|
|
70
|
-
|
|
67
|
+
zodResponse.error.issues.map((item) => {
|
|
68
|
+
console.log(item);
|
|
69
|
+
return [item.path.join("."), item.message];
|
|
70
|
+
})
|
|
71
71
|
);
|
|
72
72
|
|
|
73
73
|
return {
|
|
@@ -76,7 +76,10 @@ function formParse<T extends FormParseProps>([
|
|
|
76
76
|
fields: formData,
|
|
77
77
|
};
|
|
78
78
|
} else {
|
|
79
|
-
return {
|
|
79
|
+
return {
|
|
80
|
+
success: zodResponse.success,
|
|
81
|
+
data: zodResponse.data as T[1] extends ZodType<infer U> ? U : never,
|
|
82
|
+
};
|
|
80
83
|
}
|
|
81
84
|
}
|
|
82
85
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
+
import { HttpDebugService } from "./httpDebug";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Retrieves information about the caller of the current function.
|
|
@@ -11,6 +12,7 @@ import path from "path";
|
|
|
11
12
|
* - `functionName`: The name of the function that called the current function, or "Unknown function" if it cannot be determined.
|
|
12
13
|
* - `callerInfo`: The file path of the caller relative to the project root, or "Unknown caller" if it cannot be determined.
|
|
13
14
|
*/
|
|
15
|
+
|
|
14
16
|
function getCaller() {
|
|
15
17
|
const projectRoot = process.cwd();
|
|
16
18
|
|
|
@@ -18,13 +20,10 @@ function getCaller() {
|
|
|
18
20
|
const stack = err.stack || "";
|
|
19
21
|
const stackLines = stack.split("\n").map((line) => line.trim());
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// The third line should be the direct caller
|
|
24
|
-
// We start from 2 because indexes are zero-based
|
|
23
|
+
const ignoreFile = HttpDebugService.ignoreFile;
|
|
24
|
+
|
|
25
25
|
let callerIndex = 2;
|
|
26
26
|
|
|
27
|
-
// Ignore internal or infrastructure lines if necessary
|
|
28
27
|
while (
|
|
29
28
|
callerIndex < stackLines.length &&
|
|
30
29
|
(stackLines[callerIndex].includes("node:internal") ||
|
|
@@ -33,24 +32,29 @@ function getCaller() {
|
|
|
33
32
|
callerIndex++;
|
|
34
33
|
}
|
|
35
34
|
|
|
35
|
+
if (ignoreFile) {
|
|
36
|
+
while (
|
|
37
|
+
callerIndex < stackLines.length &&
|
|
38
|
+
stackLines[callerIndex].includes(ignoreFile)
|
|
39
|
+
) {
|
|
40
|
+
callerIndex++;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
const callerLine = stackLines[callerIndex] || "";
|
|
37
45
|
|
|
38
46
|
let functionName = "Unknown function";
|
|
39
47
|
let callerInfo = "Unknown caller";
|
|
40
48
|
|
|
41
|
-
// Default for named functions: "at functionName (file:line:column)"
|
|
42
49
|
const namedFunctionMatch = callerLine.match(/at\s+([^(\s]+)\s+\(([^)]+)\)/);
|
|
43
50
|
if (namedFunctionMatch) {
|
|
44
51
|
functionName = namedFunctionMatch[1];
|
|
45
52
|
callerInfo = namedFunctionMatch[2];
|
|
46
|
-
}
|
|
47
|
-
// Default for anonymous functions or methods: "at file:line:column"
|
|
48
|
-
else {
|
|
53
|
+
} else {
|
|
49
54
|
const anonymousFunctionMatch = callerLine.match(/at\s+(.+)/);
|
|
50
55
|
if (anonymousFunctionMatch) {
|
|
51
56
|
callerInfo = anonymousFunctionMatch[1];
|
|
52
57
|
|
|
53
|
-
// Tenta extrair nome da função de padrões como Object.method ou Class.method
|
|
54
58
|
const objectMethodMatch = callerInfo.match(/at\s+([^(\s]+)\s+/);
|
|
55
59
|
if (objectMethodMatch && objectMethodMatch[1] !== "new") {
|
|
56
60
|
functionName = objectMethodMatch[1];
|
|
@@ -58,7 +62,6 @@ function getCaller() {
|
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
// Handles file paths
|
|
62
65
|
if (callerInfo.includes("(")) {
|
|
63
66
|
callerInfo = callerInfo.substring(
|
|
64
67
|
callerInfo.indexOf("(") + 1,
|
|
@@ -66,15 +69,11 @@ function getCaller() {
|
|
|
66
69
|
);
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
// Remove the line:column part of the file path
|
|
70
72
|
callerInfo = callerInfo.split(":").slice(0, -2).join(":");
|
|
71
73
|
|
|
72
|
-
// Make the path relative to the project
|
|
73
74
|
try {
|
|
74
75
|
callerInfo = path.relative(projectRoot, callerInfo);
|
|
75
|
-
} catch (e) {
|
|
76
|
-
// If it fails to relativize, use the original path
|
|
77
|
-
}
|
|
76
|
+
} catch (e) {}
|
|
78
77
|
|
|
79
78
|
return { functionName, callerInfo };
|
|
80
79
|
}
|
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
import { getCaller } from "../services/getCaller";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Service for managing HTTP debug configuration and behavior.
|
|
5
|
+
*
|
|
6
|
+
* This service provides functionality to configure how the `getCaller` function
|
|
7
|
+
* identifies the actual caller in the stack trace by allowing specific files
|
|
8
|
+
* to be ignored during stack trace analysis.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Configure to ignore httpAdapter.ts in stack traces
|
|
13
|
+
* HttpDebugService.setIgnoreFile("httpAdapter.ts");
|
|
14
|
+
*
|
|
15
|
+
* // Now when httpDebug is called from within httpAdapter.ts,
|
|
16
|
+
* // it will show the actual caller (e.g., cart.ts) instead
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
class HttpDebugService {
|
|
20
|
+
/**
|
|
21
|
+
* The name of the file to ignore when analyzing the stack trace.
|
|
22
|
+
* When set, the `getCaller` function will skip stack frames containing this file name.
|
|
23
|
+
*/
|
|
24
|
+
static ignoreFile?: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Sets the file name to be ignored during stack trace analysis.
|
|
28
|
+
*
|
|
29
|
+
* This method configures the debug service to skip specific files when
|
|
30
|
+
* determining the actual caller of a function. This is useful when you have
|
|
31
|
+
* adapter or wrapper functions that you want to be transparent in the debug output.
|
|
32
|
+
*
|
|
33
|
+
* @param file - The name of the file to ignore in stack traces (e.g., "httpAdapter.ts")
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Ignore the HTTP adapter file so debug shows the actual business logic caller
|
|
38
|
+
* HttpDebugService.setIgnoreFile("httpAdapter.ts");
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
static setIgnoreFile(file: string) {
|
|
42
|
+
this.ignoreFile = file;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
3
46
|
/**
|
|
4
47
|
* Logs debug information to the console when in development mode or when the
|
|
5
48
|
* `SHOW_ERRORS_IN_CONSOLE` environment variable is set to "true".
|
|
@@ -58,4 +101,4 @@ function httpDebug(name: string, body: any, cause?: any) {
|
|
|
58
101
|
}
|
|
59
102
|
}
|
|
60
103
|
|
|
61
|
-
export { httpDebug };
|
|
104
|
+
export { httpDebug, HttpDebugService };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function measureRouteExecution<T = unknown>(
|
|
2
|
+
handler: (props: any) => Promise<T>
|
|
3
|
+
) {
|
|
4
|
+
return async function measuredHandler(props: any): Promise<T> {
|
|
5
|
+
const startTime = performance.now();
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
const result = await handler(props);
|
|
9
|
+
|
|
10
|
+
const url = new URL(props.request.url);
|
|
11
|
+
const endTime = performance.now();
|
|
12
|
+
|
|
13
|
+
const duration = (endTime - startTime).toFixed(2);
|
|
14
|
+
|
|
15
|
+
console.log({
|
|
16
|
+
domain: url.hostname,
|
|
17
|
+
pathname: url.pathname,
|
|
18
|
+
method: props.request.method,
|
|
19
|
+
duration,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return result as T;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
const endTime = performance.now();
|
|
25
|
+
console.error("");
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { measureRouteExecution };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ZodType, z } from "zod";
|
|
2
2
|
|
|
3
3
|
import { ServerError } from "../http/badResponses/serverError";
|
|
4
4
|
import { UnprocessableEntity } from "../http/badResponses/unprocessableEntity";
|
|
@@ -15,7 +15,7 @@ function formatErrorMessage(error: z.ZodError) {
|
|
|
15
15
|
return [title, ...lines].join("\n");
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
class SchemaValidator<T extends
|
|
18
|
+
class SchemaValidator<T extends ZodType> {
|
|
19
19
|
functionName: string;
|
|
20
20
|
callerInfo: string;
|
|
21
21
|
|
|
@@ -29,7 +29,7 @@ class SchemaValidator<T extends Schema> {
|
|
|
29
29
|
return this.schema.safeParse(data).success;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
safeValidate(data: any): z.
|
|
32
|
+
safeValidate(data: any): z.ZodSafeParseResult<z.infer<T>> {
|
|
33
33
|
return this.schema.safeParse(data);
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -59,7 +59,7 @@ class SchemaValidator<T extends Schema> {
|
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
return formParsed.data
|
|
62
|
+
return formParsed.data as z.infer<T>;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"arkynLogInstance.d.ts","sourceRoot":"","sources":["../../src/config/arkynLogInstance.ts"],"names":[],"mappings":"AAAA,KAAK,gBAAgB,GAAG;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF;;;;GAIG;AAEH,cAAM,gBAAgB;IACpB,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAmB;IAE9C;;;;;;;;;;OAUG;IAEH,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,mBAAmB;IAqBtD;;;;;OAKG;IACH,MAAM,CAAC,cAAc,IAAI,gBAAgB,GAAG,SAAS;IAIrD;;;OAGG;IAEH,MAAM,CAAC,gBAAgB;CAGxB;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
package/tsconfig.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"allowSyntheticDefaultImports": true,
|
|
4
|
-
"declaration": true,
|
|
5
|
-
"declarationDir": "./dist",
|
|
6
|
-
"declarationMap": true,
|
|
7
|
-
"isolatedModules": true,
|
|
8
|
-
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
9
|
-
"module": "ESNext",
|
|
10
|
-
"moduleResolution": "node",
|
|
11
|
-
"outDir": "./dist",
|
|
12
|
-
"preserveWatchOutput": true,
|
|
13
|
-
"skipLibCheck": true,
|
|
14
|
-
"strict": true,
|
|
15
|
-
"target": "ESNext",
|
|
16
|
-
"types": ["bun-types"],
|
|
17
|
-
"verbatimModuleSyntax": true
|
|
18
|
-
},
|
|
19
|
-
"exclude": ["node_modules", "dist"],
|
|
20
|
-
"include": ["src/**/*.ts"]
|
|
21
|
-
}
|