diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index efe30208..aedc5657 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,7 +83,7 @@ jobs: - name: Verify types if: matrix.node-version == env.PRIMARY_NODE_VERSION && matrix.os == env.PRIMARY_OS - run: yarn run compile + run: yarn run build - name: Run unit tests with coverage if: matrix.node-version == env.PRIMARY_NODE_VERSION && matrix.os == env.PRIMARY_OS diff --git a/.gitignore b/.gitignore index b8df45de..1e4035e6 100755 --- a/.gitignore +++ b/.gitignore @@ -71,4 +71,5 @@ typings/ # stryker temp files .stryker-tmp /reports +!@types/** !/tools diff --git a/@types/consola/index.d.ts b/@types/consola/index.d.ts new file mode 100644 index 00000000..4fae9db1 --- /dev/null +++ b/@types/consola/index.d.ts @@ -0,0 +1,23 @@ +import { ConsolaLogObject, ConsolaReporter, ConsolaReporterArgs } from 'consola'; +import { InspectOptions } from 'util'; +import { ForegroundColor } from 'chalk'; + +declare module 'consola' { + type Color = typeof ForegroundColor; + + export interface ReporterOptions { + dateFormat?: string; + formatOptions?: InspectOptions; + secondaryColor?: Color; + } + + export class FancyReporter implements ConsolaReporter { + protected options: ReporterOptions; + + constructor(options?: ReporterOptions); + + public log(logObj: ConsolaLogObject, args: ConsolaReporterArgs): void; + + protected formatType(logObj: ConsolaLogObject): string; + } +} diff --git a/package.json b/package.json index 805f705d..f0ac40cd 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,11 @@ "type": "git", "url": "git+https://github.com/PruvoNet/node-upgrade-checker.git" }, + "os": [ + "darwin", + "linux", + "win32" + ], "main": "dist/index.js", "types": "dist/index.d.ts", "bin": { diff --git a/src/container/utils.ts b/src/container/utils.ts index e04b5d6d..77bb1923 100644 --- a/src/container/utils.ts +++ b/src/container/utils.ts @@ -4,7 +4,7 @@ import Abstract = interfaces.Abstract; export type Constraint = (request: Request) => boolean; -export const namedOrMultiConstraint = (symbol: symbol, target: Abstract): Constraint => { +export const namedOrMultiConstraint = (symbol: symbol, target: Abstract): Constraint => { const tagConstraint = namedConstraint(symbol); const multiInjectConstraint = taggedConstraint(METADATA_KEY.MULTI_INJECT_TAG)(target); return (request: Request): boolean => { diff --git a/src/resolvers/ciResolver/impl/resolvers/appveyor/appVeyorConfigParser.ts b/src/resolvers/ciResolver/impl/resolvers/appveyor/appVeyorConfigParser.ts index 92d47565..ed626279 100644 --- a/src/resolvers/ciResolver/impl/resolvers/appveyor/appVeyorConfigParser.ts +++ b/src/resolvers/ciResolver/impl/resolvers/appveyor/appVeyorConfigParser.ts @@ -54,7 +54,7 @@ const sorter: NodeSorter = (a: INode, b: INode) => { }; export interface IAppVeyorConfigParserOptions { - config: Record; + config: Record; } const coerceString = (o: Record): Record => { diff --git a/src/resolvers/ciResolver/impl/resolvers/circleci/circleCiConfigParser.ts b/src/resolvers/ciResolver/impl/resolvers/circleci/circleCiConfigParser.ts index c427d998..dee34dc7 100644 --- a/src/resolvers/ciResolver/impl/resolvers/circleci/circleCiConfigParser.ts +++ b/src/resolvers/ciResolver/impl/resolvers/circleci/circleCiConfigParser.ts @@ -14,7 +14,7 @@ const nodeVersionRegex = /node:([^-.]+)-?/i; type Matrix = Record; export interface ICircleCiConfigParserOptions { - config: Record; + config: Record; } const isVersionNode = (value: unknown, node: INode): value is string => { diff --git a/src/resolvers/ciResolver/impl/resolvers/githubActions/githubActionsConfigParser.ts b/src/resolvers/ciResolver/impl/resolvers/githubActions/githubActionsConfigParser.ts index 63442fd7..ee732a77 100644 --- a/src/resolvers/ciResolver/impl/resolvers/githubActions/githubActionsConfigParser.ts +++ b/src/resolvers/ciResolver/impl/resolvers/githubActions/githubActionsConfigParser.ts @@ -37,12 +37,12 @@ const sorter: NodeSorter = (a: INode, b: INode) => { return keySorter(a, b); }; -const isStringOrNumberArray = (x: any): x is StringOrNumber[] => { +const isStringOrNumberArray = (x: unknown): x is StringOrNumber[] => { return is(Array)(x) && x.every(isStringOrNumber); }; export interface IGithubActionsConfigParserOptions { - config: Record; + config: Record; } const isEnvNode = (value: unknown, node: INode): value is StringOrNumber => { diff --git a/src/resolvers/ciResolver/impl/resolvers/travisci/travisCiConfigParser.ts b/src/resolvers/ciResolver/impl/resolvers/travisci/travisCiConfigParser.ts index 260ff417..13409122 100644 --- a/src/resolvers/ciResolver/impl/resolvers/travisci/travisCiConfigParser.ts +++ b/src/resolvers/ciResolver/impl/resolvers/travisci/travisCiConfigParser.ts @@ -19,7 +19,7 @@ const yargsOptions: Options = { }; export interface ICircleCiConfigParserOptions { - config: Record; + config: Record; } const ltsRegex = new RegExp(`lts/(.+)`, `i`); diff --git a/src/utils/logger/impl/logReporter.ts b/src/utils/logger/impl/logReporter.ts index bfefcba6..c5b7f250 100644 --- a/src/utils/logger/impl/logReporter.ts +++ b/src/utils/logger/impl/logReporter.ts @@ -1,54 +1,59 @@ -// @ts-ignore -import { ConsolaLogObject, ConsolaReporter, ConsolaReporterArgs, FancyReporter } from 'consola'; +import { ConsolaLogObject, ConsolaReporter, FancyReporter, ReporterOptions } from 'consola'; import chalk = require('chalk'); import * as figures from 'figures'; +import type { Chalk, BackgroundColor, ForegroundColor } from 'chalk'; +import { Nullable } from 'Union/Nullable'; +import { isNumber } from 'ts-type-guards'; -const bgColorCache: any = {}; +const bgColorCache: Record = {}; -const chalkBgColor = (name: string): any => { - let color = bgColorCache[name]; - if (color) { - return color; +const chalkBgColor = (name: BGColor): Chalk => { + if (!bgColorCache[name]) { + bgColorCache[name] = chalk[name]; } - // @ts-ignore - color = chalk[`bg${name[0].toUpperCase()}${name.slice(1)}`]; - bgColorCache[name] = color; - return color; + return bgColorCache[name]; }; -const LEVEL_COLOR_MAP = { - 0: `red`, - 1: `yellow`, - 2: `white`, - 3: `green`, +const LEVEL_COLOR_MAP: Record> = { + 0: `bgRed`, + 1: `bgYellow`, + 2: `bgWhite`, + 3: `bgGreen`, }; -const TYPE_COLOR_MAP = { - info: `blue`, +const TYPE_COLOR_MAP: Record> = { + info: `bgBlue`, }; -const TYPE_ICONS = { +const TYPE_ICONS: Record> = { info: figures(`ℹ`), success: figures(`✔`), error: figures(`✖`), warn: figures(`Ⓘ`), }; +export type BGColor = typeof BackgroundColor; +export type Color = typeof ForegroundColor; + +export interface LogReporterOptions extends ReporterOptions { + secondaryColor: Color; + bgColor: BGColor; +} + export class LogReporter extends FancyReporter implements ConsolaReporter { - constructor(options?: any) { + private bgColor: BGColor; + constructor(options: LogReporterOptions) { super(options); + this.bgColor = options.bgColor; } - protected formatType(logObj: any): string { - // @ts-ignore - const typeColor = TYPE_COLOR_MAP[logObj.type] || LEVEL_COLOR_MAP[logObj.level] || this.options.secondaryColor; - // @ts-ignore - const typeIcon = TYPE_ICONS[logObj.type]; - const text = ` ${typeIcon || logObj.type.toUpperCase()} `; + protected formatType(logObj: ConsolaLogObject): string { + const typeColor = + (logObj.type && TYPE_COLOR_MAP[logObj.type]) || + (isNumber(logObj.level) && LEVEL_COLOR_MAP[logObj.level]) || + this.bgColor; + const typeIcon = logObj.type && TYPE_ICONS[logObj.type]; + const text = ` ${typeIcon || (logObj.type && logObj.type.toUpperCase())} `; return chalkBgColor(typeColor).black(text); } - - public log(logObj: ConsolaLogObject, args: ConsolaReporterArgs): void { - super.log(logObj, args); - } } diff --git a/src/utils/logger/impl/loggerFactory.ts b/src/utils/logger/impl/loggerFactory.ts index 6ae5d5d8..192b908c 100644 --- a/src/utils/logger/impl/loggerFactory.ts +++ b/src/utils/logger/impl/loggerFactory.ts @@ -18,7 +18,12 @@ export class LoggerFactory extends ILoggerFactory { const level = isTrace ? LogLevel.TRACE : isDebug ? LogLevel.DEBUG : LogLevel.INFO; this.options = { level, - reporters: [new LogReporter()], + reporters: [ + new LogReporter({ + secondaryColor: `grey`, + bgColor: `bgGrey`, + }), + ], }; } diff --git a/src/utils/logger/interfaces/ILogger.ts b/src/utils/logger/interfaces/ILogger.ts index 40e8e4b2..36ff0702 100644 --- a/src/utils/logger/interfaces/ILogger.ts +++ b/src/utils/logger/interfaces/ILogger.ts @@ -8,21 +8,21 @@ export enum LogLevel { } export interface ILogger { - fatal(...args: any[]): void; + fatal(...args: unknown[]): void; - error(...args: any[]): void; + error(...args: unknown[]): void; - warn(...args: any[]): void; + warn(...args: unknown[]): void; - log(...args: any[]): void; + log(...args: unknown[]): void; - info(...args: any[]): void; + info(...args: unknown[]): void; - success(...args: any[]): void; + success(...args: unknown[]): void; - debug(...args: any[]): void; + debug(...args: unknown[]): void; - trace(...args: any[]): void; + trace(...args: unknown[]): void; isDebugEnabled(): boolean; isTraceEnabled(): boolean; diff --git a/src/utils/packageInfo/impl/packageInfo.ts b/src/utils/packageInfo/impl/packageInfo.ts index a874b185..b54e5e5f 100644 --- a/src/utils/packageInfo/impl/packageInfo.ts +++ b/src/utils/packageInfo/impl/packageInfo.ts @@ -21,7 +21,7 @@ export class PackageInfo extends IPackageInfo { this.logger.debug(`Got package information of ${name}@${semver}`); const version = result.version; const engines = result.engines?.node; - const repoUrl = (result.repository as any)?.url; + const repoUrl = result.repository?.url; const commitSha = result.gitHead as string; return { name, diff --git a/src/utils/types/typeGuards.ts b/src/utils/types/typeGuards.ts index d60bb062..c351c266 100644 --- a/src/utils/types/typeGuards.ts +++ b/src/utils/types/typeGuards.ts @@ -1,6 +1,6 @@ import { isNumber, isString } from 'ts-type-guards'; import { StringOrNumber } from './types'; -export const isStringOrNumber = (x: any): x is StringOrNumber => { +export const isStringOrNumber = (x: unknown): x is StringOrNumber => { return isString(x) || isNumber(x); }; diff --git a/test/src/utils/logger/impl/logReporter.spec.ts b/test/src/utils/logger/impl/logReporter.spec.ts index c10085fd..db4aba00 100644 --- a/test/src/utils/logger/impl/logReporter.spec.ts +++ b/test/src/utils/logger/impl/logReporter.spec.ts @@ -3,22 +3,41 @@ import { PassThrough } from 'stream'; import * as chalk from 'chalk'; import * as figures from 'figures'; +interface MockedStream { + mockedStream: PassThrough; + streamPromise: Promise; + closeStream: () => void; +} + +const getMockedStream = (): MockedStream => { + const mockedStream = new PassThrough(); + const streamPromise = new Promise((resolve) => { + const logData: Uint8Array[] = []; + mockedStream.on(`data`, (data) => { + logData.push(data); + }); + mockedStream.on(`end`, () => { + resolve(Buffer.concat(logData).toString()); + }); + }); + return { + mockedStream, + streamPromise, + closeStream: (): void => { + mockedStream.end(); + mockedStream.destroy(); + }, + }; +}; + describe(`log reporter`, () => { const logReporter = new LogReporter({ secondaryColor: `grey`, + bgColor: `bgGrey`, }); it(`should log ERROR properly`, async () => { - const mockedStream = new PassThrough(); - const streamPromise = new Promise((resolve) => { - const logData: Uint8Array[] = []; - mockedStream.on(`data`, (data) => { - logData.push(data); - }); - mockedStream.on(`end`, () => { - resolve(Buffer.concat(logData).toString()); - }); - }); + const { mockedStream, streamPromise, closeStream } = getMockedStream(); logReporter.log( { level: 0, @@ -31,8 +50,7 @@ describe(`log reporter`, () => { stdout: mockedStream, } ); - mockedStream.end(); - mockedStream.destroy(); + closeStream(); const result = await streamPromise; const expected = ` ${chalk.bgRed.black(` ` + figures(`✖`) + ` `)} my message @@ -42,16 +60,7 @@ ${chalk.bgRed.black(` ` + figures(`✖`) + ` `)} my message }); it(`should log WARN properly`, async () => { - const mockedStream = new PassThrough(); - const streamPromise = new Promise((resolve) => { - const logData: Uint8Array[] = []; - mockedStream.on(`data`, (data) => { - logData.push(data); - }); - mockedStream.on(`end`, () => { - resolve(Buffer.concat(logData).toString()); - }); - }); + const { mockedStream, streamPromise, closeStream } = getMockedStream(); logReporter.log( { level: 1, @@ -64,8 +73,7 @@ ${chalk.bgRed.black(` ` + figures(`✖`) + ` `)} my message stdout: mockedStream, } ); - mockedStream.end(); - mockedStream.destroy(); + closeStream(); const result = await streamPromise; const expected = ` ${chalk.bgYellow.black(` ` + figures(`Ⓘ`) + ` `)} my message @@ -75,16 +83,7 @@ ${chalk.bgYellow.black(` ` + figures(`Ⓘ`) + ` `)} my message }); it(`should log LOG properly`, async () => { - const mockedStream = new PassThrough(); - const streamPromise = new Promise((resolve) => { - const logData: Uint8Array[] = []; - mockedStream.on(`data`, (data) => { - logData.push(data); - }); - mockedStream.on(`end`, () => { - resolve(Buffer.concat(logData).toString()); - }); - }); + const { mockedStream, streamPromise, closeStream } = getMockedStream(); logReporter.log( { level: 2, @@ -97,8 +96,7 @@ ${chalk.bgYellow.black(` ` + figures(`Ⓘ`) + ` `)} my message stdout: mockedStream, } ); - mockedStream.end(); - mockedStream.destroy(); + closeStream(); const result = await streamPromise; const expected = `${chalk.bgWhite.black(` LOG `)} my message `; @@ -106,16 +104,7 @@ ${chalk.bgYellow.black(` ` + figures(`Ⓘ`) + ` `)} my message }); it(`should log INFO properly`, async () => { - const mockedStream = new PassThrough(); - const streamPromise = new Promise((resolve) => { - const logData: Uint8Array[] = []; - mockedStream.on(`data`, (data) => { - logData.push(data); - }); - mockedStream.on(`end`, () => { - resolve(Buffer.concat(logData).toString()); - }); - }); + const { mockedStream, streamPromise, closeStream } = getMockedStream(); logReporter.log( { level: 3, @@ -128,8 +117,7 @@ ${chalk.bgYellow.black(` ` + figures(`Ⓘ`) + ` `)} my message stdout: mockedStream, } ); - mockedStream.end(); - mockedStream.destroy(); + closeStream(); const result = await streamPromise; const expected = `${chalk.bgBlue.black(` ` + figures(`ℹ`) + ` `)} my message `; @@ -137,16 +125,7 @@ ${chalk.bgYellow.black(` ` + figures(`Ⓘ`) + ` `)} my message }); it(`should log DEBUG properly`, async () => { - const mockedStream = new PassThrough(); - const streamPromise = new Promise((resolve) => { - const logData: Uint8Array[] = []; - mockedStream.on(`data`, (data) => { - logData.push(data); - }); - mockedStream.on(`end`, () => { - resolve(Buffer.concat(logData).toString()); - }); - }); + const { mockedStream, streamPromise, closeStream } = getMockedStream(); logReporter.log( { level: 4, @@ -159,8 +138,7 @@ ${chalk.bgYellow.black(` ` + figures(`Ⓘ`) + ` `)} my message stdout: mockedStream, } ); - mockedStream.end(); - mockedStream.destroy(); + closeStream(); const result = await streamPromise; const expected = `${chalk.bgGrey.black(` DEBUG `)} my message `; @@ -168,16 +146,7 @@ ${chalk.bgYellow.black(` ` + figures(`Ⓘ`) + ` `)} my message }); it(`should log TRACE properly`, async () => { - const mockedStream = new PassThrough(); - const streamPromise = new Promise((resolve) => { - const logData: Uint8Array[] = []; - mockedStream.on(`data`, (data) => { - logData.push(data); - }); - mockedStream.on(`end`, () => { - resolve(Buffer.concat(logData).toString()); - }); - }); + const { mockedStream, streamPromise, closeStream } = getMockedStream(); logReporter.log( { level: 5, @@ -190,8 +159,7 @@ ${chalk.bgYellow.black(` ` + figures(`Ⓘ`) + ` `)} my message stdout: mockedStream, } ); - mockedStream.end(); - mockedStream.destroy(); + closeStream(); const result = await streamPromise; const expected = `${chalk.bgGrey.black(` TRACE `)} my message `; diff --git a/tsconfig.build.json b/tsconfig.build.json index 0af4c9fb..2eaac29a 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -6,5 +6,5 @@ "declaration": true, "outDir": "dist" }, - "include": ["src"] + "include": ["src", "@types/**/*.d.ts"] } diff --git a/tsconfig.json b/tsconfig.json index 402cd388..d9da0344 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,5 +27,5 @@ "experimentalDecorators": true, "emitDecoratorMetadata": true }, - "include": ["src", "test", "testE2E", "testInteg", "tools"] + "include": ["src", "test", "testE2E", "testInteg", "tools", "@types/**/*.d.ts"] }