diff --git a/bin/commands/execute.ts b/bin/commands/execute.ts index 0e6eb93..aa0873b 100644 --- a/bin/commands/execute.ts +++ b/bin/commands/execute.ts @@ -6,10 +6,12 @@ import { inspect } from "node:util"; // Import Third-party Dependencies import * as rc from "@nodesecure/rc"; -import kleur from "kleur"; // Import Internal Dependencies import { store } from "../../src/localStorage.ts"; +import * as utils from "../../src/utils/index.ts"; + +const { formatter } = utils; import { fetchPackagesAndRepositoriesData } from "../../src/analysis/fetch.ts"; import * as CONSTANTS from "../../src/constants.ts"; @@ -29,7 +31,7 @@ export async function execute(options: ExecuteOptions = {}) { const { debug: debugMode } = options; if (debugMode) { - console.log(kleur.bgMagenta().bold(" > Debug mode enabled \n")); + console.log(formatter.bgMagenta.bold(" > Debug mode enabled \n")); } const [configResult] = await Promise.all([ @@ -47,8 +49,8 @@ export async function execute(options: ExecuteOptions = {}) { throw new Error("At least one reporter must be selected (either 'HTML' or 'PDF')"); } - console.log(`>> title: ${kleur.cyan().bold(report.title)}`); - console.log(`>> reporters: ${kleur.magenta().bold(report.reporters.join(","))}\n`); + console.log(`>> title: ${formatter.cyan.bold(report.title)}`); + console.log(`>> reporters: ${formatter.magenta.bold(report.reporters.join(","))}\n`); store.run(config, async() => { try { @@ -57,7 +59,7 @@ export async function execute(options: ExecuteOptions = {}) { debug(data); } await reporting.proceed(data); - console.log(kleur.green().bold("\n>> Security report successfully generated! Enjoy 🚀.\n")); + console.log(formatter.green.bold("\n>> Security report successfully generated! Enjoy 🚀.\n")); } catch (error) { console.error(error); diff --git a/bin/commands/init.ts b/bin/commands/init.ts index 5cdd1c8..70f1135 100644 --- a/bin/commands/init.ts +++ b/bin/commands/init.ts @@ -1,6 +1,10 @@ // Import Third-party Dependencies import * as rc from "@nodesecure/rc"; -import kleur from "kleur"; + +// Import Internal Dependencies +import * as utils from "../../src/utils/index.ts"; + +const { formatter } = utils; export async function init() { const configLocation = process.cwd(); @@ -11,7 +15,7 @@ export async function init() { }); if (result.ok) { - console.log(kleur.green().bold( + console.log(formatter.green.bold( "Successfully generated NodeSecure runtime configuration at current location\n" )); } diff --git a/bin/index.ts b/bin/index.ts index d608c3e..85179f3 100644 --- a/bin/index.ts +++ b/bin/index.ts @@ -5,12 +5,14 @@ import fs from "node:fs"; // Import Third-party Dependencies import sade from "sade"; -import kleur from "kleur"; // Import Internal Dependencies import * as commands from "./commands/index.ts"; +import * as utils from "../src/utils/index.ts"; -console.log(kleur.grey().bold(`\n > Executing nreport at: ${kleur.yellow().bold(process.cwd())}\n`)); +const { formatter } = utils; + +console.log(formatter.gray.bold(`\n > Executing nreport at: ${formatter.yellow.bold(process.cwd())}\n`)); const { version } = JSON.parse( fs.readFileSync(new URL("../package.json", import.meta.url), "utf-8") diff --git a/package.json b/package.json index 401c594..dd527fe 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "@topcli/spinner": "^4.0.0", "esbuild": "^0.27.0", "filenamify": "^7.0.0", - "kleur": "^4.1.5", "puppeteer": "^24.10.1", "sade": "^1.8.1", "zup": "0.0.2" diff --git a/src/analysis/fetch.ts b/src/analysis/fetch.ts index 036dc0d..3154432 100644 --- a/src/analysis/fetch.ts +++ b/src/analysis/fetch.ts @@ -2,7 +2,6 @@ import path from "node:path"; // Import Third-party Dependencies -import kleur from "kleur"; import * as scorecard from "@nodesecure/ossf-scorecard-sdk"; import { isHTTPError } from "@openally/httpie"; @@ -13,6 +12,8 @@ import * as localStorage from "../localStorage.ts"; import * as utils from "../utils/index.ts"; import * as CONSTANTS from "../constants.ts"; +const { formatter } = utils; + // CONSTANTS const kNotFoundStatusCode = 404; @@ -59,7 +60,7 @@ async function fetchPackagesStats( ) { const jsonFiles = await utils.runInSpinner( { - title: `[Fetcher: ${kleur.yellow().bold("NPM")}]`, + title: `[Fetcher: ${formatter.yellow.bold("NPM")}]`, start: "Fetching NPM packages metadata on the NPM Registry", verbose }, @@ -78,7 +79,7 @@ async function fetchRepositoriesStats( ) { const jsonFiles = await utils.runInSpinner( { - title: `[Fetcher: ${kleur.yellow().bold("GIT")}]`, + title: `[Fetcher: ${formatter.yellow.bold("GIT")}]`, start: "Cloning GIT repositories", verbose }, diff --git a/src/reporting/index.ts b/src/reporting/index.ts index 8268613..fe78b82 100644 --- a/src/reporting/index.ts +++ b/src/reporting/index.ts @@ -1,10 +1,9 @@ -// Import Third-party Dependencies -import kleur from "kleur"; - // Import Internal Dependencies import * as utils from "../utils/index.ts"; import * as localStorage from "../localStorage.ts"; +const { formatter } = utils; + // Import Reporters import { HTML, type HTMLReportData } from "./html.ts"; import { PDF } from "./pdf.ts"; @@ -15,7 +14,7 @@ export async function proceed( ): Promise { const reportHTMLPath = await utils.runInSpinner( { - title: `[Reporter: ${kleur.yellow().bold("HTML")}]`, + title: `[Reporter: ${formatter.yellow.bold("HTML")}]`, start: "Building template and assets", verbose }, @@ -29,7 +28,7 @@ export async function proceed( await utils.runInSpinner( { - title: `[Reporter: ${kleur.yellow().bold("PDF")}]`, + title: `[Reporter: ${formatter.yellow.bold("PDF")}]`, start: "Using puppeteer to convert HTML content to PDF", verbose }, diff --git a/src/utils/formatter.ts b/src/utils/formatter.ts new file mode 100644 index 0000000..d398973 --- /dev/null +++ b/src/utils/formatter.ts @@ -0,0 +1,28 @@ +// Import Node.js Dependencies +import { + styleText, + type InspectColorForeground, + type InspectColorBackground, + type InspectColorModifier +} from "node:util"; + +type StyleName = InspectColorForeground | InspectColorBackground | InspectColorModifier; + +type Formatter = { + (text: string): string; +} & { + [K in StyleName]: Formatter; +}; + +function createFormatter(styles: StyleName[] = []): Formatter { + return new Proxy( + (text: string) => styleText(styles, text), + { + get: (_, prop: string) => createFormatter([...styles, prop as StyleName]) + } + ) as Formatter; +} + +const formatter = createFormatter(); + +export { formatter }; diff --git a/src/utils/index.ts b/src/utils/index.ts index a0e9e9a..7bfbdd5 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -3,3 +3,4 @@ export * from "./cloneGITRepository.ts"; export * from "./runInSpinner.ts"; export * from "./formatNpmPackages.ts"; export * from "./charts.ts"; +export * from "./formatter.ts"; diff --git a/src/utils/runInSpinner.ts b/src/utils/runInSpinner.ts index ea0998f..fc073a0 100644 --- a/src/utils/runInSpinner.ts +++ b/src/utils/runInSpinner.ts @@ -1,6 +1,8 @@ // Import Third-party Dependencies import { Spinner } from "@topcli/spinner"; -import kleur from "kleur"; + +// Import Internal Dependencies +import { formatter } from "./formatter.ts"; export interface RunInSpinnerOptions { title: string; @@ -17,13 +19,13 @@ export async function runInSpinner( const { title, verbose = true, start = void 0 } = options; const spinner = new Spinner({ verbose }) - .start(start, { withPrefix: `${kleur.gray().bold(title)} - ` }); + .start(start, { withPrefix: `${formatter.gray.bold(title)} - ` }); try { const response = await asyncHandler(spinner); const elapsed = `${spinner.elapsedTime.toFixed(2)}ms`; - spinner.succeed(kleur.white().bold(`successfully executed in ${kleur.green().bold(elapsed)}`)); + spinner.succeed(formatter.white.bold(`successfully executed in ${formatter.green.bold(elapsed)}`)); return response; }