sm-utility 2.4.9 → 2.4.12
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/general/command.abstract.d.ts +112 -0
- package/general/command.abstract.js +130 -0
- package/general/decorators/logMethod.decorator.d.ts +4 -0
- package/general/decorators/logMethod.decorator.js +60 -0
- package/general/index.d.ts +1 -0
- package/general/index.js +3 -1
- package/general/metadata.model.d.ts +37 -1
- package/general/metadata.model.js +29 -0
- package/package.json +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { MetadataModel } from './metadata.model';
|
|
2
|
+
import { LeveledLogMethod } from 'winston';
|
|
3
|
+
type LogData<T> = {
|
|
4
|
+
context?: T;
|
|
5
|
+
};
|
|
6
|
+
type EnhancedLogParams<T, E> = {
|
|
7
|
+
logMethod: LeveledLogMethod;
|
|
8
|
+
message: string;
|
|
9
|
+
logData?: LogData<T>;
|
|
10
|
+
error?: E;
|
|
11
|
+
};
|
|
12
|
+
export declare abstract class Command {
|
|
13
|
+
protected readonly className: string;
|
|
14
|
+
protected readonly metadata: MetadataModel;
|
|
15
|
+
protected readonly logger: import("winston").Logger;
|
|
16
|
+
private startTime;
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new instance of the Command class.
|
|
19
|
+
*
|
|
20
|
+
* @param className - The name of the class extending the Command class. Used for logging purposes.
|
|
21
|
+
* @param metadata - (Optional) A metadata model containing additional information for the command.
|
|
22
|
+
* If not provided, a new `MetadataModel` will be created with a randomly generated `auditUuid`.
|
|
23
|
+
*/
|
|
24
|
+
constructor(className: string, metadata?: MetadataModel);
|
|
25
|
+
/**
|
|
26
|
+
* Executes the command logic. This method must be implemented by any class extending the Command base class.
|
|
27
|
+
*
|
|
28
|
+
* @param params - (Optional) Parameters required to execute the command. The specific structure and type of these
|
|
29
|
+
* parameters depend on the implementation in the derived class.
|
|
30
|
+
*
|
|
31
|
+
* @returns A promise that resolves when the command execution is complete. If the command encounters an error during
|
|
32
|
+
* execution, the promise should reject with the appropriate error.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* // Example implementation in a derived class
|
|
36
|
+
* class MyCommand extends Command {
|
|
37
|
+
* async execute(params?: { userId: string }): Promise<void> {
|
|
38
|
+
* try {
|
|
39
|
+
* this.logInitiated({ context: params });
|
|
40
|
+
* // Command logic here
|
|
41
|
+
* await someAsyncOperation(params?.userId);
|
|
42
|
+
* this.logFinished({ context: params });
|
|
43
|
+
* } catch (error) {
|
|
44
|
+
* this.logUnexpectedFailed(error, { context: params });
|
|
45
|
+
* throw error; // Re-throw the error for further handling
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
*/
|
|
50
|
+
abstract execute(params?: any): Promise<any>;
|
|
51
|
+
/**
|
|
52
|
+
* Logs that the command has been initiated.
|
|
53
|
+
* @param logData Optional contextual data for the log.
|
|
54
|
+
*/
|
|
55
|
+
protected logInitiated<T>(logData?: LogData<T>): void;
|
|
56
|
+
/**
|
|
57
|
+
* Logs that the command has been successfully finished.
|
|
58
|
+
* @param logData Optional contextual data for the log.
|
|
59
|
+
*/
|
|
60
|
+
protected logFinished<T>(logData?: LogData<T>): void;
|
|
61
|
+
/**
|
|
62
|
+
* Logs that the command has failed unexpectedly.
|
|
63
|
+
* @param error The error that occurred.
|
|
64
|
+
* @param logData Optional contextual data for the log.
|
|
65
|
+
*/
|
|
66
|
+
protected logUnexpectedFailed<T>(error: Error, logData?: LogData<T>): void;
|
|
67
|
+
/**
|
|
68
|
+
* Logs detailed information about the current operation, optionally including execution time and error details.
|
|
69
|
+
*
|
|
70
|
+
* @template T - The type of contextual data included in the log.
|
|
71
|
+
* @template E - The type of the error (if any) included in the log.
|
|
72
|
+
*
|
|
73
|
+
* @param params - The parameters for the enhanced log.
|
|
74
|
+
* @param params.logMethod - The logging method to be used (e.g., `logger.info` or `logger.error`).
|
|
75
|
+
* @param params.message - The log message to be recorded.
|
|
76
|
+
* @param params.logData - (Optional) Additional contextual data for the log.
|
|
77
|
+
* @param params.error - (Optional) An error object to include in the log.
|
|
78
|
+
*
|
|
79
|
+
* @remarks
|
|
80
|
+
* - If the log message does not contain the word "initiated," the method automatically appends the `executionTime` field.
|
|
81
|
+
* - If an error object is provided, it will be added to the log payload under the `err` property.
|
|
82
|
+
* - This method builds the log payload dynamically using the provided context and metadata.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* // Log a successful operation
|
|
86
|
+
* this.enhancedLog({
|
|
87
|
+
* logMethod: this.logger.info,
|
|
88
|
+
* message: 'Operation finished successfully',
|
|
89
|
+
* logData: { userId: '12345' },
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* // Log a failed operation with an error
|
|
94
|
+
* this.enhancedLog({
|
|
95
|
+
* logMethod: this.logger.error,
|
|
96
|
+
* message: 'Operation failed',
|
|
97
|
+
* logData: { userId: '12345' },
|
|
98
|
+
* error: new Error('Unexpected error'),
|
|
99
|
+
* });
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* // Log an initiated operation
|
|
103
|
+
* this.enhancedLog({
|
|
104
|
+
* logMethod: this.logger.info,
|
|
105
|
+
* message: 'Operation initiated',
|
|
106
|
+
* });
|
|
107
|
+
*/
|
|
108
|
+
protected enhancedLog<T, E>({ logMethod, message, logData, error, }: EnhancedLogParams<T, E>): void;
|
|
109
|
+
getExecutionTime(): string;
|
|
110
|
+
private buildLogData;
|
|
111
|
+
}
|
|
112
|
+
export {};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Command = void 0;
|
|
4
|
+
const logger_1 = require("../logger");
|
|
5
|
+
const metadata_model_1 = require("./metadata.model");
|
|
6
|
+
const uuid_1 = require("uuid");
|
|
7
|
+
class Command {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new instance of the Command class.
|
|
10
|
+
*
|
|
11
|
+
* @param className - The name of the class extending the Command class. Used for logging purposes.
|
|
12
|
+
* @param metadata - (Optional) A metadata model containing additional information for the command.
|
|
13
|
+
* If not provided, a new `MetadataModel` will be created with a randomly generated `auditUuid`.
|
|
14
|
+
*/
|
|
15
|
+
constructor(className, metadata = new metadata_model_1.MetadataModel({
|
|
16
|
+
auditUuid: (0, uuid_1.v4)(),
|
|
17
|
+
})) {
|
|
18
|
+
this.className = className;
|
|
19
|
+
this.metadata = metadata;
|
|
20
|
+
this.logger = logger_1.logger;
|
|
21
|
+
this.startTime = performance.now();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Logs that the command has been initiated.
|
|
25
|
+
* @param logData Optional contextual data for the log.
|
|
26
|
+
*/
|
|
27
|
+
logInitiated(logData) {
|
|
28
|
+
this.enhancedLog({
|
|
29
|
+
logMethod: this.logger.info,
|
|
30
|
+
message: `${this.className} initiated`,
|
|
31
|
+
logData,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Logs that the command has been successfully finished.
|
|
36
|
+
* @param logData Optional contextual data for the log.
|
|
37
|
+
*/
|
|
38
|
+
logFinished(logData) {
|
|
39
|
+
this.enhancedLog({
|
|
40
|
+
logMethod: this.logger.info,
|
|
41
|
+
message: `${this.className} finished`,
|
|
42
|
+
logData,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Logs that the command has failed unexpectedly.
|
|
47
|
+
* @param error The error that occurred.
|
|
48
|
+
* @param logData Optional contextual data for the log.
|
|
49
|
+
*/
|
|
50
|
+
logUnexpectedFailed(error, logData) {
|
|
51
|
+
this.enhancedLog({
|
|
52
|
+
logMethod: this.logger.error,
|
|
53
|
+
message: `${this.className} failed`,
|
|
54
|
+
logData,
|
|
55
|
+
error,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Logs detailed information about the current operation, optionally including execution time and error details.
|
|
60
|
+
*
|
|
61
|
+
* @template T - The type of contextual data included in the log.
|
|
62
|
+
* @template E - The type of the error (if any) included in the log.
|
|
63
|
+
*
|
|
64
|
+
* @param params - The parameters for the enhanced log.
|
|
65
|
+
* @param params.logMethod - The logging method to be used (e.g., `logger.info` or `logger.error`).
|
|
66
|
+
* @param params.message - The log message to be recorded.
|
|
67
|
+
* @param params.logData - (Optional) Additional contextual data for the log.
|
|
68
|
+
* @param params.error - (Optional) An error object to include in the log.
|
|
69
|
+
*
|
|
70
|
+
* @remarks
|
|
71
|
+
* - If the log message does not contain the word "initiated," the method automatically appends the `executionTime` field.
|
|
72
|
+
* - If an error object is provided, it will be added to the log payload under the `err` property.
|
|
73
|
+
* - This method builds the log payload dynamically using the provided context and metadata.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* // Log a successful operation
|
|
77
|
+
* this.enhancedLog({
|
|
78
|
+
* logMethod: this.logger.info,
|
|
79
|
+
* message: 'Operation finished successfully',
|
|
80
|
+
* logData: { userId: '12345' },
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* // Log a failed operation with an error
|
|
85
|
+
* this.enhancedLog({
|
|
86
|
+
* logMethod: this.logger.error,
|
|
87
|
+
* message: 'Operation failed',
|
|
88
|
+
* logData: { userId: '12345' },
|
|
89
|
+
* error: new Error('Unexpected error'),
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* // Log an initiated operation
|
|
94
|
+
* this.enhancedLog({
|
|
95
|
+
* logMethod: this.logger.info,
|
|
96
|
+
* message: 'Operation initiated',
|
|
97
|
+
* });
|
|
98
|
+
*/
|
|
99
|
+
enhancedLog({ logMethod, message, logData, error, }) {
|
|
100
|
+
const logPayload = {
|
|
101
|
+
...this.buildLogData(logData),
|
|
102
|
+
};
|
|
103
|
+
//* Add `executionTime` if the message is not about initiation
|
|
104
|
+
if (!message.includes('initiated')) {
|
|
105
|
+
logPayload.executionTime = this.getExecutionTime();
|
|
106
|
+
}
|
|
107
|
+
//* Add error details if present
|
|
108
|
+
if (error) {
|
|
109
|
+
logPayload.err = error;
|
|
110
|
+
}
|
|
111
|
+
//* Log the message with the appropriate level
|
|
112
|
+
logMethod(message, logPayload);
|
|
113
|
+
}
|
|
114
|
+
getExecutionTime() {
|
|
115
|
+
const executionTime = performance.now() - this.startTime;
|
|
116
|
+
if (executionTime >= 1000) {
|
|
117
|
+
//* Converting to seconds if the execution time is greater than 1000ms
|
|
118
|
+
return `${(executionTime / 1000).toFixed(2)}s`;
|
|
119
|
+
}
|
|
120
|
+
return `${executionTime.toFixed(2)}ms`;
|
|
121
|
+
}
|
|
122
|
+
buildLogData(logData) {
|
|
123
|
+
var _a;
|
|
124
|
+
return {
|
|
125
|
+
metadata: (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.getData(),
|
|
126
|
+
...logData,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
exports.Command = Command;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LogMethod = void 0;
|
|
4
|
+
const logger_1 = require("src/logger");
|
|
5
|
+
function LogMethod(options) {
|
|
6
|
+
return function (target, propertyKey, descriptor) {
|
|
7
|
+
const originalMethod = descriptor.value;
|
|
8
|
+
descriptor.value = async function (...args) {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
const className = target.constructor.name;
|
|
11
|
+
const params = (options === null || options === void 0 ? void 0 : options.logParams) ? args : undefined;
|
|
12
|
+
const metadata = (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.getData();
|
|
13
|
+
try {
|
|
14
|
+
logger_1.logger.info(`${className}.${propertyKey} Initiated`, {
|
|
15
|
+
metadata,
|
|
16
|
+
context: {
|
|
17
|
+
params,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
const result = await originalMethod.apply(this, args);
|
|
21
|
+
logger_1.logger.info(`${className}.${propertyKey} Finished`, {
|
|
22
|
+
metadata,
|
|
23
|
+
context: {
|
|
24
|
+
params,
|
|
25
|
+
result: (options === null || options === void 0 ? void 0 : options.logReturn) ? result : undefined,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (error instanceof Error) {
|
|
32
|
+
// Tentativa de deixar o stack trace mais limpo
|
|
33
|
+
const cleanStack = (_b = error.stack) === null || _b === void 0 ? void 0 : _b.split('\n').filter((line) => !line.includes('descriptor.value') &&
|
|
34
|
+
!line.includes('logMethod.decorator.ts') &&
|
|
35
|
+
!line.includes('node:internal/process/task_queues')).join('\n');
|
|
36
|
+
logger_1.logger.error(`${className}.${propertyKey} Failed`, {
|
|
37
|
+
err: { message: error.message, stack: cleanStack },
|
|
38
|
+
metadata,
|
|
39
|
+
context: {
|
|
40
|
+
params,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Caso o erro não seja uma instância de Error, logamos como um objeto desconhecido
|
|
46
|
+
logger_1.logger.error(`${className}.${propertyKey} Failed`, {
|
|
47
|
+
err: { message: 'Unknown error', details: error },
|
|
48
|
+
metadata,
|
|
49
|
+
context: {
|
|
50
|
+
params,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
return descriptor;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
exports.LogMethod = LogMethod;
|
package/general/index.d.ts
CHANGED
package/general/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MetadataModel = exports.copy = exports.shortUniqueId = exports.mergeDeep = exports.timeout = exports.randomSixDigitNumber = exports.pipe = void 0;
|
|
3
|
+
exports.Command = exports.MetadataModel = exports.copy = exports.shortUniqueId = exports.mergeDeep = exports.timeout = exports.randomSixDigitNumber = exports.pipe = void 0;
|
|
4
4
|
const nanoid_1 = require("nanoid");
|
|
5
5
|
function pipe(...fns) {
|
|
6
6
|
return (x) => fns.reduce((v, f) => f(v), x);
|
|
@@ -104,3 +104,5 @@ function copy(obj) {
|
|
|
104
104
|
exports.copy = copy;
|
|
105
105
|
var metadata_model_1 = require("./metadata.model");
|
|
106
106
|
Object.defineProperty(exports, "MetadataModel", { enumerable: true, get: function () { return metadata_model_1.MetadataModel; } });
|
|
107
|
+
var command_abstract_1 = require("./command.abstract");
|
|
108
|
+
Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return command_abstract_1.Command; } });
|
|
@@ -1,9 +1,45 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Represents metadata for tracking execution flow within commands.
|
|
3
|
+
*
|
|
4
|
+
* @param auditUuid - The UUID used to track the full execution flow.
|
|
5
|
+
* Example: The `auditUuid` from `OrderTravelCommand` will be passed to all items processed by `ProcessOrderItemCommand`.
|
|
6
|
+
* @param actionUuid - (Optional) The UUID used for tracking sub-flows.
|
|
7
|
+
* Example: `ProcessOrderItemCommand` generates its own `actionUuid` and passes it along for tracking each item.
|
|
8
|
+
* @param extraInfo - (Optional) Additional information related to the command.
|
|
9
|
+
*/
|
|
10
|
+
export interface IMetadata<T = any> {
|
|
2
11
|
auditUuid: string;
|
|
12
|
+
actionUuid?: string;
|
|
13
|
+
extraInfo?: T;
|
|
3
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* @param metadata - The metadata object containing execution tracking details.
|
|
17
|
+
*/
|
|
4
18
|
export declare class MetadataModel {
|
|
5
19
|
private metadata;
|
|
6
20
|
constructor(metadata: IMetadata);
|
|
21
|
+
/**
|
|
22
|
+
* Retrieves the complete metadata object.
|
|
23
|
+
*
|
|
24
|
+
* @returns The metadata object.
|
|
25
|
+
*/
|
|
7
26
|
getData(): IMetadata;
|
|
27
|
+
/**
|
|
28
|
+
* Retrieves the UUID used to track the full execution flow.
|
|
29
|
+
*
|
|
30
|
+
* @returns The audit UUID.
|
|
31
|
+
*/
|
|
8
32
|
getAuditUuid(): string;
|
|
33
|
+
/**
|
|
34
|
+
* Retrieves the UUID used for tracking sub-flows.
|
|
35
|
+
*
|
|
36
|
+
* @returns The action UUID, or undefined if not set.
|
|
37
|
+
*/
|
|
38
|
+
getActionUuid(): string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Retrieves additional information related to the execution flow.
|
|
41
|
+
*
|
|
42
|
+
* @returns The extra information, or undefined if not available.
|
|
43
|
+
*/
|
|
44
|
+
getExtraInfo<T = any>(): T | undefined;
|
|
9
45
|
}
|
|
@@ -1,15 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MetadataModel = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @param metadata - The metadata object containing execution tracking details.
|
|
6
|
+
*/
|
|
4
7
|
class MetadataModel {
|
|
5
8
|
constructor(metadata) {
|
|
6
9
|
this.metadata = metadata;
|
|
7
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Retrieves the complete metadata object.
|
|
13
|
+
*
|
|
14
|
+
* @returns The metadata object.
|
|
15
|
+
*/
|
|
8
16
|
getData() {
|
|
9
17
|
return this.metadata;
|
|
10
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves the UUID used to track the full execution flow.
|
|
21
|
+
*
|
|
22
|
+
* @returns The audit UUID.
|
|
23
|
+
*/
|
|
11
24
|
getAuditUuid() {
|
|
12
25
|
return this.metadata.auditUuid;
|
|
13
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Retrieves the UUID used for tracking sub-flows.
|
|
29
|
+
*
|
|
30
|
+
* @returns The action UUID, or undefined if not set.
|
|
31
|
+
*/
|
|
32
|
+
getActionUuid() {
|
|
33
|
+
return this.metadata.actionUuid;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Retrieves additional information related to the execution flow.
|
|
37
|
+
*
|
|
38
|
+
* @returns The extra information, or undefined if not available.
|
|
39
|
+
*/
|
|
40
|
+
getExtraInfo() {
|
|
41
|
+
return this.metadata.extraInfo;
|
|
42
|
+
}
|
|
14
43
|
}
|
|
15
44
|
exports.MetadataModel = MetadataModel;
|