@thi.ng/args 3.0.0 → 3.1.1

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2025-09-26T11:53:06Z
3
+ - **Last updated**: 2025-09-26T13:50:05Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -11,6 +11,20 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
11
11
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
12
12
  and/or version bumps of transitive dependencies.
13
13
 
14
+ ## [3.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/args@3.1.0) (2025-09-26)
15
+
16
+ #### 🚀 Features
17
+
18
+ - add ARG_TYPES index ([5f68489](https://github.com/thi-ng/umbrella/commit/5f68489))
19
+
20
+ #### ♻️ Refactoring
21
+
22
+ - update factory fns to only take single arg (spec) ([2766125](https://github.com/thi-ng/umbrella/commit/2766125))
23
+ - update `oneOf`, `oneOfMulti`, `tuple`, `size`, `vec`
24
+ - fix `required`-handling in `ARG_OUT_DIR` & `ARG_OUT_FILE` presets
25
+ - fix code example for `tuple()`
26
+ - update tests
27
+
14
28
  # [3.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/args@3.0.0) (2025-09-26)
15
29
 
16
30
  #### 🛑 Breaking changes
package/README.md CHANGED
@@ -102,8 +102,12 @@ section](#projects-using-this-package) in this readme.
102
102
 
103
103
  - Required arguments are now to be specified using either `required: true` or
104
104
  given a `default` value
105
- - Tuple argument order has been swapped (to be more aligned with `size` and
106
- `vec`) to: `tuple(size, coerce, {...})`
105
+ - All factory functions now only accept a single arg spec, with any type-specific
106
+ options moved into the spec, for example:
107
+ - old: `oneOf(["a","b","c"], {...})`
108
+ - new: `oneOf({ opts: ["a","b","c"], ...})`
109
+ - old: `tuple(identity, 3, {...})`
110
+ - new: `tuple({ size: 3, coerce: identity, ...})`
107
111
  - Where applicable, `delim`iters are now to be included in the arg spec (rather
108
112
  than given as separate function arg)
109
113
 
@@ -125,7 +129,7 @@ For Node.js REPL:
125
129
  const args = await import("@thi.ng/args");
126
130
  ```
127
131
 
128
- Package sizes (brotli'd, pre-treeshake): ESM: 3.39 KB
132
+ Package sizes (brotli'd, pre-treeshake): ESM: 3.47 KB
129
133
 
130
134
  ## Dependencies
131
135
 
@@ -220,20 +224,21 @@ const specs: Args<TestArgs> = {
220
224
  }),
221
225
 
222
226
  // enum value (mandatory)
223
- type: oneOf(["png", "jpg", "gif", "tiff"], {
227
+ type: oneOf({
224
228
  alias: "t",
225
229
  desc: "Image type",
230
+ opts: ["png", "jpg", "gif", "tiff"],
226
231
  // mandatory args require a `default` value and/or `required: true`
227
232
  required: true,
228
233
  }),
229
234
 
230
235
  // fixed size numeric tuple w/ `x` as delimiter
231
- size: size(2, { hint: "WxH", desc: "Target size", delim: "x" }),
236
+ size: size({ size: 2, hint: "WxH", desc: "Target size", delim: "x" }),
232
237
  // syntax sugar for:
233
238
  // size: tuple(2, coerceInt, { hint: "WxH", desc: "Target size" }, "x"),
234
239
 
235
240
  // another version for tuples of floating point values
236
- pos: vec(2, { desc: "Lat/Lon coordinates", hint: "LAT,LON" }),
241
+ pos: vec({ size: 2, desc: "Lat/Lon coordinates", hint: "LAT,LON" }),
237
242
  // syntax sugar for:
238
243
  // pos: tuple(2, coerceFloat, { desc: "Lat/Lon" }),
239
244
 
package/args.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type Fn } from "@thi.ng/api/fn";
2
- import type { ArgDef, ArgDefRequired, KVDict, KVMultiDict, Tuple } from "./api.js";
2
+ import type { ArgDef, ArgDefRequired, ArgSpec, KVDict, KVMultiDict, Tuple } from "./api.js";
3
3
  /**
4
4
  * Returns a full {@link ArgSpec} for a boolean flag. The mere presence of this
5
5
  * arg will enable the flag.
@@ -133,7 +133,9 @@ export declare const hexes: <S extends ArgDef | ArgDefRequired<unknown[]>>(spec:
133
133
  * @param opts -
134
134
  * @param spec -
135
135
  */
136
- export declare const oneOf: <K extends string, S extends ArgDef | ArgDefRequired<K>>(opts: readonly K[], spec: S) => S & {
136
+ export declare const oneOf: <K extends string, S extends ArgDef | ArgDefRequired<K>>(spec: S & {
137
+ opts: readonly K[];
138
+ }) => S & {
137
139
  type: "oneOf";
138
140
  coerce: Fn<string, K>;
139
141
  desc: string;
@@ -149,7 +151,8 @@ export declare const oneOf: <K extends string, S extends ArgDef | ArgDefRequired
149
151
  * @param opts -
150
152
  * @param spec -
151
153
  */
152
- export declare const oneOfMulti: <K extends string, S extends ArgDef | ArgDefRequired<K>>(opts: readonly K[], spec: S & {
154
+ export declare const oneOfMulti: <K extends string, S extends ArgDef | ArgDefRequired<K>>(spec: S & {
155
+ opts: readonly K[];
153
156
  delim?: string;
154
157
  }) => S & {
155
158
  type: "oneOfMulti";
@@ -216,10 +219,18 @@ export declare const kvPairsMulti: <S extends ArgDef | ArgDefRequired<KVMultiDic
216
219
  *
217
220
  * @example
218
221
  * ```ts tangle:../export/tuple.ts
219
- * import { coerceInt, parse, tuple } from "@thi.ng/args";
222
+ * import { coerceInt, parse, tuple, type Tuple } from "@thi.ng/args";
223
+ *
224
+ * interface A {
225
+ * a?: Tuple<number>;
226
+ * }
220
227
  *
221
228
  * console.log(
222
- * parse({ a: tuple(2, coerceInt, {})}, ["--a", "1,2"])
229
+ * parse<A>(
230
+ * { a: tuple({ size: 2, coerce: coerceInt }) },
231
+ * ["--a", "1,2"],
232
+ * { start: 0 }
233
+ * )
223
234
  * );
224
235
  * // {
225
236
  * // result: { a: Tuple { value: [1, 2] } },
@@ -229,11 +240,11 @@ export declare const kvPairsMulti: <S extends ArgDef | ArgDefRequired<KVMultiDic
229
240
  * // }
230
241
  * ```
231
242
  *
232
- * @param size -
233
- * @param coerce -
234
243
  * @param spec -
235
244
  */
236
- export declare const tuple: <T, S extends ArgDef | ArgDefRequired<Tuple<T>>>(size: number, coerce: Fn<string, T>, spec: S & {
245
+ export declare const tuple: <T, S extends ArgDef | ArgDefRequired<Tuple<T>>>(spec: S & {
246
+ size: number;
247
+ coerce: Fn<string, T>;
237
248
  delim?: string;
238
249
  }) => S & {
239
250
  type: "tuple";
@@ -247,12 +258,16 @@ export declare const tuple: <T, S extends ArgDef | ArgDefRequired<Tuple<T>>>(siz
247
258
  * Syntax sugar for `tuple(size, coerceInt, {...})`. See {@link tuple} for
248
259
  * further details.
249
260
  *
250
- * @param size -
251
261
  * @param spec -
252
262
  */
253
- export declare const size: <S extends ArgDef | ArgDefRequired<Tuple<number>>>(size: number, spec: S & {
263
+ export declare const size: <S extends ArgDef | ArgDefRequired<Tuple<number>>>(spec: S & {
264
+ size: number;
254
265
  delim?: string;
255
266
  }) => S & {
267
+ coerce: (x: string) => number;
268
+ size: number;
269
+ delim?: string;
270
+ } & {
256
271
  type: "tuple";
257
272
  coerce: Fn<string, Tuple<number>>;
258
273
  hint: string;
@@ -264,12 +279,16 @@ export declare const size: <S extends ArgDef | ArgDefRequired<Tuple<number>>>(si
264
279
  * Syntax sugar for `tuple(size, coerceFloat, {...})`. See {@link tuple} for
265
280
  * further details.
266
281
  *
267
- * @param size -
268
282
  * @param spec -
269
283
  */
270
- export declare const vec: <S extends ArgDef | ArgDefRequired<Tuple<number>>>(size: number, spec: S & {
284
+ export declare const vec: <S extends ArgDef | ArgDefRequired<Tuple<number>>>(spec: S & {
285
+ size: number;
271
286
  delim?: string;
272
287
  }) => S & {
288
+ coerce: (x: string) => number;
289
+ size: number;
290
+ delim?: string;
291
+ } & {
273
292
  type: "tuple";
274
293
  coerce: Fn<string, Tuple<number>>;
275
294
  hint: string;
@@ -289,6 +308,10 @@ export declare const json: <T, S extends ArgDef | ArgDefRequired<T>>(spec: S) =>
289
308
  hint: string;
290
309
  group: string;
291
310
  };
311
+ /**
312
+ * Index which maps arg type IDs to their factory functions
313
+ */
314
+ export declare const ARG_TYPES: Record<string, Fn<any, ArgSpec<any>>>;
292
315
  /**
293
316
  * Re-usable preset arg spec for a `--dry-run` flag.
294
317
  */
package/args.js CHANGED
@@ -41,24 +41,22 @@ const int = defSingle("int", coerceInt, "INT");
41
41
  const ints = defMulti("ints", coerceInt, "INT");
42
42
  const hex = defSingle("hex", coerceHexInt, "HEX");
43
43
  const hexes = defMulti("hexes", coerceHexInt, "HEX");
44
- const oneOf = (opts, spec) => ({
44
+ const oneOf = (spec) => ({
45
45
  ...spec,
46
46
  type: "oneOf",
47
- coerce: coerceOneOf(opts),
47
+ coerce: coerceOneOf(spec.opts),
48
48
  hint: spec.hint ?? "ID",
49
- desc: __desc(opts, spec.desc),
50
49
  group: spec.group ?? "main",
51
- opts
50
+ desc: __desc(spec.opts, spec.desc)
52
51
  });
53
- const oneOfMulti = (opts, spec) => ({
52
+ const oneOfMulti = (spec) => ({
54
53
  ...spec,
55
54
  type: "oneOfMulti",
56
- coerce: coerceOneOf(opts),
55
+ coerce: coerceOneOf(spec.opts),
57
56
  hint: spec.hint ?? __hint("ID", spec.delim),
58
- desc: __desc(opts, spec.desc),
59
57
  group: spec.group ?? "main",
60
- multi: true,
61
- opts
58
+ desc: __desc(spec.opts, spec.desc),
59
+ multi: true
62
60
  });
63
61
  const kvPairs = (spec) => {
64
62
  if (!spec.delim) spec.delim = "=";
@@ -80,19 +78,18 @@ const kvPairsMulti = (spec) => ({
80
78
  multi: true,
81
79
  ...spec
82
80
  });
83
- const tuple = (size2, coerce, spec) => {
81
+ const tuple = (spec) => {
84
82
  if (!spec.delim) spec.delim = ",";
85
83
  return {
84
+ ...spec,
86
85
  type: "tuple",
87
- hint: [...repeat("N", size2)].join(spec.delim),
88
- coerce: coerceTuple(coerce, size2, spec.delim),
89
- group: "main",
90
- size: size2,
91
- ...spec
86
+ coerce: coerceTuple(spec.coerce, spec.size, spec.delim),
87
+ hint: spec.hint ?? [...repeat("N", spec.size)].join(spec.delim),
88
+ group: spec.group ?? "main"
92
89
  };
93
90
  };
94
- const size = (size2, spec) => tuple(size2, coerceInt, spec);
95
- const vec = (size2, spec) => tuple(size2, coerceInt, spec);
91
+ const size = (spec) => tuple({ ...spec, coerce: coerceInt });
92
+ const vec = (spec) => tuple({ ...spec, coerce: coerceFloat });
96
93
  const json = (spec) => ({
97
94
  type: "json",
98
95
  coerce: coerceJson,
@@ -100,6 +97,23 @@ const json = (spec) => ({
100
97
  group: "main",
101
98
  ...spec
102
99
  });
100
+ const ARG_TYPES = {
101
+ flag,
102
+ float,
103
+ floats,
104
+ hex,
105
+ hexes,
106
+ int,
107
+ ints,
108
+ json,
109
+ kvPairs,
110
+ kvPairsMulti,
111
+ oneOf,
112
+ oneOfMulti,
113
+ string,
114
+ strings,
115
+ tuple
116
+ };
103
117
  const ARG_DRY_RUN = {
104
118
  dryRun: flag({
105
119
  desc: "Dry run (no changes applied)"
@@ -123,7 +137,7 @@ const ARG_OUT_DIR = (defaultVal, desc) => ({
123
137
  desc: "Output directory" + (desc ?? ""),
124
138
  hint: "PATH",
125
139
  default: defaultVal,
126
- optional: !!defaultVal
140
+ required: !!defaultVal
127
141
  })
128
142
  });
129
143
  const ARG_OUT_FILE = (defaultVal, desc) => ({
@@ -132,7 +146,7 @@ const ARG_OUT_FILE = (defaultVal, desc) => ({
132
146
  desc: "Output file" + (desc ?? ""),
133
147
  hint: "PATH",
134
148
  default: defaultVal,
135
- optional: !!defaultVal
149
+ required: !!defaultVal
136
150
  })
137
151
  });
138
152
  export {
@@ -140,6 +154,7 @@ export {
140
154
  ARG_OUT_DIR,
141
155
  ARG_OUT_FILE,
142
156
  ARG_QUIET,
157
+ ARG_TYPES,
143
158
  ARG_VERBOSE,
144
159
  flag,
145
160
  float,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/args",
3
- "version": "3.0.0",
3
+ "version": "3.1.1",
4
4
  "description": "Declarative, functional CLI argument/options parser, app framework, arg value coercions, multi/sub-commands, usage generation, error handling etc.",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -42,7 +42,7 @@
42
42
  "@thi.ng/api": "^8.12.2",
43
43
  "@thi.ng/checks": "^3.7.18",
44
44
  "@thi.ng/errors": "^2.5.42",
45
- "@thi.ng/logger": "^3.2.0",
45
+ "@thi.ng/logger": "^3.2.1",
46
46
  "@thi.ng/strings": "^3.9.22",
47
47
  "@thi.ng/text-format": "^2.2.41"
48
48
  },
@@ -110,5 +110,5 @@
110
110
  "tag": "cli",
111
111
  "year": 2018
112
112
  },
113
- "gitHead": "f3fa7a4798132f2faf9eb1ef12d99b9ca2148ec3\n"
113
+ "gitHead": "fbf4b46ba8a5ecff8c5423f4c2d158d208d20fc8\n"
114
114
  }