Skip to content

Commit

Permalink
perf: type safety
Browse files Browse the repository at this point in the history
  • Loading branch information
kabeep committed May 1, 2024
1 parent b4962f1 commit c76416a
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .xo-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"rules": {
"unicorn/filename-case": "off",
"unicorn/prefer-string-replace-all": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"import/extensions": [
"error",
"ignorePackages",
Expand Down
6 changes: 2 additions & 4 deletions src/core/PaletteError.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import chalk, { type ChalkInstance } from 'chalk';
import chalkPipe from 'chalk-pipe';
import { isBgRgb, isNil, isRgb, isString, normalizeRgb } from '../helpers/index.js';
import { isBgRgb, isRgb, isString, normalizeRgb } from '../helpers/index.js';

/**
* A palette error.
Expand Down Expand Up @@ -29,7 +29,7 @@ export default class PaletteError extends Error {
* @param {ChalkInstance} chain - The Chalk instance to chain with.
* @returns {ChalkInstance} A Chalk instance with the specified styles.
*/
palette(styles?: string, chain?: ChalkInstance): ChalkInstance {
palette(styles?: string, chain: ChalkInstance = chalk): ChalkInstance {
if (!isString(styles)) {
styles = '';
}
Expand All @@ -41,8 +41,6 @@ export default class PaletteError extends Error {
const _isBgRgb = isBgRgb(style);
if (!_isRgb && !_isBgRgb) return style;

if (isNil(chain)) chain = chalk;

const rgb = normalizeRgb(style, 'bg');
chain = _isRgb ? chain.rgb(...rgb) : chain.bgRgb(...rgb);

Expand Down
44 changes: 28 additions & 16 deletions src/core/PrintError.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { basename } from 'node:path';
import process from 'node:process';
import { ChalkInstance } from 'chalk';
import { cwd, stdout } from 'node:process';
import type { WriteStream } from 'node:tty';
import type { ChalkInstance } from 'chalk';
import type { TraceOption } from '../shared/index.js';
import TraceError from './TraceError.js';

Expand Down Expand Up @@ -38,10 +39,15 @@ export default class PrintError extends TraceError {
const title = ` ${this.message} `;
const { length } = title;

const width = this.calc((defaultLength ?? length) + 2);
const width = this.calc((defaultLength ?? length) + 2) / 2;

const prefix = this.highlight('red', this.divide(Math.floor(width / 2)));
const suffix = this.highlight('red', this.divide(Math.ceil(width / 2)));
const prefixLength = Math.floor(width);
const prefixString = this.divide(prefixLength);
const prefix = this.highlight('red', prefixString);

const suffixLength = Math.ceil(width);
const suffixString = this.divide(suffixLength);
const suffix = this.highlight('red', suffixString);

return `${prefix}${this.highlight('cyanBright', title)}${suffix}]`;
}
Expand All @@ -53,22 +59,24 @@ export default class PrintError extends TraceError {
* @returns {string} The formatted trace information.
*/
private print(track: TraceOption[]) {
const root = process.cwd();
const root: string = cwd();
const baseRoot: string = basename(cwd());
const { length } = track;

return track
.map((item, index) => {
const title = this.palette('yellowBright')(`${item.file}:${item.line}`);
const titleStylish: ChalkInstance = this.palette('yellowBright');
const title = titleStylish(`${item.file}:${item.line}`);
const summary = `- ${title} ${item.name}`;

const current = item.packageName.replace('[current]', basename(root));
const startIndex = item.address?.indexOf(current);
if (typeof startIndex !== 'number' || startIndex === -1) return;
const current = item.packageName.replace('[current]', baseRoot);
const startIndex = item.address.indexOf(current);
const shorthandAddress = item.address.slice(Math.max(0, startIndex));

const shorthandAddress = item.address!.slice(Math.max(0, startIndex));
const descStylish: ChalkInstance = this.palette('gray');
let description = descStylish(shorthandAddress.replace(current, `(${current})`));

const isLatest = index === length - 1;
let description = this.palette('gray')(shorthandAddress.replace(current, `(${current})`));
if (!isLatest) {
description += '\n';
}
Expand All @@ -95,7 +103,8 @@ export default class PrintError extends TraceError {
const prefix = this.highlight('red', this.divide(width));
const suffix = this.highlight('red', this.divide(1));

return `[${prefix}${this.palette(styles)(title)}${suffix}`;
const stylish: ChalkInstance = this.palette(styles);
return `[${prefix}${stylish(title)}${suffix}`;
}

/**
Expand All @@ -106,8 +115,9 @@ export default class PrintError extends TraceError {
* @returns {number} The calculated width.
*/
private calc(length: number, defaultLength = 32) {
const clientWidth = (process.stdout?.columns || defaultLength) - length;
const columns: number | undefined = (stdout as (WriteStream & { fd: 1 }) | undefined)?.columns;

const clientWidth = (columns ?? defaultLength) - length;
return clientWidth <= 0 ? defaultLength : clientWidth;
}

Expand All @@ -119,7 +129,8 @@ export default class PrintError extends TraceError {
* @returns {string} The highlighted content.
*/
private highlight(color: string, content: string) {
return this.palette(color)(content);
const stylish: ChalkInstance = this.palette(color);
return stylish(content);
}

/**
Expand All @@ -130,6 +141,7 @@ export default class PrintError extends TraceError {
* @returns {string} The string filled with the separator character.
*/
private divide(length: number, separator = '-') {
return Array.from({ length }).fill(separator).join('');
const ls: string[] = Array.from({ length }).map(() => separator);
return ls.join('');
}
}
8 changes: 4 additions & 4 deletions src/shared/trace-option.type.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export type TraceOption = {
export interface TraceOption {
original: string;
name: string | undefined;
address: string | undefined;
name: string;
address: string;
file: string | undefined;
line: number | undefined;
col: number | undefined;
packageName: string;
};
}
16 changes: 8 additions & 8 deletions test/core/PrintError.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,32 +47,32 @@ test('PrintError.calc - should return default length when terminal width is mini

test('PrintError.print - should generate correct trace information', () => {
const printError = new PrintError('');
const track = [
const track: TraceOption[] = [
{
original: 'at exampleFunction (/path/to/example-package/example.js:10:1)',
file: 'example.js',
line: 10,
col: 1,
name: 'exampleFunction',
packageName: 'example-package',
address: '/path/to/example-package/example.js',
},
{
original: 'at anotherFunction (/path/to/current/another.js:20:2)',
file: 'another.js',
line: 20,
col: 2,
name: 'anotherFunction',
packageName: '[current]',
address: '/path/to/current/another.js',
},
{
file: 'another.js',
line: 20,
name: 'anotherFunction',
packageName: '[current]',
},
];

const expected =
`- ${printError.palette('yellowBright')('example.js:10')} exampleFunction\n` +
` ${printError.palette('gray')('(example-package)/example.js')}\n`;
` ${printError.palette('gray')('(example-package)/example.js')}\n\n` +
`- ${printError.palette('yellowBright')('another.js:20')} anotherFunction\n` +
` ${printError.palette('gray')('/path/to/current/another.js')}`;

const result = printError['print'](track as TraceOption[]);
expect(result).toBe(expected);
Expand Down

0 comments on commit c76416a

Please sign in to comment.