diff --git a/libs/external/logger/.eslintrc.json b/libs/external/logger/.eslintrc.json new file mode 100644 index 0000000..3456be9 --- /dev/null +++ b/libs/external/logger/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/external/logger/README.md b/libs/external/logger/README.md new file mode 100644 index 0000000..671f265 --- /dev/null +++ b/libs/external/logger/README.md @@ -0,0 +1,11 @@ +# logger + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build logger` to build the library. + +## Running unit tests + +Run `nx test logger` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/external/logger/jest.config.ts b/libs/external/logger/jest.config.ts new file mode 100644 index 0000000..80dd908 --- /dev/null +++ b/libs/external/logger/jest.config.ts @@ -0,0 +1,14 @@ +/* eslint-disable */ +export default { + displayName: 'logger', + preset: '../../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': [ + 'ts-jest', + { tsconfig: '/tsconfig.spec.json' }, + ], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../coverage/libs/external/logger', +} diff --git a/libs/external/logger/package.json b/libs/external/logger/package.json new file mode 100644 index 0000000..389fb5f --- /dev/null +++ b/libs/external/logger/package.json @@ -0,0 +1,4 @@ +{ + "name": "@tematools/logger", + "version": "0.0.1" +} diff --git a/libs/external/logger/project.json b/libs/external/logger/project.json new file mode 100644 index 0000000..ca74133 --- /dev/null +++ b/libs/external/logger/project.json @@ -0,0 +1,51 @@ +{ + "name": "logger", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/external/logger/src", + "projectType": "library", + "targets": { + "build": { + "clean": true, + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/libs/external/logger", + "main": "libs/external/logger/src/index.ts", + "tsConfig": "libs/external/logger/tsconfig.lib.json", + "assets": ["libs/external/logger/*.md"] + } + }, + "publish": { + "dependsOn": ["build"], + "command": "node tools/scripts/publish.mjs logger {args.ver} {args.tag}" + }, + "version": { + "executor": "@jscutlery/semver:version", + "options": { + "push": true + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["libs/external/logger/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/external/logger/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "tags": [] +} diff --git a/libs/external/logger/src/index.ts b/libs/external/logger/src/index.ts new file mode 100644 index 0000000..0445a7f --- /dev/null +++ b/libs/external/logger/src/index.ts @@ -0,0 +1,2 @@ +export * from './lib/logger' +export * from './lib/logger-interfaces/logger.interfaces' diff --git a/libs/external/logger/src/lib/logger-core.ts b/libs/external/logger/src/lib/logger-core.ts new file mode 100644 index 0000000..b5951fb --- /dev/null +++ b/libs/external/logger/src/lib/logger-core.ts @@ -0,0 +1,272 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { LogLevel } from '@nestjs/common' +import chalk from 'chalk' +import { get } from 'env-var' +import { isMatch } from 'micromatch' +import { performance } from 'perf_hooks' + +import { + DefaultLog, + JsonLog, + LoggerConfig, + LoggerInterface, + LogMethodOptions, +} from './logger-interfaces/logger.interfaces' +import { clc } from './logger-utils/cli-colors.util' +import { isPlainObject } from './logger-utils/utils' + +const isProduction = get('NOVE_ENV').asString() === 'production' + +const JSON_SPACE = 2 + +export class LoggerCore implements LoggerInterface { + private _timers: Map = new Map() + + _config: LoggerConfig = { + labels: ['*'], + colors: { + timestamp: '#E5E5E5', + label: '#E5E5E5', + }, + } + + log(message: any, options?: LogMethodOptions): void + log(message: any, ...optionalParams: [...any, string?]): void + log(message: any, ...optionalParams: any[]): void { + const options = this._findOptions(optionalParams) + this._printMessage(message, options, 'log') + } + + error(message: any, options?: LogMethodOptions, stack?: string): void + error(message: any, ...optionalParams: [...any, string?, string?]): void + error(message: any, ...optionalParams: any[]): void { + const { options, stack } = this._findOptionsAndStack(optionalParams) + this._printMessage(message, options, 'error', 'stderr', stack) + } + + warn(message: any, options?: LogMethodOptions): void + warn(message: any, ...optionalParams: [...any, string?]): void + warn(message: any, ...optionalParams: any[]): void { + const options = this._findOptions(optionalParams) + this._printMessage(message, options, 'warn') + } + + debug(message: any, options?: LogMethodOptions): void + debug(message: any, ...optionalParams: [...any, string?]): void + debug(message: any, ...optionalParams: any[]): void { + if (isProduction) { + return + } + + const options = this._findOptions(optionalParams) + this._printMessage(message, options, 'debug') + } + + verbose(message: any, options?: LogMethodOptions): void + verbose(message: any, ...optionalParams: [...any, string?]): void + verbose(message: any, ...optionalParams: any[]): void { + const options = this._findOptions(optionalParams) + this._printMessage(message, options, 'verbose') + } + + markTime(marker: string): void { + this._timers.set(marker, performance.now()) + } + + measureTime( + marker: string, + message?: string, + options?: LogMethodOptions, + ): number { + const timeStart = this._timers.get(marker) + + if (timeStart === undefined) { + return 0 + } + + const time = performance.now() - timeStart + + if (message) { + const formattedMessage = message.replace( + RegExp('{n}'), + `${time.toFixed(3)}`, + ) + + const foundOptions = this._findOptions([options]) + this._printMessage(formattedMessage, foundOptions, 'timer') + } + + return time + } + + private _getTimestamp(): string { + const time = new Date().toISOString() + + // 2021-09-24T05:10:47.306Z => 2021-09-24 05:10:47 + return `[${`${time.substr(0, 10)} ${time.substr(11, 12)}`}]` + } + + private _printMessage( + message: any, + options: LogMethodOptions, + logLevel: LogLevel, + writeStreamType?: 'stdout' | 'stderr', + stack?: string, + ): void { + const { label } = options + + if (label && !this._isLabelAllowed(label)) { + return + } + + let computedMessage = '' + + const { json } = this._config + + if (json) { + computedMessage = this._createJsonLog({ + message, + label, + level: logLevel, + stack, + }) + } else { + computedMessage = this._createDefaultLog({ + message, + label, + level: logLevel, + stack, + }) + } + + process[writeStreamType ?? 'stdout'].write(computedMessage) + } + + private _createJsonLog(data: JsonLog): string { + const { message, level, label, stack } = data + + return `\n${JSON.stringify({ + timestamp: new Date().toISOString(), + message: isPlainObject(message) + ? JSON.stringify(message, (key, value) => + typeof value === 'bigint' ? value.toString() : value, + ) + : (message as string), + level, + label, + stack, + })}` + } + + private _createDefaultLog(data: DefaultLog): string { + const { message, level, label, stack } = data + const { colors } = this._config + + const color = this._getColorByLogLevel(level) + + const output = isPlainObject(message) + ? ` Object:\n${JSON.stringify( + message, + (key, value) => + typeof value === 'bigint' ? value.toString() : value, + JSON_SPACE, + )}` + : ` ${message as string}` + + const timestamp = chalk.hex(colors!.timestamp!)(this._getTimestamp()) + const labelMessage = label + ? chalk.hex(colors!.label!)(' [' + label + ']') + : '' + const formattedLogLevel = color(level.toUpperCase().padStart(8)) + const stackMessage = stack ? `\n${stack}` : '' + + const coloredOutput = colors!.message + ? chalk.hex(colors!.message)(output) + : output + const coloredStack = colors!.stack + ? chalk.hex(colors!.stack)(stackMessage) + : stackMessage + + const finalMessage = + timestamp + + formattedLogLevel + + labelMessage + + coloredOutput + + coloredStack + + '\n' + + return finalMessage + } + + private _findOptions(args: unknown[]): LogMethodOptions { + const options = args.find( + (arg: any) => + typeof arg === 'object' && ('trace' in arg || 'label' in arg), + ) + + if (!options) { + return {} + } + + return options + } + + private _findOptionsAndStack(args: unknown[]): { + options: LogMethodOptions + stack?: string + } { + const options = args.find( + (arg: any) => + typeof arg === 'object' && ('trace' in arg || 'label' in arg), + ) as LogMethodOptions + + const stacktraceRegex = new RegExp(/at /g) + + const stack = args.find( + (arg) => typeof arg === 'string' && stacktraceRegex.test(arg), + ) as string + + if (!options) { + return { + stack, + options: {}, + } + } + + return { + options, + stack, + } + } + + private _isLabelAllowed(label: string): boolean { + const { labels } = this._config + + if (labels === undefined) { + return true + } + + if (labels === false) { + return false + } + + return isMatch(label, labels) + } + + private _getColorByLogLevel(level: LogLevel): (text: string) => string { + switch (level) { + case 'debug': + return clc.magentaBright + case 'warn': + return clc.yellow + case 'error': + return clc.red + case 'verbose': + return clc.cyanBright + case 'timer': + return clc.lightGreen + default: + return clc.green + } + } +} diff --git a/libs/external/logger/src/lib/logger-interfaces/logger.interfaces.ts b/libs/external/logger/src/lib/logger-interfaces/logger.interfaces.ts new file mode 100644 index 0000000..f8eff12 --- /dev/null +++ b/libs/external/logger/src/lib/logger-interfaces/logger.interfaces.ts @@ -0,0 +1,53 @@ +export interface DefaultLog { + message: string + level: LogLevel + label?: string + stack?: string +} + +export interface JsonLog { + message: string + level: string + label?: string + stack?: string +} + +export interface LogMethodOptions { + label?: string +} + +/* eslint-disable @typescript-eslint/no-explicit-any */ +export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose' | 'timer' + +/** + * Logger interface from NestJS + * https://github.com/nestjs/nest/blob/master/packages/common/services/logger.service.ts + */ +export interface LoggerInterface { + log(message: any, ...optionalParams: any[]): any + error(message: any, ...optionalParams: any[]): any + warn(message: any, ...optionalParams: any[]): any + debug?(message: any, ...optionalParams: any[]): any + verbose?(message: any, ...optionalParams: any[]): any + setLogLevels?(levels: LogLevel[]): any +} + +export interface LoggerConfig { + /** + * Put labels with will be show in console + * @notice Default: `*` + */ + labels?: string | string[] | false + + /** + * @notice Default: `false` + */ + json?: boolean + + colors?: { + timestamp?: string + label?: string + message?: string + stack?: string + } +} diff --git a/libs/external/logger/src/lib/logger-utils/cli-colors.util.ts b/libs/external/logger/src/lib/logger-utils/cli-colors.util.ts new file mode 100644 index 0000000..8aace69 --- /dev/null +++ b/libs/external/logger/src/lib/logger-utils/cli-colors.util.ts @@ -0,0 +1,21 @@ +type ColorTextFn = (text: string) => string + +const isColorAllowed = (): boolean => !process.env.NO_COLOR + +const colorIfAllowed = + (colorFn: ColorTextFn) => + (text: string): string => + isColorAllowed() ? colorFn(text) : text + +export const clc = { + green: colorIfAllowed((text: string) => `\x1B[32m${text}\x1B[39m`), + yellow: colorIfAllowed((text: string) => `\x1B[33m${text}\x1B[39m`), + red: colorIfAllowed((text: string) => `\x1B[31m${text}\x1B[39m`), + magentaBright: colorIfAllowed((text: string) => `\x1B[95m${text}\x1B[39m`), + cyanBright: colorIfAllowed((text: string) => `\x1B[96m${text}\x1B[39m`), + lightGreen: colorIfAllowed((text: string) => `\x1B[92m${text}\x1B[39m`), +} + +export const yellow = colorIfAllowed( + (text: string) => `\x1B[38;5;3m${text}\x1B[39m`, +) diff --git a/libs/external/logger/src/lib/logger-utils/colorize-context.util.ts b/libs/external/logger/src/lib/logger-utils/colorize-context.util.ts new file mode 100644 index 0000000..0eaaac6 --- /dev/null +++ b/libs/external/logger/src/lib/logger-utils/colorize-context.util.ts @@ -0,0 +1,49 @@ +/* eslint-disable */ +import chalk from 'chalk' + +const CONTEXT_COLOR_CACHE: { [context: string]: number | undefined } = {} +const CONTEXT_COLOR_CACHE_SIZE = 10 + +export const colorizeContext: (context: string, text: string) => string = chalk + .bold?.ansi256 + ? (context: string, text: string) => + chalk.bold.ansi256(getContextColor(context))(text) + : chalk.ansi256 + ? (context: string, text: string) => + chalk.ansi256(getContextColor(context))(text) + : (context: string, text: string) => text + +function selectColor(namespace: string): number { + let hash = 0 + + for (let i = 0; i < namespace.length; i++) { + hash = (hash << 5) - hash + namespace.charCodeAt(i) + hash |= 0 // Convert to 32bit integer + } + + return DEBUG_COLORS[Math.abs(hash) % DEBUG_COLORS.length] +} + +function getContextColor(context: string): number { + let color = CONTEXT_COLOR_CACHE[context] + if (color !== undefined) { + return color + } + const keys = Object.keys(CONTEXT_COLOR_CACHE) + + if (keys.length > CONTEXT_COLOR_CACHE_SIZE - 1) { + keys.splice(0, keys.length - CONTEXT_COLOR_CACHE_SIZE + 1).forEach( + (key) => delete CONTEXT_COLOR_CACHE[key], + ) + } + CONTEXT_COLOR_CACHE[context] = color = selectColor(context) + return color +} + +const DEBUG_COLORS = [ + 20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68, + 69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134, + 135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 214, 215, 220, 221, +] diff --git a/libs/external/logger/src/lib/logger-utils/utils.ts b/libs/external/logger/src/lib/logger-utils/utils.ts new file mode 100644 index 0000000..f92adea --- /dev/null +++ b/libs/external/logger/src/lib/logger-utils/utils.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/ban-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +export const isUndefined = (obj: any): obj is undefined => + typeof obj === 'undefined' + +export const isObject = (fn: any): fn is object => + !isNil(fn) && typeof fn === 'object' + +export const isNil = (obj: any): obj is null | undefined => + isUndefined(obj) || obj === null + +export const isPlainObject = (fn: any): fn is object => { + if (!isObject(fn)) { + return false + } + + const proto = Object.getPrototypeOf(fn) + if (proto === null) { + return true + } + + const ctor = + Object.prototype.hasOwnProperty.call(proto, 'constructor') && + proto.constructor + + return ( + typeof ctor === 'function' && + ctor instanceof ctor && + Function.prototype.toString.call(ctor) === + Function.prototype.toString.call(Object) + ) +} + +/** + * Deep merge two objects. + * @param target + * @param ...sources + */ +export function mergeDeep(target, ...sources) { + if (!sources.length) return target + const source = sources.shift() + + if (isObject(target) && isObject(source)) { + for (const key in source) { + if (isObject(source[key])) { + if (!target[key]) Object.assign(target, { [key]: {} }) + mergeDeep(target[key], source[key]) + } else { + Object.assign(target, { [key]: source[key] }) + } + } + } + + return mergeDeep(target, ...sources) +} diff --git a/libs/external/logger/src/lib/logger.ts b/libs/external/logger/src/lib/logger.ts new file mode 100644 index 0000000..21599af --- /dev/null +++ b/libs/external/logger/src/lib/logger.ts @@ -0,0 +1,95 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types*/ +import { LoggerCore } from './logger-core' +import { + LoggerConfig, + LogMethodOptions, +} from './logger-interfaces/logger.interfaces' +import { mergeDeep } from './logger-utils/utils' + +export class Logger { + private static _instance: LoggerCore + + private get _instance(): LoggerCore { + if (!Logger._instance) { + Logger._instance = new LoggerCore() + } + + return Logger._instance + } + + configure(config: LoggerConfig): void { + if (Object.keys(config).length === 0) { + return + } + + this._instance._config = mergeDeep(this._instance._config, config) + } + + log(message: any, options?: LogMethodOptions): void + log(message: any, ...optionalParams: [...any, string?]): void + log(message: any, ...optionalParams: any[]): void { + this._instance.log(message, ...optionalParams) + } + + error(message: any, options?: LogMethodOptions): void + error(message: any, ...optionalParams: [...any, string?, string?]): void + error(message: any, ...optionalParams: any[]): void { + this._instance.error(message, ...optionalParams) + } + + warn(message: any, options?: LogMethodOptions): void + warn(message: any, ...optionalParams: [...any, string?]): void + warn(message: any, ...optionalParams: any[]): void { + this._instance.warn(message, ...optionalParams) + } + + debug(message: any, options?: LogMethodOptions): void + debug(message: any, ...optionalParams: [...any, string?]): void + debug(message: any, ...optionalParams: any[]): void { + this._instance.debug(message, ...optionalParams) + } + + verbose(message: any, options?: LogMethodOptions): void + verbose(message: any, ...optionalParams: [...any, string?]): void + verbose(message: any, ...optionalParams: any[]): void { + this._instance.verbose(message, ...optionalParams) + } + + /** + * Set a marker for time calculation + * + * @param marker Marker name + */ + markTime(marker: string): void { + this._instance.markTime(marker) + } + + /** + * Measure time that was marked by `markTime()`. Provide message if you want to log your time + * + * Example: + * ```ts + * logger.markTime('marker') + * + * // will return time result + * const time = logger.measureTime('marker') + * + * // will log message in the console and return time result + * logger.measureTime('marker', 'Function took {n} to be executed', { label: 'auth' }) + * ``` + * + * @param marker marker name + * @param message use {n} to paste time result + * @param options logger options + * + * @returns timer result in milliseconds + */ + measureTime( + marker: string, + message?: string, + options?: LogMethodOptions, + ): number { + return this._instance.measureTime(marker, message, options) + } +} diff --git a/libs/external/logger/tsconfig.json b/libs/external/logger/tsconfig.json new file mode 100644 index 0000000..25f7201 --- /dev/null +++ b/libs/external/logger/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs" + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/external/logger/tsconfig.lib.json b/libs/external/logger/tsconfig.lib.json new file mode 100644 index 0000000..6d18b27 --- /dev/null +++ b/libs/external/logger/tsconfig.lib.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": ["node"], + "target": "es6" + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/libs/external/logger/tsconfig.spec.json b/libs/external/logger/tsconfig.spec.json new file mode 100644 index 0000000..69a251f --- /dev/null +++ b/libs/external/logger/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/package-lock.json b/package-lock.json index a6e001a..facc95b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,16 +27,19 @@ "@tematools/nats": "^0.4.0", "axios": "^1.4.0", "bcrypt": "^5.1.0", + "chalk": "^4.1.2", "clsx": "^1.2.1", "env-var": "^7.3.1", "graphql": "^16.7.1", + "micromatch": "^4.0.5", + "nanoid": "^4.0.2", "nats": "^2.15.1", "nestjs-spelunker": "^1.1.5", "pg": "^8.11.1", "pg-promise": "^11.5.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", - "tslib": "^2.5.0" + "tslib": "^2.6.0" }, "devDependencies": { "@commitlint/cli": "^17.0.0", @@ -3490,6 +3493,11 @@ } } }, + "node_modules/@nestjs/apollo/node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, "node_modules/@nestjs/common": { "version": "9.4.3", "license": "MIT", @@ -3623,6 +3631,11 @@ "node": ">=8.6.0" } }, + "node_modules/@nestjs/graphql/node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, "node_modules/@nestjs/graphql/node_modules/uuid": { "version": "9.0.0", "license": "MIT", @@ -4182,6 +4195,15 @@ "tslib": "^2.3.0" } }, + "node_modules/@nx/jest/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/@nx/js": { "version": "16.5.0", "dev": true, @@ -4314,6 +4336,102 @@ "tslib": "^2.3.0" } }, + "node_modules/@nx/nx-darwin-arm64": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.5.0.tgz", + "integrity": "sha512-0+5FH3ot5o0lpL0OKD4fO2n0a6LqLxr0LwU2VYxaAR1GLzOeVE5W3jBWY9ztOE+ktm8mGaZsdIIOQ77Iz/xwsQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-darwin-x64": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.5.0.tgz", + "integrity": "sha512-yziX2oXUSyOPOcRLmFMRsNs0eBVla5IGjAKqpY4OXAPBuyrOfgsW5ztj0PQM34gvqipXtTlN04Xt/U0jzQLudA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-freebsd-x64": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.5.0.tgz", + "integrity": "sha512-hwIRRMyWrT2R4ozp6yXRNR1fwcclBlkkIQ51/1IzINPQxynMguuOvNZaJFD4OuZIDmI526++GmogPZc0aMzwkg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.5.0.tgz", + "integrity": "sha512-BEWLpBhJ2AcZNDsiExLDcM9kmQ4+E+0YUcOsrAeX1s5D4HXXVtHMdTmOucKs4NNFqMuJ2Cf3ZzqmAIkRug0beA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-gnu": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.5.0.tgz", + "integrity": "sha512-EWmTbDLbBIjM/OJ594hoFKsEka/b8jM6NehL37mlIXL6fixUEA8LlO0MfUQ+kIPg79nWIujzulkIEhYFDWM1WA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-musl": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.5.0.tgz", + "integrity": "sha512-np/7+HEtEEvtu4zo3GBBPtTG8IP++vvH3o8VXpAB9eD4Jctz3rYzbfMc7GtLZkz8LCmCsjzqnrNtmcmoaRbomQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nx/nx-linux-x64-gnu": { "version": "16.5.0", "cpu": [ @@ -4342,6 +4460,38 @@ "node": ">= 10" } }, + "node_modules/@nx/nx-win32-arm64-msvc": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.5.0.tgz", + "integrity": "sha512-u9cNKP8zrNIdeyaK5LHX+Zh+rkadE8tSE+vNulphCLhGuXJRpjaVY1juq9UQEo41NJQE6DuWWk2fnj4gALWugQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-x64-msvc": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.5.0.tgz", + "integrity": "sha512-E9109SAYNZXqCeWikZXyxNd7SZnCbdKGvqtQktS7dedHGwOmgIWfJ6bsvA7s2zHr09THQKJ4+7U1tDkWVNR9cg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nx/plugin": { "version": "16.5.0", "dev": true, @@ -4358,6 +4508,15 @@ "tslib": "^2.3.0" } }, + "node_modules/@nx/plugin/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/@nx/plugin/node_modules/fs-extra": { "version": "11.1.1", "dev": true, @@ -4419,6 +4578,15 @@ "webpack-subresource-integrity": "^5.1.0" } }, + "node_modules/@nx/webpack/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/@nx/workspace": { "version": "16.5.0", "dev": true, @@ -4446,6 +4614,15 @@ "yargs-parser": "21.1.1" } }, + "node_modules/@nx/workspace/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/@octokit/auth-token": { "version": "2.5.0", "dev": true, @@ -7072,7 +7249,8 @@ }, "node_modules/chalk": { "version": "4.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -8670,11 +8848,16 @@ } }, "node_modules/dotenv": { - "version": "10.0.0", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "dev": true, - "license": "BSD-2-Clause", + "peer": true, "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, "node_modules/duplexer": { @@ -13283,7 +13466,8 @@ }, "node_modules/micromatch": { "version": "4.0.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -13607,20 +13791,20 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.6", - "dev": true, + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz", + "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { - "nanoid": "bin/nanoid.cjs" + "nanoid": "bin/nanoid.js" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^14 || ^16 || >=18" } }, "node_modules/nats": { @@ -13977,6 +14161,15 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/nx-cloud/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/nx-cloud/node_modules/fs-extra": { "version": "11.1.1", "dev": true, @@ -13990,6 +14183,15 @@ "node": ">=14.14" } }, + "node_modules/nx/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/nx/node_modules/emoji-regex": { "version": "8.0.0", "dev": true, @@ -15254,6 +15456,24 @@ "dev": true, "license": "MIT" }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/postgres-array": { "version": "2.0.0", "license": "MIT", @@ -17636,8 +17856,9 @@ } }, "node_modules/tslib": { - "version": "2.5.0", - "license": "0BSD" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" }, "node_modules/tsscmp": { "version": "1.0.6", diff --git a/package.json b/package.json index 2676f31..956f4d2 100644 --- a/package.json +++ b/package.json @@ -35,16 +35,19 @@ "@tematools/nats": "^0.4.0", "axios": "^1.4.0", "bcrypt": "^5.1.0", + "chalk": "^4.1.2", "clsx": "^1.2.1", "env-var": "^7.3.1", "graphql": "^16.7.1", + "micromatch": "^4.0.5", + "nanoid": "^4.0.2", "nats": "^2.15.1", "nestjs-spelunker": "^1.1.5", "pg": "^8.11.1", "pg-promise": "^11.5.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", - "tslib": "^2.5.0" + "tslib": "^2.6.0" }, "devDependencies": { "@commitlint/cli": "^17.0.0", diff --git a/tsconfig.base.json b/tsconfig.base.json index a74efc6..c1f3e16 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -27,6 +27,7 @@ "libs/external/eventloop-frozen-detector/src/index.ts" ], "external/health-checks": ["libs/external/health-checks/src/index.ts"], + "external/logger": ["libs/external/logger/src/index.ts"], "external/nats": ["libs/external/nats/src/index.ts"], "external/schematics": ["libs/external/schematics/src/index.ts"], "sample": ["libs/sample/src/index.ts"]