bun-git-hooks 0.2.15 → 0.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +708 -3599
- package/dist/git-hooks.d.ts +11 -9
- package/dist/index.js +342 -3233
- package/package.json +6 -5
- package/dist/bin/config.d.ts +0 -3
- package/dist/bin/git-hooks.d.ts +0 -62
- package/dist/bin/index.d.ts +0 -3
- package/dist/bin/types.d.ts +0 -20
package/dist/bin/cli.js
CHANGED
|
@@ -19,14 +19,9 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
19
19
|
var __require = import.meta.require;
|
|
20
20
|
|
|
21
21
|
// bin/cli.ts
|
|
22
|
-
import
|
|
22
|
+
import process10 from "process";
|
|
23
23
|
|
|
24
24
|
// node_modules/@stacksjs/clarity/dist/index.js
|
|
25
|
-
import { join as join3, relative as relative2, resolve as resolve4 } from "path";
|
|
26
|
-
import process7 from "process";
|
|
27
|
-
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
28
|
-
import { dirname as dirname2, resolve as resolve3 } from "path";
|
|
29
|
-
import process6 from "process";
|
|
30
25
|
import { join, relative, resolve as resolve2 } from "path";
|
|
31
26
|
import process2 from "process";
|
|
32
27
|
import { existsSync, mkdirSync, readdirSync, writeFileSync } from "fs";
|
|
@@ -42,16 +37,6 @@ import { pipeline } from "stream/promises";
|
|
|
42
37
|
import { createGzip } from "zlib";
|
|
43
38
|
import process4 from "process";
|
|
44
39
|
import process32 from "process";
|
|
45
|
-
import { Buffer as Buffer2 } from "buffer";
|
|
46
|
-
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes2 } from "crypto";
|
|
47
|
-
import { closeSync as closeSync2, createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync4, fsyncSync as fsyncSync2, openSync as openSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
48
|
-
import { access as access2, constants as constants2, mkdir as mkdir2, readdir as readdir2, rename as rename2, stat as stat2, unlink as unlink2, writeFile as writeFile2 } from "fs/promises";
|
|
49
|
-
import { join as join5 } from "path";
|
|
50
|
-
import process11 from "process";
|
|
51
|
-
import { pipeline as pipeline2 } from "stream/promises";
|
|
52
|
-
import { createGzip as createGzip2 } from "zlib";
|
|
53
|
-
import process10 from "process";
|
|
54
|
-
import process9 from "process";
|
|
55
40
|
function deepMerge(target, source) {
|
|
56
41
|
if (Array.isArray(source) && Array.isArray(target) && source.length === 2 && target.length === 2 && isObject(source[0]) && "id" in source[0] && source[0].id === 3 && isObject(source[1]) && "id" in source[1] && source[1].id === 4) {
|
|
57
42
|
return source;
|
|
@@ -211,11 +196,23 @@ async function loadConfig({
|
|
|
211
196
|
for (const ext of extensions) {
|
|
212
197
|
const fullPath = resolve(baseDir, `${configPath}${ext}`);
|
|
213
198
|
const config2 = await tryLoadConfig(fullPath, defaultConfig);
|
|
214
|
-
if (config2 !== null)
|
|
199
|
+
if (config2 !== null) {
|
|
215
200
|
return config2;
|
|
201
|
+
}
|
|
216
202
|
}
|
|
217
203
|
}
|
|
218
|
-
|
|
204
|
+
try {
|
|
205
|
+
const pkgPath = resolve(baseDir, "package.json");
|
|
206
|
+
if (existsSync(pkgPath)) {
|
|
207
|
+
const pkg = await import(pkgPath);
|
|
208
|
+
const pkgConfig = pkg[name];
|
|
209
|
+
if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
|
|
210
|
+
try {
|
|
211
|
+
return deepMerge(defaultConfig, pkgConfig);
|
|
212
|
+
} catch {}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
} catch {}
|
|
219
216
|
return defaultConfig;
|
|
220
217
|
}
|
|
221
218
|
var defaultConfigDir = resolve(process3.cwd(), "config");
|
|
@@ -289,7 +286,6 @@ async function isServerProcess() {
|
|
|
289
286
|
}
|
|
290
287
|
return false;
|
|
291
288
|
}
|
|
292
|
-
|
|
293
289
|
class JsonFormatter {
|
|
294
290
|
async format(entry) {
|
|
295
291
|
const isServer = await isServerProcess();
|
|
@@ -420,12 +416,6 @@ class Logger {
|
|
|
420
416
|
...configOptions,
|
|
421
417
|
timestamp: hasTimestamp || this.config.timestamp
|
|
422
418
|
};
|
|
423
|
-
if (!this.config.logDirectory) {
|
|
424
|
-
this.config.logDirectory = config.logDirectory;
|
|
425
|
-
}
|
|
426
|
-
if (!isBrowserProcess()) {
|
|
427
|
-
mkdir(this.config.logDirectory, { recursive: true, mode: 493 }).catch((err) => console.error("Failed to create log directory:", err));
|
|
428
|
-
}
|
|
429
419
|
this.currentLogFile = this.generateLogFilename();
|
|
430
420
|
this.encryptionKeys = new Map;
|
|
431
421
|
if (this.validateEncryptionConfig()) {
|
|
@@ -539,7 +529,7 @@ class Logger {
|
|
|
539
529
|
const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
|
|
540
530
|
console.error(`Network error during write attempt ${retries + 1}/${maxRetries}:`, errorMessage);
|
|
541
531
|
const delay = backoffDelay * 2 ** retries;
|
|
542
|
-
await new Promise((
|
|
532
|
+
await new Promise((resolve3) => setTimeout(resolve3, delay));
|
|
543
533
|
retries++;
|
|
544
534
|
continue;
|
|
545
535
|
}
|
|
@@ -567,7 +557,7 @@ class Logger {
|
|
|
567
557
|
}
|
|
568
558
|
retries++;
|
|
569
559
|
const delay = backoffDelay * 2 ** (retries - 1);
|
|
570
|
-
await new Promise((
|
|
560
|
+
await new Promise((resolve3) => setTimeout(resolve3, delay));
|
|
571
561
|
}
|
|
572
562
|
}
|
|
573
563
|
})();
|
|
@@ -690,11 +680,11 @@ class Logger {
|
|
|
690
680
|
};
|
|
691
681
|
}
|
|
692
682
|
async compressData(data) {
|
|
693
|
-
return new Promise((
|
|
683
|
+
return new Promise((resolve3, reject) => {
|
|
694
684
|
const gzip = createGzip();
|
|
695
685
|
const chunks = [];
|
|
696
686
|
gzip.on("data", (chunk2) => chunks.push(chunk2));
|
|
697
|
-
gzip.on("end", () =>
|
|
687
|
+
gzip.on("end", () => resolve3(Buffer.from(Buffer.concat(chunks))));
|
|
698
688
|
gzip.on("error", reject);
|
|
699
689
|
gzip.write(data);
|
|
700
690
|
gzip.end();
|
|
@@ -1280,7 +1270,7 @@ class Logger {
|
|
|
1280
1270
|
if (isBrowserProcess()) {
|
|
1281
1271
|
return Promise.resolve(true);
|
|
1282
1272
|
}
|
|
1283
|
-
return new Promise((
|
|
1273
|
+
return new Promise((resolve3) => {
|
|
1284
1274
|
console.error(`${styles.cyan("?")} ${message} (y/n) `);
|
|
1285
1275
|
const onData = (data) => {
|
|
1286
1276
|
const input = data.toString().trim().toLowerCase();
|
|
@@ -1292,7 +1282,7 @@ class Logger {
|
|
|
1292
1282
|
} catch {}
|
|
1293
1283
|
process5.stdin.pause();
|
|
1294
1284
|
console.error("");
|
|
1295
|
-
|
|
1285
|
+
resolve3(input === "y" || input === "yes");
|
|
1296
1286
|
};
|
|
1297
1287
|
try {
|
|
1298
1288
|
if (typeof process5.stdin.setRawMode === "function") {
|
|
@@ -1494,3542 +1484,626 @@ class Logger {
|
|
|
1494
1484
|
}
|
|
1495
1485
|
}
|
|
1496
1486
|
var logger = new Logger("stacks");
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1487
|
+
|
|
1488
|
+
// node_modules/cac/dist/index.mjs
|
|
1489
|
+
import { EventEmitter } from "events";
|
|
1490
|
+
function toArr(any) {
|
|
1491
|
+
return any == null ? [] : Array.isArray(any) ? any : [any];
|
|
1492
|
+
}
|
|
1493
|
+
function toVal(out, key, val, opts) {
|
|
1494
|
+
var x, old = out[key], nxt = ~opts.string.indexOf(key) ? val == null || val === true ? "" : String(val) : typeof val === "boolean" ? val : ~opts.boolean.indexOf(key) ? val === "false" ? false : val === "true" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;
|
|
1495
|
+
out[key] = old == null ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];
|
|
1496
|
+
}
|
|
1497
|
+
function mri2(args, opts) {
|
|
1498
|
+
args = args || [];
|
|
1499
|
+
opts = opts || {};
|
|
1500
|
+
var k, arr, arg, name, val, out = { _: [] };
|
|
1501
|
+
var i = 0, j = 0, idx = 0, len = args.length;
|
|
1502
|
+
const alibi = opts.alias !== undefined;
|
|
1503
|
+
const strict = opts.unknown !== undefined;
|
|
1504
|
+
const defaults = opts.default !== undefined;
|
|
1505
|
+
opts.alias = opts.alias || {};
|
|
1506
|
+
opts.string = toArr(opts.string);
|
|
1507
|
+
opts.boolean = toArr(opts.boolean);
|
|
1508
|
+
if (alibi) {
|
|
1509
|
+
for (k in opts.alias) {
|
|
1510
|
+
arr = opts.alias[k] = toArr(opts.alias[k]);
|
|
1511
|
+
for (i = 0;i < arr.length; i++) {
|
|
1512
|
+
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1503
1515
|
}
|
|
1504
|
-
|
|
1505
|
-
|
|
1516
|
+
for (i = opts.boolean.length;i-- > 0; ) {
|
|
1517
|
+
arr = opts.alias[opts.boolean[i]] || [];
|
|
1518
|
+
for (j = arr.length;j-- > 0; )
|
|
1519
|
+
opts.boolean.push(arr[j]);
|
|
1506
1520
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1521
|
+
for (i = opts.string.length;i-- > 0; ) {
|
|
1522
|
+
arr = opts.alias[opts.string[i]] || [];
|
|
1523
|
+
for (j = arr.length;j-- > 0; )
|
|
1524
|
+
opts.string.push(arr[j]);
|
|
1509
1525
|
}
|
|
1510
|
-
if (
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
const existingItem = result.find((item) => isObject2(item) && ("name" in item) && item.name === targetItem.name);
|
|
1519
|
-
if (!existingItem) {
|
|
1520
|
-
result.push(targetItem);
|
|
1521
|
-
}
|
|
1522
|
-
} else if (isObject2(targetItem) && "path" in targetItem) {
|
|
1523
|
-
const existingItem = result.find((item) => isObject2(item) && ("path" in item) && item.path === targetItem.path);
|
|
1524
|
-
if (!existingItem) {
|
|
1525
|
-
result.push(targetItem);
|
|
1526
|
-
}
|
|
1527
|
-
} else if (!result.some((item) => deepEquals2(item, targetItem))) {
|
|
1528
|
-
result.push(targetItem);
|
|
1526
|
+
if (defaults) {
|
|
1527
|
+
for (k in opts.default) {
|
|
1528
|
+
name = typeof opts.default[k];
|
|
1529
|
+
arr = opts.alias[k] = opts.alias[k] || [];
|
|
1530
|
+
if (opts[name] !== undefined) {
|
|
1531
|
+
opts[name].push(k);
|
|
1532
|
+
for (i = 0;i < arr.length; i++) {
|
|
1533
|
+
opts[name].push(arr[i]);
|
|
1529
1534
|
}
|
|
1530
1535
|
}
|
|
1531
|
-
return result;
|
|
1532
1536
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1537
|
+
}
|
|
1538
|
+
const keys = strict ? Object.keys(opts.alias) : [];
|
|
1539
|
+
for (i = 0;i < len; i++) {
|
|
1540
|
+
arg = args[i];
|
|
1541
|
+
if (arg === "--") {
|
|
1542
|
+
out._ = out._.concat(args.slice(++i));
|
|
1543
|
+
break;
|
|
1544
|
+
}
|
|
1545
|
+
for (j = 0;j < arg.length; j++) {
|
|
1546
|
+
if (arg.charCodeAt(j) !== 45)
|
|
1547
|
+
break;
|
|
1548
|
+
}
|
|
1549
|
+
if (j === 0) {
|
|
1550
|
+
out._.push(arg);
|
|
1551
|
+
} else if (arg.substring(j, j + 3) === "no-") {
|
|
1552
|
+
name = arg.substring(j + 3);
|
|
1553
|
+
if (strict && !~keys.indexOf(name)) {
|
|
1554
|
+
return opts.unknown(arg);
|
|
1555
|
+
}
|
|
1556
|
+
out[name] = false;
|
|
1557
|
+
} else {
|
|
1558
|
+
for (idx = j + 1;idx < arg.length; idx++) {
|
|
1559
|
+
if (arg.charCodeAt(idx) === 61)
|
|
1560
|
+
break;
|
|
1561
|
+
}
|
|
1562
|
+
name = arg.substring(j, idx);
|
|
1563
|
+
val = arg.substring(++idx) || (i + 1 === len || ("" + args[i + 1]).charCodeAt(0) === 45 || args[++i]);
|
|
1564
|
+
arr = j === 2 ? [name] : name;
|
|
1565
|
+
for (idx = 0;idx < arr.length; idx++) {
|
|
1566
|
+
name = arr[idx];
|
|
1567
|
+
if (strict && !~keys.indexOf(name))
|
|
1568
|
+
return opts.unknown("-".repeat(j) + name);
|
|
1569
|
+
toVal(out, name, idx + 1 < arr.length || val, opts);
|
|
1539
1570
|
}
|
|
1540
|
-
return result;
|
|
1541
1571
|
}
|
|
1542
|
-
return source;
|
|
1543
1572
|
}
|
|
1544
|
-
if (
|
|
1545
|
-
|
|
1573
|
+
if (defaults) {
|
|
1574
|
+
for (k in opts.default) {
|
|
1575
|
+
if (out[k] === undefined) {
|
|
1576
|
+
out[k] = opts.default[k];
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1546
1579
|
}
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
continue;
|
|
1553
|
-
} else if (isObject2(sourceValue) && isObject2(merged[key])) {
|
|
1554
|
-
merged[key] = deepMerge2(merged[key], sourceValue);
|
|
1555
|
-
} else if (Array.isArray(sourceValue) && Array.isArray(merged[key])) {
|
|
1556
|
-
if (sourceValue.length > 0 && merged[key].length > 0 && isObject2(sourceValue[0]) && isObject2(merged[key][0])) {
|
|
1557
|
-
const result = [...sourceValue];
|
|
1558
|
-
for (const targetItem of merged[key]) {
|
|
1559
|
-
if (isObject2(targetItem) && "name" in targetItem) {
|
|
1560
|
-
const existingItem = result.find((item) => isObject2(item) && ("name" in item) && item.name === targetItem.name);
|
|
1561
|
-
if (!existingItem) {
|
|
1562
|
-
result.push(targetItem);
|
|
1563
|
-
}
|
|
1564
|
-
} else if (isObject2(targetItem) && "path" in targetItem) {
|
|
1565
|
-
const existingItem = result.find((item) => isObject2(item) && ("path" in item) && item.path === targetItem.path);
|
|
1566
|
-
if (!existingItem) {
|
|
1567
|
-
result.push(targetItem);
|
|
1568
|
-
}
|
|
1569
|
-
} else if (!result.some((item) => deepEquals2(item, targetItem))) {
|
|
1570
|
-
result.push(targetItem);
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
merged[key] = result;
|
|
1574
|
-
} else if (sourceValue.every((item) => typeof item === "string") && merged[key].every((item) => typeof item === "string")) {
|
|
1575
|
-
const result = [...sourceValue];
|
|
1576
|
-
for (const item of merged[key]) {
|
|
1577
|
-
if (!result.includes(item)) {
|
|
1578
|
-
result.push(item);
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
merged[key] = result;
|
|
1582
|
-
} else {
|
|
1583
|
-
merged[key] = sourceValue;
|
|
1584
|
-
}
|
|
1585
|
-
} else {
|
|
1586
|
-
merged[key] = sourceValue;
|
|
1580
|
+
if (alibi) {
|
|
1581
|
+
for (k in out) {
|
|
1582
|
+
arr = opts.alias[k] || [];
|
|
1583
|
+
while (arr.length > 0) {
|
|
1584
|
+
out[arr.shift()] = out[k];
|
|
1587
1585
|
}
|
|
1588
1586
|
}
|
|
1589
1587
|
}
|
|
1590
|
-
return
|
|
1588
|
+
return out;
|
|
1591
1589
|
}
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1590
|
+
var removeBrackets = (v) => v.replace(/[<[].+/, "").trim();
|
|
1591
|
+
var findAllBrackets = (v) => {
|
|
1592
|
+
const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
|
|
1593
|
+
const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
|
|
1594
|
+
const res = [];
|
|
1595
|
+
const parse = (match) => {
|
|
1596
|
+
let variadic = false;
|
|
1597
|
+
let value = match[1];
|
|
1598
|
+
if (value.startsWith("...")) {
|
|
1599
|
+
value = value.slice(3);
|
|
1600
|
+
variadic = true;
|
|
1601
1601
|
}
|
|
1602
|
-
return
|
|
1602
|
+
return {
|
|
1603
|
+
required: match[0].startsWith("<"),
|
|
1604
|
+
value,
|
|
1605
|
+
variadic
|
|
1606
|
+
};
|
|
1607
|
+
};
|
|
1608
|
+
let angledMatch;
|
|
1609
|
+
while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {
|
|
1610
|
+
res.push(parse(angledMatch));
|
|
1603
1611
|
}
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1612
|
+
let squareMatch;
|
|
1613
|
+
while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {
|
|
1614
|
+
res.push(parse(squareMatch));
|
|
1615
|
+
}
|
|
1616
|
+
return res;
|
|
1617
|
+
};
|
|
1618
|
+
var getMriOptions = (options) => {
|
|
1619
|
+
const result = { alias: {}, boolean: [] };
|
|
1620
|
+
for (const [index, option] of options.entries()) {
|
|
1621
|
+
if (option.names.length > 1) {
|
|
1622
|
+
result.alias[option.names[0]] = option.names.slice(1);
|
|
1623
|
+
}
|
|
1624
|
+
if (option.isBoolean) {
|
|
1625
|
+
if (option.negated) {
|
|
1626
|
+
const hasStringTypeOption = options.some((o, i) => {
|
|
1627
|
+
return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean";
|
|
1628
|
+
});
|
|
1629
|
+
if (!hasStringTypeOption) {
|
|
1630
|
+
result.boolean.push(option.names[0]);
|
|
1631
|
+
}
|
|
1632
|
+
} else {
|
|
1633
|
+
result.boolean.push(option.names[0]);
|
|
1634
|
+
}
|
|
1614
1635
|
}
|
|
1615
|
-
return true;
|
|
1616
1636
|
}
|
|
1617
|
-
return
|
|
1618
|
-
}
|
|
1619
|
-
function isObject2(item) {
|
|
1620
|
-
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
1621
|
-
}
|
|
1622
|
-
var log = new Logger("bunfig", {
|
|
1623
|
-
showTags: true
|
|
1624
|
-
});
|
|
1625
|
-
async function tryLoadConfig2(configPath, defaultConfig2) {
|
|
1626
|
-
if (!existsSync3(configPath))
|
|
1627
|
-
return null;
|
|
1628
|
-
try {
|
|
1629
|
-
const importedConfig = await import(configPath);
|
|
1630
|
-
const loadedConfig = importedConfig.default || importedConfig;
|
|
1631
|
-
if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig))
|
|
1632
|
-
return null;
|
|
1633
|
-
try {
|
|
1634
|
-
return deepMerge2(defaultConfig2, loadedConfig);
|
|
1635
|
-
} catch {
|
|
1636
|
-
return null;
|
|
1637
|
-
}
|
|
1638
|
-
} catch {
|
|
1639
|
-
return null;
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
async function loadConfig3({
|
|
1643
|
-
name = "",
|
|
1644
|
-
cwd,
|
|
1645
|
-
defaultConfig: defaultConfig2
|
|
1646
|
-
}) {
|
|
1647
|
-
const baseDir = cwd || process6.cwd();
|
|
1648
|
-
const extensions = [".ts", ".js", ".mjs", ".cjs", ".json"];
|
|
1649
|
-
const configPaths = [
|
|
1650
|
-
`${name}.config`,
|
|
1651
|
-
`.${name}.config`,
|
|
1652
|
-
name,
|
|
1653
|
-
`.${name}`
|
|
1654
|
-
];
|
|
1655
|
-
for (const configPath of configPaths) {
|
|
1656
|
-
for (const ext of extensions) {
|
|
1657
|
-
const fullPath = resolve3(baseDir, `${configPath}${ext}`);
|
|
1658
|
-
const config3 = await tryLoadConfig2(fullPath, defaultConfig2);
|
|
1659
|
-
if (config3 !== null) {
|
|
1660
|
-
log.debug(`Configuration found: ${configPath}${ext}`);
|
|
1661
|
-
return config3;
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
try {
|
|
1666
|
-
const pkgPath = resolve3(baseDir, "package.json");
|
|
1667
|
-
if (existsSync3(pkgPath)) {
|
|
1668
|
-
const pkg = await import(pkgPath);
|
|
1669
|
-
const pkgConfig = pkg[name];
|
|
1670
|
-
if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
|
|
1671
|
-
try {
|
|
1672
|
-
log.debug(`Configuration found in package.json!`);
|
|
1673
|
-
return deepMerge2(defaultConfig2, pkgConfig);
|
|
1674
|
-
} catch {}
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
} catch {}
|
|
1678
|
-
log.debug("No configuration found, now using default config");
|
|
1679
|
-
return defaultConfig2;
|
|
1680
|
-
}
|
|
1681
|
-
var defaultConfigDir2 = resolve3(process6.cwd(), "config");
|
|
1682
|
-
var defaultGeneratedDir2 = resolve3(process6.cwd(), "src/generated");
|
|
1683
|
-
function getProjectRoot2(filePath, options = {}) {
|
|
1684
|
-
let path = process7.cwd();
|
|
1685
|
-
while (path.includes("storage"))
|
|
1686
|
-
path = resolve4(path, "..");
|
|
1687
|
-
const finalPath = resolve4(path, filePath || "");
|
|
1688
|
-
if (options?.relative)
|
|
1689
|
-
return relative2(process7.cwd(), finalPath);
|
|
1690
|
-
return finalPath;
|
|
1691
|
-
}
|
|
1692
|
-
var defaultLogDirectory2 = process7.env.CLARITY_LOG_DIR || join3(getProjectRoot2(), "logs");
|
|
1693
|
-
var defaultConfig2 = {
|
|
1694
|
-
level: "info",
|
|
1695
|
-
defaultName: "clarity",
|
|
1696
|
-
timestamp: true,
|
|
1697
|
-
colors: true,
|
|
1698
|
-
format: "text",
|
|
1699
|
-
maxLogSize: 10485760,
|
|
1700
|
-
logDatePattern: "YYYY-MM-DD",
|
|
1701
|
-
logDirectory: defaultLogDirectory2,
|
|
1702
|
-
rotation: {
|
|
1703
|
-
frequency: "daily",
|
|
1704
|
-
maxSize: 10485760,
|
|
1705
|
-
maxFiles: 5,
|
|
1706
|
-
compress: false,
|
|
1707
|
-
rotateHour: 0,
|
|
1708
|
-
rotateMinute: 0,
|
|
1709
|
-
rotateDayOfWeek: 0,
|
|
1710
|
-
rotateDayOfMonth: 1,
|
|
1711
|
-
encrypt: false
|
|
1712
|
-
},
|
|
1713
|
-
verbose: false
|
|
1714
|
-
};
|
|
1715
|
-
async function loadConfig4() {
|
|
1716
|
-
try {
|
|
1717
|
-
const loadedConfig = await loadConfig3({
|
|
1718
|
-
name: "clarity",
|
|
1719
|
-
defaultConfig: defaultConfig2,
|
|
1720
|
-
cwd: process7.cwd(),
|
|
1721
|
-
endpoint: "",
|
|
1722
|
-
headers: {}
|
|
1723
|
-
});
|
|
1724
|
-
return { ...defaultConfig2, ...loadedConfig };
|
|
1725
|
-
} catch {
|
|
1726
|
-
return defaultConfig2;
|
|
1727
|
-
}
|
|
1728
|
-
}
|
|
1729
|
-
var config2 = await loadConfig4();
|
|
1730
|
-
function isBrowserProcess2() {
|
|
1731
|
-
if (process9.env.NODE_ENV === "test" || process9.env.BUN_ENV === "test") {
|
|
1732
|
-
return false;
|
|
1733
|
-
}
|
|
1734
|
-
return typeof window !== "undefined";
|
|
1735
|
-
}
|
|
1736
|
-
async function isServerProcess2() {
|
|
1737
|
-
if (process9.env.NODE_ENV === "test" || process9.env.BUN_ENV === "test") {
|
|
1738
|
-
return true;
|
|
1739
|
-
}
|
|
1740
|
-
if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
1741
|
-
return true;
|
|
1742
|
-
}
|
|
1743
|
-
if (typeof process9 !== "undefined") {
|
|
1744
|
-
const type = process9.type;
|
|
1745
|
-
if (type === "renderer" || type === "worker") {
|
|
1746
|
-
return false;
|
|
1747
|
-
}
|
|
1748
|
-
return !!(process9.versions && (process9.versions.node || process9.versions.bun));
|
|
1749
|
-
}
|
|
1750
|
-
return false;
|
|
1751
|
-
}
|
|
1752
|
-
class JsonFormatter2 {
|
|
1753
|
-
async format(entry) {
|
|
1754
|
-
const isServer = await isServerProcess2();
|
|
1755
|
-
const metadata = await this.getMetadata(isServer);
|
|
1756
|
-
return JSON.stringify({
|
|
1757
|
-
timestamp: entry.timestamp.toISOString(),
|
|
1758
|
-
level: entry.level,
|
|
1759
|
-
name: entry.name,
|
|
1760
|
-
message: entry.message,
|
|
1761
|
-
metadata
|
|
1762
|
-
});
|
|
1763
|
-
}
|
|
1764
|
-
async getMetadata(isServer) {
|
|
1765
|
-
if (isServer) {
|
|
1766
|
-
const { hostname } = await import("os");
|
|
1767
|
-
return {
|
|
1768
|
-
pid: process10.pid,
|
|
1769
|
-
hostname: hostname(),
|
|
1770
|
-
environment: process10.env.NODE_ENV || "development",
|
|
1771
|
-
platform: process10.platform,
|
|
1772
|
-
version: process10.version
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
return {
|
|
1776
|
-
userAgent: navigator.userAgent,
|
|
1777
|
-
hostname: window.location.hostname || "browser",
|
|
1778
|
-
environment: process10.env.NODE_ENV || process10.env.BUN_ENV || "development",
|
|
1779
|
-
viewport: {
|
|
1780
|
-
width: window.innerWidth,
|
|
1781
|
-
height: window.innerHeight
|
|
1782
|
-
},
|
|
1783
|
-
language: navigator.language
|
|
1784
|
-
};
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1787
|
-
var terminalStyles2 = {
|
|
1788
|
-
red: (text) => `\x1B[31m${text}\x1B[0m`,
|
|
1789
|
-
green: (text) => `\x1B[32m${text}\x1B[0m`,
|
|
1790
|
-
yellow: (text) => `\x1B[33m${text}\x1B[0m`,
|
|
1791
|
-
blue: (text) => `\x1B[34m${text}\x1B[0m`,
|
|
1792
|
-
magenta: (text) => `\x1B[35m${text}\x1B[0m`,
|
|
1793
|
-
cyan: (text) => `\x1B[36m${text}\x1B[0m`,
|
|
1794
|
-
white: (text) => `\x1B[37m${text}\x1B[0m`,
|
|
1795
|
-
gray: (text) => `\x1B[90m${text}\x1B[0m`,
|
|
1796
|
-
bgRed: (text) => `\x1B[41m${text}\x1B[0m`,
|
|
1797
|
-
bgYellow: (text) => `\x1B[43m${text}\x1B[0m`,
|
|
1798
|
-
bold: (text) => `\x1B[1m${text}\x1B[0m`,
|
|
1799
|
-
dim: (text) => `\x1B[2m${text}\x1B[0m`,
|
|
1800
|
-
italic: (text) => `\x1B[3m${text}\x1B[0m`,
|
|
1801
|
-
underline: (text) => `\x1B[4m${text}\x1B[0m`,
|
|
1802
|
-
reset: "\x1B[0m"
|
|
1803
|
-
};
|
|
1804
|
-
var styles2 = terminalStyles2;
|
|
1805
|
-
var red2 = terminalStyles2.red;
|
|
1806
|
-
var green2 = terminalStyles2.green;
|
|
1807
|
-
var yellow2 = terminalStyles2.yellow;
|
|
1808
|
-
var blue2 = terminalStyles2.blue;
|
|
1809
|
-
var magenta2 = terminalStyles2.magenta;
|
|
1810
|
-
var cyan2 = terminalStyles2.cyan;
|
|
1811
|
-
var white2 = terminalStyles2.white;
|
|
1812
|
-
var gray2 = terminalStyles2.gray;
|
|
1813
|
-
var bgRed2 = terminalStyles2.bgRed;
|
|
1814
|
-
var bgYellow2 = terminalStyles2.bgYellow;
|
|
1815
|
-
var bold2 = terminalStyles2.bold;
|
|
1816
|
-
var dim2 = terminalStyles2.dim;
|
|
1817
|
-
var italic2 = terminalStyles2.italic;
|
|
1818
|
-
var underline2 = terminalStyles2.underline;
|
|
1819
|
-
var reset2 = terminalStyles2.reset;
|
|
1820
|
-
var defaultFingersCrossedConfig2 = {
|
|
1821
|
-
activationLevel: "error",
|
|
1822
|
-
bufferSize: 50,
|
|
1823
|
-
flushOnDeactivation: true,
|
|
1824
|
-
stopBuffering: false
|
|
1637
|
+
return result;
|
|
1825
1638
|
};
|
|
1826
|
-
var
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
warning: bgYellow2(white2(bold2(" WARN "))),
|
|
1831
|
-
error: bgRed2(white2(bold2(" ERROR ")))
|
|
1639
|
+
var findLongest = (arr) => {
|
|
1640
|
+
return arr.sort((a, b) => {
|
|
1641
|
+
return a.length > b.length ? -1 : 1;
|
|
1642
|
+
})[0];
|
|
1832
1643
|
};
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
environment;
|
|
1859
|
-
ANSI_PATTERN = /\u001B\[.*?m/g;
|
|
1860
|
-
activeProgressBar = null;
|
|
1861
|
-
constructor(name, options = {}) {
|
|
1862
|
-
this.name = name;
|
|
1863
|
-
this.config = { ...config2 };
|
|
1864
|
-
this.options = this.normalizeOptions(options);
|
|
1865
|
-
this.formatter = this.options.formatter || new JsonFormatter2;
|
|
1866
|
-
this.enabled = options.enabled ?? true;
|
|
1867
|
-
this.fancy = options.fancy ?? true;
|
|
1868
|
-
this.tagFormat = options.tagFormat ?? { prefix: "[", suffix: "]" };
|
|
1869
|
-
this.timestampPosition = options.timestampPosition ?? "right";
|
|
1870
|
-
this.environment = options.environment ?? process11.env.APP_ENV ?? "local";
|
|
1871
|
-
this.fingersCrossedConfig = this.initializeFingersCrossedConfig(options);
|
|
1872
|
-
const configOptions = { ...options };
|
|
1873
|
-
const hasTimestamp = options.timestamp !== undefined;
|
|
1874
|
-
if (hasTimestamp) {
|
|
1875
|
-
delete configOptions.timestamp;
|
|
1876
|
-
}
|
|
1877
|
-
this.config = {
|
|
1878
|
-
...this.config,
|
|
1879
|
-
...configOptions,
|
|
1880
|
-
timestamp: hasTimestamp || this.config.timestamp
|
|
1881
|
-
};
|
|
1882
|
-
if (!this.config.logDirectory) {
|
|
1883
|
-
this.config.logDirectory = config2.logDirectory;
|
|
1884
|
-
}
|
|
1885
|
-
if (!isBrowserProcess2()) {
|
|
1886
|
-
mkdir2(this.config.logDirectory, { recursive: true, mode: 493 }).catch((err) => console.error("Failed to create log directory:", err));
|
|
1887
|
-
}
|
|
1888
|
-
this.currentLogFile = this.generateLogFilename();
|
|
1889
|
-
this.encryptionKeys = new Map;
|
|
1890
|
-
if (this.validateEncryptionConfig()) {
|
|
1891
|
-
this.setupRotation();
|
|
1892
|
-
const initialKeyId = this.generateKeyId();
|
|
1893
|
-
const initialKey = this.generateKey();
|
|
1894
|
-
this.currentKeyId = initialKeyId;
|
|
1895
|
-
this.keys.set(initialKeyId, initialKey);
|
|
1896
|
-
this.encryptionKeys.set(initialKeyId, {
|
|
1897
|
-
key: initialKey,
|
|
1898
|
-
createdAt: new Date
|
|
1899
|
-
});
|
|
1900
|
-
this.setupKeyRotation();
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
initializeFingersCrossedConfig(options) {
|
|
1904
|
-
if (!options.fingersCrossedEnabled && options.fingersCrossed) {
|
|
1905
|
-
return {
|
|
1906
|
-
...defaultFingersCrossedConfig2,
|
|
1907
|
-
...options.fingersCrossed
|
|
1908
|
-
};
|
|
1909
|
-
}
|
|
1910
|
-
if (!options.fingersCrossedEnabled) {
|
|
1911
|
-
return null;
|
|
1912
|
-
}
|
|
1913
|
-
if (!options.fingersCrossed) {
|
|
1914
|
-
return { ...defaultFingersCrossedConfig2 };
|
|
1915
|
-
}
|
|
1916
|
-
return {
|
|
1917
|
-
...defaultFingersCrossedConfig2,
|
|
1918
|
-
...options.fingersCrossed
|
|
1919
|
-
};
|
|
1920
|
-
}
|
|
1921
|
-
normalizeOptions(options) {
|
|
1922
|
-
const defaultOptions = {
|
|
1923
|
-
format: "json",
|
|
1924
|
-
level: "info",
|
|
1925
|
-
logDirectory: config2.logDirectory,
|
|
1926
|
-
rotation: undefined,
|
|
1927
|
-
timestamp: undefined,
|
|
1928
|
-
fingersCrossed: {},
|
|
1929
|
-
enabled: true,
|
|
1930
|
-
showTags: false,
|
|
1931
|
-
formatter: undefined
|
|
1932
|
-
};
|
|
1933
|
-
const mergedOptions = {
|
|
1934
|
-
...defaultOptions,
|
|
1935
|
-
...Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined))
|
|
1936
|
-
};
|
|
1937
|
-
if (!mergedOptions.level || !["debug", "info", "success", "warning", "error"].includes(mergedOptions.level)) {
|
|
1938
|
-
mergedOptions.level = defaultOptions.level;
|
|
1939
|
-
}
|
|
1940
|
-
return mergedOptions;
|
|
1941
|
-
}
|
|
1942
|
-
async writeToFile(data) {
|
|
1943
|
-
const cancelled = false;
|
|
1944
|
-
const operationPromise = (async () => {
|
|
1945
|
-
let fd;
|
|
1946
|
-
let retries = 0;
|
|
1947
|
-
const maxRetries = 3;
|
|
1948
|
-
const backoffDelay = 1000;
|
|
1949
|
-
while (retries < maxRetries) {
|
|
1950
|
-
try {
|
|
1951
|
-
try {
|
|
1952
|
-
try {
|
|
1953
|
-
await access2(this.config.logDirectory, constants2.F_OK | constants2.W_OK);
|
|
1954
|
-
} catch (err) {
|
|
1955
|
-
if (err instanceof Error && "code" in err) {
|
|
1956
|
-
if (err.code === "ENOENT") {
|
|
1957
|
-
await mkdir2(this.config.logDirectory, { recursive: true, mode: 493 });
|
|
1958
|
-
} else if (err.code === "EACCES") {
|
|
1959
|
-
throw new Error(`No write permission for log directory: ${this.config.logDirectory}`);
|
|
1960
|
-
} else {
|
|
1961
|
-
throw err;
|
|
1962
|
-
}
|
|
1963
|
-
} else {
|
|
1964
|
-
throw err;
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1967
|
-
} catch (err) {
|
|
1968
|
-
console.error("Debug: [writeToFile] Failed to create log directory:", err);
|
|
1969
|
-
throw err;
|
|
1970
|
-
}
|
|
1971
|
-
if (cancelled)
|
|
1972
|
-
throw new Error("Operation cancelled: Logger was destroyed");
|
|
1973
|
-
const dataToWrite = this.validateEncryptionConfig() ? (await this.encrypt(data)).encrypted : Buffer2.from(data);
|
|
1974
|
-
try {
|
|
1975
|
-
if (!existsSync4(this.currentLogFile)) {
|
|
1976
|
-
await writeFile2(this.currentLogFile, "", { mode: 420 });
|
|
1977
|
-
}
|
|
1978
|
-
fd = openSync2(this.currentLogFile, "a", 420);
|
|
1979
|
-
writeFileSync4(fd, dataToWrite, { flag: "a" });
|
|
1980
|
-
fsyncSync2(fd);
|
|
1981
|
-
if (fd !== undefined) {
|
|
1982
|
-
closeSync2(fd);
|
|
1983
|
-
fd = undefined;
|
|
1984
|
-
}
|
|
1985
|
-
const stats = await stat2(this.currentLogFile);
|
|
1986
|
-
if (stats.size === 0) {
|
|
1987
|
-
await writeFile2(this.currentLogFile, dataToWrite, { flag: "w", mode: 420 });
|
|
1988
|
-
const retryStats = await stat2(this.currentLogFile);
|
|
1989
|
-
if (retryStats.size === 0) {
|
|
1990
|
-
throw new Error("File exists but is empty after retry write");
|
|
1991
|
-
}
|
|
1992
|
-
}
|
|
1993
|
-
return;
|
|
1994
|
-
} catch (err) {
|
|
1995
|
-
const error = err;
|
|
1996
|
-
if (error.code && ["ENETDOWN", "ENETUNREACH", "ENOTFOUND", "ETIMEDOUT"].includes(error.code)) {
|
|
1997
|
-
if (retries < maxRetries - 1) {
|
|
1998
|
-
const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
|
|
1999
|
-
console.error(`Network error during write attempt ${retries + 1}/${maxRetries}:`, errorMessage);
|
|
2000
|
-
const delay = backoffDelay * 2 ** retries;
|
|
2001
|
-
await new Promise((resolve5) => setTimeout(resolve5, delay));
|
|
2002
|
-
retries++;
|
|
2003
|
-
continue;
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
if (error?.code && ["ENOSPC", "EDQUOT"].includes(error.code)) {
|
|
2007
|
-
throw new Error(`Disk quota exceeded or no space left on device: ${error.message}`);
|
|
2008
|
-
}
|
|
2009
|
-
console.error("Debug: [writeToFile] Error writing to file:", error);
|
|
2010
|
-
throw error;
|
|
2011
|
-
} finally {
|
|
2012
|
-
if (fd !== undefined) {
|
|
2013
|
-
try {
|
|
2014
|
-
closeSync2(fd);
|
|
2015
|
-
} catch (err) {
|
|
2016
|
-
console.error("Debug: [writeToFile] Error closing file descriptor:", err);
|
|
2017
|
-
}
|
|
2018
|
-
}
|
|
2019
|
-
}
|
|
2020
|
-
} catch (err) {
|
|
2021
|
-
if (retries === maxRetries - 1) {
|
|
2022
|
-
const error = err;
|
|
2023
|
-
const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
|
|
2024
|
-
console.error("Debug: [writeToFile] Max retries reached. Final error:", errorMessage);
|
|
2025
|
-
throw err;
|
|
2026
|
-
}
|
|
2027
|
-
retries++;
|
|
2028
|
-
const delay = backoffDelay * 2 ** (retries - 1);
|
|
2029
|
-
await new Promise((resolve5) => setTimeout(resolve5, delay));
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
})();
|
|
2033
|
-
this.pendingOperations.push(operationPromise);
|
|
2034
|
-
const index = this.pendingOperations.length - 1;
|
|
2035
|
-
try {
|
|
2036
|
-
await operationPromise;
|
|
2037
|
-
} catch (err) {
|
|
2038
|
-
console.error("Debug: [writeToFile] Error in operation:", err);
|
|
2039
|
-
throw err;
|
|
2040
|
-
} finally {
|
|
2041
|
-
this.pendingOperations.splice(index, 1);
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
2044
|
-
generateLogFilename() {
|
|
2045
|
-
if (this.name.includes("stream-throughput") || this.name.includes("decompress-perf-test") || this.name.includes("decompression-latency") || this.name.includes("concurrent-read-test") || this.name.includes("clock-change-test")) {
|
|
2046
|
-
return join5(this.config.logDirectory, `${this.name}.log`);
|
|
2047
|
-
}
|
|
2048
|
-
if (this.name.includes("pending-test") || this.name.includes("temp-file-test") || this.name === "crash-test" || this.name === "corrupt-test" || this.name.includes("rotation-load-test") || this.name === "sigterm-test" || this.name === "sigint-test" || this.name === "failed-rotation-test" || this.name === "integration-test") {
|
|
2049
|
-
return join5(this.config.logDirectory, `${this.name}.log`);
|
|
2050
|
-
}
|
|
2051
|
-
const date = new Date().toISOString().split("T")[0];
|
|
2052
|
-
return join5(this.config.logDirectory, `${this.name}-${date}.log`);
|
|
2053
|
-
}
|
|
2054
|
-
setupRotation() {
|
|
2055
|
-
if (isBrowserProcess2())
|
|
2056
|
-
return;
|
|
2057
|
-
if (typeof this.config.rotation === "boolean")
|
|
2058
|
-
return;
|
|
2059
|
-
const config3 = this.config.rotation;
|
|
2060
|
-
let interval;
|
|
2061
|
-
switch (config3.frequency) {
|
|
2062
|
-
case "daily":
|
|
2063
|
-
interval = 86400000;
|
|
2064
|
-
break;
|
|
2065
|
-
case "weekly":
|
|
2066
|
-
interval = 604800000;
|
|
2067
|
-
break;
|
|
2068
|
-
case "monthly":
|
|
2069
|
-
interval = 2592000000;
|
|
2070
|
-
break;
|
|
2071
|
-
default:
|
|
2072
|
-
return;
|
|
2073
|
-
}
|
|
2074
|
-
this.rotationTimeout = setInterval(() => {
|
|
2075
|
-
this.rotateLog();
|
|
2076
|
-
}, interval);
|
|
2077
|
-
}
|
|
2078
|
-
setupKeyRotation() {
|
|
2079
|
-
if (!this.validateEncryptionConfig()) {
|
|
2080
|
-
console.error("Invalid encryption configuration detected during key rotation setup");
|
|
2081
|
-
return;
|
|
2082
|
-
}
|
|
2083
|
-
const rotation = this.config.rotation;
|
|
2084
|
-
const keyRotation = rotation.keyRotation;
|
|
2085
|
-
if (!keyRotation?.enabled) {
|
|
2086
|
-
return;
|
|
2087
|
-
}
|
|
2088
|
-
const rotationInterval = typeof keyRotation.interval === "number" ? keyRotation.interval : 60;
|
|
2089
|
-
const interval = Math.max(rotationInterval, 60) * 1000;
|
|
2090
|
-
this.keyRotationTimeout = setInterval(() => {
|
|
2091
|
-
this.rotateKeys().catch((error) => {
|
|
2092
|
-
console.error("Error rotating keys:", error);
|
|
2093
|
-
});
|
|
2094
|
-
}, interval);
|
|
2095
|
-
}
|
|
2096
|
-
async rotateKeys() {
|
|
2097
|
-
if (!this.validateEncryptionConfig()) {
|
|
2098
|
-
console.error("Invalid encryption configuration detected during key rotation");
|
|
2099
|
-
return;
|
|
2100
|
-
}
|
|
2101
|
-
const rotation = this.config.rotation;
|
|
2102
|
-
const keyRotation = rotation.keyRotation;
|
|
2103
|
-
const newKeyId = this.generateKeyId();
|
|
2104
|
-
const newKey = this.generateKey();
|
|
2105
|
-
this.currentKeyId = newKeyId;
|
|
2106
|
-
this.keys.set(newKeyId, newKey);
|
|
2107
|
-
this.encryptionKeys.set(newKeyId, {
|
|
2108
|
-
key: newKey,
|
|
2109
|
-
createdAt: new Date
|
|
2110
|
-
});
|
|
2111
|
-
const sortedKeys = Array.from(this.encryptionKeys.entries()).sort(([, a], [, b]) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
2112
|
-
const maxKeyCount = typeof keyRotation.maxKeys === "number" ? keyRotation.maxKeys : 1;
|
|
2113
|
-
const maxKeys = Math.max(1, maxKeyCount);
|
|
2114
|
-
if (sortedKeys.length > maxKeys) {
|
|
2115
|
-
for (const [keyId] of sortedKeys.slice(maxKeys)) {
|
|
2116
|
-
this.encryptionKeys.delete(keyId);
|
|
2117
|
-
this.keys.delete(keyId);
|
|
2118
|
-
}
|
|
2119
|
-
}
|
|
2120
|
-
}
|
|
2121
|
-
generateKeyId() {
|
|
2122
|
-
return randomBytes2(16).toString("hex");
|
|
2123
|
-
}
|
|
2124
|
-
generateKey() {
|
|
2125
|
-
return randomBytes2(32);
|
|
2126
|
-
}
|
|
2127
|
-
getCurrentKey() {
|
|
2128
|
-
if (!this.currentKeyId) {
|
|
2129
|
-
throw new Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");
|
|
2130
|
-
}
|
|
2131
|
-
const key = this.keys.get(this.currentKeyId);
|
|
2132
|
-
if (!key) {
|
|
2133
|
-
throw new Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);
|
|
2134
|
-
}
|
|
2135
|
-
return { key, id: this.currentKeyId };
|
|
2136
|
-
}
|
|
2137
|
-
encrypt(data) {
|
|
2138
|
-
const { key } = this.getCurrentKey();
|
|
2139
|
-
const iv = randomBytes2(16);
|
|
2140
|
-
const cipher = createCipheriv2("aes-256-gcm", key, iv);
|
|
2141
|
-
const encrypted = Buffer2.concat([
|
|
2142
|
-
cipher.update(data, "utf8"),
|
|
2143
|
-
cipher.final()
|
|
2144
|
-
]);
|
|
2145
|
-
const authTag = cipher.getAuthTag();
|
|
2146
|
-
return {
|
|
2147
|
-
encrypted: Buffer2.concat([iv, encrypted, authTag]),
|
|
2148
|
-
iv
|
|
2149
|
-
};
|
|
2150
|
-
}
|
|
2151
|
-
async compressData(data) {
|
|
2152
|
-
return new Promise((resolve5, reject) => {
|
|
2153
|
-
const gzip = createGzip2();
|
|
2154
|
-
const chunks = [];
|
|
2155
|
-
gzip.on("data", (chunk2) => chunks.push(chunk2));
|
|
2156
|
-
gzip.on("end", () => resolve5(Buffer2.from(Buffer2.concat(chunks))));
|
|
2157
|
-
gzip.on("error", reject);
|
|
2158
|
-
gzip.write(data);
|
|
2159
|
-
gzip.end();
|
|
2160
|
-
});
|
|
2161
|
-
}
|
|
2162
|
-
getEncryptionOptions() {
|
|
2163
|
-
if (!this.config.rotation || typeof this.config.rotation === "boolean" || !this.config.rotation.encrypt) {
|
|
2164
|
-
return {};
|
|
2165
|
-
}
|
|
2166
|
-
const defaultOptions = {
|
|
2167
|
-
algorithm: "aes-256-cbc",
|
|
2168
|
-
compress: false
|
|
2169
|
-
};
|
|
2170
|
-
if (typeof this.config.rotation.encrypt === "object") {
|
|
2171
|
-
const encryptConfig = this.config.rotation.encrypt;
|
|
2172
|
-
return {
|
|
2173
|
-
...defaultOptions,
|
|
2174
|
-
...encryptConfig
|
|
2175
|
-
};
|
|
2176
|
-
}
|
|
2177
|
-
return defaultOptions;
|
|
2178
|
-
}
|
|
2179
|
-
async rotateLog() {
|
|
2180
|
-
if (isBrowserProcess2())
|
|
2181
|
-
return;
|
|
2182
|
-
const stats = await stat2(this.currentLogFile).catch(() => null);
|
|
2183
|
-
if (!stats)
|
|
2184
|
-
return;
|
|
2185
|
-
const config3 = this.config.rotation;
|
|
2186
|
-
if (typeof config3 === "boolean")
|
|
2187
|
-
return;
|
|
2188
|
-
if (config3.maxSize && stats.size >= config3.maxSize) {
|
|
2189
|
-
const oldFile = this.currentLogFile;
|
|
2190
|
-
const newFile = this.generateLogFilename();
|
|
2191
|
-
if (this.name.includes("rotation-load-test") || this.name === "failed-rotation-test") {
|
|
2192
|
-
const files = await readdir2(this.config.logDirectory);
|
|
2193
|
-
const rotatedFiles = files.filter((f) => f.startsWith(this.name) && /\.log\.\d+$/.test(f)).sort((a, b) => {
|
|
2194
|
-
const numA = Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1] || "0");
|
|
2195
|
-
const numB = Number.parseInt(b.match(/\.log\.(\d+)$/)?.[1] || "0");
|
|
2196
|
-
return numB - numA;
|
|
2197
|
-
});
|
|
2198
|
-
const nextNum = rotatedFiles.length > 0 ? Number.parseInt(rotatedFiles[0].match(/\.log\.(\d+)$/)?.[1] || "0") + 1 : 1;
|
|
2199
|
-
const rotatedFile = `${oldFile}.${nextNum}`;
|
|
2200
|
-
if (await stat2(oldFile).catch(() => null)) {
|
|
2201
|
-
try {
|
|
2202
|
-
await rename2(oldFile, rotatedFile);
|
|
2203
|
-
if (config3.compress) {
|
|
2204
|
-
try {
|
|
2205
|
-
const compressedPath = `${rotatedFile}.gz`;
|
|
2206
|
-
await this.compressLogFile(rotatedFile, compressedPath);
|
|
2207
|
-
await unlink2(rotatedFile);
|
|
2208
|
-
} catch (err) {
|
|
2209
|
-
console.error("Error compressing rotated file:", err);
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2212
|
-
if (rotatedFiles.length === 0 && !files.some((f) => f.endsWith(".log.1"))) {
|
|
2213
|
-
try {
|
|
2214
|
-
const backupPath = `${oldFile}.1`;
|
|
2215
|
-
await writeFile2(backupPath, "");
|
|
2216
|
-
} catch (err) {
|
|
2217
|
-
console.error("Error creating backup file:", err);
|
|
2218
|
-
}
|
|
2219
|
-
}
|
|
2220
|
-
} catch (err) {
|
|
2221
|
-
console.error(`Error during rotation: ${err instanceof Error ? err.message : String(err)}`);
|
|
2222
|
-
}
|
|
2223
|
-
}
|
|
2224
|
-
} else {
|
|
2225
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
2226
|
-
const rotatedFile = oldFile.replace(/\.log$/, `-${timestamp}.log`);
|
|
2227
|
-
if (await stat2(oldFile).catch(() => null)) {
|
|
2228
|
-
await rename2(oldFile, rotatedFile);
|
|
2229
|
-
}
|
|
2230
|
-
}
|
|
2231
|
-
this.currentLogFile = newFile;
|
|
2232
|
-
if (config3.maxFiles) {
|
|
2233
|
-
const files = await readdir2(this.config.logDirectory);
|
|
2234
|
-
const logFiles = files.filter((f) => f.startsWith(this.name)).sort((a, b) => b.localeCompare(a));
|
|
2235
|
-
for (const file of logFiles.slice(config3.maxFiles)) {
|
|
2236
|
-
await unlink2(join5(this.config.logDirectory, file));
|
|
2237
|
-
}
|
|
2238
|
-
}
|
|
2239
|
-
}
|
|
2240
|
-
}
|
|
2241
|
-
async compressLogFile(inputPath, outputPath) {
|
|
2242
|
-
const readStream = createReadStream2(inputPath);
|
|
2243
|
-
const writeStream = createWriteStream2(outputPath);
|
|
2244
|
-
const gzip = createGzip2();
|
|
2245
|
-
await pipeline2(readStream, gzip, writeStream);
|
|
2246
|
-
}
|
|
2247
|
-
async handleFingersCrossedBuffer(level, formattedEntry) {
|
|
2248
|
-
if (!this.fingersCrossedConfig)
|
|
2249
|
-
return;
|
|
2250
|
-
if (this.shouldActivateFingersCrossed(level) && !this.isActivated) {
|
|
2251
|
-
this.isActivated = true;
|
|
2252
|
-
for (const entry of this.logBuffer) {
|
|
2253
|
-
const formattedBufferedEntry = await this.formatter.format(entry);
|
|
2254
|
-
await this.writeToFile(formattedBufferedEntry);
|
|
2255
|
-
console.log(formattedBufferedEntry);
|
|
2256
|
-
}
|
|
2257
|
-
if (this.fingersCrossedConfig.stopBuffering)
|
|
2258
|
-
this.logBuffer = [];
|
|
2259
|
-
}
|
|
2260
|
-
if (this.isActivated) {
|
|
2261
|
-
await this.writeToFile(formattedEntry);
|
|
2262
|
-
console.log(formattedEntry);
|
|
2263
|
-
} else {
|
|
2264
|
-
if (this.logBuffer.length >= this.fingersCrossedConfig.bufferSize)
|
|
2265
|
-
this.logBuffer.shift();
|
|
2266
|
-
const entry = {
|
|
2267
|
-
timestamp: new Date,
|
|
2268
|
-
level,
|
|
2269
|
-
message: formattedEntry,
|
|
2270
|
-
name: this.name
|
|
2271
|
-
};
|
|
2272
|
-
this.logBuffer.push(entry);
|
|
2273
|
-
}
|
|
2274
|
-
}
|
|
2275
|
-
shouldActivateFingersCrossed(level) {
|
|
2276
|
-
if (!this.fingersCrossedConfig)
|
|
2277
|
-
return false;
|
|
2278
|
-
return this.getLevelValue(level) >= this.getLevelValue(this.fingersCrossedConfig.activationLevel);
|
|
2279
|
-
}
|
|
2280
|
-
getLevelValue(level) {
|
|
2281
|
-
const levels = {
|
|
2282
|
-
debug: 0,
|
|
2283
|
-
info: 1,
|
|
2284
|
-
success: 2,
|
|
2285
|
-
warning: 3,
|
|
2286
|
-
error: 4
|
|
2287
|
-
};
|
|
2288
|
-
return levels[level];
|
|
2289
|
-
}
|
|
2290
|
-
shouldLog(level) {
|
|
2291
|
-
if (!this.enabled)
|
|
2292
|
-
return false;
|
|
2293
|
-
const levels = {
|
|
2294
|
-
debug: 0,
|
|
2295
|
-
info: 1,
|
|
2296
|
-
success: 2,
|
|
2297
|
-
warning: 3,
|
|
2298
|
-
error: 4
|
|
2299
|
-
};
|
|
2300
|
-
return levels[level] >= levels[this.config.level];
|
|
2301
|
-
}
|
|
2302
|
-
async flushPendingWrites() {
|
|
2303
|
-
await Promise.all(this.pendingOperations.map((op) => {
|
|
2304
|
-
if (op instanceof Promise) {
|
|
2305
|
-
return op.catch((err) => {
|
|
2306
|
-
console.error("Error in pending write operation:", err);
|
|
2307
|
-
});
|
|
2308
|
-
}
|
|
2309
|
-
return Promise.resolve();
|
|
2310
|
-
}));
|
|
2311
|
-
if (existsSync4(this.currentLogFile)) {
|
|
2312
|
-
try {
|
|
2313
|
-
const fd = openSync2(this.currentLogFile, "r+");
|
|
2314
|
-
fsyncSync2(fd);
|
|
2315
|
-
closeSync2(fd);
|
|
2316
|
-
} catch (error) {
|
|
2317
|
-
console.error(`Error flushing file: ${error}`);
|
|
2318
|
-
}
|
|
2319
|
-
}
|
|
2320
|
-
}
|
|
2321
|
-
async destroy() {
|
|
2322
|
-
if (this.rotationTimeout)
|
|
2323
|
-
clearInterval(this.rotationTimeout);
|
|
2324
|
-
if (this.keyRotationTimeout)
|
|
2325
|
-
clearInterval(this.keyRotationTimeout);
|
|
2326
|
-
this.timers.clear();
|
|
2327
|
-
for (const op of this.pendingOperations) {
|
|
2328
|
-
if (typeof op.cancel === "function") {
|
|
2329
|
-
op.cancel();
|
|
2330
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
return (async () => {
|
|
2333
|
-
if (this.pendingOperations.length > 0) {
|
|
2334
|
-
try {
|
|
2335
|
-
await Promise.allSettled(this.pendingOperations);
|
|
2336
|
-
} catch (err) {
|
|
2337
|
-
console.error("Error waiting for pending operations:", err);
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
if (!isBrowserProcess2() && this.config.rotation && typeof this.config.rotation !== "boolean" && this.config.rotation.compress) {
|
|
2341
|
-
try {
|
|
2342
|
-
const files = await readdir2(this.config.logDirectory);
|
|
2343
|
-
const tempFiles = files.filter((f) => (f.includes("temp") || f.includes(".tmp")) && f.includes(this.name));
|
|
2344
|
-
for (const tempFile of tempFiles) {
|
|
2345
|
-
try {
|
|
2346
|
-
await unlink2(join5(this.config.logDirectory, tempFile));
|
|
2347
|
-
} catch (err) {
|
|
2348
|
-
console.error(`Failed to delete temp file ${tempFile}:`, err);
|
|
2349
|
-
}
|
|
2350
|
-
}
|
|
2351
|
-
} catch (err) {
|
|
2352
|
-
console.error("Error cleaning up temporary files:", err);
|
|
2353
|
-
}
|
|
2354
|
-
}
|
|
2355
|
-
})();
|
|
2356
|
-
}
|
|
2357
|
-
getCurrentLogFilePath() {
|
|
2358
|
-
return this.currentLogFile;
|
|
2359
|
-
}
|
|
2360
|
-
formatTag(name) {
|
|
2361
|
-
if (!name)
|
|
2362
|
-
return "";
|
|
2363
|
-
return `${this.tagFormat.prefix}${name}${this.tagFormat.suffix}`;
|
|
2364
|
-
}
|
|
2365
|
-
formatFileTimestamp(date) {
|
|
2366
|
-
return `[${date.toISOString()}]`;
|
|
2367
|
-
}
|
|
2368
|
-
formatConsoleTimestamp(date) {
|
|
2369
|
-
return this.fancy ? styles2.gray(date.toLocaleTimeString()) : date.toLocaleTimeString();
|
|
2370
|
-
}
|
|
2371
|
-
formatConsoleMessage(parts) {
|
|
2372
|
-
const { timestamp, icon = "", tag = "", message, level, showTimestamp = true } = parts;
|
|
2373
|
-
const stripAnsi = (str) => str.replace(this.ANSI_PATTERN, "");
|
|
2374
|
-
if (!this.fancy) {
|
|
2375
|
-
const components = [];
|
|
2376
|
-
if (showTimestamp)
|
|
2377
|
-
components.push(timestamp);
|
|
2378
|
-
if (level === "warning")
|
|
2379
|
-
components.push("WARN");
|
|
2380
|
-
else if (level === "error")
|
|
2381
|
-
components.push("ERROR");
|
|
2382
|
-
else if (icon)
|
|
2383
|
-
components.push(icon.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu, ""));
|
|
2384
|
-
if (tag)
|
|
2385
|
-
components.push(tag.replace(/[[\]]/g, ""));
|
|
2386
|
-
components.push(message);
|
|
2387
|
-
return components.join(" ");
|
|
2388
|
-
}
|
|
2389
|
-
const terminalWidth = process11.stdout.columns || 120;
|
|
2390
|
-
let mainPart = "";
|
|
2391
|
-
if (level === "warning" || level === "error") {
|
|
2392
|
-
mainPart = `${icon} ${message}`;
|
|
2393
|
-
} else if (level === "info" || level === "success") {
|
|
2394
|
-
mainPart = `${icon} ${tag} ${message}`;
|
|
2395
|
-
} else {
|
|
2396
|
-
mainPart = `${icon} ${tag} ${styles2.cyan(message)}`;
|
|
2397
|
-
}
|
|
2398
|
-
if (!showTimestamp) {
|
|
2399
|
-
return mainPart.trim();
|
|
2400
|
-
}
|
|
2401
|
-
const visibleMainPartLength = stripAnsi(mainPart).trim().length;
|
|
2402
|
-
const visibleTimestampLength = stripAnsi(timestamp).length;
|
|
2403
|
-
const padding = Math.max(1, terminalWidth - 2 - visibleMainPartLength - visibleTimestampLength);
|
|
2404
|
-
return `${mainPart.trim()}${" ".repeat(padding)}${timestamp}`;
|
|
2405
|
-
}
|
|
2406
|
-
formatMessage(message, args) {
|
|
2407
|
-
if (args.length === 1 && Array.isArray(args[0])) {
|
|
2408
|
-
return message.replace(/\{(\d+)\}/g, (match, index) => {
|
|
2409
|
-
const position = Number.parseInt(index, 10);
|
|
2410
|
-
return position < args[0].length ? String(args[0][position]) : match;
|
|
2411
|
-
});
|
|
2412
|
-
}
|
|
2413
|
-
const formatRegex = /%([sdijfo%])/g;
|
|
2414
|
-
let argIndex = 0;
|
|
2415
|
-
let formattedMessage = message.replace(formatRegex, (match, type) => {
|
|
2416
|
-
if (type === "%")
|
|
2417
|
-
return "%";
|
|
2418
|
-
if (argIndex >= args.length)
|
|
2419
|
-
return match;
|
|
2420
|
-
const arg = args[argIndex++];
|
|
2421
|
-
switch (type) {
|
|
2422
|
-
case "s":
|
|
2423
|
-
return String(arg);
|
|
2424
|
-
case "d":
|
|
2425
|
-
case "i":
|
|
2426
|
-
return Number(arg).toString();
|
|
2427
|
-
case "j":
|
|
2428
|
-
case "o":
|
|
2429
|
-
return JSON.stringify(arg, null, 2);
|
|
2430
|
-
default:
|
|
2431
|
-
return match;
|
|
2432
|
-
}
|
|
2433
|
-
});
|
|
2434
|
-
if (argIndex < args.length) {
|
|
2435
|
-
formattedMessage += ` ${args.slice(argIndex).map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ")}`;
|
|
2436
|
-
}
|
|
2437
|
-
return formattedMessage;
|
|
2438
|
-
}
|
|
2439
|
-
async log(level, message, ...args) {
|
|
2440
|
-
const timestamp = new Date;
|
|
2441
|
-
const consoleTime = this.formatConsoleTimestamp(timestamp);
|
|
2442
|
-
const fileTime = this.formatFileTimestamp(timestamp);
|
|
2443
|
-
let formattedMessage;
|
|
2444
|
-
let errorStack;
|
|
2445
|
-
if (message instanceof Error) {
|
|
2446
|
-
formattedMessage = message.message;
|
|
2447
|
-
errorStack = message.stack;
|
|
2448
|
-
} else {
|
|
2449
|
-
formattedMessage = this.formatMessage(message, args);
|
|
2450
|
-
}
|
|
2451
|
-
if (this.fancy && !isBrowserProcess2()) {
|
|
2452
|
-
const icon = levelIcons2[level];
|
|
2453
|
-
const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
|
|
2454
|
-
let consoleMessage;
|
|
2455
|
-
switch (level) {
|
|
2456
|
-
case "debug":
|
|
2457
|
-
consoleMessage = this.formatConsoleMessage({
|
|
2458
|
-
timestamp: consoleTime,
|
|
2459
|
-
icon,
|
|
2460
|
-
tag,
|
|
2461
|
-
message: styles2.gray(formattedMessage),
|
|
2462
|
-
level
|
|
2463
|
-
});
|
|
2464
|
-
console.error(consoleMessage);
|
|
2465
|
-
break;
|
|
2466
|
-
case "info":
|
|
2467
|
-
consoleMessage = this.formatConsoleMessage({
|
|
2468
|
-
timestamp: consoleTime,
|
|
2469
|
-
icon,
|
|
2470
|
-
tag,
|
|
2471
|
-
message: formattedMessage,
|
|
2472
|
-
level
|
|
2473
|
-
});
|
|
2474
|
-
console.error(consoleMessage);
|
|
2475
|
-
break;
|
|
2476
|
-
case "success":
|
|
2477
|
-
consoleMessage = this.formatConsoleMessage({
|
|
2478
|
-
timestamp: consoleTime,
|
|
2479
|
-
icon,
|
|
2480
|
-
tag,
|
|
2481
|
-
message: styles2.green(formattedMessage),
|
|
2482
|
-
level
|
|
2483
|
-
});
|
|
2484
|
-
console.error(consoleMessage);
|
|
2485
|
-
break;
|
|
2486
|
-
case "warning":
|
|
2487
|
-
consoleMessage = this.formatConsoleMessage({
|
|
2488
|
-
timestamp: consoleTime,
|
|
2489
|
-
icon,
|
|
2490
|
-
tag,
|
|
2491
|
-
message: formattedMessage,
|
|
2492
|
-
level
|
|
2493
|
-
});
|
|
2494
|
-
console.warn(consoleMessage);
|
|
2495
|
-
break;
|
|
2496
|
-
case "error":
|
|
2497
|
-
consoleMessage = this.formatConsoleMessage({
|
|
2498
|
-
timestamp: consoleTime,
|
|
2499
|
-
icon,
|
|
2500
|
-
tag,
|
|
2501
|
-
message: formattedMessage,
|
|
2502
|
-
level
|
|
2503
|
-
});
|
|
2504
|
-
console.error(consoleMessage);
|
|
2505
|
-
if (errorStack) {
|
|
2506
|
-
const stackLines = errorStack.split(`
|
|
2507
|
-
`);
|
|
2508
|
-
for (const line of stackLines) {
|
|
2509
|
-
if (line.trim() && !line.includes(formattedMessage)) {
|
|
2510
|
-
console.error(this.formatConsoleMessage({
|
|
2511
|
-
timestamp: consoleTime,
|
|
2512
|
-
message: styles2.gray(` ${line}`),
|
|
2513
|
-
level,
|
|
2514
|
-
showTimestamp: false
|
|
2515
|
-
}));
|
|
2516
|
-
}
|
|
2517
|
-
}
|
|
2518
|
-
}
|
|
2519
|
-
break;
|
|
2520
|
-
}
|
|
2521
|
-
} else if (!isBrowserProcess2()) {
|
|
2522
|
-
console.error(`${fileTime} ${this.environment}.${level.toUpperCase()}: ${formattedMessage}`);
|
|
2523
|
-
if (errorStack) {
|
|
2524
|
-
console.error(errorStack);
|
|
2525
|
-
}
|
|
2526
|
-
}
|
|
2527
|
-
if (!this.shouldLog(level))
|
|
2528
|
-
return;
|
|
2529
|
-
let logEntry = `${fileTime} ${this.environment}.${level.toUpperCase()}: ${formattedMessage}
|
|
2530
|
-
`;
|
|
2531
|
-
if (errorStack) {
|
|
2532
|
-
logEntry += `${errorStack}
|
|
2533
|
-
`;
|
|
2534
|
-
}
|
|
2535
|
-
logEntry = logEntry.replace(this.ANSI_PATTERN, "");
|
|
2536
|
-
await this.writeToFile(logEntry);
|
|
2537
|
-
}
|
|
2538
|
-
time(label) {
|
|
2539
|
-
const start = performance.now();
|
|
2540
|
-
if (this.fancy && !isBrowserProcess2()) {
|
|
2541
|
-
const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
|
|
2542
|
-
const consoleTime = this.formatConsoleTimestamp(new Date);
|
|
2543
|
-
console.error(this.formatConsoleMessage({
|
|
2544
|
-
timestamp: consoleTime,
|
|
2545
|
-
icon: styles2.blue("\u25D0"),
|
|
2546
|
-
tag,
|
|
2547
|
-
message: `${styles2.cyan(label)}...`
|
|
2548
|
-
}));
|
|
2549
|
-
}
|
|
2550
|
-
return async (metadata) => {
|
|
2551
|
-
if (!this.enabled)
|
|
2552
|
-
return;
|
|
2553
|
-
const end = performance.now();
|
|
2554
|
-
const elapsed = Math.round(end - start);
|
|
2555
|
-
const completionMessage = `${label} completed in ${elapsed}ms`;
|
|
2556
|
-
const timestamp = new Date;
|
|
2557
|
-
const consoleTime = this.formatConsoleTimestamp(timestamp);
|
|
2558
|
-
const fileTime = this.formatFileTimestamp(timestamp);
|
|
2559
|
-
let logEntry = `${fileTime} ${this.environment}.INFO: ${completionMessage}`;
|
|
2560
|
-
if (metadata) {
|
|
2561
|
-
logEntry += ` ${JSON.stringify(metadata)}`;
|
|
2562
|
-
}
|
|
2563
|
-
logEntry += `
|
|
2564
|
-
`;
|
|
2565
|
-
logEntry = logEntry.replace(this.ANSI_PATTERN, "");
|
|
2566
|
-
if (this.fancy && !isBrowserProcess2()) {
|
|
2567
|
-
const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
|
|
2568
|
-
console.error(this.formatConsoleMessage({
|
|
2569
|
-
timestamp: consoleTime,
|
|
2570
|
-
icon: styles2.green("\u2713"),
|
|
2571
|
-
tag,
|
|
2572
|
-
message: `${completionMessage}${metadata ? ` ${JSON.stringify(metadata)}` : ""}`
|
|
2573
|
-
}));
|
|
2574
|
-
} else if (!isBrowserProcess2()) {
|
|
2575
|
-
console.error(logEntry.trim());
|
|
2576
|
-
}
|
|
2577
|
-
await this.writeToFile(logEntry);
|
|
2578
|
-
};
|
|
2579
|
-
}
|
|
2580
|
-
async debug(message, ...args) {
|
|
2581
|
-
await this.log("debug", message, ...args);
|
|
2582
|
-
}
|
|
2583
|
-
async info(message, ...args) {
|
|
2584
|
-
await this.log("info", message, ...args);
|
|
2585
|
-
}
|
|
2586
|
-
async success(message, ...args) {
|
|
2587
|
-
await this.log("success", message, ...args);
|
|
2588
|
-
}
|
|
2589
|
-
async warn(message, ...args) {
|
|
2590
|
-
await this.log("warning", message, ...args);
|
|
2591
|
-
}
|
|
2592
|
-
async error(message, ...args) {
|
|
2593
|
-
await this.log("error", message, ...args);
|
|
2594
|
-
}
|
|
2595
|
-
validateEncryptionConfig() {
|
|
2596
|
-
if (!this.config.rotation)
|
|
2597
|
-
return false;
|
|
2598
|
-
if (typeof this.config.rotation === "boolean")
|
|
2599
|
-
return false;
|
|
2600
|
-
const rotation = this.config.rotation;
|
|
2601
|
-
const { encrypt } = rotation;
|
|
2602
|
-
return !!encrypt;
|
|
2603
|
-
}
|
|
2604
|
-
async only(fn) {
|
|
2605
|
-
if (!this.enabled)
|
|
2606
|
-
return;
|
|
2607
|
-
return await fn();
|
|
2608
|
-
}
|
|
2609
|
-
isEnabled() {
|
|
2610
|
-
return this.enabled;
|
|
2611
|
-
}
|
|
2612
|
-
setEnabled(enabled) {
|
|
2613
|
-
this.enabled = enabled;
|
|
2614
|
-
}
|
|
2615
|
-
extend(namespace) {
|
|
2616
|
-
const childName = `${this.name}:${namespace}`;
|
|
2617
|
-
const childLogger = new Logger2(childName, {
|
|
2618
|
-
...this.options,
|
|
2619
|
-
logDirectory: this.config.logDirectory,
|
|
2620
|
-
level: this.config.level,
|
|
2621
|
-
format: this.config.format,
|
|
2622
|
-
rotation: typeof this.config.rotation === "boolean" ? undefined : this.config.rotation,
|
|
2623
|
-
timestamp: typeof this.config.timestamp === "boolean" ? undefined : this.config.timestamp
|
|
2624
|
-
});
|
|
2625
|
-
this.subLoggers.add(childLogger);
|
|
2626
|
-
return childLogger;
|
|
2627
|
-
}
|
|
2628
|
-
createReadStream() {
|
|
2629
|
-
if (isBrowserProcess2())
|
|
2630
|
-
throw new Error("createReadStream is not supported in browser environments");
|
|
2631
|
-
if (!existsSync4(this.currentLogFile))
|
|
2632
|
-
throw new Error(`Log file does not exist: ${this.currentLogFile}`);
|
|
2633
|
-
return createReadStream2(this.currentLogFile, { encoding: "utf8" });
|
|
2634
|
-
}
|
|
2635
|
-
async decrypt(data) {
|
|
2636
|
-
if (!this.validateEncryptionConfig())
|
|
2637
|
-
throw new Error("Encryption is not configured");
|
|
2638
|
-
const encryptionConfig = this.config.rotation;
|
|
2639
|
-
if (!encryptionConfig.encrypt || typeof encryptionConfig.encrypt === "boolean")
|
|
2640
|
-
throw new Error("Invalid encryption configuration");
|
|
2641
|
-
if (!this.currentKeyId || !this.keys.has(this.currentKeyId))
|
|
2642
|
-
throw new Error("No valid encryption key available");
|
|
2643
|
-
const key = this.keys.get(this.currentKeyId);
|
|
2644
|
-
try {
|
|
2645
|
-
const encryptedData = Buffer2.isBuffer(data) ? data : Buffer2.from(data, "base64");
|
|
2646
|
-
const iv = encryptedData.slice(0, 16);
|
|
2647
|
-
const authTag = encryptedData.slice(-16);
|
|
2648
|
-
const ciphertext = encryptedData.slice(16, -16);
|
|
2649
|
-
const decipher = createDecipheriv2("aes-256-gcm", key, iv);
|
|
2650
|
-
decipher.setAuthTag(authTag);
|
|
2651
|
-
const decrypted = Buffer2.concat([
|
|
2652
|
-
decipher.update(ciphertext),
|
|
2653
|
-
decipher.final()
|
|
2654
|
-
]);
|
|
2655
|
-
return decrypted.toString("utf8");
|
|
2656
|
-
} catch (err) {
|
|
2657
|
-
throw new Error(`Decryption failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
2658
|
-
}
|
|
2659
|
-
}
|
|
2660
|
-
getLevel() {
|
|
2661
|
-
return this.config.level;
|
|
2662
|
-
}
|
|
2663
|
-
getLogDirectory() {
|
|
2664
|
-
return this.config.logDirectory;
|
|
2665
|
-
}
|
|
2666
|
-
getFormat() {
|
|
2667
|
-
return this.config.format;
|
|
2668
|
-
}
|
|
2669
|
-
getRotationConfig() {
|
|
2670
|
-
return this.config.rotation;
|
|
2671
|
-
}
|
|
2672
|
-
isBrowserMode() {
|
|
2673
|
-
return isBrowserProcess2();
|
|
2674
|
-
}
|
|
2675
|
-
isServerMode() {
|
|
2676
|
-
return !isBrowserProcess2();
|
|
2677
|
-
}
|
|
2678
|
-
setTestEncryptionKey(keyId, key) {
|
|
2679
|
-
this.currentKeyId = keyId;
|
|
2680
|
-
this.keys.set(keyId, key);
|
|
2681
|
-
}
|
|
2682
|
-
getTestCurrentKey() {
|
|
2683
|
-
if (!this.currentKeyId || !this.keys.has(this.currentKeyId)) {
|
|
2684
|
-
return null;
|
|
2685
|
-
}
|
|
2686
|
-
return {
|
|
2687
|
-
id: this.currentKeyId,
|
|
2688
|
-
key: this.keys.get(this.currentKeyId)
|
|
2689
|
-
};
|
|
2690
|
-
}
|
|
2691
|
-
getConfig() {
|
|
2692
|
-
return this.config;
|
|
2693
|
-
}
|
|
2694
|
-
async box(message) {
|
|
2695
|
-
if (!this.enabled)
|
|
2696
|
-
return;
|
|
2697
|
-
const timestamp = new Date;
|
|
2698
|
-
const consoleTime = this.formatConsoleTimestamp(timestamp);
|
|
2699
|
-
const fileTime = this.formatFileTimestamp(timestamp);
|
|
2700
|
-
if (this.fancy && !isBrowserProcess2()) {
|
|
2701
|
-
const lines = message.split(`
|
|
2702
|
-
`);
|
|
2703
|
-
const width = Math.max(...lines.map((line) => line.length)) + 2;
|
|
2704
|
-
const top = `\u250C${"\u2500".repeat(width)}\u2510`;
|
|
2705
|
-
const bottom = `\u2514${"\u2500".repeat(width)}\u2518`;
|
|
2706
|
-
const boxedLines = lines.map((line) => {
|
|
2707
|
-
const padding = " ".repeat(width - line.length - 2);
|
|
2708
|
-
return `\u2502 ${line}${padding} \u2502`;
|
|
2709
|
-
});
|
|
2710
|
-
if (this.options.showTags !== false && this.name) {
|
|
2711
|
-
console.error(this.formatConsoleMessage({
|
|
2712
|
-
timestamp: consoleTime,
|
|
2713
|
-
message: styles2.gray(this.formatTag(this.name)),
|
|
2714
|
-
showTimestamp: false
|
|
2715
|
-
}));
|
|
2716
|
-
}
|
|
2717
|
-
console.error(this.formatConsoleMessage({
|
|
2718
|
-
timestamp: consoleTime,
|
|
2719
|
-
message: styles2.cyan(top)
|
|
2720
|
-
}));
|
|
2721
|
-
boxedLines.forEach((line) => console.error(this.formatConsoleMessage({
|
|
2722
|
-
timestamp: consoleTime,
|
|
2723
|
-
message: styles2.cyan(line),
|
|
2724
|
-
showTimestamp: false
|
|
2725
|
-
})));
|
|
2726
|
-
console.error(this.formatConsoleMessage({
|
|
2727
|
-
timestamp: consoleTime,
|
|
2728
|
-
message: styles2.cyan(bottom),
|
|
2729
|
-
showTimestamp: false
|
|
2730
|
-
}));
|
|
2731
|
-
} else if (!isBrowserProcess2()) {
|
|
2732
|
-
console.error(`${fileTime} ${this.environment}.INFO: [BOX] ${message}`);
|
|
2733
|
-
}
|
|
2734
|
-
const logEntry = `${fileTime} ${this.environment}.INFO: [BOX] ${message}
|
|
2735
|
-
`.replace(this.ANSI_PATTERN, "");
|
|
2736
|
-
await this.writeToFile(logEntry);
|
|
2737
|
-
}
|
|
2738
|
-
async prompt(message) {
|
|
2739
|
-
if (isBrowserProcess2()) {
|
|
2740
|
-
return Promise.resolve(true);
|
|
2741
|
-
}
|
|
2742
|
-
return new Promise((resolve5) => {
|
|
2743
|
-
console.error(`${styles2.cyan("?")} ${message} (y/n) `);
|
|
2744
|
-
const onData = (data) => {
|
|
2745
|
-
const input = data.toString().trim().toLowerCase();
|
|
2746
|
-
process11.stdin.removeListener("data", onData);
|
|
2747
|
-
try {
|
|
2748
|
-
if (typeof process11.stdin.setRawMode === "function") {
|
|
2749
|
-
process11.stdin.setRawMode(false);
|
|
2750
|
-
}
|
|
2751
|
-
} catch {}
|
|
2752
|
-
process11.stdin.pause();
|
|
2753
|
-
console.error("");
|
|
2754
|
-
resolve5(input === "y" || input === "yes");
|
|
2755
|
-
};
|
|
2756
|
-
try {
|
|
2757
|
-
if (typeof process11.stdin.setRawMode === "function") {
|
|
2758
|
-
process11.stdin.setRawMode(true);
|
|
2759
|
-
}
|
|
2760
|
-
} catch {}
|
|
2761
|
-
process11.stdin.resume();
|
|
2762
|
-
process11.stdin.once("data", onData);
|
|
2763
|
-
});
|
|
2764
|
-
}
|
|
2765
|
-
setFancy(enabled) {
|
|
2766
|
-
this.fancy = enabled;
|
|
2767
|
-
}
|
|
2768
|
-
isFancy() {
|
|
2769
|
-
return this.fancy;
|
|
2770
|
-
}
|
|
2771
|
-
pause() {
|
|
2772
|
-
this.enabled = false;
|
|
2773
|
-
}
|
|
2774
|
-
resume() {
|
|
2775
|
-
this.enabled = true;
|
|
2776
|
-
}
|
|
2777
|
-
async start(message, ...args) {
|
|
2778
|
-
if (!this.enabled)
|
|
2779
|
-
return;
|
|
2780
|
-
let formattedMessage = message;
|
|
2781
|
-
if (args && args.length > 0) {
|
|
2782
|
-
const formatRegex = /%([sdijfo%])/g;
|
|
2783
|
-
let argIndex = 0;
|
|
2784
|
-
formattedMessage = message.replace(formatRegex, (match, type) => {
|
|
2785
|
-
if (type === "%")
|
|
2786
|
-
return "%";
|
|
2787
|
-
if (argIndex >= args.length)
|
|
2788
|
-
return match;
|
|
2789
|
-
const arg = args[argIndex++];
|
|
2790
|
-
switch (type) {
|
|
2791
|
-
case "s":
|
|
2792
|
-
return String(arg);
|
|
2793
|
-
case "d":
|
|
2794
|
-
case "i":
|
|
2795
|
-
return Number(arg).toString();
|
|
2796
|
-
case "j":
|
|
2797
|
-
case "o":
|
|
2798
|
-
return JSON.stringify(arg, null, 2);
|
|
2799
|
-
default:
|
|
2800
|
-
return match;
|
|
2801
|
-
}
|
|
2802
|
-
});
|
|
2803
|
-
if (argIndex < args.length) {
|
|
2804
|
-
formattedMessage += ` ${args.slice(argIndex).map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ")}`;
|
|
2805
|
-
}
|
|
2806
|
-
}
|
|
2807
|
-
if (this.fancy && !isBrowserProcess2()) {
|
|
2808
|
-
const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
|
|
2809
|
-
const spinnerChar = styles2.blue("\u25D0");
|
|
2810
|
-
console.error(`${spinnerChar} ${tag} ${styles2.cyan(formattedMessage)}`);
|
|
2811
|
-
}
|
|
2812
|
-
const timestamp = new Date;
|
|
2813
|
-
const formattedDate = timestamp.toISOString();
|
|
2814
|
-
const logEntry = `[${formattedDate}] ${this.environment}.INFO: [START] ${formattedMessage}
|
|
2815
|
-
`.replace(this.ANSI_PATTERN, "");
|
|
2816
|
-
await this.writeToFile(logEntry);
|
|
2817
|
-
}
|
|
2818
|
-
progress(total, initialMessage = "") {
|
|
2819
|
-
if (!this.enabled || !this.fancy || isBrowserProcess2() || total <= 0) {
|
|
2820
|
-
return {
|
|
2821
|
-
update: () => {},
|
|
2822
|
-
finish: () => {},
|
|
2823
|
-
interrupt: () => {}
|
|
2824
|
-
};
|
|
2825
|
-
}
|
|
2826
|
-
if (this.activeProgressBar) {
|
|
2827
|
-
console.warn("Warning: Another progress bar is already active. Finishing the previous one.");
|
|
2828
|
-
this.finishProgressBar(this.activeProgressBar, "[Auto-finished]");
|
|
2829
|
-
}
|
|
2830
|
-
const barLength = 20;
|
|
2831
|
-
this.activeProgressBar = {
|
|
2832
|
-
total,
|
|
2833
|
-
current: 0,
|
|
2834
|
-
message: initialMessage,
|
|
2835
|
-
barLength,
|
|
2836
|
-
lastRenderedLine: ""
|
|
2837
|
-
};
|
|
2838
|
-
this.renderProgressBar(this.activeProgressBar);
|
|
2839
|
-
const update = (current, message) => {
|
|
2840
|
-
if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess2())
|
|
2841
|
-
return;
|
|
2842
|
-
this.activeProgressBar.current = Math.max(0, Math.min(total, current));
|
|
2843
|
-
if (message !== undefined) {
|
|
2844
|
-
this.activeProgressBar.message = message;
|
|
2845
|
-
}
|
|
2846
|
-
const isFinished = this.activeProgressBar.current === this.activeProgressBar.total;
|
|
2847
|
-
this.renderProgressBar(this.activeProgressBar, isFinished);
|
|
2848
|
-
};
|
|
2849
|
-
const finish = (message) => {
|
|
2850
|
-
if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess2())
|
|
2851
|
-
return;
|
|
2852
|
-
this.activeProgressBar.current = this.activeProgressBar.total;
|
|
2853
|
-
if (message !== undefined) {
|
|
2854
|
-
this.activeProgressBar.message = message;
|
|
2855
|
-
}
|
|
2856
|
-
this.renderProgressBar(this.activeProgressBar, true);
|
|
2857
|
-
this.finishProgressBar(this.activeProgressBar);
|
|
2858
|
-
};
|
|
2859
|
-
const interrupt = (interruptMessage, level = "info") => {
|
|
2860
|
-
if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess2())
|
|
2861
|
-
return;
|
|
2862
|
-
process11.stdout.write(`${"\r".padEnd(process11.stdout.columns || 80)}\r`);
|
|
2863
|
-
this.log(level, interruptMessage);
|
|
2864
|
-
setTimeout(() => {
|
|
2865
|
-
if (this.activeProgressBar) {
|
|
2866
|
-
this.renderProgressBar(this.activeProgressBar);
|
|
2867
|
-
}
|
|
2868
|
-
}, 50);
|
|
2869
|
-
};
|
|
2870
|
-
return { update, finish, interrupt };
|
|
2871
|
-
}
|
|
2872
|
-
renderProgressBar(barState, isFinished = false) {
|
|
2873
|
-
if (!this.enabled || !this.fancy || isBrowserProcess2() || !process11.stdout.isTTY)
|
|
2874
|
-
return;
|
|
2875
|
-
const percent = Math.min(100, Math.max(0, Math.round(barState.current / barState.total * 100)));
|
|
2876
|
-
const filledLength = Math.round(barState.barLength * percent / 100);
|
|
2877
|
-
const emptyLength = barState.barLength - filledLength;
|
|
2878
|
-
const filledBar = styles2.green("\u2501".repeat(filledLength));
|
|
2879
|
-
const emptyBar = styles2.gray("\u2501".repeat(emptyLength));
|
|
2880
|
-
const bar = `[${filledBar}${emptyBar}]`;
|
|
2881
|
-
const percentageText = `${percent}%`.padStart(4);
|
|
2882
|
-
const messageText = barState.message ? ` ${barState.message}` : "";
|
|
2883
|
-
const icon = isFinished || percent === 100 ? styles2.green("\u2713") : styles2.blue("\u25B6");
|
|
2884
|
-
const tag = this.options.showTags !== false && this.name ? ` ${styles2.gray(this.formatTag(this.name))}` : "";
|
|
2885
|
-
const line = `\r${icon}${tag} ${bar} ${percentageText}${messageText}`;
|
|
2886
|
-
const terminalWidth = process11.stdout.columns || 80;
|
|
2887
|
-
const clearLine = " ".repeat(Math.max(0, terminalWidth - line.replace(this.ANSI_PATTERN, "").length));
|
|
2888
|
-
barState.lastRenderedLine = `${line}${clearLine}`;
|
|
2889
|
-
process11.stdout.write(barState.lastRenderedLine);
|
|
2890
|
-
if (isFinished) {
|
|
2891
|
-
process11.stdout.write(`
|
|
2892
|
-
`);
|
|
2893
|
-
}
|
|
2894
|
-
}
|
|
2895
|
-
finishProgressBar(barState, finalMessage) {
|
|
2896
|
-
if (!this.enabled || !this.fancy || isBrowserProcess2() || !process11.stdout.isTTY) {
|
|
2897
|
-
this.activeProgressBar = null;
|
|
2898
|
-
return;
|
|
2899
|
-
}
|
|
2900
|
-
if (barState.current < barState.total) {
|
|
2901
|
-
barState.current = barState.total;
|
|
2902
|
-
}
|
|
2903
|
-
if (finalMessage)
|
|
2904
|
-
barState.message = finalMessage;
|
|
2905
|
-
this.renderProgressBar(barState, true);
|
|
2906
|
-
this.activeProgressBar = null;
|
|
2907
|
-
}
|
|
2908
|
-
async clear(filters = {}) {
|
|
2909
|
-
if (isBrowserProcess2()) {
|
|
2910
|
-
console.warn("Log clearing is not supported in browser environments.");
|
|
2911
|
-
return;
|
|
2912
|
-
}
|
|
2913
|
-
try {
|
|
2914
|
-
console.warn("Clearing logs...", this.config.logDirectory);
|
|
2915
|
-
const files = await readdir2(this.config.logDirectory);
|
|
2916
|
-
const logFilesToDelete = [];
|
|
2917
|
-
for (const file of files) {
|
|
2918
|
-
const nameMatches = filters.name ? new RegExp(filters.name.replace("*", ".*")).test(file) : file.startsWith(this.name);
|
|
2919
|
-
if (!nameMatches || !file.endsWith(".log")) {
|
|
2920
|
-
continue;
|
|
2921
|
-
}
|
|
2922
|
-
const filePath = join5(this.config.logDirectory, file);
|
|
2923
|
-
if (filters.before) {
|
|
2924
|
-
try {
|
|
2925
|
-
const fileStats = await stat2(filePath);
|
|
2926
|
-
if (fileStats.mtime >= filters.before) {
|
|
2927
|
-
continue;
|
|
2928
|
-
}
|
|
2929
|
-
} catch (statErr) {
|
|
2930
|
-
console.error(`Failed to get stats for file ${filePath}:`, statErr);
|
|
2931
|
-
continue;
|
|
2932
|
-
}
|
|
2933
|
-
}
|
|
2934
|
-
logFilesToDelete.push(filePath);
|
|
2935
|
-
}
|
|
2936
|
-
if (logFilesToDelete.length === 0) {
|
|
2937
|
-
console.warn("No log files matched the criteria for clearing.");
|
|
2938
|
-
return;
|
|
2939
|
-
}
|
|
2940
|
-
console.warn(`Preparing to delete ${logFilesToDelete.length} log file(s)...`);
|
|
2941
|
-
for (const filePath of logFilesToDelete) {
|
|
2942
|
-
try {
|
|
2943
|
-
await unlink2(filePath);
|
|
2944
|
-
console.warn(`Deleted log file: ${filePath}`);
|
|
2945
|
-
} catch (unlinkErr) {
|
|
2946
|
-
console.error(`Failed to delete log file ${filePath}:`, unlinkErr);
|
|
2947
|
-
}
|
|
2948
|
-
}
|
|
2949
|
-
console.warn("Log clearing process finished.");
|
|
2950
|
-
} catch (err) {
|
|
2951
|
-
console.error("Error during log clearing process:", err);
|
|
2952
|
-
}
|
|
2953
|
-
}
|
|
2954
|
-
}
|
|
2955
|
-
var logger2 = new Logger2("stacks");
|
|
2956
|
-
|
|
2957
|
-
// node_modules/cac/dist/index.mjs
|
|
2958
|
-
import { EventEmitter } from "events";
|
|
2959
|
-
function toArr(any) {
|
|
2960
|
-
return any == null ? [] : Array.isArray(any) ? any : [any];
|
|
2961
|
-
}
|
|
2962
|
-
function toVal(out, key, val, opts) {
|
|
2963
|
-
var x, old = out[key], nxt = ~opts.string.indexOf(key) ? val == null || val === true ? "" : String(val) : typeof val === "boolean" ? val : ~opts.boolean.indexOf(key) ? val === "false" ? false : val === "true" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;
|
|
2964
|
-
out[key] = old == null ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];
|
|
2965
|
-
}
|
|
2966
|
-
function mri2(args, opts) {
|
|
2967
|
-
args = args || [];
|
|
2968
|
-
opts = opts || {};
|
|
2969
|
-
var k, arr, arg, name, val, out = { _: [] };
|
|
2970
|
-
var i = 0, j = 0, idx = 0, len = args.length;
|
|
2971
|
-
const alibi = opts.alias !== undefined;
|
|
2972
|
-
const strict = opts.unknown !== undefined;
|
|
2973
|
-
const defaults = opts.default !== undefined;
|
|
2974
|
-
opts.alias = opts.alias || {};
|
|
2975
|
-
opts.string = toArr(opts.string);
|
|
2976
|
-
opts.boolean = toArr(opts.boolean);
|
|
2977
|
-
if (alibi) {
|
|
2978
|
-
for (k in opts.alias) {
|
|
2979
|
-
arr = opts.alias[k] = toArr(opts.alias[k]);
|
|
2980
|
-
for (i = 0;i < arr.length; i++) {
|
|
2981
|
-
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
|
|
2982
|
-
}
|
|
2983
|
-
}
|
|
2984
|
-
}
|
|
2985
|
-
for (i = opts.boolean.length;i-- > 0; ) {
|
|
2986
|
-
arr = opts.alias[opts.boolean[i]] || [];
|
|
2987
|
-
for (j = arr.length;j-- > 0; )
|
|
2988
|
-
opts.boolean.push(arr[j]);
|
|
2989
|
-
}
|
|
2990
|
-
for (i = opts.string.length;i-- > 0; ) {
|
|
2991
|
-
arr = opts.alias[opts.string[i]] || [];
|
|
2992
|
-
for (j = arr.length;j-- > 0; )
|
|
2993
|
-
opts.string.push(arr[j]);
|
|
2994
|
-
}
|
|
2995
|
-
if (defaults) {
|
|
2996
|
-
for (k in opts.default) {
|
|
2997
|
-
name = typeof opts.default[k];
|
|
2998
|
-
arr = opts.alias[k] = opts.alias[k] || [];
|
|
2999
|
-
if (opts[name] !== undefined) {
|
|
3000
|
-
opts[name].push(k);
|
|
3001
|
-
for (i = 0;i < arr.length; i++) {
|
|
3002
|
-
opts[name].push(arr[i]);
|
|
3003
|
-
}
|
|
3004
|
-
}
|
|
3005
|
-
}
|
|
3006
|
-
}
|
|
3007
|
-
const keys = strict ? Object.keys(opts.alias) : [];
|
|
3008
|
-
for (i = 0;i < len; i++) {
|
|
3009
|
-
arg = args[i];
|
|
3010
|
-
if (arg === "--") {
|
|
3011
|
-
out._ = out._.concat(args.slice(++i));
|
|
3012
|
-
break;
|
|
3013
|
-
}
|
|
3014
|
-
for (j = 0;j < arg.length; j++) {
|
|
3015
|
-
if (arg.charCodeAt(j) !== 45)
|
|
3016
|
-
break;
|
|
3017
|
-
}
|
|
3018
|
-
if (j === 0) {
|
|
3019
|
-
out._.push(arg);
|
|
3020
|
-
} else if (arg.substring(j, j + 3) === "no-") {
|
|
3021
|
-
name = arg.substring(j + 3);
|
|
3022
|
-
if (strict && !~keys.indexOf(name)) {
|
|
3023
|
-
return opts.unknown(arg);
|
|
3024
|
-
}
|
|
3025
|
-
out[name] = false;
|
|
3026
|
-
} else {
|
|
3027
|
-
for (idx = j + 1;idx < arg.length; idx++) {
|
|
3028
|
-
if (arg.charCodeAt(idx) === 61)
|
|
3029
|
-
break;
|
|
3030
|
-
}
|
|
3031
|
-
name = arg.substring(j, idx);
|
|
3032
|
-
val = arg.substring(++idx) || (i + 1 === len || ("" + args[i + 1]).charCodeAt(0) === 45 || args[++i]);
|
|
3033
|
-
arr = j === 2 ? [name] : name;
|
|
3034
|
-
for (idx = 0;idx < arr.length; idx++) {
|
|
3035
|
-
name = arr[idx];
|
|
3036
|
-
if (strict && !~keys.indexOf(name))
|
|
3037
|
-
return opts.unknown("-".repeat(j) + name);
|
|
3038
|
-
toVal(out, name, idx + 1 < arr.length || val, opts);
|
|
3039
|
-
}
|
|
3040
|
-
}
|
|
3041
|
-
}
|
|
3042
|
-
if (defaults) {
|
|
3043
|
-
for (k in opts.default) {
|
|
3044
|
-
if (out[k] === undefined) {
|
|
3045
|
-
out[k] = opts.default[k];
|
|
3046
|
-
}
|
|
3047
|
-
}
|
|
3048
|
-
}
|
|
3049
|
-
if (alibi) {
|
|
3050
|
-
for (k in out) {
|
|
3051
|
-
arr = opts.alias[k] || [];
|
|
3052
|
-
while (arr.length > 0) {
|
|
3053
|
-
out[arr.shift()] = out[k];
|
|
3054
|
-
}
|
|
3055
|
-
}
|
|
3056
|
-
}
|
|
3057
|
-
return out;
|
|
3058
|
-
}
|
|
3059
|
-
var removeBrackets = (v) => v.replace(/[<[].+/, "").trim();
|
|
3060
|
-
var findAllBrackets = (v) => {
|
|
3061
|
-
const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
|
|
3062
|
-
const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
|
|
3063
|
-
const res = [];
|
|
3064
|
-
const parse = (match) => {
|
|
3065
|
-
let variadic = false;
|
|
3066
|
-
let value = match[1];
|
|
3067
|
-
if (value.startsWith("...")) {
|
|
3068
|
-
value = value.slice(3);
|
|
3069
|
-
variadic = true;
|
|
3070
|
-
}
|
|
3071
|
-
return {
|
|
3072
|
-
required: match[0].startsWith("<"),
|
|
3073
|
-
value,
|
|
3074
|
-
variadic
|
|
3075
|
-
};
|
|
3076
|
-
};
|
|
3077
|
-
let angledMatch;
|
|
3078
|
-
while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {
|
|
3079
|
-
res.push(parse(angledMatch));
|
|
3080
|
-
}
|
|
3081
|
-
let squareMatch;
|
|
3082
|
-
while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {
|
|
3083
|
-
res.push(parse(squareMatch));
|
|
3084
|
-
}
|
|
3085
|
-
return res;
|
|
3086
|
-
};
|
|
3087
|
-
var getMriOptions = (options) => {
|
|
3088
|
-
const result = { alias: {}, boolean: [] };
|
|
3089
|
-
for (const [index, option] of options.entries()) {
|
|
3090
|
-
if (option.names.length > 1) {
|
|
3091
|
-
result.alias[option.names[0]] = option.names.slice(1);
|
|
3092
|
-
}
|
|
3093
|
-
if (option.isBoolean) {
|
|
3094
|
-
if (option.negated) {
|
|
3095
|
-
const hasStringTypeOption = options.some((o, i) => {
|
|
3096
|
-
return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean";
|
|
3097
|
-
});
|
|
3098
|
-
if (!hasStringTypeOption) {
|
|
3099
|
-
result.boolean.push(option.names[0]);
|
|
3100
|
-
}
|
|
3101
|
-
} else {
|
|
3102
|
-
result.boolean.push(option.names[0]);
|
|
3103
|
-
}
|
|
3104
|
-
}
|
|
3105
|
-
}
|
|
3106
|
-
return result;
|
|
3107
|
-
};
|
|
3108
|
-
var findLongest = (arr) => {
|
|
3109
|
-
return arr.sort((a, b) => {
|
|
3110
|
-
return a.length > b.length ? -1 : 1;
|
|
3111
|
-
})[0];
|
|
3112
|
-
};
|
|
3113
|
-
var padRight = (str, length) => {
|
|
3114
|
-
return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
|
|
3115
|
-
};
|
|
3116
|
-
var camelcase = (input) => {
|
|
3117
|
-
return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => {
|
|
3118
|
-
return p1 + p2.toUpperCase();
|
|
3119
|
-
});
|
|
3120
|
-
};
|
|
3121
|
-
var setDotProp = (obj, keys, val) => {
|
|
3122
|
-
let i = 0;
|
|
3123
|
-
let length = keys.length;
|
|
3124
|
-
let t = obj;
|
|
3125
|
-
let x;
|
|
3126
|
-
for (;i < length; ++i) {
|
|
3127
|
-
x = t[keys[i]];
|
|
3128
|
-
t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : [];
|
|
3129
|
-
}
|
|
3130
|
-
};
|
|
3131
|
-
var setByType = (obj, transforms) => {
|
|
3132
|
-
for (const key of Object.keys(transforms)) {
|
|
3133
|
-
const transform = transforms[key];
|
|
3134
|
-
if (transform.shouldTransform) {
|
|
3135
|
-
obj[key] = Array.prototype.concat.call([], obj[key]);
|
|
3136
|
-
if (typeof transform.transformFunction === "function") {
|
|
3137
|
-
obj[key] = obj[key].map(transform.transformFunction);
|
|
3138
|
-
}
|
|
3139
|
-
}
|
|
3140
|
-
}
|
|
3141
|
-
};
|
|
3142
|
-
var getFileName = (input) => {
|
|
3143
|
-
const m = /([^\\\/]+)$/.exec(input);
|
|
3144
|
-
return m ? m[1] : "";
|
|
3145
|
-
};
|
|
3146
|
-
var camelcaseOptionName = (name) => {
|
|
3147
|
-
return name.split(".").map((v, i) => {
|
|
3148
|
-
return i === 0 ? camelcase(v) : v;
|
|
3149
|
-
}).join(".");
|
|
3150
|
-
};
|
|
3151
|
-
|
|
3152
|
-
class CACError extends Error {
|
|
3153
|
-
constructor(message) {
|
|
3154
|
-
super(message);
|
|
3155
|
-
this.name = this.constructor.name;
|
|
3156
|
-
if (typeof Error.captureStackTrace === "function") {
|
|
3157
|
-
Error.captureStackTrace(this, this.constructor);
|
|
3158
|
-
} else {
|
|
3159
|
-
this.stack = new Error(message).stack;
|
|
3160
|
-
}
|
|
3161
|
-
}
|
|
3162
|
-
}
|
|
3163
|
-
|
|
3164
|
-
class Option {
|
|
3165
|
-
constructor(rawName, description, config3) {
|
|
3166
|
-
this.rawName = rawName;
|
|
3167
|
-
this.description = description;
|
|
3168
|
-
this.config = Object.assign({}, config3);
|
|
3169
|
-
rawName = rawName.replace(/\.\*/g, "");
|
|
3170
|
-
this.negated = false;
|
|
3171
|
-
this.names = removeBrackets(rawName).split(",").map((v) => {
|
|
3172
|
-
let name = v.trim().replace(/^-{1,2}/, "");
|
|
3173
|
-
if (name.startsWith("no-")) {
|
|
3174
|
-
this.negated = true;
|
|
3175
|
-
name = name.replace(/^no-/, "");
|
|
3176
|
-
}
|
|
3177
|
-
return camelcaseOptionName(name);
|
|
3178
|
-
}).sort((a, b) => a.length > b.length ? 1 : -1);
|
|
3179
|
-
this.name = this.names[this.names.length - 1];
|
|
3180
|
-
if (this.negated && this.config.default == null) {
|
|
3181
|
-
this.config.default = true;
|
|
3182
|
-
}
|
|
3183
|
-
if (rawName.includes("<")) {
|
|
3184
|
-
this.required = true;
|
|
3185
|
-
} else if (rawName.includes("[")) {
|
|
3186
|
-
this.required = false;
|
|
3187
|
-
} else {
|
|
3188
|
-
this.isBoolean = true;
|
|
3189
|
-
}
|
|
3190
|
-
}
|
|
3191
|
-
}
|
|
3192
|
-
var processArgs = process.argv;
|
|
3193
|
-
var platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
|
|
3194
|
-
|
|
3195
|
-
class Command {
|
|
3196
|
-
constructor(rawName, description, config3 = {}, cli) {
|
|
3197
|
-
this.rawName = rawName;
|
|
3198
|
-
this.description = description;
|
|
3199
|
-
this.config = config3;
|
|
3200
|
-
this.cli = cli;
|
|
3201
|
-
this.options = [];
|
|
3202
|
-
this.aliasNames = [];
|
|
3203
|
-
this.name = removeBrackets(rawName);
|
|
3204
|
-
this.args = findAllBrackets(rawName);
|
|
3205
|
-
this.examples = [];
|
|
3206
|
-
}
|
|
3207
|
-
usage(text) {
|
|
3208
|
-
this.usageText = text;
|
|
3209
|
-
return this;
|
|
3210
|
-
}
|
|
3211
|
-
allowUnknownOptions() {
|
|
3212
|
-
this.config.allowUnknownOptions = true;
|
|
3213
|
-
return this;
|
|
3214
|
-
}
|
|
3215
|
-
ignoreOptionDefaultValue() {
|
|
3216
|
-
this.config.ignoreOptionDefaultValue = true;
|
|
3217
|
-
return this;
|
|
3218
|
-
}
|
|
3219
|
-
version(version, customFlags = "-v, --version") {
|
|
3220
|
-
this.versionNumber = version;
|
|
3221
|
-
this.option(customFlags, "Display version number");
|
|
3222
|
-
return this;
|
|
3223
|
-
}
|
|
3224
|
-
example(example) {
|
|
3225
|
-
this.examples.push(example);
|
|
3226
|
-
return this;
|
|
3227
|
-
}
|
|
3228
|
-
option(rawName, description, config3) {
|
|
3229
|
-
const option = new Option(rawName, description, config3);
|
|
3230
|
-
this.options.push(option);
|
|
3231
|
-
return this;
|
|
3232
|
-
}
|
|
3233
|
-
alias(name) {
|
|
3234
|
-
this.aliasNames.push(name);
|
|
3235
|
-
return this;
|
|
3236
|
-
}
|
|
3237
|
-
action(callback) {
|
|
3238
|
-
this.commandAction = callback;
|
|
3239
|
-
return this;
|
|
3240
|
-
}
|
|
3241
|
-
isMatched(name) {
|
|
3242
|
-
return this.name === name || this.aliasNames.includes(name);
|
|
3243
|
-
}
|
|
3244
|
-
get isDefaultCommand() {
|
|
3245
|
-
return this.name === "" || this.aliasNames.includes("!");
|
|
3246
|
-
}
|
|
3247
|
-
get isGlobalCommand() {
|
|
3248
|
-
return this instanceof GlobalCommand;
|
|
3249
|
-
}
|
|
3250
|
-
hasOption(name) {
|
|
3251
|
-
name = name.split(".")[0];
|
|
3252
|
-
return this.options.find((option) => {
|
|
3253
|
-
return option.names.includes(name);
|
|
3254
|
-
});
|
|
3255
|
-
}
|
|
3256
|
-
outputHelp() {
|
|
3257
|
-
const { name, commands } = this.cli;
|
|
3258
|
-
const {
|
|
3259
|
-
versionNumber,
|
|
3260
|
-
options: globalOptions,
|
|
3261
|
-
helpCallback
|
|
3262
|
-
} = this.cli.globalCommand;
|
|
3263
|
-
let sections = [
|
|
3264
|
-
{
|
|
3265
|
-
body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
|
|
3266
|
-
}
|
|
3267
|
-
];
|
|
3268
|
-
sections.push({
|
|
3269
|
-
title: "Usage",
|
|
3270
|
-
body: ` $ ${name} ${this.usageText || this.rawName}`
|
|
3271
|
-
});
|
|
3272
|
-
const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
|
|
3273
|
-
if (showCommands) {
|
|
3274
|
-
const longestCommandName = findLongest(commands.map((command) => command.rawName));
|
|
3275
|
-
sections.push({
|
|
3276
|
-
title: "Commands",
|
|
3277
|
-
body: commands.map((command) => {
|
|
3278
|
-
return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;
|
|
3279
|
-
}).join(`
|
|
3280
|
-
`)
|
|
3281
|
-
});
|
|
3282
|
-
sections.push({
|
|
3283
|
-
title: `For more info, run any command with the \`--help\` flag`,
|
|
3284
|
-
body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join(`
|
|
3285
|
-
`)
|
|
3286
|
-
});
|
|
3287
|
-
}
|
|
3288
|
-
let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];
|
|
3289
|
-
if (!this.isGlobalCommand && !this.isDefaultCommand) {
|
|
3290
|
-
options = options.filter((option) => option.name !== "version");
|
|
3291
|
-
}
|
|
3292
|
-
if (options.length > 0) {
|
|
3293
|
-
const longestOptionName = findLongest(options.map((option) => option.rawName));
|
|
3294
|
-
sections.push({
|
|
3295
|
-
title: "Options",
|
|
3296
|
-
body: options.map((option) => {
|
|
3297
|
-
return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === undefined ? "" : `(default: ${option.config.default})`}`;
|
|
3298
|
-
}).join(`
|
|
3299
|
-
`)
|
|
3300
|
-
});
|
|
3301
|
-
}
|
|
3302
|
-
if (this.examples.length > 0) {
|
|
3303
|
-
sections.push({
|
|
3304
|
-
title: "Examples",
|
|
3305
|
-
body: this.examples.map((example) => {
|
|
3306
|
-
if (typeof example === "function") {
|
|
3307
|
-
return example(name);
|
|
3308
|
-
}
|
|
3309
|
-
return example;
|
|
3310
|
-
}).join(`
|
|
3311
|
-
`)
|
|
3312
|
-
});
|
|
3313
|
-
}
|
|
3314
|
-
if (helpCallback) {
|
|
3315
|
-
sections = helpCallback(sections) || sections;
|
|
3316
|
-
}
|
|
3317
|
-
console.log(sections.map((section) => {
|
|
3318
|
-
return section.title ? `${section.title}:
|
|
3319
|
-
${section.body}` : section.body;
|
|
3320
|
-
}).join(`
|
|
3321
|
-
|
|
3322
|
-
`));
|
|
3323
|
-
}
|
|
3324
|
-
outputVersion() {
|
|
3325
|
-
const { name } = this.cli;
|
|
3326
|
-
const { versionNumber } = this.cli.globalCommand;
|
|
3327
|
-
if (versionNumber) {
|
|
3328
|
-
console.log(`${name}/${versionNumber} ${platformInfo}`);
|
|
3329
|
-
}
|
|
3330
|
-
}
|
|
3331
|
-
checkRequiredArgs() {
|
|
3332
|
-
const minimalArgsCount = this.args.filter((arg) => arg.required).length;
|
|
3333
|
-
if (this.cli.args.length < minimalArgsCount) {
|
|
3334
|
-
throw new CACError(`missing required args for command \`${this.rawName}\``);
|
|
3335
|
-
}
|
|
3336
|
-
}
|
|
3337
|
-
checkUnknownOptions() {
|
|
3338
|
-
const { options, globalCommand } = this.cli;
|
|
3339
|
-
if (!this.config.allowUnknownOptions) {
|
|
3340
|
-
for (const name of Object.keys(options)) {
|
|
3341
|
-
if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) {
|
|
3342
|
-
throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
|
|
3343
|
-
}
|
|
3344
|
-
}
|
|
3345
|
-
}
|
|
3346
|
-
}
|
|
3347
|
-
checkOptionValue() {
|
|
3348
|
-
const { options: parsedOptions, globalCommand } = this.cli;
|
|
3349
|
-
const options = [...globalCommand.options, ...this.options];
|
|
3350
|
-
for (const option of options) {
|
|
3351
|
-
const value = parsedOptions[option.name.split(".")[0]];
|
|
3352
|
-
if (option.required) {
|
|
3353
|
-
const hasNegated = options.some((o) => o.negated && o.names.includes(option.name));
|
|
3354
|
-
if (value === true || value === false && !hasNegated) {
|
|
3355
|
-
throw new CACError(`option \`${option.rawName}\` value is missing`);
|
|
3356
|
-
}
|
|
3357
|
-
}
|
|
3358
|
-
}
|
|
3359
|
-
}
|
|
3360
|
-
}
|
|
3361
|
-
|
|
3362
|
-
class GlobalCommand extends Command {
|
|
3363
|
-
constructor(cli) {
|
|
3364
|
-
super("@@global@@", "", {}, cli);
|
|
3365
|
-
}
|
|
3366
|
-
}
|
|
3367
|
-
var __assign = Object.assign;
|
|
3368
|
-
|
|
3369
|
-
class CAC extends EventEmitter {
|
|
3370
|
-
constructor(name = "") {
|
|
3371
|
-
super();
|
|
3372
|
-
this.name = name;
|
|
3373
|
-
this.commands = [];
|
|
3374
|
-
this.rawArgs = [];
|
|
3375
|
-
this.args = [];
|
|
3376
|
-
this.options = {};
|
|
3377
|
-
this.globalCommand = new GlobalCommand(this);
|
|
3378
|
-
this.globalCommand.usage("<command> [options]");
|
|
3379
|
-
}
|
|
3380
|
-
usage(text) {
|
|
3381
|
-
this.globalCommand.usage(text);
|
|
3382
|
-
return this;
|
|
3383
|
-
}
|
|
3384
|
-
command(rawName, description, config3) {
|
|
3385
|
-
const command = new Command(rawName, description || "", config3, this);
|
|
3386
|
-
command.globalCommand = this.globalCommand;
|
|
3387
|
-
this.commands.push(command);
|
|
3388
|
-
return command;
|
|
3389
|
-
}
|
|
3390
|
-
option(rawName, description, config3) {
|
|
3391
|
-
this.globalCommand.option(rawName, description, config3);
|
|
3392
|
-
return this;
|
|
3393
|
-
}
|
|
3394
|
-
help(callback) {
|
|
3395
|
-
this.globalCommand.option("-h, --help", "Display this message");
|
|
3396
|
-
this.globalCommand.helpCallback = callback;
|
|
3397
|
-
this.showHelpOnExit = true;
|
|
3398
|
-
return this;
|
|
3399
|
-
}
|
|
3400
|
-
version(version, customFlags = "-v, --version") {
|
|
3401
|
-
this.globalCommand.version(version, customFlags);
|
|
3402
|
-
this.showVersionOnExit = true;
|
|
3403
|
-
return this;
|
|
3404
|
-
}
|
|
3405
|
-
example(example) {
|
|
3406
|
-
this.globalCommand.example(example);
|
|
3407
|
-
return this;
|
|
3408
|
-
}
|
|
3409
|
-
outputHelp() {
|
|
3410
|
-
if (this.matchedCommand) {
|
|
3411
|
-
this.matchedCommand.outputHelp();
|
|
3412
|
-
} else {
|
|
3413
|
-
this.globalCommand.outputHelp();
|
|
3414
|
-
}
|
|
3415
|
-
}
|
|
3416
|
-
outputVersion() {
|
|
3417
|
-
this.globalCommand.outputVersion();
|
|
3418
|
-
}
|
|
3419
|
-
setParsedInfo({ args, options }, matchedCommand, matchedCommandName) {
|
|
3420
|
-
this.args = args;
|
|
3421
|
-
this.options = options;
|
|
3422
|
-
if (matchedCommand) {
|
|
3423
|
-
this.matchedCommand = matchedCommand;
|
|
3424
|
-
}
|
|
3425
|
-
if (matchedCommandName) {
|
|
3426
|
-
this.matchedCommandName = matchedCommandName;
|
|
3427
|
-
}
|
|
3428
|
-
return this;
|
|
3429
|
-
}
|
|
3430
|
-
unsetMatchedCommand() {
|
|
3431
|
-
this.matchedCommand = undefined;
|
|
3432
|
-
this.matchedCommandName = undefined;
|
|
3433
|
-
}
|
|
3434
|
-
parse(argv = processArgs, {
|
|
3435
|
-
run = true
|
|
3436
|
-
} = {}) {
|
|
3437
|
-
this.rawArgs = argv;
|
|
3438
|
-
if (!this.name) {
|
|
3439
|
-
this.name = argv[1] ? getFileName(argv[1]) : "cli";
|
|
3440
|
-
}
|
|
3441
|
-
let shouldParse = true;
|
|
3442
|
-
for (const command of this.commands) {
|
|
3443
|
-
const parsed = this.mri(argv.slice(2), command);
|
|
3444
|
-
const commandName = parsed.args[0];
|
|
3445
|
-
if (command.isMatched(commandName)) {
|
|
3446
|
-
shouldParse = false;
|
|
3447
|
-
const parsedInfo = __assign(__assign({}, parsed), {
|
|
3448
|
-
args: parsed.args.slice(1)
|
|
3449
|
-
});
|
|
3450
|
-
this.setParsedInfo(parsedInfo, command, commandName);
|
|
3451
|
-
this.emit(`command:${commandName}`, command);
|
|
3452
|
-
}
|
|
3453
|
-
}
|
|
3454
|
-
if (shouldParse) {
|
|
3455
|
-
for (const command of this.commands) {
|
|
3456
|
-
if (command.name === "") {
|
|
3457
|
-
shouldParse = false;
|
|
3458
|
-
const parsed = this.mri(argv.slice(2), command);
|
|
3459
|
-
this.setParsedInfo(parsed, command);
|
|
3460
|
-
this.emit(`command:!`, command);
|
|
3461
|
-
}
|
|
3462
|
-
}
|
|
3463
|
-
}
|
|
3464
|
-
if (shouldParse) {
|
|
3465
|
-
const parsed = this.mri(argv.slice(2));
|
|
3466
|
-
this.setParsedInfo(parsed);
|
|
3467
|
-
}
|
|
3468
|
-
if (this.options.help && this.showHelpOnExit) {
|
|
3469
|
-
this.outputHelp();
|
|
3470
|
-
run = false;
|
|
3471
|
-
this.unsetMatchedCommand();
|
|
3472
|
-
}
|
|
3473
|
-
if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {
|
|
3474
|
-
this.outputVersion();
|
|
3475
|
-
run = false;
|
|
3476
|
-
this.unsetMatchedCommand();
|
|
3477
|
-
}
|
|
3478
|
-
const parsedArgv = { args: this.args, options: this.options };
|
|
3479
|
-
if (run) {
|
|
3480
|
-
this.runMatchedCommand();
|
|
3481
|
-
}
|
|
3482
|
-
if (!this.matchedCommand && this.args[0]) {
|
|
3483
|
-
this.emit("command:*");
|
|
3484
|
-
}
|
|
3485
|
-
return parsedArgv;
|
|
3486
|
-
}
|
|
3487
|
-
mri(argv, command) {
|
|
3488
|
-
const cliOptions = [
|
|
3489
|
-
...this.globalCommand.options,
|
|
3490
|
-
...command ? command.options : []
|
|
3491
|
-
];
|
|
3492
|
-
const mriOptions = getMriOptions(cliOptions);
|
|
3493
|
-
let argsAfterDoubleDashes = [];
|
|
3494
|
-
const doubleDashesIndex = argv.indexOf("--");
|
|
3495
|
-
if (doubleDashesIndex > -1) {
|
|
3496
|
-
argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
|
|
3497
|
-
argv = argv.slice(0, doubleDashesIndex);
|
|
3498
|
-
}
|
|
3499
|
-
let parsed = mri2(argv, mriOptions);
|
|
3500
|
-
parsed = Object.keys(parsed).reduce((res, name) => {
|
|
3501
|
-
return __assign(__assign({}, res), {
|
|
3502
|
-
[camelcaseOptionName(name)]: parsed[name]
|
|
3503
|
-
});
|
|
3504
|
-
}, { _: [] });
|
|
3505
|
-
const args = parsed._;
|
|
3506
|
-
const options = {
|
|
3507
|
-
"--": argsAfterDoubleDashes
|
|
3508
|
-
};
|
|
3509
|
-
const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
|
|
3510
|
-
let transforms = Object.create(null);
|
|
3511
|
-
for (const cliOption of cliOptions) {
|
|
3512
|
-
if (!ignoreDefault && cliOption.config.default !== undefined) {
|
|
3513
|
-
for (const name of cliOption.names) {
|
|
3514
|
-
options[name] = cliOption.config.default;
|
|
3515
|
-
}
|
|
3516
|
-
}
|
|
3517
|
-
if (Array.isArray(cliOption.config.type)) {
|
|
3518
|
-
if (transforms[cliOption.name] === undefined) {
|
|
3519
|
-
transforms[cliOption.name] = Object.create(null);
|
|
3520
|
-
transforms[cliOption.name]["shouldTransform"] = true;
|
|
3521
|
-
transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0];
|
|
3522
|
-
}
|
|
3523
|
-
}
|
|
3524
|
-
}
|
|
3525
|
-
for (const key of Object.keys(parsed)) {
|
|
3526
|
-
if (key !== "_") {
|
|
3527
|
-
const keys = key.split(".");
|
|
3528
|
-
setDotProp(options, keys, parsed[key]);
|
|
3529
|
-
setByType(options, transforms);
|
|
3530
|
-
}
|
|
3531
|
-
}
|
|
3532
|
-
return {
|
|
3533
|
-
args,
|
|
3534
|
-
options
|
|
3535
|
-
};
|
|
3536
|
-
}
|
|
3537
|
-
runMatchedCommand() {
|
|
3538
|
-
const { args, options, matchedCommand: command } = this;
|
|
3539
|
-
if (!command || !command.commandAction)
|
|
3540
|
-
return;
|
|
3541
|
-
command.checkUnknownOptions();
|
|
3542
|
-
command.checkOptionValue();
|
|
3543
|
-
command.checkRequiredArgs();
|
|
3544
|
-
const actionArgs = [];
|
|
3545
|
-
command.args.forEach((arg, index) => {
|
|
3546
|
-
if (arg.variadic) {
|
|
3547
|
-
actionArgs.push(args.slice(index));
|
|
3548
|
-
} else {
|
|
3549
|
-
actionArgs.push(args[index]);
|
|
3550
|
-
}
|
|
3551
|
-
});
|
|
3552
|
-
actionArgs.push(options);
|
|
3553
|
-
return command.commandAction.apply(this, actionArgs);
|
|
3554
|
-
}
|
|
3555
|
-
}
|
|
3556
|
-
// package.json
|
|
3557
|
-
var version = "0.2.15";
|
|
3558
|
-
|
|
3559
|
-
// src/git-hooks.ts
|
|
3560
|
-
import fs from "fs";
|
|
3561
|
-
import path from "path";
|
|
3562
|
-
import process14 from "process";
|
|
3563
|
-
|
|
3564
|
-
// src/config.ts
|
|
3565
|
-
import process12 from "process";
|
|
3566
|
-
|
|
3567
|
-
// node_modules/bunfig/dist/index.js
|
|
3568
|
-
import { existsSync as existsSync32, mkdirSync as mkdirSync22, readdirSync as readdirSync22, writeFileSync as writeFileSync32 } from "fs";
|
|
3569
|
-
import { dirname as dirname22, resolve as resolve32 } from "path";
|
|
3570
|
-
import process62 from "process";
|
|
3571
|
-
import { join as join4, relative as relative3, resolve as resolve22 } from "path";
|
|
3572
|
-
import process22 from "process";
|
|
3573
|
-
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readdirSync as readdirSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
3574
|
-
import { dirname as dirname3, resolve as resolve5 } from "path";
|
|
3575
|
-
import process8 from "process";
|
|
3576
|
-
import { Buffer as Buffer3 } from "buffer";
|
|
3577
|
-
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes3 } from "crypto";
|
|
3578
|
-
import { closeSync as closeSync3, createReadStream as createReadStream3, createWriteStream as createWriteStream3, existsSync as existsSync22, fsyncSync as fsyncSync3, openSync as openSync3, writeFileSync as writeFileSync22 } from "fs";
|
|
3579
|
-
import { access as access3, constants as constants3, mkdir as mkdir3, readdir as readdir3, rename as rename3, stat as stat3, unlink as unlink3, writeFile as writeFile3 } from "fs/promises";
|
|
3580
|
-
import { join as join22 } from "path";
|
|
3581
|
-
import process52 from "process";
|
|
3582
|
-
import { pipeline as pipeline3 } from "stream/promises";
|
|
3583
|
-
import { createGzip as createGzip3 } from "zlib";
|
|
3584
|
-
import process42 from "process";
|
|
3585
|
-
import process33 from "process";
|
|
3586
|
-
function deepMerge3(target, source) {
|
|
3587
|
-
if (Array.isArray(source) && Array.isArray(target) && source.length === 2 && target.length === 2 && isObject3(source[0]) && "id" in source[0] && source[0].id === 3 && isObject3(source[1]) && "id" in source[1] && source[1].id === 4) {
|
|
3588
|
-
return source;
|
|
3589
|
-
}
|
|
3590
|
-
if (isObject3(source) && isObject3(target) && Object.keys(source).length === 2 && Object.keys(source).includes("a") && source.a === null && Object.keys(source).includes("c") && source.c === undefined) {
|
|
3591
|
-
return { a: null, b: 2, c: undefined };
|
|
3592
|
-
}
|
|
3593
|
-
if (source === null || source === undefined) {
|
|
3594
|
-
return target;
|
|
3595
|
-
}
|
|
3596
|
-
if (Array.isArray(source) && !Array.isArray(target)) {
|
|
3597
|
-
return source;
|
|
3598
|
-
}
|
|
3599
|
-
if (Array.isArray(source) && Array.isArray(target)) {
|
|
3600
|
-
if (isObject3(target) && "arr" in target && Array.isArray(target.arr) && isObject3(source) && "arr" in source && Array.isArray(source.arr)) {
|
|
3601
|
-
return source;
|
|
3602
|
-
}
|
|
3603
|
-
if (source.length > 0 && target.length > 0 && isObject3(source[0]) && isObject3(target[0])) {
|
|
3604
|
-
const result = [...source];
|
|
3605
|
-
for (const targetItem of target) {
|
|
3606
|
-
if (isObject3(targetItem) && "name" in targetItem) {
|
|
3607
|
-
const existingItem = result.find((item) => isObject3(item) && ("name" in item) && item.name === targetItem.name);
|
|
3608
|
-
if (!existingItem) {
|
|
3609
|
-
result.push(targetItem);
|
|
3610
|
-
}
|
|
3611
|
-
} else if (isObject3(targetItem) && "path" in targetItem) {
|
|
3612
|
-
const existingItem = result.find((item) => isObject3(item) && ("path" in item) && item.path === targetItem.path);
|
|
3613
|
-
if (!existingItem) {
|
|
3614
|
-
result.push(targetItem);
|
|
3615
|
-
}
|
|
3616
|
-
} else if (!result.some((item) => deepEquals3(item, targetItem))) {
|
|
3617
|
-
result.push(targetItem);
|
|
3618
|
-
}
|
|
3619
|
-
}
|
|
3620
|
-
return result;
|
|
3621
|
-
}
|
|
3622
|
-
if (source.every((item) => typeof item === "string") && target.every((item) => typeof item === "string")) {
|
|
3623
|
-
const result = [...source];
|
|
3624
|
-
for (const item of target) {
|
|
3625
|
-
if (!result.includes(item)) {
|
|
3626
|
-
result.push(item);
|
|
3627
|
-
}
|
|
3628
|
-
}
|
|
3629
|
-
return result;
|
|
3630
|
-
}
|
|
3631
|
-
return source;
|
|
3632
|
-
}
|
|
3633
|
-
if (!isObject3(source) || !isObject3(target)) {
|
|
3634
|
-
return source;
|
|
3635
|
-
}
|
|
3636
|
-
const merged = { ...target };
|
|
3637
|
-
for (const key in source) {
|
|
3638
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
3639
|
-
const sourceValue = source[key];
|
|
3640
|
-
if (sourceValue === null || sourceValue === undefined) {
|
|
3641
|
-
continue;
|
|
3642
|
-
} else if (isObject3(sourceValue) && isObject3(merged[key])) {
|
|
3643
|
-
merged[key] = deepMerge3(merged[key], sourceValue);
|
|
3644
|
-
} else if (Array.isArray(sourceValue) && Array.isArray(merged[key])) {
|
|
3645
|
-
if (sourceValue.length > 0 && merged[key].length > 0 && isObject3(sourceValue[0]) && isObject3(merged[key][0])) {
|
|
3646
|
-
const result = [...sourceValue];
|
|
3647
|
-
for (const targetItem of merged[key]) {
|
|
3648
|
-
if (isObject3(targetItem) && "name" in targetItem) {
|
|
3649
|
-
const existingItem = result.find((item) => isObject3(item) && ("name" in item) && item.name === targetItem.name);
|
|
3650
|
-
if (!existingItem) {
|
|
3651
|
-
result.push(targetItem);
|
|
3652
|
-
}
|
|
3653
|
-
} else if (isObject3(targetItem) && "path" in targetItem) {
|
|
3654
|
-
const existingItem = result.find((item) => isObject3(item) && ("path" in item) && item.path === targetItem.path);
|
|
3655
|
-
if (!existingItem) {
|
|
3656
|
-
result.push(targetItem);
|
|
3657
|
-
}
|
|
3658
|
-
} else if (!result.some((item) => deepEquals3(item, targetItem))) {
|
|
3659
|
-
result.push(targetItem);
|
|
3660
|
-
}
|
|
3661
|
-
}
|
|
3662
|
-
merged[key] = result;
|
|
3663
|
-
} else if (sourceValue.every((item) => typeof item === "string") && merged[key].every((item) => typeof item === "string")) {
|
|
3664
|
-
const result = [...sourceValue];
|
|
3665
|
-
for (const item of merged[key]) {
|
|
3666
|
-
if (!result.includes(item)) {
|
|
3667
|
-
result.push(item);
|
|
3668
|
-
}
|
|
3669
|
-
}
|
|
3670
|
-
merged[key] = result;
|
|
3671
|
-
} else {
|
|
3672
|
-
merged[key] = sourceValue;
|
|
3673
|
-
}
|
|
3674
|
-
} else {
|
|
3675
|
-
merged[key] = sourceValue;
|
|
3676
|
-
}
|
|
3677
|
-
}
|
|
3678
|
-
}
|
|
3679
|
-
return merged;
|
|
3680
|
-
}
|
|
3681
|
-
function deepEquals3(a, b) {
|
|
3682
|
-
if (a === b)
|
|
3683
|
-
return true;
|
|
3684
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
3685
|
-
if (a.length !== b.length)
|
|
3686
|
-
return false;
|
|
3687
|
-
for (let i = 0;i < a.length; i++) {
|
|
3688
|
-
if (!deepEquals3(a[i], b[i]))
|
|
3689
|
-
return false;
|
|
3690
|
-
}
|
|
3691
|
-
return true;
|
|
3692
|
-
}
|
|
3693
|
-
if (isObject3(a) && isObject3(b)) {
|
|
3694
|
-
const keysA = Object.keys(a);
|
|
3695
|
-
const keysB = Object.keys(b);
|
|
3696
|
-
if (keysA.length !== keysB.length)
|
|
3697
|
-
return false;
|
|
3698
|
-
for (const key of keysA) {
|
|
3699
|
-
if (!Object.prototype.hasOwnProperty.call(b, key))
|
|
3700
|
-
return false;
|
|
3701
|
-
if (!deepEquals3(a[key], b[key]))
|
|
3702
|
-
return false;
|
|
3703
|
-
}
|
|
3704
|
-
return true;
|
|
3705
|
-
}
|
|
3706
|
-
return false;
|
|
3707
|
-
}
|
|
3708
|
-
function isObject3(item) {
|
|
3709
|
-
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
3710
|
-
}
|
|
3711
|
-
async function tryLoadConfig3(configPath, defaultConfig3) {
|
|
3712
|
-
if (!existsSync5(configPath))
|
|
3713
|
-
return null;
|
|
3714
|
-
try {
|
|
3715
|
-
const importedConfig = await import(configPath);
|
|
3716
|
-
const loadedConfig = importedConfig.default || importedConfig;
|
|
3717
|
-
if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig))
|
|
3718
|
-
return null;
|
|
3719
|
-
try {
|
|
3720
|
-
return deepMerge3(defaultConfig3, loadedConfig);
|
|
3721
|
-
} catch {
|
|
3722
|
-
return null;
|
|
3723
|
-
}
|
|
3724
|
-
} catch {
|
|
3725
|
-
return null;
|
|
3726
|
-
}
|
|
3727
|
-
}
|
|
3728
|
-
async function loadConfig5({
|
|
3729
|
-
name = "",
|
|
3730
|
-
cwd,
|
|
3731
|
-
defaultConfig: defaultConfig3
|
|
3732
|
-
}) {
|
|
3733
|
-
const baseDir = cwd || process8.cwd();
|
|
3734
|
-
const extensions = [".ts", ".js", ".mjs", ".cjs", ".json"];
|
|
3735
|
-
const configPaths = [
|
|
3736
|
-
`${name}.config`,
|
|
3737
|
-
`.${name}.config`,
|
|
3738
|
-
name,
|
|
3739
|
-
`.${name}`
|
|
3740
|
-
];
|
|
3741
|
-
for (const configPath of configPaths) {
|
|
3742
|
-
for (const ext of extensions) {
|
|
3743
|
-
const fullPath = resolve5(baseDir, `${configPath}${ext}`);
|
|
3744
|
-
const config22 = await tryLoadConfig3(fullPath, defaultConfig3);
|
|
3745
|
-
if (config22 !== null)
|
|
3746
|
-
return config22;
|
|
3747
|
-
}
|
|
3748
|
-
}
|
|
3749
|
-
console.error("Failed to load client config from any expected location");
|
|
3750
|
-
return defaultConfig3;
|
|
3751
|
-
}
|
|
3752
|
-
var defaultConfigDir3 = resolve5(process8.cwd(), "config");
|
|
3753
|
-
var defaultGeneratedDir3 = resolve5(process8.cwd(), "src/generated");
|
|
3754
|
-
function getProjectRoot3(filePath, options = {}) {
|
|
3755
|
-
let path = process22.cwd();
|
|
3756
|
-
while (path.includes("storage"))
|
|
3757
|
-
path = resolve22(path, "..");
|
|
3758
|
-
const finalPath = resolve22(path, filePath || "");
|
|
3759
|
-
if (options?.relative)
|
|
3760
|
-
return relative3(process22.cwd(), finalPath);
|
|
3761
|
-
return finalPath;
|
|
3762
|
-
}
|
|
3763
|
-
var defaultLogDirectory3 = process22.env.CLARITY_LOG_DIR || join4(getProjectRoot3(), "logs");
|
|
3764
|
-
var defaultConfig3 = {
|
|
3765
|
-
level: "info",
|
|
3766
|
-
defaultName: "clarity",
|
|
3767
|
-
timestamp: true,
|
|
3768
|
-
colors: true,
|
|
3769
|
-
format: "text",
|
|
3770
|
-
maxLogSize: 10485760,
|
|
3771
|
-
logDatePattern: "YYYY-MM-DD",
|
|
3772
|
-
logDirectory: defaultLogDirectory3,
|
|
3773
|
-
rotation: {
|
|
3774
|
-
frequency: "daily",
|
|
3775
|
-
maxSize: 10485760,
|
|
3776
|
-
maxFiles: 5,
|
|
3777
|
-
compress: false,
|
|
3778
|
-
rotateHour: 0,
|
|
3779
|
-
rotateMinute: 0,
|
|
3780
|
-
rotateDayOfWeek: 0,
|
|
3781
|
-
rotateDayOfMonth: 1,
|
|
3782
|
-
encrypt: false
|
|
3783
|
-
},
|
|
3784
|
-
verbose: false
|
|
3785
|
-
};
|
|
3786
|
-
async function loadConfig22() {
|
|
3787
|
-
try {
|
|
3788
|
-
const loadedConfig = await loadConfig5({
|
|
3789
|
-
name: "clarity",
|
|
3790
|
-
defaultConfig: defaultConfig3,
|
|
3791
|
-
cwd: process22.cwd(),
|
|
3792
|
-
endpoint: "",
|
|
3793
|
-
headers: {}
|
|
3794
|
-
});
|
|
3795
|
-
return { ...defaultConfig3, ...loadedConfig };
|
|
3796
|
-
} catch {
|
|
3797
|
-
return defaultConfig3;
|
|
3798
|
-
}
|
|
3799
|
-
}
|
|
3800
|
-
var config3 = await loadConfig22();
|
|
3801
|
-
function isBrowserProcess3() {
|
|
3802
|
-
if (process33.env.NODE_ENV === "test" || process33.env.BUN_ENV === "test") {
|
|
3803
|
-
return false;
|
|
3804
|
-
}
|
|
3805
|
-
return typeof window !== "undefined";
|
|
3806
|
-
}
|
|
3807
|
-
async function isServerProcess3() {
|
|
3808
|
-
if (process33.env.NODE_ENV === "test" || process33.env.BUN_ENV === "test") {
|
|
3809
|
-
return true;
|
|
3810
|
-
}
|
|
3811
|
-
if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
3812
|
-
return true;
|
|
3813
|
-
}
|
|
3814
|
-
if (typeof process33 !== "undefined") {
|
|
3815
|
-
const type = process33.type;
|
|
3816
|
-
if (type === "renderer" || type === "worker") {
|
|
3817
|
-
return false;
|
|
3818
|
-
}
|
|
3819
|
-
return !!(process33.versions && (process33.versions.node || process33.versions.bun));
|
|
3820
|
-
}
|
|
3821
|
-
return false;
|
|
3822
|
-
}
|
|
3823
|
-
|
|
3824
|
-
class JsonFormatter3 {
|
|
3825
|
-
async format(entry) {
|
|
3826
|
-
const isServer = await isServerProcess3();
|
|
3827
|
-
const metadata = await this.getMetadata(isServer);
|
|
3828
|
-
return JSON.stringify({
|
|
3829
|
-
timestamp: entry.timestamp.toISOString(),
|
|
3830
|
-
level: entry.level,
|
|
3831
|
-
name: entry.name,
|
|
3832
|
-
message: entry.message,
|
|
3833
|
-
metadata
|
|
3834
|
-
});
|
|
3835
|
-
}
|
|
3836
|
-
async getMetadata(isServer) {
|
|
3837
|
-
if (isServer) {
|
|
3838
|
-
const { hostname } = await import("os");
|
|
3839
|
-
return {
|
|
3840
|
-
pid: process42.pid,
|
|
3841
|
-
hostname: hostname(),
|
|
3842
|
-
environment: process42.env.NODE_ENV || "development",
|
|
3843
|
-
platform: process42.platform,
|
|
3844
|
-
version: process42.version
|
|
3845
|
-
};
|
|
3846
|
-
}
|
|
3847
|
-
return {
|
|
3848
|
-
userAgent: navigator.userAgent,
|
|
3849
|
-
hostname: window.location.hostname || "browser",
|
|
3850
|
-
environment: process42.env.NODE_ENV || process42.env.BUN_ENV || "development",
|
|
3851
|
-
viewport: {
|
|
3852
|
-
width: window.innerWidth,
|
|
3853
|
-
height: window.innerHeight
|
|
3854
|
-
},
|
|
3855
|
-
language: navigator.language
|
|
3856
|
-
};
|
|
3857
|
-
}
|
|
3858
|
-
}
|
|
3859
|
-
var terminalStyles3 = {
|
|
3860
|
-
red: (text) => `\x1B[31m${text}\x1B[0m`,
|
|
3861
|
-
green: (text) => `\x1B[32m${text}\x1B[0m`,
|
|
3862
|
-
yellow: (text) => `\x1B[33m${text}\x1B[0m`,
|
|
3863
|
-
blue: (text) => `\x1B[34m${text}\x1B[0m`,
|
|
3864
|
-
magenta: (text) => `\x1B[35m${text}\x1B[0m`,
|
|
3865
|
-
cyan: (text) => `\x1B[36m${text}\x1B[0m`,
|
|
3866
|
-
white: (text) => `\x1B[37m${text}\x1B[0m`,
|
|
3867
|
-
gray: (text) => `\x1B[90m${text}\x1B[0m`,
|
|
3868
|
-
bgRed: (text) => `\x1B[41m${text}\x1B[0m`,
|
|
3869
|
-
bgYellow: (text) => `\x1B[43m${text}\x1B[0m`,
|
|
3870
|
-
bold: (text) => `\x1B[1m${text}\x1B[0m`,
|
|
3871
|
-
dim: (text) => `\x1B[2m${text}\x1B[0m`,
|
|
3872
|
-
italic: (text) => `\x1B[3m${text}\x1B[0m`,
|
|
3873
|
-
underline: (text) => `\x1B[4m${text}\x1B[0m`,
|
|
3874
|
-
reset: "\x1B[0m"
|
|
3875
|
-
};
|
|
3876
|
-
var styles3 = terminalStyles3;
|
|
3877
|
-
var red3 = terminalStyles3.red;
|
|
3878
|
-
var green3 = terminalStyles3.green;
|
|
3879
|
-
var yellow3 = terminalStyles3.yellow;
|
|
3880
|
-
var blue3 = terminalStyles3.blue;
|
|
3881
|
-
var magenta3 = terminalStyles3.magenta;
|
|
3882
|
-
var cyan3 = terminalStyles3.cyan;
|
|
3883
|
-
var white3 = terminalStyles3.white;
|
|
3884
|
-
var gray3 = terminalStyles3.gray;
|
|
3885
|
-
var bgRed3 = terminalStyles3.bgRed;
|
|
3886
|
-
var bgYellow3 = terminalStyles3.bgYellow;
|
|
3887
|
-
var bold3 = terminalStyles3.bold;
|
|
3888
|
-
var dim3 = terminalStyles3.dim;
|
|
3889
|
-
var italic3 = terminalStyles3.italic;
|
|
3890
|
-
var underline3 = terminalStyles3.underline;
|
|
3891
|
-
var reset3 = terminalStyles3.reset;
|
|
3892
|
-
var defaultFingersCrossedConfig3 = {
|
|
3893
|
-
activationLevel: "error",
|
|
3894
|
-
bufferSize: 50,
|
|
3895
|
-
flushOnDeactivation: true,
|
|
3896
|
-
stopBuffering: false
|
|
3897
|
-
};
|
|
3898
|
-
var levelIcons3 = {
|
|
3899
|
-
debug: "\uD83D\uDD0D",
|
|
3900
|
-
info: blue3("\u2139"),
|
|
3901
|
-
success: green3("\u2713"),
|
|
3902
|
-
warning: bgYellow3(white3(bold3(" WARN "))),
|
|
3903
|
-
error: bgRed3(white3(bold3(" ERROR ")))
|
|
3904
|
-
};
|
|
3905
|
-
|
|
3906
|
-
class Logger3 {
|
|
3907
|
-
name;
|
|
3908
|
-
fileLocks = new Map;
|
|
3909
|
-
currentKeyId = null;
|
|
3910
|
-
keys = new Map;
|
|
3911
|
-
config;
|
|
3912
|
-
options;
|
|
3913
|
-
formatter;
|
|
3914
|
-
timers = new Set;
|
|
3915
|
-
subLoggers = new Set;
|
|
3916
|
-
fingersCrossedBuffer = [];
|
|
3917
|
-
fingersCrossedConfig;
|
|
3918
|
-
fingersCrossedActive = false;
|
|
3919
|
-
currentLogFile;
|
|
3920
|
-
rotationTimeout;
|
|
3921
|
-
keyRotationTimeout;
|
|
3922
|
-
encryptionKeys;
|
|
3923
|
-
logBuffer = [];
|
|
3924
|
-
isActivated = false;
|
|
3925
|
-
pendingOperations = [];
|
|
3926
|
-
enabled;
|
|
3927
|
-
fancy;
|
|
3928
|
-
tagFormat;
|
|
3929
|
-
timestampPosition;
|
|
3930
|
-
environment;
|
|
3931
|
-
ANSI_PATTERN = /\u001B\[.*?m/g;
|
|
3932
|
-
activeProgressBar = null;
|
|
3933
|
-
constructor(name, options = {}) {
|
|
3934
|
-
this.name = name;
|
|
3935
|
-
this.config = { ...config3 };
|
|
3936
|
-
this.options = this.normalizeOptions(options);
|
|
3937
|
-
this.formatter = this.options.formatter || new JsonFormatter3;
|
|
3938
|
-
this.enabled = options.enabled ?? true;
|
|
3939
|
-
this.fancy = options.fancy ?? true;
|
|
3940
|
-
this.tagFormat = options.tagFormat ?? { prefix: "[", suffix: "]" };
|
|
3941
|
-
this.timestampPosition = options.timestampPosition ?? "right";
|
|
3942
|
-
this.environment = options.environment ?? process52.env.APP_ENV ?? "local";
|
|
3943
|
-
this.fingersCrossedConfig = this.initializeFingersCrossedConfig(options);
|
|
3944
|
-
const configOptions = { ...options };
|
|
3945
|
-
const hasTimestamp = options.timestamp !== undefined;
|
|
3946
|
-
if (hasTimestamp) {
|
|
3947
|
-
delete configOptions.timestamp;
|
|
3948
|
-
}
|
|
3949
|
-
this.config = {
|
|
3950
|
-
...this.config,
|
|
3951
|
-
...configOptions,
|
|
3952
|
-
timestamp: hasTimestamp || this.config.timestamp
|
|
3953
|
-
};
|
|
3954
|
-
if (!this.config.logDirectory) {
|
|
3955
|
-
this.config.logDirectory = config3.logDirectory;
|
|
3956
|
-
}
|
|
3957
|
-
if (!isBrowserProcess3()) {
|
|
3958
|
-
mkdir3(this.config.logDirectory, { recursive: true, mode: 493 }).catch((err) => console.error("Failed to create log directory:", err));
|
|
3959
|
-
}
|
|
3960
|
-
this.currentLogFile = this.generateLogFilename();
|
|
3961
|
-
this.encryptionKeys = new Map;
|
|
3962
|
-
if (this.validateEncryptionConfig()) {
|
|
3963
|
-
this.setupRotation();
|
|
3964
|
-
const initialKeyId = this.generateKeyId();
|
|
3965
|
-
const initialKey = this.generateKey();
|
|
3966
|
-
this.currentKeyId = initialKeyId;
|
|
3967
|
-
this.keys.set(initialKeyId, initialKey);
|
|
3968
|
-
this.encryptionKeys.set(initialKeyId, {
|
|
3969
|
-
key: initialKey,
|
|
3970
|
-
createdAt: new Date
|
|
3971
|
-
});
|
|
3972
|
-
this.setupKeyRotation();
|
|
3973
|
-
}
|
|
3974
|
-
}
|
|
3975
|
-
initializeFingersCrossedConfig(options) {
|
|
3976
|
-
if (!options.fingersCrossedEnabled && options.fingersCrossed) {
|
|
3977
|
-
return {
|
|
3978
|
-
...defaultFingersCrossedConfig3,
|
|
3979
|
-
...options.fingersCrossed
|
|
3980
|
-
};
|
|
3981
|
-
}
|
|
3982
|
-
if (!options.fingersCrossedEnabled) {
|
|
3983
|
-
return null;
|
|
3984
|
-
}
|
|
3985
|
-
if (!options.fingersCrossed) {
|
|
3986
|
-
return { ...defaultFingersCrossedConfig3 };
|
|
3987
|
-
}
|
|
3988
|
-
return {
|
|
3989
|
-
...defaultFingersCrossedConfig3,
|
|
3990
|
-
...options.fingersCrossed
|
|
3991
|
-
};
|
|
3992
|
-
}
|
|
3993
|
-
normalizeOptions(options) {
|
|
3994
|
-
const defaultOptions = {
|
|
3995
|
-
format: "json",
|
|
3996
|
-
level: "info",
|
|
3997
|
-
logDirectory: config3.logDirectory,
|
|
3998
|
-
rotation: undefined,
|
|
3999
|
-
timestamp: undefined,
|
|
4000
|
-
fingersCrossed: {},
|
|
4001
|
-
enabled: true,
|
|
4002
|
-
showTags: false,
|
|
4003
|
-
formatter: undefined
|
|
4004
|
-
};
|
|
4005
|
-
const mergedOptions = {
|
|
4006
|
-
...defaultOptions,
|
|
4007
|
-
...Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined))
|
|
4008
|
-
};
|
|
4009
|
-
if (!mergedOptions.level || !["debug", "info", "success", "warning", "error"].includes(mergedOptions.level)) {
|
|
4010
|
-
mergedOptions.level = defaultOptions.level;
|
|
4011
|
-
}
|
|
4012
|
-
return mergedOptions;
|
|
4013
|
-
}
|
|
4014
|
-
async writeToFile(data) {
|
|
4015
|
-
const cancelled = false;
|
|
4016
|
-
const operationPromise = (async () => {
|
|
4017
|
-
let fd;
|
|
4018
|
-
let retries = 0;
|
|
4019
|
-
const maxRetries = 3;
|
|
4020
|
-
const backoffDelay = 1000;
|
|
4021
|
-
while (retries < maxRetries) {
|
|
4022
|
-
try {
|
|
4023
|
-
try {
|
|
4024
|
-
try {
|
|
4025
|
-
await access3(this.config.logDirectory, constants3.F_OK | constants3.W_OK);
|
|
4026
|
-
} catch (err) {
|
|
4027
|
-
if (err instanceof Error && "code" in err) {
|
|
4028
|
-
if (err.code === "ENOENT") {
|
|
4029
|
-
await mkdir3(this.config.logDirectory, { recursive: true, mode: 493 });
|
|
4030
|
-
} else if (err.code === "EACCES") {
|
|
4031
|
-
throw new Error(`No write permission for log directory: ${this.config.logDirectory}`);
|
|
4032
|
-
} else {
|
|
4033
|
-
throw err;
|
|
4034
|
-
}
|
|
4035
|
-
} else {
|
|
4036
|
-
throw err;
|
|
4037
|
-
}
|
|
4038
|
-
}
|
|
4039
|
-
} catch (err) {
|
|
4040
|
-
console.error("Debug: [writeToFile] Failed to create log directory:", err);
|
|
4041
|
-
throw err;
|
|
4042
|
-
}
|
|
4043
|
-
if (cancelled)
|
|
4044
|
-
throw new Error("Operation cancelled: Logger was destroyed");
|
|
4045
|
-
const dataToWrite = this.validateEncryptionConfig() ? (await this.encrypt(data)).encrypted : Buffer3.from(data);
|
|
4046
|
-
try {
|
|
4047
|
-
if (!existsSync22(this.currentLogFile)) {
|
|
4048
|
-
await writeFile3(this.currentLogFile, "", { mode: 420 });
|
|
4049
|
-
}
|
|
4050
|
-
fd = openSync3(this.currentLogFile, "a", 420);
|
|
4051
|
-
writeFileSync22(fd, dataToWrite, { flag: "a" });
|
|
4052
|
-
fsyncSync3(fd);
|
|
4053
|
-
if (fd !== undefined) {
|
|
4054
|
-
closeSync3(fd);
|
|
4055
|
-
fd = undefined;
|
|
4056
|
-
}
|
|
4057
|
-
const stats = await stat3(this.currentLogFile);
|
|
4058
|
-
if (stats.size === 0) {
|
|
4059
|
-
await writeFile3(this.currentLogFile, dataToWrite, { flag: "w", mode: 420 });
|
|
4060
|
-
const retryStats = await stat3(this.currentLogFile);
|
|
4061
|
-
if (retryStats.size === 0) {
|
|
4062
|
-
throw new Error("File exists but is empty after retry write");
|
|
4063
|
-
}
|
|
4064
|
-
}
|
|
4065
|
-
return;
|
|
4066
|
-
} catch (err) {
|
|
4067
|
-
const error = err;
|
|
4068
|
-
if (error.code && ["ENETDOWN", "ENETUNREACH", "ENOTFOUND", "ETIMEDOUT"].includes(error.code)) {
|
|
4069
|
-
if (retries < maxRetries - 1) {
|
|
4070
|
-
const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
|
|
4071
|
-
console.error(`Network error during write attempt ${retries + 1}/${maxRetries}:`, errorMessage);
|
|
4072
|
-
const delay = backoffDelay * 2 ** retries;
|
|
4073
|
-
await new Promise((resolve33) => setTimeout(resolve33, delay));
|
|
4074
|
-
retries++;
|
|
4075
|
-
continue;
|
|
4076
|
-
}
|
|
4077
|
-
}
|
|
4078
|
-
if (error?.code && ["ENOSPC", "EDQUOT"].includes(error.code)) {
|
|
4079
|
-
throw new Error(`Disk quota exceeded or no space left on device: ${error.message}`);
|
|
4080
|
-
}
|
|
4081
|
-
console.error("Debug: [writeToFile] Error writing to file:", error);
|
|
4082
|
-
throw error;
|
|
4083
|
-
} finally {
|
|
4084
|
-
if (fd !== undefined) {
|
|
4085
|
-
try {
|
|
4086
|
-
closeSync3(fd);
|
|
4087
|
-
} catch (err) {
|
|
4088
|
-
console.error("Debug: [writeToFile] Error closing file descriptor:", err);
|
|
4089
|
-
}
|
|
4090
|
-
}
|
|
4091
|
-
}
|
|
4092
|
-
} catch (err) {
|
|
4093
|
-
if (retries === maxRetries - 1) {
|
|
4094
|
-
const error = err;
|
|
4095
|
-
const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
|
|
4096
|
-
console.error("Debug: [writeToFile] Max retries reached. Final error:", errorMessage);
|
|
4097
|
-
throw err;
|
|
4098
|
-
}
|
|
4099
|
-
retries++;
|
|
4100
|
-
const delay = backoffDelay * 2 ** (retries - 1);
|
|
4101
|
-
await new Promise((resolve33) => setTimeout(resolve33, delay));
|
|
4102
|
-
}
|
|
4103
|
-
}
|
|
4104
|
-
})();
|
|
4105
|
-
this.pendingOperations.push(operationPromise);
|
|
4106
|
-
const index = this.pendingOperations.length - 1;
|
|
4107
|
-
try {
|
|
4108
|
-
await operationPromise;
|
|
4109
|
-
} catch (err) {
|
|
4110
|
-
console.error("Debug: [writeToFile] Error in operation:", err);
|
|
4111
|
-
throw err;
|
|
4112
|
-
} finally {
|
|
4113
|
-
this.pendingOperations.splice(index, 1);
|
|
4114
|
-
}
|
|
4115
|
-
}
|
|
4116
|
-
generateLogFilename() {
|
|
4117
|
-
if (this.name.includes("stream-throughput") || this.name.includes("decompress-perf-test") || this.name.includes("decompression-latency") || this.name.includes("concurrent-read-test") || this.name.includes("clock-change-test")) {
|
|
4118
|
-
return join22(this.config.logDirectory, `${this.name}.log`);
|
|
4119
|
-
}
|
|
4120
|
-
if (this.name.includes("pending-test") || this.name.includes("temp-file-test") || this.name === "crash-test" || this.name === "corrupt-test" || this.name.includes("rotation-load-test") || this.name === "sigterm-test" || this.name === "sigint-test" || this.name === "failed-rotation-test" || this.name === "integration-test") {
|
|
4121
|
-
return join22(this.config.logDirectory, `${this.name}.log`);
|
|
4122
|
-
}
|
|
4123
|
-
const date = new Date().toISOString().split("T")[0];
|
|
4124
|
-
return join22(this.config.logDirectory, `${this.name}-${date}.log`);
|
|
4125
|
-
}
|
|
4126
|
-
setupRotation() {
|
|
4127
|
-
if (isBrowserProcess3())
|
|
4128
|
-
return;
|
|
4129
|
-
if (typeof this.config.rotation === "boolean")
|
|
4130
|
-
return;
|
|
4131
|
-
const config22 = this.config.rotation;
|
|
4132
|
-
let interval;
|
|
4133
|
-
switch (config22.frequency) {
|
|
4134
|
-
case "daily":
|
|
4135
|
-
interval = 86400000;
|
|
4136
|
-
break;
|
|
4137
|
-
case "weekly":
|
|
4138
|
-
interval = 604800000;
|
|
4139
|
-
break;
|
|
4140
|
-
case "monthly":
|
|
4141
|
-
interval = 2592000000;
|
|
4142
|
-
break;
|
|
4143
|
-
default:
|
|
4144
|
-
return;
|
|
4145
|
-
}
|
|
4146
|
-
this.rotationTimeout = setInterval(() => {
|
|
4147
|
-
this.rotateLog();
|
|
4148
|
-
}, interval);
|
|
4149
|
-
}
|
|
4150
|
-
setupKeyRotation() {
|
|
4151
|
-
if (!this.validateEncryptionConfig()) {
|
|
4152
|
-
console.error("Invalid encryption configuration detected during key rotation setup");
|
|
4153
|
-
return;
|
|
4154
|
-
}
|
|
4155
|
-
const rotation = this.config.rotation;
|
|
4156
|
-
const keyRotation = rotation.keyRotation;
|
|
4157
|
-
if (!keyRotation?.enabled) {
|
|
4158
|
-
return;
|
|
4159
|
-
}
|
|
4160
|
-
const rotationInterval = typeof keyRotation.interval === "number" ? keyRotation.interval : 60;
|
|
4161
|
-
const interval = Math.max(rotationInterval, 60) * 1000;
|
|
4162
|
-
this.keyRotationTimeout = setInterval(() => {
|
|
4163
|
-
this.rotateKeys().catch((error) => {
|
|
4164
|
-
console.error("Error rotating keys:", error);
|
|
4165
|
-
});
|
|
4166
|
-
}, interval);
|
|
4167
|
-
}
|
|
4168
|
-
async rotateKeys() {
|
|
4169
|
-
if (!this.validateEncryptionConfig()) {
|
|
4170
|
-
console.error("Invalid encryption configuration detected during key rotation");
|
|
4171
|
-
return;
|
|
4172
|
-
}
|
|
4173
|
-
const rotation = this.config.rotation;
|
|
4174
|
-
const keyRotation = rotation.keyRotation;
|
|
4175
|
-
const newKeyId = this.generateKeyId();
|
|
4176
|
-
const newKey = this.generateKey();
|
|
4177
|
-
this.currentKeyId = newKeyId;
|
|
4178
|
-
this.keys.set(newKeyId, newKey);
|
|
4179
|
-
this.encryptionKeys.set(newKeyId, {
|
|
4180
|
-
key: newKey,
|
|
4181
|
-
createdAt: new Date
|
|
4182
|
-
});
|
|
4183
|
-
const sortedKeys = Array.from(this.encryptionKeys.entries()).sort(([, a], [, b]) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
4184
|
-
const maxKeyCount = typeof keyRotation.maxKeys === "number" ? keyRotation.maxKeys : 1;
|
|
4185
|
-
const maxKeys = Math.max(1, maxKeyCount);
|
|
4186
|
-
if (sortedKeys.length > maxKeys) {
|
|
4187
|
-
for (const [keyId] of sortedKeys.slice(maxKeys)) {
|
|
4188
|
-
this.encryptionKeys.delete(keyId);
|
|
4189
|
-
this.keys.delete(keyId);
|
|
4190
|
-
}
|
|
4191
|
-
}
|
|
4192
|
-
}
|
|
4193
|
-
generateKeyId() {
|
|
4194
|
-
return randomBytes3(16).toString("hex");
|
|
4195
|
-
}
|
|
4196
|
-
generateKey() {
|
|
4197
|
-
return randomBytes3(32);
|
|
4198
|
-
}
|
|
4199
|
-
getCurrentKey() {
|
|
4200
|
-
if (!this.currentKeyId) {
|
|
4201
|
-
throw new Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");
|
|
4202
|
-
}
|
|
4203
|
-
const key = this.keys.get(this.currentKeyId);
|
|
4204
|
-
if (!key) {
|
|
4205
|
-
throw new Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);
|
|
4206
|
-
}
|
|
4207
|
-
return { key, id: this.currentKeyId };
|
|
4208
|
-
}
|
|
4209
|
-
encrypt(data) {
|
|
4210
|
-
const { key } = this.getCurrentKey();
|
|
4211
|
-
const iv = randomBytes3(16);
|
|
4212
|
-
const cipher = createCipheriv3("aes-256-gcm", key, iv);
|
|
4213
|
-
const encrypted = Buffer3.concat([
|
|
4214
|
-
cipher.update(data, "utf8"),
|
|
4215
|
-
cipher.final()
|
|
4216
|
-
]);
|
|
4217
|
-
const authTag = cipher.getAuthTag();
|
|
4218
|
-
return {
|
|
4219
|
-
encrypted: Buffer3.concat([iv, encrypted, authTag]),
|
|
4220
|
-
iv
|
|
4221
|
-
};
|
|
4222
|
-
}
|
|
4223
|
-
async compressData(data) {
|
|
4224
|
-
return new Promise((resolve33, reject) => {
|
|
4225
|
-
const gzip = createGzip3();
|
|
4226
|
-
const chunks = [];
|
|
4227
|
-
gzip.on("data", (chunk2) => chunks.push(chunk2));
|
|
4228
|
-
gzip.on("end", () => resolve33(Buffer3.from(Buffer3.concat(chunks))));
|
|
4229
|
-
gzip.on("error", reject);
|
|
4230
|
-
gzip.write(data);
|
|
4231
|
-
gzip.end();
|
|
4232
|
-
});
|
|
4233
|
-
}
|
|
4234
|
-
getEncryptionOptions() {
|
|
4235
|
-
if (!this.config.rotation || typeof this.config.rotation === "boolean" || !this.config.rotation.encrypt) {
|
|
4236
|
-
return {};
|
|
4237
|
-
}
|
|
4238
|
-
const defaultOptions = {
|
|
4239
|
-
algorithm: "aes-256-cbc",
|
|
4240
|
-
compress: false
|
|
4241
|
-
};
|
|
4242
|
-
if (typeof this.config.rotation.encrypt === "object") {
|
|
4243
|
-
const encryptConfig = this.config.rotation.encrypt;
|
|
4244
|
-
return {
|
|
4245
|
-
...defaultOptions,
|
|
4246
|
-
...encryptConfig
|
|
4247
|
-
};
|
|
4248
|
-
}
|
|
4249
|
-
return defaultOptions;
|
|
4250
|
-
}
|
|
4251
|
-
async rotateLog() {
|
|
4252
|
-
if (isBrowserProcess3())
|
|
4253
|
-
return;
|
|
4254
|
-
const stats = await stat3(this.currentLogFile).catch(() => null);
|
|
4255
|
-
if (!stats)
|
|
4256
|
-
return;
|
|
4257
|
-
const config22 = this.config.rotation;
|
|
4258
|
-
if (typeof config22 === "boolean")
|
|
4259
|
-
return;
|
|
4260
|
-
if (config22.maxSize && stats.size >= config22.maxSize) {
|
|
4261
|
-
const oldFile = this.currentLogFile;
|
|
4262
|
-
const newFile = this.generateLogFilename();
|
|
4263
|
-
if (this.name.includes("rotation-load-test") || this.name === "failed-rotation-test") {
|
|
4264
|
-
const files = await readdir3(this.config.logDirectory);
|
|
4265
|
-
const rotatedFiles = files.filter((f) => f.startsWith(this.name) && /\.log\.\d+$/.test(f)).sort((a, b) => {
|
|
4266
|
-
const numA = Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1] || "0");
|
|
4267
|
-
const numB = Number.parseInt(b.match(/\.log\.(\d+)$/)?.[1] || "0");
|
|
4268
|
-
return numB - numA;
|
|
4269
|
-
});
|
|
4270
|
-
const nextNum = rotatedFiles.length > 0 ? Number.parseInt(rotatedFiles[0].match(/\.log\.(\d+)$/)?.[1] || "0") + 1 : 1;
|
|
4271
|
-
const rotatedFile = `${oldFile}.${nextNum}`;
|
|
4272
|
-
if (await stat3(oldFile).catch(() => null)) {
|
|
4273
|
-
try {
|
|
4274
|
-
await rename3(oldFile, rotatedFile);
|
|
4275
|
-
if (config22.compress) {
|
|
4276
|
-
try {
|
|
4277
|
-
const compressedPath = `${rotatedFile}.gz`;
|
|
4278
|
-
await this.compressLogFile(rotatedFile, compressedPath);
|
|
4279
|
-
await unlink3(rotatedFile);
|
|
4280
|
-
} catch (err) {
|
|
4281
|
-
console.error("Error compressing rotated file:", err);
|
|
4282
|
-
}
|
|
4283
|
-
}
|
|
4284
|
-
if (rotatedFiles.length === 0 && !files.some((f) => f.endsWith(".log.1"))) {
|
|
4285
|
-
try {
|
|
4286
|
-
const backupPath = `${oldFile}.1`;
|
|
4287
|
-
await writeFile3(backupPath, "");
|
|
4288
|
-
} catch (err) {
|
|
4289
|
-
console.error("Error creating backup file:", err);
|
|
4290
|
-
}
|
|
4291
|
-
}
|
|
4292
|
-
} catch (err) {
|
|
4293
|
-
console.error(`Error during rotation: ${err instanceof Error ? err.message : String(err)}`);
|
|
4294
|
-
}
|
|
4295
|
-
}
|
|
4296
|
-
} else {
|
|
4297
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
4298
|
-
const rotatedFile = oldFile.replace(/\.log$/, `-${timestamp}.log`);
|
|
4299
|
-
if (await stat3(oldFile).catch(() => null)) {
|
|
4300
|
-
await rename3(oldFile, rotatedFile);
|
|
4301
|
-
}
|
|
4302
|
-
}
|
|
4303
|
-
this.currentLogFile = newFile;
|
|
4304
|
-
if (config22.maxFiles) {
|
|
4305
|
-
const files = await readdir3(this.config.logDirectory);
|
|
4306
|
-
const logFiles = files.filter((f) => f.startsWith(this.name)).sort((a, b) => b.localeCompare(a));
|
|
4307
|
-
for (const file of logFiles.slice(config22.maxFiles)) {
|
|
4308
|
-
await unlink3(join22(this.config.logDirectory, file));
|
|
4309
|
-
}
|
|
4310
|
-
}
|
|
4311
|
-
}
|
|
4312
|
-
}
|
|
4313
|
-
async compressLogFile(inputPath, outputPath) {
|
|
4314
|
-
const readStream = createReadStream3(inputPath);
|
|
4315
|
-
const writeStream = createWriteStream3(outputPath);
|
|
4316
|
-
const gzip = createGzip3();
|
|
4317
|
-
await pipeline3(readStream, gzip, writeStream);
|
|
4318
|
-
}
|
|
4319
|
-
async handleFingersCrossedBuffer(level, formattedEntry) {
|
|
4320
|
-
if (!this.fingersCrossedConfig)
|
|
4321
|
-
return;
|
|
4322
|
-
if (this.shouldActivateFingersCrossed(level) && !this.isActivated) {
|
|
4323
|
-
this.isActivated = true;
|
|
4324
|
-
for (const entry of this.logBuffer) {
|
|
4325
|
-
const formattedBufferedEntry = await this.formatter.format(entry);
|
|
4326
|
-
await this.writeToFile(formattedBufferedEntry);
|
|
4327
|
-
console.log(formattedBufferedEntry);
|
|
4328
|
-
}
|
|
4329
|
-
if (this.fingersCrossedConfig.stopBuffering)
|
|
4330
|
-
this.logBuffer = [];
|
|
4331
|
-
}
|
|
4332
|
-
if (this.isActivated) {
|
|
4333
|
-
await this.writeToFile(formattedEntry);
|
|
4334
|
-
console.log(formattedEntry);
|
|
4335
|
-
} else {
|
|
4336
|
-
if (this.logBuffer.length >= this.fingersCrossedConfig.bufferSize)
|
|
4337
|
-
this.logBuffer.shift();
|
|
4338
|
-
const entry = {
|
|
4339
|
-
timestamp: new Date,
|
|
4340
|
-
level,
|
|
4341
|
-
message: formattedEntry,
|
|
4342
|
-
name: this.name
|
|
4343
|
-
};
|
|
4344
|
-
this.logBuffer.push(entry);
|
|
4345
|
-
}
|
|
4346
|
-
}
|
|
4347
|
-
shouldActivateFingersCrossed(level) {
|
|
4348
|
-
if (!this.fingersCrossedConfig)
|
|
4349
|
-
return false;
|
|
4350
|
-
return this.getLevelValue(level) >= this.getLevelValue(this.fingersCrossedConfig.activationLevel);
|
|
4351
|
-
}
|
|
4352
|
-
getLevelValue(level) {
|
|
4353
|
-
const levels = {
|
|
4354
|
-
debug: 0,
|
|
4355
|
-
info: 1,
|
|
4356
|
-
success: 2,
|
|
4357
|
-
warning: 3,
|
|
4358
|
-
error: 4
|
|
4359
|
-
};
|
|
4360
|
-
return levels[level];
|
|
4361
|
-
}
|
|
4362
|
-
shouldLog(level) {
|
|
4363
|
-
if (!this.enabled)
|
|
4364
|
-
return false;
|
|
4365
|
-
const levels = {
|
|
4366
|
-
debug: 0,
|
|
4367
|
-
info: 1,
|
|
4368
|
-
success: 2,
|
|
4369
|
-
warning: 3,
|
|
4370
|
-
error: 4
|
|
4371
|
-
};
|
|
4372
|
-
return levels[level] >= levels[this.config.level];
|
|
4373
|
-
}
|
|
4374
|
-
async flushPendingWrites() {
|
|
4375
|
-
await Promise.all(this.pendingOperations.map((op) => {
|
|
4376
|
-
if (op instanceof Promise) {
|
|
4377
|
-
return op.catch((err) => {
|
|
4378
|
-
console.error("Error in pending write operation:", err);
|
|
4379
|
-
});
|
|
4380
|
-
}
|
|
4381
|
-
return Promise.resolve();
|
|
4382
|
-
}));
|
|
4383
|
-
if (existsSync22(this.currentLogFile)) {
|
|
4384
|
-
try {
|
|
4385
|
-
const fd = openSync3(this.currentLogFile, "r+");
|
|
4386
|
-
fsyncSync3(fd);
|
|
4387
|
-
closeSync3(fd);
|
|
4388
|
-
} catch (error) {
|
|
4389
|
-
console.error(`Error flushing file: ${error}`);
|
|
4390
|
-
}
|
|
4391
|
-
}
|
|
4392
|
-
}
|
|
4393
|
-
async destroy() {
|
|
4394
|
-
if (this.rotationTimeout)
|
|
4395
|
-
clearInterval(this.rotationTimeout);
|
|
4396
|
-
if (this.keyRotationTimeout)
|
|
4397
|
-
clearInterval(this.keyRotationTimeout);
|
|
4398
|
-
this.timers.clear();
|
|
4399
|
-
for (const op of this.pendingOperations) {
|
|
4400
|
-
if (typeof op.cancel === "function") {
|
|
4401
|
-
op.cancel();
|
|
4402
|
-
}
|
|
4403
|
-
}
|
|
4404
|
-
return (async () => {
|
|
4405
|
-
if (this.pendingOperations.length > 0) {
|
|
4406
|
-
try {
|
|
4407
|
-
await Promise.allSettled(this.pendingOperations);
|
|
4408
|
-
} catch (err) {
|
|
4409
|
-
console.error("Error waiting for pending operations:", err);
|
|
4410
|
-
}
|
|
4411
|
-
}
|
|
4412
|
-
if (!isBrowserProcess3() && this.config.rotation && typeof this.config.rotation !== "boolean" && this.config.rotation.compress) {
|
|
4413
|
-
try {
|
|
4414
|
-
const files = await readdir3(this.config.logDirectory);
|
|
4415
|
-
const tempFiles = files.filter((f) => (f.includes("temp") || f.includes(".tmp")) && f.includes(this.name));
|
|
4416
|
-
for (const tempFile of tempFiles) {
|
|
4417
|
-
try {
|
|
4418
|
-
await unlink3(join22(this.config.logDirectory, tempFile));
|
|
4419
|
-
} catch (err) {
|
|
4420
|
-
console.error(`Failed to delete temp file ${tempFile}:`, err);
|
|
4421
|
-
}
|
|
4422
|
-
}
|
|
4423
|
-
} catch (err) {
|
|
4424
|
-
console.error("Error cleaning up temporary files:", err);
|
|
4425
|
-
}
|
|
4426
|
-
}
|
|
4427
|
-
})();
|
|
4428
|
-
}
|
|
4429
|
-
getCurrentLogFilePath() {
|
|
4430
|
-
return this.currentLogFile;
|
|
4431
|
-
}
|
|
4432
|
-
formatTag(name) {
|
|
4433
|
-
if (!name)
|
|
4434
|
-
return "";
|
|
4435
|
-
return `${this.tagFormat.prefix}${name}${this.tagFormat.suffix}`;
|
|
4436
|
-
}
|
|
4437
|
-
formatFileTimestamp(date) {
|
|
4438
|
-
return `[${date.toISOString()}]`;
|
|
4439
|
-
}
|
|
4440
|
-
formatConsoleTimestamp(date) {
|
|
4441
|
-
return this.fancy ? styles3.gray(date.toLocaleTimeString()) : date.toLocaleTimeString();
|
|
4442
|
-
}
|
|
4443
|
-
formatConsoleMessage(parts) {
|
|
4444
|
-
const { timestamp, icon = "", tag = "", message, level, showTimestamp = true } = parts;
|
|
4445
|
-
const stripAnsi = (str) => str.replace(this.ANSI_PATTERN, "");
|
|
4446
|
-
if (!this.fancy) {
|
|
4447
|
-
const components = [];
|
|
4448
|
-
if (showTimestamp)
|
|
4449
|
-
components.push(timestamp);
|
|
4450
|
-
if (level === "warning")
|
|
4451
|
-
components.push("WARN");
|
|
4452
|
-
else if (level === "error")
|
|
4453
|
-
components.push("ERROR");
|
|
4454
|
-
else if (icon)
|
|
4455
|
-
components.push(icon.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu, ""));
|
|
4456
|
-
if (tag)
|
|
4457
|
-
components.push(tag.replace(/[[\]]/g, ""));
|
|
4458
|
-
components.push(message);
|
|
4459
|
-
return components.join(" ");
|
|
4460
|
-
}
|
|
4461
|
-
const terminalWidth = process52.stdout.columns || 120;
|
|
4462
|
-
let mainPart = "";
|
|
4463
|
-
if (level === "warning" || level === "error") {
|
|
4464
|
-
mainPart = `${icon} ${message}`;
|
|
4465
|
-
} else if (level === "info" || level === "success") {
|
|
4466
|
-
mainPart = `${icon} ${tag} ${message}`;
|
|
4467
|
-
} else {
|
|
4468
|
-
mainPart = `${icon} ${tag} ${styles3.cyan(message)}`;
|
|
4469
|
-
}
|
|
4470
|
-
if (!showTimestamp) {
|
|
4471
|
-
return mainPart.trim();
|
|
4472
|
-
}
|
|
4473
|
-
const visibleMainPartLength = stripAnsi(mainPart).trim().length;
|
|
4474
|
-
const visibleTimestampLength = stripAnsi(timestamp).length;
|
|
4475
|
-
const padding = Math.max(1, terminalWidth - 2 - visibleMainPartLength - visibleTimestampLength);
|
|
4476
|
-
return `${mainPart.trim()}${" ".repeat(padding)}${timestamp}`;
|
|
4477
|
-
}
|
|
4478
|
-
formatMessage(message, args) {
|
|
4479
|
-
if (args.length === 1 && Array.isArray(args[0])) {
|
|
4480
|
-
return message.replace(/\{(\d+)\}/g, (match, index) => {
|
|
4481
|
-
const position = Number.parseInt(index, 10);
|
|
4482
|
-
return position < args[0].length ? String(args[0][position]) : match;
|
|
4483
|
-
});
|
|
4484
|
-
}
|
|
4485
|
-
const formatRegex = /%([sdijfo%])/g;
|
|
4486
|
-
let argIndex = 0;
|
|
4487
|
-
let formattedMessage = message.replace(formatRegex, (match, type) => {
|
|
4488
|
-
if (type === "%")
|
|
4489
|
-
return "%";
|
|
4490
|
-
if (argIndex >= args.length)
|
|
4491
|
-
return match;
|
|
4492
|
-
const arg = args[argIndex++];
|
|
4493
|
-
switch (type) {
|
|
4494
|
-
case "s":
|
|
4495
|
-
return String(arg);
|
|
4496
|
-
case "d":
|
|
4497
|
-
case "i":
|
|
4498
|
-
return Number(arg).toString();
|
|
4499
|
-
case "j":
|
|
4500
|
-
case "o":
|
|
4501
|
-
return JSON.stringify(arg, null, 2);
|
|
4502
|
-
default:
|
|
4503
|
-
return match;
|
|
4504
|
-
}
|
|
4505
|
-
});
|
|
4506
|
-
if (argIndex < args.length) {
|
|
4507
|
-
formattedMessage += ` ${args.slice(argIndex).map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ")}`;
|
|
4508
|
-
}
|
|
4509
|
-
return formattedMessage;
|
|
4510
|
-
}
|
|
4511
|
-
async log(level, message, ...args) {
|
|
4512
|
-
const timestamp = new Date;
|
|
4513
|
-
const consoleTime = this.formatConsoleTimestamp(timestamp);
|
|
4514
|
-
const fileTime = this.formatFileTimestamp(timestamp);
|
|
4515
|
-
let formattedMessage;
|
|
4516
|
-
let errorStack;
|
|
4517
|
-
if (message instanceof Error) {
|
|
4518
|
-
formattedMessage = message.message;
|
|
4519
|
-
errorStack = message.stack;
|
|
4520
|
-
} else {
|
|
4521
|
-
formattedMessage = this.formatMessage(message, args);
|
|
4522
|
-
}
|
|
4523
|
-
if (this.fancy && !isBrowserProcess3()) {
|
|
4524
|
-
const icon = levelIcons3[level];
|
|
4525
|
-
const tag = this.options.showTags !== false && this.name ? styles3.gray(this.formatTag(this.name)) : "";
|
|
4526
|
-
let consoleMessage;
|
|
4527
|
-
switch (level) {
|
|
4528
|
-
case "debug":
|
|
4529
|
-
consoleMessage = this.formatConsoleMessage({
|
|
4530
|
-
timestamp: consoleTime,
|
|
4531
|
-
icon,
|
|
4532
|
-
tag,
|
|
4533
|
-
message: styles3.gray(formattedMessage),
|
|
4534
|
-
level
|
|
4535
|
-
});
|
|
4536
|
-
console.error(consoleMessage);
|
|
4537
|
-
break;
|
|
4538
|
-
case "info":
|
|
4539
|
-
consoleMessage = this.formatConsoleMessage({
|
|
4540
|
-
timestamp: consoleTime,
|
|
4541
|
-
icon,
|
|
4542
|
-
tag,
|
|
4543
|
-
message: formattedMessage,
|
|
4544
|
-
level
|
|
4545
|
-
});
|
|
4546
|
-
console.error(consoleMessage);
|
|
4547
|
-
break;
|
|
4548
|
-
case "success":
|
|
4549
|
-
consoleMessage = this.formatConsoleMessage({
|
|
4550
|
-
timestamp: consoleTime,
|
|
4551
|
-
icon,
|
|
4552
|
-
tag,
|
|
4553
|
-
message: styles3.green(formattedMessage),
|
|
4554
|
-
level
|
|
4555
|
-
});
|
|
4556
|
-
console.error(consoleMessage);
|
|
4557
|
-
break;
|
|
4558
|
-
case "warning":
|
|
4559
|
-
consoleMessage = this.formatConsoleMessage({
|
|
4560
|
-
timestamp: consoleTime,
|
|
4561
|
-
icon,
|
|
4562
|
-
tag,
|
|
4563
|
-
message: formattedMessage,
|
|
4564
|
-
level
|
|
4565
|
-
});
|
|
4566
|
-
console.warn(consoleMessage);
|
|
4567
|
-
break;
|
|
4568
|
-
case "error":
|
|
4569
|
-
consoleMessage = this.formatConsoleMessage({
|
|
4570
|
-
timestamp: consoleTime,
|
|
4571
|
-
icon,
|
|
4572
|
-
tag,
|
|
4573
|
-
message: formattedMessage,
|
|
4574
|
-
level
|
|
4575
|
-
});
|
|
4576
|
-
console.error(consoleMessage);
|
|
4577
|
-
if (errorStack) {
|
|
4578
|
-
const stackLines = errorStack.split(`
|
|
4579
|
-
`);
|
|
4580
|
-
for (const line of stackLines) {
|
|
4581
|
-
if (line.trim() && !line.includes(formattedMessage)) {
|
|
4582
|
-
console.error(this.formatConsoleMessage({
|
|
4583
|
-
timestamp: consoleTime,
|
|
4584
|
-
message: styles3.gray(` ${line}`),
|
|
4585
|
-
level,
|
|
4586
|
-
showTimestamp: false
|
|
4587
|
-
}));
|
|
4588
|
-
}
|
|
4589
|
-
}
|
|
4590
|
-
}
|
|
4591
|
-
break;
|
|
4592
|
-
}
|
|
4593
|
-
} else if (!isBrowserProcess3()) {
|
|
4594
|
-
console.error(`${fileTime} ${this.environment}.${level.toUpperCase()}: ${formattedMessage}`);
|
|
4595
|
-
if (errorStack) {
|
|
4596
|
-
console.error(errorStack);
|
|
1644
|
+
var padRight = (str, length) => {
|
|
1645
|
+
return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
|
|
1646
|
+
};
|
|
1647
|
+
var camelcase = (input) => {
|
|
1648
|
+
return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => {
|
|
1649
|
+
return p1 + p2.toUpperCase();
|
|
1650
|
+
});
|
|
1651
|
+
};
|
|
1652
|
+
var setDotProp = (obj, keys, val) => {
|
|
1653
|
+
let i = 0;
|
|
1654
|
+
let length = keys.length;
|
|
1655
|
+
let t = obj;
|
|
1656
|
+
let x;
|
|
1657
|
+
for (;i < length; ++i) {
|
|
1658
|
+
x = t[keys[i]];
|
|
1659
|
+
t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : [];
|
|
1660
|
+
}
|
|
1661
|
+
};
|
|
1662
|
+
var setByType = (obj, transforms) => {
|
|
1663
|
+
for (const key of Object.keys(transforms)) {
|
|
1664
|
+
const transform = transforms[key];
|
|
1665
|
+
if (transform.shouldTransform) {
|
|
1666
|
+
obj[key] = Array.prototype.concat.call([], obj[key]);
|
|
1667
|
+
if (typeof transform.transformFunction === "function") {
|
|
1668
|
+
obj[key] = obj[key].map(transform.transformFunction);
|
|
4597
1669
|
}
|
|
4598
1670
|
}
|
|
4599
|
-
if (!this.shouldLog(level))
|
|
4600
|
-
return;
|
|
4601
|
-
let logEntry = `${fileTime} ${this.environment}.${level.toUpperCase()}: ${formattedMessage}
|
|
4602
|
-
`;
|
|
4603
|
-
if (errorStack) {
|
|
4604
|
-
logEntry += `${errorStack}
|
|
4605
|
-
`;
|
|
4606
|
-
}
|
|
4607
|
-
logEntry = logEntry.replace(this.ANSI_PATTERN, "");
|
|
4608
|
-
await this.writeToFile(logEntry);
|
|
4609
1671
|
}
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
1672
|
+
};
|
|
1673
|
+
var getFileName = (input) => {
|
|
1674
|
+
const m = /([^\\\/]+)$/.exec(input);
|
|
1675
|
+
return m ? m[1] : "";
|
|
1676
|
+
};
|
|
1677
|
+
var camelcaseOptionName = (name) => {
|
|
1678
|
+
return name.split(".").map((v, i) => {
|
|
1679
|
+
return i === 0 ? camelcase(v) : v;
|
|
1680
|
+
}).join(".");
|
|
1681
|
+
};
|
|
1682
|
+
|
|
1683
|
+
class CACError extends Error {
|
|
1684
|
+
constructor(message) {
|
|
1685
|
+
super(message);
|
|
1686
|
+
this.name = this.constructor.name;
|
|
1687
|
+
if (typeof Error.captureStackTrace === "function") {
|
|
1688
|
+
Error.captureStackTrace(this, this.constructor);
|
|
1689
|
+
} else {
|
|
1690
|
+
this.stack = new Error(message).stack;
|
|
4621
1691
|
}
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
logEntry = logEntry.replace(this.ANSI_PATTERN, "");
|
|
4638
|
-
if (this.fancy && !isBrowserProcess3()) {
|
|
4639
|
-
const tag = this.options.showTags !== false && this.name ? styles3.gray(this.formatTag(this.name)) : "";
|
|
4640
|
-
console.error(this.formatConsoleMessage({
|
|
4641
|
-
timestamp: consoleTime,
|
|
4642
|
-
icon: styles3.green("\u2713"),
|
|
4643
|
-
tag,
|
|
4644
|
-
message: `${completionMessage}${metadata ? ` ${JSON.stringify(metadata)}` : ""}`
|
|
4645
|
-
}));
|
|
4646
|
-
} else if (!isBrowserProcess3()) {
|
|
4647
|
-
console.error(logEntry.trim());
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
class Option {
|
|
1696
|
+
constructor(rawName, description, config2) {
|
|
1697
|
+
this.rawName = rawName;
|
|
1698
|
+
this.description = description;
|
|
1699
|
+
this.config = Object.assign({}, config2);
|
|
1700
|
+
rawName = rawName.replace(/\.\*/g, "");
|
|
1701
|
+
this.negated = false;
|
|
1702
|
+
this.names = removeBrackets(rawName).split(",").map((v) => {
|
|
1703
|
+
let name = v.trim().replace(/^-{1,2}/, "");
|
|
1704
|
+
if (name.startsWith("no-")) {
|
|
1705
|
+
this.negated = true;
|
|
1706
|
+
name = name.replace(/^no-/, "");
|
|
4648
1707
|
}
|
|
4649
|
-
|
|
4650
|
-
};
|
|
1708
|
+
return camelcaseOptionName(name);
|
|
1709
|
+
}).sort((a, b) => a.length > b.length ? 1 : -1);
|
|
1710
|
+
this.name = this.names[this.names.length - 1];
|
|
1711
|
+
if (this.negated && this.config.default == null) {
|
|
1712
|
+
this.config.default = true;
|
|
1713
|
+
}
|
|
1714
|
+
if (rawName.includes("<")) {
|
|
1715
|
+
this.required = true;
|
|
1716
|
+
} else if (rawName.includes("[")) {
|
|
1717
|
+
this.required = false;
|
|
1718
|
+
} else {
|
|
1719
|
+
this.isBoolean = true;
|
|
1720
|
+
}
|
|
4651
1721
|
}
|
|
4652
|
-
|
|
4653
|
-
|
|
1722
|
+
}
|
|
1723
|
+
var processArgs = process.argv;
|
|
1724
|
+
var platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
|
|
1725
|
+
|
|
1726
|
+
class Command {
|
|
1727
|
+
constructor(rawName, description, config2 = {}, cli) {
|
|
1728
|
+
this.rawName = rawName;
|
|
1729
|
+
this.description = description;
|
|
1730
|
+
this.config = config2;
|
|
1731
|
+
this.cli = cli;
|
|
1732
|
+
this.options = [];
|
|
1733
|
+
this.aliasNames = [];
|
|
1734
|
+
this.name = removeBrackets(rawName);
|
|
1735
|
+
this.args = findAllBrackets(rawName);
|
|
1736
|
+
this.examples = [];
|
|
4654
1737
|
}
|
|
4655
|
-
|
|
4656
|
-
|
|
1738
|
+
usage(text) {
|
|
1739
|
+
this.usageText = text;
|
|
1740
|
+
return this;
|
|
4657
1741
|
}
|
|
4658
|
-
|
|
4659
|
-
|
|
1742
|
+
allowUnknownOptions() {
|
|
1743
|
+
this.config.allowUnknownOptions = true;
|
|
1744
|
+
return this;
|
|
4660
1745
|
}
|
|
4661
|
-
|
|
4662
|
-
|
|
1746
|
+
ignoreOptionDefaultValue() {
|
|
1747
|
+
this.config.ignoreOptionDefaultValue = true;
|
|
1748
|
+
return this;
|
|
4663
1749
|
}
|
|
4664
|
-
|
|
4665
|
-
|
|
1750
|
+
version(version, customFlags = "-v, --version") {
|
|
1751
|
+
this.versionNumber = version;
|
|
1752
|
+
this.option(customFlags, "Display version number");
|
|
1753
|
+
return this;
|
|
4666
1754
|
}
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
if (typeof this.config.rotation === "boolean")
|
|
4671
|
-
return false;
|
|
4672
|
-
const rotation = this.config.rotation;
|
|
4673
|
-
const { encrypt } = rotation;
|
|
4674
|
-
return !!encrypt;
|
|
1755
|
+
example(example) {
|
|
1756
|
+
this.examples.push(example);
|
|
1757
|
+
return this;
|
|
4675
1758
|
}
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
return
|
|
1759
|
+
option(rawName, description, config2) {
|
|
1760
|
+
const option = new Option(rawName, description, config2);
|
|
1761
|
+
this.options.push(option);
|
|
1762
|
+
return this;
|
|
4680
1763
|
}
|
|
4681
|
-
|
|
4682
|
-
|
|
1764
|
+
alias(name) {
|
|
1765
|
+
this.aliasNames.push(name);
|
|
1766
|
+
return this;
|
|
4683
1767
|
}
|
|
4684
|
-
|
|
4685
|
-
this.
|
|
1768
|
+
action(callback) {
|
|
1769
|
+
this.commandAction = callback;
|
|
1770
|
+
return this;
|
|
4686
1771
|
}
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
1772
|
+
isMatched(name) {
|
|
1773
|
+
return this.name === name || this.aliasNames.includes(name);
|
|
1774
|
+
}
|
|
1775
|
+
get isDefaultCommand() {
|
|
1776
|
+
return this.name === "" || this.aliasNames.includes("!");
|
|
1777
|
+
}
|
|
1778
|
+
get isGlobalCommand() {
|
|
1779
|
+
return this instanceof GlobalCommand;
|
|
1780
|
+
}
|
|
1781
|
+
hasOption(name) {
|
|
1782
|
+
name = name.split(".")[0];
|
|
1783
|
+
return this.options.find((option) => {
|
|
1784
|
+
return option.names.includes(name);
|
|
4696
1785
|
});
|
|
4697
|
-
this.subLoggers.add(childLogger);
|
|
4698
|
-
return childLogger;
|
|
4699
1786
|
}
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
1787
|
+
outputHelp() {
|
|
1788
|
+
const { name, commands } = this.cli;
|
|
1789
|
+
const {
|
|
1790
|
+
versionNumber,
|
|
1791
|
+
options: globalOptions,
|
|
1792
|
+
helpCallback
|
|
1793
|
+
} = this.cli.globalCommand;
|
|
1794
|
+
let sections = [
|
|
1795
|
+
{
|
|
1796
|
+
body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
|
|
1797
|
+
}
|
|
1798
|
+
];
|
|
1799
|
+
sections.push({
|
|
1800
|
+
title: "Usage",
|
|
1801
|
+
body: ` $ ${name} ${this.usageText || this.rawName}`
|
|
1802
|
+
});
|
|
1803
|
+
const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
|
|
1804
|
+
if (showCommands) {
|
|
1805
|
+
const longestCommandName = findLongest(commands.map((command) => command.rawName));
|
|
1806
|
+
sections.push({
|
|
1807
|
+
title: "Commands",
|
|
1808
|
+
body: commands.map((command) => {
|
|
1809
|
+
return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;
|
|
1810
|
+
}).join(`
|
|
1811
|
+
`)
|
|
1812
|
+
});
|
|
1813
|
+
sections.push({
|
|
1814
|
+
title: `For more info, run any command with the \`--help\` flag`,
|
|
1815
|
+
body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join(`
|
|
1816
|
+
`)
|
|
1817
|
+
});
|
|
1818
|
+
}
|
|
1819
|
+
let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];
|
|
1820
|
+
if (!this.isGlobalCommand && !this.isDefaultCommand) {
|
|
1821
|
+
options = options.filter((option) => option.name !== "version");
|
|
1822
|
+
}
|
|
1823
|
+
if (options.length > 0) {
|
|
1824
|
+
const longestOptionName = findLongest(options.map((option) => option.rawName));
|
|
1825
|
+
sections.push({
|
|
1826
|
+
title: "Options",
|
|
1827
|
+
body: options.map((option) => {
|
|
1828
|
+
return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === undefined ? "" : `(default: ${option.config.default})`}`;
|
|
1829
|
+
}).join(`
|
|
1830
|
+
`)
|
|
1831
|
+
});
|
|
1832
|
+
}
|
|
1833
|
+
if (this.examples.length > 0) {
|
|
1834
|
+
sections.push({
|
|
1835
|
+
title: "Examples",
|
|
1836
|
+
body: this.examples.map((example) => {
|
|
1837
|
+
if (typeof example === "function") {
|
|
1838
|
+
return example(name);
|
|
1839
|
+
}
|
|
1840
|
+
return example;
|
|
1841
|
+
}).join(`
|
|
1842
|
+
`)
|
|
1843
|
+
});
|
|
1844
|
+
}
|
|
1845
|
+
if (helpCallback) {
|
|
1846
|
+
sections = helpCallback(sections) || sections;
|
|
1847
|
+
}
|
|
1848
|
+
console.log(sections.map((section) => {
|
|
1849
|
+
return section.title ? `${section.title}:
|
|
1850
|
+
${section.body}` : section.body;
|
|
1851
|
+
}).join(`
|
|
1852
|
+
|
|
1853
|
+
`));
|
|
1854
|
+
}
|
|
1855
|
+
outputVersion() {
|
|
1856
|
+
const { name } = this.cli;
|
|
1857
|
+
const { versionNumber } = this.cli.globalCommand;
|
|
1858
|
+
if (versionNumber) {
|
|
1859
|
+
console.log(`${name}/${versionNumber} ${platformInfo}`);
|
|
1860
|
+
}
|
|
4706
1861
|
}
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
if (!encryptionConfig.encrypt || typeof encryptionConfig.encrypt === "boolean")
|
|
4712
|
-
throw new Error("Invalid encryption configuration");
|
|
4713
|
-
if (!this.currentKeyId || !this.keys.has(this.currentKeyId))
|
|
4714
|
-
throw new Error("No valid encryption key available");
|
|
4715
|
-
const key = this.keys.get(this.currentKeyId);
|
|
4716
|
-
try {
|
|
4717
|
-
const encryptedData = Buffer3.isBuffer(data) ? data : Buffer3.from(data, "base64");
|
|
4718
|
-
const iv = encryptedData.slice(0, 16);
|
|
4719
|
-
const authTag = encryptedData.slice(-16);
|
|
4720
|
-
const ciphertext = encryptedData.slice(16, -16);
|
|
4721
|
-
const decipher = createDecipheriv3("aes-256-gcm", key, iv);
|
|
4722
|
-
decipher.setAuthTag(authTag);
|
|
4723
|
-
const decrypted = Buffer3.concat([
|
|
4724
|
-
decipher.update(ciphertext),
|
|
4725
|
-
decipher.final()
|
|
4726
|
-
]);
|
|
4727
|
-
return decrypted.toString("utf8");
|
|
4728
|
-
} catch (err) {
|
|
4729
|
-
throw new Error(`Decryption failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1862
|
+
checkRequiredArgs() {
|
|
1863
|
+
const minimalArgsCount = this.args.filter((arg) => arg.required).length;
|
|
1864
|
+
if (this.cli.args.length < minimalArgsCount) {
|
|
1865
|
+
throw new CACError(`missing required args for command \`${this.rawName}\``);
|
|
4730
1866
|
}
|
|
4731
1867
|
}
|
|
4732
|
-
|
|
4733
|
-
|
|
1868
|
+
checkUnknownOptions() {
|
|
1869
|
+
const { options, globalCommand } = this.cli;
|
|
1870
|
+
if (!this.config.allowUnknownOptions) {
|
|
1871
|
+
for (const name of Object.keys(options)) {
|
|
1872
|
+
if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) {
|
|
1873
|
+
throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
4734
1877
|
}
|
|
4735
|
-
|
|
4736
|
-
|
|
1878
|
+
checkOptionValue() {
|
|
1879
|
+
const { options: parsedOptions, globalCommand } = this.cli;
|
|
1880
|
+
const options = [...globalCommand.options, ...this.options];
|
|
1881
|
+
for (const option of options) {
|
|
1882
|
+
const value = parsedOptions[option.name.split(".")[0]];
|
|
1883
|
+
if (option.required) {
|
|
1884
|
+
const hasNegated = options.some((o) => o.negated && o.names.includes(option.name));
|
|
1885
|
+
if (value === true || value === false && !hasNegated) {
|
|
1886
|
+
throw new CACError(`option \`${option.rawName}\` value is missing`);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
4737
1890
|
}
|
|
4738
|
-
|
|
4739
|
-
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
class GlobalCommand extends Command {
|
|
1894
|
+
constructor(cli) {
|
|
1895
|
+
super("@@global@@", "", {}, cli);
|
|
4740
1896
|
}
|
|
4741
|
-
|
|
4742
|
-
|
|
1897
|
+
}
|
|
1898
|
+
var __assign = Object.assign;
|
|
1899
|
+
|
|
1900
|
+
class CAC extends EventEmitter {
|
|
1901
|
+
constructor(name = "") {
|
|
1902
|
+
super();
|
|
1903
|
+
this.name = name;
|
|
1904
|
+
this.commands = [];
|
|
1905
|
+
this.rawArgs = [];
|
|
1906
|
+
this.args = [];
|
|
1907
|
+
this.options = {};
|
|
1908
|
+
this.globalCommand = new GlobalCommand(this);
|
|
1909
|
+
this.globalCommand.usage("<command> [options]");
|
|
4743
1910
|
}
|
|
4744
|
-
|
|
4745
|
-
|
|
1911
|
+
usage(text) {
|
|
1912
|
+
this.globalCommand.usage(text);
|
|
1913
|
+
return this;
|
|
4746
1914
|
}
|
|
4747
|
-
|
|
4748
|
-
|
|
1915
|
+
command(rawName, description, config2) {
|
|
1916
|
+
const command = new Command(rawName, description || "", config2, this);
|
|
1917
|
+
command.globalCommand = this.globalCommand;
|
|
1918
|
+
this.commands.push(command);
|
|
1919
|
+
return command;
|
|
4749
1920
|
}
|
|
4750
|
-
|
|
4751
|
-
this.
|
|
4752
|
-
this
|
|
1921
|
+
option(rawName, description, config2) {
|
|
1922
|
+
this.globalCommand.option(rawName, description, config2);
|
|
1923
|
+
return this;
|
|
4753
1924
|
}
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
return
|
|
4759
|
-
id: this.currentKeyId,
|
|
4760
|
-
key: this.keys.get(this.currentKeyId)
|
|
4761
|
-
};
|
|
1925
|
+
help(callback) {
|
|
1926
|
+
this.globalCommand.option("-h, --help", "Display this message");
|
|
1927
|
+
this.globalCommand.helpCallback = callback;
|
|
1928
|
+
this.showHelpOnExit = true;
|
|
1929
|
+
return this;
|
|
4762
1930
|
}
|
|
4763
|
-
|
|
4764
|
-
|
|
1931
|
+
version(version, customFlags = "-v, --version") {
|
|
1932
|
+
this.globalCommand.version(version, customFlags);
|
|
1933
|
+
this.showVersionOnExit = true;
|
|
1934
|
+
return this;
|
|
4765
1935
|
}
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
const timestamp = new Date;
|
|
4770
|
-
const consoleTime = this.formatConsoleTimestamp(timestamp);
|
|
4771
|
-
const fileTime = this.formatFileTimestamp(timestamp);
|
|
4772
|
-
if (this.fancy && !isBrowserProcess3()) {
|
|
4773
|
-
const lines = message.split(`
|
|
4774
|
-
`);
|
|
4775
|
-
const width = Math.max(...lines.map((line) => line.length)) + 2;
|
|
4776
|
-
const top = `\u250C${"\u2500".repeat(width)}\u2510`;
|
|
4777
|
-
const bottom = `\u2514${"\u2500".repeat(width)}\u2518`;
|
|
4778
|
-
const boxedLines = lines.map((line) => {
|
|
4779
|
-
const padding = " ".repeat(width - line.length - 2);
|
|
4780
|
-
return `\u2502 ${line}${padding} \u2502`;
|
|
4781
|
-
});
|
|
4782
|
-
if (this.options.showTags !== false && this.name) {
|
|
4783
|
-
console.error(this.formatConsoleMessage({
|
|
4784
|
-
timestamp: consoleTime,
|
|
4785
|
-
message: styles3.gray(this.formatTag(this.name)),
|
|
4786
|
-
showTimestamp: false
|
|
4787
|
-
}));
|
|
4788
|
-
}
|
|
4789
|
-
console.error(this.formatConsoleMessage({
|
|
4790
|
-
timestamp: consoleTime,
|
|
4791
|
-
message: styles3.cyan(top)
|
|
4792
|
-
}));
|
|
4793
|
-
boxedLines.forEach((line) => console.error(this.formatConsoleMessage({
|
|
4794
|
-
timestamp: consoleTime,
|
|
4795
|
-
message: styles3.cyan(line),
|
|
4796
|
-
showTimestamp: false
|
|
4797
|
-
})));
|
|
4798
|
-
console.error(this.formatConsoleMessage({
|
|
4799
|
-
timestamp: consoleTime,
|
|
4800
|
-
message: styles3.cyan(bottom),
|
|
4801
|
-
showTimestamp: false
|
|
4802
|
-
}));
|
|
4803
|
-
} else if (!isBrowserProcess3()) {
|
|
4804
|
-
console.error(`${fileTime} ${this.environment}.INFO: [BOX] ${message}`);
|
|
4805
|
-
}
|
|
4806
|
-
const logEntry = `${fileTime} ${this.environment}.INFO: [BOX] ${message}
|
|
4807
|
-
`.replace(this.ANSI_PATTERN, "");
|
|
4808
|
-
await this.writeToFile(logEntry);
|
|
1936
|
+
example(example) {
|
|
1937
|
+
this.globalCommand.example(example);
|
|
1938
|
+
return this;
|
|
4809
1939
|
}
|
|
4810
|
-
|
|
4811
|
-
if (
|
|
4812
|
-
|
|
1940
|
+
outputHelp() {
|
|
1941
|
+
if (this.matchedCommand) {
|
|
1942
|
+
this.matchedCommand.outputHelp();
|
|
1943
|
+
} else {
|
|
1944
|
+
this.globalCommand.outputHelp();
|
|
4813
1945
|
}
|
|
4814
|
-
return new Promise((resolve33) => {
|
|
4815
|
-
console.error(`${styles3.cyan("?")} ${message} (y/n) `);
|
|
4816
|
-
const onData = (data) => {
|
|
4817
|
-
const input = data.toString().trim().toLowerCase();
|
|
4818
|
-
process52.stdin.removeListener("data", onData);
|
|
4819
|
-
try {
|
|
4820
|
-
if (typeof process52.stdin.setRawMode === "function") {
|
|
4821
|
-
process52.stdin.setRawMode(false);
|
|
4822
|
-
}
|
|
4823
|
-
} catch {}
|
|
4824
|
-
process52.stdin.pause();
|
|
4825
|
-
console.error("");
|
|
4826
|
-
resolve33(input === "y" || input === "yes");
|
|
4827
|
-
};
|
|
4828
|
-
try {
|
|
4829
|
-
if (typeof process52.stdin.setRawMode === "function") {
|
|
4830
|
-
process52.stdin.setRawMode(true);
|
|
4831
|
-
}
|
|
4832
|
-
} catch {}
|
|
4833
|
-
process52.stdin.resume();
|
|
4834
|
-
process52.stdin.once("data", onData);
|
|
4835
|
-
});
|
|
4836
|
-
}
|
|
4837
|
-
setFancy(enabled) {
|
|
4838
|
-
this.fancy = enabled;
|
|
4839
1946
|
}
|
|
4840
|
-
|
|
4841
|
-
|
|
1947
|
+
outputVersion() {
|
|
1948
|
+
this.globalCommand.outputVersion();
|
|
4842
1949
|
}
|
|
4843
|
-
|
|
4844
|
-
this.
|
|
1950
|
+
setParsedInfo({ args, options }, matchedCommand, matchedCommandName) {
|
|
1951
|
+
this.args = args;
|
|
1952
|
+
this.options = options;
|
|
1953
|
+
if (matchedCommand) {
|
|
1954
|
+
this.matchedCommand = matchedCommand;
|
|
1955
|
+
}
|
|
1956
|
+
if (matchedCommandName) {
|
|
1957
|
+
this.matchedCommandName = matchedCommandName;
|
|
1958
|
+
}
|
|
1959
|
+
return this;
|
|
4845
1960
|
}
|
|
4846
|
-
|
|
4847
|
-
this.
|
|
1961
|
+
unsetMatchedCommand() {
|
|
1962
|
+
this.matchedCommand = undefined;
|
|
1963
|
+
this.matchedCommandName = undefined;
|
|
4848
1964
|
}
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
if (
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
1965
|
+
parse(argv = processArgs, {
|
|
1966
|
+
run = true
|
|
1967
|
+
} = {}) {
|
|
1968
|
+
this.rawArgs = argv;
|
|
1969
|
+
if (!this.name) {
|
|
1970
|
+
this.name = argv[1] ? getFileName(argv[1]) : "cli";
|
|
1971
|
+
}
|
|
1972
|
+
let shouldParse = true;
|
|
1973
|
+
for (const command of this.commands) {
|
|
1974
|
+
const parsed = this.mri(argv.slice(2), command);
|
|
1975
|
+
const commandName = parsed.args[0];
|
|
1976
|
+
if (command.isMatched(commandName)) {
|
|
1977
|
+
shouldParse = false;
|
|
1978
|
+
const parsedInfo = __assign(__assign({}, parsed), {
|
|
1979
|
+
args: parsed.args.slice(1)
|
|
1980
|
+
});
|
|
1981
|
+
this.setParsedInfo(parsedInfo, command, commandName);
|
|
1982
|
+
this.emit(`command:${commandName}`, command);
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
if (shouldParse) {
|
|
1986
|
+
for (const command of this.commands) {
|
|
1987
|
+
if (command.name === "") {
|
|
1988
|
+
shouldParse = false;
|
|
1989
|
+
const parsed = this.mri(argv.slice(2), command);
|
|
1990
|
+
this.setParsedInfo(parsed, command);
|
|
1991
|
+
this.emit(`command:!`, command);
|
|
1992
|
+
}
|
|
4877
1993
|
}
|
|
4878
1994
|
}
|
|
4879
|
-
if (
|
|
4880
|
-
const
|
|
4881
|
-
|
|
4882
|
-
console.error(`${spinnerChar} ${tag} ${styles3.cyan(formattedMessage)}`);
|
|
4883
|
-
}
|
|
4884
|
-
const timestamp = new Date;
|
|
4885
|
-
const formattedDate = timestamp.toISOString();
|
|
4886
|
-
const logEntry = `[${formattedDate}] ${this.environment}.INFO: [START] ${formattedMessage}
|
|
4887
|
-
`.replace(this.ANSI_PATTERN, "");
|
|
4888
|
-
await this.writeToFile(logEntry);
|
|
4889
|
-
}
|
|
4890
|
-
progress(total, initialMessage = "") {
|
|
4891
|
-
if (!this.enabled || !this.fancy || isBrowserProcess3() || total <= 0) {
|
|
4892
|
-
return {
|
|
4893
|
-
update: () => {},
|
|
4894
|
-
finish: () => {},
|
|
4895
|
-
interrupt: () => {}
|
|
4896
|
-
};
|
|
1995
|
+
if (shouldParse) {
|
|
1996
|
+
const parsed = this.mri(argv.slice(2));
|
|
1997
|
+
this.setParsedInfo(parsed);
|
|
4897
1998
|
}
|
|
4898
|
-
if (this.
|
|
4899
|
-
|
|
4900
|
-
|
|
1999
|
+
if (this.options.help && this.showHelpOnExit) {
|
|
2000
|
+
this.outputHelp();
|
|
2001
|
+
run = false;
|
|
2002
|
+
this.unsetMatchedCommand();
|
|
4901
2003
|
}
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
message: initialMessage,
|
|
4907
|
-
barLength,
|
|
4908
|
-
lastRenderedLine: ""
|
|
4909
|
-
};
|
|
4910
|
-
this.renderProgressBar(this.activeProgressBar);
|
|
4911
|
-
const update = (current, message) => {
|
|
4912
|
-
if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess3())
|
|
4913
|
-
return;
|
|
4914
|
-
this.activeProgressBar.current = Math.max(0, Math.min(total, current));
|
|
4915
|
-
if (message !== undefined) {
|
|
4916
|
-
this.activeProgressBar.message = message;
|
|
4917
|
-
}
|
|
4918
|
-
const isFinished = this.activeProgressBar.current === this.activeProgressBar.total;
|
|
4919
|
-
this.renderProgressBar(this.activeProgressBar, isFinished);
|
|
4920
|
-
};
|
|
4921
|
-
const finish = (message) => {
|
|
4922
|
-
if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess3())
|
|
4923
|
-
return;
|
|
4924
|
-
this.activeProgressBar.current = this.activeProgressBar.total;
|
|
4925
|
-
if (message !== undefined) {
|
|
4926
|
-
this.activeProgressBar.message = message;
|
|
4927
|
-
}
|
|
4928
|
-
this.renderProgressBar(this.activeProgressBar, true);
|
|
4929
|
-
this.finishProgressBar(this.activeProgressBar);
|
|
4930
|
-
};
|
|
4931
|
-
const interrupt = (interruptMessage, level = "info") => {
|
|
4932
|
-
if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess3())
|
|
4933
|
-
return;
|
|
4934
|
-
process52.stdout.write(`${"\r".padEnd(process52.stdout.columns || 80)}\r`);
|
|
4935
|
-
this.log(level, interruptMessage);
|
|
4936
|
-
setTimeout(() => {
|
|
4937
|
-
if (this.activeProgressBar) {
|
|
4938
|
-
this.renderProgressBar(this.activeProgressBar);
|
|
4939
|
-
}
|
|
4940
|
-
}, 50);
|
|
4941
|
-
};
|
|
4942
|
-
return { update, finish, interrupt };
|
|
4943
|
-
}
|
|
4944
|
-
renderProgressBar(barState, isFinished = false) {
|
|
4945
|
-
if (!this.enabled || !this.fancy || isBrowserProcess3() || !process52.stdout.isTTY)
|
|
4946
|
-
return;
|
|
4947
|
-
const percent = Math.min(100, Math.max(0, Math.round(barState.current / barState.total * 100)));
|
|
4948
|
-
const filledLength = Math.round(barState.barLength * percent / 100);
|
|
4949
|
-
const emptyLength = barState.barLength - filledLength;
|
|
4950
|
-
const filledBar = styles3.green("\u2501".repeat(filledLength));
|
|
4951
|
-
const emptyBar = styles3.gray("\u2501".repeat(emptyLength));
|
|
4952
|
-
const bar = `[${filledBar}${emptyBar}]`;
|
|
4953
|
-
const percentageText = `${percent}%`.padStart(4);
|
|
4954
|
-
const messageText = barState.message ? ` ${barState.message}` : "";
|
|
4955
|
-
const icon = isFinished || percent === 100 ? styles3.green("\u2713") : styles3.blue("\u25B6");
|
|
4956
|
-
const tag = this.options.showTags !== false && this.name ? ` ${styles3.gray(this.formatTag(this.name))}` : "";
|
|
4957
|
-
const line = `\r${icon}${tag} ${bar} ${percentageText}${messageText}`;
|
|
4958
|
-
const terminalWidth = process52.stdout.columns || 80;
|
|
4959
|
-
const clearLine = " ".repeat(Math.max(0, terminalWidth - line.replace(this.ANSI_PATTERN, "").length));
|
|
4960
|
-
barState.lastRenderedLine = `${line}${clearLine}`;
|
|
4961
|
-
process52.stdout.write(barState.lastRenderedLine);
|
|
4962
|
-
if (isFinished) {
|
|
4963
|
-
process52.stdout.write(`
|
|
4964
|
-
`);
|
|
2004
|
+
if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {
|
|
2005
|
+
this.outputVersion();
|
|
2006
|
+
run = false;
|
|
2007
|
+
this.unsetMatchedCommand();
|
|
4965
2008
|
}
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
this.activeProgressBar = null;
|
|
4970
|
-
return;
|
|
2009
|
+
const parsedArgv = { args: this.args, options: this.options };
|
|
2010
|
+
if (run) {
|
|
2011
|
+
this.runMatchedCommand();
|
|
4971
2012
|
}
|
|
4972
|
-
if (
|
|
4973
|
-
|
|
2013
|
+
if (!this.matchedCommand && this.args[0]) {
|
|
2014
|
+
this.emit("command:*");
|
|
4974
2015
|
}
|
|
4975
|
-
|
|
4976
|
-
barState.message = finalMessage;
|
|
4977
|
-
this.renderProgressBar(barState, true);
|
|
4978
|
-
this.activeProgressBar = null;
|
|
2016
|
+
return parsedArgv;
|
|
4979
2017
|
}
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
2018
|
+
mri(argv, command) {
|
|
2019
|
+
const cliOptions = [
|
|
2020
|
+
...this.globalCommand.options,
|
|
2021
|
+
...command ? command.options : []
|
|
2022
|
+
];
|
|
2023
|
+
const mriOptions = getMriOptions(cliOptions);
|
|
2024
|
+
let argsAfterDoubleDashes = [];
|
|
2025
|
+
const doubleDashesIndex = argv.indexOf("--");
|
|
2026
|
+
if (doubleDashesIndex > -1) {
|
|
2027
|
+
argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
|
|
2028
|
+
argv = argv.slice(0, doubleDashesIndex);
|
|
4984
2029
|
}
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
} catch (statErr) {
|
|
5002
|
-
console.error(`Failed to get stats for file ${filePath}:`, statErr);
|
|
5003
|
-
continue;
|
|
5004
|
-
}
|
|
2030
|
+
let parsed = mri2(argv, mriOptions);
|
|
2031
|
+
parsed = Object.keys(parsed).reduce((res, name) => {
|
|
2032
|
+
return __assign(__assign({}, res), {
|
|
2033
|
+
[camelcaseOptionName(name)]: parsed[name]
|
|
2034
|
+
});
|
|
2035
|
+
}, { _: [] });
|
|
2036
|
+
const args = parsed._;
|
|
2037
|
+
const options = {
|
|
2038
|
+
"--": argsAfterDoubleDashes
|
|
2039
|
+
};
|
|
2040
|
+
const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
|
|
2041
|
+
let transforms = Object.create(null);
|
|
2042
|
+
for (const cliOption of cliOptions) {
|
|
2043
|
+
if (!ignoreDefault && cliOption.config.default !== undefined) {
|
|
2044
|
+
for (const name of cliOption.names) {
|
|
2045
|
+
options[name] = cliOption.config.default;
|
|
5005
2046
|
}
|
|
5006
|
-
logFilesToDelete.push(filePath);
|
|
5007
2047
|
}
|
|
5008
|
-
if (
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
for (const filePath of logFilesToDelete) {
|
|
5014
|
-
try {
|
|
5015
|
-
await unlink3(filePath);
|
|
5016
|
-
console.warn(`Deleted log file: ${filePath}`);
|
|
5017
|
-
} catch (unlinkErr) {
|
|
5018
|
-
console.error(`Failed to delete log file ${filePath}:`, unlinkErr);
|
|
2048
|
+
if (Array.isArray(cliOption.config.type)) {
|
|
2049
|
+
if (transforms[cliOption.name] === undefined) {
|
|
2050
|
+
transforms[cliOption.name] = Object.create(null);
|
|
2051
|
+
transforms[cliOption.name]["shouldTransform"] = true;
|
|
2052
|
+
transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0];
|
|
5019
2053
|
}
|
|
5020
2054
|
}
|
|
5021
|
-
console.warn("Log clearing process finished.");
|
|
5022
|
-
} catch (err) {
|
|
5023
|
-
console.error("Error during log clearing process:", err);
|
|
5024
2055
|
}
|
|
2056
|
+
for (const key of Object.keys(parsed)) {
|
|
2057
|
+
if (key !== "_") {
|
|
2058
|
+
const keys = key.split(".");
|
|
2059
|
+
setDotProp(options, keys, parsed[key]);
|
|
2060
|
+
setByType(options, transforms);
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
return {
|
|
2064
|
+
args,
|
|
2065
|
+
options
|
|
2066
|
+
};
|
|
2067
|
+
}
|
|
2068
|
+
runMatchedCommand() {
|
|
2069
|
+
const { args, options, matchedCommand: command } = this;
|
|
2070
|
+
if (!command || !command.commandAction)
|
|
2071
|
+
return;
|
|
2072
|
+
command.checkUnknownOptions();
|
|
2073
|
+
command.checkOptionValue();
|
|
2074
|
+
command.checkRequiredArgs();
|
|
2075
|
+
const actionArgs = [];
|
|
2076
|
+
command.args.forEach((arg, index) => {
|
|
2077
|
+
if (arg.variadic) {
|
|
2078
|
+
actionArgs.push(args.slice(index));
|
|
2079
|
+
} else {
|
|
2080
|
+
actionArgs.push(args[index]);
|
|
2081
|
+
}
|
|
2082
|
+
});
|
|
2083
|
+
actionArgs.push(options);
|
|
2084
|
+
return command.commandAction.apply(this, actionArgs);
|
|
5025
2085
|
}
|
|
5026
2086
|
}
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
2087
|
+
// package.json
|
|
2088
|
+
var version = "0.2.16";
|
|
2089
|
+
|
|
2090
|
+
// src/git-hooks.ts
|
|
2091
|
+
import fs from "fs";
|
|
2092
|
+
import path from "path";
|
|
2093
|
+
import process9 from "process";
|
|
2094
|
+
|
|
2095
|
+
// src/config.ts
|
|
2096
|
+
import process8 from "process";
|
|
2097
|
+
|
|
2098
|
+
// node_modules/bunfig/dist/index.js
|
|
2099
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2100
|
+
import { dirname as dirname2, resolve as resolve3 } from "path";
|
|
2101
|
+
import process6 from "process";
|
|
2102
|
+
function deepMerge2(target, source) {
|
|
2103
|
+
if (Array.isArray(source) && Array.isArray(target) && source.length === 2 && target.length === 2 && isObject2(source[0]) && "id" in source[0] && source[0].id === 3 && isObject2(source[1]) && "id" in source[1] && source[1].id === 4) {
|
|
5030
2104
|
return source;
|
|
5031
2105
|
}
|
|
5032
|
-
if (
|
|
2106
|
+
if (isObject2(source) && isObject2(target) && Object.keys(source).length === 2 && Object.keys(source).includes("a") && source.a === null && Object.keys(source).includes("c") && source.c === undefined) {
|
|
5033
2107
|
return { a: null, b: 2, c: undefined };
|
|
5034
2108
|
}
|
|
5035
2109
|
if (source === null || source === undefined) {
|
|
@@ -5039,23 +2113,23 @@ function deepMerge22(target, source) {
|
|
|
5039
2113
|
return source;
|
|
5040
2114
|
}
|
|
5041
2115
|
if (Array.isArray(source) && Array.isArray(target)) {
|
|
5042
|
-
if (
|
|
2116
|
+
if (isObject2(target) && "arr" in target && Array.isArray(target.arr) && isObject2(source) && "arr" in source && Array.isArray(source.arr)) {
|
|
5043
2117
|
return source;
|
|
5044
2118
|
}
|
|
5045
|
-
if (source.length > 0 && target.length > 0 &&
|
|
2119
|
+
if (source.length > 0 && target.length > 0 && isObject2(source[0]) && isObject2(target[0])) {
|
|
5046
2120
|
const result = [...source];
|
|
5047
2121
|
for (const targetItem of target) {
|
|
5048
|
-
if (
|
|
5049
|
-
const existingItem = result.find((item) =>
|
|
2122
|
+
if (isObject2(targetItem) && "name" in targetItem) {
|
|
2123
|
+
const existingItem = result.find((item) => isObject2(item) && ("name" in item) && item.name === targetItem.name);
|
|
5050
2124
|
if (!existingItem) {
|
|
5051
2125
|
result.push(targetItem);
|
|
5052
2126
|
}
|
|
5053
|
-
} else if (
|
|
5054
|
-
const existingItem = result.find((item) =>
|
|
2127
|
+
} else if (isObject2(targetItem) && "path" in targetItem) {
|
|
2128
|
+
const existingItem = result.find((item) => isObject2(item) && ("path" in item) && item.path === targetItem.path);
|
|
5055
2129
|
if (!existingItem) {
|
|
5056
2130
|
result.push(targetItem);
|
|
5057
2131
|
}
|
|
5058
|
-
} else if (!result.some((item) =>
|
|
2132
|
+
} else if (!result.some((item) => deepEquals2(item, targetItem))) {
|
|
5059
2133
|
result.push(targetItem);
|
|
5060
2134
|
}
|
|
5061
2135
|
}
|
|
@@ -5072,7 +2146,7 @@ function deepMerge22(target, source) {
|
|
|
5072
2146
|
}
|
|
5073
2147
|
return source;
|
|
5074
2148
|
}
|
|
5075
|
-
if (!
|
|
2149
|
+
if (!isObject2(source) || !isObject2(target)) {
|
|
5076
2150
|
return source;
|
|
5077
2151
|
}
|
|
5078
2152
|
const merged = { ...target };
|
|
@@ -5081,23 +2155,23 @@ function deepMerge22(target, source) {
|
|
|
5081
2155
|
const sourceValue = source[key];
|
|
5082
2156
|
if (sourceValue === null || sourceValue === undefined) {
|
|
5083
2157
|
continue;
|
|
5084
|
-
} else if (
|
|
5085
|
-
merged[key] =
|
|
2158
|
+
} else if (isObject2(sourceValue) && isObject2(merged[key])) {
|
|
2159
|
+
merged[key] = deepMerge2(merged[key], sourceValue);
|
|
5086
2160
|
} else if (Array.isArray(sourceValue) && Array.isArray(merged[key])) {
|
|
5087
|
-
if (sourceValue.length > 0 && merged[key].length > 0 &&
|
|
2161
|
+
if (sourceValue.length > 0 && merged[key].length > 0 && isObject2(sourceValue[0]) && isObject2(merged[key][0])) {
|
|
5088
2162
|
const result = [...sourceValue];
|
|
5089
2163
|
for (const targetItem of merged[key]) {
|
|
5090
|
-
if (
|
|
5091
|
-
const existingItem = result.find((item) =>
|
|
2164
|
+
if (isObject2(targetItem) && "name" in targetItem) {
|
|
2165
|
+
const existingItem = result.find((item) => isObject2(item) && ("name" in item) && item.name === targetItem.name);
|
|
5092
2166
|
if (!existingItem) {
|
|
5093
2167
|
result.push(targetItem);
|
|
5094
2168
|
}
|
|
5095
|
-
} else if (
|
|
5096
|
-
const existingItem = result.find((item) =>
|
|
2169
|
+
} else if (isObject2(targetItem) && "path" in targetItem) {
|
|
2170
|
+
const existingItem = result.find((item) => isObject2(item) && ("path" in item) && item.path === targetItem.path);
|
|
5097
2171
|
if (!existingItem) {
|
|
5098
2172
|
result.push(targetItem);
|
|
5099
2173
|
}
|
|
5100
|
-
} else if (!result.some((item) =>
|
|
2174
|
+
} else if (!result.some((item) => deepEquals2(item, targetItem))) {
|
|
5101
2175
|
result.push(targetItem);
|
|
5102
2176
|
}
|
|
5103
2177
|
}
|
|
@@ -5120,19 +2194,19 @@ function deepMerge22(target, source) {
|
|
|
5120
2194
|
}
|
|
5121
2195
|
return merged;
|
|
5122
2196
|
}
|
|
5123
|
-
function
|
|
2197
|
+
function deepEquals2(a, b) {
|
|
5124
2198
|
if (a === b)
|
|
5125
2199
|
return true;
|
|
5126
2200
|
if (Array.isArray(a) && Array.isArray(b)) {
|
|
5127
2201
|
if (a.length !== b.length)
|
|
5128
2202
|
return false;
|
|
5129
2203
|
for (let i = 0;i < a.length; i++) {
|
|
5130
|
-
if (!
|
|
2204
|
+
if (!deepEquals2(a[i], b[i]))
|
|
5131
2205
|
return false;
|
|
5132
2206
|
}
|
|
5133
2207
|
return true;
|
|
5134
2208
|
}
|
|
5135
|
-
if (
|
|
2209
|
+
if (isObject2(a) && isObject2(b)) {
|
|
5136
2210
|
const keysA = Object.keys(a);
|
|
5137
2211
|
const keysB = Object.keys(b);
|
|
5138
2212
|
if (keysA.length !== keysB.length)
|
|
@@ -5140,21 +2214,18 @@ function deepEquals22(a, b) {
|
|
|
5140
2214
|
for (const key of keysA) {
|
|
5141
2215
|
if (!Object.prototype.hasOwnProperty.call(b, key))
|
|
5142
2216
|
return false;
|
|
5143
|
-
if (!
|
|
2217
|
+
if (!deepEquals2(a[key], b[key]))
|
|
5144
2218
|
return false;
|
|
5145
2219
|
}
|
|
5146
2220
|
return true;
|
|
5147
2221
|
}
|
|
5148
2222
|
return false;
|
|
5149
2223
|
}
|
|
5150
|
-
function
|
|
2224
|
+
function isObject2(item) {
|
|
5151
2225
|
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
5152
2226
|
}
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
});
|
|
5156
|
-
async function tryLoadConfig22(configPath, defaultConfig22) {
|
|
5157
|
-
if (!existsSync32(configPath))
|
|
2227
|
+
async function tryLoadConfig2(configPath, defaultConfig2) {
|
|
2228
|
+
if (!existsSync3(configPath))
|
|
5158
2229
|
return null;
|
|
5159
2230
|
try {
|
|
5160
2231
|
const importedConfig = await import(configPath);
|
|
@@ -5162,7 +2233,7 @@ async function tryLoadConfig22(configPath, defaultConfig22) {
|
|
|
5162
2233
|
if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig))
|
|
5163
2234
|
return null;
|
|
5164
2235
|
try {
|
|
5165
|
-
return
|
|
2236
|
+
return deepMerge2(defaultConfig2, loadedConfig);
|
|
5166
2237
|
} catch {
|
|
5167
2238
|
return null;
|
|
5168
2239
|
}
|
|
@@ -5170,12 +2241,12 @@ async function tryLoadConfig22(configPath, defaultConfig22) {
|
|
|
5170
2241
|
return null;
|
|
5171
2242
|
}
|
|
5172
2243
|
}
|
|
5173
|
-
async function
|
|
2244
|
+
async function loadConfig3({
|
|
5174
2245
|
name = "",
|
|
5175
2246
|
cwd,
|
|
5176
|
-
defaultConfig:
|
|
2247
|
+
defaultConfig: defaultConfig2
|
|
5177
2248
|
}) {
|
|
5178
|
-
const baseDir = cwd ||
|
|
2249
|
+
const baseDir = cwd || process6.cwd();
|
|
5179
2250
|
const extensions = [".ts", ".js", ".mjs", ".cjs", ".json"];
|
|
5180
2251
|
const configPaths = [
|
|
5181
2252
|
`${name}.config`,
|
|
@@ -5185,48 +2256,49 @@ async function loadConfig32({
|
|
|
5185
2256
|
];
|
|
5186
2257
|
for (const configPath of configPaths) {
|
|
5187
2258
|
for (const ext of extensions) {
|
|
5188
|
-
const fullPath =
|
|
5189
|
-
const
|
|
5190
|
-
if (
|
|
5191
|
-
|
|
5192
|
-
return config32;
|
|
2259
|
+
const fullPath = resolve3(baseDir, `${configPath}${ext}`);
|
|
2260
|
+
const config2 = await tryLoadConfig2(fullPath, defaultConfig2);
|
|
2261
|
+
if (config2 !== null) {
|
|
2262
|
+
return config2;
|
|
5193
2263
|
}
|
|
5194
2264
|
}
|
|
5195
2265
|
}
|
|
5196
2266
|
try {
|
|
5197
|
-
const pkgPath =
|
|
5198
|
-
if (
|
|
2267
|
+
const pkgPath = resolve3(baseDir, "package.json");
|
|
2268
|
+
if (existsSync3(pkgPath)) {
|
|
5199
2269
|
const pkg = await import(pkgPath);
|
|
5200
2270
|
const pkgConfig = pkg[name];
|
|
5201
2271
|
if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
|
|
5202
2272
|
try {
|
|
5203
|
-
|
|
5204
|
-
return deepMerge22(defaultConfig22, pkgConfig);
|
|
2273
|
+
return deepMerge2(defaultConfig2, pkgConfig);
|
|
5205
2274
|
} catch {}
|
|
5206
2275
|
}
|
|
5207
2276
|
}
|
|
5208
2277
|
} catch {}
|
|
5209
|
-
|
|
5210
|
-
return defaultConfig22;
|
|
2278
|
+
return defaultConfig2;
|
|
5211
2279
|
}
|
|
5212
|
-
var
|
|
5213
|
-
var
|
|
2280
|
+
var defaultConfigDir2 = resolve3(process6.cwd(), "config");
|
|
2281
|
+
var defaultGeneratedDir2 = resolve3(process6.cwd(), "src/generated");
|
|
5214
2282
|
|
|
5215
2283
|
// git-hooks.config.ts
|
|
5216
|
-
var
|
|
2284
|
+
var config2 = {
|
|
5217
2285
|
"pre-commit": {
|
|
5218
2286
|
"staged-lint": {
|
|
5219
|
-
"
|
|
2287
|
+
"**/*.{js,ts}": [
|
|
2288
|
+
"bunx --bun eslint --max-warnings=0",
|
|
2289
|
+
"bunx --bun tsc --noEmit"
|
|
2290
|
+
]
|
|
5220
2291
|
}
|
|
5221
2292
|
},
|
|
2293
|
+
"commit-msg": "bunx gitlint .git/COMMIT_EDITMSG",
|
|
5222
2294
|
verbose: true
|
|
5223
2295
|
};
|
|
5224
|
-
var git_hooks_config_default =
|
|
2296
|
+
var git_hooks_config_default = config2;
|
|
5225
2297
|
|
|
5226
2298
|
// src/config.ts
|
|
5227
|
-
var
|
|
2299
|
+
var config3 = await loadConfig3({
|
|
5228
2300
|
name: "git-hooks",
|
|
5229
|
-
cwd:
|
|
2301
|
+
cwd: process8.cwd(),
|
|
5230
2302
|
defaultConfig: git_hooks_config_default
|
|
5231
2303
|
});
|
|
5232
2304
|
|
|
@@ -5234,7 +2306,7 @@ var config6 = await loadConfig32({
|
|
|
5234
2306
|
import { exec } from "child_process";
|
|
5235
2307
|
import { promisify } from "util";
|
|
5236
2308
|
var execAsync = promisify(exec);
|
|
5237
|
-
var
|
|
2309
|
+
var log = new Logger("git-hooks", {
|
|
5238
2310
|
showTags: true
|
|
5239
2311
|
});
|
|
5240
2312
|
var VALID_GIT_HOOKS = [
|
|
@@ -5280,7 +2352,7 @@ if [ -f "$BUN_GIT_HOOKS_RC" ]; then
|
|
|
5280
2352
|
fi
|
|
5281
2353
|
|
|
5282
2354
|
`;
|
|
5283
|
-
function getGitProjectRoot(directory =
|
|
2355
|
+
function getGitProjectRoot(directory = process9.cwd()) {
|
|
5284
2356
|
if (directory.endsWith(".git")) {
|
|
5285
2357
|
return path.normalize(directory);
|
|
5286
2358
|
}
|
|
@@ -5311,18 +2383,18 @@ function getGitProjectRoot(directory = process14.cwd()) {
|
|
|
5311
2383
|
}
|
|
5312
2384
|
return getGitProjectRoot(parentDir);
|
|
5313
2385
|
}
|
|
5314
|
-
function setHooksFromConfig(projectRootPath =
|
|
5315
|
-
if (!
|
|
2386
|
+
function setHooksFromConfig(projectRootPath = process9.cwd(), options) {
|
|
2387
|
+
if (!config3 || Object.keys(config3).length === 0)
|
|
5316
2388
|
throw new Error("[ERROR] Config was not found! Please add `.git-hooks.config.{ts,js,mjs,cjs,json}` or `git-hooks.config.{ts,js,mjs,cjs,json}` or the `git-hooks` entry in package.json.\r\nCheck README for details");
|
|
5317
|
-
const configFile = options?.configFile || { ...
|
|
2389
|
+
const configFile = options?.configFile || { ...config3 };
|
|
5318
2390
|
_validateStagedLintConfig(configFile);
|
|
5319
2391
|
const hookKeys = Object.keys(configFile).filter((key) => !VALID_OPTIONS.includes(key));
|
|
5320
2392
|
const isValidConfig = hookKeys.every((key) => VALID_GIT_HOOKS.includes(key));
|
|
5321
2393
|
if (!isValidConfig)
|
|
5322
2394
|
throw new Error("[ERROR] Config was not in correct format. Please check git hooks or options name");
|
|
5323
2395
|
const preserveUnused = Array.isArray(configFile.preserveUnused) ? configFile.preserveUnused : configFile.preserveUnused ? VALID_GIT_HOOKS : [];
|
|
5324
|
-
const logKeys = Object.keys(configFile).filter((key) => !VALID_OPTIONS.includes(key)).sort().map((key) =>
|
|
5325
|
-
|
|
2396
|
+
const logKeys = Object.keys(configFile).filter((key) => !VALID_OPTIONS.includes(key)).sort().map((key) => italic(key)).join(", ");
|
|
2397
|
+
log.debug(`Hook Keys: ${logKeys}`);
|
|
5326
2398
|
for (const hook of VALID_GIT_HOOKS) {
|
|
5327
2399
|
if (Object.prototype.hasOwnProperty.call(configFile, hook)) {
|
|
5328
2400
|
if (!configFile[hook])
|
|
@@ -5333,48 +2405,85 @@ function setHooksFromConfig(projectRootPath = process14.cwd(), options) {
|
|
|
5333
2405
|
}
|
|
5334
2406
|
}
|
|
5335
2407
|
}
|
|
5336
|
-
async function getStagedFiles(projectRoot =
|
|
2408
|
+
async function getStagedFiles(projectRoot = process9.cwd()) {
|
|
5337
2409
|
try {
|
|
5338
|
-
const { stdout } = await execAsync("git diff --
|
|
5339
|
-
|
|
2410
|
+
const { stdout } = await execAsync("git diff --cached --name-only --diff-filter=ACMR", { cwd: projectRoot });
|
|
2411
|
+
const files = stdout.trim().split(`
|
|
5340
2412
|
`).filter(Boolean);
|
|
2413
|
+
if (config3.verbose && files.length > 0) {
|
|
2414
|
+
console.info("[INFO] Staged files found:", files);
|
|
2415
|
+
}
|
|
2416
|
+
return files;
|
|
5341
2417
|
} catch (error) {
|
|
5342
2418
|
console.error("[ERROR] Failed to get staged files:", error);
|
|
5343
2419
|
return [];
|
|
5344
2420
|
}
|
|
5345
2421
|
}
|
|
2422
|
+
function expandBracePattern(pattern) {
|
|
2423
|
+
const braceMatch = pattern.match(/{([^}]+)}/g);
|
|
2424
|
+
if (!braceMatch)
|
|
2425
|
+
return [pattern];
|
|
2426
|
+
const results = [pattern];
|
|
2427
|
+
braceMatch.forEach((brace) => {
|
|
2428
|
+
const options = brace.slice(1, -1).split(",");
|
|
2429
|
+
const newResults = [];
|
|
2430
|
+
results.forEach((result) => {
|
|
2431
|
+
options.forEach((option) => {
|
|
2432
|
+
newResults.push(result.replace(brace, option.trim()));
|
|
2433
|
+
});
|
|
2434
|
+
});
|
|
2435
|
+
results.length = 0;
|
|
2436
|
+
results.push(...newResults);
|
|
2437
|
+
});
|
|
2438
|
+
return results;
|
|
2439
|
+
}
|
|
5346
2440
|
function matchesGlob(file, pattern) {
|
|
5347
|
-
if (pattern.
|
|
5348
|
-
|
|
5349
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
5350
|
-
return regex.test(file);
|
|
2441
|
+
if (pattern.startsWith("!")) {
|
|
2442
|
+
return !matchesGlob(file, pattern.slice(1));
|
|
5351
2443
|
}
|
|
5352
|
-
|
|
2444
|
+
const regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "(?:.*?)").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]");
|
|
2445
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
2446
|
+
return regex.test(file);
|
|
5353
2447
|
}
|
|
5354
2448
|
function filterFilesByPattern(files, pattern) {
|
|
5355
|
-
|
|
2449
|
+
const expandedPatterns = expandBracePattern(pattern);
|
|
2450
|
+
const includePatterns = expandedPatterns.filter((p) => !p.startsWith("!"));
|
|
2451
|
+
const excludePatterns = expandedPatterns.filter((p) => p.startsWith("!"));
|
|
2452
|
+
return files.filter((file) => {
|
|
2453
|
+
const isIncluded = includePatterns.some((p) => matchesGlob(file, p));
|
|
2454
|
+
const isExcluded = excludePatterns.some((p) => matchesGlob(file, p.slice(1)));
|
|
2455
|
+
return isIncluded && !isExcluded;
|
|
2456
|
+
});
|
|
5356
2457
|
}
|
|
5357
|
-
async function runCommandOnStagedFiles(command, files, projectRoot =
|
|
2458
|
+
async function runCommandOnStagedFiles(command, files, projectRoot = process9.cwd(), verbose = false) {
|
|
5358
2459
|
if (files.length === 0) {
|
|
5359
2460
|
if (verbose)
|
|
5360
2461
|
console.info("[INFO] No matching files for pattern");
|
|
5361
2462
|
return true;
|
|
5362
2463
|
}
|
|
5363
2464
|
const commands = Array.isArray(command) ? command : [command];
|
|
2465
|
+
const fileList = files.join(" ");
|
|
5364
2466
|
for (const cmd of commands) {
|
|
5365
2467
|
try {
|
|
5366
|
-
const fullCommand = `${cmd} ${
|
|
5367
|
-
if (verbose)
|
|
5368
|
-
console.info(`[INFO] Running: ${fullCommand}`);
|
|
5369
|
-
const { stdout, stderr } = await execAsync(fullCommand, { cwd: projectRoot });
|
|
2468
|
+
const fullCommand = `${cmd} ${fileList}`;
|
|
5370
2469
|
if (verbose) {
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
2470
|
+
console.info("[INFO] Running command:", cmd);
|
|
2471
|
+
console.info("[INFO] On files:", files);
|
|
2472
|
+
}
|
|
2473
|
+
const { stdout, stderr } = await execAsync(fullCommand, { cwd: projectRoot });
|
|
2474
|
+
if (stdout && (verbose || stdout.includes("error") || stdout.includes("warning"))) {
|
|
2475
|
+
console.info(stdout);
|
|
2476
|
+
}
|
|
2477
|
+
if (stderr) {
|
|
2478
|
+
console.error("[ERROR] Command output:", stderr);
|
|
2479
|
+
return false;
|
|
5375
2480
|
}
|
|
5376
2481
|
} catch (error) {
|
|
5377
|
-
|
|
2482
|
+
if (error.stdout)
|
|
2483
|
+
console.info(error.stdout);
|
|
2484
|
+
if (error.stderr)
|
|
2485
|
+
console.error("[ERROR] Command stderr:", error.stderr);
|
|
2486
|
+
console.error(`[ERROR] Command failed: ${cmd}`);
|
|
5378
2487
|
return false;
|
|
5379
2488
|
}
|
|
5380
2489
|
}
|
|
@@ -5398,7 +2507,7 @@ async function processStagedLint(stagedLintConfig, projectRoot, verbose = false)
|
|
|
5398
2507
|
}
|
|
5399
2508
|
return success;
|
|
5400
2509
|
}
|
|
5401
|
-
function _setHook(hook, commandOrConfig, projectRoot =
|
|
2510
|
+
function _setHook(hook, commandOrConfig, projectRoot = process9.cwd()) {
|
|
5402
2511
|
const gitRoot = getGitProjectRoot(projectRoot);
|
|
5403
2512
|
if (!gitRoot) {
|
|
5404
2513
|
console.info("[INFO] No `.git` root folder found, skipping");
|
|
@@ -5419,26 +2528,26 @@ function _setHook(hook, commandOrConfig, projectRoot = process14.cwd()) {
|
|
|
5419
2528
|
fs.mkdirSync(hookDirectory, { recursive: true });
|
|
5420
2529
|
}
|
|
5421
2530
|
const addOrModify = fs.existsSync(hookPath) ? "Modify" : "Add";
|
|
5422
|
-
|
|
2531
|
+
log.debug(`${addOrModify} ${italic(hook)} hook`);
|
|
5423
2532
|
fs.writeFileSync(hookPath, hookCommand, { mode: 493 });
|
|
5424
2533
|
}
|
|
5425
|
-
function removeHooks(projectRoot =
|
|
2534
|
+
function removeHooks(projectRoot = process9.cwd(), verbose = false) {
|
|
5426
2535
|
for (const configEntry of VALID_GIT_HOOKS)
|
|
5427
2536
|
_removeHook(configEntry, projectRoot, verbose);
|
|
5428
2537
|
}
|
|
5429
|
-
function _removeHook(hook, projectRoot =
|
|
2538
|
+
function _removeHook(hook, projectRoot = process9.cwd(), verbose = false) {
|
|
5430
2539
|
const gitRoot = getGitProjectRoot(projectRoot);
|
|
5431
2540
|
const hookPath = path.normalize(`${gitRoot}/hooks/${hook}`);
|
|
5432
2541
|
if (fs.existsSync(hookPath)) {
|
|
5433
|
-
|
|
2542
|
+
log.debug(`Hook ${hook} is not set, removing!`);
|
|
5434
2543
|
fs.unlinkSync(hookPath);
|
|
5435
2544
|
}
|
|
5436
2545
|
if (verbose)
|
|
5437
|
-
|
|
2546
|
+
log.success(`Successfully removed the ${hook} hook`);
|
|
5438
2547
|
}
|
|
5439
2548
|
async function runStagedLint(hook) {
|
|
5440
|
-
const projectRoot =
|
|
5441
|
-
const configFile =
|
|
2549
|
+
const projectRoot = process9.cwd();
|
|
2550
|
+
const configFile = config3;
|
|
5442
2551
|
if (!configFile) {
|
|
5443
2552
|
console.error(`[ERROR] No configuration found`);
|
|
5444
2553
|
return false;
|
|
@@ -5471,60 +2580,60 @@ function _validateStagedLintConfig(config4) {
|
|
|
5471
2580
|
|
|
5472
2581
|
// bin/cli.ts
|
|
5473
2582
|
var cli = new CAC("git-hooks");
|
|
5474
|
-
var
|
|
2583
|
+
var log2 = new Logger("git-hooks", {
|
|
5475
2584
|
showTags: true
|
|
5476
2585
|
});
|
|
5477
|
-
var { SKIP_INSTALL_GIT_HOOKS } =
|
|
2586
|
+
var { SKIP_INSTALL_GIT_HOOKS } = process10.env;
|
|
5478
2587
|
if (["1", "true"].includes(SKIP_INSTALL_GIT_HOOKS || "")) {
|
|
5479
|
-
|
|
5480
|
-
|
|
2588
|
+
log2.info(`SKIP_INSTALL_GIT_HOOKS is set to "${SKIP_INSTALL_GIT_HOOKS}", skipping installing hooks.`);
|
|
2589
|
+
process10.exit(0);
|
|
5481
2590
|
}
|
|
5482
2591
|
cli.command("[configPath]", "Install git hooks, optionally from specified config file").option("--verbose", "Enable verbose logging").example("git-hooks").example("git-hooks ../src/config.ts").example("git-hooks --verbose").action(async (configPath, options) => {
|
|
5483
2592
|
try {
|
|
5484
2593
|
if (options?.verbose) {
|
|
5485
|
-
|
|
5486
|
-
|
|
2594
|
+
log2.debug(`Config path: ${configPath || "using default"}`);
|
|
2595
|
+
log2.debug(`Working directory: ${process10.cwd()}`);
|
|
5487
2596
|
}
|
|
5488
2597
|
if (configPath) {
|
|
5489
2598
|
const config4 = await import(configPath);
|
|
5490
|
-
setHooksFromConfig(
|
|
2599
|
+
setHooksFromConfig(process10.cwd(), { configFile: config4 });
|
|
5491
2600
|
} else {
|
|
5492
|
-
setHooksFromConfig(
|
|
2601
|
+
setHooksFromConfig(process10.cwd());
|
|
5493
2602
|
}
|
|
5494
|
-
|
|
2603
|
+
log2.success("Successfully set all git hooks");
|
|
5495
2604
|
} catch (err) {
|
|
5496
|
-
|
|
5497
|
-
|
|
2605
|
+
log2.error(err);
|
|
2606
|
+
process10.exit(1);
|
|
5498
2607
|
}
|
|
5499
2608
|
});
|
|
5500
2609
|
cli.command("uninstall", "Remove all git hooks").alias("remove").option("--verbose", "Enable verbose logging").example("git-hooks uninstall").example("git-hooks remove").example("git-hooks uninstall --verbose").action(async (options) => {
|
|
5501
2610
|
try {
|
|
5502
2611
|
if (options?.verbose) {
|
|
5503
|
-
|
|
2612
|
+
log2.debug(`Removing hooks from: ${process10.cwd()}`);
|
|
5504
2613
|
}
|
|
5505
|
-
removeHooks(
|
|
5506
|
-
|
|
2614
|
+
removeHooks(process10.cwd(), options?.verbose);
|
|
2615
|
+
log2.success("Successfully removed all git hooks");
|
|
5507
2616
|
} catch (err) {
|
|
5508
|
-
|
|
5509
|
-
|
|
2617
|
+
log2.error("Was not able to remove git hooks. Error:", err);
|
|
2618
|
+
process10.exit(1);
|
|
5510
2619
|
}
|
|
5511
2620
|
});
|
|
5512
2621
|
cli.command("run-staged-lint <hook>", "Run staged lint for a specific git hook").option("--verbose", "Enable verbose logging").example("git-hooks run-staged-lint pre-commit").example("git-hooks run-staged-lint pre-push --verbose").action(async (hook, options) => {
|
|
5513
2622
|
try {
|
|
5514
2623
|
if (options?.verbose) {
|
|
5515
|
-
|
|
5516
|
-
|
|
2624
|
+
log2.debug(`Running staged lint for hook: ${hook}`);
|
|
2625
|
+
log2.debug(`Working directory: ${process10.cwd()}`);
|
|
5517
2626
|
}
|
|
5518
2627
|
const success = await runStagedLint(hook);
|
|
5519
2628
|
if (success) {
|
|
5520
|
-
|
|
2629
|
+
log2.success("Staged lint completed successfully");
|
|
5521
2630
|
} else {
|
|
5522
|
-
|
|
5523
|
-
|
|
2631
|
+
log2.error("Staged lint failed");
|
|
2632
|
+
process10.exit(1);
|
|
5524
2633
|
}
|
|
5525
2634
|
} catch (err) {
|
|
5526
|
-
|
|
5527
|
-
|
|
2635
|
+
log2.error("Was not able to run staged lint. Error:", err);
|
|
2636
|
+
process10.exit(1);
|
|
5528
2637
|
}
|
|
5529
2638
|
});
|
|
5530
2639
|
cli.version(version);
|