toilscript 0.0.1 → 0.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/LICENSE +201 -201
- package/NOTICE +94 -94
- package/README.md +101 -114
- package/bin/asc.js +0 -0
- package/bin/asinit.js +0 -0
- package/dist/asc.generated.d.ts +10022 -0
- package/dist/asc.js +24457 -0
- package/dist/asc.js.map +7 -0
- package/dist/importmap.json +9 -0
- package/dist/toilscript.generated.d.ts +11237 -0
- package/dist/toilscript.js +337 -0
- package/dist/toilscript.js.map +7 -0
- package/dist/web.js +22 -0
- package/lib/binaryen.d.ts +2 -2
- package/lib/binaryen.js +2 -2
- package/package.json +115 -114
- package/std/README.md +6 -6
- package/std/assembly/array.ts +550 -550
- package/std/assembly/arraybuffer.ts +77 -77
- package/std/assembly/atomics.ts +127 -127
- package/std/assembly/bindings/asyncify.ts +16 -16
- package/std/assembly/bindings/dom.ts +291 -291
- package/std/assembly/bindings/node.ts +6 -6
- package/std/assembly/bitflags.ts +53 -53
- package/std/assembly/builtins.ts +2650 -2650
- package/std/assembly/byteslice.ts +177 -177
- package/std/assembly/compat.ts +2 -2
- package/std/assembly/console.ts +42 -42
- package/std/assembly/crypto.ts +9 -9
- package/std/assembly/dataview.ts +181 -181
- package/std/assembly/date.ts +375 -375
- package/std/assembly/diagnostics.ts +11 -11
- package/std/assembly/encoding.ts +151 -151
- package/std/assembly/endian.ts +45 -45
- package/std/assembly/error.ts +44 -44
- package/std/assembly/fixedarray.ts +173 -173
- package/std/assembly/fixedmap.ts +326 -326
- package/std/assembly/fixedset.ts +275 -275
- package/std/assembly/function.ts +42 -42
- package/std/assembly/index.d.ts +2891 -2891
- package/std/assembly/iterator.ts +35 -35
- package/std/assembly/map.ts +269 -269
- package/std/assembly/math.ts +3289 -3289
- package/std/assembly/memory.ts +123 -123
- package/std/assembly/number.ts +388 -388
- package/std/assembly/object.ts +36 -36
- package/std/assembly/performance.ts +9 -9
- package/std/assembly/pointer.ts +80 -80
- package/std/assembly/polyfills.ts +27 -27
- package/std/assembly/process.ts +50 -50
- package/std/assembly/reference.ts +48 -48
- package/std/assembly/regexp.ts +12 -12
- package/std/assembly/rt/README.md +83 -83
- package/std/assembly/rt/common.ts +81 -81
- package/std/assembly/rt/index-incremental.ts +2 -2
- package/std/assembly/rt/index-memory.ts +1 -1
- package/std/assembly/rt/index-minimal.ts +2 -2
- package/std/assembly/rt/index-stub.ts +1 -1
- package/std/assembly/rt/index.d.ts +37 -37
- package/std/assembly/rt/itcms.ts +419 -419
- package/std/assembly/rt/memory-runtime.ts +94 -94
- package/std/assembly/rt/rtrace.ts +15 -15
- package/std/assembly/rt/stub.ts +133 -133
- package/std/assembly/rt/tcms.ts +254 -254
- package/std/assembly/rt/tlsf.ts +592 -592
- package/std/assembly/rt.ts +90 -90
- package/std/assembly/set.ts +225 -225
- package/std/assembly/shared/feature.ts +68 -68
- package/std/assembly/shared/runtime.ts +13 -13
- package/std/assembly/shared/target.ts +11 -11
- package/std/assembly/shared/tsconfig.json +11 -11
- package/std/assembly/shared/typeinfo.ts +72 -72
- package/std/assembly/staticarray.ts +423 -423
- package/std/assembly/string.ts +850 -850
- package/std/assembly/symbol.ts +114 -114
- package/std/assembly/table.ts +16 -16
- package/std/assembly/tsconfig.json +6 -6
- package/std/assembly/typedarray.ts +1954 -1954
- package/std/assembly/uri.ts +17 -17
- package/std/assembly/util/bytes.ts +107 -107
- package/std/assembly/util/casemap.ts +497 -497
- package/std/assembly/util/error.ts +58 -58
- package/std/assembly/util/hash.ts +117 -117
- package/std/assembly/util/math.ts +1922 -1922
- package/std/assembly/util/memory.ts +290 -290
- package/std/assembly/util/number.ts +873 -873
- package/std/assembly/util/sort.ts +313 -313
- package/std/assembly/util/string.ts +1202 -1202
- package/std/assembly/util/uri.ts +275 -275
- package/std/assembly/vector.ts +4 -4
- package/std/assembly.json +16 -16
- package/std/portable/index.d.ts +461 -461
- package/std/portable/index.js +416 -416
- package/std/portable.json +11 -11
- package/std/types/assembly/index.d.ts +1 -1
- package/std/types/assembly/package.json +2 -2
- package/std/types/portable/index.d.ts +1 -1
- package/std/types/portable/package.json +2 -2
- package/tsconfig-base.json +13 -13
- package/util/README.md +23 -23
- package/util/browser/fs.js +1 -1
- package/util/browser/module.js +5 -5
- package/util/browser/path.js +520 -520
- package/util/browser/process.js +59 -59
- package/util/browser/url.js +23 -23
- package/util/cpu.d.ts +9 -9
- package/util/cpu.js +42 -42
- package/util/find.d.ts +6 -6
- package/util/find.js +20 -20
- package/util/node.d.ts +21 -21
- package/util/node.js +34 -34
- package/util/options.d.ts +70 -70
- package/util/options.js +262 -262
- package/util/terminal.d.ts +52 -52
- package/util/terminal.js +35 -35
- package/util/text.d.ts +26 -26
- package/util/text.js +114 -114
- package/util/tsconfig.json +9 -9
- package/util/web.d.ts +11 -11
- package/util/web.js +33 -33
package/util/options.js
CHANGED
|
@@ -1,262 +1,262 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Command line options utility.
|
|
3
|
-
* @license Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { path, module } from "./node.js";
|
|
7
|
-
import { stdoutColors } from "./terminal.js";
|
|
8
|
-
|
|
9
|
-
const require = module.createRequire(import.meta.url);
|
|
10
|
-
|
|
11
|
-
// type | meaning
|
|
12
|
-
// -----|---------------
|
|
13
|
-
// b | boolean
|
|
14
|
-
// i | integer
|
|
15
|
-
// f | float
|
|
16
|
-
// s | string
|
|
17
|
-
// I | integer array
|
|
18
|
-
// F | float array
|
|
19
|
-
// S | string array
|
|
20
|
-
|
|
21
|
-
/** Parses the specified command line arguments according to the given configuration. */
|
|
22
|
-
export function parse(argv, config, propagateDefaults = true) {
|
|
23
|
-
var options = {};
|
|
24
|
-
var unknown = [];
|
|
25
|
-
var args = [];
|
|
26
|
-
var trailing = [];
|
|
27
|
-
|
|
28
|
-
// make an alias map and initialize defaults
|
|
29
|
-
var aliases = {};
|
|
30
|
-
Object.keys(config).forEach(key => {
|
|
31
|
-
if (key.startsWith(" ")) return;
|
|
32
|
-
var option = config[key];
|
|
33
|
-
if (option.alias != null) {
|
|
34
|
-
if (typeof option.alias === "string") aliases[option.alias] = key;
|
|
35
|
-
else if (Array.isArray(option.alias)) option.alias.forEach(alias => aliases[alias] = key);
|
|
36
|
-
}
|
|
37
|
-
if (propagateDefaults && option.default != null) options[key] = option.default;
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// iterate over argv
|
|
41
|
-
for (var i = 0, k = (argv = argv.slice()).length; i < k; ++i) {
|
|
42
|
-
let arg = argv[i];
|
|
43
|
-
if (arg == "--") { ++i; break; }
|
|
44
|
-
let match = /^(?:(-\w)(?:=(.*))?|(--\w{2,})(?:=(.*))?)$/.exec(arg), option, key;
|
|
45
|
-
if (match) {
|
|
46
|
-
if (config[arg]) option = config[key = arg]; // exact
|
|
47
|
-
else if (match[1] != null) { // alias
|
|
48
|
-
option = config[key = aliases[match[1].substring(1)]];
|
|
49
|
-
if (option && match[2] != null) argv[i--] = match[2];
|
|
50
|
-
} else if (match[3] != null) { // full
|
|
51
|
-
option = config[key = match[3].substring(2)];
|
|
52
|
-
if (option && match[4] != null) argv[i--] = match[4];
|
|
53
|
-
}
|
|
54
|
-
} else {
|
|
55
|
-
if (arg.charCodeAt(0) == 45) option = config[key = arg]; // exact
|
|
56
|
-
else { args.push(arg); continue; } // argument
|
|
57
|
-
}
|
|
58
|
-
if (option) {
|
|
59
|
-
if (option.value) {
|
|
60
|
-
// alias setting fixed values
|
|
61
|
-
Object.keys(option.value).forEach(k => options[k] = option.value[k]);
|
|
62
|
-
} else if (option.type == null || option.type === "b") {
|
|
63
|
-
// boolean flag not taking a value
|
|
64
|
-
options[key] = true;
|
|
65
|
-
} else {
|
|
66
|
-
if (i + 1 < argv.length && argv[i + 1].charCodeAt(0) != 45) {
|
|
67
|
-
// non-boolean with given value
|
|
68
|
-
switch (option.type) {
|
|
69
|
-
case "i": options[key] = parseInt(argv[++i], 10); break;
|
|
70
|
-
case "I": options[key] = (options[key] || []).concat(parseInt(argv[++i], 10)); break;
|
|
71
|
-
case "f": options[key] = parseFloat(argv[++i]); break;
|
|
72
|
-
case "F": options[key] = (options[key] || []).concat(parseFloat(argv[++i])); break;
|
|
73
|
-
case "s": options[key] = String(argv[++i]); break;
|
|
74
|
-
case "S": options[key] = (options[key] || []).concat(argv[++i].split(",")); break;
|
|
75
|
-
default: unknown.push(arg); --i;
|
|
76
|
-
}
|
|
77
|
-
} else {
|
|
78
|
-
// non-boolean with omitted value
|
|
79
|
-
switch (option.type) {
|
|
80
|
-
case "i":
|
|
81
|
-
case "f": options[key] = option.default || 0; break;
|
|
82
|
-
case "s": options[key] = option.default || ""; break;
|
|
83
|
-
case "I":
|
|
84
|
-
case "F":
|
|
85
|
-
case "S": options[key] = option.default || []; break;
|
|
86
|
-
default: unknown.push(arg);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
} else unknown.push(arg);
|
|
91
|
-
}
|
|
92
|
-
while (i < k) trailing.push(argv[i++]); // trailing
|
|
93
|
-
if (propagateDefaults) addDefaults(config, options);
|
|
94
|
-
|
|
95
|
-
return { options, unknown, arguments: args, trailing };
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** Generates the help text for the specified configuration. */
|
|
99
|
-
export function help(config, options) {
|
|
100
|
-
if (!options) options = {};
|
|
101
|
-
var indent = options.indent || 2;
|
|
102
|
-
var padding = options.padding || 24;
|
|
103
|
-
var eol = options.eol || "\n";
|
|
104
|
-
var sbCategories = {};
|
|
105
|
-
var sbOther = [];
|
|
106
|
-
Object.keys(config).forEach(key => {
|
|
107
|
-
var option = config[key];
|
|
108
|
-
if (option.description == null) return;
|
|
109
|
-
var text = "";
|
|
110
|
-
while (text.length < indent) text += " ";
|
|
111
|
-
text += "--" + key;
|
|
112
|
-
if (option.alias) text += ", -" + option.alias;
|
|
113
|
-
while (text.length < padding) text += " ";
|
|
114
|
-
var sb;
|
|
115
|
-
if (!options.noCategories && option.category) {
|
|
116
|
-
if (!(sb = sbCategories[option.category])) {
|
|
117
|
-
sbCategories[option.category] = sb = [];
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
sb = sbOther;
|
|
121
|
-
}
|
|
122
|
-
if (Array.isArray(option.description)) {
|
|
123
|
-
sb.push(text + option.description[0] + option.description.slice(1).map(line => {
|
|
124
|
-
for (let i = 0; i < padding; ++i) line = " " + line;
|
|
125
|
-
return eol + line;
|
|
126
|
-
}).join(""));
|
|
127
|
-
} else sb.push(text + option.description);
|
|
128
|
-
});
|
|
129
|
-
var sb = [];
|
|
130
|
-
var hasCategories = false;
|
|
131
|
-
Object.keys(sbCategories).forEach(category => {
|
|
132
|
-
hasCategories = true;
|
|
133
|
-
sb.push(eol + " " + stdoutColors.gray(category) + eol);
|
|
134
|
-
sb.push(sbCategories[category].join(eol));
|
|
135
|
-
});
|
|
136
|
-
if (hasCategories && sbOther.length) {
|
|
137
|
-
sb.push(eol + " " + stdoutColors.gray("Other") + eol);
|
|
138
|
-
}
|
|
139
|
-
sb.push(sbOther.join(eol));
|
|
140
|
-
return sb.join(eol);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/** Sanitizes an option value to be a valid value of the option's type. */
|
|
144
|
-
function sanitizeValue(value, type) {
|
|
145
|
-
if (value != null) {
|
|
146
|
-
switch (type) {
|
|
147
|
-
case undefined:
|
|
148
|
-
case "b": return Boolean(value);
|
|
149
|
-
case "i": return Math.trunc(value) || 0;
|
|
150
|
-
case "f": return Number(value) || 0;
|
|
151
|
-
case "s": {
|
|
152
|
-
if (value === true) return "";
|
|
153
|
-
if (value === false) return null;
|
|
154
|
-
return String(value);
|
|
155
|
-
}
|
|
156
|
-
case "I": {
|
|
157
|
-
if (!Array.isArray(value)) value = [ value ];
|
|
158
|
-
return value.map(v => Math.trunc(v) || 0);
|
|
159
|
-
}
|
|
160
|
-
case "F": {
|
|
161
|
-
if (!Array.isArray(value)) value = [ value ];
|
|
162
|
-
return value.map(v => Number(v) || 0);
|
|
163
|
-
}
|
|
164
|
-
case "S": {
|
|
165
|
-
if (!Array.isArray(value)) value = [ value ];
|
|
166
|
-
return value.map(String);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return undefined;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/** Merges two sets of options into one, preferring the current over the parent set. */
|
|
174
|
-
export function merge(config, currentOptions, parentOptions, parentBaseDir) {
|
|
175
|
-
const mergedOptions = {};
|
|
176
|
-
for (const [key, { type, mutuallyExclusive, isPath, useNodeResolution, cliOnly }] of Object.entries(config)) {
|
|
177
|
-
let currentValue = sanitizeValue(currentOptions[key], type);
|
|
178
|
-
let parentValue = sanitizeValue(parentOptions[key], type);
|
|
179
|
-
if (currentValue == null) {
|
|
180
|
-
if (parentValue != null) {
|
|
181
|
-
// only parent value present
|
|
182
|
-
if (cliOnly) continue;
|
|
183
|
-
if (Array.isArray(parentValue)) {
|
|
184
|
-
let exclude;
|
|
185
|
-
if (isPath) {
|
|
186
|
-
parentValue = parentValue.map(value => resolvePath(value, parentBaseDir, useNodeResolution));
|
|
187
|
-
}
|
|
188
|
-
if (mutuallyExclusive != null && (exclude = currentOptions[mutuallyExclusive])) {
|
|
189
|
-
mergedOptions[key] = parentValue.filter(value => !exclude.includes(value));
|
|
190
|
-
} else {
|
|
191
|
-
mergedOptions[key] = parentValue.slice();
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
if (isPath) {
|
|
195
|
-
parentValue = resolvePath(parentValue, parentBaseDir, useNodeResolution);
|
|
196
|
-
}
|
|
197
|
-
mergedOptions[key] = parentValue;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
} else if (parentValue == null) {
|
|
201
|
-
// only current value present
|
|
202
|
-
if (Array.isArray(currentValue)) {
|
|
203
|
-
mergedOptions[key] = currentValue.slice();
|
|
204
|
-
} else {
|
|
205
|
-
mergedOptions[key] = currentValue;
|
|
206
|
-
}
|
|
207
|
-
} else {
|
|
208
|
-
// both current and parent values present
|
|
209
|
-
if (Array.isArray(currentValue)) {
|
|
210
|
-
if (cliOnly) {
|
|
211
|
-
mergedOptions[key] = currentValue.slice();
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
let exclude;
|
|
215
|
-
if (isPath) {
|
|
216
|
-
parentValue = parentValue.map(value => resolvePath(value, parentBaseDir, useNodeResolution));
|
|
217
|
-
}
|
|
218
|
-
if (mutuallyExclusive != null && (exclude = currentOptions[mutuallyExclusive])) {
|
|
219
|
-
mergedOptions[key] = [
|
|
220
|
-
...currentValue,
|
|
221
|
-
...parentValue.filter(value => !currentValue.includes(value) && !exclude.includes(value))
|
|
222
|
-
];
|
|
223
|
-
} else {
|
|
224
|
-
mergedOptions[key] = [
|
|
225
|
-
...currentValue,
|
|
226
|
-
...parentValue.filter(value => !currentValue.includes(value)) // dedup
|
|
227
|
-
];
|
|
228
|
-
}
|
|
229
|
-
} else {
|
|
230
|
-
mergedOptions[key] = currentValue;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return mergedOptions;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/** Normalizes a path. */
|
|
238
|
-
export function normalizePath(p) {
|
|
239
|
-
const parsed = path.parse(p);
|
|
240
|
-
if (!parsed.root) {
|
|
241
|
-
parsed.root = "./";
|
|
242
|
-
}
|
|
243
|
-
return path.format(parsed);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/** Resolves a single possibly relative path. Keeps absolute paths, otherwise prepends baseDir. */
|
|
247
|
-
export function resolvePath(p, baseDir, useNodeResolution = false) {
|
|
248
|
-
if (path.isAbsolute(p)) return p;
|
|
249
|
-
if (useNodeResolution && !p.startsWith(".") && require.resolve) {
|
|
250
|
-
return require.resolve(p, { paths: [ baseDir ] });
|
|
251
|
-
}
|
|
252
|
-
return normalizePath(path.join(baseDir, p));
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/** Populates default values on a parsed options result. */
|
|
256
|
-
export function addDefaults(config, options) {
|
|
257
|
-
for (const [key, { default: defaultValue }] of Object.entries(config)) {
|
|
258
|
-
if (options[key] == null && defaultValue != null) {
|
|
259
|
-
options[key] = defaultValue;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Command line options utility.
|
|
3
|
+
* @license Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { path, module } from "./node.js";
|
|
7
|
+
import { stdoutColors } from "./terminal.js";
|
|
8
|
+
|
|
9
|
+
const require = module.createRequire(import.meta.url);
|
|
10
|
+
|
|
11
|
+
// type | meaning
|
|
12
|
+
// -----|---------------
|
|
13
|
+
// b | boolean
|
|
14
|
+
// i | integer
|
|
15
|
+
// f | float
|
|
16
|
+
// s | string
|
|
17
|
+
// I | integer array
|
|
18
|
+
// F | float array
|
|
19
|
+
// S | string array
|
|
20
|
+
|
|
21
|
+
/** Parses the specified command line arguments according to the given configuration. */
|
|
22
|
+
export function parse(argv, config, propagateDefaults = true) {
|
|
23
|
+
var options = {};
|
|
24
|
+
var unknown = [];
|
|
25
|
+
var args = [];
|
|
26
|
+
var trailing = [];
|
|
27
|
+
|
|
28
|
+
// make an alias map and initialize defaults
|
|
29
|
+
var aliases = {};
|
|
30
|
+
Object.keys(config).forEach(key => {
|
|
31
|
+
if (key.startsWith(" ")) return;
|
|
32
|
+
var option = config[key];
|
|
33
|
+
if (option.alias != null) {
|
|
34
|
+
if (typeof option.alias === "string") aliases[option.alias] = key;
|
|
35
|
+
else if (Array.isArray(option.alias)) option.alias.forEach(alias => aliases[alias] = key);
|
|
36
|
+
}
|
|
37
|
+
if (propagateDefaults && option.default != null) options[key] = option.default;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// iterate over argv
|
|
41
|
+
for (var i = 0, k = (argv = argv.slice()).length; i < k; ++i) {
|
|
42
|
+
let arg = argv[i];
|
|
43
|
+
if (arg == "--") { ++i; break; }
|
|
44
|
+
let match = /^(?:(-\w)(?:=(.*))?|(--\w{2,})(?:=(.*))?)$/.exec(arg), option, key;
|
|
45
|
+
if (match) {
|
|
46
|
+
if (config[arg]) option = config[key = arg]; // exact
|
|
47
|
+
else if (match[1] != null) { // alias
|
|
48
|
+
option = config[key = aliases[match[1].substring(1)]];
|
|
49
|
+
if (option && match[2] != null) argv[i--] = match[2];
|
|
50
|
+
} else if (match[3] != null) { // full
|
|
51
|
+
option = config[key = match[3].substring(2)];
|
|
52
|
+
if (option && match[4] != null) argv[i--] = match[4];
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
if (arg.charCodeAt(0) == 45) option = config[key = arg]; // exact
|
|
56
|
+
else { args.push(arg); continue; } // argument
|
|
57
|
+
}
|
|
58
|
+
if (option) {
|
|
59
|
+
if (option.value) {
|
|
60
|
+
// alias setting fixed values
|
|
61
|
+
Object.keys(option.value).forEach(k => options[k] = option.value[k]);
|
|
62
|
+
} else if (option.type == null || option.type === "b") {
|
|
63
|
+
// boolean flag not taking a value
|
|
64
|
+
options[key] = true;
|
|
65
|
+
} else {
|
|
66
|
+
if (i + 1 < argv.length && argv[i + 1].charCodeAt(0) != 45) {
|
|
67
|
+
// non-boolean with given value
|
|
68
|
+
switch (option.type) {
|
|
69
|
+
case "i": options[key] = parseInt(argv[++i], 10); break;
|
|
70
|
+
case "I": options[key] = (options[key] || []).concat(parseInt(argv[++i], 10)); break;
|
|
71
|
+
case "f": options[key] = parseFloat(argv[++i]); break;
|
|
72
|
+
case "F": options[key] = (options[key] || []).concat(parseFloat(argv[++i])); break;
|
|
73
|
+
case "s": options[key] = String(argv[++i]); break;
|
|
74
|
+
case "S": options[key] = (options[key] || []).concat(argv[++i].split(",")); break;
|
|
75
|
+
default: unknown.push(arg); --i;
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
// non-boolean with omitted value
|
|
79
|
+
switch (option.type) {
|
|
80
|
+
case "i":
|
|
81
|
+
case "f": options[key] = option.default || 0; break;
|
|
82
|
+
case "s": options[key] = option.default || ""; break;
|
|
83
|
+
case "I":
|
|
84
|
+
case "F":
|
|
85
|
+
case "S": options[key] = option.default || []; break;
|
|
86
|
+
default: unknown.push(arg);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} else unknown.push(arg);
|
|
91
|
+
}
|
|
92
|
+
while (i < k) trailing.push(argv[i++]); // trailing
|
|
93
|
+
if (propagateDefaults) addDefaults(config, options);
|
|
94
|
+
|
|
95
|
+
return { options, unknown, arguments: args, trailing };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Generates the help text for the specified configuration. */
|
|
99
|
+
export function help(config, options) {
|
|
100
|
+
if (!options) options = {};
|
|
101
|
+
var indent = options.indent || 2;
|
|
102
|
+
var padding = options.padding || 24;
|
|
103
|
+
var eol = options.eol || "\n";
|
|
104
|
+
var sbCategories = {};
|
|
105
|
+
var sbOther = [];
|
|
106
|
+
Object.keys(config).forEach(key => {
|
|
107
|
+
var option = config[key];
|
|
108
|
+
if (option.description == null) return;
|
|
109
|
+
var text = "";
|
|
110
|
+
while (text.length < indent) text += " ";
|
|
111
|
+
text += "--" + key;
|
|
112
|
+
if (option.alias) text += ", -" + option.alias;
|
|
113
|
+
while (text.length < padding) text += " ";
|
|
114
|
+
var sb;
|
|
115
|
+
if (!options.noCategories && option.category) {
|
|
116
|
+
if (!(sb = sbCategories[option.category])) {
|
|
117
|
+
sbCategories[option.category] = sb = [];
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
sb = sbOther;
|
|
121
|
+
}
|
|
122
|
+
if (Array.isArray(option.description)) {
|
|
123
|
+
sb.push(text + option.description[0] + option.description.slice(1).map(line => {
|
|
124
|
+
for (let i = 0; i < padding; ++i) line = " " + line;
|
|
125
|
+
return eol + line;
|
|
126
|
+
}).join(""));
|
|
127
|
+
} else sb.push(text + option.description);
|
|
128
|
+
});
|
|
129
|
+
var sb = [];
|
|
130
|
+
var hasCategories = false;
|
|
131
|
+
Object.keys(sbCategories).forEach(category => {
|
|
132
|
+
hasCategories = true;
|
|
133
|
+
sb.push(eol + " " + stdoutColors.gray(category) + eol);
|
|
134
|
+
sb.push(sbCategories[category].join(eol));
|
|
135
|
+
});
|
|
136
|
+
if (hasCategories && sbOther.length) {
|
|
137
|
+
sb.push(eol + " " + stdoutColors.gray("Other") + eol);
|
|
138
|
+
}
|
|
139
|
+
sb.push(sbOther.join(eol));
|
|
140
|
+
return sb.join(eol);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Sanitizes an option value to be a valid value of the option's type. */
|
|
144
|
+
function sanitizeValue(value, type) {
|
|
145
|
+
if (value != null) {
|
|
146
|
+
switch (type) {
|
|
147
|
+
case undefined:
|
|
148
|
+
case "b": return Boolean(value);
|
|
149
|
+
case "i": return Math.trunc(value) || 0;
|
|
150
|
+
case "f": return Number(value) || 0;
|
|
151
|
+
case "s": {
|
|
152
|
+
if (value === true) return "";
|
|
153
|
+
if (value === false) return null;
|
|
154
|
+
return String(value);
|
|
155
|
+
}
|
|
156
|
+
case "I": {
|
|
157
|
+
if (!Array.isArray(value)) value = [ value ];
|
|
158
|
+
return value.map(v => Math.trunc(v) || 0);
|
|
159
|
+
}
|
|
160
|
+
case "F": {
|
|
161
|
+
if (!Array.isArray(value)) value = [ value ];
|
|
162
|
+
return value.map(v => Number(v) || 0);
|
|
163
|
+
}
|
|
164
|
+
case "S": {
|
|
165
|
+
if (!Array.isArray(value)) value = [ value ];
|
|
166
|
+
return value.map(String);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Merges two sets of options into one, preferring the current over the parent set. */
|
|
174
|
+
export function merge(config, currentOptions, parentOptions, parentBaseDir) {
|
|
175
|
+
const mergedOptions = {};
|
|
176
|
+
for (const [key, { type, mutuallyExclusive, isPath, useNodeResolution, cliOnly }] of Object.entries(config)) {
|
|
177
|
+
let currentValue = sanitizeValue(currentOptions[key], type);
|
|
178
|
+
let parentValue = sanitizeValue(parentOptions[key], type);
|
|
179
|
+
if (currentValue == null) {
|
|
180
|
+
if (parentValue != null) {
|
|
181
|
+
// only parent value present
|
|
182
|
+
if (cliOnly) continue;
|
|
183
|
+
if (Array.isArray(parentValue)) {
|
|
184
|
+
let exclude;
|
|
185
|
+
if (isPath) {
|
|
186
|
+
parentValue = parentValue.map(value => resolvePath(value, parentBaseDir, useNodeResolution));
|
|
187
|
+
}
|
|
188
|
+
if (mutuallyExclusive != null && (exclude = currentOptions[mutuallyExclusive])) {
|
|
189
|
+
mergedOptions[key] = parentValue.filter(value => !exclude.includes(value));
|
|
190
|
+
} else {
|
|
191
|
+
mergedOptions[key] = parentValue.slice();
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
if (isPath) {
|
|
195
|
+
parentValue = resolvePath(parentValue, parentBaseDir, useNodeResolution);
|
|
196
|
+
}
|
|
197
|
+
mergedOptions[key] = parentValue;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} else if (parentValue == null) {
|
|
201
|
+
// only current value present
|
|
202
|
+
if (Array.isArray(currentValue)) {
|
|
203
|
+
mergedOptions[key] = currentValue.slice();
|
|
204
|
+
} else {
|
|
205
|
+
mergedOptions[key] = currentValue;
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
// both current and parent values present
|
|
209
|
+
if (Array.isArray(currentValue)) {
|
|
210
|
+
if (cliOnly) {
|
|
211
|
+
mergedOptions[key] = currentValue.slice();
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
let exclude;
|
|
215
|
+
if (isPath) {
|
|
216
|
+
parentValue = parentValue.map(value => resolvePath(value, parentBaseDir, useNodeResolution));
|
|
217
|
+
}
|
|
218
|
+
if (mutuallyExclusive != null && (exclude = currentOptions[mutuallyExclusive])) {
|
|
219
|
+
mergedOptions[key] = [
|
|
220
|
+
...currentValue,
|
|
221
|
+
...parentValue.filter(value => !currentValue.includes(value) && !exclude.includes(value))
|
|
222
|
+
];
|
|
223
|
+
} else {
|
|
224
|
+
mergedOptions[key] = [
|
|
225
|
+
...currentValue,
|
|
226
|
+
...parentValue.filter(value => !currentValue.includes(value)) // dedup
|
|
227
|
+
];
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
mergedOptions[key] = currentValue;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return mergedOptions;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Normalizes a path. */
|
|
238
|
+
export function normalizePath(p) {
|
|
239
|
+
const parsed = path.parse(p);
|
|
240
|
+
if (!parsed.root) {
|
|
241
|
+
parsed.root = "./";
|
|
242
|
+
}
|
|
243
|
+
return path.format(parsed);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** Resolves a single possibly relative path. Keeps absolute paths, otherwise prepends baseDir. */
|
|
247
|
+
export function resolvePath(p, baseDir, useNodeResolution = false) {
|
|
248
|
+
if (path.isAbsolute(p)) return p;
|
|
249
|
+
if (useNodeResolution && !p.startsWith(".") && require.resolve) {
|
|
250
|
+
return require.resolve(p, { paths: [ baseDir ] });
|
|
251
|
+
}
|
|
252
|
+
return normalizePath(path.join(baseDir, p));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/** Populates default values on a parsed options result. */
|
|
256
|
+
export function addDefaults(config, options) {
|
|
257
|
+
for (const [key, { default: defaultValue }] of Object.entries(config)) {
|
|
258
|
+
if (options[key] == null && defaultValue != null) {
|
|
259
|
+
options[key] = defaultValue;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
package/util/terminal.d.ts
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Terminal colors utility definitions.
|
|
3
|
-
* @license Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/** Color code for gray. */
|
|
7
|
-
export const GRAY: string;
|
|
8
|
-
/** Color code for red. */
|
|
9
|
-
export const RED: string;
|
|
10
|
-
/** Color code for green. */
|
|
11
|
-
export const GREEN: string;
|
|
12
|
-
/** Color code for yellow. */
|
|
13
|
-
export const YELLOW: string;
|
|
14
|
-
/** Color code for blue. */
|
|
15
|
-
export const BLUE: string;
|
|
16
|
-
/** Color code for magenta. */
|
|
17
|
-
export const MAGENTA: string;
|
|
18
|
-
/** Color code for cyan. */
|
|
19
|
-
export const CYAN: string;
|
|
20
|
-
/** Color code for white. */
|
|
21
|
-
export const WHITE: string;
|
|
22
|
-
/** Code to reset any colors. */
|
|
23
|
-
export const RESET: string;
|
|
24
|
-
|
|
25
|
-
/** Color utility class. */
|
|
26
|
-
export class Colors {
|
|
27
|
-
/** Constructs a new instance for the given stream. */
|
|
28
|
-
constructor(stream: { isTTY: boolean });
|
|
29
|
-
/** Whether terminal colors are enabled. */
|
|
30
|
-
enabled: boolean;
|
|
31
|
-
/** Colors a string in gray if {@link enabled}. */
|
|
32
|
-
gray(text: string): string;
|
|
33
|
-
/** Colors a string in red if {@link enabled}. */
|
|
34
|
-
red(text: string): string;
|
|
35
|
-
/** Colors a string in green if {@link enabled}. */
|
|
36
|
-
green(text: string): string;
|
|
37
|
-
/** Colors a string in yellow if {@link enabled}. */
|
|
38
|
-
yellow(text: string): string;
|
|
39
|
-
/** Colors a string in blue if {@link enabled}. */
|
|
40
|
-
blue(text: string): string;
|
|
41
|
-
/** Colors a string in magenta if {@link enabled}. */
|
|
42
|
-
magenta(text: string): string;
|
|
43
|
-
/** Colors a string in cyan if {@link enabled}. */
|
|
44
|
-
cyan(text: string): string;
|
|
45
|
-
/** Colors a string in white if {@link enabled}. */
|
|
46
|
-
white(text: string): string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** Color utility for stdout. */
|
|
50
|
-
export const stdoutColors: Colors;
|
|
51
|
-
/** Color utility for stderr. */
|
|
52
|
-
export const stderrColors: Colors;
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Terminal colors utility definitions.
|
|
3
|
+
* @license Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** Color code for gray. */
|
|
7
|
+
export const GRAY: string;
|
|
8
|
+
/** Color code for red. */
|
|
9
|
+
export const RED: string;
|
|
10
|
+
/** Color code for green. */
|
|
11
|
+
export const GREEN: string;
|
|
12
|
+
/** Color code for yellow. */
|
|
13
|
+
export const YELLOW: string;
|
|
14
|
+
/** Color code for blue. */
|
|
15
|
+
export const BLUE: string;
|
|
16
|
+
/** Color code for magenta. */
|
|
17
|
+
export const MAGENTA: string;
|
|
18
|
+
/** Color code for cyan. */
|
|
19
|
+
export const CYAN: string;
|
|
20
|
+
/** Color code for white. */
|
|
21
|
+
export const WHITE: string;
|
|
22
|
+
/** Code to reset any colors. */
|
|
23
|
+
export const RESET: string;
|
|
24
|
+
|
|
25
|
+
/** Color utility class. */
|
|
26
|
+
export class Colors {
|
|
27
|
+
/** Constructs a new instance for the given stream. */
|
|
28
|
+
constructor(stream: { isTTY: boolean });
|
|
29
|
+
/** Whether terminal colors are enabled. */
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
/** Colors a string in gray if {@link enabled}. */
|
|
32
|
+
gray(text: string): string;
|
|
33
|
+
/** Colors a string in red if {@link enabled}. */
|
|
34
|
+
red(text: string): string;
|
|
35
|
+
/** Colors a string in green if {@link enabled}. */
|
|
36
|
+
green(text: string): string;
|
|
37
|
+
/** Colors a string in yellow if {@link enabled}. */
|
|
38
|
+
yellow(text: string): string;
|
|
39
|
+
/** Colors a string in blue if {@link enabled}. */
|
|
40
|
+
blue(text: string): string;
|
|
41
|
+
/** Colors a string in magenta if {@link enabled}. */
|
|
42
|
+
magenta(text: string): string;
|
|
43
|
+
/** Colors a string in cyan if {@link enabled}. */
|
|
44
|
+
cyan(text: string): string;
|
|
45
|
+
/** Colors a string in white if {@link enabled}. */
|
|
46
|
+
white(text: string): string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Color utility for stdout. */
|
|
50
|
+
export const stdoutColors: Colors;
|
|
51
|
+
/** Color utility for stderr. */
|
|
52
|
+
export const stderrColors: Colors;
|