jackspeak 4.0.0 → 4.0.2
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/dist/commonjs/index.d.ts +61 -69
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +197 -292
- package/dist/commonjs/index.js.map +1 -1
- package/dist/esm/index.d.ts +61 -69
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +192 -288
- package/dist/esm/index.js.map +1 -1
- package/package.json +10 -11
- package/dist/commonjs/parse-args-cjs.cjs.map +0 -1
- package/dist/commonjs/parse-args-cjs.d.cts.map +0 -1
- package/dist/commonjs/parse-args.d.ts +0 -4
- package/dist/commonjs/parse-args.js +0 -50
- package/dist/esm/parse-args.d.ts +0 -4
- package/dist/esm/parse-args.d.ts.map +0 -1
- package/dist/esm/parse-args.js +0 -26
- package/dist/esm/parse-args.js.map +0 -1
package/dist/commonjs/index.js
CHANGED
|
@@ -3,23 +3,61 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.jack = exports.Jack = exports.isConfigOption = exports.isConfigType = void 0;
|
|
6
|
+
exports.jack = exports.Jack = exports.isConfigOption = exports.isConfigOptionOfType = exports.isConfigType = void 0;
|
|
7
7
|
const node_util_1 = require("node:util");
|
|
8
|
-
const parse_args_js_1 = require("./parse-args.js");
|
|
9
8
|
// it's a tiny API, just cast it inline, it's fine
|
|
10
9
|
//@ts-ignore
|
|
11
10
|
const cliui_1 = __importDefault(require("@isaacs/cliui"));
|
|
12
11
|
const node_path_1 = require("node:path");
|
|
13
|
-
const
|
|
12
|
+
const isConfigType = (t) => typeof t === 'string' &&
|
|
13
|
+
(t === 'string' || t === 'number' || t === 'boolean');
|
|
14
|
+
exports.isConfigType = isConfigType;
|
|
15
|
+
const isValidValue = (v, type, multi) => {
|
|
16
|
+
if (multi) {
|
|
17
|
+
if (!Array.isArray(v))
|
|
18
|
+
return false;
|
|
19
|
+
return !v.some((v) => !isValidValue(v, type, false));
|
|
20
|
+
}
|
|
21
|
+
if (Array.isArray(v))
|
|
22
|
+
return false;
|
|
23
|
+
return typeof v === type;
|
|
24
|
+
};
|
|
25
|
+
const isValidOption = (v, vo) => !!vo &&
|
|
26
|
+
(Array.isArray(v) ? v.every(x => isValidOption(x, vo)) : vo.includes(v));
|
|
27
|
+
/**
|
|
28
|
+
* Determine whether an unknown object is a {@link ConfigOption} based only
|
|
29
|
+
* on its `type` and `multiple` property
|
|
30
|
+
*/
|
|
31
|
+
const isConfigOptionOfType = (o, type, multi) => !!o &&
|
|
32
|
+
typeof o === 'object' &&
|
|
33
|
+
(0, exports.isConfigType)(o.type) &&
|
|
34
|
+
o.type === type &&
|
|
35
|
+
!!o.multiple === multi;
|
|
36
|
+
exports.isConfigOptionOfType = isConfigOptionOfType;
|
|
37
|
+
/**
|
|
38
|
+
* Determine whether an unknown object is a {@link ConfigOption} based on
|
|
39
|
+
* it having all valid properties
|
|
40
|
+
*/
|
|
41
|
+
const isConfigOption = (o, type, multi) => (0, exports.isConfigOptionOfType)(o, type, multi) &&
|
|
42
|
+
undefOrType(o.short, 'string') &&
|
|
43
|
+
undefOrType(o.description, 'string') &&
|
|
44
|
+
undefOrType(o.hint, 'string') &&
|
|
45
|
+
undefOrType(o.validate, 'function') &&
|
|
46
|
+
(o.type === 'boolean' ?
|
|
47
|
+
o.validOptions === undefined
|
|
48
|
+
: undefOrTypeArray(o.validOptions, o.type)) &&
|
|
49
|
+
(o.default === undefined || isValidValue(o.default, type, multi));
|
|
50
|
+
exports.isConfigOption = isConfigOption;
|
|
51
|
+
const isHeading = (r) => r.type === 'heading';
|
|
52
|
+
const isDescription = (r) => r.type === 'description';
|
|
53
|
+
const width = Math.min(process?.stdout?.columns ?? 80, 80);
|
|
14
54
|
// indentation spaces from heading level
|
|
15
55
|
const indent = (n) => (n - 1) * 2;
|
|
16
|
-
const toEnvKey = (pref, key) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.replace(/ /g, '_');
|
|
22
|
-
};
|
|
56
|
+
const toEnvKey = (pref, key) => [pref, key.replace(/[^a-zA-Z0-9]+/g, ' ')]
|
|
57
|
+
.join(' ')
|
|
58
|
+
.trim()
|
|
59
|
+
.toUpperCase()
|
|
60
|
+
.replace(/ /g, '_');
|
|
23
61
|
const toEnvVal = (value, delim = '\n') => {
|
|
24
62
|
const str = typeof value === 'string' ? value
|
|
25
63
|
: typeof value === 'boolean' ?
|
|
@@ -41,256 +79,144 @@ const fromEnvVal = (env, type, multiple, delim = '\n') => (multiple ?
|
|
|
41
79
|
: type === 'string' ? env
|
|
42
80
|
: type === 'boolean' ? env === '1'
|
|
43
81
|
: +env.trim());
|
|
44
|
-
const isConfigType = (t) => typeof t === 'string' &&
|
|
45
|
-
(t === 'string' || t === 'number' || t === 'boolean');
|
|
46
|
-
exports.isConfigType = isConfigType;
|
|
47
82
|
const undefOrType = (v, t) => v === undefined || typeof v === t;
|
|
48
83
|
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);
|
|
50
84
|
// print the value type, for error message reporting
|
|
51
85
|
const valueType = (v) => typeof v === 'string' ? 'string'
|
|
52
86
|
: typeof v === 'boolean' ? 'boolean'
|
|
53
87
|
: typeof v === 'number' ? 'number'
|
|
54
88
|
: Array.isArray(v) ?
|
|
55
|
-
joinTypes([...new Set(v.map(v => valueType(v)))])
|
|
89
|
+
`${joinTypes([...new Set(v.map(v => valueType(v)))])}[]`
|
|
56
90
|
: `${v.type}${v.multiple ? '[]' : ''}`;
|
|
57
91
|
const joinTypes = (types) => types.length === 1 && typeof types[0] === 'string' ?
|
|
58
92
|
types[0]
|
|
59
93
|
: `(${types.join('|')})`;
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
: undefOrTypeArray(o.validOptions, o.type)) &&
|
|
81
|
-
(o.default === undefined || isValidValue(o.default, type, multi)) &&
|
|
82
|
-
!!o.multiple === multi;
|
|
83
|
-
exports.isConfigOption = isConfigOption;
|
|
84
|
-
function num(o = {}) {
|
|
85
|
-
const { default: def, validate: val, validOptions, ...rest } = o;
|
|
86
|
-
if (def !== undefined && !isValidValue(def, 'number', false)) {
|
|
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
|
-
});
|
|
101
|
-
}
|
|
102
|
-
const validate = val ?
|
|
103
|
-
val
|
|
104
|
-
: undefined;
|
|
105
|
-
return {
|
|
106
|
-
...rest,
|
|
107
|
-
default: def,
|
|
108
|
-
validate,
|
|
109
|
-
validOptions,
|
|
110
|
-
type: 'number',
|
|
111
|
-
multiple: false,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
function numList(o = {}) {
|
|
115
|
-
const { default: def, validate: val, validOptions, ...rest } = o;
|
|
116
|
-
if (def !== undefined && !isValidValue(def, 'number', true)) {
|
|
117
|
-
throw new TypeError('invalid default value', {
|
|
118
|
-
cause: {
|
|
119
|
-
found: def,
|
|
120
|
-
wanted: 'number[]',
|
|
121
|
-
},
|
|
122
|
-
});
|
|
94
|
+
const validateFieldMeta = (field, fieldMeta) => {
|
|
95
|
+
if (fieldMeta) {
|
|
96
|
+
if (field.type !== undefined && field.type !== fieldMeta.type) {
|
|
97
|
+
throw new TypeError(`invalid type`, {
|
|
98
|
+
cause: {
|
|
99
|
+
found: field.type,
|
|
100
|
+
wanted: [fieldMeta.type, undefined],
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (field.multiple !== undefined &&
|
|
105
|
+
!!field.multiple !== fieldMeta.multiple) {
|
|
106
|
+
throw new TypeError(`invalid multiple`, {
|
|
107
|
+
cause: {
|
|
108
|
+
found: field.multiple,
|
|
109
|
+
wanted: [fieldMeta.multiple, undefined],
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return fieldMeta;
|
|
123
114
|
}
|
|
124
|
-
if (!
|
|
125
|
-
throw new TypeError(
|
|
115
|
+
if (!(0, exports.isConfigType)(field.type)) {
|
|
116
|
+
throw new TypeError(`invalid type`, {
|
|
126
117
|
cause: {
|
|
127
|
-
found:
|
|
128
|
-
wanted: 'number
|
|
118
|
+
found: field.type,
|
|
119
|
+
wanted: ['string', 'number', 'boolean'],
|
|
129
120
|
},
|
|
130
121
|
});
|
|
131
122
|
}
|
|
132
|
-
const validate = val ?
|
|
133
|
-
val
|
|
134
|
-
: undefined;
|
|
135
123
|
return {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
validate,
|
|
139
|
-
validOptions,
|
|
140
|
-
type: 'number',
|
|
141
|
-
multiple: true,
|
|
124
|
+
type: field.type,
|
|
125
|
+
multiple: !!field.multiple,
|
|
142
126
|
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
default: def,
|
|
168
|
-
validate,
|
|
169
|
-
validOptions,
|
|
170
|
-
type: 'string',
|
|
171
|
-
multiple: false,
|
|
127
|
+
};
|
|
128
|
+
const validateField = (o, type, multiple) => {
|
|
129
|
+
const validateValidOptions = (def, validOptions) => {
|
|
130
|
+
if (!undefOrTypeArray(validOptions, type)) {
|
|
131
|
+
throw new TypeError('invalid validOptions', {
|
|
132
|
+
cause: {
|
|
133
|
+
found: validOptions,
|
|
134
|
+
wanted: valueType({ type, multiple: true }),
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
if (def !== undefined && validOptions !== undefined) {
|
|
139
|
+
const valid = Array.isArray(def) ?
|
|
140
|
+
def.every(v => validOptions.includes(v))
|
|
141
|
+
: validOptions.includes(def);
|
|
142
|
+
if (!valid) {
|
|
143
|
+
throw new TypeError('invalid default value not in validOptions', {
|
|
144
|
+
cause: {
|
|
145
|
+
found: def,
|
|
146
|
+
wanted: validOptions,
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
172
151
|
};
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const { default: def, validate: val, validOptions, ...rest } = o;
|
|
176
|
-
if (def !== undefined && !isValidValue(def, 'string', true)) {
|
|
152
|
+
if (o.default !== undefined &&
|
|
153
|
+
!isValidValue(o.default, type, multiple)) {
|
|
177
154
|
throw new TypeError('invalid default value', {
|
|
178
155
|
cause: {
|
|
179
|
-
found:
|
|
180
|
-
wanted:
|
|
156
|
+
found: o.default,
|
|
157
|
+
wanted: valueType({ type, multiple }),
|
|
181
158
|
},
|
|
182
159
|
});
|
|
183
160
|
}
|
|
184
|
-
if (
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
found: validOptions,
|
|
188
|
-
wanted: 'string[]',
|
|
189
|
-
},
|
|
190
|
-
});
|
|
161
|
+
if ((0, exports.isConfigOptionOfType)(o, 'number', false) ||
|
|
162
|
+
(0, exports.isConfigOptionOfType)(o, 'number', true)) {
|
|
163
|
+
validateValidOptions(o.default, o.validOptions);
|
|
191
164
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return {
|
|
196
|
-
...rest,
|
|
197
|
-
default: def,
|
|
198
|
-
validate,
|
|
199
|
-
validOptions,
|
|
200
|
-
type: 'string',
|
|
201
|
-
multiple: true,
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
function flag(o = {}) {
|
|
205
|
-
const { hint, default: def, validate: val, ...rest } = o;
|
|
206
|
-
delete rest.validOptions;
|
|
207
|
-
if (def !== undefined && !isValidValue(def, 'boolean', false)) {
|
|
208
|
-
throw new TypeError('invalid default value');
|
|
209
|
-
}
|
|
210
|
-
const validate = val ?
|
|
211
|
-
val
|
|
212
|
-
: undefined;
|
|
213
|
-
if (hint !== undefined) {
|
|
214
|
-
throw new TypeError('cannot provide hint for flag');
|
|
165
|
+
else if ((0, exports.isConfigOptionOfType)(o, 'string', false) ||
|
|
166
|
+
(0, exports.isConfigOptionOfType)(o, 'string', true)) {
|
|
167
|
+
validateValidOptions(o.default, o.validOptions);
|
|
215
168
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
function flagList(o = {}) {
|
|
225
|
-
const { hint, default: def, validate: val, ...rest } = o;
|
|
226
|
-
delete rest.validOptions;
|
|
227
|
-
if (def !== undefined && !isValidValue(def, 'boolean', true)) {
|
|
228
|
-
throw new TypeError('invalid default value');
|
|
229
|
-
}
|
|
230
|
-
const validate = val ?
|
|
231
|
-
val
|
|
232
|
-
: undefined;
|
|
233
|
-
if (hint !== undefined) {
|
|
234
|
-
throw new TypeError('cannot provide hint for flag list');
|
|
169
|
+
else if ((0, exports.isConfigOptionOfType)(o, 'boolean', false) ||
|
|
170
|
+
(0, exports.isConfigOptionOfType)(o, 'boolean', true)) {
|
|
171
|
+
if (o.hint !== undefined) {
|
|
172
|
+
throw new TypeError('cannot provide hint for flag');
|
|
173
|
+
}
|
|
174
|
+
if (o.validOptions !== undefined) {
|
|
175
|
+
throw new TypeError('cannot provide validOptions for flag');
|
|
176
|
+
}
|
|
235
177
|
}
|
|
236
|
-
return
|
|
237
|
-
|
|
238
|
-
default: def,
|
|
239
|
-
validate,
|
|
240
|
-
type: 'boolean',
|
|
241
|
-
multiple: true,
|
|
242
|
-
};
|
|
243
|
-
}
|
|
178
|
+
return o;
|
|
179
|
+
};
|
|
244
180
|
const toParseArgsOptionsConfig = (options) => {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
: String(config.default),
|
|
267
|
-
};
|
|
181
|
+
return Object.entries(options).reduce((acc, [longOption, o]) => {
|
|
182
|
+
const p = {
|
|
183
|
+
type: 'string',
|
|
184
|
+
multiple: !!o.multiple,
|
|
185
|
+
...(typeof o.short === 'string' ? { short: o.short } : undefined),
|
|
186
|
+
};
|
|
187
|
+
const setNoBool = () => {
|
|
188
|
+
if (!longOption.startsWith('no-') && !options[`no-${longOption}`]) {
|
|
189
|
+
acc[`no-${longOption}`] = {
|
|
190
|
+
type: 'boolean',
|
|
191
|
+
multiple: !!o.multiple,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
const setDefault = (def, fn) => {
|
|
196
|
+
if (def !== undefined) {
|
|
197
|
+
p.default = fn(def);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
if ((0, exports.isConfigOption)(o, 'number', false)) {
|
|
201
|
+
setDefault(o.default, String);
|
|
268
202
|
}
|
|
269
|
-
else {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
type: 'boolean',
|
|
286
|
-
multiple: config.multiple,
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return c;
|
|
203
|
+
else if ((0, exports.isConfigOption)(o, 'number', true)) {
|
|
204
|
+
setDefault(o.default, d => d.map(v => String(v)));
|
|
205
|
+
}
|
|
206
|
+
else if ((0, exports.isConfigOption)(o, 'string', false) ||
|
|
207
|
+
(0, exports.isConfigOption)(o, 'string', true)) {
|
|
208
|
+
setDefault(o.default, v => v);
|
|
209
|
+
}
|
|
210
|
+
else if ((0, exports.isConfigOption)(o, 'boolean', false) ||
|
|
211
|
+
(0, exports.isConfigOption)(o, 'boolean', true)) {
|
|
212
|
+
p.type = 'boolean';
|
|
213
|
+
setDefault(o.default, v => v);
|
|
214
|
+
setNoBool();
|
|
215
|
+
}
|
|
216
|
+
acc[longOption] = p;
|
|
217
|
+
return acc;
|
|
218
|
+
}, {});
|
|
291
219
|
};
|
|
292
|
-
const isHeading = (r) => r.type === 'heading';
|
|
293
|
-
const isDescription = (r) => r.type === 'description';
|
|
294
220
|
/**
|
|
295
221
|
* Class returned by the {@link jack} function and all configuration
|
|
296
222
|
* definition methods. This is what gets chained together.
|
|
@@ -328,16 +254,12 @@ class Jack {
|
|
|
328
254
|
this.validate(values);
|
|
329
255
|
}
|
|
330
256
|
catch (er) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
e.cause = { path: source };
|
|
338
|
-
}
|
|
257
|
+
if (source && er instanceof Error) {
|
|
258
|
+
/* c8 ignore next */
|
|
259
|
+
const cause = typeof er.cause === 'object' ? er.cause : {};
|
|
260
|
+
er.cause = { ...cause, path: source };
|
|
339
261
|
}
|
|
340
|
-
throw
|
|
262
|
+
throw er;
|
|
341
263
|
}
|
|
342
264
|
for (const [field, value] of Object.entries(values)) {
|
|
343
265
|
const my = this.#configSet[field];
|
|
@@ -400,10 +322,9 @@ class Jack {
|
|
|
400
322
|
if (args === process.argv) {
|
|
401
323
|
args = args.slice(process._eval !== undefined ? 1 : 2);
|
|
402
324
|
}
|
|
403
|
-
const
|
|
404
|
-
const result = (0, parse_args_js_1.parseArgs)({
|
|
325
|
+
const result = (0, node_util_1.parseArgs)({
|
|
405
326
|
args,
|
|
406
|
-
options,
|
|
327
|
+
options: toParseArgsOptionsConfig(this.#configSet),
|
|
407
328
|
// always strict, but using our own logic
|
|
408
329
|
strict: false,
|
|
409
330
|
allowPositionals: this.#allowPositionals,
|
|
@@ -496,13 +417,10 @@ class Jack {
|
|
|
496
417
|
for (const [field, value] of Object.entries(p.values)) {
|
|
497
418
|
const valid = this.#configSet[field]?.validate;
|
|
498
419
|
const validOptions = this.#configSet[field]?.validOptions;
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
if (valid && !valid(value)) {
|
|
504
|
-
cause = cause || { name: field, found: value };
|
|
505
|
-
}
|
|
420
|
+
const cause = validOptions && !isValidOption(value, validOptions) ?
|
|
421
|
+
{ name: field, found: value, validOptions: validOptions }
|
|
422
|
+
: valid && !valid(value) ? { name: field, found: value }
|
|
423
|
+
: undefined;
|
|
506
424
|
if (cause) {
|
|
507
425
|
throw new Error(`Invalid value provided for --${field}: ${JSON.stringify(value)}`, { cause });
|
|
508
426
|
}
|
|
@@ -555,18 +473,11 @@ class Jack {
|
|
|
555
473
|
},
|
|
556
474
|
});
|
|
557
475
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
!
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
found: value,
|
|
564
|
-
validOptions: config.validOptions,
|
|
565
|
-
};
|
|
566
|
-
}
|
|
567
|
-
if (config.validate && !config.validate(value)) {
|
|
568
|
-
cause = cause || { name: field, found: value };
|
|
569
|
-
}
|
|
476
|
+
const cause = config.validOptions && !isValidOption(value, config.validOptions) ?
|
|
477
|
+
{ name: field, found: value, validOptions: config.validOptions }
|
|
478
|
+
: config.validate && !config.validate(value) ?
|
|
479
|
+
{ name: field, found: value }
|
|
480
|
+
: undefined;
|
|
570
481
|
if (cause) {
|
|
571
482
|
throw new Error(`Invalid config value for ${field}: ${value}`, {
|
|
572
483
|
cause,
|
|
@@ -603,37 +514,37 @@ class Jack {
|
|
|
603
514
|
* Add one or more number fields.
|
|
604
515
|
*/
|
|
605
516
|
num(fields) {
|
|
606
|
-
return this.#
|
|
517
|
+
return this.#addFieldsWith(fields, 'number', false);
|
|
607
518
|
}
|
|
608
519
|
/**
|
|
609
520
|
* Add one or more multiple number fields.
|
|
610
521
|
*/
|
|
611
522
|
numList(fields) {
|
|
612
|
-
return this.#
|
|
523
|
+
return this.#addFieldsWith(fields, 'number', true);
|
|
613
524
|
}
|
|
614
525
|
/**
|
|
615
526
|
* Add one or more string option fields.
|
|
616
527
|
*/
|
|
617
528
|
opt(fields) {
|
|
618
|
-
return this.#
|
|
529
|
+
return this.#addFieldsWith(fields, 'string', false);
|
|
619
530
|
}
|
|
620
531
|
/**
|
|
621
532
|
* Add one or more multiple string option fields.
|
|
622
533
|
*/
|
|
623
534
|
optList(fields) {
|
|
624
|
-
return this.#
|
|
535
|
+
return this.#addFieldsWith(fields, 'string', true);
|
|
625
536
|
}
|
|
626
537
|
/**
|
|
627
538
|
* Add one or more flag fields.
|
|
628
539
|
*/
|
|
629
540
|
flag(fields) {
|
|
630
|
-
return this.#
|
|
541
|
+
return this.#addFieldsWith(fields, 'boolean', false);
|
|
631
542
|
}
|
|
632
543
|
/**
|
|
633
544
|
* Add one or more multiple flag fields.
|
|
634
545
|
*/
|
|
635
546
|
flagList(fields) {
|
|
636
|
-
return this.#
|
|
547
|
+
return this.#addFieldsWith(fields, 'boolean', true);
|
|
637
548
|
}
|
|
638
549
|
/**
|
|
639
550
|
* Generic field definition method. Similar to flag/flagList/number/etc,
|
|
@@ -641,29 +552,22 @@ class Jack {
|
|
|
641
552
|
* fields on each one, or Jack won't know how to define them.
|
|
642
553
|
*/
|
|
643
554
|
addFields(fields) {
|
|
644
|
-
|
|
645
|
-
for (const [name, field] of Object.entries(fields)) {
|
|
646
|
-
this.#validateName(name, field);
|
|
647
|
-
next.#fields.push({
|
|
648
|
-
type: 'config',
|
|
649
|
-
name,
|
|
650
|
-
value: field,
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
Object.assign(next.#configSet, fields);
|
|
654
|
-
return next;
|
|
555
|
+
return this.#addFields(this, fields);
|
|
655
556
|
}
|
|
656
|
-
#
|
|
657
|
-
|
|
557
|
+
#addFieldsWith(fields, type, multiple) {
|
|
558
|
+
return this.#addFields(this, fields, {
|
|
559
|
+
type,
|
|
560
|
+
multiple,
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
#addFields(next, fields, opt) {
|
|
658
564
|
Object.assign(next.#configSet, Object.fromEntries(Object.entries(fields).map(([name, field]) => {
|
|
659
565
|
this.#validateName(name, field);
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
});
|
|
666
|
-
return [name, option];
|
|
566
|
+
const { type, multiple } = validateFieldMeta(field, opt);
|
|
567
|
+
const value = { ...field, type, multiple };
|
|
568
|
+
validateField(value, type, multiple);
|
|
569
|
+
next.#fields.push({ type: 'config', name, value });
|
|
570
|
+
return [name, value];
|
|
667
571
|
})));
|
|
668
572
|
return next;
|
|
669
573
|
}
|
|
@@ -699,6 +603,7 @@ class Jack {
|
|
|
699
603
|
if (this.#usage)
|
|
700
604
|
return this.#usage;
|
|
701
605
|
let headingLevel = 1;
|
|
606
|
+
//@ts-ignore
|
|
702
607
|
const ui = (0, cliui_1.default)({ width });
|
|
703
608
|
const first = this.#fields[0];
|
|
704
609
|
let start = first?.type === 'heading' ? 1 : 0;
|
|
@@ -941,6 +846,11 @@ class Jack {
|
|
|
941
846
|
}
|
|
942
847
|
}
|
|
943
848
|
exports.Jack = Jack;
|
|
849
|
+
/**
|
|
850
|
+
* Main entry point. Create and return a {@link Jack} object.
|
|
851
|
+
*/
|
|
852
|
+
const jack = (options = {}) => new Jack(options);
|
|
853
|
+
exports.jack = jack;
|
|
944
854
|
// Unwrap and un-indent, so we can wrap description
|
|
945
855
|
// strings however makes them look nice in the code.
|
|
946
856
|
const normalize = (s, pre = false) => {
|
|
@@ -1002,9 +912,4 @@ const normalizeOneLine = (s, pre = false) => {
|
|
|
1002
912
|
.trim();
|
|
1003
913
|
return pre ? `\`${n}\`` : n;
|
|
1004
914
|
};
|
|
1005
|
-
/**
|
|
1006
|
-
* Main entry point. Create and return a {@link Jack} object.
|
|
1007
|
-
*/
|
|
1008
|
-
const jack = (options = {}) => new Jack(options);
|
|
1009
|
-
exports.jack = jack;
|
|
1010
915
|
//# sourceMappingURL=index.js.map
|