npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

node-uncli

v0.0.1

Published

A simple, fast, and visually appealing CLI tool library.

Readme

uncli

一个简单、快速、美观的 CLI 工具库

uncli 是一个现代化的 TypeScript CLI 工具库,它封装了 commander、inquirer、ora 和 chalk 等流行库,提供统一、简洁的 API 接口,让你能够快速构建美观的命令行应用。

✨ 特性

  • 🚀 简单易用 - 提供直观的 API,隐藏底层库的复杂性
  • 💪 类型安全 - 完整的 TypeScript 支持,提供编译时类型检查
  • 🎨 美观输出 - 内置颜色、样式和加载动画支持
  • 🔧 功能完整 - 命令管理、交互式提示、加载动画、样式输出一应俱全
  • 📦 开箱即用 - 零配置,安装即用
  • 🌳 Tree-shakable - 支持 ES Module,按需引入

📦 安装

npm install uncli
yarn add uncli
pnpm add uncli

🚀 快速开始

import { UnCli, prompt, createSpinner, style, PromptType } from 'uncli';

// 创建 CLI 应用
const cli = new UnCli('my-app', '1.0.0');

// 定义命令
cli.command({
  name: 'init',
  description: '初始化项目',
  options: [
    {
      flags: '-t, --template <name>',
      description: '模板名称',
      defaultValue: 'default'
    }
  ],
  action: async (options) => {
    // 使用交互式提示
    const projectName = await prompt({
      type: PromptType.Input,
      message: '项目名称:',
      default: 'my-project'
    });
    
    // 使用加载动画
    const spinner = createSpinner({ text: '正在创建项目...' });
    spinner.start();
    
    // 模拟异步操作
    await new Promise(resolve => setTimeout(resolve, 2000));
    
    spinner.succeed('项目创建成功!');
    
    // 使用样式输出
    console.log(style.success('✓ 完成'));
    console.log(style.info(`项目名称: ${projectName}`));
    console.log(style.info(`使用模板: ${options.template}`));
  }
});

// 解析命令行参数
cli.parse();

📖 API 文档

命令管理

UnCli

创建 CLI 应用实例。

import { UnCli } from 'uncli';

const cli = new UnCli('app-name', '1.0.0');

command(config)

注册一个命令。

cli.command({
  name: 'build',
  description: '构建项目',
  options: [
    {
      flags: '-o, --output <path>',
      description: '输出目录',
      defaultValue: './dist'
    },
    {
      flags: '-w, --watch',
      description: '监听文件变化',
      defaultValue: false
    }
  ],
  action: (options) => {
    console.log(`构建到: ${options.output}`);
    if (options.watch) {
      console.log('监听模式已启用');
    }
  }
});

parse(argv?)

解析命令行参数并执行匹配的命令。

// 解析默认的命令行参数
cli.parse();

// 解析自定义参数
cli.parse(['node', 'cli.js', 'build', '--output', './dist']);

交互式提示

prompt(config)

显示交互式提示并获取用户输入。

文本输入
import { prompt, PromptType } from 'uncli';

const name = await prompt({
  type: PromptType.Input,
  message: '请输入您的名字:',
  default: 'Anonymous',
  validate: (input) => {
    if (input.length < 2) {
      return '名字至少需要 2 个字符';
    }
    return true;
  }
});
确认提示
const confirmed = await prompt({
  type: PromptType.Confirm,
  message: '确认继续吗?',
  default: true
});
单选列表
const framework = await prompt({
  type: PromptType.List,
  message: '选择一个框架:',
  choices: [
    'React',
    'Vue',
    'Angular',
    { name: 'Svelte (推荐)', value: 'svelte' }
  ]
});
多选列表
const features = await prompt({
  type: PromptType.Checkbox,
  message: '选择需要的功能:',
  choices: [
    { name: 'TypeScript', value: 'ts', checked: true },
    { name: 'ESLint', value: 'eslint', checked: true },
    { name: 'Prettier', value: 'prettier' },
    { name: 'Jest', value: 'jest' }
  ]
});
密码输入
const password = await prompt({
  type: PromptType.Password,
  message: '请输入密码:',
  validate: (input) => {
    if (input.length < 6) {
      return '密码至少需要 6 个字符';
    }
    return true;
  }
});

加载动画

createSpinner(config)

创建加载动画实例。

import { createSpinner } from 'uncli';

const spinner = createSpinner({
  text: '正在加载...',
  color: 'cyan',
  spinner: 'dots'
});

// 启动动画
spinner.start();

// 更新文本
spinner.text('正在处理数据...');

// 成功结束
spinner.succeed('加载完成!');

// 失败结束
spinner.fail('加载失败!');

// 警告结束
spinner.warn('加载完成,但有警告');

// 信息结束
spinner.info('这是一条信息');

// 停止动画(不显示状态图标)
spinner.stop();

Spinner 类

也可以直接使用 Spinner 类:

import { Spinner } from 'uncli';

const spinner = new Spinner({ text: '正在加载...' });
spinner.start();

// 执行异步操作
await someAsyncOperation();

spinner.succeed('完成!');

样式输出

style

提供各种文本样式和颜色。

颜色
import { style } from 'uncli';

console.log(style.red('错误信息'));
console.log(style.green('成功信息'));
console.log(style.yellow('警告信息'));
console.log(style.blue('提示信息'));
console.log(style.magenta('品红色文本'));
console.log(style.cyan('青色文本'));
console.log(style.white('白色文本'));
console.log(style.gray('灰色文本'));
文本样式
console.log(style.bold('粗体文本'));
console.log(style.italic('斜体文本'));
console.log(style.underline('下划线文本'));
console.log(style.strikethrough('删除线文本'));
语义化样式
console.log(style.success('✓ 操作成功'));
console.log(style.error('✗ 操作失败'));
console.log(style.warning('⚠ 警告信息'));
console.log(style.info('ℹ 提示信息'));
组合样式
const boldRed = style.combine(style.bold, style.red);
console.log(boldRed('重要错误'));

const underlineBlue = style.combine(style.underline, style.blue);
console.log(underlineBlue('链接文本'));

错误处理

uncli 提供了统一的错误类型:

import {
  UnCliError,
  ValidationError,
  CommandError,
  UserCancelError
} from 'uncli';

try {
  // 你的代码
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('参数验证失败:', error.message);
  } else if (error instanceof CommandError) {
    console.error('命令执行失败:', error.message);
  } else if (error instanceof UserCancelError) {
    console.log('用户取消了操作');
  } else if (error instanceof UnCliError) {
    console.error('uncli 错误:', error.message);
  }
}

🎯 完整示例

#!/usr/bin/env node
import { UnCli, prompt, createSpinner, style, PromptType } from 'uncli';

const cli = new UnCli('project-cli', '1.0.0');

// 初始化命令
cli.command({
  name: 'init',
  description: '初始化新项目',
  action: async () => {
    console.log(style.bold('\n🚀 创建新项目\n'));

    // 收集项目信息
    const projectName = await prompt({
      type: PromptType.Input,
      message: '项目名称:',
      validate: (input) => {
        if (!input) return '项目名称不能为空';
        if (!/^[a-z0-9-]+$/.test(input)) {
          return '项目名称只能包含小写字母、数字和连字符';
        }
        return true;
      }
    });

    const framework = await prompt({
      type: PromptType.List,
      message: '选择框架:',
      choices: ['React', 'Vue', 'Angular', 'Svelte']
    });

    const features = await prompt({
      type: PromptType.Checkbox,
      message: '选择功能:',
      choices: [
        { name: 'TypeScript', value: 'typescript', checked: true },
        { name: 'ESLint', value: 'eslint', checked: true },
        { name: 'Prettier', value: 'prettier' },
        { name: 'Jest', value: 'jest' }
      ]
    });

    const useGit = await prompt({
      type: PromptType.Confirm,
      message: '初始化 Git 仓库?',
      default: true
    });

    // 创建项目
    const spinner = createSpinner({ text: '正在创建项目...', color: 'cyan' });
    spinner.start();

    // 模拟项目创建过程
    await new Promise(resolve => setTimeout(resolve, 1000));
    spinner.text('正在安装依赖...');
    await new Promise(resolve => setTimeout(resolve, 1500));
    
    if (useGit) {
      spinner.text('正在初始化 Git...');
      await new Promise(resolve => setTimeout(resolve, 500));
    }

    spinner.succeed('项目创建成功!');

    // 显示项目信息
    console.log('\n' + style.bold('项目信息:'));
    console.log(style.gray('─'.repeat(40)));
    console.log(`${style.cyan('名称:')} ${projectName}`);
    console.log(`${style.cyan('框架:')} ${framework}`);
    console.log(`${style.cyan('功能:')} ${features.join(', ')}`);
    console.log(`${style.cyan('Git:')} ${useGit ? '是' : '否'}`);
    console.log(style.gray('─'.repeat(40)));

    console.log('\n' + style.success('✓ 完成!'));
    console.log('\n' + style.bold('下一步:'));
    console.log(`  ${style.gray('$')} cd ${projectName}`);
    console.log(`  ${style.gray('$')} npm install`);
    console.log(`  ${style.gray('$')} npm run dev\n`);
  }
});

// 构建命令
cli.command({
  name: 'build',
  description: '构建项目',
  options: [
    {
      flags: '-m, --mode <mode>',
      description: '构建模式',
      defaultValue: 'production'
    },
    {
      flags: '-w, --watch',
      description: '监听文件变化',
      defaultValue: false
    }
  ],
  action: async (options) => {
    console.log(style.bold(`\n📦 构建项目 (${options.mode})\n`));

    const spinner = createSpinner({ text: '正在构建...', color: 'green' });
    spinner.start();

    // 模拟构建过程
    await new Promise(resolve => setTimeout(resolve, 2000));

    spinner.succeed('构建完成!');

    if (options.watch) {
      console.log(style.info('\n👀 监听文件变化中...'));
    }
  }
});

// 解析命令
cli.parse();

🔧 开发

# 安装依赖
npm install

# 构建
npm run build

# 运行测试
npm test

# 生成覆盖率报告
npm run test:coverage

# 监听模式
npm run test:watch

📝 许可证

MIT