From b4b4a8b7ca5d7a5dd9cbab6c8246bff2cab7a851 Mon Sep 17 00:00:00 2001 From: Angus ZENG Date: Sun, 14 Jan 2024 11:55:40 +0800 Subject: [PATCH] build(project): refactor the project, simplified the API and usage --- .vscode/launch.json | 57 +- .vscode/settings.json | 5 +- CHANGES.md | 4 + README.md | 80 +- docs/zh-CN/README.md | 4 - docs/zh-CN/apis/README.md | 15 - .../apis/functions/DEFAULT_JSON_FORMATTER.md | 9 - .../apis/functions/DEFAULT_TEXT_FORMATTER.md | 9 - .../apis/functions/createColorfulTTYDriver.md | 13 - .../apis/functions/createConsoleDriver.md | 9 - docs/zh-CN/apis/functions/createFactory.md | 25 - .../zh-CN/apis/functions/getDefaultFactory.md | 11 - .../apis/interfaces/IColorfulTTYDriver.md | 28 - docs/zh-CN/apis/interfaces/IDriver.md | 33 - docs/zh-CN/apis/interfaces/IFactory.md | 137 --- docs/zh-CN/apis/interfaces/IFormatter.md | 22 - docs/zh-CN/apis/interfaces/ILogger.md | 53 -- docs/zh-CN/tutorial/01-install.md | 29 - docs/zh-CN/tutorial/02-basic-usage.md | 179 ---- docs/zh-CN/tutorial/03-formatter.md | 129 --- docs/zh-CN/tutorial/04-custom-input.md | 112 --- docs/zh-CN/tutorial/05-custom-output.md | 178 ---- docs/zh-CN/tutorial/06-factory.md | 102 --- docs/zh-CN/tutorial/README.md | 10 - package-lock.json | 857 ++++++++---------- package.json | 14 +- src/examples/01.quick-start.ts | 133 --- src/examples/02.custom-formatter.ts | 121 --- src/examples/03.built-in-colorful-driver.ts | 67 -- src/examples/04.object-logs.ts | 96 -- src/examples/05.using-factory.ts | 126 --- .../{07.custom-driver.ts => custom-driver.ts} | 17 +- src/examples/custom-formatter.ts | 52 ++ .../{06.custom-levels.ts => custom-levels.ts} | 20 +- src/examples/quick-start.ts | 109 +++ src/examples/using-factory.ts | 98 ++ src/lib/Common.ts | 300 ------ src/lib/Decl.ts | 191 ++++ src/lib/Drivers/ColorfulTTY.ts | 251 ----- src/lib/Drivers/Console.ts | 5 +- src/lib/Factory.ts | 315 ++----- src/lib/Formatters.ts | 20 +- src/lib/Logger.ts | 205 +---- src/lib/index.ts | 10 +- tsconfig.json | 17 +- 45 files changed, 1057 insertions(+), 3220 deletions(-) delete mode 100644 docs/zh-CN/README.md delete mode 100644 docs/zh-CN/apis/README.md delete mode 100644 docs/zh-CN/apis/functions/DEFAULT_JSON_FORMATTER.md delete mode 100644 docs/zh-CN/apis/functions/DEFAULT_TEXT_FORMATTER.md delete mode 100644 docs/zh-CN/apis/functions/createColorfulTTYDriver.md delete mode 100644 docs/zh-CN/apis/functions/createConsoleDriver.md delete mode 100644 docs/zh-CN/apis/functions/createFactory.md delete mode 100644 docs/zh-CN/apis/functions/getDefaultFactory.md delete mode 100644 docs/zh-CN/apis/interfaces/IColorfulTTYDriver.md delete mode 100644 docs/zh-CN/apis/interfaces/IDriver.md delete mode 100644 docs/zh-CN/apis/interfaces/IFactory.md delete mode 100644 docs/zh-CN/apis/interfaces/IFormatter.md delete mode 100644 docs/zh-CN/apis/interfaces/ILogger.md delete mode 100644 docs/zh-CN/tutorial/01-install.md delete mode 100644 docs/zh-CN/tutorial/02-basic-usage.md delete mode 100644 docs/zh-CN/tutorial/03-formatter.md delete mode 100644 docs/zh-CN/tutorial/04-custom-input.md delete mode 100644 docs/zh-CN/tutorial/05-custom-output.md delete mode 100644 docs/zh-CN/tutorial/06-factory.md delete mode 100644 docs/zh-CN/tutorial/README.md delete mode 100644 src/examples/01.quick-start.ts delete mode 100644 src/examples/02.custom-formatter.ts delete mode 100644 src/examples/03.built-in-colorful-driver.ts delete mode 100644 src/examples/04.object-logs.ts delete mode 100644 src/examples/05.using-factory.ts rename src/examples/{07.custom-driver.ts => custom-driver.ts} (83%) create mode 100644 src/examples/custom-formatter.ts rename src/examples/{06.custom-levels.ts => custom-levels.ts} (64%) create mode 100644 src/examples/quick-start.ts create mode 100644 src/examples/using-factory.ts delete mode 100644 src/lib/Common.ts create mode 100644 src/lib/Decl.ts delete mode 100644 src/lib/Drivers/ColorfulTTY.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index d97f30a..e1ebf2c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,78 +7,61 @@ { "type": "node", "request": "launch", - "name": "[LiteRT/Logger] Example 01: Quick Start", - "program": "${workspaceFolder}/src/examples/01.quick-start.ts", + "name": "[LiteRT/Logger] Example Quick Start", + "program": "${workspaceFolder}/src/examples/quick-start.ts", "sourceMaps": true, "stopOnEntry": false, "outFiles": [ - "${workspaceFolder}/{lib,examples}/**/*.js" + "${workspaceFolder}/lib/**/*.js", + "${workspaceFolder}/examples/**/*.js", ] }, { "type": "node", "request": "launch", - "name": "[LiteRT/Logger] Example 02: Custom Formatter", - "program": "${workspaceFolder}/src/examples/02.custom-formatter.ts", + "name": "[LiteRT/Logger] Example: Custom Formatter", + "program": "${workspaceFolder}/src/examples/custom-formatter.ts", "sourceMaps": true, "stopOnEntry": false, "outFiles": [ - "${workspaceFolder}/{lib,examples}/**/*.js" + "${workspaceFolder}/lib/**/*.js", + "${workspaceFolder}/examples/**/*.js", ] }, { "type": "node", "request": "launch", - "name": "[LiteRT/Logger] Example 03: Built-In Colorful TTY Driver", - "program": "${workspaceFolder}/src/examples/03.built-in-colorful-driver.ts", + "name": "[LiteRT/Logger] Example: Using Factory", + "program": "${workspaceFolder}/src/examples/using-factory.ts", "sourceMaps": true, "stopOnEntry": false, "outFiles": [ - "${workspaceFolder}/{lib,examples}/**/*.js" + "${workspaceFolder}/lib/**/*.js", + "${workspaceFolder}/examples/**/*.js", ] }, { "type": "node", "request": "launch", - "name": "[LiteRT/Logger] Example 04: Object Logs", - "program": "${workspaceFolder}/src/examples/04.object-logs.ts", + "name": "[LiteRT/Logger] Example: Custom Levels", + "program": "${workspaceFolder}/src/examples/custom-levels.ts", "sourceMaps": true, "stopOnEntry": false, "outFiles": [ - "${workspaceFolder}/{lib,examples}/**/*.js" + "${workspaceFolder}/lib/**/*.js", + "${workspaceFolder}/examples/**/*.js", ] }, { "type": "node", "request": "launch", - "name": "[LiteRT/Logger] Example 05: Using Factory", - "program": "${workspaceFolder}/src/examples/05.using-factory.ts", + "name": "[LiteRT/Logger] Example: Custom Driver", + "program": "${workspaceFolder}/src/examples/custom-driver.ts", "sourceMaps": true, "stopOnEntry": false, "outFiles": [ - "${workspaceFolder}/{lib,examples}/**/*.js" - ] - }, - { - "type": "node", - "request": "launch", - "name": "[LiteRT/Logger] Example 06: Custom Levels", - "program": "${workspaceFolder}/src/examples/06.custom-levels.ts", - "sourceMaps": true, - "stopOnEntry": false, - "outFiles": [ - "${workspaceFolder}/{lib,examples}/**/*.js" - ] - }, - { - "type": "node", - "request": "launch", - "name": "[LiteRT/Logger] Example 07: Custom Driver", - "program": "${workspaceFolder}/src/examples/07.custom-driver.ts", - "sourceMaps": true, - "stopOnEntry": false, - "outFiles": [ - "${workspaceFolder}/{lib,examples}/**/*.js" + "${workspaceFolder}/lib/**/*.js", + "${workspaceFolder}/examples/**/*.js", ] } ] diff --git a/.vscode/settings.json b/.vscode/settings.json index 00ad71f..b73fbe7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,6 @@ { - "typescript.tsdk": "node_modules\\typescript\\lib" + "typescript.tsdk": "node_modules\\typescript\\lib", + "cSpell.words": [ + "unmute" + ] } \ No newline at end of file diff --git a/CHANGES.md b/CHANGES.md index 10e1b48..03db60a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Changes Logs +## v2.0.0 + +- build(project): refactor the project, simplified the API and usage. + ## v1.2.1 - fix(logger): removed debug code. diff --git a/README.md b/README.md index b2d86eb..cce402f 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,20 @@ [![GitHub issues](https://img.shields.io/github/issues/litert/logger.js.svg)](https://github.com/litert/logger.js/issues) [![GitHub Releases](https://img.shields.io/github/release/litert/logger.js.svg)](https://github.com/litert/logger.js/releases "Stable Release") -A logs-writer for LiteRT framework. +A logs writer for LiteRT framework. + +## Features + +- [x] Log stack trace. +- [x] Enable/Disable log levels. +- [x] Custom levels. +- [x] Custom formats. +- [x] Custom output drivers. ## Requirement -- TypeScript v2.7.1 (or newer) -- Node.js v8.0.0 (or newer) +- TypeScript v5.0.0 (or newer) +- Node.js v18.0.0 (or newer) ## Installation @@ -21,9 +29,71 @@ Install by NPM: npm i @litert/logger --save ``` -## Document +## Quick Start + +Simple usage: + +```ts +// The imported module is a LoggerFactory singleton object, so you can use it directly. +import LoggerFactory from "@litert/logger"; + +const logger = LoggerFactory.createLogger('Demo'); + +logger.info('Hello, world!'); +logger.warning('Hello, world!'); + +// Now, just disable a level, and it will not be printed. +logger.setLevelOptions({ levels: ['error'], enabled: false }); + +logger.error('Hello, world! (WILL NOT BE PRINTED)'); + +// let's turn on the stack trace, print 2 lines of stack trace. +// +// without specifying levels, all levels will be affected. +logger.setLevelOptions({ traceDepth: 2 }); + +logger.notice('Hello, world!'); +``` + +Use custom log formatter: + +```ts +import LoggerFactory from "@litert/logger"; + +LoggerFactory.setLevelOptions({ enabled: true }); + +const logger = LoggerFactory.createLogger('Demo'); + +logger.setLevelOptions({ + formatter: function(log, subj, lv, dt, traces): string { + + if (traces?.length) { + + return `${new Date(dt).toISOString()} - ${subj} - ${lv} - ${log} + + ${traces.join('\n ')} +`; + } + + return `${new Date(dt).toISOString()} - ${subj} - ${lv} - ${log}`; + } +}); + +logger.info('Hello, world!'); +logger.warning('Hello, world!'); + +logger.setLevelOptions({ traceDepth: 2 }); + +logger.error('Hello, world!'); +``` + +More Examples: -- [简体中文版](./docs/zh-CN/README.md) +- [Quick Start](./src/examples/quick-start.ts) +- [Custom log levels](./src/examples/custom-levels.ts) +- [Custom log formatter](./src/examples/custom-formatter.ts) +- [Custom log output driver](./src/examples/custom-driver.ts) +- [Using factory](./src/examples/using-factory.ts) ## License diff --git a/docs/zh-CN/README.md b/docs/zh-CN/README.md deleted file mode 100644 index 961e714..0000000 --- a/docs/zh-CN/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# LiteRT/Logger 文档 - -- [快速入门](./tutorial/README.md) -- [API 文档](./apis/README.md) diff --git a/docs/zh-CN/apis/README.md b/docs/zh-CN/apis/README.md deleted file mode 100644 index a04dba9..0000000 --- a/docs/zh-CN/apis/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# LiteRT/Logger API 文档 - -## 目录 - -- [`模块方法 createColorfulTTYDriver`](./functions/createColorfulTTYDriver.md) -- [`模块方法 createConsoleDriver`](./functions/createConsoleDriver.md) -- [`模块方法 createFactory`](./functions/createFactory.md) -- [`模块方法 getDefaultFactory`](./functions/getDefaultFactory.md) -- [`模块方法 DEFAULT_TEXT_FORMATTER`](./functions/DEFAULT_TEXT_FORMATTER.md) -- [`模块方法 DEFAULT_JSON_FORMATTER`](./functions/DEFAULT_JSON_FORMATTER.md) -- [`接口 IColorfulTTYDriver`](./interfaces/IColorfulTTYDriver.md) -- [`接口 IDriver`](./interfaces/IDriver.md) -- [`接口 IFactory`](./interfaces/IFactory.md) -- [`接口 IFormatter`](./interfaces/IFormatter.md) -- [`接口 ILogger`](./interfaces/ILogger.md) diff --git a/docs/zh-CN/apis/functions/DEFAULT_JSON_FORMATTER.md b/docs/zh-CN/apis/functions/DEFAULT_JSON_FORMATTER.md deleted file mode 100644 index 2aff81d..0000000 --- a/docs/zh-CN/apis/functions/DEFAULT_JSON_FORMATTER.md +++ /dev/null @@ -1,9 +0,0 @@ -# 模块方法 DEFAULT_JSON_FORMATTER - -该方法是默认的自定义输入类型日志格式化函数。 - -## 声明 - -```ts -declare const DEFAULT_JSON_FORMATTER: IFormatter; -``` diff --git a/docs/zh-CN/apis/functions/DEFAULT_TEXT_FORMATTER.md b/docs/zh-CN/apis/functions/DEFAULT_TEXT_FORMATTER.md deleted file mode 100644 index 1e45832..0000000 --- a/docs/zh-CN/apis/functions/DEFAULT_TEXT_FORMATTER.md +++ /dev/null @@ -1,9 +0,0 @@ -# 模块方法 DEFAULT_TEXT_FORMATTER - -该方法是默认的文本日志格式化函数。 - -## 声明 - -```ts -declare const DEFAULT_TEXT_FORMATTER: IFormatter; -``` diff --git a/docs/zh-CN/apis/functions/createColorfulTTYDriver.md b/docs/zh-CN/apis/functions/createColorfulTTYDriver.md deleted file mode 100644 index bd8b08a..0000000 --- a/docs/zh-CN/apis/functions/createColorfulTTYDriver.md +++ /dev/null @@ -1,13 +0,0 @@ -# 模块方法 createColorfulTTYDriver - -该方法用于创建一个新的彩色命令行输出驱动对象。 - -## 声明 - -```ts -function createColorfulTTYDriver(): IColorfulTTYDriver; -``` - -## 注意 - -如果当前输出环境不支持彩色输出,则降级为控制台输出。 diff --git a/docs/zh-CN/apis/functions/createConsoleDriver.md b/docs/zh-CN/apis/functions/createConsoleDriver.md deleted file mode 100644 index aed07e2..0000000 --- a/docs/zh-CN/apis/functions/createConsoleDriver.md +++ /dev/null @@ -1,9 +0,0 @@ -# 模块方法 createConsoleDriver - -该方法用于创建一个新的控制台输出驱动对象。 - -## 声明 - -```ts -function createConsoleDriver(): IDriver; -``` diff --git a/docs/zh-CN/apis/functions/createFactory.md b/docs/zh-CN/apis/functions/createFactory.md deleted file mode 100644 index 59e00dd..0000000 --- a/docs/zh-CN/apis/functions/createFactory.md +++ /dev/null @@ -1,25 +0,0 @@ -# 模块方法 createFactory - -该方法用于创建一个新的日志控制器工厂。 - -## 声明 - -```ts -type DefaultLevels = "error" | "notice" | "warning" | "debug" | "info"; - -function createFactory< - L extends string = DefaultLevels ->(levels: L[]): IFactory; -``` - -## 参数 - -- 泛型参数 `L` - - 指定可以使用的日志等级,用于静态类型检查和 IDE 自动完成。 - -- 形参 `levels` - - 真正起定义日志等级的作用。 - - diff --git a/docs/zh-CN/apis/functions/getDefaultFactory.md b/docs/zh-CN/apis/functions/getDefaultFactory.md deleted file mode 100644 index a6afca8..0000000 --- a/docs/zh-CN/apis/functions/getDefaultFactory.md +++ /dev/null @@ -1,11 +0,0 @@ -# 模块方法 getDefaultFactory - -该方法用于获取默认的日志控制器工厂。 - -## 声明 - -```ts -type DefaultLevels = "error" | "notice" | "warning" | "debug" | "info"; - -function getDefaultFactory(): IFactory; -``` diff --git a/docs/zh-CN/apis/interfaces/IColorfulTTYDriver.md b/docs/zh-CN/apis/interfaces/IColorfulTTYDriver.md deleted file mode 100644 index b6a37b0..0000000 --- a/docs/zh-CN/apis/interfaces/IColorfulTTYDriver.md +++ /dev/null @@ -1,28 +0,0 @@ -# 接口 IColorfulTTYDriver - -该接口定义彩色命令行输出驱动的方法列表。 - -```ts -type ColorSet = "blue" | "cyan" | "green" | "magenta" | "grey" | - "red" | "yellow" | "white" | "black" | "default"; - -interface IColorfulTTYDriver -extends IDriver { - - /** - * 设置指定等级的日志的输出前景色。 - * - * @param color 颜色名称 - * @param level 指定要设置的日志等级。如果不指定,则修改默认的日志输出颜色。 - */ - foreColor(color: ColorSet, level?: string): this; - - /** - * 设置指定等级的日志的输出背景色。 - * - * @param color 颜色名称 - * @param level 指定要设置的日志等级。如果不指定,则修改默认的日志输出颜色。 - */ - bgColor(color: ColorSet, level?: string): this; -} -``` diff --git a/docs/zh-CN/apis/interfaces/IDriver.md b/docs/zh-CN/apis/interfaces/IDriver.md deleted file mode 100644 index 8997869..0000000 --- a/docs/zh-CN/apis/interfaces/IDriver.md +++ /dev/null @@ -1,33 +0,0 @@ -# 接口 IDriver - -该接口定义日志控制器输出驱动的方法列表。 - -```ts -interface IDriver { - - /** - * 该方法提供给日志控制器调用,用于写日志到输出设备。 - * - * @param text 已经格式化的日志文本 - * @param subject 日志的主题 - * @param level 日志的等级 - * @param date 日志的时间 - */ - write( - text: string, - subject: string, - level: string, - date: Date - ): void; - - /** - * 将输出缓存中的日志全部输出到输出设备。 - */ - flush(): void | Promise; - - /** - * 关闭驱动。 - */ - close(): void | Promise; -} -``` diff --git a/docs/zh-CN/apis/interfaces/IFactory.md b/docs/zh-CN/apis/interfaces/IFactory.md deleted file mode 100644 index 57e1e4a..0000000 --- a/docs/zh-CN/apis/interfaces/IFactory.md +++ /dev/null @@ -1,137 +0,0 @@ -# 接口 IFactory - -该接口定义日志控制器工厂的方法列表。 - -```ts -interface IFactory< - /** - * L 是日志控制器工厂支持的日志等级列表。 - */ - L extends string -> { - - /** - * 对于所有该工厂创建的控制器对象,关闭输出指定等级的日志。 - * - * @param level 指定一个或者多个日志等级,留空或者输入空数组表示所有等级 - */ - mute(level?: L | L[]): this; - - /** - * 对于所有该工厂创建的控制器对象,打开输出指定等级的日志。 - * - * @param level 指定一个或者多个日志等级,留空或者输入空数组表示所有等级 - */ - unmute(level?: L | L[]): this; - - /** - * 对于所有该工厂创建的控制器对象,打开或者关闭日志输出位置的追踪信息。 - * - * @param depth 指定要输出的追踪信息层数,默认为 1 层,设置为 0 则不输出、 - * @param level 指定一个或者多个日志等级,留空或者输入空数组则表示所有等级 - */ - enableTrace(depth?: number, level?: L | L[]): this; - - /** - * 注册一个新的日志输出驱动。 - * - * @param name 驱动唯一名称。 - * @param driver 驱动对象。 - */ - registerDriver(name: string, driver: IDriver): boolean; - - /** - * 根据驱动的唯一注册名称,获取驱动对象。 - * - * 如果不存在,则返回 null。 - * - * @param name 驱动的唯一注册名称 - */ - getDriver(name: string): IDriver | null; - - /** - * 获取所有已经注册的驱动对象唯一注册名称列表。 - */ - getDriverNames(): string[]; - - /** - * 注册一个新的自定义输入类型的日志格式化函数。 - * - * @param name 日志格式化函数的唯一注册名称。 - * @param formatter 日志格式化函数 - */ - registerDataFormatter(name: string, formatter: IFormatter): boolean; - - /** - * 注册一个新的文本型的日志格式化函数。 - * - * @param name 日志格式化函数的唯一注册名称。 - * @param formatter 日志格式化函数 - */ - registerTextFormatter(name: string, formatter: IFormatter): boolean; - - /** - * 根据唯一注册名称获取一个自定义输入类型的日志格式化函数。 - * - * @param name 唯一注册名称 - */ - getDataFormatter(name: string): IFormatter; - - /** - * 根据唯一注册名称获取一个文本型的日志格式化函数。 - * - * @param name 唯一注册名称 - */ - getTextFormatter(name: string): IFormatter; - - /** - * 获取所有已经注册的自定义输入类型日志格式化函数的名称。 - */ - getDataFormatterNames(): string[]; - - /** - * 获取所有已经注册的文本型日志格式化函数的名称。 - */ - getTextFormatterNames(): string[]; - - /** - * 获取所有该工厂创建的日志控制器对象的主题列表。 - */ - getSubjects(): string[]; - - /** - * 获取该工厂支持的所有日至等级列表。 - */ - getLevels(): L[]; - - /** - * 创建一个文本型的日志控制器。 - * - * 已经存在则返回已存在的控制器对象。 - * - * @param subject 日志的主题。(默认值:default) - * @param formatter 日志格式化函数或者预注册的格式化函数唯一名称。(默认值:default) - * @param driver 已注册的驱动名称。(默认值:console) - */ - createTextLogger( - subject?: string, - formatter?: IFormatter | string, - driver?: string - ): ILogger; - - /** - * 创建一个自定义输入类型的日志控制器。 - * - * 已经存在则返回已存在的控制器对象。 - * - * @param subject 日志的主题。(默认值:default) - * @param formatter 日志格式化函数或者预注册的格式化函数唯一名称。(默认值:default) - * @param driver 已注册的驱动名称。(默认值:console) - */ - createDataLogger( - subject?: string, - formatter?: IFormatter | string, - driver?: string - ): ILogger; -} -``` \ No newline at end of file diff --git a/docs/zh-CN/apis/interfaces/IFormatter.md b/docs/zh-CN/apis/interfaces/IFormatter.md deleted file mode 100644 index 876b6b1..0000000 --- a/docs/zh-CN/apis/interfaces/IFormatter.md +++ /dev/null @@ -1,22 +0,0 @@ -# 接口 IFactory - -该接口定义日志格式化函数。 - -```ts -/** - * 用于格式化日志为字符串的函数。 - * - * @param log 日志的输入内容。 - * @param subject 日志的主题。 - * @param level 日志等级。 - * @param date 日志写入时间。 - * @param traces 日志的追踪信息。 - */ -export type IFormatter = ( - log: T, - subject: string, - level: L, - date: Date, - traces?: string[] -) => string; -``` diff --git a/docs/zh-CN/apis/interfaces/ILogger.md b/docs/zh-CN/apis/interfaces/ILogger.md deleted file mode 100644 index bfebd9d..0000000 --- a/docs/zh-CN/apis/interfaces/ILogger.md +++ /dev/null @@ -1,53 +0,0 @@ -# 接口 ILogger - -该接口定义日志控制器的方法列表。 - -```ts -interface ILogger { - - /** - * 获取该控制器的日志主题。 - */ - getSubject(): string; - - /** - * 获取该控制器支持的所有日至等级列表。 - */ - getLevels(): L[]; - - /** - * 打开或者关闭日志输出位置的追踪信息。 - * - * @param depth 指定要输出的追踪信息层数,默认为 1 层,设置为 0 则不输出、 - * @param level 指定一个或者多个日志等级,留空或者输入空数组则表示所有等级 - */ - enableTrace(depth?: number, level?: L | L[]): this; - - /** - * 打开输出指定等级的日志。 - * - * @param level 指定一个或者多个日志等级,留空或者输入空数组表示所有等级 - */ - unmute(level?: L | L[]): this; - - /** - * 关闭输出指定等级的日志。 - * - * @param level 指定一个或者多个日志等级,留空或者输入空数组表示所有等级 - */ - mute(level?: L | L[]): this; - - /** - * 刷新输出驱动的缓存。 - */ - flush(): void | Promise; - - /** - * 日志等级名称对应的日志写入方法。 - * - * @param log 输入的日志内容 - * @param date 日志的产生时间,默认为当前时间。 - */ - [key in L]: (log: T, date?: Date): this; -} -``` \ No newline at end of file diff --git a/docs/zh-CN/tutorial/01-install.md b/docs/zh-CN/tutorial/01-install.md deleted file mode 100644 index 7228d25..0000000 --- a/docs/zh-CN/tutorial/01-install.md +++ /dev/null @@ -1,29 +0,0 @@ -# 安装与使用 - -## 安装 - -推荐使用 NPM 安装,例如: - -```sh -npm i @litert/logger -S -``` - -如果想使用开发版本,则使用下面的语句 - -```sh -npm i @litert/logger@dev -S -``` - -## 使用 - -通过 import/require 导入即可使用。 - -```ts -import Loggers from "@litert/logger"; - -let log = Loggers.createTextLogger("Example"); - -log.unmute(); - -log.info("Hello world!"); -``` diff --git a/docs/zh-CN/tutorial/02-basic-usage.md b/docs/zh-CN/tutorial/02-basic-usage.md deleted file mode 100644 index 4ca18b1..0000000 --- a/docs/zh-CN/tutorial/02-basic-usage.md +++ /dev/null @@ -1,179 +0,0 @@ -# 基本使用 - -## 1. 文本日志 - -通常日志都是写入一些文本记录。 - -先来看一个例子: - -```ts -/** - * 导入 Logger 库,并命名为 Loggers。 - * - * 此处 Loggers 其实是一个日志控制器工厂对象,用来创建不同的日志控制器对象。 - */ -import Loggers from "@litert/logger"; - -/** - * 使用日志控制器工厂对象创建一个主题为 Text-Log 的文本日志控制器对象。 - */ -let log = Loggers.createTextLogger("Text-Log"); - -/** - * 默认情况下,所有的日志都是被关闭输出的,通过 unmute 方法可以打开一个或者所有等级的 - * 日志的输出。 - */ -log.unmute(); - -/** - * 好了,现在可以输出日志,来输出一条 INFO 等级的日志试试。 - */ -log.info("Hello world!"); -``` - -编译并运行上面的代码,将会看到一行输出如下: - -``` -[2018-08-12T07:57:23.400Z][info] Text-Log: Hello world! -``` - -## 2. 基本概念 - -上面的代码里,我们接触到了如下概念: - -- 日志控制器 -- 日志控制器工厂 -- 日志等级 - -让我逐个解释下。 - -### 2.1. 日志控制器 - -日志控制器是指直接在代码里用来输出日志的对象,也就是上面代码里面的 `log` 变量,它是 -一个仅支持文本输入的日志控制器对象。 - -### 2.2. 日志控制器工厂 - -正如字面意思,日志控制器是由一个工厂对象创建的,这个工厂对象就叫做**日志控制器工厂**。 -我们通过 TypeScript 的 `import` 语法导入了 `Loggers` 这个变量,其实它是一个默认的 -日志控制器工厂对象,你也可以再创建一个新的日志控制器工厂,具体请看后文。 - -### 2.3. 日志等级 - -日志是用来记录程序运行过程中的一些事件的,不同事件的重要程度不同,这个程度也就是 -“日志等级”。日志有多少个等级是在创建日志控制工厂时就确定的,其下所有日志控制器都有 -相同的日志等级, - -> 默认日志控制器工厂提供 `debug`、`info`、`error`、`warning`、`notice` 五个等级。 -> 如果不能满足,请尝试创建新的日志控制器工厂。 - -## 3. 日志控制器的基本方法 - -### 3.1. mute/unmute 方法 - -前面提到,所有日志等级都是默认关闭输出的,可以使用日志控制器的 `unmute` 方法打开。 - -```ts -log.unmute(); // 打开所有等级的日志输出 -log.unmute("debug"); // 打开 DEBUG 等级的日志输出 -log.unmute([ // 打开 INFO 和 ERROR 等级的日志输出 - "info", - "error" -]); -``` - -同理,可以用 `mute` 方法关闭各个等级的日志输出。 - -```ts -log.mute(); // 关闭所有等级的日志输出 -log.mute("debug"); // 关闭 DEBUG 等级的日志输出 -log.mute([ // 关闭 INFO 和 ERROR 等级的日志输出 - "info", - "error" -]); -``` - -### 3.2. 日志输出方法 - -使用日志等级名称相同的方法名,即可输出该等级的日志,例如: - -```ts -log.error("This is a piece of ERROR log."); -log.warning("This is a piece of WARNING log."); -log.notice("This is a piece of NOTICE log."); -log.info("This is a piece of INFO log."); -log.debug("This is a piece of DEBUG log."); -``` - -这些日志输出方法声明如下:(以 `error` 为例) - -```ts -public error( - log: string, - data?: Date -): this; -``` - -可见,它都返回日志控制器对象本身。所以上面的代码可以用链式写法: - -```ts -log.error("This is a piece of ERROR log.") -.warning("This is a piece of WARNING log.") -.notice("This is a piece of NOTICE log.") -.info("This is a piece of INFO log.") -.debug("This is a piece of DEBUG log."); -``` - -此外,我们注意到它还有第二个参数,一个可选的 Date 类型的参数。这个参数用于指定日志的 -发生时间,如果省略,则会使用系统当前时间,例如: - -```ts -log.info("Using default."); -log.info("Using custom time.", new Date("2018-02-01 00:00:00")); -``` - -### 3.3. 日志追踪 - -很多时候,日志都是用于调试的,那么很可能需要得到日志的写入位置。那么,可以使用 -日志控制器的 `enableTrace` 方法。 - -```ts -log.enableTrace(); // 打开所有等级日志的追踪信息。 -log.info("See the trace info below."); -``` - -将会看到类型如下的输出: - -``` -[2018-08-12T08:32:08.341Z][info] Trace: See the trace info below. - at traceDemo (/home/fenying/logger/examples/demo.js:58:4) -``` - -可以看到日志的输出位置。 - -该方法声明如下: - -```ts -public enableTrace( - depth: number = 1, - levels?: string | string[] -): this; -``` - -第一个参数指定要显示的调用栈深度,设置为 0 则不显示。 -第二个参数指定要配置的日志等级,默认是配置所有的日志等级。 - -例如: - -```ts -log.enableTrace(); // 将所有等级的日志追踪信息设置为 1 层。 -log.enableTrace(5); // 将所有等级的日志追踪信息设置为 5 层。 -log.enableTrace(0); // 关闭所有等级的日志追踪信息。 -log.enableTrace(0, []); // 关闭所有等级的日志追踪信息。 -log.enableTrace( // 将 DEBUG 日志追踪信息设置为 3 层。 - 3, "debug" -); -log.enableTrace( // 关闭 INFO/ERROR 日志的追踪信息。 - 0, ["info", "error"] -); -``` diff --git a/docs/zh-CN/tutorial/03-formatter.md b/docs/zh-CN/tutorial/03-formatter.md deleted file mode 100644 index dd9eb47..0000000 --- a/docs/zh-CN/tutorial/03-formatter.md +++ /dev/null @@ -1,129 +0,0 @@ -# 日志格式化 - -## 格式化函数 - -我们注意到,日志的输出都是如下格式的 - -``` -[2018-08-12T07:57:23.400Z][info] Text-Log: Hello world! -``` - -也就是 - -``` -[yyyy-mm-ddThh:mm:ss.###Z][LEVEL] SUBJECT: LOG_TEXT -``` - -这样的格式。 - -如果希望换一个格式怎么办呢?很简单,来看看日志控制器工厂的 `createTextLogger` 方法。 - -```ts -public createTextLogger( - subject?: string, - formatter?: IFormatter, - driver?: string -): ILogger; -``` - -第一个参数 `subject` 我们已经知道,是控制器的主题。 -第二个参数 `formatter` 是我们要关注的格式化方法。 - -> 暂且忽略第三个参数,将在后文中提到。 - -`formatter` 是一个 `IFormatter` 类型的参数,来看看 `IFormatter` -的定义。 - - -```ts -/** - * 一个用于格式化日志为字符串的函数。 - * - * @param log 日志的输入内容。 - * @param subject 日志的主题。 - * @param level 日志等级。 - * @param date 日志写入时间。 - * @param traces 日志的追踪信息。 - */ -export type IFormatter = ( - log: T, - subject: string, - level: L, - date: Date, - traces?: string[] -) => string; -``` - -> - 对于文本日志,`T` 总是 `string`。 -> - 对于默认的日志控制器工厂,`L` 总是 `DefaultLevels`。也就是 -> -> ```ts -> type DefaultLevels = "error" | "notice" | "warning" | -> "debug" | "info"; -> ``` - -因此,它其实是一个函数,将日志的内容进行处理,返回格式化之后的文本内容。 - -根据上面的信息,我们可以实现一个自定义的格式化函数: - -```ts -const log = Loggers.createTextLogger( - "Custom-Formatter", - function(text, subject, level, date, traces): string { - - let ret = `${date} - ${subject} - ${level} - ${text}`; - - if (traces) { - - ret += `\nTrace Stack:\n ${traces.join("\n ")}`; - } - - return ret; - } -); - -log.info("Hello"); - -log.enableTrace(); - -log.info("world"); -``` - -尝试运行,可以得到如下输出: - -``` -Sun Aug 12 2018 17:04:26 GMT+0800 (中国标准时间) - Custom-Formatter - info - Hello -Sun Aug 12 2018 17:04:26 GMT+0800 (中国标准时间) - Custom-Formatter - info - world -Trace Stack: - formatterDemo (/home/fenying/logger/examples/demo.js:99:4) -``` - -## 预注册格式化函数 - -通常来说,一个格式化函数是反复使用的,所以,可以通过 `IFactory.registerTextFormatter` 和 -`IFactory.registerDataFormatter` 两个方法,将一个格式化函数进行预注册,然后通过注册的名称即可使用。 - -```ts - -Loggers.registerTextFormatter( - "custom_formatter_1", - function(text, subject, level, date, traces): string { - - let ret = `${date} - ${subject} - ${level} - ${text}`; - - if (traces) { - - ret += `\nTrace Stack:\n ${traces.join("\n ")}`; - } - - return ret; - } -); - -const log = Loggers.createTextLogger( - "Custom-Formatter", - "custom_formatter_1" -); - -log.info("Hello"); -``` diff --git a/docs/zh-CN/tutorial/04-custom-input.md b/docs/zh-CN/tutorial/04-custom-input.md deleted file mode 100644 index b1c31e6..0000000 --- a/docs/zh-CN/tutorial/04-custom-input.md +++ /dev/null @@ -1,112 +0,0 @@ -# 自定义输入格式 - -前面我们使用的都是将字符串文本作为日志内容,传递给日志控制器对象。假如需要更复杂的输入 -内容呢?例如某些 API 网关需要记录 API 访问日志,那么肯定不是用字符串能简单解决的。 - -下面来看看日志控制器工厂对象的 `createDataLogger` 方法。 - -```ts -public createDataLogger( - subject?: string, - formatter?: IFormatter, - driver?: string -): ILogger; -``` - -这个方法有一个可选的泛型参数 `T`,这个泛型参数也就是用于指定创建出来的控制器能接受什么 -作为日志的输入内容。下面看个示例: - -```ts -interface HTTPLog { - - method: "GET" | "POST" | "HEAD"; - - ip: string; - - uri: string; -} - -const logs = Loggers.createDataLogger("HTTP-Logs"); - -logs.unmute(); - -logs.info({ - ip: "192.168.1.122", - method: "GET", - uri: "/index.html" -}); - -logs.info({ - ip: "192.168.1.128", - method: "POST", - uri: "/upload.php" -}); -``` - -运行得到输出如下: - -``` -{"subject":"HTTP-Logs","level":"info","date":1534066661287,"log":{"ip":"192.168.1.122","method":"GET","uri":"/index.html"}} -{"subject":"HTTP-Logs","level":"info","date":1534066661287,"log":{"ip":"192.168.1.122","method":"POST","uri":"/upload.php"}} -``` - -咦,输出变成了 JSON ?是的,这不是出错了。因为 `createDataLogger` 方法使用的默认的 -格式化函数就是将日志格式化为 JSON。 - -所以你也可以自己实现一个格式化函数,例如: - -```ts -interface HTTPLog { - - method: "GET" | "POST" | "HEAD"; - - ip: string; - - uri: string; -} - -const logs = Loggers.createDataLogger( - "HTTP-Logs", - function(log, subject, level, date, traces): string { - - /** - * 注意这里 log 不是 string 类型,而是 HTTPLog 类型的对象。 - */ - return `${date} - ${log.ip} - ${log.method} ${log.uri}`; - } -); - -logs.unmute(); - -logs.info({ - ip: "192.168.1.122", - method: "GET", - uri: "/index.html" -}); - -logs.info({ - ip: "192.168.1.128", - method: "POST", - uri: "/upload.php" -}); -``` - -得到如下输出: - -``` -Sun Aug 12 2018 17:30:16 GMT+0800 (中国标准时间) - 192.168.1.122 - GET /index.html -Sun Aug 12 2018 17:30:16 GMT+0800 (中国标准时间) - 192.168.1.128 - POST /upload.php -``` - -> 从 `createDataLogger` 方法声明可以看出, `createTextLogger` 方法只是对 -> `createDataLogger` 方法的一层封装。相当于 -> -> ```ts -> Loggers.createDataLogger( -> subject, -> DEFAULT_TEXT_FORMATTER -> ); -> ``` -> -> 是的,`createTextLogger` 使用的默认格式化函数为 `DEFAULT_TEXT_FORMATTER`, -> 而 `createDataLogger` 则是使用 `DEFAULT_JSON_FORMATTER`。 diff --git a/docs/zh-CN/tutorial/05-custom-output.md b/docs/zh-CN/tutorial/05-custom-output.md deleted file mode 100644 index e09296a..0000000 --- a/docs/zh-CN/tutorial/05-custom-output.md +++ /dev/null @@ -1,178 +0,0 @@ -# 自定义输出位置 - -## 1. 使用驱动 - -到目前为止,我们讨论的日志全部都是输出到控制台。假如我们需要输出到文件该怎么办? - -在之前的内容里,`createTextLogger` 和 `createDataLogger` 方法的第三个参数 `driver` -一直都被忽略了。其实,这个参数就是用于指定日志的输出驱动的名字。 - -`driver` 一词取自“驱动”之意,意味着只要改动这个参数,就可以完成输出位置的改动,将 -格式化好的日志内容输出到指定的地方。例如文件、数据库、Redis…… - -下面我们看看驱动如何使用。 - -控制器工厂提供了三个与驱动相关的方法。 - -```ts -/** - * 获取已经注册的驱动名称列表。 - */ -public getDriverNames(): string[]; - -/** - * 根据驱动注册的名称,获取驱动对象。 - */ -public getDriver(name: string): IDriver | null; - -/** - * 注册一个新的驱动。 - */ -public registerDriver(name: string, driver: IDriver): boolean; -``` - -从这三个方法可以看出,驱动是要先注册才能使用的。 - -由于每个驱动对象都可以注册一个名称,也就是说,同一种驱动的不同实例对象,可以注册为多个 -不同名称的驱动。 - -例如:(假设有一个驱动叫 `FileLogDriver`,用于将日志写到文件里) - -```ts -Loggers.registerDriver( - "file-a", - new FileLogDriver("/home/fenying/a.log") -); - -Loggers.registerDriver( - "file-b", - new FileLogDriver("/home/fenying/b.log") -); -``` - -然后在创建日志控制器的时候,指定对应的驱动: - -```ts -const logs = Loggers.createTextLogger( - "Example", - undefined, // 使用默认的格式化函数 - "file-a" -); -``` - -## 2. 实现自定义驱动 - -可以根据需要自行实现一个驱动,先看看 `IDriver` 的定义: - -```ts -interface IDriver { - - /** - * 该方法提供给日志控制器调用,用于写日志到输出设备。 - * - * @param text 已经格式化的日志文本 - * @param subject 日志的主题 - * @param level 日志的等级 - * @param date 日志的时间 - */ - write( - text: string, - subject: string, - level: string, - date: Date - ): void; - - /** - * 将输出缓存中的日志全部输出到输出设备。 - */ - flush(): void | Promise; - - /** - * 关闭驱动。 - */ - close(): void | Promise; -} -``` - -对于一个驱动,只需要实现上面三个方法即可。 - -下面来写一个简单的文件驱动。 - -```ts -import * as fs from "fs"; - -class FileLogDriver implements IDriver { - - private _ws: fs.WriteStream; - - public constructor(file: string) { - - this._ws = fs.createWriteStream(file); - } - - public write( - text: string, - subject: string, - level: string, - date: Date - ): void { - - if (this._ws) { - - this._ws.write(text + "\n"); - } - } - - public flush(): void | Promise { - - // 未使用缓存,此处什么都不用做。 - return; - } - - public close(): void | Promise { - - this._ws.end(); - delete this._ws; - } -} -``` - -然后就可以使用它了。 - -```ts - -const fd = new FileLogDriver("a.log"); - -Loggers.registerDriver( - "file-a", - fd -); - -const logs = Loggers.createTextLogger( - "Example", - undefined, - "file-a" -); - -logs.unmute(); - -logs.info("HI"); - -logs.debug("Hello"); - -fd.close(); -``` - -执行后看看当前目录下的 `a.log` 文件,是否有日志内容? - -## 3. 内置的驱动 - -内置的驱动有两种: - -- `Console` - - 默认的驱动类型,注册名为 `console`。 - -- `ColorfulTTY` - - 提供输出颜色支持的命令行输出功能,可以使用 `createColorfulTTYDriver` 方法创建。 diff --git a/docs/zh-CN/tutorial/06-factory.md b/docs/zh-CN/tutorial/06-factory.md deleted file mode 100644 index de5f709..0000000 --- a/docs/zh-CN/tutorial/06-factory.md +++ /dev/null @@ -1,102 +0,0 @@ -# 工厂与日志等级 - -## 1. 创建自定义工厂 - -至此,与日志控制器有关的内容基本都学完了,最后来看一下控制器工厂的使用。到目前为止, -我们使用的都是默认的控制器工厂,那要如何创建一个控制器工厂呢? - -使用 `createFactory` 方法即可,它的声明如下: - -```ts -function createFactory< - L extends string = DefaultLevels ->(levels: L[]): IFactory; -``` - -这个方法有两个参数: - -- 泛型参数 `L` ,指定可以使用的日志等级,这个参数用于静态类型检查和 IDE 自动完成。 -- 形参 `levels`,它是 `L` 类型的数组,这个参数才真正起定义日志等级的作用。 - -也就是说通过 `L` 指定 `levels` 可以输入的值,用于 TypeScript 静态类型检查,和 IDE 的 -自动完成、语法提示等。 `levels` 才是真正在运行时定义可用日志等级的参数。 - -> 对于默认工厂,参数 `L = DefaultLevels`,`levels = DEFAULT_LEVELS`。 - -例如: - -```ts -import Loggers, { createFactory } from "@litert/logger"; - -/** - * 定义三种日志等级。 - */ -type MyLevels = "normal" | "secure" | "failure"; - -const factory1 = createFactory([ - "normal", "secure", "failure" -]); - -const logs = factory1.createTextLogger("Test"); - -logs.unmute(); - -logs.normal("This is a NORMAL log."); - -logs.secure("This is a SECURE log."); -``` - -## 2. 工厂的基本方法 - -### 2.1. mute/unmute - -类似日志控制器,每个工厂也提供 mute/unmute 方法,这两个方法作用于所有由该工厂创建的 -控制器对象。 - -> 即不同的工厂之间,互不干扰。 - -```ts -factory.unmute(); // 打开所有等级的日志输出 -factory.unmute("debug"); // 打开 DEBUG 等级的日志输出 -factory.unmute([ // 打开 INFO 和 ERROR 等级的日志输出 - "info", - "error" -]); -``` - -同理,可以用 `mute` 方法关闭各个等级的日志输出。 - -```ts -factory.mute(); // 关闭所有等级的日志输出 -factory.mute("debug"); // 关闭 DEBUG 等级的日志输出 -factory.mute([ // 关闭 INFO 和 ERROR 等级的日志输出 - "info", - "error" -]); -``` - -### 2.2. enableTrace - -类似日志控制器,每个工厂也提供 enableTrace 方法,这个方法作用于所有由该工厂创建的 -控制器对象。 - -```ts -factory.enableTrace(); // 将所有等级的日志追踪信息设置为 1 层。 -factory.enableTrace(5); // 将所有等级的日志追踪信息设置为 5 层。 -factory.enableTrace(0); // 关闭所有等级的日志追踪信息。 -factory.enableTrace(0, []); // 关闭所有等级的日志追踪信息。 -factory.enableTrace( // 将 DEBUG 日志追踪信息设置为 3 层。 - 3, "debug" -); -factory.enableTrace( // 关闭 INFO/ERROR 日志的追踪信息。 - 0, ["info", "error"] -); -``` - -## 2.3. getSubjects - -该方法可以获取所有由该工厂创建的控制器对象的主题列表。 - -## 2.4. getLevels - -该方法可以获取所有由该工厂支持的日志等级名称数组。 diff --git a/docs/zh-CN/tutorial/README.md b/docs/zh-CN/tutorial/README.md deleted file mode 100644 index 34a94d5..0000000 --- a/docs/zh-CN/tutorial/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# 入门教程 - -## 目录 - -1. [安装与使用](./01-install.md) -2. [基本使用](./02-basic-usage.md) -3. [日志格式化](./03-formatter.md) -4. [自定义输入格式](./04-custom-input.md) -5. [自定义输出位置](./05-custom-output.md) -6. [工厂与日志等级](./06-factory.md) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index aa1ec7b..c9c2f63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,20 @@ { "name": "@litert/logger", - "version": "1.2.1", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@litert/logger", - "version": "1.2.1", + "version": "2.0.0", "license": "Apache-2.0", "devDependencies": { - "@commitlint/cli": "^17.7.2", - "@commitlint/config-conventional": "^17.7.0", - "@litert/eslint-plugin-rules": "^0.1.5", - "@types/node": "^20.8.4", + "@commitlint/cli": "^18.4.4", + "@commitlint/config-conventional": "^18.4.4", + "@litert/eslint-plugin-rules": "^0.1.6", + "@types/node": "^20.11.0", "husky": "^8.0.3", - "typescript": "^5.2.2" + "typescript": "^5.3.3" }, "engines": { "node": ">=8.0.0" @@ -30,12 +30,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -123,9 +123,9 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", @@ -208,16 +208,16 @@ } }, "node_modules/@commitlint/cli": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.7.2.tgz", - "integrity": "sha512-t3N7TZq7lOeqTOyEgfGcaltHqEJf7YDlPg75MldeVPPyz14jZq/+mbGF9tueDLFX8R6RwdymrN6D+U5XwZ8Iwg==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-18.4.4.tgz", + "integrity": "sha512-Ro3wIo//fV3XiV1EkdpHog6huaEyNcUAVrSmtgKqYM5g982wOWmP4FXvEDFwRMVgz878CNBvvCc33dMZ5AQJ/g==", "dev": true, "dependencies": { - "@commitlint/format": "^17.4.4", - "@commitlint/lint": "^17.7.0", - "@commitlint/load": "^17.7.2", - "@commitlint/read": "^17.5.1", - "@commitlint/types": "^17.4.4", + "@commitlint/format": "^18.4.4", + "@commitlint/lint": "^18.4.4", + "@commitlint/load": "^18.4.4", + "@commitlint/read": "^18.4.4", + "@commitlint/types": "^18.4.4", "execa": "^5.0.0", "lodash.isfunction": "^3.0.9", "resolve-from": "5.0.0", @@ -228,41 +228,41 @@ "commitlint": "cli.js" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/config-conventional": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.7.0.tgz", - "integrity": "sha512-iicqh2o6et+9kWaqsQiEYZzfLbtoWv9uZl8kbI8EGfnc0HeGafQBF7AJ0ylN9D/2kj6txltsdyQs8+2fTMwWEw==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-18.4.4.tgz", + "integrity": "sha512-Bz3sPQSboBN+Et/KyZrR+OJ3z9PrHDw7Bls0/hv94PmuHBtMq1dCGxS9XzTGzxeMNlytCC4kxF083tbhPljl3Q==", "dev": true, "dependencies": { - "conventional-changelog-conventionalcommits": "^6.1.0" + "conventional-changelog-conventionalcommits": "^7.0.2" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/config-validator": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.6.7.tgz", - "integrity": "sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-18.4.4.tgz", + "integrity": "sha512-/QI8KIg/h7O0Eus36fPcEcO3QPBcdXuGfZeCF5m15k0EB2bcU8s6pHNTNEa6xz9PrAefHCL+yzRJj7w20T6Mow==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", + "@commitlint/types": "^18.4.4", "ajv": "^8.11.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/ensure": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.6.7.tgz", - "integrity": "sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-18.4.4.tgz", + "integrity": "sha512-KjD19p6julB5WrQL+Cd8p+AePwpl1XzGAjB0jnuFMKWtji9L7ucCZUKDstGjlkBZGGzH/nvdB8K+bh5K27EVUg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", + "@commitlint/types": "^18.4.4", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", @@ -270,205 +270,183 @@ "lodash.upperfirst": "^4.3.1" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/execute-rule": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz", - "integrity": "sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-18.4.4.tgz", + "integrity": "sha512-a37Nd3bDQydtg9PCLLWM9ZC+GO7X5i4zJvrggJv5jBhaHsXeQ9ZWdO6ODYR+f0LxBXXNYK3geYXJrCWUCP8JEg==", "dev": true, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/format": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz", - "integrity": "sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-18.4.4.tgz", + "integrity": "sha512-2v3V5hVlv0R3pe7p66IX5F7cjeVvGM5JqITRIbBCFvGHPJ/CG74rjTkAu0RBEiIhlk3eOaLjVGq3d5falPkLBA==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", + "@commitlint/types": "^18.4.4", "chalk": "^4.1.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/is-ignored": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.7.0.tgz", - "integrity": "sha512-043rA7m45tyEfW7Zv2vZHF++176MLHH9h70fnPoYlB1slKBeKl8BwNIlnPg4xBdRBVNPaCqvXxWswx2GR4c9Hw==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-18.4.4.tgz", + "integrity": "sha512-rXWes9owKBTjfTr6Od7YlflRg4N+ngkOH+dUZhk0qL/XQb26mHz0EgVgdixMVBac1OsohRwJaLmVHX+5F6vfmg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", + "@commitlint/types": "^18.4.4", "semver": "7.5.4" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/lint": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.7.0.tgz", - "integrity": "sha512-TCQihm7/uszA5z1Ux1vw+Nf3yHTgicus/+9HiUQk+kRSQawByxZNESeQoX9ujfVd3r4Sa+3fn0JQAguG4xvvbA==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-18.4.4.tgz", + "integrity": "sha512-SoyQstVxMY5Z4GnFRtRzy+NWYb+yVseXgir+7BxnpB59oH05C9XztRrhDw6OnkNeXhjINTpi1HLnuY7So+CaAQ==", "dev": true, "dependencies": { - "@commitlint/is-ignored": "^17.7.0", - "@commitlint/parse": "^17.7.0", - "@commitlint/rules": "^17.7.0", - "@commitlint/types": "^17.4.4" + "@commitlint/is-ignored": "^18.4.4", + "@commitlint/parse": "^18.4.4", + "@commitlint/rules": "^18.4.4", + "@commitlint/types": "^18.4.4" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/load": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.7.2.tgz", - "integrity": "sha512-XA7WTnsjHZ4YH6ZYsrnxgLdXzriwMMq+utZUET6spbOEEIPBCDLdOQXS26P+v3TTO4hUHOEhzUquaBv3jbBixw==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-18.4.4.tgz", + "integrity": "sha512-RaDIa9qwOw2xRJ3Jr2DBXd14rmnHJIX2XdZF4kmoF1rgsg/+7cvrExLSUNAkQUNimyjCn1b/bKX2Omm+GdY0XQ==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.6.7", - "@commitlint/execute-rule": "^17.4.0", - "@commitlint/resolve-extends": "^17.6.7", - "@commitlint/types": "^17.4.4", - "@types/node": "20.5.1", + "@commitlint/config-validator": "^18.4.4", + "@commitlint/execute-rule": "^18.4.4", + "@commitlint/resolve-extends": "^18.4.4", + "@commitlint/types": "^18.4.4", "chalk": "^4.1.0", - "cosmiconfig": "^8.0.0", - "cosmiconfig-typescript-loader": "^4.0.0", + "cosmiconfig": "^8.3.6", + "cosmiconfig-typescript-loader": "^5.0.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "lodash.uniq": "^4.5.0", - "resolve-from": "^5.0.0", - "ts-node": "^10.8.1", - "typescript": "^4.6.4 || ^5.0.0" + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/load/node_modules/@types/node": { - "version": "20.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", - "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", - "dev": true - }, "node_modules/@commitlint/message": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.4.2.tgz", - "integrity": "sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-18.4.4.tgz", + "integrity": "sha512-lHF95mMDYgAI1LBXveJUyg4eLaMXyOqJccCK3v55ZOEUsMPrDi8upqDjd/NmzWmESYihaOMBTAnxm+6oD1WoDQ==", "dev": true, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/parse": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.7.0.tgz", - "integrity": "sha512-dIvFNUMCUHqq5Abv80mIEjLVfw8QNuA4DS7OWip4pcK/3h5wggmjVnlwGCDvDChkw2TjK1K6O+tAEV78oxjxag==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-18.4.4.tgz", + "integrity": "sha512-99G7dyn/OoyNWXJni0Ki0K3aJd01pEb/Im/Id6y4X7PN+kGOahjz2z/cXYYHn7xDdooqFVdiVrVLeChfgpWZ2g==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", - "conventional-changelog-angular": "^6.0.0", - "conventional-commits-parser": "^4.0.0" + "@commitlint/types": "^18.4.4", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/read": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.5.1.tgz", - "integrity": "sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-18.4.4.tgz", + "integrity": "sha512-r58JbWky4gAFPea/CZmvlqP9Ehbs+8gSEUqhIJOojKzTc3xlxFnZUDVPcEnnaqzQEEoV6C69VW7xuzdcBlu/FQ==", "dev": true, "dependencies": { - "@commitlint/top-level": "^17.4.0", - "@commitlint/types": "^17.4.4", - "fs-extra": "^11.0.0", + "@commitlint/top-level": "^18.4.4", + "@commitlint/types": "^18.4.4", "git-raw-commits": "^2.0.11", "minimist": "^1.2.6" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/resolve-extends": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz", - "integrity": "sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-18.4.4.tgz", + "integrity": "sha512-RRpIHSbRnFvmGifVk21Gqazf1QF/yeP+Kkg/e3PlkegcOKd/FGOXp/Kx9cvSO2K7ucSn4GD/oBvgasFoy+NCAw==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.6.7", - "@commitlint/types": "^17.4.4", + "@commitlint/config-validator": "^18.4.4", + "@commitlint/types": "^18.4.4", "import-fresh": "^3.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0", "resolve-global": "^1.0.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/rules": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.7.0.tgz", - "integrity": "sha512-J3qTh0+ilUE5folSaoK91ByOb8XeQjiGcdIdiB/8UT1/Rd1itKo0ju/eQVGyFzgTMYt8HrDJnGTmNWwcMR1rmA==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-18.4.4.tgz", + "integrity": "sha512-6Uzlsnl/GljEI+80NWjf4ThOfR8NIsbm18IfXYuCEchlwMHSxiuYG4rHSK5DNmG/+MIo8eR5VdQ0gQyt7kWzAA==", "dev": true, "dependencies": { - "@commitlint/ensure": "^17.6.7", - "@commitlint/message": "^17.4.2", - "@commitlint/to-lines": "^17.4.0", - "@commitlint/types": "^17.4.4", + "@commitlint/ensure": "^18.4.4", + "@commitlint/message": "^18.4.4", + "@commitlint/to-lines": "^18.4.4", + "@commitlint/types": "^18.4.4", "execa": "^5.0.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/to-lines": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.4.0.tgz", - "integrity": "sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-18.4.4.tgz", + "integrity": "sha512-mwe2Roa59NCz/krniAdCygFabg7+fQCkIhXqBHw00XQ8Y7lw4poZLLxeGI3p3bLpcEOXdqIDrEGLwHmG5lBdwQ==", "dev": true, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/top-level": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.4.0.tgz", - "integrity": "sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-18.4.4.tgz", + "integrity": "sha512-PBwW1drgeavl9CadB7IPRUk6rkUP/O8jEkxjlC+ofuh3pw0bzJdAT+Kw7M1Yc9KtTb9xTaqUB8uvRtaybHa/tQ==", "dev": true, "dependencies": { "find-up": "^5.0.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/types": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", - "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", + "version": "18.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-18.4.4.tgz", + "integrity": "sha512-/FykLtodD8gKs3+VNkAUwofu4LBHankclj+I8fB2jTRvG6PV7k/OUt4P+VbM7ip853qS4F0g7Z6hLNa6JeMcAQ==", "dev": true, "dependencies": { "chalk": "^4.1.0" }, "engines": { - "node": ">=v14" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" + "node": ">=v18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -496,9 +474,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -541,22 +519,22 @@ "dev": true }, "node_modules/@eslint/js": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", - "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -577,46 +555,21 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@litert/eslint-plugin-rules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@litert/eslint-plugin-rules/-/eslint-plugin-rules-0.1.5.tgz", - "integrity": "sha512-Xyt/MZ52HbJZuhVQaS99BjXGnTdBN3Fnh2xT7bVhCX7wkPhM7poQvu2H1KyaNfEml3qRNbaW7kR+8W9dPN5FMg==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@litert/eslint-plugin-rules/-/eslint-plugin-rules-0.1.6.tgz", + "integrity": "sha512-5Rq2p9LRZ27ejPqkuDF1BSrbrwOBvFYSBQhPo1HZlcnmeaZRU6KdKqWCFPUqvmZ2HhnbodMCVoWGo0M+aGrBAA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", - "eslint": "^8.45.0", - "eslint-plugin-deprecation": "^1.4.1" + "@typescript-eslint/eslint-plugin": "^6.9.0", + "@typescript-eslint/parser": "^6.9.0", + "eslint": "^8.52.0", + "eslint-plugin-deprecation": "^1.5.0" }, "engines": { "node": "12.x || 14.x || >= 16" @@ -657,30 +610,6 @@ "node": ">= 8" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "node_modules/@types/json-schema": { "version": "7.0.13", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", @@ -688,24 +617,24 @@ "dev": true }, "node_modules/@types/minimist": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.3.tgz", - "integrity": "sha512-ZYFzrvyWUNhaPomn80dsMNgMeXxNWZBdkuG/hWlUvXvbdUH8ZERNBGXnU87McuGcWDsyzX2aChCv/SVN348k3A==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "dev": true }, "node_modules/@types/node": { - "version": "20.8.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz", - "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==", + "version": "20.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", "dev": true, "dependencies": { - "undici-types": "~5.25.1" + "undici-types": "~5.26.4" } }, "node_modules/@types/normalize-package-data": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz", - "integrity": "sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, "node_modules/@types/semver": { @@ -715,16 +644,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz", - "integrity": "sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz", + "integrity": "sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/type-utils": "6.7.5", - "@typescript-eslint/utils": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/type-utils": "6.18.1", + "@typescript-eslint/utils": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -750,15 +679,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz", - "integrity": "sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.1.tgz", + "integrity": "sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/typescript-estree": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/typescript-estree": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", "debug": "^4.3.4" }, "engines": { @@ -778,13 +707,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", - "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.1.tgz", + "integrity": "sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5" + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -795,13 +724,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz", - "integrity": "sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.1.tgz", + "integrity": "sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.5", - "@typescript-eslint/utils": "6.7.5", + "@typescript-eslint/typescript-estree": "6.18.1", + "@typescript-eslint/utils": "6.18.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -822,9 +751,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", - "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.1.tgz", + "integrity": "sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -835,16 +764,17 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", - "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.1.tgz", + "integrity": "sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/visitor-keys": "6.18.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, @@ -861,18 +791,42 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", - "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.1.tgz", + "integrity": "sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/scope-manager": "6.18.1", + "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/typescript-estree": "6.18.1", "semver": "^7.5.4" }, "engines": { @@ -887,12 +841,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", - "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.1.tgz", + "integrity": "sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/types": "6.18.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -903,10 +857,16 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -924,15 +884,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", @@ -973,12 +924,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1137,45 +1082,45 @@ "dev": true }, "node_modules/conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", "dev": true, "dependencies": { "compare-func": "^2.0.0" }, "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/conventional-changelog-conventionalcommits": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", - "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", + "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", "dev": true, "dependencies": { "compare-func": "^2.0.0" }, "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", "dev": true, "dependencies": { - "is-text-path": "^1.0.1", + "is-text-path": "^2.0.0", "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" + "meow": "^12.0.1", + "split2": "^4.0.0" }, "bin": { - "conventional-commits-parser": "cli.js" + "conventional-commits-parser": "cli.mjs" }, "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/cosmiconfig": { @@ -1205,26 +1150,22 @@ } }, "node_modules/cosmiconfig-typescript-loader": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", - "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", + "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", "dev": true, + "dependencies": { + "jiti": "^1.19.1" + }, "engines": { - "node": ">=v14.21.3" + "node": ">=v16" }, "peerDependencies": { "@types/node": "*", - "cosmiconfig": ">=7", - "ts-node": ">=10", + "cosmiconfig": ">=8.2", "typescript": ">=4" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1305,15 +1246,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1387,18 +1319,19 @@ } }, "node_modules/eslint": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", - "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.51.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -1824,26 +1757,21 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, - "node_modules/fs-extra": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", - "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1884,6 +1812,52 @@ "node": ">=10" } }, + "node_modules/git-raw-commits/node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits/node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/git-raw-commits/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1929,9 +1903,9 @@ } }, "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1963,12 +1937,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -1984,15 +1952,6 @@ "node": ">=6" } }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2002,6 +1961,18 @@ "node": ">=8" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -2119,12 +2090,12 @@ "dev": true }, "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2209,15 +2180,15 @@ } }, "node_modules/is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", "dev": true, "dependencies": { - "text-extensions": "^1.0.0" + "text-extensions": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/isexe": { @@ -2226,6 +2197,15 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2268,18 +2248,6 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -2435,12 +2403,6 @@ "node": ">=10" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -2454,37 +2416,12 @@ } }, "node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", "dev": true, "engines": { - "node": ">=10" + "node": ">=16.10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2996,9 +2933,9 @@ } }, "node_modules/resolve": { - "version": "1.22.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", - "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -3185,12 +3122,12 @@ "dev": true }, "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, - "dependencies": { - "readable-stream": "^3.0.0" + "engines": { + "node": ">= 10.x" } }, "node_modules/string_decoder": { @@ -3286,12 +3223,15 @@ } }, "node_modules/text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", "dev": true, "engines": { - "node": ">=0.10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/text-table": { @@ -3348,49 +3288,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -3443,9 +3340,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -3456,20 +3353,11 @@ } }, "node_modules/undici-types": { - "version": "5.25.3", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", - "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3485,12 +3373,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -3590,15 +3472,6 @@ "node": ">=12" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 8646b34..5879501 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@litert/logger", - "version": "1.2.1", + "version": "2.0.0", "description": "A logs-recorder for LiteRT framework.", "main": "lib/index.js", "scripts": { @@ -33,14 +33,14 @@ "types": "lib/index.d.ts", "typings": "lib/index.d.ts", "devDependencies": { - "@commitlint/cli": "^17.7.2", - "@commitlint/config-conventional": "^17.7.0", - "@litert/eslint-plugin-rules": "^0.1.5", - "@types/node": "^20.8.4", + "@commitlint/cli": "^18.4.4", + "@commitlint/config-conventional": "^18.4.4", + "@litert/eslint-plugin-rules": "^0.1.6", + "@types/node": "^20.11.0", "husky": "^8.0.3", - "typescript": "^5.2.2" + "typescript": "^5.3.3" }, "engines": { - "node": ">=8.0.0" + "node": ">=18.0.0" } } diff --git a/src/examples/01.quick-start.ts b/src/examples/01.quick-start.ts deleted file mode 100644 index d1b1632..0000000 --- a/src/examples/01.quick-start.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Copyright 2023 Angus ZENG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Loggers from '../lib'; - -(function quickStart(): void { - - /** - * First, create a log controller, giving a subject. - */ - const logs = Loggers.createTextLogger('Quick-Start'); - - /** - * By default, all the levels of logs are muted. - * - * Here we use method "unmute" to turn on the output of all levels of logs. - */ - logs.unmute(); - - /** - * Output a log of INFO level. - */ - logs.info('This is INFO log.'); - - logs.error('This is ERROR log.'); - - /** - * You can mute a specific level of logs, e.g. mute the DEBUG level. - */ - logs.mute('debug'); - - /** - * Now the DEBUG logs couldn't be output (No errors, but ignored.) - */ - logs.debug('This is DEBUG log but it won\'t be output because it\'s muted.'); - - logs.warning('This is WARNING log.'); - - logs.notice('This is NOTICE log.'); - - /** - * Also, unmuting a specific level is allowed. - */ - logs.unmute('debug'); - - /** - * Now the DEBUG logs will be output. - */ - logs.debug('This is DEBUG log.'); - - /** - * If you wanna trace where the log is logged, just turn on the log-tracing. - * And now the calling spot will be appended after the logs' output. - */ - logs.enableTrace(); - - logs.info('This is INFO log.'); - - /** - * Or if you wanna print the whole calling-stack? - */ - logs.enableTrace(10); - - logs.notice('This is NOTICE log.'); - - logs.enableTrace(0); - - /** - * And you can turn on the whole calling-stack for DEBUG level only. - */ - logs.enableTrace(10, 'debug'); - - logs.error('This is ERROR log.'); - - logs.debug('This is DEBUG log.'); - - logs.enableTrace(0); - - /** - * Besides, you can pass a Date object for the log, instead of the current - * time. - */ - logs.debug('See the log time', new Date('2018-02-01 11:22:33.233')); - - /** - * And you can mute levels for all log controllers at once. - */ - const logs2 = Loggers.createTextLogger('Quick-Start-2'); - - logs2.unmute(); - - Loggers.mute(); - - logs.info('This will not be output.'); - - logs2.info('This will not be output.'); - - /** - * So can you unmute all log controllers at once too. - */ - Loggers.unmute(); - - logs.info('This will be output.'); - - logs2.info('This will be output.'); - - /** - * Or just mute specific level for all levels. - */ - Loggers.mute('debug'); - - logs.debug('This will not be output.'); - - logs2.debug('This will not be output.'); - - logs.error('This will be output.'); - - logs2.error('This will be output.'); - -})(); diff --git a/src/examples/02.custom-formatter.ts b/src/examples/02.custom-formatter.ts deleted file mode 100644 index c8a63a0..0000000 --- a/src/examples/02.custom-formatter.ts +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Copyright 2023 Angus ZENG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Loggers from '../lib'; - -(function customFormatter(): void { - - /** - * First, create a log controller, giving a subject and a formater. - */ - const logs1 = Loggers.createTextLogger( - 'Custom-Formatter 1', - function(log, subj, lv, dt, traces): string { - - if (traces) { - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log} - - ${traces.join('\n ')} -`; - } - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log}`; - } - ); - - /** - * By default, all the levels of logs are muted. - * - * Here we use method "unmute" to turn on the output of all levels of logs. - */ - logs1.unmute(); - - /** - * Output a log of INFO level. - */ - logs1.info('This is INFO log.'); - - logs1.error('This is ERROR log.'); - - /** - * Now the DEBUG logs couldn't be output (No errors, but ignored.) - */ - logs1.debug('This is DEBUG log.'); - - logs1.enableTrace(); - - logs1.warning('This is WARNING log.'); - - logs1.enableTrace(10); - - logs1.notice('This is NOTICE log.'); - - /** - * Or used a pre-registered formatter. - */ - - /** - * First, create a log controller, giving a subject and a formater. - */ - Loggers.registerTextFormatter( - 'custom_text_formatter', - function(log, subj, lv, dt, traces): string { - - if (traces) { - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log} - - ${traces.join('\n ')} -`; - } - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log}`; - } - ); - - const logs2 = Loggers.createTextLogger( - 'Custom-Formatter 2', - 'custom_text_formatter' - ); - - /** - * By default, all the levels of logs are muted. - * - * Here we use method "unmute" to turn on the output of all levels of logs. - */ - logs2.unmute(); - - /** - * Output a log of INFO level. - */ - logs2.info('This is INFO log.'); - - logs2.error('This is ERROR log.'); - - /** - * Now the DEBUG logs couldn't be output (No errors, but ignored.) - */ - logs2.debug('This is DEBUG log.'); - - logs2.enableTrace(); - - logs2.warning('This is WARNING log.'); - - logs2.enableTrace(10); - - logs2.notice('This is NOTICE log.'); -})(); diff --git a/src/examples/03.built-in-colorful-driver.ts b/src/examples/03.built-in-colorful-driver.ts deleted file mode 100644 index 8de5e49..0000000 --- a/src/examples/03.built-in-colorful-driver.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright 2023 Angus ZENG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Loggers, { createColorfulTTYDriver } from '../lib'; - -(function builtInColorfulDriver(): void { - - const theColorDriver = createColorfulTTYDriver(); - - theColorDriver.foreColor('green', 'info'); - theColorDriver.foreColor('red', 'error'); - theColorDriver.foreColor('yellow', 'warning'); - theColorDriver.foreColor('grey', 'notice'); - theColorDriver.foreColor('cyan', 'debug'); - - Loggers.registerDriver('colorful', theColorDriver); - - /** - * First, create a log controller, giving a subject. - */ - const logs = Loggers.createTextLogger( - 'Colorful', - undefined, - 'colorful' - ); - - /** - * By default, all the levels of logs are muted. - * - * Here we use method "unmute" to turn on the output of all levels of logs. - */ - logs.unmute(); - - /** - * Output a log of INFO level. - */ - logs.info('This is INFO log.'); - - logs.error('This is ERROR log.'); - - /** - * Now the DEBUG logs couldn't be output (No errors, but ignored.) - */ - logs.debug('This is DEBUG log.'); - - logs.enableTrace(); - - logs.warning('This is WARNING log.'); - - logs.enableTrace(10); - - logs.notice('This is NOTICE log.'); - -})(); diff --git a/src/examples/04.object-logs.ts b/src/examples/04.object-logs.ts deleted file mode 100644 index e6a67de..0000000 --- a/src/examples/04.object-logs.ts +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright 2023 Angus ZENG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Loggers from '../lib'; - -interface ILogInfo { - - 'action': string; - - 'user': string; - - 'result': 'succeed' | 'failed'; -} - -(function objectLogs(): void { - - /** - * First, create a log controller, giving a subject and a formater. - */ - const logs = Loggers.createDataLogger( - 'Object-Formatter', - function(log, subj, lv, dt, traces): string { - - if (traces) { - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log.user} - ${log.action} - ${log.result} - - ${traces.join('\n ')} -`; - } - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log.user} - ${log.action} - ${log.result}`; - } - ); - - /** - * By default, all the levels of logs are muted. - * - * Here we use method "unmute" to turn on the output of all levels of logs. - */ - logs.unmute(); - - /** - * Output a log of INFO level. - */ - logs.info({ - action: 'Login', - user: 'admin', - result: 'succeed' - }); - - logs.error({ - action: 'Login', - user: 'admin', - result: 'failed' - }); - - /** - * Now the DEBUG logs couldn't be output (No errors, but ignored.) - */ - logs.debug({ - action: 'Login', - user: 'sofia', - result: 'failed' - }); - - logs.enableTrace(); - - logs.warning({ - action: 'DeleteAccount', - user: 'sofia', - result: 'succeed' - }); - - logs.enableTrace(10); - - logs.notice({ - action: 'RegisterAccount', - user: 'john', - result: 'succeed' - }); - -})(); diff --git a/src/examples/05.using-factory.ts b/src/examples/05.using-factory.ts deleted file mode 100644 index 8eb19bb..0000000 --- a/src/examples/05.using-factory.ts +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright 2023 Angus ZENG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createFactory, - DEFAULT_LEVELS -} from '../lib'; - -interface ILogInfo { - - 'action': string; - - 'user': string; - - 'result': 'succeed' | 'failed'; -} - -(function objectLogs(): void { - - const factory1 = createFactory(DEFAULT_LEVELS); - const factory2 = createFactory(DEFAULT_LEVELS); - - /** - * First, create a log controller, giving a subject. - */ - const logs1 = factory1.createDataLogger( - 'Using-Factory-1', - function(log, subj, lv, dt, traces): string { - - if (traces) { - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log.user} - ${log.action} - ${log.result} - - ${traces.join('\n ')} -`; - } - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log.user} - ${log.action} - ${log.result}`; - } - ); - - const logs2 = factory2.createDataLogger( - 'Using-Factory-2', - function(log, subj, lv, dt, traces): string { - - if (traces) { - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log.user} - ${log.action} - ${log.result} - - ${traces.join('\n ')} -`; - } - - return `${dt.toISOString()} - ${subj} - ${lv} - ${log.user} - ${log.action} - ${log.result}`; - } - ); - - /** - * Unmute all levels for all log controllers created by factory1. - */ - factory1.unmute(); - - /** - * Output a log of INFO level. - */ - logs1.info({ - action: 'Login', - user: 'admin', - result: 'succeed' - }); - - /** - * The logs from controller created by factory2 won't be output. - * Because controllers from different factory are isolated. - */ - logs2.info({ - action: 'Login', - user: 'admin', - result: 'succeed' - }); - - logs1.error({ - action: 'Login', - user: 'admin', - result: 'failed' - }); - - /** - * Now the DEBUG logs couldn't be output (No errors, but ignored.) - */ - logs1.error({ - action: 'Login', - user: 'sofia', - result: 'failed' - }); - - logs1.enableTrace(); - - logs1.warning({ - action: 'DeleteAccount', - user: 'sofia', - result: 'succeed' - }); - - logs1.enableTrace(10); - - logs1.debug({ - action: 'RegisterAccount', - user: 'john', - result: 'succeed' - }); - -})(); diff --git a/src/examples/07.custom-driver.ts b/src/examples/custom-driver.ts similarity index 83% rename from src/examples/07.custom-driver.ts rename to src/examples/custom-driver.ts index 2ce030a..bc8a38f 100644 --- a/src/examples/07.custom-driver.ts +++ b/src/examples/custom-driver.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 Angus ZENG + * Copyright 2024 Angus ZENG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -import Loggers, { IDriver } from '../lib'; +import LoggerFactory, { IDriver } from '../lib'; import * as fs from 'node:fs'; class FileLogDriver implements IDriver { @@ -49,18 +49,9 @@ class FileLogDriver implements IDriver { const fd = new FileLogDriver('a.log'); -Loggers.registerDriver( - 'file-a', - fd -); +const logs = LoggerFactory.createLogger('Example'); -const logs = Loggers.createTextLogger( - 'Example', - undefined, - 'file-a' -); - -logs.unmute(); +logs.setLevelOptions({ traceDepth: 2, driver: fd }); logs.info('HI'); diff --git a/src/examples/custom-formatter.ts b/src/examples/custom-formatter.ts new file mode 100644 index 0000000..436f836 --- /dev/null +++ b/src/examples/custom-formatter.ts @@ -0,0 +1,52 @@ +/** + * Copyright 2024 Angus ZENG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import LoggerFactory from '../lib'; + +/** + * First, create a logger, giving a subject. + */ +const logs1 = LoggerFactory.createLogger('Custom-Formatter 1'); + +logs1.setLevelOptions({ + formatter: function(log, subj, lv, dt, traces): string { + + if (traces) { + + return `${new Date(dt).toISOString()} - ${subj} - ${lv} - ${log} + + ${traces.join('\n ')} +`; + } + + return `${new Date(dt).toISOString()} - ${subj} - ${lv} - ${log}`; + } +}); + +/** + * Output a log of INFO level. + */ +logs1.info('This is INFO log.'); + +logs1.error('This is ERROR log.'); + +logs1.setLevelOptions({ traceDepth: 2 }); + +logs1.debug('This is DEBUG log.'); + +logs1.warning('This is WARNING log.'); + +logs1.notice('This is NOTICE log.'); diff --git a/src/examples/06.custom-levels.ts b/src/examples/custom-levels.ts similarity index 64% rename from src/examples/06.custom-levels.ts rename to src/examples/custom-levels.ts index a235170..9388c90 100644 --- a/src/examples/06.custom-levels.ts +++ b/src/examples/custom-levels.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 Angus ZENG + * Copyright 2024 Angus ZENG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,21 +14,13 @@ * limitations under the License. */ -import { - createFactory -} from '../lib'; +import { createLoggerFactory } from '../lib'; -/** - * Define the customized levels of logs. - */ -type MyLevels = 'normal' | 'secure' | 'failure'; - -const factory1 = createFactory([ +const factory1 = createLoggerFactory([ 'normal', 'secure', 'failure' ]); -const logs = factory1.createTextLogger('Test'); - -logs.unmute(); +const logs = factory1.createLogger('Test'); -logs.normal('This is a normal log.'); +logs.normal('This is a NORMAL log.'); +logs.secure('This is a SECURE log.'); diff --git a/src/examples/quick-start.ts b/src/examples/quick-start.ts new file mode 100644 index 0000000..83d75ea --- /dev/null +++ b/src/examples/quick-start.ts @@ -0,0 +1,109 @@ +/** + * Copyright 2024 Angus ZENG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import LoggerFactory from '../lib'; + +(function quickStart(): void { + + /** + * First, create a logger, giving a subject. + */ + const loggerA = LoggerFactory.createLogger('A'); + + /** + * Output a log of INFO level. + */ + loggerA.info('This is INFO log.'); + + loggerA.error('This is ERROR log.'); + + /** + * You can mute a specific level of logs, e.g. mute the DEBUG level. + */ + loggerA.setLevelOptions({ levels: 'debug', enabled: false }); + + /** + * Now the DEBUG logs couldn't be output (No errors, but ignored.) + */ + loggerA.debug('This is DEBUG log but it won\'t be output because it\'s muted.'); + + loggerA.warning('This is WARNING log.'); + + loggerA.notice('This is NOTICE log.'); + + /** + * Also, unmute a specific level is allowed. + */ + loggerA.setLevelOptions({ levels: 'debug', enabled: true }); + + /** + * Now the DEBUG logs will be output. + */ + loggerA.debug('This is DEBUG log.'); + + /** + * If you wanna trace where the log is logged, just turn on the log-tracing. + * And now the calling spot will be appended after the logs' output. + */ + loggerA.setLevelOptions({ 'traceDepth': 2 }); + + loggerA.info('This is INFO log with at most 2 lines of stack traces.'); + + /** + * Or if you wanna print the whole calling-stack? + */ + loggerA.setLevelOptions({ 'traceDepth': 10 }); + + loggerA.notice('This is NOTICE log with at most 10 lines of stack traces.'); + + loggerA.setLevelOptions({ 'traceDepth': 0 }); + + /** + * And you can turn on the whole calling-stack for DEBUG level only. + */ + loggerA.setLevelOptions({ levels: 'debug', 'traceDepth': 10 }); + + loggerA.error('This is ERROR log without stack traces.'); + + loggerA.debug('This is DEBUG log with at most 10 lines of stack traces.'); + + loggerA.setLevelOptions({ 'traceDepth': 0 }); + + /** + * Besides, you can pass a Date object for the log, instead of the current + * time. + */ + loggerA.debug('See the log time', Date.parse('2018-02-01 11:22:33.233')); + + /** + * Change the default options for new loggers. + * + * Will not affect the existing loggers. + */ + LoggerFactory.setLevelOptions({ levels: ['error', 'debug', 'warning'], enabled: false }); + + const loggerB = LoggerFactory.createLogger('B'); + + loggerB.info('This is INFO log.'); + + loggerB.error('This is ERROR log. but will not be output.'); + + loggerB.debug('This is DEBUG log. but will not be output.'); + + loggerA.setLevelOptions({ enabled: false }); + + loggerB.warning('This is WARNING log. but will not be output.'); +})(); diff --git a/src/examples/using-factory.ts b/src/examples/using-factory.ts new file mode 100644 index 0000000..6dc06ca --- /dev/null +++ b/src/examples/using-factory.ts @@ -0,0 +1,98 @@ +/** + * Copyright 2024 Angus ZENG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as LibLogs from '../lib'; + +interface ILogInfo { + + 'action': string; + + 'user': string; + + 'result': string; +} + +const formatter = function(log, subj, lv, dt, traces): string { + + if (traces) { + + return `${new Date(dt).toISOString()} - ${subj} - ${lv} - ${log.user} - ${log.action} - ${log.result} + +${traces.join('\n ')} +`; + } + + return `${new Date(dt).toISOString()} - ${subj} - ${lv} - ${log.user} - ${log.action} - ${log.result}`; + +} as LibLogs.IFormatter; + +const factory1 = LibLogs.createLoggerFactory(LibLogs.DEFAULT_LEVELS, undefined, formatter); +const factory2 = LibLogs.createLoggerFactory(LibLogs.DEFAULT_LEVELS, undefined, formatter); + +factory2.setLevelOptions({ enabled: false }); +/** + * First, create a logger, giving a subject. + */ +const logger1 = factory1.createLogger('Using-Factory-1'); +const logger2 = factory2.createLogger('Using-Factory-2'); + +/** + * Output a log of INFO level. + */ +logger1.info({ + action: 'Login', + user: 'admin', + result: 'succeed' +}); + +/** + * The logs from logger created by factory2 won't be output. + * Because loggers from different factory are isolated. + */ +logger2.info({ + action: 'Login', + user: 'admin', + result: 'succeed' +}); + +logger1.error({ + action: 'Login', + user: 'admin', + result: 'failed' +}); + +// Now changed the default level settings for factory2. +factory2.setLevelOptions({ enabled: true }); + +/** + * However, the logs from loggers created by factory2 before are still muted. + */ +logger2.info({ + action: 'Login', + user: 'admin', + result: 'needs 2fa' +}); + +const logger3 = factory2.createLogger('Using-Factory-2-New'); + +/** + * The new loggers created by factory2 now will be output. + */ +logger3.info({ + action: 'Login', + user: 'admin', + result: 'password incorrect' +}); diff --git a/src/lib/Common.ts b/src/lib/Common.ts deleted file mode 100644 index 8334a52..0000000 --- a/src/lib/Common.ts +++ /dev/null @@ -1,300 +0,0 @@ -/** - * Copyright 2023 Angus ZENG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * The name of default driver. - */ -export const DEFAULT_DRIVER = 'console'; - -/** - * The name of default subject. - */ -export const DEFAULT_SUBJECT = 'default'; - -/** - * The names of default levels. - */ -export const DEFAULT_LEVELS: readonly IDefaultLevels[] = [ - 'error', - 'notice', - 'warning', - 'debug', - 'info' -]; - -/** - * The function serializing or formatting original input of logs into text form. - * - * @param log The original input of log. - * @param subject The subject of log. - * @param level The level of log. - * @param date The datetime of log. - * @param traces The trace-info of log. - */ -export type IFormatter = ( - log: T, - subject: string, - level: TLevel, - date: Date, - traces?: readonly string[] -) => string; - -export interface IDriver { - - /** - * This method is provided to be called by logger, to send logs - * to target device. - * - * @param text The formatted log text. - * @param subject The subject of log - * @param level The level of log - * @param date The data of log - */ - write( - text: string, - subject: string, - level: string, - date: Date - ): void; - - /** - * Flush all logs in the log driver buffer. - */ - flush(): void | Promise; - - /** - * Shutdown the driver. - * - * This method should invoke method `flush` automatically before closing - * driver. - */ - close(): void | Promise; -} - -export interface IBaseLogger { - - /** - * Get the subject of current logger. - */ - getSubject(): string; - - /** - * Get the levels list of this logger supports. - */ - getLevels(): TLv[]; - - /** - * Enable or disable trace info of all levels or determined level of - * current logger. - * - * @param depth Set the depth of tracing stack, by default it's 1. - * Set to 0 to shutdown displaying trace stack. - * @param level Determine a level or a list of level to be disabled tracing. - * By default it will be all levels. - */ - enableTrace(depth?: number, level?: TLv | readonly TLv[]): this; - - /** - * Unmute all levels or determined level of current logger. - * - * @param level Determine a level or a list of level to be unmuted. - * By default it will be all levels. - */ - unmute(level?: TLv | readonly TLv[]): this; - - /** - * Mute all levels or determined level of current logger. - * - * @param level Determine a level or a list of level to be muted. - * By default it will be all levels. - */ - mute(level?: TLv | readonly TLv[]): this; - - /** - * Check a determined level or all levels of current logger is muted. - * - * @param level Determine a level to be checked. If not provided, it will check all levels. - */ - isMuted(level?: TLv): boolean; - - /** - * Flush the logs in driver's buffer. - */ - flush(): void | Promise; -} - -/** - * The logging methods signature. - */ -export type ILoggerMethod = (log: T, date?: Date) => ILogger; - -/** - * The logging methods signature. - * - * @deprecated Use `ILoggerMethod` instead. - */ -export type LoggerMethod = ILoggerMethod; - -/** - * The logger interface. - */ -export type ILogger = IBaseLogger & Record< - TLevel, - ILoggerMethod ->; - -/** - * The default levels of loggers. - */ -export type IDefaultLevels = 'error' | 'notice' | 'warning' | 'debug' | 'info'; - -/** - * The default levels of loggers. - * - * @deprecated Use `IDefaultLevels` instead. - */ -export type DefaultLevels = IDefaultLevels; - -/** - * The logger factory interface. - */ -export interface IFactory { - - /** - * Mute all levels of all loggers, or determined level of all loggers. - * - * @param level Determine a level or a list of level to be muted. - * By default it will be all levels. - */ - mute(level?: TLv | readonly TLv[]): this; - - /** - * Enable all levels of all loggers, or determined level of all loggers. - * - * @param level Determine a level or a list of level to be unmuted. - * By default it will be all levels. - */ - unmute(level?: TLv | readonly TLv[]): this; - - /** - * Disable or enable trace info for all levels of all loggers, or for - * determined level of all loggers. - * - * @param depth Set the depth of tracing stack, by default it's 1. - * Set to 0 to shutdown displaying trace stack. - * @param level Determine a level or a list of level to be disabled tracing. - * By default it will be all levels. - */ - enableTrace(depth?: number, level?: TLv | readonly TLv[]): this; - - /** - * Added a new driver. - * - * @param name The unique name of driver - * @param driver The driver object. - */ - registerDriver(name: string, driver: IDriver): boolean; - - /** - * Find and return an existing driver by its unique name. - * - * @param name The unique name of driver - */ - getDriver(name: string): IDriver | null; - - /** - * Get the names list of registered drivers. - */ - getDriverNames(): string[]; - - /** - * Added a new formatter for data logger. - * - * @param name The unique name of formatter - * @param formatter The formatter. - */ - registerDataFormatter(name: string, formatter: IFormatter): boolean; - - /** - * Added a new formatter for text logger. - * - * @param name The unique name of formatter - * @param formatter The formatter. - */ - registerTextFormatter(name: string, formatter: IFormatter): boolean; - - /** - * Find and return an existing formatter by its unique name. - * - * @param name The unique name of data formatter - */ - getDataFormatter(name: string): IFormatter; - - /** - * Find and return an existing formatter by its unique name. - * - * @param name The unique name of text formatter - */ - getTextFormatter(name: string): IFormatter; - - /** - * Get the names list of registered data formatters. - */ - getDataFormatterNames(): string[]; - - /** - * Get the names list of registered text formatters. - */ - getTextFormatterNames(): string[]; - - /** - * Get the subjects list of created loggers. - */ - getSubjects(): string[]; - - /** - * Get the levels list of this factory supports. - */ - getLevels(): TLv[]; - - /** - * Create a simple text logger. - * - * @param subject The unique subject of logger. (default: default) - * @param formatter The formatter helps stringify input data. - * (default: DEFAULT_TEXT_FORMATTER) - * @param driver The driver to write logs. (default: console) - */ - createTextLogger( - subject?: string, - formatter?: IFormatter | string, - driver?: string - ): ILogger; - - /** - * Create a simple data logger. - * - * @param subject The unique subject of logger. (default: default) - * @param formatter The formatter helps stringify input data. - * (default: DEFAULT_JSON_FORMATTER) - * @param driver The driver to write logs. (default: console) - */ - createDataLogger( - subject?: string, - formatter?: IFormatter | string, - driver?: string - ): ILogger; -} diff --git a/src/lib/Decl.ts b/src/lib/Decl.ts new file mode 100644 index 0000000..3d032d2 --- /dev/null +++ b/src/lib/Decl.ts @@ -0,0 +1,191 @@ +/** + * Copyright 2024 Angus ZENG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The names of default levels. + */ +export const DEFAULT_LEVELS: readonly IDefaultLevels[] = [ + 'error', + 'notice', + 'warning', + 'debug', + 'info' +]; + +/** + * The function serializing or formatting original input of logs into text form. + * + * @param log The original input of log. + * @param subject The subject of log. + * @param level The level of log. + * @param time The time of log. + * @param traces The trace-info of log. + */ +export type IFormatter = ( + log: TLog, + subject: string, + level: TLv, + time: number, + traces?: readonly string[] +) => string; + +export interface IDriver { + + /** + * This method is provided to be called by logger, to send logs to target output device. + * + * @param text The formatted log text. + * @param subject The subject of log + * @param level The level of log + * @param time The time of log + */ + write( + text: string, + subject: string, + level: string, + time: number + ): void; + + /** + * Flush all logs in the log driver buffer. + */ + flush(): void | Promise; + + /** + * Shutdown the driver. + * + * This method should invoke method `flush` automatically before closing driver. + */ + close(): void | Promise; +} + +export interface ILevelOptions { + + /** + * Enable or disable the log output of this level. + */ + 'enabled': boolean; + + /** + * The trace depth of this level. + */ + 'traceDepth': number; + + /** + * The formatter of this level. + */ + 'formatter': IFormatter; + + /** + * The driver of this level. + */ + 'driver': IDriver; +} + +export interface ILevelUpdateOptions extends Partial> { + + /** + * The level name to be updated. + * + * > If not specified or set to empty array `[]`, the options will be applied to all levels. + * + * @default all levels + */ + 'levels'?: TLv | TLv[]; +} + +export interface IBaseLogger { + + /** + * The subject of current logger. + * + * @readonly + */ + readonly 'subject': string; + + /** + * The level names of current logger. + */ + readonly 'levels': readonly TLv[]; + + /** + * Configure the specific levels of current logger. + * + * @param options The new options of levels. + */ + setLevelOptions(options: ILevelUpdateOptions): this; + + /** + * Get the options of specific level. + * + * @param level The level name. + */ + getLevel(level: TLv): ILevelOptions; +} + +/** + * The logging methods signature. + */ +export type ILoggerMethod = (log: TLog, time?: number) => ILogger; + +/** + * The logger interface. + */ +export type ILogger = IBaseLogger & Record< + TLv, + ILoggerMethod +>; + +/** + * The default levels of loggers. + */ +export type IDefaultLevels = 'error' | 'notice' | 'warning' | 'debug' | 'info'; + +/** + * The logger factory interface. + */ +export interface IFactory { + + /** + * The level names of current factory. + * + * @readonly + */ + readonly 'levels': readonly TLv[]; + + /** + * Setup the default options of specific levels for new loggers created by this factory. + * + * > Only applies to new loggers created after calling this method. + * + * @param options The new options of levels. + */ + setLevelOptions(options: ILevelUpdateOptions): this; + + /** + * Get the default options of specific level for new loggers created by this factory. + * + * @param level The level name. + */ + getLevelOptions(level: TLv): ILevelOptions; + + /** + * Create a logger. + * + * @param subject The subject of logger. + */ + createLogger(subject: string): ILogger; +} diff --git a/src/lib/Drivers/ColorfulTTY.ts b/src/lib/Drivers/ColorfulTTY.ts deleted file mode 100644 index b2265fd..0000000 --- a/src/lib/Drivers/ColorfulTTY.ts +++ /dev/null @@ -1,251 +0,0 @@ -/** - * Copyright 2023 Angus ZENG - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { IDriver } from '../Common'; - -export type IForeColorSet = 'blue' | 'cyan' | 'green' | 'magenta' | 'grey' | -'red' | 'yellow' | 'white' | 'black' | 'default'; - -export type IBgColorSet = IForeColorSet; - -/** - * @deprecated Use `IForeColorSet` instead. - */ -export type ForeColorSet = IForeColorSet; - -/** - * @deprecated Use `IBgColorSet` instead. - */ -export type BgColorSet = IBgColorSet; - -const BG_COLOR_ENDING = '\x1B[49m'; -const FORE_COLOR_ENDING = '\x1B[39m'; - -type IWriter = ( - text: string, - subject: string, - level: string, - date: Date -) => void; - -function nonColorfulWriter(text: string): void { - - console.log(text); -} - -const FORE_COLORS: Record = { - 'default': '', - 'blue': '\u001b[34m', - 'cyan': '\u001b[36m', - 'green': '\u001b[32m', - 'magenta': '\u001b[35m', - 'red': '\u001b[31m', - 'yellow': '\u001b[33m', - 'white': '\u001b[37m', - 'grey': '\u001b[90m', - 'black': '\u001b[30m' -}; - -const BG_COLORS: Record = { - 'default': '', - 'white': '\u001b[47m', - 'grey': '\u001b[49;5;8m', - 'black': '\u001b[40m', - 'blue': '\u001b[44m', - 'cyan': '\u001b[46m', - 'green': '\u001b[42m', - 'magenta': '\u001b[45m', - 'red': '\u001b[41m', - 'yellow': '\u001b[43m' -}; - -export interface IColorfulTTYDriver - extends IDriver { - - /** - * Set the fore-color for the logs of a level. - * - * @param color The color of the level. - * @param level Specify the level to be colorified. - * If no level specified, then the default color will be set. - */ - foreColor(color: IForeColorSet, level?: string): this; - - /** - * Set the background-color for the logs of a level. - * - * @param color The color of the level. - * @param level Specify the level to be colorified. - * If no level specified, then the default color will be set. - */ - bgColor(color: IBgColorSet, level?: string): this; -} - -interface IStyle { - - start: string; - - end: string; -} - -const DEFAULT_LEVEL = Symbol('__default__'); - -class ColorfulTTYDriver implements IColorfulTTYDriver { - - private _foreColors: Record; - - private _bgColors: Record; - - private _levels: Record; - - public constructor() { - - this._bgColors = { - [DEFAULT_LEVEL]: 'default' - }; - this._foreColors = { - [DEFAULT_LEVEL]: 'default' - }; - - this._levels = { - [DEFAULT_LEVEL]: { - start: '', - end: '' - } - }; - - this.write = this._buildWriter() as any; - } - - public bgColor(color: IBgColorSet, level?: string): this { - - this._bgColors[level ?? DEFAULT_LEVEL] = color === 'default' ? - '' : BG_COLORS[color]; - - this._rebuild(level ?? DEFAULT_LEVEL); - - return this; - } - - public foreColor(color: IForeColorSet, level?: string): this { - - this._foreColors[level ?? DEFAULT_LEVEL] = color === 'default' ? - '' : FORE_COLORS[color]; - - this._rebuild(level ?? DEFAULT_LEVEL); - - return this; - } - - private _rebuild(level: string | symbol): void { - - let start: string = ''; - let end: string = ''; - - if (this._foreColors[level]) { - - start += this._foreColors[level] || ''; - end = FORE_COLOR_ENDING + end; - } - - if (this._bgColors[level]) { - - start += this._bgColors[level] || ''; - end = BG_COLOR_ENDING + end; - } - - this._levels[level] = { start, end }; - } - - public write(): void { - - return; - } - - public flush(): void { - - // do nothing. - } - - public close(): void { - - // do nothing. - } - - public static isTerminal(): boolean { - - return this.isNodeJS() && ( - process.stdout.isTTY || - process.stdout.constructor.name === 'Socket' // Debugging - ); - } - - public static isNodeJS(): boolean { - - try { - - return typeof process.stdout === 'object'; - } - catch { - - return false; - } - } - - private _buildWriter(): IWriter { - - if (ColorfulTTYDriver.isTerminal()) { - - return this._buildWriterForTerminal(); - } - - return nonColorfulWriter; - } - - private _buildWriterForTerminal(): IWriter { - - const cs: string[] = []; - - cs.push('return function(text, subject, level, date) {'); - cs.push('const dec = this._levels[level] || this._levels[DEFAULT_LEVEL];'); - cs.push('return console.log('); - cs.push(' text.split("\\n").map('); - cs.push(' (x) => `${dec.start}${x}${dec.end}`'); - cs.push(' ).join("\\n")'); - cs.push(');'); - cs.push('};'); - - return (new Function( - 'DEFAULT_LEVEL', - cs.join('\n') - ))(DEFAULT_LEVEL); - } -} - -/** - * Create a colorful-tty driver. - */ -export function createColorfulTTYDriver(): IColorfulTTYDriver { - - if (!ColorfulTTYDriver.isTerminal()) { - - console.warn( - 'The ColorfulTTYDriver is only usable in Node.JS terminal.' - ); - } - - return new ColorfulTTYDriver(); -} diff --git a/src/lib/Drivers/Console.ts b/src/lib/Drivers/Console.ts index d04376a..babda77 100644 --- a/src/lib/Drivers/Console.ts +++ b/src/lib/Drivers/Console.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 Angus ZENG + * Copyright 2024 Angus ZENG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,13 @@ * limitations under the License. */ -import { IDriver } from '../Common'; +import type { IDriver } from '../Decl'; class ConsoleDriver implements IDriver { public write(text: string): void { + // eslint-disable-next-line no-console console.log(text); } diff --git a/src/lib/Factory.ts b/src/lib/Factory.ts index aa9fe0a..2418681 100644 --- a/src/lib/Factory.ts +++ b/src/lib/Factory.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 Angus ZENG + * Copyright 2024 Angus ZENG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,307 +14,104 @@ * limitations under the License. */ -import { Logger, ILevelOptions } from './Logger'; - -import { - DEFAULT_JSON_FORMATTER, - DEFAULT_TEXT_FORMATTER -} from './Formatters'; - +import * as dL from './Decl'; +import { Logger } from './Logger'; import { createConsoleDriver } from './Drivers/Console'; +import { DEFAULT_TEXT_FORMATTER } from './Formatters'; -import { - IFactory, - IFormatter, - ILogger, - IDefaultLevels, - IDriver, - DEFAULT_SUBJECT, - DEFAULT_DRIVER, - DEFAULT_LEVELS -} from './Common'; - -class LoggerFactory implements IFactory { - - protected _drivers: Record; - - protected _loggers: Record>; - - protected _globalConfig: Record; - - protected _formatters: { - text: Record>; - data: Record>; - }; - - protected _levels: readonly string[]; - - public constructor(levels: readonly string[] = DEFAULT_LEVELS) { - - this._loggers = {}; - - this._formatters = { - 'text': { - 'default': DEFAULT_TEXT_FORMATTER - }, - 'data': { - 'default': DEFAULT_JSON_FORMATTER - } - }; - - this._drivers = { - [DEFAULT_DRIVER]: createConsoleDriver() - }; - - this._levels = levels; - - this._globalConfig = {}; - - for (const lv of levels) { - - this._globalConfig[lv] = { - enabled: false, - trace: 0 - }; - } - } - - /** - * Get the names list of registered drivers. - */ - public getDriverNames(): string[] { - - return Object.keys(this._drivers); - } - - /** - * Get the names list of registered formatters. - */ - public getDataFormatterNames(): string[] { - - return Object.keys(this._formatters.data); - } - - /** - * Get the names list of registered formatters. - */ - public getTextFormatterNames(): string[] { - - return Object.keys(this._formatters.text); - } +class LoggerFactory< + TLog, + TLv extends string +> implements dL.IFactory { /** - * Get the subjects list of created loggers. + * The options of levels for new logger. */ - public getSubjects(): string[] { - - return Object.keys(this._loggers); - } - - /** - * Get the levels list of this factory supports. - */ - public getLevels(): string[] { - - return [...this._levels]; - } - - public mute(levels?: string | readonly string[]): this { - - if (!levels?.length) { + protected readonly _lvOpts: Record>; - levels = this._levels; - } - else if (typeof levels === 'string') { - - levels = [ levels ]; - } - - for (const level of levels) { + public constructor( + driver: dL.IDriver, + public readonly levels: readonly TLv[], + formatter: dL.IFormatter + ) { - this._globalConfig[level].enabled = false; - } - - for (const subject in this._loggers) { - - this._loggers[subject].mute(levels); - } - - return this; - } - - public unmute(levels?: string | readonly string[]): this { - - if (!levels?.length) { - - levels = this._levels; - } - else if (typeof levels === 'string') { + this._lvOpts = {}; - levels = [ levels ]; - } - - for (const level of levels) { - - this._globalConfig[level].enabled = true; - } - - for (const subject in this._loggers) { + for (const lv of levels) { - this._loggers[subject].unmute(levels); + this._lvOpts[lv] = { + enabled: true, + traceDepth: 0, + driver, + formatter + }; } - - return this; } - public enableTrace(depth: number = 1, levels?: string | string[]): this { - - if (!levels || levels.length === 0) { + public setLevelOptions(options: dL.ILevelUpdateOptions): this { - levels = this._levels.slice(); - } - else if (typeof levels === 'string') { - - levels = [ levels ]; - } + const levels = options.levels?.length ? + Array.isArray(options.levels) ? options.levels : [options.levels] : + this.levels; for (const lv of levels) { - this._globalConfig[lv].trace = depth; - - for (const subject in this._loggers) { + if (!this.levels.includes(lv)) { - this._loggers[subject].enableTrace(depth, lv); + continue; } - } - return this; - } - - public registerDriver(name: string, driver: IDriver): boolean { - - if (this._drivers[name]) { - - return false; - } - - this._drivers[name] = driver; - - return true; - } - - public getDriver(name: string): IDriver { - - return this._drivers[name] || null; - } - - public getDataFormatter(name: string): IFormatter { - - return this._formatters.data[name] || null; - } - - public getTextFormatter(name: string): IFormatter { - - return this._formatters.text[name] || null; - } - - public registerDataFormatter( - name: string, - formatter: IFormatter - ): boolean { - - if (this._formatters.data[name]) { + this._lvOpts[lv] = { + 'traceDepth': Math.max(0, options.traceDepth ?? this._lvOpts[lv]?.traceDepth ?? 0), + 'enabled': options.enabled ?? this._lvOpts[lv]?.enabled ?? true, + 'driver': options.driver ?? this._lvOpts[lv].driver, + 'formatter': options.formatter ?? this._lvOpts[lv].formatter + }; - return false; } - this._formatters.data[name] = formatter as unknown as IFormatter; - - return true; + return this; } - public registerTextFormatter( - name: string, - formatter: IFormatter - ): boolean { + public getLevelOptions(level: TLv): dL.ILevelOptions { - if (this._formatters.text[name]) { - - return false; - } - - this._formatters.text[name] = formatter; - - return true; + return this._lvOpts[level]; } - public createTextLogger( - subject: string = DEFAULT_SUBJECT, - formatter: IFormatter | string = 'default', - driver: string = DEFAULT_DRIVER - ): ILogger { + public createLogger(subject: TLv): dL.ILogger { - const formatterFn = typeof formatter === 'string' ? this._formatters.text[formatter] : formatter; - - if (typeof formatterFn !== 'function') { - - throw new TypeError(`Unknown formatter ${formatter as string}`); - } - - return this.createDataLogger( - subject, - formatterFn, - driver - ); - } - - public createDataLogger( - subject: string = DEFAULT_SUBJECT, - formatter: IFormatter | string = 'default', - driver: string = DEFAULT_DRIVER - ): ILogger { - - if (this._loggers[subject]) { - - return this._loggers[subject]; - } - - const formatFn = typeof formatter === 'string' ? this._formatters.data[formatter] : formatter; - - if (typeof formatFn !== 'function') { - - throw new TypeError(`Unknown formatter ${formatter as string}`); - } - - this._loggers[subject] = new Logger( + return new Logger( subject, - this.getDriver(driver), - this._globalConfig, - formatFn as IFormatter, - this._levels - ) as unknown as ILogger; - - return this._loggers[subject]; + this._lvOpts, + this.levels + ) as dL.ILogger; } } /** * Create a new factory object. */ -export function createFactory(levels: readonly TLv[]): IFactory { - - return new LoggerFactory(levels) as unknown as IFactory; +export function createLoggerFactory< + TData = string, + const TLv extends string = dL.IDefaultLevels +>( + levels: readonly TLv[] = dL.DEFAULT_LEVELS as TLv[], + driver: dL.IDriver = createConsoleDriver(), + formatter: dL.IFormatter = DEFAULT_TEXT_FORMATTER as dL.IFormatter, +): dL.IFactory { + + return new LoggerFactory(driver, levels, formatter) as unknown as dL.IFactory; } /** * The default factory object. */ -const factory = createFactory(DEFAULT_LEVELS); +const factory = createLoggerFactory(dL.DEFAULT_LEVELS); /** * Get the default factory object. */ -export function getDefaultFactory(): IFactory { +export function getDefaultLoggerFactory(): dL.IFactory { - return factory as unknown as IFactory; + return factory; } diff --git a/src/lib/Formatters.ts b/src/lib/Formatters.ts index 92110ac..180b88a 100644 --- a/src/lib/Formatters.ts +++ b/src/lib/Formatters.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 Angus ZENG + * Copyright 2024 Angus ZENG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -import { IFormatter } from './Common'; +import type { IFormatter } from './Decl'; /** * The default formatter for text log. @@ -23,17 +23,17 @@ export const DEFAULT_TEXT_FORMATTER: IFormatter = function( log: string, subject: string, level: string, - date: Date, + time: number, traces?: readonly string[] ): string { if (traces) { - return `[${date.toISOString()}][${level}] ${subject}: ${log} + return `[${new Date(time).toISOString()}][${level}] ${subject}: ${log} at ${traces.join('\n at ')}`; } - return `[${date.toISOString()}][${level}] ${subject}: ${log}`; + return `[${new Date(time).toISOString()}][${level}] ${subject}: ${log}`; }; /** @@ -43,15 +43,9 @@ export const DEFAULT_JSON_FORMATTER: IFormatter = function( log: unknown, subject: string, level: string, - date: Date, + time: number, traces?: readonly string[] ): string { - return JSON.stringify({ - subject, - level, - date: date.getTime(), - log, - traces - }); + return JSON.stringify({ subject, level, time, log, traces }); }; diff --git a/src/lib/Logger.ts b/src/lib/Logger.ts index 4459e02..6208f4d 100644 --- a/src/lib/Logger.ts +++ b/src/lib/Logger.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 Angus ZENG + * Copyright 2024 Angus ZENG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,39 +14,7 @@ * limitations under the License. */ -import { - - IFormatter, - IDriver, - IBaseLogger, - DEFAULT_LEVELS, - ILoggerMethod, - -} from './Common'; - -/** - * Internal settings of each level - */ -export interface ILevelOptions { - - /** - * If the level is enabled for output. - */ - 'enabled': boolean; - - /** - * How many lines of stack trace could be logged. - */ - 'trace': number; -} - -function createMutedLogMethod(logger: Logger): ILoggerMethod { - - return function(): unknown { - - return logger; - } as ILoggerMethod; -} +import type * as dL from './Decl'; /** * Create a logging method, works like a JIT compiler. @@ -55,13 +23,13 @@ function createLogMethod( subject: string, level: string, traceDepth: number, - driver: IDriver, - formatter: IFormatter -): ILoggerMethod { + driver: dL.IDriver, + formatter: dL.IFormatter +): dL.ILoggerMethod { const cs: string[] = []; - cs.push('return function(log, now = new Date()) {'); + cs.push('return function(log, dt = Date.now()) {'); subject = JSON.stringify(subject); level = JSON.stringify(level); @@ -84,18 +52,18 @@ function createLogMethod( if (traceDepth) { - cs.push(' now,'); + cs.push(' dt,'); cs.push(' traces'); } else { - cs.push(' now'); + cs.push(' dt'); } cs.push(' ),'); cs.push(` ${subject},`); cs.push(` ${level},`); - cs.push(' now'); + cs.push(' dt'); cs.push(');'); cs.push('return this;'); @@ -111,156 +79,67 @@ function createLogMethod( ); } -export class Logger implements IBaseLogger { - - /** - * The options of all levels. - */ - protected readonly _options: Record; +export class Logger implements dL.IBaseLogger { - /** - * The subject of current logger. - */ - protected readonly _subject: string; + private readonly _mutedLogger = (): this => this; - /** - * The log formatter of current logger. - */ - protected readonly _formatter!: IFormatter; - - /** - * The log output driver of current logger. - */ - protected readonly _driver: IDriver; - - /** - * The log levels of current logger. - */ - protected readonly _levels: readonly string[]; + protected readonly _options: Record> = {}; public constructor( - subject: string, - driver: IDriver, - settings: Record, - formatFn: IFormatter, - levels: readonly string[] = DEFAULT_LEVELS + public readonly subject: string, + defaultOptions: Record>, + public readonly levels: readonly TLv[] ) { - this._options = {}; - - this._levels = levels; - - this._driver = driver; - - this._subject = subject; - - this._formatter = formatFn; - for (const lv of levels) { - this._options[lv] = { - enabled: settings[lv].enabled, - trace: settings[lv].trace - }; - - this._updateMethod(lv); + this.setLevelOptions({ + ...defaultOptions[lv], + 'levels': lv + }); } } - public flush(): void | Promise { - - return this._driver.flush(); - } - - public getSubject(): string { - - return this._subject; - } - - public getLevels(): string[] { - - return [...this._levels]; - } - - public enableTrace(depth: number = 1, levels?: string | string[]): this { + public setLevelOptions(options: dL.ILevelUpdateOptions): this { - if (!levels || levels.length === 0) { + const levels = options.levels?.length ? + Array.isArray(options.levels) ? options.levels : [options.levels] : + this.levels; - levels = this._levels.slice(); - } - else if (typeof levels === 'string') { - - levels = [ levels ]; - } - - for (const level of levels) { - - this._options[level].trace = depth; - this._updateMethod(level); - } - - return this; - } - - public unmute(levels?: string | readonly string[]): this { - - if (!levels?.length) { + for (const lv of levels) { - levels = this._levels; - } - else if (typeof levels === 'string') { + if (!this.levels.includes(lv)) { - levels = [ levels ]; - } + continue; + } - for (const level of levels) { + this._options[lv] = { + 'traceDepth': Math.max(0, options.traceDepth ?? this._options[lv]?.traceDepth ?? 0), + 'enabled': options.enabled ?? this._options[lv]?.enabled ?? true, + 'driver': options.driver ?? this._options[lv].driver, + 'formatter': options.formatter ?? this._options[lv].formatter + }; - this._options[level].enabled = true; - this._updateMethod(level); + this._updateMethod(lv); } return this; } - public isMuted(level?: string): boolean { - - if (undefined === level) { - - return this._levels.every((lv) => !this._options[lv].enabled); - } - - return !this._options[level].enabled; - } - - public mute(levels?: string | readonly string[]): this { - - if (!levels?.length) { + public getLevel(level: TLv): dL.ILevelOptions { - levels = this._levels; - } - else if (typeof levels === 'string') { - - levels = [ levels ]; - } - - for (const level of levels) { - - this._options[level].enabled = false; - this._updateMethod(level); - } - - return this; + return this._options[level]; } protected _updateMethod(lv: string): void { // @ts-expect-error - this[lv] = this._options[lv].enabled ? createLogMethod( - this._subject, + this[lv] = this._options[lv].enabled ? createLogMethod( + this.subject, lv, - this._options[lv].trace, - this._driver, - this._formatter - ) : createMutedLogMethod(this); + this._options[lv].traceDepth, + this._options[lv].driver, + this._options[lv].formatter + ) : this._mutedLogger; } } diff --git a/src/lib/index.ts b/src/lib/index.ts index 8d32607..330072c 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 Angus ZENG + * Copyright 2024 Angus ZENG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,16 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { getDefaultFactory } from './Factory'; +import { getDefaultLoggerFactory } from './Factory'; -export default getDefaultFactory(); +export default getDefaultLoggerFactory(); -export * from './Common'; +export * from './Decl'; export * from './Factory'; export * from './Formatters'; export * from './Drivers/Console'; - -export * from './Drivers/ColorfulTTY'; diff --git a/tsconfig.json b/tsconfig.json index f3b1b07..6e0e707 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { /* Basic Options */ - "target": "es2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "target": "es2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ // "lib": [], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ @@ -19,21 +19,24 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ "declaration": true, "declarationMap": true, + "forceConsistentCasingInFileNames": true, "sourceMap": true, - "rootDir": "./src", - "outDir": ".", + "rootDir": "src", + "outDir": "./", "noImplicitAny": true, - "forceConsistentCasingInFileNames": true, "noUnusedLocals": true, "noImplicitReturns": true, "strictNullChecks": true, + "strictFunctionTypes": true, + "lib": ["es2020"], "newLine": "LF", + "alwaysStrict": true, /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ + "strict": true /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ // "noUnusedLocals": true, /* Report errors on unused locals. */ @@ -64,4 +67,4 @@ "./*.d.ts", "./**/*.d.ts" ] -} +} \ No newline at end of file