jackspeak 2.3.6 → 3.1.0

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/README.md CHANGED
@@ -155,6 +155,9 @@ Options:
155
155
  in the usage output, like `--option=<hint>`
156
156
  - `validate` A function that returns false (or throws) if an
157
157
  option value is invalid.
158
+ - `validOptions` An array of strings or numbers that define the
159
+ valid values that can be set. This is not allowed on `boolean`
160
+ (flag) options. May be used along with a `validate()` method.
158
161
  - `default` A default value for the field. Note that this may be
159
162
  overridden by an environment variable, if present.
160
163
 
@@ -9,7 +9,7 @@ import { inspect, InspectOptions } from 'node:util';
9
9
  * Defines the type of value that is valid, given a config definition's
10
10
  * {@link ConfigType} and boolean multiple setting
11
11
  */
12
- export type ValidValue<T extends ConfigType, M extends boolean> = [
12
+ export type ValidValue<T extends ConfigType = ConfigType, M extends boolean = boolean> = [
13
13
  T,
14
14
  M
15
15
  ] extends ['number', true] ? number[] : [T, M] extends ['string', true] ? string[] : [T, M] extends ['boolean', true] ? boolean[] : [T, M] extends ['number', false] ? number : [T, M] extends ['string', false] ? string : [T, M] extends ['boolean', false] ? boolean : [T, M] extends ['string', boolean] ? string | string[] : [T, M] extends ['boolean', boolean] ? boolean | boolean[] : [T, M] extends ['number', boolean] ? number | number[] : [T, M] extends [ConfigType, false] ? string | number | boolean : [T, M] extends [ConfigType, true] ? string[] | number[] | boolean[] : string | number | boolean | string[] | number[] | boolean[];
@@ -17,17 +17,21 @@ export type ValidValue<T extends ConfigType, M extends boolean> = [
17
17
  * The meta information for a config option definition, when the
18
18
  * type and multiple values can be inferred by the method being used
19
19
  */
20
- export type ConfigOptionMeta<T extends ConfigType, M extends boolean> = {
21
- default?: ValidValue<T, M> | undefined;
20
+ export type ConfigOptionMeta<T extends ConfigType, M extends boolean = boolean, O extends undefined | (T extends 'boolean' ? never : T extends 'string' ? string[] : T extends 'number' ? number[] : number[] | string[]) = undefined | (T extends 'boolean' ? never : T extends 'string' ? string[] : T extends 'number' ? number[] : number[] | string[])> = {
21
+ default?: undefined | (ValidValue<T, M> & (O extends number[] | string[] ? M extends false ? O[number] : O[number][] : unknown));
22
+ validOptions?: O;
22
23
  description?: string;
23
- validate?: ((v: any) => v is ValidValue<T, M>) | ((v: any) => boolean);
24
+ validate?: ((v: unknown) => v is ValidValue<T, M>) | ((v: unknown) => boolean);
24
25
  short?: string | undefined;
25
26
  type?: T;
26
- } & (T extends 'boolean' ? {} : {
27
- hint?: string | undefined;
28
- }) & (M extends false ? {} : {
29
- multiple?: M | undefined;
30
- delim?: string | undefined;
27
+ hint?: T extends 'boolean' ? never : string;
28
+ delim?: M extends true ? string : never;
29
+ } & (M extends false ? {
30
+ multiple?: false | undefined;
31
+ } : M extends true ? {
32
+ multiple: true;
33
+ } : {
34
+ multiple?: boolean;
31
35
  });
32
36
  /**
33
37
  * A set of {@link ConfigOptionMeta} fields, referenced by their longOption
@@ -60,13 +64,14 @@ export type MultiType<M extends boolean> = M extends true ? {
60
64
  /**
61
65
  * A config field definition, in its full representation.
62
66
  */
63
- export type ConfigOptionBase<T extends ConfigType, M extends boolean> = {
67
+ export type ConfigOptionBase<T extends ConfigType, M extends boolean = boolean> = {
64
68
  type: T;
65
69
  short?: string | undefined;
66
70
  default?: ValidValue<T, M> | undefined;
67
71
  description?: string;
68
72
  hint?: T extends 'boolean' ? undefined : string | undefined;
69
- validate?: (v: any) => v is ValidValue<T, M>;
73
+ validate?: (v: unknown) => v is ValidValue<T, M>;
74
+ validOptions?: T extends 'boolean' ? undefined : T extends 'string' ? readonly string[] : T extends 'number' ? readonly number[] : readonly number[] | readonly string[];
70
75
  } & MultiType<M>;
71
76
  export declare const isConfigType: (t: string) => t is ConfigType;
72
77
  export declare const isConfigOption: <T extends ConfigType, M extends boolean>(o: any, type: T, multi: M) => o is ConfigOptionBase<T, M>;
@@ -75,13 +80,13 @@ export declare const isConfigOption: <T extends ConfigType, M extends boolean>(o
75
80
  * string values.
76
81
  */
77
82
  export type ConfigSet = {
78
- [longOption: string]: ConfigOptionBase<ConfigType, boolean>;
83
+ [longOption: string]: ConfigOptionBase<ConfigType>;
79
84
  };
80
85
  /**
81
86
  * The 'values' field returned by {@link Jack#parse}
82
87
  */
83
88
  export type OptionsResults<T extends ConfigSet> = {
84
- [k in keyof T]?: T[k] extends ConfigOptionBase<'string', false> ? string : T[k] extends ConfigOptionBase<'string', true> ? string[] : T[k] extends ConfigOptionBase<'number', false> ? number : T[k] extends ConfigOptionBase<'number', true> ? number[] : T[k] extends ConfigOptionBase<'boolean', false> ? boolean : T[k] extends ConfigOptionBase<'boolean', true> ? boolean[] : never;
89
+ [k in keyof T]?: T[k]['validOptions'] extends string[] | number[] ? T[k] extends ConfigOptionBase<'string' | 'number', false> ? T[k]['validOptions'][number] : T[k] extends ConfigOptionBase<'string' | 'number', true> ? T[k]['validOptions'][number][] : never : T[k] extends ConfigOptionBase<'string', false> ? string : T[k] extends ConfigOptionBase<'string', true> ? string[] : T[k] extends ConfigOptionBase<'number', false> ? number : T[k] extends ConfigOptionBase<'number', true> ? number[] : T[k] extends ConfigOptionBase<'boolean', false> ? boolean : T[k] extends ConfigOptionBase<'boolean', true> ? boolean[] : never;
85
90
  };
86
91
  /**
87
92
  * The object retured by {@link Jack#parse}
@@ -140,7 +145,7 @@ export type TextRow = Heading | Description;
140
145
  export type UsageField = TextRow | {
141
146
  type: 'config';
142
147
  name: string;
143
- value: ConfigOptionBase<ConfigType, boolean>;
148
+ value: ConfigOptionBase<ConfigType>;
144
149
  };
145
150
  /**
146
151
  * Options provided to the {@link Jack} constructor
@@ -215,7 +220,7 @@ export declare class Jack<C extends ConfigSet = {}> {
215
220
  * Validate that any arbitrary object is a valid configuration `values`
216
221
  * object. Useful when loading config files or other sources.
217
222
  */
218
- validate(o: any): asserts o is Parsed<C>['values'];
223
+ validate(o: unknown): asserts o is Parsed<C>['values'];
219
224
  /**
220
225
  * Add a heading to the usage output banner
221
226
  */
@@ -272,7 +277,8 @@ export declare class Jack<C extends ConfigSet = {}> {
272
277
  toJSON(): {
273
278
  [k: string]: {
274
279
  default?: string | number | boolean | string[] | number[] | boolean[] | undefined;
275
- validate?: ((v: any) => v is string | number | boolean | string[] | number[] | boolean[]) | undefined;
280
+ validOptions?: readonly number[] | readonly string[] | undefined;
281
+ validate?: ((v: unknown) => v is string | number | boolean | string[] | number[] | boolean[]) | undefined;
276
282
  description?: string | undefined;
277
283
  short?: string | undefined;
278
284
  delim?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -21,51 +21,41 @@ const toEnvKey = (pref, key) => {
21
21
  .replace(/ /g, '_');
22
22
  };
23
23
  const toEnvVal = (value, delim = '\n') => {
24
- const str = typeof value === 'string'
25
- ? value
26
- : typeof value === 'boolean'
27
- ? value
28
- ? '1'
24
+ const str = typeof value === 'string' ? value
25
+ : typeof value === 'boolean' ?
26
+ value ? '1'
29
27
  : '0'
30
- : typeof value === 'number'
31
- ? String(value)
32
- : Array.isArray(value)
33
- ? value
34
- .map((v) => toEnvVal(v))
35
- .join(delim)
36
- : /* c8 ignore start */
37
- undefined;
28
+ : typeof value === 'number' ? String(value)
29
+ : Array.isArray(value) ?
30
+ value.map((v) => toEnvVal(v)).join(delim)
31
+ : /* c8 ignore start */ undefined;
38
32
  if (typeof str !== 'string') {
39
33
  throw new Error(`could not serialize value to environment: ${JSON.stringify(value)}`);
40
34
  }
41
35
  /* c8 ignore stop */
42
36
  return str;
43
37
  };
44
- const fromEnvVal = (env, type, multiple, delim = '\n') => (multiple
45
- ? env
46
- ? env.split(delim).map(v => fromEnvVal(v, type, false))
38
+ const fromEnvVal = (env, type, multiple, delim = '\n') => (multiple ?
39
+ env ? env.split(delim).map(v => fromEnvVal(v, type, false))
47
40
  : []
48
- : type === 'string'
49
- ? env
50
- : type === 'boolean'
51
- ? env === '1'
41
+ : type === 'string' ? env
42
+ : type === 'boolean' ? env === '1'
52
43
  : +env.trim());
53
44
  const isConfigType = (t) => typeof t === 'string' &&
54
45
  (t === 'string' || t === 'number' || t === 'boolean');
55
46
  exports.isConfigType = isConfigType;
56
47
  const undefOrType = (v, t) => v === undefined || typeof v === t;
48
+ const undefOrTypeArray = (v, t) => v === undefined || (Array.isArray(v) && v.every(x => typeof x === t));
49
+ const isValidOption = (v, vo) => Array.isArray(v) ? v.every(x => isValidOption(x, vo)) : vo.includes(v);
57
50
  // print the value type, for error message reporting
58
- const valueType = (v) => typeof v === 'string'
59
- ? 'string'
60
- : typeof v === 'boolean'
61
- ? 'boolean'
62
- : typeof v === 'number'
63
- ? 'number'
64
- : Array.isArray(v)
65
- ? joinTypes([...new Set(v.map(v => valueType(v)))]) + '[]'
51
+ const valueType = (v) => typeof v === 'string' ? 'string'
52
+ : typeof v === 'boolean' ? 'boolean'
53
+ : typeof v === 'number' ? 'number'
54
+ : Array.isArray(v) ?
55
+ joinTypes([...new Set(v.map(v => valueType(v)))]) + '[]'
66
56
  : `${v.type}${v.multiple ? '[]' : ''}`;
67
- const joinTypes = (types) => types.length === 1 && typeof types[0] === 'string'
68
- ? types[0]
57
+ const joinTypes = (types) => types.length === 1 && typeof types[0] === 'string' ?
58
+ types[0]
69
59
  : `(${types.join('|')})`;
70
60
  const isValidValue = (v, type, multi) => {
71
61
  if (multi) {
@@ -85,80 +75,140 @@ const isConfigOption = (o, type, multi) => !!o &&
85
75
  undefOrType(o.description, 'string') &&
86
76
  undefOrType(o.hint, 'string') &&
87
77
  undefOrType(o.validate, 'function') &&
78
+ (o.type === 'boolean' ?
79
+ o.validOptions === undefined
80
+ : undefOrTypeArray(o.validOptions, o.type)) &&
88
81
  (o.default === undefined || isValidValue(o.default, type, multi)) &&
89
82
  !!o.multiple === multi;
90
83
  exports.isConfigOption = isConfigOption;
91
84
  function num(o = {}) {
92
- const { default: def, validate: val, ...rest } = o;
85
+ const { default: def, validate: val, validOptions, ...rest } = o;
93
86
  if (def !== undefined && !isValidValue(def, 'number', false)) {
94
- throw new TypeError('invalid default value');
87
+ throw new TypeError('invalid default value', {
88
+ cause: {
89
+ found: def,
90
+ wanted: 'number',
91
+ },
92
+ });
93
+ }
94
+ if (!undefOrTypeArray(validOptions, 'number')) {
95
+ throw new TypeError('invalid validOptions', {
96
+ cause: {
97
+ found: validOptions,
98
+ wanted: 'number[]',
99
+ },
100
+ });
95
101
  }
96
- const validate = val
97
- ? val
102
+ const validate = val ?
103
+ val
98
104
  : undefined;
99
105
  return {
100
106
  ...rest,
101
107
  default: def,
102
108
  validate,
109
+ validOptions,
103
110
  type: 'number',
104
111
  multiple: false,
105
112
  };
106
113
  }
107
114
  function numList(o = {}) {
108
- const { default: def, validate: val, ...rest } = o;
115
+ const { default: def, validate: val, validOptions, ...rest } = o;
109
116
  if (def !== undefined && !isValidValue(def, 'number', true)) {
110
- throw new TypeError('invalid default value');
117
+ throw new TypeError('invalid default value', {
118
+ cause: {
119
+ found: def,
120
+ wanted: 'number[]',
121
+ },
122
+ });
111
123
  }
112
- const validate = val
113
- ? val
124
+ if (!undefOrTypeArray(validOptions, 'number')) {
125
+ throw new TypeError('invalid validOptions', {
126
+ cause: {
127
+ found: validOptions,
128
+ wanted: 'number[]',
129
+ },
130
+ });
131
+ }
132
+ const validate = val ?
133
+ val
114
134
  : undefined;
115
135
  return {
116
136
  ...rest,
117
137
  default: def,
118
138
  validate,
139
+ validOptions,
119
140
  type: 'number',
120
141
  multiple: true,
121
142
  };
122
143
  }
123
144
  function opt(o = {}) {
124
- const { default: def, validate: val, ...rest } = o;
145
+ const { default: def, validate: val, validOptions, ...rest } = o;
125
146
  if (def !== undefined && !isValidValue(def, 'string', false)) {
126
- throw new TypeError('invalid default value');
147
+ throw new TypeError('invalid default value', {
148
+ cause: {
149
+ found: def,
150
+ wanted: 'string',
151
+ },
152
+ });
127
153
  }
128
- const validate = val
129
- ? val
154
+ if (!undefOrTypeArray(validOptions, 'string')) {
155
+ throw new TypeError('invalid validOptions', {
156
+ cause: {
157
+ found: validOptions,
158
+ wanted: 'string[]',
159
+ },
160
+ });
161
+ }
162
+ const validate = val ?
163
+ val
130
164
  : undefined;
131
165
  return {
132
166
  ...rest,
133
167
  default: def,
134
168
  validate,
169
+ validOptions,
135
170
  type: 'string',
136
171
  multiple: false,
137
172
  };
138
173
  }
139
174
  function optList(o = {}) {
140
- const { default: def, validate: val, ...rest } = o;
175
+ const { default: def, validate: val, validOptions, ...rest } = o;
141
176
  if (def !== undefined && !isValidValue(def, 'string', true)) {
142
- throw new TypeError('invalid default value');
177
+ throw new TypeError('invalid default value', {
178
+ cause: {
179
+ found: def,
180
+ wanted: 'string[]',
181
+ },
182
+ });
183
+ }
184
+ if (!undefOrTypeArray(validOptions, 'string')) {
185
+ throw new TypeError('invalid validOptions', {
186
+ cause: {
187
+ found: validOptions,
188
+ wanted: 'string[]',
189
+ },
190
+ });
143
191
  }
144
- const validate = val
145
- ? val
192
+ const validate = val ?
193
+ val
146
194
  : undefined;
147
195
  return {
148
196
  ...rest,
149
197
  default: def,
150
198
  validate,
199
+ validOptions,
151
200
  type: 'string',
152
201
  multiple: true,
153
202
  };
154
203
  }
155
204
  function flag(o = {}) {
156
205
  const { hint, default: def, validate: val, ...rest } = o;
206
+ delete rest.validOptions;
157
207
  if (def !== undefined && !isValidValue(def, 'boolean', false)) {
158
208
  throw new TypeError('invalid default value');
159
209
  }
160
- const validate = val
161
- ? val
210
+ const validate = val ?
211
+ val
162
212
  : undefined;
163
213
  if (hint !== undefined) {
164
214
  throw new TypeError('cannot provide hint for flag');
@@ -173,11 +223,12 @@ function flag(o = {}) {
173
223
  }
174
224
  function flagList(o = {}) {
175
225
  const { hint, default: def, validate: val, ...rest } = o;
226
+ delete rest.validOptions;
176
227
  if (def !== undefined && !isValidValue(def, 'boolean', true)) {
177
228
  throw new TypeError('invalid default value');
178
229
  }
179
- const validate = val
180
- ? val
230
+ const validate = val ?
231
+ val
181
232
  : undefined;
182
233
  if (hint !== undefined) {
183
234
  throw new TypeError('cannot provide hint for flag list');
@@ -210,8 +261,8 @@ const toParseArgsOptionsConfig = (options) => {
210
261
  c[longOption] = {
211
262
  type: 'string',
212
263
  multiple: false,
213
- default: config.default === undefined
214
- ? undefined
264
+ default: config.default === undefined ?
265
+ undefined
215
266
  : String(config.default),
216
267
  };
217
268
  }
@@ -219,7 +270,7 @@ const toParseArgsOptionsConfig = (options) => {
219
270
  const conf = config;
220
271
  c[longOption] = {
221
272
  type: conf.type,
222
- multiple: conf.multiple,
273
+ multiple: !!conf.multiple,
223
274
  default: conf.default,
224
275
  };
225
276
  }
@@ -277,14 +328,25 @@ class Jack {
277
328
  this.validate(values);
278
329
  }
279
330
  catch (er) {
280
- throw Object.assign(er, source ? { source } : {});
331
+ const e = er;
332
+ if (source && e && typeof e === 'object') {
333
+ if (e.cause && typeof e.cause === 'object') {
334
+ Object.assign(e.cause, { path: source });
335
+ }
336
+ else {
337
+ e.cause = { path: source };
338
+ }
339
+ }
340
+ throw e;
281
341
  }
282
342
  for (const [field, value] of Object.entries(values)) {
283
343
  const my = this.#configSet[field];
284
344
  // already validated, just for TS's benefit
285
345
  /* c8 ignore start */
286
346
  if (!my) {
287
- throw new Error('unexpected field in config set: ' + field);
347
+ throw new Error('unexpected field in config set: ' + field, {
348
+ cause: { found: field },
349
+ });
288
350
  }
289
351
  /* c8 ignore stop */
290
352
  my.default = value;
@@ -355,18 +417,27 @@ class Jack {
355
417
  throw new Error(`Unknown option '${token.rawName}'. ` +
356
418
  `To specify a positional argument starting with a '-', ` +
357
419
  `place it at the end of the command after '--', as in ` +
358
- `'-- ${token.rawName}'`);
420
+ `'-- ${token.rawName}'`, {
421
+ cause: {
422
+ found: token.rawName + (token.value ? `=${token.value}` : ''),
423
+ },
424
+ });
359
425
  }
360
426
  if (value === undefined) {
361
427
  if (token.value === undefined) {
362
428
  if (my.type !== 'boolean') {
363
- throw new Error(`No value provided for ${token.rawName}, expected ${my.type}`);
429
+ throw new Error(`No value provided for ${token.rawName}, expected ${my.type}`, {
430
+ cause: {
431
+ name: token.rawName,
432
+ wanted: valueType(my),
433
+ },
434
+ });
364
435
  }
365
436
  value = true;
366
437
  }
367
438
  else {
368
439
  if (my.type === 'boolean') {
369
- throw new Error(`Flag ${token.rawName} does not take a value, received '${token.value}'`);
440
+ throw new Error(`Flag ${token.rawName} does not take a value, received '${token.value}'`, { cause: { found: token } });
370
441
  }
371
442
  if (my.type === 'string') {
372
443
  value = token.value;
@@ -375,7 +446,13 @@ class Jack {
375
446
  value = +token.value;
376
447
  if (value !== value) {
377
448
  throw new Error(`Invalid value '${token.value}' provided for ` +
378
- `'${token.rawName}' option, expected number`);
449
+ `'${token.rawName}' option, expected number`, {
450
+ cause: {
451
+ name: token.rawName,
452
+ found: token.value,
453
+ wanted: 'number',
454
+ },
455
+ });
379
456
  }
380
457
  }
381
458
  }
@@ -400,8 +477,16 @@ class Jack {
400
477
  }
401
478
  for (const [field, value] of Object.entries(p.values)) {
402
479
  const valid = this.#configSet[field]?.validate;
480
+ const validOptions = this.#configSet[field]?.validOptions;
481
+ let cause;
482
+ if (validOptions && !isValidOption(value, validOptions)) {
483
+ cause = { name: field, found: value, validOptions: validOptions };
484
+ }
403
485
  if (valid && !valid(value)) {
404
- throw new Error(`Invalid value provided for --${field}: ${JSON.stringify(value)}`);
486
+ cause ??= { name: field, found: value };
487
+ }
488
+ if (cause) {
489
+ throw new Error(`Invalid value provided for --${field}: ${JSON.stringify(value)}`, { cause });
405
490
  }
406
491
  }
407
492
  this.#writeEnv(p);
@@ -418,7 +503,7 @@ class Jack {
418
503
  // recurse so we get the core config key we care about.
419
504
  this.#noNoFields(yes, val, s);
420
505
  if (this.#configSet[yes]?.type === 'boolean') {
421
- throw new Error(`do not set '${s}', instead set '${yes}' as desired.`);
506
+ throw new Error(`do not set '${s}', instead set '${yes}' as desired.`, { cause: { found: s, wanted: yes } });
422
507
  }
423
508
  }
424
509
  /**
@@ -427,22 +512,48 @@ class Jack {
427
512
  */
428
513
  validate(o) {
429
514
  if (!o || typeof o !== 'object') {
430
- throw new Error('Invalid config: not an object');
515
+ throw new Error('Invalid config: not an object', {
516
+ cause: { found: o },
517
+ });
431
518
  }
519
+ const opts = o;
432
520
  for (const field in o) {
433
- this.#noNoFields(field, o[field]);
521
+ const value = opts[field];
522
+ /* c8 ignore next - for TS */
523
+ if (value === undefined)
524
+ continue;
525
+ this.#noNoFields(field, value);
434
526
  const config = this.#configSet[field];
435
527
  if (!config) {
436
- throw new Error(`Unknown config option: ${field}`);
528
+ throw new Error(`Unknown config option: ${field}`, {
529
+ cause: { found: field },
530
+ });
437
531
  }
438
- if (!isValidValue(o[field], config.type, !!config.multiple)) {
439
- throw Object.assign(new Error(`Invalid value ${valueType(o[field])} for ${field}, expected ${valueType(config)}`), {
440
- field,
441
- value: o[field],
532
+ if (!isValidValue(value, config.type, !!config.multiple)) {
533
+ throw new Error(`Invalid value ${valueType(value)} for ${field}, expected ${valueType(config)}`, {
534
+ cause: {
535
+ name: field,
536
+ found: value,
537
+ wanted: valueType(config),
538
+ },
442
539
  });
443
540
  }
444
- if (config.validate && !config.validate(o[field])) {
445
- throw new Error(`Invalid config value for ${field}: ${o[field]}`);
541
+ let cause;
542
+ if (config.validOptions &&
543
+ !isValidOption(value, config.validOptions)) {
544
+ cause = {
545
+ name: field,
546
+ found: value,
547
+ validOptions: config.validOptions,
548
+ };
549
+ }
550
+ if (config.validate && !config.validate(value)) {
551
+ cause ??= { name: field, found: value };
552
+ }
553
+ if (cause) {
554
+ throw new Error(`Invalid config value for ${field}: ${value}`, {
555
+ cause,
556
+ });
446
557
  }
447
558
  }
448
559
  }
@@ -753,21 +864,21 @@ class Jack {
753
864
  const { value } = field;
754
865
  const desc = value.description || '';
755
866
  const mult = value.multiple ? 'Can be set multiple times' : '';
756
- const dmDelim = mult && (desc.includes('\n') ? '\n\n' : '\n');
757
- const text = normalize(desc + dmDelim + mult);
867
+ const opts = value.validOptions?.length ?
868
+ `Valid options:${value.validOptions.map(v => ` ${JSON.stringify(v)}`)}`
869
+ : '';
870
+ const dmDelim = desc.includes('\n') ? '\n\n' : '\n';
871
+ const extra = [opts, mult].join(dmDelim).trim();
872
+ const text = (normalize(desc) + dmDelim + extra).trim();
758
873
  const hint = value.hint ||
759
- (value.type === 'number'
760
- ? 'n'
761
- : value.type === 'string'
762
- ? field.name
874
+ (value.type === 'number' ? 'n'
875
+ : value.type === 'string' ? field.name
763
876
  : undefined);
764
- const short = !value.short
765
- ? ''
766
- : value.type === 'boolean'
767
- ? `-${value.short} `
877
+ const short = !value.short ? ''
878
+ : value.type === 'boolean' ? `-${value.short} `
768
879
  : `-${value.short}<${hint}> `;
769
- const left = value.type === 'boolean'
770
- ? `${short}--${field.name}`
880
+ const left = value.type === 'boolean' ?
881
+ `${short}--${field.name}`
771
882
  : `${short}--${field.name}=<${hint}>`;
772
883
  const row = { text, left, type: 'config' };
773
884
  if (text.length > width - maxMax) {
@@ -795,10 +906,11 @@ class Jack {
795
906
  ...(def.multiple ? { multiple: true } : {}),
796
907
  ...(def.delim ? { delim: def.delim } : {}),
797
908
  ...(def.short ? { short: def.short } : {}),
798
- ...(def.description
799
- ? { description: normalize(def.description) }
909
+ ...(def.description ?
910
+ { description: normalize(def.description) }
800
911
  : {}),
801
912
  ...(def.validate ? { validate: def.validate } : {}),
913
+ ...(def.validOptions ? { validOptions: def.validOptions } : {}),
802
914
  ...(def.default !== undefined ? { default: def.default } : {}),
803
915
  },
804
916
  ]));
@@ -813,12 +925,12 @@ class Jack {
813
925
  exports.Jack = Jack;
814
926
  // Unwrap and un-indent, so we can wrap description
815
927
  // strings however makes them look nice in the code.
816
- const normalize = (s, pre = false) => pre
817
- ? // prepend a ZWSP to each line so cliui doesn't strip it.
818
- s
819
- .split('\n')
820
- .map(l => `\u200b${l}`)
821
- .join('\n')
928
+ const normalize = (s, pre = false) => pre ?
929
+ // prepend a ZWSP to each line so cliui doesn't strip it.
930
+ s
931
+ .split('\n')
932
+ .map(l => `\u200b${l}`)
933
+ .join('\n')
822
934
  : s
823
935
  // remove single line breaks, except for lists
824
936
  .replace(/([^\n])\n[ \t]*([^\n])/g, (_, $1, $2) => !/^[-*]/.test($2) ? `${$1} ${$2}` : `${$1}\n${$2}`)
@@ -832,8 +944,8 @@ const normalize = (s, pre = false) => pre
832
944
  // normalize for markdown printing, remove leading spaces on lines
833
945
  const normalizeMarkdown = (s, pre = false) => {
834
946
  const n = normalize(s, pre).replace(/\\/g, '\\\\');
835
- return pre
836
- ? `\`\`\`\n${n.replace(/\u200b/g, '')}\n\`\`\``
947
+ return pre ?
948
+ `\`\`\`\n${n.replace(/\u200b/g, '')}\n\`\`\``
837
949
  : n.replace(/\n +/g, '\n').trim();
838
950
  };
839
951
  const normalizeOneLine = (s, pre = false) => {