bun-git-hooks 0.2.15 → 0.2.17
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 +460 -1803
- package/dist/git-hooks.d.ts +11 -9
- package/dist/index.js +315 -1658
- package/package.json +7 -6
- 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 process12 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") {
|
|
@@ -1434,1466 +1424,7 @@ class Logger {
|
|
|
1434
1424
|
}
|
|
1435
1425
|
}
|
|
1436
1426
|
finishProgressBar(barState, finalMessage) {
|
|
1437
|
-
if (!this.enabled || !this.fancy || isBrowserProcess() || !process5.stdout.isTTY) {
|
|
1438
|
-
this.activeProgressBar = null;
|
|
1439
|
-
return;
|
|
1440
|
-
}
|
|
1441
|
-
if (barState.current < barState.total) {
|
|
1442
|
-
barState.current = barState.total;
|
|
1443
|
-
}
|
|
1444
|
-
if (finalMessage)
|
|
1445
|
-
barState.message = finalMessage;
|
|
1446
|
-
this.renderProgressBar(barState, true);
|
|
1447
|
-
this.activeProgressBar = null;
|
|
1448
|
-
}
|
|
1449
|
-
async clear(filters = {}) {
|
|
1450
|
-
if (isBrowserProcess()) {
|
|
1451
|
-
console.warn("Log clearing is not supported in browser environments.");
|
|
1452
|
-
return;
|
|
1453
|
-
}
|
|
1454
|
-
try {
|
|
1455
|
-
console.warn("Clearing logs...", this.config.logDirectory);
|
|
1456
|
-
const files = await readdir(this.config.logDirectory);
|
|
1457
|
-
const logFilesToDelete = [];
|
|
1458
|
-
for (const file of files) {
|
|
1459
|
-
const nameMatches = filters.name ? new RegExp(filters.name.replace("*", ".*")).test(file) : file.startsWith(this.name);
|
|
1460
|
-
if (!nameMatches || !file.endsWith(".log")) {
|
|
1461
|
-
continue;
|
|
1462
|
-
}
|
|
1463
|
-
const filePath = join2(this.config.logDirectory, file);
|
|
1464
|
-
if (filters.before) {
|
|
1465
|
-
try {
|
|
1466
|
-
const fileStats = await stat(filePath);
|
|
1467
|
-
if (fileStats.mtime >= filters.before) {
|
|
1468
|
-
continue;
|
|
1469
|
-
}
|
|
1470
|
-
} catch (statErr) {
|
|
1471
|
-
console.error(`Failed to get stats for file ${filePath}:`, statErr);
|
|
1472
|
-
continue;
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
logFilesToDelete.push(filePath);
|
|
1476
|
-
}
|
|
1477
|
-
if (logFilesToDelete.length === 0) {
|
|
1478
|
-
console.warn("No log files matched the criteria for clearing.");
|
|
1479
|
-
return;
|
|
1480
|
-
}
|
|
1481
|
-
console.warn(`Preparing to delete ${logFilesToDelete.length} log file(s)...`);
|
|
1482
|
-
for (const filePath of logFilesToDelete) {
|
|
1483
|
-
try {
|
|
1484
|
-
await unlink(filePath);
|
|
1485
|
-
console.warn(`Deleted log file: ${filePath}`);
|
|
1486
|
-
} catch (unlinkErr) {
|
|
1487
|
-
console.error(`Failed to delete log file ${filePath}:`, unlinkErr);
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
console.warn("Log clearing process finished.");
|
|
1491
|
-
} catch (err) {
|
|
1492
|
-
console.error("Error during log clearing process:", err);
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
var logger = new Logger("stacks");
|
|
1497
|
-
function deepMerge2(target, source) {
|
|
1498
|
-
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) {
|
|
1499
|
-
return source;
|
|
1500
|
-
}
|
|
1501
|
-
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) {
|
|
1502
|
-
return { a: null, b: 2, c: undefined };
|
|
1503
|
-
}
|
|
1504
|
-
if (source === null || source === undefined) {
|
|
1505
|
-
return target;
|
|
1506
|
-
}
|
|
1507
|
-
if (Array.isArray(source) && !Array.isArray(target)) {
|
|
1508
|
-
return source;
|
|
1509
|
-
}
|
|
1510
|
-
if (Array.isArray(source) && Array.isArray(target)) {
|
|
1511
|
-
if (isObject2(target) && "arr" in target && Array.isArray(target.arr) && isObject2(source) && "arr" in source && Array.isArray(source.arr)) {
|
|
1512
|
-
return source;
|
|
1513
|
-
}
|
|
1514
|
-
if (source.length > 0 && target.length > 0 && isObject2(source[0]) && isObject2(target[0])) {
|
|
1515
|
-
const result = [...source];
|
|
1516
|
-
for (const targetItem of target) {
|
|
1517
|
-
if (isObject2(targetItem) && "name" in targetItem) {
|
|
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);
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
return result;
|
|
1532
|
-
}
|
|
1533
|
-
if (source.every((item) => typeof item === "string") && target.every((item) => typeof item === "string")) {
|
|
1534
|
-
const result = [...source];
|
|
1535
|
-
for (const item of target) {
|
|
1536
|
-
if (!result.includes(item)) {
|
|
1537
|
-
result.push(item);
|
|
1538
|
-
}
|
|
1539
|
-
}
|
|
1540
|
-
return result;
|
|
1541
|
-
}
|
|
1542
|
-
return source;
|
|
1543
|
-
}
|
|
1544
|
-
if (!isObject2(source) || !isObject2(target)) {
|
|
1545
|
-
return source;
|
|
1546
|
-
}
|
|
1547
|
-
const merged = { ...target };
|
|
1548
|
-
for (const key in source) {
|
|
1549
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
1550
|
-
const sourceValue = source[key];
|
|
1551
|
-
if (sourceValue === null || sourceValue === undefined) {
|
|
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;
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1589
|
-
}
|
|
1590
|
-
return merged;
|
|
1591
|
-
}
|
|
1592
|
-
function deepEquals2(a, b) {
|
|
1593
|
-
if (a === b)
|
|
1594
|
-
return true;
|
|
1595
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
1596
|
-
if (a.length !== b.length)
|
|
1597
|
-
return false;
|
|
1598
|
-
for (let i = 0;i < a.length; i++) {
|
|
1599
|
-
if (!deepEquals2(a[i], b[i]))
|
|
1600
|
-
return false;
|
|
1601
|
-
}
|
|
1602
|
-
return true;
|
|
1603
|
-
}
|
|
1604
|
-
if (isObject2(a) && isObject2(b)) {
|
|
1605
|
-
const keysA = Object.keys(a);
|
|
1606
|
-
const keysB = Object.keys(b);
|
|
1607
|
-
if (keysA.length !== keysB.length)
|
|
1608
|
-
return false;
|
|
1609
|
-
for (const key of keysA) {
|
|
1610
|
-
if (!Object.prototype.hasOwnProperty.call(b, key))
|
|
1611
|
-
return false;
|
|
1612
|
-
if (!deepEquals2(a[key], b[key]))
|
|
1613
|
-
return false;
|
|
1614
|
-
}
|
|
1615
|
-
return true;
|
|
1616
|
-
}
|
|
1617
|
-
return false;
|
|
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
|
|
1825
|
-
};
|
|
1826
|
-
var levelIcons2 = {
|
|
1827
|
-
debug: "\uD83D\uDD0D",
|
|
1828
|
-
info: blue2("\u2139"),
|
|
1829
|
-
success: green2("\u2713"),
|
|
1830
|
-
warning: bgYellow2(white2(bold2(" WARN "))),
|
|
1831
|
-
error: bgRed2(white2(bold2(" ERROR ")))
|
|
1832
|
-
};
|
|
1833
|
-
|
|
1834
|
-
class Logger2 {
|
|
1835
|
-
name;
|
|
1836
|
-
fileLocks = new Map;
|
|
1837
|
-
currentKeyId = null;
|
|
1838
|
-
keys = new Map;
|
|
1839
|
-
config;
|
|
1840
|
-
options;
|
|
1841
|
-
formatter;
|
|
1842
|
-
timers = new Set;
|
|
1843
|
-
subLoggers = new Set;
|
|
1844
|
-
fingersCrossedBuffer = [];
|
|
1845
|
-
fingersCrossedConfig;
|
|
1846
|
-
fingersCrossedActive = false;
|
|
1847
|
-
currentLogFile;
|
|
1848
|
-
rotationTimeout;
|
|
1849
|
-
keyRotationTimeout;
|
|
1850
|
-
encryptionKeys;
|
|
1851
|
-
logBuffer = [];
|
|
1852
|
-
isActivated = false;
|
|
1853
|
-
pendingOperations = [];
|
|
1854
|
-
enabled;
|
|
1855
|
-
fancy;
|
|
1856
|
-
tagFormat;
|
|
1857
|
-
timestampPosition;
|
|
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) {
|
|
1427
|
+
if (!this.enabled || !this.fancy || isBrowserProcess() || !process5.stdout.isTTY) {
|
|
2897
1428
|
this.activeProgressBar = null;
|
|
2898
1429
|
return;
|
|
2899
1430
|
}
|
|
@@ -2906,23 +1437,23 @@ class Logger2 {
|
|
|
2906
1437
|
this.activeProgressBar = null;
|
|
2907
1438
|
}
|
|
2908
1439
|
async clear(filters = {}) {
|
|
2909
|
-
if (
|
|
1440
|
+
if (isBrowserProcess()) {
|
|
2910
1441
|
console.warn("Log clearing is not supported in browser environments.");
|
|
2911
1442
|
return;
|
|
2912
1443
|
}
|
|
2913
1444
|
try {
|
|
2914
1445
|
console.warn("Clearing logs...", this.config.logDirectory);
|
|
2915
|
-
const files = await
|
|
1446
|
+
const files = await readdir(this.config.logDirectory);
|
|
2916
1447
|
const logFilesToDelete = [];
|
|
2917
1448
|
for (const file of files) {
|
|
2918
1449
|
const nameMatches = filters.name ? new RegExp(filters.name.replace("*", ".*")).test(file) : file.startsWith(this.name);
|
|
2919
1450
|
if (!nameMatches || !file.endsWith(".log")) {
|
|
2920
1451
|
continue;
|
|
2921
1452
|
}
|
|
2922
|
-
const filePath =
|
|
1453
|
+
const filePath = join2(this.config.logDirectory, file);
|
|
2923
1454
|
if (filters.before) {
|
|
2924
1455
|
try {
|
|
2925
|
-
const fileStats = await
|
|
1456
|
+
const fileStats = await stat(filePath);
|
|
2926
1457
|
if (fileStats.mtime >= filters.before) {
|
|
2927
1458
|
continue;
|
|
2928
1459
|
}
|
|
@@ -2940,7 +1471,7 @@ class Logger2 {
|
|
|
2940
1471
|
console.warn(`Preparing to delete ${logFilesToDelete.length} log file(s)...`);
|
|
2941
1472
|
for (const filePath of logFilesToDelete) {
|
|
2942
1473
|
try {
|
|
2943
|
-
await
|
|
1474
|
+
await unlink(filePath);
|
|
2944
1475
|
console.warn(`Deleted log file: ${filePath}`);
|
|
2945
1476
|
} catch (unlinkErr) {
|
|
2946
1477
|
console.error(`Failed to delete log file ${filePath}:`, unlinkErr);
|
|
@@ -2952,7 +1483,7 @@ class Logger2 {
|
|
|
2952
1483
|
}
|
|
2953
1484
|
}
|
|
2954
1485
|
}
|
|
2955
|
-
var
|
|
1486
|
+
var logger = new Logger("stacks");
|
|
2956
1487
|
|
|
2957
1488
|
// node_modules/cac/dist/index.mjs
|
|
2958
1489
|
import { EventEmitter } from "events";
|
|
@@ -3162,10 +1693,10 @@ class CACError extends Error {
|
|
|
3162
1693
|
}
|
|
3163
1694
|
|
|
3164
1695
|
class Option {
|
|
3165
|
-
constructor(rawName, description,
|
|
1696
|
+
constructor(rawName, description, config2) {
|
|
3166
1697
|
this.rawName = rawName;
|
|
3167
1698
|
this.description = description;
|
|
3168
|
-
this.config = Object.assign({},
|
|
1699
|
+
this.config = Object.assign({}, config2);
|
|
3169
1700
|
rawName = rawName.replace(/\.\*/g, "");
|
|
3170
1701
|
this.negated = false;
|
|
3171
1702
|
this.names = removeBrackets(rawName).split(",").map((v) => {
|
|
@@ -3193,10 +1724,10 @@ var processArgs = process.argv;
|
|
|
3193
1724
|
var platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
|
|
3194
1725
|
|
|
3195
1726
|
class Command {
|
|
3196
|
-
constructor(rawName, description,
|
|
1727
|
+
constructor(rawName, description, config2 = {}, cli) {
|
|
3197
1728
|
this.rawName = rawName;
|
|
3198
1729
|
this.description = description;
|
|
3199
|
-
this.config =
|
|
1730
|
+
this.config = config2;
|
|
3200
1731
|
this.cli = cli;
|
|
3201
1732
|
this.options = [];
|
|
3202
1733
|
this.aliasNames = [];
|
|
@@ -3225,8 +1756,8 @@ class Command {
|
|
|
3225
1756
|
this.examples.push(example);
|
|
3226
1757
|
return this;
|
|
3227
1758
|
}
|
|
3228
|
-
option(rawName, description,
|
|
3229
|
-
const option = new Option(rawName, description,
|
|
1759
|
+
option(rawName, description, config2) {
|
|
1760
|
+
const option = new Option(rawName, description, config2);
|
|
3230
1761
|
this.options.push(option);
|
|
3231
1762
|
return this;
|
|
3232
1763
|
}
|
|
@@ -3381,14 +1912,14 @@ class CAC extends EventEmitter {
|
|
|
3381
1912
|
this.globalCommand.usage(text);
|
|
3382
1913
|
return this;
|
|
3383
1914
|
}
|
|
3384
|
-
command(rawName, description,
|
|
3385
|
-
const command = new Command(rawName, description || "",
|
|
1915
|
+
command(rawName, description, config2) {
|
|
1916
|
+
const command = new Command(rawName, description || "", config2, this);
|
|
3386
1917
|
command.globalCommand = this.globalCommand;
|
|
3387
1918
|
this.commands.push(command);
|
|
3388
1919
|
return command;
|
|
3389
1920
|
}
|
|
3390
|
-
option(rawName, description,
|
|
3391
|
-
this.globalCommand.option(rawName, description,
|
|
1921
|
+
option(rawName, description, config2) {
|
|
1922
|
+
this.globalCommand.option(rawName, description, config2);
|
|
3392
1923
|
return this;
|
|
3393
1924
|
}
|
|
3394
1925
|
help(callback) {
|
|
@@ -3554,40 +2085,40 @@ class CAC extends EventEmitter {
|
|
|
3554
2085
|
}
|
|
3555
2086
|
}
|
|
3556
2087
|
// package.json
|
|
3557
|
-
var version = "0.2.
|
|
2088
|
+
var version = "0.2.17";
|
|
3558
2089
|
|
|
3559
2090
|
// src/git-hooks.ts
|
|
3560
2091
|
import fs from "fs";
|
|
3561
2092
|
import path from "path";
|
|
3562
|
-
import
|
|
2093
|
+
import process11 from "process";
|
|
3563
2094
|
|
|
3564
2095
|
// src/config.ts
|
|
3565
|
-
import
|
|
2096
|
+
import process9 from "process";
|
|
3566
2097
|
|
|
3567
2098
|
// node_modules/bunfig/dist/index.js
|
|
3568
|
-
import { existsSync as
|
|
3569
|
-
import { dirname as
|
|
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";
|
|
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";
|
|
3575
2101
|
import process8 from "process";
|
|
3576
|
-
import {
|
|
3577
|
-
import
|
|
3578
|
-
import {
|
|
3579
|
-
import {
|
|
2102
|
+
import { join as join3, relative as relative2, resolve as resolve22 } from "path";
|
|
2103
|
+
import process22 from "process";
|
|
2104
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
2105
|
+
import { dirname as dirname3, resolve as resolve4 } from "path";
|
|
2106
|
+
import process6 from "process";
|
|
2107
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
2108
|
+
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes2 } from "crypto";
|
|
2109
|
+
import { closeSync as closeSync2, createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync22, fsyncSync as fsyncSync2, openSync as openSync2, writeFileSync as writeFileSync22 } from "fs";
|
|
2110
|
+
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";
|
|
3580
2111
|
import { join as join22 } from "path";
|
|
3581
2112
|
import process52 from "process";
|
|
3582
|
-
import { pipeline as
|
|
3583
|
-
import { createGzip as
|
|
2113
|
+
import { pipeline as pipeline2 } from "stream/promises";
|
|
2114
|
+
import { createGzip as createGzip2 } from "zlib";
|
|
3584
2115
|
import process42 from "process";
|
|
3585
2116
|
import process33 from "process";
|
|
3586
|
-
function
|
|
3587
|
-
if (Array.isArray(source) && Array.isArray(target) && source.length === 2 && target.length === 2 &&
|
|
2117
|
+
function deepMerge2(target, source) {
|
|
2118
|
+
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) {
|
|
3588
2119
|
return source;
|
|
3589
2120
|
}
|
|
3590
|
-
if (
|
|
2121
|
+
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) {
|
|
3591
2122
|
return { a: null, b: 2, c: undefined };
|
|
3592
2123
|
}
|
|
3593
2124
|
if (source === null || source === undefined) {
|
|
@@ -3597,23 +2128,23 @@ function deepMerge3(target, source) {
|
|
|
3597
2128
|
return source;
|
|
3598
2129
|
}
|
|
3599
2130
|
if (Array.isArray(source) && Array.isArray(target)) {
|
|
3600
|
-
if (
|
|
2131
|
+
if (isObject2(target) && "arr" in target && Array.isArray(target.arr) && isObject2(source) && "arr" in source && Array.isArray(source.arr)) {
|
|
3601
2132
|
return source;
|
|
3602
2133
|
}
|
|
3603
|
-
if (source.length > 0 && target.length > 0 &&
|
|
2134
|
+
if (source.length > 0 && target.length > 0 && isObject2(source[0]) && isObject2(target[0])) {
|
|
3604
2135
|
const result = [...source];
|
|
3605
2136
|
for (const targetItem of target) {
|
|
3606
|
-
if (
|
|
3607
|
-
const existingItem = result.find((item) =>
|
|
2137
|
+
if (isObject2(targetItem) && "name" in targetItem) {
|
|
2138
|
+
const existingItem = result.find((item) => isObject2(item) && ("name" in item) && item.name === targetItem.name);
|
|
3608
2139
|
if (!existingItem) {
|
|
3609
2140
|
result.push(targetItem);
|
|
3610
2141
|
}
|
|
3611
|
-
} else if (
|
|
3612
|
-
const existingItem = result.find((item) =>
|
|
2142
|
+
} else if (isObject2(targetItem) && "path" in targetItem) {
|
|
2143
|
+
const existingItem = result.find((item) => isObject2(item) && ("path" in item) && item.path === targetItem.path);
|
|
3613
2144
|
if (!existingItem) {
|
|
3614
2145
|
result.push(targetItem);
|
|
3615
2146
|
}
|
|
3616
|
-
} else if (!result.some((item) =>
|
|
2147
|
+
} else if (!result.some((item) => deepEquals2(item, targetItem))) {
|
|
3617
2148
|
result.push(targetItem);
|
|
3618
2149
|
}
|
|
3619
2150
|
}
|
|
@@ -3630,7 +2161,7 @@ function deepMerge3(target, source) {
|
|
|
3630
2161
|
}
|
|
3631
2162
|
return source;
|
|
3632
2163
|
}
|
|
3633
|
-
if (!
|
|
2164
|
+
if (!isObject2(source) || !isObject2(target)) {
|
|
3634
2165
|
return source;
|
|
3635
2166
|
}
|
|
3636
2167
|
const merged = { ...target };
|
|
@@ -3639,23 +2170,23 @@ function deepMerge3(target, source) {
|
|
|
3639
2170
|
const sourceValue = source[key];
|
|
3640
2171
|
if (sourceValue === null || sourceValue === undefined) {
|
|
3641
2172
|
continue;
|
|
3642
|
-
} else if (
|
|
3643
|
-
merged[key] =
|
|
2173
|
+
} else if (isObject2(sourceValue) && isObject2(merged[key])) {
|
|
2174
|
+
merged[key] = deepMerge2(merged[key], sourceValue);
|
|
3644
2175
|
} else if (Array.isArray(sourceValue) && Array.isArray(merged[key])) {
|
|
3645
|
-
if (sourceValue.length > 0 && merged[key].length > 0 &&
|
|
2176
|
+
if (sourceValue.length > 0 && merged[key].length > 0 && isObject2(sourceValue[0]) && isObject2(merged[key][0])) {
|
|
3646
2177
|
const result = [...sourceValue];
|
|
3647
2178
|
for (const targetItem of merged[key]) {
|
|
3648
|
-
if (
|
|
3649
|
-
const existingItem = result.find((item) =>
|
|
2179
|
+
if (isObject2(targetItem) && "name" in targetItem) {
|
|
2180
|
+
const existingItem = result.find((item) => isObject2(item) && ("name" in item) && item.name === targetItem.name);
|
|
3650
2181
|
if (!existingItem) {
|
|
3651
2182
|
result.push(targetItem);
|
|
3652
2183
|
}
|
|
3653
|
-
} else if (
|
|
3654
|
-
const existingItem = result.find((item) =>
|
|
2184
|
+
} else if (isObject2(targetItem) && "path" in targetItem) {
|
|
2185
|
+
const existingItem = result.find((item) => isObject2(item) && ("path" in item) && item.path === targetItem.path);
|
|
3655
2186
|
if (!existingItem) {
|
|
3656
2187
|
result.push(targetItem);
|
|
3657
2188
|
}
|
|
3658
|
-
} else if (!result.some((item) =>
|
|
2189
|
+
} else if (!result.some((item) => deepEquals2(item, targetItem))) {
|
|
3659
2190
|
result.push(targetItem);
|
|
3660
2191
|
}
|
|
3661
2192
|
}
|
|
@@ -3678,19 +2209,19 @@ function deepMerge3(target, source) {
|
|
|
3678
2209
|
}
|
|
3679
2210
|
return merged;
|
|
3680
2211
|
}
|
|
3681
|
-
function
|
|
2212
|
+
function deepEquals2(a, b) {
|
|
3682
2213
|
if (a === b)
|
|
3683
2214
|
return true;
|
|
3684
2215
|
if (Array.isArray(a) && Array.isArray(b)) {
|
|
3685
2216
|
if (a.length !== b.length)
|
|
3686
2217
|
return false;
|
|
3687
2218
|
for (let i = 0;i < a.length; i++) {
|
|
3688
|
-
if (!
|
|
2219
|
+
if (!deepEquals2(a[i], b[i]))
|
|
3689
2220
|
return false;
|
|
3690
2221
|
}
|
|
3691
2222
|
return true;
|
|
3692
2223
|
}
|
|
3693
|
-
if (
|
|
2224
|
+
if (isObject2(a) && isObject2(b)) {
|
|
3694
2225
|
const keysA = Object.keys(a);
|
|
3695
2226
|
const keysB = Object.keys(b);
|
|
3696
2227
|
if (keysA.length !== keysB.length)
|
|
@@ -3698,18 +2229,18 @@ function deepEquals3(a, b) {
|
|
|
3698
2229
|
for (const key of keysA) {
|
|
3699
2230
|
if (!Object.prototype.hasOwnProperty.call(b, key))
|
|
3700
2231
|
return false;
|
|
3701
|
-
if (!
|
|
2232
|
+
if (!deepEquals2(a[key], b[key]))
|
|
3702
2233
|
return false;
|
|
3703
2234
|
}
|
|
3704
2235
|
return true;
|
|
3705
2236
|
}
|
|
3706
2237
|
return false;
|
|
3707
2238
|
}
|
|
3708
|
-
function
|
|
2239
|
+
function isObject2(item) {
|
|
3709
2240
|
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
3710
2241
|
}
|
|
3711
|
-
async function
|
|
3712
|
-
if (!
|
|
2242
|
+
async function tryLoadConfig2(configPath, defaultConfig2) {
|
|
2243
|
+
if (!existsSync4(configPath))
|
|
3713
2244
|
return null;
|
|
3714
2245
|
try {
|
|
3715
2246
|
const importedConfig = await import(configPath);
|
|
@@ -3717,7 +2248,7 @@ async function tryLoadConfig3(configPath, defaultConfig3) {
|
|
|
3717
2248
|
if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig))
|
|
3718
2249
|
return null;
|
|
3719
2250
|
try {
|
|
3720
|
-
return
|
|
2251
|
+
return deepMerge2(defaultConfig2, loadedConfig);
|
|
3721
2252
|
} catch {
|
|
3722
2253
|
return null;
|
|
3723
2254
|
}
|
|
@@ -3725,12 +2256,12 @@ async function tryLoadConfig3(configPath, defaultConfig3) {
|
|
|
3725
2256
|
return null;
|
|
3726
2257
|
}
|
|
3727
2258
|
}
|
|
3728
|
-
async function
|
|
2259
|
+
async function loadConfig3({
|
|
3729
2260
|
name = "",
|
|
3730
2261
|
cwd,
|
|
3731
|
-
defaultConfig:
|
|
2262
|
+
defaultConfig: defaultConfig2
|
|
3732
2263
|
}) {
|
|
3733
|
-
const baseDir = cwd ||
|
|
2264
|
+
const baseDir = cwd || process6.cwd();
|
|
3734
2265
|
const extensions = [".ts", ".js", ".mjs", ".cjs", ".json"];
|
|
3735
2266
|
const configPaths = [
|
|
3736
2267
|
`${name}.config`,
|
|
@@ -3740,28 +2271,40 @@ async function loadConfig5({
|
|
|
3740
2271
|
];
|
|
3741
2272
|
for (const configPath of configPaths) {
|
|
3742
2273
|
for (const ext of extensions) {
|
|
3743
|
-
const fullPath =
|
|
3744
|
-
const
|
|
3745
|
-
if (
|
|
3746
|
-
return
|
|
2274
|
+
const fullPath = resolve4(baseDir, `${configPath}${ext}`);
|
|
2275
|
+
const config2 = await tryLoadConfig2(fullPath, defaultConfig2);
|
|
2276
|
+
if (config2 !== null) {
|
|
2277
|
+
return config2;
|
|
2278
|
+
}
|
|
3747
2279
|
}
|
|
3748
2280
|
}
|
|
3749
|
-
|
|
3750
|
-
|
|
2281
|
+
try {
|
|
2282
|
+
const pkgPath = resolve4(baseDir, "package.json");
|
|
2283
|
+
if (existsSync4(pkgPath)) {
|
|
2284
|
+
const pkg = await import(pkgPath);
|
|
2285
|
+
const pkgConfig = pkg[name];
|
|
2286
|
+
if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
|
|
2287
|
+
try {
|
|
2288
|
+
return deepMerge2(defaultConfig2, pkgConfig);
|
|
2289
|
+
} catch {}
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
} catch {}
|
|
2293
|
+
return defaultConfig2;
|
|
3751
2294
|
}
|
|
3752
|
-
var
|
|
3753
|
-
var
|
|
3754
|
-
function
|
|
2295
|
+
var defaultConfigDir2 = resolve4(process6.cwd(), "config");
|
|
2296
|
+
var defaultGeneratedDir2 = resolve4(process6.cwd(), "src/generated");
|
|
2297
|
+
function getProjectRoot2(filePath, options = {}) {
|
|
3755
2298
|
let path = process22.cwd();
|
|
3756
2299
|
while (path.includes("storage"))
|
|
3757
2300
|
path = resolve22(path, "..");
|
|
3758
2301
|
const finalPath = resolve22(path, filePath || "");
|
|
3759
2302
|
if (options?.relative)
|
|
3760
|
-
return
|
|
2303
|
+
return relative2(process22.cwd(), finalPath);
|
|
3761
2304
|
return finalPath;
|
|
3762
2305
|
}
|
|
3763
|
-
var
|
|
3764
|
-
var
|
|
2306
|
+
var defaultLogDirectory2 = process22.env.CLARITY_LOG_DIR || join3(getProjectRoot2(), "logs");
|
|
2307
|
+
var defaultConfig2 = {
|
|
3765
2308
|
level: "info",
|
|
3766
2309
|
defaultName: "clarity",
|
|
3767
2310
|
timestamp: true,
|
|
@@ -3769,7 +2312,7 @@ var defaultConfig3 = {
|
|
|
3769
2312
|
format: "text",
|
|
3770
2313
|
maxLogSize: 10485760,
|
|
3771
2314
|
logDatePattern: "YYYY-MM-DD",
|
|
3772
|
-
logDirectory:
|
|
2315
|
+
logDirectory: defaultLogDirectory2,
|
|
3773
2316
|
rotation: {
|
|
3774
2317
|
frequency: "daily",
|
|
3775
2318
|
maxSize: 10485760,
|
|
@@ -3785,26 +2328,26 @@ var defaultConfig3 = {
|
|
|
3785
2328
|
};
|
|
3786
2329
|
async function loadConfig22() {
|
|
3787
2330
|
try {
|
|
3788
|
-
const loadedConfig = await
|
|
2331
|
+
const loadedConfig = await loadConfig3({
|
|
3789
2332
|
name: "clarity",
|
|
3790
|
-
defaultConfig:
|
|
2333
|
+
defaultConfig: defaultConfig2,
|
|
3791
2334
|
cwd: process22.cwd(),
|
|
3792
2335
|
endpoint: "",
|
|
3793
2336
|
headers: {}
|
|
3794
2337
|
});
|
|
3795
|
-
return { ...
|
|
2338
|
+
return { ...defaultConfig2, ...loadedConfig };
|
|
3796
2339
|
} catch {
|
|
3797
|
-
return
|
|
2340
|
+
return defaultConfig2;
|
|
3798
2341
|
}
|
|
3799
2342
|
}
|
|
3800
|
-
var
|
|
3801
|
-
function
|
|
2343
|
+
var config2 = await loadConfig22();
|
|
2344
|
+
function isBrowserProcess2() {
|
|
3802
2345
|
if (process33.env.NODE_ENV === "test" || process33.env.BUN_ENV === "test") {
|
|
3803
2346
|
return false;
|
|
3804
2347
|
}
|
|
3805
2348
|
return typeof window !== "undefined";
|
|
3806
2349
|
}
|
|
3807
|
-
async function
|
|
2350
|
+
async function isServerProcess2() {
|
|
3808
2351
|
if (process33.env.NODE_ENV === "test" || process33.env.BUN_ENV === "test") {
|
|
3809
2352
|
return true;
|
|
3810
2353
|
}
|
|
@@ -3821,9 +2364,9 @@ async function isServerProcess3() {
|
|
|
3821
2364
|
return false;
|
|
3822
2365
|
}
|
|
3823
2366
|
|
|
3824
|
-
class
|
|
2367
|
+
class JsonFormatter2 {
|
|
3825
2368
|
async format(entry) {
|
|
3826
|
-
const isServer = await
|
|
2369
|
+
const isServer = await isServerProcess2();
|
|
3827
2370
|
const metadata = await this.getMetadata(isServer);
|
|
3828
2371
|
return JSON.stringify({
|
|
3829
2372
|
timestamp: entry.timestamp.toISOString(),
|
|
@@ -3856,7 +2399,7 @@ class JsonFormatter3 {
|
|
|
3856
2399
|
};
|
|
3857
2400
|
}
|
|
3858
2401
|
}
|
|
3859
|
-
var
|
|
2402
|
+
var terminalStyles2 = {
|
|
3860
2403
|
red: (text) => `\x1B[31m${text}\x1B[0m`,
|
|
3861
2404
|
green: (text) => `\x1B[32m${text}\x1B[0m`,
|
|
3862
2405
|
yellow: (text) => `\x1B[33m${text}\x1B[0m`,
|
|
@@ -3873,37 +2416,37 @@ var terminalStyles3 = {
|
|
|
3873
2416
|
underline: (text) => `\x1B[4m${text}\x1B[0m`,
|
|
3874
2417
|
reset: "\x1B[0m"
|
|
3875
2418
|
};
|
|
3876
|
-
var
|
|
3877
|
-
var
|
|
3878
|
-
var
|
|
3879
|
-
var
|
|
3880
|
-
var
|
|
3881
|
-
var
|
|
3882
|
-
var
|
|
3883
|
-
var
|
|
3884
|
-
var
|
|
3885
|
-
var
|
|
3886
|
-
var
|
|
3887
|
-
var
|
|
3888
|
-
var
|
|
3889
|
-
var
|
|
3890
|
-
var
|
|
3891
|
-
var
|
|
3892
|
-
var
|
|
2419
|
+
var styles2 = terminalStyles2;
|
|
2420
|
+
var red2 = terminalStyles2.red;
|
|
2421
|
+
var green2 = terminalStyles2.green;
|
|
2422
|
+
var yellow2 = terminalStyles2.yellow;
|
|
2423
|
+
var blue2 = terminalStyles2.blue;
|
|
2424
|
+
var magenta2 = terminalStyles2.magenta;
|
|
2425
|
+
var cyan2 = terminalStyles2.cyan;
|
|
2426
|
+
var white2 = terminalStyles2.white;
|
|
2427
|
+
var gray2 = terminalStyles2.gray;
|
|
2428
|
+
var bgRed2 = terminalStyles2.bgRed;
|
|
2429
|
+
var bgYellow2 = terminalStyles2.bgYellow;
|
|
2430
|
+
var bold2 = terminalStyles2.bold;
|
|
2431
|
+
var dim2 = terminalStyles2.dim;
|
|
2432
|
+
var italic2 = terminalStyles2.italic;
|
|
2433
|
+
var underline2 = terminalStyles2.underline;
|
|
2434
|
+
var reset2 = terminalStyles2.reset;
|
|
2435
|
+
var defaultFingersCrossedConfig2 = {
|
|
3893
2436
|
activationLevel: "error",
|
|
3894
2437
|
bufferSize: 50,
|
|
3895
2438
|
flushOnDeactivation: true,
|
|
3896
2439
|
stopBuffering: false
|
|
3897
2440
|
};
|
|
3898
|
-
var
|
|
2441
|
+
var levelIcons2 = {
|
|
3899
2442
|
debug: "\uD83D\uDD0D",
|
|
3900
|
-
info:
|
|
3901
|
-
success:
|
|
3902
|
-
warning:
|
|
3903
|
-
error:
|
|
2443
|
+
info: blue2("\u2139"),
|
|
2444
|
+
success: green2("\u2713"),
|
|
2445
|
+
warning: bgYellow2(white2(bold2(" WARN "))),
|
|
2446
|
+
error: bgRed2(white2(bold2(" ERROR ")))
|
|
3904
2447
|
};
|
|
3905
2448
|
|
|
3906
|
-
class
|
|
2449
|
+
class Logger2 {
|
|
3907
2450
|
name;
|
|
3908
2451
|
fileLocks = new Map;
|
|
3909
2452
|
currentKeyId = null;
|
|
@@ -3932,9 +2475,9 @@ class Logger3 {
|
|
|
3932
2475
|
activeProgressBar = null;
|
|
3933
2476
|
constructor(name, options = {}) {
|
|
3934
2477
|
this.name = name;
|
|
3935
|
-
this.config = { ...
|
|
2478
|
+
this.config = { ...config2 };
|
|
3936
2479
|
this.options = this.normalizeOptions(options);
|
|
3937
|
-
this.formatter = this.options.formatter || new
|
|
2480
|
+
this.formatter = this.options.formatter || new JsonFormatter2;
|
|
3938
2481
|
this.enabled = options.enabled ?? true;
|
|
3939
2482
|
this.fancy = options.fancy ?? true;
|
|
3940
2483
|
this.tagFormat = options.tagFormat ?? { prefix: "[", suffix: "]" };
|
|
@@ -3951,12 +2494,6 @@ class Logger3 {
|
|
|
3951
2494
|
...configOptions,
|
|
3952
2495
|
timestamp: hasTimestamp || this.config.timestamp
|
|
3953
2496
|
};
|
|
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
2497
|
this.currentLogFile = this.generateLogFilename();
|
|
3961
2498
|
this.encryptionKeys = new Map;
|
|
3962
2499
|
if (this.validateEncryptionConfig()) {
|
|
@@ -3975,7 +2512,7 @@ class Logger3 {
|
|
|
3975
2512
|
initializeFingersCrossedConfig(options) {
|
|
3976
2513
|
if (!options.fingersCrossedEnabled && options.fingersCrossed) {
|
|
3977
2514
|
return {
|
|
3978
|
-
...
|
|
2515
|
+
...defaultFingersCrossedConfig2,
|
|
3979
2516
|
...options.fingersCrossed
|
|
3980
2517
|
};
|
|
3981
2518
|
}
|
|
@@ -3983,10 +2520,10 @@ class Logger3 {
|
|
|
3983
2520
|
return null;
|
|
3984
2521
|
}
|
|
3985
2522
|
if (!options.fingersCrossed) {
|
|
3986
|
-
return { ...
|
|
2523
|
+
return { ...defaultFingersCrossedConfig2 };
|
|
3987
2524
|
}
|
|
3988
2525
|
return {
|
|
3989
|
-
...
|
|
2526
|
+
...defaultFingersCrossedConfig2,
|
|
3990
2527
|
...options.fingersCrossed
|
|
3991
2528
|
};
|
|
3992
2529
|
}
|
|
@@ -3994,7 +2531,7 @@ class Logger3 {
|
|
|
3994
2531
|
const defaultOptions = {
|
|
3995
2532
|
format: "json",
|
|
3996
2533
|
level: "info",
|
|
3997
|
-
logDirectory:
|
|
2534
|
+
logDirectory: config2.logDirectory,
|
|
3998
2535
|
rotation: undefined,
|
|
3999
2536
|
timestamp: undefined,
|
|
4000
2537
|
fingersCrossed: {},
|
|
@@ -4022,11 +2559,11 @@ class Logger3 {
|
|
|
4022
2559
|
try {
|
|
4023
2560
|
try {
|
|
4024
2561
|
try {
|
|
4025
|
-
await
|
|
2562
|
+
await access2(this.config.logDirectory, constants2.F_OK | constants2.W_OK);
|
|
4026
2563
|
} catch (err) {
|
|
4027
2564
|
if (err instanceof Error && "code" in err) {
|
|
4028
2565
|
if (err.code === "ENOENT") {
|
|
4029
|
-
await
|
|
2566
|
+
await mkdir2(this.config.logDirectory, { recursive: true, mode: 493 });
|
|
4030
2567
|
} else if (err.code === "EACCES") {
|
|
4031
2568
|
throw new Error(`No write permission for log directory: ${this.config.logDirectory}`);
|
|
4032
2569
|
} else {
|
|
@@ -4042,22 +2579,22 @@ class Logger3 {
|
|
|
4042
2579
|
}
|
|
4043
2580
|
if (cancelled)
|
|
4044
2581
|
throw new Error("Operation cancelled: Logger was destroyed");
|
|
4045
|
-
const dataToWrite = this.validateEncryptionConfig() ? (await this.encrypt(data)).encrypted :
|
|
2582
|
+
const dataToWrite = this.validateEncryptionConfig() ? (await this.encrypt(data)).encrypted : Buffer2.from(data);
|
|
4046
2583
|
try {
|
|
4047
2584
|
if (!existsSync22(this.currentLogFile)) {
|
|
4048
|
-
await
|
|
2585
|
+
await writeFile2(this.currentLogFile, "", { mode: 420 });
|
|
4049
2586
|
}
|
|
4050
|
-
fd =
|
|
2587
|
+
fd = openSync2(this.currentLogFile, "a", 420);
|
|
4051
2588
|
writeFileSync22(fd, dataToWrite, { flag: "a" });
|
|
4052
|
-
|
|
2589
|
+
fsyncSync2(fd);
|
|
4053
2590
|
if (fd !== undefined) {
|
|
4054
|
-
|
|
2591
|
+
closeSync2(fd);
|
|
4055
2592
|
fd = undefined;
|
|
4056
2593
|
}
|
|
4057
|
-
const stats = await
|
|
2594
|
+
const stats = await stat2(this.currentLogFile);
|
|
4058
2595
|
if (stats.size === 0) {
|
|
4059
|
-
await
|
|
4060
|
-
const retryStats = await
|
|
2596
|
+
await writeFile2(this.currentLogFile, dataToWrite, { flag: "w", mode: 420 });
|
|
2597
|
+
const retryStats = await stat2(this.currentLogFile);
|
|
4061
2598
|
if (retryStats.size === 0) {
|
|
4062
2599
|
throw new Error("File exists but is empty after retry write");
|
|
4063
2600
|
}
|
|
@@ -4070,7 +2607,7 @@ class Logger3 {
|
|
|
4070
2607
|
const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
|
|
4071
2608
|
console.error(`Network error during write attempt ${retries + 1}/${maxRetries}:`, errorMessage);
|
|
4072
2609
|
const delay = backoffDelay * 2 ** retries;
|
|
4073
|
-
await new Promise((
|
|
2610
|
+
await new Promise((resolve32) => setTimeout(resolve32, delay));
|
|
4074
2611
|
retries++;
|
|
4075
2612
|
continue;
|
|
4076
2613
|
}
|
|
@@ -4083,7 +2620,7 @@ class Logger3 {
|
|
|
4083
2620
|
} finally {
|
|
4084
2621
|
if (fd !== undefined) {
|
|
4085
2622
|
try {
|
|
4086
|
-
|
|
2623
|
+
closeSync2(fd);
|
|
4087
2624
|
} catch (err) {
|
|
4088
2625
|
console.error("Debug: [writeToFile] Error closing file descriptor:", err);
|
|
4089
2626
|
}
|
|
@@ -4098,7 +2635,7 @@ class Logger3 {
|
|
|
4098
2635
|
}
|
|
4099
2636
|
retries++;
|
|
4100
2637
|
const delay = backoffDelay * 2 ** (retries - 1);
|
|
4101
|
-
await new Promise((
|
|
2638
|
+
await new Promise((resolve32) => setTimeout(resolve32, delay));
|
|
4102
2639
|
}
|
|
4103
2640
|
}
|
|
4104
2641
|
})();
|
|
@@ -4124,7 +2661,7 @@ class Logger3 {
|
|
|
4124
2661
|
return join22(this.config.logDirectory, `${this.name}-${date}.log`);
|
|
4125
2662
|
}
|
|
4126
2663
|
setupRotation() {
|
|
4127
|
-
if (
|
|
2664
|
+
if (isBrowserProcess2())
|
|
4128
2665
|
return;
|
|
4129
2666
|
if (typeof this.config.rotation === "boolean")
|
|
4130
2667
|
return;
|
|
@@ -4191,10 +2728,10 @@ class Logger3 {
|
|
|
4191
2728
|
}
|
|
4192
2729
|
}
|
|
4193
2730
|
generateKeyId() {
|
|
4194
|
-
return
|
|
2731
|
+
return randomBytes2(16).toString("hex");
|
|
4195
2732
|
}
|
|
4196
2733
|
generateKey() {
|
|
4197
|
-
return
|
|
2734
|
+
return randomBytes2(32);
|
|
4198
2735
|
}
|
|
4199
2736
|
getCurrentKey() {
|
|
4200
2737
|
if (!this.currentKeyId) {
|
|
@@ -4208,24 +2745,24 @@ class Logger3 {
|
|
|
4208
2745
|
}
|
|
4209
2746
|
encrypt(data) {
|
|
4210
2747
|
const { key } = this.getCurrentKey();
|
|
4211
|
-
const iv =
|
|
4212
|
-
const cipher =
|
|
4213
|
-
const encrypted =
|
|
2748
|
+
const iv = randomBytes2(16);
|
|
2749
|
+
const cipher = createCipheriv2("aes-256-gcm", key, iv);
|
|
2750
|
+
const encrypted = Buffer2.concat([
|
|
4214
2751
|
cipher.update(data, "utf8"),
|
|
4215
2752
|
cipher.final()
|
|
4216
2753
|
]);
|
|
4217
2754
|
const authTag = cipher.getAuthTag();
|
|
4218
2755
|
return {
|
|
4219
|
-
encrypted:
|
|
2756
|
+
encrypted: Buffer2.concat([iv, encrypted, authTag]),
|
|
4220
2757
|
iv
|
|
4221
2758
|
};
|
|
4222
2759
|
}
|
|
4223
2760
|
async compressData(data) {
|
|
4224
|
-
return new Promise((
|
|
4225
|
-
const gzip =
|
|
2761
|
+
return new Promise((resolve32, reject) => {
|
|
2762
|
+
const gzip = createGzip2();
|
|
4226
2763
|
const chunks = [];
|
|
4227
2764
|
gzip.on("data", (chunk2) => chunks.push(chunk2));
|
|
4228
|
-
gzip.on("end", () =>
|
|
2765
|
+
gzip.on("end", () => resolve32(Buffer2.from(Buffer2.concat(chunks))));
|
|
4229
2766
|
gzip.on("error", reject);
|
|
4230
2767
|
gzip.write(data);
|
|
4231
2768
|
gzip.end();
|
|
@@ -4249,9 +2786,9 @@ class Logger3 {
|
|
|
4249
2786
|
return defaultOptions;
|
|
4250
2787
|
}
|
|
4251
2788
|
async rotateLog() {
|
|
4252
|
-
if (
|
|
2789
|
+
if (isBrowserProcess2())
|
|
4253
2790
|
return;
|
|
4254
|
-
const stats = await
|
|
2791
|
+
const stats = await stat2(this.currentLogFile).catch(() => null);
|
|
4255
2792
|
if (!stats)
|
|
4256
2793
|
return;
|
|
4257
2794
|
const config22 = this.config.rotation;
|
|
@@ -4261,7 +2798,7 @@ class Logger3 {
|
|
|
4261
2798
|
const oldFile = this.currentLogFile;
|
|
4262
2799
|
const newFile = this.generateLogFilename();
|
|
4263
2800
|
if (this.name.includes("rotation-load-test") || this.name === "failed-rotation-test") {
|
|
4264
|
-
const files = await
|
|
2801
|
+
const files = await readdir2(this.config.logDirectory);
|
|
4265
2802
|
const rotatedFiles = files.filter((f) => f.startsWith(this.name) && /\.log\.\d+$/.test(f)).sort((a, b) => {
|
|
4266
2803
|
const numA = Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1] || "0");
|
|
4267
2804
|
const numB = Number.parseInt(b.match(/\.log\.(\d+)$/)?.[1] || "0");
|
|
@@ -4269,14 +2806,14 @@ class Logger3 {
|
|
|
4269
2806
|
});
|
|
4270
2807
|
const nextNum = rotatedFiles.length > 0 ? Number.parseInt(rotatedFiles[0].match(/\.log\.(\d+)$/)?.[1] || "0") + 1 : 1;
|
|
4271
2808
|
const rotatedFile = `${oldFile}.${nextNum}`;
|
|
4272
|
-
if (await
|
|
2809
|
+
if (await stat2(oldFile).catch(() => null)) {
|
|
4273
2810
|
try {
|
|
4274
|
-
await
|
|
2811
|
+
await rename2(oldFile, rotatedFile);
|
|
4275
2812
|
if (config22.compress) {
|
|
4276
2813
|
try {
|
|
4277
2814
|
const compressedPath = `${rotatedFile}.gz`;
|
|
4278
2815
|
await this.compressLogFile(rotatedFile, compressedPath);
|
|
4279
|
-
await
|
|
2816
|
+
await unlink2(rotatedFile);
|
|
4280
2817
|
} catch (err) {
|
|
4281
2818
|
console.error("Error compressing rotated file:", err);
|
|
4282
2819
|
}
|
|
@@ -4284,7 +2821,7 @@ class Logger3 {
|
|
|
4284
2821
|
if (rotatedFiles.length === 0 && !files.some((f) => f.endsWith(".log.1"))) {
|
|
4285
2822
|
try {
|
|
4286
2823
|
const backupPath = `${oldFile}.1`;
|
|
4287
|
-
await
|
|
2824
|
+
await writeFile2(backupPath, "");
|
|
4288
2825
|
} catch (err) {
|
|
4289
2826
|
console.error("Error creating backup file:", err);
|
|
4290
2827
|
}
|
|
@@ -4296,25 +2833,25 @@ class Logger3 {
|
|
|
4296
2833
|
} else {
|
|
4297
2834
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
4298
2835
|
const rotatedFile = oldFile.replace(/\.log$/, `-${timestamp}.log`);
|
|
4299
|
-
if (await
|
|
4300
|
-
await
|
|
2836
|
+
if (await stat2(oldFile).catch(() => null)) {
|
|
2837
|
+
await rename2(oldFile, rotatedFile);
|
|
4301
2838
|
}
|
|
4302
2839
|
}
|
|
4303
2840
|
this.currentLogFile = newFile;
|
|
4304
2841
|
if (config22.maxFiles) {
|
|
4305
|
-
const files = await
|
|
2842
|
+
const files = await readdir2(this.config.logDirectory);
|
|
4306
2843
|
const logFiles = files.filter((f) => f.startsWith(this.name)).sort((a, b) => b.localeCompare(a));
|
|
4307
2844
|
for (const file of logFiles.slice(config22.maxFiles)) {
|
|
4308
|
-
await
|
|
2845
|
+
await unlink2(join22(this.config.logDirectory, file));
|
|
4309
2846
|
}
|
|
4310
2847
|
}
|
|
4311
2848
|
}
|
|
4312
2849
|
}
|
|
4313
2850
|
async compressLogFile(inputPath, outputPath) {
|
|
4314
|
-
const readStream =
|
|
4315
|
-
const writeStream =
|
|
4316
|
-
const gzip =
|
|
4317
|
-
await
|
|
2851
|
+
const readStream = createReadStream2(inputPath);
|
|
2852
|
+
const writeStream = createWriteStream2(outputPath);
|
|
2853
|
+
const gzip = createGzip2();
|
|
2854
|
+
await pipeline2(readStream, gzip, writeStream);
|
|
4318
2855
|
}
|
|
4319
2856
|
async handleFingersCrossedBuffer(level, formattedEntry) {
|
|
4320
2857
|
if (!this.fingersCrossedConfig)
|
|
@@ -4382,9 +2919,9 @@ class Logger3 {
|
|
|
4382
2919
|
}));
|
|
4383
2920
|
if (existsSync22(this.currentLogFile)) {
|
|
4384
2921
|
try {
|
|
4385
|
-
const fd =
|
|
4386
|
-
|
|
4387
|
-
|
|
2922
|
+
const fd = openSync2(this.currentLogFile, "r+");
|
|
2923
|
+
fsyncSync2(fd);
|
|
2924
|
+
closeSync2(fd);
|
|
4388
2925
|
} catch (error) {
|
|
4389
2926
|
console.error(`Error flushing file: ${error}`);
|
|
4390
2927
|
}
|
|
@@ -4409,13 +2946,13 @@ class Logger3 {
|
|
|
4409
2946
|
console.error("Error waiting for pending operations:", err);
|
|
4410
2947
|
}
|
|
4411
2948
|
}
|
|
4412
|
-
if (!
|
|
2949
|
+
if (!isBrowserProcess2() && this.config.rotation && typeof this.config.rotation !== "boolean" && this.config.rotation.compress) {
|
|
4413
2950
|
try {
|
|
4414
|
-
const files = await
|
|
2951
|
+
const files = await readdir2(this.config.logDirectory);
|
|
4415
2952
|
const tempFiles = files.filter((f) => (f.includes("temp") || f.includes(".tmp")) && f.includes(this.name));
|
|
4416
2953
|
for (const tempFile of tempFiles) {
|
|
4417
2954
|
try {
|
|
4418
|
-
await
|
|
2955
|
+
await unlink2(join22(this.config.logDirectory, tempFile));
|
|
4419
2956
|
} catch (err) {
|
|
4420
2957
|
console.error(`Failed to delete temp file ${tempFile}:`, err);
|
|
4421
2958
|
}
|
|
@@ -4438,7 +2975,7 @@ class Logger3 {
|
|
|
4438
2975
|
return `[${date.toISOString()}]`;
|
|
4439
2976
|
}
|
|
4440
2977
|
formatConsoleTimestamp(date) {
|
|
4441
|
-
return this.fancy ?
|
|
2978
|
+
return this.fancy ? styles2.gray(date.toLocaleTimeString()) : date.toLocaleTimeString();
|
|
4442
2979
|
}
|
|
4443
2980
|
formatConsoleMessage(parts) {
|
|
4444
2981
|
const { timestamp, icon = "", tag = "", message, level, showTimestamp = true } = parts;
|
|
@@ -4465,7 +3002,7 @@ class Logger3 {
|
|
|
4465
3002
|
} else if (level === "info" || level === "success") {
|
|
4466
3003
|
mainPart = `${icon} ${tag} ${message}`;
|
|
4467
3004
|
} else {
|
|
4468
|
-
mainPart = `${icon} ${tag} ${
|
|
3005
|
+
mainPart = `${icon} ${tag} ${styles2.cyan(message)}`;
|
|
4469
3006
|
}
|
|
4470
3007
|
if (!showTimestamp) {
|
|
4471
3008
|
return mainPart.trim();
|
|
@@ -4520,9 +3057,9 @@ class Logger3 {
|
|
|
4520
3057
|
} else {
|
|
4521
3058
|
formattedMessage = this.formatMessage(message, args);
|
|
4522
3059
|
}
|
|
4523
|
-
if (this.fancy && !
|
|
4524
|
-
const icon =
|
|
4525
|
-
const tag = this.options.showTags !== false && this.name ?
|
|
3060
|
+
if (this.fancy && !isBrowserProcess2()) {
|
|
3061
|
+
const icon = levelIcons2[level];
|
|
3062
|
+
const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
|
|
4526
3063
|
let consoleMessage;
|
|
4527
3064
|
switch (level) {
|
|
4528
3065
|
case "debug":
|
|
@@ -4530,7 +3067,7 @@ class Logger3 {
|
|
|
4530
3067
|
timestamp: consoleTime,
|
|
4531
3068
|
icon,
|
|
4532
3069
|
tag,
|
|
4533
|
-
message:
|
|
3070
|
+
message: styles2.gray(formattedMessage),
|
|
4534
3071
|
level
|
|
4535
3072
|
});
|
|
4536
3073
|
console.error(consoleMessage);
|
|
@@ -4550,7 +3087,7 @@ class Logger3 {
|
|
|
4550
3087
|
timestamp: consoleTime,
|
|
4551
3088
|
icon,
|
|
4552
3089
|
tag,
|
|
4553
|
-
message:
|
|
3090
|
+
message: styles2.green(formattedMessage),
|
|
4554
3091
|
level
|
|
4555
3092
|
});
|
|
4556
3093
|
console.error(consoleMessage);
|
|
@@ -4581,7 +3118,7 @@ class Logger3 {
|
|
|
4581
3118
|
if (line.trim() && !line.includes(formattedMessage)) {
|
|
4582
3119
|
console.error(this.formatConsoleMessage({
|
|
4583
3120
|
timestamp: consoleTime,
|
|
4584
|
-
message:
|
|
3121
|
+
message: styles2.gray(` ${line}`),
|
|
4585
3122
|
level,
|
|
4586
3123
|
showTimestamp: false
|
|
4587
3124
|
}));
|
|
@@ -4590,7 +3127,7 @@ class Logger3 {
|
|
|
4590
3127
|
}
|
|
4591
3128
|
break;
|
|
4592
3129
|
}
|
|
4593
|
-
} else if (!
|
|
3130
|
+
} else if (!isBrowserProcess2()) {
|
|
4594
3131
|
console.error(`${fileTime} ${this.environment}.${level.toUpperCase()}: ${formattedMessage}`);
|
|
4595
3132
|
if (errorStack) {
|
|
4596
3133
|
console.error(errorStack);
|
|
@@ -4609,14 +3146,14 @@ class Logger3 {
|
|
|
4609
3146
|
}
|
|
4610
3147
|
time(label) {
|
|
4611
3148
|
const start = performance.now();
|
|
4612
|
-
if (this.fancy && !
|
|
4613
|
-
const tag = this.options.showTags !== false && this.name ?
|
|
3149
|
+
if (this.fancy && !isBrowserProcess2()) {
|
|
3150
|
+
const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
|
|
4614
3151
|
const consoleTime = this.formatConsoleTimestamp(new Date);
|
|
4615
3152
|
console.error(this.formatConsoleMessage({
|
|
4616
3153
|
timestamp: consoleTime,
|
|
4617
|
-
icon:
|
|
3154
|
+
icon: styles2.blue("\u25D0"),
|
|
4618
3155
|
tag,
|
|
4619
|
-
message: `${
|
|
3156
|
+
message: `${styles2.cyan(label)}...`
|
|
4620
3157
|
}));
|
|
4621
3158
|
}
|
|
4622
3159
|
return async (metadata) => {
|
|
@@ -4635,15 +3172,15 @@ class Logger3 {
|
|
|
4635
3172
|
logEntry += `
|
|
4636
3173
|
`;
|
|
4637
3174
|
logEntry = logEntry.replace(this.ANSI_PATTERN, "");
|
|
4638
|
-
if (this.fancy && !
|
|
4639
|
-
const tag = this.options.showTags !== false && this.name ?
|
|
3175
|
+
if (this.fancy && !isBrowserProcess2()) {
|
|
3176
|
+
const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
|
|
4640
3177
|
console.error(this.formatConsoleMessage({
|
|
4641
3178
|
timestamp: consoleTime,
|
|
4642
|
-
icon:
|
|
3179
|
+
icon: styles2.green("\u2713"),
|
|
4643
3180
|
tag,
|
|
4644
3181
|
message: `${completionMessage}${metadata ? ` ${JSON.stringify(metadata)}` : ""}`
|
|
4645
3182
|
}));
|
|
4646
|
-
} else if (!
|
|
3183
|
+
} else if (!isBrowserProcess2()) {
|
|
4647
3184
|
console.error(logEntry.trim());
|
|
4648
3185
|
}
|
|
4649
3186
|
await this.writeToFile(logEntry);
|
|
@@ -4686,7 +3223,7 @@ class Logger3 {
|
|
|
4686
3223
|
}
|
|
4687
3224
|
extend(namespace) {
|
|
4688
3225
|
const childName = `${this.name}:${namespace}`;
|
|
4689
|
-
const childLogger = new
|
|
3226
|
+
const childLogger = new Logger2(childName, {
|
|
4690
3227
|
...this.options,
|
|
4691
3228
|
logDirectory: this.config.logDirectory,
|
|
4692
3229
|
level: this.config.level,
|
|
@@ -4698,11 +3235,11 @@ class Logger3 {
|
|
|
4698
3235
|
return childLogger;
|
|
4699
3236
|
}
|
|
4700
3237
|
createReadStream() {
|
|
4701
|
-
if (
|
|
3238
|
+
if (isBrowserProcess2())
|
|
4702
3239
|
throw new Error("createReadStream is not supported in browser environments");
|
|
4703
3240
|
if (!existsSync22(this.currentLogFile))
|
|
4704
3241
|
throw new Error(`Log file does not exist: ${this.currentLogFile}`);
|
|
4705
|
-
return
|
|
3242
|
+
return createReadStream2(this.currentLogFile, { encoding: "utf8" });
|
|
4706
3243
|
}
|
|
4707
3244
|
async decrypt(data) {
|
|
4708
3245
|
if (!this.validateEncryptionConfig())
|
|
@@ -4714,13 +3251,13 @@ class Logger3 {
|
|
|
4714
3251
|
throw new Error("No valid encryption key available");
|
|
4715
3252
|
const key = this.keys.get(this.currentKeyId);
|
|
4716
3253
|
try {
|
|
4717
|
-
const encryptedData =
|
|
3254
|
+
const encryptedData = Buffer2.isBuffer(data) ? data : Buffer2.from(data, "base64");
|
|
4718
3255
|
const iv = encryptedData.slice(0, 16);
|
|
4719
3256
|
const authTag = encryptedData.slice(-16);
|
|
4720
3257
|
const ciphertext = encryptedData.slice(16, -16);
|
|
4721
|
-
const decipher =
|
|
3258
|
+
const decipher = createDecipheriv2("aes-256-gcm", key, iv);
|
|
4722
3259
|
decipher.setAuthTag(authTag);
|
|
4723
|
-
const decrypted =
|
|
3260
|
+
const decrypted = Buffer2.concat([
|
|
4724
3261
|
decipher.update(ciphertext),
|
|
4725
3262
|
decipher.final()
|
|
4726
3263
|
]);
|
|
@@ -4742,10 +3279,10 @@ class Logger3 {
|
|
|
4742
3279
|
return this.config.rotation;
|
|
4743
3280
|
}
|
|
4744
3281
|
isBrowserMode() {
|
|
4745
|
-
return
|
|
3282
|
+
return isBrowserProcess2();
|
|
4746
3283
|
}
|
|
4747
3284
|
isServerMode() {
|
|
4748
|
-
return !
|
|
3285
|
+
return !isBrowserProcess2();
|
|
4749
3286
|
}
|
|
4750
3287
|
setTestEncryptionKey(keyId, key) {
|
|
4751
3288
|
this.currentKeyId = keyId;
|
|
@@ -4769,7 +3306,7 @@ class Logger3 {
|
|
|
4769
3306
|
const timestamp = new Date;
|
|
4770
3307
|
const consoleTime = this.formatConsoleTimestamp(timestamp);
|
|
4771
3308
|
const fileTime = this.formatFileTimestamp(timestamp);
|
|
4772
|
-
if (this.fancy && !
|
|
3309
|
+
if (this.fancy && !isBrowserProcess2()) {
|
|
4773
3310
|
const lines = message.split(`
|
|
4774
3311
|
`);
|
|
4775
3312
|
const width = Math.max(...lines.map((line) => line.length)) + 2;
|
|
@@ -4782,25 +3319,25 @@ class Logger3 {
|
|
|
4782
3319
|
if (this.options.showTags !== false && this.name) {
|
|
4783
3320
|
console.error(this.formatConsoleMessage({
|
|
4784
3321
|
timestamp: consoleTime,
|
|
4785
|
-
message:
|
|
3322
|
+
message: styles2.gray(this.formatTag(this.name)),
|
|
4786
3323
|
showTimestamp: false
|
|
4787
3324
|
}));
|
|
4788
3325
|
}
|
|
4789
3326
|
console.error(this.formatConsoleMessage({
|
|
4790
3327
|
timestamp: consoleTime,
|
|
4791
|
-
message:
|
|
3328
|
+
message: styles2.cyan(top)
|
|
4792
3329
|
}));
|
|
4793
3330
|
boxedLines.forEach((line) => console.error(this.formatConsoleMessage({
|
|
4794
3331
|
timestamp: consoleTime,
|
|
4795
|
-
message:
|
|
3332
|
+
message: styles2.cyan(line),
|
|
4796
3333
|
showTimestamp: false
|
|
4797
3334
|
})));
|
|
4798
3335
|
console.error(this.formatConsoleMessage({
|
|
4799
3336
|
timestamp: consoleTime,
|
|
4800
|
-
message:
|
|
3337
|
+
message: styles2.cyan(bottom),
|
|
4801
3338
|
showTimestamp: false
|
|
4802
3339
|
}));
|
|
4803
|
-
} else if (!
|
|
3340
|
+
} else if (!isBrowserProcess2()) {
|
|
4804
3341
|
console.error(`${fileTime} ${this.environment}.INFO: [BOX] ${message}`);
|
|
4805
3342
|
}
|
|
4806
3343
|
const logEntry = `${fileTime} ${this.environment}.INFO: [BOX] ${message}
|
|
@@ -4808,11 +3345,11 @@ class Logger3 {
|
|
|
4808
3345
|
await this.writeToFile(logEntry);
|
|
4809
3346
|
}
|
|
4810
3347
|
async prompt(message) {
|
|
4811
|
-
if (
|
|
3348
|
+
if (isBrowserProcess2()) {
|
|
4812
3349
|
return Promise.resolve(true);
|
|
4813
3350
|
}
|
|
4814
|
-
return new Promise((
|
|
4815
|
-
console.error(`${
|
|
3351
|
+
return new Promise((resolve32) => {
|
|
3352
|
+
console.error(`${styles2.cyan("?")} ${message} (y/n) `);
|
|
4816
3353
|
const onData = (data) => {
|
|
4817
3354
|
const input = data.toString().trim().toLowerCase();
|
|
4818
3355
|
process52.stdin.removeListener("data", onData);
|
|
@@ -4823,7 +3360,7 @@ class Logger3 {
|
|
|
4823
3360
|
} catch {}
|
|
4824
3361
|
process52.stdin.pause();
|
|
4825
3362
|
console.error("");
|
|
4826
|
-
|
|
3363
|
+
resolve32(input === "y" || input === "yes");
|
|
4827
3364
|
};
|
|
4828
3365
|
try {
|
|
4829
3366
|
if (typeof process52.stdin.setRawMode === "function") {
|
|
@@ -4876,10 +3413,10 @@ class Logger3 {
|
|
|
4876
3413
|
formattedMessage += ` ${args.slice(argIndex).map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ")}`;
|
|
4877
3414
|
}
|
|
4878
3415
|
}
|
|
4879
|
-
if (this.fancy && !
|
|
4880
|
-
const tag = this.options.showTags !== false && this.name ?
|
|
4881
|
-
const spinnerChar =
|
|
4882
|
-
console.error(`${spinnerChar} ${tag} ${
|
|
3416
|
+
if (this.fancy && !isBrowserProcess2()) {
|
|
3417
|
+
const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
|
|
3418
|
+
const spinnerChar = styles2.blue("\u25D0");
|
|
3419
|
+
console.error(`${spinnerChar} ${tag} ${styles2.cyan(formattedMessage)}`);
|
|
4883
3420
|
}
|
|
4884
3421
|
const timestamp = new Date;
|
|
4885
3422
|
const formattedDate = timestamp.toISOString();
|
|
@@ -4888,7 +3425,7 @@ class Logger3 {
|
|
|
4888
3425
|
await this.writeToFile(logEntry);
|
|
4889
3426
|
}
|
|
4890
3427
|
progress(total, initialMessage = "") {
|
|
4891
|
-
if (!this.enabled || !this.fancy ||
|
|
3428
|
+
if (!this.enabled || !this.fancy || isBrowserProcess2() || total <= 0) {
|
|
4892
3429
|
return {
|
|
4893
3430
|
update: () => {},
|
|
4894
3431
|
finish: () => {},
|
|
@@ -4909,7 +3446,7 @@ class Logger3 {
|
|
|
4909
3446
|
};
|
|
4910
3447
|
this.renderProgressBar(this.activeProgressBar);
|
|
4911
3448
|
const update = (current, message) => {
|
|
4912
|
-
if (!this.activeProgressBar || !this.enabled || !this.fancy ||
|
|
3449
|
+
if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess2())
|
|
4913
3450
|
return;
|
|
4914
3451
|
this.activeProgressBar.current = Math.max(0, Math.min(total, current));
|
|
4915
3452
|
if (message !== undefined) {
|
|
@@ -4919,7 +3456,7 @@ class Logger3 {
|
|
|
4919
3456
|
this.renderProgressBar(this.activeProgressBar, isFinished);
|
|
4920
3457
|
};
|
|
4921
3458
|
const finish = (message) => {
|
|
4922
|
-
if (!this.activeProgressBar || !this.enabled || !this.fancy ||
|
|
3459
|
+
if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess2())
|
|
4923
3460
|
return;
|
|
4924
3461
|
this.activeProgressBar.current = this.activeProgressBar.total;
|
|
4925
3462
|
if (message !== undefined) {
|
|
@@ -4929,7 +3466,7 @@ class Logger3 {
|
|
|
4929
3466
|
this.finishProgressBar(this.activeProgressBar);
|
|
4930
3467
|
};
|
|
4931
3468
|
const interrupt = (interruptMessage, level = "info") => {
|
|
4932
|
-
if (!this.activeProgressBar || !this.enabled || !this.fancy ||
|
|
3469
|
+
if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess2())
|
|
4933
3470
|
return;
|
|
4934
3471
|
process52.stdout.write(`${"\r".padEnd(process52.stdout.columns || 80)}\r`);
|
|
4935
3472
|
this.log(level, interruptMessage);
|
|
@@ -4942,18 +3479,18 @@ class Logger3 {
|
|
|
4942
3479
|
return { update, finish, interrupt };
|
|
4943
3480
|
}
|
|
4944
3481
|
renderProgressBar(barState, isFinished = false) {
|
|
4945
|
-
if (!this.enabled || !this.fancy ||
|
|
3482
|
+
if (!this.enabled || !this.fancy || isBrowserProcess2() || !process52.stdout.isTTY)
|
|
4946
3483
|
return;
|
|
4947
3484
|
const percent = Math.min(100, Math.max(0, Math.round(barState.current / barState.total * 100)));
|
|
4948
3485
|
const filledLength = Math.round(barState.barLength * percent / 100);
|
|
4949
3486
|
const emptyLength = barState.barLength - filledLength;
|
|
4950
|
-
const filledBar =
|
|
4951
|
-
const emptyBar =
|
|
3487
|
+
const filledBar = styles2.green("\u2501".repeat(filledLength));
|
|
3488
|
+
const emptyBar = styles2.gray("\u2501".repeat(emptyLength));
|
|
4952
3489
|
const bar = `[${filledBar}${emptyBar}]`;
|
|
4953
3490
|
const percentageText = `${percent}%`.padStart(4);
|
|
4954
3491
|
const messageText = barState.message ? ` ${barState.message}` : "";
|
|
4955
|
-
const icon = isFinished || percent === 100 ?
|
|
4956
|
-
const tag = this.options.showTags !== false && this.name ? ` ${
|
|
3492
|
+
const icon = isFinished || percent === 100 ? styles2.green("\u2713") : styles2.blue("\u25B6");
|
|
3493
|
+
const tag = this.options.showTags !== false && this.name ? ` ${styles2.gray(this.formatTag(this.name))}` : "";
|
|
4957
3494
|
const line = `\r${icon}${tag} ${bar} ${percentageText}${messageText}`;
|
|
4958
3495
|
const terminalWidth = process52.stdout.columns || 80;
|
|
4959
3496
|
const clearLine = " ".repeat(Math.max(0, terminalWidth - line.replace(this.ANSI_PATTERN, "").length));
|
|
@@ -4965,7 +3502,7 @@ class Logger3 {
|
|
|
4965
3502
|
}
|
|
4966
3503
|
}
|
|
4967
3504
|
finishProgressBar(barState, finalMessage) {
|
|
4968
|
-
if (!this.enabled || !this.fancy ||
|
|
3505
|
+
if (!this.enabled || !this.fancy || isBrowserProcess2() || !process52.stdout.isTTY) {
|
|
4969
3506
|
this.activeProgressBar = null;
|
|
4970
3507
|
return;
|
|
4971
3508
|
}
|
|
@@ -4978,13 +3515,13 @@ class Logger3 {
|
|
|
4978
3515
|
this.activeProgressBar = null;
|
|
4979
3516
|
}
|
|
4980
3517
|
async clear(filters = {}) {
|
|
4981
|
-
if (
|
|
3518
|
+
if (isBrowserProcess2()) {
|
|
4982
3519
|
console.warn("Log clearing is not supported in browser environments.");
|
|
4983
3520
|
return;
|
|
4984
3521
|
}
|
|
4985
3522
|
try {
|
|
4986
3523
|
console.warn("Clearing logs...", this.config.logDirectory);
|
|
4987
|
-
const files = await
|
|
3524
|
+
const files = await readdir2(this.config.logDirectory);
|
|
4988
3525
|
const logFilesToDelete = [];
|
|
4989
3526
|
for (const file of files) {
|
|
4990
3527
|
const nameMatches = filters.name ? new RegExp(filters.name.replace("*", ".*")).test(file) : file.startsWith(this.name);
|
|
@@ -4994,7 +3531,7 @@ class Logger3 {
|
|
|
4994
3531
|
const filePath = join22(this.config.logDirectory, file);
|
|
4995
3532
|
if (filters.before) {
|
|
4996
3533
|
try {
|
|
4997
|
-
const fileStats = await
|
|
3534
|
+
const fileStats = await stat2(filePath);
|
|
4998
3535
|
if (fileStats.mtime >= filters.before) {
|
|
4999
3536
|
continue;
|
|
5000
3537
|
}
|
|
@@ -5012,7 +3549,7 @@ class Logger3 {
|
|
|
5012
3549
|
console.warn(`Preparing to delete ${logFilesToDelete.length} log file(s)...`);
|
|
5013
3550
|
for (const filePath of logFilesToDelete) {
|
|
5014
3551
|
try {
|
|
5015
|
-
await
|
|
3552
|
+
await unlink2(filePath);
|
|
5016
3553
|
console.warn(`Deleted log file: ${filePath}`);
|
|
5017
3554
|
} catch (unlinkErr) {
|
|
5018
3555
|
console.error(`Failed to delete log file ${filePath}:`, unlinkErr);
|
|
@@ -5024,7 +3561,7 @@ class Logger3 {
|
|
|
5024
3561
|
}
|
|
5025
3562
|
}
|
|
5026
3563
|
}
|
|
5027
|
-
var
|
|
3564
|
+
var logger2 = new Logger2("stacks");
|
|
5028
3565
|
function deepMerge22(target, source) {
|
|
5029
3566
|
if (Array.isArray(source) && Array.isArray(target) && source.length === 2 && target.length === 2 && isObject22(source[0]) && "id" in source[0] && source[0].id === 3 && isObject22(source[1]) && "id" in source[1] && source[1].id === 4) {
|
|
5030
3567
|
return source;
|
|
@@ -5150,11 +3687,11 @@ function deepEquals22(a, b) {
|
|
|
5150
3687
|
function isObject22(item) {
|
|
5151
3688
|
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
5152
3689
|
}
|
|
5153
|
-
var
|
|
3690
|
+
var log = new Logger2("bunfig", {
|
|
5154
3691
|
showTags: true
|
|
5155
3692
|
});
|
|
5156
3693
|
async function tryLoadConfig22(configPath, defaultConfig22) {
|
|
5157
|
-
if (!
|
|
3694
|
+
if (!existsSync3(configPath))
|
|
5158
3695
|
return null;
|
|
5159
3696
|
try {
|
|
5160
3697
|
const importedConfig = await import(configPath);
|
|
@@ -5170,63 +3707,146 @@ async function tryLoadConfig22(configPath, defaultConfig22) {
|
|
|
5170
3707
|
return null;
|
|
5171
3708
|
}
|
|
5172
3709
|
}
|
|
3710
|
+
function applyEnvVarsToConfig(name, config3, verbose = false) {
|
|
3711
|
+
if (!name)
|
|
3712
|
+
return config3;
|
|
3713
|
+
const envPrefix = name.toUpperCase().replace(/-/g, "_");
|
|
3714
|
+
const result = { ...config3 };
|
|
3715
|
+
function processObject(obj, path = []) {
|
|
3716
|
+
const result2 = { ...obj };
|
|
3717
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
3718
|
+
const envPath = [...path, key];
|
|
3719
|
+
const formatKey = (k) => k.replace(/([A-Z])/g, "_$1").toUpperCase();
|
|
3720
|
+
const envKey = `${envPrefix}_${envPath.map(formatKey).join("_")}`;
|
|
3721
|
+
const oldEnvKey = `${envPrefix}_${envPath.map((p) => p.toUpperCase()).join("_")}`;
|
|
3722
|
+
if (verbose)
|
|
3723
|
+
log.info(`Checking environment variable ${envKey} for config ${name}.${envPath.join(".")}`);
|
|
3724
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
3725
|
+
result2[key] = processObject(value, envPath);
|
|
3726
|
+
} else {
|
|
3727
|
+
const envValue = process8.env[envKey] || process8.env[oldEnvKey];
|
|
3728
|
+
if (envValue !== undefined) {
|
|
3729
|
+
if (verbose) {
|
|
3730
|
+
log.info(`Using environment variable ${envValue ? envKey : oldEnvKey} for config ${name}.${envPath.join(".")}`);
|
|
3731
|
+
}
|
|
3732
|
+
if (typeof value === "number") {
|
|
3733
|
+
result2[key] = Number(envValue);
|
|
3734
|
+
} else if (typeof value === "boolean") {
|
|
3735
|
+
result2[key] = envValue.toLowerCase() === "true";
|
|
3736
|
+
} else if (Array.isArray(value)) {
|
|
3737
|
+
try {
|
|
3738
|
+
const parsed = JSON.parse(envValue);
|
|
3739
|
+
if (Array.isArray(parsed)) {
|
|
3740
|
+
result2[key] = parsed;
|
|
3741
|
+
} else {
|
|
3742
|
+
result2[key] = envValue.split(",").map((item) => item.trim());
|
|
3743
|
+
}
|
|
3744
|
+
} catch {
|
|
3745
|
+
result2[key] = envValue.split(",").map((item) => item.trim());
|
|
3746
|
+
}
|
|
3747
|
+
} else {
|
|
3748
|
+
result2[key] = envValue;
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
}
|
|
3752
|
+
}
|
|
3753
|
+
return result2;
|
|
3754
|
+
}
|
|
3755
|
+
return processObject(result);
|
|
3756
|
+
}
|
|
5173
3757
|
async function loadConfig32({
|
|
5174
3758
|
name = "",
|
|
3759
|
+
alias,
|
|
5175
3760
|
cwd,
|
|
5176
|
-
defaultConfig: defaultConfig22
|
|
3761
|
+
defaultConfig: defaultConfig22,
|
|
3762
|
+
verbose = false,
|
|
3763
|
+
checkEnv = true
|
|
5177
3764
|
}) {
|
|
5178
|
-
const
|
|
3765
|
+
const configWithEnvVars = checkEnv && typeof defaultConfig22 === "object" && defaultConfig22 !== null && !Array.isArray(defaultConfig22) ? applyEnvVarsToConfig(name, defaultConfig22, verbose) : defaultConfig22;
|
|
3766
|
+
const baseDir = cwd || process8.cwd();
|
|
5179
3767
|
const extensions = [".ts", ".js", ".mjs", ".cjs", ".json"];
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
3768
|
+
if (verbose) {
|
|
3769
|
+
log.info(`Loading configuration for "${name}"${alias ? ` (alias: "${alias}")` : ""} from ${baseDir}`);
|
|
3770
|
+
}
|
|
3771
|
+
const configPatterns = [];
|
|
3772
|
+
configPatterns.push(`${name}.config`);
|
|
3773
|
+
configPatterns.push(`.${name}.config`);
|
|
3774
|
+
configPatterns.push(name);
|
|
3775
|
+
configPatterns.push(`.${name}`);
|
|
3776
|
+
if (alias) {
|
|
3777
|
+
configPatterns.push(`${alias}.config`);
|
|
3778
|
+
configPatterns.push(`.${alias}.config`);
|
|
3779
|
+
configPatterns.push(alias);
|
|
3780
|
+
configPatterns.push(`.${alias}`);
|
|
3781
|
+
}
|
|
3782
|
+
for (const configPath of configPatterns) {
|
|
5187
3783
|
for (const ext of extensions) {
|
|
5188
|
-
const fullPath =
|
|
5189
|
-
const
|
|
5190
|
-
if (
|
|
5191
|
-
|
|
5192
|
-
|
|
3784
|
+
const fullPath = resolve3(baseDir, `${configPath}${ext}`);
|
|
3785
|
+
const config3 = await tryLoadConfig22(fullPath, configWithEnvVars);
|
|
3786
|
+
if (config3 !== null) {
|
|
3787
|
+
if (verbose) {
|
|
3788
|
+
log.success(`Configuration loaded from: ${configPath}${ext}`);
|
|
3789
|
+
}
|
|
3790
|
+
return config3;
|
|
5193
3791
|
}
|
|
5194
3792
|
}
|
|
5195
3793
|
}
|
|
5196
3794
|
try {
|
|
5197
|
-
const pkgPath =
|
|
5198
|
-
if (
|
|
3795
|
+
const pkgPath = resolve3(baseDir, "package.json");
|
|
3796
|
+
if (existsSync3(pkgPath)) {
|
|
5199
3797
|
const pkg = await import(pkgPath);
|
|
5200
|
-
|
|
3798
|
+
let pkgConfig = pkg[name];
|
|
3799
|
+
if (!pkgConfig && alias) {
|
|
3800
|
+
pkgConfig = pkg[alias];
|
|
3801
|
+
if (pkgConfig && verbose) {
|
|
3802
|
+
log.success(`Using alias "${alias}" configuration from package.json`);
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
5201
3805
|
if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
|
|
5202
3806
|
try {
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
3807
|
+
if (verbose) {
|
|
3808
|
+
log.success(`Configuration loaded from package.json: ${pkgConfig === pkg[name] ? name : alias}`);
|
|
3809
|
+
}
|
|
3810
|
+
return deepMerge22(configWithEnvVars, pkgConfig);
|
|
3811
|
+
} catch (error) {
|
|
3812
|
+
if (verbose) {
|
|
3813
|
+
log.warn(`Failed to merge package.json config:`, error);
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
5206
3816
|
}
|
|
5207
3817
|
}
|
|
5208
|
-
} catch {
|
|
5209
|
-
|
|
5210
|
-
|
|
3818
|
+
} catch (error) {
|
|
3819
|
+
if (verbose) {
|
|
3820
|
+
log.warn(`Failed to load package.json:`, error);
|
|
3821
|
+
}
|
|
3822
|
+
}
|
|
3823
|
+
if (verbose) {
|
|
3824
|
+
log.info(`No configuration found for "${name}"${alias ? ` or alias "${alias}"` : ""}, using default configuration with environment variables`);
|
|
3825
|
+
}
|
|
3826
|
+
return configWithEnvVars;
|
|
5211
3827
|
}
|
|
5212
|
-
var defaultConfigDir22 =
|
|
5213
|
-
var defaultGeneratedDir22 =
|
|
3828
|
+
var defaultConfigDir22 = resolve3(process8.cwd(), "config");
|
|
3829
|
+
var defaultGeneratedDir22 = resolve3(process8.cwd(), "src/generated");
|
|
5214
3830
|
|
|
5215
3831
|
// git-hooks.config.ts
|
|
5216
|
-
var
|
|
3832
|
+
var config3 = {
|
|
5217
3833
|
"pre-commit": {
|
|
5218
3834
|
"staged-lint": {
|
|
5219
|
-
"
|
|
3835
|
+
"**/*.{js,ts}": [
|
|
3836
|
+
"bunx --bun eslint --max-warnings=0",
|
|
3837
|
+
"bunx --bun tsc --noEmit"
|
|
3838
|
+
]
|
|
5220
3839
|
}
|
|
5221
3840
|
},
|
|
3841
|
+
"commit-msg": "bunx gitlint .git/COMMIT_EDITMSG",
|
|
5222
3842
|
verbose: true
|
|
5223
3843
|
};
|
|
5224
|
-
var git_hooks_config_default =
|
|
3844
|
+
var git_hooks_config_default = config3;
|
|
5225
3845
|
|
|
5226
3846
|
// src/config.ts
|
|
5227
|
-
var
|
|
3847
|
+
var config4 = await loadConfig32({
|
|
5228
3848
|
name: "git-hooks",
|
|
5229
|
-
cwd:
|
|
3849
|
+
cwd: process9.cwd(),
|
|
5230
3850
|
defaultConfig: git_hooks_config_default
|
|
5231
3851
|
});
|
|
5232
3852
|
|
|
@@ -5234,7 +3854,7 @@ var config6 = await loadConfig32({
|
|
|
5234
3854
|
import { exec } from "child_process";
|
|
5235
3855
|
import { promisify } from "util";
|
|
5236
3856
|
var execAsync = promisify(exec);
|
|
5237
|
-
var
|
|
3857
|
+
var log2 = new Logger("git-hooks", {
|
|
5238
3858
|
showTags: true
|
|
5239
3859
|
});
|
|
5240
3860
|
var VALID_GIT_HOOKS = [
|
|
@@ -5280,7 +3900,7 @@ if [ -f "$BUN_GIT_HOOKS_RC" ]; then
|
|
|
5280
3900
|
fi
|
|
5281
3901
|
|
|
5282
3902
|
`;
|
|
5283
|
-
function getGitProjectRoot(directory =
|
|
3903
|
+
function getGitProjectRoot(directory = process11.cwd()) {
|
|
5284
3904
|
if (directory.endsWith(".git")) {
|
|
5285
3905
|
return path.normalize(directory);
|
|
5286
3906
|
}
|
|
@@ -5311,18 +3931,18 @@ function getGitProjectRoot(directory = process14.cwd()) {
|
|
|
5311
3931
|
}
|
|
5312
3932
|
return getGitProjectRoot(parentDir);
|
|
5313
3933
|
}
|
|
5314
|
-
function setHooksFromConfig(projectRootPath =
|
|
5315
|
-
if (!
|
|
3934
|
+
function setHooksFromConfig(projectRootPath = process11.cwd(), options) {
|
|
3935
|
+
if (!config4 || Object.keys(config4).length === 0)
|
|
5316
3936
|
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 || { ...
|
|
3937
|
+
const configFile = options?.configFile || { ...config4 };
|
|
5318
3938
|
_validateStagedLintConfig(configFile);
|
|
5319
3939
|
const hookKeys = Object.keys(configFile).filter((key) => !VALID_OPTIONS.includes(key));
|
|
5320
3940
|
const isValidConfig = hookKeys.every((key) => VALID_GIT_HOOKS.includes(key));
|
|
5321
3941
|
if (!isValidConfig)
|
|
5322
3942
|
throw new Error("[ERROR] Config was not in correct format. Please check git hooks or options name");
|
|
5323
3943
|
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
|
-
|
|
3944
|
+
const logKeys = Object.keys(configFile).filter((key) => !VALID_OPTIONS.includes(key)).sort().map((key) => italic(key)).join(", ");
|
|
3945
|
+
log2.debug(`Hook Keys: ${logKeys}`);
|
|
5326
3946
|
for (const hook of VALID_GIT_HOOKS) {
|
|
5327
3947
|
if (Object.prototype.hasOwnProperty.call(configFile, hook)) {
|
|
5328
3948
|
if (!configFile[hook])
|
|
@@ -5333,48 +3953,85 @@ function setHooksFromConfig(projectRootPath = process14.cwd(), options) {
|
|
|
5333
3953
|
}
|
|
5334
3954
|
}
|
|
5335
3955
|
}
|
|
5336
|
-
async function getStagedFiles(projectRoot =
|
|
3956
|
+
async function getStagedFiles(projectRoot = process11.cwd()) {
|
|
5337
3957
|
try {
|
|
5338
|
-
const { stdout } = await execAsync("git diff --
|
|
5339
|
-
|
|
3958
|
+
const { stdout } = await execAsync("git diff --cached --name-only --diff-filter=ACMR", { cwd: projectRoot });
|
|
3959
|
+
const files = stdout.trim().split(`
|
|
5340
3960
|
`).filter(Boolean);
|
|
3961
|
+
if (config4.verbose && files.length > 0) {
|
|
3962
|
+
console.info("[INFO] Staged files found:", files);
|
|
3963
|
+
}
|
|
3964
|
+
return files;
|
|
5341
3965
|
} catch (error) {
|
|
5342
3966
|
console.error("[ERROR] Failed to get staged files:", error);
|
|
5343
3967
|
return [];
|
|
5344
3968
|
}
|
|
5345
3969
|
}
|
|
3970
|
+
function expandBracePattern(pattern) {
|
|
3971
|
+
const braceMatch = pattern.match(/{([^}]+)}/g);
|
|
3972
|
+
if (!braceMatch)
|
|
3973
|
+
return [pattern];
|
|
3974
|
+
const results = [pattern];
|
|
3975
|
+
braceMatch.forEach((brace) => {
|
|
3976
|
+
const options = brace.slice(1, -1).split(",");
|
|
3977
|
+
const newResults = [];
|
|
3978
|
+
results.forEach((result) => {
|
|
3979
|
+
options.forEach((option) => {
|
|
3980
|
+
newResults.push(result.replace(brace, option.trim()));
|
|
3981
|
+
});
|
|
3982
|
+
});
|
|
3983
|
+
results.length = 0;
|
|
3984
|
+
results.push(...newResults);
|
|
3985
|
+
});
|
|
3986
|
+
return results;
|
|
3987
|
+
}
|
|
5346
3988
|
function matchesGlob(file, pattern) {
|
|
5347
|
-
if (pattern.
|
|
5348
|
-
|
|
5349
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
5350
|
-
return regex.test(file);
|
|
3989
|
+
if (pattern.startsWith("!")) {
|
|
3990
|
+
return !matchesGlob(file, pattern.slice(1));
|
|
5351
3991
|
}
|
|
5352
|
-
|
|
3992
|
+
const regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "(?:.*?)").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]");
|
|
3993
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
3994
|
+
return regex.test(file);
|
|
5353
3995
|
}
|
|
5354
3996
|
function filterFilesByPattern(files, pattern) {
|
|
5355
|
-
|
|
3997
|
+
const expandedPatterns = expandBracePattern(pattern);
|
|
3998
|
+
const includePatterns = expandedPatterns.filter((p) => !p.startsWith("!"));
|
|
3999
|
+
const excludePatterns = expandedPatterns.filter((p) => p.startsWith("!"));
|
|
4000
|
+
return files.filter((file) => {
|
|
4001
|
+
const isIncluded = includePatterns.some((p) => matchesGlob(file, p));
|
|
4002
|
+
const isExcluded = excludePatterns.some((p) => matchesGlob(file, p.slice(1)));
|
|
4003
|
+
return isIncluded && !isExcluded;
|
|
4004
|
+
});
|
|
5356
4005
|
}
|
|
5357
|
-
async function runCommandOnStagedFiles(command, files, projectRoot =
|
|
4006
|
+
async function runCommandOnStagedFiles(command, files, projectRoot = process11.cwd(), verbose = false) {
|
|
5358
4007
|
if (files.length === 0) {
|
|
5359
4008
|
if (verbose)
|
|
5360
4009
|
console.info("[INFO] No matching files for pattern");
|
|
5361
4010
|
return true;
|
|
5362
4011
|
}
|
|
5363
4012
|
const commands = Array.isArray(command) ? command : [command];
|
|
4013
|
+
const fileList = files.join(" ");
|
|
5364
4014
|
for (const cmd of commands) {
|
|
5365
4015
|
try {
|
|
5366
|
-
const fullCommand = `${cmd} ${
|
|
5367
|
-
if (verbose)
|
|
5368
|
-
console.info(`[INFO] Running: ${fullCommand}`);
|
|
5369
|
-
const { stdout, stderr } = await execAsync(fullCommand, { cwd: projectRoot });
|
|
4016
|
+
const fullCommand = `${cmd} ${fileList}`;
|
|
5370
4017
|
if (verbose) {
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
4018
|
+
console.info("[INFO] Running command:", cmd);
|
|
4019
|
+
console.info("[INFO] On files:", files);
|
|
4020
|
+
}
|
|
4021
|
+
const { stdout, stderr } = await execAsync(fullCommand, { cwd: projectRoot });
|
|
4022
|
+
if (stdout && (verbose || stdout.includes("error") || stdout.includes("warning"))) {
|
|
4023
|
+
console.info(stdout);
|
|
4024
|
+
}
|
|
4025
|
+
if (stderr) {
|
|
4026
|
+
console.error("[ERROR] Command output:", stderr);
|
|
4027
|
+
return false;
|
|
5375
4028
|
}
|
|
5376
4029
|
} catch (error) {
|
|
5377
|
-
|
|
4030
|
+
if (error.stdout)
|
|
4031
|
+
console.info(error.stdout);
|
|
4032
|
+
if (error.stderr)
|
|
4033
|
+
console.error("[ERROR] Command stderr:", error.stderr);
|
|
4034
|
+
console.error(`[ERROR] Command failed: ${cmd}`);
|
|
5378
4035
|
return false;
|
|
5379
4036
|
}
|
|
5380
4037
|
}
|
|
@@ -5398,7 +4055,7 @@ async function processStagedLint(stagedLintConfig, projectRoot, verbose = false)
|
|
|
5398
4055
|
}
|
|
5399
4056
|
return success;
|
|
5400
4057
|
}
|
|
5401
|
-
function _setHook(hook, commandOrConfig, projectRoot =
|
|
4058
|
+
function _setHook(hook, commandOrConfig, projectRoot = process11.cwd()) {
|
|
5402
4059
|
const gitRoot = getGitProjectRoot(projectRoot);
|
|
5403
4060
|
if (!gitRoot) {
|
|
5404
4061
|
console.info("[INFO] No `.git` root folder found, skipping");
|
|
@@ -5408,7 +4065,7 @@ function _setHook(hook, commandOrConfig, projectRoot = process14.cwd()) {
|
|
|
5408
4065
|
if (typeof commandOrConfig === "string") {
|
|
5409
4066
|
hookCommand = PREPEND_SCRIPT + commandOrConfig;
|
|
5410
4067
|
} else if (commandOrConfig.stagedLint || commandOrConfig["staged-lint"]) {
|
|
5411
|
-
hookCommand = PREPEND_SCRIPT + `git-hooks run-staged-lint ${hook}`;
|
|
4068
|
+
hookCommand = PREPEND_SCRIPT + `bun git-hooks run-staged-lint ${hook}`;
|
|
5412
4069
|
} else {
|
|
5413
4070
|
console.error(`[ERROR] Invalid command or config for hook ${hook}`);
|
|
5414
4071
|
return;
|
|
@@ -5419,26 +4076,26 @@ function _setHook(hook, commandOrConfig, projectRoot = process14.cwd()) {
|
|
|
5419
4076
|
fs.mkdirSync(hookDirectory, { recursive: true });
|
|
5420
4077
|
}
|
|
5421
4078
|
const addOrModify = fs.existsSync(hookPath) ? "Modify" : "Add";
|
|
5422
|
-
|
|
4079
|
+
log2.debug(`${addOrModify} ${italic(hook)} hook`);
|
|
5423
4080
|
fs.writeFileSync(hookPath, hookCommand, { mode: 493 });
|
|
5424
4081
|
}
|
|
5425
|
-
function removeHooks(projectRoot =
|
|
4082
|
+
function removeHooks(projectRoot = process11.cwd(), verbose = false) {
|
|
5426
4083
|
for (const configEntry of VALID_GIT_HOOKS)
|
|
5427
4084
|
_removeHook(configEntry, projectRoot, verbose);
|
|
5428
4085
|
}
|
|
5429
|
-
function _removeHook(hook, projectRoot =
|
|
4086
|
+
function _removeHook(hook, projectRoot = process11.cwd(), verbose = false) {
|
|
5430
4087
|
const gitRoot = getGitProjectRoot(projectRoot);
|
|
5431
4088
|
const hookPath = path.normalize(`${gitRoot}/hooks/${hook}`);
|
|
5432
4089
|
if (fs.existsSync(hookPath)) {
|
|
5433
|
-
|
|
4090
|
+
log2.debug(`Hook ${hook} is not set, removing!`);
|
|
5434
4091
|
fs.unlinkSync(hookPath);
|
|
5435
4092
|
}
|
|
5436
4093
|
if (verbose)
|
|
5437
|
-
|
|
4094
|
+
log2.success(`Successfully removed the ${hook} hook`);
|
|
5438
4095
|
}
|
|
5439
4096
|
async function runStagedLint(hook) {
|
|
5440
|
-
const projectRoot =
|
|
5441
|
-
const configFile =
|
|
4097
|
+
const projectRoot = process11.cwd();
|
|
4098
|
+
const configFile = config4;
|
|
5442
4099
|
if (!configFile) {
|
|
5443
4100
|
console.error(`[ERROR] No configuration found`);
|
|
5444
4101
|
return false;
|
|
@@ -5458,10 +4115,10 @@ async function runStagedLint(hook) {
|
|
|
5458
4115
|
console.error(`[ERROR] No staged lint configuration found for hook ${hook}`);
|
|
5459
4116
|
return false;
|
|
5460
4117
|
}
|
|
5461
|
-
function _validateStagedLintConfig(
|
|
4118
|
+
function _validateStagedLintConfig(config5) {
|
|
5462
4119
|
for (const hook of VALID_GIT_HOOKS) {
|
|
5463
|
-
if (hook !== "pre-commit" &&
|
|
5464
|
-
const hookConfig =
|
|
4120
|
+
if (hook !== "pre-commit" && config5[hook] && typeof config5[hook] === "object") {
|
|
4121
|
+
const hookConfig = config5[hook];
|
|
5465
4122
|
if (hookConfig["stagedLint"] || hookConfig["staged-lint"]) {
|
|
5466
4123
|
throw new Error(`staged-lint is only allowed in pre-commit hook. Found in ${hook} hook.`);
|
|
5467
4124
|
}
|
|
@@ -5471,60 +4128,60 @@ function _validateStagedLintConfig(config4) {
|
|
|
5471
4128
|
|
|
5472
4129
|
// bin/cli.ts
|
|
5473
4130
|
var cli = new CAC("git-hooks");
|
|
5474
|
-
var
|
|
4131
|
+
var log3 = new Logger("git-hooks", {
|
|
5475
4132
|
showTags: true
|
|
5476
4133
|
});
|
|
5477
|
-
var { SKIP_INSTALL_GIT_HOOKS } =
|
|
4134
|
+
var { SKIP_INSTALL_GIT_HOOKS } = process12.env;
|
|
5478
4135
|
if (["1", "true"].includes(SKIP_INSTALL_GIT_HOOKS || "")) {
|
|
5479
|
-
|
|
5480
|
-
|
|
4136
|
+
log3.info(`SKIP_INSTALL_GIT_HOOKS is set to "${SKIP_INSTALL_GIT_HOOKS}", skipping installing hooks.`);
|
|
4137
|
+
process12.exit(0);
|
|
5481
4138
|
}
|
|
5482
4139
|
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
4140
|
try {
|
|
5484
4141
|
if (options?.verbose) {
|
|
5485
|
-
|
|
5486
|
-
|
|
4142
|
+
log3.debug(`Config path: ${configPath || "using default"}`);
|
|
4143
|
+
log3.debug(`Working directory: ${process12.cwd()}`);
|
|
5487
4144
|
}
|
|
5488
4145
|
if (configPath) {
|
|
5489
|
-
const
|
|
5490
|
-
setHooksFromConfig(
|
|
4146
|
+
const config5 = await import(configPath);
|
|
4147
|
+
setHooksFromConfig(process12.cwd(), { configFile: config5 });
|
|
5491
4148
|
} else {
|
|
5492
|
-
setHooksFromConfig(
|
|
4149
|
+
setHooksFromConfig(process12.cwd());
|
|
5493
4150
|
}
|
|
5494
|
-
|
|
4151
|
+
log3.success("Successfully set all git hooks");
|
|
5495
4152
|
} catch (err) {
|
|
5496
|
-
|
|
5497
|
-
|
|
4153
|
+
log3.error(err);
|
|
4154
|
+
process12.exit(1);
|
|
5498
4155
|
}
|
|
5499
4156
|
});
|
|
5500
4157
|
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
4158
|
try {
|
|
5502
4159
|
if (options?.verbose) {
|
|
5503
|
-
|
|
4160
|
+
log3.debug(`Removing hooks from: ${process12.cwd()}`);
|
|
5504
4161
|
}
|
|
5505
|
-
removeHooks(
|
|
5506
|
-
|
|
4162
|
+
removeHooks(process12.cwd(), options?.verbose);
|
|
4163
|
+
log3.success("Successfully removed all git hooks");
|
|
5507
4164
|
} catch (err) {
|
|
5508
|
-
|
|
5509
|
-
|
|
4165
|
+
log3.error("Was not able to remove git hooks. Error:", err);
|
|
4166
|
+
process12.exit(1);
|
|
5510
4167
|
}
|
|
5511
4168
|
});
|
|
5512
4169
|
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
4170
|
try {
|
|
5514
4171
|
if (options?.verbose) {
|
|
5515
|
-
|
|
5516
|
-
|
|
4172
|
+
log3.debug(`Running staged lint for hook: ${hook}`);
|
|
4173
|
+
log3.debug(`Working directory: ${process12.cwd()}`);
|
|
5517
4174
|
}
|
|
5518
4175
|
const success = await runStagedLint(hook);
|
|
5519
4176
|
if (success) {
|
|
5520
|
-
|
|
4177
|
+
log3.success("Staged lint completed successfully");
|
|
5521
4178
|
} else {
|
|
5522
|
-
|
|
5523
|
-
|
|
4179
|
+
log3.error("Staged lint failed");
|
|
4180
|
+
process12.exit(1);
|
|
5524
4181
|
}
|
|
5525
4182
|
} catch (err) {
|
|
5526
|
-
|
|
5527
|
-
|
|
4183
|
+
log3.error("Was not able to run staged lint. Error:", err);
|
|
4184
|
+
process12.exit(1);
|
|
5528
4185
|
}
|
|
5529
4186
|
});
|
|
5530
4187
|
cli.version(version);
|