@kibibit/cli-lit

generate a lit CLI tool from a typescript class

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
@kibibit/cli-lit
151.5.55 years ago6 years agoMinified + gzip package size for @kibibit/cli-lit in KB

Readme

@kibibit/cli-lit

generate a :fire:lit:fire: CLI tool from a typescript class


Installation

Install Globally

npm i -g @kibibit/cli-lit 
and run it using
cli-lit --name <cli_name> --file <typescript_file> --class <exported_class>

Install Locally

npm i --save @kibibit/cli-lit
Then, you can add it to your package.json as a script:
"scripts": {
  // ...
  "generate-cli": "cli-lit --name <cli_name> --file <typescript_file> --class <exported_class>"
}
and run it using
npm run generate-cli

NPM Development Commands

When running npm install @kibibit/cli-lit, it will automatically compile the typescript decorators.
  • npm run compile - compile typescript decorators file to javascript
  • npm run build:doc - will compile a new README.md file based on general-readme.md and the decorators' jsdoc comments.

Examples

import * as request from 'request-promise';
import * as keytar from 'keytar';
import * as homeConfig from 'home-config';
import { description, cligroup, cliRename, cliOptionalParams, cliBeforeEach } from '@kibibit/cli-lit';

const cfg = homeConfig.load('.myConfigFile');

export class UserActions {
    /* Added FOR the CLI.
     * This will make sure the user is logged in
     * already and retrieve the user token to
     * pass to the function called. If the
     * user is not logged in, throw an error. */
    @cliBeforeEach()
    static getUserToken() {
        const loginErr = Error('Please run my-cli setup to login');

        if (!cfg.username) throw loginErr;

        return keytar.getToken('myCLI', cfg.username)
          .then((token) => {
              return {
                  token: token
              };
          })
          .catch((err) => {
              throw loginErr;
          });
    }

    /* Added FOR the CLI.
     * This will save the user token in the OS's keychain,
     * and the logged in username in a configuration
     * file called .myConfigFile in order to do this once and pass the token using the getUserToken function */
    @cliAfterEach()
    static saveUserToken(functionName, returnValue, givenParams) {
        if (functionName === 'loginUser') {
            return keytar
                .setPassword('myCLI', givenParams.username, returnValue)
                .then(() => cfg.username = givenParams.username)
                .then(() => cfg.save())
        }
    }

    @cliRename('setup')
    @clidescription(`Initial setup to use the CLI`)
    static loginUser(username, password) {
        const options = createLoginOptions(username, password);

        return request(options);
    }

    @cliRename('set')
    @clidescription(`Set the logged in user's email`)
    @cligroup('user.email')
    static setEmail(token, email) {
        const options = postOptions('/user', token, {
            email: email
        });

        return request(options);
    }

    @cliRename('get')
    @clidescription(`Get the logged in user's email`)
    @cligroup('user.email')
    static getEmail(token) {
        const options = getOptions('/user/email', token);

        return request(options);
    }

    @cliRename('publish')
    @clidescription(`Publish a new blog piece`)
    @cligroup('user.blog')
    static postBlog(token, title, markdown) {
        const options = postOptions('/blog', token, {
            title: title,
            body: markdown
        });

        return request(options);
    }

    @cliRename('read')
    @clidescription(`Read a blog piece. Get's a title as a search term`)
    @cligroup('user.blog')
    static getBlog(token, title) {
        const options = getOptions(`/blog/${title}`, token);

        return request(options);
    }
}

Available Decorators

Functions

cliDescription(...args)

Create a description for the CLI. That description will be displayed when calling the function with -h or --help. This is usually a one liner summary of what the function does.

cliGroup(cliGroup)

Create a group or several groups for the function in CLI form. To create a nested group inside a group, you can chain the group names with a ..

cliRename(newFunctionName)

Give this function a different name in CLI mode. This is usually combined with @cliGroup to allow function hierarchy, like nesting set and get functions inside a group.

cliOptionalParams(optionalArray)

Optional params for this function. Usually when a default value is set to that param in typescript or passed from the @cliBeforeEach function

cliHiddenParams(hiddenArray)

HIDDEN params for this function. Usually when a beforeEach function passes that argument instead

cliBeforeEach()

Runs before all function called. The function should return an object with keys as input names and value as the value passed. You can also return a promise that resolves to an object. For example, you might want to fetch a token from the system's keychain in order to do an http request, or ask the user to input a username and password in an inquirer.js manner

cliAfterEach()

runs after all functions called.

cliIgnore()

Ignore this function when translating the class into a CLI.


cliDescription(...args)

Create a description for the CLI. That description will be displayed when calling the function with -h or --help. This is usually a one liner summary of what the function does.


Kind: global function
| Param | Description | | --- | --- | | ...args |

the description of the function

|
Example
.@cliDescription(`get the user's info`)
static getUserInfo(userId) { ... }

cliGroup(cliGroup)

Create a group or several groups for the function in CLI form. To create a nested group inside a group, you can chain the group names with a ..


Kind: global function
| Param | Type | Description | | --- | --- | --- | | cliGroup | string |

The group path string. every inner group is separated by a dot (.)

|
Example
// will create a cli command:
// $ cli user info get <user_id>
.@cliRename('get')
.@cliGroup('user.info')
static getUserInfo(userId) { ... }

cliRename(newFunctionName)

Give this function a different name in CLI mode. This is usually combined with @cliGroup to allow function hierarchy, like nesting set and get functions inside a group.


Kind: global function
| Param | Type | Description | | --- | --- | --- | | newFunctionName | string |

the new function name

|
Example
// will create a cli command:
// $ cli get <user_id>
.@cliRename('get')
static getUserInfo(userId) { ... }

cliOptionalParams(optionalArray)

Optional params for this function. Usually when a default value is set to that param in typescript or passed from the @cliBeforeEach function


Kind: global function
| Param | Type | Description | | --- | --- | --- | | optionalArray | Array.<string> |

array of optional params

|
Example
// will create a cli command:
// $ cli renameUser <new_name>
.@cliOptionalParams(['newName'])
static renameUser(newName: string = randomName()) { ... }

cliHiddenParams(hiddenArray)

HIDDEN params for this function. Usually when a beforeEach function passes that argument instead


Kind: global function
| Param | Type | Description | | --- | --- | --- | | hiddenArray | Array.<string> |

array of hidden params

|
Example
// won't ask the user to set a token.
.@cliHiddenParams(['token'])
static getUserInfo(token: string, ) { ... }

cliBeforeEach()

Runs before all function called. The function should return an object with keys as input names and value as the value passed. You can also return a promise that resolves to an object. For example, you might want to fetch a token from the system's keychain in order to do an http request, or ask the user to input a username and password in an inquirer.js manner


Kind: global function
Example
// won't ask the user to set a token.
.@cliBeforeEach()
static fetchTokenFromKeychain() {
  return keytar.getPassword(cfg.username)
    .then((token) => ({ token: token }))
    .catch(() => throw new Error('user not logged in'));
}

cliAfterEach()

runs after all functions called.


Kind: global function
Example
.@cliAfterEach()
static logResult(functionName, returnValue, givenParams) {
  console.log('function result: ', returnValue);
}

cliIgnore()

Ignore this function when translating the class into a CLI.


Kind: global function
Example
.@cliIgnore()
static dontTraslate(arg) { ... }

Contributing

If you have suggestions for how @kibibit/cli-lit could be improved, or want to report a bug, open an issue! We'd love all and any contributions.
For more, check out the Contributing Guide.

Contributors

Neil Kalman
Neil Kalman

🚇 🎨 💻

License

MIT © 2019 Neil Kalman