Skip to content

Commit 5dd876f

Browse files
authored
feat!: Refactored CLI, Typed Flags, Updated Docs & Build (v0.2.0) (#2)
* refact!: Major refactor of the parser * fix(lint): apply linter fixes * feat!: complete CLI architecture redesign BREAKING CHANGE: Restructured the entire CLI implementation with a modular approach - Introduced namespaced architecture with Cli.Setup as main entry point - Added strongly typed flag system with validation - Implemented command tree-based parser - Added usage/help text generation - Introduced utility functions for type conversion Changes include: - Replaced monolithic Cli class with modular namespaces - Added dedicated parser with tree-based command resolution - Introduced TypedFlag system with built-in validation - Added built-in help text generation - Improved error handling and type safety - Added caching for better performance - Introduced string/number/boolean utilities Closes #1 * feat: enhance CLI flag handling to support multiple values * docs: update contributing guide file name * test: add unit tests for utility functions * test: add unit tests for UsageGenerator functionality * test: update Utils.isValidBoolean tests to include numeric values * test: add unit tests for Flag and Command classes * refactor: clean up comments and improve code readability in Parser * test: add unit tests for Parser functionality including Node, Tree, and Scope * refactor: simplify isValid and convert methods in Flags namespace * refactor: reorder imports for consistency and clarity in cli and usageGenerator files; update parser tests for improved import structure * test: add unit tests for TypedFlag class in Flags module to validate initialization, input validation, conversion, and default values * feat: introduce CliError class for improved error handling in CLI argument parsing * feat: export CliError from cli module for enhanced error handling * test: add comprehensive tests for Cli module covering setup, command and flag parsing, error handling, help generation, and default values * refactor: improve test descriptions for clarity and consistency across CLI and Flags modules * chore: add MIT License file to the repository * feat: add benchmarking capabilities for Climonad CLI framework * docs: update README and package.json for improved clarity and performance description * chore: bump version to 0.2.0 in package.json * fix: update package.json to correct module paths and exports configuration * feat: expand keywords in package.json for better discoverability * feat: enhance package.json with additional scripts and dependencies for improved testing and build processes * fix: update devDependencies in package.json to latest versions for improved compatibility and performance * fix: update Node.js engine version in package.json and package-lock.json to >=20.0.0
1 parent d1a2a6c commit 5dd876f

21 files changed

+2437
-592
lines changed
File renamed without changes.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Eduardo Marques Santos
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 126 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
> ⚠️ This library is in **early development**. APIs may change without notice.
44
5-
**A lightning-fast, lightweight library for building powerful command-line interfaces in Node.js.**
5+
**A high-performance, low-overhead library for building modern command-line interfaces in Node.js.**
66

77
## Table of Contents
88

99
- [Features](#features)
1010
- [Installation](#installation)
1111
- [Quick Start](#quick-start)
12+
- [Argument Parsing and Handling](#argument-parsing-and-handling)
1213
- [Performance](#performance)
1314
- [API Reference](#api-reference)
1415
- [Contributing](#contributing)
@@ -26,88 +27,167 @@
2627
### Define Your CLI
2728

2829
```javascript
29-
import { Cli, Cmd, Bool, Str, Num } from "climonad"
30+
import { Cli } from "climonad"
3031

3132
const cli = new Cli({
3233
name: "my-app",
3334
description: "A powerful CLI application",
35+
// Global Commands:
3436
commands: [
35-
new Cmd({
37+
Cli.cmd({
3638
name: "init",
3739
description: "Initialize the project",
38-
alias: "i",
39-
fn: () => console.log("Project initialization started..."),
4040
}),
41-
new Cmd({
41+
Cli.cmd({
4242
name: "build",
4343
description: "Build the project",
44-
alias: "b",
45-
fn: (data) => {
46-
console.log(`Building... (verbose: ${data.options.verbose}, output: ${data.options.output})`)
47-
},
44+
// Command Scoped Options:
45+
options: [
46+
Cli.str({
47+
name: "output",
48+
flag: "--out",
49+
alias: "-o",
50+
description: "Set output directory",
51+
}),
52+
],
4853
}),
4954
],
50-
options: [
51-
new Bool({ name: "verbose", alias: "v", description: "Enable verbose output" }),
52-
new Str({ name: "output", alias: "o", description: "Specify output path" }),
53-
],
55+
// Global Options:
56+
options: [Cli.bool({ name: "verboseOption", flag: "--verbose", description: "Enable verbose output" })],
5457
})
5558

5659
cli.run(process.argv.slice(2))
5760
```
5861

59-
## Performance
62+
## Argument Parsing and Handling
6063

61-
> 💡 **Note**: These are preliminary metrics from an **early development version**. Climonad's API and performance are still evolving.
64+
Climonad uses a declarative configuration approach to define and parse CLI arguments. Here's how it works:
6265

63-
`Climonad` is engineered for speed, and early benchmarks highlight its efficiency. These benchmarks were conducted using **Deno's built-in `bench` tool**, ensuring consistent and reliable results:
66+
### Commands
6467

65-
| **Operation** | **Time (avg)** | **Ops/Second** |
66-
| ----------------------- | -------------- | -------------- |
67-
| CLI Initialization | ~309.4 ns | 3,232,000 |
68-
| Basic Command Execution | ~244.9 ns | 4,083,000 |
69-
| Command with Options | ~271.1 ns | 3,689,000 |
68+
Commands represent distinct actions or functionalities. For example, "build" or "serve". You define commands using `Cli.cmd()` and assign them descriptions, aliases, and options. During runtime, Climonad identifies the invoked command based on the first positional argument:
69+
70+
```javascript
71+
Cli.cmd({
72+
name: "serve",
73+
description: "Start the development server",
74+
alias: "s",
75+
})
76+
```
77+
78+
Users can invoke this command using `serve` or its alias `s`:
79+
80+
```bash
81+
my-app serve
82+
my-app s
83+
```
84+
85+
### Options
86+
87+
Options modify the behavior of commands. They are identified by flags (e.g., `--verbose`) or aliases (e.g., `-v`). Climonad supports different types of options:
88+
89+
- **Boolean Flags**: Toggle features on or off.
90+
- **String Options**: Accept string values.
91+
- **Number Options**: Accept numeric inputs.
92+
- **Default Values**: Provide fallbacks when options are not specified.
93+
94+
Example:
95+
96+
```javascript
97+
Cli.str({
98+
name: "host",
99+
flag: "--host",
100+
description: "Specify the hostname",
101+
default: "localhost",
102+
})
103+
Cli.num({
104+
name: "port",
105+
flag: "--port",
106+
description: "Set the port number",
107+
})
108+
Cli.bool({
109+
name: "verbose",
110+
flag: "--verbose",
111+
description: "Enable verbose logging",
112+
})
113+
```
114+
115+
Users can pass options as:
116+
117+
```bash
118+
my-app serve --host localhost --port 8080 --verbose
119+
```
70120

71-
## Testing Status 🧪
121+
### Parsing Logic
122+
123+
- **Positional Arguments**: Climonad identifies commands based on their position. For example, in `my-app serve`, "serve" is a positional argument matched to a command.
124+
- **Flag Arguments**: Options prefixed with `--` (or aliases like `-v`) are parsed and mapped to their respective definitions.
125+
- **Default Values**: If a flag is not provided, Climonad falls back to the default value defined in its configuration.
126+
127+
Example:
128+
129+
```javascript
130+
const result = cli.parse(["serve", "--host", "example.com", "--port", "3000"])
131+
```
72132

73-
> 🛠️ If you'd like to contribute by expanding test coverage, check out our [Contributing section!](#contributing-)
133+
Results in:
74134

75-
At this stage (v0.x.x), Climonad includes only a basic test to validate core functionality. Comprehensive tests for edge cases, integration scenarios, and performance are planned in upcoming releases.
135+
```js
136+
{
137+
"commands": Set(1) { "serve" },
138+
"options": Map(2) { "host" => "example.com", "port" => 3000 },
139+
"generateHelp": [Function (anonymous)]
140+
}
141+
```
76142

77-
## API Reference
143+
### Auto Help Generation
78144

79-
### `Cli`
145+
Climonad provides built-in support for command-scoped help generation. Users can invoke the `-h` or `--help` flag to display detailed help information:
80146

81-
The main class for defining and running CLI applications.
147+
- **Global Help**: When used without a command, it shows help for the entire CLI application.
148+
- **Command-Scoped Help**: When used with a command, it displays help specific to that command.
82149

83-
#### Constructor
150+
Example:
84151

85-
```typescript
86-
new Cli({
87-
name: string,
88-
description: string,
89-
commands?: Cmd[],
90-
options?: Option[],
91-
});
152+
```bash
153+
my-app --help
154+
my-app serve --help
92155
```
93156

94-
#### Methods
157+
This feature is automatically enabled, requiring no additional configuration.
158+
159+
### Error Handling
160+
161+
Climonad provides robust error handling for invalid or unknown arguments. For example:
162+
163+
- If a required command or option is missing, it throws a `CliError`.
164+
- If an invalid value is provided for a typed option (e.g., `--port not-a-number`), it raises an appropriate error.
165+
166+
## Performance
167+
168+
> 💡 **Note**: These are preliminary metrics from an **early development version**. Climonad's API and performance are still evolving.
95169
96-
- `run(args: string[])`: Parse and execute CLI commands.
170+
These [`benchmarks`](test/bench.ts) were conducted using **Deno's built-in [`bench`](https://docs.deno.com/api/deno/~/Deno.bench) tool**, ensuring consistent and reliable results:
97171

98-
### `Cmd`
172+
| **Operation** | **Time (avg)** | **Ops/Second** |
173+
| ----------------------- | -------------- | -------------- |
174+
| CLI Initialization | ~725.4 ns | 1,379,000 |
175+
| Basic Command Execution | ~190.5 ns | 5,249,000 |
176+
| Command with Options | ~654.5 ns | 1,528,000 |
99177

100-
Define commands with a name, description, and execution function.
178+
### Algorithmic Complexity (Latest Update)
101179

102-
### Option Types
180+
- **CLI Initialization**: O(n) where n is the total number of commands and options being registered
181+
- **Command/Option Lookup**: O(1) using an optimized tree structure with path caching
182+
- **Argument Parsing**: O(n) where n is the number of input arguments
183+
- **Help Generation**: O(m) where m is the number of commands/options in the current scope
184+
- **Space Complexity**: O(n) where n is the total number of registered commands and options, with a small additional overhead for the path cache which improves lookup performance.
103185

104-
- `Bool`: Boolean flags (`--verbose`).
105-
- `Str`: String options (`--output path`).
106-
- `Num`: Numeric options (`--buildNumber 42`).
186+
Climonad is now highly efficient for both small scripts and large CLI applications with many commands and options.
107187

108188
## Contributing 🤝
109189

110-
[We love contributions!](/CONTRIBUTIONS_GUIDE.md) Here’s how you can help:
190+
[We love contributions!](/CONTRIBUTING_GUIDE.md) Here’s how you can help:
111191

112192
1. 🐛 **Report Bugs**: Found a bug? [Open an issue](https://github.com/supitsdu/climonad/issues).
113193
2. 💡 **Suggest Features**: Got an idea? Let us know by opening an issue.
@@ -118,4 +198,4 @@ Define commands with a name, description, and execution function.
118198

119199
## License
120200

121-
MIT License © 2024
201+
Licensed under the [MIT License](LICENSE).

0 commit comments

Comments
 (0)