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

@qui-cli/plugin

v4.0.0

Published

@qui-cli plugin structure and registrar

Downloads

492

Readme

@qui-cli/plugin

@qui-cli plugin structure and registrar

npm version Module type: ESM

Install

npm install @qui-cli/plugin

Usage

Refer to @qui-cli/env for a complete example defining a plugin. The model is to define an ESM module and then to register that module with the Plugin.Registrar. The plugin module can optionally define the following hooks:

  • configure(config?: Plugin.Configuration) => void may be invoked either manually before processing user-provided command line arguments (e.g. to update default values) and also (if defined) when options() is invoked. See Configuration below.
  • options() => Plugin.Options is invoked (if defined) when preparing to process user-provided command-line arguments and must return a Plugin.Options object describing any user-configurable command line arguments and other user-readable documentation. See Options below.
  • init(args: Plugin.Arguments<ReturnType<typeof options>>) => void is invoked to process any user-provided command line arguments. See Initialization below.

Recommended Plugin Structure

Refer to @qui-cli/shell for a relatively straight-forward example.

📁 @example/plugin
 ↳ package.json
 ↳ 📁 src
    ↳ index.ts
    ↳ Example.ts

package.json

Define both a name and version. Include @qui-cli/plugin and any other plugins that your Plugin depends on as peer dependencies:

{
  "peerDependencies": {
    "@qui-cli/plugin": "^2.4"
  }
}

While npm will install all dependencies at the same level of the ./node_modules/ folder hierarchy, tools like pnpm will not install non-peer dependencies at the same level as the plugin. To ensure that the plugin's peers are both installed and shared properly with other plugins that rely on them, plugin dependencies must be listed as peerDependencies.

src/index.ts

Register your plugin with the Plugin.Registrar and export the module for the convenience of other plugins that may depend on it.

import { register } from '@qui-cli/plugin';
import * as Example from './Example.js';

await register(Example);
export { Example };

src/Example.ts

Define your plugin module, including exported name and any of the optional Plugin Hooks.

export const name = 'example';

export function configure(config?) {
  // ...
}

export function myMethod() {
  // ...
}

Plugin Hooks

See dev-plugin-lifecycle for an illustration of the order in which hooks are called.

Configuration

The configure() hook may prepare the plugin module for use.

While the provided Plugin.Configuration type can be used as the parameter type for the configure() hook, it is recommended to extend that configuration to support IntelliSense in your IDE:

type Configuration = Plugin.Configuration & {
  myOption?: string;
};

All plugin-defined configuration parameters must be optional, as the configure() hook may be invoked with no parameters to ensure that a plugin is ready to to provide options() or receive init().

In general, it is recommended that configure() be used to set/update/instantiate any module variables that are used elsewhere, and can be understood as the constructor for the singleton object represented by the plugin module.

Options

The options() hook may provide command-line options for jackspeak initialization and user-facing usage documentation.

type ConfigSet<Value> = Record<
  string,
  {
    description?: string; // user-readable usage information
    short?: string; // single-character short-hand for this option
    default?: Value;
    hint?: string
    validate?: (value: any) => v is Value | (v: any) => boolean;
    type?: 'number' | 'string' | 'boolean';
    multiple?: boolean;
    delim?: string // default ' '
  }
>;

type Paragraph = {
  text: string;
  level?: 1 | 2 | 3 | 4 | 5 | 6;
  pre?: boolean;
};

type Options = {
  // an option that expects a single number
  num?: ConfigSet<number>;

  // an option that expects a `delim`-separated list of numbers
  numList?: ConfigSet<number[]>;

  // an option that expects a string value (optionally quoted)
  opt?: ConfigSet<string>;

  // an option that expects a `delim`-separated list of strings
  optList?: ConfigSet<string[]>;

  // a flag that is set (true) or unset (false), --example can be explicitly unset as --no-example
  flag?: ConfigSet<boolean>;

  // a flag that can be set multiple times (-d vs -ddd)
  flagList?: ConfigSet<boolean[]>;

  // must explicitly define type and multiple
  fields?: ConfigSet<any>;

  // additional user-readable usage information
  man?: Paragraph[];
};

For example, the options() hook could be defined thus:

export function options() {
  return {
    flag: {
      foo: {
        description: 'Engage foo-ness',
        short: 'f'
      }
    },
    opt: {
      bar: {
        description: `Bar value`,
        short: 'b',
        default: 'argle-bargle'
      }
    }
  };
}

Initialization

The init() hook may receive user-provided command line arguments to update the plugin configuration. The arguments are provided as the result of the jackspeak parse() method.

The arguments may be assumed to reflect that Plugin.Options object returned from the options() hook (if no options() hook is defined, it is recommended to examine only the positional arguments).

export function init({
  values: { foo, bar }
}: Plugin.ExpectedArguments<typeof options>) {
  // ...
}

API

import * as Plugin from '@qui-cli/plugin';

Plugin.register(plugin): void

Register a plugin for use.

import * as MyPlugin from './MyPlugin.js';

Plugin.register(MyPlugin);

Plugin.Configuration

Typing for configure() hook. Intended to be extended to provide IntelliSense support, discussed in detail in Configuration.

type Configuration = Plugin.Configuration & {
  // ...
};

export function configure(config?: Configuration) {
  // ...
}

Plugin.Options

Typing for options() hook. Maps 1:1 to the jackspeak options API, discussed in detail inOptions.

export function options(): Plugin.Options {
  // ...
}

Plugin.ExpectedArguments

Typing for init() hook. Intended to provide IntelliSense support for parameters defined by options() hook.

export function init(args: Plugin.ExpectedArguments<typeof options>) {
  // ...
}

Plugin.Registrar

The Plugin Registrar, responsible for tracking plugin registrations and triggering plugin hooks. Intended primarily for use by @qui-cli/core

Plugin.mergeOptions(a, b): Plugin.Options

Merge two Plugin.Options objects. b overwrites a in the event of duplicate keys.