https://github.com/lillallol/fn-to-cli
Converts typescript functions to node CLI executable.
https://github.com/lillallol/fn-to-cli
cli cli-generator
Last synced: 2 months ago
JSON representation
Converts typescript functions to node CLI executable.
- Host: GitHub
- URL: https://github.com/lillallol/fn-to-cli
- Owner: lillallol
- License: mit
- Created: 2021-03-05T16:47:05.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2021-05-14T14:58:42.000Z (about 4 years ago)
- Last Synced: 2025-03-03T07:48:08.789Z (3 months ago)
- Topics: cli, cli-generator
- Language: TypeScript
- Homepage:
- Size: 939 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# fn-to-cli
## Table of contents
- [fn-to-cli](#fn-to-cli)
- [Table of contents](#table-of-contents)
- [Installation](#installation)
- [Description](#description)
- [Code coverage](#code-coverage)
- [Quick start](#quick-start)
- [Example](#example)
- [Documentation](#documentation)
- [Motivation](#motivation)
- [Contributing](#contributing)
- [Changelog](#changelog)
- [2.0.3](#203)
- [2.0.2](#202)
- [2.0.1](#201)
- [2.0.0](#200)
- [1.0.0](#100)
- [License](#license)## Installation
```bash
npm install fn-to-cli
```## Description
This module converts typescript functions to CLI.
## Code coverage
Code coverage is around 90%.
## Quick start
For a quick start:
0. execute from terminal:
```bash
npx fn-to-cli --help;
```1. add `@CLI` JSDoc tag comment to the functions you want to convert to CLI
2. compile your typescript project to javascript project
3. execute from terminal:```bash
npx fn-to-cli;
```If something goes wrong you will receive helpful error messages that will guide you on resolving the error.
## Example
1. Create a new folder and set it as your current working directory:
```bash
mkdir example; cd ./example;
```2. Create `./package.json` with the following content:
```json
{
"name": "some-random-package-name",
"version": "1.0.0",
"private": true,
"main": "./dist/index.js",
"bin": "bin/bin.js",
"scripts": {
"build-ts": "rm -rf ./dist; npx tsc",
"build-bin": "rm -rf ./bin; npx fn-to-cli",
"build": "npm run build-ts && npm run build-bin",
"test": "jest"
},
"devDependencies": {
"jest": "^26.6.3",
"typescript": "^4.2.3"
},
"dependencies": {
"fn-to-cli": "file:.."
}
}
```
Notice the bin property in `./package.json`. This is used by `fn-to-cli` as a path to output the generated CLI.
3. Delete from `./package.json` the line:
```bash
"fn-to-cli": "../"
```4. Install `fn-to-cli`:
```bash
npm install fn-to-cli;
```this will also install the rest of the dependencies.
5. Create `./tsconfig.json` with the following content:
```json
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"module": "CommonJS",
"target": "ESNext",
"declaration": true
},
"exclude": [
"node_modules"
]
}
```
6. Create `./src/index.ts` with the following content:
```ts
export { foo } from "./foo";
```
7. Create `./src/foo.ts` with the following content:
```ts
/**
* Some tag less description for command foo.
* @CLI
*/
export function foo(_: {
/**
* @description
* Some tag full description for option `a` of command `foo`.
*/
a: string;
/**
* Some tag less description for option `b` of command `foo`.
* @default true
* @flag V
*/
b?: boolean;
}): void {
const { a } = _;
let { b } = _;
if (b === undefined) b = true;
console.log(`foo executed with a = "${a}", b = ${b}`);
}
```
8. Create `./src/bar/bar.ts` with the following content:
```ts
/**
* @description
* Some tag full description for command `bar`.
* @CLI baz
*/
export default function bar(_: {
/**
* Some tag less description for option `c` of command `bar`.
*/
c: boolean;
/**
* Some tag less description for option `d` of command `bar`.
* @private
* @default true
*/
d?: boolean;
}): void {
const { c } = _;
let { d } = _;
if (d === undefined) d = true;
console.log(`bar executed with c = ${c}, d = ${d}`);
}
```
9. Execute:
```bash
npm run build;
```This command does two things:
- builds typescript to javascript
- generates the CLI10. Now you can use the generated CLI. Here are some examples:
```bash
node ./bin/bin.js foo --a "'hello'";
node ./bin/bin.js foo --a "'hello'" -V "false";
node ./bin/bin.js baz --c "false";
```
## Documentation
Execute the following command:
```bash
npx fn-to-cli --help
```to get the CLI documentation:
```txt
CLI syntax:fn-to-cli fnToCLI? [[-- | -] ]#
Description:
Converts typescript functions to CLI.
Non required options:
-t --pathToTsconfig : string = "./tsconfig.json" Path to `tsconfig.json`.
-p --pathToPackageJson : string = "./package.json" Path to `package.json`.
-s --strict : boolean = false For one command CLI, it is optional to write the command name when using the CLI. Give `true` to disable that.```
The CLI generator works by searching deeply in the directory defined by the property `compilerOptions.outDir` of `tsconfig.json`, for all the `.d.ts` files that have functions with `@CLI` JSDoc tag. These functions become commands to the generated CLI.
The generated CLI is saved to the path defined by the `bin` property of `package.json`, and imports js functions from the directories `compilerOptions.outDir`, and `node_modules`, so it will not work if these folders are missing or moved.
Each function with the `@CLI` JSDoc tag has to:
1. have a single parameter that is `TypeLiteral`, for example:
```
{
param1 : string,
param2 : boolean
}
```2. be a function declaration statement, for example:
- incorrect:
```ts
const foo = () => {
//some code
};
```- correct:
```ts
function foo() {
//some code
}
```3. be named or default exported
4. have name
5. have description in its JSDoc comment via a `@description` tag or tag-less
6. same for each property in its parameter type signature
7. have `@default` JSDoc tag with initialization value for each optional parameter
8. be inside the `rootDir` directory as defined by the provided `tsconfig.json`
9. be in a `.ts` fileThe functions can have:
1. `@flag` JSDoc tag for any of its properties. It has to have a single letter as a value which can be used instead of the parameter names in the CLI.
2. `@cliPrivate` JSDoc tag for any of its optional properties. These properties will not be visible in the documentation of the CLI and will not receive a value even if the user of the CLI provides one for them.## Motivation
A typescript function with JSDoc comments, contains all the necessary information to be converted automatically to a cli. Why would anyone waste their time doing the conversion manually? Automating that is the only maintainable solution.
## Contributing
I am open to suggestions/pull request to improve this program.
You will find the following commands useful:
- Clones the github repository of this project:
```bash
git clone https://github.com/lillallol/fn-to-cli
```- Installs the node modules (nothing will work without them):
```bash
npm install
```- Tests the source code:
```bash
npm run test-src
```- Tests the example in the example folder:
```bash
npm run test-example
```- Lints the source folder using typescript and eslint:
```bash
npm run lint
```- Builds the typescript code from the `./src` folder to javascript code in `./dist`:
```bash
npm run build-ts
```- Creates the CLI executable of this program in `./bin/bin.js`:
```bash
npm run build-bin
```Make sure that the `./dist` exists when you execute this command, otherwise it will not work.
- Injects in place the generated toc and imported files to `README.md`:
```bash
npm run build-md
```- Checks the project for spelling mistakes:
```bash
npm run spell-check
```Take a look at the related configuration `./cspell.json`.
- Checks `./src` for dead typescript files:
```bash
npm run dead-files
```Take a look at the related configuration `./unimportedrc.json`.
## Changelog
### 2.0.3
Removed package name and version from the CLI generated documentation.
### 2.0.2
Removed the unnecessary quotation marks from the default values in the CLI generated documentation.
### 2.0.1
**bug fixes:**
Moved `typescript-is` from development dependencies to dependencies.
### 2.0.0
**breaking changes**:
- Command line arguments are now evaluated with `eval` instead of `JSON.parse`.
- `-v` and `--version` are reserved for printing the version.
- `@private` JSDoc tag is now replaced with `@cliPrivate`.
- The `@CLI` JSDoc tag can now get a value as a custom name for the command.**non breaking changes**
- `json5` node module is used for parsing `package.json` and `tsconfig.json`. That means (among others) no more headaches with trailing commas.
- You can now add any type you want for command options.
- The default JSDoc tag value is no longer validated that it is the same type as the argument type.**other**
- `README.md` has been improved and extra sections like changelog and contributing have been added. You can read the example section code in the `README.md` now.
### 1.0.0
- Published the package to npm.
## License
MIT