From ab9322e1ab9c0a07cdab7275f3398286dee67a64 Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Wed, 28 Aug 2024 03:40:26 +0300 Subject: [PATCH] feat: remove chalk dependency --- jest.config.ts | 1 - package.json | 3 +-- pnpm-lock.yaml | 3 --- src/cmd.ts | 16 ++++++++-------- src/logger.ts | 10 +++++----- src/utils.ts | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 19 deletions(-) diff --git a/jest.config.ts b/jest.config.ts index 3515e15..5f14d44 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -88,7 +88,6 @@ export default { // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module // moduleNameMapper: {}, // moduleNameMapper: { - // chalk: "/node_modules/chalk/source/index.js", // "#ansi-styles": "/node_modules/chalk/source/vendor/ansi-styles/index.js", // "#supports-color": "/node_modules/chalk/source/vendor/supports-color/index.js", // }, diff --git a/package.json b/package.json index 5df073f..dc05075 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "bin": { "simple-scaffold": "cmd.js" }, - "packageManager": "pnpm@9.0.4", + "packageManager": "pnpm@9.8.0", "keywords": [ "javascript", "cli", @@ -38,7 +38,6 @@ "changelog": "conventional-changelog -i CHANGELOG.md -s -r 0; echo \"# Change Log\n\n$(cat CHANGELOG.md)\" > CHANGELOG.md" }, "dependencies": { - "chalk": "^4.1.2", "date-fns": "^3.6.0", "glob": "^11.0.0", "handlebars": "^4.7.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3d720a9..4cdefaf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,6 @@ importers: .: dependencies: - chalk: - specifier: ^4.1.2 - version: 4.1.2 date-fns: specifier: ^3.6.0 version: 3.6.0 diff --git a/src/cmd.ts b/src/cmd.ts index 51cce07..bc184a5 100644 --- a/src/cmd.ts +++ b/src/cmd.ts @@ -3,13 +3,13 @@ import path from "node:path" import fs from "node:fs/promises" import { massarg } from "massarg" -import chalk from "chalk" import { ListCommandCliOptions, LogLevel, ScaffoldCmdConfig } from "./types" import { Scaffold } from "./scaffold" import { getConfigFile, parseAppendData, parseConfigFile } from "./config" import { log } from "./logger" import { MassargCommand } from "massarg/command" import { getUniqueTmpPath as generateUniqueTmpPath } from "./file" +import { colorize } from "./utils" export async function parseCliArgs(args = process.argv.slice(2)) { const isProjectRoot = Boolean(await fs.stat(path.join(__dirname, "package.json")).catch(() => false)) @@ -134,7 +134,7 @@ export async function parseCliArgs(args = process.argv.slice(2)) { defaultValue: LogLevel.info, description: "Determine amount of logs to display. The values are: " + - `${chalk.bold`\`none | debug | info | warn | error\``}. ` + + `${colorize.bold`\`none | debug | info | warn | error\``}. ` + "The provided level will display messages of the same level or higher.", parse: (v) => { const val = v.toLowerCase() @@ -185,7 +185,7 @@ export async function parseCliArgs(args = process.argv.slice(2)) { } try { const file = await getConfigFile(config, tmpPath) - console.log(chalk.underline`Available templates:\n`) + console.log(colorize.underline`Available templates:\n`) console.log(Object.keys(file).join("\n")) } catch (e) { const message = "message" in (e as any) ? (e as any).message : e?.toString() @@ -212,7 +212,7 @@ export async function parseCliArgs(args = process.argv.slice(2)) { defaultValue: LogLevel.none, description: "Determine amount of logs to display. The values are: " + - `${chalk.bold`\`none | debug | info | warn | error\``}. ` + + `${colorize.bold`\`none | debug | info | warn | error\``}. ` + "The provided level will display messages of the same level or higher.", parse: (v) => { const val = v.toLowerCase() @@ -251,7 +251,7 @@ export async function parseCliArgs(args = process.argv.slice(2)) { bindOption: true, lineLength: 100, useGlobalTableColumns: true, - usageText: [chalk.yellow`simple-scaffold`, chalk.gray`[options]`, chalk.cyan``].join(" "), + usageText: [colorize.yellow`simple-scaffold`, colorize.gray`[options]`, colorize.cyan``].join(" "), optionOptions: { displayNegations: true, }, @@ -259,9 +259,9 @@ export async function parseCliArgs(args = process.argv.slice(2)) { `Version: ${pkg.version}`, `Copyright © Chen Asraf 2017-${new Date().getFullYear()}`, ``, - `Documentation: ${chalk.underline`https://chenasraf.github.io/simple-scaffold`}`, - `NPM: ${chalk.underline`https://npmjs.com/package/simple-scaffold`}`, - `GitHub: ${chalk.underline`https://github.com/chenasraf/simple-scaffold`}`, + `Documentation: ${colorize.underline`https://chenasraf.github.io/simple-scaffold`}`, + `NPM: ${colorize.underline`https://npmjs.com/package/simple-scaffold`}`, + `GitHub: ${colorize.underline`https://github.com/chenasraf/simple-scaffold`}`, ].join("\n"), }) .parse(args) diff --git a/src/logger.ts b/src/logger.ts index ee87af8..2014608 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -1,6 +1,6 @@ import util from "util" import { LogConfig, LogLevel, ScaffoldConfig } from "./types" -import chalk from "chalk" +import { colorize, TermColor } from "./utils" export function log(config: LogConfig, level: LogLevel, ...obj: any[]): void { const priority: Record = { @@ -15,7 +15,7 @@ export function log(config: LogConfig, level: LogLevel, ...obj: any[]): void { return } - const levelColor: Record = { + const levelColor: Record = { [LogLevel.none]: "reset", [LogLevel.debug]: "blue", [LogLevel.info]: "dim", @@ -23,16 +23,16 @@ export function log(config: LogConfig, level: LogLevel, ...obj: any[]): void { [LogLevel.error]: "red", } - const chalkFn: any = chalk[levelColor[level]] + const colorFn = colorize[levelColor[level]] const key: "log" | "warn" | "error" = level === LogLevel.error ? "error" : level === LogLevel.warning ? "warn" : "log" const logFn: any = console[key] logFn( ...obj.map((i) => i instanceof Error - ? chalkFn(i, JSON.stringify(i, undefined, 1), i.stack) + ? colorFn(i, JSON.stringify(i, undefined, 1), i.stack) : typeof i === "object" ? util.inspect(i, { depth: null, colors: true }) - : chalkFn(i), + : colorFn(i), ), ) } diff --git a/src/utils.ts b/src/utils.ts index 492013a..3af4928 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -15,3 +15,55 @@ export function wrapNoopResolver(value: Resolver): Resolver value } + +const colorMap = { + reset: 0, + dim: 2, + bold: 1, + italic: 3, + underline: 4, + red: 31, + green: 32, + yellow: 33, + blue: 34, + magenta: 35, + cyan: 36, + white: 37, + gray: 90, +} as const + +export type TermColor = keyof typeof colorMap + +function _colorize(text: string, color: TermColor): string { + const c = colorMap[color]! + return `\x1b[${c}m${text}\x1b[0m` +} + +function isTemplateStringArray(template: TemplateStringsArray | unknown): template is TemplateStringsArray { + return Array.isArray(template) && typeof template[0] === "string" +} + +const createColorize = + (color: TermColor) => + (template: TemplateStringsArray | unknown, ...params: unknown[]): string => { + return isTemplateStringArray(template) + ? _colorize( + (template as TemplateStringsArray).reduce((acc, str, i) => acc + str + (params[i] ?? ""), ""), + color, + ) + : _colorize(String(template), color) + } + +type TemplateStringsFn = ReturnType & ((text: string) => string) +type TemplateStringsFns = { [key in TermColor]: TemplateStringsFn } + +export const colorize: typeof _colorize & TemplateStringsFns = Object.assign( + _colorize, + Object.entries(colorMap).reduce( + (acc, [key]) => { + acc[key as TermColor] = createColorize(key as TermColor) + return acc + }, + {} as Record, + ), +)