vitest 0.0.66 → 0.0.70
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/bin/vitest.mjs +3 -3
- package/dist/cli.js +3859 -0
- package/dist/constants-d4c70610.js +25 -0
- package/dist/entry.js +3331 -0
- package/dist/global-e40b54d6.js +16 -0
- package/dist/index-6427e0f2.js +12 -0
- package/dist/index-e37648e9.js +31 -0
- package/dist/index.d.ts +304 -5
- package/dist/index.js +5 -46
- package/dist/{chunk-ANPMHBIF.js → suite-819c135e.js} +16 -45
- package/dist/{chunk-5TNYWP3O.js → utils-9dcc4050.js} +1 -18
- package/dist/{runtime/worker.js → worker.js} +31 -48
- package/package.json +17 -9
- package/dist/chunk-APGELTDH.js +0 -19
- package/dist/chunk-R2SMNEBL.js +0 -95
- package/dist/chunk-VLGIKNLC.js +0 -78
- package/dist/chunk-XUIDSY4V.js +0 -35
- package/dist/chunk-YPKHVZRP.js +0 -86
- package/dist/global-PRFYLY7P.js +0 -22
- package/dist/node/cli.d.ts +0 -1
- package/dist/node/cli.js +0 -2612
- package/dist/options-63a726fa.d.ts +0 -294
- package/dist/runtime/entry.d.ts +0 -7
- package/dist/runtime/entry.js +0 -2545
- package/dist/runtime/worker.d.ts +0 -23
package/dist/cli.js
ADDED
|
@@ -0,0 +1,3859 @@
|
|
|
1
|
+
import require$$2, { EventEmitter } from 'events';
|
|
2
|
+
import require$$0 from 'tty';
|
|
3
|
+
import { performance } from 'perf_hooks';
|
|
4
|
+
import path, { isAbsolute, relative, dirname, basename, resolve } from 'path';
|
|
5
|
+
import { n as notNullish, g as getNames, s as slash, a as getTests, b as getSuites, t as toArray, h as hasFailed } from './utils-9dcc4050.js';
|
|
6
|
+
import { existsSync, promises } from 'fs';
|
|
7
|
+
import { SourceMapConsumer } from 'source-map';
|
|
8
|
+
import process$2 from 'process';
|
|
9
|
+
import require$$0$1 from 'assert';
|
|
10
|
+
import { createServer } from 'vite';
|
|
11
|
+
import { d as defaultIncludes, a as defaultExcludes, b as distDir } from './constants-d4c70610.js';
|
|
12
|
+
import { MessageChannel } from 'worker_threads';
|
|
13
|
+
import { pathToFileURL } from 'url';
|
|
14
|
+
import Piscina from 'piscina';
|
|
15
|
+
import fg from 'fast-glob';
|
|
16
|
+
import mm from 'micromatch';
|
|
17
|
+
import readline from 'readline';
|
|
18
|
+
|
|
19
|
+
function toArr(any) {
|
|
20
|
+
return any == null ? [] : Array.isArray(any) ? any : [any];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function toVal(out, key, val, opts) {
|
|
24
|
+
var x, old=out[key], nxt=(
|
|
25
|
+
!!~opts.string.indexOf(key) ? (val == null || val === true ? '' : String(val))
|
|
26
|
+
: typeof val === 'boolean' ? val
|
|
27
|
+
: !!~opts.boolean.indexOf(key) ? (val === 'false' ? false : val === 'true' || (out._.push((x = +val,x * 0 === 0) ? x : val),!!val))
|
|
28
|
+
: (x = +val,x * 0 === 0) ? x : val
|
|
29
|
+
);
|
|
30
|
+
out[key] = old == null ? nxt : (Array.isArray(old) ? old.concat(nxt) : [old, nxt]);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function mri2 (args, opts) {
|
|
34
|
+
args = args || [];
|
|
35
|
+
opts = opts || {};
|
|
36
|
+
|
|
37
|
+
var k, arr, arg, name, val, out={ _:[] };
|
|
38
|
+
var i=0, j=0, idx=0, len=args.length;
|
|
39
|
+
|
|
40
|
+
const alibi = opts.alias !== void 0;
|
|
41
|
+
const strict = opts.unknown !== void 0;
|
|
42
|
+
const defaults = opts.default !== void 0;
|
|
43
|
+
|
|
44
|
+
opts.alias = opts.alias || {};
|
|
45
|
+
opts.string = toArr(opts.string);
|
|
46
|
+
opts.boolean = toArr(opts.boolean);
|
|
47
|
+
|
|
48
|
+
if (alibi) {
|
|
49
|
+
for (k in opts.alias) {
|
|
50
|
+
arr = opts.alias[k] = toArr(opts.alias[k]);
|
|
51
|
+
for (i=0; i < arr.length; i++) {
|
|
52
|
+
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (i=opts.boolean.length; i-- > 0;) {
|
|
58
|
+
arr = opts.alias[opts.boolean[i]] || [];
|
|
59
|
+
for (j=arr.length; j-- > 0;) opts.boolean.push(arr[j]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (i=opts.string.length; i-- > 0;) {
|
|
63
|
+
arr = opts.alias[opts.string[i]] || [];
|
|
64
|
+
for (j=arr.length; j-- > 0;) opts.string.push(arr[j]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (defaults) {
|
|
68
|
+
for (k in opts.default) {
|
|
69
|
+
name = typeof opts.default[k];
|
|
70
|
+
arr = opts.alias[k] = opts.alias[k] || [];
|
|
71
|
+
if (opts[name] !== void 0) {
|
|
72
|
+
opts[name].push(k);
|
|
73
|
+
for (i=0; i < arr.length; i++) {
|
|
74
|
+
opts[name].push(arr[i]);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const keys = strict ? Object.keys(opts.alias) : [];
|
|
81
|
+
|
|
82
|
+
for (i=0; i < len; i++) {
|
|
83
|
+
arg = args[i];
|
|
84
|
+
|
|
85
|
+
if (arg === '--') {
|
|
86
|
+
out._ = out._.concat(args.slice(++i));
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (j=0; j < arg.length; j++) {
|
|
91
|
+
if (arg.charCodeAt(j) !== 45) break; // "-"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (j === 0) {
|
|
95
|
+
out._.push(arg);
|
|
96
|
+
} else if (arg.substring(j, j + 3) === 'no-') {
|
|
97
|
+
name = arg.substring(j + 3);
|
|
98
|
+
if (strict && !~keys.indexOf(name)) {
|
|
99
|
+
return opts.unknown(arg);
|
|
100
|
+
}
|
|
101
|
+
out[name] = false;
|
|
102
|
+
} else {
|
|
103
|
+
for (idx=j+1; idx < arg.length; idx++) {
|
|
104
|
+
if (arg.charCodeAt(idx) === 61) break; // "="
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
name = arg.substring(j, idx);
|
|
108
|
+
val = arg.substring(++idx) || (i+1 === len || (''+args[i+1]).charCodeAt(0) === 45 || args[++i]);
|
|
109
|
+
arr = (j === 2 ? [name] : name);
|
|
110
|
+
|
|
111
|
+
for (idx=0; idx < arr.length; idx++) {
|
|
112
|
+
name = arr[idx];
|
|
113
|
+
if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name);
|
|
114
|
+
toVal(out, name, (idx + 1 < arr.length) || val, opts);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (defaults) {
|
|
120
|
+
for (k in opts.default) {
|
|
121
|
+
if (out[k] === void 0) {
|
|
122
|
+
out[k] = opts.default[k];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (alibi) {
|
|
128
|
+
for (k in out) {
|
|
129
|
+
arr = opts.alias[k] || [];
|
|
130
|
+
while (arr.length > 0) {
|
|
131
|
+
out[arr.shift()] = out[k];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const removeBrackets = (v) => v.replace(/[<[].+/, "").trim();
|
|
140
|
+
const findAllBrackets = (v) => {
|
|
141
|
+
const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
|
|
142
|
+
const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
|
|
143
|
+
const res = [];
|
|
144
|
+
const parse = (match) => {
|
|
145
|
+
let variadic = false;
|
|
146
|
+
let value = match[1];
|
|
147
|
+
if (value.startsWith("...")) {
|
|
148
|
+
value = value.slice(3);
|
|
149
|
+
variadic = true;
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
required: match[0].startsWith("<"),
|
|
153
|
+
value,
|
|
154
|
+
variadic
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
let angledMatch;
|
|
158
|
+
while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {
|
|
159
|
+
res.push(parse(angledMatch));
|
|
160
|
+
}
|
|
161
|
+
let squareMatch;
|
|
162
|
+
while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {
|
|
163
|
+
res.push(parse(squareMatch));
|
|
164
|
+
}
|
|
165
|
+
return res;
|
|
166
|
+
};
|
|
167
|
+
const getMriOptions = (options) => {
|
|
168
|
+
const result = {alias: {}, boolean: []};
|
|
169
|
+
for (const [index, option] of options.entries()) {
|
|
170
|
+
if (option.names.length > 1) {
|
|
171
|
+
result.alias[option.names[0]] = option.names.slice(1);
|
|
172
|
+
}
|
|
173
|
+
if (option.isBoolean) {
|
|
174
|
+
if (option.negated) {
|
|
175
|
+
const hasStringTypeOption = options.some((o, i) => {
|
|
176
|
+
return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean";
|
|
177
|
+
});
|
|
178
|
+
if (!hasStringTypeOption) {
|
|
179
|
+
result.boolean.push(option.names[0]);
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
result.boolean.push(option.names[0]);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return result;
|
|
187
|
+
};
|
|
188
|
+
const findLongest = (arr) => {
|
|
189
|
+
return arr.sort((a, b) => {
|
|
190
|
+
return a.length > b.length ? -1 : 1;
|
|
191
|
+
})[0];
|
|
192
|
+
};
|
|
193
|
+
const padRight = (str, length) => {
|
|
194
|
+
return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
|
|
195
|
+
};
|
|
196
|
+
const camelcase = (input) => {
|
|
197
|
+
return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => {
|
|
198
|
+
return p1 + p2.toUpperCase();
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
const setDotProp = (obj, keys, val) => {
|
|
202
|
+
let i = 0;
|
|
203
|
+
let length = keys.length;
|
|
204
|
+
let t = obj;
|
|
205
|
+
let x;
|
|
206
|
+
for (; i < length; ++i) {
|
|
207
|
+
x = t[keys[i]];
|
|
208
|
+
t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : [];
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const setByType = (obj, transforms) => {
|
|
212
|
+
for (const key of Object.keys(transforms)) {
|
|
213
|
+
const transform = transforms[key];
|
|
214
|
+
if (transform.shouldTransform) {
|
|
215
|
+
obj[key] = Array.prototype.concat.call([], obj[key]);
|
|
216
|
+
if (typeof transform.transformFunction === "function") {
|
|
217
|
+
obj[key] = obj[key].map(transform.transformFunction);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
const getFileName = (input) => {
|
|
223
|
+
const m = /([^\\\/]+)$/.exec(input);
|
|
224
|
+
return m ? m[1] : "";
|
|
225
|
+
};
|
|
226
|
+
const camelcaseOptionName = (name) => {
|
|
227
|
+
return name.split(".").map((v, i) => {
|
|
228
|
+
return i === 0 ? camelcase(v) : v;
|
|
229
|
+
}).join(".");
|
|
230
|
+
};
|
|
231
|
+
class CACError extends Error {
|
|
232
|
+
constructor(message) {
|
|
233
|
+
super(message);
|
|
234
|
+
this.name = this.constructor.name;
|
|
235
|
+
if (typeof Error.captureStackTrace === "function") {
|
|
236
|
+
Error.captureStackTrace(this, this.constructor);
|
|
237
|
+
} else {
|
|
238
|
+
this.stack = new Error(message).stack;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
class Option {
|
|
244
|
+
constructor(rawName, description, config) {
|
|
245
|
+
this.rawName = rawName;
|
|
246
|
+
this.description = description;
|
|
247
|
+
this.config = Object.assign({}, config);
|
|
248
|
+
rawName = rawName.replace(/\.\*/g, "");
|
|
249
|
+
this.negated = false;
|
|
250
|
+
this.names = removeBrackets(rawName).split(",").map((v) => {
|
|
251
|
+
let name = v.trim().replace(/^-{1,2}/, "");
|
|
252
|
+
if (name.startsWith("no-")) {
|
|
253
|
+
this.negated = true;
|
|
254
|
+
name = name.replace(/^no-/, "");
|
|
255
|
+
}
|
|
256
|
+
return camelcaseOptionName(name);
|
|
257
|
+
}).sort((a, b) => a.length > b.length ? 1 : -1);
|
|
258
|
+
this.name = this.names[this.names.length - 1];
|
|
259
|
+
if (this.negated && this.config.default == null) {
|
|
260
|
+
this.config.default = true;
|
|
261
|
+
}
|
|
262
|
+
if (rawName.includes("<")) {
|
|
263
|
+
this.required = true;
|
|
264
|
+
} else if (rawName.includes("[")) {
|
|
265
|
+
this.required = false;
|
|
266
|
+
} else {
|
|
267
|
+
this.isBoolean = true;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const processArgs = process.argv;
|
|
273
|
+
const platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
|
|
274
|
+
|
|
275
|
+
class Command {
|
|
276
|
+
constructor(rawName, description, config = {}, cli) {
|
|
277
|
+
this.rawName = rawName;
|
|
278
|
+
this.description = description;
|
|
279
|
+
this.config = config;
|
|
280
|
+
this.cli = cli;
|
|
281
|
+
this.options = [];
|
|
282
|
+
this.aliasNames = [];
|
|
283
|
+
this.name = removeBrackets(rawName);
|
|
284
|
+
this.args = findAllBrackets(rawName);
|
|
285
|
+
this.examples = [];
|
|
286
|
+
}
|
|
287
|
+
usage(text) {
|
|
288
|
+
this.usageText = text;
|
|
289
|
+
return this;
|
|
290
|
+
}
|
|
291
|
+
allowUnknownOptions() {
|
|
292
|
+
this.config.allowUnknownOptions = true;
|
|
293
|
+
return this;
|
|
294
|
+
}
|
|
295
|
+
ignoreOptionDefaultValue() {
|
|
296
|
+
this.config.ignoreOptionDefaultValue = true;
|
|
297
|
+
return this;
|
|
298
|
+
}
|
|
299
|
+
version(version, customFlags = "-v, --version") {
|
|
300
|
+
this.versionNumber = version;
|
|
301
|
+
this.option(customFlags, "Display version number");
|
|
302
|
+
return this;
|
|
303
|
+
}
|
|
304
|
+
example(example) {
|
|
305
|
+
this.examples.push(example);
|
|
306
|
+
return this;
|
|
307
|
+
}
|
|
308
|
+
option(rawName, description, config) {
|
|
309
|
+
const option = new Option(rawName, description, config);
|
|
310
|
+
this.options.push(option);
|
|
311
|
+
return this;
|
|
312
|
+
}
|
|
313
|
+
alias(name) {
|
|
314
|
+
this.aliasNames.push(name);
|
|
315
|
+
return this;
|
|
316
|
+
}
|
|
317
|
+
action(callback) {
|
|
318
|
+
this.commandAction = callback;
|
|
319
|
+
return this;
|
|
320
|
+
}
|
|
321
|
+
isMatched(name) {
|
|
322
|
+
return this.name === name || this.aliasNames.includes(name);
|
|
323
|
+
}
|
|
324
|
+
get isDefaultCommand() {
|
|
325
|
+
return this.name === "" || this.aliasNames.includes("!");
|
|
326
|
+
}
|
|
327
|
+
get isGlobalCommand() {
|
|
328
|
+
return this instanceof GlobalCommand;
|
|
329
|
+
}
|
|
330
|
+
hasOption(name) {
|
|
331
|
+
name = name.split(".")[0];
|
|
332
|
+
return this.options.find((option) => {
|
|
333
|
+
return option.names.includes(name);
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
outputHelp() {
|
|
337
|
+
const {name, commands} = this.cli;
|
|
338
|
+
const {
|
|
339
|
+
versionNumber,
|
|
340
|
+
options: globalOptions,
|
|
341
|
+
helpCallback
|
|
342
|
+
} = this.cli.globalCommand;
|
|
343
|
+
let sections = [
|
|
344
|
+
{
|
|
345
|
+
body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
|
|
346
|
+
}
|
|
347
|
+
];
|
|
348
|
+
sections.push({
|
|
349
|
+
title: "Usage",
|
|
350
|
+
body: ` $ ${name} ${this.usageText || this.rawName}`
|
|
351
|
+
});
|
|
352
|
+
const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
|
|
353
|
+
if (showCommands) {
|
|
354
|
+
const longestCommandName = findLongest(commands.map((command) => command.rawName));
|
|
355
|
+
sections.push({
|
|
356
|
+
title: "Commands",
|
|
357
|
+
body: commands.map((command) => {
|
|
358
|
+
return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;
|
|
359
|
+
}).join("\n")
|
|
360
|
+
});
|
|
361
|
+
sections.push({
|
|
362
|
+
title: `For more info, run any command with the \`--help\` flag`,
|
|
363
|
+
body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join("\n")
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];
|
|
367
|
+
if (!this.isGlobalCommand && !this.isDefaultCommand) {
|
|
368
|
+
options = options.filter((option) => option.name !== "version");
|
|
369
|
+
}
|
|
370
|
+
if (options.length > 0) {
|
|
371
|
+
const longestOptionName = findLongest(options.map((option) => option.rawName));
|
|
372
|
+
sections.push({
|
|
373
|
+
title: "Options",
|
|
374
|
+
body: options.map((option) => {
|
|
375
|
+
return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? "" : `(default: ${option.config.default})`}`;
|
|
376
|
+
}).join("\n")
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
if (this.examples.length > 0) {
|
|
380
|
+
sections.push({
|
|
381
|
+
title: "Examples",
|
|
382
|
+
body: this.examples.map((example) => {
|
|
383
|
+
if (typeof example === "function") {
|
|
384
|
+
return example(name);
|
|
385
|
+
}
|
|
386
|
+
return example;
|
|
387
|
+
}).join("\n")
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
if (helpCallback) {
|
|
391
|
+
sections = helpCallback(sections) || sections;
|
|
392
|
+
}
|
|
393
|
+
console.log(sections.map((section) => {
|
|
394
|
+
return section.title ? `${section.title}:
|
|
395
|
+
${section.body}` : section.body;
|
|
396
|
+
}).join("\n\n"));
|
|
397
|
+
}
|
|
398
|
+
outputVersion() {
|
|
399
|
+
const {name} = this.cli;
|
|
400
|
+
const {versionNumber} = this.cli.globalCommand;
|
|
401
|
+
if (versionNumber) {
|
|
402
|
+
console.log(`${name}/${versionNumber} ${platformInfo}`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
checkRequiredArgs() {
|
|
406
|
+
const minimalArgsCount = this.args.filter((arg) => arg.required).length;
|
|
407
|
+
if (this.cli.args.length < minimalArgsCount) {
|
|
408
|
+
throw new CACError(`missing required args for command \`${this.rawName}\``);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
checkUnknownOptions() {
|
|
412
|
+
const {options, globalCommand} = this.cli;
|
|
413
|
+
if (!this.config.allowUnknownOptions) {
|
|
414
|
+
for (const name of Object.keys(options)) {
|
|
415
|
+
if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) {
|
|
416
|
+
throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
checkOptionValue() {
|
|
422
|
+
const {options: parsedOptions, globalCommand} = this.cli;
|
|
423
|
+
const options = [...globalCommand.options, ...this.options];
|
|
424
|
+
for (const option of options) {
|
|
425
|
+
const value = parsedOptions[option.name.split(".")[0]];
|
|
426
|
+
if (option.required) {
|
|
427
|
+
const hasNegated = options.some((o) => o.negated && o.names.includes(option.name));
|
|
428
|
+
if (value === true || value === false && !hasNegated) {
|
|
429
|
+
throw new CACError(`option \`${option.rawName}\` value is missing`);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
class GlobalCommand extends Command {
|
|
436
|
+
constructor(cli) {
|
|
437
|
+
super("@@global@@", "", {}, cli);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
var __assign = Object.assign;
|
|
442
|
+
class CAC extends EventEmitter {
|
|
443
|
+
constructor(name = "") {
|
|
444
|
+
super();
|
|
445
|
+
this.name = name;
|
|
446
|
+
this.commands = [];
|
|
447
|
+
this.rawArgs = [];
|
|
448
|
+
this.args = [];
|
|
449
|
+
this.options = {};
|
|
450
|
+
this.globalCommand = new GlobalCommand(this);
|
|
451
|
+
this.globalCommand.usage("<command> [options]");
|
|
452
|
+
}
|
|
453
|
+
usage(text) {
|
|
454
|
+
this.globalCommand.usage(text);
|
|
455
|
+
return this;
|
|
456
|
+
}
|
|
457
|
+
command(rawName, description, config) {
|
|
458
|
+
const command = new Command(rawName, description || "", config, this);
|
|
459
|
+
command.globalCommand = this.globalCommand;
|
|
460
|
+
this.commands.push(command);
|
|
461
|
+
return command;
|
|
462
|
+
}
|
|
463
|
+
option(rawName, description, config) {
|
|
464
|
+
this.globalCommand.option(rawName, description, config);
|
|
465
|
+
return this;
|
|
466
|
+
}
|
|
467
|
+
help(callback) {
|
|
468
|
+
this.globalCommand.option("-h, --help", "Display this message");
|
|
469
|
+
this.globalCommand.helpCallback = callback;
|
|
470
|
+
this.showHelpOnExit = true;
|
|
471
|
+
return this;
|
|
472
|
+
}
|
|
473
|
+
version(version, customFlags = "-v, --version") {
|
|
474
|
+
this.globalCommand.version(version, customFlags);
|
|
475
|
+
this.showVersionOnExit = true;
|
|
476
|
+
return this;
|
|
477
|
+
}
|
|
478
|
+
example(example) {
|
|
479
|
+
this.globalCommand.example(example);
|
|
480
|
+
return this;
|
|
481
|
+
}
|
|
482
|
+
outputHelp() {
|
|
483
|
+
if (this.matchedCommand) {
|
|
484
|
+
this.matchedCommand.outputHelp();
|
|
485
|
+
} else {
|
|
486
|
+
this.globalCommand.outputHelp();
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
outputVersion() {
|
|
490
|
+
this.globalCommand.outputVersion();
|
|
491
|
+
}
|
|
492
|
+
setParsedInfo({args, options}, matchedCommand, matchedCommandName) {
|
|
493
|
+
this.args = args;
|
|
494
|
+
this.options = options;
|
|
495
|
+
if (matchedCommand) {
|
|
496
|
+
this.matchedCommand = matchedCommand;
|
|
497
|
+
}
|
|
498
|
+
if (matchedCommandName) {
|
|
499
|
+
this.matchedCommandName = matchedCommandName;
|
|
500
|
+
}
|
|
501
|
+
return this;
|
|
502
|
+
}
|
|
503
|
+
unsetMatchedCommand() {
|
|
504
|
+
this.matchedCommand = void 0;
|
|
505
|
+
this.matchedCommandName = void 0;
|
|
506
|
+
}
|
|
507
|
+
parse(argv = processArgs, {
|
|
508
|
+
run = true
|
|
509
|
+
} = {}) {
|
|
510
|
+
this.rawArgs = argv;
|
|
511
|
+
if (!this.name) {
|
|
512
|
+
this.name = argv[1] ? getFileName(argv[1]) : "cli";
|
|
513
|
+
}
|
|
514
|
+
let shouldParse = true;
|
|
515
|
+
for (const command of this.commands) {
|
|
516
|
+
const parsed = this.mri(argv.slice(2), command);
|
|
517
|
+
const commandName = parsed.args[0];
|
|
518
|
+
if (command.isMatched(commandName)) {
|
|
519
|
+
shouldParse = false;
|
|
520
|
+
const parsedInfo = __assign(__assign({}, parsed), {
|
|
521
|
+
args: parsed.args.slice(1)
|
|
522
|
+
});
|
|
523
|
+
this.setParsedInfo(parsedInfo, command, commandName);
|
|
524
|
+
this.emit(`command:${commandName}`, command);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
if (shouldParse) {
|
|
528
|
+
for (const command of this.commands) {
|
|
529
|
+
if (command.name === "") {
|
|
530
|
+
shouldParse = false;
|
|
531
|
+
const parsed = this.mri(argv.slice(2), command);
|
|
532
|
+
this.setParsedInfo(parsed, command);
|
|
533
|
+
this.emit(`command:!`, command);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
if (shouldParse) {
|
|
538
|
+
const parsed = this.mri(argv.slice(2));
|
|
539
|
+
this.setParsedInfo(parsed);
|
|
540
|
+
}
|
|
541
|
+
if (this.options.help && this.showHelpOnExit) {
|
|
542
|
+
this.outputHelp();
|
|
543
|
+
run = false;
|
|
544
|
+
this.unsetMatchedCommand();
|
|
545
|
+
}
|
|
546
|
+
if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {
|
|
547
|
+
this.outputVersion();
|
|
548
|
+
run = false;
|
|
549
|
+
this.unsetMatchedCommand();
|
|
550
|
+
}
|
|
551
|
+
const parsedArgv = {args: this.args, options: this.options};
|
|
552
|
+
if (run) {
|
|
553
|
+
this.runMatchedCommand();
|
|
554
|
+
}
|
|
555
|
+
if (!this.matchedCommand && this.args[0]) {
|
|
556
|
+
this.emit("command:*");
|
|
557
|
+
}
|
|
558
|
+
return parsedArgv;
|
|
559
|
+
}
|
|
560
|
+
mri(argv, command) {
|
|
561
|
+
const cliOptions = [
|
|
562
|
+
...this.globalCommand.options,
|
|
563
|
+
...command ? command.options : []
|
|
564
|
+
];
|
|
565
|
+
const mriOptions = getMriOptions(cliOptions);
|
|
566
|
+
let argsAfterDoubleDashes = [];
|
|
567
|
+
const doubleDashesIndex = argv.indexOf("--");
|
|
568
|
+
if (doubleDashesIndex > -1) {
|
|
569
|
+
argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
|
|
570
|
+
argv = argv.slice(0, doubleDashesIndex);
|
|
571
|
+
}
|
|
572
|
+
let parsed = mri2(argv, mriOptions);
|
|
573
|
+
parsed = Object.keys(parsed).reduce((res, name) => {
|
|
574
|
+
return __assign(__assign({}, res), {
|
|
575
|
+
[camelcaseOptionName(name)]: parsed[name]
|
|
576
|
+
});
|
|
577
|
+
}, {_: []});
|
|
578
|
+
const args = parsed._;
|
|
579
|
+
const options = {
|
|
580
|
+
"--": argsAfterDoubleDashes
|
|
581
|
+
};
|
|
582
|
+
const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
|
|
583
|
+
let transforms = Object.create(null);
|
|
584
|
+
for (const cliOption of cliOptions) {
|
|
585
|
+
if (!ignoreDefault && cliOption.config.default !== void 0) {
|
|
586
|
+
for (const name of cliOption.names) {
|
|
587
|
+
options[name] = cliOption.config.default;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
if (Array.isArray(cliOption.config.type)) {
|
|
591
|
+
if (transforms[cliOption.name] === void 0) {
|
|
592
|
+
transforms[cliOption.name] = Object.create(null);
|
|
593
|
+
transforms[cliOption.name]["shouldTransform"] = true;
|
|
594
|
+
transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0];
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
for (const key of Object.keys(parsed)) {
|
|
599
|
+
if (key !== "_") {
|
|
600
|
+
const keys = key.split(".");
|
|
601
|
+
setDotProp(options, keys, parsed[key]);
|
|
602
|
+
setByType(options, transforms);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return {
|
|
606
|
+
args,
|
|
607
|
+
options
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
runMatchedCommand() {
|
|
611
|
+
const {args, options, matchedCommand: command} = this;
|
|
612
|
+
if (!command || !command.commandAction)
|
|
613
|
+
return;
|
|
614
|
+
command.checkUnknownOptions();
|
|
615
|
+
command.checkOptionValue();
|
|
616
|
+
command.checkRequiredArgs();
|
|
617
|
+
const actionArgs = [];
|
|
618
|
+
command.args.forEach((arg, index) => {
|
|
619
|
+
if (arg.variadic) {
|
|
620
|
+
actionArgs.push(args.slice(index));
|
|
621
|
+
} else {
|
|
622
|
+
actionArgs.push(args[index]);
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
actionArgs.push(options);
|
|
626
|
+
return command.commandAction.apply(this, actionArgs);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const cac = (name = "") => new CAC(name);
|
|
631
|
+
|
|
632
|
+
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
633
|
+
|
|
634
|
+
var picocolors = {exports: {}};
|
|
635
|
+
|
|
636
|
+
let tty = require$$0;
|
|
637
|
+
|
|
638
|
+
let isColorSupported =
|
|
639
|
+
!("NO_COLOR" in process.env || process.argv.includes("--no-color")) &&
|
|
640
|
+
("FORCE_COLOR" in process.env ||
|
|
641
|
+
process.argv.includes("--color") ||
|
|
642
|
+
process.platform === "win32" ||
|
|
643
|
+
(tty.isatty(1) && process.env.TERM !== "dumb") ||
|
|
644
|
+
"CI" in process.env);
|
|
645
|
+
|
|
646
|
+
let formatter =
|
|
647
|
+
(open, close, replace = open) =>
|
|
648
|
+
input => {
|
|
649
|
+
let string = "" + input;
|
|
650
|
+
let index = string.indexOf(close, open.length);
|
|
651
|
+
return ~index
|
|
652
|
+
? open + replaceClose(string, close, replace, index) + close
|
|
653
|
+
: open + string + close
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
let replaceClose = (string, close, replace, index) => {
|
|
657
|
+
let start = string.substring(0, index) + replace;
|
|
658
|
+
let end = string.substring(index + close.length);
|
|
659
|
+
let nextIndex = end.indexOf(close);
|
|
660
|
+
return ~nextIndex ? start + replaceClose(end, close, replace, nextIndex) : start + end
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
let createColors = (enabled = isColorSupported) => ({
|
|
664
|
+
isColorSupported: enabled,
|
|
665
|
+
reset: enabled ? s => `\x1b[0m${s}\x1b[0m` : String,
|
|
666
|
+
bold: enabled ? formatter("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m") : String,
|
|
667
|
+
dim: enabled ? formatter("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m") : String,
|
|
668
|
+
italic: enabled ? formatter("\x1b[3m", "\x1b[23m") : String,
|
|
669
|
+
underline: enabled ? formatter("\x1b[4m", "\x1b[24m") : String,
|
|
670
|
+
inverse: enabled ? formatter("\x1b[7m", "\x1b[27m") : String,
|
|
671
|
+
hidden: enabled ? formatter("\x1b[8m", "\x1b[28m") : String,
|
|
672
|
+
strikethrough: enabled ? formatter("\x1b[9m", "\x1b[29m") : String,
|
|
673
|
+
black: enabled ? formatter("\x1b[30m", "\x1b[39m") : String,
|
|
674
|
+
red: enabled ? formatter("\x1b[31m", "\x1b[39m") : String,
|
|
675
|
+
green: enabled ? formatter("\x1b[32m", "\x1b[39m") : String,
|
|
676
|
+
yellow: enabled ? formatter("\x1b[33m", "\x1b[39m") : String,
|
|
677
|
+
blue: enabled ? formatter("\x1b[34m", "\x1b[39m") : String,
|
|
678
|
+
magenta: enabled ? formatter("\x1b[35m", "\x1b[39m") : String,
|
|
679
|
+
cyan: enabled ? formatter("\x1b[36m", "\x1b[39m") : String,
|
|
680
|
+
white: enabled ? formatter("\x1b[37m", "\x1b[39m") : String,
|
|
681
|
+
gray: enabled ? formatter("\x1b[90m", "\x1b[39m") : String,
|
|
682
|
+
bgBlack: enabled ? formatter("\x1b[40m", "\x1b[49m") : String,
|
|
683
|
+
bgRed: enabled ? formatter("\x1b[41m", "\x1b[49m") : String,
|
|
684
|
+
bgGreen: enabled ? formatter("\x1b[42m", "\x1b[49m") : String,
|
|
685
|
+
bgYellow: enabled ? formatter("\x1b[43m", "\x1b[49m") : String,
|
|
686
|
+
bgBlue: enabled ? formatter("\x1b[44m", "\x1b[49m") : String,
|
|
687
|
+
bgMagenta: enabled ? formatter("\x1b[45m", "\x1b[49m") : String,
|
|
688
|
+
bgCyan: enabled ? formatter("\x1b[46m", "\x1b[49m") : String,
|
|
689
|
+
bgWhite: enabled ? formatter("\x1b[47m", "\x1b[49m") : String,
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
picocolors.exports = createColors();
|
|
693
|
+
picocolors.exports.createColors = createColors;
|
|
694
|
+
|
|
695
|
+
var c = picocolors.exports;
|
|
696
|
+
|
|
697
|
+
var version = "0.0.70";
|
|
698
|
+
|
|
699
|
+
function Diff() {}
|
|
700
|
+
Diff.prototype = {
|
|
701
|
+
diff: function diff(oldString, newString) {
|
|
702
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
703
|
+
var callback = options.callback;
|
|
704
|
+
|
|
705
|
+
if (typeof options === 'function') {
|
|
706
|
+
callback = options;
|
|
707
|
+
options = {};
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
this.options = options;
|
|
711
|
+
var self = this;
|
|
712
|
+
|
|
713
|
+
function done(value) {
|
|
714
|
+
if (callback) {
|
|
715
|
+
setTimeout(function () {
|
|
716
|
+
callback(undefined, value);
|
|
717
|
+
}, 0);
|
|
718
|
+
return true;
|
|
719
|
+
} else {
|
|
720
|
+
return value;
|
|
721
|
+
}
|
|
722
|
+
} // Allow subclasses to massage the input prior to running
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
oldString = this.castInput(oldString);
|
|
726
|
+
newString = this.castInput(newString);
|
|
727
|
+
oldString = this.removeEmpty(this.tokenize(oldString));
|
|
728
|
+
newString = this.removeEmpty(this.tokenize(newString));
|
|
729
|
+
var newLen = newString.length,
|
|
730
|
+
oldLen = oldString.length;
|
|
731
|
+
var editLength = 1;
|
|
732
|
+
var maxEditLength = newLen + oldLen;
|
|
733
|
+
var bestPath = [{
|
|
734
|
+
newPos: -1,
|
|
735
|
+
components: []
|
|
736
|
+
}]; // Seed editLength = 0, i.e. the content starts with the same values
|
|
737
|
+
|
|
738
|
+
var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
|
|
739
|
+
|
|
740
|
+
if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
|
|
741
|
+
// Identity per the equality and tokenizer
|
|
742
|
+
return done([{
|
|
743
|
+
value: this.join(newString),
|
|
744
|
+
count: newString.length
|
|
745
|
+
}]);
|
|
746
|
+
} // Main worker method. checks all permutations of a given edit length for acceptance.
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
function execEditLength() {
|
|
750
|
+
for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {
|
|
751
|
+
var basePath = void 0;
|
|
752
|
+
|
|
753
|
+
var addPath = bestPath[diagonalPath - 1],
|
|
754
|
+
removePath = bestPath[diagonalPath + 1],
|
|
755
|
+
_oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
|
|
756
|
+
|
|
757
|
+
if (addPath) {
|
|
758
|
+
// No one else is going to attempt to use this value, clear it
|
|
759
|
+
bestPath[diagonalPath - 1] = undefined;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
var canAdd = addPath && addPath.newPos + 1 < newLen,
|
|
763
|
+
canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen;
|
|
764
|
+
|
|
765
|
+
if (!canAdd && !canRemove) {
|
|
766
|
+
// If this path is a terminal then prune
|
|
767
|
+
bestPath[diagonalPath] = undefined;
|
|
768
|
+
continue;
|
|
769
|
+
} // Select the diagonal that we want to branch from. We select the prior
|
|
770
|
+
// path whose position in the new string is the farthest from the origin
|
|
771
|
+
// and does not pass the bounds of the diff graph
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
if (!canAdd || canRemove && addPath.newPos < removePath.newPos) {
|
|
775
|
+
basePath = clonePath(removePath);
|
|
776
|
+
self.pushComponent(basePath.components, undefined, true);
|
|
777
|
+
} else {
|
|
778
|
+
basePath = addPath; // No need to clone, we've pulled it from the list
|
|
779
|
+
|
|
780
|
+
basePath.newPos++;
|
|
781
|
+
self.pushComponent(basePath.components, true, undefined);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
_oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done
|
|
785
|
+
|
|
786
|
+
if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) {
|
|
787
|
+
return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken));
|
|
788
|
+
} else {
|
|
789
|
+
// Otherwise track this path as a potential candidate and continue.
|
|
790
|
+
bestPath[diagonalPath] = basePath;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
editLength++;
|
|
795
|
+
} // Performs the length of edit iteration. Is a bit fugly as this has to support the
|
|
796
|
+
// sync and async mode which is never fun. Loops over execEditLength until a value
|
|
797
|
+
// is produced.
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
if (callback) {
|
|
801
|
+
(function exec() {
|
|
802
|
+
setTimeout(function () {
|
|
803
|
+
// This should not happen, but we want to be safe.
|
|
804
|
+
|
|
805
|
+
/* istanbul ignore next */
|
|
806
|
+
if (editLength > maxEditLength) {
|
|
807
|
+
return callback();
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
if (!execEditLength()) {
|
|
811
|
+
exec();
|
|
812
|
+
}
|
|
813
|
+
}, 0);
|
|
814
|
+
})();
|
|
815
|
+
} else {
|
|
816
|
+
while (editLength <= maxEditLength) {
|
|
817
|
+
var ret = execEditLength();
|
|
818
|
+
|
|
819
|
+
if (ret) {
|
|
820
|
+
return ret;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
pushComponent: function pushComponent(components, added, removed) {
|
|
826
|
+
var last = components[components.length - 1];
|
|
827
|
+
|
|
828
|
+
if (last && last.added === added && last.removed === removed) {
|
|
829
|
+
// We need to clone here as the component clone operation is just
|
|
830
|
+
// as shallow array clone
|
|
831
|
+
components[components.length - 1] = {
|
|
832
|
+
count: last.count + 1,
|
|
833
|
+
added: added,
|
|
834
|
+
removed: removed
|
|
835
|
+
};
|
|
836
|
+
} else {
|
|
837
|
+
components.push({
|
|
838
|
+
count: 1,
|
|
839
|
+
added: added,
|
|
840
|
+
removed: removed
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
},
|
|
844
|
+
extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) {
|
|
845
|
+
var newLen = newString.length,
|
|
846
|
+
oldLen = oldString.length,
|
|
847
|
+
newPos = basePath.newPos,
|
|
848
|
+
oldPos = newPos - diagonalPath,
|
|
849
|
+
commonCount = 0;
|
|
850
|
+
|
|
851
|
+
while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {
|
|
852
|
+
newPos++;
|
|
853
|
+
oldPos++;
|
|
854
|
+
commonCount++;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
if (commonCount) {
|
|
858
|
+
basePath.components.push({
|
|
859
|
+
count: commonCount
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
basePath.newPos = newPos;
|
|
864
|
+
return oldPos;
|
|
865
|
+
},
|
|
866
|
+
equals: function equals(left, right) {
|
|
867
|
+
if (this.options.comparator) {
|
|
868
|
+
return this.options.comparator(left, right);
|
|
869
|
+
} else {
|
|
870
|
+
return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase();
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
removeEmpty: function removeEmpty(array) {
|
|
874
|
+
var ret = [];
|
|
875
|
+
|
|
876
|
+
for (var i = 0; i < array.length; i++) {
|
|
877
|
+
if (array[i]) {
|
|
878
|
+
ret.push(array[i]);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
return ret;
|
|
883
|
+
},
|
|
884
|
+
castInput: function castInput(value) {
|
|
885
|
+
return value;
|
|
886
|
+
},
|
|
887
|
+
tokenize: function tokenize(value) {
|
|
888
|
+
return value.split('');
|
|
889
|
+
},
|
|
890
|
+
join: function join(chars) {
|
|
891
|
+
return chars.join('');
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
|
|
895
|
+
function buildValues(diff, components, newString, oldString, useLongestToken) {
|
|
896
|
+
var componentPos = 0,
|
|
897
|
+
componentLen = components.length,
|
|
898
|
+
newPos = 0,
|
|
899
|
+
oldPos = 0;
|
|
900
|
+
|
|
901
|
+
for (; componentPos < componentLen; componentPos++) {
|
|
902
|
+
var component = components[componentPos];
|
|
903
|
+
|
|
904
|
+
if (!component.removed) {
|
|
905
|
+
if (!component.added && useLongestToken) {
|
|
906
|
+
var value = newString.slice(newPos, newPos + component.count);
|
|
907
|
+
value = value.map(function (value, i) {
|
|
908
|
+
var oldValue = oldString[oldPos + i];
|
|
909
|
+
return oldValue.length > value.length ? oldValue : value;
|
|
910
|
+
});
|
|
911
|
+
component.value = diff.join(value);
|
|
912
|
+
} else {
|
|
913
|
+
component.value = diff.join(newString.slice(newPos, newPos + component.count));
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
newPos += component.count; // Common case
|
|
917
|
+
|
|
918
|
+
if (!component.added) {
|
|
919
|
+
oldPos += component.count;
|
|
920
|
+
}
|
|
921
|
+
} else {
|
|
922
|
+
component.value = diff.join(oldString.slice(oldPos, oldPos + component.count));
|
|
923
|
+
oldPos += component.count; // Reverse add and remove so removes are output first to match common convention
|
|
924
|
+
// The diffing algorithm is tied to add then remove output and this is the simplest
|
|
925
|
+
// route to get the desired output with minimal overhead.
|
|
926
|
+
|
|
927
|
+
if (componentPos && components[componentPos - 1].added) {
|
|
928
|
+
var tmp = components[componentPos - 1];
|
|
929
|
+
components[componentPos - 1] = components[componentPos];
|
|
930
|
+
components[componentPos] = tmp;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
} // Special case handle for when one terminal is ignored (i.e. whitespace).
|
|
934
|
+
// For this case we merge the terminal into the prior string and drop the change.
|
|
935
|
+
// This is only available for string mode.
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
var lastComponent = components[componentLen - 1];
|
|
939
|
+
|
|
940
|
+
if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) {
|
|
941
|
+
components[componentLen - 2].value += lastComponent.value;
|
|
942
|
+
components.pop();
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
return components;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
function clonePath(path) {
|
|
949
|
+
return {
|
|
950
|
+
newPos: path.newPos,
|
|
951
|
+
components: path.components.slice(0)
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
//
|
|
956
|
+
// Ranges and exceptions:
|
|
957
|
+
// Latin-1 Supplement, 0080–00FF
|
|
958
|
+
// - U+00D7 × Multiplication sign
|
|
959
|
+
// - U+00F7 ÷ Division sign
|
|
960
|
+
// Latin Extended-A, 0100–017F
|
|
961
|
+
// Latin Extended-B, 0180–024F
|
|
962
|
+
// IPA Extensions, 0250–02AF
|
|
963
|
+
// Spacing Modifier Letters, 02B0–02FF
|
|
964
|
+
// - U+02C7 ˇ ˇ Caron
|
|
965
|
+
// - U+02D8 ˘ ˘ Breve
|
|
966
|
+
// - U+02D9 ˙ ˙ Dot Above
|
|
967
|
+
// - U+02DA ˚ ˚ Ring Above
|
|
968
|
+
// - U+02DB ˛ ˛ Ogonek
|
|
969
|
+
// - U+02DC ˜ ˜ Small Tilde
|
|
970
|
+
// - U+02DD ˝ ˝ Double Acute Accent
|
|
971
|
+
// Latin Extended Additional, 1E00–1EFF
|
|
972
|
+
|
|
973
|
+
var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/;
|
|
974
|
+
var reWhitespace = /\S/;
|
|
975
|
+
var wordDiff = new Diff();
|
|
976
|
+
|
|
977
|
+
wordDiff.equals = function (left, right) {
|
|
978
|
+
if (this.options.ignoreCase) {
|
|
979
|
+
left = left.toLowerCase();
|
|
980
|
+
right = right.toLowerCase();
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right);
|
|
984
|
+
};
|
|
985
|
+
|
|
986
|
+
wordDiff.tokenize = function (value) {
|
|
987
|
+
// All whitespace symbols except newline group into one token, each newline - in separate token
|
|
988
|
+
var tokens = value.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/); // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set.
|
|
989
|
+
|
|
990
|
+
for (var i = 0; i < tokens.length - 1; i++) {
|
|
991
|
+
// If we have an empty string in the next field and we have only word chars before and after, merge
|
|
992
|
+
if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) {
|
|
993
|
+
tokens[i] += tokens[i + 2];
|
|
994
|
+
tokens.splice(i + 1, 2);
|
|
995
|
+
i--;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
return tokens;
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
var lineDiff = new Diff();
|
|
1003
|
+
|
|
1004
|
+
lineDiff.tokenize = function (value) {
|
|
1005
|
+
var retLines = [],
|
|
1006
|
+
linesAndNewlines = value.split(/(\n|\r\n)/); // Ignore the final empty token that occurs if the string ends with a new line
|
|
1007
|
+
|
|
1008
|
+
if (!linesAndNewlines[linesAndNewlines.length - 1]) {
|
|
1009
|
+
linesAndNewlines.pop();
|
|
1010
|
+
} // Merge the content and line separators into single tokens
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
for (var i = 0; i < linesAndNewlines.length; i++) {
|
|
1014
|
+
var line = linesAndNewlines[i];
|
|
1015
|
+
|
|
1016
|
+
if (i % 2 && !this.options.newlineIsToken) {
|
|
1017
|
+
retLines[retLines.length - 1] += line;
|
|
1018
|
+
} else {
|
|
1019
|
+
if (this.options.ignoreWhitespace) {
|
|
1020
|
+
line = line.trim();
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
retLines.push(line);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
return retLines;
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
function diffLines(oldStr, newStr, callback) {
|
|
1031
|
+
return lineDiff.diff(oldStr, newStr, callback);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
var sentenceDiff = new Diff();
|
|
1035
|
+
|
|
1036
|
+
sentenceDiff.tokenize = function (value) {
|
|
1037
|
+
return value.split(/(\S.+?[.!?])(?=\s+|$)/);
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
var cssDiff = new Diff();
|
|
1041
|
+
|
|
1042
|
+
cssDiff.tokenize = function (value) {
|
|
1043
|
+
return value.split(/([{}:;,]|\s+)/);
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
function _typeof(obj) {
|
|
1047
|
+
"@babel/helpers - typeof";
|
|
1048
|
+
|
|
1049
|
+
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
|
1050
|
+
_typeof = function (obj) {
|
|
1051
|
+
return typeof obj;
|
|
1052
|
+
};
|
|
1053
|
+
} else {
|
|
1054
|
+
_typeof = function (obj) {
|
|
1055
|
+
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
return _typeof(obj);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
function _toConsumableArray(arr) {
|
|
1063
|
+
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
function _arrayWithoutHoles(arr) {
|
|
1067
|
+
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
function _iterableToArray(iter) {
|
|
1071
|
+
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
function _unsupportedIterableToArray(o, minLen) {
|
|
1075
|
+
if (!o) return;
|
|
1076
|
+
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
1077
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1078
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
1079
|
+
if (n === "Map" || n === "Set") return Array.from(o);
|
|
1080
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
function _arrayLikeToArray(arr, len) {
|
|
1084
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
1085
|
+
|
|
1086
|
+
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
1087
|
+
|
|
1088
|
+
return arr2;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
function _nonIterableSpread() {
|
|
1092
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
var objectPrototypeToString = Object.prototype.toString;
|
|
1096
|
+
var jsonDiff = new Diff(); // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a
|
|
1097
|
+
// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:
|
|
1098
|
+
|
|
1099
|
+
jsonDiff.useLongestToken = true;
|
|
1100
|
+
jsonDiff.tokenize = lineDiff.tokenize;
|
|
1101
|
+
|
|
1102
|
+
jsonDiff.castInput = function (value) {
|
|
1103
|
+
var _this$options = this.options,
|
|
1104
|
+
undefinedReplacement = _this$options.undefinedReplacement,
|
|
1105
|
+
_this$options$stringi = _this$options.stringifyReplacer,
|
|
1106
|
+
stringifyReplacer = _this$options$stringi === void 0 ? function (k, v) {
|
|
1107
|
+
return typeof v === 'undefined' ? undefinedReplacement : v;
|
|
1108
|
+
} : _this$options$stringi;
|
|
1109
|
+
return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' ');
|
|
1110
|
+
};
|
|
1111
|
+
|
|
1112
|
+
jsonDiff.equals = function (left, right) {
|
|
1113
|
+
return Diff.prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1'));
|
|
1114
|
+
};
|
|
1115
|
+
// object that is already on the "stack" of items being processed. Accepts an optional replacer
|
|
1116
|
+
|
|
1117
|
+
function canonicalize(obj, stack, replacementStack, replacer, key) {
|
|
1118
|
+
stack = stack || [];
|
|
1119
|
+
replacementStack = replacementStack || [];
|
|
1120
|
+
|
|
1121
|
+
if (replacer) {
|
|
1122
|
+
obj = replacer(key, obj);
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
var i;
|
|
1126
|
+
|
|
1127
|
+
for (i = 0; i < stack.length; i += 1) {
|
|
1128
|
+
if (stack[i] === obj) {
|
|
1129
|
+
return replacementStack[i];
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
var canonicalizedObj;
|
|
1134
|
+
|
|
1135
|
+
if ('[object Array]' === objectPrototypeToString.call(obj)) {
|
|
1136
|
+
stack.push(obj);
|
|
1137
|
+
canonicalizedObj = new Array(obj.length);
|
|
1138
|
+
replacementStack.push(canonicalizedObj);
|
|
1139
|
+
|
|
1140
|
+
for (i = 0; i < obj.length; i += 1) {
|
|
1141
|
+
canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key);
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
stack.pop();
|
|
1145
|
+
replacementStack.pop();
|
|
1146
|
+
return canonicalizedObj;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
if (obj && obj.toJSON) {
|
|
1150
|
+
obj = obj.toJSON();
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
if (_typeof(obj) === 'object' && obj !== null) {
|
|
1154
|
+
stack.push(obj);
|
|
1155
|
+
canonicalizedObj = {};
|
|
1156
|
+
replacementStack.push(canonicalizedObj);
|
|
1157
|
+
|
|
1158
|
+
var sortedKeys = [],
|
|
1159
|
+
_key;
|
|
1160
|
+
|
|
1161
|
+
for (_key in obj) {
|
|
1162
|
+
/* istanbul ignore else */
|
|
1163
|
+
if (obj.hasOwnProperty(_key)) {
|
|
1164
|
+
sortedKeys.push(_key);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
sortedKeys.sort();
|
|
1169
|
+
|
|
1170
|
+
for (i = 0; i < sortedKeys.length; i += 1) {
|
|
1171
|
+
_key = sortedKeys[i];
|
|
1172
|
+
canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
stack.pop();
|
|
1176
|
+
replacementStack.pop();
|
|
1177
|
+
} else {
|
|
1178
|
+
canonicalizedObj = obj;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
return canonicalizedObj;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
var arrayDiff = new Diff();
|
|
1185
|
+
|
|
1186
|
+
arrayDiff.tokenize = function (value) {
|
|
1187
|
+
return value.slice();
|
|
1188
|
+
};
|
|
1189
|
+
|
|
1190
|
+
arrayDiff.join = arrayDiff.removeEmpty = function (value) {
|
|
1191
|
+
return value;
|
|
1192
|
+
};
|
|
1193
|
+
|
|
1194
|
+
function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
1195
|
+
if (!options) {
|
|
1196
|
+
options = {};
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
if (typeof options.context === 'undefined') {
|
|
1200
|
+
options.context = 4;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
var diff = diffLines(oldStr, newStr, options);
|
|
1204
|
+
diff.push({
|
|
1205
|
+
value: '',
|
|
1206
|
+
lines: []
|
|
1207
|
+
}); // Append an empty value to make cleanup easier
|
|
1208
|
+
|
|
1209
|
+
function contextLines(lines) {
|
|
1210
|
+
return lines.map(function (entry) {
|
|
1211
|
+
return ' ' + entry;
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
var hunks = [];
|
|
1216
|
+
var oldRangeStart = 0,
|
|
1217
|
+
newRangeStart = 0,
|
|
1218
|
+
curRange = [],
|
|
1219
|
+
oldLine = 1,
|
|
1220
|
+
newLine = 1;
|
|
1221
|
+
|
|
1222
|
+
var _loop = function _loop(i) {
|
|
1223
|
+
var current = diff[i],
|
|
1224
|
+
lines = current.lines || current.value.replace(/\n$/, '').split('\n');
|
|
1225
|
+
current.lines = lines;
|
|
1226
|
+
|
|
1227
|
+
if (current.added || current.removed) {
|
|
1228
|
+
var _curRange;
|
|
1229
|
+
|
|
1230
|
+
// If we have previous context, start with that
|
|
1231
|
+
if (!oldRangeStart) {
|
|
1232
|
+
var prev = diff[i - 1];
|
|
1233
|
+
oldRangeStart = oldLine;
|
|
1234
|
+
newRangeStart = newLine;
|
|
1235
|
+
|
|
1236
|
+
if (prev) {
|
|
1237
|
+
curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : [];
|
|
1238
|
+
oldRangeStart -= curRange.length;
|
|
1239
|
+
newRangeStart -= curRange.length;
|
|
1240
|
+
}
|
|
1241
|
+
} // Output our changes
|
|
1242
|
+
|
|
1243
|
+
|
|
1244
|
+
(_curRange = curRange).push.apply(_curRange, _toConsumableArray(lines.map(function (entry) {
|
|
1245
|
+
return (current.added ? '+' : '-') + entry;
|
|
1246
|
+
}))); // Track the updated file position
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
if (current.added) {
|
|
1250
|
+
newLine += lines.length;
|
|
1251
|
+
} else {
|
|
1252
|
+
oldLine += lines.length;
|
|
1253
|
+
}
|
|
1254
|
+
} else {
|
|
1255
|
+
// Identical context lines. Track line changes
|
|
1256
|
+
if (oldRangeStart) {
|
|
1257
|
+
// Close out any changes that have been output (or join overlapping)
|
|
1258
|
+
if (lines.length <= options.context * 2 && i < diff.length - 2) {
|
|
1259
|
+
var _curRange2;
|
|
1260
|
+
|
|
1261
|
+
// Overlapping
|
|
1262
|
+
(_curRange2 = curRange).push.apply(_curRange2, _toConsumableArray(contextLines(lines)));
|
|
1263
|
+
} else {
|
|
1264
|
+
var _curRange3;
|
|
1265
|
+
|
|
1266
|
+
// end the range and output
|
|
1267
|
+
var contextSize = Math.min(lines.length, options.context);
|
|
1268
|
+
|
|
1269
|
+
(_curRange3 = curRange).push.apply(_curRange3, _toConsumableArray(contextLines(lines.slice(0, contextSize))));
|
|
1270
|
+
|
|
1271
|
+
var hunk = {
|
|
1272
|
+
oldStart: oldRangeStart,
|
|
1273
|
+
oldLines: oldLine - oldRangeStart + contextSize,
|
|
1274
|
+
newStart: newRangeStart,
|
|
1275
|
+
newLines: newLine - newRangeStart + contextSize,
|
|
1276
|
+
lines: curRange
|
|
1277
|
+
};
|
|
1278
|
+
|
|
1279
|
+
if (i >= diff.length - 2 && lines.length <= options.context) {
|
|
1280
|
+
// EOF is inside this hunk
|
|
1281
|
+
var oldEOFNewline = /\n$/.test(oldStr);
|
|
1282
|
+
var newEOFNewline = /\n$/.test(newStr);
|
|
1283
|
+
var noNlBeforeAdds = lines.length == 0 && curRange.length > hunk.oldLines;
|
|
1284
|
+
|
|
1285
|
+
if (!oldEOFNewline && noNlBeforeAdds && oldStr.length > 0) {
|
|
1286
|
+
// special case: old has no eol and no trailing context; no-nl can end up before adds
|
|
1287
|
+
// however, if the old file is empty, do not output the no-nl line
|
|
1288
|
+
curRange.splice(hunk.oldLines, 0, '\');
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
if (!oldEOFNewline && !noNlBeforeAdds || !newEOFNewline) {
|
|
1292
|
+
curRange.push('\');
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
hunks.push(hunk);
|
|
1297
|
+
oldRangeStart = 0;
|
|
1298
|
+
newRangeStart = 0;
|
|
1299
|
+
curRange = [];
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
oldLine += lines.length;
|
|
1304
|
+
newLine += lines.length;
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1308
|
+
for (var i = 0; i < diff.length; i++) {
|
|
1309
|
+
_loop(i);
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
return {
|
|
1313
|
+
oldFileName: oldFileName,
|
|
1314
|
+
newFileName: newFileName,
|
|
1315
|
+
oldHeader: oldHeader,
|
|
1316
|
+
newHeader: newHeader,
|
|
1317
|
+
hunks: hunks
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
function formatPatch(diff) {
|
|
1321
|
+
var ret = [];
|
|
1322
|
+
|
|
1323
|
+
if (diff.oldFileName == diff.newFileName) {
|
|
1324
|
+
ret.push('Index: ' + diff.oldFileName);
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
ret.push('===================================================================');
|
|
1328
|
+
ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader));
|
|
1329
|
+
ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader));
|
|
1330
|
+
|
|
1331
|
+
for (var i = 0; i < diff.hunks.length; i++) {
|
|
1332
|
+
var hunk = diff.hunks[i]; // Unified Diff Format quirk: If the chunk size is 0,
|
|
1333
|
+
// the first number is one lower than one would expect.
|
|
1334
|
+
// https://www.artima.com/weblogs/viewpost.jsp?thread=164293
|
|
1335
|
+
|
|
1336
|
+
if (hunk.oldLines === 0) {
|
|
1337
|
+
hunk.oldStart -= 1;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
if (hunk.newLines === 0) {
|
|
1341
|
+
hunk.newStart -= 1;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@');
|
|
1345
|
+
ret.push.apply(ret, hunk.lines);
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
return ret.join('\n') + '\n';
|
|
1349
|
+
}
|
|
1350
|
+
function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
1351
|
+
return formatPatch(structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options));
|
|
1352
|
+
}
|
|
1353
|
+
function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) {
|
|
1354
|
+
return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options);
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
/* eslint-disable yoda */
|
|
1358
|
+
|
|
1359
|
+
function isFullwidthCodePoint(codePoint) {
|
|
1360
|
+
if (!Number.isInteger(codePoint)) {
|
|
1361
|
+
return false;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
// Code points are derived from:
|
|
1365
|
+
// https://unicode.org/Public/UNIDATA/EastAsianWidth.txt
|
|
1366
|
+
return codePoint >= 0x1100 && (
|
|
1367
|
+
codePoint <= 0x115F || // Hangul Jamo
|
|
1368
|
+
codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET
|
|
1369
|
+
codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET
|
|
1370
|
+
// CJK Radicals Supplement .. Enclosed CJK Letters and Months
|
|
1371
|
+
(0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) ||
|
|
1372
|
+
// Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
|
|
1373
|
+
(0x3250 <= codePoint && codePoint <= 0x4DBF) ||
|
|
1374
|
+
// CJK Unified Ideographs .. Yi Radicals
|
|
1375
|
+
(0x4E00 <= codePoint && codePoint <= 0xA4C6) ||
|
|
1376
|
+
// Hangul Jamo Extended-A
|
|
1377
|
+
(0xA960 <= codePoint && codePoint <= 0xA97C) ||
|
|
1378
|
+
// Hangul Syllables
|
|
1379
|
+
(0xAC00 <= codePoint && codePoint <= 0xD7A3) ||
|
|
1380
|
+
// CJK Compatibility Ideographs
|
|
1381
|
+
(0xF900 <= codePoint && codePoint <= 0xFAFF) ||
|
|
1382
|
+
// Vertical Forms
|
|
1383
|
+
(0xFE10 <= codePoint && codePoint <= 0xFE19) ||
|
|
1384
|
+
// CJK Compatibility Forms .. Small Form Variants
|
|
1385
|
+
(0xFE30 <= codePoint && codePoint <= 0xFE6B) ||
|
|
1386
|
+
// Halfwidth and Fullwidth Forms
|
|
1387
|
+
(0xFF01 <= codePoint && codePoint <= 0xFF60) ||
|
|
1388
|
+
(0xFFE0 <= codePoint && codePoint <= 0xFFE6) ||
|
|
1389
|
+
// Kana Supplement
|
|
1390
|
+
(0x1B000 <= codePoint && codePoint <= 0x1B001) ||
|
|
1391
|
+
// Enclosed Ideographic Supplement
|
|
1392
|
+
(0x1F200 <= codePoint && codePoint <= 0x1F251) ||
|
|
1393
|
+
// CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
|
|
1394
|
+
(0x20000 <= codePoint && codePoint <= 0x3FFFD)
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
const ANSI_BACKGROUND_OFFSET = 10;
|
|
1399
|
+
|
|
1400
|
+
const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;
|
|
1401
|
+
|
|
1402
|
+
const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;
|
|
1403
|
+
|
|
1404
|
+
const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;
|
|
1405
|
+
|
|
1406
|
+
function assembleStyles() {
|
|
1407
|
+
const codes = new Map();
|
|
1408
|
+
const styles = {
|
|
1409
|
+
modifier: {
|
|
1410
|
+
reset: [0, 0],
|
|
1411
|
+
// 21 isn't widely supported and 22 does the same thing
|
|
1412
|
+
bold: [1, 22],
|
|
1413
|
+
dim: [2, 22],
|
|
1414
|
+
italic: [3, 23],
|
|
1415
|
+
underline: [4, 24],
|
|
1416
|
+
overline: [53, 55],
|
|
1417
|
+
inverse: [7, 27],
|
|
1418
|
+
hidden: [8, 28],
|
|
1419
|
+
strikethrough: [9, 29]
|
|
1420
|
+
},
|
|
1421
|
+
color: {
|
|
1422
|
+
black: [30, 39],
|
|
1423
|
+
red: [31, 39],
|
|
1424
|
+
green: [32, 39],
|
|
1425
|
+
yellow: [33, 39],
|
|
1426
|
+
blue: [34, 39],
|
|
1427
|
+
magenta: [35, 39],
|
|
1428
|
+
cyan: [36, 39],
|
|
1429
|
+
white: [37, 39],
|
|
1430
|
+
|
|
1431
|
+
// Bright color
|
|
1432
|
+
blackBright: [90, 39],
|
|
1433
|
+
redBright: [91, 39],
|
|
1434
|
+
greenBright: [92, 39],
|
|
1435
|
+
yellowBright: [93, 39],
|
|
1436
|
+
blueBright: [94, 39],
|
|
1437
|
+
magentaBright: [95, 39],
|
|
1438
|
+
cyanBright: [96, 39],
|
|
1439
|
+
whiteBright: [97, 39]
|
|
1440
|
+
},
|
|
1441
|
+
bgColor: {
|
|
1442
|
+
bgBlack: [40, 49],
|
|
1443
|
+
bgRed: [41, 49],
|
|
1444
|
+
bgGreen: [42, 49],
|
|
1445
|
+
bgYellow: [43, 49],
|
|
1446
|
+
bgBlue: [44, 49],
|
|
1447
|
+
bgMagenta: [45, 49],
|
|
1448
|
+
bgCyan: [46, 49],
|
|
1449
|
+
bgWhite: [47, 49],
|
|
1450
|
+
|
|
1451
|
+
// Bright color
|
|
1452
|
+
bgBlackBright: [100, 49],
|
|
1453
|
+
bgRedBright: [101, 49],
|
|
1454
|
+
bgGreenBright: [102, 49],
|
|
1455
|
+
bgYellowBright: [103, 49],
|
|
1456
|
+
bgBlueBright: [104, 49],
|
|
1457
|
+
bgMagentaBright: [105, 49],
|
|
1458
|
+
bgCyanBright: [106, 49],
|
|
1459
|
+
bgWhiteBright: [107, 49]
|
|
1460
|
+
}
|
|
1461
|
+
};
|
|
1462
|
+
|
|
1463
|
+
// Alias bright black as gray (and grey)
|
|
1464
|
+
styles.color.gray = styles.color.blackBright;
|
|
1465
|
+
styles.bgColor.bgGray = styles.bgColor.bgBlackBright;
|
|
1466
|
+
styles.color.grey = styles.color.blackBright;
|
|
1467
|
+
styles.bgColor.bgGrey = styles.bgColor.bgBlackBright;
|
|
1468
|
+
|
|
1469
|
+
for (const [groupName, group] of Object.entries(styles)) {
|
|
1470
|
+
for (const [styleName, style] of Object.entries(group)) {
|
|
1471
|
+
styles[styleName] = {
|
|
1472
|
+
open: `\u001B[${style[0]}m`,
|
|
1473
|
+
close: `\u001B[${style[1]}m`
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1476
|
+
group[styleName] = styles[styleName];
|
|
1477
|
+
|
|
1478
|
+
codes.set(style[0], style[1]);
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
Object.defineProperty(styles, groupName, {
|
|
1482
|
+
value: group,
|
|
1483
|
+
enumerable: false
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
Object.defineProperty(styles, 'codes', {
|
|
1488
|
+
value: codes,
|
|
1489
|
+
enumerable: false
|
|
1490
|
+
});
|
|
1491
|
+
|
|
1492
|
+
styles.color.close = '\u001B[39m';
|
|
1493
|
+
styles.bgColor.close = '\u001B[49m';
|
|
1494
|
+
|
|
1495
|
+
styles.color.ansi = wrapAnsi16();
|
|
1496
|
+
styles.color.ansi256 = wrapAnsi256();
|
|
1497
|
+
styles.color.ansi16m = wrapAnsi16m();
|
|
1498
|
+
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
1499
|
+
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
1500
|
+
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
1501
|
+
|
|
1502
|
+
// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js
|
|
1503
|
+
Object.defineProperties(styles, {
|
|
1504
|
+
rgbToAnsi256: {
|
|
1505
|
+
value: (red, green, blue) => {
|
|
1506
|
+
// We use the extended greyscale palette here, with the exception of
|
|
1507
|
+
// black and white. normal palette only has 4 greyscale shades.
|
|
1508
|
+
if (red === green && green === blue) {
|
|
1509
|
+
if (red < 8) {
|
|
1510
|
+
return 16;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
if (red > 248) {
|
|
1514
|
+
return 231;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
return Math.round(((red - 8) / 247) * 24) + 232;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
return 16 +
|
|
1521
|
+
(36 * Math.round(red / 255 * 5)) +
|
|
1522
|
+
(6 * Math.round(green / 255 * 5)) +
|
|
1523
|
+
Math.round(blue / 255 * 5);
|
|
1524
|
+
},
|
|
1525
|
+
enumerable: false
|
|
1526
|
+
},
|
|
1527
|
+
hexToRgb: {
|
|
1528
|
+
value: hex => {
|
|
1529
|
+
const matches = /(?<colorString>[a-f\d]{6}|[a-f\d]{3})/i.exec(hex.toString(16));
|
|
1530
|
+
if (!matches) {
|
|
1531
|
+
return [0, 0, 0];
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
let {colorString} = matches.groups;
|
|
1535
|
+
|
|
1536
|
+
if (colorString.length === 3) {
|
|
1537
|
+
colorString = colorString.split('').map(character => character + character).join('');
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
const integer = Number.parseInt(colorString, 16);
|
|
1541
|
+
|
|
1542
|
+
return [
|
|
1543
|
+
(integer >> 16) & 0xFF,
|
|
1544
|
+
(integer >> 8) & 0xFF,
|
|
1545
|
+
integer & 0xFF
|
|
1546
|
+
];
|
|
1547
|
+
},
|
|
1548
|
+
enumerable: false
|
|
1549
|
+
},
|
|
1550
|
+
hexToAnsi256: {
|
|
1551
|
+
value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
1552
|
+
enumerable: false
|
|
1553
|
+
},
|
|
1554
|
+
ansi256ToAnsi: {
|
|
1555
|
+
value: code => {
|
|
1556
|
+
if (code < 8) {
|
|
1557
|
+
return 30 + code;
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
if (code < 16) {
|
|
1561
|
+
return 90 + (code - 8);
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
let red;
|
|
1565
|
+
let green;
|
|
1566
|
+
let blue;
|
|
1567
|
+
|
|
1568
|
+
if (code >= 232) {
|
|
1569
|
+
red = (((code - 232) * 10) + 8) / 255;
|
|
1570
|
+
green = red;
|
|
1571
|
+
blue = red;
|
|
1572
|
+
} else {
|
|
1573
|
+
code -= 16;
|
|
1574
|
+
|
|
1575
|
+
const remainder = code % 36;
|
|
1576
|
+
|
|
1577
|
+
red = Math.floor(code / 36) / 5;
|
|
1578
|
+
green = Math.floor(remainder / 6) / 5;
|
|
1579
|
+
blue = (remainder % 6) / 5;
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
const value = Math.max(red, green, blue) * 2;
|
|
1583
|
+
|
|
1584
|
+
if (value === 0) {
|
|
1585
|
+
return 30;
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));
|
|
1589
|
+
|
|
1590
|
+
if (value === 2) {
|
|
1591
|
+
result += 60;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
return result;
|
|
1595
|
+
},
|
|
1596
|
+
enumerable: false
|
|
1597
|
+
},
|
|
1598
|
+
rgbToAnsi: {
|
|
1599
|
+
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
1600
|
+
enumerable: false
|
|
1601
|
+
},
|
|
1602
|
+
hexToAnsi: {
|
|
1603
|
+
value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
1604
|
+
enumerable: false
|
|
1605
|
+
}
|
|
1606
|
+
});
|
|
1607
|
+
|
|
1608
|
+
return styles;
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
const ansiStyles = assembleStyles();
|
|
1612
|
+
|
|
1613
|
+
const astralRegex = /^[\uD800-\uDBFF][\uDC00-\uDFFF]$/;
|
|
1614
|
+
|
|
1615
|
+
const ESCAPES$1 = [
|
|
1616
|
+
'\u001B',
|
|
1617
|
+
'\u009B'
|
|
1618
|
+
];
|
|
1619
|
+
|
|
1620
|
+
const wrapAnsi$1 = code => `${ESCAPES$1[0]}[${code}m`;
|
|
1621
|
+
|
|
1622
|
+
const checkAnsi = (ansiCodes, isEscapes, endAnsiCode) => {
|
|
1623
|
+
let output = [];
|
|
1624
|
+
ansiCodes = [...ansiCodes];
|
|
1625
|
+
|
|
1626
|
+
for (let ansiCode of ansiCodes) {
|
|
1627
|
+
const ansiCodeOrigin = ansiCode;
|
|
1628
|
+
if (ansiCode.includes(';')) {
|
|
1629
|
+
ansiCode = ansiCode.split(';')[0][0] + '0';
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
const item = ansiStyles.codes.get(Number.parseInt(ansiCode, 10));
|
|
1633
|
+
if (item) {
|
|
1634
|
+
const indexEscape = ansiCodes.indexOf(item.toString());
|
|
1635
|
+
if (indexEscape === -1) {
|
|
1636
|
+
output.push(wrapAnsi$1(isEscapes ? item : ansiCodeOrigin));
|
|
1637
|
+
} else {
|
|
1638
|
+
ansiCodes.splice(indexEscape, 1);
|
|
1639
|
+
}
|
|
1640
|
+
} else if (isEscapes) {
|
|
1641
|
+
output.push(wrapAnsi$1(0));
|
|
1642
|
+
break;
|
|
1643
|
+
} else {
|
|
1644
|
+
output.push(wrapAnsi$1(ansiCodeOrigin));
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
if (isEscapes) {
|
|
1649
|
+
output = output.filter((element, index) => output.indexOf(element) === index);
|
|
1650
|
+
|
|
1651
|
+
if (endAnsiCode !== undefined) {
|
|
1652
|
+
const fistEscapeCode = wrapAnsi$1(ansiStyles.codes.get(Number.parseInt(endAnsiCode, 10)));
|
|
1653
|
+
// TODO: Remove the use of `.reduce` here.
|
|
1654
|
+
// eslint-disable-next-line unicorn/no-array-reduce
|
|
1655
|
+
output = output.reduce((current, next) => next === fistEscapeCode ? [next, ...current] : [...current, next], []);
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
return output.join('');
|
|
1660
|
+
};
|
|
1661
|
+
|
|
1662
|
+
function sliceAnsi(string, begin, end) {
|
|
1663
|
+
const characters = [...string];
|
|
1664
|
+
const ansiCodes = [];
|
|
1665
|
+
|
|
1666
|
+
let stringEnd = typeof end === 'number' ? end : characters.length;
|
|
1667
|
+
let isInsideEscape = false;
|
|
1668
|
+
let ansiCode;
|
|
1669
|
+
let visible = 0;
|
|
1670
|
+
let output = '';
|
|
1671
|
+
|
|
1672
|
+
for (const [index, character] of characters.entries()) {
|
|
1673
|
+
let leftEscape = false;
|
|
1674
|
+
|
|
1675
|
+
if (ESCAPES$1.includes(character)) {
|
|
1676
|
+
const code = /\d[^m]*/.exec(string.slice(index, index + 18));
|
|
1677
|
+
ansiCode = code && code.length > 0 ? code[0] : undefined;
|
|
1678
|
+
|
|
1679
|
+
if (visible < stringEnd) {
|
|
1680
|
+
isInsideEscape = true;
|
|
1681
|
+
|
|
1682
|
+
if (ansiCode !== undefined) {
|
|
1683
|
+
ansiCodes.push(ansiCode);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
} else if (isInsideEscape && character === 'm') {
|
|
1687
|
+
isInsideEscape = false;
|
|
1688
|
+
leftEscape = true;
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
if (!isInsideEscape && !leftEscape) {
|
|
1692
|
+
visible++;
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
if (!astralRegex.test(character) && isFullwidthCodePoint(character.codePointAt())) {
|
|
1696
|
+
visible++;
|
|
1697
|
+
|
|
1698
|
+
if (typeof end !== 'number') {
|
|
1699
|
+
stringEnd++;
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
if (visible > begin && visible <= stringEnd) {
|
|
1704
|
+
output += character;
|
|
1705
|
+
} else if (visible === begin && !isInsideEscape && ansiCode !== undefined) {
|
|
1706
|
+
output = checkAnsi(ansiCodes);
|
|
1707
|
+
} else if (visible >= stringEnd) {
|
|
1708
|
+
output += checkAnsi(ansiCodes, true, ansiCode);
|
|
1709
|
+
break;
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
return output;
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
function ansiRegex({onlyFirst = false} = {}) {
|
|
1717
|
+
const pattern = [
|
|
1718
|
+
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
|
|
1719
|
+
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
|
|
1720
|
+
].join('|');
|
|
1721
|
+
|
|
1722
|
+
return new RegExp(pattern, onlyFirst ? undefined : 'g');
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
function stripAnsi(string) {
|
|
1726
|
+
if (typeof string !== 'string') {
|
|
1727
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
return string.replace(ansiRegex(), '');
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
var emojiRegex = function () {
|
|
1734
|
+
// https://mths.be/emoji
|
|
1735
|
+
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
|
|
1736
|
+
};
|
|
1737
|
+
|
|
1738
|
+
function stringWidth(string) {
|
|
1739
|
+
if (typeof string !== 'string' || string.length === 0) {
|
|
1740
|
+
return 0;
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
string = stripAnsi(string);
|
|
1744
|
+
|
|
1745
|
+
if (string.length === 0) {
|
|
1746
|
+
return 0;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
string = string.replace(emojiRegex(), ' ');
|
|
1750
|
+
|
|
1751
|
+
let width = 0;
|
|
1752
|
+
|
|
1753
|
+
for (let index = 0; index < string.length; index++) {
|
|
1754
|
+
const codePoint = string.codePointAt(index);
|
|
1755
|
+
|
|
1756
|
+
// Ignore control characters
|
|
1757
|
+
if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) {
|
|
1758
|
+
continue;
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
// Ignore combining characters
|
|
1762
|
+
if (codePoint >= 0x300 && codePoint <= 0x36F) {
|
|
1763
|
+
continue;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
// Surrogates
|
|
1767
|
+
if (codePoint > 0xFFFF) {
|
|
1768
|
+
index++;
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
width += isFullwidthCodePoint(codePoint) ? 2 : 1;
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
return width;
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
function getIndexOfNearestSpace(string, wantedIndex, shouldSearchRight) {
|
|
1778
|
+
if (string.charAt(wantedIndex) === ' ') {
|
|
1779
|
+
return wantedIndex;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
for (let index = 1; index <= 3; index++) {
|
|
1783
|
+
if (shouldSearchRight) {
|
|
1784
|
+
if (string.charAt(wantedIndex + index) === ' ') {
|
|
1785
|
+
return wantedIndex + index;
|
|
1786
|
+
}
|
|
1787
|
+
} else if (string.charAt(wantedIndex - index) === ' ') {
|
|
1788
|
+
return wantedIndex - index;
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
return wantedIndex;
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
function cliTruncate(text, columns, options) {
|
|
1796
|
+
options = {
|
|
1797
|
+
position: 'end',
|
|
1798
|
+
preferTruncationOnSpace: false,
|
|
1799
|
+
truncationCharacter: '…',
|
|
1800
|
+
...options,
|
|
1801
|
+
};
|
|
1802
|
+
|
|
1803
|
+
const {position, space, preferTruncationOnSpace} = options;
|
|
1804
|
+
let {truncationCharacter} = options;
|
|
1805
|
+
|
|
1806
|
+
if (typeof text !== 'string') {
|
|
1807
|
+
throw new TypeError(`Expected \`input\` to be a string, got ${typeof text}`);
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
if (typeof columns !== 'number') {
|
|
1811
|
+
throw new TypeError(`Expected \`columns\` to be a number, got ${typeof columns}`);
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
if (columns < 1) {
|
|
1815
|
+
return '';
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
if (columns === 1) {
|
|
1819
|
+
return truncationCharacter;
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
const length = stringWidth(text);
|
|
1823
|
+
|
|
1824
|
+
if (length <= columns) {
|
|
1825
|
+
return text;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
if (position === 'start') {
|
|
1829
|
+
if (preferTruncationOnSpace) {
|
|
1830
|
+
const nearestSpace = getIndexOfNearestSpace(text, length - columns + 1, true);
|
|
1831
|
+
return truncationCharacter + sliceAnsi(text, nearestSpace, length).trim();
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
if (space === true) {
|
|
1835
|
+
truncationCharacter += ' ';
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
return truncationCharacter + sliceAnsi(text, length - columns + stringWidth(truncationCharacter), length);
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
if (position === 'middle') {
|
|
1842
|
+
if (space === true) {
|
|
1843
|
+
truncationCharacter = ` ${truncationCharacter} `;
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
const half = Math.floor(columns / 2);
|
|
1847
|
+
|
|
1848
|
+
if (preferTruncationOnSpace) {
|
|
1849
|
+
const spaceNearFirstBreakPoint = getIndexOfNearestSpace(text, half);
|
|
1850
|
+
const spaceNearSecondBreakPoint = getIndexOfNearestSpace(text, length - (columns - half) + 1, true);
|
|
1851
|
+
return sliceAnsi(text, 0, spaceNearFirstBreakPoint) + truncationCharacter + sliceAnsi(text, spaceNearSecondBreakPoint, length).trim();
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
return (
|
|
1855
|
+
sliceAnsi(text, 0, half)
|
|
1856
|
+
+ truncationCharacter
|
|
1857
|
+
+ sliceAnsi(text, length - (columns - half) + stringWidth(truncationCharacter), length)
|
|
1858
|
+
);
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
if (position === 'end') {
|
|
1862
|
+
if (preferTruncationOnSpace) {
|
|
1863
|
+
const nearestSpace = getIndexOfNearestSpace(text, columns - 1);
|
|
1864
|
+
return sliceAnsi(text, 0, nearestSpace) + truncationCharacter;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
if (space === true) {
|
|
1868
|
+
truncationCharacter = ` ${truncationCharacter}`;
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
return sliceAnsi(text, 0, columns - stringWidth(truncationCharacter)) + truncationCharacter;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${position}`);
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
const F_RIGHT = "\u2192";
|
|
1878
|
+
const F_DOWN = "\u2193";
|
|
1879
|
+
const F_UP = "\u2191";
|
|
1880
|
+
const F_DOWN_RIGHT = "\u21B3";
|
|
1881
|
+
const F_POINTER = "\u276F";
|
|
1882
|
+
const F_DOT = "\xB7";
|
|
1883
|
+
const F_CHECK = "\u221A";
|
|
1884
|
+
const F_CROSS = "\xD7";
|
|
1885
|
+
|
|
1886
|
+
async function printError(error) {
|
|
1887
|
+
const { server } = process.__vitest__;
|
|
1888
|
+
let e = error;
|
|
1889
|
+
if (typeof error === "string") {
|
|
1890
|
+
e = {
|
|
1891
|
+
message: error.split(/\n/g)[0],
|
|
1892
|
+
stack: error
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
let codeFramePrinted = false;
|
|
1896
|
+
const stacks = parseStack(e.stack || e.stackStr || "");
|
|
1897
|
+
const nearest = stacks.find((stack) => server.moduleGraph.getModuleById(stack.file));
|
|
1898
|
+
if (nearest) {
|
|
1899
|
+
const mod = server.moduleGraph.getModuleById(nearest.file);
|
|
1900
|
+
const transformResult = mod == null ? void 0 : mod.ssrTransformResult;
|
|
1901
|
+
const pos = await getOriginalPos(transformResult == null ? void 0 : transformResult.map, nearest);
|
|
1902
|
+
if (pos && existsSync(nearest.file)) {
|
|
1903
|
+
const sourceCode = await promises.readFile(nearest.file, "utf-8");
|
|
1904
|
+
displayErrorMessage(e);
|
|
1905
|
+
displayFilePath(nearest.file, pos);
|
|
1906
|
+
displayCodeFrame(sourceCode, pos);
|
|
1907
|
+
codeFramePrinted = true;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
if (!codeFramePrinted)
|
|
1911
|
+
console.error(e);
|
|
1912
|
+
if (e.showDiff)
|
|
1913
|
+
displayDiff(e.actual, e.expected);
|
|
1914
|
+
}
|
|
1915
|
+
function displayDiff(actual, expected) {
|
|
1916
|
+
console.error(c.gray(generateDiff(stringify(actual), stringify(expected))));
|
|
1917
|
+
}
|
|
1918
|
+
function displayErrorMessage(error) {
|
|
1919
|
+
const errorName = error.name || error.nameStr || "Unknown Error";
|
|
1920
|
+
console.error(c.red(`${c.bold(errorName)}: ${error.message}`));
|
|
1921
|
+
}
|
|
1922
|
+
function displayFilePath(filePath, pos) {
|
|
1923
|
+
console.log(c.gray(`${filePath}:${pos.line}:${pos.column}`));
|
|
1924
|
+
}
|
|
1925
|
+
function displayCodeFrame(sourceCode, pos) {
|
|
1926
|
+
console.log(c.yellow(generateCodeFrame(sourceCode, pos)));
|
|
1927
|
+
}
|
|
1928
|
+
function getOriginalPos(map, { line, column }) {
|
|
1929
|
+
return new Promise((resolve) => {
|
|
1930
|
+
if (!map)
|
|
1931
|
+
return resolve(null);
|
|
1932
|
+
SourceMapConsumer.with(map, null, (consumer) => {
|
|
1933
|
+
const pos = consumer.originalPositionFor({ line, column });
|
|
1934
|
+
if (pos.line != null && pos.column != null)
|
|
1935
|
+
resolve(pos);
|
|
1936
|
+
else
|
|
1937
|
+
resolve(null);
|
|
1938
|
+
});
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1941
|
+
const splitRE = /\r?\n/;
|
|
1942
|
+
function posToNumber(source, pos) {
|
|
1943
|
+
if (typeof pos === "number")
|
|
1944
|
+
return pos;
|
|
1945
|
+
const lines = source.split(splitRE);
|
|
1946
|
+
const { line, column } = pos;
|
|
1947
|
+
let start = 0;
|
|
1948
|
+
for (let i = 0; i < line - 1; i++)
|
|
1949
|
+
start += lines[i].length + 1;
|
|
1950
|
+
return start + column;
|
|
1951
|
+
}
|
|
1952
|
+
function generateCodeFrame(source, start = 0, end, range = 2) {
|
|
1953
|
+
start = posToNumber(source, start);
|
|
1954
|
+
end = end || start;
|
|
1955
|
+
const lines = source.split(splitRE);
|
|
1956
|
+
let count = 0;
|
|
1957
|
+
const res = [];
|
|
1958
|
+
function lineNo(no = "") {
|
|
1959
|
+
return c.gray(`${String(no).padStart(3, " ")}| `);
|
|
1960
|
+
}
|
|
1961
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1962
|
+
count += lines[i].length + 1;
|
|
1963
|
+
if (count >= start) {
|
|
1964
|
+
for (let j = i - range; j <= i + range || end > count; j++) {
|
|
1965
|
+
if (j < 0 || j >= lines.length)
|
|
1966
|
+
continue;
|
|
1967
|
+
const lineLength = lines[j].length;
|
|
1968
|
+
if (lineLength > 200)
|
|
1969
|
+
return "";
|
|
1970
|
+
res.push(lineNo(j + 1) + cliTruncate(lines[j], process.stdout.columns - 5));
|
|
1971
|
+
if (j === i) {
|
|
1972
|
+
const pad = start - (count - lineLength);
|
|
1973
|
+
const length = Math.max(1, end > count ? lineLength - pad : end - start);
|
|
1974
|
+
res.push(lineNo() + " ".repeat(pad) + F_UP.repeat(length));
|
|
1975
|
+
} else if (j > i) {
|
|
1976
|
+
if (end > count) {
|
|
1977
|
+
const length = Math.max(1, Math.min(end - count, lineLength));
|
|
1978
|
+
res.push(lineNo() + F_UP.repeat(length));
|
|
1979
|
+
}
|
|
1980
|
+
count += lineLength + 1;
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
break;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
return res.join("\n");
|
|
1987
|
+
}
|
|
1988
|
+
function stringify(obj) {
|
|
1989
|
+
return String(obj);
|
|
1990
|
+
}
|
|
1991
|
+
const stackFnCallRE = /at (.*) \((.+):(\d+):(\d+)\)$/;
|
|
1992
|
+
const stackBarePathRE = /at ()(.+):(\d+):(\d+)$/;
|
|
1993
|
+
function parseStack(stack) {
|
|
1994
|
+
const lines = stack.split("\n");
|
|
1995
|
+
const stackFrames = lines.map((raw) => {
|
|
1996
|
+
const line = raw.trim();
|
|
1997
|
+
const match = line.match(stackFnCallRE) || line.match(stackBarePathRE);
|
|
1998
|
+
if (!match)
|
|
1999
|
+
return null;
|
|
2000
|
+
let file = match[2];
|
|
2001
|
+
if (file.startsWith("file://"))
|
|
2002
|
+
file = file.slice(7);
|
|
2003
|
+
return {
|
|
2004
|
+
method: match[1],
|
|
2005
|
+
file: match[2],
|
|
2006
|
+
line: parseInt(match[3]),
|
|
2007
|
+
column: parseInt(match[4])
|
|
2008
|
+
};
|
|
2009
|
+
});
|
|
2010
|
+
return stackFrames.filter(notNullish);
|
|
2011
|
+
}
|
|
2012
|
+
function generateDiff(actual, expected) {
|
|
2013
|
+
const diffSize = 2048;
|
|
2014
|
+
if (actual.length > diffSize)
|
|
2015
|
+
actual = `${actual.substring(0, diffSize)} ... Lines skipped`;
|
|
2016
|
+
if (expected.length > diffSize)
|
|
2017
|
+
expected = `${expected.substring(0, diffSize)} ... Lines skipped`;
|
|
2018
|
+
return unifiedDiff(actual, expected);
|
|
2019
|
+
}
|
|
2020
|
+
function unifiedDiff(actual, expected) {
|
|
2021
|
+
const indent = " ";
|
|
2022
|
+
function cleanUp(line) {
|
|
2023
|
+
if (line[0] === "+")
|
|
2024
|
+
return indent + c.green(`${line[0]}${line.slice(1)}`);
|
|
2025
|
+
if (line[0] === "-")
|
|
2026
|
+
return indent + c.red(`${line[0]}${line.slice(1)}`);
|
|
2027
|
+
if (line.match(/@@/))
|
|
2028
|
+
return "--";
|
|
2029
|
+
if (line.match(/\\ No newline/))
|
|
2030
|
+
return null;
|
|
2031
|
+
return indent + line;
|
|
2032
|
+
}
|
|
2033
|
+
const msg = createPatch("string", actual, expected);
|
|
2034
|
+
const lines = msg.split("\n").splice(5);
|
|
2035
|
+
return `
|
|
2036
|
+
${indent}${c.red("- actual")}
|
|
2037
|
+
${indent}${c.green("+ expected")}
|
|
2038
|
+
|
|
2039
|
+
${lines.map(cleanUp).filter(notBlank).join("\n")}`;
|
|
2040
|
+
}
|
|
2041
|
+
function notBlank(line) {
|
|
2042
|
+
return typeof line !== "undefined" && line !== null;
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
const ESC = '\u001B[';
|
|
2046
|
+
const OSC = '\u001B]';
|
|
2047
|
+
const BEL = '\u0007';
|
|
2048
|
+
const SEP = ';';
|
|
2049
|
+
const isTerminalApp = process.env.TERM_PROGRAM === 'Apple_Terminal';
|
|
2050
|
+
|
|
2051
|
+
const ansiEscapes = {};
|
|
2052
|
+
|
|
2053
|
+
ansiEscapes.cursorTo = (x, y) => {
|
|
2054
|
+
if (typeof x !== 'number') {
|
|
2055
|
+
throw new TypeError('The `x` argument is required');
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
if (typeof y !== 'number') {
|
|
2059
|
+
return ESC + (x + 1) + 'G';
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
return ESC + (y + 1) + ';' + (x + 1) + 'H';
|
|
2063
|
+
};
|
|
2064
|
+
|
|
2065
|
+
ansiEscapes.cursorMove = (x, y) => {
|
|
2066
|
+
if (typeof x !== 'number') {
|
|
2067
|
+
throw new TypeError('The `x` argument is required');
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
let returnValue = '';
|
|
2071
|
+
|
|
2072
|
+
if (x < 0) {
|
|
2073
|
+
returnValue += ESC + (-x) + 'D';
|
|
2074
|
+
} else if (x > 0) {
|
|
2075
|
+
returnValue += ESC + x + 'C';
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
if (y < 0) {
|
|
2079
|
+
returnValue += ESC + (-y) + 'A';
|
|
2080
|
+
} else if (y > 0) {
|
|
2081
|
+
returnValue += ESC + y + 'B';
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
return returnValue;
|
|
2085
|
+
};
|
|
2086
|
+
|
|
2087
|
+
ansiEscapes.cursorUp = (count = 1) => ESC + count + 'A';
|
|
2088
|
+
ansiEscapes.cursorDown = (count = 1) => ESC + count + 'B';
|
|
2089
|
+
ansiEscapes.cursorForward = (count = 1) => ESC + count + 'C';
|
|
2090
|
+
ansiEscapes.cursorBackward = (count = 1) => ESC + count + 'D';
|
|
2091
|
+
|
|
2092
|
+
ansiEscapes.cursorLeft = ESC + 'G';
|
|
2093
|
+
ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's';
|
|
2094
|
+
ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u';
|
|
2095
|
+
ansiEscapes.cursorGetPosition = ESC + '6n';
|
|
2096
|
+
ansiEscapes.cursorNextLine = ESC + 'E';
|
|
2097
|
+
ansiEscapes.cursorPrevLine = ESC + 'F';
|
|
2098
|
+
ansiEscapes.cursorHide = ESC + '?25l';
|
|
2099
|
+
ansiEscapes.cursorShow = ESC + '?25h';
|
|
2100
|
+
|
|
2101
|
+
ansiEscapes.eraseLines = count => {
|
|
2102
|
+
let clear = '';
|
|
2103
|
+
|
|
2104
|
+
for (let i = 0; i < count; i++) {
|
|
2105
|
+
clear += ansiEscapes.eraseLine + (i < count - 1 ? ansiEscapes.cursorUp() : '');
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
if (count) {
|
|
2109
|
+
clear += ansiEscapes.cursorLeft;
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
return clear;
|
|
2113
|
+
};
|
|
2114
|
+
|
|
2115
|
+
ansiEscapes.eraseEndLine = ESC + 'K';
|
|
2116
|
+
ansiEscapes.eraseStartLine = ESC + '1K';
|
|
2117
|
+
ansiEscapes.eraseLine = ESC + '2K';
|
|
2118
|
+
ansiEscapes.eraseDown = ESC + 'J';
|
|
2119
|
+
ansiEscapes.eraseUp = ESC + '1J';
|
|
2120
|
+
ansiEscapes.eraseScreen = ESC + '2J';
|
|
2121
|
+
ansiEscapes.scrollUp = ESC + 'S';
|
|
2122
|
+
ansiEscapes.scrollDown = ESC + 'T';
|
|
2123
|
+
|
|
2124
|
+
ansiEscapes.clearScreen = '\u001Bc';
|
|
2125
|
+
|
|
2126
|
+
ansiEscapes.clearTerminal = process.platform === 'win32' ?
|
|
2127
|
+
`${ansiEscapes.eraseScreen}${ESC}0f` :
|
|
2128
|
+
// 1. Erases the screen (Only done in case `2` is not supported)
|
|
2129
|
+
// 2. Erases the whole screen including scrollback buffer
|
|
2130
|
+
// 3. Moves cursor to the top-left position
|
|
2131
|
+
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
|
2132
|
+
`${ansiEscapes.eraseScreen}${ESC}3J${ESC}H`;
|
|
2133
|
+
|
|
2134
|
+
ansiEscapes.beep = BEL;
|
|
2135
|
+
|
|
2136
|
+
ansiEscapes.link = (text, url) => {
|
|
2137
|
+
return [
|
|
2138
|
+
OSC,
|
|
2139
|
+
'8',
|
|
2140
|
+
SEP,
|
|
2141
|
+
SEP,
|
|
2142
|
+
url,
|
|
2143
|
+
BEL,
|
|
2144
|
+
text,
|
|
2145
|
+
OSC,
|
|
2146
|
+
'8',
|
|
2147
|
+
SEP,
|
|
2148
|
+
SEP,
|
|
2149
|
+
BEL
|
|
2150
|
+
].join('');
|
|
2151
|
+
};
|
|
2152
|
+
|
|
2153
|
+
ansiEscapes.image = (buffer, options = {}) => {
|
|
2154
|
+
let returnValue = `${OSC}1337;File=inline=1`;
|
|
2155
|
+
|
|
2156
|
+
if (options.width) {
|
|
2157
|
+
returnValue += `;width=${options.width}`;
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
if (options.height) {
|
|
2161
|
+
returnValue += `;height=${options.height}`;
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
if (options.preserveAspectRatio === false) {
|
|
2165
|
+
returnValue += ';preserveAspectRatio=0';
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
return returnValue + ':' + buffer.toString('base64') + BEL;
|
|
2169
|
+
};
|
|
2170
|
+
|
|
2171
|
+
ansiEscapes.iTerm = {
|
|
2172
|
+
setCwd: (cwd = process.cwd()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
|
|
2173
|
+
|
|
2174
|
+
annotation: (message, options = {}) => {
|
|
2175
|
+
let returnValue = `${OSC}1337;`;
|
|
2176
|
+
|
|
2177
|
+
const hasX = typeof options.x !== 'undefined';
|
|
2178
|
+
const hasY = typeof options.y !== 'undefined';
|
|
2179
|
+
if ((hasX || hasY) && !(hasX && hasY && typeof options.length !== 'undefined')) {
|
|
2180
|
+
throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined');
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
message = message.replace(/\|/g, '');
|
|
2184
|
+
|
|
2185
|
+
returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation=';
|
|
2186
|
+
|
|
2187
|
+
if (options.length > 0) {
|
|
2188
|
+
returnValue +=
|
|
2189
|
+
(hasX ?
|
|
2190
|
+
[message, options.length, options.x, options.y] :
|
|
2191
|
+
[options.length, message]).join('|');
|
|
2192
|
+
} else {
|
|
2193
|
+
returnValue += message;
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
return returnValue + BEL;
|
|
2197
|
+
}
|
|
2198
|
+
};
|
|
2199
|
+
|
|
2200
|
+
var onetime$2 = {exports: {}};
|
|
2201
|
+
|
|
2202
|
+
var mimicFn$2 = {exports: {}};
|
|
2203
|
+
|
|
2204
|
+
const mimicFn$1 = (to, from) => {
|
|
2205
|
+
for (const prop of Reflect.ownKeys(from)) {
|
|
2206
|
+
Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop));
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
return to;
|
|
2210
|
+
};
|
|
2211
|
+
|
|
2212
|
+
mimicFn$2.exports = mimicFn$1;
|
|
2213
|
+
// TODO: Remove this for the next major release
|
|
2214
|
+
mimicFn$2.exports.default = mimicFn$1;
|
|
2215
|
+
|
|
2216
|
+
const mimicFn = mimicFn$2.exports;
|
|
2217
|
+
|
|
2218
|
+
const calledFunctions = new WeakMap();
|
|
2219
|
+
|
|
2220
|
+
const onetime = (function_, options = {}) => {
|
|
2221
|
+
if (typeof function_ !== 'function') {
|
|
2222
|
+
throw new TypeError('Expected a function');
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
let returnValue;
|
|
2226
|
+
let callCount = 0;
|
|
2227
|
+
const functionName = function_.displayName || function_.name || '<anonymous>';
|
|
2228
|
+
|
|
2229
|
+
const onetime = function (...arguments_) {
|
|
2230
|
+
calledFunctions.set(onetime, ++callCount);
|
|
2231
|
+
|
|
2232
|
+
if (callCount === 1) {
|
|
2233
|
+
returnValue = function_.apply(this, arguments_);
|
|
2234
|
+
function_ = null;
|
|
2235
|
+
} else if (options.throw === true) {
|
|
2236
|
+
throw new Error(`Function \`${functionName}\` can only be called once`);
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2239
|
+
return returnValue;
|
|
2240
|
+
};
|
|
2241
|
+
|
|
2242
|
+
mimicFn(onetime, function_);
|
|
2243
|
+
calledFunctions.set(onetime, callCount);
|
|
2244
|
+
|
|
2245
|
+
return onetime;
|
|
2246
|
+
};
|
|
2247
|
+
|
|
2248
|
+
onetime$2.exports = onetime;
|
|
2249
|
+
// TODO: Remove this for the next major release
|
|
2250
|
+
onetime$2.exports.default = onetime;
|
|
2251
|
+
|
|
2252
|
+
onetime$2.exports.callCount = function_ => {
|
|
2253
|
+
if (!calledFunctions.has(function_)) {
|
|
2254
|
+
throw new Error(`The given function \`${function_.name}\` is not wrapped by the \`onetime\` package`);
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
return calledFunctions.get(function_);
|
|
2258
|
+
};
|
|
2259
|
+
|
|
2260
|
+
var onetime$1 = onetime$2.exports;
|
|
2261
|
+
|
|
2262
|
+
var signalExit$1 = {exports: {}};
|
|
2263
|
+
|
|
2264
|
+
var signals$1 = {exports: {}};
|
|
2265
|
+
|
|
2266
|
+
(function (module) {
|
|
2267
|
+
// This is not the set of all possible signals.
|
|
2268
|
+
//
|
|
2269
|
+
// It IS, however, the set of all signals that trigger
|
|
2270
|
+
// an exit on either Linux or BSD systems. Linux is a
|
|
2271
|
+
// superset of the signal names supported on BSD, and
|
|
2272
|
+
// the unknown signals just fail to register, so we can
|
|
2273
|
+
// catch that easily enough.
|
|
2274
|
+
//
|
|
2275
|
+
// Don't bother with SIGKILL. It's uncatchable, which
|
|
2276
|
+
// means that we can't fire any callbacks anyway.
|
|
2277
|
+
//
|
|
2278
|
+
// If a user does happen to register a handler on a non-
|
|
2279
|
+
// fatal signal like SIGWINCH or something, and then
|
|
2280
|
+
// exit, it'll end up firing `process.emit('exit')`, so
|
|
2281
|
+
// the handler will be fired anyway.
|
|
2282
|
+
//
|
|
2283
|
+
// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
|
|
2284
|
+
// artificially, inherently leave the process in a
|
|
2285
|
+
// state from which it is not safe to try and enter JS
|
|
2286
|
+
// listeners.
|
|
2287
|
+
module.exports = [
|
|
2288
|
+
'SIGABRT',
|
|
2289
|
+
'SIGALRM',
|
|
2290
|
+
'SIGHUP',
|
|
2291
|
+
'SIGINT',
|
|
2292
|
+
'SIGTERM'
|
|
2293
|
+
];
|
|
2294
|
+
|
|
2295
|
+
if (process.platform !== 'win32') {
|
|
2296
|
+
module.exports.push(
|
|
2297
|
+
'SIGVTALRM',
|
|
2298
|
+
'SIGXCPU',
|
|
2299
|
+
'SIGXFSZ',
|
|
2300
|
+
'SIGUSR2',
|
|
2301
|
+
'SIGTRAP',
|
|
2302
|
+
'SIGSYS',
|
|
2303
|
+
'SIGQUIT',
|
|
2304
|
+
'SIGIOT'
|
|
2305
|
+
// should detect profiler and enable/disable accordingly.
|
|
2306
|
+
// see #21
|
|
2307
|
+
// 'SIGPROF'
|
|
2308
|
+
);
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
if (process.platform === 'linux') {
|
|
2312
|
+
module.exports.push(
|
|
2313
|
+
'SIGIO',
|
|
2314
|
+
'SIGPOLL',
|
|
2315
|
+
'SIGPWR',
|
|
2316
|
+
'SIGSTKFLT',
|
|
2317
|
+
'SIGUNUSED'
|
|
2318
|
+
);
|
|
2319
|
+
}
|
|
2320
|
+
}(signals$1));
|
|
2321
|
+
|
|
2322
|
+
// Note: since nyc uses this module to output coverage, any lines
|
|
2323
|
+
// that are in the direct sync flow of nyc's outputCoverage are
|
|
2324
|
+
// ignored, since we can never get coverage for them.
|
|
2325
|
+
// grab a reference to node's real process object right away
|
|
2326
|
+
var process$1 = commonjsGlobal.process;
|
|
2327
|
+
|
|
2328
|
+
const processOk = function (process) {
|
|
2329
|
+
return process &&
|
|
2330
|
+
typeof process === 'object' &&
|
|
2331
|
+
typeof process.removeListener === 'function' &&
|
|
2332
|
+
typeof process.emit === 'function' &&
|
|
2333
|
+
typeof process.reallyExit === 'function' &&
|
|
2334
|
+
typeof process.listeners === 'function' &&
|
|
2335
|
+
typeof process.kill === 'function' &&
|
|
2336
|
+
typeof process.pid === 'number' &&
|
|
2337
|
+
typeof process.on === 'function'
|
|
2338
|
+
};
|
|
2339
|
+
|
|
2340
|
+
// some kind of non-node environment, just no-op
|
|
2341
|
+
/* istanbul ignore if */
|
|
2342
|
+
if (!processOk(process$1)) {
|
|
2343
|
+
signalExit$1.exports = function () {};
|
|
2344
|
+
} else {
|
|
2345
|
+
var assert = require$$0$1;
|
|
2346
|
+
var signals = signals$1.exports;
|
|
2347
|
+
var isWin = /^win/i.test(process$1.platform);
|
|
2348
|
+
|
|
2349
|
+
var EE = require$$2;
|
|
2350
|
+
/* istanbul ignore if */
|
|
2351
|
+
if (typeof EE !== 'function') {
|
|
2352
|
+
EE = EE.EventEmitter;
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
var emitter;
|
|
2356
|
+
if (process$1.__signal_exit_emitter__) {
|
|
2357
|
+
emitter = process$1.__signal_exit_emitter__;
|
|
2358
|
+
} else {
|
|
2359
|
+
emitter = process$1.__signal_exit_emitter__ = new EE();
|
|
2360
|
+
emitter.count = 0;
|
|
2361
|
+
emitter.emitted = {};
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
// Because this emitter is a global, we have to check to see if a
|
|
2365
|
+
// previous version of this library failed to enable infinite listeners.
|
|
2366
|
+
// I know what you're about to say. But literally everything about
|
|
2367
|
+
// signal-exit is a compromise with evil. Get used to it.
|
|
2368
|
+
if (!emitter.infinite) {
|
|
2369
|
+
emitter.setMaxListeners(Infinity);
|
|
2370
|
+
emitter.infinite = true;
|
|
2371
|
+
}
|
|
2372
|
+
|
|
2373
|
+
signalExit$1.exports = function (cb, opts) {
|
|
2374
|
+
/* istanbul ignore if */
|
|
2375
|
+
if (!processOk(commonjsGlobal.process)) {
|
|
2376
|
+
return
|
|
2377
|
+
}
|
|
2378
|
+
assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler');
|
|
2379
|
+
|
|
2380
|
+
if (loaded === false) {
|
|
2381
|
+
load();
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
var ev = 'exit';
|
|
2385
|
+
if (opts && opts.alwaysLast) {
|
|
2386
|
+
ev = 'afterexit';
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
var remove = function () {
|
|
2390
|
+
emitter.removeListener(ev, cb);
|
|
2391
|
+
if (emitter.listeners('exit').length === 0 &&
|
|
2392
|
+
emitter.listeners('afterexit').length === 0) {
|
|
2393
|
+
unload();
|
|
2394
|
+
}
|
|
2395
|
+
};
|
|
2396
|
+
emitter.on(ev, cb);
|
|
2397
|
+
|
|
2398
|
+
return remove
|
|
2399
|
+
};
|
|
2400
|
+
|
|
2401
|
+
var unload = function unload () {
|
|
2402
|
+
if (!loaded || !processOk(commonjsGlobal.process)) {
|
|
2403
|
+
return
|
|
2404
|
+
}
|
|
2405
|
+
loaded = false;
|
|
2406
|
+
|
|
2407
|
+
signals.forEach(function (sig) {
|
|
2408
|
+
try {
|
|
2409
|
+
process$1.removeListener(sig, sigListeners[sig]);
|
|
2410
|
+
} catch (er) {}
|
|
2411
|
+
});
|
|
2412
|
+
process$1.emit = originalProcessEmit;
|
|
2413
|
+
process$1.reallyExit = originalProcessReallyExit;
|
|
2414
|
+
emitter.count -= 1;
|
|
2415
|
+
};
|
|
2416
|
+
signalExit$1.exports.unload = unload;
|
|
2417
|
+
|
|
2418
|
+
var emit = function emit (event, code, signal) {
|
|
2419
|
+
/* istanbul ignore if */
|
|
2420
|
+
if (emitter.emitted[event]) {
|
|
2421
|
+
return
|
|
2422
|
+
}
|
|
2423
|
+
emitter.emitted[event] = true;
|
|
2424
|
+
emitter.emit(event, code, signal);
|
|
2425
|
+
};
|
|
2426
|
+
|
|
2427
|
+
// { <signal>: <listener fn>, ... }
|
|
2428
|
+
var sigListeners = {};
|
|
2429
|
+
signals.forEach(function (sig) {
|
|
2430
|
+
sigListeners[sig] = function listener () {
|
|
2431
|
+
/* istanbul ignore if */
|
|
2432
|
+
if (!processOk(commonjsGlobal.process)) {
|
|
2433
|
+
return
|
|
2434
|
+
}
|
|
2435
|
+
// If there are no other listeners, an exit is coming!
|
|
2436
|
+
// Simplest way: remove us and then re-send the signal.
|
|
2437
|
+
// We know that this will kill the process, so we can
|
|
2438
|
+
// safely emit now.
|
|
2439
|
+
var listeners = process$1.listeners(sig);
|
|
2440
|
+
if (listeners.length === emitter.count) {
|
|
2441
|
+
unload();
|
|
2442
|
+
emit('exit', null, sig);
|
|
2443
|
+
/* istanbul ignore next */
|
|
2444
|
+
emit('afterexit', null, sig);
|
|
2445
|
+
/* istanbul ignore next */
|
|
2446
|
+
if (isWin && sig === 'SIGHUP') {
|
|
2447
|
+
// "SIGHUP" throws an `ENOSYS` error on Windows,
|
|
2448
|
+
// so use a supported signal instead
|
|
2449
|
+
sig = 'SIGINT';
|
|
2450
|
+
}
|
|
2451
|
+
/* istanbul ignore next */
|
|
2452
|
+
process$1.kill(process$1.pid, sig);
|
|
2453
|
+
}
|
|
2454
|
+
};
|
|
2455
|
+
});
|
|
2456
|
+
|
|
2457
|
+
signalExit$1.exports.signals = function () {
|
|
2458
|
+
return signals
|
|
2459
|
+
};
|
|
2460
|
+
|
|
2461
|
+
var loaded = false;
|
|
2462
|
+
|
|
2463
|
+
var load = function load () {
|
|
2464
|
+
if (loaded || !processOk(commonjsGlobal.process)) {
|
|
2465
|
+
return
|
|
2466
|
+
}
|
|
2467
|
+
loaded = true;
|
|
2468
|
+
|
|
2469
|
+
// This is the number of onSignalExit's that are in play.
|
|
2470
|
+
// It's important so that we can count the correct number of
|
|
2471
|
+
// listeners on signals, and don't wait for the other one to
|
|
2472
|
+
// handle it instead of us.
|
|
2473
|
+
emitter.count += 1;
|
|
2474
|
+
|
|
2475
|
+
signals = signals.filter(function (sig) {
|
|
2476
|
+
try {
|
|
2477
|
+
process$1.on(sig, sigListeners[sig]);
|
|
2478
|
+
return true
|
|
2479
|
+
} catch (er) {
|
|
2480
|
+
return false
|
|
2481
|
+
}
|
|
2482
|
+
});
|
|
2483
|
+
|
|
2484
|
+
process$1.emit = processEmit;
|
|
2485
|
+
process$1.reallyExit = processReallyExit;
|
|
2486
|
+
};
|
|
2487
|
+
signalExit$1.exports.load = load;
|
|
2488
|
+
|
|
2489
|
+
var originalProcessReallyExit = process$1.reallyExit;
|
|
2490
|
+
var processReallyExit = function processReallyExit (code) {
|
|
2491
|
+
/* istanbul ignore if */
|
|
2492
|
+
if (!processOk(commonjsGlobal.process)) {
|
|
2493
|
+
return
|
|
2494
|
+
}
|
|
2495
|
+
process$1.exitCode = code || /* istanbul ignore next */ 0;
|
|
2496
|
+
emit('exit', process$1.exitCode, null);
|
|
2497
|
+
/* istanbul ignore next */
|
|
2498
|
+
emit('afterexit', process$1.exitCode, null);
|
|
2499
|
+
/* istanbul ignore next */
|
|
2500
|
+
originalProcessReallyExit.call(process$1, process$1.exitCode);
|
|
2501
|
+
};
|
|
2502
|
+
|
|
2503
|
+
var originalProcessEmit = process$1.emit;
|
|
2504
|
+
var processEmit = function processEmit (ev, arg) {
|
|
2505
|
+
if (ev === 'exit' && processOk(commonjsGlobal.process)) {
|
|
2506
|
+
/* istanbul ignore else */
|
|
2507
|
+
if (arg !== undefined) {
|
|
2508
|
+
process$1.exitCode = arg;
|
|
2509
|
+
}
|
|
2510
|
+
var ret = originalProcessEmit.apply(this, arguments);
|
|
2511
|
+
/* istanbul ignore next */
|
|
2512
|
+
emit('exit', process$1.exitCode, null);
|
|
2513
|
+
/* istanbul ignore next */
|
|
2514
|
+
emit('afterexit', process$1.exitCode, null);
|
|
2515
|
+
/* istanbul ignore next */
|
|
2516
|
+
return ret
|
|
2517
|
+
} else {
|
|
2518
|
+
return originalProcessEmit.apply(this, arguments)
|
|
2519
|
+
}
|
|
2520
|
+
};
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
var signalExit = signalExit$1.exports;
|
|
2524
|
+
|
|
2525
|
+
const restoreCursor = onetime$1(() => {
|
|
2526
|
+
signalExit(() => {
|
|
2527
|
+
process$2.stderr.write('\u001B[?25h');
|
|
2528
|
+
}, {alwaysLast: true});
|
|
2529
|
+
});
|
|
2530
|
+
|
|
2531
|
+
let isHidden = false;
|
|
2532
|
+
|
|
2533
|
+
const cliCursor = {};
|
|
2534
|
+
|
|
2535
|
+
cliCursor.show = (writableStream = process$2.stderr) => {
|
|
2536
|
+
if (!writableStream.isTTY) {
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
isHidden = false;
|
|
2541
|
+
writableStream.write('\u001B[?25h');
|
|
2542
|
+
};
|
|
2543
|
+
|
|
2544
|
+
cliCursor.hide = (writableStream = process$2.stderr) => {
|
|
2545
|
+
if (!writableStream.isTTY) {
|
|
2546
|
+
return;
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
restoreCursor();
|
|
2550
|
+
isHidden = true;
|
|
2551
|
+
writableStream.write('\u001B[?25l');
|
|
2552
|
+
};
|
|
2553
|
+
|
|
2554
|
+
cliCursor.toggle = (force, writableStream) => {
|
|
2555
|
+
if (force !== undefined) {
|
|
2556
|
+
isHidden = force;
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2559
|
+
if (isHidden) {
|
|
2560
|
+
cliCursor.show(writableStream);
|
|
2561
|
+
} else {
|
|
2562
|
+
cliCursor.hide(writableStream);
|
|
2563
|
+
}
|
|
2564
|
+
};
|
|
2565
|
+
|
|
2566
|
+
const ESCAPES = new Set([
|
|
2567
|
+
'\u001B',
|
|
2568
|
+
'\u009B',
|
|
2569
|
+
]);
|
|
2570
|
+
|
|
2571
|
+
const END_CODE = 39;
|
|
2572
|
+
const ANSI_ESCAPE_BELL = '\u0007';
|
|
2573
|
+
const ANSI_CSI = '[';
|
|
2574
|
+
const ANSI_OSC = ']';
|
|
2575
|
+
const ANSI_SGR_TERMINATOR = 'm';
|
|
2576
|
+
const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
2577
|
+
|
|
2578
|
+
const wrapAnsiCode = code => `${ESCAPES.values().next().value}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
2579
|
+
const wrapAnsiHyperlink = uri => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${uri}${ANSI_ESCAPE_BELL}`;
|
|
2580
|
+
|
|
2581
|
+
// Calculate the length of words split on ' ', ignoring
|
|
2582
|
+
// the extra characters added by ansi escape codes
|
|
2583
|
+
const wordLengths = string => string.split(' ').map(character => stringWidth(character));
|
|
2584
|
+
|
|
2585
|
+
// Wrap a long word across multiple rows
|
|
2586
|
+
// Ansi escape codes do not count towards length
|
|
2587
|
+
const wrapWord = (rows, word, columns) => {
|
|
2588
|
+
const characters = [...word];
|
|
2589
|
+
|
|
2590
|
+
let isInsideEscape = false;
|
|
2591
|
+
let isInsideLinkEscape = false;
|
|
2592
|
+
let visible = stringWidth(stripAnsi(rows[rows.length - 1]));
|
|
2593
|
+
|
|
2594
|
+
for (const [index, character] of characters.entries()) {
|
|
2595
|
+
const characterLength = stringWidth(character);
|
|
2596
|
+
|
|
2597
|
+
if (visible + characterLength <= columns) {
|
|
2598
|
+
rows[rows.length - 1] += character;
|
|
2599
|
+
} else {
|
|
2600
|
+
rows.push(character);
|
|
2601
|
+
visible = 0;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
if (ESCAPES.has(character)) {
|
|
2605
|
+
isInsideEscape = true;
|
|
2606
|
+
isInsideLinkEscape = characters.slice(index + 1).join('').startsWith(ANSI_ESCAPE_LINK);
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
if (isInsideEscape) {
|
|
2610
|
+
if (isInsideLinkEscape) {
|
|
2611
|
+
if (character === ANSI_ESCAPE_BELL) {
|
|
2612
|
+
isInsideEscape = false;
|
|
2613
|
+
isInsideLinkEscape = false;
|
|
2614
|
+
}
|
|
2615
|
+
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
2616
|
+
isInsideEscape = false;
|
|
2617
|
+
}
|
|
2618
|
+
|
|
2619
|
+
continue;
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
visible += characterLength;
|
|
2623
|
+
|
|
2624
|
+
if (visible === columns && index < characters.length - 1) {
|
|
2625
|
+
rows.push('');
|
|
2626
|
+
visible = 0;
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
// It's possible that the last row we copy over is only
|
|
2631
|
+
// ansi escape characters, handle this edge-case
|
|
2632
|
+
if (!visible && rows[rows.length - 1].length > 0 && rows.length > 1) {
|
|
2633
|
+
rows[rows.length - 2] += rows.pop();
|
|
2634
|
+
}
|
|
2635
|
+
};
|
|
2636
|
+
|
|
2637
|
+
// Trims spaces from a string ignoring invisible sequences
|
|
2638
|
+
const stringVisibleTrimSpacesRight = string => {
|
|
2639
|
+
const words = string.split(' ');
|
|
2640
|
+
let last = words.length;
|
|
2641
|
+
|
|
2642
|
+
while (last > 0) {
|
|
2643
|
+
if (stringWidth(words[last - 1]) > 0) {
|
|
2644
|
+
break;
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
last--;
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
if (last === words.length) {
|
|
2651
|
+
return string;
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
return words.slice(0, last).join(' ') + words.slice(last).join('');
|
|
2655
|
+
};
|
|
2656
|
+
|
|
2657
|
+
// The wrap-ansi module can be invoked in either 'hard' or 'soft' wrap mode
|
|
2658
|
+
//
|
|
2659
|
+
// 'hard' will never allow a string to take up more than columns characters
|
|
2660
|
+
//
|
|
2661
|
+
// 'soft' allows long words to expand past the column length
|
|
2662
|
+
const exec = (string, columns, options = {}) => {
|
|
2663
|
+
if (options.trim !== false && string.trim() === '') {
|
|
2664
|
+
return '';
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
let returnValue = '';
|
|
2668
|
+
let escapeCode;
|
|
2669
|
+
let escapeUrl;
|
|
2670
|
+
|
|
2671
|
+
const lengths = wordLengths(string);
|
|
2672
|
+
let rows = [''];
|
|
2673
|
+
|
|
2674
|
+
for (const [index, word] of string.split(' ').entries()) {
|
|
2675
|
+
if (options.trim !== false) {
|
|
2676
|
+
rows[rows.length - 1] = rows[rows.length - 1].trimStart();
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
let rowLength = stringWidth(rows[rows.length - 1]);
|
|
2680
|
+
|
|
2681
|
+
if (index !== 0) {
|
|
2682
|
+
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
2683
|
+
// If we start with a new word but the current row length equals the length of the columns, add a new row
|
|
2684
|
+
rows.push('');
|
|
2685
|
+
rowLength = 0;
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
if (rowLength > 0 || options.trim === false) {
|
|
2689
|
+
rows[rows.length - 1] += ' ';
|
|
2690
|
+
rowLength++;
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
|
|
2694
|
+
// In 'hard' wrap mode, the length of a line is never allowed to extend past 'columns'
|
|
2695
|
+
if (options.hard && lengths[index] > columns) {
|
|
2696
|
+
const remainingColumns = (columns - rowLength);
|
|
2697
|
+
const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns);
|
|
2698
|
+
const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns);
|
|
2699
|
+
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
2700
|
+
rows.push('');
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
wrapWord(rows, word, columns);
|
|
2704
|
+
continue;
|
|
2705
|
+
}
|
|
2706
|
+
|
|
2707
|
+
if (rowLength + lengths[index] > columns && rowLength > 0 && lengths[index] > 0) {
|
|
2708
|
+
if (options.wordWrap === false && rowLength < columns) {
|
|
2709
|
+
wrapWord(rows, word, columns);
|
|
2710
|
+
continue;
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
rows.push('');
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
if (rowLength + lengths[index] > columns && options.wordWrap === false) {
|
|
2717
|
+
wrapWord(rows, word, columns);
|
|
2718
|
+
continue;
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
rows[rows.length - 1] += word;
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
if (options.trim !== false) {
|
|
2725
|
+
rows = rows.map(row => stringVisibleTrimSpacesRight(row));
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
const pre = [...rows.join('\n')];
|
|
2729
|
+
|
|
2730
|
+
for (const [index, character] of pre.entries()) {
|
|
2731
|
+
returnValue += character;
|
|
2732
|
+
|
|
2733
|
+
if (ESCAPES.has(character)) {
|
|
2734
|
+
const {groups} = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(pre.slice(index).join('')) || {groups: {}};
|
|
2735
|
+
if (groups.code !== undefined) {
|
|
2736
|
+
const code = Number.parseFloat(groups.code);
|
|
2737
|
+
escapeCode = code === END_CODE ? undefined : code;
|
|
2738
|
+
} else if (groups.uri !== undefined) {
|
|
2739
|
+
escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
const code = ansiStyles.codes.get(Number(escapeCode));
|
|
2744
|
+
|
|
2745
|
+
if (pre[index + 1] === '\n') {
|
|
2746
|
+
if (escapeUrl) {
|
|
2747
|
+
returnValue += wrapAnsiHyperlink('');
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
if (escapeCode && code) {
|
|
2751
|
+
returnValue += wrapAnsiCode(code);
|
|
2752
|
+
}
|
|
2753
|
+
} else if (character === '\n') {
|
|
2754
|
+
if (escapeCode && code) {
|
|
2755
|
+
returnValue += wrapAnsiCode(escapeCode);
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
if (escapeUrl) {
|
|
2759
|
+
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
return returnValue;
|
|
2765
|
+
};
|
|
2766
|
+
|
|
2767
|
+
// For each newline, invoke the method separately
|
|
2768
|
+
function wrapAnsi(string, columns, options) {
|
|
2769
|
+
return String(string)
|
|
2770
|
+
.normalize()
|
|
2771
|
+
.replace(/\r\n/g, '\n')
|
|
2772
|
+
.split('\n')
|
|
2773
|
+
.map(line => exec(line, columns, options))
|
|
2774
|
+
.join('\n');
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
const defaultTerminalHeight = 24;
|
|
2778
|
+
|
|
2779
|
+
const getWidth = stream => {
|
|
2780
|
+
const {columns} = stream;
|
|
2781
|
+
|
|
2782
|
+
if (!columns) {
|
|
2783
|
+
return 80;
|
|
2784
|
+
}
|
|
2785
|
+
|
|
2786
|
+
return columns;
|
|
2787
|
+
};
|
|
2788
|
+
|
|
2789
|
+
const fitToTerminalHeight = (stream, text) => {
|
|
2790
|
+
const terminalHeight = stream.rows || defaultTerminalHeight;
|
|
2791
|
+
const lines = text.split('\n');
|
|
2792
|
+
|
|
2793
|
+
const toRemove = lines.length - terminalHeight;
|
|
2794
|
+
if (toRemove <= 0) {
|
|
2795
|
+
return text;
|
|
2796
|
+
}
|
|
2797
|
+
|
|
2798
|
+
return sliceAnsi(
|
|
2799
|
+
text,
|
|
2800
|
+
lines.slice(0, toRemove).join('\n').length + 1,
|
|
2801
|
+
text.length);
|
|
2802
|
+
};
|
|
2803
|
+
|
|
2804
|
+
function createLogUpdate(stream, {showCursor = false} = {}) {
|
|
2805
|
+
let previousLineCount = 0;
|
|
2806
|
+
let previousWidth = getWidth(stream);
|
|
2807
|
+
let previousOutput = '';
|
|
2808
|
+
|
|
2809
|
+
const render = (...arguments_) => {
|
|
2810
|
+
if (!showCursor) {
|
|
2811
|
+
cliCursor.hide();
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
let output = arguments_.join(' ') + '\n';
|
|
2815
|
+
output = fitToTerminalHeight(stream, output);
|
|
2816
|
+
const width = getWidth(stream);
|
|
2817
|
+
if (output === previousOutput && previousWidth === width) {
|
|
2818
|
+
return;
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
previousOutput = output;
|
|
2822
|
+
previousWidth = width;
|
|
2823
|
+
output = wrapAnsi(output, width, {
|
|
2824
|
+
trim: false,
|
|
2825
|
+
hard: true,
|
|
2826
|
+
wordWrap: false,
|
|
2827
|
+
});
|
|
2828
|
+
stream.write(ansiEscapes.eraseLines(previousLineCount) + output);
|
|
2829
|
+
previousLineCount = output.split('\n').length;
|
|
2830
|
+
};
|
|
2831
|
+
|
|
2832
|
+
render.clear = () => {
|
|
2833
|
+
stream.write(ansiEscapes.eraseLines(previousLineCount));
|
|
2834
|
+
previousOutput = '';
|
|
2835
|
+
previousWidth = getWidth(stream);
|
|
2836
|
+
previousLineCount = 0;
|
|
2837
|
+
};
|
|
2838
|
+
|
|
2839
|
+
render.done = () => {
|
|
2840
|
+
previousOutput = '';
|
|
2841
|
+
previousWidth = getWidth(stream);
|
|
2842
|
+
previousLineCount = 0;
|
|
2843
|
+
|
|
2844
|
+
if (!showCursor) {
|
|
2845
|
+
cliCursor.show();
|
|
2846
|
+
}
|
|
2847
|
+
};
|
|
2848
|
+
|
|
2849
|
+
return render;
|
|
2850
|
+
}
|
|
2851
|
+
|
|
2852
|
+
createLogUpdate(process$2.stdout);
|
|
2853
|
+
|
|
2854
|
+
createLogUpdate(process$2.stderr);
|
|
2855
|
+
|
|
2856
|
+
const DURATION_LONG = 300;
|
|
2857
|
+
const MAX_HEIGHT = 20;
|
|
2858
|
+
const spinnerMap = new WeakMap();
|
|
2859
|
+
const outputMap = new WeakMap();
|
|
2860
|
+
const pointer = c.yellow(F_POINTER);
|
|
2861
|
+
const skipped = c.yellow(F_DOWN);
|
|
2862
|
+
function formatTestPath(root, path) {
|
|
2863
|
+
var _a;
|
|
2864
|
+
if (isAbsolute(path))
|
|
2865
|
+
path = relative(root, path);
|
|
2866
|
+
const dir = dirname(path);
|
|
2867
|
+
const ext = ((_a = path.match(/(\.(spec|test)\.[cm]?[tj]sx?)$/)) == null ? void 0 : _a[0]) || "";
|
|
2868
|
+
const base = basename(path, ext);
|
|
2869
|
+
return slash(c.dim(`${dir}/`) + c.bold(base)) + c.dim(ext);
|
|
2870
|
+
}
|
|
2871
|
+
function renderSnapshotSummary(rootDir, snapshots) {
|
|
2872
|
+
const summary = [];
|
|
2873
|
+
if (snapshots.added)
|
|
2874
|
+
summary.push(c.bold(c.green(`${snapshots.added} written`)));
|
|
2875
|
+
if (snapshots.unmatched)
|
|
2876
|
+
summary.push(c.bold(c.red(`${snapshots.unmatched} failed`)));
|
|
2877
|
+
if (snapshots.updated)
|
|
2878
|
+
summary.push(c.bold(c.green(`${snapshots.updated} updated `)));
|
|
2879
|
+
if (snapshots.filesRemoved) {
|
|
2880
|
+
if (snapshots.didUpdate)
|
|
2881
|
+
summary.push(c.bold(c.green(`${snapshots.filesRemoved} files removed `)));
|
|
2882
|
+
else
|
|
2883
|
+
summary.push(c.bold(c.yellow(`${snapshots.filesRemoved} files obsolete `)));
|
|
2884
|
+
}
|
|
2885
|
+
if (snapshots.filesRemovedList && snapshots.filesRemovedList.length) {
|
|
2886
|
+
const [head, ...tail] = snapshots.filesRemovedList;
|
|
2887
|
+
summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, head)}`);
|
|
2888
|
+
tail.forEach((key) => {
|
|
2889
|
+
summary.push(` ${c.gray(F_DOT)} ${formatTestPath(rootDir, key)}`);
|
|
2890
|
+
});
|
|
2891
|
+
}
|
|
2892
|
+
if (snapshots.unchecked) {
|
|
2893
|
+
if (snapshots.didUpdate)
|
|
2894
|
+
summary.push(c.bold(c.green(`${snapshots.unchecked} removed`)));
|
|
2895
|
+
else
|
|
2896
|
+
summary.push(c.bold(c.yellow(`${snapshots.unchecked} obsolete`)));
|
|
2897
|
+
snapshots.uncheckedKeysByFile.forEach((uncheckedFile) => {
|
|
2898
|
+
summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, uncheckedFile.filePath)}`);
|
|
2899
|
+
uncheckedFile.keys.forEach((key) => summary.push(` ${c.gray(F_DOT)} ${key}`));
|
|
2900
|
+
});
|
|
2901
|
+
}
|
|
2902
|
+
return summary;
|
|
2903
|
+
}
|
|
2904
|
+
function getStateString(tasks, name = "tests") {
|
|
2905
|
+
if (tasks.length === 0)
|
|
2906
|
+
return c.dim(`no ${name}`);
|
|
2907
|
+
const passed = tasks.filter((i) => {
|
|
2908
|
+
var _a;
|
|
2909
|
+
return ((_a = i.result) == null ? void 0 : _a.state) === "pass";
|
|
2910
|
+
});
|
|
2911
|
+
const failed = tasks.filter((i) => {
|
|
2912
|
+
var _a;
|
|
2913
|
+
return ((_a = i.result) == null ? void 0 : _a.state) === "fail";
|
|
2914
|
+
});
|
|
2915
|
+
const skipped2 = tasks.filter((i) => i.mode === "skip");
|
|
2916
|
+
const todo = tasks.filter((i) => i.mode === "todo");
|
|
2917
|
+
return [
|
|
2918
|
+
failed.length ? c.bold(c.red(`${failed.length} failed`)) : null,
|
|
2919
|
+
passed.length ? c.bold(c.green(`${passed.length} passed`)) : null,
|
|
2920
|
+
skipped2.length ? c.yellow(`${skipped2.length} skipped`) : null,
|
|
2921
|
+
todo.length ? c.gray(`${todo.length} todo`) : null
|
|
2922
|
+
].filter(Boolean).join(c.dim(" | ")) + c.gray(` (${tasks.length})`);
|
|
2923
|
+
}
|
|
2924
|
+
function getStateSymbol(task) {
|
|
2925
|
+
if (task.mode === "skip" || task.mode === "todo")
|
|
2926
|
+
return skipped;
|
|
2927
|
+
if (!task.result)
|
|
2928
|
+
return c.gray("\xB7");
|
|
2929
|
+
if (task.result.state === "run") {
|
|
2930
|
+
if (task.type === "suite")
|
|
2931
|
+
return pointer;
|
|
2932
|
+
let spinner = spinnerMap.get(task);
|
|
2933
|
+
if (!spinner) {
|
|
2934
|
+
spinner = elegantSpinner();
|
|
2935
|
+
spinnerMap.set(task, spinner);
|
|
2936
|
+
}
|
|
2937
|
+
return c.yellow(spinner());
|
|
2938
|
+
}
|
|
2939
|
+
if (task.result.state === "pass")
|
|
2940
|
+
return c.green(F_CHECK);
|
|
2941
|
+
if (task.result.state === "fail") {
|
|
2942
|
+
return task.type === "suite" ? pointer : c.red(F_CROSS);
|
|
2943
|
+
}
|
|
2944
|
+
return " ";
|
|
2945
|
+
}
|
|
2946
|
+
function renderTree(tasks, level = 0) {
|
|
2947
|
+
var _a, _b, _c, _d;
|
|
2948
|
+
let output = [];
|
|
2949
|
+
for (const task of tasks) {
|
|
2950
|
+
let delta = 1;
|
|
2951
|
+
let suffix = task.mode === "skip" || task.mode === "todo" ? ` ${c.dim("[skipped]")}` : "";
|
|
2952
|
+
const prefix = ` ${getStateSymbol(task)} `;
|
|
2953
|
+
if (task.type === "suite")
|
|
2954
|
+
suffix += c.dim(` (${getTests(task).length})`);
|
|
2955
|
+
if ((_a = task.result) == null ? void 0 : _a.end) {
|
|
2956
|
+
const duration = task.result.end - task.result.start;
|
|
2957
|
+
if (duration > DURATION_LONG)
|
|
2958
|
+
suffix += c.yellow(` ${Math.round(duration)}${c.dim("ms")}`);
|
|
2959
|
+
}
|
|
2960
|
+
if (task.name)
|
|
2961
|
+
output.push(" ".repeat(level) + prefix + task.name + suffix);
|
|
2962
|
+
else
|
|
2963
|
+
delta = 0;
|
|
2964
|
+
if (((_b = task.result) == null ? void 0 : _b.state) !== "pass" && outputMap.get(task) != null) {
|
|
2965
|
+
let data = outputMap.get(task);
|
|
2966
|
+
if (typeof data === "string") {
|
|
2967
|
+
data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
|
|
2968
|
+
if (data === "")
|
|
2969
|
+
data = void 0;
|
|
2970
|
+
}
|
|
2971
|
+
if (data != null) {
|
|
2972
|
+
const out = `${" ".repeat(level)}${F_RIGHT} ${data}`;
|
|
2973
|
+
output.push(` ${c.gray(cliTruncate(out, process.stdout.columns - 3))}`);
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
if ((((_c = task.result) == null ? void 0 : _c.state) === "fail" || ((_d = task.result) == null ? void 0 : _d.state) === "run") && task.type === "suite" && task.tasks.length > 0)
|
|
2977
|
+
output = output.concat(renderTree(task.tasks, level + delta));
|
|
2978
|
+
}
|
|
2979
|
+
return output.slice(0, MAX_HEIGHT).join("\n");
|
|
2980
|
+
}
|
|
2981
|
+
const createRenderer = (_tasks) => {
|
|
2982
|
+
let tasks = _tasks;
|
|
2983
|
+
let timer;
|
|
2984
|
+
const log = createLogUpdate(process.stdout);
|
|
2985
|
+
function update() {
|
|
2986
|
+
log(renderTree(tasks));
|
|
2987
|
+
}
|
|
2988
|
+
return {
|
|
2989
|
+
start() {
|
|
2990
|
+
if (timer)
|
|
2991
|
+
return this;
|
|
2992
|
+
timer = setInterval(update, 200);
|
|
2993
|
+
return this;
|
|
2994
|
+
},
|
|
2995
|
+
update(_tasks2) {
|
|
2996
|
+
tasks = _tasks2;
|
|
2997
|
+
update();
|
|
2998
|
+
return this;
|
|
2999
|
+
},
|
|
3000
|
+
async stop() {
|
|
3001
|
+
if (timer) {
|
|
3002
|
+
clearInterval(timer);
|
|
3003
|
+
timer = void 0;
|
|
3004
|
+
}
|
|
3005
|
+
log.clear();
|
|
3006
|
+
console.log(renderTree(tasks));
|
|
3007
|
+
return this;
|
|
3008
|
+
}
|
|
3009
|
+
};
|
|
3010
|
+
};
|
|
3011
|
+
function getFullName(task) {
|
|
3012
|
+
return getNames(task).join(c.gray(" > "));
|
|
3013
|
+
}
|
|
3014
|
+
const spinnerFrames = process.platform === "win32" ? ["-", "\\", "|", "/"] : ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
3015
|
+
function elegantSpinner() {
|
|
3016
|
+
let index = 0;
|
|
3017
|
+
return () => {
|
|
3018
|
+
index = ++index % spinnerFrames.length;
|
|
3019
|
+
return spinnerFrames[index];
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
const isTTY = process.stdout.isTTY && !process.env.CI;
|
|
3024
|
+
class DefaultReporter {
|
|
3025
|
+
constructor(ctx) {
|
|
3026
|
+
this.ctx = ctx;
|
|
3027
|
+
this.start = 0;
|
|
3028
|
+
this.end = 0;
|
|
3029
|
+
const mode = ctx.config.watch ? c.yellow(" DEV ") : c.cyan(" RUN ");
|
|
3030
|
+
console.log(`${c.inverse(c.bold(mode))} ${c.gray(this.ctx.config.root)}
|
|
3031
|
+
`);
|
|
3032
|
+
this.start = performance.now();
|
|
3033
|
+
}
|
|
3034
|
+
relative(path) {
|
|
3035
|
+
return relative(this.ctx.config.root, path);
|
|
3036
|
+
}
|
|
3037
|
+
onStart() {
|
|
3038
|
+
if (isTTY) {
|
|
3039
|
+
const files = this.ctx.state.getFiles(this.watchFilters);
|
|
3040
|
+
if (!this.renderer)
|
|
3041
|
+
this.renderer = createRenderer(files).start();
|
|
3042
|
+
else
|
|
3043
|
+
this.renderer.update(files);
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
onTaskUpdate(pack) {
|
|
3047
|
+
var _a, _b, _c;
|
|
3048
|
+
if (isTTY)
|
|
3049
|
+
return;
|
|
3050
|
+
const task = this.ctx.state.idMap[pack[0]];
|
|
3051
|
+
if (task.type === "test" && ((_a = task.result) == null ? void 0 : _a.state) && ((_b = task.result) == null ? void 0 : _b.state) !== "run") {
|
|
3052
|
+
console.log(` ${getStateSymbol(task)} ${getFullName(task)}`);
|
|
3053
|
+
if (task.result.state === "fail")
|
|
3054
|
+
console.log(c.red(` ${F_RIGHT} ${(_c = task.result.error) == null ? void 0 : _c.message}`));
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
async onFinished(files = this.ctx.state.getFiles()) {
|
|
3058
|
+
var _a, _b;
|
|
3059
|
+
this.end = performance.now();
|
|
3060
|
+
await this.stopListRender();
|
|
3061
|
+
console.log();
|
|
3062
|
+
const suites = getSuites(files);
|
|
3063
|
+
const tests = getTests(files);
|
|
3064
|
+
const failedSuites = suites.filter((i) => {
|
|
3065
|
+
var _a2;
|
|
3066
|
+
return (_a2 = i.result) == null ? void 0 : _a2.error;
|
|
3067
|
+
});
|
|
3068
|
+
const failedTests = tests.filter((i) => {
|
|
3069
|
+
var _a2;
|
|
3070
|
+
return ((_a2 = i.result) == null ? void 0 : _a2.state) === "fail";
|
|
3071
|
+
});
|
|
3072
|
+
if (failedSuites.length) {
|
|
3073
|
+
console.error(c.bold(c.red(`
|
|
3074
|
+
Failed to run ${failedSuites.length} suites:`)));
|
|
3075
|
+
for (const suite of failedSuites) {
|
|
3076
|
+
console.error(c.red(`
|
|
3077
|
+
- ${getFullName(suite)}`));
|
|
3078
|
+
await printError((_a = suite.result) == null ? void 0 : _a.error);
|
|
3079
|
+
console.log();
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
3082
|
+
if (failedTests.length) {
|
|
3083
|
+
console.error(c.bold(c.red(`
|
|
3084
|
+
Failed Tests (${failedTests.length})`)));
|
|
3085
|
+
for (const test of failedTests) {
|
|
3086
|
+
console.error(`${c.red(`
|
|
3087
|
+
${c.inverse(" FAIL ")}`)} ${getFullName(test)}`);
|
|
3088
|
+
await printError((_b = test.result) == null ? void 0 : _b.error);
|
|
3089
|
+
console.log();
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
const executionTime = this.end - this.start;
|
|
3093
|
+
const threadTime = tests.reduce((acc, test) => {
|
|
3094
|
+
var _a2;
|
|
3095
|
+
return acc + (((_a2 = test.result) == null ? void 0 : _a2.end) ? test.result.end - test.result.start : 0);
|
|
3096
|
+
}, 0);
|
|
3097
|
+
const padTitle = (str) => c.dim(`${str.padStart(10)} `);
|
|
3098
|
+
const time = (time2) => {
|
|
3099
|
+
if (time2 > 1e3)
|
|
3100
|
+
return `${(time2 / 1e3).toFixed(2)}s`;
|
|
3101
|
+
return `${Math.round(time2)}ms`;
|
|
3102
|
+
};
|
|
3103
|
+
const snapshotOutput = renderSnapshotSummary(this.ctx.config.root, this.ctx.snapshot.summary);
|
|
3104
|
+
if (snapshotOutput.length) {
|
|
3105
|
+
console.log(snapshotOutput.map((t, i) => i === 0 ? `${padTitle("Snapshots")} ${t}` : `${padTitle("")} ${t}`).join("\n"));
|
|
3106
|
+
if (snapshotOutput.length > 1)
|
|
3107
|
+
console.log();
|
|
3108
|
+
}
|
|
3109
|
+
console.log(padTitle("Test Files"), getStateString(files));
|
|
3110
|
+
console.log(padTitle("Tests"), getStateString(tests));
|
|
3111
|
+
if (this.watchFilters)
|
|
3112
|
+
console.log(padTitle("Time"), time(threadTime));
|
|
3113
|
+
else
|
|
3114
|
+
console.log(padTitle("Time"), time(executionTime) + c.gray(` (in thread ${time(threadTime)}, ${(executionTime / threadTime * 100).toFixed(2)}%)`));
|
|
3115
|
+
console.log();
|
|
3116
|
+
}
|
|
3117
|
+
async onWatcherStart() {
|
|
3118
|
+
await this.stopListRender();
|
|
3119
|
+
const failed = getTests(this.ctx.state.getFiles()).filter((i) => {
|
|
3120
|
+
var _a;
|
|
3121
|
+
return ((_a = i.result) == null ? void 0 : _a.state) === "fail";
|
|
3122
|
+
});
|
|
3123
|
+
if (failed.length)
|
|
3124
|
+
console.log(`
|
|
3125
|
+
${c.bold(c.inverse(c.red(" FAIL ")))}${c.red(` ${failed.length} tests failed. Watching for file changes...`)}`);
|
|
3126
|
+
else
|
|
3127
|
+
console.log(`
|
|
3128
|
+
${c.bold(c.inverse(c.green(" PASS ")))}${c.green(" Waiting for file changes...")}`);
|
|
3129
|
+
}
|
|
3130
|
+
async onWatcherRerun(files, trigger) {
|
|
3131
|
+
await this.stopListRender();
|
|
3132
|
+
this.watchFilters = files;
|
|
3133
|
+
console.clear();
|
|
3134
|
+
console.log(c.blue("Re-running tests...") + c.dim(` [ ${this.relative(trigger)} ]
|
|
3135
|
+
`));
|
|
3136
|
+
}
|
|
3137
|
+
async stopListRender() {
|
|
3138
|
+
var _a;
|
|
3139
|
+
(_a = this.renderer) == null ? void 0 : _a.stop();
|
|
3140
|
+
this.renderer = void 0;
|
|
3141
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3145
|
+
class SnapshotManager {
|
|
3146
|
+
constructor(config) {
|
|
3147
|
+
this.config = config;
|
|
3148
|
+
this.summary = void 0;
|
|
3149
|
+
this.clear();
|
|
3150
|
+
}
|
|
3151
|
+
clear() {
|
|
3152
|
+
this.summary = emptySummary(this.config.snapshotOptions);
|
|
3153
|
+
}
|
|
3154
|
+
add(result) {
|
|
3155
|
+
addSnapshotResult(this.summary, result);
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
function emptySummary(options) {
|
|
3159
|
+
const summary = {
|
|
3160
|
+
added: 0,
|
|
3161
|
+
failure: false,
|
|
3162
|
+
filesAdded: 0,
|
|
3163
|
+
filesRemoved: 0,
|
|
3164
|
+
filesRemovedList: [],
|
|
3165
|
+
filesUnmatched: 0,
|
|
3166
|
+
filesUpdated: 0,
|
|
3167
|
+
matched: 0,
|
|
3168
|
+
total: 0,
|
|
3169
|
+
unchecked: 0,
|
|
3170
|
+
uncheckedKeysByFile: [],
|
|
3171
|
+
unmatched: 0,
|
|
3172
|
+
updated: 0,
|
|
3173
|
+
didUpdate: options.updateSnapshot === "all"
|
|
3174
|
+
};
|
|
3175
|
+
return summary;
|
|
3176
|
+
}
|
|
3177
|
+
function addSnapshotResult(summary, result) {
|
|
3178
|
+
if (result.added)
|
|
3179
|
+
summary.filesAdded++;
|
|
3180
|
+
if (result.fileDeleted)
|
|
3181
|
+
summary.filesRemoved++;
|
|
3182
|
+
if (result.unmatched)
|
|
3183
|
+
summary.filesUnmatched++;
|
|
3184
|
+
if (result.updated)
|
|
3185
|
+
summary.filesUpdated++;
|
|
3186
|
+
summary.added += result.added;
|
|
3187
|
+
summary.matched += result.matched;
|
|
3188
|
+
summary.unchecked += result.unchecked;
|
|
3189
|
+
if (result.uncheckedKeys && result.uncheckedKeys.length > 0) {
|
|
3190
|
+
summary.uncheckedKeysByFile.push({
|
|
3191
|
+
filePath: result.filepath,
|
|
3192
|
+
keys: result.uncheckedKeys
|
|
3193
|
+
});
|
|
3194
|
+
}
|
|
3195
|
+
summary.unmatched += result.unmatched;
|
|
3196
|
+
summary.updated += result.updated;
|
|
3197
|
+
summary.total += result.added + result.matched + result.unmatched + result.updated;
|
|
3198
|
+
}
|
|
3199
|
+
|
|
3200
|
+
/*
|
|
3201
|
+
How it works:
|
|
3202
|
+
`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.
|
|
3203
|
+
*/
|
|
3204
|
+
|
|
3205
|
+
class Node {
|
|
3206
|
+
value;
|
|
3207
|
+
next;
|
|
3208
|
+
|
|
3209
|
+
constructor(value) {
|
|
3210
|
+
this.value = value;
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
|
|
3214
|
+
class Queue {
|
|
3215
|
+
#head;
|
|
3216
|
+
#tail;
|
|
3217
|
+
#size;
|
|
3218
|
+
|
|
3219
|
+
constructor() {
|
|
3220
|
+
this.clear();
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3223
|
+
enqueue(value) {
|
|
3224
|
+
const node = new Node(value);
|
|
3225
|
+
|
|
3226
|
+
if (this.#head) {
|
|
3227
|
+
this.#tail.next = node;
|
|
3228
|
+
this.#tail = node;
|
|
3229
|
+
} else {
|
|
3230
|
+
this.#head = node;
|
|
3231
|
+
this.#tail = node;
|
|
3232
|
+
}
|
|
3233
|
+
|
|
3234
|
+
this.#size++;
|
|
3235
|
+
}
|
|
3236
|
+
|
|
3237
|
+
dequeue() {
|
|
3238
|
+
const current = this.#head;
|
|
3239
|
+
if (!current) {
|
|
3240
|
+
return;
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
this.#head = this.#head.next;
|
|
3244
|
+
this.#size--;
|
|
3245
|
+
return current.value;
|
|
3246
|
+
}
|
|
3247
|
+
|
|
3248
|
+
clear() {
|
|
3249
|
+
this.#head = undefined;
|
|
3250
|
+
this.#tail = undefined;
|
|
3251
|
+
this.#size = 0;
|
|
3252
|
+
}
|
|
3253
|
+
|
|
3254
|
+
get size() {
|
|
3255
|
+
return this.#size;
|
|
3256
|
+
}
|
|
3257
|
+
|
|
3258
|
+
* [Symbol.iterator]() {
|
|
3259
|
+
let current = this.#head;
|
|
3260
|
+
|
|
3261
|
+
while (current) {
|
|
3262
|
+
yield current.value;
|
|
3263
|
+
current = current.next;
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
function pLimit(concurrency) {
|
|
3269
|
+
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
|
|
3270
|
+
throw new TypeError('Expected `concurrency` to be a number from 1 and up');
|
|
3271
|
+
}
|
|
3272
|
+
|
|
3273
|
+
const queue = new Queue();
|
|
3274
|
+
let activeCount = 0;
|
|
3275
|
+
|
|
3276
|
+
const next = () => {
|
|
3277
|
+
activeCount--;
|
|
3278
|
+
|
|
3279
|
+
if (queue.size > 0) {
|
|
3280
|
+
queue.dequeue()();
|
|
3281
|
+
}
|
|
3282
|
+
};
|
|
3283
|
+
|
|
3284
|
+
const run = async (fn, resolve, args) => {
|
|
3285
|
+
activeCount++;
|
|
3286
|
+
|
|
3287
|
+
const result = (async () => fn(...args))();
|
|
3288
|
+
|
|
3289
|
+
resolve(result);
|
|
3290
|
+
|
|
3291
|
+
try {
|
|
3292
|
+
await result;
|
|
3293
|
+
} catch {}
|
|
3294
|
+
|
|
3295
|
+
next();
|
|
3296
|
+
};
|
|
3297
|
+
|
|
3298
|
+
const enqueue = (fn, resolve, args) => {
|
|
3299
|
+
queue.enqueue(run.bind(undefined, fn, resolve, args));
|
|
3300
|
+
|
|
3301
|
+
(async () => {
|
|
3302
|
+
// This function needs to wait until the next microtask before comparing
|
|
3303
|
+
// `activeCount` to `concurrency`, because `activeCount` is updated asynchronously
|
|
3304
|
+
// when the run function is dequeued and called. The comparison in the if-statement
|
|
3305
|
+
// needs to happen asynchronously as well to get an up-to-date value for `activeCount`.
|
|
3306
|
+
await Promise.resolve();
|
|
3307
|
+
|
|
3308
|
+
if (activeCount < concurrency && queue.size > 0) {
|
|
3309
|
+
queue.dequeue()();
|
|
3310
|
+
}
|
|
3311
|
+
})();
|
|
3312
|
+
};
|
|
3313
|
+
|
|
3314
|
+
const generator = (fn, ...args) => new Promise(resolve => {
|
|
3315
|
+
enqueue(fn, resolve, args);
|
|
3316
|
+
});
|
|
3317
|
+
|
|
3318
|
+
Object.defineProperties(generator, {
|
|
3319
|
+
activeCount: {
|
|
3320
|
+
get: () => activeCount,
|
|
3321
|
+
},
|
|
3322
|
+
pendingCount: {
|
|
3323
|
+
get: () => queue.size,
|
|
3324
|
+
},
|
|
3325
|
+
clearQueue: {
|
|
3326
|
+
value: () => {
|
|
3327
|
+
queue.clear();
|
|
3328
|
+
},
|
|
3329
|
+
},
|
|
3330
|
+
});
|
|
3331
|
+
|
|
3332
|
+
return generator;
|
|
3333
|
+
}
|
|
3334
|
+
|
|
3335
|
+
class EndError extends Error {
|
|
3336
|
+
constructor(value) {
|
|
3337
|
+
super();
|
|
3338
|
+
this.value = value;
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
|
|
3342
|
+
// The input can also be a promise, so we await it.
|
|
3343
|
+
const testElement = async (element, tester) => tester(await element);
|
|
3344
|
+
|
|
3345
|
+
// The input can also be a promise, so we `Promise.all()` them both.
|
|
3346
|
+
const finder = async element => {
|
|
3347
|
+
const values = await Promise.all(element);
|
|
3348
|
+
if (values[1] === true) {
|
|
3349
|
+
throw new EndError(values[0]);
|
|
3350
|
+
}
|
|
3351
|
+
|
|
3352
|
+
return false;
|
|
3353
|
+
};
|
|
3354
|
+
|
|
3355
|
+
async function pLocate(
|
|
3356
|
+
iterable,
|
|
3357
|
+
tester,
|
|
3358
|
+
{
|
|
3359
|
+
concurrency = Number.POSITIVE_INFINITY,
|
|
3360
|
+
preserveOrder = true,
|
|
3361
|
+
} = {},
|
|
3362
|
+
) {
|
|
3363
|
+
const limit = pLimit(concurrency);
|
|
3364
|
+
|
|
3365
|
+
// Start all the promises concurrently with optional limit.
|
|
3366
|
+
const items = [...iterable].map(element => [element, limit(testElement, element, tester)]);
|
|
3367
|
+
|
|
3368
|
+
// Check the promises either serially or concurrently.
|
|
3369
|
+
const checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY);
|
|
3370
|
+
|
|
3371
|
+
try {
|
|
3372
|
+
await Promise.all(items.map(element => checkLimit(finder, element)));
|
|
3373
|
+
} catch (error) {
|
|
3374
|
+
if (error instanceof EndError) {
|
|
3375
|
+
return error.value;
|
|
3376
|
+
}
|
|
3377
|
+
|
|
3378
|
+
throw error;
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3381
|
+
|
|
3382
|
+
const typeMappings = {
|
|
3383
|
+
directory: 'isDirectory',
|
|
3384
|
+
file: 'isFile',
|
|
3385
|
+
};
|
|
3386
|
+
|
|
3387
|
+
function checkType(type) {
|
|
3388
|
+
if (type in typeMappings) {
|
|
3389
|
+
return;
|
|
3390
|
+
}
|
|
3391
|
+
|
|
3392
|
+
throw new Error(`Invalid type specified: ${type}`);
|
|
3393
|
+
}
|
|
3394
|
+
|
|
3395
|
+
const matchType = (type, stat) => type === undefined || stat[typeMappings[type]]();
|
|
3396
|
+
|
|
3397
|
+
async function locatePath(
|
|
3398
|
+
paths,
|
|
3399
|
+
{
|
|
3400
|
+
cwd = process$2.cwd(),
|
|
3401
|
+
type = 'file',
|
|
3402
|
+
allowSymlinks = true,
|
|
3403
|
+
concurrency,
|
|
3404
|
+
preserveOrder,
|
|
3405
|
+
} = {},
|
|
3406
|
+
) {
|
|
3407
|
+
checkType(type);
|
|
3408
|
+
|
|
3409
|
+
const statFunction = allowSymlinks ? promises.stat : promises.lstat;
|
|
3410
|
+
|
|
3411
|
+
return pLocate(paths, async path_ => {
|
|
3412
|
+
try {
|
|
3413
|
+
const stat = await statFunction(path.resolve(cwd, path_));
|
|
3414
|
+
return matchType(type, stat);
|
|
3415
|
+
} catch {
|
|
3416
|
+
return false;
|
|
3417
|
+
}
|
|
3418
|
+
}, {concurrency, preserveOrder});
|
|
3419
|
+
}
|
|
3420
|
+
|
|
3421
|
+
const findUpStop = Symbol('findUpStop');
|
|
3422
|
+
|
|
3423
|
+
async function findUpMultiple(name, options = {}) {
|
|
3424
|
+
let directory = path.resolve(options.cwd || '');
|
|
3425
|
+
const {root} = path.parse(directory);
|
|
3426
|
+
const stopAt = path.resolve(directory, options.stopAt || root);
|
|
3427
|
+
const limit = options.limit || Number.POSITIVE_INFINITY;
|
|
3428
|
+
const paths = [name].flat();
|
|
3429
|
+
|
|
3430
|
+
const runMatcher = async locateOptions => {
|
|
3431
|
+
if (typeof name !== 'function') {
|
|
3432
|
+
return locatePath(paths, locateOptions);
|
|
3433
|
+
}
|
|
3434
|
+
|
|
3435
|
+
const foundPath = await name(locateOptions.cwd);
|
|
3436
|
+
if (typeof foundPath === 'string') {
|
|
3437
|
+
return locatePath([foundPath], locateOptions);
|
|
3438
|
+
}
|
|
3439
|
+
|
|
3440
|
+
return foundPath;
|
|
3441
|
+
};
|
|
3442
|
+
|
|
3443
|
+
const matches = [];
|
|
3444
|
+
// eslint-disable-next-line no-constant-condition
|
|
3445
|
+
while (true) {
|
|
3446
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3447
|
+
const foundPath = await runMatcher({...options, cwd: directory});
|
|
3448
|
+
|
|
3449
|
+
if (foundPath === findUpStop) {
|
|
3450
|
+
break;
|
|
3451
|
+
}
|
|
3452
|
+
|
|
3453
|
+
if (foundPath) {
|
|
3454
|
+
matches.push(path.resolve(directory, foundPath));
|
|
3455
|
+
}
|
|
3456
|
+
|
|
3457
|
+
if (directory === stopAt || matches.length >= limit) {
|
|
3458
|
+
break;
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
directory = path.dirname(directory);
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3464
|
+
return matches;
|
|
3465
|
+
}
|
|
3466
|
+
|
|
3467
|
+
async function findUp(name, options = {}) {
|
|
3468
|
+
const matches = await findUpMultiple(name, {...options, limit: 1});
|
|
3469
|
+
return matches[0];
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3472
|
+
var __defProp$1 = Object.defineProperty;
|
|
3473
|
+
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
3474
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
3475
|
+
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
3476
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3477
|
+
var __spreadValues$1 = (a, b) => {
|
|
3478
|
+
for (var prop in b || (b = {}))
|
|
3479
|
+
if (__hasOwnProp$1.call(b, prop))
|
|
3480
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
3481
|
+
if (__getOwnPropSymbols$1)
|
|
3482
|
+
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
3483
|
+
if (__propIsEnum$1.call(b, prop))
|
|
3484
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
3485
|
+
}
|
|
3486
|
+
return a;
|
|
3487
|
+
};
|
|
3488
|
+
const configFiles = [
|
|
3489
|
+
"vitest.config.ts",
|
|
3490
|
+
"vitest.config.js",
|
|
3491
|
+
"vitest.config.mjs",
|
|
3492
|
+
"vite.config.ts",
|
|
3493
|
+
"vite.config.js",
|
|
3494
|
+
"vite.config.mjs"
|
|
3495
|
+
];
|
|
3496
|
+
async function initViteServer(options = {}) {
|
|
3497
|
+
var _a, _b;
|
|
3498
|
+
const root = resolve(options.root || process.cwd());
|
|
3499
|
+
process.chdir(root);
|
|
3500
|
+
if (options.dom)
|
|
3501
|
+
options.environment = "happy-dom";
|
|
3502
|
+
const configPath = options.config ? resolve(root, options.config) : await findUp(configFiles, { cwd: root });
|
|
3503
|
+
const resolved = __spreadValues$1({}, options);
|
|
3504
|
+
resolved.config = configPath;
|
|
3505
|
+
resolved.root = root;
|
|
3506
|
+
if (options.cliFilters)
|
|
3507
|
+
resolved.cliFilters = toArray(options.cliFilters);
|
|
3508
|
+
const server = await createServer({
|
|
3509
|
+
root,
|
|
3510
|
+
logLevel: "error",
|
|
3511
|
+
clearScreen: false,
|
|
3512
|
+
configFile: resolved.config,
|
|
3513
|
+
optimizeDeps: {
|
|
3514
|
+
exclude: [
|
|
3515
|
+
"vitest"
|
|
3516
|
+
]
|
|
3517
|
+
}
|
|
3518
|
+
});
|
|
3519
|
+
await server.pluginContainer.buildStart({});
|
|
3520
|
+
Object.assign(resolved, server.config.test);
|
|
3521
|
+
resolved.depsInline = ((_a = resolved.deps) == null ? void 0 : _a.inline) || [];
|
|
3522
|
+
resolved.depsExternal = ((_b = resolved.deps) == null ? void 0 : _b.external) || [];
|
|
3523
|
+
resolved.environment = resolved.environment || "node";
|
|
3524
|
+
resolved.threads = resolved.threads ?? true;
|
|
3525
|
+
resolved.interpretDefault = resolved.interpretDefault ?? true;
|
|
3526
|
+
resolved.includes = resolved.includes ?? defaultIncludes;
|
|
3527
|
+
resolved.excludes = resolved.excludes ?? defaultExcludes;
|
|
3528
|
+
const CI = !!process.env.CI;
|
|
3529
|
+
const UPDATE_SNAPSHOT = resolved.update || process.env.UPDATE_SNAPSHOT;
|
|
3530
|
+
resolved.snapshotOptions = {
|
|
3531
|
+
updateSnapshot: CI && !UPDATE_SNAPSHOT ? "none" : UPDATE_SNAPSHOT ? "all" : "new"
|
|
3532
|
+
};
|
|
3533
|
+
if (process.env.VITEST_MAX_THREADS)
|
|
3534
|
+
resolved.maxThreads = parseInt(process.env.VITEST_MAX_THREADS);
|
|
3535
|
+
if (process.env.VITEST_MIN_THREADS)
|
|
3536
|
+
resolved.minThreads = parseInt(process.env.VITEST_MIN_THREADS);
|
|
3537
|
+
return {
|
|
3538
|
+
server,
|
|
3539
|
+
config: resolved
|
|
3540
|
+
};
|
|
3541
|
+
}
|
|
3542
|
+
|
|
3543
|
+
async function transformRequest(server, id) {
|
|
3544
|
+
if (id.match(/\.(?:[cm]?[jt]sx?|json)$/)) {
|
|
3545
|
+
return await server.transformRequest(id, { ssr: true });
|
|
3546
|
+
} else {
|
|
3547
|
+
const result = await server.transformRequest(id);
|
|
3548
|
+
if (!result)
|
|
3549
|
+
return void 0;
|
|
3550
|
+
return await server.ssrTransform(result.code, result.map, id);
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
|
|
3554
|
+
function createPool(ctx) {
|
|
3555
|
+
if (ctx.config.threads)
|
|
3556
|
+
return createWorkerPool(ctx);
|
|
3557
|
+
else
|
|
3558
|
+
return createFakePool(ctx);
|
|
3559
|
+
}
|
|
3560
|
+
const workerPath = new URL("./dist/worker.js", pathToFileURL(distDir)).href;
|
|
3561
|
+
function createFakePool(ctx) {
|
|
3562
|
+
const runTestFiles = async (files, invalidates) => {
|
|
3563
|
+
const { default: run } = await import(workerPath);
|
|
3564
|
+
const { workerPort, port } = createChannel(ctx);
|
|
3565
|
+
const data = {
|
|
3566
|
+
port: workerPort,
|
|
3567
|
+
config: ctx.config,
|
|
3568
|
+
files,
|
|
3569
|
+
invalidates
|
|
3570
|
+
};
|
|
3571
|
+
await run(data, { transferList: [workerPort] });
|
|
3572
|
+
port.close();
|
|
3573
|
+
workerPort.close();
|
|
3574
|
+
};
|
|
3575
|
+
return {
|
|
3576
|
+
runTestFiles,
|
|
3577
|
+
close: async () => {
|
|
3578
|
+
}
|
|
3579
|
+
};
|
|
3580
|
+
}
|
|
3581
|
+
function createWorkerPool(ctx) {
|
|
3582
|
+
const options = {
|
|
3583
|
+
filename: workerPath
|
|
3584
|
+
};
|
|
3585
|
+
if (ctx.config.maxThreads != null)
|
|
3586
|
+
options.maxThreads = ctx.config.maxThreads;
|
|
3587
|
+
if (ctx.config.minThreads != null)
|
|
3588
|
+
options.minThreads = ctx.config.minThreads;
|
|
3589
|
+
const piscina = new Piscina(options);
|
|
3590
|
+
const runTestFiles = async (files, invalidates) => {
|
|
3591
|
+
await Promise.all(files.map(async (file) => {
|
|
3592
|
+
const { workerPort, port } = createChannel(ctx);
|
|
3593
|
+
const data = {
|
|
3594
|
+
port: workerPort,
|
|
3595
|
+
config: ctx.config,
|
|
3596
|
+
files: [file],
|
|
3597
|
+
invalidates
|
|
3598
|
+
};
|
|
3599
|
+
await piscina.run(data, { transferList: [workerPort] });
|
|
3600
|
+
port.close();
|
|
3601
|
+
workerPort.close();
|
|
3602
|
+
}));
|
|
3603
|
+
};
|
|
3604
|
+
return {
|
|
3605
|
+
runTestFiles,
|
|
3606
|
+
close: () => piscina.destroy()
|
|
3607
|
+
};
|
|
3608
|
+
}
|
|
3609
|
+
function createChannel(ctx) {
|
|
3610
|
+
const channel = new MessageChannel();
|
|
3611
|
+
const port = channel.port2;
|
|
3612
|
+
const workerPort = channel.port1;
|
|
3613
|
+
port.on("message", async ({ id, method, args = [] }) => {
|
|
3614
|
+
var _a, _b, _c, _d;
|
|
3615
|
+
async function send(fn) {
|
|
3616
|
+
try {
|
|
3617
|
+
port.postMessage({ id, result: await fn() });
|
|
3618
|
+
} catch (e) {
|
|
3619
|
+
port.postMessage({ id, error: e });
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
switch (method) {
|
|
3623
|
+
case "snapshotSaved":
|
|
3624
|
+
return send(() => ctx.snapshot.add(args[0]));
|
|
3625
|
+
case "fetch":
|
|
3626
|
+
return send(() => transformRequest(ctx.server, ...args));
|
|
3627
|
+
case "onCollected":
|
|
3628
|
+
ctx.state.collectFiles(args[0]);
|
|
3629
|
+
(_b = (_a = ctx.reporter).onStart) == null ? void 0 : _b.call(_a, args[0].map((i) => i.filepath));
|
|
3630
|
+
return;
|
|
3631
|
+
case "onTaskUpdate":
|
|
3632
|
+
ctx.state.updateTasks([args[0]]);
|
|
3633
|
+
(_d = (_c = ctx.reporter).onTaskUpdate) == null ? void 0 : _d.call(_c, args[0]);
|
|
3634
|
+
return;
|
|
3635
|
+
}
|
|
3636
|
+
console.error("Unhandled message", method, args);
|
|
3637
|
+
});
|
|
3638
|
+
return { workerPort, port };
|
|
3639
|
+
}
|
|
3640
|
+
|
|
3641
|
+
function isTargetFile(id, config) {
|
|
3642
|
+
if (mm.isMatch(id, config.excludes))
|
|
3643
|
+
return false;
|
|
3644
|
+
return mm.isMatch(id, config.includes);
|
|
3645
|
+
}
|
|
3646
|
+
async function globTestFiles(config) {
|
|
3647
|
+
var _a;
|
|
3648
|
+
let testFilepaths = await fg(config.includes, {
|
|
3649
|
+
absolute: true,
|
|
3650
|
+
cwd: config.root,
|
|
3651
|
+
ignore: config.excludes
|
|
3652
|
+
});
|
|
3653
|
+
if ((_a = config.cliFilters) == null ? void 0 : _a.length)
|
|
3654
|
+
testFilepaths = testFilepaths.filter((i) => config.cliFilters.some((f) => i.includes(f)));
|
|
3655
|
+
return testFilepaths;
|
|
3656
|
+
}
|
|
3657
|
+
|
|
3658
|
+
const WATCHER_DEBOUNCE = 50;
|
|
3659
|
+
async function startWatcher(ctx, pool) {
|
|
3660
|
+
var _a;
|
|
3661
|
+
const { reporter, server } = ctx;
|
|
3662
|
+
(_a = reporter.onWatcherStart) == null ? void 0 : _a.call(reporter);
|
|
3663
|
+
let timer;
|
|
3664
|
+
const changedTests = new Set();
|
|
3665
|
+
const seen = new Set();
|
|
3666
|
+
let promise;
|
|
3667
|
+
server.watcher.on("change", (id) => {
|
|
3668
|
+
id = slash(id);
|
|
3669
|
+
getAffectedTests(ctx, id, changedTests, seen);
|
|
3670
|
+
if (changedTests.size === 0)
|
|
3671
|
+
return;
|
|
3672
|
+
rerunFile(id);
|
|
3673
|
+
});
|
|
3674
|
+
server.watcher.on("unlink", (id) => {
|
|
3675
|
+
id = slash(id);
|
|
3676
|
+
seen.add(id);
|
|
3677
|
+
if (id in ctx.state.filesMap) {
|
|
3678
|
+
delete ctx.state.filesMap[id];
|
|
3679
|
+
changedTests.delete(id);
|
|
3680
|
+
}
|
|
3681
|
+
});
|
|
3682
|
+
server.watcher.on("add", async (id) => {
|
|
3683
|
+
id = slash(id);
|
|
3684
|
+
if (isTargetFile(id, ctx.config)) {
|
|
3685
|
+
changedTests.add(id);
|
|
3686
|
+
rerunFile(id);
|
|
3687
|
+
}
|
|
3688
|
+
});
|
|
3689
|
+
async function rerunFile(id) {
|
|
3690
|
+
await promise;
|
|
3691
|
+
clearTimeout(timer);
|
|
3692
|
+
timer = setTimeout(async () => {
|
|
3693
|
+
if (changedTests.size === 0) {
|
|
3694
|
+
seen.clear();
|
|
3695
|
+
return;
|
|
3696
|
+
}
|
|
3697
|
+
ctx.state.getFiles().forEach((file) => {
|
|
3698
|
+
var _a2;
|
|
3699
|
+
if (((_a2 = file.result) == null ? void 0 : _a2.state) === "fail")
|
|
3700
|
+
changedTests.add(file.filepath);
|
|
3701
|
+
});
|
|
3702
|
+
const invalidates = Array.from(seen);
|
|
3703
|
+
const tests = Array.from(changedTests);
|
|
3704
|
+
changedTests.clear();
|
|
3705
|
+
seen.clear();
|
|
3706
|
+
promise = start(tests, id, invalidates);
|
|
3707
|
+
await promise;
|
|
3708
|
+
}, WATCHER_DEBOUNCE);
|
|
3709
|
+
}
|
|
3710
|
+
async function start(tests, id, invalidates) {
|
|
3711
|
+
var _a2, _b, _c;
|
|
3712
|
+
await ((_a2 = reporter.onWatcherRerun) == null ? void 0 : _a2.call(reporter, tests, id));
|
|
3713
|
+
await pool.runTestFiles(tests, invalidates);
|
|
3714
|
+
await ((_b = reporter.onFinished) == null ? void 0 : _b.call(reporter, ctx.state.getFiles(tests)));
|
|
3715
|
+
await ((_c = reporter.onWatcherStart) == null ? void 0 : _c.call(reporter));
|
|
3716
|
+
}
|
|
3717
|
+
if (process.stdin.isTTY)
|
|
3718
|
+
listenToKeybard();
|
|
3719
|
+
await new Promise(() => {
|
|
3720
|
+
});
|
|
3721
|
+
}
|
|
3722
|
+
function getAffectedTests(ctx, id, set = new Set(), seen = new Set()) {
|
|
3723
|
+
if (seen.has(id) || set.has(id) || id.includes("/node_modules/") || id.includes("/vitest/dist/"))
|
|
3724
|
+
return set;
|
|
3725
|
+
seen.add(id);
|
|
3726
|
+
if (id in ctx.state.filesMap) {
|
|
3727
|
+
set.add(id);
|
|
3728
|
+
return set;
|
|
3729
|
+
}
|
|
3730
|
+
const mod = ctx.server.moduleGraph.getModuleById(id);
|
|
3731
|
+
if (mod) {
|
|
3732
|
+
mod.importers.forEach((i) => {
|
|
3733
|
+
if (i.id)
|
|
3734
|
+
getAffectedTests(ctx, i.id, set, seen);
|
|
3735
|
+
});
|
|
3736
|
+
}
|
|
3737
|
+
return set;
|
|
3738
|
+
}
|
|
3739
|
+
function listenToKeybard() {
|
|
3740
|
+
readline.emitKeypressEvents(process.stdin);
|
|
3741
|
+
process.stdin.setRawMode(true);
|
|
3742
|
+
process.stdin.on("keypress", (str, key) => {
|
|
3743
|
+
if (str === "" || str === "")
|
|
3744
|
+
process.exit();
|
|
3745
|
+
if (str === "\r")
|
|
3746
|
+
process.exit();
|
|
3747
|
+
});
|
|
3748
|
+
}
|
|
3749
|
+
|
|
3750
|
+
async function start(ctx) {
|
|
3751
|
+
var _a, _b;
|
|
3752
|
+
const { config } = ctx;
|
|
3753
|
+
const testFilepaths = await globTestFiles(config);
|
|
3754
|
+
if (!testFilepaths.length) {
|
|
3755
|
+
console.error("No test files found");
|
|
3756
|
+
process.exitCode = 1;
|
|
3757
|
+
return;
|
|
3758
|
+
}
|
|
3759
|
+
const pool = createPool(ctx);
|
|
3760
|
+
await pool.runTestFiles(testFilepaths);
|
|
3761
|
+
if (hasFailed(ctx.state.getFiles()))
|
|
3762
|
+
process.exitCode = 1;
|
|
3763
|
+
await ((_b = (_a = ctx.reporter).onFinished) == null ? void 0 : _b.call(_a, ctx.state.getFiles()));
|
|
3764
|
+
if (config.watch)
|
|
3765
|
+
await startWatcher(ctx, pool);
|
|
3766
|
+
else
|
|
3767
|
+
await pool.close();
|
|
3768
|
+
}
|
|
3769
|
+
|
|
3770
|
+
class StateManager {
|
|
3771
|
+
constructor() {
|
|
3772
|
+
this.filesMap = {};
|
|
3773
|
+
this.idMap = {};
|
|
3774
|
+
this.taskFileMap = new WeakMap();
|
|
3775
|
+
}
|
|
3776
|
+
getFiles(keys) {
|
|
3777
|
+
if (keys)
|
|
3778
|
+
return keys.map((key) => this.filesMap[key]);
|
|
3779
|
+
return Object.values(this.filesMap);
|
|
3780
|
+
}
|
|
3781
|
+
collectFiles(files) {
|
|
3782
|
+
files.forEach((file) => {
|
|
3783
|
+
this.filesMap[file.filepath] = file;
|
|
3784
|
+
this.updateId(file);
|
|
3785
|
+
});
|
|
3786
|
+
}
|
|
3787
|
+
updateId(task) {
|
|
3788
|
+
if (this.idMap[task.id] === task)
|
|
3789
|
+
return;
|
|
3790
|
+
this.idMap[task.id] = task;
|
|
3791
|
+
if (task.type === "suite") {
|
|
3792
|
+
task.tasks.forEach((task2) => {
|
|
3793
|
+
this.updateId(task2);
|
|
3794
|
+
});
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3797
|
+
updateTasks(packs) {
|
|
3798
|
+
for (const [id, result] of packs) {
|
|
3799
|
+
if (this.idMap[id])
|
|
3800
|
+
this.idMap[id].result = result;
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
}
|
|
3804
|
+
|
|
3805
|
+
var __defProp = Object.defineProperty;
|
|
3806
|
+
var __defProps = Object.defineProperties;
|
|
3807
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
3808
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3809
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
3810
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
3811
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3812
|
+
var __spreadValues = (a, b) => {
|
|
3813
|
+
for (var prop in b || (b = {}))
|
|
3814
|
+
if (__hasOwnProp.call(b, prop))
|
|
3815
|
+
__defNormalProp(a, prop, b[prop]);
|
|
3816
|
+
if (__getOwnPropSymbols)
|
|
3817
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
3818
|
+
if (__propIsEnum.call(b, prop))
|
|
3819
|
+
__defNormalProp(a, prop, b[prop]);
|
|
3820
|
+
}
|
|
3821
|
+
return a;
|
|
3822
|
+
};
|
|
3823
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
3824
|
+
const cli = cac("vitest");
|
|
3825
|
+
cli.version(version).option("-r, --root <path>", "root path").option("-c, --config <path>", "path to config file").option("-u, --update", "update snapshot").option("--global", "inject apis globally").option("--dom", "mock browser api with happy-dom").option("--environment <env>", "runner environment", {
|
|
3826
|
+
default: "node"
|
|
3827
|
+
}).help();
|
|
3828
|
+
cli.command("run [...filters]").action(run);
|
|
3829
|
+
cli.command("watch [...filters]").action(dev);
|
|
3830
|
+
cli.command("dev [...filters]").action(dev);
|
|
3831
|
+
cli.command("[...filters]").action(dev);
|
|
3832
|
+
cli.parse();
|
|
3833
|
+
async function dev(cliFilters, argv) {
|
|
3834
|
+
argv.watch = !process.env.CI;
|
|
3835
|
+
await run(cliFilters, argv);
|
|
3836
|
+
}
|
|
3837
|
+
async function run(cliFilters, argv) {
|
|
3838
|
+
process.env.VITEST = "true";
|
|
3839
|
+
console.log(c.magenta(c.bold("\nVitest is in closed beta exclusively for Sponsors")));
|
|
3840
|
+
console.log(c.yellow("Learn more at https://vitest.dev\n"));
|
|
3841
|
+
const { config, server } = await initViteServer(__spreadProps(__spreadValues({}, argv), { cliFilters }));
|
|
3842
|
+
const ctx = process.__vitest__ = {
|
|
3843
|
+
server,
|
|
3844
|
+
config,
|
|
3845
|
+
state: new StateManager(),
|
|
3846
|
+
snapshot: new SnapshotManager(config),
|
|
3847
|
+
reporter: config.reporter
|
|
3848
|
+
};
|
|
3849
|
+
ctx.reporter = ctx.reporter || new DefaultReporter(ctx);
|
|
3850
|
+
try {
|
|
3851
|
+
await start(ctx);
|
|
3852
|
+
} catch (e) {
|
|
3853
|
+
process.exitCode = 1;
|
|
3854
|
+
throw e;
|
|
3855
|
+
} finally {
|
|
3856
|
+
if (!config.watch)
|
|
3857
|
+
await server.close();
|
|
3858
|
+
}
|
|
3859
|
+
}
|