diff --git a/.gitignore b/.gitignore index 673cbc8..f3e5574 100644 --- a/.gitignore +++ b/.gitignore @@ -126,3 +126,4 @@ out *.d.ts dist build +storage diff --git a/README.md b/README.md index f3a359f..06afab3 100644 --- a/README.md +++ b/README.md @@ -31,102 +31,196 @@ npm install @secjs/logger ## Usage +### Config logging template + +> First you need to create the configuration file logging in the config folder on project root path. Is extremely important to use export default in these configurations. + +```ts +import { Env } from '@secjs/env' +import { Path } from '@secjs/utils' + +export default { + /* + |-------------------------------------------------------------------------- + | Default Log Channel + |-------------------------------------------------------------------------- + | + | This option defines the default log channel that gets used when writing + | messages to the logs. The name specified in this option should match + | one of the channels defined in the "channels" configuration object. + | + */ + + default: Env('LOGGING_CHANNEL', 'application'), + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. + | + | Available Drivers: "console", "debug", "file". + | Available Formatters: "context", "debug", "json", "log". + | + */ + + channels: { + application: { + driver: 'console', + context: 'Logger', + formatter: 'context', + }, + debug: { + driver: 'debug', + context: 'Debugger', + formatter: 'context', + namespace: 'api:main', + }, + file: { + driver: 'file', + context: 'Logger', + formatter: 'log', + filePath: Path.noBuild().logs('secjs.log'), + }, + }, +} +``` + ### Log / Logger -> Log any type of requests in your application in public mode +> With the config/logging file created you can use Log and Logger classes to start logging. ```ts -import { Log, Logger } from '@secjs/logger' +import { Log, Logger, Color } from '@secjs/logger' -Log('Hello World!') -// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Log] Hello World! +0ms +// Log and Logger will always use the default values of channel inside config/logging, the default channel in here is "application". +Log.log('Hello World!') +// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Logger] Hello World! +0ms -const logger = new Logger('LogService') +const logger = new Logger() logger.success('Hello World!') -// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [LogService] Hello World! +0ms +// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Logger] Hello World! +0ms -logger.warn('Hello World!', { context: 'LogController' }) +// You can pass options to formatters and drivers as second parameter +logger.warn('Hello World!', { color: Color.purple, context: 'LogController' }) // [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [LogController] Hello World! +0ms ``` -### Formatters / Transporters / LogMapper +### Using other channels -> Use transporters and formatters to keep a pattern in how the application will handle the logs. And use mappers -> to set formatters and transporters that are going to be used. See the example: +> You can use any channel that you configure inside config/logging, SecJS has default channels inside the template file. ```ts -import { - LogMapper, - JsonFormatter, - FileTransporter, - ContextFormatter, - changeLogFnMapper, - ConsoleTransporter, -} from '@secjs/logger' - -const logMapper = new LogMapper([new JsonFormatter()], [new FileTransporter()]) - -// This function is important to change the default mapper from Log function -changeLogFnMapper(logMapper) -const logger = new Logger('Context', logMapper) - -// You can use addFormatter and addTransporter to add more formatters and transporters -logMapper.addFormatter(new ContextFormatter('Context')) -logMapper.addTransporter(new ConsoleTransporter('stdout')) - -// You can use removeFormatter and removeTransporter too. -logMapper.removeFormatter(ContextFormatter) -logMapper.removeTransporter(ConsoleTransporter) +Log.channel('debug').log('Hello debug world!', { namespace: 'api:example' }) +// api:example [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Debugger] Hello debug world! +0ms ``` -> Now Log function and Logger class will use the logMapper instance, -> all logs will be stringify by JsonFormatter, and be saved inside FileTransporter. - -### Custom formatters and transporters - -> Here are all the already implemented formatters and transporters from @secjs/logger +> You can use many channels to handle the log in all of then ```ts -import { - LogFormatter, - JsonFormatter, - DebugFormatter, - ContextFormatter, - FileTransporter, - DebugTransporter, - ConsoleTransporter, -} from '@secjs/logger' +Log.channels('debug', 'application', 'file').info('Hello World!', { namespace: 'api:example' }) +// api:example [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Debugger] Hello World! +0ms +// [SecJS] - PID: 38114 - dd/mm/yyyy, hh:mm:ss PM [Logger] Hello World! +0ms + +// In storage/logs/secjs.log file +// [SecJS] - PID: 196416 - dd/mm/yyyy, hh:mm:ss [INFO] Hello World! ``` -> You can define your own formatters and transporters using the contracts +### Extending drivers, channels and formatters + +> Nowadays, @secjs/logger has only FileDriver, DebugDriver and ConsoleDriver support, but you can extend the drivers for Logger class if you implement DriverContract interface. ```ts -import { FormatterContract, TransporterContract } from '@secjs/logger' +import { DriverContract, FormatterContract, format } from '@secjs/logger' + +interface CustomDriverOpts {} -export class CustomFormatter implements FormatterContract { - format(message: any, options?: any) { - createFileToTransportToS3(message, options.filePath) +class CustomDriver implements DriverContract { + private readonly _level: string + private readonly _context: string + private readonly _formatter: string + + constructor(channel: string) { + const config = Config.get(`logging.channels.${channel}`) - deleteTheFile(options.filePath) + this._level = config.level || 'INFO' + this._context = config.context || 'CustomDriver' + this._formatter = config.formatter || 'context' + } + + transport(message: string, options?: CustomDriverOpts): void { + options = Object.assign( + {}, + { + level: this._level, + context: this._context, + streamType: this._streamType, + }, + options, + ) + + message = format(this._formatter, message, options) + + process[this._streamType].write(`${message}\n`) } } +``` + +> Same to extend formatters + +```ts +class CustomFormatter implements FormatterContract { + // all the methods implemented from FormatterContract... +} +``` -export class CustomTransporter implements TransporterContract { - transport(logFormatted: any, options?: any) { - sendToS3(logFormatted, options.s3Bucket) +> Constructor is extremely important in your CustomDriver class, it's the constructor that will use the values from config/logging channels to manipulate your CustomDriver using channel and channels method from logger. +> So if you are building a CustomDriver, and you want to use it, you can create a new channel inside config/logging channels or change the driver from an existing channel. + +```ts +// extending channels +// config/logging file + +export default { + // default etc... + + channels: { + mychannel: { + driver: 'custom', + level: 'INFO', + formatter: 'context', + context: 'Logger', + } + // ... other disks } } ``` -> Then, use it with the mappers +> Now you can build your new driver using Logger class ```ts -import { LogMapper } from '@secjs/logger' +const driverName = 'custom' +const formatterName = 'custom' +const driver = CustomDriver +const formatter = CustomFormatter -const s3LogMapper = new LogMapper([new CustomFormatter()], [new CustomFormatter()]) +Logger.buildDriver(driverName, driver) +Logger.buildFormatter(formatterName, CustomFormatter) + +console.log(Logger.drivers) // ['console', 'debug', 'file', 'custom'] +console.log(Logger.formatters) // ['context', 'debug', 'json', 'log', 'custom'] +``` + +> Now, if you have implemented your channel in config/logging, you can use him inside logger + +```ts +// options of your driver and formatter +const options = {} -const s3Logger = new Logger('S3LoggerService', s3LogMapper) +// Will use CustomDriver to handle the log actions +logger.channel('mychannel').success('Hello World!!', options) ``` --- diff --git a/config/logging.ts b/config/logging.ts new file mode 100644 index 0000000..981a28c --- /dev/null +++ b/config/logging.ts @@ -0,0 +1,49 @@ +import { Env } from '@secjs/env' +import { Path } from '@secjs/utils' + +export default { + /* + |-------------------------------------------------------------------------- + | Default Log Channel + |-------------------------------------------------------------------------- + | + | This option defines the default log channel that gets used when writing + | messages to the logs. The name specified in this option should match + | one of the channels defined in the "channels" configuration object. + | + */ + + default: Env('LOGGING_CHANNEL', 'application'), + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. + | + | Available Drivers: "console", "debug", "file". + | Available Formatters: "context", "debug", "json", "log". + | + */ + + channels: { + application: { + driver: 'console', + context: 'Logger', + formatter: 'context', + }, + debug: { + driver: 'debug', + context: 'Debugger', + formatter: 'context', + namespace: 'api:main', + }, + file: { + driver: 'file', + context: 'Logger', + formatter: 'log', + filePath: Path.noBuild().logs('secjs.log'), + }, + }, +} diff --git a/index.ts b/index.ts index 3995083..7e99720 100644 --- a/index.ts +++ b/index.ts @@ -1,19 +1,18 @@ -export * from './src/utils/Color' -export * from './src/utils/getTimestamp' - -export * from './src/Logger/Log' -export * from './src/Logger/Logger' -export * from './src/Logger/LogMapper' -export * from './src/Logger/defaultMapper' - +export * from './src/Contracts/DriverContract' export * from './src/Contracts/FormatterContract' -export * from './src/Contracts/TransporterContract' + +export * from './src/Drivers/FileDriver' +export * from './src/Drivers/DebugDriver' +export * from './src/Drivers/ConsoleDriver' export * from './src/Formatters/LogFormatter' export * from './src/Formatters/JsonFormatter' export * from './src/Formatters/DebugFormatter' export * from './src/Formatters/ContextFormatter' -export * from './src/Transporters/FileTransporter' -export * from './src/Transporters/DebugTransporter' -export * from './src/Transporters/ConsoleTransporter' +export * from './src/utils/Color' +export * from './src/utils/format' +export * from './src/utils/getTimestamp' + +export * from './src/Log' +export * from './src/Logger' diff --git a/package-lock.json b/package-lock.json index 327064d..c707304 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,10 @@ "debug": "4.3.1" }, "devDependencies": { + "@secjs/config": "1.0.9", + "@secjs/env": "1.2.8", + "@secjs/exceptions": "1.0.4", + "@secjs/utils": "1.5.4", "@types/debug": "4.1.5", "@types/jest": "27.0.1", "@types/node": "14.14.37", @@ -39,7 +43,8 @@ "ts-loader": "9.2.3", "ts-node": "10.0.0", "tsconfig-paths": "3.9.0", - "typescript": "4.3.5" + "typescript": "4.3.5", + "uuid": "^8.3.2" } }, "node_modules/@babel/code-frame": { @@ -1293,6 +1298,57 @@ "node": ">= 8" } }, + "node_modules/@secjs/config": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@secjs/config/-/config-1.0.9.tgz", + "integrity": "sha512-5eB/UoZBPG1cgcUBmoXSpBUU/SLnT6dhjuWuIuyrfWRtFODY7S3zAoaBHzHYWtEuwjhoAfCvjIziZme7C8+/bg==", + "dev": true + }, + "node_modules/@secjs/env": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@secjs/env/-/env-1.2.8.tgz", + "integrity": "sha512-J5BZe2NwlP02NvlzLMWjRnXKqVL7jwceDahZcPTQCwFcVGVQaVSZoci+wJ6+/kj66++2XIdExS3xhIkHimiYYQ==", + "dev": true, + "dependencies": { + "dotenv": "10.0.0" + } + }, + "node_modules/@secjs/exceptions": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@secjs/exceptions/-/exceptions-1.0.4.tgz", + "integrity": "sha512-prj8eNUOqJtrEdUFX58gqvo1RsuKZJI6pJnUr/molkDEerhWEF4lAuR8gliQo+cA+LASAvCeJXDkTWR/xbodMQ==", + "dev": true + }, + "node_modules/@secjs/utils": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@secjs/utils/-/utils-1.5.4.tgz", + "integrity": "sha512-43hDBBoOI632oKPmf0LlkflOB1CLYcBEm3Q4F3Vw9ArJp8b5MDfW7LHGC4k8U6ucJsJoptbnvI/X4fW6MHQnFw==", + "dev": true, + "dependencies": { + "mime-types": "2.1.34" + } + }, + "node_modules/@secjs/utils/node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@secjs/utils/node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -1397,35 +1453,6 @@ "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", "dev": true }, - "node_modules/@types/eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==", - "dev": true, - "peer": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", - "dev": true, - "peer": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", - "dev": true, - "peer": true - }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -1731,181 +1758,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "dev": true, - "peer": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "dev": true, - "peer": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true, - "peer": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "dev": true, - "peer": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true, - "peer": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true, - "peer": true - }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -1993,16 +1845,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peer": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -2439,16 +2281,6 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6.0" - } - }, "node_modules/ci-info": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", @@ -3073,6 +2905,15 @@ "node": ">=8" } }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/electron-to-chromium": { "version": "1.3.856", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.856.tgz", @@ -3174,13 +3015,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-module-lexer": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.2.tgz", - "integrity": "sha512-YkAGWqxZq2B4FxQ5y687UwywDwvLQhIMCZ+SDU7ZW729SDHOEI6wVFXwTRecz+yiwJzCsVwC6V7bxyNbZSB1rg==", - "dev": true, - "peer": true - }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -3868,16 +3702,6 @@ "node": ">=0.10.0" } }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.x" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -4154,6 +3978,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", "dev": true, "funding": { "url": "https://ko-fi.com/tunnckoCore/commissions" @@ -4321,13 +4146,6 @@ "node": ">= 6" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "peer": true - }, "node_modules/global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -6618,16 +6436,6 @@ "node": ">=4" } }, - "node_modules/loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6.11.5" - } - }, "node_modules/locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", @@ -6929,13 +6737,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true - }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -7475,16 +7276,6 @@ } ] }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "peer": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -7761,25 +7552,6 @@ "node": ">=10" } }, - "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "peer": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -7801,16 +7573,6 @@ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", "dev": true }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "peer": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8261,93 +8023,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/terser": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", - "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", - "dev": true, - "peer": true, - "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", - "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", - "dev": true, - "peer": true, - "dependencies": { - "jest-worker": "^27.0.6", - "p-limit": "^3.1.0", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "peer": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "peer": true - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -8679,6 +8354,15 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -8748,20 +8432,6 @@ "makeerror": "1.0.x" } }, - "node_modules/watchpack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", - "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", - "dev": true, - "peer": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -8771,87 +8441,6 @@ "node": ">=10.4" } }, - "node_modules/webpack": { - "version": "5.56.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.56.0.tgz", - "integrity": "sha512-pJ7esw2AGkpZL0jqsEAKnDEfRZdrc9NVjAWA+d1mFkwj68ng9VQ6+Wnrl+kS5dlDHvrat5ASK5vd7wp6I7f53Q==", - "dev": true, - "peer": true, - "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.3", - "es-module-lexer": "^0.9.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^3.2.0" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-sources": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.1.tgz", - "integrity": "sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true, - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz", - "integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==", - "dev": true, - "peer": true, - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -9048,19 +8637,6 @@ "engines": { "node": ">=6" } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } }, "dependencies": { @@ -10026,6 +9602,53 @@ "fastq": "^1.6.0" } }, + "@secjs/config": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@secjs/config/-/config-1.0.9.tgz", + "integrity": "sha512-5eB/UoZBPG1cgcUBmoXSpBUU/SLnT6dhjuWuIuyrfWRtFODY7S3zAoaBHzHYWtEuwjhoAfCvjIziZme7C8+/bg==", + "dev": true + }, + "@secjs/env": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@secjs/env/-/env-1.2.8.tgz", + "integrity": "sha512-J5BZe2NwlP02NvlzLMWjRnXKqVL7jwceDahZcPTQCwFcVGVQaVSZoci+wJ6+/kj66++2XIdExS3xhIkHimiYYQ==", + "dev": true, + "requires": { + "dotenv": "10.0.0" + } + }, + "@secjs/exceptions": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@secjs/exceptions/-/exceptions-1.0.4.tgz", + "integrity": "sha512-prj8eNUOqJtrEdUFX58gqvo1RsuKZJI6pJnUr/molkDEerhWEF4lAuR8gliQo+cA+LASAvCeJXDkTWR/xbodMQ==", + "dev": true + }, + "@secjs/utils": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@secjs/utils/-/utils-1.5.4.tgz", + "integrity": "sha512-43hDBBoOI632oKPmf0LlkflOB1CLYcBEm3Q4F3Vw9ArJp8b5MDfW7LHGC4k8U6ucJsJoptbnvI/X4fW6MHQnFw==", + "dev": true, + "requires": { + "mime-types": "2.1.34" + }, + "dependencies": { + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "requires": { + "mime-db": "1.51.0" + } + } + } + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -10127,35 +9750,6 @@ "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", "dev": true }, - "@types/eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A==", - "dev": true, - "peer": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", - "dev": true, - "peer": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", - "dev": true, - "peer": true - }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -10379,181 +9973,6 @@ "eslint-visitor-keys": "^2.0.0" } }, - "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", - "dev": true, - "peer": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true, - "peer": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true, - "peer": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true, - "peer": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "dev": true, - "peer": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true, - "peer": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "dev": true, - "peer": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "dev": true, - "peer": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "dev": true, - "peer": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true, - "peer": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "dev": true, - "peer": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "dev": true, - "peer": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "dev": true, - "peer": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "dev": true, - "peer": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "dev": true, - "peer": true, - "requires": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true, - "peer": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true, - "peer": true - }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -10620,14 +10039,6 @@ "uri-js": "^4.2.2" } }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peer": true, - "requires": {} - }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -10952,13 +10363,6 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "peer": true - }, "ci-info": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", @@ -11456,6 +10860,12 @@ } } }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true + }, "electron-to-chromium": { "version": "1.3.856", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.856.tgz", @@ -11539,13 +10949,6 @@ "unbox-primitive": "^1.0.1" } }, - "es-module-lexer": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.2.tgz", - "integrity": "sha512-YkAGWqxZq2B4FxQ5y687UwywDwvLQhIMCZ+SDU7ZW729SDHOEI6wVFXwTRecz+yiwJzCsVwC6V7bxyNbZSB1rg==", - "dev": true, - "peer": true - }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -12030,13 +11433,6 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "peer": true - }, "execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -12384,13 +11780,6 @@ "is-glob": "^4.0.1" } }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "peer": true - }, "global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -14126,13 +13515,6 @@ } } }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true, - "peer": true - }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", @@ -14372,13 +13754,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "peer": true - }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -14767,16 +14142,6 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "peer": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -14973,18 +14338,6 @@ "xmlchars": "^2.2.0" } }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "peer": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -15000,16 +14353,6 @@ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", "dev": true }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "peer": true, - "requires": { - "randombytes": "^2.1.0" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -15358,61 +14701,6 @@ "supports-hyperlinks": "^2.0.0" } }, - "terser": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", - "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", - "dev": true, - "peer": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "peer": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "peer": true - } - } - }, - "terser-webpack-plugin": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", - "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", - "dev": true, - "peer": true, - "requires": { - "jest-worker": "^27.0.6", - "p-limit": "^3.1.0", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "peer": true, - "requires": { - "yocto-queue": "^0.1.0" - } - } - } - }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -15642,6 +14930,12 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -15704,80 +14998,12 @@ "makeerror": "1.0.x" } }, - "watchpack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", - "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", - "dev": true, - "peer": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, "webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", "dev": true }, - "webpack": { - "version": "5.56.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.56.0.tgz", - "integrity": "sha512-pJ7esw2AGkpZL0jqsEAKnDEfRZdrc9NVjAWA+d1mFkwj68ng9VQ6+Wnrl+kS5dlDHvrat5ASK5vd7wp6I7f53Q==", - "dev": true, - "peer": true, - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.3", - "es-module-lexer": "^0.9.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^3.2.0" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true, - "peer": true - }, - "acorn-import-assertions": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz", - "integrity": "sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==", - "dev": true, - "peer": true, - "requires": {} - } - } - }, - "webpack-sources": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.1.tgz", - "integrity": "sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA==", - "dev": true, - "peer": true - }, "whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -15924,13 +15150,6 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "peer": true } } } diff --git a/package.json b/package.json index 6085a55..6ff75e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@secjs/logger", - "version": "1.2.2", + "version": "1.2.3", "description": "", "license": "MIT", "author": "João Lenon", @@ -22,6 +22,10 @@ "debug": "4.3.1" }, "devDependencies": { + "@secjs/config": "1.0.9", + "@secjs/env": "1.2.8", + "@secjs/exceptions": "1.0.4", + "@secjs/utils": "1.5.4", "@types/debug": "4.1.5", "@types/jest": "27.0.1", "@types/node": "14.14.37", @@ -48,7 +52,8 @@ "ts-loader": "9.2.3", "ts-node": "10.0.0", "tsconfig-paths": "3.9.0", - "typescript": "4.3.5" + "typescript": "4.3.5", + "uuid": "^8.3.2" }, "husky": { "hooks": { diff --git a/src/Contracts/DriverContract.ts b/src/Contracts/DriverContract.ts new file mode 100644 index 0000000..7893e51 --- /dev/null +++ b/src/Contracts/DriverContract.ts @@ -0,0 +1,3 @@ +export interface DriverContract { + transport(message: string, options?: any): void | Promise +} diff --git a/src/Contracts/FormatterContract.ts b/src/Contracts/FormatterContract.ts index fa21dc9..2427401 100644 --- a/src/Contracts/FormatterContract.ts +++ b/src/Contracts/FormatterContract.ts @@ -1,8 +1,3 @@ export interface FormatterContract { format(message: any, options?: any) } - -export interface FormatterMapperContract { - name: string - impl: FormatterContract -} diff --git a/src/Contracts/TransporterContract.ts b/src/Contracts/TransporterContract.ts deleted file mode 100644 index c3326fe..0000000 --- a/src/Contracts/TransporterContract.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface TransporterContract { - transport(logFormatted: any, options?: any) -} - -export interface TransporterMapperContract { - name: string - impl: TransporterContract -} diff --git a/src/Drivers/ConsoleDriver.ts b/src/Drivers/ConsoleDriver.ts new file mode 100644 index 0000000..1670085 --- /dev/null +++ b/src/Drivers/ConsoleDriver.ts @@ -0,0 +1,43 @@ +import { Config } from '@secjs/config' +import { Color } from '../utils/Color' +import { format } from '../utils/format' +import { DriverContract } from '../Contracts/DriverContract' + +export interface ConsoleDriverOpts { + color: Color + level: string + context: string + streamType: string +} + +export class ConsoleDriver implements DriverContract { + private readonly _level: string + private readonly _context: string + private readonly _formatter: string + private readonly _streamType: string + + constructor(channel: string) { + const config = Config.get(`logging.channels.${channel}`) || {} + + this._level = config.level || 'INFO' + this._context = config.context || 'ConsoleDriver' + this._formatter = config.formatter || 'context' + this._streamType = config.streamType || 'stdout' + } + + transport(message: string, options?: ConsoleDriverOpts): void { + options = Object.assign( + {}, + { + level: this._level, + context: this._context, + streamType: this._streamType, + }, + options, + ) + + message = format(this._formatter, message, options) + + process[this._streamType].write(`${message}\n`) + } +} diff --git a/src/Drivers/DebugDriver.ts b/src/Drivers/DebugDriver.ts new file mode 100644 index 0000000..07d356d --- /dev/null +++ b/src/Drivers/DebugDriver.ts @@ -0,0 +1,45 @@ +import { debug } from 'debug' +import { Color } from '../utils/Color' +import { Config } from '@secjs/config' +import { format } from '../utils/format' +import { DriverContract } from '../Contracts/DriverContract' + +export interface DebugDriverOpts { + color: Color + level: string + context: string + formatter: string + namespace: string +} + +export class DebugDriver implements DriverContract { + private readonly _level: string + private readonly _context: string + private readonly _formatter: string + private readonly _namespace: string + + constructor(channel: string) { + const config = Config.get(`logging.channels.${channel}`) || {} + + this._level = config.level || 'DEBUG' + this._context = config.context || 'DebugDriver' + this._formatter = config.formatter || 'context' + this._namespace = config.namespace || 'api:main' + } + + transport(message: string, options?: DebugDriverOpts): void { + options = Object.assign( + {}, + { + level: this._level, + context: this._context, + namespace: this._namespace, + }, + options, + ) + + message = format(this._formatter, message, options) + + debug(options.namespace)(message) + } +} diff --git a/src/Drivers/Drivers.ts b/src/Drivers/Drivers.ts new file mode 100644 index 0000000..18395ef --- /dev/null +++ b/src/Drivers/Drivers.ts @@ -0,0 +1,9 @@ +import { FileDriver } from './FileDriver' +import { DebugDriver } from './DebugDriver' +import { ConsoleDriver } from './ConsoleDriver' + +export const Drivers = { + file: FileDriver, + debug: DebugDriver, + console: ConsoleDriver, +} diff --git a/src/Drivers/FileDriver.ts b/src/Drivers/FileDriver.ts new file mode 100644 index 0000000..09ba05a --- /dev/null +++ b/src/Drivers/FileDriver.ts @@ -0,0 +1,53 @@ +import { parse } from 'path' +import { Path } from '@secjs/utils' +import { Color } from '../utils/Color' +import { Config } from '@secjs/config' +import { DriverContract } from '../Contracts/DriverContract' +import { createWriteStream, existsSync, mkdirSync } from 'fs' + +export interface FileDriverOpts { + level: string + context: string + formatter: string + filePath: string +} + +export class FileDriver implements DriverContract { + private readonly _level: string + private readonly _context: string + private readonly _filePath: string + private readonly _formatter: string + + constructor(channel: string) { + const config = Config.get(`logging.channels.${channel}`) || {} + + this._level = config.level || 'INFO' + this._context = config.context || 'FileDriver' + this._filePath = config.filePath || Path.noBuild().logs('secjs.log') + this._formatter = config.formatter || 'log' + } + + transport(message: string, options?: FileDriverOpts): void { + options = Object.assign( + {}, + { level: this._level, context: this._context, filePath: this._filePath }, + options, + ) + + const path = parse(options.filePath) + + if (!existsSync(path.dir)) { + mkdirSync(path.dir, { recursive: true }) + } + + const stream = createWriteStream(options.filePath, { flags: 'a' }) + + stream.write(`${Color.removeColors(message)}` + '\n') + + stream.on('error', err => { + throw err + }) + + stream.end() + } +} diff --git a/src/Formatters/ContextFormatter.ts b/src/Formatters/ContextFormatter.ts index 3f99224..368010c 100644 --- a/src/Formatters/ContextFormatter.ts +++ b/src/Formatters/ContextFormatter.ts @@ -9,28 +9,19 @@ export interface ContextFormatterOptions { } export class ContextFormatter implements FormatterContract { - private readonly presets: ContextFormatterOptions - - constructor(context = ContextFormatter.name, color = Color.green) { - this.presets = { color, context } - } - - resolvePreset(options?: ContextFormatterOptions) { - return { - ...this.presets, - ...options, - } - } - format(message: string, options?: ContextFormatterOptions): string { - const presets = this.resolvePreset(options) + options = Object.assign( + {}, + { color: Color.green, context: 'Logger' }, + options, + ) const pid = Color.yellow(`[SecJS] - PID: ${process.pid}`) - const timestamp = Color.white(getTimestamp()) - const messageCtx = Color.yellow(`[${presets.context}] `) + const timestamp = getTimestamp() + const messageCtx = Color.yellow(`[${options.context}] `) const timestampDiff = ContextFormatter.getTimestampDiff() - return `${pid} - ${timestamp} ${messageCtx}${presets.color( + return `${pid} - ${timestamp} ${messageCtx}${options.color( message, )}${timestampDiff}` } diff --git a/src/Formatters/DebugFormatter.ts b/src/Formatters/DebugFormatter.ts index 2be8209..4ca0340 100644 --- a/src/Formatters/DebugFormatter.ts +++ b/src/Formatters/DebugFormatter.ts @@ -6,31 +6,23 @@ import { FormatterContract } from '../Contracts/FormatterContract' export interface DebugFormatterOptions { color: Chalk context: string + namespace: string } export class DebugFormatter implements FormatterContract { - private readonly presets: DebugFormatterOptions - - constructor(context = DebugFormatter.name, color = Color.white) { - this.presets = { color, context } - } - - resolvePreset(options?: DebugFormatterOptions) { - return { - ...this.presets, - ...options, - } - } - format(message: string, options?: DebugFormatterOptions): string { - const presets = this.resolvePreset(options) + options = Object.assign( + {}, + { color: Color.green, context: 'Debugger', namespace: 'api:main' }, + options, + ) const pid = Color.purple(`[SecJS Debugger] - PID: ${process.pid}`) const timestamp = Color.white(getTimestamp()) - const messageCtx = Color.yellow(`[${presets.context}] `) + const messageCtx = Color.yellow(`[${options.context}] `) const timestampDiff = DebugFormatter.getTimestampDiff() - return `${pid} - ${timestamp} ${messageCtx}${presets.color( + return `${pid} - ${timestamp} ${messageCtx}${options.color( message, )}${timestampDiff}` } diff --git a/src/Formatters/Formatters.ts b/src/Formatters/Formatters.ts new file mode 100644 index 0000000..b8357cd --- /dev/null +++ b/src/Formatters/Formatters.ts @@ -0,0 +1,11 @@ +import { ContextFormatter } from './ContextFormatter' +import { DebugFormatter } from './DebugFormatter' +import { JsonFormatter } from './JsonFormatter' +import { LogFormatter } from './LogFormatter' + +export const Formatters = { + context: ContextFormatter, + debug: DebugFormatter, + json: JsonFormatter, + log: LogFormatter, +} diff --git a/src/Formatters/JsonFormatter.ts b/src/Formatters/JsonFormatter.ts index 297a22d..3640371 100644 --- a/src/Formatters/JsonFormatter.ts +++ b/src/Formatters/JsonFormatter.ts @@ -7,28 +7,15 @@ export interface JsonFormatterOptions { } export class JsonFormatter implements FormatterContract { - private readonly presets: JsonFormatterOptions - - constructor(color = Color.white) { - this.presets = { color } - } - - resolvePreset(options?: JsonFormatterOptions) { - return { - ...this.presets, - ...options, - } - } - format( message: Record, options?: JsonFormatterOptions, ): string { - const presets = this.resolvePreset(options) + options = Object.assign({}, { color: Color.green }, options) const pid = Color.yellow(`[SecJS] - PID: ${process.pid}`) - return `${pid} - ${Color.bold('JSON:')} ${presets.color( + return `${pid} - ${Color.bold('JSON:')} ${options.color( JSON.stringify(message), )}` } diff --git a/src/Formatters/LogFormatter.ts b/src/Formatters/LogFormatter.ts index 48bb9bd..076a095 100644 --- a/src/Formatters/LogFormatter.ts +++ b/src/Formatters/LogFormatter.ts @@ -9,30 +9,14 @@ export interface LogFormatterOptions { } export class LogFormatter implements FormatterContract { - private readonly presets: LogFormatterOptions - - constructor( - color = Color.info, - level: 'INFO' | 'DEBUG' | 'WARN' | 'ERROR' | 'SUCCESS' = 'INFO', - ) { - this.presets = { color, level } - } - - resolvePreset(options?: LogFormatterOptions) { - return { - ...this.presets, - ...options, - } - } - format(message: string, options?: LogFormatterOptions): string { - const presets = this.resolvePreset(options) + options = Object.assign({}, { color: Color.green, level: 'info' }, options) const pid = Color.yellow(`[SecJS] - PID: ${process.pid}`) - const timestamp = Color.white(getTimestamp()) - const level = LogFormatter.paintByLevel(presets.level) + const timestamp = getTimestamp() + const level = LogFormatter.paintByLevel(options.level) - return `${pid} - ${timestamp} ${level} ${presets.color(message)}` + return `${pid} - ${timestamp} ${level} ${options.color(message)}` } private static paintByLevel(level: string) { diff --git a/src/Log.ts b/src/Log.ts new file mode 100644 index 0000000..ab0bfc7 --- /dev/null +++ b/src/Log.ts @@ -0,0 +1,78 @@ +import { Logger } from './Logger' +import { DriverContract } from './Contracts/DriverContract' +import { FormatterContract } from './Contracts/FormatterContract' + +export class Log { + private static logger: Logger = new Logger() + + static buildDriver(name: string, driver: DriverContract): typeof Log { + Logger.buildDriver(name, driver) + + return this + } + + static buildFormatter( + name: string, + formatter: FormatterContract, + ): typeof Log { + Logger.buildFormatter(name, formatter) + + return this + } + + static get drivers(): string[] { + return Logger.drivers + } + + static get formatters(): string[] { + return Logger.formatters + } + + static channel(channel: string): typeof Log { + this.logger.channel(channel) + + return this + } + + static channels(...channels: string[]): typeof Log { + this.logger.channels(...channels) + + return this + } + + static log(message: any, options?: any) { + this.logger.log(message, options) + + this.logger = new Logger() + } + + static info(message: any, options?: any) { + this.logger.info(message, options) + + this.logger = new Logger() + } + + static warn(message: any, options?: any) { + this.logger.warn(message, options) + + this.logger = new Logger() + } + + static error(message: any, options?: any) { + this.logger.error(message, options) + + this.logger = new Logger() + } + + static debug(message: any, options?: any) { + this.logger.debug(message, options) + + this.logger = new Logger() + } + + static success(message: any, options?: any) { + this.logger.success(message, options) + + this.logger = new Logger() + } +} diff --git a/src/Logger.ts b/src/Logger.ts new file mode 100644 index 0000000..7133320 --- /dev/null +++ b/src/Logger.ts @@ -0,0 +1,193 @@ +import { + InternalServerException, + NotImplementedException, +} from '@secjs/exceptions' + +import { Config } from '@secjs/config' +import { Color } from './utils/Color' +import { Drivers } from './Drivers/Drivers' +import { Formatters } from './Formatters/Formatters' +import { DriverContract } from './Contracts/DriverContract' +import { FormatterContract } from './Contracts/FormatterContract' + +export class Logger { + private _tempDrivers: DriverContract[] | null = null + private _defaultDriver: DriverContract | null = null + + static buildDriver(name: string, driver: DriverContract) { + if (Drivers[name]) { + throw new InternalServerException(`Driver ${name} already exists`) + } + + Drivers[name] = driver + } + + static buildFormatter(name: string, formatter: FormatterContract) { + if (Formatters[name]) { + throw new InternalServerException(`Formatter ${name} already exists`) + } + + Formatters[name] = formatter + } + + static get drivers(): string[] { + return Object.keys(Drivers) + } + + static get formatters(): string[] { + return Object.keys(Formatters) + } + + constructor() { + const defaultChannel = Config.get('logging.default') + const channelConfig = Config.get(`logging.channels.${defaultChannel}`) + + this._defaultDriver = new Drivers[channelConfig.driver](defaultChannel) + } + + private _driver(message: any, options?: any) { + if (this._tempDrivers && this._tempDrivers.length) { + this._tempDrivers.forEach(tempDriver => { + tempDriver.transport(message, options) + }) + + return + } + + this._defaultDriver.transport(message, options) + } + + changeDefaultChannel(channel: string): Logger { + const channelConfig = Config.get(`logging.channels.${channel}`) + + if (!channelConfig) { + throw new NotImplementedException( + `Channel ${channel} is not configured inside logging.channels object from config/logging file`, + ) + } + + if (!Drivers[channelConfig.driver]) { + throw new NotImplementedException( + `Driver ${channelConfig.driver} does not exist, use Storage.build method to create a new driver`, + ) + } + + this._defaultDriver = new Drivers[channelConfig.driver](channel) + + return this + } + + channel(channel: string): Logger { + const channelConfig = Config.get(`logging.channels.${channel}`) + + if (!channelConfig) { + throw new NotImplementedException( + `Channel ${channel} is not configured inside logging.channels object from config/logging file`, + ) + } + + if (!Drivers[channelConfig.driver]) { + throw new NotImplementedException( + `Driver ${channelConfig.driver} does not exist, use Storage.build method to create a new driver`, + ) + } + + this._tempDrivers = [] + + this._tempDrivers.push(new Drivers[channelConfig.driver](channel)) + + return this + } + + channels(...channels: string[]): Logger { + this._tempDrivers = [] + + channels.forEach(channel => { + const channelConfig = Config.get(`logging.channels.${channel}`) + + if (!channelConfig) { + throw new NotImplementedException( + `Channel ${channel} is not configured inside logging.channels object from config/logging file`, + ) + } + + if (!Drivers[channelConfig.driver]) { + throw new NotImplementedException( + `Driver ${channelConfig.driver} does not exist, use Storage.build method to create a new driver`, + ) + } + + this._tempDrivers.push(new Drivers[channelConfig.driver](channel)) + }) + + return this + } + + log(message: any, options?: any) { + options = Object.assign({}, { context: 'Logger' }, options) + + this._driver(message, options) + + this._tempDrivers = [] + } + + info(message: any, options?: any) { + options = Object.assign({}, { context: 'Logger' }, options) + + options.level = 'INFO' + options.color = Color.cyan + options.streamType = 'stdout' + + this._driver(message, options) + + this._tempDrivers = [] + } + + warn(message: any, options?: any) { + options = Object.assign({}, { context: 'Logger' }, options) + + options.level = 'WARN' + options.color = Color.orange + options.streamType = 'stdout' + + this._driver(message, options) + + this._tempDrivers = [] + } + + error(message: any, options?: any) { + options = Object.assign({}, { context: 'Logger' }, options) + + options.level = 'ERROR' + options.color = Color.red + options.streamType = 'stderr' + + this._driver(message, options) + + this._tempDrivers = [] + } + + debug(message: any, options?: any) { + options = Object.assign({}, { context: 'Logger' }, options) + + options.level = 'DEBUG' + options.color = Color.purple + options.streamType = 'stdout' + + this._driver(message, options) + + this._tempDrivers = [] + } + + success(message: any, options?: any) { + options = Object.assign({}, { context: 'Logger' }, options) + + options.level = 'SUCCESS' + options.color = Color.green + options.streamType = 'stdout' + + this._driver(message, options) + + this._tempDrivers = [] + } +} diff --git a/src/Logger/Log.ts b/src/Logger/Log.ts deleted file mode 100644 index 3c5dc1e..0000000 --- a/src/Logger/Log.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { LogMapper } from './LogMapper' -import { defaultMapper } from './defaultMapper' - -let mapper = defaultMapper - -export function Log( - message: any, - formatterOpts: any = {}, - transporterOpts: any = {}, -): void { - formatterOpts.context = 'Log' - - mapper.resolve(message, formatterOpts, transporterOpts) -} - -export function changeLogFnMapper(m: LogMapper) { - mapper = m -} diff --git a/src/Logger/LogMapper.ts b/src/Logger/LogMapper.ts deleted file mode 100644 index 3da868d..0000000 --- a/src/Logger/LogMapper.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { - FormatterContract, - FormatterMapperContract, -} from '../Contracts/FormatterContract' - -import { - TransporterContract, - TransporterMapperContract, -} from '../Contracts/TransporterContract' - -export class LogMapper { - formatters: FormatterMapperContract[] = [] - transporters: TransporterMapperContract[] = [] - - constructor( - formatters: FormatterContract[], - transporters: TransporterContract[], - ) { - formatters.forEach(formatter => this.addFormatter(formatter)) - transporters.forEach(transporter => this.addTransporter(transporter)) - } - - addFormatter(formatter: FormatterContract) { - this.formatters.push({ name: formatter.constructor.name, impl: formatter }) - } - - addTransporter(transporter: TransporterContract) { - this.transporters.push({ - name: transporter.constructor.name, - impl: transporter, - }) - } - - removeFormatter(formatter: { new (): FormatterContract }) { - this.formatters.forEach((f, i) => { - if (f.name === formatter.name) this.transporters.splice(i, 1) - }) - } - - removeTransporter(transporter: { new (): TransporterContract }) { - this.transporters.forEach((t, i) => { - if (t.name === transporter.name) this.transporters.splice(i, 1) - }) - } - - resolve(message: any, formatterOpts?: any, transporterOpts?: any) { - this.transporters.forEach(transporter => { - this.formatters.forEach(formatter => { - transporter.impl.transport( - formatter.impl.format(message, formatterOpts), - transporterOpts, - ) - }) - }) - } -} diff --git a/src/Logger/Logger.ts b/src/Logger/Logger.ts deleted file mode 100644 index bbadcf8..0000000 --- a/src/Logger/Logger.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Color } from '../utils/Color' -import { LogMapper } from './LogMapper' -import { defaultMapper } from './defaultMapper' - -export class Logger { - private readonly context: string - private readonly mapper: LogMapper - - constructor(context = Logger.name, mapper?: LogMapper) { - this.context = context - this.mapper = mapper || defaultMapper - } - - info(message: any, formatterOpts: any = {}, transporterOpts: any = {}) { - formatterOpts.level = 'INFO' - formatterOpts.color = Color.cyan - formatterOpts.context = formatterOpts.context || this.context - transporterOpts.streamType = 'stdout' - - this.mapper.resolve(message, formatterOpts, transporterOpts) - } - - debug(message: any, formatterOpts: any = {}, transporterOpts: any = {}) { - formatterOpts.level = 'DEBUG' - formatterOpts.color = Color.purple - formatterOpts.context = formatterOpts.context || this.context - transporterOpts.streamType = 'stdout' - - this.mapper.resolve(message, formatterOpts, transporterOpts) - } - - warn(message: any, formatterOpts: any = {}, transporterOpts: any = {}) { - formatterOpts.level = 'WARN' - formatterOpts.color = Color.orange - formatterOpts.context = formatterOpts.context || this.context - transporterOpts.streamType = 'stdout' - - this.mapper.resolve(message, formatterOpts, transporterOpts) - } - - error(message: any, formatterOpts: any = {}, transporterOpts: any = {}) { - formatterOpts.level = 'ERROR' - formatterOpts.color = Color.red - formatterOpts.context = formatterOpts.context || this.context - transporterOpts.streamType = 'stderr' - - this.mapper.resolve(message, formatterOpts, transporterOpts) - } - - success(message: any, formatterOpts: any = {}, transporterOpts: any = {}) { - formatterOpts.level = 'SUCCESS' - formatterOpts.color = Color.green - formatterOpts.context = formatterOpts.context || this.context - transporterOpts.streamType = 'stdout' - - this.mapper.resolve(message, formatterOpts, transporterOpts) - } -} diff --git a/src/Logger/defaultMapper.ts b/src/Logger/defaultMapper.ts deleted file mode 100644 index 5c04d2b..0000000 --- a/src/Logger/defaultMapper.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { LogMapper } from './LogMapper' -import { ContextFormatter } from '../Formatters/ContextFormatter' -import { ConsoleTransporter } from '../Transporters/ConsoleTransporter' - -export let defaultMapper = new LogMapper( - [new ContextFormatter()], - [new ConsoleTransporter()], -) - -export function changeDefaultMapper(m: LogMapper) { - defaultMapper = m -} diff --git a/src/Transporters/ConsoleTransporter.ts b/src/Transporters/ConsoleTransporter.ts deleted file mode 100644 index d1bf41d..0000000 --- a/src/Transporters/ConsoleTransporter.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { TransporterContract } from '../Contracts/TransporterContract' - -export interface ConsoleTransporterOptions { - streamType: 'stdout' | 'stderr' -} - -export class ConsoleTransporter implements TransporterContract { - private readonly presets: ConsoleTransporterOptions - - constructor(streamType: 'stdout' | 'stderr' = 'stdout') { - this.presets = { streamType } - } - - resolvePreset(options?: ConsoleTransporterOptions) { - return { - ...this.presets, - ...options, - } - } - - transport(log: string, options?: ConsoleTransporterOptions): void { - const presets = this.resolvePreset(options) - - process[presets.streamType].write(`${log}\n`) - } -} diff --git a/src/Transporters/DebugTransporter.ts b/src/Transporters/DebugTransporter.ts deleted file mode 100644 index c433383..0000000 --- a/src/Transporters/DebugTransporter.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { debug } from 'debug' -import { TransporterContract } from '../Contracts/TransporterContract' - -export interface DebugTransporterOptions { - namespace: string -} - -export class DebugTransporter implements TransporterContract { - private readonly presets: DebugTransporterOptions - - constructor(namespace = 'api:main') { - this.presets = { namespace } - } - - resolvePreset(options?: DebugTransporterOptions) { - return { - ...this.presets, - ...options, - } - } - - transport(log: string, options?: DebugTransporterOptions): void { - const presets = this.resolvePreset(options) - - debug(presets.namespace)(log) - } -} diff --git a/src/Transporters/FileTransporter.ts b/src/Transporters/FileTransporter.ts deleted file mode 100644 index cd225b2..0000000 --- a/src/Transporters/FileTransporter.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Color } from '../utils/Color' -import { createWriteStream, existsSync, mkdirSync } from 'fs' -import { TransporterContract } from '../Contracts/TransporterContract' - -export interface FileTransporterOptions { - path: string - fileName: string -} - -export class FileTransporter implements TransporterContract { - private readonly presets: FileTransporterOptions - - constructor(path = `${process.cwd()}/storage/logs`, fileName = 'secjs.log') { - this.presets = { path, fileName } - } - - resolvePreset(options?: FileTransporterOptions) { - return { - ...this.presets, - ...options, - } - } - - transport(log: string, options?: FileTransporterOptions): void { - const presets = this.resolvePreset(options) - - const path = `${presets.path}/${presets.fileName}` - - if (!existsSync(presets.path)) mkdirSync(presets.path, { recursive: true }) - - const stream = createWriteStream(path, { flags: 'a' }) - - stream.write(`${Color.removeColors(log)}` + '\n') - - stream.on('error', err => { - throw err - }) - - stream.end() - } -} diff --git a/src/utils/format.ts b/src/utils/format.ts new file mode 100644 index 0000000..6a4976f --- /dev/null +++ b/src/utils/format.ts @@ -0,0 +1,12 @@ +import { Formatters } from '../Formatters/Formatters' +import { NotImplementedException } from '@secjs/exceptions' + +export function format(formatter: string, message: any, options?: any): string { + const Formatter = Formatters[formatter] + + if (!Formatter) { + throw new NotImplementedException(`Formatter ${formatter} not found`) + } + + return new Formatter().format(message, options) +} diff --git a/src/utils/global.ts b/src/utils/global.ts index f457081..9bcc768 100644 --- a/src/utils/global.ts +++ b/src/utils/global.ts @@ -1,27 +1,30 @@ -import { Log } from '../Logger/Log' -import { Logger } from '../Logger/Logger' -import { LogMapper } from '../Logger/LogMapper' -import { DebugFormatter } from '../Formatters/DebugFormatter' -import { DebugTransporter } from '../Transporters/DebugTransporter' +import { DriverContract } from '../Contracts/DriverContract' +import { FormatterContract } from '../Contracts/FormatterContract' export {} declare global { - function Debug(message: any, namespace?: string, context?: string): void - function Log(message: any, formatterOpts?: any, transporterOpts?: any): void + class Log { + static buildDriver(name: string, driver: DriverContract): typeof Log + static buildFormatter( + name: string, + formatter: FormatterContract, + ): typeof Log + + static get drivers(): string[] + static get formatters(): string[] + static channel(channel: string): typeof Log + static channels(...channels: string[]): typeof Log + + static log(message: any, options?: any) + static info(message: any, options?: any) + static warn(message: any, options?: any) + static error(message: any, options?: any) + static debug(message: any, options?: any) + static success(message: any, options?: any) + } } const _global = global as any -const debug = new Logger().debug.bind({ - context: 'Debugger', - mapper: new LogMapper([new DebugFormatter()], [new DebugTransporter()]), -}) _global.Log = Log -_global.Debug = ( - message: any, - namespace = 'api:main', - context = 'Debug', -): void => { - debug(message, { context }, { namespace }) -}