1.0.0 • Published 6 months ago

@digm-dev/yargonaut v1.0.0

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
6 months ago

@digm/yargonaut

✨ Decorate your yargs CLI output with chalk styles and figlet fonts.

NPM Version License


💡 Note: This package, @digm/yargonaut, is a modern rewrite and successor to the original yargonaut package by James Talmage. It aims to provide the same core functionality but with improved stability and a slightly different API. Full credit for the original concept goes to James Talmage.


Table of Contents


Motivation

The original yargonaut was a fantastic idea but relied on patching Node.js's require mechanism, which could be fragile and dependent on specific versions of yargs and y18n.

This rewrite (@digm/yargonaut) achieves the same goal – styling yargs output – by using the official yargs updateLocale API. This results in:

  • Improved Stability: No more monkey-patching internals. Works reliably across yargs versions (that support updateLocale).
  • No require Order Dependency: Import yargs and @digm/yargonaut in any order.
  • Modern Codebase: Written in TypeScript, uses modern JavaScript features.
  • Explicit Initialization: Requires passing your yargs instance for clear control.

Return to top

Installation


bunbun add @digm/yargonaut yargs chalk figlet
npmpnpm add @digm/yargonaut yargs chalk figlet
pnpmpnpm add @digm/yargonaut yargs chalk figlet
yarnyarn add @digm/yargonaut yargs chalk figlet

!NOTE @digm/yargonaut requires yargs, chalk, and figlet as peer dependencies. You need to install them alongside it.

Return to top

Usage


The key difference from the original yargonaut is that you must instantiate Yargonaut with your configured yargs instance.

import yargs from 'yargs/yargs';
import {hideBin} from 'yargs/helpers';
import {Yargonaut} from '@digm/yargonaut'; // Import the class

// 1. Get your yargs instance
const yargsInstance = yargs(hideBin(process.argv));

// 2. Create a Yargonaut instance, passing the yargs instance
const yargonaut = new Yargonaut(yargsInstance);

// 3. Configure styles and fonts using yargonaut
yargonaut
    .style('blue.bold', 'Commands:') // Style specific keys
    .help('Big')                   // Apply 'Big' font to all help sections
    .errorsStyle('red');           // Apply 'red' style to all error messages

// 4. Define your yargs commands and options *on the original yargs instance*
yargsInstance
    .command('launch <rocket>', 'Launch the specified rocket', (y) => {
        y.positional('rocket', {describe: 'Rocket name', type: 'string'});
    })
    .option('speed', {alias: 's', describe: 'Launch speed', choices: ['ludicrous', 'warp'], default: 'warp'})
    .demandCommand(1, 'You must specify a command.')
    .help() // Enable standard help output (which will be styled)
    .argv; // Parse arguments and trigger output if needed

// Yargonaut automatically called yargsInstance.updateLocale() when you used .style(), .font(), etc.

Return to top

Example Output (Conceptual)


Running the above script with --help might produce output where "Commands:" is blue and bold, and the section titles ("Commands:", "Options:") are rendered using the "Big" figlet font, while any error messages (e.g., for missing commands) would appear in red.

Return to top

Customizing Output


For fine-grained control, you can provide a function to customizeOutput. This function runs after Yargonaut applies its styles/fonts but before the string is sent to yargs.

import yargs from "yargs/yargs";
import {hideBin} from "yargs/helpers";
import {Yargonaut} from "@digm/yargonaut";
import type figlet from "figlet"; // Import figlet type if needed

const yargsInstance = yargs(hideBin(process.argv));
const yargonaut = new Yargonaut(yargsInstance);

yargonaut.customizeOutput(
    ({ key, modifiedString, fontName, styleString }) => {
        console.log(
            `[Customizing] Key: ${key}, Font: ${fontName}, Style: ${styleString}`,
        );
        // Add a prefix to all modified strings
        if (typeof modifiedString === "string") {
            return `🚀 ${modifiedString}`;
        }
        // Handle plural objects if necessary
        if (typeof modifiedString === "object" && modifiedString !== null) {
            return {
                one: `🚀 ${modifiedString.one}`,
                other: `🚀 ${modifiedString.other}`,
            };
        }
        return modifiedString;
    },
);

yargonaut.help("Standard"); // Apply font, then customization function will run

yargsInstance.command("fly", "Fly somewhere").help().argv;

Return to top

API Summary


MethodTypeDescription
new Yargonaut(yargs)ConstructorCreates & initializes the Yargonaut instance.
Configuration Methods(Chainable)
.help(fontName)ConfigApply figlet font to help section titles.
.errors(fontName)ConfigApply figlet font to error message titles.
.font(fontName, keys)ConfigApply figlet font to specific or all keys.
.helpStyle(styleString)ConfigApply chalk style to help sections.
.errorsStyle(styleString)ConfigApply chalk style to error messages.
.style(styleString, keys)ConfigApply chalk style to specific or all keys.
.transformWholeString(keys)ConfigRender entire string with figlet for specified keys.
.transformUpToFirstColon(keys)ConfigRender string up to first colon with figlet.
.customizeOutput(customizationFunction)ConfigSet a function for final output customization.
Utility Methods
.renderTextAsFont(text, fontName)UtilityRenders text with a specified figlet font.
.listAvailableFonts()UtilityReturns an array of available figlet font names.
.printTextInFont(fontName, text)UtilityPrints text rendered in a specific font to console.
.printTextInAllFonts(text)UtilityPrints text rendered in all available fonts.
.getFigletInstance()UtilityReturns the figlet instance.
.getChalkInstance()UtilityReturns the chalk instance.

Return to top

API Details


Constructor

new Yargonaut(yargsInstance)

Creates and initializes a new Yargonaut instance, linking it to your configured yargs instance.

  • Parameters:
    • yargsInstance: YargsInstance - The instance returned by yargs/yargs(...). Must have an updateLocale method.
  • Throws: Error if yargsInstance is invalid or missing updateLocale.
  • Returns: Yargonaut instance.

Configuration Methods

These methods configure how Yargonaut styles output and are chainable (they return this).

.help(fontName)

Apply a specific figlet font to the titles of help sections (e.g., "Commands:", "Options:").

  • Parameters:
    • fontName: string - The name of the figlet font (e.g., 'Standard', 'Big'). See 
`.listAvailableFonts()`.
  • Returns: this (Yargonaut instance).

.errors(fontName)

Apply a specific figlet font to the titles of error messages (where applicable based on the transform function, e.g., " Missing required argument:").

  • Parameters:
    • fontName: string - The name of the figlet font. See `.listAvailableFonts()`.
  • Returns: this (Yargonaut instance).

.font(fontName, keys)

Apply a specific figlet font to one or more yargs locale keys.

  • Parameters:
    • fontName: string - The name of the figlet font. See `.listAvailableFonts()`.
    • keys?: string | string[] - Optional. A single key string or an array of key strings to apply the font to. If omitted, applies to all known keys.
  • Returns: this (Yargonaut instance).

.helpStyle(styleString)

Apply a chalk style to all help section titles.

  • Parameters:
    • styleString: string - A chalk style string (e.g., 'blue.bold'). See 
Chalk documentation.
  • Returns: this (Yargonaut instance).

.errorsStyle(styleString)

Apply a chalk style to all error messages.

  • Parameters:
    • styleString: string - A chalk style string (e.g., 'red'). See 
Chalk documentation.
  • Returns: this (Yargonaut instance).

.style(styleString, keys)

Apply a chalk style to one or more yargs locale keys.

  • Parameters:
    • styleString: string - A chalk style string (e.g., 'green.underline'). See 
Chalk documentation.
    • keys?: string | string[] - Optional. A single key string or an array of key strings to apply the style to. If omitted, applies to all known keys.
  • Returns: this (Yargonaut instance).

.transformWholeString(keys)

Set the transform strategy to render the entire string with figlet for the specified keys.

  • Parameters:
    • keys?: string | string[] - Optional. Key(s) to apply this transform strategy to. If omitted, applies to all known keys.
  • Returns: this (Yargonaut instance).

.transformUpToFirstColon(keys)

Set the transform strategy to render only the part of the string up to the first colon with figlet for the specified keys. This is useful for keys like "Missing required argument: %s" where you only want to figletize the label part.

  • Parameters:
    • keys?: string | string[] - Optional. Key(s) to apply this transform strategy to. If omitted, applies to all known keys.
  • Returns: this (Yargonaut instance).

.customizeOutput(customizationFunction)

Set a function to customize the output before it's sent to yargs. This lets you add your own final touches to the text after Yargonaut has applied fonts and styles, but before the text is passed to yargs.

  • Parameters:
    • customizationFunction: OutputCustomizationFunction | undefined - A function that processes the text, or undefined to remove a previously set function. The function receives an object with the key, original string, modified string, figlet instance, font name, and style string, and returns the final string to use.
  • Returns: this (Yargonaut instance).

Utility Methods

These methods provide utility functions for working with figlet fonts and chalk styles.

.renderTextAsFont(text, fontName)

Render text using a specified figlet font.

  • Parameters:
    • text: string - The text to render.
    • fontName?: string - Optional. The name of the figlet font to use. If omitted, the default font is used.
  • Returns: string - The rendered string, or the original string if there is an error.

.listAvailableFonts()

Get a list of all available figlet fonts.

  • Returns: string[] - Array of font names. If there is an error, an empty array is returned and the error is logged.

.printTextInFont(fontName, text)

Print text rendered in a specific font to the console.

  • Parameters:
    • fontName?: string - Optional. The name of the figlet font to use. Defaults to the default font.
    • text?: string - Optional. The text to render. Defaults to the fontName.
  • Returns: void.

.printTextInAllFonts(text)

Print text rendered in all available fonts to the console.

  • Parameters:
    • text?: string - Optional. The text to render. Defaults to the font name for each font.
  • Returns: void.

.getFigletInstance()

Get the figlet instance used by Yargonaut.

  • Returns: typeof figlet - The figlet instance.

.getChalkInstance()

Get the chalk instance used by Yargonaut.

  • Returns: typeof chalk - The chalk instance.

!Note This documentation does not cover internal methods that are not exported in the public

Differences from Original yargonaut

  • Initialization: Requires new Yargonaut(yargsInstance) instead of just require('yargonaut').
  • No require Order: Does not depend on being required before yargs.
  • Stability: Uses public yargs.updateLocale API, avoiding internal patching.
  • ocd Renamed: The ocd() method is now outputCustomizationDelegate() with slightly different parameters passed to the callback.
  • Getter Methods Removed: Methods like getAllKeys, getHelpKeys, getErrorKeys are removed from the instance API ( they are internal implementation details or available via imports from yargs-keys.ts if needed).

Return to top

Development

Conventional Commits & Local Validation (Optional)

This project uses Conventional Commits for versioning and changelog generation, managed by Cocogitto. Use the cog command for interactions.

To help ensure your commit messages follow the standard before you push, we provide an optional Git commit-msg hook that validates your message locally. This gives you immediate feedback and helps prevent CI failures on pull requests.

Installation:

  1. Make sure you have cocogitto installed (usually via cargo install cocogitto or brew install cocogitto/tap/cocogitto).
  2. Navigate to the project root directory in your terminal.
  3. Run the following command to install the hook defined in our cog.toml:

    cog install-hook commit-msg

    (Alternatively, cog install-hook --all installs all hooks defined in cog.toml, if any others are added in the future).

Usage:

Once installed, the hook runs automatically every time you execute git commit. If your commit message doesn't adhere to the Conventional Commits standard, the hook will prevent the commit and show an error message, prompting you to fix the message.

You can bypass the hook temporarily if needed (e.g., for fixup! commits if you haven't configured them to be ignored) using git commit --no-verify.

While this hook is optional, using it is recommended for a smoother development experience. The commit message format is enforced server-side via GitHub Actions on Pull Requests regardless.

Return to top

TypeScript Types

Yargonaut is written in TypeScript and exports type definitions for better developer experience. The following types are available for import:

Core Types

import {
    Yargonaut,
    TransformFunction,
    OutputCustomizationFunction,
    YargsKeyConfig
} from 'yargonaut';

OutputCustomizationFunction

This type defines the function signature for custom output handlers:

// Parameters for the output customization function
interface OutputCustomizationParams {
  /** The yargs locale key being processed */
  key: string;
  /** The original string from yargs before any modifications */
  originalString: string | { one: string; other: string };
  /** The string after Yargonaut has applied fonts and styles */
  modifiedString: string | { one: string; other: string };
  /** The figlet library instance for additional font rendering if needed */
  figletInstance: typeof figlet;
  /** The name of the font that was applied, if any */
  fontName?: string;
  /** The style string that was applied, if any */
  styleString?: string;
}

// Function type for customizing output
type OutputCustomizationFunction = (
  params: OutputCustomizationParams
) => string | { one: string; other: string };

Example usage:

const myCustomizer: OutputCustomizationFunction = ({ key, modifiedString, fontName }) => {
    // Add a prefix to all help text
    if (key === 'help') {
        return `✨ ${modifiedString}`;
    }
    // For other keys, just return the already modified value
    return modifiedString;
};

yargonaut.customizeOutput(myCustomizer);

TransformFunction

This type defines how text is split for figlet rendering:

type TransformFunction = (text: string) => {
    renderPart: string;
    nonRenderPart: string
};

Example of a custom transform function:

const customTransform: TransformFunction = (text) => {
    // Only render the first word with figlet
    const words = text.split(' ');
    const firstWord = words.shift() || '';
    return {
        renderPart: firstWord,
        nonRenderPart: words.length ? ' ' + words.join(' ') : ''
    };
};

// Apply your custom transform to specific keys
yargonaut.font('Standard', 'Commands:')
    .#applyTransform(customTransform, ['Commands:']);

YargsKeyConfig

This type defines the configuration for yargs locale keys:

type YargsKeyConfig = {
    transform?: TransformFunction;
    error?: boolean;
    plural?: string;
    isPlural?: boolean;
};

Return to top

Contributing

Development Environment:

This project uses Bun as the runtime and package manager for development. Please ensure you have Bun installed before attempting to contribute. It's used for installing dependencies, running tests, executing build scripts, and managing version updates via hooks.

Contributions to @digm/yargonaut are welcome and appreciated! Here's how you can contribute:

Getting Started

  1. Fork the repository on GitHub
  2. Clone your fork to your local machine
  3. Install dependencies:
    bun install

Development Workflow

  1. Create a feature branch:
    git checkout -b feature/your-feature-name
  2. Make your changes and write tests if applicable
  3. Run tests to ensure everything works:
    bun test
  4. Run linting to ensure code quality:
    bun run lint
  5. Format your code:
    bun run format:biome

Pull Requests

  1. Push your changes to your fork
  2. Submit a pull request to the main repository
  3. Describe your changes in detail in the PR description
  4. Reference any related issues using GitHub's issue linking

Code Style

This project uses ESLint and Biome for code quality and formatting. Please ensure your code follows these standards by running the linting and formatting commands before submitting a PR.

Reporting Issues

If you find a bug or have a feature request, please open an issue on GitHub. Be sure to include:

  • A clear, descriptive title
  • A detailed description of the issue or feature request
  • Steps to reproduce (for bugs)
  • Expected behavior and actual behavior
  • Any relevant code snippets or error messages

Return to top

Acknowledgements

  • All contributors to yargs, chalk, and figlet.

Return to top

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Return to top