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 +3 -0
- package/dist/commonjs/index.d.ts +22 -16
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +204 -92
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/package.json +3 -1
- package/dist/commonjs/parse-args-cjs.cjs.map +1 -1
- package/dist/esm/index.d.ts +22 -16
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +204 -92
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/package.json +3 -1
- package/dist/esm/parse-args.js +2 -2
- package/dist/esm/parse-args.js.map +1 -1
- package/package.json +5 -4
- package/dist/commonjs/parse-args.d.ts.map +0 -1
- package/dist/commonjs/parse-args.js.map +0 -1
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
|
|
package/dist/commonjs/index.d.ts
CHANGED
|
@@ -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> |
|
|
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:
|
|
24
|
+
validate?: ((v: unknown) => v is ValidValue<T, M>) | ((v: unknown) => boolean);
|
|
24
25
|
short?: string | undefined;
|
|
25
26
|
type?: T;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
multiple?:
|
|
30
|
-
|
|
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:
|
|
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
|
|
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
|
|
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:
|
|
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
|
-
|
|
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":";AAAA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAA;AAExD;;GAEG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAE3D,OAAO,EAAE,OAAO,EAAE,cAAc,EAAmB,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/commonjs/index.js
CHANGED
|
@@ -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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
? '
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
113
|
-
|
|
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
|
-
|
|
129
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
439
|
-
throw
|
|
440
|
-
|
|
441
|
-
|
|
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
|
-
|
|
445
|
-
|
|
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
|
|
757
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
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
|
-
|
|
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) => {
|