icore 1.0.6 → 1.0.7

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/readme.md +53 -53
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icore",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Declarative command line interface mechanics for Node.js",
5
5
  "keywords": [
6
6
  "command-line",
package/readme.md CHANGED
@@ -7,6 +7,13 @@
7
7
 
8
8
  Small dependency-free command line interface mechanics for [Node.js®](https://nodejs.org) applications.
9
9
 
10
+ Supports a practical GNU-style option syntax:
11
+
12
+ - long options: `--name value`, `--name=value`;
13
+ - boolean flags: `--flag`, `--flag=true`, `--flag=false`, `--no-flag`;
14
+ - short aliases: `-f`, `-n value`;
15
+ - option terminator: `--`.
16
+
10
17
  ### Installation
11
18
 
12
19
  To use `icore` in your project, run:
@@ -47,8 +54,8 @@ import { parseArgv } from 'icore';
47
54
  const argv = parseArgv([
48
55
  'hello',
49
56
  '--name',
50
- 'User',
51
- '--upper'
57
+ 'Alice',
58
+ '--uppercase'
52
59
  ]);
53
60
  ```
54
61
 
@@ -58,8 +65,8 @@ Result:
58
65
  {
59
66
  positionals: ['hello'],
60
67
  options: {
61
- name: 'User',
62
- upper: true
68
+ name: 'Alice',
69
+ uppercase: true
63
70
  }
64
71
  }
65
72
  ```
@@ -70,10 +77,10 @@ options without consuming the following positional argument:
70
77
  ```ts
71
78
  const argv = parseArgv([
72
79
  'hello',
73
- '--upper',
74
- 'User'
80
+ '--uppercase',
81
+ 'Alice'
75
82
  ], {
76
- upper: {
83
+ uppercase: {
77
84
  type: 'boolean'
78
85
  }
79
86
  });
@@ -83,9 +90,9 @@ Result:
83
90
 
84
91
  ```ts
85
92
  {
86
- positionals: ['hello', 'User'],
93
+ positionals: ['hello', 'Alice'],
87
94
  options: {
88
- upper: true
95
+ uppercase: true
89
96
  }
90
97
  }
91
98
  ```
@@ -102,12 +109,12 @@ const options = parseOptions({
102
109
  type: 'string',
103
110
  default: 'world'
104
111
  },
105
- upper: {
112
+ uppercase: {
106
113
  type: 'boolean'
107
114
  }
108
115
  } as const, {
109
- name: 'User',
110
- upper: true
116
+ name: 'Alice',
117
+ uppercase: true
111
118
  });
112
119
  ```
113
120
 
@@ -115,8 +122,8 @@ Result:
115
122
 
116
123
  ```ts
117
124
  {
118
- name: 'User',
119
- upper: true
125
+ name: 'Alice',
126
+ uppercase: true
120
127
  }
121
128
  ```
122
129
 
@@ -133,11 +140,11 @@ const result = parseOptionsDetailed({
133
140
  type: 'string',
134
141
  default: 'world'
135
142
  },
136
- upper: {
143
+ uppercase: {
137
144
  type: 'boolean'
138
145
  }
139
146
  } as const, {
140
- upper: true
147
+ uppercase: true
141
148
  });
142
149
  ```
143
150
 
@@ -147,11 +154,11 @@ Result:
147
154
  {
148
155
  options: {
149
156
  name: 'world',
150
- upper: true
157
+ uppercase: true
151
158
  },
152
159
  provided: {
153
160
  name: false,
154
- upper: true
161
+ uppercase: true
155
162
  }
156
163
  }
157
164
  ```
@@ -173,14 +180,14 @@ const command = defineCommand({
173
180
  type: 'string',
174
181
  default: 'world'
175
182
  },
176
- upper: {
183
+ uppercase: {
177
184
  type: 'boolean'
178
185
  }
179
186
  },
180
187
  async handle({ options }) {
181
188
  const message = `Hello, ${options.name}!`;
182
189
 
183
- return options.upper ? message.toUpperCase() : message;
190
+ return options.uppercase ? message.toUpperCase() : message;
184
191
  }
185
192
  });
186
193
  ```
@@ -235,7 +242,7 @@ import { resolveCommand } from 'icore';
235
242
  const resolved = resolveCommand(registry, [
236
243
  'hello',
237
244
  'formal',
238
- 'User'
245
+ 'Alice'
239
246
  ]);
240
247
  ```
241
248
 
@@ -246,7 +253,7 @@ Result:
246
253
  name: 'hello formal',
247
254
  path: ['hello', 'formal'],
248
255
  command: helloFormalCommand,
249
- positionals: ['User']
256
+ positionals: ['Alice']
250
257
  }
251
258
  ```
252
259
 
@@ -263,8 +270,8 @@ segments.
263
270
  const resolved = resolveCommandFromArgs(registry, [
264
271
  'hello',
265
272
  '--name',
266
- 'User',
267
- '--upper'
273
+ 'Alice',
274
+ '--uppercase'
268
275
  ]);
269
276
  ```
270
277
 
@@ -275,7 +282,7 @@ Resolves a command from a registry and runs its handler.
275
282
  ```ts
276
283
  const output = await runCommandFromRegistry(
277
284
  registry,
278
- ['hello', '--name', 'User', '--upper'],
285
+ ['hello', '--name', 'Alice', '--uppercase'],
279
286
  context
280
287
  );
281
288
  ```
@@ -299,7 +306,7 @@ const nameOptions = {
299
306
  } as const;
300
307
 
301
308
  const greetingOptions = {
302
- upper: {
309
+ uppercase: {
303
310
  type: 'boolean'
304
311
  }
305
312
  } as const;
@@ -315,7 +322,7 @@ handler.
315
322
  ```ts
316
323
  const output = await runCommand(
317
324
  command,
318
- ['hello', '--name', 'User', '--upper'],
325
+ ['hello', '--name', 'Alice', '--uppercase'],
319
326
  context
320
327
  );
321
328
  ```
@@ -325,7 +332,7 @@ positionals with `allowExtraPositionals: true`.
325
332
 
326
333
  ### How It Works
327
334
 
328
- ![yuml diagram](http://yuml.me/diagram/scruffy;dir:LR;/class/[*argv*%20{bg:gray}|External;hello%20--name%20User%20--upper]->[*matches*%20{bg:lavender}|System;parse,%20resolve,%20validate,%20infer]->[*typed%20result*%20{bg:honeydew}|Container;command=hello;%20name=User;%20upper=true]->[*your%20app*%20{bg:cornsilk}|System;business%20logic%20and%20output])
335
+ ![yuml diagram](http://yuml.me/diagram/scruffy;dir:LR;/class/[*argv*%20{bg:gray}|External;hello%20--name%20Alice%20--uppercase]->[*matches*%20{bg:lavender}|System;parse,%20resolve,%20validate,%20infer]->[*typed%20result*%20{bg:honeydew}|Container;command=hello;%20name=Alice;%20uppercase=true]->[*your%20app*%20{bg:cornsilk}|System;business%20logic%20and%20output])
329
336
 
330
337
 
331
338
  ### Example
@@ -340,20 +347,20 @@ const exampleCommand = defineCommand({
340
347
  type: 'string',
341
348
  default: 'world'
342
349
  },
343
- upper: {
350
+ uppercase: {
344
351
  type: 'boolean'
345
352
  }
346
353
  },
347
354
  async handle({ options }) {
348
355
  const message = `Hello, ${options.name}!`;
349
356
 
350
- return options.upper ? message.toUpperCase() : message;
357
+ return options.uppercase ? message.toUpperCase() : message;
351
358
  }
352
359
  });
353
360
 
354
361
  const output = await runCommand(
355
362
  exampleCommand,
356
- ['hello', '--name', 'User', '--upper'],
363
+ ['hello', '--name', 'Alice', '--uppercase'],
357
364
  {}
358
365
  );
359
366
 
@@ -363,8 +370,8 @@ console.log(output);
363
370
  Terminal output:
364
371
 
365
372
  ```console
366
- $ node cli.js hello --name User --upper
367
- HELLO, USER!
373
+ $ node cli.js hello --name Alice --uppercase
374
+ HELLO, ALICE!
368
375
  ```
369
376
 
370
377
  The command handler receives parsed options, user-provided option metadata,
@@ -386,7 +393,7 @@ const schema = {
386
393
  type: 'string',
387
394
  alias: 'n'
388
395
  },
389
- upper: {
396
+ uppercase: {
390
397
  type: 'boolean',
391
398
  alias: 'u'
392
399
  }
@@ -419,7 +426,7 @@ boolean flag form, and values outside `choices`.
419
426
 
420
427
  ```ts
421
428
  const schema = {
422
- upper: {
429
+ uppercase: {
423
430
  type: 'boolean'
424
431
  }
425
432
  } as const;
@@ -429,20 +436,20 @@ Boolean options accept **flag form**, explicit `true` / `false` values, and
429
436
  schema-known negation:
430
437
 
431
438
  ```sh
432
- --upper
433
- --upper=true
434
- --upper=false
435
- --no-upper
439
+ --uppercase
440
+ --uppercase=true
441
+ --uppercase=false
442
+ --no-uppercase
436
443
  ```
437
444
 
438
445
  Invalid explicit values are rejected:
439
446
 
440
447
  ```sh
441
- --upper=yes
442
- --upper=
448
+ --uppercase=yes
449
+ --uppercase=
443
450
  ```
444
451
 
445
- `--upper false` keeps `--upper` as `true` and leaves `false` as a positional
452
+ `--uppercase false` keeps `--uppercase` as `true` and leaves `false` as a positional
446
453
  argument.
447
454
 
448
455
  #### `type: 'number'`
@@ -474,7 +481,7 @@ const schema = {
474
481
  type: 'string',
475
482
  default: 'world'
476
483
  },
477
- upper: {
484
+ uppercase: {
478
485
  type: 'boolean'
479
486
  }
480
487
  } as const;
@@ -487,7 +494,7 @@ type Options = InferOptions<typeof schema>;
487
494
  ```ts
488
495
  type Options = {
489
496
  name: string;
490
- upper: boolean | undefined;
497
+ uppercase: boolean | undefined;
491
498
  };
492
499
  ```
493
500
 
@@ -529,13 +536,6 @@ type Name = 'hello formal';
529
536
 
530
537
  ### Facade of arguments
531
538
 
532
- Supports a practical GNU-style option syntax:
533
-
534
- - long options: `--name value`, `--name=value`;
535
- - boolean flags: `--flag`, `--flag=true`, `--flag=false`, `--no-flag`;
536
- - short aliases: `-f`, `-n value`;
537
- - option terminator: `--`.
538
-
539
539
  Use `--` to stop option parsing. The terminator itself is not included in
540
540
  positionals; every following token is treated as positional, even when it starts
541
541
  with `-`.
@@ -565,8 +565,8 @@ after printing `error.message`, terminal output can look like this:
565
565
  $ node cli.js hello --unknown
566
566
  Unexpected argument '--unknown'
567
567
 
568
- $ node cli.js hello --upper=yes
569
- Expected '--upper' as boolean flag
568
+ $ node cli.js hello --uppercase=yes
569
+ Expected '--uppercase' as boolean flag
570
570
 
571
571
  $ node cli.js hello --name=
572
572
  Expected '--name' as string