@stacksjs/bun-router 0.0.10 → 0.0.11

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.
@@ -4254,45 +4254,46 @@ class JsonBody {
4254
4254
 
4255
4255
  // ../../node_modules/ts-rate-limiter/dist/index.js
4256
4256
  import { existsSync as existsSync7, statSync as statSync2 } from "fs";
4257
- import { existsSync as existsSync8, mkdirSync as mkdirSync3, readdirSync as readdirSync3, writeFileSync as writeFileSync5 } from "fs";
4258
- import { homedir as homedir2 } from "os";
4259
- import { dirname as dirname3, resolve as resolve7 } from "path";
4260
- import process12 from "process";
4261
4257
  import { join as join3, relative as relative2, resolve as resolve4 } from "path";
4262
- import process72 from "process";
4263
- import { existsSync as existsSync32, mkdirSync as mkdirSync2, readdirSync as readdirSync22, writeFileSync as writeFileSync3 } from "fs";
4264
- import { homedir as homedir3 } from "os";
4265
- import { dirname as dirname2, resolve as resolve32 } from "path";
4266
- import process62 from "process";
4267
- import { join as join4, relative as relative3, resolve as resolve22 } from "path";
4268
- import process22 from "process";
4269
- import { existsSync as existsSync22, mkdirSync as mkdirSync4, readdirSync as readdirSync4, writeFileSync as writeFileSync4 } from "fs";
4270
- import { dirname as dirname4, resolve as resolve8 } from "path";
4271
4258
  import process9 from "process";
4272
4259
  import { Buffer as Buffer2 } from "buffer";
4273
4260
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes3 } from "crypto";
4274
- import { closeSync as closeSync2, createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync222, fsyncSync as fsyncSync2, openSync as openSync2, writeFileSync as writeFileSync22 } from "fs";
4261
+ import { closeSync as closeSync2, createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync22, fsyncSync as fsyncSync2, openSync as openSync2, writeFileSync as writeFileSync3 } from "fs";
4275
4262
  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";
4276
- import { join as join22 } from "path";
4277
- import process52 from "process";
4263
+ import { isAbsolute as isAbsolute2, join as join22, resolve as resolve22 } from "path";
4264
+ import process42 from "process";
4278
4265
  import { pipeline as pipeline2 } from "stream/promises";
4279
4266
  import { createGzip as createGzip2 } from "zlib";
4280
- import process42 from "process";
4281
4267
  import process32 from "process";
4282
- import { Buffer as Buffer22 } from "buffer";
4283
- import { createCipheriv as createCipheriv22, createDecipheriv as createDecipheriv22, randomBytes as randomBytes22 } from "crypto";
4284
- import { closeSync as closeSync22, createReadStream as createReadStream22, createWriteStream as createWriteStream22, existsSync as existsSync42, fsyncSync as fsyncSync22, openSync as openSync22, writeFileSync as writeFileSync42 } from "fs";
4285
- import { access as access22, constants as constants22, mkdir as mkdir22, readdir as readdir22, rename as rename22, stat as stat22, unlink as unlink22, writeFile as writeFile22 } from "fs/promises";
4286
- import { isAbsolute as isAbsolute2, join as join5, resolve as resolve62 } from "path";
4287
- import process11 from "process";
4288
- import { pipeline as pipeline22 } from "stream/promises";
4289
- import { createGzip as createGzip22 } from "zlib";
4290
- import process10 from "process";
4291
- import process92 from "process";
4268
+ import process22 from "process";
4269
+ import process52 from "process";
4270
+ import { existsSync as existsSync32 } from "fs";
4271
+ import { resolve as resolve32 } from "path";
4272
+ import { existsSync as existsSync42 } from "fs";
4273
+ import { existsSync as existsSync52, mkdirSync as mkdirSync2, readdirSync as readdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync22 } from "fs";
4274
+ import { homedir as homedir2 } from "os";
4275
+ import { dirname as dirname2, resolve as resolve52 } from "path";
4276
+ import process72 from "process";
4277
+ import { existsSync as existsSync62, readdirSync as readdirSync22 } from "fs";
4278
+ import { extname as extname2, resolve as resolve62 } from "path";
4292
4279
  import process82 from "process";
4293
- import { existsSync as existsSync52 } from "fs";
4294
- import { resolve as resolve52 } from "path";
4295
- import { existsSync as existsSync72 } from "fs";
4280
+ var __defProp3 = Object.defineProperty;
4281
+ var __returnValue3 = (v) => v;
4282
+ function __exportSetter3(name, newValue) {
4283
+ this[name] = __returnValue3.bind(null, newValue);
4284
+ }
4285
+ var __export3 = (target, all) => {
4286
+ for (var name in all)
4287
+ __defProp3(target, name, {
4288
+ get: all[name],
4289
+ enumerable: true,
4290
+ configurable: true,
4291
+ set: __exportSetter3.bind(all, name)
4292
+ });
4293
+ };
4294
+ var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
4295
+ var __require22 = import.meta.require;
4296
+
4296
4297
  class ConfigCache2 {
4297
4298
  cache = new Map;
4298
4299
  totalHits = 0;
@@ -4531,254 +4532,62 @@ class PerformanceMonitor2 {
4531
4532
  return this.metrics.filter((m) => m.duration > threshold);
4532
4533
  }
4533
4534
  }
4534
- var globalCache2 = new ConfigCache2;
4535
- var globalPerformanceMonitor2 = new PerformanceMonitor2;
4536
- function deepMerge2(target, source) {
4537
- 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) {
4538
- return source;
4539
- }
4540
- 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) {
4541
- return { a: null, b: 2, c: undefined };
4542
- }
4543
- if (source === null || source === undefined) {
4544
- return target;
4545
- }
4546
- if (Array.isArray(source) && !Array.isArray(target)) {
4547
- return source;
4548
- }
4549
- if (Array.isArray(source) && Array.isArray(target)) {
4550
- if (isObject2(target) && "arr" in target && Array.isArray(target.arr) && isObject2(source) && "arr" in source && Array.isArray(source.arr)) {
4551
- return source;
4552
- }
4553
- if (source.length > 0 && target.length > 0 && isObject2(source[0]) && isObject2(target[0])) {
4554
- const result = [...source];
4555
- for (const targetItem of target) {
4556
- if (isObject2(targetItem) && "name" in targetItem) {
4557
- const existingItem = result.find((item) => isObject2(item) && ("name" in item) && item.name === targetItem.name);
4558
- if (!existingItem) {
4559
- result.push(targetItem);
4560
- }
4561
- } else if (isObject2(targetItem) && "path" in targetItem) {
4562
- const existingItem = result.find((item) => isObject2(item) && ("path" in item) && item.path === targetItem.path);
4563
- if (!existingItem) {
4564
- result.push(targetItem);
4565
- }
4566
- } else if (!result.some((item) => deepEquals2(item, targetItem))) {
4567
- result.push(targetItem);
4568
- }
4569
- }
4570
- return result;
4571
- }
4572
- if (source.every((item) => typeof item === "string") && target.every((item) => typeof item === "string")) {
4573
- const result = [...source];
4574
- for (const item of target) {
4575
- if (!result.includes(item)) {
4576
- result.push(item);
4577
- }
4578
- }
4579
- return result;
4580
- }
4581
- return source;
4582
- }
4583
- if (!isObject2(source) || !isObject2(target)) {
4584
- return source;
4585
- }
4586
- const merged = { ...target };
4587
- for (const key in source) {
4588
- if (Object.prototype.hasOwnProperty.call(source, key)) {
4589
- const sourceValue = source[key];
4590
- if (sourceValue === null || sourceValue === undefined) {
4591
- continue;
4592
- } else if (isObject2(sourceValue) && isObject2(merged[key])) {
4593
- merged[key] = deepMerge2(merged[key], sourceValue);
4594
- } else if (Array.isArray(sourceValue) && Array.isArray(merged[key])) {
4595
- if (sourceValue.length > 0 && merged[key].length > 0 && isObject2(sourceValue[0]) && isObject2(merged[key][0])) {
4596
- const result = [...sourceValue];
4597
- for (const targetItem of merged[key]) {
4598
- if (isObject2(targetItem) && "name" in targetItem) {
4599
- const existingItem = result.find((item) => isObject2(item) && ("name" in item) && item.name === targetItem.name);
4600
- if (!existingItem) {
4601
- result.push(targetItem);
4602
- }
4603
- } else if (isObject2(targetItem) && "path" in targetItem) {
4604
- const existingItem = result.find((item) => isObject2(item) && ("path" in item) && item.path === targetItem.path);
4605
- if (!existingItem) {
4606
- result.push(targetItem);
4607
- }
4608
- } else if (!result.some((item) => deepEquals2(item, targetItem))) {
4609
- result.push(targetItem);
4610
- }
4611
- }
4612
- merged[key] = result;
4613
- } else if (sourceValue.every((item) => typeof item === "string") && merged[key].every((item) => typeof item === "string")) {
4614
- const result = [...sourceValue];
4615
- for (const item of merged[key]) {
4616
- if (!result.includes(item)) {
4617
- result.push(item);
4618
- }
4619
- }
4620
- merged[key] = result;
4621
- } else {
4622
- merged[key] = sourceValue;
4623
- }
4624
- } else {
4625
- merged[key] = sourceValue;
4626
- }
4627
- }
4628
- }
4629
- return merged;
4630
- }
4631
- function deepEquals2(a, b) {
4632
- if (a === b)
4633
- return true;
4634
- if (Array.isArray(a) && Array.isArray(b)) {
4635
- if (a.length !== b.length)
4636
- return false;
4637
- for (let i = 0;i < a.length; i++) {
4638
- if (!deepEquals2(a[i], b[i]))
4639
- return false;
4640
- }
4641
- return true;
4642
- }
4643
- if (isObject2(a) && isObject2(b)) {
4644
- const keysA = Object.keys(a);
4645
- const keysB = Object.keys(b);
4646
- if (keysA.length !== keysB.length)
4647
- return false;
4648
- for (const key of keysA) {
4649
- if (!Object.prototype.hasOwnProperty.call(b, key))
4650
- return false;
4651
- if (!deepEquals2(a[key], b[key]))
4652
- return false;
4653
- }
4654
- return true;
4655
- }
4656
- return false;
4657
- }
4658
- function isObject2(item) {
4659
- return Boolean(item && typeof item === "object" && !Array.isArray(item));
4535
+ function createKey2(configName, options = {}) {
4536
+ const sortedKeys = Object.keys(options).sort();
4537
+ const optionsStr = sortedKeys.map((key) => `${key}:${options[key]}`).join("|");
4538
+ return optionsStr ? `${configName}:${optionsStr}` : configName;
4660
4539
  }
4661
- async function tryLoadConfig2(configPath, defaultConfig3) {
4662
- if (!existsSync22(configPath))
4663
- return null;
4540
+ function isEquivalent2(a, b) {
4664
4541
  try {
4665
- const importedConfig = await import(configPath);
4666
- const loadedConfig = importedConfig.default || importedConfig;
4667
- if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig))
4668
- return null;
4669
- try {
4670
- return deepMerge2(defaultConfig3, loadedConfig);
4671
- } catch {
4672
- return null;
4673
- }
4542
+ return JSON.stringify(a) === JSON.stringify(b);
4674
4543
  } catch {
4675
- return null;
4544
+ return a === b;
4676
4545
  }
4677
4546
  }
4678
- async function loadConfig2({
4679
- name = "",
4680
- cwd,
4681
- defaultConfig: defaultConfig3
4682
- }) {
4683
- const baseDir = cwd || process9.cwd();
4684
- const extensions = [".ts", ".js", ".mjs", ".cjs", ".json"];
4685
- const configPaths = [
4686
- `${name}.config`,
4687
- `.${name}.config`,
4688
- name,
4689
- `.${name}`
4690
- ];
4691
- for (const configPath of configPaths) {
4692
- for (const ext of extensions) {
4693
- const fullPath = resolve8(baseDir, `${configPath}${ext}`);
4694
- const config22 = await tryLoadConfig2(fullPath, defaultConfig3);
4695
- if (config22 !== null) {
4696
- return config22;
4697
- }
4698
- }
4699
- }
4700
- try {
4701
- const pkgPath = resolve8(baseDir, "package.json");
4702
- if (existsSync22(pkgPath)) {
4703
- const pkg = await import(pkgPath);
4704
- const pkgConfig = pkg[name];
4705
- if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
4706
- try {
4707
- return deepMerge2(defaultConfig3, pkgConfig);
4708
- } catch {}
4709
- }
4710
- }
4711
- } catch {}
4712
- return defaultConfig3;
4547
+ function estimateMemoryUsage2(cache) {
4548
+ const stats = cache.getStats();
4549
+ return stats.size * 2;
4713
4550
  }
4714
- var defaultConfigDir2 = resolve8(process9.cwd(), "config");
4715
- var defaultGeneratedDir2 = resolve8(process9.cwd(), "src/generated");
4551
+ var globalCache2;
4552
+ var globalPerformanceMonitor2;
4553
+ var CacheUtils2;
4554
+ var init_cache2 = __esm2(() => {
4555
+ globalCache2 = new ConfigCache2;
4556
+ globalPerformanceMonitor2 = new PerformanceMonitor2;
4557
+ CacheUtils2 = {
4558
+ createKey: createKey2,
4559
+ isEquivalent: isEquivalent2,
4560
+ estimateMemoryUsage: estimateMemoryUsage2
4561
+ };
4562
+ });
4716
4563
  function getProjectRoot2(filePath, options = {}) {
4717
- let path = process22.cwd();
4564
+ let path = process9.cwd();
4718
4565
  while (path.includes("storage"))
4719
- path = resolve22(path, "..");
4720
- const finalPath = resolve22(path, filePath || "");
4566
+ path = resolve4(path, "..");
4567
+ const finalPath = resolve4(path, filePath || "");
4721
4568
  if (options?.relative)
4722
- return relative3(process22.cwd(), finalPath);
4569
+ return relative2(process9.cwd(), finalPath);
4723
4570
  return finalPath;
4724
4571
  }
4725
- var defaultLogDirectory2 = process22.env.CLARITY_LOG_DIR || join4(getProjectRoot2(), "logs");
4726
- var defaultConfig3 = {
4727
- level: "info",
4728
- defaultName: "clarity",
4729
- timestamp: true,
4730
- colors: true,
4731
- format: "text",
4732
- maxLogSize: 10485760,
4733
- logDatePattern: "YYYY-MM-DD",
4734
- logDirectory: defaultLogDirectory2,
4735
- rotation: {
4736
- frequency: "daily",
4737
- maxSize: 10485760,
4738
- maxFiles: 5,
4739
- compress: false,
4740
- rotateHour: 0,
4741
- rotateMinute: 0,
4742
- rotateDayOfWeek: 0,
4743
- rotateDayOfMonth: 1,
4744
- encrypt: false
4745
- },
4746
- verbose: false
4747
- };
4748
- async function loadConfig22() {
4749
- try {
4750
- const loadedConfig = await loadConfig2({
4751
- name: "clarity",
4752
- defaultConfig: defaultConfig3,
4753
- cwd: process22.cwd(),
4754
- endpoint: "",
4755
- headers: {}
4756
- });
4757
- return { ...defaultConfig3, ...loadedConfig };
4758
- } catch {
4759
- return defaultConfig3;
4760
- }
4761
- }
4762
- var config5 = await loadConfig22();
4763
4572
  function isBrowserProcess2() {
4764
- if (process32.env.NODE_ENV === "test" || process32.env.BUN_ENV === "test") {
4573
+ if (process22.env.NODE_ENV === "test" || process22.env.BUN_ENV === "test") {
4765
4574
  return false;
4766
4575
  }
4767
4576
  return typeof window !== "undefined";
4768
4577
  }
4769
4578
  async function isServerProcess2() {
4770
- if (process32.env.NODE_ENV === "test" || process32.env.BUN_ENV === "test") {
4579
+ if (process22.env.NODE_ENV === "test" || process22.env.BUN_ENV === "test") {
4771
4580
  return true;
4772
4581
  }
4773
4582
  if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
4774
4583
  return true;
4775
4584
  }
4776
- if (typeof process32 !== "undefined") {
4777
- const type = process32.type;
4585
+ if (typeof process22 !== "undefined") {
4586
+ const type = process22.type;
4778
4587
  if (type === "renderer" || type === "worker") {
4779
4588
  return false;
4780
4589
  }
4781
- return !!(process32.versions && (process32.versions.node || process32.versions.bun));
4590
+ return !!(process22.versions && (process22.versions.node || process22.versions.bun));
4782
4591
  }
4783
4592
  return false;
4784
4593
  }
@@ -4799,17 +4608,17 @@ class JsonFormatter2 {
4799
4608
  if (isServer) {
4800
4609
  const { hostname } = await import("os");
4801
4610
  return {
4802
- pid: process42.pid,
4611
+ pid: process32.pid,
4803
4612
  hostname: hostname(),
4804
- environment: process42.env.NODE_ENV || "development",
4805
- platform: process42.platform,
4806
- version: process42.version
4613
+ environment: process32.env.NODE_ENV || "development",
4614
+ platform: process32.platform,
4615
+ version: process32.version
4807
4616
  };
4808
4617
  }
4809
4618
  return {
4810
4619
  userAgent: navigator.userAgent,
4811
4620
  hostname: window.location.hostname || "browser",
4812
- environment: process42.env.NODE_ENV || process42.env.BUN_ENV || "development",
4621
+ environment: process32.env.NODE_ENV || process32.env.BUN_ENV || "development",
4813
4622
  viewport: {
4814
4623
  width: window.innerWidth,
4815
4624
  height: window.innerHeight
@@ -4818,64 +4627,12 @@ class JsonFormatter2 {
4818
4627
  };
4819
4628
  }
4820
4629
  }
4821
- var terminalStyles2 = {
4822
- red: (text) => `\x1B[31m${text}\x1B[0m`,
4823
- green: (text) => `\x1B[32m${text}\x1B[0m`,
4824
- yellow: (text) => `\x1B[33m${text}\x1B[0m`,
4825
- blue: (text) => `\x1B[34m${text}\x1B[0m`,
4826
- magenta: (text) => `\x1B[35m${text}\x1B[0m`,
4827
- cyan: (text) => `\x1B[36m${text}\x1B[0m`,
4828
- white: (text) => `\x1B[37m${text}\x1B[0m`,
4829
- gray: (text) => `\x1B[90m${text}\x1B[0m`,
4830
- bgRed: (text) => `\x1B[41m${text}\x1B[0m`,
4831
- bgYellow: (text) => `\x1B[43m${text}\x1B[0m`,
4832
- bold: (text) => `\x1B[1m${text}\x1B[0m`,
4833
- dim: (text) => `\x1B[2m${text}\x1B[0m`,
4834
- italic: (text) => `\x1B[3m${text}\x1B[0m`,
4835
- underline: (text) => `\x1B[4m${text}\x1B[0m`,
4836
- reset: "\x1B[0m"
4837
- };
4838
- var styles2 = terminalStyles2;
4839
- var red2 = terminalStyles2.red;
4840
- var green2 = terminalStyles2.green;
4841
- var yellow2 = terminalStyles2.yellow;
4842
- var blue2 = terminalStyles2.blue;
4843
- var magenta2 = terminalStyles2.magenta;
4844
- var cyan2 = terminalStyles2.cyan;
4845
- var white2 = terminalStyles2.white;
4846
- var gray2 = terminalStyles2.gray;
4847
- var bgRed2 = terminalStyles2.bgRed;
4848
- var bgYellow2 = terminalStyles2.bgYellow;
4849
- var bold2 = terminalStyles2.bold;
4850
- var dim2 = terminalStyles2.dim;
4851
- var italic2 = terminalStyles2.italic;
4852
- var underline2 = terminalStyles2.underline;
4853
- var reset2 = terminalStyles2.reset;
4854
- var defaultFingersCrossedConfig2 = {
4855
- activationLevel: "error",
4856
- bufferSize: 50,
4857
- flushOnDeactivation: true,
4858
- stopBuffering: false
4859
- };
4860
- var levelIcons2 = {
4861
- debug: "\uD83D\uDD0D",
4862
- info: blue2("\u2139"),
4863
- success: green2("\u2713"),
4864
- warning: bgYellow2(white2(bold2(" WARN "))),
4865
- error: bgRed2(white2(bold2(" ERROR ")))
4866
- };
4867
4630
 
4868
4631
  class Logger2 {
4869
4632
  name;
4870
4633
  fileLocks = new Map;
4871
4634
  currentKeyId = null;
4872
4635
  keys = new Map;
4873
- config;
4874
- options;
4875
- formatter;
4876
- timers = new Set;
4877
- subLoggers = new Set;
4878
- fingersCrossedBuffer = [];
4879
4636
  fingersCrossedConfig;
4880
4637
  fingersCrossedActive = false;
4881
4638
  currentLogFile;
@@ -4890,6 +4647,12 @@ class Logger2 {
4890
4647
  tagFormat;
4891
4648
  timestampPosition;
4892
4649
  environment;
4650
+ config;
4651
+ options;
4652
+ formatter;
4653
+ timers = new Set;
4654
+ subLoggers = new Set;
4655
+ fingersCrossedBuffer = [];
4893
4656
  ANSI_PATTERN = /\u001B\[.*?m/g;
4894
4657
  activeProgressBar = null;
4895
4658
  constructor(name, options = {}) {
@@ -4901,7 +4664,7 @@ class Logger2 {
4901
4664
  this.fancy = options.fancy ?? true;
4902
4665
  this.tagFormat = options.tagFormat ?? { prefix: "[", suffix: "]" };
4903
4666
  this.timestampPosition = options.timestampPosition ?? "right";
4904
- this.environment = options.environment ?? process52.env.APP_ENV ?? "local";
4667
+ this.environment = options.environment ?? process42.env.APP_ENV ?? "local";
4905
4668
  this.fingersCrossedConfig = this.initializeFingersCrossedConfig(options);
4906
4669
  const configOptions = { ...options };
4907
4670
  const hasTimestamp = options.timestamp !== undefined;
@@ -4911,7 +4674,8 @@ class Logger2 {
4911
4674
  this.config = {
4912
4675
  ...this.config,
4913
4676
  ...configOptions,
4914
- timestamp: hasTimestamp || this.config.timestamp
4677
+ timestamp: hasTimestamp || this.config.timestamp,
4678
+ level: this.options.level ?? "info"
4915
4679
  };
4916
4680
  this.currentLogFile = this.generateLogFilename();
4917
4681
  this.encryptionKeys = new Map;
@@ -4928,6 +4692,19 @@ class Logger2 {
4928
4692
  this.setupKeyRotation();
4929
4693
  }
4930
4694
  }
4695
+ shouldActivateFingersCrossed(level) {
4696
+ if (!this.fingersCrossedConfig)
4697
+ return false;
4698
+ const levels = {
4699
+ debug: 0,
4700
+ info: 1,
4701
+ success: 2,
4702
+ warning: 3,
4703
+ error: 4
4704
+ };
4705
+ const activation = this.fingersCrossedConfig.activationLevel ?? "error";
4706
+ return levels[level] >= levels[activation];
4707
+ }
4931
4708
  initializeFingersCrossedConfig(options) {
4932
4709
  if (!options.fingersCrossedEnabled && options.fingersCrossed) {
4933
4710
  return {
@@ -4956,6 +4733,7 @@ class Logger2 {
4956
4733
  fingersCrossed: {},
4957
4734
  enabled: true,
4958
4735
  showTags: false,
4736
+ showIcons: true,
4959
4737
  formatter: undefined
4960
4738
  };
4961
4739
  const mergedOptions = {
@@ -4967,6 +4745,9 @@ class Logger2 {
4967
4745
  }
4968
4746
  return mergedOptions;
4969
4747
  }
4748
+ shouldWriteToFile() {
4749
+ return !isBrowserProcess2() && this.config.writeToFile === true;
4750
+ }
4970
4751
  async writeToFile(data) {
4971
4752
  const cancelled = false;
4972
4753
  const operationPromise = (async () => {
@@ -5000,11 +4781,11 @@ class Logger2 {
5000
4781
  throw new Error("Operation cancelled: Logger was destroyed");
5001
4782
  const dataToWrite = this.validateEncryptionConfig() ? (await this.encrypt(data)).encrypted : Buffer2.from(data);
5002
4783
  try {
5003
- if (!existsSync222(this.currentLogFile)) {
4784
+ if (!existsSync22(this.currentLogFile)) {
5004
4785
  await writeFile2(this.currentLogFile, "", { mode: 420 });
5005
4786
  }
5006
4787
  fd = openSync2(this.currentLogFile, "a", 420);
5007
- writeFileSync22(fd, dataToWrite, { flag: "a" });
4788
+ writeFileSync3(fd, dataToWrite, { flag: "a" });
5008
4789
  fsyncSync2(fd);
5009
4790
  if (fd !== undefined) {
5010
4791
  closeSync2(fd);
@@ -5082,6 +4863,8 @@ class Logger2 {
5082
4863
  setupRotation() {
5083
4864
  if (isBrowserProcess2())
5084
4865
  return;
4866
+ if (!this.shouldWriteToFile())
4867
+ return;
5085
4868
  if (typeof this.config.rotation === "boolean")
5086
4869
  return;
5087
4870
  const config22 = this.config.rotation;
@@ -5166,13 +4949,18 @@ class Logger2 {
5166
4949
  const { key } = this.getCurrentKey();
5167
4950
  const iv = randomBytes3(16);
5168
4951
  const cipher = createCipheriv2("aes-256-gcm", key, iv);
5169
- const encrypted = Buffer2.concat([
5170
- cipher.update(data, "utf8"),
5171
- cipher.final()
5172
- ]);
4952
+ const input = Buffer2.isBuffer(data) ? data : Buffer2.from(data, "utf8");
4953
+ const part1 = cipher.update(input);
4954
+ const part2 = cipher.final();
4955
+ const totalCipherLen = part1.length + part2.length;
5173
4956
  const authTag = cipher.getAuthTag();
4957
+ const out = Buffer2.allocUnsafe(16 + totalCipherLen + 16);
4958
+ iv.copy(out, 0);
4959
+ part1.copy(out, 16);
4960
+ part2.copy(out, 16 + part1.length);
4961
+ authTag.copy(out, 16 + totalCipherLen);
5174
4962
  return {
5175
- encrypted: Buffer2.concat([iv, encrypted, authTag]),
4963
+ encrypted: out,
5176
4964
  iv
5177
4965
  };
5178
4966
  }
@@ -5207,6 +4995,8 @@ class Logger2 {
5207
4995
  async rotateLog() {
5208
4996
  if (isBrowserProcess2())
5209
4997
  return;
4998
+ if (!this.shouldWriteToFile())
4999
+ return;
5210
5000
  const stats = await stat2(this.currentLogFile).catch(() => null);
5211
5001
  if (!stats)
5212
5002
  return;
@@ -5279,42 +5069,19 @@ class Logger2 {
5279
5069
  this.isActivated = true;
5280
5070
  for (const entry of this.logBuffer) {
5281
5071
  const formattedBufferedEntry = await this.formatter.format(entry);
5282
- await this.writeToFile(formattedBufferedEntry);
5072
+ if (this.shouldWriteToFile())
5073
+ await this.writeToFile(formattedBufferedEntry);
5283
5074
  console.log(formattedBufferedEntry);
5284
5075
  }
5285
5076
  if (this.fingersCrossedConfig.stopBuffering)
5286
5077
  this.logBuffer = [];
5287
5078
  }
5288
5079
  if (this.isActivated) {
5289
- await this.writeToFile(formattedEntry);
5080
+ if (this.shouldWriteToFile())
5081
+ await this.writeToFile(formattedEntry);
5290
5082
  console.log(formattedEntry);
5291
- } else {
5292
- if (this.logBuffer.length >= this.fingersCrossedConfig.bufferSize)
5293
- this.logBuffer.shift();
5294
- const entry = {
5295
- timestamp: new Date,
5296
- level,
5297
- message: formattedEntry,
5298
- name: this.name
5299
- };
5300
- this.logBuffer.push(entry);
5301
5083
  }
5302
5084
  }
5303
- shouldActivateFingersCrossed(level) {
5304
- if (!this.fingersCrossedConfig)
5305
- return false;
5306
- return this.getLevelValue(level) >= this.getLevelValue(this.fingersCrossedConfig.activationLevel);
5307
- }
5308
- getLevelValue(level) {
5309
- const levels = {
5310
- debug: 0,
5311
- info: 1,
5312
- success: 2,
5313
- warning: 3,
5314
- error: 4
5315
- };
5316
- return levels[level];
5317
- }
5318
5085
  shouldLog(level) {
5319
5086
  if (!this.enabled)
5320
5087
  return false;
@@ -5336,7 +5103,7 @@ class Logger2 {
5336
5103
  }
5337
5104
  return Promise.resolve();
5338
5105
  }));
5339
- if (existsSync222(this.currentLogFile)) {
5106
+ if (existsSync22(this.currentLogFile)) {
5340
5107
  try {
5341
5108
  const fd = openSync2(this.currentLogFile, "r+");
5342
5109
  fsyncSync2(fd);
@@ -5394,7 +5161,17 @@ class Logger2 {
5394
5161
  return `[${date.toISOString()}]`;
5395
5162
  }
5396
5163
  formatConsoleTimestamp(date) {
5397
- return this.fancy ? styles2.gray(date.toLocaleTimeString()) : date.toLocaleTimeString();
5164
+ return this.shouldStyleConsole() ? styles2.gray(date.toLocaleTimeString()) : date.toLocaleTimeString();
5165
+ }
5166
+ shouldStyleConsole() {
5167
+ if (!this.fancy || isBrowserProcess2())
5168
+ return false;
5169
+ const noColor = typeof process42.env.NO_COLOR !== "undefined";
5170
+ const forceColorDisabled = process42.env.FORCE_COLOR === "0";
5171
+ if (noColor || forceColorDisabled)
5172
+ return false;
5173
+ const hasTTY = typeof process42.stderr !== "undefined" && process42.stderr.isTTY || typeof process42.stdout !== "undefined" && process42.stdout.isTTY;
5174
+ return !!hasTTY;
5398
5175
  }
5399
5176
  formatConsoleMessage(parts) {
5400
5177
  const { timestamp, icon = "", tag = "", message, level, showTimestamp = true } = parts;
@@ -5414,7 +5191,7 @@ class Logger2 {
5414
5191
  components.push(message);
5415
5192
  return components.join(" ");
5416
5193
  }
5417
- const terminalWidth = process52.stdout.columns || 120;
5194
+ const terminalWidth = process42.stdout.columns || 120;
5418
5195
  let mainPart = "";
5419
5196
  if (level === "warning" || level === "error") {
5420
5197
  mainPart = `${icon} ${message}`;
@@ -5464,8 +5241,80 @@ class Logger2 {
5464
5241
  }
5465
5242
  return formattedMessage;
5466
5243
  }
5244
+ formatMarkdown(input) {
5245
+ if (!input)
5246
+ return input;
5247
+ let out = input;
5248
+ out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, text, url) => {
5249
+ const label = styles2.underline(styles2.blue(text));
5250
+ const absFile = this.toAbsoluteFilePath(url);
5251
+ if (absFile && this.shouldStyleConsole() && this.supportsHyperlinks()) {
5252
+ const href = `file://${encodeURI(absFile)}`;
5253
+ const OSC = "\x1B]8;;";
5254
+ const ST = "\x1B\\";
5255
+ return `${OSC}${href}${ST}${label}${OSC}${ST}`;
5256
+ }
5257
+ if (this.shouldStyleConsole() && this.supportsHyperlinks()) {
5258
+ const OSC = "\x1B]8;;";
5259
+ const ST = "\x1B\\";
5260
+ return `${OSC}${url}${ST}${label}${OSC}${ST}`;
5261
+ }
5262
+ return label;
5263
+ });
5264
+ out = out.replace(/`([^`]+)`/g, (_, m) => styles2.bgGray(m));
5265
+ out = out.replace(/\*\*([^*]+)\*\*/g, (_, m) => styles2.bold(m));
5266
+ out = out.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, (_, m) => styles2.italic(m));
5267
+ out = out.replace(/(?<!_)_([^_]+)_(?!_)/g, (_, m) => styles2.italic(m));
5268
+ out = out.replace(/~([^~]+)~/g, (_, m) => styles2.strikethrough(m));
5269
+ return out;
5270
+ }
5271
+ supportsHyperlinks() {
5272
+ if (isBrowserProcess2())
5273
+ return false;
5274
+ const env = process42.env;
5275
+ if (!env)
5276
+ return false;
5277
+ if (env.TERM_PROGRAM === "iTerm.app" || env.TERM_PROGRAM === "vscode" || env.TERM_PROGRAM === "WezTerm")
5278
+ return true;
5279
+ if (env.WT_SESSION)
5280
+ return true;
5281
+ if (env.TERM === "xterm-kitty")
5282
+ return true;
5283
+ const vte = env.VTE_VERSION ? Number.parseInt(env.VTE_VERSION, 10) : 0;
5284
+ if (!Number.isNaN(vte) && vte >= 5000)
5285
+ return true;
5286
+ return false;
5287
+ }
5288
+ toAbsoluteFilePath(input) {
5289
+ try {
5290
+ let p = input;
5291
+ if (p.startsWith("file://")) {
5292
+ p = p.replace(/^file:\/\//, "");
5293
+ }
5294
+ if (p.startsWith("~")) {
5295
+ const home = process42.env.HOME || "";
5296
+ if (home)
5297
+ p = p.replace(/^~(?=$|\/)/, home);
5298
+ }
5299
+ if (isAbsolute2(p) || p.startsWith("./") || p.startsWith("../")) {
5300
+ p = resolve22(p);
5301
+ } else {
5302
+ return null;
5303
+ }
5304
+ return existsSync22(p) ? p : null;
5305
+ } catch {
5306
+ return null;
5307
+ }
5308
+ }
5309
+ buildOutputTexts(input) {
5310
+ const consoleText = this.shouldStyleConsole() ? this.formatMarkdown(input) : input;
5311
+ const fileText = input.replace(this.ANSI_PATTERN, "");
5312
+ return { consoleText, fileText };
5313
+ }
5467
5314
  async log(level, message, ...args) {
5468
- const timestamp = new Date;
5315
+ if (!this.shouldLog(level))
5316
+ return;
5317
+ const timestamp = new Date;
5469
5318
  const consoleTime = this.formatConsoleTimestamp(timestamp);
5470
5319
  const fileTime = this.formatFileTimestamp(timestamp);
5471
5320
  let formattedMessage;
@@ -5476,8 +5325,9 @@ class Logger2 {
5476
5325
  } else {
5477
5326
  formattedMessage = this.formatMessage(message, args);
5478
5327
  }
5479
- if (this.fancy && !isBrowserProcess2()) {
5480
- const icon = levelIcons2[level];
5328
+ const { consoleText: baseConsoleText, fileText } = this.buildOutputTexts(formattedMessage);
5329
+ if (this.shouldStyleConsole()) {
5330
+ const icon = this.options.showIcons === false ? "" : levelIcons2[level];
5481
5331
  const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
5482
5332
  let consoleMessage;
5483
5333
  switch (level) {
@@ -5486,7 +5336,7 @@ class Logger2 {
5486
5336
  timestamp: consoleTime,
5487
5337
  icon,
5488
5338
  tag,
5489
- message: styles2.gray(formattedMessage),
5339
+ message: styles2.gray(baseConsoleText),
5490
5340
  level
5491
5341
  });
5492
5342
  console.error(consoleMessage);
@@ -5496,17 +5346,17 @@ class Logger2 {
5496
5346
  timestamp: consoleTime,
5497
5347
  icon,
5498
5348
  tag,
5499
- message: formattedMessage,
5349
+ message: baseConsoleText,
5500
5350
  level
5501
5351
  });
5502
- console.error(consoleMessage);
5352
+ console.warn(consoleMessage);
5503
5353
  break;
5504
5354
  case "success":
5505
5355
  consoleMessage = this.formatConsoleMessage({
5506
5356
  timestamp: consoleTime,
5507
5357
  icon,
5508
5358
  tag,
5509
- message: styles2.green(formattedMessage),
5359
+ message: styles2.green(baseConsoleText),
5510
5360
  level
5511
5361
  });
5512
5362
  console.error(consoleMessage);
@@ -5516,7 +5366,7 @@ class Logger2 {
5516
5366
  timestamp: consoleTime,
5517
5367
  icon,
5518
5368
  tag,
5519
- message: formattedMessage,
5369
+ message: baseConsoleText,
5520
5370
  level
5521
5371
  });
5522
5372
  console.warn(consoleMessage);
@@ -5526,7 +5376,7 @@ class Logger2 {
5526
5376
  timestamp: consoleTime,
5527
5377
  icon,
5528
5378
  tag,
5529
- message: formattedMessage,
5379
+ message: baseConsoleText,
5530
5380
  level
5531
5381
  });
5532
5382
  console.error(consoleMessage);
@@ -5552,25 +5402,68 @@ class Logger2 {
5552
5402
  console.error(errorStack);
5553
5403
  }
5554
5404
  }
5555
- if (!this.shouldLog(level))
5556
- return;
5557
- let logEntry = `${fileTime} ${this.environment}.${level.toUpperCase()}: ${formattedMessage}
5405
+ let logEntry = `${fileTime} ${this.environment}.${level.toUpperCase()}: ${fileText}
5558
5406
  `;
5559
5407
  if (errorStack) {
5560
5408
  logEntry += `${errorStack}
5561
5409
  `;
5562
5410
  }
5563
5411
  logEntry = logEntry.replace(this.ANSI_PATTERN, "");
5564
- await this.writeToFile(logEntry);
5412
+ if (this.shouldWriteToFile())
5413
+ await this.writeToFile(logEntry);
5414
+ }
5415
+ progress(total, initialMessage = "") {
5416
+ const noop = {
5417
+ update: (_current, _message) => {},
5418
+ finish: (_message) => {},
5419
+ interrupt: (_message, _level) => {}
5420
+ };
5421
+ if (!this.enabled)
5422
+ return noop;
5423
+ const barLength = 30;
5424
+ this.activeProgressBar = {
5425
+ total: Math.max(1, total || 1),
5426
+ current: 0,
5427
+ message: initialMessage || "",
5428
+ barLength,
5429
+ lastRenderedLine: ""
5430
+ };
5431
+ if (this.shouldStyleConsole() && !isBrowserProcess2() && process42.stdout.isTTY) {
5432
+ this.renderProgressBar(this.activeProgressBar);
5433
+ }
5434
+ const update = (current, message) => {
5435
+ if (!this.enabled || !this.activeProgressBar)
5436
+ return;
5437
+ this.activeProgressBar.current = Math.min(Math.max(0, current), this.activeProgressBar.total);
5438
+ if (message !== undefined)
5439
+ this.activeProgressBar.message = message;
5440
+ if (this.shouldStyleConsole() && !isBrowserProcess2() && process42.stdout.isTTY)
5441
+ this.renderProgressBar(this.activeProgressBar);
5442
+ };
5443
+ const finish = (message) => {
5444
+ if (!this.activeProgressBar)
5445
+ return;
5446
+ this.finishProgressBar(this.activeProgressBar, message);
5447
+ };
5448
+ const interrupt = (message, level = "info") => {
5449
+ if (!isBrowserProcess2() && process42.stdout.isTTY)
5450
+ process42.stdout.write(`
5451
+ `);
5452
+ const method = level === "warning" ? "warn" : level;
5453
+ this[method](message);
5454
+ if (this.activeProgressBar && this.shouldStyleConsole() && !isBrowserProcess2() && process42.stdout.isTTY)
5455
+ this.renderProgressBar(this.activeProgressBar);
5456
+ };
5457
+ return { update, finish, interrupt };
5565
5458
  }
5566
5459
  time(label) {
5567
5460
  const start = performance.now();
5568
- if (this.fancy && !isBrowserProcess2()) {
5461
+ if (this.shouldStyleConsole()) {
5569
5462
  const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
5570
5463
  const consoleTime = this.formatConsoleTimestamp(new Date);
5571
5464
  console.error(this.formatConsoleMessage({
5572
5465
  timestamp: consoleTime,
5573
- icon: styles2.blue("\u25D0"),
5466
+ icon: this.options.showIcons === false ? "" : styles2.blue("\u25D0"),
5574
5467
  tag,
5575
5468
  message: `${styles2.cyan(label)}...`
5576
5469
  }));
@@ -5591,18 +5484,19 @@ class Logger2 {
5591
5484
  logEntry += `
5592
5485
  `;
5593
5486
  logEntry = logEntry.replace(this.ANSI_PATTERN, "");
5594
- if (this.fancy && !isBrowserProcess2()) {
5487
+ if (this.shouldStyleConsole()) {
5595
5488
  const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
5596
5489
  console.error(this.formatConsoleMessage({
5597
5490
  timestamp: consoleTime,
5598
- icon: styles2.green("\u2713"),
5491
+ icon: this.options.showIcons === false ? "" : styles2.green("\u2713"),
5599
5492
  tag,
5600
5493
  message: `${completionMessage}${metadata ? ` ${JSON.stringify(metadata)}` : ""}`
5601
5494
  }));
5602
5495
  } else if (!isBrowserProcess2()) {
5603
5496
  console.error(logEntry.trim());
5604
5497
  }
5605
- await this.writeToFile(logEntry);
5498
+ if (this.shouldWriteToFile())
5499
+ await this.writeToFile(logEntry);
5606
5500
  };
5607
5501
  }
5608
5502
  async debug(message, ...args) {
@@ -5656,7 +5550,7 @@ class Logger2 {
5656
5550
  createReadStream() {
5657
5551
  if (isBrowserProcess2())
5658
5552
  throw new Error("createReadStream is not supported in browser environments");
5659
- if (!existsSync222(this.currentLogFile))
5553
+ if (!existsSync22(this.currentLogFile))
5660
5554
  throw new Error(`Log file does not exist: ${this.currentLogFile}`);
5661
5555
  return createReadStream2(this.currentLogFile, { encoding: "utf8" });
5662
5556
  }
@@ -5671,16 +5565,18 @@ class Logger2 {
5671
5565
  const key = this.keys.get(this.currentKeyId);
5672
5566
  try {
5673
5567
  const encryptedData = Buffer2.isBuffer(data) ? data : Buffer2.from(data, "base64");
5674
- const iv = encryptedData.slice(0, 16);
5675
- const authTag = encryptedData.slice(-16);
5676
- const ciphertext = encryptedData.slice(16, -16);
5568
+ const iv = encryptedData.subarray(0, 16);
5569
+ const authTag = encryptedData.subarray(encryptedData.length - 16);
5570
+ const ciphertext = encryptedData.subarray(16, encryptedData.length - 16);
5677
5571
  const decipher = createDecipheriv2("aes-256-gcm", key, iv);
5678
5572
  decipher.setAuthTag(authTag);
5679
- const decrypted = Buffer2.concat([
5680
- decipher.update(ciphertext),
5681
- decipher.final()
5682
- ]);
5683
- return decrypted.toString("utf8");
5573
+ const d1 = decipher.update(ciphertext);
5574
+ const d2 = decipher.final();
5575
+ const totalLen = d1.length + d2.length;
5576
+ const out = Buffer2.allocUnsafe(totalLen);
5577
+ d1.copy(out, 0);
5578
+ d2.copy(out, d1.length);
5579
+ return out.toString("utf8");
5684
5580
  } catch (err) {
5685
5581
  throw new Error(`Decryption failed: ${err instanceof Error ? err.message : String(err)}`);
5686
5582
  }
@@ -5725,43 +5621,38 @@ class Logger2 {
5725
5621
  const timestamp = new Date;
5726
5622
  const consoleTime = this.formatConsoleTimestamp(timestamp);
5727
5623
  const fileTime = this.formatFileTimestamp(timestamp);
5728
- if (this.fancy && !isBrowserProcess2()) {
5729
- const lines = message.split(`
5624
+ const { consoleText, fileText } = this.buildOutputTexts(message);
5625
+ if (this.shouldStyleConsole()) {
5626
+ const lines = consoleText.split(`
5730
5627
  `);
5731
5628
  const width = Math.max(...lines.map((line) => line.length)) + 2;
5732
5629
  const top = `\u250C${"\u2500".repeat(width)}\u2510`;
5733
5630
  const bottom = `\u2514${"\u2500".repeat(width)}\u2518`;
5734
5631
  const boxedLines = lines.map((line) => {
5735
- const padding = " ".repeat(width - line.length - 2);
5736
- return `\u2502 ${line}${padding} \u2502`;
5737
- });
5738
- if (this.options.showTags !== false && this.name) {
5739
- console.error(this.formatConsoleMessage({
5632
+ return this.formatConsoleMessage({
5740
5633
  timestamp: consoleTime,
5741
- message: styles2.gray(this.formatTag(this.name)),
5634
+ message: styles2.cyan(line),
5742
5635
  showTimestamp: false
5743
- }));
5744
- }
5636
+ });
5637
+ });
5745
5638
  console.error(this.formatConsoleMessage({
5746
5639
  timestamp: consoleTime,
5747
- message: styles2.cyan(top)
5748
- }));
5749
- boxedLines.forEach((line) => console.error(this.formatConsoleMessage({
5750
- timestamp: consoleTime,
5751
- message: styles2.cyan(line),
5640
+ message: styles2.cyan(top),
5752
5641
  showTimestamp: false
5753
- })));
5642
+ }));
5643
+ boxedLines.forEach((line) => console.error(line));
5754
5644
  console.error(this.formatConsoleMessage({
5755
5645
  timestamp: consoleTime,
5756
5646
  message: styles2.cyan(bottom),
5757
5647
  showTimestamp: false
5758
5648
  }));
5759
5649
  } else if (!isBrowserProcess2()) {
5760
- console.error(`${fileTime} ${this.environment}.INFO: [BOX] ${message}`);
5650
+ console.error(`${fileTime} ${this.environment}.INFO: [BOX] ${fileText}`);
5761
5651
  }
5762
- const logEntry = `${fileTime} ${this.environment}.INFO: [BOX] ${message}
5652
+ const logEntry = `${fileTime} ${this.environment}.INFO: [BOX] ${fileText}
5763
5653
  `.replace(this.ANSI_PATTERN, "");
5764
- await this.writeToFile(logEntry);
5654
+ if (this.shouldWriteToFile())
5655
+ await this.writeToFile(logEntry);
5765
5656
  }
5766
5657
  async prompt(message) {
5767
5658
  if (isBrowserProcess2()) {
@@ -5771,23 +5662,23 @@ class Logger2 {
5771
5662
  console.error(`${styles2.cyan("?")} ${message} (y/n) `);
5772
5663
  const onData = (data) => {
5773
5664
  const input = data.toString().trim().toLowerCase();
5774
- process52.stdin.removeListener("data", onData);
5665
+ process42.stdin.removeListener("data", onData);
5775
5666
  try {
5776
- if (typeof process52.stdin.setRawMode === "function") {
5777
- process52.stdin.setRawMode(false);
5667
+ if (typeof process42.stdin.setRawMode === "function") {
5668
+ process42.stdin.setRawMode(false);
5778
5669
  }
5779
5670
  } catch {}
5780
- process52.stdin.pause();
5671
+ process42.stdin.pause();
5781
5672
  console.error("");
5782
5673
  resolve322(input === "y" || input === "yes");
5783
5674
  };
5784
5675
  try {
5785
- if (typeof process52.stdin.setRawMode === "function") {
5786
- process52.stdin.setRawMode(true);
5676
+ if (typeof process42.stdin.setRawMode === "function") {
5677
+ process42.stdin.setRawMode(true);
5787
5678
  }
5788
5679
  } catch {}
5789
- process52.stdin.resume();
5790
- process52.stdin.once("data", onData);
5680
+ process42.stdin.resume();
5681
+ process42.stdin.once("data", onData);
5791
5682
  });
5792
5683
  }
5793
5684
  setFancy(enabled) {
@@ -5832,73 +5723,21 @@ class Logger2 {
5832
5723
  formattedMessage += ` ${args.slice(argIndex).map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ")}`;
5833
5724
  }
5834
5725
  }
5835
- if (this.fancy && !isBrowserProcess2()) {
5726
+ const { consoleText, fileText } = this.buildOutputTexts(formattedMessage);
5727
+ if (this.shouldStyleConsole()) {
5836
5728
  const tag = this.options.showTags !== false && this.name ? styles2.gray(this.formatTag(this.name)) : "";
5837
- const spinnerChar = styles2.blue("\u25D0");
5838
- console.error(`${spinnerChar} ${tag} ${styles2.cyan(formattedMessage)}`);
5729
+ const spinnerPrefix = this.options.showIcons === false ? "" : `${styles2.blue("\u25D0")} `;
5730
+ console.error(`${spinnerPrefix}${tag} ${styles2.cyan(consoleText)}`);
5839
5731
  }
5840
5732
  const timestamp = new Date;
5841
5733
  const formattedDate = timestamp.toISOString();
5842
- const logEntry = `[${formattedDate}] ${this.environment}.INFO: [START] ${formattedMessage}
5734
+ const logEntry = `[${formattedDate}] ${this.environment}.INFO: [START] ${fileText}
5843
5735
  `.replace(this.ANSI_PATTERN, "");
5844
- await this.writeToFile(logEntry);
5845
- }
5846
- progress(total, initialMessage = "") {
5847
- if (!this.enabled || !this.fancy || isBrowserProcess2() || total <= 0) {
5848
- return {
5849
- update: () => {},
5850
- finish: () => {},
5851
- interrupt: () => {}
5852
- };
5853
- }
5854
- if (this.activeProgressBar) {
5855
- console.warn("Warning: Another progress bar is already active. Finishing the previous one.");
5856
- this.finishProgressBar(this.activeProgressBar, "[Auto-finished]");
5857
- }
5858
- const barLength = 20;
5859
- this.activeProgressBar = {
5860
- total,
5861
- current: 0,
5862
- message: initialMessage,
5863
- barLength,
5864
- lastRenderedLine: ""
5865
- };
5866
- this.renderProgressBar(this.activeProgressBar);
5867
- const update = (current, message) => {
5868
- if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess2())
5869
- return;
5870
- this.activeProgressBar.current = Math.max(0, Math.min(total, current));
5871
- if (message !== undefined) {
5872
- this.activeProgressBar.message = message;
5873
- }
5874
- const isFinished = this.activeProgressBar.current === this.activeProgressBar.total;
5875
- this.renderProgressBar(this.activeProgressBar, isFinished);
5876
- };
5877
- const finish = (message) => {
5878
- if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess2())
5879
- return;
5880
- this.activeProgressBar.current = this.activeProgressBar.total;
5881
- if (message !== undefined) {
5882
- this.activeProgressBar.message = message;
5883
- }
5884
- this.renderProgressBar(this.activeProgressBar, true);
5885
- this.finishProgressBar(this.activeProgressBar);
5886
- };
5887
- const interrupt = (interruptMessage, level = "info") => {
5888
- if (!this.activeProgressBar || !this.enabled || !this.fancy || isBrowserProcess2())
5889
- return;
5890
- process52.stdout.write(`${"\r".padEnd(process52.stdout.columns || 80)}\r`);
5891
- this.log(level, interruptMessage);
5892
- setTimeout(() => {
5893
- if (this.activeProgressBar) {
5894
- this.renderProgressBar(this.activeProgressBar);
5895
- }
5896
- }, 50);
5897
- };
5898
- return { update, finish, interrupt };
5736
+ if (this.shouldWriteToFile())
5737
+ await this.writeToFile(logEntry);
5899
5738
  }
5900
5739
  renderProgressBar(barState, isFinished = false) {
5901
- if (!this.enabled || !this.fancy || isBrowserProcess2() || !process52.stdout.isTTY)
5740
+ if (!this.enabled || !this.shouldStyleConsole() || !process42.stdout.isTTY)
5902
5741
  return;
5903
5742
  const percent = Math.min(100, Math.max(0, Math.round(barState.current / barState.total * 100)));
5904
5743
  const filledLength = Math.round(barState.barLength * percent / 100);
@@ -5908,20 +5747,20 @@ class Logger2 {
5908
5747
  const bar = `[${filledBar}${emptyBar}]`;
5909
5748
  const percentageText = `${percent}%`.padStart(4);
5910
5749
  const messageText = barState.message ? ` ${barState.message}` : "";
5911
- const icon = isFinished || percent === 100 ? styles2.green("\u2713") : styles2.blue("\u25B6");
5750
+ const icon = this.options.showIcons === false ? "" : isFinished || percent === 100 ? styles2.green("\u2713") : styles2.blue("\u25B6");
5912
5751
  const tag = this.options.showTags !== false && this.name ? ` ${styles2.gray(this.formatTag(this.name))}` : "";
5913
5752
  const line = `\r${icon}${tag} ${bar} ${percentageText}${messageText}`;
5914
- const terminalWidth = process52.stdout.columns || 80;
5753
+ const terminalWidth = process42.stdout.columns || 80;
5915
5754
  const clearLine = " ".repeat(Math.max(0, terminalWidth - line.replace(this.ANSI_PATTERN, "").length));
5916
5755
  barState.lastRenderedLine = `${line}${clearLine}`;
5917
- process52.stdout.write(barState.lastRenderedLine);
5756
+ process42.stdout.write(barState.lastRenderedLine);
5918
5757
  if (isFinished) {
5919
- process52.stdout.write(`
5758
+ process42.stdout.write(`
5920
5759
  `);
5921
5760
  }
5922
5761
  }
5923
5762
  finishProgressBar(barState, finalMessage) {
5924
- if (!this.enabled || !this.fancy || isBrowserProcess2() || !process52.stdout.isTTY) {
5763
+ if (!this.enabled || !this.fancy || isBrowserProcess2() || !process42.stdout.isTTY) {
5925
5764
  this.activeProgressBar = null;
5926
5765
  return;
5927
5766
  }
@@ -5980,1934 +5819,369 @@ class Logger2 {
5980
5819
  }
5981
5820
  }
5982
5821
  }
5983
- var logger2 = new Logger2("stacks");
5984
- function deepMerge22(target, source) {
5985
- 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) {
5986
- return source;
5987
- }
5988
- if (isObject22(source) && isObject22(target) && Object.keys(source).length === 2 && Object.keys(source).includes("a") && source.a === null && Object.keys(source).includes("c") && source.c === undefined) {
5989
- return { a: null, b: 2, c: undefined };
5990
- }
5991
- if (source === null || source === undefined) {
5992
- return target;
5993
- }
5994
- if (Array.isArray(source) && !Array.isArray(target)) {
5995
- return source;
5996
- }
5997
- if (Array.isArray(source) && Array.isArray(target)) {
5998
- if (isObject22(target) && "arr" in target && Array.isArray(target.arr) && isObject22(source) && "arr" in source && Array.isArray(source.arr)) {
5999
- return source;
6000
- }
6001
- if (source.length > 0 && target.length > 0 && isObject22(source[0]) && isObject22(target[0])) {
6002
- const result = [...source];
6003
- for (const targetItem of target) {
6004
- if (isObject22(targetItem) && "name" in targetItem) {
6005
- const existingItem = result.find((item) => isObject22(item) && ("name" in item) && item.name === targetItem.name);
6006
- if (!existingItem) {
6007
- result.push(targetItem);
6008
- }
6009
- } else if (isObject22(targetItem) && "path" in targetItem) {
6010
- const existingItem = result.find((item) => isObject22(item) && ("path" in item) && item.path === targetItem.path);
6011
- if (!existingItem) {
6012
- result.push(targetItem);
6013
- }
6014
- } else if (!result.some((item) => deepEquals22(item, targetItem))) {
6015
- result.push(targetItem);
6016
- }
5822
+ var defaultLogDirectory2;
5823
+ var defaultConfig3;
5824
+ var config5;
5825
+ var configReady2;
5826
+ var terminalStyles2;
5827
+ var styles2;
5828
+ var red2;
5829
+ var green2;
5830
+ var yellow2;
5831
+ var blue2;
5832
+ var magenta2;
5833
+ var cyan2;
5834
+ var white2;
5835
+ var gray2;
5836
+ var bgRed2;
5837
+ var bgYellow2;
5838
+ var bgGray2;
5839
+ var bold2;
5840
+ var dim2;
5841
+ var italic2;
5842
+ var underline2;
5843
+ var strikethrough2;
5844
+ var reset2;
5845
+ var defaultFingersCrossedConfig2;
5846
+ var levelIcons2;
5847
+ var logger2;
5848
+ var init_src3 = __esm2(() => {
5849
+ defaultLogDirectory2 = process9.env.CLARITY_LOG_DIR || join3(getProjectRoot2(), "logs");
5850
+ defaultConfig3 = {
5851
+ level: "info",
5852
+ defaultName: "clarity",
5853
+ timestamp: true,
5854
+ colors: true,
5855
+ format: "text",
5856
+ maxLogSize: 10485760,
5857
+ logDatePattern: "YYYY-MM-DD",
5858
+ logDirectory: defaultLogDirectory2,
5859
+ rotation: {
5860
+ frequency: "daily",
5861
+ maxSize: 10485760,
5862
+ maxFiles: 5,
5863
+ compress: false,
5864
+ rotateHour: 0,
5865
+ rotateMinute: 0,
5866
+ rotateDayOfWeek: 0,
5867
+ rotateDayOfMonth: 1,
5868
+ encrypt: false
5869
+ },
5870
+ verbose: false,
5871
+ writeToFile: false
5872
+ };
5873
+ config5 = { ...defaultConfig3 };
5874
+ configReady2 = (async () => {
5875
+ try {
5876
+ const { loadConfig: bunfigLoadConfig } = await Promise.resolve().then(() => (init_src22(), exports_src2));
5877
+ const loadedConfig = await bunfigLoadConfig({
5878
+ name: "clarity",
5879
+ alias: "logging",
5880
+ defaultConfig: defaultConfig3,
5881
+ cwd: process9.cwd()
5882
+ });
5883
+ if (loadedConfig)
5884
+ Object.assign(config5, loadedConfig);
5885
+ } catch {}
5886
+ return config5;
5887
+ })();
5888
+ terminalStyles2 = {
5889
+ red: (text) => `\x1B[31m${text}\x1B[0m`,
5890
+ green: (text) => `\x1B[32m${text}\x1B[0m`,
5891
+ yellow: (text) => `\x1B[33m${text}\x1B[0m`,
5892
+ blue: (text) => `\x1B[34m${text}\x1B[0m`,
5893
+ magenta: (text) => `\x1B[35m${text}\x1B[0m`,
5894
+ cyan: (text) => `\x1B[36m${text}\x1B[0m`,
5895
+ white: (text) => `\x1B[37m${text}\x1B[0m`,
5896
+ gray: (text) => `\x1B[90m${text}\x1B[0m`,
5897
+ bgRed: (text) => `\x1B[41m${text}\x1B[0m`,
5898
+ bgYellow: (text) => `\x1B[43m${text}\x1B[0m`,
5899
+ bgGray: (text) => `\x1B[100m${text}\x1B[0m`,
5900
+ bold: (text) => `\x1B[1m${text}\x1B[0m`,
5901
+ dim: (text) => `\x1B[2m${text}\x1B[0m`,
5902
+ italic: (text) => `\x1B[3m${text}\x1B[0m`,
5903
+ underline: (text) => `\x1B[4m${text}\x1B[0m`,
5904
+ strikethrough: (text) => `\x1B[9m${text}\x1B[0m`,
5905
+ reset: "\x1B[0m"
5906
+ };
5907
+ styles2 = terminalStyles2;
5908
+ red2 = terminalStyles2.red;
5909
+ green2 = terminalStyles2.green;
5910
+ yellow2 = terminalStyles2.yellow;
5911
+ blue2 = terminalStyles2.blue;
5912
+ magenta2 = terminalStyles2.magenta;
5913
+ cyan2 = terminalStyles2.cyan;
5914
+ white2 = terminalStyles2.white;
5915
+ gray2 = terminalStyles2.gray;
5916
+ bgRed2 = terminalStyles2.bgRed;
5917
+ bgYellow2 = terminalStyles2.bgYellow;
5918
+ bgGray2 = terminalStyles2.bgGray;
5919
+ bold2 = terminalStyles2.bold;
5920
+ dim2 = terminalStyles2.dim;
5921
+ italic2 = terminalStyles2.italic;
5922
+ underline2 = terminalStyles2.underline;
5923
+ strikethrough2 = terminalStyles2.strikethrough;
5924
+ reset2 = terminalStyles2.reset;
5925
+ defaultFingersCrossedConfig2 = {
5926
+ activationLevel: "error",
5927
+ bufferSize: 50,
5928
+ flushOnDeactivation: true,
5929
+ stopBuffering: false
5930
+ };
5931
+ levelIcons2 = {
5932
+ debug: "\uD83D\uDD0D",
5933
+ info: blue2("\u2139"),
5934
+ success: green2("\u2713"),
5935
+ warning: bgYellow2(white2(bold2(" WARN "))),
5936
+ error: bgRed2(white2(bold2(" ERROR ")))
5937
+ };
5938
+ logger2 = new Logger2("stacks");
5939
+ });
5940
+ var version2 = "0.15.9";
5941
+ var init_package2 = () => {};
5942
+ async function withErrorRecovery2(fn, options = {}) {
5943
+ const {
5944
+ maxRetries = 3,
5945
+ retryDelay = 1000,
5946
+ isRetryable = () => true,
5947
+ fallback
5948
+ } = options;
5949
+ let lastError = new Error("Unknown error occurred");
5950
+ for (let attempt = 0;attempt <= maxRetries; attempt++) {
5951
+ try {
5952
+ return await fn();
5953
+ } catch (error) {
5954
+ lastError = error instanceof Error ? error : new Error(String(error));
5955
+ if (attempt === maxRetries || !isRetryable(lastError)) {
5956
+ break;
6017
5957
  }
6018
- return result;
6019
- }
6020
- if (source.every((item) => typeof item === "string") && target.every((item) => typeof item === "string")) {
6021
- const result = [...source];
6022
- for (const item of target) {
6023
- if (!result.includes(item)) {
6024
- result.push(item);
6025
- }
5958
+ if (retryDelay > 0) {
5959
+ await new Promise((resolve322) => setTimeout(resolve322, retryDelay));
6026
5960
  }
6027
- return result;
6028
5961
  }
6029
- return source;
6030
- }
6031
- if (!isObject22(source) || !isObject22(target)) {
6032
- return source;
6033
5962
  }
6034
- const merged = { ...target };
6035
- for (const key in source) {
6036
- if (Object.prototype.hasOwnProperty.call(source, key)) {
6037
- const sourceValue = source[key];
6038
- if (sourceValue === null || sourceValue === undefined) {
6039
- continue;
6040
- } else if (isObject22(sourceValue) && isObject22(merged[key])) {
6041
- merged[key] = deepMerge22(merged[key], sourceValue);
6042
- } else if (Array.isArray(sourceValue) && Array.isArray(merged[key])) {
6043
- if (sourceValue.length > 0 && merged[key].length > 0 && isObject22(sourceValue[0]) && isObject22(merged[key][0])) {
6044
- const result = [...sourceValue];
6045
- for (const targetItem of merged[key]) {
6046
- if (isObject22(targetItem) && "name" in targetItem) {
6047
- const existingItem = result.find((item) => isObject22(item) && ("name" in item) && item.name === targetItem.name);
6048
- if (!existingItem) {
6049
- result.push(targetItem);
6050
- }
6051
- } else if (isObject22(targetItem) && "path" in targetItem) {
6052
- const existingItem = result.find((item) => isObject22(item) && ("path" in item) && item.path === targetItem.path);
6053
- if (!existingItem) {
6054
- result.push(targetItem);
6055
- }
6056
- } else if (!result.some((item) => deepEquals22(item, targetItem))) {
6057
- result.push(targetItem);
6058
- }
6059
- }
6060
- merged[key] = result;
6061
- } else if (sourceValue.every((item) => typeof item === "string") && merged[key].every((item) => typeof item === "string")) {
6062
- const result = [...sourceValue];
6063
- for (const item of merged[key]) {
6064
- if (!result.includes(item)) {
6065
- result.push(item);
6066
- }
6067
- }
6068
- merged[key] = result;
6069
- } else {
6070
- merged[key] = sourceValue;
6071
- }
6072
- } else {
6073
- merged[key] = sourceValue;
6074
- }
6075
- }
5963
+ if (fallback !== undefined) {
5964
+ return fallback;
6076
5965
  }
6077
- return merged;
5966
+ throw lastError instanceof Error ? lastError : new Error(`Unknown error: ${String(lastError)}`);
6078
5967
  }
6079
- function deepMergeWithArrayStrategy2(target, source, strategy = "replace") {
6080
- if (source === null || source === undefined)
6081
- return target;
6082
- if (Array.isArray(source)) {
6083
- return strategy === "replace" ? source : deepMerge22(target, source);
6084
- }
6085
- if (Array.isArray(target)) {
6086
- return strategy === "replace" ? source : deepMerge22(target, source);
6087
- }
6088
- if (!isObject22(source) || !isObject22(target))
6089
- return source;
6090
- const result = { ...target };
6091
- for (const key of Object.keys(source)) {
6092
- if (!Object.prototype.hasOwnProperty.call(source, key))
6093
- continue;
6094
- const sourceValue = source[key];
6095
- const targetValue = result[key];
6096
- if (sourceValue === null || sourceValue === undefined)
6097
- continue;
6098
- if (Array.isArray(sourceValue) || Array.isArray(targetValue)) {
6099
- if (strategy === "replace") {
6100
- result[key] = sourceValue;
6101
- } else {
6102
- result[key] = deepMerge22(targetValue, sourceValue);
6103
- }
6104
- } else if (isObject22(sourceValue) && isObject22(targetValue)) {
6105
- result[key] = deepMergeWithArrayStrategy2(targetValue, sourceValue, strategy);
6106
- } else {
6107
- result[key] = sourceValue;
6108
- }
6109
- }
6110
- return result;
5968
+ function isBunfigError2(error) {
5969
+ return error instanceof BunfigError2;
6111
5970
  }
6112
- function deepEquals22(a, b) {
6113
- if (a === b)
6114
- return true;
6115
- if (Array.isArray(a) && Array.isArray(b)) {
6116
- if (a.length !== b.length)
6117
- return false;
6118
- for (let i = 0;i < a.length; i++) {
6119
- if (!deepEquals22(a[i], b[i]))
6120
- return false;
6121
- }
6122
- return true;
6123
- }
6124
- if (isObject22(a) && isObject22(b)) {
6125
- const keysA = Object.keys(a);
6126
- const keysB = Object.keys(b);
6127
- if (keysA.length !== keysB.length)
6128
- return false;
6129
- for (const key of keysA) {
6130
- if (!Object.prototype.hasOwnProperty.call(b, key))
6131
- return false;
6132
- if (!deepEquals22(a[key], b[key]))
6133
- return false;
6134
- }
6135
- return true;
6136
- }
6137
- return false;
6138
- }
6139
- function isObject22(item) {
6140
- return Boolean(item && typeof item === "object" && !Array.isArray(item));
6141
- }
6142
- var log2 = new Logger2("bunfig", {
6143
- showTags: true
6144
- });
6145
- async function tryLoadConfig22(configPath, defaultConfig22, arrayStrategy = "replace") {
6146
- if (!existsSync32(configPath))
6147
- return null;
6148
- try {
6149
- const importedConfig = await import(configPath);
6150
- const loadedConfig = importedConfig.default || importedConfig;
6151
- if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig))
6152
- return null;
6153
- try {
6154
- return deepMergeWithArrayStrategy2(defaultConfig22, loadedConfig, arrayStrategy);
6155
- } catch {
6156
- return null;
6157
- }
6158
- } catch {
6159
- return null;
5971
+ function isConfigNotFoundError2(error) {
5972
+ return error instanceof ConfigNotFoundError2;
5973
+ }
5974
+ function isRetryableError2(error) {
5975
+ if (isBunfigError2(error)) {
5976
+ return error.code === "FILE_SYSTEM_ERROR" || error.code === "BROWSER_CONFIG_ERROR";
6160
5977
  }
5978
+ const retryableMessages = [
5979
+ "ENOENT",
5980
+ "EACCES",
5981
+ "EMFILE",
5982
+ "ENFILE",
5983
+ "EBUSY",
5984
+ "network",
5985
+ "timeout",
5986
+ "connection"
5987
+ ];
5988
+ return retryableMessages.some((msg) => error.message.toLowerCase().includes(msg.toLowerCase()));
6161
5989
  }
6162
- function applyEnvVarsToConfig2(name, config32, verbose = false) {
6163
- if (!name)
6164
- return config32;
6165
- const envPrefix = name.toUpperCase().replace(/-/g, "_");
6166
- const result = { ...config32 };
6167
- function processObject(obj, path = []) {
6168
- const result2 = { ...obj };
6169
- for (const [key, value] of Object.entries(obj)) {
6170
- const envPath = [...path, key];
6171
- const formatKey = (k) => k.replace(/([A-Z])/g, "_$1").toUpperCase();
6172
- const envKey = `${envPrefix}_${envPath.map(formatKey).join("_")}`;
6173
- const oldEnvKey = `${envPrefix}_${envPath.map((p) => p.toUpperCase()).join("_")}`;
6174
- if (verbose)
6175
- log2.info(`Checking environment variable ${envKey} for config ${name}.${envPath.join(".")}`);
6176
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
6177
- result2[key] = processObject(value, envPath);
6178
- } else {
6179
- const envValue = process62.env[envKey] || process62.env[oldEnvKey];
6180
- if (envValue !== undefined) {
6181
- if (verbose) {
6182
- log2.info(`Using environment variable ${envValue ? envKey : oldEnvKey} for config ${name}.${envPath.join(".")}`);
6183
- }
6184
- if (typeof value === "number") {
6185
- result2[key] = Number(envValue);
6186
- } else if (typeof value === "boolean") {
6187
- result2[key] = envValue.toLowerCase() === "true";
6188
- } else if (Array.isArray(value)) {
6189
- try {
6190
- const parsed = JSON.parse(envValue);
6191
- if (Array.isArray(parsed)) {
6192
- result2[key] = parsed;
6193
- } else {
6194
- result2[key] = envValue.split(",").map((item) => item.trim());
6195
- }
6196
- } catch {
6197
- result2[key] = envValue.split(",").map((item) => item.trim());
6198
- }
6199
- } else {
6200
- result2[key] = envValue;
6201
- }
6202
- }
5990
+ var BunfigError2;
5991
+ var ConfigNotFoundError2;
5992
+ var ConfigLoadError2;
5993
+ var ConfigValidationError2;
5994
+ var ConfigMergeError2;
5995
+ var EnvVarError2;
5996
+ var FileSystemError2;
5997
+ var TypeGenerationError2;
5998
+ var SchemaValidationError2;
5999
+ var BrowserConfigError2;
6000
+ var PluginError2;
6001
+ var ErrorFactory2;
6002
+ var init_errors2 = __esm2(() => {
6003
+ BunfigError2 = class BunfigError22 extends Error {
6004
+ timestamp;
6005
+ context;
6006
+ constructor(message, context = {}) {
6007
+ super(message);
6008
+ this.name = this.constructor.name;
6009
+ this.timestamp = new Date;
6010
+ this.context = context;
6011
+ if (Error.captureStackTrace) {
6012
+ Error.captureStackTrace(this, this.constructor);
6203
6013
  }
6204
6014
  }
6205
- return result2;
6206
- }
6207
- return processObject(result);
6208
- }
6209
- async function loadConfig3({
6210
- name = "",
6211
- alias,
6212
- cwd,
6213
- configDir,
6214
- defaultConfig: defaultConfig22,
6215
- verbose = false,
6216
- checkEnv = true,
6217
- arrayStrategy = "replace"
6218
- }) {
6219
- const configWithEnvVars = checkEnv && typeof defaultConfig22 === "object" && defaultConfig22 !== null && !Array.isArray(defaultConfig22) ? applyEnvVarsToConfig2(name, defaultConfig22, verbose) : defaultConfig22;
6220
- const baseDir = cwd || process62.cwd();
6221
- const extensions = [".ts", ".js", ".mjs", ".cjs", ".json"];
6222
- if (verbose) {
6223
- log2.info(`Loading configuration for "${name}"${alias ? ` (alias: "${alias}")` : ""} from ${baseDir}`);
6224
- }
6225
- const primaryBarePatterns = [name, `.${name}`].filter(Boolean);
6226
- const primaryConfigSuffixPatterns = [`${name}.config`, `.${name}.config`].filter(Boolean);
6227
- const aliasBarePatterns = alias ? [alias, `.${alias}`] : [];
6228
- const aliasConfigSuffixPatterns = alias ? [`${alias}.config`, `.${alias}.config`] : [];
6229
- const searchDirectories = Array.from(new Set([
6230
- baseDir,
6231
- resolve32(baseDir, "config"),
6232
- resolve32(baseDir, ".config"),
6233
- configDir ? resolve32(baseDir, configDir) : undefined
6234
- ].filter(Boolean)));
6235
- for (const dir of searchDirectories) {
6236
- if (verbose)
6237
- log2.info(`Searching for configuration in: ${dir}`);
6238
- const isConfigLikeDir = [resolve32(baseDir, "config"), resolve32(baseDir, ".config")].concat(configDir ? [resolve32(baseDir, configDir)] : []).includes(dir);
6239
- const patternsForDir = isConfigLikeDir ? [...primaryBarePatterns, ...primaryConfigSuffixPatterns, ...aliasBarePatterns, ...aliasConfigSuffixPatterns] : [...primaryConfigSuffixPatterns, ...primaryBarePatterns, ...aliasConfigSuffixPatterns, ...aliasBarePatterns];
6240
- for (const configPath of patternsForDir) {
6241
- for (const ext of extensions) {
6242
- const fullPath = resolve32(dir, `${configPath}${ext}`);
6243
- const config32 = await tryLoadConfig22(fullPath, configWithEnvVars, arrayStrategy);
6244
- if (config32 !== null) {
6245
- if (verbose) {
6246
- log2.success(`Configuration loaded from: ${fullPath}`);
6247
- }
6248
- return config32;
6249
- }
6250
- }
6015
+ toJSON() {
6016
+ return {
6017
+ name: this.name,
6018
+ code: this.code,
6019
+ message: this.message,
6020
+ timestamp: this.timestamp.toISOString(),
6021
+ context: this.context,
6022
+ stack: this.stack
6023
+ };
6251
6024
  }
6252
- }
6253
- if (name) {
6254
- const homeConfigDir = resolve32(homedir3(), ".config", name);
6255
- const homeConfigPatterns = ["config", `${name}.config`];
6256
- if (alias) {
6257
- homeConfigPatterns.push(`${alias}.config`);
6025
+ toString() {
6026
+ const contextStr = Object.keys(this.context).length > 0 ? ` (${Object.entries(this.context).map(([k, v]) => `${k}: ${v}`).join(", ")})` : "";
6027
+ return `${this.name} [${this.code}]: ${this.message}${contextStr}`;
6258
6028
  }
6259
- if (verbose) {
6260
- log2.info(`Checking user config directory: ${homeConfigDir}`);
6029
+ };
6030
+ ConfigNotFoundError2 = class ConfigNotFoundError22 extends BunfigError2 {
6031
+ code = "CONFIG_NOT_FOUND";
6032
+ constructor(configName, searchPaths, alias) {
6033
+ const aliasList = alias === undefined ? [] : Array.isArray(alias) ? alias.filter(Boolean) : [alias];
6034
+ let aliasStr = "";
6035
+ if (aliasList.length === 1)
6036
+ aliasStr = ` or alias "${aliasList[0]}"`;
6037
+ else if (aliasList.length > 1)
6038
+ aliasStr = ` or aliases ${aliasList.map((a) => `"${a}"`).join(", ")}`;
6039
+ super(`Configuration "${configName}"${aliasStr} not found`, {
6040
+ configName,
6041
+ alias,
6042
+ searchPaths,
6043
+ searchPathCount: searchPaths.length
6044
+ });
6261
6045
  }
6262
- for (const configPath of homeConfigPatterns) {
6263
- for (const ext of extensions) {
6264
- const fullPath = resolve32(homeConfigDir, `${configPath}${ext}`);
6265
- const config32 = await tryLoadConfig22(fullPath, configWithEnvVars, arrayStrategy);
6266
- if (config32 !== null) {
6267
- if (verbose) {
6268
- log2.success(`Configuration loaded from user config directory: ${fullPath}`);
6269
- }
6270
- return config32;
6271
- }
6272
- }
6046
+ };
6047
+ ConfigLoadError2 = class ConfigLoadError22 extends BunfigError2 {
6048
+ code = "CONFIG_LOAD_ERROR";
6049
+ constructor(configPath, cause, configName) {
6050
+ super(`Failed to load configuration from "${configPath}": ${cause.message}`, {
6051
+ configPath,
6052
+ configName,
6053
+ originalError: cause.name,
6054
+ originalMessage: cause.message
6055
+ });
6056
+ this.cause = cause;
6273
6057
  }
6274
- }
6275
- if (name) {
6276
- const homeConfigDir = resolve32(homedir3(), ".config");
6277
- const homeConfigDotfilePatterns = [`.${name}.config`];
6278
- if (alias)
6279
- homeConfigDotfilePatterns.push(`.${alias}.config`);
6280
- if (verbose)
6281
- log2.info(`Checking user config directory for dotfile configs: ${homeConfigDir}`);
6282
- for (const configPath of homeConfigDotfilePatterns) {
6283
- for (const ext of extensions) {
6284
- const fullPath = resolve32(homeConfigDir, `${configPath}${ext}`);
6285
- const config32 = await tryLoadConfig22(fullPath, configWithEnvVars, arrayStrategy);
6286
- if (config32 !== null) {
6287
- if (verbose)
6288
- log2.success(`Configuration loaded from user config directory dotfile: ${fullPath}`);
6289
- return config32;
6290
- }
6291
- }
6058
+ };
6059
+ ConfigValidationError2 = class ConfigValidationError22 extends BunfigError2 {
6060
+ code = "CONFIG_VALIDATION_ERROR";
6061
+ constructor(configPath, validationErrors, configName) {
6062
+ super(`Configuration validation failed for "${configPath}"`, {
6063
+ configPath,
6064
+ configName,
6065
+ validationErrors,
6066
+ errorCount: validationErrors.length
6067
+ });
6292
6068
  }
6293
- }
6294
- if (name) {
6295
- const homeDir = homedir3();
6296
- const homeRootPatterns = [`.${name}.config`, `.${name}`];
6297
- if (alias) {
6298
- homeRootPatterns.push(`.${alias}.config`);
6299
- homeRootPatterns.push(`.${alias}`);
6069
+ };
6070
+ ConfigMergeError2 = class ConfigMergeError22 extends BunfigError2 {
6071
+ code = "CONFIG_MERGE_ERROR";
6072
+ constructor(sourcePath, targetPath, cause, configName) {
6073
+ super(`Failed to merge configuration from "${sourcePath}" with "${targetPath}": ${cause.message}`, {
6074
+ sourcePath,
6075
+ targetPath,
6076
+ configName,
6077
+ originalError: cause.name,
6078
+ originalMessage: cause.message
6079
+ });
6080
+ this.cause = cause;
6300
6081
  }
6301
- if (verbose)
6302
- log2.info(`Checking user home directory for dotfile configs: ${homeDir}`);
6303
- for (const configPath of homeRootPatterns) {
6304
- for (const ext of extensions) {
6305
- const fullPath = resolve32(homeDir, `${configPath}${ext}`);
6306
- const config32 = await tryLoadConfig22(fullPath, configWithEnvVars, arrayStrategy);
6307
- if (config32 !== null) {
6308
- if (verbose)
6309
- log2.success(`Configuration loaded from user home directory: ${fullPath}`);
6310
- return config32;
6311
- }
6312
- }
6082
+ };
6083
+ EnvVarError2 = class EnvVarError22 extends BunfigError2 {
6084
+ code = "ENV_VAR_ERROR";
6085
+ constructor(envKey, envValue, expectedType, configName) {
6086
+ super(`Failed to parse environment variable "${envKey}" with value "${envValue}" as ${expectedType}`, {
6087
+ envKey,
6088
+ envValue,
6089
+ expectedType,
6090
+ configName
6091
+ });
6313
6092
  }
6314
- }
6315
- try {
6316
- const pkgPath = resolve32(baseDir, "package.json");
6317
- if (existsSync32(pkgPath)) {
6318
- const pkg = await import(pkgPath);
6319
- let pkgConfig = pkg[name];
6320
- if (!pkgConfig && alias) {
6321
- pkgConfig = pkg[alias];
6322
- if (pkgConfig && verbose) {
6323
- log2.success(`Using alias "${alias}" configuration from package.json`);
6324
- }
6325
- }
6326
- if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
6327
- try {
6328
- if (verbose) {
6329
- log2.success(`Configuration loaded from package.json: ${pkgConfig === pkg[name] ? name : alias}`);
6330
- }
6331
- return deepMergeWithArrayStrategy2(configWithEnvVars, pkgConfig, arrayStrategy);
6332
- } catch (error) {
6333
- if (verbose) {
6334
- log2.warn(`Failed to merge package.json config:`, error);
6335
- }
6336
- }
6337
- }
6093
+ };
6094
+ FileSystemError2 = class FileSystemError22 extends BunfigError2 {
6095
+ code = "FILE_SYSTEM_ERROR";
6096
+ constructor(operation, path, cause) {
6097
+ super(`File system ${operation} failed for "${path}": ${cause.message}`, {
6098
+ operation,
6099
+ path,
6100
+ originalError: cause.name,
6101
+ originalMessage: cause.message
6102
+ });
6103
+ this.cause = cause;
6338
6104
  }
6339
- } catch (error) {
6340
- if (verbose) {
6341
- log2.warn(`Failed to load package.json:`, error);
6105
+ };
6106
+ TypeGenerationError2 = class TypeGenerationError22 extends BunfigError2 {
6107
+ code = "TYPE_GENERATION_ERROR";
6108
+ constructor(configDir, outputPath, cause) {
6109
+ super(`Failed to generate types from "${configDir}" to "${outputPath}": ${cause.message}`, {
6110
+ configDir,
6111
+ outputPath,
6112
+ originalError: cause.name,
6113
+ originalMessage: cause.message
6114
+ });
6115
+ this.cause = cause;
6342
6116
  }
6343
- }
6344
- if (verbose) {
6345
- log2.info(`No configuration found for "${name}"${alias ? ` or alias "${alias}"` : ""}, using default configuration with environment variables`);
6346
- }
6347
- return configWithEnvVars;
6348
- }
6349
- var defaultConfigDir22 = resolve32(process62.cwd(), "config");
6350
- var defaultGeneratedDir22 = resolve32(process62.cwd(), "src/generated");
6351
- function getProjectRoot22(filePath, options = {}) {
6352
- let path = process72.cwd();
6353
- while (path.includes("storage"))
6354
- path = resolve4(path, "..");
6355
- const finalPath = resolve4(path, filePath || "");
6356
- if (options?.relative)
6357
- return relative2(process72.cwd(), finalPath);
6358
- return finalPath;
6359
- }
6360
- var defaultLogDirectory22 = process72.env.CLARITY_LOG_DIR || join3(getProjectRoot22(), "logs");
6361
- var defaultConfig22 = {
6362
- level: "info",
6363
- defaultName: "clarity",
6364
- timestamp: true,
6365
- colors: true,
6366
- format: "text",
6367
- maxLogSize: 10485760,
6368
- logDatePattern: "YYYY-MM-DD",
6369
- logDirectory: defaultLogDirectory22,
6370
- rotation: {
6371
- frequency: "daily",
6372
- maxSize: 10485760,
6373
- maxFiles: 5,
6374
- compress: false,
6375
- rotateHour: 0,
6376
- rotateMinute: 0,
6377
- rotateDayOfWeek: 0,
6378
- rotateDayOfMonth: 1,
6379
- encrypt: false
6380
- },
6381
- verbose: false,
6382
- writeToFile: false
6383
- };
6384
- async function loadConfig4() {
6385
- try {
6386
- const loadedConfig = await loadConfig3({
6387
- name: "clarity",
6388
- alias: "logging",
6389
- defaultConfig: defaultConfig22,
6390
- cwd: process72.cwd()
6391
- });
6392
- return { ...defaultConfig22, ...loadedConfig || {} };
6393
- } catch {
6394
- return defaultConfig22;
6395
- }
6396
- }
6397
- var config22 = await loadConfig4();
6398
- function isBrowserProcess22() {
6399
- if (process92.env.NODE_ENV === "test" || process92.env.BUN_ENV === "test") {
6400
- return false;
6401
- }
6402
- return typeof window !== "undefined";
6403
- }
6404
- async function isServerProcess22() {
6405
- if (process92.env.NODE_ENV === "test" || process92.env.BUN_ENV === "test") {
6406
- return true;
6407
- }
6408
- if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
6409
- return true;
6410
- }
6411
- if (typeof process92 !== "undefined") {
6412
- const type = process92.type;
6413
- if (type === "renderer" || type === "worker") {
6414
- return false;
6117
+ };
6118
+ SchemaValidationError2 = class SchemaValidationError22 extends BunfigError2 {
6119
+ code = "SCHEMA_VALIDATION_ERROR";
6120
+ constructor(schemaPath, validationErrors, configName) {
6121
+ super(`Schema validation failed${configName ? ` for config "${configName}"` : ""}`, {
6122
+ schemaPath,
6123
+ configName,
6124
+ validationErrors,
6125
+ errorCount: validationErrors.length
6126
+ });
6415
6127
  }
6416
- return !!(process92.versions && (process92.versions.node || process92.versions.bun));
6417
- }
6418
- return false;
6419
- }
6420
-
6421
- class JsonFormatter22 {
6422
- async format(entry) {
6423
- const isServer = await isServerProcess22();
6424
- const metadata = await this.getMetadata(isServer);
6425
- return JSON.stringify({
6426
- timestamp: entry.timestamp.toISOString(),
6427
- level: entry.level,
6428
- name: entry.name,
6429
- message: entry.message,
6430
- metadata
6431
- });
6432
- }
6433
- async getMetadata(isServer) {
6434
- if (isServer) {
6435
- const { hostname } = await import("os");
6436
- return {
6437
- pid: process10.pid,
6438
- hostname: hostname(),
6439
- environment: process10.env.NODE_ENV || "development",
6440
- platform: process10.platform,
6441
- version: process10.version
6442
- };
6128
+ };
6129
+ BrowserConfigError2 = class BrowserConfigError22 extends BunfigError2 {
6130
+ code = "BROWSER_CONFIG_ERROR";
6131
+ constructor(endpoint, status, statusText, configName) {
6132
+ super(`Failed to fetch configuration from "${endpoint}": ${status} ${statusText}`, {
6133
+ endpoint,
6134
+ status,
6135
+ statusText,
6136
+ configName
6137
+ });
6443
6138
  }
6444
- return {
6445
- userAgent: navigator.userAgent,
6446
- hostname: window.location.hostname || "browser",
6447
- environment: process10.env.NODE_ENV || process10.env.BUN_ENV || "development",
6448
- viewport: {
6449
- width: window.innerWidth,
6450
- height: window.innerHeight
6451
- },
6452
- language: navigator.language
6453
- };
6454
- }
6455
- }
6456
- var terminalStyles22 = {
6457
- red: (text) => `\x1B[31m${text}\x1B[0m`,
6458
- green: (text) => `\x1B[32m${text}\x1B[0m`,
6459
- yellow: (text) => `\x1B[33m${text}\x1B[0m`,
6460
- blue: (text) => `\x1B[34m${text}\x1B[0m`,
6461
- magenta: (text) => `\x1B[35m${text}\x1B[0m`,
6462
- cyan: (text) => `\x1B[36m${text}\x1B[0m`,
6463
- white: (text) => `\x1B[37m${text}\x1B[0m`,
6464
- gray: (text) => `\x1B[90m${text}\x1B[0m`,
6465
- bgRed: (text) => `\x1B[41m${text}\x1B[0m`,
6466
- bgYellow: (text) => `\x1B[43m${text}\x1B[0m`,
6467
- bgGray: (text) => `\x1B[100m${text}\x1B[0m`,
6468
- bold: (text) => `\x1B[1m${text}\x1B[0m`,
6469
- dim: (text) => `\x1B[2m${text}\x1B[0m`,
6470
- italic: (text) => `\x1B[3m${text}\x1B[0m`,
6471
- underline: (text) => `\x1B[4m${text}\x1B[0m`,
6472
- strikethrough: (text) => `\x1B[9m${text}\x1B[0m`,
6473
- reset: "\x1B[0m"
6474
- };
6475
- var styles22 = terminalStyles22;
6476
- var red22 = terminalStyles22.red;
6477
- var green22 = terminalStyles22.green;
6478
- var yellow22 = terminalStyles22.yellow;
6479
- var blue22 = terminalStyles22.blue;
6480
- var magenta22 = terminalStyles22.magenta;
6481
- var cyan22 = terminalStyles22.cyan;
6482
- var white22 = terminalStyles22.white;
6483
- var gray22 = terminalStyles22.gray;
6484
- var bgRed22 = terminalStyles22.bgRed;
6485
- var bgYellow22 = terminalStyles22.bgYellow;
6486
- var bgGray2 = terminalStyles22.bgGray;
6487
- var bold22 = terminalStyles22.bold;
6488
- var dim22 = terminalStyles22.dim;
6489
- var italic22 = terminalStyles22.italic;
6490
- var underline22 = terminalStyles22.underline;
6491
- var strikethrough2 = terminalStyles22.strikethrough;
6492
- var reset22 = terminalStyles22.reset;
6493
- var defaultFingersCrossedConfig22 = {
6494
- activationLevel: "error",
6495
- bufferSize: 50,
6496
- flushOnDeactivation: true,
6497
- stopBuffering: false
6498
- };
6499
- var levelIcons22 = {
6500
- debug: "\uD83D\uDD0D",
6501
- info: blue22("\u2139"),
6502
- success: green22("\u2713"),
6503
- warning: bgYellow22(white22(bold22(" WARN "))),
6504
- error: bgRed22(white22(bold22(" ERROR ")))
6505
- };
6506
-
6507
- class Logger22 {
6508
- name;
6509
- fileLocks = new Map;
6510
- currentKeyId = null;
6511
- keys = new Map;
6512
- fingersCrossedConfig;
6513
- fingersCrossedActive = false;
6514
- currentLogFile;
6515
- rotationTimeout;
6516
- keyRotationTimeout;
6517
- encryptionKeys;
6518
- logBuffer = [];
6519
- isActivated = false;
6520
- pendingOperations = [];
6521
- enabled;
6522
- fancy;
6523
- tagFormat;
6524
- timestampPosition;
6525
- environment;
6526
- config;
6527
- options;
6528
- formatter;
6529
- timers = new Set;
6530
- subLoggers = new Set;
6531
- fingersCrossedBuffer = [];
6532
- ANSI_PATTERN = /\u001B\[.*?m/g;
6533
- activeProgressBar = null;
6534
- constructor(name, options = {}) {
6535
- this.name = name;
6536
- this.config = { ...config22 };
6537
- this.options = this.normalizeOptions(options);
6538
- this.formatter = this.options.formatter || new JsonFormatter22;
6539
- this.enabled = options.enabled ?? true;
6540
- this.fancy = options.fancy ?? true;
6541
- this.tagFormat = options.tagFormat ?? { prefix: "[", suffix: "]" };
6542
- this.timestampPosition = options.timestampPosition ?? "right";
6543
- this.environment = options.environment ?? process11.env.APP_ENV ?? "local";
6544
- this.fingersCrossedConfig = this.initializeFingersCrossedConfig(options);
6545
- const configOptions = { ...options };
6546
- const hasTimestamp = options.timestamp !== undefined;
6547
- if (hasTimestamp) {
6548
- delete configOptions.timestamp;
6549
- }
6550
- this.config = {
6551
- ...this.config,
6552
- ...configOptions,
6553
- timestamp: hasTimestamp || this.config.timestamp
6554
- };
6555
- this.currentLogFile = this.generateLogFilename();
6556
- this.encryptionKeys = new Map;
6557
- if (this.validateEncryptionConfig()) {
6558
- this.setupRotation();
6559
- const initialKeyId = this.generateKeyId();
6560
- const initialKey = this.generateKey();
6561
- this.currentKeyId = initialKeyId;
6562
- this.keys.set(initialKeyId, initialKey);
6563
- this.encryptionKeys.set(initialKeyId, {
6564
- key: initialKey,
6565
- createdAt: new Date
6566
- });
6567
- this.setupKeyRotation();
6568
- }
6569
- }
6570
- shouldActivateFingersCrossed(level) {
6571
- if (!this.fingersCrossedConfig)
6572
- return false;
6573
- const levels = {
6574
- debug: 0,
6575
- info: 1,
6576
- success: 2,
6577
- warning: 3,
6578
- error: 4
6579
- };
6580
- const activation = this.fingersCrossedConfig.activationLevel ?? "error";
6581
- return levels[level] >= levels[activation];
6582
- }
6583
- initializeFingersCrossedConfig(options) {
6584
- if (!options.fingersCrossedEnabled && options.fingersCrossed) {
6585
- return {
6586
- ...defaultFingersCrossedConfig22,
6587
- ...options.fingersCrossed
6588
- };
6589
- }
6590
- if (!options.fingersCrossedEnabled) {
6591
- return null;
6592
- }
6593
- if (!options.fingersCrossed) {
6594
- return { ...defaultFingersCrossedConfig22 };
6595
- }
6596
- return {
6597
- ...defaultFingersCrossedConfig22,
6598
- ...options.fingersCrossed
6599
- };
6600
- }
6601
- normalizeOptions(options) {
6602
- const defaultOptions = {
6603
- format: "json",
6604
- level: "info",
6605
- logDirectory: config22.logDirectory,
6606
- rotation: undefined,
6607
- timestamp: undefined,
6608
- fingersCrossed: {},
6609
- enabled: true,
6610
- showTags: false,
6611
- showIcons: true,
6612
- formatter: undefined
6613
- };
6614
- const mergedOptions = {
6615
- ...defaultOptions,
6616
- ...Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined))
6617
- };
6618
- if (!mergedOptions.level || !["debug", "info", "success", "warning", "error"].includes(mergedOptions.level)) {
6619
- mergedOptions.level = defaultOptions.level;
6620
- }
6621
- return mergedOptions;
6622
- }
6623
- shouldWriteToFile() {
6624
- return !isBrowserProcess22() && this.config.writeToFile === true;
6625
- }
6626
- async writeToFile(data) {
6627
- const cancelled = false;
6628
- const operationPromise = (async () => {
6629
- let fd;
6630
- let retries = 0;
6631
- const maxRetries = 3;
6632
- const backoffDelay = 1000;
6633
- while (retries < maxRetries) {
6634
- try {
6635
- try {
6636
- try {
6637
- await access22(this.config.logDirectory, constants22.F_OK | constants22.W_OK);
6638
- } catch (err) {
6639
- if (err instanceof Error && "code" in err) {
6640
- if (err.code === "ENOENT") {
6641
- await mkdir22(this.config.logDirectory, { recursive: true, mode: 493 });
6642
- } else if (err.code === "EACCES") {
6643
- throw new Error(`No write permission for log directory: ${this.config.logDirectory}`);
6644
- } else {
6645
- throw err;
6646
- }
6647
- } else {
6648
- throw err;
6649
- }
6650
- }
6651
- } catch (err) {
6652
- console.error("Debug: [writeToFile] Failed to create log directory:", err);
6653
- throw err;
6654
- }
6655
- if (cancelled)
6656
- throw new Error("Operation cancelled: Logger was destroyed");
6657
- const dataToWrite = this.validateEncryptionConfig() ? (await this.encrypt(data)).encrypted : Buffer22.from(data);
6658
- try {
6659
- if (!existsSync42(this.currentLogFile)) {
6660
- await writeFile22(this.currentLogFile, "", { mode: 420 });
6661
- }
6662
- fd = openSync22(this.currentLogFile, "a", 420);
6663
- writeFileSync42(fd, dataToWrite, { flag: "a" });
6664
- fsyncSync22(fd);
6665
- if (fd !== undefined) {
6666
- closeSync22(fd);
6667
- fd = undefined;
6668
- }
6669
- const stats = await stat22(this.currentLogFile);
6670
- if (stats.size === 0) {
6671
- await writeFile22(this.currentLogFile, dataToWrite, { flag: "w", mode: 420 });
6672
- const retryStats = await stat22(this.currentLogFile);
6673
- if (retryStats.size === 0) {
6674
- throw new Error("File exists but is empty after retry write");
6675
- }
6676
- }
6677
- return;
6678
- } catch (err) {
6679
- const error = err;
6680
- if (error.code && ["ENETDOWN", "ENETUNREACH", "ENOTFOUND", "ETIMEDOUT"].includes(error.code)) {
6681
- if (retries < maxRetries - 1) {
6682
- const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
6683
- console.error(`Network error during write attempt ${retries + 1}/${maxRetries}:`, errorMessage);
6684
- const delay = backoffDelay * 2 ** retries;
6685
- await new Promise((resolve522) => setTimeout(resolve522, delay));
6686
- retries++;
6687
- continue;
6688
- }
6689
- }
6690
- if (error?.code && ["ENOSPC", "EDQUOT"].includes(error.code)) {
6691
- throw new Error(`Disk quota exceeded or no space left on device: ${error.message}`);
6692
- }
6693
- console.error("Debug: [writeToFile] Error writing to file:", error);
6694
- throw error;
6695
- } finally {
6696
- if (fd !== undefined) {
6697
- try {
6698
- closeSync22(fd);
6699
- } catch (err) {
6700
- console.error("Debug: [writeToFile] Error closing file descriptor:", err);
6701
- }
6702
- }
6703
- }
6704
- } catch (err) {
6705
- if (retries === maxRetries - 1) {
6706
- const error = err;
6707
- const errorMessage = typeof error.message === "string" ? error.message : "Unknown error";
6708
- console.error("Debug: [writeToFile] Max retries reached. Final error:", errorMessage);
6709
- throw err;
6710
- }
6711
- retries++;
6712
- const delay = backoffDelay * 2 ** (retries - 1);
6713
- await new Promise((resolve522) => setTimeout(resolve522, delay));
6714
- }
6715
- }
6716
- })();
6717
- this.pendingOperations.push(operationPromise);
6718
- const index = this.pendingOperations.length - 1;
6719
- try {
6720
- await operationPromise;
6721
- } catch (err) {
6722
- console.error("Debug: [writeToFile] Error in operation:", err);
6723
- throw err;
6724
- } finally {
6725
- this.pendingOperations.splice(index, 1);
6726
- }
6727
- }
6728
- generateLogFilename() {
6729
- 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")) {
6730
- return join5(this.config.logDirectory, `${this.name}.log`);
6731
- }
6732
- 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") {
6733
- return join5(this.config.logDirectory, `${this.name}.log`);
6734
- }
6735
- const date = new Date().toISOString().split("T")[0];
6736
- return join5(this.config.logDirectory, `${this.name}-${date}.log`);
6737
- }
6738
- setupRotation() {
6739
- if (isBrowserProcess22())
6740
- return;
6741
- if (!this.shouldWriteToFile())
6742
- return;
6743
- if (typeof this.config.rotation === "boolean")
6744
- return;
6745
- const config32 = this.config.rotation;
6746
- let interval;
6747
- switch (config32.frequency) {
6748
- case "daily":
6749
- interval = 86400000;
6750
- break;
6751
- case "weekly":
6752
- interval = 604800000;
6753
- break;
6754
- case "monthly":
6755
- interval = 2592000000;
6756
- break;
6757
- default:
6758
- return;
6759
- }
6760
- this.rotationTimeout = setInterval(() => {
6761
- this.rotateLog();
6762
- }, interval);
6763
- }
6764
- setupKeyRotation() {
6765
- if (!this.validateEncryptionConfig()) {
6766
- console.error("Invalid encryption configuration detected during key rotation setup");
6767
- return;
6768
- }
6769
- const rotation = this.config.rotation;
6770
- const keyRotation = rotation.keyRotation;
6771
- if (!keyRotation?.enabled) {
6772
- return;
6773
- }
6774
- const rotationInterval = typeof keyRotation.interval === "number" ? keyRotation.interval : 60;
6775
- const interval = Math.max(rotationInterval, 60) * 1000;
6776
- this.keyRotationTimeout = setInterval(() => {
6777
- this.rotateKeys().catch((error) => {
6778
- console.error("Error rotating keys:", error);
6779
- });
6780
- }, interval);
6781
- }
6782
- async rotateKeys() {
6783
- if (!this.validateEncryptionConfig()) {
6784
- console.error("Invalid encryption configuration detected during key rotation");
6785
- return;
6786
- }
6787
- const rotation = this.config.rotation;
6788
- const keyRotation = rotation.keyRotation;
6789
- const newKeyId = this.generateKeyId();
6790
- const newKey = this.generateKey();
6791
- this.currentKeyId = newKeyId;
6792
- this.keys.set(newKeyId, newKey);
6793
- this.encryptionKeys.set(newKeyId, {
6794
- key: newKey,
6795
- createdAt: new Date
6796
- });
6797
- const sortedKeys = Array.from(this.encryptionKeys.entries()).sort(([, a], [, b]) => b.createdAt.getTime() - a.createdAt.getTime());
6798
- const maxKeyCount = typeof keyRotation.maxKeys === "number" ? keyRotation.maxKeys : 1;
6799
- const maxKeys = Math.max(1, maxKeyCount);
6800
- if (sortedKeys.length > maxKeys) {
6801
- for (const [keyId] of sortedKeys.slice(maxKeys)) {
6802
- this.encryptionKeys.delete(keyId);
6803
- this.keys.delete(keyId);
6804
- }
6805
- }
6806
- }
6807
- generateKeyId() {
6808
- return randomBytes22(16).toString("hex");
6809
- }
6810
- generateKey() {
6811
- return randomBytes22(32);
6812
- }
6813
- getCurrentKey() {
6814
- if (!this.currentKeyId) {
6815
- throw new Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");
6816
- }
6817
- const key = this.keys.get(this.currentKeyId);
6818
- if (!key) {
6819
- throw new Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);
6820
- }
6821
- return { key, id: this.currentKeyId };
6822
- }
6823
- encrypt(data) {
6824
- const { key } = this.getCurrentKey();
6825
- const iv = randomBytes22(16);
6826
- const cipher = createCipheriv22("aes-256-gcm", key, iv);
6827
- const input = Buffer22.isBuffer(data) ? data : Buffer22.from(data, "utf8");
6828
- const part1 = cipher.update(input);
6829
- const part2 = cipher.final();
6830
- const totalCipherLen = part1.length + part2.length;
6831
- const authTag = cipher.getAuthTag();
6832
- const out = Buffer22.allocUnsafe(16 + totalCipherLen + 16);
6833
- iv.copy(out, 0);
6834
- part1.copy(out, 16);
6835
- part2.copy(out, 16 + part1.length);
6836
- authTag.copy(out, 16 + totalCipherLen);
6837
- return {
6838
- encrypted: out,
6839
- iv
6840
- };
6841
- }
6842
- async compressData(data) {
6843
- return new Promise((resolve522, reject) => {
6844
- const gzip = createGzip22();
6845
- const chunks = [];
6846
- gzip.on("data", (chunk2) => chunks.push(chunk2));
6847
- gzip.on("end", () => resolve522(Buffer22.from(Buffer22.concat(chunks))));
6848
- gzip.on("error", reject);
6849
- gzip.write(data);
6850
- gzip.end();
6851
- });
6852
- }
6853
- getEncryptionOptions() {
6854
- if (!this.config.rotation || typeof this.config.rotation === "boolean" || !this.config.rotation.encrypt) {
6855
- return {};
6856
- }
6857
- const defaultOptions = {
6858
- algorithm: "aes-256-cbc",
6859
- compress: false
6860
- };
6861
- if (typeof this.config.rotation.encrypt === "object") {
6862
- const encryptConfig = this.config.rotation.encrypt;
6863
- return {
6864
- ...defaultOptions,
6865
- ...encryptConfig
6866
- };
6867
- }
6868
- return defaultOptions;
6869
- }
6870
- async rotateLog() {
6871
- if (isBrowserProcess22())
6872
- return;
6873
- if (!this.shouldWriteToFile())
6874
- return;
6875
- const stats = await stat22(this.currentLogFile).catch(() => null);
6876
- if (!stats)
6877
- return;
6878
- const config32 = this.config.rotation;
6879
- if (typeof config32 === "boolean")
6880
- return;
6881
- if (config32.maxSize && stats.size >= config32.maxSize) {
6882
- const oldFile = this.currentLogFile;
6883
- const newFile = this.generateLogFilename();
6884
- if (this.name.includes("rotation-load-test") || this.name === "failed-rotation-test") {
6885
- const files = await readdir22(this.config.logDirectory);
6886
- const rotatedFiles = files.filter((f) => f.startsWith(this.name) && /\.log\.\d+$/.test(f)).sort((a, b) => {
6887
- const numA = Number.parseInt(a.match(/\.log\.(\d+)$/)?.[1] || "0");
6888
- const numB = Number.parseInt(b.match(/\.log\.(\d+)$/)?.[1] || "0");
6889
- return numB - numA;
6890
- });
6891
- const nextNum = rotatedFiles.length > 0 ? Number.parseInt(rotatedFiles[0].match(/\.log\.(\d+)$/)?.[1] || "0") + 1 : 1;
6892
- const rotatedFile = `${oldFile}.${nextNum}`;
6893
- if (await stat22(oldFile).catch(() => null)) {
6894
- try {
6895
- await rename22(oldFile, rotatedFile);
6896
- if (config32.compress) {
6897
- try {
6898
- const compressedPath = `${rotatedFile}.gz`;
6899
- await this.compressLogFile(rotatedFile, compressedPath);
6900
- await unlink22(rotatedFile);
6901
- } catch (err) {
6902
- console.error("Error compressing rotated file:", err);
6903
- }
6904
- }
6905
- if (rotatedFiles.length === 0 && !files.some((f) => f.endsWith(".log.1"))) {
6906
- try {
6907
- const backupPath = `${oldFile}.1`;
6908
- await writeFile22(backupPath, "");
6909
- } catch (err) {
6910
- console.error("Error creating backup file:", err);
6911
- }
6912
- }
6913
- } catch (err) {
6914
- console.error(`Error during rotation: ${err instanceof Error ? err.message : String(err)}`);
6915
- }
6916
- }
6917
- } else {
6918
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
6919
- const rotatedFile = oldFile.replace(/\.log$/, `-${timestamp}.log`);
6920
- if (await stat22(oldFile).catch(() => null)) {
6921
- await rename22(oldFile, rotatedFile);
6922
- }
6923
- }
6924
- this.currentLogFile = newFile;
6925
- if (config32.maxFiles) {
6926
- const files = await readdir22(this.config.logDirectory);
6927
- const logFiles = files.filter((f) => f.startsWith(this.name)).sort((a, b) => b.localeCompare(a));
6928
- for (const file of logFiles.slice(config32.maxFiles)) {
6929
- await unlink22(join5(this.config.logDirectory, file));
6930
- }
6931
- }
6932
- }
6933
- }
6934
- async compressLogFile(inputPath, outputPath) {
6935
- const readStream = createReadStream22(inputPath);
6936
- const writeStream = createWriteStream22(outputPath);
6937
- const gzip = createGzip22();
6938
- await pipeline22(readStream, gzip, writeStream);
6939
- }
6940
- async handleFingersCrossedBuffer(level, formattedEntry) {
6941
- if (!this.fingersCrossedConfig)
6942
- return;
6943
- if (this.shouldActivateFingersCrossed(level) && !this.isActivated) {
6944
- this.isActivated = true;
6945
- for (const entry of this.logBuffer) {
6946
- const formattedBufferedEntry = await this.formatter.format(entry);
6947
- if (this.shouldWriteToFile())
6948
- await this.writeToFile(formattedBufferedEntry);
6949
- console.log(formattedBufferedEntry);
6950
- }
6951
- if (this.fingersCrossedConfig.stopBuffering)
6952
- this.logBuffer = [];
6953
- }
6954
- if (this.isActivated) {
6955
- if (this.shouldWriteToFile())
6956
- await this.writeToFile(formattedEntry);
6957
- console.log(formattedEntry);
6958
- }
6959
- }
6960
- shouldLog(level) {
6961
- if (!this.enabled)
6962
- return false;
6963
- const levels = {
6964
- debug: 0,
6965
- info: 1,
6966
- success: 2,
6967
- warning: 3,
6968
- error: 4
6969
- };
6970
- return levels[level] >= levels[this.config.level];
6971
- }
6972
- async flushPendingWrites() {
6973
- await Promise.all(this.pendingOperations.map((op) => {
6974
- if (op instanceof Promise) {
6975
- return op.catch((err) => {
6976
- console.error("Error in pending write operation:", err);
6977
- });
6978
- }
6979
- return Promise.resolve();
6980
- }));
6981
- if (existsSync42(this.currentLogFile)) {
6982
- try {
6983
- const fd = openSync22(this.currentLogFile, "r+");
6984
- fsyncSync22(fd);
6985
- closeSync22(fd);
6986
- } catch (error) {
6987
- console.error(`Error flushing file: ${error}`);
6988
- }
6989
- }
6990
- }
6991
- async destroy() {
6992
- if (this.rotationTimeout)
6993
- clearInterval(this.rotationTimeout);
6994
- if (this.keyRotationTimeout)
6995
- clearInterval(this.keyRotationTimeout);
6996
- this.timers.clear();
6997
- for (const op of this.pendingOperations) {
6998
- if (typeof op.cancel === "function") {
6999
- op.cancel();
7000
- }
7001
- }
7002
- return (async () => {
7003
- if (this.pendingOperations.length > 0) {
7004
- try {
7005
- await Promise.allSettled(this.pendingOperations);
7006
- } catch (err) {
7007
- console.error("Error waiting for pending operations:", err);
7008
- }
7009
- }
7010
- if (!isBrowserProcess22() && this.config.rotation && typeof this.config.rotation !== "boolean" && this.config.rotation.compress) {
7011
- try {
7012
- const files = await readdir22(this.config.logDirectory);
7013
- const tempFiles = files.filter((f) => (f.includes("temp") || f.includes(".tmp")) && f.includes(this.name));
7014
- for (const tempFile of tempFiles) {
7015
- try {
7016
- await unlink22(join5(this.config.logDirectory, tempFile));
7017
- } catch (err) {
7018
- console.error(`Failed to delete temp file ${tempFile}:`, err);
7019
- }
7020
- }
7021
- } catch (err) {
7022
- console.error("Error cleaning up temporary files:", err);
7023
- }
7024
- }
7025
- })();
7026
- }
7027
- getCurrentLogFilePath() {
7028
- return this.currentLogFile;
7029
- }
7030
- formatTag(name) {
7031
- if (!name)
7032
- return "";
7033
- return `${this.tagFormat.prefix}${name}${this.tagFormat.suffix}`;
7034
- }
7035
- formatFileTimestamp(date) {
7036
- return `[${date.toISOString()}]`;
7037
- }
7038
- formatConsoleTimestamp(date) {
7039
- return this.shouldStyleConsole() ? styles22.gray(date.toLocaleTimeString()) : date.toLocaleTimeString();
7040
- }
7041
- shouldStyleConsole() {
7042
- if (!this.fancy || isBrowserProcess22())
7043
- return false;
7044
- const noColor = typeof process11.env.NO_COLOR !== "undefined";
7045
- const forceColorDisabled = process11.env.FORCE_COLOR === "0";
7046
- if (noColor || forceColorDisabled)
7047
- return false;
7048
- const hasTTY = typeof process11.stderr !== "undefined" && process11.stderr.isTTY || typeof process11.stdout !== "undefined" && process11.stdout.isTTY;
7049
- return !!hasTTY;
7050
- }
7051
- formatConsoleMessage(parts) {
7052
- const { timestamp, icon = "", tag = "", message, level, showTimestamp = true } = parts;
7053
- const stripAnsi = (str) => str.replace(this.ANSI_PATTERN, "");
7054
- if (!this.fancy) {
7055
- const components = [];
7056
- if (showTimestamp)
7057
- components.push(timestamp);
7058
- if (level === "warning")
7059
- components.push("WARN");
7060
- else if (level === "error")
7061
- components.push("ERROR");
7062
- else if (icon)
7063
- components.push(icon.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu, ""));
7064
- if (tag)
7065
- components.push(tag.replace(/[[\]]/g, ""));
7066
- components.push(message);
7067
- return components.join(" ");
7068
- }
7069
- const terminalWidth = process11.stdout.columns || 120;
7070
- let mainPart = "";
7071
- if (level === "warning" || level === "error") {
7072
- mainPart = `${icon} ${message}`;
7073
- } else if (level === "info" || level === "success") {
7074
- mainPart = `${icon} ${tag} ${message}`;
7075
- } else {
7076
- mainPart = `${icon} ${tag} ${styles22.cyan(message)}`;
7077
- }
7078
- if (!showTimestamp) {
7079
- return mainPart.trim();
7080
- }
7081
- const visibleMainPartLength = stripAnsi(mainPart).trim().length;
7082
- const visibleTimestampLength = stripAnsi(timestamp).length;
7083
- const padding = Math.max(1, terminalWidth - 2 - visibleMainPartLength - visibleTimestampLength);
7084
- return `${mainPart.trim()}${" ".repeat(padding)}${timestamp}`;
7085
- }
7086
- formatMessage(message, args) {
7087
- if (args.length === 1 && Array.isArray(args[0])) {
7088
- return message.replace(/\{(\d+)\}/g, (match, index) => {
7089
- const position = Number.parseInt(index, 10);
7090
- return position < args[0].length ? String(args[0][position]) : match;
7091
- });
7092
- }
7093
- const formatRegex = /%([sdijfo%])/g;
7094
- let argIndex = 0;
7095
- let formattedMessage = message.replace(formatRegex, (match, type) => {
7096
- if (type === "%")
7097
- return "%";
7098
- if (argIndex >= args.length)
7099
- return match;
7100
- const arg = args[argIndex++];
7101
- switch (type) {
7102
- case "s":
7103
- return String(arg);
7104
- case "d":
7105
- case "i":
7106
- return Number(arg).toString();
7107
- case "j":
7108
- case "o":
7109
- return JSON.stringify(arg, null, 2);
7110
- default:
7111
- return match;
7112
- }
7113
- });
7114
- if (argIndex < args.length) {
7115
- formattedMessage += ` ${args.slice(argIndex).map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ")}`;
7116
- }
7117
- return formattedMessage;
7118
- }
7119
- formatMarkdown(input) {
7120
- if (!input)
7121
- return input;
7122
- let out = input;
7123
- out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, text, url) => {
7124
- const label = styles22.underline(styles22.blue(text));
7125
- const absFile = this.toAbsoluteFilePath(url);
7126
- if (absFile && this.shouldStyleConsole() && this.supportsHyperlinks()) {
7127
- const href = `file://${encodeURI(absFile)}`;
7128
- const OSC = "\x1B]8;;";
7129
- const ST = "\x1B\\";
7130
- return `${OSC}${href}${ST}${label}${OSC}${ST}`;
7131
- }
7132
- if (this.shouldStyleConsole() && this.supportsHyperlinks()) {
7133
- const OSC = "\x1B]8;;";
7134
- const ST = "\x1B\\";
7135
- return `${OSC}${url}${ST}${label}${OSC}${ST}`;
7136
- }
7137
- return label;
7138
- });
7139
- out = out.replace(/`([^`]+)`/g, (_, m) => styles22.bgGray(m));
7140
- out = out.replace(/\*\*([^*]+)\*\*/g, (_, m) => styles22.bold(m));
7141
- out = out.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, (_, m) => styles22.italic(m));
7142
- out = out.replace(/(?<!_)_([^_]+)_(?!_)/g, (_, m) => styles22.italic(m));
7143
- out = out.replace(/~([^~]+)~/g, (_, m) => styles22.strikethrough(m));
7144
- return out;
7145
- }
7146
- supportsHyperlinks() {
7147
- if (isBrowserProcess22())
7148
- return false;
7149
- const env = process11.env;
7150
- if (!env)
7151
- return false;
7152
- if (env.TERM_PROGRAM === "iTerm.app" || env.TERM_PROGRAM === "vscode" || env.TERM_PROGRAM === "WezTerm")
7153
- return true;
7154
- if (env.WT_SESSION)
7155
- return true;
7156
- if (env.TERM === "xterm-kitty")
7157
- return true;
7158
- const vte = env.VTE_VERSION ? Number.parseInt(env.VTE_VERSION, 10) : 0;
7159
- if (!Number.isNaN(vte) && vte >= 5000)
7160
- return true;
7161
- return false;
7162
- }
7163
- toAbsoluteFilePath(input) {
7164
- try {
7165
- let p = input;
7166
- if (p.startsWith("file://")) {
7167
- p = p.replace(/^file:\/\//, "");
7168
- }
7169
- if (p.startsWith("~")) {
7170
- const home = process11.env.HOME || "";
7171
- if (home)
7172
- p = p.replace(/^~(?=$|\/)/, home);
7173
- }
7174
- if (isAbsolute2(p) || p.startsWith("./") || p.startsWith("../")) {
7175
- p = resolve62(p);
7176
- } else {
7177
- return null;
7178
- }
7179
- return existsSync42(p) ? p : null;
7180
- } catch {
7181
- return null;
7182
- }
7183
- }
7184
- buildOutputTexts(input) {
7185
- const consoleText = this.shouldStyleConsole() ? this.formatMarkdown(input) : input;
7186
- const fileText = input.replace(this.ANSI_PATTERN, "");
7187
- return { consoleText, fileText };
7188
- }
7189
- async log(level, message, ...args) {
7190
- const timestamp = new Date;
7191
- const consoleTime = this.formatConsoleTimestamp(timestamp);
7192
- const fileTime = this.formatFileTimestamp(timestamp);
7193
- let formattedMessage;
7194
- let errorStack;
7195
- if (message instanceof Error) {
7196
- formattedMessage = message.message;
7197
- errorStack = message.stack;
7198
- } else {
7199
- formattedMessage = this.formatMessage(message, args);
7200
- }
7201
- const { consoleText: baseConsoleText, fileText } = this.buildOutputTexts(formattedMessage);
7202
- if (this.shouldStyleConsole()) {
7203
- const icon = this.options.showIcons === false ? "" : levelIcons22[level];
7204
- const tag = this.options.showTags !== false && this.name ? styles22.gray(this.formatTag(this.name)) : "";
7205
- let consoleMessage;
7206
- switch (level) {
7207
- case "debug":
7208
- consoleMessage = this.formatConsoleMessage({
7209
- timestamp: consoleTime,
7210
- icon,
7211
- tag,
7212
- message: styles22.gray(baseConsoleText),
7213
- level
7214
- });
7215
- console.error(consoleMessage);
7216
- break;
7217
- case "info":
7218
- consoleMessage = this.formatConsoleMessage({
7219
- timestamp: consoleTime,
7220
- icon,
7221
- tag,
7222
- message: baseConsoleText,
7223
- level
7224
- });
7225
- console.warn(consoleMessage);
7226
- break;
7227
- case "success":
7228
- consoleMessage = this.formatConsoleMessage({
7229
- timestamp: consoleTime,
7230
- icon,
7231
- tag,
7232
- message: styles22.green(baseConsoleText),
7233
- level
7234
- });
7235
- console.error(consoleMessage);
7236
- break;
7237
- case "warning":
7238
- consoleMessage = this.formatConsoleMessage({
7239
- timestamp: consoleTime,
7240
- icon,
7241
- tag,
7242
- message: baseConsoleText,
7243
- level
7244
- });
7245
- console.warn(consoleMessage);
7246
- break;
7247
- case "error":
7248
- consoleMessage = this.formatConsoleMessage({
7249
- timestamp: consoleTime,
7250
- icon,
7251
- tag,
7252
- message: baseConsoleText,
7253
- level
7254
- });
7255
- console.error(consoleMessage);
7256
- if (errorStack) {
7257
- const stackLines = errorStack.split(`
7258
- `);
7259
- for (const line of stackLines) {
7260
- if (line.trim() && !line.includes(formattedMessage)) {
7261
- console.error(this.formatConsoleMessage({
7262
- timestamp: consoleTime,
7263
- message: styles22.gray(` ${line}`),
7264
- level,
7265
- showTimestamp: false
7266
- }));
7267
- }
7268
- }
7269
- }
7270
- break;
7271
- }
7272
- } else if (!isBrowserProcess22()) {
7273
- console.error(`${fileTime} ${this.environment}.${level.toUpperCase()}: ${formattedMessage}`);
7274
- if (errorStack) {
7275
- console.error(errorStack);
7276
- }
7277
- }
7278
- if (!this.shouldLog(level))
7279
- return;
7280
- let logEntry = `${fileTime} ${this.environment}.${level.toUpperCase()}: ${fileText}
7281
- `;
7282
- if (errorStack) {
7283
- logEntry += `${errorStack}
7284
- `;
7285
- }
7286
- logEntry = logEntry.replace(this.ANSI_PATTERN, "");
7287
- if (this.shouldWriteToFile())
7288
- await this.writeToFile(logEntry);
7289
- }
7290
- progress(total, initialMessage = "") {
7291
- const noop = {
7292
- update: (_current, _message) => {},
7293
- finish: (_message) => {},
7294
- interrupt: (_message, _level) => {}
7295
- };
7296
- if (!this.enabled)
7297
- return noop;
7298
- const barLength = 30;
7299
- this.activeProgressBar = {
7300
- total: Math.max(1, total || 1),
7301
- current: 0,
7302
- message: initialMessage || "",
7303
- barLength,
7304
- lastRenderedLine: ""
7305
- };
7306
- if (this.shouldStyleConsole() && !isBrowserProcess22() && process11.stdout.isTTY) {
7307
- this.renderProgressBar(this.activeProgressBar);
7308
- }
7309
- const update = (current, message) => {
7310
- if (!this.enabled || !this.activeProgressBar)
7311
- return;
7312
- this.activeProgressBar.current = Math.min(Math.max(0, current), this.activeProgressBar.total);
7313
- if (message !== undefined)
7314
- this.activeProgressBar.message = message;
7315
- if (this.shouldStyleConsole() && !isBrowserProcess22() && process11.stdout.isTTY)
7316
- this.renderProgressBar(this.activeProgressBar);
7317
- };
7318
- const finish = (message) => {
7319
- if (!this.activeProgressBar)
7320
- return;
7321
- this.finishProgressBar(this.activeProgressBar, message);
7322
- };
7323
- const interrupt = (message, level = "info") => {
7324
- if (!isBrowserProcess22() && process11.stdout.isTTY)
7325
- process11.stdout.write(`
7326
- `);
7327
- const method = level === "warning" ? "warn" : level;
7328
- this[method](message);
7329
- if (this.activeProgressBar && this.shouldStyleConsole() && !isBrowserProcess22() && process11.stdout.isTTY)
7330
- this.renderProgressBar(this.activeProgressBar);
7331
- };
7332
- return { update, finish, interrupt };
7333
- }
7334
- time(label) {
7335
- const start = performance.now();
7336
- if (this.shouldStyleConsole()) {
7337
- const tag = this.options.showTags !== false && this.name ? styles22.gray(this.formatTag(this.name)) : "";
7338
- const consoleTime = this.formatConsoleTimestamp(new Date);
7339
- console.error(this.formatConsoleMessage({
7340
- timestamp: consoleTime,
7341
- icon: this.options.showIcons === false ? "" : styles22.blue("\u25D0"),
7342
- tag,
7343
- message: `${styles22.cyan(label)}...`
7344
- }));
7345
- }
7346
- return async (metadata) => {
7347
- if (!this.enabled)
7348
- return;
7349
- const end = performance.now();
7350
- const elapsed = Math.round(end - start);
7351
- const completionMessage = `${label} completed in ${elapsed}ms`;
7352
- const timestamp = new Date;
7353
- const consoleTime = this.formatConsoleTimestamp(timestamp);
7354
- const fileTime = this.formatFileTimestamp(timestamp);
7355
- let logEntry = `${fileTime} ${this.environment}.INFO: ${completionMessage}`;
7356
- if (metadata) {
7357
- logEntry += ` ${JSON.stringify(metadata)}`;
7358
- }
7359
- logEntry += `
7360
- `;
7361
- logEntry = logEntry.replace(this.ANSI_PATTERN, "");
7362
- if (this.shouldStyleConsole()) {
7363
- const tag = this.options.showTags !== false && this.name ? styles22.gray(this.formatTag(this.name)) : "";
7364
- console.error(this.formatConsoleMessage({
7365
- timestamp: consoleTime,
7366
- icon: this.options.showIcons === false ? "" : styles22.green("\u2713"),
7367
- tag,
7368
- message: `${completionMessage}${metadata ? ` ${JSON.stringify(metadata)}` : ""}`
7369
- }));
7370
- } else if (!isBrowserProcess22()) {
7371
- console.error(logEntry.trim());
7372
- }
7373
- if (this.shouldWriteToFile())
7374
- await this.writeToFile(logEntry);
7375
- };
7376
- }
7377
- async debug(message, ...args) {
7378
- await this.log("debug", message, ...args);
7379
- }
7380
- async info(message, ...args) {
7381
- await this.log("info", message, ...args);
7382
- }
7383
- async success(message, ...args) {
7384
- await this.log("success", message, ...args);
7385
- }
7386
- async warn(message, ...args) {
7387
- await this.log("warning", message, ...args);
7388
- }
7389
- async error(message, ...args) {
7390
- await this.log("error", message, ...args);
7391
- }
7392
- validateEncryptionConfig() {
7393
- if (!this.config.rotation)
7394
- return false;
7395
- if (typeof this.config.rotation === "boolean")
7396
- return false;
7397
- const rotation = this.config.rotation;
7398
- const { encrypt } = rotation;
7399
- return !!encrypt;
7400
- }
7401
- async only(fn) {
7402
- if (!this.enabled)
7403
- return;
7404
- return await fn();
7405
- }
7406
- isEnabled() {
7407
- return this.enabled;
7408
- }
7409
- setEnabled(enabled) {
7410
- this.enabled = enabled;
7411
- }
7412
- extend(namespace) {
7413
- const childName = `${this.name}:${namespace}`;
7414
- const childLogger = new Logger22(childName, {
7415
- ...this.options,
7416
- logDirectory: this.config.logDirectory,
7417
- level: this.config.level,
7418
- format: this.config.format,
7419
- rotation: typeof this.config.rotation === "boolean" ? undefined : this.config.rotation,
7420
- timestamp: typeof this.config.timestamp === "boolean" ? undefined : this.config.timestamp
7421
- });
7422
- this.subLoggers.add(childLogger);
7423
- return childLogger;
7424
- }
7425
- createReadStream() {
7426
- if (isBrowserProcess22())
7427
- throw new Error("createReadStream is not supported in browser environments");
7428
- if (!existsSync42(this.currentLogFile))
7429
- throw new Error(`Log file does not exist: ${this.currentLogFile}`);
7430
- return createReadStream22(this.currentLogFile, { encoding: "utf8" });
7431
- }
7432
- async decrypt(data) {
7433
- if (!this.validateEncryptionConfig())
7434
- throw new Error("Encryption is not configured");
7435
- const encryptionConfig = this.config.rotation;
7436
- if (!encryptionConfig.encrypt || typeof encryptionConfig.encrypt === "boolean")
7437
- throw new Error("Invalid encryption configuration");
7438
- if (!this.currentKeyId || !this.keys.has(this.currentKeyId))
7439
- throw new Error("No valid encryption key available");
7440
- const key = this.keys.get(this.currentKeyId);
7441
- try {
7442
- const encryptedData = Buffer22.isBuffer(data) ? data : Buffer22.from(data, "base64");
7443
- const iv = encryptedData.subarray(0, 16);
7444
- const authTag = encryptedData.subarray(encryptedData.length - 16);
7445
- const ciphertext = encryptedData.subarray(16, encryptedData.length - 16);
7446
- const decipher = createDecipheriv22("aes-256-gcm", key, iv);
7447
- decipher.setAuthTag(authTag);
7448
- const d1 = decipher.update(ciphertext);
7449
- const d2 = decipher.final();
7450
- const totalLen = d1.length + d2.length;
7451
- const out = Buffer22.allocUnsafe(totalLen);
7452
- d1.copy(out, 0);
7453
- d2.copy(out, d1.length);
7454
- return out.toString("utf8");
7455
- } catch (err) {
7456
- throw new Error(`Decryption failed: ${err instanceof Error ? err.message : String(err)}`);
7457
- }
7458
- }
7459
- getLevel() {
7460
- return this.config.level;
7461
- }
7462
- getLogDirectory() {
7463
- return this.config.logDirectory;
7464
- }
7465
- getFormat() {
7466
- return this.config.format;
7467
- }
7468
- getRotationConfig() {
7469
- return this.config.rotation;
7470
- }
7471
- isBrowserMode() {
7472
- return isBrowserProcess22();
7473
- }
7474
- isServerMode() {
7475
- return !isBrowserProcess22();
7476
- }
7477
- setTestEncryptionKey(keyId, key) {
7478
- this.currentKeyId = keyId;
7479
- this.keys.set(keyId, key);
7480
- }
7481
- getTestCurrentKey() {
7482
- if (!this.currentKeyId || !this.keys.has(this.currentKeyId)) {
7483
- return null;
7484
- }
7485
- return {
7486
- id: this.currentKeyId,
7487
- key: this.keys.get(this.currentKeyId)
7488
- };
7489
- }
7490
- getConfig() {
7491
- return this.config;
7492
- }
7493
- async box(message) {
7494
- if (!this.enabled)
7495
- return;
7496
- const timestamp = new Date;
7497
- const consoleTime = this.formatConsoleTimestamp(timestamp);
7498
- const fileTime = this.formatFileTimestamp(timestamp);
7499
- const { consoleText, fileText } = this.buildOutputTexts(message);
7500
- if (this.shouldStyleConsole()) {
7501
- const lines = consoleText.split(`
7502
- `);
7503
- const width = Math.max(...lines.map((line) => line.length)) + 2;
7504
- const top = `\u250C${"\u2500".repeat(width)}\u2510`;
7505
- const bottom = `\u2514${"\u2500".repeat(width)}\u2518`;
7506
- const boxedLines = lines.map((line) => {
7507
- return this.formatConsoleMessage({
7508
- timestamp: consoleTime,
7509
- message: styles22.cyan(line),
7510
- showTimestamp: false
7511
- });
7512
- });
7513
- console.error(this.formatConsoleMessage({
7514
- timestamp: consoleTime,
7515
- message: styles22.cyan(top),
7516
- showTimestamp: false
7517
- }));
7518
- boxedLines.forEach((line) => console.error(line));
7519
- console.error(this.formatConsoleMessage({
7520
- timestamp: consoleTime,
7521
- message: styles22.cyan(bottom),
7522
- showTimestamp: false
7523
- }));
7524
- } else if (!isBrowserProcess22()) {
7525
- console.error(`${fileTime} ${this.environment}.INFO: [BOX] ${fileText}`);
7526
- }
7527
- const logEntry = `${fileTime} ${this.environment}.INFO: [BOX] ${fileText}
7528
- `.replace(this.ANSI_PATTERN, "");
7529
- if (this.shouldWriteToFile())
7530
- await this.writeToFile(logEntry);
7531
- }
7532
- async prompt(message) {
7533
- if (isBrowserProcess22()) {
7534
- return Promise.resolve(true);
7535
- }
7536
- return new Promise((resolve522) => {
7537
- console.error(`${styles22.cyan("?")} ${message} (y/n) `);
7538
- const onData = (data) => {
7539
- const input = data.toString().trim().toLowerCase();
7540
- process11.stdin.removeListener("data", onData);
7541
- try {
7542
- if (typeof process11.stdin.setRawMode === "function") {
7543
- process11.stdin.setRawMode(false);
7544
- }
7545
- } catch {}
7546
- process11.stdin.pause();
7547
- console.error("");
7548
- resolve522(input === "y" || input === "yes");
7549
- };
7550
- try {
7551
- if (typeof process11.stdin.setRawMode === "function") {
7552
- process11.stdin.setRawMode(true);
7553
- }
7554
- } catch {}
7555
- process11.stdin.resume();
7556
- process11.stdin.once("data", onData);
7557
- });
7558
- }
7559
- setFancy(enabled) {
7560
- this.fancy = enabled;
7561
- }
7562
- isFancy() {
7563
- return this.fancy;
7564
- }
7565
- pause() {
7566
- this.enabled = false;
7567
- }
7568
- resume() {
7569
- this.enabled = true;
7570
- }
7571
- async start(message, ...args) {
7572
- if (!this.enabled)
7573
- return;
7574
- let formattedMessage = message;
7575
- if (args && args.length > 0) {
7576
- const formatRegex = /%([sdijfo%])/g;
7577
- let argIndex = 0;
7578
- formattedMessage = message.replace(formatRegex, (match, type) => {
7579
- if (type === "%")
7580
- return "%";
7581
- if (argIndex >= args.length)
7582
- return match;
7583
- const arg = args[argIndex++];
7584
- switch (type) {
7585
- case "s":
7586
- return String(arg);
7587
- case "d":
7588
- case "i":
7589
- return Number(arg).toString();
7590
- case "j":
7591
- case "o":
7592
- return JSON.stringify(arg, null, 2);
7593
- default:
7594
- return match;
7595
- }
6139
+ };
6140
+ PluginError2 = class PluginError22 extends BunfigError2 {
6141
+ code = "PLUGIN_ERROR";
6142
+ constructor(pluginName, operation, cause) {
6143
+ super(`Plugin "${pluginName}" failed during ${operation}: ${cause.message}`, {
6144
+ pluginName,
6145
+ operation,
6146
+ originalError: cause.name,
6147
+ originalMessage: cause.message
7596
6148
  });
7597
- if (argIndex < args.length) {
7598
- formattedMessage += ` ${args.slice(argIndex).map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ")}`;
7599
- }
7600
- }
7601
- const { consoleText, fileText } = this.buildOutputTexts(formattedMessage);
7602
- if (this.shouldStyleConsole()) {
7603
- const tag = this.options.showTags !== false && this.name ? styles22.gray(this.formatTag(this.name)) : "";
7604
- const spinnerPrefix = this.options.showIcons === false ? "" : `${styles22.blue("\u25D0")} `;
7605
- console.error(`${spinnerPrefix}${tag} ${styles22.cyan(consoleText)}`);
7606
- }
7607
- const timestamp = new Date;
7608
- const formattedDate = timestamp.toISOString();
7609
- const logEntry = `[${formattedDate}] ${this.environment}.INFO: [START] ${fileText}
7610
- `.replace(this.ANSI_PATTERN, "");
7611
- if (this.shouldWriteToFile())
7612
- await this.writeToFile(logEntry);
7613
- }
7614
- renderProgressBar(barState, isFinished = false) {
7615
- if (!this.enabled || !this.shouldStyleConsole() || !process11.stdout.isTTY)
7616
- return;
7617
- const percent = Math.min(100, Math.max(0, Math.round(barState.current / barState.total * 100)));
7618
- const filledLength = Math.round(barState.barLength * percent / 100);
7619
- const emptyLength = barState.barLength - filledLength;
7620
- const filledBar = styles22.green("\u2501".repeat(filledLength));
7621
- const emptyBar = styles22.gray("\u2501".repeat(emptyLength));
7622
- const bar = `[${filledBar}${emptyBar}]`;
7623
- const percentageText = `${percent}%`.padStart(4);
7624
- const messageText = barState.message ? ` ${barState.message}` : "";
7625
- const icon = this.options.showIcons === false ? "" : isFinished || percent === 100 ? styles22.green("\u2713") : styles22.blue("\u25B6");
7626
- const tag = this.options.showTags !== false && this.name ? ` ${styles22.gray(this.formatTag(this.name))}` : "";
7627
- const line = `\r${icon}${tag} ${bar} ${percentageText}${messageText}`;
7628
- const terminalWidth = process11.stdout.columns || 80;
7629
- const clearLine = " ".repeat(Math.max(0, terminalWidth - line.replace(this.ANSI_PATTERN, "").length));
7630
- barState.lastRenderedLine = `${line}${clearLine}`;
7631
- process11.stdout.write(barState.lastRenderedLine);
7632
- if (isFinished) {
7633
- process11.stdout.write(`
7634
- `);
7635
- }
7636
- }
7637
- finishProgressBar(barState, finalMessage) {
7638
- if (!this.enabled || !this.fancy || isBrowserProcess22() || !process11.stdout.isTTY) {
7639
- this.activeProgressBar = null;
7640
- return;
7641
- }
7642
- if (barState.current < barState.total) {
7643
- barState.current = barState.total;
7644
- }
7645
- if (finalMessage)
7646
- barState.message = finalMessage;
7647
- this.renderProgressBar(barState, true);
7648
- this.activeProgressBar = null;
7649
- }
7650
- async clear(filters = {}) {
7651
- if (isBrowserProcess22()) {
7652
- console.warn("Log clearing is not supported in browser environments.");
7653
- return;
7654
- }
7655
- try {
7656
- console.warn("Clearing logs...", this.config.logDirectory);
7657
- const files = await readdir22(this.config.logDirectory);
7658
- const logFilesToDelete = [];
7659
- for (const file of files) {
7660
- const nameMatches = filters.name ? new RegExp(filters.name.replace("*", ".*")).test(file) : file.startsWith(this.name);
7661
- if (!nameMatches || !file.endsWith(".log")) {
7662
- continue;
7663
- }
7664
- const filePath = join5(this.config.logDirectory, file);
7665
- if (filters.before) {
7666
- try {
7667
- const fileStats = await stat22(filePath);
7668
- if (fileStats.mtime >= filters.before) {
7669
- continue;
7670
- }
7671
- } catch (statErr) {
7672
- console.error(`Failed to get stats for file ${filePath}:`, statErr);
7673
- continue;
7674
- }
7675
- }
7676
- logFilesToDelete.push(filePath);
7677
- }
7678
- if (logFilesToDelete.length === 0) {
7679
- console.warn("No log files matched the criteria for clearing.");
7680
- return;
7681
- }
7682
- console.warn(`Preparing to delete ${logFilesToDelete.length} log file(s)...`);
7683
- for (const filePath of logFilesToDelete) {
7684
- try {
7685
- await unlink22(filePath);
7686
- console.warn(`Deleted log file: ${filePath}`);
7687
- } catch (unlinkErr) {
7688
- console.error(`Failed to delete log file ${filePath}:`, unlinkErr);
7689
- }
7690
- }
7691
- console.warn("Log clearing process finished.");
7692
- } catch (err) {
7693
- console.error("Error during log clearing process:", err);
7694
- }
7695
- }
7696
- }
7697
- var logger22 = new Logger22("stacks");
7698
-
7699
- class BunfigError2 extends Error {
7700
- timestamp;
7701
- context;
7702
- constructor(message, context = {}) {
7703
- super(message);
7704
- this.name = this.constructor.name;
7705
- this.timestamp = new Date;
7706
- this.context = context;
7707
- if (Error.captureStackTrace) {
7708
- Error.captureStackTrace(this, this.constructor);
7709
- }
7710
- }
7711
- toJSON() {
7712
- return {
7713
- name: this.name,
7714
- code: this.code,
7715
- message: this.message,
7716
- timestamp: this.timestamp.toISOString(),
7717
- context: this.context,
7718
- stack: this.stack
7719
- };
7720
- }
7721
- toString() {
7722
- const contextStr = Object.keys(this.context).length > 0 ? ` (${Object.entries(this.context).map(([k, v]) => `${k}: ${v}`).join(", ")})` : "";
7723
- return `${this.name} [${this.code}]: ${this.message}${contextStr}`;
7724
- }
7725
- }
7726
-
7727
- class ConfigNotFoundError2 extends BunfigError2 {
7728
- code = "CONFIG_NOT_FOUND";
7729
- constructor(configName, searchPaths, alias) {
7730
- const aliasStr = alias ? ` or alias "${alias}"` : "";
7731
- super(`Configuration "${configName}"${aliasStr} not found`, {
7732
- configName,
7733
- alias,
7734
- searchPaths,
7735
- searchPathCount: searchPaths.length
7736
- });
7737
- }
7738
- }
7739
-
7740
- class ConfigLoadError2 extends BunfigError2 {
7741
- code = "CONFIG_LOAD_ERROR";
7742
- constructor(configPath, cause, configName) {
7743
- super(`Failed to load configuration from "${configPath}": ${cause.message}`, {
7744
- configPath,
7745
- configName,
7746
- originalError: cause.name,
7747
- originalMessage: cause.message
7748
- });
7749
- this.cause = cause;
7750
- }
7751
- }
7752
-
7753
- class ConfigValidationError2 extends BunfigError2 {
7754
- code = "CONFIG_VALIDATION_ERROR";
7755
- constructor(configPath, validationErrors, configName) {
7756
- super(`Configuration validation failed for "${configPath}"`, {
7757
- configPath,
7758
- configName,
7759
- validationErrors,
7760
- errorCount: validationErrors.length
7761
- });
7762
- }
7763
- }
7764
-
7765
- class ConfigMergeError2 extends BunfigError2 {
7766
- code = "CONFIG_MERGE_ERROR";
7767
- constructor(sourcePath, targetPath, cause, configName) {
7768
- super(`Failed to merge configuration from "${sourcePath}" with "${targetPath}": ${cause.message}`, {
7769
- sourcePath,
7770
- targetPath,
7771
- configName,
7772
- originalError: cause.name,
7773
- originalMessage: cause.message
7774
- });
7775
- this.cause = cause;
7776
- }
7777
- }
7778
-
7779
- class EnvVarError2 extends BunfigError2 {
7780
- code = "ENV_VAR_ERROR";
7781
- constructor(envKey, envValue, expectedType, configName) {
7782
- super(`Failed to parse environment variable "${envKey}" with value "${envValue}" as ${expectedType}`, {
7783
- envKey,
7784
- envValue,
7785
- expectedType,
7786
- configName
7787
- });
7788
- }
7789
- }
7790
-
7791
- class FileSystemError2 extends BunfigError2 {
7792
- code = "FILE_SYSTEM_ERROR";
7793
- constructor(operation, path, cause) {
7794
- super(`File system ${operation} failed for "${path}": ${cause.message}`, {
7795
- operation,
7796
- path,
7797
- originalError: cause.name,
7798
- originalMessage: cause.message
7799
- });
7800
- this.cause = cause;
7801
- }
7802
- }
7803
-
7804
- class TypeGenerationError2 extends BunfigError2 {
7805
- code = "TYPE_GENERATION_ERROR";
7806
- constructor(configDir, outputPath, cause) {
7807
- super(`Failed to generate types from "${configDir}" to "${outputPath}": ${cause.message}`, {
7808
- configDir,
7809
- outputPath,
7810
- originalError: cause.name,
7811
- originalMessage: cause.message
7812
- });
7813
- this.cause = cause;
7814
- }
7815
- }
7816
-
7817
- class SchemaValidationError2 extends BunfigError2 {
7818
- code = "SCHEMA_VALIDATION_ERROR";
7819
- constructor(schemaPath, validationErrors, configName) {
7820
- super(`Schema validation failed${configName ? ` for config "${configName}"` : ""}`, {
7821
- schemaPath,
7822
- configName,
7823
- validationErrors,
7824
- errorCount: validationErrors.length
7825
- });
7826
- }
7827
- }
7828
-
7829
- class BrowserConfigError2 extends BunfigError2 {
7830
- code = "BROWSER_CONFIG_ERROR";
7831
- constructor(endpoint, status, statusText, configName) {
7832
- super(`Failed to fetch configuration from "${endpoint}": ${status} ${statusText}`, {
7833
- endpoint,
7834
- status,
7835
- statusText,
7836
- configName
7837
- });
7838
- }
7839
- }
7840
-
7841
- class PluginError2 extends BunfigError2 {
7842
- code = "PLUGIN_ERROR";
7843
- constructor(pluginName, operation, cause) {
7844
- super(`Plugin "${pluginName}" failed during ${operation}: ${cause.message}`, {
7845
- pluginName,
7846
- operation,
7847
- originalError: cause.name,
7848
- originalMessage: cause.message
7849
- });
7850
- this.cause = cause;
7851
- }
7852
- }
7853
- var ErrorFactory2 = {
7854
- configNotFound(configName, searchPaths, alias) {
7855
- return new ConfigNotFoundError2(configName, searchPaths, alias);
7856
- },
7857
- configLoad(configPath, cause, configName) {
7858
- return new ConfigLoadError2(configPath, cause, configName);
7859
- },
7860
- configValidation(configPath, errors, configName) {
7861
- return new ConfigValidationError2(configPath, errors, configName);
7862
- },
7863
- configMerge(sourcePath, targetPath, cause, configName) {
7864
- return new ConfigMergeError2(sourcePath, targetPath, cause, configName);
7865
- },
7866
- envVar(envKey, envValue, expectedType, configName) {
7867
- return new EnvVarError2(envKey, envValue, expectedType, configName);
7868
- },
7869
- fileSystem(operation, path, cause) {
7870
- return new FileSystemError2(operation, path, cause);
7871
- },
7872
- typeGeneration(configDir, outputPath, cause) {
7873
- return new TypeGenerationError2(configDir, outputPath, cause);
7874
- },
7875
- schemaValidation(schemaPath, errors, configName) {
7876
- return new SchemaValidationError2(schemaPath, errors, configName);
7877
- },
7878
- browserConfig(endpoint, status, statusText, configName) {
7879
- return new BrowserConfigError2(endpoint, status, statusText, configName);
7880
- },
7881
- plugin(pluginName, operation, cause) {
7882
- return new PluginError2(pluginName, operation, cause);
7883
- }
7884
- };
7885
- async function withErrorRecovery2(fn, options = {}) {
7886
- const {
7887
- maxRetries = 3,
7888
- retryDelay = 1000,
7889
- isRetryable = () => true,
7890
- fallback
7891
- } = options;
7892
- let lastError = new Error("Unknown error occurred");
7893
- for (let attempt = 0;attempt <= maxRetries; attempt++) {
7894
- try {
7895
- return await fn();
7896
- } catch (error) {
7897
- lastError = error instanceof Error ? error : new Error(String(error));
7898
- if (attempt === maxRetries || !isRetryable(lastError)) {
7899
- break;
7900
- }
7901
- if (retryDelay > 0) {
7902
- await new Promise((resolve522) => setTimeout(resolve522, retryDelay));
7903
- }
6149
+ this.cause = cause;
7904
6150
  }
7905
- }
7906
- if (fallback !== undefined) {
7907
- return fallback;
7908
- }
7909
- throw lastError instanceof Error ? lastError : new Error(`Unknown error: ${String(lastError)}`);
7910
- }
6151
+ };
6152
+ ErrorFactory2 = {
6153
+ configNotFound(configName, searchPaths, alias) {
6154
+ return new ConfigNotFoundError2(configName, searchPaths, alias);
6155
+ },
6156
+ configLoad(configPath, cause, configName) {
6157
+ return new ConfigLoadError2(configPath, cause, configName);
6158
+ },
6159
+ configValidation(configPath, errors, configName) {
6160
+ return new ConfigValidationError2(configPath, errors, configName);
6161
+ },
6162
+ configMerge(sourcePath, targetPath, cause, configName) {
6163
+ return new ConfigMergeError2(sourcePath, targetPath, cause, configName);
6164
+ },
6165
+ envVar(envKey, envValue, expectedType, configName) {
6166
+ return new EnvVarError2(envKey, envValue, expectedType, configName);
6167
+ },
6168
+ fileSystem(operation, path, cause) {
6169
+ return new FileSystemError2(operation, path, cause);
6170
+ },
6171
+ typeGeneration(configDir, outputPath, cause) {
6172
+ return new TypeGenerationError2(configDir, outputPath, cause);
6173
+ },
6174
+ schemaValidation(schemaPath, errors, configName) {
6175
+ return new SchemaValidationError2(schemaPath, errors, configName);
6176
+ },
6177
+ browserConfig(endpoint, status, statusText, configName) {
6178
+ return new BrowserConfigError2(endpoint, status, statusText, configName);
6179
+ },
6180
+ plugin(pluginName, operation, cause) {
6181
+ return new PluginError2(pluginName, operation, cause);
6182
+ }
6183
+ };
6184
+ });
7911
6185
 
7912
6186
  class EnvProcessor2 {
7913
6187
  defaultParsers;
@@ -7958,7 +6232,7 @@ class EnvProcessor2 {
7958
6232
  }
7959
6233
  ];
7960
6234
  }
7961
- async applyEnvironmentVariables(configName, config32, options = {}) {
6235
+ async applyEnvironmentVariables(configName, config22, options = {}) {
7962
6236
  const {
7963
6237
  prefix,
7964
6238
  useCamelCase = true,
@@ -7970,12 +6244,12 @@ class EnvProcessor2 {
7970
6244
  const operation = async () => {
7971
6245
  if (!configName) {
7972
6246
  return {
7973
- config: config32,
6247
+ config: config22,
7974
6248
  source: { type: "environment", priority: 50, timestamp: new Date }
7975
6249
  };
7976
6250
  }
7977
6251
  const envPrefix = prefix || this.generateEnvPrefix(configName);
7978
- const result = { ...config32 };
6252
+ const result = { ...config22 };
7979
6253
  this.processObject(result, [], envPrefix, {
7980
6254
  useCamelCase,
7981
6255
  useBackwardCompatibility,
@@ -8014,10 +6288,10 @@ class EnvProcessor2 {
8014
6288
  if (typeof value === "object" && value !== null && !Array.isArray(value)) {
8015
6289
  this.processObject(value, envPath, envPrefix, options);
8016
6290
  } else {
8017
- const envValue = process82.env[envKey] || (oldEnvKey ? process82.env[oldEnvKey] : undefined);
6291
+ const envValue = process52.env[envKey] || (oldEnvKey ? process52.env[oldEnvKey] : undefined);
8018
6292
  if (envValue !== undefined) {
8019
6293
  if (options.verbose) {
8020
- const _usedKey = process82.env[envKey] ? envKey : oldEnvKey;
6294
+ const _usedKey = process52.env[envKey] ? envKey : oldEnvKey;
8021
6295
  }
8022
6296
  try {
8023
6297
  obj[key] = this.parseEnvironmentValue(envValue, typeof value, envKey, options.customParsers, options.configName);
@@ -8053,7 +6327,7 @@ class EnvProcessor2 {
8053
6327
  getEnvironmentVariables(prefix) {
8054
6328
  const envVars = {};
8055
6329
  const upperPrefix = prefix.toUpperCase();
8056
- for (const [key, value] of Object.entries(process82.env)) {
6330
+ for (const [key, value] of Object.entries(process52.env)) {
8057
6331
  if (key.startsWith(upperPrefix) && value !== undefined) {
8058
6332
  envVars[key] = value;
8059
6333
  }
@@ -8077,11 +6351,11 @@ class EnvProcessor2 {
8077
6351
  errors
8078
6352
  };
8079
6353
  }
8080
- generateEnvVarDocs(configName, defaultConfig32, options = {}) {
6354
+ generateEnvVarDocs(configName, defaultConfig22, options = {}) {
8081
6355
  const { prefix, format = "text" } = options;
8082
6356
  const envPrefix = prefix || this.generateEnvPrefix(configName);
8083
6357
  const envVars = [];
8084
- this.extractEnvVarInfo(defaultConfig32, [], envPrefix, envVars);
6358
+ this.extractEnvVarInfo(defaultConfig22, [], envPrefix, envVars);
8085
6359
  switch (format) {
8086
6360
  case "markdown":
8087
6361
  return this.formatAsMarkdown(envVars, configName);
@@ -8148,7 +6422,18 @@ class EnvProcessor2 {
8148
6422
  return result;
8149
6423
  }
8150
6424
  }
8151
- function deepMerge3(target, source, options = {}) {
6425
+ var init_env_processor2 = __esm2(() => {
6426
+ init_cache2();
6427
+ init_errors2();
6428
+ });
6429
+ function getEnvOrDefault2(key, defaultValue) {
6430
+ const process62 = __require22("process");
6431
+ if (typeof process62 === "undefined" || !process62.env)
6432
+ return defaultValue;
6433
+ const envValue = process62.env[key];
6434
+ return envValue !== undefined ? envValue : defaultValue;
6435
+ }
6436
+ function deepMerge2(target, source, options = {}) {
8152
6437
  const visited = new WeakMap;
8153
6438
  return deepMergeWithVisited2(target, source, options, visited);
8154
6439
  }
@@ -8170,7 +6455,7 @@ function deepMergeWithVisited2(target, source, options, visited) {
8170
6455
  if (Array.isArray(source) || Array.isArray(target)) {
8171
6456
  return mergeArraysWithVisited2(target, source, arrayMergeMode, visited);
8172
6457
  }
8173
- if (!isObject3(source) || !isObject3(target)) {
6458
+ if (!isObject2(source) || !isObject2(target)) {
8174
6459
  return source;
8175
6460
  }
8176
6461
  return mergeObjectsWithVisited2(target, source, options, visited);
@@ -8199,7 +6484,7 @@ function mergeArraysWithVisited2(target, source, mode, visited) {
8199
6484
  function concatArraysWithDedup2(target, source) {
8200
6485
  const result = [...source];
8201
6486
  for (const item of target) {
8202
- if (!result.some((existingItem) => deepEquals3(existingItem, item))) {
6487
+ if (!result.some((existingItem) => deepEquals2(existingItem, item))) {
8203
6488
  result.push(item);
8204
6489
  }
8205
6490
  }
@@ -8210,7 +6495,7 @@ function smartMergeArraysWithVisited2(target, source, visited) {
8210
6495
  return target;
8211
6496
  if (target.length === 0)
8212
6497
  return source;
8213
- if (isObject3(source[0]) && isObject3(target[0])) {
6498
+ if (isObject2(source[0]) && isObject2(target[0])) {
8214
6499
  return mergeObjectArraysWithVisited2(target, source, visited);
8215
6500
  }
8216
6501
  if (source.every((item) => typeof item === "string") && target.every((item) => typeof item === "string")) {
@@ -8227,7 +6512,7 @@ function smartMergeArraysWithVisited2(target, source, visited) {
8227
6512
  function mergeObjectArraysWithVisited2(target, source, _visited) {
8228
6513
  const result = [...source];
8229
6514
  for (const targetItem of target) {
8230
- if (!isObject3(targetItem)) {
6515
+ if (!isObject2(targetItem)) {
8231
6516
  result.push(targetItem);
8232
6517
  continue;
8233
6518
  }
@@ -8235,7 +6520,7 @@ function mergeObjectArraysWithVisited2(target, source, _visited) {
8235
6520
  let hasMatch = false;
8236
6521
  for (const key of identifierKeys) {
8237
6522
  if (key in targetItem) {
8238
- const existingItem = result.find((item) => isObject3(item) && (key in item) && item[key] === targetItem[key]);
6523
+ const existingItem = result.find((item) => isObject2(item) && (key in item) && item[key] === targetItem[key]);
8239
6524
  if (existingItem) {
8240
6525
  hasMatch = true;
8241
6526
  break;
@@ -8250,11 +6535,11 @@ function mergeObjectArraysWithVisited2(target, source, _visited) {
8250
6535
  }
8251
6536
  function mergeObjectsWithVisited2(target, source, options, visited) {
8252
6537
  const sourceObj = source;
8253
- if (isObject3(sourceObj) && visited.has(sourceObj)) {
6538
+ if (isObject2(sourceObj) && visited.has(sourceObj)) {
8254
6539
  return visited.get(sourceObj);
8255
6540
  }
8256
6541
  const merged = { ...target };
8257
- if (isObject3(sourceObj)) {
6542
+ if (isObject2(sourceObj)) {
8258
6543
  visited.set(sourceObj, merged);
8259
6544
  }
8260
6545
  for (const key in sourceObj) {
@@ -8270,7 +6555,7 @@ function mergeObjectsWithVisited2(target, source, options, visited) {
8270
6555
  merged[key] = sourceValue;
8271
6556
  continue;
8272
6557
  }
8273
- if (isObject3(sourceValue) && isObject3(targetValue)) {
6558
+ if (isObject2(sourceValue) && isObject2(targetValue)) {
8274
6559
  merged[key] = deepMergeWithVisited2(targetValue, sourceValue, options, visited);
8275
6560
  } else if (Array.isArray(sourceValue) || Array.isArray(targetValue)) {
8276
6561
  merged[key] = mergeArraysWithVisited2(targetValue, sourceValue, options.arrayMergeMode || "smart", visited);
@@ -8280,26 +6565,26 @@ function mergeObjectsWithVisited2(target, source, options, visited) {
8280
6565
  }
8281
6566
  return merged;
8282
6567
  }
8283
- function deepMergeWithArrayStrategy22(target, source, strategy = "replace") {
6568
+ function deepMergeWithArrayStrategy2(target, source, strategy = "replace") {
8284
6569
  const arrayMergeMode = strategy === "replace" ? "replace" : "smart";
8285
- return deepMerge3(target, source, {
6570
+ return deepMerge2(target, source, {
8286
6571
  arrayMergeMode,
8287
6572
  skipNullish: true
8288
6573
  });
8289
6574
  }
8290
- function deepEquals3(a, b) {
6575
+ function deepEquals2(a, b) {
8291
6576
  if (a === b)
8292
6577
  return true;
8293
6578
  if (Array.isArray(a) && Array.isArray(b)) {
8294
6579
  if (a.length !== b.length)
8295
6580
  return false;
8296
6581
  for (let i = 0;i < a.length; i++) {
8297
- if (!deepEquals3(a[i], b[i]))
6582
+ if (!deepEquals2(a[i], b[i]))
8298
6583
  return false;
8299
6584
  }
8300
6585
  return true;
8301
6586
  }
8302
- if (isObject3(a) && isObject3(b)) {
6587
+ if (isObject2(a) && isObject2(b)) {
8303
6588
  const keysA = Object.keys(a);
8304
6589
  const keysB = Object.keys(b);
8305
6590
  if (keysA.length !== keysB.length)
@@ -8307,20 +6592,28 @@ function deepEquals3(a, b) {
8307
6592
  for (const key of keysA) {
8308
6593
  if (!Object.prototype.hasOwnProperty.call(b, key))
8309
6594
  return false;
8310
- if (!deepEquals3(a[key], b[key]))
6595
+ if (!deepEquals2(a[key], b[key]))
8311
6596
  return false;
8312
6597
  }
8313
6598
  return true;
8314
6599
  }
8315
6600
  return false;
8316
6601
  }
8317
- function isObject3(item) {
6602
+ function isObject2(item) {
8318
6603
  return Boolean(item && typeof item === "object" && !Array.isArray(item));
8319
6604
  }
6605
+ var ArrayMergeStrategies2;
6606
+ var init_utils2 = __esm2(() => {
6607
+ ArrayMergeStrategies2 = {
6608
+ replace: "replace",
6609
+ concat: "concat",
6610
+ smart: "smart"
6611
+ };
6612
+ });
8320
6613
 
8321
6614
  class ConfigFileLoader2 {
8322
6615
  extensions = [".ts", ".js", ".mjs", ".cjs", ".json", ".mts", ".cts"];
8323
- async loadFromPath(configPath, defaultConfig32, options = {}) {
6616
+ async loadFromPath(configPath, defaultConfig22, options = {}) {
8324
6617
  const {
8325
6618
  arrayStrategy = "replace",
8326
6619
  useCache = true,
@@ -8338,7 +6631,7 @@ class ConfigFileLoader2 {
8338
6631
  }
8339
6632
  }
8340
6633
  const loadOperation = async () => {
8341
- if (!existsSync52(configPath)) {
6634
+ if (!existsSync32(configPath)) {
8342
6635
  return null;
8343
6636
  }
8344
6637
  try {
@@ -8353,7 +6646,7 @@ class ConfigFileLoader2 {
8353
6646
  if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig)) {
8354
6647
  throw new ConfigLoadError2(configPath, new Error("Configuration must export a valid object"), "unknown");
8355
6648
  }
8356
- const mergedConfig = deepMergeWithArrayStrategy22(defaultConfig32, loadedConfig, arrayStrategy);
6649
+ const mergedConfig = deepMergeWithArrayStrategy2(defaultConfig22, loadedConfig, arrayStrategy);
8357
6650
  const source = {
8358
6651
  type: "file",
8359
6652
  path: configPath,
@@ -8375,10 +6668,10 @@ class ConfigFileLoader2 {
8375
6668
  }
8376
6669
  return loadOperation();
8377
6670
  }
8378
- async tryLoadFromPaths(configPaths, defaultConfig32, options = {}) {
6671
+ async tryLoadFromPaths(configPaths, defaultConfig22, options = {}) {
8379
6672
  for (const configPath of configPaths) {
8380
6673
  try {
8381
- const result = await this.loadFromPath(configPath, defaultConfig32, options);
6674
+ const result = await this.loadFromPath(configPath, defaultConfig22, options);
8382
6675
  if (result) {
8383
6676
  return result;
8384
6677
  }
@@ -8398,7 +6691,7 @@ class ConfigFileLoader2 {
8398
6691
  const paths = [];
8399
6692
  for (const pattern of patterns) {
8400
6693
  for (const ext of this.extensions) {
8401
- paths.push(resolve52(directory, `${pattern}${ext}`));
6694
+ paths.push(resolve32(directory, `${pattern}${ext}`));
8402
6695
  }
8403
6696
  }
8404
6697
  return paths;
@@ -8409,17 +6702,26 @@ class ConfigFileLoader2 {
8409
6702
  if (configName) {
8410
6703
  patterns.push(configName, `.${configName}.config`, `${configName}.config`, `.${configName}`);
8411
6704
  }
8412
- if (alias) {
8413
- patterns.push(alias, `.${alias}.config`, `${alias}.config`, `.${alias}`);
6705
+ const aliases = alias === undefined ? [] : Array.isArray(alias) ? alias : [alias];
6706
+ for (const a of aliases) {
6707
+ if (!a)
6708
+ continue;
6709
+ patterns.push(a, `.${a}.config`, `${a}.config`, `.${a}`);
8414
6710
  if (configName) {
8415
- patterns.push(`${configName}.${alias}.config`, `.${configName}.${alias}.config`);
6711
+ patterns.push(`${configName}.${a}.config`, `.${configName}.${a}.config`);
8416
6712
  }
8417
6713
  }
8418
- return patterns.filter(Boolean);
6714
+ const seen = new Set;
6715
+ return patterns.filter((p) => {
6716
+ if (!p || seen.has(p))
6717
+ return false;
6718
+ seen.add(p);
6719
+ return true;
6720
+ });
8419
6721
  }
8420
6722
  checkFileAccess(filePath) {
8421
6723
  return withErrorRecovery2(async () => {
8422
- return existsSync52(filePath);
6724
+ return existsSync32(filePath);
8423
6725
  }, {
8424
6726
  maxRetries: 2,
8425
6727
  retryDelay: 100,
@@ -8428,14 +6730,14 @@ class ConfigFileLoader2 {
8428
6730
  }
8429
6731
  async discoverConfigFiles(directory, configName, alias) {
8430
6732
  const discoveredFiles = [];
8431
- if (!existsSync52(directory)) {
6733
+ if (!existsSync32(directory)) {
8432
6734
  return discoveredFiles;
8433
6735
  }
8434
6736
  if (configName || alias) {
8435
6737
  const patterns = this.generateNamePatterns(configName || "", alias);
8436
6738
  for (const pattern of patterns) {
8437
6739
  for (const ext of this.extensions) {
8438
- const filePath = resolve52(directory, `${pattern}${ext}`);
6740
+ const filePath = resolve32(directory, `${pattern}${ext}`);
8439
6741
  if (await this.checkFileAccess(filePath)) {
8440
6742
  discoveredFiles.push(filePath);
8441
6743
  }
@@ -8447,7 +6749,7 @@ class ConfigFileLoader2 {
8447
6749
  const files = readdirSync32(directory);
8448
6750
  for (const file of files) {
8449
6751
  if (this.looksLikeConfigFile(file)) {
8450
- const filePath = resolve52(directory, file);
6752
+ const filePath = resolve32(directory, file);
8451
6753
  if (await this.checkFileAccess(filePath)) {
8452
6754
  discoveredFiles.push(filePath);
8453
6755
  }
@@ -8470,23 +6772,23 @@ class ConfigFileLoader2 {
8470
6772
  async validateConfigFile(filePath) {
8471
6773
  const errors = [];
8472
6774
  try {
8473
- if (!existsSync52(filePath)) {
6775
+ if (!existsSync32(filePath)) {
8474
6776
  errors.push("Configuration file does not exist");
8475
6777
  return errors;
8476
6778
  }
8477
6779
  const imported = await import(filePath);
8478
- const config32 = imported.default || imported;
8479
- if (config32 === undefined) {
6780
+ const config22 = imported.default || imported;
6781
+ if (config22 === undefined) {
8480
6782
  errors.push("Configuration file must export a default value or named exports");
8481
- } else if (typeof config32 !== "object" || config32 === null) {
6783
+ } else if (typeof config22 !== "object" || config22 === null) {
8482
6784
  errors.push("Configuration must be an object");
8483
- } else if (Array.isArray(config32)) {
6785
+ } else if (Array.isArray(config22)) {
8484
6786
  errors.push("Configuration cannot be an array at the root level");
8485
6787
  }
8486
6788
  if (filePath.endsWith(".json")) {
8487
6789
  try {
8488
- const { readFileSync: readFileSync2 } = await import("fs");
8489
- const content = readFileSync2(filePath, "utf8");
6790
+ const { readFileSync: readFileSync22 } = await import("fs");
6791
+ const content = readFileSync22(filePath, "utf8");
8490
6792
  JSON.parse(content);
8491
6793
  } catch (jsonError) {
8492
6794
  errors.push(`Invalid JSON syntax: ${jsonError}`);
@@ -8523,10 +6825,14 @@ class ConfigFileLoader2 {
8523
6825
  return preloaded;
8524
6826
  }
8525
6827
  }
8526
- var URL_PATTERN2 = /^https?:\/\//;
6828
+ var init_file_loader2 = __esm2(() => {
6829
+ init_cache2();
6830
+ init_errors2();
6831
+ init_utils2();
6832
+ });
8527
6833
 
8528
6834
  class ConfigValidator2 {
8529
- async validateConfiguration(config32, schema, options = {}) {
6835
+ async validateConfiguration(config22, schema, options = {}) {
8530
6836
  const {
8531
6837
  stopOnFirstError = false,
8532
6838
  validateRequired = true,
@@ -8548,11 +6854,11 @@ class ConfigValidator2 {
8548
6854
  };
8549
6855
  try {
8550
6856
  if (typeof schema === "string") {
8551
- return await this.validateWithSchemaFile(config32, schema, resolvedOptions);
6857
+ return await this.validateWithSchemaFile(config22, schema, resolvedOptions);
8552
6858
  } else if (Array.isArray(schema)) {
8553
- return this.validateWithRules(config32, [...schema, ...customRules], resolvedOptions);
6859
+ return this.validateWithRules(config22, [...schema, ...customRules], resolvedOptions);
8554
6860
  } else {
8555
- return this.validateWithJSONSchema(config32, schema, resolvedOptions);
6861
+ return this.validateWithJSONSchema(config22, schema, resolvedOptions);
8556
6862
  }
8557
6863
  } catch (error) {
8558
6864
  errors.push({
@@ -8569,26 +6875,26 @@ class ConfigValidator2 {
8569
6875
  }
8570
6876
  return operation();
8571
6877
  }
8572
- async validateWithSchemaFile(config32, schemaPath, options) {
6878
+ async validateWithSchemaFile(config22, schemaPath, options) {
8573
6879
  try {
8574
- if (!existsSync72(schemaPath)) {
6880
+ if (!existsSync42(schemaPath)) {
8575
6881
  throw new SchemaValidationError2(schemaPath, [{ path: "", message: "Schema file does not exist" }]);
8576
6882
  }
8577
6883
  const schemaModule = await import(schemaPath);
8578
6884
  const schema = schemaModule.default || schemaModule;
8579
6885
  if (Array.isArray(schema)) {
8580
- return this.validateWithRules(config32, schema, options);
6886
+ return this.validateWithRules(config22, schema, options);
8581
6887
  } else {
8582
- return this.validateWithJSONSchema(config32, schema, options);
6888
+ return this.validateWithJSONSchema(config22, schema, options);
8583
6889
  }
8584
6890
  } catch (error) {
8585
6891
  throw new SchemaValidationError2(schemaPath, [{ path: "", message: `Failed to load schema: ${error}` }]);
8586
6892
  }
8587
6893
  }
8588
- validateWithJSONSchema(config32, schema, options) {
6894
+ validateWithJSONSchema(config22, schema, options) {
8589
6895
  const errors = [];
8590
6896
  const warnings = [];
8591
- this.validateObjectAgainstSchema(config32, schema, "", errors, warnings, options);
6897
+ this.validateObjectAgainstSchema(config22, schema, "", errors, warnings, options);
8592
6898
  return {
8593
6899
  isValid: errors.length === 0,
8594
6900
  errors,
@@ -8722,12 +7028,12 @@ class ConfigValidator2 {
8722
7028
  }
8723
7029
  }
8724
7030
  }
8725
- validateWithRules(config32, rules, options) {
7031
+ validateWithRules(config22, rules, options) {
8726
7032
  const errors = [];
8727
7033
  const warnings = [];
8728
7034
  for (const rule of rules) {
8729
7035
  try {
8730
- const value = this.getValueByPath(config32, rule.path);
7036
+ const value = this.getValueByPath(config22, rule.path);
8731
7037
  const ruleErrors = this.validateWithRule(value, rule, rule.path);
8732
7038
  errors.push(...ruleErrors);
8733
7039
  if (options.stopOnFirstError && errors.length > 0) {
@@ -8892,9 +7198,22 @@ class ConfigValidator2 {
8892
7198
  };
8893
7199
  }
8894
7200
  }
8895
- var log22 = new Logger22("bunfig", {
8896
- showTags: true
7201
+ var URL_PATTERN2;
7202
+ var init_validator2 = __esm2(() => {
7203
+ init_cache2();
7204
+ init_errors2();
7205
+ URL_PATTERN2 = /^https?:\/\//;
8897
7206
  });
7207
+ function formatAliasSuffix2(alias) {
7208
+ if (!alias)
7209
+ return "";
7210
+ const list = Array.isArray(alias) ? alias.filter(Boolean) : [alias];
7211
+ if (list.length === 0)
7212
+ return "";
7213
+ if (list.length === 1)
7214
+ return ` or alias "${list[0]}"`;
7215
+ return ` or aliases ${list.map((a) => `"${a}"`).join(", ")}`;
7216
+ }
8898
7217
 
8899
7218
  class ConfigLoader2 {
8900
7219
  fileLoader = new ConfigFileLoader2;
@@ -8977,14 +7296,14 @@ class ConfigLoader2 {
8977
7296
  performance2.onMetrics(metrics);
8978
7297
  }
8979
7298
  if (performance2.slowThreshold && metrics.duration > performance2.slowThreshold) {
8980
- log22.warn(`Slow configuration loading detected: ${metrics.duration}ms for ${baseOptions.name}`);
7299
+ log2.warn(`Slow configuration loading detected: ${metrics.duration}ms for ${baseOptions.name}`);
8981
7300
  }
8982
7301
  result.metrics = metrics;
8983
7302
  }
8984
7303
  return result;
8985
7304
  } catch (error) {
8986
7305
  const duration = Date.now() - startTime;
8987
- log22.error(`Configuration loading failed after ${duration}ms:`, [error instanceof Error ? error : new Error(String(error))]);
7306
+ log2.error(`Configuration loading failed after ${duration}ms:`, [error instanceof Error ? error : new Error(String(error))]);
8988
7307
  throw error;
8989
7308
  }
8990
7309
  }
@@ -8994,44 +7313,44 @@ class ConfigLoader2 {
8994
7313
  alias,
8995
7314
  cwd,
8996
7315
  configDir,
8997
- defaultConfig: defaultConfig32,
7316
+ defaultConfig: defaultConfig22,
8998
7317
  checkEnv = true,
8999
7318
  arrayStrategy = "replace",
9000
7319
  verbose = false
9001
7320
  } = options;
9002
- const baseDir = cwd || process12.cwd();
7321
+ const baseDir = cwd || process72.cwd();
9003
7322
  const searchPaths = [];
9004
- const localResult = await this.loadLocalConfiguration(name, alias, baseDir, configDir, defaultConfig32, arrayStrategy, verbose, checkEnv, cacheOptions);
7323
+ const localResult = await this.loadLocalConfiguration(name, alias, baseDir, configDir, defaultConfig22, arrayStrategy, verbose, checkEnv, cacheOptions);
9005
7324
  if (localResult) {
9006
7325
  searchPaths.push(...this.getLocalSearchPaths(name, alias, baseDir, configDir));
9007
7326
  return this.finalizeResult(localResult, searchPaths, checkEnv, name, verbose);
9008
7327
  }
9009
- const homeResult = await this.loadHomeConfiguration(name, alias, defaultConfig32, arrayStrategy, verbose, checkEnv);
7328
+ const homeResult = await this.loadHomeConfiguration(name, alias, defaultConfig22, arrayStrategy, verbose, checkEnv);
9010
7329
  if (homeResult) {
9011
7330
  searchPaths.push(...this.getHomeSearchPaths(name, alias));
9012
7331
  return this.finalizeResult(homeResult, searchPaths, checkEnv, name, verbose);
9013
7332
  }
9014
- const packageResult = await this.loadPackageJsonConfiguration(name, alias, baseDir, defaultConfig32, arrayStrategy, verbose, checkEnv);
7333
+ const packageResult = await this.loadPackageJsonConfiguration(name, alias, baseDir, defaultConfig22, arrayStrategy, verbose, checkEnv);
9015
7334
  if (packageResult) {
9016
- searchPaths.push(resolve7(baseDir, "package.json"));
7335
+ searchPaths.push(resolve52(baseDir, "package.json"));
9017
7336
  return this.finalizeResult(packageResult, searchPaths, checkEnv, name, verbose);
9018
7337
  }
9019
7338
  searchPaths.push(...this.getAllSearchPaths(name, alias, baseDir, configDir));
9020
7339
  if (throwOnNotFound) {
9021
7340
  throw ErrorFactory2.configNotFound(name, searchPaths, alias);
9022
7341
  }
9023
- const envResult = await this.applyEnvironmentVariables(name, defaultConfig32, checkEnv, verbose);
7342
+ const envResult = await this.applyEnvironmentVariables(name, defaultConfig22, checkEnv, verbose);
9024
7343
  return {
9025
7344
  ...envResult,
9026
- warnings: [`No configuration file found for "${name}"${alias ? ` or alias "${alias}"` : ""}, using defaults with environment variables`]
7345
+ warnings: [`No configuration file found for "${name}"${formatAliasSuffix2(alias)}, using defaults with environment variables`]
9027
7346
  };
9028
7347
  }
9029
- async loadLocalConfiguration(name, alias, baseDir, configDir, defaultConfig32, arrayStrategy, verbose, checkEnv, cacheOptions) {
9030
- const envDefaultConfig = checkEnv ? applyEnvVarsToConfig22(name, defaultConfig32, verbose) : defaultConfig32;
7348
+ async loadLocalConfiguration(name, alias, baseDir, configDir, defaultConfig22, arrayStrategy, verbose, checkEnv, cacheOptions) {
7349
+ const envDefaultConfig = checkEnv ? applyEnvVarsToConfig2(name, defaultConfig22, verbose) : defaultConfig22;
9031
7350
  const searchDirectories = this.getLocalDirectories(baseDir, configDir);
9032
7351
  for (const directory of searchDirectories) {
9033
7352
  if (verbose) {
9034
- log22.info(`Searching for configuration in: ${directory}`);
7353
+ log2.info(`Searching for configuration in: ${directory}`);
9035
7354
  }
9036
7355
  const configPaths = this.fileLoader.generateConfigPaths(name, directory, alias);
9037
7356
  const result = await this.fileLoader.tryLoadFromPaths(configPaths, envDefaultConfig, {
@@ -9042,56 +7361,72 @@ class ConfigLoader2 {
9042
7361
  });
9043
7362
  if (result) {
9044
7363
  if (verbose) {
9045
- log22.success(`Configuration loaded from: ${result.source.path}`);
7364
+ log2.success(`Configuration loaded from: ${result.source.path}`);
9046
7365
  }
9047
7366
  return result;
9048
7367
  }
9049
7368
  }
9050
7369
  return null;
9051
7370
  }
9052
- async loadHomeConfiguration(name, alias, defaultConfig32, arrayStrategy, verbose, checkEnv) {
7371
+ async loadHomeConfiguration(name, alias, defaultConfig22, arrayStrategy, verbose, checkEnv) {
9053
7372
  if (!name)
9054
7373
  return null;
9055
- const envDefaultConfig = checkEnv ? applyEnvVarsToConfig22(name, defaultConfig32, verbose) : defaultConfig32;
7374
+ const envDefaultConfig = checkEnv ? applyEnvVarsToConfig2(name, defaultConfig22, verbose) : defaultConfig22;
9056
7375
  const homeDirectories = [
9057
- resolve7(homedir2(), ".config", name),
9058
- resolve7(homedir2(), ".config"),
7376
+ resolve52(homedir2(), ".config", name),
7377
+ resolve52(homedir2(), ".config"),
9059
7378
  homedir2()
9060
7379
  ];
9061
7380
  for (const directory of homeDirectories) {
9062
7381
  if (verbose) {
9063
- log22.info(`Checking home directory: ${directory}`);
7382
+ log2.info(`Checking home directory: ${directory}`);
9064
7383
  }
9065
7384
  const configPaths = this.fileLoader.generateConfigPaths(name, directory, alias);
9066
7385
  const result = await this.fileLoader.tryLoadFromPaths(configPaths, envDefaultConfig, { arrayStrategy, verbose });
9067
7386
  if (result) {
9068
7387
  if (verbose) {
9069
- log22.success(`Configuration loaded from home directory: ${result.source.path}`);
7388
+ log2.success(`Configuration loaded from home directory: ${result.source.path}`);
9070
7389
  }
9071
7390
  return result;
9072
7391
  }
9073
7392
  }
9074
7393
  return null;
9075
7394
  }
9076
- async loadPackageJsonConfiguration(name, alias, baseDir, defaultConfig32, arrayStrategy, verbose, checkEnv) {
9077
- const envDefaultConfig = checkEnv ? applyEnvVarsToConfig22(name, defaultConfig32, verbose) : defaultConfig32;
7395
+ async loadPackageJsonConfiguration(name, alias, baseDir, defaultConfig22, arrayStrategy, verbose, checkEnv) {
7396
+ const envDefaultConfig = checkEnv ? applyEnvVarsToConfig2(name, defaultConfig22, verbose) : defaultConfig22;
9078
7397
  try {
9079
- const pkgPath = resolve7(baseDir, "package.json");
9080
- if (!existsSync8(pkgPath)) {
7398
+ const pkgPath = resolve52(baseDir, "package.json");
7399
+ if (!existsSync52(pkgPath)) {
7400
+ return null;
7401
+ }
7402
+ let pkg = {};
7403
+ try {
7404
+ pkg = JSON.parse(readFileSync2(pkgPath, "utf8"));
7405
+ } catch (parseError) {
7406
+ if (verbose) {
7407
+ log2.warn(`Failed to parse package.json:`, [parseError instanceof Error ? parseError : new Error(String(parseError))]);
7408
+ }
9081
7409
  return null;
9082
7410
  }
9083
- const pkg = await import(pkgPath);
9084
7411
  let pkgConfig = pkg[name];
9085
7412
  let usedName = name;
9086
7413
  if (!pkgConfig && alias) {
9087
- pkgConfig = pkg[alias];
9088
- usedName = alias;
7414
+ const aliases = Array.isArray(alias) ? alias : [alias];
7415
+ for (const a of aliases) {
7416
+ if (!a)
7417
+ continue;
7418
+ if (pkg[a]) {
7419
+ pkgConfig = pkg[a];
7420
+ usedName = a;
7421
+ break;
7422
+ }
7423
+ }
9089
7424
  }
9090
7425
  if (pkgConfig && typeof pkgConfig === "object" && !Array.isArray(pkgConfig)) {
9091
7426
  if (verbose) {
9092
- log22.success(`Configuration loaded from package.json: ${usedName}`);
7427
+ log2.success(`Configuration loaded from package.json: ${usedName}`);
9093
7428
  }
9094
- const mergedConfig = deepMergeWithArrayStrategy22(envDefaultConfig, pkgConfig, arrayStrategy);
7429
+ const mergedConfig = deepMergeWithArrayStrategy2(envDefaultConfig, pkgConfig, arrayStrategy);
9095
7430
  return {
9096
7431
  config: mergedConfig,
9097
7432
  source: {
@@ -9104,15 +7439,15 @@ class ConfigLoader2 {
9104
7439
  }
9105
7440
  } catch (error) {
9106
7441
  if (verbose) {
9107
- log22.warn(`Failed to load package.json:`, [error instanceof Error ? error : new Error(String(error))]);
7442
+ log2.warn(`Failed to load package.json:`, [error instanceof Error ? error : new Error(String(error))]);
9108
7443
  }
9109
7444
  }
9110
7445
  return null;
9111
7446
  }
9112
- async applyEnvironmentVariables(name, config32, checkEnv, verbose) {
9113
- if (!checkEnv || !name || typeof config32 !== "object" || config32 === null || Array.isArray(config32)) {
7447
+ async applyEnvironmentVariables(name, config22, checkEnv, verbose) {
7448
+ if (!checkEnv || !name || typeof config22 !== "object" || config22 === null || Array.isArray(config22)) {
9114
7449
  return {
9115
- config: config32,
7450
+ config: config22,
9116
7451
  source: {
9117
7452
  type: "default",
9118
7453
  priority: 10,
@@ -9120,7 +7455,7 @@ class ConfigLoader2 {
9120
7455
  }
9121
7456
  };
9122
7457
  }
9123
- const processedConfig = applyEnvVarsToConfig22(name, config32, verbose);
7458
+ const processedConfig = applyEnvVarsToConfig2(name, config22, verbose);
9124
7459
  return {
9125
7460
  config: processedConfig,
9126
7461
  source: {
@@ -9137,16 +7472,16 @@ class ConfigLoader2 {
9137
7472
  path: result.source.path
9138
7473
  };
9139
7474
  }
9140
- async validateConfiguration(config32, schema, customValidator, configName) {
7475
+ async validateConfiguration(config22, schema, customValidator, configName) {
9141
7476
  const errors = [];
9142
7477
  if (customValidator) {
9143
- const customErrors = customValidator(config32);
7478
+ const customErrors = customValidator(config22);
9144
7479
  if (customErrors) {
9145
7480
  errors.push(...customErrors);
9146
7481
  }
9147
7482
  }
9148
7483
  if (schema) {
9149
- const validationResult = await this.validator.validateConfiguration(config32, schema);
7484
+ const validationResult = await this.validator.validateConfiguration(config22, schema);
9150
7485
  if (!validationResult.isValid) {
9151
7486
  errors.push(...validationResult.errors.map((e) => e.path ? `${e.path}: ${e.message}` : e.message));
9152
7487
  }
@@ -9166,8 +7501,10 @@ class ConfigLoader2 {
9166
7501
  }
9167
7502
  generateCacheKey(configName, options) {
9168
7503
  const keyParts = [configName];
9169
- if (options.alias)
9170
- keyParts.push(`alias:${options.alias}`);
7504
+ if (options.alias) {
7505
+ const aliasKey = Array.isArray(options.alias) ? options.alias.join(",") : options.alias;
7506
+ keyParts.push(`alias:${aliasKey}`);
7507
+ }
9171
7508
  if (options.cwd)
9172
7509
  keyParts.push(`cwd:${options.cwd}`);
9173
7510
  if (options.configDir)
@@ -9179,16 +7516,16 @@ class ConfigLoader2 {
9179
7516
  getLocalDirectories(baseDir, configDir) {
9180
7517
  return Array.from(new Set([
9181
7518
  baseDir,
9182
- resolve7(baseDir, "config"),
9183
- resolve7(baseDir, ".config"),
9184
- configDir ? resolve7(baseDir, configDir) : undefined
7519
+ resolve52(baseDir, "config"),
7520
+ resolve52(baseDir, ".config"),
7521
+ configDir ? resolve52(baseDir, configDir) : undefined
9185
7522
  ].filter(Boolean)));
9186
7523
  }
9187
7524
  getAllSearchPaths(name, alias, baseDir, configDir) {
9188
7525
  const paths = [];
9189
7526
  paths.push(...this.getLocalSearchPaths(name, alias, baseDir, configDir));
9190
7527
  paths.push(...this.getHomeSearchPaths(name, alias));
9191
- paths.push(resolve7(baseDir, "package.json"));
7528
+ paths.push(resolve52(baseDir, "package.json"));
9192
7529
  return paths;
9193
7530
  }
9194
7531
  getLocalSearchPaths(name, alias, baseDir, configDir) {
@@ -9203,8 +7540,8 @@ class ConfigLoader2 {
9203
7540
  if (!name)
9204
7541
  return [];
9205
7542
  const homeDirectories = [
9206
- resolve7(homedir2(), ".config", name),
9207
- resolve7(homedir2(), ".config"),
7543
+ resolve52(homedir2(), ".config", name),
7544
+ resolve52(homedir2(), ".config"),
9208
7545
  homedir2()
9209
7546
  ];
9210
7547
  const paths = [];
@@ -9217,8 +7554,107 @@ class ConfigLoader2 {
9217
7554
  return this.loadConfig(options);
9218
7555
  }
9219
7556
  }
9220
- var globalConfigLoader2 = new ConfigLoader2;
9221
- function applyEnvVarsToConfig22(name, config4, verbose = false) {
7557
+ function shouldHandleConfigLoadErrorGracefully2(error) {
7558
+ const isPermissionError = error.message.includes("EACCES") || error.message.includes("EPERM") || error.message.includes("permission denied");
7559
+ const isSyntaxError = !isPermissionError && (error.message.includes("syntax") || error.message.includes("Expected") || error.message.includes("Unexpected") || error.message.includes("BuildMessage"));
7560
+ const isStructureError = error.message.includes("Configuration must export a valid object") || error.message.includes("Configuration file is empty and exports nothing");
7561
+ return isSyntaxError || isStructureError;
7562
+ }
7563
+ async function loadConfigWithResult2(options) {
7564
+ return globalConfigLoader2.loadConfig({
7565
+ ...options,
7566
+ __strictErrorHandling: true
7567
+ });
7568
+ }
7569
+ async function loadConfig2(options) {
7570
+ const defaultConfig22 = "defaultConfig" in options && options.defaultConfig !== undefined ? options.defaultConfig : {};
7571
+ const isEnhanced = "cache" in options || "performance" in options || "schema" in options || "validate" in options;
7572
+ try {
7573
+ let result;
7574
+ if (isEnhanced) {
7575
+ result = await globalConfigLoader2.loadConfig(options);
7576
+ } else {
7577
+ result = await globalConfigLoader2.loadConfig({
7578
+ ...options,
7579
+ defaultConfig: defaultConfig22,
7580
+ cache: { enabled: true },
7581
+ performance: { enabled: false }
7582
+ });
7583
+ }
7584
+ return result?.config ?? defaultConfig22;
7585
+ } catch (error) {
7586
+ const errorName = error instanceof Error ? error.name : "UnknownError";
7587
+ const errorMessage = error instanceof Error ? error.message : String(error);
7588
+ const isConfigError = errorName === "ConfigNotFoundError" || errorName === "ConfigLoadError" || errorName === "ConfigValidationError" || errorMessage.includes("config");
7589
+ if (!isConfigError && options.verbose) {
7590
+ log2.warn(`Unexpected error loading config, using defaults:`, [error instanceof Error ? error : new Error(String(error))]);
7591
+ }
7592
+ const configOptions = isEnhanced ? { ...options, defaultConfig: defaultConfig22 } : {
7593
+ ...options,
7594
+ defaultConfig: defaultConfig22,
7595
+ cache: { enabled: true },
7596
+ performance: { enabled: false }
7597
+ };
7598
+ const shouldCheckEnv = "checkEnv" in options ? options.checkEnv !== false : true;
7599
+ if (shouldCheckEnv) {
7600
+ const envResult = await globalConfigLoader2.applyEnvironmentVariables(configOptions.name || "", defaultConfig22, true, configOptions.verbose || false);
7601
+ return envResult?.config ?? defaultConfig22;
7602
+ }
7603
+ return defaultConfig22;
7604
+ }
7605
+ }
7606
+ async function config22(nameOrOptions = { defaultConfig: {} }) {
7607
+ if (typeof nameOrOptions === "string") {
7608
+ const { cwd } = await import("process");
7609
+ try {
7610
+ const result = await globalConfigLoader2.loadConfig({
7611
+ name: nameOrOptions,
7612
+ cwd: cwd(),
7613
+ generatedDir: "./generated",
7614
+ configDir: "./config",
7615
+ defaultConfig: {},
7616
+ checkEnv: true,
7617
+ arrayStrategy: "replace"
7618
+ });
7619
+ return result.config;
7620
+ } catch (error) {
7621
+ if (error instanceof Error && (error.name === "ConfigNotFoundError" || error.name === "ConfigLoadError" && shouldHandleConfigLoadErrorGracefully2(error))) {
7622
+ const envResult = await globalConfigLoader2.applyEnvironmentVariables(nameOrOptions, {}, true, false);
7623
+ return envResult.config;
7624
+ }
7625
+ throw error;
7626
+ }
7627
+ }
7628
+ try {
7629
+ const result = await globalConfigLoader2.loadConfig({
7630
+ ...nameOrOptions,
7631
+ cwd: nameOrOptions.cwd || process72.cwd(),
7632
+ cache: { enabled: true },
7633
+ performance: { enabled: false }
7634
+ });
7635
+ return result.config;
7636
+ } catch (error) {
7637
+ if (error instanceof Error && (error.name === "ConfigNotFoundError" || error.name === "ConfigLoadError" && shouldHandleConfigLoadErrorGracefully2(error))) {
7638
+ const envResult = await globalConfigLoader2.applyEnvironmentVariables(nameOrOptions.name || "", nameOrOptions.defaultConfig || {}, nameOrOptions.checkEnv !== false, nameOrOptions.verbose || false);
7639
+ return envResult.config;
7640
+ }
7641
+ throw error;
7642
+ }
7643
+ }
7644
+ async function tryLoadConfig2(configPath, defaultConfig22, arrayStrategy = "replace") {
7645
+ const fileLoader = new ConfigFileLoader2;
7646
+ try {
7647
+ const result = await fileLoader.loadFromPath(configPath, defaultConfig22, {
7648
+ arrayStrategy,
7649
+ useCache: false,
7650
+ trackPerformance: false
7651
+ });
7652
+ return result ? result.config : null;
7653
+ } catch {
7654
+ return null;
7655
+ }
7656
+ }
7657
+ function applyEnvVarsToConfig2(name, config32, verbose = false) {
9222
7658
  const _envProcessor = new EnvProcessor2;
9223
7659
  const envPrefix = name.toUpperCase().replace(/[^A-Z0-9]/g, "_");
9224
7660
  function processConfigLevel(obj, path = []) {
@@ -9233,7 +7669,7 @@ function applyEnvVarsToConfig22(name, config4, verbose = false) {
9233
7669
  let envValue;
9234
7670
  let usedKey;
9235
7671
  for (const envKey of envKeys) {
9236
- envValue = process12.env[envKey];
7672
+ envValue = process72.env[envKey];
9237
7673
  if (envValue !== undefined) {
9238
7674
  usedKey = envKey;
9239
7675
  break;
@@ -9263,11 +7699,200 @@ function applyEnvVarsToConfig22(name, config4, verbose = false) {
9263
7699
  }
9264
7700
  return result;
9265
7701
  }
9266
- return processConfigLevel(config4);
7702
+ return processConfigLevel(config32);
7703
+ }
7704
+ function generateConfigTypes2(options) {
7705
+ const configDir = resolve52(process72.cwd(), options.configDir);
7706
+ const generatedDir = resolve52(process72.cwd(), options.generatedDir);
7707
+ const outputFile = resolve52(generatedDir, "config-types.ts");
7708
+ if (!existsSync52(dirname2(outputFile)))
7709
+ mkdirSync2(dirname2(outputFile), { recursive: true, mode: 511 });
7710
+ const files = existsSync52(configDir) ? readdirSync3(configDir).map((file) => file.replace(/\.(ts|js|mjs|cjs|mts|cts|json)$/, "")).sort() : [];
7711
+ const content = `// Generated by bunfig v${version2}
7712
+ export type ConfigNames = ${files.length ? `'${files.join("' | '")}'` : "string"}
7713
+ `;
7714
+ writeFileSync22(outputFile, content, { mode: 438 });
7715
+ }
7716
+ function createLibraryConfig2(options) {
7717
+ let configCache = null;
7718
+ let loadPromise = null;
7719
+ const startLoading = () => {
7720
+ if (!loadPromise) {
7721
+ loadPromise = loadConfig2(options).then((loadedConfig) => {
7722
+ configCache = loadedConfig;
7723
+ return loadedConfig;
7724
+ }, (error) => {
7725
+ const defaultConfig32 = "defaultConfig" in options ? options.defaultConfig : {};
7726
+ configCache = defaultConfig32;
7727
+ const verbose = "verbose" in options && options.verbose;
7728
+ if (verbose) {
7729
+ log2.warn(`Config loading failed, using defaults:`, [error instanceof Error ? error : new Error(String(error))]);
7730
+ }
7731
+ return defaultConfig32;
7732
+ });
7733
+ }
7734
+ return loadPromise;
7735
+ };
7736
+ const defaultConfig22 = "defaultConfig" in options ? options.defaultConfig : {};
7737
+ configCache = defaultConfig22;
7738
+ startLoading();
7739
+ return new Proxy({}, {
7740
+ get(target, prop) {
7741
+ if (configCache) {
7742
+ return configCache[prop];
7743
+ }
7744
+ const value = defaultConfig22[prop];
7745
+ startLoading();
7746
+ return value;
7747
+ },
7748
+ has(target, prop) {
7749
+ return prop in (configCache || defaultConfig22);
7750
+ },
7751
+ ownKeys() {
7752
+ return Object.keys(configCache || defaultConfig22);
7753
+ },
7754
+ getOwnPropertyDescriptor(target, prop) {
7755
+ return Object.getOwnPropertyDescriptor(configCache || defaultConfig22, prop);
7756
+ },
7757
+ set(target, prop, value) {
7758
+ if (!configCache) {
7759
+ configCache = { ...defaultConfig22 };
7760
+ }
7761
+ configCache[prop] = value;
7762
+ return true;
7763
+ }
7764
+ });
7765
+ }
7766
+ var log2;
7767
+ var globalConfigLoader2;
7768
+ var defaultConfigDir2;
7769
+ var defaultGeneratedDir2;
7770
+ var init_config2 = __esm2(() => {
7771
+ init_src3();
7772
+ init_package2();
7773
+ init_cache2();
7774
+ init_errors2();
7775
+ init_env_processor2();
7776
+ init_file_loader2();
7777
+ init_validator2();
7778
+ init_utils2();
7779
+ log2 = new Logger2("bunfig", {
7780
+ showTags: true
7781
+ });
7782
+ globalConfigLoader2 = new ConfigLoader2;
7783
+ defaultConfigDir2 = resolve52(process72.cwd(), "config");
7784
+ defaultGeneratedDir2 = resolve52(process72.cwd(), "src/generated");
7785
+ });
7786
+ function bunfigPlugin2(options) {
7787
+ const configDir = resolve62(process82.cwd(), options?.configDir || "./config");
7788
+ function readConfigSelection() {
7789
+ if (!existsSync62(configDir))
7790
+ return [];
7791
+ const allowed = new Set([".ts", ".js", ".mjs", ".cjs", ".mts", ".cts", ".json"]);
7792
+ const priority = [".ts", ".mts", ".cts", ".js", ".mjs", ".cjs", ".json"];
7793
+ const entries = readdirSync22(configDir).filter((file) => allowed.has(extname2(file))).map((file) => ({ base: file.replace(/\.(?:ts|js|mjs|cjs|mts|cts|json)$/i, ""), file }));
7794
+ const bestByBase = new Map;
7795
+ for (const { base, file } of entries) {
7796
+ const ext = extname2(file).toLowerCase();
7797
+ const current = bestByBase.get(base);
7798
+ if (!current) {
7799
+ bestByBase.set(base, file);
7800
+ continue;
7801
+ }
7802
+ const currExt = extname2(current).toLowerCase();
7803
+ if (priority.indexOf(ext) < priority.indexOf(currExt)) {
7804
+ bestByBase.set(base, file);
7805
+ }
7806
+ }
7807
+ return Array.from(bestByBase.entries()).map(([base, file]) => ({ base, file })).sort((a, b) => a.base.localeCompare(b.base));
7808
+ }
7809
+ function generateModuleSource() {
7810
+ const selections = readConfigSelection();
7811
+ const names = selections.map((s) => s.base);
7812
+ const union = names.length ? names.map((n) => `'${n}'`).join(" | ") : "string";
7813
+ const byName = selections.length ? `{
7814
+ ${selections.map((sel) => {
7815
+ const abs = resolve62(configDir, sel.file).replace(/\\/g, "/");
7816
+ return ` '${sel.base}': typeof import('${abs}').default`;
7817
+ }).join(`,
7818
+ `)}
7819
+ }` : "Record<string, any>";
7820
+ const source = `export type ConfigNames = ${union}
7821
+ export type ConfigByName = ${byName}
7822
+ export type Config<N extends ConfigNames> = N extends keyof ConfigByName ? ConfigByName[N] : unknown
7823
+ export type ConfigOf = Config
7824
+ `;
7825
+ return source;
7826
+ }
7827
+ return {
7828
+ name: "bunfig-plugin",
7829
+ setup(builder) {
7830
+ builder.onResolve({ filter: /^virtual:bunfig-types$/ }, (args) => {
7831
+ return { path: args.path, namespace: "bunfig-virtual" };
7832
+ });
7833
+ builder.onLoad({ filter: /^virtual:bunfig-types$/, namespace: "bunfig-virtual" }, () => {
7834
+ const contents = generateModuleSource();
7835
+ return { contents, loader: "ts" };
7836
+ });
7837
+ }
7838
+ };
9267
7839
  }
9268
- var defaultConfigDir3 = resolve7(process12.cwd(), "config");
9269
- var defaultGeneratedDir3 = resolve7(process12.cwd(), "src/generated");
9270
- var defaultConfig32 = {
7840
+ var init_plugin2 = () => {};
7841
+ var exports_src2 = {};
7842
+ __export3(exports_src2, {
7843
+ withErrorRecovery: () => withErrorRecovery2,
7844
+ tryLoadConfig: () => tryLoadConfig2,
7845
+ loadConfigWithResult: () => loadConfigWithResult2,
7846
+ loadConfig: () => loadConfig2,
7847
+ isRetryableError: () => isRetryableError2,
7848
+ isConfigNotFoundError: () => isConfigNotFoundError2,
7849
+ isBunfigError: () => isBunfigError2,
7850
+ globalPerformanceMonitor: () => globalPerformanceMonitor2,
7851
+ globalCache: () => globalCache2,
7852
+ getEnvOrDefault: () => getEnvOrDefault2,
7853
+ generateConfigTypes: () => generateConfigTypes2,
7854
+ defaultGeneratedDir: () => defaultGeneratedDir2,
7855
+ defaultConfigDir: () => defaultConfigDir2,
7856
+ deepMergeWithArrayStrategy: () => deepMergeWithArrayStrategy2,
7857
+ deepMerge: () => deepMerge2,
7858
+ createLibraryConfig: () => createLibraryConfig2,
7859
+ config: () => config22,
7860
+ bunfigPlugin: () => bunfigPlugin2,
7861
+ applyEnvVarsToConfig: () => applyEnvVarsToConfig2,
7862
+ TypeGenerationError: () => TypeGenerationError2,
7863
+ SchemaValidationError: () => SchemaValidationError2,
7864
+ PluginError: () => PluginError2,
7865
+ PerformanceMonitor: () => PerformanceMonitor2,
7866
+ FileSystemError: () => FileSystemError2,
7867
+ ErrorFactory: () => ErrorFactory2,
7868
+ EnvVarError: () => EnvVarError2,
7869
+ EnvProcessor: () => EnvProcessor2,
7870
+ ConfigValidator: () => ConfigValidator2,
7871
+ ConfigValidationError: () => ConfigValidationError2,
7872
+ ConfigNotFoundError: () => ConfigNotFoundError2,
7873
+ ConfigMergeError: () => ConfigMergeError2,
7874
+ ConfigLoader: () => ConfigLoader2,
7875
+ ConfigLoadError: () => ConfigLoadError2,
7876
+ ConfigFileLoader: () => ConfigFileLoader2,
7877
+ ConfigCache: () => ConfigCache2,
7878
+ CacheUtils: () => CacheUtils2,
7879
+ BunfigError: () => BunfigError2,
7880
+ BrowserConfigError: () => BrowserConfigError2,
7881
+ ArrayMergeStrategies: () => ArrayMergeStrategies2
7882
+ });
7883
+ var init_src22 = __esm2(() => {
7884
+ init_config2();
7885
+ init_errors2();
7886
+ init_cache2();
7887
+ init_errors2();
7888
+ init_plugin2();
7889
+ init_env_processor2();
7890
+ init_file_loader2();
7891
+ init_validator2();
7892
+ init_utils2();
7893
+ });
7894
+ init_src22();
7895
+ var defaultConfig22 = {
9271
7896
  verbose: false,
9272
7897
  storage: "memory",
9273
7898
  algorithm: "fixed-window",
@@ -9286,7 +7911,7 @@ var defaultConfig32 = {
9286
7911
  enableSlidingWindow: false
9287
7912
  }
9288
7913
  };
9289
- var config32 = defaultConfig32;
7914
+ var config32 = defaultConfig22;
9290
7915
 
9291
7916
  class MemoryStorage {
9292
7917
  records;
@@ -9297,9 +7922,9 @@ class MemoryStorage {
9297
7922
  constructor(options) {
9298
7923
  this.records = new Map;
9299
7924
  this.timestamps = new Map;
9300
- const defaultConfig4 = config32.memoryStorage || {};
9301
- this.enableAutoCleanup = options?.enableAutoCleanup ?? defaultConfig4.enableAutoCleanup ?? false;
9302
- this.cleanupIntervalMs = options?.cleanupIntervalMs ?? defaultConfig4.cleanupIntervalMs ?? 60000;
7925
+ const defaultConfig32 = config32.memoryStorage || {};
7926
+ this.enableAutoCleanup = options?.enableAutoCleanup ?? defaultConfig32.enableAutoCleanup ?? false;
7927
+ this.cleanupIntervalMs = options?.cleanupIntervalMs ?? defaultConfig32.cleanupIntervalMs ?? 60000;
9303
7928
  this.cleanupTimer = null;
9304
7929
  if (this.enableAutoCleanup) {
9305
7930
  this.startCleanupTimer();
@@ -9726,6 +8351,26 @@ class RateLimiter {
9726
8351
  return this.checkFixedWindow(key);
9727
8352
  }
9728
8353
  }
8354
+ async peek(key) {
8355
+ if (typeof this.storage.getCount !== "function")
8356
+ return null;
8357
+ const count = await this.storage.getCount(key);
8358
+ const now = Date.now();
8359
+ return {
8360
+ allowed: this.draftMode ? true : count < this.maxRequests,
8361
+ current: count,
8362
+ limit: this.maxRequests,
8363
+ remaining: this.windowMs,
8364
+ resetTime: now + this.windowMs
8365
+ };
8366
+ }
8367
+ async enforce(key) {
8368
+ const result = await this.consume(key);
8369
+ if (!result.allowed) {
8370
+ throw new RateLimitError(`Rate limit exceeded for '${key}'`, result);
8371
+ }
8372
+ return result;
8373
+ }
9729
8374
  async reset(key) {
9730
8375
  await this.storage.reset(key);
9731
8376
  if (this.algorithm === "token-bucket") {
@@ -9779,6 +8424,25 @@ class RateLimiter {
9779
8424
  this.tokenBuckets.clear();
9780
8425
  }
9781
8426
  }
8427
+
8428
+ class RateLimitError extends Error {
8429
+ name = "RateLimitError";
8430
+ retryAfter;
8431
+ result;
8432
+ constructor(message, result) {
8433
+ super(message);
8434
+ this.result = result;
8435
+ this.retryAfter = Math.max(1, Math.ceil(result.remaining / 1000));
8436
+ }
8437
+ toHeaders() {
8438
+ return {
8439
+ "Retry-After": String(this.retryAfter),
8440
+ "RateLimit-Limit": String(this.result.limit),
8441
+ "RateLimit-Remaining": "0",
8442
+ "RateLimit-Reset": String(Math.ceil(this.result.resetTime / 1000))
8443
+ };
8444
+ }
8445
+ }
9782
8446
  async function createRateLimiter(options = {}) {
9783
8447
  const finalOptions = {
9784
8448
  windowMs: options.windowMs ?? config32.windowMs ?? 60000,
@@ -9952,7 +8616,7 @@ class RateLimit {
9952
8616
  return response || new Response("Not Found", { status: 404 });
9953
8617
  }
9954
8618
  if (!this.limiter) {
9955
- await new Promise((resolve9) => setTimeout(resolve9, 50));
8619
+ await new Promise((resolve7) => setTimeout(resolve7, 50));
9956
8620
  if (!this.limiter) {
9957
8621
  const response = await next();
9958
8622
  return response || new Response("Not Found", { status: 404 });
@@ -10451,8 +9115,8 @@ class MemorySessionStore {
10451
9115
  }
10452
9116
 
10453
9117
  // src/session/file-store.ts
10454
- import { existsSync as existsSync9, mkdirSync as mkdirSync6, readdirSync as readdirSync6, unlinkSync, writeFileSync as writeFileSync6, readFileSync as readFileSync2 } from "fs";
10455
- import { join as join6 } from "path";
9118
+ import { existsSync as existsSync9, mkdirSync as mkdirSync3, readdirSync as readdirSync5, unlinkSync, writeFileSync as writeFileSync5, readFileSync as readFileSync3 } from "fs";
9119
+ import { join as join5 } from "path";
10456
9120
  import { tmpdir } from "os";
10457
9121
 
10458
9122
  class FileSessionStore {
@@ -10461,22 +9125,22 @@ class FileSessionStore {
10461
9125
  cleanupInterval = null;
10462
9126
  constructor(defaultTtl = 86400, dir) {
10463
9127
  this.defaultTtl = defaultTtl;
10464
- this.dir = dir || join6(tmpdir(), "bun-router-sessions");
9128
+ this.dir = dir || join5(tmpdir(), "bun-router-sessions");
10465
9129
  if (!existsSync9(this.dir)) {
10466
- mkdirSync6(this.dir, { recursive: true });
9130
+ mkdirSync3(this.dir, { recursive: true });
10467
9131
  }
10468
9132
  this.cleanupInterval = setInterval(() => this.cleanup(), 10 * 60 * 1000);
10469
9133
  }
10470
9134
  filePath(sid) {
10471
9135
  const safeSid = sid.replace(/[^a-zA-Z0-9_-]/g, "");
10472
- return join6(this.dir, `${safeSid}.json`);
9136
+ return join5(this.dir, `${safeSid}.json`);
10473
9137
  }
10474
9138
  async get(sid) {
10475
9139
  const path = this.filePath(sid);
10476
9140
  if (!existsSync9(path))
10477
9141
  return null;
10478
9142
  try {
10479
- const content = readFileSync2(path, "utf-8");
9143
+ const content = readFileSync3(path, "utf-8");
10480
9144
  const stored = JSON.parse(content);
10481
9145
  if (Date.now() > stored.expiresAt) {
10482
9146
  unlinkSync(path);
@@ -10492,7 +9156,7 @@ class FileSessionStore {
10492
9156
  data: session,
10493
9157
  expiresAt: Date.now() + (ttl ?? this.defaultTtl) * 1000
10494
9158
  };
10495
- writeFileSync6(this.filePath(sid), JSON.stringify(stored), "utf-8");
9159
+ writeFileSync5(this.filePath(sid), JSON.stringify(stored), "utf-8");
10496
9160
  }
10497
9161
  async destroy(sid) {
10498
9162
  const path = this.filePath(sid);
@@ -10508,15 +9172,15 @@ class FileSessionStore {
10508
9172
  data: session,
10509
9173
  expiresAt: Date.now() + (ttl ?? this.defaultTtl) * 1000
10510
9174
  };
10511
- writeFileSync6(path, JSON.stringify(stored), "utf-8");
9175
+ writeFileSync5(path, JSON.stringify(stored), "utf-8");
10512
9176
  }
10513
9177
  async all() {
10514
9178
  const result = {};
10515
9179
  const now = Date.now();
10516
9180
  try {
10517
- const files = readdirSync6(this.dir).filter((f) => f.endsWith(".json"));
9181
+ const files = readdirSync5(this.dir).filter((f) => f.endsWith(".json"));
10518
9182
  for (const file of files) {
10519
- const content = readFileSync2(join6(this.dir, file), "utf-8");
9183
+ const content = readFileSync3(join5(this.dir, file), "utf-8");
10520
9184
  const stored = JSON.parse(content);
10521
9185
  if (now <= stored.expiresAt) {
10522
9186
  const sid = file.replace(".json", "");
@@ -10528,26 +9192,26 @@ class FileSessionStore {
10528
9192
  }
10529
9193
  async length() {
10530
9194
  try {
10531
- return readdirSync6(this.dir).filter((f) => f.endsWith(".json")).length;
9195
+ return readdirSync5(this.dir).filter((f) => f.endsWith(".json")).length;
10532
9196
  } catch {
10533
9197
  return 0;
10534
9198
  }
10535
9199
  }
10536
9200
  async clear() {
10537
9201
  try {
10538
- const files = readdirSync6(this.dir).filter((f) => f.endsWith(".json"));
9202
+ const files = readdirSync5(this.dir).filter((f) => f.endsWith(".json"));
10539
9203
  for (const file of files) {
10540
- unlinkSync(join6(this.dir, file));
9204
+ unlinkSync(join5(this.dir, file));
10541
9205
  }
10542
9206
  } catch {}
10543
9207
  }
10544
9208
  cleanup() {
10545
9209
  const now = Date.now();
10546
9210
  try {
10547
- const files = readdirSync6(this.dir).filter((f) => f.endsWith(".json"));
9211
+ const files = readdirSync5(this.dir).filter((f) => f.endsWith(".json"));
10548
9212
  for (const file of files) {
10549
- const path = join6(this.dir, file);
10550
- const content = readFileSync2(path, "utf-8");
9213
+ const path = join5(this.dir, file);
9214
+ const content = readFileSync3(path, "utf-8");
10551
9215
  const stored = JSON.parse(content);
10552
9216
  if (now > stored.expiresAt) {
10553
9217
  unlinkSync(path);
@@ -11305,8 +9969,8 @@ class FileSecurity {
11305
9969
 
11306
9970
  // src/middleware/file_upload.ts
11307
9971
  import { randomUUID as randomUUID2 } from "crypto";
11308
- import { existsSync as existsSync10, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "fs";
11309
- import { basename, extname as extname2, join as join7 } from "path";
9972
+ import { existsSync as existsSync10, mkdirSync as mkdirSync4, writeFileSync as writeFileSync6 } from "fs";
9973
+ import { basename, extname as extname3, join as join6 } from "path";
11310
9974
  class FileUpload {
11311
9975
  config;
11312
9976
  fileSecurity;
@@ -11328,7 +9992,7 @@ class FileUpload {
11328
9992
  };
11329
9993
  this.fileSecurity = new FileSecurity(config4);
11330
9994
  if (this.config.createDestination && !existsSync10(this.config.destination)) {
11331
- mkdirSync7(this.config.destination, { recursive: true });
9995
+ mkdirSync4(this.config.destination, { recursive: true });
11332
9996
  }
11333
9997
  }
11334
9998
  async handle(req, next) {
@@ -11355,12 +10019,12 @@ class FileUpload {
11355
10019
  return this.createErrorResponse(`File type ${baseType} not allowed. Allowed types: ${this.config.allowedMimeTypes.join(", ")}`, 415);
11356
10020
  }
11357
10021
  }
11358
- const fileExtension = extname2(value.name).toLowerCase();
10022
+ const fileExtension = extname3(value.name).toLowerCase();
11359
10023
  if (this.config.allowedExtensions.length > 0 && !this.config.allowedExtensions.includes(fileExtension)) {
11360
10024
  return this.createErrorResponse(`File extension ${fileExtension} not allowed. Allowed extensions: ${this.config.allowedExtensions.join(", ")}`, 415);
11361
10025
  }
11362
10026
  const filename = this.generateFilename(value.name);
11363
- const filePath = join7(this.config.destination, filename);
10027
+ const filePath = join6(this.config.destination, filename);
11364
10028
  const buffer = await value.arrayBuffer();
11365
10029
  const uploadedFile = {
11366
10030
  fieldName: key,
@@ -11375,7 +10039,7 @@ class FileUpload {
11375
10039
  if (!securityCheck.isValid) {
11376
10040
  return this.createErrorResponse(`Security validation failed: ${securityCheck.errors.join(", ")}`, 400);
11377
10041
  }
11378
- writeFileSync7(filePath, new Uint8Array(buffer));
10042
+ writeFileSync6(filePath, new Uint8Array(buffer));
11379
10043
  uploadedFiles.push(uploadedFile);
11380
10044
  } else {
11381
10045
  if (fields[key]) {
@@ -11412,7 +10076,7 @@ class FileUpload {
11412
10076
  if (this.config.preserveOriginalName && !this.config.generateUniqueFilename) {
11413
10077
  return sanitizedName;
11414
10078
  }
11415
- const extension = extname2(sanitizedName);
10079
+ const extension = extname3(sanitizedName);
11416
10080
  const baseName = basename(sanitizedName, extension);
11417
10081
  if (this.config.generateUniqueFilename) {
11418
10082
  const uuid = randomUUID2();
@@ -12386,7 +11050,7 @@ function performanceAlerting(options = {}) {
12386
11050
  }
12387
11051
 
12388
11052
  // src/middleware/performance_dashboard.ts
12389
- import process13 from "process";
11053
+ import process11 from "process";
12390
11054
 
12391
11055
  class PerformanceDashboard {
12392
11056
  options;
@@ -12823,12 +11487,12 @@ else {
12823
11487
  }
12824
11488
  const system = {
12825
11489
  uptime: now - this.startTime,
12826
- nodeVersion: process13.version,
12827
- bunVersion: process13.versions.bun || "N/A",
12828
- platform: process13.platform,
12829
- arch: process13.arch,
12830
- memory: process13.memoryUsage(),
12831
- cpu: process13.cpuUsage()
11490
+ nodeVersion: process11.version,
11491
+ bunVersion: process11.versions.bun || "N/A",
11492
+ platform: process11.platform,
11493
+ arch: process11.arch,
11494
+ memory: process11.memoryUsage(),
11495
+ cpu: process11.cpuUsage()
12832
11496
  };
12833
11497
  return {
12834
11498
  metrics,
@@ -12911,7 +11575,7 @@ function performanceDashboard(options = {}) {
12911
11575
 
12912
11576
  // src/middleware/performance_monitor.ts
12913
11577
  import crypto2 from "crypto";
12914
- import process15 from "process";
11578
+ import process12 from "process";
12915
11579
  class PerformanceMonitor3 {
12916
11580
  options;
12917
11581
  metrics = [];
@@ -13005,13 +11669,13 @@ class PerformanceMonitor3 {
13005
11669
  return req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || req.headers.get("x-real-ip") || req.headers.get("cf-connecting-ip") || "unknown";
13006
11670
  }
13007
11671
  async collectSystemMetrics() {
13008
- const memory = process15.memoryUsage();
13009
- const cpu = process15.cpuUsage();
11672
+ const memory = process12.memoryUsage();
11673
+ const cpu = process12.cpuUsage();
13010
11674
  return { memory, cpu };
13011
11675
  }
13012
11676
  takeSample(profileData) {
13013
- const memory = process15.memoryUsage();
13014
- const cpu = process15.cpuUsage();
11677
+ const memory = process12.memoryUsage();
11678
+ const cpu = process12.cpuUsage();
13015
11679
  const timestamp = Date.now();
13016
11680
  if (!profileData.systemSamples) {
13017
11681
  profileData.systemSamples = [];
@@ -13230,8 +11894,8 @@ class PerformanceMonitor3 {
13230
11894
  async collectMetrics(params) {
13231
11895
  const { req, res, startTime, startMemory: _startMemory, startCPU, error } = params;
13232
11896
  const endTime = performance.now();
13233
- const endMemory = process15.memoryUsage();
13234
- const endCpu = process15.cpuUsage(startCPU);
11897
+ const endMemory = process12.memoryUsage();
11898
+ const endCpu = process12.cpuUsage(startCPU);
13235
11899
  const url = new URL(req.url);
13236
11900
  const requestId = req.requestId || crypto2.randomUUID();
13237
11901
  const cpuUsage = {
@@ -13292,8 +11956,8 @@ class PerformanceMonitor3 {
13292
11956
  this.requestsThisSecond++;
13293
11957
  console.warn(`[PerformanceMonitor] Handling request: ${req.method} ${new URL(req.url).pathname}`);
13294
11958
  const startTime = performance.now();
13295
- const startMemory = process15.memoryUsage();
13296
- const startCPU = process15.cpuUsage();
11959
+ const startMemory = process12.memoryUsage();
11960
+ const startCPU = process12.cpuUsage();
13297
11961
  const profilingSamples = [];
13298
11962
  let profilingInterval;
13299
11963
  if (this.options.profiling?.enabled) {
@@ -13413,8 +12077,8 @@ class PerformanceMonitor3 {
13413
12077
  }
13414
12078
  getProfiles() {
13415
12079
  const profiles = [];
13416
- const currentMemory = process15.memoryUsage();
13417
- const currentCpu = process15.cpuUsage();
12080
+ const currentMemory = process12.memoryUsage();
12081
+ const currentCpu = process12.cpuUsage();
13418
12082
  profiles.push({
13419
12083
  timestamp: Date.now(),
13420
12084
  memoryUsage: currentMemory,