ts-logs
Version:
This package provide a skd for audit and manager logs in nodejs and express
289 lines • 12.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Log = void 0;
const node_crypto_1 = require("node:crypto");
const write_default_local_util_1 = require("../utils/write-default-local.util");
const build_log_message_util_1 = require("../utils/build-log-message.util");
const delete_expired_file_util_1 = require("../utils/delete-expired-file.util");
const log_utils_1 = require("../utils/log.utils");
const s3_provider_1 = require("./s3-provider");
const http_provider_1 = require("./http-provider");
const get_logs_dirname_util_1 = require("../utils/get-logs-dirname.util");
const mongo_provider_1 = require("./mongo-provider");
/**
* @description Global log to manage steps and behavior.
* @summary Create a global log and added steps, print or publish result.
* @summary Check `stateType` option.
* It defines the behavior of the state. Whether to change state or return a new instance without changing original state.
* If `stateType` is defined as `stateful` the original state of log will be changed. If `stateType` is defined as `stateless`
* a new instance of Log will be created and returned without change the original state.
* @default `stateType` is `stateful`
*/
class Log {
constructor({ stateType, ...props }) {
this.uid = props.uid ?? (0, node_crypto_1.randomUUID)();
this.name = props.name ?? 'default';
this.ip = props.ip ?? 'none';
this.origin = props.origin ?? 'none';
this.createdAt = props?.createdAt ?? new Date();
this.stateType = stateType ?? 'stateful';
const statefulArr = props.steps ? [...props.steps] : [];
const statelessArr = Object.freeze(props.steps ?? []);
const isStateful = typeof stateType === 'undefined' || stateType === 'stateful';
this.steps = isStateful ? statefulArr : statelessArr;
!isStateful && Object.freeze(this);
}
/**
* @description Create a new global log.
* @param props as Partial LProps
* @returns instance of Log
*/
static init(props) {
return new Log(props);
}
/**
* @description Create a new global log changing stateType.
* @param stateType as LogStateType
* @returns instance of Log
*/
clone(stateType) {
return new Log({ ...this, stateType });
}
/**
* @description Check if exist some step for log.
* @returns true if exist some step and return false if step is empty.
*/
hasSteps() {
return this.steps.length > 0;
}
/**
* @description Create a new instance of Log with ip attribute. This is an immutable instance, the method does not change state, it returns a new one.
* @param ip as request origin address
* @returns instance of Log with ip address set
* @summary Check `stateType` option.
* It defines the behavior of the state. Whether to change state or return a new instance without changing original state.
* If `stateType` is defined as `stateful` the original state of log will be changed. If `stateType` is defined as `stateless`
* a new instance of Log will be created and returned without change the original state.
* @default `stateType` is `stateful`
*/
setIp(ip) {
if (this.stateType === 'stateful') {
this.ip = ip;
return this;
}
return new Log({ ...this, ip });
}
/**
* @description Set a new uid to identify the log instance
* @param uid as unique identifier id
* @returns instance of Log with uid set
* @summary Check `stateType` option.
* It defines the behavior of the state. Whether to change state or return a new instance without changing original state.
* If `stateType` is defined as `stateful` the original state of log will be changed. If `stateType` is defined as `stateless`
* a new instance of Log will be created and returned without change the original state.
* @default `stateType` is `stateful`
*/
setId(uid) {
if (this.stateType === 'stateful') {
this.uid = uid;
return this;
}
return new Log({ ...this, uid });
}
/**
* @description Create a new instance of Log with url attribute. This is an immutable instance, the method does not change state, it returns a new one.
* @param url as request origin url address
* @returns instance of Log with url address set
* @summary Check `stateType` option.
* It defines the behavior of the state. Whether to change state or return a new instance without changing original state.
* If `stateType` is defined as `stateful` the original state of log will be changed. If `stateType` is defined as `stateless`
* a new instance of Log will be created and returned without change the original state.
* @default `stateType` is `stateful`
*/
setOrigin(url) {
if (this.stateType === 'stateful') {
this.origin = url;
return this;
}
return new Log({ ...this, origin: url });
}
/**
* @description Define log name. This attribute is used to create a folder name on store local.
* @param name log name as string
* @returns instance of Log with log name set
* @summary Check `stateType` option.
* It defines the behavior of the state. Whether to change state or return a new instance without changing original state.
* If `stateType` is defined as `stateful` the original state of log will be changed. If `stateType` is defined as `stateless`
* a new instance of Log will be created and returned without change the original state.
* @default `stateType` is `stateful`
*/
setName(name) {
if (this.stateType === 'stateful') {
this.name = name;
return this;
}
return new Log({ ...this, name });
}
/**
* @description Add a log step to instance.
* @param step as instance of Step.
* @returns instance of Log with added step.
* @summary Check `stateType` option.
* It defines the behavior of the state. Whether to change state or return a new instance without changing original state.
* If `stateType` is defined as `stateful` the original state of log will be changed. If `stateType` is defined as `stateless`
* a new instance of Log will be created and returned without change the original state.
* @default `stateType` is `stateful`
*/
addStep(step) {
if (this.stateType === 'stateful') {
this.steps = [...this.steps, step];
return this;
}
return new Log({ ...this, steps: [...this.steps, step] });
}
/**
* @description Add a log step to instance.
* @param step as instance of Step.
* @returns instance of Log with added step.
* @summary Check `stateType` option.
* It defines the behavior of the state. Whether to change state or return a new instance without changing original state.
* If `stateType` is defined as `stateful` the original state of log will be changed. If `stateType` is defined as `stateless`
* a new instance of Log will be created and returned without change the original state.
* @default `stateType` is `stateful`
*/
addSteps(steps) {
if (this.stateType === 'stateful') {
this.steps = [...this.steps, ...steps];
return this;
}
return new Log({ ...this, steps: [...this.steps, ...steps] });
}
/**
* @description Remove a log step from instance.
* @param uid as step uid to identify what step to remove.
* @returns instance of Log without removed step.
* @summary Check `stateType` option.
* It defines the behavior of the state. Whether to change state or return a new instance without changing original state.
* If `stateType` is defined as `stateful` the original state of log will be changed. If `stateType` is defined as `stateless`
* a new instance of Log will be created and returned without change the original state.
* @default `stateType` is `stateful`
*/
removeStep(uid) {
const steps = this.steps.filter((step) => step.uid !== uid);
if (this.stateType === 'stateful') {
this.steps = steps;
return this;
}
return new Log({ ...this, steps });
}
/**
* @description Save logs locally where the app is running
* @param path absolute path of the folder where the file will be saved.
* @returns
* @emits fileName: Omit the file name as the file name is defined based on the log name plus creation date
* @example path: "/home/user/my-app/logs"
* @default path: "/[app-folder]/logs/[log-name]-[year]-[month]-[day].log".
* @throws If an error occurs in the local saving process, the logs will be displayed on the standard output (terminal)
*/
async writeLocal(path) {
try {
return (0, write_default_local_util_1.default)(this, path);
}
catch (error) {
(0, log_utils_1.default)(error.message + '\n');
return this.print();
}
}
/**
* @description Print log and all steps on terminal.
* @param locales as LocalesArgument to format date.
* @param options as DateTimeFormatOptions to format date.
*/
print(locales, options) {
const message = (0, build_log_message_util_1.default)(this, locales, options);
(0, log_utils_1.default)(message);
}
/**
* @description Publish log using a provider.
* @requires provider as `S3Config` or `HttpConfig` you can provide it using CONFIG @see example below.
* @todo implement provider to publish on
* @external aws-s3
* @external http
* @example
*
* import { Config, Log } from 'ts-logs';
*
* const httpConfig = Config.Http({ url: "https://domain.com/logs" });
*
* const log = Log.init({ name: "test..." });
*
* const result = await log.publish(httpConfig);
*
* console.log(result.statusCode);
*
* > 200
*
*/
async publish(config) {
try {
let result = null;
if (!!config?.ignoreEmpty && !(this.hasSteps())) {
return result;
}
else if (config?.bucketName && config?.region && config?.credentials) {
result = await s3_provider_1.default.save(config, this);
}
else if (config?.url && config.type !== 'mongodb') {
result = await http_provider_1.default.save(config, this);
}
else if (config.type === 'mongodb' && config.url) {
result = await mongo_provider_1.default.save(config, this);
}
if (!!(config?.clearAfterPublish))
this.clear();
return result;
}
catch (error) {
(0, log_utils_1.default)(`error on publish...${error.message}\n`);
return null;
}
}
/**
* @description Delete expired files based in 'days' params.
* @param days as integer.
* @param dirname as string.
*/
rmLogs(days, dirname) {
return new Promise((resolve, reject) => {
try {
const dir = (0, get_logs_dirname_util_1.GetLogsDirname)(this.name, dirname);
(0, delete_expired_file_util_1.DeleteExpiredFile)(days, dir);
resolve();
}
catch (error) {
(0, log_utils_1.default)(`error on delete expired files...${error.message}\n`);
reject(error);
}
});
}
/**
* @description Delete all steps from log instance and generate a new uid.
* @summary If stateType is defined as `stateful` the original state will be replaced.
* @summary If stateType is defined as `stateless` a new instance will be created and the original state will not be changed.
* @returns instance of Log
*/
clear() {
const uid = (0, node_crypto_1.randomUUID)();
if (this.stateType === 'stateful') {
this.createdAt = new Date();
this.steps = [];
this.uid = uid;
return this;
}
const createdAt = new Date();
return new Log({ ...this, steps: [], uid, createdAt });
}
}
exports.Log = Log;
exports.default = Log;
//# sourceMappingURL=log.js.map