fn-to-cli
v2.0.3
Published
Convert typescript functions to CLI executables.
Downloads
53
Maintainers
Readme
fn-to-cli
Table of contents
Installation
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:
execute from terminal:
npx fn-to-cli --help;
add
@CLI
JSDoc tag comment to the functions you want to convert to CLIcompile your typescript project to javascript project
execute from terminal:
npx fn-to-cli;
If something goes wrong you will receive helpful error messages that will guide you on resolving the error.
Example
Create a new folder and set it as your current working directory:
mkdir example; cd ./example;
Create
./package.json
with the following content:{ "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 byfn-to-cli
as a path to output the generated CLI.Delete from
./package.json
the line:"fn-to-cli": "../"
Install
fn-to-cli
:npm install fn-to-cli;
this will also install the rest of the dependencies.
Create
./tsconfig.json
with the following content:{ "compilerOptions": { "rootDir": "./src", "outDir": "./dist", "module": "CommonJS", "target": "ESNext", "declaration": true }, "exclude": [ "node_modules" ] }
Create
./src/index.ts
with the following content:export { foo } from "./foo";
Create
./src/foo.ts
with the following content:/** * 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}`); }
Create
./src/bar/bar.ts
with the following content:/** * @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}`); }
Execute:
npm run build;
This command does two things:
- builds typescript to javascript
- generates the CLI
Now you can use the generated CLI. Here are some examples:
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:
npx fn-to-cli --help
to get the CLI documentation:
CLI syntax:
fn-to-cli fnToCLI? [[--<option> | -<flag>] <value>]#
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:
have a single parameter that is
TypeLiteral
, for example:{ param1 : string, param2 : boolean }
be a function declaration statement, for example:
incorrect:
const foo = () => { //some code };
correct:
function foo() { //some code }
be named or default exported
have name
have description in its JSDoc comment via a
@description
tag or tag-lesssame for each property in its parameter type signature
have
@default
JSDoc tag with initialization value for each optional parameterbe inside the
rootDir
directory as defined by the providedtsconfig.json
be in a
.ts
file
The functions can have:
@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.@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:
git clone https://github.com/lillallol/fn-to-cli
Installs the node modules (nothing will work without them):
npm install
Tests the source code:
npm run test-src
Tests the example in the example folder:
npm run test-example
Lints the source folder using typescript and eslint:
npm run lint
Builds the typescript code from the
./src
folder to javascript code in./dist
:npm run build-ts
Creates the CLI executable of this program in
./bin/bin.js
: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
:npm run build-md
Checks the project for spelling mistakes:
npm run spell-check
Take a look at the related configuration
./cspell.json
.Checks
./src
for dead typescript files: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 ofJSON.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 parsingpackage.json
andtsconfig.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 theREADME.md
now.
1.0.0
- Published the package to npm.
License
MIT