icore 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/readme.md +51 -103
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "icore",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Declarative command line interface mechanics for Node.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"command-line",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
22
|
-
"url": "
|
|
22
|
+
"url": "git@github.com:woodger/icore.git"
|
|
23
23
|
},
|
|
24
24
|
"main": "dist/index.js",
|
|
25
25
|
"types": "dist/index.d.ts",
|
package/readme.md
CHANGED
|
@@ -7,48 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
Small dependency-free command line interface mechanics for [Node.js®](https://nodejs.org) applications.
|
|
9
9
|
|
|
10
|
+
[API](#api) | [Option Schemas](#option-schemas) | [Type Inference](#type-inference)
|
|
11
|
+
|
|
10
12
|
### How it works?
|
|
11
13
|
|
|
12
14
|

|
|
13
15
|
|
|
14
|
-
`icore` helps describe CLI commands with small option schemas and keeps command
|
|
15
|
-
handlers focused on application work. It standardizes argument parsing,
|
|
16
|
-
primitive option validation, defaults, choices, numeric ranges, and positional
|
|
17
|
-
argument checks. It can also resolve commands from a registry and report whether
|
|
18
|
-
each option was provided explicitly by the user or filled from a default.
|
|
19
|
-
|
|
20
|
-
## Non-goals
|
|
21
|
-
|
|
22
|
-
`icore` stops at CLI mechanics. It does not build API DTOs, call SDKs,
|
|
23
|
-
format output, manage process lifecycle, or validate business rules.
|
|
24
|
-
|
|
25
|
-
## Table of Contents
|
|
26
|
-
|
|
27
|
-
- [Installation](#installation)
|
|
28
|
-
- [Requirements](#requirements)
|
|
29
|
-
- [Non-goals](#non-goals)
|
|
30
|
-
- [Why icore?](#why-icore)
|
|
31
|
-
- [Supported Syntax](#supported-syntax)
|
|
32
|
-
- [Basic Usage](#basic-usage)
|
|
33
|
-
- [Design Goals](#design-goals)
|
|
34
|
-
- [What icore Handles](#what-icore-handles)
|
|
35
|
-
- [What icore Does Not Handle](#what-icore-does-not-handle)
|
|
36
|
-
- [Option Schemas](#option-schemas)
|
|
37
|
-
- [API](#api)
|
|
38
|
-
|
|
39
|
-
## Installation
|
|
40
|
-
|
|
41
|
-
```sh
|
|
42
|
-
npm install icore
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Requirements
|
|
46
|
-
|
|
47
|
-
- Node.js `>=16.9.0`
|
|
48
|
-
- TypeScript is supported through bundled declaration files.
|
|
49
|
-
|
|
50
|
-
## Why icore?
|
|
51
|
-
|
|
52
16
|
Use `icore` when you need more than raw argument parsing:
|
|
53
17
|
|
|
54
18
|
- typed command definitions;
|
|
@@ -62,20 +26,38 @@ Use `icore` when you need more than raw argument parsing:
|
|
|
62
26
|
Use [`node:util.parseArgs`](https://nodejs.org/api/util.html#utilparseargsconfig)
|
|
63
27
|
directly when you only need low-level argument parsing.
|
|
64
28
|
|
|
65
|
-
|
|
29
|
+
### Installation
|
|
66
30
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
31
|
+
To use `icores` in your project, run:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
npm install icore
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Table of Contents
|
|
38
|
+
|
|
39
|
+
- [`parseArgv(args, schema?)`](#parseargvargs-schema)
|
|
40
|
+
- [`parseOptions(schema, values)`](#parseoptionsschema-values)
|
|
41
|
+
- [`parseOptionsDetailed(schema, values)`](#parseoptionsdetailedschema-values)
|
|
42
|
+
- [`defineCommand(command)`](#definecommandcommand)
|
|
43
|
+
- [`defineCommandRegistry(commands)`](#definecommandregistrycommands)
|
|
44
|
+
- [`isCommandName(registry, value)`](#iscommandnameregistry-value)
|
|
45
|
+
- [`resolveCommand(registry, positionals)`](#resolvecommandregistry-positionals)
|
|
46
|
+
- [`resolveCommandFromArgs(registry, args)`](#resolvecommandfromargsregistry-args)
|
|
47
|
+
- [`runCommandFromRegistry(registry, args, context)`](#runcommandfromregistryregistry-args-context)
|
|
48
|
+
- [`mergeOptionsSchema(...schemas)`](#mergeoptionsschemaschemas)
|
|
49
|
+
- [`runCommand(command, args, context)`](#runcommandcommand-args-context)
|
|
50
|
+
|
|
51
|
+
### Design Goals
|
|
52
|
+
|
|
53
|
+
- describe CLI mechanics declaratively;
|
|
54
|
+
- use literal option types: `type: 'string' | 'boolean' | 'number'`;
|
|
55
|
+
- keep handlers free from repetitive option parsing;
|
|
56
|
+
- keep domain and API semantics outside the framework;
|
|
57
|
+
- provide predictable user-facing errors;
|
|
58
|
+
- avoid runtime dependencies.
|
|
77
59
|
|
|
78
|
-
|
|
60
|
+
#### Basic Usage
|
|
79
61
|
|
|
80
62
|
```ts
|
|
81
63
|
import { defineCommand, runCommand } from 'icore';
|
|
@@ -119,47 +101,6 @@ const {
|
|
|
119
101
|
} = require('icore');
|
|
120
102
|
```
|
|
121
103
|
|
|
122
|
-
## Design Goals
|
|
123
|
-
|
|
124
|
-
- describe CLI mechanics declaratively;
|
|
125
|
-
- use literal option types: `type: 'string' | 'boolean' | 'number'`;
|
|
126
|
-
- keep handlers free from repetitive option parsing;
|
|
127
|
-
- keep domain and API semantics outside the framework;
|
|
128
|
-
- provide predictable user-facing errors;
|
|
129
|
-
- avoid runtime dependencies.
|
|
130
|
-
|
|
131
|
-
## What icore Handles
|
|
132
|
-
|
|
133
|
-
`icore` handles generic CLI mechanics:
|
|
134
|
-
|
|
135
|
-
- parsing long options;
|
|
136
|
-
- validating known options;
|
|
137
|
-
- rejecting duplicated options;
|
|
138
|
-
- checking required options;
|
|
139
|
-
- applying and validating defaults;
|
|
140
|
-
- validating string choices;
|
|
141
|
-
- validating boolean flag form;
|
|
142
|
-
- composing option schemas;
|
|
143
|
-
- defining command registries;
|
|
144
|
-
- resolving commands by path;
|
|
145
|
-
- preserving user-provided option metadata;
|
|
146
|
-
- parsing numbers;
|
|
147
|
-
- validating integer, minimum, and maximum numeric constraints;
|
|
148
|
-
- checking command path and extra positional arguments.
|
|
149
|
-
|
|
150
|
-
## What icore Does Not Handle
|
|
151
|
-
|
|
152
|
-
`icore` intentionally does not handle application-specific behavior:
|
|
153
|
-
|
|
154
|
-
- building API request DTOs;
|
|
155
|
-
- calling SDKs or network clients;
|
|
156
|
-
- managing database, HTTP, or gRPC lifecycle;
|
|
157
|
-
- checking business invariants such as `from <= to`;
|
|
158
|
-
- resolving mutually exclusive command modes;
|
|
159
|
-
- formatting output as JSON, tables, CSV, or other application formats.
|
|
160
|
-
|
|
161
|
-
Keep those decisions near the command handler or in your application layer.
|
|
162
|
-
|
|
163
104
|
## Option Schemas
|
|
164
105
|
|
|
165
106
|
Options are described as plain objects.
|
|
@@ -227,7 +168,7 @@ const schema = {
|
|
|
227
168
|
Number options parse decimal numeric values and can validate integer and range
|
|
228
169
|
constraints. Defaults are validated with the same rules as user-provided values.
|
|
229
170
|
|
|
230
|
-
|
|
171
|
+
### API
|
|
231
172
|
|
|
232
173
|
### `parseArgv(args, schema?)`
|
|
233
174
|
|
|
@@ -540,7 +481,7 @@ const output = await runCommand(
|
|
|
540
481
|
By default, extra positionals are rejected. A command can opt in to extra
|
|
541
482
|
positionals with `allowExtraPositionals: true`.
|
|
542
483
|
|
|
543
|
-
|
|
484
|
+
### Type Inference
|
|
544
485
|
|
|
545
486
|
Use `InferOptions` when you need the parsed option type explicitly.
|
|
546
487
|
|
|
@@ -606,7 +547,22 @@ type Name = CommandName<typeof usersGetAccountsCommand>;
|
|
|
606
547
|
type Name = 'users get-accounts';
|
|
607
548
|
```
|
|
608
549
|
|
|
609
|
-
|
|
550
|
+
### Facade of arguments
|
|
551
|
+
|
|
552
|
+
The table below provides examples of how to specify the syntax.
|
|
553
|
+
|
|
554
|
+
| Syntax | Supported | Notes |
|
|
555
|
+
|---|---:|---|
|
|
556
|
+
| `--name value` | yes | string and number options |
|
|
557
|
+
| `--name=value` | yes | string and number options |
|
|
558
|
+
| `--flag` | yes | boolean options |
|
|
559
|
+
| `--flag=true` | no | boolean options are flag-only |
|
|
560
|
+
| `-f` | no | short aliases are not supported |
|
|
561
|
+
| `--no-cache` | no | negative boolean flags are not supported |
|
|
562
|
+
| repeated options | no | duplicates are rejected |
|
|
563
|
+
| multiple values | no | arrays are not supported |
|
|
564
|
+
|
|
565
|
+
### Error Messages
|
|
610
566
|
|
|
611
567
|
`icore` throws regular `Error` objects with predictable user-facing messages.
|
|
612
568
|
Applications should treat these messages as display text, not as a
|
|
@@ -627,7 +583,7 @@ Expected '--depth' to be greater than or equal to 1
|
|
|
627
583
|
|
|
628
584
|
Applications can catch these errors and decide how to print them.
|
|
629
585
|
|
|
630
|
-
|
|
586
|
+
### Project Boundary
|
|
631
587
|
|
|
632
588
|
`icore` is intended to be a small CLI mechanics module. It should not grow into a
|
|
633
589
|
domain-specific framework for a particular SDK or API.
|
|
@@ -638,11 +594,3 @@ Good responsibilities for `icore`:
|
|
|
638
594
|
- command path checking;
|
|
639
595
|
- common argument errors;
|
|
640
596
|
- typed command handler input.
|
|
641
|
-
|
|
642
|
-
Responsibilities that should stay outside `icore`:
|
|
643
|
-
|
|
644
|
-
- business validation;
|
|
645
|
-
- SDK lifecycle management;
|
|
646
|
-
- provider-specific request modes;
|
|
647
|
-
- generated contract mapping;
|
|
648
|
-
- presentation formatting.
|