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 🙏

© 2024 – Pkg Stats / Ryan Hefner

artesa

v0.4.3

Published

*Artesà* is a NodeJS class-oriented complete solution for creating command line interfaces. It's strongly influenced by [Laravel artisan CLI](https://laravel.com/docs/8.x/artisan#introduction)

Downloads

2

Readme

Artesa (Artesà)

Artesà is a NodeJS class-oriented complete solution for creating command line interfaces. It's strongly influenced by Laravel artisan CLI

Note! This project is early WIP. Documentation is WIP as well.

Features

  • Class oriented extendable commands.
  • Dynamic autogenerated CLI help feedback and Command help feedback.
  • Expressively argument/option parser.
  • Input/Output utilities (colors, warnings, etc...)

Getting Started

Install artesa as a dependency:

npm install artesa

Then, create the CLI entrypoint:

// cli.ts
import { CLI } from 'artesa'

CLI.execute({
  //Routes
}).run(process.argv.slice(2))
  .then(r => r)
  .catch(e => console.error(e));

In artesa, CLI works like a router. You provide a list of "paths" and which commands must be called for each path. We'll see how to define routes later on the next section.

When we call to run(), CLI will run the suitable command based on the input provided. Usually for CLIs, process.argv is used as input. In case you use process.argv, be sure to remove the first two elements as they refer to the node and script path.

For the time being, we can try it calling CLI without any command (it will print the help):

node cli

Registering Commands

A command is a class which contains the logic to perform a specific action in the CLI. Let's see an example:

import { Command } from 'artesa';
import { ArgumentBag, OptionBag } from 'artesa';

export class SampleCommand extends Command {
  protected async handle(args: ArgumentBag, options: OptionBag): Promise<number> {
    this.io.success(`Command have been executed`);
    return 0;
  }
}

A command must implement the handle() method where stays the action logic. This is a quite simple command which just prints out a message in a green-boxed style (we'll see output helpers later). However, commands can be as complex as the action it is implementing requires. Notice handle() returns a Promise thus you can perform async calls.

Registering the command

Once we have a command created, we must register it into the CLI we defined before. As we explained previously, CLI works like a router. Commands are registered with a "path" to call them. Let's modify our entrypoint to register our command:

As we want to call our command with node cli sample, this will be how CLI entrypoint should look like:

//cli.ts
import { CLI } from 'artesa'
import { SampleCommand } from './commands/sample.command'

CLI.execute({
  'sample': SampleCommand
}).run(process.argv.slice(2))
  .then(r => r)
  .catch(e => console.error(e));

That's it. Now SampleCommand.handle() will be called with:

node cli sample

You can list all command available calling to the CLI without any path or with the option -h|--help:

node cli --help
node cli

The command path cannot contain whitespaces. You can use other kind of separators (for instance, :: sample:one) or use nested commands which is explained in the next section.

Nested commands

Sometimes commands are tightly related. For instance, if we have a Car model in our project, we might need create, update and destroy a Car. In this scenario, would be really nice to be able to create command paths like:

cli cars create
cli cars update
cli cars destroy

This can be done using nested commands in our route list. First, create the commands which performs the actions as explained in the above section:

export class CreateCarCommand extends Command {...}
export class UpdateCarCommand extends Command {...}
export class DestroyCarCommand extends Command {...}

Then, let's register them in our entrypoint as nested commands:

//cli.ts
import { CLI } from 'artesa'
import { SampleCommand } from './commands/sample.command';
import { CreateCarCommand } from './commands/cars/create.command'
import { UpdateCarCommand } from './commands/cars/update.command'
import { DestroyCarCommand } from './commands/cars/destroy.command'

CLI.execute({
  'sample': SampleCommand,
  'cars': {
    'create': CreateCarCommand,
    'update': UpdateCarCommand,
    'destroy': DestroyCarCommand
  },
}).run(process.argv.slice(2))
  .then(r => r)
  .catch(e => console.error(e));

That's it, if we call to the CLI help we'll see our nested commands:

node cli --help // or just node cli
node cli cars --help // or just node cars

Command arguments

TODO

Command options

TODO

Command output utilities

TODO