UNPKG

ts-logs

Version:

This package provide a skd for audit and manager logs in nodejs and express

289 lines 12.5 kB
"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