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

@dawiidio/pli

v1.0.1

Published

create CLI for any project within a few minutes with Pli and keep it along with your project!

Downloads

3

Readme

pli

create CLI for any project within a few minutes with Pli!

Installation and usage

pli-terminal-gif

Global installation is recommended

npm install -g @dawiidio/pli 
# or 
yarn global add @dawiidio/pli
npm install @dawiidio/pli 
# or
yarn add @dawiidio/pli 

You can use it also via npx

npx @dawiidio/pli

Usage

init pli in current directory

# by default pli init will produce templates directory with sample template file
pli init

# config file is optional, but if you want to create
# more complex templates it may be useful
# to generate it run
pli init -c

# by default pli init will produce typescript config file and examples, if you prefer js use
pli init -c -t js

the above command creates templates directory and sample template file in it, which looks like this:

export function hello() {
    return 'Hello $NAME$';
}

as you can see we have $NAME$ which defines pli's variable. This variable will be extracted and prompted to fill with value after selecting template, you can now run pli command in current directory, pli will prompt you with below message:

? Select template (Use arrow keys)
❯ hello.js 

select template hello.js by pressing enter

? Select template hello.js
? Output directory  <-- type directory where file should be saved or leave it empty to save in current
? Insert value for NAME :  <-- type value for name, e.g. David

when last variable is filled with value pli starts its magic and produces result file, after successful creation process you will see summary like below:

Following structure was created inside directory /your/current/working/directory
├─ hello.js

That's it! You can see the results by opening file. For example

cat hello.js

should return

export function hello() {
    return 'Hello David';
}

cli

pli run

runs cli, default command

Commands:
  pli run   runs cli, default command                                  [default]
  pli init  initializes pli in current directory

Options:
      --help                Show help                                  [boolean]
      --version             Show version number                        [boolean]
  -c, --config              path to config file                         [string]
  -d, --dry                 dry run, results will not be saved         [boolean]
  -l, --logLevel            log level. Available options: error, warn, info,
                            debug. Multiple options separated by pipe sign "|"
                                                     [string] [default: "error"]
  -o, --allowOverwriting    allow overwriting output files while committing data
                            to storage                                 [boolean]
  -t, --templatesDirectory  override templates directory
                                                [boolean] [default: "templates"]

Examples

The above example is just the simplest one, you can create more sophisticated templates with many directories, variables and files. See examples for more

Config file

to create more powerful tools and templates the config file may be needed, run

# for typescript config file run
pli init -c
# for javascript config file run
pli init -c -t js

the above command creates pli.config.js or pli.config.ts file in current directory, now this is the time to create more complex templates, we will create a React component template with support for css modules.

run

mkdir templates/\\$NAME$
touch templates/\\$NAME$/\\$NAME$.tsx 
touch templates/\\$NAME$/\\$NAME$.module.css

in templates/$NAME$/$NAME$.tsx file add

import React, { FunctionComponent } from "react";
import styles from './$NAME$.module.css';

interface $NAME$Props {

}

export const $NAME$:FunctionComponent<$NAME$Props> = ({  }) => {

    return (
        <div className={styles.$NAME$Root}>
            Component $NAME$
        </div>
    )
};

now we have a template for React component, but we want to have support for css modules, so we need to add css file for it.

in templates/$NAME$/$NAME$.module.css file add

.$NAME$Root {

}

now we have a template files for React component with css module support, and it will work just fine now, but we can make it even better.

in pli.config.ts file add

import { Template, IConfig, TemplateVariable, ITemplateVariable, IVariableScope } from '@dawiidio/pli';

const config: IConfig = {
    templates: [
        new Template({
            // readable name, instead of "$NAME$" you will see "React Component" in cli
            name: 'React Component', 
            // if you want to extend from existing template in templates directory you need to provide its name
            id: '$NAME$',
            // all will be generated relative to src/components directory
            defaultOutputDirectoryPath: 'src/components',
            variables: [
                new TemplateVariable({
                    // variable name, it will be replaced with value in template files
                    name: 'NAME',
                    // you can pass default value for our variable
                    defaultValue: 'MyComponent',
                    // let's add some validation for our variable
                    validate: (value: string) => {
                        if (value.length < 3) {
                            throw new Error('Name must be at least 3 characters long');
                        }
                    }
                }),
                new TemplateVariable({
                    // variable name, it will be replaced with value in template files
                    name: 'DIRNAME',
                    // this variable will subscribe from NAME variable, so it will be updated when NAME is updated
                    defaultValue: '$NAME$',
                    ui: {
                        // you can also hide variables from user, so it will be used only for internal purposes
                        hidden: true
                    }
                }).pipe(
                    // you can pipe variable value and trnasform it as you want, 
                    // in this case we will replace all spaces with dashes
                    // and then we will convert all letters to lowercase
                    // so if we type "My Component" as NAME variable value
                    // DIRNAME will be "my-component"
                    (value: string, variable: ITemplateVariable, scope: IVariableScope) => value.replace(/\s/g, '-').toLowerCase()
                )
            ],
        })
    ]
}

export default config;

after adding config file we can run pli, if you set $NAME$ to e.g. TestFilters you will see below message:

Following structure was created inside directory /myProject/src/components
├─ TestFilters/
│  ├─ TestFilters.module.css
│  ├─ TestFilters.tsx

Variables

You can create variables in your templates by using notation with dollars $MY_VAR$. Variable name is case-sensitive, so $my_var$ and $MY_VAR$ are different variables. Variable name can contain only letters, numbers and underscores.

Variables can be used in any file, or directory name, or in other variable defaultValue field which means that variable will subscribe to changes of variables passed in defaultValue. You can use variables also in outputMapping in template config.

Scopes

Variables are organised in scopes, so you can have variables with the same name in different scopes. It is useful when you want to access variables from different template. For example if you want to add template as an entry to another template you can use variables from parent template i child. Also, variables from child will be extracted and prompted to fill with value when selecting parent template.

Example:

import { Template, IConfig, TemplateVariable } from '@dawiidio/pli';

const childTemplate = new Template({
    name: 'Child',
    id: 'child.ts',
    variables: [
        new TemplateVariable({
            name: 'CHILD_VAR',
            defaultValue: 'child'
        })
    ]
});

// parent template will prompt for PARENT_VAR and CHILD_VAR
const parentTemplate = new Template({
    name: 'Parent',
    id: 'parent.ts',
    variables: [
        new TemplateVariable({
            name: 'PARENT_VAR',
            defaultValue: 'parent'
        }),
    ],
    entries: [
        childTemplate
    ]
});

const config: IConfig = {
    templates: [
        parentTemplate,
    ]
}

export default config;

Output mapping

You can map output of template which allows you to create more complex templates, for example you can create template which will remap child template output to different directory or filename.

import { Template, IConfig, TemplateVariable } from '@dawiidio/pli';

const childTemplate = new Template({
    name: 'Child',
    id: 'child.ts',
    variables: [
        new TemplateVariable({
            name: 'CHILD_VAR',
            defaultValue: 'child'
        })
    ]
});

const parentTemplate = new Template({
    name: 'Parent',
    id: 'parent.ts',
    variables: [
        new TemplateVariable({
            name: 'PARENT_VAR',
            defaultValue: 'parent'
        }),
    ],
    entries: [
        childTemplate
    ],
    outputMapping: {
        // note thath you can not use CHILD_VAR in this scope
        'child.ts': '$PARENT_VAR$.ts',
        'parent.ts': '$PARENT_VAR$_somePostfix.ts',
    }
});

const config: IConfig = {
    templates: [
        parentTemplate,
    ]
}

export default config;