Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add jsdocs for utils functions #286

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/utils/box.ts
Expand Up @@ -200,6 +200,9 @@ export type BoxOpts = {
style?: Partial<BoxStyle>;
};

/**
* The default style applied to a box if no custom style is specified. See {@link BoxStyle}.
*/
const defaultStyle: BoxStyle = {
borderColor: "white",
borderStyle: "rounded",
Expand All @@ -210,6 +213,12 @@ const defaultStyle: BoxStyle = {
marginBottom: 1,
};

/**
* Creates a styled box with text content, customisable via options.
* @param {string} text - The text to display in the box.
* @param {BoxOpts} [_opts={}] - Optional settings for the appearance and behaviour of the box. See {@link BoxOpts}.
* @returns {string} The formatted box as a string, ready for printing or logging.
*/
export function box(text: string, _opts: BoxOpts = {}) {
const opts = {
..._opts,
Expand Down
26 changes: 26 additions & 0 deletions src/utils/color.ts
Expand Up @@ -21,6 +21,11 @@ const isCompatibleTerminal =
const isCI =
"CI" in env &&
("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);

/**
* Determines support for terminal colours based on the environment and capabilities of the terminal.
* @type {boolean} isColorSupported - Indicates whether colour support is enabled in the terminal.
*/
const isColorSupported =
!isDisabled &&
(isForced || (isWindows && !isDumbTerminal) || isCompatibleTerminal || isCI);
Expand Down Expand Up @@ -118,21 +123,42 @@ const colorDefs = {
export type ColorName = keyof typeof colorDefs;
export type ColorFunction = (text: string | number) => string;

/**
* Creates an object that maps colour names to their respective colour functions,
* based on whether or not colour support is enabled.
* @param {boolean} [useColor=isColorSupported] - Specifies whether to use colour functions or fallback to plain strings.
* @returns {Record<ColorName, ColorFunction>} An object where keys are colour names and values are functions to apply those colours. See {@link ColorFunction}.
*/
function createColors(useColor = isColorSupported) {
return useColor
? colorDefs
: Object.fromEntries(Object.keys(colorDefs).map((key) => [key, String]));
}

/**
* An object containing functions for colouring text. Each function corresponds to a terminal colour. See {@link ColorName} for available colours.
*/
export const colors = createColors() as Record<ColorName, ColorFunction>;

/**
* Gets a colour function by name, with an option for a fallback colour if the requested colour is not found.
* @param {ColorName} color - The name of the colour function to get. See {@link ColorName}.
* @param {ColorName} [fallback="reset"] - The name of the fallback colour function if the requested colour is not found. See {@link ColorName}.
* @returns {ColorFunction} The colour function that corresponds to the requested colour, or the fallback colour function. See {@link ColorFunction}.
*/
export function getColor(
color: ColorName,
fallback: ColorName = "reset",
): ColorFunction {
return colors[color] || colors[fallback];
}

/**
* Applies a specified colour to a given text string or number.
* @param {ColorName} color - The colour to apply. See {@link ColorName}.
* @param {string | number} text - The text to colour.
* @returns {string} The coloured text.
*/
export function colorize(color: ColorName, text: string | number): string {
return getColor(color)(text);
}
5 changes: 5 additions & 0 deletions src/utils/error.ts
@@ -1,5 +1,10 @@
import { sep } from "node:path";

/**
* Parses a stack trace string and normalises its paths by removing the current working directory and the "file://" protocol.
* @param {string} stack - The stack trace string.
* @returns {string[]} An array of stack trace lines with normalised paths.
*/
export function parseStack(stack: string) {
const cwd = process.cwd() + sep;

Expand Down
14 changes: 14 additions & 0 deletions src/utils/format.ts
@@ -1,5 +1,6 @@
import { vsprintf } from "printj";

// Predefined rules for replacing format arguments
const FORMAT_ARGS = [
["additional", 5],
["message", 4],
Expand All @@ -8,9 +9,16 @@ const FORMAT_ARGS = [
["tag", 3],
]; // .sort((a, b) => b[0].length - a[0].length)

// Caches compiled format strings for reuse
const _compileCache: any = {};
// process.on('beforeExit', () => { console.log(_compileCache) })

/**
* Compiles a format string by replacing placeholders with appropriate position indices.
* Caches compiled formats for efficiency.
* @param {string} format - The format string containing the placeholders to replace.
* @returns {string} The compiled format string with placeholders replaced by positional indices.
*/
export function compileFormat(format: string) {
if (_compileCache[format]) {
return _compileCache[format];
Expand All @@ -28,6 +36,12 @@ export function compileFormat(format: string) {
return _format;
}

/**
* Formats a string according to a custom format, using vsprintf for string formatting.
* @param {string} format - The custom format string.
* @param {any[]} argv - The arguments to format into the string.
* @returns {string} The formatted string.
*/
export function formatString(format: string, argv: any) {
return vsprintf(compileFormat(format), argv);
}
11 changes: 11 additions & 0 deletions src/utils/log.ts
@@ -1,7 +1,18 @@
/**
* Checks if the given argument is a simple JavaScript object.
* @param {any} obj - The object to test.
* @returns {boolean} `true` if the argument is a plain object, otherwise `false`.
*/
export function isPlainObject(obj: any) {
return Object.prototype.toString.call(obj) === "[object Object]";
}

/**
* Determines whether the given argument is a protocol object. A log object must be a simple object and
* must contain either a 'message' or 'args' field, but not a 'stack' field.
* @param {any} arg - The argument to check.
* @returns {boolean} `true` if the argument is a log object according to the specified criteria, otherwise `false`.
*/
export function isLogObj(arg: any) {
// Should be plain object
if (!isPlainObject(arg)) {
Expand Down